@zvada/cr8 0.1.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.
@@ -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. |
@@ -82,24 +83,26 @@ Omitting `--sequence` reads the latest session immediately before a mutation. Th
82
83
  | `playbook PLAYBOOK_ID` | Load one current methodology, decision flow, and acceptance gate. |
83
84
  | `styles [--playbook PLAYBOOK_ID]` | List composition systems, optionally filtered to a playbook. |
84
85
  | `style STYLE_ID` | Load one current visual direction with concrete composition and hierarchy rules. |
85
- | `guide [--topic canvas-foundations\|web-app\|faithful-reproduction\|app-store]` | Backward-compatible alias for loading a legacy-named playbook. |
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. |
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. |
86
88
  | `skills [list]` | List the skills that ship with this CLI: name, description, when to read each, files, and where they live on disk. |
87
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`. |
88
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`. |
89
91
  | `skills install [--host claude\|codex\|agents\|all] [--dir DIR] [--force]` | Install every shipped skill where the hosts look, linking to the package's skills or writing the embedded copy. |
90
- | `tree [--root ID]` | Return the complete semantic hierarchy or one subtree. |
91
- | `find [--query TEXT] [--type TYPE] [--role ROLE] [--root ID] [--limit N]` | Discover stable IDs. |
92
+ | `tree [--root ID]` | Return the semantic hierarchy with each layer's stored `x`, `y`, `width`, `height` and its actual layout in `resolved.localGeometry` (relative to its parent) and `resolved.worldGeometry` (canvas coordinates). Flow layout can override stored bounds. Scope with `--root` to inspect one section. |
93
+ | `find [--query TEXT] [--type TYPE] [--role ROLE] [--token ID] [--color HEX] [--root ID] [--limit N]` | Discover stable IDs with all filters combined. Token and color searches cover fill, instance text color, stroke and shadow, including image effects. Hex matches resolve tokens and normalize shorthand, case and alpha; results include matching `colors` properties and token IDs. With both paint filters, the same property must match both. |
92
94
  | `inspect ID` | Return one node, its root, descendants, and layout issues. |
93
95
  | `doctor [--root ID]` | Run deterministic diagnostics: `layout`, a layer that overflows, clips or has no room, `overlap`, a root artboard lying over another (named with the overlap in px; with `--root`, only the pairs that root is part of), and `contrast`, a text that reads below 4.5:1 (3:1 at display sizes) on what lies under it, or that sits on an image with no plate or scrim. A `hygiene` notice names clutter an iteration left: a root artboard holding nothing, or a generated asset no layer shows (`remove_asset` drops it). A `warning` makes the design unhealthy (exit `2`); a `notice` (a colour that reads short of its minimum, or hygiene) is listed and does not. Exits `2` on a warning; a report of notices alone exits `0`. |
94
96
  | `doctor --cloud` | Ask the account hub and the media Worker what they run and whether they still accept this version; exits `2` when one is unreachable, refuses this client, or is older than the runtime. |
95
97
  | `edit --ops JSON` / `edit --file FILE` | Apply up to 100 scene operations as one transaction. |
96
- | `compose --json JSON` / `compose --file FILE [--parent ID]` | Create nested editable hierarchy atomically without pre-generating scene IDs. Each draft key is returned as a stable key-to-ID map. Omit `--parent` for a root node; `--parent null` and `--parent root` mean the same. |
98
+ | `compose --json JSON` / `compose --file FILE [--parent ID]` | Create nested editable hierarchy from an array of drafts or `{nodes,tokens,textStyles}` in one transaction. Each draft key is returned as a stable key-to-ID map. Omit `--parent` for a root node; `--parent null` and `--parent root` mean the same. A new root artboard composed where another root sits lands clear of it, to the right of them all at the y it asked for, and the answer says where (`placed`). |
97
99
  | `duplicate --source ID [--name TEXT]` | Create a normal independent artboard and return its old-to-new ID map. |
