diff --git a/desktop/README.md b/desktop/README.md index ef04af3..1a551a3 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -1,28 +1,85 @@ # openmud Desktop -Desktop app that loads openmud.ai. Built with Electron. +Electron desktop app for openmud. -## Local dev +## Local development + +### Full stack (web API + desktop shell) + +From repository root: -**Full stack (matches production):** ```bash npm run dev ``` -Runs vercel dev + desktop. Desktop loads localhost:3947. Add `OPENAI_API_KEY` to `web/.env`. -**Desktop only** (hits production API): +This runs the local web app and launches desktop pointed at local web (`PORT=3947` in dev scripts). + +### Desktop app only + ```bash -cd desktop && npm start +cd desktop +npm start ``` -## Build .dmg (macOS only) +This launches the desktop shell directly. + +## Build outputs (macOS) + +From `desktop/`: ```bash npm run build:dmg ``` -Output: `dist/mudrag-1.0.0.dmg` +Default artifact location: `desktop/dist/` (for example `openmud-.dmg` and/or zip artifacts, depending on build mode). + +## Local signed + notarized build + +Use when testing signing locally (without GitHub Actions secrets): + +1. Copy `desktop/.env.signing.example` to `desktop/.env.signing`. +2. Fill `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, and `APPLE_TEAM_ID`. +3. Run: + +```bash +cd desktop +npm run build:local +``` + +This uses `scripts/build-signed-local.js` to build, notarize, staple, and verify a zip artifact. + +## Release runbook + +From repository root: + +```bash +npm run release:desktop +``` + +Optional version bump arg: + +```bash +npm run release:desktop patch +npm run release:desktop minor +npm run release:desktop major +``` + +What this does: + +1. Bumps `desktop/package.json` version. +2. Commits the version bump. +3. Creates and pushes tag `desktop-v`. +4. Triggers `.github/workflows/release-desktop.yml`. + +## CI behavior + +`release-desktop.yml` builds on macOS when a `desktop-v*` tag is pushed (or manually via workflow dispatch). + +- If signing secrets are present, CI builds signed `zip` and `dmg`. +- If signing secrets are absent, CI builds unsigned app bundle and zips `openmud.app`. -## CI +## Common pitfalls -GitHub Actions builds the .dmg on release. See `.github/workflows/desktop.yml`. +1. Packaging scripts currently assume Node 20 for deterministic desktop build/test flow (`scripts/build-and-verify.sh` enforces this). +2. Missing Apple signing credentials will produce unsigned output in CI/local. +3. Auto-update checks use `/api/desktop-version`; releases without zip/dmg assets will not be picked up by updater endpoints. diff --git a/docs/API.md b/docs/API.md index bb96c9d..ebe8d49 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,86 +1,147 @@ -# openmud Chat API Contract +# openmud API Notes -The frontend calls `POST /chat` on the Contech API. Backend should support: +This document covers the current serverless API under `web/api`. +It focuses on the routes that drive chat, model access policy, usage limits, desktop updates, and project/chat sync. -## Where to put API keys +## Runtime and config -**Never put API keys in the chat or in the frontend.** They would be exposed in logs, browser dev tools, and chat history. +- Deploy target: Vercel serverless functions in `web/api`. +- Local env template: `web/.env.example`. +- Required for chat: at least one of `OPENAI_API_KEY` or `ANTHROPIC_API_KEY`. +- Required for authenticated usage tracking and dashboards: `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`. -Put keys in your **openmud Vercel project** (the `/api` serverless functions use them): +## Core chat route -1. **Vercel** – Project → Settings → Environment Variables -2. **Local** – Copy `config/env.example` to `.env` (add `.env` to `.gitignore`) +`POST /api/chat` -``` -OPENAI_API_KEY=sk-... -ANTHROPIC_API_KEY=sk-ant-... -``` - -The frontend never sees or sends keys—it only sends the model name. The backend picks the key based on the model. - -## Request body +### Request body ```json { - "messages": [{"role": "user|assistant", "content": "..."}], - "model": "gpt-4o-mini|mud1|claude-3-5-haiku-20241022|...", + "messages": [{ "role": "user|assistant|system", "content": "..." }], + "model": "mud1", "temperature": 0.7, - "max_tokens": 512, - "use_tools": true, - "available_tools": ["build_schedule", "render_proposal_html", "estimate_project_cost", ...] + "max_tokens": 1024, + "use_tools": false, + "estimate_context": null, + "stream": false, + "project_id": "optional-project-id" } ``` -## Model routing +### Provider override headers (BYOK) -- **mud1** – openmud custom model (in development) -- **gpt-*** – OpenAI API (OPENAI_API_KEY) -- **claude-*** – Anthropic API (ANTHROPIC_API_KEY) +- `X-OpenAI-Api-Key` +- `X-Anthropic-Api-Key` +- `X-Grok-Api-Key` +- `X-OpenRouter-Api-Key` +- `X-OpenClaw-Api-Key` +- `X-OpenClaw-Base-Url` +- `X-OpenClaw-Model` +- `X-Openmud-Relay-Token` +- `X-Client-Date` (calendar intent timezone helper) -## Tool calling +### Auth and model policy -When `use_tools: true`, OpenAI and Anthropic models run tool-calling with: +Policy is enforced in `web/api/chat.js` + `web/api/lib/model-policy.js`: -1. Enable function/tool calling for the selected model -2. Load schemas from `tools/registry.py` through `GET /api/python/registry` -3. Execute estimating tools through `POST /api/python/tools` -4. Return the tool result in the response +1. `mud1` is hosted and free (`hosted_free`). +2. Hosted beta models are platform-hosted with daily caps (`hosted_beta`). +3. Premium/non-hosted models require BYOK (`byok`). +4. Desktop agent model (`openclaw`) is treated as `desktop_agent`. -## Response +Auth behavior: -```json -{ - "response": "Assistant message text", - "tools_used": ["build_schedule", "estimate_project_cost"] -} -``` +1. Hosted requests require authenticated user context. +2. BYOK requests can run without sign-in. +3. Hosted beta requests allocate usage before model execution. -## Python tool executor +### Response shape -`POST /api/python/tools` +Base response: ```json { - "tool_name": "calculate_labor_cost", - "arguments": { - "labor_type": "operator", - "hours": 40, - "region": "utah" - } + "response": "Assistant text", + "tools_used": [] } ``` -## Tool registry endpoint +Optional fields returned for specific flows: + +- `rag`: mud1 retrieval metadata (`confidence`, `fallback_used`, `sources`). +- `_proposal_html`: proposal/document generation HTML payload. +- `_choices`: disambiguation choices (for relay contact ambiguity). + +### Important behavior + +- `mud1` path runs RAG with optional project context merge. +- `stream=true` is only supported when `use_tools=false`. +- Relay token path can execute email/calendar/iMessage workflows through local agent relay. +- Usage events are logged when user context is present. + +## Related platform routes + +### `GET /api/platform` + +Returns public platform policy and model catalog: + +- `default_model` +- `tier_limits` +- policy notes (`mud1 free`, hosted beta limits, BYOK support) +- `models` with `access` classification + +### `GET|POST /api/usage` + +- `GET`: current daily usage (`used`, `limit`, `tier`, `date`) +- `POST`: allocate usage (unless `increment=false`) and optionally log usage event + +### `GET /api/dashboard?days=30` + +Per-user analytics from `usage_events`: + +- totals +- daily breakdown +- by model/source/usage kind +- recent events + +Returns `needs_setup: true` when usage tables are missing. + +## Agentic step route (desktop/tool loop) + +`POST /api/agentic-step` + +- Requires authenticated user. +- Allocates usage using the same limit path as chat. +- Calls Anthropic with a fixed agentic tool set for one step. +- Returns `{ stop_reason, text, tool_calls, content, usage }`. + +## Project and message sync routes + +- `GET|POST|PUT /api/projects` +- `GET|POST|PUT /api/chat-messages` + +Both require authenticated user and Supabase service role access. +Both enforce project ownership (`user_id`) before read/write. + +## Desktop delivery routes + +- `GET /api/desktop-version`: latest desktop version metadata for updater. +- `GET /api/download-desktop`: redirect to latest zip (or dmg fallback). +- `GET /api/download-dmg`: dmg download endpoint (supports proxy streaming with `GITHUB_TOKEN`). -`GET /api/python/registry` +## Setup runbook: usage tables -Returns OpenAI-compatible function schemas from `tools/registry.py`. +If dashboard or usage APIs indicate setup is missing: -## Tool telemetry endpoint +1. Open Supabase SQL editor for the project. +2. Run `web/api/lib/migrations/003_combined_setup.sql`. +3. Re-test `GET /api/dashboard`. -`GET /api/tool-metrics` +## Common pitfalls -Returns in-memory metrics for: -- tool success/error rate -- fallback rate when tools were enabled -- tool latency and recent errors +1. `401` on `/api/chat`: hosted request without auth session. +2. `403` on `/api/chat`: model requires BYOK key, but no provider key header was supplied. +3. `429` on `/api/chat`: hosted beta daily cap reached. +4. `needs_setup: true` on dashboard: usage migrations not applied. +5. Relay automation failures with `openclaw`: missing/invalid `X-Openmud-Relay-Token` or no connected Mac agent. diff --git a/scripts/README.md b/scripts/README.md index 8ad7cca..68dbf80 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,9 +1,31 @@ # Scripts -Build and utility scripts for the openmud project. +Build, release, and maintenance scripts used from the repository root. -| Script | Purpose | -|--------|---------| -| `release-desktop.js` | Bump version, commit, tag, push → triggers GitHub Actions to build .dmg. Run via `npm run release:desktop` | -| `make_favicon.py` | Generate favicon assets for the web app | -| `make_logo_transparent.py` | Process logo for transparency | +## Common developer flows + +| Command | What it runs | Purpose | +|---|---|---| +| `npm run dev` | `scripts/dev-wrapper.sh` | Start local web + desktop dev workflow. | +| `npm run dev:test` | `scripts/dev-and-test.sh` | Start dev environment and run validation checks. | +| `npm run build:test` | `scripts/build-and-verify.sh` | Build unsigned desktop app bundle, zip, and verify archive integrity. | +| `npm run release:desktop` | `scripts/release-desktop.js` | Bump desktop version, commit, tag, and push (`desktop-v*`) to trigger release workflow. | + +## Script inventory + +| File | Purpose | +|---|---| +| `scripts/release-desktop.js` | Desktop release automation (version bump + git tag/push). | +| `scripts/build-signed-local.js` | Local signed + notarized desktop build using keychain cert + `.env.signing`. | +| `scripts/build-and-verify.sh` | Local unsigned packaging test (`openmud.app` zip smoke check). | +| `scripts/dev-wrapper.sh` | Root dev bootstrap used by `npm run dev`. | +| `scripts/dev-from-symlink.sh` | Local static/site dev helper used by `dev:site`. | +| `scripts/dev-and-test.sh` | Combined dev/test helper. | +| `scripts/smoke-test.js` | Smoke checks for local build/runtime behavior. | +| `scripts/site-bot.js` | Synthetic site checks used in CI and local QA. | +| `scripts/setup-auth.js` | Auth setup helper for local/dev environment. | +| `scripts/generate-apple-jwt.js` | Utility for generating Apple auth JWTs. | +| `scripts/install-latest-dmg.sh` | Download/install latest desktop DMG helper. | +| `scripts/after-pack.js` | Electron post-pack hook used during desktop build. | +| `scripts/make_favicon.py` | Favicon generation utility. | +| `scripts/make_logo_transparent.py` | Logo processing utility. |