mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 10:40:42 +00:00
7.6 KiB
7.6 KiB
summary, read_when, title
| summary | read_when | title | |||
|---|---|---|---|---|---|
| Plan and audit checklist for moving Canvas out of core and into a bundled experimental plugin. |
|
Canvas plugin refactor |
Canvas plugin refactor
Canvas is low-use and experimental. Treat it as a bundled plugin, not a core feature. Core may keep generic gateway, node, HTTP, auth, config, and native-client plumbing, but Canvas-specific behavior should live under extensions/canvas.
Goal
Move Canvas ownership to extensions/canvas while preserving the current paired-node behavior:
- the agent-facing
canvastool is registered by the Canvas plugin - Canvas node commands are allowed only when the Canvas plugin registers them
- A2UI host/source files live under the Canvas plugin
- Canvas document materialization lives under the Canvas plugin
- CLI command implementation lives under the Canvas plugin, or delegates through a plugin-owned runtime barrel
- docs and plugin inventory describe Canvas as experimental and plugin-backed
Non-goals
- Do not redesign the native app Canvas UI in this refactor.
- Do not remove Canvas protocol/client support from iOS, Android, or macOS unless a separate product decision says Canvas should be deleted.
- Do not build a broad plugin service framework only for Canvas unless at least one other bundled plugin needs the same seam.
Current branch state
Done:
- Added bundled plugin package in
extensions/canvas. - Added
extensions/canvas/openclaw.plugin.json. - Moved the agent
canvastool fromsrc/agents/tools/canvas-tool.tstoextensions/canvas/src/tool.ts. - Removed core registration of
createCanvasToolfromsrc/agents/openclaw-tools.ts. - Moved Canvas host implementation from
src/canvas-hosttoextensions/canvas/src/host. - Kept
extensions/canvas/runtime-api.tsas the plugin-owned compatibility barrel for tests, packaging, and external public Canvas helpers. - Moved Canvas document materialization from
src/gateway/canvas-documents.tstoextensions/canvas/src/documents.ts. - Moved Canvas CLI implementation and A2UI JSONL helpers into
extensions/canvas/src/cli.ts. - Moved Canvas host URL and scoped capability helpers into
extensions/canvas/src. - Moved Canvas node command defaults out of hardcoded core lists and into plugin
nodeInvokePolicies. - Added plugin-owned Canvas host config at
plugins.entries.canvas.config.host. - Moved Canvas and A2UI HTTP serving behind Canvas plugin HTTP route registration.
- Added generic plugin WebSocket upgrade dispatch for plugin-owned HTTP routes.
- Replaced Canvas-specific gateway host URL and node capability auth with generic hosted plugin surface and node capability helpers.
- Added plugin-owned hosted media resolvers so Canvas document URLs resolve through the Canvas plugin instead of core importing Canvas document internals.
- Added
api.registerNodeCliFeature(...)so Canvas can declareopenclaw nodes canvasas a plugin-owned node feature without manually spelling the parent command path. - Removed production
src/**imports ofextensions/canvas/runtime-api.js. - Moved the A2UI bundle source from
apps/shared/OpenClawKit/Tools/CanvasA2UItoextensions/canvas/src/host/a2ui-app. - Moved A2UI build/copy implementation under
extensions/canvas/scriptsand replaced root build wiring with generic bundled-plugin asset hooks. - Removed the runtime legacy top-level
canvasHostconfig alias. - Kept the Canvas doctor migration so
openclaw doctor --fixrewrites oldcanvasHostconfigs intoplugins.entries.canvas.config.host. - Removed old-agent Canvas protocol compatibility behind gateway protocol v4. Native clients and gateways now use only
pluginSurfaceUrls.canvasplusnode.pluginSurface.refresh; the deprecatedcanvasHostUrl,canvasCapability, andnode.canvas.capability.refreshpath is intentionally unsupported in this experimental refactor. - Updated generated plugin inventory to include Canvas.
- Added plugin reference docs at
docs/plugins/reference/canvas.md.
Known remaining core-owned Canvas surfaces:
- Native app Canvas handlers under
apps/still intentionally consume the Canvas plugin surface - native app Canvas protocol/client handlers under
apps/ - published artifact output still uses
dist/canvas-host/a2uifor backwards-compatible runtime lookup, but the copy step is now plugin-owned
Target shape
extensions/canvas should own:
- plugin manifest and package metadata
- agent tool registration
- node invoke command policy
- Canvas host and A2UI runtime
- Canvas A2UI bundle source and asset build/copy scripts
- Canvas document creation and asset resolution
- Canvas CLI implementation
- Canvas docs page and plugin inventory entry
Core should own only generic seams:
- plugin discovery and registration
- generic agent tool registry
- generic node invoke policy registry
- generic gateway HTTP/auth and WebSocket upgrade dispatch
- generic hosted plugin surface URL resolution
- generic hosted media resolver registration
- generic node capability transport
- generic config plumbing
- generic bundled-plugin asset hook discovery
Native apps may keep Canvas command handlers as clients of the protocol. They are not the plugin runtime owner.
Migration steps
- Treat
plugins.entries.canvas.config.hostas the plugin-owned config surface. - Update docs so Canvas is described as an experimental bundled plugin.
- Run focused Canvas tests, plugin inventory checks, plugin SDK API checks, and build/type gates affected by runtime boundaries.
Audit checklist
Before calling the refactor complete:
rg "src/canvas-host|../canvas-host"returns no live source imports.rg "canvas-tool|createCanvasTool" srcfinds no core-owned Canvas tool implementation.rg "canvas.present|canvas.snapshot|canvas.a2ui" src/gatewayfinds no hardcoded allowlist defaults outside generic plugin policy tests.rg "extensions/canvas/runtime-api" src --glob '!**/*.test.ts'is empty.rg "canvas-documents" srcis empty.rg "registerNodesCanvasCommands|nodes-canvas" srcis empty; the Canvas plugin registersopenclaw nodes canvasthrough nested plugin CLI metadata.rg "createCanvasHostHandler|handleA2uiHttpRequest" src/gatewayreturns no gateway runtime ownership.rg "apps/shared/OpenClawKit/Tools/CanvasA2UI|canvas-a2ui-copy|extensions/canvas/src/host/a2ui" scripts .github package.jsonfinds only compatibility wrappers or plugin-owned paths.pnpm plugins:inventory:checkpasses.pnpm plugin-sdk:api:checkpasses, or generated API baselines are intentionally updated and reviewed.- Targeted Canvas tests pass.
- Changed-lanes tests pass for Canvas host/A2UI paths.
- PR body explicitly says Canvas is experimental and plugin-backed.
Verification commands
Use targeted local checks while iterating:
pnpm test extensions/canvas/src/host/server.test.ts extensions/canvas/src/host/server.state-dir.test.ts extensions/canvas/src/host/file-resolver.test.ts
pnpm test src/gateway/server.plugin-node-capability-auth.test.ts src/gateway/server-import-boundary.test.ts
pnpm test extensions/canvas/src/config-migration.test.ts src/commands/doctor-legacy-config.migrations.test.ts
pnpm test test/scripts/changed-lanes.test.ts test/scripts/build-all.test.ts extensions/canvas/scripts/bundle-a2ui.test.ts test/scripts/bundled-plugin-assets.test.ts extensions/canvas/scripts/copy-a2ui.test.ts src/infra/run-node.test.ts
pnpm tsgo:extensions
pnpm plugins:inventory:check
pnpm plugin-sdk:api:check
Run pnpm build before push if runtime barrel, lazy import, packaging, or published plugin surfaces change.