AQBot uses two directory roots with distinct responsibilities:
| Root | Platform path | Purpose |
|---|---|---|
| Config home | macOS/Linux: ~/.aqbot/Windows: %USERPROFILE%\.aqbot\ |
Application state, database, encryption keys, SSL, vector DB |
| Documents root | macOS/Linux: ~/Documents/aqbot/Windows: %USERPROFILE%\Documents\aqbot\ |
User-visible files: images, documents, backups |
Both directories are created automatically on first launch.
~/.aqbot/
├── aqbot.db # SQLite database (all app state, settings, keys, …)
├── master.key # 32-byte AES-256 master encryption key (mode 0600 on Unix)
├── vector_db/ # sqlite-vec vector store for knowledge-base embeddings
└── ssl/ # Self-signed TLS certificate and private key for the gateway
├── cert.pem
└── key.pem # mode 0600 on Unix
~/Documents/aqbot/
├── images/ # Image attachments (chat uploads, avatars, AI-generated)
├── files/ # Non-image file attachments (documents, code, archives)
└── backups/ # Default location for auto- and manual backups
All paths stored in the database (e.g. messages.attachments, stored_files.storage_path)
use relative paths under the documents root (e.g. images/abc123_photo.jpg).
User-created files (images, documents, backups) belong in a user-visible
location under ~/Documents/ so users can browse, back up, and share them
with standard OS tools. Application internals (database, encryption keys,
vector indices) stay hidden in ~/.aqbot/ to avoid clutter and accidental
modification.
Tauri's app_data_dir() resolves to platform-specific, version-locked paths
(e.g. ~/Library/Application Support/top.aqbot.app/ on macOS). Using a
user-visible ~/.aqbot/ makes backups, debugging, and cross-version upgrades
predictable and independent of the Tauri bundle identifier.
The database and its master encryption key are always migrated as a matched
pair. During the one-time migration from the legacy app_data_dir:
- Both files are copied to
~/.aqbot/*.migratingstaging names. - Both staging files are renamed to their final names in a single pass.
- If either step fails the staging files are cleaned up and the old location is left intact — no data is ever left in a half-migrated state.
vector_db/ and ssl/ are migrated best-effort (rename, falling back to
copy+delete for cross-device moves). A failure to migrate a subdirectory is
logged as a warning; the application continues normally and the new
subdirectory will be created empty on next use.
resolve_backup_dir(None) returns ~/Documents/aqbot/backups/.
Users may override this via Settings → Backup → Backup Directory; an absolute
path stored there takes precedence.
generate_self_signed_cert writes cert.pem and key.pem to
~/.aqbot/ssl/. The private key is written atomically (temp-file + rename)
with mode 0600 on Unix.
- Application state (database, keys, vector DB): read/write under
~/.aqbot/ - User files (images, documents, backups): read/write under
~/Documents/aqbot/ - Database paths for files must be relative to the documents root
- Do not hard-code paths derived from
app_data_dir, bundle identifier, or application version strings - All directory names are lowercase with no spaces
- This rule applies equally to frontend, backend, and test code: every hand-written source file MUST be 3000 lines or fewer. A file that would exceed 3000 lines MUST be split before more code is added; there are no frontend or backend exceptions.
- Split UI code into focused components and composables/hooks. Extract logic that can be reused into a dedicated module with a small, explicit interface instead of duplicating it across callers.
- If business logic is intentionally not reusable, split it by cohesive domain responsibility, workflow stage, or feature area, then reference those files through explicit language-native modules, imports, or source includes. Do not split at arbitrary line numbers or hide oversized implementations behind generated indirection.
- Keep the original entry file as a small facade when callers need a stable interface. Every extracted file is subject to the same 3000-line limit.
- Before completing a code change, scan the affected repository for source files over 3000 lines and continue decomposing until none remain.
- Machine-generated dependency locks, generated artifacts, and binary assets are maintained by their generators and MUST NOT be manually split or edited merely to satisfy this source-code limit.
- All user-visible text MUST use i18n, including tooltips, placeholders, empty states, modal content, notifications, context menus, and accessibility labels such as
aria-labeland imagealttext. - Do not add raw Chinese or English UI copy directly in TS/TSX. Technical identifiers, protocol names, brand names, code samples, URLs, file extensions, and units may remain literal when they are intentionally language-neutral.
- Simplified Chinese (
zh-CN) and English (en-US) are the semantic source locales. Every new key MUST be added to both with equivalent meaning before other locales are updated. - Every locale MUST contain the same leaf-key set, non-empty values, and identical interpolation placeholders such as
{{count}}. - A key existing in every locale is not sufficient: non-English locales MUST NOT copy the English value for translatable UI text. Intentional shared values such as
HTTP,GitHub, model IDs, and product names must be explicitly treated as language-neutral. - Prefer
t('namespace.key')after the locale entry exists. Do not use a Chinese or EnglishdefaultValueto hide a missing locale entry. - Dynamic keys MUST be backed by a finite, reviewable key set in every locale; never construct unbounded translation keys from external input.
- Before completing i18n work, run the locale completeness tests and scan changed UI files for raw visible strings. Verify at least one Chinese locale, English, and one non-Latin locale when sentence fragments are composed around dynamic components.
All antd <Image> components must use blur-mask preview:
<Image preview={{ mask: { blur: true }, scaleStep: 0.5 }} />mask: { blur: true }— hover shows a blurred overlay (nevermask: falseor plain text mask)scaleStep: 0.5— consistent zoom step across the app- These settings apply to all image previews: chat attachments, file list thumbnails, avatar previews, etc.