Files
NianToB/docs/M1_HANDOFF.md

201 lines
6.1 KiB
Markdown

# 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`.