@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
@@ -0,0 +1,165 @@
1
+ // Shared input-schema primitives for the Gavana tool definitions.
2
+ //
3
+ // Extracted from scripts/gavana-agent-mcp.mjs so tool definitions can live outside
4
+ // the server. The handle shapes (canvas:, node:, asset:, model:, action:, job:) and
5
+ // the revision/idempotency contract are part of the published tool schemas, so these
6
+ // describe() strings are user-visible — edit them as carefully as a tool description.
7
+ import { z } from "zod";
8
+
9
+ const canvasReference = z.string().min(1).describe("Stable canvas:<id> or canvas:<ownerUid>:<id> handle. Agent Canvas may also be addressed as agent-canvas.");
10
+ const imageDestination = z.string().min(1).describe("agent-canvas, new-canvas, or a stable existing canvas handle.");
11
+ const nodeReference = z.string().min(1).describe("Stable node:<id> handle.");
12
+ const connectionReference = z.string().min(1).describe("Stable connection:<id> handle.");
13
+ const assetReference = z
14
+ .string()
15
+ .regex(/^asset:(?:[A-Za-z0-9_-]{1,180}:)?[A-Za-z0-9_-]{1,180}$/)
16
+ .describe("Stable asset:<id> or shared asset:<ownerUid>:<id> handle.");
17
+ const imageReferenceInput = z
18
+ .union([
19
+ z.union([nodeReference, assetReference]),
20
+ z
21
+ .object({
22
+ handle: z.union([nodeReference, assetReference]),
23
+ role: z.enum(["identity", "construction", "texture", "fit", "style"]).optional(),
24
+ })
25
+ .strict(),
26
+ ])
27
+ .describe("A durable image handle, optionally with the visual role it must preserve.");
28
+ const jobReference = z.string().min(1).describe("Temporary opaque job:<id> compatibility handle for image and Action work.");
29
+ const modelReference = z
30
+ .string()
31
+ .regex(/^model:[A-Za-z0-9_-]{8,600}$/)
32
+ .describe("Stable opaque model:<id> handle returned by model_list.");
33
+ const actionReference = z
34
+ .string()
35
+ .regex(/^action:[a-z0-9]+(?:-[a-z0-9]+)*$/)
36
+ .describe("Stable action:<slug> handle returned by action_list.");
37
+ const videoImageReference = z
38
+ .union([
39
+ nodeReference,
40
+ assetReference,
41
+ z
42
+ .string()
43
+ .url()
44
+ .regex(/^https:\/\//i, "Use a public HTTPS image URL."),
45
+ ])
46
+ .describe("Stable node:/asset: image handle or public HTTPS image URL.");
47
+ const rawModelId = z
48
+ .string()
49
+ .min(1)
50
+ .max(240)
51
+ .refine((value) => !value.startsWith("model:"), "Use the exact model: handle returned by model_list.")
52
+ .describe("Provider model id. Prefer an opaque model: handle returned by model_list.");
53
+ const exactCanvasReference = z
54
+ .string()
55
+ .regex(/^canvas:[A-Za-z0-9_-]{1,180}(?::[A-Za-z0-9_-]{1,180})?$/)
56
+ .describe("Exact stable canvas:<id> or canvas:<ownerUid>:<id> handle.");
57
+ const recipeReference = z
58
+ .string()
59
+ .regex(/^recipe:[A-Za-z0-9_-]{1,180}$/)
60
+ .describe("Stable recipe:<id> handle.");
61
+ const campaignReference = z
62
+ .string()
63
+ .regex(/^campaign:[A-Za-z0-9_-]{1,180}$/)
64
+ .describe("Stable campaign:<id> handle returned by campaign_plan.");
65
+ const runReference = z
66
+ .string()
67
+ .regex(/^run:[A-Za-z0-9_-]{1,180}$/)
68
+ .describe("Opaque run:<id> handle. Image and Action Runs are temporary; Recipe Runs currently persist.");
69
+ const campaignProductReference = z
70
+ .string()
71
+ .max(400)
72
+ .describe("Prefer one exact product image node:<id>, asset:<id>, or shared asset:<ownerUid>:<id> handle. A human-readable title is forwarded only so the server can return ambiguity candidates; it is never guessed.");
73
+ const listCursor = z.string().min(1).max(8_192).optional().describe("Opaque page.nextCursor returned by the previous call with the same filters.");
74
+ const listLimit = (maximum) => z.number().int().min(1).max(maximum).optional().describe(`Maximum items in this page (1-${maximum}).`);
75
+ const approvedOutputReferences = z
76
+ .array(
77
+ z
78
+ .string()
79
+ .regex(/^node:[A-Za-z0-9_-]{1,180}$/)
80
+ .describe("One exact generated direction node:<id> handle."),
81
+ )
82
+ .length(2)
83
+ .refine((handles) => new Set(handles).size === handles.length, "Approve two different output nodes.");
84
+ const campaignIdempotencyKey = z.string().min(8).max(200).describe("Required caller-stable retry key. Reuse it only for the exact same campaign action.");
85
+ const recipeForkIdempotencyKey = z.string().min(8).max(200).describe("Required caller-stable retry key. Reuse it only for the exact same Recipe fork.");
86
+ const campaignAspectRatio = z.enum(["1:1", "4:5", "3:4", "16:9", "9:16"]);
87
+ const MAX_LOCAL_REFERENCE_IMAGE_BYTES = 50 * 1024 * 1024;
88
+ const revisionFields = {
89
+ baseRevision: z.string().min(1).optional().describe("Revision returned by canvas_get. Omit to read the latest revision immediately before the write."),
90
+ idempotencyKey: z.string().min(8).describe("Required caller-stable retry key. Reuse it only when retrying the same intended mutation."),
91
+ };
92
+ function imageSchema() {
93
+ return z.object({
94
+ canvasId: canvasReference.optional(),
95
+ destination: imageDestination.optional(),
96
+ canvasTitle: z.string().min(1).max(160).optional(),
97
+ ...revisionFields,
98
+ targetNodeIds: z.array(nodeReference).min(1).max(4).optional(),
99
+ targetTitle: z.string().min(1).max(160).optional(),
100
+ targetX: z.number().finite().optional(),
101
+ targetY: z.number().finite().optional(),
102
+ targetWidth: z.number().min(40).max(10_000).optional(),
103
+ targetHeight: z.number().min(40).max(10_000).optional(),
104
+ prompt: z.string().max(8_000).optional(),
105
+ promptNodeId: nodeReference.optional(),
106
+ references: z
107
+ .array(imageReferenceInput)
108
+ .max(16)
109
+ .optional(),
110
+ source: z.union([nodeReference, assetReference]).optional(),
111
+ connectionId: z.string().max(180).optional(),
112
+ model: z.union([modelReference, rawModelId]).optional(),
113
+ size: z.string().max(80).optional(),
114
+ quality: z.string().max(80).optional(),
115
+ count: z.number().int().min(1).max(4).optional(),
116
+ wait: z.boolean().default(true),
117
+ timeoutSeconds: z.number().min(1).max(3_600).default(900),
118
+ });
119
+ }
120
+
121
+ function validateImageInput(operation, value) {
122
+ const issues = [];
123
+ if (!value.destination && !value.canvasId) issues.push("Provide destination or canvasId.");
124
+ if (value.destination === "new-canvas" && !value.canvasTitle) issues.push("new-canvas requires canvasTitle.");
125
+ // prompt and promptNodeId may both be omitted only when explicit targets
126
+ // are supplied — an existing target can carry a visible prompt-mode
127
+ // connection that supplies the prompt. Without a target the tool would
128
+ // mint a blank auto-target no edge can point at, the server would reject
129
+ // the job, and the blank node would be left behind as an orphan.
130
+ if (operation !== "variations" && !value.prompt && !value.promptNodeId && !value.targetNodeIds?.length) issues.push("Provide prompt or promptNodeId, or pass targetNodeIds whose nodes have a prompt connection.");
131
+ if (operation !== "generate" && !value.source && !value.references?.length) issues.push(`${operation} requires source or references.`);
132
+ if (!issues.length) return;
133
+ const error = new Error(`Input validation error: ${issues.join(" ")}`);
134
+ error.code = "invalid_image_input";
135
+ throw error;
136
+ }
137
+
138
+ export {
139
+ MAX_LOCAL_REFERENCE_IMAGE_BYTES,
140
+ actionReference,
141
+ approvedOutputReferences,
142
+ assetReference,
143
+ campaignAspectRatio,
144
+ campaignIdempotencyKey,
145
+ campaignProductReference,
146
+ campaignReference,
147
+ canvasReference,
148
+ connectionReference,
149
+ exactCanvasReference,
150
+ imageDestination,
151
+ imageReferenceInput,
152
+ imageSchema,
153
+ jobReference,
154
+ listCursor,
155
+ listLimit,
156
+ modelReference,
157
+ nodeReference,
158
+ rawModelId,
159
+ recipeForkIdempotencyKey,
160
+ recipeReference,
161
+ revisionFields,
162
+ runReference,
163
+ validateImageInput,
164
+ videoImageReference,
165
+ };
@@ -0,0 +1,37 @@
1
+ // Tool definition: video_generate
2
+ //
3
+ // Registered through ./definitions.mjs. ./registry.mjs is the catalog that says
4
+ // this tool exists and on which surfaces; this file is what it does.
5
+ import { z } from "zod";
6
+ import { canvasReference, modelReference, rawModelId, videoImageReference } from "./schemas.mjs";
7
+ import { withProgress } from "./progress.mjs";
8
+
9
+ export function defineVideoGenerate(client) {
10
+ return {
11
+ title: "Generate video",
12
+ description: "Queue model-aware video generation with optional durable canvas frames, asset references, or public HTTPS image references.",
13
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
14
+ inputSchema: z.object({
15
+ model: z.union([modelReference, rawModelId]),
16
+ connectionId: z.string().min(1).max(180).optional(),
17
+ prompt: z.string().min(1).max(8_000),
18
+ idempotencyKey: z.string().min(8).max(200),
19
+ canvasId: canvasReference.optional().describe("Required when a frame or reference uses a node: handle."),
20
+ ownerUid: z.string().min(1).max(180).optional(),
21
+ aspectRatio: z.string().min(1).max(40).optional(),
22
+ durationSeconds: z.number().int().min(1).max(120).optional(),
23
+ resolution: z.string().min(1).max(40).optional(),
24
+ generateAudio: z.boolean().optional(),
25
+ firstFrame: videoImageReference.optional(),
26
+ lastFrame: videoImageReference.optional(),
27
+ references: z.array(videoImageReference).max(9).optional(),
28
+ wait: z.boolean().default(true),
29
+ timeoutSeconds: z.number().min(1).max(3_600).default(1_800),
30
+ }),
31
+ handler: async ({ wait, timeoutSeconds, ...input }, extra) => {
32
+ const queued = await client.startVideo(input);
33
+ if (wait === false) return queued;
34
+ return client.waitForJob(queued.id, withProgress({ timeoutMs: timeoutSeconds * 1000 }, extra));
35
+ },
36
+ };
37
+ }
@@ -0,0 +1,12 @@
1
+ // The single source of the CLI package version.
2
+ //
3
+ // Its own module because three things need it and two of them must not drag in
4
+ // the tool registry: client.mjs stamps every request's User-Agent, the stdio MCP
5
+ // server advertises it as its server version, and capabilities.mjs re-exports it
6
+ // for `gavana version`. Reading it from a literal is what let the User-Agent
7
+ // report 0.1.0 for the whole life of 0.1.1, and let the MCP server advertise
8
+ // 0.1.0 while packaged as 0.1.1.
9
+ //
10
+ // scripts/gavana-mcp-tool-contract.test.mjs asserts this equals
11
+ // packages/cli/package.json, so the two cannot drift.
12
+ export const GAVANA_CLI_VERSION = "0.2.0";