@gavana.ai/cli 0.2.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/LICENSE.md +7 -0
  3. package/README.md +237 -0
  4. package/bin/craftboard.mjs +5 -0
  5. package/bin/gavana.mjs +5 -0
  6. package/guides/connections.md +35 -0
  7. package/guides/examples-common-mistakes.md +29 -0
  8. package/guides/existing-canvases.md +19 -0
  9. package/guides/generated-assets.md +29 -0
  10. package/guides/getting-started.md +26 -0
  11. package/guides/notes-text-sections.md +44 -0
  12. package/guides/paid-action-safety.md +22 -0
  13. package/guides/prompt-lists.md +20 -0
  14. package/guides/sections-layout.md +43 -0
  15. package/guides/validation-recovery.md +33 -0
  16. package/package.json +44 -0
  17. package/src/canvas-agent-guide.mjs +133 -0
  18. package/src/canvas-agent-validation.mjs +554 -0
  19. package/src/canvas-layout.mjs +287 -0
  20. package/src/capabilities.mjs +61 -0
  21. package/src/client.mjs +1141 -0
  22. package/src/commands.mjs +259 -0
  23. package/src/config.mjs +197 -0
  24. package/src/guide-sources.mjs +86 -0
  25. package/src/runner.mjs +1968 -0
  26. package/src/tools/action_get.mjs +16 -0
  27. package/src/tools/action_list.mjs +21 -0
  28. package/src/tools/action_run.mjs +60 -0
  29. package/src/tools/agent_canvas_get.mjs +15 -0
  30. package/src/tools/asset_get.mjs +16 -0
  31. package/src/tools/asset_list.mjs +17 -0
  32. package/src/tools/asset_upload.mjs +24 -0
  33. package/src/tools/campaign_cancel.mjs +16 -0
  34. package/src/tools/campaign_get.mjs +16 -0
  35. package/src/tools/campaign_plan.mjs +31 -0
  36. package/src/tools/campaign_review.mjs +24 -0
  37. package/src/tools/campaign_start.mjs +19 -0
  38. package/src/tools/canvas_apply_batch.mjs +35 -0
  39. package/src/tools/canvas_create.mjs +15 -0
  40. package/src/tools/canvas_get.mjs +16 -0
  41. package/src/tools/canvas_list.mjs +17 -0
  42. package/src/tools/canvas_render.mjs +34 -0
  43. package/src/tools/canvas_validate.mjs +34 -0
  44. package/src/tools/connection_create.mjs +38 -0
  45. package/src/tools/connection_delete.mjs +31 -0
  46. package/src/tools/definitions.mjs +111 -0
  47. package/src/tools/guide_get.mjs +16 -0
  48. package/src/tools/guide_search.mjs +16 -0
  49. package/src/tools/helpers.mjs +66 -0
  50. package/src/tools/image_edit.mjs +8 -0
  51. package/src/tools/image_generate.mjs +8 -0
  52. package/src/tools/image_tool.mjs +56 -0
  53. package/src/tools/image_variations.mjs +8 -0
  54. package/src/tools/job_cancel.mjs +16 -0
  55. package/src/tools/job_get.mjs +17 -0
  56. package/src/tools/job_wait.mjs +18 -0
  57. package/src/tools/model_get.mjs +16 -0
  58. package/src/tools/model_list.mjs +23 -0
  59. package/src/tools/node_create.mjs +36 -0
  60. package/src/tools/node_delete.mjs +31 -0
  61. package/src/tools/node_get.mjs +16 -0
  62. package/src/tools/node_move.mjs +37 -0
  63. package/src/tools/node_resize.mjs +37 -0
  64. package/src/tools/node_update.mjs +36 -0
  65. package/src/tools/progress.mjs +101 -0
  66. package/src/tools/provider_list.mjs +17 -0
  67. package/src/tools/recipe_fork.mjs +32 -0
  68. package/src/tools/recipe_get.mjs +19 -0
  69. package/src/tools/recipe_run.mjs +61 -0
  70. package/src/tools/recipe_search.mjs +17 -0
  71. package/src/tools/registry.mjs +550 -0
  72. package/src/tools/run_cancel.mjs +16 -0
  73. package/src/tools/run_get.mjs +17 -0
  74. package/src/tools/run_wait.mjs +18 -0
  75. package/src/tools/schemas.mjs +165 -0
  76. package/src/tools/video_generate.mjs +37 -0
  77. package/src/version.mjs +12 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,54 @@
