- The Windows installer remains the single user-facing entry point.
- Bundled OpenClaw runtime ships inside the installer.
- The first real delivery milestone in Stage D is not full business cloud integration.
- The first real delivery milestone is: installer can become truly usable by letting the user bind an OpenClaw employee `api_key`, fetch runtime config from cloud, and start bundled runtime automatically.
## 2. Product Principles
Current fixed principles:
- The user must first bind an OpenClaw employee `api_key` before OpenClaw can be used.
- This `api_key` is the runtime employee identity key, not the upstream model vendor key.
- The user should not manually enter provider, model, base_url, model vendor api_key, local Node path, OpenClaw entry path, or Gateway token in the normal product flow.
- The desktop app stores the employee `api_key` in Electron Main secret storage.
- Renderer remains a UI layer only and does not own raw credentials.
## 3. First Real Usable Flow
Stage D step 1 user flow should be:
1. User installs the Windows app.
2. User opens the desktop app.
3. User goes to settings or first-run activation view.
4. User binds an OpenClaw employee `api_key`.
5. Electron Main calls `POST /openclaw-employee-config` with `{ api_key, action: "init" }`.
6. Main receives cloud runtime payload.
7. Main generates local managed runtime config.
8. Bundled runtime starts.
9. Gateway becomes available.
10. User can start using the installer product.
## 4. Required Runtime Cloud APIs
Current required runtime-side APIs are:
-`POST /openclaw-employee-config`
-`POST /openclaw-heartbeat`
-`POST /openclaw-employee-events`
For Stage D step 1, only the first endpoint is required for initial delivery.
## 5. Runtime Config Strategy
The current runtime config strategy is:
- user provides employee `api_key`
- cloud returns runtime payload
- desktop app writes local managed config
- bundled runtime starts from that managed config
The `openclaw-employee-config` payload should provide business-controlled runtime fields such as:
-`persona_prompt`
-`welcome_message`
-`work_hours`
-`auto_reply_rules`
-`resource_quota`
-`llm.model_id`
-`llm.temperature`
-`llm.max_tokens`
-`llm.provider.base_url`
-`llm.provider.api_key`
-`skills`
-`channels`
-`config_version`
-`endpoints.heartbeat`
-`endpoints.events`
The desktop app should still add local machine-specific values such as:
- workspace path
- runtime state/log paths
- bundled Gateway bind and port
- local managed config output path
## 6. Security Rules
- Employee `api_key` stays in Electron Main and secret storage.
- Raw `api_key` must not be exposed to Renderer.
- Diagnostics export must not dump raw credentials.
- If employee `api_key` is missing, bundled runtime must not pretend to be available.
- If `openclaw-employee-config` fetch fails, bundled runtime must not start.
## 7. What Is Not Stage D Step 1 Yet
Not part of this first delivery slice:
- full product-side login, account, credits, and Skills production integration
- heartbeat and event reporting implementation
- full entitlement or billing product UX
- final release polish such as icon, signing, and upgrade path
## 8. Acceptance for This First Delivery Slice
Stage D step 1 should only be considered complete when:
- user can bind an OpenClaw employee `api_key`
- app can successfully call `POST /openclaw-employee-config`
- app can generate managed runtime config from real cloud payload
- bundled runtime starts from that config
- installer becomes truly usable without manual provider/model/base_url configuration
本计划基于当前 `dev` 分支代码事实制定,目标是把现有 Windows OpenClaw 客户端安装包链路改造成 **只面向 macOS Apple Silicon 的内部测试 DMG 包**。
本次改造不做双平台共存,不保留 Windows NSIS 安装器作为目标链路,也不纳入 Apple Developer ID 签名、公证、staple 等正式外部分发能力。阶段性目标是先让 M 芯片 Mac 上可以构建、安装、启动并跑通 bundled runtime 与 workspace execution。
- Electron darwin arm64 zip 直连 GitHub 会卡住;用 `HTTPS_PROXY=http://127.0.0.1:7897 HTTP_PROXY=http://127.0.0.1:7897 ALL_PROXY=http://127.0.0.1:7897 ELECTRON_GET_USE_PROXY=true` 可下载成功。
- Keep the desktop app as the main Windows client while moving from technical PoC to real deliverable integration.
- Use Electron plus React plus TypeScript plus pnpm workspace.
- Keep `Renderer -> preload -> Electron Main -> GatewayClient / RuntimeManager / cloud clients` as the stable boundary.
- Ship a bundled OpenClaw runtime inside the installer so the desktop app becomes the single user-facing entry point.
The practical end goal is:
- user installs one Windows app
- user binds an OpenClaw employee `api_key`
- app fetches runtime configuration from cloud
- app generates local managed runtime config automatically
- app starts bundled OpenClaw runtime locally
- app reports runtime liveness and events back to cloud
- user can use the installer without manually filling provider, model, base_url, or vendor model api_key
## 2. Current Stage
Current stage should now be treated as:
- Stage A: complete
- Stage B: complete
- Stage C technical PoC: complete
- Stage D formal delivery: started, but not complete
Practical interpretation:
- installer generation works
- installer bundled-runtime smoke works
- desktop app can carry and launch bundled runtime on this machine
- real runtime cloud config integration for `openclaw-employee-config` is implemented
- runtime cloud supervisor is implemented for heartbeat, config sync, and event flush
- bundled runtime now includes a preinstalled Python layer for core table/document/web/config tasks
- diagnostics and smoke now expose runtime cloud telemetry
- installer can now be treated as trial-usable, but not yet as a final stable delivery
## 3. What Has Been Completed
### 3.1 Desktop architecture and local runtime path
Completed:
- Electron plus React plus TypeScript desktop app is working
- preload and IPC boundary is in place
- real local Gateway integration works
- sessions, history, chat.send, diagnostics export, and keytar-backed secrets are implemented
- bundled runtime detect, start, stop, restart, health, and tail logs are implemented
### 3.2 Installer and bundled runtime PoC
Completed:
- NSIS installer is generated at `dist/installer/QianjiangClaw-Setup-0.1.0.exe`
- installer smoke passes
- installer bundled-runtime smoke passes
- installer includes `vendor/openclaw-runtime` as extraResources
- generated installer can launch bundled runtime and connect bundled Gateway in the current verification environment
### 3.3 Bundled Python runtime payload
Completed in code and packaging:
- bundled runtime now materializes a Python runtime under `vendor/openclaw-runtime/python`
- the payload includes the first locked dependency set for built-in Skills:
-`openpyxl`
-`pandas`
-`requests`
-`beautifulsoup4`
-`lxml`
-`pypdf`
-`python-docx`
-`charset-normalizer`
-`pyyaml`
- runtime readiness now requires Node/OpenClaw files plus Python payload plus import self-check
- bundled runtime smoke now asserts `pythonReady = true`
- installer smoke now validates the packaged Python payload and imports the locked package set directly from `resources/vendor/openclaw-runtime/python`
### 3.4 Product UI baseline
Completed:
- desktop product UI is in place
- workspace page prioritizes account summary, current skill, execution policy, chat, and session flow
- diagnostics page includes Gateway, bundled runtime, logs, installed paths, runtime cloud, and export snapshot
- runtime cloud telemetry status is visible in diagnostics
### 3.5 Runtime cloud configuration integration
Completed in code:
-`OpenClawConfigClient` is implemented around `POST /openclaw-employee-config`
- the desktop app stores employee `api_key` in `SecretManager/keytar`
- the settings flow can save the runtime cloud base URL and employee `api_key`
- bundled runtime startup is now driven by cloud-fetched config instead of only the old local PoC path
- the returned payload is normalized into managed runtime config before runtime startup
- diagnostics now include runtime cloud config status
Implemented runtime-cloud behavior:
- if employee `api_key` is missing, runtime stays unconfigured and should not auto-start as usable
- if `POST /openclaw-employee-config` succeeds, the app extracts runtime-critical fields such as:
-`llm.provider.base_url`
-`llm.provider.api_key`
-`llm.model_id`
-`config_version`
- runtime heartbeat/events endpoints
- those values are merged into the local managed runtime config used by bundled OpenClaw
- runtime config sync is now implemented with a periodic `action: "sync"` flow
- sync results update runtime cloud status and runtime telemetry state
### 3.6 Runtime cloud heartbeat, events, and telemetry
Completed in code:
-`RuntimeCloudSupervisor` is implemented in Electron Main as the runtime cloud orchestrator
-`POST /openclaw-heartbeat` is implemented and scheduled through the supervisor
-`POST /openclaw-employee-events` is implemented with in-memory queueing and batch flush
- runtime cloud event production is wired into desktop lifecycle and chat flow
- runtime telemetry is exposed through preload/IPC as `runtimeTelemetry.getStatus()`
- diagnostics export includes `runtimeTelemetry`
- smoke validates runtime telemetry instead of only runtime startup
Implemented event/telemetry behavior:
- heartbeat loop runs independently of local runtime health and does not stop bundled runtime on cloud failure
- config sync loop runs independently and records changed/unchanged state into telemetry
- event queue batches and flushes runtime cloud events without blocking desktop chat flow
- the current core event set includes:
-`startup`
-`message_received`
-`message_sent`
-`error`
-`config_updated`
-`shutdown`
- runtime telemetry currently records:
- heartbeat success/error and last billing summary
- config sync success/error
- queued and accepted event counts
- message/error counters
- current config version
### 3.7 Real cloud endpoint verification
Verified:
- the real endpoint `https://xuphfkscoptnjoaecbvn.supabase.co/functions/v1/openclaw-employee-config` responds successfully with a real employee `api_key`
- the response contains runtime-critical fields including:
-`config_version`
-`llm.provider.base_url`
-`llm.provider.api_key`
-`llm.model_id`
-`endpoints.heartbeat`
-`endpoints.events`
This means the project is no longer only using mock contract data for runtime configuration.
### 3.8 Current verification result
Verified in the latest local acceptance pass:
-`corepack pnpm typecheck` passes
-`corepack pnpm build` passes
-`build/scripts/electron-smoke.ps1` passes
- smoke confirms bundled runtime is running in `bundled-runtime` mode
- smoke confirms the packaged Python payload contains the 9 locked dependencies
- smoke confirms runtime telemetry records heartbeat, config sync, and accepted runtime cloud events
### 3.9 Frontend refactor progress
Completed in the current frontend refactor pass:
- sidebar composition is extracted from `App.tsx` into `apps/ui/src/features/shell/AppSidebar.tsx`
-`AppSidebar` now composes `Sidebar`, `ExpertTree`, and `SessionList`
- expert category config and matching logic now live in `ExpertTree`
-`App.tsx` no longer inlines sidebar nav, expert tree, or session list JSX
- confirmed-unused legacy sidebar/expert CSS rules were removed
- current `App.tsx` size is about 4178 lines, so the sidebar split is complete but further reduction is still needed
6. only after that treat Stage D as entering broader product delivery work
## 8. Next-Start Checklist
When work resumes next time, start here:
1. read the runtime cloud API source document under `docs/` (the runtime cloud API integration document)
2. read `docs/progress-summary.md`
3. verify `openclaw-employee-config`, `openclaw-heartbeat`, and `openclaw-employee-events` still respond correctly in the target environment
4. verify the bundled Python payload is still present in `vendor/openclaw-runtime/python`
5. verify the packaged Python payload is still present in `dist/installer/win-unpacked/resources/vendor/openclaw-runtime/python`
6. run smoke and confirm runtime telemetry still shows heartbeat/config sync/event acceptance
7. run installer acceptance with a real employee `api_key`
8. expand runtime-side recovery/event coverage where needed
9. then continue the remaining product-side cloud APIs
## 9. Current One-Line Status
Current status: installer, bundled runtime, preinstalled Python payload, runtime cloud config, heartbeat, events, config sync, and runtime telemetry are all working; the app can now auto-fetch OpenClaw runtime config from user-bound employee `api_key`, start bundled runtime, report cloud heartbeat/events, and export diagnostics, but Stage D is still incomplete until broader runtime hardening, product-side cloud APIs, and wider real-world acceptance are finished.
## 10. 2026-05-07 Frontend Refactor Follow-Up
Completed:
- removed `resolveExpertVisualKey` and `buildShortcutPrompt` from `AppSidebar` / `ExpertTree` props; `ExpertTree` now imports the pure helpers directly
- added `ConversationWorkspaceView` to own the chat/expert workspace display composition while keeping stream, composer, session, and smoke logic in `App.tsx`
- moved workspace status chip derivation into `features/shell/startupStatus.ts`
- reduced `App.tsx` to 2672 lines without changing smoke action shapes
Skipped intentionally:
- did not wire `useChatSessionsController`; current local session flow has subtle active-session reset behavior that should be reconciled separately
- did not delete CSS; duplicate selector areas are in the frozen conversation/final theme layers and were not safe to trim in this pass
Verified:
- App encoding check: first bytes `105,109,112`, no UTF-8 BOM
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:subagent-driven-development` (recommended) or `superpowers:executing-plans` to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 基于当前客户端代码事实,把 renderer 收敛成更稳定、更专业、更易维护的 AI 桌面工作台。
**Architecture:** 不重写业务链路,不改 Electron IPC 合约。先固化事实基线和样式边界,再逐步压薄 `App.tsx`、收敛 CSS 覆盖、补齐工作台交互和可访问性。
**Tech Stack:** Electron renderer, Vite, React 19, TypeScript, plain CSS modules via `apps/ui/src/styles.css`, existing smoke hooks.
## Progress Sync - 2026-05-25
- Current committed progress: `4c81b90 style(ui): calm renderer shell visuals`.
- Validation passed after the CSS work: `corepack pnpm --filter @qjclaw/ui typecheck`; `corepack pnpm build`.
- Phase 1 is complete except baseline screenshots.
- Phase 2 has completed token cleanup, visual-noise reduction, and validation; duplicate layout ownership still needs a dedicated review pass.
-`shell.css`: base shell layout and non-theme structural behavior.
-`chat.css`: conversation-specific structure only under `.conversation-shell`.
-`theme-openclaw.css`: final product skin and current gray/blue visual theme.
Expected:
- No new global `.message-list` or `.composer-shell` visual overrides outside the intended layer.
- Conversation-only changes remain scoped under `.conversation-shell ...`.
Progress note:
- Partially addressed by `4c81b90`.
- Still open: dedicated review of ownership overlap across `components.css`, `shell.css`, `chat.css`, and `theme-openclaw.css`.
- Completed on 2026-05-25: removed shell/sidebar/main-shell responsive overrides from `components.css`, kept shell responsive ownership in `shell.css`, and removed structural `main-shell`/`content-area` overrides from `theme-openclaw.css`.
- Documented the desktop-first `min-width: 960px` shell contract in `shell.css`.
-[x]**Step 3: Remove obvious visual noise**
In touched rules:
- Replace heavy color shadows with `var(--revamp-shadow-soft)` or border-only states.
- Avoid new `translateY` hover movement.
- Keep card radius at or below existing app norms unless the rule already requires larger panels.
- Do not add decorative orbs, bokeh, or unrelated gradients.
Expected:
- Left sidebar and workspace feel calmer.
- Active/hover/focus states remain visible.
Progress note:
- Completed by `4c81b90`; removed several `translateY` hover effects, softened shadows, reduced decorative gradients, and replaced purple scrollbar/drag states with blue/gray variants.
- Create or modify focused hooks only under existing `apps/ui/src/features/*`
-[x]**Step 1: 拆出纯 props 组装**
Move only pure prop-building logic from `App.tsx` into focused helpers or hooks when all inputs are already available.
Candidate boundaries:
- Conversation workspace props.
- Settings panel props.
- Sidebar derived labels and entries.
Expected:
- No behavior change.
- No IPC calls move across ownership boundaries in this step.
-`App.tsx` line count decreases, but line count is not the success metric; clearer ownership is.
Progress note:
- Completed on 2026-05-25 by grouping `ConversationWorkspaceView` props into focused `status`, `emptyState`, `messages`, `composer`, and `actions` objects.
- IPC calls, stream lifecycle, composer submit/cancel, session actions, startup overlay actions, and smoke hooks remain in `App.tsx`.
-[x]**Step 2: Keep high-risk flows in place**
Do not move these during this phase:
- stream request lifecycle
-`__QJC_SMOKE__`
-`__QJC_SMOKE_ACTIONS__`
- composer submit/cancel
- session creation/closing
- startup overlay retry/export actions
Expected:
- Existing smoke tests do not need selector or action rewrites.
Progress note:
- Confirmed during the prop grouping pass; no smoke contract or high-risk flow was moved.
-[x]**Step 3: Reduce oversized component props**
For `ConversationWorkspaceView`, group related props into typed objects only when ownership is obvious:
- Long Chinese, English, URLs, and code blocks do not break layout.
- Message actions do not shift message height when appearing.
Progress note:
- Completed on 2026-05-25: added long-line wrapping guards for message text, assistant markdown, and code blocks while preserving existing message alignment and `aria-live` trace behavior.
-[x]**Step 3: Task panel icon cleanup**
Replace visible emoji used as UI icons with existing icon components or local SVG components.
Known target:
-`apps/ui/src/features/tasks/TaskPanelView.tsx`: package icon in the content output heading.
Expected:
- No visible emoji icons remain in primary tool controls or headings.
- Existing Chinese text remains unchanged except for necessary label updates.
Progress note:
- Completed on 2026-05-25: replaced the content-output heading emoji with a local SVG icon and changed copy feedback to text-only `已复制`.
-[x]**Step 4: Automation tasks density**
Requirements:
- Keep list, detail, form, and run history usable without window-level scroll confusion.
- Filter buttons and edit/create actions must have clear active and disabled states.
- Error state must use `role="alert"` or visible announced equivalent.
Expected:
- The page reads as an operational tool, not a card-heavy marketing layout.
- Long task prompts truncate or wrap predictably.
Progress note:
- Completed on 2026-05-25: tightened list/detail/form/run-history spacing, preserved `role="alert"` errors, and added clearer active/disabled states.
-[x]**Step 5: Settings hierarchy**
Requirements:
- Keep config source toggle visible and keyboard reachable.
- Secret reveal and copy controls must stay accessible.
- Save/reset/edit buttons must communicate disabled state clearly.
- Tabs must preserve `aria` semantics from existing `Tabs` component.
Expected:
- Users can scan required vs optional config groups quickly.
- Editing one section does not visually imply other sections are editing.
Progress note:
- Completed on 2026-05-25: preserved source toggle, secret reveal/copy, save/reset/edit, and Tabs semantics; copy feedback is now text-only without emoji.
-[x]**Step 6: Validate key workflows**
Run:
```sh
corepack pnpm --filter @qjclaw/ui typecheck
corepack pnpm build
```
If touched flow has existing source tests, also run:
- Pressing Enter moves focus target to main content.
Progress note:
- Completed on 2026-05-25: added `跳到主内容` skip link and `main#main-content` with `tabIndex={-1}`.
-[x]**Step 2: Add skip link styles**
Add CSS:
```css
.skip-link {
position: fixed;
top: 10px;
left: 10px;
z-index: 10000;
padding: 8px 12px;
border-radius: 8px;
background: #ffffff;
color: #1d4ed8;
border: 1px solid rgba(37, 99, 235, 0.38);
transform: translateY(-140%);
}
.skip-link:focus-visible {
transform: translateY(0);
outline: 2px solid rgba(37, 99, 235, 0.56);
outline-offset: 2px;
}
```
Expected:
- Hidden by default.
- Visible only when focused.
Progress note:
- Completed on 2026-05-25 in `shell.css`.
-[x]**Step 3: Confirm nav tab order**
Manual validation:
- Tab order starts at skip link.
- Then window controls if focusable.
- Then sidebar primary navigation.
- Then page/workspace content.
- Then composer or page actions.
Expected:
- No keyboard trap.
- No hidden active control receives focus unless intentionally screen-reader-only.
Progress note:
- Confirmed on 2026-05-25 with browser snapshot: first Tab focuses skip link, Enter moves focus to `main#main-content`, then navigation/content controls remain reachable.
[ERROR] Generate Seedance split video failed with exit code 1. See E:\testworkspace2\projects\douyin\output\分析一下这个文件\video_seedance_stderr.txt | split_error=Seedance clip 1 failed. See E:\testworkspace2\projects\douyin\output\分析一下这个文件\seedance-split-runs\20260427-095752\shots\shot-01\stderr.txt
2. Remote zip bundles are discovered from `skills[].skill.download_url`, downloaded, and extracted.
3. Bundle content is materialized into local project roots plus shared `skills/` and `cron/` content.
4. Materialized projects are registered in local project metadata.
5. Empty inventory does not recreate a local fallback project; chat session creation waits for the first cloud-backed project.
6. Sessions are bound to projects through `ProjectStoreService`.
7.`ProjectContextService` builds and caches project snapshots from `SOUL.md`, `USER.md`, `README.md`, and tracked memory files.
8.`ProjectExecutionRouter` routes each request to one of:
-`workspace-entry`
-`skill`
-`chat-fallback`
9.`ipc.ts` prepares each request against the session's project snapshot before execution.
10. Bundle reconciliation removes stale bundle-managed projects, shared `skills/` entries, shared `cron/` entries, and stale manifest records when the expected cloud bundle set changes.
11. Bundle freshness probes the remote bundle with HTTP metadata before deciding whether an existing local materialization can be reused.
12. Same-`projectId` replacement now stages project/shared assets, commits them in order, and either finalizes or rolls back the whole replacement set.
13. Broader churn coverage now verifies survivor, replacement, removal, and addition flows across multiple projects without changing the current cloud protocol.
## 3. Code-truth execution behavior
Current behavior verified from code:
-`workspace-entry` executes inside the isolated project root.
- aggregates the main project-isolation regression smokes
- now includes reconcile, freshness, replacement, and churn service-level coverage
Electron smoke validation is also stronger now:
- workspace-entry validation no longer assumes the final status label must contain `workspace`
- smoke state records status label history and validates that a workspace-agent phase actually occurred
- smoke action selection now follows the active project session instead of assuming a stable pre-replacement session id
## 5. What is still incomplete
The earlier core gaps are closed.
The main follow-up areas now are:
- deciding whether the `project-isolation-smoke.ps1` and `cloud-bundle-smoke.ps1` gate pair should be wired into broader external CI / release coverage
- expanding deterministic churn coverage into larger or randomized stress matrices only when product changes raise the risk level
- keeping related product and rollout docs aligned with the implementation
- implementing any future protocol migration away from single `skills[].skill.download_url` only when backend is ready
## 6. Recommended next implementation order
1. Keep the current project-isolation smoke set green.
2. Use `project-isolation-smoke.ps1` plus `cloud-bundle-smoke.ps1` as the default higher-level regression gate pair.
3. Expand breadth only when new isolation surfaces or larger multi-project behaviors are introduced.
4. Handle any future `download_url` protocol evolution as a dedicated compatibility task.
## 7. Bottom line
Current status:
- The core project isolation chain is implemented.
- Session and project binding are implemented.
- Cloud-owned inventory enforcement is implemented.
- Project context injection is implemented.
- Cloud zip sync is implemented.
- Default chat refresh is aligned with other project-aware execution paths.
- Stale bundle reconciliation is implemented for bundle-managed cleanup.
- Bundle freshness hardening is implemented and smoke-verified.
- Replacement / rollback hardening is implemented and smoke-verified.
- Multi-project churn coverage is implemented at the service level.
- Remaining work is mostly broader regression breadth, gate wiring, and future protocol evolution.
Cloud returns skill metadata and download URLs, desktop downloads the skill to local cache, chat selection causes Main to project that cached file into OpenClaw's real skill directory, and bundled runtime then executes that local projected skill.
Status: Bundle ingestion, cloud-owned inventory enforcement, freshness hardening, replacement/rollback hardening, broader churn coverage, and lifecycle smoke are implemented
## 1. Product constraints
This plan follows the confirmed product constraints:
- Projects are defined by backend config, not local CRUD.
- The current source payload is `openclaw-employee-config`.
- The active bundle source is `skills[].skill.download_url`.
-`project_bundle_url` is not part of the current implementation.
- Project inventory is fixed by backend configuration.
- The current protocol returns a `skills` array.
- Each `skills[]` object uses one `skill.download_url` string to point at one project zip.
- Multiple projects are currently expressed by multiple `skills[]` objects.
- If the backend later changes to multi-value download URLs, that will be a separate protocol and implementation task.
## 2. What is already implemented
### Cloud bundle ingestion
- Runtime cloud bootstrap and payload update both trigger project bundle sync.
- Zip-backed remote skills are discovered and downloaded.
- Bundles are extracted and normalized.
- Project files are materialized into local project roots.
- Shared bundle `skills/` and `cron/` content is materialized.
- Synced projects are registered in local project metadata.
### Cloud-owned inventory enforcement
- No implicit local `default` project is created when there are no materialized projects.
- Session listing returns `[]` when no active project exists.
- Session creation is blocked with `Waiting for cloud project bundle sync.` until a cloud-backed project arrives.
- The first synced bundle-backed project becomes active cleanly.
### Project-bound execution
- Sessions are bound to projects.
- Each execution is prepared against the session's project.
- Project context snapshots are injected into request preparation.
- The router can choose `workspace-entry`, `skill`, or `chat-fallback`.
-`chat-fallback`, `skill`, and `workspace-entry` all schedule post-execution project context refresh.
### Stale bundle reconciliation
- Sync derives the expected bundle-backed project set from the current payload.
- Bundle-managed projects missing from the expected set are removed locally.
- Bundle-managed shared `skills/` entries missing from the expected set are removed locally.
- Bundle-managed shared `cron/` entries missing from the expected set are removed locally.
- Stale bundle manifest records are pruned.
- If the active bundle project is removed, active project falls back to the remaining valid project set.
### Freshness hardening
- Reuse is no longer assumed from `sourceUrl + configVersion` alone.
- When a manifest record is otherwise reusable, the bundle service performs a `HEAD` probe.
- The probe captures `ETag`, `Last-Modified`, and `Content-Length` when available.
- If those values change, the bundle is re-downloaded and re-materialized.
- If an older manifest lacks freshness identity and the remote now exposes one, the service forces one refresh to establish the baseline.
- Bundle manifest records now persist remote freshness metadata.
### Replacement and rollback hardening
- Bundle installation now follows `stage -> commit -> finalize/rollback`.
- Replacement can swap the project root plus shared `skills/` and `cron/` entries for the same logical `projectId`.
- If replacement fails after commit but before project metadata is fully updated, the previous project root, shared skill entries, and cron entries are restored.
- Recovery on the next sync is verified and keeps manifest ownership aligned with the recovered state.
### Regression smoke coverage
-`workspace-entry-smoke`
-`cloud-bundle-smoke`
-`project-context-refresh-smoke`
-`default-chat-smoke`
-`project-empty-inventory-smoke`
-`project-bundle-reconcile-smoke`
-`project-bundle-freshness-smoke`
-`project-bundle-replacement-smoke`
-`project-bundle-churn-smoke`
-`project-isolation-smoke`
Additional lifecycle coverage now verified:
- cloud bundle smoke covers payload `sync`
- cloud bundle smoke covers cached `init`
- cloud bundle smoke covers same-`projectId` replacement through Electron UI/main flow
- replacement smoke covers service-level rollback injection and recovery on the next sync
-`project-isolation-smoke.ps1` now aggregates reconcile, freshness, replacement, and multi-project churn coverage into the broader project-isolation gate
- Electron smoke validates workspace-agent status history instead of relying on the final status label only
## 5. Important current limitations
### Broad UI regression breadth is still selective
The targeted Electron lifecycle smoke for cloud bundle replacement now exists, but the full UI regression matrix is still intentionally selective rather than exhaustive.
### Stress breadth can still expand
The current replacement and churn coverage is strong for deterministic paths, but future changes may still need larger randomized multi-project stress coverage.
## 6. What has been completed so far
Completed enough to count as real implementation:
- project-bound session model
- cloud-owned inventory enforcement
- project context snapshot model
- cloud zip materialization path
- project-aware execution routing
- default chat refresh alignment with other project-aware paths
- stale bundle-managed cleanup for project/skill/cron/manifest state
- bundle freshness hardening using remote metadata probe
- replacement / rollback hardening for same-project bundle updates
- broader service-level churn coverage for multi-project inventory transitions
- smoke coverage for empty inventory, removal, freshness, replacement, churn, and Electron lifecycle validation
This project is no longer at the design-only stage.
## 7. What should happen next
Recommended next work:
1. Keep the current smoke set green as adjacent runtime work lands.
2. Use `project-isolation-smoke.ps1` plus `cloud-bundle-smoke.ps1` as the main higher-level regression gate pair.
3. Expand breadth only when upcoming product changes introduce new isolation surfaces.
4. If backend protocol changes from single `download_url` to a multi-value form, handle it as a separate compatibility task instead of folding it into unrelated hardening work.
## 8. Final summary
The single-instance plus task-isolation foundation is implemented.
The earlier main gaps around cloud-owned inventory, replacement/rollback hardening, and lifecycle smoke have been closed.
The remaining work is mostly broader regression breadth and future protocol evolution, not missing core behavior.
宿主协议不一样。ing Claude's current work───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────