From 1cd7a59dfc39a2b1f8b65a0fcb4244e081fd146a Mon Sep 17 00:00:00 2001 From: Roberto Date: Fri, 15 May 2026 22:30:34 +0200 Subject: [PATCH] Add Contextual chat --- adiuvAI | 2 +- ...6-05-15-floating-chat-deprecation-sweep.md | 967 + graphify-out/GRAPH_REPORT.md | 1109 +- graphify-out/graph.html | 10 +- graphify-out/graph.json | 19681 +++++++++++++--- 5 files changed, 17478 insertions(+), 4291 deletions(-) create mode 100644 docs/superpowers/plans/2026-05-15-floating-chat-deprecation-sweep.md diff --git a/adiuvAI b/adiuvAI index 6aa7cb3..c1b1b28 160000 --- a/adiuvAI +++ b/adiuvAI @@ -1 +1 @@ -Subproject commit 6aa7cb3d223de12dcbf4b2c09564ae8487886284 +Subproject commit c1b1b289c1750fb282aed3cc63735ac4b755b719 diff --git a/docs/superpowers/plans/2026-05-15-floating-chat-deprecation-sweep.md b/docs/superpowers/plans/2026-05-15-floating-chat-deprecation-sweep.md new file mode 100644 index 0000000..a8a7065 --- /dev/null +++ b/docs/superpowers/plans/2026-05-15-floating-chat-deprecation-sweep.md @@ -0,0 +1,967 @@ +# Floating Chat Deprecation Sweep Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Delete every floating-chat code path across the adiuvAI Electron app — components, context, hooks, DOM attributes, stream branches, main-process methods, and shared-type artefacts — in five clean commits. + +**Architecture:** The contextual sidebar (M4) fully replaces floating chat; floating is dead code with no live consumers. Each task targets one layer: (1) renderer components/context/hooks, (2) DOM data-attributes, (3) renderer hook logic, (4) main-process IPC/orchestrator, (5) store/localStorage keys sweep. + +**Tech Stack:** TypeScript, React 19, Electron (main + preload + renderer), tRPC v11, Zod, electron-store. + +--- + +## Pre-flight: baseline tsc check + +- [ ] **Run tsc before touching anything** + +```bash +cd /c/Users/PC-Roby/Documents/_adiuvai_workspace/adiuvAI +source ~/.nvm/nvm.sh && npx tsc --noEmit 2>&1 | tail -20 +``` + +Record the number of pre-existing errors (expected: 0). Any errors here are pre-existing and not your fault. + +--- + +## Task M6.1 — Delete FloatingChat component, context, hook + AppShell cleanup + +**Files:** +- Delete: `src/renderer/components/ai/FloatingChat.tsx` +- Delete: `src/renderer/context/FloatingChatContext.tsx` +- Delete: `src/renderer/hooks/useDoubleClickAI.ts` +- Modify: `src/renderer/components/layout/AppShell.tsx` +- Modify: `src/renderer/components/projects/ProjectDetail.tsx` +- Modify: `src/renderer/components/timeline/TimelineGanttView.tsx` +- Modify: `src/renderer/routes/notes.$noteId.tsx` +- Modify: `src/renderer/routes/tasks.tsx` + +### Context + +Six files import from `FloatingChatContext` or `FloatingChat`. After deleting the three source files, all six must be cleaned up. + +`ProjectDetail.tsx`, `TimelineGanttView.tsx`, `notes.$noteId.tsx`, and `tasks.tsx` import `useFloatingChat()` and call `registerSection`/`unregisterSection`. These are pure floating-chat wiring — they register DOM regions with the floating panel so it could anchor itself. With floating chat gone, these calls become dead code and must be removed entirely (no replacement needed; the contextual sidebar uses `useContextualScope` for scope awareness, which is already imported in tasks.tsx and ProjectDetail.tsx). + +`AppShell.tsx` wraps the tree in `` (line 151) and calls `useDoubleClickAI()` inside `AppShellInner` (line 166). + +### Steps + +- [ ] **Step 1: Confirm all consumers before deletion** + +```bash +grep -rn "FloatingChat\|useFloatingChat\|FloatingChatProvider\|useDoubleClickAI" src/renderer/ +``` + +Expected output matches: `AppShell.tsx`, `FloatingChat.tsx`, `FloatingChatContext.tsx`, `useDoubleClickAI.ts`, `ProjectDetail.tsx`, `TimelineGanttView.tsx`, `notes.$noteId.tsx`, `tasks.tsx`. If any unexpected file appears, stop and report before proceeding. + +- [ ] **Step 2: Delete the three source files** + +```bash +git rm src/renderer/components/ai/FloatingChat.tsx +git rm src/renderer/context/FloatingChatContext.tsx +git rm src/renderer/hooks/useDoubleClickAI.ts +``` + +- [ ] **Step 3: Clean AppShell.tsx** + +Open `src/renderer/components/layout/AppShell.tsx`. + +Remove line 28: +```ts +import { useDoubleClickAI } from '@/hooks/useDoubleClickAI'; +``` + +Remove lines 70–71: +```ts +import { FloatingChatPortal } from '@/components/ai/FloatingChat'; +import { FloatingChatProvider } from '@/context/FloatingChatContext'; +``` + +In `AppShell` (around line 149–163), change: +```tsx +export function AppShell({ children }: AppShellProps) { + return ( + + + + +
+ {children} +
+
+
+
+
+ ); +} +``` +to: +```tsx +export function AppShell({ children }: AppShellProps) { + return ( + + + +
+ {children} +
+
+
+
+ ); +} +``` + +In `AppShellInner` (around line 166), remove: +```ts +useDoubleClickAI(); +``` + +Search for `` in the file (around line 288) and delete that line. + +- [ ] **Step 4: Clean ProjectDetail.tsx** + +Open `src/renderer/components/projects/ProjectDetail.tsx`. + +Remove line 24: +```ts +import { useFloatingChat } from '@/context/FloatingChatContext'; +``` + +Remove line 63: +```ts +const { registerSection, unregisterSection } = useFloatingChat(); +``` + +Remove the `useEffect` block that calls `registerSection`/`unregisterSection` (lines ~91–101): +```ts +useEffect(() => { + if (isLoading || !project) return; + registerSection({ id: 'project-summary', label: 'Project Summary', ref: summaryRef, projectId }); + registerSection({ id: 'project-tasks', label: 'Tasks', ref: tasksRef, projectId }); + registerSection({ id: 'project-notes', label: 'Notes', ref: notesRef, projectId }); + return () => { + unregisterSection('project-summary'); + unregisterSection('project-tasks'); + unregisterSection('project-notes'); + }; +}, [projectId, isLoading, project, registerSection, unregisterSection]); +``` + +- [ ] **Step 5: Clean TimelineGanttView.tsx** + +Open `src/renderer/components/timeline/TimelineGanttView.tsx`. + +Remove line 31: +```ts +import { useFloatingChat } from '@/context/FloatingChatContext'; +``` + +Remove line 95: +```ts +const { registerSection, unregisterSection } = useFloatingChat(); +``` + +Remove the `useEffect` that calls `registerSection`/`unregisterSection` (lines ~107–110): +```ts +useEffect(() => { + registerSection({ id: sectionId, label: sectionLabel, ref: sectionRef, projectId }); + return () => unregisterSection(sectionId); +}, [sectionId, sectionLabel, projectId, registerSection, unregisterSection]); +``` + +- [ ] **Step 6: Clean notes.$noteId.tsx** + +Open `src/renderer/routes/notes.$noteId.tsx`. + +Remove line 29: +```ts +import { useFloatingChat } from '@/context/FloatingChatContext'; +``` + +Remove line 117: +```ts +const { registerSection, unregisterSection } = useFloatingChat(); +``` + +Remove the `useEffect` that calls `registerSection`/`unregisterSection` (lines ~119–128): +```ts +useEffect(() => { + registerSection({ + id: 'note-editor', + label: 'Note Editor', + ref: editorRef, + projectId: noteProjectId, + anchorMode: 'right-margin', + }); + return () => unregisterSection('note-editor'); +}, [noteId, noteProjectId, registerSection, unregisterSection]); +``` + +- [ ] **Step 7: Clean tasks.tsx** + +Open `src/renderer/routes/tasks.tsx`. + +Remove line 5: +```ts +import { useFloatingChat } from '@/context/FloatingChatContext'; +``` + +Remove line 18: +```ts +const { registerSection, unregisterSection } = useFloatingChat(); +``` + +Remove the `useEffect` that calls `registerSection`/`unregisterSection` (lines ~20–27): +```ts +useEffect(() => { + registerSection({ id: 'tasks-overview', label: 'Tasks Overview', ref: overviewRef }); + registerSection({ id: 'tasks-list', label: 'Task List', ref: listRef }); + return () => { + unregisterSection('tasks-overview'); + unregisterSection('tasks-list'); + }; +}, [registerSection, unregisterSection]); +``` + +Also remove the `overviewRef` and `listRef` ref declarations if they are now unused (check whether they are still referenced by the JSX `ref=` attributes after M6.2 strips `data-ai-section`): +```ts +const overviewRef = useRef(null); +const listRef = useRef(null); +``` + +Note: After M6.2 removes `data-ai-section` attributes, `ref={overviewRef}` and `ref={listRef}` in the JSX will also be gone, making the refs fully dead. Remove them here (or in M6.2 — just do it in whichever task you're in when you notice them). + +- [ ] **Step 8: Type check** + +```bash +source ~/.nvm/nvm.sh && npx tsc --noEmit 2>&1 | grep -i "error" | head -30 +``` + +Expected: zero errors related to FloatingChat, FloatingChatContext, useDoubleClickAI. If any appear, locate the offending file and remove the import/usage. + +- [ ] **Step 9: Commit** + +```bash +git add src/renderer/components/layout/AppShell.tsx \ + src/renderer/components/projects/ProjectDetail.tsx \ + src/renderer/components/timeline/TimelineGanttView.tsx \ + src/renderer/routes/notes.\$noteId.tsx \ + src/renderer/routes/tasks.tsx +git commit -m "$(cat <<'EOF' +refactor(contextual): delete FloatingChat, FloatingChatContext, useDoubleClickAI + +Replaced by ContextualChatProvider + AdiuvaTriggerButton in M4. +Pre-1.0 clean removal — no deprecation period. +EOF +)" +``` + +--- + +## Task M6.2 — Strip all `data-ai-section` attributes + +**Files:** +- Modify: `src/renderer/components/projects/ProjectDetail.tsx` +- Modify: `src/renderer/components/timeline/TimelineGanttView.tsx` +- Modify: `src/renderer/routes/notes.$noteId.tsx` +- Modify: `src/renderer/routes/tasks.tsx` + +### Context + +`data-ai-section` was used by `useDoubleClickAI` to walk the DOM and find the nearest section anchor to open floating chat. Now that floating chat is gone, these attributes are purely dead markup. The contextual sidebar uses `scope` payloads, not DOM attributes. + +Current occurrences (7 total): +- `ProjectDetail.tsx:538` — `data-ai-section="project-summary"` +- `ProjectDetail.tsx:620` — `data-ai-section="project-tasks"` +- `ProjectDetail.tsx:631` — `data-ai-section="project-notes"` +- `TimelineGanttView.tsx:239` — `data-ai-section={sectionId}` +- `notes.$noteId.tsx:291` — `data-ai-section="note-editor"` +- `tasks.tsx:42` — `data-ai-section="tasks-overview"` +- `tasks.tsx:61` — `data-ai-section="tasks-list"` + +### Steps + +- [ ] **Step 1: List all occurrences** + +```bash +grep -rn "data-ai-section" src/renderer/ +``` + +Confirm you see exactly the 7 occurrences listed above. If more appear, handle them too. + +- [ ] **Step 2: Remove from ProjectDetail.tsx** + +For each JSX element with a `data-ai-section` prop, delete only that prop (keep `className` and all others). Example: + +Find: +```tsx +
+``` +Change to: +```tsx +
+``` + +Repeat for `project-tasks` and `project-notes`. + +- [ ] **Step 3: Remove from TimelineGanttView.tsx** + +Find the element at line ~239 and remove only the `data-ai-section={sectionId}` prop. Keep `ref={sectionRef}` and any other props. + +Also check: after M6.1 removed `registerSection`/`unregisterSection`, there may now be `sectionRef`, `sectionId`, `sectionLabel` variables declared but unused. Remove any that are now dead. Check with: + +```bash +grep -n "sectionRef\|sectionId\|sectionLabel" src/renderer/components/timeline/TimelineGanttView.tsx +``` + +If these variables are only used by the removed `useEffect` and the now-removed `data-ai-section` attribute, delete their declarations too. + +- [ ] **Step 4: Remove from notes.$noteId.tsx** + +Find the `` at line ~291: +```tsx + +``` +Change to: +```tsx + +``` + +Note: `editorRef` is still used by the existing scroll area ref, so keep it. + +- [ ] **Step 5: Remove from tasks.tsx** + +Remove `data-ai-section="tasks-overview"` from the div at line ~42 and `data-ai-section="tasks-list"` from the div at line ~61. Also remove `ref={overviewRef}` and `ref={listRef}` from those elements if the refs were removed in M6.1. + +If `overviewRef` and `listRef` are now unused (no JSX `ref=` and no other use), delete their `useRef` declarations too. + +- [ ] **Step 6: Verify clean** + +```bash +grep -rn "data-ai-section" src/renderer/ +echo "exit=$?" +``` + +Expected: no output, `exit=1` (grep found nothing). + +- [ ] **Step 7: Type check + commit** + +```bash +source ~/.nvm/nvm.sh && npx tsc --noEmit 2>&1 | grep -i "error" | head -20 +``` + +Expected: zero errors. + +```bash +git add src/renderer/components/projects/ProjectDetail.tsx \ + src/renderer/components/timeline/TimelineGanttView.tsx \ + src/renderer/routes/notes.\$noteId.tsx \ + src/renderer/routes/tasks.tsx +git commit -m "$(cat <<'EOF' +refactor(contextual): strip all data-ai-section attributes + +Section-anchoring obsolete now that there is no floating chat. +The contextual sidebar uses scope payload, not DOM attributes. +EOF +)" +``` + +--- + +## Task M6.3 — Drop `'floating'` from `useAIChat` + `ChatInputBox` + `useChatStream` + +**Files:** +- Modify: `src/renderer/hooks/useAIChat.ts` +- Modify: `src/renderer/hooks/useChatStream.ts` +- Modify: `src/renderer/components/ai/ChatInputBox.tsx` +- Modify: `src/renderer/components/brief/TaskBriefChat.tsx` + +### Context + +`useAIChat.ts` has `FloatingDomainSignal` type, `'floating'` in `UIChatContext.type` union, a `scope` field, a `'floating'` cache-key branch, `isFloating` logic in `handleSend`, `floating_domain` switch case, and `onDomainSignalRef`. All dead after M6.1 deleted `FloatingChat.tsx` which was the only consumer. + +`useChatStream.ts` has a `floating_domain` case and the `onDomainSignal` option — kept during M2.1 explicitly "until M6 removes floating." Now is the time. + +`ChatInputBox.tsx` has `'floating'` as a variant in `ChatInputBoxVariant` with its own style entry. This is a visual variant only — the type can be removed if nothing still passes `variant="floating"`. After `FloatingChat.tsx` is gone, nothing does. + +`TaskBriefChat.tsx` passes `mode: 'floating'` to `chatMutation.mutate(...)`. After removing the floating mode from the tRPC schema (M6.4), this becomes a type error. Fix it here by removing `mode: 'floating'` and `scope` from the mutation call — task briefs will fall through to the default home orchestrator, or better: use `mode: 'contextual'` with the scope. Since task brief already passes `scope: { type: 'task', id: taskId }`, change `mode: 'floating'` to `mode: 'contextual'`. + +`parseMutationsToEntityTags` and `TABLE_TO_ENTITY` in `useAIChat.ts` are still needed — `useChatStream.ts` imports `parseMutationsToEntityTags` from `useAIChat.ts`. Keep both exports. + +### Steps + +- [ ] **Step 1: Edit useAIChat.ts** + +Open `src/renderer/hooks/useAIChat.ts`. + +**Delete lines 4–13** (the `FloatingDomainSignal` type): +```ts +export type FloatingDomainSignal = + | 'tasks' + | 'notes' + | 'timelines' + | 'projects' + | { + type: 'task' | 'timeline' | 'project' | 'note' | 'node'; + id?: string | null; + section?: 'task' | 'timeline' | 'note' | null; + }; +``` + +**Replace the `UIChatContext` interface** (lines 23–31): +```ts +export interface UIChatContext { + type: 'global' | 'project' | 'floating'; + projectId?: string; + /** For floating mode — the entity scope to pass to the backend. */ + scope?: { + type: 'task' | 'project' | 'note' | 'timeline'; + id?: string; + }; +} +``` +with: +```ts +export interface UIChatContext { + type: 'global' | 'project'; + projectId?: string; +} +``` + +**Delete the `UseAIChatOptions` interface** (lines 50–52): +```ts +interface UseAIChatOptions { + onDomainSignal?: (domain: FloatingDomainSignal) => void; +} +``` + +**Update the `useAIChat` function signature** — remove the `options` parameter: +```ts +export function useAIChat(defaultContext: UIChatContext, options?: UseAIChatOptions): UseAIChatReturn { +``` +becomes: +```ts +export function useAIChat(defaultContext: UIChatContext): UseAIChatReturn { +``` + +**Update `getContextCacheKey`** — replace the entire function body: +```ts +function getContextCacheKey(ctx: UIChatContext): string { + if (ctx.type === 'global') return 'global'; + if (ctx.type === 'project') return `project:${ctx.projectId ?? ''}`; + + // Floating chat should keep a single continuous session while the panel is open, + // even when route/section context changes due floating-domain navigation. + return 'floating'; +} +``` +with: +```ts +function getContextCacheKey(ctx: UIChatContext): string { + if (ctx.type === 'global') return 'global'; + return `project:${ctx.projectId ?? ''}`; +} +``` + +**Update the `useMemo` for `contextCacheKey`** — remove `defaultContext.scope?.type` and `defaultContext.scope?.id` from deps: +```ts +const contextCacheKey = useMemo( + () => getContextCacheKey(defaultContext), + [defaultContext.type, defaultContext.projectId, defaultContext.scope?.type, defaultContext.scope?.id], +); +``` +becomes: +```ts +const contextCacheKey = useMemo( + () => getContextCacheKey(defaultContext), + [defaultContext.type, defaultContext.projectId], +); +``` + +**Remove `onDomainSignalRef`** (lines 151–152): +```ts +const onDomainSignalRef = useRef(options?.onDomainSignal); +onDomainSignalRef.current = options?.onDomainSignal; +``` + +**Remove the `floating_domain` case** from the `switch (event.type)` block (lines 237–239): +```ts +case 'floating_domain': + onDomainSignalRef.current?.(event.domain); + break; +``` + +**Remove `isFloating` and the conditional spread** in `handleSend` (lines 249–259): +```ts +const isFloating = ctx.type === 'floating'; + +chatMutationRef.current.mutate( + { + requestId, + message: trimmed, + conversationHistory, + sessionId: sessionIdRef.current, + ...(isFloating && ctx.scope + ? { mode: 'floating' as const, scope: ctx.scope } + : {}), + }, +``` +becomes: +```ts +chatMutationRef.current.mutate( + { + requestId, + message: trimmed, + conversationHistory, + sessionId: sessionIdRef.current, + }, +``` + +- [ ] **Step 2: Edit useChatStream.ts** + +Open `src/renderer/hooks/useChatStream.ts`. + +Remove `onDomainSignal` from `UseChatStreamArgs` interface (lines 17–18): +```ts + /** Optional: legacy floating_domain pivot signal. Kept until M6 removes floating. */ + onDomainSignal?: (domain: unknown) => void; +``` + +Remove `onDomainSignal` from the destructuring of `useChatStream`'s argument (line 25): +```ts + onDomainSignal, +``` + +Remove `domainRef` declarations (lines 33–34): +```ts + const domainRef = useRef(onDomainSignal); + domainRef.current = onDomainSignal; +``` + +Remove the `floating_domain` case from the switch block (lines 70–72): +```ts + case 'floating_domain': + domainRef.current?.(event.domain); + break; +``` + +- [ ] **Step 3: Edit ChatInputBox.tsx** + +Open `src/renderer/components/ai/ChatInputBox.tsx`. + +The `'floating'` variant in `ChatInputBoxVariant` (line 12) and its entry in `VARIANT_STYLES` (lines 30–35) should be removed since no live code passes `variant="floating"` any more. + +Change: +```ts +type ChatInputBoxVariant = 'panel' | 'floating' | 'comment'; +``` +to: +```ts +type ChatInputBoxVariant = 'panel' | 'comment'; +``` + +Remove the `floating` entry from `VARIANT_STYLES` (lines 30–35): +```ts + floating: { + container: 'flex items-center gap-2 px-3 py-2.5', + textarea: 'flex-1 resize-none bg-transparent text-sm placeholder:text-muted-foreground/60 outline-none max-h-20 overflow-y-auto', + button: 'flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary text-primary-foreground shadow-sm transition-all hover:bg-primary/90 active:scale-95 disabled:opacity-30 disabled:cursor-not-allowed', + iconSize: 14, + }, +``` + +Also remove the comment about FloatingChat on line 52: +```ts + // Re-init when the cache key changes (context switches in FloatingChat). +``` +Replace with a neutral comment or just remove the comment line. + +- [ ] **Step 4: Fix TaskBriefChat.tsx** + +Open `src/renderer/components/brief/TaskBriefChat.tsx`. + +At line ~174–184, change: +```ts + chatMutation.mutate( + { + requestId, + message: trimmed, + conversationHistory, + sessionId, + mode: 'floating', + scope: { type: 'task', id: taskId }, + briefMode: true, + briefingContext: briefingText || undefined, + }, +``` +to: +```ts + chatMutation.mutate( + { + requestId, + message: trimmed, + conversationHistory, + sessionId, + mode: 'contextual', + scope: { type: 'task', id: taskId }, + briefMode: true, + briefingContext: briefingText || undefined, + }, +``` + +- [ ] **Step 5: Type check** + +```bash +source ~/.nvm/nvm.sh && npx tsc --noEmit 2>&1 | grep -i "error" | head -30 +``` + +Expected: zero errors. If tsc reports that `'floating'` is no longer valid for some type (from M6.4 not yet done), note it — the router schema still allows `'floating'` until M6.4. If tsc reports that `useAIChat` call sites are broken, check them: + +```bash +grep -rn "useAIChat" src/renderer/ +``` + +All call sites should be passing only `type: 'global'` or `type: 'project'` contexts after FloatingChat.tsx was deleted. + +- [ ] **Step 6: Commit** + +```bash +git add src/renderer/hooks/useAIChat.ts \ + src/renderer/hooks/useChatStream.ts \ + src/renderer/components/ai/ChatInputBox.tsx \ + src/renderer/components/brief/TaskBriefChat.tsx +git commit -m "$(cat <<'EOF' +refactor(contextual): drop 'floating' branch from useAIChat and useChatStream + +UIChatContext is now 'global' | 'project' only. Floating domain +signal, scope field, and onDomainSignal callback removed. ChatInputBox +no longer defines floating variant. TaskBriefChat migrated to contextual mode. +EOF +)" +``` + +--- + +## Task M6.4 — Main process: drop `sendFloatingRequest`, `orchestrateFloating`, floating mode + +**Files:** +- Modify: `src/main/api/backend-client.ts` +- Modify: `src/main/ai/orchestrator.ts` +- Modify: `src/main/router/index.ts` +- Modify: `src/preload/trpc.ts` +- Modify: `src/renderer/lib/ipcLink.ts` +- Modify: `src/shared/api-types.ts` + +### Context + +`backend-client.ts` has `sendFloatingRequest` (lines 398–458) and a `floating_domain` case in its WS message handler (lines 1060–1063). + +`orchestrator.ts` has `OrchestrateFloatingInput` interface (lines 40–49) and `orchestrateFloating` function (lines 142–173). It also imports `WsFloatingRequest` from shared types. + +`router/index.ts` imports `orchestrateFloating` (line 16) and uses it at lines 950–960. The `mode` enum must change from `z.enum(['home', 'floating', 'contextual'])` to `z.enum(['contextual'])`. + +`preload/trpc.ts` defines the `V3StreamEvent` union which includes `floating_domain` (lines 29–42). + +`renderer/lib/ipcLink.ts` defines a duplicate `V3StreamEvent` type which also includes `floating_domain` (lines 16–33). + +`shared/api-types.ts` defines `WsFloatingDomainSchema` (lines 217–228) and `WsFloatingDomain` type. + +Check also whether `WsFloatingRequest` type is still needed by anything after removing `orchestrateFloating`: +```bash +grep -rn "WsFloatingRequest\|WsFloatingDomain" src/ +``` + +### Steps + +- [ ] **Step 1: Delete sendFloatingRequest from backend-client.ts** + +Open `src/main/api/backend-client.ts`. + +Delete the entire `sendFloatingRequest` method (lines ~394–458), from the JSDoc comment through the closing `}`. + +Also delete the `floating_domain` case in the WS message handler (lines ~1060–1063): +```ts + case 'floating_domain': { + const listener = this.streamListeners.get(frame.data.requestId); + listener?.onDomain(frame.data.domain); + break; + } +``` + +Also check whether `onDomain` is still used in `StreamListener` type or elsewhere. If `onDomain` callback is only referenced by `sendFloatingRequest` and the `floating_domain` case, delete the `onDomain` field from `StreamListener` too (search for `onDomain` to confirm all uses). + +- [ ] **Step 2: Delete orchestrateFloating from orchestrator.ts** + +Open `src/main/ai/orchestrator.ts`. + +Delete lines 40–49 (`OrchestrateFloatingInput` interface): +```ts +interface OrchestrateFloatingInput { + message: string; + requestId?: string; + sessionId?: string; + scope: WsFloatingRequest['scope']; + conversationHistory?: WsFloatingRequest['conversationHistory']; + briefMode?: boolean; + briefingContext?: string; + sender?: Electron.WebContents; +} +``` + +Delete lines 1–16 of the import section's `WsFloatingRequest` import. Change: +```ts +import type { WsFloatingRequest } from '../../shared/api-types'; +``` +to nothing (remove the line entirely), since `WsFloatingRequest` is only used by `OrchestrateFloatingInput`. + +Delete the entire `orchestrateFloating` function (lines 142–173): +```ts +export async function orchestrateFloating(input: OrchestrateFloatingInput): Promise { + ... +} +``` + +Update the docstring at the top of the file (lines 1–10) — remove the reference to `sendFloatingRequest()`: +``` + * 2. Delegates to BackendClient.sendHomeRequest() / sendFloatingRequest() +``` +becomes: +``` + * 2. Delegates to BackendClient.sendHomeRequest() / sendContextualRequest() +``` + +- [ ] **Step 3: Update router/index.ts** + +Open `src/main/router/index.ts`. + +Change line 16 — remove `orchestrateFloating` from the import: +```ts +import { orchestrate, orchestrateFloating, orchestrateContextual, orchestrateTaskBriefResearch, dailyBrief, getCachedBrief, invalidateBriefCache } from '../ai/orchestrator'; +``` +becomes: +```ts +import { orchestrate, orchestrateContextual, orchestrateTaskBriefResearch, dailyBrief, getCachedBrief, invalidateBriefCache } from '../ai/orchestrator'; +``` + +Change line 933 — update the `mode` enum: +```ts + mode: z.enum(['home', 'floating', 'contextual']).optional(), +``` +becomes: +```ts + mode: z.enum(['contextual']).optional(), +``` + +Delete the floating branch in the mutation handler (lines 950–960): +```ts + if (input.mode === 'floating' && input.scope) { + return await orchestrateFloating({ + message: input.message, + requestId: input.requestId, + sessionId: input.sessionId, + scope: input.scope as Parameters[0]['scope'], + conversationHistory: input.conversationHistory, + briefMode: input.briefMode, + briefingContext: input.briefingContext, + sender: ctx.sender, + }); + } +``` + +The resulting mutation handler should flow: `if contextual → orchestrateContextual`, else `→ orchestrate`. + +- [ ] **Step 4: Update preload/trpc.ts** + +Open `src/preload/trpc.ts`. + +Remove the `floating_domain` case from the `V3StreamEvent` union (lines 29–42): +```ts + | { + type: 'floating_domain'; + requestId: string; + domain: + | 'tasks' + | 'notes' + | 'timelines' + | 'projects' + | { + type: 'task' | 'timeline' | 'project' | 'note' | 'node'; + id?: string | null; + section?: 'task' | 'timeline' | 'note' | null; + }; + }; +``` + +The `V3StreamEvent` union becomes: +```ts +type V3StreamEvent = + | { type: 'stream_start'; requestId: string } + | { type: 'stream_text'; requestId: string; chunk: string } + | { type: 'stream_end'; requestId: string; mutations?: unknown[] }; +``` + +- [ ] **Step 5: Update renderer/lib/ipcLink.ts** + +Open `src/renderer/lib/ipcLink.ts`. + +Remove the `floating_domain` case from the `V3StreamEvent` union (lines 16–33) the same way as done in preload. The type becomes: +```ts +type V3StreamEvent = + | { type: 'stream_start'; requestId: string } + | { type: 'stream_text'; requestId: string; chunk: string } + | { type: 'stream_end'; requestId: string; mutations?: unknown[] }; +``` + +- [ ] **Step 6: Update shared/api-types.ts** + +Open `src/shared/api-types.ts`. + +Check whether `WsFloatingDomainSchema` / `WsFloatingDomain` are imported anywhere: +```bash +grep -rn "WsFloatingDomain\|WsFloatingRequest" src/ +``` + +If `WsFloatingRequest` is imported only by the now-deleted orchestrator import, and `WsFloatingDomain` is imported nowhere, delete both from `shared/api-types.ts`: +- Delete `WsFloatingDomainSchema` Zod object (lines 217–228) +- Delete `export type WsFloatingDomain = z.infer;` (line 229) +- If `WsFloatingRequest` type/schema exists, delete it too (search for it in the file) + +- [ ] **Step 7: Sweep for any remaining floating references in main** + +```bash +grep -rn "floating\|Floating" src/main/ src/preload/ | grep -v node_modules | grep -v "\.md:" +``` + +Any remaining references to floating in these directories should be removed. Common residuals: +- `onDomain` callback type in `StreamListener` (if `sendFloatingRequest` was its only consumer) +- Stale comments in `backend-client.ts` mentioning floating + +- [ ] **Step 8: Type check** + +```bash +source ~/.nvm/nvm.sh && npx tsc --noEmit 2>&1 | grep -i "error" | head -30 +``` + +Expected: zero errors. The `TaskBriefChat.tsx` now sends `mode: 'contextual'` which is valid per the updated schema. + +- [ ] **Step 9: Commit** + +```bash +git add src/main/api/backend-client.ts \ + src/main/ai/orchestrator.ts \ + src/main/router/index.ts \ + src/preload/trpc.ts \ + src/renderer/lib/ipcLink.ts \ + src/shared/api-types.ts +git commit -m "$(cat <<'EOF' +refactor(contextual): main process drops sendFloatingRequest and floating mode + +ai.chat tRPC procedure now accepts mode='contextual' (or unset for home). +Orchestrator loses the floating delegation branch. Backend client method +and WsFloatingDomain shared type removed. +EOF +)" +``` + +--- + +## Task M6.8 — Sweep electron-store and localStorage `'floating'` keys + +**Files:** +- Inspect: `src/main/store.ts` +- Inspect: `src/renderer/` (any localStorage usage) + +### Context + +`src/main/store.ts` defines the electron-store schema — no `floating.*` keys exist in the current schema (verified: `AppSettings` has `sidebarCollapsed`, `encryptedTokens`, `backendUrl`, `deviceId`, `dailyBriefCache`, `localAgents`, `formatPrefs`, `uiLanguage`, `timelineZoom`). No floating keys. + +This task is a verification sweep. If nothing is found, the commit is skipped. + +### Steps + +- [ ] **Step 1: Search for any floating.* key usage** + +```bash +grep -rn "floating\." src/main/ src/preload/ src/renderer/ | grep -v node_modules | grep -v "\.md:" +``` + +Also check localStorage: +```bash +grep -rn "localStorage" src/renderer/ | grep -v node_modules | grep "float" +``` + +- [ ] **Step 2: Decision point** + +If Step 1 returns NO results (or only results already cleaned by M6.1–M6.4), this task is a no-op. Skip the commit and note in the final report: "M6.8: no floating.* store or localStorage keys found — no commit needed." + +If Step 1 returns results with actual floating key reads/writes in store.ts or localStorage calls: +- Delete the key from `AppSettings` interface and the `defaults` object in `store.ts` +- Delete any `localStorage.getItem('floating.*')` or `setItem('floating.*', ...)` calls + +- [ ] **Step 3: Conditional commit** + +Only run this if changes were made in Step 2: + +```bash +git add -A +git status --short # confirm what's staged +git commit -m "$(cat <<'EOF' +chore(contextual): purge residual 'floating' keys from store and renderer +EOF +)" +``` + +--- + +## Final Self-Review Checklist + +After all commits, run these verification checks and paste the output into your report: + +- [ ] **FloatingChat imports gone** +```bash +grep -rn "FloatingChat\|useFloatingChat\|FloatingChatProvider\|useDoubleClickAI" src/renderer/ +``` +Expected: no output. + +- [ ] **data-ai-section gone** +```bash +grep -rn "data-ai-section" src/renderer/ +``` +Expected: no output. + +- [ ] **floating string in renderer hooks** +```bash +grep -rn "'floating'" src/renderer/hooks/ +``` +Expected: no output (sidebar.tsx uses `"floating"` as a layout variant — that is unrelated and harmless). + +- [ ] **UIChatContext type** +```bash +grep -n "type:" src/renderer/hooks/useAIChat.ts | head -5 +``` +Expected: `'global' | 'project'` only. + +- [ ] **tRPC schema** +```bash +grep -n "floating" src/main/router/index.ts +``` +Expected: no output. + +- [ ] **sendFloatingRequest gone** +```bash +grep -rn "sendFloatingRequest\|orchestrateFloating" src/main/ +``` +Expected: no output. + +- [ ] **Final tsc** +```bash +source ~/.nvm/nvm.sh && npx tsc --noEmit 2>&1 | grep -c "error TS" +``` +Expected: `0` diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index 8ff200c..720a92d 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,45 +1,45 @@ -# Graph Report - . (2026-05-14) +# Graph Report - . (2026-05-15) ## Corpus Check -- 166 files · ~405,615 words +- 92 files · ~217,586 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 2908 nodes · 5718 edges · 148 communities detected -- Extraction: 55% EXTRACTED · 45% INFERRED · 0% AMBIGUOUS · INFERRED: 2551 edges (avg confidence: 0.59) +- 3313 nodes · 6328 edges · 169 communities detected +- Extraction: 57% EXTRACTED · 43% INFERRED · 0% AMBIGUOUS · INFERRED: 2713 edges (avg confidence: 0.6) - Token cost: 0 input · 0 output ## Community Hubs (Navigation) -- [[_COMMUNITY_API Auth + Memory Backbone|API Auth + Memory Backbone]] -- [[_COMMUNITY_Agent Runners (deepbrieffolder)|Agent Runners (deep/brief/folder)]] -- [[_COMMUNITY_Chat + Device WebSocket|Chat + Device WebSocket]] -- [[_COMMUNITY_Email Integrations (GmailMS Graph)|Email Integrations (Gmail/MS Graph)]] -- [[_COMMUNITY_Device + Agent Runtime Tests|Device + Agent Runtime Tests]] -- [[_COMMUNITY_Filesystem + Client Agents|Filesystem + Client Agents]] -- [[_COMMUNITY_Electron Renderer Core (TS)|Electron Renderer Core (TS)]] -- [[_COMMUNITY_Alembic Migrations|Alembic Migrations]] -- [[_COMMUNITY_Electron Main + Indexer|Electron Main + Indexer]] -- [[_COMMUNITY_Billing + Quotas|Billing + Quotas]] -- [[_COMMUNITY_HomeProject Brief Agents|Home/Project Brief Agents]] -- [[_COMMUNITY_Memory Tests + Seeds|Memory Tests + Seeds]] -- [[_COMMUNITY_Agent Config + App Bootstrap|Agent Config + App Bootstrap]] -- [[_COMMUNITY_Middleware + Settings|Middleware + Settings]] -- [[_COMMUNITY_OAuth Providers|OAuth Providers]] -- [[_COMMUNITY_Architecture References|Architecture References]] -- [[_COMMUNITY_Agent Setup + Journey|Agent Setup + Journey]] -- [[_COMMUNITY_Middleware Tests|Middleware Tests]] -- [[_COMMUNITY_Project UI Mockups|Project UI Mockups]] -- [[_COMMUNITY_Client List UI|Client List UI]] -- [[_COMMUNITY_AI Chat UI Surface|AI Chat UI Surface]] -- [[_COMMUNITY_HTML Preprocessor|HTML Preprocessor]] -- [[_COMMUNITY_AI Brand UI Patterns|AI Brand UI Patterns]] -- [[_COMMUNITY_Chrome DevTools Perf Profile|Chrome DevTools Perf Profile]] -- [[_COMMUNITY_Task Context Menu|Task Context Menu]] -- [[_COMMUNITY_Renderer Components|Renderer Components]] -- [[_COMMUNITY_Timeline Event Issues|Timeline Event Issues]] -- [[_COMMUNITY_Brand Identity System|Brand Identity System]] -- [[_COMMUNITY_Datei18n Components|Date/i18n Components]] -- [[_COMMUNITY_Date Utilities|Date Utilities]] +- [[_COMMUNITY_Community 0|Community 0]] +- [[_COMMUNITY_Community 1|Community 1]] +- [[_COMMUNITY_Community 2|Community 2]] +- [[_COMMUNITY_Community 3|Community 3]] +- [[_COMMUNITY_Community 4|Community 4]] +- [[_COMMUNITY_Community 5|Community 5]] +- [[_COMMUNITY_Community 6|Community 6]] +- [[_COMMUNITY_Community 7|Community 7]] +- [[_COMMUNITY_Community 8|Community 8]] +- [[_COMMUNITY_Community 9|Community 9]] +- [[_COMMUNITY_Community 10|Community 10]] +- [[_COMMUNITY_Community 11|Community 11]] +- [[_COMMUNITY_Community 12|Community 12]] +- [[_COMMUNITY_Community 13|Community 13]] +- [[_COMMUNITY_Community 14|Community 14]] +- [[_COMMUNITY_Community 15|Community 15]] +- [[_COMMUNITY_Community 16|Community 16]] +- [[_COMMUNITY_Community 17|Community 17]] +- [[_COMMUNITY_Community 18|Community 18]] +- [[_COMMUNITY_Community 19|Community 19]] +- [[_COMMUNITY_Community 20|Community 20]] +- [[_COMMUNITY_Community 21|Community 21]] +- [[_COMMUNITY_Community 22|Community 22]] +- [[_COMMUNITY_Community 23|Community 23]] +- [[_COMMUNITY_Community 24|Community 24]] +- [[_COMMUNITY_Community 25|Community 25]] +- [[_COMMUNITY_Community 26|Community 26]] +- [[_COMMUNITY_Community 27|Community 27]] +- [[_COMMUNITY_Community 28|Community 28]] +- [[_COMMUNITY_Community 29|Community 29]] - [[_COMMUNITY_Community 30|Community 30]] - [[_COMMUNITY_Community 31|Community 31]] - [[_COMMUNITY_Community 32|Community 32]] @@ -47,27 +47,26 @@ - [[_COMMUNITY_Community 34|Community 34]] - [[_COMMUNITY_Community 35|Community 35]] - [[_COMMUNITY_Community 36|Community 36]] +- [[_COMMUNITY_Community 37|Community 37]] - [[_COMMUNITY_Community 38|Community 38]] +- [[_COMMUNITY_Community 39|Community 39]] - [[_COMMUNITY_Community 40|Community 40]] - [[_COMMUNITY_Community 41|Community 41]] -- [[_COMMUNITY_Community 42|Community 42]] -- [[_COMMUNITY_Community 49|Community 49]] -- [[_COMMUNITY_Community 51|Community 51]] -- [[_COMMUNITY_Community 52|Community 52]] -- [[_COMMUNITY_Community 56|Community 56]] +- [[_COMMUNITY_Community 43|Community 43]] +- [[_COMMUNITY_Community 44|Community 44]] +- [[_COMMUNITY_Community 46|Community 46]] +- [[_COMMUNITY_Community 47|Community 47]] +- [[_COMMUNITY_Community 48|Community 48]] +- [[_COMMUNITY_Community 55|Community 55]] - [[_COMMUNITY_Community 57|Community 57]] - [[_COMMUNITY_Community 58|Community 58]] -- [[_COMMUNITY_Community 59|Community 59]] +- [[_COMMUNITY_Community 64|Community 64]] - [[_COMMUNITY_Community 65|Community 65]] -- [[_COMMUNITY_Community 77|Community 77]] -- [[_COMMUNITY_Community 78|Community 78]] -- [[_COMMUNITY_Community 79|Community 79]] -- [[_COMMUNITY_Community 80|Community 80]] -- [[_COMMUNITY_Community 81|Community 81]] -- [[_COMMUNITY_Community 82|Community 82]] -- [[_COMMUNITY_Community 83|Community 83]] -- [[_COMMUNITY_Community 84|Community 84]] -- [[_COMMUNITY_Community 85|Community 85]] +- [[_COMMUNITY_Community 67|Community 67]] +- [[_COMMUNITY_Community 68|Community 68]] +- [[_COMMUNITY_Community 69|Community 69]] +- [[_COMMUNITY_Community 74|Community 74]] +- [[_COMMUNITY_Community 75|Community 75]] - [[_COMMUNITY_Community 86|Community 86]] - [[_COMMUNITY_Community 87|Community 87]] - [[_COMMUNITY_Community 88|Community 88]] @@ -76,51 +75,48 @@ - [[_COMMUNITY_Community 91|Community 91]] - [[_COMMUNITY_Community 92|Community 92]] - [[_COMMUNITY_Community 93|Community 93]] -- [[_COMMUNITY_Community 118|Community 118]] -- [[_COMMUNITY_Community 119|Community 119]] -- [[_COMMUNITY_Community 120|Community 120]] -- [[_COMMUNITY_Community 121|Community 121]] -- [[_COMMUNITY_Community 122|Community 122]] -- [[_COMMUNITY_Community 123|Community 123]] -- [[_COMMUNITY_Community 169|Community 169]] -- [[_COMMUNITY_Community 170|Community 170]] -- [[_COMMUNITY_Community 171|Community 171]] -- [[_COMMUNITY_Community 173|Community 173]] -- [[_COMMUNITY_Community 174|Community 174]] -- [[_COMMUNITY_Community 175|Community 175]] -- [[_COMMUNITY_Community 176|Community 176]] -- [[_COMMUNITY_Community 177|Community 177]] -- [[_COMMUNITY_Community 178|Community 178]] -- [[_COMMUNITY_Community 179|Community 179]] -- [[_COMMUNITY_Community 180|Community 180]] -- [[_COMMUNITY_Community 181|Community 181]] -- [[_COMMUNITY_Community 182|Community 182]] -- [[_COMMUNITY_Community 183|Community 183]] +- [[_COMMUNITY_Community 94|Community 94]] +- [[_COMMUNITY_Community 95|Community 95]] +- [[_COMMUNITY_Community 96|Community 96]] +- [[_COMMUNITY_Community 97|Community 97]] +- [[_COMMUNITY_Community 98|Community 98]] +- [[_COMMUNITY_Community 99|Community 99]] +- [[_COMMUNITY_Community 100|Community 100]] +- [[_COMMUNITY_Community 101|Community 101]] +- [[_COMMUNITY_Community 102|Community 102]] +- [[_COMMUNITY_Community 103|Community 103]] +- [[_COMMUNITY_Community 104|Community 104]] +- [[_COMMUNITY_Community 105|Community 105]] +- [[_COMMUNITY_Community 106|Community 106]] +- [[_COMMUNITY_Community 107|Community 107]] +- [[_COMMUNITY_Community 132|Community 132]] +- [[_COMMUNITY_Community 133|Community 133]] +- [[_COMMUNITY_Community 134|Community 134]] +- [[_COMMUNITY_Community 135|Community 135]] +- [[_COMMUNITY_Community 136|Community 136]] +- [[_COMMUNITY_Community 137|Community 137]] +- [[_COMMUNITY_Community 138|Community 138]] +- [[_COMMUNITY_Community 139|Community 139]] - [[_COMMUNITY_Community 184|Community 184]] -- [[_COMMUNITY_Community 231|Community 231]] -- [[_COMMUNITY_Community 232|Community 232]] -- [[_COMMUNITY_Community 236|Community 236]] -- [[_COMMUNITY_Community 237|Community 237]] -- [[_COMMUNITY_Community 238|Community 238]] -- [[_COMMUNITY_Community 239|Community 239]] -- [[_COMMUNITY_Community 240|Community 240]] -- [[_COMMUNITY_Community 241|Community 241]] -- [[_COMMUNITY_Community 242|Community 242]] -- [[_COMMUNITY_Community 243|Community 243]] -- [[_COMMUNITY_Community 244|Community 244]] -- [[_COMMUNITY_Community 245|Community 245]] -- [[_COMMUNITY_Community 246|Community 246]] -- [[_COMMUNITY_Community 247|Community 247]] -- [[_COMMUNITY_Community 248|Community 248]] -- [[_COMMUNITY_Community 249|Community 249]] -- [[_COMMUNITY_Community 250|Community 250]] -- [[_COMMUNITY_Community 251|Community 251]] -- [[_COMMUNITY_Community 252|Community 252]] +- [[_COMMUNITY_Community 185|Community 185]] +- [[_COMMUNITY_Community 186|Community 186]] +- [[_COMMUNITY_Community 188|Community 188]] +- [[_COMMUNITY_Community 189|Community 189]] +- [[_COMMUNITY_Community 190|Community 190]] +- [[_COMMUNITY_Community 191|Community 191]] +- [[_COMMUNITY_Community 192|Community 192]] +- [[_COMMUNITY_Community 193|Community 193]] +- [[_COMMUNITY_Community 194|Community 194]] +- [[_COMMUNITY_Community 195|Community 195]] +- [[_COMMUNITY_Community 196|Community 196]] +- [[_COMMUNITY_Community 197|Community 197]] +- [[_COMMUNITY_Community 198|Community 198]] +- [[_COMMUNITY_Community 199|Community 199]] +- [[_COMMUNITY_Community 204|Community 204]] +- [[_COMMUNITY_Community 205|Community 205]] +- [[_COMMUNITY_Community 206|Community 206]] - [[_COMMUNITY_Community 253|Community 253]] - [[_COMMUNITY_Community 254|Community 254]] -- [[_COMMUNITY_Community 255|Community 255]] -- [[_COMMUNITY_Community 256|Community 256]] -- [[_COMMUNITY_Community 257|Community 257]] - [[_COMMUNITY_Community 258|Community 258]] - [[_COMMUNITY_Community 259|Community 259]] - [[_COMMUNITY_Community 260|Community 260]] @@ -158,18 +154,43 @@ - [[_COMMUNITY_Community 292|Community 292]] - [[_COMMUNITY_Community 293|Community 293]] - [[_COMMUNITY_Community 294|Community 294]] +- [[_COMMUNITY_Community 295|Community 295]] +- [[_COMMUNITY_Community 296|Community 296]] +- [[_COMMUNITY_Community 297|Community 297]] +- [[_COMMUNITY_Community 298|Community 298]] +- [[_COMMUNITY_Community 299|Community 299]] +- [[_COMMUNITY_Community 300|Community 300]] +- [[_COMMUNITY_Community 301|Community 301]] +- [[_COMMUNITY_Community 302|Community 302]] +- [[_COMMUNITY_Community 303|Community 303]] +- [[_COMMUNITY_Community 304|Community 304]] +- [[_COMMUNITY_Community 305|Community 305]] +- [[_COMMUNITY_Community 306|Community 306]] +- [[_COMMUNITY_Community 307|Community 307]] +- [[_COMMUNITY_Community 308|Community 308]] +- [[_COMMUNITY_Community 309|Community 309]] +- [[_COMMUNITY_Community 310|Community 310]] +- [[_COMMUNITY_Community 311|Community 311]] +- [[_COMMUNITY_Community 312|Community 312]] +- [[_COMMUNITY_Community 313|Community 313]] +- [[_COMMUNITY_Community 315|Community 315]] +- [[_COMMUNITY_Community 316|Community 316]] +- [[_COMMUNITY_Community 317|Community 317]] +- [[_COMMUNITY_Community 318|Community 318]] +- [[_COMMUNITY_Community 319|Community 319]] +- [[_COMMUNITY_Community 320|Community 320]] ## God Nodes (most connected - your core abstractions) 1. `MemoryMiddleware` - 236 edges 2. `User` - 127 edges -3. `MemoryProactive` - 107 edges -4. `Subscription` - 98 edges -5. `MemoryAssociative` - 98 edges -6. `MemoryEpisodic` - 93 edges -7. `AgentRunLog` - 91 edges +3. `AgentRunLog` - 107 edges +4. `MemoryProactive` - 107 edges +5. `Subscription` - 98 edges +6. `MemoryAssociative` - 98 edges +7. `MemoryEpisodic` - 93 edges 8. `MemoryCore` - 90 edges 9. `UserProfile` - 79 edges -10. `MemoryRelation` - 65 edges +10. `StreamFormatter` - 70 edges ## Surprising Connections (you probably didn't know these) - `recordRunAction()` --calls--> `getDb()` [INFERRED] @@ -184,799 +205,911 @@ api\app\billing\tier_manager.py → api\app\models.py ## Hyperedges (group relationships) -- **Task Form Dialog keyboard polish** — kbddesign_rovingfocus_hook, kbddesign_listboxkeys_hook, kbddesign_datefield_withtime, kbddesign_propertypill_button [EXTRACTED 1.00] -- **Memory V2 in-house pipeline** — memv2_fact_extraction, memv2_memory_fact_table, memv2_user_profile_table, memv2_forgetting_decay, memv2_episode_summarization [EXTRACTED 1.00] -- **Production LLM Agent Stack (ZDR)** — llmreport_home_agent, llmreport_floating_agent, llmreport_brief_agent, llmreport_unified_processor, llmreport_memory_extractor, llmreport_openai_zdr, llmreport_anthropic_zdr [EXTRACTED 1.00] -- **Memory Evolution Pipeline (extraction + storage + decision)** — memory_extraction_module, memory_middleware, memory_associative_table, memory_relations_table [EXTRACTED 0.90] -- **Folder Indexing Pipeline (scan, WS, summarize, store)** — scanner_module, indexer_module, device_ws, folder_indexer [EXTRACTED 0.90] -- **Onboarding Storage Split (encrypted core vs local prefs)** — onboarding_flow_component, memory_core_table, electron_store [EXTRACTED 0.85] +- **V3 streaming flow: Renderer -> Orchestrator -> BackendClient -> Device WS -> DrizzleExecutor** — ui_ChatSurface, orchestrator_orchestrate, backendclient_sendHomeRequest, backendclient_openDeviceWebSocket, drizzleexecutor_execute [INFERRED 0.90] +- **Folder indexing pipeline: scan -> session -> WS batch -> manifest update** — scanner_scanFolder, indexer_startIndexSession, backendclient_sendIndexFileBatch, schema_projectFolderFiles [EXTRACTED 1.00] +- **Agent-run logging: tool_call -> recordRunAction -> agent_run_actions + run_complete -> agent_runs** — backendclient_openDeviceWebSocket, backendclient_recordRunAction, schema_agentRuns, schema_agentRunActions [EXTRACTED 1.00] +- **** — FilesSection, FolderLinkCard, FolderFileList, FolderUnlinkDialog, FolderChip [INFERRED 0.90] +- **** — useAIChat, useChatStream, ContextualChatContext [INFERRED 0.90] +- **** — AddEventDialog, EditEventDialog, TimelineGanttView, ProjectDetail [INFERRED 0.85] +- **** — ProjectsPage, TasksPage, TimelinePage, NoteDetailPage, ContextualScope [INFERRED 0.85] +- **** — TierManager, quota.check_folder_quota, quota.add_token_usage, models.MonthlyTokenUsage, billing_router [EXTRACTED 1.00] +- **** — device_ws.endpoint, brief_agent.run_home_brief, brief_agent.run_project_brief, output_formatter.StreamFormatter, api-types.ts [EXTRACTED 1.00] +- **Contextual sidebar frontend architecture** — concept/contextual_sidebar, concept/ContextualChatProvider, concept/ChatSurface, concept/useContextualScope [EXTRACTED 1.00] +- **Contextual backend pipeline (WS frame → run_contextual_stream → Langfuse prompt)** — concept/contextual_request_frame, concept/contextual_scope_update_frame, run_contextual_stream, concept/contextual_system_prompt [EXTRACTED 1.00] +- **Folder index session WS flow** — _handle_index_session_start, _handle_index_file_batch, _handle_index_session_cancel, _index_sessions [EXTRACTED 1.00] ## Communities -### Community 0 - "API Auth + Memory Backbone" +### Community 0 - "Community 0" Cohesion: 0.03 -Nodes (259): Base, Shared declarative base for all ORM models., ExtractionQueue, MemoryAssociative, MemoryCore, MemoryEpisodic, MemoryProactive, MemoryRelation (+251 more) +Nodes (252): Base, Shared declarative base for all ORM models., ExtractionQueue, MemoryAssociative, MemoryCore, MemoryEpisodic, MemoryProactive, MemoryRelation (+244 more) -### Community 1 - "Agent Runners (deep/brief/folder)" +### Community 1 - "Community 1" Cohesion: 0.02 -Nodes (183): make_query_relations_tool(), Relations agent — read-only tool wrapping MemoryMiddleware.query_relations., Return a query_relations tool bound to *user_id*., _as_text(), _build_processing_tools(), _fetch_projects(), _finalize_run(), _make_agent_executor() (+175 more) +Nodes (207): make_query_relations_tool(), Relations agent — read-only tool wrapping MemoryMiddleware.query_relations., Return a query_relations tool bound to *user_id*., _build_read_tools(), Brief agent — produces plain-text home and project status briefs. Read-only t, Stream a plain-text daily home brief. Yields (event_type, data) tuples id, Stream a plain-text project status brief for project_id. Yields (event_ty, _resolve_language() (+199 more) -### Community 2 - "Chat + Device WebSocket" -Cohesion: 0.03 -Nodes (168): AgentRunLog, AgentCatalogItem, AgentCreationCheckRequest, AgentCreationCheckResponse, AgentRunLogResponse, AgentTriggerRequest, ChatContext, ChatRequest (+160 more) +### Community 2 - "Community 2" +Cohesion: 0.02 +Nodes (184): get_client(), list_clients(), Client agent — read-only tools for the clients table., List clients, optionally filtered by a name/email substring search. search:, Get full details for one client by UUID. id: the client's UUID., get_file_metadata(), list_directory(), Filesystem agent — tools for reading local directories and files on Electron. (+176 more) -### Community 3 - "Email Integrations (Gmail/MS Graph)" +### Community 3 - "Community 3" +Cohesion: 0.04 +Nodes (140): AgentRunLog, Scope for a floating request — narrows the agent to a specific entity., Client → Server: Floating chat message scoped to an entity., Server → Client: signals start of a streaming response., Server → Client: streamed text token., Server → Client: signals end of a streaming response., Structured floating domain payload for UI routing decisions., Server → Client: domain determined for a floating request. (+132 more) + +### Community 4 - "Community 4" Cohesion: 0.03 Nodes (84): _build_gmail_query(), GmailClient, _parse_body(), _parse_date(), Gmail API client for cloud agent integration. Wraps the Google Gmail REST API, Remove HTML tags and decode entities to get plain text., Recursively extract the plain-text body from a Gmail message payload. Pre, Parse an RFC 2822 email date header into a UTC ``datetime``. (+76 more) -### Community 4 - "Device + Agent Runtime Tests" -Cohesion: 0.03 -Nodes (102): CloudAgentConfig, LocalAgentConfig, _format_entities_for_context(), _format_metadata(), _format_projects(), _get_extraction_rules(), _get_no_match_behavior(), _is_overdue() (+94 more) +### Community 5 - "Community 5" +Cohesion: 0.04 +Nodes (99): AgentCatalogItem, AgentCreationCheckRequest, AgentCreationCheckResponse, AgentRunLogResponse, AgentTriggerRequest, ChatContext, ChatRequest, ChatResponse (+91 more) -### Community 5 - "Filesystem + Client Agents" -Cohesion: 0.03 -Nodes (97): get_client(), list_clients(), Client agent — read-only tools for the clients table., List clients, optionally filtered by a name/email substring search. search:, Get full details for one client by UUID. id: the client's UUID., get_file_metadata(), list_directory(), Filesystem agent — tools for reading local directories and files on Electron. (+89 more) - -### Community 6 - "Electron Renderer Core (TS)" +### Community 6 - "Community 6" Cohesion: 0.03 Nodes (19): AuthExpiredError, BackendClient, logHttp(), logHttpResponse(), logWsRecv(), logWsSend(), OfflineError, QuotaError (+11 more) -### Community 7 - "Alembic Migrations" +### Community 7 - "Community 7" +Cohesion: 0.03 +Nodes (84): _uuid(), get_page_details(), _proactive_hints_injection(), Return a system-prompt paragraph listing proactive behavioral hints. Retu, Return a system-prompt paragraph listing proactive behavioral hints. Retu, Fetch full details for the entity currently in view. entity_type: one of, embed_text(), OpenAI embedding helper for associative memory tier. Single public function: (+76 more) + +### Community 8 - "Community 8" Cohesion: 0.04 -Nodes (69): _get_url(), Alembic migration environment — async-compatible. At runtime the app uses ``p, Convert an asyncpg URL to a psycopg2 URL for Alembic CLI., Emit SQL without a live DB connection., Run migrations against a live DB using the async engine., run_migrations_offline(), run_migrations_online(), run_migrations_online_async() (+61 more) +Nodes (70): _get_url(), Alembic migration environment — async-compatible. At runtime the app uses ``p, Convert an asyncpg URL to a psycopg2 URL for Alembic CLI., Emit SQL without a live DB connection., Run migrations against a live DB using the async engine., run_migrations_offline(), run_migrations_online(), run_migrations_online_async() (+62 more) -### Community 8 - "Electron Main + Indexer" +### Community 9 - "Community 9" Cohesion: 0.05 -Nodes (42): startAgentScheduler(), tickAgentScheduler(), checkConnectivity(), dailyBrief(), generateAndCacheBrief(), getBriefTimeSlot(), getCachedBrief(), getCurrentSlotKey() (+34 more) +Nodes (43): startAgentScheduler(), tickAgentScheduler(), checkConnectivity(), dailyBrief(), generateAndCacheBrief(), getBriefTimeSlot(), getCachedBrief(), getCurrentSlotKey() (+35 more) -### Community 9 - "Billing + Quotas" +### Community 10 - "Community 10" Cohesion: 0.05 -Nodes (56): MonthlyTokenUsage, add_token_usage(), check_folder_quota(), _current_year_month(), QuotaExceeded, Quota checks and atomic token-usage accounting for folder integration., Raised when a folder operation cannot proceed under the user's tier., Raise QuotaExceeded if folder_max_files or folder_monthly_tokens would be vi (+48 more) +Nodes (55): MonthlyTokenUsage, add_token_usage(), check_folder_quota(), _current_year_month(), QuotaExceeded, Quota checks and atomic token-usage accounting for folder integration., Raised when a folder operation cannot proceed under the user's tier., Raise QuotaExceeded if folder_max_files or folder_monthly_tokens would be v (+47 more) -### Community 10 - "Home/Project Brief Agents" +### Community 11 - "Community 11" Cohesion: 0.03 Nodes (71): home_brief Langfuse prompt, ProjectBriefCard renderer, project_brief Langfuse prompt, Read-only tool subset, run_home_brief() function, run_project_brief() function, WS brief_request frame, Anthropic Zero Retention Addendum (+63 more) -### Community 11 - "Memory Tests + Seeds" +### Community 12 - "Community 12" Cohesion: 0.05 -Nodes (58): _uuid(), _normalize_domain_payload(), _proactive_hints_injection(), Return a system-prompt paragraph listing proactive behavioral hints. Retu, embed_text(), OpenAI embedding helper for associative memory tier. Single public function:, Call OpenAI text-embedding-3-small. Return None on failure (caller falls back to, Exception (+50 more) +Nodes (22): Settings, get_session(), Database engine, session factory, and base model. All app code uses the async, FastAPI dependency that yields an async DB session per request., BaseSettings, StripeService, Settings, _auth_header() (+14 more) -### Community 12 - "Agent Config + App Bootstrap" +### Community 13 - "Community 13" Cohesion: 0.06 -Nodes (43): lifespan(), _memory_audit_cron_tick(), _memory_cron_tick(), Weekly cron: contradiction scan + label canonicalization for all users (Phase 7), Hourly cron: drain Free-tier extraction queue + mine proactive patterns for Powe, In-process TTL buffer for per-session LangChain message history. Stores the ful, _SessionBuffer, audit_memory() (+35 more) +Nodes (43): lifespan(), _memory_audit_cron_tick(), _memory_cron_tick(), Weekly cron: contradiction scan + label canonicalization for all users (Phase 7), Hourly cron: drain Free-tier extraction queue + mine proactive patterns for Powe, In-process TTL buffer for per-session LangChain message history. Stores the ful, Append a synthetic system message to the buffer for the given session., _SessionBuffer (+35 more) -### Community 13 - "Middleware + Settings" -Cohesion: 0.04 -Nodes (29): Settings, get_session(), Database engine, session factory, and base model. All app code uses the async, FastAPI dependency that yields an async DB session per request., _get_client_ip(), RateLimiter, IP-based sliding-window rate limiter. Cloudflare-aware: uses CF-Connecting-IP, Extract real client IP behind Cloudflare / reverse proxy. (+21 more) - -### Community 14 - "OAuth Providers" +### Community 14 - "Community 14" Cohesion: 0.06 Nodes (25): generate_pkce_pair(), OAuthUserInfo, OAuth 2.0 + PKCE provider abstractions. Each provider implements a three-step, Fetch the authenticated user's identity from Google., Normalized user identity returned by any provider., Generate a (code_verifier, code_challenge) pair for PKCE S256. The code_v, Tests for auth routes: register, login, refresh, me, OAuth social login. Exer, POST /api/v1/auth/refresh (+17 more) -### Community 15 - "Architecture References" +### Community 15 - "Community 15" +Cohesion: 0.05 +Nodes (44): AddEventDialog component, ChatMessage type, ContextualChatProvider + useContextualChat, DateField input component, DateTimeField segmented input, shadcn Dialog primitives, EditEventDialog component, FilesSection component (+36 more) + +### Community 16 - "Community 16" +Cohesion: 0.05 +Nodes (53): BackendClient.checkFolderQuota (pre-flight), BackendClient.connectPersistent (Device WS), BackendClient.openDeviceWebSocket (frame dispatcher), recordRunAction() - persist agent_run_actions row, BackendClient.registerIndexSession, BackendClient.sendBriefRequest, BackendClient.sendContextualRequest, BackendClient.sendHomeRequest (+45 more) + +### Community 17 - "Community 17" +Cohesion: 0.05 +Nodes (52): DST handling (Europe/Rome), StreamFormatter, WsFrameType, WsHomeRequest, WsStreamEnd, WsStreamStart, WsStreamText, _HOME_SYSTEM_PROMPT (+44 more) + +### Community 18 - "Community 18" Cohesion: 0.05 Nodes (49): AgentRunLog, Agent Runner UML Sequence Diagram, AgentScheduler, AIChatPanel (visual reference), AppShell Component, AuthManager, Caveman Mode (token compression), deep_agent.py (+41 more) -### Community 16 - "Agent Setup + Journey" +### Community 19 - "Community 19" Cohesion: 0.09 Nodes (44): make_directory_tools(), Return filesystem tools that resolve relative paths against *base_directory*., AgentConfig, Structured agent configuration (replaces freeform prompt_template)., _as_text(), _build_system_prompt(), _call_llm_with_tools(), _extract_agent_config() (+36 more) -### Community 17 - "Middleware Tests" -Cohesion: 0.09 -Nodes (15): _auth_header(), _make_jwt(), _override_db(), Tests for Step 9 middleware: auth, rate limiting, and sanitizer. Auth tests:, Each test uses a fresh unique user_id so windows never collide., POST /auth/register is exempt — 25 calls should never return 429., POST /auth/login is exempt — multiple failed attempts are not rate-limited., Mock ``run_home`` to inject controlled strings into chat responses. (+7 more) +### Community 20 - "Community 20" +Cohesion: 0.06 +Nodes (45): ContextualBufferProxy, ContextualScope pydantic model, NoteDetailPage route component, ProjectsPage route component, Pydantic Settings (env config), TasksPage route component, TierManager singleton (FEATURES matrix), TimelinePage route component (+37 more) -### Community 18 - "Project UI Mockups" +### Community 21 - "Community 21" Cohesion: 0.06 Nodes (41): App Logo (Top Left), Assignee Label, Client Label Tag, Client: Umbrella Labs, Client: Wayne Enterprises, Completed Count Card (8), Design Pattern: Filter Tab Bar, Design Pattern: Inline Metadata Chips (+33 more) -### Community 19 - "Client List UI" +### Community 22 - "Community 22" Cohesion: 0.08 Nodes (37): AI Project Summary Card, Add Button (Timeline / Tasks / Notes), Client: Acme Corp, Client: Globex Inc, Client: Initech Solutions, Client List in Sidebar, Client: Umbrella Labs, Client: Wayne Enterprises (+29 more) -### Community 20 - "AI Chat UI Surface" +### Community 23 - "Community 23" +Cohesion: 0.06 +Nodes (22): _get_client_ip(), RateLimiter, IP-based sliding-window rate limiter. Cloudflare-aware: uses CF-Connecting-IP, Extract real client IP behind Cloudflare / reverse proxy., Sliding-window rate limiter keyed on client IP. Only applies to POST /api, OriginValidator, Security middleware stack. 1. RequestSizeLimiter — reject bodies > 4 KB (wait, Reject request bodies larger than max_bytes. (+14 more) + +### Community 24 - "Community 24" Cohesion: 0.08 Nodes (32): AI Agent Avatar (Sparkles + adiuvAI Label), AI Follow-Up Suggestion Text (setting a due date), AI Response Block (adiuvAI Agent Reply), adiuvAI Brand Name (Wordmark in Chat), App Logo (Golden Diamond Icon), Chat Conversation Area (Scrollable Message List), Chat Input Bar (Ask me anything...), Chat Send Button (Arrow Up, Amber) (+24 more) -### Community 21 - "HTML Preprocessor" +### Community 25 - "Community 25" Cohesion: 0.12 Nodes (24): PreprocessResult, Base types for the preprocessor system., Output of a preprocessor handler. Attributes ---------- content, _extract_metadata(), preprocess_email_html(), Preprocessor for email HTML files. Handles: - HTML stripping via BeautifulSo, Extract Subject/From/To/Date from raw HTML or plain text., Return only the latest message in a threaded email. (+16 more) -### Community 22 - "AI Brand UI Patterns" +### Community 26 - "Community 26" Cohesion: 0.11 Nodes (27): Design Pattern: AI as Quiet Partner, App Logo (Golden Diamond Icon), Brand Personality: Calm, Intelligent, Warm, Ask Me Anything Chat Input, Suggestion Chip: Any overdue tasks?, Suggestion Chip: Suggest next actions, Suggestion Chip: Summarize this week, Suggestion Chip: What's on my plate today? (+19 more) -### Community 23 - "Chrome DevTools Perf Profile" +### Community 27 - "Community 27" Cohesion: 0.09 Nodes (27): Animations Track (purple bars), CPU Track (high utilization), createTask, Chrome DevTools Performance Recording, Evaluate Script Task, Frames Track, Function call frames (deep stacks), GPU Track (+19 more) -### Community 24 - "Task Context Menu" +### Community 28 - "Community 28" Cohesion: 0.08 Nodes (26): Color Submenu, Copy Link Action, Delete Action, Duplicate Action, Edit Action, Mark as Done Action, Progress Submenu (10%-100%), Task Assignee Avatars (+18 more) -### Community 25 - "Renderer Components" -Cohesion: 0.11 -Nodes (15): getTimeGreeting(), relativeDate(), t(), ProjectTabBar(), attemptClose(), formValid(), handleClose(), loadRowIntoForm() (+7 more) - -### Community 26 - "Timeline Event Issues" +### Community 29 - "Community 29" Cohesion: 0.1 Nodes (21): Issue: Dual Date Axes (year-month + short month), Event: Alpha Release (checkpoint), Event: Beta Testing (activity bar), Event: Design Phase Complete, Event: Post-Launch Review, Event: Production Launch, Event: Project Kickoff (milestone, checked), Event Type: activity (rounded bar) (+13 more) -### Community 27 - "Brand Identity System" -Cohesion: 0.16 -Nodes (20): Brand Color: Canvas Dark (#0c0c0c) — dark mode background, Brand Color: Canvas Light (#f4edf3) — light mode background, Brand Color: Golden (#fbc881) — AI/Nord accent, Brand Color: Ink (#040404) — user/Sud/text, Brand Color: Slate (#8a8ea9) — secondary/muted, Compass Settle Animation (5s ease-in-out infinite), adiuvAI Brand Identity System, adiuvAI Color Palette (+12 more) - -### Community 28 - "Date/i18n Components" -Cohesion: 0.14 -Nodes (18): AddEventDialog Component, DateField UI Component, EditEventDialog Component, i18n Translation JSON Files (en/it/es/fr/de), parseDate Utility, Sonner Toast Notifications Plan, Timeline Batch Add Plan, Sonner Notifications Ralph Loop Prompt (+10 more) - -### Community 29 - "Date Utilities" -Cohesion: 0.15 -Nodes (10): detectBrowserFormatPrefs(), formatDate(), formatDateTime(), formatDueDate(), formatTime(), formatTs(), inferDateFormat(), useFormatPrefs() (+2 more) - ### Community 30 - "Community 30" -Cohesion: 0.15 -Nodes (17): AI Email Drafting Workflow (Focus Tasks Feature), Apply & Continue Button (Top Right), Checklist: Check contract dates (Section A.2), Checklist: Offer 10% discount-based loyalty credit, Checklist: Tone professional & sincere, Command / Prompt Input Footer, Draft Client Email - Follow-up Task, Focus Tasks Email Draft View (+9 more) +Cohesion: 0.13 +Nodes (11): handler(), clampPosition(), computeAnchorPosition(), computeDualAnchor(), FloatingChatProvider(), getChatWidth(), useFloatingChat(), useContextualScope() (+3 more) ### Community 31 - "Community 31" Cohesion: 0.16 -Nodes (16): AdiuvAI Brand, Pinkish-Lavender Rounded Square Background, Brand Value: Calm, Intelligent, Warm, Brand Value: Precision and Clarity, Color: Golden Amber (#F5C07A), Color: Pinkish-Lavender Background (#F0EBF4), Color: Near-Black (#1A1A1A), Design Style: Flat Minimal Geometric (+8 more) +Nodes (20): Brand Color: Canvas Dark (#0c0c0c) — dark mode background, Brand Color: Canvas Light (#f4edf3) — light mode background, Brand Color: Golden (#fbc881) — AI/Nord accent, Brand Color: Ink (#040404) — user/Sud/text, Brand Color: Slate (#8a8ea9) — secondary/muted, Compass Settle Animation (5s ease-in-out infinite), adiuvAI Brand Identity System, adiuvAI Color Palette (+12 more) ### Community 32 - "Community 32" -Cohesion: 0.19 -Nodes (9): handler(), clampPosition(), computeAnchorPosition(), computeDualAnchor(), FloatingChatProvider(), getChatWidth(), useFloatingChat(), useDoubleClickAI() (+1 more) +Cohesion: 0.13 +Nodes (19): AddEventDialog (stage-then-commit batch), DateField primitive, DateField withTime + flat props, EditEventDialog migrated to DateField, PropertyPill as
-
2908 nodes · 5718 edges · 295 communities
+
3313 nodes · 6328 edges · 321 communities