@everfir/az8-cli 0.2.0-preview.1 → 0.2.0-preview.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 CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable AZ8 CLI changes are recorded here. The CLI package has its own linear version sequence;
4
4
  it does not inherit the Web application or monorepo root version.
5
5
 
6
+ ## 0.2.0-preview.2 - 2026-07-21
7
+
8
+ ### Added
9
+
10
+ - A platform-neutral built-in agent Skill available through `az8 guide` without credentials or a
11
+ network connection.
12
+ - Section-level Markdown and versioned JSON guide output for progressive discovery.
13
+ - Agent onboarding for platform concepts, runtime capability discovery, first-session, Canvas,
14
+ generation and media SOPs, failure recovery, prohibited actions, and completion checks.
15
+
16
+ ### Safety and compatibility
17
+
18
+ - The Skill never replaces Project-scoped `capabilities.detail` or Workflow Definition discovery;
19
+ dynamic schemas, permissions, completion, History, and retry policy remain runtime-authoritative.
20
+ - Existing semantic Operations and protocol version `1.0` are unchanged.
21
+
6
22
  ## 0.2.0-preview.1 - 2026-07-21
7
23
 
8
24
  First installable internal preview.
package/README.md CHANGED
@@ -11,18 +11,39 @@ AZ8 CLI requires Node.js 20 or newer. Install the preview channel from the confi
11
11
  npm install --global @everfir/az8-cli@preview
12
12
  az8 --version
13
13
  az8 help
14
+ az8 guide
14
15
  ```
15
16
 
16
17
  For a supplied release artifact, install the exact immutable tarball instead:
17
18
 
18
19
  ```bash
19
- npm install --global ./everfir-az8-cli-0.2.0-preview.1.tgz
20
+ npm install --global ./everfir-az8-cli-0.2.0-preview.2.tgz
20
21
  az8 --version
21
22
  ```
22
23
 
23
24
  `az8 --version` must report the version selected for the agent environment. Preview releases do not
24
25
  replace npm's `latest` channel. Pin an exact version or tarball for reproducible agent runs.
25
26
 
27
+ ## Built-in agent Skill
28
+
29
+ Run `az8 guide` before the first AZ8 action in a new agent environment. It requires no token or
30
+ network access and prints the versioned Skill shipped in the installed package. The guide defines
31
+ the platform concepts, safe operating contract, first-session and authoring SOPs, generation and
32
+ media workflows, failure recovery, prohibited actions, and completion checklist:
33
+
34
+ ```bash
35
+ az8 guide
36
+ az8 guide --section bootstrap
37
+ az8 guide --section safety
38
+ az8 guide --format json
39
+ ```
40
+
41
+ The guide teaches discovery; it does not freeze dynamic product schemas. After selecting a Project,
42
+ the agent must query `capabilities.summary` and `capabilities.detail` for the effective Operations,
43
+ permissions, input schema, History, completion, and retry semantics of the installed version and
44
+ current account. Workflow Definition queries and `planGeneration` remain authoritative for current
45
+ generation inputs.
46
+
26
47
  ## Credentials and environment
27
48
 
28
49
  Use an ignored `.env.local` or process environment:
@@ -311,8 +332,9 @@ moves the Canvas context offline, and requires explicit reconnect and inspection
311
332
  Before distributing a preview tarball, verify all of the following from its clean installation, not
312
333
  from TypeScript source:
313
334
 
314
- 1. `az8 --version` matches the immutable package version and `az8 help` lists Project, persistent
315
- Canvas, one-shot, upload, and download entry points.
335
+ 1. `az8 --version` matches the immutable package version; `az8 help` lists the built-in guide,
336
+ Project, persistent Canvas, one-shot, upload, and download entry points; and `az8 guide` plus its
337
+ JSON form work without credentials or network access.
316
338
  2. With no credential, an authenticated command fails without connecting and without printing a
317
339
  token. With the test token, `projects create` returns a new Project owned by the authenticated
318
340
  account.
package/RELEASE.md CHANGED
@@ -35,7 +35,7 @@ repository-wide `pnpm verify`. Publishing is an external action and requires exp
35
35
  authorization:
36
36
 
37
37
  ```bash
