Skip to content

Commit f92ec4c

Browse files
committed
Merge remote-tracking branch 'origin' into feat/e2e-linux-ci-default
2 parents da3c04b + 8486a3b commit f92ec4c

122 files changed

Lines changed: 16043 additions & 1569 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.claude/agents/memory-keeper.md‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
name: memory-keeper
3+
description: Updates .claude/memory.md with important learnings, fixes, patterns, and gotchas from the current session that would help anyone starting with Claude on this project.
4+
model: sonnet
5+
color: purple
6+
---
7+
8+
# Memory Keeper
9+
10+
## Purpose
11+
12+
Scan the current conversation context and update `.claude/memory.md` with anything important that was learned, fixed, discovered, or decided during this session. This file serves as institutional knowledge for anyone starting with Claude on this project.
13+
14+
## What to capture
15+
16+
- **Fixes and workarounds** — what broke and how it was fixed (e.g. CORS errors, service gate issues)
17+
- **Gotchas** — non-obvious things that tripped us up (e.g. socket not connected at startup)
18+
- **Strict instructions** — rules or patterns the user emphasized
19+
- **Architecture decisions** — why something was done a certain way
20+
- **Environment setup** — things needed to get the project running
21+
- **Commands that matter** — non-obvious commands or flags
22+
23+
## What NOT to capture
24+
25+
- Obvious things derivable from `CLAUDE.md` or code
26+
- Temporary debugging steps
27+
- Personal info about the user
28+
- Anything already documented elsewhere
29+
30+
## How to update
31+
32+
1. Read the current `.claude/memory.md` file
33+
2. Review the conversation context for new learnings
34+
3. Add new entries under the appropriate section
35+
4. Keep entries short — one line per item, max two lines for complex ones
36+
5. Use `##` headers to group by topic
37+
6. Do not duplicate existing entries
38+
7. Remove entries that are no longer true
39+
40+
## Format
41+
42+
```markdown
43+
## Section Name
44+
45+
- **Short title** — Brief explanation of what was learned and why it matters
46+
```
47+
48+
## Rules
49+
50+
- Keep the file under 100 lines total
51+
- Be concise — this is a quick reference, not documentation
52+
- Every entry should answer: "What would I wish I knew before starting?"
53+
- Update in place — edit existing entries if they've changed, don't append duplicates

