refactor(plugin): extract dirigent slash command and fix recursive prepare copy
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
"TASKLIST.md"
|
"TASKLIST.md"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "mkdir -p dist/dirigent && cp plugin/* dist/dirigent/",
|
"prepare": "mkdir -p dist/dirigent && cp -r plugin/* dist/dirigent/",
|
||||||
"postinstall": "node scripts/install-dirigent-openclaw.mjs --install",
|
"postinstall": "node scripts/install-dirigent-openclaw.mjs --install",
|
||||||
"uninstall": "node scripts/install-dirigent-openclaw.mjs --uninstall",
|
"uninstall": "node scripts/install-dirigent-openclaw.mjs --uninstall",
|
||||||
"update": "node scripts/install-dirigent-openclaw.mjs --update"
|
"update": "node scripts/install-dirigent-openclaw.mjs --update"
|
||||||
|
|||||||
59
plugin/commands/dirigent-command.ts
Normal file
59
plugin/commands/dirigent-command.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||||
|
import { advanceTurn, getTurnDebugInfo, resetTurn } from "../turn-manager.js";
|
||||||
|
|
||||||
|
type CommandDeps = {
|
||||||
|
api: OpenClawPluginApi;
|
||||||
|
policyState: { channelPolicies: Record<string, unknown> };
|
||||||
|
};
|
||||||
|
|
||||||
|
export function registerDirigentCommand(deps: CommandDeps): void {
|
||||||
|
const { api, policyState } = deps;
|
||||||
|
|
||||||
|
api.registerCommand({
|
||||||
|
name: "dirigent",
|
||||||
|
description: "Dirigent channel policy management",
|
||||||
|
acceptsArgs: true,
|
||||||
|
handler: async (cmdCtx) => {
|
||||||
|
const args = cmdCtx.args || "";
|
||||||
|
const parts = args.trim().split(/\s+/);
|
||||||
|
const subCmd = parts[0] || "help";
|
||||||
|
|
||||||
|
if (subCmd === "help") {
|
||||||
|
return {
|
||||||
|
text:
|
||||||
|
`Dirigent commands:\n` +
|
||||||
|
`/dirigent status - Show current channel status\n` +
|
||||||
|
`/dirigent turn-status - Show turn-based speaking status\n` +
|
||||||
|
`/dirigent turn-advance - Manually advance turn\n` +
|
||||||
|
`/dirigent turn-reset - Reset turn order`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subCmd === "status") {
|
||||||
|
return { text: JSON.stringify({ policies: policyState.channelPolicies }, null, 2) };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subCmd === "turn-status") {
|
||||||
|
const channelId = cmdCtx.channelId;
|
||||||
|
if (!channelId) return { text: "Cannot get channel ID", isError: true };
|
||||||
|
return { text: JSON.stringify(getTurnDebugInfo(channelId), null, 2) };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subCmd === "turn-advance") {
|
||||||
|
const channelId = cmdCtx.channelId;
|
||||||
|
if (!channelId) return { text: "Cannot get channel ID", isError: true };
|
||||||
|
const next = advanceTurn(channelId);
|
||||||
|
return { text: JSON.stringify({ ok: true, nextSpeaker: next }) };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subCmd === "turn-reset") {
|
||||||
|
const channelId = cmdCtx.channelId;
|
||||||
|
if (!channelId) return { text: "Cannot get channel ID", isError: true };
|
||||||
|
resetTurn(channelId);
|
||||||
|
return { text: JSON.stringify({ ok: true }) };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { text: `Unknown subcommand: ${subCmd}`, isError: true };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -3,13 +3,14 @@ import path from "node:path";
|
|||||||
import { spawn, type ChildProcess } from "node:child_process";
|
import { spawn, type ChildProcess } from "node:child_process";
|
||||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||||
import { evaluateDecision, resolvePolicy, type ChannelPolicy, type Decision, type DirigentConfig } from "./rules.js";
|
import { evaluateDecision, resolvePolicy, type ChannelPolicy, type Decision, type DirigentConfig } from "./rules.js";
|
||||||
import { advanceTurn, resetTurn, initTurnOrder, getTurnDebugInfo } from "./turn-manager.js";
|
import { initTurnOrder } from "./turn-manager.js";
|
||||||
import { startModeratorPresence, stopModeratorPresence } from "./moderator-presence.js";
|
import { startModeratorPresence, stopModeratorPresence } from "./moderator-presence.js";
|
||||||
import { registerMessageReceivedHook } from "./hooks/message-received.js";
|
import { registerMessageReceivedHook } from "./hooks/message-received.js";
|
||||||
import { registerBeforeModelResolveHook } from "./hooks/before-model-resolve.js";
|
import { registerBeforeModelResolveHook } from "./hooks/before-model-resolve.js";
|
||||||
import { registerBeforePromptBuildHook } from "./hooks/before-prompt-build.js";
|
import { registerBeforePromptBuildHook } from "./hooks/before-prompt-build.js";
|
||||||
import { registerBeforeMessageWriteHook } from "./hooks/before-message-write.js";
|
import { registerBeforeMessageWriteHook } from "./hooks/before-message-write.js";
|
||||||
import { registerMessageSentHook } from "./hooks/message-sent.js";
|
import { registerMessageSentHook } from "./hooks/message-sent.js";
|
||||||
|
import { registerDirigentCommand } from "./commands/dirigent-command.js";
|
||||||
|
|
||||||
// ── No-Reply API child process lifecycle ──────────────────────────────
|
// ── No-Reply API child process lifecycle ──────────────────────────────
|
||||||
let noReplyProcess: ChildProcess | null = null;
|
let noReplyProcess: ChildProcess | null = null;
|
||||||
@@ -745,49 +746,9 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Register slash commands for Discord
|
// Register slash commands for Discord
|
||||||
api.registerCommand({
|
registerDirigentCommand({
|
||||||
name: "dirigent",
|
api,
|
||||||
description: "Dirigent channel policy management",
|
policyState,
|
||||||
acceptsArgs: true,
|
|
||||||
handler: async (cmdCtx) => {
|
|
||||||
const args = cmdCtx.args || "";
|
|
||||||
const parts = args.trim().split(/\s+/);
|
|
||||||
const subCmd = parts[0] || "help";
|
|
||||||
|
|
||||||
if (subCmd === "help") {
|
|
||||||
return { text: `Dirigent commands:\n` +
|
|
||||||
`/dirigent status - Show current channel status\n` +
|
|
||||||
`/dirigent turn-status - Show turn-based speaking status\n` +
|
|
||||||
`/dirigent turn-advance - Manually advance turn\n` +
|
|
||||||
`/dirigent turn-reset - Reset turn order` };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subCmd === "status") {
|
|
||||||
return { text: JSON.stringify({ policies: policyState.channelPolicies }, null, 2) };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subCmd === "turn-status") {
|
|
||||||
const channelId = cmdCtx.channelId;
|
|
||||||
if (!channelId) return { text: "Cannot get channel ID", isError: true };
|
|
||||||
return { text: JSON.stringify(getTurnDebugInfo(channelId), null, 2) };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subCmd === "turn-advance") {
|
|
||||||
const channelId = cmdCtx.channelId;
|
|
||||||
if (!channelId) return { text: "Cannot get channel ID", isError: true };
|
|
||||||
const next = advanceTurn(channelId);
|
|
||||||
return { text: JSON.stringify({ ok: true, nextSpeaker: next }) };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subCmd === "turn-reset") {
|
|
||||||
const channelId = cmdCtx.channelId;
|
|
||||||
if (!channelId) return { text: "Cannot get channel ID", isError: true };
|
|
||||||
resetTurn(channelId);
|
|
||||||
return { text: JSON.stringify({ ok: true }) };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { text: `Unknown subcommand: ${subCmd}`, isError: true };
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle NO_REPLY detection before message write
|
// Handle NO_REPLY detection before message write
|
||||||
|
|||||||
Reference in New Issue
Block a user