Skip to content

feat(core): extract PR mutation handlers (approve, reject, edit)#167

Open
galligan wants to merge 1 commit into
fire-6/feedback-handlersfrom
fire-7/pr-handlers
Open

feat(core): extract PR mutation handlers (approve, reject, edit)#167
galligan wants to merge 1 commit into
fire-6/feedback-handlersfrom
fire-7/pr-handlers

Conversation

@galligan

@galligan galligan commented Feb 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Extract approveHandler, rejectHandler, editHandler to core
  • Simplest handlers: validate input → call GitHubClient method → return Result
  • Each handler is ~50-80 lines with typed input/output (FIRE-7)

Test plan

  • bun run check passes
  • bun test passes (288 tests)

🤘🏻 In-collaboration-with: Claude Code

Greptile Summary

Extracts PR mutation handlers (approveHandler, rejectHandler, editHandler) from CLI to core package for code reuse.

  • approve.ts and reject.ts are clean, straightforward implementations
  • edit.ts has critical bugs in comment editing:
    • extractNumericId() won't correctly decode GitHub node IDs (needs base64 decoding)
    • Missing fallback to entry.database_id field
    • Missing support for review_comment subtype (only handles issue comments)
  • The CLI implementation (apps/cli/src/commands/edit.ts) has the correct approach that should be replicated

Confidence Score: 2/5

  • Not safe to merge - critical bugs in edit handler will cause runtime failures
  • The editHandler has three critical bugs that will cause failures when editing comments: incorrect numeric ID extraction, missing database_id fallback, and missing review_comment support. The approve and reject handlers are fine.
  • packages/core/src/handlers/edit.ts requires fixes before merging

Important Files Changed

Filename Overview
packages/core/src/handlers/approve.ts New approve handler - validates input, authenticates, and submits APPROVE review. Clean implementation, no issues found.
packages/core/src/handlers/reject.ts New reject handler - validates input, authenticates, and submits REQUEST_CHANGES review. Clean implementation, no issues found.
packages/core/src/handlers/edit.ts New edit handler - has critical bug in extractNumericId() and missing review_comment handling. The comment editing logic will fail for entries without database_id field.
packages/core/src/handlers/index.ts Export file - adds exports for approve, reject, and edit handlers. No issues.

Fix All in Claude Code Fix All in Codex

Last reviewed commit: 8889f7c

@linear

linear Bot commented Feb 22, 2026

Copy link
Copy Markdown

Add three transport-agnostic PR mutation handlers:
- approveHandler: submit APPROVE review via REST API
- rejectHandler: submit REQUEST_CHANGES review via REST API
- editHandler: polymorphic — edit PR metadata (title, body, base, labels,
  milestone) or edit a comment body; routes by classifyId()

All validate repo format, authenticate via detectAuth, and return
Result<T, Error>. No transport-specific code.

