@whfzgyx/ojo-local-canvas-server
v0.1.3
Published
Local OJO Canvas HTTP server for Codex and workspace-driven canvas previews.
Readme
@whfzgyx/ojo-local-canvas-server
Local OJO Canvas HTTP server for workspace-driven Canvas previews.
This package serves the Canvas frontend, exposes the minimal local /api/server/v1 contracts, watches workspace source changes, builds prototype output, publishes resources into a local data store, and emits local-events / local-version updates for the Canvas frontend.
Install
npm install @whfzgyx/ojo-local-canvas-serverCLI
The server serves multiple workspaces from one process. Directory names are project ids:
ojo-local-canvas-server \
--workspaces-root /absolute/path/to/ojo-workspacesThen open:
http://127.0.0.1:8787/p/<project-id>?mode=codexOpening /p/<project-id> also works; the server redirects to the mode=codex URL required by the Canvas frontend.
Supported flags map to the existing env vars:
--host LOCAL_CANVAS_HOST
--port LOCAL_CANVAS_PORT
--workspaces-root LOCAL_CANVAS_WORKSPACES_ROOT
--canvas-dist LOCAL_CANVAS_CANVAS_DIST
--data-root LOCAL_CANVAS_DATA_ROOT
--watch LOCAL_CANVAS_WATCH
--build-on-start LOCAL_CANVAS_BUILD_ON_STARTThe legacy env-only launch style remains supported.
Node API
import {
loadConfig,
startLocalCanvasServer,
type LocalCanvasConfig,
} from '@whfzgyx/ojo-local-canvas-server';
const config: LocalCanvasConfig = loadConfig({
...process.env,
LOCAL_CANVAS_WORKSPACES_ROOT: '/absolute/path/to/workspaces',
LOCAL_CANVAS_DATA_ROOT: '/absolute/path/to/.local-canvas-data',
});
const server = await startLocalCanvasServer(config);
console.log(server.url);
await server.close();Exports:
createLocalCanvasServer(config?)startLocalCanvasServer(config?)loadConfig(env?)validateConfig(config)LocalCanvasConfig
HTTP Surface
Each project runtime is initialized lazily from LOCAL_CANVAS_WORKSPACES_ROOT/<projectId>.
Key routes:
GET /p/:projectId?mode=codexGET /healthGET /__ojo_canvas_server/healthGET /__ojo_canvas_server/projectsGET /__ojo_canvas_server/projects/:projectId/statusPOST /__ojo_canvas_server/projects/:projectId/reloadPOST /__ojo_canvas_server/projects/:projectId/stopGET /api/server/v1/projects/:projectIdGET /api/server/v1/projects/:projectId/draftPUT /api/server/v1/projects/:projectId/draftGET /api/server/v1/projects/:projectId/prototypesGET /api/server/v1/projects/:projectId/state-page-revisionPOST /api/server/v1/projects/:projectId/state-page-revisionPOST /api/server/v1/projects/:projectId/state-page-revision:generateGET /api/server/v1/projects/:projectId/local-versionGET /api/server/v1/projects/:projectId/local-eventsGET /api/server/v1/projects/:projectId/prototype-dist/:manifestKey/:distPathPOST /api/server/v1/resources/batch-get-metaGET /api/server/v1/local-resources?key=...
canvasDist
By default the npm package serves the bundled Canvas frontend from:
dist/canvas-distThe bundled dist is pruned for local Codex canvas usage. It keeps the assets needed by /p/:projectId?mode=codex and excludes large public assets for unrelated dashboard, landing page, inspire, subscribe, and creation option routes.
canvasDist is still available as an override for local Canvas frontend development, usually:
irise-web-canvas-frontend/apps/canvas/distUse --canvas-dist or LOCAL_CANVAS_CANVAS_DIST only when you intentionally want a different Canvas frontend build than the one bundled in this package.
Build And Refresh Behavior
The package owns:
- HTTP server
- workspace watcher
- install/build/publish pipeline
- resource store
- project state store
local-eventslocal-versionprototype-distserving
When builds succeed, the server updates local project state and emits refresh events consumed by the Canvas frontend. When builds fail, it writes build_status=failed and preserves the previous usable canvas state so the iframe is not refreshed into a broken version.
Ignored watcher paths include generated output such as prototype/dist/**, plus .git/**, node_modules/**, and .local-canvas-data/**. Source changes should go through paths such as prototype/src/**, components/**, prototype config files, package manifests, or lockfiles.
Boundary With ojo-codex-plugin-better
This package is the reusable Canvas Server capability.
It should not contain:
- Codex MCP gateway
- Codex in-app widget resource
- plugin-scoped singleton supervisor
- Codex plugin manifest
- multi-task plugin lifecycle management
ojo-codex-plugin-better should depend on this package, start it through the Node API or CLI, and keep singleton process coordination in the plugin layer.
Next Architecture Step
ProjectRuntimeRegistry / ProjectRuntime live in this package. Plugin-specific MCP/widget/supervisor logic should remain in ojo-codex-plugin-better.
Local Development
npm install
npm run typecheck
npm test
npm run pack:dry-run
npm packDo not publish automatically from CI or local scripts. Run npm publish --access public only after confirming package name, license, access, and release version.
Publishing Checklist
- Confirm package name:
@whfzgyx/ojo-local-canvas-server - Confirm npm scope access for
@whfzgyx - Confirm license before public publish
- Confirm bundled
dist/canvas-distis included in the package file list - Confirm version bump
- Confirm
npm pack --dry-runfile list - Confirm smoke test passes from the generated
.tgz
