fix: add Skill tool to allowedTools and restore locale templates

- Add 'Skill' to allowedTools so model can invoke Skill tool to load
  review/security-review SKILL.md content
- Restore src/costrict/command/locales/ with zh-CN/en templates telling
  model to use Skill tool (aligns with opencode PR #360 approach)
- Remove model: 'inherit' from review registration (was resolving to
  wrong model, strict:plan works without it)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
kingboung 2026-05-12 10:50:43 +08:00
parent c431001a4a
commit e68415c7e9
6 changed files with 64 additions and 16 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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<string, string> = { zh: 'zh-CN', en: 'en' }
const TEMPLATES: Record<string, Record<string, string>> = {
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 ?? ''
}
}

View File

@ -0,0 +1,5 @@
# 代码审查
请使用 Skill 工具加载 `review` 技能来对以下内容执行代码审查:$ARGUMENTS
全程请使用中文进行回答与文件写入。

View File

@ -0,0 +1,5 @@
# 安全代码审查
请使用 Skill 工具加载 `security-review` 技能来对以下内容执行安全代码审查:$ARGUMENTS
全程请使用中文进行回答与文件写入。

View File

@ -1,5 +1,6 @@
import { registerBundledSkill } from 'src/skills/bundledSkills.js' import { registerBundledSkill } from 'src/skills/bundledSkills.js'
import { getResolvedLanguage } from 'src/utils/language.js' import { getResolvedLanguage } from 'src/utils/language.js'
import { CommandLocale } from 'src/costrict/command/locales/index.js'
import { import {
SKILL_FILES, SKILL_FILES,
SKILL_METADATA, SKILL_METADATA,
@ -12,11 +13,22 @@ function getLocale(): string {
return LOCALE_MAP[lang] ?? 'zh-CN' return LOCALE_MAP[lang] ?? 'zh-CN'
} }
function registerSkillVariant( const ALLOWED_TOOLS = [
'Skill',
'Glob',
'Grep',
'Read',
'TodoWrite',
'Bash',
'Agent',
]
function registerReviewSkill(
name: string, name: string,
skillKey: string, skillKey: string,
files: Record<string, string>, files: Record<string, string>,
description: string, description: string,
forked: boolean,
): void { ): void {
registerBundledSkill({ registerBundledSkill({
name, name,
@ -24,19 +36,15 @@ function registerSkillVariant(
whenToUse: description, whenToUse: description,
userInvocable: true, userInvocable: true,
disableModelInvocation: true, disableModelInvocation: true,
allowedTools: [ allowedTools: ALLOWED_TOOLS,
'Glob', context: forked ? 'fork' : undefined,
'Grep',
'Read',
'TodoWrite',
'Bash',
'Agent',
],
model: 'inherit',
context: 'fork',
files, files,
async getPromptForCommand(args) { 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] const meta = localeMetadata[skillKey]
if (!meta || !files) continue if (!meta || !files) continue
// Register /review, /security-review // /review, /security-review — inline in main session
registerSkillVariant(meta.name, skillKey, files, meta.description) registerReviewSkill(meta.name, skillKey, files, meta.description, false)
// Register /strict:review, /strict:security-review // /strict:review, /strict:security-review — forked sub-agent
registerSkillVariant(`strict:${skillKey}`, skillKey, files, meta.description) registerReviewSkill(`strict:${skillKey}`, skillKey, files, meta.description, true)
} }
} }