- Rename all user-facing and technical identifiers from OpenPets/Pet to FamiliarOS/Familiar. - Rename packages from @open-pets/* to @familiaros/*; rename install-pet/pet-format packages. - Rename plugin IDs and directories from openpets.* to familiaros.*. - Rename IPC namespace from openpets:* to familiaros:* and state filenames from openpets-* to familiaros-* with legacy migration. - Rename source files (pet-window, built-in-pet, default-pet-controller, etc.) to familiar equivalents. - Update locales (en, es-419, ja, ko, pt-BR, zh-Hans, zh-Hant) and tray/pet context menu strings. - Add Familiar naming feature: preference, settings input, tray menu display. - Update assets and packaging config; all desktop tests pass.
8.7 KiB
apps/desktop/
Responsibility
FamiliarOS desktop companion application. Tray-first Electron app providing animated desktop familiars that react to coding agent events. Manages familiar installations, the React/Tailwind Control Center, plugin automation/runtime, agent integrations (Claude Code, OpenCode, Cursor, Pi guidance), and local IPC for CLI communication.
Design
- Tray-First UX: No default main window; tray actions open the singleton React/Tailwind Control Center and route directly to Dashboard, Familiars, Integrations, Plugins, and Settings.
- Single Instance: Uses
app.requestSingleInstanceLock()with second-instance focusing - Security Model:
- Sandboxed renderers with contextIsolation
- Preload scripts expose limited APIs via
contextBridge - CSP:
default-src 'none', inline styles only - Mock keychain to prevent OS credential prompts
- IPC network security: loopback/private address filtering for TCP mode
- State Management: File-based JSON state with atomic writes (temp + rename)
- Familiar Architecture:
- Default familiar (always visible when enabled)
- Agent familiars (lease-based, appear on explicit agent requests)
- Built-in fallback familiar (bundled spritesheet)
- Speech bubbles with reaction messages and status badges
- User-configurable reaction-to-animation mapping
- Lease Manager: 15s TTL leases for agent familiar routing with heartbeat renewal
- Logging: Structured logging with scopes, log rotation (2MB max), and sensitive data redaction
- Plugin Subsystem: Declarative manifest plugins and JavaScript plugin hosting with permission approval, config schemas, command/status surfaces, catalog/local installs, SDK bridge quotas, storage, schedules, restricted HTTPS fetch, and safe path/ZIP/manifest validation
Flow
Startup: main.ts → installAppLifecycle() → initializeAppState() → initializeLogger() → createAppTray() → startLocalIpcServer() → initialize plugin service with JavaScript host/SDK bridge → optionally showDefaultPet()
Familiar Display: IPC Request → local-ipc.ts → LeaseManager.acquire() → agent-familiar-controller.ts → familiar-window.ts → HTML/CSS spritesheet animation with reaction-to-animation mapping
Installation: Catalog fetch (V3 with pagination fallback to V2) → ZIP download → yauzl extraction → validation → state update → tray refresh
Agent Setup: UI → agent-setup.ts → Claude/OpenCode/Cursor CLI detection → MCP config modification → hooks installation → memory file management
Control Center: Tray route → openControlCenterWindow(route) → windows.ts loads Vite renderer and sends route events → control-center-preload.cjs exposes narrow page APIs → React Dashboard/Familiars/Integrations/Plugins/Settings routes render snapshots and invoke actions.
Plugins: Control Center plugins route → plugin-service.ts → catalog or local manifest/entry loader → permission approval/state update → plugin-runtime.ts schedules declarative timers or starts plugin-js-host.ts → plugin-sdk-bridge.ts applies approved SDK calls to familiar/schedule/storage/command/status/network APIs
Integration Points
- Workspace Packages:
@familiaros/agent-events,@familiaros/claude,@familiaros/cli,@familiaros/cursor,@familiaros/mcp,@familiaros/opencode - External Services:
https://familiaros.dev/familiars/catalog.v2.json(familiar catalog V2)https://familiaros.dev/familiars/catalog.v3.json(familiar catalog V3 with pagination)https://familiaros.dev/plugins/catalog.v1.json(plugin catalog V1)https://zip.familiaros.dev/familiars/{id}.zip(familiar downloads)https://zip.familiaros.dev/plugins/{id}.zip(plugin downloads)- GitHub API (release checks)
- System Integration:
- Claude Code:
~/.claude/CLAUDE.md,~/.claude/settings.json,claude mcpcommands - OpenCode:
~/.opencode/config.json - Cursor:
~/.cursor/mcp.json,.cursor/rules/familiaros.mdc - Codex:
~/.codex/familiars/(local familiar development) - IPC: Discovery file at platform-specific path, Unix socket/Windows named pipe/TCP
- Logs:
userData/logs/familiaros.log
- Claude Code:
- Build:
electron-builderwith ASAR, cross-platform (macOS/Windows/Linux)
Key Files
main.ts: Entry point, lifecycle coordinationtray.ts: System tray icon and menuwindows.ts: Control Center BrowserWindow management, Dashboard snapshot, route targeting, IPC handlers, and internal protocolsrenderer/: React/Tailwind Control Center for Dashboard, Familiars, Integrations, Plugins, and Settingslocal-ipc.ts: TCP/Unix socket server for CLI communicationlease-manager.ts: Familiar routing lease lifecyclefamiliar-window.ts: Familiar rendering (transparent frameless windows, CSS sprite animation, speech bubbles, status badges)default-familiar-controller.ts/agent-familiar-controller.ts: Familiar visibility/state management with transient displaysapp-state.ts: Persistent state management (JSON file)agent-setup.ts: Claude/OpenCode/Cursor integration logicplugin-service.ts: Plugin orchestration for snapshots, enable/config/reload, command execution, catalog install/update/uninstall, local loading, permission approval, JavaScript host wiring, and runtime reloadsplugin-manifest.ts:familiaros.plugin.jsonv1/v2 schema/types/validator for declarative timer plugins and JavaScript SDK plugins, config fields, permissions, commands/status/network, and actionsplugin-runtime.ts: Runtime that compiles enabled declarative timers and starts JavaScript plugin hosts for approved familiar/schedule/storage/command/status/network actionsplugin-state.ts: Atomic JSON state store for installed plugins, enabled flag, approved permissions, config, broken state, and update metadataplugin-config.ts: Plugin default/effective config validation and config reference resolutionplugin-catalog.ts/plugin-catalog-validation.ts: Plugin catalog fetch/cache and strict catalog entry validationplugin-package.ts: Catalog plugin ZIP download, SHA-256 verification, manifest extraction, install, and safe uninstall path resolutionplugin-local-loader.ts: Local developer plugin folder validation and manifest snapshotting into app dataplugin-manifest-reader.ts: Safe installed-manifest reader enforcing allowed roots, size limits, path containment, and expected id/versionplugin-familiar-api.ts: Runtime bridge from plugin actions to default familiar speech/reaction APIsplugin-js-host.ts: Hidden sandboxed BrowserWindow host for JavaScript plugin entry modules, SDK IPC tokening, session hardening, startup handshake, and teardownplugin-sdk-bridge.ts: Permission-checked SDK API for JavaScript plugins with quotas, plugin storage, schedules, config listeners, commands/status, logs, and restricted HTTPS fetchfamiliar-installation.ts: Catalog ZIP download and extractioncodex-familiars.ts: Local Codex familiar importcatalog.ts: Remote catalog fetching with V3 pagination and fixture fallbacklogger.ts: Structured logging with scopes (app, ipc, lease, familiar, state, tray, ui)reaction-animation-mapping.ts: Reaction-to-animation state mapping with user overridesreaction-messages.ts: Message pools for each reaction typecontrol-center-preload.cjs/familiar-preload.cjs/plugin-sdk-preload.cjs: Narrow contextBridge APIs for the Control Center, familiar windows, and plugin SDK host; the legacypreload.cjstask-window bridge andplugins-window.tsUI have been removedelectron-builder.yml: Packaging configurationscripts/release-local.mjs: macOS-local release automation with GitHub draft creationcontracts/catalog-fixture.contract.ts: Catalog V2 validation contract tests against fixture datacontracts/local-ipc-protocol.contract.ts: IPC protocol validation contract tests for request/response parsingcontracts/plugin-manifest.contract.ts: Plugin manifest boundary contract for v1 schema, config references, permissions, deferred features, and action validation
Test Structure
- Behavior tests (
tests/*.test.ts): Unit tests for lease manager, state management, version checking, ZIP safety, Codex familiars, Claude memory, and reaction animation mapping. Compiled to.test-dist/tests/. - Contract tests (
contracts/*.contract.ts): Public API boundary validation for catalog fixtures, IPC protocol, and plugin manifest schema. Compiled to.test-dist/contracts/. - Runtime checks (
src/check-*.ts): Remaining runtime validation checks compiled todist/. - Test runner (
scripts/run-tests.mjs): Orchestrates preload syntax checks → test compilation → behavior tests → contract tests → dist checks.