From 803abe52a5eb0ce2036fec00ddf4520c0df6080e Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Thu, 30 Apr 2026 02:33:42 -0400 Subject: [PATCH] fix: clarify configure-ecc skill copy roots --- docs/ja-JP/skills/configure-ecc/SKILL.md | 15 ++++- docs/zh-CN/skills/configure-ecc/SKILL.md | 14 ++++- skills/configure-ecc/SKILL.md | 15 ++++- .../docs/configure-ecc-install-paths.test.js | 63 +++++++++++++++++++ 4 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 tests/docs/configure-ecc-install-paths.test.js diff --git a/docs/ja-JP/skills/configure-ecc/SKILL.md b/docs/ja-JP/skills/configure-ecc/SKILL.md index e93a4d0a..0ecc1f75 100644 --- a/docs/ja-JP/skills/configure-ecc/SKILL.md +++ b/docs/ja-JP/skills/configure-ecc/SKILL.md @@ -130,9 +130,20 @@ Options: ### 2c: インストールの実行 -選択された各スキルについて、スキルディレクトリ全体をコピーします: +選択された各スキルについて、正しいソースルートからスキルディレクトリ全体をコピーします: + ```bash -cp -r $ECC_ROOT/skills/ $TARGET/skills/ +# ステップ 2a で選択したコアスキルは .agents/skills/ 配下にあります +cp -R "$ECC_ROOT/.agents/skills/" "$TARGET/skills/" + +# ステップ 2b/2c で選択したニッチスキルは skills/ 配下にあります +cp -R "$ECC_ROOT/skills/" "$TARGET/skills/" +``` + +glob で取得したソースディレクトリを処理するときは、trailing slash 付きのソースをそのまま `cp` に渡さないでください。宛先名にディレクトリ名を明示します: + +```bash +cp -R "${src%/}" "$TARGET/skills/$(basename "${src%/}")" ``` 注: `continuous-learning` と `continuous-learning-v2` には追加ファイル(config.json、フック、スクリプト)があります — SKILL.md だけでなく、ディレクトリ全体がコピーされることを確認してください。 diff --git a/docs/zh-CN/skills/configure-ecc/SKILL.md b/docs/zh-CN/skills/configure-ecc/SKILL.md index 8a07d030..d4f02643 100644 --- a/docs/zh-CN/skills/configure-ecc/SKILL.md +++ b/docs/zh-CN/skills/configure-ecc/SKILL.md @@ -199,10 +199,20 @@ mkdir -p $TARGET/skills $TARGET/rules ### 2d: 执行安装 -对于每个选定的技能,复制整个技能目录: +对于每个选定的技能,请从正确的源目录复制整个技能目录: ```bash -cp -r $ECC_ROOT/skills/ $TARGET/skills/ +# 步骤 2a 选中的核心技能位于 .agents/skills/ +cp -R "$ECC_ROOT/.agents/skills/" "$TARGET/skills/" + +# 步骤 2b/2c 选中的细分技能位于 skills/ +cp -R "$ECC_ROOT/skills/" "$TARGET/skills/" +``` + +遍历 glob 得到的源目录时,不要把带 trailing slash 的源路径直接传给 `cp`。显式使用目录名作为目标名: + +```bash +cp -R "${src%/}" "$TARGET/skills/$(basename "${src%/}")" ``` 注意:`continuous-learning` 和 `continuous-learning-v2` 有额外的文件(config.json、钩子、脚本)——确保复制整个目录,而不仅仅是 SKILL.md。 diff --git a/skills/configure-ecc/SKILL.md b/skills/configure-ecc/SKILL.md index 5f53503a..cf38d362 100644 --- a/skills/configure-ecc/SKILL.md +++ b/skills/configure-ecc/SKILL.md @@ -195,9 +195,20 @@ For each selected category, print the full list of skills below and ask the user ### 2d: Execute Installation -For each selected skill, copy the entire skill directory: +For each selected skill, copy the entire skill directory from the correct source root: + ```bash -cp -r $ECC_ROOT/skills/ $TARGET/skills/ +# Core skills selected from Step 2a live under .agents/skills/ +cp -R "$ECC_ROOT/.agents/skills/" "$TARGET/skills/" + +# Niche skills selected from Step 2b/2c live under skills/ +cp -R "$ECC_ROOT/skills/" "$TARGET/skills/" +``` + +When iterating over globbed source directories, never pass a trailing-slash source directly to `cp`. Use the directory path as the destination name explicitly: + +```bash +cp -R "${src%/}" "$TARGET/skills/$(basename "${src%/}")" ``` Note: `continuous-learning` and `continuous-learning-v2` have extra files (config.json, hooks, scripts) — ensure the entire directory is copied, not just SKILL.md. diff --git a/tests/docs/configure-ecc-install-paths.test.js b/tests/docs/configure-ecc-install-paths.test.js new file mode 100644 index 00000000..a5787e9c --- /dev/null +++ b/tests/docs/configure-ecc-install-paths.test.js @@ -0,0 +1,63 @@ +'use strict'; + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const repoRoot = path.resolve(__dirname, '..', '..'); + +const configureEccDocs = [ + 'skills/configure-ecc/SKILL.md', + 'docs/zh-CN/skills/configure-ecc/SKILL.md', + 'docs/ja-JP/skills/configure-ecc/SKILL.md', +]; + +let passed = 0; +let failed = 0; + +function test(name, fn) { + try { + fn(); + console.log(` ✓ ${name}`); + passed++; + } catch (error) { + console.log(` ✗ ${name}`); + console.log(` Error: ${error.message}`); + failed++; + } +} + +console.log('\n=== Testing configure-ecc install path guidance ===\n'); + +for (const relativePath of configureEccDocs) { + const content = fs.readFileSync(path.join(repoRoot, relativePath), 'utf8'); + + test(`${relativePath} separates core and niche skill source roots`, () => { + assert.ok( + content.includes('$ECC_ROOT/.agents/skills/'), + 'Expected configure-ecc to document the core skill source root' + ); + assert.ok( + content.includes('$ECC_ROOT/skills/'), + 'Expected configure-ecc to document the niche skill source root' + ); + }); + + test(`${relativePath} documents defensive copy form for trailing slash sources`, () => { + assert.ok( + content.includes('${src%/}'), + 'Expected configure-ecc to strip trailing slash before copying' + ); + assert.ok( + content.includes('$(basename "${src%/}")'), + 'Expected configure-ecc to preserve the skill directory name explicitly' + ); + }); +} + +if (failed > 0) { + console.log(`\nFailed: ${failed}`); + process.exit(1); +} + +console.log(`\nPassed: ${passed}`);