pi-orchestrator-config 4.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +808 -0
- package/agents/api-documenter.md +32 -0
- package/agents/bash-expert.md +53 -0
- package/agents/code-reviewer-docs.md +145 -0
- package/agents/code-reviewer-guidelines.md +97 -0
- package/agents/code-reviewer-quality.md +142 -0
- package/agents/code-reviewer-security.md +107 -0
- package/agents/code-reviewer-spec.md +164 -0
- package/agents/debugger.md +63 -0
- package/agents/docker-expert.md +40 -0
- package/agents/docs-fetcher.md +48 -0
- package/agents/git-expert.md +63 -0
- package/agents/github-expert.md +83 -0
- package/agents/go-expert.md +62 -0
- package/agents/issue-reviewer-feasibility.md +60 -0
- package/agents/issue-reviewer-scope.md +63 -0
- package/agents/issue-reviewer-spec.md +77 -0
- package/agents/java-expert.md +31 -0
- package/agents/jenkins-expert.md +38 -0
- package/agents/kubernetes-expert.md +40 -0
- package/agents/planner.md +42 -0
- package/agents/python-expert.md +61 -0
- package/agents/reviewer.md +26 -0
- package/agents/scout.md +40 -0
- package/agents/security-auditor.md +254 -0
- package/agents/technical-documentation-writer.md +37 -0
- package/agents/test-automator.md +55 -0
- package/agents/test-runner.md +47 -0
- package/agents/ts-expert.md +23 -0
- package/agents/worker.md +30 -0
- package/extensions/acpx-provider/index.ts +104 -0
- package/extensions/acpx-provider/load-runtime.ts +99 -0
- package/extensions/acpx-provider/runtime-models.ts +40 -0
- package/extensions/cli-provider/agents/claude.ts +128 -0
- package/extensions/cli-provider/agents/cursor.ts +84 -0
- package/extensions/cli-provider/agents/gemini.ts +100 -0
- package/extensions/cli-provider/discover.ts +77 -0
- package/extensions/cli-provider/index.ts +57 -0
- package/extensions/cli-provider/parsers.ts +304 -0
- package/extensions/cli-provider/providers.ts +58 -0
- package/extensions/cli-provider/runner.ts +225 -0
- package/extensions/cli-provider/runtime-models.ts +32 -0
- package/extensions/cli-provider/session-reaper.ts +122 -0
- package/extensions/cli-provider/sessions.ts +533 -0
- package/extensions/cli-provider/shared/discover-cache.ts +235 -0
- package/extensions/cli-provider/types.ts +48 -0
- package/extensions/coms/coms-net-server.ts +1642 -0
- package/extensions/coms/coms-net-wrapper.ts +521 -0
- package/extensions/coms/coms-net.ts +1589 -0
- package/extensions/coms/coms-p2p.ts +1879 -0
- package/extensions/coms/coms-shared.ts +510 -0
- package/extensions/coms/coms-wrapper.ts +138 -0
- package/extensions/coms/index.ts +20 -0
- package/extensions/coms/themeMap.ts +147 -0
- package/extensions/image-gen/image-gen.ts +332 -0
- package/extensions/image-gen/index.ts +14 -0
- package/extensions/orchestrator/agents.ts +134 -0
- package/extensions/orchestrator/ask-user.ts +293 -0
- package/extensions/orchestrator/async-agents.ts +1037 -0
- package/extensions/orchestrator/async-capability.ts +129 -0
- package/extensions/orchestrator/async-runner.ts +324 -0
- package/extensions/orchestrator/async-status-parse.ts +31 -0
- package/extensions/orchestrator/async-status-ui.ts +201 -0
- package/extensions/orchestrator/async-wait.ts +36 -0
- package/extensions/orchestrator/btw.ts +210 -0
- package/extensions/orchestrator/cron-status-format.ts +126 -0
- package/extensions/orchestrator/cron-status-ui.ts +132 -0
- package/extensions/orchestrator/cron.ts +730 -0
- package/extensions/orchestrator/dreaming.ts +355 -0
- package/extensions/orchestrator/enforcement-helpers.ts +530 -0
- package/extensions/orchestrator/enforcement-rules.ts +329 -0
- package/extensions/orchestrator/enforcement.ts +828 -0
- package/extensions/orchestrator/extended-autocomplete.ts +593 -0
- package/extensions/orchestrator/git-helpers.ts +420 -0
- package/extensions/orchestrator/github-autocomplete.ts +250 -0
- package/extensions/orchestrator/icons.ts +17 -0
- package/extensions/orchestrator/index.ts +100 -0
- package/extensions/orchestrator/memory-embeddings.ts +281 -0
- package/extensions/orchestrator/memory-promotion.ts +449 -0
- package/extensions/orchestrator/memory-provenance.ts +80 -0
- package/extensions/orchestrator/memory-query-class.ts +90 -0
- package/extensions/orchestrator/memory-scoring.ts +434 -0
- package/extensions/orchestrator/memory-tools.ts +883 -0
- package/extensions/orchestrator/memory-tree.ts +212 -0
- package/extensions/orchestrator/nvim.ts +169 -0
- package/extensions/orchestrator/overlay-dashboard-utils.ts +25 -0
- package/extensions/orchestrator/overlay-dashboard.ts +512 -0
- package/extensions/orchestrator/pi-config-review-state.ts +303 -0
- package/extensions/orchestrator/preference-extractor.ts +106 -0
- package/extensions/orchestrator/project-settings.ts +468 -0
- package/extensions/orchestrator/promotion-queue.ts +311 -0
- package/extensions/orchestrator/resolve-agent-model.ts +32 -0
- package/extensions/orchestrator/review-ui.ts +204 -0
- package/extensions/orchestrator/rule-placeholders.ts +12 -0
- package/extensions/orchestrator/rules.ts +481 -0
- package/extensions/orchestrator/session-search.ts +243 -0
- package/extensions/orchestrator/session-validation.ts +374 -0
- package/extensions/orchestrator/situation-report.ts +370 -0
- package/extensions/orchestrator/status-bar.ts +31 -0
- package/extensions/orchestrator/status-line.ts +192 -0
- package/extensions/orchestrator/status.ts +110 -0
- package/extensions/orchestrator/subagent-tool.ts +1748 -0
- package/extensions/orchestrator/task-lifecycle.ts +88 -0
- package/extensions/orchestrator/utils.ts +227 -0
- package/extensions/pidash/index.ts +15 -0
- package/extensions/pidash/pidash.ts +941 -0
- package/extensions/pidiff/index.ts +13 -0
- package/extensions/pidiff/pidiff.ts +369 -0
- package/extensions/providers/acpx-driver.ts +479 -0
- package/extensions/providers/built-in-drivers.ts +52 -0
- package/extensions/providers/claude-driver.ts +319 -0
- package/extensions/providers/cursor-acpx-driver.ts +398 -0
- package/extensions/providers/cursor-cli-driver.ts +484 -0
- package/extensions/providers/gemini-driver.ts +302 -0
- package/extensions/providers/index.ts +513 -0
- package/extensions/shared/build-system-prompt.ts +57 -0
- package/extensions/shared/create-runtime-provider.ts +190 -0
- package/extensions/shared/daemon-manager.ts +248 -0
- package/extensions/shared/file-logger.ts +115 -0
- package/extensions/shared/managed-refresh.ts +211 -0
- package/extensions/shared/provider-driver.ts +295 -0
- package/extensions/shared/provider-errors.ts +305 -0
- package/extensions/shared/provider-registry.ts +388 -0
- package/extensions/shared/stream-builder.ts +275 -0
- package/extensions/shared/types.ts +20 -0
- package/extensions/shared/ui/README.md +10 -0
- package/extensions/shared/ui/badge.tsx +52 -0
- package/extensions/shared/ui/button.tsx +58 -0
- package/extensions/shared/ui/collapsible.tsx +21 -0
- package/extensions/shared/ui/dropdown-menu.tsx +266 -0
- package/extensions/shared/ui/input.tsx +20 -0
- package/extensions/shared/ui/popover.tsx +114 -0
- package/extensions/shared/ui/resizable.tsx +48 -0
- package/extensions/shared/ui/scroll-area.tsx +53 -0
- package/extensions/shared/ui/select.tsx +201 -0
- package/extensions/shared/ui/separator.tsx +25 -0
- package/extensions/shared/ui/tooltip.tsx +64 -0
- package/extensions/shared/ws-client.ts +74 -0
- package/package.json +59 -0
- package/prompts/coderabbit-rate-limit.md +95 -0
- package/prompts/create-coms-feature-manager.md +186 -0
- package/prompts/create-skill.md +128 -0
- package/prompts/domain-model.md +109 -0
- package/prompts/external-ai.md +665 -0
- package/prompts/implement-and-review.md +25 -0
- package/prompts/implement.md +26 -0
- package/prompts/issue-review.md +256 -0
- package/prompts/pr-review.md +753 -0
- package/prompts/query-db.md +154 -0
- package/prompts/refine-review.md +208 -0
- package/prompts/release.md +235 -0
- package/prompts/remember.md +33 -0
- package/prompts/review-handler-status.md +27 -0
- package/prompts/review-handler.md +677 -0
- package/prompts/review-local.md +159 -0
- package/prompts/scout-and-plan.md +21 -0
- package/rules/00-orchestrator-core.md +42 -0
- package/rules/05-issue-first-workflow.md +119 -0
- package/rules/10-agent-routing.md +58 -0
- package/rules/15-mcp-launchpad.md +46 -0
- package/rules/20-code-review-loop.md +234 -0
- package/rules/25-documentation-updates.md +15 -0
- package/rules/30-prompt-templates.md +19 -0
- package/rules/35-memory.md +240 -0
- package/rules/40-critical-rules.md +124 -0
- package/rules/45-file-preview.md +29 -0
- package/rules/50-agent-bug-reporting.md +90 -0
- package/rules/55-coms-protocol.md +63 -0
- package/rules/60-task-tracking.md +66 -0
- package/skills/conflict-resolver/SKILL.md +213 -0
- package/skills/skill-creator/SKILL.md +85 -0
- package/skills/systematic-debugging/SKILL.md +353 -0
- package/skills/test-driven-development/SKILL.md +335 -0
- package/skills/update-agents-md/SKILL.md +282 -0
- package/templates/coms-feature-manager-prompt.md +313 -0
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Review a GitHub PR and post inline comments on selected findings
|
|
3
|
+
argument-hint: "[PR number or URL]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Raw Arguments
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
$ARGUMENTS
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
# GitHub PR Review Command
|
|
13
|
+
|
|
14
|
+
> **Bug Reporting Policy:** If you encounter ANY error, unexpected behavior, or reproducible bug
|
|
15
|
+
> while executing this command — DO NOT work around it silently. Ask the user:
|
|
16
|
+
> "Should I create a GitHub issue for this?" Route to:
|
|
17
|
+
> `myk-org/pi-config` for plugin/command spec or `myk-pi-tools` CLI issues.
|
|
18
|
+
> Do not silently skip steps or apply manual fixes that hide the root cause.
|
|
19
|
+
|
|
20
|
+
Reviews a GitHub PR and posts inline review comments on selected findings.
|
|
21
|
+
|
|
22
|
+
## Prerequisites Check (MANDATORY)
|
|
23
|
+
|
|
24
|
+
Before starting, verify the tools are available:
|
|
25
|
+
|
|
26
|
+
### Step 0: Check uv
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
uv --version
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If not found, install from <https://docs.astral.sh/uv/getting-started/installation/>
|
|
33
|
+
|
|
34
|
+
### Step 1: Check myk-pi-tools
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
myk-pi-tools --version
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If not found, prompt user: "myk-pi-tools is required. Install with: `uv tool install myk-pi-tools`. Install now?"
|
|
41
|
+
|
|
42
|
+
- Yes: Run `uv tool install myk-pi-tools`
|
|
43
|
+
- No: Abort with instructions
|
|
44
|
+
|
|
45
|
+
### Step 2: Continue with workflow
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
- `/pr-review` - Review PR from current branch (auto-detect)
|
|
50
|
+
- `/pr-review 123` - Review PR #123 in current repo
|
|
51
|
+
- `/pr-review https://github.com/owner/repo/pull/123` - Review from URL
|
|
52
|
+
|
|
53
|
+
## Task Plan
|
|
54
|
+
|
|
55
|
+
Before starting any work, create ALL tasks upfront using `TaskCreate`, then set their dependencies
|
|
56
|
+
using `TaskUpdate` with `addBlockedBy`. The task system enforces execution order — blocked tasks cannot start.
|
|
57
|
+
|
|
58
|
+
### Task List
|
|
59
|
+
|
|
60
|
+
| Task | Title | blockedBy |
|
|
61
|
+
|------|-------|-----------|
|
|
62
|
+
| 1 | PR Detection | — |
|
|
63
|
+
| 2 | Clone & checkout PR | 1 |
|
|
64
|
+
| 3 | (auto-complete — reviewers read from clone) | 1 |
|
|
65
|
+
| 4 | Check past review comments | 1, 2 |
|
|
66
|
+
| 5 | Review — Code Quality | 2 |
|
|
67
|
+
| 6 | Review — Guidelines | 2 |
|
|
68
|
+
| 7 | Review — Security | 2 |
|
|
69
|
+
| 8 | Review — Docs | 2 |
|
|
70
|
+
| 9 | Review — Spec | 2 |
|
|
71
|
+
| 10 | Merge & deduplicate findings | 4, 5, 6, 7, 8, 9 |
|
|
72
|
+
| 11 | User selection | 10 |
|
|
73
|
+
| 12 | Post comments | 11 |
|
|
74
|
+
| 13 | Store comments | 12 |
|
|
75
|
+
| 14 | Summary | 13 |
|
|
76
|
+
|
|
77
|
+
### Dependency Graph
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
Task 1 (PR Detection)
|
|
81
|
+
├── Task 2 (Clone & checkout PR) ────┐
|
|
82
|
+
│ Task 3 auto-completes instantly │
|
|
83
|
+
│ Task 2 unblocks: │
|
|
84
|
+
│ ├── Task 5 (Review: Quality) │
|
|
85
|
+
│ ├── Task 6 (Review: Guidelines) │
|
|
86
|
+
│ ├── Task 7 (Review: Security) │
|
|
87
|
+
│ ├── Task 8 (Review: Docs) │
|
|
88
|
+
│ └── Task 9 (Review: Spec) │
|
|
89
|
+
└── Task 4 (Past comments) ──────────┤ (also needs Task 2)
|
|
90
|
+
▼
|
|
91
|
+
Task 10 (Merge findings)
|
|
92
|
+
│
|
|
93
|
+
Task 11 (User selection)
|
|
94
|
+
│
|
|
95
|
+
Task 12 (Post comments)
|
|
96
|
+
│
|
|
97
|
+
Task 13 (Store comments)
|
|
98
|
+
│
|
|
99
|
+
Task 14 (Summary)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Create all 14 tasks using `TaskCreate` NOW, before starting any work.
|
|
103
|
+
Then IMMEDIATELY set dependencies using `TaskUpdate` with `addBlockedBy` for each task per the table above.
|
|
104
|
+
|
|
105
|
+
`TaskCreate` does NOT accept `addBlockedBy` — dependencies MUST be set via `TaskUpdate` after creation.
|
|
106
|
+
|
|
107
|
+
Example two-step flow:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
# Step 1: Create all tasks
|
|
111
|
+
TaskCreate(subject="PR Detection", ...) → Task 1
|
|
112
|
+
TaskCreate(subject="Fetch PR diff", ...) → Task 2
|
|
113
|
+
TaskCreate(subject="Fetch AGENTS.md", ...) → Task 3
|
|
114
|
+
TaskCreate(subject="Review — Docs", ...) → Task 8
|
|
115
|
+
TaskCreate(subject="Review — Spec", ...) → Task 9
|
|
116
|
+
...all 14 tasks...
|
|
117
|
+
|
|
118
|
+
# Step 2: Set dependencies
|
|
119
|
+
TaskUpdate(taskId="2", addBlockedBy=["1"])
|
|
120
|
+
TaskUpdate(taskId="3", addBlockedBy=["1"])
|
|
121
|
+
TaskUpdate(taskId="4", addBlockedBy=["1", "2"])
|
|
122
|
+
TaskUpdate(taskId="5", addBlockedBy=["2"])
|
|
123
|
+
TaskUpdate(taskId="6", addBlockedBy=["2"])
|
|
124
|
+
TaskUpdate(taskId="7", addBlockedBy=["2"])
|
|
125
|
+
TaskUpdate(taskId="8", addBlockedBy=["2"])
|
|
126
|
+
TaskUpdate(taskId="9", addBlockedBy=["2"])
|
|
127
|
+
TaskUpdate(taskId="10", addBlockedBy=["4", "5", "6", "7", "8", "9"])
|
|
128
|
+
TaskUpdate(taskId="11", addBlockedBy=["10"])
|
|
129
|
+
TaskUpdate(taskId="12", addBlockedBy=["11"])
|
|
130
|
+
TaskUpdate(taskId="13", addBlockedBy=["12"])
|
|
131
|
+
TaskUpdate(taskId="14", addBlockedBy=["13"])
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
> 🚨 **HARD RULE: NEVER start a task while its `blockedBy` tasks are incomplete.**
|
|
135
|
+
> The task system enforces this via `addBlockedBy` — but even if you could bypass it, **DON'T**.
|
|
136
|
+
> Posting comments from partial reviewer results is a **CRITICAL violation**.
|
|
137
|
+
> ALL 5 reviewers (Tasks 5, 6, 7, 8, 9) MUST complete before merging findings (Task 10).
|
|
138
|
+
|
|
139
|
+
## Workflow
|
|
140
|
+
|
|
141
|
+
**PROJECT_TMP_DIR** is the project-scoped temp directory from `getProjectTmpDir(cwd)`.
|
|
142
|
+
All temp files for this workflow go there —
|
|
143
|
+
|
|
144
|
+
### Phase 0: PR Detection — Task 1
|
|
145
|
+
|
|
146
|
+
If the raw arguments are empty:
|
|
147
|
+
|
|
148
|
+
1. Detect from current branch and fetch PR metadata:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
myk-pi-tools pr info $(gh pr view --json number --jq '.number')
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This returns JSON with all needed fields: `owner`, `repo`, `pr_number`, `author`,
|
|
155
|
+
`head_sha`, `base_ref`, `title`, `state`, `labels`, `assignees`, `is_fork`, `head_repo`, `body`.
|
|
156
|
+
|
|
157
|
+
2. Extract and store all fields from the JSON output — these are used by Phase 1c and Phase 5.
|
|
158
|
+
|
|
159
|
+
3. Fetch the latest commit timestamp from `head_sha` (needed by Phase 1c to compare
|
|
160
|
+
against comment timestamps):
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
gh api /repos/{owner}/{repo}/commits/{head_sha} --jq '.commit.committer.date'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Always use the base repo (`{owner}/{repo}`) — GitHub resolves fork PR commits
|
|
167
|
+
from the base repo via `refs/pull/*/head`, so this works for both fork and non-fork PRs.
|
|
168
|
+
|
|
169
|
+
Store this as `LATEST_COMMIT_DATE` (ISO 8601 timestamp).
|
|
170
|
+
|
|
171
|
+
If the raw arguments contain a PR number or URL:
|
|
172
|
+
|
|
173
|
+
1. Fetch PR metadata using the CLI:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
myk-pi-tools pr info <cleaned_arguments>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
This returns JSON with all needed fields: `owner`, `repo`, `pr_number`, `author`,
|
|
180
|
+
`head_sha`, `base_ref`, `title`, `state`, `labels`, `assignees`, `is_fork`, `head_repo`, `body`.
|
|
181
|
+
|
|
182
|
+
2. Extract and store all fields from the JSON output — these are used by Phase 1c and Phase 5.
|
|
183
|
+
|
|
184
|
+
3. Fetch the latest commit timestamp from `head_sha` (needed by Phase 1c to compare
|
|
185
|
+
against comment timestamps):
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
gh api /repos/{owner}/{repo}/commits/{head_sha} --jq '.commit.committer.date'
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Always use the base repo (`{owner}/{repo}`) — GitHub resolves fork PR commits
|
|
192
|
+
from the base repo via `refs/pull/*/head`, so this works for both fork and non-fork PRs.
|
|
193
|
+
|
|
194
|
+
Store this as `LATEST_COMMIT_DATE` (ISO 8601 timestamp).
|
|
195
|
+
|
|
196
|
+
Tasks 2 and 3 are independent — execute them in parallel.
|
|
197
|
+
Task 4 depends on Task 2 (needs the diff data) and will start after Task 2 completes.
|
|
198
|
+
|
|
199
|
+
### Phase 1a: Clone & Checkout PR — Task 2
|
|
200
|
+
|
|
201
|
+
Clone the target repo and checkout the PR branch. This gives reviewers full repo access
|
|
202
|
+
instead of passing a truncated diff in the prompt.
|
|
203
|
+
|
|
204
|
+
**Delegate to `git-expert`** with this task:
|
|
205
|
+
|
|
206
|
+
> Clone `https://github.com/{owner}/{repo}.git` (depth 50) to `{PROJECT_TMP_DIR}/pr-review-{owner}-{repo}-{pr_number}`.
|
|
207
|
+
> Then run: gh pr checkout {pr_number}
|
|
208
|
+
> Then get the base branch: gh pr view {pr_number} --json baseRefName --jq '.baseRefName'
|
|
209
|
+
> Then fetch the base: git fetch origin {base_branch} --depth 50
|
|
210
|
+
> Report REVIEW_DIR and BASE_BRANCH.
|
|
211
|
+
|
|
212
|
+
Store:
|
|
213
|
+
|
|
214
|
+
- `REVIEW_DIR` — the clone path (used as `cwd` for reviewers)
|
|
215
|
+
- `BASE_BRANCH` — the PR's target branch (used for `git diff`)
|
|
216
|
+
|
|
217
|
+
If cloning or checkout fails, fall back to `myk-pi-tools pr diff` (original behavior).
|
|
218
|
+
|
|
219
|
+
### Phase 1b: (Removed — reviewers read AGENTS.md from clone)
|
|
220
|
+
|
|
221
|
+
Task 3 is no longer needed — reviewers have full repo access via the clone
|
|
222
|
+
and read AGENTS.md independently per their agent instructions.
|
|
223
|
+
|
|
224
|
+
### Phase 1c: Check Past Review Comments — Task 4
|
|
225
|
+
|
|
226
|
+
Fetch ALL human review threads (resolved + unresolved) from the PR:
|
|
227
|
+
|
|
228
|
+
Use the `owner`, `repo`, and `pr_number` from Phase 0 to construct the PR URL:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
myk-pi-tools reviews fetch --output-dir ${PROJECT_TMP_DIR} --user {current_github_user} --include-resolved https://github.com/{owner}/{repo}/pull/{pr_number}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Where `{current_github_user}` is obtained from:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
gh api user --jq '.login'
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Also fetch ALL unresolved review threads from all authors (for dedup in Phase 2):
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
myk-pi-tools reviews fetch --output-dir ${PROJECT_TMP_DIR}/all-unresolved https://github.com/{owner}/{repo}/pull/{pr_number}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
This second call omits `--user` and `--include-resolved`, so it returns only currently-unresolved
|
|
247
|
+
threads from every author (humans, Qodo, CodeRabbit, etc.). The output is passed to
|
|
248
|
+
reviewers in Phase 2 so they can avoid raising duplicate findings.
|
|
249
|
+
|
|
250
|
+
Parse the JSON output from the `--user` fetch (`${PROJECT_TMP_DIR}`). This file is used
|
|
251
|
+
for resolved/unresolved categorization below. The all-unresolved fetch (`${PROJECT_TMP_DIR}/all-unresolved`)
|
|
252
|
+
is used separately in Phase 2 for dedup context — do NOT use it for the resolved/unresolved
|
|
253
|
+
categorization above. However, it IS used later in this same phase for `[AUTHOR-QUESTION]`
|
|
254
|
+
detection (see "Detect questions directed at us" section below).
|
|
255
|
+
|
|
256
|
+
For the `human` list, categorize each thread:
|
|
257
|
+
|
|
258
|
+
**Unresolved threads:**
|
|
259
|
+
|
|
260
|
+
- These are still open on GitHub — but the PR author may have fixed the code without resolving the thread.
|
|
261
|
+
- Check the diff from Phase 1a — did the code at `path:line` change?
|
|
262
|
+
- **Code changed:** Review the changed code to verify the fix is correct.
|
|
263
|
+
- Fix looks correct → resolve the thread on GitHub by setting its status to `addressed`
|
|
264
|
+
with reply "Verified fix in code — resolving." in the JSON, then mark as
|
|
265
|
+
"✅ Fixed but not resolved by author — resolved by us". Store verdict to DB as `resolved_fixed`.
|
|
266
|
+
- Fix looks wrong/incomplete → include in findings as "❌ Code changed but fix is incorrect".
|
|
267
|
+
Store verdict to DB as `resolved_bad_fix`.
|
|
268
|
+
- **Code NOT changed:** The finding may be genuinely unaddressed — but only re-raise
|
|
269
|
+
if the PR author has pushed new commits since the comment was posted.
|
|
270
|
+
- Compare the comment's `created_at` timestamp against `LATEST_COMMIT_DATE` from Phase 0.
|
|
271
|
+
- **New commits exist after comment** (`LATEST_COMMIT_DATE` > comment `created_at`):
|
|
272
|
+
The author pushed changes but didn't address this finding.
|
|
273
|
+
Include in the findings presented to the user in Phase 4.
|
|
274
|
+
Mark as "⚠️ UNRESOLVED from previous review"
|
|
275
|
+
- **No new commits after comment** (`LATEST_COMMIT_DATE` ≤ comment `created_at`):
|
|
276
|
+
The comment is already visible on the PR and the author hasn't pushed any changes yet.
|
|
277
|
+
Silently skip — do NOT include in findings or auto-post.
|
|
278
|
+
This avoids replying to our own still-visible unresolved thread with no new information.
|
|
279
|
+
|
|
280
|
+
**Resolved threads:**
|
|
281
|
+
|
|
282
|
+
- Read the full thread including ALL replies from the PR author.
|
|
283
|
+
- Check the diff from Phase 1a — did the code at `path:line` change?
|
|
284
|
+
- **Code changed:** Review the changed code to verify the fix is correct. Don't trust blindly.
|
|
285
|
+
- Fix looks correct → mark as "✅ Resolved — fix verified"
|
|
286
|
+
- Fix looks wrong/incomplete → include in findings as "❌ Resolved but fix is incorrect"
|
|
287
|
+
- **Code NOT changed:** Read the PR author's response/reply.
|
|
288
|
+
- Valid response (by design, wrong assumption, clarification) → mark as "✅ Resolved — response accepted"
|
|
289
|
+
- Invalid/missing response → include in findings as "❌ Resolved without code change or valid response"
|
|
290
|
+
|
|
291
|
+
**Store resolution verdicts to DB (MANDATORY):**
|
|
292
|
+
|
|
293
|
+
After evaluating each resolved thread, persist YOUR verdict to the PR review database.
|
|
294
|
+
For each resolved thread that was previously posted by us (matched in the `--user` fetch),
|
|
295
|
+
call:
|
|
296
|
+
|
|
297
|
+
To store the verdict, write the author's response to a temp file first (to avoid shell quoting issues),
|
|
298
|
+
then run the CLI:
|
|
299
|
+
|
|
300
|
+
1. Write `{author_response}` text to `${PROJECT_TMP_DIR}/resolution-response.txt` using the `write` tool
|
|
301
|
+
2. Run: `myk-pi-tools pr update-resolution {owner} {repo} {pr_number} --path {path} --line {line} --status {resolution_status} --response-file ${PROJECT_TMP_DIR}/resolution-response.txt`
|
|
302
|
+
|
|
303
|
+
Where:
|
|
304
|
+
|
|
305
|
+
- `{resolution_status}` is one of:
|
|
306
|
+
- `resolved_fixed` (code changed, fix verified)
|
|
307
|
+
- `resolved_accepted` (response accepted, no code change needed)
|
|
308
|
+
- `resolved_bad_fix` (code changed but fix is incorrect)
|
|
309
|
+
- `resolved_no_fix` (resolved without code change or valid response)
|
|
310
|
+
- `{author_response}` is the PR author's reply text (why they resolved/dismissed)
|
|
311
|
+
|
|
312
|
+
This persists resolution decisions to the DB so future review cycles can query them.
|
|
313
|
+
Resolution decisions are OURS (from this LLM evaluation), not the PR author's click.
|
|
314
|
+
|
|
315
|
+
**All past comment statuses are included in the combined findings in Phase 4 —
|
|
316
|
+
not presented as a separate summary.**
|
|
317
|
+
|
|
318
|
+
**Detect questions directed at us (MANDATORY):**
|
|
319
|
+
|
|
320
|
+
After processing our own threads above, scan for questions/comments from others that need
|
|
321
|
+
our attention. This covers two sources:
|
|
322
|
+
|
|
323
|
+
**Source 1 — Review thread questions:**
|
|
324
|
+
|
|
325
|
+
Scan the all-unresolved JSON from `${PROJECT_TMP_DIR}/all-unresolved/`. For each thread:
|
|
326
|
+
|
|
327
|
+
- Skip threads authored by us (already handled above)
|
|
328
|
+
- Skip threads from bots (Qodo, CodeRabbit, GitHub Actions, dependabot, etc.)
|
|
329
|
+
- Check if ANY comment in the thread **explicitly @mentions** the current user (`@{current_github_user}`)
|
|
330
|
+
|
|
331
|
+
For each matching @mention comment, include it as an `[AUTHOR-QUESTION]` finding **only if**
|
|
332
|
+
there is no subsequent comment authored by `{current_github_user}` after that mention.
|
|
333
|
+
Compare using the `created_at` field on reply objects (ISO timestamp) — a reply from us
|
|
334
|
+
with a `created_at` later than the @mention comment's `created_at` means we already
|
|
335
|
+
responded. Do NOT rely on array position alone — always compare `created_at` timestamps.
|
|
336
|
+
|
|
337
|
+
**Do NOT use loose heuristics** (e.g., "thread is on a file we changed") or thread-level
|
|
338
|
+
"no reply anywhere" checks. Only explicit @mentions with no subsequent reply from us qualify —
|
|
339
|
+
this prevents false positives from unrelated reviewer conversations and correctly handles
|
|
340
|
+
late @mentions in threads where we participated earlier.
|
|
341
|
+
|
|
342
|
+
**Source 2 — General PR issue comments:**
|
|
343
|
+
|
|
344
|
+
Fetch PR issue comments (standalone PR comments, not tied to code lines):
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
gh api /repos/{owner}/{repo}/issues/{pr_number}/comments --paginate
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
For each comment:
|
|
351
|
+
|
|
352
|
+
- Skip comments authored by us
|
|
353
|
+
- Skip bot comments (Qodo, CodeRabbit, GitHub Actions, dependabot, etc.)
|
|
354
|
+
- Check if the comment **explicitly @mentions** the current user (`@{current_github_user}`)
|
|
355
|
+
- Check we haven't responded — no comment from us with a `created_at` later than
|
|
356
|
+
the @mention comment's `created_at`. Use `created_at` only (not `updated_at`) —
|
|
357
|
+
edits for typos/formatting shift `updated_at` forward and would cause false positives
|
|
358
|
+
by making our earlier response appear to predate the mention.
|
|
359
|
+
|
|
360
|
+
If matched, include it as an `[AUTHOR-QUESTION]` finding.
|
|
361
|
+
|
|
362
|
+
**Only explicit @mentions qualify.** Do NOT match comments just because they contain a
|
|
363
|
+
question mark — this would produce false positives from conversations between other
|
|
364
|
+
collaborators. Store the original `comment_id` and `comment_url` (from the API's
|
|
365
|
+
`html_url` field) for use in Phase 5 reply formatting.
|
|
366
|
+
|
|
367
|
+
**For each `[AUTHOR-QUESTION]`, generate a suggested answer:**
|
|
368
|
+
|
|
369
|
+
Read the relevant code, diff, and surrounding context referenced by the question. Analyze
|
|
370
|
+
what the commenter is asking and draft a concise, technically accurate suggested answer.
|
|
371
|
+
Store the suggested answer alongside the finding for presentation in Phase 4.
|
|
372
|
+
|
|
373
|
+
The suggested answer should:
|
|
374
|
+
|
|
375
|
+
- Reference specific code/lines when applicable
|
|
376
|
+
- Be ready to post as-is (the user can approve it directly)
|
|
377
|
+
- Be concise — answer the question, don't lecture
|
|
378
|
+
- If the answer requires a code change, note that explicitly
|
|
379
|
+
|
|
380
|
+
### Phase 2: Code Analysis — Tasks 5, 6, 7, 8, 9
|
|
381
|
+
|
|
382
|
+
Spawn ALL 5 review agents as async subagents
|
|
383
|
+
with `taskId` linking each to its task:
|
|
384
|
+
|
|
385
|
+
Use the actual task IDs returned by `TaskCreate` — do NOT hardcode IDs.
|
|
386
|
+
|
|
387
|
+
Before spawning reviewers, read the all-unresolved JSON from `${PROJECT_TMP_DIR}/all-unresolved/`
|
|
388
|
+
(the output of the second `reviews fetch` call — NOT the `--user` fetch used in Phase 1c)
|
|
389
|
+
and format the existing comments as a block of context. Build an `EXISTING_COMMENTS` string
|
|
390
|
+
listing each unresolved thread with its file path, line number, author, and body.
|
|
391
|
+
|
|
392
|
+
> **Note:** Some comment types (e.g., Qodo sticky findings without code refs) may have an empty
|
|
393
|
+
> `path` or `null` line number. Use `"(no file)"` as fallback when path is missing and
|
|
394
|
+
> `"(no line)"` when line is missing or null.
|
|
395
|
+
|
|
396
|
+
Also build a `CODE_SUGGESTIONS` instruction block to include in each reviewer's task:
|
|
397
|
+
|
|
398
|
+
> When a finding has a concrete code fix, include a GitHub suggestion block showing the
|
|
399
|
+
> corrected code. Use the exact syntax so the PR author can apply it with one click:
|
|
400
|
+
>
|
|
401
|
+
> ````text
|
|
402
|
+
> ```suggestion
|
|
403
|
+
> fixed code here
|
|
404
|
+
> ```
|
|
405
|
+
> ````
|
|
406
|
+
>
|
|
407
|
+
> Only include suggestions for specific code replacements — not for architectural concerns,
|
|
408
|
+
> missing tests, new files, or design questions where the fix isn't a simple line replacement.
|
|
409
|
+
> The suggestion must replace the exact lines referenced by the finding.
|
|
410
|
+
|
|
411
|
+
Then include `EXISTING_COMMENTS` and `CODE_SUGGESTIONS` in every reviewer's task prompt:
|
|
412
|
+
|
|
413
|
+
```text
|
|
414
|
+
subagent(tasks=[
|
|
415
|
+
{agent: "code-reviewer-quality", task: "Review this PR for code quality. Run: git diff origin/<BASE_BRANCH>...HEAD to see changes. Read any files needed for context.\n\n<review-history>\nMANDATORY — before reviewing any code, run:\nmyk-pi-tools pr get-review-history {owner} {repo} {pr_number}\nReview the output. Do NOT re-raise any finding marked as resolved_accepted, resolved_fixed, or skipped. These have been evaluated and decided in prior review cycles. Only flag a previously resolved finding if the code at that location has materially changed since the resolution.\n</review-history>\n\n<existing-unresolved-comments>\nThe following unresolved review comments already exist on this PR from other reviewers. Do NOT raise findings that duplicate these — skip them. If you find the same issue but with additional context or a different angle, note that it references the existing comment.\n\n<EXISTING_COMMENTS>\n</existing-unresolved-comments>\n\n<code-suggestions>\n<CODE_SUGGESTIONS>\n</code-suggestions>", cwd: "<REVIEW_DIR>", name: "Review Quality", taskId: "<task 5 ID>"},
|
|
416
|
+
{agent: "code-reviewer-guidelines", task: "Review this PR for guideline adherence. Run: git diff origin/<BASE_BRANCH>...HEAD to see changes. Read AGENTS.md and check compliance.\n\n<review-history>\nMANDATORY — before reviewing any code, run:\nmyk-pi-tools pr get-review-history {owner} {repo} {pr_number}\nReview the output. Do NOT re-raise any finding marked as resolved_accepted, resolved_fixed, or skipped. These have been evaluated and decided in prior review cycles. Only flag a previously resolved finding if the code at that location has materially changed since the resolution.\n</review-history>\n\n<existing-unresolved-comments>\nThe following unresolved review comments already exist on this PR from other reviewers. Do NOT raise findings that duplicate these — skip them. If you find the same issue but with additional context or a different angle, note that it references the existing comment.\n\n<EXISTING_COMMENTS>\n</existing-unresolved-comments>\n\n<code-suggestions>\n<CODE_SUGGESTIONS>\n</code-suggestions>", cwd: "<REVIEW_DIR>", name: "Review Guidelines", taskId: "<task 6 ID>"},
|
|
417
|
+
{agent: "code-reviewer-security", task: "Review this PR for bugs and security. Run: git diff origin/<BASE_BRANCH>...HEAD to see changes. Trace data flow through changed code.\n\n<review-history>\nMANDATORY — before reviewing any code, run:\nmyk-pi-tools pr get-review-history {owner} {repo} {pr_number}\nReview the output. Do NOT re-raise any finding marked as resolved_accepted, resolved_fixed, or skipped. These have been evaluated and decided in prior review cycles. Only flag a previously resolved finding if the code at that location has materially changed since the resolution.\n</review-history>\n\n<existing-unresolved-comments>\nThe following unresolved review comments already exist on this PR from other reviewers. Do NOT raise findings that duplicate these — skip them. If you find the same issue but with additional context or a different angle, note that it references the existing comment.\n\n<EXISTING_COMMENTS>\n</existing-unresolved-comments>\n\n<code-suggestions>\n<CODE_SUGGESTIONS>\n</code-suggestions>", cwd: "<REVIEW_DIR>", name: "Review Security", taskId: "<task 7 ID>"},
|
|
418
|
+
{agent: "code-reviewer-docs", task: "Review this PR for documentation quality. Run: git diff origin/<BASE_BRANCH>...HEAD to see changes. Check all docs for completeness and accuracy.\n\n<review-history>\nMANDATORY — before reviewing any code, run:\nmyk-pi-tools pr get-review-history {owner} {repo} {pr_number}\nReview the output. Do NOT re-raise any finding marked as resolved_accepted, resolved_fixed, or skipped. These have been evaluated and decided in prior review cycles. Only flag a previously resolved finding if the code at that location has materially changed since the resolution.\n</review-history>\n\n<existing-unresolved-comments>\nThe following unresolved review comments already exist on this PR from other reviewers. Do NOT raise findings that duplicate these — skip them. If you find the same issue but with additional context or a different angle, note that it references the existing comment.\n\n<EXISTING_COMMENTS>\n</existing-unresolved-comments>\n\n<code-suggestions>\n<CODE_SUGGESTIONS>\n</code-suggestions>", cwd: "<REVIEW_DIR>", name: "Review Docs", taskId: "<task 8 ID>"},
|
|
419
|
+
{agent: "code-reviewer-spec", task: "Review this PR for spec compliance. Run: git diff origin/<BASE_BRANCH>...HEAD to see changes. Check PR description claims vs diff, issue deliverables vs diff, and scope creep.\n\n<review-history>\nMANDATORY — before reviewing any code, run:\nmyk-pi-tools pr get-review-history {owner} {repo} {pr_number}\nReview the output. Do NOT re-raise any finding marked as resolved_accepted, resolved_fixed, or skipped. These have been evaluated and decided in prior review cycles. Only flag a previously resolved finding if the code at that location has materially changed since the resolution.\n</review-history>\n\n<existing-unresolved-comments>\nThe following unresolved review comments already exist on this PR from other reviewers. Do NOT raise findings that duplicate these — skip them. If you find the same issue but with additional context or a different angle, note that it references the existing comment.\n\n<EXISTING_COMMENTS>\n</existing-unresolved-comments>\n\n<code-suggestions>\n<CODE_SUGGESTIONS>\n</code-suggestions>", cwd: "<REVIEW_DIR>", name: "Review Spec", taskId: "<task 9 ID>"},
|
|
420
|
+
])
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Where `<EXISTING_COMMENTS>` is replaced with the formatted unresolved comments from
|
|
424
|
+
`${PROJECT_TMP_DIR}/all-unresolved/`. If no unresolved comments exist, replace with
|
|
425
|
+
"No existing unresolved comments found."
|
|
426
|
+
|
|
427
|
+
Each reviewer runs in the cloned repo directory (`REVIEW_DIR`) and has full access to:
|
|
428
|
+
|
|
429
|
+
- All source files via `read` tool
|
|
430
|
+
- The PR diff via `git diff origin/<BASE_BRANCH>...HEAD`
|
|
431
|
+
- Project guidelines (AGENTS.md/CLAUDE.md) — read independently per agent instructions
|
|
432
|
+
- File history, imports, tests — anything in the repo
|
|
433
|
+
|
|
434
|
+
Each agent should analyze for security, bugs, error handling, and performance issues
|
|
435
|
+
and return their findings as prose.
|
|
436
|
+
|
|
437
|
+
**After spawning, verify the response confirms all 5 agents were spawned.**
|
|
438
|
+
If any spawn fails, STOP and report the error — do NOT continue waiting.
|
|
439
|
+
|
|
440
|
+
**After spawning, your turn is DONE.** Do NOT poll, sleep, call TaskOutput,
|
|
441
|
+
or check status. Results arrive automatically as follow-up messages.
|
|
442
|
+
When each reviewer finishes, its task is auto-completed via `taskId`.
|
|
443
|
+
Task 10 (Merge findings) auto-unblocks when all 5 reviewer tasks complete.
|
|
444
|
+
|
|
445
|
+
### Phase 3: Merge & Deduplicate Findings — Task 10
|
|
446
|
+
|
|
447
|
+
Merge and deduplicate the findings from all 5 reviewers AND the past review comment analysis from Task 4 into a single combined findings list.
|
|
448
|
+
|
|
449
|
+
Reviewers were already instructed in Phase 2 to skip findings that duplicate existing
|
|
450
|
+
unresolved PR comments. However, verify that no duplicates slipped through by comparing
|
|
451
|
+
the merged findings against the all-unresolved list from `${PROJECT_TMP_DIR}/all-unresolved/`.
|
|
452
|
+
Drop any **`[NEW]`** finding (from Phase 2 reviewers) that raises the same issue as an
|
|
453
|
+
existing unresolved comment.
|
|
454
|
+
|
|
455
|
+
> **IMPORTANT:** `[PREV-UNRESOLVED]`, `[PREV-BAD-FIX]`, and `[PREV-NO-FIX]` items from
|
|
456
|
+
> Task 4 are NEVER dropped by dedup. These represent the current user's own prior review
|
|
457
|
+
> comments that naturally appear in the all-unresolved list — removing them would lose
|
|
458
|
+
> tracking of unresolved prior findings. Dedup applies ONLY to `[NEW]` findings.
|
|
459
|
+
|
|
460
|
+
**Previously skipped findings dedup:** Also check the PR review database for findings
|
|
461
|
+
the user previously skipped on this same PR. Run:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
myk-pi-tools pr get-skipped-comments {owner} {repo} {pr_number}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
This returns a JSON array of previously skipped comments with `path`, `line`, `body`,
|
|
468
|
+
`severity`, `skip_reason`, and `head_sha`.
|
|
469
|
+
|
|
470
|
+
For each `[NEW]` finding, compare against the skipped list using path + body similarity
|
|
471
|
+
(same file and similar description = match). Matched findings are auto-skipped with
|
|
472
|
+
`"Auto-skipped (previously dismissed): <skip_reason>"`. The user still sees them in the
|
|
473
|
+
Phase 4 table and can override by selecting them explicitly.
|
|
474
|
+
|
|
475
|
+
### Phase 4: User Selection — Task 11
|
|
476
|
+
|
|
477
|
+
Present ALL findings to user in one combined list, grouped by severity (CRITICAL, WARNING, SUGGESTION).
|
|
478
|
+
This includes:
|
|
479
|
+
|
|
480
|
+
1. **Past review findings** from Phase 1c (unresolved, incorrectly resolved, or bad fixes)
|
|
481
|
+
2. **New code review findings** from Phase 2
|
|
482
|
+
|
|
483
|
+
Each finding shows its source:
|
|
484
|
+
|
|
485
|
+
- `[PREV-UNRESOLVED]` — unresolved from previous review cycle
|
|
486
|
+
- `[PREV-BAD-FIX]` — resolved but fix is incorrect
|
|
487
|
+
- `[PREV-NO-FIX]` — resolved without code change or valid response
|
|
488
|
+
- `[AUTHOR-QUESTION]` — question/comment from someone on the PR directed at us
|
|
489
|
+
- `[NEW]` — new finding from current code analysis
|
|
490
|
+
|
|
491
|
+
**Auto-post previous findings:** `[PREV-UNRESOLVED]`, `[PREV-BAD-FIX]`, and `[PREV-NO-FIX]`
|
|
492
|
+
findings are **automatically included** in the post list — they are the user's own prior
|
|
493
|
+
comments that remain unaddressed and MUST be re-raised. Do NOT ask the user to select these.
|
|
494
|
+
Show them in the list marked as "(auto-post)" so the user knows they'll be re-raised.
|
|
495
|
+
|
|
496
|
+
> **Note:** `[PREV-UNRESOLVED]` findings where no new commits exist after the comment
|
|
497
|
+
> (silently skipped in Phase 1c) do NOT appear here — they were already filtered out.
|
|
498
|
+
|
|
499
|
+
**Author questions require user approval:** `[AUTHOR-QUESTION]` findings are NOT auto-posted.
|
|
500
|
+
They require user review because the AI-generated answer may need editing or the user may
|
|
501
|
+
choose not to respond. Author questions are presented with approve/edit/skip options (see below).
|
|
502
|
+
|
|
503
|
+
**Author question presentation:**
|
|
504
|
+
|
|
505
|
+
For each `[AUTHOR-QUESTION]` finding, display:
|
|
506
|
+
|
|
507
|
+
1. The original question/comment (who asked, where, full text)
|
|
508
|
+
2. The AI-generated **suggested answer** from Phase 1c
|
|
509
|
+
3. An action prompt for the user:
|
|
510
|
+
- **approve** — post the suggested answer as-is
|
|
511
|
+
- **edit** — user provides a revised answer (print prompt as regular text, NOT `ask_user`)
|
|
512
|
+
- **skip** — don't reply to this question
|
|
513
|
+
|
|
514
|
+
Collect user decisions for all author questions before proceeding. Approved/edited answers
|
|
515
|
+
are included in the Phase 5 post step. Skipped questions are excluded from posting.
|
|
516
|
+
|
|
517
|
+
**Numbering:** Display three separate numbered sections:
|
|
518
|
+
|
|
519
|
+
1. Previous findings (P1, P2, ...) marked "(auto-post)"
|
|
520
|
+
2. Author questions (Q1, Q2, ...) with suggested answers and action prompts
|
|
521
|
+
3. New findings (1, 2, ...) for user selection
|
|
522
|
+
|
|
523
|
+
This avoids ambiguity — user selections for new findings always refer to the `[NEW]` numbering.
|
|
524
|
+
|
|
525
|
+
**User selects from `[NEW]` findings only:**
|
|
526
|
+
|
|
527
|
+
- 'all' = Post all new findings (previous findings are always auto-posted regardless)
|
|
528
|
+
- 'none' = Skip posting new findings (previous findings are still auto-posted)
|
|
529
|
+
- Specific numbers = Post only those new findings (numbers refer to the `[NEW]` list)
|
|
530
|
+
|
|
531
|
+
If there are ZERO `[NEW]` findings AND zero `[AUTHOR-QUESTION]` findings, skip user
|
|
532
|
+
selection entirely — auto-post the previous findings and proceed directly to Phase 5
|
|
533
|
+
(the auto-post path still generates the comments JSON and posts them — see Phase 5).
|
|
534
|
+
|
|
535
|
+
If there are ZERO `[NEW]` findings but `[AUTHOR-QUESTION]` findings exist, skip new
|
|
536
|
+
finding selection but still present author questions with suggested answers for
|
|
537
|
+
user approval/edit/skip.
|
|
538
|
+
|
|
539
|
+
🚨 **Skip reason collection (MANDATORY — NEVER SKIP THIS STEP):**
|
|
540
|
+
|
|
541
|
+
**HARD RULE: If the user skipped ANY finding (said 'no', selected specific numbers
|
|
542
|
+
that exclude some findings, or said 'none'), you MUST ask for skip reasons
|
|
543
|
+
BEFORE proceeding to Phase 5. Do NOT continue the workflow without collecting
|
|
544
|
+
skip reasons. Skipping this step is a HARD VIOLATION.**
|
|
545
|
+
|
|
546
|
+
After the user selects which findings to post, compute the skipped set (total `[NEW]`
|
|
547
|
+
findings minus user-selected findings). If the skipped set is non-empty:
|
|
548
|
+
|
|
549
|
+
1. Ask the user for skip reasons as a **normal chat message** (do NOT use `ask_user` — skip
|
|
550
|
+
reasons are often multiline and `ask_user` only supports single-line input).
|
|
551
|
+
Print this prompt as regular text:
|
|
552
|
+
|
|
553
|
+
```text
|
|
554
|
+
You skipped findings 2, 4, 5. Why?
|
|
555
|
+
Give one reason for all, or per-finding (e.g., "2: not relevant, 4 and 5: style only")
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
**STOP your turn after printing this prompt.** Do NOT continue the workflow.
|
|
559
|
+
The user will respond with their skip reasons in their next message.
|
|
560
|
+
Resume the workflow (step 2 below) only after receiving the user's response.
|
|
561
|
+
|
|
562
|
+
2. AI refines each reason — make it concise, technical, and useful for future reference:
|
|
563
|
+
- User: "don't care" → "Style-only finding — no functional impact"
|
|
564
|
+
- User: "we do it this way" → "Intentional pattern — project convention"
|
|
565
|
+
- User: "already covered" → "Already validated by existing test coverage"
|
|
566
|
+
|
|
567
|
+
3. AI classifies each refined reason (no user interaction):
|
|
568
|
+
- **Finding-specific** — references specific code, line, variable, or one-off context.
|
|
569
|
+
Store in DB only (same-PR dedup).
|
|
570
|
+
- **Generalizable** — references a project-wide pattern, convention, or category of
|
|
571
|
+
findings (e.g., "don't flag snake_case", "print() is intentional in CLI modules").
|
|
572
|
+
Store in DB AND append to `.pi/data/review-guidelines.md`.
|
|
573
|
+
|
|
574
|
+
4. For generalizable reasons, append one line per finding to `.pi/data/review-guidelines.md`
|
|
575
|
+
(create the file if it doesn't exist). Format:
|
|
576
|
+
|
|
577
|
+
```markdown
|
|
578
|
+
- Do not flag <finding type> — <refined reason>
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
This file is read by all 5 reviewer agents before reviewing, so the same class of
|
|
582
|
+
finding won't be raised again on future PRs in this repo.
|
|
583
|
+
|
|
584
|
+
### Phase 5: Post Comments — Task 12
|
|
585
|
+
|
|
586
|
+
**Step 1: Post `[NEW]` and `[PREV-*]` findings as new review comments:**
|
|
587
|
+
|
|
588
|
+
Write JSON to temp file for all `[NEW]` (user-selected) and `[PREV-*]` (auto-posted)
|
|
589
|
+
findings. If only `[PREV-*]` findings exist (zero `[NEW]` findings, selection was skipped),
|
|
590
|
+
still generate the JSON for the auto-posted items:
|
|
591
|
+
|
|
592
|
+
Use the `owner`, `repo`, `pr_number`, and `head_sha` from Phase 0 or Phase 1a metadata:
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
myk-pi-tools pr post-comment {owner}/{repo} {pr_number} {head_sha} ${PROJECT_TMP_DIR}/pr-review-comments.json
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
**Step 2: Reply to `[AUTHOR-QUESTION]` findings (approved/edited only):**
|
|
599
|
+
|
|
600
|
+
For each approved or edited author question, reply using the appropriate method based on
|
|
601
|
+
the question's source:
|
|
602
|
+
|
|
603
|
+
**Review thread questions** (have a `thread_id`):
|
|
604
|
+
|
|
605
|
+
Write a JSON file with the reply and use `reviews post` which correctly replies in the
|
|
606
|
+
existing thread via GraphQL `addPullRequestReviewThreadReply`:
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
myk-pi-tools reviews post ${PROJECT_TMP_DIR}/author-question-replies.json
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
The JSON file MUST use the `reviews post` format with the `"human"` category key:
|
|
613
|
+
|
|
614
|
+
```json
|
|
615
|
+
{
|
|
616
|
+
"metadata": {"owner": "{owner}", "repo": "{repo}", "pr_number": "{pr_number}"},
|
|
617
|
+
"human": [
|
|
618
|
+
{"thread_id": "{thread_id}", "status": "not_addressed", "reply": "{approved_answer}"}
|
|
619
|
+
]
|
|
620
|
+
}
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**IMPORTANT:** Use `status: "not_addressed"` (NOT `"addressed"`). These are threads owned
|
|
624
|
+
by someone else — `"addressed"` would auto-resolve their thread, which is inappropriate.
|
|
625
|
+
`"not_addressed"` posts the reply but leaves the thread open for the original author to resolve.
|
|
626
|
+
|
|
627
|
+
**General PR issue comments** (no `thread_id`, have `comment_id`):
|
|
628
|
+
|
|
629
|
+
Write the reply body to a temp file to avoid shell injection, then post via the GitHub API
|
|
630
|
+
with a quoted reference to the original question:
|
|
631
|
+
|
|
632
|
+
Write the raw markdown reply to a plain text file first, then use `jq` to safely
|
|
633
|
+
encode it as valid JSON (handles quotes, backslashes, newlines):
|
|
634
|
+
|
|
635
|
+
```bash
|
|
636
|
+
# 1. Build the reply body as raw markdown (not JSON)
|
|
637
|
+
cat > ${PROJECT_TMP_DIR}/author-reply-body.md << 'REPLY_EOF'
|
|
638
|
+
> @{commenter} [asked]({comment_url}):
|
|
639
|
+
> {original_question_first_line}
|
|
640
|
+
|
|
641
|
+
{approved_answer}
|
|
642
|
+
REPLY_EOF
|
|
643
|
+
|
|
644
|
+
# 2. Encode as valid JSON using jq (handles all special characters safely)
|
|
645
|
+
jq -Rs '{body: .}' < ${PROJECT_TMP_DIR}/author-reply-body.md > ${PROJECT_TMP_DIR}/author-reply-body.json
|
|
646
|
+
|
|
647
|
+
# 3. Post via gh api
|
|
648
|
+
gh api /repos/{owner}/{repo}/issues/{pr_number}/comments --input ${PROJECT_TMP_DIR}/author-reply-body.json
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
NEVER build JSON by string interpolation — always write the reply body as raw text
|
|
652
|
+
and use `jq -Rs '{body: .}'` to produce valid JSON. This prevents both shell injection
|
|
653
|
+
and JSON encoding errors from quotes, backslashes, or newlines in the answer.
|
|
654
|
+
|
|
655
|
+
### Phase 5b: Store Posted Comments — Task 13
|
|
656
|
+
|
|
657
|
+
After posting comments, store ALL findings (posted AND skipped) in the PR review database
|
|
658
|
+
for future cycle tracking and same-PR dedup of skipped findings.
|
|
659
|
+
|
|
660
|
+
1. Write a JSON file with ALL findings:
|
|
661
|
+
|
|
662
|
+
```bash
|
|
663
|
+
cat > ${PROJECT_TMP_DIR}/pr-review-store.json << 'EOF'
|
|
664
|
+
{
|
|
665
|
+
"metadata": {"owner": "{owner}", "repo": "{repo}", "pr_number": {pr_number}, "head_sha": "{head_sha}", "author": "{author}"},
|
|
666
|
+
"comments": [
|
|
667
|
+
{
|
|
668
|
+
"thread_id": null,
|
|
669
|
+
"comment_id": null,
|
|
670
|
+
"path": "file.py",
|
|
671
|
+
"line": 42,
|
|
672
|
+
"body": "Comment body as posted",
|
|
673
|
+
"severity": "WARNING",
|
|
674
|
+
"posted_at": "<ISO timestamp>",
|
|
675
|
+
"status": "posted"
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
"thread_id": null,
|
|
679
|
+
"comment_id": null,
|
|
680
|
+
"path": "file.py",
|
|
681
|
+
"line": 99,
|
|
682
|
+
"body": "Finding description that was skipped",
|
|
683
|
+
"severity": "SUGGESTION",
|
|
684
|
+
"posted_at": null,
|
|
685
|
+
"status": "skipped",
|
|
686
|
+
"skip_reason": "Refined skip reason from Phase 4"
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"thread_id": "thread_abc123",
|
|
690
|
+
"comment_id": 456,
|
|
691
|
+
"path": "utils.py",
|
|
692
|
+
"line": 10,
|
|
693
|
+
"body": "Author question: should this use sleep=0?",
|
|
694
|
+
"severity": "QUESTION",
|
|
695
|
+
"posted_at": "<ISO timestamp>",
|
|
696
|
+
"status": "posted",
|
|
697
|
+
"source": "author-question"
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
"thread_id": null,
|
|
701
|
+
"comment_id": 789,
|
|
702
|
+
"path": null,
|
|
703
|
+
"line": null,
|
|
704
|
+
"body": "General PR question that was skipped",
|
|
705
|
+
"severity": "QUESTION",
|
|
706
|
+
"posted_at": null,
|
|
707
|
+
"status": "skipped",
|
|
708
|
+
"skip_reason": "User chose not to respond",
|
|
709
|
+
"source": "author-question"
|
|
710
|
+
}
|
|
711
|
+
]
|
|
712
|
+
}
|
|
713
|
+
EOF
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
Include `[AUTHOR-QUESTION]` findings with `status: "posted"` (approved/edited and posted)
|
|
717
|
+
or `status: "skipped"` (user chose to skip). Use `"posted"` (not `"answered"`) because
|
|
718
|
+
the `myk-pi-tools pr store-pr-review` CLI only accepts `posted` or `skipped` as valid
|
|
719
|
+
statuses.
|
|
720
|
+
|
|
721
|
+
**Note on `source` field:** The `source: "author-question"` field in the JSON example is
|
|
722
|
+
for LLM context only — the CLI's DB schema does not have a `source` column and will
|
|
723
|
+
ignore it. Future review cycles detect already-answered questions by matching
|
|
724
|
+
`path`/`line`/`body` similarity against stored comments, same as other finding types.
|
|
725
|
+
|
|
726
|
+
Use `{author}` from Phase 0 (`myk-pi-tools pr info` returns `author` field).
|
|
727
|
+
|
|
728
|
+
1. Store to database:
|
|
729
|
+
|
|
730
|
+
```bash
|
|
731
|
+
myk-pi-tools pr store-pr-review ${PROJECT_TMP_DIR}/pr-review-store.json
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
**This step is MANDATORY — never skip it.** The database is used by future `/pr-review`
|
|
735
|
+
runs to track which comments were posted, verify they were addressed, and auto-skip
|
|
736
|
+
previously dismissed findings.
|
|
737
|
+
|
|
738
|
+
### Phase 6: Summary — Task 14
|
|
739
|
+
|
|
740
|
+
Display final summary with counts and links. Include:
|
|
741
|
+
|
|
742
|
+
- New findings posted / skipped counts
|
|
743
|
+
- Previous findings re-raised count
|
|
744
|
+
- Author questions answered / skipped counts
|
|
745
|
+
- Total comments posted
|
|
746
|
+
- PR link
|
|
747
|
+
|
|
748
|
+
### Cleanup
|
|
749
|
+
|
|
750
|
+
After the review is complete (all phases done):
|
|
751
|
+
|
|
752
|
+
1. Delete all tasks: `TaskUpdate(taskId="N", status="deleted")` for every task created in this workflow
|
|
753
|
+
2. Delegate to `git-expert`: remove the clone directory `REVIEW_DIR`
|