diff --git a/SKILLS.md b/SKILLS.md index 2bea1e8..0c1c1b3 100644 --- a/SKILLS.md +++ b/SKILLS.md @@ -4,8 +4,8 @@ 并给出与本 Playbook(`docs/` + `rulesets/`)配套的技能编写建议与内置技能清单。 > 提示:Codex skills 是“按用户安装”的(默认在 -> `~/.codex/skills`)。本仓库将 skills 以可分发的形式放在 -> `codex/skills/`,并提供脚本一键安装到你的 `CODEX_HOME`。 +> `~/.agents/skills`)。本仓库将 skills 以可分发的形式放在 +> `codex/skills/`,并提供脚本一键安装到你的 `~/.agents`。 --- @@ -38,14 +38,14 @@ codex/skills/ 最终安装到本机后,对应路径为: ```txt -$CODEX_HOME/skills//SKILL.md +~/.agents/skills//SKILL.md ``` --- ## 3. 安装到本机(推荐) -使用统一入口 `playbook.py` 安装 skills(会把 `codex/skills/*` 复制到 `$CODEX_HOME/skills/`): +使用统一入口 `playbook.py` 安装 skills(会把 `codex/skills/*` 复制到 `~/.agents/skills/`): ```toml # playbook.toml @@ -54,7 +54,7 @@ project_root = "." [install_skills] mode = "all" # list|all -codex_home = "~/.codex" +agents_home = "~/.agents" ``` ```bash @@ -74,10 +74,10 @@ skills = ["style-cleanup", "commit-message"] ```toml [install_skills] mode = "all" -codex_home = "./.codex" +agents_home = "./.agents" ``` -> 注意:Codex 只会从 `CODEX_HOME` 加载 skills;使用本地安装时,启动 Codex 需设置同样的 `CODEX_HOME`。 +> 注意:Codex 默认从 `~/.agents/skills` 加载 skills;使用本地安装时,需要确保 Codex 能发现该路径。 如果你的项目通过 `git subtree` vendoring 本 Playbook(推荐前缀 `docs/standards/playbook`),则在目标项目里执行: diff --git a/codex/skills/writing-skills/SKILL.md b/codex/skills/writing-skills/SKILL.md index c60f18a..f97a3ee 100644 --- a/codex/skills/writing-skills/SKILL.md +++ b/codex/skills/writing-skills/SKILL.md @@ -9,7 +9,7 @@ description: Use when creating new skills, editing existing skills, or verifying **Writing skills IS Test-Driven Development applied to process documentation.** -**Personal skills live in agent-specific directories (`~/.claude/skills` for Claude Code, `~/.codex/skills` for Codex)** +**Personal skills live in agent-specific directories (`~/.claude/skills` for Claude Code, `~/.agents/skills` for Codex)** You write test cases (pressure scenarios with subagents), watch them fail (baseline behavior), write the skill (documentation), watch tests pass (agents comply), and refactor (close loopholes). diff --git a/playbook.toml.example b/playbook.toml.example index fd09ce1..fe91a93 100644 --- a/playbook.toml.example +++ b/playbook.toml.example @@ -14,6 +14,7 @@ [sync_rules] # 同步 AGENT_RULES.md(配置节存在即启用) # force = false # 可选:覆盖已有文件 +# no_backup = false # 可选:跳过备份 [sync_memory_bank] # 同步 memory-bank/(配置节存在即启用) @@ -32,11 +33,12 @@ [sync_standards] # langs = ["tsl", "cpp"] # 必填:要同步的语言 # gitattr_mode = "append" # append(补全缺失)|overwrite(覆盖)|block(插入块)|skip(跳过) +# no_backup = false # 可选:跳过备份(.agents/.gitattributes) [install_skills] # mode = "list" # list|all # skills = ["brainstorming"] # mode=list 时必填 -# codex_home = "~/.codex" # 可选:默认 ~/.codex +# agents_home = "~/.agents" # 可选:默认 ~/.agents [format_md] # tool = "prettier" # 仅支持 prettier diff --git a/scripts/playbook.py b/scripts/playbook.py index 51d001c..c41045a 100644 --- a/scripts/playbook.py +++ b/scripts/playbook.py @@ -1056,16 +1056,19 @@ def normalize_globs(raw: object) -> list[str]: def install_skills_action(config: dict, context: dict) -> int: mode = str(config.get("mode", "list")).lower() - codex_home = Path(config.get("codex_home", "~/.codex")).expanduser() - if not codex_home.is_absolute(): - codex_home = (context["project_root"] / codex_home).resolve() + if "codex_home" in config: + print("ERROR: codex_home is no longer supported; use agents_home", file=sys.stderr) + return 2 + agents_home = Path(config.get("agents_home", "~/.agents")).expanduser() + if not agents_home.is_absolute(): + agents_home = (context["project_root"] / agents_home).resolve() skills_src_root = PLAYBOOK_ROOT / "codex/skills" if not skills_src_root.is_dir(): print(f"ERROR: skills source not found: {skills_src_root}", file=sys.stderr) return 2 - skills_dst_root = codex_home / "skills" + skills_dst_root = agents_home / "skills" ensure_dir(skills_dst_root) if mode == "all": diff --git a/tests/cli/test_playbook_cli.py b/tests/cli/test_playbook_cli.py index d070fa9..bb605b0 100644 --- a/tests/cli/test_playbook_cli.py +++ b/tests/cli/test_playbook_cli.py @@ -126,6 +126,27 @@ langs = ["tsl"] self.assertEqual(block[bullet_idx - 1], "") def test_install_skills(self): + with tempfile.TemporaryDirectory() as tmp_dir: + target = Path(tmp_dir) / "agents" + config_body = f""" +[playbook] +project_root = "{tmp_dir}" + +[install_skills] +agents_home = "{target}" +mode = "list" +skills = ["brainstorming"] +""" + config_path = Path(tmp_dir) / "playbook.toml" + config_path.write_text(config_body, encoding="utf-8") + + result = run_cli("-config", str(config_path)) + + skill_file = target / "skills/brainstorming/SKILL.md" + self.assertEqual(result.returncode, 0) + self.assertTrue(skill_file.is_file()) + + def test_install_skills_rejects_codex_home(self): with tempfile.TemporaryDirectory() as tmp_dir: target = Path(tmp_dir) / "codex" config_body = f""" @@ -142,9 +163,8 @@ skills = ["brainstorming"] result = run_cli("-config", str(config_path)) - skill_file = target / "skills/brainstorming/SKILL.md" - self.assertEqual(result.returncode, 0) - self.assertTrue(skill_file.is_file()) + self.assertNotEqual(result.returncode, 0) + self.assertIn("codex_home", result.stdout + result.stderr) if __name__ == "__main__": unittest.main()