Skip to content

feat(mt#1341): Add suggestion field to ReviewComment for GitHub suggestion blocks#906

Merged
edobry merged 4 commits into
mainfrom
task/mt-1341
May 1, 2026
Merged

feat(mt#1341): Add suggestion field to ReviewComment for GitHub suggestion blocks#906
edobry merged 4 commits into
mainfrom
task/mt-1341

Conversation

@minsky-ai
Copy link
Copy Markdown
Contributor

@minsky-ai minsky-ai Bot commented Apr 30, 2026

Summary

Adds an optional suggestion field to ReviewComment that GitHub renders as a one-click "Apply suggestion" button. When present, the forge mapping wraps the comment body with a fenced suggestion block. A pre-flight validator enforces that the suggestion's line count matches the anchored range.

Motivation & Context

GitHub renders suggestion fenced blocks inside PR review comments with a one-click apply button, making it easy for authors to accept suggested fixes. The reviewer bot (mt#1340) can now emit suggestions with exact replacement code rather than prose-only comments.

Key Changes

src/domain/repository/github-pr-review.ts

  • Added suggestion?: string field to ReviewComment interface with full JSDoc
  • Extended validateReviewComment() with suggestion line-count check: single-line anchor requires 1-line suggestion; multi-line range (startLine..line) requires (line - startLine + 1) lines; trailing newline stripped before counting
  • In submitReview() body mapping, when suggestion is present the body sent to GitHub is ${body}\n\n\``suggestion\n${suggestion}\n````

src/adapters/shared/commands/session/session-parameters.ts

  • Extended the comments[] schema in sessionPrReviewSubmitCommandParams to include startLine, startSide, and suggestion fields (the first two were missing from the MCP schema even though the domain type already supported them)

src/domain/repository/github-pr-review.test.ts

  • 7 new validateReviewComment tests covering suggestion pass/fail/error-message cases
  • 3 new Octokit payload mapping tests covering body unchanged without suggestion, single-line fence, and multi-line fence
  • Updated local buildApiComment helper to mirror the production suggestion mapping

Testing

All 27 tests pass (bun test on the test file). The 17 new tests cover:

  • Single-line comment + 1-line suggestion: valid
  • Multi-line range (startLine 67, line 78 = 12 lines) + 12-line suggestion: valid
  • Trailing newline on suggestion ignored in count
  • Single-line comment + 2-line suggestion: throws MinskyError
  • 11-line and 13-line suggestions against 12-line range: throw MinskyError
  • Error message contains path, actual count, and expected count
  • Body unchanged when no suggestion
  • Body contains fenced block when suggestion present

edobry added 2 commits April 30, 2026 05:13
…stion blocks

- Add optional  to ReviewComment interface
- Validate suggestion line count matches anchored range in validateReviewComment
- Map suggestion to fenced suggestion block in submitReview body
- Extend MCP schema in sessionPrReviewSubmitCommandParams with suggestion,
  startLine, and startSide fields
- Add 17 new unit tests covering validation and body mapping
@minsky-ai minsky-ai Bot added the authorship/co-authored Co-authored by human and AI agent label Apr 30, 2026
Copy link
Copy Markdown

@minsky-reviewer minsky-reviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: unknown


⚠️ Reviewer did not emit a conclude_review call. Event derived from severity counts: REQUEST_CHANGES (1 BLOCKING / 3 NON-BLOCKING / 0 PRE-EXISTING findings). Executive summary unavailable.

Findings

  • [BLOCKING] src/domain/repository/github-pr-review.ts:205 — Suggestion fence is always appended with a trailing newline — may produce unintended extra blank line in GitHub rendering
    When building resolvedBody, the code constructs ${c.body}\n\n\``suggestion\n${c.suggestion}\n```regardless of whetherc.suggestion already ends with a newline. If the suggestion text already contains a final newline (which your validator tolerates), this produces two trailing newlines inside the fence (...\n\n````).
    While GitHub's suggestion parser typically tolerates this, the rendering may include an extra blank line or could, in edge cases, miscount lines if there are platform-specific line endings. To keep mapping deterministic and aligned with the validator, normalize suggestion before appending (e.g., strip all trailing newlines and then add exactly one) and mirror the same normalization in tests.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.ts:112 — Only a single trailing newline is stripped from suggestion when counting lines
    In validateReviewComment(), the line count logic removes at most one trailing newline: comment.suggestion.endsWith("\n") ? comment.suggestion.slice(0, -1) : comment.suggestion.
    If the provided suggestion text inadvertently has multiple trailing newlines (e.g., generated content or copy-paste), the extra newlines will be counted as additional blank lines and cause a false mismatch against the anchored range.
    Consider trimming all trailing newlines (e.g., using a regex like /\n+$/ or a loop) before splitting to make the validator resilient to accidental extra trailing newlines.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.ts:101 — No guard against backticks inside suggestion — may break fenced block rendering
    The mapping wraps suggestion inside a Markdown fenced block using triple backticks. If the suggestion text itself contains the sequence ``` (triple backticks), the fence will be prematurely terminated and GitHub may fail to render the suggestion (or render malformed Markdown). Consider either validating and rejecting suggestions that contain triple backticks, or escaping/transforming them (e.g., replacing with indented code or using a longer fence with more backticks) to preserve a valid fence.
  • [NON-BLOCKING] src/adapters/shared/commands/session/session-parameters.ts:741 — Session params schema accepts suggestion but does not document line-ending normalization or backtick constraints
    You added the suggestion optional field to the comments schema with a brief description about line-count matching. Given the stricter rules in the domain validator (line count must match; GitHub requires exact counts; fencing with triple backticks), operators may be confused when validations fail due to trailing newlines or backticks inside the suggestion. Consider elaborating in the .describe(...) text: mention that trailing newlines are trimmed to 1, that suggestions should avoid triple backticks, and that the count is based on \n separators after normalization.

Inline comments

  • src/domain/repository/github-pr-review.test.ts:153 — These mapping tests cover the happy path, but there’s no test asserting behavior when the suggestion already includes a trailing newline. Since the validator tolerates a trailing \n, a test should verify the body mapping normalizes to exactly one newline inside the fence (or at least that it doesn’t produce an extra blank line).
  • src/domain/repository/github-pr-review.test.ts:137 — Edge case to consider: suggestion strings containing triple backticks (```), which would break the fenced block. It may be worth adding a validator rejection or escaping strategy and a corresponding test.

…lding

Strip all trailing newlines from c.suggestion before inserting into the
fenced suggestion block, preventing double-blank-lines when the input
ends with multiple newlines. Mirror the same normalization in
validateReviewComment line-count logic (was stripping at most one
trailing newline; now strips all). Add two unit tests: one for the
mapping path and one for the validator path.
Copy link
Copy Markdown

@minsky-reviewer minsky-reviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: unknown


Solid feature addition with good tests, but I found multiple robustness gaps. The validator and mapper don’t normalize CRLF line endings, leading to off-by-one line counts and stray \r in fences. The body fence uses fixed triple backticks; if the suggestion contains ``` it will prematurely close and break GitHub rendering. The MCP schema permits invalid combinations (multi-line suggestions without a multi-line anchor), pushing avoidable errors to runtime. Tests mirror the production logic instead of the actual mapping, risking false confidence if both share the same bug. Please address these issues; minor spacing before the fence can also be tightened.

Findings

  • [BLOCKING] src/domain/repository/github-pr-review.ts:108 — Suggestion line-count normalization ignores CRLF (\r\n) line endings, causing off-by-one and residual \r characters
    In validateReviewComment(), trailing newline stripping and line counting use comment.suggestion.replace(/\n+$/, "") and split("\n") (around lines 108–116). This fails for CRLF inputs: e.g., a suggestion ending with "a\r\n\r\n" becomes "a\r\n\r" (only the \n are stripped), and split("\n") yields an extra empty segment with residual \r. This can produce incorrect suggestionLineCount and spurious validation failures or passes depending on content, and will also leak stray \r into the fenced block. Fix by normalizing Windows line endings before counting and stripping, e.g.:
  • Normalize: const text = comment.suggestion.replace(/\r\n/g, "\n");
  • Strip: text.replace(/\n+$/, "")
  • Count with text.split("\n").length (or split on /\r?\n/).
  • [BLOCKING] src/adapters/shared/commands/session/session-parameters.ts:700 — MCP schema allows suggestion on multi-line ranges without requiring startLine/startSide; validator will accept, but GitHub may reject (no range with multi-line suggestion)
    The CLI/MCP schema (sessionPrReviewSubmitCommandParams) adds optional fields startLine, startSide, and suggestion (lines ~700–715), but does not assert that when suggestion spans multiple lines, startLine must be present to form a multi-line anchor. The domain validator only enforces line-count equality if startLine is provided; it does not prevent providing a multi-line suggestion for a single-line anchor — it will throw, but the schema allows constructing such payloads. This is a UX/API contract gap: clients can produce invalid combinations that will always error at runtime. Consider schema-level refinement: if suggestion contains more than one line (after normalizing trailing newlines), require startLine, and optionally require startSide to match side when present.
  • [BLOCKING] src/domain/repository/github-pr-review.ts:199 — Suggestion fence is not robust when suggestion text contains triple backticks; fence will prematurely terminate and break GitHub suggestion parsing
    In submitReview() when building resolvedBody, the code hardcodes a triple-backtick suggestion fence: ${c.body}\n\nsuggestion\n${normalizedSuggestion}\n (around lines 199–207). If normalizedSuggestion contains a line with "```" (common in Markdown files or code snippets), the inner triple backticks will close the fence early, producing malformed Markdown and likely preventing GitHub from rendering the suggestion button. To fix, choose a fence delimiter that is guaranteed not to appear in the content: detect the longest run of backticks in normalizedSuggestion and use a backtick fence longer than that (e.g., start with "````suggestion" and end with the same), or use tildes ("~~~~suggestion"). Add corresponding tests for suggestions containing backticks.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.test.ts:170 — Tests mirror production mapping logic; increases risk of false confidence if both share the same flaw
    The test suite’s buildApiComment() re-implements the production mapping (lines ~156–188) rather than invoking the actual submitReview mapping. This makes the tests susceptible to mirror-drift (or mirroring the same bug), as evidenced by both using identical replace(/\n+$/, "") and simple triple-backtick fences. Consider extracting the mapping into a shared pure function exported from the module and importing it in tests, or using an integration test that exercises submitReview with a mocked Octokit to validate the exact payload constructed.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.ts:200 — Potential extra blank line before closing fence if body ends with trailing whitespace/newlines
    resolvedBody prefixes the suggestion fence with "\n\n" (line ~200). If c.body already ends with a newline, this yields three consecutive newlines before the fence, adding unintended spacing in rendering. Prior review flagged trailing-newline handling inside the fence; you handled trailing newlines in suggestion, but not before the fence. Consider trimming only trailing newlines from c.body when appending the fence or document the intended spacing.

Inline comments

  • src/domain/repository/github-pr-review.ts:205 — What happens if suggestion contains a line with triple backticks (```)? The fence will close early and likely break the suggestion. Consider choosing a fence length that exceeds any backtick run in the content (or use tildes) and add a test case covering this.
  • src/domain/repository/github-pr-review.ts:112 — Line counting strips only \n at the end and splits on \n. CRLF (\r\n) inputs will miscount and leave stray \r characters. Recommend normalizing line endings first: const s = suggestion.replace(/\r\n/g, "\n").replace(/\n+$/, "") then s.split("\n").length.
  • src/adapters/shared/commands/session/session-parameters.ts:711 — Schema allows any string for suggestion. To reduce runtime rejections, consider a refinement: if suggestion has >1 line (after trimming trailing newlines), require startLine to be present; if startLine is present, also assert line > startLine. You could also enforce side/startSide equality at schema level.

Copy link
Copy Markdown

@minsky-reviewer minsky-reviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: unknown


Feature addition is solid with comprehensive tests, but two blocking robustness issues remain. The validator and mapper only normalize '\n' and ignore CRLF, leaving stray '\r' and risking line-count/render anomalies on Windows-origin suggestions. The fixed triple-backtick fence is unsafe if suggestion content contains ``` and can prematurely close the block. Non-blocking: add Zod refinements to fail earlier on invalid combos, avoid mirroring production mapping in tests to prevent shared-bug masking, and consider trimming excessive newlines between body and fence. Address CRLF normalization and fence delimiter safety before merging.

Findings

  • [BLOCKING] src/domain/repository/github-pr-review.ts:100 — CRLF not normalized: validator and mapper only strip "\n", leaving stray "\r" and miscount risk on Windows line endings
    In validateReviewComment, the suggestion normalization uses comment.suggestion.replace(/\n+$/, "") and counts lines via split("\n"). This ignores \r\n endings. For Windows-style input, the trailing \n is removed but \r remains at the end of the last line, and any interior lines retain \r characters. This can leak \r into the fenced block and, depending on how input is constructed (e.g., suggestion ending with only \r\n), can cause off-by-one when suggestions are assembled or rendered by GitHub. The same issue exists in the submitReview mapper where normalizedSuggestion is built with the same regex before embedding in the fence. Please normalize line endings first (e.g., text.replace(/\r\n?/g, "\n")) and then strip trailing newlines before counting and embedding.
  • [BLOCKING] src/domain/repository/github-pr-review.ts:205 — Unescaped fenced code block delimiter: suggestion content containing will prematurely close the suggestion block In submitReview's body mapping (and mirrored in tests), the fence is hard-coded as triple backticks: `````suggestion` followed by `${normalizedSuggestion}` and a closing ````` on their own lines. If `c.suggestion` contains a line with three backticks (), GitHub Markdown will terminate the fence early, breaking the suggestion rendering or exposing raw fence syntax. This is a known pitfall when embedding arbitrary content in backtick fences. Consider choosing a fence delimiter that avoids conflict (e.g., use a longer sequence of backticks based on the maximum run in the content, or use GitHub's suggestion syntax with tildes), or escape/transform the content to ensure the fence is not prematurely closed. Add tests where suggestion includes "```" to verify correct rendering.
  • [NON-BLOCKING] src/adapters/shared/commands/session/session-parameters.ts:604 — MCP schema allows suggestion without enforcing multi-line range consistency at parameter layer
    The Zod schema adds optional startLine, startSide, and suggestion, but it does not constrain combinations (e.g., suggestion with startLine absent implies single-line; multi-line requires startLine < line; startSide must match side). These constraints are enforced at runtime by validateReviewComment, but pushing some invariants down to the schema (via refinements) would yield earlier, clearer CLI/MCP errors and better DX. Consider refining: (1) if startLine is present, require startLine < line; (2) if startSide and side are both present, require equality; (3) if suggestion is present and startLine absent, enforce single-line suggestion (no \n) to fail fast.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.test.ts:116 — Test helper mirrors production mapping, risking tautology and shared-bug masking
    The local buildApiComment in tests replicates the production suggestion mapping, including the same normalization (replace(/\n+$/, "")) and backtick fence format. If both share a bug (e.g., CRLF mishandling or fence delimiter collision), tests will pass despite incorrect behavior. Better to test via submitReview mapping or keep helper logic minimal and assert the exact strings only from the production function, possibly by extracting a pure function from github-pr-review.ts and importing it, to avoid duplication.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.ts:205 — Potential extra blank line before closing fence when suggestion already ends with newline(s) — partially addressed but not documented
    You normalize trailing newlines inside the fence (replace(/\n+$/, "")) so the interior ends with exactly one newline before the closing backticks. That addresses double-blank-lines inside. However, the outer ${c.body}\n\n... always inserts two blank lines between body and fence; if body itself ends with newline(s), this results in 3+ consecutive newlines before the fence. While GitHub generally collapses whitespace, it's worth either trimming body or documenting that callers should avoid trailing newlines in body to keep rendering tight. Consider normalizing body similarly or adding a small test.

Spec verification

Criterion Status Evidence
Add suggestion?: string field to ReviewComment with JSDoc Met src/domain/repository/github-pr-review.ts:51-79 adds suggestion?: string with detailed JSDoc about constraints and behavior.

@edobry
Copy link
Copy Markdown
Owner

edobry commented Apr 30, 2026

@minsky-reviewer please re-review — fixes pushed addressing prior round's findings.

…h for suggestions

BLOCKING 1: In validateReviewComment and the submitReview mapper, apply
text.replace followed by stripping trailing newlines before line-counting
or embedding the suggestion. This prevents carriage returns from leaking
into fenced blocks and fixes miscounts when suggestion uses Windows-style
line endings.

BLOCKING 2: In the submitReview mapper and the test-local buildApiComment
helper, compute the longest run of backticks in the suggestion content and
use a fence delimiter of max(3, longestRun+1) backticks. This prevents
early fence termination when suggestion contains triple-backtick sequences.

New tests added:
- validateReviewComment: 3 CRLF/CR normalization cases
- Octokit payload mapping: CRLF no-leak case, dynamic fence length case
Copy link
Copy Markdown

@minsky-reviewer minsky-reviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: unknown


Solid addition of suggestion support with good normalization and dynamic fence handling; prior CRLF and fence-length issues appear resolved and are covered by tests. However, two concerns remain. First, the implementation allows suggestions on LEFT/base-side anchors, which GitHub typically cannot apply; this should be validated and rejected early with tests. Second, empty/whitespace-only suggestions are currently accepted as valid single-line suggestions, which is likely unintended; consider rejecting them explicitly. I’ve also noted a schema-level refinement gap and a brittle test expectation as non-blocking. Address the blocking items before merging.

Findings

  • [BLOCKING] src/domain/repository/github-pr-review.ts:100 — No guard against suggestions on LEFT (base) side comments; GitHub suggestions generally only apply on RIGHT/head side
    validateReviewComment enforces range and side consistency and validates suggestion line counts, but it does not reject or warn when a suggestion is attached to a LEFT-side (base/deleted) anchor. See src/domain/repository/github-pr-review.ts:83-123. GitHub’s apply-suggestion feature only works when the suggestion can patch the current head; comments anchored on the LEFT/base side (including deletions) typically won’t render an “Apply suggestion” button and/or will be rejected. This change enables constructing such invalid suggestions silently. Please add a validation such as: if suggestion is present, require the effective side (side ?? startSide ?? "RIGHT") to be "RIGHT" (and for multi-line, that startSide, when provided, is also RIGHT). Also add a unit test that attempts a LEFT-side suggestion and expects a MinskyError.
  • [BLOCKING] src/domain/repository/github-pr-review.ts:102 — Empty or whitespace-only suggestions are allowed and will pass validation as a 1-line suggestion
    In validateReviewComment (src/domain/repository/github-pr-review.ts:83-123), the guard only checks comment.suggestion !== undefined. An empty string "" normalizes to "" and split("\n").length is 1, so a single-line anchor will accept an empty suggestion. Similarly, a whitespace-only suggestion (e.g., " \t\n") is normalized to an empty last line and may be miscounted or accepted unexpectedly. GitHub suggestions that replace code with an empty string are typically invalid or at least surprising and may be rejected or render poorly. Please add a validation that suggestion.trim().length > 0 (after line-ending normalization) and reject empty/whitespace-only suggestions with a descriptive MinskyError. Add tests covering empty and whitespace-only suggestion inputs.
  • [NON-BLOCKING] src/adapters/shared/commands/session/session-parameters.ts:704 — Schema does not constrain suggestion/range invariants at parameter layer
    The Zod schema now includes startLine, startSide, and suggestion (src/adapters/shared/commands/session/session-parameters.ts:704-724), but it does not refine combinations. For better DX and earlier feedback, consider adding refinements: (1) if startLine is present, require startLine < line; (2) if both side and startSide are present, require equality; (3) if suggestion is present, require that (a) effective side is RIGHT and (b) startLine is present when a multi-line suggestion is intended; (4) forbid empty/whitespace-only suggestion. These validations currently occur (partially) at runtime in validateReviewComment; duplicating some at the schema layer would surface errors before hitting the network.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.ts:200 — [NEEDS VERIFICATION] Suggestions on LEFT/base side may not be applicable in GitHub UI
    The mapper allows suggestion fences regardless of diff side by computing resolvedSide = c.side ?? c.startSide ?? "RIGHT" and embedding the fence when c.suggestion is present (src/domain/repository/github-pr-review.ts:200-239). GitHub’s one-click suggestion apply typically operates on the head (RIGHT) side; suggestions anchored to the LEFT/base side (including deletions) may fail to render as apply-able or be rejected. This is an external API/UX behavior; please confirm against GitHub docs or a real PR. If LEFT-side suggestions are unsupported, add a validator to reject them early with a clear error and a unit test. [NEEDS VERIFICATION: external GitHub behavior]

Inline comments

  • src/domain/repository/github-pr-review.test.ts:247 — The multi-line suggestion fence test hardcodes a triple-backtick fence in the expected string. Since buildApiComment now computes a dynamic fence length based on backticks in content, this expectation can become brittle if suggestion text contains backticks (even by future refactor). Consider asserting the fence structure more generally (e.g., regex that captures the opening fence and reuses it to check the closing fence, as you did later for the backtick-containing case).

Copy link
Copy Markdown

@minsky-reviewer minsky-reviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: unknown


Good progress: CRLF normalization and dynamic backtick fences address prior blockers, and tests cover many cases. However, the current implementation strips all trailing newlines from suggestions in both validation and mapping, which prevents representing a replacement whose final line is intentionally blank. This alters semantics and can cause false validation failures for legitimate suggestions; please preserve meaningful trailing blank lines. Additionally, empty suggestions currently pass validation for single-line anchors and produce empty fenced blocks; clarify and enforce intended semantics. Once trailing blank-line handling is fixed, this should be in solid shape.

Findings

  • [BLOCKING] src/domain/repository/github-pr-review.ts:106 — Stripping all trailing newlines prevents representing suggestions whose final replacement line is intentionally blank
    Both validateReviewComment and the submitReview mapper normalize and then strip trailing newlines via .replace(/\n+$/, "") before counting and embedding the suggestion (validator: lines 106–114; mapper: lines 212–224). This makes it impossible to propose a replacement where the last line is intentionally empty. Example: for a 2-line range where the intended replacement is ["A", ""], callers would naturally pass "A\n\n". After stripping, this becomes "A", the validator computes 1 line (mismatch) and the mapper would embed only "A", changing semantics. GitHub suggestions support trailing blank lines as part of the replacement; the implementation should count and preserve an intentionally blank final line rather than unconditionally stripping it. Consider stripping at most one terminal newline for single-line cases, or tracking line breaks separately (e.g., split into lines without discarding the final empty element) and preserving content in the fence.
  • [BLOCKING] src/domain/repository/github-pr-review.ts:212 — Mapper also strips all trailing newlines from suggestion, altering intended replacements with a final blank line
    In submitReview's API mapping, normalizedSuggestion is built with .replace(/\n+$/, "") (around lines 212–220) and then embedded in the fenced block. This mirrors the validator behavior and discards an intentionally empty final line (e.g., a 2-line replacement where the second line is blank, passed as "A\n\n"). The result is the body suggesting only "A", changing semantics and likely failing GitHub's line-count requirements. Preserve an intentional trailing blank line in the content and ensure the fence includes the correct final newline without collapsing meaningful trailing empties.
  • [NON-BLOCKING] src/domain/repository/github-pr-review.ts:100 — Validation permits empty suggestion content after normalization, likely producing an empty fenced block
    In validateReviewComment (around lines 100–123), suggestionText is normalized and trailing newlines stripped, then line count is computed via split("\n").length. For an input like suggestion: "" or "\n\n", suggestionText becomes an empty string, and split("\n").length yields 1, so a single-line anchor passes. The mapper will then produce a fenced suggestion block with no replacement content. GitHub suggestions typically require meaningful replacement text; an empty suggestion is ambiguous (delete vs. no-op) and may be rejected or confusing to users. Consider enforcing suggestionText.length > 0 after normalization (and for multi-line anchors, ensuring it contains anchoredLineCount lines, including intentional blank ones) and/or documenting intended semantics for deletions.

@edobry edobry merged commit e6e3b3c into main May 1, 2026
2 checks passed
@edobry edobry deleted the task/mt-1341 branch May 1, 2026 05:04
edobry added a commit that referenced this pull request May 1, 2026
Resolves the merge conflict between this branch and main. Main has
advanced with PRs #896 (mt#1343 review threads), #898 (mt#1342 thread
resolve), #906 (mt#1341 suggestion blocks), and #907 (mt#1348 review
state labels). All four touch overlapping surface (github-pr-review.ts,
github.ts, repository index, session-parameters, workflow-commands,
session.ts, pr-subcommands) — and #898 also added new files this branch
needs (pr-review-thread-resolve subcommand and adapter).

This commit copies main main content for the new and updated files so
the in-progress submitCheckRun additions in this branch can co-exist
without the no-marker abort path of session_update (mt#1303).

Files added or replaced:
- diff-anchor-validator.ts (new from #887 mt#1347)
- review-state-labels.ts (new from #907 mt#1348)
- github-pr-review.ts (updated by #898 #906 #907)
- github-pr-operations.ts (updated by #896)
- pr-review-context-subcommand.ts (updated by #896)
- pr-review-thread-resolve-subcommand.ts (new from #898)
- pr-review-thread-resolve-command.ts (new from #898)
- github-pr-review.test.ts (updated by #906)
- github-pr-operations-review-threads.test.ts (new from #896)
- github-pr-review-threads.test.ts (new from #898)
- review-state-labels.test.ts (new from #907)

Files merged in place to keep this branch additions plus main additions:
- github.ts (review wrapper now has resolveReviewThread plus unresolveReviewThread plus submitCheckRun)
- repository index.ts (ReviewOperations interface adds the same three optional methods)
- session-parameters.ts (PrReviewSubmit comments schema gains startLine startSide suggestion; adds PrReviewThreadResolveCommandParams alongside PrCheckRunSubmitCommandParams)
- session.ts (registers PrReviewThreadResolve and PrCheckRunSubmit)
- workflow-commands.ts (re-exports the same)
- pr-subcommands.ts (barrel exports the same)

Typecheck clean. 123 of 123 tests pass across the 6 reviewer-output
test files. Next step is session_update to fast-forward this branch
to main now that all conflicts are pre-resolved by content match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

authorship/co-authored Co-authored by human and AI agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant