caplets 0.16.0 → 0.17.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.
- package/README.md +87 -0
- package/dist/index.js +1938 -702
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -15,455 +15,19 @@ import { createServer as createServer$1 } from "http";
|
|
|
15
15
|
import { Http2ServerRequest, constants as constants$1 } from "http2";
|
|
16
16
|
import { Readable } from "stream";
|
|
17
17
|
import crypto$1 from "crypto";
|
|
18
|
-
//#region
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
operation: "Wrapper operation: get_caplet, check_backend, list_tools, search_tools, get_tool, or call_tool.",
|
|
29
|
-
query: "Required for search_tools only.",
|
|
30
|
-
limit: "Optional search_tools result limit.",
|
|
31
|
-
tool: "Exact downstream tool name for get_tool or call_tool.",
|
|
32
|
-
arguments: "Required JSON object for call_tool arguments/downstream inputs.",
|
|
33
|
-
fields: "Optional call_tool structured output paths when outputSchema allows it."
|
|
18
|
+
//#region \0rolldown/runtime.js
|
|
19
|
+
var __defProp$1 = Object.defineProperty;
|
|
20
|
+
var __exportAll$1 = (all, no_symbols) => {
|
|
21
|
+
let target = {};
|
|
22
|
+
for (var name in all) __defProp$1(target, name, {
|
|
23
|
+
get: all[name],
|
|
24
|
+
enumerable: true
|
|
25
|
+
});
|
|
26
|
+
if (!no_symbols) __defProp$1(target, Symbol.toStringTag, { value: "Module" });
|
|
27
|
+
return target;
|
|
34
28
|
};
|
|
35
|
-
function generatedToolInputJsonSchema() {
|
|
36
|
-
return {
|
|
37
|
-
type: "object",
|
|
38
|
-
properties: {
|
|
39
|
-
operation: {
|
|
40
|
-
type: "string",
|
|
41
|
-
enum: operations,
|
|
42
|
-
description: generatedToolInputDescriptions.operation
|
|
43
|
-
},
|
|
44
|
-
query: {
|
|
45
|
-
type: "string",
|
|
46
|
-
description: generatedToolInputDescriptions.query
|
|
47
|
-
},
|
|
48
|
-
limit: {
|
|
49
|
-
type: "integer",
|
|
50
|
-
minimum: 1,
|
|
51
|
-
description: generatedToolInputDescriptions.limit
|
|
52
|
-
},
|
|
53
|
-
tool: {
|
|
54
|
-
type: "string",
|
|
55
|
-
description: generatedToolInputDescriptions.tool
|
|
56
|
-
},
|
|
57
|
-
arguments: {
|
|
58
|
-
type: "object",
|
|
59
|
-
description: generatedToolInputDescriptions.arguments
|
|
60
|
-
},
|
|
61
|
-
fields: {
|
|
62
|
-
type: "array",
|
|
63
|
-
items: {
|
|
64
|
-
type: "string",
|
|
65
|
-
minLength: 1
|
|
66
|
-
},
|
|
67
|
-
minItems: 1,
|
|
68
|
-
description: generatedToolInputDescriptions.fields
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
required: ["operation"],
|
|
72
|
-
additionalProperties: false
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
29
|
//#endregion
|
|
76
|
-
//#region ../core/dist/
|
|
77
|
-
var __create = Object.create;
|
|
78
|
-
var __defProp = Object.defineProperty;
|
|
79
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
80
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
81
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
82
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
83
|
-
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
84
|
-
var __copyProps = (to, from, except, desc) => {
|
|
85
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
86
|
-
key = keys[i];
|
|
87
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
88
|
-
get: ((k) => from[k]).bind(null, key),
|
|
89
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return to;
|
|
93
|
-
};
|
|
94
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
95
|
-
value: mod,
|
|
96
|
-
enumerable: true
|
|
97
|
-
}) : target, mod));
|
|
98
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
99
|
-
const CAPLETS_ERROR_CODES = [
|
|
100
|
-
"CONFIG_NOT_FOUND",
|
|
101
|
-
"CONFIG_EXISTS",
|
|
102
|
-
"CONFIG_INVALID",
|
|
103
|
-
"REQUEST_INVALID",
|
|
104
|
-
"SERVER_NOT_FOUND",
|
|
105
|
-
"SERVER_UNAVAILABLE",
|
|
106
|
-
"SERVER_START_TIMEOUT",
|
|
107
|
-
"UNKNOWN_OPERATION",
|
|
108
|
-
"TOOL_NOT_FOUND",
|
|
109
|
-
"TOOL_CALL_TIMEOUT",
|
|
110
|
-
"AUTH_REQUIRED",
|
|
111
|
-
"AUTH_FAILED",
|
|
112
|
-
"AUTH_REFRESH_FAILED",
|
|
113
|
-
"DOWNSTREAM_PROTOCOL_ERROR",
|
|
114
|
-
"DOWNSTREAM_TOOL_ERROR",
|
|
115
|
-
"UNSUPPORTED_TRANSPORT",
|
|
116
|
-
"INTERNAL_ERROR"
|
|
117
|
-
];
|
|
118
|
-
var CapletsError = class extends Error {
|
|
119
|
-
code;
|
|
120
|
-
details;
|
|
121
|
-
constructor(code, message, details) {
|
|
122
|
-
super(message);
|
|
123
|
-
this.name = "CapletsError";
|
|
124
|
-
this.code = code;
|
|
125
|
-
this.details = details;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
const SECRET_KEY_PATTERN = /(token|secret|authorization|auth|api[-_]?key|password|credential|clientsecret|client_secret|code|refresh)/i;
|
|
129
|
-
const SECRET_VALUE_PATTERN = /(bearer\s+)[a-z0-9._~+/=-]+|([?&](?:access_token|refresh_token|token|code)=)[^&\s]+/gi;
|
|
130
|
-
function redactSecrets(value) {
|
|
131
|
-
if (typeof value === "string") return value.replace(SECRET_VALUE_PATTERN, "$1$2[REDACTED]");
|
|
132
|
-
if (Array.isArray(value)) return value.map((item) => redactSecrets(item));
|
|
133
|
-
if (value && typeof value === "object") {
|
|
134
|
-
const redacted = {};
|
|
135
|
-
for (const [key, nested] of Object.entries(value)) redacted[key] = SECRET_KEY_PATTERN.test(key) ? "[REDACTED]" : redactSecrets(nested);
|
|
136
|
-
return redacted;
|
|
137
|
-
}
|
|
138
|
-
return value;
|
|
139
|
-
}
|
|
140
|
-
function toSafeError(error, fallback = "INTERNAL_ERROR") {
|
|
141
|
-
if (error instanceof CapletsError) return {
|
|
142
|
-
code: error.code,
|
|
143
|
-
message: String(redactSecrets(error.message)),
|
|
144
|
-
...error.details === void 0 ? {} : { details: redactSecrets(error.details) }
|
|
145
|
-
};
|
|
146
|
-
if (error instanceof Error) return {
|
|
147
|
-
code: fallback,
|
|
148
|
-
message: String(redactSecrets(error.message))
|
|
149
|
-
};
|
|
150
|
-
return {
|
|
151
|
-
code: fallback,
|
|
152
|
-
message: String(redactSecrets(error))
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
function errorResult(error, fallback) {
|
|
156
|
-
const safe = toSafeError(error, fallback);
|
|
157
|
-
return {
|
|
158
|
-
isError: true,
|
|
159
|
-
content: [{
|
|
160
|
-
type: "text",
|
|
161
|
-
text: `${safe.code}: ${safe.message}`
|
|
162
|
-
}],
|
|
163
|
-
structuredContent: { error: safe }
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
function textContent(text) {
|
|
167
|
-
return text ? [{
|
|
168
|
-
type: "text",
|
|
169
|
-
text
|
|
170
|
-
}] : [];
|
|
171
|
-
}
|
|
172
|
-
function compactJsonText(value, maxLength = 600) {
|
|
173
|
-
return compactText(JSON.stringify(value) ?? String(value), maxLength);
|
|
174
|
-
}
|
|
175
|
-
function compactText(value, maxLength = 600) {
|
|
176
|
-
const collapsed = value.replace(/\s+/gu, " ").trim();
|
|
177
|
-
return collapsed.length > maxLength ? `${collapsed.slice(0, maxLength - 1).trimEnd()}…` : collapsed;
|
|
178
|
-
}
|
|
179
|
-
function resultKeys(value) {
|
|
180
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return "scalar result";
|
|
181
|
-
const keys = Object.keys(value).filter((key) => key !== "elapsedMs");
|
|
182
|
-
return keys.length > 0 ? `structured keys: ${keys.join(", ")}` : "empty structured result";
|
|
183
|
-
}
|
|
184
|
-
function statusSummary(value) {
|
|
185
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return compactJsonText(value);
|
|
186
|
-
const record = value;
|
|
187
|
-
return [
|
|
188
|
-
typeof record.status === "number" ? `status ${record.status}` : void 0,
|
|
189
|
-
typeof record.statusText === "string" && record.statusText ? record.statusText : void 0,
|
|
190
|
-
typeof record.exitCode === "number" ? `exit ${record.exitCode}` : void 0,
|
|
191
|
-
"body" in record ? "body" : void 0,
|
|
192
|
-
"json" in record ? "json" : void 0,
|
|
193
|
-
typeof record.stdout === "string" && record.stdout ? "stdout" : void 0,
|
|
194
|
-
typeof record.stderr === "string" && record.stderr ? "stderr" : void 0
|
|
195
|
-
].filter((part) => Boolean(part)).join("; ") || resultKeys(record);
|
|
196
|
-
}
|
|
197
|
-
function compactStructuredContent(value) {
|
|
198
|
-
return textContent(statusSummary(value));
|
|
199
|
-
}
|
|
200
|
-
function searchToolList(tools, query, limit, compact) {
|
|
201
|
-
const tokens = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
|
|
202
|
-
return tools.filter((tool) => {
|
|
203
|
-
const haystack = `${tool.name}\n${tool.description ?? ""}`.toLocaleLowerCase();
|
|
204
|
-
return tokens.some((token) => haystack.includes(token));
|
|
205
|
-
}).sort((left, right) => left.name.localeCompare(right.name)).slice(0, limit).map(compact);
|
|
206
|
-
}
|
|
207
|
-
const DEFAULT_INPUT_SCHEMA$1 = {
|
|
208
|
-
type: "object",
|
|
209
|
-
additionalProperties: true
|
|
210
|
-
};
|
|
211
|
-
var CliToolsManager = class {
|
|
212
|
-
registry;
|
|
213
|
-
constructor(registry) {
|
|
214
|
-
this.registry = registry;
|
|
215
|
-
}
|
|
216
|
-
updateRegistry(registry) {
|
|
217
|
-
this.registry = registry;
|
|
218
|
-
}
|
|
219
|
-
invalidate(_serverId) {}
|
|
220
|
-
async checkTools(config) {
|
|
221
|
-
const startedAt = Date.now();
|
|
222
|
-
try {
|
|
223
|
-
for (const action of actionsFor(config)) {
|
|
224
|
-
const cwdTemplate = action.cwd ?? config.cwd;
|
|
225
|
-
if (cwdTemplate && !cwdTemplate.includes("$input")) {
|
|
226
|
-
if (!existsSync(interpolateRequiredString(cwdTemplate, {}, "cwd"))) throw new CapletsError("CONFIG_INVALID", `CLI cwd does not exist for ${config.server}/${action.name}`);
|
|
227
|
-
}
|
|
228
|
-
if (!action.command.includes("$input")) resolveCommandPath(action.command);
|
|
229
|
-
}
|
|
230
|
-
this.registry.setStatus(config.server, "available");
|
|
231
|
-
return {
|
|
232
|
-
id: config.server,
|
|
233
|
-
status: "available",
|
|
234
|
-
toolCount: Object.keys(config.actions).length,
|
|
235
|
-
elapsedMs: Date.now() - startedAt
|
|
236
|
-
};
|
|
237
|
-
} catch (error) {
|
|
238
|
-
const safe = toSafeError(error, "SERVER_UNAVAILABLE");
|
|
239
|
-
this.registry.setStatus(config.server, "unavailable", safe);
|
|
240
|
-
return {
|
|
241
|
-
id: config.server,
|
|
242
|
-
status: "unavailable",
|
|
243
|
-
elapsedMs: Date.now() - startedAt,
|
|
244
|
-
error: safe
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
async listTools(config) {
|
|
249
|
-
return actionsFor(config).map((action) => this.toTool(action));
|
|
250
|
-
}
|
|
251
|
-
async getTool(config, toolName) {
|
|
252
|
-
return this.toTool(getAction(config, toolName));
|
|
253
|
-
}
|
|
254
|
-
async callTool(config, toolName, args) {
|
|
255
|
-
const action = getAction(config, toolName);
|
|
256
|
-
validateInput(action, args);
|
|
257
|
-
const execution = resolveExecution(config, action, args);
|
|
258
|
-
const startedAt = Date.now();
|
|
259
|
-
const controller = new AbortController();
|
|
260
|
-
const timeout = setTimeout(() => controller.abort(), execution.timeoutMs);
|
|
261
|
-
try {
|
|
262
|
-
const result = await spawnCommand(execution, controller.signal, () => Date.now() - startedAt);
|
|
263
|
-
const structured = parseStructuredResult(action, result, result.exitCode !== 0);
|
|
264
|
-
return {
|
|
265
|
-
content: compactStructuredContent(structured),
|
|
266
|
-
structuredContent: structured,
|
|
267
|
-
isError: result.exitCode !== 0
|
|
268
|
-
};
|
|
269
|
-
} catch (error) {
|
|
270
|
-
if (isAbortError$1(error)) throw new CapletsError("TOOL_CALL_TIMEOUT", `CLI tool timed out for ${config.server}/${toolName}`);
|
|
271
|
-
if (error instanceof CapletsError) throw error;
|
|
272
|
-
throw new CapletsError("DOWNSTREAM_TOOL_ERROR", `CLI tool failed for ${config.server}/${toolName}`, toSafeError(error));
|
|
273
|
-
} finally {
|
|
274
|
-
clearTimeout(timeout);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
compact(config, tool) {
|
|
278
|
-
return {
|
|
279
|
-
id: config.server,
|
|
280
|
-
tool: tool.name,
|
|
281
|
-
...tool.description ? { description: tool.description } : {},
|
|
282
|
-
hasInputSchema: Boolean(tool.inputSchema),
|
|
283
|
-
hasOutputSchema: Boolean(tool.outputSchema)
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
search(config, tools, query, limit) {
|
|
287
|
-
return searchToolList(tools, query, limit, (tool) => this.compact(config, tool));
|
|
288
|
-
}
|
|
289
|
-
toTool(action) {
|
|
290
|
-
return {
|
|
291
|
-
name: action.name,
|
|
292
|
-
...action.description ? { description: action.description } : {},
|
|
293
|
-
inputSchema: action.inputSchema ?? DEFAULT_INPUT_SCHEMA$1,
|
|
294
|
-
...action.outputSchema ? { outputSchema: action.outputSchema } : {},
|
|
295
|
-
...action.annotations ? { annotations: action.annotations } : {}
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
function actionsFor(config) {
|
|
300
|
-
return Object.entries(config.actions).map(([name, action]) => ({
|
|
301
|
-
name,
|
|
302
|
-
...action
|
|
303
|
-
})).sort((left, right) => left.name.localeCompare(right.name));
|
|
304
|
-
}
|
|
305
|
-
function getAction(config, toolName) {
|
|
306
|
-
const actions = actionsFor(config);
|
|
307
|
-
const action = actions.find((candidate) => candidate.name === toolName);
|
|
308
|
-
if (!action) throw new CapletsError("TOOL_NOT_FOUND", `Tool ${toolName} was not found on ${config.server}`, {
|
|
309
|
-
server: config.server,
|
|
310
|
-
tool: toolName,
|
|
311
|
-
suggestions: actions.map((candidate) => candidate.name).filter((name) => name.toLocaleLowerCase().includes(toolName.toLocaleLowerCase()[0] ?? "")).slice(0, 5)
|
|
312
|
-
});
|
|
313
|
-
return action;
|
|
314
|
-
}
|
|
315
|
-
function resolveExecution(config, action, input) {
|
|
316
|
-
const cwd = interpolateString(action.cwd ?? config.cwd, input, "cwd");
|
|
317
|
-
if (cwd && !existsSync(cwd)) throw new CapletsError("CONFIG_INVALID", `CLI cwd does not exist for ${config.server}/${action.name}`);
|
|
318
|
-
const env = {
|
|
319
|
-
...process.env,
|
|
320
|
-
...resolveEnv(config.env, input),
|
|
321
|
-
...resolveEnv(action.env, input)
|
|
322
|
-
};
|
|
323
|
-
return {
|
|
324
|
-
command: interpolateString(action.command, input, "command") ?? action.command,
|
|
325
|
-
args: (action.args ?? []).map((arg, index) => interpolateRequiredString(arg, input, `args.${index}`)),
|
|
326
|
-
...cwd ? { cwd } : {},
|
|
327
|
-
env,
|
|
328
|
-
timeoutMs: action.timeoutMs ?? config.timeoutMs,
|
|
329
|
-
maxOutputBytes: action.maxOutputBytes ?? config.maxOutputBytes
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
function resolveEnv(env, input) {
|
|
333
|
-
if (!env) return {};
|
|
334
|
-
return Object.fromEntries(Object.entries(env).map(([key, value]) => [key, interpolateRequiredString(value, input, `env.${key}`)]));
|
|
335
|
-
}
|
|
336
|
-
function interpolateString(value, input, field) {
|
|
337
|
-
return value === void 0 ? void 0 : interpolateRequiredString(value, input, field);
|
|
338
|
-
}
|
|
339
|
-
function interpolateRequiredString(value, input, field) {
|
|
340
|
-
return value.replace(/\$input(?:\.([A-Za-z0-9_.-]+))?/g, (_match, path) => {
|
|
341
|
-
if (!path) throw new CapletsError("REQUEST_INVALID", `CLI ${field} cannot interpolate $input directly`);
|
|
342
|
-
const selected = valueAtPath$1(input, path);
|
|
343
|
-
if (selected === void 0 || selected === null) throw new CapletsError("REQUEST_INVALID", `CLI ${field} references missing input ${path}`);
|
|
344
|
-
if (typeof selected !== "string" && typeof selected !== "number" && typeof selected !== "boolean") throw new CapletsError("REQUEST_INVALID", `CLI ${field} input ${path} must be a string, number, or boolean`);
|
|
345
|
-
return String(selected);
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
function valueAtPath$1(input, path) {
|
|
349
|
-
let current = input;
|
|
350
|
-
for (const segment of path.split(".")) {
|
|
351
|
-
if (!current || typeof current !== "object" || Array.isArray(current)) return;
|
|
352
|
-
current = current[segment];
|
|
353
|
-
}
|
|
354
|
-
return current;
|
|
355
|
-
}
|
|
356
|
-
function validateInput(action, input) {
|
|
357
|
-
const schema = action.inputSchema;
|
|
358
|
-
if (!schema) return;
|
|
359
|
-
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
360
|
-
for (const key of required) if (typeof key === "string" && (input[key] === void 0 || input[key] === null)) throw new CapletsError("REQUEST_INVALID", `CLI tool ${action.name} requires input ${key}`);
|
|
361
|
-
const properties = isPlainObject$7(schema.properties) ? schema.properties : {};
|
|
362
|
-
for (const [key, property] of Object.entries(properties)) {
|
|
363
|
-
if (input[key] === void 0 || !isPlainObject$7(property) || typeof property.type !== "string") continue;
|
|
364
|
-
if (!matchesJsonType(input[key], property.type)) throw new CapletsError("REQUEST_INVALID", `CLI tool ${action.name} input ${key} must be ${property.type}`);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function matchesJsonType(value, type) {
|
|
368
|
-
switch (type) {
|
|
369
|
-
case "string": return typeof value === "string";
|
|
370
|
-
case "number":
|
|
371
|
-
case "integer": return typeof value === "number" && (type === "number" || Number.isInteger(value));
|
|
372
|
-
case "boolean": return typeof value === "boolean";
|
|
373
|
-
case "object": return isPlainObject$7(value);
|
|
374
|
-
case "array": return Array.isArray(value);
|
|
375
|
-
case "null": return value === null;
|
|
376
|
-
default: return true;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
function spawnCommand(execution, signal, elapsedMs) {
|
|
380
|
-
return new Promise((resolve, reject) => {
|
|
381
|
-
let stdout = "";
|
|
382
|
-
let stderr = "";
|
|
383
|
-
let outputBytes = 0;
|
|
384
|
-
const child = spawn(execution.command, execution.args, {
|
|
385
|
-
cwd: execution.cwd,
|
|
386
|
-
env: execution.env,
|
|
387
|
-
shell: false,
|
|
388
|
-
signal,
|
|
389
|
-
windowsHide: true
|
|
390
|
-
});
|
|
391
|
-
child.on("error", reject);
|
|
392
|
-
const append = (stream, chunk) => {
|
|
393
|
-
outputBytes += chunk.byteLength;
|
|
394
|
-
if (outputBytes > execution.maxOutputBytes) {
|
|
395
|
-
child.kill();
|
|
396
|
-
reject(new CapletsError("DOWNSTREAM_TOOL_ERROR", "CLI tool output exceeded byte limit"));
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
if (stream === "stdout") stdout += chunk.toString("utf8");
|
|
400
|
-
else stderr += chunk.toString("utf8");
|
|
401
|
-
};
|
|
402
|
-
child.stdout?.on("data", (chunk) => append("stdout", chunk));
|
|
403
|
-
child.stderr?.on("data", (chunk) => append("stderr", chunk));
|
|
404
|
-
child.on("close", (exitCode, childSignal) => {
|
|
405
|
-
resolve({
|
|
406
|
-
exitCode,
|
|
407
|
-
signal: childSignal,
|
|
408
|
-
stdout,
|
|
409
|
-
stderr,
|
|
410
|
-
elapsedMs: elapsedMs()
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
function parseStructuredResult(action, result, tolerateInvalidJson = false) {
|
|
416
|
-
const structured = {
|
|
417
|
-
exitCode: result.exitCode,
|
|
418
|
-
stdout: result.stdout,
|
|
419
|
-
stderr: result.stderr,
|
|
420
|
-
elapsedMs: result.elapsedMs,
|
|
421
|
-
...result.signal ? { signal: result.signal } : {}
|
|
422
|
-
};
|
|
423
|
-
if (action.output?.type === "json" && result.stdout.trim()) try {
|
|
424
|
-
structured.json = JSON.parse(result.stdout);
|
|
425
|
-
} catch (error) {
|
|
426
|
-
if (tolerateInvalidJson) {
|
|
427
|
-
structured.jsonParseError = toSafeError(error);
|
|
428
|
-
return structured;
|
|
429
|
-
}
|
|
430
|
-
throw new CapletsError("DOWNSTREAM_PROTOCOL_ERROR", `CLI tool ${action.name} stdout was not valid JSON`, toSafeError(error));
|
|
431
|
-
}
|
|
432
|
-
return structured;
|
|
433
|
-
}
|
|
434
|
-
function resolveCommandPath(command) {
|
|
435
|
-
if (isAbsolute(command) || /[\\/]/.test(command)) {
|
|
436
|
-
assertExecutable(command);
|
|
437
|
-
return command;
|
|
438
|
-
}
|
|
439
|
-
for (const directory of (process.env.PATH ?? "").split(delimiter)) {
|
|
440
|
-
if (!directory) continue;
|
|
441
|
-
const candidate = join(directory, command);
|
|
442
|
-
if (isExecutable(candidate)) return candidate;
|
|
443
|
-
if (process.platform === "win32") for (const ext of (process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")) {
|
|
444
|
-
const windowsCandidate = join(directory, `${command}${ext.toLowerCase()}`);
|
|
445
|
-
if (isExecutable(windowsCandidate)) return windowsCandidate;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
throw new CapletsError("SERVER_UNAVAILABLE", `CLI command ${command} was not found on PATH`);
|
|
449
|
-
}
|
|
450
|
-
function assertExecutable(path) {
|
|
451
|
-
if (!isExecutable(path)) throw new CapletsError("SERVER_UNAVAILABLE", `CLI command ${path} is not executable`);
|
|
452
|
-
}
|
|
453
|
-
function isExecutable(path) {
|
|
454
|
-
try {
|
|
455
|
-
accessSync(path, constants.X_OK);
|
|
456
|
-
return true;
|
|
457
|
-
} catch {
|
|
458
|
-
return false;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
function isAbortError$1(error) {
|
|
462
|
-
return error instanceof Error && error.name === "AbortError";
|
|
463
|
-
}
|
|
464
|
-
function isPlainObject$7(value) {
|
|
465
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
466
|
-
}
|
|
30
|
+
//#region ../core/dist/generated-tool-input-schema-B6rce396.js
|
|
467
31
|
var _a$1;
|
|
468
32
|
/** A special constant with type `never` */
|
|
469
33
|
const NEVER = /* @__PURE__ */ Object.freeze({ status: "aborted" });
|
|
@@ -607,7 +171,7 @@ const allowsEval = /* @__PURE__ */ cached(() => {
|
|
|
607
171
|
return false;
|
|
608
172
|
}
|
|
609
173
|
});
|
|
610
|
-
function isPlainObject$
|
|
174
|
+
function isPlainObject$8(o) {
|
|
611
175
|
if (isObject(o) === false) return false;
|
|
612
176
|
const ctor = o.constructor;
|
|
613
177
|
if (ctor === void 0) return true;
|
|
@@ -618,7 +182,7 @@ function isPlainObject$6(o) {
|
|
|
618
182
|
return true;
|
|
619
183
|
}
|
|
620
184
|
function shallowClone(o) {
|
|
621
|
-
if (isPlainObject$
|
|
185
|
+
if (isPlainObject$8(o)) return { ...o };
|
|
622
186
|
if (Array.isArray(o)) return [...o];
|
|
623
187
|
if (o instanceof Map) return new Map(o);
|
|
624
188
|
if (o instanceof Set) return new Set(o);
|
|
@@ -701,7 +265,7 @@ function omit(schema, mask) {
|
|
|
701
265
|
}));
|
|
702
266
|
}
|
|
703
267
|
function extend(schema, shape) {
|
|
704
|
-
if (!isPlainObject$
|
|
268
|
+
if (!isPlainObject$8(shape)) throw new Error("Invalid input to extend: expected a plain object");
|
|
705
269
|
const checks = schema._zod.def.checks;
|
|
706
270
|
if (checks && checks.length > 0) {
|
|
707
271
|
const existingShape = schema._zod.def.shape;
|
|
@@ -717,7 +281,7 @@ function extend(schema, shape) {
|
|
|
717
281
|
} }));
|
|
718
282
|
}
|
|
719
283
|
function safeExtend(schema, shape) {
|
|
720
|
-
if (!isPlainObject$
|
|
284
|
+
if (!isPlainObject$8(shape)) throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
721
285
|
return clone(schema, mergeDefs(schema._zod.def, { get shape() {
|
|
722
286
|
const _shape = {
|
|
723
287
|
...schema._zod.def.shape,
|
|
@@ -908,7 +472,7 @@ const _parse = (_Err) => (schema, value, _ctx, _params) => {
|
|
|
908
472
|
}
|
|
909
473
|
return result.value;
|
|
910
474
|
};
|
|
911
|
-
const parse$
|
|
475
|
+
const parse$1 = /* @__PURE__ */ _parse($ZodRealError);
|
|
912
476
|
const _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
|
913
477
|
const ctx = _ctx ? {
|
|
914
478
|
..._ctx,
|
|
@@ -945,7 +509,7 @@ const _safeParse = (_Err) => (schema, value, _ctx) => {
|
|
|
945
509
|
data: result.value
|
|
946
510
|
};
|
|
947
511
|
};
|
|
948
|
-
const safeParse$
|
|
512
|
+
const safeParse$1 = /* @__PURE__ */ _safeParse($ZodRealError);
|
|
949
513
|
const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {
|
|
950
514
|
const ctx = _ctx ? {
|
|
951
515
|
..._ctx,
|
|
@@ -964,7 +528,7 @@ const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {
|
|
|
964
528
|
data: result.value
|
|
965
529
|
};
|
|
966
530
|
};
|
|
967
|
-
const safeParseAsync$
|
|
531
|
+
const safeParseAsync$1 = /* @__PURE__ */ _safeParseAsync($ZodRealError);
|
|
968
532
|
const _encode = (_Err) => (schema, value, _ctx) => {
|
|
969
533
|
const ctx = _ctx ? {
|
|
970
534
|
..._ctx,
|
|
@@ -1063,7 +627,7 @@ const string$1 = (params) => {
|
|
|
1063
627
|
return new RegExp(`^${regex}$`);
|
|
1064
628
|
};
|
|
1065
629
|
const integer = /^-?\d+$/;
|
|
1066
|
-
const number$
|
|
630
|
+
const number$1 = /^-?\d+(?:\.\d+)?$/;
|
|
1067
631
|
const boolean$1 = /^(?:true|false)$/i;
|
|
1068
632
|
const _null$2 = /^null$/i;
|
|
1069
633
|
const lowercase = /^[^A-Z]*$/;
|
|
@@ -1537,10 +1101,10 @@ const $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
|
1537
1101
|
defineLazy(inst, "~standard", () => ({
|
|
1538
1102
|
validate: (value) => {
|
|
1539
1103
|
try {
|
|
1540
|
-
const r = safeParse$
|
|
1104
|
+
const r = safeParse$1(inst, value);
|
|
1541
1105
|
return r.success ? { value: r.data } : { issues: r.error?.issues };
|
|
1542
1106
|
} catch (_) {
|
|
1543
|
-
return safeParseAsync$
|
|
1107
|
+
return safeParseAsync$1(inst, value).then((r) => r.success ? { value: r.data } : { issues: r.error?.issues });
|
|
1544
1108
|
}
|
|
1545
1109
|
},
|
|
1546
1110
|
vendor: "zod",
|
|
@@ -1830,7 +1394,7 @@ const $ZodJWT = /* @__PURE__ */ $constructor("$ZodJWT", (inst, def) => {
|
|
|
1830
1394
|
});
|
|
1831
1395
|
const $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
|
|
1832
1396
|
$ZodType.init(inst, def);
|
|
1833
|
-
inst._zod.pattern = inst._zod.bag.pattern ?? number$
|
|
1397
|
+
inst._zod.pattern = inst._zod.bag.pattern ?? number$1;
|
|
1834
1398
|
inst._zod.parse = (payload, _ctx) => {
|
|
1835
1399
|
if (def.coerce) try {
|
|
1836
1400
|
payload.value = Number(payload.value);
|
|
@@ -2317,7 +1881,7 @@ function mergeValues$1(a, b) {
|
|
|
2317
1881
|
valid: true,
|
|
2318
1882
|
data: a
|
|
2319
1883
|
};
|
|
2320
|
-
if (isPlainObject$
|
|
1884
|
+
if (isPlainObject$8(a) && isPlainObject$8(b)) {
|
|
2321
1885
|
const bKeys = Object.keys(b);
|
|
2322
1886
|
const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
|
|
2323
1887
|
const newObj = {
|
|
@@ -2393,7 +1957,7 @@ const $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
2393
1957
|
$ZodType.init(inst, def);
|
|
2394
1958
|
inst._zod.parse = (payload, ctx) => {
|
|
2395
1959
|
const input = payload.value;
|
|
2396
|
-
if (!isPlainObject$
|
|
1960
|
+
if (!isPlainObject$8(input)) {
|
|
2397
1961
|
payload.issues.push({
|
|
2398
1962
|
expected: "record",
|
|
2399
1963
|
code: "invalid_type",
|
|
@@ -2460,7 +2024,7 @@ const $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
2460
2024
|
issues: []
|
|
2461
2025
|
}, ctx);
|
|
2462
2026
|
if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
|
|
2463
|
-
if (typeof key === "string" && number$
|
|
2027
|
+
if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) {
|
|
2464
2028
|
const retryResult = def.keyType._zod.run({
|
|
2465
2029
|
value: Number(key),
|
|
2466
2030
|
issues: []
|
|
@@ -4135,8 +3699,8 @@ const initializer = (inst, issues) => {
|
|
|
4135
3699
|
const ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer, { Parent: Error });
|
|
4136
3700
|
const parse$2 = /* @__PURE__ */ _parse(ZodRealError);
|
|
4137
3701
|
const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
4138
|
-
const safeParse$
|
|
4139
|
-
const safeParseAsync$
|
|
3702
|
+
const safeParse$2 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
3703
|
+
const safeParseAsync$2 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
|
|
4140
3704
|
const encode = /* @__PURE__ */ _encode(ZodRealError);
|
|
4141
3705
|
const decode = /* @__PURE__ */ _decode(ZodRealError);
|
|
4142
3706
|
const encodeAsync = /* @__PURE__ */ _encodeAsync(ZodRealError);
|
|
@@ -4192,9 +3756,9 @@ const ZodType$1 = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
|
|
|
4192
3756
|
inst.type = def.type;
|
|
4193
3757
|
Object.defineProperty(inst, "_def", { value: def });
|
|
4194
3758
|
inst.parse = (data, params) => parse$2(inst, data, params, { callee: inst.parse });
|
|
4195
|
-
inst.safeParse = (data, params) => safeParse$
|
|
3759
|
+
inst.safeParse = (data, params) => safeParse$2(inst, data, params);
|
|
4196
3760
|
inst.parseAsync = async (data, params) => parseAsync(inst, data, params, { callee: inst.parseAsync });
|
|
4197
|
-
inst.safeParseAsync = async (data, params) => safeParseAsync$
|
|
3761
|
+
inst.safeParseAsync = async (data, params) => safeParseAsync$2(inst, data, params);
|
|
4198
3762
|
inst.spa = inst.safeParseAsync;
|
|
4199
3763
|
inst.encode = (data, params) => encode(inst, data, params);
|
|
4200
3764
|
inst.decode = (data, params) => decode(inst, data, params);
|
|
@@ -4543,7 +4107,7 @@ const ZodNumber$1 = /* @__PURE__ */ $constructor("ZodNumber", (inst, def) => {
|
|
|
4543
4107
|
inst.isFinite = true;
|
|
4544
4108
|
inst.format = bag.format ?? null;
|
|
4545
4109
|
});
|
|
4546
|
-
function number$
|
|
4110
|
+
function number$2(params) {
|
|
4547
4111
|
return /* @__PURE__ */ _number(ZodNumber$1, params);
|
|
4548
4112
|
}
|
|
4549
4113
|
const ZodNumberFormat = /* @__PURE__ */ $constructor("ZodNumberFormat", (inst, def) => {
|
|
@@ -4989,6 +4553,571 @@ function preprocess(fn, schema) {
|
|
|
4989
4553
|
out: schema
|
|
4990
4554
|
});
|
|
4991
4555
|
}
|
|
4556
|
+
const operations = [
|
|
4557
|
+
"get_caplet",
|
|
4558
|
+
"check_backend",
|
|
4559
|
+
"list_tools",
|
|
4560
|
+
"search_tools",
|
|
4561
|
+
"get_tool",
|
|
4562
|
+
"call_tool"
|
|
4563
|
+
];
|
|
4564
|
+
const mcpOperations = [
|
|
4565
|
+
...operations,
|
|
4566
|
+
"list_resources",
|
|
4567
|
+
"search_resources",
|
|
4568
|
+
"list_resource_templates",
|
|
4569
|
+
"read_resource",
|
|
4570
|
+
"list_prompts",
|
|
4571
|
+
"search_prompts",
|
|
4572
|
+
"get_prompt",
|
|
4573
|
+
"complete"
|
|
4574
|
+
];
|
|
4575
|
+
const generatedToolInputDescriptions = {
|
|
4576
|
+
operation: "Wrapper operation: get_caplet, check_backend, list_tools, search_tools, get_tool, call_tool. MCP Caplets also expose resources, prompts, and completions.",
|
|
4577
|
+
query: "Required for search operations only.",
|
|
4578
|
+
limit: "Optional list/search result limit.",
|
|
4579
|
+
tool: "Exact downstream tool name for get_tool or call_tool.",
|
|
4580
|
+
arguments: "JSON object for call_tool arguments/downstream inputs or get_prompt arguments.",
|
|
4581
|
+
fields: "Optional call_tool structured output paths when outputSchema allows it.",
|
|
4582
|
+
uri: "Exact downstream resource URI for read_resource.",
|
|
4583
|
+
prompt: "Exact downstream prompt name for get_prompt.",
|
|
4584
|
+
ref: "Completion target reference for complete.",
|
|
4585
|
+
argument: "Completion argument object for complete."
|
|
4586
|
+
};
|
|
4587
|
+
const completionRefSchema = union([object$1({
|
|
4588
|
+
type: literal("prompt"),
|
|
4589
|
+
name: string().min(1)
|
|
4590
|
+
}).strict(), object$1({
|
|
4591
|
+
type: literal("resourceTemplate"),
|
|
4592
|
+
uri: string().min(1)
|
|
4593
|
+
}).strict()]);
|
|
4594
|
+
const completionArgumentSchema = object$1({
|
|
4595
|
+
name: string().min(1),
|
|
4596
|
+
value: string()
|
|
4597
|
+
}).strict();
|
|
4598
|
+
const baseShape = {
|
|
4599
|
+
query: string().optional().describe(generatedToolInputDescriptions.query),
|
|
4600
|
+
limit: number$2().int().positive().optional().describe(generatedToolInputDescriptions.limit),
|
|
4601
|
+
tool: string().optional().describe(generatedToolInputDescriptions.tool),
|
|
4602
|
+
arguments: object$1({}).catchall(any()).optional().describe(generatedToolInputDescriptions.arguments),
|
|
4603
|
+
fields: array(string().min(1)).min(1).optional().describe(generatedToolInputDescriptions.fields)
|
|
4604
|
+
};
|
|
4605
|
+
function generatedToolInputSchemaForCaplet(caplet) {
|
|
4606
|
+
return object$1({
|
|
4607
|
+
operation: (caplet.backend === "mcp" ? _enum(mcpOperations) : _enum(operations)).describe(generatedToolInputDescriptions.operation),
|
|
4608
|
+
...baseShape,
|
|
4609
|
+
...caplet.backend === "mcp" ? {
|
|
4610
|
+
uri: string().optional().describe(generatedToolInputDescriptions.uri),
|
|
4611
|
+
prompt: string().optional().describe(generatedToolInputDescriptions.prompt),
|
|
4612
|
+
ref: completionRefSchema.optional().describe(generatedToolInputDescriptions.ref),
|
|
4613
|
+
argument: completionArgumentSchema.optional().describe(generatedToolInputDescriptions.argument)
|
|
4614
|
+
} : {}
|
|
4615
|
+
}).strict();
|
|
4616
|
+
}
|
|
4617
|
+
object$1({
|
|
4618
|
+
operation: _enum(operations).describe(generatedToolInputDescriptions.operation),
|
|
4619
|
+
...baseShape
|
|
4620
|
+
}).strict();
|
|
4621
|
+
function generatedToolInputJsonSchemaForCaplet(caplet) {
|
|
4622
|
+
const mcp = caplet.backend === "mcp";
|
|
4623
|
+
return {
|
|
4624
|
+
type: "object",
|
|
4625
|
+
properties: {
|
|
4626
|
+
operation: {
|
|
4627
|
+
type: "string",
|
|
4628
|
+
enum: mcp ? mcpOperations : operations,
|
|
4629
|
+
description: generatedToolInputDescriptions.operation
|
|
4630
|
+
},
|
|
4631
|
+
query: {
|
|
4632
|
+
type: "string",
|
|
4633
|
+
description: generatedToolInputDescriptions.query
|
|
4634
|
+
},
|
|
4635
|
+
limit: {
|
|
4636
|
+
type: "integer",
|
|
4637
|
+
minimum: 1,
|
|
4638
|
+
description: generatedToolInputDescriptions.limit
|
|
4639
|
+
},
|
|
4640
|
+
tool: {
|
|
4641
|
+
type: "string",
|
|
4642
|
+
description: generatedToolInputDescriptions.tool
|
|
4643
|
+
},
|
|
4644
|
+
arguments: {
|
|
4645
|
+
type: "object",
|
|
4646
|
+
description: generatedToolInputDescriptions.arguments
|
|
4647
|
+
},
|
|
4648
|
+
fields: {
|
|
4649
|
+
type: "array",
|
|
4650
|
+
items: {
|
|
4651
|
+
type: "string",
|
|
4652
|
+
minLength: 1
|
|
4653
|
+
},
|
|
4654
|
+
minItems: 1,
|
|
4655
|
+
description: generatedToolInputDescriptions.fields
|
|
4656
|
+
},
|
|
4657
|
+
...mcp ? {
|
|
4658
|
+
uri: {
|
|
4659
|
+
type: "string",
|
|
4660
|
+
description: generatedToolInputDescriptions.uri
|
|
4661
|
+
},
|
|
4662
|
+
prompt: {
|
|
4663
|
+
type: "string",
|
|
4664
|
+
description: generatedToolInputDescriptions.prompt
|
|
4665
|
+
},
|
|
4666
|
+
ref: {
|
|
4667
|
+
oneOf: [{
|
|
4668
|
+
type: "object",
|
|
4669
|
+
properties: {
|
|
4670
|
+
type: { const: "prompt" },
|
|
4671
|
+
name: {
|
|
4672
|
+
type: "string",
|
|
4673
|
+
minLength: 1
|
|
4674
|
+
}
|
|
4675
|
+
},
|
|
4676
|
+
required: ["type", "name"],
|
|
4677
|
+
additionalProperties: false
|
|
4678
|
+
}, {
|
|
4679
|
+
type: "object",
|
|
4680
|
+
properties: {
|
|
4681
|
+
type: { const: "resourceTemplate" },
|
|
4682
|
+
uri: {
|
|
4683
|
+
type: "string",
|
|
4684
|
+
minLength: 1
|
|
4685
|
+
}
|
|
4686
|
+
},
|
|
4687
|
+
required: ["type", "uri"],
|
|
4688
|
+
additionalProperties: false
|
|
4689
|
+
}],
|
|
4690
|
+
description: generatedToolInputDescriptions.ref
|
|
4691
|
+
},
|
|
4692
|
+
argument: {
|
|
4693
|
+
type: "object",
|
|
4694
|
+
properties: {
|
|
4695
|
+
name: {
|
|
4696
|
+
type: "string",
|
|
4697
|
+
minLength: 1
|
|
4698
|
+
},
|
|
4699
|
+
value: { type: "string" }
|
|
4700
|
+
},
|
|
4701
|
+
required: ["name", "value"],
|
|
4702
|
+
additionalProperties: false,
|
|
4703
|
+
description: generatedToolInputDescriptions.argument
|
|
4704
|
+
}
|
|
4705
|
+
} : {}
|
|
4706
|
+
},
|
|
4707
|
+
required: ["operation"],
|
|
4708
|
+
additionalProperties: false
|
|
4709
|
+
};
|
|
4710
|
+
}
|
|
4711
|
+
function generatedToolInputJsonSchema() {
|
|
4712
|
+
return generatedToolInputJsonSchemaForCaplet({ backend: "tool" });
|
|
4713
|
+
}
|
|
4714
|
+
//#endregion
|
|
4715
|
+
//#region ../core/dist/options-DM1cMRcp.js
|
|
4716
|
+
var __create = Object.create;
|
|
4717
|
+
var __defProp = Object.defineProperty;
|
|
4718
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4719
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4720
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4721
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4722
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
4723
|
+
var __exportAll = (all, no_symbols) => {
|
|
4724
|
+
let target = {};
|
|
4725
|
+
for (var name in all) __defProp(target, name, {
|
|
4726
|
+
get: all[name],
|
|
4727
|
+
enumerable: true
|
|
4728
|
+
});
|
|
4729
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
4730
|
+
return target;
|
|
4731
|
+
};
|
|
4732
|
+
var __copyProps = (to, from, except, desc) => {
|
|
4733
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
4734
|
+
key = keys[i];
|
|
4735
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
4736
|
+
get: ((k) => from[k]).bind(null, key),
|
|
4737
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
4738
|
+
});
|
|
4739
|
+
}
|
|
4740
|
+
return to;
|
|
4741
|
+
};
|
|
4742
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
4743
|
+
value: mod,
|
|
4744
|
+
enumerable: true
|
|
4745
|
+
}) : target, mod));
|
|
4746
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
4747
|
+
const CAPLETS_ERROR_CODES = [
|
|
4748
|
+
"CONFIG_NOT_FOUND",
|
|
4749
|
+
"CONFIG_EXISTS",
|
|
4750
|
+
"CONFIG_INVALID",
|
|
4751
|
+
"REQUEST_INVALID",
|
|
4752
|
+
"SERVER_NOT_FOUND",
|
|
4753
|
+
"SERVER_UNAVAILABLE",
|
|
4754
|
+
"SERVER_START_TIMEOUT",
|
|
4755
|
+
"UNKNOWN_OPERATION",
|
|
4756
|
+
"TOOL_NOT_FOUND",
|
|
4757
|
+
"TOOL_CALL_TIMEOUT",
|
|
4758
|
+
"AUTH_REQUIRED",
|
|
4759
|
+
"AUTH_FAILED",
|
|
4760
|
+
"AUTH_REFRESH_FAILED",
|
|
4761
|
+
"DOWNSTREAM_PROTOCOL_ERROR",
|
|
4762
|
+
"DOWNSTREAM_TOOL_ERROR",
|
|
4763
|
+
"UNSUPPORTED_OPERATION",
|
|
4764
|
+
"UNSUPPORTED_CAPABILITY",
|
|
4765
|
+
"PROMPT_NOT_FOUND",
|
|
4766
|
+
"DOWNSTREAM_RESOURCE_ERROR",
|
|
4767
|
+
"DOWNSTREAM_PROMPT_ERROR",
|
|
4768
|
+
"DOWNSTREAM_COMPLETION_ERROR",
|
|
4769
|
+
"UNSUPPORTED_TRANSPORT",
|
|
4770
|
+
"INTERNAL_ERROR"
|
|
4771
|
+
];
|
|
4772
|
+
var CapletsError = class extends Error {
|
|
4773
|
+
code;
|
|
4774
|
+
details;
|
|
4775
|
+
constructor(code, message, details) {
|
|
4776
|
+
super(message);
|
|
4777
|
+
this.name = "CapletsError";
|
|
4778
|
+
this.code = code;
|
|
4779
|
+
this.details = details;
|
|
4780
|
+
}
|
|
4781
|
+
};
|
|
4782
|
+
const SECRET_KEY_PATTERN = /(token|secret|authorization|auth|api[-_]?key|password|credential|clientsecret|client_secret|code|refresh)/i;
|
|
4783
|
+
const SECRET_VALUE_PATTERN = /(bearer\s+)[a-z0-9._~+/=-]+|([?&](?:access_token|refresh_token|token|code)=)[^&\s]+/gi;
|
|
4784
|
+
function redactSecrets(value) {
|
|
4785
|
+
if (typeof value === "string") return value.replace(SECRET_VALUE_PATTERN, "$1$2[REDACTED]");
|
|
4786
|
+
if (Array.isArray(value)) return value.map((item) => redactSecrets(item));
|
|
4787
|
+
if (value && typeof value === "object") {
|
|
4788
|
+
const redacted = {};
|
|
4789
|
+
for (const [key, nested] of Object.entries(value)) redacted[key] = SECRET_KEY_PATTERN.test(key) ? "[REDACTED]" : redactSecrets(nested);
|
|
4790
|
+
return redacted;
|
|
4791
|
+
}
|
|
4792
|
+
return value;
|
|
4793
|
+
}
|
|
4794
|
+
function toSafeError(error, fallback = "INTERNAL_ERROR") {
|
|
4795
|
+
if (error instanceof CapletsError) return {
|
|
4796
|
+
code: error.code,
|
|
4797
|
+
message: String(redactSecrets(error.message)),
|
|
4798
|
+
...error.details === void 0 ? {} : { details: redactSecrets(error.details) }
|
|
4799
|
+
};
|
|
4800
|
+
if (error instanceof Error) return {
|
|
4801
|
+
code: fallback,
|
|
4802
|
+
message: String(redactSecrets(error.message))
|
|
4803
|
+
};
|
|
4804
|
+
return {
|
|
4805
|
+
code: fallback,
|
|
4806
|
+
message: String(redactSecrets(error))
|
|
4807
|
+
};
|
|
4808
|
+
}
|
|
4809
|
+
function errorResult(error, fallback) {
|
|
4810
|
+
const safe = toSafeError(error, fallback);
|
|
4811
|
+
return {
|
|
4812
|
+
isError: true,
|
|
4813
|
+
content: [{
|
|
4814
|
+
type: "text",
|
|
4815
|
+
text: `${safe.code}: ${safe.message}`
|
|
4816
|
+
}],
|
|
4817
|
+
structuredContent: { error: safe }
|
|
4818
|
+
};
|
|
4819
|
+
}
|
|
4820
|
+
function textContent(text) {
|
|
4821
|
+
return text ? [{
|
|
4822
|
+
type: "text",
|
|
4823
|
+
text
|
|
4824
|
+
}] : [];
|
|
4825
|
+
}
|
|
4826
|
+
function compactJsonText(value, maxLength = 600) {
|
|
4827
|
+
return compactText(JSON.stringify(value) ?? String(value), maxLength);
|
|
4828
|
+
}
|
|
4829
|
+
function compactText(value, maxLength = 600) {
|
|
4830
|
+
const collapsed = value.replace(/\s+/gu, " ").trim();
|
|
4831
|
+
return collapsed.length > maxLength ? `${collapsed.slice(0, maxLength - 1).trimEnd()}…` : collapsed;
|
|
4832
|
+
}
|
|
4833
|
+
function resultKeys(value) {
|
|
4834
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return "scalar result";
|
|
4835
|
+
const keys = Object.keys(value).filter((key) => key !== "elapsedMs");
|
|
4836
|
+
return keys.length > 0 ? `structured keys: ${keys.join(", ")}` : "empty structured result";
|
|
4837
|
+
}
|
|
4838
|
+
function statusSummary(value) {
|
|
4839
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return compactJsonText(value);
|
|
4840
|
+
const record = value;
|
|
4841
|
+
return [
|
|
4842
|
+
typeof record.status === "number" ? `status ${record.status}` : void 0,
|
|
4843
|
+
typeof record.statusText === "string" && record.statusText ? record.statusText : void 0,
|
|
4844
|
+
typeof record.exitCode === "number" ? `exit ${record.exitCode}` : void 0,
|
|
4845
|
+
"body" in record ? "body" : void 0,
|
|
4846
|
+
"json" in record ? "json" : void 0,
|
|
4847
|
+
typeof record.stdout === "string" && record.stdout ? "stdout" : void 0,
|
|
4848
|
+
typeof record.stderr === "string" && record.stderr ? "stderr" : void 0
|
|
4849
|
+
].filter((part) => Boolean(part)).join("; ") || resultKeys(record);
|
|
4850
|
+
}
|
|
4851
|
+
function compactStructuredContent(value) {
|
|
4852
|
+
return textContent(statusSummary(value));
|
|
4853
|
+
}
|
|
4854
|
+
function searchToolList(tools, query, limit, compact) {
|
|
4855
|
+
const tokens = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
|
|
4856
|
+
return tools.filter((tool) => {
|
|
4857
|
+
const haystack = `${tool.name}\n${tool.description ?? ""}`.toLocaleLowerCase();
|
|
4858
|
+
return tokens.some((token) => haystack.includes(token));
|
|
4859
|
+
}).sort((left, right) => left.name.localeCompare(right.name)).slice(0, limit).map(compact);
|
|
4860
|
+
}
|
|
4861
|
+
const DEFAULT_INPUT_SCHEMA$1 = {
|
|
4862
|
+
type: "object",
|
|
4863
|
+
additionalProperties: true
|
|
4864
|
+
};
|
|
4865
|
+
var CliToolsManager = class {
|
|
4866
|
+
registry;
|
|
4867
|
+
constructor(registry) {
|
|
4868
|
+
this.registry = registry;
|
|
4869
|
+
}
|
|
4870
|
+
updateRegistry(registry) {
|
|
4871
|
+
this.registry = registry;
|
|
4872
|
+
}
|
|
4873
|
+
invalidate(_serverId) {}
|
|
4874
|
+
async checkTools(config) {
|
|
4875
|
+
const startedAt = Date.now();
|
|
4876
|
+
try {
|
|
4877
|
+
for (const action of actionsFor(config)) {
|
|
4878
|
+
const cwdTemplate = action.cwd ?? config.cwd;
|
|
4879
|
+
if (cwdTemplate && !cwdTemplate.includes("$input")) {
|
|
4880
|
+
if (!existsSync(interpolateRequiredString(cwdTemplate, {}, "cwd"))) throw new CapletsError("CONFIG_INVALID", `CLI cwd does not exist for ${config.server}/${action.name}`);
|
|
4881
|
+
}
|
|
4882
|
+
if (!action.command.includes("$input")) resolveCommandPath(action.command);
|
|
4883
|
+
}
|
|
4884
|
+
this.registry.setStatus(config.server, "available");
|
|
4885
|
+
return {
|
|
4886
|
+
id: config.server,
|
|
4887
|
+
status: "available",
|
|
4888
|
+
toolCount: Object.keys(config.actions).length,
|
|
4889
|
+
elapsedMs: Date.now() - startedAt
|
|
4890
|
+
};
|
|
4891
|
+
} catch (error) {
|
|
4892
|
+
const safe = toSafeError(error, "SERVER_UNAVAILABLE");
|
|
4893
|
+
this.registry.setStatus(config.server, "unavailable", safe);
|
|
4894
|
+
return {
|
|
4895
|
+
id: config.server,
|
|
4896
|
+
status: "unavailable",
|
|
4897
|
+
elapsedMs: Date.now() - startedAt,
|
|
4898
|
+
error: safe
|
|
4899
|
+
};
|
|
4900
|
+
}
|
|
4901
|
+
}
|
|
4902
|
+
async listTools(config) {
|
|
4903
|
+
return actionsFor(config).map((action) => this.toTool(action));
|
|
4904
|
+
}
|
|
4905
|
+
async getTool(config, toolName) {
|
|
4906
|
+
return this.toTool(getAction(config, toolName));
|
|
4907
|
+
}
|
|
4908
|
+
async callTool(config, toolName, args) {
|
|
4909
|
+
const action = getAction(config, toolName);
|
|
4910
|
+
validateInput(action, args);
|
|
4911
|
+
const execution = resolveExecution(config, action, args);
|
|
4912
|
+
const startedAt = Date.now();
|
|
4913
|
+
const controller = new AbortController();
|
|
4914
|
+
const timeout = setTimeout(() => controller.abort(), execution.timeoutMs);
|
|
4915
|
+
try {
|
|
4916
|
+
const result = await spawnCommand(execution, controller.signal, () => Date.now() - startedAt);
|
|
4917
|
+
const structured = parseStructuredResult(action, result, result.exitCode !== 0);
|
|
4918
|
+
return {
|
|
4919
|
+
content: compactStructuredContent(structured),
|
|
4920
|
+
structuredContent: structured,
|
|
4921
|
+
isError: result.exitCode !== 0
|
|
4922
|
+
};
|
|
4923
|
+
} catch (error) {
|
|
4924
|
+
if (isAbortError$1(error)) throw new CapletsError("TOOL_CALL_TIMEOUT", `CLI tool timed out for ${config.server}/${toolName}`);
|
|
4925
|
+
if (error instanceof CapletsError) throw error;
|
|
4926
|
+
throw new CapletsError("DOWNSTREAM_TOOL_ERROR", `CLI tool failed for ${config.server}/${toolName}`, toSafeError(error));
|
|
4927
|
+
} finally {
|
|
4928
|
+
clearTimeout(timeout);
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
compact(config, tool) {
|
|
4932
|
+
return {
|
|
4933
|
+
id: config.server,
|
|
4934
|
+
tool: tool.name,
|
|
4935
|
+
...tool.description ? { description: tool.description } : {},
|
|
4936
|
+
hasInputSchema: Boolean(tool.inputSchema),
|
|
4937
|
+
hasOutputSchema: Boolean(tool.outputSchema)
|
|
4938
|
+
};
|
|
4939
|
+
}
|
|
4940
|
+
search(config, tools, query, limit) {
|
|
4941
|
+
return searchToolList(tools, query, limit, (tool) => this.compact(config, tool));
|
|
4942
|
+
}
|
|
4943
|
+
toTool(action) {
|
|
4944
|
+
return {
|
|
4945
|
+
name: action.name,
|
|
4946
|
+
...action.description ? { description: action.description } : {},
|
|
4947
|
+
inputSchema: action.inputSchema ?? DEFAULT_INPUT_SCHEMA$1,
|
|
4948
|
+
...action.outputSchema ? { outputSchema: action.outputSchema } : {},
|
|
4949
|
+
...action.annotations ? { annotations: action.annotations } : {}
|
|
4950
|
+
};
|
|
4951
|
+
}
|
|
4952
|
+
};
|
|
4953
|
+
function actionsFor(config) {
|
|
4954
|
+
return Object.entries(config.actions).map(([name, action]) => ({
|
|
4955
|
+
name,
|
|
4956
|
+
...action
|
|
4957
|
+
})).sort((left, right) => left.name.localeCompare(right.name));
|
|
4958
|
+
}
|
|
4959
|
+
function getAction(config, toolName) {
|
|
4960
|
+
const actions = actionsFor(config);
|
|
4961
|
+
const action = actions.find((candidate) => candidate.name === toolName);
|
|
4962
|
+
if (!action) throw new CapletsError("TOOL_NOT_FOUND", `Tool ${toolName} was not found on ${config.server}`, {
|
|
4963
|
+
server: config.server,
|
|
4964
|
+
tool: toolName,
|
|
4965
|
+
suggestions: actions.map((candidate) => candidate.name).filter((name) => name.toLocaleLowerCase().includes(toolName.toLocaleLowerCase()[0] ?? "")).slice(0, 5)
|
|
4966
|
+
});
|
|
4967
|
+
return action;
|
|
4968
|
+
}
|
|
4969
|
+
function resolveExecution(config, action, input) {
|
|
4970
|
+
const cwd = interpolateString(action.cwd ?? config.cwd, input, "cwd");
|
|
4971
|
+
if (cwd && !existsSync(cwd)) throw new CapletsError("CONFIG_INVALID", `CLI cwd does not exist for ${config.server}/${action.name}`);
|
|
4972
|
+
const env = {
|
|
4973
|
+
...process.env,
|
|
4974
|
+
...resolveEnv(config.env, input),
|
|
4975
|
+
...resolveEnv(action.env, input)
|
|
4976
|
+
};
|
|
4977
|
+
return {
|
|
4978
|
+
command: interpolateString(action.command, input, "command") ?? action.command,
|
|
4979
|
+
args: (action.args ?? []).map((arg, index) => interpolateRequiredString(arg, input, `args.${index}`)),
|
|
4980
|
+
...cwd ? { cwd } : {},
|
|
4981
|
+
env,
|
|
4982
|
+
timeoutMs: action.timeoutMs ?? config.timeoutMs,
|
|
4983
|
+
maxOutputBytes: action.maxOutputBytes ?? config.maxOutputBytes
|
|
4984
|
+
};
|
|
4985
|
+
}
|
|
4986
|
+
function resolveEnv(env, input) {
|
|
4987
|
+
if (!env) return {};
|
|
4988
|
+
return Object.fromEntries(Object.entries(env).map(([key, value]) => [key, interpolateRequiredString(value, input, `env.${key}`)]));
|
|
4989
|
+
}
|
|
4990
|
+
function interpolateString(value, input, field) {
|
|
4991
|
+
return value === void 0 ? void 0 : interpolateRequiredString(value, input, field);
|
|
4992
|
+
}
|
|
4993
|
+
function interpolateRequiredString(value, input, field) {
|
|
4994
|
+
return value.replace(/\$input(?:\.([A-Za-z0-9_.-]+))?/g, (_match, path) => {
|
|
4995
|
+
if (!path) throw new CapletsError("REQUEST_INVALID", `CLI ${field} cannot interpolate $input directly`);
|
|
4996
|
+
const selected = valueAtPath$1(input, path);
|
|
4997
|
+
if (selected === void 0 || selected === null) throw new CapletsError("REQUEST_INVALID", `CLI ${field} references missing input ${path}`);
|
|
4998
|
+
if (typeof selected !== "string" && typeof selected !== "number" && typeof selected !== "boolean") throw new CapletsError("REQUEST_INVALID", `CLI ${field} input ${path} must be a string, number, or boolean`);
|
|
4999
|
+
return String(selected);
|
|
5000
|
+
});
|
|
5001
|
+
}
|
|
5002
|
+
function valueAtPath$1(input, path) {
|
|
5003
|
+
let current = input;
|
|
5004
|
+
for (const segment of path.split(".")) {
|
|
5005
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) return;
|
|
5006
|
+
current = current[segment];
|
|
5007
|
+
}
|
|
5008
|
+
return current;
|
|
5009
|
+
}
|
|
5010
|
+
function validateInput(action, input) {
|
|
5011
|
+
const schema = action.inputSchema;
|
|
5012
|
+
if (!schema) return;
|
|
5013
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
5014
|
+
for (const key of required) if (typeof key === "string" && (input[key] === void 0 || input[key] === null)) throw new CapletsError("REQUEST_INVALID", `CLI tool ${action.name} requires input ${key}`);
|
|
5015
|
+
const properties = isPlainObject$6(schema.properties) ? schema.properties : {};
|
|
5016
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
5017
|
+
if (input[key] === void 0 || !isPlainObject$6(property) || typeof property.type !== "string") continue;
|
|
5018
|
+
if (!matchesJsonType(input[key], property.type)) throw new CapletsError("REQUEST_INVALID", `CLI tool ${action.name} input ${key} must be ${property.type}`);
|
|
5019
|
+
}
|
|
5020
|
+
}
|
|
5021
|
+
function matchesJsonType(value, type) {
|
|
5022
|
+
switch (type) {
|
|
5023
|
+
case "string": return typeof value === "string";
|
|
5024
|
+
case "number":
|
|
5025
|
+
case "integer": return typeof value === "number" && (type === "number" || Number.isInteger(value));
|
|
5026
|
+
case "boolean": return typeof value === "boolean";
|
|
5027
|
+
case "object": return isPlainObject$6(value);
|
|
5028
|
+
case "array": return Array.isArray(value);
|
|
5029
|
+
case "null": return value === null;
|
|
5030
|
+
default: return true;
|
|
5031
|
+
}
|
|
5032
|
+
}
|
|
5033
|
+
function spawnCommand(execution, signal, elapsedMs) {
|
|
5034
|
+
return new Promise((resolve, reject) => {
|
|
5035
|
+
let stdout = "";
|
|
5036
|
+
let stderr = "";
|
|
5037
|
+
let outputBytes = 0;
|
|
5038
|
+
const child = spawn(execution.command, execution.args, {
|
|
5039
|
+
cwd: execution.cwd,
|
|
5040
|
+
env: execution.env,
|
|
5041
|
+
shell: false,
|
|
5042
|
+
signal,
|
|
5043
|
+
windowsHide: true
|
|
5044
|
+
});
|
|
5045
|
+
child.on("error", reject);
|
|
5046
|
+
const append = (stream, chunk) => {
|
|
5047
|
+
outputBytes += chunk.byteLength;
|
|
5048
|
+
if (outputBytes > execution.maxOutputBytes) {
|
|
5049
|
+
child.kill();
|
|
5050
|
+
reject(new CapletsError("DOWNSTREAM_TOOL_ERROR", "CLI tool output exceeded byte limit"));
|
|
5051
|
+
return;
|
|
5052
|
+
}
|
|
5053
|
+
if (stream === "stdout") stdout += chunk.toString("utf8");
|
|
5054
|
+
else stderr += chunk.toString("utf8");
|
|
5055
|
+
};
|
|
5056
|
+
child.stdout?.on("data", (chunk) => append("stdout", chunk));
|
|
5057
|
+
child.stderr?.on("data", (chunk) => append("stderr", chunk));
|
|
5058
|
+
child.on("close", (exitCode, childSignal) => {
|
|
5059
|
+
resolve({
|
|
5060
|
+
exitCode,
|
|
5061
|
+
signal: childSignal,
|
|
5062
|
+
stdout,
|
|
5063
|
+
stderr,
|
|
5064
|
+
elapsedMs: elapsedMs()
|
|
5065
|
+
});
|
|
5066
|
+
});
|
|
5067
|
+
});
|
|
5068
|
+
}
|
|
5069
|
+
function parseStructuredResult(action, result, tolerateInvalidJson = false) {
|
|
5070
|
+
const structured = {
|
|
5071
|
+
exitCode: result.exitCode,
|
|
5072
|
+
stdout: result.stdout,
|
|
5073
|
+
stderr: result.stderr,
|
|
5074
|
+
elapsedMs: result.elapsedMs,
|
|
5075
|
+
...result.signal ? { signal: result.signal } : {}
|
|
5076
|
+
};
|
|
5077
|
+
if (action.output?.type === "json" && result.stdout.trim()) try {
|
|
5078
|
+
structured.json = JSON.parse(result.stdout);
|
|
5079
|
+
} catch (error) {
|
|
5080
|
+
if (tolerateInvalidJson) {
|
|
5081
|
+
structured.jsonParseError = toSafeError(error);
|
|
5082
|
+
return structured;
|
|
5083
|
+
}
|
|
5084
|
+
throw new CapletsError("DOWNSTREAM_PROTOCOL_ERROR", `CLI tool ${action.name} stdout was not valid JSON`, toSafeError(error));
|
|
5085
|
+
}
|
|
5086
|
+
return structured;
|
|
5087
|
+
}
|
|
5088
|
+
function resolveCommandPath(command) {
|
|
5089
|
+
if (isAbsolute(command) || /[\\/]/.test(command)) {
|
|
5090
|
+
assertExecutable(command);
|
|
5091
|
+
return command;
|
|
5092
|
+
}
|
|
5093
|
+
for (const directory of (process.env.PATH ?? "").split(delimiter)) {
|
|
5094
|
+
if (!directory) continue;
|
|
5095
|
+
const candidate = join(directory, command);
|
|
5096
|
+
if (isExecutable(candidate)) return candidate;
|
|
5097
|
+
if (process.platform === "win32") for (const ext of (process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")) {
|
|
5098
|
+
const windowsCandidate = join(directory, `${command}${ext.toLowerCase()}`);
|
|
5099
|
+
if (isExecutable(windowsCandidate)) return windowsCandidate;
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
throw new CapletsError("SERVER_UNAVAILABLE", `CLI command ${command} was not found on PATH`);
|
|
5103
|
+
}
|
|
5104
|
+
function assertExecutable(path) {
|
|
5105
|
+
if (!isExecutable(path)) throw new CapletsError("SERVER_UNAVAILABLE", `CLI command ${path} is not executable`);
|
|
5106
|
+
}
|
|
5107
|
+
function isExecutable(path) {
|
|
5108
|
+
try {
|
|
5109
|
+
accessSync(path, constants.X_OK);
|
|
5110
|
+
return true;
|
|
5111
|
+
} catch {
|
|
5112
|
+
return false;
|
|
5113
|
+
}
|
|
5114
|
+
}
|
|
5115
|
+
function isAbortError$1(error) {
|
|
5116
|
+
return error instanceof Error && error.name === "AbortError";
|
|
5117
|
+
}
|
|
5118
|
+
function isPlainObject$6(value) {
|
|
5119
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5120
|
+
}
|
|
4992
5121
|
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
4993
5122
|
const ZodIssueCode$1 = {
|
|
4994
5123
|
invalid_type: "invalid_type",
|
|
@@ -12509,9 +12638,9 @@ const capletMcpServerSchema = object$1({
|
|
|
12509
12638
|
cwd: string().min(1).optional().describe("Working directory for stdio servers."),
|
|
12510
12639
|
url: string().min(1).optional().describe("Remote MCP server URL for http or sse transport."),
|
|
12511
12640
|
auth: capletRemoteAuthSchema.optional(),
|
|
12512
|
-
startupTimeoutMs: number$
|
|
12513
|
-
callTimeoutMs: number$
|
|
12514
|
-
toolCacheTtlMs: number$
|
|
12641
|
+
startupTimeoutMs: number$2().int().positive().optional().describe("Timeout in milliseconds for starting or checking a downstream server."),
|
|
12642
|
+
callTimeoutMs: number$2().int().positive().optional().describe("Timeout in milliseconds for downstream tool calls."),
|
|
12643
|
+
toolCacheTtlMs: number$2().int().nonnegative().optional().describe("Milliseconds downstream tool metadata stays fresh. Set 0 to refresh every time."),
|
|
12515
12644
|
disabled: boolean().optional().describe("When true, omit this Caplet from discovery and do not start its MCP server.")
|
|
12516
12645
|
}).strict().superRefine((server, ctx) => {
|
|
12517
12646
|
const effectiveTransport = server.transport ?? (server.command ? "stdio" : void 0);
|
|
@@ -12566,8 +12695,8 @@ const capletOpenApiEndpointSchema = object$1({
|
|
|
12566
12695
|
specUrl: string().min(1).optional().describe("Remote OpenAPI specification URL."),
|
|
12567
12696
|
baseUrl: string().min(1).optional().describe("Override base URL for OpenAPI requests."),
|
|
12568
12697
|
auth: capletEndpointAuthSchema.describe("Explicit OpenAPI request auth config. Use {\"type\":\"none\"} for public APIs."),
|
|
12569
|
-
requestTimeoutMs: number$
|
|
12570
|
-
operationCacheTtlMs: number$
|
|
12698
|
+
requestTimeoutMs: number$2().int().positive().optional().describe("Timeout in milliseconds for OpenAPI HTTP requests."),
|
|
12699
|
+
operationCacheTtlMs: number$2().int().nonnegative().optional().describe("Milliseconds OpenAPI operation metadata stays fresh. Set 0 to refresh every time."),
|
|
12571
12700
|
disabled: boolean().optional().describe("When true, omit this Caplet from discovery.")
|
|
12572
12701
|
}).strict().superRefine((endpoint, ctx) => {
|
|
12573
12702
|
if (Boolean(endpoint.specPath) === Boolean(endpoint.specUrl)) ctx.addIssue({
|
|
@@ -12604,9 +12733,9 @@ const capletGraphQlEndpointSchema = object$1({
|
|
|
12604
12733
|
introspection: literal(true).optional().describe("Load schema through endpoint introspection."),
|
|
12605
12734
|
operations: record(string().regex(SERVER_ID_PATTERN), capletGraphQlOperationSchema).optional().describe("Configured GraphQL operations keyed by stable tool name."),
|
|
12606
12735
|
auth: capletEndpointAuthSchema.describe("Explicit GraphQL request auth config. Use {\"type\":\"none\"} for public APIs."),
|
|
12607
|
-
requestTimeoutMs: number$
|
|
12608
|
-
operationCacheTtlMs: number$
|
|
12609
|
-
selectionDepth: number$
|
|
12736
|
+
requestTimeoutMs: number$2().int().positive().optional().describe("Timeout in milliseconds for GraphQL HTTP requests."),
|
|
12737
|
+
operationCacheTtlMs: number$2().int().nonnegative().optional().describe("Milliseconds GraphQL operation metadata stays fresh. Set 0 to refresh every time."),
|
|
12738
|
+
selectionDepth: number$2().int().positive().max(5).optional().describe("Maximum depth for auto-generated GraphQL selection sets."),
|
|
12610
12739
|
disabled: boolean().optional().describe("When true, omit this Caplet from discovery.")
|
|
12611
12740
|
}).strict().superRefine((endpoint, ctx) => {
|
|
12612
12741
|
if (Number(Boolean(endpoint.schemaPath)) + Number(Boolean(endpoint.schemaUrl)) + Number(endpoint.introspection === true) !== 1) ctx.addIssue({
|
|
@@ -12627,7 +12756,7 @@ const capletGraphQlEndpointSchema = object$1({
|
|
|
12627
12756
|
});
|
|
12628
12757
|
const httpScalarMappingSchema$1 = record(string(), union([
|
|
12629
12758
|
string(),
|
|
12630
|
-
number$
|
|
12759
|
+
number$2(),
|
|
12631
12760
|
boolean()
|
|
12632
12761
|
]));
|
|
12633
12762
|
const capletHttpActionSchema = object$1({
|
|
@@ -12655,8 +12784,8 @@ const capletHttpApiSchema = object$1({
|
|
|
12655
12784
|
baseUrl: string().min(1).regex(HTTP_BASE_URL_PATTERN, "HTTP API baseUrl must not include credentials, query, or fragment").describe("Base URL for HTTP action requests."),
|
|
12656
12785
|
auth: capletEndpointAuthSchema.describe("Explicit HTTP API request auth config. Use {\"type\":\"none\"} for public APIs."),
|
|
12657
12786
|
actions: record(string().regex(SERVER_ID_PATTERN), capletHttpActionSchema).refine((actions) => Object.keys(actions).length > 0, "HTTP API must define at least one action").describe("Configured HTTP actions keyed by stable tool name."),
|
|
12658
|
-
requestTimeoutMs: number$
|
|
12659
|
-
maxResponseBytes: number$
|
|
12787
|
+
requestTimeoutMs: number$2().int().positive().optional().describe("Timeout in milliseconds for HTTP action requests."),
|
|
12788
|
+
maxResponseBytes: number$2().int().positive().optional().describe("Maximum HTTP action response body bytes to read."),
|
|
12660
12789
|
disabled: boolean().optional().describe("When true, omit this Caplet from discovery.")
|
|
12661
12790
|
}).strict().superRefine((api, ctx) => {
|
|
12662
12791
|
if (api.baseUrl && !hasEnvReference$1(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
|
|
@@ -12686,8 +12815,8 @@ const capletCliToolActionSchema = object$1({
|
|
|
12686
12815
|
args: array(string()).optional().describe("Arguments passed to the command."),
|
|
12687
12816
|
env: record(string(), string()).optional().describe("Additional environment variables."),
|
|
12688
12817
|
cwd: string().min(1).optional().describe("Working directory for this action."),
|
|
12689
|
-
timeoutMs: number$
|
|
12690
|
-
maxOutputBytes: number$
|
|
12818
|
+
timeoutMs: number$2().int().positive().optional(),
|
|
12819
|
+
maxOutputBytes: number$2().int().positive().optional(),
|
|
12691
12820
|
output: capletCliToolOutputSchema.optional(),
|
|
12692
12821
|
annotations: capletCliToolAnnotationsSchema.optional()
|
|
12693
12822
|
}).strict();
|
|
@@ -12695,16 +12824,16 @@ const capletCliToolsSchema = object$1({
|
|
|
12695
12824
|
actions: record(string().regex(SERVER_ID_PATTERN), capletCliToolActionSchema).refine((actions) => Object.keys(actions).length > 0, "CLI tools backend must define at least one action").describe("Configured CLI actions keyed by stable tool name."),
|
|
12696
12825
|
cwd: string().min(1).optional().describe("Default working directory for CLI actions."),
|
|
12697
12826
|
env: record(string(), string()).optional().describe("Default environment variables."),
|
|
12698
|
-
timeoutMs: number$
|
|
12699
|
-
maxOutputBytes: number$
|
|
12827
|
+
timeoutMs: number$2().int().positive().optional(),
|
|
12828
|
+
maxOutputBytes: number$2().int().positive().optional(),
|
|
12700
12829
|
disabled: boolean().optional().describe("When true, omit this Caplet from discovery.")
|
|
12701
12830
|
}).strict();
|
|
12702
12831
|
const capletSetSchema = object$1({
|
|
12703
12832
|
configPath: string().min(1).optional().describe("Child Caplets config.json path."),
|
|
12704
12833
|
capletsRoot: string().min(1).optional().describe("Child Markdown Caplets root directory."),
|
|
12705
|
-
defaultSearchLimit: number$
|
|
12706
|
-
maxSearchLimit: number$
|
|
12707
|
-
toolCacheTtlMs: number$
|
|
12834
|
+
defaultSearchLimit: number$2().int().positive().optional(),
|
|
12835
|
+
maxSearchLimit: number$2().int().positive().max(50).optional(),
|
|
12836
|
+
toolCacheTtlMs: number$2().int().nonnegative().optional(),
|
|
12708
12837
|
disabled: boolean().optional().describe("When true, omit this Caplet from discovery.")
|
|
12709
12838
|
}).strict().superRefine((set, ctx) => {
|
|
12710
12839
|
if (!set.configPath && !set.capletsRoot) ctx.addIssue({
|
|
@@ -12942,14 +13071,24 @@ function defaultStateBaseDir(env = process.env, home = homedir(), platform = pro
|
|
|
12942
13071
|
if (platform === "win32") return env.LOCALAPPDATA && win32.isAbsolute(env.LOCALAPPDATA) ? env.LOCALAPPDATA : win32.join(home, "AppData", "Local");
|
|
12943
13072
|
return env.XDG_STATE_HOME && posix.isAbsolute(env.XDG_STATE_HOME) ? env.XDG_STATE_HOME : posix.join(home, ".local", "state");
|
|
12944
13073
|
}
|
|
13074
|
+
function defaultCacheBaseDir(env = process.env, home = homedir(), platform = process.platform) {
|
|
13075
|
+
if (platform === "win32") return env.LOCALAPPDATA && win32.isAbsolute(env.LOCALAPPDATA) ? env.LOCALAPPDATA : win32.join(home, "AppData", "Local");
|
|
13076
|
+
if (platform === "darwin") return posix.join(home, "Library", "Caches");
|
|
13077
|
+
return env.XDG_CACHE_HOME && posix.isAbsolute(env.XDG_CACHE_HOME) ? env.XDG_CACHE_HOME : posix.join(home, ".cache");
|
|
13078
|
+
}
|
|
12945
13079
|
function defaultConfigPath(env = process.env, home = homedir(), platform = process.platform) {
|
|
12946
13080
|
return (platform === "win32" ? win32.join : posix.join)(defaultConfigBaseDir(env, home, platform), "caplets", "config.json");
|
|
12947
13081
|
}
|
|
12948
13082
|
function defaultAuthDir(env = process.env, home = homedir(), platform = process.platform) {
|
|
12949
13083
|
return (platform === "win32" ? win32.join : posix.join)(defaultStateBaseDir(env, home, platform), "caplets", "auth");
|
|
12950
13084
|
}
|
|
13085
|
+
function defaultCompletionCacheDir(env = process.env, home = homedir(), platform = process.platform) {
|
|
13086
|
+
const pathJoin = platform === "win32" ? win32.join : posix.join;
|
|
13087
|
+
return platform === "win32" ? pathJoin(defaultCacheBaseDir(env, home, platform), "caplets", "cache", "completions") : pathJoin(defaultCacheBaseDir(env, home, platform), "caplets", "completions");
|
|
13088
|
+
}
|
|
12951
13089
|
const DEFAULT_CONFIG_PATH = defaultConfigPath();
|
|
12952
13090
|
const DEFAULT_AUTH_DIR = defaultAuthDir();
|
|
13091
|
+
const DEFAULT_COMPLETION_CACHE_DIR = defaultCompletionCacheDir();
|
|
12953
13092
|
const PROJECT_CONFIG_FILE = join(".caplets", "config.json");
|
|
12954
13093
|
function resolveConfigPath(path) {
|
|
12955
13094
|
return path ?? DEFAULT_CONFIG_PATH;
|
|
@@ -13062,9 +13201,9 @@ const publicServerSchema = object$1({
|
|
|
13062
13201
|
url: string().url().optional().describe("Remote MCP server URL for http or sse transport."),
|
|
13063
13202
|
auth: remoteAuthSchema.optional(),
|
|
13064
13203
|
tags: array(string().trim().min(1).max(80)).optional(),
|
|
13065
|
-
startupTimeoutMs: number$
|
|
13066
|
-
callTimeoutMs: number$
|
|
13067
|
-
toolCacheTtlMs: number$
|
|
13204
|
+
startupTimeoutMs: number$2().int().positive().default(1e4).describe("Timeout in milliseconds for starting or checking a downstream server."),
|
|
13205
|
+
callTimeoutMs: number$2().int().positive().default(6e4).describe("Timeout in milliseconds for downstream tool calls."),
|
|
13206
|
+
toolCacheTtlMs: number$2().int().nonnegative().default(3e4).describe("Milliseconds downstream tool metadata stays fresh. Set 0 to refresh every time."),
|
|
13068
13207
|
disabled: boolean().default(false).describe("When true, omit this server from Caplets discovery and do not start it.")
|
|
13069
13208
|
}).strict();
|
|
13070
13209
|
const normalizedServerSchema = publicServerSchema.extend({ body: string().optional() });
|
|
@@ -13076,8 +13215,8 @@ const publicOpenApiEndpointSchema = object$1({
|
|
|
13076
13215
|
baseUrl: string().url().optional().describe("Override base URL for OpenAPI requests."),
|
|
13077
13216
|
auth: openApiAuthSchema.describe("Explicit OpenAPI request auth config. Use {\"type\":\"none\"} for public APIs."),
|
|
13078
13217
|
tags: array(string().trim().min(1).max(80)).optional(),
|
|
13079
|
-
requestTimeoutMs: number$
|
|
13080
|
-
operationCacheTtlMs: number$
|
|
13218
|
+
requestTimeoutMs: number$2().int().positive().default(6e4).describe("Timeout in milliseconds for OpenAPI HTTP requests."),
|
|
13219
|
+
operationCacheTtlMs: number$2().int().nonnegative().default(3e4).describe("Milliseconds OpenAPI operation metadata stays fresh. Set 0 to refresh every time."),
|
|
13081
13220
|
disabled: boolean().default(false).describe("When true, omit this OpenAPI Caplet from discovery.")
|
|
13082
13221
|
}).strict();
|
|
13083
13222
|
const normalizedOpenApiEndpointSchema = publicOpenApiEndpointSchema.extend({ body: string().optional() });
|
|
@@ -13102,9 +13241,9 @@ const publicGraphQlEndpointSchema = object$1({
|
|
|
13102
13241
|
operations: record(string().regex(SERVER_ID_PATTERN), graphQlOperationSchema).optional().describe("Configured GraphQL operations keyed by stable tool name."),
|
|
13103
13242
|
auth: openApiAuthSchema.describe("Explicit GraphQL request auth config. Use {\"type\":\"none\"} for public APIs."),
|
|
13104
13243
|
tags: array(string().trim().min(1).max(80)).optional(),
|
|
13105
|
-
requestTimeoutMs: number$
|
|
13106
|
-
operationCacheTtlMs: number$
|
|
13107
|
-
selectionDepth: number$
|
|
13244
|
+
requestTimeoutMs: number$2().int().positive().default(6e4).describe("Timeout in milliseconds for GraphQL HTTP requests."),
|
|
13245
|
+
operationCacheTtlMs: number$2().int().nonnegative().default(3e4).describe("Milliseconds GraphQL operation metadata stays fresh. Set 0 to refresh every time."),
|
|
13246
|
+
selectionDepth: number$2().int().positive().max(5).default(2).describe("Maximum depth for auto-generated GraphQL selection sets."),
|
|
13108
13247
|
disabled: boolean().default(false).describe("When true, omit this GraphQL Caplet.")
|
|
13109
13248
|
}).strict().superRefine((endpoint, ctx) => {
|
|
13110
13249
|
if (Number(Boolean(endpoint.schemaPath)) + Number(Boolean(endpoint.schemaUrl)) + Number(endpoint.introspection === true) !== 1) ctx.addIssue({
|
|
@@ -13115,7 +13254,7 @@ const publicGraphQlEndpointSchema = object$1({
|
|
|
13115
13254
|
const normalizedGraphQlEndpointSchema = publicGraphQlEndpointSchema.extend({ body: string().optional() });
|
|
13116
13255
|
const httpScalarMappingSchema = record(string(), union([
|
|
13117
13256
|
string(),
|
|
13118
|
-
number$
|
|
13257
|
+
number$2(),
|
|
13119
13258
|
boolean()
|
|
13120
13259
|
]));
|
|
13121
13260
|
const httpActionSchema = object$1({
|
|
@@ -13147,8 +13286,8 @@ const publicHttpApiSchema = object$1({
|
|
|
13147
13286
|
auth: openApiAuthSchema.describe("Explicit HTTP API request auth config. Use {\"type\":\"none\"} for public APIs."),
|
|
13148
13287
|
actions: record(string().regex(SERVER_ID_PATTERN), httpActionSchema).refine((actions) => Object.keys(actions).length > 0, "HTTP API must define at least one action").describe("Configured HTTP actions keyed by stable tool name."),
|
|
13149
13288
|
tags: array(string().trim().min(1).max(80)).optional(),
|
|
13150
|
-
requestTimeoutMs: number$
|
|
13151
|
-
maxResponseBytes: number$
|
|
13289
|
+
requestTimeoutMs: number$2().int().positive().default(6e4).describe("Timeout in milliseconds for HTTP action requests."),
|
|
13290
|
+
maxResponseBytes: number$2().int().positive().default(2e5).describe("Maximum HTTP action response body bytes to read."),
|
|
13152
13291
|
disabled: boolean().default(false).describe("When true, omit this HTTP API Caplet.")
|
|
13153
13292
|
}).strict();
|
|
13154
13293
|
const normalizedHttpApiSchema = publicHttpApiSchema.extend({ body: string().optional() });
|
|
@@ -13167,8 +13306,8 @@ const cliToolActionSchema = object$1({
|
|
|
13167
13306
|
args: array(string()).optional().describe("Arguments passed to the command."),
|
|
13168
13307
|
env: record(string(), string()).optional().describe("Additional environment variables for the command."),
|
|
13169
13308
|
cwd: string().min(1).optional().describe("Working directory for this action."),
|
|
13170
|
-
timeoutMs: number$
|
|
13171
|
-
maxOutputBytes: number$
|
|
13309
|
+
timeoutMs: number$2().int().positive().optional().describe("Command timeout in milliseconds."),
|
|
13310
|
+
maxOutputBytes: number$2().int().positive().optional().describe("Maximum combined stdout and stderr bytes to keep."),
|
|
13172
13311
|
output: cliToolOutputSchema.optional(),
|
|
13173
13312
|
annotations: cliToolAnnotationsSchema.optional()
|
|
13174
13313
|
}).strict();
|
|
@@ -13179,8 +13318,8 @@ const publicCliToolsSchema = object$1({
|
|
|
13179
13318
|
cwd: string().min(1).optional().describe("Default working directory for CLI actions."),
|
|
13180
13319
|
env: record(string(), string()).optional().describe("Default environment variables for CLI actions."),
|
|
13181
13320
|
tags: array(string().trim().min(1).max(80)).optional(),
|
|
13182
|
-
timeoutMs: number$
|
|
13183
|
-
maxOutputBytes: number$
|
|
13321
|
+
timeoutMs: number$2().int().positive().default(6e4).describe("Default timeout in milliseconds for CLI actions."),
|
|
13322
|
+
maxOutputBytes: number$2().int().positive().default(2e5).describe("Default maximum combined stdout and stderr bytes to keep."),
|
|
13184
13323
|
disabled: boolean().default(false).describe("When true, omit this CLI tools Caplet.")
|
|
13185
13324
|
}).strict();
|
|
13186
13325
|
const normalizedCliToolsSchema = publicCliToolsSchema.extend({ body: string().optional() });
|
|
@@ -13189,9 +13328,9 @@ const publicCapletSetSchema = object$1({
|
|
|
13189
13328
|
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"),
|
|
13190
13329
|
configPath: string().min(1).optional().describe("Child Caplets config.json path."),
|
|
13191
13330
|
capletsRoot: string().min(1).optional().describe("Child Markdown Caplets root directory."),
|
|
13192
|
-
defaultSearchLimit: number$
|
|
13193
|
-
maxSearchLimit: number$
|
|
13194
|
-
toolCacheTtlMs: number$
|
|
13331
|
+
defaultSearchLimit: number$2().int().positive().default(20).describe("Default maximum number of child Caplet search results."),
|
|
13332
|
+
maxSearchLimit: number$2().int().positive().max(50).default(50).describe("Maximum accepted child Caplet search result limit."),
|
|
13333
|
+
toolCacheTtlMs: number$2().int().nonnegative().default(3e4).describe("Milliseconds child Caplet metadata stays fresh. Set 0 to refresh every time."),
|
|
13195
13334
|
tags: array(string().trim().min(1).max(80)).optional(),
|
|
13196
13335
|
disabled: boolean().default(false).describe("When true, omit this Caplet set.")
|
|
13197
13336
|
}).strict().superRefine((set, ctx) => {
|
|
@@ -13210,8 +13349,19 @@ function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, graphQlE
|
|
|
13210
13349
|
return object$1({
|
|
13211
13350
|
$schema: string().url().optional().describe("Optional JSON Schema URL for editor validation."),
|
|
13212
13351
|
version: literal(1).default(1).describe("Caplets config schema version."),
|
|
13213
|
-
defaultSearchLimit: number$
|
|
13214
|
-
maxSearchLimit: number$
|
|
13352
|
+
defaultSearchLimit: number$2().int().positive().default(20).describe("Default maximum number of same-server search results."),
|
|
13353
|
+
maxSearchLimit: number$2().int().positive().max(50).default(50).describe("Maximum accepted search_tools limit."),
|
|
13354
|
+
completion: object$1({
|
|
13355
|
+
discoveryTimeoutMs: number$2().int().positive().default(750),
|
|
13356
|
+
overallTimeoutMs: number$2().int().positive().default(1500),
|
|
13357
|
+
cacheTtlMs: number$2().int().nonnegative().default(3e5),
|
|
13358
|
+
negativeCacheTtlMs: number$2().int().nonnegative().default(3e4)
|
|
13359
|
+
}).strict().default({
|
|
13360
|
+
discoveryTimeoutMs: 750,
|
|
13361
|
+
overallTimeoutMs: 1500,
|
|
13362
|
+
cacheTtlMs: 3e5,
|
|
13363
|
+
negativeCacheTtlMs: 3e4
|
|
13364
|
+
}).describe("Shell completion discovery timeout and cache settings."),
|
|
13215
13365
|
mcpServers: record(string().regex(SERVER_ID_PATTERN), serverValueSchema).default({}).describe("Downstream MCP servers keyed by stable server ID."),
|
|
13216
13366
|
openapiEndpoints: record(string().regex(SERVER_ID_PATTERN), openApiEndpointValueSchema).default({}).describe("OpenAPI endpoints keyed by stable Caplet ID."),
|
|
13217
13367
|
graphqlEndpoints: record(string().regex(SERVER_ID_PATTERN), graphQlEndpointValueSchema).default({}).describe("GraphQL endpoints keyed by stable Caplet ID."),
|
|
@@ -13726,7 +13876,8 @@ function parseConfig(input) {
|
|
|
13726
13876
|
version: parsed.data.version,
|
|
13727
13877
|
options: {
|
|
13728
13878
|
defaultSearchLimit: parsed.data.defaultSearchLimit,
|
|
13729
|
-
maxSearchLimit: parsed.data.maxSearchLimit
|
|
13879
|
+
maxSearchLimit: parsed.data.maxSearchLimit,
|
|
13880
|
+
completion: parsed.data.completion
|
|
13730
13881
|
},
|
|
13731
13882
|
mcpServers: servers,
|
|
13732
13883
|
openapiEndpoints,
|
|
@@ -17306,10 +17457,10 @@ const ZodMiniType = /* @__PURE__ */ $constructor("ZodMiniType", (inst, def) => {
|
|
|
17306
17457
|
$ZodType.init(inst, def);
|
|
17307
17458
|
inst.def = def;
|
|
17308
17459
|
inst.type = def.type;
|
|
17309
|
-
inst.parse = (data, params) => parse$
|
|
17310
|
-
inst.safeParse = (data, params) => safeParse$
|
|
17460
|
+
inst.parse = (data, params) => parse$1(inst, data, params, { callee: inst.parse });
|
|
17461
|
+
inst.safeParse = (data, params) => safeParse$1(inst, data, params);
|
|
17311
17462
|
inst.parseAsync = async (data, params) => parseAsync$1(inst, data, params, { callee: inst.parseAsync });
|
|
17312
|
-
inst.safeParseAsync = async (data, params) => safeParseAsync$
|
|
17463
|
+
inst.safeParseAsync = async (data, params) => safeParseAsync$1(inst, data, params);
|
|
17313
17464
|
inst.check = (...checks) => {
|
|
17314
17465
|
return inst.clone({
|
|
17315
17466
|
...def,
|
|
@@ -17355,11 +17506,11 @@ function objectFromShape(shape) {
|
|
|
17355
17506
|
throw new Error("Mixed Zod versions detected in object shape.");
|
|
17356
17507
|
}
|
|
17357
17508
|
function safeParse(schema, data) {
|
|
17358
|
-
if (isZ4Schema(schema)) return safeParse$
|
|
17509
|
+
if (isZ4Schema(schema)) return safeParse$1(schema, data);
|
|
17359
17510
|
return schema.safeParse(data);
|
|
17360
17511
|
}
|
|
17361
17512
|
async function safeParseAsync(schema, data) {
|
|
17362
|
-
if (isZ4Schema(schema)) return await safeParseAsync$
|
|
17513
|
+
if (isZ4Schema(schema)) return await safeParseAsync$1(schema, data);
|
|
17363
17514
|
return await schema.safeParseAsync(data);
|
|
17364
17515
|
}
|
|
17365
17516
|
function getObjectShape(schema) {
|
|
@@ -17473,7 +17624,7 @@ const AssertObjectSchema = custom((v) => v !== null && (typeof v === "object" ||
|
|
|
17473
17624
|
/**
|
|
17474
17625
|
* A progress token, used to associate progress notifications with the original request.
|
|
17475
17626
|
*/
|
|
17476
|
-
const ProgressTokenSchema = union([string(), number$
|
|
17627
|
+
const ProgressTokenSchema = union([string(), number$2().int()]);
|
|
17477
17628
|
/**
|
|
17478
17629
|
* An opaque token used to represent a cursor for pagination.
|
|
17479
17630
|
*/
|
|
@@ -17482,13 +17633,13 @@ looseObject({
|
|
|
17482
17633
|
/**
|
|
17483
17634
|
* Requested duration in milliseconds to retain task from creation.
|
|
17484
17635
|
*/
|
|
17485
|
-
ttl: number$
|
|
17636
|
+
ttl: number$2().optional(),
|
|
17486
17637
|
/**
|
|
17487
17638
|
* Time in milliseconds to wait between task status requests.
|
|
17488
17639
|
*/
|
|
17489
|
-
pollInterval: number$
|
|
17640
|
+
pollInterval: number$2().optional()
|
|
17490
17641
|
});
|
|
17491
|
-
const TaskMetadataSchema = object$1({ ttl: number$
|
|
17642
|
+
const TaskMetadataSchema = object$1({ ttl: number$2().optional() });
|
|
17492
17643
|
/**
|
|
17493
17644
|
* Metadata for associating messages with a task.
|
|
17494
17645
|
* Include this in the `_meta` field under the key `io.modelcontextprotocol/related-task`.
|
|
@@ -17555,7 +17706,7 @@ _meta: RequestMetaSchema.optional() });
|
|
|
17555
17706
|
/**
|
|
17556
17707
|
* A uniquely identifying ID for a request in JSON-RPC.
|
|
17557
17708
|
*/
|
|
17558
|
-
const RequestIdSchema = union([string(), number$
|
|
17709
|
+
const RequestIdSchema = union([string(), number$2().int()]);
|
|
17559
17710
|
/**
|
|
17560
17711
|
* A request that expects a response.
|
|
17561
17712
|
*/
|
|
@@ -17612,7 +17763,7 @@ const JSONRPCErrorResponseSchema = object$1({
|
|
|
17612
17763
|
/**
|
|
17613
17764
|
* The error type that occurred.
|
|
17614
17765
|
*/
|
|
17615
|
-
code: number$
|
|
17766
|
+
code: number$2().int(),
|
|
17616
17767
|
/**
|
|
17617
17768
|
* A short description of the error. The message SHOULD be limited to a concise single sentence.
|
|
17618
17769
|
*/
|
|
@@ -17948,11 +18099,11 @@ const ProgressSchema = object$1({
|
|
|
17948
18099
|
/**
|
|
17949
18100
|
* The progress thus far. This should increase every time progress is made, even if the total is unknown.
|
|
17950
18101
|
*/
|
|
17951
|
-
progress: number$
|
|
18102
|
+
progress: number$2(),
|
|
17952
18103
|
/**
|
|
17953
18104
|
* Total number of items to process (or total progress required), if known.
|
|
17954
18105
|
*/
|
|
17955
|
-
total: optional(number$
|
|
18106
|
+
total: optional(number$2()),
|
|
17956
18107
|
/**
|
|
17957
18108
|
* An optional message describing the current progress.
|
|
17958
18109
|
*/
|
|
@@ -18008,7 +18159,7 @@ const TaskSchema = object$1({
|
|
|
18008
18159
|
* Time in milliseconds to keep task results available after completion.
|
|
18009
18160
|
* If null, the task has unlimited lifetime until manually cleaned up.
|
|
18010
18161
|
*/
|
|
18011
|
-
ttl: union([number$
|
|
18162
|
+
ttl: union([number$2(), _null()]),
|
|
18012
18163
|
/**
|
|
18013
18164
|
* ISO 8601 timestamp when the task was created.
|
|
18014
18165
|
*/
|
|
@@ -18017,7 +18168,7 @@ const TaskSchema = object$1({
|
|
|
18017
18168
|
* ISO 8601 timestamp when the task was last updated.
|
|
18018
18169
|
*/
|
|
18019
18170
|
lastUpdatedAt: string(),
|
|
18020
|
-
pollInterval: optional(number$
|
|
18171
|
+
pollInterval: optional(number$2()),
|
|
18021
18172
|
/**
|
|
18022
18173
|
* Optional diagnostic message for failed tasks or other status information.
|
|
18023
18174
|
*/
|
|
@@ -18132,7 +18283,7 @@ const AnnotationsSchema = object$1({
|
|
|
18132
18283
|
/**
|
|
18133
18284
|
* Importance hint for the resource, from 0 (least) to 1 (most).
|
|
18134
18285
|
*/
|
|
18135
|
-
priority: number$
|
|
18286
|
+
priority: number$2().min(0).max(1).optional(),
|
|
18136
18287
|
/**
|
|
18137
18288
|
* ISO 8601 timestamp for the most recent modification.
|
|
18138
18289
|
*/
|
|
@@ -18163,7 +18314,7 @@ const ResourceSchema = object$1({
|
|
|
18163
18314
|
*
|
|
18164
18315
|
* This can be used by Hosts to display file sizes and estimate context window usage.
|
|
18165
18316
|
*/
|
|
18166
|
-
size: optional(number$
|
|
18317
|
+
size: optional(number$2()),
|
|
18167
18318
|
/**
|
|
18168
18319
|
* Optional annotations for the client.
|
|
18169
18320
|
*/
|
|
@@ -18690,7 +18841,7 @@ const ListChangedOptionsBaseSchema = object$1({
|
|
|
18690
18841
|
*
|
|
18691
18842
|
* @default 300
|
|
18692
18843
|
*/
|
|
18693
|
-
debounceMs: number$
|
|
18844
|
+
debounceMs: number$2().int().nonnegative().default(300)
|
|
18694
18845
|
});
|
|
18695
18846
|
/**
|
|
18696
18847
|
* The severity of a log message.
|
|
@@ -18759,15 +18910,15 @@ name: string().optional() })).optional(),
|
|
|
18759
18910
|
/**
|
|
18760
18911
|
* How much to prioritize cost when selecting a model.
|
|
18761
18912
|
*/
|
|
18762
|
-
costPriority: number$
|
|
18913
|
+
costPriority: number$2().min(0).max(1).optional(),
|
|
18763
18914
|
/**
|
|
18764
18915
|
* How much to prioritize sampling speed (latency) when selecting a model.
|
|
18765
18916
|
*/
|
|
18766
|
-
speedPriority: number$
|
|
18917
|
+
speedPriority: number$2().min(0).max(1).optional(),
|
|
18767
18918
|
/**
|
|
18768
18919
|
* How much to prioritize intelligence and capabilities when selecting a model.
|
|
18769
18920
|
*/
|
|
18770
|
-
intelligencePriority: number$
|
|
18921
|
+
intelligencePriority: number$2().min(0).max(1).optional()
|
|
18771
18922
|
});
|
|
18772
18923
|
/**
|
|
18773
18924
|
* Controls tool usage behavior in sampling requests.
|
|
@@ -18857,13 +19008,13 @@ const CreateMessageRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend
|
|
|
18857
19008
|
"thisServer",
|
|
18858
19009
|
"allServers"
|
|
18859
19010
|
]).optional(),
|
|
18860
|
-
temperature: number$
|
|
19011
|
+
temperature: number$2().optional(),
|
|
18861
19012
|
/**
|
|
18862
19013
|
* The requested maximum number of tokens to sample (to prevent runaway completions).
|
|
18863
19014
|
*
|
|
18864
19015
|
* The client MAY choose to sample fewer tokens than the requested maximum.
|
|
18865
19016
|
*/
|
|
18866
|
-
maxTokens: number$
|
|
19017
|
+
maxTokens: number$2().int(),
|
|
18867
19018
|
stopSequences: array(string()).optional(),
|
|
18868
19019
|
/**
|
|
18869
19020
|
* Optional metadata to pass through to the LLM provider. The format of this metadata is provider-specific.
|
|
@@ -18967,8 +19118,8 @@ const StringSchemaSchema = object$1({
|
|
|
18967
19118
|
type: literal("string"),
|
|
18968
19119
|
title: string().optional(),
|
|
18969
19120
|
description: string().optional(),
|
|
18970
|
-
minLength: number$
|
|
18971
|
-
maxLength: number$
|
|
19121
|
+
minLength: number$2().optional(),
|
|
19122
|
+
maxLength: number$2().optional(),
|
|
18972
19123
|
format: _enum([
|
|
18973
19124
|
"email",
|
|
18974
19125
|
"uri",
|
|
@@ -18984,9 +19135,9 @@ const NumberSchemaSchema = object$1({
|
|
|
18984
19135
|
type: _enum(["number", "integer"]),
|
|
18985
19136
|
title: string().optional(),
|
|
18986
19137
|
description: string().optional(),
|
|
18987
|
-
minimum: number$
|
|
18988
|
-
maximum: number$
|
|
18989
|
-
default: number$
|
|
19138
|
+
minimum: number$2().optional(),
|
|
19139
|
+
maximum: number$2().optional(),
|
|
19140
|
+
default: number$2().optional()
|
|
18990
19141
|
});
|
|
18991
19142
|
/**
|
|
18992
19143
|
* Schema for single-selection enumeration without display titles for options.
|
|
@@ -19029,8 +19180,8 @@ const PrimitiveSchemaDefinitionSchema = union([
|
|
|
19029
19180
|
type: literal("array"),
|
|
19030
19181
|
title: string().optional(),
|
|
19031
19182
|
description: string().optional(),
|
|
19032
|
-
minItems: number$
|
|
19033
|
-
maxItems: number$
|
|
19183
|
+
minItems: number$2().optional(),
|
|
19184
|
+
maxItems: number$2().optional(),
|
|
19034
19185
|
items: object$1({
|
|
19035
19186
|
type: literal("string"),
|
|
19036
19187
|
enum: array(string())
|
|
@@ -19040,8 +19191,8 @@ const PrimitiveSchemaDefinitionSchema = union([
|
|
|
19040
19191
|
type: literal("array"),
|
|
19041
19192
|
title: string().optional(),
|
|
19042
19193
|
description: string().optional(),
|
|
19043
|
-
minItems: number$
|
|
19044
|
-
maxItems: number$
|
|
19194
|
+
minItems: number$2().optional(),
|
|
19195
|
+
maxItems: number$2().optional(),
|
|
19045
19196
|
items: object$1({ anyOf: array(object$1({
|
|
19046
19197
|
const: string(),
|
|
19047
19198
|
title: string()
|
|
@@ -19146,7 +19297,7 @@ const ElicitResultSchema = ResultSchema.extend({
|
|
|
19146
19297
|
*/
|
|
19147
19298
|
content: preprocess((val) => val === null ? void 0 : val, record(string(), union([
|
|
19148
19299
|
string(),
|
|
19149
|
-
number$
|
|
19300
|
+
number$2(),
|
|
19150
19301
|
boolean(),
|
|
19151
19302
|
array(string())
|
|
19152
19303
|
])).optional())
|
|
@@ -19219,7 +19370,7 @@ const CompleteResultSchema = ResultSchema.extend({ completion: looseObject({
|
|
|
19219
19370
|
/**
|
|
19220
19371
|
* The total number of completion options available. This can exceed the number of values actually sent in the response.
|
|
19221
19372
|
*/
|
|
19222
|
-
total: optional(number$
|
|
19373
|
+
total: optional(number$2().int()),
|
|
19223
19374
|
/**
|
|
19224
19375
|
* Indicates whether there are additional completion options beyond those provided in the current response, even if the exact total is unknown.
|
|
19225
19376
|
*/
|
|
@@ -28891,8 +29042,8 @@ const OAuthClientMetadataSchema = object$1({
|
|
|
28891
29042
|
const OAuthClientInformationSchema = object$1({
|
|
28892
29043
|
client_id: string(),
|
|
28893
29044
|
client_secret: string().optional(),
|
|
28894
|
-
client_id_issued_at: number$
|
|
28895
|
-
client_secret_expires_at: number$
|
|
29045
|
+
client_id_issued_at: number$2().optional(),
|
|
29046
|
+
client_secret_expires_at: number$2().optional()
|
|
28896
29047
|
}).strip();
|
|
28897
29048
|
/**
|
|
28898
29049
|
* RFC 7591 OAuth 2.0 Dynamic Client Registration full response (client information plus metadata)
|
|
@@ -31267,14 +31418,28 @@ var DownstreamManager = class {
|
|
|
31267
31418
|
async checkServer(server) {
|
|
31268
31419
|
const startedAt = Date.now();
|
|
31269
31420
|
try {
|
|
31421
|
+
const capabilities = (await this.connect(server)).client.getServerCapabilities() ?? {};
|
|
31270
31422
|
const tools = await this.refreshTools(server, true);
|
|
31271
31423
|
this.registry.setStatus(server.server, "available");
|
|
31272
|
-
|
|
31424
|
+
const result = {
|
|
31273
31425
|
id: server.server,
|
|
31274
31426
|
status: "available",
|
|
31427
|
+
capabilities: {
|
|
31428
|
+
tools: Boolean(capabilities.tools),
|
|
31429
|
+
resources: Boolean(capabilities.resources),
|
|
31430
|
+
resourceTemplates: Boolean(capabilities.resources),
|
|
31431
|
+
prompts: Boolean(capabilities.prompts),
|
|
31432
|
+
completions: Boolean(capabilities.completions)
|
|
31433
|
+
},
|
|
31275
31434
|
toolCount: tools.length,
|
|
31276
31435
|
elapsedMs: Date.now() - startedAt
|
|
31277
31436
|
};
|
|
31437
|
+
if (capabilities.resources) Object.assign(result, {
|
|
31438
|
+
resourceCount: (await this.listResources(server, true)).length,
|
|
31439
|
+
resourceTemplateCount: (await this.listResourceTemplates(server, true)).length
|
|
31440
|
+
});
|
|
31441
|
+
if (capabilities.prompts) Object.assign(result, { promptCount: (await this.listPrompts(server, true)).length });
|
|
31442
|
+
return result;
|
|
31278
31443
|
} catch (error) {
|
|
31279
31444
|
const safe = toSafeError(error, "SERVER_UNAVAILABLE");
|
|
31280
31445
|
this.registry.setStatus(server.server, "unavailable", safe);
|
|
@@ -31316,6 +31481,86 @@ var DownstreamManager = class {
|
|
|
31316
31481
|
throw new CapletsError("DOWNSTREAM_TOOL_ERROR", `Downstream tool failed for ${server.server}/${toolName}`, toSafeError(error));
|
|
31317
31482
|
}
|
|
31318
31483
|
}
|
|
31484
|
+
async listResources(server, force = false) {
|
|
31485
|
+
const connection = await this.assertCapability(server, "resources");
|
|
31486
|
+
if (!force && connection.resources && this.isCacheFresh(connection.resourcesFetchedAt, server.toolCacheTtlMs)) return connection.resources;
|
|
31487
|
+
const resources = [];
|
|
31488
|
+
let cursor;
|
|
31489
|
+
do {
|
|
31490
|
+
const result = await connection.client.listResources(cursor ? { cursor } : void 0, { timeout: server.startupTimeoutMs });
|
|
31491
|
+
resources.push(...result.resources ?? []);
|
|
31492
|
+
cursor = result.nextCursor;
|
|
31493
|
+
} while (cursor);
|
|
31494
|
+
connection.resources = resources;
|
|
31495
|
+
connection.resourcesFetchedAt = Date.now();
|
|
31496
|
+
return resources;
|
|
31497
|
+
}
|
|
31498
|
+
async listResourceTemplates(server, force = false) {
|
|
31499
|
+
const connection = await this.assertCapability(server, "resources");
|
|
31500
|
+
if (!force && connection.resourceTemplates && this.isCacheFresh(connection.resourceTemplatesFetchedAt, server.toolCacheTtlMs)) return connection.resourceTemplates;
|
|
31501
|
+
const resourceTemplates = [];
|
|
31502
|
+
let cursor;
|
|
31503
|
+
do {
|
|
31504
|
+
const result = await connection.client.listResourceTemplates(cursor ? { cursor } : void 0, { timeout: server.startupTimeoutMs });
|
|
31505
|
+
resourceTemplates.push(...result.resourceTemplates ?? []);
|
|
31506
|
+
cursor = result.nextCursor;
|
|
31507
|
+
} while (cursor);
|
|
31508
|
+
connection.resourceTemplates = resourceTemplates;
|
|
31509
|
+
connection.resourceTemplatesFetchedAt = Date.now();
|
|
31510
|
+
return resourceTemplates;
|
|
31511
|
+
}
|
|
31512
|
+
async readResource(server, uri) {
|
|
31513
|
+
const connection = await this.assertCapability(server, "resources");
|
|
31514
|
+
try {
|
|
31515
|
+
return await connection.client.readResource({ uri }, { timeout: server.callTimeoutMs });
|
|
31516
|
+
} catch (error) {
|
|
31517
|
+
throw new CapletsError("DOWNSTREAM_RESOURCE_ERROR", `Downstream resource read failed for ${server.server}/${uri}`, toSafeError(error));
|
|
31518
|
+
}
|
|
31519
|
+
}
|
|
31520
|
+
async listPrompts(server, force = false) {
|
|
31521
|
+
const connection = await this.assertCapability(server, "prompts");
|
|
31522
|
+
if (!force && connection.prompts && this.isCacheFresh(connection.promptsFetchedAt, server.toolCacheTtlMs)) return connection.prompts;
|
|
31523
|
+
const prompts = [];
|
|
31524
|
+
let cursor;
|
|
31525
|
+
do {
|
|
31526
|
+
const result = await connection.client.listPrompts(cursor ? { cursor } : void 0, { timeout: server.startupTimeoutMs });
|
|
31527
|
+
prompts.push(...result.prompts ?? []);
|
|
31528
|
+
cursor = result.nextCursor;
|
|
31529
|
+
} while (cursor);
|
|
31530
|
+
connection.prompts = prompts;
|
|
31531
|
+
connection.promptsFetchedAt = Date.now();
|
|
31532
|
+
return prompts;
|
|
31533
|
+
}
|
|
31534
|
+
async getPrompt(server, promptName, args) {
|
|
31535
|
+
if (!(await this.listPrompts(server)).some((prompt) => prompt.name === promptName)) throw new CapletsError("PROMPT_NOT_FOUND", `Prompt ${promptName} was not found on ${server.server}`);
|
|
31536
|
+
const connection = await this.connect(server);
|
|
31537
|
+
try {
|
|
31538
|
+
return await connection.client.getPrompt({
|
|
31539
|
+
name: promptName,
|
|
31540
|
+
arguments: stringifyPromptArgs(args)
|
|
31541
|
+
}, { timeout: server.callTimeoutMs });
|
|
31542
|
+
} catch (error) {
|
|
31543
|
+
throw new CapletsError("DOWNSTREAM_PROMPT_ERROR", `Downstream prompt failed for ${server.server}/${promptName}`, toSafeError(error));
|
|
31544
|
+
}
|
|
31545
|
+
}
|
|
31546
|
+
async complete(server, request) {
|
|
31547
|
+
const connection = await this.assertCapability(server, "completions");
|
|
31548
|
+
const params = {
|
|
31549
|
+
ref: request.ref.type === "prompt" ? {
|
|
31550
|
+
type: "ref/prompt",
|
|
31551
|
+
name: request.ref.name
|
|
31552
|
+
} : {
|
|
31553
|
+
type: "ref/resource",
|
|
31554
|
+
uri: request.ref.uri
|
|
31555
|
+
},
|
|
31556
|
+
argument: request.argument
|
|
31557
|
+
};
|
|
31558
|
+
try {
|
|
31559
|
+
return await connection.client.complete(params, { timeout: server.callTimeoutMs });
|
|
31560
|
+
} catch (error) {
|
|
31561
|
+
throw new CapletsError("DOWNSTREAM_COMPLETION_ERROR", `Downstream completion failed for ${server.server}`, toSafeError(error));
|
|
31562
|
+
}
|
|
31563
|
+
}
|
|
31319
31564
|
compact(server, tool) {
|
|
31320
31565
|
return {
|
|
31321
31566
|
id: server.server,
|
|
@@ -31325,9 +31570,75 @@ var DownstreamManager = class {
|
|
|
31325
31570
|
hasOutputSchema: Boolean(tool.outputSchema)
|
|
31326
31571
|
};
|
|
31327
31572
|
}
|
|
31573
|
+
compactResource(server, resource) {
|
|
31574
|
+
return {
|
|
31575
|
+
id: server.server,
|
|
31576
|
+
kind: "resource",
|
|
31577
|
+
uri: resource.uri,
|
|
31578
|
+
...resource.name ? { name: resource.name } : {},
|
|
31579
|
+
...resource.description ? { description: resource.description } : {},
|
|
31580
|
+
...resource.mimeType ? { mimeType: resource.mimeType } : {},
|
|
31581
|
+
...typeof resource.size === "number" ? { size: resource.size } : {}
|
|
31582
|
+
};
|
|
31583
|
+
}
|
|
31584
|
+
compactResourceTemplate(server, template) {
|
|
31585
|
+
return {
|
|
31586
|
+
id: server.server,
|
|
31587
|
+
kind: "resourceTemplate",
|
|
31588
|
+
uriTemplate: template.uriTemplate,
|
|
31589
|
+
...template.name ? { name: template.name } : {},
|
|
31590
|
+
...template.description ? { description: template.description } : {},
|
|
31591
|
+
...template.mimeType ? { mimeType: template.mimeType } : {}
|
|
31592
|
+
};
|
|
31593
|
+
}
|
|
31594
|
+
compactPrompt(server, prompt) {
|
|
31595
|
+
return {
|
|
31596
|
+
id: server.server,
|
|
31597
|
+
prompt: prompt.name,
|
|
31598
|
+
...prompt.description ? { description: prompt.description } : {},
|
|
31599
|
+
...prompt.arguments ? { arguments: prompt.arguments } : {}
|
|
31600
|
+
};
|
|
31601
|
+
}
|
|
31602
|
+
searchResources(server, resources, query, limit) {
|
|
31603
|
+
const lower = query.toLocaleLowerCase();
|
|
31604
|
+
return resources.map((resource) => this.compactResource(server, resource)).filter((resource) => [
|
|
31605
|
+
resource.uri,
|
|
31606
|
+
resource.name,
|
|
31607
|
+
resource.description,
|
|
31608
|
+
resource.mimeType
|
|
31609
|
+
].some((value) => value?.toLocaleLowerCase().includes(lower))).slice(0, limit);
|
|
31610
|
+
}
|
|
31611
|
+
searchResourceTemplates(server, templates, query, limit) {
|
|
31612
|
+
const lower = query.toLocaleLowerCase();
|
|
31613
|
+
return templates.map((template) => this.compactResourceTemplate(server, template)).filter((template) => [
|
|
31614
|
+
template.uriTemplate,
|
|
31615
|
+
template.name,
|
|
31616
|
+
template.description,
|
|
31617
|
+
template.mimeType
|
|
31618
|
+
].some((value) => value?.toLocaleLowerCase().includes(lower))).slice(0, limit);
|
|
31619
|
+
}
|
|
31620
|
+
searchPrompts(server, prompts, query, limit) {
|
|
31621
|
+
const lower = query.toLocaleLowerCase();
|
|
31622
|
+
return prompts.map((prompt) => this.compactPrompt(server, prompt)).filter((prompt) => [
|
|
31623
|
+
prompt.prompt,
|
|
31624
|
+
prompt.description,
|
|
31625
|
+
...(prompt.arguments ?? []).flatMap((arg) => [arg.name, arg.description])
|
|
31626
|
+
].some((value) => value?.toLocaleLowerCase().includes(lower))).slice(0, limit);
|
|
31627
|
+
}
|
|
31328
31628
|
search(server, tools, query, limit) {
|
|
31329
31629
|
return searchToolList(tools, query, limit, (tool) => this.compact(server, tool));
|
|
31330
31630
|
}
|
|
31631
|
+
async assertCapability(server, capability) {
|
|
31632
|
+
const connection = await this.connect(server);
|
|
31633
|
+
if (!connection.client.getServerCapabilities()?.[capability]) throw new CapletsError("UNSUPPORTED_CAPABILITY", `${server.server} does not advertise MCP ${capability}`, {
|
|
31634
|
+
server: server.server,
|
|
31635
|
+
capability
|
|
31636
|
+
});
|
|
31637
|
+
return connection;
|
|
31638
|
+
}
|
|
31639
|
+
isCacheFresh(fetchedAt, ttlMs) {
|
|
31640
|
+
return fetchedAt !== void 0 && ttlMs > 0 && Date.now() - fetchedAt <= ttlMs;
|
|
31641
|
+
}
|
|
31331
31642
|
async refreshTools(server, force) {
|
|
31332
31643
|
const connection = await this.connect(server);
|
|
31333
31644
|
const now = Date.now();
|
|
@@ -31371,6 +31682,20 @@ var DownstreamManager = class {
|
|
|
31371
31682
|
transport,
|
|
31372
31683
|
configFingerprint: expectedFingerprint
|
|
31373
31684
|
};
|
|
31685
|
+
client.setNotificationHandler(ToolListChangedNotificationSchema, () => {
|
|
31686
|
+
connection.tools = void 0;
|
|
31687
|
+
connection.toolsFetchedAt = void 0;
|
|
31688
|
+
});
|
|
31689
|
+
client.setNotificationHandler(ResourceListChangedNotificationSchema, () => {
|
|
31690
|
+
connection.resources = void 0;
|
|
31691
|
+
connection.resourcesFetchedAt = void 0;
|
|
31692
|
+
connection.resourceTemplates = void 0;
|
|
31693
|
+
connection.resourceTemplatesFetchedAt = void 0;
|
|
31694
|
+
});
|
|
31695
|
+
client.setNotificationHandler(PromptListChangedNotificationSchema, () => {
|
|
31696
|
+
connection.prompts = void 0;
|
|
31697
|
+
connection.promptsFetchedAt = void 0;
|
|
31698
|
+
});
|
|
31374
31699
|
pendingConnection = connection;
|
|
31375
31700
|
this.connecting.set(server.server, connection);
|
|
31376
31701
|
transport.onclose = () => {
|
|
@@ -31501,6 +31826,18 @@ function nearbyToolNames(tools, needle) {
|
|
|
31501
31826
|
function isTimeoutLike(error) {
|
|
31502
31827
|
return error instanceof Error && /timeout|timed out|aborted/i.test(error.message);
|
|
31503
31828
|
}
|
|
31829
|
+
function stringifyPromptArgs(args) {
|
|
31830
|
+
const stringified = {};
|
|
31831
|
+
for (const [key, value] of Object.entries(args)) {
|
|
31832
|
+
if (typeof value === "string") {
|
|
31833
|
+
stringified[key] = value;
|
|
31834
|
+
continue;
|
|
31835
|
+
}
|
|
31836
|
+
const serialized = JSON.stringify(value);
|
|
31837
|
+
if (typeof serialized === "string") stringified[key] = serialized;
|
|
31838
|
+
}
|
|
31839
|
+
return stringified;
|
|
31840
|
+
}
|
|
31504
31841
|
function isAuthRemediationError(error) {
|
|
31505
31842
|
return error instanceof CapletsError && (error.code === "AUTH_REQUIRED" || error.code === "AUTH_FAILED");
|
|
31506
31843
|
}
|
|
@@ -56362,7 +56699,7 @@ function capabilityDescription(server) {
|
|
|
56362
56699
|
return [
|
|
56363
56700
|
`${server.name} Caplet.`,
|
|
56364
56701
|
server.description,
|
|
56365
|
-
"Use get_caplet for details when needed; use search_tools or list_tools to discover downstream operations."
|
|
56702
|
+
server.backend === "mcp" ? "Use get_caplet for details when needed; use tools for actions, resources for readable context, prompts for reusable workflows, and complete for prompt/resource-template arguments." : "Use get_caplet for details when needed; use search_tools or list_tools to discover downstream operations."
|
|
56366
56703
|
].filter(Boolean).join(" ");
|
|
56367
56704
|
}
|
|
56368
56705
|
var ServerRegistry = class {
|
|
@@ -56578,17 +56915,9 @@ function cloneJsonValue(value) {
|
|
|
56578
56915
|
function throwInvalid(message) {
|
|
56579
56916
|
throw new CapletsError("REQUEST_INVALID", message);
|
|
56580
56917
|
}
|
|
56581
|
-
const generatedToolInputSchema = object$1({
|
|
56582
|
-
operation: _enum(operations).describe(generatedToolInputDescriptions.operation),
|
|
56583
|
-
query: string().optional().describe(generatedToolInputDescriptions.query),
|
|
56584
|
-
limit: number$1().int().positive().optional().describe(generatedToolInputDescriptions.limit),
|
|
56585
|
-
tool: string().optional().describe(generatedToolInputDescriptions.tool),
|
|
56586
|
-
arguments: record(string(), unknown()).optional().describe(generatedToolInputDescriptions.arguments),
|
|
56587
|
-
fields: array(string().min(1)).min(1).optional().describe(generatedToolInputDescriptions.fields)
|
|
56588
|
-
}).strict();
|
|
56589
56918
|
async function handleServerTool(server, request, registry, downstream, openapi, graphql, http, cli, caplets) {
|
|
56590
56919
|
const startedAt = Date.now();
|
|
56591
|
-
const parsed = validateOperationRequest(request, registry.config.options.maxSearchLimit);
|
|
56920
|
+
const parsed = validateOperationRequest(request, registry.config.options.maxSearchLimit, server.backend);
|
|
56592
56921
|
switch (parsed.operation) {
|
|
56593
56922
|
case "get_caplet": return jsonResult(registry.detail(server), metadataFor(server, "get_caplet", void 0, startedAt));
|
|
56594
56923
|
case "check_backend": return jsonResult(await backendFor(server, downstream, openapi, graphql, http, cli, caplets).check(server), metadataFor(server, "check_backend", void 0, startedAt));
|
|
@@ -56629,11 +56958,75 @@ async function handleServerTool(server, request, registry, downstream, openapi,
|
|
|
56629
56958
|
validateFieldSelection(tool.outputSchema, parsed.fields);
|
|
56630
56959
|
return annotateCallToolResult(projectCallToolResult(await backend.callTool(server, parsed.tool, parsed.arguments), tool.outputSchema, parsed.fields), metadataFor(server, "call_tool", parsed.tool, startedAt));
|
|
56631
56960
|
}
|
|
56961
|
+
case "list_resources": {
|
|
56962
|
+
const backend = mcpBackendFor(server, downstream);
|
|
56963
|
+
const resources = await backend.listResources(server);
|
|
56964
|
+
const templates = await backend.listResourceTemplates(server);
|
|
56965
|
+
const limit = parsed.limit ?? resources.length + templates.length;
|
|
56966
|
+
return jsonResult({
|
|
56967
|
+
id: server.server,
|
|
56968
|
+
name: server.name,
|
|
56969
|
+
resources: resources.slice(0, limit).map((resource) => backend.compactResource(server, resource)),
|
|
56970
|
+
resourceTemplates: templates.slice(0, Math.max(0, limit - resources.length)).map((template) => backend.compactResourceTemplate(server, template))
|
|
56971
|
+
}, metadataFor(server, "list_resources", void 0, startedAt));
|
|
56972
|
+
}
|
|
56973
|
+
case "search_resources": {
|
|
56974
|
+
const backend = mcpBackendFor(server, downstream);
|
|
56975
|
+
const resources = await backend.listResources(server);
|
|
56976
|
+
const templates = await backend.listResourceTemplates(server);
|
|
56977
|
+
const limit = parsed.limit ?? registry.config.options.defaultSearchLimit;
|
|
56978
|
+
const resourceMatches = backend.searchResources(server, resources, parsed.query, limit);
|
|
56979
|
+
const templateMatches = backend.searchResourceTemplates(server, templates, parsed.query, Math.max(0, limit - resourceMatches.length));
|
|
56980
|
+
return jsonResult({
|
|
56981
|
+
id: server.server,
|
|
56982
|
+
name: server.name,
|
|
56983
|
+
query: parsed.query,
|
|
56984
|
+
matches: [...resourceMatches, ...templateMatches]
|
|
56985
|
+
}, metadataFor(server, "search_resources", void 0, startedAt));
|
|
56986
|
+
}
|
|
56987
|
+
case "list_resource_templates": {
|
|
56988
|
+
const backend = mcpBackendFor(server, downstream);
|
|
56989
|
+
const templates = await backend.listResourceTemplates(server);
|
|
56990
|
+
const limit = parsed.limit ?? templates.length;
|
|
56991
|
+
return jsonResult({
|
|
56992
|
+
id: server.server,
|
|
56993
|
+
name: server.name,
|
|
56994
|
+
resourceTemplates: templates.slice(0, limit).map((template) => backend.compactResourceTemplate(server, template))
|
|
56995
|
+
}, metadataFor(server, "list_resource_templates", void 0, startedAt));
|
|
56996
|
+
}
|
|
56997
|
+
case "read_resource": return annotateMcpResult(await mcpBackendFor(server, downstream).readResource(server, parsed.uri), metadataFor(server, "read_resource", { uri: parsed.uri }, startedAt));
|
|
56998
|
+
case "list_prompts": {
|
|
56999
|
+
const backend = mcpBackendFor(server, downstream);
|
|
57000
|
+
const prompts = await backend.listPrompts(server);
|
|
57001
|
+
const limit = parsed.limit ?? prompts.length;
|
|
57002
|
+
return jsonResult({
|
|
57003
|
+
id: server.server,
|
|
57004
|
+
name: server.name,
|
|
57005
|
+
prompts: prompts.slice(0, limit).map((prompt) => backend.compactPrompt(server, prompt))
|
|
57006
|
+
}, metadataFor(server, "list_prompts", void 0, startedAt));
|
|
57007
|
+
}
|
|
57008
|
+
case "search_prompts": {
|
|
57009
|
+
const backend = mcpBackendFor(server, downstream);
|
|
57010
|
+
const prompts = await backend.listPrompts(server);
|
|
57011
|
+
const limit = parsed.limit ?? registry.config.options.defaultSearchLimit;
|
|
57012
|
+
return jsonResult({
|
|
57013
|
+
id: server.server,
|
|
57014
|
+
name: server.name,
|
|
57015
|
+
query: parsed.query,
|
|
57016
|
+
prompts: backend.searchPrompts(server, prompts, parsed.query, limit)
|
|
57017
|
+
}, metadataFor(server, "search_prompts", void 0, startedAt));
|
|
57018
|
+
}
|
|
57019
|
+
case "get_prompt": return annotateMcpResult(await mcpBackendFor(server, downstream).getPrompt(server, parsed.prompt, parsed.arguments), metadataFor(server, "get_prompt", { prompt: parsed.prompt }, startedAt));
|
|
57020
|
+
case "complete": return annotateMcpResult(await mcpBackendFor(server, downstream).complete(server, {
|
|
57021
|
+
ref: parsed.ref,
|
|
57022
|
+
argument: parsed.argument
|
|
57023
|
+
}), metadataFor(server, "complete", void 0, startedAt));
|
|
56632
57024
|
}
|
|
56633
57025
|
}
|
|
56634
|
-
function validateOperationRequest(request, maxSearchLimit) {
|
|
56635
|
-
|
|
56636
|
-
|
|
57026
|
+
function validateOperationRequest(request, maxSearchLimit, backend = "tool") {
|
|
57027
|
+
const result = generatedToolInputSchemaForCaplet({ backend }).safeParse(request);
|
|
57028
|
+
if (request && typeof request === "object" && "operation" in request && typeof request.operation === "string" && !mcpOperations.includes(request.operation)) throw new CapletsError("UNKNOWN_OPERATION", `Unknown operation: ${request.operation}`);
|
|
57029
|
+
if (request && typeof request === "object" && "operation" in request && typeof request.operation === "string" && backend !== "mcp" && mcpOperations.includes(request.operation) && !operations.includes(request.operation)) throw new CapletsError("UNSUPPORTED_OPERATION", `${request.operation} is only available for MCP-backed Caplets`);
|
|
56637
57030
|
if (!result.success) throw new CapletsError("REQUEST_INVALID", "Generated server tool request is invalid", result.error.issues);
|
|
56638
57031
|
const value = result.data;
|
|
56639
57032
|
const keys = Object.keys(value).sort();
|
|
@@ -56680,7 +57073,7 @@ function validateOperationRequest(request, maxSearchLimit) {
|
|
|
56680
57073
|
"fields"
|
|
56681
57074
|
]);
|
|
56682
57075
|
if (!value.tool) throw new CapletsError("REQUEST_INVALID", "call_tool requires tool");
|
|
56683
|
-
if (!isPlainObject$
|
|
57076
|
+
if (!isPlainObject$7(value.arguments)) throw new CapletsError("REQUEST_INVALID", "call_tool.arguments must be a JSON object");
|
|
56684
57077
|
return value.fields === void 0 ? {
|
|
56685
57078
|
operation: "call_tool",
|
|
56686
57079
|
tool: value.tool,
|
|
@@ -56691,23 +57084,82 @@ function validateOperationRequest(request, maxSearchLimit) {
|
|
|
56691
57084
|
arguments: value.arguments,
|
|
56692
57085
|
fields: value.fields
|
|
56693
57086
|
};
|
|
57087
|
+
case "list_resources":
|
|
57088
|
+
case "list_resource_templates":
|
|
57089
|
+
case "list_prompts":
|
|
57090
|
+
allowed(["limit"]);
|
|
57091
|
+
if (value.limit !== void 0 && value.limit > maxSearchLimit) throw new CapletsError("REQUEST_INVALID", `${value.operation} limit must be <= ${maxSearchLimit}`);
|
|
57092
|
+
return value.limit === void 0 ? { operation: value.operation } : {
|
|
57093
|
+
operation: value.operation,
|
|
57094
|
+
limit: value.limit
|
|
57095
|
+
};
|
|
57096
|
+
case "search_resources":
|
|
57097
|
+
case "search_prompts":
|
|
57098
|
+
allowed(["query", "limit"]);
|
|
57099
|
+
if (!value.query) throw new CapletsError("REQUEST_INVALID", `${value.operation} requires query`);
|
|
57100
|
+
if (value.limit !== void 0 && value.limit > maxSearchLimit) throw new CapletsError("REQUEST_INVALID", `${value.operation} limit must be <= ${maxSearchLimit}`);
|
|
57101
|
+
return value.limit === void 0 ? {
|
|
57102
|
+
operation: value.operation,
|
|
57103
|
+
query: value.query
|
|
57104
|
+
} : {
|
|
57105
|
+
operation: value.operation,
|
|
57106
|
+
query: value.query,
|
|
57107
|
+
limit: value.limit
|
|
57108
|
+
};
|
|
57109
|
+
case "read_resource":
|
|
57110
|
+
allowed(["uri"]);
|
|
57111
|
+
if (!value.uri) throw new CapletsError("REQUEST_INVALID", "read_resource requires uri");
|
|
57112
|
+
return {
|
|
57113
|
+
operation: "read_resource",
|
|
57114
|
+
uri: value.uri
|
|
57115
|
+
};
|
|
57116
|
+
case "get_prompt":
|
|
57117
|
+
allowed(["prompt", "arguments"]);
|
|
57118
|
+
if (!value.prompt) throw new CapletsError("REQUEST_INVALID", "get_prompt requires prompt");
|
|
57119
|
+
if (value.arguments !== void 0 && !isPlainObject$7(value.arguments)) throw new CapletsError("REQUEST_INVALID", "get_prompt.arguments must be a JSON object");
|
|
57120
|
+
return {
|
|
57121
|
+
operation: "get_prompt",
|
|
57122
|
+
prompt: value.prompt,
|
|
57123
|
+
arguments: value.arguments ?? {}
|
|
57124
|
+
};
|
|
57125
|
+
case "complete":
|
|
57126
|
+
allowed(["ref", "argument"]);
|
|
57127
|
+
if (!value.ref) throw new CapletsError("REQUEST_INVALID", "complete requires ref");
|
|
57128
|
+
if (!value.argument) throw new CapletsError("REQUEST_INVALID", "complete requires argument");
|
|
57129
|
+
return {
|
|
57130
|
+
operation: "complete",
|
|
57131
|
+
ref: value.ref,
|
|
57132
|
+
argument: value.argument
|
|
57133
|
+
};
|
|
56694
57134
|
}
|
|
56695
|
-
|
|
57135
|
+
throw new CapletsError("INTERNAL_ERROR", "Unhandled operation");
|
|
56696
57136
|
}
|
|
56697
|
-
function
|
|
56698
|
-
throw new CapletsError("
|
|
57137
|
+
function mcpBackendFor(server, downstream) {
|
|
57138
|
+
if (server.backend !== "mcp") throw new CapletsError("UNSUPPORTED_OPERATION", "MCP resource, prompt, and completion operations require an MCP-backed Caplet");
|
|
57139
|
+
return downstream;
|
|
56699
57140
|
}
|
|
56700
|
-
function metadataFor(server, operation,
|
|
57141
|
+
function metadataFor(server, operation, target, startedAt) {
|
|
57142
|
+
const targetFields = typeof target === "string" ? { tool: target } : target ?? {};
|
|
56701
57143
|
return {
|
|
56702
57144
|
id: server.server,
|
|
56703
57145
|
name: server.name,
|
|
56704
57146
|
backend: server.backend,
|
|
56705
57147
|
operation,
|
|
56706
|
-
...
|
|
57148
|
+
...targetFields,
|
|
56707
57149
|
status: "ok",
|
|
56708
57150
|
...startedAt === void 0 ? {} : { elapsedMs: Date.now() - startedAt }
|
|
56709
57151
|
};
|
|
56710
57152
|
}
|
|
57153
|
+
function annotateMcpResult(result, metadata) {
|
|
57154
|
+
const existingMeta = result._meta;
|
|
57155
|
+
return {
|
|
57156
|
+
...result,
|
|
57157
|
+
_meta: {
|
|
57158
|
+
...isPlainObject$7(existingMeta) ? existingMeta : {},
|
|
57159
|
+
caplets: metadata
|
|
57160
|
+
}
|
|
57161
|
+
};
|
|
57162
|
+
}
|
|
56711
57163
|
function jsonResult(value, metadata) {
|
|
56712
57164
|
return {
|
|
56713
57165
|
content: [{
|
|
@@ -56731,7 +57183,7 @@ function annotateCallToolResult(result, metadata) {
|
|
|
56731
57183
|
return {
|
|
56732
57184
|
...result,
|
|
56733
57185
|
_meta: {
|
|
56734
|
-
...isPlainObject$
|
|
57186
|
+
...isPlainObject$7(existingMeta) ? existingMeta : {},
|
|
56735
57187
|
caplets: annotatedMetadata
|
|
56736
57188
|
}
|
|
56737
57189
|
};
|
|
@@ -56739,7 +57191,7 @@ function annotateCallToolResult(result, metadata) {
|
|
|
56739
57191
|
function projectCallToolResult(result, outputSchema, fields) {
|
|
56740
57192
|
if (result.isError === true) return result;
|
|
56741
57193
|
const structuredContent = result.structuredContent;
|
|
56742
|
-
if (!isPlainObject$
|
|
57194
|
+
if (!isPlainObject$7(structuredContent)) throw new CapletsError("DOWNSTREAM_PROTOCOL_ERROR", "Field selection requires the downstream tool to return object structuredContent");
|
|
56743
57195
|
const projected = projectStructuredContent(structuredContent, outputSchema, fields);
|
|
56744
57196
|
return {
|
|
56745
57197
|
...result,
|
|
@@ -56748,11 +57200,11 @@ function projectCallToolResult(result, outputSchema, fields) {
|
|
|
56748
57200
|
};
|
|
56749
57201
|
}
|
|
56750
57202
|
function extractArtifacts(result) {
|
|
56751
|
-
if (!isPlainObject$
|
|
57203
|
+
if (!isPlainObject$7(result) || !Array.isArray(result.content)) return [];
|
|
56752
57204
|
const artifacts = [];
|
|
56753
57205
|
const seen = /* @__PURE__ */ new Set();
|
|
56754
57206
|
for (const item of result.content) {
|
|
56755
|
-
if (!isPlainObject$
|
|
57207
|
+
if (!isPlainObject$7(item) || item.type !== "text" || typeof item.text !== "string") continue;
|
|
56756
57208
|
const text = item.text;
|
|
56757
57209
|
for (const link of parseMarkdownLinks(text)) {
|
|
56758
57210
|
const label = link.label;
|
|
@@ -56867,7 +57319,7 @@ function artifactKindFromText(text) {
|
|
|
56867
57319
|
if (/network[-_ ]?(?:log)?|har\b/.test(text)) return "network-log";
|
|
56868
57320
|
return "file";
|
|
56869
57321
|
}
|
|
56870
|
-
function isPlainObject$
|
|
57322
|
+
function isPlainObject$7(value) {
|
|
56871
57323
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
56872
57324
|
}
|
|
56873
57325
|
function backendFor(server, downstream, openapi, graphql, http, cli, caplets) {
|
|
@@ -57175,6 +57627,38 @@ var CapletsEngine = class {
|
|
|
57175
57627
|
return errorResult(error);
|
|
57176
57628
|
}
|
|
57177
57629
|
}
|
|
57630
|
+
async completeCliWords(words) {
|
|
57631
|
+
const { completeCliWords } = await Promise.resolve().then(() => completion_CxGG6ae3_exports).then((n) => n.r);
|
|
57632
|
+
return await completeCliWords(words, {
|
|
57633
|
+
config: this.registry.config,
|
|
57634
|
+
managers: {
|
|
57635
|
+
listTools: async (server) => this.listCompletionTools(server),
|
|
57636
|
+
listPrompts: async (server) => {
|
|
57637
|
+
if (server.backend !== "mcp") return [];
|
|
57638
|
+
return (await this.downstream.listPrompts(server)).map((prompt) => ({
|
|
57639
|
+
name: prompt.name,
|
|
57640
|
+
...prompt.description ? { description: prompt.description } : {}
|
|
57641
|
+
}));
|
|
57642
|
+
},
|
|
57643
|
+
listResources: async (server) => {
|
|
57644
|
+
if (server.backend !== "mcp") return [];
|
|
57645
|
+
return (await this.downstream.listResources(server)).map((resource) => ({
|
|
57646
|
+
uri: resource.uri,
|
|
57647
|
+
...resource.name ? { name: resource.name } : {},
|
|
57648
|
+
...resource.description ? { description: resource.description } : {}
|
|
57649
|
+
}));
|
|
57650
|
+
},
|
|
57651
|
+
listResourceTemplates: async (server) => {
|
|
57652
|
+
if (server.backend !== "mcp") return [];
|
|
57653
|
+
return (await this.downstream.listResourceTemplates(server)).map((template) => ({
|
|
57654
|
+
uriTemplate: template.uriTemplate,
|
|
57655
|
+
...template.name ? { name: template.name } : {},
|
|
57656
|
+
...template.description ? { description: template.description } : {}
|
|
57657
|
+
}));
|
|
57658
|
+
}
|
|
57659
|
+
}
|
|
57660
|
+
});
|
|
57661
|
+
}
|
|
57178
57662
|
async close() {
|
|
57179
57663
|
this.closed = true;
|
|
57180
57664
|
try {
|
|
@@ -57194,6 +57678,12 @@ var CapletsEngine = class {
|
|
|
57194
57678
|
this.reloadListeners.clear();
|
|
57195
57679
|
}
|
|
57196
57680
|
}
|
|
57681
|
+
async listCompletionTools(server) {
|
|
57682
|
+
return (server.backend === "mcp" ? await this.downstream.listTools(server) : server.backend === "openapi" ? await this.openapi.listTools(server) : server.backend === "graphql" ? await this.graphql.listTools(server) : server.backend === "http" ? await this.http.listTools(server) : server.backend === "cli" ? await this.cli.listTools(server) : await this.capletSets.listTools(server)).map((tool) => ({
|
|
57683
|
+
name: tool.name,
|
|
57684
|
+
...tool.description ? { description: tool.description } : {}
|
|
57685
|
+
}));
|
|
57686
|
+
}
|
|
57197
57687
|
async reloadOnce() {
|
|
57198
57688
|
if (this.closed) return false;
|
|
57199
57689
|
let nextConfig;
|
|
@@ -57476,6 +57966,565 @@ function hasEnv$1(value) {
|
|
|
57476
57966
|
return value !== void 0 && value.trim() !== "";
|
|
57477
57967
|
}
|
|
57478
57968
|
//#endregion
|
|
57969
|
+
//#region ../core/dist/completion-CxGG6ae3.js
|
|
57970
|
+
var completion_CxGG6ae3_exports = /* @__PURE__ */ __exportAll$1({
|
|
57971
|
+
a: () => formatCapletList,
|
|
57972
|
+
c: () => resolveCliConfigPaths,
|
|
57973
|
+
i: () => trailingSpaceCompletionToken,
|
|
57974
|
+
l: () => cliCommands,
|
|
57975
|
+
n: () => completionScript,
|
|
57976
|
+
o: () => formatConfigPaths,
|
|
57977
|
+
r: () => completion_exports,
|
|
57978
|
+
s: () => listCaplets,
|
|
57979
|
+
t: () => completeCliWords,
|
|
57980
|
+
u: () => completionShells
|
|
57981
|
+
});
|
|
57982
|
+
const completionShells = [
|
|
57983
|
+
"bash",
|
|
57984
|
+
"zsh",
|
|
57985
|
+
"fish",
|
|
57986
|
+
"powershell",
|
|
57987
|
+
"cmd"
|
|
57988
|
+
];
|
|
57989
|
+
const cliCommands = {
|
|
57990
|
+
completion: "completion",
|
|
57991
|
+
completeHidden: "__complete",
|
|
57992
|
+
serve: "serve",
|
|
57993
|
+
init: "init",
|
|
57994
|
+
list: "list",
|
|
57995
|
+
install: "install",
|
|
57996
|
+
add: "add",
|
|
57997
|
+
getCaplet: "get-caplet",
|
|
57998
|
+
checkBackend: "check-backend",
|
|
57999
|
+
listTools: "list-tools",
|
|
58000
|
+
searchTools: "search-tools",
|
|
58001
|
+
getTool: "get-tool",
|
|
58002
|
+
callTool: "call-tool",
|
|
58003
|
+
listResources: "list-resources",
|
|
58004
|
+
searchResources: "search-resources",
|
|
58005
|
+
listResourceTemplates: "list-resource-templates",
|
|
58006
|
+
readResource: "read-resource",
|
|
58007
|
+
listPrompts: "list-prompts",
|
|
58008
|
+
searchPrompts: "search-prompts",
|
|
58009
|
+
getPrompt: "get-prompt",
|
|
58010
|
+
complete: "complete",
|
|
58011
|
+
config: "config",
|
|
58012
|
+
auth: "auth"
|
|
58013
|
+
};
|
|
58014
|
+
const topLevelCommandNames = [
|
|
58015
|
+
cliCommands.serve,
|
|
58016
|
+
cliCommands.init,
|
|
58017
|
+
cliCommands.list,
|
|
58018
|
+
cliCommands.install,
|
|
58019
|
+
cliCommands.add,
|
|
58020
|
+
cliCommands.getCaplet,
|
|
58021
|
+
cliCommands.checkBackend,
|
|
58022
|
+
cliCommands.listTools,
|
|
58023
|
+
cliCommands.searchTools,
|
|
58024
|
+
cliCommands.getTool,
|
|
58025
|
+
cliCommands.callTool,
|
|
58026
|
+
cliCommands.listResources,
|
|
58027
|
+
cliCommands.searchResources,
|
|
58028
|
+
cliCommands.listResourceTemplates,
|
|
58029
|
+
cliCommands.readResource,
|
|
58030
|
+
cliCommands.listPrompts,
|
|
58031
|
+
cliCommands.searchPrompts,
|
|
58032
|
+
cliCommands.getPrompt,
|
|
58033
|
+
cliCommands.complete,
|
|
58034
|
+
cliCommands.config,
|
|
58035
|
+
cliCommands.auth,
|
|
58036
|
+
cliCommands.completion
|
|
58037
|
+
];
|
|
58038
|
+
const cliSubcommands = {
|
|
58039
|
+
[cliCommands.add]: [
|
|
58040
|
+
"cli",
|
|
58041
|
+
"mcp",
|
|
58042
|
+
"openapi",
|
|
58043
|
+
"graphql",
|
|
58044
|
+
"http"
|
|
58045
|
+
],
|
|
58046
|
+
[cliCommands.auth]: [
|
|
58047
|
+
"login",
|
|
58048
|
+
"logout",
|
|
58049
|
+
"list"
|
|
58050
|
+
],
|
|
58051
|
+
[cliCommands.completion]: [...completionShells],
|
|
58052
|
+
[cliCommands.config]: ["path", "paths"]
|
|
58053
|
+
};
|
|
58054
|
+
const capletIdCommands = new Set([
|
|
58055
|
+
cliCommands.getCaplet,
|
|
58056
|
+
cliCommands.checkBackend,
|
|
58057
|
+
cliCommands.listTools,
|
|
58058
|
+
cliCommands.searchTools,
|
|
58059
|
+
cliCommands.listResources,
|
|
58060
|
+
cliCommands.searchResources,
|
|
58061
|
+
cliCommands.listResourceTemplates,
|
|
58062
|
+
cliCommands.readResource,
|
|
58063
|
+
cliCommands.listPrompts,
|
|
58064
|
+
cliCommands.searchPrompts,
|
|
58065
|
+
cliCommands.complete
|
|
58066
|
+
]);
|
|
58067
|
+
const qualifiedToolCommands = new Set([cliCommands.getTool, cliCommands.callTool]);
|
|
58068
|
+
const qualifiedPromptCommands = new Set([cliCommands.getPrompt]);
|
|
58069
|
+
function listCaplets(configWithSources, options) {
|
|
58070
|
+
const { config, sources, shadows } = configWithSources;
|
|
58071
|
+
return allCaplets(config).filter((server) => options.includeDisabled || !server.disabled).map((server) => ({
|
|
58072
|
+
server: server.server,
|
|
58073
|
+
backend: server.backend,
|
|
58074
|
+
name: server.name,
|
|
58075
|
+
description: server.description,
|
|
58076
|
+
disabled: server.disabled,
|
|
58077
|
+
status: initialServerStatus(server),
|
|
58078
|
+
source: sources[server.server]?.kind ?? "unknown",
|
|
58079
|
+
path: sources[server.server]?.path ?? null,
|
|
58080
|
+
shadows: shadows[server.server] ?? []
|
|
58081
|
+
})).sort((left, right) => left.server.localeCompare(right.server));
|
|
58082
|
+
}
|
|
58083
|
+
function initialServerStatus(server) {
|
|
58084
|
+
return server.disabled ? "disabled" : "not_started";
|
|
58085
|
+
}
|
|
58086
|
+
function allCaplets(config) {
|
|
58087
|
+
return [
|
|
58088
|
+
...Object.values(config.mcpServers),
|
|
58089
|
+
...Object.values(config.openapiEndpoints),
|
|
58090
|
+
...Object.values(config.graphqlEndpoints),
|
|
58091
|
+
...Object.values(config.httpApis),
|
|
58092
|
+
...Object.values(config.cliTools)
|
|
58093
|
+
];
|
|
58094
|
+
}
|
|
58095
|
+
function formatCapletList(rows, format = "plain") {
|
|
58096
|
+
return format === "markdown" ? formatCapletListMarkdown(rows) : formatCapletListPlain(rows);
|
|
58097
|
+
}
|
|
58098
|
+
function formatCapletListMarkdown(rows) {
|
|
58099
|
+
if (rows.length === 0) return "## Configured Caplets\n\nNo configured Caplets found.\n";
|
|
58100
|
+
const heading = [
|
|
58101
|
+
"## Configured Caplets",
|
|
58102
|
+
"",
|
|
58103
|
+
`${rows.length} ${rows.length === 1 ? "Caplet" : "Caplets"} shown.`,
|
|
58104
|
+
""
|
|
58105
|
+
];
|
|
58106
|
+
const entries = rows.flatMap((row) => [
|
|
58107
|
+
`- \`${row.server}\` — ${row.name}`,
|
|
58108
|
+
` - Backend: ${row.backend}`,
|
|
58109
|
+
` - Status: ${row.status}`,
|
|
58110
|
+
` - Source: ${row.source}`,
|
|
58111
|
+
...row.disabled ? [" - Disabled: true"] : [],
|
|
58112
|
+
...row.path ? [` - Path: ${row.path}`] : []
|
|
58113
|
+
]);
|
|
58114
|
+
const warnings = rows.flatMap((row) => row.shadows.map((shadow) => `Warning: ${formatSourceKind(row.source)} Caplet ${row.server} shadows ${formatSourceKind(shadow.kind)} Caplet at ${shadow.path}`));
|
|
58115
|
+
if (warnings.length === 0) return `${[...heading, ...entries].join("\n")}\n`;
|
|
58116
|
+
return `${[
|
|
58117
|
+
...heading,
|
|
58118
|
+
...entries,
|
|
58119
|
+
"",
|
|
58120
|
+
"Warnings:",
|
|
58121
|
+
...warnings.map((warning) => `- ${warning}`)
|
|
58122
|
+
].join("\n")}\n`;
|
|
58123
|
+
}
|
|
58124
|
+
function formatCapletListPlain(rows) {
|
|
58125
|
+
if (rows.length === 0) return "No configured Caplets found.\n";
|
|
58126
|
+
const entries = rows.map((row) => [
|
|
58127
|
+
row.server,
|
|
58128
|
+
` Name: ${row.name}`,
|
|
58129
|
+
` Backend: ${row.backend}`,
|
|
58130
|
+
` Status: ${row.status}`,
|
|
58131
|
+
` Source: ${row.source}`,
|
|
58132
|
+
...row.disabled ? [" Disabled: true"] : [],
|
|
58133
|
+
...row.path ? [` Path: ${row.path}`] : []
|
|
58134
|
+
].join("\n")).join("\n\n");
|
|
58135
|
+
const warnings = rows.flatMap((row) => row.shadows.map((shadow) => `Warning: ${formatSourceKind(row.source)} Caplet ${row.server} shadows ${formatSourceKind(shadow.kind)} Caplet at ${shadow.path}`));
|
|
58136
|
+
if (warnings.length === 0) return `Configured Caplets (${rows.length})\n\n${entries}\n`;
|
|
58137
|
+
return `Configured Caplets (${rows.length})\n\n${entries}\n\n${warnings.join("\n")}\n`;
|
|
58138
|
+
}
|
|
58139
|
+
function formatSourceKind(kind) {
|
|
58140
|
+
if (kind.startsWith("project")) return "project";
|
|
58141
|
+
if (kind.startsWith("global")) return "global";
|
|
58142
|
+
return kind;
|
|
58143
|
+
}
|
|
58144
|
+
function resolveCliConfigPaths(envConfigPath, authDir) {
|
|
58145
|
+
const configPath = resolveConfigPath(envConfigPath);
|
|
58146
|
+
const effectiveAuthDir = authDir ?? DEFAULT_AUTH_DIR;
|
|
58147
|
+
return {
|
|
58148
|
+
userConfig: configPath,
|
|
58149
|
+
projectConfig: resolveProjectConfigPath(),
|
|
58150
|
+
userRoot: resolveCapletsRoot(configPath),
|
|
58151
|
+
stateRoot: dirname(effectiveAuthDir),
|
|
58152
|
+
projectRoot: resolveProjectCapletsRoot(),
|
|
58153
|
+
authDir: effectiveAuthDir,
|
|
58154
|
+
envConfig: envConfigPath ?? null
|
|
58155
|
+
};
|
|
58156
|
+
}
|
|
58157
|
+
function formatConfigPaths(paths, format = "plain") {
|
|
58158
|
+
if (format === "markdown") return formatConfigPathsMarkdown(paths);
|
|
58159
|
+
return formatConfigPathsPlain(paths);
|
|
58160
|
+
}
|
|
58161
|
+
function formatConfigPathsMarkdown(paths) {
|
|
58162
|
+
return [
|
|
58163
|
+
"## Caplets paths",
|
|
58164
|
+
"",
|
|
58165
|
+
`- User config: ${paths.userConfig}`,
|
|
58166
|
+
`- Project config: ${paths.projectConfig}`,
|
|
58167
|
+
`- User Caplets root: ${paths.userRoot}`,
|
|
58168
|
+
`- State root: ${paths.stateRoot}`,
|
|
58169
|
+
`- Project Caplets root: ${paths.projectRoot}`,
|
|
58170
|
+
`- Auth directory: ${paths.authDir}`,
|
|
58171
|
+
`- CAPLETS_CONFIG: ${paths.envConfig ?? "unset"}`
|
|
58172
|
+
].join("\n") + "\n";
|
|
58173
|
+
}
|
|
58174
|
+
function formatConfigPathsPlain(paths) {
|
|
58175
|
+
return [
|
|
58176
|
+
"Caplets paths",
|
|
58177
|
+
"",
|
|
58178
|
+
`User config: ${paths.userConfig}`,
|
|
58179
|
+
`Project config: ${paths.projectConfig}`,
|
|
58180
|
+
`User root: ${paths.userRoot}`,
|
|
58181
|
+
`State root: ${paths.stateRoot}`,
|
|
58182
|
+
`Project root: ${paths.projectRoot}`,
|
|
58183
|
+
`Auth directory: ${paths.authDir}`,
|
|
58184
|
+
`CAPLETS_CONFIG: ${paths.envConfig ?? "unset"}`
|
|
58185
|
+
].join("\n") + "\n";
|
|
58186
|
+
}
|
|
58187
|
+
function completionCacheKey(input) {
|
|
58188
|
+
return createHash("sha256").update(JSON.stringify(input)).digest("hex");
|
|
58189
|
+
}
|
|
58190
|
+
function readCompletionCacheEntry(cacheDir, key, now = Date.now()) {
|
|
58191
|
+
try {
|
|
58192
|
+
const parsed = JSON.parse(readFileSync(cachePath(cacheDir, key), "utf8"));
|
|
58193
|
+
if (parsed.status === "positive" && Array.isArray(parsed.candidates)) return {
|
|
58194
|
+
...parsed,
|
|
58195
|
+
fresh: now <= parsed.expiresAt
|
|
58196
|
+
};
|
|
58197
|
+
if (parsed.status === "negative" && typeof parsed.reason === "string") return {
|
|
58198
|
+
...parsed,
|
|
58199
|
+
fresh: now <= parsed.expiresAt
|
|
58200
|
+
};
|
|
58201
|
+
} catch {
|
|
58202
|
+
return;
|
|
58203
|
+
}
|
|
58204
|
+
}
|
|
58205
|
+
function writeCompletionCacheEntry(cacheDir, key, entry) {
|
|
58206
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
58207
|
+
const path = cachePath(cacheDir, key);
|
|
58208
|
+
const tempPath = `${path}.${process.pid}.tmp`;
|
|
58209
|
+
writeFileSync(tempPath, JSON.stringify(entry), { mode: 384 });
|
|
58210
|
+
renameSync(tempPath, path);
|
|
58211
|
+
}
|
|
58212
|
+
function cachePath(cacheDir, key) {
|
|
58213
|
+
return join(cacheDir, `${key}.json`);
|
|
58214
|
+
}
|
|
58215
|
+
async function discoverCompletionCandidates(serverId, kind, options) {
|
|
58216
|
+
const server = enabledServer(serverId, options.config);
|
|
58217
|
+
if (!server) return [];
|
|
58218
|
+
const completion = options.completion ?? options.config.options.completion;
|
|
58219
|
+
const now = options.now ?? Date.now();
|
|
58220
|
+
const configCandidates = configDefinedCandidates(serverId, kind, options.config);
|
|
58221
|
+
const cacheDir = options.cacheDir ?? DEFAULT_COMPLETION_CACHE_DIR;
|
|
58222
|
+
const key = completionCacheKey({
|
|
58223
|
+
server: server.server,
|
|
58224
|
+
backend: server.backend,
|
|
58225
|
+
kind,
|
|
58226
|
+
fingerprint: completionFingerprint(server, kind, completion)
|
|
58227
|
+
});
|
|
58228
|
+
const cached = readCompletionCacheEntry(cacheDir, key, now);
|
|
58229
|
+
if (cached?.status === "positive" && cached.fresh) return cached.candidates;
|
|
58230
|
+
if (cached?.status === "negative" && cached.fresh) return cached.candidates ?? configCandidates;
|
|
58231
|
+
try {
|
|
58232
|
+
const live = await withTimeout(liveCandidates(server, kind, options.managers), Math.min(completion.discoveryTimeoutMs, completion.overallTimeoutMs));
|
|
58233
|
+
const candidates = dedupeCandidates([...configCandidates, ...live]);
|
|
58234
|
+
writeCompletionCacheEntry(cacheDir, key, {
|
|
58235
|
+
status: "positive",
|
|
58236
|
+
fetchedAt: now,
|
|
58237
|
+
expiresAt: now + completion.cacheTtlMs,
|
|
58238
|
+
candidates
|
|
58239
|
+
});
|
|
58240
|
+
return candidates;
|
|
58241
|
+
} catch (error) {
|
|
58242
|
+
writeCompletionCacheEntry(cacheDir, key, {
|
|
58243
|
+
status: "negative",
|
|
58244
|
+
fetchedAt: now,
|
|
58245
|
+
expiresAt: now + completion.negativeCacheTtlMs,
|
|
58246
|
+
reason: negativeReason(error),
|
|
58247
|
+
...cached?.status === "positive" ? { candidates: cached.candidates } : {}
|
|
58248
|
+
});
|
|
58249
|
+
if (cached?.status === "positive") return cached.candidates;
|
|
58250
|
+
return configCandidates;
|
|
58251
|
+
}
|
|
58252
|
+
}
|
|
58253
|
+
function configDefinedCandidates(serverId, kind, config) {
|
|
58254
|
+
if (kind !== "tools") return [];
|
|
58255
|
+
const cli = config.cliTools[serverId];
|
|
58256
|
+
if (cli && !cli.disabled) return Object.keys(cli.actions).map((name) => ({ value: `${serverId}.${name}` }));
|
|
58257
|
+
const http = config.httpApis[serverId];
|
|
58258
|
+
if (http && !http.disabled) return Object.keys(http.actions).map((name) => ({ value: `${serverId}.${name}` }));
|
|
58259
|
+
const graphql = config.graphqlEndpoints[serverId];
|
|
58260
|
+
if (graphql && !graphql.disabled && graphql.operations) return Object.keys(graphql.operations).map((name) => ({ value: `${serverId}.${name}` }));
|
|
58261
|
+
return [];
|
|
58262
|
+
}
|
|
58263
|
+
async function liveCandidates(server, kind, managers) {
|
|
58264
|
+
if (kind === "tools" && managers?.listTools) return (await managers.listTools(server)).map((tool) => ({
|
|
58265
|
+
value: `${server.server}.${tool.name}`,
|
|
58266
|
+
description: tool.description
|
|
58267
|
+
}));
|
|
58268
|
+
if (kind === "tools") return [];
|
|
58269
|
+
if (server.backend !== "mcp") return [];
|
|
58270
|
+
if (kind === "prompts" && managers?.listPrompts) return (await managers.listPrompts(server)).map((prompt) => ({
|
|
58271
|
+
value: `${server.server}.${prompt.name}`,
|
|
58272
|
+
description: prompt.description
|
|
58273
|
+
}));
|
|
58274
|
+
if (kind === "resources" && managers?.listResources) return (await managers.listResources(server)).map((resource) => ({
|
|
58275
|
+
value: resource.uri,
|
|
58276
|
+
label: resource.name,
|
|
58277
|
+
description: resource.description
|
|
58278
|
+
}));
|
|
58279
|
+
if (kind === "resourceTemplates" && managers?.listResourceTemplates) return (await managers.listResourceTemplates(server)).map((template) => ({
|
|
58280
|
+
value: template.uriTemplate,
|
|
58281
|
+
label: template.name,
|
|
58282
|
+
description: template.description
|
|
58283
|
+
}));
|
|
58284
|
+
throw new CapletsError("UNSUPPORTED_CAPABILITY", `Completion discovery is unsupported for ${kind}`);
|
|
58285
|
+
}
|
|
58286
|
+
function completionFingerprint(server, kind, completion) {
|
|
58287
|
+
return JSON.stringify({
|
|
58288
|
+
kind,
|
|
58289
|
+
completion: {
|
|
58290
|
+
discoveryTimeoutMs: completion.discoveryTimeoutMs,
|
|
58291
|
+
cacheTtlMs: completion.cacheTtlMs,
|
|
58292
|
+
negativeCacheTtlMs: completion.negativeCacheTtlMs
|
|
58293
|
+
},
|
|
58294
|
+
server: secretFreeServerShape(server)
|
|
58295
|
+
});
|
|
58296
|
+
}
|
|
58297
|
+
function secretFreeServerShape(server) {
|
|
58298
|
+
const base = {
|
|
58299
|
+
server: server.server,
|
|
58300
|
+
backend: server.backend,
|
|
58301
|
+
name: server.name,
|
|
58302
|
+
description: server.description,
|
|
58303
|
+
tags: server.tags,
|
|
58304
|
+
disabled: server.disabled
|
|
58305
|
+
};
|
|
58306
|
+
switch (server.backend) {
|
|
58307
|
+
case "mcp": return {
|
|
58308
|
+
...base,
|
|
58309
|
+
transport: server.transport,
|
|
58310
|
+
command: server.command,
|
|
58311
|
+
args: server.args,
|
|
58312
|
+
cwd: server.cwd,
|
|
58313
|
+
url: server.url,
|
|
58314
|
+
authType: server.auth?.type,
|
|
58315
|
+
startupTimeoutMs: server.startupTimeoutMs,
|
|
58316
|
+
callTimeoutMs: server.callTimeoutMs
|
|
58317
|
+
};
|
|
58318
|
+
case "openapi": return {
|
|
58319
|
+
...base,
|
|
58320
|
+
specPath: server.specPath,
|
|
58321
|
+
specUrl: server.specUrl,
|
|
58322
|
+
baseUrl: server.baseUrl,
|
|
58323
|
+
authType: server.auth.type,
|
|
58324
|
+
requestTimeoutMs: server.requestTimeoutMs
|
|
58325
|
+
};
|
|
58326
|
+
case "graphql": return {
|
|
58327
|
+
...base,
|
|
58328
|
+
endpointUrl: server.endpointUrl,
|
|
58329
|
+
schemaPath: server.schemaPath,
|
|
58330
|
+
schemaUrl: server.schemaUrl,
|
|
58331
|
+
authType: server.auth.type,
|
|
58332
|
+
operationNames: server.operations ? Object.keys(server.operations) : void 0
|
|
58333
|
+
};
|
|
58334
|
+
case "http": return {
|
|
58335
|
+
...base,
|
|
58336
|
+
baseUrl: server.baseUrl,
|
|
58337
|
+
authType: server.auth.type,
|
|
58338
|
+
actions: Object.fromEntries(Object.entries(server.actions).map(([name, action]) => [name, {
|
|
58339
|
+
method: action.method,
|
|
58340
|
+
path: action.path
|
|
58341
|
+
}])),
|
|
58342
|
+
requestTimeoutMs: server.requestTimeoutMs
|
|
58343
|
+
};
|
|
58344
|
+
case "cli": return {
|
|
58345
|
+
...base,
|
|
58346
|
+
cwd: server.cwd,
|
|
58347
|
+
actions: Object.fromEntries(Object.entries(server.actions).map(([name, action]) => [name, {
|
|
58348
|
+
command: action.command,
|
|
58349
|
+
args: action.args,
|
|
58350
|
+
cwd: action.cwd
|
|
58351
|
+
}])),
|
|
58352
|
+
timeoutMs: server.timeoutMs,
|
|
58353
|
+
maxOutputBytes: server.maxOutputBytes
|
|
58354
|
+
};
|
|
58355
|
+
case "caplets": return {
|
|
58356
|
+
...base,
|
|
58357
|
+
configPath: server.configPath,
|
|
58358
|
+
capletsRoot: server.capletsRoot,
|
|
58359
|
+
defaultSearchLimit: server.defaultSearchLimit,
|
|
58360
|
+
maxSearchLimit: server.maxSearchLimit
|
|
58361
|
+
};
|
|
58362
|
+
}
|
|
58363
|
+
}
|
|
58364
|
+
function negativeReason(error) {
|
|
58365
|
+
if (error instanceof CapletsError) {
|
|
58366
|
+
if (error.code === "AUTH_REQUIRED" || error.code === "AUTH_FAILED" || error.code === "AUTH_REFRESH_FAILED") return "auth_required";
|
|
58367
|
+
if (error.code === "SERVER_UNAVAILABLE" || error.code === "SERVER_START_TIMEOUT") return "unavailable";
|
|
58368
|
+
if (error.code === "UNSUPPORTED_CAPABILITY" || error.code === "UNSUPPORTED_OPERATION") return "unsupported";
|
|
58369
|
+
if (error.code === "TOOL_CALL_TIMEOUT" || error.code === "DOWNSTREAM_COMPLETION_ERROR") return "timeout";
|
|
58370
|
+
}
|
|
58371
|
+
return error instanceof Error && error.message.includes("timeout") ? "timeout" : "error";
|
|
58372
|
+
}
|
|
58373
|
+
async function withTimeout(promise, timeoutMs) {
|
|
58374
|
+
let timeout;
|
|
58375
|
+
try {
|
|
58376
|
+
return await Promise.race([promise, new Promise((_, reject) => {
|
|
58377
|
+
timeout = setTimeout(() => reject(/* @__PURE__ */ new Error("completion discovery timeout")), timeoutMs);
|
|
58378
|
+
})]);
|
|
58379
|
+
} finally {
|
|
58380
|
+
if (timeout) clearTimeout(timeout);
|
|
58381
|
+
}
|
|
58382
|
+
}
|
|
58383
|
+
function enabledServer(serverId, config) {
|
|
58384
|
+
const server = config.mcpServers[serverId] ?? config.openapiEndpoints[serverId] ?? config.graphqlEndpoints[serverId] ?? config.httpApis[serverId] ?? config.cliTools[serverId] ?? config.capletSets[serverId];
|
|
58385
|
+
return server && !server.disabled ? server : void 0;
|
|
58386
|
+
}
|
|
58387
|
+
function dedupeCandidates(candidates) {
|
|
58388
|
+
const seen = /* @__PURE__ */ new Set();
|
|
58389
|
+
return candidates.filter((candidate) => {
|
|
58390
|
+
if (seen.has(candidate.value)) return false;
|
|
58391
|
+
seen.add(candidate.value);
|
|
58392
|
+
return true;
|
|
58393
|
+
});
|
|
58394
|
+
}
|
|
58395
|
+
var completion_exports = /* @__PURE__ */ __exportAll({
|
|
58396
|
+
completeCliWords: () => completeCliWords,
|
|
58397
|
+
completionScript: () => completionScript,
|
|
58398
|
+
trailingSpaceCompletionToken: () => trailingSpaceCompletionToken
|
|
58399
|
+
});
|
|
58400
|
+
const trailingSpaceCompletionToken = "__CAPLETS_TRAILING_SPACE__";
|
|
58401
|
+
const optionValueSuggestions = {
|
|
58402
|
+
"*": { "--format": [
|
|
58403
|
+
"markdown",
|
|
58404
|
+
"md",
|
|
58405
|
+
"plain",
|
|
58406
|
+
"json"
|
|
58407
|
+
] },
|
|
58408
|
+
serve: { "--transport": ["stdio", "http"] },
|
|
58409
|
+
"add:mcp": { "--transport": ["http", "sse"] },
|
|
58410
|
+
"add:cli": { "--include": [
|
|
58411
|
+
"git",
|
|
58412
|
+
"gh",
|
|
58413
|
+
"package"
|
|
58414
|
+
] }
|
|
58415
|
+
};
|
|
58416
|
+
function completionScript(shell) {
|
|
58417
|
+
switch (shell) {
|
|
58418
|
+
case "bash": return bashCompletionScript();
|
|
58419
|
+
case "zsh": return zshCompletionScript();
|
|
58420
|
+
case "fish": return fishCompletionScript();
|
|
58421
|
+
case "powershell": return powershellCompletionScript();
|
|
58422
|
+
case "cmd": return cmdCompletionScript();
|
|
58423
|
+
default: throw new CapletsError("REQUEST_INVALID", "completion shell must be bash, zsh, fish, powershell, or cmd");
|
|
58424
|
+
}
|
|
58425
|
+
}
|
|
58426
|
+
async function completeCliWords(words, options = {}) {
|
|
58427
|
+
try {
|
|
58428
|
+
const normalized = words.length === 0 ? [""] : words;
|
|
58429
|
+
const current = normalized.at(-1) ?? "";
|
|
58430
|
+
const previous = normalized.at(-2);
|
|
58431
|
+
const command = normalized[0] ?? "";
|
|
58432
|
+
const subcommand = normalized[1] ?? "";
|
|
58433
|
+
if (command === cliCommands.complete && previous === "--prompt" && subcommand) return prefixFilter((await discoverCompletionCandidates(subcommand, "prompts", discoveryOptions(options))).map((candidate) => candidate.value.replace(`${subcommand}.`, "")), current);
|
|
58434
|
+
if (command === cliCommands.complete && previous === "--resource-template" && subcommand) return prefixFilter((await discoverCompletionCandidates(subcommand, "resourceTemplates", discoveryOptions(options))).map((candidate) => candidate.value), current);
|
|
58435
|
+
const optionValues = suggestionsForOptionValue(command, subcommand, previous);
|
|
58436
|
+
if (optionValues) return prefixFilter(optionValues, current);
|
|
58437
|
+
if (normalized.length === 1) return prefixFilter([...topLevelCommandNames], current);
|
|
58438
|
+
if (normalized.length === 2 && command in cliSubcommands) return prefixFilter(cliSubcommands[command], current);
|
|
58439
|
+
if (normalized.length === 2 && capletIdCommands.has(command)) return prefixFilter(promptResourceCommands.has(command) ? configuredCapletIds(options, { backend: "mcp" }) : configuredCapletIds(options), current);
|
|
58440
|
+
if (normalized.length === 2 && (qualifiedToolCommands.has(command) || qualifiedPromptCommands.has(command))) {
|
|
58441
|
+
if (current.includes(".")) return prefixFilter((await discoverCompletionCandidates(current.slice(0, current.indexOf(".")), qualifiedToolCommands.has(command) ? "tools" : "prompts", discoveryOptions(options))).map((candidate) => candidate.value), current);
|
|
58442
|
+
return prefixFilter(configuredCapletIds(options, qualifiedPromptCommands.has(command) ? { backend: "mcp" } : void 0).map((id) => `${id}.`), current);
|
|
58443
|
+
}
|
|
58444
|
+
if (command === cliCommands.readResource && normalized.length === 3) return prefixFilter((await discoverCompletionCandidates(subcommand, "resources", discoveryOptions(options))).map((candidate) => candidate.value), current);
|
|
58445
|
+
if (command === cliCommands.auth && ["login", "logout"].includes(subcommand) && normalized.length === 3) return prefixFilter(configuredCapletIds(options), current);
|
|
58446
|
+
return [];
|
|
58447
|
+
} catch {
|
|
58448
|
+
return [];
|
|
58449
|
+
}
|
|
58450
|
+
}
|
|
58451
|
+
function suggestionsForOptionValue(command, subcommand, previous) {
|
|
58452
|
+
if (!previous) return void 0;
|
|
58453
|
+
return optionValueSuggestions[`${command}:${subcommand}`]?.[previous] ?? optionValueSuggestions[command]?.[previous] ?? optionValueSuggestions["*"]?.[previous];
|
|
58454
|
+
}
|
|
58455
|
+
const promptResourceCommands = new Set([
|
|
58456
|
+
cliCommands.getPrompt,
|
|
58457
|
+
cliCommands.readResource,
|
|
58458
|
+
cliCommands.complete
|
|
58459
|
+
]);
|
|
58460
|
+
function configuredCapletIds(options, filter = {}) {
|
|
58461
|
+
return listCaplets(options.config ? {
|
|
58462
|
+
config: options.config,
|
|
58463
|
+
sources: {},
|
|
58464
|
+
shadows: {}
|
|
58465
|
+
} : loadConfigWithSources(options.configPath, options.projectConfigPath), { includeDisabled: false }).filter((row) => !filter.backend || row.backend === filter.backend).map((row) => row.server);
|
|
58466
|
+
}
|
|
58467
|
+
function discoveryOptions(options) {
|
|
58468
|
+
return {
|
|
58469
|
+
config: options.config ?? loadConfigWithSources(options.configPath, options.projectConfigPath).config,
|
|
58470
|
+
completion: options.completion,
|
|
58471
|
+
cacheDir: options.cacheDir,
|
|
58472
|
+
managers: options.managers
|
|
58473
|
+
};
|
|
58474
|
+
}
|
|
58475
|
+
function prefixFilter(values, prefix) {
|
|
58476
|
+
return values.filter((value) => value.startsWith(prefix));
|
|
58477
|
+
}
|
|
58478
|
+
function bashCompletionScript() {
|
|
58479
|
+
return `# caplets bash completion
|
|
58480
|
+
_caplets_completions() {
|
|
58481
|
+
local IFS=$'\n'
|
|
58482
|
+
COMPREPLY=( $(caplets __complete --shell bash -- "\${COMP_WORDS[@]:1}" 2>/dev/null) )
|
|
58483
|
+
}
|
|
58484
|
+
complete -o default -F _caplets_completions caplets
|
|
58485
|
+
`;
|
|
58486
|
+
}
|
|
58487
|
+
function zshCompletionScript() {
|
|
58488
|
+
return `#compdef caplets
|
|
58489
|
+
_caplets() {
|
|
58490
|
+
local -a suggestions
|
|
58491
|
+
suggestions=("\${(@f)$(caplets __complete --shell zsh -- "\${words[@]:1}" 2>/dev/null)}")
|
|
58492
|
+
compadd -- $suggestions
|
|
58493
|
+
}
|
|
58494
|
+
_caplets "$@"
|
|
58495
|
+
`;
|
|
58496
|
+
}
|
|
58497
|
+
function fishCompletionScript() {
|
|
58498
|
+
return `# caplets fish completion
|
|
58499
|
+
function __caplets_complete
|
|
58500
|
+
set -l tokens (commandline -opc)
|
|
58501
|
+
set -l current (commandline -ct)
|
|
58502
|
+
caplets __complete --shell fish -- $tokens[2..-1] $current 2>/dev/null
|
|
58503
|
+
end
|
|
58504
|
+
complete -c caplets -f -a '(__caplets_complete)'
|
|
58505
|
+
`;
|
|
58506
|
+
}
|
|
58507
|
+
function powershellCompletionScript() {
|
|
58508
|
+
return `# caplets PowerShell completion
|
|
58509
|
+
Register-ArgumentCompleter -Native -CommandName caplets -ScriptBlock {
|
|
58510
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
58511
|
+
$tokens = @($commandAst.CommandElements | Select-Object -Skip 1 | ForEach-Object { $_.ToString() })
|
|
58512
|
+
if ($tokens.Count -eq 0 -or $commandAst.Extent.Text.EndsWith(' ')) { $tokens += '${trailingSpaceCompletionToken}' }
|
|
58513
|
+
caplets __complete --shell powershell -- @tokens 2>$null | ForEach-Object {
|
|
58514
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
58515
|
+
}
|
|
58516
|
+
}
|
|
58517
|
+
`;
|
|
58518
|
+
}
|
|
58519
|
+
function cmdCompletionScript() {
|
|
58520
|
+
return `@echo off
|
|
58521
|
+
REM caplets cmd completion helper
|
|
58522
|
+
REM cmd.exe has no native programmable completion API. This doskey macro prints suggestions for the current words.
|
|
58523
|
+
doskey caplets-complete=caplets __complete --shell cmd -- $* 2^>nul
|
|
58524
|
+
REM Usage: caplets-complete get-caplet
|
|
58525
|
+
`;
|
|
58526
|
+
}
|
|
58527
|
+
//#endregion
|
|
57479
58528
|
//#region ../core/dist/index.js
|
|
57480
58529
|
/**
|
|
57481
58530
|
* Experimental server task features for MCP SDK.
|
|
@@ -58773,7 +59822,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
|
|
|
58773
59822
|
values: [],
|
|
58774
59823
|
hasMore: false
|
|
58775
59824
|
} };
|
|
58776
|
-
var version$1 = "0.
|
|
59825
|
+
var version$1 = "0.18.0";
|
|
58777
59826
|
var CapletsMcpSession = class {
|
|
58778
59827
|
engine;
|
|
58779
59828
|
server;
|
|
@@ -58815,6 +59864,7 @@ var CapletsMcpSession = class {
|
|
|
58815
59864
|
if (!previousCaplet || serializeCaplet(previousCaplet) !== serializeCaplet(caplet)) tool.update({
|
|
58816
59865
|
title: caplet.name,
|
|
58817
59866
|
description: capabilityDescription(caplet),
|
|
59867
|
+
paramsSchema: generatedToolInputSchemaForCaplet(caplet).shape,
|
|
58818
59868
|
callback: async (request) => this.handleTool(serverId, request),
|
|
58819
59869
|
enabled: true
|
|
58820
59870
|
});
|
|
@@ -58828,7 +59878,7 @@ var CapletsMcpSession = class {
|
|
|
58828
59878
|
return this.server.registerTool(caplet.server, {
|
|
58829
59879
|
title: caplet.name,
|
|
58830
59880
|
description: capabilityDescription(caplet),
|
|
58831
|
-
inputSchema:
|
|
59881
|
+
inputSchema: generatedToolInputSchemaForCaplet(caplet).shape
|
|
58832
59882
|
}, async (request) => this.handleTool(caplet.server, request));
|
|
58833
59883
|
}
|
|
58834
59884
|
async handleTool(serverId, request) {
|
|
@@ -62424,124 +63474,6 @@ function starterConfig() {
|
|
|
62424
63474
|
} }
|
|
62425
63475
|
}, null, 2);
|
|
62426
63476
|
}
|
|
62427
|
-
function listCaplets(configWithSources, options) {
|
|
62428
|
-
const { config, sources, shadows } = configWithSources;
|
|
62429
|
-
return allCaplets(config).filter((server) => options.includeDisabled || !server.disabled).map((server) => ({
|
|
62430
|
-
server: server.server,
|
|
62431
|
-
backend: server.backend,
|
|
62432
|
-
name: server.name,
|
|
62433
|
-
description: server.description,
|
|
62434
|
-
disabled: server.disabled,
|
|
62435
|
-
status: initialServerStatus(server),
|
|
62436
|
-
source: sources[server.server]?.kind ?? "unknown",
|
|
62437
|
-
path: sources[server.server]?.path ?? null,
|
|
62438
|
-
shadows: shadows[server.server] ?? []
|
|
62439
|
-
})).sort((left, right) => left.server.localeCompare(right.server));
|
|
62440
|
-
}
|
|
62441
|
-
function initialServerStatus(server) {
|
|
62442
|
-
return server.disabled ? "disabled" : "not_started";
|
|
62443
|
-
}
|
|
62444
|
-
function allCaplets(config) {
|
|
62445
|
-
return [
|
|
62446
|
-
...Object.values(config.mcpServers),
|
|
62447
|
-
...Object.values(config.openapiEndpoints),
|
|
62448
|
-
...Object.values(config.graphqlEndpoints),
|
|
62449
|
-
...Object.values(config.httpApis),
|
|
62450
|
-
...Object.values(config.cliTools)
|
|
62451
|
-
];
|
|
62452
|
-
}
|
|
62453
|
-
function formatCapletList(rows, format = "plain") {
|
|
62454
|
-
return format === "markdown" ? formatCapletListMarkdown(rows) : formatCapletListPlain(rows);
|
|
62455
|
-
}
|
|
62456
|
-
function formatCapletListMarkdown(rows) {
|
|
62457
|
-
if (rows.length === 0) return "## Configured Caplets\n\nNo configured Caplets found.\n";
|
|
62458
|
-
const heading = [
|
|
62459
|
-
"## Configured Caplets",
|
|
62460
|
-
"",
|
|
62461
|
-
`${rows.length} ${rows.length === 1 ? "Caplet" : "Caplets"} shown.`,
|
|
62462
|
-
""
|
|
62463
|
-
];
|
|
62464
|
-
const entries = rows.flatMap((row) => [
|
|
62465
|
-
`- \`${row.server}\` — ${row.name}`,
|
|
62466
|
-
` - Backend: ${row.backend}`,
|
|
62467
|
-
` - Status: ${row.status}`,
|
|
62468
|
-
` - Source: ${row.source}`,
|
|
62469
|
-
...row.disabled ? [" - Disabled: true"] : [],
|
|
62470
|
-
...row.path ? [` - Path: ${row.path}`] : []
|
|
62471
|
-
]);
|
|
62472
|
-
const warnings = rows.flatMap((row) => row.shadows.map((shadow) => `Warning: ${formatSourceKind(row.source)} Caplet ${row.server} shadows ${formatSourceKind(shadow.kind)} Caplet at ${shadow.path}`));
|
|
62473
|
-
if (warnings.length === 0) return `${[...heading, ...entries].join("\n")}\n`;
|
|
62474
|
-
return `${[
|
|
62475
|
-
...heading,
|
|
62476
|
-
...entries,
|
|
62477
|
-
"",
|
|
62478
|
-
"Warnings:",
|
|
62479
|
-
...warnings.map((warning) => `- ${warning}`)
|
|
62480
|
-
].join("\n")}\n`;
|
|
62481
|
-
}
|
|
62482
|
-
function formatCapletListPlain(rows) {
|
|
62483
|
-
if (rows.length === 0) return "No configured Caplets found.\n";
|
|
62484
|
-
const entries = rows.map((row) => [
|
|
62485
|
-
row.server,
|
|
62486
|
-
` Name: ${row.name}`,
|
|
62487
|
-
` Backend: ${row.backend}`,
|
|
62488
|
-
` Status: ${row.status}`,
|
|
62489
|
-
` Source: ${row.source}`,
|
|
62490
|
-
...row.disabled ? [" Disabled: true"] : [],
|
|
62491
|
-
...row.path ? [` Path: ${row.path}`] : []
|
|
62492
|
-
].join("\n")).join("\n\n");
|
|
62493
|
-
const warnings = rows.flatMap((row) => row.shadows.map((shadow) => `Warning: ${formatSourceKind(row.source)} Caplet ${row.server} shadows ${formatSourceKind(shadow.kind)} Caplet at ${shadow.path}`));
|
|
62494
|
-
if (warnings.length === 0) return `Configured Caplets (${rows.length})\n\n${entries}\n`;
|
|
62495
|
-
return `Configured Caplets (${rows.length})\n\n${entries}\n\n${warnings.join("\n")}\n`;
|
|
62496
|
-
}
|
|
62497
|
-
function formatSourceKind(kind) {
|
|
62498
|
-
if (kind.startsWith("project")) return "project";
|
|
62499
|
-
if (kind.startsWith("global")) return "global";
|
|
62500
|
-
return kind;
|
|
62501
|
-
}
|
|
62502
|
-
function resolveCliConfigPaths(envConfigPath, authDir) {
|
|
62503
|
-
const configPath = resolveConfigPath(envConfigPath);
|
|
62504
|
-
const effectiveAuthDir = authDir ?? DEFAULT_AUTH_DIR;
|
|
62505
|
-
return {
|
|
62506
|
-
userConfig: configPath,
|
|
62507
|
-
projectConfig: resolveProjectConfigPath(),
|
|
62508
|
-
userRoot: resolveCapletsRoot(configPath),
|
|
62509
|
-
stateRoot: dirname(effectiveAuthDir),
|
|
62510
|
-
projectRoot: resolveProjectCapletsRoot(),
|
|
62511
|
-
authDir: effectiveAuthDir,
|
|
62512
|
-
envConfig: envConfigPath ?? null
|
|
62513
|
-
};
|
|
62514
|
-
}
|
|
62515
|
-
function formatConfigPaths(paths, format = "plain") {
|
|
62516
|
-
if (format === "markdown") return formatConfigPathsMarkdown(paths);
|
|
62517
|
-
return formatConfigPathsPlain(paths);
|
|
62518
|
-
}
|
|
62519
|
-
function formatConfigPathsMarkdown(paths) {
|
|
62520
|
-
return [
|
|
62521
|
-
"## Caplets paths",
|
|
62522
|
-
"",
|
|
62523
|
-
`- User config: ${paths.userConfig}`,
|
|
62524
|
-
`- Project config: ${paths.projectConfig}`,
|
|
62525
|
-
`- User Caplets root: ${paths.userRoot}`,
|
|
62526
|
-
`- State root: ${paths.stateRoot}`,
|
|
62527
|
-
`- Project Caplets root: ${paths.projectRoot}`,
|
|
62528
|
-
`- Auth directory: ${paths.authDir}`,
|
|
62529
|
-
`- CAPLETS_CONFIG: ${paths.envConfig ?? "unset"}`
|
|
62530
|
-
].join("\n") + "\n";
|
|
62531
|
-
}
|
|
62532
|
-
function formatConfigPathsPlain(paths) {
|
|
62533
|
-
return [
|
|
62534
|
-
"Caplets paths",
|
|
62535
|
-
"",
|
|
62536
|
-
`User config: ${paths.userConfig}`,
|
|
62537
|
-
`Project config: ${paths.projectConfig}`,
|
|
62538
|
-
`User root: ${paths.userRoot}`,
|
|
62539
|
-
`State root: ${paths.stateRoot}`,
|
|
62540
|
-
`Project root: ${paths.projectRoot}`,
|
|
62541
|
-
`Auth directory: ${paths.authDir}`,
|
|
62542
|
-
`CAPLETS_CONFIG: ${paths.envConfig ?? "unset"}`
|
|
62543
|
-
].join("\n") + "\n";
|
|
62544
|
-
}
|
|
62545
63477
|
function installCaplets(repo, options = {}) {
|
|
62546
63478
|
const source = resolveInstallSource(repo);
|
|
62547
63479
|
try {
|
|
@@ -65738,7 +66670,15 @@ const ENGINE_COMMANDS = new Set([
|
|
|
65738
66670
|
"list_tools",
|
|
65739
66671
|
"search_tools",
|
|
65740
66672
|
"get_tool",
|
|
65741
|
-
"call_tool"
|
|
66673
|
+
"call_tool",
|
|
66674
|
+
"list_resources",
|
|
66675
|
+
"search_resources",
|
|
66676
|
+
"list_resource_templates",
|
|
66677
|
+
"read_resource",
|
|
66678
|
+
"list_prompts",
|
|
66679
|
+
"search_prompts",
|
|
66680
|
+
"get_prompt",
|
|
66681
|
+
"complete"
|
|
65742
66682
|
]);
|
|
65743
66683
|
async function dispatchRemoteCliRequest(request, context) {
|
|
65744
66684
|
try {
|
|
@@ -65789,6 +66729,16 @@ async function dispatch(request, context) {
|
|
|
65789
66729
|
...optionalProp("force", optionalBoolean(request.arguments, "force"))
|
|
65790
66730
|
})
|
|
65791
66731
|
};
|
|
66732
|
+
if (request.command === "complete_cli") {
|
|
66733
|
+
const shell = optionalString(request.arguments, "shell") ?? "bash";
|
|
66734
|
+
if (!completionShells.includes(shell)) return [];
|
|
66735
|
+
const engine = new CapletsEngine(context);
|
|
66736
|
+
try {
|
|
66737
|
+
return await engine.completeCliWords(optionalStringArray(request.arguments, "words") ?? [""]);
|
|
66738
|
+
} finally {
|
|
66739
|
+
await engine.close();
|
|
66740
|
+
}
|
|
66741
|
+
}
|
|
65792
66742
|
if (request.command === "auth_list") return listAuthRows({
|
|
65793
66743
|
...optionalProp("configPath", context.configPath),
|
|
65794
66744
|
...optionalProp("authDir", context.authDir)
|
|
@@ -65905,6 +66855,12 @@ function requiredString(args, key) {
|
|
|
65905
66855
|
if (typeof value !== "string" || value.length === 0) throw new CapletsError("REQUEST_INVALID", `${key} must be a non-empty string`);
|
|
65906
66856
|
return value;
|
|
65907
66857
|
}
|
|
66858
|
+
function optionalString(args, key) {
|
|
66859
|
+
const value = args[key];
|
|
66860
|
+
if (value === void 0) return;
|
|
66861
|
+
if (typeof value !== "string") throw new CapletsError("REQUEST_INVALID", `${key} must be a string`);
|
|
66862
|
+
return value;
|
|
66863
|
+
}
|
|
65908
66864
|
function optionalObject(args, key) {
|
|
65909
66865
|
const value = args[key];
|
|
65910
66866
|
if (value === void 0) return {};
|
|
@@ -66467,6 +67423,9 @@ async function runCli(args, io = {}) {
|
|
|
66467
67423
|
throw error;
|
|
66468
67424
|
}
|
|
66469
67425
|
}
|
|
67426
|
+
function normalizeCompletionWords(words) {
|
|
67427
|
+
return words.map((word) => word === "__CAPLETS_TRAILING_SPACE__" ? "" : word);
|
|
67428
|
+
}
|
|
66470
67429
|
function createProgram(io = {}) {
|
|
66471
67430
|
const writeOut = io.writeOut ?? ((value) => process.stdout.write(value));
|
|
66472
67431
|
const writeErr = io.writeErr ?? ((value) => process.stderr.write(value));
|
|
@@ -66481,7 +67440,27 @@ function createProgram(io = {}) {
|
|
|
66481
67440
|
writeErr,
|
|
66482
67441
|
outputError: (value, write) => write(value)
|
|
66483
67442
|
});
|
|
66484
|
-
program.command(
|
|
67443
|
+
program.command(cliCommands.completion).description("Print a shell completion script.").argument("<shell>", "completion shell: bash, zsh, fish, powershell, or cmd").action((shell) => {
|
|
67444
|
+
if (!completionShells.includes(shell)) throw new CapletsError("REQUEST_INVALID", "completion shell must be bash, zsh, fish, powershell, or cmd");
|
|
67445
|
+
writeOut(completionScript(shell));
|
|
67446
|
+
});
|
|
67447
|
+
program.command(cliCommands.completeHidden, { hidden: true }).description("Internal shell completion endpoint.").option("--shell <shell>", "completion shell").allowUnknownOption(true).argument("[words...]", "words to complete").action(async (words, options) => {
|
|
67448
|
+
const shell = completionShells.includes(options.shell) ? options.shell : "bash";
|
|
67449
|
+
const remote = remoteClientForCli(io);
|
|
67450
|
+
const configPath = currentConfigPath();
|
|
67451
|
+
const completionWords = normalizeCompletionWords(words);
|
|
67452
|
+
let suggestions = [];
|
|
67453
|
+
try {
|
|
67454
|
+
suggestions = remote ? await remote.request("complete_cli", {
|
|
67455
|
+
shell,
|
|
67456
|
+
words: completionWords
|
|
67457
|
+
}) : await completeCliWords(completionWords, configPath ? { configPath } : {});
|
|
67458
|
+
} catch {
|
|
67459
|
+
suggestions = [];
|
|
67460
|
+
}
|
|
67461
|
+
if (suggestions.length > 0) writeOut(`${suggestions.join("\n")}\n`);
|
|
67462
|
+
});
|
|
67463
|
+
program.command(cliCommands.serve).description("Serve configured Caplets as an MCP server.").option("--transport <transport>", "server transport: stdio or http").option("--host <host>", "HTTP bind host").option("--port <port>", "HTTP bind port").option("--path <path>", "HTTP service base path").option("--user <user>", "HTTP Basic Auth username").option("--password <password>", "HTTP Basic Auth password").option("--allow-unauthenticated-http", "allow unauthenticated HTTP serving on non-loopback hosts").option("--trust-proxy", "trust X-Forwarded-* headers from a reverse proxy").action(async (options) => {
|
|
66485
67464
|
const resolved = resolveServeOptions(options);
|
|
66486
67465
|
const configPath = currentConfigPath();
|
|
66487
67466
|
await (io.serve ?? ((serveOptions) => serveResolvedCaplets(serveOptions, {
|
|
@@ -66489,7 +67468,7 @@ function createProgram(io = {}) {
|
|
|
66489
67468
|
...io.authDir ? { authDir: io.authDir } : {}
|
|
66490
67469
|
}, writeErr)))(resolved);
|
|
66491
67470
|
});
|
|
66492
|
-
program.command(
|
|
67471
|
+
program.command(cliCommands.init).description("Create a starter Caplets config file.").option("--force", "overwrite an existing config file").action(async (options) => {
|
|
66493
67472
|
const remote = remoteClientForCli(io);
|
|
66494
67473
|
if (remote) {
|
|
66495
67474
|
writeOut(`Created remote Caplets config at ${(await remote.request("init", { force: Boolean(options.force) })).path}\n`);
|
|
@@ -66501,7 +67480,7 @@ function createProgram(io = {}) {
|
|
|
66501
67480
|
force: Boolean(options.force)
|
|
66502
67481
|
})}\n`);
|
|
66503
67482
|
});
|
|
66504
|
-
program.command(
|
|
67483
|
+
program.command(cliCommands.list).description("List configured Caplets.").option("--all", "include disabled Caplets").option("--json", "print JSON output").option("--format <format>", "output format: plain, markdown, md, or json", parseOutputFormat).action(async (options) => {
|
|
66505
67484
|
const includeDisabled = Boolean(options.all);
|
|
66506
67485
|
const remote = remoteClientForCli(io);
|
|
66507
67486
|
if (remote) {
|
|
@@ -66520,7 +67499,7 @@ function createProgram(io = {}) {
|
|
|
66520
67499
|
}
|
|
66521
67500
|
writeOut(formatCapletList(rows, options.format ?? "plain"));
|
|
66522
67501
|
});
|
|
66523
|
-
program.command(
|
|
67502
|
+
program.command(cliCommands.install).description("Install Caplets from a repo's caplets directory.").argument("<repo>", "local repo path, Git URL, or GitHub owner/repo").argument("[caplets...]", "optional Caplet IDs to install").option("-g, --global", "install to the user Caplets root").option("--force", "overwrite installed Caplets").action(async (repo, capletIds, options) => {
|
|
66524
67503
|
const remote = remoteClientForCli(io);
|
|
66525
67504
|
if (remote) {
|
|
66526
67505
|
if (options.global) writeErr("Warning: --global is not supported in remote mode; the server controls the installation destination.\n");
|
|
@@ -66539,7 +67518,7 @@ function createProgram(io = {}) {
|
|
|
66539
67518
|
});
|
|
66540
67519
|
for (const caplet of result.installed) writeOut(`Installed ${caplet.id} to ${caplet.destination}\n`);
|
|
66541
67520
|
});
|
|
66542
|
-
const add = program.command(
|
|
67521
|
+
const add = program.command(cliCommands.add).description("Add generated Caplet files.");
|
|
66543
67522
|
add.command("cli").description("Add a CLI tools Caplet.").argument("<id>", "Caplet ID/display seed").option("--repo <path>", "repository path to inspect").option("--include <items>", "comma-separated generators to include: git,gh,package").option("--command <name>", "single CLI command template to generate").option("-g, --global", "write to the user Caplets root").option("--print", "print generated Caplet text without writing a file").option("--output <path>", "output path").option("--force", "overwrite an existing destination file").action(async (id, options) => {
|
|
66544
67523
|
const remote = remoteClientForCli(io);
|
|
66545
67524
|
if (remote) {
|
|
@@ -66620,7 +67599,7 @@ function createProgram(io = {}) {
|
|
|
66620
67599
|
destinationRoot: addDestinationRoot(options, currentConfigPath())
|
|
66621
67600
|
}));
|
|
66622
67601
|
});
|
|
66623
|
-
program.command(
|
|
67602
|
+
program.command(cliCommands.getCaplet).description("Print a configured Caplet card.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
|
|
66624
67603
|
await executeOperation(caplet, { operation: "get_caplet" }, {
|
|
66625
67604
|
writeOut,
|
|
66626
67605
|
writeErr,
|
|
@@ -66631,7 +67610,7 @@ function createProgram(io = {}) {
|
|
|
66631
67610
|
format: options.format
|
|
66632
67611
|
});
|
|
66633
67612
|
});
|
|
66634
|
-
program.command(
|
|
67613
|
+
program.command(cliCommands.checkBackend).description("Check backend availability for a configured Caplet.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
|
|
66635
67614
|
await executeOperation(caplet, { operation: "check_backend" }, {
|
|
66636
67615
|
writeOut,
|
|
66637
67616
|
writeErr,
|
|
@@ -66642,7 +67621,7 @@ function createProgram(io = {}) {
|
|
|
66642
67621
|
format: options.format
|
|
66643
67622
|
});
|
|
66644
67623
|
});
|
|
66645
|
-
program.command(
|
|
67624
|
+
program.command(cliCommands.listTools).description("List downstream tools for a configured Caplet.").argument("<caplet>", "configured Caplet ID").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => {
|
|
66646
67625
|
await executeOperation(caplet, { operation: "list_tools" }, {
|
|
66647
67626
|
writeOut,
|
|
66648
67627
|
writeErr,
|
|
@@ -66653,7 +67632,7 @@ function createProgram(io = {}) {
|
|
|
66653
67632
|
format: options.format
|
|
66654
67633
|
});
|
|
66655
67634
|
});
|
|
66656
|
-
program.command(
|
|
67635
|
+
program.command(cliCommands.searchTools).description("Search downstream tools for a configured Caplet.").argument("<caplet>", "configured Caplet ID").argument("<query>", "search query").option("--limit <n>", "maximum number of tools to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, query, options) => {
|
|
66657
67636
|
await executeOperation(caplet, options.limit === void 0 ? {
|
|
66658
67637
|
operation: "search_tools",
|
|
66659
67638
|
query
|
|
@@ -66671,7 +67650,7 @@ function createProgram(io = {}) {
|
|
|
66671
67650
|
format: options.format
|
|
66672
67651
|
});
|
|
66673
67652
|
});
|
|
66674
|
-
program.command(
|
|
67653
|
+
program.command(cliCommands.getTool).description("Print one downstream tool schema.").argument("<caplet.tool>", "qualified target, split on the first dot").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
|
|
66675
67654
|
const { caplet, tool } = parseQualifiedTarget(target);
|
|
66676
67655
|
await executeOperation(caplet, {
|
|
66677
67656
|
operation: "get_tool",
|
|
@@ -66686,7 +67665,7 @@ function createProgram(io = {}) {
|
|
|
66686
67665
|
format: options.format
|
|
66687
67666
|
});
|
|
66688
67667
|
});
|
|
66689
|
-
program.command(
|
|
67668
|
+
program.command(cliCommands.callTool).description("Call one downstream tool.").argument("<caplet.tool>", "qualified target, split on the first dot").option("--args <json-object>", "JSON object of downstream tool arguments").option("--field <path>", "project a field from structured output", collect, []).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
|
|
66690
67669
|
const { caplet, tool } = parseQualifiedTarget(target);
|
|
66691
67670
|
await executeOperation(caplet, {
|
|
66692
67671
|
operation: "call_tool",
|
|
@@ -66703,7 +67682,119 @@ function createProgram(io = {}) {
|
|
|
66703
67682
|
format: options.format
|
|
66704
67683
|
});
|
|
66705
67684
|
});
|
|
66706
|
-
|
|
67685
|
+
program.command(cliCommands.listResources).description("List MCP resources for a configured MCP Caplet.").argument("<caplet>").option("--limit <n>", "maximum number of resources to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, options.limit === void 0 ? { operation: "list_resources" } : {
|
|
67686
|
+
operation: "list_resources",
|
|
67687
|
+
limit: options.limit
|
|
67688
|
+
}, {
|
|
67689
|
+
writeOut,
|
|
67690
|
+
writeErr,
|
|
67691
|
+
setExitCode,
|
|
67692
|
+
authDir: io.authDir,
|
|
67693
|
+
env,
|
|
67694
|
+
remote: remoteClientForCli(io),
|
|
67695
|
+
format: options.format
|
|
67696
|
+
}));
|
|
67697
|
+
program.command(cliCommands.searchResources).description("Search MCP resources and resource templates for a configured MCP Caplet.").argument("<caplet>").argument("<query>").option("--limit <n>", "maximum number of matches to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, query, options) => executeOperation(caplet, options.limit === void 0 ? {
|
|
67698
|
+
operation: "search_resources",
|
|
67699
|
+
query
|
|
67700
|
+
} : {
|
|
67701
|
+
operation: "search_resources",
|
|
67702
|
+
query,
|
|
67703
|
+
limit: options.limit
|
|
67704
|
+
}, {
|
|
67705
|
+
writeOut,
|
|
67706
|
+
writeErr,
|
|
67707
|
+
setExitCode,
|
|
67708
|
+
authDir: io.authDir,
|
|
67709
|
+
env,
|
|
67710
|
+
remote: remoteClientForCli(io),
|
|
67711
|
+
format: options.format
|
|
67712
|
+
}));
|
|
67713
|
+
program.command(cliCommands.listResourceTemplates).description("List MCP resource templates for a configured MCP Caplet.").argument("<caplet>").option("--limit <n>", "maximum number of templates to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, options.limit === void 0 ? { operation: "list_resource_templates" } : {
|
|
67714
|
+
operation: "list_resource_templates",
|
|
67715
|
+
limit: options.limit
|
|
67716
|
+
}, {
|
|
67717
|
+
writeOut,
|
|
67718
|
+
writeErr,
|
|
67719
|
+
setExitCode,
|
|
67720
|
+
authDir: io.authDir,
|
|
67721
|
+
env,
|
|
67722
|
+
remote: remoteClientForCli(io),
|
|
67723
|
+
format: options.format
|
|
67724
|
+
}));
|
|
67725
|
+
program.command(cliCommands.readResource).description("Read one MCP resource by URI.").argument("<caplet>").argument("<uri>").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, uri, options) => executeOperation(caplet, {
|
|
67726
|
+
operation: "read_resource",
|
|
67727
|
+
uri
|
|
67728
|
+
}, {
|
|
67729
|
+
writeOut,
|
|
67730
|
+
writeErr,
|
|
67731
|
+
setExitCode,
|
|
67732
|
+
authDir: io.authDir,
|
|
67733
|
+
env,
|
|
67734
|
+
remote: remoteClientForCli(io),
|
|
67735
|
+
format: options.format
|
|
67736
|
+
}));
|
|
67737
|
+
program.command(cliCommands.listPrompts).description("List MCP prompts for a configured MCP Caplet.").argument("<caplet>").option("--limit <n>", "maximum number of prompts to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, options.limit === void 0 ? { operation: "list_prompts" } : {
|
|
67738
|
+
operation: "list_prompts",
|
|
67739
|
+
limit: options.limit
|
|
67740
|
+
}, {
|
|
67741
|
+
writeOut,
|
|
67742
|
+
writeErr,
|
|
67743
|
+
setExitCode,
|
|
67744
|
+
authDir: io.authDir,
|
|
67745
|
+
env,
|
|
67746
|
+
remote: remoteClientForCli(io),
|
|
67747
|
+
format: options.format
|
|
67748
|
+
}));
|
|
67749
|
+
program.command(cliCommands.searchPrompts).description("Search MCP prompts for a configured MCP Caplet.").argument("<caplet>").argument("<query>").option("--limit <n>", "maximum number of prompts to return", parsePositiveInteger).option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, query, options) => executeOperation(caplet, options.limit === void 0 ? {
|
|
67750
|
+
operation: "search_prompts",
|
|
67751
|
+
query
|
|
67752
|
+
} : {
|
|
67753
|
+
operation: "search_prompts",
|
|
67754
|
+
query,
|
|
67755
|
+
limit: options.limit
|
|
67756
|
+
}, {
|
|
67757
|
+
writeOut,
|
|
67758
|
+
writeErr,
|
|
67759
|
+
setExitCode,
|
|
67760
|
+
authDir: io.authDir,
|
|
67761
|
+
env,
|
|
67762
|
+
remote: remoteClientForCli(io),
|
|
67763
|
+
format: options.format
|
|
67764
|
+
}));
|
|
67765
|
+
program.command(cliCommands.getPrompt).description("Get one MCP prompt by name.").argument("<caplet.prompt>", "qualified target, split on the first dot").option("--args <json-object>", "JSON object of prompt arguments").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (target, options) => {
|
|
67766
|
+
const { caplet, tool: prompt } = parseQualifiedTarget(target);
|
|
67767
|
+
await executeOperation(caplet, {
|
|
67768
|
+
operation: "get_prompt",
|
|
67769
|
+
prompt,
|
|
67770
|
+
arguments: parseJsonObjectOption(options.args, "get-prompt --args")
|
|
67771
|
+
}, {
|
|
67772
|
+
writeOut,
|
|
67773
|
+
writeErr,
|
|
67774
|
+
setExitCode,
|
|
67775
|
+
authDir: io.authDir,
|
|
67776
|
+
env,
|
|
67777
|
+
remote: remoteClientForCli(io),
|
|
67778
|
+
format: options.format
|
|
67779
|
+
});
|
|
67780
|
+
});
|
|
67781
|
+
program.command(cliCommands.complete).description("Complete an MCP prompt or resource-template argument.").argument("<caplet>").requiredOption("--argument <name>", "argument name").option("--value <value>", "argument prefix", "").option("--prompt <name>", "prompt name to complete").option("--resource-template <uri-template>", "resource template URI to complete").option("--format <format>", "output format: markdown, md, plain, or json", parseOutputFormat).action(async (caplet, options) => executeOperation(caplet, {
|
|
67782
|
+
operation: "complete",
|
|
67783
|
+
ref: completionRefFromOptions(options),
|
|
67784
|
+
argument: {
|
|
67785
|
+
name: options.argument,
|
|
67786
|
+
value: options.value
|
|
67787
|
+
}
|
|
67788
|
+
}, {
|
|
67789
|
+
writeOut,
|
|
67790
|
+
writeErr,
|
|
67791
|
+
setExitCode,
|
|
67792
|
+
authDir: io.authDir,
|
|
67793
|
+
env,
|
|
67794
|
+
remote: remoteClientForCli(io),
|
|
67795
|
+
format: options.format
|
|
67796
|
+
}));
|
|
67797
|
+
const config = program.command(cliCommands.config).description("Inspect Caplets config locations.");
|
|
66707
67798
|
config.command("path").description("Print the effective user config path.").action(() => {
|
|
66708
67799
|
writeOut(`${resolveConfigPath(currentConfigPath())}\n`);
|
|
66709
67800
|
});
|
|
@@ -66715,7 +67806,7 @@ function createProgram(io = {}) {
|
|
|
66715
67806
|
}
|
|
66716
67807
|
writeOut(formatConfigPaths(paths, options.format ?? "plain"));
|
|
66717
67808
|
});
|
|
66718
|
-
const auth = program.command(
|
|
67809
|
+
const auth = program.command(cliCommands.auth).description("Manage OAuth credentials for remote servers.");
|
|
66719
67810
|
auth.command("login").description("Authenticate a configured remote OAuth server.").argument("<server>", "configured server ID").option("--no-open", "print the authorization URL without opening a browser").action(async (serverId, options) => {
|
|
66720
67811
|
const remote = remoteClientForCli(io);
|
|
66721
67812
|
if (remote) {
|
|
@@ -66800,7 +67891,15 @@ function remoteCommandForOperation(operation) {
|
|
|
66800
67891
|
case "list_tools":
|
|
66801
67892
|
case "search_tools":
|
|
66802
67893
|
case "get_tool":
|
|
66803
|
-
case "call_tool":
|
|
67894
|
+
case "call_tool":
|
|
67895
|
+
case "list_resources":
|
|
67896
|
+
case "search_resources":
|
|
67897
|
+
case "list_resource_templates":
|
|
67898
|
+
case "read_resource":
|
|
67899
|
+
case "list_prompts":
|
|
67900
|
+
case "search_prompts":
|
|
67901
|
+
case "get_prompt":
|
|
67902
|
+
case "complete": return operation;
|
|
66804
67903
|
default: return;
|
|
66805
67904
|
}
|
|
66806
67905
|
}
|
|
@@ -66848,6 +67947,29 @@ function parseCallToolArgs(value) {
|
|
|
66848
67947
|
if (!isPlainObject(parsed)) throw new CapletsError("REQUEST_INVALID", "call-tool --args must be a JSON object");
|
|
66849
67948
|
return parsed;
|
|
66850
67949
|
}
|
|
67950
|
+
function parseJsonObjectOption(value, label) {
|
|
67951
|
+
if (value === void 0) return {};
|
|
67952
|
+
let parsed;
|
|
67953
|
+
try {
|
|
67954
|
+
parsed = JSON.parse(value);
|
|
67955
|
+
} catch (error) {
|
|
67956
|
+
throw new CapletsError("REQUEST_INVALID", `${label} must be valid JSON`, error);
|
|
67957
|
+
}
|
|
67958
|
+
if (!isPlainObject(parsed)) throw new CapletsError("REQUEST_INVALID", `${label} must be a JSON object`);
|
|
67959
|
+
return parsed;
|
|
67960
|
+
}
|
|
67961
|
+
function completionRefFromOptions(options) {
|
|
67962
|
+
if (options.prompt && options.resourceTemplate) throw new CapletsError("REQUEST_INVALID", "complete accepts either --prompt or --resource-template, not both");
|
|
67963
|
+
if (options.prompt) return {
|
|
67964
|
+
type: "prompt",
|
|
67965
|
+
name: options.prompt
|
|
67966
|
+
};
|
|
67967
|
+
if (options.resourceTemplate) return {
|
|
67968
|
+
type: "resourceTemplate",
|
|
67969
|
+
uri: options.resourceTemplate
|
|
67970
|
+
};
|
|
67971
|
+
throw new CapletsError("REQUEST_INVALID", "complete requires --prompt or --resource-template");
|
|
67972
|
+
}
|
|
66851
67973
|
function isPlainObject(value) {
|
|
66852
67974
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
66853
67975
|
}
|
|
@@ -66978,6 +68100,55 @@ function markdownSummaryForOperation(result, request) {
|
|
|
66978
68100
|
"",
|
|
66979
68101
|
"Use `--format json` to inspect the full structured result."
|
|
66980
68102
|
].filter((line) => line !== void 0).join("\n");
|
|
68103
|
+
case "list_resources":
|
|
68104
|
+
case "search_resources": {
|
|
68105
|
+
const resources = Array.isArray(payload.resources) ? payload.resources : [];
|
|
68106
|
+
const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
|
|
68107
|
+
const matches = Array.isArray(payload.matches) ? payload.matches : [...resources, ...templates];
|
|
68108
|
+
return [
|
|
68109
|
+
`## MCP resources for \`${id}\``,
|
|
68110
|
+
"",
|
|
68111
|
+
`${matches.length} item${matches.length === 1 ? "" : "s"} found.`,
|
|
68112
|
+
"",
|
|
68113
|
+
...formatResourceLines(matches, "markdown")
|
|
68114
|
+
].join("\n");
|
|
68115
|
+
}
|
|
68116
|
+
case "list_resource_templates": {
|
|
68117
|
+
const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
|
|
68118
|
+
return [
|
|
68119
|
+
`## MCP resource templates for \`${id}\``,
|
|
68120
|
+
"",
|
|
68121
|
+
...formatResourceLines(templates, "markdown")
|
|
68122
|
+
].join("\n");
|
|
68123
|
+
}
|
|
68124
|
+
case "read_resource": return [
|
|
68125
|
+
`## Resource \`${String(request.uri ?? "")}\``,
|
|
68126
|
+
"",
|
|
68127
|
+
summarizeResourceRead(payload),
|
|
68128
|
+
"",
|
|
68129
|
+
"Use `--format json` to inspect all contents."
|
|
68130
|
+
].join("\n");
|
|
68131
|
+
case "list_prompts":
|
|
68132
|
+
case "search_prompts": {
|
|
68133
|
+
const prompts = Array.isArray(payload.prompts) ? payload.prompts : [];
|
|
68134
|
+
return [
|
|
68135
|
+
`## MCP prompts for \`${id}\``,
|
|
68136
|
+
"",
|
|
68137
|
+
...formatPromptLines(prompts, "markdown")
|
|
68138
|
+
].join("\n");
|
|
68139
|
+
}
|
|
68140
|
+
case "get_prompt": return [
|
|
68141
|
+
`## Prompt \`${String(request.caplet)}.${String(request.prompt)}\``,
|
|
68142
|
+
"",
|
|
68143
|
+
summarizePromptResult(payload),
|
|
68144
|
+
"",
|
|
68145
|
+
"Use `--format json` to inspect all messages."
|
|
68146
|
+
].join("\n");
|
|
68147
|
+
case "complete": return [
|
|
68148
|
+
`## Completion for \`${id}\``,
|
|
68149
|
+
"",
|
|
68150
|
+
summarizeCompletionResult(payload)
|
|
68151
|
+
].join("\n");
|
|
66981
68152
|
default: return JSON.stringify(payload, null, 2);
|
|
66982
68153
|
}
|
|
66983
68154
|
}
|
|
@@ -67034,6 +68205,33 @@ function plainSummaryForOperation(result, request) {
|
|
|
67034
68205
|
`Result: ${summarizeCallResult(payload)}`,
|
|
67035
68206
|
"Use --format json to inspect the full structured result."
|
|
67036
68207
|
].filter((line) => Boolean(line)).join("\n");
|
|
68208
|
+
case "list_resources":
|
|
68209
|
+
case "search_resources": {
|
|
68210
|
+
const resources = Array.isArray(payload.resources) ? payload.resources : [];
|
|
68211
|
+
const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
|
|
68212
|
+
const matches = Array.isArray(payload.matches) ? payload.matches : [...resources, ...templates];
|
|
68213
|
+
return [`MCP resources for ${id} (${matches.length}):`, ...formatResourceLines(matches, "plain")].join("\n");
|
|
68214
|
+
}
|
|
68215
|
+
case "list_resource_templates": {
|
|
68216
|
+
const templates = Array.isArray(payload.resourceTemplates) ? payload.resourceTemplates : [];
|
|
68217
|
+
return [`MCP resource templates for ${id}:`, ...formatResourceLines(templates, "plain")].join("\n");
|
|
68218
|
+
}
|
|
68219
|
+
case "read_resource": return [
|
|
68220
|
+
`Resource ${String(request.uri ?? "")}`,
|
|
68221
|
+
summarizeResourceRead(payload),
|
|
68222
|
+
"Use --format json to inspect all contents."
|
|
68223
|
+
].join("\n");
|
|
68224
|
+
case "list_prompts":
|
|
68225
|
+
case "search_prompts": {
|
|
68226
|
+
const prompts = Array.isArray(payload.prompts) ? payload.prompts : [];
|
|
68227
|
+
return [`MCP prompts for ${id}:`, ...formatPromptLines(prompts, "plain")].join("\n");
|
|
68228
|
+
}
|
|
68229
|
+
case "get_prompt": return [
|
|
68230
|
+
`Prompt ${String(request.caplet)}.${String(request.prompt)}`,
|
|
68231
|
+
summarizePromptResult(payload),
|
|
68232
|
+
"Use --format json to inspect all messages."
|
|
68233
|
+
].join("\n");
|
|
68234
|
+
case "complete": return [`Completion for ${id}`, summarizeCompletionResult(payload)].join("\n");
|
|
67037
68235
|
default: return JSON.stringify(payload, null, 2);
|
|
67038
68236
|
}
|
|
67039
68237
|
}
|
|
@@ -67050,6 +68248,44 @@ function formatToolLines(tools, format) {
|
|
|
67050
68248
|
return `- ${displayName}${flags ? ` (${flags})` : ""}${tool.description ? ` — ${compactDescription(String(tool.description))}` : ""}`;
|
|
67051
68249
|
});
|
|
67052
68250
|
}
|
|
68251
|
+
function formatResourceLines(resources, format) {
|
|
68252
|
+
if (resources.length === 0) return ["- none"];
|
|
68253
|
+
return resources.map((resource) => {
|
|
68254
|
+
if (!isPlainObject(resource)) return `- ${String(resource)}`;
|
|
68255
|
+
const name = String(resource.uri ?? resource.uriTemplate ?? "unknown");
|
|
68256
|
+
const displayName = format === "markdown" ? `\`${name}\`` : name;
|
|
68257
|
+
const label = typeof resource.name === "string" ? ` (${resource.name})` : "";
|
|
68258
|
+
return `- ${typeof resource.kind === "string" ? `${resource.kind}: ` : ""}${displayName}${label}${resource.description ? ` — ${compactDescription(String(resource.description))}` : ""}`;
|
|
68259
|
+
});
|
|
68260
|
+
}
|
|
68261
|
+
function formatPromptLines(prompts, format) {
|
|
68262
|
+
if (prompts.length === 0) return ["- none"];
|
|
68263
|
+
return prompts.map((prompt) => {
|
|
68264
|
+
if (!isPlainObject(prompt)) return `- ${String(prompt)}`;
|
|
68265
|
+
const name = String(prompt.prompt ?? prompt.name ?? "unknown");
|
|
68266
|
+
return `- ${format === "markdown" ? `\`${name}\`` : name}${Array.isArray(prompt.arguments) ? ` (${prompt.arguments.length} args)` : ""}${prompt.description ? ` — ${compactDescription(String(prompt.description))}` : ""}`;
|
|
68267
|
+
});
|
|
68268
|
+
}
|
|
68269
|
+
function summarizeResourceRead(payload) {
|
|
68270
|
+
const contents = Array.isArray(payload.contents) ? payload.contents : [];
|
|
68271
|
+
if (contents.length === 0) return "No contents returned.";
|
|
68272
|
+
const first = contents.find(isPlainObject);
|
|
68273
|
+
if (!first) return `${contents.length} content item${contents.length === 1 ? "" : "s"} returned.`;
|
|
68274
|
+
return previewValue(typeof first.text === "string" ? first.text : first.blob) ?? `${contents.length} content item${contents.length === 1 ? "" : "s"} returned.`;
|
|
68275
|
+
}
|
|
68276
|
+
function summarizePromptResult(payload) {
|
|
68277
|
+
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
68278
|
+
if (messages.length === 0) return "No messages returned.";
|
|
68279
|
+
const first = messages.find(isPlainObject);
|
|
68280
|
+
if (!first) return `${messages.length} message${messages.length === 1 ? "" : "s"} returned.`;
|
|
68281
|
+
return previewValue((isPlainObject(first.content) ? first.content : void 0)?.text ?? first.content) ?? `${messages.length} message${messages.length === 1 ? "" : "s"} returned.`;
|
|
68282
|
+
}
|
|
68283
|
+
function summarizeCompletionResult(payload) {
|
|
68284
|
+
const completion = isPlainObject(payload.completion) ? payload.completion : void 0;
|
|
68285
|
+
const values = Array.isArray(completion?.values) ? completion.values : [];
|
|
68286
|
+
if (values.length > 0) return values.map((value) => `- ${String(value)}`).join("\n");
|
|
68287
|
+
return previewValue(payload) ?? "No completions returned.";
|
|
68288
|
+
}
|
|
67053
68289
|
function compactDescription(value) {
|
|
67054
68290
|
const firstParagraph = value.trim().split(/\n\s*\n/u)[0] ?? "";
|
|
67055
68291
|
const collapsed = (firstParagraph.match(/^.*?(?:[.!?](?=\s|$)|$)/u)?.[0] ?? firstParagraph).replace(/\s+/gu, " ").trim();
|
|
@@ -67124,7 +68360,7 @@ function writeAddResult(writeOut, label, result) {
|
|
|
67124
68360
|
}
|
|
67125
68361
|
//#endregion
|
|
67126
68362
|
//#region package.json
|
|
67127
|
-
var version = "0.
|
|
68363
|
+
var version = "0.17.0";
|
|
67128
68364
|
//#endregion
|
|
67129
68365
|
//#region src/index.ts
|
|
67130
68366
|
async function main() {
|