@caplets/core 0.18.9 → 0.20.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.
Files changed (132) hide show
  1. package/dist/attach/options.d.ts +10 -0
  2. package/dist/attach/server.d.ts +5 -0
  3. package/dist/caplet-files-bundle.d.ts +430 -0
  4. package/dist/caplet-files.d.ts +3 -266
  5. package/dist/caplet-source/bundle.d.ts +7 -0
  6. package/dist/caplet-source/filesystem.d.ts +7 -0
  7. package/dist/caplet-source/filesystem.js +2 -0
  8. package/dist/caplet-source/index.d.ts +4 -0
  9. package/dist/caplet-source/parse.d.ts +35 -0
  10. package/dist/caplet-source/types.d.ts +9 -0
  11. package/dist/caplet-source.js +7011 -0
  12. package/dist/cli/auth.d.ts +40 -2
  13. package/dist/cli/cloud-add.d.ts +8 -0
  14. package/dist/cli/code-mode.d.ts +16 -0
  15. package/dist/cli/commands.d.ts +8 -1
  16. package/dist/cli/doctor.d.ts +21 -0
  17. package/dist/cli/setup-caplet.d.ts +12 -0
  18. package/dist/cli/setup.d.ts +11 -0
  19. package/dist/cli-tools.d.ts +1 -1
  20. package/dist/cli.d.ts +8 -1
  21. package/dist/cloud/apply.d.ts +36 -0
  22. package/dist/cloud/client.d.ts +30 -0
  23. package/dist/cloud/presence.d.ts +29 -0
  24. package/dist/cloud/project-root.d.ts +2 -0
  25. package/dist/cloud/runtime-adapter.d.ts +23 -0
  26. package/dist/cloud/runtime-http.d.ts +6 -0
  27. package/dist/cloud/sync.d.ts +10 -0
  28. package/dist/cloud-auth/client.d.ts +57 -0
  29. package/dist/cloud-auth/errors.d.ts +11 -0
  30. package/dist/cloud-auth/open-url.d.ts +7 -0
  31. package/dist/cloud-auth/store.d.ts +35 -0
  32. package/dist/cloud-auth/types.d.ts +67 -0
  33. package/dist/code-mode/api.d.ts +32 -0
  34. package/dist/code-mode/declarations.d.ts +5 -0
  35. package/dist/code-mode/diagnostics.d.ts +8 -0
  36. package/dist/code-mode/index.d.ts +4 -0
  37. package/dist/code-mode/logs.d.ts +21 -0
  38. package/dist/code-mode/runner.d.ts +15 -0
  39. package/dist/code-mode/runtime-api.generated.d.ts +1 -0
  40. package/dist/code-mode/sandbox.d.ts +28 -0
  41. package/dist/code-mode/static-analysis.d.ts +2 -0
  42. package/dist/code-mode/tool.d.ts +11 -0
  43. package/dist/code-mode/types.d.ts +120 -0
  44. package/dist/code-mode.js +147855 -0
  45. package/dist/{completion-RqzHpHRY.js → completion-CbazRAiL.js} +20 -1
  46. package/dist/config/paths.d.ts +2 -0
  47. package/dist/config-runtime.d.ts +183 -0
  48. package/dist/config-runtime.js +421 -0
  49. package/dist/config.d.ts +76 -9
  50. package/dist/downstream.d.ts +20 -2
  51. package/dist/engine.d.ts +20 -0
  52. package/dist/exposure/direct-names.d.ts +9 -0
  53. package/dist/exposure/discovery.d.ts +75 -0
  54. package/dist/exposure/policy.d.ts +8 -0
  55. package/dist/filesystem-Kkg32TOJ.js +66 -0
  56. package/dist/generated-tool-input-schema.d.ts +89 -59
  57. package/dist/generated-tool-input-schema.js +172 -1
  58. package/dist/graphql.d.ts +1 -1
  59. package/dist/http-actions.d.ts +1 -1
  60. package/dist/index.d.ts +48 -0
  61. package/dist/index.js +4176 -501
  62. package/dist/native/options.d.ts +22 -3
  63. package/dist/native/remote.d.ts +2 -1
  64. package/dist/native/service.d.ts +13 -3
  65. package/dist/native/tools.d.ts +2 -0
  66. package/dist/native.d.ts +1 -1
  67. package/dist/native.js +3 -431
  68. package/dist/observed-output-shapes/extract.d.ts +5 -0
  69. package/dist/observed-output-shapes/file-store.d.ts +17 -0
  70. package/dist/observed-output-shapes/index.d.ts +7 -0
  71. package/dist/observed-output-shapes/key.d.ts +14 -0
  72. package/dist/observed-output-shapes/merge.d.ts +2 -0
  73. package/dist/observed-output-shapes/pure.d.ts +5 -0
  74. package/dist/observed-output-shapes/pure.js +241 -0
  75. package/dist/observed-output-shapes/schema.d.ts +1 -0
  76. package/dist/observed-output-shapes/types.d.ts +84 -0
  77. package/dist/observed-output-shapes/typescript.d.ts +7 -0
  78. package/dist/observed-output-shapes-uzAMQPhg.js +485 -0
  79. package/dist/observed-output-shapes.js +2 -0
  80. package/dist/openapi.d.ts +1 -1
  81. package/dist/project-binding/attach.d.ts +46 -0
  82. package/dist/project-binding/errors.d.ts +17 -0
  83. package/dist/project-binding/gitignore.d.ts +5 -0
  84. package/dist/project-binding/index.d.ts +2 -0
  85. package/dist/project-binding/mutagen.d.ts +65 -0
  86. package/dist/project-binding/routes.d.ts +9 -0
  87. package/dist/project-binding/session.d.ts +82 -0
  88. package/dist/project-binding/sync-filter.d.ts +19 -0
  89. package/dist/project-binding/sync-size.d.ts +27 -0
  90. package/dist/project-binding/transport.d.ts +21 -0
  91. package/dist/project-binding/types.d.ts +31 -0
  92. package/dist/project-binding/workspaces.d.ts +60 -0
  93. package/dist/project-binding.js +22 -0
  94. package/dist/redaction.d.ts +14 -0
  95. package/dist/redaction.js +30 -0
  96. package/dist/registry.d.ts +4 -0
  97. package/dist/remote/options.d.ts +44 -0
  98. package/dist/remote/selection.d.ts +26 -0
  99. package/dist/remote-control/types.d.ts +1 -1
  100. package/dist/runtime-plan/features.d.ts +7 -0
  101. package/dist/runtime-plan/index.d.ts +4 -0
  102. package/dist/runtime-plan/planner.d.ts +5 -0
  103. package/dist/runtime-plan/resources.d.ts +13 -0
  104. package/dist/runtime-plan/types.d.ts +82 -0
  105. package/dist/runtime-plan.js +281 -0
  106. package/dist/schemas-1HZ0kFpx.js +4270 -0
  107. package/dist/{generated-tool-input-schema--kVuUNc5.js → schemas-BZ6BBrh7.js} +1 -161
  108. package/dist/serve/daemon/config.d.ts +8 -0
  109. package/dist/serve/daemon/index.d.ts +16 -0
  110. package/dist/serve/daemon/paths.d.ts +3 -0
  111. package/dist/serve/daemon/platform-darwin.d.ts +2 -0
  112. package/dist/serve/daemon/platform-linux.d.ts +2 -0
  113. package/dist/serve/daemon/platform-windows.d.ts +2 -0
  114. package/dist/serve/daemon/platform.d.ts +9 -0
  115. package/dist/serve/daemon/process.d.ts +5 -0
  116. package/dist/serve/daemon/types.d.ts +86 -0
  117. package/dist/serve/http.d.ts +8 -0
  118. package/dist/serve/index.d.ts +5 -1
  119. package/dist/serve/native-session.d.ts +19 -0
  120. package/dist/serve/options.d.ts +1 -0
  121. package/dist/serve/session.d.ts +15 -3
  122. package/dist/server/options.d.ts +1 -1
  123. package/dist/{options-DnOUjft1.js → service-D0MwLNyb.js} +38003 -27618
  124. package/dist/setup/hash.d.ts +3 -0
  125. package/dist/setup/local-store.d.ts +34 -0
  126. package/dist/setup/runner.d.ts +40 -0
  127. package/dist/setup/types.d.ts +52 -0
  128. package/dist/stable-json.d.ts +3 -0
  129. package/dist/stable-json.js +26 -0
  130. package/dist/tools.d.ts +38 -12
  131. package/dist/validation-CdqbI2zN.js +174 -0
  132. package/package.json +48 -6
