Skip to content

Conversation

@shuhuiluo
Copy link
Collaborator

@shuhuiluo shuhuiluo commented Dec 7, 2025

  • Add state_reason parameter to getIssueEventEmoji/Header
  • Show ⚪ "Issue Closed as Not Planned" for not_planned
  • Show ✅ "Issue Closed" for completed or unspecified
  • Add state_reason field to IssuesPayloadSchema

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Issue status display now respects issue "state reason": issues closed as "not planned" show a distinct indicator (⚪) and the header "Issue Closed as Not Planned"; other closures keep the standard ✅ and "Issue Closed".
    • Event handling updated so incoming issue state reasons are reflected in UI status and messaging.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 7, 2025

Walkthrough

Added support for issue closure reasons. The IssuesPayloadSchema now includes an optional state_reason enum on the issue object. The helper functions getIssueEventEmoji(action, stateReason?) and getIssueEventHeader(action, stateReason?) were extended with an optional stateReason parameter and updated to return different emoji/header when stateReason is "not_planned". Call sites in event formatting code were updated to pass issue.state_reason into these helpers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify the new state_reason enum and .nullish() usage in src/types/events-api.ts correctly reflect intended values and nullability.
  • Review updated signatures in src/formatters/shared.ts for TypeScript typing and any places that may still call the old signatures.
  • Confirm call sites in src/formatters/events-api.ts and src/formatters/webhook-events.ts now pass issue.state_reason in all relevant code paths.
  • Check the conditional branches for "not_planned" produce the exact emoji and header text intended and that localization/formatting expectations are preserved.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main feature: distinguishing between different issue close reasons (completed vs not planned) through emoji and header text changes.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/issue-state-reason

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bfc58ba and 4228137.

📒 Files selected for processing (4)
  • src/formatters/events-api.ts (1 hunks)
  • src/formatters/shared.ts (1 hunks)
  • src/formatters/webhook-events.ts (1 hunks)
  • src/types/events-api.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/types/events-api.ts
  • src/formatters/events-api.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Store context externally - maintain stateless bot architecture with no message history, thread context, or conversation memory
Use <@{userId}> for mentions in messages AND add mentions in sendMessage options - do not use @username format
Implement event handlers for onMessage, onSlashCommand, onReaction, onTip, and onInteractionResponse to respond to Towns Protocol events
Define slash commands in src/commands.ts as a const array with name and description properties, then register handlers using bot.onSlashCommand()
Set ID in interaction requests and match ID in responses to correlate form submissions, button clicks, and transaction/signature responses
Use readContract for reading smart contract state, writeContract for SimpleAccount operations, and execute() for external contract interactions
Fund bot.appAddress (Smart Account) for on-chain operations, not bot.botId (Gas Wallet/EOA)
Use bot.* handler methods directly (outside event handlers) for unprompted messages via webhooks, timers, or tasks - requires channelId, spaceId, or other context stored externally
Always check permissions using handler.hasAdminPermission() before performing admin operations like ban, redact, or pin
User IDs are hex addresses in format 0x..., not usernames - use them consistently throughout event handling and message sending
Slash commands do not trigger onMessage - register slash command handlers using bot.onSlashCommand() instead
Use getSmartAccountFromUserId() to retrieve a user's wallet address from their userId
Include required environment variables: APP_PRIVATE_DATA (bot credentials) and JWT_SECRET (webhook security token)

Files:

  • src/formatters/shared.ts
  • src/formatters/webhook-events.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Provide alt text for image attachments and use appropriate MIME types for chunked attachments (videos, screenshots)

Files:

  • src/formatters/shared.ts
  • src/formatters/webhook-events.ts
🧬 Code graph analysis (1)
src/formatters/webhook-events.ts (1)
src/formatters/shared.ts (2)
  • getIssueEventEmoji (79-90)
  • getIssueEventHeader (95-106)
🔇 Additional comments (3)
src/formatters/webhook-events.ts (1)

74-91: LGTM!

The formatIssue function correctly propagates issue.state_reason to the helper functions. The optional parameter handling aligns with the updated signatures in shared.ts, and this change enables proper differentiation between "completed" and "not planned" issue closures.

src/formatters/shared.ts (2)

