@zvada/cr8 0.2.0 → 0.3.1
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 +21 -16
- package/dist/cr8.mjs +212 -142
- package/docs/user/app-store-screenshots.md +0 -2
- package/docs/user/cli.md +7 -5
- package/docs/user/desktop.md +51 -7
- package/docs/user/feedback.md +5 -1
- package/docs/user/install.md +83 -34
- package/docs/user/mcp.md +49 -17
- package/package.json +15 -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
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,35 @@ 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.
|
|
84
|
+
|
|
85
|
+
Saved host configuration is not a verified connection. The shared launcher reports live agent presence after a successful MCP call; discovery alone is not enough. If a host reports an unsupported protocol (`-32022`), use CR8's CLI and local browser while waiting for a compatible host. See [checked Claude Code/Codex versions and recovery](install.md#host-compatibility); SDK integration tests do not establish those hosts' readiness.
|
|
67
86
|
|
|
68
|
-
`
|
|
87
|
+
`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
88
|
|
|
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. `
|
|
89
|
+
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
90
|
|
|
72
91
|
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
92
|
|
|
@@ -91,6 +110,14 @@ Selection does not mutate the scene, consume a collaboration sequence, send a ch
|
|
|
91
110
|
|
|
92
111
|
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
112
|
|
|
113
|
+
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.
|
|
114
|
+
|
|
115
|
+
## Join a human-owned session
|
|
116
|
+
|
|
117
|
+
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.
|
|
118
|
+
|
|
119
|
+
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. `cr8 start designs/first` enables MCP by default; the readiness answer includes `mcpUrl`. The low-level `cr8 serve` command needs `--mcp`. 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.
|
|
120
|
+
|
|
94
121
|
## Development host
|
|
95
122
|
|
|
96
123
|
Expose Streamable HTTP on loopback:
|
|
@@ -99,6 +126,11 @@ Expose Streamable HTTP on loopback:
|
|
|
99
126
|
cr8 mcp --transport http --port 3001
|
|
100
127
|
```
|
|
101
128
|
|
|
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.
|
|
129
|
+
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.
|
|
130
|
+
|
|
131
|
+
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
132
|
|
|
104
133
|
Non-loopback HTTP binding is rejected because authentication is outside the local product scope.
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
`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.1",
|
|
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,21 @@
|
|
|
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"
|
|
75
|
+
},
|
|
76
|
+
"overrides": {
|
|
77
|
+
"sharp": "0.35.4"
|
|
71
78
|
},
|
|
72
79
|
"devDependencies": {
|
|
73
80
|
"@babel/parser": "7.29.7",
|
|
@@ -75,8 +82,8 @@
|
|
|
75
82
|
"@cr8/core": "file:packages/core",
|
|
76
83
|
"@cr8/media-safety": "file:packages/media-safety",
|
|
77
84
|
"@cr8/runtime": "file:packages/runtime",
|
|
78
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
79
85
|
"@oxlint/plugins": "1.78.0",
|
|
86
|
+
"@tanstack/eslint-plugin-query": "^5.102.8",
|
|
80
87
|
"@types/node": "^24.13.3",
|
|
81
88
|
"ajv": "^8.20.0",
|
|
82
89
|
"esbuild": "^0.25.0",
|
|
@@ -88,6 +95,9 @@
|
|
|
88
95
|
"tsx": "^4.23.12",
|
|
89
96
|
"typescript": "^7.0.2",
|
|
90
97
|
"vite": "6.4.3",
|
|
91
|
-
"zod": "^4.
|
|
98
|
+
"zod": "^4.2.0",
|
|
99
|
+
"@modelcontextprotocol/client": "^2.0.0",
|
|
100
|
+
"@modelcontextprotocol/core": "^2.0.0",
|
|
101
|
+
"@modelcontextprotocol/server": "^2.0.0"
|
|
92
102
|
}
|
|
93
103
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cr8-design
|
|
3
3
|
description: Design in CR8 as the designer, from a brief or a reference, through its MCP or CLI surfaces. Use for new product screens, landing pages, marketing visuals, App Store screenshots, faithful reproduction of an existing page or picture, and any task where an agent designs on a canvas while a person watches or collaborates.
|
|
4
|
-
allowed-tools: Bash(cr8:*), Bash(npx @zvada/cr8@0.
|
|
4
|
+
allowed-tools: Bash(cr8:*), Bash(npx @zvada/cr8@0.3.1:*)
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# CR8 Design
|
|
8
8
|
|
|
9
|
-
You are the designer. The person watches the canvas and edits beside you; you work it through MCP or the CLI. CR8's playbooks and styles are the taste, loaded fresh each time; the files under `references/` hold the detail (`
|
|
9
|
+
You are the designer. The person watches the canvas and edits beside you; you work it through MCP or the CLI. CR8's playbooks and styles are the taste, loaded fresh each time; the files under `references/` hold the detail (`read_skill` with `name` and `path`, or `cr8 skills get cr8-design --path references/x.md`).
|
|
10
10
|
|
|
11
11
|
Use the MCP server or CLI from the installation that supplied this skill. Check unfamiliar commands with `cr8 --help` and `cr8 schema --command TYPE`; if a source checkout describes a command missing from a published fallback, use the matching checkout build or update the installed plugin.
|
|
12
12
|
|
|
@@ -13,7 +13,7 @@ Choose by deliverable:
|
|
|
13
13
|
- `web-app`: dense web and desktop product surfaces.
|
|
14
14
|
- `canvas-foundations`: the default structure and verification discipline; enough on its own for a single simple artboard.
|
|
15
15
|
|
|
16
|
-
A playbook that lists no styles is used alone.
|
|
16
|
+
A playbook that lists no styles is used alone.
|
|
17
17
|
|
|
18
18
|
## Projects
|
|
19
19
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cr8-flows
|
|
3
3
|
description: Build, run and reuse CR8 Flows, node graphs over image, vector and video models, through its MCP or CLI surfaces. Use when a task needs several generations in sequence or in parallel, a repeatable recipe a person can rerun and edit, a video or vector step, or a chain such as draft, edit, upscale; and when a person asks for variations, a campaign kit, or a pipeline rather than one picture.
|
|
4
|
-
allowed-tools: Bash(cr8:*), Bash(npx @zvada/cr8@0.
|
|
4
|
+
allowed-tools: Bash(cr8:*), Bash(npx @zvada/cr8@0.3.1:*)
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# CR8 Flows
|
|
8
8
|
|
|
9
|
-
A flow is a small graph saved in the project's `flows.json`: input steps, model steps and output steps, wired by typed ports. The person sees it as cards on a canvas, watches a run step by step, and can rerun or edit it later. Use a flow when the work is more than one generation, when it should be repeatable, or when it needs video, vector or an edit chain; use `canvas_generate` for one picture straight onto a design. This file is the contract; the files under `references/` hold the detail, read with `
|
|
9
|
+
A flow is a small graph saved in the project's `flows.json`: input steps, model steps and output steps, wired by typed ports. The person sees it as cards on a canvas, watches a run step by step, and can rerun or edit it later. Use a flow when the work is more than one generation, when it should be repeatable, or when it needs video, vector or an edit chain; use `canvas_generate` for one picture straight onto a design. This file is the contract; the files under `references/` hold the detail, read with `read_skill` (`name` and `path`) or `cr8 skills get cr8-flows --path references/<file>`.
|
|
10
10
|
|
|
11
11
|
## Start
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ You mint every id (flow, steps, edges): kebab-case, unique in the project. Steps
|
|
|
20
20
|
|
|
21
21
|
## Run and results
|
|
22
22
|
|
|
23
|
-
`workflow_run` runs the saved revision and answers with every output; `wait: false` answers at once and `workflow_run_status` follows it; `fromNodeId` reruns one step and what is downstream of it, reusing the rest. A failed run answers a `recovery` sentence.
|
|
23
|
+
`workflow_run` runs the saved revision and answers with every output; `wait: false` answers at once and `workflow_run_status` follows it; `fromNodeId` reruns one step and what is downstream of it, reusing the rest. A failed run answers a `recovery` sentence. Generated outputs stay on managed cloud paths, with their last result recorded in `flow-runs.json`. Judge them by looking: `workflow_place_output` copies images or SVGs into the project's immutable assets and inserts them in one scene transaction; `all: true` makes a review board, and without it one output is placed on an artboard. Clips stay in Flows. Detail in `references/run.md` and `references/results.md`.
|
|
24
24
|
|
|
25
25
|
## Account
|
|
26
26
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Where outputs land
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Flow outputs stay on their managed cloud `src`, with generation provenance. `flow-runs.json` beside `flows.json` records the last result so the graph can show it again; it does not make the output available offline. An output has `file` only when it already references a local project asset. **Add to Design** / `workflow_place_output` copies and validates image or SVG bytes into the project's immutable `assets/` before inserting an asset and layer in one scene transaction. Clips stay in Flows (`clip_stays_cloud`).
|
|
6
6
|
|
|
7
7
|
## Judge by looking
|
|
8
8
|
|
|
9
|
-
Never judge a run by its status.
|
|
9
|
+
Never judge a run by its status. Inspect each output in Flows, open `file` when present, or make a review board: `workflow_place_output` with `all: true` (CLI `workflow-place ID --all`) puts every output of the last run on one review artboard named after the flow, side by side at equal height, to the right of everything on the design; it answers the board's `artboardId`, its `x`, `y`, `width` and `height`, and `placed`, each output's layer and `file`. Read that artboard (export it with `canvas_export`, or look in the browser). Compose your own artboards clear of the board, since `canvas_doctor` names root artboards that overlap. `canvas_doctor` checks structure and legibility, not the brief.
|
|
10
10
|
|
|
11
11
|
## Place one output on a design
|
|
12
12
|
|
|
@@ -18,4 +18,4 @@ A run refused before any step with `connection_required` or `connection_expired`
|
|
|
18
18
|
|
|
19
19
|
## What a run answers
|
|
20
20
|
|
|
21
|
-
On the CLI, `workflow-run` and `workflow-run-status` answer compactly: each step's status and each output
|
|
21
|
+
On the CLI, `workflow-run` and `workflow-run-status` answer compactly: each step's status and each output's managed `src`; `file` is present only for an existing local project asset. New generated images, SVGs and clips stay on their cloud paths until an explicit download or placement. `--full` adds the provenance and the prompts sent. Over MCP the answer is the whole run: `status`, `nodeResults` (each step's status, artifact and provider ids), `outputs` (each with `outputNodeId`, `sourceNodeId`, the `asset`, and `file` when the project holds a copy), and on failure `failedNodeId` and `recovery`.
|