# Tree Forking UI Design

> **Date:** 2026-02-24
> **Feature:** Personal tree forking — explicit modal, reason capture, fork badge

---

## Overview

Add a proper fork UX to the flow library. The backend is fully complete (POST `/trees/:id/fork`, fork fields in API responses, tests passing). The frontend needs: a `ForkModal` component with a "Reason for Forking" field, updated fork handlers in `TreeLibraryPage` and `MyTreesPage`, fork field types on `Tree`, and a "Fork" chip on tree cards.

---

## What's Being Built

### 1. Types — `frontend/src/types/tree.ts`

Add `ForkInfo` interface and fork fields to `Tree`:

```ts
export interface ForkInfo {
  parent_tree_id: string
  parent_tree_name: string | null
  fork_depth: number
  fork_reason: string | null
  has_parent_updates: boolean
}
```

Add to `Tree`:
```ts
fork_info?: ForkInfo | null
parent_tree_id?: string | null
fork_depth?: number
```

Add to `TreeCreate`:
```ts
fork_reason?: string
```

### 2. `ForkModal` Component — `frontend/src/components/library/ForkModal.tsx`

A focused dialog with:
- **Name field** — pre-filled with `"Copy of <original name>"`
- **"Reason for Forking"** — optional textarea (placeholder: "e.g. customizing for a specific client…")
- **Cancel** (secondary) + **Fork** (gradient) buttons
- Calls `treesApi.fork(treeId, { name, fork_reason })` on submit
- Success: shows toast, navigates to `/my-trees`
- Error: shows inline error, stays open

### 3. Update Fork Handlers

In `TreeLibraryPage` and `MyTreesPage`, replace the current silent `handleForkTree` (which calls `treesApi.fork()` directly) with a handler that:
1. Sets the selected tree to fork
2. Opens `ForkModal`

The modal handles the actual API call and navigation.

### 4. "Fork" Badge on Tree Cards

In `TreeGridView`, `TreeListView`, and `TreeTableView`, render a small chip when `fork_depth > 0` (or `parent_tree_id` is set on `TreeListItem`):

```tsx
{tree.fork_depth > 0 && (
  <span className="rounded-full bg-violet-400/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-violet-400">
    Fork
  </span>
)}
```

`fork_depth` needs to be added to `TreeListItem` (it comes from the backend list response).

---

## What's NOT Being Built

- Lineage tree view / "forked from" link — out of scope
- "Has updates available" notification — out of scope
- Fork management / ancestry tracking UI — out of scope

---

## Data Flow

```
User clicks "Fork" on a card
  → onForkTree(tree) called
  → parent sets forkTarget state + opens ForkModal
  → user fills Name + optional Reason
  → ForkModal calls treesApi.fork(treeId, { name, fork_reason })
  → on success: toast "Flow forked!" + navigate('/my-trees')
  → My Trees page loads, forked flow shows "Fork" badge
```

---

## Files Changed

| File | Change |
|------|--------|
| `frontend/src/types/tree.ts` | Add `ForkInfo`, fork fields on `Tree`, `fork_depth` on `TreeListItem` |
| `frontend/src/components/library/ForkModal.tsx` | New component |
| `frontend/src/pages/TreeLibraryPage.tsx` | Open modal instead of silent fork |
| `frontend/src/pages/MyTreesPage.tsx` | Open modal instead of silent fork |
| `frontend/src/components/library/TreeGridView.tsx` | Fork badge |
| `frontend/src/components/library/TreeListView.tsx` | Fork badge |
| `frontend/src/components/library/TreeTableView.tsx` | Fork badge |
