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:
parent
861cf51d8d
commit
404a881758
105
CLAUDE.md
105
CLAUDE.md
@ -25,6 +25,13 @@ bun run db:migrate:local # apply migrations locally
|
|||||||
bun run db:migrate:prod # apply migrations to production D1
|
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
|
tech stack
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -37,7 +44,9 @@ tech stack
|
|||||||
| database | Cloudflare D1 (SQLite) via Drizzle ORM |
|
| database | Cloudflare D1 (SQLite) via Drizzle ORM |
|
||||||
| auth | WorkOS (SSO, directory sync) |
|
| auth | WorkOS (SSO, directory sync) |
|
||||||
| ai agent | AI SDK v6 + OpenRouter (kimi-k2.5 model) |
|
| 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 |
|
| state | React Context, server actions |
|
||||||
|
|
||||||
|
|
||||||
@ -52,10 +61,14 @@ critical architecture patterns
|
|||||||
- environment variables accessed via `getCloudflareContext()` → `env.DB` for D1
|
- environment variables accessed via `getCloudflareContext()` → `env.DB` for D1
|
||||||
|
|
||||||
### database
|
### database
|
||||||
- schema split across `src/db/schema.ts` (core) and `src/db/schema-netsuite.ts` (integration)
|
|
||||||
- drizzle ORM with D1 (SQLite dialect)
|
- drizzle ORM with D1 (SQLite dialect)
|
||||||
- text IDs (UUIDs), text dates (ISO 8601 format)
|
- text IDs (UUIDs), text dates (ISO 8601 format)
|
||||||
- migrations in `drizzle/` directory - **add new migrations, never modify old ones**
|
- 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
|
### authentication & middleware
|
||||||
- WorkOS handles SSO, email/password, directory sync
|
- WorkOS handles SSO, email/password, directory sync
|
||||||
@ -66,19 +79,27 @@ critical architecture patterns
|
|||||||
### ai agent harness
|
### ai agent harness
|
||||||
- located in `src/lib/agent/` - a complete AI-assisted system
|
- located in `src/lib/agent/` - a complete AI-assisted system
|
||||||
- `provider.ts`: OpenRouter setup for kimi-k2.5 model
|
- `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
|
- `system-prompt.ts`: dynamic prompt builder with page/user context
|
||||||
- `catalog.ts`: component specs for DynamicUI rendering
|
- `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/api/agent/route.ts`: streamText endpoint with 10-step multi-tool loop
|
||||||
- `src/app/actions/agent.ts`: D1 persistence (save/load/delete conversations)
|
- `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:
|
- ai sdk v6 gotchas:
|
||||||
- `inputSchema` not `parameters` for tool() definitions
|
- `inputSchema` not `parameters` for tool() definitions
|
||||||
- UIMessage uses `parts` array, no `.content` field
|
- UIMessage uses `parts` array, no `.content` field
|
||||||
- useChat: `sendMessage({ text })` not `append({ role, content })`
|
- useChat: `sendMessage({ text })` not `append({ role, content })`
|
||||||
- useChat: `status` is "streaming"|"submitted"|"ready"|"error", not `isGenerating`
|
- 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
|
- 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
|
### netsuite integration
|
||||||
- full bidirectional sync via REST API
|
- full bidirectional sync via REST API
|
||||||
@ -98,6 +119,56 @@ critical architecture patterns
|
|||||||
- sandbox URLs use different separators (123456-sb1 vs 123456_SB1)
|
- sandbox URLs use different separators (123456-sb1 vs 123456_SB1)
|
||||||
- omitting "line" param on line items adds new line (doesn't update)
|
- 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
|
### typescript discipline
|
||||||
- strict types: no `any`, no `as`, no `!` - use `unknown` with proper narrowing
|
- 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 }`
|
- discriminated unions over optional properties: `{ status: 'ok'; data: T } | { status: 'error'; error: E }`
|
||||||
@ -115,35 +186,45 @@ project structure
|
|||||||
src/
|
src/
|
||||||
├── app/ # next.js app router
|
├── app/ # next.js app router
|
||||||
│ ├── (auth)/ # auth pages (login, signup, etc)
|
│ ├── (auth)/ # auth pages (login, signup, etc)
|
||||||
│ ├── api/ # api routes (server actions, agent, webhooks)
|
│ ├── api/ # api routes (agent, push, netsuite, auth)
|
||||||
│ ├── dashboard/ # protected dashboard routes
|
│ ├── dashboard/ # protected dashboard routes
|
||||||
│ ├── actions/ # server actions (data mutations)
|
│ ├── actions/ # server actions (data mutations)
|
||||||
│ ├── globals.css # tailwind + theme variables
|
│ ├── globals.css # tailwind + theme variables
|
||||||
│ ├── layout.tsx # root layout
|
│ ├── layout.tsx # root layout
|
||||||
│ ├── middleware.ts # auth + public path checks
|
|
||||||
│ └── page.tsx # home page
|
│ └── page.tsx # home page
|
||||||
├── components/ # react components
|
├── components/ # react components
|
||||||
│ ├── ui/ # shadcn/ui primitives (auto-generated)
|
│ ├── ui/ # shadcn/ui primitives (auto-generated)
|
||||||
│ ├── agent/ # ai chat components
|
│ ├── agent/ # ai chat (ChatView, ChatProvider, ChatPanelShell)
|
||||||
|
│ ├── native/ # capacitor mobile components
|
||||||
│ ├── netsuite/ # netsuite connection ui
|
│ ├── netsuite/ # netsuite connection ui
|
||||||
|
│ ├── files/ # google drive file browser
|
||||||
│ └── *.tsx # app-specific components
|
│ └── *.tsx # app-specific components
|
||||||
├── db/
|
├── db/
|
||||||
│ ├── index.ts # getDb() function
|
│ ├── index.ts # getDb() function
|
||||||
│ ├── schema.ts # core drizzle schema
|
│ ├── schema.ts # core drizzle schema
|
||||||
│ └── schema-netsuite.ts # netsuite-specific tables
|
│ ├── schema-netsuite.ts # netsuite sync tables
|
||||||
├── hooks/ # custom react hooks
|
│ ├── schema-plugins.ts # plugin/skills tables
|
||||||
|
│ └── schema-theme.ts # theme tables
|
||||||
|
├── hooks/ # custom react hooks (incl. native hooks)
|
||||||
├── lib/
|
├── lib/
|
||||||
│ ├── agent/ # ai agent harness
|
│ ├── agent/ # ai agent harness + plugins/
|
||||||
|
│ ├── google/ # google drive integration
|
||||||
|
│ ├── native/ # capacitor platform detection + photo queue
|
||||||
│ ├── netsuite/ # netsuite integration
|
│ ├── netsuite/ # netsuite integration
|
||||||
|
│ ├── push/ # push notification sender
|
||||||
|
│ ├── theme/ # theme presets, apply, fonts
|
||||||
│ ├── auth.ts # workos integration
|
│ ├── auth.ts # workos integration
|
||||||
│ ├── permissions.ts # rbac checks
|
│ ├── permissions.ts # rbac checks
|
||||||
│ ├── utils.ts # cn() for class merging
|
│ ├── utils.ts # cn() for class merging
|
||||||
│ └── validations/ # zod schemas
|
│ └── validations/ # zod schemas
|
||||||
└── types/ # global typescript types
|
└── types/ # global typescript types
|
||||||
|
|
||||||
|
ios/ # xcode project (capacitor)
|
||||||
|
android/ # android studio project (capacitor)
|
||||||
drizzle/ # database migrations (auto-generated)
|
drizzle/ # database migrations (auto-generated)
|
||||||
docs/ # user documentation
|
docs/ # user documentation
|
||||||
public/ # static assets
|
public/ # static assets
|
||||||
|
capacitor.config.ts # capacitor native config
|
||||||
wrangler.jsonc # cloudflare workers config
|
wrangler.jsonc # cloudflare workers config
|
||||||
drizzle.config.ts # drizzle orm config
|
drizzle.config.ts # drizzle orm config
|
||||||
next.config.ts # next.js config
|
next.config.ts # next.js config
|
||||||
@ -175,6 +256,8 @@ required:
|
|||||||
- WORKOS_API_KEY, WORKOS_CLIENT_ID
|
- WORKOS_API_KEY, WORKOS_CLIENT_ID
|
||||||
- OPENROUTER_API_KEY (for ai agent)
|
- OPENROUTER_API_KEY (for ai agent)
|
||||||
- NETSUITE_* (if using netsuite sync)
|
- NETSUITE_* (if using netsuite sync)
|
||||||
|
- GOOGLE_SERVICE_ACCOUNT_ENCRYPTION_KEY (if using google drive)
|
||||||
|
- FCM_SERVER_KEY (if using push notifications)
|
||||||
|
|
||||||
development tips
|
development tips
|
||||||
---
|
---
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user