import os from "node:os"; import path from "node:path"; import chokidar, { type FSWatcher } from "chokidar"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { createSubsystemLogger } from "../../logging/subsystem.js"; import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { CONFIG_DIR, resolveUserPath } from "../../utils.js"; import { resolvePluginSkillDirs } from "./plugin-skills.js"; import {
type SkillsChangeEvent,
bumpSkillsSnapshotVersion,
getSkillsSnapshotVersion,
registerSkillsChangeListener,
resetSkillsRefreshStateForTest,
setSkillsChangeListenerErrorHandler,
shouldRefreshSnapshotForVersion,
} from "./refresh-state.js";
export {
bumpSkillsSnapshotVersion,
getSkillsSnapshotVersion,
registerSkillsChangeListener,
shouldRefreshSnapshotForVersion,
type SkillsChangeEvent,
} from "./refresh-state.js";
function toWatchGlobRoot(raw: string): string { // Chokidar treats globs as POSIX-ish patterns. Normalize Windows separators // so `*` works consistently across platforms. return raw.replaceAll("\\", "/").replace(/\/+$/, "");
}
function resolveWatchTargets(workspaceDir: string, config?: OpenClawConfig): string[] { // Skills are defined by SKILL.md; watch only those files to avoid traversing // or watching unrelated large trees (e.g. datasets) that can exhaust FDs. const targets = new Set<string>(); for (const root of resolveWatchPaths(workspaceDir, config)) { const globRoot = toWatchGlobRoot(root); // Some configs point directly at a skill folder.
targets.add(`${globRoot}/SKILL.md`); // Standard layout: <skillsRoot>/<skillName>/SKILL.md
targets.add(`${globRoot}/*/SKILL.md`);
} return Array.from(targets).toSorted();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.