@gavana.ai/cli 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +42 -2
- package/guides/creative-canvas.md +52 -0
- package/guides/generated-assets.md +7 -2
- package/guides/paid-action-safety.md +1 -1
- package/guides/sections-layout.md +3 -3
- package/guides/validation-recovery.md +9 -2
- package/package.json +1 -1
- package/src/canvas-agent-guide.mjs +3 -3
- package/src/canvas-agent-validation.mjs +30 -15
- package/src/capabilities.mjs +3 -1
- package/src/client.mjs +252 -0
- package/src/commands.mjs +25 -3
- package/src/config.mjs +50 -17
- package/src/guide-sources.mjs +12 -4
- package/src/mcp-targets.mjs +72 -0
- package/src/runner.mjs +205 -58
- package/src/tools/campaign_plan.mjs +2 -2
- package/src/tools/campaign_review.mjs +2 -2
- package/src/tools/campaign_start.mjs +2 -2
- package/src/tools/definitions.mjs +34 -0
- package/src/tools/element_archive.mjs +12 -0
- package/src/tools/element_collection_create.mjs +11 -0
- package/src/tools/element_collection_delete.mjs +12 -0
- package/src/tools/element_collection_list.mjs +13 -0
- package/src/tools/element_collection_update.mjs +12 -0
- package/src/tools/element_create.mjs +11 -0
- package/src/tools/element_get.mjs +12 -0
- package/src/tools/element_history.mjs +13 -0
- package/src/tools/element_list.mjs +13 -0
- package/src/tools/element_restore.mjs +12 -0
- package/src/tools/element_update.mjs +21 -0
- package/src/tools/element_update_collections.mjs +12 -0
- package/src/tools/image_tool.mjs +3 -3
- package/src/tools/registry.mjs +202 -0
- package/src/tools/schemas.mjs +63 -1
- package/src/tools/work_continue.mjs +42 -0
- package/src/tools/work_execute.mjs +12 -0
- package/src/tools/work_get.mjs +12 -0
- package/src/tools/work_prepare.mjs +21 -0
- package/src/tools/work_refresh.mjs +12 -0
- package/src/version.mjs +5 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog — @gavana.ai/cli
|
|
2
2
|
|
|
3
|
+
## 0.2.2
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Image commands and MCP tools now return immediately after the durable Canvas
|
|
8
|
+
targets and Run are queued. Use `--wait` in the CLI or `wait: true` in an MCP
|
|
9
|
+
call when the completed image is required in the same interaction.
|
|
10
|
+
- Distinct local image references upload concurrently while their original
|
|
11
|
+
reference order and duplicate-upload reuse remain stable.
|
|
12
|
+
|
|
13
|
+
## 0.2.1
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- macOS Keychain-backed profiles now distinguish a credential that is genuinely
|
|
18
|
+
absent from one that the current process cannot access. Restricted processes
|
|
19
|
+
report `keychain_inaccessible` with an actionable explanation instead of
|
|
20
|
+
sending users through login again.
|
|
21
|
+
|
|
3
22
|
## 0.2.0
|
|
4
23
|
|
|
5
24
|
First release published to npm. Version 0.1.0 existed in this repository but was
|
package/README.md
CHANGED
|
@@ -103,6 +103,9 @@ retried automatically.
|
|
|
103
103
|
gavana canvas list
|
|
104
104
|
gavana canvas list --limit 25 --jq '.canvases[].handle' -r
|
|
105
105
|
gavana asset get asset:OWNER_UID:ASSET_ID
|
|
106
|
+
gavana element list
|
|
107
|
+
gavana element get element:ELEMENT_ID@v3
|
|
108
|
+
gavana element create --name "Soft window light" --type lighting --guidelines "Keep diffuse, cool window light."
|
|
106
109
|
gavana recipe search "product visual"
|
|
107
110
|
gavana recipe run recipe:product-visual-direction --input product-context="A matte black travel bottle" --destination agent-canvas
|
|
108
111
|
gavana model list --capability image.generate
|
|
@@ -111,6 +114,7 @@ gavana action list
|
|
|
111
114
|
gavana action get action:resize
|
|
112
115
|
gavana action run action:resize --input ./product.png --destination agent-canvas --width 1080 --height 1350
|
|
113
116
|
gavana image generate --destination agent-canvas --model model:OPAQUE_MODEL_KEY --prompt "A studio product photograph"
|
|
117
|
+
gavana image generate --destination agent-canvas --prompt "A studio product photograph" --wait
|
|
114
118
|
gavana model list --capability video.generate
|
|
115
119
|
gavana video generate --model model:OPAQUE_MODEL_KEY --prompt "A slow product turntable" --duration 15 --aspect-ratio 9:16 --download ./turntable.mp4
|
|
116
120
|
gavana video generate --model model:OPAQUE_MODEL_KEY --prompt "Animate the fabric naturally" --first-frame ./product.png --no-wait
|
|
@@ -176,8 +180,13 @@ text-only Recipes.
|
|
|
176
180
|
|
|
177
181
|
Recipe, image, and Action work returns a shared `run:` handle with typed outputs,
|
|
178
182
|
duration estimates, observed queue/execution timing, and stable retry guidance.
|
|
179
|
-
|
|
180
|
-
|
|
183
|
+
Image commands return as soon as Gavana has created the durable Canvas targets
|
|
184
|
+
and queued the Run, so the caller can continue while generation proceeds. Add
|
|
185
|
+
`--wait` only when the completed image is needed in the same command. `--no-wait`
|
|
186
|
+
remains accepted for existing image scripts. Recipe and Action commands retain
|
|
187
|
+
their existing wait-by-default behavior. Waiting and `run get|wait|cancel`
|
|
188
|
+
require `job:manage`; a start-only token can queue image work directly or use
|
|
189
|
+
`--no-wait` with a signed webhook.
|
|
181
190
|
The legacy `job:` handle remains an image and Action compatibility alias; it is
|
|
182
191
|
never used for Recipes. Image and Action `run:` and `job:` handles point to the
|
|
183
192
|
same temporary record and expire together:
|
|
@@ -217,6 +226,37 @@ commands for canvases, recipes, assets, Actions, models, and providers accept `-
|
|
|
217
226
|
`--jq` selector supports property paths, array indexes, and `[]` projections
|
|
218
227
|
without requiring a separate jq installation.
|
|
219
228
|
|
|
229
|
+
## Elements
|
|
230
|
+
|
|
231
|
+
Elements are reusable visual references, not copied image files. Use
|
|
232
|
+
`element list`, `element get element:<id>@v<n>`, and `element history` to
|
|
233
|
+
inspect current or immutable historical revisions. Create or update with one
|
|
234
|
+
or more `--source-asset asset:<id>` references, `--guidelines`, or both.
|
|
235
|
+
`element archive` asks for interactive confirmation; in scripts and other
|
|
236
|
+
non-interactive environments it requires `--yes`. An archived Element remains
|
|
237
|
+
restorable with `element restore`. `element collection-delete` follows the same
|
|
238
|
+
confirmation rule and never deletes the Elements it organized.
|
|
239
|
+
|
|
240
|
+
Apply an exact immutable revision during image work with repeatable
|
|
241
|
+
`--element element:<id>@v<n>` flags. JSON callers may also pass
|
|
242
|
+
`{ "handle": "element:<id>@v<n>", "role": "style", "influence": 0.8 }`.
|
|
243
|
+
An image job accepts up to eight Elements; their source images share the
|
|
244
|
+
existing 16-reference limit.
|
|
245
|
+
|
|
246
|
+
## Chat-first work
|
|
247
|
+
|
|
248
|
+
Use `work_prepare` or `gavana work prepare` for a broad campaign request. It
|
|
249
|
+
returns exactly three directions and a recommendation without paid generation.
|
|
250
|
+
Use `work_continue` or `gavana work continue` to answer a factual question,
|
|
251
|
+
select one direction, adjust the brief, or acknowledge a changed Canvas with
|
|
252
|
+
`--rebase`. `work_execute` and `gavana work execute work:<id> --confirm
|
|
253
|
+
--idempotency-key KEY` send `confirm: true`, start only the selected direction,
|
|
254
|
+
and return durable progress immediately; they never wait or automatically
|
|
255
|
+
retry paid work. `work_get` is read-only and never polls providers or writes
|
|
256
|
+
state; use `gavana work refresh work:<id>` to reconcile provider progress.
|
|
257
|
+
The snapshot returns the latest brief, choice, outputs, and Canvas
|
|
258
|
+
synchronization state.
|
|
259
|
+
|
|
220
260
|
## JavaScript client
|
|
221
261
|
|
|
222
262
|
The same dependency-free client is exported for Node.js applications:
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: creative-canvas
|
|
3
|
+
title: Creative Canvas
|
|
4
|
+
description: Keep creative work on the Canvas without lifecycle states.
|
|
5
|
+
keywords: ["creative", "ideas", "directions", "brainstorm", "refine", "compose", "campaign"]
|
|
6
|
+
order: 11
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## The Canvas is the memory
|
|
10
|
+
|
|
11
|
+
Every generated image, written thought, reference, and experiment remains on the Canvas until a person deletes it. Do not assign creative output a draft, rejected, accepted, approved, or final lifecycle state. A retained node has value even when it is not currently selected.
|
|
12
|
+
|
|
13
|
+
Reference handles and connections are durable provenance. They explain where a creative result came from; they do not require a user to click Keep or clear a review gate.
|
|
14
|
+
|
|
15
|
+
## Spatial structure, not stages
|
|
16
|
+
|
|
17
|
+
Use an ordinary Section only when the person explicitly asks to organize work. Name it for their brief; it is never a required left-to-right workflow. Any node may move between Sections, appear in more than one discussion, become a reference for later work, or remain untouched. Do not move, rename, or create Sections unless the user requests structure.
|
|
18
|
+
|
|
19
|
+
## Campaign assistance
|
|
20
|
+
|
|
21
|
+
When a person supplies only a product and a broad ask, do not jump straight to a
|
|
22
|
+
generic photoshoot, poster, or banner. First make a visible reference-led
|
|
23
|
+
concept cluster with three roles:
|
|
24
|
+
|
|
25
|
+
- **Product identity:** the exact supplied product, logo, garment, or other
|
|
26
|
+
identity reference when one exists.
|
|
27
|
+
- **Brand-world:** the lighting, material, setting, and cultural visual world.
|
|
28
|
+
- **Typography/layout:** the editorial hierarchy, copy placement, crop, and
|
|
29
|
+
composition reference.
|
|
30
|
+
|
|
31
|
+
Connect each source to the work it informs. If inspiration is missing and the
|
|
32
|
+
current request explicitly authorizes generation, autonomously create small,
|
|
33
|
+
clearly labelled concept-reference images or boards for every missing role: a
|
|
34
|
+
product-identity concept study, brand-world, and typography/layout. A
|
|
35
|
+
product-identity study is provisional when no exact product source exists; none
|
|
36
|
+
of these generated concept references may be claimed as product evidence,
|
|
37
|
+
official assets, or real campaigns. If the request authorizes preparation only,
|
|
38
|
+
create editable prompt and Text references without starting a paid image job.
|
|
39
|
+
|
|
40
|
+
Infer a concise brief and create at least three materially different directions.
|
|
41
|
+
Vary the central idea, composition, setting, copy hierarchy, typography/layout
|
|
42
|
+
concept, or audience — not merely the pose or crop. Give every direction a
|
|
43
|
+
short rationale Text node and preserve all attempts on the Canvas. Add one
|
|
44
|
+
**Recommended next move** Text node that explains the strongest direction; this
|
|
45
|
+
is editorial advice, not approval.
|
|
46
|
+
|
|
47
|
+
Do not create a default Section set. If a person asks for a structured campaign
|
|
48
|
+
area, use only the ordinary Sections they request. Ask one short question only
|
|
49
|
+
when a missing product-versus-style distinction would materially change the
|
|
50
|
+
work. Otherwise make a useful first pass and let the person point to, combine,
|
|
51
|
+
or refine any result. Exporting or publishing is an explicit action from any
|
|
52
|
+
selected node or Section, not a status transition.
|
|
@@ -10,20 +10,25 @@ order: 6
|
|
|
10
10
|
|
|
11
11
|
- Read the destination canvas and relevant source nodes.
|
|
12
12
|
- Use exact source `node:` or `asset:` handles.
|
|
13
|
+
- Before image or video generation, call `model_list` for the required capability and pass its exact `model:` handle. A bare model name does not select a saved connection. If no matching model is returned, report that the agent account cannot access that connection; do not ask the user to add a key again.
|
|
13
14
|
- For a standalone image request, pass every visual source in `references`.
|
|
14
15
|
Use `{ "handle": "node:...", "role": "identity" }` when its
|
|
15
16
|
responsibility is known; valid roles are `identity`, `construction`,
|
|
16
17
|
`texture`, `fit`, and `style`. Do not flatten multi-reference work
|
|
17
18
|
into prompt prose or omit a source during fallback.
|
|
19
|
+
- Reuse existing Canvas `node:` or `asset:` handles directly. Do not download
|
|
20
|
+
and re-upload a generated Canvas image merely to use it as the next
|
|
21
|
+
generation's reference. State whether a style reference establishes the
|
|
22
|
+
brand-world or typography/layout direction in the prompt.
|
|
18
23
|
- 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
24
|
- Connect prompts, products, references, Lists, and frame inputs to their target with the correct direction and mode.
|
|
20
25
|
|
|
21
26
|
## Paid execution
|
|
22
27
|
|
|
23
|
-
Generation is allowed only after explicit current-turn user intent. Start one run with one caller-stable idempotency key.
|
|
28
|
+
Generation is allowed only after explicit current-turn user intent. Start one run with one caller-stable idempotency key. Image tools return durable queued progress by default; report that progress immediately and do not automatically call `run_wait`. Call `run_wait` only when the current user explicitly needs the completed asset in this same interaction. Otherwise, a later `run_get` or Canvas read can observe progress and the durable output. Do not start another run while one is pending. A terminal failure must be reported without automatic retry.
|
|
24
29
|
|
|
25
30
|
## Completion
|
|
26
31
|
|
|
27
32
|
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
33
|
|
|
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,
|
|
34
|
+
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, and delivery state. Do not claim Done while it says `doneClaimAllowed: false`, including when delivery is pending, failed, or non-durable. Render the Canvas for visual inspection when the request includes a campaign, poster, banner, or multi-direction composition. Reference provenance is not a user workflow state and never requires a Keep action. Never create another paid provider call automatically.
|
|
@@ -15,7 +15,7 @@ Start paid work only when the current user message explicitly asks to run or gen
|
|
|
15
15
|
## Retry boundary
|
|
16
16
|
|
|
17
17
|
- Use one stable idempotency key for one intended paid operation.
|
|
18
|
-
-
|
|
18
|
+
- Return an image Run's durable queued progress immediately. Do not call `run_wait` unless the current user explicitly needs the completed asset in this same interaction; otherwise observe it later with `run_get` or a Canvas read.
|
|
19
19
|
- Never automatically retry a terminal failure, timeout, disconnect, or ambiguous provider response with a new key.
|
|
20
20
|
- Ask for new user intent before any new paid attempt.
|
|
21
21
|
|
|
@@ -10,10 +10,10 @@ order: 3
|
|
|
10
10
|
|
|
11
11
|
- Treat the current canvas as user-owned. Preserve existing coordinates unless reorganization was explicitly requested.
|
|
12
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
|
|
14
|
-
- Keep
|
|
13
|
+
- Use 48 units of inner Section padding, 32 units between sibling nodes, and at least 80 units between major clusters.
|
|
14
|
+
- Keep a left-to-right direction only when the user asks for a linear workflow. For creative exploration, use Sections as optional spatial places rather than a required sequence.
|
|
15
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.
|
|
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. A normal feed photoshoot uses 4:5 portrait frames in its own 2x2 Section. Put horizontal 16:9 campaign ads in a separate Section with their own targets; do not mix formats unless the user explicitly asks for a mixed-format deliverable.
|
|
17
17
|
- Size Sections after their contents. Do not use Section overlap as a substitute for node placement.
|
|
18
18
|
- Run `canvas_validate` before and after a multi-node layout change.
|
|
19
19
|
|
|
@@ -12,7 +12,14 @@ Call it with only `canvasId` to audit the current graph. Pass the proposed `oper
|
|
|
12
12
|
|
|
13
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
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,
|
|
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, and delivery state. Never claim Done unless `completionReview.doneClaimAllowed` is true; pending, failed, or non-durable generated outputs block that claim even when the geometry is clean.
|
|
16
|
+
|
|
17
|
+
For a campaign, poster, banner, or multi-direction composition, structural
|
|
18
|
+
validation is necessary but not visual proof. Render the completed Canvas and
|
|
19
|
+
check the actual composition, distinctness of directions, visible product and
|
|
20
|
+
layout, and separation of 4:5 feed work from 16:9 ads. Report an unavailable
|
|
21
|
+
render or incomplete visual check as a limitation rather than claiming it was
|
|
22
|
+
verified.
|
|
16
23
|
|
|
17
24
|
## Blocked writes
|
|
18
25
|
|
|
@@ -30,4 +37,4 @@ When a batch is rejected with error-severity findings:
|
|
|
30
37
|
- Use a new idempotency key if the corrected payload represents a changed intent.
|
|
31
38
|
- Read and validate again after a successful write.
|
|
32
39
|
|
|
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.
|
|
40
|
+
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. Reference provenance is not authorization to regenerate.
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Guide metadata, lookup, and search. The prose itself lives in ../guides/*.md
|
|
2
2
|
// and is loaded through ./guide-sources.mjs, so editing a guide is a content
|
|
3
3
|
// change rather than a code change. Graph validation moved to
|
|
4
|
-
// ./canvas-agent-validation.mjs in guide version 1.
|
|
4
|
+
// ./canvas-agent-validation.mjs in guide version 1.5.0.
|
|
5
5
|
import { GAVANA_CANVAS_GUIDE_SOURCES } from "./guide-sources.mjs";
|
|
6
6
|
|
|
7
|
-
export const GAVANA_CANVAS_GUIDE_VERSION = "1.
|
|
7
|
+
export const GAVANA_CANVAS_GUIDE_VERSION = "1.5.1";
|
|
8
8
|
export const GAVANA_CANVAS_GUIDE_INDEX_URI = `gavana://guides/canvas/v${GAVANA_CANVAS_GUIDE_VERSION.split(".")[0]}/index`;
|
|
9
9
|
export const GAVANA_CANVAS_GUIDE_WORKFLOW_INSTRUCTION =
|
|
10
|
-
"For the first canvas task in a session, and before any unfamiliar canvas operation, inspect the relevant guide through MCP resources or call guide_search then guide_get. Before changing an existing canvas, call canvas_get. For spatial, multi-node, or destructive work, call canvas_validate with the proposed operations, apply one revision-safe atomic batch, then call canvas_validate again. When a standalone image fallback uses visual references, forward every exact node:/asset: handle (and each known role) in the image request; never reduce that work to a prompt-only generation. After an image or workflow finishes, read completionReview. Never claim Done while completionReview.doneClaimAllowed is false,
|
|
10
|
+
"For the first canvas task in a session, and before any unfamiliar canvas operation, inspect the relevant guide through MCP resources or call guide_search then guide_get. Before changing an existing canvas, call canvas_get. For spatial, multi-node, or destructive work, call canvas_validate with the proposed operations, apply one revision-safe atomic batch, then call canvas_validate again. Campaign work must read creative-canvas and use a reference-led concept before image output. Before image or video generation, call model_list for the required capability and use its exact model: handle; a bare model name does not select a saved connection. If no matching model is returned, report that the agent account cannot access the connection instead of asking the user to add a key again. When a standalone image fallback uses visual references, forward every exact node:/asset: handle (and each known role) in the image request; never reduce that work to a prompt-only generation. Image tools return durable queued progress by default; report it immediately and call run_wait only when the current user explicitly needs the completed asset in the same interaction. A later run_get or Canvas read can observe progress. After an image or workflow finishes, read completionReview. Never claim Done while completionReview.doneClaimAllowed is false, delivery is pending, failed, or non-durable, or blocking findings remain. Render campaign compositions for visual inspection. Treat legacy warnings as review items, not permission to rewrite unrelated work.";
|
|
11
11
|
export const GAVANA_CANVAS_GUIDE_READ_ONLY_INSTRUCTION =
|
|
12
12
|
"For the first canvas task in a session, and before any unfamiliar canvas review, inspect the relevant guide through MCP resources or call guide_search then guide_get. Call canvas_get before reasoning about an existing canvas, and use canvas_validate to audit its current graph. Treat validation warnings as review items and never claim to mutate the canvas.";
|
|
13
13
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Deterministic canvas graph validation and destructive-impact reporting.
|
|
2
2
|
//
|
|
3
|
-
// Split out of canvas-agent-guide.mjs in guide version 1.
|
|
3
|
+
// Split out of canvas-agent-guide.mjs in guide version 1.5.0: guide prose is now
|
|
4
4
|
// editable markdown under ../guides/, and validation is code. The two no longer
|
|
5
5
|
// share a file. Validation still cites guide topics, so it imports the guide URI
|
|
6
6
|
// helpers — the dependency runs one way only (validation -> guide).
|
|
@@ -333,8 +333,9 @@ function agentOwnsNode(node) {
|
|
|
333
333
|
function buildCompletionReview(canvas, findings) {
|
|
334
334
|
const generatedOutputs = canvas.nodes.filter(isGeneratedOutput);
|
|
335
335
|
const durableOutputs = generatedOutputs.filter(hasDurableOutput);
|
|
336
|
-
const pendingOutputs = generatedOutputs.filter((node) => node.metadata?.aiJobStatus === "queued" || node.metadata?.aiJobStatus === "running"
|
|
336
|
+
const pendingOutputs = generatedOutputs.filter((node) => node.metadata?.aiJobStatus === "queued" || node.metadata?.aiJobStatus === "running");
|
|
337
337
|
const failedOutputs = generatedOutputs.filter((node) => node.metadata?.status === "error" || node.metadata?.aiJobStatus === "failed" || node.metadata?.aiJobStatus === "canceled");
|
|
338
|
+
const nonDurableOutputs = generatedOutputs.filter((node) => !hasDurableOutput(node) && !pendingOutputs.includes(node) && !failedOutputs.includes(node));
|
|
338
339
|
const overlap = reviewArea(findings, "node_overlap");
|
|
339
340
|
const containment = reviewArea(findings, "section_content_overflow", "unsectioned_node");
|
|
340
341
|
const referenceLineage = reviewArea(findings, "broken_generated_lineage", "unconnected_generated_output", "orphan_media_placeholder");
|
|
@@ -342,12 +343,13 @@ function buildCompletionReview(canvas, findings) {
|
|
|
342
343
|
const blockingFindings = findings.filter((finding) => finding.blocksWrite === true || finding.blocksCompletion === true);
|
|
343
344
|
const blockingFindingCodes = uniqueSorted(blockingFindings.map((finding) => finding.code));
|
|
344
345
|
const advisoryFindingCodes = uniqueSorted(findings.filter((finding) => !blockingFindings.includes(finding)).map((finding) => finding.code));
|
|
345
|
-
const
|
|
346
|
+
const delivery = deliveryReview(pendingOutputs, failedOutputs, nonDurableOutputs);
|
|
347
|
+
const doneClaimAllowed = blockingFindings.length === 0 && delivery.status === "clear";
|
|
346
348
|
|
|
347
349
|
return {
|
|
348
|
-
status: doneClaimAllowed ? "ready" :
|
|
350
|
+
status: doneClaimAllowed ? "ready" : "blocked",
|
|
349
351
|
doneClaimAllowed,
|
|
350
|
-
instruction: "Do not claim Done while blocking findings remain or
|
|
352
|
+
instruction: "Do not claim Done while blocking findings remain or generated output delivery is pending, failed, or non-durable.",
|
|
351
353
|
outputs: {
|
|
352
354
|
count: generatedOutputs.length,
|
|
353
355
|
durableCount: durableOutputs.length,
|
|
@@ -359,11 +361,27 @@ function buildCompletionReview(canvas, findings) {
|
|
|
359
361
|
containment,
|
|
360
362
|
referenceLineage,
|
|
361
363
|
productFidelity,
|
|
364
|
+
delivery,
|
|
362
365
|
blockingFindingCodes,
|
|
363
366
|
advisoryFindingCodes,
|
|
364
367
|
};
|
|
365
368
|
}
|
|
366
369
|
|
|
370
|
+
function deliveryReview(pendingOutputs, failedOutputs, nonDurableOutputs) {
|
|
371
|
+
const statuses = [
|
|
372
|
+
pendingOutputs.length ? "pending" : "",
|
|
373
|
+
failedOutputs.length ? "failed" : "",
|
|
374
|
+
nonDurableOutputs.length ? "non-durable" : "",
|
|
375
|
+
].filter(Boolean);
|
|
376
|
+
return {
|
|
377
|
+
status: statuses.length ? "blocked" : "clear",
|
|
378
|
+
...(statuses.length ? { reasons: statuses } : {}),
|
|
379
|
+
pendingOutputHandles: pendingOutputs.map((node) => nodeHandle(node.id)).sort(),
|
|
380
|
+
failedOutputHandles: failedOutputs.map((node) => nodeHandle(node.id)).sort(),
|
|
381
|
+
nonDurableOutputHandles: nonDurableOutputs.map((node) => nodeHandle(node.id)).sort(),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
367
385
|
function reviewArea(findings, ...codes) {
|
|
368
386
|
const matched = findings.filter((finding) => codes.includes(finding.code));
|
|
369
387
|
const blocking = matched.some((finding) => finding.blocksWrite === true || finding.blocksCompletion === true);
|
|
@@ -385,17 +403,14 @@ function productFidelityReview(canvas, generatedOutputs) {
|
|
|
385
403
|
evidenceMissingOutputHandles: [],
|
|
386
404
|
};
|
|
387
405
|
}
|
|
388
|
-
const needsReview = referenceTargets.filter((node) => node.metadata?.outputValidationStatus === "needs-review" || node.metadata?.outputValidationStatus === "checking");
|
|
389
|
-
const evidenceMissing = referenceTargets.filter((node) => !node.metadata?.outputValidationStatus || node.metadata?.outputValidationStatus === "skipped");
|
|
390
406
|
return {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
.sort((left, right) => left.nodeHandle.localeCompare(right.nodeHandle)),
|
|
407
|
+
// References preserve origin and intent. They never turn a retained
|
|
408
|
+
// creative output into a completion gate.
|
|
409
|
+
status: "passed",
|
|
410
|
+
reviewedOutputCount: referenceTargets.length,
|
|
411
|
+
needsReviewOutputHandles: [],
|
|
412
|
+
evidenceMissingOutputHandles: [],
|
|
413
|
+
reasons: [],
|
|
399
414
|
};
|
|
400
415
|
}
|
|
401
416
|
|
package/src/capabilities.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { GAVANA_CLI_VERSION } from "./version.mjs";
|
|
5
5
|
|
|
6
6
|
export { GAVANA_CLI_VERSION };
|
|
7
|
-
export const GAVANA_MCP_TOOLSETS = Object.freeze(["canvas", "recipes", "assets", "models", "actions", "images", "videos", "runs", "campaigns"]);
|
|
7
|
+
export const GAVANA_MCP_TOOLSETS = Object.freeze(["canvas", "recipes", "assets", "elements", "models", "actions", "images", "videos", "runs", "campaigns"]);
|
|
8
8
|
|
|
9
9
|
import { GAVANA_TOOL_REGISTRY } from "./tools/registry.mjs";
|
|
10
10
|
|
|
@@ -37,6 +37,7 @@ const TOOLSET_FOR_PREFIX = Object.freeze([
|
|
|
37
37
|
["node_", "canvas"],
|
|
38
38
|
["connection_", "canvas"],
|
|
39
39
|
["asset_", "assets"],
|
|
40
|
+
["element_", "elements"],
|
|
40
41
|
["provider_", "models"],
|
|
41
42
|
["model_", "models"],
|
|
42
43
|
["action_", "actions"],
|
|
@@ -44,6 +45,7 @@ const TOOLSET_FOR_PREFIX = Object.freeze([
|
|
|
44
45
|
["video_", "videos"],
|
|
45
46
|
["job_", "runs"],
|
|
46
47
|
["run_", "runs"],
|
|
48
|
+
["work_", "canvas"],
|
|
47
49
|
]);
|
|
48
50
|
|
|
49
51
|
export function gavanaToolsetForName(name) {
|