@inkeep/agents-cli 0.1.5 → 0.1.6

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 (59) hide show
  1. package/SUPPLEMENTAL_TERMS.md +40 -0
  2. package/dist/commands/create.d.ts +12 -0
  3. package/dist/commands/create.js +865 -0
  4. package/dist/config.d.ts +4 -4
  5. package/dist/index.js +5306 -20407
  6. package/package.json +15 -6
  7. package/dist/__tests__/api.test.d.ts +0 -1
  8. package/dist/__tests__/api.test.js +0 -257
  9. package/dist/__tests__/cli.test.d.ts +0 -1
  10. package/dist/__tests__/cli.test.js +0 -153
  11. package/dist/__tests__/commands/config.test.d.ts +0 -1
  12. package/dist/__tests__/commands/config.test.js +0 -154
  13. package/dist/__tests__/commands/init.test.d.ts +0 -1
  14. package/dist/__tests__/commands/init.test.js +0 -186
  15. package/dist/__tests__/commands/pull.test.d.ts +0 -1
  16. package/dist/__tests__/commands/pull.test.js +0 -54
  17. package/dist/__tests__/commands/push-spinner.test.d.ts +0 -1
  18. package/dist/__tests__/commands/push-spinner.test.js +0 -127
  19. package/dist/__tests__/commands/push.test.d.ts +0 -1
  20. package/dist/__tests__/commands/push.test.js +0 -265
  21. package/dist/__tests__/config-validation.test.d.ts +0 -1
  22. package/dist/__tests__/config-validation.test.js +0 -98
  23. package/dist/__tests__/package.test.d.ts +0 -1
  24. package/dist/__tests__/package.test.js +0 -82
  25. package/dist/__tests__/utils/json-comparator.test.d.ts +0 -1
  26. package/dist/__tests__/utils/json-comparator.test.js +0 -174
  27. package/dist/__tests__/utils/ts-loader.test.d.ts +0 -1
  28. package/dist/__tests__/utils/ts-loader.test.js +0 -232
  29. package/dist/api.d.ts +0 -23
  30. package/dist/api.js +0 -140
  31. package/dist/commands/chat-enhanced.d.ts +0 -7
  32. package/dist/commands/chat-enhanced.js +0 -396
  33. package/dist/commands/chat.d.ts +0 -5
  34. package/dist/commands/chat.js +0 -125
  35. package/dist/commands/config.d.ts +0 -6
  36. package/dist/commands/config.js +0 -128
  37. package/dist/commands/init.d.ts +0 -5
  38. package/dist/commands/init.js +0 -171
  39. package/dist/commands/list-graphs.d.ts +0 -6
  40. package/dist/commands/list-graphs.js +0 -131
  41. package/dist/commands/pull.d.ts +0 -15
  42. package/dist/commands/pull.js +0 -305
  43. package/dist/commands/pull.llm-generate.d.ts +0 -10
  44. package/dist/commands/pull.llm-generate.js +0 -184
  45. package/dist/commands/push.d.ts +0 -6
  46. package/dist/commands/push.js +0 -268
  47. package/dist/exports.d.ts +0 -2
  48. package/dist/exports.js +0 -2
  49. package/dist/index.js.map +0 -7
  50. package/dist/types/config.d.ts +0 -9
  51. package/dist/types/config.js +0 -3
  52. package/dist/types/graph.d.ts +0 -10
  53. package/dist/types/graph.js +0 -1
  54. package/dist/utils/json-comparator.d.ts +0 -60
  55. package/dist/utils/json-comparator.js +0 -222
  56. package/dist/utils/mcp-runner.d.ts +0 -6
  57. package/dist/utils/mcp-runner.js +0 -147
  58. package/dist/utils/ts-loader.d.ts +0 -5
  59. package/dist/utils/ts-loader.js +0 -145