1
+ # Changelog — @gavana.ai/cli
2
+
3
+ ## 0.2.0
4
+
5
+ First release published to npm. Version 0.1.0 existed in this repository but was
6
+ never published, so there is no upgrade path to describe — everything below is
7
+ what shipped between the two internal versions, kept here because the package
8
+ exports (`@gavana.ai/cli/client`, `@gavana.ai/cli/capabilities`) are consumed
9
+ inside the repository and by the MCP server.
10
+
11
+ ### Added
12
+
13
+ - **One command table.** `src/commands.mjs` declares every `gavana` command
14
+ once. Root help, per-group help, and the zsh/bash/fish completion scripts are
15
+ all generated from it, and dispatch is gated on it. Before, those four things
16
+ were four hand-maintained copies of the same list, and they had drifted.
17
+ - **Shell completions complete sub-commands.** `gavana completion zsh|bash|fish`
18
+ previously offered only the top-level groups; it now offers each group's
19
+ actions too. Deprecated and alias commands stay dispatchable and stay out of
20
+ completions.
21
+ - **Tool registry export.** `src/tools/registry.mjs` carries every tool
22
+ definition shared by the stdio MCP server and the hosted endpoint, with each
23
+ tool's schema in `src/tools/schemas.mjs`.
24
+ - **Progress helper.** `src/tools/progress.mjs` turns the client's existing
25
+ `onProgress` polling callback into MCP `notifications/progress` messages.
26
+ - **Guides as markdown.** The Canvas Agent Guide is now
27
+ `packages/cli/guides/*.md` rather than string literals, and ships in the
28
+ package.
29
+
30
+ ### Fixed
31
+
32
+ - An unknown command is now rejected wherever it appears. `gavana version bogus`
33
+ and `gavana capabilities bogus` used to print a result and exit 0, because
34
+ both commands answered before anything checked whether the command existed.
35
+ They now exit 2 with `Unknown command`. `gavana --version` still answers, as
36
+ it carries no command at all.
37
+
38
+ ### Deprecated
39
+
40
+ Still callable; nothing is removed in 0.2.0.
41
+
42
+ - **`gavana campaign *`** — `plan`, `start`, `get`, `review`, `cancel`. Hidden
43
+ from help and completions, and rejected unless
44
+ `GAVANA_ENABLE_LEGACY_CAMPAIGN_COMMANDS=true`. Existing `gavana recipe *`
45
+ commands remain API compatibility operations; this does not expose the
46
+ production Recipe UI.
47
+ - **`gavana ai-connection list`** — a compatibility alias for
48
+ `gavana provider list`. Dispatches identically, no longer advertised.
49
+
50
+ ### Compatibility
51
+
52
+ - The `craftboard` and `craftboard-canvas` binaries, and the
53
+ `CRAFTBOARD_*` environment variables, continue to work as aliases. They are
54
+ not deprecated.
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ # Gavana Customer Package License
2
+
3
+ Copyright 2026 Gavana. All rights reserved.
4
+
5
+ This package is proprietary software. Permission to install and use it is
6
+ governed by the current [Gavana Terms of Service](https://app.gavana.ai/terms).
7
+ No rights are granted beyond those terms.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # Gavana CLI
2
+
3
+ The Gavana CLI is a JSON-first command-line client for the Gavana
4
+ Canvas API. It can read and change canvases, work with assets, explicitly run
5
+ Recipes, run deterministic Image Actions, and observe every execution through
6
+ shared Run and Job interfaces without opening the browser. It also queues
7
+ model-aware video generation with local or durable frame references.
8
+
9
+ ## Install from npm
10
+
11
+ ```sh
12
+ npm install --global @gavana.ai/cli
13
+ gavana --help
14
+ ```
15
+
16
+ The npm command works after the package owner publishes this release. For local
17
+ package verification from the Gavana repository, run
18
+ `npm run test:canvas-cli-package`.
19
+
20
+ Use of the published CLI is subject to the current
21
+ [Gavana Terms of Service](https://app.gavana.ai/terms). Its customer package
22
+ license incorporates those terms by reference.
23
+
24
+ Node.js 20 or newer is required. `craftboard` and `craftboard-canvas` remain
25
+ available as compatibility aliases.
26
+
27
+ ## Sign in
28
+
29
+ Browser OAuth is the default:
30
+
31
+ ```sh
32
+ gavana auth login
33
+ gavana auth status
34
+ ```
35
+
36
+ The CLI opens Gavana, asks the user to approve exact scopes, and returns through
37
+ a loopback callback. On macOS the resulting revocable token is stored in
38
+ Keychain; custom config paths and other platforms use the mode-`0600` config
39
+ file. Use `--read-only` for a browse-only profile.
40
+
41
+ Named profiles keep accounts and environments separate:
42
+
43
+ ```sh
44
+ gavana auth login --profile work
45
+ gavana auth login --profile staging --base-url https://staging.example.com
46
+ gavana config list
47
+ gavana config use work
48
+ gavana canvas list --profile staging
49
+ ```
50
+
51
+ Manual Agent Access tokens remain supported for automation and compatibility.
52
+
53
+ Create an Agent Access token in Gavana, then save it without putting the
54
+ secret in shell history. On zsh (the default shell on current macOS):
55
+
56
+ ```sh
57
+ read -rs 'GAVANA_AGENT_TOKEN?Paste Agent Access token: '; printf '\n'; printf '%s' "$GAVANA_AGENT_TOKEN" | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin; unset GAVANA_AGENT_TOKEN
58
+ gavana auth status
59
+ ```
60
+
61
+ On Bash:
62
+
63
+ ```bash
64
+ read -rsp 'Paste Agent Access token: ' GAVANA_AGENT_TOKEN; printf '\n'; printf '%s' "$GAVANA_AGENT_TOKEN" | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin; unset GAVANA_AGENT_TOKEN
65
+ ```
66
+
67
+ On PowerShell:
68
+
69
+ ```powershell
70
+ $secureToken = Read-Host 'Paste Agent Access token' -AsSecureString
71
+ $token = [System.Net.NetworkCredential]::new('', $secureToken).Password
72
+ $token | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin
73
+ Remove-Variable token, secureToken
74
+ ```
75
+
76
+ The saved configuration lives at
77
+ `~/.config/gavana/agent.json` with file mode `0600`. Environment variables
78
+ `GAVANA_BASE_URL` and `GAVANA_AGENT_TOKEN` override saved values. Existing
79
+ `~/.config/craftboard/agent.json` and `CRAFTBOARD_*` aliases remain readable.
80
+
81
+ ## Discover and diagnose
82
+
83
+ ```sh
84
+ gavana doctor
85
+ gavana version
86
+ gavana completion zsh
87
+ gavana canvas --help
88
+ gavana api GET /canvases --field limit=10
89
+ gavana mcp install codex
90
+ gavana mcp install codex --read-only
91
+ gavana mcp config cursor
92
+ ```
93
+
94
+ JSON remains the stable scripting default. Use `--output human` for a compact
95
+ terminal view, or `jsonl`, `markdown`, `raw`, and `--jq` for composition.
96
+ Transient network errors and `429/502/503/504` responses are retried only for
97
+ safe GET requests, respecting `Retry-After`; paid generation writes are never
98
+ retried automatically.
99
+
100
+ ## Examples
101
+
102
+ ```sh
103
+ gavana canvas list
104
+ gavana canvas list --limit 25 --jq '.canvases[].handle' -r
105
+ gavana asset get asset:OWNER_UID:ASSET_ID
106
+ gavana recipe search "product visual"
107
+ gavana recipe run recipe:product-visual-direction --input product-context="A matte black travel bottle" --destination agent-canvas
108
+ gavana model list --capability image.generate
109
+ gavana model get model:OPAQUE_MODEL_KEY
110
+ gavana action list
111
+ gavana action get action:resize
112
+ gavana action run action:resize --input ./product.png --destination agent-canvas --width 1080 --height 1350
113
+ gavana image generate --destination agent-canvas --model model:OPAQUE_MODEL_KEY --prompt "A studio product photograph"
114
+ gavana model list --capability video.generate
115
+ gavana video generate --model model:OPAQUE_MODEL_KEY --prompt "A slow product turntable" --duration 15 --aspect-ratio 9:16 --download ./turntable.mp4
116
+ gavana video generate --model model:OPAQUE_MODEL_KEY --prompt "Animate the fabric naturally" --first-frame ./product.png --no-wait
117
+ gavana video download job:JOB_ID --file ./result.mp4
118
+ gavana run wait run:RUN_ID --output markdown
119
+ ```
120
+
121
+ `video generate` validates duration, aspect ratio, resolution, audio, and frame
122
+ capabilities against the selected model before starting paid work. Use
123
+ `gavana model get model:OPAQUE_MODEL_KEY` to inspect its exact values.
124
+ First frame, last frame, and repeatable `--reference` inputs accept image
125
+ `node:` or `asset:` handles, public HTTPS URLs, local image paths, stdin (`-`),
126
+ or the macOS clipboard. Local images upload privately first. Pass
127
+ `--canvas canvas:<id>` when any input is a `node:` handle. A last frame requires
128
+ a first frame.
129
+
130
+ Video generation returns a `job:` handle. By default the CLI waits up to 30
131
+ minutes and returns the completed job with its authenticated video download
132
+ path. Add `--download ./output.mp4` to stream the successful result directly to
133
+ disk, or use `video download job:<id> --file ./output.mp4` later. Existing files
134
+ are preserved unless `--yes` is supplied. Use `--no-wait` to return after
135
+ queueing, then use `job get`, `job wait`, or `job cancel`. Waiting, downloading,
136
+ and cancellation require `job:manage`; generation requires `canvas:read`,
137
+ `asset:read`, and `video:generate`.
138
+
139
+ Image Actions resize, crop, reframe, composite, add text, overlay, color grade,
140
+ or rotate existing images. They are deterministic and do not spend AI credits.
141
+ Use `action get` to inspect the exact input order, valid fields, defaults, and
142
+ limits. `action run` accepts `node:` and `asset:` handles, local image paths,
143
+ stdin (`-`), or the macOS clipboard.
144
+ Local, stdin, and clipboard inputs are privately uploaded first and therefore
145
+ also require the token's `image:generate` scope; existing handles do not.
146
+
147
+ For reference-aware image generation, repeat `--reference` for every durable
148
+ visual and repeat `--reference-role` in the same order when the role is known:
149
+ `identity`, `construction`, `texture`, `fit`, or `style`. Gavana records the
150
+ exact handles and roles in the job result and target-node provenance, and sends
151
+ the request through the reference/edit backend rather than dropping inputs into
152
+ a prompt-only fallback.
153
+
154
+ `recipe run` takes repeatable named inputs such as
155
+ `--input product-context="A matte black travel bottle"` and
156
+ `--input offer-brief=@brief.md`. Use the exact keys returned by `recipe get`.
157
+ For distinct product variants, use a Prompt List: connect the product image
158
+ once to the List, make one explicit direction per row, and connect the List to
159
+ an image generator. Each row inherits the same reference; agents should state
160
+ that the exact product must be preserved and never substituted. For a style
161
+ that belongs to only one row, use that row's `referenceBindings` with the
162
+ durable image handle (`{ "nodeId": "node:<id>", "role": "style" }`), rather
163
+ than inserting a copied image name into prompt text. Gavana preserves the
164
+ shared Product -> Prompt List -> output path and draws the row Style -> output
165
+ edge separately.
166
+ Written ports accept text, text/sticky `node:` handles, and image handles when
167
+ the Recipe asks for “an image or written note.” Image ports may also use local
168
+ raster paths, stdin, or the clipboard and are uploaded privately first. Upload
169
+ a local visual first and pass its `asset:` handle when using it on a written
170
+ reference port; `@path` on that port reads the file as text. Starting a Recipe
171
+ creates a private instance when needed, materializes its declared outputs on
172
+ the destination canvas, and returns their durable `node:` and `asset:` handles.
173
+ `recipe fork` remains setup-only and never starts a Run. All Recipe starts
174
+ currently require `image:generate` and its dependent scopes, including
175
+ text-only Recipes.
176
+
177
+ Recipe, image, and Action work returns a shared `run:` handle with typed outputs,
178
+ duration estimates, observed queue/execution timing, and stable retry guidance.
179
+ Default waiting and `run get|wait|cancel` require `job:manage`; a start-only
180
+ token can use `--no-wait` with a signed webhook.
181
+ The legacy `job:` handle remains an image and Action compatibility alias; it is
182
+ never used for Recipes. Image and Action `run:` and `job:` handles point to the
183
+ same temporary record and expire together:
184
+ the default retention is 24 hours while unacknowledged, 15 minutes after the
185
+ first successful server finalization (from a Run GET or callback), and seven
186
+ days for the expired tombstone. Recipe Run records currently persist without
187
+ that temporary TTL. Persist the returned durable asset and node handles.
188
+ For a signed terminal
189
+ callback, provide the endpoint and read the secret from an environment
190
+ variable:
191
+
192
+ ```sh
193
+ read -rs 'GAVANA_WEBHOOK_SECRET?Webhook signing secret: '; printf '\n'
194
+ export GAVANA_WEBHOOK_SECRET
195
+ gavana image generate \
196
+ --destination agent-canvas \
197
+ --prompt "A studio product photograph" \
198
+ --webhook-url 'https://automation.example.com/hooks/gavana' \
199
+ --no-wait
200
+ unset GAVANA_WEBHOOK_SECRET
201
+ ```
202
+
203
+ Use `--webhook-secret-env NAME` to select a different variable. The CLI never
204
+ prints the secret. Successful Image and Action callbacks are sent only after
205
+ Gavana has stored the durable canvas, node, and asset results. Failed,
206
+ canceled, or expired callbacks describe the terminal state without requiring
207
+ images; Recipe callbacks contain their typed terminal outputs. A start-only token remains revocable while
208
+ Gavana's worker resumes the Run independently of the original CLI process.
209
+ If the token expires or is revoked first, the Recipe stops with
210
+ `delegation_revoked` and sends its signed failed callback.
211
+
212
+ Commands emit one JSON result to stdout by default. Progress and errors go to
213
+ stderr, making the CLI safe to compose in scripts and agent workflows. List
214
+ commands for canvases, recipes, assets, Actions, models, and providers accept `--limit` and
215
+ `--cursor`; responses return the continuation at `page.nextCursor`. Use
216
+ `--output jsonl` for line-oriented output. The built-in
217
+ `--jq` selector supports property paths, array indexes, and `[]` projections
218
+ without requiring a separate jq installation.
219
+
220
+ ## JavaScript client
221
+
222
+ The same dependency-free client is exported for Node.js applications:
223
+
224
+ ```js
225
+ import { createCanvasAgentClient } from "@gavana.ai/cli";
226
+
227
+ const client = createCanvasAgentClient({
228
+ baseUrl: process.env.GAVANA_BASE_URL,
229
+ token: process.env.GAVANA_AGENT_TOKEN,
230
+ surface: "api",
231
+ });
232
+
233
+ const result = await client.listCanvases();
234
+ ```
235
+
236
+ Remote servers must use HTTPS. Plain HTTP is accepted only for local loopback
237
+ development.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runCraftboardAgentCli } from "../src/runner.mjs";
4
+
5
+ process.exitCode = await runCraftboardAgentCli();
package/bin/gavana.mjs ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runGavanaCli } from "../src/runner.mjs";
4
+
5
+ process.exitCode = await runGavanaCli();
@@ -0,0 +1,35 @@
1
+ ---
2
+ id: connections
3
+ title: Connections
4
+ description: Create directed, persistent relationships with valid endpoint semantics.
5
+ keywords: ["connection","connect","edge","direction","input","output","reference","list","first-frame","last-frame","prompt"]
6
+ order: 4
7
+ ---
8
+
9
+ ## Direction
10
+
11
+ A connection goes from source to target. Use source input or instruction -> transformation or generator -> output. Never connect a node to itself, and never connect a Section as if it were a workflow step.
12
+
13
+ ## Modes
14
+
15
+ - Omit `mode` for a normal dependency or transformation flow.
16
+ - `prompt`: a text or sticky note whose content is the generation prompt for the target image node. One prompt connection per target; image generation reads the prompt from this node when the request omits a prompt.
17
+ - `reference`: an image reference that guides another node.
18
+ - `list`: a Prompt List or Image List flow.
19
+ - `first-frame`: an image used as the first frame of a video node.
20
+ - `last-frame`: an image used as the last frame of a video node.
21
+
22
+ Use exact `node:` handles or batch-local `client:` references. Connections remain attached when nodes move. Avoid duplicate edges with the same source, target, and mode.
23
+
24
+ ## Batch-local example
25
+
26
+ ```json
27
+ {
28
+ "type": "connection.create",
29
+ "clientId": "brief-to-generator",
30
+ "from": "client:brief",
31
+ "to": "client:generator"
32
+ }
33
+ ```
34
+
35
+ Do not rely on spatial proximity to imply a relationship. If a relationship matters to execution or later understanding, connect it.
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: examples-common-mistakes
3
+ title: Examples and Common Mistakes
4
+ description: Compact patterns to copy and anti-patterns agents must avoid.
5
+ keywords: ["example","examples","mistake","mistakes","anti-pattern","section","note","text","generated","connection"]
6
+ order: 10
7
+ ---
8
+
9
+ ## Good patterns
10
+
11
+ - Research cluster: one Section, several Sticky observations, one Text synthesis, and directed observation -> synthesis connections.
12
+ - Creative workflow: source image -> Prompt List -> empty generator -> generated outputs.
13
+ - Video workflow: first image -[first-frame]-> video target and optional last image -[last-frame]-> video target.
14
+ - Existing-canvas addition: new contained Section outside the current bounds, with no existing-node mutations.
15
+
16
+ ## Common mistakes
17
+
18
+ - Using long Text or Sticky nodes as fake headers instead of Sections.
19
+ - Creating every node at `{ "x": 0, "y": 0 }` or stacking nodes on top of one another.
20
+ - Leaving generated outputs disconnected from their prompt, List, source, or stage.
21
+ - Connecting a Section to workflow nodes.
22
+ - Treating nearby objects as implicit inputs without explicit handles or connections.
23
+ - Copying a style image name into prompt text instead of using a row-level reference binding.
24
+ - Writing generated media content directly into node metadata.
25
+ - Reorganizing or deleting existing work when the user asked only to add something.
26
+ - Starting generation when the user asked only to prepare a workflow.
27
+ - Retrying a failed paid operation automatically.
28
+ - Reporting a temporary Job or Run handle as a durable Canvas output.
29
+ - Passing `force: true` to push a batch past error-severity findings instead of fixing the operations. Force is for explicit, user-approved exceptions only.
@@ -0,0 +1,19 @@
1
+ ---
2
+ id: existing-canvases
3
+ title: Editing Existing Canvases Safely
4
+ description: Preserve user structure, concurrent edits, and unrelated content while making scoped changes.
5
+ keywords: ["existing","preserve","concurrent","revision","conflict","409","idempotency","unrelated","delete","scope"]
6
+ order: 7
7
+ ---
8
+
9
+ ## Preservation contract
10
+
11
+ - Call `canvas_get` and retain the exact revision before planning a write.
12
+ - Make the smallest requested delta. Do not move, resize, retitle, reconnect, delete, or rewrite an existing node outside the requested scope.
13
+ - Prefer one atomic batch for related nodes and connections so a malformed operation leaves no partial graph.
14
+ - Pass the read revision as `baseRevision`.
15
+ - On `409`, read again and rebase the intended additions around the newer graph. Preserve the concurrent user change.
16
+ - Reuse an idempotency key only for an identical intended payload. If the intended payload changes, use a new key.
17
+ - Pass proposed delete operations to `canvas_validate` and report their node and connection impact before applying them.
18
+
19
+ An agent-authored addition should be removable without damaging surrounding user work. Exact returned handles are the audit trail.
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: generated-assets
3
+ title: Generated Images, Videos, and Durable Outputs
4
+ description: Prepare media nodes, start only explicit generation, and preserve output lineage.
5
+ keywords: ["generated","generation","image","video","output","asset","durable","lineage","placeholder","job"]
6
+ order: 6
7
+ ---
8
+
9
+ ## Before generation
10
+
11
+ - Read the destination canvas and relevant source nodes.
12
+ - Use exact source `node:` or `asset:` handles.
13
+ - For a standalone image request, pass every visual source in `references`.
14
+ Use `{ "handle": "node:...", "role": "identity" }` when its
15
+ responsibility is known; valid roles are `identity`, `construction`,
16
+ `texture`, `fit`, and `style`. Do not flatten multi-reference work
17
+ into prompt prose or omit a source during fallback.
18
+ - Create an empty image or video target only through supported operations. Do not write media bytes, storage keys, or arbitrary output URLs into metadata.
19
+ - Connect prompts, products, references, Lists, and frame inputs to their target with the correct direction and mode.
20
+
21
+ ## Paid execution
22
+
23
+ Generation is allowed only after explicit current-turn user intent. Start one run with one caller-stable idempotency key. Poll the returned Run or Job; do not start another run while waiting. A terminal failure must be reported without automatic retry.
24
+
25
+ ## Completion
26
+
27
+ Do not claim a generated image is durable until the result returns a target `node:`, durable `asset:`, and the final canvas read shows server-owned media fields. A video Job may return a protected download without materializing a native video node; report exactly what the server returned and do not invent durability.
28
+
29
+ Keep generated output spatially near its input stage and connected to its source, prompt, List, or workflow. After finalization, run `canvas_validate` and read `completionReview`: it reports overlap, full-frame Section containment, reference lineage, durable output count, and product-fidelity review state. Do not claim Done while it says `doneClaimAllowed: false`. Product-fidelity uncertainty requires human review; never create another paid provider call automatically.
@@ -0,0 +1,26 @@
1
+ ---
2
+ id: getting-started
3
+ title: Canvas Agent Workflow
4
+ description: The required inspect, guide, validate, edit, and review sequence for every canvas task.
5
+ keywords: ["start","workflow","inspect","read","validate","edit","review","revision","idempotency"]
6
+ order: 1
7
+ ---
8
+
9
+ ## Required sequence
10
+
11
+ 1. Identify one exact canvas handle. Never guess between candidates.
12
+ 2. Call `canvas_get` before reasoning about or changing an existing canvas.
13
+ 3. Read the guide topics relevant to the requested operation.
14
+ 4. Plan the smallest graph change that satisfies the request. Preserve unrelated nodes, connections, positions, metadata, and the user's current structure.
15
+ 5. Call `canvas_validate` with the proposed operations before a large, spatial, or destructive batch.
16
+ 6. Apply related changes atomically with `canvas_apply_batch`, the current `baseRevision`, and one caller-stable idempotency key.
17
+ 7. If a write returns revision conflict `409`, read the canvas again, preserve the newer user change, and retry the same intent. Reuse the same idempotency key only for the same payload.
18
+ 8. Call `canvas_validate` after editing. Report exact changed handles and unresolved warnings.
19
+
20
+ ## Non-negotiable safety
21
+
22
+ - Building or preparing a workflow does not mean running it.
23
+ - Never start image, video, Action, or Recipe generation unless the user explicitly requested that paid action in the current conversation.
24
+ - Never automatically retry a failed paid action.
25
+ - Never delete, disconnect, overwrite, or reorganize existing work unless the user explicitly requested that scope.
26
+ - Generated media content is server-owned. Use generation or import tools; do not place bytes or arbitrary media URLs into node metadata.
@@ -0,0 +1,44 @@
1
+ ---
2
+ id: notes-text-sections
3
+ title: Notes, Text, and Sections
4
+ description: Choose the correct native canvas object for observations, durable copy, headings, and spatial groups.
5
+ keywords: ["note","notes","sticky","text","heading","header","section","frame","content","annotation"]
6
+ order: 2
7
+ ---
8
+
9
+ ## Object grammar
10
+
11
+ - Sticky note: one short observation, idea, decision, question, or human annotation. Create a `sticky` node and put the readable value in `metadata.content`.
12
+ - Text: a paragraph, prompt, brief, instruction, caption, or durable written output. Create a `text` node and put the body in `metadata.content`.
13
+ - Section: a labeled spatial container and navigation landmark. Create a `text` node with `metadata.isSection: true`. Put the section title in `title`; keep `metadata.content` empty unless the user asked for a section description.
14
+ - Heading: use the title of a real Section. Do not stretch an ordinary Text or Sticky node across the canvas to imitate a section header.
15
+
16
+ ## Section example
17
+
18
+ ```json
19
+ {
20
+ "type": "node.create",
21
+ "clientId": "research-section",
22
+ "node": {
23
+ "type": "text",
24
+ "title": "Customer objections",
25
+ "position": { "x": 1200, "y": 200 },
26
+ "width": 1040,
27
+ "height": 720,
28
+ "metadata": { "isSection": true }
29
+ }
30
+ }
31
+ ```
32
+
33
+ Place each child's complete frame inside the Section bounds; a centered but
34
+ overflowing frame is not contained. A Section may overlap its children by
35
+ design; ordinary nodes should not overlap one another. A child whose frame
36
+ crosses its Section boundary receives a `section_content_overflow` finding.
37
+
38
+ ## Stored membership
39
+
40
+ Membership is stored: the server keeps `metadata.sectionId` on every node
41
+ whose complete frame fits inside a Section, recomputing it after each batch on
42
+ create, move, resize, and delete. When Sections nest or overlap, the smallest
43
+ containing Section wins. Do not set `sectionId` yourself — geometry is the
44
+ source of truth and caller-supplied values are corrected.
@@ -0,0 +1,22 @@
1
+ ---
2
+ id: paid-action-safety
3
+ title: Paid Action Safety
4
+ description: Separate preparation from execution and prevent accidental or repeated provider charges.
5
+ keywords: ["paid","credits","cost","generate","run","retry","failure","prepare","setup","explicit"]
6
+ order: 8
7
+ ---
8
+
9
+ ## Intent boundary
10
+
11
+ "Build", "prepare", "set up", "connect", "draft", and "make ready" authorize graph edits only. They do not authorize Recipe, image, video, or Action execution.
12
+
13
+ Start paid work only when the current user message explicitly asks to run or generate it. Do not infer authorization from an older message, a node label, an unfinished placeholder, or nearby content.
14
+
15
+ ## Retry boundary
16
+
17
+ - Use one stable idempotency key for one intended paid operation.
18
+ - Poll the returned handle with status tools.
19
+ - Never automatically retry a terminal failure, timeout, disconnect, or ambiguous provider response with a new key.
20
+ - Ask for new user intent before any new paid attempt.
21
+
22
+ Deterministic Actions may be described as credit-free only when `action_get` confirms that contract. Inspect an Action before running it.
@@ -0,0 +1,20 @@
1
+ ---
2
+ id: prompt-lists
3
+ title: Prompt Lists and Repeated Directions
4
+ description: Represent several editable creative directions as one native Prompt List with shared and row-specific references.
5
+ keywords: ["prompt","list","directions","rows","referenceBindings","product","style","batch","generator"]
6
+ order: 5
7
+ ---
8
+
9
+ ## Prompt List shape
10
+
11
+ Use one `text` node with:
12
+
13
+ - `metadata.isList: true`
14
+ - `metadata.listType: "prompt"`
15
+ - `metadata.listExecutionMode: "batch"` for separate outputs
16
+ - one checked `metadata.listItems` entry per direction
17
+
18
+ Connect a shared product image to the List once. Connect the List to one empty image generator. For a row-specific style, store the exact style image in that row's `referenceBindings` as `{ "nodeId": "node:<id>", "role": "style" }`. Do not copy a filename into prompt prose as a substitute for a binding.
19
+
20
+ Every product-variant row should explicitly say to preserve the exact connected product and not substitute it. Building the List and generator prepares the workflow only; it must not start generation.
@@ -0,0 +1,43 @@
1
+ ---
2
+ id: sections-layout
3
+ title: Sections and Layout
4
+ description: Place native objects in readable groups without hiding or rearranging existing work.
5
+ keywords: ["section","layout","position","overlap","spacing","grid","right","below","contain","navigation"]
6
+ order: 3
7
+ ---
8
+
9
+ ## Layout rules
10
+
11
+ - Treat the current canvas as user-owned. Preserve existing coordinates unless reorganization was explicitly requested.
12
+ - For additions to an existing canvas, compute its visible bounding box and place the new Section to the right with at least 160 canvas units of outer spacing. If right-side placement would make the canvas excessively wide, place it below with the same spacing.
13
+ - Use 48 units of inner Section padding, 32 units between sibling nodes, and at least 80 units between major stages.
14
+ - Keep workflow direction consistent, normally left to right. Keep inputs before transformations and outputs after them.
15
+ - Use compact rows or columns. Avoid extremely long, thin canvases that become unreadable at Fit Canvas.
16
+ - For 2-8 generated image outputs, reserve each requested final aspect frame before work begins and pack the complete result cluster as a grid. The usual four-image photoshoot is a 2x2 grid; do not stack it as a tall output column that can overlap when images finalize.
17
+ - Size Sections after their contents. Do not use Section overlap as a substitute for node placement.
18
+ - Run `canvas_validate` before and after a multi-node layout change.
19
+
20
+ ## One task = one Section
21
+
22
+ Group each task's output in a titled Section sized to its contents plus 48
23
+ units of padding. Workflow creation and multi-output image generation wrap
24
+ their clusters in a Section automatically (multi-output wrapping applies to
25
+ automatic placement; passing explicit target coordinates opts out and leaves
26
+ placement fully caller-controlled); do the same for hand-built
27
+ clusters. Agent-created nodes left outside every Section raise an info-level
28
+ `unsectioned_node` finding. Membership is stored server-side as
29
+ `metadata.sectionId`, recomputed from complete-frame geometry after every
30
+ batch. Agent-created Sections receive an owned auto-fit contract; after a
31
+ generated child changes size, Gavana refits only that still-owned Section to
32
+ the full child bounds plus 48 units. Do not use this as permission to move or
33
+ resize a user-controlled Section.
34
+
35
+ For a newly proposed agent cluster, ordinary-node overlap and full-frame
36
+ Section overflow are write-blocking errors. On an existing Canvas, historical
37
+ user-created overlap or overflow remains advisory so an unrelated scoped edit
38
+ can still proceed. Agent-owned task findings still block completion review
39
+ until they are corrected.
40
+
41
+ ## Existing canvas rule
42
+
43
+ When the user says "add", do not interpret it as "reorganize". New work should be distinguishable, spatially contained, and reversible without moving unrelated content.
@@ -0,0 +1,33 @@
1
+ ---
2
+ id: validation-recovery
3
+ title: Validation and Recovery
4
+ description: Interpret structural findings, correct invalid batches, and finish with an evidence-based review.
5
+ keywords: ["validate","lint","overlap","orphan","header","connection","destructive","recovery","error","atomic","blocked","force"]
6
+ order: 9
7
+ ---
8
+
9
+ ## Use `canvas_validate`
10
+
11
+ Call it with only `canvasId` to audit the current graph. Pass the proposed `operations` to inspect the planned post-batch graph and destructive impact before writing.
12
+
13
+ Warning- and info-level findings are advisory. Error-severity findings caused by the proposed agent write have teeth: `canvas_apply_batch` rejects that batch and writes nothing. Historical findings remain visible for review but do not turn an unrelated scoped write into a forced cleanup. Validation never mutates the canvas or consumes an idempotency key.
14
+
15
+ `summary.passed` means there is no structural error. `summary.reviewRequired` is true when errors, warnings, or truncated findings still require agent or human review. `completionReview` is the finalization-ready structured view: it names overlap, containment, reference lineage, output count, and product-fidelity state. Never claim Done unless `completionReview.doneClaimAllowed` is true.
16
+
17
+ ## Blocked writes
18
+
19
+ When a batch is rejected with error-severity findings:
20
+
21
+ - Nothing was written and the idempotency key was not consumed — the same key retries the corrected batch of the same intent.
22
+ - The rejection lists the blocking findings. Fix the listed operations, then confirm with `canvas_validate` using the same `operations` before applying again.
23
+ - `force: true` applies the batch despite error findings. Use it only after validating, and only when the user explicitly accepts the listed findings — never as a routine retry shortcut.
24
+
25
+ ## Recovery
26
+
27
+ - If an operation is rejected, the atomic batch makes no partial change.
28
+ - Read the finding's exact handles and linked guide topic.
29
+ - Correct unsupported object types, metadata, endpoint modes, positions, or references instead of guessing repeatedly.
30
+ - Use a new idempotency key if the corrected payload represents a changed intent.
31
+ - Read and validate again after a successful write.
32
+
33
+ Common findings include ordinary-node overlap, Section content overflow, generated output without an incoming relationship, text imitating a Section header, broken lineage handles, unclear media connections, and proposed deletions. Product-fidelity uncertainty is a review state, not authorization to regenerate.