Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/desktop-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.npm
key: desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'apps/controller/static/runtime-plugins/openclaw-weixin/package-lock.json') }}
key: desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'packages/slimclaw/runtime-plugins/openclaw-weixin/package.json') }}
restore-keys: |
desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-
desktop-npm-cache-${{ runner.os }}-
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/desktop-ci-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.npm
key: desktop-npm-cache-${{ runner.os }}-arm64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'apps/controller/static/runtime-plugins/openclaw-weixin/package-lock.json') }}
key: desktop-npm-cache-${{ runner.os }}-arm64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'packages/slimclaw/runtime-plugins/openclaw-weixin/package.json') }}
restore-keys: |
desktop-npm-cache-${{ runner.os }}-arm64-
desktop-npm-cache-${{ runner.os }}-
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/desktop-ci-dist-full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.npm
key: desktop-npm-cache-${{ runner.os }}-arm64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'apps/controller/static/runtime-plugins/openclaw-weixin/package-lock.json') }}
key: desktop-npm-cache-${{ runner.os }}-arm64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'packages/slimclaw/runtime-plugins/openclaw-weixin/package.json') }}
restore-keys: |
desktop-npm-cache-${{ runner.os }}-arm64-
desktop-npm-cache-${{ runner.os }}-
Expand Down Expand Up @@ -151,7 +151,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.npm
key: desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'apps/controller/static/runtime-plugins/openclaw-weixin/package-lock.json') }}
key: desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'packages/slimclaw/runtime-plugins/openclaw-weixin/package.json') }}
restore-keys: |
desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-
desktop-npm-cache-${{ runner.os }}-
Expand Down Expand Up @@ -328,7 +328,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~\AppData\Local\npm-cache
key: desktop-npm-cache-${{ runner.os }}-x64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'apps/controller/static/runtime-plugins/openclaw-weixin/package-lock.json') }}
key: desktop-npm-cache-${{ runner.os }}-x64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'packages/slimclaw/runtime-plugins/openclaw-weixin/package.json') }}
restore-keys: |
desktop-npm-cache-${{ runner.os }}-x64-
desktop-npm-cache-${{ runner.os }}-
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/desktop-ci-dist-lite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.npm
key: desktop-npm-cache-${{ runner.os }}-arm64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'apps/controller/static/runtime-plugins/openclaw-weixin/package-lock.json') }}
key: desktop-npm-cache-${{ runner.os }}-arm64-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'packages/slimclaw/runtime-plugins/openclaw-weixin/package.json') }}
restore-keys: |
desktop-npm-cache-${{ runner.os }}-arm64-
desktop-npm-cache-${{ runner.os }}-
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/desktop-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.npm
key: desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'apps/controller/static/runtime-plugins/openclaw-weixin/package-lock.json') }}
key: desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('packages/slimclaw/runtime-seed/package-lock.json', 'packages/slimclaw/runtime-plugins/openclaw-weixin/package.json') }}
restore-keys: |
desktop-npm-cache-${{ runner.os }}-${{ matrix.arch }}-
desktop-npm-cache-${{ runner.os }}-
Expand Down
32 changes: 21 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Nexu is a desktop-first OpenClaw platform. Users create AI bots, connect them to
- `apps/controller` — Single-user local control plane for Nexu config, OpenClaw sync, and runtime orchestration
- `apps/desktop` — Electron desktop runtime shell and sidecar orchestrator
- `apps/web` — React + Ant Design + Vite
- `packages/slimclaw` — Repo-local Nexu-owned OpenClaw runtime contract, prepared runtime root, and staging/patch ownership for local dev and desktop packaging
- `packages/slimclaw` — Repo-local Nexu-owned OpenClaw runtime contract and single source of truth for prepared runtime, builtin runtime assets, and staging/patch ownership for local dev and desktop packaging
- `packages/shared` — Shared Zod schemas
- `packages/dev-utils` — TS-first reusable utilities for local script tooling