98
100
  | `import IMAGE_PATH [--as-frame \| --asset-only] [--name TEXT] [--parent ID] [--x N] [--y N] [--width N] [--height N] [--fit contain\|cover\|fill]` | Validate a static PNG/JPEG/WebP, copy it into the project's content-addressed assets, and place one editable image or root artboard atomically. PNG, JPEG, WebP or SVG (an SVG is sanitized and stays a vector). `--asset-only` registers the asset and places no layer, for `place --asset` later. |
99
- | `capture URL [--name TEXT] [--viewport WIDTHxHEIGHT] [--wait MS] [--timeout MS]` | Capture an HTTP(S) page with local Chrome/Chromium and place the result as a root artboard. |
100
- | `verify --reference IMAGE_PATH --root FRAME_ID [--tolerance 0.01]` | Run `doctor`, export the exact frame with CR8's canonical renderer, and compare same-size pixels against a local reference. |
101
+ | `capture URL [--name TEXT] [--viewport WIDTHxHEIGHT] [--wait MS] [--timeout MS] [--layers]` | Capture an HTTP(S) page with local Chrome/Chromium and place the result as a root artboard. With `--layers`, the page becomes editable layers instead of one picture: the browser lays it out, and every box that paints becomes a frame with its fill, border, radius and clipping, every run of text a text layer with its size, weight, line height, colour and the closest family CR8 ships, every picture and inline vector an asset. Exact geometry; shadows and gradients are dropped; the answer counts what was made and says when the page exceeded the budget of 1500 layers or 48 pictures. |
102
+ | `verify --reference IMAGE_PATH --root FRAME_ID [--tolerance 0.01] [--ink-tolerance 0.25]` | Run `doctor`, export the exact frame with CR8's canonical renderer, and compare same-size pixels against a local reference. A screen is mostly background, so the fraction over the whole viewport flatters: the answer also gives `inkMismatchedFraction`, the share of the pixels that carry ink in either image that differ, the `regions` that differ most, and writes a difference image beside the exports (`diffPath`), the render dimmed with every differing pixel red. A pass needs the ink gate too. |
101
103
  | `export --root FRAME_ID [--out PATH] [--scale 1\|2]` | Render the exact root artboard with the same canonical renderer and write it as a PNG: to `<project>/exports/<frame-name>.png` (created as needed) unless `--out` names a path (relative to the current directory). Answers `path`, `width`, `height`, `bytes`, `scale`, `rootId` and `name`; changes nothing. `--scale 2` renders at twice the pixels. |
102
- | `generate [--prompt TEXT] [--node ID] [--model auto\|fast\|quality\|vector\|ID] [--ratio 1:1\|16:9\|9:16\|4:3\|3:4] [--count 1..4]` | Add image or native SVG output as normal editable artboards. `--model` takes a preset word or an image or vector model id from `media-models`; `--node` turns Auto/Fast into a reference edit and feeds an editor or upscaler, which needs no `--prompt`. |
104
+ | `generate [--prompt TEXT] [--node ID] [--into FRAME_ID] [--model auto\|fast\|quality\|vector\|ID] [--ratio 1:1\|16:9\|9:16\|4:3\|3:4] [--count 1..4] [--remove-background]` | Add image or native SVG output as normal editable artboards. `--model` takes a preset word or an image or vector model id from `media-models`; `--node` turns Auto/Fast into a reference edit and feeds an editor or upscaler, which needs no `--prompt`. With `--into`, count defaults to one and the output covers the named root or nested frame behind its children. Its resolved size chooses the nearest supported ratio; it never enters the frame’s flow layout. Target and capacity are validated before a provider job starts. |
105
+ | `expand-svg SVG_IMAGE_ID [--remove-background]` | Expand an existing SVG image in place into native vector layers. Preserve the immutable source and one undo restores the image. Refuse unsupported SVG features without changing the document. |
103
106
  | `decompose --node ID [--prompt TEXT] [--layers 2..8]` | Replace an image in place with editable raster/text layers. |
104
107
  | `reset --yes` | Clear the current canvas while keeping its project name. |
105
108
  | `watch [--since N] [--timeout MS]` | Return retained collaboration events after a sequence. |
@@ -110,13 +113,13 @@ Omitting `--sequence` reads the latest session immediately before a mutation. Th
110
113
  | `media-job JOB_ID` | Read a media job by the id `media-create` returned. |
111
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. |
112
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. |
113
- | `media-materialize --src PATH` | Copy a completed job's output into the project as an ordinary asset, ready for `edit` with `insert_node`. |
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. |
114
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. |
115
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. |
116
119
  | `workflow-delete WORKFLOW_ID [--workspace-id ID] [--revision N]` | Delete one workflow using optimistic concurrency and a retry-safe request ID. Same defaults. |
117
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. |
118
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. |
119
- | `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`, `file`, the workspace-relative path the output is kept at such as `designs/launch/assets/sha256-….webp`, and `src`, its runtime path). `--full` prints the whole answer with every step's artifact and provenance. `--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. |
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. |
120
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`. |
121
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. |
122
125
  | `exec --command JSON` | Send a command object from the published schema. |
@@ -134,7 +137,7 @@ Canvas sequences and workflow revisions are deliberately separate. Every workflo
134
137
 
135
138
  `import` and `capture` return the created `assetId`, `imageId`, optional `frameId`, managed source path, dimensions, and placement. Imported bytes are validated before any scene mutation; `--dry-run` validates and plans without copying or changing the project. `capture` and `verify` require an installed Chrome or Chromium and honor `CR8_CHROME_PATH` (or `CHROME_PATH`) when automatic discovery is insufficient. They launch isolated, temporary headless profiles and remove them after the command. If Chrome cannot start with its sandbox (some container and CI images), the CLI retries once without it.
136
139
 
137
- `verify` is intentionally stricter than `doctor`: both layout diagnostics and visual comparison must pass. The default tolerance permits at most 1% normalized mean channel error and 1% pixels whose channel difference exceeds 8/255, accommodating browser image resampling while still rejecting visible drift. It exits `2` on a cleanly completed failed gate and `1` when verification could not run. `export` renders the same frame through the same renderer and writes it to disk, so the file it answers is the file `verify` compares and the Export button saves; `export --root FRAME_ID` followed by `verify --reference <that file> --root FRAME_ID` passes.
140
+ `verify` is intentionally stricter than `doctor`: both layout diagnostics and visual comparison must pass, and the visual comparison judges the ink, not the viewport: on a screen where eight percent of the pixels carry ink, a copy that differs in one percent of all pixels can differ in a fifth of the ink, and the answer says so. The default tolerance permits at most 1% normalized mean channel error and 1% pixels whose channel difference exceeds 8/255, accommodating browser image resampling while still rejecting visible drift. It exits `2` on a cleanly completed failed gate and `1` when verification could not run. `export` renders the same frame through the same renderer and writes it to disk, so the file it answers is the file `verify` compares and the Export button saves; `export --root FRAME_ID` followed by `verify --reference <that file> --root FRAME_ID` passes.
138
141
 
139
142
  `feedback --dry-run` is the exception: it prints the exact Hivenet event without sending it. A live submission contains only supplied feedback fields, opaque delivery IDs, and the CLI version; it never includes canvas data, prompts, the current directory, Git state, or an agent session. See [feedback](feedback.md).
140
143
 
@@ -156,42 +159,32 @@ cr8 skills path # where they live on disk
156
159
 
157
160
  ## Atomic operations
158
161
 
159
- Use `compose` for new hierarchy and `edit` for precise changes to existing IDs. A composition file is an array of normal scene nodes without `id` or `parentId`; every node instead has a request-local `key`, and frames nest their children directly. The runtime generates collision-safe IDs, flattens the tree into the canonical scene model, and returns `nodeIds` so later edits remain explicit:
162
+ Use `compose` for new hierarchy and `edit` for precise changes to existing IDs. A composition file accepts an array of drafts or an object with `nodes`, optional color `tokens`, and optional `textStyles`. Every node has a request-local `key`; the runtime creates IDs and returns `nodeIds` for follow-up edits. Frames nest their children directly:
160
163
 
161
164
  ```json
162
- [
163
- {
164
- "key": "screen",
165
- "type": "frame",
166
- "name": "Landing page",
167
- "x": 0,
168
- "y": 0,
169
- "width": 1200,
170
- "height": 800,
171
- "fill": "#ffffff",
172
- "clip": true,
173
- "layout": { "mode": "absolute" },
165
+ {
166
+ "tokens": {
167
+ "studio-ink": { "type": "color", "value": "#263c32" }
168
+ },
169
+ "textStyles": {
170
+ "heading": { "fontFamily": "newsreader", "fontSize": 40, "fill": { "type": "token", "tokenId": "studio-ink" } }
171
+ },
172
+ "nodes": [{
173
+ "key": "Screen", "type": "frame", "width": 640, "height": 360,
174
+ "layout": "vertical",
174
175
  "children": [
175
- {
176
- "key": "headline",
177
- "type": "text",
178
- "name": "Headline",
179
- "x": 48,
180
- "y": 48,
181
- "width": 640,
182
- "height": 120,
183
- "text": "One nested request.",
184
- "fill": "#151516",
185
- "fontFamily": "inter",
186
- "fontSize": 64,
187
- "fontWeight": 700
188
- }
176
+ { "key": "Headline", "type": "text", "width": 592, "height": 56, "text": "Make room for good work.", "textStyle": "heading" },
177
+ { "key": "Image slot", "type": "frame", "width": 592, "height": 244, "clip": true, "children": [] }
189
178
  ]
190
- }
191
- ]
179
+ }]
180
+ }
192
181
  ```
193
182
 
194
- Composition keys must be unique within the request and are never persisted into the document. Root frames remain square-edged, validation is atomic, and nested input does not create a second document format.
183
+ Compose defaults `name` to the key and `x`/`y` to zero. Frames default to absolute layout: root artboards are white and clipped; nested frames are transparent and unclipped. `horizontal`, `vertical` and `stack` presets use 12px gap and 24px padding; pass a full layout object for exact control. `layoutItem: { "width": "fill" }` defaults its other fields to auto positioning and fixed height. Text defaults to regular 16px Manrope; explicit properties override its named preset. Text has three sizing rules: `textGrowth: "fixed"` (the legacy default), `"auto"` (natural width and height, preserving explicit newlines), and `"auto-height"` (wrap at its resolved width and grow vertically). Frames accept `sizing: { "width": "fixed", "height": "hug" }`, or hug on either axis. Compose may omit an axis supplied by intrinsic sizing or explicit fill in a flow parent; ordinary stored nodes still have complete fallback bounds. Parent fill constraints take precedence. In a hug main axis, fill children contribute their natural/authored size; absolute-positioned children do not enlarge a flow container.
184
+
185
+ `set_text` changes text growth and `set_frame` changes frame sizing. Switching a growing axis to fixed keeps its current visible size. A handle resize fixes only the dimensions it changes; horizontal resizing of auto text becomes auto-height. Scale preserves sizing rules and scales typography and spacing. The browser measures the bundled fonts; CLI/MCP prepare the same derived measurements in a warm local Chrome renderer. If Chrome is unavailable, adaptive agent edits fail explicitly; local browser editing remains available. `doctor` reports `textMeasurement: "complete" | "unavailable"`, and an unavailable fixed-text check is only an estimate. Inspect an export after changing copy or width.
186
+
187
+ Palettes and layers are one undoable transaction. Color tokens stay live across their users, so namespace alternate palettes. Text presets are resolved to ordinary properties on editable text nodes; they are not persistent styles or a second scene model. Keys are not persisted. Root artboards stay square-edged, and validation is atomic.
195
188
 
196
189
  `edit` supports `set_text`, `set_geometry`, `set_geometries`, `scale_node`, `set_fill`, `set_appearance`, `set_frame`, `set_layout`, `set_layout_item`, `set_token`, `remove_token`, `insert_asset`, `insert_node`, `insert_nodes`, `move_node`, `reorder_node`, `remove_node`, `remove_nodes`, and `remove_asset`, `rename_document`. Use the bulk geometry, insertion, and removal operations for multi-selection work so the scene map is copied once.
197
190
 
@@ -238,14 +231,27 @@ Exit codes are `1` for invalid/unavailable/rejected work, `2` for diagnostics, `
238
231
 