79-90: Clean implementation with proper optional handling.

The function correctly handles the stateReason parameter as optional with string | null type, which accommodates GitHub's API where state_reason can be absent, null, or a string value. The logic appropriately checks for "not_planned" only when action === "closed".


95-106: LGTM!

The header function mirrors the emoji function's structure and provides clear, descriptive text for each state. The implementation is consistent and correct.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c1bbed4 and bfc58ba.

📒 Files selected for processing (4)
  • src/formatters/events-api.ts (1 hunks)
  • src/formatters/shared.ts (1 hunks)
  • src/formatters/webhook-events.ts (1 hunks)
  • src/types/events-api.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Store context externally - maintain stateless bot architecture with no message history, thread context, or conversation memory
Use <@{userId}> for mentions in messages AND add mentions in sendMessage options - do not use @username format
Implement event handlers for onMessage, onSlashCommand, onReaction, onTip, and onInteractionResponse to respond to Towns Protocol events
Define slash commands in src/commands.ts as a const array with name and description properties, then register handlers using bot.onSlashCommand()
Set ID in interaction requests and match ID in responses to correlate form submissions, button clicks, and transaction/signature responses
Use readContract for reading smart contract state, writeContract for SimpleAccount operations, and execute() for external contract interactions
Fund bot.appAddress (Smart Account) for on-chain operations, not bot.botId (Gas Wallet/EOA)
Use bot.* handler methods directly (outside event handlers) for unprompted messages via webhooks, timers, or tasks - requires channelId, spaceId, or other context stored externally
Always check permissions using handler.hasAdminPermission() before performing admin operations like ban, redact, or pin
User IDs are hex addresses in format 0x..., not usernames - use them consistently throughout event handling and message sending
Slash commands do not trigger onMessage - register slash command handlers using bot.onSlashCommand() instead
Use getSmartAccountFromUserId() to retrieve a user's wallet address from their userId
Include required environment variables: APP_PRIVATE_DATA (bot credentials) and JWT_SECRET (webhook security token)

Files:

  • src/types/events-api.ts
  • src/formatters/shared.ts
  • src/formatters/events-api.ts
  • src/formatters/webhook-events.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Provide alt text for image attachments and use appropriate MIME types for chunked attachments (videos, screenshots)

Files:

  • src/types/events-api.ts
  • src/formatters/shared.ts
  • src/formatters/events-api.ts
  • src/formatters/webhook-events.ts
🧬 Code graph analysis (2)
src/formatters/events-api.ts (1)
src/formatters/shared.ts (2)
  • getIssueEventEmoji (79-90)
  • getIssueEventHeader (95-106)
src/formatters/webhook-events.ts (1)
src/formatters/shared.ts (2)
  • getIssueEventEmoji (79-90)
  • getIssueEventHeader (95-106)
🔇 Additional comments (4)
src/formatters/webhook-events.ts (1)

77-78: LGTM!

The changes correctly propagate issue.state_reason to the helper functions, enabling proper emoji and header selection based on the issue closure reason.

src/formatters/events-api.ts (1)

77-78: LGTM!

The changes correctly propagate issue.state_reason to the helper functions, maintaining consistency with the webhook event formatter.

src/formatters/shared.ts (2)

76-90: LGTM!

The function correctly handles the new stateReason parameter, distinguishing between issues closed as "not_planned" (⚪) and those completed or with unspecified reason (✅). The optional parameter maintains backward compatibility.


92-106: LGTM!

The function correctly implements differentiated header text based on the stateReason, providing clear user-facing labels that distinguish between planned closures and those marked as not planned.

- Add state_reason parameter to getIssueEventEmoji/Header
- Show ⚪ "Issue Closed as Not Planned" for not_planned
- Show ✅ "Issue Closed" for completed or unspecified
- Add state_reason field to IssuesPayloadSchema

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@shuhuiluo shuhuiluo force-pushed the feat/issue-state-reason branch from bfc58ba to 4228137 Compare December 8, 2025 01:43
@shuhuiluo
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@shuhuiluo shuhuiluo merged commit 8819efc into main Dec 8, 2025
1 check passed
@shuhuiluo shuhuiluo deleted the feat/issue-state-reason branch December 8, 2025 01:51
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.

2 participants