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
17 changes: 17 additions & 0 deletions docs/frontend-ui-audit-2026-09-25/SessionSources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Session Sources UI audit

| Line | Element | Verdict | Reason | Suggested change |
| ---------------------------- | ------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| SessionSourceRow.tsx | Resource rows | fix | Earlier standalone row styling duplicated sidebar chrome | Resolved with SidebarRow and shared file/model icons |
| SessionToolActivityGroup.tsx | Activity disclosure | fix | Local typography overrides conflicted with detail panel defaults | Resolved with SidebarSectionHeader and useCollapsible |
| SessionToolActivityGroup.tsx | Failure details | fix | Error surface should follow shared feedback appearance | Resolved with PageNotice |
| SessionSourcesView.tsx | Canvas | fix | Generic surface grey differed from work area | Resolved with EDITOR_TAB_CANVAS_BG_CLASS |
| SessionSourcesView.tsx | Category headers / pagination | keep with reason | Shared SidebarSectionHeader and Button own geometry and controls | Preserve shared components |
| SessionSourceThumbnail.tsx | 3px miniature radius and size | keep with reason | Tiny source previews need their icon-sized optical geometry; width follows caller's shared icon scale | No global token change |
| SessionSourcesView.tsx | 8px row / 16px category spacing | keep with reason | Explicit user-approved density uses standard spacing utilities | Preserve local layout |
| SessionSourceRow.tsx | Path tooltip | keep with reason | Shared Tooltip exposes truncated human-readable location; encoded transport refs stay private | Preserve |
| features/SessionSources | Shared presentation/navigation | abstract | Rail preview, source detail rows and complete page need one identity/navigation implementation | Implemented feature module; old rail-only wrappers removed |

Totals: 4 resolved fixes, 4 keep with reason, 1 implemented abstraction. No raw production buttons, inputs or clickable substitutes introduced. Metadata colors use semantic tokens; shared components own typography/hover/focus. No global design-system sweep.

Visual evidence in ../verification-2026-09-25/session-sources: final categorized light page, dark 340px page, empty/loading/error states. These render actual feature and shared components using fictional source fixtures; navigation and image loading are mocked. They are not native-app E2E evidence. The user subsequently explicitly requested their original application screenshot; user-screenshot.png is included unchanged as the primary PR illustration.
67 changes: 67 additions & 0 deletions docs/frontend-ui-audit-2026-09-28/ChatPanelCompanionLayout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# ChatPanelCompanionLayout UI audit

| Line | Element | Verdict | Reason | Suggested change |
| ---------------------------------- | ---------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| `ChatPanelCompanionLayout.tsx:60` | Companion header and actions | keep with reason | Reuses PanelHeader, PANEL_HEADER_TOKENS, shared Button, existing translated title/close/move labels; no native action elements or custom clickable substitutes added | None |
| `ChatPanelCompanionLayout.tsx:48` | Resizable divider | keep with reason | Reuses VerticalResizeHandle and useColumnResize, including existing drag cancellation/unmount cleanup | None |
| `ChatPanelCompanionLayout.tsx:25` | Reading width constraints | keep with reason | Feature-owned initial/min/max reading widths; a 50% CSS cap reserves at least half the available pane for chat even in narrow layouts | None |
| `ChatPanelCompanionLayout.tsx:135` | Chat/companion composition | keep with reason | Stable chat subtree; companion replaces only the summary rail and unmounts on close or owner change | None |
| `SessionSourcesContent.tsx:10` | Shared source data container | keep with reason | Both the companion and Station renderer consume the same source hook, shared-file scope and SessionSourcesView; category disclosures, navigation, retry and theme tokens remain shared | None |

Verdict totals: **0 fix**, **5 keep with reason**, **0 abstract**.

## State and architecture

The owning state is one transient per-store `ChatPanelCompanion`, identified by type, session ID and owner tab ID. Opening is idempotent and validates the active conversation at the write boundary. The host rejects stale scope immediately, then clears the slot on navigation/unmount. No new persistent setting, tab schema, API, database or wire protocol is introduced. Existing Station sources tabs remain compatible; opening there is explicit.

Architecture review covered state ownership, type/control flow, default destination, content reuse, entry-point parity and session-scope resolution. Backend/schema/wire and migration layers are unchanged. This is not a general-purpose tab framework: the supported companion type is currently `session-sources`.

