From bc371bdea286caf35431d6456d45d60d1da26658 Mon Sep 17 00:00:00 2001 From: YellowSnnowmann <167776381+YellowSnnowmann@users.noreply.github.com> Date: Sat, 16 May 2026 03:32:02 +0530 Subject: [PATCH] docs: align Claude/Codex context with current main (#1789) --- .claude/memory.md | 18 ++++++-- .claude/rules/README.md | 10 ++-- AGENTS.md | 100 +++++++++++++++++++++------------------- CLAUDE.md | 74 ++++++++++++++++------------- CODEX_WORKPAD.md | 4 ++ 5 files changed, 117 insertions(+), 89 deletions(-) diff --git a/.claude/memory.md b/.claude/memory.md index b79d035cc..f6a0f5672 100644 --- a/.claude/memory.md +++ b/.claude/memory.md @@ -26,14 +26,21 @@ Quick reference for anyone starting with Claude on this project. Updated by the - **Ask user when in doubt** — never assume scope or approach - **PRs target upstream** — `tinyhumansai/openhuman` main branch, not fork -## Local AI Presets & Daemon Gotcha +## Local AI Presets - **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. - **Device detection** uses `sysinfo` crate (`src/openhuman/local_ai/device.rs`). Apple Silicon = GPU always; others = best-effort. - **`OPENHUMAN_LOCAL_AI_TIER` env var** overrides the selected tier at config load time (in `load.rs`). - **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`. - **Default config maps to Medium tier** (`gemma3:4b-it-qat`). If someone changes `model_ids.rs` defaults, they should keep `presets.rs` in sync. -- **Daemon binary gotcha** — A daemon process (`openhuman-aarch64-apple-darwin run`) auto-starts on port 7788 and respawns on kill. `pnpm 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. + +## Core process (in-process, no sidecar) + +- **Core runs in-process** as a tokio task inside the Tauri host (sidecar removed in PR #1061). Lifecycle owned by `core_process::CoreProcessHandle` in `app/src-tauri/src/core_process.rs`. +- **`pnpm core:stage` is a no-op echo** — there is no `target/debug/openhuman-core` binary to copy into `app/src-tauri/binaries/`. Rebuilding via `pnpm dev:app` is enough to pick up new RPC methods in the in-process server. +- **Token auth**: per-launch hex bearer in `OPENHUMAN_CORE_TOKEN`, exposed to the renderer via `core_rpc_token` Tauri command. Always call RPC through `invoke('core_rpc_relay', { request: { method, params } })` — avoids the CORS preflight `fetch()` would trigger. +- **Stale-listener policy** (#1130): if the port is already in use, the handle probes `GET /` to decide if it's an OpenHuman core, then term/force-kill with PID revalidation guarding against PID reuse. Set `OPENHUMAN_CORE_REUSE_EXISTING=1` to attach to a manually-started `openhuman-core serve` for debugging. +- **Default port** `7788`. Stage token (when running standalone): `~/.openhuman-staging/core.token` under `OPENHUMAN_APP_ENV=staging`. ## Onboarding System @@ -177,6 +184,7 @@ Quick reference for anyone starting with Claude on this project. Updated by the ## Environment -- **Core sidecar port** — `7788` (default). Check with `lsof -i :7788`. -- **Stage sidecar** — `cd app && pnpm core:stage` (required for core RPC). -- **Kill stuck processes** — `lsof -i :7788` then `kill `. +- **Core port** — `7788` (default; in-process inside Tauri host). Check with `lsof -i :7788`. +- **`pnpm core:stage`** — no-op (sidecar removed in PR #1061). Use `pnpm dev:app` for full Tauri+core dev. +- **Kill stuck processes** — `lsof -i :7788` then `kill `. Useful when `dev:app` reports a stale listener and you want to force a fresh boot rather than relying on the handle's auto-recovery. +- **Skills runtime removed** — the QuickJS / `rquickjs` runtime is gone; `src/openhuman/skills/` is metadata-only ("Legacy skill metadata helpers retained after QuickJS runtime removal"). Skill execution surfaces are being rebuilt; don't assume a `.skill` can run end-to-end without checking the current code. diff --git a/.claude/rules/README.md b/.claude/rules/README.md index e77c57774..2cd2356e8 100644 --- a/.claude/rules/README.md +++ b/.claude/rules/README.md @@ -6,11 +6,15 @@ Authoritative docs for AI agents and contributors: - **[`CLAUDE.md`](../../CLAUDE.md)** — repo layout, runtime scope, commands, frontend/Tauri/Rust conventions, testing, debug logging, feature workflow. - **[`AGENTS.md`](../../AGENTS.md)** — RPC controller patterns, `RpcOutcome` contract. +- **[`.claude/memory.md`](../memory.md)** — project memory: fixes, gotchas, strict rules, workflow notes. - **[`gitbooks/developing/architecture.md`](../../gitbooks/developing/architecture.md)** — narrative architecture, dual-socket sync. -- **[`gitbooks/resources/design-language.md`](../../gitbooks/resources/design-language.md)** — visual language. +- **[`gitbooks/developing/architecture/frontend.md`](../../gitbooks/developing/architecture/frontend.md)** — frontend layout. +- **[`gitbooks/developing/architecture/tauri-shell.md`](../../gitbooks/developing/architecture/tauri-shell.md)** — Tauri shell. +- **[`gitbooks/developing/architecture/agent-harness.md`](../../gitbooks/developing/architecture/agent-harness.md)** — agent harness / tool surface. - **[`gitbooks/developing/e2e-testing.md`](../../gitbooks/developing/e2e-testing.md)** — WDIO/Appium testing. -- **[`gitbooks/developing/frontend.md`](../../gitbooks/developing/frontend.md)** — frontend. -- **[`gitbooks/developing/tauri-shell.md`](../../gitbooks/developing/tauri-shell.md)** — Tauri shell. +- **[`gitbooks/developing/cef.md`](../../gitbooks/developing/cef.md)** — CEF runtime notes. +- **[`gitbooks/developing/testing-strategy.md`](../../gitbooks/developing/testing-strategy.md)** — testing strategy. +- **[`gitbooks/developing/agent-observability.md`](../../gitbooks/developing/agent-observability.md)** — agent observability. ## When to add a file here diff --git a/AGENTS.md b/AGENTS.md index 468ce8137..71af2296f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # OpenHuman -**AI-powered assistant for communities — React + Tauri v2 desktop app with a Rust core (JSON-RPC / CLI) and sandboxed QuickJS skills.** +**AI assistant for communities — React + Tauri v2 desktop app with a Rust core (JSON-RPC / CLI) embedded in-process.** This file orients contributors and coding agents. Authoritative narrative architecture: [`gitbooks/developing/architecture.md`](gitbooks/developing/architecture.md). Frontend layout: [`gitbooks/developing/architecture/frontend.md`](gitbooks/developing/architecture/frontend.md). Tauri shell: [`gitbooks/developing/architecture/tauri-shell.md`](gitbooks/developing/architecture/tauri-shell.md). @@ -10,57 +10,54 @@ This file orients contributors and coding agents. Authoritative narrative archit | Path | Role | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`app/`** | Yarn workspace **`openhuman-app`**: Vite + React (`app/src/`), Tauri desktop host (`app/src-tauri/`), Vitest tests | -| **Repo root `src/`** | Rust library **`openhuman_core`** and **`openhuman-core`** CLI binary entrypoint (`src/main.rs`) — `core_server`, `openhuman::*` domains, skills runtime (QuickJS / `rquickjs`), MCP routing in the core process | -| **Skills registry** | **[`tinyhumansai/openhuman-skills`](https://github.com/tinyhumansai/openhuman-skills)** on GitHub — canonical skill packages and TS build; not vendored in this tree (see blurb below). | -| **`Cargo.toml`** (root) | Core crate; `cargo build --bin openhuman-core` produces the sidecar the UI stages via `app`’s `core:stage` | +| **`app/`** | pnpm workspace **`openhuman-app`** (v0.53.45): Vite + React (`app/src/`), Tauri desktop host (`app/src-tauri/`), Vitest tests | +| **Repo root `src/`** | Rust library crate **`openhuman`** (lib name) with **`openhuman-core`** CLI binary entrypoint (`src/main.rs`) — `src/core/` (transport: HTTP/JSON-RPC, CLI, dispatch, auth, event bus), `src/openhuman/*` domains. The QuickJS skills runtime has been removed; `src/openhuman/skills/` is metadata-only now. | +| **Skills registry** | **[`tinyhumansai/openhuman-skills`](https://github.com/tinyhumansai/openhuman-skills)** on GitHub — canonical skill packages and TS build; not vendored in this tree. | +| **`Cargo.toml`** (root) | Core crate; `cargo build --bin openhuman-core` produces the CLI binary. Helper binaries: `slack-backfill`, `gmail-backfill-3d` in `src/bin/`. | | **`docs/`** | Architecture and deep-internal references | -| **`gitbooks/developing/`** | Public contributor docs — frontend, Tauri shell, testing, release, skills | +| **`gitbooks/developing/`** | Public contributor docs — frontend, Tauri shell, testing, release, agent harness, CEF, observability | -Commands in documentation assume the **repo root** unless noted: `pnpm dev` runs the `app` workspace. +Commands in documentation assume the **repo root** unless noted: `pnpm dev` runs Vite-only inside the `app` workspace; `pnpm dev:app` runs the full Tauri desktop dev (CEF runtime). -**Skills registry:** Skill sources and the bundler live in **[github.com/tinyhumansai/openhuman-skills](https://github.com/tinyhumansai/openhuman-skills)**. Clone that repository to author or change skills (`pnpm install`, `pnpm build`). The desktop app’s skills catalog defaults to that GitHub slug; override with `VITE_SKILLS_GITHUB_REPO` (see [`app/src/utils/config.ts`](app/src/utils/config.ts)). +**Skills registry:** Skill sources and the bundler live in **[github.com/tinyhumansai/openhuman-skills](https://github.com/tinyhumansai/openhuman-skills)**. The desktop app's skills catalog defaults to that GitHub slug; override with `VITE_SKILLS_GITHUB_REPO` (see [`app/src/utils/config.ts`](app/src/utils/config.ts)). Note: since the QuickJS runtime was removed, the desktop app no longer *executes* skill packages — it only discovers, installs metadata, and renders catalog entries. Skill execution surfaces are being rebuilt; check the current domain modules before assuming a skill can run end-to-end. --- ## Runtime scope -- **Shipped product**: desktop — Windows, macOS, Linux (see [`gitbooks/developing/architecture.md`](gitbooks/developing/architecture.md) “Platform reach”). -- **Tauri host** (`app/src-tauri`): **desktop-only** (`compile_error!` for non-desktop targets). Do not add Android/iOS branches inside `app/src-tauri`. -- **Core binary** (`openhuman-core`): spawned/staged as a **sidecar**; the Web UI talks to it over HTTP (`core_rpc_relay` + `core_rpc` client), not by re-implementing domain logic in the shell. +- **Shipped product**: desktop — Windows, macOS, Linux (see [`gitbooks/developing/architecture.md`](gitbooks/developing/architecture.md) "Platform reach"). +- **Tauri host** (`app/src-tauri`): **desktop-only**. Do not add Android/iOS branches. +- **Core runs in-process** as a tokio task inside the Tauri host (sidecar removed in PR #1061). The host owns its lifetime via `core_process::CoreProcessHandle` in `app/src-tauri/src/core_process.rs`. Frontend RPC still goes over HTTP to `http://127.0.0.1:/rpc` authenticated with a per-launch hex bearer in `OPENHUMAN_CORE_TOKEN`; the Tauri command `core_rpc_token` exposes it to the renderer. Set `OPENHUMAN_CORE_REUSE_EXISTING=1` to attach to an externally-started `openhuman-core` process for debugging. **Where logic lives** -- **Rust (`openhuman` / repo root `src/`)**: **Business logic and execution**—domains, skills runtime, RPC, persistence, and CLI behavior. This is the authoritative place for rules and side effects. -- **Tauri + React (`app/`)**: **Interaction and UX**—screens, navigation, input, accessibility, windowing, and bridging to the core. The shell presents and orchestrates; it does not duplicate core business rules. +- **Rust (`openhuman` / repo root `src/`)**: **Business logic and execution**—domains, RPC, persistence, CLI behavior. Authoritative. +- **Tauri + React (`app/`)**: **Interaction and UX**—screens, navigation, input, accessibility, windowing, and bridging to the in-process core. The shell presents and orchestrates; it does not duplicate core business rules. --- ## Commands (from repository root) ```bash -# Frontend + Tauri dev (workspace delegates to app/) +# Vite dev only (no Tauri host) pnpm dev -# Desktop with Tauri (loads env via scripts/load-dotenv.sh) -pnpm tauri dev +# Full desktop with Tauri/CEF (loads env via scripts/load-dotenv.sh) +pnpm dev:app # Production UI build (app workspace) pnpm build -# Typecheck / lint / format (app workspace) -pnpm typecheck +# Typecheck / lint / format +pnpm typecheck # alias for `pnpm compile` (tsc --noEmit) pnpm lint -pnpm format +pnpm format # Prettier + cargo fmt pnpm format:check -# Stage openhuman core binary next to Tauri resources (required for core RPC) -cd app && pnpm core:stage +# `pnpm core:stage` is a no-op — sidecar removed in PR #1061; core is in-process. -# Skills — develop in the GitHub registry repo, then build (see tinyhumansai/openhuman-skills). -# If you keep a local clone path wired in app scripts, you can also run: -pnpm workspace openhuman-app skills:build -pnpm workspace openhuman-app skills:watch +# Skills — author / build in the registry repo (tinyhumansai/openhuman-skills). +# There are no `skills:build` / `skills:watch` scripts in this repo's app workspace. # Rust — core library + CLI (repo root) cargo check --manifest-path Cargo.toml @@ -68,11 +65,16 @@ cargo build --manifest-path Cargo.toml --bin openhuman-core # Rust — Tauri shell only cargo check --manifest-path app/src-tauri/Cargo.toml +pnpm rust:check # same as above + +# whisper-rs / llama.cpp on macOS Tahoe (Apple Silicon) fail with `-mcpu=native`. +# Workaround for `cargo check`/`cargo test`: +GGML_NATIVE=OFF cargo check --manifest-path Cargo.toml ``` -**Tests**: Vitest in `app/` (`pnpm test`, `pnpm test:coverage`). Rust tests via `cargo test` at repo root as wired in `app/package.json`. +**Tests**: Vitest in `app/` (`pnpm test`, `pnpm test:coverage`); Rust via `pnpm test:rust` (runs `scripts/test-rust-with-mock.sh`). -**Quality**: ESLint + Prettier + Husky in the `app` workspace. +**Quality**: ESLint + Prettier + Husky in the `app` workspace. Pre-push hook runs `pnpm rust:check`. Use `--no-verify` only for unrelated pre-existing breakage and call it out in the PR body. ### Codex web / Linear-launched PR checklist @@ -262,25 +264,25 @@ run_case() { Order matters for auth and realtime: -`Redux Provider` → `PersistGate` → **`UserProvider`** → **`SocketProvider`** → **`AIProvider`** → **`SkillProvider`** → **`HashRouter`** → `AppRoutes`. +`Sentry.ErrorBoundary` → `Redux Provider` → `PersistGate` (with `PersistRehydrationScreen`) → `BootCheckGate` → **`CoreStateProvider`** → **`SocketProvider`** → **`ChatRuntimeProvider`** → `HashRouter` → `CommandProvider` → `ServiceBlockingGate` → `AppShell` (`AppRoutes` + `BottomTabBar` + `AppWalkthrough` + `MascotFrameProducer`). -There is **no** `TelegramProvider` in the current tree; Telegram may appear in UI copy or legacy settings, but MTProto is not an active provider here. +`CoreStateProvider` owns auth: session tokens are NOT in redux-persist; they live in the in-process core and are fetched via `fetchCoreAppSnapshot()` RPC. There is no `UserProvider`, `AIProvider`, `SkillProvider`, or `TelegramProvider`. ### State (`app/src/store/`) -Redux Toolkit slices include **auth**, **user**, **socket**, **ai**, **skills**, **team**, and related modules. Prefer Redux (and persist where configured) over ad hoc `localStorage` for app state; see project rules for exceptions. +Redux Toolkit slices: `accounts`, `channelConnections`, `chatRuntime`, `coreMode`, `deepLinkAuth`, `mascot`, `notification`, `providerSurface`, `socket` (+ `socketSelectors`), `thread`. Plus `userScopedStorage` for per-user persistence keys. Prefer Redux (and redux-persist where configured) over ad hoc `localStorage` for app state. Documented exception: ephemeral UI state like upsell-banner dismiss flags use `localStorage` with the `openhuman:upsell:` prefix. ### Services (`app/src/services/`) -Singleton-style modules include **`apiClient`**, **`socketService`**, **`coreRpcClient`** (HTTP bridge to the core process), and domain **`api/*`** clients. There is **no** `mtprotoService` in this tree. +Singleton-style modules: `apiClient`, `socketService`, `coreRpcClient`, `coreCommandClient`, `chatService`, `analytics`, `notificationService`, `webviewAccountService`, `daemonHealthService`, `meetCallService`, `memorySyncService`, `bootCheckService`, `walletApi`, plus domain `api/*` clients. Always call the in-process core via `invoke('core_rpc_relay', ...)` — never raw `fetch()` (CORS preflight) or `callCoreRpc()` for service-status calls (socket may not be connected yet). ### MCP (`app/src/lib/mcp/`) -Transport, validation, and types for JSON-RPC-style messaging over Socket.io — **not** a large Telegram tool pack. Tooling for agents is driven by the **skills** system and backend; see `agentToolRegistry.ts` and core RPC. +Transport, validation, and types for JSON-RPC-style messaging over Socket.io. Tooling for agents is driven by the **skills** catalog metadata + backend tool registry; see `agentToolRegistry.ts` and core RPC. (Skill execution itself moved out-of-process when the QuickJS runtime was removed.) -### Routing (`app/src/AppRoutes.tsx`) +### Routing (`app/src/AppRoutes.tsx`, HashRouter) -Hash routes include `/`, `/onboarding`, `/mnemonic`, `/home`, `/intelligence`, `/skills`, `/conversations`, `/invites`, `/agents`, `/settings/*`, plus `DefaultRedirect`. **No** dedicated `/login` route in `AppRoutes` (auth flows use the welcome/onboarding paths). +`/` (Welcome, public), `/onboarding/*`, `/home`, `/human`, `/intelligence`, `/skills`, `/chat` (unified agent + connected web apps — replaces the old `/conversations` and `/accounts` routes), `/channels`, `/invites`, `/notifications`, `/rewards`, `/webhooks` → redirect to `/settings/webhooks-triggers`, `/settings/*`. Default `*` → `DefaultRedirect`. There is **no** `/login`, **no** `/mnemonic` (Recovery Phrase moved to Settings panel), **no** `/agents`, **no** `/conversations`. ### AI configuration @@ -290,9 +292,11 @@ Bundled prompts live under **`src/openhuman/agent/prompts/`** at the **repositor ## Tauri shell (`app/src-tauri/`) -Thin desktop host: window management, daemon health bridging, **core process lifecycle** (`core_process`, `CoreProcessHandle`), and **JSON-RPC relay** to the **`openhuman-core`** sidecar (`core_rpc_relay`, `core_rpc`). +Thin desktop host. Top-level modules: `core_process`, `core_rpc`, `cdp`, `cef_preflight`, `cef_profile`, `dictation_hotkeys`, `file_logging`, `mascot_native_window`, `native_notifications`, `notification_settings`, `process_kill`, `process_recovery`, `screen_capture`, `window_state`, plus per-provider scanners (`discord_scanner`, `gmessages_scanner`, `imessage_scanner`, `meet_scanner`, `slack_scanner`, `telegram_scanner`, `whatsapp_scanner`), `meet_audio` / `meet_call` / `meet_video`, `fake_camera`, `webview_accounts`, `webview_apis`. -Registered IPC commands (see [`gitbooks/developing/architecture/tauri-shell.md`](gitbooks/developing/architecture/tauri-shell.md)) include **`greet`**, **`write_ai_config_file`**, **`ai_get_config`**, **`ai_refresh_config`**, **`core_rpc_relay`**, **window** commands, and **OpenHuman service / daemon host** helpers (`openhuman_*`). +**Core lifecycle**: `core_process::CoreProcessHandle` spawns the in-process JSON-RPC server and authenticates inbound RPC with a hex bearer (`OPENHUMAN_CORE_TOKEN`). Stale-listener policy (#1130): on conflict the handle probes `GET /`, decides if the listener is an OpenHuman core, then `kill_pid_term` → `kill_pid_force` with PID revalidation guarding against PID reuse. `restart_core_process` / `start_core_process` Tauri commands let the frontend cycle it for updates. + +Registered IPC commands (see [`gitbooks/developing/architecture/tauri-shell.md`](gitbooks/developing/architecture/tauri-shell.md)) include `greet`, `write_ai_config_file`, `ai_get_config`, `ai_refresh_config`, `core_rpc_relay`, `core_rpc_token`, `start_core_process`, `restart_core_process`, window commands, and `openhuman_*` daemon helpers. Deep link plugin is registered where supported; behavior is platform-specific (see platform notes below). @@ -300,16 +304,16 @@ Deep link plugin is registered where supported; behavior is platform-specific (s ## Rust core (repo root `src/`) -- **`openhuman/`** — Domain logic (skills, memory, channels, config, …). RPC controllers live in **`rpc.rs`** files per domain; use **`RpcOutcome`** pattern per [`AGENTS.md`](AGENTS.md) / internal rules. -- **`src/openhuman/` module layout**: **New** functionality must live in a **dedicated subdirectory** (its own folder/module, e.g. `openhuman/my_domain/mod.rs` plus related files, or a new subfolder under an existing domain). Do **not** add new standalone `*.rs` files directly at `src/openhuman/` root; place new code in a module directory and declare it from `mod.rs` (or merge into an existing domain folder). -- **Controller schema contract**: Shared controller metadata types live in **`src/core/mod.rs`** (`ControllerSchema`, `FieldSchema`, `TypeSchema`) and are consumed by adapters (RPC/CLI) in different ways. -- **Domain schema files**: For each domain, define controller schema metadata in a dedicated module inside the domain folder (example: **`src/openhuman/cron/schemas.rs`**) and export from the domain `mod.rs`. -- **Controller-only exposure rule**: Expose domain functionality to **CLI and JSON-RPC through the controller registry** (`schemas.rs` + registered handlers). Do **not** add domain-specific branches or one-off transport logic in `src/core/cli.rs` or `src/core/jsonrpc.rs` just to expose a feature. -- **Light `mod.rs` rule**: Keep domain `mod.rs` files light and export-focused. Put operational code in sibling files (example: `ops.rs`, `store.rs`, `schedule.rs`, `types.rs`), then re-export the public API from `mod.rs`. -- **`core_server/`** — Transport only: Axum/HTTP, JSON-RPC envelope, CLI parsing, **dispatch** (`core_server::dispatch`) — **no** heavy business logic here. -- **Layering**: Implementation in `openhuman::/`, controllers in `openhuman::/rpc.rs`, routes in `core_server/`. +- **`src/openhuman/`** — Domain logic. Current domains: `about_app`, `accessibility`, `agent`, `app_state`, `approval`, `autocomplete`, `billing`, `channels`, `composio`, `config`, `context`, `cost`, `credentials`, `cron`, `doctor`, `embeddings`, `encryption`, `health`, `heartbeat`, `integrations`, `learning`, `local_ai`, `meet`, `meet_agent`, `memory`, `migration`, `node_runtime`, `notifications`, `overlay`, `people`, `prompt_injection`, `provider_surfaces`, `providers`, `redirect_links`, `referral`, `routing`, `scheduler_gate`, `screen_intelligence`, `security`, `service`, `skills`, `socket`, `subconscious`, `team`, `text_input`, `threads`, `tokenjuice`, `tool_timeout`, `tools`, `tree_summarizer`, `update`, `voice`, `wallet`, `webhooks`, `webview_accounts`, `webview_apis`, `webview_notifications`. RPC controllers in per-domain `rpc.rs`; use **`RpcOutcome`** pattern (see "RPC Controller Pattern" below). +- **`src/openhuman/` module layout**: **New** functionality must live in a **dedicated subdirectory** (e.g. `openhuman/my_domain/mod.rs` plus related files, or a new subfolder under an existing domain). Do **not** add new standalone `*.rs` files directly at `src/openhuman/` root (`dev_paths.rs` and `util.rs` are grandfathered). +- **Controller schema contract**: Shared controller metadata types live in `src/core/types.rs` / `src/core/mod.rs` (`ControllerSchema`, `FieldSchema`, `TypeSchema`) and are consumed by adapters (RPC/CLI). +- **Domain schema files**: For each domain, define controller schema metadata in a dedicated module inside the domain folder (example: `src/openhuman/cron/schemas.rs`) and export from the domain `mod.rs`. +- **Controller-only exposure rule**: Expose domain functionality to **CLI and JSON-RPC through the controller registry** (`schemas.rs` + registered handlers wired into `src/core/all.rs`). Do **not** add domain-specific branches in `src/core/cli.rs` or `src/core/jsonrpc.rs`. +- **Light `mod.rs` rule**: Keep domain `mod.rs` files light and export-focused. Put operational code in sibling files (`ops.rs`, `store.rs`, `schedule.rs`, `types.rs`, `bus.rs`). +- **`src/core/`** — Transport only: Axum/HTTP, JSON-RPC envelope, CLI parsing, **dispatch** (`src/core/dispatch.rs`), auth, observability, event bus. **No** heavy business logic here. (Older docs that say `core_server` mean this directory; there is no `src/core_server/`.) +- **Layering**: Implementation in `openhuman::/`, controllers in `openhuman::/rpc.rs`, routes/dispatch in `src/core/`. -Skills runtime uses **QuickJS** (`rquickjs`) in **`src/openhuman/skills/`** (e.g. `qjs_skill_instance.rs`, `qjs_engine.rs`), not V8/deno_core in this repository. +The previous QuickJS / `rquickjs` skills runtime has been removed. `src/openhuman/skills/` now contains metadata helpers only (`ops_create`, `ops_discover`, `ops_install`, `ops_parse`, `inject`, `schemas`, `types`) — its `mod.rs` and `types.rs` carry the marker comment "Legacy … retained after QuickJS runtime removal." Do not assume the runtime can execute a `.skill` package end-to-end; check what `ops_install` and the current agent tool path actually do before planning a feature that needs it. ### Controller migration checklist @@ -523,12 +527,12 @@ Follow this order so behavior is **specified**, **proven in Rust**, **proven ove ## Platform notes - **macOS deep links**: Often require a built **`.app`** bundle; not only `tauri dev`. -- **`window.__TAURI__`**: Not assumed at module load; guard Tauri usage accordingly. -- **Core sidecar**: Must be staged/built so `core_rpc` can reach the `openhuman-core` binary (see `scripts/stage-core-sidecar.mjs`). +- **`window.__TAURI__`**: Not assumed at module load; use `isTauri()` (from `app/src/services/webviewAccountService.ts`) or wrap `invoke(...)` in `try/catch`. +- **Core is in-process**: `core_rpc` reaches `http://127.0.0.1:/rpc` (default port `7788`) authenticated with `OPENHUMAN_CORE_TOKEN`. `scripts/stage-core-sidecar.mjs` no longer exists; `pnpm core:stage` is a no-op echo (sidecar removed in PR #1061). For standalone debugging: `./target/debug/openhuman-core serve` writes its token to `{workspace}/core.token` (default `~/.openhuman-staging/core.token` under `OPENHUMAN_APP_ENV=staging`); public endpoints `GET /health`, `GET /schema`, `GET /events` need no auth. --- -_Last aligned with monorepo layout (`app/` + root `src/`), QuickJS skills in `openhuman_core`, skills catalog on GitHub (`tinyhumansai/openhuman-skills`), and Tauri shell IPC as of repo state._ +_Last aligned with monorepo layout (`app/` + root `src/`), in-process core (no sidecar), QuickJS removed, skills catalog on GitHub (`tinyhumansai/openhuman-skills`), and Tauri shell IPC as of `openhuman-app` v0.53.45 / repo `main`._ --- diff --git a/CLAUDE.md b/CLAUDE.md index 22730541c..861b9feff 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,20 +10,20 @@ Narrative architecture: [`gitbooks/developing/architecture.md`](gitbooks/develop | Path | Role | | --- | --- | -| **`app/`** | Yarn workspace `openhuman-app`: Vite + React (`app/src/`), Tauri desktop host (`app/src-tauri/`), Vitest tests | -| **`src/`** (root) | Rust lib `openhuman_core` + `openhuman` CLI binary — `core_server`, `openhuman::*` domains, MCP routing | -| **`Cargo.toml`** (root) | Core crate; `cargo build --bin openhuman` produces the sidecar staged by `app`'s `core:stage` | -| **`docs/`** | Remaining deep internals (memory pipeline excalidraws, sentry, telegram-login, etc.). Public contributor docs live in `gitbooks/developing/`. | +| **`app/`** | pnpm workspace `openhuman-app` (v0.53.45): Vite + React (`app/src/`), Tauri desktop host (`app/src-tauri/`), Vitest tests | +| **`src/`** (root) | Rust lib crate `openhuman` + `openhuman-core` CLI binary (`src/main.rs`) — `src/core/` (transport: Axum/HTTP, JSON-RPC, CLI), `src/openhuman/*` domains, event bus | +| **`Cargo.toml`** (root) | Core crate; `cargo build --bin openhuman-core` produces the binary. Also defines `slack-backfill` and `gmail-backfill-3d` helper binaries in `src/bin/`. | +| **`docs/`** | Remaining deep internals (memory pipeline excalidraws, sentry, etc.). Public contributor docs live in `gitbooks/developing/`. | -Commands assume the **repo root**; `pnpm dev` delegates to the `app` workspace. (Repo migrated from yarn to pnpm — `package.json` enforces pnpm via the `packageManager` field.) +Commands assume the **repo root**; `pnpm dev` delegates to the `app` workspace. The root `package.json` is `openhuman-repo` (private) and enforces pnpm via the `packageManager` field. --- ## Runtime scope - **Shipped product**: desktop — Windows, macOS, Linux. -- **Tauri host** (`app/src-tauri`): desktop-only (`compile_error!` for other targets). No Android/iOS branches. -- **Core binary** (`openhuman`): spawned as a **sidecar**; the UI talks to it over HTTP (`core_rpc_relay` + `core_rpc` client), not by duplicating domain logic. +- **Tauri host** (`app/src-tauri`): desktop-only. No Android/iOS branches. +- **Core runs in-process** inside the Tauri host as a tokio task — there is **no sidecar binary anymore** (removed in PR #1061). The lifecycle is owned by `core_process::CoreProcessHandle` in `app/src-tauri/src/core_process.rs`; on Cmd+Q the core dies with the GUI. Frontend RPC still goes over HTTP (`core_rpc_relay` + `core_rpc` client) to `http://127.0.0.1:/rpc`, authenticated with a per-launch bearer in `OPENHUMAN_CORE_TOKEN`. Set `OPENHUMAN_CORE_REUSE_EXISTING=1` to attach to an externally-started `openhuman-core` process (e.g. a debug harness). **Where logic lives** - **Rust core**: business logic, execution, domains, RPC, persistence, CLI. Authoritative. @@ -34,25 +34,28 @@ Commands assume the **repo root**; `pnpm dev` delegates to the `app` workspace. ## Commands (from repo root) ```bash -pnpm dev # Frontend + Tauri dev -pnpm tauri dev # Desktop with Tauri (loads env via scripts/load-dotenv.sh) +pnpm dev # Vite dev server only (app workspace) +pnpm dev:app # Full Tauri desktop dev (CEF runtime, loads env via scripts/load-dotenv.sh) pnpm build # Production UI build -pnpm typecheck # Typecheck (app workspace) -pnpm lint # ESLint -pnpm format # Prettier write -pnpm format:check # Prettier check -cd app && pnpm core:stage # Stage openhuman binary next to Tauri resources +pnpm typecheck # tsc --noEmit (app workspace, aliased to `compile`) +pnpm compile # Same as typecheck +pnpm lint # ESLint --cache +pnpm format # Prettier write + cargo fmt +pnpm format:check # Prettier check + cargo fmt --check # Rust — core library + CLI cargo check --manifest-path Cargo.toml -cargo build --manifest-path Cargo.toml --bin openhuman +cargo build --manifest-path Cargo.toml --bin openhuman-core # Rust — Tauri shell cargo check --manifest-path app/src-tauri/Cargo.toml +pnpm rust:check # Tauri shell check ``` -**Tests**: Vitest in `app/` (`pnpm test:unit`, `pnpm test:coverage`); Rust via `cargo test`. -**Quality**: ESLint + Prettier + Husky in `app`. +Note: `pnpm core:stage` is a no-op (echoes a message). The sidecar was removed in PR #1061; core is linked in-process. + +**Tests**: `pnpm test` (Vitest, app workspace) · `pnpm test:coverage` · `pnpm test:rust` (cargo test via `scripts/test-rust-with-mock.sh`). +**Quality**: ESLint + Prettier + Husky in `app`. Pre-push hook runs `pnpm rust:check` — pass `--no-verify` only for unrelated pre-existing breakage. ### Agent debug runners (`scripts/debug/`) @@ -105,7 +108,7 @@ PRs must meet **≥ 80% coverage on changed lines**. Enforced by [`.github/workf - Co-locate as `*.test.ts` / `*.test.tsx` under `app/src/**`. - Config: `app/test/vitest.config.ts`; setup: `app/src/test/setup.ts`. -- Run: `pnpm test:unit`, `pnpm test:coverage`. +- Run from repo root: `pnpm test` or `pnpm test:coverage`. (Inside `app/`, `pnpm test:unit` is also defined.) - Prefer behavior over implementation. Use helpers in `app/src/test/`. No real network, no time flakes. ### Shared mock backend @@ -131,9 +134,9 @@ docker compose -f e2e/docker-compose.yml run --rm e2e # Linux E2E on macOS Use `element-helpers.ts` (`clickNativeButton`, `waitForWebView`, `clickToggle`) — never raw `XCUIElementType*`. Assert UI outcomes and mock effects. -### Deterministic core-sidecar reset +### Deterministic core reset (E2E) -`app/scripts/e2e-run-spec.sh` creates and cleans a temp `OPENHUMAN_WORKSPACE` by default. `OPENHUMAN_WORKSPACE` redirects core config + storage away from `~/.openhuman`. +`app/scripts/e2e-run-spec.sh` creates and cleans a temp `OPENHUMAN_WORKSPACE` by default. `OPENHUMAN_WORKSPACE` redirects core config + storage away from `~/.openhuman`. Each spec gets a fresh in-process core inside the freshly-built Tauri bundle. ### Rust tests with mock @@ -147,15 +150,17 @@ bash scripts/test-rust-with-mock.sh --test json_rpc_e2e ## Frontend (`app/src/`) **Provider chain** (`App.tsx`): -`Redux` → `PersistGate` → `UserProvider` → `SocketProvider` → `AIProvider` → `SkillProvider` → `HashRouter` → `AppRoutes`. +`Sentry.ErrorBoundary` → `Redux Provider` → `PersistGate` (with `PersistRehydrationScreen`) → `BootCheckGate` → `CoreStateProvider` → `SocketProvider` → `ChatRuntimeProvider` → `HashRouter` → `CommandProvider` → `ServiceBlockingGate` → `AppShell` (`AppRoutes` + `BottomTabBar` + walkthrough/mascot/snackbars). -**State** (`store/`): Redux Toolkit slices — auth, user, socket, ai, skills, team, etc. Prefer Redux (persisted where configured) over ad-hoc `localStorage`. +No `UserProvider` / `AIProvider` / `SkillProvider` — auth and core snapshot live in `CoreStateProvider`, fetched via `fetchCoreAppSnapshot()` RPC (auth tokens are NOT in redux-persist; they live in the in-process core). -**Services** (`services/`): singletons — `apiClient`, `socketService`, `coreRpcClient` (HTTP bridge to core), domain `api/*` clients. +**State** (`store/`): Redux Toolkit slices — `accounts`, `channelConnections`, `chatRuntime`, `coreMode`, `deepLinkAuth`, `mascot`, `notification`, `providerSurface`, `socket`, `thread`. Persisted slices via redux-persist. Prefer Redux over ad-hoc `localStorage` (exception: ephemeral UI state like upsell dismiss flags). -**MCP** (`lib/mcp/`): JSON-RPC transport, validation, types over Socket.io. Tooling is driven by the backend + skills system. +**Services** (`services/`): singletons — `apiClient`, `socketService`, `coreRpcClient` + `coreCommandClient` (HTTP bridge to in-process core via Tauri IPC), `chatService`, `analytics`, `notificationService`, `webviewAccountService`, `daemonHealthService`, plus domain `api/*` clients. -**Routing** (`AppRoutes.tsx`): hash routes `/`, `/onboarding`, `/mnemonic`, `/home`, `/intelligence`, `/skills`, `/conversations`, `/invites`, `/agents`, `/settings/*`. No `/login`. +**MCP** (`lib/mcp/`): JSON-RPC transport, validation, types over Socket.io. + +**Routing** (`AppRoutes.tsx`, HashRouter): `/` (Welcome), `/onboarding/*`, `/home`, `/human`, `/intelligence`, `/skills`, `/chat` (unified agent + connected web apps, replaces old `/conversations` + `/accounts`), `/channels`, `/invites`, `/notifications`, `/rewards`, `/webhooks` (redirects to `/settings/webhooks-triggers`), `/settings/*`. Default catch-all is `DefaultRedirect`. There is no `/login`, no `/mnemonic` (recovery phrase moved to Settings), no `/agents`, no `/conversations`. **AI config**: bundled prompts in `src/openhuman/agent/prompts/` (also bundled via `app/src-tauri/tauri.conf.json` `resources`). Loaders in `app/src/lib/ai/` use `?raw` imports, optional remote fetch, and `ai_get_config` / `ai_refresh_config` in Tauri. @@ -163,9 +168,11 @@ bash scripts/test-rust-with-mock.sh --test json_rpc_e2e ## Tauri shell (`app/src-tauri/`) -Thin desktop host: window management, daemon health, **core process lifecycle** (`core_process`, `CoreProcessHandle`), **JSON-RPC relay** (`core_rpc_relay`, `core_rpc`). +Thin desktop host. Top-level modules: `core_process`, `core_rpc`, `cdp`, `cef_preflight`, `cef_profile`, `dictation_hotkeys`, `file_logging`, `mascot_native_window`, `native_notifications`, `notification_settings`, `process_kill`, `process_recovery`, `screen_capture`, `window_state`, plus the per-provider scanner modules (`discord_scanner`, `gmessages_scanner`, `imessage_scanner`, `meet_scanner`, `slack_scanner`, `telegram_scanner`, `whatsapp_scanner`), `meet_audio` / `meet_call` / `meet_video`, `fake_camera`, `webview_accounts`, `webview_apis`. -Registered IPC (see [`gitbooks/developing/architecture/tauri-shell.md`](gitbooks/developing/architecture/tauri-shell.md)): `greet`, `write_ai_config_file`, `ai_get_config`, `ai_refresh_config`, `core_rpc_relay`, window commands, `openhuman_*` daemon helpers. +**Core lifecycle**: `core_process::CoreProcessHandle` spawns the JSON-RPC server as an in-process tokio task and authenticates inbound RPC with a per-launch hex bearer (`OPENHUMAN_CORE_TOKEN`). On stale-listener detection (#1130) the handle revalidates the PID before force-killing so PID reuse can't kill an unrelated process. `restart_core_process` / `start_core_process` Tauri commands let the frontend cycle it for updates. + +Registered IPC (see [`gitbooks/developing/architecture/tauri-shell.md`](gitbooks/developing/architecture/tauri-shell.md)) includes `greet`, `write_ai_config_file`, `ai_get_config`, `ai_refresh_config`, `core_rpc_relay`, `core_rpc_token`, `start_core_process`, `restart_core_process`, window commands, and `openhuman_*` daemon helpers. Always use `invoke('core_rpc_relay', ...)` for in-process RPC (avoids CORS preflight that `fetch()` would trigger). ### CEF child webviews — no new JS injection @@ -185,19 +192,20 @@ Watch out for Tauri plugins that inject JS by default. `tauri-plugin-opener` shi ## Rust core (`src/`) -- **`openhuman/`** — Domain logic (memory, channels, config, cron, skills, webhooks, …). RPC controllers in per-domain `rpc.rs`; use `RpcOutcome` per [`AGENTS.md`](AGENTS.md). -- **Module layout rule**: new functionality goes in a **dedicated subdirectory** (`openhuman//mod.rs` + siblings). **Do not** add new standalone `*.rs` files at `src/openhuman/` root. -- **Controller schema contract**: shared types in `src/core/mod.rs` (`ControllerSchema`, `FieldSchema`, `TypeSchema`). +- **`src/openhuman/`** — Domain logic. Current domains: `about_app`, `accessibility`, `agent`, `app_state`, `approval`, `autocomplete`, `billing`, `channels`, `composio`, `config`, `context`, `cost`, `credentials`, `cron`, `doctor`, `embeddings`, `encryption`, `health`, `heartbeat`, `integrations`, `learning`, `local_ai`, `meet`, `meet_agent`, `memory`, `migration`, `node_runtime`, `notifications`, `overlay`, `people`, `prompt_injection`, `provider_surfaces`, `providers`, `redirect_links`, `referral`, `routing`, `scheduler_gate`, `screen_intelligence`, `security`, `service`, `skills`, `socket`, `subconscious`, `team`, `text_input`, `threads`, `tokenjuice`, `tool_timeout`, `tools`, `tree_summarizer`, `update`, `voice`, `wallet`, `webhooks`, `webview_accounts`, `webview_apis`, `webview_notifications`. RPC controllers in per-domain `rpc.rs` / `schemas.rs`; use `RpcOutcome` per [`AGENTS.md`](AGENTS.md). +- **Skills runtime removed**: the QuickJS / `rquickjs` runtime that previously executed skill packages is gone. `src/openhuman/skills/` is now a metadata-only domain (`ops_create`, `ops_discover`, `ops_install`, `ops_parse`, `inject`, `schemas`, `types`) — see the module header comment "Legacy skill metadata helpers retained after QuickJS runtime removal." +- **Module layout rule**: new functionality goes in a **dedicated subdirectory** (`openhuman//mod.rs` + siblings). **Do not** add new standalone `*.rs` files at `src/openhuman/` root (`dev_paths.rs` and `util.rs` are grandfathered, not a template). +- **Controller schema contract**: shared types in `src/core/types.rs` / `src/core/mod.rs` (`ControllerSchema`, `FieldSchema`, `TypeSchema`). - **Domain schema files**: per-domain `schemas.rs` (e.g. `src/openhuman/cron/schemas.rs`), exported from domain `mod.rs`. - **Controller-only exposure**: expose features to CLI and JSON-RPC via the controller registry. **Do not** add domain branches in `src/core/cli.rs` / `src/core/jsonrpc.rs`. - **Light `mod.rs`**: keep domain `mod.rs` export-focused. Operational code in `ops.rs`, `store.rs`, `types.rs`, etc. -- **`core_server/`** — Transport only: Axum/HTTP, JSON-RPC envelope, CLI parsing, dispatch. No heavy logic. +- **`src/core/`** — Transport only. Modules: `all`, `all_tests`, `auth`, `autocomplete_cli_adapter`, `cli`, `cli_tests`, `dispatch`, `event_bus/`, `jsonrpc`, `jsonrpc_tests`, `legacy_aliases`, `logging`, `memory_cli`, `observability`, `rpc_log`, `shutdown`, `socketio`, `types`, plus `agent_cli`. No heavy domain logic here. (There is no `src/core_server/` — older docs that reference `core_server` mean `src/core/`.) ### Controller migration checklist - `src/openhuman//mod.rs`: add `mod schemas;`, re-export `all_controller_schemas as all__controller_schemas` and `all_registered_controllers as all__registered_controllers`. - `src/openhuman//schemas.rs` defines `schemas`, `all_controller_schemas`, `all_registered_controllers`, and `handle_*` fns delegating to domain `rpc.rs`. -- Wire exports into `src/core/all.rs`. Remove migrated branches from `src/rpc/dispatch.rs`. +- Wire exports into `src/core/all.rs`. Remove migrated branches from `src/core/dispatch.rs`. ### Event bus (`src/core/event_bus/`) @@ -299,4 +307,4 @@ Specify → prove in Rust → prove over RPC → surface in the UI → test. - **Vendored CEF-aware `tauri-cli`**: runtime is CEF; only the vendored CLI at `app/src-tauri/vendor/tauri-cef/crates/tauri-cli` bundles Chromium into `Contents/Frameworks/`. Stock `@tauri-apps/cli` produces a broken bundle (panic in `cef::library_loader::LibraryLoader::new`). `pnpm dev:app` and all `cargo tauri` scripts call `pnpm tauri:ensure` which runs [`scripts/ensure-tauri-cli.sh`](scripts/ensure-tauri-cli.sh). If overwritten, reinstall with `cargo install --locked --path app/src-tauri/vendor/tauri-cef/crates/tauri-cli`. - **macOS deep links**: often require a built `.app` bundle, not just `tauri dev`. - **Tauri environment guard**: use `isTauri()` (from `app/src/services/webviewAccountService.ts`) or wrap `invoke(...)` in `try/catch`; do not check `window.__TAURI__` directly — it is not present at module load and bypasses the established wrapper contract. -- **Core sidecar**: must be staged so `core_rpc` can reach the `openhuman` binary (see `scripts/stage-core-sidecar.mjs`). +- **Core is in-process** (no sidecar): `core_rpc` reaches the embedded server at `http://127.0.0.1:/rpc` with bearer auth via `OPENHUMAN_CORE_TOKEN`. `scripts/stage-core-sidecar.mjs` no longer exists; `pnpm core:stage` is a no-op echo. To run the core standalone for debugging, use `./target/debug/openhuman-core serve` (token at `{workspace}/core.token`, default `~/.openhuman-staging/core.token` under `OPENHUMAN_APP_ENV=staging`). diff --git a/CODEX_WORKPAD.md b/CODEX_WORKPAD.md index da1eebc01..e1c45595e 100644 --- a/CODEX_WORKPAD.md +++ b/CODEX_WORKPAD.md @@ -1,5 +1,9 @@ # CODEX Workpad +> **Format**: chronological log of Codex/AI-driven sweeps. Entries below are historical — read them as "what happened on this date" rather than as a description of current repo state. For current state see [`CLAUDE.md`](CLAUDE.md), [`AGENTS.md`](AGENTS.md), and [`.claude/memory.md`](.claude/memory.md). +> +> Append new entries at the bottom with a date heading and a short Scope / Validation / Follow-up structure. Do not edit older entries in place. + ## Portfolio Readiness Pass - 2026-05-12 ### Scope