diff --git a/src/costrict/command/locales/en/review.txt b/src/costrict/command/locales/en/review.txt new file mode 100644 index 000000000..5fe8f59ab --- /dev/null +++ b/src/costrict/command/locales/en/review.txt @@ -0,0 +1,5 @@ +# Code Review + +Please use the Skill tool to load the `review` skill to perform a code review on: $ARGUMENTS + +Please respond and write all files in English throughout the entire process. diff --git a/src/costrict/command/locales/en/security-review.txt b/src/costrict/command/locales/en/security-review.txt new file mode 100644 index 000000000..7158d1849 --- /dev/null +++ b/src/costrict/command/locales/en/security-review.txt @@ -0,0 +1,5 @@ +# Code Security Review + +Please use the Skill tool to load the `security-review` skill to perform a security review on: $ARGUMENTS + +Please respond and write all files in English throughout the entire process. diff --git a/src/costrict/command/locales/index.ts b/src/costrict/command/locales/index.ts new file mode 100644 index 000000000..ca9a0285f --- /dev/null +++ b/src/costrict/command/locales/index.ts @@ -0,0 +1,20 @@ +import { getResolvedLanguage } from 'src/utils/language.js' +import ZH_CN_REVIEW from './zh-CN/review.txt' +import EN_REVIEW from './en/review.txt' +import ZH_CN_SECURITY_REVIEW from './zh-CN/security-review.txt' +import EN_SECURITY_REVIEW from './en/security-review.txt' + +const LOCALE_MAP: Record = { zh: 'zh-CN', en: 'en' } + +const TEMPLATES: Record> = { + review: { 'zh-CN': ZH_CN_REVIEW, en: EN_REVIEW }, + 'security-review': { 'zh-CN': ZH_CN_SECURITY_REVIEW, en: EN_SECURITY_REVIEW }, +} + +export namespace CommandLocale { + export function get(name: string): string { + const lang = getResolvedLanguage() + const locale = LOCALE_MAP[lang] ?? 'zh-CN' + return TEMPLATES[name]?.[locale] ?? TEMPLATES[name]?.en ?? '' + } +} diff --git a/src/costrict/command/locales/zh-CN/review.txt b/src/costrict/command/locales/zh-CN/review.txt new file mode 100644 index 000000000..fec845816 --- /dev/null +++ b/src/costrict/command/locales/zh-CN/review.txt @@ -0,0 +1,5 @@ +# 代码审查 + +请使用 Skill 工具加载 `review` 技能来对以下内容执行代码审查:$ARGUMENTS + +全程请使用中文进行回答与文件写入。 diff --git a/src/costrict/command/locales/zh-CN/security-review.txt b/src/costrict/command/locales/zh-CN/security-review.txt new file mode 100644 index 000000000..02a2084f3 --- /dev/null +++ b/src/costrict/command/locales/zh-CN/security-review.txt @@ -0,0 +1,5 @@ +# 安全代码审查 + +请使用 Skill 工具加载 `security-review` 技能来对以下内容执行安全代码审查:$ARGUMENTS + +全程请使用中文进行回答与文件写入。 diff --git a/src/costrict/skills/reviewSkills.ts b/src/costrict/skills/reviewSkills.ts index 84ae3ce03..b324c3108 100644 --- a/src/costrict/skills/reviewSkills.ts +++ b/src/costrict/skills/reviewSkills.ts @@ -1,5 +1,6 @@ import { registerBundledSkill } from 'src/skills/bundledSkills.js' import { getResolvedLanguage } from 'src/utils/language.js' +import { CommandLocale } from 'src/costrict/command/locales/index.js' import { SKILL_FILES, SKILL_METADATA, @@ -12,11 +13,22 @@ function getLocale(): string { return LOCALE_MAP[lang] ?? 'zh-CN' } -function registerSkillVariant( +const ALLOWED_TOOLS = [ + 'Skill', + 'Glob', + 'Grep', + 'Read', + 'TodoWrite', + 'Bash', + 'Agent', +] + +function registerReviewSkill( name: string, skillKey: string, files: Record, description: string, + forked: boolean, ): void { registerBundledSkill({ name, @@ -24,19 +36,15 @@ function registerSkillVariant( whenToUse: description, userInvocable: true, disableModelInvocation: true, - allowedTools: [ - 'Glob', - 'Grep', - 'Read', - 'TodoWrite', - 'Bash', - 'Agent', - ], - model: 'inherit', - context: 'fork', + allowedTools: ALLOWED_TOOLS, + context: forked ? 'fork' : undefined, files, async getPromptForCommand(args) { - return [{ type: 'text', text: args.trim() || `Please perform a ${skillKey}.` }] + const template = CommandLocale.get(skillKey) + const text = template + ? template.replace('$ARGUMENTS', args.trim()) + : args.trim() || `Please perform a ${skillKey}.` + return [{ type: 'text', text }] }, }) } @@ -51,10 +59,10 @@ export function registerReviewSkills(): void { const meta = localeMetadata[skillKey] if (!meta || !files) continue - // Register /review, /security-review - registerSkillVariant(meta.name, skillKey, files, meta.description) + // /review, /security-review — inline in main session + registerReviewSkill(meta.name, skillKey, files, meta.description, false) - // Register /strict:review, /strict:security-review - registerSkillVariant(`strict:${skillKey}`, skillKey, files, meta.description) + // /strict:review, /strict:security-review — forked sub-agent + registerReviewSkill(`strict:${skillKey}`, skillKey, files, meta.description, true) } }