Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions app/(dashboard)/plans/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,21 +197,13 @@ export default async function PlanDetailPage({ params }: { params: Promise<{ id:
</div>
)}

{/* Long-form description, clamped with an expander */}
{plan.description && <PlanDescriptionCard description={plan.description} />}

{/* Linked design spec, rendered read-only from its source */}
{plan.specUrl && (
<SpecCard
specUrl={plan.specUrl}
markdown={await fetchSpecMarkdown(plan.specUrl, profile?.organizationId ?? null)}
/>
)}

{/* Tasks front and center; delivery/impact/demand context one click away */}
<Tabs defaultValue="tasks">
{/* The spec is the work's anchor: description + linked design spec live in
a default Overview tab so they read properly and every tab's content
starts above the fold. */}
<Tabs defaultValue="overview">
<div className="flex items-center justify-between flex-wrap gap-2">
<TabsList className="bg-muted">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="tasks">Tasks ({plan.taskCount})</TabsTrigger>
<TabsTrigger value="assets">Assets &amp; PRs ({plan.planAssets.length})</TabsTrigger>
<TabsTrigger value="impact">Impact ({impactedAssets.length})</TabsTrigger>
Expand All @@ -220,6 +212,27 @@ export default async function PlanDetailPage({ params }: { params: Promise<{ id:
<AddTaskDialog plan={plan} teamMembers={teamMembers} />
</div>

<TabsContent value="overview" className="mt-4 space-y-6">
{/* Long-form description, clamped with an expander */}
{plan.description && <PlanDescriptionCard description={plan.description} />}

{/* Linked design spec, rendered read-only from its source */}
{plan.specUrl && (
<SpecCard
specUrl={plan.specUrl}
markdown={await fetchSpecMarkdown(plan.specUrl, profile?.organizationId ?? null)}
/>
)}

{!plan.description && !plan.specUrl && (
<Card className="bg-card border-border">
<CardContent className="py-8 text-center text-sm text-muted-foreground">
No description or linked spec yet — add one with Edit so the plan carries its own specification.
</CardContent>
</Card>
)}
</TabsContent>

<TabsContent value="tasks" className="mt-4">
<PlanTasksSection
tasks={plan.tasks}
Expand Down
36 changes: 24 additions & 12 deletions app/(dashboard)/releases/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,36 @@ export default async function ReleaseDetailPage({ params }: { params: Promise<{
</div>
</div>

{release.description && (
<Card className="bg-card border-border">
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-muted-foreground">Description</CardTitle>
</CardHeader>
<CardContent className="prose prose-sm dark:prose-invert max-w-none">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{release.description}</ReactMarkdown>
</CardContent>
</Card>
)}

<Tabs defaultValue="assets">
{/* The description (the release notes) lives in a default Overview tab so
it reads properly and every tab's content starts above the fold. */}
<Tabs defaultValue="overview">
<TabsList className="bg-muted">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="assets">Assets &amp; Versions ({release.assets.length})</TabsTrigger>
<TabsTrigger value="plans">Plans ({release.plans.length})</TabsTrigger>
<TabsTrigger value="work-items">Work Items ({release.workItems.length})</TabsTrigger>
</TabsList>

<TabsContent value="overview" className="mt-4">
{release.description ? (
<Card className="bg-card border-border">
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-muted-foreground">Description</CardTitle>
</CardHeader>
<CardContent className="prose prose-sm dark:prose-invert max-w-none">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{release.description}</ReactMarkdown>
</CardContent>
</Card>
) : (
<Card className="bg-card border-border">
<CardContent className="py-8 text-center text-sm text-muted-foreground">
No description yet — it becomes the release notes. Write one, or derive it from the
delivered work items{config.ai.enabled && editable ? ' with Draft release notes' : ''}.
</CardContent>
</Card>
)}
</TabsContent>

<TabsContent value="assets" className="mt-4">
<ReleaseAssetsSection
releaseId={release.id}
Expand Down
3 changes: 2 additions & 1 deletion docs/app-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ Header (type/health badges, current version chip from latest shipped release, re
- **Record** (v0.4.4) — the asset's current-state register: a candidates banner ("N resolved features can join this asset's record" with one-click graduation), capabilities list (lineage chip from `originSummary`, verification freshness dot, expandable markdown, edit dialog, remove-with-reason dialog), derived **Known issues** (open bug/ux) and **Debt register** (open tech_debt) cards, and a struck-through **Previously** card for tombstoned capabilities.

#### `/releases` & `/releases/[id]` — Releases (v0.4.1)
List: status tabs (All / In Progress / Shipped), rows with asset+version chips, plan counts, derived work-item type dots; create side panel. Detail mirrors plan-detail layout:
List: status tabs (All / In Progress / Shipped), rows with asset+version chips, plan counts, derived work-item type dots; create side panel. Detail mirrors plan-detail layout (v0.4.4: description moved into a default **Overview** tab — it is the release notes; empty state points at Draft release notes when AI is enabled):
- **Assets & Versions** — one row per `release_assets` entry with inline version/note editing, per-asset PR chips rolled up from attached plans, and a suggestion banner for plan-targeted assets missing from the release
- **Plans** — attach/detach (a "ships in" picker also exists on plan detail); **Work Items** — derived through attached plans, grouped Features / Bugs & UX / Tech Debt (the release-notes structure)
- **Mark Shipped** confirm lists unversioned assets; shipped/abandoned releases render read-only. "Draft release notes" (flagged AI) opens an editable dialog; saving writes the description explicitly.
Expand All @@ -322,6 +322,7 @@ Client component (`PlansClient`) with:
- **Link Milestone** (`plan-sync-dialog.tsx`): binds the plan to a GitHub milestone via an org connection; milestone issues mirror as read-only plan tasks (mixed with native tasks); Unlink converts mirrored tasks to native. Sync also refreshes `code_plan_assets.prStatus` for PR URLs in the connection's repo
- Stats row: Overall Progress (% + progress bar + task count), Target Assets (count + names), Assignees (avatars)
- Tags row
- Tabs (v0.4.4: the long-form description + linked spec moved into a default **Overview** tab — the spec anchors the work, and every tab's content starts above the fold): **Overview** (clamped markdown description via `plan-description-card.tsx`, linked design spec via `SpecCard`, empty-state prompt when neither exists) / Tasks / Assets & PRs / Impact / Work Items
- **Target Assets & PRs** (`plan-assets-section.tsx`): per-asset rows with branch, PR link, PR status badge; inline edit form; add/remove target assets → plan-asset actions
- **Impact Analysis**: assets depending on the plan's targets (via `asset_dependencies`), with dependency path and health badges
- **Linked Work Items**: items linked via `work_item_code_plans` with type/status badges
Expand Down
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ <h2>See it in action</h2>
<button class="tour-tab" data-img="screenshots/asset-history.png" data-caption="Asset history — a version ladder of shipped releases, delivered plans, resolved work items, and design notes (user- or agent-authored).">Asset History</button>
<button class="tour-tab" data-img="screenshots/releases.png" data-caption="Releases — group the plans that ship together, stamp per-asset versions, and track the ship lifecycle.">Releases</button>
<button class="tour-tab" data-img="screenshots/release-detail.png" data-caption="A shipped release — per-asset version stamps, merged PR chips rolled up from attached plans, and derived release notes.">Release Detail</button>
<button class="tour-tab" data-img="screenshots/plan-detail.png" data-caption="A code plan — tasks, target assets, branch/PR delivery tracking, and the release it ships in.">Code Plan</button>
<button class="tour-tab" data-img="screenshots/plan-detail.png" data-caption="A code plan — progress, target assets, the release it ships in, and its specification up front in the Overview tab.">Code Plan</button>
<button class="tour-tab" data-img="screenshots/work-items.png" data-caption="Work items — features, bugs, UX issues, and tech debt with severity, asset/area, and the plans that address them.">Work Items</button>
<button class="tour-tab" data-img="screenshots/asset-dependencies.png" data-caption="Asset dependencies — both directions of the graph, feeding impact analysis when plans target an asset.">Dependencies</button>
</div>
Expand Down
Binary file modified docs/screenshots/plan-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/release-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading