mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-07 03:40:36 -07:00
feat(ui): add source indicators to slash commands (#18839)
This commit is contained in:
@@ -37,6 +37,7 @@ import { sanitizeForDisplay } from '../ui/utils/textUtils.js';
|
||||
|
||||
interface CommandDirectory {
|
||||
path: string;
|
||||
namespace: string;
|
||||
extensionName?: string;
|
||||
extensionId?: string;
|
||||
}
|
||||
@@ -111,6 +112,7 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
this.parseAndAdaptFile(
|
||||
path.join(dirInfo.path, file),
|
||||
dirInfo.path,
|
||||
dirInfo.namespace,
|
||||
dirInfo.extensionName,
|
||||
dirInfo.extensionId,
|
||||
),
|
||||
@@ -151,10 +153,16 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
const storage = this.config?.storage ?? new Storage(this.projectRoot);
|
||||
|
||||
// 1. User commands
|
||||
dirs.push({ path: Storage.getUserCommandsDir() });
|
||||
dirs.push({
|
||||
path: Storage.getUserCommandsDir(),
|
||||
namespace: 'user',
|
||||
});
|
||||
|
||||
// 2. Project commands (override user commands)
|
||||
dirs.push({ path: storage.getProjectCommandsDir() });
|
||||
dirs.push({
|
||||
path: storage.getProjectCommandsDir(),
|
||||
namespace: 'workspace',
|
||||
});
|
||||
|
||||
// 3. Extension commands (processed last to detect all conflicts)
|
||||
if (this.config) {
|
||||
@@ -165,6 +173,7 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
|
||||
const extensionCommandDirs = activeExtensions.map((ext) => ({
|
||||
path: path.join(ext.path, 'commands'),
|
||||
namespace: ext.name,
|
||||
extensionName: ext.name,
|
||||
extensionId: ext.id,
|
||||
}));
|
||||
@@ -179,14 +188,16 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
* Parses a single .toml file and transforms it into a SlashCommand object.
|
||||
* @param filePath The absolute path to the .toml file.
|
||||
* @param baseDir The root command directory for name calculation.
|
||||
* @param namespace The namespace of the command.
|
||||
* @param extensionName Optional extension name to prefix commands with.
|
||||
* @returns A promise resolving to a SlashCommand, or null if the file is invalid.
|
||||
*/
|
||||
private async parseAndAdaptFile(
|
||||
filePath: string,
|
||||
baseDir: string,
|
||||
extensionName?: string,
|
||||
extensionId?: string,
|
||||
namespace: string,
|
||||
extensionName: string | undefined,
|
||||
extensionId: string | undefined,
|
||||
): Promise<SlashCommand | null> {
|
||||
let fileContent: string;
|
||||
try {
|
||||
@@ -245,16 +256,11 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
})
|
||||
.join(':');
|
||||
|
||||
// Add extension name tag for extension commands
|
||||
const defaultDescription = `Custom command from ${path.basename(filePath)}`;
|
||||
let description = validDef.description || defaultDescription;
|
||||
|
||||
description = sanitizeForDisplay(description, 100);
|
||||
|
||||
if (extensionName) {
|
||||
description = `[${extensionName}] ${description}`;
|
||||
}
|
||||
|
||||
const processors: IPromptProcessor[] = [];
|
||||
const usesArgs = validDef.prompt.includes(SHORTHAND_ARGS_PLACEHOLDER);
|
||||
const usesShellInjection = validDef.prompt.includes(
|
||||
@@ -285,6 +291,7 @@ export class FileCommandLoader implements ICommandLoader {
|
||||
|
||||
return {
|
||||
name: baseCommandName,
|
||||
namespace,
|
||||
description,
|
||||
kind: CommandKind.FILE,
|
||||
extensionName,
|
||||
|
||||
Reference in New Issue
Block a user