@caplets/core 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/caplet-files.d.ts +8 -0
- package/dist/cli/auth.d.ts +26 -2
- package/dist/cli/inspection.d.ts +2 -2
- package/dist/{completion-L23s2FGB.js → completion-DRPTunQd.js} +6 -5
- package/dist/config.d.ts +11 -0
- package/dist/engine.d.ts +2 -0
- package/dist/index.js +429 -139
- package/dist/native/service.d.ts +6 -0
- package/dist/native.js +129 -12
- package/dist/{options-bnsSREid.js → options-BlNyqF_E.js} +320 -19
- package/package.json +7 -5
package/dist/native/service.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { NativeCapletsServiceResolutionInput } from "./options";
|
|
2
2
|
import { resolveNativeCapletsServiceOptions } from "./options";
|
|
3
3
|
import { type RemoteCapletsClient } from "./remote";
|
|
4
|
+
import { type CapletsConfig } from "../config";
|
|
4
5
|
import { generatedToolInputJsonSchemaForCaplet } from "../generated-tool-input-schema";
|
|
5
6
|
export type NativeCapletsServiceOptions = NativeCapletsServiceResolutionInput & {
|
|
6
7
|
configPath?: string;
|
|
@@ -12,6 +13,7 @@ export type NativeCapletsServiceOptions = NativeCapletsServiceResolutionInput &
|
|
|
12
13
|
remoteClientFactory?: (options: Extract<ReturnType<typeof resolveNativeCapletsServiceOptions>, {
|
|
13
14
|
mode: "remote";
|
|
14
15
|
}>["remote"]) => RemoteCapletsClient;
|
|
16
|
+
localServiceFactory?: (options: LocalNativeCapletsServiceOptions) => NativeCapletsService;
|
|
15
17
|
};
|
|
16
18
|
export type NativeCapletTool = {
|
|
17
19
|
caplet: string;
|
|
@@ -31,3 +33,7 @@ export type NativeCapletsService = {
|
|
|
31
33
|
close(): Promise<void>;
|
|
32
34
|
};
|
|
33
35
|
export declare function createNativeCapletsService(options?: NativeCapletsServiceOptions): NativeCapletsService;
|
|
36
|
+
type LocalNativeCapletsServiceOptions = NativeCapletsServiceOptions & {
|
|
37
|
+
configLoader?: (configPath: string, projectConfigPath: string) => CapletsConfig;
|
|
38
|
+
};
|
|
39
|
+
export {};
|
package/dist/native.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Q as ToolListChangedNotificationSchema, _ as StreamableHTTPClientTransport, a as resolveCapletsServer, b as Client, bt as parseConfig, i as resolveCapletsMode, jt as CapletsError, l as capabilityDescription, n as mcpUrlForBase, o as CapletsEngine, vt as loadLocalOverlayConfigWithSources } from "./options-BlNyqF_E.js";
|
|
2
2
|
import { a as generatedToolInputJsonSchemaForCaplet, i as generatedToolInputJsonSchema, l as operations, o as generatedToolInputSchema } from "./generated-tool-input-schema-BYoyY-l-.js";
|
|
3
3
|
//#region src/native/options.ts
|
|
4
4
|
const DEFAULT_POLL_INTERVAL_MS = 3e4;
|
|
@@ -155,10 +155,10 @@ var RemoteNativeCapletsService = class {
|
|
|
155
155
|
await this.reloadFromClient();
|
|
156
156
|
return !this.closed;
|
|
157
157
|
} catch (retryError) {
|
|
158
|
-
this.warn(`Could not reload remote Caplets tools: ${errorMessage(retryError)}\n`);
|
|
158
|
+
this.warn(`Could not reload remote Caplets tools: ${errorMessage$1(retryError)}\n`);
|
|
159
159
|
return false;
|
|
160
160
|
}
|
|
161
|
-
this.warn(`Could not reload remote Caplets tools: ${errorMessage(error)}\n`);
|
|
161
|
+
this.warn(`Could not reload remote Caplets tools: ${errorMessage$1(error)}\n`);
|
|
162
162
|
return false;
|
|
163
163
|
}
|
|
164
164
|
}
|
|
@@ -248,14 +248,14 @@ function operationNamesFromSchema(schema) {
|
|
|
248
248
|
function isPlainObject(value) {
|
|
249
249
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
250
250
|
}
|
|
251
|
-
function errorMessage(error) {
|
|
251
|
+
function errorMessage$1(error) {
|
|
252
252
|
return error instanceof Error ? error.message : String(error);
|
|
253
253
|
}
|
|
254
254
|
function remoteAuthError() {
|
|
255
255
|
return new CapletsError("AUTH_FAILED", "Remote Caplets authentication failed; check CAPLETS_SERVER_USER and CAPLETS_SERVER_PASSWORD.");
|
|
256
256
|
}
|
|
257
257
|
function isSessionFailure(error) {
|
|
258
|
-
const message = errorMessage(error).toLowerCase();
|
|
258
|
+
const message = errorMessage$1(error).toLowerCase();
|
|
259
259
|
return /session|transport|connection|connect|closed|invalid/u.test(message);
|
|
260
260
|
}
|
|
261
261
|
function isAuthFailure(error) {
|
|
@@ -264,18 +264,33 @@ function isAuthFailure(error) {
|
|
|
264
264
|
const statusCode = typeof candidate?.statusCode === "number" ? candidate.statusCode : void 0;
|
|
265
265
|
const code = typeof candidate?.code === "number" ? candidate.code : void 0;
|
|
266
266
|
if (status === 401 || status === 403 || statusCode === 401 || statusCode === 403 || code === 401 || code === 403) return true;
|
|
267
|
-
return /\b(401|403|unauthorized|forbidden)\b/iu.test(errorMessage(error));
|
|
267
|
+
return /\b(401|403|unauthorized|forbidden)\b/iu.test(errorMessage$1(error));
|
|
268
268
|
}
|
|
269
269
|
//#endregion
|
|
270
270
|
//#region src/native/service.ts
|
|
271
271
|
function createNativeCapletsService(options = {}) {
|
|
272
272
|
const resolved = resolveNativeCapletsServiceOptions(options);
|
|
273
|
-
if (resolved.mode === "remote")
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
273
|
+
if (resolved.mode === "remote") {
|
|
274
|
+
const localOptions = {
|
|
275
|
+
...options,
|
|
276
|
+
mode: "local",
|
|
277
|
+
configLoader: createLocalOverlayConfigLoader(options)
|
|
278
|
+
};
|
|
279
|
+
const local = (options.localServiceFactory ?? createDefaultNativeCapletsService)(localOptions);
|
|
280
|
+
try {
|
|
281
|
+
return new CompositeNativeCapletsService(new RemoteNativeCapletsService({
|
|
282
|
+
client: (options.remoteClientFactory ?? createSdkRemoteCapletsClient)(resolved.remote),
|
|
283
|
+
clientFactory: () => (options.remoteClientFactory ?? createSdkRemoteCapletsClient)(resolved.remote),
|
|
284
|
+
pollIntervalMs: resolved.remote.pollIntervalMs,
|
|
285
|
+
...options.writeErr ? { writeErr: options.writeErr } : {}
|
|
286
|
+
}), local, options);
|
|
287
|
+
} catch (error) {
|
|
288
|
+
local.close().catch((closeError) => {
|
|
289
|
+
writeErr(options, `Could not close local overlay Caplets service: ${errorMessage(closeError)}\n`);
|
|
290
|
+
});
|
|
291
|
+
throw error;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
279
294
|
return new DefaultNativeCapletsService(options);
|
|
280
295
|
}
|
|
281
296
|
var DefaultNativeCapletsService = class {
|
|
@@ -311,6 +326,108 @@ var DefaultNativeCapletsService = class {
|
|
|
311
326
|
await this.engine.close();
|
|
312
327
|
}
|
|
313
328
|
};
|
|
329
|
+
function createDefaultNativeCapletsService(options) {
|
|
330
|
+
return new DefaultNativeCapletsService(options);
|
|
331
|
+
}
|
|
332
|
+
var CompositeNativeCapletsService = class {
|
|
333
|
+
remote;
|
|
334
|
+
local;
|
|
335
|
+
options;
|
|
336
|
+
listeners = /* @__PURE__ */ new Set();
|
|
337
|
+
unsubscribers;
|
|
338
|
+
tools = [];
|
|
339
|
+
closed = false;
|
|
340
|
+
batchingReload = false;
|
|
341
|
+
constructor(remote, local, options) {
|
|
342
|
+
this.remote = remote;
|
|
343
|
+
this.local = local;
|
|
344
|
+
this.options = options;
|
|
345
|
+
this.unsubscribers = [this.remote.onToolsChanged(() => this.updateMergedTools()), this.local.onToolsChanged(() => this.updateMergedTools())];
|
|
346
|
+
this.tools = this.mergeTools();
|
|
347
|
+
}
|
|
348
|
+
listTools() {
|
|
349
|
+
return [...this.tools];
|
|
350
|
+
}
|
|
351
|
+
async execute(capletId, request) {
|
|
352
|
+
if (this.local.listTools().some((tool) => tool.caplet === capletId)) return await this.local.execute(capletId, request);
|
|
353
|
+
return await this.remote.execute(capletId, request);
|
|
354
|
+
}
|
|
355
|
+
async reload() {
|
|
356
|
+
if (this.closed) return false;
|
|
357
|
+
this.batchingReload = true;
|
|
358
|
+
const remoteReloaded = await this.reloadChild(this.remote, "remote");
|
|
359
|
+
const localReloaded = await this.reloadChild(this.local, "local overlay");
|
|
360
|
+
this.batchingReload = false;
|
|
361
|
+
if (remoteReloaded === void 0 || localReloaded === void 0) return false;
|
|
362
|
+
this.updateMergedTools();
|
|
363
|
+
return remoteReloaded || localReloaded;
|
|
364
|
+
}
|
|
365
|
+
onToolsChanged(listener) {
|
|
366
|
+
this.listeners.add(listener);
|
|
367
|
+
return () => this.listeners.delete(listener);
|
|
368
|
+
}
|
|
369
|
+
async close() {
|
|
370
|
+
if (this.closed) return;
|
|
371
|
+
this.closed = true;
|
|
372
|
+
for (const unsubscribe of this.unsubscribers.splice(0)) unsubscribe();
|
|
373
|
+
this.listeners.clear();
|
|
374
|
+
await Promise.all([this.remote.close(), this.local.close()]);
|
|
375
|
+
}
|
|
376
|
+
updateMergedTools() {
|
|
377
|
+
if (this.closed || this.batchingReload) return;
|
|
378
|
+
const tools = this.mergeTools();
|
|
379
|
+
if (JSON.stringify(tools) === JSON.stringify(this.tools)) return;
|
|
380
|
+
this.tools = tools;
|
|
381
|
+
for (const listener of this.listeners) try {
|
|
382
|
+
listener(this.listTools());
|
|
383
|
+
} catch (error) {
|
|
384
|
+
writeErr(this.options, `Caplets tools-changed listener failed: ${errorMessage(error)}\n`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
mergeTools() {
|
|
388
|
+
const localTools = this.local.listTools();
|
|
389
|
+
const localIds = new Set(localTools.map((tool) => tool.caplet));
|
|
390
|
+
return [...this.remote.listTools().filter((tool) => !localIds.has(tool.caplet)), ...localTools];
|
|
391
|
+
}
|
|
392
|
+
async reloadChild(service, label) {
|
|
393
|
+
try {
|
|
394
|
+
return await service.reload();
|
|
395
|
+
} catch (error) {
|
|
396
|
+
writeErr(this.options, `Could not reload composite Caplets tools from ${label}: ${errorMessage(error)}\n`);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
function createLocalOverlayConfigLoader(options) {
|
|
402
|
+
let hasLoaded = false;
|
|
403
|
+
let previousWarnings = /* @__PURE__ */ new Set();
|
|
404
|
+
return (configPath, projectConfigPath) => {
|
|
405
|
+
let result;
|
|
406
|
+
try {
|
|
407
|
+
result = loadLocalOverlayConfigWithSources(configPath, projectConfigPath);
|
|
408
|
+
} catch (error) {
|
|
409
|
+
writeErr(options, `Caplets local overlay warning: Could not load local overlay config: ${errorMessage(error)}\n`);
|
|
410
|
+
if (hasLoaded) throw new CapletsError("CONFIG_INVALID", "Caplets local overlay reload failed; keeping last known-good config.", error);
|
|
411
|
+
hasLoaded = true;
|
|
412
|
+
return parseConfig({});
|
|
413
|
+
}
|
|
414
|
+
for (const warning of result.warnings) writeErr(options, `Caplets local overlay warning${typeof warning.path === "string" ? ` at ${warning.path}` : ""}: ${warning.message}\n`);
|
|
415
|
+
const warnings = new Set(result.warnings.map(warningKey));
|
|
416
|
+
if (hasLoaded && [...warnings].some((warning) => !previousWarnings.has(warning))) throw new CapletsError("CONFIG_INVALID", "Caplets local overlay reload produced new warnings; keeping last known-good config.");
|
|
417
|
+
previousWarnings = warnings;
|
|
418
|
+
hasLoaded = true;
|
|
419
|
+
return result.config;
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function warningKey(warning) {
|
|
423
|
+
return `${warning.kind}\0${warning.path}\0${warning.message}`;
|
|
424
|
+
}
|
|
425
|
+
function writeErr(options, message) {
|
|
426
|
+
(options.writeErr ?? ((value) => process.stderr.write(value)))(message);
|
|
427
|
+
}
|
|
428
|
+
function errorMessage(error) {
|
|
429
|
+
return error instanceof Error ? error.message : String(error);
|
|
430
|
+
}
|
|
314
431
|
//#endregion
|
|
315
432
|
//#region src/native/process-cleanup.ts
|
|
316
433
|
function registerNativeCapletsProcessCleanup(service) {
|