@caplets/core 0.26.1 → 0.28.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/dist/attach/api.d.ts +10 -1
- package/dist/caplet-files-bundle.d.ts +1 -0
- package/dist/caplet-source.js +39 -3
- package/dist/cli/code-mode.d.ts +3 -2
- package/dist/cli/commands.d.ts +3 -1
- package/dist/cli/inspection.d.ts +2 -1
- package/dist/cli.d.ts +4 -0
- package/dist/code-mode/types.d.ts +2 -1
- package/dist/{completion-CFOJucl5.js → completion-CjE0EnbF.js} +16 -4
- package/dist/config/paths.d.ts +9 -0
- package/dist/config/validation.d.ts +2 -0
- package/dist/config-runtime.d.ts +6 -1
- package/dist/config-runtime.js +34 -3
- package/dist/config.d.ts +13 -2
- package/dist/engine.d.ts +18 -0
- package/dist/errors.d.ts +1 -1
- package/dist/esm-Db9dhnIG.js +7488 -0
- package/dist/exposure/namespace.d.ts +39 -0
- package/dist/index.js +840 -483
- package/dist/native/options.d.ts +1 -0
- package/dist/native/remote.d.ts +4 -2
- package/dist/native/service.d.ts +16 -2
- package/dist/native.js +1 -1
- package/dist/node-BgWIvSVP.js +17214 -0
- package/dist/rolldown-runtime-CE-6LUnI.js +44 -0
- package/dist/serve/http.d.ts +16 -1
- package/dist/serve/options.d.ts +2 -0
- package/dist/{service-aBIn4nrw.js → service-BfPCRxQ9.js} +2043 -154
- package/dist/src-Cd2QIUm1.js +813 -0
- package/dist/telemetry/context.d.ts +13 -0
- package/dist/telemetry/debug.d.ts +10 -0
- package/dist/telemetry/delivery.d.ts +1 -0
- package/dist/telemetry/events.d.ts +70 -0
- package/dist/telemetry/identity.d.ts +1 -0
- package/dist/telemetry/index.d.ts +8 -0
- package/dist/telemetry/intake.generated.d.ts +2 -0
- package/dist/telemetry/notice.d.ts +8 -0
- package/dist/telemetry/privacy.d.ts +3 -0
- package/dist/telemetry/providers.d.ts +21 -0
- package/dist/telemetry/runtime.d.ts +40 -0
- package/dist/telemetry/state.d.ts +53 -0
- package/dist/{validation-GD2x5HW1.js → validation-CWzd2gtn.js} +3 -1
- package/package.json +3 -1
|
@@ -1,53 +1,20 @@
|
|
|
1
|
+
import { i as __require, o as __toESM, t as __commonJSMin } from "./rolldown-runtime-CE-6LUnI.js";
|
|
1
2
|
import { A as safeParseAsync$1, C as toJSONSchema, D as parse$3, E as $ZodType, F as NEVER, M as defineLazy, N as normalizeParams, O as parseAsync, P as $constructor, S as datetime, T as $ZodObject, _ as record, a as any, b as unknown, c as custom, d as literal, f as looseObject, g as preprocess, h as optional, i as _null, j as clone, k as safeParse$1, l as discriminatedUnion, m as object$1, o as array, p as number$1, r as _enum, s as boolean, t as ZodNumber$1, u as intersection, v as string, w as _coercedNumber, x as url, y as union } from "./schemas-BoqMu4MG.js";
|
|
2
|
-
import { a as
|
|
3
|
+
import { a as SERVER_ID_PATTERN, c as isUrl, d as CapletsError, f as errorResult, i as NAMESPACE_ALIAS_LABEL_PATTERN, l as validateHttpActionHeaders, m as toSafeError, n as HEADER_NAME_PATTERN, o as isAllowedHttpBaseUrl, p as redactSecrets, r as HTTP_BASE_URL_PATTERN, s as isAllowedRemoteUrl, t as FORBIDDEN_HEADERS } from "./validation-CWzd2gtn.js";
|
|
3
4
|
import { generatedToolInputJsonSchema, generatedToolInputJsonSchemaForCaplet, generatedToolInputSchemaForCaplet, mcpOperations, operations } from "./generated-tool-input-schema.js";
|
|
4
|
-
import { f as observedOutputShapeKey, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-DuP7mJQf.js";
|
|
5
|
-
import {
|
|
6
|
-
import { accessSync, chmodSync, constants, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, watch, writeFileSync } from "node:fs";
|
|
5
|
+
import { f as observedOutputShapeKey, g as stableJsonStringify, h as schemaHash, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-DuP7mJQf.js";
|
|
6
|
+
import { accessSync, chmodSync, constants, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, watch, writeFileSync } from "node:fs";
|
|
7
7
|
import { basename, delimiter, dirname, extname, isAbsolute, join, parse, posix, relative, resolve, sep, win32 } from "node:path";
|
|
8
8
|
import { spawn } from "node:child_process";
|
|
9
9
|
import process$1 from "node:process";
|
|
10
10
|
import { PassThrough } from "node:stream";
|
|
11
11
|
import { createServer } from "node:http";
|
|
12
12
|
import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
|
|
13
|
-
import { homedir } from "node:os";
|
|
13
|
+
import { arch, homedir, platform } from "node:os";
|
|
14
14
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
15
15
|
import { readFile } from "node:fs/promises";
|
|
16
16
|
import ts from "typescript";
|
|
17
17
|
import { getQuickJS, shouldInterruptAfterDeadline } from "quickjs-emscripten";
|
|
18
|
-
//#region \0rolldown/runtime.js
|
|
19
|
-
var __create = Object.create;
|
|
20
|
-
var __defProp = Object.defineProperty;
|
|
21
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
22
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
23
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
24
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
25
|
-
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
26
|
-
var __exportAll = (all, no_symbols) => {
|
|
27
|
-
let target = {};
|
|
28
|
-
for (var name in all) __defProp(target, name, {
|
|
29
|
-
get: all[name],
|
|
30
|
-
enumerable: true
|
|
31
|
-
});
|
|
32
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
33
|
-
return target;
|
|
34
|
-
};
|
|
35
|
-
var __copyProps = (to, from, except, desc) => {
|
|
36
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
37
|
-
key = keys[i];
|
|
38
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
39
|
-
get: ((k) => from[k]).bind(null, key),
|
|
40
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
return to;
|
|
44
|
-
};
|
|
45
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
46
|
-
value: mod,
|
|
47
|
-
enumerable: true
|
|
48
|
-
}) : target, mod));
|
|
49
|
-
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
|
|
50
|
-
//#endregion
|
|
51
18
|
//#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v3/helpers/util.js
|
|
52
19
|
var util$1;
|
|
53
20
|
(function(util) {
|
|
@@ -17242,6 +17209,18 @@ function defaultConfigPath(env = process.env, home = homedir(), platform = proce
|
|
|
17242
17209
|
function defaultAuthDir(env = process.env, home = homedir(), platform = process.platform) {
|
|
17243
17210
|
return (platform === "win32" ? win32.join : posix.join)(defaultStateBaseDir(env, home, platform), "caplets", "auth");
|
|
17244
17211
|
}
|
|
17212
|
+
function defaultTelemetryStateDir(env = process.env, home = homedir(), platform = process.platform) {
|
|
17213
|
+
return (platform === "win32" ? win32.join : posix.join)(defaultStateBaseDir(env, home, platform), "caplets", "telemetry");
|
|
17214
|
+
}
|
|
17215
|
+
function defaultTelemetryIdentityPath(env = process.env, home = homedir(), platform = process.platform) {
|
|
17216
|
+
return (platform === "win32" ? win32.join : posix.join)(defaultTelemetryStateDir(env, home, platform), "identity.json");
|
|
17217
|
+
}
|
|
17218
|
+
function defaultTelemetryNoticePath(env = process.env, home = homedir(), platform = process.platform) {
|
|
17219
|
+
return (platform === "win32" ? win32.join : posix.join)(defaultTelemetryStateDir(env, home, platform), "notice.json");
|
|
17220
|
+
}
|
|
17221
|
+
function defaultTelemetryDeliveryHealthPath(env = process.env, home = homedir(), platform = process.platform) {
|
|
17222
|
+
return (platform === "win32" ? win32.join : posix.join)(defaultTelemetryStateDir(env, home, platform), "delivery-health.json");
|
|
17223
|
+
}
|
|
17245
17224
|
function defaultArtifactDir(env = process.env, home = homedir(), platform = process.platform) {
|
|
17246
17225
|
return (platform === "win32" ? win32.join : posix.join)(defaultStateBaseDir(env, home, platform), "caplets", "artifacts");
|
|
17247
17226
|
}
|
|
@@ -17256,6 +17235,10 @@ function defaultObservedOutputShapeCacheDir(env = process.env, home = homedir(),
|
|
|
17256
17235
|
const DEFAULT_CONFIG_PATH = defaultConfigPath();
|
|
17257
17236
|
const DEFAULT_AUTH_DIR = defaultAuthDir();
|
|
17258
17237
|
const DEFAULT_ARTIFACT_DIR = defaultArtifactDir();
|
|
17238
|
+
const DEFAULT_TELEMETRY_STATE_DIR = defaultTelemetryStateDir();
|
|
17239
|
+
defaultTelemetryIdentityPath();
|
|
17240
|
+
defaultTelemetryNoticePath();
|
|
17241
|
+
defaultTelemetryDeliveryHealthPath();
|
|
17259
17242
|
const DEFAULT_COMPLETION_CACHE_DIR = defaultCompletionCacheDir();
|
|
17260
17243
|
const DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR = defaultObservedOutputShapeCacheDir();
|
|
17261
17244
|
const PROJECT_CONFIG_FILE = join(".caplets", "config.json");
|
|
@@ -18627,8 +18610,8 @@ function compactToolSafetyHints(tool) {
|
|
|
18627
18610
|
};
|
|
18628
18611
|
}
|
|
18629
18612
|
function compactToolSchemaHints(tool) {
|
|
18630
|
-
const schema = isRecord$
|
|
18631
|
-
const properties = isRecord$
|
|
18613
|
+
const schema = isRecord$9(tool.inputSchema) ? tool.inputSchema : void 0;
|
|
18614
|
+
const properties = isRecord$9(schema?.properties) ? schema.properties : {};
|
|
18632
18615
|
const acceptedArgs = Object.keys(properties).sort();
|
|
18633
18616
|
const requiredArgs = Array.isArray(schema?.required) ? schema.required.filter((value) => typeof value === "string").sort() : [];
|
|
18634
18617
|
const argsTemplate = compactArgsTemplate(properties, requiredArgs, acceptedArgs);
|
|
@@ -18652,7 +18635,7 @@ function compactArgsTemplate(properties, requiredArgs, acceptedArgs) {
|
|
|
18652
18635
|
if (templateArgs.length === 0 || templateArgs.length > 4) return void 0;
|
|
18653
18636
|
if (requiredArgs.length === 0 && acceptedArgs.length > 3) return void 0;
|
|
18654
18637
|
const entries = templateArgs.flatMap((name) => {
|
|
18655
|
-
const value = placeholderForSchema(isRecord$
|
|
18638
|
+
const value = placeholderForSchema(isRecord$9(properties[name]) ? properties[name] : void 0);
|
|
18656
18639
|
return value === void 0 ? [] : [[name, value]];
|
|
18657
18640
|
});
|
|
18658
18641
|
return entries.length === templateArgs.length ? Object.fromEntries(entries) : void 0;
|
|
@@ -18672,13 +18655,13 @@ function placeholderForSchema(schema) {
|
|
|
18672
18655
|
}
|
|
18673
18656
|
}
|
|
18674
18657
|
function compactToolSelectionHints(tool) {
|
|
18675
|
-
if (!isRecord$
|
|
18658
|
+
if (!isRecord$9(tool)) return {};
|
|
18676
18659
|
return {
|
|
18677
18660
|
...typeof tool.useWhen === "string" && tool.useWhen.trim() ? { useWhen: tool.useWhen.trim() } : {},
|
|
18678
18661
|
...typeof tool.avoidWhen === "string" && tool.avoidWhen.trim() ? { avoidWhen: tool.avoidWhen.trim() } : {}
|
|
18679
18662
|
};
|
|
18680
18663
|
}
|
|
18681
|
-
function isRecord$
|
|
18664
|
+
function isRecord$9(value) {
|
|
18682
18665
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18683
18666
|
}
|
|
18684
18667
|
function sameServerConfig(left, right) {
|
|
@@ -18753,7 +18736,7 @@ function markdownCallToolResultContent(result, context = {}) {
|
|
|
18753
18736
|
return textContent(renderStructuredMarkdown(result, context));
|
|
18754
18737
|
}
|
|
18755
18738
|
function hasRenderableStructuredContent(value) {
|
|
18756
|
-
if (!isRecord$
|
|
18739
|
+
if (!isRecord$8(value)) return false;
|
|
18757
18740
|
return Object.keys(value).some((key) => key !== "caplets" && key !== "elapsedMs");
|
|
18758
18741
|
}
|
|
18759
18742
|
function renderStructuredMarkdown(value, context) {
|
|
@@ -18887,13 +18870,13 @@ function renderErrorMarkdown(value, title) {
|
|
|
18887
18870
|
].join("\n");
|
|
18888
18871
|
}
|
|
18889
18872
|
function isDiscoveryWrapper(value) {
|
|
18890
|
-
return isRecord$
|
|
18873
|
+
return isRecord$8(value) && "result" in value;
|
|
18891
18874
|
}
|
|
18892
18875
|
function isErrorStructuredContent(value) {
|
|
18893
|
-
return isRecord$
|
|
18876
|
+
return isRecord$8(value) && "error" in value;
|
|
18894
18877
|
}
|
|
18895
18878
|
function isHttpLikeResult(value) {
|
|
18896
|
-
return isRecord$
|
|
18879
|
+
return isRecord$8(value) && ("status" in value || "statusText" in value || "body" in value);
|
|
18897
18880
|
}
|
|
18898
18881
|
function isGraphQlHttpResult(value) {
|
|
18899
18882
|
if (!isHttpLikeResult(value)) return false;
|
|
@@ -18901,7 +18884,7 @@ function isGraphQlHttpResult(value) {
|
|
|
18901
18884
|
return Boolean(body && ("data" in body || "errors" in body));
|
|
18902
18885
|
}
|
|
18903
18886
|
function isCliResult(value) {
|
|
18904
|
-
return isRecord$
|
|
18887
|
+
return isRecord$8(value) && ("exitCode" in value || "stdout" in value || "stderr" in value);
|
|
18905
18888
|
}
|
|
18906
18889
|
function renderBodyValue(value) {
|
|
18907
18890
|
if (value === void 0) return "_No response body._";
|
|
@@ -18969,8 +18952,8 @@ function compactListHints(record) {
|
|
|
18969
18952
|
const acceptedArgs = stringArrayValue(record.acceptedArgs);
|
|
18970
18953
|
if (requiredArgs.length > 0) hints.push(`required args: ${requiredArgs.join(", ")}`);
|
|
18971
18954
|
else if (acceptedArgs.length > 0) hints.push(`args: ${acceptedArgs.join(", ")}`);
|
|
18972
|
-
if (isRecord$
|
|
18973
|
-
if (isRecord$
|
|
18955
|
+
if (isRecord$8(record.argsTemplate)) hints.push(`args template: ${compactJsonText(record.argsTemplate, 160)}`);
|
|
18956
|
+
if (isRecord$8(record.callTemplate)) hints.push(`call: ${compactJsonText(record.callTemplate, 220)}`);
|
|
18974
18957
|
if (record.supportsFields === true) hints.push("supports fields");
|
|
18975
18958
|
if (record.readOnlyHint === true) hints.push("read-only");
|
|
18976
18959
|
if (record.destructiveHint === true) hints.push("destructive");
|
|
@@ -19040,9 +19023,9 @@ function humanizeKey(key) {
|
|
|
19040
19023
|
return key.replace(/([A-Z])/gu, " $1").replace(/^./u, (char) => char.toUpperCase());
|
|
19041
19024
|
}
|
|
19042
19025
|
function asRecord$3(value) {
|
|
19043
|
-
return isRecord$
|
|
19026
|
+
return isRecord$8(value) ? value : void 0;
|
|
19044
19027
|
}
|
|
19045
|
-
function isRecord$
|
|
19028
|
+
function isRecord$8(value) {
|
|
19046
19029
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
19047
19030
|
}
|
|
19048
19031
|
//#endregion
|
|
@@ -26005,7 +25988,11 @@ const capletExposureSchema = _enum([
|
|
|
26005
25988
|
"direct_and_code_mode",
|
|
26006
25989
|
"progressive_and_code_mode"
|
|
26007
25990
|
]).describe("How this Caplet is exposed to agents.");
|
|
26008
|
-
const capletShadowingSchema = _enum([
|
|
25991
|
+
const capletShadowingSchema = _enum([
|
|
25992
|
+
"forbid",
|
|
25993
|
+
"allow",
|
|
25994
|
+
"namespace"
|
|
25995
|
+
]).describe("Whether attached local Caplets may shadow this remote Caplet ID.");
|
|
26009
25996
|
const capletEndpointAuthSchema = discriminatedUnion("type", [
|
|
26010
25997
|
object$1({ type: literal("none") }).strict(),
|
|
26011
25998
|
object$1({
|
|
@@ -27288,7 +27275,33 @@ const exposureSchema = _enum([
|
|
|
27288
27275
|
"direct_and_code_mode",
|
|
27289
27276
|
"progressive_and_code_mode"
|
|
27290
27277
|
]).describe("How this Caplet is exposed to agents.");
|
|
27291
|
-
const shadowingSchema = _enum([
|
|
27278
|
+
const shadowingSchema = _enum([
|
|
27279
|
+
"forbid",
|
|
27280
|
+
"allow",
|
|
27281
|
+
"namespace"
|
|
27282
|
+
]).default("forbid").describe("Whether attached local Caplets may shadow this remote Caplet ID.");
|
|
27283
|
+
const namespaceAliasLabelSchema = string().regex(NAMESPACE_ALIAS_LABEL_PATTERN, "namespace alias labels must be lowercase DNS-style labels using letters, numbers, or hyphens").describe("Namespace label used when qualifying colliding Caplet IDs.");
|
|
27284
|
+
const namespaceAliasesSchema = object$1({
|
|
27285
|
+
local: namespaceAliasLabelSchema.optional(),
|
|
27286
|
+
upstreams: record(string().trim().min(1), namespaceAliasLabelSchema).default({}).describe("Namespace aliases keyed by durable upstream source identity.")
|
|
27287
|
+
}).strict().default({ upstreams: {} }).superRefine((aliases, ctx) => {
|
|
27288
|
+
const seen = /* @__PURE__ */ new Map();
|
|
27289
|
+
const addAlias = (value, path) => {
|
|
27290
|
+
if (!value) return;
|
|
27291
|
+
const existing = seen.get(value);
|
|
27292
|
+
if (existing) {
|
|
27293
|
+
ctx.addIssue({
|
|
27294
|
+
code: "custom",
|
|
27295
|
+
path,
|
|
27296
|
+
message: `namespace alias '${value}' is already used at ${existing.join(".")}`
|
|
27297
|
+
});
|
|
27298
|
+
return;
|
|
27299
|
+
}
|
|
27300
|
+
seen.set(value, path);
|
|
27301
|
+
};
|
|
27302
|
+
addAlias(aliases.local, ["local"]);
|
|
27303
|
+
for (const [selector, alias] of Object.entries(aliases.upstreams)) addAlias(alias, ["upstreams", selector]);
|
|
27304
|
+
}).describe("Source-level namespace aliases for hash-qualified Caplet IDs.");
|
|
27292
27305
|
const publicServerSchema = object$1({
|
|
27293
27306
|
name: string().trim().min(1).max(80).describe("Human-readable server display name."),
|
|
27294
27307
|
description: string().describe("Capability description shown to agents before downstream tools 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"),
|
|
@@ -27525,6 +27538,7 @@ function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, googleDi
|
|
|
27525
27538
|
version: literal(1).default(1).describe("Caplets config schema version."),
|
|
27526
27539
|
defaultSearchLimit: number$1().int().positive().default(20).describe("Default maximum number of same-server search results."),
|
|
27527
27540
|
maxSearchLimit: number$1().int().positive().max(50).default(50).describe("Maximum accepted search_tools limit."),
|
|
27541
|
+
telemetry: boolean().optional().describe("Set false to disable anonymous Caplets telemetry for this user config."),
|
|
27528
27542
|
completion: object$1({
|
|
27529
27543
|
discoveryTimeoutMs: number$1().int().positive().default(750),
|
|
27530
27544
|
overallTimeoutMs: number$1().int().positive().default(1500),
|
|
@@ -27545,6 +27559,7 @@ function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, googleDi
|
|
|
27545
27559
|
exposureDiscoveryTimeoutMs: 15e3,
|
|
27546
27560
|
exposureDiscoveryConcurrency: 4
|
|
27547
27561
|
}).describe("Global Caplets runtime options."),
|
|
27562
|
+
namespaceAliases: namespaceAliasesSchema,
|
|
27548
27563
|
mcpServers: record(string().regex(SERVER_ID_PATTERN), serverValueSchema).default({}).describe("Downstream MCP servers keyed by stable server ID."),
|
|
27549
27564
|
openapiEndpoints: record(string().regex(SERVER_ID_PATTERN), openApiEndpointValueSchema).default({}).describe("OpenAPI endpoints keyed by stable Caplet ID."),
|
|
27550
27565
|
googleDiscoveryApis: record(string().regex(SERVER_ID_PATTERN), googleDiscoveryApiValueSchema).default({}).describe("Google Discovery APIs keyed by stable Caplet ID."),
|
|
@@ -28321,6 +28336,8 @@ function mergeConfigInputs(...inputs) {
|
|
|
28321
28336
|
merged = {
|
|
28322
28337
|
...merged,
|
|
28323
28338
|
...input,
|
|
28339
|
+
telemetry: input.telemetry === void 0 ? merged?.telemetry : input.telemetry,
|
|
28340
|
+
namespaceAliases: mergeNamespaceAliases(merged?.namespaceAliases, input.namespaceAliases),
|
|
28324
28341
|
mcpServers: {
|
|
28325
28342
|
...merged?.mcpServers,
|
|
28326
28343
|
...input.mcpServers
|
|
@@ -28353,19 +28370,37 @@ function mergeConfigInputs(...inputs) {
|
|
|
28353
28370
|
}
|
|
28354
28371
|
return merged;
|
|
28355
28372
|
}
|
|
28373
|
+
function mergeNamespaceAliases(left, right) {
|
|
28374
|
+
if (right !== void 0 && !isPlainObject$5(right)) return right;
|
|
28375
|
+
if (left !== void 0 && !isPlainObject$5(left)) return left;
|
|
28376
|
+
if (!isPlainObject$5(left) && !isPlainObject$5(right)) return;
|
|
28377
|
+
const leftRecord = isPlainObject$5(left) ? left : void 0;
|
|
28378
|
+
const rightRecord = isPlainObject$5(right) ? right : void 0;
|
|
28379
|
+
const leftUpstreams = isPlainObject$5(leftRecord?.upstreams) ? leftRecord.upstreams : void 0;
|
|
28380
|
+
const rightUpstreams = isPlainObject$5(rightRecord?.upstreams) ? rightRecord.upstreams : void 0;
|
|
28381
|
+
return stripUndefined({
|
|
28382
|
+
...leftRecord,
|
|
28383
|
+
...rightRecord,
|
|
28384
|
+
upstreams: {
|
|
28385
|
+
...leftUpstreams,
|
|
28386
|
+
...rightUpstreams
|
|
28387
|
+
}
|
|
28388
|
+
});
|
|
28389
|
+
}
|
|
28356
28390
|
function mergeConfigInputsWithSources(...inputs) {
|
|
28357
28391
|
let merged = {};
|
|
28358
28392
|
const sources = {};
|
|
28359
28393
|
const shadows = {};
|
|
28360
28394
|
for (const entry of inputs) {
|
|
28361
28395
|
if (entry?.input === void 0) continue;
|
|
28362
|
-
|
|
28396
|
+
const entryInput = entry.source.kind === "global-config" ? entry.input : stripUserOnlyConfig(entry.input);
|
|
28397
|
+
for (const id of capletIds(entryInput)) {
|
|
28363
28398
|
const source = sourceForId(entry.source, id);
|
|
28364
28399
|
if (sources[id]) shadows[id] = [...shadows[id] ?? [], sources[id]];
|
|
28365
28400
|
sources[id] = source;
|
|
28366
28401
|
merged = removeCapletId(merged, id);
|
|
28367
28402
|
}
|
|
28368
|
-
merged = mergeConfigInputs(merged,
|
|
28403
|
+
merged = mergeConfigInputs(merged, entryInput) ?? {};
|
|
28369
28404
|
}
|
|
28370
28405
|
return {
|
|
28371
28406
|
input: merged,
|
|
@@ -28373,6 +28408,10 @@ function mergeConfigInputsWithSources(...inputs) {
|
|
|
28373
28408
|
shadows
|
|
28374
28409
|
};
|
|
28375
28410
|
}
|
|
28411
|
+
function stripUserOnlyConfig(input) {
|
|
28412
|
+
const { telemetry: _telemetry, ...rest } = input;
|
|
28413
|
+
return rest;
|
|
28414
|
+
}
|
|
28376
28415
|
function removeCapletBackendId(input, backend, id) {
|
|
28377
28416
|
const caplets = input[backend];
|
|
28378
28417
|
if (!isPlainObject$5(caplets)) return input;
|
|
@@ -28469,6 +28508,7 @@ function parseConfig(input, options = {}) {
|
|
|
28469
28508
|
});
|
|
28470
28509
|
return {
|
|
28471
28510
|
version: parsed.data.version,
|
|
28511
|
+
telemetry: parsed.data.telemetry,
|
|
28472
28512
|
options: {
|
|
28473
28513
|
defaultSearchLimit: parsed.data.defaultSearchLimit,
|
|
28474
28514
|
maxSearchLimit: parsed.data.maxSearchLimit,
|
|
@@ -28477,6 +28517,10 @@ function parseConfig(input, options = {}) {
|
|
|
28477
28517
|
exposureDiscoveryConcurrency: parsed.data.options.exposureDiscoveryConcurrency,
|
|
28478
28518
|
completion: parsed.data.completion
|
|
28479
28519
|
},
|
|
28520
|
+
namespaceAliases: stripUndefined({
|
|
28521
|
+
local: parsed.data.namespaceAliases.local,
|
|
28522
|
+
upstreams: parsed.data.namespaceAliases.upstreams
|
|
28523
|
+
}),
|
|
28480
28524
|
mcpServers: servers,
|
|
28481
28525
|
openapiEndpoints,
|
|
28482
28526
|
googleDiscoveryApis,
|
|
@@ -28609,17 +28653,17 @@ function googleDiscoveryScopesForOperations(operations) {
|
|
|
28609
28653
|
return [...new Set(operations.flatMap((operation) => operation.scopes))].sort();
|
|
28610
28654
|
}
|
|
28611
28655
|
function validateGoogleDiscoveryDocument(value) {
|
|
28612
|
-
if (!isRecord$
|
|
28656
|
+
if (!isRecord$7(value)) throw new Error("Invalid Google Discovery document: expected an object");
|
|
28613
28657
|
if (value.kind !== void 0 && value.kind !== "discovery#restDescription") throw new Error("Invalid Google Discovery document: expected kind discovery#restDescription");
|
|
28614
|
-
if (value.resources !== void 0 && !isRecord$
|
|
28615
|
-
if (value.methods !== void 0 && !isRecord$
|
|
28616
|
-
if (!isRecord$
|
|
28617
|
-
if (value.schemas !== void 0 && !isRecord$
|
|
28618
|
-
if (value.parameters !== void 0 && !isRecord$
|
|
28658
|
+
if (value.resources !== void 0 && !isRecord$7(value.resources)) throw new Error("Invalid Google Discovery document: expected resources object");
|
|
28659
|
+
if (value.methods !== void 0 && !isRecord$7(value.methods)) throw new Error("Invalid Google Discovery document: expected methods object");
|
|
28660
|
+
if (!isRecord$7(value.resources) && !isRecord$7(value.methods)) throw new Error("Invalid Google Discovery document: expected resources or methods object");
|
|
28661
|
+
if (value.schemas !== void 0 && !isRecord$7(value.schemas)) throw new Error("Invalid Google Discovery document: expected schemas object");
|
|
28662
|
+
if (value.parameters !== void 0 && !isRecord$7(value.parameters)) throw new Error("Invalid Google Discovery document: expected parameters object");
|
|
28619
28663
|
return value;
|
|
28620
28664
|
}
|
|
28621
28665
|
function collectDocumentMethods(document) {
|
|
28622
|
-
return [...Object.entries(document.methods ?? {}).filter((entry) => isRecord$
|
|
28666
|
+
return [...Object.entries(document.methods ?? {}).filter((entry) => isRecord$7(entry[1])).map(([methodKey, method]) => ({
|
|
28623
28667
|
resourcePath: [],
|
|
28624
28668
|
methodKey,
|
|
28625
28669
|
method
|
|
@@ -28628,9 +28672,9 @@ function collectDocumentMethods(document) {
|
|
|
28628
28672
|
function collectMethods(resources, resourcePath = []) {
|
|
28629
28673
|
const entries = [];
|
|
28630
28674
|
for (const [resourceName, resource] of Object.entries(resources)) {
|
|
28631
|
-
if (!isRecord$
|
|
28675
|
+
if (!isRecord$7(resource)) continue;
|
|
28632
28676
|
const nextPath = [...resourcePath, resourceName];
|
|
28633
|
-
for (const [methodKey, method] of Object.entries(resource.methods ?? {})) if (isRecord$
|
|
28677
|
+
for (const [methodKey, method] of Object.entries(resource.methods ?? {})) if (isRecord$7(method)) entries.push({
|
|
28634
28678
|
resourcePath: nextPath,
|
|
28635
28679
|
methodKey,
|
|
28636
28680
|
method
|
|
@@ -28803,7 +28847,7 @@ function globMatches(pattern, name) {
|
|
|
28803
28847
|
function isJsonSchemaObject(value) {
|
|
28804
28848
|
return value.type === "object" || "properties" in value || "additionalProperties" in value;
|
|
28805
28849
|
}
|
|
28806
|
-
function isRecord$
|
|
28850
|
+
function isRecord$7(value) {
|
|
28807
28851
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28808
28852
|
}
|
|
28809
28853
|
function collapseWhitespace(value) {
|
|
@@ -63892,6 +63936,746 @@ async function withTimeout(promise, timeoutMs) {
|
|
|
63892
63936
|
}
|
|
63893
63937
|
}
|
|
63894
63938
|
//#endregion
|
|
63939
|
+
//#region src/telemetry/state.ts
|
|
63940
|
+
function telemetryStateDir(options = {}) {
|
|
63941
|
+
return options.stateDir ?? DEFAULT_TELEMETRY_STATE_DIR;
|
|
63942
|
+
}
|
|
63943
|
+
function telemetryIdentityPath(options = {}) {
|
|
63944
|
+
return join(telemetryStateDir(options), "identity.json");
|
|
63945
|
+
}
|
|
63946
|
+
function telemetryNoticePath(options = {}) {
|
|
63947
|
+
return join(telemetryStateDir(options), "notice.json");
|
|
63948
|
+
}
|
|
63949
|
+
function telemetryDeliveryHealthPath(options = {}) {
|
|
63950
|
+
return join(telemetryStateDir(options), "delivery-health.json");
|
|
63951
|
+
}
|
|
63952
|
+
function readTelemetryIdentity(options = {}) {
|
|
63953
|
+
const path = telemetryIdentityPath(options);
|
|
63954
|
+
const existing = readJson(path);
|
|
63955
|
+
if (typeof existing?.id === "string" && /^anon_[a-f0-9]{32}$/u.test(existing.id)) return {
|
|
63956
|
+
kind: "stable",
|
|
63957
|
+
id: existing.id
|
|
63958
|
+
};
|
|
63959
|
+
if (!options.create) return {
|
|
63960
|
+
kind: "ephemeral",
|
|
63961
|
+
id: ephemeralId(),
|
|
63962
|
+
reason: "state-unavailable"
|
|
63963
|
+
};
|
|
63964
|
+
const identity = {
|
|
63965
|
+
id: stableId(),
|
|
63966
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
63967
|
+
};
|
|
63968
|
+
if (!writePrivateJson(path, identity)) return {
|
|
63969
|
+
kind: "ephemeral",
|
|
63970
|
+
id: ephemeralId(),
|
|
63971
|
+
reason: "state-unavailable"
|
|
63972
|
+
};
|
|
63973
|
+
return {
|
|
63974
|
+
kind: "stable",
|
|
63975
|
+
id: identity.id
|
|
63976
|
+
};
|
|
63977
|
+
}
|
|
63978
|
+
function rotateTelemetryIdentity(options = {}) {
|
|
63979
|
+
const identity = {
|
|
63980
|
+
id: stableId(),
|
|
63981
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
63982
|
+
};
|
|
63983
|
+
if (!writePrivateJson(telemetryIdentityPath(options), identity)) return {
|
|
63984
|
+
kind: "ephemeral",
|
|
63985
|
+
id: ephemeralId(),
|
|
63986
|
+
reason: "state-unavailable"
|
|
63987
|
+
};
|
|
63988
|
+
return {
|
|
63989
|
+
kind: "stable",
|
|
63990
|
+
id: identity.id
|
|
63991
|
+
};
|
|
63992
|
+
}
|
|
63993
|
+
function deleteTelemetryIdentity(options = {}) {
|
|
63994
|
+
try {
|
|
63995
|
+
rmSync(telemetryIdentityPath(options), { force: true });
|
|
63996
|
+
} catch {}
|
|
63997
|
+
}
|
|
63998
|
+
function readTelemetryNotice(options = {}) {
|
|
63999
|
+
const existing = readJson(telemetryNoticePath(options));
|
|
64000
|
+
if (existing?.shown === true && typeof existing.shownAt === "string" && isTelemetrySurface(existing.surface)) return {
|
|
64001
|
+
shown: true,
|
|
64002
|
+
shownAt: existing.shownAt,
|
|
64003
|
+
surface: existing.surface
|
|
64004
|
+
};
|
|
64005
|
+
return { shown: false };
|
|
64006
|
+
}
|
|
64007
|
+
function recordTelemetryNoticeShown(options) {
|
|
64008
|
+
const notice = {
|
|
64009
|
+
shown: true,
|
|
64010
|
+
shownAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
64011
|
+
surface: options.surface
|
|
64012
|
+
};
|
|
64013
|
+
writePrivateJson(telemetryNoticePath(options), notice);
|
|
64014
|
+
return notice;
|
|
64015
|
+
}
|
|
64016
|
+
function readTelemetryDeliveryHealth(options = {}) {
|
|
64017
|
+
const existing = readJson(telemetryDeliveryHealthPath(options));
|
|
64018
|
+
if (!isDeliveryHealth(existing)) return {};
|
|
64019
|
+
return existing;
|
|
64020
|
+
}
|
|
64021
|
+
function recordTelemetryDrop(options) {
|
|
64022
|
+
const health = readTelemetryDeliveryHealth(options);
|
|
64023
|
+
health[options.provider] = health[options.provider] ?? {};
|
|
64024
|
+
health[options.provider][options.reason] = (health[options.provider][options.reason] ?? 0) + 1;
|
|
64025
|
+
writePrivateJson(telemetryDeliveryHealthPath(options), health);
|
|
64026
|
+
}
|
|
64027
|
+
function writePrivateJson(path, value) {
|
|
64028
|
+
try {
|
|
64029
|
+
mkdirSync(dirname(path), {
|
|
64030
|
+
recursive: true,
|
|
64031
|
+
mode: 448
|
|
64032
|
+
});
|
|
64033
|
+
const tmp = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
64034
|
+
writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, { mode: 384 });
|
|
64035
|
+
renameSync(tmp, path);
|
|
64036
|
+
return true;
|
|
64037
|
+
} catch {
|
|
64038
|
+
return false;
|
|
64039
|
+
}
|
|
64040
|
+
}
|
|
64041
|
+
function readJson(path) {
|
|
64042
|
+
if (!existsSync(path)) return void 0;
|
|
64043
|
+
try {
|
|
64044
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
64045
|
+
} catch {
|
|
64046
|
+
return;
|
|
64047
|
+
}
|
|
64048
|
+
}
|
|
64049
|
+
function stableId() {
|
|
64050
|
+
return `anon_${randomBytes(16).toString("hex")}`;
|
|
64051
|
+
}
|
|
64052
|
+
function ephemeralId() {
|
|
64053
|
+
return `ephemeral_${randomBytes(16).toString("hex")}`;
|
|
64054
|
+
}
|
|
64055
|
+
function isTelemetrySurface(value) {
|
|
64056
|
+
return value === "cli" || value === "serve" || value === "attach" || value === "daemon" || value === "native" || value === "code_mode";
|
|
64057
|
+
}
|
|
64058
|
+
function isDeliveryHealth(value) {
|
|
64059
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
64060
|
+
for (const provider of Object.values(value)) {
|
|
64061
|
+
if (!provider || typeof provider !== "object" || Array.isArray(provider)) return false;
|
|
64062
|
+
for (const count of Object.values(provider)) if (typeof count !== "number" || !Number.isInteger(count) || count < 0) return false;
|
|
64063
|
+
}
|
|
64064
|
+
return true;
|
|
64065
|
+
}
|
|
64066
|
+
//#endregion
|
|
64067
|
+
//#region src/telemetry/context.ts
|
|
64068
|
+
function resolveTelemetryState(options) {
|
|
64069
|
+
const env = options.env ?? process.env;
|
|
64070
|
+
const executionContext = classifyExecutionContext(env);
|
|
64071
|
+
const notice = readTelemetryNotice(options);
|
|
64072
|
+
const base = {
|
|
64073
|
+
surface: options.surface,
|
|
64074
|
+
visibility: options.visibility,
|
|
64075
|
+
executionContext,
|
|
64076
|
+
notice,
|
|
64077
|
+
stateDir: options.stateDir
|
|
64078
|
+
};
|
|
64079
|
+
if (options.debug) return {
|
|
64080
|
+
...base,
|
|
64081
|
+
status: "debug",
|
|
64082
|
+
decider: "debug"
|
|
64083
|
+
};
|
|
64084
|
+
if (env.CAPLETS_DISABLE_TELEMETRY === "1") return {
|
|
64085
|
+
...base,
|
|
64086
|
+
status: "disabled",
|
|
64087
|
+
decider: "env"
|
|
64088
|
+
};
|
|
64089
|
+
if (options.config?.telemetry === false) return {
|
|
64090
|
+
...base,
|
|
64091
|
+
status: "disabled",
|
|
64092
|
+
decider: "config"
|
|
64093
|
+
};
|
|
64094
|
+
if (isTestEnv(env)) return {
|
|
64095
|
+
...base,
|
|
64096
|
+
status: "disabled",
|
|
64097
|
+
decider: "test"
|
|
64098
|
+
};
|
|
64099
|
+
if (executionContext !== "ci" && !notice.shown && !options.allowWithoutNotice) return {
|
|
64100
|
+
...base,
|
|
64101
|
+
status: "suppressed",
|
|
64102
|
+
decider: "notice"
|
|
64103
|
+
};
|
|
64104
|
+
return {
|
|
64105
|
+
...base,
|
|
64106
|
+
status: "enabled",
|
|
64107
|
+
decider: "default",
|
|
64108
|
+
identity: readTelemetryIdentity({
|
|
64109
|
+
...options,
|
|
64110
|
+
create: options.createIdentity !== false
|
|
64111
|
+
})
|
|
64112
|
+
};
|
|
64113
|
+
}
|
|
64114
|
+
function classifyExecutionContext(env = process.env) {
|
|
64115
|
+
if (env.CI === "true" || env.GITHUB_ACTIONS === "true" || env.BUILDKITE === "true") return "ci";
|
|
64116
|
+
return process.stdout.isTTY || process.stderr.isTTY ? "interactive" : "noninteractive";
|
|
64117
|
+
}
|
|
64118
|
+
function isTestEnv(env) {
|
|
64119
|
+
return env.NODE_ENV === "test" || env.VITEST === "true" || env.VITEST_WORKER_ID !== void 0 || env.CAPLETS_TEST === "1";
|
|
64120
|
+
}
|
|
64121
|
+
//#endregion
|
|
64122
|
+
//#region src/telemetry/notice.ts
|
|
64123
|
+
const TELEMETRY_NOTICE = "Caplets collects anonymous telemetry for product usage and reliability. Disable it with CAPLETS_DISABLE_TELEMETRY=1 or `caplets telemetry disable`.\n";
|
|
64124
|
+
function maybePrintTelemetryNotice(options) {
|
|
64125
|
+
if (!options.stderrIsTTY) return false;
|
|
64126
|
+
if (readTelemetryNotice(options).shown) return false;
|
|
64127
|
+
options.writeErr(TELEMETRY_NOTICE);
|
|
64128
|
+
recordTelemetryNoticeShown({
|
|
64129
|
+
...options,
|
|
64130
|
+
surface: options.surface
|
|
64131
|
+
});
|
|
64132
|
+
return true;
|
|
64133
|
+
}
|
|
64134
|
+
//#endregion
|
|
64135
|
+
//#region src/telemetry/privacy.ts
|
|
64136
|
+
const ALLOWED_PROPERTY_KEYS = /* @__PURE__ */ new Set([
|
|
64137
|
+
"$process_person_profile",
|
|
64138
|
+
"$geoip_disable",
|
|
64139
|
+
"package",
|
|
64140
|
+
"version",
|
|
64141
|
+
"surface",
|
|
64142
|
+
"runtime_mode",
|
|
64143
|
+
"execution_context",
|
|
64144
|
+
"command_family",
|
|
64145
|
+
"operation_family",
|
|
64146
|
+
"outcome",
|
|
64147
|
+
"duration_bucket",
|
|
64148
|
+
"timeout_bucket",
|
|
64149
|
+
"integration",
|
|
64150
|
+
"exposure_mode",
|
|
64151
|
+
"backend_mcp_count",
|
|
64152
|
+
"backend_openapi_count",
|
|
64153
|
+
"backend_google_discovery_count",
|
|
64154
|
+
"backend_graphql_count",
|
|
64155
|
+
"backend_http_count",
|
|
64156
|
+
"backend_cli_count",
|
|
64157
|
+
"backend_caplets_count",
|
|
64158
|
+
"direct_count",
|
|
64159
|
+
"progressive_count",
|
|
64160
|
+
"code_mode_count",
|
|
64161
|
+
"session_category",
|
|
64162
|
+
"any_caplet_invoked",
|
|
64163
|
+
"provider",
|
|
64164
|
+
"reason",
|
|
64165
|
+
"count_bucket",
|
|
64166
|
+
"error_code",
|
|
64167
|
+
"diagnostic_category",
|
|
64168
|
+
"os_family",
|
|
64169
|
+
"arch",
|
|
64170
|
+
"node_major"
|
|
64171
|
+
]);
|
|
64172
|
+
const SAFE_STRING = /^[a-zA-Z0-9@._:-]{1,80}$/u;
|
|
64173
|
+
const SAFE_PACKAGE = /^@?[a-zA-Z0-9._-]+(?:\/[a-zA-Z0-9._-]+)?$/u;
|
|
64174
|
+
const SUSPICIOUS_VALUE = [
|
|
64175
|
+
/^\/|^[A-Za-z]:\\/u,
|
|
64176
|
+
/^https?:\/\//iu,
|
|
64177
|
+
/[a-z0-9-]+\.[a-z]{2,}/iu,
|
|
64178
|
+
/(?:^|[_.-])token(?:$|[_.=-])/iu,
|
|
64179
|
+
/(?:^|[_.-])secret(?:$|[_.=-])/iu,
|
|
64180
|
+
/(?:^|[_.-])key(?:$|[_.=-])/iu,
|
|
64181
|
+
/^sk-[a-z0-9]/iu,
|
|
64182
|
+
/^gh[pousr]_[a-z0-9]/iu,
|
|
64183
|
+
/^[A-Z_]{3,}=.+/u
|
|
64184
|
+
];
|
|
64185
|
+
const COMMAND_FAMILIES = /* @__PURE__ */ new Set([
|
|
64186
|
+
"init",
|
|
64187
|
+
"setup",
|
|
64188
|
+
"add",
|
|
64189
|
+
"install",
|
|
64190
|
+
"auth",
|
|
64191
|
+
"remote",
|
|
64192
|
+
"doctor",
|
|
64193
|
+
"serve",
|
|
64194
|
+
"attach",
|
|
64195
|
+
"daemon",
|
|
64196
|
+
"inspect",
|
|
64197
|
+
"check",
|
|
64198
|
+
"tools",
|
|
64199
|
+
"resources",
|
|
64200
|
+
"prompts",
|
|
64201
|
+
"complete",
|
|
64202
|
+
"code_mode",
|
|
64203
|
+
"native",
|
|
64204
|
+
"telemetry",
|
|
64205
|
+
"unknown"
|
|
64206
|
+
]);
|
|
64207
|
+
const STRING_VALUE_ALLOWLISTS = {
|
|
64208
|
+
surface: /* @__PURE__ */ new Set([
|
|
64209
|
+
"cli",
|
|
64210
|
+
"serve",
|
|
64211
|
+
"attach",
|
|
64212
|
+
"daemon",
|
|
64213
|
+
"native",
|
|
64214
|
+
"code_mode"
|
|
64215
|
+
]),
|
|
64216
|
+
runtime_mode: /* @__PURE__ */ new Set([
|
|
64217
|
+
"local",
|
|
64218
|
+
"remote",
|
|
64219
|
+
"cloud",
|
|
64220
|
+
"unknown"
|
|
64221
|
+
]),
|
|
64222
|
+
execution_context: /* @__PURE__ */ new Set([
|
|
64223
|
+
"interactive",
|
|
64224
|
+
"noninteractive",
|
|
64225
|
+
"ci"
|
|
64226
|
+
]),
|
|
64227
|
+
command_family: COMMAND_FAMILIES,
|
|
64228
|
+
operation_family: COMMAND_FAMILIES,
|
|
64229
|
+
outcome: /* @__PURE__ */ new Set([
|
|
64230
|
+
"success",
|
|
64231
|
+
"failure",
|
|
64232
|
+
"cancelled",
|
|
64233
|
+
"timeout",
|
|
64234
|
+
"suppressed"
|
|
64235
|
+
]),
|
|
64236
|
+
duration_bucket: /* @__PURE__ */ new Set([
|
|
64237
|
+
"lt_100ms",
|
|
64238
|
+
"lt_1s",
|
|
64239
|
+
"lt_5s",
|
|
64240
|
+
"lt_30s",
|
|
64241
|
+
"gte_30s"
|
|
64242
|
+
]),
|
|
64243
|
+
timeout_bucket: /* @__PURE__ */ new Set([
|
|
64244
|
+
"none",
|
|
64245
|
+
"lt_1s",
|
|
64246
|
+
"lt_10s",
|
|
64247
|
+
"lt_60s",
|
|
64248
|
+
"gte_60s"
|
|
64249
|
+
]),
|
|
64250
|
+
integration: /* @__PURE__ */ new Set([
|
|
64251
|
+
"opencode",
|
|
64252
|
+
"pi",
|
|
64253
|
+
"native",
|
|
64254
|
+
"unknown"
|
|
64255
|
+
]),
|
|
64256
|
+
exposure_mode: /* @__PURE__ */ new Set([
|
|
64257
|
+
"direct",
|
|
64258
|
+
"progressive",
|
|
64259
|
+
"code_mode",
|
|
64260
|
+
"mixed",
|
|
64261
|
+
"unknown"
|
|
64262
|
+
]),
|
|
64263
|
+
session_category: /* @__PURE__ */ new Set([
|
|
64264
|
+
"created",
|
|
64265
|
+
"reused",
|
|
64266
|
+
"none",
|
|
64267
|
+
"unknown"
|
|
64268
|
+
]),
|
|
64269
|
+
provider: /* @__PURE__ */ new Set(["posthog", "sentry"]),
|
|
64270
|
+
reason: /* @__PURE__ */ new Set(["not_configured", "send_failed"]),
|
|
64271
|
+
diagnostic_category: /* @__PURE__ */ new Set([
|
|
64272
|
+
"config",
|
|
64273
|
+
"auth",
|
|
64274
|
+
"network",
|
|
64275
|
+
"runtime",
|
|
64276
|
+
"validation",
|
|
64277
|
+
"code_mode",
|
|
64278
|
+
"provider",
|
|
64279
|
+
"unknown"
|
|
64280
|
+
])
|
|
64281
|
+
};
|
|
64282
|
+
function assertTelemetrySafeProperties(properties) {
|
|
64283
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
64284
|
+
if (!ALLOWED_PROPERTY_KEYS.has(key)) throw new Error(`unknown telemetry property: ${key}`);
|
|
64285
|
+
if (typeof value === "string") {
|
|
64286
|
+
const valueAllowlist = STRING_VALUE_ALLOWLISTS[key];
|
|
64287
|
+
if (valueAllowlist && !valueAllowlist.has(value)) throw new Error(`unsafe telemetry property ${key}`);
|
|
64288
|
+
if (key === "error_code" && !/^[A-Z_]{2,80}$/u.test(value)) throw new Error(`unsafe telemetry property ${key}`);
|
|
64289
|
+
if (!(key === "package" ? SAFE_PACKAGE.test(value) : SAFE_STRING.test(value)) || key !== "package" && key !== "version" && SUSPICIOUS_VALUE.some((pattern) => pattern.test(value))) throw new Error(`unsafe telemetry property ${key}`);
|
|
64290
|
+
continue;
|
|
64291
|
+
}
|
|
64292
|
+
if (typeof value === "number") {
|
|
64293
|
+
if (!Number.isFinite(value) || value < 0 || !Number.isInteger(value)) throw new Error(`unsafe telemetry property ${key}`);
|
|
64294
|
+
continue;
|
|
64295
|
+
}
|
|
64296
|
+
if (typeof value === "boolean") continue;
|
|
64297
|
+
throw new Error(`unsafe telemetry property ${key}`);
|
|
64298
|
+
}
|
|
64299
|
+
}
|
|
64300
|
+
function stripSentryEvent(event) {
|
|
64301
|
+
const stripped = {};
|
|
64302
|
+
if (event.tags && typeof event.tags === "object" && !Array.isArray(event.tags)) stripped.tags = event.tags;
|
|
64303
|
+
if (Array.isArray(event.fingerprint)) stripped.fingerprint = event.fingerprint;
|
|
64304
|
+
if (event.level) stripped.level = event.level;
|
|
64305
|
+
return stripped;
|
|
64306
|
+
}
|
|
64307
|
+
//#endregion
|
|
64308
|
+
//#region src/telemetry/events.ts
|
|
64309
|
+
const PRODUCT_EVENTS = /* @__PURE__ */ new Set([
|
|
64310
|
+
"caplets_cli_command",
|
|
64311
|
+
"caplets_tool_activation",
|
|
64312
|
+
"caplets_code_mode_outcome"
|
|
64313
|
+
]);
|
|
64314
|
+
const RELIABILITY_EVENTS = /* @__PURE__ */ new Set(["caplets_reliability_error"]);
|
|
64315
|
+
function buildProductTelemetryEvent(input) {
|
|
64316
|
+
if (!PRODUCT_EVENTS.has(input.name)) throw new Error(`unknown telemetry event: ${input.name}`);
|
|
64317
|
+
assertTelemetrySafeProperties(input.properties);
|
|
64318
|
+
return {
|
|
64319
|
+
provider: "posthog",
|
|
64320
|
+
name: input.name,
|
|
64321
|
+
distinctId: input.distinctId,
|
|
64322
|
+
properties: {
|
|
64323
|
+
...input.properties,
|
|
64324
|
+
$process_person_profile: false
|
|
64325
|
+
}
|
|
64326
|
+
};
|
|
64327
|
+
}
|
|
64328
|
+
function buildReliabilityTelemetryEvent(input) {
|
|
64329
|
+
if (!RELIABILITY_EVENTS.has(input.name)) throw new Error(`unknown telemetry event: ${input.name}`);
|
|
64330
|
+
assertTelemetrySafeProperties(input.properties);
|
|
64331
|
+
const tags = tagsFor(input.properties);
|
|
64332
|
+
return {
|
|
64333
|
+
provider: "sentry",
|
|
64334
|
+
name: input.name,
|
|
64335
|
+
tags,
|
|
64336
|
+
fingerprint: [
|
|
64337
|
+
tags.package ?? "unknown",
|
|
64338
|
+
tags.surface ?? "unknown",
|
|
64339
|
+
tags.command_family ?? "unknown",
|
|
64340
|
+
tags.runtime_mode ?? "unknown",
|
|
64341
|
+
tags.error_code ?? "unknown",
|
|
64342
|
+
tags.diagnostic_category ?? "unknown"
|
|
64343
|
+
]
|
|
64344
|
+
};
|
|
64345
|
+
}
|
|
64346
|
+
function durationBucket(ms) {
|
|
64347
|
+
if (ms < 100) return "lt_100ms";
|
|
64348
|
+
if (ms < 1e3) return "lt_1s";
|
|
64349
|
+
if (ms < 5e3) return "lt_5s";
|
|
64350
|
+
if (ms < 3e4) return "lt_30s";
|
|
64351
|
+
return "gte_30s";
|
|
64352
|
+
}
|
|
64353
|
+
function timeoutBucket(ms) {
|
|
64354
|
+
if (ms === void 0) return "none";
|
|
64355
|
+
if (ms < 1e3) return "lt_1s";
|
|
64356
|
+
if (ms < 1e4) return "lt_10s";
|
|
64357
|
+
if (ms < 6e4) return "lt_60s";
|
|
64358
|
+
return "gte_60s";
|
|
64359
|
+
}
|
|
64360
|
+
function tagsFor(properties) {
|
|
64361
|
+
return Object.fromEntries(Object.entries(properties).map(([key, value]) => [key, String(value)]));
|
|
64362
|
+
}
|
|
64363
|
+
//#endregion
|
|
64364
|
+
//#region src/telemetry/debug.ts
|
|
64365
|
+
var TelemetryDebugSink = class {
|
|
64366
|
+
records = [];
|
|
64367
|
+
capture(state, event) {
|
|
64368
|
+
this.records.push({
|
|
64369
|
+
state,
|
|
64370
|
+
event
|
|
64371
|
+
});
|
|
64372
|
+
}
|
|
64373
|
+
toJSON() {
|
|
64374
|
+
return this.records;
|
|
64375
|
+
}
|
|
64376
|
+
};
|
|
64377
|
+
//#endregion
|
|
64378
|
+
//#region src/telemetry/providers.ts
|
|
64379
|
+
function createTelemetryDispatcher(options = {}) {
|
|
64380
|
+
let posthog;
|
|
64381
|
+
let sentry;
|
|
64382
|
+
async function posthogClient() {
|
|
64383
|
+
const token = options.posthogToken ?? process.env.CAPLETS_POSTHOG_TOKEN ?? "phc_pUZ2ZCRtFkC5qCGDNYcoYEhxxjTaooH57Cj4PTRXovyB";
|
|
64384
|
+
if (!token) return void 0;
|
|
64385
|
+
posthog ??= Promise.resolve((options.factories?.createPostHog ?? defaultPostHogFactory)(token));
|
|
64386
|
+
return posthog;
|
|
64387
|
+
}
|
|
64388
|
+
async function sentryClient() {
|
|
64389
|
+
const dsn = options.sentryDsn ?? process.env.CAPLETS_SENTRY_DSN ?? "https://c66cfd76aad69209bcf44be4cd79f9b5@o4508042228006912.ingest.us.sentry.io/4511620382392320";
|
|
64390
|
+
if (!dsn) return void 0;
|
|
64391
|
+
sentry ??= Promise.resolve((options.factories?.createSentry ?? defaultSentryFactory)(dsn));
|
|
64392
|
+
return sentry;
|
|
64393
|
+
}
|
|
64394
|
+
return {
|
|
64395
|
+
async capture(state, event) {
|
|
64396
|
+
if (state.status !== "enabled") return;
|
|
64397
|
+
try {
|
|
64398
|
+
if (event.provider === "posthog") {
|
|
64399
|
+
await capturePostHog(await posthogClient(), event, state.stateDir ?? options.stateDir);
|
|
64400
|
+
return;
|
|
64401
|
+
}
|
|
64402
|
+
await captureSentry(await sentryClient(), event, state.stateDir ?? options.stateDir);
|
|
64403
|
+
} catch {
|
|
64404
|
+
recordTelemetryDrop({
|
|
64405
|
+
stateDir: state.stateDir ?? options.stateDir,
|
|
64406
|
+
provider: event.provider,
|
|
64407
|
+
reason: "send_failed"
|
|
64408
|
+
});
|
|
64409
|
+
}
|
|
64410
|
+
},
|
|
64411
|
+
async shutdown() {
|
|
64412
|
+
const clients = await Promise.allSettled([posthog, sentry]);
|
|
64413
|
+
for (const client of clients) {
|
|
64414
|
+
if (client.status !== "fulfilled" || !client.value) continue;
|
|
64415
|
+
if ("shutdown" in client.value) await Promise.resolve(client.value.shutdown()).catch(() => void 0);
|
|
64416
|
+
if ("flush" in client.value) await Promise.resolve(client.value.flush(2e3)).catch(() => void 0);
|
|
64417
|
+
}
|
|
64418
|
+
}
|
|
64419
|
+
};
|
|
64420
|
+
}
|
|
64421
|
+
async function capturePostHog(client, event, stateDir) {
|
|
64422
|
+
if (!client) {
|
|
64423
|
+
recordTelemetryDrop({
|
|
64424
|
+
stateDir,
|
|
64425
|
+
provider: "posthog",
|
|
64426
|
+
reason: "not_configured"
|
|
64427
|
+
});
|
|
64428
|
+
return;
|
|
64429
|
+
}
|
|
64430
|
+
client.capture({
|
|
64431
|
+
distinctId: event.distinctId,
|
|
64432
|
+
event: event.name,
|
|
64433
|
+
properties: {
|
|
64434
|
+
...event.properties,
|
|
64435
|
+
$geoip_disable: true
|
|
64436
|
+
}
|
|
64437
|
+
});
|
|
64438
|
+
}
|
|
64439
|
+
async function captureSentry(client, event, stateDir) {
|
|
64440
|
+
if (!client) {
|
|
64441
|
+
recordTelemetryDrop({
|
|
64442
|
+
stateDir,
|
|
64443
|
+
provider: "sentry",
|
|
64444
|
+
reason: "not_configured"
|
|
64445
|
+
});
|
|
64446
|
+
return;
|
|
64447
|
+
}
|
|
64448
|
+
client.captureEvent({
|
|
64449
|
+
level: "error",
|
|
64450
|
+
tags: event.tags,
|
|
64451
|
+
fingerprint: event.fingerprint
|
|
64452
|
+
});
|
|
64453
|
+
}
|
|
64454
|
+
async function defaultPostHogFactory(token) {
|
|
64455
|
+
const { PostHog } = await import("./node-BgWIvSVP.js");
|
|
64456
|
+
return new PostHog(token, {
|
|
64457
|
+
flushAt: 20,
|
|
64458
|
+
flushInterval: 1e4,
|
|
64459
|
+
disableGeoip: true,
|
|
64460
|
+
historicalMigration: false
|
|
64461
|
+
});
|
|
64462
|
+
}
|
|
64463
|
+
async function defaultSentryFactory(dsn) {
|
|
64464
|
+
const sentry = await import("./esm-Db9dhnIG.js");
|
|
64465
|
+
const options = {
|
|
64466
|
+
dsn,
|
|
64467
|
+
sendDefaultPii: false,
|
|
64468
|
+
defaultIntegrations: false,
|
|
64469
|
+
integrations: [],
|
|
64470
|
+
tracesSampleRate: 0,
|
|
64471
|
+
transport: sentry.makeNodeTransport,
|
|
64472
|
+
stackParser: sentry.defaultStackParser,
|
|
64473
|
+
beforeSend(event) {
|
|
64474
|
+
return stripSentryEvent(event);
|
|
64475
|
+
}
|
|
64476
|
+
};
|
|
64477
|
+
return new sentry.NodeClient(options);
|
|
64478
|
+
}
|
|
64479
|
+
//#endregion
|
|
64480
|
+
//#region package.json
|
|
64481
|
+
var version = "0.28.0";
|
|
64482
|
+
//#endregion
|
|
64483
|
+
//#region src/telemetry/runtime.ts
|
|
64484
|
+
function createRuntimeTelemetryContext(options) {
|
|
64485
|
+
return {
|
|
64486
|
+
...options,
|
|
64487
|
+
dispatcher: options.dispatcher ?? createTelemetryDispatcher({ stateDir: options.stateDir })
|
|
64488
|
+
};
|
|
64489
|
+
}
|
|
64490
|
+
async function captureRuntimeTelemetryEvent(context, name, properties) {
|
|
64491
|
+
const state = resolveTelemetryState({
|
|
64492
|
+
config: context.config,
|
|
64493
|
+
env: context.env,
|
|
64494
|
+
stateDir: context.stateDir,
|
|
64495
|
+
surface: context.surface,
|
|
64496
|
+
visibility: context.visibility,
|
|
64497
|
+
debug: context.debugSink !== void 0
|
|
64498
|
+
});
|
|
64499
|
+
if (state.status !== "enabled" && state.status !== "debug") return;
|
|
64500
|
+
const event = buildProductTelemetryEvent({
|
|
64501
|
+
name,
|
|
64502
|
+
distinctId: (state.identity ?? readTelemetryIdentity({
|
|
64503
|
+
stateDir: context.stateDir,
|
|
64504
|
+
create: false
|
|
64505
|
+
})).id,
|
|
64506
|
+
properties: {
|
|
64507
|
+
package: "@caplets/core",
|
|
64508
|
+
version,
|
|
64509
|
+
surface: context.surface,
|
|
64510
|
+
runtime_mode: context.runtimeMode ?? "unknown",
|
|
64511
|
+
execution_context: state.executionContext,
|
|
64512
|
+
...context.integration ? { integration: context.integration } : {},
|
|
64513
|
+
...properties
|
|
64514
|
+
}
|
|
64515
|
+
});
|
|
64516
|
+
if (state.status === "debug") {
|
|
64517
|
+
context.debugSink?.capture("debug", event);
|
|
64518
|
+
return;
|
|
64519
|
+
}
|
|
64520
|
+
await context.dispatcher.capture(state, event);
|
|
64521
|
+
}
|
|
64522
|
+
async function captureRuntimeReliabilityEvent(context, properties) {
|
|
64523
|
+
const state = resolveTelemetryState({
|
|
64524
|
+
config: context.config,
|
|
64525
|
+
env: context.env,
|
|
64526
|
+
stateDir: context.stateDir,
|
|
64527
|
+
surface: context.surface,
|
|
64528
|
+
visibility: context.visibility,
|
|
64529
|
+
debug: context.debugSink !== void 0
|
|
64530
|
+
});
|
|
64531
|
+
if (state.status !== "enabled" && state.status !== "debug") return;
|
|
64532
|
+
const event = buildReliabilityTelemetryEvent({
|
|
64533
|
+
name: "caplets_reliability_error",
|
|
64534
|
+
properties: {
|
|
64535
|
+
package: "@caplets/core",
|
|
64536
|
+
version,
|
|
64537
|
+
surface: context.surface,
|
|
64538
|
+
runtime_mode: context.runtimeMode ?? "unknown",
|
|
64539
|
+
execution_context: state.executionContext,
|
|
64540
|
+
...context.integration ? { integration: context.integration } : {},
|
|
64541
|
+
os_family: platform(),
|
|
64542
|
+
arch: arch(),
|
|
64543
|
+
node_major: Number(process.versions.node.split(".")[0] ?? 0),
|
|
64544
|
+
...properties
|
|
64545
|
+
}
|
|
64546
|
+
});
|
|
64547
|
+
if (state.status === "debug") {
|
|
64548
|
+
context.debugSink?.capture("debug", event);
|
|
64549
|
+
return;
|
|
64550
|
+
}
|
|
64551
|
+
await context.dispatcher.capture(state, event);
|
|
64552
|
+
}
|
|
64553
|
+
function backendFamilyCounts(config) {
|
|
64554
|
+
return {
|
|
64555
|
+
backend_mcp_count: enabledCount(config.mcpServers),
|
|
64556
|
+
backend_openapi_count: enabledCount(config.openapiEndpoints),
|
|
64557
|
+
backend_google_discovery_count: enabledCount(config.googleDiscoveryApis),
|
|
64558
|
+
backend_graphql_count: enabledCount(config.graphqlEndpoints),
|
|
64559
|
+
backend_http_count: enabledCount(config.httpApis),
|
|
64560
|
+
backend_cli_count: enabledCount(config.cliTools),
|
|
64561
|
+
backend_caplets_count: enabledCount(config.capletSets)
|
|
64562
|
+
};
|
|
64563
|
+
}
|
|
64564
|
+
function exposureModeCounts(config) {
|
|
64565
|
+
let direct = 0;
|
|
64566
|
+
let progressive = 0;
|
|
64567
|
+
let codeMode = 0;
|
|
64568
|
+
for (const caplet of allCaplets$1(config)) {
|
|
64569
|
+
if (caplet.disabled || caplet.setup || caplet.projectBinding?.required) continue;
|
|
64570
|
+
const exposure = resolveExposure(caplet.exposure, config.options.exposure);
|
|
64571
|
+
if (exposure.direct) direct += 1;
|
|
64572
|
+
if (exposure.progressive) progressive += 1;
|
|
64573
|
+
if (exposure.codeMode) codeMode += 1;
|
|
64574
|
+
}
|
|
64575
|
+
return {
|
|
64576
|
+
direct_count: direct,
|
|
64577
|
+
progressive_count: progressive,
|
|
64578
|
+
code_mode_count: codeMode
|
|
64579
|
+
};
|
|
64580
|
+
}
|
|
64581
|
+
function operationFamilyFromOperation(operation) {
|
|
64582
|
+
if (operation === "inspect") return "inspect";
|
|
64583
|
+
if (operation === "check") return "check";
|
|
64584
|
+
if (operation === "tools" || operation === "search_tools" || operation === "get_tool" || operation === "describe_tool" || operation === "call_tool") return "tools";
|
|
64585
|
+
if (operation === "resources" || operation === "resource_templates" || operation === "read_resource" || operation === "search_resources" || operation === "list_resources" || operation === "list_resource_templates" || operation === "search_resource_templates") return "resources";
|
|
64586
|
+
if (operation === "prompts" || operation === "get_prompt" || operation === "list_prompts" || operation === "search_prompts") return "prompts";
|
|
64587
|
+
if (operation === "complete") return "complete";
|
|
64588
|
+
if (operation === "code_mode") return "code_mode";
|
|
64589
|
+
return "unknown";
|
|
64590
|
+
}
|
|
64591
|
+
function outcomeFromResult(result) {
|
|
64592
|
+
if (isRecord$6(result) && result.isError === true) {
|
|
64593
|
+
if (errorCodeFromResult$1(result).toLowerCase().includes("timeout")) return "timeout";
|
|
64594
|
+
return "failure";
|
|
64595
|
+
}
|
|
64596
|
+
if (isRecord$6(result) && result.ok === false) {
|
|
64597
|
+
const code = errorCodeFromResult$1(result);
|
|
64598
|
+
if (typeof code === "string" && code.toLowerCase().includes("timeout")) return "timeout";
|
|
64599
|
+
return "failure";
|
|
64600
|
+
}
|
|
64601
|
+
return "success";
|
|
64602
|
+
}
|
|
64603
|
+
function codeModeTelemetryProperties(envelope, durationMs, timeoutMs) {
|
|
64604
|
+
const record = isRecord$6(envelope) ? envelope : {};
|
|
64605
|
+
const meta = isRecord$6(record.meta) ? record.meta : {};
|
|
64606
|
+
const sessionStatus = meta.sessionStatus;
|
|
64607
|
+
const effectiveTimeoutMs = timeoutMs ?? (typeof meta.timeoutMs === "number" ? meta.timeoutMs : void 0);
|
|
64608
|
+
return {
|
|
64609
|
+
command_family: "code_mode",
|
|
64610
|
+
outcome: outcomeFromResult(record),
|
|
64611
|
+
duration_bucket: durationBucket(durationMs),
|
|
64612
|
+
timeout_bucket: timeoutBucket(effectiveTimeoutMs),
|
|
64613
|
+
session_category: sessionStatus === "created" || sessionStatus === "reused" ? sessionStatus : sessionStatus === null ? "none" : "unknown",
|
|
64614
|
+
any_caplet_invoked: codeModeEnvelopeInvokedCaplet(record)
|
|
64615
|
+
};
|
|
64616
|
+
}
|
|
64617
|
+
function toolActivationProperties(input) {
|
|
64618
|
+
return {
|
|
64619
|
+
operation_family: operationFamilyFromOperation(input.operation),
|
|
64620
|
+
exposure_mode: input.exposureMode,
|
|
64621
|
+
outcome: outcomeFromResult(input.result),
|
|
64622
|
+
duration_bucket: durationBucket(input.durationMs),
|
|
64623
|
+
...backendFamilyCounts(input.config),
|
|
64624
|
+
...exposureModeCounts(input.config)
|
|
64625
|
+
};
|
|
64626
|
+
}
|
|
64627
|
+
function enabledCount(record) {
|
|
64628
|
+
return Object.values(record).filter((caplet) => !caplet.disabled).length;
|
|
64629
|
+
}
|
|
64630
|
+
function allCaplets$1(config) {
|
|
64631
|
+
return [
|
|
64632
|
+
...Object.values(config.mcpServers),
|
|
64633
|
+
...Object.values(config.openapiEndpoints),
|
|
64634
|
+
...Object.values(config.googleDiscoveryApis),
|
|
64635
|
+
...Object.values(config.graphqlEndpoints),
|
|
64636
|
+
...Object.values(config.httpApis),
|
|
64637
|
+
...Object.values(config.cliTools),
|
|
64638
|
+
...Object.values(config.capletSets)
|
|
64639
|
+
];
|
|
64640
|
+
}
|
|
64641
|
+
function isRecord$6(value) {
|
|
64642
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
64643
|
+
}
|
|
64644
|
+
function runtimeFailureTelemetryProperties(input) {
|
|
64645
|
+
const errorCode = errorCodeFromResult$1(input.result);
|
|
64646
|
+
return {
|
|
64647
|
+
operation_family: operationFamilyFromOperation(input.operation),
|
|
64648
|
+
exposure_mode: input.exposureMode,
|
|
64649
|
+
error_code: errorCode,
|
|
64650
|
+
diagnostic_category: diagnosticCategoryFromCode(errorCode)
|
|
64651
|
+
};
|
|
64652
|
+
}
|
|
64653
|
+
function errorCodeFromResult$1(result) {
|
|
64654
|
+
if (!isRecord$6(result)) return "UNKNOWN";
|
|
64655
|
+
const error = isRecord$6(result.error) ? result.error : isRecord$6(result.structuredContent) && isRecord$6(result.structuredContent.error) ? result.structuredContent.error : void 0;
|
|
64656
|
+
if (isRecord$6(error) && typeof error.code === "string") return error.code;
|
|
64657
|
+
return "UNKNOWN";
|
|
64658
|
+
}
|
|
64659
|
+
function diagnosticCategoryFromCode(code) {
|
|
64660
|
+
if (code.startsWith("CONFIG")) return "config";
|
|
64661
|
+
if (code.startsWith("AUTH")) return "auth";
|
|
64662
|
+
if (code.includes("NETWORK") || code.includes("UNAVAILABLE")) return "network";
|
|
64663
|
+
if (code.includes("VALID") || code.includes("REQUEST")) return "validation";
|
|
64664
|
+
if (code.includes("CODE_MODE") || code.includes("SANDBOX")) return "code_mode";
|
|
64665
|
+
return "runtime";
|
|
64666
|
+
}
|
|
64667
|
+
function codeModeEnvelopeInvokedCaplet(record) {
|
|
64668
|
+
const meta = isRecord$6(record.meta) ? record.meta : void 0;
|
|
64669
|
+
return hasBooleanTrue(meta, "anyCapletInvoked") || hasBooleanTrue(meta, "capletInvoked") || hasPositiveNumber(meta, "capletInvocationCount") || hasPositiveNumber(meta, "toolCallCount");
|
|
64670
|
+
}
|
|
64671
|
+
function hasBooleanTrue(record, key) {
|
|
64672
|
+
return record?.[key] === true;
|
|
64673
|
+
}
|
|
64674
|
+
function hasPositiveNumber(record, key) {
|
|
64675
|
+
const value = record?.[key];
|
|
64676
|
+
return typeof value === "number" && value > 0;
|
|
64677
|
+
}
|
|
64678
|
+
//#endregion
|
|
63895
64679
|
//#region src/engine.ts
|
|
63896
64680
|
var CapletsEngine = class {
|
|
63897
64681
|
registry;
|
|
@@ -63910,6 +64694,8 @@ var CapletsEngine = class {
|
|
|
63910
64694
|
observedOutputShapeStore;
|
|
63911
64695
|
observedOutputShapeScope;
|
|
63912
64696
|
projectFingerprint;
|
|
64697
|
+
telemetry;
|
|
64698
|
+
telemetryExecuteExposureMode;
|
|
63913
64699
|
reloadListeners = /* @__PURE__ */ new Set();
|
|
63914
64700
|
lastExposureSnapshot;
|
|
63915
64701
|
watchers = [];
|
|
@@ -63927,6 +64713,18 @@ var CapletsEngine = class {
|
|
|
63927
64713
|
this.configLoader = options.configLoader ?? runtimeConfigLoader(options.authDir, options.vaultRecoveryTarget);
|
|
63928
64714
|
const config = this.loadConfigWithWarnings();
|
|
63929
64715
|
this.registry = new ServerRegistry(config);
|
|
64716
|
+
this.telemetry = createRuntimeTelemetryContext({
|
|
64717
|
+
config: this.registry.config,
|
|
64718
|
+
env: options.telemetryEnv,
|
|
64719
|
+
stateDir: options.telemetryStateDir,
|
|
64720
|
+
surface: options.telemetrySurface ?? "serve",
|
|
64721
|
+
visibility: options.telemetryVisibility ?? "unknown",
|
|
64722
|
+
runtimeMode: options.telemetryRuntimeMode ?? runtimeModeFromEnv(options.telemetryEnv),
|
|
64723
|
+
integration: options.telemetryIntegration,
|
|
64724
|
+
debugSink: options.telemetryDebugSink,
|
|
64725
|
+
dispatcher: options.telemetryDispatcher
|
|
64726
|
+
});
|
|
64727
|
+
this.telemetryExecuteExposureMode = options.telemetrySurface === "code_mode" ? "code_mode" : "progressive";
|
|
63930
64728
|
this.downstream = new DownstreamManager(this.registry, selectAuthOptions(options.authDir));
|
|
63931
64729
|
this.openapi = new OpenApiManager(this.registry, selectHttpLikeOptions(options));
|
|
63932
64730
|
this.googleDiscovery = new GoogleDiscoveryManager(this.registry, selectHttpLikeOptions(options));
|
|
@@ -63991,44 +64789,73 @@ var CapletsEngine = class {
|
|
|
63991
64789
|
return await this.reloading;
|
|
63992
64790
|
}
|
|
63993
64791
|
async execute(serverId, request) {
|
|
64792
|
+
const started = Date.now();
|
|
64793
|
+
let caplet;
|
|
63994
64794
|
try {
|
|
63995
|
-
|
|
64795
|
+
caplet = this.registry.require(serverId);
|
|
64796
|
+
const result = await handleServerTool(caplet, request, this.registry, this.downstream, this.openapi, this.graphql, this.http, this.cli, this.capletSets, {
|
|
63996
64797
|
observedOutputShapeStore: this.observedOutputShapeStore,
|
|
63997
64798
|
observedOutputShapeScope: this.observedOutputShapeScope,
|
|
63998
64799
|
projectFingerprint: this.projectFingerprint
|
|
63999
64800
|
}, this.googleDiscovery);
|
|
64801
|
+
this.captureToolActivation(caplet, operationFromRequest(request), this.telemetryExecuteExposureMode, result, started);
|
|
64802
|
+
return result;
|
|
64000
64803
|
} catch (error) {
|
|
64001
|
-
|
|
64804
|
+
const result = errorResult(error);
|
|
64805
|
+
this.captureReliabilityError(operationFromRequest(request), this.telemetryExecuteExposureMode, result);
|
|
64806
|
+
this.captureToolActivation(caplet, operationFromRequest(request), this.telemetryExecuteExposureMode, result, started);
|
|
64807
|
+
return result;
|
|
64002
64808
|
}
|
|
64003
64809
|
}
|
|
64004
64810
|
async executeDirectTool(serverId, toolName, args) {
|
|
64811
|
+
const started = Date.now();
|
|
64812
|
+
let caplet;
|
|
64005
64813
|
try {
|
|
64006
|
-
|
|
64007
|
-
|
|
64814
|
+
caplet = this.registry.require(serverId);
|
|
64815
|
+
const annotated = annotateDirectResult(await this.callTool(caplet, toolName, args), caplet, toolName);
|
|
64816
|
+
this.captureToolActivation(caplet, "call_tool", "direct", annotated, started);
|
|
64817
|
+
return annotated;
|
|
64008
64818
|
} catch (error) {
|
|
64009
|
-
|
|
64819
|
+
const result = errorResult(error);
|
|
64820
|
+
this.captureReliabilityError("call_tool", "direct", result);
|
|
64821
|
+
this.captureToolActivation(caplet, "call_tool", "direct", result, started);
|
|
64822
|
+
return result;
|
|
64010
64823
|
}
|
|
64011
64824
|
}
|
|
64012
64825
|
async readDirectResource(serverId, downstreamUri) {
|
|
64826
|
+
const started = Date.now();
|
|
64827
|
+
let caplet;
|
|
64013
64828
|
try {
|
|
64014
|
-
|
|
64829
|
+
caplet = this.registry.require(serverId);
|
|
64015
64830
|
if (caplet.backend !== "mcp") throw new Error(`Caplet ${serverId} has no MCP resources`);
|
|
64016
|
-
|
|
64831
|
+
const annotated = annotateDirectResult(await this.downstream.readResource(caplet, downstreamUri), caplet, "read_resource");
|
|
64832
|
+
this.captureToolActivation(caplet, "read_resource", "direct", annotated, started);
|
|
64833
|
+
return annotated;
|
|
64017
64834
|
} catch (error) {
|
|
64018
|
-
|
|
64835
|
+
const result = errorResult(error);
|
|
64836
|
+
this.captureReliabilityError("read_resource", "direct", result);
|
|
64837
|
+
this.captureToolActivation(caplet, "read_resource", "direct", result, started);
|
|
64838
|
+
return result;
|
|
64019
64839
|
}
|
|
64020
64840
|
}
|
|
64021
64841
|
async getDirectPrompt(serverId, promptName, args) {
|
|
64842
|
+
const started = Date.now();
|
|
64843
|
+
let caplet;
|
|
64022
64844
|
try {
|
|
64023
|
-
|
|
64845
|
+
caplet = this.registry.require(serverId);
|
|
64024
64846
|
if (caplet.backend !== "mcp") throw new Error(`Caplet ${serverId} has no MCP prompts`);
|
|
64025
|
-
|
|
64847
|
+
const annotated = annotateDirectResult(await this.downstream.getPrompt(caplet, promptName, args), caplet, promptName);
|
|
64848
|
+
this.captureToolActivation(caplet, "get_prompt", "direct", annotated, started);
|
|
64849
|
+
return annotated;
|
|
64026
64850
|
} catch (error) {
|
|
64027
|
-
|
|
64851
|
+
const result = errorResult(error);
|
|
64852
|
+
this.captureReliabilityError("get_prompt", "direct", result);
|
|
64853
|
+
this.captureToolActivation(caplet, "get_prompt", "direct", result, started);
|
|
64854
|
+
return result;
|
|
64028
64855
|
}
|
|
64029
64856
|
}
|
|
64030
64857
|
async completeCliWords(words) {
|
|
64031
|
-
const { completeCliWords } = await import("./completion-
|
|
64858
|
+
const { completeCliWords } = await import("./completion-CjE0EnbF.js").then((n) => n.r);
|
|
64032
64859
|
return await completeCliWords(words, {
|
|
64033
64860
|
config: this.registry.config,
|
|
64034
64861
|
managers: {
|
|
@@ -64059,6 +64886,9 @@ var CapletsEngine = class {
|
|
|
64059
64886
|
}
|
|
64060
64887
|
});
|
|
64061
64888
|
}
|
|
64889
|
+
async captureCodeModeOutcome(envelope, options) {
|
|
64890
|
+
await captureRuntimeTelemetryEvent(this.telemetry, "caplets_code_mode_outcome", codeModeTelemetryProperties(envelope, Date.now() - options.started, options.timeoutMs));
|
|
64891
|
+
}
|
|
64062
64892
|
async close() {
|
|
64063
64893
|
this.closed = true;
|
|
64064
64894
|
try {
|
|
@@ -64075,6 +64905,7 @@ var CapletsEngine = class {
|
|
|
64075
64905
|
this.closeWatchers();
|
|
64076
64906
|
await this.downstream.close();
|
|
64077
64907
|
await this.capletSets.close();
|
|
64908
|
+
await this.telemetry.dispatcher.shutdown();
|
|
64078
64909
|
this.reloadListeners.clear();
|
|
64079
64910
|
}
|
|
64080
64911
|
}
|
|
@@ -64112,6 +64943,7 @@ var CapletsEngine = class {
|
|
|
64112
64943
|
const previousConfig = this.registry.config;
|
|
64113
64944
|
const nextRegistry = new ServerRegistry(nextConfig);
|
|
64114
64945
|
this.registry = nextRegistry;
|
|
64946
|
+
this.telemetry.config = nextConfig;
|
|
64115
64947
|
this.downstream.updateRegistry(nextRegistry);
|
|
64116
64948
|
this.openapi.updateRegistry(nextRegistry);
|
|
64117
64949
|
this.googleDiscovery.updateRegistry(nextRegistry);
|
|
@@ -64229,6 +65061,29 @@ var CapletsEngine = class {
|
|
|
64229
65061
|
if (!this.closed) this.resetWatchers();
|
|
64230
65062
|
}, this.watchDebounceMs);
|
|
64231
65063
|
}
|
|
65064
|
+
captureReliabilityError(operation, exposureMode, result) {
|
|
65065
|
+
captureRuntimeReliabilityEvent(this.telemetry, {
|
|
65066
|
+
command_family: commandFamilyForTelemetrySurface(this.telemetry.surface),
|
|
65067
|
+
...runtimeFailureTelemetryProperties({
|
|
65068
|
+
operation,
|
|
65069
|
+
exposureMode,
|
|
65070
|
+
result
|
|
65071
|
+
})
|
|
65072
|
+
}).catch(() => void 0);
|
|
65073
|
+
}
|
|
65074
|
+
captureToolActivation(caplet, operation, exposureMode, result, started) {
|
|
65075
|
+
captureRuntimeTelemetryEvent(this.telemetry, "caplets_tool_activation", {
|
|
65076
|
+
command_family: commandFamilyForTelemetrySurface(this.telemetry.surface),
|
|
65077
|
+
...toolActivationProperties({
|
|
65078
|
+
config: this.registry.config,
|
|
65079
|
+
caplet,
|
|
65080
|
+
operation,
|
|
65081
|
+
exposureMode,
|
|
65082
|
+
result,
|
|
65083
|
+
durationMs: Date.now() - started
|
|
65084
|
+
})
|
|
65085
|
+
}).catch(() => void 0);
|
|
65086
|
+
}
|
|
64232
65087
|
};
|
|
64233
65088
|
function runtimeConfigLoader(authDir, vaultRecoveryTarget) {
|
|
64234
65089
|
const vaultResolver = vaultResolverForAuthDir(authDir);
|
|
@@ -64331,7 +65186,7 @@ function annotateDirectResult(result, caplet, operation) {
|
|
|
64331
65186
|
return {
|
|
64332
65187
|
...result,
|
|
64333
65188
|
_meta: {
|
|
64334
|
-
...isRecord$
|
|
65189
|
+
...isRecord$5(existingMeta) ? existingMeta : {},
|
|
64335
65190
|
caplets: {
|
|
64336
65191
|
capletId: caplet.server,
|
|
64337
65192
|
backend: caplet.backend,
|
|
@@ -64344,9 +65199,25 @@ function annotateDirectResult(result, caplet, operation) {
|
|
|
64344
65199
|
function isUnsupportedCapability(error) {
|
|
64345
65200
|
return error instanceof CapletsError && error.code === "UNSUPPORTED_CAPABILITY";
|
|
64346
65201
|
}
|
|
64347
|
-
function isRecord$
|
|
65202
|
+
function isRecord$5(value) {
|
|
64348
65203
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
64349
65204
|
}
|
|
65205
|
+
function operationFromRequest(request) {
|
|
65206
|
+
return isRecord$5(request) ? request.operation : void 0;
|
|
65207
|
+
}
|
|
65208
|
+
function runtimeModeFromEnv(env) {
|
|
65209
|
+
const mode = env?.CAPLETS_MODE ?? process.env.CAPLETS_MODE;
|
|
65210
|
+
if (mode === "local" || mode === "remote" || mode === "cloud") return mode;
|
|
65211
|
+
return "unknown";
|
|
65212
|
+
}
|
|
65213
|
+
function commandFamilyForTelemetrySurface(surface) {
|
|
65214
|
+
if (surface === "serve") return "serve";
|
|
65215
|
+
if (surface === "attach") return "attach";
|
|
65216
|
+
if (surface === "daemon") return "daemon";
|
|
65217
|
+
if (surface === "code_mode") return "code_mode";
|
|
65218
|
+
if (surface === "native") return "native";
|
|
65219
|
+
return "tools";
|
|
65220
|
+
}
|
|
64350
65221
|
//#endregion
|
|
64351
65222
|
//#region src/code-mode/runtime-api.generated.ts
|
|
64352
65223
|
const CODE_MODE_RUNTIME_API_DECLARATION = "type JsonPrimitive=string|number|boolean|null;type JsonValue=JsonPrimitive|JsonValue[]|{[key:string]:JsonValue};interface CapletHandle<Id extends string>{readonly id:Id;/** Show this Caplet card,without tool/resource/prompt schemas. */ inspect():Promise<CapletCard<Id>>;/** Check backend readiness/auth;expected unavailable states return ok:false. */ check():Promise<CapletsResult<BackendCheckResult>>;/** List tool summaries for the discovery pass;may be empty. */ tools(input?:PageInput):Promise<Page<ToolSummary>>;/** Search tool summaries for the discovery pass;may be empty. */ searchTools(query:string,input?:PageInput):Promise<Page<ToolSummary>>;/** Get schema,callSignature,types,examples;prefer outputSchema/outputTypeScript over observed hints. */ describeTool(name:string):Promise<CapletsResult<ToolDescriptor>>;/** Call one tool;expected failures return ok:false. Filter bulky data in script before returning. */ callTool(name:string,args?:unknown):Promise<CapletsResult<unknown>>;/** List readable resources for the discovery pass;many backends expose none. */ resources(input?:PageInput):Promise<Page<ResourceSummary>>;/** Search readable resources for the discovery pass;many backends expose none. */ searchResources(query:string,input?:PageInput):Promise<Page<ResourceSummary>>;/** List resource templates for the discovery pass;many backends expose none. */ resourceTemplates(input?:PageInput):Promise<Page<ResourceTemplateSummary>>;/** Read one resource by URI;unsupported/missing resources return ok:false. */ readResource(uri:string):Promise<CapletsResult<ResourceReadResult>>;/** List reusable prompts for the discovery pass;many backends expose none. */ prompts(input?:PageInput):Promise<Page<PromptSummary>>;/** Search reusable prompts for the discovery pass;many backends expose none. */ searchPrompts(query:string,input?:PageInput):Promise<Page<PromptSummary>>;/** Get one prompt by name and args;unsupported/missing prompts return ok:false. */ getPrompt(name:string,args?:unknown):Promise<CapletsResult<PromptResult>>;/** Complete a prompt or resource-template argument. */ complete(input:CompleteInput):Promise<CapletsResult<CompleteResult>>;}interface DebugApi{readLogs(input:ReadLogsInput):Promise<ReadLogsResult>;readRecovery(input:ReadCodeModeRecoveryInput):Promise<ReadCodeModeRecoveryResult>;}type CapletCard<Id extends string>={id:Id;name:string;description:string;useWhen?:string;avoidWhen?:string;tags?:string[];backend?:unknown;};type PageInput={limit?:number;cursor?:string};type Page<T>={items:T[];nextCursor?:string;truncated?:boolean};type CapletsResult<T>=|{ok:true;data:T;meta?:CapletsMeta}|{ok:false;error:CapletsError;meta?:CapletsMeta};type CapletsMeta={[key:string]:unknown};type CapletsError={code:string;message:string;details?:unknown};type BackendCheckResult=unknown;type ToolSummary={/** Exact downstream tool identifier for describeTool(name)and callTool(name,args). */ name:string;title?:string;description?:string;/** Optional author-supplied hint for when to prefer this tool. */ useWhen?:string;/** Optional author-supplied hint for when to avoid this tool. */ avoidWhen?:string;/** True when the tool declares that it only reads data. */ readOnlyHint?:boolean;/** True when the tool declares that it may perform destructive writes. */ destructiveHint?:boolean;};type ToolDescriptor={id?:string;tool?:unknown;inputSchema?:unknown;outputSchema?:unknown;callSignature?:string;inputTypeScript?:string;outputTypeScript?:string;observedOutputShape?:ObservedOutputShape;examples?:unknown[];};type ObservedOutputShape={version:1;source:\"observed\";observedAt:string;sampleCount:number;typeScript:string;jsonShape:JsonShape;truncated:boolean;};type JsonShape=|{kind:\"null\"}|{kind:\"boolean\"}|{kind:\"number\"}|{kind:\"string\"}|{kind:\"unknown\"}|{kind:\"array\";element?:JsonShape;truncated?:boolean}|{kind:\"object\";fields:Record<string,{optional:boolean;shape:JsonShape}>;truncated?:boolean;}|{kind:\"union\";variants:JsonShape[]};type ResourceSummary={uri?:string;name?:string;title?:string;description?:string};type ResourceTemplateSummary={uriTemplate?:string;name?:string;title?:string;description?:string;};type ResourceReadResult=unknown;type PromptSummary={name?:string;title?:string;description?:string};type PromptResult=unknown;type CompleteInput={ref:{type:\"prompt\";name:string}|{type:\"resourceTemplate\";uri:string};argument:{name:string;value:string};};type CompleteResult=unknown;type ReadLogsInput={logRef:string;cursor?:string;limit?:number};type ReadLogsResult={entries:CodeModeLogEntry[];nextCursor?:string};type ReadCodeModeRecoveryInput={recoveryRef:string;cursor?:string;limit?:number};type CodeModeDiagnostic={code:string;message:string;severity:\"error\"|\"warning\"|\"info\";line?:number;column?:number;};type CodeModeRecoveryClassification=\"setup_like\"|\"side_effecting\"|\"unknown\";type CodeModeRecoveryEntry={timestamp:string;code:string;declarationHash:string;outcome:{ok:true}|{ok:false;code:string;message:string};diagnostics:Array<Pick<CodeModeDiagnostic,\"code\"|\"severity\"|\"message\">>;recoveryClassification:CodeModeRecoveryClassification;logsStored?:boolean;summary?:string;};type ReadCodeModeRecoveryResult={entries:CodeModeRecoveryEntry[];nextCursor?:string};type CodeModeLogEntry={level:\"log\"|\"info\"|\"warn\"|\"error\"|\"debug\";message:string;timestamp:string;};type CodeModeSessionStatus=\"created\"|\"reused\";type CodeModeRunMeta={runId:string;traceId:string;declarationHash:string;durationMs:number;timeoutMs:number;maxTimeoutMs:number;sessionId?:string|null;sessionStatus?:CodeModeSessionStatus|null;recoveryRef?:string|null;};interface Console{log(...values:unknown[]):void;info(...values:unknown[]):void;warn(...values:unknown[]):void;error(...values:unknown[]):void;debug(...values:unknown[]):void;}declare const console:Console;";
|
|
@@ -79871,9 +80742,11 @@ async function runCodeMode(input) {
|
|
|
79871
80742
|
const callable = listCodeModeCallableCaplets(input.service);
|
|
79872
80743
|
const declaration = generateCodeModeDeclarations({ caplets: callable });
|
|
79873
80744
|
const declarationHash = codeModeDeclarationHash(declaration);
|
|
80745
|
+
const platformRuntimeHash = codeModeDeclarationHash(CODE_MODE_PLATFORM_RUNTIME_SOURCE);
|
|
80746
|
+
let invokedCaplet = false;
|
|
79874
80747
|
const sessionCompatibility = {
|
|
79875
80748
|
declarationHash,
|
|
79876
|
-
platformRuntimeHash
|
|
80749
|
+
platformRuntimeHash,
|
|
79877
80750
|
runtimeScope: input.runtimeScope ?? "",
|
|
79878
80751
|
version: 1
|
|
79879
80752
|
};
|
|
@@ -79890,7 +80763,8 @@ async function runCodeMode(input) {
|
|
|
79890
80763
|
};
|
|
79891
80764
|
const meta = () => ({
|
|
79892
80765
|
...metaBase,
|
|
79893
|
-
durationMs: Date.now() - startedAt
|
|
80766
|
+
durationMs: Date.now() - startedAt,
|
|
80767
|
+
anyCapletInvoked: invokedCaplet
|
|
79894
80768
|
});
|
|
79895
80769
|
if (input.sessionId !== void 0 && !input.sessionManager) return {
|
|
79896
80770
|
ok: false,
|
|
@@ -79977,7 +80851,6 @@ async function runCodeMode(input) {
|
|
|
79977
80851
|
};
|
|
79978
80852
|
}
|
|
79979
80853
|
const capturedLogs = [];
|
|
79980
|
-
let invokedCaplet = false;
|
|
79981
80854
|
const api = createCodeModeCapletsApi({
|
|
79982
80855
|
service: input.service,
|
|
79983
80856
|
readLogs: async (readInput) => input.logStore?.read(readInput) ?? { entries: [] },
|
|
@@ -80283,6 +81156,7 @@ function emptyCodeModeRunMeta() {
|
|
|
80283
81156
|
durationMs: 0,
|
|
80284
81157
|
timeoutMs: 0,
|
|
80285
81158
|
maxTimeoutMs: 0,
|
|
81159
|
+
anyCapletInvoked: false,
|
|
80286
81160
|
sessionId: null,
|
|
80287
81161
|
sessionStatus: null,
|
|
80288
81162
|
recoveryRef: null
|
|
@@ -80542,18 +81416,28 @@ function resolveNativeCapletsServiceOptions(input = {}, env = process.env) {
|
|
|
80542
81416
|
...remoteFetch ? { fetch: remoteFetch } : {}
|
|
80543
81417
|
}, env);
|
|
80544
81418
|
const cloud = resolveNativeCloudPresence(input.remote?.cloud, env);
|
|
81419
|
+
const requestInit = mode.mode === "cloud" && cloud ? { headers: { Authorization: `Bearer ${cloud.accessToken}` } } : server.requestInit;
|
|
80545
81420
|
return {
|
|
80546
81421
|
mode: mode.mode,
|
|
80547
81422
|
remote: {
|
|
80548
81423
|
url: server.attachUrl,
|
|
80549
81424
|
auth: nativeAuthFromRemoteAuth$1(server.auth),
|
|
80550
81425
|
pollIntervalMs: parsePollInterval(input.remote?.pollIntervalMs),
|
|
80551
|
-
requestInit:
|
|
81426
|
+
requestInit: withRequestHeaders(requestInit, input.remote?.requestHeaders),
|
|
80552
81427
|
...cloud ? { cloud } : {},
|
|
80553
81428
|
...server.fetch ? { fetch: server.fetch } : {}
|
|
80554
81429
|
}
|
|
80555
81430
|
};
|
|
80556
81431
|
}
|
|
81432
|
+
function withRequestHeaders(requestInit, requestHeaders) {
|
|
81433
|
+
if (!requestHeaders) return requestInit;
|
|
81434
|
+
const headers = new Headers(requestInit.headers);
|
|
81435
|
+
for (const [name, value] of Object.entries(requestHeaders)) headers.set(name, value);
|
|
81436
|
+
return {
|
|
81437
|
+
...requestInit,
|
|
81438
|
+
headers
|
|
81439
|
+
};
|
|
81440
|
+
}
|
|
80557
81441
|
function resolveNativeHostedCloudRemote(url, workspace, fetch) {
|
|
80558
81442
|
return resolveHostedCloudRemote({
|
|
80559
81443
|
url,
|
|
@@ -80968,7 +81852,382 @@ function projectSyncFiles(projectRoot) {
|
|
|
80968
81852
|
}));
|
|
80969
81853
|
}
|
|
80970
81854
|
//#endregion
|
|
81855
|
+
//#region src/attach/api.ts
|
|
81856
|
+
const CAPLETS_ATTACH_SESSION_HEADER = "caplets-attach-session-id";
|
|
81857
|
+
async function buildAttachProjection(engine) {
|
|
81858
|
+
const snapshot = await engine.exposureSnapshot();
|
|
81859
|
+
const partial = sortAttachProjectionInput({
|
|
81860
|
+
caplets: snapshot.progressiveCaplets.map(progressiveCapletExport),
|
|
81861
|
+
tools: snapshot.directTools.map(toolExport),
|
|
81862
|
+
resources: snapshot.directResources.map(resourceExport),
|
|
81863
|
+
resourceTemplates: snapshot.directResourceTemplates.map(resourceTemplateExport),
|
|
81864
|
+
prompts: snapshot.directPrompts.map(promptExport),
|
|
81865
|
+
completions: completionExports(snapshot),
|
|
81866
|
+
codeModeCaplets: snapshot.codeModeCaplets.map(codeModeCapletExport),
|
|
81867
|
+
diagnostics: snapshot.hiddenCaplets.map((hidden) => ({
|
|
81868
|
+
code: `ATTACH_CAPLET_${hidden.reason.toUpperCase()}`,
|
|
81869
|
+
message: `Caplet ${hidden.capletId} is not exported: ${hidden.reason}.`,
|
|
81870
|
+
capletId: hidden.capletId,
|
|
81871
|
+
...hidden.error ? { details: hidden.error } : {}
|
|
81872
|
+
}))
|
|
81873
|
+
});
|
|
81874
|
+
const revision = revisionFor(partial);
|
|
81875
|
+
const manifest = {
|
|
81876
|
+
version: 1,
|
|
81877
|
+
revision,
|
|
81878
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
81879
|
+
...withRevisionExportIds(revision, partial)
|
|
81880
|
+
};
|
|
81881
|
+
return {
|
|
81882
|
+
manifest,
|
|
81883
|
+
routes: routesFor(manifest)
|
|
81884
|
+
};
|
|
81885
|
+
}
|
|
81886
|
+
async function buildNativeAttachProjection(service) {
|
|
81887
|
+
const tools = service.listTools();
|
|
81888
|
+
const partial = sortAttachProjectionInput({
|
|
81889
|
+
caplets: nativeProgressiveCaplets(tools),
|
|
81890
|
+
tools: nativeDirectTools(tools),
|
|
81891
|
+
resources: [],
|
|
81892
|
+
resourceTemplates: [],
|
|
81893
|
+
prompts: [],
|
|
81894
|
+
completions: [],
|
|
81895
|
+
codeModeCaplets: nativeCodeModeCaplets(tools),
|
|
81896
|
+
diagnostics: []
|
|
81897
|
+
});
|
|
81898
|
+
const revision = revisionFor(partial);
|
|
81899
|
+
const manifest = {
|
|
81900
|
+
version: 1,
|
|
81901
|
+
revision,
|
|
81902
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
81903
|
+
...withRevisionExportIds(revision, partial)
|
|
81904
|
+
};
|
|
81905
|
+
return {
|
|
81906
|
+
manifest,
|
|
81907
|
+
routes: routesFor(manifest)
|
|
81908
|
+
};
|
|
81909
|
+
}
|
|
81910
|
+
function nativeProgressiveCaplets(tools) {
|
|
81911
|
+
return tools.filter((tool) => tool.codeModeRun !== true && !nativeDirectToolOperation(tool)).map((tool) => ({
|
|
81912
|
+
stableId: `native:${tool.caplet}`,
|
|
81913
|
+
kind: "caplet",
|
|
81914
|
+
name: tool.caplet,
|
|
81915
|
+
title: tool.title,
|
|
81916
|
+
description: tool.description,
|
|
81917
|
+
inputSchema: tool.inputSchema,
|
|
81918
|
+
outputSchema: tool.outputSchema,
|
|
81919
|
+
annotations: tool.annotations,
|
|
81920
|
+
schemaHash: schemaHash(tool.inputSchema ?? null),
|
|
81921
|
+
capletId: tool.caplet,
|
|
81922
|
+
shadowing: tool.shadowing ?? "forbid"
|
|
81923
|
+
}));
|
|
81924
|
+
}
|
|
81925
|
+
function nativeDirectTools(tools) {
|
|
81926
|
+
return tools.flatMap((tool) => {
|
|
81927
|
+
const operation = nativeDirectToolOperation(tool);
|
|
81928
|
+
if (!operation || tool.codeModeRun === true || !tool.sourceCaplet) return [];
|
|
81929
|
+
return [{
|
|
81930
|
+
stableId: `native-tool:${tool.caplet}`,
|
|
81931
|
+
kind: "tool",
|
|
81932
|
+
name: tool.caplet,
|
|
81933
|
+
downstreamName: operation,
|
|
81934
|
+
title: tool.title,
|
|
81935
|
+
description: tool.description,
|
|
81936
|
+
inputSchema: tool.inputSchema,
|
|
81937
|
+
outputSchema: tool.outputSchema,
|
|
81938
|
+
annotations: tool.annotations,
|
|
81939
|
+
schemaHash: schemaHash({
|
|
81940
|
+
input: tool.inputSchema,
|
|
81941
|
+
output: tool.outputSchema
|
|
81942
|
+
}),
|
|
81943
|
+
capletId: tool.sourceCaplet,
|
|
81944
|
+
shadowing: tool.shadowing ?? "forbid"
|
|
81945
|
+
}];
|
|
81946
|
+
});
|
|
81947
|
+
}
|
|
81948
|
+
function nativeDirectToolOperation(tool) {
|
|
81949
|
+
if (!tool.sourceCaplet || !tool.caplet.startsWith(`${tool.sourceCaplet}__`)) return;
|
|
81950
|
+
return tool.caplet.slice(tool.sourceCaplet.length + 2);
|
|
81951
|
+
}
|
|
81952
|
+
function nativeCodeModeCaplets(tools) {
|
|
81953
|
+
return tools.flatMap((tool) => (tool.codeModeCaplets ?? []).map((caplet) => ({
|
|
81954
|
+
stableId: `native-code-mode:${caplet.id}`,
|
|
81955
|
+
kind: "caplet",
|
|
81956
|
+
name: caplet.name,
|
|
81957
|
+
title: caplet.name,
|
|
81958
|
+
description: caplet.description,
|
|
81959
|
+
schemaHash: null,
|
|
81960
|
+
capletId: caplet.id,
|
|
81961
|
+
shadowing: caplet.shadowing ?? "forbid"
|
|
81962
|
+
})));
|
|
81963
|
+
}
|
|
81964
|
+
async function invokeNativeAttachExport(service, projection, request) {
|
|
81965
|
+
if (request.revision !== projection.manifest.revision) throw new CapletsError("ATTACH_MANIFEST_STALE", "Attach manifest revision is stale.");
|
|
81966
|
+
const route = projection.routes.get(request.exportId);
|
|
81967
|
+
if (!route || route.kind !== request.kind) throw new CapletsError("ATTACH_EXPORT_NOT_FOUND", "Attach export was not found.");
|
|
81968
|
+
if (route.kind !== "caplet") {
|
|
81969
|
+
if (route.kind === "tool") return await service.execute(`${route.capletId}__${route.downstreamName}`, request.input);
|
|
81970
|
+
throw new CapletsError("REQUEST_INVALID", "Native attach sessions only support Caplet and tool exports.");
|
|
81971
|
+
}
|
|
81972
|
+
return await service.execute(route.capletId, request.input);
|
|
81973
|
+
}
|
|
81974
|
+
async function invokeAttachExport$1(engine, projection, request) {
|
|
81975
|
+
if (request.revision !== projection.manifest.revision) throw new CapletsError("ATTACH_MANIFEST_STALE", "Attach manifest revision is stale.");
|
|
81976
|
+
const route = projection.routes.get(request.exportId);
|
|
81977
|
+
if (!route || route.kind !== request.kind) throw new CapletsError("ATTACH_EXPORT_NOT_FOUND", "Attach export was not found.");
|
|
81978
|
+
if (route.kind === "caplet") return await engine.execute(route.capletId, request.input);
|
|
81979
|
+
if (route.kind === "tool") return await engine.executeDirectTool(route.capletId, route.downstreamName, isRecord$4(request.input) ? request.input : {});
|
|
81980
|
+
if (route.kind === "resource") return await engine.readDirectResource(route.capletId, route.downstreamUri);
|
|
81981
|
+
if (route.kind === "resourceTemplate") {
|
|
81982
|
+
const uri = isRecord$4(request.input) && typeof request.input.uri === "string" ? request.input.uri : void 0;
|
|
81983
|
+
if (!uri) throw new CapletsError("REQUEST_INVALID", "Attach resource template invoke requires input.uri.");
|
|
81984
|
+
const downstreamUri = downstreamResourceUri$1(route.capletId, uri);
|
|
81985
|
+
if (!directResourceUriMatchesTemplate(downstreamUri, route.downstreamUriTemplate)) throw new CapletsError("ATTACH_EXPORT_NOT_FOUND", "Attach resource URI does not match the exported resource template.");
|
|
81986
|
+
return await engine.readDirectResource(route.capletId, downstreamUri);
|
|
81987
|
+
}
|
|
81988
|
+
if (route.kind === "prompt") return await engine.getDirectPrompt(route.capletId, route.downstreamName, isRecord$4(request.input) ? stringifyRecord(request.input) : {});
|
|
81989
|
+
if (route.kind === "completion") return await engine.execute(route.capletId, {
|
|
81990
|
+
...normalizeCompletionInput(projection.manifest, route.capletId, request.input),
|
|
81991
|
+
operation: "complete"
|
|
81992
|
+
});
|
|
81993
|
+
throw new CapletsError("REQUEST_INVALID", "Attach export kind is not invokable via /v1/attach/invoke.");
|
|
81994
|
+
}
|
|
81995
|
+
function attachErrorResponse(error) {
|
|
81996
|
+
const safe = toSafeError(error, "INTERNAL_ERROR");
|
|
81997
|
+
return {
|
|
81998
|
+
status: safe.code === "ATTACH_MANIFEST_STALE" ? 409 : safe.code === "ATTACH_EXPORT_NOT_FOUND" ? 404 : safe.code === "REQUEST_INVALID" ? 400 : 500,
|
|
81999
|
+
body: {
|
|
82000
|
+
ok: false,
|
|
82001
|
+
error: safe
|
|
82002
|
+
}
|
|
82003
|
+
};
|
|
82004
|
+
}
|
|
82005
|
+
function progressiveCapletExport(entry) {
|
|
82006
|
+
const inputSchema = generatedToolInputJsonSchemaForCaplet(entry.caplet);
|
|
82007
|
+
return {
|
|
82008
|
+
stableId: `progressive:${entry.caplet.server}`,
|
|
82009
|
+
kind: "caplet",
|
|
82010
|
+
name: entry.caplet.server,
|
|
82011
|
+
title: entry.caplet.name,
|
|
82012
|
+
description: entry.caplet.description,
|
|
82013
|
+
inputSchema,
|
|
82014
|
+
schemaHash: schemaHash(inputSchema),
|
|
82015
|
+
capletId: entry.caplet.server,
|
|
82016
|
+
shadowing: shadowingPolicy(entry.caplet)
|
|
82017
|
+
};
|
|
82018
|
+
}
|
|
82019
|
+
function codeModeCapletExport(entry) {
|
|
82020
|
+
return {
|
|
82021
|
+
stableId: `code_mode:${entry.caplet.server}`,
|
|
82022
|
+
kind: "caplet",
|
|
82023
|
+
name: entry.caplet.name,
|
|
82024
|
+
title: entry.caplet.name,
|
|
82025
|
+
description: entry.caplet.description,
|
|
82026
|
+
schemaHash: null,
|
|
82027
|
+
capletId: entry.caplet.server,
|
|
82028
|
+
shadowing: shadowingPolicy(entry.caplet)
|
|
82029
|
+
};
|
|
82030
|
+
}
|
|
82031
|
+
function toolExport(entry) {
|
|
82032
|
+
return {
|
|
82033
|
+
stableId: `tool:${entry.caplet.server}:${entry.downstreamName}`,
|
|
82034
|
+
kind: "tool",
|
|
82035
|
+
name: entry.name,
|
|
82036
|
+
downstreamName: entry.downstreamName,
|
|
82037
|
+
title: entry.tool.name,
|
|
82038
|
+
description: entry.tool.description,
|
|
82039
|
+
inputSchema: entry.tool.inputSchema,
|
|
82040
|
+
outputSchema: entry.tool.outputSchema,
|
|
82041
|
+
annotations: entry.tool.annotations,
|
|
82042
|
+
schemaHash: schemaHash({
|
|
82043
|
+
input: entry.tool.inputSchema,
|
|
82044
|
+
output: entry.tool.outputSchema
|
|
82045
|
+
}),
|
|
82046
|
+
capletId: entry.caplet.server,
|
|
82047
|
+
shadowing: shadowingPolicy(entry.caplet)
|
|
82048
|
+
};
|
|
82049
|
+
}
|
|
82050
|
+
function resourceExport(entry) {
|
|
82051
|
+
return {
|
|
82052
|
+
stableId: `resource:${entry.caplet.server}:${entry.downstreamUri}`,
|
|
82053
|
+
kind: "resource",
|
|
82054
|
+
uri: entry.uri,
|
|
82055
|
+
downstreamUri: entry.downstreamUri,
|
|
82056
|
+
title: entry.resource.name,
|
|
82057
|
+
description: entry.resource.description,
|
|
82058
|
+
...entry.resource.mimeType ? { mimeType: entry.resource.mimeType } : {},
|
|
82059
|
+
...typeof entry.resource.size === "number" ? { size: entry.resource.size } : {},
|
|
82060
|
+
schemaHash: null,
|
|
82061
|
+
capletId: entry.caplet.server,
|
|
82062
|
+
shadowing: shadowingPolicy(entry.caplet)
|
|
82063
|
+
};
|
|
82064
|
+
}
|
|
82065
|
+
function resourceTemplateExport(entry) {
|
|
82066
|
+
return {
|
|
82067
|
+
stableId: `resourceTemplate:${entry.caplet.server}:${entry.downstreamUriTemplate}`,
|
|
82068
|
+
kind: "resourceTemplate",
|
|
82069
|
+
uriTemplate: entry.uriTemplate,
|
|
82070
|
+
downstreamUriTemplate: entry.downstreamUriTemplate,
|
|
82071
|
+
title: entry.resourceTemplate.name,
|
|
82072
|
+
description: entry.resourceTemplate.description,
|
|
82073
|
+
...entry.resourceTemplate.mimeType ? { mimeType: entry.resourceTemplate.mimeType } : {},
|
|
82074
|
+
schemaHash: null,
|
|
82075
|
+
capletId: entry.caplet.server,
|
|
82076
|
+
shadowing: shadowingPolicy(entry.caplet)
|
|
82077
|
+
};
|
|
82078
|
+
}
|
|
82079
|
+
function promptExport(entry) {
|
|
82080
|
+
const inputSchema = { arguments: entry.prompt.arguments ?? [] };
|
|
82081
|
+
return {
|
|
82082
|
+
stableId: `prompt:${entry.caplet.server}:${entry.downstreamName}`,
|
|
82083
|
+
kind: "prompt",
|
|
82084
|
+
name: entry.name,
|
|
82085
|
+
downstreamName: entry.downstreamName,
|
|
82086
|
+
title: entry.prompt.name,
|
|
82087
|
+
description: entry.prompt.description,
|
|
82088
|
+
inputSchema,
|
|
82089
|
+
schemaHash: schemaHash(inputSchema),
|
|
82090
|
+
capletId: entry.caplet.server,
|
|
82091
|
+
shadowing: shadowingPolicy(entry.caplet)
|
|
82092
|
+
};
|
|
82093
|
+
}
|
|
82094
|
+
function completionExports(snapshot) {
|
|
82095
|
+
return [...new Map([...snapshot.directPrompts, ...snapshot.directResourceTemplates].map((entry) => [entry.caplet.server, entry.caplet])).entries()].sort(([left], [right]) => left.localeCompare(right)).map(([capletId, caplet]) => ({
|
|
82096
|
+
stableId: `completion:${capletId}`,
|
|
82097
|
+
kind: "completion",
|
|
82098
|
+
name: `${capletId}:complete`,
|
|
82099
|
+
title: "Complete",
|
|
82100
|
+
description: `MCP completion for ${capletId}.`,
|
|
82101
|
+
schemaHash: null,
|
|
82102
|
+
capletId,
|
|
82103
|
+
shadowing: shadowingPolicy(caplet)
|
|
82104
|
+
}));
|
|
82105
|
+
}
|
|
82106
|
+
function shadowingPolicy(caplet) {
|
|
82107
|
+
return caplet.shadowing ?? "forbid";
|
|
82108
|
+
}
|
|
82109
|
+
function sortAttachProjectionInput(partial) {
|
|
82110
|
+
return {
|
|
82111
|
+
caplets: sortByStableId(partial.caplets),
|
|
82112
|
+
tools: sortByStableId(partial.tools),
|
|
82113
|
+
resources: sortByStableId(partial.resources),
|
|
82114
|
+
resourceTemplates: sortByStableId(partial.resourceTemplates),
|
|
82115
|
+
prompts: sortByStableId(partial.prompts),
|
|
82116
|
+
completions: sortByStableId(partial.completions),
|
|
82117
|
+
codeModeCaplets: sortByStableId(partial.codeModeCaplets),
|
|
82118
|
+
diagnostics: [...partial.diagnostics].sort((left, right) => diagnosticSortKey(left).localeCompare(diagnosticSortKey(right)))
|
|
82119
|
+
};
|
|
82120
|
+
}
|
|
82121
|
+
function sortByStableId(entries) {
|
|
82122
|
+
return [...entries].sort((left, right) => left.stableId.localeCompare(right.stableId));
|
|
82123
|
+
}
|
|
82124
|
+
function diagnosticSortKey(diagnostic) {
|
|
82125
|
+
return stableJsonStringify({
|
|
82126
|
+
code: diagnostic.code,
|
|
82127
|
+
capletId: diagnostic.capletId ?? "",
|
|
82128
|
+
message: diagnostic.message
|
|
82129
|
+
});
|
|
82130
|
+
}
|
|
82131
|
+
function revisionFor(value) {
|
|
82132
|
+
return `sha256:${createHash("sha256").update(stableJsonStringify(value)).digest("hex")}`;
|
|
82133
|
+
}
|
|
82134
|
+
function withRevisionExportIds(revision, partial) {
|
|
82135
|
+
return {
|
|
82136
|
+
...partial,
|
|
82137
|
+
caplets: partial.caplets.map((entry) => withExportId(revision, entry)),
|
|
82138
|
+
tools: partial.tools.map((entry) => withExportId(revision, entry)),
|
|
82139
|
+
resources: partial.resources.map((entry) => withExportId(revision, entry)),
|
|
82140
|
+
resourceTemplates: partial.resourceTemplates.map((entry) => withExportId(revision, entry)),
|
|
82141
|
+
prompts: partial.prompts.map((entry) => withExportId(revision, entry)),
|
|
82142
|
+
completions: partial.completions.map((entry) => withExportId(revision, entry)),
|
|
82143
|
+
codeModeCaplets: partial.codeModeCaplets.map((entry) => withExportId(revision, entry))
|
|
82144
|
+
};
|
|
82145
|
+
}
|
|
82146
|
+
function withExportId(revision, entry) {
|
|
82147
|
+
return {
|
|
82148
|
+
...entry,
|
|
82149
|
+
exportId: `${revision}:${entry.stableId}`
|
|
82150
|
+
};
|
|
82151
|
+
}
|
|
82152
|
+
function routesFor(manifest) {
|
|
82153
|
+
const routes = /* @__PURE__ */ new Map();
|
|
82154
|
+
for (const entry of manifest.caplets) routes.set(entry.exportId, {
|
|
82155
|
+
kind: "caplet",
|
|
82156
|
+
capletId: entry.capletId
|
|
82157
|
+
});
|
|
82158
|
+
for (const entry of manifest.tools) routes.set(entry.exportId, {
|
|
82159
|
+
kind: "tool",
|
|
82160
|
+
capletId: entry.capletId,
|
|
82161
|
+
downstreamName: entry.downstreamName
|
|
82162
|
+
});
|
|
82163
|
+
for (const entry of manifest.resources) routes.set(entry.exportId, {
|
|
82164
|
+
kind: "resource",
|
|
82165
|
+
capletId: entry.capletId,
|
|
82166
|
+
downstreamUri: entry.downstreamUri
|
|
82167
|
+
});
|
|
82168
|
+
for (const entry of manifest.resourceTemplates) routes.set(entry.exportId, {
|
|
82169
|
+
kind: "resourceTemplate",
|
|
82170
|
+
capletId: entry.capletId,
|
|
82171
|
+
downstreamUriTemplate: entry.downstreamUriTemplate
|
|
82172
|
+
});
|
|
82173
|
+
for (const entry of manifest.prompts) routes.set(entry.exportId, {
|
|
82174
|
+
kind: "prompt",
|
|
82175
|
+
capletId: entry.capletId,
|
|
82176
|
+
downstreamName: entry.downstreamName
|
|
82177
|
+
});
|
|
82178
|
+
for (const entry of manifest.completions) routes.set(entry.exportId, {
|
|
82179
|
+
kind: "completion",
|
|
82180
|
+
capletId: entry.capletId
|
|
82181
|
+
});
|
|
82182
|
+
for (const entry of manifest.codeModeCaplets) routes.set(entry.exportId, {
|
|
82183
|
+
kind: "caplet",
|
|
82184
|
+
capletId: entry.capletId
|
|
82185
|
+
});
|
|
82186
|
+
return routes;
|
|
82187
|
+
}
|
|
82188
|
+
function normalizeCompletionInput(manifest, capletId, input) {
|
|
82189
|
+
if (!isRecord$4(input)) return {};
|
|
82190
|
+
const ref = input.ref;
|
|
82191
|
+
if (!isRecord$4(ref)) return input;
|
|
82192
|
+
if (ref.type === "prompt" && typeof ref.name === "string") {
|
|
82193
|
+
const prompt = manifest.prompts.find((entry) => entry.capletId === capletId && (entry.name === ref.name || entry.downstreamName === ref.name));
|
|
82194
|
+
if (!prompt) return input;
|
|
82195
|
+
return {
|
|
82196
|
+
...input,
|
|
82197
|
+
ref: {
|
|
82198
|
+
...ref,
|
|
82199
|
+
name: prompt.downstreamName
|
|
82200
|
+
}
|
|
82201
|
+
};
|
|
82202
|
+
}
|
|
82203
|
+
if (ref.type === "resourceTemplate" && typeof ref.uri === "string") {
|
|
82204
|
+
const resourceTemplate = manifest.resourceTemplates.find((entry) => entry.capletId === capletId && (entry.uriTemplate === ref.uri || entry.downstreamUriTemplate === ref.uri));
|
|
82205
|
+
if (!resourceTemplate) return input;
|
|
82206
|
+
return {
|
|
82207
|
+
...input,
|
|
82208
|
+
ref: {
|
|
82209
|
+
...ref,
|
|
82210
|
+
uri: resourceTemplate.downstreamUriTemplate
|
|
82211
|
+
}
|
|
82212
|
+
};
|
|
82213
|
+
}
|
|
82214
|
+
return input;
|
|
82215
|
+
}
|
|
82216
|
+
function isRecord$4(value) {
|
|
82217
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
82218
|
+
}
|
|
82219
|
+
function stringifyRecord(record) {
|
|
82220
|
+
return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, typeof value === "string" ? value : JSON.stringify(value)]));
|
|
82221
|
+
}
|
|
82222
|
+
function downstreamResourceUri$1(capletId, uri) {
|
|
82223
|
+
if (!uri.startsWith("caplets://")) return uri;
|
|
82224
|
+
const decoded = decodeDirectResourceUri(uri);
|
|
82225
|
+
if (decoded.capletId !== capletId) throw new CapletsError("ATTACH_EXPORT_NOT_FOUND", "Attach resource template URI belongs to a different Caplet.");
|
|
82226
|
+
return decoded.downstreamUri;
|
|
82227
|
+
}
|
|
82228
|
+
//#endregion
|
|
80971
82229
|
//#region src/native/remote.ts
|
|
82230
|
+
const ATTACH_SESSION_UNSUPPORTED_RETRY_MS = 6e4;
|
|
80972
82231
|
function createSdkRemoteCapletsClient(options) {
|
|
80973
82232
|
const listeners = /* @__PURE__ */ new Set();
|
|
80974
82233
|
let manifest;
|
|
@@ -80976,18 +82235,50 @@ function createSdkRemoteCapletsClient(options) {
|
|
|
80976
82235
|
let eventsAbort;
|
|
80977
82236
|
let eventsStartInFlight;
|
|
80978
82237
|
let eventsReconnectTimer;
|
|
82238
|
+
let attachSessionId;
|
|
82239
|
+
let attachSessionInFlight;
|
|
82240
|
+
let attachSessionsUnsupportedUntil = 0;
|
|
80979
82241
|
let closed = false;
|
|
80980
82242
|
const resolveRuntimeOptions = async () => {
|
|
80981
82243
|
return options.resolveRuntimeOptions ? await options.resolveRuntimeOptions() : options;
|
|
80982
82244
|
};
|
|
80983
82245
|
const fetchFor = (runtimeOptions) => runtimeOptions.fetch ?? fetch;
|
|
80984
82246
|
const fetchCurrentManifest = async () => {
|
|
80985
|
-
|
|
80986
|
-
|
|
82247
|
+
return await withAttachSessionRetry(async (runtimeOptions, sessionId) => {
|
|
82248
|
+
return await fetchAttachManifest(runtimeOptions.url, runtimeOptions.requestInit, sessionId, fetchFor(runtimeOptions));
|
|
82249
|
+
});
|
|
80987
82250
|
};
|
|
80988
82251
|
const invokeCurrentExport = async (body) => {
|
|
82252
|
+
return await withAttachSessionRetry(async (runtimeOptions, sessionId) => {
|
|
82253
|
+
return await invokeAttachExport(runtimeOptions.url, runtimeOptions.requestInit, sessionId, fetchFor(runtimeOptions), body);
|
|
82254
|
+
});
|
|
82255
|
+
};
|
|
82256
|
+
const ensureAttachSession = async (runtimeOptions) => {
|
|
82257
|
+
if (!options.attachSessionMetadata) return void 0;
|
|
82258
|
+
if (attachSessionsUnsupportedUntil > Date.now()) return void 0;
|
|
82259
|
+
attachSessionsUnsupportedUntil = 0;
|
|
82260
|
+
if (attachSessionId) return attachSessionId;
|
|
82261
|
+
if (attachSessionInFlight) return await attachSessionInFlight;
|
|
82262
|
+
attachSessionInFlight = createAttachSession(runtimeOptions.url, runtimeOptions.requestInit, fetchFor(runtimeOptions), options.attachSessionMetadata);
|
|
82263
|
+
try {
|
|
82264
|
+
attachSessionId = await attachSessionInFlight;
|
|
82265
|
+
if (!attachSessionId) attachSessionsUnsupportedUntil = Date.now() + ATTACH_SESSION_UNSUPPORTED_RETRY_MS;
|
|
82266
|
+
return attachSessionId;
|
|
82267
|
+
} finally {
|
|
82268
|
+
attachSessionInFlight = void 0;
|
|
82269
|
+
}
|
|
82270
|
+
};
|
|
82271
|
+
const withAttachSessionRetry = async (operation) => {
|
|
80989
82272
|
const runtimeOptions = await resolveRuntimeOptions();
|
|
80990
|
-
|
|
82273
|
+
const sessionId = await ensureAttachSession(runtimeOptions);
|
|
82274
|
+
if (closed) throw new CapletsError("SERVER_UNAVAILABLE", "Remote Caplets client is closed.");
|
|
82275
|
+
try {
|
|
82276
|
+
return await operation(runtimeOptions, sessionId);
|
|
82277
|
+
} catch (error) {
|
|
82278
|
+
if (!options.attachSessionMetadata || attachSessionsUnsupportedUntil > Date.now() || !sessionId || !isAttachSessionNotFound(error)) throw error;
|
|
82279
|
+
if (attachSessionId === sessionId) attachSessionId = void 0;
|
|
82280
|
+
return await operation(runtimeOptions, await ensureAttachSession(runtimeOptions));
|
|
82281
|
+
}
|
|
80991
82282
|
};
|
|
80992
82283
|
const clearEventsReconnectTimer = () => {
|
|
80993
82284
|
if (eventsReconnectTimer) {
|
|
@@ -81007,7 +82298,9 @@ function createSdkRemoteCapletsClient(options) {
|
|
|
81007
82298
|
try {
|
|
81008
82299
|
const runtimeOptions = await resolveRuntimeOptions();
|
|
81009
82300
|
if (closed || eventsAbort || listeners.size === 0) return;
|
|
81010
|
-
|
|
82301
|
+
const sessionId = await ensureAttachSession(runtimeOptions);
|
|
82302
|
+
if (closed || eventsAbort || listeners.size === 0) return;
|
|
82303
|
+
eventsAbort = startAttachEvents(runtimeOptions.url, runtimeOptions.requestInit, sessionId, fetchFor(runtimeOptions), listeners, (closedAbort, retry) => {
|
|
81011
82304
|
if (eventsAbort !== closedAbort) return;
|
|
81012
82305
|
eventsAbort = void 0;
|
|
81013
82306
|
if (!retry || closedAbort.signal.aborted || listeners.size === 0) return;
|
|
@@ -81089,6 +82382,13 @@ function createSdkRemoteCapletsClient(options) {
|
|
|
81089
82382
|
eventsAbort?.abort();
|
|
81090
82383
|
eventsAbort = void 0;
|
|
81091
82384
|
listeners.clear();
|
|
82385
|
+
const pendingSessionId = await attachSessionInFlight?.catch(() => void 0);
|
|
82386
|
+
const sessionId = attachSessionId ?? pendingSessionId;
|
|
82387
|
+
attachSessionId = void 0;
|
|
82388
|
+
if (sessionId) await (async () => {
|
|
82389
|
+
const runtimeOptions = await resolveRuntimeOptions();
|
|
82390
|
+
await closeAttachSession(runtimeOptions.url, runtimeOptions.requestInit, fetchFor(runtimeOptions), sessionId);
|
|
82391
|
+
})().catch(() => void 0);
|
|
81092
82392
|
}
|
|
81093
82393
|
};
|
|
81094
82394
|
}
|
|
@@ -81285,16 +82585,62 @@ function remoteCodeModeCallableNativeTools$1(tools) {
|
|
|
81285
82585
|
function nativeToolRouteId(tool) {
|
|
81286
82586
|
return tool.codeModeRun ? nativeCodeModeToolId : tool.name;
|
|
81287
82587
|
}
|
|
81288
|
-
async function fetchAttachManifest(attachUrl, requestInit, fetchImpl) {
|
|
82588
|
+
async function fetchAttachManifest(attachUrl, requestInit, attachSessionId, fetchImpl) {
|
|
82589
|
+
const headers = attachHeaders(requestInit, attachSessionId);
|
|
81289
82590
|
const response = await fetchImpl(new URL("manifest", slashUrl(attachUrl)), {
|
|
81290
82591
|
...requestInit,
|
|
81291
|
-
method: "GET"
|
|
82592
|
+
method: "GET",
|
|
82593
|
+
headers
|
|
81292
82594
|
});
|
|
81293
|
-
if (!response.ok)
|
|
82595
|
+
if (!response.ok) {
|
|
82596
|
+
let payload;
|
|
82597
|
+
try {
|
|
82598
|
+
payload = await response.json();
|
|
82599
|
+
} catch {
|
|
82600
|
+
payload = { error: { message: `Caplets attach manifest returned HTTP ${response.status}.` } };
|
|
82601
|
+
}
|
|
82602
|
+
throw attachPayloadError(payload, response.status, "manifest");
|
|
82603
|
+
}
|
|
81294
82604
|
return await response.json();
|
|
81295
82605
|
}
|
|
81296
|
-
async function
|
|
82606
|
+
async function createAttachSession(attachUrl, requestInit, fetchImpl, metadata) {
|
|
82607
|
+
const headers = new Headers(requestInit?.headers);
|
|
82608
|
+
headers.set("content-type", "application/json");
|
|
82609
|
+
const response = await fetchImpl(new URL("sessions", slashUrl(attachUrl)), {
|
|
82610
|
+
...requestInit,
|
|
82611
|
+
method: "POST",
|
|
82612
|
+
headers,
|
|
82613
|
+
body: JSON.stringify(metadata)
|
|
82614
|
+
});
|
|
82615
|
+
if (!response.ok) {
|
|
82616
|
+
if (response.status === 404) return void 0;
|
|
82617
|
+
let payload;
|
|
82618
|
+
try {
|
|
82619
|
+
payload = await response.json();
|
|
82620
|
+
} catch {
|
|
82621
|
+
payload = void 0;
|
|
82622
|
+
}
|
|
82623
|
+
if (response.status === 400 && isAttachSessionProjectContextRejected(payload)) return;
|
|
82624
|
+
throw new CapletsError("SERVER_UNAVAILABLE", `Caplets attach session returned HTTP ${response.status}.`);
|
|
82625
|
+
}
|
|
82626
|
+
const payload = await response.json();
|
|
82627
|
+
if (!isPlainObject(payload) || typeof payload.sessionId !== "string") throw new CapletsError("SERVER_UNAVAILABLE", "Caplets attach session response was invalid.");
|
|
82628
|
+
return payload.sessionId;
|
|
82629
|
+
}
|
|
82630
|
+
async function closeAttachSession(attachUrl, requestInit, fetchImpl, attachSessionId) {
|
|
82631
|
+
await fetchImpl(new URL(`sessions/${encodeURIComponent(attachSessionId)}`, slashUrl(attachUrl)), {
|
|
82632
|
+
...requestInit,
|
|
82633
|
+
method: "DELETE",
|
|
82634
|
+
headers: attachHeaders(requestInit, attachSessionId)
|
|
82635
|
+
});
|
|
82636
|
+
}
|
|
82637
|
+
function attachHeaders(requestInit, attachSessionId) {
|
|
81297
82638
|
const headers = new Headers(requestInit?.headers);
|
|
82639
|
+
if (attachSessionId) headers.set(CAPLETS_ATTACH_SESSION_HEADER, attachSessionId);
|
|
82640
|
+
return headers;
|
|
82641
|
+
}
|
|
82642
|
+
async function invokeAttachExport(attachUrl, requestInit, attachSessionId, fetchImpl, body) {
|
|
82643
|
+
const headers = attachHeaders(requestInit, attachSessionId);
|
|
81298
82644
|
headers.set("content-type", "application/json");
|
|
81299
82645
|
const response = await fetchImpl(new URL("invoke", slashUrl(attachUrl)), {
|
|
81300
82646
|
...requestInit,
|
|
@@ -81306,10 +82652,10 @@ async function invokeAttachExport(attachUrl, requestInit, fetchImpl, body) {
|
|
|
81306
82652
|
try {
|
|
81307
82653
|
payload = await response.json();
|
|
81308
82654
|
} catch (error) {
|
|
81309
|
-
if (!response.ok) throw attachPayloadError({ error: { message: `Caplets attach invoke returned HTTP ${response.status}.` } }, response.status);
|
|
82655
|
+
if (!response.ok) throw attachPayloadError({ error: { message: `Caplets attach invoke returned HTTP ${response.status}.` } }, response.status, "invoke");
|
|
81310
82656
|
throw error;
|
|
81311
82657
|
}
|
|
81312
|
-
if (!response.ok) throw attachPayloadError(payload, response.status);
|
|
82658
|
+
if (!response.ok) throw attachPayloadError(payload, response.status, "invoke");
|
|
81313
82659
|
if (isPlainObject(payload) && payload.ok === true && "data" in payload) return payload.data;
|
|
81314
82660
|
return payload;
|
|
81315
82661
|
}
|
|
@@ -81409,7 +82755,7 @@ function primitiveInvokeInput(capletId, operation, input) {
|
|
|
81409
82755
|
function toolsFromManifest(manifest) {
|
|
81410
82756
|
const codeModeCaplets = manifest.codeModeCaplets ?? [];
|
|
81411
82757
|
const codeModeMarker = attachCodeModeMarker(codeModeCaplets);
|
|
81412
|
-
const codeModeShadowing = codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : "allow";
|
|
82758
|
+
const codeModeShadowing = codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : codeModeCaplets.some((entry) => entry.shadowing === "namespace") ? "namespace" : "allow";
|
|
81413
82759
|
return [
|
|
81414
82760
|
...manifest.caplets.map((entry) => ({
|
|
81415
82761
|
name: entry.capletId,
|
|
@@ -81566,9 +82912,9 @@ function slashUrl(url) {
|
|
|
81566
82912
|
next.pathname = next.pathname.endsWith("/") ? next.pathname : `${next.pathname}/`;
|
|
81567
82913
|
return next;
|
|
81568
82914
|
}
|
|
81569
|
-
function attachPayloadError(payload, status) {
|
|
82915
|
+
function attachPayloadError(payload, status, endpoint) {
|
|
81570
82916
|
const error = isPlainObject(payload) && isPlainObject(payload.error) ? payload.error : void 0;
|
|
81571
|
-
const message = typeof error?.message === "string" ? error.message : `Caplets attach
|
|
82917
|
+
const message = typeof error?.message === "string" ? error.message : `Caplets attach ${endpoint} returned HTTP ${status}.`;
|
|
81572
82918
|
const thrown = new Error(message);
|
|
81573
82919
|
thrown.status = status;
|
|
81574
82920
|
if (error && "code" in error) thrown.code = error.code;
|
|
@@ -81577,14 +82923,23 @@ function attachPayloadError(payload, status) {
|
|
|
81577
82923
|
function isAttachManifestStale(error) {
|
|
81578
82924
|
return isPlainObject(error) && error.code === "ATTACH_MANIFEST_STALE";
|
|
81579
82925
|
}
|
|
81580
|
-
function
|
|
82926
|
+
function isAttachSessionNotFound(error) {
|
|
82927
|
+
return error.code === "REQUEST_INVALID" && /\battach session was not found\b/iu.test(errorMessage$1(error));
|
|
82928
|
+
}
|
|
82929
|
+
function isAttachSessionProjectContextRejected(payload) {
|
|
82930
|
+
const error = isPlainObject(payload) && isPlainObject(payload.error) ? payload.error : void 0;
|
|
82931
|
+
return error?.code === "REQUEST_INVALID" && typeof error.message === "string" && /\bproject context is only accepted by loopback runtimes\b/iu.test(error.message);
|
|
82932
|
+
}
|
|
82933
|
+
function startAttachEvents(attachUrl, requestInit, attachSessionId, fetchImpl, listeners, onClose) {
|
|
81581
82934
|
const abort = new AbortController();
|
|
81582
82935
|
let retry = true;
|
|
81583
82936
|
(async () => {
|
|
81584
82937
|
try {
|
|
82938
|
+
const headers = attachHeaders(requestInit, attachSessionId);
|
|
81585
82939
|
const response = await fetchImpl(new URL("events", slashUrl(attachUrl)), {
|
|
81586
82940
|
...requestInit,
|
|
81587
82941
|
method: "GET",
|
|
82942
|
+
headers,
|
|
81588
82943
|
signal: abort.signal
|
|
81589
82944
|
});
|
|
81590
82945
|
if (!response.ok) {
|
|
@@ -81711,6 +83066,119 @@ function isPermanentRemoteCredentialsCode(code) {
|
|
|
81711
83066
|
return code === "remote_credentials_required" || code === "remote_credentials_revoked" || code === "remote_auth_failed";
|
|
81712
83067
|
}
|
|
81713
83068
|
//#endregion
|
|
83069
|
+
//#region src/exposure/namespace.ts
|
|
83070
|
+
function resolveNamespaceExposure(entries, options = {}) {
|
|
83071
|
+
const hashLength = options.hashLength ?? 4;
|
|
83072
|
+
const maxHashLength = options.maxHashLength ?? 8;
|
|
83073
|
+
const groups = groupByBaseId(entries);
|
|
83074
|
+
const visibleRecords = [];
|
|
83075
|
+
const suppressedBareIds = /* @__PURE__ */ new Map();
|
|
83076
|
+
const unavailableDiagnostics = [];
|
|
83077
|
+
const reservedBareIds = new Set(groups.keys());
|
|
83078
|
+
for (const [baseId, group] of groups) {
|
|
83079
|
+
if (group.length === 1) {
|
|
83080
|
+
visibleRecords.push(visibleRecord(group[0], baseId, false));
|
|
83081
|
+
continue;
|
|
83082
|
+
}
|
|
83083
|
+
if (!isNamespaceCollisionGroup(group)) {
|
|
83084
|
+
visibleRecords.push(visibleRecord(nonNamespaceWinner(group), baseId, false));
|
|
83085
|
+
continue;
|
|
83086
|
+
}
|
|
83087
|
+
const diagnostics = validateNamespaceGroup(baseId, group);
|
|
83088
|
+
if (diagnostics.length > 0) {
|
|
83089
|
+
unavailableDiagnostics.push(...diagnostics);
|
|
83090
|
+
continue;
|
|
83091
|
+
}
|
|
83092
|
+
const resolved = qualifyNamespaceGroup(group, {
|
|
83093
|
+
baseId,
|
|
83094
|
+
hashLength,
|
|
83095
|
+
maxHashLength,
|
|
83096
|
+
reservedBareIds
|
|
83097
|
+
});
|
|
83098
|
+
if ("diagnostic" in resolved) {
|
|
83099
|
+
unavailableDiagnostics.push(resolved.diagnostic);
|
|
83100
|
+
continue;
|
|
83101
|
+
}
|
|
83102
|
+
visibleRecords.push(...resolved.records);
|
|
83103
|
+
suppressedBareIds.set(baseId, diagnostic(baseId, "namespace_collision", group, resolved.records.map((record) => record.id)));
|
|
83104
|
+
}
|
|
83105
|
+
return {
|
|
83106
|
+
visibleRecords,
|
|
83107
|
+
routes: new Map(visibleRecords.map((record) => [record.id, record.route])),
|
|
83108
|
+
suppressedBareIds,
|
|
83109
|
+
unavailableDiagnostics
|
|
83110
|
+
};
|
|
83111
|
+
}
|
|
83112
|
+
function groupByBaseId(entries) {
|
|
83113
|
+
const groups = /* @__PURE__ */ new Map();
|
|
83114
|
+
for (const entry of entries) groups.set(entry.baseId, [...groups.get(entry.baseId) ?? [], entry]);
|
|
83115
|
+
return groups;
|
|
83116
|
+
}
|
|
83117
|
+
function isNamespaceCollisionGroup(group) {
|
|
83118
|
+
const upstreams = group.filter((entry) => entry.sourceKind === "upstream");
|
|
83119
|
+
return upstreams.length > 0 && upstreams.every((entry) => entry.shadowing === "namespace");
|
|
83120
|
+
}
|
|
83121
|
+
function nonNamespaceWinner(group) {
|
|
83122
|
+
const forbiddingUpstream = group.find((entry) => entry.sourceKind === "upstream" && entry.shadowing === "forbid");
|
|
83123
|
+
if (forbiddingUpstream) return forbiddingUpstream;
|
|
83124
|
+
const local = group.find((entry) => entry.sourceKind === "local");
|
|
83125
|
+
if (local) return local;
|
|
83126
|
+
return group.find((entry) => entry.sourceKind === "upstream") ?? group[0];
|
|
83127
|
+
}
|
|
83128
|
+
function validateNamespaceGroup(baseId, group) {
|
|
83129
|
+
const diagnostics = [];
|
|
83130
|
+
for (const entry of group) {
|
|
83131
|
+
if (!entry.durableSourceIdentity) {
|
|
83132
|
+
diagnostics.push(diagnostic(baseId, "missing_durable_source_identity", group, []));
|
|
83133
|
+
break;
|
|
83134
|
+
}
|
|
83135
|
+
if (entry.namespaceAlias && !NAMESPACE_ALIAS_LABEL_PATTERN.test(entry.namespaceAlias)) {
|
|
83136
|
+
diagnostics.push(diagnostic(baseId, "namespace_alias_invalid", group, []));
|
|
83137
|
+
break;
|
|
83138
|
+
}
|
|
83139
|
+
}
|
|
83140
|
+
return diagnostics;
|
|
83141
|
+
}
|
|
83142
|
+
function qualifyNamespaceGroup(group, options) {
|
|
83143
|
+
const ids = group.map((entry) => qualifiedId(entry, options.baseId, options.hashLength));
|
|
83144
|
+
if (!(new Set(ids).size !== ids.length || ids.some((id) => options.reservedBareIds.has(id) || !SERVER_ID_PATTERN.test(id)))) return { records: group.map((entry, index) => visibleRecord(entry, ids[index], true)) };
|
|
83145
|
+
return { diagnostic: diagnostic(options.baseId, "generated_id_collision", group, []) };
|
|
83146
|
+
}
|
|
83147
|
+
function qualifiedId(entry, baseId, hashLength) {
|
|
83148
|
+
return `${namespaceLabel(entry)}-${createHash("sha256").update(entry.durableSourceIdentity ?? "").digest("hex").slice(0, hashLength)}__${baseId}`;
|
|
83149
|
+
}
|
|
83150
|
+
function visibleRecord(entry, id, namespaced) {
|
|
83151
|
+
return {
|
|
83152
|
+
...entry,
|
|
83153
|
+
id,
|
|
83154
|
+
label: namespaceLabel(entry),
|
|
83155
|
+
namespaced
|
|
83156
|
+
};
|
|
83157
|
+
}
|
|
83158
|
+
function namespaceLabel(entry) {
|
|
83159
|
+
return entry.namespaceAlias ?? entry.sourceLabel ?? entry.sourceKind;
|
|
83160
|
+
}
|
|
83161
|
+
function diagnostic(requestedId, reason, group, alternatives) {
|
|
83162
|
+
return {
|
|
83163
|
+
requestedId,
|
|
83164
|
+
reason,
|
|
83165
|
+
alternatives,
|
|
83166
|
+
sources: group.map((entry) => ({
|
|
83167
|
+
sourceKind: entry.sourceKind,
|
|
83168
|
+
label: namespaceLabel(entry),
|
|
83169
|
+
...entry.durableSourceIdentity ? { durableSourceIdentity: entry.durableSourceIdentity } : {}
|
|
83170
|
+
})),
|
|
83171
|
+
hint: diagnosticHint(requestedId, reason, alternatives)
|
|
83172
|
+
};
|
|
83173
|
+
}
|
|
83174
|
+
function diagnosticHint(requestedId, reason, alternatives) {
|
|
83175
|
+
if (reason === "namespace_collision") return `Caplet '${requestedId}' is unavailable because namespace shadowing exposes qualified alternatives: ${alternatives.join(", ")}.`;
|
|
83176
|
+
if (reason === "missing_durable_source_identity") return `Caplet '${requestedId}' could not be namespaced because at least one source has no durable identity.`;
|
|
83177
|
+
if (reason === "namespace_alias_invalid") return `Caplet '${requestedId}' could not be namespaced because an alias label is invalid.`;
|
|
83178
|
+
if (reason === "unsupported_protocol") return `Caplet '${requestedId}' could not be namespaced because a source protocol cannot represent namespace metadata.`;
|
|
83179
|
+
return `Caplet '${requestedId}' could not be namespaced because generated qualified IDs were not unique.`;
|
|
83180
|
+
}
|
|
83181
|
+
//#endregion
|
|
81714
83182
|
//#region src/cloud-auth/errors.ts
|
|
81715
83183
|
const SECRET_PATTERN = /(cap_access_[a-z0-9._~+/=-]+|cap_refresh_[a-z0-9._~+/=-]+|one_time_code_[a-z0-9._~+/=-]+|Bearer\s+)[^\s"]*/giu;
|
|
81716
83184
|
function redactCloudAuthSecrets(value) {
|
|
@@ -82852,7 +84320,11 @@ var DefaultNativeCapletsService = class {
|
|
|
82852
84320
|
this.writeErr = options.writeErr ?? (() => void 0);
|
|
82853
84321
|
this.engine = new CapletsEngine({
|
|
82854
84322
|
...options,
|
|
82855
|
-
writeErr: this.writeErr
|
|
84323
|
+
writeErr: this.writeErr,
|
|
84324
|
+
telemetrySurface: options.telemetrySurface ?? "native",
|
|
84325
|
+
telemetryVisibility: options.telemetryVisibility ?? "hidden",
|
|
84326
|
+
telemetryRuntimeMode: options.telemetryRuntimeMode ?? runtimeModeFromNativeOptions(options),
|
|
84327
|
+
telemetryIntegration: options.telemetryIntegration ?? "native"
|
|
82856
84328
|
});
|
|
82857
84329
|
this.postReloadRefresh = this.refreshExposureSnapshot({ emitToolsChanged: this.hasSnapshotBackedDirectExposure() });
|
|
82858
84330
|
this.unsubscribeEngineReload = this.engine.onReload(() => {
|
|
@@ -82883,7 +84355,16 @@ var DefaultNativeCapletsService = class {
|
|
|
82883
84355
|
];
|
|
82884
84356
|
}
|
|
82885
84357
|
async execute(capletId, request) {
|
|
82886
|
-
if (capletId === "code_mode")
|
|
84358
|
+
if (capletId === "code_mode") {
|
|
84359
|
+
const started = Date.now();
|
|
84360
|
+
const envelope = await executeCodeModeRunNative(this.codeModeDelegate(), request, this.codeModeSessions);
|
|
84361
|
+
const parsed = codeModeRunInputSchema.safeParse(request);
|
|
84362
|
+
this.engine.captureCodeModeOutcome(envelope, {
|
|
84363
|
+
started,
|
|
84364
|
+
...parsed.success && parsed.data.timeoutMs !== void 0 ? { timeoutMs: parsed.data.timeoutMs } : {}
|
|
84365
|
+
}).catch(() => void 0);
|
|
84366
|
+
return envelope;
|
|
84367
|
+
}
|
|
82887
84368
|
const route = this.directToolRoutes.get(capletId);
|
|
82888
84369
|
if (route) {
|
|
82889
84370
|
if (isMcpPrimitiveRoute(route.operationName)) return await this.engine.execute(route.capletId, nativeMcpPrimitiveRequest(route.operationName, request));
|
|
@@ -82891,6 +84372,9 @@ var DefaultNativeCapletsService = class {
|
|
|
82891
84372
|
}
|
|
82892
84373
|
return await this.engine.execute(capletId, request);
|
|
82893
84374
|
}
|
|
84375
|
+
async captureCodeModeOutcome(envelope, options) {
|
|
84376
|
+
await this.engine.captureCodeModeOutcome(envelope, options);
|
|
84377
|
+
}
|
|
82894
84378
|
codeModeService() {
|
|
82895
84379
|
return this.codeModeDelegate();
|
|
82896
84380
|
}
|
|
@@ -83111,9 +84595,39 @@ function nativeMcpPrimitiveRequest(operationName, request) {
|
|
|
83111
84595
|
};
|
|
83112
84596
|
return { operation: operationName };
|
|
83113
84597
|
}
|
|
84598
|
+
function operationFromNativeRequest(request) {
|
|
84599
|
+
return isRecord(request) ? request.operation : void 0;
|
|
84600
|
+
}
|
|
83114
84601
|
function isRecord(value) {
|
|
83115
84602
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
83116
84603
|
}
|
|
84604
|
+
function runtimeModeFromNativeOptions(options) {
|
|
84605
|
+
if (options.mode === "local") return "local";
|
|
84606
|
+
if (options.mode === "remote") return "remote";
|
|
84607
|
+
if (options.mode === "cloud") return "cloud";
|
|
84608
|
+
if (options.remote?.url) return "remote";
|
|
84609
|
+
const envMode = options.telemetryEnv?.CAPLETS_MODE ?? process.env.CAPLETS_MODE;
|
|
84610
|
+
if (envMode === "remote" || envMode === "cloud" || envMode === "local") return envMode;
|
|
84611
|
+
return "local";
|
|
84612
|
+
}
|
|
84613
|
+
function telemetryConfigFromNativeOptions(options) {
|
|
84614
|
+
const configPath = resolveConfigPath(options.configPath);
|
|
84615
|
+
const config = createLocalOverlayConfigLoader(options)(configPath, options.projectConfigPath ?? resolveProjectConfigPath());
|
|
84616
|
+
const explicitTelemetry = readTelemetryOnlyConfig(configPath);
|
|
84617
|
+
return explicitTelemetry === void 0 ? config : {
|
|
84618
|
+
...config,
|
|
84619
|
+
telemetry: explicitTelemetry
|
|
84620
|
+
};
|
|
84621
|
+
}
|
|
84622
|
+
function readTelemetryOnlyConfig(path) {
|
|
84623
|
+
if (!existsSync(path)) return void 0;
|
|
84624
|
+
try {
|
|
84625
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
84626
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? typeof parsed.telemetry === "boolean" ? parsed.telemetry : void 0 : void 0;
|
|
84627
|
+
} catch {
|
|
84628
|
+
return;
|
|
84629
|
+
}
|
|
84630
|
+
}
|
|
83117
84631
|
function codeModeRunNativeTool(capletTools) {
|
|
83118
84632
|
const codeModeCaplets = capletTools.map((tool) => ({
|
|
83119
84633
|
id: tool.caplet,
|
|
@@ -83197,7 +84711,7 @@ function createLocalOverlayService(options) {
|
|
|
83197
84711
|
}
|
|
83198
84712
|
function createCompositeRemoteService(remoteOptions, local, options, authKind) {
|
|
83199
84713
|
const { remote, presence } = createCompositeRemoteParts(remoteOptions, local, options, authKind);
|
|
83200
|
-
return new CompositeNativeCapletsService(remote, local, options, presence);
|
|
84714
|
+
return new CompositeNativeCapletsService(remote, local, options, remoteOptions.url.toString(), presence);
|
|
83201
84715
|
}
|
|
83202
84716
|
function createCompositeRemoteParts(remoteOptions, local, options, authKind, resolveRuntimeRemoteOptions) {
|
|
83203
84717
|
const remote = new RemoteNativeCapletsService({
|
|
@@ -83207,7 +84721,7 @@ function createCompositeRemoteParts(remoteOptions, local, options, authKind, res
|
|
|
83207
84721
|
authKind,
|
|
83208
84722
|
...options.writeErr ? { writeErr: options.writeErr } : {}
|
|
83209
84723
|
});
|
|
83210
|
-
const presence = createProjectBindingSessionManager(remoteOptions.cloud, local, options);
|
|
84724
|
+
const presence = createProjectBindingSessionManager(remoteOptions.cloud, remoteOptions, local, options);
|
|
83211
84725
|
return {
|
|
83212
84726
|
remote,
|
|
83213
84727
|
...presence ? { presence } : {}
|
|
@@ -83215,13 +84729,33 @@ function createCompositeRemoteParts(remoteOptions, local, options, authKind, res
|
|
|
83215
84729
|
}
|
|
83216
84730
|
function createRemoteClient(remoteOptions, options, authKind, resolveRuntimeRemoteOptions) {
|
|
83217
84731
|
if (options.remoteClientFactory) return options.remoteClientFactory(remoteOptions);
|
|
84732
|
+
const attachSessionMetadata = isLoopbackRemote(remoteOptions) ? attachSessionMetadataForOptions(options) : void 0;
|
|
83218
84733
|
return createSdkRemoteCapletsClient({
|
|
83219
84734
|
...remoteOptions,
|
|
83220
84735
|
authKind,
|
|
83221
84736
|
...options.writeErr ? { writeErr: options.writeErr } : {},
|
|
84737
|
+
...attachSessionMetadata ? { attachSessionMetadata } : {},
|
|
83222
84738
|
...resolveRuntimeRemoteOptions ? { resolveRuntimeOptions: resolveRuntimeRemoteOptions } : {}
|
|
83223
84739
|
});
|
|
83224
84740
|
}
|
|
84741
|
+
function attachSessionMetadataForOptions(options) {
|
|
84742
|
+
if (!options.projectRoot) return void 0;
|
|
84743
|
+
const projectRoot = canonicalProjectRootForMetadata(options.projectRoot);
|
|
84744
|
+
return {
|
|
84745
|
+
projectRoot,
|
|
84746
|
+
projectConfigPath: resolve(projectRoot, ".caplets", "config.json")
|
|
84747
|
+
};
|
|
84748
|
+
}
|
|
84749
|
+
function canonicalProjectRootForMetadata(projectRoot) {
|
|
84750
|
+
try {
|
|
84751
|
+
return realpathSync(projectRoot);
|
|
84752
|
+
} catch {
|
|
84753
|
+
return projectRoot;
|
|
84754
|
+
}
|
|
84755
|
+
}
|
|
84756
|
+
function isLoopbackRemote(remoteOptions) {
|
|
84757
|
+
return remoteOptions.url.protocol === "http:" && isLoopbackHost(remoteOptions.url.hostname);
|
|
84758
|
+
}
|
|
83225
84759
|
var ProfileBackedNativeCapletsService = class {
|
|
83226
84760
|
options;
|
|
83227
84761
|
baseRemote;
|
|
@@ -83289,7 +84823,7 @@ var ProfileBackedNativeCapletsService = class {
|
|
|
83289
84823
|
const signature = remoteOptionsSignature(remoteOptions);
|
|
83290
84824
|
if (!this.delegate) {
|
|
83291
84825
|
const { remote, presence } = createCompositeRemoteParts(remoteOptions, this.local, this.options, this.authKind, () => this.resolveProfileRemoteOptions());
|
|
83292
|
-
this.delegate = new CompositeNativeCapletsService(remote, this.local, this.options, presence);
|
|
84826
|
+
this.delegate = new CompositeNativeCapletsService(remote, this.local, this.options, remoteOptions.url.toString(), presence);
|
|
83293
84827
|
this.unsubscribeDelegate = this.delegate.onToolsChanged((tools) => this.emit(tools));
|
|
83294
84828
|
this.remoteSignature = signature;
|
|
83295
84829
|
this.credentialExpiresAt = remoteOptions.credentialExpiresAt;
|
|
@@ -83301,7 +84835,7 @@ var ProfileBackedNativeCapletsService = class {
|
|
|
83301
84835
|
await Promise.all([remote.close(), presence?.close()]);
|
|
83302
84836
|
return;
|
|
83303
84837
|
}
|
|
83304
|
-
await this.delegate.replaceRemote(remote, presence);
|
|
84838
|
+
await this.delegate.replaceRemote(remote, remoteOptions.url.toString(), presence);
|
|
83305
84839
|
this.remoteSignature = signature;
|
|
83306
84840
|
this.credentialExpiresAt = remoteOptions.credentialExpiresAt;
|
|
83307
84841
|
} catch (error) {
|
|
@@ -83386,23 +84920,44 @@ var CompositeNativeCapletsService = class {
|
|
|
83386
84920
|
remote;
|
|
83387
84921
|
local;
|
|
83388
84922
|
options;
|
|
84923
|
+
remoteIdentity;
|
|
83389
84924
|
presence;
|
|
83390
84925
|
listeners = /* @__PURE__ */ new Set();
|
|
83391
84926
|
unsubscribeRemote;
|
|
83392
84927
|
unsubscribeLocal;
|
|
83393
84928
|
warnedShadowedLocalCaplets = /* @__PURE__ */ new Set();
|
|
83394
84929
|
tools = [];
|
|
84930
|
+
routes = /* @__PURE__ */ new Map();
|
|
84931
|
+
namespaceDiagnostics = /* @__PURE__ */ new Map();
|
|
83395
84932
|
closed = false;
|
|
83396
84933
|
batchingReload = false;
|
|
83397
84934
|
codeModeSessions = new CodeModeSessionManager();
|
|
83398
|
-
|
|
84935
|
+
telemetry;
|
|
84936
|
+
ownsTelemetryDispatcher;
|
|
84937
|
+
constructor(remote, local, options, remoteIdentity, presence) {
|
|
83399
84938
|
this.remote = remote;
|
|
83400
84939
|
this.local = local;
|
|
83401
84940
|
this.options = options;
|
|
84941
|
+
this.remoteIdentity = remoteIdentity;
|
|
83402
84942
|
this.presence = presence;
|
|
83403
84943
|
this.unsubscribeRemote = this.remote.onToolsChanged(() => this.updateMergedTools());
|
|
83404
84944
|
this.unsubscribeLocal = this.local.onToolsChanged(() => this.updateMergedTools());
|
|
83405
|
-
this.
|
|
84945
|
+
this.ownsTelemetryDispatcher = options.telemetryDispatcher === void 0;
|
|
84946
|
+
this.telemetry = createRuntimeTelemetryContext({
|
|
84947
|
+
config: telemetryConfigFromNativeOptions(options),
|
|
84948
|
+
env: options.telemetryEnv,
|
|
84949
|
+
stateDir: options.telemetryStateDir,
|
|
84950
|
+
surface: options.telemetrySurface ?? "native",
|
|
84951
|
+
visibility: options.telemetryVisibility ?? "hidden",
|
|
84952
|
+
runtimeMode: options.telemetryRuntimeMode ?? runtimeModeFromNativeOptions(options),
|
|
84953
|
+
integration: options.telemetryIntegration ?? "native",
|
|
84954
|
+
debugSink: options.telemetryDebugSink,
|
|
84955
|
+
dispatcher: options.telemetryDispatcher
|
|
84956
|
+
});
|
|
84957
|
+
const merged = this.mergeTools();
|
|
84958
|
+
this.tools = merged.tools;
|
|
84959
|
+
this.routes = merged.routes;
|
|
84960
|
+
this.namespaceDiagnostics = merged.namespaceDiagnostics;
|
|
83406
84961
|
this.startPresence();
|
|
83407
84962
|
}
|
|
83408
84963
|
listTools() {
|
|
@@ -83410,8 +84965,12 @@ var CompositeNativeCapletsService = class {
|
|
|
83410
84965
|
}
|
|
83411
84966
|
async execute(capletId, request) {
|
|
83412
84967
|
if (capletId === "code_mode") return await executeCodeModeRunNative(this, request, this.codeModeSessions);
|
|
83413
|
-
|
|
83414
|
-
return await this.
|
|
84968
|
+
const route = this.routes.get(capletId);
|
|
84969
|
+
if (route?.service === "local") return await this.local.execute(route.capletId, request);
|
|
84970
|
+
if (route?.service === "remote") return await this.executeRemote(route.capletId, request);
|
|
84971
|
+
const diagnostic = this.namespaceDiagnostics.get(capletId);
|
|
84972
|
+
if (diagnostic) throw new CapletsError("CAPLET_NAMESPACE_COLLISION", diagnostic.hint, diagnostic);
|
|
84973
|
+
return await this.executeRemote(capletId, request);
|
|
83415
84974
|
}
|
|
83416
84975
|
codeModeService() {
|
|
83417
84976
|
return {
|
|
@@ -83431,6 +84990,8 @@ var CompositeNativeCapletsService = class {
|
|
|
83431
84990
|
this.batchingReload = false;
|
|
83432
84991
|
if (remoteReloaded === void 0 || localReloaded === void 0) return false;
|
|
83433
84992
|
if (localReloaded) await this.presence?.updateAllowedCapletIds(this.local.listTools().map((tool) => tool.caplet));
|
|
84993
|
+
this.telemetry.config = telemetryConfigFromNativeOptions(this.options);
|
|
84994
|
+
this.startPresence();
|
|
83434
84995
|
this.updateMergedTools();
|
|
83435
84996
|
return remoteReloaded || localReloaded;
|
|
83436
84997
|
}
|
|
@@ -83448,19 +85009,23 @@ var CompositeNativeCapletsService = class {
|
|
|
83448
85009
|
await Promise.all([
|
|
83449
85010
|
this.remote.close(),
|
|
83450
85011
|
this.local.close(),
|
|
83451
|
-
this.presence?.close()
|
|
85012
|
+
this.presence?.close(),
|
|
85013
|
+
this.ownsTelemetryDispatcher ? this.telemetry.dispatcher.shutdown() : void 0
|
|
83452
85014
|
]);
|
|
83453
85015
|
}
|
|
83454
|
-
async replaceRemote(remote, presence) {
|
|
85016
|
+
async replaceRemote(remote, remoteIdentityOrPresence, presence) {
|
|
85017
|
+
const remoteIdentity = typeof remoteIdentityOrPresence === "string" ? remoteIdentityOrPresence : this.remoteIdentity;
|
|
85018
|
+
const nextPresence = typeof remoteIdentityOrPresence === "string" ? presence : remoteIdentityOrPresence;
|
|
83455
85019
|
if (this.closed) {
|
|
83456
|
-
await Promise.all([remote.close(),
|
|
85020
|
+
await Promise.all([remote.close(), nextPresence?.close()]);
|
|
83457
85021
|
return;
|
|
83458
85022
|
}
|
|
83459
85023
|
const previousRemote = this.remote;
|
|
83460
85024
|
const previousPresence = this.presence;
|
|
83461
85025
|
this.unsubscribeRemote();
|
|
83462
85026
|
this.remote = remote;
|
|
83463
|
-
this.
|
|
85027
|
+
this.remoteIdentity = remoteIdentity;
|
|
85028
|
+
this.presence = nextPresence;
|
|
83464
85029
|
this.unsubscribeRemote = this.remote.onToolsChanged(() => this.updateMergedTools());
|
|
83465
85030
|
await Promise.all([previousRemote.close(), previousPresence?.close()]);
|
|
83466
85031
|
if (this.closed) return;
|
|
@@ -83469,30 +85034,145 @@ var CompositeNativeCapletsService = class {
|
|
|
83469
85034
|
}
|
|
83470
85035
|
updateMergedTools() {
|
|
83471
85036
|
if (this.closed || this.batchingReload) return;
|
|
83472
|
-
const
|
|
83473
|
-
if (JSON.stringify(tools) === JSON.stringify(this.tools))
|
|
83474
|
-
|
|
85037
|
+
const merged = this.mergeTools();
|
|
85038
|
+
if (JSON.stringify(merged.tools) === JSON.stringify(this.tools)) {
|
|
85039
|
+
this.routes = merged.routes;
|
|
85040
|
+
this.namespaceDiagnostics = merged.namespaceDiagnostics;
|
|
85041
|
+
return;
|
|
85042
|
+
}
|
|
85043
|
+
this.tools = merged.tools;
|
|
85044
|
+
this.routes = merged.routes;
|
|
85045
|
+
this.namespaceDiagnostics = merged.namespaceDiagnostics;
|
|
83475
85046
|
for (const listener of this.listeners) try {
|
|
83476
85047
|
listener(this.listTools());
|
|
83477
85048
|
} catch (error) {
|
|
83478
85049
|
writeErr(this.options, `Caplets tools-changed listener failed: ${errorMessage(error)}\n`);
|
|
83479
85050
|
}
|
|
83480
85051
|
}
|
|
85052
|
+
async executeRemote(capletId, request) {
|
|
85053
|
+
const started = Date.now();
|
|
85054
|
+
try {
|
|
85055
|
+
const result = await this.remote.execute(capletId, request);
|
|
85056
|
+
this.captureRemoteToolActivation(request, result, started);
|
|
85057
|
+
return result;
|
|
85058
|
+
} catch (error) {
|
|
85059
|
+
const result = errorResult(error);
|
|
85060
|
+
this.captureRemoteReliabilityError(request, result);
|
|
85061
|
+
this.captureRemoteToolActivation(request, result, started);
|
|
85062
|
+
throw error;
|
|
85063
|
+
}
|
|
85064
|
+
}
|
|
85065
|
+
captureRemoteToolActivation(request, result, started) {
|
|
85066
|
+
captureRuntimeTelemetryEvent(this.telemetry, "caplets_tool_activation", {
|
|
85067
|
+
command_family: "native",
|
|
85068
|
+
...toolActivationProperties({
|
|
85069
|
+
config: this.telemetry.config,
|
|
85070
|
+
caplet: void 0,
|
|
85071
|
+
operation: operationFromNativeRequest(request),
|
|
85072
|
+
exposureMode: "direct",
|
|
85073
|
+
result,
|
|
85074
|
+
durationMs: Date.now() - started
|
|
85075
|
+
})
|
|
85076
|
+
}).catch(() => void 0);
|
|
85077
|
+
}
|
|
85078
|
+
captureRemoteReliabilityError(request, result) {
|
|
85079
|
+
captureRuntimeReliabilityEvent(this.telemetry, {
|
|
85080
|
+
command_family: "native",
|
|
85081
|
+
...runtimeFailureTelemetryProperties({
|
|
85082
|
+
operation: operationFromNativeRequest(request),
|
|
85083
|
+
exposureMode: "direct",
|
|
85084
|
+
result
|
|
85085
|
+
})
|
|
85086
|
+
}).catch(() => void 0);
|
|
85087
|
+
}
|
|
83481
85088
|
mergeTools() {
|
|
83482
85089
|
const allLocalTools = this.local.listTools();
|
|
83483
85090
|
const allRemoteTools = this.remote.listTools();
|
|
83484
85091
|
const remoteCodeModeTools = remoteCodeModeCallableNativeTools(allRemoteTools);
|
|
83485
85092
|
const remoteIds = remoteSuppressedCapletIds(allRemoteTools, remoteCodeModeTools);
|
|
83486
|
-
const
|
|
85093
|
+
const unsuppressedLocalTools = allLocalTools.filter((tool) => tool.codeModeRun !== true && !remoteIds.has(tool.sourceCaplet ?? tool.caplet));
|
|
83487
85094
|
this.warnShadowedLocalCaplets(allLocalTools, remoteIds);
|
|
83488
|
-
const
|
|
83489
|
-
const
|
|
83490
|
-
const
|
|
83491
|
-
|
|
85095
|
+
const unsuppressedLocalCodeModeTools = codeModeCallableNativeTools(allLocalTools, { fallbackToVisible: false }).filter((tool) => !remoteIds.has(tool.caplet));
|
|
85096
|
+
const remoteTools = allRemoteTools.filter((tool) => tool.codeModeRun !== true);
|
|
85097
|
+
const resolved = this.resolveVisibleToolIds(remoteTools, unsuppressedLocalTools, remoteCodeModeTools, unsuppressedLocalCodeModeTools);
|
|
85098
|
+
const codeModeTools = [...resolved.remoteCodeModeTools, ...resolved.localCodeModeTools];
|
|
85099
|
+
return {
|
|
85100
|
+
tools: [
|
|
85101
|
+
...resolved.remoteTools,
|
|
85102
|
+
...resolved.localTools,
|
|
85103
|
+
...codeModeTools.length > 0 ? [codeModeRunNativeTool(codeModeTools)] : []
|
|
85104
|
+
],
|
|
85105
|
+
routes: resolved.routes,
|
|
85106
|
+
namespaceDiagnostics: resolved.namespaceDiagnostics
|
|
85107
|
+
};
|
|
83492
85108
|
}
|
|
83493
|
-
|
|
83494
|
-
const
|
|
83495
|
-
|
|
85109
|
+
resolveVisibleToolIds(remoteTools, localTools, remoteCodeModeTools, localCodeModeTools) {
|
|
85110
|
+
const resolution = resolveNamespaceExposure(nativeNamespaceEntries([{
|
|
85111
|
+
service: "remote",
|
|
85112
|
+
tools: [...remoteTools, ...remoteCodeModeTools]
|
|
85113
|
+
}, {
|
|
85114
|
+
service: "local",
|
|
85115
|
+
tools: [...localTools, ...localCodeModeTools]
|
|
85116
|
+
}], {
|
|
85117
|
+
...nativeNamespaceContext(this.options),
|
|
85118
|
+
remoteIdentity: this.remoteIdentity
|
|
85119
|
+
}));
|
|
85120
|
+
const namespacedRecords = resolution.visibleRecords.filter((record) => record.namespaced);
|
|
85121
|
+
const namespacedBaseIds = new Set(namespacedRecords.map((record) => record.baseId));
|
|
85122
|
+
const diagnosticBaseIds = new Set(resolution.unavailableDiagnostics.map((diagnostic) => diagnostic.requestedId));
|
|
85123
|
+
const routes = /* @__PURE__ */ new Map();
|
|
85124
|
+
const namespaceDiagnostics = new Map(resolution.suppressedBareIds);
|
|
85125
|
+
for (const diagnostic of resolution.unavailableDiagnostics) namespaceDiagnostics.set(diagnostic.requestedId, diagnostic);
|
|
85126
|
+
const alternativesByBaseId = /* @__PURE__ */ new Map();
|
|
85127
|
+
const staleIdsByBaseId = /* @__PURE__ */ new Map();
|
|
85128
|
+
const setRoute = (visibleCapletId, route, overwrite) => {
|
|
85129
|
+
if (overwrite || !routes.has(visibleCapletId)) routes.set(visibleCapletId, route);
|
|
85130
|
+
};
|
|
85131
|
+
const rewrite = (service, tools, overwrite) => {
|
|
85132
|
+
const rewritten = [];
|
|
85133
|
+
for (const tool of tools) {
|
|
85134
|
+
const baseId = sourceBaseId(tool);
|
|
85135
|
+
if (diagnosticBaseIds.has(baseId)) continue;
|
|
85136
|
+
if (!namespacedBaseIds.has(baseId)) {
|
|
85137
|
+
rewritten.push(tool);
|
|
85138
|
+
setRoute(tool.caplet, {
|
|
85139
|
+
service,
|
|
85140
|
+
capletId: tool.caplet
|
|
85141
|
+
}, overwrite);
|
|
85142
|
+
continue;
|
|
85143
|
+
}
|
|
85144
|
+
const record = namespacedRecords.find((candidate) => candidate.baseId === baseId && candidate.route.service === service);
|
|
85145
|
+
if (!record) continue;
|
|
85146
|
+
const visibleTool = renameNativeTool(tool, record.id);
|
|
85147
|
+
rewritten.push(visibleTool);
|
|
85148
|
+
addMapSetValue(alternativesByBaseId, baseId, visibleTool.caplet);
|
|
85149
|
+
if (tool.caplet !== visibleTool.caplet) addMapSetValue(staleIdsByBaseId, baseId, tool.caplet);
|
|
85150
|
+
setRoute(visibleTool.caplet, {
|
|
85151
|
+
service,
|
|
85152
|
+
capletId: tool.caplet
|
|
85153
|
+
}, overwrite);
|
|
85154
|
+
}
|
|
85155
|
+
return rewritten;
|
|
85156
|
+
};
|
|
85157
|
+
const remoteVisibleTools = rewrite("remote", remoteTools, false);
|
|
85158
|
+
const localVisibleTools = rewrite("local", localTools, true);
|
|
85159
|
+
const remoteVisibleCodeModeTools = rewrite("remote", remoteCodeModeTools, false);
|
|
85160
|
+
const localVisibleCodeModeTools = rewrite("local", localCodeModeTools, true);
|
|
85161
|
+
for (const [baseId, alternatives] of alternativesByBaseId) {
|
|
85162
|
+
const baseDiagnostic = resolution.suppressedBareIds.get(baseId);
|
|
85163
|
+
if (!baseDiagnostic) continue;
|
|
85164
|
+
const alternativeList = [...alternatives];
|
|
85165
|
+
namespaceDiagnostics.set(baseId, namespaceDiagnosticWithAlternatives(baseId, baseDiagnostic, alternativeList));
|
|
85166
|
+
for (const staleId of staleIdsByBaseId.get(baseId) ?? []) namespaceDiagnostics.set(staleId, namespaceDiagnosticWithAlternatives(staleId, baseDiagnostic, alternativeList));
|
|
85167
|
+
}
|
|
85168
|
+
return {
|
|
85169
|
+
remoteTools: remoteVisibleTools,
|
|
85170
|
+
localTools: localVisibleTools,
|
|
85171
|
+
remoteCodeModeTools: remoteVisibleCodeModeTools,
|
|
85172
|
+
localCodeModeTools: localVisibleCodeModeTools,
|
|
85173
|
+
routes,
|
|
85174
|
+
namespaceDiagnostics
|
|
85175
|
+
};
|
|
83496
85176
|
}
|
|
83497
85177
|
warnShadowedLocalCaplets(localTools, remoteIds) {
|
|
83498
85178
|
const localIds = /* @__PURE__ */ new Set([...localTools.filter((tool) => tool.codeModeRun !== true).map((tool) => tool.sourceCaplet ?? tool.caplet), ...codeModeCallableNativeTools(localTools, { fallbackToVisible: false }).map((tool) => tool.caplet)]);
|
|
@@ -83513,47 +85193,256 @@ var CompositeNativeCapletsService = class {
|
|
|
83513
85193
|
}
|
|
83514
85194
|
startPresence() {
|
|
83515
85195
|
this.presence?.start().catch((error) => {
|
|
83516
|
-
writeErr(this.options, `Could not
|
|
85196
|
+
writeErr(this.options, `Could not start upstream Project Binding: ${errorMessage(error)}\n`);
|
|
83517
85197
|
});
|
|
83518
85198
|
}
|
|
83519
85199
|
};
|
|
85200
|
+
function addMapSetValue(map, key, value) {
|
|
85201
|
+
let values = map.get(key);
|
|
85202
|
+
if (!values) {
|
|
85203
|
+
values = /* @__PURE__ */ new Set();
|
|
85204
|
+
map.set(key, values);
|
|
85205
|
+
}
|
|
85206
|
+
values.add(value);
|
|
85207
|
+
}
|
|
85208
|
+
function namespaceDiagnosticWithAlternatives(requestedId, diagnostic, alternatives) {
|
|
85209
|
+
return {
|
|
85210
|
+
...diagnostic,
|
|
85211
|
+
requestedId,
|
|
85212
|
+
alternatives,
|
|
85213
|
+
hint: `Caplet '${requestedId}' is unavailable because namespace shadowing exposes qualified alternatives: ${alternatives.join(", ")}.`
|
|
85214
|
+
};
|
|
85215
|
+
}
|
|
85216
|
+
function nativeNamespaceContext(options) {
|
|
85217
|
+
const configPath = options.configPath ?? resolveConfigPath();
|
|
85218
|
+
const projectConfigPath = options.projectConfigPath ?? resolveProjectConfigPath();
|
|
85219
|
+
let namespaceAliases = parseConfig({}).namespaceAliases;
|
|
85220
|
+
try {
|
|
85221
|
+
namespaceAliases = loadLocalOverlayConfigWithSources(configPath, projectConfigPath).config.namespaceAliases;
|
|
85222
|
+
} catch {}
|
|
85223
|
+
return {
|
|
85224
|
+
localIdentity: `local:${configPath}\0${projectConfigPath}`,
|
|
85225
|
+
namespaceAliases
|
|
85226
|
+
};
|
|
85227
|
+
}
|
|
85228
|
+
function nativeNamespaceEntries(groups, identities) {
|
|
85229
|
+
const entries = /* @__PURE__ */ new Map();
|
|
85230
|
+
for (const group of groups) {
|
|
85231
|
+
const byBaseId = /* @__PURE__ */ new Map();
|
|
85232
|
+
for (const tool of group.tools) {
|
|
85233
|
+
const baseId = sourceBaseId(tool);
|
|
85234
|
+
byBaseId.set(baseId, [...byBaseId.get(baseId) ?? [], tool]);
|
|
85235
|
+
}
|
|
85236
|
+
for (const [baseId, tools] of byBaseId) {
|
|
85237
|
+
const service = group.service;
|
|
85238
|
+
entries.set(`${service}:${baseId}`, {
|
|
85239
|
+
baseId,
|
|
85240
|
+
sourceKind: service === "local" ? "local" : "upstream",
|
|
85241
|
+
sourceLabel: service === "local" ? "local" : "remote",
|
|
85242
|
+
namespaceAlias: service === "local" ? identities.namespaceAliases.local : identities.namespaceAliases.upstreams[identities.remoteIdentity],
|
|
85243
|
+
durableSourceIdentity: service === "local" ? identities.localIdentity : identities.remoteIdentity,
|
|
85244
|
+
shadowing: aggregateShadowing(tools),
|
|
85245
|
+
route: {
|
|
85246
|
+
service,
|
|
85247
|
+
baseId
|
|
85248
|
+
}
|
|
85249
|
+
});
|
|
85250
|
+
}
|
|
85251
|
+
}
|
|
85252
|
+
return [...entries.values()];
|
|
85253
|
+
}
|
|
85254
|
+
function aggregateShadowing(tools) {
|
|
85255
|
+
if (tools.some((tool) => (tool.shadowing ?? "forbid") === "forbid")) return "forbid";
|
|
85256
|
+
if (tools.some((tool) => tool.shadowing === "namespace")) return "namespace";
|
|
85257
|
+
return "allow";
|
|
85258
|
+
}
|
|
85259
|
+
function sourceBaseId(tool) {
|
|
85260
|
+
return tool.sourceCaplet ?? tool.caplet;
|
|
85261
|
+
}
|
|
85262
|
+
function renameNativeTool(tool, visibleBaseId) {
|
|
85263
|
+
const baseId = sourceBaseId(tool);
|
|
85264
|
+
const visibleCapletId = tool.sourceCaplet && tool.caplet.startsWith(`${baseId}__`) ? `${visibleBaseId}${tool.caplet.slice(baseId.length)}` : visibleBaseId;
|
|
85265
|
+
const operationName = tool.sourceCaplet && tool.caplet.startsWith(`${baseId}__`) ? tool.caplet.slice(baseId.length + 2) : void 0;
|
|
85266
|
+
const toolName = operationName ? nativeDirectToolName(visibleBaseId, operationName) : nativeCapletToolName(visibleCapletId);
|
|
85267
|
+
return {
|
|
85268
|
+
...tool,
|
|
85269
|
+
caplet: visibleCapletId,
|
|
85270
|
+
...tool.sourceCaplet ? { sourceCaplet: visibleBaseId } : {},
|
|
85271
|
+
toolName
|
|
85272
|
+
};
|
|
85273
|
+
}
|
|
83520
85274
|
function remoteCodeModeCallableNativeTools(tools) {
|
|
83521
85275
|
return codeModeCallableNativeTools(tools, { fallbackToVisible: true });
|
|
83522
85276
|
}
|
|
83523
85277
|
function remoteSuppressedCapletIds(allRemoteTools, remoteCodeModeTools = remoteCodeModeCallableNativeTools(allRemoteTools)) {
|
|
83524
|
-
return new Set([...allRemoteTools.filter((tool) => tool.codeModeRun !== true && tool.shadowing
|
|
85278
|
+
return new Set([...allRemoteTools.filter((tool) => tool.codeModeRun !== true && (tool.shadowing ?? "forbid") === "forbid").map((tool) => tool.sourceCaplet ?? tool.caplet), ...remoteCodeModeTools.filter((tool) => (tool.shadowing ?? "forbid") === "forbid").map((tool) => tool.caplet)].filter((caplet) => caplet !== nativeCodeModeToolId));
|
|
85279
|
+
}
|
|
85280
|
+
function createProjectBindingSessionManager(cloud, remoteOptions, local, options) {
|
|
85281
|
+
const allowedCapletIds = local.listTools().map((tool) => tool.caplet);
|
|
85282
|
+
if (cloud) {
|
|
85283
|
+
const projectRoot = cloud.projectRoot ?? findProjectRoot();
|
|
85284
|
+
const cloudFetch = options.remote?.fetch;
|
|
85285
|
+
return new ProjectBindingSessionManager({
|
|
85286
|
+
client: new CapletsCloudClient({
|
|
85287
|
+
baseUrl: cloud.url,
|
|
85288
|
+
accessToken: cloud.accessToken,
|
|
85289
|
+
...cloudFetch ? { fetch: cloudFetch } : {}
|
|
85290
|
+
}),
|
|
85291
|
+
workspaceId: cloud.workspaceId,
|
|
85292
|
+
projectRoot,
|
|
85293
|
+
projectFingerprint: fingerprintProjectRoot(projectRoot),
|
|
85294
|
+
projectFiles: projectSyncFiles(projectRoot),
|
|
85295
|
+
allowedCapletIds,
|
|
85296
|
+
heartbeatIntervalMs: cloud.heartbeatIntervalMs,
|
|
85297
|
+
onError: (error) => {
|
|
85298
|
+
writeErr(options, `Caplets Cloud Project Binding heartbeat failed: ${errorMessage(error)}\n`);
|
|
85299
|
+
}
|
|
85300
|
+
});
|
|
85301
|
+
}
|
|
85302
|
+
if (!options.projectRoot || !isLoopbackRemote(remoteOptions)) return;
|
|
85303
|
+
return new RemoteProjectBindingSessionManager({
|
|
85304
|
+
attachUrl: remoteOptions.url,
|
|
85305
|
+
requestInit: remoteOptions.requestInit,
|
|
85306
|
+
fetch: remoteOptions.fetch,
|
|
85307
|
+
projectRoot: options.projectRoot,
|
|
85308
|
+
allowedCapletIds,
|
|
85309
|
+
heartbeatIntervalMs: 3e4,
|
|
85310
|
+
writeErr: options.writeErr
|
|
85311
|
+
});
|
|
83525
85312
|
}
|
|
83526
|
-
|
|
83527
|
-
|
|
83528
|
-
|
|
83529
|
-
|
|
83530
|
-
|
|
83531
|
-
|
|
85313
|
+
var RemoteProjectBindingSessionManager = class {
|
|
85314
|
+
options;
|
|
85315
|
+
bindingId;
|
|
85316
|
+
sessionId;
|
|
85317
|
+
allowedCapletIds;
|
|
85318
|
+
heartbeatTimer;
|
|
85319
|
+
startPromise;
|
|
85320
|
+
unsupported = false;
|
|
85321
|
+
constructor(options) {
|
|
85322
|
+
this.options = options;
|
|
85323
|
+
this.allowedCapletIds = [...options.allowedCapletIds];
|
|
85324
|
+
}
|
|
85325
|
+
async start() {
|
|
85326
|
+
if (this.unsupported) return;
|
|
85327
|
+
if (!this.startPromise) {
|
|
85328
|
+
const start = this.register();
|
|
85329
|
+
this.startPromise = start;
|
|
85330
|
+
start.catch((error) => {
|
|
85331
|
+
if (isUnsupportedProjectBinding(error)) this.unsupported = true;
|
|
85332
|
+
if (this.startPromise === start) this.startPromise = void 0;
|
|
85333
|
+
});
|
|
83532
85334
|
}
|
|
83533
|
-
|
|
85335
|
+
return await this.startPromise;
|
|
83534
85336
|
}
|
|
83535
|
-
|
|
83536
|
-
|
|
83537
|
-
|
|
83538
|
-
|
|
83539
|
-
|
|
83540
|
-
|
|
83541
|
-
|
|
83542
|
-
|
|
83543
|
-
|
|
83544
|
-
|
|
83545
|
-
|
|
83546
|
-
|
|
83547
|
-
|
|
83548
|
-
|
|
83549
|
-
|
|
83550
|
-
|
|
83551
|
-
|
|
83552
|
-
|
|
83553
|
-
|
|
83554
|
-
|
|
85337
|
+
async close() {
|
|
85338
|
+
await this.startPromise?.catch(() => void 0);
|
|
85339
|
+
this.stopHeartbeat();
|
|
85340
|
+
const bindingId = this.bindingId;
|
|
85341
|
+
this.bindingId = void 0;
|
|
85342
|
+
const sessionId = this.sessionId;
|
|
85343
|
+
this.sessionId = void 0;
|
|
85344
|
+
if (!bindingId || !sessionId) return;
|
|
85345
|
+
await this.fetchJson(projectBindingUrl(this.options.attachUrl, bindingId, "session"), {
|
|
85346
|
+
method: "DELETE",
|
|
85347
|
+
body: {
|
|
85348
|
+
sessionId,
|
|
85349
|
+
terminalReason: {
|
|
85350
|
+
code: "completed",
|
|
85351
|
+
message: "Binding Session completed."
|
|
85352
|
+
}
|
|
85353
|
+
}
|
|
85354
|
+
}).catch(() => void 0);
|
|
85355
|
+
}
|
|
85356
|
+
async updateAllowedCapletIds(allowedCapletIds) {
|
|
85357
|
+
this.allowedCapletIds = [...allowedCapletIds];
|
|
85358
|
+
await this.startPromise?.catch(() => void 0);
|
|
85359
|
+
if (!this.bindingId || !this.sessionId) return;
|
|
85360
|
+
await this.heartbeat().catch(() => void 0);
|
|
85361
|
+
}
|
|
85362
|
+
async register() {
|
|
85363
|
+
const projectFingerprint = fingerprintProjectRoot(this.options.projectRoot);
|
|
85364
|
+
const response = await this.fetchJson(projectBindingUrl(this.options.attachUrl, "sessions"), {
|
|
85365
|
+
method: "POST",
|
|
85366
|
+
body: {
|
|
85367
|
+
projectRoot: this.options.projectRoot,
|
|
85368
|
+
projectFingerprint,
|
|
85369
|
+
allowedCapletIds: this.allowedCapletIds
|
|
85370
|
+
}
|
|
85371
|
+
});
|
|
85372
|
+
if (!response.binding?.bindingId || !response.sessionId) throw new CapletsError("SERVER_UNAVAILABLE", "Project Binding session response was invalid.");
|
|
85373
|
+
this.bindingId = response.binding.bindingId;
|
|
85374
|
+
this.sessionId = response.sessionId;
|
|
85375
|
+
this.startHeartbeat();
|
|
85376
|
+
}
|
|
85377
|
+
startHeartbeat() {
|
|
85378
|
+
this.stopHeartbeat();
|
|
85379
|
+
this.heartbeatTimer = setInterval(() => {
|
|
85380
|
+
this.heartbeat().catch((error) => {
|
|
85381
|
+
this.disconnect();
|
|
85382
|
+
this.options.writeErr?.(`Remote Project Binding heartbeat failed: ${errorMessage(error)}\n`);
|
|
85383
|
+
});
|
|
85384
|
+
}, this.options.heartbeatIntervalMs);
|
|
85385
|
+
this.heartbeatTimer.unref?.();
|
|
85386
|
+
}
|
|
85387
|
+
stopHeartbeat() {
|
|
85388
|
+
if (!this.heartbeatTimer) return;
|
|
85389
|
+
clearInterval(this.heartbeatTimer);
|
|
85390
|
+
this.heartbeatTimer = void 0;
|
|
85391
|
+
}
|
|
85392
|
+
disconnect() {
|
|
85393
|
+
this.stopHeartbeat();
|
|
85394
|
+
this.bindingId = void 0;
|
|
85395
|
+
this.sessionId = void 0;
|
|
85396
|
+
this.startPromise = void 0;
|
|
85397
|
+
}
|
|
85398
|
+
async heartbeat() {
|
|
85399
|
+
if (!this.bindingId || !this.sessionId) return;
|
|
85400
|
+
await this.fetchJson(projectBindingUrl(this.options.attachUrl, this.bindingId, "heartbeat"), {
|
|
85401
|
+
method: "POST",
|
|
85402
|
+
body: {
|
|
85403
|
+
sessionId: this.sessionId,
|
|
85404
|
+
state: "ready",
|
|
85405
|
+
syncState: "idle",
|
|
85406
|
+
allowedCapletIds: this.allowedCapletIds
|
|
85407
|
+
}
|
|
85408
|
+
});
|
|
85409
|
+
}
|
|
85410
|
+
async fetchJson(url, input) {
|
|
85411
|
+
const headers = new Headers(this.options.requestInit.headers);
|
|
85412
|
+
headers.set("content-type", "application/json");
|
|
85413
|
+
const response = await (this.options.fetch ?? fetch)(url, {
|
|
85414
|
+
...this.options.requestInit,
|
|
85415
|
+
method: input.method,
|
|
85416
|
+
headers,
|
|
85417
|
+
body: JSON.stringify(input.body)
|
|
85418
|
+
});
|
|
85419
|
+
if (!response.ok) {
|
|
85420
|
+
let payload;
|
|
85421
|
+
try {
|
|
85422
|
+
payload = await response.json();
|
|
85423
|
+
} catch {
|
|
85424
|
+
payload = void 0;
|
|
85425
|
+
}
|
|
85426
|
+
const error = isRecord(payload) && isRecord(payload.error) ? payload.error : void 0;
|
|
85427
|
+
if (error?.code === "UNSUPPORTED_CAPABILITY" && typeof error.message === "string") throw new CapletsError("UNSUPPORTED_CAPABILITY", error.message);
|
|
85428
|
+
throw new CapletsError("SERVER_UNAVAILABLE", `Project Binding request failed (${response.status}).`);
|
|
83555
85429
|
}
|
|
83556
|
-
|
|
85430
|
+
return await response.json().catch(() => ({}));
|
|
85431
|
+
}
|
|
85432
|
+
};
|
|
85433
|
+
function isUnsupportedProjectBinding(error) {
|
|
85434
|
+
return isRecord(error) && error.code === "UNSUPPORTED_CAPABILITY";
|
|
85435
|
+
}
|
|
85436
|
+
function projectBindingUrl(attachUrl, ...segments) {
|
|
85437
|
+
const url = new URL(attachUrl);
|
|
85438
|
+
url.pathname = [
|
|
85439
|
+
url.pathname.replace(/\/+$/u, ""),
|
|
85440
|
+
"project-bindings",
|
|
85441
|
+
...segments.map(encodeURIComponent)
|
|
85442
|
+
].join("/");
|
|
85443
|
+
url.search = "";
|
|
85444
|
+
url.hash = "";
|
|
85445
|
+
return url;
|
|
83557
85446
|
}
|
|
83558
85447
|
function createLocalOverlayConfigLoader(options) {
|
|
83559
85448
|
let hasLoaded = false;
|
|
@@ -83591,4 +85480,4 @@ function errorMessage(error) {
|
|
|
83591
85480
|
return error instanceof Error ? error.message : String(error);
|
|
83592
85481
|
}
|
|
83593
85482
|
//#endregion
|
|
83594
|
-
export {
|
|
85483
|
+
export { redactCodeModeLogText as $, getParseErrorMessage as $n, readTokenBundle as $t, resolveRemoteMode as A, GetPromptRequestSchema as An, loadProjectConfig as At, nativeCodeModeToolId as B, LoggingLevelSchema as Bn, discoverCapletFiles as Bt, CapletsCloudClient as C, CreateMessageResultSchema as Cn, ServerRegistry as Ct, normalizeRemoteProfileHostUrl as D, ElicitResultSchema as Dn, loadConfigWithSources as Dt, isCapletsCloudUrl as E, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as En, loadConfig as Et, resolveCapletsServer as F, ListPromptsRequestSchema as Fn, FileVaultStore as Ft, runCodeMode as G, assertCompleteRequestPrompt as Gn, markdownStructuredContent as Gt, codeModeRunInputSchema as H, ReadResourceRequestSchema as Hn, loadCapletFilesFromMap as Ht, nativeCapletPromptGuidance as I, ListResourceTemplatesRequestSchema as In, VAULT_MAX_VALUE_BYTES as It, diagnoseCodeModeTypeScript as J, isJSONRPCErrorResponse as Jn, runOAuthFlow as Jt, CodeModeSessionManager as K, assertCompleteRequestResourceTemplate as Kn, refreshOAuthTokenBundle as Kt, nativeCapletToolDescription as L, ListResourcesRequestSchema as Ln, validateVaultKeyName as Lt, controlUrlForBase as M, InitializedNotificationSchema as Mn, vaultBootstrapResolver as Mt, isLoopbackHost as N, JSONRPCMessageSchema as Nn, vaultResolverForAuthDir as Nt, resolveCapletsRemote as O, EmptyResultSchema as On, loadGlobalConfig as Ot, parseServerBaseUrl as P, LATEST_PROTOCOL_VERSION as Pn, vaultStoreForAuthDir as Pt, CodeModeLogStore as Q, getObjectShape as Qn, isTokenBundleExpired as Qt, nativeCapletToolName as R, ListRootsResultSchema as Rn, decryptVaultValue as Rt, buildProjectSyncManifest as S, CompleteRequestSchema as Sn, handleServerTool as St, hostedCloudWorkspaceFromRemoteUrl as T, CreateTaskResultSchema as Tn, GoogleDiscoveryManager as Tt, codeModeRunParamsSchema as U, SUPPORTED_PROTOCOL_VERSIONS as Un, hasRenderableStructuredContent as Ut, nativeCodeModeToolName as V, McpError as Vn, validateCapletFile as Vt, emptyCodeModeRunMeta as W, SetLevelRequestSchema as Wn, markdownCallToolResultContent as Wt, listCodeModeCallableCaplets as X, isJSONRPCResultResponse as Xn, startOAuthFlow as Xt, createCodeModeCapletsApi as Y, isJSONRPCRequest as Yn, startGenericOAuthFlow as Yt, CodeModeJournalStore as Z, getLiteralValue as Zn, deleteTokenBundle as Zt, attachErrorResponse as _, Protocol as _n, rotateTelemetryIdentity as _t, CloudAuthStore as a, defaultConfigPath as an, safeParse as ar, version as at, invokeAttachExport$1 as b, CallToolRequestSchema as bn, findProjectRoot as bt, redactedCloudAuthStatus as c, resolveCapletsRoot as cn, buildProductTelemetryEvent as ct, projectBindingError as d, resolveProjectConfigPath as dn, maybePrintTelemetryNotice as dt, DEFAULT_AUTH_DIR as en, getSchemaDescription as er, codeModeDeclarationHash as et, projectBindingRecovery as f, ReadBuffer as fn, resolveTelemetryState as ft, CAPLETS_ATTACH_SESSION_HEADER as g, AjvJsonSchemaValidator as gn, readTelemetryNotice as gt, createSdkRemoteCapletsClient as h, assertToolsCallTaskCapability as hn, readTelemetryIdentity as ht, createRemoteProfileStore as i, defaultConfigBaseDir as in, objectFromShape as ir, CapletsEngine as it, appendBasePath as j, InitializeRequestSchema as jn, parseConfig as jt, resolveHostedCloudRemote as k, ErrorCode as kn, loadLocalOverlayConfigWithSources as kt, PROJECT_BINDING_ERROR_CODES as l, resolveConfigPath as ln, buildReliabilityTelemetryEvent as lt, RemoteNativeCapletsService as m, assertClientRequestTaskCapability as mn, readTelemetryDeliveryHealth as mt, resolveRemoteSelection as n, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as nn, isZ4Schema as nr, generateCodeModeRunToolDescription as nt, cloudAuthPath as o, defaultStateBaseDir as on, safeParseAsync as or, createTelemetryDispatcher as ot, CloudAuthClient as p, serializeMessage as pn, deleteTelemetryIdentity as pt, QuickJsCodeModeSandbox as q, isInitializeRequest as qn, runGenericOAuthFlow as qt, cloudCredentialsFromRemoteProfile as r, defaultCacheBaseDir as rn, normalizeObjectSchema as rr, minifyCodeModeDeclarationText as rt, migrateCredentials as s, defaultTelemetryStateDir as sn, TelemetryDebugSink as st, createNativeCapletsService as t, DEFAULT_COMPLETION_CACHE_DIR as tn, isSchemaOptional as tr, generateCodeModeDeclarations as tt, ProjectBindingError as u, resolveProjectCapletsRoot as un, durationBucket as ut, buildAttachProjection as v, mergeCapabilities as vn, resolveExposure as vt, resolveNativeCapletsServiceOptions as w, CreateMessageResultWithToolsSchema as wn, capabilityDescription as wt, invokeNativeAttachExport as x, CallToolResultSchema as xn, fingerprintProjectRoot as xt, buildNativeAttachProjection as y, toJsonSchemaCompat as yn, decodeDirectResourceUri as yt, nativeCapletsSystemGuidance as z, ListToolsRequestSchema as zn, encryptVaultValue as zt };
|