Compare commits
8 Commits
bead/nixos
...
e0fdc70d2e
| Author | SHA1 | Date | |
|---|---|---|---|
| e0fdc70d2e | |||
| 352c89756f | |||
| a14ff9be4d | |||
| 90217ec85a | |||
| f99f4069f0 | |||
| 320a2d3738 | |||
| 92b6cfb710 | |||
| 996fb86ed8 |
18
.gitea/workflows/ci.yml
Normal file
18
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: https://git.johnogle.info/johno/gitea-actions/nix-setup@main
|
||||||
|
|
||||||
|
- name: Check flake
|
||||||
|
run: nix flake check
|
||||||
@@ -9,7 +9,7 @@ Directory Structure:
|
|||||||
----------------------
|
----------------------
|
||||||
• packages/ - Custom Nix packages leveraged across various configurations.
|
• packages/ - Custom Nix packages leveraged across various configurations.
|
||||||
• roles/ - Role-based configurations (e.g., kodi, bluetooth) each with its own module (default.nix) for inclusion in machine setups.
|
• roles/ - Role-based configurations (e.g., kodi, bluetooth) each with its own module (default.nix) for inclusion in machine setups.
|
||||||
• machines/ - Machine-specific configurations (e.g., nix-book, z790prors, boxy, wixos) including configuration.nix and hardware-configuration.nix tailored for each hardware.
|
• machines/ - Machine-specific configurations (e.g., nix-book, zix790prors, boxy) including configuration.nix and hardware-configuration.nix tailored for each hardware.
|
||||||
• home/ - Home-manager configurations for personal environments and application settings (e.g., home-nix-book.nix, home-z790prors.nix).
|
• home/ - Home-manager configurations for personal environments and application settings (e.g., home-nix-book.nix, home-z790prors.nix).
|
||||||
|
|
||||||
Design Principles:
|
Design Principles:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ This repository uses `beads` for issue tracking and management. Run `bd quicksta
|
|||||||
|
|
||||||
### Flake Structure
|
### Flake Structure
|
||||||
- **flake.nix**: Main entry point defining inputs (nixpkgs, home-manager, plasma-manager, etc.) and outputs for multiple NixOS configurations
|
- **flake.nix**: Main entry point defining inputs (nixpkgs, home-manager, plasma-manager, etc.) and outputs for multiple NixOS configurations
|
||||||
- **Machines**: `nix-book`, `boxy`, `wixos` (WSL configuration), `zix790prors`, `live-usb`, `johno-macbookpro` (Darwin/macOS)
|
- **Machines**: `nix-book`, `boxy`, `zix790prors`, `live-usb`, `johno-macbookpro` (Darwin/macOS)
|
||||||
- **Home configurations**: Standalone home-manager configuration for user `johno`
|
- **Home configurations**: Standalone home-manager configuration for user `johno`
|
||||||
|
|
||||||
### Directory Structure
|
### Directory Structure
|
||||||
@@ -78,7 +78,6 @@ The repository also uses a modular home-manager role system for user-space confi
|
|||||||
- **nix-book**: Compact laptop → excludes office/media roles due to SSD space constraints
|
- **nix-book**: Compact laptop → excludes office/media roles due to SSD space constraints
|
||||||
- **boxy**: Living room media center → optimized for media consumption, excludes sync/office (shared machine)
|
- **boxy**: Living room media center → optimized for media consumption, excludes sync/office (shared machine)
|
||||||
- **zix790prors**: All-purpose workstation → full desktop experience with all roles enabled
|
- **zix790prors**: All-purpose workstation → full desktop experience with all roles enabled
|
||||||
- **wixos**: WSL2 development → full desktop experience, inherits from zix790prors Windows host
|
|
||||||
- **live-usb**: Temporary environment → only base + desktop roles, no persistent services
|
- **live-usb**: Temporary environment → only base + desktop roles, no persistent services
|
||||||
- **johno-macbookpro**: macOS work laptop → Darwin-specific configuration with development tools
|
- **johno-macbookpro**: macOS work laptop → Darwin-specific configuration with development tools
|
||||||
|
|
||||||
@@ -111,7 +110,6 @@ darwin-rebuild build --flake .#johno-macbookpro
|
|||||||
- `nix-book`: Compact laptop with storage constraints, uses `home/home-laptop-compact.nix`
|
- `nix-book`: Compact laptop with storage constraints, uses `home/home-laptop-compact.nix`
|
||||||
- `boxy`: Shared living room media center/gaming desktop with AMD GPU, uses `home/home-media-center.nix`
|
- `boxy`: Shared living room media center/gaming desktop with AMD GPU, uses `home/home-media-center.nix`
|
||||||
- `zix790prors`: Powerful all-purpose workstation (gaming, 3D modeling, development), dual-boots Windows 11 with shared btrfs /games partition, uses `home/home-desktop.nix`
|
- `zix790prors`: Powerful all-purpose workstation (gaming, 3D modeling, development), dual-boots Windows 11 with shared btrfs /games partition, uses `home/home-desktop.nix`
|
||||||
- `wixos`: WSL2 development environment running in Windows partition of zix790prors, uses `home/home-desktop.nix`
|
|
||||||
- `live-usb`: Bootable ISO configuration, uses `home/home-live-usb.nix`
|
- `live-usb`: Bootable ISO configuration, uses `home/home-live-usb.nix`
|
||||||
- `johno-macbookpro`: macOS work laptop, uses `home/home-darwin-work.nix`
|
- `johno-macbookpro`: macOS work laptop, uses `home/home-darwin-work.nix`
|
||||||
|
|
||||||
|
|||||||
67
flake.lock
generated
67
flake.lock
generated
@@ -60,22 +60,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1765121682,
|
|
||||||
"narHash": "sha256-4VBOP18BFeiPkyhy9o4ssBNQEvfvv1kXkasAYd0+rrA=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "65f23138d8d09a92e30f1e5c87611b23ef451bf3",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
@@ -241,38 +225,18 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixos-wsl": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1765841014,
|
|
||||||
"narHash": "sha256-55V0AJ36V5Egh4kMhWtDh117eE3GOjwq5LhwxDn9eHg=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "NixOS-WSL",
|
|
||||||
"rev": "be4af8042e7a61fa12fda58fe9a3b3babdefe17b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"ref": "main",
|
|
||||||
"repo": "NixOS-WSL",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1765472234,
|
"lastModified": 1767480499,
|
||||||
"narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=",
|
"narHash": "sha256-8IQQUorUGiSmFaPnLSo2+T+rjHtiNWc+OAzeHck7N48=",
|
||||||
"owner": "NixOS",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b",
|
"rev": "30a3c519afcf3f99e2c6df3b359aec5692054d92",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "nixos",
|
||||||
"ref": "nixos-unstable",
|
"ref": "nixos-25.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -293,22 +257,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1767480499,
|
|
||||||
"narHash": "sha256-8IQQUorUGiSmFaPnLSo2+T+rjHtiNWc+OAzeHck7N48=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "30a3c519afcf3f99e2c6df3b359aec5692054d92",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixos-25.11",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"plasma-manager": {
|
"plasma-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"home-manager": [
|
"home-manager": [
|
||||||
@@ -364,8 +312,7 @@
|
|||||||
"jovian": "jovian",
|
"jovian": "jovian",
|
||||||
"nix-darwin": "nix-darwin",
|
"nix-darwin": "nix-darwin",
|
||||||
"nix-doom-emacs-unstraightened": "nix-doom-emacs-unstraightened",
|
"nix-doom-emacs-unstraightened": "nix-doom-emacs-unstraightened",
|
||||||
"nixos-wsl": "nixos-wsl",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs": "nixpkgs_2",
|
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
"plasma-manager": "plasma-manager",
|
"plasma-manager": "plasma-manager",
|
||||||
"plasma-manager-unstable": "plasma-manager-unstable"
|
"plasma-manager-unstable": "plasma-manager-unstable"
|
||||||
|
|||||||
18
flake.nix
18
flake.nix
@@ -4,7 +4,6 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
|
||||||
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
nixos-wsl.url = "github:nix-community/NixOS-WSL/main";
|
|
||||||
|
|
||||||
nix-darwin = {
|
nix-darwin = {
|
||||||
url = "github:nix-darwin/nix-darwin/nix-darwin-25.11";
|
url = "github:nix-darwin/nix-darwin/nix-darwin-25.11";
|
||||||
@@ -55,7 +54,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, nixpkgs-unstable, nixos-wsl, ... } @ inputs: let
|
outputs = { self, nixpkgs, nixpkgs-unstable, ... } @ inputs: let
|
||||||
# Shared overlay function to reduce duplication across module sets
|
# Shared overlay function to reduce duplication across module sets
|
||||||
# Parameters:
|
# Parameters:
|
||||||
# unstableOverlays: Additional overlays to apply when importing nixpkgs-unstable
|
# unstableOverlays: Additional overlays to apply when importing nixpkgs-unstable
|
||||||
@@ -84,6 +83,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
nixosModules = [
|
nixosModules = [
|
||||||
./roles
|
./roles
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
@@ -157,24 +157,10 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
nixosConfigurations.wixos = nixpkgs.lib.nixosSystem rec {
|
|
||||||
system = "x86_64-linux";
|
|
||||||
modules = nixosModules ++ [
|
|
||||||
nixos-wsl.nixosModules.default
|
|
||||||
./machines/wixos/configuration.nix
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.users.johno = import ./home/home-desktop.nix;
|
|
||||||
home-manager.extraSpecialArgs = { inherit system; };
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
nixosConfigurations.zix790prors = nixpkgs.lib.nixosSystem rec {
|
nixosConfigurations.zix790prors = nixpkgs.lib.nixosSystem rec {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = nixosModules ++ [
|
modules = nixosModules ++ [
|
||||||
./machines/zix790prors/configuration.nix
|
./machines/zix790prors/configuration.nix
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
{
|
{
|
||||||
home-manager.users.johno = import ./home/home-desktop.nix;
|
home-manager.users.johno = import ./home/home-desktop.nix;
|
||||||
home-manager.extraSpecialArgs = { inherit system; };
|
home-manager.extraSpecialArgs = { inherit system; };
|
||||||
|
|||||||
@@ -1,217 +1,350 @@
|
|||||||
---
|
---
|
||||||
description: Manage and respond to Gitea/Forgejo PR review comments
|
description: Address Gitea/Forgejo PR review comments with code changes
|
||||||
---
|
---
|
||||||
|
|
||||||
# Gitea PR Review Comments
|
# Gitea PR Review
|
||||||
|
|
||||||
This skill enables reading PR review comments and posting inline thread replies on Gitea/Forgejo instances.
|
You are tasked with **addressing** PR review comments by making code changes, then summarizing what was done. This skill drives PR progress, not just conversation.
|
||||||
|
|
||||||
|
## Philosophy
|
||||||
|
|
||||||
|
**Comments are work items, not conversation starters.**
|
||||||
|
|
||||||
|
When a reviewer leaves a comment, they're identifying something that needs attention. This skill:
|
||||||
|
1. Categorizes comments by actionability
|
||||||
|
2. Makes code changes to address actionable comments
|
||||||
|
3. Commits and pushes those changes
|
||||||
|
4. Posts a single summary comment describing what was done
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- `tea` CLI configured with a Gitea/Forgejo instance
|
- `tea` CLI configured with a Gitea/Forgejo instance
|
||||||
- Access token from tea config: `~/.config/tea/config.yml`
|
- Access token from tea config: `~/.config/tea/config.yml`
|
||||||
- Repository must be a Gitea/Forgejo remote (not GitHub)
|
- Repository must be a Gitea/Forgejo remote (not GitHub)
|
||||||
|
- **Nix users**: All tools available via nixpkgs (`nix run nixpkgs#tea`)
|
||||||
|
|
||||||
## Configuration
|
## Initial Setup
|
||||||
|
|
||||||
Get the Gitea instance URL and token from tea config:
|
When this command is invoked:
|
||||||
|
|
||||||
|
1. **Parse the input for PR number**:
|
||||||
|
- If a PR number is provided as argument, use it
|
||||||
|
- If no PR number, detect from current branch (see PR Detection section)
|
||||||
|
|
||||||
|
2. **Verify required tools are available**:
|
||||||
```bash
|
```bash
|
||||||
# Get the default login URL and token
|
which tea
|
||||||
yq -r '.logins[] | select(.name == "default") | .url' ~/.config/tea/config.yml
|
|
||||||
yq -r '.logins[] | select(.name == "default") | .token' ~/.config/tea/config.yml
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Or if you have a specific login name:
|
If tea is missing:
|
||||||
|
```
|
||||||
|
Error: `tea` CLI not found.
|
||||||
|
|
||||||
|
Please install:
|
||||||
|
- Nix: nix run nixpkgs#tea
|
||||||
|
- Other: https://gitea.com/gitea/tea
|
||||||
|
```
|
||||||
|
**STOP** if tea is missing.
|
||||||
|
|
||||||
|
3. **Extract configuration from tea config**:
|
||||||
```bash
|
```bash
|
||||||
yq -r '.logins[] | select(.name == "YOUR_LOGIN") | .url' ~/.config/tea/config.yml
|
# Read tea config (it's YAML but simple enough to grep)
|
||||||
yq -r '.logins[] | select(.name == "YOUR_LOGIN") | .token' ~/.config/tea/config.yml
|
TEA_CONFIG="$HOME/.config/tea/config.yml"
|
||||||
|
GITEA_URL=$(grep -A1 'logins:' "$TEA_CONFIG" | grep 'url:' | head -1 | sed 's/.*url: //')
|
||||||
|
TOKEN=$(grep -A5 'logins:' "$TEA_CONFIG" | grep 'token:' | head -1 | sed 's/.*token: //')
|
||||||
```
|
```
|
||||||
|
|
||||||
## Commands
|
If config is missing or invalid:
|
||||||
|
```
|
||||||
|
Error: Could not read tea config at ~/.config/tea/config.yml
|
||||||
|
|
||||||
### 1. List PR Review Comments
|
Please ensure `tea` is installed and configured:
|
||||||
|
1. Install tea
|
||||||
|
2. Log in: tea login add --url https://your-gitea-instance --token YOUR_TOKEN
|
||||||
|
```
|
||||||
|
**STOP** if config is invalid.
|
||||||
|
|
||||||
Fetch all reviews and their comments for a PR:
|
4. **Detect repository info from git remote**:
|
||||||
|
```bash
|
||||||
|
REMOTE_URL=$(git remote get-url origin)
|
||||||
|
# Parse owner and repo from URL (handles both SSH and HTTPS)
|
||||||
|
OWNER=$(echo "$REMOTE_URL" | sed -E 's#.*[:/]([^/]+)/[^/]+\.git$#\1#')
|
||||||
|
REPO=$(echo "$REMOTE_URL" | sed -E 's#.*/([^/]+)\.git$#\1#')
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Ensure we're on the PR branch**:
|
||||||
|
```bash
|
||||||
|
CURRENT_BRANCH=$(git branch --show-current)
|
||||||
|
# Verify this branch corresponds to the PR
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Respond with**:
|
||||||
|
```
|
||||||
|
Addressing PR review comments for PR #{PR_NUMBER}...
|
||||||
|
|
||||||
|
Repository: {OWNER}/{REPO}
|
||||||
|
Branch: {CURRENT_BRANCH}
|
||||||
|
Gitea URL: {GITEA_URL}
|
||||||
|
```
|
||||||
|
|
||||||
|
## PR Detection
|
||||||
|
|
||||||
|
If no PR number is provided, detect from the current branch:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Set environment variables
|
CURRENT_BRANCH=$(git branch --show-current)
|
||||||
GITEA_URL="https://git.johnogle.info"
|
tea pr list --fields index,head --output simple | grep "$CURRENT_BRANCH"
|
||||||
TOKEN="<your-token>"
|
```
|
||||||
OWNER="<repo-owner>"
|
|
||||||
REPO="<repo-name>"
|
|
||||||
PR_NUMBER="<pr-number>"
|
|
||||||
|
|
||||||
# Get all reviews for the PR
|
If no PR exists for the current branch, use `AskUserQuestion`:
|
||||||
|
|
||||||
|
```
|
||||||
|
No PR found for branch '{CURRENT_BRANCH}'.
|
||||||
|
|
||||||
|
Would you like to:
|
||||||
|
1. Enter a PR number manually
|
||||||
|
2. Cancel
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
### Step 1: Fetch and Parse Comments
|
||||||
|
|
||||||
|
Fetch all reviews and their comments:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Fetch reviews (filter out dismissed reviews)
|
||||||
curl -s -H "Authorization: token $TOKEN" \
|
curl -s -H "Authorization: token $TOKEN" \
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews" | jq
|
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews" \
|
||||||
|
| jq '[.[] | select(.dismissed != true)]'
|
||||||
|
|
||||||
# Get comments for a specific review
|
# For each review, fetch comments
|
||||||
REVIEW_ID="<review-id>"
|
|
||||||
curl -s -H "Authorization: token $TOKEN" \
|
curl -s -H "Authorization: token $TOKEN" \
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews/$REVIEW_ID/comments" | jq
|
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews/$REVIEW_ID/comments"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. View All Review Comments (Combined)
|
**Filter resolved comments**: When processing comments, skip any that have been marked as resolved. Check the `resolver` field in the comment response - if it's not null, the comment has been resolved and should be skipped.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Get all reviews and their comments in one view
|
# Example: Filter to only unresolved comments
|
||||||
curl -s -H "Authorization: token $TOKEN" \
|
jq '[.[] | select(.resolver == null)]'
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews" | \
|
|
||||||
jq -r '.[] | "Review \(.id) by \(.user.login): \(.state)\n Body: \(.body)"'
|
|
||||||
|
|
||||||
# For each review, show inline comments
|
|
||||||
for REVIEW_ID in $(curl -s -H "Authorization: token $TOKEN" \
|
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews" | jq -r '.[].id'); do
|
|
||||||
echo "=== Review $REVIEW_ID comments ==="
|
|
||||||
curl -s -H "Authorization: token $TOKEN" \
|
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews/$REVIEW_ID/comments" | \
|
|
||||||
jq -r '.[] | "[\(.path):\(.line)] \(.body)"'
|
|
||||||
done
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Reply to Review Comments (Web Endpoint Method)
|
If no reviews found or all comments are resolved:
|
||||||
|
|
||||||
The Gitea REST API does not support replying to review comment threads. The web UI uses a different endpoint:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
POST /{owner}/{repo}/pulls/{pr_number}/files/reviews/comments
|
No unresolved reviews found for PR #{PR_NUMBER}.
|
||||||
Content-Type: multipart/form-data
|
Nothing to address.
|
||||||
|
```
|
||||||
|
**STOP** here.
|
||||||
|
|
||||||
|
### Step 2: Categorize Comments
|
||||||
|
|
||||||
|
For each comment, categorize it as one of:
|
||||||
|
|
||||||
|
| Category | Description | Action |
|
||||||
|
|----------|-------------|--------|
|
||||||
|
| **actionable** | Requests a code change, addition, or fix | Launch subagent to make change |
|
||||||
|
| **question** | Asks for clarification or explanation | Include answer in summary |
|
||||||
|
| **acknowledged** | FYI, self-resolved, or "no action needed" noted | Note in summary |
|
||||||
|
| **blocked** | Requires external input or is out of scope | Flag for user |
|
||||||
|
|
||||||
|
**Categorization heuristics**:
|
||||||
|
- Contains "add", "change", "fix", "update", "consider adding", "should be" → **actionable**
|
||||||
|
- Contains "?" or "why", "how", "what" → **question**
|
||||||
|
- Contains "no need to update", "will be separate", "acknowledged" → **acknowledged**
|
||||||
|
- Contains "discuss", "later", "out of scope", "blocked by" → **blocked**
|
||||||
|
|
||||||
|
Display the categorization:
|
||||||
|
```
|
||||||
|
## Comment Analysis
|
||||||
|
|
||||||
|
### Actionable (will make changes):
|
||||||
|
1. {file}:{line} - "{comment_summary}" → Will add nix note to prerequisites
|
||||||
|
|
||||||
|
### Questions (will answer in summary):
|
||||||
|
2. {file}:{line} - "{comment_summary}" → Explain CI token approach
|
||||||
|
|
||||||
|
### Acknowledged (no action needed):
|
||||||
|
3. {file}:{line} - "{comment_summary}" → Reviewer noted separate skill
|
||||||
|
|
||||||
|
### Blocked (needs input):
|
||||||
|
(none)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Required form fields:**
|
### Step 3: User Confirmation
|
||||||
- `reply`: Review ID to reply to
|
|
||||||
- `content`: The reply message
|
|
||||||
- `path`: File path
|
|
||||||
- `line`: Line number
|
|
||||||
- `side`: `proposed` or `original`
|
|
||||||
- `single_review`: `true`
|
|
||||||
- `origin`: `timeline`
|
|
||||||
- `_csrf`: CSRF token (required for web endpoint)
|
|
||||||
|
|
||||||
**Authentication Challenge:**
|
Use `AskUserQuestion` to confirm the plan:
|
||||||
This endpoint requires session-based authentication, not API tokens. Options:
|
|
||||||
|
|
||||||
#### Option A: Use Browser Session (Recommended)
|
```
|
||||||
|
I've categorized {N} comments. My plan:
|
||||||
|
|
||||||
1. Log in to Gitea in your browser
|
**Will make changes for:**
|
||||||
2. Open browser developer tools and copy cookies
|
- {file}:{line}: {planned_change}
|
||||||
3. Use the session cookies with curl
|
|
||||||
|
**Will explain in summary:**
|
||||||
|
- {file}:{line}: {planned_explanation}
|
||||||
|
|
||||||
|
**No action needed:**
|
||||||
|
- {file}:{line}: {reason}
|
||||||
|
|
||||||
|
Proceed with this plan?
|
||||||
|
```
|
||||||
|
|
||||||
|
Options:
|
||||||
|
1. **Proceed** - Execute the plan
|
||||||
|
2. **Modify** - Let user adjust categorization
|
||||||
|
3. **Cancel** - Exit without changes
|
||||||
|
|
||||||
|
### Step 4: Address Actionable Comments (Parallel Subagents)
|
||||||
|
|
||||||
|
For each actionable comment, launch a subagent using the Task tool:
|
||||||
|
|
||||||
|
```
|
||||||
|
Launch Task subagent with:
|
||||||
|
- subagent_type: "general-purpose"
|
||||||
|
- prompt: |
|
||||||
|
You are addressing a PR review comment. Make the requested change and nothing else.
|
||||||
|
|
||||||
|
**File**: {file_path}
|
||||||
|
**Line**: {line_number}
|
||||||
|
**Comment**: {comment_body}
|
||||||
|
**Diff context**:
|
||||||
|
```
|
||||||
|
{diff_hunk}
|
||||||
|
```
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
1. Read the file to understand context
|
||||||
|
2. Make the minimal change to address the comment
|
||||||
|
3. Do NOT commit - just make the edit
|
||||||
|
4. Report what you changed
|
||||||
|
|
||||||
|
Be precise. Only change what's needed to address this specific comment.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important**: Launch actionable comment subagents in parallel when they touch different files. For comments on the same file, run sequentially to avoid conflicts.
|
||||||
|
|
||||||
|
Wait for all subagents to complete and collect their results.
|
||||||
|
|
||||||
|
### Step 5: Commit and Push
|
||||||
|
|
||||||
|
After all subagents complete:
|
||||||
|
|
||||||
|
1. **Stage changes**:
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Create commit with summary**:
|
||||||
|
```bash
|
||||||
|
git commit -m "Address PR review comments
|
||||||
|
|
||||||
|
Changes made:
|
||||||
|
- {file1}: {change_summary}
|
||||||
|
- {file2}: {change_summary}
|
||||||
|
|
||||||
|
Addresses comments from review by {reviewer}"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Push to remote**:
|
||||||
|
```bash
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 6: Post Summary Comment
|
||||||
|
|
||||||
|
Post a single comment summarizing all actions taken:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# First, get CSRF token from the PR page
|
tea comment $PR_NUMBER "$(cat <<'EOF'
|
||||||
CSRF=$(curl -s -c cookies.txt -b cookies.txt \
|
## Review Comments Addressed
|
||||||
"$GITEA_URL/$OWNER/$REPO/pulls/$PR_NUMBER/files" | \
|
|
||||||
grep -oP 'name="_csrf" value="\K[^"]+')
|
|
||||||
|
|
||||||
# Post the reply
|
cc @{reviewer1} @{reviewer2}
|
||||||
curl -s -b cookies.txt \
|
|
||||||
-F "reply=$REVIEW_ID" \
|
**Changes made** (commit {SHORT_SHA}):
|
||||||
-F "content=Your reply message here" \
|
- `{file1}:{line}`: {what_was_changed}
|
||||||
-F "path=$FILE_PATH" \
|
- `{file2}:{line}`: {what_was_changed}
|
||||||
-F "line=$LINE_NUMBER" \
|
|
||||||
-F "side=proposed" \
|
**Responses to questions**:
|
||||||
-F "single_review=true" \
|
- `{file3}:{line}`: {answer_to_question}
|
||||||
-F "origin=timeline" \
|
|
||||||
-F "_csrf=$CSRF" \
|
**Acknowledged** (no action needed):
|
||||||
"$GITEA_URL/$OWNER/$REPO/pulls/$PR_NUMBER/files/reviews/comments"
|
- `{file4}:{line}`: {reason_no_action}
|
||||||
|
|
||||||
|
---
|
||||||
|
*Automated response via /gitea_pr_review*
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Option B: Create Top-Level Comment (Fallback)
|
### Step 7: Final Summary
|
||||||
|
|
||||||
If thread replies are not critical, use the API to create a top-level comment:
|
Display to user:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
# Create a top-level comment mentioning the review context
|
## PR Review Complete
|
||||||
curl -s -X POST \
|
|
||||||
-H "Authorization: token $TOKEN" \
|
**Commit**: {SHA}
|
||||||
-H "Content-Type: application/json" \
|
**Changes**: {N} files modified
|
||||||
-d "{\"body\": \"Re: @reviewer's comment on $FILE_PATH:$LINE_NUMBER\n\nYour reply here\"}" \
|
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/issues/$PR_NUMBER/comments"
|
### Actions Taken:
|
||||||
|
- [x] {file1}:{line} - Added nix prerequisite note
|
||||||
|
- [x] {file2}:{line} - Explained CI approach in comment
|
||||||
|
- [ ] {file3}:{line} - Acknowledged (separate skill)
|
||||||
|
|
||||||
|
**Reviewers tagged**: @{reviewer1}, @{reviewer2}
|
||||||
|
**Comment posted**: {comment_url}
|
||||||
|
|
||||||
|
PR URL: {GITEA_URL}/{OWNER}/{REPO}/pulls/{PR_NUMBER}
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use tea CLI:
|
**Note**: When posting the summary comment, tag all reviewers who left comments so they receive notifications about the changes.
|
||||||
```bash
|
|
||||||
tea comment $PR_NUMBER "Re: @reviewer's comment on $FILE_PATH:$LINE_NUMBER
|
|
||||||
|
|
||||||
Your reply here"
|
## Error Handling
|
||||||
|
|
||||||
|
### Subagent failed to make change
|
||||||
|
|
||||||
|
If a subagent fails:
|
||||||
|
```
|
||||||
|
Warning: Could not address comment on {file}:{line}
|
||||||
|
|
||||||
|
Reason: {error}
|
||||||
|
|
||||||
|
Options:
|
||||||
|
1. Skip this comment and continue
|
||||||
|
2. Retry with manual guidance
|
||||||
|
3. Abort all changes
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Submit a New Review
|
### Push failed
|
||||||
|
|
||||||
Create a new review with inline comments:
|
```
|
||||||
|
Error pushing changes: {error}
|
||||||
|
|
||||||
```bash
|
Your changes are committed locally. You may need to:
|
||||||
curl -s -X POST \
|
1. Pull and resolve conflicts: git pull --rebase
|
||||||
-H "Authorization: token $TOKEN" \
|
2. Push again: git push
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"body": "Overall review comments",
|
|
||||||
"event": "COMMENT",
|
|
||||||
"comments": [
|
|
||||||
{
|
|
||||||
"path": "path/to/file.py",
|
|
||||||
"body": "Comment on this line",
|
|
||||||
"new_position": 10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}' \
|
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Event types: `COMMENT`, `APPROVE`, `REQUEST_CHANGES`
|
### No actionable comments
|
||||||
|
|
||||||
## Workflow Example
|
If all comments are questions/acknowledged:
|
||||||
|
|
||||||
### Reading and Responding to Reviews
|
|
||||||
|
|
||||||
1. **Set up environment**:
|
|
||||||
```bash
|
|
||||||
export GITEA_URL=$(yq -r '.logins[] | select(.name == "default") | .url' ~/.config/tea/config.yml)
|
|
||||||
export TOKEN=$(yq -r '.logins[] | select(.name == "default") | .token' ~/.config/tea/config.yml)
|
|
||||||
export OWNER="johno"
|
|
||||||
export REPO="nixos-configs"
|
|
||||||
export PR_NUMBER="5"
|
|
||||||
```
|
```
|
||||||
|
No code changes needed.
|
||||||
|
|
||||||
2. **List all pending review comments**:
|
All comments are either questions or acknowledged items.
|
||||||
```bash
|
Posting summary comment with explanations...
|
||||||
# Get reviews
|
|
||||||
curl -s -H "Authorization: token $TOKEN" \
|
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews" | \
|
|
||||||
jq -r '.[] | select(.state == "REQUEST_CHANGES" or .state == "COMMENT") |
|
|
||||||
"Review \(.id) by \(.user.login) (\(.state)):\n\(.body)\n"'
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Get detailed comments for a review**:
|
|
||||||
```bash
|
|
||||||
REVIEW_ID="2"
|
|
||||||
curl -s -H "Authorization: token $TOKEN" \
|
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews/$REVIEW_ID/comments" | \
|
|
||||||
jq -r '.[] | "File: \(.path):\(.line)\nComment: \(.body)\nID: \(.id)\n---"'
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Respond using top-level comment** (most reliable):
|
|
||||||
```bash
|
|
||||||
tea comment $PR_NUMBER "Addressing review feedback:
|
|
||||||
|
|
||||||
- File \`path/to/file.py\` line 10: Fixed the issue by...
|
|
||||||
- File \`other/file.py\` line 25: Updated as suggested..."
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Reference
|
## API Reference
|
||||||
|
|
||||||
### Endpoints
|
### Endpoints Used
|
||||||
|
|
||||||
| Action | Method | Endpoint |
|
| Action | Method | Endpoint |
|
||||||
|--------|--------|----------|
|
|--------|--------|----------|
|
||||||
| List reviews | GET | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews` |
|
| List reviews | GET | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews` |
|
||||||
| Get review | GET | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{id}` |
|
|
||||||
| Get review comments | GET | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments` |
|
| Get review comments | GET | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments` |
|
||||||
| Create review | POST | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews` |
|
| Create issue comment | POST | via `tea comment` |
|
||||||
| Submit review | POST | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{id}` |
|
|
||||||
| Delete review | DELETE | `/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{id}` |
|
|
||||||
| Create issue comment | POST | `/api/v1/repos/{owner}/{repo}/issues/{index}/comments` |
|
|
||||||
|
|
||||||
### Review States
|
### Review States
|
||||||
|
|
||||||
@@ -220,25 +353,120 @@ Event types: `COMMENT`, `APPROVE`, `REQUEST_CHANGES`
|
|||||||
- `APPROVE` - Approving the changes
|
- `APPROVE` - Approving the changes
|
||||||
- `REQUEST_CHANGES` - Requesting changes before merge
|
- `REQUEST_CHANGES` - Requesting changes before merge
|
||||||
|
|
||||||
|
## Shell Command Patterns
|
||||||
|
|
||||||
|
Claude Code's bash execution has quirks. Use these patterns for reliability:
|
||||||
|
|
||||||
|
### curl requests
|
||||||
|
|
||||||
|
**DO** - Use single quotes for URL and header separately:
|
||||||
|
```bash
|
||||||
|
curl -s 'https://git.example.com/api/v1/repos/owner/repo/pulls/1/reviews' \
|
||||||
|
-H 'Authorization: token YOUR_TOKEN_HERE' | jq .
|
||||||
|
```
|
||||||
|
|
||||||
|
**DON'T** - Variable expansion in `-H` flag often fails:
|
||||||
|
```bash
|
||||||
|
# This may fail with "blank argument" errors
|
||||||
|
curl -s -H "Authorization: token $TOKEN" "$URL"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Iterating over reviews
|
||||||
|
|
||||||
|
**DO** - Run separate commands for each review ID:
|
||||||
|
```bash
|
||||||
|
echo "=== Review 4 ===" && curl -s 'URL/reviews/4/comments' -H 'Authorization: token ...' | jq .
|
||||||
|
echo "=== Review 5 ===" && curl -s 'URL/reviews/5/comments' -H 'Authorization: token ...' | jq .
|
||||||
|
```
|
||||||
|
|
||||||
|
**DON'T** - For loops with multiline bodies often fail:
|
||||||
|
```bash
|
||||||
|
# This may cause syntax errors
|
||||||
|
for id in 4 5 6; do
|
||||||
|
curl -s "URL/reviews/$id/comments"
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
### tea comment
|
||||||
|
|
||||||
|
**DO** - Use single-quoted string for comment body:
|
||||||
|
```bash
|
||||||
|
tea comment 26 '## Summary
|
||||||
|
|
||||||
|
Changes made:
|
||||||
|
- Item 1
|
||||||
|
- Item 2'
|
||||||
|
```
|
||||||
|
|
||||||
|
**DON'T** - Heredocs may hang or timeout:
|
||||||
|
```bash
|
||||||
|
# This may hang indefinitely
|
||||||
|
tea comment 26 "$(cat <<'EOF'
|
||||||
|
...
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
```
|
||||||
|
|
||||||
## Limitations
|
## Limitations
|
||||||
|
|
||||||
1. **Thread replies**: The Gitea REST API does not support replying directly to review comment threads. This is a known limitation. Workarounds:
|
1. **Thread replies**: Gitea API doesn't support inline thread replies. We post a single summary comment instead.
|
||||||
- Use top-level comments with context
|
|
||||||
- Use the web UI manually for thread replies
|
|
||||||
- Implement session-based authentication to use the web endpoint
|
|
||||||
|
|
||||||
2. **CSRF tokens**: The web endpoint for thread replies requires CSRF tokens, which expire and need to be fetched from the page.
|
2. **Complex changes**: For comments requiring significant refactoring, the subagent may need guidance. The skill will flag these as "blocked" for user input.
|
||||||
|
|
||||||
3. **Session auth**: API tokens work for REST API but not for web endpoints that require session cookies.
|
3. **Merge conflicts**: If the branch is behind, you may need to rebase before changes can be pushed.
|
||||||
|
|
||||||
## Tips
|
## Example Session
|
||||||
|
|
||||||
- Always quote file paths and line numbers when responding via top-level comments
|
```
|
||||||
- Use `tea pr view $PR_NUMBER --comments` to see all comments
|
User: /gitea_pr_review 26
|
||||||
- Use `tea open pulls/$PR_NUMBER` to open the PR in browser for manual thread replies
|
Assistant: Addressing PR review comments for PR #26...
|
||||||
- Consider using `tea pr approve $PR_NUMBER` after addressing all comments
|
|
||||||
|
Repository: johno/nixos-configs
|
||||||
|
Branch: bead/nixos-configs-vru
|
||||||
|
Gitea URL: https://git.johnogle.info
|
||||||
|
|
||||||
|
## Comment Analysis
|
||||||
|
|
||||||
|
### Actionable (will make changes):
|
||||||
|
1. gitea_pr_review.md:12 - "could we indicate nix+nixpkgs satisfies this?"
|
||||||
|
→ Will add note that nix users can get tools via nixpkgs
|
||||||
|
|
||||||
|
### Questions (will answer in summary):
|
||||||
|
(none)
|
||||||
|
|
||||||
|
### Acknowledged (no action needed):
|
||||||
|
2. gitea_pr_review.md:50 - "we eventually want to run this in CI..."
|
||||||
|
→ Reviewer noted this will be a separate skill
|
||||||
|
|
||||||
|
Proceed with this plan? [Proceed]
|
||||||
|
|
||||||
|
Launching subagent to address comment 1...
|
||||||
|
[Subagent completes edit]
|
||||||
|
|
||||||
|
Committing changes...
|
||||||
|
[abc1234] Address PR review comments
|
||||||
|
|
||||||
|
Pushing to remote...
|
||||||
|
Done.
|
||||||
|
|
||||||
|
Posting summary comment...
|
||||||
|
|
||||||
|
## PR Review Complete
|
||||||
|
|
||||||
|
**Commit**: abc1234
|
||||||
|
**Changes**: 1 file modified
|
||||||
|
|
||||||
|
### Actions Taken:
|
||||||
|
- [x] gitea_pr_review.md:12 - Added nix prerequisite note
|
||||||
|
- [ ] gitea_pr_review.md:50 - Acknowledged (separate skill)
|
||||||
|
|
||||||
|
**Comment posted**: https://git.johnogle.info/.../pulls/26#issuecomment-XXX
|
||||||
|
|
||||||
|
PR URL: https://git.johnogle.info/johno/nixos-configs/pulls/26
|
||||||
|
```
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
- Gitea API Documentation: https://docs.gitea.com/api/1.20/
|
|
||||||
- `tea` CLI: https://gitea.com/gitea/tea
|
- `tea` CLI: https://gitea.com/gitea/tea
|
||||||
|
- Gitea API: https://docs.gitea.com/api/
|
||||||
|
- `/beads_workflow` for full development workflow
|
||||||
|
|||||||
@@ -42,7 +42,46 @@ AskUserQuestion with:
|
|||||||
- options from filtered bd ready output
|
- options from filtered bd ready output
|
||||||
```
|
```
|
||||||
|
|
||||||
## Phase 2: Parallel Implementation
|
## Phase 2: Worktree Setup
|
||||||
|
|
||||||
|
Before launching implementation subagents, create worktrees for all selected beads:
|
||||||
|
|
||||||
|
1. **Get repository name**:
|
||||||
|
```bash
|
||||||
|
REPO_NAME=$(git remote get-url origin | sed 's|.*/||' | sed 's/\.git$//')
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **For each selected bead**, create its worktree:
|
||||||
|
```bash
|
||||||
|
BEAD_ID="[bead-id]"
|
||||||
|
# Check if worktree already exists
|
||||||
|
if [ -d "$HOME/wt/${REPO_NAME}/${BEAD_ID}" ]; then
|
||||||
|
echo "Worktree already exists: ~/wt/${REPO_NAME}/${BEAD_ID}"
|
||||||
|
# Ask user: remove and recreate, or skip this bead?
|
||||||
|
else
|
||||||
|
git worktree add -b "bead/${BEAD_ID}" "$HOME/wt/${REPO_NAME}/${BEAD_ID}"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Track created worktrees**:
|
||||||
|
Maintain a list of (bead_id, worktree_path) pairs for use in subagent instructions.
|
||||||
|
|
||||||
|
4. **Report status**:
|
||||||
|
```
|
||||||
|
Created worktrees:
|
||||||
|
- nixos-configs-abc → ~/wt/nixos-configs/nixos-configs-abc (branch: bead/nixos-configs-abc)
|
||||||
|
- nixos-configs-xyz → ~/wt/nixos-configs/nixos-configs-xyz (branch: bead/nixos-configs-xyz)
|
||||||
|
|
||||||
|
Skipped (existing worktree):
|
||||||
|
- nixos-configs-123 → Ask user for resolution
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: If a worktree or branch already exists, ask the user before proceeding:
|
||||||
|
- Remove existing worktree and branch, then recreate
|
||||||
|
- Skip this bead
|
||||||
|
- Use existing worktree as-is (risky - branch may have diverged)
|
||||||
|
|
||||||
|
## Phase 3: Parallel Implementation
|
||||||
|
|
||||||
For each selected bead, launch a subagent using the Task tool. All subagents should be launched in parallel (single message with multiple Task tool calls).
|
For each selected bead, launch a subagent using the Task tool. All subagents should be launched in parallel (single message with multiple Task tool calls).
|
||||||
|
|
||||||
@@ -53,16 +92,43 @@ Each implementation subagent should receive these instructions:
|
|||||||
```
|
```
|
||||||
Work on bead [BEAD_ID]: [BEAD_TITLE]
|
Work on bead [BEAD_ID]: [BEAD_TITLE]
|
||||||
|
|
||||||
1. **Create worktree**:
|
Worktree path: [WORKTREE_PATH]
|
||||||
- Branch name: `bead/[BEAD_ID]`
|
|
||||||
- Worktree path: `~/wt/[REPO_NAME]/[BEAD_ID]`
|
|
||||||
- Command: `git worktree add -b bead/[BEAD_ID] ~/wt/[REPO_NAME]/[BEAD_ID]`
|
|
||||||
|
|
||||||
2. **Review the bead requirements**:
|
## CRITICAL: Branch Verification (MUST DO FIRST)
|
||||||
|
|
||||||
|
1. **Navigate to worktree**:
|
||||||
|
```bash
|
||||||
|
cd [WORKTREE_PATH]
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verify branch** (MANDATORY before ANY modifications):
|
||||||
|
```bash
|
||||||
|
CURRENT_BRANCH=$(git branch --show-current)
|
||||||
|
echo "Current branch: $CURRENT_BRANCH"
|
||||||
|
pwd
|
||||||
|
```
|
||||||
|
|
||||||
|
**ABORT CONDITIONS** - If ANY of these are true, STOP IMMEDIATELY:
|
||||||
|
- Branch is `main` or `master`
|
||||||
|
- Branch does not match `bead/[BEAD_ID]`
|
||||||
|
|
||||||
|
If you detect any abort condition:
|
||||||
|
```
|
||||||
|
ABORTING: Branch verification failed.
|
||||||
|
Expected branch: bead/[BEAD_ID]
|
||||||
|
Actual branch: [CURRENT_BRANCH]
|
||||||
|
Working directory: [pwd output]
|
||||||
|
|
||||||
|
DO NOT PROCEED. Report this error to the orchestrator.
|
||||||
|
```
|
||||||
|
|
||||||
|
## After Verification Passes
|
||||||
|
|
||||||
|
3. **Review the bead requirements**:
|
||||||
- Run `bd show [BEAD_ID]` to understand the acceptance criteria
|
- Run `bd show [BEAD_ID]` to understand the acceptance criteria
|
||||||
- Note any external issue references (GitHub issues, Linear tickets, etc.)
|
- Note any external issue references (GitHub issues, Linear tickets, etc.)
|
||||||
|
|
||||||
3. **Extract validation criteria**:
|
4. **Extract validation criteria**:
|
||||||
- Check for a plan: `thoughts/beads-[BEAD_ID]/plan.md`
|
- Check for a plan: `thoughts/beads-[BEAD_ID]/plan.md`
|
||||||
- If plan exists:
|
- If plan exists:
|
||||||
- Read the plan and find the "Automated Verification" section
|
- Read the plan and find the "Automated Verification" section
|
||||||
@@ -74,12 +140,12 @@ Work on bead [BEAD_ID]: [BEAD_TITLE]
|
|||||||
- Check if `package.json` exists → try `npm test`
|
- Check if `package.json` exists → try `npm test`
|
||||||
- If none found, note "No validation criteria found"
|
- If none found, note "No validation criteria found"
|
||||||
|
|
||||||
4. **Implement the changes**:
|
5. **Implement the changes**:
|
||||||
- Work in the worktree directory
|
- Work in the worktree directory
|
||||||
- Complete all acceptance criteria listed in the bead
|
- Complete all acceptance criteria listed in the bead
|
||||||
|
|
||||||
After implementation, run validation:
|
After implementation, run validation:
|
||||||
- Execute each validation command from step 3
|
- Execute each validation command from step 4
|
||||||
- Track results in this format:
|
- Track results in this format:
|
||||||
```
|
```
|
||||||
VALIDATION_RESULTS:
|
VALIDATION_RESULTS:
|
||||||
@@ -91,12 +157,12 @@ Work on bead [BEAD_ID]: [BEAD_TITLE]
|
|||||||
- Continue with PR creation (don't block)
|
- Continue with PR creation (don't block)
|
||||||
- Document failures in bead notes: `bd update [BEAD_ID] --notes="Validation failures: [list]"`
|
- Document failures in bead notes: `bd update [BEAD_ID] --notes="Validation failures: [list]"`
|
||||||
|
|
||||||
5. **Commit and push**:
|
6. **Commit and push**:
|
||||||
- Stage all changes: `git add -A`
|
- Stage all changes: `git add -A`
|
||||||
- Create a descriptive commit message
|
- Create a descriptive commit message
|
||||||
- Push the branch: `git push -u origin bead/[BEAD_ID]`
|
- Push the branch: `git push -u origin bead/[BEAD_ID]`
|
||||||
|
|
||||||
6. **Create a PR**:
|
7. **Create a PR**:
|
||||||
- Detect hosting provider from origin URL: `git remote get-url origin`
|
- Detect hosting provider from origin URL: `git remote get-url origin`
|
||||||
- If URL contains `github.com`, use `gh`; otherwise use `tea` (Gitea/Forgejo)
|
- If URL contains `github.com`, use `gh`; otherwise use `tea` (Gitea/Forgejo)
|
||||||
- PR title: "[BEAD_ID] [BEAD_TITLE]"
|
- PR title: "[BEAD_ID] [BEAD_TITLE]"
|
||||||
@@ -156,13 +222,13 @@ Work on bead [BEAD_ID]: [BEAD_TITLE]
|
|||||||
| nix flake check | SKIP | command not found |"
|
| nix flake check | SKIP | command not found |"
|
||||||
```
|
```
|
||||||
|
|
||||||
7. **Update bead status**:
|
8. **Update bead status**:
|
||||||
- Mark the bead as "in_review": `bd update [BEAD_ID] --status=in_review`
|
- Mark the bead as "in_review": `bd update [BEAD_ID] --status=in_review`
|
||||||
- Add the PR URL to the bead notes: `bd update [BEAD_ID] --notes="$(bd show [BEAD_ID] --json | jq -r '.notes')
|
- Add the PR URL to the bead notes: `bd update [BEAD_ID] --notes="$(bd show [BEAD_ID] --json | jq -r '.notes')
|
||||||
|
|
||||||
PR: [PR_URL]"`
|
PR: [PR_URL]"`
|
||||||
|
|
||||||
8. **Report results**:
|
9. **Report results**:
|
||||||
- Return:
|
- Return:
|
||||||
- PR URL
|
- PR URL
|
||||||
- Bead ID
|
- Bead ID
|
||||||
@@ -175,15 +241,24 @@ PR: [PR_URL]"`
|
|||||||
|
|
||||||
### Launching Subagents
|
### Launching Subagents
|
||||||
|
|
||||||
|
For each bead, substitute into the template:
|
||||||
|
- `[BEAD_ID]` - the bead ID
|
||||||
|
- `[BEAD_TITLE]` - the bead title
|
||||||
|
- `[WORKTREE_PATH]` - the worktree path created in Phase 2
|
||||||
|
|
||||||
Use `subagent_type: "general-purpose"` for implementation subagents. Launch all selected beads' subagents in a single message for parallel execution:
|
Use `subagent_type: "general-purpose"` for implementation subagents. Launch all selected beads' subagents in a single message for parallel execution:
|
||||||
|
|
||||||
```
|
```
|
||||||
<Task calls for each selected bead - all in one message>
|
<Task calls for each selected bead - all in one message>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Important**: The worktree paths were created in Phase 2. Use the exact paths that were created, e.g.:
|
||||||
|
- `~/wt/nixos-configs/nixos-configs-abc`
|
||||||
|
- `~/wt/nixos-configs/nixos-configs-xyz`
|
||||||
|
|
||||||
Collect results from all subagents before proceeding.
|
Collect results from all subagents before proceeding.
|
||||||
|
|
||||||
## Phase 3: Parallel Review
|
## Phase 4: Parallel Review
|
||||||
|
|
||||||
After all implementation subagents complete, launch review subagents for each PR.
|
After all implementation subagents complete, launch review subagents for each PR.
|
||||||
|
|
||||||
@@ -218,7 +293,7 @@ Review PR for bead [BEAD_ID]
|
|||||||
|
|
||||||
Launch all review subagents in parallel.
|
Launch all review subagents in parallel.
|
||||||
|
|
||||||
## Phase 4: Cleanup and Summary
|
## Phase 5: Cleanup and Summary
|
||||||
|
|
||||||
After reviews complete:
|
After reviews complete:
|
||||||
|
|
||||||
@@ -264,9 +339,21 @@ Example output:
|
|||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
|
- **Worktree creation failures** (Phase 2):
|
||||||
|
- If `git worktree add` fails (branch exists, path exists), prompt user:
|
||||||
|
- Remove existing and retry
|
||||||
|
- Skip this bead
|
||||||
|
- Use existing (with warning about potential divergence)
|
||||||
|
- Do NOT proceed to subagent launch until worktree is confirmed
|
||||||
|
|
||||||
|
- **Branch verification failures** (subagent reports):
|
||||||
|
- If subagent reports it's on `main` or `master`, do NOT retry
|
||||||
|
- Mark bead as failed with reason "Branch verification failed"
|
||||||
|
- Continue with other beads but flag this as a critical issue
|
||||||
|
- Investigation required: the worktree may have been corrupted or not created properly
|
||||||
|
|
||||||
- **Subagent failures**: If a subagent fails or times out, note it in the summary but continue with other beads
|
- **Subagent failures**: If a subagent fails or times out, note it in the summary but continue with other beads
|
||||||
- **PR creation failures**: Report the error but continue with reviews of successful PRs
|
- **PR creation failures**: Report the error but continue with reviews of successful PRs
|
||||||
- **Worktree conflicts**: If a worktree already exists, ask the user if they want to remove it or skip that bead
|
|
||||||
|
|
||||||
## Resource Limits
|
## Resource Limits
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
# Edit this configuration file to define what should be installed on
|
|
||||||
# your system. Help is available in the configuration.nix(5) man page, on
|
|
||||||
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
|
||||||
|
|
||||||
# NixOS-WSL specific options are documented on the NixOS-WSL repository:
|
|
||||||
# https://github.com/nix-community/NixOS-WSL
|
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
];
|
|
||||||
|
|
||||||
roles = {
|
|
||||||
audio.enable = true;
|
|
||||||
desktop = {
|
|
||||||
enable = true;
|
|
||||||
wayland = true;
|
|
||||||
};
|
|
||||||
nvidia = {
|
|
||||||
enable = true;
|
|
||||||
package = "latest";
|
|
||||||
graphics.extraPackages = with pkgs; [
|
|
||||||
mesa
|
|
||||||
libvdpau-va-gl
|
|
||||||
libva-vdpau-driver
|
|
||||||
];
|
|
||||||
};
|
|
||||||
users.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.hostName = "wixos";
|
|
||||||
|
|
||||||
wsl.enable = true;
|
|
||||||
wsl.defaultUser = "johno";
|
|
||||||
wsl.startMenuLaunchers = true;
|
|
||||||
wsl.useWindowsDriver = true;
|
|
||||||
wsl.wslConf.network.hostname = "wixos";
|
|
||||||
wsl.wslConf.user.default = "johno";
|
|
||||||
|
|
||||||
# WSL-specific environment variables for graphics
|
|
||||||
environment.sessionVariables = {
|
|
||||||
LD_LIBRARY_PATH = [
|
|
||||||
"/usr/lib/wsl/lib"
|
|
||||||
"/run/opengl-driver/lib"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# This value determines the NixOS release from which the default
|
|
||||||
# settings for stateful data, like file locations and database versions
|
|
||||||
# on your system were taken. It's perfectly fine and recommended to leave
|
|
||||||
# this value at the release version of the first install of this system.
|
|
||||||
# Before changing this value read the documentation for this option
|
|
||||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
|
||||||
system.stateVersion = "24.05"; # Did you read the comment?
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
git
|
git
|
||||||
glances
|
glances
|
||||||
|
ghostty.terminfo # So tmux works when SSH'ing from ghostty
|
||||||
pciutils
|
pciutils
|
||||||
tree
|
tree
|
||||||
usbutils
|
usbutils
|
||||||
|
|||||||
Reference in New Issue
Block a user