@papicandela/mcx-core 0.1.0 → 0.2.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,172 @@
1
+ /**
2
+ * Type Generator for MCX Adapters
3
+ *
4
+ * Generates TypeScript type declarations from adapter definitions.
5
+ * Used to provide LLM context with minimal tokens (Cloudflare pattern).
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const types = generateTypes(adapters, { includeDescriptions: true });
10
+ * // Output:
11
+ * // declare const myAdapter: {
12
+ * // getData(params: { id: string }): Promise<unknown>;
13
+ * // }
14
+ * ```
15
+ */
16
+
17
+ import type { Adapter, ParameterDefinition } from "./types.js";
18
+
19
+ /**
20
+ * Options for type generation
21
+ */
22
+ export interface TypeGeneratorOptions {
23
+ /** Include JSDoc descriptions in output (default: true) */
24
+ includeDescriptions?: boolean;
25
+ /** Use async return types (default: true) */
26
+ asyncResults?: boolean;
27
+ /** Namespace prefix for declarations (default: none) */
28
+ namespace?: string;
29
+ }
30
+
31
+ /**
32
+ * Generate TypeScript type declarations from adapters.
33
+ *
34
+ * @param adapters - Array of adapters to generate types for
35
+ * @param options - Generation options
36
+ * @returns TypeScript declaration string
37
+ */
38
+ export function generateTypes(
39
+ adapters: Adapter[],
40
+ options: TypeGeneratorOptions = {}
41
+ ): string {
42
+ const { includeDescriptions = true, asyncResults = true } = options;
43
+ const lines: string[] = [];
44
+
45
+ for (const adapter of adapters) {
46
+ const safeName = sanitizeIdentifier(adapter.name);
47
+
48
+ // Generate input interface for each tool with parameters
49
+ for (const [toolName, tool] of Object.entries(adapter.tools)) {
50
+ if (tool.parameters && Object.keys(tool.parameters).length > 0) {
51
+ const inputTypeName = `${capitalize(safeName)}_${capitalize(toolName)}_Input`;
52
+ lines.push(generateInputInterface(inputTypeName, tool.parameters, includeDescriptions));
53
+ lines.push("");
54
+ }
55
+ }
56
+
57
+ // Generate adapter declaration
58
+ if (includeDescriptions && adapter.description) {
59
+ lines.push(`/** ${adapter.description} */`);
60
+ }
61
+ lines.push(`declare const ${safeName}: {`);
62
+
63
+ for (const [toolName, tool] of Object.entries(adapter.tools)) {
64
+ const safeToolName = sanitizeIdentifier(toolName);
65
+ const hasParams = tool.parameters && Object.keys(tool.parameters).length > 0;
66
+ const inputTypeName = `${capitalize(safeName)}_${capitalize(toolName)}_Input`;
67
+
68
+ if (includeDescriptions && tool.description) {
69
+ lines.push(` /** ${tool.description} */`);
70
+ }
71
+
72
+ const paramStr = hasParams ? `params: ${inputTypeName}` : "";
73
+ const returnType = asyncResults ? "Promise<unknown>" : "unknown";
74
+ lines.push(` ${safeToolName}(${paramStr}): ${returnType};`);
75
+ }
76
+
77
+ lines.push("};");
78
+ lines.push("");
79
+ }
80
+
81
+ return lines.join("\n").trim();
82
+ }
83
+
84
+ /**
85
+ * Generate a compact type summary for token-constrained contexts.
86
+ * Returns a condensed one-liner per adapter.
87
+ *
88
+ * @param adapters - Array of adapters
89
+ * @returns Compact summary string
90
+ */
91
+ export function generateTypesSummary(adapters: Adapter[]): string {
92
+ return adapters
93
+ .map((adapter) => {
94
+ const methods = Object.keys(adapter.tools).join(", ");
95
+ return `${adapter.name}: { ${methods} }`;
96
+ })
97
+ .join("\n");
98
+ }
99
+
100
+ /**
101
+ * Generate input interface for a tool's parameters
102
+ */
103
+ function generateInputInterface(
104
+ typeName: string,
105
+ parameters: Record<string, ParameterDefinition>,
106
+ includeDescriptions: boolean
107
+ ): string {
108
+ const lines: string[] = [`interface ${typeName} {`];
109
+
110
+ for (const [paramName, param] of Object.entries(parameters)) {
111
+ if (includeDescriptions && param.description) {
112
+ lines.push(` /** ${param.description} */`);
113
+ }
114
+
115
+ const tsType = paramTypeToTS(param.type);
116
+ const optional = param.required === false ? "?" : "";
117
+ lines.push(` ${paramName}${optional}: ${tsType};`);
118
+ }
119
+
120
+ lines.push("}");
121
+ return lines.join("\n");
122
+ }
123
+
124
+ /**
125
+ * Convert parameter type to TypeScript type
126
+ */
127
+ function paramTypeToTS(type: string): string {
128
+ const typeMap: Record<string, string> = {
129
+ string: "string",
130
+ number: "number",
131
+ boolean: "boolean",
132
+ object: "Record<string, unknown>",
133
+ array: "unknown[]",
134
+ };
135
+ return typeMap[type] || "unknown";
136
+ }
137
+
138
+ /**
139
+ * Sanitize a string to be a valid JavaScript identifier
140
+ */
141
+ export function sanitizeIdentifier(name: string): string {
142
+ // Replace invalid characters with underscores
143
+ let safe = name.replace(/[^a-zA-Z0-9_$]/g, "_");
144
+
145
+ // Prefix with underscore if starts with number
146
+ if (/^[0-9]/.test(safe)) {
147
+ safe = "_" + safe;
148
+ }
149
+
150
+ // Handle reserved words
151
+ const reserved = [
152
+ "break", "case", "catch", "continue", "debugger", "default", "delete",
153
+ "do", "else", "finally", "for", "function", "if", "in", "instanceof",
154
+ "new", "return", "switch", "this", "throw", "try", "typeof", "var",
155
+ "void", "while", "with", "class", "const", "enum", "export", "extends",
156
+ "import", "super", "implements", "interface", "let", "package", "private",
157
+ "protected", "public", "static", "yield",
158
+ ];
159
+
160
+ if (reserved.includes(safe)) {
161
+ safe = safe + "_";
162
+ }
163
+
164
+ return safe;
165
+ }
166
+
167
+ /**
168
+ * Capitalize first letter of a string
169
+ */
170
+ function capitalize(str: string): string {
171
+ return str.charAt(0).toUpperCase() + str.slice(1);
172
+ }
package/src/types.ts CHANGED
@@ -1,7 +1,48 @@
1
1
  import type { z } from "zod";
