From 404a88175806fb0a213b70bf82a1757ec6ac14e9 Mon Sep 17 00:00:00 2001 From: Nicholai Date: Sat, 7 Feb 2026 02:27:53 -0700 Subject: [PATCH] docs(claude): add mobile, themes, plugins, drive (#54) Document recent features added since initial CLAUDE.md: - Capacitor mobile app architecture and native hooks - Plugin/skills system with registry pattern - Visual theme system with 10 presets + AI generation - Google Drive integration via service account - Updated agent harness to reflect unified chat arch - Expanded project structure and schema file listing Co-authored-by: Nicholai --- CLAUDE.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 11 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b1e48d9..7d19337 100755 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,6 +25,13 @@ bun run db:migrate:local # apply migrations locally bun run db:migrate:prod # apply migrations to production D1 ``` +mobile (capacitor): +```bash +bun cap:sync # sync web assets + plugins to native projects +bun cap:ios # open xcode project +bun cap:android # open android studio project +``` + tech stack --- @@ -37,7 +44,9 @@ tech stack | database | Cloudflare D1 (SQLite) via Drizzle ORM | | auth | WorkOS (SSO, directory sync) | | ai agent | AI SDK v6 + OpenRouter (kimi-k2.5 model) | -| integrations | NetSuite REST API | +| integrations | NetSuite REST API, Google Drive API | +| mobile | Capacitor (iOS + Android webview) | +| themes | 10 presets + AI-generated custom themes (oklch) | | state | React Context, server actions | @@ -52,10 +61,14 @@ critical architecture patterns - environment variables accessed via `getCloudflareContext()` → `env.DB` for D1 ### database -- schema split across `src/db/schema.ts` (core) and `src/db/schema-netsuite.ts` (integration) - drizzle ORM with D1 (SQLite dialect) - text IDs (UUIDs), text dates (ISO 8601 format) - migrations in `drizzle/` directory - **add new migrations, never modify old ones** +- schema files: + - `src/db/schema.ts` - core tables (users, projects, customers, vendors, etc.) + - `src/db/schema-netsuite.ts` - netsuite sync tables + - `src/db/schema-plugins.ts` - plugins, plugin_config, plugin_events + - `src/db/schema-theme.ts` - custom_themes, user_theme_preference ### authentication & middleware - WorkOS handles SSO, email/password, directory sync @@ -66,19 +79,27 @@ critical architecture patterns ### ai agent harness - located in `src/lib/agent/` - a complete AI-assisted system - `provider.ts`: OpenRouter setup for kimi-k2.5 model - - `tools.ts`: queryData, navigateTo, showNotification, renderComponent tools + - `tools.ts`: queryData, navigateTo, showNotification, renderComponent, plus theme tools (listThemes, setTheme, generateTheme, editTheme) and plugin tools (installSkill, uninstallSkill, toggleInstalledSkill, listInstalledSkills) - `system-prompt.ts`: dynamic prompt builder with page/user context - `catalog.ts`: component specs for DynamicUI rendering - - `chat-adapter.ts`: re-exports useChat hook + action handlers + - `chat-adapter.ts`: getTextFromParts, action registry, tool dispatch - `src/app/api/agent/route.ts`: streamText endpoint with 10-step multi-tool loop - `src/app/actions/agent.ts`: D1 persistence (save/load/delete conversations) -- components: `src/components/agent/chat-panel.tsx` (side panel), `src/components/dashboard-chat.tsx` (inline) +- unified chat architecture: one component, two presentations + - `ChatProvider` (layout level) owns chat state + panel open/close + persistence + - `ChatView variant="page"` on /dashboard (hero idle, typewriter, stats) + - `ChatView variant="panel"` in `ChatPanelShell` on all other pages + - `src/hooks/use-compass-chat.ts`: shared hook (useChat + action handlers + tool dispatch) + - chat state persists across navigation +- usage tracking: `agent_config`, `agent_usage`, `user_model_preference` tables track tokens/costs per conversation, per-user model override if admin allows - ai sdk v6 gotchas: - `inputSchema` not `parameters` for tool() definitions - UIMessage uses `parts` array, no `.content` field - useChat: `sendMessage({ text })` not `append({ role, content })` - useChat: `status` is "streaming"|"submitted"|"ready"|"error", not `isGenerating` + - useChat: needs `transport: new DefaultChatTransport({ api })` not `api` prop - zod schemas must use `import { z } from "zod/v4"` to match AI SDK internals + - ToolUIPart: properties may be flat or nested under toolInvocation ### netsuite integration - full bidirectional sync via REST API @@ -98,6 +119,56 @@ critical architecture patterns - sandbox URLs use different separators (123456-sb1 vs 123456_SB1) - omitting "line" param on line items adds new line (doesn't update) +### capacitor mobile app +- webview-based native wrapper loading the live cloudflare deployment (not a static export) +- the web app must never break because of native code: all capacitor imports are dynamic (`await import()` inside effects), gated behind `isNative()` checks, components return `null` on web +- platform detection: `src/lib/native/platform.ts` exports `isNative()`, `isIOS()`, `isAndroid()` +- native hooks in `src/hooks/`: `use-native.ts`, `use-native-push.ts`, `use-native-camera.ts`, `use-biometric-auth.ts`, `use-photo-queue.ts` +- native components in `src/components/native/`: biometric lock screen, offline banner, status bar sync, upload queue indicator, push registration +- offline photo queue (`src/lib/native/photo-queue.ts`): survives app kill, uses filesystem + preferences + background uploader +- push notifications via FCM HTTP v1 (`src/lib/push/send.ts`), routes to both iOS APNS and Android FCM +- `src/app/api/push/register/route.ts`: POST/DELETE for device token management +- env: FCM_SERVER_KEY +- see `docs/native-mobile.md` for full iOS/Android setup and app store submission guide + +### plugin/skills system +- agent can install external "skills" (github-hosted SKILL.md files in skills.sh format) or full plugin modules +- skills inject system prompt sections at priority 80, full plugins can also provide tools, components, query types, and action handlers +- source types: `builtin`, `local`, `npm`, `skills` +- key files in `src/lib/agent/plugins/`: + - `types.ts`: PluginManifest, PluginModule, SkillFrontmatter + - `skills-client.ts`: fetchSkillFromGitHub, parseSkillMd + - `loader.ts`: loadPluginModule (local/npm/builtin) + - `registry.ts`: buildRegistry, getRegistry (30s TTL cache per worker isolate) +- `src/app/actions/plugins.ts`: installSkill, uninstallSkill, toggleSkill, getInstalledSkills +- database: `plugins`, `plugin_config`, `plugin_events` tables in `src/db/schema-plugins.ts` + +### visual theme system +- per-user themeable UI with 10 built-in presets + AI-generated custom themes +- themes are full oklch color maps (32 keys for light + dark), fonts (sans/serif/mono with google fonts), design tokens (radius, spacing, shadows) +- presets: native-compass (default), corpo, notebook, doom-64, bubblegum, developers-choice, anslopics-clood, violet-bloom, soy, mocha +- key files in `src/lib/theme/`: + - `types.ts`: ThemeDefinition, ColorMap, ThemeFonts, ThemeTokens + - `presets.ts`: all 10 preset definitions + - `apply.ts`: `applyTheme()` injects css vars into `