diff --git a/CLAUDE.md b/CLAUDE.md index e524e1a..f06cb14 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,10 +1,68 @@ # CLAUDE.md -## Entry Point +## AI AGENT — STOP. READ THIS FIRST. -This project uses **Skill workflow documents → manual Agent calls** pattern. Slash commands like `/smoke-test` are **not registered** as Claude Code commands — they are workflow documents in `skills/` that describe step-by-step processes. The main thread reads the Skill doc, then calls `Agent(subagent_type="xxx")` sequentially. +**This is a Test-Agent project. It has a defined execution framework. You MUST follow it.** -There is **no auto-orchestration engine**. The main thread reads Skill docs and calls Agents sequentially. Agents may invoke utils but often implement equivalent logic themselves. +- Do NOT call `Agent()` directly. +- Do NOT spawn sub-agents without reading the relevant Skill doc first. +- Do NOT skip the Skill workflow layer. + +**Correct flow:** +1. Read `skills/.md` to understand the workflow +2. Follow the Skill doc's step-by-step agent call sequence +3. Call `Agent(subagent_type="xxx")` ONLY when and how the Skill doc says + +**If no Skill doc matches the task:** fall back to `skills/test-coordinator.md` (通用编排). + +--- + +## Two Ways to Use Test-Agent + +### Way 1: Standalone CLI (no AI required) + +```bash +cd project-dir +pip install -e runtime/ # first time only +tagent run "path/to/prd.md" # router + orchestrator end-to-end +tagent catalog # list 16 experts + 32 skills +tagent status # check run status +tagent report # full execution report +tagent doctor # health check +``` + +The CLI uses the same runtime (router + orchestrator + utils) without needing Claude Code. + +### Way 2: Claude Code Agent Collaboration (AI-assisted) + +```bash +cd project-dir && claude +# Inside Claude Code: +# 1. Read skills/smoke-test.md +# 2. Follow the workflow: call Agent(subagent_type="requirements-analyst"), then test-lead, etc. +# 3. Outputs in workspace/ +``` + +**⚠️ Critical:** Claude Code agents WILL try to bypass the Skill layer and call Agent() directly. The main thread MUST enforce reading Skill docs first. + +--- + +## Architecture + +``` +Standalone CLI (tagent) AI Agent Mode (Claude Code) + │ │ + ▼ ▼ + runtime/router Skill docs (skills/*.md) + │ │ + ▼ ▼ + runtime/orchestrator Agent defs (agents/*.md) + │ │ + ▼ ▼ + utils/*.py (78 modules) utils/*.py (78 modules) +``` + +Both paths converge at the utils execution layer. ## Directory Map @@ -13,31 +71,17 @@ There is **no auto-orchestration engine**. The main thread reads Skill docs and | Agent definitions | `agents/` (16 agents) | | Skill workflow docs | `skills/` (35 skills) | | Python utils | `utils/` (78 modules) | +| Runtime (CLI + orchestrator + MCP) | `runtime/` | | Config templates | `config/` (incl. `.env.example`) | | Test outputs | `workspace/` | -| Runtime / MCP | `runtime/` | | CI pipelines | `ci/` | | Docs | `docs/` | | Marketplace | `marketplace/` | -## How to Run - -1. Copy `config/.env.example` to `.env` and fill in required values -2. Read the relevant Skill doc in `skills/` to understand the workflow -3. Call agents manually via `Agent(subagent_type="xxx")` following the Skill flow -4. Outputs land in `workspace/` - -## Architecture - -``` -Skill docs (skills/*.md) → define workflows -Agent defs (agents/*.md) → define roles + tool access -Utils (utils/*.py) → executable implementations -``` - -## Design Limitations +## Design Notes -- `/smoke-test` etc. are **not** registered slash commands. They are workflow documents. -- Agent definitions contain Python import hints (e.g. `from utils.prd_loader import load_prd`) as prompts for AI agents, not actual executable code. -- `test-lead` cannot recursively spawn sub-agents (Claude Code architecture limitation). +- Slash commands like `/smoke-test` are **not** registered. They are Skill workflow documents. +- Agent definitions contain Python import hints as prompts for AI agents — not actual executable code. +- `test-lead` cannot recursively spawn sub-agents (Claude Code limitation). Main thread orchestrates. - Pentest workflows require `tagent.yml` with `pentest.authorized: true` — see `tagent.yml.example`. +- MCP server (`python -m runtime.mcp.test_orchestrator.server`) provides catalog/plan/run/status/report tools. diff --git a/install.py b/install.py index d4c6d66..d17d857 100644 --- a/install.py +++ b/install.py @@ -70,7 +70,7 @@ def _parse_args(): PRESERVE_FILES = [ ".env", os.path.join("workspace", "测试数据", "test_data.json"), - os.path.join("workspace", "执行日志", "baselines", "perf_baseline.json"), + os.path.join("workspace", "测试报告", "baselines", "perf_baseline.json"), "workspace/regression_modules.yaml", ] @@ -286,19 +286,18 @@ def create_dirs(project_root): os.path.join("workspace", "测试用例"), os.path.join("workspace", "测试数据"), os.path.join("workspace", "测试报告"), - os.path.join("workspace", "测试用例", "charters"), + os.path.join("workspace", "测试报告", "allure-results"), + os.path.join("workspace", "测试报告", "jmeter-results"), + os.path.join("workspace", "测试报告", "jmeter-report"), + os.path.join("workspace", "测试报告", "coverage-report"), + os.path.join("workspace", "测试报告", "baselines"), + os.path.join("workspace", "测试报告", "history"), + os.path.join("workspace", "截图"), os.path.join("workspace", "自动化脚本", "python", "pages"), os.path.join("workspace", "自动化脚本", "python", "api"), os.path.join("workspace", "自动化脚本", "python", "tests"), os.path.join("workspace", "自动化脚本", "python", "scripts"), os.path.join("workspace", "自动化脚本", "jmeter"), - os.path.join("workspace", "执行日志", "allure-results"), - os.path.join("workspace", "执行日志", "jmeter-results"), - os.path.join("workspace", "执行日志", "jmeter-report"), - os.path.join("workspace", "执行日志", "coverage-report"), - os.path.join("workspace", "执行日志", "baselines"), - os.path.join("workspace", "执行日志", "history"), - os.path.join("workspace", "执行日志", "截图"), "memory", ] for d in dirs: @@ -390,6 +389,26 @@ def copy_utils(template_dir, project_root): print(f" ✓ {count} 个 .py 文件已拷贝") +def copy_runtime(template_dir, project_root): + """拷贝 runtime 目录下所有 .py 文件(MCP servers / orchestrator / router 等)。""" + print("→ 拷贝 runtime...") + runtime_src = os.path.join(template_dir, "runtime") + runtime_dst = os.path.join(project_root, "runtime") + count = 0 + skip = {".pyc", "__pycache__", ".ruff_cache", ".pytest_cache", ".egg-info"} + for root, dirs, files in os.walk(runtime_src): + dirs[:] = [d for d in dirs if d not in skip] + for f in files: + if f.endswith(".py") or f.endswith(".md"): + src = os.path.join(root, f) + rel = os.path.relpath(src, runtime_src) + dst = os.path.join(runtime_dst, rel) + os.makedirs(os.path.dirname(dst), exist_ok=True) + shutil.copy2(src, dst) + count += 1 + print(f" ✓ {count} 个文件已拷贝") + + def copy_ci(template_dir, project_root): """拷贝 CI/CD 文件。""" print("→ 拷贝 CI/CD...") @@ -499,13 +518,17 @@ def finish(project_root): 项目目录: {project_root} - 下一步: - 1. 编辑 {project_root}/.env(最少 8 必填字段,详见 配置清单.md) - 2. 安装 Java JRE 17 + JMeter 5.6.3 + Allure CLI(详见 部署说明.md) - 3. claude /login # 首次登录 Claude Code - 4. cd {project_root} && claude # 启动 - 5. cd {project_root} && claude # 进入项目 - 6. 阅读 skills/smoke-test.md 工作流 # 第一次冒烟验证 + === 独立使用(不需 AI)=== + pip install -e {project_root}/runtime/ + tagent run "path/to/prd.md" # 一键执行 + tagent doctor # 健康检查 + tagent catalog # 查看所有专家和技能 + + === AI 协作模式 === + 1. 编辑 {project_root}/.env + 2. claude /login + 3. cd {project_root} && claude + 4. AI 会自动读取 CLAUDE.md,请确保它遵循 skills/ 流程文档 {'=' * 50} """ @@ -625,6 +648,7 @@ def do_update(): copy_skills(template_dir, PROJECT_ROOT) copy_config(template_dir, PROJECT_ROOT) copy_utils(template_dir, PROJECT_ROOT) + copy_runtime(template_dir, PROJECT_ROOT) copy_ci(template_dir, PROJECT_ROOT) copy_top_level_docs(template_dir, PROJECT_ROOT) @@ -692,6 +716,7 @@ def main(): copy_skills(template_dir, PROJECT_ROOT) copy_config(template_dir, PROJECT_ROOT) copy_utils(template_dir, PROJECT_ROOT) + copy_runtime(template_dir, PROJECT_ROOT) copy_ci(template_dir, PROJECT_ROOT) copy_top_level_docs(template_dir, PROJECT_ROOT)