2
2
 
3
+ // ============================================================================
4
+ // Unified Adapter Types (compatible with @papicandela/mcx-adapters)
5
+ // ============================================================================
6
+
7
+ /**
8
+ * Parameter definition for adapter tools
9
+ */
10
+ export interface ParameterDefinition {
11
+ type: "string" | "number" | "boolean" | "object" | "array";
12
+ description?: string;
13
+ required?: boolean;
14
+ default?: unknown;
15
+ }
16
+
17
+ /**
18
+ * Adapter tool definition (unified interface)
19
+ */
20
+ export interface AdapterTool<TParams = unknown, TResult = unknown> {
21
+ description: string;
22
+ parameters?: Record<string, ParameterDefinition>;
23
+ execute: (params: TParams) => Promise<TResult> | TResult;
24
+ }
25
+
3
26
  /**
4
- * Configuration for an adapter method parameter
27
+ * A registered adapter instance (unified interface)
28
+ *
29
+ * This is the canonical adapter interface used throughout MCX.
30
+ * Compatible with both core and adapters package.
31
+ */
32
+ export interface Adapter<TTools extends Record<string, AdapterTool> = Record<string, AdapterTool>> {
33
+ name: string;
34
+ description?: string;
35
+ version?: string;
36
+ tools: TTools;
37
+ dispose?: () => Promise<void> | void;
38
+ }
39
+
40
+ // ============================================================================
41
+ // Legacy Types (deprecated - use unified types above)
42
+ // ============================================================================
43
+
44
+ /**
45
+ * @deprecated Use ParameterDefinition instead
5
46
  */