@@ -1,4 +1,5 @@
1
- import { Ct as resolveCapletsRoot, Et as resolveProjectConfigPath, Lt as __exportAll, Pt as CapletsError, St as DEFAULT_COMPLETION_CACHE_DIR, gt as loadConfigWithSources, wt as resolveConfigPath, xt as DEFAULT_AUTH_DIR } from "./options-DnOUjft1.js";
1
+ import { St as resolveProjectConfigPath, Y as loadConfigWithSources, bt as resolveConfigPath, mt as DEFAULT_COMPLETION_CACHE_DIR, pt as DEFAULT_AUTH_DIR, vn as __exportAll, yt as resolveCapletsRoot } from "./service-D0MwLNyb.js";
2
+ import { u as CapletsError } from "./validation-CdqbI2zN.js";
2
3
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
3
4
  import { dirname, join } from "node:path";
4
5
  import { createHash } from "node:crypto";
@@ -13,9 +14,13 @@ const completionShells = [
13
14
  const cliCommands = {
14
15
  completion: "completion",
15
16
  completeHidden: "__complete",
17
+ codeMode: "code-mode",
16
18
  serve: "serve",
19
+ attach: "attach",
20
+ cloud: "cloud",
17
21
  init: "init",
18
22
  setup: "setup",
23
+ doctor: "doctor",
19
24
  list: "list",
20
25
  install: "install",
21
26
  add: "add",
@@ -38,8 +43,12 @@ const cliCommands = {
38
43
  };
39
44
  const topLevelCommandNames = [
40
45
  cliCommands.serve,
46
+ cliCommands.codeMode,
47
+ cliCommands.attach,
48
+ cliCommands.cloud,
41
49
  cliCommands.init,
42
50
  cliCommands.setup,
51
+ cliCommands.doctor,
43
52
  cliCommands.list,
44
53
  cliCommands.install,
45
54
  cliCommands.add,
@@ -74,8 +83,18 @@ const cliSubcommands = {
74
83
  "logout",
75
84
  "list"
76
85
  ],
86
+ [cliCommands.cloud]: ["auth"],
87
+ [cliCommands.codeMode]: ["types"],
77
88
  [cliCommands.completion]: [...completionShells],
78
89
  [cliCommands.config]: ["path", "paths"],
90
+ [cliCommands.serve]: [
91
+ "start",
92
+ "stop",
93
+ "status",
94
+ "restart",
95
+ "enable",
96
+ "disable"
97
+ ],
79
98
  [cliCommands.setup]: [
80
99
  "codex",
81
100
  "claude-code",
@@ -6,9 +6,11 @@ export declare function defaultCacheBaseDir(env?: PathEnv, home?: string, platfo
6
6
  export declare function defaultConfigPath(env?: PathEnv, home?: string, platform?: Platform): string;
7
7
  export declare function defaultAuthDir(env?: PathEnv, home?: string, platform?: Platform): string;
8
8
  export declare function defaultCompletionCacheDir(env?: PathEnv, home?: string, platform?: Platform): string;
9
+ export declare function defaultObservedOutputShapeCacheDir(env?: PathEnv, home?: string, platform?: Platform): string;
9
10
  export declare const DEFAULT_CONFIG_PATH: string;
10
11
  export declare const DEFAULT_AUTH_DIR: string;
11
12
  export declare const DEFAULT_COMPLETION_CACHE_DIR: string;
13
+ export declare const DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR: string;
12
14
  export declare const PROJECT_CONFIG_FILE: string;
13
15
  export declare function resolveConfigPath(path?: string): string;
14
16
  export declare function resolveProjectConfigPath(cwd?: string): string;
@@ -0,0 +1,183 @@
1
+ export type RemoteAuthConfig = {
2
+ type: "none";
3
+ } | {
4
+ type: "bearer";
5
+ token: string;
6
+ } | {
7
+ type: "headers";
8
+ headers: Record<string, string>;
9
+ } | {
10
+ type: "oauth2" | "oidc";
11
+ authorizationUrl?: string | undefined;
12
+ tokenUrl?: string | undefined;
13
+ issuer?: string | undefined;
14
+ resourceMetadataUrl?: string | undefined;
15
+ authorizationServerMetadataUrl?: string | undefined;
16
+ openidConfigurationUrl?: string | undefined;
17
+ clientMetadataUrl?: string | undefined;
18
+ clientId?: string | undefined;
19
+ clientSecret?: string | undefined;
20
+ scopes?: string[] | undefined;
21
+ redirectUri?: string | undefined;
22
+ };
23
+ export type CapletSetupCommandConfig = {
24
+ label: string;
25
+ command: string;
26
+ args?: string[] | undefined;
27
+ env?: Record<string, string> | undefined;
28
+ cwd?: string | undefined;
29
+ timeoutMs?: number | undefined;
30
+ maxOutputBytes?: number | undefined;
31
+ };
32
+ export type CapletSetupConfig = {
33
+ commands?: CapletSetupCommandConfig[] | undefined;
34
+ verify?: CapletSetupCommandConfig[] | undefined;
35
+ };
36
+ export type ProjectBindingConfig = {
37
+ required: true;
38
+ };
39
+ export type RuntimeFeature = "docker" | "browser";
40
+ export type RuntimeResourceClass = "standard" | "large" | "heavy";
41
+ export type RuntimeRequirementsConfig = {
42
+ features?: RuntimeFeature[] | undefined;
43
+ resources?: {
44
+ class?: RuntimeResourceClass | undefined;
45
+ } | undefined;
46
+ };
47
+ export type AgentSelectionHintsConfig = {
48
+ useWhen?: string | undefined;
49
+ avoidWhen?: string | undefined;
50
+ };
51
+ export type CapletExposure = "direct" | "progressive" | "code_mode" | "direct_and_code_mode" | "progressive_and_code_mode";
52
+ export type CapletServerConfig = CommonCapletConfig & {
53
+ backend: "mcp";
54
+ transport: "stdio" | "http" | "sse";
55
+ command?: string | undefined;
56
+ args?: string[] | undefined;
57
+ env?: Record<string, string> | undefined;
58
+ cwd?: string | undefined;
59
+ url?: string | undefined;
60
+ auth?: RemoteAuthConfig | undefined;
61
+ startupTimeoutMs: number;
62
+ callTimeoutMs: number;
63
+ toolCacheTtlMs: number;
64
+ };
65
+ export type OpenApiAuthConfig = RemoteAuthConfig;
66
+ export type OpenApiEndpointConfig = CommonCapletConfig & {
67
+ backend: "openapi";
68
+ specPath?: string | undefined;
69
+ specUrl?: string | undefined;
70
+ baseUrl?: string | undefined;
71
+ auth: OpenApiAuthConfig;
72
+ requestTimeoutMs: number;
73
+ operationCacheTtlMs: number;
74
+ };
75
+ export type GraphQlOperationConfig = AgentSelectionHintsConfig & {
76
+ document?: string | undefined;
77
+ documentPath?: string | undefined;
78
+ operationName?: string | undefined;
79
+ description?: string | undefined;
80
+ };
81
+ export type GraphQlEndpointConfig = CommonCapletConfig & {
82
+ backend: "graphql";
83
+ endpointUrl: string;
84
+ schemaPath?: string | undefined;
85
+ schemaUrl?: string | undefined;
86
+ introspection?: true | undefined;
87
+ operations?: Record<string, GraphQlOperationConfig> | undefined;
88
+ auth: OpenApiAuthConfig;
89
+ requestTimeoutMs: number;
90
+ operationCacheTtlMs: number;
91
+ selectionDepth: number;
92
+ };
93
+ export type HttpActionConfig = AgentSelectionHintsConfig & {
94
+ method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
95
+ path: string;
96
+ description?: string | undefined;
97
+ inputSchema?: Record<string, unknown> | undefined;
98
+ outputSchema?: Record<string, unknown> | undefined;
99
+ query?: Record<string, string | number | boolean> | undefined;
100
+ headers?: Record<string, string | number | boolean> | undefined;
101
+ jsonBody?: unknown;
102
+ };
103
+ export type HttpApiConfig = CommonCapletConfig & {
104
+ backend: "http";
105
+ baseUrl: string;
106
+ auth: OpenApiAuthConfig;
107
+ actions: Record<string, HttpActionConfig>;
108
+ requestTimeoutMs: number;
109
+ maxResponseBytes: number;
110
+ };
111
+ export type CliToolActionConfig = AgentSelectionHintsConfig & {
112
+ description?: string | undefined;
113
+ inputSchema?: Record<string, unknown> | undefined;
114
+ outputSchema?: Record<string, unknown> | undefined;
115
+ command: string;
116
+ args?: string[] | undefined;
117
+ env?: Record<string, string> | undefined;
118
+ cwd?: string | undefined;
119
+ timeoutMs?: number | undefined;
120
+ maxOutputBytes?: number | undefined;
121
+ output?: {
122
+ type: "text" | "json";
123
+ } | undefined;
124
+ annotations?: {
125
+ readOnlyHint?: boolean | undefined;
126
+ destructiveHint?: boolean | undefined;
127
+ idempotentHint?: boolean | undefined;
128
+ openWorldHint?: boolean | undefined;
129
+ } | undefined;
130
+ };
131
+ export type CliToolsConfig = CommonCapletConfig & {
132
+ backend: "cli";
133
+ actions: Record<string, CliToolActionConfig>;
134
+ cwd?: string | undefined;
135
+ env?: Record<string, string> | undefined;
136
+ timeoutMs: number;
137
+ maxOutputBytes: number;
138
+ };
139
+ export type CapletSetConfig = CommonCapletConfig & {
140
+ backend: "caplets";
141
+ configPath?: string | undefined;
142
+ capletsRoot?: string | undefined;
143
+ defaultSearchLimit: number;
144
+ maxSearchLimit: number;
145
+ toolCacheTtlMs: number;
146
+ };
147
+ export type CapletConfig = CapletServerConfig | OpenApiEndpointConfig | GraphQlEndpointConfig | HttpApiConfig | CliToolsConfig | CapletSetConfig;
148
+ export type CapletsConfig = {
149
+ version: 1;
150
+ options: {
151
+ defaultSearchLimit: number;
152
+ maxSearchLimit: number;
153
+ exposure: CapletExposure;
154
+ exposureDiscoveryTimeoutMs: number;
155
+ exposureDiscoveryConcurrency: number;
156
+ completion: {
157
+ discoveryTimeoutMs: number;
158
+ overallTimeoutMs: number;
159
+ cacheTtlMs: number;
160
+ negativeCacheTtlMs: number;
161
+ };
162
+ };
163
+ mcpServers: Record<string, CapletServerConfig>;
164
+ openapiEndpoints: Record<string, OpenApiEndpointConfig>;
165
+ graphqlEndpoints: Record<string, GraphQlEndpointConfig>;
166
+ httpApis: Record<string, HttpApiConfig>;
167
+ cliTools: Record<string, CliToolsConfig>;
168
+ capletSets: Record<string, CapletSetConfig>;
169
+ };
170
+ type CommonCapletConfig = AgentSelectionHintsConfig & {
171
+ server: string;
172
+ name: string;
173
+ description: string;
174
+ exposure?: CapletExposure | undefined;
175
+ tags?: string[] | undefined;
176
+ body?: string | undefined;
177
+ setup?: CapletSetupConfig | undefined;
178
+ projectBinding?: ProjectBindingConfig | undefined;
179
+ runtime?: RuntimeRequirementsConfig | undefined;
180
+ disabled: boolean;
181
+ };
182
+ export declare function parseConfig(input: unknown): CapletsConfig;
183
+ export {};
@@ -0,0 +1,421 @@
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-BZ6BBrh7.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-CdqbI2zN.js";
3
+ //#region src/config-runtime.ts
4
+ const stringMapSchema = record(string(), string());
5
+ const authSchema = discriminatedUnion("type", [
6
+ object({ type: literal("none") }).strict(),
7
+ object({
8
+ type: literal("bearer"),
9
+ token: string().min(1)
10
+ }).strict(),
11
+ object({
12
+ type: literal("headers"),
13
+ headers: stringMapSchema
14
+ }).strict(),
15
+ oauthLikeSchema("oauth2"),
16
+ oauthLikeSchema("oidc")
17
+ ]);
18
+ const setupCommandSchema = object({
19
+ label: string().min(1),
20
+ command: string().min(1),
21
+ args: array(string()).optional(),
22
+ env: stringMapSchema.optional(),
23
+ cwd: string().min(1).optional(),
24
+ timeoutMs: number().int().positive().optional(),
25
+ maxOutputBytes: number().int().positive().optional()
26
+ }).strict();
27
+ const setupSchema = object({
28
+ commands: array(setupCommandSchema).optional(),
29
+ verify: array(setupCommandSchema).optional()
30
+ }).strict().refine((setup) => (setup.commands?.length ?? 0) > 0 || (setup.verify?.length ?? 0) > 0, "setup must define at least one command or verify step");
31
+ const projectBindingSchema = object({ required: literal(true) }).strict();
32
+ const runtimeRequirementsSchema = object({
33
+ features: array(_enum(["docker", "browser"])).refine((features) => new Set(features).size === features.length, { message: "runtime.features must not contain duplicate feature names" }).optional(),
34
+ resources: object({ class: _enum([
35
+ "standard",
36
+ "large",
37
+ "heavy"
38
+ ]).optional() }).strict().optional()
39
+ }).strict();
40
+ const agentSelectionHintSchema = string().trim().min(1).max(500);
41
+ const agentSelectionHintsSchema = {
42
+ useWhen: agentSelectionHintSchema.optional(),
43
+ avoidWhen: agentSelectionHintSchema.optional()
44
+ };
45
+ const exposureSchema = _enum([
46
+ "direct",
47
+ "progressive",
48
+ "code_mode",
49
+ "direct_and_code_mode",
50
+ "progressive_and_code_mode"
51
+ ]);
52
+ const commonSchema = {
53
+ name: string().trim().min(1).max(80),
54
+ 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"),
55
+ tags: array(string().trim().min(1).max(80)).optional(),
56
+ exposure: exposureSchema.optional(),
57
+ ...agentSelectionHintsSchema,
58
+ body: string().optional(),
59
+ setup: setupSchema.optional(),
60
+ projectBinding: projectBindingSchema.optional(),
61
+ runtime: runtimeRequirementsSchema.optional(),
62
+ disabled: boolean().default(false)
63
+ };
64
+ const mcpServerSchema = object({
65
+ ...commonSchema,
66
+ transport: _enum([
67
+ "stdio",
68
+ "http",
69
+ "sse"
70
+ ]).optional(),
71
+ command: string().min(1).optional(),
72
+ args: array(string()).optional(),
73
+ env: stringMapSchema.optional(),
74
+ cwd: string().min(1).optional(),
75
+ url: string().min(1).optional(),
76
+ auth: authSchema.optional(),
77
+ startupTimeoutMs: number().int().positive().default(1e4),
78
+ callTimeoutMs: number().int().positive().default(6e4),
79
+ toolCacheTtlMs: number().int().nonnegative().default(3e4)
80
+ }).strict();
81
+ const openApiEndpointSchema = object({
82
+ ...commonSchema,
83
+ specPath: string().min(1).optional(),
84
+ specUrl: string().min(1).optional(),
85
+ baseUrl: string().min(1).optional(),
86
+ auth: authSchema,
87
+ requestTimeoutMs: number().int().positive().default(6e4),
88
+ operationCacheTtlMs: number().int().nonnegative().default(3e4)
89
+ }).strict();
90
+ const graphQlOperationSchema = object({
91
+ document: string().min(1).optional(),
92
+ documentPath: string().min(1).optional(),
93
+ operationName: string().min(1).optional(),
94
+ description: string().min(1).optional(),
95
+ ...agentSelectionHintsSchema
96
+ }).strict().refine((operation) => Boolean(operation.document) !== Boolean(operation.documentPath), { message: "GraphQL operation must define exactly one document source" });
97
+ const graphQlEndpointSchema = object({
98
+ ...commonSchema,
99
+ endpointUrl: string().min(1),
100
+ schemaPath: string().min(1).optional(),
101
+ schemaUrl: string().min(1).optional(),
102
+ introspection: literal(true).optional(),
103
+ operations: record(string().regex(SERVER_ID_PATTERN), graphQlOperationSchema).optional(),
104
+ auth: authSchema,
105
+ requestTimeoutMs: number().int().positive().default(6e4),
106
+ operationCacheTtlMs: number().int().nonnegative().default(3e4),
107
+ selectionDepth: number().int().positive().max(5).default(2)
108
+ }).strict();
109
+ const scalarMapSchema = record(string(), union([
110
+ string(),
111
+ number(),
112
+ boolean()
113
+ ]));
114
+ const httpActionSchema = object({
115
+ method: _enum([
116
+ "GET",
117
+ "POST",
118
+ "PUT",
119
+ "PATCH",
120
+ "DELETE"
121
+ ]),
122
+ path: string().min(1).regex(/^\//, "HTTP action path must start with /").refine((value) => !value.startsWith("//"), "HTTP action path must not start with //").refine((value) => !isUrl(value), "HTTP action path must be a URL path, not a URL"),
123
+ description: string().min(1).optional(),
124
+ ...agentSelectionHintsSchema,
125
+ inputSchema: record(string(), unknown()).optional(),
126
+ outputSchema: record(string(), unknown()).optional(),
127
+ query: scalarMapSchema.optional(),
128
+ headers: scalarMapSchema.optional(),
129
+ jsonBody: unknown().optional()
130
+ }).strict().refine((action) => action.method !== "GET" || action.jsonBody === void 0, {
131
+ path: ["jsonBody"],
132
+ message: "HTTP GET actions must not define jsonBody"
133
+ });
134
+ const httpApiSchema = object({
135
+ ...commonSchema,
136
+ baseUrl: string().min(1).regex(HTTP_BASE_URL_PATTERN, "HTTP API baseUrl must not include credentials, query, or fragment"),
137
+ auth: authSchema,
138
+ actions: record(string().regex(SERVER_ID_PATTERN), httpActionSchema).refine((actions) => Object.keys(actions).length > 0, "HTTP API must define at least one action"),
139
+ requestTimeoutMs: number().int().positive().default(6e4),
140
+ maxResponseBytes: number().int().positive().default(2e5)
141
+ }).strict();
142
+ const cliActionSchema = object({
143
+ description: string().min(1).optional(),
144
+ ...agentSelectionHintsSchema,
145
+ inputSchema: record(string(), unknown()).optional(),
146
+ outputSchema: record(string(), unknown()).optional(),
147
+ command: string().min(1),
148
+ args: array(string()).optional(),
149
+ env: stringMapSchema.optional(),
150
+ cwd: string().min(1).optional(),
151
+ timeoutMs: number().int().positive().optional(),
152
+ maxOutputBytes: number().int().positive().optional(),
153
+ output: object({ type: _enum(["text", "json"]).default("text") }).strict().optional(),
154
+ annotations: object({
155
+ readOnlyHint: boolean().optional(),
156
+ destructiveHint: boolean().optional(),
157
+ idempotentHint: boolean().optional(),
158
+ openWorldHint: boolean().optional()
159
+ }).strict().optional()
160
+ }).strict();
161
+ const cliToolsSchema = object({
162
+ ...commonSchema,
163
+ actions: record(string().regex(SERVER_ID_PATTERN), cliActionSchema).refine((actions) => Object.keys(actions).length > 0, "CLI tools backend must define at least one action"),
164
+ cwd: string().min(1).optional(),
165
+ env: stringMapSchema.optional(),
166
+ timeoutMs: number().int().positive().default(6e4),
167
+ maxOutputBytes: number().int().positive().default(2e5)
168
+ }).strict();
169
+ const capletSetSchema = object({
170
+ ...commonSchema,
171
+ configPath: string().min(1).optional(),
172
+ capletsRoot: string().min(1).optional(),
173
+ defaultSearchLimit: number().int().positive().default(20),
174
+ maxSearchLimit: number().int().positive().max(50).default(50),
175
+ toolCacheTtlMs: number().int().nonnegative().default(3e4)
176
+ }).strict();
177
+ const configSchema = object({
178
+ version: literal(1).default(1),
179
+ defaultSearchLimit: number().int().positive().default(20),
180
+ maxSearchLimit: number().int().positive().max(50).default(50),
181
+ completion: object({
182
+ discoveryTimeoutMs: number().int().positive().default(750),
183
+ overallTimeoutMs: number().int().positive().default(1500),
184
+ cacheTtlMs: number().int().nonnegative().default(3e5),
185
+ negativeCacheTtlMs: number().int().nonnegative().default(3e4)
186
+ }).strict().default({
187
+ discoveryTimeoutMs: 750,
188
+ overallTimeoutMs: 1500,
189
+ cacheTtlMs: 3e5,
190
+ negativeCacheTtlMs: 3e4
191
+ }),
192
+ options: object({
193
+ exposure: exposureSchema.default("code_mode"),
194
+ exposureDiscoveryTimeoutMs: number().int().positive().default(15e3),
195
+ exposureDiscoveryConcurrency: number().int().positive().max(32).default(4)
196
+ }).strict().default({
197
+ exposure: "code_mode",
198
+ exposureDiscoveryTimeoutMs: 15e3,
199
+ exposureDiscoveryConcurrency: 4
200
+ }),
201
+ mcpServers: record(string().regex(SERVER_ID_PATTERN), mcpServerSchema).default({}),
202
+ openapiEndpoints: record(string().regex(SERVER_ID_PATTERN), openApiEndpointSchema).default({}),
203
+ graphqlEndpoints: record(string().regex(SERVER_ID_PATTERN), graphQlEndpointSchema).default({}),
204
+ httpApis: record(string().regex(SERVER_ID_PATTERN), httpApiSchema).default({}),
205
+ cliTools: record(string().regex(SERVER_ID_PATTERN), cliToolsSchema).default({}),
206
+ capletSets: record(string().regex(SERVER_ID_PATTERN), capletSetSchema).default({})
207
+ }).strict().superRefine((config, ctx) => {
208
+ if (config.defaultSearchLimit > config.maxSearchLimit) ctx.addIssue({
209
+ code: "custom",
210
+ path: ["defaultSearchLimit"],
211
+ message: "defaultSearchLimit must be <= maxSearchLimit"
212
+ });
213
+ validateBackends(config, ctx);
214
+ });
215
+ function parseConfig(input) {
216
+ const parsed = configSchema.safeParse(input);
217
+ if (!parsed.success) throw new CapletsError("CONFIG_INVALID", "Caplets config is invalid", parsed.error.issues);
218
+ const config = parsed.data;
219
+ return {
220
+ version: 1,
221
+ options: {
222
+ defaultSearchLimit: config.defaultSearchLimit,
223
+ maxSearchLimit: config.maxSearchLimit,
224
+ exposure: config.options.exposure,
225
+ exposureDiscoveryTimeoutMs: config.options.exposureDiscoveryTimeoutMs,
226
+ exposureDiscoveryConcurrency: config.options.exposureDiscoveryConcurrency,
227
+ completion: config.completion
228
+ },
229
+ mcpServers: mapBackend(config.mcpServers, "mcp", (id, raw) => {
230
+ const server = raw;
231
+ return {
232
+ ...server,
233
+ server: id,
234
+ transport: server.transport ?? (server.command ? "stdio" : "http")
235
+ };
236
+ }),
237
+ openapiEndpoints: mapBackend(config.openapiEndpoints, "openapi"),
238
+ graphqlEndpoints: mapBackend(config.graphqlEndpoints, "graphql"),
239
+ httpApis: mapBackend(config.httpApis, "http"),
240
+ cliTools: mapBackend(config.cliTools, "cli"),
241
+ capletSets: mapBackend(config.capletSets, "caplets")
242
+ };
243
+ }
244
+ function oauthLikeSchema(type) {
245
+ return object({
246
+ type: literal(type),
247
+ authorizationUrl: string().min(1).optional(),
248
+ tokenUrl: string().min(1).optional(),
249
+ issuer: string().min(1).optional(),
250
+ resourceMetadataUrl: string().min(1).optional(),
251
+ authorizationServerMetadataUrl: string().min(1).optional(),
252
+ openidConfigurationUrl: string().min(1).optional(),
253
+ clientMetadataUrl: string().min(1).optional(),
254
+ clientId: string().min(1).optional(),
255
+ clientSecret: string().min(1).optional(),
256
+ scopes: array(string().min(1)).optional(),
257
+ redirectUri: string().min(1).optional()
258
+ }).strict();
259
+ }
260
+ function validateBackends(config, ctx) {
261
+ for (const [server, raw] of Object.entries(config.mcpServers)) {
262
+ const effectiveTransport = raw.transport ?? (raw.command ? "stdio" : void 0);
263
+ if (Boolean(raw.command) === Boolean(raw.url)) ctx.addIssue({
264
+ code: "custom",
265
+ path: ["mcpServers", server],
266
+ message: "MCP server must define exactly one connection shape: command or url"
267
+ });
268
+ if (effectiveTransport === "stdio" && !raw.command) ctx.addIssue({
269
+ code: "custom",
270
+ path: [
271
+ "mcpServers",
272
+ server,
273
+ "command"
274
+ ],
275
+ message: "stdio servers require command"
276
+ });
277
+ if ((effectiveTransport === "http" || effectiveTransport === "sse") && !raw.url) ctx.addIssue({
278
+ code: "custom",
279
+ path: [
280
+ "mcpServers",
281
+ server,
282
+ "url"
283
+ ],
284
+ message: "remote servers require url"
285
+ });
286
+ if (raw.url && !hasEnvReference(raw.url) && !isAllowedRemoteUrl(raw.url)) ctx.addIssue({
287
+ code: "custom",
288
+ path: [
289
+ "mcpServers",
290
+ server,
291
+ "url"
292
+ ],
293
+ message: "remote url must use https except loopback development urls"
294
+ });
295
+ validateAuthHeaders(raw.auth, ctx, [
296
+ "mcpServers",
297
+ server,
298
+ "auth"
299
+ ]);
300
+ }
301
+ for (const [server, raw] of Object.entries(config.openapiEndpoints)) {
302
+ if (Boolean(raw.specPath) === Boolean(raw.specUrl)) ctx.addIssue({
303
+ code: "custom",
304
+ path: ["openapiEndpoints", server],
305
+ message: "OpenAPI endpoint must define exactly one spec source: specPath or specUrl"
306
+ });
307
+ if (raw.specUrl && !hasEnvReference(raw.specUrl) && !isAllowedRemoteUrl(raw.specUrl)) ctx.addIssue({
308
+ code: "custom",
309
+ path: [
310
+ "openapiEndpoints",
311
+ server,
312
+ "specUrl"
313
+ ],
314
+ message: "OpenAPI specUrl must use https except loopback development urls"
315
+ });
316
+ if (raw.baseUrl && !hasEnvReference(raw.baseUrl) && !isAllowedRemoteUrl(raw.baseUrl)) ctx.addIssue({
317
+ code: "custom",
318
+ path: [
319
+ "openapiEndpoints",
320
+ server,
321
+ "baseUrl"
322
+ ],
323
+ message: "OpenAPI baseUrl must use https except loopback development urls"
324
+ });
325
+ validateAuthHeaders(raw.auth, ctx, [
326
+ "openapiEndpoints",
327
+ server,
328
+ "auth"
329
+ ]);
330
+ }
331
+ for (const [server, raw] of Object.entries(config.graphqlEndpoints)) {
332
+ if (Number(Boolean(raw.schemaPath)) + Number(Boolean(raw.schemaUrl)) + Number(raw.introspection === true) !== 1) ctx.addIssue({
333
+ code: "custom",
334
+ path: ["graphqlEndpoints", server],
335
+ message: "GraphQL endpoint must define exactly one schema source"
336
+ });
337
+ if (raw.endpointUrl && !hasEnvReference(raw.endpointUrl) && !isAllowedRemoteUrl(raw.endpointUrl)) ctx.addIssue({
338
+ code: "custom",
339
+ path: [
340
+ "graphqlEndpoints",
341
+ server,
342
+ "endpointUrl"
343
+ ],
344
+ message: "GraphQL endpointUrl must use https except loopback development urls"
345
+ });
346
+ validateAuthHeaders(raw.auth, ctx, [
347
+ "graphqlEndpoints",
348
+ server,
349
+ "auth"
350
+ ]);
351
+ }
352
+ for (const [server, raw] of Object.entries(config.httpApis)) {
353
+ if (raw.baseUrl && !hasEnvReference(raw.baseUrl) && !isAllowedHttpBaseUrl(raw.baseUrl)) ctx.addIssue({
354
+ code: "custom",
355
+ path: [
356
+ "httpApis",
357
+ server,
358
+ "baseUrl"
359
+ ],
360
+ message: "HTTP API baseUrl must use https except loopback development urls and must not include credentials, query, or fragment"
361
+ });
362
+ validateAuthHeaders(raw.auth, ctx, [
363
+ "httpApis",
364
+ server,
365
+ "auth"
366
+ ]);
367
+ for (const [actionName, action] of Object.entries(raw.actions)) if (action.headers) validateHttpActionHeaders(action.headers, ctx, [
368
+ "httpApis",
369
+ server,
370
+ "actions",
371
+ actionName,
372
+ "headers"
373
+ ]);
374
+ }
375
+ for (const [server, raw] of Object.entries(config.capletSets)) {
376
+ if (!raw.configPath && !raw.capletsRoot) ctx.addIssue({
377
+ code: "custom",
378
+ path: ["capletSets", server],
379
+ message: "Caplet set must define at least one source: configPath or capletsRoot"
380
+ });
381
+ if (raw.defaultSearchLimit > raw.maxSearchLimit) ctx.addIssue({
382
+ code: "custom",
383
+ path: [
384
+ "capletSets",
385
+ server,
386
+ "defaultSearchLimit"
387
+ ],
388
+ message: "defaultSearchLimit must be <= maxSearchLimit"
389
+ });
390
+ }
391
+ }
392
+ function validateAuthHeaders(auth, ctx, path) {
393
+ if (auth?.type !== "headers") return;
394
+ for (const headerName of Object.keys(auth.headers)) {
395
+ const normalized = headerName.toLowerCase();
396
+ if (!HEADER_NAME_PATTERN.test(headerName) || FORBIDDEN_HEADERS.has(normalized)) ctx.addIssue({
397
+ code: "custom",
398
+ path: [
399
+ ...path,
400
+ "headers",
401
+ headerName
402
+ ],
403
+ message: `header ${headerName} is not allowed`
404
+ });
405
+ }
406
+ }
407
+ function mapBackend(records, backend, prepare) {
408
+ return Object.fromEntries(Object.entries(records).map(([id, raw]) => [id, stripUndefined({
409
+ ...prepare ? prepare(id, raw) : raw,
410
+ server: id,
411
+ backend
412
+ })]));
413
+ }
414
+ function stripUndefined(value) {
415
+ return Object.fromEntries(Object.entries(value).filter(([, nested]) => nested !== void 0));
416
+ }
417
+ function hasEnvReference(value) {
418
+ return /\$\{?[A-Z_][A-Z0-9_]*\}?|\$env:[A-Z_][A-Z0-9_]*/u.test(value);
419
+ }
420
+ //#endregion
421
+ export { parseConfig };