diff --git a/.workflows/solve-issue.yaml b/.workflows/solve-issue.yaml index 62692f3..ba8be3b 100644 --- a/.workflows/solve-issue.yaml +++ b/.workflows/solve-issue.yaml @@ -1,5 +1,5 @@ name: "solve-issue" -description: "TDD-driven issue resolution for small, focused changes. Loop protection relies on engine maxRounds." +description: "TDD-driven issue resolution for small, focused changes. Loop protection relies on engine maxRounds. Uses pnpm." roles: planner: description: "Analyzes issue and outputs a TDD test spec" @@ -8,34 +8,64 @@ roles: - issue-analysis - planning procedure: | - On first run (no previous steps): + CRITICAL: First, determine which mode you are in by scanning the task prompt. + Choose EXACTLY ONE mode — do NOT default to Mode A if Mode B applies. + + **How to choose:** + - If the prompt contains ANY of these keywords: "PR #", "PR#", "pulls/", "继续修复", "continue", "review feedback", "existing branch", "fix/", or mentions a branch name → **Mode B** + - If the prompt was forwarded from tester with fix_spec → **Mode C** + - Otherwise → **Mode A** + + **Mode A — Fresh issue (first time, no existing PR):** 1. Read the issue and all comments from Gitea using `tea issues -r ` 2. Look for project conventions files (CLAUDE.md, CONTRIBUTING.md, .cursor/rules/) in the repo 3. Assess whether the issue has enough information to produce a test spec 4. If insufficient info: comment on the issue via `echo "..." | tea comment -r ` (skip if you already commented), then output $status=insufficient_info 5. If sufficient: produce a detailed TDD test spec in markdown covering all scenarios + 6. The test spec is stored in CAS automatically by the uwf pipeline (agents do not need to call `ocas put` directly) + 7. Output **$status=ready** with plan hash and repoPath - On subsequent runs (bounced back by tester with fix_spec): + **Mode B — Continue on existing PR (prompt mentions PR, branch, or review feedback):** + YOU MUST output $status=continue (NOT ready) when in this mode. + 1. Extract the PR number and branch name from the prompt + 2. Read the PR and its review comments from Gitea: `tea pr --comments -r ` + 3. Read the existing issue for full context: `tea issues -r ` + 4. Look for project conventions files (CLAUDE.md, CONTRIBUTING.md, .cursor/rules/) in the repo + 5. Produce a TDD test spec that ONLY covers the changes requested in the review — do NOT re-spec already-implemented features + 6. The test spec is stored in CAS automatically by the uwf pipeline (agents do not need to call `ocas put` directly) + 7. Find the existing worktree: `git worktree list` and locate the branch + 8. Output **$status=continue** with plan hash, repoPath, branch name, and worktree path + + **Mode C — Bounced back by tester (fix_spec):** 1. Read the tester's output from the previous step to understand what's wrong with the spec 2. Revise the test spec accordingly + 3. The test spec is stored in CAS automatically by the uwf pipeline (agents do not need to call `ocas put` directly) + 4. Output **$status=ready** with plan hash and repoPath - After producing the test spec: - 1. Store it via `uwf cas put-text ""` and capture the returned hash - 2. Put the hash in frontmatter.plan (required when $status=ready) - 3. Set repoPath to the absolute path of the repository root - output: "Output a brief summary of the test spec. Set $status to ready (with plan hash and repoPath) or insufficient_info." + IMPORTANT: Extract the repo remote (owner/repo) from git: + ```bash + git remote get-url origin | sed 's|.*[:/]\([^/]*/[^.]*\).*|\1|' + ``` + Store the result as repoRemote in your frontmatter output so downstream roles can use it. + output: "Output a brief summary of the test spec. Set $status to ready (fresh), continue (existing PR), or insufficient_info." frontmatter: oneOf: - - type: object - properties: + - properties: $status: { const: "ready" } plan: { type: string } repoPath: { type: string } required: [$status, plan, repoPath] - - type: object - properties: + - properties: + $status: { const: "continue" } + plan: { type: string } + repoPath: { type: string } + branch: { type: string } + worktree: { type: string } + required: [$status, plan, repoPath, branch, worktree] + - properties: $status: { const: "insufficient_info" } - required: [$status] + reason: { type: string } + required: [$status, reason] developer: description: "TDD implementation per test spec" goal: "You are a developer agent. You implement code changes following TDD — write tests first, then implementation." @@ -51,32 +81,46 @@ roles: 3. First time (no existing branch): - `git worktree add .worktrees/fix/- -b fix/- origin/main` - `cd .worktrees/fix/- && pnpm install` - 4. If bounced back from reviewer or tester (branch already exists): + 4. If continuing on existing branch (prompt says "Continue work on existing branch" or provides a worktree path): + - cd directly into the worktree path provided in the prompt + - `git fetch origin && git rebase origin/main` + - Do NOT create a new branch or worktree + 5. If bounced back from reviewer or tester (branch already exists but no explicit worktree path): - cd into the existing worktree under `.worktrees/fix/-` - `git fetch origin && git rebase origin/main` - 5. ALL subsequent work must happen inside the worktree directory. + 6. ALL subsequent work must happen inside the worktree directory. Then implement TDD: - 6. Read the test spec from CAS: `uwf cas get ` (find the hash from the planner's output in your task prompt) + 6. Read the test spec from CAS: `ocas get ` (find the hash from the planner's output in your task prompt) 7. If bounced back from reviewer or tester: read the previous role's feedback in your task prompt 8. Write tests first based on the spec 9. Implement the code to make tests pass 10. Ensure `pnpm run build` passes with no errors 11. Run `pnpm test` to verify all tests pass + After implementation, before reporting done: + 12. Add a changeset file (`.changeset/.md`) with correct bump type: + - `patch` for bug fixes, internal refactors, test-only changes + - `minor` for new features, new CLI commands, new API surfaces + - `major` for breaking changes + List every affected package in the changeset frontmatter. + 13. Update documentation if the change affects user-facing behavior: + - `README.md` — usage examples, feature descriptions + - `.cards/` — architecture decision records (if applicable) + - CLI prompt subcommand output (if CLI help text changes) + - CLI `--help` text (if flags/commands are added or changed) + If you cannot complete the implementation (e.g. the issue is too complex, blocked by external factors, or repeated attempts fail), set $status=failed with a reason. output: "List all files changed and provide a summary. Set $status to done (with branch/worktree), or failed (with reason)." frontmatter: oneOf: - - type: object - properties: + - properties: $status: { const: "done" } branch: { type: string } worktree: { type: string } required: [$status, branch, worktree] - - type: object - properties: + - properties: $status: { const: "failed" } reason: { type: string } required: [$status, reason] @@ -104,19 +148,25 @@ roles: - No `console.log` in production code - No dynamic imports in production code + Documentation & changeset checks: + 6. Changeset exists in `.changeset/` with correct bump type (`patch`/`minor`/`major`) and lists all affected packages + 7. If the change is user-facing, documentation is updated: + - `README.md` reflects new/changed behavior + - `.cards/` architecture cards updated if design decisions changed + - CLI prompt subcommand output updated (if it generates skill/reference content) + - CLI `--help` text matches new flags/commands + Only review standards compliance. Do NOT test functionality. If rejecting, you MUST explain the specific reason in your output. output: "Explain your decision with specific file/line references. Set $status to approved (with branch/worktree) or rejected (with comments)." frontmatter: oneOf: - - type: object - properties: + - properties: $status: { const: "approved" } branch: { type: string } worktree: { type: string } required: [$status, branch, worktree] - - type: object - properties: + - properties: $status: { const: "rejected" } comments: { type: string } worktree: { type: string } @@ -130,7 +180,7 @@ roles: The worktree path is provided in your task prompt. cd into it first. 1. Run `pnpm test` for automated test verification - 2. Read the test spec from CAS: `uwf cas get ` (find the hash from the planner step in the thread history) + 2. Read the test spec from CAS: `ocas get ` (find the hash from the planner step in the thread history) 3. Verify each scenario in the spec is covered and passing 4. Determine outcome: - passed: all scenarios verified, tests pass @@ -139,19 +189,16 @@ roles: output: "Report test results per scenario. Set $status to passed (with branch/worktree), fix_code (with report), or fix_spec (with report)." frontmatter: oneOf: - - type: object - properties: + - properties: $status: { const: "passed" } branch: { type: string } worktree: { type: string } required: [$status, branch, worktree] - - type: object - properties: + - properties: $status: { const: "fix_code" } report: { type: string } required: [$status, report] - - type: object - properties: + - properties: $status: { const: "fix_spec" } report: { type: string } required: [$status, report] @@ -178,13 +225,11 @@ roles: output: "Include PR URL on success or error log on failure. Set $status to committed (with prUrl) or hook_failed (with error)." frontmatter: oneOf: - - type: object - properties: + - properties: $status: { const: "committed" } prUrl: { type: string } required: [$status, prUrl] - - type: object - properties: + - properties: $status: { const: "hook_failed" } error: { type: string } required: [$status, error] @@ -193,8 +238,9 @@ graph: new: { role: "planner", prompt: "Analyze the issue and produce an implementation plan." } resume: { role: "planner", prompt: "Review the previous run output and continue the work." } planner: - insufficient_info: { role: "$END", prompt: "Insufficient information to proceed; end the workflow." } + insufficient_info: { role: "$SUSPEND", prompt: "信息不足,需要补充:{{{reason}}}" } ready: { role: "developer", prompt: "Implement the TDD test spec (CAS hash: {{{plan}}}) in repo {{{repoPath}}}." } + continue: { role: "developer", prompt: "Continue work on existing branch {{{branch}}} at worktree {{{worktree}}}. Implement the revised TDD test spec (CAS hash: {{{plan}}}) in repo {{{repoPath}}}. Do NOT create a new branch or worktree — cd into the existing worktree and work there." } developer: done: { role: "reviewer", prompt: "Review branch {{{branch}}} at {{{worktree}}} for code standards compliance." } failed: { role: "$END", prompt: "Developer failed: {{{reason}}}. Ending workflow." }