Expand Down Expand Up @@ -188,6 +188,8 @@ The desktop test suite includes real launchd integration tests that run on macOS
- Config generator output must match `specs/references/openclaw-config-schema.md`.
- Do not add dependencies without explicit approval.
- Do not modify OpenClaw source code.
- **Historical spec/plan docs are snapshots, not living docs.** Treat `specs/**`, `docs/plans/**`, and other dated plan/spec artifacts as committed historical snapshots. Do not keep mutating them during normal documentation evolution; if the current truth changes, update live docs (`AGENTS.md`, `ARCHITECTURE.md`, `CONTRIBUTING.md`, `docs/**`) or create a new snapshot artifact instead.
- **Slimclaw is the single runtime source of truth.** `packages/slimclaw` is the only canonical owner for Nexu's embedded OpenClaw capability packaging, prepared runtime artifacts, builtin runtime plugins, and staging contract. Runtime changes should land through slimclaw by default. Any exception must be justified through a spec/plan PR and explicit team discussion before implementation.
- Never commit code changes until explicitly told to do so.
- Desktop packaged app: never use `npx`, `npm`, `pnpm`, or any shell command that relies on the user's PATH. The packaged Electron app has no shell profile — resolve bin paths programmatically via `require.resolve()` and execute with `process.execPath`. The app must be fully self-contained.
- Windows packaging split: use `pnpm dist:win` for the full installer/release path and keep it close to CI semantics. Use `pnpm dist:win:local` for local Windows validation when you need fast iteration; it is intentionally dir-only and reuse-first, so it is not a substitute for the full release build.
Expand Down Expand Up @@ -217,7 +219,7 @@ See `ARCHITECTURE.md` for the full bird's-eye view. Key points:
- Monorepo: `apps/controller` (Hono), `apps/web` (React), `apps/desktop` (Electron), `packages/shared` (Zod schemas), `nexu-skills/` (skill repo)
- Type safety: Zod -> OpenAPI -> generated frontend SDK. Never duplicate types.
- Config generator: `apps/controller/src/lib/openclaw-config-compiler.ts` builds OpenClaw config from local controller state
- Local runtime flow: `apps/controller` owns Nexu config/state, writes OpenClaw config/skills/templates, and manages the slimclaw-backed OpenClaw runtime contract directly; desktop wraps that controller-first stack with Electron + web sidecars
- Local runtime flow: `apps/controller` owns Nexu config/state and writes dynamic OpenClaw config/skills/state, while `packages/slimclaw` remains the sole owner of the prepared embedded OpenClaw runtime and builtin runtime artifacts; desktop wraps that controller-first stack with Electron + web sidecars
- Key data flows: local config compilation, desktop runtime boot, channel sync, file-based skill catalog

## Code style (quick reference)
Expand Down Expand Up @@ -271,7 +273,13 @@ See `ARCHITECTURE.md` for the full bird's-eye view. Key points:

## Documentation maintenance

After significant code changes, verify documentation is current.
After significant code changes, verify the live documentation is current.

### Live docs vs historical snapshots

- Treat `AGENTS.md`, `ARCHITECTURE.md`, `CONTRIBUTING.md`, and `docs/**` as the living documentation set.
- Treat `specs/**`, `docs/plans/**`, and other dated design/plan artifacts as historical snapshots. Once committed, they are frozen by default and should not be used as the target for routine doc drift cleanup.
- If guidance changes, update the live docs or add a new snapshot doc that supersedes the old one. Do not silently rewrite old snapshots to look current.

### Diff baseline

Expand All @@ -283,25 +291,27 @@ git diff --name-only $(git merge-base HEAD origin/main)...HEAD

