fix(openclaw): use sync plugin registration (#498)
Co-authored-by: Niemand Assistant <niemand@kessler.io>
This commit is contained in:
@@ -177,17 +177,16 @@ function buildOpenClawConfig(
|
|||||||
function generateEntryPoint(commands: OpenClawCommandRegistration[]): string {
|
function generateEntryPoint(commands: OpenClawCommandRegistration[]): string {
|
||||||
const commandRegistrations = commands
|
const commandRegistrations = commands
|
||||||
.map((cmd) => {
|
.map((cmd) => {
|
||||||
// JSON.stringify produces a fully-escaped string literal safe for JS/TS source embedding
|
|
||||||
const safeName = JSON.stringify(cmd.name)
|
const safeName = JSON.stringify(cmd.name)
|
||||||
const safeDesc = JSON.stringify(cmd.description ?? "")
|
const safeDesc = JSON.stringify(cmd.description ?? "")
|
||||||
const safeNotFound = JSON.stringify(`Command ${cmd.name} not found. Check skills directory.`)
|
const safeBody = JSON.stringify(cmd.body)
|
||||||
return ` api.registerCommand({
|
return ` api.registerCommand({
|
||||||
name: ${safeName},
|
name: ${safeName},
|
||||||
description: ${safeDesc},
|
description: ${safeDesc},
|
||||||
acceptsArgs: ${cmd.acceptsArgs},
|
acceptsArgs: ${cmd.acceptsArgs},
|
||||||
requireAuth: false,
|
requireAuth: false,
|
||||||
handler: (ctx) => ({
|
handler: () => ({
|
||||||
text: skills[${safeName}] ?? ${safeNotFound},
|
text: ${safeBody},
|
||||||
}),
|
}),
|
||||||
});`
|
});`
|
||||||
})
|
})
|
||||||
@@ -195,39 +194,7 @@ function generateEntryPoint(commands: OpenClawCommandRegistration[]): string {
|
|||||||
|
|
||||||
return `// Auto-generated OpenClaw plugin entry point
|
return `// Auto-generated OpenClaw plugin entry point
|
||||||
// Converted from Claude Code plugin format by compound-plugin CLI
|
// Converted from Claude Code plugin format by compound-plugin CLI
|
||||||
import { promises as fs } from "fs";
|
export default function register(api) {
|
||||||
import path from "path";
|
|
||||||
import { fileURLToPath } from "url";
|
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
||||||
|
|
||||||
// Pre-load skill bodies for command responses
|
|
||||||
const skills: Record<string, string> = {};
|
|
||||||
|
|
||||||
async function loadSkills() {
|
|
||||||
const skillsDir = path.join(__dirname, "skills");
|
|
||||||
try {
|
|
||||||
const entries = await fs.readdir(skillsDir, { withFileTypes: true });
|
|
||||||
for (const entry of entries) {
|
|
||||||
if (!entry.isDirectory()) continue;
|
|
||||||
const skillPath = path.join(skillsDir, entry.name, "SKILL.md");
|
|
||||||
try {
|
|
||||||
const content = await fs.readFile(skillPath, "utf8");
|
|
||||||
// Strip frontmatter
|
|
||||||
const body = content.replace(/^---[\\s\\S]*?---\\n*/, "");
|
|
||||||
skills[entry.name.replace(/^cmd-/, "")] = body.trim();
|
|
||||||
} catch {
|
|
||||||
// Skill file not found, skip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// Skills directory not found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function register(api) {
|
|
||||||
await loadSkills();
|
|
||||||
|
|
||||||
${commandRegistrations}
|
${commandRegistrations}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -231,9 +231,11 @@ describe("convertClaudeToOpenClaw", () => {
|
|||||||
expect(nameLine).toBeDefined()
|
expect(nameLine).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("generateEntryPoint emits typed skills record", () => {
|
test("generateEntryPoint inlines command bodies for sync registration", () => {
|
||||||
const bundle = convertClaudeToOpenClaw(fixturePlugin, defaultOptions)
|
const bundle = convertClaudeToOpenClaw(fixturePlugin, defaultOptions)
|
||||||
expect(bundle.entryPoint).toContain("const skills: Record<string, string> = {}")
|
expect(bundle.entryPoint).not.toContain("const skills: Record<string, string> = {}")
|
||||||
|
expect(bundle.entryPoint).toContain('text: "Plan the work. See ~/.openclaw/settings for config."')
|
||||||
|
expect(bundle.entryPoint).toContain("export default function register(api)")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("plugin without MCP servers has no openclawConfig", () => {
|
test("plugin without MCP servers has no openclawConfig", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user