mindforge-sdk 11.0.0 → 11.7.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/README.md +29 -6
- package/dist/client.js +39 -3
- package/dist/events.d.ts +4 -2
- package/dist/events.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ if (!valid) console.error(errors);
|
|
|
64
64
|
- The SDK operates on local files and provides no network authentication. Do not expose SDK
|
|
65
65
|
endpoints to the public internet.
|
|
66
66
|
|
|
67
|
-
## New in v11.
|
|
67
|
+
## New in v11.7.0
|
|
68
68
|
|
|
69
69
|
### Additional exports
|
|
70
70
|
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
MindForgeClient,
|
|
74
74
|
MindForgeEventStream,
|
|
75
75
|
WebSocketEventStream,
|
|
76
|
-
VERSION, // '11.
|
|
76
|
+
VERSION, // '11.7.0'
|
|
77
77
|
} from 'mindforge-sdk';
|
|
78
78
|
|
|
79
79
|
import type {
|
|
@@ -102,11 +102,34 @@ for await (const chunk of stream) {
|
|
|
102
102
|
|
|
103
103
|
### Batch execution
|
|
104
104
|
|
|
105
|
+
Runs commands concurrently (semaphore-bounded by `maxConcurrency`, default 3). Each
|
|
106
|
+
task's `command` is the executable and `options.args` is a **string array** — it is NOT a
|
|
107
|
+
shell string. Commands run with `shell: false`, so arguments are passed directly to the
|
|
108
|
+
process and are safe from shell injection.
|
|
109
|
+
|
|
105
110
|
```typescript
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
const batch = await client.batchExecute({
|
|
112
|
+
tasks: [
|
|
113
|
+
{ id: 'task-a', command: 'node', options: { args: ['--version'] } },
|
|
114
|
+
{ id: 'task-b', command: 'git', options: { args: ['rev-parse', 'HEAD'] } },
|
|
115
|
+
],
|
|
116
|
+
maxConcurrency: 4,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
for (const entry of batch.results) {
|
|
120
|
+
if (entry.status === 'fulfilled') {
|
|
121
|
+
// entry.result is { stdout, stderr, exitCode }
|
|
122
|
+
const { stdout, stderr, exitCode } = entry.result as {
|
|
123
|
+
stdout: string; stderr: string; exitCode: number;
|
|
124
|
+
};
|
|
125
|
+
console.log(`${entry.taskId} exited ${exitCode}: ${stdout.trim()}`);
|
|
126
|
+
} else {
|
|
127
|
+
// entry.status === 'rejected'
|
|
128
|
+
console.error(`${entry.taskId} failed: ${entry.error}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
console.log(`batch finished in ${batch.totalDurationMs}ms`);
|
|
110
133
|
```
|
|
111
134
|
|
|
112
135
|
### Runtime config validation
|
package/dist/client.js
CHANGED
|
@@ -38,6 +38,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.MindForgeClient = void 0;
|
|
40
40
|
const events_1 = require("events");
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
41
42
|
const fs = __importStar(require("fs"));
|
|
42
43
|
const path = __importStar(require("path"));
|
|
43
44
|
const events_2 = require("./events");
|
|
@@ -235,7 +236,8 @@ class MindForgeClient extends events_1.EventEmitter {
|
|
|
235
236
|
await eventSource.connect();
|
|
236
237
|
const chunks = [];
|
|
237
238
|
let resolveNext = null;
|
|
238
|
-
eventSource.on('stream_chunk', (
|
|
239
|
+
eventSource.on('stream_chunk', (raw) => {
|
|
240
|
+
const data = raw; // socket payload is untyped JSON; narrow at the boundary
|
|
239
241
|
if (resolveNext) {
|
|
240
242
|
resolveNext({ value: data, done: data.type === 'done' });
|
|
241
243
|
resolveNext = null;
|
|
@@ -307,8 +309,42 @@ class MindForgeClient extends events_1.EventEmitter {
|
|
|
307
309
|
errors.push('taskTimeoutMs must be positive');
|
|
308
310
|
return { valid: errors.length === 0, errors };
|
|
309
311
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
+
executeCommand(command, options) {
|
|
313
|
+
const args = Array.isArray(options?.args) ? options.args : [];
|
|
314
|
+
const cwd = options?.cwd ?? this.projectRoot;
|
|
315
|
+
const timeoutMs = this.config.taskTimeoutMs;
|
|
316
|
+
return new Promise((resolve, reject) => {
|
|
317
|
+
const child = (0, child_process_1.spawn)(command, args, { cwd, shell: false });
|
|
318
|
+
let stdout = '';
|
|
319
|
+
let stderr = '';
|
|
320
|
+
let settled = false;
|
|
321
|
+
const timer = setTimeout(() => {
|
|
322
|
+
if (settled)
|
|
323
|
+
return;
|
|
324
|
+
child.kill('SIGTERM');
|
|
325
|
+
setTimeout(() => { if (!child.killed)
|
|
326
|
+
child.kill('SIGKILL'); }, 2000).unref();
|
|
327
|
+
settled = true;
|
|
328
|
+
reject(new Error(`Command timed out after ${timeoutMs}ms: ${command}`));
|
|
329
|
+
}, timeoutMs);
|
|
330
|
+
timer.unref();
|
|
331
|
+
child.stdout?.on('data', (d) => { stdout += d.toString(); });
|
|
332
|
+
child.stderr?.on('data', (d) => { stderr += d.toString(); });
|
|
333
|
+
child.on('error', (err) => {
|
|
334
|
+
if (settled)
|
|
335
|
+
return;
|
|
336
|
+
clearTimeout(timer);
|
|
337
|
+
settled = true;
|
|
338
|
+
reject(err);
|
|
339
|
+
});
|
|
340
|
+
child.on('close', (code) => {
|
|
341
|
+
if (settled)
|
|
342
|
+
return;
|
|
343
|
+
clearTimeout(timer);
|
|
344
|
+
settled = true;
|
|
345
|
+
resolve({ stdout, stderr, exitCode: code ?? -1 });
|
|
346
|
+
});
|
|
347
|
+
});
|
|
312
348
|
}
|
|
313
349
|
}
|
|
314
350
|
exports.MindForgeClient = MindForgeClient;
|
package/dist/events.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export declare class MindForgeEventStream {
|
|
|
25
25
|
*/
|
|
26
26
|
stop(): void;
|
|
27
27
|
}
|
|
28
|
+
type EventHandler = (data: unknown) => void;
|
|
28
29
|
export declare class WebSocketEventStream {
|
|
29
30
|
private url;
|
|
30
31
|
private ws;
|
|
@@ -33,7 +34,8 @@ export declare class WebSocketEventStream {
|
|
|
33
34
|
private listeners;
|
|
34
35
|
constructor(url?: string);
|
|
35
36
|
connect(): Promise<void>;
|
|
36
|
-
on(eventType: string, handler:
|
|
37
|
-
off(eventType: string, handler:
|
|
37
|
+
on(eventType: string, handler: EventHandler): void;
|
|
38
|
+
off(eventType: string, handler: EventHandler): void;
|
|
38
39
|
disconnect(): void;
|
|
39
40
|
}
|
|
41
|
+
export {};
|
package/dist/events.js
CHANGED
|
@@ -202,7 +202,7 @@ class WebSocketEventStream {
|
|
|
202
202
|
this.ws.onerror = (err) => reject(err);
|
|
203
203
|
this.ws.onmessage = (event) => {
|
|
204
204
|
try {
|
|
205
|
-
const parsed = JSON.parse(event.data
|
|
205
|
+
const parsed = JSON.parse(String(event.data));
|
|
206
206
|
const handlers = this.listeners.get(parsed.type) || new Set();
|
|
207
207
|
handlers.forEach(handler => handler(parsed.data));
|
|
208
208
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,4 +8,4 @@ export { commands, batch } from './commands';
|
|
|
8
8
|
export { MindForgeMemory } from './memory';
|
|
9
9
|
export type { CommandOptions } from './commands';
|
|
10
10
|
export type { MindForgeConfig, PhaseResult, TaskResult, SecurityFinding, GateResult, HealthReport, HealthIssue, MindForgeEvent, AuditLogEntry, WaveExecutionResult, MigrationResult, StreamChunk, StreamingExecutionResult, BatchExecutionRequest, BatchExecutionResult, } from './types';
|
|
11
|
-
export declare const VERSION = "11.
|
|
11
|
+
export declare const VERSION = "11.7.0";
|
package/dist/index.js
CHANGED
|
@@ -15,4 +15,4 @@ Object.defineProperty(exports, "commands", { enumerable: true, get: function ()
|
|
|
15
15
|
Object.defineProperty(exports, "batch", { enumerable: true, get: function () { return commands_1.batch; } });
|
|
16
16
|
var memory_1 = require("./memory");
|
|
17
17
|
Object.defineProperty(exports, "MindForgeMemory", { enumerable: true, get: function () { return memory_1.MindForgeMemory; } });
|
|
18
|
-
exports.VERSION = '11.
|
|
18
|
+
exports.VERSION = '11.7.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindforge-sdk",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.7.0",
|
|
4
4
|
"description": "MindForge SDK \u2014 Programmatic API for embedding MindForge in tools",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,9 +20,10 @@
|
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc",
|
|
23
|
-
"
|
|
23
|
+
"pretest": "npm run build",
|
|
24
|
+
"test": "node tests/sdk.test.js && node tests/execute-command.test.js",
|
|
24
25
|
"lint": "eslint .",
|
|
25
|
-
"prepublishOnly": "npm
|
|
26
|
+
"prepublishOnly": "npm test"
|
|
26
27
|
},
|
|
27
28
|
"keywords": [
|
|
28
29
|
"mindforge",
|