@zvada/cr8 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +3 -5
- package/.codex-plugin/mcp.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +18 -15
- package/dist/cr8.mjs +212 -142
- package/docs/user/app-store-screenshots.md +0 -2
- package/docs/user/cli.md +4 -4
- package/docs/user/desktop.md +47 -7
- package/docs/user/feedback.md +5 -1
- package/docs/user/install.md +60 -34
- package/docs/user/mcp.md +47 -17
- package/package.json +12 -5
- package/skills/cr8-design/SKILL.md +2 -2
- package/skills/cr8-design/references/start.md +1 -1
- package/skills/cr8-flows/SKILL.md +3 -3
- package/skills/cr8-flows/references/results.md +2 -2
- package/skills/cr8-flows/references/run.md +1 -1
|
@@ -12,5 +12,3 @@ With MCP, call:
|
|
|
12
12
|
With the CLI, use `cr8 playbooks`, `cr8 playbook app-store`, `cr8 styles --playbook app-store`, and `cr8 style <chosen-style>`.
|
|
13
13
|
|
|
14
14
|
Playbooks define the task methodology and acceptance gate. Style Directions define the composition system: signature visual mass, layout, hierarchy, typography, color, imagery, anti-patterns, and visual checks. CR8 validates both against shared typed contracts and caches responses in process memory only. The installed skill and local design project never persist their bodies, so service updates are available without reinstalling the plugin.
|
|
15
|
-
|
|
16
|
-
`canvas_guide({ topic: "app-store" })` and `cr8 guide --topic app-store` remain backward-compatible aliases for the playbook during migration.
|
package/docs/user/cli.md
CHANGED
|
@@ -73,6 +73,7 @@ Omitting `--sequence` reads the latest session immediately before a mutation. Th
|
|
|
73
73
|
| `serve [--workspace DIR] [--project PATH] [--port N] [--host LOOPBACK] [--open]` | Open one project and serve the loopback canvas; emit JSON readiness with the `port` (and a `note` when the default was busy) and `record`, as `start` does. A workspace with no project is refused with a sentence naming `cr8 start <path>`. |
|
|
74
74
|
| `init PROJECT_PATH [--workspace DIR]` | Create a blank project directory and release it. |
|
|
75
75
|
| `mcp [--transport stdio\|http] [--port N] [--workspace DIR]` | Serve the MCP tools; `http` mounts `/mcp` on the loopback listener for development hosts. |
|
|
76
|
+
| `mcp-connect [--workspace DIR] [--project PATH]` | Recommended host registration: join the unique compatible runtime in the agent session's workspace, or start project-free stdio discovery. Defaults to `CLAUDE_PROJECT_DIR`, then the launch directory. A fixed workspace is optional; multiple live runtimes require an explicit project. |
|
|
76
77
|
| `projects [--workspace DIR]` | List bounded, workspace-relative CR8 projects and identify the active one. With `--workspace` (or `CR8_WORKSPACE`) the catalog is read from disk, so no server needs to run yet. Each ready project held by a live process carries a `session` with its `pid` and `port`. |
|
|
77
78
|
| `open PROJECT_PATH` | Atomically switch to another listed project. |
|
|
78
79
|
| `status` | Answer `url`, the runtime that answered, and summarize artboards, nodes, assets, diagnostics, and the dynamic design-knowledge discovery flow; its data carries `workspaceRoot` and `project` (`path`, `directory`), which project this runtime serves from where, and `mediaConnection`, whether the person's account is connected on this device, which generation needs. |
|
|
@@ -84,7 +85,6 @@ Omitting `--sequence` reads the latest session immediately before a mutation. Th
|
|
|
84
85
|
| `style STYLE_ID` | Load one current visual direction with concrete composition and hierarchy rules. |
|
|
85
86
|
| `materials [--kind icon\|recipe] [--query TEXT]` | Search the bundled named vector icons and small product recipes. Read-only; no open project, runtime connection or network needed. |
|
|
86
87
|
| `material MATERIAL_ID [--key-prefix PREFIX]` | Return ordinary compose drafts in `result.data.composition`, with source attribution. Adapt them and pass them to `compose`; recipes are independent editable copies. The prefix namespaces node, token and text-style keys. |
|
|
87
|
-
| `guide [--topic canvas-foundations\|web-app\|faithful-reproduction\|app-store]` | Backward-compatible alias for loading a legacy-named playbook. |
|
|
88
88
|
| `skills [list]` | List the skills that ship with this CLI: name, description, when to read each, files, and where they live on disk. |
|
|
89
89
|
| `skills get NAME [--path FILE]` | Print a skill's `SKILL.md` as markdown, not JSON, or one file it references such as `agents/openai.yaml`. |
|
|
90
90
|
| `skills path [NAME]` | Print the on-disk skills directory, or one skill's; the compiled binary carries them embedded and refuses with `skills_embedded`. |
|
|
@@ -113,13 +113,13 @@ Omitting `--sequence` reads the latest session immediately before a mutation. Th
|
|
|
113
113
|
| `media-job JOB_ID` | Read a media job by the id `media-create` returned. |
|
|
114
114
|
| `media-download JOB_ID --out FILE [--output N]` | Write a completed media job's output to a file as it came, a clip included, so an agent can look at it or hand it over; `--output` is the 1-based output, the first when left out. |
|
|
115
115
|
| `place (--job JOB_ID [--output N] \| --asset ASSET_ID) [--artboard FRAME_ID] [--fit cover\|contain] [--behind\|--on-top] [--name NAME]` | Put a picture on the design: a completed media job's output (copied into the project with its provider, model and generation ids as provenance) or an asset the project holds (an import), as an image layer in the named root artboard, centred at no more than 80 % of it (`--fit cover` fills it and goes behind what it holds), or in a new artboard to the right of everything. Answers `{ assetId, nodeId, artboardId, created, sequence, file }`. A clip stays on its cloud path. |
|
|
116
|
-
| `media-materialize --src PATH` | Copy
|
|
116
|
+
| `media-materialize --src PATH` | Copy an output into durable project files and return its source and dimensions; does not register an asset or layer. Use `place --job JOB_ID` to put it on the canvas. |
|
|
117
117
|
| `workflow-create (--json JSON\|--file FILE) [--workspace-id ID] [--revision N]` | Create one workflow. The workflow needs an `id` you mint (see `schema --workflow`). `--workspace-id` defaults to the open project's and `--revision` to the catalog's current revision, read just before the request; an explicit stale revision still conflicts. |
|
|
118
118
|
| `workflow-replace WORKFLOW_ID (--json JSON\|--file FILE) [--workspace-id ID] [--revision N]` | Atomically replace one workflow; the path identity must match `workflow.id`. Same defaults. |
|
|
119
119
|
| `workflow-delete WORKFLOW_ID [--workspace-id ID] [--revision N]` | Delete one workflow using optimistic concurrency and a retry-safe request ID. Same defaults. |
|
|
120
120
|
| `workflow-templates` / `workflow-template TEMPLATE_ID` | List the templates a new flow starts from (id, name, what each makes, step count), or read one as a complete placed workflow: fill the brief's `text` (and an asset step's `assetId`), then pass it to `workflow-create`. Neither needs a revision. |
|
|
121
121
|
| `workflow-preflight WORKFLOW_ID [--workspace-id ID] [--revision N]` | Check required inputs, assets, outputs, and deterministic node order without mutating the workflow (the same defaults as the mutations). Answers `ready` (the graph, with `issues`), `executable` with `blockers` (the account: `connection_required` or `connection_expired`, each with a `recovery` naming `cr8 connect --open`), and `steps[]` with each model step's `resolvedPrompt`, the exact text a run sends. |
|
|
122
|
-
| `workflow-run WORKFLOW_ID [--workspace-id ID] [--revision N] [--request-id ID] [--from NODE_ID] [--detach] [--full]` | Execute that exact ready revision (by default the current one) through the media service. The answer is compact: `status`, `runId`, `workflowId`, `workflowRevision`, `failedNodeId` when it failed, `steps[]` (`nodeId`, `status`, and a `message` for a failed or a kept step) and `outputs[]` (`outputNodeId
|
|
122
|
+
| `workflow-run WORKFLOW_ID [--workspace-id ID] [--revision N] [--request-id ID] [--from NODE_ID \| --node NODE_ID] [--detach] [--full]` | Execute that exact ready revision (by default the current one) through the media service. The answer is compact: `status`, `runId`, `workflowId`, `workflowRevision`, `failedNodeId` when it failed, `steps[]` (`nodeId`, `status`, and a `message` for a failed or a kept step) and `outputs[]` (`outputNodeId` and `src`, the managed cloud path for a generated output; `file` is included only for an output already stored in the project). Generated Flow outputs stay on their cloud paths until `workflow-place` copies an image or SVG into the design. `--full` prints the whole answer with every step's artifact and provenance. `--node NODE_ID` runs only that generation node using available upstream results, refuses missing upstream generations without spending, and returns the node’s own output. `--from NODE_ID` starts at one step: it and every step after it run, and a model step before it keeps what the flow last made for it. Reuse the request ID only to recover the same run. |
|
|
123
123
|
| `workflow-run-status WORKFLOW_ID --request-id ID [--workspace-id ID] [--full]` | Where a run started with `--detach` is: the steps visited so far while it runs, or its answer once it ended, compact like `workflow-run`'s unless `--full`. |
|
|
124
124
|
| `workflow-place WORKFLOW_ID [--output NODE_ID] [--artboard FRAME_ID] [--name NAME] [--fit cover\|contain] [--behind\|--on-top] [--all]` | Put what the flow last made on the design: the named output of its last completed run (the first when none is named) becomes a project asset with its generation provenance and an image layer in the named root artboard, or filling a new artboard to the right of everything, named after the output (or `--name`). In a named artboard the layer is centred at up to 80 % of the artboard's width and height, never enlarged; `--fit cover` fills the artboard (the image cropped to it) and `--fit contain` scales it to the largest size that fits inside, centred. Answers `assetId`, `nodeId`, `artboardId`, `created`, the design's `sequence` and `file`, the workspace-relative path the asset is kept at. `--all` places every output of the run on one new review artboard named `<flow name> · review` (or `--name`), side by side at one height with a small gap, to the right of everything, and answers `artboardId`, `created`, the board's `x`, `y`, `width` and `height` (so an agent lays its own artboards clear of it), `sequence` and `placed[]` (`outputNodeId`, `assetId`, `nodeId`, `file`), with `skipped[]` for clips. Idempotent: an output already placed there, or a review board of that name already holding every output, answers `created: false` and adds nothing; an asset the project holds is shown again, never copied twice. A clip is refused on its own, since it stays in Flows. A `--fit cover` placement goes behind what the artboard already holds (it is the background); `--behind` does so for any placement and `--on-top` keeps a cover placement above. |
|
|
125
125
|
| `exec --command JSON` | Send a command object from the published schema. |
|
|
@@ -231,7 +231,7 @@ Exit codes are `1` for invalid/unavailable/rejected work, `2` for diagnostics, `
|
|
|
231
231
|
|
|
232
232
|
## Media
|
|
233
233
|
|
|
234
|
-
There are two ways to make media. `generate` runs a product preset (`auto`, `fast`, `quality`, `vector`) and places the output on the canvas in one call; CR8 chooses the model behind it. `generate --model ID` with an image or vector model id from `media-models` runs that model and places its output the same way; a model that takes no prompt, such as an upscaler, needs `--node` and no `--prompt`. `media-create --model ID` runs any model of the registry, including direct provider bindings and the video and enhancement models; it prints the job envelope (`status`, `result.outputs` on their cloud paths, or `error`), and
|
|
234
|
+
There are two ways to make media. `generate` runs a product preset (`auto`, `fast`, `quality`, `vector`) and places the output on the canvas in one call; CR8 chooses the model behind it. `generate --model ID` with an image or vector model id from `media-models` runs that model and places its output the same way; a model that takes no prompt, such as an upscaler, needs `--node` and no `--prompt`. `media-create --model ID` runs any model of the registry, including direct provider bindings and the video and enhancement models; it prints the job envelope (`status`, `result.outputs` on their cloud paths, or `error`), and an image or SVG reaches the canvas through `place --job JOB_ID`, which copies its bytes, registers the asset and places its layer in one retryable transaction. Prefer `generate` for a quick artboard from a prompt or a reference, and `media-create` when the model, its parameters or its category matter. `media-models` lists the registry as summaries: each model's id, its task (`generate`, `edit`, `enhance`, `utility`), whether an image is `required` or `optional`, the `choices` it narrows (the ratios, durations, resolutions and scales it makes where fewer than the vocabulary's, and whether a seed may be set) and one line; `--full` prints each model's `inputSchema` and metadata instead. `media-model ID` prints one model in full, and `media-job ID` reads a job back. The registry spans image generation, editing, enhancement and utilities, vector generation and video generation; a video job's output is an MP4 on its cloud path. Model inputs use the model's own vocabulary (`prompt`, `count`, `aspect_ratio`, `image`, `seed`) as published in the schema; a project asset is named in the `image` field as `{ "assetId", "src" }` and ingested before the job starts.
|
|
235
235
|
|
|
236
236
|
The CLI calls the server-side provider-neutral media boundary through the running project process. Connect the account once, from the canvas, with `cr8 connect --open`, or through an agent's `canvas_connect`; CLI and MCP requests then share the short-lived, device-bound grant kept in your configuration directory (see [install](install.md#accounts-and-ai-media)), whatever project is open. A generation the account blocks answers `connection_required` or `connection_expired`, with the recovery in `details.blockers`. `CR8_MEDIA_API_URL` and `CR8_MEDIA_API_TOKEN` remain operator-only overrides for private deployments, not user installation settings.
|
|
237
237
|
|
package/docs/user/desktop.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# CR8 desktop
|
|
1
|
+
# CR8 desktop
|
|
2
2
|
|
|
3
3
|
The desktop build is an optional window around the same loopback CR8 runtime used by the browser, CLI, and MCP integration. It does not own another document database, copy project files into an Electron profile, or replace the agent-facing installation. The browser, CLI, and MCP installation remain fully usable without Electron.
|
|
4
4
|
|
|
5
5
|
## Runtime model
|
|
6
6
|
|
|
7
7
|
1. The main process resolves one explicit workspace and design project.
|
|
8
|
-
2. It spawns `cr8 serve` from the bundled runtime on an ephemeral loopback port, or attaches to a runtime that already holds the project's lease (the lease records the listener port).
|
|
8
|
+
2. It spawns `cr8 serve --mcp --managed` from the bundled runtime on an ephemeral loopback port, or attaches to a runtime that already holds the project's lease (the lease records the listener port).
|
|
9
9
|
3. Electron loads that exact `http://127.0.0.1:<port>` URL. Opening the printed URL in a normal browser shows the same running session. On macOS the window hides its title bar and the page's own top bar is the drag region, with room for the traffic lights; other platforms keep their native frame.
|
|
10
|
-
4. The project remains the normal portable `cr8.json`, optional `flows.json`, and content-addressed `assets/`. Closing
|
|
10
|
+
4. The project remains the normal portable `cr8.json`, optional `flows.json`, and content-addressed `assets/`. Closing a window releases its presence. A managed runtime stays alive while a desktop, launcher-backed agent or browser is connected, and closes after a short grace period once the last client leaves. An externally owned runtime remains controlled by its original host.
|
|
11
11
|
|
|
12
|
-
The
|
|
12
|
+
The canvas has no preload bridge. A bundled setup view inside that same native window has a narrow, validated IPC bridge for choosing folders and configuring agent connections; it is never exposed to the editor, MCP App or account hub. Renderer Node integration and webviews are disabled, context isolation and Chromium sandboxing are enabled, and permissions are denied. Project switching updates the one trusted loopback origin to the runtime's exact active URL; stale or unrelated loopback ports remain blocked. Navigation and popup creation stay inside that origin, except that an AI-media connection URL on the configured HTTPS account origin is opened in the system browser while the CR8 window remains local.
|
|
13
13
|
|
|
14
14
|
## Selecting a project
|
|
15
15
|
|
|
@@ -21,9 +21,37 @@ The desktop executable accepts:
|
|
|
21
21
|
--project <path> Workspace-relative directory containing cr8.json
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
The equivalent environment variables are `CR8_CWD`, `CR8_WORKSPACE`, and `CR8_PROJECT`. Command-line values win. Any other switch (for example `--remote-debugging-port=9333` or `--disable-gpu`) is left to Electron and Chromium. If `--project` is omitted
|
|
24
|
+
The equivalent environment variables are `CR8_CWD`, `CR8_WORKSPACE`, and `CR8_PROJECT`. Command-line values win. Any other switch (for example `--remote-debugging-port=9333` or `--disable-gpu`) is left to Electron and Chromium. If `--project` is omitted and the workspace itself is not a project, CR8 offers Create/Open instead of guessing among designs or using a global recent-file database.
|
|
25
25
|
|
|
26
|
-
The
|
|
26
|
+
The local runtime owns the project's single-writer lease. CLI agent commands can target its loopback URL. Design and Flows share that runtime while scene sequence and workflow revision remain independent.
|
|
27
|
+
|
|
28
|
+
## First launch and agent setup
|
|
29
|
+
|
|
30
|
+
First launch offers a skippable questionnaire and optional agent setup, then opens the workspace without creating a file. Canvas offers **New file** and **Open canvas** afterward. Creation asks for a name and workspace folder, then creates `designs/<name>/cr8.json` through the canonical initializer. Cancel creates nothing. Local editing needs no account, system Node, npm or separate skills.
|
|
31
|
+
|
|
32
|
+
The agent screen connects **Claude Code** or **Codex**. Connect uses the installed host CLI to add one user-level `cr8-desktop` entry pointing to CR8's stable launcher, with no fixed workspace, project or launch directory. The agent does not need to be running: setup only uses its CLI administration commands. It preserves unrelated configuration and refuses duplicate CR8 integrations. If the CLI isn't found, choose **Locate CLI…** or continue without it. **Copy setup prompt** offers the same server definition for agent-assisted setup. Configuration saved and a live agent handshake are different states; restart an existing agent session to load a new registration. A saved choice doesn't trigger sign-in or an agent turn.
|
|
33
|
+
|
|
34
|
+
Return through **CR8 → Settings…** on macOS or **File → Settings…** on Windows/Linux (⌘, / Ctrl+,), then choose **Agents · MCP**. Setup works before choosing a workspace or design. Each new agent session supplies its own project folder through `CLAUDE_PROJECT_DIR` or its launch directory. CR8 joins that workspace's unique compatible runtime, or starts without a design and waits for an explicit file choice. Settings is an in-place dashboard section with the Canvas/Flows/Settings sidebar. **Back to editor** returns to the mounted editor, preserving selection, undo, and Flow drafts. Disconnect removes only an entry still matching the configuration CR8 created; if it changed externally, use the agent's settings instead. Switching repositories does not require reconnecting; project switching within a running session remains canonical `canvas_open`.
|
|
35
|
+
|
|
36
|
+
The launcher lives in desktop-owned application data under `agent/` and is refreshed when the app opens, so normal app replacement preserves host configuration. It launches the bundled engine with the desktop window closed, joining a compatible live project runtime or starting one lazily. A moved app is repaired by opening it at its new location. Restart active agent sessions to adopt an updated runtime; version mismatch fails with an actionable message rather than replacing a running writer. The npm/plugin install remains independent. Existing externally owned or older stdio sessions keep their original agent connection and lifetime.
|
|
37
|
+
|
|
38
|
+
**File → New Canvas…** opens the creation surface; **File → Open Project Folder…** opens an existing project. Setup preferences record completion, owned connections, and the explicitly chosen workspace folder. They never store project contents or an auto-open last design. Opening another project reuses the native window without relaunching the app. An attached runtime supplies the trusted account origin through `/health`.
|
|
39
|
+
|
|
40
|
+
**Settings → Account** shows the device’s actual media identity, connection status, sign-in/reconnect, account management, and device sign-out. It works before any design is open through the bundled runtime’s canonical media connection endpoints. Account sign-in opens the trusted account hub in the browser. Credentials stay in the runtime; Settings receives only the public status. Local editing remains available while signed out. No usage or billing values are invented.
|
|
41
|
+
|
|
42
|
+
## Canvas, Flows and Settings
|
|
43
|
+
|
|
44
|
+
The desktop has one workspace dashboard with exactly **Canvas**, **Flows**, and **Settings** in its sidebar. There is no Home section. **Canvas** lists recent canvas files with real artwork thumbnails, search, and explicit workspace selection. **Flows** lists recent saved flows across those same project files, with separate Recent flows and Templates tabs. Both sections work before an editor is open and read the canonical bounded, symlink-safe project catalog without starting a runtime or maintaining another file database.
|
|
45
|
+
|
|
46
|
+
Click a file to open its canvas, or a saved flow to open its owning project and graph. A template asks whether to use an existing project or create a named project file, then opens an editable draft. Save commits it to the project’s `flows.json`. The editor occupies the full window without the dashboard sidebar. **Files**, **Flows**, and **Settings** controls return to the respective dashboard section; **Back to editor** resumes the mounted editor without losing work.
|
|
47
|
+
|
|
48
|
+
Settings is a page in this dashboard, never a modal over the canvas. A normal launch after onboarding returns to the Canvas section in the chosen workspace without auto-opening a last document. Explicit `--project` launches still open that canvas directly. Browser and MCP App product names are **Canvas** and **Flows**; protocol identifiers remain compatible.
|
|
49
|
+
|
|
50
|
+
## Manual MCP and command-line setup
|
|
51
|
+
|
|
52
|
+
**Settings → Agents · MCP → Manual MCP setup** shows selectable, syntax-highlighted JSON using the same stable launcher as Connect. Merge that entry into the client's user settings; different client formats use the same command and arguments. The per-agent **Copy setup prompt** handles those host-specific instructions. Copying does not modify a host. **Refresh connections** checks changes made outside CR8. If a client cannot provide its project folder, add an explicit `--workspace /absolute/path` in its configuration.
|
|
53
|
+
|
|
54
|
+
**Settings → Command line** provides a copyable invocation of the full bundled CLI under the desktop’s application data `bin/cr8` (`bin/cr8.cmd` on Windows, shown for PowerShell). The command initially runs `--help`; replace that argument with a CR8 command and target a workspace explicitly when needed. It works without system Node or npm and follows app replacement, just like the MCP launcher. CR8 does not edit shell profiles or add itself to PATH. The independent `npx @zvada/cr8` route remains available and never installs Electron.
|
|
27
55
|
|
|
28
56
|
## Development and packaging
|
|
29
57
|
|
|
@@ -40,4 +68,16 @@ Run the built wrapper with Electron and explicit project arguments:
|
|
|
40
68
|
npx electron dist/desktop/main.mjs --workspace "$PWD" --project designs/example
|
|
41
69
|
```
|
|
42
70
|
|
|
43
|
-
`packages/desktop/electron-builder.yml` packages the bundled main process and unpacks `dist/cr8.mjs` beside the asar so Node can run it. `npm run build:desktop` builds the runtime and main process before invoking Electron Builder. The release workflow signs and notarizes the macOS build when the Apple secrets are configured, ships Windows unsigned until a certificate is chosen, and attaches every installer to the GitHub release. The app does not
|
|
71
|
+
`packages/desktop/electron-builder.yml` packages the bundled main process and unpacks `dist/cr8.mjs` beside the asar so Node can run it. `npm run build:desktop` builds the runtime and main process before invoking Electron Builder. The release workflow signs and notarizes the macOS build when the Apple secrets are configured, ships Windows unsigned until a certificate is chosen, and attaches every installer to the GitHub release. Local packaging always passes `--publish never`. The app does not check for or install desktop updates: replace it with a newer download and restart. npm updates affect only the npm installation, not this app. GitHub downloads currently require access to the private repository.
|
|
72
|
+
|
|
73
|
+
## Verification
|
|
74
|
+
|
|
75
|
+
`npm run test:desktop` runs the native macOS onboarding test against built assets: one native window from onboarding through canvas, workspace dashboard search and navigation, Canvas/Flows switching, Settings before a design exists, copied CLI execution without system Node, copied MCP configuration and handshake, cancel/create, actual host CLI registration in isolated configuration directories when those CLIs are installed, launcher MCP handshake, shared edits, desktop restart, one-step human undo after returning from the dashboard/Settings, project opening without relaunch, and removal of owned host entries. It uses Playwright's default Electron loader. `npm run test:install` verifies the separately packed command product. Other platforms still require their native installed-artifact checks before release.
|
|
76
|
+
|
|
77
|
+
Canvas file cards use the canonical renderer and local project assets, with a bounded disposable memory cache. Empty canvases and unavailable previews are labeled. Refreshing previews never changes the active project.
|
|
78
|
+
|
|
79
|
+
The dashboard uses neutral dark surfaces, soft hairlines, and original illustrated product icons generated through `designs/cr8-product-icons/flows.json`. Icon provenance is recorded in `packages/editor/src/workspace/icons/provenance.json`. Krea was used as a visual reference; its artwork is not bundled.
|
|
80
|
+
|
|
81
|
+
The local browser and desktop load the same workspace screens from `packages/editor/src/workspace`, including Canvas, Flows, Settings and onboarding. Inter typography and interface styles are shared with the editor. Electron contributes native folder dialogs, its bundled CLI and explicit agent registration; browser Settings provides manual MCP configuration and the npx command. The browser stays bound to the workspace of its local runtime. Opening Settings preserves the mounted editor and Flow draft in both hosts. The public account website remains a separate account-only build.
|
|
82
|
+
|
|
83
|
+
For a browser session started from the CLI, include `--mcp` in the start command to enable agent connections. Browser Settings offers per-agent setup prompts and a version-matched `npx … mcp-connect` configuration without a fixed workspace. When the agent runs in the browser's workspace, it follows the unique live runtime across design switches and reconnects. If multiple runtimes are open there, add `--project designs/name` to select one explicitly.
|
package/docs/user/feedback.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Feedback for CR8
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use the feedback button in the bottom-right corner of any CR8 screen to suggest a feature, report a problem, or share other feedback. The same form is available in the local browser, desktop, account hub, onboarding and embedded MCP App, without requiring sign-in or an open project. Closing the form preserves its draft in the current view; reloading the page clears it.
|
|
4
|
+
|
|
5
|
+
Only clicking **Send feedback** sends a report to HiveNet. Human reports are marked `author: "human"` and contain the message, feedback type, CR8 version and an opaque submission ID. They include no account identity, project content, screenshots, paths, cookies or referrer. Sending requires internet access; failures preserve the draft and an unchanged retry reuses its submission ID to prevent duplicate reports. There is no background outbox or automatic retry.
|
|
6
|
+
|
|
7
|
+
The CLI and MCP also send actionable product reports to [HiveNet](https://hivenet.app), for agents or people working on CR8 or using its installed tools and docs.
|
|
4
8
|
|
|
5
9
|
Feedback is always an explicit external write. An agent must state what it is sending before it submits; CR8 never reports usage, failures, prompts, canvas content, or ambient context automatically.
|
|
6
10
|
|
package/docs/user/install.md
CHANGED
|
@@ -3,47 +3,52 @@
|
|
|
3
3
|
CR8 is one local process. It serves the Design and Flows workspace to your browser, speaks MCP to an agent, and answers a JSON CLI. It creates no daemon and no document until you ask for one. Projects live in your repositories; the hosted account hub only signs you in for AI media.
|
|
4
4
|
|
|
5
5
|
> [!IMPORTANT]
|
|
6
|
-
> CR8 is proprietary software under the terms in the repository's `LICENSE`: install and use it, do not copy, modify or redistribute it.
|
|
6
|
+
> CR8 is proprietary software under the terms in the repository's `LICENSE`: install and use it, do not copy, modify or redistribute it.
|
|
7
7
|
|
|
8
|
-
## From
|
|
8
|
+
## From npm
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
git clone https://github.com/zvadaadam/baby-canva.git "$HOME/.cr8"
|
|
14
|
-
cd "$HOME/.cr8"
|
|
15
|
-
npm ci && npm run build:package
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
That builds `dist/cr8.mjs`: the MCP server, the CLI, the browser workspace and the MCP App in one file. Put it on your path however you like; the rest of this page writes `cr8` and means `node "$HOME/.cr8/dist/cr8.mjs"`.
|
|
19
|
-
|
|
20
|
-
## From npm (after the first release)
|
|
10
|
+
Requires Node.js 20.19 or newer; use a currently supported Node LTS release. This route is public and does not require access to the source repository.
|
|
21
11
|
|
|
22
12
|
```bash
|
|
23
13
|
npx @zvada/cr8 start designs/first
|
|
24
14
|
```
|
|
25
15
|
|
|
26
|
-
That single command creates the project when it does not exist, serves it on a loopback port and opens your browser. The same binary is the MCP server and the CLI; install it once with `npm install -g @zvada/cr8` if you would rather not type `npx`.
|
|
16
|
+
That single command creates the project when it does not exist, serves it on a loopback port and opens your browser. The same binary is the MCP server and the CLI; install it once with `npm install -g @zvada/cr8` if you would rather not type `npx`. The rest of this page writes `cr8` and means whichever install you chose.
|
|
17
|
+
|
|
18
|
+
## A release binary
|
|
27
19
|
|
|
28
|
-
|
|
20
|
+
The source repository is private: its GitHub release pages and assets require repository access. Publishing a release there does **not** make the downloads public. Until a public download channel is available, use npm on other computers.
|
|
29
21
|
|
|
30
|
-
|
|
22
|
+
For people with repository access, each release carries one executable per platform and a `SHA256SUMS.txt`:
|
|
31
23
|
|
|
32
24
|
| File | For |
|
|
33
25
|
| --- | --- |
|
|
34
|
-
| `cr8-darwin-arm64.zip` | Apple silicon Macs
|
|
35
|
-
| `cr8-darwin-x64.zip` | Intel Macs
|
|
26
|
+
| `cr8-darwin-arm64-unsigned.zip` | Apple silicon Macs |
|
|
27
|
+
| `cr8-darwin-x64-unsigned.zip` | Intel Macs |
|
|
36
28
|
| `cr8-linux-x64.tar.gz`, `cr8-linux-arm64.tar.gz` | Linux |
|
|
37
29
|
| `cr8-windows-x64.zip` | Windows |
|
|
38
30
|
|
|
39
31
|
Check the download before you run it, then start:
|
|
40
32
|
|
|
41
33
|
```bash
|
|
42
|
-
shasum -a 256 -
|
|
43
|
-
|
|
34
|
+
shasum -a 256 cr8-darwin-arm64-unsigned.zip
|
|
35
|
+
# Compare the printed hash with this archive’s entry in SHA256SUMS.txt.
|
|
36
|
+
unzip cr8-darwin-arm64-unsigned.zip && ./cr8-darwin-arm64 start designs/first
|
|
44
37
|
```
|
|
45
38
|
|
|
46
|
-
The binary needs no Node.js.
|
|
39
|
+
The binary needs no Node.js. The macOS archives end in `-unsigned` today, because no signing certificate is configured yet; Gatekeeper refuses them until you allow them in System Settings, and a signed release is the fix, not a habit. They lose the suffix once a certificate is set. GitHub attests a build only for a public repository, so while this one is private a release ships its checksums alone.
|
|
40
|
+
|
|
41
|
+
## From source
|
|
42
|
+
|
|
43
|
+
You need repository access, Git and Node.js 20.19 or newer.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git clone https://github.com/zvadaadam/baby-canva.git "$HOME/.cr8"
|
|
47
|
+
cd "$HOME/.cr8"
|
|
48
|
+
npm ci && npm run build:package
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
That builds `dist/cr8.mjs`: the MCP server, the CLI, the browser workspace and the MCP App in one file. Put it on your path however you like; installed this way, `cr8` on this page means `node "$HOME/.cr8/dist/cr8.mjs"`.
|
|
47
52
|
|
|
48
53
|
## Start a project
|
|
49
54
|
|
|
@@ -57,31 +62,52 @@ cr8 start --no-open # serves without opening a browser; the answer carries
|
|
|
57
62
|
|
|
58
63
|
## Add it to an agent
|
|
59
64
|
|
|
60
|
-
The agent host owns the process: it starts CR8 when
|
|
65
|
+
Use an agent host that supports MCP `2026-07-28`; CR8 rejects older protocol handshakes. The agent host owns the process: it starts CR8 when needed and stops it when the session ends. Do not start a separate server for the agent.
|
|
61
66
|
|
|
62
67
|
**Codex**
|
|
63
68
|
|
|
64
69
|
```bash
|
|
65
|
-
codex mcp add cr8 -- cr8 mcp
|
|
70
|
+
codex mcp add cr8 -- npx -y @zvada/cr8@0.3.0 mcp-connect
|
|
66
71
|
```
|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
This saves a user-level connection available across projects. CR8 uses the directory where the host launches it. Ask it: *Initialize CR8 at `designs/thumbnail` and create a 1280 × 720 YouTube thumbnail. Keep every layer editable and show me the canvas.*
|
|
69
74
|
|
|
70
75
|
**Claude Code**
|
|
71
76
|
|
|
72
77
|
```bash
|
|
73
|
-
claude mcp add --transport stdio --scope user cr8 -- cr8 mcp
|
|
78
|
+
claude mcp add --transport stdio --scope user cr8 -- npx -y @zvada/cr8@0.3.0 mcp-connect
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Claude Code exposes its project directory to the server. Once the repository is public the plugin marketplace is the shorter road: `/plugin marketplace add zvadaadam/baby-canva`, then `/plugin install cr8`.
|
|
82
|
+
|
|
83
|
+
**Manual setup.** Add this to the host's user-level MCP settings, adapting the syntax for hosts such as Codex that use TOML:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"cr8": {
|
|
89
|
+
"command": "npx",
|
|
90
|
+
"args": ["--yes", "@zvada/cr8@0.3.0", "mcp-connect"]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
74
94
|
```
|
|
75
95
|
|
|
76
|
-
|
|
96
|
+
Keep the launch directory dynamic. CR8 follows `CLAUDE_PROJECT_DIR` or the host's launch directory, joins that workspace's unique compatible runtime, and waits for an explicit file choice when none is running. Clients that cannot supply their project folder can add `--workspace /absolute/path/to/workspace`; multiple live runtimes in that folder require an explicit `--project designs/name`. Installation creates no design files. The npm version is pinned to match the running editor and bundled guidance; update the saved version when upgrading CR8.
|
|
77
97
|
|
|
78
|
-
|
|
98
|
+
The repository's `.mcp.json` is for a built source checkout; copying it alone into another project will not install its `dist/cr8.mjs`. The installable Claude and Codex plugins use the same `mcp-connect` behavior. The Codex plugin resolves its bundled runtime from the plugin's installation directory.
|
|
79
99
|
|
|
80
100
|
Use `/mcp` to diagnose a host, and `codex mcp remove cr8` or `claude mcp remove cr8` to take it out.
|
|
81
101
|
|
|
102
|
+
## Desktop and browser sessions
|
|
103
|
+
|
|
104
|
+
The desktop installer already includes Electron, the CR8 runtime, MCP App and embedded skills. First launch offers an optional questionnaire and agent setup before opening the workspace. **Connect** in onboarding or **Settings → Agents · MCP** uses the installed Claude Code or Codex CLI to add a user-level connection. No agent chat, chosen folder, design, or account is required. It points to a stable bundled launcher, works with the desktop closed, and survives normal app replacement. Setup preserves existing integrations and can remove its own unchanged entries. Saved configuration and a live connection have separate status.
|
|
105
|
+
|
|
106
|
+
Browser Settings offers **Copy setup prompt** for each agent and syntax-highlighted manual configuration. The prompts use the same server definition and ask the agent to preserve other integrations. The browser cannot register a native host directly. For collaboration with a human browser session, run `cr8 start designs/first --mcp`; the standard `mcp-connect` registration discovers it in the agent's workspace. Its `mcpUrl` is also available for hosts using a direct, session-specific Streamable HTTP connection.
|
|
107
|
+
|
|
82
108
|
## Skills
|
|
83
109
|
|
|
84
|
-
Three skills ship with CR8, in the package's `skills/` directory: `cr8-design` for design work on a canvas, `cr8-flows` for building and running flows, and `cr8-feedback` for reporting. Each is a `SKILL.md` with an `agents/openai.yaml` beside it. The same text is embedded in the runtime: the MCP server hands it out through `
|
|
110
|
+
Three skills ship with CR8, in the package's `skills/` directory: `cr8-design` for design work on a canvas, `cr8-flows` for building and running flows, and `cr8-feedback` for reporting. Each is a `SKILL.md` with an `agents/openai.yaml` beside it. The same text is embedded in the runtime: the MCP server hands it out through `list_skills` and `read_skill`, or the Skills extension (`skills/list`, `skills/get` and `resources/read`), and the CLI through `cr8 skills get NAME`, so what an agent reads always matches the version it runs. Each is a short `SKILL.md` contract plus a `references/` folder the contract lists at its end (the flows skill's `references/models.md` is the guide to which model does which job); the hosts read the folder whole, and `cr8 skills get NAME --path references/<file>` prints one reference.
|
|
85
111
|
|
|
86
112
|
To put them where the hosts look:
|
|
87
113
|
|
|
@@ -115,7 +141,7 @@ your-repository/
|
|
|
115
141
|
├── flows.json # created after the first saved flow
|
|
116
142
|
├── flow-runs.json # what each flow last made, created after the first run
|
|
117
143
|
├── assets/
|
|
118
|
-
│ └── sha256-….webp # imports, Design generations and
|
|
144
|
+
│ └── sha256-….webp # imports, Design generations and placed Flow outputs
|
|
119
145
|
├── .gitignore
|
|
120
146
|
└── .cr8/
|
|
121
147
|
├── session.json
|
|
@@ -125,11 +151,11 @@ your-repository/
|
|
|
125
151
|
|
|
126
152
|
- `cr8.json` is the strict, versioned, human-readable project envelope.
|
|
127
153
|
- `flows.json` holds the project's flows, with its own revision because flow edits are not scene history.
|
|
128
|
-
- `flow-runs.json` holds the last run of each flow: how it ended and what it made,
|
|
129
|
-
- `assets/` holds immutable content-addressed imports, Design generations and
|
|
154
|
+
- `flow-runs.json` holds the last run of each flow: how it ended and what it made, including managed cloud paths for generated outputs. The Flows library and graph read this metadata; viewing cloud outputs requires network access and a connected CR8 account.
|
|
155
|
+
- `assets/` holds immutable content-addressed imports, Design generations and Flow outputs explicitly placed into the design. Scene documents store relative `assets/…` paths, so saved designs survive moves and clones and render offline.
|
|
130
156
|
- `.cr8/` holds disposable coordination state. The generated `.gitignore` excludes it.
|
|
131
157
|
|
|
132
|
-
Commit `cr8.json`, `flows.json` and `flow-runs.json` when present, `assets/` and `.gitignore` when you want Git history: a clone
|
|
158
|
+
Commit `cr8.json`, `flows.json` and `flow-runs.json` when present, `assets/` and `.gitignore` when you want Git history: a clone contains the saved designs, flows and their last-run metadata. Unplaced generated Flow outputs remain in the cloud. Nothing global decides which repository an agent edits.
|
|
133
159
|
|
|
134
160
|
Older projects that still carry `.relay/session.json` migrate on open; the new file is written beside the old one, which is preserved.
|
|
135
161
|
|
|
@@ -145,7 +171,7 @@ Three roads ask for the account, and all end on the same page:
|
|
|
145
171
|
- The CLI: `cr8 connect --open` prints the sign-in URL, opens it and waits until you have signed in; `cr8 status` reports the connection as `mediaConnection`, and `cr8 disconnect` forgets the grant.
|
|
146
172
|
- An agent: when a generation answers that the account is not connected, it calls `canvas_connect` and gives you the URL to open. It never asks for your credentials.
|
|
147
173
|
|
|
148
|
-
Every generation is recorded in the media Worker's catalog with its provider, model, prompt, parameters and source. A Design generation is downloaded, validated and written into the project's asset directory before the scene may reference it,
|
|
174
|
+
Every generation is recorded in the media Worker's catalog with its provider, model, prompt, parameters and source. A Design generation is downloaded, validated and written into the project's asset directory before the scene may reference it, while Flow outputs stay on managed cloud paths until Add to Design copies an image or SVG into the project. Clips stay in Flows. Losing the network stops new generations; it does not stop a design from opening.
|
|
149
175
|
|
|
150
176
|
## Updating
|
|
151
177
|
|
|
@@ -155,6 +181,6 @@ From npm: run `npx @zvada/cr8@latest` or `npm install -g @zvada/cr8@latest`. Fro
|
|
|
155
181
|
cd "$HOME/.cr8" && git pull --ff-only && npm ci && npm run build:package
|
|
156
182
|
```
|
|
157
183
|
|
|
158
|
-
|
|
184
|
+
The MCP examples above pin a version: installing a newer global CLI does not update those pins. Remove and re-add that host entry with the chosen version, then restart the agent session. Update a plugin through its host and refresh any separately copied skills with that version’s `cr8 skills install --force`. Projects stay outside the installation directory; opening one in a newer runtime can still migrate its format, so keep a project backup before major upgrades. The desktop app does not update itself; see the [desktop wrapper](desktop.md).
|
|
159
185
|
|
|
160
186
|
See the [local-first decision](../decisions/2026-08-15-local-first-install.md), the [MCP App](mcp.md), the [CLI guide](cli.md) and the [desktop wrapper](desktop.md). Releases themselves are described in [the release runbook](../operations/release.md).
|
package/docs/user/mcp.md
CHANGED
|
@@ -10,7 +10,7 @@ The MCP server calls the canonical command executor directly. It does not shell
|
|
|
10
10
|
|
|
11
11
|
The embedded App treats the runtime's document as canonical. Human edits that have not reached the runtime yet stay in memory while the App session is mounted; nothing is written to browser storage, so opening a different workspace cannot leak stale canvas state across sessions.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Install from npm
|
|
14
14
|
|
|
15
15
|
Node.js 20.19 or newer:
|
|
16
16
|
|
|
@@ -18,37 +18,38 @@ Node.js 20.19 or newer:
|
|
|
18
18
|
{
|
|
19
19
|
"mcpServers": {
|
|
20
20
|
"cr8": {
|
|
21
|
-
"command": "
|
|
21
|
+
"command": "npx",
|
|
22
22
|
"args": [
|
|
23
|
-
"
|
|
24
|
-
"
|
|
23
|
+
"--yes",
|
|
24
|
+
"@zvada/cr8@latest",
|
|
25
|
+
"mcp-connect"
|
|
25
26
|
]
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
The default stdio transport writes no readiness output because stdout belongs to MCP.
|
|
32
|
+
The default stdio transport writes no readiness output because stdout belongs to MCP. npm downloads the bundled runtime, which includes the CLI, local canvas, MCP App and matching skills. For a controlled rollout, replace `@latest` with a specific released version. See [agent setup](install.md#add-it-to-an-agent) for Codex and Claude Code commands.
|
|
32
33
|
|
|
33
|
-
Installation creates no document and starts no browser. `canvas_init` or `canvas_open` receives an explicit workspace-relative directory. The workspace is, in order, an explicit `--workspace /absolute/root`, the
|
|
34
|
+
Installation creates no document and starts no browser. `canvas_init` or `canvas_open` receives an explicit workspace-relative directory. The workspace is, in order, an explicit `--workspace /absolute/root`, `CLAUDE_PROJECT_DIR`, then the directory where the host launches CR8. The home directory and filesystem root are refused, including through symlinks. Hosts that launch outside the intended project must configure `--workspace`; CR8 does not request the deprecated MCP roots API. Absolute project paths, parent escapes and symlink escapes fail closed.
|
|
34
35
|
|
|
35
|
-
After a project opens, the same MCP process lazily starts its loopback human canvas and returns `canvasUrl`.
|
|
36
|
+
After a project opens, the same MCP process lazily starts its loopback human canvas and returns `canvasUrl`. `mcp-connect` joins a compatible runtime already open in the session's workspace. Server credentials never belong in an end-user MCP snippet.
|
|
36
37
|
|
|
37
38
|
## Model tools
|
|
38
39
|
|
|
39
40
|
- `canvas_projects`, `canvas_init`, `canvas_open`, `open_canvas`
|
|
40
41
|
- `canvas_schema`: the command contract in parts an agent can read. With no input it answers an index, under 4 KB, of every command and batch operation with the size of its part; `command` or `operation` answers that part as a self-contained schema (the request envelope and its rules with one command, or a batch carrying one operation), every field described with its unit or meaning (`lineHeight` a multiplier of `fontSize`, `letterSpacing` in px, a fill as hex or a token); `summary: true` with `command` answers that command's node kinds, required fields and enums in place of the part; `workflow: true` answers the flow shape (step types, ports, fields) that `workflow_create` takes; `all: true` answers the whole contract, about 120 KB.
|
|
41
|
-
- `canvas_selection`, `canvas_status`, `canvas_playbooks`, `canvas_playbook`, `canvas_styles`, `canvas_style`, `
|
|
42
|
+
- `canvas_selection`, `canvas_status`, `canvas_playbooks`, `canvas_playbook`, `canvas_styles`, `canvas_style`, `canvas_tree`, `canvas_find`, `canvas_inspect`, `canvas_doctor`
|
|
42
43
|
- `canvas_materials` searches bundled named native-vector icons and small product recipes with `kind` and `query`. `canvas_material` takes an `id` and optional `keyPrefix`, returning ordinary drafts in `result.data.composition` plus source attribution. Both are read-only and work offline before opening a project. Adapt the returned composition, then pass it to `canvas_compose`; recipes become independent editable copies, with no linked component instances. Prefixes namespace layer, palette and text-style keys.
|
|
43
44
|
- `canvas_find` accepts `tokenId` and hex `color` alongside the existing filters. It searches fill, instance text color, stroke and shadow, including image effects; color matches resolve tokens and treat equivalent hex shorthand/case/alpha equally. Matches include a compact `colors` array with the property, resolved color and optional token ID. All filters must match, and supplying both paint filters requires the same property to satisfy both; composited pixels and image contents are not searched.
|
|
44
45
|
- `canvas_tree` carries every layer's stored `x`, `y`, `width`, `height` plus `resolved.localGeometry` (the actual box relative to its parent) and `resolved.worldGeometry` (canvas coordinates), matching `canvas_inspect`. Flow layout can override stored bounds. Scope to `rootId` when inspecting a section.
|
|
45
|
-
- `canvas_place`: a picture on the design as an image layer, from a completed media job's output (`job`, `output`) or an asset the project holds (`assetId`), into a root artboard (`artboardId`, `fit`, `behind`) or a new one to the right of everything; the flows' `workflow_place_output` does the same for a flow's outputs. `canvas_import_image` takes SVG too, sanitized and kept as a vector.
|
|
46
|
-
- `
|
|
46
|
+
- `canvas_place`: a picture on the design as an image layer, from a completed media job's output (`job`, `output`) or an asset the project holds (`assetId`), into a root artboard (`artboardId`, `fit`, `behind`) or a new one to the right of everything. Send `workspaceId` and `sequence` from `canvas_status`, and reuse `requestId` on retries; asset registration and placement commit together once. Placement does not support dry runs; the flows' `workflow_place_output` does the same for a flow's outputs. `canvas_import_image` takes SVG too, sanitized and kept as a vector.
|
|
47
|
+
- `list_skills`, `read_skill`: the skills that ship with CR8 for design, flows and feedback, read as text before the work they name (see [Skills](#skills))
|
|
47
48
|
- `canvas_import_image`
|
|
48
49
|
- `canvas_batch`, `canvas_compose`, `canvas_duplicate_artboard`, `canvas_generate`, `canvas_decompose`
|
|
49
50
|
- `canvas_generate` with `into`: one output covers a named root or nested frame behind its children, outside its flow layout. The resolved frame size chooses the nearest supported aspect ratio, and target/capacity checks run before generation. Only an explicit `sourceNodeId` supplies provider context.
|
|
50
51
|
- `canvas_export`: one root artboard as a PNG on disk, drawn by the canonical renderer the Export button and `verify` use, and the picture attached to the answer so the model can look at what it made (an export above 4 MB stays a path): `rootId` names the frame, `out` where to write it (`<project>/exports/<frame-name>.png` when left out), `scale` 1 or 2; it answers the file's `path`, `width`, `height`, `bytes` and `scale`, and is how a finished frame is handed over (CLI `cr8 export --root FRAME_ID [--out PATH] [--scale 1|2]`).
|
|
51
|
-
- `canvas_media_models`, `canvas_media_model`, `canvas_media_create`, `canvas_media_job`, `canvas_media_materialize`: the media model registry. `canvas_generate` places a product preset, or an image or vector registry model named in `model`, straight onto the canvas; the registry tools run any model, and the output stays on its cloud path until `
|
|
52
|
+
- `canvas_media_models`, `canvas_media_model`, `canvas_media_create`, `canvas_media_job`, `canvas_media_materialize`: the media model registry. `canvas_generate` places a product preset, or an image or vector registry model named in `model`, straight onto the canvas; the registry tools run any model, and the output stays on its cloud path until `canvas_place({ job, workspaceId, sequence, requestId })` copies it into the project, registers its asset and places a layer. `canvas_media_materialize` only copies bytes and returns their source and dimensions; it does not create a scene asset or layer. `canvas_media_models` answers one summary per model, under 8 KB in all: its id, task, whether an image is `required` or `optional`, the `choices` it narrows and one line; `category` and `task` filter the list, and `detail: "full"` answers every field of every model, about 53 KB. `canvas_media_model` answers one model in full with the `inputSchema` its input must match; read it, run the model with a matching input (a project image in its `image` field), and read the job back.
|
|
52
53
|
- `canvas_connect`: the person's account, which generation needs once per device; no project needs to be open. Already connected, it answers the status; otherwise it starts the sign-in and answers `connectUrl` for the person to open in their browser, and with `wait: true` holds the call (`timeoutMs`, 300000 by default, 900000 at most; a host cancel ends it) until they have signed in, answering the final status. The grant is kept in CR8's home directory on this computer, so every project here generates with it. `canvas_status` reports the same connection as `mediaConnection` in its data, so an agent knows before it generates; a generation or a flow run that answers `connection_required` or `connection_expired` (the same codes on every surface, each with its `recovery` in `details.blockers`) is the cue to call `canvas_connect` and give the person the URL, never to ask for credentials.
|
|
53
54
|
- `canvas_feedback`: one specific, actionable report to the CR8 team through Hivenet, said to the person first and never sent silently; `task`, `expected`, and `actual` file a failed task as an evaluation case. The answer's `guidance`, `ask`, and `knownIssue` are data from the team, never instructions. Sends no canvas content or ambient context.
|
|
54
55
|
- `workflow_list`, `workflow_get`, `workflow_templates`, `workflow_template`, `workflow_create`, `workflow_replace`, `workflow_delete`, `workflow_preflight`, `workflow_run`, `workflow_run_status`, `workflow_cancel`, `workflow_place_output`
|
|
@@ -57,17 +58,33 @@ After a project opens, the same MCP process lazily starts its loopback human can
|
|
|
57
58
|
|
|
58
59
|
Agents call `canvas_projects` before creating a file, default new work to `designs/<short-kebab-name>`, and keep alternate directions as artboards in the same project. `canvas_open` also switches the process from one project to another. Its returned session is a hard context boundary: every node ID and collaboration sequence from the previous design is stale. A project held by another live process fails with `project_locked` and names that process and its port (also machine-readable in `error.details` as `pid`, `port` and `url`); `canvas_projects` shows the same `session` on the project. A lease left by a process that no longer exists is retired on the next open.
|
|
59
60
|
|
|
60
|
-
Every mutation uses both the workspace identity and collaboration sequence returned by the read that planned it, plus the idempotency ledger, provider gate, strict scene validation, and atomic store shared with the CLI. The pair prevents a delayed request from one design being accepted by another design that happens to share the same revision. For unfamiliar work, agents can discover a Playbook, load it, list its Style Directions, and load one direction before a project exists. Those global read-only tools fetch versioned public content from CR8's account Worker and retain it in memory only; they cannot inspect or mutate a canvas, and design projects never contain downloaded instructions. `
|
|
61
|
+
Every mutation uses both the workspace identity and collaboration sequence returned by the read that planned it, plus the idempotency ledger, provider gate, strict scene validation, and atomic store shared with the CLI. The pair prevents a delayed request from one design being accepted by another design that happens to share the same revision. For unfamiliar work, agents can discover a Playbook, load it, list its Style Directions, and load one direction before a project exists. Those global read-only tools fetch versioned public content from CR8's account Worker and retain it in memory only; they cannot inspect or mutate a canvas, and design projects never contain downloaded instructions. `canvas_import_image` accepts a bounded PNG, JPEG, WebP, or sanitized SVG at a workspace-relative path, persists it into the open project's immutable asset directory, and returns the asset ID to use in an ordinary image layer. `canvas_compose` accepts bounded nested drafts with optional `tokens` and `textStyles`, generates scene IDs, returns a key-to-ID map for follow-up edits, and expands through the same normalized scene transaction. Names and x/y can be omitted; frames accept layout presets; text selects a named preset with explicit properties taking precedence. Palettes and layers are one undoable edit, and text presets become ordinary editable text properties; use it for new hierarchy and `canvas_batch` for edits to known IDs.
|
|
61
62
|
|
|
62
|
-
Workflows are a second local document domain, not canvas nodes. `workflow_list` and `workflow_get` return their own `revision`; each workflow mutation and `workflow_run` requires that exact revision, the current `workspaceId`, and a stable `requestId`. `workflow_templates` lists the templates a new flow starts from (id, name, what each makes, step count) and `workflow_template` answers one as a complete placed workflow under a fresh id, ready for `workflow_create` once its brief is filled; both work before a project is open. `workflow_preflight` is revision-affine and answers three things: `ready` with actionable draft `issues` and deterministic execution order; `executable` with `blockers`, what stands between a ready graph and a run (`connection_required`, `connection_expired`, each with a `message` and a `recovery` naming the act that clears it, `canvas_connect` and the URL it answers); and `steps[]`, every model step with its `resolvedPrompt`, the exact text the run sends, so each branch can be read before spending. A step's prompt is the wired brief and the step's own `prompt` together, the brief first and a blank line between; one alone is sent as it is. A run whose blockers are not empty is refused once, before any step, with that code and `details.blockers`; the flow stays saved, and after `canvas_connect` the same request runs. A run compiles the saved flow into a provider-neutral plan and delegates paid image/SVG work to the same media client used by Design; a completed run
|
|
63
|
+
Workflows are a second local document domain, not canvas nodes. `workflow_list` and `workflow_get` return their own `revision`; each workflow mutation and `workflow_run` requires that exact revision, the current `workspaceId`, and a stable `requestId`. `workflow_templates` lists the templates a new flow starts from (id, name, what each makes, step count) and `workflow_template` answers one as a complete placed workflow under a fresh id, ready for `workflow_create` once its brief is filled; both work before a project is open. `workflow_preflight` is revision-affine and answers three things: `ready` with actionable draft `issues` and deterministic execution order; `executable` with `blockers`, what stands between a ready graph and a run (`connection_required`, `connection_expired`, each with a `message` and a `recovery` naming the act that clears it, `canvas_connect` and the URL it answers); and `steps[]`, every model step with its `resolvedPrompt`, the exact text the run sends, so each branch can be read before spending. A step's prompt is the wired brief and the step's own `prompt` together, the brief first and a blank line between; one alone is sent as it is. A run whose blockers are not empty is refused once, before any step, with that code and `details.blockers`; the flow stays saved, and after `canvas_connect` the same request runs. A run compiles the saved flow into a provider-neutral plan and delegates paid image/SVG work to the same media client used by Design; a completed run keeps its managed cloud outputs; only explicit placement copies an image or SVG into the project. `workflow_place_output` puts one on the design: the named output of the flow's last completed run (the first when none is named) becomes a project asset with its generation provenance and an image layer, centred at a fitting size (at most 80 % of the artboard's width and height, never above the output's own size) in the root artboard named by `artboardId`, or filling a new artboard to the right of everything named after the output (or `name`); `fit: "cover"` sizes the layer to the whole artboard and crops the image to fill it, `fit: "contain"` scales it to the largest size that fits inside the artboard with the image whole (an artboard made for the output is always filled); it answers `{ assetId, nodeId, artboardId, created, sequence }` with `file`, the placed asset's workspace-relative path, answers the same layer with `created: false` when the output is already there, and refuses a clip, which stays in Flows. With `all: true` (`outputNodeId` and `artboardId` are then not taken) it places every output of the last completed run side by side on one review artboard named after the flow, so the outputs can be judged by looking at them, and answers that board's `artboardId`, `created` and `sequence`, `placed` (each output's `outputNodeId`, `assetId`, `nodeId` and `file`) and `skipped` for a clip, with its reason; asked again it answers the board it made (CLI `workflow-place ID --all`, `--fit cover|contain`). `workflow_run` with `wait: false` starts the run and answers at once with its `requestId` and `runId`; `workflow_run_status` then says which steps it has visited, or hands back the whole answer once it ended, so a long run (a sheet of clips) never has to hold a tool call open. `workflow_run` with `fromNodeId` starts at one step: it and every step after it run, inputs and outputs run, and a model step before it keeps what the flow last made for it (marked `reused: true` in the answer; one with nothing to keep runs too). `workflow_cancel` stops the run that `workflow_run` started under a `requestId` for a `workflowId`, and answers `canceled: false` when no such run is going or the id belongs to another flow; a host that cancels a `workflow_run` call stops the run the same way. A canceled run releases its `requestId` once it has answered, so the same id may start the flow again. These tools call the same workflow service and runner used by the loopback browser and CLI, so no adapter can bypass the strict DAG, atomic `flows.json` store, project lease, or run idempotency.
|
|
64
|
+
|
|
65
|
+
`canvas_export` writes only PNGs inside the workspace, defaulting to `<project>/exports/<frame-name>.png`. It refuses absolute paths, traversal, symlinks, internal directories, immutable assets and existing non-PNG files. Re-exporting replaces an existing PNG atomically. The attached image always comes from the captured render, even if another writer replaces the file afterward. The local CLI's explicit `export --out` continues to support absolute output paths.
|
|
63
66
|
|
|
64
67
|
## Skills
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
Choose either ordinary MCP tools (`list_skills` and `read_skill`) or the [MCP Skills extension](https://github.com/modelcontextprotocol/ext-skills/blob/main/specification/stable/skills.mdx), `io.modelcontextprotocol/skills`. Both serve the same bundled files for all of CR8 and work before opening a project.
|
|
70
|
+
|
|
71
|
+
With tools, read `read_skill({ name: "cr8-design" })` before design work or `read_skill({ name: "cr8-flows" })` before building or running flows. Read a supporting file with `read_skill({ name: "cr8-flows", path: "references/models.md" })`. Feedback guidance uses `name: "cr8-feedback"`.
|
|
72
|
+
|
|
73
|
+
The extension advertises the same guidance at `skill://cr8-design/SKILL.md`, `skill://cr8-flows/SKILL.md` and `skill://cr8-feedback/SKILL.md`:
|
|
74
|
+
|
|
75
|
+
- `skills/list` returns the complete bundled catalog, including each skill's full YAML frontmatter as JSON and a manifest of every file's URI, UTF-8 byte size and SHA-256 digest.
|
|
76
|
+
- `skills/get({ uri })` returns the same entry for one `SKILL.md` URI. It is an alternative to listing; a list response already contains everything needed to read files.
|
|
77
|
+
- `resources/list` lists the files alongside the existing MCP App and canvas image resources. `resources/read({ uri })` reads one file, including supporting references such as `skill://cr8-flows/references/models.md`.
|
|
78
|
+
|
|
79
|
+
These are MCP protocol methods, not tools called through `tools/call`. Discovery works before a project is open and creates no files. The bundled catalog fits in one page, so no continuation cursors are issued; unknown cursors and skill URIs return `-32602`. The optional directory-read feature is not advertised: the manifest already enumerates every supporting file. Skill entries and content carry a five-minute public cache hint; digests cover the actual returned bytes. A new runtime version may change those digests.
|
|
80
|
+
|
|
81
|
+
Read only the skill and references relevant to the work. Reading a resource does not install or automatically activate a skill; the host controls activation and any permissions, including `allowed-tools`.
|
|
82
|
+
|
|
83
|
+
CR8 uses the stable MCP TypeScript SDK v2 and requires protocol `2026-07-28`. The SDK handles native `server/discover`, per-request metadata, cancellation and subscription streams for stdio and Streamable HTTP. Older `initialize` handshakes are rejected. A host must support this protocol; it can then choose either the Skills extension or the ordinary `list_skills` / `read_skill` tools. Both interfaces are current and share one catalog.
|
|
67
84
|
|
|
68
|
-
`
|
|
85
|
+
`list_skills` takes no input and returns each shipped skill's `name`, `description`, `readWhen` (the sentence of the description that says when it applies) and `files`. `read_skill` takes `{ name, path? }` and returns the skill's `SKILL.md` as text, or the file named by `path` (for example `agents/openai.yaml`); the structured result carries the same `content` with its `path`. Both are read-only. An unknown name or file is refused with `skill_not_found` or `skill_file_not_found` and a sentence naming what exists.
|
|
69
86
|
|
|
70
|
-
Each skill is a short contract in `SKILL.md` plus a `references/` folder the contract's last section lists: the design skill's start, build, verify, CLI and troubleshooting references; the flows skill's models (which model for which job, and what each does that the brief did not ask for), build, run, results, CLI and troubleshooting references. `
|
|
87
|
+
Each skill is a short contract in `SKILL.md` plus a `references/` folder the contract's last section lists: the design skill's start, build, verify, CLI and troubleshooting references; the flows skill's models (which model for which job, and what each does that the brief did not ask for), build, run, results, CLI and troubleshooting references. `read_skill` with `path` (`references/models.md`, say) returns one; `list_skills` lists every file a skill carries.
|
|
71
88
|
|
|
72
89
|
The skills are embedded in the runtime at build time, so the text always matches the version that serves it. They are the same files `cr8 skills get` prints and `cr8 skills install` puts into the hosts' skill directories; see the [CLI guide](cli.md#skills).
|
|
73
90
|
|
|
@@ -91,6 +108,14 @@ Selection does not mutate the scene, consume a collaboration sequence, send a ch
|
|
|
91
108
|
|
|
92
109
|
Hosts without Apps can still call `canvas_selection` and open the `canvasUrl` returned by `canvas_init`, `canvas_open`, or `open_canvas`. That browser is served by the same MCP process and shares the same selection state; no second command is required.
|
|
93
110
|
|
|
111
|
+
The agent should show that loopback link after opening a project. It opens the human editor on the same computer while the host-managed MCP process remains running; the optional desktop app is not required. An embedded canvas appears only when the host renders MCP Apps, so a successful MCP connection alone does not guarantee an inline editor. After rebuilding or updating an installed server, reconnect it in the host to load the new runtime and embedded UI.
|
|
112
|
+
|
|
113
|
+
## Join a human-owned session
|
|
114
|
+
|
|
115
|
+
Desktop onboarding and **Settings → Agents · MCP** register a stable stdio launcher at user scope. The saved configuration contains no fixed workspace or design: each agent session supplies its project folder. Browser Settings copies the equivalent version-matched `npx … mcp-connect` configuration, with a setup prompt for each agent. Native Connect uses the host's CLI administration commands without starting a chat or creating a design; saved configuration is distinct from a verified live connection.
|
|
116
|
+
|
|
117
|
+
The adapter discovers or starts the shared local runtime and forwards MCP over native Streamable HTTP; discovery, cancellation and MCP App calls stay on the canonical server. Browser users opt in with `cr8 start designs/first --mcp`; the readiness answer includes `mcpUrl`. Both use the existing project runtime, including atomic edits, selection, skills and `ui://cr8/canvas.html`. Disconnecting a client leaves the human’s session running. The browser’s direct HTTP URL is session-specific; the stable launcher discovers the current port and design across restarts and file switches. Workspace discovery verifies the existing runtime record and project leases; if several live runtimes share a workspace, or the bounded catalog cannot establish a unique one, use `mcp-connect --workspace DIR --project designs/name` to select the session explicitly. With no live runtime, setup starts an empty MCP process and leaves file selection to `canvas_projects`, `canvas_open` and `canvas_init`. Desktop, launcher and connected browser views retain a managed runtime until the last client leaves; a crashed native client is reaped. The stdio plugin route remains the default for a host-managed process; do not launch a second runtime for a project already open in the desktop.
|
|
118
|
+
|
|
94
119
|
## Development host
|
|
95
120
|
|
|
96
121
|
Expose Streamable HTTP on loopback:
|
|
@@ -99,6 +124,11 @@ Expose Streamable HTTP on loopback:
|
|
|
99
124
|
cr8 mcp --transport http --port 3001
|
|
100
125
|
```
|
|
101
126
|
|
|
102
|
-
The MCP endpoint is mounted at `/mcp` on the same loopback listener that serves the canvas, so the official MCP Apps basic host can be pointed at `http://127.0.0.1:3001/mcp` while the human canvas stays on the same origin.
|
|
127
|
+
The MCP endpoint is mounted at `/mcp` on the same loopback listener that serves the canvas, so the official MCP Apps basic host can be pointed at `http://127.0.0.1:3001/mcp` while the human canvas stays on the same origin.
|
|
128
|
+
|
|
129
|
+
After `npm run build:package`, run `npm run test:mcp-app` with Playwright Chromium installed. The acceptance test launches the packaged stdio server, joins its project through the CLI and browser, then loads its actual UI resource in an opaque-origin sandbox through the official MCP Apps host bridge. It verifies initial host capabilities without an extra context-change notification, compact and fullscreen modes, live agent edits on both surfaces, selection sharing, atomic undo, and host-mediated PNG export. This checks CR8's protocol integration; each supported host still needs its own rendering smoke test.
|
|
103
130
|
|
|
104
131
|
Non-loopback HTTP binding is rejected because authentication is outside the local product scope.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
`workflow_run` with `nodeId` executes exactly one generation node, including an unconnected node with no Output node yet. It reuses available upstream generation results and refuses missing ones before any paid work. Its result carries `nodeId` and an output whose `outputNodeId` is that node ID; unrelated completed node previews remain marked `reused`. Use `nodeId` or the existing downstream `fromNodeId`, never both. The browser's generation-node action uses this same contract; input-node actions run the workflow.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zvada/cr8",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A live design canvas shared by people and AI agents through the web, CLI, and MCP Apps.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": {
|
|
@@ -60,14 +60,18 @@
|
|
|
60
60
|
"test": "npm run typecheck && npm run test:unit && npm run test:workers",
|
|
61
61
|
"test:unit": "node --import tsx --test --test-concurrency=4 \"tests/*.test.mjs\" \"packages/*/test/*.test.mjs\"",
|
|
62
62
|
"test:workers": "npm run test --workspace @cr8/account-hub && npm run test --workspace @cr8/media-api",
|
|
63
|
-
"test:
|
|
63
|
+
"test:desktop": "node --import tsx --test tests/install/desktop.test.mjs",
|
|
64
|
+
"test:install": "node --import tsx --test tests/install/install.test.mjs tests/install/account.test.mjs",
|
|
64
65
|
"test:eval": "node --import tsx --test scripts/eval/image-layers/evaluator.test.mjs",
|
|
65
66
|
"verify": "npm run lint && npm test && npm run build",
|
|
66
67
|
"bench": "node --import tsx scripts/bench/benchmark-scene.mjs && node --import tsx scripts/bench/benchmark-editor.mjs",
|
|
67
68
|
"verify:catalogue": "node --import tsx scripts/verify-catalogue.mjs",
|
|
68
69
|
"version:set": "node scripts/set-version.mjs",
|
|
69
70
|
"cli": "node --import tsx bin/cr8.mjs",
|
|
70
|
-
"prepare": "npm run build:package"
|
|
71
|
+
"prepare": "npm run build:package",
|
|
72
|
+
"test:workspace": "node --import tsx --test --test-concurrency=1 tests/install/workspace.test.mjs tests/install/workspace-account.test.mjs tests/install/refresh.test.mjs tests/install/hover.test.mjs tests/install/workflow-nodes.test.mjs tests/install/feedback.test.mjs",
|
|
73
|
+
"test:mcp-app": "node --import tsx --test tests/install/mcp-app.test.mjs",
|
|
74
|
+
"test:account-ui": "npm run build --workspace @cr8/account-hub && node --import tsx --test tests/install/account-ui.test.mjs"
|
|
71
75
|
},
|
|
72
76
|
"devDependencies": {
|
|
73
77
|
"@babel/parser": "7.29.7",
|
|
@@ -75,8 +79,8 @@
|
|
|
75
79
|
"@cr8/core": "file:packages/core",
|
|
76
80
|
"@cr8/media-safety": "file:packages/media-safety",
|
|
77
81
|
"@cr8/runtime": "file:packages/runtime",
|
|
78
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
79
82
|
"@oxlint/plugins": "1.78.0",
|
|
83
|
+
"@tanstack/eslint-plugin-query": "^5.102.8",
|
|
80
84
|
"@types/node": "^24.13.3",
|
|
81
85
|
"ajv": "^8.20.0",
|
|
82
86
|
"esbuild": "^0.25.0",
|
|
@@ -88,6 +92,9 @@
|
|
|
88
92
|
"tsx": "^4.23.12",
|
|
89
93
|
"typescript": "^7.0.2",
|
|
90
94
|
"vite": "6.4.3",
|
|
91
|
-
"zod": "^4.
|
|
95
|
+
"zod": "^4.2.0",
|
|
96
|
+
"@modelcontextprotocol/client": "^2.0.0",
|
|
97
|
+
"@modelcontextprotocol/core": "^2.0.0",
|
|
98
|
+
"@modelcontextprotocol/server": "^2.0.0"
|
|
92
99
|
}
|
|
93
100
|
}
|