mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 04:41:40 +00:00
refactor(auto-reply): share slash parsing for config/debug
This commit is contained in:
38
src/auto-reply/reply/commands-setunset.ts
Normal file
38
src/auto-reply/reply/commands-setunset.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { parseConfigValue } from "./config-value.js";
|
||||||
|
|
||||||
|
export type SetUnsetParseResult =
|
||||||
|
| { kind: "set"; path: string; value: unknown }
|
||||||
|
| { kind: "unset"; path: string }
|
||||||
|
| { kind: "error"; message: string };
|
||||||
|
|
||||||
|
export function parseSetUnsetCommand(params: {
|
||||||
|
slash: string;
|
||||||
|
action: "set" | "unset";
|
||||||
|
args: string;
|
||||||
|
}): SetUnsetParseResult {
|
||||||
|
const action = params.action;
|
||||||
|
const args = params.args.trim();
|
||||||
|
if (action === "unset") {
|
||||||
|
if (!args) {
|
||||||
|
return { kind: "error", message: `Usage: ${params.slash} unset path` };
|
||||||
|
}
|
||||||
|
return { kind: "unset", path: args };
|
||||||
|
}
|
||||||
|
if (!args) {
|
||||||
|
return { kind: "error", message: `Usage: ${params.slash} set path=value` };
|
||||||
|
}
|
||||||
|
const eqIndex = args.indexOf("=");
|
||||||
|
if (eqIndex <= 0) {
|
||||||
|
return { kind: "error", message: `Usage: ${params.slash} set path=value` };
|
||||||
|
}
|
||||||
|
const path = args.slice(0, eqIndex).trim();
|
||||||
|
const rawValue = args.slice(eqIndex + 1);
|
||||||
|
if (!path) {
|
||||||
|
return { kind: "error", message: `Usage: ${params.slash} set path=value` };
|
||||||
|
}
|
||||||
|
const parsed = parseConfigValue(rawValue);
|
||||||
|
if (parsed.error) {
|
||||||
|
return { kind: "error", message: parsed.error };
|
||||||
|
}
|
||||||
|
return { kind: "set", path, value: parsed.value };
|
||||||
|
}
|
||||||
46
src/auto-reply/reply/commands-slash-parse.ts
Normal file
46
src/auto-reply/reply/commands-slash-parse.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
export type SlashCommandParseResult =
|
||||||
|
| { kind: "no-match" }
|
||||||
|
| { kind: "empty" }
|
||||||
|
| { kind: "invalid" }
|
||||||
|
| { kind: "parsed"; action: string; args: string };
|
||||||
|
|
||||||
|
export type ParsedSlashCommand =
|
||||||
|
| { ok: true; action: string; args: string }
|
||||||
|
| { ok: false; message: string };
|
||||||
|
|
||||||
|
export function parseSlashCommandActionArgs(raw: string, slash: string): SlashCommandParseResult {
|
||||||
|
const trimmed = raw.trim();
|
||||||
|
const slashLower = slash.toLowerCase();
|
||||||
|
if (!trimmed.toLowerCase().startsWith(slashLower)) {
|
||||||
|
return { kind: "no-match" };
|
||||||
|
}
|
||||||
|
const rest = trimmed.slice(slash.length).trim();
|
||||||
|
if (!rest) {
|
||||||
|
return { kind: "empty" };
|
||||||
|
}
|
||||||
|
const match = rest.match(/^(\S+)(?:\s+([\s\S]+))?$/);
|
||||||
|
if (!match) {
|
||||||
|
return { kind: "invalid" };
|
||||||
|
}
|
||||||
|
const action = match[1]?.toLowerCase() ?? "";
|
||||||
|
const args = (match[2] ?? "").trim();
|
||||||
|
return { kind: "parsed", action, args };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseSlashCommandOrNull(
|
||||||
|
raw: string,
|
||||||
|
slash: string,
|
||||||
|
opts: { invalidMessage: string; defaultAction?: string },
|
||||||
|
): ParsedSlashCommand | null {
|
||||||
|
const parsed = parseSlashCommandActionArgs(raw, slash);
|
||||||
|
if (parsed.kind === "no-match") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (parsed.kind === "invalid") {
|
||||||
|
return { ok: false, message: opts.invalidMessage };
|
||||||
|
}
|
||||||
|
if (parsed.kind === "empty") {
|
||||||
|
return { ok: true, action: opts.defaultAction ?? "show", args: "" };
|
||||||
|
}
|
||||||
|
return { ok: true, action: parsed.action, args: parsed.args };
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { parseConfigValue } from "./config-value.js";
|
import { parseSetUnsetCommand } from "./commands-setunset.js";
|
||||||
|
import { parseSlashCommandOrNull } from "./commands-slash-parse.js";
|
||||||
|
|
||||||
export type ConfigCommand =
|
export type ConfigCommand =
|
||||||
| { action: "show"; path?: string }
|
| { action: "show"; path?: string }
|
||||||
@@ -7,60 +8,31 @@ export type ConfigCommand =
|
|||||||
| { action: "error"; message: string };
|
| { action: "error"; message: string };
|
||||||
|
|
||||||
export function parseConfigCommand(raw: string): ConfigCommand | null {
|
export function parseConfigCommand(raw: string): ConfigCommand | null {
|
||||||
const trimmed = raw.trim();
|
const parsed = parseSlashCommandOrNull(raw, "/config", {
|
||||||
if (!trimmed.toLowerCase().startsWith("/config")) {
|
invalidMessage: "Invalid /config syntax.",
|
||||||
|
});
|
||||||
|
if (!parsed) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const rest = trimmed.slice("/config".length).trim();
|
if (!parsed.ok) {
|
||||||
if (!rest) {
|
return { action: "error", message: parsed.message };
|
||||||
return { action: "show" };
|
|
||||||
}
|
}
|
||||||
|
const { action, args } = parsed;
|
||||||
const match = rest.match(/^(\S+)(?:\s+([\s\S]+))?$/);
|
|
||||||
if (!match) {
|
|
||||||
return { action: "error", message: "Invalid /config syntax." };
|
|
||||||
}
|
|
||||||
const action = match[1].toLowerCase();
|
|
||||||
const args = (match[2] ?? "").trim();
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "show":
|
case "show":
|
||||||
return { action: "show", path: args || undefined };
|
return { action: "show", path: args || undefined };
|
||||||
case "get":
|
case "get":
|
||||||
return { action: "show", path: args || undefined };
|
return { action: "show", path: args || undefined };
|
||||||
case "unset": {
|
case "unset":
|
||||||
if (!args) {
|
|
||||||
return { action: "error", message: "Usage: /config unset path" };
|
|
||||||
}
|
|
||||||
return { action: "unset", path: args };
|
|
||||||
}
|
|
||||||
case "set": {
|
case "set": {
|
||||||
if (!args) {
|
const parsed = parseSetUnsetCommand({ slash: "/config", action, args });
|
||||||
return {
|
if (parsed.kind === "error") {
|
||||||
action: "error",
|
return { action: "error", message: parsed.message };
|
||||||
message: "Usage: /config set path=value",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
const eqIndex = args.indexOf("=");
|
return parsed.kind === "set"
|
||||||
if (eqIndex <= 0) {
|
? { action: "set", path: parsed.path, value: parsed.value }
|
||||||
return {
|
: { action: "unset", path: parsed.path };
|
||||||
action: "error",
|
|
||||||
message: "Usage: /config set path=value",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const path = args.slice(0, eqIndex).trim();
|
|
||||||
const rawValue = args.slice(eqIndex + 1);
|
|
||||||
if (!path) {
|
|
||||||
return {
|
|
||||||
action: "error",
|
|
||||||
message: "Usage: /config set path=value",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const parsed = parseConfigValue(rawValue);
|
|
||||||
if (parsed.error) {
|
|
||||||
return { action: "error", message: parsed.error };
|
|
||||||
}
|
|
||||||
return { action: "set", path, value: parsed.value };
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { parseConfigValue } from "./config-value.js";
|
import { parseSetUnsetCommand } from "./commands-setunset.js";
|
||||||
|
import { parseSlashCommandOrNull } from "./commands-slash-parse.js";
|
||||||
|
|
||||||
export type DebugCommand =
|
export type DebugCommand =
|
||||||
| { action: "show" }
|
| { action: "show" }
|
||||||
@@ -8,60 +9,31 @@ export type DebugCommand =
|
|||||||
| { action: "error"; message: string };
|
| { action: "error"; message: string };
|
||||||
|
|
||||||
export function parseDebugCommand(raw: string): DebugCommand | null {
|
export function parseDebugCommand(raw: string): DebugCommand | null {
|
||||||
const trimmed = raw.trim();
|
const parsed = parseSlashCommandOrNull(raw, "/debug", {
|
||||||
if (!trimmed.toLowerCase().startsWith("/debug")) {
|
invalidMessage: "Invalid /debug syntax.",
|
||||||
|
});
|
||||||
|
if (!parsed) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const rest = trimmed.slice("/debug".length).trim();
|
if (!parsed.ok) {
|
||||||
if (!rest) {
|
return { action: "error", message: parsed.message };
|
||||||
return { action: "show" };
|
|
||||||
}
|
}
|
||||||
|
const { action, args } = parsed;
|
||||||
const match = rest.match(/^(\S+)(?:\s+([\s\S]+))?$/);
|
|
||||||
if (!match) {
|
|
||||||
return { action: "error", message: "Invalid /debug syntax." };
|
|
||||||
}
|
|
||||||
const action = match[1].toLowerCase();
|
|
||||||
const args = (match[2] ?? "").trim();
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "show":
|
case "show":
|
||||||
return { action: "show" };
|
return { action: "show" };
|
||||||
case "reset":
|
case "reset":
|
||||||
return { action: "reset" };
|
return { action: "reset" };
|
||||||
case "unset": {
|
case "unset":
|
||||||
if (!args) {
|
|
||||||
return { action: "error", message: "Usage: /debug unset path" };
|
|
||||||
}
|
|
||||||
return { action: "unset", path: args };
|
|
||||||
}
|
|
||||||
case "set": {
|
case "set": {
|
||||||
if (!args) {
|
const parsed = parseSetUnsetCommand({ slash: "/debug", action, args });
|
||||||
return {
|
if (parsed.kind === "error") {
|
||||||
action: "error",
|
return { action: "error", message: parsed.message };
|
||||||
message: "Usage: /debug set path=value",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
const eqIndex = args.indexOf("=");
|
return parsed.kind === "set"
|
||||||
if (eqIndex <= 0) {
|
? { action: "set", path: parsed.path, value: parsed.value }
|
||||||
return {
|
: { action: "unset", path: parsed.path };
|
||||||
action: "error",
|
|
||||||
message: "Usage: /debug set path=value",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const path = args.slice(0, eqIndex).trim();
|
|
||||||
const rawValue = args.slice(eqIndex + 1);
|
|
||||||
if (!path) {
|
|
||||||
return {
|
|
||||||
action: "error",
|
|
||||||
message: "Usage: /debug set path=value",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const parsed = parseConfigValue(rawValue);
|
|
||||||
if (parsed.error) {
|
|
||||||
return { action: "error", message: parsed.error };
|
|
||||||
}
|
|
||||||
return { action: "set", path, value: parsed.value };
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user