239
232
  ## Media
240
233
 
241
- 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 the output reaches the canvas through `media-materialize --src` followed by `edit` with `insert_node`. 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.
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.
242
235
 
243
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.
244
237
 
245
- Generation clones the source artboard into normal alternatives, swaps in generated assets copied into the project, and returns the new root/asset IDs. Decomposition atomically replaces the selected image node with a clipped frame of ordinary image/text children. The old source remains in asset provenance and the whole command is undoable.
238
+ Without `--into`, generation creates ordinary alternative artboards (cloning the source artboard when an image source is selected), with locally saved assets and returned root/asset IDs. With `--into`, it returns `assetId`, `nodeId`, `artboardId`, `frameId`, and the chosen `aspectRatio`; only `--node` supplies image context to the provider. Decomposition atomically replaces the selected image node with a clipped frame of ordinary image/text children. The old source remains in asset provenance and the whole command is undoable.
246
239
 
247
240
  See the [media API](../internals/media-api.md).
248
241
 
242
+ ## Editable SVGs
243
+
244
+ Vector generation expands supported SVGs into ordinary selectable paths. Inspect `result.data.vectors` for `editable`, `pathIds`, `backgroundRemoved`, and any fallback warning. Gradients, masks, unsupported stroke styles and other features that cannot be represented faithfully remain an intact SVG image; a conversion limit never repeats the generation.
245
+
246
+ ```bash
247
+ cr8 generate --model vector --prompt "A simple cork tree icon, flat colors" --count 1 --remove-background --workspace-id PROJECT_ID --sequence N
248
+ cr8 expand-svg SVG_IMAGE_ID --remove-background --workspace-id PROJECT_ID --sequence N
249
+ ```
250
+
251
+ The browser exposes **Edit vector layers** for existing SVG images. **Remove background** only removes a single solid shape covering the SVG viewport; it preserves internal white details. It does not remove irregular backgrounds or reconstruct holes. The vector composer starts with **Transparent** enabled and lets you keep the generated background instead. The result states when no separate background was identified.
252
+
253
+ Expansion preserves the original when a stretched image's SVG aspect-ratio rules, or a rounded root image's outline/shadow, cannot be retained faithfully. Expanded paths support the normal fill, position, size, Scale, outline, shadow and delete controls; there is no Bézier-point editor yet. The immutable SVG remains in Assets. Current artboard export is PNG/JPEG; the saved source SVG retains the original generated artwork.
254
+
249
255
  ## Local security
250
256
 
251
257
  The unauthenticated runtime binds only to loopback, validates the `Host` and `Origin` headers, and enforces same-origin browser writes. Projects store their canonical document in `cr8.json`; content-addressed assets live in `assets/`, while retry receipts, selections and the single-writer lease live in the ignored `.cr8/` directory; the device grant lives in your configuration directory, in no project.
