mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 12:11:09 +00:00
add multi-language for hooks ui
This commit is contained in:
parent
b08154dbee
commit
7a53185dbf
11 changed files with 844 additions and 171 deletions
|
|
@ -9,7 +9,8 @@ import { Box, Text } from 'ink';
|
|||
import { theme } from '../../semantic-colors.js';
|
||||
import { useKeypress } from '../../hooks/useKeypress.js';
|
||||
import type { HookEventDisplayInfo } from './types.js';
|
||||
import { SOURCE_DISPLAY_MAP } from './constants.js';
|
||||
import { getTranslatedSourceDisplayMap } from './constants.js';
|
||||
import { t } from '../../../i18n/index.js';
|
||||
|
||||
interface HookDetailStepProps {
|
||||
hook: HookEventDisplayInfo;
|
||||
|
|
@ -23,6 +24,9 @@ export function HookDetailStep({
|
|||
const hasConfigs = hook.configs.length > 0;
|
||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||
|
||||
// Get translated source display map
|
||||
const sourceDisplayMap = getTranslatedSourceDisplayMap();
|
||||
|
||||
// Handle keyboard navigation
|
||||
useKeypress(
|
||||
(key) => {
|
||||
|
|
@ -61,7 +65,7 @@ export function HookDetailStep({
|
|||
{hook.exitCodes.length > 0 && (
|
||||
<Box flexDirection="column" marginBottom={1}>
|
||||
<Text bold color={theme.text.primary}>
|
||||
Exit codes:
|
||||
{t('Exit codes:')}
|
||||
</Text>
|
||||
{hook.exitCodes.map((ec, index) => (
|
||||
<Box key={index}>
|
||||
|
|
@ -79,12 +83,12 @@ export function HookDetailStep({
|
|||
{hasConfigs ? (
|
||||
<>
|
||||
<Text bold color={theme.text.primary}>
|
||||
Configured hooks:
|
||||
{t('Configured hooks:')}
|
||||
</Text>
|
||||
{hook.configs.map((config, index) => {
|
||||
const isSelected = index === selectedIndex;
|
||||
const sourceDisplay =
|
||||
SOURCE_DISPLAY_MAP[config.source] || config.source;
|
||||
sourceDisplayMap[config.source] || config.source;
|
||||
|
||||
return (
|
||||
<Box key={index}>
|
||||
|
|
@ -107,23 +111,23 @@ export function HookDetailStep({
|
|||
);
|
||||
})}
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.secondary}>Esc to go back</Text>
|
||||
<Text color={theme.text.secondary}>{t('Esc to go back')}</Text>
|
||||
</Box>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Box>
|
||||
<Text color={theme.text.secondary}>
|
||||
No hooks configured for this event.
|
||||
{t('No hooks configured for this event.')}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.secondary}>
|
||||
To add hooks, edit settings.json directly or ask Qwen.
|
||||
{t('To add hooks, edit settings.json directly or ask Qwen.')}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.secondary}>Esc to go back</Text>
|
||||
<Text color={theme.text.secondary}>{t('Esc to go back')}</Text>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { Box, Text } from 'ink';
|
|||
import { theme } from '../../semantic-colors.js';
|
||||
import { useKeypress } from '../../hooks/useKeypress.js';
|
||||
import type { HookEventDisplayInfo } from './types.js';
|
||||
import { t } from '../../../i18n/index.js';
|
||||
|
||||
interface HooksListStepProps {
|
||||
hooks: HookEventDisplayInfo[];
|
||||
|
|
@ -41,7 +42,7 @@ export function HooksListStep({
|
|||
if (hooks.length === 0) {
|
||||
return (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
<Text color={theme.text.secondary}>No hook events found.</Text>
|
||||
<Text color={theme.text.secondary}>{t('No hook events found.')}</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
@ -52,21 +53,26 @@ export function HooksListStep({
|
|||
0,
|
||||
);
|
||||
|
||||
// Get the correct plural/singular form
|
||||
const hooksConfiguredText =
|
||||
totalConfigured === 1
|
||||
? t('{{count}} hook configured', { count: String(totalConfigured) })
|
||||
: t('{{count}} hooks configured', { count: String(totalConfigured) });
|
||||
|
||||
return (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
<Box marginBottom={1}>
|
||||
<Text bold color={theme.text.primary}>
|
||||
Hooks
|
||||
</Text>
|
||||
<Text color={theme.text.secondary}>
|
||||
{` · ${totalConfigured} hook${totalConfigured !== 1 ? 's' : ''} configured`}
|
||||
{t('Hooks')}
|
||||
</Text>
|
||||
<Text color={theme.text.secondary}>{` · ${hooksConfiguredText}`}</Text>
|
||||
</Box>
|
||||
|
||||
<Box marginBottom={1}>
|
||||
<Text color={theme.text.secondary}>
|
||||
This menu is read-only. To add or modify hooks, edit settings.json
|
||||
directly or ask Qwen Code.
|
||||
{t(
|
||||
'This menu is read-only. To add or modify hooks, edit settings.json directly or ask Qwen Code.',
|
||||
)}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
|
|
@ -101,7 +107,7 @@ export function HooksListStep({
|
|||
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.secondary}>
|
||||
Enter to select · Esc to cancel
|
||||
{t('Enter to select · Esc to cancel')}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -25,9 +25,10 @@ import { HooksListStep } from './HooksListStep.js';
|
|||
import { HookDetailStep } from './HookDetailStep.js';
|
||||
import {
|
||||
DISPLAY_HOOK_EVENTS,
|
||||
SOURCE_DISPLAY_MAP,
|
||||
getTranslatedSourceDisplayMap,
|
||||
createEmptyHookEventInfo,
|
||||
} from './constants.js';
|
||||
import { t } from '../../../i18n/index.js';
|
||||
|
||||
const debugLogger = createDebugLogger('HOOKS_DIALOG');
|
||||
|
||||
|
|
@ -44,6 +45,7 @@ export function HooksManagementDialog({
|
|||
const [selectedHookIndex, setSelectedHookIndex] = useState<number>(-1);
|
||||
const [hooks, setHooks] = useState<HookEventDisplayInfo[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [loadError, setLoadError] = useState<string | null>(null);
|
||||
|
||||
// Load hooks data
|
||||
const fetchHooksData = useCallback((): HookEventDisplayInfo[] => {
|
||||
|
|
@ -55,6 +57,9 @@ export function HooksManagementDialog({
|
|||
SettingScope.Workspace,
|
||||
).settings;
|
||||
|
||||
// Get translated source display map
|
||||
const sourceDisplayMap = getTranslatedSourceDisplayMap();
|
||||
|
||||
const result: HookEventDisplayInfo[] = [];
|
||||
|
||||
for (const eventName of DISPLAY_HOOK_EVENTS) {
|
||||
|
|
@ -70,7 +75,7 @@ export function HooksManagementDialog({
|
|||
hookInfo.configs.push({
|
||||
config: hookConfig,
|
||||
source: HooksConfigSource.User,
|
||||
sourceDisplay: SOURCE_DISPLAY_MAP[HooksConfigSource.User],
|
||||
sourceDisplay: sourceDisplayMap[HooksConfigSource.User],
|
||||
enabled: true,
|
||||
});
|
||||
}
|
||||
|
|
@ -87,7 +92,7 @@ export function HooksManagementDialog({
|
|||
hookInfo.configs.push({
|
||||
config: hookConfig,
|
||||
source: HooksConfigSource.Project,
|
||||
sourceDisplay: SOURCE_DISPLAY_MAP[HooksConfigSource.Project],
|
||||
sourceDisplay: sourceDisplayMap[HooksConfigSource.Project],
|
||||
enabled: true,
|
||||
});
|
||||
}
|
||||
|
|
@ -103,7 +108,7 @@ export function HooksManagementDialog({
|
|||
hookInfo.configs.push({
|
||||
config: hookConfig,
|
||||
source: HooksConfigSource.Extensions,
|
||||
sourceDisplay: SOURCE_DISPLAY_MAP[HooksConfigSource.Extensions],
|
||||
sourceDisplay: sourceDisplayMap[HooksConfigSource.Extensions],
|
||||
enabled: true,
|
||||
});
|
||||
}
|
||||
|
|
@ -120,11 +125,15 @@ export function HooksManagementDialog({
|
|||
// Load hooks data on initial render
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
setLoadError(null);
|
||||
try {
|
||||
const hooksData = fetchHooksData();
|
||||
setHooks(hooksData);
|
||||
} catch (error) {
|
||||
debugLogger.error('Error loading hooks:', error);
|
||||
setLoadError(
|
||||
error instanceof Error ? error.message : 'Failed to load hooks',
|
||||
);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
|
@ -180,7 +189,21 @@ export function HooksManagementDialog({
|
|||
if (isLoading) {
|
||||
return (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
<Text color={theme.text.secondary}>Loading hooks...</Text>
|
||||
<Text color={theme.text.secondary}>{t('Loading hooks...')}</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (loadError) {
|
||||
return (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
<Text color={theme.status.error}>{t('Error loading hooks:')}</Text>
|
||||
<Text color={theme.text.secondary}>{loadError}</Text>
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.secondary}>
|
||||
{t('Press Escape to close')}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
@ -203,7 +226,7 @@ export function HooksManagementDialog({
|
|||
}
|
||||
return (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
<Text color={theme.text.secondary}>No hook selected</Text>
|
||||
<Text color={theme.text.secondary}>{t('No hook selected')}</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,144 +6,182 @@
|
|||
|
||||
import { HooksConfigSource, HookEventName } from '@qwen-code/qwen-code-core';
|
||||
import type { HookExitCode, HookEventDisplayInfo } from './types.js';
|
||||
import { t } from '../../../i18n/index.js';
|
||||
|
||||
/**
|
||||
* Exit code descriptions for different hook types
|
||||
*/
|
||||
export const HOOK_EXIT_CODES: Record<string, HookExitCode[]> = {
|
||||
[HookEventName.Stop]: [
|
||||
{ code: 0, description: 'stdout/stderr not shown' },
|
||||
{ code: 2, description: 'show stderr to model and continue conversation' },
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
[HookEventName.PreToolUse]: [
|
||||
{ code: 0, description: 'stdout/stderr not shown' },
|
||||
{ code: 2, description: 'show stderr to model and block tool call' },
|
||||
{
|
||||
code: 'Other',
|
||||
description: 'show stderr to user only but continue with tool call',
|
||||
},
|
||||
],
|
||||
[HookEventName.PostToolUse]: [
|
||||
{ code: 0, description: 'stdout shown in transcript mode (ctrl+o)' },
|
||||
{ code: 2, description: 'show stderr to model immediately' },
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
[HookEventName.PostToolUseFailure]: [
|
||||
{ code: 0, description: 'stdout shown in transcript mode (ctrl+o)' },
|
||||
{ code: 2, description: 'show stderr to model immediately' },
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
[HookEventName.Notification]: [
|
||||
{ code: 0, description: 'stdout/stderr not shown' },
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
[HookEventName.UserPromptSubmit]: [
|
||||
{ code: 0, description: 'stdout shown to model' },
|
||||
{
|
||||
code: 2,
|
||||
description:
|
||||
'block processing, erase original prompt, and show stderr to user only',
|
||||
},
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
[HookEventName.SessionStart]: [
|
||||
{ code: 0, description: 'stdout shown to model' },
|
||||
{
|
||||
code: 'Other',
|
||||
description: 'show stderr to user only (blocking errors ignored)',
|
||||
},
|
||||
],
|
||||
[HookEventName.SessionEnd]: [
|
||||
{ code: 0, description: 'command completes successfully' },
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
[HookEventName.SubagentStart]: [
|
||||
{ code: 0, description: 'stdout shown to subagent' },
|
||||
{
|
||||
code: 'Other',
|
||||
description: 'show stderr to user only (blocking errors ignored)',
|
||||
},
|
||||
],
|
||||
[HookEventName.SubagentStop]: [
|
||||
{ code: 0, description: 'stdout/stderr not shown' },
|
||||
{
|
||||
code: 2,
|
||||
description: 'show stderr to subagent and continue having it run',
|
||||
},
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
[HookEventName.PreCompact]: [
|
||||
{ code: 0, description: 'stdout appended as custom compact instructions' },
|
||||
{ code: 2, description: 'block compaction' },
|
||||
{
|
||||
code: 'Other',
|
||||
description: 'show stderr to user only but continue with compaction',
|
||||
},
|
||||
],
|
||||
[HookEventName.PermissionRequest]: [
|
||||
{ code: 0, description: 'use hook decision if provided' },
|
||||
{ code: 'Other', description: 'show stderr to user only' },
|
||||
],
|
||||
};
|
||||
export function getHookExitCodes(eventName: string): HookExitCode[] {
|
||||
const exitCodesMap: Record<string, HookExitCode[]> = {
|
||||
[HookEventName.Stop]: [
|
||||
{ code: 0, description: t('stdout/stderr not shown') },
|
||||
{
|
||||
code: 2,
|
||||
description: t('show stderr to model and continue conversation'),
|
||||
},
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
[HookEventName.PreToolUse]: [
|
||||
{ code: 0, description: t('stdout/stderr not shown') },
|
||||
{ code: 2, description: t('show stderr to model and block tool call') },
|
||||
{
|
||||
code: 'Other',
|
||||
description: t('show stderr to user only but continue with tool call'),
|
||||
},
|
||||
],
|
||||
[HookEventName.PostToolUse]: [
|
||||
{ code: 0, description: t('stdout shown in transcript mode (ctrl+o)') },
|
||||
{ code: 2, description: t('show stderr to model immediately') },
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
[HookEventName.PostToolUseFailure]: [
|
||||
{ code: 0, description: t('stdout shown in transcript mode (ctrl+o)') },
|
||||
{ code: 2, description: t('show stderr to model immediately') },
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
[HookEventName.Notification]: [
|
||||
{ code: 0, description: t('stdout/stderr not shown') },
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
[HookEventName.UserPromptSubmit]: [
|
||||
{ code: 0, description: t('stdout shown to model') },
|
||||
{
|
||||
code: 2,
|
||||
description: t(
|
||||
'block processing, erase original prompt, and show stderr to user only',
|
||||
),
|
||||
},
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
[HookEventName.SessionStart]: [
|
||||
{ code: 0, description: t('stdout shown to model') },
|
||||
{
|
||||
code: 'Other',
|
||||
description: t('show stderr to user only (blocking errors ignored)'),
|
||||
},
|
||||
],
|
||||
[HookEventName.SessionEnd]: [
|
||||
{ code: 0, description: t('command completes successfully') },
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
[HookEventName.SubagentStart]: [
|
||||
{ code: 0, description: t('stdout shown to subagent') },
|
||||
{
|
||||
code: 'Other',
|
||||
description: t('show stderr to user only (blocking errors ignored)'),
|
||||
},
|
||||
],
|
||||
[HookEventName.SubagentStop]: [
|
||||
{ code: 0, description: t('stdout/stderr not shown') },
|
||||
{
|
||||
code: 2,
|
||||
description: t('show stderr to subagent and continue having it run'),
|
||||
},
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
[HookEventName.PreCompact]: [
|
||||
{
|
||||
code: 0,
|
||||
description: t('stdout appended as custom compact instructions'),
|
||||
},
|
||||
{ code: 2, description: t('block compaction') },
|
||||
{
|
||||
code: 'Other',
|
||||
description: t('show stderr to user only but continue with compaction'),
|
||||
},
|
||||
],
|
||||
[HookEventName.PermissionRequest]: [
|
||||
{ code: 0, description: t('use hook decision if provided') },
|
||||
{ code: 'Other', description: t('show stderr to user only') },
|
||||
],
|
||||
};
|
||||
return exitCodesMap[eventName] || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Short one-line description for hooks list view
|
||||
*/
|
||||
export const HOOK_SHORT_DESCRIPTIONS: Record<string, string> = {
|
||||
[HookEventName.PreToolUse]: 'Before tool execution',
|
||||
[HookEventName.PostToolUse]: 'After tool execution',
|
||||
[HookEventName.PostToolUseFailure]: 'After tool execution fails',
|
||||
[HookEventName.Notification]: 'When notifications are sent',
|
||||
[HookEventName.UserPromptSubmit]: 'When the user submits a prompt',
|
||||
[HookEventName.SessionStart]: 'When a new session is started',
|
||||
[HookEventName.Stop]: 'Right before Qwen Code concludes its response',
|
||||
[HookEventName.SubagentStart]: 'When a subagent (Agent tool call) is started',
|
||||
[HookEventName.SubagentStop]:
|
||||
'Right before a subagent concludes its response',
|
||||
[HookEventName.PreCompact]: 'Before conversation compaction',
|
||||
[HookEventName.SessionEnd]: 'When a session is ending',
|
||||
[HookEventName.PermissionRequest]: 'When a permission dialog is displayed',
|
||||
};
|
||||
export function getHookShortDescription(eventName: string): string {
|
||||
const descriptions: Record<string, string> = {
|
||||
[HookEventName.PreToolUse]: t('Before tool execution'),
|
||||
[HookEventName.PostToolUse]: t('After tool execution'),
|
||||
[HookEventName.PostToolUseFailure]: t('After tool execution fails'),
|
||||
[HookEventName.Notification]: t('When notifications are sent'),
|
||||
[HookEventName.UserPromptSubmit]: t('When the user submits a prompt'),
|
||||
[HookEventName.SessionStart]: t('When a new session is started'),
|
||||
[HookEventName.Stop]: t('Right before Qwen Code concludes its response'),
|
||||
[HookEventName.SubagentStart]: t(
|
||||
'When a subagent (Agent tool call) is started',
|
||||
),
|
||||
[HookEventName.SubagentStop]: t(
|
||||
'Right before a subagent concludes its response',
|
||||
),
|
||||
[HookEventName.PreCompact]: t('Before conversation compaction'),
|
||||
[HookEventName.SessionEnd]: t('When a session is ending'),
|
||||
[HookEventName.PermissionRequest]: t(
|
||||
'When a permission dialog is displayed',
|
||||
),
|
||||
};
|
||||
return descriptions[eventName] || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Detailed description for each hook event type (shown in detail view)
|
||||
*/
|
||||
export const HOOK_DESCRIPTIONS: Record<string, string> = {
|
||||
[HookEventName.Stop]: '',
|
||||
[HookEventName.PreToolUse]:
|
||||
'Input to command is JSON of tool call arguments.',
|
||||
[HookEventName.PostToolUse]:
|
||||
'Input to command is JSON with fields "inputs" (tool call arguments) and "response" (tool call response).',
|
||||
[HookEventName.PostToolUseFailure]:
|
||||
'Input to command is JSON with tool_name, tool_input, tool_use_id, error, error_type, is_interrupt, and is_timeout.',
|
||||
[HookEventName.Notification]:
|
||||
'Input to command is JSON with notification message and type.',
|
||||
[HookEventName.UserPromptSubmit]:
|
||||
'Input to command is JSON with original user prompt text.',
|
||||
[HookEventName.SessionStart]:
|
||||
'Input to command is JSON with session start source.',
|
||||
[HookEventName.SessionEnd]:
|
||||
'Input to command is JSON with session end reason.',
|
||||
[HookEventName.SubagentStart]:
|
||||
'Input to command is JSON with agent_id and agent_type.',
|
||||
[HookEventName.SubagentStop]:
|
||||
'Input to command is JSON with agent_id, agent_type, and agent_transcript_path.',
|
||||
[HookEventName.PreCompact]:
|
||||
'Input to command is JSON with compaction details.',
|
||||
[HookEventName.PermissionRequest]:
|
||||
'Input to command is JSON with tool_name, tool_input, and tool_use_id. Output JSON with hookSpecificOutput containing decision to allow or deny.',
|
||||
};
|
||||
export function getHookDescription(eventName: string): string {
|
||||
const descriptions: Record<string, string> = {
|
||||
[HookEventName.Stop]: '',
|
||||
[HookEventName.PreToolUse]: t(
|
||||
'Input to command is JSON of tool call arguments.',
|
||||
),
|
||||
[HookEventName.PostToolUse]: t(
|
||||
'Input to command is JSON with fields "inputs" (tool call arguments) and "response" (tool call response).',
|
||||
),
|
||||
[HookEventName.PostToolUseFailure]: t(
|
||||
'Input to command is JSON with tool_name, tool_input, tool_use_id, error, error_type, is_interrupt, and is_timeout.',
|
||||
),
|
||||
[HookEventName.Notification]: t(
|
||||
'Input to command is JSON with notification message and type.',
|
||||
),
|
||||
[HookEventName.UserPromptSubmit]: t(
|
||||
'Input to command is JSON with original user prompt text.',
|
||||
),
|
||||
[HookEventName.SessionStart]: t(
|
||||
'Input to command is JSON with session start source.',
|
||||
),
|
||||
[HookEventName.SessionEnd]: t(
|
||||
'Input to command is JSON with session end reason.',
|
||||
),
|
||||
[HookEventName.SubagentStart]: t(
|
||||
'Input to command is JSON with agent_id and agent_type.',
|
||||
),
|
||||
[HookEventName.SubagentStop]: t(
|
||||
'Input to command is JSON with agent_id, agent_type, and agent_transcript_path.',
|
||||
),
|
||||
[HookEventName.PreCompact]: t(
|
||||
'Input to command is JSON with compaction details.',
|
||||
),
|
||||
[HookEventName.PermissionRequest]: t(
|
||||
'Input to command is JSON with tool_name, tool_input, and tool_use_id. Output JSON with hookSpecificOutput containing decision to allow or deny.',
|
||||
),
|
||||
};
|
||||
return descriptions[eventName] || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Source display mapping
|
||||
* Source display mapping (translated)
|
||||
*/
|
||||
export const SOURCE_DISPLAY_MAP: Record<HooksConfigSource, string> = {
|
||||
[HooksConfigSource.Project]: 'Local Settings',
|
||||
[HooksConfigSource.User]: 'User Settings',
|
||||
[HooksConfigSource.System]: 'System Settings',
|
||||
[HooksConfigSource.Extensions]: 'Extensions',
|
||||
};
|
||||
export function getTranslatedSourceDisplayMap(): Record<
|
||||
HooksConfigSource,
|
||||
string
|
||||
> {
|
||||
return {
|
||||
[HooksConfigSource.Project]: t('Local Settings'),
|
||||
[HooksConfigSource.User]: t('User Settings'),
|
||||
[HooksConfigSource.System]: t('System Settings'),
|
||||
[HooksConfigSource.Extensions]: t('Extensions'),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* List of hook events to display in the UI
|
||||
|
|
@ -171,9 +209,9 @@ export function createEmptyHookEventInfo(
|
|||
): HookEventDisplayInfo {
|
||||
return {
|
||||
event: eventName,
|
||||
shortDescription: HOOK_SHORT_DESCRIPTIONS[eventName] || '',
|
||||
description: HOOK_DESCRIPTIONS[eventName] || '',
|
||||
exitCodes: HOOK_EXIT_CODES[eventName] || [],
|
||||
shortDescription: getHookShortDescription(eventName),
|
||||
description: getHookDescription(eventName),
|
||||
exitCodes: getHookExitCodes(eventName),
|
||||
configs: [],
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue