@execbox/core 0.1.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.
@@ -0,0 +1,456 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
28
+ let ajv = require("ajv");
29
+ ajv = __toESM(ajv);
30
+ let zod = require("zod");
31
+ zod = __toESM(zod);
32
+
33
+ //#region src/identifier.ts
34
+ const RESERVED_WORDS = new Set([
35
+ "await",
36
+ "break",
37
+ "case",
38
+ "catch",
39
+ "class",
40
+ "const",
41
+ "continue",
42
+ "debugger",
43
+ "default",
44
+ "delete",
45
+ "do",
46
+ "else",
47
+ "enum",
48
+ "export",
49
+ "extends",
50
+ "false",
51
+ "finally",
52
+ "for",
53
+ "function",
54
+ "if",
55
+ "import",
56
+ "in",
57
+ "instanceof",
58
+ "new",
59
+ "null",
60
+ "return",
61
+ "super",
62
+ "switch",
63
+ "this",
64
+ "throw",
65
+ "true",
66
+ "try",
67
+ "typeof",
68
+ "var",
69
+ "void",
70
+ "while",
71
+ "with",
72
+ "yield"
73
+ ]);
74
+ /**
75
+ * Returns whether the value is a valid JavaScript identifier.
76
+ */
77
+ function isValidIdentifier(value) {
78
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value);
79
+ }
80
+ /**
81
+ * Returns whether the identifier is reserved in JavaScript source.
82
+ */
83
+ function isReservedWord(value) {
84
+ return RESERVED_WORDS.has(value);
85
+ }
86
+ /**
87
+ * Throws when the value cannot be used as a bare JavaScript identifier.
88
+ */
89
+ function assertValidIdentifier(value, label = "identifier") {
90
+ if (!isValidIdentifier(value) || isReservedWord(value)) throw new Error(`Invalid ${label}: ${value}`);
91
+ }
92
+ /**
93
+ * Converts a raw identifier-like value into a safe JavaScript identifier.
94
+ */
95
+ function sanitizeIdentifier(value) {
96
+ const sanitized = value.trim().replace(/[^A-Za-z0-9_$]+/g, "_").replace(/^_+|_+$/g, "");
97
+ let safeName = sanitized.length > 0 ? sanitized : "_";
98
+ if (/^[0-9]/.test(safeName)) safeName = `_${safeName}`;
99
+ if (isReservedWord(safeName)) safeName = `${safeName}_`;
100
+ return safeName;
101
+ }
102
+ /**
103
+ * Renders the name as a bare identifier when possible, otherwise as a string literal.
104
+ */
105
+ function serializePropertyName(name) {
106
+ return isValidIdentifier(name) ? name : JSON.stringify(name);
107
+ }
108
+
109
+ //#endregion
110
+ //#region src/sanitize.ts
111
+ /**
112
+ * Converts a raw tool name into a safe JavaScript identifier.
113
+ */
114
+ function sanitizeToolName(name) {
115
+ return sanitizeIdentifier(name);
116
+ }
117
+
118
+ //#endregion
119
+ //#region src/errors.ts
120
+ /**
121
+ * Structured failure used internally to propagate executor and tool errors.
122
+ */
123
+ var ExecuteFailure = class extends Error {
124
+ code;
125
+ /**
126
+ * Creates a structured failure with a trusted executor or tool error code.
127
+ */
128
+ constructor(code, message) {
129
+ super(message);
130
+ this.code = code;
131
+ this.name = "ExecuteFailure";
132
+ }
133
+ };
134
+ /**
135
+ * Returns whether a thrown value is an {@link ExecuteFailure}.
136
+ */
137
+ function isExecuteFailure(value) {
138
+ return value instanceof ExecuteFailure;
139
+ }
140
+ /**
141
+ * Returns whether a value can be serialized through the JSON-only host/guest boundary.
142
+ */
143
+ function isJsonSerializable(value, active = /* @__PURE__ */ new Set(), memo = /* @__PURE__ */ new WeakSet()) {
144
+ if (value === null) return true;
145
+ switch (typeof value) {
146
+ case "string":
147
+ case "boolean": return true;
148
+ case "number": return Number.isFinite(value);
149
+ case "bigint":
150
+ case "function":
151
+ case "symbol":
152
+ case "undefined": return false;
153
+ case "object": {
154
+ const objectValue = value;
155
+ if (memo.has(objectValue)) return true;
156
+ if (active.has(objectValue)) return false;
157
+ active.add(objectValue);
158
+ let isSerializable = false;
159
+ try {
160
+ if (Array.isArray(value)) {
161
+ isSerializable = value.every((item) => isJsonSerializable(item, active, memo));
162
+ return isSerializable;
163
+ }
164
+ const prototype = Object.getPrototypeOf(value);
165
+ if (prototype !== Object.prototype && prototype !== null) return false;
166
+ isSerializable = Object.values(value).every((item) => isJsonSerializable(item, active, memo));
167
+ return isSerializable;
168
+ } finally {
169
+ active.delete(objectValue);
170
+ if (isSerializable) memo.add(objectValue);
171
+ }
172
+ }
173
+ }
174
+ return false;
175
+ }
176
+
177
+ //#endregion
178
+ //#region src/schema/normalizeSchema.ts
179
+ const z = "z" in zod && typeof zod.z === "object" ? zod.z : zod;
180
+ const toJsonSchema = ("toJSONSchema" in zod ? zod.toJSONSchema : void 0) ?? ("toJSONSchema" in z ? z.toJSONSchema : void 0);
181
+ function isRecord$1(value) {
182
+ return typeof value === "object" && value !== null;
183
+ }
184
+ function isZodSchema(value) {
185
+ return isRecord$1(value) && typeof value.safeParse === "function";
186
+ }
187
+ function isZodRawShape(value) {
188
+ return isRecord$1(value) && Object.keys(value).length > 0 && Object.values(value).every(isZodSchema);
189
+ }
190
+ function normalizeZodSchema(schema) {
191
+ if (typeof toJsonSchema !== "function") throw new Error("Installed zod package does not expose toJSONSchema");
192
+ const jsonSchema = toJsonSchema(schema);
193
+ if ("$schema" in jsonSchema) {
194
+ const { $schema: _ignored, ...rest } = jsonSchema;
195
+ return rest;
196
+ }
197
+ return jsonSchema;
198
+ }
199
+ /**
200
+ * Normalizes supported tool schema inputs to the JSON Schema form used internally.
201
+ */
202
+ function normalizeToolSchema(schema, phase, toolName) {
203
+ if (schema === void 0) return;
204
+ if (isZodSchema(schema)) return normalizeZodSchema(schema);
205
+ if (isZodRawShape(schema)) return normalizeZodSchema(z.object(schema));
206
+ if (isRecord$1(schema)) return schema;
207
+ throw new Error(`Unsupported ${phase} schema for tool ${toolName}. Expected JSON Schema, a Zod schema, or an MCP-style Zod shape.`);
208
+ }
209
+
210
+ //#endregion
211
+ //#region src/typegen/render.ts
212
+ /**
213
+ * Indents each line of the given string by a specified number of levels.
214
+ */
215
+ function indent(value, level = 1) {
216
+ return value.split("\n").map((line) => `${" ".repeat(level)}${line}`).join("\n");
217
+ }
218
+ /**
219
+ * Renders a short TSDoc-style block when documentation is available.
220
+ */
221
+ function renderDocComment(lines) {
222
+ if (lines.length === 0) return "";
223
+ return [
224
+ "/**",
225
+ ...lines.map((line) => ` * ${line}`),
226
+ " */"
227
+ ].join("\n");
228
+ }
229
+ /**
230
+ * Renders a namespace declaration with optional members.
231
+ */
232
+ function renderNamespaceDeclaration(name, members) {
233
+ if (members.length === 0) return `declare namespace ${name} {}`;
234
+ return `declare namespace ${name} {\n${indent(members.join("\n\n"))}\n}`;
235
+ }
236
+
237
+ //#endregion
238
+ //#region src/typegen/jsonSchema.ts
239
+ function isRecord(value) {
240
+ return typeof value === "object" && value !== null;
241
+ }
242
+ /**
243
+ * Converts a supported JSON Schema fragment into a TypeScript type expression.
244
+ */
245
+ function schemaToType(schema, level = 0) {
246
+ if (!schema) return "unknown";
247
+ if ("allOf" in schema || "anyOf" in schema || "oneOf" in schema || "$ref" in schema || Array.isArray(schema.type)) return "unknown";
248
+ switch (schema.type) {
249
+ case "string": return "string";
250
+ case "number":
251
+ case "integer": return "number";
252
+ case "boolean": return "boolean";
253
+ case "null": return "null";
254
+ case "array": {
255
+ const itemType = schemaToType(isRecord(schema.items) ? schema.items : void 0, level + 1);
256
+ if (isValidIdentifier(itemType)) return `${itemType}[]`;
257
+ return `Array<${itemType}>`;
258
+ }
259
+ case "object": {
260
+ const properties = isRecord(schema.properties) ? schema.properties : {};
261
+ const required = new Set(Array.isArray(schema.required) ? schema.required.filter((value) => typeof value === "string") : []);
262
+ const entries = Object.entries(properties);
263
+ if (entries.length === 0) return "Record<string, unknown>";
264
+ return `{\n${indent(entries.map(([name, propertySchema]) => {
265
+ const propertyType = schemaToType(isRecord(propertySchema) ? propertySchema : void 0, level + 1);
266
+ const optionalToken = required.has(name) ? "" : "?";
267
+ return `${serializePropertyName(name)}${optionalToken}: ${propertyType};`;
268
+ }).join("\n"), level + 1)}\n${" ".repeat(level)}}`;
269
+ }
270
+ default: return "unknown";
271
+ }
272
+ }
273
+ function formatToolDeclaration(name, tool) {
274
+ const lines = [];
275
+ const comment = tool.description ? renderDocComment([tool.description]) : "";
276
+ if (comment) lines.push(comment);
277
+ const inputType = schemaToType(tool.inputSchema);
278
+ const outputType = schemaToType(tool.outputSchema);
279
+ lines.push(`function ${name}(input: ${inputType}): Promise<${outputType}>;`);
280
+ return lines.join("\n");
281
+ }
282
+ /**
283
+ * Generates a namespace declaration for a provider's tool schemas.
284
+ */
285
+ function generateTypesFromJsonSchema(providerName, tools) {
286
+ return renderNamespaceDeclaration(providerName, Object.entries(tools).map(([name, tool]) => formatToolDeclaration(name, tool)));
287
+ }
288
+
289
+ //#endregion
290
+ //#region src/provider/resolveProvider.ts
291
+ const DEFAULT_PROVIDER_NAME = "codemode";
292
+ function assertValidNamespace(name) {
293
+ assertValidIdentifier(name, "provider namespace");
294
+ }
295
+ function compileValidator(ajv$1, schema) {
296
+ return schema ? ajv$1.compile(schema) : void 0;
297
+ }
298
+ function formatValidationMessage(ajv$1, phase, toolName, validator) {
299
+ return `Invalid ${phase} for tool ${toolName}: ${ajv$1.errorsText(validator.errors)}`;
300
+ }
301
+ /**
302
+ * Resolves a tool provider into the validated, sanitized shape consumed by executors.
303
+ */
304
+ function resolveProvider(provider) {
305
+ const name = provider.name ?? DEFAULT_PROVIDER_NAME;
306
+ assertValidNamespace(name);
307
+ const ajv$1 = new ajv.default({
308
+ allErrors: true,
309
+ strict: false
310
+ });
311
+ const originalToSafeName = {};
312
+ const safeToOriginalName = {};
313
+ const usedSafeNames = /* @__PURE__ */ new Set();
314
+ const resolvedTools = {};
315
+ const typegenTools = {};
316
+ for (const [originalName, descriptor] of Object.entries(provider.tools)) {
317
+ const baseSafeName = sanitizeToolName(originalName);
318
+ let safeName = baseSafeName;
319
+ let suffix = 2;
320
+ while (usedSafeNames.has(safeName)) {
321
+ safeName = `${baseSafeName}__${suffix}`;
322
+ suffix += 1;
323
+ }
324
+ usedSafeNames.add(safeName);
325
+ originalToSafeName[originalName] = safeName;
326
+ safeToOriginalName[safeName] = originalName;
327
+ const inputSchema = normalizeToolSchema(descriptor.inputSchema, "input", originalName);
328
+ const outputSchema = normalizeToolSchema(descriptor.outputSchema, "output", originalName);
329
+ const inputValidator = compileValidator(ajv$1, inputSchema);
330
+ const outputValidator = compileValidator(ajv$1, outputSchema);
331
+ resolvedTools[safeName] = {
332
+ description: descriptor.description,
333
+ execute: async (input, context) => {
334
+ if (inputValidator && !inputValidator(input)) throw new ExecuteFailure("validation_error", formatValidationMessage(ajv$1, "input", originalName, inputValidator));
335
+ try {
336
+ const result = await descriptor.execute(input, context);
337
+ if (!isJsonSerializable(result)) throw new ExecuteFailure("serialization_error", `Tool ${originalName} returned a non-serializable value`);
338
+ if (outputValidator && !outputValidator(result)) throw new ExecuteFailure("validation_error", formatValidationMessage(ajv$1, "output", originalName, outputValidator));
339
+ return result;
340
+ } catch (error) {
341
+ if (isExecuteFailure(error)) throw error;
342
+ throw new ExecuteFailure("tool_error", error instanceof Error ? error.message : `Tool ${originalName} failed`);
343
+ }
344
+ },
345
+ inputSchema,
346
+ originalName,
347
+ outputSchema,
348
+ safeName
349
+ };
350
+ typegenTools[safeName] = {
351
+ description: descriptor.description,
352
+ inputSchema,
353
+ outputSchema
354
+ };
355
+ }
356
+ return {
357
+ name,
358
+ originalToSafeName,
359
+ safeToOriginalName,
360
+ tools: resolvedTools,
361
+ types: provider.types ?? generateTypesFromJsonSchema(name, typegenTools)
362
+ };
363
+ }
364
+
365
+ //#endregion
366
+ Object.defineProperty(exports, 'ExecuteFailure', {
367
+ enumerable: true,
368
+ get: function () {
369
+ return ExecuteFailure;
370
+ }
371
+ });
372
+ Object.defineProperty(exports, '__toESM', {
373
+ enumerable: true,
374
+ get: function () {
375
+ return __toESM;
376
+ }
377
+ });
378
+ Object.defineProperty(exports, 'assertValidIdentifier', {
379
+ enumerable: true,
380
+ get: function () {
381
+ return assertValidIdentifier;
382
+ }
383
+ });
384
+ Object.defineProperty(exports, 'generateTypesFromJsonSchema', {
385
+ enumerable: true,
386
+ get: function () {
387
+ return generateTypesFromJsonSchema;
388
+ }
389
+ });
390
+ Object.defineProperty(exports, 'isExecuteFailure', {
391
+ enumerable: true,
392
+ get: function () {
393
+ return isExecuteFailure;
394
+ }
395
+ });
396
+ Object.defineProperty(exports, 'isJsonSerializable', {
397
+ enumerable: true,
398
+ get: function () {
399
+ return isJsonSerializable;
400
+ }
401
+ });
402
+ Object.defineProperty(exports, 'isReservedWord', {
403
+ enumerable: true,
404
+ get: function () {
405
+ return isReservedWord;
406
+ }
407
+ });
408
+ Object.defineProperty(exports, 'isValidIdentifier', {
409
+ enumerable: true,
410
+ get: function () {
411
+ return isValidIdentifier;
412
+ }
413
+ });
414
+ Object.defineProperty(exports, 'renderDocComment', {
415
+ enumerable: true,
416
+ get: function () {
417
+ return renderDocComment;
418
+ }
419
+ });
420
+ Object.defineProperty(exports, 'renderNamespaceDeclaration', {
421
+ enumerable: true,
422
+ get: function () {
423
+ return renderNamespaceDeclaration;
424
+ }
425
+ });
426
+ Object.defineProperty(exports, 'resolveProvider', {
427
+ enumerable: true,
428
+ get: function () {
429
+ return resolveProvider;
430
+ }
431
+ });
432
+ Object.defineProperty(exports, 'sanitizeIdentifier', {
433
+ enumerable: true,
434
+ get: function () {
435
+ return sanitizeIdentifier;
436
+ }
437
+ });
438
+ Object.defineProperty(exports, 'sanitizeToolName', {
439
+ enumerable: true,
440
+ get: function () {
441
+ return sanitizeToolName;
442
+ }
443
+ });
444
+ Object.defineProperty(exports, 'schemaToType', {
445
+ enumerable: true,
446
+ get: function () {
447
+ return schemaToType;
448
+ }
449
+ });
450
+ Object.defineProperty(exports, 'serializePropertyName', {
451
+ enumerable: true,
452
+ get: function () {
453
+ return serializePropertyName;
454
+ }
455
+ });
456
+ //# sourceMappingURL=resolveProvider-CixOjPKp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProvider-CixOjPKp.cjs","names":["isRecord","lines: string[]","ajv","Ajv","originalToSafeName: Record<string, string>","safeToOriginalName: Record<string, string>","resolvedTools: Record<string, ResolvedToolDescriptor>","typegenTools: Record<string, TypegenToolDescriptor>"],"sources":["../src/identifier.ts","../src/sanitize.ts","../src/errors.ts","../src/schema/normalizeSchema.ts","../src/typegen/render.ts","../src/typegen/jsonSchema.ts","../src/provider/resolveProvider.ts"],"sourcesContent":["const RESERVED_WORDS = new Set([\n \"await\",\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"enum\",\n \"export\",\n \"extends\",\n \"false\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"new\",\n \"null\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"true\",\n \"try\",\n \"typeof\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n]);\n\n/**\n * Returns whether the value is a valid JavaScript identifier.\n */\nexport function isValidIdentifier(value: string): boolean {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value);\n}\n\n/**\n * Returns whether the identifier is reserved in JavaScript source.\n */\nexport function isReservedWord(value: string): boolean {\n return RESERVED_WORDS.has(value);\n}\n\n/**\n * Throws when the value cannot be used as a bare JavaScript identifier.\n */\nexport function assertValidIdentifier(\n value: string,\n label = \"identifier\",\n): void {\n if (!isValidIdentifier(value) || isReservedWord(value)) {\n throw new Error(`Invalid ${label}: ${value}`);\n }\n}\n\n/**\n * Converts a raw identifier-like value into a safe JavaScript identifier.\n */\nexport function sanitizeIdentifier(value: string): string {\n const sanitized = value\n .trim()\n .replace(/[^A-Za-z0-9_$]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n\n let safeName = sanitized.length > 0 ? sanitized : \"_\";\n\n if (/^[0-9]/.test(safeName)) {\n safeName = `_${safeName}`;\n }\n\n if (isReservedWord(safeName)) {\n safeName = `${safeName}_`;\n }\n\n return safeName;\n}\n\n/**\n * Renders the name as a bare identifier when possible, otherwise as a string literal.\n */\nexport function serializePropertyName(name: string): string {\n return isValidIdentifier(name) ? name : JSON.stringify(name);\n}\n","import { sanitizeIdentifier } from \"./identifier\";\n\n/**\n * Converts a raw tool name into a safe JavaScript identifier.\n */\nexport function sanitizeToolName(name: string): string {\n return sanitizeIdentifier(name);\n}\n","import type { ExecuteErrorCode } from \"./types\";\n\n/**\n * Structured failure used internally to propagate executor and tool errors.\n */\nexport class ExecuteFailure extends Error {\n code: ExecuteErrorCode;\n\n /**\n * Creates a structured failure with a trusted executor or tool error code.\n */\n constructor(code: ExecuteErrorCode, message: string) {\n super(message);\n this.code = code;\n this.name = \"ExecuteFailure\";\n }\n}\n\n/**\n * Returns whether a thrown value is an {@link ExecuteFailure}.\n */\nexport function isExecuteFailure(value: unknown): value is ExecuteFailure {\n return value instanceof ExecuteFailure;\n}\n\n/**\n * Returns whether a value can be serialized through the JSON-only host/guest boundary.\n */\nexport function isJsonSerializable(\n value: unknown,\n active = new Set<object>(),\n memo = new WeakSet<object>(),\n): boolean {\n if (value === null) {\n return true;\n }\n\n switch (typeof value) {\n case \"string\":\n case \"boolean\":\n return true;\n case \"number\":\n return Number.isFinite(value);\n case \"bigint\":\n case \"function\":\n case \"symbol\":\n case \"undefined\":\n return false;\n case \"object\": {\n const objectValue = value as object;\n\n if (memo.has(objectValue)) {\n return true;\n }\n\n if (active.has(objectValue)) {\n return false;\n }\n\n active.add(objectValue);\n let isSerializable = false;\n\n try {\n if (Array.isArray(value)) {\n isSerializable = value.every((item) =>\n isJsonSerializable(item, active, memo),\n );\n return isSerializable;\n }\n\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n return false;\n }\n\n isSerializable = Object.values(value).every((item) =>\n isJsonSerializable(item, active, memo),\n );\n return isSerializable;\n } finally {\n active.delete(objectValue);\n if (isSerializable) {\n memo.add(objectValue);\n }\n }\n }\n }\n\n return false;\n}\n","import * as zod from \"zod\";\nimport type { ZodRawShape, ZodTypeAny } from \"zod\";\n\nimport type { JsonSchema, ToolSchema } from \"../types\";\n\nconst z = \"z\" in zod && typeof zod.z === \"object\" ? zod.z : zod;\nconst toJsonSchema =\n (\"toJSONSchema\" in zod ? zod.toJSONSchema : undefined) ??\n (\"toJSONSchema\" in z ? z.toJSONSchema : undefined);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isZodSchema(value: unknown): value is ZodTypeAny {\n return isRecord(value) && typeof value.safeParse === \"function\";\n}\n\nfunction isZodRawShape(value: unknown): value is ZodRawShape {\n return (\n isRecord(value) &&\n Object.keys(value).length > 0 &&\n Object.values(value).every(isZodSchema)\n );\n}\n\nfunction normalizeZodSchema(schema: ZodTypeAny): JsonSchema {\n if (typeof toJsonSchema !== \"function\") {\n throw new Error(\"Installed zod package does not expose toJSONSchema\");\n }\n\n const jsonSchema = toJsonSchema(schema) as JsonSchema & {\n $schema?: string;\n };\n\n if (\"$schema\" in jsonSchema) {\n const { $schema: _ignored, ...rest } = jsonSchema;\n return rest;\n }\n\n return jsonSchema;\n}\n\n/**\n * Normalizes supported tool schema inputs to the JSON Schema form used internally.\n */\nexport function normalizeToolSchema(\n schema: ToolSchema | undefined,\n phase: \"input\" | \"output\",\n toolName: string,\n): JsonSchema | undefined {\n if (schema === undefined) {\n return undefined;\n }\n\n if (isZodSchema(schema)) {\n return normalizeZodSchema(schema);\n }\n\n if (isZodRawShape(schema)) {\n return normalizeZodSchema(z.object(schema));\n }\n\n if (isRecord(schema)) {\n return schema;\n }\n\n throw new Error(\n `Unsupported ${phase} schema for tool ${toolName}. Expected JSON Schema, a Zod schema, or an MCP-style Zod shape.`,\n );\n}\n","/**\n * Indents each line of the given string by a specified number of levels.\n */\nexport function indent(value: string, level = 1): string {\n return value\n .split(\"\\n\")\n .map((line) => `${\" \".repeat(level)}${line}`)\n .join(\"\\n\");\n}\n\n/**\n * Renders a short TSDoc-style block when documentation is available.\n */\nexport function renderDocComment(lines: string[]): string {\n if (lines.length === 0) {\n return \"\";\n }\n\n return [\"/**\", ...lines.map((line) => ` * ${line}`), \" */\"].join(\"\\n\");\n}\n\n/**\n * Renders a namespace declaration with optional members.\n */\nexport function renderNamespaceDeclaration(\n name: string,\n members: string[],\n): string {\n if (members.length === 0) {\n return `declare namespace ${name} {}`;\n }\n\n return `declare namespace ${name} {\\n${indent(members.join(\"\\n\\n\"))}\\n}`;\n}\n","import { isValidIdentifier, serializePropertyName } from \"../identifier\";\nimport type { JsonSchema, TypegenToolDescriptor } from \"../types\";\nimport { indent, renderDocComment, renderNamespaceDeclaration } from \"./render\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport { indent } from \"./render\";\n\n/**\n * Converts a supported JSON Schema fragment into a TypeScript type expression.\n */\nexport function schemaToType(\n schema: JsonSchema | undefined,\n level = 0,\n): string {\n if (!schema) {\n return \"unknown\";\n }\n\n if (\n \"allOf\" in schema ||\n \"anyOf\" in schema ||\n \"oneOf\" in schema ||\n \"$ref\" in schema ||\n Array.isArray(schema.type)\n ) {\n return \"unknown\";\n }\n\n switch (schema.type) {\n case \"string\":\n return \"string\";\n case \"number\":\n case \"integer\":\n return \"number\";\n case \"boolean\":\n return \"boolean\";\n case \"null\":\n return \"null\";\n case \"array\": {\n const itemType = schemaToType(\n isRecord(schema.items) ? (schema.items as JsonSchema) : undefined,\n level + 1,\n );\n\n if (isValidIdentifier(itemType)) {\n return `${itemType}[]`;\n }\n\n return `Array<${itemType}>`;\n }\n case \"object\": {\n const properties = isRecord(schema.properties) ? schema.properties : {};\n const required = new Set(\n Array.isArray(schema.required)\n ? schema.required.filter(\n (value): value is string => typeof value === \"string\",\n )\n : [],\n );\n const entries = Object.entries(properties);\n\n if (entries.length === 0) {\n return \"Record<string, unknown>\";\n }\n\n const lines = entries.map(([name, propertySchema]) => {\n const propertyType = schemaToType(\n isRecord(propertySchema) ? (propertySchema as JsonSchema) : undefined,\n level + 1,\n );\n const optionalToken = required.has(name) ? \"\" : \"?\";\n return `${serializePropertyName(name)}${optionalToken}: ${propertyType};`;\n });\n\n return `{\\n${indent(lines.join(\"\\n\"), level + 1)}\\n${\" \".repeat(level)}}`;\n }\n default:\n return \"unknown\";\n }\n}\n\nfunction formatToolDeclaration(\n name: string,\n tool: TypegenToolDescriptor,\n): string {\n const lines: string[] = [];\n const comment = tool.description ? renderDocComment([tool.description]) : \"\";\n if (comment) {\n lines.push(comment);\n }\n\n const inputType = schemaToType(tool.inputSchema);\n const outputType = schemaToType(tool.outputSchema);\n lines.push(`function ${name}(input: ${inputType}): Promise<${outputType}>;`);\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generates a namespace declaration for a provider's tool schemas.\n */\nexport function generateTypesFromJsonSchema(\n providerName: string,\n tools: Record<string, TypegenToolDescriptor>,\n): string {\n return renderNamespaceDeclaration(\n providerName,\n Object.entries(tools).map(([name, tool]) =>\n formatToolDeclaration(name, tool),\n ),\n );\n}\n","import Ajv, { type AnySchemaObject, type ValidateFunction } from \"ajv\";\n\nimport {\n ExecuteFailure,\n isExecuteFailure,\n isJsonSerializable,\n} from \"../errors\";\nimport { assertValidIdentifier } from \"../identifier\";\nimport { sanitizeToolName } from \"../sanitize\";\nimport { normalizeToolSchema } from \"../schema/normalizeSchema\";\nimport { generateTypesFromJsonSchema } from \"../typegen/jsonSchema\";\nimport type {\n JsonSchema,\n ResolvedToolDescriptor,\n ResolvedToolProvider,\n ToolExecutionContext,\n ToolProvider,\n TypegenToolDescriptor,\n} from \"../types\";\n\nconst DEFAULT_PROVIDER_NAME = \"codemode\";\nfunction assertValidNamespace(name: string): void {\n assertValidIdentifier(name, \"provider namespace\");\n}\n\nfunction compileValidator(\n ajv: Ajv,\n schema: JsonSchema | undefined,\n): ValidateFunction | undefined {\n return schema ? ajv.compile(schema as AnySchemaObject) : undefined;\n}\n\nfunction formatValidationMessage(\n ajv: Ajv,\n phase: \"input\" | \"output\",\n toolName: string,\n validator: ValidateFunction,\n): string {\n return `Invalid ${phase} for tool ${toolName}: ${ajv.errorsText(validator.errors)}`;\n}\n\n/**\n * Resolves a tool provider into the validated, sanitized shape consumed by executors.\n */\nexport function resolveProvider(provider: ToolProvider): ResolvedToolProvider {\n const name = provider.name ?? DEFAULT_PROVIDER_NAME;\n assertValidNamespace(name);\n\n const ajv = new Ajv({\n allErrors: true,\n strict: false,\n });\n\n const originalToSafeName: Record<string, string> = {};\n const safeToOriginalName: Record<string, string> = {};\n const usedSafeNames = new Set<string>();\n const resolvedTools: Record<string, ResolvedToolDescriptor> = {};\n const typegenTools: Record<string, TypegenToolDescriptor> = {};\n\n for (const [originalName, descriptor] of Object.entries(provider.tools)) {\n const baseSafeName = sanitizeToolName(originalName);\n let safeName = baseSafeName;\n let suffix = 2;\n\n while (usedSafeNames.has(safeName)) {\n safeName = `${baseSafeName}__${suffix}`;\n suffix += 1;\n }\n\n usedSafeNames.add(safeName);\n originalToSafeName[originalName] = safeName;\n safeToOriginalName[safeName] = originalName;\n\n const inputSchema = normalizeToolSchema(\n descriptor.inputSchema,\n \"input\",\n originalName,\n );\n const outputSchema = normalizeToolSchema(\n descriptor.outputSchema,\n \"output\",\n originalName,\n );\n const inputValidator = compileValidator(ajv, inputSchema);\n const outputValidator = compileValidator(ajv, outputSchema);\n\n resolvedTools[safeName] = {\n description: descriptor.description,\n execute: async (\n input: unknown,\n context: ToolExecutionContext,\n ): Promise<unknown> => {\n if (inputValidator && !inputValidator(input)) {\n throw new ExecuteFailure(\n \"validation_error\",\n formatValidationMessage(ajv, \"input\", originalName, inputValidator),\n );\n }\n\n try {\n const result = await descriptor.execute(input, context);\n\n if (!isJsonSerializable(result)) {\n throw new ExecuteFailure(\n \"serialization_error\",\n `Tool ${originalName} returned a non-serializable value`,\n );\n }\n\n if (outputValidator && !outputValidator(result)) {\n throw new ExecuteFailure(\n \"validation_error\",\n formatValidationMessage(\n ajv,\n \"output\",\n originalName,\n outputValidator,\n ),\n );\n }\n\n return result;\n } catch (error) {\n if (isExecuteFailure(error)) {\n throw error;\n }\n\n throw new ExecuteFailure(\n \"tool_error\",\n error instanceof Error\n ? error.message\n : `Tool ${originalName} failed`,\n );\n }\n },\n inputSchema,\n originalName,\n outputSchema,\n safeName,\n };\n\n typegenTools[safeName] = {\n description: descriptor.description,\n inputSchema,\n outputSchema,\n };\n }\n\n return {\n name,\n originalToSafeName,\n safeToOriginalName,\n tools: resolvedTools,\n types: provider.types ?? generateTypesFromJsonSchema(name, typegenTools),\n };\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@execbox/core",
3
+ "version": "0.1.0",
4
+ "description": "Core execution contract, provider resolution, and MCP adapters.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=22"
9
+ },
10
+ "main": "./dist/index.cjs",
11
+ "module": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "require": "./dist/index.cjs"
18
+ },
19
+ "./mcp": {
20
+ "types": "./dist/mcp/index.d.ts",
21
+ "import": "./dist/mcp/index.js",
22
+ "require": "./dist/mcp/index.cjs"
23
+ }
24
+ },
25
+ "sideEffects": false,
26
+ "files": [
27
+ "dist",
28
+ "README.md",
29
+ "LICENSE"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsdown"
33
+ },
34
+ "keywords": [
35
+ "mcp",
36
+ "model-context-protocol",
37
+ "sandbox",
38
+ "code-execution",
39
+ "tools"
40
+ ],
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/aallam/execbox.git",
44
+ "directory": "packages/core"
45
+ },
46
+ "homepage": "https://github.com/aallam/execbox/tree/main/packages/core#readme",
47
+ "bugs": "https://github.com/aallam/execbox/issues",
48
+ "dependencies": {
49
+ "@modelcontextprotocol/sdk": "^1.28.0",
50
+ "acorn": "^8.15.0",
51
+ "ajv": "^8.17.1",
52
+ "zod": "^4.3.6"
53
+ }
54
+ }