‎.claude/memory.md‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Project Memory
2+
3+
Quick reference for anyone starting with Claude on this project. Updated by the `memory-keeper` agent.
4+
5+
## Fixes & Gotchas
6+
7+
- **ServiceBlockingGate CORS errors** — The gate calls `openhumanServiceStatus()` and `openhumanAgentServerStatus()` at startup. These used `callCoreRpc()` which falls back to raw `fetch()` when socket isn't connected yet, causing CORS errors. Fix: route through `invoke('core_rpc_relay')` instead (Tauri IPC, no CORS).
8+
- **Socket not connected at startup** — `SocketProvider` only connects when a Redux `auth.token` is set. At fresh launch (no token), socket is null, so any `callCoreRpc()` call falls back to `fetch()`. Always use `invoke('core_rpc_relay')` for local sidecar RPC calls.
9+
- **`openhuman.agent_server_status` doesn't exist** — This RPC method is not registered in the core. The gate checks it but it always errors. The gate passes if either service is Running OR agent server is running OR core is reachable.
10+
- **Cargo incremental builds can serve stale UI** — If the app shows old frontend after a Rust rebuild, run `cargo clean --manifest-path app/src-tauri/Cargo.toml` before rebuilding.
11+
- **macOS deep links require .app bundle** — `yarn tauri dev` does NOT support deep links. Must use `yarn tauri build --debug --bundles app`.
12+
13+
## Strict Rules
14+
15+
- **No dynamic imports in `app/src/`** — Use static `import` at file top. Guard call sites with `try/catch` for Tauri/non-Tauri safety. See CLAUDE.md.
16+
- **Service RPC calls must use Tauri IPC** — Never use `callCoreRpc()` for service operations. Use `invoke('core_rpc_relay', { request: { method, params } })`.
17+
- **All frontend env vars go through `app/src/utils/config.ts`** — Never read `import.meta.env.VITE_*` directly in other files. Import from config.ts instead. See `.env.example` files for the full list.
18+
- **Always run checks before commit** — `yarn typecheck`, `yarn lint`, `yarn format:check`, `yarn build`, `yarn tauri dev`. Husky hooks enforce some but run all manually first.
19+
- **Stage specific files** — Never `git add -A`. Always `git add <specific-files>`.
20+
21+
## Workflow
22+
23+
- **Agent order**: architectobot (plan) → user approval → codecrusher (implement) → architectobot (verify)
24+
- **Always read CLAUDE.md first** before any issue work
25+
- **Ask user when in doubt** — never assume scope or approach
26+
- **PRs target upstream** — `tinyhumansai/openhuman` main branch, not fork
27+
28+
## Local AI Presets & Daemon Gotcha
29+
30+
- **Tier system lives in `src/openhuman/local_ai/presets.rs`** — single source of truth for tier→model ID mapping. To change default models for a release, edit `all_presets()` there.
31+
- **Device detection** uses `sysinfo` crate (`src/openhuman/local_ai/device.rs`). Apple Silicon = GPU always; others = best-effort.
32+
- **`OPENHUMAN_LOCAL_AI_TIER` env var** overrides the selected tier at config load time (in `load.rs`).
33+
- **Frontend tier selector** is in `LocalModelPanel.tsx` under Settings > Local AI Model. Uses `coreRpcClient` to call 3 RPC methods: `local_ai_device_profile`, `local_ai_presets`, `local_ai_apply_preset`.
34+
- **Default config maps to Medium tier** (`gemma3:4b-it-qat`). If someone changes `model_ids.rs` defaults, they should keep `presets.rs` in sync.
35+
- **Daemon binary gotcha** — A daemon process (`openhuman-aarch64-apple-darwin run`) auto-starts on port 7788 and respawns on kill. `yarn tauri dev` reuses it if already running. When adding new RPC methods, you must replace this binary: `cp -f target/debug/openhuman-core app/src-tauri/binaries/openhuman-aarch64-apple-darwin`, then kill the old PID so it respawns with the new binary.
36+
37+
## Onboarding System
38+
39+
- **OnboardingOverlay is a portal, not a route** — mounted in `App.tsx`, renders via `createPortal` at z-[9999]. There is no `/onboarding` route in `AppRoutes.tsx`. Gating is purely Redux + workspace flag.
40+
- **Deferred onboarding** — `onboardingDeferredByUser` in `authSlice.ts` (persisted via redux-persist) durably tracks when a user clicks "Set up later". `SetupBanner.tsx` provides the resume path.
41+
- **`selectHasIncompleteOnboarding` is unused** in production code — only tested. Don't use it for new features.
42+
- **`formatBytes` / `formatEta` / `progressFromStatus`** — shared in `app/src/utils/localAiHelpers.ts`. Home.tsx and LocalModelPanel.tsx still have local copies (can be migrated later).
43+
- **Notification z-index stacking** — ErrorReportNotification: z-[10000] bottom-right. OnboardingOverlay: z-[9999]. LocalAIDownloadSnackbar: z-[9998] bottom-left.
44+
- **React Compiler lint** — `useCallback` deps must match the full inferred closure. Using `user?._id` as dep when the closure captures `user` triggers `preserve-manual-memoization`. Use `user` as the dep instead.
45+
- **`setState` in effects** — ESLint `react-hooks/set-state-in-effect` catches synchronous setState in useEffect bodies. Use lazy initializers, compute at render, or event handlers instead.
46+
47+
## Environment
48+
49+
- **Core sidecar port** — `7788` (default). Check with `lsof -i :7788`.
50+
- **Stage sidecar** — `cd app && yarn core:stage` (required for core RPC).
51+
- **Kill stuck processes** — `lsof -i :7788` then `kill <PID>`.

