@@ -88,6 +88,9 @@ const TARGETS = [
8888 // 写 `read: CONVENTIONS.md`。所以装完必须打印激活方式,否则又是「装了不生效」。
8989 { name : 'Aider' , dir : '.aider/skills' , detect : [ '.aider.conf.yml' , '.aider.chat.history.md' , '.aider.tags.cache.v3' , '.aider' ] } ,
9090 { name : 'OpenCode' , dir : '.opencode/skills' , detect : '.opencode' , global : { dir : '.config/opencode/skills' , detect : '.config/opencode' } } ,
91+ // Qwen Code = QwenLM/qwen-code 这个 CLI(Gemini CLI 的 fork),**不是**通义灵码
92+ // (通义灵码是阿里的 IDE 插件,另一个产品,路径完全不同)。旧文档写混过。
93+ // 路径经官方文档核实:项目 .qwen/skills/、用户 ~/.qwen/skills/,自动发现无需配置。
9194 { name : 'Qwen Code' , dir : '.qwen/skills' , detect : '.qwen' , global : { dir : '.qwen/skills' , detect : '.qwen' } } ,
9295 // Hermes 官方文档:只自动加载 ~/.hermes/skills/("the primary directory and
9396 // source of truth"),项目级目录不被自动发现,外部目录必须写进
@@ -525,6 +528,57 @@ ${skillList}
525528 }
526529}
527530
531+ // Qwen Code 与 Gemini CLI 同源(前者是后者的 fork),两套机制都对得上:
532+ // - skills:官方文档确认自动发现 .qwen/skills/ 与 ~/.qwen/skills/,无需配置
533+ // (qwenlm.github.io/qwen-code-docs/en/users/features/skills/)
534+ // - bootstrap:分层记忆系统的默认上下文文件就是 QWEN.md,从 cwd 逐层向上到项目根
535+ // 发现并拼接(可用 contextFileName 改名,默认 QWEN.md);全局在 ~/.qwen/QWEN.md
536+ // v1.7.10 及更早只装 skills、不写 bootstrap —— skills 能被发现,但没有引导就不会
537+ // 在恰当时机自动触发,等于死重。
538+ function generateQwenBootstrap ( baseDir , isGlobal ) {
539+ const skillEntries = scanSkillEntries ( SKILLS_SRC ) ;
540+ const skillList = skillEntries . map ( s => `- **${ s . name } **: ${ s . desc } ` ) . join ( '\n' ) ;
541+ const scope = isGlobal ? '已全局安装 superpowers-zh 技能框架,所有项目共享' : '本项目已安装 superpowers-zh 技能框架' ;
542+ const skillsRef = isGlobal ? '~/.qwen/skills/' : '.qwen/skills/' ;
543+
544+ const content = `# Superpowers-ZH 中文增强版
545+
546+ ${ scope } (${ skillEntries . length } 个 skills)。
547+
548+ ## 核心规则
549+
550+ 1. **收到任务时,先检查是否有匹配的 skill** — 哪怕只有 1% 的可能性也要检查
551+ 2. **设计先于编码** — 收到功能需求时,先用 brainstorming skill 做需求分析
552+ 3. **测试先于实现** — 写代码前先写测试(TDD)
553+ 4. **验证先于完成** — 声称完成前必须运行验证命令
554+
555+ ## 可用 Skills
556+
557+ Skills 位于 \`${ skillsRef } \` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。
558+
559+ ${ skillList }
560+
561+ ## 如何使用
562+
563+ 当任务匹配某个 skill 时,读取对应的 \`${ skillsRef } <skill-name>/SKILL.md\` 并严格遵循其流程。
564+ ` ;
565+
566+ const qwenPath = isGlobal ? resolve ( baseDir , '.qwen' , 'QWEN.md' ) : resolve ( baseDir , 'QWEN.md' ) ;
567+ mkdirSync ( dirname ( qwenPath ) , { recursive : true } ) ;
568+ if ( existsSync ( qwenPath ) ) {
569+ const existing = readFileSync ( qwenPath , 'utf8' ) ;
570+ if ( ! existing . includes ( 'superpowers-zh' ) ) {
571+ writeFileSync ( qwenPath , existing . replace ( / \s + $ / , '' ) + '\n\n' + wrapWithSentinel ( content ) , 'utf8' ) ;
572+ console . log ( ` ✅ Qwen Code: 追加 skills 引用 -> ${ qwenPath } ` ) ;
573+ } else {
574+ console . log ( ` ✅ Qwen Code: QWEN.md 已包含 superpowers-zh 引用` ) ;
575+ }
576+ } else {
577+ writeFileSync ( qwenPath , wrapWithSentinel ( content ) , 'utf8' ) ;
578+ console . log ( ` ✅ Qwen Code: bootstrap -> ${ qwenPath } ` ) ;
579+ }
580+ }
581+
528582function generateHermesBootstrap ( projectDir , isGlobal ) {
529583 // 全局模式不写 bootstrap:Hermes 的用户级指令文件约定未在 docs 证实,
530584 // 往 $HOME 根目录写 HERMES.md 是猜路径 + 污染主目录。~/.hermes/skills/ 里的
@@ -854,6 +908,10 @@ function installForTarget(target, baseDir, isGlobal) {
854908 generateGeminiBootstrap ( baseDir , isGlobal ) ;
855909 }
856910
911+ if ( target . name === 'Qwen Code' ) {
912+ generateQwenBootstrap ( baseDir , isGlobal ) ;
913+ }
914+
857915 if ( target . name === 'Hermes Agent' ) {
858916 generateHermesBootstrap ( baseDir , isGlobal ) ;
859917 }
@@ -904,6 +962,7 @@ const LEGACY_SKILL_DIRS = ['.kiro/steering'];
904962const BOOTSTRAP_CLEAN_SECTION = [
905963 'CLAUDE.md' ,
906964 'GEMINI.md' ,
965+ 'QWEN.md' ,
907966 'HERMES.md' ,
908967 'CONVENTIONS.md' ,
909968 'CODEBUDDY.md' ,
@@ -987,7 +1046,9 @@ function cleanBootstrapSection(filePath) {
9871046// 仅 Claude Code(~/.claude/CLAUDE.md,全局记忆已证实)和 Qoder(~/.qoder/rules/,镜像其项目机制)
9881047// 会写全局 bootstrap;其余全局工具靠 skill 自动发现,无 bootstrap 需清理。
9891048const GLOBAL_BOOTSTRAP_DELETE = [ '.qoder/rules/superpowers-zh.md' ] ;
990- const GLOBAL_BOOTSTRAP_CLEAN_SECTION = [ '.claude/CLAUDE.md' ] ;
1049+ // qwen 在 GLOBAL_OK 里,--global 会写 ~/.qwen/QWEN.md,全局卸载必须清掉它,
1050+ // 否则 --global 装卸一轮会在用户主目录留残留。
1051+ const GLOBAL_BOOTSTRAP_CLEAN_SECTION = [ '.claude/CLAUDE.md' , '.qwen/QWEN.md' ] ;
9911052
9921053function uninstallForTarget ( target , srcSkillNames , baseDir , isGlobal ) {
9931054 const relDir = isGlobal ? ( target . global && target . global . dir ) : target . dir ;
0 commit comments