38
- npm publish ./tmp/az8-cli-release/everfir-az8-cli-0.2.0-preview.1.tgz --tag preview
38
+ npm publish ./tmp/az8-cli-release/everfir-az8-cli-0.2.0-preview.2.tgz --tag preview
39
39
  npm view @everfir/az8-cli dist-tags versions --json
40
40
  ```
41
41
 
package/dist/main.js CHANGED
@@ -23860,8 +23860,73 @@ var OrderedFrameWriter = class {
23860
23860
  import { randomUUID } from "node:crypto";
23861
23861
  import path5 from "node:path";
23862
23862
 
23863
- // src/canvas-one-shot.ts
23863
+ // src/agent-guide.ts
23864
23864
  import { readFile as readFile2 } from "node:fs/promises";
23865
+ var AGENT_GUIDE_URL = new URL("../skills/az8-cli/SKILL.md", import.meta.url);
23866
+ async function renderAgentGuide(options) {
23867
+ const guide = parseAgentGuide(await readFile2(AGENT_GUIDE_URL, "utf8"));
23868
+ const selected = options.section ? guide.sections.find((section) => section.id === options.section) : void 0;
23869
+ if (options.section && !selected) {
23870
+ throw new Error(
23871
+ `Unknown guide section: ${options.section}. Available sections: ${guide.sections.map((section) => section.id).join(", ")}.`
23872
+ );
23873
+ }
23874
+ if (options.format === "markdown") {
23875
+ return `${selected ? selected.markdown : guide.markdown.trimEnd()}
23876
+ `;
23877
+ }
23878
+ return `${JSON.stringify(
23879
+ {
23880
+ format: "az8.agent-guide.v1",
23881
+ packageVersion: options.packageVersion,
23882
+ skill: { description: guide.description, name: guide.name },
23883
+ ...selected ? { selectedSection: selected.id } : {},
23884
+ sections: selected ? [selected] : guide.sections
23885
+ },
23886
+ null,
23887
+ 2
23888
+ )}
23889
+ `;
23890
+ }
23891
+ function parseAgentGuideFormat(value) {
23892
+ if (value === void 0 || value === "markdown") return "markdown";
23893
+ if (value === "json") return "json";
23894
+ throw new Error(`Unknown guide format: ${value}. Expected markdown or json.`);
23895
+ }
23896
+ function parseAgentGuide(source) {
23897
+ const normalized = source.replaceAll("\r\n", "\n");
23898
+ const frontmatter = normalized.match(/^---\n([\s\S]*?)\n---\n/);
23899
+ if (!frontmatter) throw new Error("Packaged AZ8 agent guide has invalid frontmatter.");
23900
+ const name = readFrontmatterValue(frontmatter[1] ?? "", "name");
23901
+ const description = readFrontmatterValue(frontmatter[1] ?? "", "description");
23902
+ const body = normalized.slice(frontmatter[0].length);
23903
+ const headings = [...body.matchAll(/^## (.+)$/gm)];
23904
+ if (headings.length === 0) throw new Error("Packaged AZ8 agent guide has no sections.");
23905
+ const sections = headings.map((heading, index) => {
23906
+ const title = heading[1]?.trim() ?? "";
23907
+ const start = heading.index ?? 0;
23908
+ const end = headings[index + 1]?.index ?? body.length;
23909
+ return {
23910
+ id: slugify(title),
23911
+ markdown: body.slice(start, end).trimEnd(),
23912
+ title
23913
+ };
23914
+ });
23915
+ return { description, markdown: normalized, name, sections };
23916
+ }
23917
+ function readFrontmatterValue(frontmatter, key) {
23918
+ const prefix = `${key}:`;
23919
+ const line = frontmatter.split("\n").find((candidate) => candidate.startsWith(prefix));
23920
+ const value = line?.slice(prefix.length).trim();
23921
+ if (!value) throw new Error(`Packaged AZ8 agent guide is missing ${key}.`);
23922
+ return value.replace(/^(?:"(.*)"|'(.*)')$/, "$1$2");
23923
+ }
23924
+ function slugify(value) {
23925
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
23926
+ }
23927
+
23928
+ // src/canvas-one-shot.ts
23929
+ import { readFile as readFile3 } from "node:fs/promises";
23865
23930
  import path3 from "node:path";
23866
23931
  var MAX_INPUT_BYTES = 1024 * 1024;
23867
23932
  var PROCESS_SCOPED_OPERATIONS = /* @__PURE__ */ new Set(["redo", "undo"]);
@@ -23913,7 +23978,7 @@ async function readCanvasOneShotInput(argv2, dependencies = {}) {
23913
23978
  if (file !== void 0) {
23914
23979
  const filePath = path3.resolve(dependencies.cwd ?? process.cwd(), file);
23915
23980
  try {
23916
- source = dependencies.readFile ? await dependencies.readFile(filePath) : await readFile2(filePath, "utf8");
23981
+ source = dependencies.readFile ? await dependencies.readFile(filePath) : await readFile3(filePath, "utf8");
23917
23982
  } catch {
23918
23983
  throw canvasClientFailure(
23919
23984
  "invalid-operation-input",
@@ -24667,6 +24732,26 @@ async function runAz8Cli(argv2, dependencies = {}) {
24667
24732
  }
24668
24733
  const [scope, command, resourceId, capability] = readPositionals(argv2);
24669
24734
  if (!scope || scope === "help" || scope === "-h") return helpResult();
24735
+ if (scope === "guide") {
24736
+ if (command && command !== "help" && command !== "-h") {
24737
+ return errorResult(`Unknown guide command: ${command}`);
24738
+ }
24739
+ if (command === "help" || command === "-h") return guideHelpResult();
24740
+ try {
24741
+ const format = readGuideOption(argv2, "--format");
24742
+ const section = readGuideOption(argv2, "--section");
24743
+ return {
24744
+ exitCode: 0,
24745
+ stdout: await renderAgentGuide({
24746
+ format: parseAgentGuideFormat(format),
24747
+ packageVersion: readAz8CliVersion(),
24748
+ ...section ? { section } : {}
24749
+ })
24750
+ };
24751
+ } catch (error) {
24752
+ return errorResult(error instanceof Error ? error.message : "Unable to read agent guide.");
24753
+ }
24754
+ }
24670
24755
  if (scope !== "projects" && scope !== "canvas") return errorResult(`Unknown scope: ${scope}`);
24671
24756
  if (!command || command === "help" || command === "-h") {
24672
24757
  return scope === "projects" ? projectHelpResult() : canvasHelpResult();
@@ -24892,9 +24977,11 @@ function readPositionals(args2) {
24892
24977
  "--position-y",
24893
24978
  "--request-id",
24894
24979
  "--scope",
24980
+ "--section",
24895
24981
  "--service-url",
24896
24982
  "--timeout-ms",
24897
- "--view-node-id"
24983
+ "--view-node-id",
24984
+ "--format"
24898
24985
  ]);
24899
24986
  const positionals = [];
24900
24987
  for (let index = 0; index < args2.length; index += 1) {
@@ -24910,7 +24997,9 @@ function readPositionals(args2) {
24910
24997
  function helpResult() {
24911
24998
  return {
24912
24999
  exitCode: 0,
24913
- stdout: `${projectHelpOutput()}
25000
+ stdout: `${guideHelpOutput()}
25001
+
25002
+ ${projectHelpOutput()}
24914
25003
 
24915
25004
  ${canvasHelpOutput()}
24916
25005
 
@@ -24918,6 +25007,16 @@ ${commonHelpOutput()}
24918
25007
  `
