You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: streamline desktop local dev workflow (#640)
* feat: add local dev supervisor workflow
* feat: refine local dev workflow and desktop runtime scaffolding
* docs: add dev workflow faq
* fix: remove nested controller tsx watcher
* refactor: share ensure guards across dev process helpers
* chore: remove stale task notes
* refactor: centralize local dev path resolution
* refactor: move dev orchestration into scripts/dev
Keep @nexu/dev-utils focused on atomic helpers so service-level controller and web flows stay easier to reason about and recover. Add lightweight session tracing so leaked dev processes can be correlated and cleaned up without heavy self-healing.
* refactor: clarify scripts dev module boundaries
* feat: externalize dev runtime ownership
* feat: split local dev into explicit service controls
* refactor: remove legacy desktop dev launchers
* fix: run desktop local dev through the Vite supervisor
* fix: harden local dev stack flow
* chore: sync workspace lockfiles
* fix: restore desktop dev auth session
Copy file name to clipboardExpand all lines: AGENTS.md
+23-17Lines changed: 23 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,7 @@ Nexu is a desktop-first OpenClaw platform. Users create AI bots, connect them to
12
12
-`apps/web` — React + Ant Design + Vite
13
13
-`openclaw-runtime` — Repo-local packaged OpenClaw runtime for local dev and desktop packaging; replaces global `openclaw` CLI
14
14
-`packages/shared` — Shared Zod schemas
15
+
-`packages/dev-utils` — TS-first reusable utilities for local script tooling
15
16
16
17
## Project overview
17
18
@@ -23,13 +24,16 @@ All commands use pnpm. Target a single app with `pnpm --filter <package>`.
23
24
24
25
```bash
25
26
pnpm install # Install
26
-
pnpm dev # Local controller-first web stack (Controller + Web)
27
-
pnpm dev:controller # Controller only
28
-
pnpm start # Build and launch the desktop local runtime stack
29
-
pnpm stop # Stop the desktop local runtime stack
30
-
pnpm restart # Restart the desktop local runtime stack
31
-
pnpm reset-state # Stop desktop runtime and delete repo-local desktop state
32
-
pnpm status # Show desktop local runtime status
27
+
pnpm --filter @nexu/shared build # Build shared dist required by cold-start dev flows
28
+
pnpm dev start # Start the lightweight local stack: openclaw -> controller -> web -> desktop
29
+
pnpm dev start <service># Start one local-dev service: desktop|openclaw|controller|web
30
+
pnpm dev restart # Restart the lightweight local stack
31
+
pnpm dev stop # Stop the lightweight local stack in reverse order
32
+
pnpm dev stop <service># Stop one local-dev service
33
+
pnpm dev restart <service># Restart one local-dev service
34
+
pnpm dev status <service># Show status for one local-dev service
35
+
pnpm dev logs <service># Show active-session log tail (max 200 lines) for one local-dev service
36
+
pnpm dev:controller # Legacy controller-only direct dev entrypoint
33
37
pnpm dist:mac # Build signed macOS desktop distributables
34
38
pnpm dist:mac:arm64 # Build signed Apple Silicon macOS desktop distributables
35
39
pnpm dist:mac:x64 # Build signed Intel macOS desktop distributables
@@ -67,15 +71,16 @@ This repo is desktop-first. Prefer the controller-first path and remove or ignor
67
71
68
72
## Desktop local development
69
73
70
-
- Use `pnpm install` first, then `pnpm start` / `pnpm stop` / `pnpm restart` / `pnpm status` as the standard local desktop workflow.
71
-
-`pnpm start` is the canonical local desktop entrypoint and now applies safe startup optimizations by default: it reuses existing build artifacts when present and reuses the prepared OpenClaw sidecar cache when its inputs have not changed.
72
-
- Temporary escape hatches exist for debugging or suspicious cache behavior: `NEXU_DESKTOP_FORCE_FULL_START=1` disables the optimized start path, `NEXU_DESKTOP_DISABLE_BUILD_REUSE=1` disables build artifact reuse only, and `NEXU_DESKTOP_DISABLE_OPENCLAW_SIDECAR_CACHE=1` disables the OpenClaw sidecar cache only.
73
-
-`pnpm reset-state` is the reset button for the optimized path too: it stops the desktop runtime and clears repo-local runtime state plus cached sidecars under `.tmp/sidecars/`.
74
+
- Minimal cold-start setup on a fresh machine is: `pnpm install` -> `pnpm --filter @nexu/shared build` -> copy `scripts/dev/.env.example` to `scripts/dev/.env` only if you need dev-only overrides.
75
+
- Default daily flow is: `pnpm dev start` -> `pnpm dev status <service>` / `pnpm dev logs <service>` as needed -> `pnpm dev stop`.
76
+
- Use `pnpm dev restart` for a clean full-stack recycle; use `pnpm dev restart <service>` only when you are intentionally touching one service.
77
+
- Explicit single-service control remains available through `pnpm dev start <desktop|openclaw|controller|web>`, `pnpm dev stop <service>`, `pnpm dev restart <service>`, `pnpm dev status <service>`, and `pnpm dev logs <service>`.
78
+
-`pnpm dev` intentionally does not support `all`; the full local stack order remains `openclaw` -> `controller` -> `web` -> `desktop`.
79
+
-`pnpm dev logs <service>` is session-scoped, prints a fixed header, and tails at most the last 200 lines from the active service session.
80
+
-`scripts/dev/.env.example` is the source-of-truth template for dev-only overrides. Copy it to `scripts/dev/.env` only when you need to override ports, URLs, state paths, or the shared OpenClaw gateway token for local development.
74
81
- Keep the detailed startup optimization rules, cache invalidation behavior, and troubleshooting notes in `specs/guides/desktop-runtime-guide.md`; keep only the core workflow expectations here.
75
82
- The repo also includes a local Slack reply smoke probe at `scripts/probe/slack-reply-probe.mjs` (`pnpm probe:slack prepare` / `pnpm probe:slack run`) for verifying the end-to-end Slack DM reply path after local runtime or OpenClaw changes.
76
83
- The Slack smoke probe is not zero-setup: install Chrome Canary first, then manually log into Slack in the opened Canary window before running `pnpm probe:slack run`.
77
-
- The desktop dev launcher is `apps/desktop/scripts/dev-cli.mjs`; `apps/desktop/dev.sh` is only a thin compatibility wrapper.
78
-
- Treat `pnpm start` as the canonical cold-start entrypoint for the full local desktop runtime.
79
84
- The active desktop runtime path is controller-first: desktop launches `controller + web + openclaw` and no longer starts local `api`, `gateway`, or `pglite` sidecars.
80
85
- Desktop local runtime should not depend on PostgreSQL. In dev mode, all state (config, OpenClaw state, logs) lives under `.tmp/desktop/nexu-home/`, fully isolated from the packaged app. Launchd plists go to `.tmp/launchd/`, runtime-ports.json also lives there.
81
86
- In packaged mode, data is split across two directories (see table below). Launchd plists go to `~/Library/LaunchAgents/`.
@@ -90,21 +95,18 @@ This repo is desktop-first. Prefer the controller-first path and remove or ignor
90
95
91
96
The split is intentional: `NEXU_HOME` holds lightweight user preferences that should persist across reinstalls; Electron `userData` holds heavy runtime state tied to the app lifecycle. `OPENCLAW_STATE_DIR` is explicitly set by the desktop launcher to point to the `userData` path — do not rely on the controller's default fallback.
92
97
-`tmux` is no longer required for the desktop local-dev workflow; process state is tracked by the platform-aware launcher entrypoints.
93
-
- For startup troubleshooting, use `pnpm logs` and `node apps/desktop/scripts/dev-cli.mjs devlog` when you need the raw dev-cli timeline.
94
-
-`pnpm reset-state` is a dev-only cleanup shortcut; it stops the stack and removes repo-local desktop runtime state under `.tmp/desktop/`, but it does not delete packaged app state.
95
98
- To fully reset local desktop + controller state, stop the stack, remove `.tmp/desktop/`, then remove `~/.nexu/` and `~/Library/Application Support/@nexu/desktop/`.
96
-
- If `pnpm start` exits immediately because `electron/cli.js` cannot be resolved from `apps/desktop`, validate `pnpm -C apps/desktop exec electron --version` and consult `specs/guides/desktop-runtime-guide.md` before changing the launcher flow.
97
99
- Desktop already exposes an agent-friendly runtime observability surface; prefer subscribing/querying before adding temporary UI or ad hoc debug logging.
98
100
- For deeper desktop runtime inspection, use the existing event/query path (`onRuntimeEvent(...)`, `runtime:query-events`, `queryRuntimeEvents(...)`) instead of rebuilding one-off diagnostics.
99
101
- Use `actionId`, `reasonCode`, and `cursor` / `nextCursor` as the primary correlation and incremental-fetch primitives for desktop runtime debugging.
100
-
- To fully clear local desktop runtime state, use `node apps/desktop/scripts/dev-cli.mjs reset-state`.
- The controller sidecar is packaged by `apps/desktop/scripts/prepare-controller-sidecar.mjs` which deep-copies all controller `dependencies` and their transitive deps into `.dist-runtime/controller/node_modules/`. Keep controller deps minimal to avoid bloating the desktop distributable.
103
104
- SkillHub (catalog, install, uninstall) runs in the controller via HTTP — not in the Electron main process via IPC. The web app always uses HTTP SDK for skill operations.
104
105
- Desktop auto-update is channel-specific. Packaged builds should embed `NEXU_DESKTOP_UPDATE_CHANNEL` (`stable` / `beta` / `nightly`) so the updater checks the matching feed, and update diagnostics should always log the effective feed URL plus remote `version` / `releaseDate` when available.
105
106
106
107
## Hard rules
107
108
109
+
-**Debugging first principle: binary isolate, don't guess.** For UI/runtime regressions, start with overall bisection and add tiny reversible `quick return` / `quick fail` probes at key boundaries. Prefer changes that create obvious UI/log differences, narrow the fault domain quickly, and can be reverted immediately after verification. Do not start by rewriting route guards, state flows, or core logic based on intuition.
108
110
-**Never use `any`.** Use `unknown` with narrowing or `z.infer<typeof schema>`.
109
111
- No foreign keys in Drizzle schema — application-level joins only.
110
112
- Credentials (bot tokens, signing secrets) must never appear in logs or errors.
@@ -168,6 +170,7 @@ See `ARCHITECTURE.md` for the full bird's-eye view. Key points:
- Daily local-dev flow: `pnpm dev start` -> `pnpm dev logs <service>` / `pnpm dev status <service>` when needed -> `pnpm dev restart` for a clean recycle -> `pnpm dev stop`
261
266
- OpenClaw managed skills dir (expected default): `~/.openclaw/skills/`
262
267
- Slack smoke probe setup: install Chrome Canary, set `PROBE_SLACK_URL`, run `pnpm probe:slack prepare`, then manually log into Slack in Canary before `pnpm probe:slack run`
263
268
-`openclaw-runtime` is installed implicitly by `pnpm install`; local development should normally not use a global `openclaw` CLI
269
+
- Full-stack startup order is `openclaw` -> `controller` -> `web` -> `desktop`; shutdown order is the reverse
264
270
- Prefer `./openclaw-wrapper` over global `openclaw` in local development; it executes `openclaw-runtime/node_modules/openclaw/openclaw.mjs`
265
271
- When OpenClaw is started manually, set `RUNTIME_MANAGE_OPENCLAW_PROCESS=false` for `@nexu/controller` to avoid launching a second OpenClaw process
266
272
- If behavior differs, verify effective `OPENCLAW_STATE_DIR` / `OPENCLAW_CONFIG_PATH` used by the running controller process.
0 commit comments