mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
(feat): Initial Version of Custom Commands (#4572)
This commit is contained in:
@@ -22,6 +22,7 @@ import { LoadedSettings } from '../../config/settings.js';
|
||||
import { type CommandContext, type SlashCommand } from '../commands/types.js';
|
||||
import { CommandService } from '../../services/CommandService.js';
|
||||
import { BuiltinCommandLoader } from '../../services/BuiltinCommandLoader.js';
|
||||
import { FileCommandLoader } from '../../services/FileCommandLoader.js';
|
||||
|
||||
/**
|
||||
* Hook to define and process slash commands (e.g., /help, /clear).
|
||||
@@ -162,8 +163,10 @@ export const useSlashCommandProcessor = (
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
const load = async () => {
|
||||
// TODO - Add other loaders for custom commands.
|
||||
const loaders = [new BuiltinCommandLoader(config)];
|
||||
const loaders = [
|
||||
new BuiltinCommandLoader(config),
|
||||
new FileCommandLoader(config),
|
||||
];
|
||||
const commandService = await CommandService.create(
|
||||
loaders,
|
||||
controller.signal,
|
||||
@@ -192,12 +195,7 @@ export const useSlashCommandProcessor = (
|
||||
}
|
||||
|
||||
const userMessageTimestamp = Date.now();
|
||||
if (trimmed !== '/quit' && trimmed !== '/exit') {
|
||||
addItem(
|
||||
{ type: MessageType.USER, text: trimmed },
|
||||
userMessageTimestamp,
|
||||
);
|
||||
}
|
||||
addItem({ type: MessageType.USER, text: trimmed }, userMessageTimestamp);
|
||||
|
||||
const parts = trimmed.substring(1).trim().split(/\s+/);
|
||||
const commandPath = parts.filter((p) => p); // The parts of the command, e.g., ['memory', 'add']
|
||||
@@ -207,9 +205,21 @@ export const useSlashCommandProcessor = (
|
||||
let pathIndex = 0;
|
||||
|
||||
for (const part of commandPath) {
|
||||
const foundCommand = currentCommands.find(
|
||||
(cmd) => cmd.name === part || cmd.altNames?.includes(part),
|
||||
);
|
||||
// TODO: For better performance and architectural clarity, this two-pass
|
||||
// search could be replaced. A more optimal approach would be to
|
||||
// pre-compute a single lookup map in `CommandService.ts` that resolves
|
||||
// all name and alias conflicts during the initial loading phase. The
|
||||
// processor would then perform a single, fast lookup on that map.
|
||||
|
||||
// First pass: check for an exact match on the primary command name.
|
||||
let foundCommand = currentCommands.find((cmd) => cmd.name === part);
|
||||
|
||||
// Second pass: if no primary name matches, check for an alias.
|
||||
if (!foundCommand) {
|
||||
foundCommand = currentCommands.find((cmd) =>
|
||||
cmd.altNames?.includes(part),
|
||||
);
|
||||
}
|
||||
|
||||
if (foundCommand) {
|
||||
commandToExecute = foundCommand;
|
||||
@@ -290,6 +300,12 @@ export const useSlashCommandProcessor = (
|
||||
process.exit(0);
|
||||
}, 100);
|
||||
return { type: 'handled' };
|
||||
|
||||
case 'submit_prompt':
|
||||
return {
|
||||
type: 'submit_prompt',
|
||||
content: result.content,
|
||||
};
|
||||
default: {
|
||||
const unhandled: never = result;
|
||||
throw new Error(`Unhandled slash command result: ${unhandled}`);
|
||||
|
||||
Reference in New Issue
Block a user