@gguf/claw
Version:
Multi-channel AI gateway with extensible messaging integrations
194 lines (191 loc) • 7.56 kB
JavaScript
import "./paths-B4BZAPZh.js";
import { B as theme, O as danger } from "./utils-CP9YLh6M.js";
import "./registry-B-j4DRfe.js";
import { f as defaultRuntime } from "./subsystem-BCQGGxdd.js";
import "./exec-DYqRzFbo.js";
import "./agent-scope-BnZW9Gh2.js";
import { kt as ensureAuthProfileStore, l as normalizeProviderId } from "./model-selection-CqaTAlhy.js";
import "./github-copilot-token-D2zp6kMZ.js";
import "./boolean-BsqeuxE6.js";
import "./env-VriqyjXT.js";
import "./message-channel-Bena1Tzd.js";
import "./config-PQiujvsf.js";
import "./manifest-registry-4k4vkhPS.js";
import "./client-BdSkEtCd.js";
import "./call-BCz_8mqq.js";
import "./pairing-token-B-_eiWlR.js";
import { t as formatDocsLink } from "./links-BVCMOGeE.js";
import "./progress-CaVMHLaE.js";
import { n as callGatewayFromCli, t as addGatewayClientOptions } from "./gateway-rpc-BM7hekCw.js";
import path from "node:path";
import fs from "node:fs/promises";
//#region src/agents/pi-auth-json.ts
async function readAuthJson(filePath) {
try {
const raw = await fs.readFile(filePath, "utf8");
const parsed = JSON.parse(raw);
if (!parsed || typeof parsed !== "object") return {};
return parsed;
} catch {
return {};
}
}
/**
* Convert an OpenClaw auth-profiles credential to pi-coding-agent auth.json format.
* Returns null if the credential cannot be converted.
*/
function convertCredential(cred) {
if (cred.type === "api_key") {
const key = typeof cred.key === "string" ? cred.key.trim() : "";
if (!key) return null;
return {
type: "api_key",
key
};
}
if (cred.type === "token") {
const token = typeof cred.token === "string" ? cred.token.trim() : "";
if (!token) return null;
const expires = typeof cred.expires === "number" ? cred.expires : NaN;
if (Number.isFinite(expires) && expires > 0 && Date.now() >= expires) return null;
return {
type: "api_key",
key: token
};
}
if (cred.type === "oauth") {
const accessRaw = cred.access;
const refreshRaw = cred.refresh;
const expiresRaw = cred.expires;
const access = typeof accessRaw === "string" ? accessRaw.trim() : "";
const refresh = typeof refreshRaw === "string" ? refreshRaw.trim() : "";
const expires = typeof expiresRaw === "number" ? expiresRaw : NaN;
if (!access || !refresh || !Number.isFinite(expires) || expires <= 0) return null;
return {
type: "oauth",
access,
refresh,
expires
};
}
return null;
}
/**
* Check if two auth.json credentials are equivalent.
*/
function credentialsEqual(a, b) {
if (!a || typeof a !== "object") return false;
if (a.type !== b.type) return false;
if (a.type === "api_key" && b.type === "api_key") return a.key === b.key;
if (a.type === "oauth" && b.type === "oauth") return a.access === b.access && a.refresh === b.refresh && a.expires === b.expires;
return false;
}
/**
* pi-coding-agent's ModelRegistry/AuthStorage expects credentials in auth.json.
*
* OpenClaw stores credentials in auth-profiles.json instead. This helper
* bridges all credentials into agentDir/auth.json so pi-coding-agent can
* (a) consider providers authenticated and (b) include built-in models in its
* registry/catalog output.
*
* Syncs all credential types: api_key, token (as api_key), and oauth.
*/
async function ensurePiAuthJsonFromAuthProfiles(agentDir) {
const store = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
const authPath = path.join(agentDir, "auth.json");
const providerCredentials = /* @__PURE__ */ new Map();
for (const [, cred] of Object.entries(store.profiles)) {
const provider = normalizeProviderId(String(cred.provider ?? "")).trim();
if (!provider || providerCredentials.has(provider)) continue;
const converted = convertCredential(cred);
if (converted) providerCredentials.set(provider, converted);
}
if (providerCredentials.size === 0) return {
wrote: false,
authPath
};
const existing = await readAuthJson(authPath);
let changed = false;
for (const [provider, cred] of providerCredentials) if (!credentialsEqual(existing[provider], cred)) {
existing[provider] = cred;
changed = true;
}
if (!changed) return {
wrote: false,
authPath
};
await fs.mkdir(agentDir, {
recursive: true,
mode: 448
});
await fs.writeFile(authPath, `${JSON.stringify(existing, null, 2)}\n`, { mode: 384 });
return {
wrote: true,
authPath
};
}
//#endregion
//#region src/cli/system-cli.ts
const normalizeWakeMode = (raw) => {
const mode = typeof raw === "string" ? raw.trim() : "";
if (!mode) return "next-heartbeat";
if (mode === "now" || mode === "next-heartbeat") return mode;
throw new Error("--mode must be now or next-heartbeat");
};
function registerSystemCli(program) {
const system = program.command("system").description("System tools (events, heartbeat, presence)").addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/system", "docs.openclaw.ai/cli/system")}\n`);
addGatewayClientOptions(system.command("event").description("Enqueue a system event and optionally trigger a heartbeat").requiredOption("--text <text>", "System event text").option("--mode <mode>", "Wake mode (now|next-heartbeat)", "next-heartbeat").option("--json", "Output JSON", false)).action(async (opts) => {
try {
const text = typeof opts.text === "string" ? opts.text.trim() : "";
if (!text) throw new Error("--text is required");
const result = await callGatewayFromCli("wake", opts, {
mode: normalizeWakeMode(opts.mode),
text
}, { expectFinal: false });
if (opts.json) defaultRuntime.log(JSON.stringify(result, null, 2));
else defaultRuntime.log("ok");
} catch (err) {
defaultRuntime.error(danger(String(err)));
defaultRuntime.exit(1);
}
});
const heartbeat = system.command("heartbeat").description("Heartbeat controls");
addGatewayClientOptions(heartbeat.command("last").description("Show the last heartbeat event").option("--json", "Output JSON", false)).action(async (opts) => {
try {
const result = await callGatewayFromCli("last-heartbeat", opts, void 0, { expectFinal: false });
defaultRuntime.log(JSON.stringify(result, null, 2));
} catch (err) {
defaultRuntime.error(danger(String(err)));
defaultRuntime.exit(1);
}
});
addGatewayClientOptions(heartbeat.command("enable").description("Enable heartbeats").option("--json", "Output JSON", false)).action(async (opts) => {
try {
const result = await callGatewayFromCli("set-heartbeats", opts, { enabled: true }, { expectFinal: false });
defaultRuntime.log(JSON.stringify(result, null, 2));
} catch (err) {
defaultRuntime.error(danger(String(err)));
defaultRuntime.exit(1);
}
});
addGatewayClientOptions(heartbeat.command("disable").description("Disable heartbeats").option("--json", "Output JSON", false)).action(async (opts) => {
try {
const result = await callGatewayFromCli("set-heartbeats", opts, { enabled: false }, { expectFinal: false });
defaultRuntime.log(JSON.stringify(result, null, 2));
} catch (err) {
defaultRuntime.error(danger(String(err)));
defaultRuntime.exit(1);
}
});
addGatewayClientOptions(system.command("presence").description("List system presence entries").option("--json", "Output JSON", false)).action(async (opts) => {
try {
const result = await callGatewayFromCli("system-presence", opts, void 0, { expectFinal: false });
defaultRuntime.log(JSON.stringify(result, null, 2));
} catch (err) {
defaultRuntime.error(danger(String(err)));
defaultRuntime.exit(1);
}
});
}
//#endregion
export { registerSystemCli, ensurePiAuthJsonFromAuthProfiles as t };