feat: add OpenProse plugin skills
This commit is contained in:
61
src/agents/skills/plugin-skills.ts
Normal file
61
src/agents/skills/plugin-skills.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import {
|
||||
normalizePluginsConfig,
|
||||
resolveEnableState,
|
||||
resolveMemorySlotDecision,
|
||||
} from "../../plugins/config-state.js";
|
||||
import { loadPluginManifestRegistry } from "../../plugins/manifest-registry.js";
|
||||
|
||||
const log = createSubsystemLogger("skills");
|
||||
|
||||
export function resolvePluginSkillDirs(params: {
|
||||
workspaceDir: string;
|
||||
config?: ClawdbotConfig;
|
||||
}): string[] {
|
||||
const workspaceDir = params.workspaceDir.trim();
|
||||
if (!workspaceDir) return [];
|
||||
const registry = loadPluginManifestRegistry({
|
||||
workspaceDir,
|
||||
config: params.config,
|
||||
});
|
||||
if (registry.plugins.length === 0) return [];
|
||||
const normalizedPlugins = normalizePluginsConfig(params.config?.plugins);
|
||||
const memorySlot = normalizedPlugins.slots.memory;
|
||||
let selectedMemoryPluginId: string | null = null;
|
||||
const seen = new Set<string>();
|
||||
const resolved: string[] = [];
|
||||
|
||||
for (const record of registry.plugins) {
|
||||
if (!record.skills || record.skills.length === 0) continue;
|
||||
const enableState = resolveEnableState(record.id, record.origin, normalizedPlugins);
|
||||
if (!enableState.enabled) continue;
|
||||
const memoryDecision = resolveMemorySlotDecision({
|
||||
id: record.id,
|
||||
kind: record.kind,
|
||||
slot: memorySlot,
|
||||
selectedId: selectedMemoryPluginId,
|
||||
});
|
||||
if (!memoryDecision.enabled) continue;
|
||||
if (memoryDecision.selected && record.kind === "memory") {
|
||||
selectedMemoryPluginId = record.id;
|
||||
}
|
||||
for (const raw of record.skills) {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) continue;
|
||||
const candidate = path.resolve(record.rootDir, trimmed);
|
||||
if (!fs.existsSync(candidate)) {
|
||||
log.warn(`plugin skill path not found (${record.id}): ${candidate}`);
|
||||
continue;
|
||||
}
|
||||
if (seen.has(candidate)) continue;
|
||||
seen.add(candidate);
|
||||
resolved.push(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import chokidar, { type FSWatcher } from "chokidar";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import { CONFIG_DIR, resolveUserPath } from "../../utils.js";
|
||||
import { resolvePluginSkillDirs } from "./plugin-skills.js";
|
||||
|
||||
type SkillsChangeEvent = {
|
||||
workspaceDir?: string;
|
||||
@@ -59,6 +60,8 @@ function resolveWatchPaths(workspaceDir: string, config?: ClawdbotConfig): strin
|
||||
.filter(Boolean)
|
||||
.map((dir) => resolveUserPath(dir));
|
||||
paths.push(...extraDirs);
|
||||
const pluginSkillDirs = resolvePluginSkillDirs({ workspaceDir, config });
|
||||
paths.push(...pluginSkillDirs);
|
||||
return paths;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
resolveClawdbotMetadata,
|
||||
resolveSkillInvocationPolicy,
|
||||
} from "./frontmatter.js";
|
||||
import { resolvePluginSkillDirs } from "./plugin-skills.js";
|
||||
import { serializeByKey } from "./serialize.js";
|
||||
import type {
|
||||
ParsedSkillFrontmatter,
|
||||
@@ -120,6 +121,11 @@ function loadSkillEntries(
|
||||
const extraDirs = extraDirsRaw
|
||||
.map((d) => (typeof d === "string" ? d.trim() : ""))
|
||||
.filter(Boolean);
|
||||
const pluginSkillDirs = resolvePluginSkillDirs({
|
||||
workspaceDir,
|
||||
config: opts?.config,
|
||||
});
|
||||
const mergedExtraDirs = [...extraDirs, ...pluginSkillDirs];
|
||||
|
||||
const bundledSkills = bundledSkillsDir
|
||||
? loadSkills({
|
||||
@@ -127,7 +133,7 @@ function loadSkillEntries(
|
||||
source: "clawdbot-bundled",
|
||||
})
|
||||
: [];
|
||||
const extraSkills = extraDirs.flatMap((dir) => {
|
||||
const extraSkills = mergedExtraDirs.flatMap((dir) => {
|
||||
const resolved = resolveUserPath(dir);
|
||||
return loadSkills({
|
||||
dir: resolved,
|
||||
|
||||
Reference in New Issue
Block a user