Metadata-Version: 2.4
Name: promotion-harness-agent
Version: 0.1.4
Summary: Add your description here
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: agent-client-protocol>=0.9.0
Requires-Dist: mcp<2,>=1
Requires-Dist: pydantic>=2.12.5
Requires-Dist: fastapi>=0.115.0
Requires-Dist: uvicorn>=0.30.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pytest>=9.0.2
Requires-Dist: pytest-asyncio>=1.3.0

# Promotion Harness Agent

Promotion Harness Agent 是财经营销部门的本地 Harness Agent MVP。它通过状态机、ACP Agent、阶段上下文、工具门禁、StageOutput、Acceptance Gate 和本地 UI，把一句需求推进为 PRD、技术方案、编码、质量闭环、部署和回归验证，并把运行证据落到目标仓库的 `.harness/` 目录中。

当前主链路：

```text
PLANNING
  -> PRD_DRAFTING
  -> TECH_SPEC_DRAFTING
  -> CODING
  -> QUALITY_LOOP
  -> DEPLOYING
  -> REGRESSION_TESTING
  -> FINISHED
```

---

## 用户指南

### 1. 安装

如果已经有发布包，直接安装：

```bash
pip install promotion-harness-agent
```

升级到最新版本：

```bash
pip install -U promotion-harness-agent
```

确认 CLI 可用：

```bash
promotion-harness --help
```

### 2. 初始化目标仓库

进入你希望由 Promotion Harness Agent 管理的业务仓库：

```bash
cd /path/to/your-repo
promotion-harness init
```

初始化会创建或补齐：

```text
.harness/
  config.json
  current_run.json
  stage_context_policy.json
  stage_acceptance_policy.json
  runs/
  knowledge/
```

其中 `.harness/knowledge/` 是给 Oncall 帮手 Agent 和后续策略编写 Agent 使用的知识底座。它包含运行诊断、策略编写、工具配置、StageOutput、Acceptance 等说明。

如果想刷新知识底座：

```bash
promotion-harness init --knowledge-refresh safe
```

刷新模式：

- `safe`：默认模式。补齐缺失文件，只刷新未被用户改过的托管知识文件。
- `missing`：只补齐缺失文件，不改已有文件。
- `force`：强制覆盖托管知识文件。

### 3. 启动本地 UI

安装态使用：

```bash
promotion-harness ui
```

指定地址和端口：

```bash
promotion-harness ui --host 127.0.0.1 --port 8010
```

UI 会启动 FastAPI 后端，并托管打包好的 React 前端静态资源。启动后可以在页面中：

- 输入需求并启动 run。
- 查看当前阶段、trace、产物、准出结果。
- 恢复或重试阶段。
- 配置上下文策略、工具层、Harness 准出策略。
- 使用右下角“帮手”悬浮入口进入 Oncall Agent 页面。

### 4. 使用 Oncall 帮手 Agent

UI 右下角有“帮手”悬浮入口，也可以从左侧导航进入“帮手 / Oncall Agent”。

Oncall Agent 支持：

- 询问当前 run 为什么卡住。
- 分析 `progress.json`、`trace.ndjson`、StageOutput、Acceptance 结果。
- 解释工具为什么被拒、为什么授权阻塞。
- 查询策略、工具层、准出规则应该怎么配置。
- 连续对话：后端会优先复用 ACP 原生 session；如果 ACP runtime 不支持恢复，会用本地历史问答作为 fallback。

Oncall 会话记录保存在目标仓库：

```text
.harness/oncall/sessions/<session_id>/
  session.json
  turns/<turn_id>/
    prompt.md
    answer.md
    events.ndjson
```

系统默认保留最近 5 个 Oncall session，每个 session 保留最近 10 轮 turn，避免 `.harness/oncall/` 无限增长。用户也可以在 Oncall 页面顶栏的“历史保留设置”中调整或重置默认值。

### 5. 命令行运行流水线

如果不使用 UI，也可以直接运行：

```bash
promotion-harness run --requirement "写一个测试的加法函数"
```

恢复当前 active run：

```bash
promotion-harness resume
```

### 6. 运行产物在哪里