The data path is View all → openSessionSources → openChatPanelSourcesAtom → ChatPanelShell/ChatPanelCompanionLayout → shared SessionSourcesContent → existing source history reader. Loading, empty, error/retry and same-session refresh behavior remain owned by useSessionSourcesState and SessionSourcesView. Closing releases the content; reopening is a fresh view, not a persisted cache. Category state is preserved through same-session refresh but resets after closing.

## Verification

- `pnpm test:app src/engines/ChatPanel/ChatPanelCompanionLayout.test.ts src/engines/ChatPanel/sessionSources/openSessionSources.test.ts src/engines/ChatPanel/sessionSources/useSessionSources.test.ts src/features/SessionSources/SessionSourcesView.test.ts src/modules/WorkStation/TabContent/renderers/sessionSources.test.ts src/modules/WorkStation/TabContent/renderers/sessionSources.activities.test.ts` — 41 tests passed in 6 files
- `pnpm typecheck:fast` — passed after adding the concrete HTMLDivElement ref type in the new test
- ESLint on all changed/new production and test files — passed
- Changed production controls inspected: only shared Button actions; no raw button/input or clickable element substitutes introduced
- Native visual automation cannot select the unbundled ORG2 Dev executable; browser-mode app cannot access desktop session IPC. Isolated real-component rendering is used for layout evidence, not claimed as native/data integration verification

## Performance guard

| Area | Verdict | Evidence | Change or reason kept | Verification |
| ------------------ | ------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Background work | keep | Existing useSessionSourcesState history reads and visibility listener | Only mounted source content owns reads; no new polling; existing in-flight sharing and stale-response guard retained | Existing hook visibility/stale/error tests plus companion disposal tests |
| Memory | keep | One nullable atom slot and one mounted companion | No per-session map or app-lifetime result cache; close/navigation/unmount releases content | Composition tests assert disposal and slot clearing |
| Scope/isolation | keep | Owner tab ID plus session ID at write and render boundaries | Stale open is rejected; scope changes remove old content before effect cleanup | Stale-action and session/tab-switch tests |
| Rendering/hot path | keep | Chat subtree retains position; source content lazy loads; shared resize hook uses DOM writes | Open/repeat/close preserves the same input node and unsent draft | Parent shell composition test |

Performance verdict: **blocked** for native runtime measurement only. Unit ownership/lifecycle checks passed; native idle CPU/RSS, native window resizing and cloud-session manual validation were not measured. No runtime performance improvement is claimed.

### Rendered follow-up

- Real ChatPanelCompanionLayout, shared header/buttons, resizing, SessionSourcesContent and SessionSourcesView rendered in an isolated browser fixture. Only desktop state/API/navigation dependencies and source payloads were fixtures.
- Verified View all opens alongside the chat draft, repeated open retains the view, category collapse works, and close restores the summary. Inspected dark/narrow and light/wide rendering.
- At 1200px, source content measured 420px and chat 779px. Dragging the divider 80px left grew sources to 500px.
- At 600px, sources were capped at 300px. Found that the shared resize hook initially used the uncapped stored width; changed drag initialization to read the actual layout width. Verified dragging 20px right immediately shrinks the pane to 280px. The hook still uses its configured width when no measured width is available.
- `pnpm test:app src/scaffold/Resize/hooks/useColumnResize.test.ts src/engines/ChatPanel/ChatPanelCompanionLayout.test.ts` — 5 passed, including the new constrained-width regression (42 distinct relevant tests passed across both runs).
- Typecheck and lint passed after the resize change; `git diff --check` for the tracked files touched by this change passed. Native runtime measurement remains unverified as stated above.

### Floating chrome overlap regression

The initial isolated preview used an in-flow sample header, so it missed the live shell's absolute overlay chrome. The source companion started at y=0 and its header/actions overlapped the global conversation toolbar. ChatPanel now passes its canonical chromeTopInsetPx through ChatPanelShell to the companion and its resize divider, just as the transcript and summary rail already consume it. No independent header-height constants were added.

- Regression coverage renders real ChatPanelShell and ChatPanelChrome, transitions between collapsed overlay (44px), expanded overlay (80px), and in-flow (0px), and asserts that the source pane, divider and unchanged chat/source mounts follow the shared inset.
- `pnpm test:app src/engines/ChatPanel/ChatPanelCompanionLayout.test.ts src/engines/ChatPanel/header/ChatPanelChrome.test.ts src/engines/ChatPanel/header/chatPanelHeaderLayout.test.ts` — 28 tests passed in 3 files.
- `pnpm typecheck:fast` and ESLint on the four changed production/test files passed; tracked-file diff whitespace checks passed.
- Rendered real ChatPanelChrome and its published-header slot component with the companion: light 1280px collapsed toolbar and dark 600px expanded toolbar. Source header/actions appear below the global toolbar in both. Collapsed companion top measured 44px; narrow expanded screenshot confirms separation and 50% width cap. Closing sources works and retains the chat draft.
- Preview fixtures replace desktop state/platform dependencies, source payloads and navigation; this is rendered component evidence, not native app verification. Native automation limitation described above still applies.

