From c90fb05333e9063469690870f585c74e5596a49e Mon Sep 17 00:00:00 2001 From: xiaoxing0135 <706015750@qq.com> Date: Tue, 2 Jun 2026 23:37:01 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20address=20code=20review=20findings?= =?UTF-8?q?=20=E2=80=94=20version=20sync,=20CLAUDE.md,=20install.py=20gaps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ROADMAP: V1.42.0 → V1.43.0 to match VERSION - CLAUDE.md: new entry-point doc with directory map, design limitations - README: replace /smoke-test pseudo-command with correct workflow reference - install.py: add FULL_GUIDE.md + tagent.yml.example to copy_top_level_docs - install.py: fix finish() to remove /smoke-test, reference skill doc instead - install.py: add memory/ to create_dirs - memory/.gitkeep: initialize required directory Closes code review issues #1 #2 #3 #5 #7 #9 #11 --- CLAUDE.md | 43 +++++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- ROADMAP.md | 2 +- install.py | 6 ++++-- memory/.gitkeep | 0 5 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 CLAUDE.md create mode 100644 memory/.gitkeep diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..e524e1a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,43 @@ +# CLAUDE.md + +## Entry Point + +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. + +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. + +## Directory Map + +| What | Where | +|------|-------| +| Agent definitions | `agents/` (16 agents) | +| Skill workflow docs | `skills/` (35 skills) | +| Python utils | `utils/` (78 modules) | +| 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 + +- `/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). +- Pentest workflows require `tagent.yml` with `pentest.authorized: true` — see `tagent.yml.example`. diff --git a/README.md b/README.md index 400b9ac..c026b32 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ python install.py ~/test-agent-project # macOS / Linux example, any folder After deployment, outputs under `workspace/`: test cases (Excel + xmind + markmap + opml) + Word report + decision logs. -**Next**: edit `.env` → `claude /login` → `cd project-dir && claude` → `/smoke-test` +**Next**: `cp config/.env.example .env` → edit `.env` → `cd project-dir && claude` → read `skills/smoke-test.md` workflow, run agents per the flow ## 🖥 Desktop App diff --git a/ROADMAP.md b/ROADMAP.md index 57f5ce4..e495698 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,7 +1,7 @@ # Test-Agent V1.x ROADMAP > 项目终态目标:每个 expert / skill 真 LLM-driven / script-backed 实装,**绝不输出 mock 数据**。 -> 当前状态:V1.42.0 (**expert rollout 收尾 + skill rollout 完成(16/16)+ Phase 3 完成 + Phase 4 完成 + Phase 5 完成**) +> 当前状态:V1.43.0 (**expert rollout 收尾 + skill rollout 完成(16/16)+ Phase 3 完成 + Phase 4 完成 + Phase 5 完成**) > - **expert 16/16 active**(11 production + 5 script);0 rollout。 > - **skill 30/32 active**(23 production + 7 script);0 rollout;2 暂为 V2 vision 方法论参考。 > - 3 meta-skill(nuwa-skill / darwin-skill / karpathy-guidelines)独立,工具属性,不在 32 业务 skill 数内。 diff --git a/install.py b/install.py index 5c4e442..d4c6d66 100644 --- a/install.py +++ b/install.py @@ -299,6 +299,7 @@ def create_dirs(project_root): os.path.join("workspace", "执行日志", "baselines"), os.path.join("workspace", "执行日志", "history"), os.path.join("workspace", "执行日志", "截图"), + "memory", ] for d in dirs: os.makedirs(os.path.join(project_root, d), exist_ok=True) @@ -409,7 +410,7 @@ def copy_top_level_docs(template_dir, project_root): docs = [ "LICENSE", "NOTICE.md", "SECURITY.md", "CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "ROADMAP.md", "README.md", "README.zh-CN.md", - "CHANGELOG.md", "VERSION", + "CHANGELOG.md", "VERSION", "FULL_GUIDE.md", "tagent.yml.example", ] for f in docs: src = os.path.join(template_dir, f) @@ -503,7 +504,8 @@ def finish(project_root): 2. 安装 Java JRE 17 + JMeter 5.6.3 + Allure CLI(详见 部署说明.md) 3. claude /login # 首次登录 Claude Code 4. cd {project_root} && claude # 启动 - 5. 在 Claude 提示符内: > /smoke-test # 第一次冒烟验证 + 5. cd {project_root} && claude # 进入项目 + 6. 阅读 skills/smoke-test.md 工作流 # 第一次冒烟验证 {'=' * 50} """ diff --git a/memory/.gitkeep b/memory/.gitkeep new file mode 100644 index 0000000..e69de29 From 85d2cc3b0467f125e508400698ce36a702c37a24 Mon Sep 17 00:00:00 2001 From: xiaoxing0135 <706015750@qq.com> Date: Tue, 2 Jun 2026 23:55:07 +0800 Subject: [PATCH 2/2] fix: enforce AI framework gate + standalone CLI path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CLAUDE.md: add hard AI agent STOP gate with 3 Do-NOT rules - CLAUDE.md: document standalone CLI (tagent) as first-class path - install.py: add copy_runtime to deploy MCP/CLI modules - install.py: restructure workspace dirs — remove 执行日志/charters, flatten into 测试报告/ + 截图/ - install.py: finish() shows both CLI and AI collaboration paths --- CLAUDE.md | 90 ++++++++++++++++++++++++++++++++++++++++-------------- install.py | 57 ++++++++++++++++++++++++---------- 2 files changed, 108 insertions(+), 39 deletions(-) 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)