每次 run 的状态和证据写入：

```text
.harness/runs/<run_id>/
  progress.json
  trace.ndjson
  docs/
  context/
  stage_outputs/
  acceptance/
  outputs/
  logs/
  auth_block.json
```

关键文件：

- `.harness/current_run.json`：当前 active run 指针。
- `progress.json`：当前状态、metadata、阶段结果、准出结果。
- `trace.ndjson`：状态机、ACP、工具、gate、acceptance 事件流。
- `stage_outputs/<STAGE>.json`：阶段标准输出。
- `acceptance/<STAGE>.json`：准出 verdict 与失败原因。

---

## 开发者指南

### 1. 本地安装态验证（推荐）

如果要验证“用户实际安装后看到什么”，推荐先构建完整 wheel，再在干净虚拟环境中安装这个 wheel。这个流程会验证：

- 前端是否已经打包并同步到 `ui_backend/static/`。
- `.harness/knowledge/` 模板是否进入 Python 包。
- `promotion-harness ui` 是否使用 wheel 内的静态资源，而不是源码开发服务器。

```bash
cd /Users/bytedance/Documents/Project/explore/harness/caijing_harness_agent/my_harness_agent

# 1. 清理旧构建产物和旧安装检查环境
rm -rf dist build promotion_harness_agent.egg-info .venv-install-check

# 2. 构建前端静态资源 + Python wheel/sdist
npm run package:build

# 3. 新建干净虚拟环境并安装刚构建的 wheel
python3 -m venv .venv-install-check
source .venv-install-check/bin/activate
python -m pip install --upgrade pip
python -m pip install --force-reinstall --no-cache-dir dist/*.whl
hash -r

# 4. 确认 CLI 来自当前虚拟环境
which promotion-harness
python -m pip show promotion-harness-agent
promotion-harness --help
```

确认 wheel 内包含最新前端静态资源和知识底座：

```bash
python - <<'PY'
import pathlib
import ui_backend
import core.knowledge_base

static = pathlib.Path(ui_backend.__file__).parent / "static"
print("static:", static)
js_files = list((static / "assets").glob("*.js"))
print("js:", js_files)
for p in js_files:
    text = p.read_text(encoding="utf-8", errors="ignore")
    print(p.name, "oncall=", "oncall" in text.lower(), "帮手=", "帮手" in text)

knowledge_templates = pathlib.Path(core.knowledge_base.__file__).parent / "templates"
print("knowledge_templates:", knowledge_templates)
print("README exists:", (knowledge_templates / "README.md").exists())
PY
```

预期至少看到：

```text
oncall= True
帮手= True
README exists: True
```

最后到目标 git 仓库中验证安装态 UI：

```bash
cd /path/to/your-target-repo
promotion-harness init
find .harness/knowledge -maxdepth 3 -type f | sort | head
promotion-harness ui --port 8011
```

浏览器打开：

```text
http://127.0.0.1:8011
```

如果曾经打开过旧页面，建议使用无痕窗口或强制刷新缓存。

### 2. 开发态调试（可编辑安装）

日常改 Python 代码时，可以使用可编辑安装。建议先创建并激活虚拟环境，避免污染系统 Python 环境。

使用标准 `venv`：

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

如果使用 `uv`：

```bash
uv venv
source .venv/bin/activate
uv pip install -e .
```

确认 CLI：

```bash
promotion-harness --help
```

注意：可编辑安装适合开发 Python 代码，但 `promotion-harness ui` 仍然读取 `ui_backend/static/` 中的打包前端。如果只跑可编辑安装但没有重新 bundle 前端，安装态 UI 可能还是旧页面。

### 3. 开发态运行

直接运行流水线：

```bash
uv run python run.py --requirement "..."
```

开发态 UI：

```bash
npm run ui:dev
```

这个命令会同时启动：

- 后端：`HARNESS_UI_BACKEND_RELOAD=1 uv run python -m ui_backend`
- 前端：`npm --prefix ui_frontend run dev -- --host 127.0.0.1 --port 5173`

如果只想验证前端是否能编译：

```bash
npm --prefix ui_frontend run build
```