### Isolated PR branch verification

After integrating latest `origin/develop` without rewriting reviewed history:

- `pnpm test src/features/SessionSources src/engines/ChatPanel/sessionSources src/engines/ChatPanel/ChatPanelCompanionLayout.test.ts src/engines/ChatPanel/header/ChatPanelChrome.test.ts src/engines/ChatPanel/header/chatPanelHeaderLayout.test.ts src/scaffold/Resize/hooks/useColumnResize.test.ts src/modules/WorkStation/TabContent/renderers/sessionSources.test.ts src/modules/WorkStation/TabContent/renderers/sessionSources.activities.test.ts` — 98 tests passed in 15 files.
- `pnpm typecheck:fast` — passed on the isolated PR branch.
- ESLint on the 14 changed/new TypeScript files — passed.
- `pnpm check:test-placement` — passed, 636 directories.
- `git diff --cached --check` — passed; staged scope and private-path/debug-output inspection found no unrelated additions.
13 changes: 13 additions & 0 deletions docs/frontend-ui-audit-2026-09-28/SessionSourceCategory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Session source categories UI audit

| Line | Element | Verdict | Reason | Suggested change |
| ---------------------------------------------------------- | ------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `src/features/SessionSources/SessionSourceCategory.tsx:31` | Category disclosure | keep with reason | Reuses SidebarSectionHeader with expanded/onToggle, matching existing tool activity disclosures. Shared Button supplies native keyboard activation and aria-expanded; DisclosureChevron supplies shared motion and reduced-motion rules. | Keep the existing header family; no new accordion primitive. |
| `src/features/SessionSources/SessionSourceCategory.tsx:40` | Category body | keep with reason | Preserves existing row spacing, tokens and shared source/tool rows. Hidden bodies unmount; category-local page count survives reopening. | Keep shared row composition. |
| `src/features/SessionSources/SessionSourceCategory.tsx:60` | More sources | keep with reason | Existing tertiary small Button and translated label are retained. | No raw controls or new visual tokens. |

Verdict totals: **0 fix**, **3 keep with reason**, **0 abstract**.

All four categories share one SessionSourceCategory adapter. This adapter owns only local disclosure and pagination and calls the existing useCollapsible hook; no persistence or generic component API is added. Existing grouping, provenance, navigation and gallery ownership stay in place.

Verified independent mouse/keyboard collapse, count visibility, refresh/error/retry continuity, retained pagination and session-key remount reset. Chrome component preview uses real UI components, Tailwind, utility styles and light/dark token sheets; native file/image navigation is stubbed in that preview. Light 1000px and dark 420px screenshots are in docs/verification-2026-09-28/source-collapse. No native App or mobile device visual claim is made.
9 changes: 9 additions & 0 deletions docs/org2-performance-guard-2026-09-25/SessionSources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Session Sources lifecycle audit

Source requests are session scoped, single-flight while pending and released by consumer reference count. Pending request ownership is removed at settlement/disposal; no completed-result global cache. Hidden documents pause noncritical refresh; visibility return revalidates. Session-keyed renderer prevents stale list/gallery/page state crossing sessions. Inactive tabs do not read history or resolve images. Old rows survive failed refresh; retry is explicit.

Reader work is bounded at input-line, reference, pending-call, nested-resource and tool-action boundaries. Native SQL extracts compact visible source messages, not entire session objects. Structured references and completed tool facts are separate; errors never masquerade as successful resources, and edit receipts do not synthesize attachments.

Category arrays and semantic detail maps live with the mounted view. Four category page counters start at 30 rows each (at most 30 image thumbnail reads); activity details start at 20 unique rows per action type. More content loads by explicit action. Duplicate display actions retain original call IDs and occurrence totals. No new recurring poller, worker or network transport.

Validation covers coalesced reads, refresh/session races, hidden/inactive lifecycle, retry, page reset, image identity/gallery, activity aggregation and actual provider transcript readers. No native CPU/RSS sampling, large-history benchmark, dual-machine sharing run or complete packaged-app E2E in this PR. Verdict: scoped/bounded lifecycle supported by tests; no measured performance claim.
Loading
Loading