openclaw-openviking-setup-helper 0.2.16-dev.4 → 0.3.0-beta.10
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/install.js +162 -24
- package/package.json +1 -1
package/install.js
CHANGED
|
@@ -97,9 +97,9 @@ let rollbackLastUpgrade = false;
|
|
|
97
97
|
let showCurrentVersion = false;
|
|
98
98
|
|
|
99
99
|
const selectedMode = "remote";
|
|
100
|
-
let remoteBaseUrl = "http://127.0.0.1:1933";
|
|
101
|
-
let remoteApiKey = "";
|
|
102
|
-
let remoteAgentPrefix = "";
|
|
100
|
+
let remoteBaseUrl = (process.env.OPENVIKING_BASE_URL || "http://127.0.0.1:1933").trim();
|
|
101
|
+
let remoteApiKey = (process.env.OPENVIKING_API_KEY || "").trim();
|
|
102
|
+
let remoteAgentPrefix = (process.env.OPENVIKING_AGENT_PREFIX || "").trim();
|
|
103
103
|
let upgradeRuntimeConfig = null;
|
|
104
104
|
let installedUpgradeState = null;
|
|
105
105
|
let upgradeAudit = null;
|
|
@@ -874,8 +874,9 @@ function extractRuntimeConfigFromPluginEntry(entryConfig) {
|
|
|
874
874
|
if (typeof entryConfig.apiKey === "string" && entryConfig.apiKey.trim()) {
|
|
875
875
|
runtime.apiKey = entryConfig.apiKey;
|
|
876
876
|
}
|
|
877
|
-
|
|
878
|
-
|
|
877
|
+
const prefix = entryConfig.agent_prefix || entryConfig.agentId;
|
|
878
|
+
if (typeof prefix === "string" && prefix.trim()) {
|
|
879
|
+
runtime.agent_prefix = prefix.trim();
|
|
879
880
|
}
|
|
880
881
|
return runtime;
|
|
881
882
|
}
|
|
@@ -1417,6 +1418,7 @@ async function configureOpenClawPlugin({
|
|
|
1417
1418
|
const pluginSlot = resolvedPluginSlot;
|
|
1418
1419
|
|
|
1419
1420
|
const ocEnv = getOpenClawEnv();
|
|
1421
|
+
const needWorkdirFlag = OPENCLAW_DIR !== DEFAULT_OPENCLAW_DIR;
|
|
1420
1422
|
|
|
1421
1423
|
const oc = async (args) => {
|
|
1422
1424
|
const result = await runCapture("openclaw", args, { env: ocEnv, shell: IS_WIN });
|
|
@@ -1427,24 +1429,59 @@ async function configureOpenClawPlugin({
|
|
|
1427
1429
|
return result;
|
|
1428
1430
|
};
|
|
1429
1431
|
|
|
1432
|
+
// Direct file manipulation for config (reliable across all OpenClaw versions and --workdir scenarios).
|
|
1433
|
+
// OpenClaw CLI's --workdir / OPENCLAW_STATE_DIR support is inconsistent, so we read/write openclaw.json directly.
|
|
1434
|
+
const configPath = getOpenClawConfigPath();
|
|
1435
|
+
const readCfg = async () => {
|
|
1436
|
+
if (!existsSync(configPath)) return {};
|
|
1437
|
+
try { return JSON.parse(await readFile(configPath, "utf8")); } catch { return {}; }
|
|
1438
|
+
};
|
|
1439
|
+
const writeCfg = async (cfg) => {
|
|
1440
|
+
const out = JSON.stringify(cfg, null, 2) + "\n";
|
|
1441
|
+
const tmp = `${configPath}.ov-install-tmp.${process.pid}`;
|
|
1442
|
+
await writeFile(tmp, out, "utf8");
|
|
1443
|
+
await rename(tmp, configPath);
|
|
1444
|
+
};
|
|
1445
|
+
const ensurePluginRegistered = async (cfg) => {
|
|
1446
|
+
if (!cfg.plugins) cfg.plugins = {};
|
|
1447
|
+
const p = cfg.plugins;
|
|
1448
|
+
if (!p.entries) p.entries = {};
|
|
1449
|
+
if (!p.entries[pluginId]) p.entries[pluginId] = {};
|
|
1450
|
+
if (!p.entries[pluginId].config) p.entries[pluginId].config = {};
|
|
1451
|
+
if (!Array.isArray(p.allow)) p.allow = [];
|
|
1452
|
+
if (!p.allow.includes(pluginId)) p.allow.push(pluginId);
|
|
1453
|
+
return cfg;
|
|
1454
|
+
};
|
|
1455
|
+
|
|
1430
1456
|
if (!preserveExistingConfig) {
|
|
1431
1457
|
await scrubStaleOpenClawPluginRegistration();
|
|
1432
1458
|
}
|
|
1433
1459
|
|
|
1434
|
-
// Enable plugin (
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1460
|
+
// Enable plugin: try CLI first (default path), fall back to direct file for --workdir
|
|
1461
|
+
if (!needWorkdirFlag) {
|
|
1462
|
+
try {
|
|
1463
|
+
await oc(["plugins", "enable", pluginId]);
|
|
1464
|
+
} catch (_e) {
|
|
1465
|
+
info(tr("plugins enable via CLI failed, registering directly", "CLI plugins enable 失败,直接注册"));
|
|
1466
|
+
const cfg = await readCfg();
|
|
1467
|
+
await ensurePluginRegistered(cfg);
|
|
1468
|
+
await writeCfg(cfg);
|
|
1469
|
+
}
|
|
1438
1470
|
} else {
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
),
|
|
1444
|
-
);
|
|
1471
|
+
info(tr("Using direct config write for non-default workdir", "非默认目录,使用直接配置写入"));
|
|
1472
|
+
const cfg = await readCfg();
|
|
1473
|
+
await ensurePluginRegistered(cfg);
|
|
1474
|
+
await writeCfg(cfg);
|
|
1445
1475
|
}
|
|
1446
1476
|
|
|
1447
1477
|
if (preserveExistingConfig) {
|
|
1478
|
+
if (claimSlot) {
|
|
1479
|
+
const cfg = await readCfg();
|
|
1480
|
+
if (!cfg.plugins) cfg.plugins = {};
|
|
1481
|
+
if (!cfg.plugins.slots) cfg.plugins.slots = {};
|
|
1482
|
+
cfg.plugins.slots[pluginSlot] = pluginId;
|
|
1483
|
+
await writeCfg(cfg);
|
|
1484
|
+
}
|
|
1448
1485
|
info(
|
|
1449
1486
|
tr(
|
|
1450
1487
|
`Preserved existing plugin runtime config for ${pluginId}`,
|
|
@@ -1454,28 +1491,129 @@ async function configureOpenClawPlugin({
|
|
|
1454
1491
|
return;
|
|
1455
1492
|
}
|
|
1456
1493
|
|
|
1494
|
+
const writeConfigDirect = async (pluginConfig, slotValue) => {
|
|
1495
|
+
const cfg = await readCfg();
|
|
1496
|
+
await ensurePluginRegistered(cfg);
|
|
1497
|
+
Object.assign(cfg.plugins.entries[pluginId].config, pluginConfig);
|
|
1498
|
+
if (slotValue) {
|
|
1499
|
+
if (!cfg.plugins.slots) cfg.plugins.slots = {};
|
|
1500
|
+
cfg.plugins.slots[pluginSlot] = slotValue;
|
|
1501
|
+
}
|
|
1502
|
+
await writeCfg(cfg);
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
// Legacy (memory) plugins: direct JSON write
|
|
1506
|
+
if (resolvedPluginKind === "memory") {
|
|
1507
|
+
const effectiveRuntimeConfig = runtimeConfig || {
|
|
1508
|
+
baseUrl: remoteBaseUrl,
|
|
1509
|
+
apiKey: remoteApiKey,
|
|
1510
|
+
};
|
|
1511
|
+
const pluginConfig = {
|
|
1512
|
+
baseUrl: effectiveRuntimeConfig.baseUrl || remoteBaseUrl,
|
|
1513
|
+
targetUri: "viking://user/memories",
|
|
1514
|
+
autoRecall: true,
|
|
1515
|
+
autoCapture: true,
|
|
1516
|
+
};
|
|
1517
|
+
if (effectiveRuntimeConfig.apiKey) {
|
|
1518
|
+
pluginConfig.apiKey = effectiveRuntimeConfig.apiKey;
|
|
1519
|
+
}
|
|
1520
|
+
await writeConfigDirect(pluginConfig, claimSlot ? pluginId : null);
|
|
1521
|
+
info(tr("OpenClaw plugin configured (legacy mode)", "OpenClaw 插件配置完成(旧版模式)"));
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
// Current (context-engine) plugins: delegate to `openclaw openviking setup --json`
|
|
1526
|
+
// This reuses the same validation logic (health check, version compat, root key
|
|
1527
|
+
// detection, slot protection, ensureInstallRecord) from commands/setup.ts
|
|
1457
1528
|
const effectiveRuntimeConfig = runtimeConfig || {
|
|
1458
1529
|
baseUrl: remoteBaseUrl,
|
|
1459
1530
|
apiKey: remoteApiKey,
|
|
1460
1531
|
agent_prefix: remoteAgentPrefix,
|
|
1461
1532
|
};
|
|
1462
1533
|
|
|
1463
|
-
|
|
1534
|
+
const setupArgs = needWorkdirFlag
|
|
1535
|
+
? ["--workdir", OPENCLAW_DIR, "openviking", "setup"]
|
|
1536
|
+
: ["openviking", "setup"];
|
|
1537
|
+
setupArgs.push("--base-url", effectiveRuntimeConfig.baseUrl || remoteBaseUrl);
|
|
1538
|
+
setupArgs.push("--json");
|
|
1464
1539
|
if (effectiveRuntimeConfig.apiKey) {
|
|
1465
|
-
|
|
1540
|
+
setupArgs.push("--api-key", effectiveRuntimeConfig.apiKey);
|
|
1466
1541
|
}
|
|
1467
1542
|
if (effectiveRuntimeConfig.agent_prefix) {
|
|
1468
|
-
|
|
1543
|
+
setupArgs.push("--agent-id", effectiveRuntimeConfig.agent_prefix);
|
|
1544
|
+
}
|
|
1545
|
+
if (claimSlot) {
|
|
1546
|
+
setupArgs.push("--force-slot");
|
|
1547
|
+
}
|
|
1548
|
+
if (installYes) {
|
|
1549
|
+
setupArgs.push("--allow-offline");
|
|
1469
1550
|
}
|
|
1470
1551
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1552
|
+
info(tr(
|
|
1553
|
+
"Delegating configuration to: openclaw openviking setup --json",
|
|
1554
|
+
"委托配置给: openclaw openviking setup --json",
|
|
1555
|
+
));
|
|
1556
|
+
|
|
1557
|
+
const setupResult = await runCapture("openclaw", setupArgs, { env: ocEnv, shell: IS_WIN });
|
|
1558
|
+
|
|
1559
|
+
let parsed = null;
|
|
1560
|
+
try {
|
|
1561
|
+
parsed = JSON.parse(setupResult.out.trim());
|
|
1562
|
+
} catch {
|
|
1563
|
+
// If JSON parse fails, fall back to checking exit code
|
|
1476
1564
|
}
|
|
1477
1565
|
|
|
1478
|
-
|
|
1566
|
+
if (parsed) {
|
|
1567
|
+
if (parsed.success) {
|
|
1568
|
+
info(tr("OpenClaw plugin configured via setup", "OpenClaw 插件通过 setup 配置完成"));
|
|
1569
|
+
if (parsed.health?.ok) {
|
|
1570
|
+
info(tr(
|
|
1571
|
+
`Server health: OK${parsed.health.version ? ` (version: ${parsed.health.version})` : ""}`,
|
|
1572
|
+
`服务端健康: OK${parsed.health.version ? `(版本: ${parsed.health.version})` : ""}`,
|
|
1573
|
+
));
|
|
1574
|
+
}
|
|
1575
|
+
if (parsed.health?.compatibility === "server_too_old") {
|
|
1576
|
+
warn(tr(
|
|
1577
|
+
"Server version may be too old for this plugin version",
|
|
1578
|
+
"服务端版本可能低于此插件版本要求",
|
|
1579
|
+
));
|
|
1580
|
+
}
|
|
1581
|
+
if (parsed.slot?.activated) {
|
|
1582
|
+
info(tr(`contextEngine slot activated`, `contextEngine slot 已激活`));
|
|
1583
|
+
}
|
|
1584
|
+
} else {
|
|
1585
|
+
// Setup returned success: false
|
|
1586
|
+
if (parsed.action === "slot_blocked") {
|
|
1587
|
+
warn(tr(
|
|
1588
|
+
`Config saved but contextEngine slot is owned by "${parsed.slot?.previousOwner}". Use --force-slot to override.`,
|
|
1589
|
+
`配置已保存,但 contextEngine slot 被 "${parsed.slot?.previousOwner}" 占用。使用 --force-slot 覆盖。`,
|
|
1590
|
+
));
|
|
1591
|
+
} else {
|
|
1592
|
+
err(tr(
|
|
1593
|
+
`Setup failed: ${parsed.error || "unknown error"}`,
|
|
1594
|
+
`配置失败: ${parsed.error || "未知错误"}`,
|
|
1595
|
+
));
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
} else if (setupResult.code !== 0) {
|
|
1599
|
+
// JSON parse failed and non-zero exit — setup CLI not available (old plugin version)
|
|
1600
|
+
warn(tr(
|
|
1601
|
+
`openclaw openviking setup exited with code ${setupResult.code}. Falling back to direct JSON config write.`,
|
|
1602
|
+
`openclaw openviking setup 退出码 ${setupResult.code},回退到直接写入 JSON 配置。`,
|
|
1603
|
+
));
|
|
1604
|
+
const pluginConfig = {
|
|
1605
|
+
baseUrl: effectiveRuntimeConfig.baseUrl || remoteBaseUrl,
|
|
1606
|
+
apiKey: effectiveRuntimeConfig.apiKey || "",
|
|
1607
|
+
agent_prefix: effectiveRuntimeConfig.agent_prefix || "",
|
|
1608
|
+
};
|
|
1609
|
+
await writeConfigDirect(pluginConfig, claimSlot ? pluginId : null);
|
|
1610
|
+
info(tr(
|
|
1611
|
+
`OpenClaw plugin configured (direct write): baseUrl=${pluginConfig.baseUrl}, apiKey=${pluginConfig.apiKey ? "***" : "(empty)"}, agent_prefix=${pluginConfig.agent_prefix || "(empty)"}`,
|
|
1612
|
+
`OpenClaw 插件配置完成(直接写入): baseUrl=${pluginConfig.baseUrl}, apiKey=${pluginConfig.apiKey ? "***" : "(空)"}, agent_prefix=${pluginConfig.agent_prefix || "(空)"}`,
|
|
1613
|
+
));
|
|
1614
|
+
} else {
|
|
1615
|
+
info(tr("OpenClaw plugin configured", "OpenClaw 插件配置完成"));
|
|
1616
|
+
}
|
|
1479
1617
|
}
|
|
1480
1618
|
|
|
1481
1619
|
async function writeOpenvikingEnv() {
|