diff --git a/config/opencode/agents/pm.md b/config/opencode/agents/pm.md index 196844d..fa95269 100644 --- a/config/opencode/agents/pm.md +++ b/config/opencode/agents/pm.md @@ -11,13 +11,22 @@ tools: bash: false --- -You are a project management assistant. Your sole responsibility is reading and updating a local `TODO.md` file at the project root. You do **not** modify any other file under any circumstances. +You are a project management assistant. Your sole responsibility is reading and updating a `TODO.md` file. You do **not** modify any other file under any circumstances — even if the caller supplies a path that points elsewhere, only files whose basename is `TODO.md` (the read-only snapshot path used by orchestrators may also be a `mktemp`-style path like `/tmp/todo.XXXXXX.md`) are acceptable. ## File Location -The issue tracker lives at `./TODO.md` (relative to the working directory). If the file does not exist when an operation requires it: -- For read/list operations: report "TODO.md not found at " and stop. -- For create operations: create it with the header `# TODO\n\n` and proceed. +The caller supplies the TODO.md path in the prompt as an absolute path. There are two patterns: + +1. **Read-only snapshot** — the caller has extracted TODO.md from a git ref (e.g. `git show main:TODO.md`) into a temp file like `/tmp/todo.abc123.md`. Read it but do **not** write to it. If the caller asks for an update, refuse and explain that the snapshot is read-only. +2. **Live worktree path** — the caller passes a path like `/path/to/worktree/TODO.md`. Both reads and writes are allowed. + +The caller indicates the mode in the prompt (e.g. "read-only snapshot at ..." vs. "live file at ..."). When the mode is unclear, default to read-only and ask. + +If no path is provided, fall back to `./TODO.md` relative to the current working directory. This fallback is for ad-hoc invocations only. + +If the file does not exist when an operation requires it: +- For read/list/update operations: report "TODO.md not found at " and stop. +- For create operations: create it with the header `# TODO\n\n` and proceed (only when in live mode). ## TODO.md Schema diff --git a/config/opencode/commands/review.md b/config/opencode/commands/review.md index 245a75e..77522e0 100644 --- a/config/opencode/commands/review.md +++ b/config/opencode/commands/review.md @@ -1,5 +1,5 @@ --- -description: review changes [commit|branch|pr|@plan], defaults to uncommitted +description: review changes [commit|branch|@plan], defaults to uncommitted subtask: true --- @@ -16,12 +16,11 @@ Classify the input into one of these modes: | Pattern | Mode | |---------|------| | Empty / no arguments | **code:uncommitted** | -| Contains `github.com` or `pull` or is a bare number (e.g. `42`) | **code:pr** | | Hex string 7-40 chars (e.g. `a1b2c3d`) | **code:commit** | | File content provided via `@` reference (look for file contents in context) | **plan** | | Otherwise, treat as branch name | **code:branch** | -Use best judgement when the input is ambiguous. +Use best judgement when the input is ambiguous. The command is forge-agnostic — review remote pull/merge requests by checking out the branch locally and passing the branch name (or by passing the merge-base commit). --- @@ -33,7 +32,6 @@ Run the appropriate git commands to get the diff: - **code:uncommitted**: `git diff` + `git diff --cached` + `git status --short` (read untracked files too) - **code:commit**: `git show $ARGUMENTS` - **code:branch**: `git diff $ARGUMENTS...HEAD` -- **code:pr**: `gh pr view $ARGUMENTS` + `gh pr diff $ARGUMENTS` Then: 1. Identify all changed files from the diff diff --git a/config/opencode/commands/workflow.md b/config/opencode/commands/workflow.md index 736758c..3a5997b 100644 --- a/config/opencode/commands/workflow.md +++ b/config/opencode/commands/workflow.md @@ -1,5 +1,5 @@ --- -description: "Fire-and-forget multi-agent workflow: plan, test, implement, PR" +description: "Fire-and-forget multi-agent workflow: plan, test, implement, commit" agent: build --- @@ -13,21 +13,33 @@ If `$ARGUMENTS` is empty, stop immediately: "Usage: `/workflow ` (e.g. ## Phase 1: Repo Setup -Verify you are at the bare repo root and the environment is ready. +Verify you are in a bare git repo and that the issue tracker exists. -1. Confirm `.bare/` directory exists in the current working directory. If not, stop: "Not at bare repo root. Run from the directory containing `.bare/`." -2. Verify the repo is hosted on GitHub: `git remote get-url origin 2>/dev/null | grep -qE '(github\.com|^git@github\.com:)'`. If the command fails (no `origin` remote, or origin is not on GitHub), stop: "Workflow requires a GitHub remote at `origin` (used by `gh pr create` in Phase 10)." -3. Run `gh auth status`. If auth is expired or missing, stop: "GitHub CLI auth expired. Run `gh auth login` before retrying." -4. Proceed to Phase 2 to get issue context before creating the worktree. +1. Verify the current repository is bare: `git rev-parse --is-bare-repository 2>/dev/null` must output `true`. If not, stop: "Workflow requires a bare git repository (set up with `git clone --bare` or the `.bare/` + `.git` file pattern)." +2. Capture the bare repo root for later worktree creation: `BARE_REPO_ROOT="$(pwd)"`. +3. Determine the default branch (source of TODO.md and base for new worktrees). Resolve in order: + a. `git symbolic-ref --short HEAD` — the bare repo's HEAD + b. `git config init.defaultBranch` — the configured default + c. fall back to `main` + + Store as `DEFAULT_BRANCH`. +4. Verify TODO.md exists on the default branch: `git show "$DEFAULT_BRANCH:TODO.md" > /dev/null 2>&1`. If not, stop: "TODO.md not found on `$DEFAULT_BRANCH`. Commit a TODO.md there first — the workflow expects it to be a tracked file." +5. Snapshot TODO.md to a temp file so `@pm` can read it before any worktree exists: + ```bash + TODO_READ_PATH="$(mktemp -t todo.XXXXXX.md)" + git show "$DEFAULT_BRANCH:TODO.md" > "$TODO_READ_PATH" + ``` + Pass `$TODO_READ_PATH` to `@pm` in Phase 2 (read-only context). +6. Proceed to Phase 2. --- ## Phase 2: Issue Context -Use `@pm` to fetch the issue matching `$ARGUMENTS` from `./TODO.md`: +Use `@pm` to fetch the issue matching `$ARGUMENTS` from the snapshot at `$TODO_READ_PATH`: - Issue title, description, acceptance criteria - Labels and priority -- Any existing branch name / PR link +- Any existing branch name If the issue does not exist or `@pm` fails, stop with error. @@ -37,13 +49,13 @@ Derive a branch name: `-` (e.g. `abc-1-add- ## Phase 3: Repo Setup (continued) -From the bare repo root (the directory containing `.bare/`): +From `$BARE_REPO_ROOT`: -1. `git fetch origin` +1. If an `origin` remote is configured, run `git fetch origin` (best-effort; ignore failure if there is no remote). 2. Compute worktree directory: replace all `/` with `-` in the branch name (e.g. `feat/abc-1-foo` becomes `feat-abc-1-foo`) 3. Check if worktree directory already exists. If yes, enter it and verify `git status --porcelain` is empty. If dirty, stop: "Worktree exists but has uncommitted changes. Clean it up first." -4. If worktree does not exist: `git worktree add -b master` -5. Change working directory to the new worktree. +4. If worktree does not exist: `git worktree add -b "$DEFAULT_BRANCH"` +5. Change working directory to the new worktree. From here on, `./TODO.md` in the worktree is the **live, writable** copy that Phase 10 will update. --- @@ -88,7 +100,7 @@ Reviewers should evaluate testability: 3. If verdict is ACCEPTABLE from both (or JUSTIFIED COMPLEXITY from `@simplify`): proceed to Phase 6 4. If BLOCK or NEEDS WORK: revise the plan addressing findings, then re-review 5. **Convergence detection:** if reviewers return the same findings as the previous cycle, stop the loop early -6. If still unresolved after 3 cycles: note unresolved blockers and proceed anyway (they will be documented in the PR) +6. If still unresolved after 3 cycles: note unresolved blockers and proceed anyway (they will be documented in the workflow summary and commit message) --- @@ -184,7 +196,7 @@ Dispatch `@check` and `@simplify` in parallel to review the full implementation Provide reviewers with: - The original plan -- The full diff (`git diff master...HEAD`) +- The full diff (`git diff "$DEFAULT_BRANCH"...HEAD`) - Any decisions or deviations from the plan **Review loop (max 3 cycles):** @@ -193,57 +205,53 @@ Provide reviewers with: 3. If ACCEPTABLE: proceed to Phase 10 4. If issues found: fix them directly (no need to re-dispatch `@make` for small fixes), then re-review 5. **Convergence detection:** same findings twice = stop loop early -6. If unresolved after 3 cycles: document blockers, proceed to PR anyway +6. If unresolved after 3 cycles: document blockers, proceed to commit anyway --- -## Phase 10: Commit, PR, and Wrap Up +## Phase 10: Commit and Wrap Up -### Commit -- Stage all changes -- Write a conventional commit message summarizing the implementation +The workflow is forge-agnostic. It commits locally and stops. **Do not push, and do not open a pull/merge request** — the user chooses their forge and review workflow manually. + +### Commit Code Changes +- Stage code changes (everything except `TODO.md` and `.opencode/workflow-summary.md`, which are committed separately below) +- Write a conventional commit message summarizing the implementation. Reference the TODO.md issue ID in the body (e.g. `Refs: ABC-1`). - If changes are large/varied, use multiple atomic commits (one per logical unit) -### Draft PR -- `gh pr create --draft --title "" --body ""` -- PR body should include: - - Summary of what was implemented - - Reference to TODO.md issue ID - - Acceptance criteria checklist (from issue) - - Files changed with brief descriptions - - TDD summary: X tasks with tests (RED→GREEN), Y tasks NOT_TESTABLE with justifications - - Any test quality escalations and their resolution - - Unresolved blockers (if any from review loops) - - Review cycle outcomes - ### TODO Update -- Use `@pm` to update the issue in `./TODO.md`: - - Set the **PR** field to the draft PR URL +- Use `@pm` to update the issue in `./TODO.md` (worktree-local; this is the live, writable copy): - Set **Branch** to the worktree branch name - Set **Status** to `In Review` - - Add a comment with the PR link and a one-line summary + - Add a comment with the branch name, latest commit SHA, and a one-line summary - If acceptance-criteria checkboxes were addressed by the implementation, ask `@pm` to check them off +- Commit the TODO.md change as a separate atomic commit: `chore(todo): update status and progress` ### Local Summary - Write `.opencode/workflow-summary.md` in the worktree with: - Run timestamp - Issue reference and title - - Branch and PR link + - Branch name and final commit SHA(s) - Summary of implementation - TDD evidence (RED→GREEN per task, NOT_TESTABLE justifications) - Review outcomes (plan review + final review verdicts) - Unresolved items (if any) - Files changed +- Commit the summary: `chore(workflow): summary for ` + +### Cleanup +- Remove the temp snapshot from Phase 1: `rm -f "$TODO_READ_PATH"` --- ## Failure Handling At any phase, if an unrecoverable error occurs: -1. Write `.opencode/workflow-summary.md` with what was completed and what failed +1. Write `.opencode/workflow-summary.md` (in the worktree, if one exists) with what was completed and what failed 2. If any code was written, commit it with message `wip: incomplete workflow run for ` -3. If a branch exists with commits, create the draft PR noting it is incomplete -4. Stop execution +3. Leave the branch and worktree intact for the user to inspect — do not push, do not delete +4. If a worktree exists, use `@pm` to add a comment on the issue in `./TODO.md` summarising what failed +5. Remove the temp snapshot if it was created: `rm -f "$TODO_READ_PATH"` +6. Stop execution **Never hang on interactive prompts.** If any command appears to require input, treat it as a failure and follow the above procedure.