refactor: 优化 Claude Code 规则入口 (#6)
This commit is contained in:
@@ -1,24 +1,9 @@
|
|||||||
# Claude Code 项目入口
|
# Claude Code 项目入口
|
||||||
|
|
||||||
本仓库的完整开发规则以 [AGENTS.md](AGENTS.md) 为唯一事实来源。
|
@AGENTS.md
|
||||||
|
|
||||||
Claude Code 开始任何工作前,必须按顺序阅读:
|
## Claude Code 专用说明
|
||||||
|
|
||||||
1. 根目录的 `AGENTS.md`;
|
- 上方导入的 `AGENTS.md` 是所有编码 Agent 的共同规则事实来源,Claude Code 必须完整遵守。
|
||||||
2. Gitea Wiki 的项目档案;Wiki 不可用时读取 `docs/00-project-profile.md` 镜像并明确其 revision;
|
- 本文件只记录 Claude Code 特有的入口或工具差异;当前没有额外的项目专用差异。
|
||||||
3. Gitea Wiki 的架构与代码地图、业务规则,以及任务直接涉及的主题页;
|
- 共同规则变化时只修改 `AGENTS.md`,不要在本文件重复维护。
|
||||||
4. 任务涉及目录中更具体的 `AGENTS.md`;
|
|
||||||
5. 当前 Gitea 工单及其父级 MVP、Epic 工单。
|
|
||||||
|
|
||||||
必须遵守以下入口规则:
|
|
||||||
|
|
||||||
- 方案经用户确认并建立单元任务工单后,才能修改产品代码。
|
|
||||||
- 只修改当前工单范围内的文件,保留用户已有和无关的改动。
|
|
||||||
- 在单元任务中明确文档影响;入口、命令、配置、数据、业务规则或排错方式变化时先更新对应 Wiki。
|
|
||||||
- 严格遵守 `AGENTS.md` 的效率与范围控制:优先真实反馈、复用未失效的检查结果、完成必要闭环后停止,但不得省略安全和最终验收。
|
|
||||||
- 实现、测试、Git 提交、待验收、Wiki 任务归档、导出本地镜像和关闭工单的顺序不得跳过。
|
|
||||||
- 长期文档先修改 Wiki,再导出 `docs/`;不得直接编辑镜像作为最终结果。
|
|
||||||
- 未经用户明确验收,不得关闭工单。
|
|
||||||
- 不得把密码、令牌、Cookie、私钥或生产数据写入代码、日志、工单和文档。
|
|
||||||
|
|
||||||
不要在本文件复制完整工作流。流程发生变化时只更新 `AGENTS.md`,本文件保持为 Claude Code 的稳定入口,防止两套规则不一致。
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ CORE_DOCUMENT_REQUIREMENTS = {
|
|||||||
}
|
}
|
||||||
REQUIRED_FILES = (
|
REQUIRED_FILES = (
|
||||||
"AGENTS.md",
|
"AGENTS.md",
|
||||||
|
"CLAUDE.md",
|
||||||
"README.md",
|
"README.md",
|
||||||
"docs/00-project-profile.md",
|
"docs/00-project-profile.md",
|
||||||
"docs/01-workflow.md",
|
"docs/01-workflow.md",
|
||||||
@@ -191,6 +192,25 @@ def check_agent_efficiency_rules(errors: list[str], root: Path = ROOT) -> None:
|
|||||||
errors.append(f"AGENTS.md 缺少:{section}")
|
errors.append(f"AGENTS.md 缺少:{section}")
|
||||||
|
|
||||||
|
|
||||||
|
def check_claude_code_entry(errors: list[str], root: Path = ROOT) -> None:
|
||||||
|
"""检查 Claude Code 入口直接复用共同 Agent 规则。"""
|
||||||
|
|
||||||
|
path = root / "CLAUDE.md"
|
||||||
|
if not path.is_file():
|
||||||
|
return
|
||||||
|
content = path.read_text(encoding="utf-8")
|
||||||
|
lines = {line.strip() for line in content.splitlines()}
|
||||||
|
if "@AGENTS.md" not in lines:
|
||||||
|
errors.append("CLAUDE.md 缺少独立的 @AGENTS.md 导入")
|
||||||
|
required = (
|
||||||
|
"共同规则事实来源",
|
||||||
|
"只记录 Claude Code 特有",
|
||||||
|
"只修改 `AGENTS.md`",
|
||||||
|
)
|
||||||
|
for section in missing_sections(content, required):
|
||||||
|
errors.append(f"CLAUDE.md 缺少:{section}")
|
||||||
|
|
||||||
|
|
||||||
def core_mapping_errors(configured_mappings: dict[str, str]) -> list[str]:
|
def core_mapping_errors(configured_mappings: dict[str, str]) -> list[str]:
|
||||||
errors: list[str] = []
|
errors: list[str] = []
|
||||||
for page, expected_path in CORE_PAGE_PATHS.items():
|
for page, expected_path in CORE_PAGE_PATHS.items():
|
||||||
@@ -258,6 +278,7 @@ def main() -> int:
|
|||||||
check_core_documents(errors)
|
check_core_documents(errors)
|
||||||
check_task_template(errors)
|
check_task_template(errors)
|
||||||
check_agent_efficiency_rules(errors)
|
check_agent_efficiency_rules(errors)
|
||||||
|
check_claude_code_entry(errors)
|
||||||
check_archives(errors)
|
check_archives(errors)
|
||||||
|
|
||||||
for warning in warnings:
|
for warning in warnings:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@ from check_harness import ( # noqa: E402
|
|||||||
CORE_DOCUMENT_REQUIREMENTS,
|
CORE_DOCUMENT_REQUIREMENTS,
|
||||||
CORE_PAGE_PATHS,
|
CORE_PAGE_PATHS,
|
||||||
REQUIRED_FILES,
|
REQUIRED_FILES,
|
||||||
|
check_claude_code_entry,
|
||||||
check_core_documents,
|
check_core_documents,
|
||||||
check_agent_efficiency_rules,
|
check_agent_efficiency_rules,
|
||||||
check_task_template,
|
check_task_template,
|
||||||
@@ -62,6 +64,23 @@ class AgentRuleTests(unittest.TestCase):
|
|||||||
check_agent_efficiency_rules(errors)
|
check_agent_efficiency_rules(errors)
|
||||||
self.assertEqual(errors, [])
|
self.assertEqual(errors, [])
|
||||||
|
|
||||||
|
def test_claude_code_entry_imports_shared_rules(self) -> None:
|
||||||
|
errors: list[str] = []
|
||||||
|
check_claude_code_entry(errors)
|
||||||
|
self.assertEqual(errors, [])
|
||||||
|
|
||||||
|
def test_claude_code_entry_requires_exact_import_line(self) -> None:
|
||||||
|
with tempfile.TemporaryDirectory() as directory:
|
||||||
|
root = Path(directory)
|
||||||
|
(root / "CLAUDE.md").write_text(
|
||||||
|
"共同规则事实来源\n只记录 Claude Code 特有\n"
|
||||||
|
"共同规则只修改 `AGENTS.md`\n",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
errors: list[str] = []
|
||||||
|
check_claude_code_entry(errors, root)
|
||||||
|
self.assertIn("CLAUDE.md 缺少独立的 @AGENTS.md 导入", errors)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user