feat: prepare Zhinian desktop client for pilot release
This commit is contained in:
200
docs/M1_HANDOFF.md
Normal file
200
docs/M1_HANDOFF.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# YINIAN Desktop M1 Handoff
|
||||
|
||||
> Updated: 2026-04-26
|
||||
> Scope: M1 foundation closure after ClawX fork adaptation. See `docs/PILOT_QA.md` for the current M2 pilot demo and QA gate.
|
||||
|
||||
## 1. What M1 Delivers
|
||||
|
||||
M1 turns the ClawX fork into a YINIAN-ready desktop foundation without removing the original ClawX/OpenClaw capabilities.
|
||||
|
||||
Delivered:
|
||||
|
||||
- YINIAN login-first product flow.
|
||||
- Auth session restore and logout cleanup.
|
||||
- Hotel tenant context and hotel switching.
|
||||
- Config snapshot sync from mock or HTTP control plane.
|
||||
- Local skill registry grouped by `hotelId`.
|
||||
- Skills sync v0 from manifest to registry.
|
||||
- Today page as the new production home route.
|
||||
- Skills page replaced with YINIAN skill control surface.
|
||||
- Gateway auto-start deferred until YINIAN authentication.
|
||||
- Legacy ClawX E2E compatibility preserved.
|
||||
- Workspace packages added for future kernel/skill/UI boundaries.
|
||||
|
||||
Not delivered in M1:
|
||||
|
||||
- Real skill bundle download.
|
||||
- Signature verification and unpacking.
|
||||
- Real OTA skill execution.
|
||||
- Final backend API contract.
|
||||
- Customer-ready pilot dashboard depth.
|
||||
|
||||
## 2. Main Behavior
|
||||
|
||||
### Production Flow
|
||||
|
||||
1. App starts.
|
||||
2. Renderer calls `window.yinian.auth.restoreSession()`.
|
||||
3. If no valid session exists, user is redirected to `/login`.
|
||||
4. Login succeeds through mock control plane by default, or HTTP mode when configured.
|
||||
5. App loads config and local skill registry for the current hotel.
|
||||
6. App navigates to `/today`.
|
||||
7. Gateway initializes and starts only after authenticated hotel context exists.
|
||||
|
||||
### E2E Compatibility Flow
|
||||
|
||||
When Electron is launched with `CLAWX_E2E=1`, main process appends `e2e=1` to the renderer URL.
|
||||
|
||||
In E2E mode:
|
||||
|
||||
- Legacy setup flow remains available.
|
||||
- `/` renders the original Chat page, not Today.
|
||||
- Default language is English unless the test changes it.
|
||||
- Gateway store is initialized after setup, but gateway is not auto-started.
|
||||
|
||||
This keeps the inherited ClawX regression suite valid while production behavior moves to YINIAN.
|
||||
|
||||
## 3. Environment Switches
|
||||
|
||||
| Variable | Values | Default | Purpose |
|
||||
|---|---|---:|---|
|
||||
| `YINIAN_API_BASE_URL` | URL | unset | Enables HTTP control plane. When unset, app uses mock mode. |
|
||||
| `CLAWX_LEGACY_AUTOSTART` | `1` / unset | unset | Restores old main-process gateway auto-start for debugging. Production YINIAN keeps gateway deferred until login. |
|
||||
| `CLAWX_E2E` | `1` / unset | unset | Enables E2E compatibility mode. Used by Playwright fixtures. |
|
||||
| `CLAWX_E2E_SKIP_SETUP` | `1` / unset | unset | Adds `e2eSkipSetup=1` for tests that bypass setup. |
|
||||
|
||||
## 4. Storage Boundary
|
||||
|
||||
YINIAN uses a separate Electron store namespace:
|
||||
|
||||
- Store name: `yinian`
|
||||
- Helper: `electron/yinian/storage.ts`
|
||||
|
||||
Stored data:
|
||||
|
||||
- `session`: persisted YINIAN session metadata.
|
||||
- `configs`: config snapshots keyed by hotel id.
|
||||
- `skillRegistryByHotel`: local skill registries keyed by hotel id.
|
||||
|
||||
Important constraints:
|
||||
|
||||
- Renderer never reads tokens directly.
|
||||
- Renderer accesses auth/config/skill data only through `window.yinian`.
|
||||
- Mock mode persists enough session data to restore the local demo.
|
||||
- HTTP mode keeps `accessToken` in memory and reserves persistence for `refreshToken`.
|
||||
- Logout clears session, current hotel config, and current hotel skill registry through the control plane.
|
||||
|
||||
## 5. Public Renderer API
|
||||
|
||||
The preload exposes `window.yinian`:
|
||||
|
||||
```ts
|
||||
window.yinian.auth.restoreSession()
|
||||
window.yinian.auth.getSessionState()
|
||||
window.yinian.auth.loginWithSms(input)
|
||||
window.yinian.auth.loginWithPassword(input)
|
||||
window.yinian.auth.logout()
|
||||
|
||||
window.yinian.app.getConfig()
|
||||
window.yinian.app.switchHotel(hotelId)
|
||||
|
||||
window.yinian.skills.sync()
|
||||
window.yinian.skills.listLocal()
|
||||
window.yinian.skills.getRegistry(hotelId?)
|
||||
```
|
||||
|
||||
Shared types live in `shared/yinian.ts`.
|
||||
|
||||
## 6. Module Inventory
|
||||
|
||||
### Electron Main
|
||||
|
||||
- `electron/main/ipc/yinian.ts`
|
||||
- IPC handlers for auth, config, hotel switching, skill sync, and registry reads.
|
||||
- `electron/yinian/control-plane.ts`
|
||||
- Chooses mock or HTTP control plane.
|
||||
- `electron/yinian/mock-control-plane.ts`
|
||||
- Local demo implementation with persisted session/config/registry.
|
||||
- `electron/yinian/http-control-plane.ts`
|
||||
- HTTP implementation scaffold for server integration.
|
||||
- `electron/yinian/storage.ts`
|
||||
- YINIAN-specific storage namespace.
|
||||
- `electron/main/index.ts`
|
||||
- Defers gateway auto-start.
|
||||
- Adds E2E renderer query parameters.
|
||||
- `electron/preload/index.ts`
|
||||
- Exposes `window.yinian`.
|
||||
|
||||
### Renderer
|
||||
|
||||
- `src/stores/yinian.ts`
|
||||
- Auth/session/config store.
|
||||
- Restores session on boot.
|
||||
- Refreshes config and skill registry after login and hotel switch.
|
||||
- `src/stores/yinian-skills.ts`
|
||||
- Local registry and skill sync store.
|
||||
- `src/pages/YinianLogin/`
|
||||
- Login UI.
|
||||
- `src/pages/Today/`
|
||||
- M1 hotel home surface.
|
||||
- `src/pages/YinianSkills/`
|
||||
- Skill registry and sync surface.
|
||||
- `src/components/layout/YinianTenantBar.tsx`
|
||||
- Current hotel switcher and logout.
|
||||
- `src/App.tsx`
|
||||
- YINIAN auth gate, production `/today`, E2E compatibility paths.
|
||||
|
||||
### Workspace Packages
|
||||
|
||||
- `packages/kernel-core`
|
||||
- `packages/kernel-context`
|
||||
- `packages/kernel-adapter-openclaw`
|
||||
- `packages/skill-spec`
|
||||
- `packages/skills-hotel-core`
|
||||
- `packages/ui-kit`
|
||||
|
||||
These are M1 boundary scaffolds. They are intentionally thin and should harden during M2/M3.
|
||||
|
||||
### Tests
|
||||
|
||||
- `tests/unit/yinian-control-plane.test.ts`
|
||||
- `tests/unit/yinian-store.test.ts`
|
||||
- `tests/unit/yinian-skills-store.test.ts`
|
||||
|
||||
Inherited ClawX unit and E2E tests are still expected to pass.
|
||||
|
||||
## 7. Verification Baseline
|
||||
|
||||
Last known green run:
|
||||
|
||||
```bash
|
||||
pnpm run typecheck
|
||||
pnpm run test
|
||||
pnpm run test:e2e
|
||||
```
|
||||
|
||||
Results:
|
||||
|
||||
- Typecheck: passed.
|
||||
- Unit tests: 89 files, 572 tests passed.
|
||||
- E2E: 26 passed, 1 skipped.
|
||||
|
||||
Known non-blocking warnings:
|
||||
|
||||
- Vitest `MaxListenersExceededWarning`.
|
||||
- Vite dynamic/static import chunk warnings.
|
||||
- Vite large chunk warning.
|
||||
- Playwright/Electron `NO_COLOR` ignored because `FORCE_COLOR` is set.
|
||||
|
||||
## 8. M2 Entry Points
|
||||
|
||||
Recommended next steps:
|
||||
|
||||
1. Define real server contract v0.
|
||||
2. Upgrade Today page into a pilot operations cockpit.
|
||||
3. Expand Skills Manager status model and UI.
|
||||
4. Start design system consolidation across Login, Today, Skills, and tenant switcher.
|
||||
|
||||
See `task_plan.md` for the active phased plan.
|
||||
|
||||
The first draft of the server contract now lives in `docs/SERVER_CONTRACT_V0.md`.
|
||||
Reference in New Issue
Block a user