@@ -1,9 +0,0 @@
1
- import type { ModelSettings } from '@inkeep/agents-core';
2
- export interface InkeepConfig {
3
- tenantId: string;
4
- projectId: string;
5
- apiUrl?: string;
6
- outputDirectory?: string;
7
- modelSettings?: ModelSettings;
8
- }
9
- export declare function defineConfig(config: InkeepConfig): InkeepConfig;
@@ -1,3 +0,0 @@
1
- export function defineConfig(config) {
2
- return config;
3
- }
@@ -1,10 +0,0 @@
1
- export interface GraphData {
2
- id: string;
3
- name: string;
4
- description?: string;
5
- agents: Record<string, any>;
6
- tools: Record<string, any>;
7
- contextConfigs: any[];
8
- credentialReferences: any[];
9
- }
10
- export type FullGraphDefinition = GraphData;
@@ -1 +0,0 @@
1
- export {};
@@ -1,60 +0,0 @@
1
- /**
2
- * Options for JSON comparison
3
- */
4
- export interface ComparisonOptions {
5
- /** Whether to ignore order in arrays (default: true) */
6
- ignoreArrayOrder?: boolean;
7
- /** Whether to ignore case in string comparisons (default: false) */
8
- ignoreCase?: boolean;
9
- /** Whether to ignore whitespace differences (default: false) */
10
- ignoreWhitespace?: boolean;
11
- /** Custom key paths to ignore during comparison */
12
- ignorePaths?: string[];
13
- /** Whether to show detailed differences (default: false) */
14
- showDetails?: boolean;
15
- }
16
- /**
17
- * Result of JSON comparison
18
- */
19
- export interface ComparisonResult {
20
- /** Whether the objects are equivalent */
21
- isEqual: boolean;
22
- /** List of differences found */
23
- differences: Difference[];
24
- /** Summary statistics */
25
- stats: {
26
- totalKeys: number;
27
- differentKeys: number;
28
- missingKeys: number;
29
- extraKeys: number;
30
- };
31
- }
32
- /**
33
- * Represents a difference between two objects
34
- */
35
- export interface Difference {
36
- /** Path to the differing value */
37
- path: string;
38
- /** Type of difference */
39
- type: 'different' | 'missing' | 'extra' | 'type_mismatch';
40
- /** Value in the first object */
41
- value1?: any;
42
- /** Value in the second object */
43
- value2?: any;
44
- /** Description of the difference */
45
- description: string;
46
- }
47
- /**
48
- * Compare two JSON objects for structural equivalence
49
- * Handles arrays with different ordering and nested objects
50
- */
51
- export declare function compareJsonObjects(obj1: any, obj2: any, options?: ComparisonOptions): ComparisonResult;
52
- /**
53
- * Create a normalized version of a JSON object for comparison
54
- * This can be useful for creating a canonical representation
55
- */
56
- export declare function normalizeJsonObject(obj: any, options?: ComparisonOptions): any;
57
- /**
58
- * Get a summary of differences in a human-readable format
59
- */
60
- export declare function getDifferenceSummary(result: ComparisonResult): string;
@@ -1,222 +0,0 @@
1
- /**
2
- * Compare two JSON objects for structural equivalence
3
- * Handles arrays with different ordering and nested objects
4
- */
5
- export function compareJsonObjects(obj1, obj2, options = {}) {
6
- const { ignoreArrayOrder = true, ignoreCase = false, ignoreWhitespace = false, ignorePaths = [], } = options;
7
- const differences = [];
8
- const stats = {
9
- totalKeys: 0,
10
- differentKeys: 0,
11
- missingKeys: 0,
12
- extraKeys: 0,
13
- };
14
- function normalizeValue(value) {
15
- if (typeof value === 'string') {
16
- let normalized = value;
17
- if (ignoreCase) {
18
- normalized = normalized.toLowerCase();
19
- }
20
- if (ignoreWhitespace) {
21
- normalized = normalized.trim().replace(/\s+/g, ' ');
22
- }
23
- return normalized;
24
- }
25
- return value;
26
- }
27
- function shouldIgnorePath(path) {
28
- return ignorePaths.some((ignorePath) => {
29
- if (ignorePath.endsWith('*')) {
30
- return path.startsWith(ignorePath.slice(0, -1));
31
- }
32
- return path === ignorePath;
33
- });
34
- }
35
- function compareValues(value1, value2, path = '') {
36
- if (shouldIgnorePath(path)) {
37
- return true;
38
- }
39
- // Handle null/undefined
40
- if (value1 === null || value1 === undefined) {
41
- if (value2 === null || value2 === undefined) {
42
- return true;
43
- }
44
- differences.push({
45
- path,
46
- type: 'different',
47
- value1,
48
- value2,
49
- description: `Null/undefined mismatch: ${value1} vs ${value2}`,
50
- });
51
- return false;
52
- }
53
- if (value2 === null || value2 === undefined) {
54
- differences.push({
55
- path,
56
- type: 'different',
57
- value1,
58
- value2,
59
- description: `Null/undefined mismatch: ${value1} vs ${value2}`,
60
- });
61
- return false;
62
- }
63
- // Handle different types
64
- if (typeof value1 !== typeof value2) {
65
- differences.push({
66
- path,
67
- type: 'type_mismatch',
68
- value1,
69
- value2,
70
- description: `Type mismatch: ${typeof value1} vs ${typeof value2}`,
71
- });
72
- return false;
73
- }
74
- // Handle primitives
75
- if (typeof value1 !== 'object') {
76
- const normalized1 = normalizeValue(value1);
77
- const normalized2 = normalizeValue(value2);
78
- if (normalized1 !== normalized2) {
79
- differences.push({
80
- path,
81
- type: 'different',
82
- value1,
83
- value2,
84
- description: `Value mismatch: ${value1} vs ${value2}`,
85
- });
86
- return false;
87
- }
88
- return true;
89
- }
90
- // Handle arrays
91
- if (Array.isArray(value1) && Array.isArray(value2)) {
92
- if (value1.length !== value2.length) {
93
- differences.push({
94
- path,
95
- type: 'different',
96
- value1: value1.length,
97
- value2: value2.length,
98
- description: `Array length mismatch: ${value1.length} vs ${value2.length}`,
99
- });
100
- return false; // Array length mismatch is a fundamental difference
101
- }
102
- if (ignoreArrayOrder) {
103
- // Compare arrays ignoring order
104
- const sorted1 = [...value1].sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
105
- const sorted2 = [...value2].sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
106
- for (let i = 0; i < sorted1.length; i++) {
107
- compareValues(sorted1[i], sorted2[i], `${path}[${i}]`); // Don't return false, just collect differences
108
- }
109
- }
110
- else {
111
- // Compare arrays in order
112
- for (let i = 0; i < value1.length; i++) {
113
- compareValues(value1[i], value2[i], `${path}[${i}]`); // Don't return false, just collect differences
114
- }
115
- }
116
- return true;
117
- }
118
- // Handle objects
119
- if (typeof value1 === 'object' && typeof value2 === 'object') {
120
- const keys1 = Object.keys(value1);
121
- const keys2 = Object.keys(value2);
122
- const allKeys = new Set([...keys1, ...keys2]);
123
- stats.totalKeys += allKeys.size;
124
- for (const key of allKeys) {
125
- const currentPath = path ? `${path}.${key}` : key;
126
- if (!keys1.includes(key)) {
127
- differences.push({
128
- path: currentPath,
129
- type: 'missing',
130
- value2: value2[key],
131
- description: `Missing key in first object: ${key}`,
132
- });
133
- stats.missingKeys++;
134
- continue; // Continue checking other keys instead of returning false
135
- }
136
- if (!keys2.includes(key)) {
137
- differences.push({
138
- path: currentPath,
139
- type: 'extra',
140
- value1: value1[key],
141
- description: `Extra key in first object: ${key}`,
142
- });
143
- stats.extraKeys++;
144
- continue; // Continue checking other keys instead of returning false
145
- }
146
- if (!compareValues(value1[key], value2[key], currentPath)) {
147
- stats.differentKeys++;
148
- // Don't return false here, continue checking other keys
149
- }
150
- }
151
- return true;
152
- }
153
- return true;
154
- }
155
- compareValues(obj1, obj2);
156
- return {
157
- isEqual: differences.length === 0,
158
- differences,
159
- stats,
160
- };
161
- }
162
- /**
163
- * Create a normalized version of a JSON object for comparison
164
- * This can be useful for creating a canonical representation
165
- */
166
- export function normalizeJsonObject(obj, options = {}) {
167
- const { ignoreArrayOrder = true, ignoreCase = false, ignoreWhitespace = false } = options;
168
- function normalizeValue(value) {
169
- if (typeof value === 'string') {
170
- let normalized = value;
171
- if (ignoreCase) {
172
- normalized = normalized.toLowerCase();
173
- }
174
- if (ignoreWhitespace) {
175
- normalized = normalized.trim().replace(/\s+/g, ' ');
176
- }
177
- return normalized;
178
- }
179
- if (Array.isArray(value)) {
180
- const normalizedArray = value.map(normalizeValue);
181
- if (ignoreArrayOrder) {
182
- return normalizedArray.sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
183
- }
184
- return normalizedArray;
185
- }
186
- if (typeof value === 'object' && value !== null) {
187
- const normalizedObj = {};
188
- const sortedKeys = Object.keys(value).sort();
189
- for (const key of sortedKeys) {
190
- normalizedObj[key] = normalizeValue(value[key]);
191
- }
192
- return normalizedObj;
193
- }
194
- return value;
195
- }
196
- return normalizeValue(obj);
197
- }
198
- /**
199
- * Get a summary of differences in a human-readable format
200
- */
201
- export function getDifferenceSummary(result) {
202
- if (result.isEqual) {
203
- return '✅ Objects are equivalent';
204
- }
205
- const { differences, stats } = result;
206
- const summary = [`❌ Objects differ (${differences.length} differences found)`];
207
- summary.push(`📊 Statistics:`);
208
- summary.push(` • Total keys: ${stats.totalKeys}`);
209
- summary.push(` • Different values: ${stats.differentKeys}`);
210
- summary.push(` • Missing keys: ${stats.missingKeys}`);
211
- summary.push(` • Extra keys: ${stats.extraKeys}`);
212
- if (differences.length > 0) {
213
- summary.push(`\n🔍 Differences:`);
214
- differences.slice(0, 10).forEach((diff, index) => {
215
- summary.push(` ${index + 1}. ${diff.path}: ${diff.description}`);
216
- });
217
- if (differences.length > 10) {
218
- summary.push(` ... and ${differences.length - 10} more differences`);
219
- }
220
- }
221
- return summary.join('\n');
222
- }
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * MCP Runner - Loads and starts MCP servers from a graph file
4
- * This is executed as a subprocess by the CLI
5
- */
6
- export {};
@@ -1,147 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * MCP Runner - Loads and starts MCP servers from a graph file
4
- * This is executed as a subprocess by the CLI
5
- */
6
- import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
7
- import http from 'node:http';
8
- import { homedir } from 'node:os';
9
- import { join } from 'node:path';
10
- const MCP_DIR = join(homedir(), '.inkeep', 'mcp');
11
- const REGISTRY_FILE = join(MCP_DIR, 'servers.json');
12
- // Ensure MCP directory exists
13
- if (!existsSync(MCP_DIR)) {
14
- mkdirSync(MCP_DIR, { recursive: true });
15
- }
16
- async function startServers(graphPath) {
17
- try {
18
- // Import the graph module
19
- const module = await import(graphPath);
20
- // Get servers
21
- const servers = module.servers || module.tools || [];
22
- // Get graph ID
23
- let graphId = 'unknown';
24
- if (module.graph && typeof module.graph.getId === 'function') {
25
- graphId = module.graph.getId();
26
- }
27
- const registeredServers = [];
28
- let nextPort = 3100;
29
- // Start each server
30
- for (const server of servers) {
31
- if (!server)
32
- continue;
33
- // Get server metadata
34
- const name = server.name || 'unnamed';
35
- const id = server.id || name;
36
- const description = server.description || '';
37
- // Check deployment type
38
- const isLocal = typeof server.execute === 'function' ||
39
- typeof server.init === 'function' ||
40
- !server.serverUrl;
41
- if (isLocal) {
42
- // Start local server
43
- const port = server.port || nextPort++;
44
- // Initialize if needed
45
- if (typeof server.init === 'function') {
46
- await server.init();
47
- }
48
- // Create HTTP server for local MCP
49
- if (typeof server.execute === 'function') {
50
- const httpServer = http.createServer(async (req, res) => {
51
- if (req.method === 'POST' && req.url === '/mcp') {
52
- let body = '';
53
- req.on('data', (chunk) => (body += chunk));
54
- req.on('end', async () => {
55
- try {
56
- const params = JSON.parse(body);
57
- const result = await server.execute(params);
58
- res.writeHead(200, { 'Content-Type': 'application/json' });
59
- res.end(JSON.stringify({ result }));
60
- }
61
- catch (error) {
62
- res.writeHead(500, { 'Content-Type': 'application/json' });
63
- res.end(JSON.stringify({ error: error.message }));
64
- }
65
- });
66
- }
67
- else {
68
- res.writeHead(404);
69
- res.end('Not Found');
70
- }
71
- });
72
- httpServer.listen(port, () => {
73
- console.log(JSON.stringify({
74
- type: 'server_started',
75
- name,
76
- port,
77
- deployment: 'local',
78
- }));
79
- });
80
- }
81
- registeredServers.push({
82
- pid: process.pid,
83
- graphId,
84
- toolId: id,
85
- name,
86
- port,
87
- deployment: 'local',
88
- transport: 'http',
89
- command: graphPath,
90
- startedAt: new Date().toISOString(),
91
- description,
92
- });
93
- }
94
- else {
95
- // Register remote server
96
- registeredServers.push({
97
- pid: process.pid,
98
- graphId,
99
- toolId: id,
100
- name,
101
- serverUrl: server.serverUrl || server.getServerUrl?.(),
102
- deployment: 'remote',
103
- transport: server.transport || 'http',
104
- command: graphPath,
105
- startedAt: new Date().toISOString(),
106
- description,
107
- });
108
- console.log(JSON.stringify({
109
- type: 'server_registered',
110
- name,
111
- serverUrl: server.serverUrl,
112
- deployment: 'remote',
113
- }));
114
- }
115
- }
116
- // Save to registry
117
- writeFileSync(REGISTRY_FILE, JSON.stringify({ servers: registeredServers }, null, 2));
118
- console.log(JSON.stringify({
119
- type: 'all_started',
120
- count: registeredServers.length,
121
- }));
122
- // Keep process alive
123
- process.stdin.resume();
124
- // Handle shutdown
125
- process.on('SIGINT', () => {
126
- console.log(JSON.stringify({ type: 'shutting_down' }));
127
- process.exit(0);
128
- });
129
- }
130
- catch (error) {
131
- console.error(JSON.stringify({
132
- type: 'error',
133
- message: error.message,
134
- }));
135
- process.exit(1);
136
- }
137
- }
138
- // Get graph path from command line
139
- const graphPath = process.argv[2];
140
- if (!graphPath) {
141
- console.error(JSON.stringify({
142
- type: 'error',
143
- message: 'Graph path is required',
144
- }));
145
- process.exit(1);
146
- }
147
- startServers(graphPath);
@@ -1,5 +0,0 @@
1
- /**
2
- * Loads a TypeScript module and returns its exports
3
- * This works by creating a temporary loader script that tsx can execute
4
- */
5
- export declare function loadTypeScriptModule(filePath: string): Promise<any>;
@@ -1,145 +0,0 @@
1
- import { execFileSync } from 'node:child_process';
2
- import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
- import { tmpdir } from 'node:os';
4
- import { dirname, join } from 'node:path';
5
- import { pathToFileURL } from 'node:url';
6
- /**
7
- * Loads a TypeScript module and returns its exports
8
- * This works by creating a temporary loader script that tsx can execute
9
- */
10
- export async function loadTypeScriptModule(filePath) {
11
- const tempDir = join(tmpdir(), 'inkeep-cli-loader');
12
- mkdirSync(tempDir, { recursive: true });
13
- const loaderPath = join(tempDir, 'loader.mjs');
14
- const outputPath = join(tempDir, 'output.json');
15
- // Create a loader script that will import the module and serialize its exports
16
- const loaderScript = `
17
- import { writeFileSync } from 'fs';
18
-
19
- async function loadModule() {
20
- try {
21
- const module = await import('${pathToFileURL(filePath).href}');
22
-
23
- // Serialize the module exports (functions can't be serialized, so we just mark them)
24
- const serializable = {};
25
-
26
- for (const [key, value] of Object.entries(module)) {
27
- if (typeof value === 'function') {
28
- // Mark functions
29
- serializable[key] = { __type: 'function', name: value.name || key };
30
- } else if (value && typeof value === 'object') {
31
- // For objects, check if they have specific methods/properties
32
- const obj = { __type: 'object' };
33
-
34
- // Check for config-like properties (for inkeep.config.ts files)
35
- if (value.tenantId) obj.tenantId = value.tenantId;
36
- if (value.projectId) obj.projectId = value.projectId;
37
- if (value.apiUrl) obj.apiUrl = value.apiUrl;
38
- if (value.outputDirectory) obj.outputDirectory = value.outputDirectory;
39
- if (value.modelSettings) obj.modelSettings = value.modelSettings;
40
-
41
- // Check for tool-like properties
42
- if (value.id) obj.id = value.id;
43
- if (value.name) obj.name = value.name;
44
- if (value.description) obj.description = value.description;
45
- if (value.serverUrl) obj.serverUrl = value.serverUrl;
46
- if (value.port) obj.port = value.port;
47
- if (value.deployment) obj.deployment = value.deployment;
48
- if (value.transport) obj.transport = value.transport;
49
- if (typeof value.execute === 'function') obj.hasExecute = true;
50
- if (typeof value.init === 'function') obj.hasInit = true;
51
- if (typeof value.getServerUrl === 'function') obj.hasGetServerUrl = true;
52
- if (typeof value.getId === 'function') {
53
- try {
54
- obj.graphId = value.getId();
55
- } catch {}
56
- }
57
-
58
- // Check if it's an array
59
- if (Array.isArray(value)) {
60
- obj.__type = 'array';
61
- obj.items = value.map(item => {
62
- if (item && typeof item === 'object') {
63
- const itemObj = {};
64
- if (item.id) itemObj.id = item.id;
65
- if (item.name) itemObj.name = item.name;
66
- if (item.description) itemObj.description = item.description;
67
- if (item.serverUrl) itemObj.serverUrl = item.serverUrl;
68
- if (item.port) itemObj.port = item.port;
69
- if (item.deployment) itemObj.deployment = item.deployment;
70
- if (item.transport) itemObj.transport = item.transport;
71
- if (typeof item.execute === 'function') itemObj.hasExecute = true;
72
- if (typeof item.init === 'function') itemObj.hasInit = true;
73
- if (typeof item.getServerUrl === 'function') itemObj.hasGetServerUrl = true;
74
- return itemObj;
75
- }
76
- return item;
77
- });
78
- }
79
-
80
- serializable[key] = obj;
81
- } else {
82
- serializable[key] = value;
83
- }
84
- }
85
-
86
- writeFileSync('${outputPath}', JSON.stringify(serializable, null, 2));
87
- process.exit(0);
88
- } catch (error) {
89
- console.error('Failed to load module:', error.message);
90
- writeFileSync('${outputPath}', JSON.stringify({ __error: error.message }));
91
- process.exit(1);
92
- }
93
- }
94
-
95
- loadModule();
96
- `;
97
- try {
98
- // Write the loader script
99
- writeFileSync(loaderPath, loaderScript);
100
- // Execute the loader script with tsx, passing environment variables
101
- // Load the .env file from the graph directory if it exists
102
- const graphDir = dirname(filePath);
103
- const envPath = join(graphDir, '..', '.env');
104
- const envVars = { ...process.env };
105
- // If no environment variables are set, use test defaults
106
- if (!process.env.ENVIRONMENT) {
107
- envVars.ENVIRONMENT = 'test';
108
- envVars.DB_FILE_NAME = ':memory:'; // Use in-memory DB for CLI testing
109
- envVars.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || 'test-key';
110
- }
111
- // Use node directly with tsx for better performance in CI
112
- // Try to find tsx in node_modules first for better performance
113
- const tsxPath = join(process.cwd(), 'node_modules', '.bin', 'tsx');
114
- const command = require('fs').existsSync(tsxPath) ? tsxPath : 'tsx';
115
- execFileSync(command, [loaderPath], {
116
- cwd: process.cwd(), // Use cwd which is in the pnpm workspace
117
- stdio: 'pipe',
118
- encoding: 'utf-8',
119
- env: envVars,
120
- timeout: 15000, // Reduced to 15 second timeout for faster failure detection
121
- windowsHide: true, // Hide console window on Windows
122
- });
123
- // Read the output
124
- const outputJson = readFileSync(outputPath, 'utf-8');
125
- const output = JSON.parse(outputJson);
126
- // Clean up with retries to handle file locks
127
- rmSync(tempDir, { recursive: true, force: true, maxRetries: 3 });
128
- if (output.__error) {
129
- throw new Error(output.__error);
130
- }
131
- return output;
132
- }
133
- catch (error) {
134
- // Clean up on error
135
- try {
136
- rmSync(tempDir, { recursive: true, force: true, maxRetries: 3 });
137
- }
138
- catch { }
139
- // Add more context to timeout errors
140
- if (error.code === 'ETIMEDOUT' || error.message?.includes('timed out')) {
141
- throw new Error(`TypeScript module loading timed out for ${filePath}: ${error.message}`);
142
- }
143
- throw error;
144
- }
145
- }