‎.env.example‎

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Root environment variables — Rust core, Tauri shell, and shared settings.
2+
# Copy to .env and fill in values as needed.
3+
# Loaded via: source scripts/load-dotenv.sh
4+
#
5+
# Tags: [required] must be set, [optional] has a sensible default or can be blank
6+
7+
# ---------------------------------------------------------------------------
8+
# Backend API
9+
# ---------------------------------------------------------------------------
10+
# [required] Primary backend URL (read by Rust core and QuickJS skills sandbox)
11+
BACKEND_URL=https://staging-api.alphahuman.xyz
12+
# [required] Also read by Vite frontend (VITE_ prefix required for browser exposure)
13+
VITE_BACKEND_URL=https://staging-api.alphahuman.xyz
14+
15+
# ---------------------------------------------------------------------------
16+
# Core process
17+
# ---------------------------------------------------------------------------
18+
# [optional] Default: 7788
19+
OPENHUMAN_CORE_PORT=7788
20+
# [optional] Default: http://127.0.0.1:7788/rpc
21+
OPENHUMAN_CORE_RPC_URL=http://127.0.0.1:7788/rpc
22+
# [optional] Run mode: child (default, spawns sidecar) | inprocess
23+
OPENHUMAN_CORE_RUN_MODE=child
24+
# [optional] Override path to openhuman core binary (leave blank for auto-detection)
25+
OPENHUMAN_CORE_BIN=
26+
27+
# ---------------------------------------------------------------------------
28+
# Config overrides (override config.toml values at runtime)
29+
# ---------------------------------------------------------------------------
30+
# [required] API key for the LLM provider
31+
OPENHUMAN_API_KEY=
32+
# [optional] Default model to use
33+
OPENHUMAN_MODEL=
34+
# [optional] Workspace directory (default: ~/.openhuman)
35+
OPENHUMAN_WORKSPACE=
36+
# [optional] Default: 0.7
37+
OPENHUMAN_TEMPERATURE=0.7
38+
39+
# ---------------------------------------------------------------------------
40+
# Runtime flags
41+
# ---------------------------------------------------------------------------
42+
# [optional] Default: 0
43+
OPENHUMAN_BROWSER_ALLOW_ALL=0
44+
# [optional] Default: 0
45+
OPENHUMAN_LOG_PROMPTS=0
46+
# [optional] Enable reasoning mode
47+
OPENHUMAN_REASONING_ENABLED=
48+
49+
# ---------------------------------------------------------------------------
50+
# Web search
51+
# ---------------------------------------------------------------------------
52+
# [optional] Default: false
53+
OPENHUMAN_WEB_SEARCH_ENABLED=false
54+
# [optional] Search provider name
55+
OPENHUMAN_WEB_SEARCH_PROVIDER=
56+
# [optional] Required if web search provider is Brave
57+
OPENHUMAN_BRAVE_API_KEY=
58+
# [optional] Default: 5
59+
OPENHUMAN_WEB_SEARCH_MAX_RESULTS=5
60+
# [optional] Default: 10
61+
OPENHUMAN_WEB_SEARCH_TIMEOUT_SECS=10
62+
63+
# ---------------------------------------------------------------------------
64+
# Storage
65+
# ---------------------------------------------------------------------------
66+
# [optional] Storage backend (default: SQLite)
67+
OPENHUMAN_STORAGE_PROVIDER=
68+
# [optional] Database connection URL
69+
OPENHUMAN_STORAGE_DB_URL=
70+
# [optional] Connection timeout in seconds
71+
OPENHUMAN_STORAGE_CONNECT_TIMEOUT_SECS=
72+
73+
# ---------------------------------------------------------------------------
74+
# Proxy
75+
# ---------------------------------------------------------------------------
76+
# [optional] Default: false
77+
OPENHUMAN_PROXY_ENABLED=false
78+
# [optional] HTTP proxy URL
79+
OPENHUMAN_HTTP_PROXY=
80+
# [optional] HTTPS proxy URL
81+
OPENHUMAN_HTTPS_PROXY=
82+
# [optional] Catch-all proxy URL
83+
OPENHUMAN_ALL_PROXY=
84+
# [optional] Comma-separated hosts to bypass proxy
85+
OPENHUMAN_NO_PROXY=
86+
# [optional] Proxy scope
87+
OPENHUMAN_PROXY_SCOPE=
88+
# [optional] Comma-separated services to proxy
89+
OPENHUMAN_PROXY_SERVICES=
90+
91+
# ---------------------------------------------------------------------------
92+
# Local AI model tier
93+
# ---------------------------------------------------------------------------
94+
# [optional] Override selected model tier: low, medium, high
95+
# Applies the corresponding preset at config load time (overrides config.toml).
96+
OPENHUMAN_LOCAL_AI_TIER=
97+
98+
# ---------------------------------------------------------------------------
99+
# Local AI binary overrides
100+
# ---------------------------------------------------------------------------
101+
# [optional] Override path to whisper binary
102+
WHISPER_BIN=
103+
# [optional] Override path to piper binary
104+
PIPER_BIN=
105+
# [optional] Override path to ollama binary
106+
OLLAMA_BIN=
107+
108+
# ---------------------------------------------------------------------------
109+
# Skills
110+
# ---------------------------------------------------------------------------
111+
# [optional] Override skills registry URL
112+
SKILLS_REGISTRY_URL=
113+
114+
# ---------------------------------------------------------------------------
115+
# Error Reporting (Sentry)
116+
# ---------------------------------------------------------------------------
117+
# [optional] Sentry DSN for Rust core error reporting (no PII is sent)
118+
OPENHUMAN_SENTRY_DSN=
119+
# [optional] Default: true — set to false to disable anonymized analytics & crash reports
120+
OPENHUMAN_ANALYTICS_ENABLED=true
121+
122+
# ---------------------------------------------------------------------------
123+
# Logging
124+
# ---------------------------------------------------------------------------
125+
# [optional] Default: info
126+
RUST_LOG=info
127+
# [optional] Default: 0 (set to 1 for full backtraces)
128+
RUST_BACKTRACE=1
129+
130+
# ---------------------------------------------------------------------------
131+
# Testing (do not set in production)
132+
# ---------------------------------------------------------------------------
133+
# [optional] Enable mock service mode
134+
# OPENHUMAN_SERVICE_MOCK=0
135+
# [optional] Path to mock state file
136+
# OPENHUMAN_SERVICE_MOCK_STATE_FILE=
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Installer Smoke
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
smoke-unix:
13+
name: Smoke install.sh (${{ matrix.os }})
14+
runs-on: ${{ matrix.os }}
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
os: [ubuntu-22.04, macos-latest]
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name: Run installer dry-run
24+
run: bash scripts/install.sh --dry-run --verbose
25+
26+
# smoke-windows:
27+
# name: Smoke install.ps1 (windows-latest)
28+
# runs-on: windows-latest
29+
# steps:
30+
# - name: Checkout
31+
# uses: actions/checkout@v4
32+
33+
# - name: Run installer dry-run
34+
# shell: pwsh
35+
# run: ./scripts/install.ps1 -DryRun

0 commit comments

Comments
 (0)