nexus/docs/plans/2026-04-11-nexus-phase-13-settings-consolidation.md
Nexus Dev 87b45c730c docs(nexus): wave 3 plans (phases 12-16) + phase 11.5 backlog
Six plans drafted after Wave 2 completed:

Phase 11.5 — per-project scoping follow-up (BACKLOG)
  The 5 BLOCKED tabs from Phase 11 (Agents, Gates, Costs, Activity,
  Org) each need projectId scoping in the corresponding backend types
  and list components. Not time-critical — shipped as TabPlaceholder
  components in Phase 11 with honest data-gap badges. Each of the 5
  tickets is self-contained and can run independently when the
  placeholder UX hurts or when Wave 3 completes. Recommends dropping
  the Org tab entirely rather than building per-project scoping for it.

Phase 12 — Promote-to-project transition (WAVE 3)
  Replaces Phase 9's synchronous assistantHandoff() with the animated
  700ms compress-and-rise from spec 5.6. New files: PromoteTransition,
  BrainstormerPanel, usePromoteToProject state machine. CSS-first
  animation, not Motion library. Respects prefers-reduced-motion.
  Depends on Phase 9 (Assistant) and Phase 11 (Projects).

Phase 13 — Settings consolidation (WAVE 3)
  Collapses the nested instance-settings tree into a single-column
  scroll with 8 section cards (Workspace, LocalAI, Cloud, Skills,
  Routines, Telegram, About, Danger). Phase 13 is the one phase
  where routing changes ARE phase-owned: it strips nested
  /instance/settings sub-routes and replaces with Navigate redirects.

Phase 14 — Voice + CmdK globalization (WAVE 3)
  Lifts voice state out of ChatInput's internal VoiceMicButton into
  a shared VoiceContext so the top-strip GlobalMicButton becomes
  functional from any route, with speech queued to the Assistant
  inbox per spec 5.5. Replaces the CmdKButton synthetic-keydown shim
  with a real CommandPaletteContext. Extends CommandPalette search
  to cover conversations, projects, issues, agents, settings,
  workshops. Also fixes the pre-existing useKeyboardShortcuts.ts
  destructure bug caught during Phase 6/11 reviews.

Phase 15 — Mobile parity (WAVE 3)
  4-destination MobileTabBar replacing MobileBottomNav. History +
  Memory sheets become full-screen on mobile. Promote transition
  uses a full-screen takeover instead of split layout. BuilderTabStrip
  scrolls horizontally with edge fades. Single 768px breakpoint.

Phase 16 — Cleanup pass (WAVE 4, sequential)
  Deletes dead chrome files (ChatPanel, ChatPanelContext, Sidebar,
  InstanceSidebar, BreadcrumbBar, PropertiesPanel, MobileBottomNav).
  Migrates ChatMessageList off ChatPanelContext first (flagged
  hazard from Phase 9). Vocabulary sweep company to workspace in
  UI strings only (backend keeps company identifiers per upstream
  sync constraint). Fixes the minor issues accumulated across
  Phase 8-15 reviews (useKeyboardShortcuts destructure bug,
  GlobalMicButton test double-render, Projects umbrella regex
  duplication, PersonalAssistant brittle fixed height). Visual
  QA pass.

Wave structure for Wave 3 dispatch:
  Wave 3A: Phase 12, Phase 13, Phase 14, Phase 15 in parallel
           (4 subagents, disjoint file ownership)
  Wave 3B: Phase 16 sequential (intentionally touches everything)

Phase 11.5 stays in backlog — not in any wave. It activates when
the TabPlaceholder UX becomes a friction point or when a milestone
explicitly pulls one of its tickets into scope.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 13:11:12 +00:00

8.1 KiB

Nexus Phase 13 — Settings Consolidation

Use superpowers:test-driven-development. Commit atomically per section.

Goal: Collapse the current Paperclip nested instance-settings tree (/instance/settings/general, /instance/settings/integrations, …) into a single-column scroll page at /instance/settings/general (the URL stays so existing bookmarks still work) with ~8 section cards per docs/specs/2026-04-11-nexus-layout-overhaul.md §8. Move the Skill Aggregator, Routines, Telegram bridge, and re-run onboarding link into section cards. Drop the nested sub-routes from App.tsx (they redirect to the single page).

Source of truth: spec §8 (Mode 4 — Settings). Phase 8 established the frame; the Settings destination in the IconRail already points at /instance/settings/general.

Branch: nexus/design-system-migration.


Ownership boundaries

You may create or modify ONLY:

Path Action
ui/src/pages/InstanceSettings.tsx (or equivalent single page) Major rewrite into single-column scroll
ui/src/pages/instance/settings/** or sub-pages Modify — kill the child sub-pages, fold into sections
ui/src/components/settings/** Create (new subdir for section cards)
ui/src/App.tsx Routes may be removed (nested settings sub-routes) — see note

Exception on App.tsx: Phase 13 is the one phase where routing changes ARE owned by the phase, because the instance-settings tree is being collapsed. You may remove nested /instance/settings/integrations, /instance/settings/adapters, etc. routes and replace them with <Navigate to="/instance/settings/general" replace /> redirects so existing bookmarks still work. Do not touch any other App.tsx route.

You MUST NOT touch:

  • ui/src/pages/PersonalAssistant.tsx, ui/src/components/assistant/** (Phase 9/12)
  • ui/src/pages/Projects.tsx, ui/src/pages/ProjectDetail.tsx, ui/src/components/projects/** (Phase 11)
  • ui/src/pages/ContentStudio.tsx, ui/src/pages/StudioWorkshopDetail.tsx, ui/src/components/studio/** (Phase 10)
  • ui/src/components/Layout.tsx, ui/src/components/frame/** (Phase 8)
  • Any backend code

Scope (strictly)

Section cards per spec §8.1

  1. WORKSPACE — root directory, theme toggle (dark/light), re-run onboarding link
  2. LOCAL AI — Hermes provider, Whisper STT model, Piper TTS voice
  3. CLOUD PROVIDERS — Anthropic / OpenAI API keys (masked), Puter.js status
  4. SKILLS — Skill Aggregator browse/install/assign (currently wherever it lives; Phase 13 folds it in)
  5. ROUTINES — list of workspace routines with edit/pause (currently the top-level /routines route — folded in; that route stays for backwards compat)
  6. TELEGRAM BRIDGE — bot token, allowed chat IDs
  7. ABOUT — Nexus version, fork info, MIT license
  8. DANGER ZONE — reset workspace, delete all conversations

Each card: 1px charcoal border, 8px radius, 24px padding, transparent fill. Uppercase 1.4px-tracked title in silver + hairline rule. Sections listed vertically with 24px gap.

What to preserve from the existing nested pages

  • All existing form state, field validation, save handlers
  • The API endpoints each section uses (likely instanceSettingsApi, skillsApi, routinesApi, etc.)
  • Access control checks (though single-user self-hosted, some checks may still exist)

What to kill from the chrome

  • The old left-rail InstanceSidebar that showed nested settings sub-links — already unmounted by Phase 8 but the component file may linger; delete it in Phase 13 along with its test file
  • Any /instance/settings/* sub-routes other than /general

File plan

File Action
ui/src/pages/InstanceSettings.tsx (or the existing main settings page file) Rewrite into single-column scroll that renders 8 section cards
ui/src/components/settings/WorkspaceSection.tsx Create
ui/src/components/settings/LocalAISection.tsx Create
ui/src/components/settings/CloudProvidersSection.tsx Create
ui/src/components/settings/SkillsSection.tsx Create (embeds Skill Aggregator)
ui/src/components/settings/RoutinesSection.tsx Create (reuses routines list components)
ui/src/components/settings/TelegramSection.tsx Create
ui/src/components/settings/AboutSection.tsx Create
ui/src/components/settings/DangerZoneSection.tsx Create
Each section + .test.tsx for tests Create tests
ui/src/components/InstanceSidebar.tsx Delete (was a Phase 8 legacy candidate)
ui/src/App.tsx Strip nested /instance/settings/* sub-routes except /general; add redirect stubs

Implementation notes

Single-page layout

export function InstanceSettings() {
  return (
    <div className="mx-auto w-full max-w-[960px] px-6 py-8 space-y-6">
      <h1 className="text-[14px] font-semibold uppercase tracking-[0.1em] text-primary">
        Settings
      </h1>
      <WorkspaceSection />
      <LocalAISection />
      <CloudProvidersSection />
      <SkillsSection />
      <RoutinesSection />
      <TelegramSection />
      <AboutSection />
      <DangerZoneSection />
    </div>
  );
}

Section card skeleton

Every section uses the same shell:

export function SettingsSection({ title, children }: { title: string; children: ReactNode }) {
  return (
    <section
      aria-label={title}
      className="rounded-[8px] border border-border bg-transparent p-6"
    >
      <header className="mb-4">
        <h2 className="text-[12px] font-semibold uppercase tracking-[0.14em] text-muted-foreground">
          {title}
        </h2>
        <hr className="mt-2 border-border" />
      </header>
      <div className="space-y-4">{children}</div>
    </section>
  );
}

Consider extracting SettingsSection as a shared primitive in components/settings/SettingsSection.tsx and importing it from all 8 section files — that's 9 files total but keeps each section shell 1-line and eliminates drift.

Routines fold-in strategy

The existing /routines top-level route and its page stay. The Routines section in Settings either:

  • (a) renders a compact read-only list of routines with an "open full routines page" link that navigates to /routines, OR
  • (b) renders the full interactive routines UI inline

Recommendation (a) — single responsibility per page. Phase 16 decides whether to delete /routines.

Skills fold-in

Same pattern: the Skills section embeds the Skill Aggregator UI inline (browse + installed count + assignments) OR links out to a Skill Aggregator page if one exists. Read the codebase to find where Skills currently live. If there's an existing route, link to it from the section; if it's unrouted, embed the component.


Acceptance criteria

  1. /instance/settings/general renders a single-column scroll page with 8 section cards
  2. Any previous /instance/settings/<sub> URL (e.g., /instance/settings/integrations) redirects to /instance/settings/general
  3. The theme toggle in the WORKSPACE section switches between light/dark and persists
  4. API key fields mask their values and never log them
  5. All new components have tests using the Phase 8 pattern
  6. npx vitest run src/components/settings/ passes
  7. npx tsc --noEmit 2>&1 | grep -E "(settings/|InstanceSettings\.tsx)" clean
  8. InstanceSidebar.tsx deleted (and any other dead settings chrome files)
  9. No file outside declared ownership touched
  10. Existing settings functionality preserved — nothing breaks

Before you begin

Read:

  • ui/src/pages/InstanceSettings.tsx (or whatever the main settings page is named)
  • Any nested settings sub-pages (grep for InstanceSettings*.tsx or look under ui/src/pages/instance/settings/)
  • ui/src/api/instanceSettings.ts for the API shape
  • The current routines list component and skills aggregator UI locations

Report format

  • Status
  • Commit SHAs
  • Files created / modified / deleted
  • Tests added / passing
  • Typecheck result
  • Nested sub-routes removed and their redirect targets
  • Skill Aggregator fold-in strategy (inline vs link-out)
  • Routines section strategy (compact list vs full inline)
  • Concerns, deviations, self-review