### 4. 打包前端静态资源

安装态 `promotion-harness ui` 依赖 `ui_backend/static/` 中的打包前端。如果你修改了前端，并希望安装态 UI 使用最新页面，需要执行：

```bash
npm run ui:bundle
```

完整打包命令：

```bash
npm run package:build
```

它会：

1. 构建 `ui_frontend/dist`。
2. 同步静态资源到 `ui_backend/static/`。
3. 执行 `uv build` 生成 Python wheel 和 sdist。

### 5. 测试策略

日常开发不要默认直接跑全量测试。优先使用分层反馈。

推荐先获取测试建议：

```bash
uv run python -m tools.test_feedback recommend
```

按改动文件获取建议：

```bash
uv run python -m tools.test_feedback recommend --path ui_backend/oncall.py --path ui_frontend/src/pages/OncallAgentPage.tsx
```

快反馈：

```bash
uv run python -m tools.test_feedback run fast
```

阶段级验证：

```bash
uv run python -m tools.test_feedback run stage
```

仓库级回归：

```bash
uv run python -m tools.test_feedback run regression
```

完整验收：

```bash
uv run python -m tools.test_feedback run acceptance
```

或：

```bash
uv run pytest -q
```

### 6. 常用定向测试

Oncall Agent / UI 后端：

```bash
uv run pytest tests/test_ui_oncall.py tests/test_ui_backend_api.py -q
```

知识底座与 init 分发：

```bash
uv run pytest tests/test_harness_cli.py tests/test_knowledge_base_distribution.py tests/test_knowledge_packaging.py -q
```

前端构建：

```bash
npm --prefix ui_frontend run build
```

### 7. 目录约定

```text
core/                     # 状态机、上下文、ACP runtime、gate、policy、tool/capability 层
core/knowledge_base/      # 随包分发的 .harness/knowledge 模板和安装逻辑
agents/                   # 各阶段 Agent handler
ui_backend/               # FastAPI 后端和 process/oncall/control API
ui_frontend/              # Vite + React 前端
ui_backend/static/        # 安装态 UI 静态资源
tools/                    # 测试反馈、runner、linter、ACP wrapper
scripts/                  # 一次性调试/复现脚本
tests/                    # 仓库级 pytest 测试
docs/                     # 架构、调研、调试记录
.harness/                 # 当前仓库作为目标仓库运行时的控制面产物
```

注意：生成的业务代码和业务测试应写入被 Harness 管理的目标仓库真实目录，不要默认写到额外的 `workspace/src` 或 `workspace/tests`。

### 8. 发布流程

#### 8.1 更新版本号

修改 `pyproject.toml`：

```toml
[project]
version = "0.1.x"
```

每次重新发布必须提升版本号，已经发布的版本号不能覆盖上传。

#### 8.2 构建发布产物

```bash
rm -rf dist
npm run package:build
```

产物位置：

```text
dist/*.whl
dist/*.tar.gz
```

#### 8.3 干净环境验证

```bash
python -m venv .venv-publish-check
source .venv-publish-check/bin/activate
pip install dist/*.whl
promotion-harness --help
promotion-harness ui --help
```

建议再找一个临时 git 仓库验证 init：

```bash
mkdir -p /tmp/promotion-harness-smoke
cd /tmp/promotion-harness-smoke
git init
promotion-harness init
find .harness/knowledge -maxdepth 3 -type f | sort
```

#### 8.4 上传

如果发布到 PyPI：

```bash
python -m pip install twine
python -m twine upload dist/*
```

如果发布到内部 Python 包仓库：

```bash
python -m twine upload --repository-url https://<your-internal-pypi>/ dist/*
```

如果内部使用 `uv publish`：

```bash
uv publish
```

或：

```bash
uv publish --publish-url https://<your-internal-pypi>/legacy/
```

---

## 当前说明

- 主链路通过 ACP 驱动 `coco acp serve`。
- Oncall Agent 也通过 ACP 调用模型，并使用 `.harness/knowledge/` 作为本地知识索引。
- `tools/legacy/coco_runner.py` 仅用于兼容/历史参考，不是主运行路径。
