@caplets/core 0.26.0 → 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.
@@ -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: "forbid" | "allow";
30
+ shadowing: CapletShadowingPolicy;
30
31
  };
31
32
  export type AttachProgressiveCapletExport = AttachManifestExport & {
32
33
  kind: "caplet";
@@ -454,6 +454,7 @@ export declare const capletFileSchema: z.ZodObject<{
454
454
  shadowing: z.ZodOptional<z.ZodEnum<{
455
455
  forbid: "forbid";
456
456
  allow: "allow";
457
+ namespace: "namespace";
457
458
  }>>;
458
459
  }, z.core.$strict>;
459
460
  export declare function capletJsonSchema(): unknown;
@@ -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(["forbid", "allow"]).describe("Whether attached local Caplets may shadow this remote Caplet ID.");
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(["forbid", "allow"]).default("forbid");
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 {
@@ -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;
package/dist/cli.d.ts CHANGED
@@ -24,4 +24,9 @@ type CliIO = {
24
24
  readStdin?: () => Promise<string>;
25
25
  };
26
26
  export declare function runCli(args: string[], io?: CliIO): Promise<void>;
27
+ export declare const readHiddenInputForTest: typeof readHiddenInput;
28
+ declare function readHiddenInput(label: string, options?: {
29
+ input?: NodeJS.ReadableStream;
30
+ output?: Pick<NodeJS.WriteStream, "write">;
31
+ }): Promise<string>;
27
32
  export declare function createProgram(io?: CliIO): Command;
@@ -6,7 +6,7 @@ export type CodeModeCallableCaplet = {
6
6
  id: string;
7
7
  name: string;
8
8
  description: string;
9
- shadowing?: "forbid" | "allow";
9
+ shadowing?: "forbid" | "allow" | "namespace";
10
10
  useWhen?: string;
11
11
  avoidWhen?: string;
12
12
  };
@@ -1,5 +1,5 @@
1
- import { Bn as __exportAll, Ft as DEFAULT_COMPLETION_CACHE_DIR, Ht as resolveConfigPath, Pt as DEFAULT_AUTH_DIR, Vt as resolveCapletsRoot, Wt as resolveProjectConfigPath, lt as loadConfigWithSources } from "./service-rvZ7z6FI.js";
2
- import { u as CapletsError } from "./validation-C4tYXw6G.js";
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;
@@ -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>;
@@ -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 isAllowedHttpBaseUrl, c as validateHttpActionHeaders, i as SERVER_ID_PATTERN, n as HEADER_NAME_PATTERN, o as isAllowedRemoteUrl, r as HTTP_BASE_URL_PATTERN, s as isUrl, t as FORBIDDEN_HEADERS, u as CapletsError } from "./validation-C4tYXw6G.js";
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(["forbid", "allow"]).default("forbid");
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>>>>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Node's POSIX filesystem APIs do not treat backslashes as path separators. Tests
3
+ * sometimes emulate Windows daemon operations with POSIX temp directories, which
4
+ * `node:path.win32` renders as drive-less absolute paths such as
5
+ * `\tmp\caplets-...`. On POSIX hosts those strings would otherwise be created as
6
+ * single backslash-named entries in the current working directory.
7
+ */
8
+ export declare function daemonHostPath(path: string): string;
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", "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>;