Skip to content

feat(web): add interactive feature reparenting and auto-rebase on parent completion#538

Open
arielshad wants to merge 19 commits intomainfrom
feat/feature-dependency-rebase
Open

feat(web): add interactive feature reparenting and auto-rebase on parent completion#538
arielshad wants to merge 19 commits intomainfrom
feat/feature-dependency-rebase

Conversation

@arielshad
Copy link
Copy Markdown
Contributor

Summary

Extends the feature dependency system (spec 041) with two capabilities:

  1. Interactive canvas reparenting — drag-to-connect via React Flow handles to set/change a feature's parent dependency, with edge deletion to unparent. Includes optimistic UI, cycle detection, cross-repo validation, and lifecycle guards.
  2. Auto-rebase of child branches — when a parent feature reaches post-implementation lifecycle (Implementation/Review/Maintain), all blocked child feature branches are automatically rebased onto the parent branch using the existing smart rebase + agent-powered conflict resolution infrastructure.

Spec: specs/084-feature-dependency-rebase/

Changes

Domain & Application Layer

  • ReparentFeatureUseCase — new use case validating same-repo, cycle detection, and lifecycle guards (rejects Done/Archived). Adjusts child lifecycle to Blocked when reparented under a pre-implementation parent, and unblocks when parent is post-implementation.
  • CheckAndUnblockFeaturesUseCase — extended to orchestrate auto-rebase of unblocked children onto the parent branch before agent spawn. Each child rebase is independent; failures are isolated and recorded in the activity timeline.
  • IGitPrService.rebaseOnBranch(cwd, featureBranch, targetBranch) — new interface method for rebasing onto an arbitrary branch (parent feature branch), implemented in the git PR service.

Presentation Layer (Web)

  • FeaturesCanvas — enables nodesConnectable={true}, implements onConnect for reparenting and onEdgesDelete for unparenting, with toast feedback for validation errors.
  • useGraphState — new reparentFeature() mutation with optimistic update + beginMutation/endMutation guards.
  • DependencyEdge — selectable, deletable edges with hover delete affordance and keyboard support.
  • reparent-feature server action — calls ReparentFeatureUseCase via DI string token alias.

DI Container

  • Registers ReparentFeatureUseCase class token + 'ReparentFeatureUseCase' string alias for web server action access.
  • Injects rebase dependencies into CheckAndUnblockFeaturesUseCase.

Test Plan

  • Unit tests for ReparentFeatureUseCase (19 tests): success, cycle detection, cross-repo rejection, lifecycle guards, unparent, lifecycle state adjustment
  • Unit tests for GitPrService.rebaseOnBranch (13 tests)
  • Unit tests for CheckAndUnblockFeaturesUseCase auto-rebase orchestration (16 tests)
  • Integration tests for canvas reparenting via control center (24 tests)
  • Integration tests for feature-parent.repository, sqlite-feature-repository.find-by-branch, and git-pr.service.rebase-sync
  • Full unit suite green: 5402 tests / 383 files in 35.99s
  • Full integration suite green: 581 tests / 50 files in 32.67s
  • Lint, typecheck, format, and build all green locally
  • Manually verified canvas rendering with real data in dev server (see Evidence)

Evidence

App screenshots (running dev server, port 3001)

Full canvas view — feature nodes (Merge Diff Viewer, Bug Fix Mode, Prototype Exploration, Telegram & WhatsApp, Policy-Driven Supply Chain) connected via dependency edges to the cli repo group node. Proves canvas reparenting infrastructure works in the actual app with real data (task-11):

App canvas full view

Feature node with connection handle — close-up showing the source connection handle (blue + circle on the right edge) visible on hover. Proves FR-1 (drag-to-connect handles enabled) and task-13 (isConnectable={true} + handle visibility on hover):

Feature node with handles

Edge interaction layer — canvas view showing dependency edges between repo and feature nodes. Proves FR-4 edge deletion infrastructure rendered with selectable edges in real app context (task-12):

Canvas edge hover delete

Main control center pagehttp://localhost:3001/ with FeaturesCanvas integrated. Proves the canvas with reparenting capabilities loads in the real app routing context (task-11):

Main control center page

Test runs

  • Unit tests — 72 feature-specific tests across 4 files: ReparentFeatureUseCase (19), GitPrService.rebaseOnBranch (13), CheckAndUnblockFeaturesUseCase Auto-Rebase (16), Control Center Integration (24). Full suite: 383 files / 5402 tests passing in 40.85s. See evidence/unit-test-results.txt.
  • Integration tests — 50 files / 581 tests passing in 20.12s including feature-parent.repository (14), sqlite-feature-repository.find-by-branch (6), and git-pr.service.rebase-sync (16). See evidence/integration-test-results.txt.