6
47
  export interface AdapterMethodParameter {
7
48
  name: string;
@@ -12,7 +53,7 @@ export interface AdapterMethodParameter {
12
53
  }
13
54
 
14
55
  /**
15
- * Configuration for an adapter method
56
+ * @deprecated Use AdapterTool instead
16
57
  */
17
58
  export interface AdapterMethodConfig {
18
59
  name: string;
@@ -22,7 +63,7 @@ export interface AdapterMethodConfig {
22
63
  }
23
64
 
24
65
  /**
25
- * A method exposed by an adapter
66
+ * @deprecated Use AdapterTool instead
26
67
  */
27
68
  export interface AdapterMethod {
28
69
  name: string;
@@ -32,7 +73,7 @@ export interface AdapterMethod {
32
73
  }
33
74
 
34
75
  /**
35
- * Configuration for defining an adapter
76
+ * @deprecated Use Adapter with tools: Record<> instead
36
77
  */
37
78
  export interface AdapterConfig<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {
38
79
  name: string;
@@ -43,9 +84,9 @@ export interface AdapterConfig<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {
43
84
  }
44
85
 
45
86
  /**
46
- * A registered adapter instance
87
+ * @deprecated Legacy adapter interface - use Adapter instead
47
88
  */
48
- export interface Adapter {
89
+ export interface LegacyAdapter {
49
90
  name: string;
50
91
  description?: string;
51
92
  version: string;
@@ -53,18 +94,41 @@ export interface Adapter {
53
94
  config?: unknown;
54
95
  }
55
96
 
97
+ import type { NetworkPolicy } from "./sandbox/network-policy.js";
98
+ import type { AnalysisConfig } from "./sandbox/analyzer/index.js";
99
+
56
100
  /**
57
- * Configuration for the sandbox execution environment
101
+ * Configuration for the sandbox execution environment.
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * const config: SandboxConfig = {
106
+ * timeout: 10000,
107
+ * networkPolicy: { mode: 'blocked' },
108
+ * normalizeCode: true,
109
+ * analysis: {
110
+ * enabled: true,
111
+ * blockOnError: true,
112
+ * rules: { 'no-infinite-loop': 'error' }
113
+ * }
114
+ * };
115
+ * ```
58
116
  */
59
117
  export interface SandboxConfig {
60
118
  /** Timeout in milliseconds (default: 5000) */
61
119
  timeout?: number;
62
- /** Memory limit in MB (default: 128) */
120
+ /** Memory limit in MB (default: 128, not enforced in Bun Workers) */
63
121
  memoryLimit?: number;
64
122
  /** Whether to allow async/await (default: true) */
65
123
  allowAsync?: boolean;
66
- /** Custom global variables to inject */
124
+ /** Custom global variables to inject into sandbox */
67
125
  globals?: Record<string, unknown>;
126
+ /** Network access policy - blocked, allowed (whitelist), or unrestricted (default: blocked) */
127
+ networkPolicy?: NetworkPolicy;
128
+ /** Normalize code before execution - auto-add return, syntax validation (default: true) */
129
+ normalizeCode?: boolean;
130
+ /** Pre-execution analysis - detects infinite loops, dangerous patterns (default: enabled) */
131
+ analysis?: AnalysisConfig;
68
132
  }
69
133
 
70
134
  /**
@@ -133,6 +197,8 @@ export interface MCXConfig {
133
197
  adaptersDir?: string;
134
198
  /** Path to skills directory */
135
199
  skillsDir?: string;
200
+ /** Environment variables to inject into sandbox */
201
+ env?: Record<string, string | undefined>;
136
202
  }
137
203
 
138
204
  /**
@@ -143,4 +209,6 @@ export interface ExecutionContext {
143
209
  adapters: Record<string, Record<string, (...args: unknown[]) => unknown | Promise<unknown>>>;
144
210
  /** Custom variables */
145
211
  variables?: Record<string, unknown>;
212
+ /** Environment variables accessible in sandbox */
213
+ env?: Record<string, string | undefined>;
146
214
  }