Frontend Development
Add organization-scoped product behavior with complete loading, error, empty, and durable-state handling.
Recovery and Context loading
The root document stays mounted around route errors. Retry invalidates route data before resetting the error boundary. Backend timeout, connectivity, unreadable-response and contract failures have sanitized server diagnostics; raw gateway bodies are never shown to the user.
Context files, sources and assessments load independently. A failed refresh retains previously loaded content with an explicit warning; a different assessment never inherits the previous assessment as its result. Navigation summaries may be unavailable without blocking organization access. Invalid historical dates render safely, and invalid saved timezones display an explicit UTC fallback.
Historical assessment links resolve against immutable organization-scoped storage even after leaving the recent-history menu. Context file enumeration reads fixed documents and department playbook prefixes, avoiding unrelated run/chat objects; content hashes are read only for the requested page.
Ownership
The frontend presents backend-owned state and submits typed user intent. It does not invent task identifiers, infer authorization, or become the canonical owner of lifecycle state.
Add a Product Route
- Keep the organization ID in the route and query scope.
- Define typed loader/query behavior.
- Render loading, empty, partial, failure, and success states.
- Keep mutations explicit and refresh or reconcile affected data.
- Preserve actionable backend validation messages without leaking raw internal errors.
- Add route and helper tests.
Extend Integration Management
Managed provider name, description, URLs, icon, setup Markdown, categories, departments, and grants should remain catalog-driven. Registry cards are summaries only: logo, name, two-line description, readiness, and one contextual action. Provider management belongs in the shared sheet so connection, access, tools, Context, lifecycle actions, and unsaved-work handling stay consistent.
Keep the stable integration key and active sheet section in validated route search. Fetch the selected integration independently of filtered or paginated card results, and exclude section-only state from list loader dependencies. Browser history must be able to close and reopen the sheet without losing registry filters.
Compose provider-specific panels into the sheet rather than adding another overlay or a generic configuration framework. Every editable panel reports dirty and pending state. Search-only UI stays transient; pending submission locks navigation and lifecycle actions; dirty navigation goes through one discard confirmation. Initialize drafts from the canonical integration projection before reporting state so opening a clean panel never creates a transient dirty snapshot. Keep lifecycle actions in Connection and filter tool search by stable tool names rather than provider prose. Keep large MCP inventories in the connected-only Tools section, with search and bulk-selection controls outside the scrolling inventory. Discover lazily on first entry, retain the panel while the sheet remains open, and deduplicate development effect replay. Visibility refreshes may refresh the route projection, but they must not repeat provider discovery unless the integration ID, persisted revision, permission mode, explicit tool snapshot, or an explicit retry changed.
Integration Usage drafts retain their own saved Context revision. Route refreshes and browser-focus events must preserve unsaved text, resource selections, focus and validation errors. A clean draft may adopt a newer Context revision; a dirty draft saves against its original revision so concurrent edits produce a conflict without losing the draft. Successful saves adopt the returned canonical context and revision. Only switching integration identity resets the panel.
Run bun run --cwd apps/frontend build followed by
bun run scripts/integration-context-journey.ts for the production browser regression. It starts an
isolated fixture backend and frontend, exercises focus/timer refreshes and conflicting saves, and
never contacts a real database or provider.
Onboarding uses the same redacted integration projection. Render that loader result directly and refresh it when the setup tab becomes visible again; do not copy it into component state that can remain stale after a separate connection or authorization flow.
OAuth providers usually need:
- service selection;
- connect and callback states;
- redacted identity;
- missing-scope handling;
- same-account reauthorization; and
- disconnect confirmation.
Human Inbox
Keep Questions, Approvals, and Reconciliation visibly distinct. A user should know whether they are providing information, authorizing a future effect, or recording the result of a possibly completed effect.
Context Rendering
Render source Markdown through the safe product boundary, preview PDFs without treating them as trusted executable content, and keep citations linked to retained source identity.
Product Theme
Use the shared Oblive color language: Geist, neutral surfaces, green primary, restrained shadows, and accessible light/dark states. This documentation site mirrors those tokens without importing frontend CSS directly.
Documentation Impact
When UI changes alter a documented flow, replace the affected screenshot and update the operator steps in the same commit.
Page and asset recovery
Route failures show an incident reference and offer both data retry and a full page reload. The
frontend server logs frontend.page_failure with that reference, the build ID, route pathname and
failure category. Query strings, error messages, stack traces and page content are not sent.
VITE_BUILD_ID may identify a release; builds default to their build timestamp.
A failed Vite asset preload or dynamic import can reload the document once in five minutes per tab. The guard survives reloads in session storage; unavailable storage disables automatic reload. Repeated failures remain visible rather than entering a reload loop. Context source and health failures remain isolated from independently readable panels.
Optional integration onboarding reuses the Integrations route and its connection sheet. Durable setup status comes from company research progress; opening the page or dismissing its introductory dialog never completes setup. Continue/Skip saves completion before opening the initial ordinary chat. Headers and footers remain fixed while the company form or integration list scrolls.
After building the production frontend, run bun run scripts/onboarding-integrations-journey.ts.
The isolated fixture covers the company form, explanatory dialog, search, credential errors and
refresh-safe drafts, OAuth return URLs, reloads, mobile geometry, completion retries, ordinary chat,
and skipping when the catalog is unavailable. It does not invoke providers or modify real companies.