| Changed area | Affected docs |
|---|---|
| `apps/web/src/pages/` or routing | `specs/FRONTEND.md` |
| `apps/controller/src/routes/` | `specs/references/api-patterns.md`, `specs/product-specs/*.md` |
| `apps/controller/src/runtime/` | `ARCHITECTURE.md`, `specs/RELIABILITY.md` |
| `apps/web/src/components/channel-setup/` | `specs/FRONTEND.md` |
| `apps/web/src/pages/` or routing | `docs/**`, `AGENTS.md` if command/workflow guidance changed |
| `apps/controller/src/routes/` | `ARCHITECTURE.md`, `CONTRIBUTING.md`, `docs/**` if contributor-facing behavior changed |
| `apps/controller/src/runtime/` | `ARCHITECTURE.md`, `AGENTS.md`, `docs/**` if runtime workflow changed |
| `apps/web/src/components/channel-setup/` | `docs/**` |
| `nexu-skills/` | `ARCHITECTURE.md` (monorepo layout) |
| `packages/shared/src/schemas/` | `ARCHITECTURE.md` (type safety) |
| `packages/slimclaw/**` | `AGENTS.md`, `ARCHITECTURE.md`, `CONTRIBUTING.md`, `docs/**` when contributor/runtime guidance changed |
| `package.json` scripts | `AGENTS.md` Commands section |
| New/moved doc files | `AGENTS.md` Where to look |

### Cross-reference checklist

1. `AGENTS.md` Where to look table — all paths valid
2. `specs/DESIGN.md` <-> `specs/design-specs/` + `specs/designs/` (indexed)
3. `specs/product-specs/index.md` <-> actual spec files
4. `specs/FRONTEND.md` Pages <-> `apps/web/src/app.tsx` routes
2. `ARCHITECTURE.md` still reflects the active system shape and ownership boundaries
3. `CONTRIBUTING.md` and `docs/zh/guide/contributing.md` still reflect the active contributor workflow when changed
4. `docs/.vitepress/config.ts` still indexes any new or moved live docs pages

### Rules

- Regenerate `specs/generated/db-schema.md` fully from schema source
- Only touch snapshot docs under `specs/**` when creating/replacing a snapshot or correcting an objective factual breakage that cannot be left stale
- Regenerate `specs/generated/db-schema.md` fully from schema source when that generated snapshot itself is intentionally updated
- Preserve original language (English/Chinese)
- Do not auto-commit; present changes for review

Expand Down
9 changes: 5 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Architecture

Nexu uses a controller-first local runtime model. In desktop/local mode, a single `apps/controller` process owns Nexu config, compiles OpenClaw config, materializes skills/templates, and orchestrates the OpenClaw runtime.
Nexu uses a controller-first local runtime model. In desktop/local mode, a single `apps/controller` process owns Nexu config, compiles dynamic OpenClaw config, materializes stateful skills/templates, and orchestrates the OpenClaw runtime. The embedded runtime artifact itself is owned by `packages/slimclaw`, which is the single source of truth for prepared OpenClaw runtime assets, builtin runtime plugins, and runtime staging.

## System diagram

Expand Down Expand Up @@ -48,14 +48,15 @@ Never hand-write types that duplicate a schema. Use `z.infer<typeof schema>`.
- **`apps/web/`** — React frontend. Pages in `src/pages/`, generated SDK in `lib/api/`, auth client in `src/lib/auth-client.ts`.
- **`apps/desktop/`** — Electron desktop runtime shell and sidecar orchestrator. The active local path launches `controller + web + openclaw` sidecars only.
- **`packages/shared/`** — Shared Zod schemas in `src/schemas/`. Includes bot, channel, gateway, invite, model, skill, and OpenClaw config schemas.
- **`packages/slimclaw/`** — Nexu-owned embedded OpenClaw runtime contract. Owns prepare/install/prune flows, prepared runtime artifacts, builtin runtime plugin ownership, and staging/patch application.
- **`nexu-skills/`** — Public skill repository. Each skill is a directory with `SKILL.md` frontmatter. `skills.json` is the built catalog index.
- **`specs/`** — Design docs, references, product specs, exec plans, generated artifacts.
- **`specs/`** — Historical design docs, references, product specs, exec plans, and generated snapshots. Useful for context, but not the living source of truth for day-to-day doc maintenance.

