feat(flows): NF-6 Phase 7 — pr-opened/synchronize/closed flows + delete final inline calls #390
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!390
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/flows-phase-7-pr-open-close"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Final NF-6 phase. Wraps the last 2 legacy webhook helpers (
handlePullRequestOpened+handlePullRequestClosed) into baked-in flows, then deletes the inline calls from webhook.ts. Webhook becomes purenormalize → dispatchToFlows.Ships
3 new baked-in flows + 2 new node types:
pr-openedpull_request.openedhandlePullRequestOpened(review-fallback timer + no-workflows shortcut)pr-synchronizepull_request.synchronizepr-closedpull_request.closedhandlePullRequestClosed(worktree cleanup + post-merge rebase probe)Two new node types:
forge.handle_pr_opened— async; awaits the legacy handler so the timer arming + decidePostCiAction launch happens before the run recordsok.forge.handle_pr_closed— sync void; same MUST-stay-sync-void contract asforge.handle_issue_closed_cleanup(anasyncwrapper would silently flip the fire-and-forget semantics into await-completion).Cutover
config/agents.json::node_flows.suppress_legacyadds the 3 new trigger kinds.webhook.tsdrops the inlinehandlePullRequestOpened/handlePullRequestClosedcalls + their imports.Final dispatcher is ~30 lines:
dispatchToFlowsMigration totals (Phases 1-7)
Test plan
pull_request.closedarm — coverage inpr-closed-graph.test.ts🤖 Generated with Claude Code
Final NF-6 phase. Wraps the last 2 legacy webhook helpers (`handlePullRequestOpened` + `handlePullRequestClosed`) into baked-in flows, then deletes the inline calls from webhook.ts. Webhook becomes pure normalize → `dispatchToFlows`. ## Ships 3 new baked-in flows + 2 new node types: | Flow | Trigger | Wraps | |---|---|---| | `pr-opened` | `pull_request.opened` | `handlePullRequestOpened` (review-fallback timer + no-workflows shortcut) | | `pr-synchronize` | `pull_request.synchronize` | same handler — legacy code shared one helper | | `pr-closed` | `pull_request.closed` | `handlePullRequestClosed` (worktree cleanup + post-merge rebase probe) | Two new node types: - `forge.handle_pr_opened` — async; awaits the legacy handler so the fire-and-forget timer arming + decidePostCiAction launch happen before the run records `ok`. - `forge.handle_pr_closed` — sync void; same MUST-stay-sync-void contract as `forge.handle_issue_closed_cleanup` (an `async` wrapper would silently flip the fire-and-forget semantics into await-completion). ## Cutover `config/agents.json::node_flows.suppress_legacy` adds the 3 new trigger kinds (`pull_request.opened`, `pull_request.synchronize`, `pull_request.closed`). `webhook.ts` drops the inline `handlePullRequestOpened` / `handlePullRequestClosed` calls plus their imports. Final dispatcher is ~30 lines: - signature verify - parse + multi-repo gate - normalize → ForgeEvent - `dispatchToFlows` ## Test plan - [x] 16 new e2e tests across 2 files - [x] Full suite: 1946 pass / 4 pre-existing fail - [x] Server typecheck clean - [x] AGENT_NODE_COUNT bumped from 17 to 19 - [x] Removed 2 stale tests in `webhook.test.ts` for the deleted inline `pull_request.closed` arm — coverage in `pr-closed-graph.test.ts` ## Migration totals (Phases 1-7) - 12 baked-in flows shipped - 19 flow node types - ~1900 lines of legacy code deleted across the migration - Webhook dispatcher: ~30 LOC (was ~200 LOC of switch + plumbing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>