48 lines
3.4 KiB
JavaScript
48 lines
3.4 KiB
JavaScript
// D2 scratch root (mos-0863 D2, mos-0847): the example file plus the plug-in keys, nothing live.
|
|
// Usage: node d2-build.mjs <harness> writes d2/config/{config.json,businesses/mosaic-stack.json}
|
|
import { chmodSync, mkdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { spawnSync } from "node:child_process";
|
|
const LAND = "/mnt/storage/scratch/sage-r64/land";
|
|
const D2 = "/mnt/storage/scratch/sage-r64/d2";
|
|
const harness = process.argv[2];
|
|
if (!["pi", "claude-code"].includes(harness)) throw new Error("harness?");
|
|
const FAR = "2099-01-01";
|
|
const secrets = join(D2, "secrets");
|
|
mkdirSync(secrets, { recursive: true, mode: 0o700 });
|
|
const w = (f, o) => { mkdirSync(join(f, ".."), { recursive: true }); writeFileSync(f, JSON.stringify(o, null, 2) + "\n"); };
|
|
const doc = JSON.parse(readFileSync(join(LAND, "packages/business/examples/mosaic-stack.example.json"), "utf8"));
|
|
const edits = [];
|
|
// Every /home/you token path and YYYY-MM-DD date becomes a stand-in file and a far date.
|
|
const walk = (o, at) => {
|
|
for (const [k, v] of Object.entries(o)) {
|
|
if (v && typeof v === "object") walk(v, `${at}.${k}`);
|
|
else if (k === "file" && typeof v === "string" && v.startsWith("/home/you/")) {
|
|
const f = join(secrets, v.split("/").pop());
|
|
writeFileSync(f, "placeholder-not-a-token"); chmodSync(f, 0o600);
|
|
o[k] = f; edits.push(`${at}.file -> stand-in`);
|
|
} else if ((k === "expires" || k === "rotateBy") && v === "YYYY-MM-DD") { o[k] = FAR; edits.push(`${at}.${k} -> ${FAR}`); }
|
|
}
|
|
};
|
|
walk(doc, "");
|
|
let n = 1; for (const r of Object.values(doc.roles)) if (r.tracker && "botId" in r.tracker) r.tracker.botId = n++;
|
|
if (doc.tracker?.sync && "botId" in doc.tracker.sync) doc.tracker.sync.botId = n++;
|
|
edits.push("botIds 1..n (example has 0)");
|
|
doc.vars["tracker.baseUrl"] = "http://127.0.0.1:9"; doc.vars["gitea.baseUrl"] = "http://127.0.0.1:9"; edits.push("baseUrls -> 127.0.0.1:9");
|
|
for (const m of Object.values(doc.launch.models)) m.provider = "anthropic";
|
|
doc.launch.limits.models = { anthropic: doc.launch.limits.models["your-provider"] }; edits.push("your-provider -> anthropic");
|
|
doc.roles.coder.vars = { ...doc.roles.coder.vars, harness, thinking: "medium" }; edits.push(`coder vars harness ${harness}, thinking medium`);
|
|
doc.plugins = { ...(doc.plugins ?? {}), harness: ["pi", "claude-code"] }; edits.push("plugins.harness [pi, claude-code]");
|
|
const project = join(D2, "project");
|
|
if (!existsSync(join(project, ".git"))) {
|
|
mkdirSync(project, { recursive: true });
|
|
const g = (...a) => { const r = spawnSync("git", ["-c", "user.name=d2", "-c", "[email protected]", "-C", project, ...a], { encoding: "utf8" }); if (r.status) throw new Error(r.stderr); };
|
|
g("init", "-q", "-b", "main"); writeFileSync(join(project, "README.md"), "D2 scratch project\n"); g("add", "README.md"); g("commit", "-q", "-m", "one");
|
|
}
|
|
doc.projects.stack.root = project; edits.push("projects.stack.root -> scratch repo on main");
|
|
w(join(D2, "config", "config.json"), { configVersion: 1, environment: "development", dataRoot: join(D2, harness === "pi" ? "datapi" : "data"),
|
|
execution: { backend: "docker", provider: "zai", model: "glm-5.3-flash", adapter: "mock" } });
|
|
w(join(D2, "config", "businesses", "mosaic-stack.json"), doc);
|
|
mkdirSync(join(D2, harness === "pi" ? "datapi" : "data"), { recursive: true, mode: 0o700 });
|
|
console.log(edits.join("\n"));
|