Files
openclaw-zero-token/auto-reply/skill-commands-base.ts
sjhu 571e14a236 feat: upgrade to upstream v2026.3.28
Major upgrade from e26988a38 to upstream v2026.3.28 (f9b107928).
Key changes:
- Upstream src/, ui/, extensions/ (89 bundled extensions)
- Zero-token web providers preserved in src/zero-token/
- AskOnce plugin restored and registered as CLI command
- Added missing packages: @anthropic-ai/vertex-sdk, @modelcontextprotocol/sdk
- Fixed tsconfig rootDir, skipLibCheck for plugin-sdk DTS build
- Added askonce to bundled plugin metadata and package.json exports
- Fixed AskOnce CLI command registration (missing commands metadata)
- Restored AskOnce adapter imports (correct 5-level relative paths)
- Removed stale migration artifacts from root directory
2026-03-30 17:58:12 +08:00

97 lines
2.7 KiB
TypeScript

import type { SkillCommandSpec } from "../agents/skills.js";
import { getChatCommands } from "./commands-registry.data.js";
export function listReservedChatSlashCommandNames(extraNames: string[] = []): Set<string> {
const reserved = new Set<string>();
for (const command of getChatCommands()) {
if (command.nativeName) {
reserved.add(command.nativeName.toLowerCase());
}
for (const alias of command.textAliases) {
const trimmed = alias.trim();
if (!trimmed.startsWith("/")) {
continue;
}
reserved.add(trimmed.slice(1).toLowerCase());
}
}
for (const name of extraNames) {
const trimmed = name.trim().toLowerCase();
if (trimmed) {
reserved.add(trimmed);
}
}
return reserved;
}
function normalizeSkillCommandLookup(value: string): string {
return value
.trim()
.toLowerCase()
.replace(/[\s_]+/g, "-");
}
function findSkillCommand(
skillCommands: SkillCommandSpec[],
rawName: string,
): SkillCommandSpec | undefined {
const trimmed = rawName.trim();
if (!trimmed) {
return undefined;
}
const lowered = trimmed.toLowerCase();
const normalized = normalizeSkillCommandLookup(trimmed);
return skillCommands.find((entry) => {
if (entry.name.toLowerCase() === lowered) {
return true;
}
if (entry.skillName.toLowerCase() === lowered) {
return true;
}
return (
normalizeSkillCommandLookup(entry.name) === normalized ||
normalizeSkillCommandLookup(entry.skillName) === normalized
);
});
}
export function resolveSkillCommandInvocation(params: {
commandBodyNormalized: string;
skillCommands: SkillCommandSpec[];
}): { command: SkillCommandSpec; args?: string } | null {
const trimmed = params.commandBodyNormalized.trim();
if (!trimmed.startsWith("/")) {
return null;
}
const match = trimmed.match(/^\/([^\s]+)(?:\s+([\s\S]+))?$/);
if (!match) {
return null;
}
const commandName = match[1]?.trim().toLowerCase();
if (!commandName) {
return null;
}
if (commandName === "skill") {
const remainder = match[2]?.trim();
if (!remainder) {
return null;
}
const skillMatch = remainder.match(/^([^\s]+)(?:\s+([\s\S]+))?$/);
if (!skillMatch) {
return null;
}
const skillCommand = findSkillCommand(params.skillCommands, skillMatch[1] ?? "");
if (!skillCommand) {
return null;
}
const args = skillMatch[2]?.trim();
return { command: skillCommand, args: args || undefined };
}
const command = params.skillCommands.find((entry) => entry.name.toLowerCase() === commandName);
if (!command) {
return null;
}
const args = match[2]?.trim();
return { command, args: args || undefined };
}