@webority/ensemble 0.5.9 → 0.5.11
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/lib/core.js +38 -3
- package/package.json +9 -6
package/lib/core.js
CHANGED
|
@@ -364,6 +364,36 @@ function writeRunnerConfig(api, machineToken) {
|
|
|
364
364
|
} catch (e) { /* best-effort */ }
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
+
function ensureWindowsRuntimePath() {
|
|
368
|
+
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === 'path') || 'Path';
|
|
369
|
+
const currentProcessPath = process.env[pathKey] || '';
|
|
370
|
+
const normalize = (value) => value.replace(/[\\/]+$/, '').toLowerCase();
|
|
371
|
+
if (!currentProcessPath.split(';').some((entry) => normalize(entry) === normalize(BIN_DIR))) {
|
|
372
|
+
process.env[pathKey] = [currentProcessPath, BIN_DIR].filter(Boolean).join(';');
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const script =
|
|
376
|
+
"$ErrorActionPreference = 'Stop'; " +
|
|
377
|
+
'$target = $env:ENSEMBLE_BIN_TO_ADD; ' +
|
|
378
|
+
"$current = [Environment]::GetEnvironmentVariable('Path', 'User'); " +
|
|
379
|
+
"$entries = @($current -split ';' | Where-Object { $_ }); " +
|
|
380
|
+
"if (-not ($entries | Where-Object { [string]::Equals($_.TrimEnd('\\'), $target.TrimEnd('\\'), " +
|
|
381
|
+
"[StringComparison]::OrdinalIgnoreCase) })) { " +
|
|
382
|
+
"[Environment]::SetEnvironmentVariable('Path', (($entries + $target) -join ';'), 'User') }";
|
|
383
|
+
const result = spawnSync(
|
|
384
|
+
'powershell.exe',
|
|
385
|
+
['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', script],
|
|
386
|
+
{
|
|
387
|
+
encoding: 'utf8',
|
|
388
|
+
env: { ...process.env, ENSEMBLE_BIN_TO_ADD: BIN_DIR },
|
|
389
|
+
},
|
|
390
|
+
);
|
|
391
|
+
if (result.status !== 0) {
|
|
392
|
+
throw new Error('could not add ' + BIN_DIR + ' to the Windows user PATH: ' +
|
|
393
|
+
((result.stderr || result.error || 'unknown error').toString().trim()));
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
367
397
|
// --- wire ensemble-runtime into each installed harness (hooks + MCP) ---
|
|
368
398
|
// Fleet engines: Claude, Codex, Grok, OpenCode, OMP (oh-my-pi), Gemini, Antigravity (when present).
|
|
369
399
|
// Hooks = mail at turn boundaries. MCP = who/send/read/reply tools every turn.
|
|
@@ -399,7 +429,11 @@ function wireHooks() {
|
|
|
399
429
|
if (mergeClaudeHooks(path.join(HOME, '.claude', 'settings.json'), runtimeInvoke)) report.push('claude:hooks');
|
|
400
430
|
}
|
|
401
431
|
if (enginePresent('codex')) {
|
|
402
|
-
|
|
432
|
+
const windowsRuntime = pf.os === 'windows' ? path.basename(runtimeExe) : null;
|
|
433
|
+
if (windowsRuntime) ensureWindowsRuntimePath();
|
|
434
|
+
if (writeEngineHooks(path.join(HOME, '.codex', 'hooks.json'), runtimeInvoke, 'codex', windowsRuntime)) {
|
|
435
|
+
report.push('codex:hooks');
|
|
436
|
+
}
|
|
403
437
|
}
|
|
404
438
|
if (enginePresent('grok')) {
|
|
405
439
|
if (writeEngineHooks(path.join(HOME, '.grok', 'hooks', 'agent-bus.json'), runtimeInvoke, 'grok')) report.push('grok:hooks');
|
|
@@ -704,7 +738,7 @@ function isEnsembleHook(h) {
|
|
|
704
738
|
// only MCP worked). MERGE-preserving: keep other events + the user's own groups on our events, dedup
|
|
705
739
|
// our entry so re-runs don't stack, and migrate away the legacy lowercase keys. [BUG-06673-hooks]
|
|
706
740
|
// Returns true when written, false when skipped (malformed JSON left untouched).
|
|
707
|
-
function writeEngineHooks(file, runtimeInvoke, engine) {
|
|
741
|
+
function writeEngineHooks(file, runtimeInvoke, engine, windowsRuntime) {
|
|
708
742
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
709
743
|
let existing = {};
|
|
710
744
|
if (fs.existsSync(file)) {
|
|
@@ -729,7 +763,8 @@ function writeEngineHooks(file, runtimeInvoke, engine) {
|
|
|
729
763
|
// command directly and the hook handler is already silent-safe on failure.
|
|
730
764
|
const events = { SessionStart: 'session-start', UserPromptSubmit: 'user-prompt', Stop: 'stop', SessionEnd: 'session-end' };
|
|
731
765
|
for (const [evt, ev] of Object.entries(events)) {
|
|
732
|
-
const
|
|
766
|
+
const runtimeCommand = windowsRuntime || `"${runtimeInvoke}"`;
|
|
767
|
+
const command = `${runtimeCommand} hook ${ev} --engine ${engine}`;
|
|
733
768
|
const groups = Array.isArray(hooks[evt]) ? hooks[evt] : (hooks[evt] == null ? [] : [hooks[evt]]);
|
|
734
769
|
const kept = groups
|
|
735
770
|
.filter((g) => g && typeof g === 'object' && !Array.isArray(g))
|
package/package.json
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/ensemble",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.11",
|
|
4
4
|
"description": "Connect this machine to Ensemble — runs the local agent runner and wires the ensemble session bus so your coding sessions talk (per-org, isolated).",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ensemble": "bin/ensemble.js"
|
|
7
7
|
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "node --test"
|
|
10
|
+
},
|
|
8
11
|
"engines": {
|
|
9
12
|
"node": ">=18"
|
|
10
13
|
},
|
|
11
14
|
"optionalDependencies": {
|
|
12
|
-
"@webority/ensemble-darwin-arm64": "0.5.
|
|
13
|
-
"@webority/ensemble-darwin-x64": "0.5.
|
|
14
|
-
"@webority/ensemble-linux-arm64": "0.5.
|
|
15
|
-
"@webority/ensemble-linux-x64": "0.5.
|
|
16
|
-
"@webority/ensemble-win-x64": "0.5.
|
|
15
|
+
"@webority/ensemble-darwin-arm64": "0.5.11",
|
|
16
|
+
"@webority/ensemble-darwin-x64": "0.5.11",
|
|
17
|
+
"@webority/ensemble-linux-arm64": "0.5.11",
|
|
18
|
+
"@webority/ensemble-linux-x64": "0.5.11",
|
|
19
|
+
"@webority/ensemble-win-x64": "0.5.11"
|
|
17
20
|
},
|
|
18
21
|
"files": [
|
|
19
22
|
"bin",
|