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 <nicholaivogelfilms@gmail.com>
This commit is contained in:
Nicholai 2026-02-07 02:27:53 -07:00 committed by GitHub
parent 861cf51d8d
commit 404a881758
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

105
CLAUDE.md
View File

@ -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 `<style id="compass-theme-vars">`, instant without page reload
- `fonts.ts`: `loadGoogleFonts()` dynamic `<link>` injection
- `src/app/actions/themes.ts`: getUserThemePreference, setUserThemePreference, saveCustomTheme, deleteCustomTheme
- database: `custom_themes`, `user_theme_preference` tables in `src/db/schema-theme.ts`
### google drive integration
- domain-wide delegation via service account (impersonates users by email)
- two-layer permissions: compass RBAC first, then google workspace permissions
- bidirectional: browse drive files in compass, upload from compass to drive, supports shared drives
- key files in `src/lib/google/`:
- `auth/service-account.ts`: JWT creation, token exchange (web crypto API, RS256)
- `client/drive-client.ts`: REST client with retry, rate limiting, impersonation
- `mapper.ts`: DriveFile -> FileItem
- `src/app/actions/google-drive.ts`: 17 server actions (connect, disconnect, list, search, create, rename, move, trash, restore, upload, etc.)
- file browser UI in `src/components/files/`
- database: `google_auth`, `google_starred_files` tables, `users.google_email` column
- env: GOOGLE_SERVICE_ACCOUNT_ENCRYPTION_KEY
- see `docs/google-drive/GOOGLE-DRIVE-INTEGRATION.md` for full setup guide
### typescript discipline
- strict types: no `any`, no `as`, no `!` - use `unknown` with proper narrowing
- discriminated unions over optional properties: `{ status: 'ok'; data: T } | { status: 'error'; error: E }`
@ -115,35 +186,45 @@ project structure
src/
├── app/ # next.js app router
│ ├── (auth)/ # auth pages (login, signup, etc)
│ ├── api/ # api routes (server actions, agent, webhooks)
│ ├── api/ # api routes (agent, push, netsuite, auth)
│ ├── dashboard/ # protected dashboard routes
│ ├── actions/ # server actions (data mutations)
│ ├── globals.css # tailwind + theme variables
│ ├── layout.tsx # root layout
│ ├── middleware.ts # auth + public path checks
│ └── page.tsx # home page
├── components/ # react components
│ ├── ui/ # shadcn/ui primitives (auto-generated)
│ ├── agent/ # ai chat components
│ ├── agent/ # ai chat (ChatView, ChatProvider, ChatPanelShell)
│ ├── native/ # capacitor mobile components
│ ├── netsuite/ # netsuite connection ui
│ ├── files/ # google drive file browser
│ └── *.tsx # app-specific components
├── db/
│ ├── index.ts # getDb() function
│ ├── schema.ts # core drizzle schema
│ └── schema-netsuite.ts # netsuite-specific tables
├── hooks/ # custom react hooks
│ ├── schema-netsuite.ts # netsuite sync tables
│ ├── schema-plugins.ts # plugin/skills tables
│ └── schema-theme.ts # theme tables
├── hooks/ # custom react hooks (incl. native hooks)
├── lib/
│ ├── agent/ # ai agent harness
│ ├── agent/ # ai agent harness + plugins/
│ ├── google/ # google drive integration
│ ├── native/ # capacitor platform detection + photo queue
│ ├── netsuite/ # netsuite integration
│ ├── push/ # push notification sender
│ ├── theme/ # theme presets, apply, fonts
│ ├── auth.ts # workos integration
│ ├── permissions.ts # rbac checks
│ ├── utils.ts # cn() for class merging
│ └── validations/ # zod schemas
└── types/ # global typescript types
ios/ # xcode project (capacitor)
android/ # android studio project (capacitor)
drizzle/ # database migrations (auto-generated)
docs/ # user documentation
public/ # static assets
capacitor.config.ts # capacitor native config
wrangler.jsonc # cloudflare workers config
drizzle.config.ts # drizzle orm config
next.config.ts # next.js config
@ -175,6 +256,8 @@ required:
- WORKOS_API_KEY, WORKOS_CLIENT_ID
- OPENROUTER_API_KEY (for ai agent)
- NETSUITE_* (if using netsuite sync)
- GOOGLE_SERVICE_ACCOUNT_ENCRYPTION_KEY (if using google drive)
- FCM_SERVER_KEY (if using push notifications)
development tips
---