🤘🏻 In-collaboration-with: [Claude Code](https://claude.com/claude-code)
@galligan galligan force-pushed the fire-6/feedback-handlers branch from 07f873a to c806561 Compare February 22, 2026 03:51
@galligan galligan changed the title feat(core): extract PR mutation handlers to core feat(core): extract PR mutation handlers (approve, reject, edit) Feb 22, 2026
@galligan galligan marked this pull request as ready for review February 22, 2026 04:07

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

4 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +202 to +209
const numericId = extractNumericId(entry.id);
if (!numericId) {
return Result.err(
new ValidationError({
message: `Cannot determine numeric ID for comment: ${entry.id}`,
})
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

extractNumericId(entry.id) won't work reliably - entry.database_id is optional and not always populated. Should use the same approach as apps/cli/src/commands/edit.ts:168-175 which tries entry.database_id first, then falls back to base64 decoding:

Suggested change
const numericId = extractNumericId(entry.id);
if (!numericId) {
return Result.err(
new ValidationError({
message: `Cannot determine numeric ID for comment: ${entry.id}`,
})
);
}
// Prefer stored database_id (synced from GitHub API)
const numericId = entry.database_id ?? extractNumericId(entry.id);
if (!numericId) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/core/src/handlers/edit.ts
Line: 202-209

Comment:
`extractNumericId(entry.id)` won't work reliably - `entry.database_id` is optional and not always populated. Should use the same approach as `apps/cli/src/commands/edit.ts:168-175` which tries `entry.database_id` first, then falls back to base64 decoding:

```suggestion
  // Prefer stored database_id (synced from GitHub API)
  const numericId = entry.database_id ?? extractNumericId(entry.id);
  if (!numericId) {
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Comment on lines +222 to +231
}

/** Extract numeric ID from various GitHub ID formats. */
function extractNumericId(id: string): number | null {
// Try direct numeric
const num = Number(id);
if (!Number.isNaN(num) && num > 0) {
return num;
}
// Try extracting trailing number from node ID patterns

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

extractNumericId() is too simplistic - GitHub node IDs are base64-encoded (e.g., "IC_kwDO..."). The regex won't extract the numeric ID correctly. Use the base64 decoding approach from apps/cli/src/commands/edit.ts:148-162:

Suggested change
}
/** Extract numeric ID from various GitHub ID formats. */
function extractNumericId(id: string): number | null {
// Try direct numeric
const num = Number(id);
if (!Number.isNaN(num) && num > 0) {
return num;
}
// Try extracting trailing number from node ID patterns
function extractNumericId(id: string): number | null {
// Try direct numeric
const num = Number(id);
if (!Number.isNaN(num) && num > 0) {
return num;
}
// Try base64 decoding for GraphQL node IDs
try {
const decoded = Buffer.from(id, "base64").toString("utf8");
const matches = decoded.match(/\d+/g);
const last = matches?.at(-1);
return last ? Number(last) : null;
} catch {
return null;
}
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/core/src/handlers/edit.ts
Line: 222-231

Comment:
`extractNumericId()` is too simplistic - GitHub node IDs are base64-encoded (e.g., "IC_kwDO..."). The regex won't extract the numeric ID correctly. Use the base64 decoding approach from `apps/cli/src/commands/edit.ts:148-162`:

```suggestion
function extractNumericId(id: string): number | null {
  // Try direct numeric
  const num = Number(id);
  if (!Number.isNaN(num) && num > 0) {
    return num;
  }
  // Try base64 decoding for GraphQL node IDs
  try {
    const decoded = Buffer.from(id, "base64").toString("utf8");
    const matches = decoded.match(/\d+/g);
    const last = matches?.at(-1);
    return last ? Number(last) : null;
  } catch {
    return null;
  }
}
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Comment on lines +211 to +214
const editResult = await client.editIssueComment(
owner,
repo,
numericId,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Only handles issue comments - missing review_comment support. Check entry.subtype and call client.editReviewComment() for review comments (see apps/cli/src/commands/edit.ts:622-626)

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/core/src/handlers/edit.ts
Line: 211-214

Comment:
Only handles issue comments - missing `review_comment` support. Check `entry.subtype` and call `client.editReviewComment()` for review comments (see `apps/cli/src/commands/edit.ts:622-626`)

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8889f7c379

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +99 to +100
const normalized = normalizeShortId(input.id);
const resolved = resolveShortId(normalized);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Populate short-ID cache before resolving edit target

This path resolves @shortid via resolveShortId only, but it never loads entries or calls buildShortIdCache, so in a fresh process the map is empty and valid short IDs fail with Could not resolve short ID. That makes edit by short ID non-functional unless some previous command happened to warm the in-memory cache first.

Useful? React with 👍 / 👎.

);
}

const editResult = await client.editIssueComment(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Route review-comment edits to the review endpoint

The handler always calls editIssueComment, but GitHub review comments require the pull-review endpoint (editReviewComment). When the cached entry is a review_comment, this uses the wrong API route and edit requests fail for code-review comments, which are a primary feedback type in this tool.

Useful? React with 👍 / 👎.

Comment on lines +231 to +233
// Try extracting trailing number from node ID patterns
const match = id.match(/(\d+)$/);
return match ? Number(match[1]) : null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop deriving REST comment IDs from node-id suffixes

Extracting the REST comment ID by regexing trailing digits from entry.id is unreliable because entry.id is an opaque GraphQL node ID, not the REST numeric ID. This causes frequent false failures (Cannot determine numeric ID) and can also produce an unrelated number when a node ID happens to end with digits, potentially editing the wrong comment.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant