UNPKG

@gguf/claw

Version:

WhatsApp gateway CLI (Baileys web) with Pi RPC agent

187 lines (184 loc) 7.29 kB
import { t as createSubsystemLogger } from "./subsystem-CAq3uyo7.js"; import { t as CONFIG_DIR } from "./utils-CKSrBNwq.js"; import { c as resolveBundledSkillsDir, d as hasBinary, f as isBundledSkillAllowed, g as resolveSkillConfig, h as resolveConfigPath, i as loadWorkspaceSkillEntries, m as resolveBundledAllowlist, p as isConfigPathTruthy, t as resolveSkillsInstallPreferences } from "./skills-D5JDj3TR.js"; import path from "node:path"; import { loadSkillsFromDir } from "@mariozechner/pi-coding-agent"; //#region src/agents/skills/bundled-context.ts const skillsLogger = createSubsystemLogger("skills"); let hasWarnedMissingBundledDir = false; function resolveBundledSkillsContext(opts = {}) { const dir = resolveBundledSkillsDir(opts); const names = /* @__PURE__ */ new Set(); if (!dir) { if (!hasWarnedMissingBundledDir) { hasWarnedMissingBundledDir = true; skillsLogger.warn("Bundled skills directory could not be resolved; built-in skills may be missing."); } return { dir, names }; } const result = loadSkillsFromDir({ dir, source: "openclaw-bundled" }); for (const skill of result.skills) if (skill.name.trim()) names.add(skill.name); return { dir, names }; } //#endregion //#region src/agents/skills-status.ts function resolveSkillKey(entry) { return entry.metadata?.skillKey ?? entry.skill.name; } function selectPreferredInstallSpec(install, prefs) { if (install.length === 0) return; const indexed = install.map((spec, index) => ({ spec, index })); const findKind = (kind) => indexed.find((item) => item.spec.kind === kind); const brewSpec = findKind("brew"); const nodeSpec = findKind("node"); const goSpec = findKind("go"); const uvSpec = findKind("uv"); if (prefs.preferBrew && hasBinary("brew") && brewSpec) return brewSpec; if (uvSpec) return uvSpec; if (nodeSpec) return nodeSpec; if (brewSpec) return brewSpec; if (goSpec) return goSpec; return indexed[0]; } function normalizeInstallOptions(entry, prefs) { const install = entry.metadata?.install ?? []; if (install.length === 0) return []; const platform = process.platform; const filtered = install.filter((spec) => { const osList = spec.os ?? []; return osList.length === 0 || osList.includes(platform); }); if (filtered.length === 0) return []; const toOption = (spec, index) => { const id = (spec.id ?? `${spec.kind}-${index}`).trim(); const bins = spec.bins ?? []; let label = (spec.label ?? "").trim(); if (spec.kind === "node" && spec.package) label = `Install ${spec.package} (${prefs.nodeManager})`; if (!label) if (spec.kind === "brew" && spec.formula) label = `Install ${spec.formula} (brew)`; else if (spec.kind === "node" && spec.package) label = `Install ${spec.package} (${prefs.nodeManager})`; else if (spec.kind === "go" && spec.module) label = `Install ${spec.module} (go)`; else if (spec.kind === "uv" && spec.package) label = `Install ${spec.package} (uv)`; else if (spec.kind === "download" && spec.url) { const url = spec.url.trim(); const last = url.split("/").pop(); label = `Download ${last && last.length > 0 ? last : url}`; } else label = "Run installer"; return { id, kind: spec.kind, label, bins }; }; if (filtered.every((spec) => spec.kind === "download")) return filtered.map((spec, index) => toOption(spec, index)); const preferred = selectPreferredInstallSpec(filtered, prefs); if (!preferred) return []; return [toOption(preferred.spec, preferred.index)]; } function buildSkillStatus(entry, config, prefs, eligibility, bundledNames) { const skillKey = resolveSkillKey(entry); const skillConfig = resolveSkillConfig(config, skillKey); const disabled = skillConfig?.enabled === false; const blockedByAllowlist = !isBundledSkillAllowed(entry, resolveBundledAllowlist(config)); const always = entry.metadata?.always === true; const emoji = entry.metadata?.emoji ?? entry.frontmatter.emoji; const homepageRaw = entry.metadata?.homepage ?? entry.frontmatter.homepage ?? entry.frontmatter.website ?? entry.frontmatter.url; const homepage = homepageRaw?.trim() ? homepageRaw.trim() : void 0; const bundled = bundledNames && bundledNames.size > 0 ? bundledNames.has(entry.skill.name) : entry.skill.source === "openclaw-bundled"; const requiredBins = entry.metadata?.requires?.bins ?? []; const requiredAnyBins = entry.metadata?.requires?.anyBins ?? []; const requiredEnv = entry.metadata?.requires?.env ?? []; const requiredConfig = entry.metadata?.requires?.config ?? []; const requiredOs = entry.metadata?.os ?? []; const missingBins = requiredBins.filter((bin) => { if (hasBinary(bin)) return false; if (eligibility?.remote?.hasBin?.(bin)) return false; return true; }); const missingAnyBins = requiredAnyBins.length > 0 && !(requiredAnyBins.some((bin) => hasBinary(bin)) || eligibility?.remote?.hasAnyBin?.(requiredAnyBins)) ? requiredAnyBins : []; const missingOs = requiredOs.length > 0 && !requiredOs.includes(process.platform) && !eligibility?.remote?.platforms?.some((platform) => requiredOs.includes(platform)) ? requiredOs : []; const missingEnv = []; for (const envName of requiredEnv) { if (process.env[envName]) continue; if (skillConfig?.env?.[envName]) continue; if (skillConfig?.apiKey && entry.metadata?.primaryEnv === envName) continue; missingEnv.push(envName); } const configChecks = requiredConfig.map((pathStr) => { return { path: pathStr, value: resolveConfigPath(config, pathStr), satisfied: isConfigPathTruthy(config, pathStr) }; }); const missingConfig = configChecks.filter((check) => !check.satisfied).map((check) => check.path); const missing = always ? { bins: [], anyBins: [], env: [], config: [], os: [] } : { bins: missingBins, anyBins: missingAnyBins, env: missingEnv, config: missingConfig, os: missingOs }; const eligible = !disabled && !blockedByAllowlist && (always || missing.bins.length === 0 && missing.anyBins.length === 0 && missing.env.length === 0 && missing.config.length === 0 && missing.os.length === 0); return { name: entry.skill.name, description: entry.skill.description, source: entry.skill.source, bundled, filePath: entry.skill.filePath, baseDir: entry.skill.baseDir, skillKey, primaryEnv: entry.metadata?.primaryEnv, emoji, homepage, always, disabled, blockedByAllowlist, eligible, requirements: { bins: requiredBins, anyBins: requiredAnyBins, env: requiredEnv, config: requiredConfig, os: requiredOs }, missing, configChecks, install: normalizeInstallOptions(entry, prefs ?? resolveSkillsInstallPreferences(config)) }; } function buildWorkspaceSkillStatus(workspaceDir, opts) { const managedSkillsDir = opts?.managedSkillsDir ?? path.join(CONFIG_DIR, "skills"); const bundledContext = resolveBundledSkillsContext(); const skillEntries = opts?.entries ?? loadWorkspaceSkillEntries(workspaceDir, { config: opts?.config, managedSkillsDir, bundledSkillsDir: bundledContext.dir }); const prefs = resolveSkillsInstallPreferences(opts?.config); return { workspaceDir, managedSkillsDir, skills: skillEntries.map((entry) => buildSkillStatus(entry, opts?.config, prefs, opts?.eligibility, bundledContext.names)) }; } //#endregion export { buildWorkspaceSkillStatus as t };