@everfir/az8-cli 0.2.0-preview.1 → 0.2.0-preview.3

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,34 @@
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.3 - 2026-07-21
7
+
8
+ ### Changed
9
+
10
+ - The built-in Skill now treats credentials as an operator or agent-host provisioning precondition
11
+ and explains inherited environment, default `.env.local`, and explicit `--env-file` resolution.
12
+ - Authentication is verified with a bounded Project read without inspecting, printing, copying, or
13
+ editing the token source.
14
+ - The shell example that could encourage an agent to type a real token into a recorded interaction
15
+ has been removed, and missing or invalid credentials now direct the agent back to secure external
16
+ provisioning.
17
+
18
+ ## 0.2.0-preview.2 - 2026-07-21
19
+
20
+ ### Added
21
+
22
+ - A platform-neutral built-in agent Skill available through `az8 guide` without credentials or a
23
+ network connection.
24
+ - Section-level Markdown and versioned JSON guide output for progressive discovery.
25
+ - Agent onboarding for platform concepts, runtime capability discovery, first-session, Canvas,
26
+ generation and media SOPs, failure recovery, prohibited actions, and completion checks.
27
+
28
+ ### Safety and compatibility
29
+
30
+ - The Skill never replaces Project-scoped `capabilities.detail` or Workflow Definition discovery;
31
+ dynamic schemas, permissions, completion, History, and retry policy remain runtime-authoritative.
32
+ - Existing semantic Operations and protocol version `1.0` are unchanged.
33
+
6
34
  ## 0.2.0-preview.1 - 2026-07-21
7
35
 
8
36
  First installable internal preview.
package/README.md CHANGED
@@ -11,29 +11,55 @@ 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.3.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
- Use an ignored `.env.local` or process environment:
49
+ Credentials must be provisioned outside the agent's recorded interaction. Use an ignored
50
+ `.env.local`, an explicit env-file path, or an inherited process environment:
29
51
 
30
52
  ```dotenv
31
- AZ8_TOKEN=...
53
+ AZ8_TOKEN=<operator-provisioned-secret>
32
54
  AZ8_ENVIRONMENT=test
33
55
  ```
34
56
 
35
57
  `AZ8_ENVIRONMENT` accepts `test` or `production`. Command-line `--environment` overrides the env
36
- value. Tokens must not be passed through argv or stdio protocol payloads.
58
+ value. Without `--env-file`, the CLI searches from the working directory upward for `.env.local`.
59
+ An explicit file is selected by path, for example
60
+ `--environment test --env-file /secure/path/.env.local`. Agents must not read, print, edit, or ask
61
+ users to paste credential contents; verify authentication with a bounded `projects list` read.
62
+ Tokens must not be passed through argv or stdio protocol payloads.
37
63
 
38
64
  ## Project Management
39
65
 
@@ -311,8 +337,9 @@ moves the Canvas context offline, and requires explicit reconnect and inspection
311
337
  Before distributing a preview tarball, verify all of the following from its clean installation, not
312
338
  from TypeScript source:
313
339
 
314
- 1. `az8 --version` matches the immutable package version and `az8 help` lists Project, persistent
315
- Canvas, one-shot, upload, and download entry points.
340
+ 1. `az8 --version` matches the immutable package version; `az8 help` lists the built-in guide,
341
+ Project, persistent Canvas, one-shot, upload, and download entry points; and `az8 guide` plus its
342
+ JSON form work without credentials or network access.
316
343
  2. With no credential, an authenticated command fails without connecting and without printing a
317
344
  token. With the test token, `projects create` returns a new Project owned by the authenticated
