From 9c26285424411fecbce88b41457bf9cb2391c22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=A9=98?= Date: Mon, 25 May 2026 09:07:28 +0000 Subject: [PATCH] chore: make solve-issue.yaml portable and add developer failed exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove hardcoded ~/repos/workflow paths from procedure text - Use .worktrees/ relative to repo root instead of global path - Add developer failed → $END exit for unrecoverable situations - Add worktree field to reviewer rejected variant - Fix test workflowPath to use import.meta.dirname Refs #506 --- .workflows/solve-issue.yaml | 95 ++++++++++--------- .../solve-issue-tea-worktree.test.ts | 12 ++- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/.workflows/solve-issue.yaml b/.workflows/solve-issue.yaml index 548eeca..617c951 100644 --- a/.workflows/solve-issue.yaml +++ b/.workflows/solve-issue.yaml @@ -10,9 +10,9 @@ roles: procedure: | On first run (no previous steps): 1. Read the issue and all comments from Gitea using `tea issues -r ` - 2. Read CLAUDE.md (or equivalent project conventions file) to understand coding standards + 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 and terminate + 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 On subsequent runs (bounced back by tester with fix_spec): @@ -21,7 +21,8 @@ roles: 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) + 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." frontmatter: oneOf: @@ -40,32 +41,41 @@ roles: - coding procedure: | IMPORTANT: Always work in a git worktree, NEVER modify the main working directory directly. + The repo path and other details are provided in your task prompt. Before starting any work, set up an isolated worktree: - 1. `cd ~/repos/workflow && git fetch origin` to get latest refs - 2. First time (no existing branch): - - `git worktree add ~/repos/workflow-worktrees/fix/- -b fix/- origin/main` - - `cd ~/repos/workflow-worktrees/fix/- && bun install` - 3. If bounced back from reviewer or tester (branch already exists): - - The worktree should already exist at `~/repos/workflow-worktrees/fix/-` - - `cd ~/repos/workflow-worktrees/fix/-` + 1. cd into the repo path provided in your task prompt + 2. `git fetch origin` to get latest refs + 3. First time (no existing branch): + - `git worktree add .worktrees/fix/- -b fix/- origin/main` + - `cd .worktrees/fix/- && bun install` + 4. If bounced back from reviewer or tester (branch already exists): + - cd into the existing worktree under `.worktrees/fix/-` - `git fetch origin && git rebase origin/main` - 4. ALL subsequent work must happen inside the worktree directory. + 5. ALL subsequent work must happen inside the worktree directory. Then implement TDD: - 5. Read the test spec from CAS: `uwf cas get ` (find the hash from the latest planner step's frontmatter.plan) - 6. If bounced back from reviewer or tester: read the previous role's output to understand what needs fixing - 7. Write tests first based on the spec - 8. Implement the code to make tests pass - 9. Ensure `bun run build` passes with no errors - 10. Run `bun test` to verify all tests pass - output: "List all files changed and provide a summary. Include branch name and worktree path in frontmatter." + 6. Read the test spec from CAS: `uwf cas 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 `bun run build` passes with no errors + 11. Run `bun test` to verify all tests pass + + 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: - type: object - properties: - branch: { type: string } - worktree: { type: string } - required: [branch, worktree] + oneOf: + - properties: + $status: { const: "done" } + branch: { type: string } + worktree: { type: string } + required: [$status, branch, worktree] + - properties: + $status: { const: "failed" } + reason: { type: string } + required: [$status, reason] reviewer: description: "Code standards compliance check" goal: "You are a code reviewer. You verify code standards compliance — NOT functionality (that's the tester's job)." @@ -73,7 +83,7 @@ roles: - code-review - static-analysis procedure: | - First, cd into the worktree: `cd ~/repos/workflow-worktrees/fix/-*` (find the exact directory) + The worktree path is provided in your task prompt. cd into it first. Before reviewing, verify the git branch: 1. Run `git branch --show-current` — confirm the branch name references the issue number being worked on @@ -85,12 +95,9 @@ roles: 4. `bunx biome check` — no lint violations 5. TypeScript strict mode — no type errors - Soft checks (review against CLAUDE.md conventions): - - Functional-first: `function` + `type`, not `class` + `interface` - - No optional properties (`?:`) — use `T | null` - - Naming conventions (kebab-case files, PascalCase types, camelCase functions) - - Module boundary discipline (folder exports via index.ts) - - No `console.log` (use structured logger) + Soft checks (review against project conventions if CLAUDE.md / .cursor/rules exist): + - Naming conventions, module boundaries, code style + - No `console.log` in production code - No dynamic imports in production code Only review standards compliance. Do NOT test functionality. @@ -106,17 +113,18 @@ roles: - properties: $status: { const: "rejected" } comments: { type: string } - required: [$status, comments] + worktree: { type: string } + required: [$status, comments, worktree] tester: description: "Functional correctness verification" goal: "You are a tester agent. You verify that the implementation correctly satisfies every scenario in the test spec." capabilities: - testing procedure: | - First, cd into the worktree: `cd ~/repos/workflow-worktrees/fix/-*` (find the exact directory) + The worktree path is provided in your task prompt. cd into it first. 1. Run `bun test` for automated test verification - 2. Read the test spec from CAS: `uwf cas get ` (find the hash from the latest planner step's frontmatter.plan) + 2. Read the test spec from CAS: `uwf cas 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 @@ -143,21 +151,21 @@ roles: goal: "You are a committer agent. You create a clean commit and push a PR linking the original issue." capabilities: [] procedure: | - First, cd into the worktree: `cd ~/repos/workflow-worktrees/fix/-*` (find the exact directory) + The worktree path, branch name, and repo info are provided in your task prompt. + cd into the worktree first. Note: You inherit the developer's worktree and branch. Do NOT create a new branch. 1. Stage all changes: `git add -A` 2. Commit with a descriptive message referencing the issue: `git commit -m "type: description\n\nFixes #N"` 3. Push the branch: `git push -u origin ` - If push hook fails: capture the error log in your output, mark hook_failed - 4. On push success: create a PR via `tea pr create --repo uncaged/workflow --title "..." --description "..."` - - The `--repo` flag is required to work in worktree directories (fixes #474 "path segment [0] is empty" error) - - If working on a different repo, extract owner/repo from: `git remote get-url origin | sed 's/.*[:/]\([^/]*\/[^.]*\).*/\1/'` - - PR description must follow the project template: What / Why / Changes / Ref sections, with `Fixes #N` in Ref - - On tea failure: capture stderr/stdout, log the error clearly, include PR details (title, description, branch) for manual creation, and mark success=false + 4. On push success: create a PR via `tea pr create --repo --title "..." --description "..."` + - Extract owner/repo from: `git remote get-url origin | sed 's/.*[:/]\([^/]*\/[^.]*\).*/\1/'` + - PR description must include: What / Why / Changes / Ref sections, with `Fixes #N` in Ref + - On tea failure: capture stderr/stdout, include PR details for manual creation, mark hook_failed 5. After PR creation, clean up the worktree: - - `cd ~/repos/workflow` - - `git worktree remove ~/repos/workflow-worktrees/fix/-` + - cd to the repo root (parent of .worktrees) + - `git worktree remove ` output: "Include PR URL on success or error log on failure. Set $status to committed (with prUrl) or hook_failed (with error)." frontmatter: oneOf: @@ -176,9 +184,10 @@ graph: insufficient_info: { role: "$END", prompt: "Insufficient information to proceed; end the workflow." } ready: { role: "developer", prompt: "Implement the TDD test spec (CAS hash: {{{plan}}}) in repo {{{repoPath}}}." } developer: - _: { role: "reviewer", prompt: "Review branch {{{branch}}} at {{{worktree}}} for code standards compliance." } + done: { role: "reviewer", prompt: "Review branch {{{branch}}} at {{{worktree}}} for code standards compliance." } + failed: { role: "$END", prompt: "Developer failed: {{{reason}}}. Ending workflow." } reviewer: - rejected: { role: "developer", prompt: "Reviewer rejected: {{{comments}}}. Fix the issues." } + rejected: { role: "developer", prompt: "Reviewer rejected: {{{comments}}}. Fix the issues in repo {{{worktree}}}." } approved: { role: "tester", prompt: "Review passed. Run tests on branch {{{branch}}} at {{{worktree}}}." } tester: fix_code: { role: "developer", prompt: "Tests found code issues: {{{report}}}. Fix and re-submit." } diff --git a/packages/cli-workflow/src/__tests__/solve-issue-tea-worktree.test.ts b/packages/cli-workflow/src/__tests__/solve-issue-tea-worktree.test.ts index ec7fa70..5683213 100644 --- a/packages/cli-workflow/src/__tests__/solve-issue-tea-worktree.test.ts +++ b/packages/cli-workflow/src/__tests__/solve-issue-tea-worktree.test.ts @@ -13,8 +13,16 @@ import { parse } from "yaml"; */ describe("solve-issue workflow: tea pr create worktree fix", () => { - // Navigate up from packages/cli-workflow to repo root - const workflowPath = join(process.cwd(), "..", "..", ".workflows", "solve-issue.yaml"); + // Navigate up from packages/cli-workflow/src/__tests__ to repo root + const workflowPath = join( + import.meta.dirname, + "..", + "..", + "..", + "..", + ".workflows", + "solve-issue.yaml", + ); test("committer procedure should include --repo flag in tea pr create command", async () => { const yamlContent = await readFile(workflowPath, "utf-8");