Conversation
Add a reusable ErrorBoundary class component with three visual levels (root, route, widget) and wire it into the component tree at three strategic points: 1. Root level — wraps the entire AppShell so catastrophic errors show a "Something went wrong, click to reload" screen instead of a white screen. 2. Route level — wraps TaskDetailView and TaskListView in MainContent so a crash in one view doesn't kill the sidebar/navigation. Uses key props to reset boundary state when switching tasks/repos. 3. Widget level — wraps TaskDiffViewer, which parses external git output and is the most likely crash source. Shows a compact inline fallback with a retry button. Each boundary logs the error and component stack to the console via componentDidCatch and shows a user-friendly fallback with contextual heading, error message, and a retry/reload action. - Add src/ui/components/ErrorBoundary.tsx (reusable, three levels) - Wrap AppShell render in root-level ErrorBoundary - Wrap TaskDetailView and TaskListView in route-level boundaries - Wrap TaskDiffViewer in widget-level boundary SUSTN-Task: 2192899f-1194-4f25-b94a-b5227d9374eb
Full lifecycle tracking for PRs opened by SUSTN — from creation through review cycles to merge. Core: - GitHub API service (gh CLI) for reviews, comments, replies, re-request review - PR lifecycle orchestration: poll GitHub every 2min, classify comments (actionable vs conversational), auto-address via Claude, reply to conversational, re-request review - Heuristic comment classifier (actionable = change requests, conversational = praise/questions/nits) - PR state machine: opened → in_review → changes_requested → addressing → re_review_requested → approved → merged - Max review cycles guard (default 5, configurable) → flags needs_human_attention Data model (migration 16): - pr_state, pr_number, pr_review_cycles columns on tasks - pr_reviews table (synced from GitHub) - pr_comments table (synced from GitHub, with classification + addressed_in_commit tracking) Rust: - engine_address_review command (fresh Claude session with PR diff + review comments as context) - run_gh_api / run_gh_api_post commands for GitHub API access UI: - PR state badge on TaskRow (color-coded by lifecycle state) - PR state chip in TaskDetailHeader with review cycle counter - PR Lifecycle settings in Integrations (toggle + max cycles) - Auto-sets prState/prNumber when PRs are created (manual, auto, scheduler) Hooks: - usePrLifecyclePoller mounted in AppShell (2min polling interval) - Event listeners for agent:review-addressed / review-address-failed New files: - src/core/services/github.ts - src/core/services/pr-lifecycle.ts - src/core/db/pr-lifecycle.ts - src/core/api/usePrLifecycle.ts
Overlay synced PR review comments inline in the diff viewer at their exact file/line positions. Comments appear in blue bubbles (vs amber for local SUSTN comments) with: - Reviewer name and classification badge (actionable/conversational) - "Addressed" indicator when the agent has pushed a fix - Reply button that posts via GitHub API using the user's token - Reply text appears as a nested quote below the original comment Also adds comment count indicator in diff header showing how many comments come from the PR. Modified: - TaskDiffViewer: new GitHubPrComment type, GitHubCommentBubble component, merged annotation list, reply handler - TaskDetailView: fetch pr_comments via usePrComments, pass to diff viewer with reply callback
Task no longer transitions to "done" when a PR is created — it stays
in "review" until the PR is approved or merged. This keeps the diff
viewer interactive (inline comments, reply to GH comments) throughout
the entire PR review cycle.
Changes:
- useEngine handleTaskResult: state stays "review" after auto-PR
- useScheduler: same — "review" not "done" after auto-PR
- TaskDetailView: remove handleUpdateState("done") after PR creation,
update sidebar actions (View PR + Mark Done when PR exists,
hide Request Changes since feedback comes from GitHub)
- pr-lifecycle service: set task state to "done" when prState becomes
"approved" or "merged" (the only two terminal states)
The flow is now:
pending → in_progress → review → [PR created, stays review] →
PR approved/merged → done
The PR poller was not syncing comments when a reviewer left inline comments without formally requesting changes. Comments were only fetched inside the CHANGES_REQUESTED branch of the state machine. Fixes: - Sync PR comments on every poll tick, even without a formal review - Backfill pr_state/pr_number for tasks created before lifecycle wiring (queries pr_url IS NOT NULL AND pr_state IS NULL on startup) - Add verbose debug logging throughout the poller: - Tick start, settings check, active PR count - PR status fetch results (state, merged, reviewDecision) - Review count and details (reviewer, state, timestamp) - Comment sync count - Backfill operations
Two bugs fixed: 1. Comments were only synced when reviewer formally requested changes. Now comments are synced on every poll tick regardless of review state — plain comments, approvals, etc all get their inline comments pulled in. 2. Replies posted from SUSTN's diff viewer were getting synced back as separate comments on the next poll. Now we track reply bodies in the DB and skip GitHub comments whose body matches one of our recorded replies. Also refactored processTaskPr to: - Sync + classify comments BEFORE branching on review state - Use DB-sourced comments for actionable/conversational decisions (instead of raw GitHub comments) so classification is persisted - Disabled auto-reply for conversational comments (heuristic not reliable enough) — user can reply manually from diff viewer
Re-enables fully automated replies to conversational review comments. The heuristic classifier drafts a reply (or falls back to "Thanks for the feedback!"), posts it via gh api, and records it in pr_comments so it won't be re-synced as a duplicate.
Three fixes:
1. Classifier now defaults to actionable — only marks comments as
conversational if they're clearly praise ("nice!", "lgtm", "👍")
or explicit nits ("nit: ..."). Everything else (questions,
suggestions, concerns) is actionable.
2. Comments are now processed (classified, replied to, addressed)
even without a formal CHANGES_REQUESTED review. Previously the
agent only acted when a reviewer clicked "Request changes" —
now inline comments alone trigger the full lifecycle.
3. Removed the classification badge from the diff viewer UI —
it was noise. Only the "Addressed" indicator remains.
…ssion Drop the regex-based comment classifier entirely. All review comments now go to Claude in a single session that resumes the original task session, preserving the agent's reasoning context. The prompt asks Claude to handle EVERY comment: - Code changes needed → make them and commit - Question about reasoning → explain (Claude has context from the original session that wrote the code) - Praise/acknowledgment → draft a brief thanks Claude returns structured JSON with per-comment replies and whether code was changed, which the poller uses to: - Post replies to GitHub via gh api - Mark comments as addressed in the DB - Push code changes and re-request review Rust changes: - engine_address_review now accepts resume_session_id parameter - Updated prompt to request unified classification + action - Session ID saved back to task for future review cycles This means the session accumulates context across review cycles — each round builds on the previous one.
Claude was returning comment_id: null because the prompt wasn't explicit enough about requiring the IDs back. Two fixes: 1. Updated prompt to use COMMENT_ID tag format, emphasize "MUST return the numeric ID", add example with real-looking number, and add "Do NOT use null" instruction 2. Added fallback in TS — if Claude still returns null IDs but the reply count matches the comment count, zip them positionally. Logs when this happens so we can track reliability. Also updated the comment format from [Comment ID: X] to [COMMENT_ID: X] to match the prompt's CRITICAL instruction.
…ctly The worker's execute_task() overrides the prompt with its own resume template when resume_session_id is set — it formats a generic "address the feedback" prompt and asks for files_modified/summary JSON, completely ignoring our carefully crafted prompt that asks for per-comment replies with comment_ids. Fix: engine_address_review now calls invoke_claude_cli directly, managing branch checkout and SHA retrieval itself. This ensures Claude sees our exact prompt with COMMENT_ID tags and returns the replies format we need to post per-comment responses on GitHub.
Three improvements:
1. Remove the "Addressed N review comment(s) in commit..." summary
comment posted to GitHub after addressing reviews. Per-comment
replies already explain what was done — the summary was noise.
2. PR state changes in the activity timeline now show human-readable
labels ("PR moved to In Review", "PR moved to Addressing Feedback")
instead of raw "pr_state_change" text. Uses GitPullRequest icon.
3. Redesigned GitHub comment bubbles in the diff viewer:
- Card-based layout with header/body/footer sections
- Reviewer avatar initial + name in header bar
- Green "Resolved" badge with checkmark when addressed
- Reply shown in a dedicated footer section with reply icon
- Reply form with keyboard shortcut hint, matching the local
comment form style
- Proper visual hierarchy and spacing
Complete redesign of the PR review comment overlay: - GitHub-style threaded layout with avatar → card → timeline line - Reviewer avatar with colored gradient (blue for reviewer, green for SUSTN reply) - Comment card with header bar (name + resolved badge) and body with proper text sizing and word wrapping - Reply shown as a separate threaded card connected by a vertical timeline line, labeled "You via SUSTN" - Full text is always visible (break-words, no truncation) - Stronger visual boundaries: rounded-lg border, bg-background body, muted header - Reply form: larger textarea, proper focus ring, keyboard hint
The max-w-xl on the comment container was leaving dead space on the right side. Now comments fill the available width. Also tightened gaps between avatar and card (2.5 → 2), reduced reply card padding, and used rounded-md instead of rounded-lg for crisper edges.
Replace the oversized threaded layout with a compact single-card design: reviewer header, comment body, and reply all in one contained card (max 480px). No avatars, no timeline lines, no separate reply cards. - 12px base text, tight padding (2.5/2px) - Reply nested inline as a bordered section within the same card - Resolved state shown with green header + checkmark badge - Reply form compact with 2-row textarea
Replace cryptic "5 (5 from PR)" with clear "5 GitHub comments". Also drops the local comment count from the label since inline SUSTN comments are already visible in the diff.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Added verbose logging after engine_address_review returns to trace exactly what happens: summary length, JSON parse result, reply count, push result. This will show in the console why the state gets stuck. Also wrapped the outer catch in a nested try/catch so the task state ALWAYS transitions out of "addressing" even if the DB update itself fails.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.