Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 67 additions & 23 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -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/<task>.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 <run_id> # check run status
tagent report <run_id> # 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

Expand All @@ -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.
57 changes: 41 additions & 16 deletions install.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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...")
Expand Down Expand Up @@ -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}
"""
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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)

Expand Down
Loading