24919
25008
  };
24920
25009
  }
25010
+ function guideHelpOutput() {
25011
+ return [
25012
+ "Agent onboarding:",
25013
+ " az8 guide Read the complete built-in agent Skill",
25014
+ " az8 guide --section <section> Read one Skill section",
25015
+ " az8 guide --format markdown|json Select output (default: markdown)",
25016
+ " Sections: contract, concepts, bootstrap, interaction-modes, canvas-sop, generation,",
25017
+ " media, recovery, safety, completion"
25018
+ ].join("\n");
25019
+ }
24921
25020
  function projectHelpOutput() {
24922
25021
  return [
24923
25022
  "Project management:",
@@ -24966,6 +25065,7 @@ function commonHelpOutput() {
24966
25065
  return [
24967
25066
  `AZ8 CLI ${readAz8CliVersion()}`,
24968
25067
  " az8 --version Print the installed package version",
25068
+ " az8 guide Read the built-in agent onboarding Skill",
24969
25069
  "",
24970
25070
  "Common options:",
24971
25071
  " --environment <test|production> Select the API environment (default: production)",
@@ -24980,6 +25080,18 @@ function canvasHelpResult() {
24980
25080
  ${commonHelpOutput()}
24981
25081
  ` };
24982
25082
  }
25083
+ function guideHelpResult() {
25084
+ return { exitCode: 0, stdout: `${guideHelpOutput()}
25085
+
25086
+ ${commonHelpOutput()}
25087
+ ` };
25088
+ }
25089
+ function readGuideOption(argv2, name) {
25090
+ if (!argv2.includes(name)) return void 0;
25091
+ const value = readOption(argv2, name);
25092
+ if (!value) throw new Error(`${name} requires a value.`);
25093
+ return value;
25094
+ }
24983
25095
  function projectHelpResult() {
24984
25096
  return { exitCode: 0, stdout: `${projectHelpOutput()}
24985
25097
 
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@everfir/az8-cli",
3
- "version": "0.2.0-preview.1",
3
+ "version": "0.2.0-preview.2",
4
4
  "description": "Semantic Project Canvas client for AZ8 Studio agents.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "files": [
8
8
  "dist",
9
+ "skills",
9
10
  "CHANGELOG.md",
10
11
  "RELEASE.md"
11
12
  ],
@@ -0,0 +1,278 @@
1
+ ---
2
+ name: az8-cli
3
+ description: Use AZ8 CLI to safely select or create Projects, inspect and author Project Canvases, run generation workflows, transfer media, and participate as a persistent collaborative agent. Use whenever a task asks an agent to read, create, edit, organize, generate, upload, or download content in AZ8 Studio.
4
+ ---
5
+
6
+ # Use AZ8 CLI
7
+
8
+ Treat `az8` as a semantic AZ8 Studio client, not as a document editor or generic backend client.
9
+ Follow this guide before the first Project Canvas action in a new environment. Query runtime
10
+ capabilities instead of guessing operation names or input shapes.
11
+
12
+ ## Contract
13
+
14
+ - Use only public `az8 projects` and `az8 canvas` commands. Never mutate backend records, Yjs,
15
+ Collaborative Document fields, Core Node payloads, or Project Content bindings directly.
16
+ - Explicitly select `test` or `production`. Never infer authorization to write production data.
17
+ - Read the relevant Canvas facts before planning a write. Submit one semantic Operation at a time.
18
+ - Treat every accepted write as a blocker: wait for its terminal Receipt before issuing any later
19
+ query or Operation.
20
+ - A sequence is ordered but not transactional. Stop immediately after the first failure or
21
+ indeterminate result; do not execute later steps.
22
+ - Never automatically retry a write. Retry only bounded reads when the returned error says doing so
23
+ is safe. An idempotency key does not authorize blind replay.
24
+ - Keep tokens in the process environment or an ignored env file. Never put a token in argv, an
25
+ stdio frame, a prompt, a log, or output.
26
+
27
+ ## Concepts
28
+
29
+ - **Project** is the collaboration and permission boundary. Create, list, get, and rename Projects
30
+ through `az8 projects`.
31
+ - **Project Canvas** is the synchronized creative surface inside one Project. A persistent client
32
+ has its own connection, lifecycle, projection, History, Receipt Log, and Awareness identity.
33
+ - **View Node** is a Canvas placement: note, group, or resource target with position, size, parent,
34
+ stacking, Draft, and presentation state.
35
+ - **Core Node** is immutable or server-owned creative content such as an image, video, or audio.
36
+ Resource View Nodes resolve Core Nodes through Project Content. Do not manufacture Core Nodes or
37
+ bindings.
38
+ - **Project Content** is the authority that associates a View Node target with its effective Core
39
+ Node output. Assets are a separate organization of Core Nodes and are not implemented here.
40
+ - **Workflow Definition** describes a generation capability and its current input contract.
41
+ **Workflow Run** is one server-side generation execution.
42
+ - **Operation** is one validated business interaction. **Command** is its internal mutation
43
+ boundary and is never caller-accessible.
44
+ - **Receipt** is the append-only record of one attempted Operation. It reports identity, ordering,
45
+ outcome, revisions, and optional usage. It is not Canvas History.
46
+ - **History** contains reversible local interactions. Only Operations advertised as `undoable`
47
+ participate. A generation start is a History barrier and is not undone by `undo`.
48
+ - **Awareness** is ephemeral presence, client name, and Attention Cursor information. It never
49
+ grants authority, changes persisted authorship, or proves a business result.
50
+ - **Actor** is the authenticated account from `AZ8_TOKEN`. A client or awareness name cannot
51
+ impersonate another author.
52
+
53
+ ## Bootstrap
54
+
55
+ 1. Verify the installed client and explicitly choose an environment:
56
+
57
+ ```bash
58
+ az8 --version
59
+ export AZ8_ENVIRONMENT=test
60
+ export AZ8_TOKEN=...
61
+ ```
62
+
63
+ Prefer an ignored `.env.local` when the shell environment is not appropriate. Never print the
64
+ token to confirm it.
65
+
66
+ 2. Select an existing Project or create a bounded workspace:
67
+
68
+ ```bash
69
+ az8 projects list --scope owned
70
+ az8 projects get <project-id>
71
+ az8 projects create --name "Agent workspace"
72
+ ```
73
+
74
+ Retain the returned Project ID. Confirm the authenticated role before assuming write access.
75
+
76
+ 3. Discover the effective surface for that Project:
77
+
78
+ ```bash
79
+ az8 canvas query <project-id> capabilities.summary
80
+ az8 canvas query <project-id> capabilities.detail
81
+ az8 canvas query <project-id> canvas.summary
82
+ ```
83
+
84
+ `capabilities.summary` is the short menu. `capabilities.detail` is authoritative for exact JSON
85
+ Schema, `effect`, `history`, `completion`, and `retry`. Availability is filtered by the current
86
+ account, Project role, upstream services, and CLI version. Do not rely on remembered schemas.
87
+
88
+ 4. Use `canvas.detail` only when exact node geometry, Draft, status, or bindings are needed:
89
+
90
+ ```bash
91
+ az8 canvas query <project-id> canvas.detail --view-node-id <view-node-id>
92
+ ```
93
+
94
+ 5. Choose one-shot for independent tasks and persistent stdio for a collaborative session. Finish
95
+ by inspecting the affected View Nodes or Workflow Run rather than trusting visual assumptions.
96
+
97
+ ## Interaction modes
98
+
99
+ Use one-shot commands for a self-contained query, write, upload, or download:
100
+
101
+ ```bash
102
+ printf '%s\n' '{"text":"Idea","position":{"x":160,"y":160}}' |
103
+ az8 canvas operation <project-id> createNote --input-stdin --request-id create-note-1
104
+ ```
105
+
106
+ - Supply Operation input through exactly one of `--input-stdin`, `--input-file`, or `--input-json`.
107
+ - Give every write attempt a meaningful unique `--request-id` and retain its returned Receipt.
108
+ - Each invocation opens, hydrates, executes, and closes a real Canvas client.
109
+ - One-shot processes do not preserve local History, Receipt Log, Awareness, or request replay.
110
+ Therefore `undo`, `redo`, `receipts.summary`, and `receipt.detail` require persistent stdio.
111
+
112
+ Use persistent stdio when multiple ordered interactions, live synchronization, History, Receipt
113
+ lookup, observations, or human collaboration matter:
114
+
115
+ ```bash
116
+ az8 canvas open <project-id> --write --format ndjson
117
+ ```
118
+
119
+ 1. Continuously drain stdout; it is an ordered NDJSON protocol stream and may apply backpressure.
120
+ 2. Read `hello`, select protocol `1.0`, then send `initialize` for the same Project ID.
121
+ 3. Wait for `ready` before any query or Operation.
122
+ 4. Keep exactly one reader for stdout. Parse each frame by `type`, `requestId`, and `streamSeq`.
123
+ 5. Use `compact` observations by default. Query `awareness.detail` when cursor context is needed;
124
+ cursor coordinates are intentionally not streamed.
125
+ 6. On an observation gap, query summary/detail and rebuild the local view.
126
+ 7. Send `shutdown` and wait for ordered completion. EOF or a signal is emergency cleanup, not a
127
+ cancellation or rollback mechanism.
128
+
129
+ Protocol truth is written to stdout. stderr contains diagnostics only. Unknown optional fields are
130
+ additive; ignore them. Do not treat a process exit code as the result of the last persistent request.
131
+
132
+ ## Canvas SOP
133
+
134
+ 1. Query `canvas.summary`; query selected details only as needed.
135
+ 2. Query `capabilities.detail` and validate the planned Operation input against its schema.
136
+ 3. Pick explicit absolute Canvas coordinates. Public move positions remain absolute even for group
137
+ children.
138
+ 4. Submit one Operation with a new request ID and wait for its terminal Receipt.
139
+ 5. Confirm the Receipt outcome and affected IDs, then query the changed View Node when subsequent
140
+ work depends on its exact state.
141
+ 6. Only then plan the next interaction.
142
+
143
+ Common capabilities include notes, move/resize/rename, duplicate/remove, groups and stacking, Core
144
+ Node placement, and media targets. The runtime catalog is authoritative. Group nodes cannot nest;
145
+ stacking applies only among siblings. Unsupported World, Decoration, Asset, alignment, and automatic
146
+ layout behavior must not be simulated through lower-level writes.
147
+
148
+ Use `undo` or `redo` only in the same persistent session and only after checking History semantics
149
+ in capability detail. Silent edits are valid Web-equivalent interactions but do not create History
150
+ entries. Never use compensating low-level mutations to imitate undo.
151
+
152
+ ## Generation
153
+
154
+ Generation is an explicit sequence, never one transaction:
155
+
156
+ 1. Create a target with `createMediaTarget` and retain its View Node ID.
157
+ 2. Call the read-only `planGeneration` Operation with the target, prompt, and any references. Use
158
+ `detail: "detail"` when configuration fields or dynamic enum options are needed.
159
+ 3. If the plan reports blocking issues, resolve them and plan again. Do not execute a non-ready
160
+ plan.
161
+ 4. Execute `plan.operations` exactly in order, one Operation at a time. Each step revalidates
162
+ current facts. Stop after the first non-success.
163
+ 5. `startGeneration` succeeds when the Workflow Run is accepted and immediate Canvas effects are
164
+ acknowledged. This completes the start interaction; it does not mean generation finished.
165
+ 6. Retain the Workflow Run ID. Use `waitWorkflowRun` when waiting is useful, or `getWorkflowRun`
166
+ later. An observation-window timeout while the authoritative Run remains pending/running is an
167
+ ordinary read outcome and does not cancel the Run or take a healthy context offline.
168
+ 7. On terminal success, query the target detail and resolve its current output Core Node through
169
+ Project Content before downloading or placing it elsewhere.
170
+
171
+ Workflow Definitions change over time. Query `workflowDefinitions.summary`, then
172
+ `workflowDefinition.detail` only when planning detail is insufficient. Never guess a Definition,
173
+ configuration option, modality, cost, or media compatibility from its display name.
174
+
175
+ The start Receipt may report `usage.credits.status` as `estimated`, `not-consumed`, or `unknown`.
176
+ Estimated cost is informational, not final charged usage. There is no second confirmation. Never
177
+ claim actual credit consumption from an estimate.
178
+
179
+ ## Media
180
+
181
+ For a local image, video, or audio file, use the semantic upload wrapper:
182
+
183
+ ```bash
184
+ az8 canvas upload <project-id> \
185
+ --file ./reference.png \
186
+ --idempotency-key reference-image-1 \
187
+ --name "Reference image" \
188
+ --position-x 640 --position-y 160
189
+ ```
190
+
191
+ - Use a stable logical idempotency key for that exact file intent. Conflicting key reuse is an
192
+ error. Replay only after inspecting and reconciling the prior attempt.
193
+ - Let the CLI inspect bytes, MIME, size, and checksum and let the server create the Core Node and
194
+ binding. Do not supply a claimed media type, upload URL, Core Node ID, or Project Content record.
195
+ - A known failure may leave one inspectable `failed` View Node. An unknown response leaves it
196
+ `pending` and isolates the context; do not create a replacement until reconciliation.
197
+
198
+ Use `importExternalMedia` only for a deliberate public HTTP(S) media URL. It references that URL; it
199
+ does not upload bytes or add content to an Asset.
200
+
201
+ Download only an effective View Node output or an explicit Core Node within the Project context:
202
+
203
+ ```bash
204
+ az8 canvas download <project-id> --view-node-id <view-node-id> --output ./result.png
205
+ ```
206
+
207
+ The destination must be explicit. Existing files are preserved unless `--overwrite` is explicitly
208
+ chosen. Verify the returned absolute path, byte count, detected MIME, Core Node ID, and SHA-256.
209
+ Never extract or reuse hidden media URLs as a general downloader.
210
+
211
+ ## Recovery
212
+
213
+ Classify the outcome before deciding what to do:
214
+
215
+ - **Succeeded:** accept only a terminal success result/Receipt, retain returned identities, and
216
+ inspect facts required by the next step.
217
+ - **Definitive failure:** the Operation did not take its promised effect. Fix input, permissions, or
218
+ business state before making a new explicitly identified attempt.
219
+ - **Indeterminate write:** acknowledgement, transport, backend response, or deadline was lost after
220
+ the write might have started. Assume neither success nor failure. Stop the sequence, take the
221
+ context offline, reconnect manually, inspect Canvas/Project Content/Workflow facts and Receipts,
222
+ then decide whether a new attempt is safe. Never automatically retry.
223
+ - **Read failure:** retry only if capability/error metadata marks the read retryable, and keep the
224
+ retry bounded. A reconnect failure cancels queued unfinished work; it does not replay it.
225
+ - **Workflow wait timeout:** if the Run is authoritatively still pending or running, treat this as
226
+ the end of one observation window. Continue other work or query later; do not cancel or restart.
227
+ - **Caller cancellation:** cancellation is safe only before an Operation begins. Once a write has
228
+ attempted to start, interruption waits for its deadline and cannot roll it back. After uncertainty,
229
+ reconcile facts before acting.
230
+
231
+ For one-shot Canvas commands, exit `0` means success, `1` means a definitive caller/business
232
+ failure, and `2` means an indeterminate lifecycle or transport outcome. Media download may return
233
+ `130` for caller cancellation. Always read the structured result; do not generalize these codes to
234
+ Project commands or the lifetime of a persistent stdio process.
235
+
236
+ ## Safety
237
+
238
+ Never:
239
+
240
+ - write raw backend endpoints, Yjs maps, Collaborative Document paths, generic patches, Core Node
241
+ payloads, or Project Content bindings;
242
+ - invent an Operation or input field absent from `capabilities.detail`;
243
+ - execute writes concurrently, continue a planned sequence after a failure, or wrap multiple
244
+ Operations in assumed transaction semantics;
245
+ - automatically retry a write, reuse a request ID for an unrelated attempt, or treat an idempotency
246
+ key as proof that blind replay is safe;
247
+ - conclude that a timed-out write failed, conclude that an accepted Workflow Run completed, or
248
+ conclude that an Awareness event persisted data;
249
+ - expose a token, presigned URL, permanent media URL, env-file contents, or private output in logs
250
+ or protocol payloads;
251
+ - use awareness client names to impersonate persisted authors or treat Attention Cursor position as
252
+ authority;
253
+ - use one-shot as if it retained History, Receipts, replay state, observations, or presence;
254
+ - attempt Asset membership, arbitrary Core Node creation, 3D World editing, unsupported
255
+ Decoration, alignment, or automatic layout through lower-level access;
256
+ - write production unless the user explicitly selected and authorized production for the concrete
257
+ action.
258
+
259
+ ## Completion
260
+
261
+ Before reporting a task complete, verify all applicable facts:
262
+
263
+ - The intended environment, Project ID, authenticated role, and installed CLI version are known.
264
+ - Runtime capability discovery—not memory—authorized every Operation and input schema used.
265
+ - Every write has its own request ID, terminal Receipt, and sequential position; no write was
266
+ automatically retried.
267
+ - The first failure stopped the remaining sequence, and every indeterminate effect was reconciled
268
+ after explicit reconnect/inspection.
269
+ - Created or edited View Nodes were checked at the detail level needed by downstream work.
270
+ - Generation start and generation completion were reported as separate interactions; the target's
271
+ effective Core Node was resolved after completion.
272
+ - Media transfers were verified by identities and checksums without exposing URLs or credentials.
273
+ - Persistent stdio was shut down in order, or any abnormal termination and uncertain active write
274
+ was disclosed.
275
+ - Deferred scopes were not approximated by bypassing the public semantic surface.
276
+
277
+ When any item cannot be proven, report the uncertainty and the next safe read or reconciliation
278
+ step instead of claiming completion.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "AZ8 CLI"
3
+ short_description: "Safely create and collaborate in AZ8 Project Canvases"
4
+ default_prompt: "Use $az8-cli to create or edit an AZ8 Project Canvas safely."