@@ -58,9 +58,15 @@ const TARGETS = [
5858 // Cursor 经官方文档核实(cursor.com/docs/skills):.cursor/skills/<name>/SKILL.md,
5959 // 启动时自动发现并交给 Agent 按上下文选用,也可在对话里打 / 手动点名。无需配置。
6060 { name : 'Cursor' , dir : '.cursor/skills' , detect : [ '.cursor' , '.cursorrules' ] } ,
61- // Codex 全局:docs 确认 Codex 启动时扫描 ~/.agents/skills/(不是 ~/.codex/skills),
62- // 直接把每个 skill 复制到 ~/.agents/skills/<skill>/ 正好命中它的扁平扫描。
63- { name : 'Codex CLI' , dir : '.codex/skills' , detect : '.codex' , global : { dir : '.agents/skills' , detect : '.codex' } } ,
61+ // Codex 各层级扫的都是 .agents/skills,**从不扫 .codex/skills**。官方文档
62+ // (developers.openai.com/codex/skills,308 跳 learn.chatgpt.com/docs/build-skills)
63+ // 给出的完整清单只有:
64+ // $CWD/.agents/skills、$CWD/../.agents/skills、$REPO_ROOT/.agents/skills
65+ // $HOME/.agents/skills、/etc/codex/skills、以及内置 skill
66+ // 全局一直是对的(~/.agents/skills),但**项目级原来装到 .codex/skills —— Codex
67+ // 不读那里,等于装了不生效**。v1.7.11 改为 .agents/skills,并清理旧位置。
68+ // 与 Antigravity 装在同一目录是预期的:两者共用 .agents/skills 这个开放约定。
69+ { name : 'Codex CLI' , dir : '.agents/skills' , detect : '.codex' , global : { dir : '.agents/skills' , detect : '.codex' } } ,
6470 // Kiro 的 steering 与 Cline / Kilo 的 rules 同性质:**每轮常驻**。官方文档
6571 // (kiro.dev/docs/steering)明确 `.kiro/steering/` 下的文件默认 inclusion: always,
6672 // "loaded into every Kiro interaction automatically"。
@@ -140,10 +146,14 @@ const TARGETS = [
140146 // 优先级 项目级 > 用户级。v1.7.10 及更早文档写「用户级路径尚未验证」而没有
141147 // --global —— 现已核实,补上。
142148 { name : 'CodeBuddy' , dir : '.codebuddy/skills' , detect : [ '.codebuddy' , 'CODEBUDDY.md' ] , global : { dir : '.codebuddy/skills' , detect : '.codebuddy' } } ,
143- // 华为云码道(CodeArts Doer):skills 放 .codeartsdoer/skills/(用户在 #20 确认)。
144- // 仅 skills-only —— 其 bootstrap/指令文件约定未证实,靠 CodeArts 自身 skill 发现;
145- // 若不自动触发需在对话里手动点名 skill(docs 已说明)。
146- { name : 'CodeArts' , dir : '.codeartsdoer/skills' , detect : '.codeartsdoer' } ,
149+ // 华为云码道(CodeArts Doer)。原注释只写「用户在 #20 确认」—— 已补官方出处:
150+ // support.huaweicloud.com/usermanual-codeartssnap/codeartsdoer_ug_0024.html
151+ // 项目级:项目根目录的 ./.codeartsdoer/skills/
152+ // 个人级:%USERPROFILE%/.codeartsdoer/skills ← 即 ~/.codeartsdoer/skills
153+ // 每个 skill 目录根必须有 SKILL.md,自动发现、创建后立刻生效、无需配置。
154+ // 个人级路径既然已证实,v1.7.11 起支持 --global(此前一直在拒绝名单里)。
155+ // 仍是 skills-only —— 其 bootstrap/指令文件约定未证实,不猜路径。
156+ { name : 'CodeArts' , dir : '.codeartsdoer/skills' , detect : '.codeartsdoer' , global : { dir : '.codeartsdoer/skills' , detect : '.codeartsdoer' } } ,
147157 // Cline / Kilo Code 是 VS Code 扩展,加载的是「rules」而非 skills,且 rules 每轮常驻
148158 // system prompt。因此 skills 放各自的 skills/ 目录(不被自动加载),只在 rules 目录里
149159 // 放一份小索引 —— 见 generateClineBootstrapRule / generateKiloCodeBootstrapRule。
@@ -1058,6 +1068,24 @@ function installForTarget(target, baseDir, isGlobal) {
10581068 generateQwenBootstrap ( baseDir , isGlobal ) ;
10591069 }
10601070
1071+ // Codex 项目级旧位置清理:v1.7.10 及更早装到 .codex/skills,而 Codex 从不扫那里。
1072+ // 升级的人通常直接重装不会先卸载,不清的话旧目录留着白占地方、还让人以为在生效。
1073+ if ( target . name === 'Codex CLI' && ! isGlobal ) {
1074+ const legacy = resolve ( baseDir , '.codex' , 'skills' ) ;
1075+ if ( existsSync ( legacy ) ) {
1076+ const ours = new Set ( scanSkillEntries ( SKILLS_SRC ) . map ( s => s . name ) ) ;
1077+ let n = 0 ;
1078+ for ( const e of readdirSync ( legacy , { withFileTypes : true } ) ) {
1079+ if ( e . isDirectory ( ) && ours . has ( e . name ) ) { rmSync ( resolve ( legacy , e . name ) , { recursive : true , force : true } ) ; n ++ ; }
1080+ }
1081+ if ( n > 0 ) {
1082+ console . log ( ` 🧹 Codex: 清理旧位置 ${ n } 个 skill 目录 <- .codex/skills/` ) ;
1083+ console . log ( ` (Codex 只扫 .agents/skills,旧版装错了地方)` ) ;
1084+ }
1085+ try { if ( readdirSync ( legacy ) . filter ( x => x !== '.DS_Store' ) . length === 0 ) rmSync ( legacy , { recursive : true , force : true } ) ; } catch { }
1086+ }
1087+ }
1088+
10611089 if ( target . name === 'VS Code' ) {
10621090 generateVSCodeBootstrap ( baseDir ) ;
10631091 }
@@ -1113,7 +1141,7 @@ const BOOTSTRAP_DELETE = [
11131141// v1.7.9 及更早把 skill 正文直接装进 .kiro/steering/<skill>/,而 steering 每轮常驻 ——
11141142// 那 335 KB 会一直进 prompt。升级的用户不会重跑旧版卸载,所以这里按老路径也清一遍,
11151143// 否则新旧两份并存,开销问题原样保留。
1116- const LEGACY_SKILL_DIRS = [ '.kiro/steering' ] ;
1144+ const LEGACY_SKILL_DIRS = [ '.kiro/steering' , '.codex/skills' ] ;
11171145const BOOTSTRAP_CLEAN_SECTION = [
11181146 'CLAUDE.md' ,
11191147 'GEMINI.md' ,
@@ -1387,10 +1415,19 @@ function install(forceToolName, force, isGlobal) {
13871415 let installed = 0 ;
13881416 const pool = isGlobal ? GLOBAL_TARGETS : TARGETS ;
13891417
1418+ // 先把所有工具的检测结果一次性算完,再开始装。
1419+ // 边装边判会有顺序依赖:Codex 装到 .agents/skills 会创建 .agents/,紧接着
1420+ // Antigravity(detect: '.agents')就被误判为「项目里有」,于是多装一份。
1421+ // 两款共用 .agents/skills 是官方约定,但检测必须基于**安装前**的项目状态。
1422+ const detectedBefore = new Map ( ) ;
1423+ for ( const target of pool ) {
1424+ const dm = isGlobal ? target . global . detect : target . detect ;
1425+ const ds = Array . isArray ( dm ) ? dm : [ dm ] ;
1426+ detectedBefore . set ( target . name , ds . some ( d => existsSync ( resolve ( baseDir , d ) ) ) ) ;
1427+ }
1428+
13901429 for ( const target of pool ) {
1391- const detectMarker = isGlobal ? target . global . detect : target . detect ;
1392- const detects = Array . isArray ( detectMarker ) ? detectMarker : [ detectMarker ] ;
1393- const found = detects . some ( d => existsSync ( resolve ( baseDir , d ) ) ) ;
1430+ const found = detectedBefore . get ( target . name ) ;
13941431 if ( found ) {
13951432 installForTarget ( target , baseDir , isGlobal ) ;
13961433 installed ++ ;
0 commit comments