318
345
  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.3.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.3",
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,304 @@
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
+ - Require the operator or agent host to provision credentials outside the recorded interaction.
25
+ Keep tokens in the inherited process environment or an ignored env file. Never type, read, copy,
26
+ print, or return a token through a shell tool call, argv, stdio frame, prompt, log, or output.
27
+
28
+ ## Concepts
29
+
30
+ - **Project** is the collaboration and permission boundary. Create, list, get, and rename Projects
31
+ through `az8 projects`.
32
+ - **Project Canvas** is the synchronized creative surface inside one Project. A persistent client
33
+ has its own connection, lifecycle, projection, History, Receipt Log, and Awareness identity.
34
+ - **View Node** is a Canvas placement: note, group, or resource target with position, size, parent,
35
+ stacking, Draft, and presentation state.
36
+ - **Core Node** is immutable or server-owned creative content such as an image, video, or audio.
37
+ Resource View Nodes resolve Core Nodes through Project Content. Do not manufacture Core Nodes or
38
+ bindings.
39
+ - **Project Content** is the authority that associates a View Node target with its effective Core
40
+ Node output. Assets are a separate organization of Core Nodes and are not implemented here.
41
+ - **Workflow Definition** describes a generation capability and its current input contract.
42
+ **Workflow Run** is one server-side generation execution.
43
+ - **Operation** is one validated business interaction. **Command** is its internal mutation
44
+ boundary and is never caller-accessible.
45
+ - **Receipt** is the append-only record of one attempted Operation. It reports identity, ordering,
46
+ outcome, revisions, and optional usage. It is not Canvas History.
47
+ - **History** contains reversible local interactions. Only Operations advertised as `undoable`
48
+ participate. A generation start is a History barrier and is not undone by `undo`.
49
+ - **Awareness** is ephemeral presence, client name, and Attention Cursor information. It never
50
+ grants authority, changes persisted authorship, or proves a business result.
51
+ - **Actor** is the authenticated account from `AZ8_TOKEN`. A client or awareness name cannot
52
+ impersonate another author.
53
+
54
+ ## Bootstrap
55
+
56
+ 1. Verify the installed client without credentials:
57
+
58
+ ```bash
59
+ az8 --version
60
+ ```
61
+
62
+ 2. Require credentials to be provisioned by the operator or agent host before authenticating. The
63
+ CLI accepts `AZ8_TOKEN` from its inherited process environment or an env file. A provisioned env
64
+ file has this shape, but the agent must not fill the placeholder with a real token in a recorded
65
+ interaction:
66
+
67
+ ```dotenv
68
+ AZ8_TOKEN=<operator-provisioned-secret>
69
+ AZ8_ENVIRONMENT=test
70
+ ```
71
+
72
+ With no `--env-file`, the CLI searches for `.env.local` from the working directory upward. An
73
+ explicit file may live elsewhere and is selected only by path:
74
+
75
+ ```bash
76
+ az8 projects list --scope owned --page-size 1 \
77
+ --environment test --env-file /secure/path/.env.local
78
+ ```
79
+
80
+ Use the authenticated read as the credential check. Never verify a token with `cat`, `sed`,
81
+ `grep`, `env`, `printenv`, `echo`, shell tracing, or by reading the env file through another
82
+ tool. Do not create, edit, move, or delete a credential file unless the operator explicitly asks
83
+ through a secure provisioning workflow. Keep it outside version control with owner-only access.
84
+
85
+ The inherited process environment overrides env-file values; `--environment` overrides
86
+ `AZ8_ENVIRONMENT`. Always pass or provision the intended environment explicitly. If the CLI
87
+ reports a missing token or authentication failure, stop and ask the operator to provision or
88
+ replace it outside the conversation. Never ask them to paste the secret into chat.
89
+
90
+ 3. Select an existing Project or create a bounded workspace:
91
+
92
+ ```bash
93
+ az8 projects list --scope owned
94
+ az8 projects get <project-id>
95
+ az8 projects create --name "Agent workspace"
96
+ ```
97
+
98
+ Retain the returned Project ID. Confirm the authenticated role before assuming write access.
99
+
100
+ 4. Discover the effective surface for that Project:
101
+
102
+ ```bash
103
+ az8 canvas query <project-id> capabilities.summary
104
+ az8 canvas query <project-id> capabilities.detail
105
+ az8 canvas query <project-id> canvas.summary
106
+ ```
107
+
108
+ `capabilities.summary` is the short menu. `capabilities.detail` is authoritative for exact JSON
109
+ Schema, `effect`, `history`, `completion`, and `retry`. Availability is filtered by the current
110
+ account, Project role, upstream services, and CLI version. Do not rely on remembered schemas.
111
+
112
+ 5. Use `canvas.detail` only when exact node geometry, Draft, status, or bindings are needed:
113
+
114
+ ```bash
115
+ az8 canvas query <project-id> canvas.detail --view-node-id <view-node-id>
116
+ ```
117
+
118
+ 6. Choose one-shot for independent tasks and persistent stdio for a collaborative session. Finish
119
+ by inspecting the affected View Nodes or Workflow Run rather than trusting visual assumptions.
120
+
121
+ ## Interaction modes
122
+
123
+ Use one-shot commands for a self-contained query, write, upload, or download:
124
+
125
+ ```bash
126
+ printf '%s\n' '{"text":"Idea","position":{"x":160,"y":160}}' |
127
+ az8 canvas operation <project-id> createNote --input-stdin --request-id create-note-1
128
+ ```
129
+
130
+ - Supply Operation input through exactly one of `--input-stdin`, `--input-file`, or `--input-json`.
131
+ - Give every write attempt a meaningful unique `--request-id` and retain its returned Receipt.
132
+ - Each invocation opens, hydrates, executes, and closes a real Canvas client.
133
+ - One-shot processes do not preserve local History, Receipt Log, Awareness, or request replay.
134
+ Therefore `undo`, `redo`, `receipts.summary`, and `receipt.detail` require persistent stdio.
135
+
136
+ Use persistent stdio when multiple ordered interactions, live synchronization, History, Receipt
137
+ lookup, observations, or human collaboration matter:
138
+
139
+ ```bash
140
+ az8 canvas open <project-id> --write --format ndjson
141
+ ```
142
+
143
+ 1. Continuously drain stdout; it is an ordered NDJSON protocol stream and may apply backpressure.
144
+ 2. Read `hello`, select protocol `1.0`, then send `initialize` for the same Project ID.
145
+ 3. Wait for `ready` before any query or Operation.
146
+ 4. Keep exactly one reader for stdout. Parse each frame by `type`, `requestId`, and `streamSeq`.
147
+ 5. Use `compact` observations by default. Query `awareness.detail` when cursor context is needed;
148
+ cursor coordinates are intentionally not streamed.
149
+ 6. On an observation gap, query summary/detail and rebuild the local view.
150
+ 7. Send `shutdown` and wait for ordered completion. EOF or a signal is emergency cleanup, not a
151
+ cancellation or rollback mechanism.
152
+
153
+ Protocol truth is written to stdout. stderr contains diagnostics only. Unknown optional fields are
154
+ additive; ignore them. Do not treat a process exit code as the result of the last persistent request.
155
+
156
+ ## Canvas SOP
157
+
158
+ 1. Query `canvas.summary`; query selected details only as needed.
159
+ 2. Query `capabilities.detail` and validate the planned Operation input against its schema.
160
+ 3. Pick explicit absolute Canvas coordinates. Public move positions remain absolute even for group
161
+ children.
162
+ 4. Submit one Operation with a new request ID and wait for its terminal Receipt.
163
+ 5. Confirm the Receipt outcome and affected IDs, then query the changed View Node when subsequent
164
+ work depends on its exact state.
165
+ 6. Only then plan the next interaction.
166
+
167
+ Common capabilities include notes, move/resize/rename, duplicate/remove, groups and stacking, Core
168
+ Node placement, and media targets. The runtime catalog is authoritative. Group nodes cannot nest;
169
+ stacking applies only among siblings. Unsupported World, Decoration, Asset, alignment, and automatic
170
+ layout behavior must not be simulated through lower-level writes.
171
+
172
+ Use `undo` or `redo` only in the same persistent session and only after checking History semantics
173
+ in capability detail. Silent edits are valid Web-equivalent interactions but do not create History
174
+ entries. Never use compensating low-level mutations to imitate undo.
175
+
176
+ ## Generation
177
+
178
+ Generation is an explicit sequence, never one transaction:
179
+
180
+ 1. Create a target with `createMediaTarget` and retain its View Node ID.
181
+ 2. Call the read-only `planGeneration` Operation with the target, prompt, and any references. Use
182
+ `detail: "detail"` when configuration fields or dynamic enum options are needed.
183
+ 3. If the plan reports blocking issues, resolve them and plan again. Do not execute a non-ready
184
+ plan.
185
+ 4. Execute `plan.operations` exactly in order, one Operation at a time. Each step revalidates
186
+ current facts. Stop after the first non-success.
187
+ 5. `startGeneration` succeeds when the Workflow Run is accepted and immediate Canvas effects are
188
+ acknowledged. This completes the start interaction; it does not mean generation finished.
189
+ 6. Retain the Workflow Run ID. Use `waitWorkflowRun` when waiting is useful, or `getWorkflowRun`
190
+ later. An observation-window timeout while the authoritative Run remains pending/running is an
191
+ ordinary read outcome and does not cancel the Run or take a healthy context offline.
192
+ 7. On terminal success, query the target detail and resolve its current output Core Node through
193
+ Project Content before downloading or placing it elsewhere.
194
+
195
+ Workflow Definitions change over time. Query `workflowDefinitions.summary`, then
196
+ `workflowDefinition.detail` only when planning detail is insufficient. Never guess a Definition,
197
+ configuration option, modality, cost, or media compatibility from its display name.
198
+
199
+ The start Receipt may report `usage.credits.status` as `estimated`, `not-consumed`, or `unknown`.
200
+ Estimated cost is informational, not final charged usage. There is no second confirmation. Never
201
+ claim actual credit consumption from an estimate.
202
+
203
+ ## Media
204
+
205
+ For a local image, video, or audio file, use the semantic upload wrapper:
206
+
207
+ ```bash
208
+ az8 canvas upload <project-id> \
209
+ --file ./reference.png \
210
+ --idempotency-key reference-image-1 \
211
+ --name "Reference image" \
212
+ --position-x 640 --position-y 160
213
+ ```
214
+
215
+ - Use a stable logical idempotency key for that exact file intent. Conflicting key reuse is an
216
+ error. Replay only after inspecting and reconciling the prior attempt.
217
+ - Let the CLI inspect bytes, MIME, size, and checksum and let the server create the Core Node and
218
+ binding. Do not supply a claimed media type, upload URL, Core Node ID, or Project Content record.
219
+ - A known failure may leave one inspectable `failed` View Node. An unknown response leaves it
220
+ `pending` and isolates the context; do not create a replacement until reconciliation.
221
+
222
+ Use `importExternalMedia` only for a deliberate public HTTP(S) media URL. It references that URL; it
223
+ does not upload bytes or add content to an Asset.
224
+
225
+ Download only an effective View Node output or an explicit Core Node within the Project context:
226
+
227
+ ```bash
228
+ az8 canvas download <project-id> --view-node-id <view-node-id> --output ./result.png
229
+ ```
230
+
231
+ The destination must be explicit. Existing files are preserved unless `--overwrite` is explicitly
232
+ chosen. Verify the returned absolute path, byte count, detected MIME, Core Node ID, and SHA-256.
233
+ Never extract or reuse hidden media URLs as a general downloader.
234
+
235
+ ## Recovery
236
+
237
+ Classify the outcome before deciding what to do:
238
+
239
+ - **Succeeded:** accept only a terminal success result/Receipt, retain returned identities, and
240
+ inspect facts required by the next step.
241
+ - **Definitive failure:** the Operation did not take its promised effect. Fix input, permissions, or
242
+ business state before making a new explicitly identified attempt.
243
+ - **Indeterminate write:** acknowledgement, transport, backend response, or deadline was lost after
244
+ the write might have started. Assume neither success nor failure. Stop the sequence, take the
245
+ context offline, reconnect manually, inspect Canvas/Project Content/Workflow facts and Receipts,
246
+ then decide whether a new attempt is safe. Never automatically retry.
247
+ - **Read failure:** retry only if capability/error metadata marks the read retryable, and keep the
248
+ retry bounded. A reconnect failure cancels queued unfinished work; it does not replay it.
249
+ - **Workflow wait timeout:** if the Run is authoritatively still pending or running, treat this as
250
+ the end of one observation window. Continue other work or query later; do not cancel or restart.
251
+ - **Caller cancellation:** cancellation is safe only before an Operation begins. Once a write has
252
+ attempted to start, interruption waits for its deadline and cannot roll it back. After uncertainty,
253
+ reconcile facts before acting.
254
+
255
+ For one-shot Canvas commands, exit `0` means success, `1` means a definitive caller/business
256
+ failure, and `2` means an indeterminate lifecycle or transport outcome. Media download may return
257
+ `130` for caller cancellation. Always read the structured result; do not generalize these codes to
258
+ Project commands or the lifetime of a persistent stdio process.
259
+
260
+ ## Safety
261
+
262
+ Never:
263
+
264
+ - write raw backend endpoints, Yjs maps, Collaborative Document paths, generic patches, Core Node
265
+ payloads, or Project Content bindings;
266
+ - invent an Operation or input field absent from `capabilities.detail`;
267
+ - execute writes concurrently, continue a planned sequence after a failure, or wrap multiple
268
+ Operations in assumed transaction semantics;
269
+ - automatically retry a write, reuse a request ID for an unrelated attempt, or treat an idempotency
270
+ key as proof that blind replay is safe;
271
+ - conclude that a timed-out write failed, conclude that an accepted Workflow Run completed, or
272
+ conclude that an Awareness event persisted data;
273
+ - expose a token, presigned URL, permanent media URL, env-file contents, or private output in logs
274
+ or protocol payloads;
275
+ - inspect, print, or edit an operator-provisioned credential source merely to check whether it
276
+ exists; authenticate with a bounded read instead;
277
+ - use awareness client names to impersonate persisted authors or treat Attention Cursor position as
278
+ authority;
279
+ - use one-shot as if it retained History, Receipts, replay state, observations, or presence;
280
+ - attempt Asset membership, arbitrary Core Node creation, 3D World editing, unsupported
281
+ Decoration, alignment, or automatic layout through lower-level access;
282
+ - write production unless the user explicitly selected and authorized production for the concrete
283
+ action.
284
+
285
+ ## Completion
286
+
287
+ Before reporting a task complete, verify all applicable facts:
288
+
289
+ - The intended environment, Project ID, authenticated role, and installed CLI version are known.
290
+ - Runtime capability discovery—not memory—authorized every Operation and input schema used.
291
+ - Every write has its own request ID, terminal Receipt, and sequential position; no write was
292
+ automatically retried.
293
+ - The first failure stopped the remaining sequence, and every indeterminate effect was reconciled
294
+ after explicit reconnect/inspection.
295
+ - Created or edited View Nodes were checked at the detail level needed by downstream work.
296
+ - Generation start and generation completion were reported as separate interactions; the target's
297
+ effective Core Node was resolved after completion.
298
+ - Media transfers were verified by identities and checksums without exposing URLs or credentials.
299
+ - Persistent stdio was shut down in order, or any abnormal termination and uncertain active write
300
+ was disclosed.
301
+ - Deferred scopes were not approximated by bypassing the public semantic surface.
302
+
303
+ When any item cannot be proven, report the uncertainty and the next safe read or reconciliation
304
+ 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."