mirror of
https://github.com/volcengine/OpenViking.git
synced 2026-09-29 04:02:57 +08:00
115 lines
4.1 KiB
JavaScript
Generated
115 lines
4.1 KiB
JavaScript
Generated
// GENERATED FROM examples/memory-plugin-shared/lib. DO NOT EDIT.
|
|
/**
|
|
* Interactive ovcli.conf setup wizard shared by the OpenViking memory plugins.
|
|
*
|
|
* Lets a pure-marketplace install (no installer script) configure the server
|
|
* URL and API key that both the lifecycle hooks and the stdio MCP proxy read:
|
|
*
|
|
* node <plugin>/scripts/setup.mjs
|
|
*
|
|
* Conventions: show current values, keep existing secrets on empty input,
|
|
* merge-write (never drop unknown fields), back up the previous file, 0600.
|
|
*/
|
|
|
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
|
|
import { dirname } from "node:path";
|
|
import { createInterface } from "node:readline/promises";
|
|
import { loadCredentialFiles } from "./credentials.mjs";
|
|
|
|
const CLOUD_URL = "https://api.vikingdb.cn-beijing.volces.com/openviking";
|
|
const LOCAL_URL = "http://127.0.0.1:1933";
|
|
|
|
function maskSecret(value) {
|
|
const s = String(value || "");
|
|
if (!s) return "(not set)";
|
|
if (s.length <= 8) return "****";
|
|
return `${s.slice(0, 4)}…${s.slice(-4)} (${s.length} chars)`;
|
|
}
|
|
|
|
function readJsonSafe(path) {
|
|
try {
|
|
return JSON.parse(readFileSync(path, "utf-8"));
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
export async function runSetupWizard({
|
|
input = process.stdin,
|
|
output = process.stdout,
|
|
env = process.env,
|
|
} = {}) {
|
|
// cliPath is empty until the file exists; first-run writes go to the candidate
|
|
// path (OPENVIKING_CLI_CONFIG_FILE, else ~/.openviking/ovcli.conf).
|
|
const { cliPath, cliPathCandidate } = loadCredentialFiles(env);
|
|
const targetPath = cliPath || cliPathCandidate;
|
|
const current = readJsonSafe(targetPath);
|
|
const rl = createInterface({ input, output });
|
|
const say = (line = "") => output.write(`${line}\n`);
|
|
|
|
try {
|
|
say("OpenViking memory plugin setup");
|
|
say(`Config file: ${targetPath}`);
|
|
say("");
|
|
say("Current values:");
|
|
say(` url: ${current.url || "(not set)"}`);
|
|
say(` api_key: ${maskSecret(current.api_key)}`);
|
|
if (current.account) say(` account: ${current.account}`);
|
|
if (current.user) say(` user: ${current.user}`);
|
|
say("");
|
|
|
|
const defaultUrl = current.url || LOCAL_URL;
|
|
say("Where do you connect to OpenViking?");
|
|
say(` 1) Self-hosted / local [${LOCAL_URL}]`);
|
|
say(` 2) Volcengine OpenViking Cloud [${CLOUD_URL}]`);
|
|
say(` 3) Custom URL / keep current [${defaultUrl}]`);
|
|
const mode = (await rl.question("Choice [1/2/3, default 3]: ")).trim();
|
|
let url = defaultUrl;
|
|
if (mode === "1") {
|
|
url = LOCAL_URL;
|
|
} else if (mode === "2") {
|
|
url = CLOUD_URL;
|
|
} else {
|
|
const answer = (await rl.question(`Server URL [${defaultUrl}]: `)).trim();
|
|
if (answer) url = answer;
|
|
}
|
|
|
|
const keyPrompt = current.api_key
|
|
? `API key [enter = keep ${maskSecret(current.api_key)}, '-' = clear]: `
|
|
: "API key (leave empty for unauthenticated local mode): ";
|
|
const keyAnswer = await rl.question(keyPrompt);
|
|
let apiKey = current.api_key || "";
|
|
if (keyAnswer === "-") apiKey = "";
|
|
else if (keyAnswer.trim()) apiKey = keyAnswer.trim();
|
|
else if (!current.api_key) apiKey = "";
|
|
|
|
const next = { ...current, url, api_key: apiKey };
|
|
|
|
say("");
|
|
say("Changes:");
|
|
say(` url: ${current.url || "(not set)"} -> ${next.url}`);
|
|
say(` api_key: ${maskSecret(current.api_key)} -> ${maskSecret(next.api_key)}`);
|
|
const confirm = (await rl.question("Write config? [Y/n] ")).trim().toLowerCase();
|
|
if (confirm === "n" || confirm === "no") {
|
|
say("Aborted; nothing written.");
|
|
return { written: false, path: targetPath };
|
|
}
|
|
|
|
mkdirSync(dirname(targetPath), { recursive: true });
|
|
if (existsSync(targetPath)) {
|
|
copyFileSync(targetPath, `${targetPath}.bak.${Date.now()}`);
|
|
}
|
|
writeFileSync(targetPath, `${JSON.stringify(next, null, 2)}\n`, { mode: 0o600 });
|
|
try {
|
|
chmodSync(targetPath, 0o600);
|
|
} catch {
|
|
/* best effort on platforms without chmod semantics */
|
|
}
|
|
say(`Written: ${targetPath}`);
|
|
say("The stdio MCP proxy and hooks pick this up on the next harness start.");
|
|
return { written: true, path: targetPath };
|
|
} finally {
|
|
rl.close();
|
|
}
|
|
}
|