8.3 KiB
8.3 KiB
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 33-persistent-memory | 02 | execute | 1 |
|
true |
|
|
Purpose: ASST-04 requires assistant and project builder modes to work standalone or together. The PersonalAssistantPage is the entry point for assistant mode. Output: Working assistant page with mode-gated visibility, sidebar link, and memory API client.
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/33-persistent-memory/33-RESEARCH.md @ui/src/App.tsx @ui/src/components/Layout.tsx @ui/src/api/hardware.ts @ui/src/components/ChatPanel.tsxFrom ui/src/api/hardware.ts:
export type NexusMode = "personal_ai" | "project_builder" | "both";
export interface NexusSettings { mode: NexusMode; }
export function fetchNexusSettings(): Promise<NexusSettings>;
From ui/src/App.tsx (route pattern):
// Board routes at line 122-180
function boardRoutes() {
return <>
<Route index element={<Navigate to="dashboard" replace />} />
<Route path="dashboard" element={<Dashboard />} />
// ... more routes
</>;
}
From ui/src/components/Layout.tsx (sidebar pattern):
// ChatPanel rendered at line 463
// Sidebar NavLinks with icons (lucide-react)
From ui/src/components/ChatPanel.tsx:
// Existing chat panel component — renders conversation list + message list
// Used as slide-over panel in Layout
Task 1: Create useNexusMode hook, memory API client, and PersonalAssistantPage
ui/src/hooks/useNexusMode.ts,
ui/src/api/assistantMemory.ts,
ui/src/pages/PersonalAssistant.tsx
Create `ui/src/hooks/useNexusMode.ts`:
- Export `useNexusMode()` hook that calls `useQuery` with key `["nexus", "settings"]` fetching `fetchNexusSettings()` from `../api/hardware`
- Return `{ mode, isLoading, isAssistantEnabled }` where `isAssistantEnabled = mode !== "project_builder"`
- Default mode to `"both"` while loading
Create `ui/src/api/assistantMemory.ts`:
- Export `assistantMemoryApi` object with:
- `getMemory(companyId: string)` — GET `/assistant-memory/${companyId}` using `api.get`
- `appendFact(companyId: string, fact: string)` — PATCH `/assistant-memory/${companyId}` with `{ fact }`
- `clearMemory(companyId: string)` — DELETE `/assistant-memory/${companyId}`
- Import `api` from `./client`
Create `ui/src/pages/PersonalAssistant.tsx`:
- Export default `PersonalAssistant` component
- Use `useNexusMode()` — if `!isAssistantEnabled`, render `<Navigate to="/dashboard" replace />`
- Render a full-page chat layout:
- Use `useCompany()` to get `selectedCompany`
- Create or retrieve an assistant conversation (use existing `chatApi.listConversations` with a dedicated agent filter, or create a new one)
- Render `ChatPanel`-style UI: conversation list on left, messages on right
- Include a header with "Personal Assistant" title and a "Turn this into a project" button (wired in Plan 03)
- Styling: Use existing Tailwind patterns from Layout.tsx. Full height (`h-full`), flex layout, clean assistant-focused design.
- The "Turn this into a project" button should be present but disabled with tooltip "Coming soon" — Plan 03 wires the actual handoff.
ui/src/api/hardware.ts,
ui/src/api/client.ts,
ui/src/components/ChatPanel.tsx,
ui/src/context/CompanyContext.tsx,
ui/src/hooks/useStreamingChat.ts,
ui/src/components/ChatMessageList.tsx
pnpm --filter @paperclipai/ui tsc --noEmit
- grep -q "useNexusMode" ui/src/hooks/useNexusMode.ts
- grep -q "isAssistantEnabled" ui/src/hooks/useNexusMode.ts
- grep -q "fetchNexusSettings" ui/src/hooks/useNexusMode.ts
- grep -q "assistantMemoryApi" ui/src/api/assistantMemory.ts
- grep -q "appendFact" ui/src/api/assistantMemory.ts
- grep -q "PersonalAssistant" ui/src/pages/PersonalAssistant.tsx
- grep -q "useNexusMode" ui/src/pages/PersonalAssistant.tsx
- grep -q "project_builder\|isAssistantEnabled" ui/src/pages/PersonalAssistant.tsx
PersonalAssistant page renders full-page chat when mode allows, redirects to dashboard when project_builder only. Memory API client ready. Mode hook available for any component.
Task 2: Wire assistant route in App.tsx and sidebar link in Layout.tsx
ui/src/App.tsx,
ui/src/components/Layout.tsx
In `ui/src/App.tsx`:
- Add lazy import: `const PersonalAssistant = React.lazy(() => import("./pages/PersonalAssistant"));` (or direct import if lazy loading is not used in this codebase — check existing import pattern)
- Add route inside `boardRoutes()` function, after the dashboard route: `} />`
- Also add `} />` for direct conversation linking
In `ui/src/components/Layout.tsx`:
- Add a sidebar NavLink for the assistant page
- Use `MessageCircle` or `Bot` icon from lucide-react (check which icons are already imported)
- Place it prominently — after Dashboard in the nav order
- Gate visibility using `useNexusMode()` — only show when `isAssistantEnabled` is true
- NavLink target: `/assistant`
- Label: "Assistant"
ui/src/App.tsx,
ui/src/components/Layout.tsx
pnpm --filter @paperclipai/ui tsc --noEmit
- grep -q "PersonalAssistant" ui/src/App.tsx
- grep -q "assistant" ui/src/App.tsx
- grep -q "assistant" ui/src/components/Layout.tsx
- grep -q "useNexusMode\|isAssistantEnabled" ui/src/components/Layout.tsx
/assistant route exists and renders PersonalAssistant page. Sidebar shows Assistant link when mode is personal_ai or both, hidden when project_builder. TypeScript compiles clean.
pnpm --filter @paperclipai/ui tsc --noEmit
<success_criteria>
- PersonalAssistantPage renders chat interface when mode allows
- Route /assistant exists in board routes
- Sidebar link visible only when assistant mode enabled
- Mode redirect works (project_builder -> dashboard)
- TypeScript compiles without errors </success_criteria>