@everfir/az8-cli 0.2.0-preview.4 → 0.2.0-preview.5
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 +12 -0
- package/README.md +15 -6
- package/RELEASE.md +1 -1
- package/dist/main.js +72 -15
- package/package.json +1 -1
- package/skills/az8-cli/SKILL.md +13 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
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.5 - 2026-07-22
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- Canvas awareness names now preserve the authenticated user's Web-equivalent display name first
|
|
11
|
+
and append a CLI-owned parenthesized client suffix, defaulting to `(cli)`.
|
|
12
|
+
- `--client-name <suffix>` may override the client suffix for persistent and one-shot lifecycles,
|
|
13
|
+
but caller-provided parentheses are rejected so presence cannot obscure the name boundary.
|
|
14
|
+
- CLI attention awareness now publishes only the semantic cursor and omits selection bounds.
|
|
15
|
+
- `startGeneration` now carries valid Workflow execution-time estimates into the View Node's
|
|
16
|
+
generation history as Web-compatible median and maximum completion timestamps.
|
|
17
|
+
|
|
6
18
|
## 0.2.0-preview.4 - 2026-07-22
|
|
7
19
|
|
|
8
20
|
### Changed
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ az8 guide
|
|
|
17
17
|
For a supplied release artifact, install the exact immutable tarball instead:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npm install --global ./everfir-az8-cli-0.2.0-preview.
|
|
20
|
+
npm install --global ./everfir-az8-cli-0.2.0-preview.5.tgz
|
|
21
21
|
az8 --version
|
|
22
22
|
```
|
|
23
23
|
|
|
@@ -124,7 +124,10 @@ az8 canvas operation <project-id> startGeneration \
|
|
|
124
124
|
Operation input is one JSON object supplied by exactly one of `--input-stdin`, `--input-file`, or
|
|
125
125
|
`--input-json`; omitted input defaults to `{}`. Input is limited to one MiB. `--timeout-ms` controls
|
|
126
126
|
the same Operation acknowledgement or domain observation window as persistent stdio, and
|
|
127
|
-
`--client-name` changes only the ephemeral awareness
|
|
127
|
+
`--client-name` changes only the parenthesized client suffix of the ephemeral awareness name. The
|
|
128
|
+
authenticated display name always remains first: the default is `<current user> (cli)`, while
|
|
129
|
+
`--client-name codex` produces `<current user> (codex)`. Parentheses are owned by the CLI and are
|
|
130
|
+
rejected in caller-provided suffixes.
|
|
128
131
|
|
|
129
132
|
Success writes one `az8.canvas.one-shot.v1` JSON document to stdout and exits `0`. A definitive
|
|
130
133
|
input, validation, permission, or business failure writes structured JSON to stderr and exits `1`.
|
|
@@ -216,7 +219,7 @@ Canvas query, keep capability discovery and all ordered Operations in the same l
|
|
|
216
219
|
it down only after the authoring task is complete.
|
|
217
220
|
|
|
218
221
|
```bash
|
|
219
|
-
az8 canvas open <project-id> --write --format ndjson
|
|
222
|
+
az8 canvas open <project-id> --write --format ndjson [--client-name codex]
|
|
220
223
|
```
|
|
221
224
|
|
|
222
225
|
The process writes one `hello` frame, then waits for an `initialize` request on stdin:
|
|
@@ -226,9 +229,12 @@ The process writes one `hello` frame, then waits for an `initialize` request on
|
|
|
226
229
|
```
|
|
227
230
|
|
|
228
231
|
Before readiness the client hydrates the current authenticated account profile. Canvas Operations use
|
|
229
|
-
that immutable account id and display name for persisted creator data.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
that immutable account id and display name for persisted creator data. Awareness always displays the
|
|
233
|
+
authenticated name first and a CLI-owned parenthesized client suffix second. The default suffix is
|
|
234
|
+
`cli`; startup `--client-name` overrides it, otherwise `initialize.client.name` may provide it.
|
|
235
|
+
Caller suffixes cannot contain parentheses. This name is awareness-only and cannot impersonate or
|
|
236
|
+
rename the persisted author. The CLI publishes its Attention Cursor but deliberately omits selection
|
|
237
|
+
bounds. Project owner metadata is likewise never treated as the current actor on shared Projects.
|
|
232
238
|
|
|
233
239
|
After `ready`, requests use `query`, `configureObservations`, `operation`, `reconnect`, or `shutdown`.
|
|
234
240
|
The public authoring surface includes the note lifecycle, non-World View Node hierarchy operations,
|
|
@@ -311,6 +317,9 @@ explicitly submitting the same input. An uncertain backend or collaboration outc
|
|
|
311
317
|
are acknowledged. It first estimates the exact current Draft inputs, then materializes literal Core
|
|
312
318
|
Nodes and starts with the estimate's cost and Definition version. This estimate is internal: there is
|
|
313
319
|
no public estimate Operation, balance query, caller-supplied expected cost, or second confirmation.
|
|
320
|
+
When the estimate includes execution-time ranges, the generation history records Web-compatible
|
|
321
|
+
median and maximum completion timestamps from the pre-submit time so Web can render the same expected
|
|
322
|
+
generation duration for a CLI-started Run.
|
|
314
323
|
Waiting for a terminal result is deliberately a separate operation. Generation is a non-undoable
|
|
315
324
|
Canvas History barrier. The CLI does not expose Assets, arbitrary Core Node creation, or 3D World
|
|
316
325
|
operations.
|
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.
|
|
38
|
+
npm publish ./tmp/az8-cli-release/everfir-az8-cli-0.2.0-preview.5.tgz --tag preview
|
|
39
39
|
npm view @everfir/az8-cli dist-tags versions --json
|
|
40
40
|
```
|
|
41
41
|
|
package/dist/main.js
CHANGED
|
@@ -4527,6 +4527,27 @@ var require_src2 = __commonJS({
|
|
|
4527
4527
|
}
|
|
4528
4528
|
});
|
|
4529
4529
|
|
|
4530
|
+
// src/canvas-awareness.ts
|
|
4531
|
+
var DEFAULT_CANVAS_CLIENT_NAME = "cli";
|
|
4532
|
+
function normalizeCanvasClientName(value) {
|
|
4533
|
+
const name = (value ?? DEFAULT_CANVAS_CLIENT_NAME).trim();
|
|
4534
|
+
if (!name) {
|
|
4535
|
+
throw invalidClientName("Canvas client name must not be empty.");
|
|
4536
|
+
}
|
|
4537
|
+
if (/[()]/.test(name)) {
|
|
4538
|
+
throw invalidClientName(
|
|
4539
|
+
"Canvas client name must not contain parentheses; AZ8 adds the required (name) suffix."
|
|
4540
|
+
);
|
|
4541
|
+
}
|
|
4542
|
+
return name;
|
|
4543
|
+
}
|
|
4544
|
+
function formatCanvasAwarenessName(actorDisplayName, clientName) {
|
|
4545
|
+
return `${actorDisplayName} (${normalizeCanvasClientName(clientName)})`;
|
|
4546
|
+
}
|
|
4547
|
+
function invalidClientName(message) {
|
|
4548
|
+
return Object.assign(new Error(message), { code: "invalid-client-name" });
|
|
4549
|
+
}
|
|
4550
|
+
|
|
4530
4551
|
// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/math.js
|
|
4531
4552
|
var floor = Math.floor;
|
|
4532
4553
|
var abs = Math.abs;
|
|
@@ -22727,9 +22748,26 @@ function mapWorkflowRunEstimate(value, definitionId) {
|
|
|
22727
22748
|
canAfford: value.can_afford,
|
|
22728
22749
|
definitionId: value.definition_id,
|
|
22729
22750
|
definitionVersion: value.definition_version,
|
|
22730
|
-
estimatedCost: value.estimated_cost
|
|
22751
|
+
estimatedCost: value.estimated_cost,
|
|
22752
|
+
executionTimeRanges: (value.execution_time_ranges ?? []).flatMap((item) => {
|
|
22753
|
+
const range = item.range;
|
|
22754
|
+
if (!range || !isNonNegativeFinite(range.minSeconds) || !isNonNegativeFinite(range.maxSeconds) || !isNonNegativeFinite(range.medianSeconds) || !isNonNegativeFinite(range.sampleCount)) {
|
|
22755
|
+
return [];
|
|
22756
|
+
}
|
|
22757
|
+
return [
|
|
22758
|
+
{
|
|
22759
|
+
maxSeconds: range.maxSeconds,
|
|
22760
|
+
medianSeconds: range.medianSeconds,
|
|
22761
|
+
minSeconds: range.minSeconds,
|
|
22762
|
+
sampleCount: range.sampleCount
|
|
22763
|
+
}
|
|
22764
|
+
];
|
|
22765
|
+
})
|
|
22731
22766
|
};
|
|
22732
22767
|
}
|
|
22768
|
+
function isNonNegativeFinite(value) {
|
|
22769
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
22770
|
+
}
|
|
22733
22771
|
function mapWorkflowDefinition(value) {
|
|
22734
22772
|
if (!value.id || !value.name || typeof value.version !== "number") {
|
|
22735
22773
|
throw new Error("Workflow Runtime returned an invalid Definition.");
|
|
@@ -22903,7 +22941,8 @@ var CanvasSession = class {
|
|
|
22903
22941
|
projectionRevision = 0;
|
|
22904
22942
|
actorId = null;
|
|
22905
22943
|
health;
|
|
22906
|
-
async connect(
|
|
22944
|
+
async connect(clientName, onState) {
|
|
22945
|
+
const normalizedClientName = normalizeCanvasClientName(clientName);
|
|
22907
22946
|
this.closeContext();
|
|
22908
22947
|
this.transition("authenticating", onState);
|
|
22909
22948
|
this.health.connectionAttempts += 1;
|
|
@@ -22927,7 +22966,10 @@ var CanvasSession = class {
|
|
|
22927
22966
|
});
|
|
22928
22967
|
this.document = document2;
|
|
22929
22968
|
try {
|
|
22930
|
-
document2.setIdentity({
|
|
22969
|
+
document2.setIdentity({
|
|
22970
|
+
accountId: actor.accountId,
|
|
22971
|
+
displayName: formatCanvasAwarenessName(actor.displayName, normalizedClientName)
|
|
22972
|
+
});
|
|
22931
22973
|
this.transition("hydrating", onState);
|
|
22932
22974
|
const foundationData = this.dependencies.foundationData ?? createAz8FoundationDataSystem(this.config);
|
|
22933
22975
|
const projectContent = this.dependencies.projectContent ?? createAz8ProjectContentSystem(this.config);
|
|
@@ -23037,8 +23079,7 @@ var CanvasSession = class {
|
|
|
23037
23079
|
}
|
|
23038
23080
|
publishAttentionBounds(bounds) {
|
|
23039
23081
|
this.requireDocument().setAttention({
|
|
23040
|
-
cursor: { x: bounds.x + bounds.width + 24, y: bounds.y + bounds.height / 2 }
|
|
23041
|
-
selection: bounds
|
|
23082
|
+
cursor: { x: bounds.x + bounds.width + 24, y: bounds.y + bounds.height / 2 }
|
|
23042
23083
|
});
|
|
23043
23084
|
}
|
|
23044
23085
|
closeContext() {
|
|
@@ -23379,18 +23420,20 @@ function requirePositiveInteger(value, field) {
|
|
|
23379
23420
|
|
|
23380
23421
|
// src/canvas-protocol-server.ts
|
|
23381
23422
|
var CanvasProtocolServer = class {
|
|
23382
|
-
constructor(config, projectId, output, session) {
|
|
23423
|
+
constructor(config, projectId, output, session, options = {}) {
|
|
23383
23424
|
this.projectId = projectId;
|
|
23384
23425
|
this.output = output;
|
|
23426
|
+
this.options = options;
|
|
23385
23427
|
this.client = new CanvasClient(config, projectId, session);
|
|
23386
23428
|
}
|
|
23387
23429
|
projectId;
|
|
23388
23430
|
output;
|
|
23431
|
+
options;
|
|
23389
23432
|
client;
|
|
23390
23433
|
initialized = false;
|
|
23391
23434
|
shuttingDown = false;
|
|
23392
23435
|
shutdownFinalized = false;
|
|
23393
|
-
|
|
23436
|
+
clientName = "cli";
|
|
23394
23437
|
observationPreset = "compact";
|
|
23395
23438
|
observationInclude = /* @__PURE__ */ new Set();
|
|
23396
23439
|
recordedRequests = /* @__PURE__ */ new Map();
|
|
@@ -23533,8 +23576,11 @@ var CanvasProtocolServer = class {
|
|
|
23533
23576
|
"initialize projectId does not match canvas open."
|
|
23534
23577
|
);
|
|
23535
23578
|
}
|
|
23579
|
+
const clientName = normalizeCanvasClientName(
|
|
23580
|
+
this.options.clientName ?? request.payload.client?.name
|
|
23581
|
+
);
|
|
23536
23582
|
this.initialized = true;
|
|
23537
|
-
this.
|
|
23583
|
+
this.clientName = clientName;
|
|
23538
23584
|
this.observationPreset = request.payload.observationPreset ?? "compact";
|
|
23539
23585
|
this.unsubscribeObservation = this.session.subscribe((observation) => {
|
|
23540
23586
|
const category = observation.kind === "workflow" ? "workflow" : "canvas";
|
|
@@ -23558,7 +23604,7 @@ var CanvasProtocolServer = class {
|
|
|
23558
23604
|
}
|
|
23559
23605
|
async connect(requestId) {
|
|
23560
23606
|
try {
|
|
23561
|
-
await this.client.connect(this.
|
|
23607
|
+
await this.client.connect(this.clientName, (state) => {
|
|
23562
23608
|
void this.output.emitMandatory({ payload: { state }, requestId, type: "lifecycle" });
|
|
23563
23609
|
});
|
|
23564
23610
|
} catch (error) {
|
|
@@ -23936,7 +23982,7 @@ async function runCanvasOneShot(config, command, dependencies = {}) {
|
|
|
23936
23982
|
try {
|
|
23937
23983
|
assertProcessIndependent(command);
|
|
23938
23984
|
client = dependencies.clientFactory?.(config, command.projectId) ?? new CanvasClient(config, command.projectId);
|
|
23939
|
-
await client.connect(command.clientName
|
|
23985
|
+
await client.connect(normalizeCanvasClientName(command.clientName));
|
|
23940
23986
|
if (command.kind === "query") {
|
|
23941
23987
|
return {
|
|
23942
23988
|
exitCode: 0,
|
|
@@ -24159,7 +24205,7 @@ async function runCanvasMediaDownload(config, command, dependencies = {}) {
|
|
|
24159
24205
|
try {
|
|
24160
24206
|
client = dependencies.mediaDownloadClientFactory?.(config, command.projectId) ?? new CanvasClient(config, command.projectId);
|
|
24161
24207
|
try {
|
|
24162
|
-
await client.connect(command.clientName
|
|
24208
|
+
await client.connect(normalizeCanvasClientName(command.clientName));
|
|
24163
24209
|
} catch {
|
|
24164
24210
|
throw new MediaDownloadError(
|
|
24165
24211
|
"canvas-connection-failed",
|
|
@@ -25029,7 +25075,7 @@ function projectHelpOutput() {
|
|
|
25029
25075
|
function canvasHelpOutput() {
|
|
25030
25076
|
return [
|
|
25031
25077
|
"Canvas:",
|
|
25032
|
-
" az8 canvas open <project-id> --write --format ndjson",
|
|
25078
|
+
" az8 canvas open <project-id> --write --format ndjson [--client-name <suffix>]",
|
|
25033
25079
|
" az8 canvas inspect <project-id> Print the latest persisted snapshot as JSON",
|
|
25034
25080
|
" az8 canvas upload <project-id> --file <path> --idempotency-key <key>",
|
|
25035
25081
|
" az8 canvas download <project-id> (--view-node-id <id> | --core-node-id <id>) --output <path>",
|
|
@@ -25042,7 +25088,7 @@ function canvasHelpOutput() {
|
|
|
25042
25088
|
" --input-json <json> Read one inline JSON object",
|
|
25043
25089
|
" --request-id <id> Set the Operation Receipt request ID",
|
|
25044
25090
|
" --timeout-ms <ms> Set the operation acknowledgement timeout",
|
|
25045
|
-
" --client-name <
|
|
25091
|
+
" --client-name <suffix> Set the parenthesized awareness client suffix",
|
|
25046
25092
|
"",
|
|
25047
25093
|
"One-shot query options:",
|
|
25048
25094
|
" --view-node-id <id> Select one View Node for canvas.detail",
|
|
@@ -25235,7 +25281,15 @@ async function runPersistentCanvas(args2) {
|
|
|
25235
25281
|
});
|
|
25236
25282
|
try {
|
|
25237
25283
|
const config = await resolveCliConfig(args2, {});
|
|
25238
|
-
|
|
25284
|
+
const requestedClientName = readOption3(args2, "--client-name");
|
|
25285
|
+
const clientName = requestedClientName ? normalizeCanvasClientName(requestedClientName) : void 0;
|
|
25286
|
+
server = new CanvasProtocolServer(
|
|
25287
|
+
config,
|
|
25288
|
+
projectId,
|
|
25289
|
+
output,
|
|
25290
|
+
void 0,
|
|
25291
|
+
clientName ? { clientName } : {}
|
|
25292
|
+
);
|
|
25239
25293
|
const shutdownOnSignal = (signal) => {
|
|
25240
25294
|
void server?.shutdownFromControl(signal.toLowerCase()).finally(() => process.stdin.destroy());
|
|
25241
25295
|
};
|
|
@@ -25252,7 +25306,10 @@ async function runPersistentCanvas(args2) {
|
|
|
25252
25306
|
}
|
|
25253
25307
|
function readOption3(args2, name) {
|
|
25254
25308
|
const index = args2.indexOf(name);
|
|
25255
|
-
|
|
25309
|
+
if (index < 0) return void 0;
|
|
25310
|
+
const value = args2[index + 1];
|
|
25311
|
+
if (!value || value.startsWith("--")) throw new Error(`${name} requires a value.`);
|
|
25312
|
+
return value;
|
|
25256
25313
|
}
|
|
25257
25314
|
function safeDiagnostic(error) {
|
|
25258
25315
|
const message = error instanceof Error ? error.message : "Persistent Canvas client failed.";
|
package/package.json
CHANGED
package/skills/az8-cli/SKILL.md
CHANGED
|
@@ -46,8 +46,10 @@ capabilities instead of guessing operation names or input shapes.
|
|
|
46
46
|
outcome, revisions, and optional usage. It is not Canvas History.
|
|
47
47
|
- **History** contains reversible local interactions. Only Operations advertised as `undoable`
|
|
48
48
|
participate. A generation start is a History barrier and is not undone by `undo`.
|
|
49
|
-
- **Awareness** is ephemeral presence, client
|
|
50
|
-
|
|
49
|
+
- **Awareness** is ephemeral presence, client suffix, and Attention Cursor information. The visible
|
|
50
|
+
name is always `<authenticated display name> (<client suffix>)`; the default suffix is `cli`.
|
|
51
|
+
CLI awareness does not publish selection bounds. Awareness never grants authority, changes
|
|
52
|
+
persisted authorship, or proves a business result.
|
|
51
53
|
- **Actor** is the authenticated account from `AZ8_TOKEN`. A client or awareness name cannot
|
|
52
54
|
impersonate another author.
|
|
53
55
|
|
|
@@ -131,6 +133,10 @@ and Operations, observe concurrent changes, and shut it down only after the Canv
|
|
|
131
133
|
az8 canvas open <project-id> --write --format ndjson
|
|
132
134
|
```
|
|
133
135
|
|
|
136
|
+
Use `--client-name <suffix>` only when a more specific CLI presence label helps collaborators. The
|
|
137
|
+
CLI owns the surrounding parentheses, rejects parentheses in the supplied suffix, and always keeps
|
|
138
|
+
the authenticated user display name first.
|
|
139
|
+
|
|
134
140
|
1. Continuously drain stdout; it is an ordered NDJSON protocol stream and may apply backpressure.
|
|
135
141
|
2. Read `hello`, select protocol `1.0`, then send `initialize` for the same Project ID.
|
|
136
142
|
3. Wait for `ready` before any query or Operation.
|
|
@@ -207,7 +213,9 @@ configuration option, modality, cost, or media compatibility from its display na
|
|
|
207
213
|
|
|
208
214
|
The start Receipt may report `usage.credits.status` as `estimated`, `not-consumed`, or `unknown`.
|
|
209
215
|
Estimated cost is informational, not final charged usage. There is no second confirmation. Never
|
|
210
|
-
claim actual credit consumption from an estimate.
|
|
216
|
+
claim actual credit consumption from an estimate. When timing data is available, `startGeneration`
|
|
217
|
+
also records the same median and maximum completion timestamps Web uses to display expected duration;
|
|
218
|
+
these timestamps remain estimates and do not change the Run's completion boundary.
|
|
211
219
|
|
|
212
220
|
## Media
|
|
213
221
|
|
|
@@ -285,8 +293,8 @@ Never:
|
|
|
285
293
|
or protocol payloads;
|
|
286
294
|
- inspect, print, or edit an operator-provisioned credential source merely to check whether it
|
|
287
295
|
exists; authenticate with a bounded read instead;
|
|
288
|
-
- use awareness client
|
|
289
|
-
authority;
|
|
296
|
+
- use awareness client suffixes to impersonate persisted authors, supply parentheses to obscure the
|
|
297
|
+
authenticated-name boundary, or treat Attention Cursor position as authority;
|
|
290
298
|
- use one-shot as if it retained History, Receipts, replay state, observations, or presence;
|
|
291
299
|
- attempt Asset membership, arbitrary Core Node creation, 3D World editing, unsupported
|
|
292
300
|
Decoration, alignment, or automatic layout through lower-level access;
|