@askexenow/exe-os 0.9.92 → 0.9.93
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/dist/bin/cli.js +58 -1
- package/dist/bin/stack-update.js +58 -1
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -20315,7 +20315,7 @@ function hydrateEnv(raw, opts) {
|
|
|
20315
20315
|
for (const [key, value] of env.entries()) {
|
|
20316
20316
|
if (!/CHANGEME/.test(value)) continue;
|
|
20317
20317
|
if (key === "EXE_LICENSE_KEY" && license) replacements[key] = license;
|
|
20318
|
-
else if (key === "MONITOR_AGENT_KEY") continue;
|
|
20318
|
+
else if (key === "MONITOR_AGENT_TOKEN" || key === "MONITOR_AGENT_KEY") continue;
|
|
20319
20319
|
else if (key === "EXE_GATEWAY_WS_RELAY_AUTH_TOKEN") replacements[key] = randomHexSecret(24);
|
|
20320
20320
|
else if (key.endsWith("_PASSWORD")) replacements[key] = randomSecret(24);
|
|
20321
20321
|
else if (key.endsWith("_TOKEN")) replacements[key] = randomHexSecret(32);
|
|
@@ -20327,6 +20327,45 @@ function hydrateEnv(raw, opts) {
|
|
|
20327
20327
|
const remaining = [...parseEnv(next).entries()].filter(([, value]) => /CHANGEME/.test(value)).map(([key, value]) => `${key}=${value}`);
|
|
20328
20328
|
return { raw: next, hadPlaceholders: /CHANGEME/.test(raw), remaining: [...new Set(remaining)] };
|
|
20329
20329
|
}
|
|
20330
|
+
async function pairMonitorAgent(hubUrl, licenseKey, domain, envFile) {
|
|
20331
|
+
if (!hubUrl || !licenseKey || !domain) {
|
|
20332
|
+
return { paired: false, error: "Missing hubUrl, licenseKey, or domain for monitor pairing" };
|
|
20333
|
+
}
|
|
20334
|
+
const registrationUrl = `${hubUrl.replace(/\/+$/, "")}/api/register-agent`;
|
|
20335
|
+
try {
|
|
20336
|
+
const res = await fetch(registrationUrl, {
|
|
20337
|
+
method: "POST",
|
|
20338
|
+
headers: {
|
|
20339
|
+
"content-type": "application/json",
|
|
20340
|
+
authorization: `Bearer ${licenseKey}`
|
|
20341
|
+
},
|
|
20342
|
+
body: JSON.stringify({ name: domain, host: domain, port: 45876 }),
|
|
20343
|
+
signal: AbortSignal.timeout(15e3)
|
|
20344
|
+
});
|
|
20345
|
+
if (!res.ok) {
|
|
20346
|
+
const body = await res.text().catch(() => "");
|
|
20347
|
+
return { paired: false, error: `Monitor hub returned HTTP ${res.status}: ${body}` };
|
|
20348
|
+
}
|
|
20349
|
+
const data = await res.json();
|
|
20350
|
+
if (!data.token || !data.key) {
|
|
20351
|
+
return { paired: false, error: "Monitor hub response missing token or key" };
|
|
20352
|
+
}
|
|
20353
|
+
if (existsSync34(envFile)) {
|
|
20354
|
+
const envRaw = readFileSync29(envFile, "utf8");
|
|
20355
|
+
const patched = patchEnv(envRaw, {
|
|
20356
|
+
MONITOR_AGENT_TOKEN: data.token,
|
|
20357
|
+
MONITOR_AGENT_KEY: data.key
|
|
20358
|
+
});
|
|
20359
|
+
if (patched !== envRaw) {
|
|
20360
|
+
writeFileSync25(envFile, patched, { mode: 384 });
|
|
20361
|
+
}
|
|
20362
|
+
}
|
|
20363
|
+
return { paired: true, systemName: data.name ?? domain };
|
|
20364
|
+
} catch (err) {
|
|
20365
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
20366
|
+
return { paired: false, error: `Monitor hub unreachable: ${reason}` };
|
|
20367
|
+
}
|
|
20368
|
+
}
|
|
20330
20369
|
function bootstrapStackHost(options) {
|
|
20331
20370
|
const exec2 = options.exec ?? defaultExec;
|
|
20332
20371
|
const createdFiles = [];
|
|
@@ -20399,6 +20438,24 @@ async function runStackUpdate(options) {
|
|
|
20399
20438
|
const report = bootstrapStackHost({ ...options, installDocker: options.installDocker ?? !!options.yes });
|
|
20400
20439
|
if (!options.dryRun) assertHostReadyForApply(report);
|
|
20401
20440
|
}
|
|
20441
|
+
const hubUrl = options.monitorHubUrl || parseEnv(readFileSync29(options.envFile, "utf8")).get("MONITOR_HUB_URL") || "";
|
|
20442
|
+
const pairLicense = options.licenseKey || process.env.EXE_LICENSE_KEY || loadLicense() || "";
|
|
20443
|
+
const pairDomain = options.domain || process.env.EXE_STACK_DOMAIN || process.env.CUSTOMER_DOMAIN || "";
|
|
20444
|
+
if (hubUrl && pairLicense && pairDomain) {
|
|
20445
|
+
const envBefore = readFileSync29(options.envFile, "utf8");
|
|
20446
|
+
const hasPlaceholder = /CHANGEME/.test(parseEnv(envBefore).get("MONITOR_AGENT_TOKEN") ?? "");
|
|
20447
|
+
if (hasPlaceholder) {
|
|
20448
|
+
const pair = options.pairMonitor ? options.pairMonitor(hubUrl, pairLicense, pairDomain, options.envFile) : pairMonitorAgent(hubUrl, pairLicense, pairDomain, options.envFile);
|
|
20449
|
+
const result = await pair;
|
|
20450
|
+
if (typeof result === "object" && result && "paired" in result) {
|
|
20451
|
+
if (result.paired) {
|
|
20452
|
+
console.log(`[stack-update] Monitor agent paired: ${result.systemName}`);
|
|
20453
|
+
} else {
|
|
20454
|
+
console.warn(`[stack-update] Monitor pairing skipped: ${result.error}`);
|
|
20455
|
+
}
|
|
20456
|
+
}
|
|
20457
|
+
}
|
|
20458
|
+
}
|
|
20402
20459
|
const manifest = await loadStackManifest(options.manifestRef, options.fetchText, options.manifestPublicKey, options.manifestAuthToken);
|
|
20403
20460
|
const envRaw = readFileSync29(options.envFile, "utf8");
|
|
20404
20461
|
const plan = createStackUpdatePlan(manifest, envRaw, options.targetVersion);
|
package/dist/bin/stack-update.js
CHANGED
|
@@ -467,7 +467,7 @@ function hydrateEnv(raw, opts) {
|
|
|
467
467
|
for (const [key, value] of env.entries()) {
|
|
468
468
|
if (!/CHANGEME/.test(value)) continue;
|
|
469
469
|
if (key === "EXE_LICENSE_KEY" && license) replacements[key] = license;
|
|
470
|
-
else if (key === "MONITOR_AGENT_KEY") continue;
|
|
470
|
+
else if (key === "MONITOR_AGENT_TOKEN" || key === "MONITOR_AGENT_KEY") continue;
|
|
471
471
|
else if (key === "EXE_GATEWAY_WS_RELAY_AUTH_TOKEN") replacements[key] = randomHexSecret(24);
|
|
472
472
|
else if (key.endsWith("_PASSWORD")) replacements[key] = randomSecret(24);
|
|
473
473
|
else if (key.endsWith("_TOKEN")) replacements[key] = randomHexSecret(32);
|
|
@@ -479,6 +479,45 @@ function hydrateEnv(raw, opts) {
|
|
|
479
479
|
const remaining = [...parseEnv(next).entries()].filter(([, value]) => /CHANGEME/.test(value)).map(([key, value]) => `${key}=${value}`);
|
|
480
480
|
return { raw: next, hadPlaceholders: /CHANGEME/.test(raw), remaining: [...new Set(remaining)] };
|
|
481
481
|
}
|
|
482
|
+
async function pairMonitorAgent(hubUrl, licenseKey, domain, envFile) {
|
|
483
|
+
if (!hubUrl || !licenseKey || !domain) {
|
|
484
|
+
return { paired: false, error: "Missing hubUrl, licenseKey, or domain for monitor pairing" };
|
|
485
|
+
}
|
|
486
|
+
const registrationUrl = `${hubUrl.replace(/\/+$/, "")}/api/register-agent`;
|
|
487
|
+
try {
|
|
488
|
+
const res = await fetch(registrationUrl, {
|
|
489
|
+
method: "POST",
|
|
490
|
+
headers: {
|
|
491
|
+
"content-type": "application/json",
|
|
492
|
+
authorization: `Bearer ${licenseKey}`
|
|
493
|
+
},
|
|
494
|
+
body: JSON.stringify({ name: domain, host: domain, port: 45876 }),
|
|
495
|
+
signal: AbortSignal.timeout(15e3)
|
|
496
|
+
});
|
|
497
|
+
if (!res.ok) {
|
|
498
|
+
const body = await res.text().catch(() => "");
|
|
499
|
+
return { paired: false, error: `Monitor hub returned HTTP ${res.status}: ${body}` };
|
|
500
|
+
}
|
|
501
|
+
const data = await res.json();
|
|
502
|
+
if (!data.token || !data.key) {
|
|
503
|
+
return { paired: false, error: "Monitor hub response missing token or key" };
|
|
504
|
+
}
|
|
505
|
+
if (existsSync4(envFile)) {
|
|
506
|
+
const envRaw = readFileSync3(envFile, "utf8");
|
|
507
|
+
const patched = patchEnv(envRaw, {
|
|
508
|
+
MONITOR_AGENT_TOKEN: data.token,
|
|
509
|
+
MONITOR_AGENT_KEY: data.key
|
|
510
|
+
});
|
|
511
|
+
if (patched !== envRaw) {
|
|
512
|
+
writeFileSync2(envFile, patched, { mode: 384 });
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return { paired: true, systemName: data.name ?? domain };
|
|
516
|
+
} catch (err) {
|
|
517
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
518
|
+
return { paired: false, error: `Monitor hub unreachable: ${reason}` };
|
|
519
|
+
}
|
|
520
|
+
}
|
|
482
521
|
function bootstrapStackHost(options) {
|
|
483
522
|
const exec = options.exec ?? defaultExec;
|
|
484
523
|
const createdFiles = [];
|
|
@@ -551,6 +590,24 @@ async function runStackUpdate(options) {
|
|
|
551
590
|
const report = bootstrapStackHost({ ...options, installDocker: options.installDocker ?? !!options.yes });
|
|
552
591
|
if (!options.dryRun) assertHostReadyForApply(report);
|
|
553
592
|
}
|
|
593
|
+
const hubUrl = options.monitorHubUrl || parseEnv(readFileSync3(options.envFile, "utf8")).get("MONITOR_HUB_URL") || "";
|
|
594
|
+
const pairLicense = options.licenseKey || process.env.EXE_LICENSE_KEY || loadLicense() || "";
|
|
595
|
+
const pairDomain = options.domain || process.env.EXE_STACK_DOMAIN || process.env.CUSTOMER_DOMAIN || "";
|
|
596
|
+
if (hubUrl && pairLicense && pairDomain) {
|
|
597
|
+
const envBefore = readFileSync3(options.envFile, "utf8");
|
|
598
|
+
const hasPlaceholder = /CHANGEME/.test(parseEnv(envBefore).get("MONITOR_AGENT_TOKEN") ?? "");
|
|
599
|
+
if (hasPlaceholder) {
|
|
600
|
+
const pair = options.pairMonitor ? options.pairMonitor(hubUrl, pairLicense, pairDomain, options.envFile) : pairMonitorAgent(hubUrl, pairLicense, pairDomain, options.envFile);
|
|
601
|
+
const result = await pair;
|
|
602
|
+
if (typeof result === "object" && result && "paired" in result) {
|
|
603
|
+
if (result.paired) {
|
|
604
|
+
console.log(`[stack-update] Monitor agent paired: ${result.systemName}`);
|
|
605
|
+
} else {
|
|
606
|
+
console.warn(`[stack-update] Monitor pairing skipped: ${result.error}`);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
554
611
|
const manifest = await loadStackManifest(options.manifestRef, options.fetchText, options.manifestPublicKey, options.manifestAuthToken);
|
|
555
612
|
const envRaw = readFileSync3(options.envFile, "utf8");
|
|
556
613
|
const plan = createStackUpdatePlan(manifest, envRaw, options.targetVersion);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.93",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|