@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/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@gavana.ai/cli",
3
+ "version": "0.2.0",
4
+ "description": "JSON-first command-line client for the Gavana Canvas API",
5
+ "type": "module",
6
+ "bin": {
7
+ "gavana": "bin/gavana.mjs",
8
+ "gavana-canvas": "bin/gavana.mjs",
9
+ "craftboard": "bin/craftboard.mjs",
10
+ "craftboard-canvas": "bin/craftboard.mjs"
11
+ },
12
+ "exports": {
13
+ ".": "./src/client.mjs",
14
+ "./client": "./src/client.mjs",
15
+ "./capabilities": "./src/capabilities.mjs"
16
+ },
17
+ "files": [
18
+ "CHANGELOG.md",
19
+ "bin",
20
+ "guides",
21
+ "src",
22
+ "README.md",
23
+ "LICENSE.md"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "engines": {
29
+ "node": ">=20"
30
+ },
31
+ "license": "SEE LICENSE IN LICENSE.md",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://gitlab.com/avada/gavana.ai.git",
35
+ "directory": "packages/cli"
36
+ },
37
+ "keywords": [
38
+ "gavana",
39
+ "craftboard",
40
+ "canvas",
41
+ "cli",
42
+ "ai"
43
+ ]
44
+ }
@@ -0,0 +1,133 @@
1
+ // Guide metadata, lookup, and search. The prose itself lives in ../guides/*.md
2
+ // and is loaded through ./guide-sources.mjs, so editing a guide is a content
3
+ // change rather than a code change. Graph validation moved to
4
+ // ./canvas-agent-validation.mjs in guide version 1.2.0.
5
+ import { GAVANA_CANVAS_GUIDE_SOURCES } from "./guide-sources.mjs";
6
+
7
+ export const GAVANA_CANVAS_GUIDE_VERSION = "1.2.0";
8
+ export const GAVANA_CANVAS_GUIDE_INDEX_URI = `gavana://guides/canvas/v${GAVANA_CANVAS_GUIDE_VERSION.split(".")[0]}/index`;
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, blocking findings remain, or product-fidelity review is needed. Treat legacy warnings as review items, not permission to rewrite unrelated work.";
11
+ export const GAVANA_CANVAS_GUIDE_READ_ONLY_INSTRUCTION =
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
+
14
+ const GUIDE_BASE_URI = `gavana://guides/canvas/v${GAVANA_CANVAS_GUIDE_VERSION.split(".")[0]}`;
15
+ const MAX_SEARCH_RESULTS = 10;
16
+
17
+ const guide = (id, title, description, keywords, markdown) =>
18
+ Object.freeze({
19
+ id,
20
+ title,
21
+ description,
22
+ keywords: Object.freeze(keywords),
23
+ uri: `${GUIDE_BASE_URI}/${id}`,
24
+ mimeType: "text/markdown",
25
+ markdown: `# ${title}\n\nGuide version: ${GAVANA_CANVAS_GUIDE_VERSION}\n\n${markdown.trim()}\n`,
26
+ });
27
+
28
+ export const GAVANA_CANVAS_GUIDES = Object.freeze(
29
+ GAVANA_CANVAS_GUIDE_SOURCES.map((source) => guide(source.id, source.title, source.description, source.keywords, source.markdown)),
30
+ );
31
+
32
+ const GUIDE_BY_ID = new Map(GAVANA_CANVAS_GUIDES.map((entry) => [entry.id, entry]));
33
+ const GUIDE_BY_URI = new Map(GAVANA_CANVAS_GUIDES.map((entry) => [entry.uri, entry]));
34
+
35
+ export function canvasGuideIndexMarkdown() {
36
+ const rows = GAVANA_CANVAS_GUIDES.map((entry) => `- [${entry.title}](${entry.uri}): ${entry.description}`).join("\n");
37
+ return `# Gavana Canvas Agent Guide\n\nGuide version: ${GAVANA_CANVAS_GUIDE_VERSION}\n\nThis is the canonical guide index for MCP agents. Use MCP resources when supported, or call guide_search and guide_get with the same topic IDs.\n\n${rows}\n`;
38
+ }
39
+
40
+ export function listCanvasGuideResources() {
41
+ return [
42
+ {
43
+ name: "gavana-canvas-agent-guide-index",
44
+ title: "Gavana Canvas Agent Guide",
45
+ description: "Canonical index for versioned Canvas construction and safety guidance.",
46
+ uri: GAVANA_CANVAS_GUIDE_INDEX_URI,
47
+ mimeType: "text/markdown",
48
+ },
49
+ ...GAVANA_CANVAS_GUIDES.map((entry) => ({
50
+ name: `gavana-canvas-guide-${entry.id}`,
51
+ title: entry.title,
52
+ description: entry.description,
53
+ uri: entry.uri,
54
+ mimeType: entry.mimeType,
55
+ })),
56
+ ];
57
+ }
58
+
59
+ export function readCanvasGuideResource(uri) {
60
+ if (uri === GAVANA_CANVAS_GUIDE_INDEX_URI) {
61
+ return {
62
+ id: "index",
63
+ title: "Gavana Canvas Agent Guide",
64
+ description: "Canonical index for versioned Canvas construction and safety guidance.",
65
+ uri,
66
+ mimeType: "text/markdown",
67
+ guideVersion: GAVANA_CANVAS_GUIDE_VERSION,
68
+ markdown: canvasGuideIndexMarkdown(),
69
+ };
70
+ }
71
+ const entry = GUIDE_BY_URI.get(String(uri || ""));
72
+ return entry ? publicGuide(entry) : null;
73
+ }
74
+
75
+ export function getCanvasGuide(idOrUri) {
76
+ const value = String(idOrUri || "").trim();
77
+ if (value === "index" || value === GAVANA_CANVAS_GUIDE_INDEX_URI) return readCanvasGuideResource(GAVANA_CANVAS_GUIDE_INDEX_URI);
78
+ const entry = GUIDE_BY_ID.get(value) || GUIDE_BY_URI.get(value);
79
+ if (entry) return publicGuide(entry);
80
+ const error = new Error(`Unknown Canvas guide: ${value || "(empty)"}. Available guide IDs: ${GAVANA_CANVAS_GUIDES.map((item) => item.id).join(", ")}.`);
81
+ error.code = "unknown_canvas_guide";
82
+ throw error;
83
+ }
84
+
85
+ export function searchCanvasGuides(query, limit = MAX_SEARCH_RESULTS) {
86
+ const cleanQuery = String(query || "")
87
+ .trim()
88
+ .toLowerCase()
89
+ .slice(0, 240);
90
+ const tokens = Array.from(new Set(cleanQuery.split(/[^a-z0-9]+/).filter((token) => token.length > 1)));
91
+ const results = GAVANA_CANVAS_GUIDES.map((entry) => {
92
+ const title = entry.title.toLowerCase();
93
+ const description = entry.description.toLowerCase();
94
+ const keywords = entry.keywords.join(" ").toLowerCase();
95
+ const markdown = entry.markdown.toLowerCase();
96
+ const score = tokens.reduce((sum, token) => sum + (entry.id.includes(token) ? 12 : 0) + (title.includes(token) ? 8 : 0) + (keywords.includes(token) ? 5 : 0) + (description.includes(token) ? 3 : 0) + (markdown.includes(token) ? 1 : 0), 0);
97
+ return { entry, score };
98
+ })
99
+ .filter(({ score }) => !tokens.length || score > 0)
100
+ .sort((a, b) => b.score - a.score || a.entry.id.localeCompare(b.entry.id))
101
+ .slice(0, Math.max(1, Math.min(MAX_SEARCH_RESULTS, Number(limit) || MAX_SEARCH_RESULTS)))
102
+ .map(({ entry, score }) => ({
103
+ id: entry.id,
104
+ title: entry.title,
105
+ description: entry.description,
106
+ uri: entry.uri,
107
+ score,
108
+ }));
109
+ return {
110
+ guideVersion: GAVANA_CANVAS_GUIDE_VERSION,
111
+ indexUri: GAVANA_CANVAS_GUIDE_INDEX_URI,
112
+ query: cleanQuery,
113
+ results,
114
+ availableGuideIds: GAVANA_CANVAS_GUIDES.map((entry) => entry.id),
115
+ };
116
+ }
117
+
118
+ /** Guide URI for a topic id, or undefined. canvas-agent-validation.mjs uses this to cite guides in findings. */
119
+ export function canvasGuideUriForId(guideId) {
120
+ return GUIDE_BY_ID.get(String(guideId || ""))?.uri;
121
+ }
122
+
123
+ function publicGuide(entry) {
124
+ return {
125
+ id: entry.id,
126
+ title: entry.title,
127
+ description: entry.description,
128
+ uri: entry.uri,
129
+ mimeType: entry.mimeType,
130
+ guideVersion: GAVANA_CANVAS_GUIDE_VERSION,
131
+ markdown: entry.markdown,
132
+ };
133
+ }