chore: update subproject commits for waitlist and website
This commit is contained in:
@@ -79,6 +79,8 @@ Main Process (Node.js)
|
|||||||
- `src/main/auth/auth-manager.ts` — Login, register, logout, OAuth flow (singleton)
|
- `src/main/auth/auth-manager.ts` — Login, register, logout, OAuth flow (singleton)
|
||||||
- `src/main/auth/backup-key.ts` — Device-specific AES-256 backup key (safeStorage, not password-derived)
|
- `src/main/auth/backup-key.ts` — Device-specific AES-256 backup key (safeStorage, not password-derived)
|
||||||
- `src/main/ai/token.ts` — Two-tier token storage: safeStorage + electron-store fallback
|
- `src/main/ai/token.ts` — Two-tier token storage: safeStorage + electron-store fallback
|
||||||
|
- `src/main/auth/locale-defaults.ts` — Detects timezone, date/time format, language from OS locale
|
||||||
|
- `src/main/api/format-row.ts` — Formats timestamp columns in query results using user's FormatPrefs
|
||||||
|
|
||||||
**Non-obvious details**:
|
**Non-obvious details**:
|
||||||
- `electron-trpc` is NOT used — custom IPC bridge in `ipc.ts` + `ipcLink.ts` because electron-trpc bundles tRPC v10 internals
|
- `electron-trpc` is NOT used — custom IPC bridge in `ipc.ts` + `ipcLink.ts` because electron-trpc bundles tRPC v10 internals
|
||||||
@@ -88,6 +90,30 @@ Main Process (Node.js)
|
|||||||
- Timestamps are milliseconds (JavaScript `Date.getTime()`), not ISO strings
|
- Timestamps are milliseconds (JavaScript `Date.getTime()`), not ISO strings
|
||||||
- Notes auto-embed to LanceDB on create/update (fire-and-forget, errors swallowed)
|
- Notes auto-embed to LanceDB on create/update (fire-and-forget, errors swallowed)
|
||||||
|
|
||||||
|
**Onboarding Wizard**:
|
||||||
|
- First-run wizard collects 5 fields: `job_role`, `industry`, `primary_use_case`, `tone_preference`, `language`. Plus `user_name` derived from profile `name`+`surname`.
|
||||||
|
- All fields stored as encrypted core memory (backend `MemoryMiddleware`), not local electron-store.
|
||||||
|
- `onboarding_completed_at` on the `users` table (nullable TIMESTAMPTZ) gates the flow — `null` = show wizard, non-null = skip.
|
||||||
|
- `AppShell.tsx` gates: if `profile.onboardingCompletedAt == null` → render `<OnboardingFlow>` instead of the app.
|
||||||
|
- `auth.status` tRPC procedure auto-seeds `language` and `user_name` into MemoryCore if missing (fire-and-forget `.catch(() => {})`).
|
||||||
|
- Format prefs (timezone, dateFormat, timeFormat) are stored in electron-store (`FormatPrefs`), not core memory — they're device-specific.
|
||||||
|
- `drizzle-executor.ts` wraps all query results through `formatRow()`/`formatRows()` using the user's FormatPrefs.
|
||||||
|
- Settings > Profile section allows post-onboarding editing of all fields + format prefs.
|
||||||
|
- **Gotcha — shadcn Button `outline` variant in dark mode**: The variant defines `dark:bg-input/30 dark:border-input dark:hover:bg-input/50` which overrides any custom `className` background. Fix: switch between `variant="default"` and `variant="outline"` instead of adding className overrides.
|
||||||
|
- **Gotcha — locale codes vs human names**: `app.getLocale()` and `navigator.language` return codes like `en-US`. Use `Intl.DisplayNames(undefined, { type: 'language' })` to convert to "English". This must be done in both the main process (`locale-defaults.ts`) and renderer (`OnboardingFlow.tsx`).
|
||||||
|
|
||||||
|
**i18n (Internationalization)**:
|
||||||
|
- Uses `i18next` + `react-i18next` with bundled JSON translations (no lazy loading).
|
||||||
|
- Config in `src/renderer/i18n.ts`. 5 languages: EN, IT, ES, FR, DE. `SUPPORTED_LANGUAGES` array exported for UI selectors.
|
||||||
|
- Translation files: `src/renderer/locales/{en,it,es,fr,de}/translation.json`. Namespaces: `nav`, `auth`, `tasks`, `settings`, `common`, `errors`, `home`, `timeline`, `projects`, `agents`.
|
||||||
|
- **`common.*` namespace** holds shared labels (`save`, `cancel`, `delete`, `edit`, `add`, `rename`, `saving`, `deleting`, `creating`, `renameDescription`, `deleteTitle`). Before adding a new key, check if `common.*` already has it.
|
||||||
|
- Pluralization uses i18next `_one`/`_other` suffixes (e.g. `tasksDueToday_one`, `tasksDueToday_other`).
|
||||||
|
- `LanguageSync` component in `src/renderer/index.tsx` reads persisted `uiLanguage` from electron-store via tRPC on startup and syncs to i18next.
|
||||||
|
- Language selector lives in `GeneralSection.tsx` (Settings > General). On change it: (1) calls `i18n.changeLanguage()`, (2) persists to electron-store via `setUiLanguage` mutation, (3) writes to backend core memory so AI responds in the same language.
|
||||||
|
- `getUiLanguage()` exported from `src/main/store.ts` — used by `orchestrator.ts` to append language hint to daily brief prompt.
|
||||||
|
- Static data arrays that need translation use `labelKey` pattern (not `label`): store a translation key, call `t(labelKey)` at render time. Used in `NAV_ITEMS`, `COLUMNS`, `SECTIONS`, `SUGGESTION_CHIPS`.
|
||||||
|
- When adding new translated text: add the key to **all 5** JSON files. Keep `common.*` keys consistent across all languages.
|
||||||
|
|
||||||
**Google OAuth (adiuvAI side)**:
|
**Google OAuth (adiuvAI side)**:
|
||||||
- `adiuvai://` is NOT accepted by Google as a redirect URI — Google only accepts `http://localhost` or `https://`. The API backend exposes `GET /auth/oauth/google/web-callback` which receives the Google redirect and immediately bounces to `adiuvai://oauth/callback?...`. The redirect URI registered in Google Cloud Console points to the backend, not the Electron app.
|
- `adiuvai://` is NOT accepted by Google as a redirect URI — Google only accepts `http://localhost` or `https://`. The API backend exposes `GET /auth/oauth/google/web-callback` which receives the Google redirect and immediately bounces to `adiuvai://oauth/callback?...`. The redirect URI registered in Google Cloud Console points to the backend, not the Electron app.
|
||||||
- `app.requestSingleInstanceLock()` is required for the `second-instance` event to fire on Windows/Linux. If it returns `false`, call `app.quit()` immediately (another instance is already running).
|
- `app.requestSingleInstanceLock()` is required for the `second-instance` event to fire on Windows/Linux. If it returns `false`, call `app.quit()` immediately (another instance is already running).
|
||||||
@@ -182,6 +208,17 @@ FastAPI app (app/main.py)
|
|||||||
- **CORS includes `app://`**: Electron uses custom `app://` protocol, not http/https
|
- **CORS includes `app://`**: Electron uses custom `app://` protocol, not http/https
|
||||||
- **Vector search on encrypted data is not semantic**: Backend derives deterministic 32-dim floats from blob SHA-256 for storage/search — a known trade-off
|
- **Vector search on encrypted data is not semantic**: Backend derives deterministic 32-dim floats from blob SHA-256 for storage/search — a known trade-off
|
||||||
|
|
||||||
|
**Onboarding (API side)**:
|
||||||
|
- `PUT /auth/me/memory` — updates core memory k/v pairs and optionally marks onboarding complete (`mark_onboarded: true` sets `users.onboarding_completed_at`).
|
||||||
|
- `POST /auth/me/onboarding/reset` — nullifies `onboarding_completed_at` so the wizard re-runs.
|
||||||
|
- `POST /auth/onboarding/normalize` — LLM-normalizes free-text onboarding inputs via `gpt-4o-mini`; returns inputs unchanged on error.
|
||||||
|
- `get_current_user()` in `auth.py` middleware now decrypts core memory blocks and includes them in `UserProfile.memory` dict.
|
||||||
|
- `users.onboarding_completed_at` is a nullable TIMESTAMPTZ column — returned as epoch ms (int) in UserProfile schema.
|
||||||
|
|
||||||
|
**i18n (API side)**:
|
||||||
|
- `_language_instruction()` in `app/core/deep_agent.py` reads the user's `language` from `MemoryCore` and appends a system prompt directive ("Always respond in {language}") to all 4 `run_*` functions.
|
||||||
|
- The Electron client writes the user's chosen language to backend core memory on language change, so the API picks it up on the next agent call.
|
||||||
|
|
||||||
**Google OAuth (api side)**:
|
**Google OAuth (api side)**:
|
||||||
- OAuth routes live in `app/api/routes/auth.py`: `GET /auth/oauth/{provider}/authorize`, `POST /auth/oauth/{provider}/callback`, `GET /auth/oauth/{provider}/web-callback` (bounces to deep link, excluded from OpenAPI schema).
|
- OAuth routes live in `app/api/routes/auth.py`: `GET /auth/oauth/{provider}/authorize`, `POST /auth/oauth/{provider}/callback`, `GET /auth/oauth/{provider}/web-callback` (bounces to deep link, excluded from OpenAPI schema).
|
||||||
- Provider abstraction in `app/auth/oauth_providers.py` — `GoogleOAuthProvider` uses `httpx` directly (no `authlib`). PKCE S256 is implemented manually via `generate_pkce_pair()`.
|
- Provider abstraction in `app/auth/oauth_providers.py` — `GoogleOAuthProvider` uses `httpx` directly (no `authlib`). PKCE S256 is implemented manually via `generate_pkce_pair()`.
|
||||||
|
|||||||
2
waitlist
2
waitlist
Submodule waitlist updated: d32fc7ae30...df43f4783a
2
website
2
website
Submodule website updated: 7da1f5811e...0006f36215
Reference in New Issue
Block a user