git:20260824.680846f to git:20260825.d797854

2 added, 1 removed. Audit A to A.

# DOX — packages/client/src/components/folder
Files in this directory. One row per source file. See change: fold-oversized-agents-directories.
| File | Purpose |
|------|---------|
| `CwdGonePill.tsx` | Red `cwd gone` pill next to `WorktreePill` when `session.cwdMissing`. See change: add-worktree-lifecycle-actions. |
| `DirectoryHomeView.tsx` | Directory home page for the bare `/folder/:encodedCwd` route. → see `DirectoryHomeView.tsx.AGENTS.md` |
- | `FolderActionBar.tsx` | Sidebar folder-group action bar. Buttons: Initialize, Clean up broken. Directory Settings gear + Terminals + Editor REMOVED; renders `null` when it holds nothing. → see `FolderActionBar.tsx.AGENTS.md` |
+ | `folder-menu-labels.ts` | Pure label builders for the folder actions menu's directory group. `projectSetupLabel(status, base, updateBadge)` → `Project setup… n/N` tally (from the checklist) + localized `● update` badge (on `setupOutdated`); bare label when the checklist is absent. See change: add-folder-action-banner. |
+ | `FolderActionBanner.tsx` | Tier-0 full-width call-to-action banner for a directory card (replaces the deleted `FolderActionBar`). One banner max by a fixed severity ladder `failure > running > retrust > init-needed > setup`; test id `folder-banner-{setup,init-needed,retrust,failed,running}-<cwd>`, setup action `folder-banner-setup-action-<cwd>`. Setup rung ("Not a pi project yet", info, `mdiTextBoxCheckOutline`) gates on the REQUIRED `.pi/settings.json` checklist entry AND on `isProjectRoot` (pinned/workspace/positive-git). Spawns project-init + re-probes when the spawned session reaches `ended` (unconditional on outcome). Hook rungs re-host `WorktreeInitButton` (chip/trust dialog). Colours ONLY from `--severity-{info,warning,error}-{bg,fg,border}`. Exports `FolderActionBanner`, `computeBannerRung`, `setupState`, `BannerRung`. Fail-open: absent/uninterpretable checklist → no banner; checklist wins over the deprecated `configured` boolean. See change: add-folder-action-banner. |
| `FolderActionsMenu.tsx` | The folder header's single trailing control. `mdiFolderCogOutline` trigger (`folder-actions-menu-<cwd>`, `aria-haspopup=menu`, `aria-expanded`, `stopPropagation`) → grouped popover / mobile sheet (`folder-actions-menu-panel-<cwd>`, `role=menu`, `data-menu-form=sheet|popover`). Exports `FolderActionsMenu`, `FolderMenuItem`; RE-exports `FOLDER_MENU_GROUPS`/`FolderMenuGroup` from `dashboard-plugin-runtime/folder-menu-contributions` (one taxonomy for host + plugins). Host-owned group order `workspace → directory → create → open → maintenance`; a group renders only when non-empty (`folder-menu-group-<group>`). Merges caller `items` (host, keep declared order) with `useFolderMenuItems(cwd)` contributions — read HERE, so an OPEN menu converges on a late-mounting section. `FolderMenuItem` gains `badge?` (renders `folder-menu-badge-<id>`, part of the accessible name) + `disabled?` (`aria-disabled`, stays focusable per APG, callback never fires, menu stays open); `onSelect` wrapped in try/catch so a plugin throw cannot take the sidebar down. See change: move-slot-actions-to-menu. Items `role=menuitem` + `folder-menu-item-<id>`; `FolderMenuItem.node` lets an item render its own node (add-to-workspace keeps `add-to-workspace-btn-<cwd>` + its popover). Caller owns `open` — `SessionList` keys it by SCOPE `folder:<cwd>`. ArrowDown/Up rove `[role=menuitem]`; Escape closes + refocuses trigger; outside mousedown/touchstart closes. Sheet gates on `useMobile()` (compound `<768w OR <600h`, reused verbatim) via `DialogPortal`; desktop PORTALS via `LayerPortal` + a `fixed` panel positioned from `usePopoverFlip`'s `triggerRect`/`flipUp`/`anchorRight`. BOTH forms carry the `z-popover` layer token (never inline `absolute z-50`) — portaling escapes each `SessionCard`'s `isolate` stacking context, the fix for the folder-menu UNDERLAP (z-index/layering/stacking-context). `mdiDotsHorizontal` REJECTED — `WorktreeActionsMenu` already renders it inside the folder body. See change: add-folder-actions-menu. See change: add-overlay-layering-system (spec overlay-layering). |
| `FolderEditorView.tsx` | Folder-scoped internal Monaco pane. Wraps `SplitWorkspaceProvider` keyed by `folderPaneId(cwd)`, renders… → see `FolderEditorView.tsx.AGENTS.md` |
| `FolderSpawnButtons.tsx` | Stacked spawn buttons in folder header: `+ New Session` (green, always) + `+ New Worktree` (orange, gated by `showWorktree`). Min-height 44px on mobile. Exports `FolderSpawnButtons`. |
| `FolderStatusCapsule.tsx` | The folder header's ONE liveness surface, in BOTH collapse states. Exports `FolderStatusCapsule`. Replaces the raw `(N)` count + `FolderNeedsYouPill` + `FolderStatusRollup`. Segments render in fixed severity order `CAPSULE_SEGMENT_ORDER` (needs-you > error > working > idle); zero counts absent; no countable sessions → no capsule. Non-idle segments are `<button>`s navigating to `firstIds[bucket]`; idle is an inert `<span>` (not a disabled button) that still carries an aria-label. Test ids `folder-status-capsule-<cwd>` + `folder-capsule-seg-{needs-you,error,working,idle}-<cwd>`, plus `data-capsule-segment` for order assertions. Counts cap at `999+`. Owns the per-candidate `WidgetBarProbe` (absent/undefined = unclassified = excluded, so needs-you never flashes high). Colors from `--status-*` only, never `--severity-*`. `flex-none` + `whitespace-nowrap` — sheds nothing; the folder name absorbs width pressure. Activation calls `stopPropagation()` then routes through `SessionList`'s existing reveal path (`onSeekToCard`), which owns guarded expand, layout-settled scroll and the hidden/filtered degrade notices. See change: unify-folder-status-capsule. |