بنقرة واحدة
pr-code-review
// Performs code review on every open PR of TizenFX and replies with technical responses to new comments left by other reviewers. Never asks the author/reviewers for action and never leaves follow-up reminders.
// Performs code review on every open PR of TizenFX and replies with technical responses to new comments left by other reviewers. Never asks the author/reviewers for action and never leaves follow-up reminders.
| name | pr-code-review |
| description | Performs code review on every open PR of TizenFX and replies with technical responses to new comments left by other reviewers. Never asks the author/reviewers for action and never leaves follow-up reminders. |
For every open PR in the samsung/TizenFX repository:
All comments are written in English.
Role boundaries (important):
Follow-up on @X review (unanswered), @author Could you please address..., "please confirm", "checking review status" stylegh CLI (authenticated)gh pr list --repo samsung/TizenFX --state open \
--json number,title,author,updatedAt,isDraft,labels \
--jq '[.[] | select(.isDraft | not)]
| sort_by(.updatedAt) | reverse
| .[] | "\(.number)\t\(.title)\t\(.author.login)\t\(.updatedAt)"'
draft PRs are skippedai-task labeled PRs are reviewed on the same basis (serves as an objective second-pass review of AI-authored PRs)Core rule: if no new commits or human comments have appeared since the last AI activity, skip immediately. (This rule fundamentally blocks the "leave follow-up on a PR where nothing changed" pattern.)
For each PR:
Look up the most recent AI activity timestamp (both review and issue comments):
LAST_AI_AT=$(
{
gh api repos/samsung/TizenFX/pulls/{NUMBER}/comments \
--jq '.[] | select(.body | startswith("🤖 [AI Review]")) | .created_at'
gh api repos/samsung/TizenFX/issues/{NUMBER}/comments \
--jq '.[] | select(.body | startswith("🤖 [AI Review]")) | .created_at'
} | sort | tail -1
)
Check for new commits and new human comments after that timestamp:
NEW_COMMITS=$(gh api repos/samsung/TizenFX/pulls/{NUMBER}/commits \
--jq ".[] | select(.commit.committer.date > \"$LAST_AI_AT\") | .sha" | wc -l)
NEW_HUMAN_COMMENTS=$(
{
gh api repos/samsung/TizenFX/pulls/{NUMBER}/comments \
--jq ".[] | select(.created_at > \"$LAST_AI_AT\")
| select(.body | startswith(\"🤖 [AI Review]\") | not) | .id"
gh api repos/samsung/TizenFX/issues/{NUMBER}/comments \
--jq ".[] | select(.created_at > \"$LAST_AI_AT\")
| select(.body | startswith(\"🤖 [AI Review]\") | not) | .id"
} | wc -l
)
Decision:
LAST_AI_AT is empty → new PR. Proceed to Stage ③ (full-diff review). Stage ④ not needed.NEW_COMMITS == 0 && NEW_HUMAN_COMMENTS == 0 → skip. Reason: no-delta.NEW_COMMITS > 0 → proceed to Stage ③ (delta-range review).NEW_HUMAN_COMMENTS > 0 → proceed to Stage ④ (respond only to new human comments).Review from the perspective of a .NET / C# / Tizen expert developer.
Review priorities:
Public API documentation check (🔴 Critical):
///) or is missing required tags, always flag it.<summary> — all public/protected members<param name="..."> — every parameter<returns> — non-void methods, property getters<exception cref="..."> — explicitly thrown exceptions<typeparam name="..."> — generic types/methods<since_tizen> — TizenFX public API version info (TizenFX convention)internal, private, file-scoped members are out of scope (not flagged)partial class has documentation on the other side, it is OK[EditorBrowsable(EditorBrowsableState.Never)] are excluded — by TizenFX convention, IntelliSense-hidden APIs are not part of the official documentation surfaceFull-file fetch required before flagging missing docs (to prevent false positives):
A raw diff can clip attributes or existing XML doc out of context. Before flagging missing documentation, always fetch the file at the PR branch and verify:
# Get the PR head SHA
HEAD_SHA=$(gh api repos/samsung/TizenFX/pulls/{NUMBER} --jq '.head.sha')
# Fetch full file content (base64 → decode)
gh api repos/samsung/TizenFX/contents/{FILE_PATH}?ref=$HEAD_SHA \
--jq '.content' | base64 -d
Checkpoints:
[EditorBrowsable(EditorBrowsableState.Never)] / [Obsolete] placed right above the member?[EditorBrowsable(...Never)]? (if yes, skip all its members)partial class already contain XML doc? (check via grep -l or repeated gh api .../contents)/// doc already present but only missing a few tags, vs. completely missing?If any one of the four applies, do not flag. Prioritize accuracy over diff-browsing convenience.
Comment style rules (concise + diff-centric):
🤖 [AI Review]```suggestion block when proposing a fix. Avoid prose-only feedback with no diff.@author please address... ❌)Standard template (inline comment):
🤖 [AI Review]
🟡 **Suggestion**: {one-line reason}
```suggestion
{corrected code — in a form directly applicable from GitHub}
```
Critical exception (structural issues that cannot be expressed as a suggestion block — class split, signature change, etc.): prose allowed but keep it within 3 sentences; attach a Before/After code snippet whenever possible.
Public API missing-docs template example:
🤖 [AI Review]
🔴 **Critical**: Public API missing XML documentation. TizenFX public APIs require `<summary>`, `<param>`, `<returns>`, and `<since_tizen>` tags.
```suggestion
/// <summary>
/// {Brief description of what this member does}.
/// </summary>
/// <param name="value">{Description of parameter}.</param>
/// <returns>{Description of return value}.</returns>
/// <since_tizen> {API level} </since_tizen>
public int DoSomething(int value)
```
Line-level inline comment call:
gh api repos/samsung/TizenFX/pulls/{NUMBER}/comments \
-f body="🤖 [AI Review]
🟡 **Suggestion**: Use FrozenDictionary for this read-only mapping.
\`\`\`suggestion
private static readonly FrozenDictionary<string, int> _mapping = new Dictionary<string, int>
{
...
}.ToFrozenDictionary();
\`\`\`" \
-f commit_id="{COMMIT_SHA}" \
-f path="{FILE_PATH}" \
-F line={LINE_NUMBER}
Final summary comment — required behavior
After completing the inline review, post exactly one PR-level summary comment via gh pr comment. Which form to use depends on what was produced:
Case A — at least one inline comment was left (optional; recommended once total ≥ 2):
gh pr comment {NUMBER} --repo samsung/TizenFX --body "🤖 [AI Review]
Left {N} inline comments (🔴 {critical}, 🟡 {suggestion}). See inline for details.
---
*Automated review by AI assistant*"
Case B — no inline comments produced (the diff was reviewed and judged clean): mandatory. Posting nothing is no longer acceptable — the audit trail and the maintainers must be able to see that the review ran.
gh pr comment {NUMBER} --repo samsung/TizenFX --body "🤖 [AI Review]
**Reviewed — no findings.**
**Scope checked:**
- {3–6 bullets enumerating what was actually verified on this diff — see rules below}
No 🔴 critical issues, no 🟡 suggestions to flag.
---
*Automated review — final merge decision rests with human reviewers.*"
Rules for the Scope checked block (Case B):
ArgumentNullException.ThrowIfNull ≥ .NET 6), excluded-pattern intent (e.g., "lines with custom messages left untouched")since_tizen, edge cases handled, no breaking changeCase C — only Stage ④ replies were produced (no Stage ③ inline comments): do not post a Case-B summary; the reply itself is the activity record. (Stage ② already filtered out "skip — no-delta" before we reached this point.)
Target: new human comments after LAST_AI_AT that are not replies to a previous AI comment.
Response principles (strict):
✅ Allowed:
```suggestion block when possible❌ Forbidden:
Could you please..., Please confirm..., "please check")Thanks!, Agreed. alone)Comment format:
🤖 [AI Review]```suggestion block when helpfulReply call (preserving reply-to relationship):
gh api repos/samsung/TizenFX/pulls/{NUMBER}/comments \
-f body="🤖 [AI Review]
{technical response — 1–3 sentences, with suggestion block when possible}" \
-F in_reply_to={COMMENT_ID}
Judgment guide: when unsure whether to respond, choose not to. A comment that doesn't add value to the code is noise.
@-mention)approve / request changes (inline comments only)merge / closeai-task PRs are not skipped)Case A = inline-summary, Case B = clean-review, Case C = replies-only)no-delta / draft / quota-5)