@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.
- package/dist/attach/options.d.ts +10 -0
- package/dist/attach/server.d.ts +5 -0
- package/dist/caplet-files-bundle.d.ts +430 -0
- package/dist/caplet-files.d.ts +3 -266
- package/dist/caplet-source/bundle.d.ts +7 -0
- package/dist/caplet-source/filesystem.d.ts +7 -0
- package/dist/caplet-source/filesystem.js +2 -0
- package/dist/caplet-source/index.d.ts +4 -0
- package/dist/caplet-source/parse.d.ts +35 -0
- package/dist/caplet-source/types.d.ts +9 -0
- package/dist/caplet-source.js +7011 -0
- package/dist/cli/auth.d.ts +40 -2
- package/dist/cli/cloud-add.d.ts +8 -0
- package/dist/cli/code-mode.d.ts +16 -0
- package/dist/cli/commands.d.ts +8 -1
- package/dist/cli/doctor.d.ts +21 -0
- package/dist/cli/setup-caplet.d.ts +12 -0
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli-tools.d.ts +1 -1
- package/dist/cli.d.ts +8 -1
- package/dist/cloud/apply.d.ts +36 -0
- package/dist/cloud/client.d.ts +30 -0
- package/dist/cloud/presence.d.ts +29 -0
- package/dist/cloud/project-root.d.ts +2 -0
- package/dist/cloud/runtime-adapter.d.ts +23 -0
- package/dist/cloud/runtime-http.d.ts +6 -0
- package/dist/cloud/sync.d.ts +10 -0
- package/dist/cloud-auth/client.d.ts +57 -0
- package/dist/cloud-auth/errors.d.ts +11 -0
- package/dist/cloud-auth/open-url.d.ts +7 -0
- package/dist/cloud-auth/store.d.ts +35 -0
- package/dist/cloud-auth/types.d.ts +67 -0
- package/dist/code-mode/api.d.ts +32 -0
- package/dist/code-mode/declarations.d.ts +5 -0
- package/dist/code-mode/diagnostics.d.ts +8 -0
- package/dist/code-mode/index.d.ts +4 -0
- package/dist/code-mode/logs.d.ts +21 -0
- package/dist/code-mode/runner.d.ts +15 -0
- package/dist/code-mode/runtime-api.generated.d.ts +1 -0
- package/dist/code-mode/sandbox.d.ts +28 -0
- package/dist/code-mode/static-analysis.d.ts +2 -0
- package/dist/code-mode/tool.d.ts +11 -0
- package/dist/code-mode/types.d.ts +120 -0
- package/dist/code-mode.js +147855 -0
- package/dist/{completion-RqzHpHRY.js → completion-CbazRAiL.js} +20 -1
- package/dist/config/paths.d.ts +2 -0
- package/dist/config-runtime.d.ts +183 -0
- package/dist/config-runtime.js +421 -0
- package/dist/config.d.ts +76 -9
- package/dist/downstream.d.ts +20 -2
- package/dist/engine.d.ts +20 -0
- package/dist/exposure/direct-names.d.ts +9 -0
- package/dist/exposure/discovery.d.ts +75 -0
- package/dist/exposure/policy.d.ts +8 -0
- package/dist/filesystem-Kkg32TOJ.js +66 -0
- package/dist/generated-tool-input-schema.d.ts +89 -59
- package/dist/generated-tool-input-schema.js +172 -1
- package/dist/graphql.d.ts +1 -1
- package/dist/http-actions.d.ts +1 -1
- package/dist/index.d.ts +48 -0
- package/dist/index.js +4176 -501
- package/dist/native/options.d.ts +22 -3
- package/dist/native/remote.d.ts +2 -1
- package/dist/native/service.d.ts +13 -3
- package/dist/native/tools.d.ts +2 -0
- package/dist/native.d.ts +1 -1
- package/dist/native.js +3 -431
- package/dist/observed-output-shapes/extract.d.ts +5 -0
- package/dist/observed-output-shapes/file-store.d.ts +17 -0
- package/dist/observed-output-shapes/index.d.ts +7 -0
- package/dist/observed-output-shapes/key.d.ts +14 -0
- package/dist/observed-output-shapes/merge.d.ts +2 -0
- package/dist/observed-output-shapes/pure.d.ts +5 -0
- package/dist/observed-output-shapes/pure.js +241 -0
- package/dist/observed-output-shapes/schema.d.ts +1 -0
- package/dist/observed-output-shapes/types.d.ts +84 -0
- package/dist/observed-output-shapes/typescript.d.ts +7 -0
- package/dist/observed-output-shapes-uzAMQPhg.js +485 -0
- package/dist/observed-output-shapes.js +2 -0
- package/dist/openapi.d.ts +1 -1
- package/dist/project-binding/attach.d.ts +46 -0
- package/dist/project-binding/errors.d.ts +17 -0
- package/dist/project-binding/gitignore.d.ts +5 -0
- package/dist/project-binding/index.d.ts +2 -0
- package/dist/project-binding/mutagen.d.ts +65 -0
- package/dist/project-binding/routes.d.ts +9 -0
- package/dist/project-binding/session.d.ts +82 -0
- package/dist/project-binding/sync-filter.d.ts +19 -0
- package/dist/project-binding/sync-size.d.ts +27 -0
- package/dist/project-binding/transport.d.ts +21 -0
- package/dist/project-binding/types.d.ts +31 -0
- package/dist/project-binding/workspaces.d.ts +60 -0
- package/dist/project-binding.js +22 -0
- package/dist/redaction.d.ts +14 -0
- package/dist/redaction.js +30 -0
- package/dist/registry.d.ts +4 -0
- package/dist/remote/options.d.ts +44 -0
- package/dist/remote/selection.d.ts +26 -0
- package/dist/remote-control/types.d.ts +1 -1
- package/dist/runtime-plan/features.d.ts +7 -0
- package/dist/runtime-plan/index.d.ts +4 -0
- package/dist/runtime-plan/planner.d.ts +5 -0
- package/dist/runtime-plan/resources.d.ts +13 -0
- package/dist/runtime-plan/types.d.ts +82 -0
- package/dist/runtime-plan.js +281 -0
- package/dist/schemas-1HZ0kFpx.js +4270 -0
- package/dist/{generated-tool-input-schema--kVuUNc5.js → schemas-BZ6BBrh7.js} +1 -161
- package/dist/serve/daemon/config.d.ts +8 -0
- package/dist/serve/daemon/index.d.ts +16 -0
- package/dist/serve/daemon/paths.d.ts +3 -0
- package/dist/serve/daemon/platform-darwin.d.ts +2 -0
- package/dist/serve/daemon/platform-linux.d.ts +2 -0
- package/dist/serve/daemon/platform-windows.d.ts +2 -0
- package/dist/serve/daemon/platform.d.ts +9 -0
- package/dist/serve/daemon/process.d.ts +5 -0
- package/dist/serve/daemon/types.d.ts +86 -0
- package/dist/serve/http.d.ts +8 -0
- package/dist/serve/index.d.ts +5 -1
- package/dist/serve/native-session.d.ts +19 -0
- package/dist/serve/options.d.ts +1 -0
- package/dist/serve/session.d.ts +15 -3
- package/dist/server/options.d.ts +1 -1
- package/dist/{options-DnOUjft1.js → service-D0MwLNyb.js} +38003 -27618
- package/dist/setup/hash.d.ts +3 -0
- package/dist/setup/local-store.d.ts +34 -0
- package/dist/setup/runner.d.ts +40 -0
- package/dist/setup/types.d.ts +52 -0
- package/dist/stable-json.d.ts +3 -0
- package/dist/stable-json.js +26 -0
- package/dist/tools.d.ts +38 -12
- package/dist/validation-CdqbI2zN.js +174 -0
- package/package.json +48 -6
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
//#region src/observed-output-shapes/types.ts
|
|
5
|
+
const OBSERVED_OUTPUT_SHAPE_VERSION = 1;
|
|
6
|
+
const OBSERVED_OUTPUT_SHAPE_LIMITS = {
|
|
7
|
+
maxDepth: 6,
|
|
8
|
+
maxObjectFields: 40,
|
|
9
|
+
maxArrayElements: 20,
|
|
10
|
+
maxUnionVariants: 4,
|
|
11
|
+
maxTypeScriptChars: 4e3,
|
|
12
|
+
maxStoredJsonBytes: 16e3,
|
|
13
|
+
ttlMs: 720 * 60 * 60 * 1e3,
|
|
14
|
+
maxLocalEntries: 2e3
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/stable-json.ts
|
|
18
|
+
function stableJsonValue(value) {
|
|
19
|
+
if (Array.isArray(value)) return value.map((item) => stableJsonValue(item));
|
|
20
|
+
if (isPlainObject$2(value)) {
|
|
21
|
+
const sorted = {};
|
|
22
|
+
for (const key of Object.keys(value).sort()) {
|
|
23
|
+
const item = value[key];
|
|
24
|
+
if (item !== void 0) sorted[key] = stableJsonValue(item);
|
|
25
|
+
}
|
|
26
|
+
return sorted;
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
function stableJsonStringify(value) {
|
|
31
|
+
return JSON.stringify(stableJsonValue(value));
|
|
32
|
+
}
|
|
33
|
+
function isPlainObject$2(value) {
|
|
34
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/schema-hash.ts
|
|
38
|
+
function schemaHash(schema) {
|
|
39
|
+
if (schema === void 0 || schema === null) return null;
|
|
40
|
+
const json = stableJsonStringify(schema);
|
|
41
|
+
return `sha256:${createHash("sha256").update(json).digest("hex")}`;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/observed-output-shapes/key.ts
|
|
45
|
+
function observedOutputShapeStorageKey(key) {
|
|
46
|
+
return stableHash(key);
|
|
47
|
+
}
|
|
48
|
+
function observedOutputShapeKey(input) {
|
|
49
|
+
const toolDescriptorHash = input.toolDescriptor ? stableHash(input.toolDescriptor) : void 0;
|
|
50
|
+
const outputSchemaHash = schemaHash(input.outputSchema) ?? void 0;
|
|
51
|
+
return {
|
|
52
|
+
scope: input.scope,
|
|
53
|
+
...input.workspaceId ? { workspaceId: input.workspaceId } : {},
|
|
54
|
+
...input.projectFingerprint ? { projectFingerprint: input.projectFingerprint } : {},
|
|
55
|
+
capletId: input.caplet.server,
|
|
56
|
+
backendKind: input.caplet.backend,
|
|
57
|
+
backendFingerprint: backendFingerprint(input.caplet),
|
|
58
|
+
toolName: input.toolName,
|
|
59
|
+
...toolDescriptorHash ? { toolDescriptorHash } : {},
|
|
60
|
+
...outputSchemaHash ? { outputSchemaHash } : {},
|
|
61
|
+
resultVersion: 1
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function backendFingerprint(caplet) {
|
|
65
|
+
return stableHash(nonSecretBackendIdentity(caplet));
|
|
66
|
+
}
|
|
67
|
+
function stableHash(value) {
|
|
68
|
+
return createHash("sha256").update(stableJsonStringify(value)).digest("hex");
|
|
69
|
+
}
|
|
70
|
+
function nonSecretBackendIdentity(caplet) {
|
|
71
|
+
switch (caplet.backend) {
|
|
72
|
+
case "mcp": return caplet.transport === "stdio" ? {
|
|
73
|
+
backend: caplet.backend,
|
|
74
|
+
server: caplet.server,
|
|
75
|
+
transport: caplet.transport,
|
|
76
|
+
command: caplet.command,
|
|
77
|
+
args: caplet.args,
|
|
78
|
+
cwd: caplet.cwd
|
|
79
|
+
} : {
|
|
80
|
+
backend: caplet.backend,
|
|
81
|
+
server: caplet.server,
|
|
82
|
+
transport: caplet.transport,
|
|
83
|
+
url: caplet.url
|
|
84
|
+
};
|
|
85
|
+
case "openapi": return {
|
|
86
|
+
backend: caplet.backend,
|
|
87
|
+
server: caplet.server,
|
|
88
|
+
specPath: caplet.specPath,
|
|
89
|
+
specUrl: caplet.specUrl,
|
|
90
|
+
baseUrl: caplet.baseUrl
|
|
91
|
+
};
|
|
92
|
+
case "graphql": return {
|
|
93
|
+
backend: caplet.backend,
|
|
94
|
+
server: caplet.server,
|
|
95
|
+
endpointUrl: caplet.endpointUrl,
|
|
96
|
+
schemaPath: caplet.schemaPath,
|
|
97
|
+
schemaUrl: caplet.schemaUrl,
|
|
98
|
+
introspection: caplet.introspection,
|
|
99
|
+
operations: caplet.operations
|
|
100
|
+
};
|
|
101
|
+
case "http": return {
|
|
102
|
+
backend: caplet.backend,
|
|
103
|
+
server: caplet.server,
|
|
104
|
+
baseUrl: caplet.baseUrl,
|
|
105
|
+
actions: Object.fromEntries(Object.entries(caplet.actions).map(([name, action]) => [name, {
|
|
106
|
+
method: action.method,
|
|
107
|
+
path: action.path,
|
|
108
|
+
query: action.query,
|
|
109
|
+
hasJsonBody: action.jsonBody !== void 0
|
|
110
|
+
}]))
|
|
111
|
+
};
|
|
112
|
+
case "cli": return {
|
|
113
|
+
backend: caplet.backend,
|
|
114
|
+
server: caplet.server,
|
|
115
|
+
cwd: caplet.cwd,
|
|
116
|
+
actions: Object.fromEntries(Object.entries(caplet.actions).map(([name, action]) => [name, {
|
|
117
|
+
command: action.command,
|
|
118
|
+
args: action.args,
|
|
119
|
+
cwd: action.cwd,
|
|
120
|
+
output: action.output
|
|
121
|
+
}]))
|
|
122
|
+
};
|
|
123
|
+
case "caplets": return {
|
|
124
|
+
backend: caplet.backend,
|
|
125
|
+
server: caplet.server,
|
|
126
|
+
configPath: caplet.configPath,
|
|
127
|
+
capletsRoot: caplet.capletsRoot
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region src/observed-output-shapes/file-store.ts
|
|
133
|
+
var FileObservedOutputShapeStore = class {
|
|
134
|
+
cacheDir;
|
|
135
|
+
options;
|
|
136
|
+
constructor(cacheDir, options = {}) {
|
|
137
|
+
this.cacheDir = cacheDir;
|
|
138
|
+
this.options = options;
|
|
139
|
+
}
|
|
140
|
+
async read(key) {
|
|
141
|
+
try {
|
|
142
|
+
const parsed = JSON.parse(readFileSync(this.pathFor(key), "utf8"));
|
|
143
|
+
if (Date.now() > Date.parse(parsed.expiresAt)) return void 0;
|
|
144
|
+
if (!isObservedOutputShape(parsed.shape)) return void 0;
|
|
145
|
+
return parsed.shape;
|
|
146
|
+
} catch {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async write(key, shape) {
|
|
151
|
+
const payload = {
|
|
152
|
+
key,
|
|
153
|
+
shape,
|
|
154
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
155
|
+
expiresAt: new Date(Date.now() + this.ttlMs()).toISOString()
|
|
156
|
+
};
|
|
157
|
+
if (new TextEncoder().encode(JSON.stringify(payload)).byteLength > OBSERVED_OUTPUT_SHAPE_LIMITS.maxStoredJsonBytes) return;
|
|
158
|
+
mkdirSync(this.cacheDir, { recursive: true });
|
|
159
|
+
const path = this.pathFor(key);
|
|
160
|
+
const tempPath = `${path}.${process.pid}.tmp`;
|
|
161
|
+
writeFileSync(tempPath, JSON.stringify(payload), { mode: 384 });
|
|
162
|
+
renameSync(tempPath, path);
|
|
163
|
+
this.prune().catch(() => void 0);
|
|
164
|
+
}
|
|
165
|
+
async prune(now = /* @__PURE__ */ new Date()) {
|
|
166
|
+
if (!existsSync(this.cacheDir)) return {
|
|
167
|
+
removed: 0,
|
|
168
|
+
remaining: 0
|
|
169
|
+
};
|
|
170
|
+
const files = this.entries();
|
|
171
|
+
let removed = 0;
|
|
172
|
+
const live = [];
|
|
173
|
+
for (const file of files) try {
|
|
174
|
+
const parsed = JSON.parse(readFileSync(file.path, "utf8"));
|
|
175
|
+
const expiresAt = Date.parse(parsed.expiresAt);
|
|
176
|
+
if (!Number.isFinite(expiresAt) || now.getTime() > expiresAt || !isObservedOutputShape(parsed.shape)) {
|
|
177
|
+
rmSync(file.path, { force: true });
|
|
178
|
+
removed++;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
live.push({
|
|
182
|
+
path: file.path,
|
|
183
|
+
expiresAt,
|
|
184
|
+
mtimeMs: file.mtimeMs
|
|
185
|
+
});
|
|
186
|
+
} catch {
|
|
187
|
+
rmSync(file.path, { force: true });
|
|
188
|
+
removed++;
|
|
189
|
+
}
|
|
190
|
+
const maxEntries = this.maxEntries();
|
|
191
|
+
const overflow = Math.max(0, live.length - maxEntries);
|
|
192
|
+
if (overflow > 0) for (const entry of live.sort((a, b) => a.mtimeMs - b.mtimeMs).slice(0, overflow)) {
|
|
193
|
+
rmSync(entry.path, { force: true });
|
|
194
|
+
removed++;
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
removed,
|
|
198
|
+
remaining: Math.max(0, live.length - overflow)
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
async health() {
|
|
202
|
+
try {
|
|
203
|
+
mkdirSync(this.cacheDir, { recursive: true });
|
|
204
|
+
const probe = join(this.cacheDir, `.health-${process.pid}.json`);
|
|
205
|
+
writeFileSync(probe, "{}", { mode: 384 });
|
|
206
|
+
rmSync(probe, { force: true });
|
|
207
|
+
const prune = await this.prune();
|
|
208
|
+
return {
|
|
209
|
+
path: this.cacheDir,
|
|
210
|
+
readable: true,
|
|
211
|
+
writable: true,
|
|
212
|
+
entryCount: this.entries().length,
|
|
213
|
+
prune
|
|
214
|
+
};
|
|
215
|
+
} catch (error) {
|
|
216
|
+
return {
|
|
217
|
+
path: this.cacheDir,
|
|
218
|
+
readable: false,
|
|
219
|
+
writable: false,
|
|
220
|
+
error: error instanceof Error ? error.message : String(error)
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
pathFor(key) {
|
|
225
|
+
return join(this.cacheDir, `${observedOutputShapeStorageKey(key)}.json`);
|
|
226
|
+
}
|
|
227
|
+
entries() {
|
|
228
|
+
try {
|
|
229
|
+
return readdirSync(this.cacheDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => {
|
|
230
|
+
const path = join(this.cacheDir, entry.name);
|
|
231
|
+
return {
|
|
232
|
+
path,
|
|
233
|
+
mtimeMs: readMtimeMs(path)
|
|
234
|
+
};
|
|
235
|
+
});
|
|
236
|
+
} catch {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
ttlMs() {
|
|
241
|
+
return this.options.ttlMs ?? OBSERVED_OUTPUT_SHAPE_LIMITS.ttlMs;
|
|
242
|
+
}
|
|
243
|
+
maxEntries() {
|
|
244
|
+
return this.options.maxEntries ?? OBSERVED_OUTPUT_SHAPE_LIMITS.maxLocalEntries;
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
function readMtimeMs(path) {
|
|
248
|
+
try {
|
|
249
|
+
return statSync(path).mtimeMs;
|
|
250
|
+
} catch {
|
|
251
|
+
return 0;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function isObservedOutputShape(value) {
|
|
255
|
+
return Boolean(value && typeof value === "object" && value.version === 1 && value.source === "observed" && typeof value.typeScript === "string" && typeof value.sampleCount === "number");
|
|
256
|
+
}
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/observed-output-shapes/merge.ts
|
|
259
|
+
function mergeJsonShapes(left, right) {
|
|
260
|
+
if (left.kind === "unknown" || right.kind === "unknown") return { kind: "unknown" };
|
|
261
|
+
if (left.kind === right.kind) {
|
|
262
|
+
if (left.kind === "object" && right.kind === "object") return mergeObjects(left, right);
|
|
263
|
+
if (left.kind === "array" && right.kind === "array") return mergeArrays(left, right);
|
|
264
|
+
if (left.kind === "union" && right.kind === "union") return boundedUnion([...left.variants, ...right.variants]);
|
|
265
|
+
return left;
|
|
266
|
+
}
|
|
267
|
+
return boundedUnion([...left.kind === "union" ? left.variants : [left], ...right.kind === "union" ? right.variants : [right]]);
|
|
268
|
+
}
|
|
269
|
+
function mergeObjects(left, right) {
|
|
270
|
+
const fields = {};
|
|
271
|
+
const keys = [...new Set([...Object.keys(left.fields), ...Object.keys(right.fields)])].sort();
|
|
272
|
+
let truncated = left.truncated === true || right.truncated === true;
|
|
273
|
+
const selected = keys.slice(0, OBSERVED_OUTPUT_SHAPE_LIMITS.maxObjectFields);
|
|
274
|
+
truncated = truncated || keys.length > selected.length;
|
|
275
|
+
for (const key of selected) {
|
|
276
|
+
const leftField = left.fields[key];
|
|
277
|
+
const rightField = right.fields[key];
|
|
278
|
+
if (leftField && rightField) fields[key] = {
|
|
279
|
+
optional: true,
|
|
280
|
+
shape: mergeJsonShapes(leftField.shape, rightField.shape)
|
|
281
|
+
};
|
|
282
|
+
else fields[key] = {
|
|
283
|
+
optional: true,
|
|
284
|
+
shape: (leftField ?? rightField).shape
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
kind: "object",
|
|
289
|
+
fields,
|
|
290
|
+
...truncated ? { truncated: true } : {}
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function mergeArrays(left, right) {
|
|
294
|
+
const element = left.element && right.element ? mergeJsonShapes(left.element, right.element) : left.element ?? right.element;
|
|
295
|
+
return {
|
|
296
|
+
kind: "array",
|
|
297
|
+
...element ? { element } : {},
|
|
298
|
+
...left.truncated === true || right.truncated === true ? { truncated: true } : {}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
function boundedUnion(variants) {
|
|
302
|
+
const flattened = variants.flatMap((variant) => variant.kind === "union" ? variant.variants : [variant]);
|
|
303
|
+
const unique = [];
|
|
304
|
+
for (const variant of flattened) {
|
|
305
|
+
if (variant.kind === "unknown") return { kind: "unknown" };
|
|
306
|
+
const key = JSON.stringify(variant);
|
|
307
|
+
if (!unique.some((existing) => JSON.stringify(existing) === key)) unique.push(variant);
|
|
308
|
+
}
|
|
309
|
+
if (unique.length === 1) return unique[0];
|
|
310
|
+
if (unique.length > OBSERVED_OUTPUT_SHAPE_LIMITS.maxUnionVariants) return { kind: "unknown" };
|
|
311
|
+
return {
|
|
312
|
+
kind: "union",
|
|
313
|
+
variants: unique.sort((a, b) => a.kind.localeCompare(b.kind))
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/observed-output-shapes/typescript.ts
|
|
318
|
+
function shapeToTypeScript(shape, typeName = "ObservedOutput", maxChars = OBSERVED_OUTPUT_SHAPE_LIMITS.maxTypeScriptChars) {
|
|
319
|
+
const typeScript = `type ${typeName} = ${shapeType(shape)};`;
|
|
320
|
+
if (typeScript.length <= maxChars) return {
|
|
321
|
+
typeScript,
|
|
322
|
+
truncated: hasTruncatedShape(shape)
|
|
323
|
+
};
|
|
324
|
+
return {
|
|
325
|
+
typeScript: `type ${typeName} = unknown;`,
|
|
326
|
+
truncated: true
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function shapeType(shape) {
|
|
330
|
+
switch (shape.kind) {
|
|
331
|
+
case "null": return "null";
|
|
332
|
+
case "boolean": return "boolean";
|
|
333
|
+
case "number": return "number";
|
|
334
|
+
case "string": return "string";
|
|
335
|
+
case "unknown": return "unknown";
|
|
336
|
+
case "array": return `${shape.element ? wrapArrayElement(shapeType(shape.element)) : "unknown"}[]`;
|
|
337
|
+
case "object": return objectType(shape);
|
|
338
|
+
case "union": return unionType(shape.variants);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function hasTruncatedShape(shape) {
|
|
342
|
+
if ("truncated" in shape && shape.truncated === true) return true;
|
|
343
|
+
if (shape.kind === "array") return shape.element ? hasTruncatedShape(shape.element) : false;
|
|
344
|
+
if (shape.kind === "object") return Object.values(shape.fields).some((field) => hasTruncatedShape(field.shape));
|
|
345
|
+
if (shape.kind === "union") return shape.variants.some((variant) => hasTruncatedShape(variant));
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
function objectType(shape) {
|
|
349
|
+
const entries = Object.entries(shape.fields);
|
|
350
|
+
if (entries.length === 0) return "Record<string, unknown>";
|
|
351
|
+
return `{ ${entries.map(([key, field]) => `${propertyName(key)}?: ${shapeType(field.shape)};`).join(" ")} }`;
|
|
352
|
+
}
|
|
353
|
+
function unionType(variants) {
|
|
354
|
+
const rendered = [...new Set(variants.map((variant) => shapeType(variant)))];
|
|
355
|
+
return rendered.length === 0 ? "unknown" : rendered.join(" | ");
|
|
356
|
+
}
|
|
357
|
+
function wrapArrayElement(value) {
|
|
358
|
+
return value.includes(" | ") ? `(${value})` : value;
|
|
359
|
+
}
|
|
360
|
+
function propertyName(key) {
|
|
361
|
+
return /^[A-Za-z_$][\w$]*$/u.test(key) ? key : JSON.stringify(key);
|
|
362
|
+
}
|
|
363
|
+
//#endregion
|
|
364
|
+
//#region src/observed-output-shapes/extract.ts
|
|
365
|
+
function observeOutputShape(input) {
|
|
366
|
+
const shape = extractJsonShape(input.value);
|
|
367
|
+
if (!shape) return void 0;
|
|
368
|
+
const merged = input.existing ? mergeJsonShapes(input.existing.jsonShape, shape) : shape;
|
|
369
|
+
const emitted = shapeToTypeScript(merged);
|
|
370
|
+
const observed = {
|
|
371
|
+
version: 1,
|
|
372
|
+
source: "observed",
|
|
373
|
+
observedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
374
|
+
sampleCount: (input.existing?.sampleCount ?? 0) + 1,
|
|
375
|
+
typeScript: emitted.typeScript,
|
|
376
|
+
jsonShape: merged,
|
|
377
|
+
truncated: emitted.truncated || hasTruncatedShape(merged)
|
|
378
|
+
};
|
|
379
|
+
return storedBytes(observed) > OBSERVED_OUTPUT_SHAPE_LIMITS.maxStoredJsonBytes ? {
|
|
380
|
+
...observed,
|
|
381
|
+
typeScript: "type ObservedOutput = unknown;",
|
|
382
|
+
jsonShape: { kind: "unknown" },
|
|
383
|
+
truncated: true
|
|
384
|
+
} : observed;
|
|
385
|
+
}
|
|
386
|
+
function extractJsonShape(value) {
|
|
387
|
+
if (!isShapeableJsonRoot(value)) return void 0;
|
|
388
|
+
return shapeFor(value, 0);
|
|
389
|
+
}
|
|
390
|
+
function parseShapeableJsonText(value) {
|
|
391
|
+
if (!isPlainObject$1(value) || !Array.isArray(value.content) || value.content.length !== 1) return;
|
|
392
|
+
const [item] = value.content;
|
|
393
|
+
if (!isPlainObject$1(item) || item.type !== "text" || typeof item.text !== "string") return;
|
|
394
|
+
const text = item.text.trim();
|
|
395
|
+
if (!text || !text.startsWith("{") && !text.startsWith("[")) return void 0;
|
|
396
|
+
try {
|
|
397
|
+
const parsed = JSON.parse(text);
|
|
398
|
+
return isShapeableJsonRoot(parsed) ? parsed : void 0;
|
|
399
|
+
} catch {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
function normalizedObservableValue(result) {
|
|
404
|
+
if (isPlainObject$1(result)) {
|
|
405
|
+
const structured = result.structuredContent;
|
|
406
|
+
if (structured !== void 0) {
|
|
407
|
+
if (isPlainObject$1(structured) && "caplets" in structured && "result" in structured) return isShapeableJsonRoot(structured.result) ? structured.result : void 0;
|
|
408
|
+
return isShapeableJsonRoot(structured) ? structured : void 0;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return parseShapeableJsonText(result);
|
|
412
|
+
}
|
|
413
|
+
function shapeFor(value, depth) {
|
|
414
|
+
if (depth >= OBSERVED_OUTPUT_SHAPE_LIMITS.maxDepth) return { kind: "unknown" };
|
|
415
|
+
if (value === null) return { kind: "null" };
|
|
416
|
+
if (typeof value === "boolean") return { kind: "boolean" };
|
|
417
|
+
if (typeof value === "number") return { kind: "number" };
|
|
418
|
+
if (typeof value === "string") return { kind: "string" };
|
|
419
|
+
if (Array.isArray(value)) return arrayShape(value, depth);
|
|
420
|
+
if (isPlainObject$1(value)) return objectShape(value, depth);
|
|
421
|
+
return { kind: "unknown" };
|
|
422
|
+
}
|
|
423
|
+
function arrayShape(value, depth) {
|
|
424
|
+
const sampled = value.slice(0, OBSERVED_OUTPUT_SHAPE_LIMITS.maxArrayElements);
|
|
425
|
+
let element;
|
|
426
|
+
for (const item of sampled) {
|
|
427
|
+
const itemShape = shapeFor(item, depth + 1);
|
|
428
|
+
element = element ? mergeJsonShapes(element, itemShape) : itemShape;
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
kind: "array",
|
|
432
|
+
...element ? { element } : {},
|
|
433
|
+
...value.length > sampled.length ? { truncated: true } : {}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function objectShape(value, depth) {
|
|
437
|
+
const keys = Object.keys(value).sort();
|
|
438
|
+
const selected = keys.slice(0, OBSERVED_OUTPUT_SHAPE_LIMITS.maxObjectFields);
|
|
439
|
+
const fields = {};
|
|
440
|
+
for (const key of selected) fields[key] = {
|
|
441
|
+
optional: true,
|
|
442
|
+
shape: shapeFor(value[key], depth + 1)
|
|
443
|
+
};
|
|
444
|
+
return {
|
|
445
|
+
kind: "object",
|
|
446
|
+
fields,
|
|
447
|
+
...keys.length > selected.length ? { truncated: true } : {}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function isShapeableJsonRoot(value) {
|
|
451
|
+
return Array.isArray(value) || isPlainObject$1(value);
|
|
452
|
+
}
|
|
453
|
+
function isPlainObject$1(value) {
|
|
454
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
455
|
+
}
|
|
456
|
+
function storedBytes(value) {
|
|
457
|
+
return new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
458
|
+
}
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region src/observed-output-shapes/schema.ts
|
|
461
|
+
function usefulOutputSchema(schema) {
|
|
462
|
+
if (!isPlainObject(schema)) return false;
|
|
463
|
+
if (Object.keys(schema).length === 0) return false;
|
|
464
|
+
if ("const" in schema || Array.isArray(schema.enum)) return true;
|
|
465
|
+
const type = schema.type;
|
|
466
|
+
if (Array.isArray(type)) return type.some((item) => usefulOutputSchema({
|
|
467
|
+
...schema,
|
|
468
|
+
type: item
|
|
469
|
+
}));
|
|
470
|
+
if (type === "object" || isPlainObject(schema.properties)) {
|
|
471
|
+
if (isPlainObject(schema.properties) && Object.keys(schema.properties).length > 0) return true;
|
|
472
|
+
if (schema.additionalProperties === false) return true;
|
|
473
|
+
if (isPlainObject(schema.additionalProperties)) return true;
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
if (type === "array") return usefulOutputSchema(schema.items);
|
|
477
|
+
if (typeof type === "string") return true;
|
|
478
|
+
if (Array.isArray(schema.oneOf) || Array.isArray(schema.anyOf) || Array.isArray(schema.allOf)) return true;
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
function isPlainObject(value) {
|
|
482
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
483
|
+
}
|
|
484
|
+
//#endregion
|
|
485
|
+
export { parseShapeableJsonText as a, shapeType as c, backendFingerprint as d, observedOutputShapeKey as f, OBSERVED_OUTPUT_SHAPE_VERSION as g, OBSERVED_OUTPUT_SHAPE_LIMITS as h, observeOutputShape as i, mergeJsonShapes as l, stableHash as m, extractJsonShape as n, hasTruncatedShape as o, observedOutputShapeStorageKey as p, normalizedObservableValue as r, shapeToTypeScript as s, usefulOutputSchema as t, FileObservedOutputShapeStore as u };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as parseShapeableJsonText, c as shapeType, d as backendFingerprint, f as observedOutputShapeKey, g as OBSERVED_OUTPUT_SHAPE_VERSION, h as OBSERVED_OUTPUT_SHAPE_LIMITS, i as observeOutputShape, l as mergeJsonShapes, m as stableHash, n as extractJsonShape, o as hasTruncatedShape, p as observedOutputShapeStorageKey, r as normalizedObservableValue, s as shapeToTypeScript, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-uzAMQPhg.js";
|
|
2
|
+
export { FileObservedOutputShapeStore, OBSERVED_OUTPUT_SHAPE_LIMITS, OBSERVED_OUTPUT_SHAPE_VERSION, backendFingerprint, extractJsonShape, hasTruncatedShape, mergeJsonShapes, normalizedObservableValue, observeOutputShape, observedOutputShapeKey, observedOutputShapeStorageKey, parseShapeableJsonText, shapeToTypeScript, shapeType, stableHash, usefulOutputSchema };
|
package/dist/openapi.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CompatibilityCallToolResult, Tool } from "@modelcontextprotocol/sdk/types";
|
|
2
2
|
import type { OpenApiEndpointConfig } from "./config";
|
|
3
|
-
import type
|
|
3
|
+
import { type CompactTool } from "./downstream";
|
|
4
4
|
import type { ServerRegistry } from "./registry";
|
|
5
5
|
export declare class OpenApiManager {
|
|
6
6
|
private registry;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ResolvedCapletsRemote } from "../remote/options";
|
|
2
|
+
import { type ProjectBindingSessionEvent } from "./session";
|
|
3
|
+
import type { ProjectBindingWebSocketFactory } from "./transport";
|
|
4
|
+
export type RawAttachOptions = {
|
|
5
|
+
remoteUrl?: string;
|
|
6
|
+
user?: string;
|
|
7
|
+
password?: string;
|
|
8
|
+
token?: string;
|
|
9
|
+
workspace?: string;
|
|
10
|
+
json?: boolean;
|
|
11
|
+
verbose?: boolean;
|
|
12
|
+
once?: boolean;
|
|
13
|
+
projectRoot?: string;
|
|
14
|
+
fetch?: typeof fetch;
|
|
15
|
+
};
|
|
16
|
+
export type ResolvedAttachOptions = {
|
|
17
|
+
projectRoot: string;
|
|
18
|
+
json: boolean;
|
|
19
|
+
verbose: boolean;
|
|
20
|
+
once: boolean;
|
|
21
|
+
remote: ResolvedCapletsRemote;
|
|
22
|
+
authMode: "self_hosted_remote" | "hosted_cloud";
|
|
23
|
+
selectedWorkspace?: string | undefined;
|
|
24
|
+
};
|
|
25
|
+
export declare function resolveAttachOptions(raw?: RawAttachOptions, env?: Record<string, string | undefined>): Promise<ResolvedAttachOptions>;
|
|
26
|
+
export declare function resolveAttachOptionsForRun(raw?: RawAttachOptions, env?: Record<string, string | undefined>): Promise<ResolvedAttachOptions>;
|
|
27
|
+
export declare function attachProjectOnce(raw?: RawAttachOptions, env?: Record<string, string | undefined>): Promise<{
|
|
28
|
+
ok: true;
|
|
29
|
+
projectRoot: string;
|
|
30
|
+
webSocketUrl: string;
|
|
31
|
+
}>;
|
|
32
|
+
export type AttachSessionEvent = ProjectBindingSessionEvent;
|
|
33
|
+
export declare function attachProjectSession(raw?: RawAttachOptions, env?: Record<string, string | undefined>, options?: {
|
|
34
|
+
heartbeatIntervalMs?: number | undefined;
|
|
35
|
+
signal?: AbortSignal | undefined;
|
|
36
|
+
webSocketFactory?: ProjectBindingWebSocketFactory | undefined;
|
|
37
|
+
onEvent?: (event: AttachSessionEvent) => void;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
ok: true;
|
|
40
|
+
bindingId: string;
|
|
41
|
+
sessionId: string;
|
|
42
|
+
projectRoot: string;
|
|
43
|
+
projectFingerprint: string;
|
|
44
|
+
webSocketUrl: string;
|
|
45
|
+
ended: true;
|
|
46
|
+
}>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CapletsError } from "../errors";
|
|
2
|
+
export declare const PROJECT_BINDING_ERROR_CODES: readonly ["cloud_auth_required", "cloud_auth_expired", "cloud_auth_revoked", "workspace_selection_required", "workspace_switch_required", "workspace_forbidden", "project_binding_forbidden", "endpoint_unavailable", "websocket_upgrade_required", "sync_required", "sync_failed", "sync_size_limit_exceeded", "lease_conflict", "lease_expired", "policy_denied", "usage_limit_reached", "billing_required", "subscription_past_due", "email_verification_required", "remote_credentials_required", "remote_auth_failed"];
|
|
3
|
+
export type ProjectBindingErrorCode = (typeof PROJECT_BINDING_ERROR_CODES)[number];
|
|
4
|
+
export type ProjectBindingRecovery = {
|
|
5
|
+
code: ProjectBindingErrorCode;
|
|
6
|
+
message: string;
|
|
7
|
+
recoveryCommand?: string | undefined;
|
|
8
|
+
requestId?: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare class ProjectBindingError extends CapletsError {
|
|
11
|
+
readonly projectBindingCode: ProjectBindingErrorCode;
|
|
12
|
+
readonly recoveryCommand?: string | undefined;
|
|
13
|
+
readonly requestId?: string | undefined;
|
|
14
|
+
constructor(input: ProjectBindingRecovery);
|
|
15
|
+
}
|
|
16
|
+
export declare function projectBindingRecovery(code: ProjectBindingErrorCode, message?: string): ProjectBindingRecovery;
|
|
17
|
+
export declare function projectBindingError(code: ProjectBindingErrorCode, message?: string): ProjectBindingError;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export type ManagedSyncState = "idle" | "starting" | "syncing" | "ready" | "blocked" | "stopped";
|
|
2
|
+
export type ManagedSyncDiagnosticCode = "project_sync_binary_missing" | "project_sync_auth_failed" | "project_sync_conflict" | "project_sync_process_exit" | "project_sync_status_unavailable";
|
|
3
|
+
export type MutagenCommandPlan = {
|
|
4
|
+
command: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
};
|
|
7
|
+
export type MutagenProcessResult = {
|
|
8
|
+
stdout?: string;
|
|
9
|
+
stderr?: string;
|
|
10
|
+
exitCode?: number;
|
|
11
|
+
};
|
|
12
|
+
export type MutagenProcessRunner = (command: string, args: string[]) => Promise<MutagenProcessResult>;
|
|
13
|
+
export type MutagenLastCommandStatus = MutagenCommandPlan & {
|
|
14
|
+
stdout: string;
|
|
15
|
+
stderr: string;
|
|
16
|
+
exitCode?: number;
|
|
17
|
+
};
|
|
18
|
+
export type ManagedSyncStateSnapshot = {
|
|
19
|
+
state: ManagedSyncState;
|
|
20
|
+
publicMessage: string;
|
|
21
|
+
bindingId?: string;
|
|
22
|
+
diagnosticCode?: ManagedSyncDiagnosticCode;
|
|
23
|
+
mutagenBinary?: string;
|
|
24
|
+
mutagenVersion?: string;
|
|
25
|
+
lastCommand?: MutagenLastCommandStatus;
|
|
26
|
+
};
|
|
27
|
+
export type MutagenProjectSyncDoctorData = {
|
|
28
|
+
state: ManagedSyncState;
|
|
29
|
+
diagnosticCode?: ManagedSyncDiagnosticCode;
|
|
30
|
+
mutagenBinary?: string;
|
|
31
|
+
mutagenVersion?: string;
|
|
32
|
+
lastCommand?: MutagenLastCommandStatus;
|
|
33
|
+
};
|
|
34
|
+
export type StartMutagenProjectSyncInput = {
|
|
35
|
+
bindingId: string;
|
|
36
|
+
localProjectRoot: string;
|
|
37
|
+
serverProjectRoot: string;
|
|
38
|
+
};
|
|
39
|
+
export type MutagenProjectSyncBindingInput = {
|
|
40
|
+
bindingId: string;
|
|
41
|
+
};
|
|
42
|
+
export type ManagedMutagenProjectSyncOptions = {
|
|
43
|
+
mutagenBinary?: string;
|
|
44
|
+
runner?: MutagenProcessRunner;
|
|
45
|
+
};
|
|
46
|
+
type MutagenVersionInfo = {
|
|
47
|
+
version: string;
|
|
48
|
+
};
|
|
49
|
+
export declare function planMutagenVersionCommand(mutagenBinary?: string): MutagenCommandPlan;
|
|
50
|
+
export declare function planMutagenSyncCreateCommand(input: StartMutagenProjectSyncInput, mutagenBinary?: string): MutagenCommandPlan;
|
|
51
|
+
export declare function planMutagenSyncListCommand(mutagenBinary?: string): MutagenCommandPlan;
|
|
52
|
+
export declare function planMutagenSyncTerminateCommand(bindingId: string, mutagenBinary?: string): MutagenCommandPlan;
|
|
53
|
+
export declare function mutagenSyncName(bindingId: string): string;
|
|
54
|
+
export declare class ManagedMutagenProjectSync {
|
|
55
|
+
#private;
|
|
56
|
+
readonly mutagenBinary: string;
|
|
57
|
+
constructor(options?: ManagedMutagenProjectSyncOptions);
|
|
58
|
+
start(input: StartMutagenProjectSyncInput): Promise<ManagedSyncStateSnapshot>;
|
|
59
|
+
refresh(input: MutagenProjectSyncBindingInput): Promise<ManagedSyncStateSnapshot>;
|
|
60
|
+
stop(input: MutagenProjectSyncBindingInput): Promise<ManagedSyncStateSnapshot>;
|
|
61
|
+
snapshot(): ManagedSyncStateSnapshot;
|
|
62
|
+
}
|
|
63
|
+
export declare function mutagenProjectSyncDoctorData(snapshot: ManagedSyncStateSnapshot): MutagenProjectSyncDoctorData;
|
|
64
|
+
export declare function parseMutagenVersionOutput(output: string): MutagenVersionInfo;
|
|
65
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PROJECT_BINDING_STATES, type ProjectBindingState } from "./types";
|
|
2
|
+
export { PROJECT_BINDING_STATES };
|
|
3
|
+
export type { ProjectBindingState };
|
|
4
|
+
export declare const PROJECT_BINDINGS_CONTROL_PATH = "/control/project-bindings";
|
|
5
|
+
export declare const PROJECT_BINDING_CONNECT_PATH = "/control/project-bindings/connect";
|
|
6
|
+
export declare function projectBindingConnectPath(): string;
|
|
7
|
+
export declare function projectBindingStatusPath(bindingId: string): string;
|
|
8
|
+
export declare function projectBindingConnectUrl(baseUrl: string | URL): string;
|
|
9
|
+
export declare function projectBindingStatusUrl(baseUrl: string | URL, bindingId: string): string;
|