diff --git a/kompass.jsonc b/kompass.jsonc index ad61bfa..6f25b1c 100644 --- a/kompass.jsonc +++ b/kompass.jsonc @@ -21,6 +21,7 @@ "merge": { "enabled": true }, "pr/create": { "enabled": true }, "pr/fix": { "enabled": true }, + "pr/analyze": { "enabled": true }, "pr/review": { "enabled": true }, "review": { "enabled": true }, "skill/create": { "enabled": true }, diff --git a/kompass.schema.json b/kompass.schema.json index 2faf9b6..f5df1ae 100644 --- a/kompass.schema.json +++ b/kompass.schema.json @@ -62,6 +62,9 @@ "pr/fix": { "$ref": "#/$defs/commandConfig" }, + "pr/analyze": { + "$ref": "#/$defs/commandConfig" + }, "pr/review": { "$ref": "#/$defs/commandConfig" }, @@ -113,6 +116,7 @@ "merge", "pr/create", "pr/fix", + "pr/analyze", "pr/review", "review", "skill/create", @@ -144,6 +148,7 @@ "merge", "pr/create", "pr/fix", + "pr/analyze", "pr/review", "review", "skill/create", diff --git a/packages/core/commands/index.ts b/packages/core/commands/index.ts index 8b01c89..65e6076 100644 --- a/packages/core/commands/index.ts +++ b/packages/core/commands/index.ts @@ -72,6 +72,11 @@ export const commandDefinitions: Record = { templatePath: "commands/pr/fix.md", subtask: false, }, + "pr/analyze": { + description: "Load and filter PR review history into an actionable brief", + agent: "reviewer", + templatePath: "commands/pr/analyze.md", + }, "pr/review": { description: "Review the current PR and publish review feedback", agent: "reviewer", diff --git a/packages/core/commands/loop/pr/fix.md b/packages/core/commands/loop/pr/fix.md index 21550c6..b0b1234 100644 --- a/packages/core/commands/loop/pr/fix.md +++ b/packages/core/commands/loop/pr/fix.md @@ -23,12 +23,17 @@ $ARGUMENTS - If empty, leave `` undefined and let `<%= it.config.tools.pr_load.name %>` resolve the default PR context - Initialize `` as `0` -### Load PR Context +### Delegate PR Analysis -<%~ include("@load-pr", { config: it.config, ref: "", result: "" }) %> +"> + -- Store `` as `` -- Store `` as `` +Additional context: + + +- Store the delegated result as `` +- Extract `` from the PR_URL section of `` +- Extract `` from the PR_NUMBER section of `` - STOP if `` or `` is unavailable ### Watch CI And Comments @@ -41,10 +46,14 @@ $ARGUMENTS ### Reload PR Feedback -Call `<%= it.config.tools.pr_load.name %>` with `` and store the refreshed result as ``. +"> + + +Additional context: + -- Review ``, ``, and `` -- Identify open, unresolved, actionable reviewer feedback that has not already been answered by the author or superseded by later commits +- Store the refreshed result as `` +- Use the THREADS and SUMMARY sections from `` to identify open, unresolved, actionable reviewer feedback that has not already been answered by the author or superseded by later commits - Combine actionable reviewer feedback and `` into `` - Store the number of actionable reviewer items as `` - Store the number of actionable CI failures as `` diff --git a/packages/core/commands/pr/analyze.md b/packages/core/commands/pr/analyze.md new file mode 100644 index 0000000..5521fb6 --- /dev/null +++ b/packages/core/commands/pr/analyze.md @@ -0,0 +1,102 @@ +## Goal + +Load a pull request's full review history, filter out resolved and outdated threads, and return a compact actionable brief so the caller never receives stale or already-addressed feedback in its context. + +## Additional Context + +Use `` to focus the analysis on specific feedback categories, reviewer priorities, or CI concerns that should influence which threads are flagged as actionable. + +## Workflow + +### Arguments + + +$ARGUMENTS + + +### Interpret Arguments + +- If `` looks like a PR number (e.g., "123") or URL, store it as `` +- If `` includes extra analysis guidance, scope constraints, or priorities, store it as `` +- If empty, leave `` undefined and let `<%= it.config.tools.pr_load.name %>` resolve the default PR context + +### Load PR Context + +<%~ include("@load-pr", { config: it.config, ref: "", result: "" }) %> + +- Store `` as `` +- Store `` as `` +- Store `` as `` +- Store `` as `` +- Store `` as `` +- STOP if `` or `` is unavailable + +### Filter Resolved Threads + +- Exclude every thread in `` where `isResolved` is `true` +- Exclude every thread where `isOutdated` is `true` +- For each remaining thread, check whether the latest reply from the PR author indicates the feedback was already addressed (phrases like "Fixed", "Done", "Addressed") and a later commit in `` plausibly implements that fix +- Move effectively-resolved threads to a `` list with a one-line reason +- Store the remaining threads as `` + +### Categorize Threads + +For each thread in ``: +- Classify as `critical`, `important`, `style`, `question`, or `noise` +- Record ``, ``, ``, ``, `` (one-line), `` (`yes` or `no`) +- Threads marked `noise` or `question` go to the `` list with reasons + +### Partition Groups + +- Group actionable threads (`critical`, `important`, actionable `style`) into file-disjoint groups for parallel implementation +- Threads sharing the same file or having cross-thread dependencies stay in the same group +- Store the partition as `` + +### Output + +Return a single fenced markdown block with this structure: + +``` +PR_NUMBER: +PR_BRANCH: +BASE_BRANCH: +PR_URL: +COMMIT_COUNT: + +SUMMARY: +- One-line overall assessment +- Recommended fix order: critical first, then important, then style +- Total actionable threads: +- Total resolved-silently threads: + +THREADS: +- [critical] : - (current-heading: yes/no) +- [important] : - (current-heading: yes/no) +- [style] : - (current-heading: yes/no) + +NOT_FIXING: +- [noise] - +- [question] - + +RESOLVED_SILENTLY: +- - + +GROUPS: +- group-1: , +- group-2: +``` + +If no actionable threads remain, output: +``` +PR_NUMBER: +PR_BRANCH: +BASE_BRANCH: +PR_URL: +COMMIT_COUNT: + +SUMMARY: +- No actionable feedback remaining +- Total actionable threads: 0 + +No additional steps are required. +``` diff --git a/packages/core/commands/pr/fix.md b/packages/core/commands/pr/fix.md index 20584da..8ca6d78 100644 --- a/packages/core/commands/pr/fix.md +++ b/packages/core/commands/pr/fix.md @@ -24,31 +24,41 @@ $ARGUMENTS - Otherwise, store `` as `review` - If empty, leave `` undefined and let `<%= it.config.tools.pr_load.name %>` resolve the default PR context -### Load PR Context +### Delegate PR Analysis -<%~ include("@load-pr", { config: it.config, ref: "", result: "" }) %> +"> + + +Additional context: + + +- Store the delegated result as `` +- Extract `` from the PR_NUMBER section of `` +- Extract `` from the PR_BRANCH section of `` +- Extract `` from the BASE_BRANCH section of `` +- Extract `` from the PR_URL section of `` +- Extract `` from the COMMIT_COUNT section of `` +- STOP if `` is unavailable or reports no actionable feedback ### Align Local Branch - If `` is unavailable, STOP and report that the PR head branch could not be determined -- Run `gh pr checkout ` before analyzing repository files or making code changes for this PR +- Run `gh pr checkout ` before analyzing repository files or making code changes for this PR - After checkout, store the active branch as `` - If checkout fails or times out, STOP and report that the PR branch could not be checked out locally; do not retry checkout unless the user explicitly asks - Do not inspect or modify local code for this PR until `` equals `` ### Load Changes -Call `<%= it.config.tools.changes_load.name %>` with `base: `, `head: `, and `depthHint: ` only when it is a positive integer. Store as ``. +Call `<%= it.config.tools.changes_load.name %>` with `base: `, `head: `, and `depthHint: ` only when it is a positive integer. Store as ``. ### Analyze Feedback -Separate true course corrections from noise or already-resolved feedback: -1. Review `` for open, unresolved conversations -2. Check `` for state changes (CHANGES_REQUESTED, etc.) -3. Include any CI failures, logs, failing check names, or reproduction details provided in `` as actionable feedback -4. Use `` to understand the current PR diff before deciding what to adjust -5. Prioritize critical issues (bugs, security, broken contracts, failing required checks) -6. Identify which files need changes +- Use the THREADS, SUMMARY, and GROUPS sections from `` as the filtered, actionable feedback source +- Include any CI failures, logs, failing check names, or reproduction details provided in `` as actionable feedback +- Use `` to understand the current PR diff before deciding what to adjust +- Prioritize critical issues (bugs, security, broken contracts, failing required checks) +- Identify which files need changes Do not blindly follow every suggestion—some may lead you off course. @@ -122,13 +132,13 @@ Only after commit and push succeed, reply to addressed threads: ``` # General PR comment -<%= it.config.tools.pr_sync.name %> refUrl="" commentBody="" +<%= it.config.tools.pr_sync.name %> refUrl="" commentBody="" # Reply to a specific review thread (use comment.id from threads.comments) -<%= it.config.tools.pr_sync.name %> refUrl="" replies=[{"inReplyTo": , "body": ""}] +<%= it.config.tools.pr_sync.name %> refUrl="" replies=[{"inReplyTo": , "body": ""}] # Follow-up inline review comment on a specific line -<%= it.config.tools.pr_sync.name %> refUrl="" commitId="" review={"comments": [{"path": "", "line": , "body": ""}]} +<%= it.config.tools.pr_sync.name %> refUrl="" commitId="" review={"comments": [{"path": "", "line": , "body": ""}]} ``` Confirm which feedback was addressed and which was intentionally not followed. @@ -138,7 +148,7 @@ Confirm which feedback was addressed and which was intentionally not followed. When waiting for approval or revision feedback, display: ``` -Review fixes for PR # +Review fixes for PR # - Changes made: files modified - Validation passing: @@ -147,7 +157,7 @@ Review fixes for PR # If the workflow stops after a no-change pass, display: ``` -No changes made for PR # +No changes made for PR # - Changes made: 0 files modified - Validation passing: @@ -158,7 +168,7 @@ No additional steps are required. When fixes are complete, display exactly this final completion summary and stop. Do not continue with extra analysis, planning, or follow-up tasks unless the workflow is blocked or the user asked for more: ``` -PR fix complete for # +PR fix complete for # - Changes made: files modified - Threads resolved: diff --git a/packages/core/kompass.jsonc b/packages/core/kompass.jsonc index ad61bfa..6f25b1c 100644 --- a/packages/core/kompass.jsonc +++ b/packages/core/kompass.jsonc @@ -21,6 +21,7 @@ "merge": { "enabled": true }, "pr/create": { "enabled": true }, "pr/fix": { "enabled": true }, + "pr/analyze": { "enabled": true }, "pr/review": { "enabled": true }, "review": { "enabled": true }, "skill/create": { "enabled": true }, diff --git a/packages/core/lib/config.ts b/packages/core/lib/config.ts index c5d94a5..451a68a 100644 --- a/packages/core/lib/config.ts +++ b/packages/core/lib/config.ts @@ -33,6 +33,7 @@ export const DEFAULT_COMMAND_NAMES = [ "merge", "pr/create", "pr/fix", + "pr/analyze", "pr/review", "review", "skill/create", diff --git a/packages/core/test/commands.test.ts b/packages/core/test/commands.test.ts index 65cd704..577d16e 100644 --- a/packages/core/test/commands.test.ts +++ b/packages/core/test/commands.test.ts @@ -28,7 +28,7 @@ describe("resolveCommands", () => { const commands = await resolveCommands(process.cwd()); const template = commands["pr/fix"]?.template ?? ""; - assert.match(template, /Run `gh pr checkout ` before analyzing repository files or making code changes for this PR/); + assert.match(template, /Run `gh pr checkout ` before analyzing repository files or making code changes for this PR/); assert.match(template, /Do not inspect or modify local code for this PR until `` equals ``/); assert.doesNotMatch(template, /`` differs from `` or `` differs from ``/); }); diff --git a/packages/opencode/.opencode/commands/loop/pr/fix.md b/packages/opencode/.opencode/commands/loop/pr/fix.md index 907c8d0..c90b055 100644 --- a/packages/opencode/.opencode/commands/loop/pr/fix.md +++ b/packages/opencode/.opencode/commands/loop/pr/fix.md @@ -28,22 +28,17 @@ $ARGUMENTS - If empty, leave `` undefined and let `kompass_pr_load` resolve the default PR context - Initialize `` as `0` -### Load PR Context - -- Use `kompass_pr_load` as the source of truth for PR selection -- If `` is defined, call `kompass_pr_load` with `pr: ` -- Otherwise, call `kompass_pr_load` with no arguments -- Do not run separate git or GitHub commands just to discover the PR before calling `kompass_pr_load` -- Store the result as `` -- Store the PR head branch as `` from `.pr.headRefName` when it is available -- Run `git branch --show-current` and store the trimmed result as `` when it is available -- Run `git rev-parse HEAD` and store the trimmed result as `` when it is available -- Treat the loaded PR body, discussion, review history, and any attachments or linked artifacts returned by the loader as part of the source context -- Review attached images, screenshots, videos, PDFs, and other linked files whenever they can affect the requested fix, review outcome, reproduction steps, or acceptance criteria -- If any relevant attachment cannot be accessed, note that gap and continue only when the remaining PR context is still sufficient to proceed reliably - -- Store `` as `` -- Store `` as `` +### Delegate PR Analysis + + + + +Additional context: + + +- Store the delegated result as `` +- Extract `` from the PR_URL section of `` +- Extract `` from the PR_NUMBER section of `` - STOP if `` or `` is unavailable ### Watch CI And Comments @@ -56,10 +51,14 @@ $ARGUMENTS ### Reload PR Feedback -Call `kompass_pr_load` with `` and store the refreshed result as ``. + + + +Additional context: + -- Review ``, ``, and `` -- Identify open, unresolved, actionable reviewer feedback that has not already been answered by the author or superseded by later commits +- Store the refreshed result as `` +- Use the THREADS and SUMMARY sections from `` to identify open, unresolved, actionable reviewer feedback that has not already been answered by the author or superseded by later commits - Combine actionable reviewer feedback and `` into `` - Store the number of actionable reviewer items as `` - Store the number of actionable CI failures as `` diff --git a/packages/opencode/.opencode/commands/pr/analyze.md b/packages/opencode/.opencode/commands/pr/analyze.md new file mode 100644 index 0000000..2528e26 --- /dev/null +++ b/packages/opencode/.opencode/commands/pr/analyze.md @@ -0,0 +1,117 @@ +--- +description: Load and filter PR review history into an actionable brief +agent: reviewer +--- + +## Goal + +Load a pull request's full review history, filter out resolved and outdated threads, and return a compact actionable brief so the caller never receives stale or already-addressed feedback in its context. + +## Additional Context + +Use `` to focus the analysis on specific feedback categories, reviewer priorities, or CI concerns that should influence which threads are flagged as actionable. + +## Workflow + +### Arguments + + +$ARGUMENTS + + +### Interpret Arguments + +- If `` looks like a PR number (e.g., "123") or URL, store it as `` +- If `` includes extra analysis guidance, scope constraints, or priorities, store it as `` +- If empty, leave `` undefined and let `kompass_pr_load` resolve the default PR context + +### Load PR Context + +- Use `kompass_pr_load` as the source of truth for PR selection +- If `` is defined, call `kompass_pr_load` with `pr: ` +- Otherwise, call `kompass_pr_load` with no arguments +- Do not run separate git or GitHub commands just to discover the PR before calling `kompass_pr_load` +- Store the result as `` +- Store the PR head branch as `` from `.pr.headRefName` when it is available +- Run `git branch --show-current` and store the trimmed result as `` when it is available +- Run `git rev-parse HEAD` and store the trimmed result as `` when it is available +- Treat the loaded PR body, discussion, review history, and any attachments or linked artifacts returned by the loader as part of the source context +- Review attached images, screenshots, videos, PDFs, and other linked files whenever they can affect the requested fix, review outcome, reproduction steps, or acceptance criteria +- If any relevant attachment cannot be accessed, note that gap and continue only when the remaining PR context is still sufficient to proceed reliably + +- Store `` as `` +- Store `` as `` +- Store `` as `` +- Store `` as `` +- Store `` as `` +- STOP if `` or `` is unavailable + +### Filter Resolved Threads + +- Exclude every thread in `` where `isResolved` is `true` +- Exclude every thread where `isOutdated` is `true` +- For each remaining thread, check whether the latest reply from the PR author indicates the feedback was already addressed (phrases like "Fixed", "Done", "Addressed") and a later commit in `` plausibly implements that fix +- Move effectively-resolved threads to a `` list with a one-line reason +- Store the remaining threads as `` + +### Categorize Threads + +For each thread in ``: +- Classify as `critical`, `important`, `style`, `question`, or `noise` +- Record ``, ``, ``, ``, `` (one-line), `` (`yes` or `no`) +- Threads marked `noise` or `question` go to the `` list with reasons + +### Partition Groups + +- Group actionable threads (`critical`, `important`, actionable `style`) into file-disjoint groups for parallel implementation +- Threads sharing the same file or having cross-thread dependencies stay in the same group +- Store the partition as `` + +### Output + +Return a single fenced markdown block with this structure: + +``` +PR_NUMBER: +PR_BRANCH: +BASE_BRANCH: +PR_URL: +COMMIT_COUNT: + +SUMMARY: +- One-line overall assessment +- Recommended fix order: critical first, then important, then style +- Total actionable threads: +- Total resolved-silently threads: + +THREADS: +- [critical] : - (current-heading: yes/no) +- [important] : - (current-heading: yes/no) +- [style] : - (current-heading: yes/no) + +NOT_FIXING: +- [noise] - +- [question] - + +RESOLVED_SILENTLY: +- - + +GROUPS: +- group-1: , +- group-2: +``` + +If no actionable threads remain, output: +``` +PR_NUMBER: +PR_BRANCH: +BASE_BRANCH: +PR_URL: +COMMIT_COUNT: + +SUMMARY: +- No actionable feedback remaining +- Total actionable threads: 0 + +No additional steps are required. +``` diff --git a/packages/opencode/.opencode/commands/pr/fix.md b/packages/opencode/.opencode/commands/pr/fix.md index 3b281b6..dfe990a 100644 --- a/packages/opencode/.opencode/commands/pr/fix.md +++ b/packages/opencode/.opencode/commands/pr/fix.md @@ -29,41 +29,41 @@ $ARGUMENTS - Otherwise, store `` as `review` - If empty, leave `` undefined and let `kompass_pr_load` resolve the default PR context -### Load PR Context - -- Use `kompass_pr_load` as the source of truth for PR selection -- If `` is defined, call `kompass_pr_load` with `pr: ` -- Otherwise, call `kompass_pr_load` with no arguments -- Do not run separate git or GitHub commands just to discover the PR before calling `kompass_pr_load` -- Store the result as `` -- Store the PR head branch as `` from `.pr.headRefName` when it is available -- Run `git branch --show-current` and store the trimmed result as `` when it is available -- Run `git rev-parse HEAD` and store the trimmed result as `` when it is available -- Treat the loaded PR body, discussion, review history, and any attachments or linked artifacts returned by the loader as part of the source context -- Review attached images, screenshots, videos, PDFs, and other linked files whenever they can affect the requested fix, review outcome, reproduction steps, or acceptance criteria -- If any relevant attachment cannot be accessed, note that gap and continue only when the remaining PR context is still sufficient to proceed reliably +### Delegate PR Analysis + + + + +Additional context: + + +- Store the delegated result as `` +- Extract `` from the PR_NUMBER section of `` +- Extract `` from the PR_BRANCH section of `` +- Extract `` from the BASE_BRANCH section of `` +- Extract `` from the PR_URL section of `` +- Extract `` from the COMMIT_COUNT section of `` +- STOP if `` is unavailable or reports no actionable feedback ### Align Local Branch - If `` is unavailable, STOP and report that the PR head branch could not be determined -- Run `gh pr checkout ` before analyzing repository files or making code changes for this PR +- Run `gh pr checkout ` before analyzing repository files or making code changes for this PR - After checkout, store the active branch as `` - If checkout fails or times out, STOP and report that the PR branch could not be checked out locally; do not retry checkout unless the user explicitly asks - Do not inspect or modify local code for this PR until `` equals `` ### Load Changes -Call `kompass_changes_load` with `base: `, `head: `, and `depthHint: ` only when it is a positive integer. Store as ``. +Call `kompass_changes_load` with `base: `, `head: `, and `depthHint: ` only when it is a positive integer. Store as ``. ### Analyze Feedback -Separate true course corrections from noise or already-resolved feedback: -1. Review `` for open, unresolved conversations -2. Check `` for state changes (CHANGES_REQUESTED, etc.) -3. Include any CI failures, logs, failing check names, or reproduction details provided in `` as actionable feedback -4. Use `` to understand the current PR diff before deciding what to adjust -5. Prioritize critical issues (bugs, security, broken contracts, failing required checks) -6. Identify which files need changes +- Use the THREADS, SUMMARY, and GROUPS sections from `` as the filtered, actionable feedback source +- Include any CI failures, logs, failing check names, or reproduction details provided in `` as actionable feedback +- Use `` to understand the current PR diff before deciding what to adjust +- Prioritize critical issues (bugs, security, broken contracts, failing required checks) +- Identify which files need changes Do not blindly follow every suggestion—some may lead you off course. @@ -136,13 +136,13 @@ Only after commit and push succeed, reply to addressed threads: ``` # General PR comment -kompass_pr_sync refUrl="" commentBody="" +kompass_pr_sync refUrl="" commentBody="" # Reply to a specific review thread (use comment.id from threads.comments) -kompass_pr_sync refUrl="" replies=[{"inReplyTo": , "body": ""}] +kompass_pr_sync refUrl="" replies=[{"inReplyTo": , "body": ""}] # Follow-up inline review comment on a specific line -kompass_pr_sync refUrl="" commitId="" review={"comments": [{"path": "", "line": , "body": ""}]} +kompass_pr_sync refUrl="" commitId="" review={"comments": [{"path": "", "line": , "body": ""}]} ``` Confirm which feedback was addressed and which was intentionally not followed. @@ -152,7 +152,7 @@ Confirm which feedback was addressed and which was intentionally not followed. When waiting for approval or revision feedback, display: ``` -Review fixes for PR # +Review fixes for PR # - Changes made: files modified - Validation passing: @@ -161,7 +161,7 @@ Review fixes for PR # If the workflow stops after a no-change pass, display: ``` -No changes made for PR # +No changes made for PR # - Changes made: 0 files modified - Validation passing: @@ -172,7 +172,7 @@ No additional steps are required. When fixes are complete, display exactly this final completion summary and stop. Do not continue with extra analysis, planning, or follow-up tasks unless the workflow is blocked or the user asked for more: ``` -PR fix complete for # +PR fix complete for # - Changes made: files modified - Threads resolved: diff --git a/packages/opencode/.opencode/kompass.jsonc b/packages/opencode/.opencode/kompass.jsonc index d3b5250..e650303 100644 --- a/packages/opencode/.opencode/kompass.jsonc +++ b/packages/opencode/.opencode/kompass.jsonc @@ -37,6 +37,9 @@ "pr/fix": { "enabled": true }, + "pr/analyze": { + "enabled": true + }, "pr/review": { "enabled": true }, diff --git a/packages/opencode/kompass.jsonc b/packages/opencode/kompass.jsonc index ad61bfa..6f25b1c 100644 --- a/packages/opencode/kompass.jsonc +++ b/packages/opencode/kompass.jsonc @@ -21,6 +21,7 @@ "merge": { "enabled": true }, "pr/create": { "enabled": true }, "pr/fix": { "enabled": true }, + "pr/analyze": { "enabled": true }, "pr/review": { "enabled": true }, "review": { "enabled": true }, "skill/create": { "enabled": true }, diff --git a/packages/opencode/test/commands-config.test.ts b/packages/opencode/test/commands-config.test.ts index 66fe753..dc38daf 100644 --- a/packages/opencode/test/commands-config.test.ts +++ b/packages/opencode/test/commands-config.test.ts @@ -39,6 +39,7 @@ describe("applyCommandsConfig", () => { "pr/create", "pr/review", "pr/fix", + "pr/analyze", "skill/create", "skill/optimize", "ship", @@ -63,6 +64,7 @@ describe("applyCommandsConfig", () => { assert.ok(cfg.command); assert.equal(cfg.command!["pr/review"]?.agent, "reviewer"); + assert.equal(cfg.command!["pr/analyze"]?.agent, "reviewer"); assert.equal(cfg.command!["branch"]?.agent, "worker"); assert.equal(cfg.command!["merge"]?.agent, "worker"); assert.equal(cfg.command!["pr/create"]?.agent, "worker"); @@ -501,13 +503,13 @@ describe("applyCommandsConfig", () => { assert.ok(cfg.command); const devTemplate = cfg.command!["dev"].template; - + // Should have replaced components assert.match(devTemplate, /Development Flow Navigation Guide/); // PR Author content is now inline in pr/create, not embedded in dev assert.match(devTemplate, /## Goal/); assert.match(devTemplate, /Implement a feature or fix/); - + assert.doesNotMatch(devTemplate, /<%/); }); @@ -519,13 +521,13 @@ describe("applyCommandsConfig", () => { assert.ok(cfg.command); const prCreateTemplate = cfg.command!["pr/create"].template; - + // Should have inline workflow content (no longer uses PR Author component) assert.match(prCreateTemplate, /## Goal/); assert.match(prCreateTemplate, /Create a pull request/); assert.match(prCreateTemplate, /Interpret Arguments/); assert.match(prCreateTemplate, /Load & Analyze Changes/); - + assert.doesNotMatch(prCreateTemplate, /<%/); }); @@ -577,7 +579,7 @@ describe("applyCommandsConfig", () => { assert.ok(cfg.command); const ticketDevTemplate = cfg.command!["ticket/dev"].template; - + // Should have replaced components assert.match(ticketDevTemplate, /Development Flow Navigation Guide/); // PR Author content is now inline in pr/create, not embedded here @@ -637,7 +639,7 @@ describe("applyCommandsConfig", () => { await applyCommandsConfig(cfg as never, process.cwd()); assert.ok(cfg.command); - + const commitTemplate = cfg.command!["commit"].template; assert.match(commitTemplate, /pass `uncommitted: true`/); assert.doesNotMatch(commitTemplate, /<%/); @@ -650,10 +652,10 @@ describe("applyCommandsConfig", () => { await applyCommandsConfig(cfg as never, process.cwd()); assert.ok(cfg.command); - + const commitTemplate = cfg.command!["commit"].template; const prCreateTemplate = cfg.command!["pr/create"].template; - + assert.match(commitTemplate, /pass `uncommitted: true`/); assert.match(prCreateTemplate, /base branch/); }); diff --git a/packages/web/src/content/docs/docs/reference/commands/index.mdx b/packages/web/src/content/docs/docs/reference/commands/index.mdx index f52e1e8..52c43f6 100644 --- a/packages/web/src/content/docs/docs/reference/commands/index.mdx +++ b/packages/web/src/content/docs/docs/reference/commands/index.mdx @@ -10,7 +10,7 @@ Kompass ships workflow-oriented commands authored as explicit templates in `pack - Workflow: `/ask`, `/branch`, `/commit`, `/commit-and-push`, `/merge`, `/rmslop` - Guidelines: `/learn`, `/skill/create`, `/skill/optimize` - Ticket: `/ticket/ask`, `/ticket/create`, `/ticket/dev`, `/ticket/plan`, `/ticket/plan-and-sync` -- PR: `/pr/create`, `/pr/fix`, `/pr/review`, `/review` +- PR: `/pr/create`, `/pr/fix`, `/pr/analyze`, `/pr/review`, `/review` - Orchestration: `/dev`, `/ship`, `/todo`, `/loop/pr/fix` ## What makes them different @@ -154,7 +154,15 @@ Addresses PR feedback or CI failures by making fixes and responding to review th - usage: `/pr/fix [pr-or-auto-or-context]` - arguments: optional PR ref, `auto`, or additional fix guidance -- expected tools: `pr_load`, file-edit tools, validation commands, `question` unless `auto`, `git push`, `pr_sync` +- expected tools: `command_expansion(pr/analyze)`, file-edit tools, validation commands, `question` unless `auto`, `git push`, `pr_sync` + +### `/pr/analyze` + +Loads and filters PR review history into an actionable brief, excluding resolved and outdated threads. + +- usage: `/pr/analyze [pr-or-context]` +- arguments: optional PR ref or analysis guidance +- expected tools: `pr_load` ### `/loop/pr/fix` diff --git a/packages/web/src/content/docs/docs/reference/commands/loop-pr-fix.mdx b/packages/web/src/content/docs/docs/reference/commands/loop-pr-fix.mdx index a92a51c..e853e67 100644 --- a/packages/web/src/content/docs/docs/reference/commands/loop-pr-fix.mdx +++ b/packages/web/src/content/docs/docs/reference/commands/loop-pr-fix.mdx @@ -11,9 +11,9 @@ Use `/loop/pr/fix` when a PR should be advanced hands-off until both CI and revi ## Behavior -- loads the PR and stores the PR URL and number +- delegates PR analysis to `/pr/analyze` to load and filter review history - watches `gh pr checks --watch` until the latest checks finish -- reloads the PR after checks finish +- reloads PR feedback via `/pr/analyze` after checks finish - delegates actionable CI failures and PR feedback to `/pr/fix auto` - repeats after each push until no actionable CI failures or PR feedback remain - stops on failing validation, failed push, failed PR replies, or no-change feedback loops @@ -21,4 +21,5 @@ Use `/loop/pr/fix` when a PR should be advanced hands-off until both CI and revi ## Related - `/pr/fix` +- `/pr/analyze` - `/pr/review` diff --git a/packages/web/src/content/docs/docs/reference/commands/pr-analyze.mdx b/packages/web/src/content/docs/docs/reference/commands/pr-analyze.mdx new file mode 100644 index 0000000..254974c --- /dev/null +++ b/packages/web/src/content/docs/docs/reference/commands/pr-analyze.mdx @@ -0,0 +1,33 @@ +--- +title: /pr/analyze +description: Load and filter PR review history into an actionable brief. +--- + +## Purpose + +Use `/pr/analyze` to load a pull request's full review history, filter out resolved and outdated threads, and return a compact actionable brief. The full thread history stays in the subagent's isolated context window — only filtered, actionable feedback reaches the caller. + +## Usage + +```text +/pr/analyze [pr-or-context] +``` + +## Typical flow + +- load the PR and full review history via `pr_load` +- filter out resolved and outdated threads +- detect effectively-resolved threads (author reply + later commit) +- categorize remaining threads by severity (critical, important, style, noise, question) +- partition actionable threads into file-disjoint groups for parallel implementation +- return a structured markdown brief with PR metadata, thread list, and group partition + +## Common tools + +- `pr_load` + +## Related + +- `/pr/fix` +- `/loop/pr/fix` +- `/pr/review` diff --git a/packages/web/src/content/docs/docs/reference/commands/pr-fix.mdx b/packages/web/src/content/docs/docs/reference/commands/pr-fix.mdx index d9dcca0..d975fac 100644 --- a/packages/web/src/content/docs/docs/reference/commands/pr-fix.mdx +++ b/packages/web/src/content/docs/docs/reference/commands/pr-fix.mdx @@ -15,7 +15,7 @@ Use `/pr/fix` when a PR already exists and review feedback or CI failures need a ## Typical flow -- load the PR and existing review state +- delegate PR analysis to `/pr/analyze` to load and filter review history into an actionable brief - implement the requested review or CI fixes on the current branch - run relevant validation - in default mode, show the fix summary and wait for user approval before commit, push, or replies @@ -24,7 +24,7 @@ Use `/pr/fix` when a PR already exists and review feedback or CI failures need a ## Common tools -- `pr_load` +- `command_expansion(pr/analyze)` - `question` - `apply_patch` - `pr_sync`