@caplets/core 0.26.1 → 0.27.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 +2 -1
- package/dist/caplet-files-bundle.d.ts +1 -0
- package/dist/caplet-source.js +39 -3
- package/dist/cli/inspection.d.ts +2 -1
- package/dist/code-mode/types.d.ts +1 -1
- package/dist/{completion-CFOJucl5.js → completion-1wDjwHkC.js} +4 -3
- 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 +10 -1
- package/dist/errors.d.ts +1 -1
- package/dist/exposure/namespace.d.ts +39 -0
- package/dist/index.js +14 -5
- package/dist/native/remote.d.ts +2 -1
- package/dist/native/service.d.ts +2 -2
- package/dist/native.js +1 -1
- package/dist/{service-aBIn4nrw.js → service-BGGiZLHa.js} +359 -37
- package/dist/{validation-GD2x5HW1.js → validation-CWzd2gtn.js} +3 -1
- package/package.json +1 -1
package/dist/attach/api.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CapletsEngine } from "../engine";
|
|
2
|
+
import type { CapletShadowingPolicy } from "../config";
|
|
2
3
|
export type AttachExportKind = "caplet" | "tool" | "resource" | "resourceTemplate" | "prompt" | "completion";
|
|
3
4
|
export type AttachInvokeRequest = {
|
|
4
5
|
revision: string;
|
|
@@ -26,7 +27,7 @@ export type AttachManifestExport = {
|
|
|
26
27
|
annotations?: unknown;
|
|
27
28
|
schemaHash: string | null;
|
|
28
29
|
capletId: string;
|
|
29
|
-
shadowing:
|
|
30
|
+
shadowing: CapletShadowingPolicy;
|
|
30
31
|
};
|
|
31
32
|
export type AttachProgressiveCapletExport = AttachManifestExport & {
|
|
32
33
|
kind: "caplet";
|
package/dist/caplet-source.js
CHANGED
|
@@ -10031,6 +10031,7 @@ function superRefine(fn, params) {
|
|
|
10031
10031
|
//#endregion
|
|
10032
10032
|
//#region src/config/validation.ts
|
|
10033
10033
|
const SERVER_ID_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
10034
|
+
const NAMESPACE_ALIAS_LABEL_PATTERN = /^[a-z](?:[a-z0-9-]{0,30}[a-z0-9])?$/;
|
|
10034
10035
|
const HEADER_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
10035
10036
|
const HTTP_BASE_URL_PATTERN = /^(?![a-zA-Z][a-zA-Z0-9+.-]*:\/\/[^/?#]*@)[^?#]*$/;
|
|
10036
10037
|
const FORBIDDEN_HEADERS = /* @__PURE__ */ new Set([
|
|
@@ -10169,7 +10170,11 @@ const capletExposureSchema = _enum([
|
|
|
10169
10170
|
"direct_and_code_mode",
|
|
10170
10171
|
"progressive_and_code_mode"
|
|
10171
10172
|
]).describe("How this Caplet is exposed to agents.");
|
|
10172
|
-
const capletShadowingSchema = _enum([
|
|
10173
|
+
const capletShadowingSchema = _enum([
|
|
10174
|
+
"forbid",
|
|
10175
|
+
"allow",
|
|
10176
|
+
"namespace"
|
|
10177
|
+
]).describe("Whether attached local Caplets may shadow this remote Caplet ID.");
|
|
10173
10178
|
const capletEndpointAuthSchema = discriminatedUnion("type", [
|
|
10174
10179
|
object({ type: literal("none") }).strict(),
|
|
10175
10180
|
object({
|
|
@@ -10849,7 +10854,11 @@ const exposureSchema = _enum([
|
|
|
10849
10854
|
"direct_and_code_mode",
|
|
10850
10855
|
"progressive_and_code_mode"
|
|
10851
10856
|
]);
|
|
10852
|
-
const shadowingSchema = _enum([
|
|
10857
|
+
const shadowingSchema = _enum([
|
|
10858
|
+
"forbid",
|
|
10859
|
+
"allow",
|
|
10860
|
+
"namespace"
|
|
10861
|
+
]).default("forbid");
|
|
10853
10862
|
const commonSchema = {
|
|
10854
10863
|
name: string().trim().min(1).max(80),
|
|
10855
10864
|
description: string().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"),
|
|
@@ -10988,6 +10997,28 @@ const capletSetSchema = object({
|
|
|
10988
10997
|
maxSearchLimit: number().int().positive().max(50).default(50),
|
|
10989
10998
|
toolCacheTtlMs: number().int().nonnegative().default(3e4)
|
|
10990
10999
|
}).strict();
|
|
11000
|
+
const namespaceAliasLabelSchema = string().regex(NAMESPACE_ALIAS_LABEL_PATTERN, "namespace alias labels must be lowercase DNS-style labels using letters, numbers, or hyphens");
|
|
11001
|
+
const namespaceAliasesSchema = object({
|
|
11002
|
+
local: namespaceAliasLabelSchema.optional(),
|
|
11003
|
+
upstreams: record(string().trim().min(1), namespaceAliasLabelSchema).default({})
|
|
11004
|
+
}).strict().default({ upstreams: {} }).superRefine((aliases, ctx) => {
|
|
11005
|
+
const seen = /* @__PURE__ */ new Map();
|
|
11006
|
+
const addAlias = (value, path) => {
|
|
11007
|
+
if (!value) return;
|
|
11008
|
+
const existing = seen.get(value);
|
|
11009
|
+
if (existing) {
|
|
11010
|
+
ctx.addIssue({
|
|
11011
|
+
code: "custom",
|
|
11012
|
+
path,
|
|
11013
|
+
message: `namespace alias '${value}' is already used at ${existing.join(".")}`
|
|
11014
|
+
});
|
|
11015
|
+
return;
|
|
11016
|
+
}
|
|
11017
|
+
seen.set(value, path);
|
|
11018
|
+
};
|
|
11019
|
+
addAlias(aliases.local, ["local"]);
|
|
11020
|
+
for (const [selector, alias] of Object.entries(aliases.upstreams)) addAlias(alias, ["upstreams", selector]);
|
|
11021
|
+
});
|
|
10991
11022
|
const configSchema = object({
|
|
10992
11023
|
version: literal(1).default(1),
|
|
10993
11024
|
defaultSearchLimit: number().int().positive().default(20),
|
|
@@ -11018,7 +11049,8 @@ const configSchema = object({
|
|
|
11018
11049
|
graphqlEndpoints: record(string().regex(SERVER_ID_PATTERN), graphQlEndpointSchema).default({}),
|
|
11019
11050
|
httpApis: record(string().regex(SERVER_ID_PATTERN), httpApiSchema).default({}),
|
|
11020
11051
|
cliTools: record(string().regex(SERVER_ID_PATTERN), cliToolsSchema).default({}),
|
|
11021
|
-
capletSets: record(string().regex(SERVER_ID_PATTERN), capletSetSchema).default({})
|
|
11052
|
+
capletSets: record(string().regex(SERVER_ID_PATTERN), capletSetSchema).default({}),
|
|
11053
|
+
namespaceAliases: namespaceAliasesSchema
|
|
11022
11054
|
}).strict().superRefine((config, ctx) => {
|
|
11023
11055
|
if (config.defaultSearchLimit > config.maxSearchLimit) ctx.addIssue({
|
|
11024
11056
|
code: "custom",
|
|
@@ -11041,6 +11073,10 @@ function parseConfig(input) {
|
|
|
11041
11073
|
exposureDiscoveryConcurrency: config.options.exposureDiscoveryConcurrency,
|
|
11042
11074
|
completion: config.completion
|
|
11043
11075
|
},
|
|
11076
|
+
namespaceAliases: stripUndefined({
|
|
11077
|
+
local: config.namespaceAliases.local,
|
|
11078
|
+
upstreams: config.namespaceAliases.upstreams
|
|
11079
|
+
}),
|
|
11044
11080
|
mcpServers: mapBackend(config.mcpServers, "mcp", (id, raw) => {
|
|
11045
11081
|
const server = raw;
|
|
11046
11082
|
return {
|
package/dist/cli/inspection.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CapletConfig, type ConfigSource, type ConfigWithSources } from "../config";
|
|
1
|
+
import { type CapletConfig, type CapletShadowingPolicy, type ConfigSource, type ConfigWithSources } from "../config";
|
|
2
2
|
import type { ServerStatus } from "../registry";
|
|
3
3
|
type CapletListRow = {
|
|
4
4
|
server: string;
|
|
@@ -10,6 +10,7 @@ type CapletListRow = {
|
|
|
10
10
|
source: ConfigSource["kind"] | "remote" | "unknown";
|
|
11
11
|
path: string | null;
|
|
12
12
|
shadows: ConfigSource[];
|
|
13
|
+
shadowing?: CapletShadowingPolicy | undefined;
|
|
13
14
|
};
|
|
14
15
|
type ConfigPaths = {
|
|
15
16
|
userConfig: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Hn as __exportAll, It as DEFAULT_AUTH_DIR, Kt as resolveProjectConfigPath, Lt as DEFAULT_COMPLETION_CACHE_DIR, Ut as resolveCapletsRoot, Wt as resolveConfigPath, lt as loadConfigWithSources } from "./service-
|
|
2
|
-
import {
|
|
1
|
+
import { Hn as __exportAll, It as DEFAULT_AUTH_DIR, Kt as resolveProjectConfigPath, Lt as DEFAULT_COMPLETION_CACHE_DIR, Ut as resolveCapletsRoot, Wt as resolveConfigPath, lt as loadConfigWithSources } from "./service-BGGiZLHa.js";
|
|
2
|
+
import { d as CapletsError } from "./validation-CWzd2gtn.js";
|
|
3
3
|
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
@@ -165,7 +165,8 @@ function listCaplets(configWithSources, options) {
|
|
|
165
165
|
status: initialServerStatus(server),
|
|
166
166
|
source: sources[server.server]?.kind ?? "unknown",
|
|
167
167
|
path: sources[server.server]?.path ?? null,
|
|
168
|
-
shadows: shadows[server.server] ?? []
|
|
168
|
+
shadows: shadows[server.server] ?? [],
|
|
169
|
+
shadowing: server.shadowing
|
|
169
170
|
})).sort((left, right) => left.server.localeCompare(right.server));
|
|
170
171
|
}
|
|
171
172
|
function initialServerStatus(server) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const SERVER_ID_PATTERN: RegExp;
|
|
2
|
+
export declare const NAMESPACE_ALIAS_LABEL_PATTERN: RegExp;
|
|
2
3
|
export declare const HEADER_NAME_PATTERN: RegExp;
|
|
3
4
|
export declare const HTTP_BASE_URL_PATTERN: RegExp;
|
|
4
5
|
export declare const FORBIDDEN_HEADERS: Set<string>;
|
|
@@ -10,6 +11,7 @@ type ValidationIssueSink = {
|
|
|
10
11
|
}): void;
|
|
11
12
|
};
|
|
12
13
|
export declare function validateHttpActionHeaders(headers: Record<string, unknown>, ctx: ValidationIssueSink, path: Array<string>): void;
|
|
14
|
+
export declare function isValidNamespaceAliasLabel(value: string): boolean;
|
|
13
15
|
export declare function isAllowedRemoteUrl(value: string): boolean;
|
|
14
16
|
export declare function isAllowedHttpBaseUrl(value: string): boolean;
|
|
15
17
|
export declare function isUrl(value: string): boolean;
|
package/dist/config-runtime.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export type AgentSelectionHintsConfig = {
|
|
|
49
49
|
avoidWhen?: string | undefined;
|
|
50
50
|
};
|
|
51
51
|
export type CapletExposure = "direct" | "progressive" | "code_mode" | "direct_and_code_mode" | "progressive_and_code_mode";
|
|
52
|
-
export type CapletShadowingPolicy = "forbid" | "allow";
|
|
52
|
+
export type CapletShadowingPolicy = "forbid" | "allow" | "namespace";
|
|
53
53
|
export type CapletServerConfig = CommonCapletConfig & {
|
|
54
54
|
backend: "mcp";
|
|
55
55
|
transport: "stdio" | "http" | "sse";
|
|
@@ -157,6 +157,10 @@ export type CapletSetConfig = CommonCapletConfig & {
|
|
|
157
157
|
toolCacheTtlMs: number;
|
|
158
158
|
};
|
|
159
159
|
export type CapletConfig = CapletServerConfig | OpenApiEndpointConfig | GoogleDiscoveryApiConfig | GraphQlEndpointConfig | HttpApiConfig | CliToolsConfig | CapletSetConfig;
|
|
160
|
+
export type NamespaceAliasesConfig = {
|
|
161
|
+
local?: string | undefined;
|
|
162
|
+
upstreams: Record<string, string>;
|
|
163
|
+
};
|
|
160
164
|
export type CapletsConfig = {
|
|
161
165
|
version: 1;
|
|
162
166
|
options: {
|
|
@@ -172,6 +176,7 @@ export type CapletsConfig = {
|
|
|
172
176
|
negativeCacheTtlMs: number;
|
|
173
177
|
};
|
|
174
178
|
};
|
|
179
|
+
namespaceAliases: NamespaceAliasesConfig;
|
|
175
180
|
mcpServers: Record<string, CapletServerConfig>;
|
|
176
181
|
openapiEndpoints: Record<string, OpenApiEndpointConfig>;
|
|
177
182
|
googleDiscoveryApis: Record<string, GoogleDiscoveryApiConfig>;
|
package/dist/config-runtime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as record, b as unknown, d as literal, l as discriminatedUnion, m as object, o as array, p as number, r as _enum, s as boolean, v as string, y as union } from "./schemas-BoqMu4MG.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as SERVER_ID_PATTERN, c as isUrl, d as CapletsError, i as NAMESPACE_ALIAS_LABEL_PATTERN, l as validateHttpActionHeaders, n as HEADER_NAME_PATTERN, o as isAllowedHttpBaseUrl, r as HTTP_BASE_URL_PATTERN, s as isAllowedRemoteUrl, t as FORBIDDEN_HEADERS } from "./validation-CWzd2gtn.js";
|
|
3
3
|
//#region src/config-runtime.ts
|
|
4
4
|
const stringMapSchema = record(string(), string());
|
|
5
5
|
const authSchema = discriminatedUnion("type", [
|
|
@@ -49,7 +49,11 @@ const exposureSchema = _enum([
|
|
|
49
49
|
"direct_and_code_mode",
|
|
50
50
|
"progressive_and_code_mode"
|
|
51
51
|
]);
|
|
52
|
-
const shadowingSchema = _enum([
|
|
52
|
+
const shadowingSchema = _enum([
|
|
53
|
+
"forbid",
|
|
54
|
+
"allow",
|
|
55
|
+
"namespace"
|
|
56
|
+
]).default("forbid");
|
|
53
57
|
const commonSchema = {
|
|
54
58
|
name: string().trim().min(1).max(80),
|
|
55
59
|
description: string().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"),
|
|
@@ -188,6 +192,28 @@ const capletSetSchema = object({
|
|
|
188
192
|
maxSearchLimit: number().int().positive().max(50).default(50),
|
|
189
193
|
toolCacheTtlMs: number().int().nonnegative().default(3e4)
|
|
190
194
|
}).strict();
|
|
195
|
+
const namespaceAliasLabelSchema = string().regex(NAMESPACE_ALIAS_LABEL_PATTERN, "namespace alias labels must be lowercase DNS-style labels using letters, numbers, or hyphens");
|
|
196
|
+
const namespaceAliasesSchema = object({
|
|
197
|
+
local: namespaceAliasLabelSchema.optional(),
|
|
198
|
+
upstreams: record(string().trim().min(1), namespaceAliasLabelSchema).default({})
|
|
199
|
+
}).strict().default({ upstreams: {} }).superRefine((aliases, ctx) => {
|
|
200
|
+
const seen = /* @__PURE__ */ new Map();
|
|
201
|
+
const addAlias = (value, path) => {
|
|
202
|
+
if (!value) return;
|
|
203
|
+
const existing = seen.get(value);
|
|
204
|
+
if (existing) {
|
|
205
|
+
ctx.addIssue({
|
|
206
|
+
code: "custom",
|
|
207
|
+
path,
|
|
208
|
+
message: `namespace alias '${value}' is already used at ${existing.join(".")}`
|
|
209
|
+
});
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
seen.set(value, path);
|
|
213
|
+
};
|
|
214
|
+
addAlias(aliases.local, ["local"]);
|
|
215
|
+
for (const [selector, alias] of Object.entries(aliases.upstreams)) addAlias(alias, ["upstreams", selector]);
|
|
216
|
+
});
|
|
191
217
|
const configSchema = object({
|
|
192
218
|
version: literal(1).default(1),
|
|
193
219
|
defaultSearchLimit: number().int().positive().default(20),
|
|
@@ -218,7 +244,8 @@ const configSchema = object({
|
|
|
218
244
|
graphqlEndpoints: record(string().regex(SERVER_ID_PATTERN), graphQlEndpointSchema).default({}),
|
|
219
245
|
httpApis: record(string().regex(SERVER_ID_PATTERN), httpApiSchema).default({}),
|
|
220
246
|
cliTools: record(string().regex(SERVER_ID_PATTERN), cliToolsSchema).default({}),
|
|
221
|
-
capletSets: record(string().regex(SERVER_ID_PATTERN), capletSetSchema).default({})
|
|
247
|
+
capletSets: record(string().regex(SERVER_ID_PATTERN), capletSetSchema).default({}),
|
|
248
|
+
namespaceAliases: namespaceAliasesSchema
|
|
222
249
|
}).strict().superRefine((config, ctx) => {
|
|
223
250
|
if (config.defaultSearchLimit > config.maxSearchLimit) ctx.addIssue({
|
|
224
251
|
code: "custom",
|
|
@@ -241,6 +268,10 @@ function parseConfig(input) {
|
|
|
241
268
|
exposureDiscoveryConcurrency: config.options.exposureDiscoveryConcurrency,
|
|
242
269
|
completion: config.completion
|
|
243
270
|
},
|
|
271
|
+
namespaceAliases: stripUndefined({
|
|
272
|
+
local: config.namespaceAliases.local,
|
|
273
|
+
upstreams: config.namespaceAliases.upstreams
|
|
274
|
+
}),
|
|
244
275
|
mcpServers: mapBackend(config.mcpServers, "mcp", (id, raw) => {
|
|
245
276
|
const server = raw;
|
|
246
277
|
return {
|
package/dist/config.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export type AgentSelectionHintsConfig = {
|
|
|
64
64
|
useWhen?: string | undefined;
|
|
65
65
|
avoidWhen?: string | undefined;
|
|
66
66
|
};
|
|
67
|
-
export type CapletShadowingPolicy = "forbid" | "allow";
|
|
67
|
+
export type CapletShadowingPolicy = "forbid" | "allow" | "namespace";
|
|
68
68
|
export type CapletExposure = "direct" | "progressive" | "code_mode" | "direct_and_code_mode" | "progressive_and_code_mode";
|
|
69
69
|
export type CapletServerConfig = AgentSelectionHintsConfig & {
|
|
70
70
|
server: string;
|
|
@@ -261,6 +261,10 @@ export type CapletSetConfig = AgentSelectionHintsConfig & {
|
|
|
261
261
|
runtime?: RuntimeRequirementsConfig | undefined;
|
|
262
262
|
};
|
|
263
263
|
export type CapletConfig = CapletServerConfig | OpenApiEndpointConfig | GoogleDiscoveryApiConfig | GraphQlEndpointConfig | HttpApiConfig | CliToolsConfig | CapletSetConfig;
|
|
264
|
+
export type NamespaceAliasesConfig = {
|
|
265
|
+
local?: string | undefined;
|
|
266
|
+
upstreams: Record<string, string>;
|
|
267
|
+
};
|
|
264
268
|
export type CapletsOptions = {
|
|
265
269
|
defaultSearchLimit: number;
|
|
266
270
|
maxSearchLimit: number;
|
|
@@ -278,6 +282,7 @@ export type CompletionConfig = {
|
|
|
278
282
|
export type CapletsConfig = {
|
|
279
283
|
version: 1;
|
|
280
284
|
options: CapletsOptions;
|
|
285
|
+
namespaceAliases: NamespaceAliasesConfig;
|
|
281
286
|
mcpServers: Record<string, CapletServerConfig>;
|
|
282
287
|
openapiEndpoints: Record<string, OpenApiEndpointConfig>;
|
|
283
288
|
googleDiscoveryApis: Record<string, GoogleDiscoveryApiConfig>;
|
|
@@ -350,6 +355,10 @@ export declare const configFileSchema: z.ZodObject<{
|
|
|
350
355
|
exposureDiscoveryTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
351
356
|
exposureDiscoveryConcurrency: z.ZodDefault<z.ZodNumber>;
|
|
352
357
|
}, z.core.$strict>>;
|
|
358
|
+
namespaceAliases: z.ZodDefault<z.ZodObject<{
|
|
359
|
+
local: z.ZodOptional<z.ZodString>;
|
|
360
|
+
upstreams: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
361
|
+
}, z.core.$strict>>;
|
|
353
362
|
mcpServers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
|
|
354
363
|
openapiEndpoints: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
|
|
355
364
|
googleDiscoveryApis: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const CAPLETS_ERROR_CODES: readonly ["CONFIG_NOT_FOUND", "CONFIG_EXISTS", "CONFIG_INVALID", "REQUEST_INVALID", "SERVER_NOT_FOUND", "SERVER_UNAVAILABLE", "SERVER_START_TIMEOUT", "UNKNOWN_OPERATION", "TOOL_NOT_FOUND", "TOOL_CALL_TIMEOUT", "AUTH_REQUIRED", "AUTH_FAILED", "REMOTE_CREDENTIALS_REVOKED", "AUTH_REFRESH_FAILED", "DOWNSTREAM_PROTOCOL_ERROR", "DOWNSTREAM_TOOL_ERROR", "UNSUPPORTED_OPERATION", "UNSUPPORTED_CAPABILITY", "PROMPT_NOT_FOUND", "DOWNSTREAM_RESOURCE_ERROR", "DOWNSTREAM_PROMPT_ERROR", "DOWNSTREAM_COMPLETION_ERROR", "ATTACH_MANIFEST_STALE", "ATTACH_EXPORT_NOT_FOUND", "UNSUPPORTED_TRANSPORT", "INTERNAL_ERROR"];
|
|
1
|
+
export declare const CAPLETS_ERROR_CODES: readonly ["CONFIG_NOT_FOUND", "CONFIG_EXISTS", "CONFIG_INVALID", "REQUEST_INVALID", "SERVER_NOT_FOUND", "SERVER_UNAVAILABLE", "SERVER_START_TIMEOUT", "UNKNOWN_OPERATION", "CAPLET_NAMESPACE_COLLISION", "TOOL_NOT_FOUND", "TOOL_CALL_TIMEOUT", "AUTH_REQUIRED", "AUTH_FAILED", "REMOTE_CREDENTIALS_REVOKED", "AUTH_REFRESH_FAILED", "DOWNSTREAM_PROTOCOL_ERROR", "DOWNSTREAM_TOOL_ERROR", "UNSUPPORTED_OPERATION", "UNSUPPORTED_CAPABILITY", "PROMPT_NOT_FOUND", "DOWNSTREAM_RESOURCE_ERROR", "DOWNSTREAM_PROMPT_ERROR", "DOWNSTREAM_COMPLETION_ERROR", "ATTACH_MANIFEST_STALE", "ATTACH_EXPORT_NOT_FOUND", "UNSUPPORTED_TRANSPORT", "INTERNAL_ERROR"];
|
|
2
2
|
export type CapletsErrorCode = (typeof CAPLETS_ERROR_CODES)[number];
|
|
3
3
|
export type SafeErrorSummary = {
|
|
4
4
|
code: CapletsErrorCode;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CapletShadowingPolicy } from "../config";
|
|
2
|
+
export type NamespaceSourceKind = "local" | "upstream";
|
|
3
|
+
export type NamespaceDiagnosticReason = "namespace_collision" | "missing_durable_source_identity" | "namespace_alias_invalid" | "generated_id_collision" | "unsupported_protocol";
|
|
4
|
+
export type NamespaceSourceEntry<Route = unknown> = {
|
|
5
|
+
baseId: string;
|
|
6
|
+
sourceKind: NamespaceSourceKind;
|
|
7
|
+
sourceLabel?: string | undefined;
|
|
8
|
+
namespaceAlias?: string | undefined;
|
|
9
|
+
durableSourceIdentity?: string | undefined;
|
|
10
|
+
shadowing: CapletShadowingPolicy;
|
|
11
|
+
route: Route;
|
|
12
|
+
};
|
|
13
|
+
export type NamespaceVisibleRecord<Route = unknown> = NamespaceSourceEntry<Route> & {
|
|
14
|
+
id: string;
|
|
15
|
+
label: string;
|
|
16
|
+
namespaced: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type NamespaceDiagnostic = {
|
|
19
|
+
requestedId: string;
|
|
20
|
+
reason: NamespaceDiagnosticReason;
|
|
21
|
+
alternatives: string[];
|
|
22
|
+
sources: Array<{
|
|
23
|
+
sourceKind: NamespaceSourceKind;
|
|
24
|
+
label: string;
|
|
25
|
+
durableSourceIdentity?: string | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
hint: string;
|
|
28
|
+
};
|
|
29
|
+
export type NamespaceResolution<Route = unknown> = {
|
|
30
|
+
visibleRecords: NamespaceVisibleRecord<Route>[];
|
|
31
|
+
routes: Map<string, Route>;
|
|
32
|
+
suppressedBareIds: Map<string, NamespaceDiagnostic>;
|
|
33
|
+
unavailableDiagnostics: NamespaceDiagnostic[];
|
|
34
|
+
};
|
|
35
|
+
export type NamespaceResolutionOptions = {
|
|
36
|
+
hashLength?: number | undefined;
|
|
37
|
+
maxHashLength?: number | undefined;
|
|
38
|
+
};
|
|
39
|
+
export declare function resolveNamespaceExposure<Route>(entries: NamespaceSourceEntry<Route>[], options?: NamespaceResolutionOptions): NamespaceResolution<Route>;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { $ as resolveExposure, $t as mergeCapabilities, A as nativeCapletPromptGuidance, An as isJSONRPCRequest, At as runOAuthFlow, B as CodeModeSessionManager, Bn as safeParse, Bt as defaultConfigBaseDir, C as resolveHostedCloudRemote, Cn as ReadResourceRequestSchema, Ct as validateCapletFile, D as isLoopbackHost, Dn as assertCompleteRequestResourceTemplate, Dt as markdownStructuredContent, E as controlUrlForBase, En as assertCompleteRequestPrompt, Et as markdownCallToolResultContent, Fn as getSchemaDescription, Ft as readTokenBundle, G as CodeModeJournalStore, Gt as resolveProjectCapletsRoot, H as diagnoseCodeModeTypeScript, Ht as defaultStateBaseDir, I as codeModeRunInputSchema, In as isSchemaOptional, It as DEFAULT_AUTH_DIR, J as codeModeDeclarationHash, Jt as serializeMessage, K as CodeModeLogStore, Kt as resolveProjectConfigPath, L as codeModeRunParamsSchema, Ln as isZ4Schema, M as nativeCapletToolName, Mn as getLiteralValue, Mt as startOAuthFlow, Nn as getObjectShape, Nt as deleteTokenBundle, O as parseServerBaseUrl, On as isInitializeRequest, Ot as refreshOAuthTokenBundle, Pn as getParseErrorMessage, Pt as isTokenBundleExpired, Q as CapletsEngine, Qt as Protocol, R as emptyCodeModeRunMeta, Rn as normalizeObjectSchema, Rt as DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR, S as resolveCapletsRemote, Sn as McpError, St as discoverCapletFiles, T as appendBasePath, Tn as SetLevelRequestSchema, Tt as hasRenderableStructuredContent, U as createCodeModeCapletsApi, Ut as resolveCapletsRoot, V as QuickJsCodeModeSandbox, Vn as safeParseAsync, Vt as defaultConfigPath, W as listCodeModeCallableCaplets, Wt as resolveConfigPath, X as generateCodeModeRunToolDescription, Xt as assertToolsCallTaskCapability, Y as generateCodeModeDeclarations, Yt as assertClientRequestTaskCapability, Z as minifyCodeModeDeclarationText, Zt as AjvJsonSchemaValidator, _ as CapletsCloudClient, _n as ListResourceTemplatesRequestSchema, _t as FileVaultStore, a as CloudAuthStore, an as CreateMessageResultWithToolsSchema, at as ServerRegistry, b as isCapletsCloudUrl, bn as ListToolsRequestSchema, bt as decryptVaultValue, c as redactedCloudAuthStatus, cn as ElicitResultSchema, ct as loadConfig, d as projectBindingError, dn as GetPromptRequestSchema, dt as loadLocalOverlayConfigWithSources, en as toJsonSchemaCompat, et as decodeDirectResourceUri, f as projectBindingRecovery, fn as InitializeRequestSchema, ft as loadProjectConfig, g as buildProjectSyncManifest, gn as ListPromptsRequestSchema, gt as vaultStoreForAuthDir, hn as LATEST_PROTOCOL_VERSION, ht as vaultResolverForAuthDir, i as createRemoteProfileStore, in as CreateMessageResultSchema, it as handleServerTool, j as nativeCapletToolDescription, jn as isJSONRPCResultResponse, jt as startGenericOAuthFlow, k as resolveCapletsServer, kn as isJSONRPCErrorResponse, kt as runGenericOAuthFlow, l as PROJECT_BINDING_ERROR_CODES, ln as EmptyResultSchema, lt as loadConfigWithSources, mn as JSONRPCMessageSchema, mt as vaultBootstrapResolver, n as resolveRemoteSelection, nn as CallToolResultSchema, nt as findProjectRoot, o as cloudAuthPath, on as CreateTaskResultSchema, ot as capabilityDescription, p as CloudAuthClient, pn as InitializedNotificationSchema, pt as parseConfig, q as redactCodeModeLogText, qt as ReadBuffer, r as cloudCredentialsFromRemoteProfile, rn as CompleteRequestSchema, rt as fingerprintProjectRoot, s as migrateCredentials, st as GoogleDiscoveryManager, t as createNativeCapletsService, tn as CallToolRequestSchema, tt as directResourceUriMatchesTemplate, u as ProjectBindingError, un as ErrorCode, ut as loadGlobalConfig, vn as ListResourcesRequestSchema, vt as VAULT_MAX_VALUE_BYTES, w as resolveRemoteMode, wn as SUPPORTED_PROTOCOL_VERSIONS, wt as loadCapletFilesFromMap, x as normalizeRemoteProfileHostUrl, xn as LoggingLevelSchema, xt as encryptVaultValue, y as hostedCloudWorkspaceFromRemoteUrl, yn as ListRootsResultSchema, yt as validateVaultKeyName, z as runCodeMode, zn as objectFromShape, zt as defaultCacheBaseDir } from "./service-
|
|
1
|
+
import { $ as resolveExposure, $t as mergeCapabilities, A as nativeCapletPromptGuidance, An as isJSONRPCRequest, At as runOAuthFlow, B as CodeModeSessionManager, Bn as safeParse, Bt as defaultConfigBaseDir, C as resolveHostedCloudRemote, Cn as ReadResourceRequestSchema, Ct as validateCapletFile, D as isLoopbackHost, Dn as assertCompleteRequestResourceTemplate, Dt as markdownStructuredContent, E as controlUrlForBase, En as assertCompleteRequestPrompt, Et as markdownCallToolResultContent, Fn as getSchemaDescription, Ft as readTokenBundle, G as CodeModeJournalStore, Gt as resolveProjectCapletsRoot, H as diagnoseCodeModeTypeScript, Ht as defaultStateBaseDir, I as codeModeRunInputSchema, In as isSchemaOptional, It as DEFAULT_AUTH_DIR, J as codeModeDeclarationHash, Jt as serializeMessage, K as CodeModeLogStore, Kt as resolveProjectConfigPath, L as codeModeRunParamsSchema, Ln as isZ4Schema, M as nativeCapletToolName, Mn as getLiteralValue, Mt as startOAuthFlow, Nn as getObjectShape, Nt as deleteTokenBundle, O as parseServerBaseUrl, On as isInitializeRequest, Ot as refreshOAuthTokenBundle, Pn as getParseErrorMessage, Pt as isTokenBundleExpired, Q as CapletsEngine, Qt as Protocol, R as emptyCodeModeRunMeta, Rn as normalizeObjectSchema, Rt as DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR, S as resolveCapletsRemote, Sn as McpError, St as discoverCapletFiles, T as appendBasePath, Tn as SetLevelRequestSchema, Tt as hasRenderableStructuredContent, U as createCodeModeCapletsApi, Ut as resolveCapletsRoot, V as QuickJsCodeModeSandbox, Vn as safeParseAsync, Vt as defaultConfigPath, W as listCodeModeCallableCaplets, Wt as resolveConfigPath, X as generateCodeModeRunToolDescription, Xt as assertToolsCallTaskCapability, Y as generateCodeModeDeclarations, Yt as assertClientRequestTaskCapability, Z as minifyCodeModeDeclarationText, Zt as AjvJsonSchemaValidator, _ as CapletsCloudClient, _n as ListResourceTemplatesRequestSchema, _t as FileVaultStore, a as CloudAuthStore, an as CreateMessageResultWithToolsSchema, at as ServerRegistry, b as isCapletsCloudUrl, bn as ListToolsRequestSchema, bt as decryptVaultValue, c as redactedCloudAuthStatus, cn as ElicitResultSchema, ct as loadConfig, d as projectBindingError, dn as GetPromptRequestSchema, dt as loadLocalOverlayConfigWithSources, en as toJsonSchemaCompat, et as decodeDirectResourceUri, f as projectBindingRecovery, fn as InitializeRequestSchema, ft as loadProjectConfig, g as buildProjectSyncManifest, gn as ListPromptsRequestSchema, gt as vaultStoreForAuthDir, hn as LATEST_PROTOCOL_VERSION, ht as vaultResolverForAuthDir, i as createRemoteProfileStore, in as CreateMessageResultSchema, it as handleServerTool, j as nativeCapletToolDescription, jn as isJSONRPCResultResponse, jt as startGenericOAuthFlow, k as resolveCapletsServer, kn as isJSONRPCErrorResponse, kt as runGenericOAuthFlow, l as PROJECT_BINDING_ERROR_CODES, ln as EmptyResultSchema, lt as loadConfigWithSources, mn as JSONRPCMessageSchema, mt as vaultBootstrapResolver, n as resolveRemoteSelection, nn as CallToolResultSchema, nt as findProjectRoot, o as cloudAuthPath, on as CreateTaskResultSchema, ot as capabilityDescription, p as CloudAuthClient, pn as InitializedNotificationSchema, pt as parseConfig, q as redactCodeModeLogText, qt as ReadBuffer, r as cloudCredentialsFromRemoteProfile, rn as CompleteRequestSchema, rt as fingerprintProjectRoot, s as migrateCredentials, st as GoogleDiscoveryManager, t as createNativeCapletsService, tn as CallToolRequestSchema, tt as directResourceUriMatchesTemplate, u as ProjectBindingError, un as ErrorCode, ut as loadGlobalConfig, vn as ListResourcesRequestSchema, vt as VAULT_MAX_VALUE_BYTES, w as resolveRemoteMode, wn as SUPPORTED_PROTOCOL_VERSIONS, wt as loadCapletFilesFromMap, x as normalizeRemoteProfileHostUrl, xn as LoggingLevelSchema, xt as encryptVaultValue, y as hostedCloudWorkspaceFromRemoteUrl, yn as ListRootsResultSchema, yt as validateVaultKeyName, z as runCodeMode, zn as objectFromShape, zt as defaultCacheBaseDir } from "./service-BGGiZLHa.js";
|
|
2
2
|
import { _ as record, b as unknown, d as literal, m as object, n as ZodOptional, o as array, p as number, r as _enum, s as boolean, v as string, x as url } from "./schemas-BoqMu4MG.js";
|
|
3
|
-
import {
|
|
3
|
+
import { a as SERVER_ID_PATTERN, d as CapletsError, m as toSafeError, p as redactSecrets$1, u as CAPLETS_ERROR_CODES } from "./validation-CWzd2gtn.js";
|
|
4
4
|
import { generatedToolInputJsonSchemaForCaplet, generatedToolInputSchema, generatedToolInputSchemaForCaplet } from "./generated-tool-input-schema.js";
|
|
5
5
|
import { f as observedOutputShapeKey, g as stableJsonStringify, h as schemaHash, i as observeOutputShape, u as FileObservedOutputShapeStore } from "./observed-output-shapes-DuP7mJQf.js";
|
|
6
|
-
import { a as formatCapletList, c as resolveCliConfigPaths, l as cliCommands$1, n as completionScript, o as formatConfigPaths, s as listCaplets, t as completeCliWords, u as completionShells } from "./completion-
|
|
6
|
+
import { a as formatCapletList, c as resolveCliConfigPaths, l as cliCommands$1, n as completionScript, o as formatConfigPaths, s as listCaplets, t as completeCliWords, u as completionShells } from "./completion-1wDjwHkC.js";
|
|
7
7
|
import { n as normalizeCapletSourcePath, t as FilesystemCapletSource } from "./filesystem-Kkg32TOJ.js";
|
|
8
8
|
import { parseConfig as parseConfig$1 } from "./config-runtime.js";
|
|
9
9
|
import fs, { accessSync, chmodSync, closeSync, constants, copyFileSync, cpSync, existsSync, fstatSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, watch, writeFileSync, writeSync } from "node:fs";
|
|
@@ -1553,7 +1553,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
|
|
|
1553
1553
|
} };
|
|
1554
1554
|
//#endregion
|
|
1555
1555
|
//#region package.json
|
|
1556
|
-
var version = "0.
|
|
1556
|
+
var version = "0.27.0";
|
|
1557
1557
|
//#endregion
|
|
1558
1558
|
//#region src/serve/session.ts
|
|
1559
1559
|
var CapletsMcpSession = class {
|
|
@@ -17487,8 +17487,17 @@ function mergeRemoteAndLocalRows(remoteRows, localOverlay, options) {
|
|
|
17487
17487
|
});
|
|
17488
17488
|
if (!localOverlay) return [...rows.values()].filter((row) => options.includeDisabled || !row.disabled).sort((left, right) => left.server.localeCompare(right.server));
|
|
17489
17489
|
for (const row of listCaplets(localOverlay, { includeDisabled: true })) {
|
|
17490
|
-
|
|
17490
|
+
const remote = rows.get(row.server);
|
|
17491
|
+
if (remote) {
|
|
17491
17492
|
if (row.disabled) continue;
|
|
17493
|
+
if (remote.shadowing === "namespace") {
|
|
17494
|
+
options.writeErr(`Local Caplet '${row.server}' is exposed under a qualified ID because the remote Caplet uses namespace shadowing for that Caplet ID.\n`);
|
|
17495
|
+
continue;
|
|
17496
|
+
}
|
|
17497
|
+
if (remote.shadowing !== "allow") {
|
|
17498
|
+
options.writeErr(`Local Caplet '${row.server}' is suppressed because the remote Caplet forbids shadowing that Caplet ID.\n`);
|
|
17499
|
+
continue;
|
|
17500
|
+
}
|
|
17492
17501
|
options.writeErr(`Warning: ${formatOverlaySource(row.source)} Caplet ${row.server} shadows remote Caplet\n`);
|
|
17493
17502
|
}
|
|
17494
17503
|
rows.set(row.server, row);
|
package/dist/native/remote.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { AttachCodeModeCaplet } from "../attach/api";
|
|
2
|
+
import type { CapletShadowingPolicy } from "../config";
|
|
2
3
|
import type { ResolvedNativeCapletsServiceOptions } from "./options";
|
|
3
4
|
import type { NativeCapletsService, NativeCapletsToolsChangedListener, NativeCapletTool } from "./service";
|
|
4
5
|
export type RemoteCapletsTool = {
|
|
5
6
|
name: string;
|
|
6
7
|
capletId?: string | undefined;
|
|
7
8
|
sourceCapletId?: string | undefined;
|
|
8
|
-
shadowing?:
|
|
9
|
+
shadowing?: CapletShadowingPolicy | undefined;
|
|
9
10
|
title?: string | undefined;
|
|
10
11
|
description?: string | undefined;
|
|
11
12
|
inputSchema?: unknown;
|
package/dist/native/service.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { NativeCapletsServiceResolutionInput } from "./options";
|
|
|
2
2
|
import { resolveNativeCapletsServiceOptions } from "./options";
|
|
3
3
|
import { type RemoteCapletsClient } from "./remote";
|
|
4
4
|
import type { CodeModeCallableCaplet } from "../code-mode/types";
|
|
5
|
-
import { type CapletsConfig } from "../config";
|
|
5
|
+
import { type CapletShadowingPolicy, type CapletsConfig } from "../config";
|
|
6
6
|
import { generatedToolInputJsonSchemaForCaplet } from "../generated-tool-input-schema";
|
|
7
7
|
export type NativeCapletsServiceOptions = NativeCapletsServiceResolutionInput & {
|
|
8
8
|
configPath?: string;
|
|
@@ -18,7 +18,7 @@ export type NativeCapletsServiceOptions = NativeCapletsServiceResolutionInput &
|
|
|
18
18
|
export type NativeCapletTool = {
|
|
19
19
|
caplet: string;
|
|
20
20
|
sourceCaplet?: string;
|
|
21
|
-
shadowing?:
|
|
21
|
+
shadowing?: CapletShadowingPolicy;
|
|
22
22
|
toolName: string;
|
|
23
23
|
title: string;
|
|
24
24
|
description: string;
|
package/dist/native.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as nativeCapletPromptGuidance, F as nativeCodeModeToolName, M as nativeCapletToolName, N as nativeCapletsSystemGuidance, P as nativeCodeModeToolId, h as createSdkRemoteCapletsClient, j as nativeCapletToolDescription, m as RemoteNativeCapletsService, t as createNativeCapletsService, v as resolveNativeCapletsServiceOptions } from "./service-
|
|
1
|
+
import { A as nativeCapletPromptGuidance, F as nativeCodeModeToolName, M as nativeCapletToolName, N as nativeCapletsSystemGuidance, P as nativeCodeModeToolId, h as createSdkRemoteCapletsClient, j as nativeCapletToolDescription, m as RemoteNativeCapletsService, t as createNativeCapletsService, v as resolveNativeCapletsServiceOptions } from "./service-BGGiZLHa.js";
|
|
2
2
|
import { generatedToolInputJsonSchema, generatedToolInputSchema } from "./generated-tool-input-schema.js";
|
|
3
3
|
//#region src/native/process-cleanup.ts
|
|
4
4
|
function registerNativeCapletsProcessCleanup(service, options = {}) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
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
|
|
2
|
+
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
3
|
import { generatedToolInputJsonSchema, generatedToolInputJsonSchemaForCaplet, generatedToolInputSchemaForCaplet, mcpOperations, operations } from "./generated-tool-input-schema.js";
|
|
4
4
|
import { f as observedOutputShapeKey, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-DuP7mJQf.js";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
@@ -26005,7 +26005,11 @@ const capletExposureSchema = _enum([
|
|
|
26005
26005
|
"direct_and_code_mode",
|
|
26006
26006
|
"progressive_and_code_mode"
|
|
26007
26007
|
]).describe("How this Caplet is exposed to agents.");
|
|
26008
|
-
const capletShadowingSchema = _enum([
|
|
26008
|
+
const capletShadowingSchema = _enum([
|
|
26009
|
+
"forbid",
|
|
26010
|
+
"allow",
|
|
26011
|
+
"namespace"
|
|
26012
|
+
]).describe("Whether attached local Caplets may shadow this remote Caplet ID.");
|
|
26009
26013
|
const capletEndpointAuthSchema = discriminatedUnion("type", [
|
|
26010
26014
|
object$1({ type: literal("none") }).strict(),
|
|
26011
26015
|
object$1({
|
|
@@ -27288,7 +27292,33 @@ const exposureSchema = _enum([
|
|
|
27288
27292
|
"direct_and_code_mode",
|
|
27289
27293
|
"progressive_and_code_mode"
|
|
27290
27294
|
]).describe("How this Caplet is exposed to agents.");
|
|
27291
|
-
const shadowingSchema = _enum([
|
|
27295
|
+
const shadowingSchema = _enum([
|
|
27296
|
+
"forbid",
|
|
27297
|
+
"allow",
|
|
27298
|
+
"namespace"
|
|
27299
|
+
]).default("forbid").describe("Whether attached local Caplets may shadow this remote Caplet ID.");
|
|
27300
|
+
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.");
|
|
27301
|
+
const namespaceAliasesSchema = object$1({
|
|
27302
|
+
local: namespaceAliasLabelSchema.optional(),
|
|
27303
|
+
upstreams: record(string().trim().min(1), namespaceAliasLabelSchema).default({}).describe("Namespace aliases keyed by durable upstream source identity.")
|
|
27304
|
+
}).strict().default({ upstreams: {} }).superRefine((aliases, ctx) => {
|
|
27305
|
+
const seen = /* @__PURE__ */ new Map();
|
|
27306
|
+
const addAlias = (value, path) => {
|
|
27307
|
+
if (!value) return;
|
|
27308
|
+
const existing = seen.get(value);
|
|
27309
|
+
if (existing) {
|
|
27310
|
+
ctx.addIssue({
|
|
27311
|
+
code: "custom",
|
|
27312
|
+
path,
|
|
27313
|
+
message: `namespace alias '${value}' is already used at ${existing.join(".")}`
|
|
27314
|
+
});
|
|
27315
|
+
return;
|
|
27316
|
+
}
|
|
27317
|
+
seen.set(value, path);
|
|
27318
|
+
};
|
|
27319
|
+
addAlias(aliases.local, ["local"]);
|
|
27320
|
+
for (const [selector, alias] of Object.entries(aliases.upstreams)) addAlias(alias, ["upstreams", selector]);
|
|
27321
|
+
}).describe("Source-level namespace aliases for hash-qualified Caplet IDs.");
|
|
27292
27322
|
const publicServerSchema = object$1({
|
|
27293
27323
|
name: string().trim().min(1).max(80).describe("Human-readable server display name."),
|
|
27294
27324
|
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"),
|
|
@@ -27545,6 +27575,7 @@ function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, googleDi
|
|
|
27545
27575
|
exposureDiscoveryTimeoutMs: 15e3,
|
|
27546
27576
|
exposureDiscoveryConcurrency: 4
|
|
27547
27577
|
}).describe("Global Caplets runtime options."),
|
|
27578
|
+
namespaceAliases: namespaceAliasesSchema,
|
|
27548
27579
|
mcpServers: record(string().regex(SERVER_ID_PATTERN), serverValueSchema).default({}).describe("Downstream MCP servers keyed by stable server ID."),
|
|
27549
27580
|
openapiEndpoints: record(string().regex(SERVER_ID_PATTERN), openApiEndpointValueSchema).default({}).describe("OpenAPI endpoints keyed by stable Caplet ID."),
|
|
27550
27581
|
googleDiscoveryApis: record(string().regex(SERVER_ID_PATTERN), googleDiscoveryApiValueSchema).default({}).describe("Google Discovery APIs keyed by stable Caplet ID."),
|
|
@@ -28321,6 +28352,7 @@ function mergeConfigInputs(...inputs) {
|
|
|
28321
28352
|
merged = {
|
|
28322
28353
|
...merged,
|
|
28323
28354
|
...input,
|
|
28355
|
+
namespaceAliases: mergeNamespaceAliases(merged?.namespaceAliases, input.namespaceAliases),
|
|
28324
28356
|
mcpServers: {
|
|
28325
28357
|
...merged?.mcpServers,
|
|
28326
28358
|
...input.mcpServers
|
|
@@ -28353,6 +28385,23 @@ function mergeConfigInputs(...inputs) {
|
|
|
28353
28385
|
}
|
|
28354
28386
|
return merged;
|
|
28355
28387
|
}
|
|
28388
|
+
function mergeNamespaceAliases(left, right) {
|
|
28389
|
+
if (right !== void 0 && !isPlainObject$5(right)) return right;
|
|
28390
|
+
if (left !== void 0 && !isPlainObject$5(left)) return left;
|
|
28391
|
+
if (!isPlainObject$5(left) && !isPlainObject$5(right)) return;
|
|
28392
|
+
const leftRecord = isPlainObject$5(left) ? left : void 0;
|
|
28393
|
+
const rightRecord = isPlainObject$5(right) ? right : void 0;
|
|
28394
|
+
const leftUpstreams = isPlainObject$5(leftRecord?.upstreams) ? leftRecord.upstreams : void 0;
|
|
28395
|
+
const rightUpstreams = isPlainObject$5(rightRecord?.upstreams) ? rightRecord.upstreams : void 0;
|
|
28396
|
+
return stripUndefined({
|
|
28397
|
+
...leftRecord,
|
|
28398
|
+
...rightRecord,
|
|
28399
|
+
upstreams: {
|
|
28400
|
+
...leftUpstreams,
|
|
28401
|
+
...rightUpstreams
|
|
28402
|
+
}
|
|
28403
|
+
});
|
|
28404
|
+
}
|
|
28356
28405
|
function mergeConfigInputsWithSources(...inputs) {
|
|
28357
28406
|
let merged = {};
|
|
28358
28407
|
const sources = {};
|
|
@@ -28477,6 +28526,10 @@ function parseConfig(input, options = {}) {
|
|
|
28477
28526
|
exposureDiscoveryConcurrency: parsed.data.options.exposureDiscoveryConcurrency,
|
|
28478
28527
|
completion: parsed.data.completion
|
|
28479
28528
|
},
|
|
28529
|
+
namespaceAliases: stripUndefined({
|
|
28530
|
+
local: parsed.data.namespaceAliases.local,
|
|
28531
|
+
upstreams: parsed.data.namespaceAliases.upstreams
|
|
28532
|
+
}),
|
|
28480
28533
|
mcpServers: servers,
|
|
28481
28534
|
openapiEndpoints,
|
|
28482
28535
|
googleDiscoveryApis,
|
|
@@ -64028,7 +64081,7 @@ var CapletsEngine = class {
|
|
|
64028
64081
|
}
|
|
64029
64082
|
}
|
|
64030
64083
|
async completeCliWords(words) {
|
|
64031
|
-
const { completeCliWords } = await import("./completion-
|
|
64084
|
+
const { completeCliWords } = await import("./completion-1wDjwHkC.js").then((n) => n.r);
|
|
64032
64085
|
return await completeCliWords(words, {
|
|
64033
64086
|
config: this.registry.config,
|
|
64034
64087
|
managers: {
|
|
@@ -81409,7 +81462,7 @@ function primitiveInvokeInput(capletId, operation, input) {
|
|
|
81409
81462
|
function toolsFromManifest(manifest) {
|
|
81410
81463
|
const codeModeCaplets = manifest.codeModeCaplets ?? [];
|
|
81411
81464
|
const codeModeMarker = attachCodeModeMarker(codeModeCaplets);
|
|
81412
|
-
const codeModeShadowing = codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : "allow";
|
|
81465
|
+
const codeModeShadowing = codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : codeModeCaplets.some((entry) => entry.shadowing === "namespace") ? "namespace" : "allow";
|
|
81413
81466
|
return [
|
|
81414
81467
|
...manifest.caplets.map((entry) => ({
|
|
81415
81468
|
name: entry.capletId,
|
|
@@ -81711,6 +81764,119 @@ function isPermanentRemoteCredentialsCode(code) {
|
|
|
81711
81764
|
return code === "remote_credentials_required" || code === "remote_credentials_revoked" || code === "remote_auth_failed";
|
|
81712
81765
|
}
|
|
81713
81766
|
//#endregion
|
|
81767
|
+
//#region src/exposure/namespace.ts
|
|
81768
|
+
function resolveNamespaceExposure(entries, options = {}) {
|
|
81769
|
+
const hashLength = options.hashLength ?? 4;
|
|
81770
|
+
const maxHashLength = options.maxHashLength ?? 8;
|
|
81771
|
+
const groups = groupByBaseId(entries);
|
|
81772
|
+
const visibleRecords = [];
|
|
81773
|
+
const suppressedBareIds = /* @__PURE__ */ new Map();
|
|
81774
|
+
const unavailableDiagnostics = [];
|
|
81775
|
+
const reservedBareIds = new Set(groups.keys());
|
|
81776
|
+
for (const [baseId, group] of groups) {
|
|
81777
|
+
if (group.length === 1) {
|
|
81778
|
+
visibleRecords.push(visibleRecord(group[0], baseId, false));
|
|
81779
|
+
continue;
|
|
81780
|
+
}
|
|
81781
|
+
if (!isNamespaceCollisionGroup(group)) {
|
|
81782
|
+
visibleRecords.push(visibleRecord(nonNamespaceWinner(group), baseId, false));
|
|
81783
|
+
continue;
|
|
81784
|
+
}
|
|
81785
|
+
const diagnostics = validateNamespaceGroup(baseId, group);
|
|
81786
|
+
if (diagnostics.length > 0) {
|
|
81787
|
+
unavailableDiagnostics.push(...diagnostics);
|
|
81788
|
+
continue;
|
|
81789
|
+
}
|
|
81790
|
+
const resolved = qualifyNamespaceGroup(group, {
|
|
81791
|
+
baseId,
|
|
81792
|
+
hashLength,
|
|
81793
|
+
maxHashLength,
|
|
81794
|
+
reservedBareIds
|
|
81795
|
+
});
|
|
81796
|
+
if ("diagnostic" in resolved) {
|
|
81797
|
+
unavailableDiagnostics.push(resolved.diagnostic);
|
|
81798
|
+
continue;
|
|
81799
|
+
}
|
|
81800
|
+
visibleRecords.push(...resolved.records);
|
|
81801
|
+
suppressedBareIds.set(baseId, diagnostic(baseId, "namespace_collision", group, resolved.records.map((record) => record.id)));
|
|
81802
|
+
}
|
|
81803
|
+
return {
|
|
81804
|
+
visibleRecords,
|
|
81805
|
+
routes: new Map(visibleRecords.map((record) => [record.id, record.route])),
|
|
81806
|
+
suppressedBareIds,
|
|
81807
|
+
unavailableDiagnostics
|
|
81808
|
+
};
|
|
81809
|
+
}
|
|
81810
|
+
function groupByBaseId(entries) {
|
|
81811
|
+
const groups = /* @__PURE__ */ new Map();
|
|
81812
|
+
for (const entry of entries) groups.set(entry.baseId, [...groups.get(entry.baseId) ?? [], entry]);
|
|
81813
|
+
return groups;
|
|
81814
|
+
}
|
|
81815
|
+
function isNamespaceCollisionGroup(group) {
|
|
81816
|
+
const upstreams = group.filter((entry) => entry.sourceKind === "upstream");
|
|
81817
|
+
return upstreams.length > 0 && upstreams.every((entry) => entry.shadowing === "namespace");
|
|
81818
|
+
}
|
|
81819
|
+
function nonNamespaceWinner(group) {
|
|
81820
|
+
const forbiddingUpstream = group.find((entry) => entry.sourceKind === "upstream" && entry.shadowing === "forbid");
|
|
81821
|
+
if (forbiddingUpstream) return forbiddingUpstream;
|
|
81822
|
+
const local = group.find((entry) => entry.sourceKind === "local");
|
|
81823
|
+
if (local) return local;
|
|
81824
|
+
return group.find((entry) => entry.sourceKind === "upstream") ?? group[0];
|
|
81825
|
+
}
|
|
81826
|
+
function validateNamespaceGroup(baseId, group) {
|
|
81827
|
+
const diagnostics = [];
|
|
81828
|
+
for (const entry of group) {
|
|
81829
|
+
if (!entry.durableSourceIdentity) {
|
|
81830
|
+
diagnostics.push(diagnostic(baseId, "missing_durable_source_identity", group, []));
|
|
81831
|
+
break;
|
|
81832
|
+
}
|
|
81833
|
+
if (entry.namespaceAlias && !NAMESPACE_ALIAS_LABEL_PATTERN.test(entry.namespaceAlias)) {
|
|
81834
|
+
diagnostics.push(diagnostic(baseId, "namespace_alias_invalid", group, []));
|
|
81835
|
+
break;
|
|
81836
|
+
}
|
|
81837
|
+
}
|
|
81838
|
+
return diagnostics;
|
|
81839
|
+
}
|
|
81840
|
+
function qualifyNamespaceGroup(group, options) {
|
|
81841
|
+
const ids = group.map((entry) => qualifiedId(entry, options.baseId, options.hashLength));
|
|
81842
|
+
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)) };
|
|
81843
|
+
return { diagnostic: diagnostic(options.baseId, "generated_id_collision", group, []) };
|
|
81844
|
+
}
|
|
81845
|
+
function qualifiedId(entry, baseId, hashLength) {
|
|
81846
|
+
return `${namespaceLabel(entry)}-${createHash("sha256").update(entry.durableSourceIdentity ?? "").digest("hex").slice(0, hashLength)}__${baseId}`;
|
|
81847
|
+
}
|
|
81848
|
+
function visibleRecord(entry, id, namespaced) {
|
|
81849
|
+
return {
|
|
81850
|
+
...entry,
|
|
81851
|
+
id,
|
|
81852
|
+
label: namespaceLabel(entry),
|
|
81853
|
+
namespaced
|
|
81854
|
+
};
|
|
81855
|
+
}
|
|
81856
|
+
function namespaceLabel(entry) {
|
|
81857
|
+
return entry.namespaceAlias ?? entry.sourceLabel ?? entry.sourceKind;
|
|
81858
|
+
}
|
|
81859
|
+
function diagnostic(requestedId, reason, group, alternatives) {
|
|
81860
|
+
return {
|
|
81861
|
+
requestedId,
|
|
81862
|
+
reason,
|
|
81863
|
+
alternatives,
|
|
81864
|
+
sources: group.map((entry) => ({
|
|
81865
|
+
sourceKind: entry.sourceKind,
|
|
81866
|
+
label: namespaceLabel(entry),
|
|
81867
|
+
...entry.durableSourceIdentity ? { durableSourceIdentity: entry.durableSourceIdentity } : {}
|
|
81868
|
+
})),
|
|
81869
|
+
hint: diagnosticHint(requestedId, reason, alternatives)
|
|
81870
|
+
};
|
|
81871
|
+
}
|
|
81872
|
+
function diagnosticHint(requestedId, reason, alternatives) {
|
|
81873
|
+
if (reason === "namespace_collision") return `Caplet '${requestedId}' is unavailable because namespace shadowing exposes qualified alternatives: ${alternatives.join(", ")}.`;
|
|
81874
|
+
if (reason === "missing_durable_source_identity") return `Caplet '${requestedId}' could not be namespaced because at least one source has no durable identity.`;
|
|
81875
|
+
if (reason === "namespace_alias_invalid") return `Caplet '${requestedId}' could not be namespaced because an alias label is invalid.`;
|
|
81876
|
+
if (reason === "unsupported_protocol") return `Caplet '${requestedId}' could not be namespaced because a source protocol cannot represent namespace metadata.`;
|
|
81877
|
+
return `Caplet '${requestedId}' could not be namespaced because generated qualified IDs were not unique.`;
|
|
81878
|
+
}
|
|
81879
|
+
//#endregion
|
|
81714
81880
|
//#region src/cloud-auth/errors.ts
|
|
81715
81881
|
const SECRET_PATTERN = /(cap_access_[a-z0-9._~+/=-]+|cap_refresh_[a-z0-9._~+/=-]+|one_time_code_[a-z0-9._~+/=-]+|Bearer\s+)[^\s"]*/giu;
|
|
81716
81882
|
function redactCloudAuthSecrets(value) {
|
|
@@ -83197,7 +83363,7 @@ function createLocalOverlayService(options) {
|
|
|
83197
83363
|
}
|
|
83198
83364
|
function createCompositeRemoteService(remoteOptions, local, options, authKind) {
|
|
83199
83365
|
const { remote, presence } = createCompositeRemoteParts(remoteOptions, local, options, authKind);
|
|
83200
|
-
return new CompositeNativeCapletsService(remote, local, options, presence);
|
|
83366
|
+
return new CompositeNativeCapletsService(remote, local, options, remoteOptions.url.toString(), presence);
|
|
83201
83367
|
}
|
|
83202
83368
|
function createCompositeRemoteParts(remoteOptions, local, options, authKind, resolveRuntimeRemoteOptions) {
|
|
83203
83369
|
const remote = new RemoteNativeCapletsService({
|
|
@@ -83289,7 +83455,7 @@ var ProfileBackedNativeCapletsService = class {
|
|
|
83289
83455
|
const signature = remoteOptionsSignature(remoteOptions);
|
|
83290
83456
|
if (!this.delegate) {
|
|
83291
83457
|
const { remote, presence } = createCompositeRemoteParts(remoteOptions, this.local, this.options, this.authKind, () => this.resolveProfileRemoteOptions());
|
|
83292
|
-
this.delegate = new CompositeNativeCapletsService(remote, this.local, this.options, presence);
|
|
83458
|
+
this.delegate = new CompositeNativeCapletsService(remote, this.local, this.options, remoteOptions.url.toString(), presence);
|
|
83293
83459
|
this.unsubscribeDelegate = this.delegate.onToolsChanged((tools) => this.emit(tools));
|
|
83294
83460
|
this.remoteSignature = signature;
|
|
83295
83461
|
this.credentialExpiresAt = remoteOptions.credentialExpiresAt;
|
|
@@ -83301,7 +83467,7 @@ var ProfileBackedNativeCapletsService = class {
|
|
|
83301
83467
|
await Promise.all([remote.close(), presence?.close()]);
|
|
83302
83468
|
return;
|
|
83303
83469
|
}
|
|
83304
|
-
await this.delegate.replaceRemote(remote, presence);
|
|
83470
|
+
await this.delegate.replaceRemote(remote, remoteOptions.url.toString(), presence);
|
|
83305
83471
|
this.remoteSignature = signature;
|
|
83306
83472
|
this.credentialExpiresAt = remoteOptions.credentialExpiresAt;
|
|
83307
83473
|
} catch (error) {
|
|
@@ -83386,23 +83552,30 @@ var CompositeNativeCapletsService = class {
|
|
|
83386
83552
|
remote;
|
|
83387
83553
|
local;
|
|
83388
83554
|
options;
|
|
83555
|
+
remoteIdentity;
|
|
83389
83556
|
presence;
|
|
83390
83557
|
listeners = /* @__PURE__ */ new Set();
|
|
83391
83558
|
unsubscribeRemote;
|
|
83392
83559
|
unsubscribeLocal;
|
|
83393
83560
|
warnedShadowedLocalCaplets = /* @__PURE__ */ new Set();
|
|
83394
83561
|
tools = [];
|
|
83562
|
+
routes = /* @__PURE__ */ new Map();
|
|
83563
|
+
namespaceDiagnostics = /* @__PURE__ */ new Map();
|
|
83395
83564
|
closed = false;
|
|
83396
83565
|
batchingReload = false;
|
|
83397
83566
|
codeModeSessions = new CodeModeSessionManager();
|
|
83398
|
-
constructor(remote, local, options, presence) {
|
|
83567
|
+
constructor(remote, local, options, remoteIdentity, presence) {
|
|
83399
83568
|
this.remote = remote;
|
|
83400
83569
|
this.local = local;
|
|
83401
83570
|
this.options = options;
|
|
83571
|
+
this.remoteIdentity = remoteIdentity;
|
|
83402
83572
|
this.presence = presence;
|
|
83403
83573
|
this.unsubscribeRemote = this.remote.onToolsChanged(() => this.updateMergedTools());
|
|
83404
83574
|
this.unsubscribeLocal = this.local.onToolsChanged(() => this.updateMergedTools());
|
|
83405
|
-
|
|
83575
|
+
const merged = this.mergeTools();
|
|
83576
|
+
this.tools = merged.tools;
|
|
83577
|
+
this.routes = merged.routes;
|
|
83578
|
+
this.namespaceDiagnostics = merged.namespaceDiagnostics;
|
|
83406
83579
|
this.startPresence();
|
|
83407
83580
|
}
|
|
83408
83581
|
listTools() {
|
|
@@ -83410,7 +83583,11 @@ var CompositeNativeCapletsService = class {
|
|
|
83410
83583
|
}
|
|
83411
83584
|
async execute(capletId, request) {
|
|
83412
83585
|
if (capletId === "code_mode") return await executeCodeModeRunNative(this, request, this.codeModeSessions);
|
|
83413
|
-
|
|
83586
|
+
const route = this.routes.get(capletId);
|
|
83587
|
+
if (route?.service === "local") return await this.local.execute(route.capletId, request);
|
|
83588
|
+
if (route?.service === "remote") return await this.remote.execute(route.capletId, request);
|
|
83589
|
+
const diagnostic = this.namespaceDiagnostics.get(capletId);
|
|
83590
|
+
if (diagnostic) throw new CapletsError("CAPLET_NAMESPACE_COLLISION", diagnostic.hint, diagnostic);
|
|
83414
83591
|
return await this.remote.execute(capletId, request);
|
|
83415
83592
|
}
|
|
83416
83593
|
codeModeService() {
|
|
@@ -83451,16 +83628,19 @@ var CompositeNativeCapletsService = class {
|
|
|
83451
83628
|
this.presence?.close()
|
|
83452
83629
|
]);
|
|
83453
83630
|
}
|
|
83454
|
-
async replaceRemote(remote, presence) {
|
|
83631
|
+
async replaceRemote(remote, remoteIdentityOrPresence, presence) {
|
|
83632
|
+
const remoteIdentity = typeof remoteIdentityOrPresence === "string" ? remoteIdentityOrPresence : this.remoteIdentity;
|
|
83633
|
+
const nextPresence = typeof remoteIdentityOrPresence === "string" ? presence : remoteIdentityOrPresence;
|
|
83455
83634
|
if (this.closed) {
|
|
83456
|
-
await Promise.all([remote.close(),
|
|
83635
|
+
await Promise.all([remote.close(), nextPresence?.close()]);
|
|
83457
83636
|
return;
|
|
83458
83637
|
}
|
|
83459
83638
|
const previousRemote = this.remote;
|
|
83460
83639
|
const previousPresence = this.presence;
|
|
83461
83640
|
this.unsubscribeRemote();
|
|
83462
83641
|
this.remote = remote;
|
|
83463
|
-
this.
|
|
83642
|
+
this.remoteIdentity = remoteIdentity;
|
|
83643
|
+
this.presence = nextPresence;
|
|
83464
83644
|
this.unsubscribeRemote = this.remote.onToolsChanged(() => this.updateMergedTools());
|
|
83465
83645
|
await Promise.all([previousRemote.close(), previousPresence?.close()]);
|
|
83466
83646
|
if (this.closed) return;
|
|
@@ -83469,9 +83649,15 @@ var CompositeNativeCapletsService = class {
|
|
|
83469
83649
|
}
|
|
83470
83650
|
updateMergedTools() {
|
|
83471
83651
|
if (this.closed || this.batchingReload) return;
|
|
83472
|
-
const
|
|
83473
|
-
if (JSON.stringify(tools) === JSON.stringify(this.tools))
|
|
83474
|
-
|
|
83652
|
+
const merged = this.mergeTools();
|
|
83653
|
+
if (JSON.stringify(merged.tools) === JSON.stringify(this.tools)) {
|
|
83654
|
+
this.routes = merged.routes;
|
|
83655
|
+
this.namespaceDiagnostics = merged.namespaceDiagnostics;
|
|
83656
|
+
return;
|
|
83657
|
+
}
|
|
83658
|
+
this.tools = merged.tools;
|
|
83659
|
+
this.routes = merged.routes;
|
|
83660
|
+
this.namespaceDiagnostics = merged.namespaceDiagnostics;
|
|
83475
83661
|
for (const listener of this.listeners) try {
|
|
83476
83662
|
listener(this.listTools());
|
|
83477
83663
|
} catch (error) {
|
|
@@ -83483,16 +83669,89 @@ var CompositeNativeCapletsService = class {
|
|
|
83483
83669
|
const allRemoteTools = this.remote.listTools();
|
|
83484
83670
|
const remoteCodeModeTools = remoteCodeModeCallableNativeTools(allRemoteTools);
|
|
83485
83671
|
const remoteIds = remoteSuppressedCapletIds(allRemoteTools, remoteCodeModeTools);
|
|
83486
|
-
const
|
|
83672
|
+
const unsuppressedLocalTools = allLocalTools.filter((tool) => tool.codeModeRun !== true && !remoteIds.has(tool.sourceCaplet ?? tool.caplet));
|
|
83487
83673
|
this.warnShadowedLocalCaplets(allLocalTools, remoteIds);
|
|
83488
|
-
const
|
|
83489
|
-
const
|
|
83490
|
-
const
|
|
83491
|
-
|
|
83674
|
+
const unsuppressedLocalCodeModeTools = codeModeCallableNativeTools(allLocalTools, { fallbackToVisible: false }).filter((tool) => !remoteIds.has(tool.caplet));
|
|
83675
|
+
const remoteTools = allRemoteTools.filter((tool) => tool.codeModeRun !== true);
|
|
83676
|
+
const resolved = this.resolveVisibleToolIds(remoteTools, unsuppressedLocalTools, remoteCodeModeTools, unsuppressedLocalCodeModeTools);
|
|
83677
|
+
const codeModeTools = [...resolved.remoteCodeModeTools, ...resolved.localCodeModeTools];
|
|
83678
|
+
return {
|
|
83679
|
+
tools: [
|
|
83680
|
+
...resolved.remoteTools,
|
|
83681
|
+
...resolved.localTools,
|
|
83682
|
+
...codeModeTools.length > 0 ? [codeModeRunNativeTool(codeModeTools)] : []
|
|
83683
|
+
],
|
|
83684
|
+
routes: resolved.routes,
|
|
83685
|
+
namespaceDiagnostics: resolved.namespaceDiagnostics
|
|
83686
|
+
};
|
|
83492
83687
|
}
|
|
83493
|
-
|
|
83494
|
-
const
|
|
83495
|
-
|
|
83688
|
+
resolveVisibleToolIds(remoteTools, localTools, remoteCodeModeTools, localCodeModeTools) {
|
|
83689
|
+
const resolution = resolveNamespaceExposure(nativeNamespaceEntries([{
|
|
83690
|
+
service: "remote",
|
|
83691
|
+
tools: [...remoteTools, ...remoteCodeModeTools]
|
|
83692
|
+
}, {
|
|
83693
|
+
service: "local",
|
|
83694
|
+
tools: [...localTools, ...localCodeModeTools]
|
|
83695
|
+
}], {
|
|
83696
|
+
...nativeNamespaceContext(this.options),
|
|
83697
|
+
remoteIdentity: this.remoteIdentity
|
|
83698
|
+
}));
|
|
83699
|
+
const namespacedRecords = resolution.visibleRecords.filter((record) => record.namespaced);
|
|
83700
|
+
const namespacedBaseIds = new Set(namespacedRecords.map((record) => record.baseId));
|
|
83701
|
+
const diagnosticBaseIds = new Set(resolution.unavailableDiagnostics.map((diagnostic) => diagnostic.requestedId));
|
|
83702
|
+
const routes = /* @__PURE__ */ new Map();
|
|
83703
|
+
const namespaceDiagnostics = new Map(resolution.suppressedBareIds);
|
|
83704
|
+
for (const diagnostic of resolution.unavailableDiagnostics) namespaceDiagnostics.set(diagnostic.requestedId, diagnostic);
|
|
83705
|
+
const alternativesByBaseId = /* @__PURE__ */ new Map();
|
|
83706
|
+
const staleIdsByBaseId = /* @__PURE__ */ new Map();
|
|
83707
|
+
const setRoute = (visibleCapletId, route, overwrite) => {
|
|
83708
|
+
if (overwrite || !routes.has(visibleCapletId)) routes.set(visibleCapletId, route);
|
|
83709
|
+
};
|
|
83710
|
+
const rewrite = (service, tools, overwrite) => {
|
|
83711
|
+
const rewritten = [];
|
|
83712
|
+
for (const tool of tools) {
|
|
83713
|
+
const baseId = sourceBaseId(tool);
|
|
83714
|
+
if (diagnosticBaseIds.has(baseId)) continue;
|
|
83715
|
+
if (!namespacedBaseIds.has(baseId)) {
|
|
83716
|
+
rewritten.push(tool);
|
|
83717
|
+
setRoute(tool.caplet, {
|
|
83718
|
+
service,
|
|
83719
|
+
capletId: tool.caplet
|
|
83720
|
+
}, overwrite);
|
|
83721
|
+
continue;
|
|
83722
|
+
}
|
|
83723
|
+
const record = namespacedRecords.find((candidate) => candidate.baseId === baseId && candidate.route.service === service);
|
|
83724
|
+
if (!record) continue;
|
|
83725
|
+
const visibleTool = renameNativeTool(tool, record.id);
|
|
83726
|
+
rewritten.push(visibleTool);
|
|
83727
|
+
addMapSetValue(alternativesByBaseId, baseId, visibleTool.caplet);
|
|
83728
|
+
if (tool.caplet !== visibleTool.caplet) addMapSetValue(staleIdsByBaseId, baseId, tool.caplet);
|
|
83729
|
+
setRoute(visibleTool.caplet, {
|
|
83730
|
+
service,
|
|
83731
|
+
capletId: tool.caplet
|
|
83732
|
+
}, overwrite);
|
|
83733
|
+
}
|
|
83734
|
+
return rewritten;
|
|
83735
|
+
};
|
|
83736
|
+
const remoteVisibleTools = rewrite("remote", remoteTools, false);
|
|
83737
|
+
const localVisibleTools = rewrite("local", localTools, true);
|
|
83738
|
+
const remoteVisibleCodeModeTools = rewrite("remote", remoteCodeModeTools, false);
|
|
83739
|
+
const localVisibleCodeModeTools = rewrite("local", localCodeModeTools, true);
|
|
83740
|
+
for (const [baseId, alternatives] of alternativesByBaseId) {
|
|
83741
|
+
const baseDiagnostic = resolution.suppressedBareIds.get(baseId);
|
|
83742
|
+
if (!baseDiagnostic) continue;
|
|
83743
|
+
const alternativeList = [...alternatives];
|
|
83744
|
+
namespaceDiagnostics.set(baseId, namespaceDiagnosticWithAlternatives(baseId, baseDiagnostic, alternativeList));
|
|
83745
|
+
for (const staleId of staleIdsByBaseId.get(baseId) ?? []) namespaceDiagnostics.set(staleId, namespaceDiagnosticWithAlternatives(staleId, baseDiagnostic, alternativeList));
|
|
83746
|
+
}
|
|
83747
|
+
return {
|
|
83748
|
+
remoteTools: remoteVisibleTools,
|
|
83749
|
+
localTools: localVisibleTools,
|
|
83750
|
+
remoteCodeModeTools: remoteVisibleCodeModeTools,
|
|
83751
|
+
localCodeModeTools: localVisibleCodeModeTools,
|
|
83752
|
+
routes,
|
|
83753
|
+
namespaceDiagnostics
|
|
83754
|
+
};
|
|
83496
83755
|
}
|
|
83497
83756
|
warnShadowedLocalCaplets(localTools, remoteIds) {
|
|
83498
83757
|
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)]);
|
|
@@ -83517,22 +83776,85 @@ var CompositeNativeCapletsService = class {
|
|
|
83517
83776
|
});
|
|
83518
83777
|
}
|
|
83519
83778
|
};
|
|
83520
|
-
function
|
|
83521
|
-
|
|
83779
|
+
function addMapSetValue(map, key, value) {
|
|
83780
|
+
let values = map.get(key);
|
|
83781
|
+
if (!values) {
|
|
83782
|
+
values = /* @__PURE__ */ new Set();
|
|
83783
|
+
map.set(key, values);
|
|
83784
|
+
}
|
|
83785
|
+
values.add(value);
|
|
83522
83786
|
}
|
|
83523
|
-
function
|
|
83524
|
-
return
|
|
83787
|
+
function namespaceDiagnosticWithAlternatives(requestedId, diagnostic, alternatives) {
|
|
83788
|
+
return {
|
|
83789
|
+
...diagnostic,
|
|
83790
|
+
requestedId,
|
|
83791
|
+
alternatives,
|
|
83792
|
+
hint: `Caplet '${requestedId}' is unavailable because namespace shadowing exposes qualified alternatives: ${alternatives.join(", ")}.`
|
|
83793
|
+
};
|
|
83525
83794
|
}
|
|
83526
|
-
function
|
|
83527
|
-
const
|
|
83528
|
-
|
|
83529
|
-
|
|
83530
|
-
|
|
83531
|
-
|
|
83795
|
+
function nativeNamespaceContext(options) {
|
|
83796
|
+
const configPath = options.configPath ?? resolveConfigPath();
|
|
83797
|
+
const projectConfigPath = options.projectConfigPath ?? resolveProjectConfigPath();
|
|
83798
|
+
let namespaceAliases = parseConfig({}).namespaceAliases;
|
|
83799
|
+
try {
|
|
83800
|
+
namespaceAliases = loadLocalOverlayConfigWithSources(configPath, projectConfigPath).config.namespaceAliases;
|
|
83801
|
+
} catch {}
|
|
83802
|
+
return {
|
|
83803
|
+
localIdentity: `local:${configPath}\0${projectConfigPath}`,
|
|
83804
|
+
namespaceAliases
|
|
83805
|
+
};
|
|
83806
|
+
}
|
|
83807
|
+
function nativeNamespaceEntries(groups, identities) {
|
|
83808
|
+
const entries = /* @__PURE__ */ new Map();
|
|
83809
|
+
for (const group of groups) {
|
|
83810
|
+
const byBaseId = /* @__PURE__ */ new Map();
|
|
83811
|
+
for (const tool of group.tools) {
|
|
83812
|
+
const baseId = sourceBaseId(tool);
|
|
83813
|
+
byBaseId.set(baseId, [...byBaseId.get(baseId) ?? [], tool]);
|
|
83814
|
+
}
|
|
83815
|
+
for (const [baseId, tools] of byBaseId) {
|
|
83816
|
+
const service = group.service;
|
|
83817
|
+
entries.set(`${service}:${baseId}`, {
|
|
83818
|
+
baseId,
|
|
83819
|
+
sourceKind: service === "local" ? "local" : "upstream",
|
|
83820
|
+
sourceLabel: service === "local" ? "local" : "remote",
|
|
83821
|
+
namespaceAlias: service === "local" ? identities.namespaceAliases.local : identities.namespaceAliases.upstreams[identities.remoteIdentity],
|
|
83822
|
+
durableSourceIdentity: service === "local" ? identities.localIdentity : identities.remoteIdentity,
|
|
83823
|
+
shadowing: aggregateShadowing(tools),
|
|
83824
|
+
route: {
|
|
83825
|
+
service,
|
|
83826
|
+
baseId
|
|
83827
|
+
}
|
|
83828
|
+
});
|
|
83532
83829
|
}
|
|
83533
|
-
if (tool.caplet === capletId || tool.sourceCaplet === capletId) keys.push(tool.sourceCaplet ?? tool.caplet);
|
|
83534
83830
|
}
|
|
83535
|
-
return
|
|
83831
|
+
return [...entries.values()];
|
|
83832
|
+
}
|
|
83833
|
+
function aggregateShadowing(tools) {
|
|
83834
|
+
if (tools.some((tool) => (tool.shadowing ?? "forbid") === "forbid")) return "forbid";
|
|
83835
|
+
if (tools.some((tool) => tool.shadowing === "namespace")) return "namespace";
|
|
83836
|
+
return "allow";
|
|
83837
|
+
}
|
|
83838
|
+
function sourceBaseId(tool) {
|
|
83839
|
+
return tool.sourceCaplet ?? tool.caplet;
|
|
83840
|
+
}
|
|
83841
|
+
function renameNativeTool(tool, visibleBaseId) {
|
|
83842
|
+
const baseId = sourceBaseId(tool);
|
|
83843
|
+
const visibleCapletId = tool.sourceCaplet && tool.caplet.startsWith(`${baseId}__`) ? `${visibleBaseId}${tool.caplet.slice(baseId.length)}` : visibleBaseId;
|
|
83844
|
+
const operationName = tool.sourceCaplet && tool.caplet.startsWith(`${baseId}__`) ? tool.caplet.slice(baseId.length + 2) : void 0;
|
|
83845
|
+
const toolName = operationName ? nativeDirectToolName(visibleBaseId, operationName) : nativeCapletToolName(visibleCapletId);
|
|
83846
|
+
return {
|
|
83847
|
+
...tool,
|
|
83848
|
+
caplet: visibleCapletId,
|
|
83849
|
+
...tool.sourceCaplet ? { sourceCaplet: visibleBaseId } : {},
|
|
83850
|
+
toolName
|
|
83851
|
+
};
|
|
83852
|
+
}
|
|
83853
|
+
function remoteCodeModeCallableNativeTools(tools) {
|
|
83854
|
+
return codeModeCallableNativeTools(tools, { fallbackToVisible: true });
|
|
83855
|
+
}
|
|
83856
|
+
function remoteSuppressedCapletIds(allRemoteTools, remoteCodeModeTools = remoteCodeModeCallableNativeTools(allRemoteTools)) {
|
|
83857
|
+
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));
|
|
83536
83858
|
}
|
|
83537
83859
|
function createProjectBindingSessionManager(cloud, local, options) {
|
|
83538
83860
|
if (!cloud) return;
|
|
@@ -31,6 +31,7 @@ const CAPLETS_ERROR_CODES = [
|
|
|
31
31
|
"SERVER_UNAVAILABLE",
|
|
32
32
|
"SERVER_START_TIMEOUT",
|
|
33
33
|
"UNKNOWN_OPERATION",
|
|
34
|
+
"CAPLET_NAMESPACE_COLLISION",
|
|
34
35
|
"TOOL_NOT_FOUND",
|
|
35
36
|
"TOOL_CALL_TIMEOUT",
|
|
36
37
|
"AUTH_REQUIRED",
|
|
@@ -112,6 +113,7 @@ function errorResult(error, fallback) {
|
|
|
112
113
|
//#endregion
|
|
113
114
|
//#region src/config/validation.ts
|
|
114
115
|
const SERVER_ID_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
116
|
+
const NAMESPACE_ALIAS_LABEL_PATTERN = /^[a-z](?:[a-z0-9-]{0,30}[a-z0-9])?$/;
|
|
115
117
|
const HEADER_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
116
118
|
const HTTP_BASE_URL_PATTERN = /^(?![a-zA-Z][a-zA-Z0-9+.-]*:\/\/[^/?#]*@)[^?#]*$/;
|
|
117
119
|
const FORBIDDEN_HEADERS = /* @__PURE__ */ new Set([
|
|
@@ -174,4 +176,4 @@ function isUrl(value) {
|
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
178
|
//#endregion
|
|
177
|
-
export {
|
|
179
|
+
export { SERVER_ID_PATTERN as a, isUrl as c, CapletsError as d, errorResult as f, NAMESPACE_ALIAS_LABEL_PATTERN as i, validateHttpActionHeaders as l, toSafeError as m, HEADER_NAME_PATTERN as n, isAllowedHttpBaseUrl as o, redactSecrets as p, HTTP_BASE_URL_PATTERN as r, isAllowedRemoteUrl as s, FORBIDDEN_HEADERS as t, CAPLETS_ERROR_CODES as u };
|