@@ -1,15 +1,15 @@
1
- # CR8 desktop wrapper
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 the window drains the loopback server and releases the project lease.
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 wrapper has no preload bridge. 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.
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, CR8 opens the only valid project it discovers. It fails safely when none or several exist instead of guessing or using a global recent-file database.
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 desktop process owns the project's single-writer lease while it is open. CLI agent commands can target the loopback URL printed by the process. Design and Flows use the same workspace identity and runtime, while scene sequence and workflow revision remain separate. Starting another local runtime for the same project correctly fails with `project_locked`, naming the desktop process and its port; close the desktop window before opening that project in another MCP process. **File → Open Project Folder…** relaunches the window on another folder. When the window attaches to a running runtime, it trusts the account origin that runtime reports on `/health`; a loopback `http://127.0.0.1` account hub is accepted while developing the hub.
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
 
@@ -31,7 +59,7 @@ Build the packaged runtime before the main process:
31
59
 
32
60
  ```sh
33
61
  npm run build:package
34
- npm run build:desktop:main
62
+ npm run build --workspace @cr8/desktop
35
63
  ```
36
64
 
37
65
  Run the built wrapper with Electron and explicit project arguments:
@@ -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
- `apps/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 update itself: a new version is a new download, and the runtime inside it tells you when a newer CR8 exists.
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.
@@ -1,6 +1,10 @@
1
1
  # Feedback for CR8
2
2
 
3
- CR8 uses [Hivenet](https://hivenet.app) as its agent feedback channel. This is for actionable product reports from agents or people working on CR8 and from agents using the installed CLI, MCP server, MCP App, or docs.
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
 
@@ -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. Before the first release the npm package only holds the name and the binaries are not published, so collaborators install from source (below); the npm and binary sections describe what the release workflow produces.
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 source (today)
8
+ ## From npm
9
9
 
10
- You need Git and Node.js 20.19 or newer.
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
- ## A release binary (after the first release)
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
- Each GitHub release carries one executable per platform, a `SHA256SUMS.txt` and a build-provenance attestation:
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 (signed and notarized) |
35
- | `cr8-darwin-x64.zip` | Intel Macs (signed and notarized) |
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 -c SHA256SUMS.txt --ignore-missing
43
- unzip cr8-darwin-arm64.zip && ./cr8-darwin-arm64 start designs/first
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. A macOS archive whose name ends in `-unsigned` was built without the signing certificate; Gatekeeper will refuse it until you allow it in System Settings, and a signed release is the fix, not a habit.
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 a tool is called and stops it when the session ends. Do not start a separate server for the agent.
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
- Codex passes the workspace through MCP roots. Ask it: *Initialize CR8 at `designs/thumbnail` and create a 1280 × 720 YouTube thumbnail. Keep every layer editable and show me the canvas.*
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
- Claude Code exposes its project directory to the server. Once the package is public the plugin marketplace is the shorter road: `/plugin marketplace add zvadaadam/baby-canva`, then `/plugin install cr8`.
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
- **Any host, per project.** The repository's `.mcp.json` starts the server with `--workspace .`; copy it into a project to pin CR8 to that repository. The Codex plugin carries its own server file, `.codex-plugin/mcp.json`, which runs the bundled runtime from wherever the plugin was installed.
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 `canvas_skills` and `canvas_skill`, 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.
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 flow outputs alike
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, by the paths of the copies in `assets/`. The Flows home and the graph read it, on this computer or in a clone.
129
- - `assets/` holds immutable content-addressed imports, Design generations and flow outputs. Documents store relative `assets/…` paths, so the directory survives moves and clones.
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 opens with every design, every flow and what each flow last made. Nothing global decides which repository an agent edits.
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, and a completed flow run's images and SVGs are copied there the same way, so what a flow made travels with the project; a clip stays on its cloud path. Losing the network stops new generations; it does not stop a design from opening.
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
- Restart the agent host afterwards. Projects live in their own repositories, so an update cannot touch them. The desktop app does not update itself; see the [desktop wrapper](desktop.md).
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).