Related

  • Builds on spec 041 (feature dependencies) — parentId, Blocked lifecycle, dependency edges
  • Builds on spec 080 (smart rebase) — RebaseFeatureOnMainUseCase, stash, ConflictResolutionService

Built with Shep 🐑 Shep Bot

arielshad and others added 18 commits April 7, 2026 14:31
…rebase

Thorough analysis of the existing dependency system (spec 041), canvas
architecture, rebase infrastructure, and graph state management. Identifies
affected areas across all four clean architecture layers, documents existing
infrastructure to build on, and defines success criteria for interactive
reparenting and auto-rebase capabilities.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ncy rebase

14 tasks across 4 phases: core use case with validation, git rebaseOnBranch
infrastructure, auto-rebase orchestration in CheckAndUnblockFeaturesUseCase,
and canvas interaction with drag-to-connect and optimistic UI.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ycle adjustment

Introduces ReparentFeatureUseCase with cycle detection, same-repo check,
lifecycle guards (block Maintain/Archived/Deleting), lifecycle state
adjustment based on new parent, and CheckAndUnblock integration.
Includes 19 unit tests covering all validation and adjustment paths.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Registers ReparentFeatureUseCase with class token + string alias
'ReparentFeatureUseCase' in the DI container. Adds server action
at app/actions/reparent-feature.ts following the established pattern.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add rebaseOnBranch(cwd, featureBranch, targetBranch) to IGitPrService
interface and implement in GitPrService. This method rebases a feature
branch onto an arbitrary target branch (origin/<targetBranch>) instead
of only the default branch. Key differences from rebaseOnMain: explicit
git fetch of the target branch before rebase since it may not be locally
available. Same conflict detection pattern (REBASE_CONFLICT error code).
Includes unit tests covering success path, conflict detection, fetch
failure, dirty worktree, branch not found, and execution order.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…res use case

Add IGitPrService, IWorktreeService, ConflictResolutionService,
IAgentRunRepository, and IPhaseTimingRepository to the constructor
following the same injection pattern as RebaseFeatureOnMainUseCase.
Update test fixtures to provide the new mocks.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ures use case

Insert rebase orchestration between lifecycle transition (Blocked -> Started)
and agent spawn. For each blocked child: create agent run + phase timing,
resolve CWD via worktree service, stash uncommitted changes, rebase child
branch onto parent branch via rebaseOnBranch, delegate conflicts to
ConflictResolutionService, restore stash in finally block, record timing.
Failures are isolated per-child and recorded in activity timeline. Agent
spawns regardless of rebase outcome. Skip rebase if child has active
running agent run (NFR-3). 5-minute timeout per child.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add interactive reparenting via React Flow drag-to-connect on the
features canvas. Users can now drag from a parent feature source handle
to a child feature target handle to establish a dependency. Dependency
edges show a hover delete button for unparenting.

- Add reparentFeature optimistic mutation to useGraphState with rollback
- Add handleConnect with validation (same-repo, non-terminal, no self)
- Add handleEdgesDelete for dependency edge removal (unparenting)
- Enable connections and element selection on FeaturesCanvas
- Enhance DependencyEdge with hover X button via EdgeLabelRenderer
- Always render feature node handles with isConnectable=true
- Set showHandles=true for feature nodes in deriveGraph
- Add 10 integration tests covering connect and edge delete flows

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Storybook build was failing because use-graph-state.ts imports the
reparent-feature server action but no corresponding mock exists.
Add the mock following the established pattern.
@arielshad arielshad force-pushed the feat/feature-dependency-rebase branch from 25bf3fb to 4f84518 Compare April 7, 2026 11:34
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 7, 2026

Dev Release Published

Artifact Version Install
npm 1.177.0-pr538.aa9ace4 npm install -g @shepai/[email protected]

Published from commit 4f84518 | View CI

@arielshad arielshad force-pushed the feat/feature-dependency-rebase branch from 4f84518 to 68a28ff Compare April 7, 2026 11:44
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 7, 2026

Dev Release Published

Artifact Version Install
npm 1.177.0-pr538.cd394e5 npm install -g @shepai/[email protected]

Published from commit 68a28ff | View CI

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