Compare commits

..

5 Commits

Author SHA1 Message Date
pzhang_zywl 5175fbaf14 feat: worktree 隔离方案 - 多 agent 独立工作目录 - Closes #102
CI / test (pull_request) Successful in 19s
启动 agent 后自动创建 ~/.gitea/worktrees/<user>/ 隔离目录,
多个 agent 可同时修改不同文件、不同分支互不干扰。

- _common.sh: 新增 setup_worktree/cleanup_worktree 函数
- start_dev_agent.sh: 启动时自动切 worktree
- start_qe_agent.sh: 同上
- DEV_AGENT.md/QE_AGENT.md: 启动行为增加 worktree 检查步骤

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 17:33:15 +08:00
pzhang_dev_agent_01 9dff1617ea Merge pull request 'fix: migrate Gitea config to multi-profile system' (#100) from test/issue-90 into main
CI / test (push) Successful in 18s
2026-06-05 17:17:59 +08:00
pzhang_zywl a8964db151 fix: 将 Gitea 配置迁移到 ~/.gitea/config.yaml 多账号配置体系
CI / test (pull_request) Successful in 18s
- 新增 _get_gitea_config.py 从 YAML 读取 URL/repo/token
- _common.sh 改为通过 eval python 脚本加载配置
- GITEA_CICD_SETUP.md / DEV_AGENT.md / QE_AGENT.md 更新文档
- CI 工作流改用 ${{ gitea.server_url }} / ${{ gitea.repository }}

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 17:17:48 +08:00
pzhang_zywl 2b5d901cfe fix: 更新 repo 路径 pzhang_zywl → zeekrAI 组织
CI / test (push) Successful in 18s
创建 zeekrAI 组织并将 document_analyzer 转移至其下。
更新所有文件中的 repo 路径和 git remote。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 15:50:45 +08:00
pzhang_zywl a60990b652 fix: 迁移 Gitea URL localhost:3000 → git.zywl.me - Closes #90
CI / test (push) Successful in 18s
2026-06-05 14:49:08 +08:00
6 changed files with 53 additions and 10 deletions
+2 -1
View File
@@ -63,7 +63,8 @@ export GITEA_USER=pzhang_dev_agent_01 # Dev-Agent 账号
1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md` 1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md`
2. 确认环境变量已设置(GITEA_USER + ~/.gitea/config.yaml 2. 确认环境变量已设置(GITEA_USER + ~/.gitea/config.yaml
3. `/loop 10m` 开启 10 分钟间隔的自动轮询 3. 确认当前在独立的 git worktree 中(启动脚本已自动切到 `~/.gitea/worktrees/`),不与其他 agent 共享工作目录
4.`/loop 10m` 开启 10 分钟间隔的自动轮询
4. 轮询内容(多轮递进): 4. 轮询内容(多轮递进):
a. `--action list --labels product-code` — 先捡带 `product-code` 标签的 Issue a. `--action list --labels product-code` — 先捡带 `product-code` 标签的 Issue
b. `--action list` 无过滤,筛选 title 带 `[product]` 前缀的无标签 Issue b. `--action list` 无过滤,筛选 title 带 `[product]` 前缀的无标签 Issue
+2 -1
View File
@@ -15,7 +15,8 @@ description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gi
1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md` 1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md`
2. 设好环境变量(见下方"环境要求") 2. 设好环境变量(见下方"环境要求")
3. `/loop 10m` 开启 10 分钟间隔的自动轮询 3. 确认当前在独立的 git worktree 中(启动脚本已自动切到 `~/.gitea/worktrees/`),不与其他 agent 共享工作目录
4.`/loop 10m` 开启 10 分钟间隔的自动轮询
4. 轮询内容(多轮递进): 4. 轮询内容(多轮递进):
a. `--action list --labels test-code` — 先捡带 `test-code` 标签的 Issue a. `--action list --labels test-code` — 先捡带 `test-code` 标签的 Issue
b. `--action list` 无过滤,筛选 title 带 `[test]` 前缀的无标签 Issue b. `--action list` 无过滤,筛选 title 带 `[test]` 前缀的无标签 Issue
+37 -1
View File
@@ -6,7 +6,8 @@ set -eu
# ── Resolve paths ────────────────────────────────────────────────────────────── # ── Resolve paths ──────────────────────────────────────────────────────────────
_COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" _COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="${PROJECT_DIR:-$(cd "$_COMMON_DIR/.." && pwd)}" _MAIN_REPO_DIR="$(cd "$_COMMON_DIR/.." && pwd)"
PROJECT_DIR="${PROJECT_DIR:-$_MAIN_REPO_DIR}"
# ── Load Gitea configuration ──────────────────────────────────────────────────── # ── Load Gitea configuration ────────────────────────────────────────────────────
# Primary: ~/.gitea/config.yaml (requires GITEA_USER) # Primary: ~/.gitea/config.yaml (requires GITEA_USER)
@@ -18,6 +19,41 @@ if ! eval "$(python "$_COMMON_DIR/_get_gitea_config.py" 2>/dev/null)"; then
fi fi
fi fi
# ── Worktree isolation ─────────────────────────────────────────────────────────
GITEA_WORKTREE_DIR="${GITEA_WORKTREE_DIR:-$HOME/.gitea/worktrees}"
setup_worktree() {
local user="$1"
local worktree="$GITEA_WORKTREE_DIR/$user"
# Already inside a worktree we created — reuse it.
if [ -f "$worktree/.gitea-worktree" ]; then
echo "Using existing worktree: $worktree"
PROJECT_DIR="$worktree"
cd "$PROJECT_DIR"
return 0
fi
local branch="agent/${user}/$(date +%Y%m%d-%H%M%S)"
echo "Creating worktree: $worktree (branch: $branch)"
mkdir -p "$GITEA_WORKTREE_DIR"
git -C "$_MAIN_REPO_DIR" worktree add -b "$branch" "$worktree" origin/main
touch "$worktree/.gitea-worktree"
PROJECT_DIR="$worktree"
cd "$PROJECT_DIR"
}
cleanup_worktree() {
local user="$1"
local worktree="$GITEA_WORKTREE_DIR/$user"
if [ -d "$worktree" ]; then
rm -f "$worktree/.gitea-worktree"
echo "Cleaning up worktree: $worktree"
git -C "$_MAIN_REPO_DIR" worktree remove "$worktree" 2>/dev/null || true
rm -rf "$worktree" 2>/dev/null || true
fi
}
# ── Validate required environment ────────────────────────────────────────────── # ── Validate required environment ──────────────────────────────────────────────
require_token() { require_token() {
if [ -z "${GITEA_API_TOKEN:-}" ]; then if [ -z "${GITEA_API_TOKEN:-}" ]; then
+6
View File
@@ -15,6 +15,12 @@ export GITEA_USER="$1"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/_common.sh" source "$SCRIPT_DIR/_common.sh"
# Switch to isolated worktree so multiple agents don't conflict
setup_worktree "$GITEA_USER"
# Cleanup worktree on exit (optional, comment out to keep for debugging)
trap 'cleanup_worktree "$GITEA_USER"' EXIT
banner "Dev" banner "Dev"
require_token require_token
+6
View File
@@ -15,6 +15,12 @@ export GITEA_USER="$1"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/_common.sh" source "$SCRIPT_DIR/_common.sh"
# Switch to isolated worktree so multiple agents don't conflict
setup_worktree "$GITEA_USER"
# Cleanup worktree on exit (optional, comment out to keep for debugging)
trap 'cleanup_worktree "$GITEA_USER"' EXIT
banner "QE" banner "QE"
require_token require_token
-7
View File
@@ -92,10 +92,3 @@ def test_sample_ir_json_is_valid():
assert isinstance(data, (dict, list)) assert isinstance(data, (dict, list))
else: else:
pytest.skip("Sample IR JSON not found") pytest.skip("Sample IR JSON not found")
# -- QE-Agent workflow test --------------------------------------------------
def test_qe_agent_workflow():
"""QE-Agent workflow smoke test: basic test discovery works."""
assert True