## Key data flows

**Desktop/local config generation:** Controller reads `~/.nexu/config.json` → compiles OpenClaw config JSON (agents, channels, bindings, models) → writes `OPENCLAW_CONFIG_PATH` and managed skills/templates → OpenClaw hot-reloads.
**Desktop/local config generation:** Controller reads `~/.nexu/config.json` → compiles OpenClaw config JSON (agents, channels, bindings, models) → writes `OPENCLAW_CONFIG_PATH` and managed dynamic skills/templates/state → OpenClaw hot-reloads against the slimclaw-owned prepared runtime.

**Desktop runtime boot:** Electron desktop starts the controller sidecar, waits for controller readiness/auth bootstrap, starts the web sidecar, and delegates OpenClaw process management to `apps/controller`.
**Desktop runtime boot:** Electron desktop resolves the slimclaw-owned runtime artifact, starts the controller sidecar, waits for controller readiness/auth bootstrap, starts the web sidecar, and delegates OpenClaw process management to `apps/controller`.

**Proxy policy:** Desktop bootstrap computes one normalized proxy policy from `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, and `NO_PROXY`, applies it to Electron networking, propagates the normalized uppercase env into controller/web/OpenClaw child processes, and always merges loopback bypass entries (`localhost`, `127.0.0.1`, `::1`).

Expand Down
12 changes: 10 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This file is the **canonical English** contributing guide. The docs site embeds

Thank you for helping improve nexu. The sections below cover **code**, **documentation**, and **how we review changes**.

For documentation maintenance, treat `AGENTS.md`, `ARCHITECTURE.md`, `CONTRIBUTING.md`, and `docs/**` as the live docs. Treat `specs/**`, `docs/plans/**`, and other dated design/plan artifacts as historical snapshots that are frozen by default once committed.

If you want a lower-friction entry point, we are actively looking for **Good First Issue** contributors. Start with the [good-first-issue label](https://github.com/nexu-io/nexu/labels/good-first-issue) or the [Chinese first-PR guide](https://docs.nexu.io/zh/guide/first-pr).

## Community standards
Expand Down Expand Up @@ -54,11 +56,11 @@ nexu/
│ ├── desktop/ # Electron desktop shell
│ └── controller/ # Hono backend + OpenClaw orchestration
├── packages/shared/ # Shared Zod schemas
├── packages/slimclaw/ # Repo-local OpenClaw runtime contract + prepared runtime ownership
├── packages/slimclaw/ # Single source of truth for the embedded OpenClaw runtime contract and prepared runtime artifacts
├── scripts/ # Dev/CI scripts (launchd, probes, e2e)
├── tests/ # Vitest test suites
├── docs/ # VitePress documentation site
└── specs/ # Design docs, product specs
└── specs/ # Historical design docs, product specs, and other snapshots
```

## Common commands
Expand Down Expand Up @@ -155,6 +157,12 @@ VitePress prints a local URL; use it to verify headings, links, and images.
- Chinese pages: `docs/zh/`
- New sidebar entries: update `docs/.vitepress/config.ts`
- When you add or substantially change a guide, **keep English and Chinese in sync** when both locales exist.
- Do not use `specs/**` or dated plan docs as the target for routine doc cleanup. If the current truth changes, update the live docs above or add a new snapshot doc instead of mutating old ones.

### Runtime ownership rule

- `packages/slimclaw` is the single source of truth for Nexu's embedded OpenClaw runtime packaging, prepared artifacts, builtin runtime plugins, and staging contract.
- If your change affects embedded runtime ownership or packaging behavior, route it through slimclaw by default. Anything that intentionally bypasses slimclaw should be discussed with maintainers before implementation.

### Paste images into Markdown

Expand Down
Loading
Loading