@sanity/workflow-cli 0.29.0 → 0.31.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.
- package/CHANGELOG.md +41 -0
- package/README.md +1 -1
- package/dist/commands/workflows/definition/diff.js +2 -2
- package/dist/commands/workflows/deploy.d.ts +9 -6
- package/dist/commands/workflows/deploy.js +3 -4
- package/dist/lib/context.d.ts +2 -7
- package/dist/lib/context.js +1 -2
- package/dist/lib/env.d.ts +2 -3
- package/dist/lib/fail.d.ts +5 -12
- package/dist/lib/select-deployment.d.ts +6 -7
- package/dist/lib/select-deployment.js +9 -2
- package/dist/lib/share-definitions.d.ts +3 -19
- package/dist/lib/share-definitions.js +2 -2
- package/dist/lib/telemetry-setup.d.ts +2 -7
- package/dist/lib/telemetry.d.ts +2 -29
- package/dist/lib/telemetry.js +4 -4
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @sanity/workflow-cli
|
|
2
2
|
|
|
3
|
+
## 0.31.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [ff72ece]
|
|
8
|
+
- @sanity/workflow-engine@0.31.0
|
|
9
|
+
|
|
10
|
+
## 0.30.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- 90207dc: **BREAKING:** `assertReaderModelAcknowledgement` now requires `{requiredMinReaderModel, context?}` instead of a context string, and `ReaderModelAcknowledgementError` accepts its optional context through `{context}`. The Blueprint package's `AcknowledgedDeployment` type moves to the engine as `AcknowledgedWorkflowDeployment`; update imports and use that shared name. Assignment-valued fields can now declare a non-empty `roles` list that limits newly written assignees. Existing fields without `roles` stay unconstrained, retain reader floor 4, and continue deploying with `expectedMinReaderModel: 4`; installing this release requires no coordinated rollout or configuration change.
|
|
15
|
+
|
|
16
|
+
Before adding `roles`, upgrade every Studio, CLI, MCP server, Function, and other runtime that shares the affected workflow resource, then change that deployment's literal `expectedMinReaderModel` to `8`. MCP deployments pass the same reviewed literal as the optional `expectedMinReaderModel` tool argument. Definitions and instances carrying the facet require reader model 8. User assignees qualify through direct roles or the definition's role aliases, while collective role assignees must literally match one configured role. Studio assignment controls, including manual start, auto-start, and assignees nested in to-do rows, offer only eligible choices while retaining stale current values so editors can remove or replace them. Constrained pickers name the active eligible roles and distinguish an empty eligible set from a search with no matches. Top-level plural and composite edits retain no more occurrences of a stale assignment at each declared assignment location than the previous value contained; removal and reordering therefore work, while an added copy is a new assignment and must qualify. Direct singular replacements and every assignment present in an `updateWhere` fragment remain strict. Each engine verb uses one member-directory snapshot across retries, cascade hops, and spawned children, then the next verb reads current membership.
|
|
17
|
+
|
|
18
|
+
Malformed project-member and project-user directory responses now fail loudly instead of treating bad rows or role records as missing users, and actor resolution reports those failures as `inaccessible`, so integrations can distinguish directory failures from absent membership.
|
|
19
|
+
|
|
20
|
+
CLI `start` and `definition delete` no longer apply the definition-submission acknowledgement gate; deploy, check, dry-run, definition diff, Blueprint provision, and engine definition APIs still validate the selected definitions' required floor.
|
|
21
|
+
|
|
22
|
+
No reader-fleet rollout or deployment-literal change is required for existing definitions that do not use `roles`.
|
|
23
|
+
|
|
24
|
+
**Docs impact:** Update the assignment field reference and authoring examples for `roles`, distinguish eligibility from editability, action permission, and literal queue ownership, and add the model-8 conditional adoption sequence to the prerelease rollout guide.
|
|
25
|
+
|
|
26
|
+
- b0b1550: **BREAKING:** Product-prefixed telemetry events now use `Workflows <event>` instead of `Editorial Workflows <event>`; `EditorialWorkflowsResource` is replaced by `WorkflowsResource`; and `defineWorkflows` now generates `workflows-<deployment name>` resource names instead of `editorial-workflows-<deployment name>`. Telemetry consumers matching the previous literals stop receiving events until updated, TypeScript consumers importing the previous Blueprint interface no longer compile, and an existing Blueprint stack that relies on the generated name treats the new default as a different resource identity.
|
|
27
|
+
|
|
28
|
+
Update telemetry dashboards, schemas, alerts, and queries to match the `Workflows` prefix; event suffixes, payloads, and versions are unchanged. Replace Blueprint imports with `WorkflowsResource`. Before deploying an existing Blueprint stack, either pass its recorded resource name explicitly or plan the detach-and-create migration to the new default. Workflows request-tag families and billing classification are unchanged.
|
|
29
|
+
|
|
30
|
+
Other user-facing package copy now uses the Workflows product name. No upgrade action is required for consumers that do not match telemetry event names or use the Blueprint package.
|
|
31
|
+
|
|
32
|
+
**Docs impact:** Rename the product throughout the public documentation, move the docs section to `/docs/workflows/*` with permanent redirects from every `/docs/editorial-workflows/*` path, and document the telemetry-prefix, `WorkflowsResource`, and Blueprint resource-name migrations in the telemetry reference, Blueprint guide, and release notes.
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Updated dependencies [210ca63]
|
|
37
|
+
- Updated dependencies [a3a8dc0]
|
|
38
|
+
- Updated dependencies [a3a8dc0]
|
|
39
|
+
- Updated dependencies [a3a8dc0]
|
|
40
|
+
- Updated dependencies [90207dc]
|
|
41
|
+
- Updated dependencies [b0b1550]
|
|
42
|
+
- @sanity/workflow-engine@0.30.0
|
|
43
|
+
|
|
3
44
|
## 0.29.0
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -183,7 +183,7 @@ Invoke as `sanity-workflows <command>` (or `sanity workflows <command>` once the
|
|
|
183
183
|
## Telemetry
|
|
184
184
|
|
|
185
185
|
The CLI collects usage telemetry through Sanity's standard pipeline: a
|
|
186
|
-
per-command trace (`
|
|
186
|
+
per-command trace (`Workflows CLI Command Executed` — the command id, the
|
|
187
187
|
names of declared flags used, never their values, and a success flag) plus
|
|
188
188
|
the engine's adoption events from the operations it drives. Consent is the
|
|
189
189
|
account-wide status managed by `npx sanity telemetry enable|disable|status`;
|
|
@@ -6,7 +6,7 @@ import { resolveContext } from "../../../lib/context.js";
|
|
|
6
6
|
import { fetchDeployedDefinition, selectDefinitions, validateOrFail, } from "../../../lib/definitions.js";
|
|
7
7
|
import { diffReport } from "../../../lib/diff.js";
|
|
8
8
|
import { deploymentFlags } from "../../../lib/flags.js";
|
|
9
|
-
import { deploymentToTarget } from "../../../lib/select-deployment.js";
|
|
9
|
+
import { acknowledgeDeployment, deploymentToTarget } from "../../../lib/select-deployment.js";
|
|
10
10
|
export default class DefinitionDiff extends WorkflowCommand {
|
|
11
11
|
static description = 'Diff an in-code definition against the deployed version (latest by default).';
|
|
12
12
|
static examples = [
|
|
@@ -24,7 +24,7 @@ export default class DefinitionDiff extends WorkflowCommand {
|
|
|
24
24
|
const { args, flags } = await this.parse(DefinitionDiff);
|
|
25
25
|
const { deployment, client } = await resolveContext(flags);
|
|
26
26
|
const def = selectDefinitionToDiff(deployment.definitions, args.name);
|
|
27
|
-
const target = deploymentToTarget(deployment);
|
|
27
|
+
const target = deploymentToTarget(acknowledgeDeployment(deployment, [def]));
|
|
28
28
|
const spinner = ora(`Diffing ${args.name} against deployed…`).start();
|
|
29
29
|
let deployed;
|
|
30
30
|
try {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DeployDefinitionResult, type WorkflowConfig, type WorkflowDefinition, type WorkflowDeployment } from '@sanity/workflow-engine';
|
|
1
|
+
import { type AcknowledgedWorkflowDeployment, type DeployDefinitionResult, type WorkflowConfig, type WorkflowDefinition, type WorkflowDeployment } from '@sanity/workflow-engine';
|
|
2
2
|
import { WorkflowCommand } from '../../lib/base-command.ts';
|
|
3
3
|
import { type DeploymentSelectionOptions } from '../../lib/select-deployment.ts';
|
|
4
4
|
/** A deployment paired with the definitions selected + validated for it. */
|
|
@@ -6,6 +6,9 @@ interface DeployBatch {
|
|
|
6
6
|
deployment: WorkflowDeployment;
|
|
7
7
|
defs: WorkflowDefinition[];
|
|
8
8
|
}
|
|
9
|
+
interface AcknowledgedDeployBatch extends DeployBatch {
|
|
10
|
+
deployment: AcknowledgedWorkflowDeployment;
|
|
11
|
+
}
|
|
9
12
|
/** A deployment whose deploy/diff threw, kept for the closing summary. */
|
|
10
13
|
interface DeployFailure {
|
|
11
14
|
deployment: Pick<WorkflowDeployment, 'name' | 'tag'>;
|
|
@@ -41,7 +44,7 @@ export declare function validateModeFlags(check: boolean, dryRun: boolean): void
|
|
|
41
44
|
export declare function resolveBatches(config: WorkflowConfig, { only, selection }: {
|
|
42
45
|
only: string | undefined;
|
|
43
46
|
selection: DeploymentSelectionOptions;
|
|
44
|
-
}): Promise<
|
|
47
|
+
}): Promise<AcknowledgedDeployBatch[]>;
|
|
45
48
|
/**
|
|
46
49
|
* Select and validate every deployment's definitions up front. Validation runs
|
|
47
50
|
* before any network write ({@link validateOrFail} exits on a bad definition),
|
|
@@ -51,7 +54,7 @@ export declare function resolveBatches(config: WorkflowConfig, { only, selection
|
|
|
51
54
|
* multi-deployment run the failure names its deployment — it exits before any
|
|
52
55
|
* banner could attribute it.
|
|
53
56
|
*/
|
|
54
|
-
export declare function buildBatches(deployments: WorkflowDeployment[], only: string | undefined):
|
|
57
|
+
export declare function buildBatches(deployments: WorkflowDeployment[], only: string | undefined): AcknowledgedDeployBatch[];
|
|
55
58
|
/**
|
|
56
59
|
* Run `processBatch` over each batch, continuing past a failure so one bad
|
|
57
60
|
* deployment can't strand the rest — deployments are independent, and deploys
|
|
@@ -62,10 +65,10 @@ export declare function buildBatches(deployments: WorkflowDeployment[], only: st
|
|
|
62
65
|
* An auth rejection also rethrows regardless of batch count: a dead token is
|
|
63
66
|
* never batch-local, so continuing would just repeat the same failure.
|
|
64
67
|
*/
|
|
65
|
-
export declare function reconcileBatches({ batches, log, processBatch, }: {
|
|
66
|
-
batches:
|
|
68
|
+
export declare function reconcileBatches<T extends DeployBatch>({ batches, log, processBatch, }: {
|
|
69
|
+
batches: T[];
|
|
67
70
|
log: (line: string) => void;
|
|
68
|
-
processBatch: (batch:
|
|
71
|
+
processBatch: (batch: T) => Promise<void>;
|
|
69
72
|
}): Promise<DeployFailure[]>;
|
|
70
73
|
/**
|
|
71
74
|
* The closing summary for a multi-deployment run that had failures: the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
|
-
import {
|
|
3
|
+
import { computeDiffEntries, errorMessage, workflow, } from '@sanity/workflow-engine';
|
|
4
4
|
import logSymbols from 'log-symbols';
|
|
5
5
|
import ora from 'ora';
|
|
6
6
|
import { WorkflowCommand } from "../../lib/base-command.js";
|
|
@@ -10,7 +10,7 @@ import { diffReport } from "../../lib/diff.js";
|
|
|
10
10
|
import { fail, isAuthRejection } from "../../lib/fail.js";
|
|
11
11
|
import { deploymentFlags } from "../../lib/flags.js";
|
|
12
12
|
import { loadWorkflowConfig } from "../../lib/load-config.js";
|
|
13
|
-
import { deploymentLabel, deploymentToTarget, selectDeployments, } from "../../lib/select-deployment.js";
|
|
13
|
+
import { acknowledgeDeployment, deploymentLabel, deploymentToTarget, selectDeployments, } from "../../lib/select-deployment.js";
|
|
14
14
|
import { shareDefinitionsAfterDeploy } from "../../lib/share-definitions.js";
|
|
15
15
|
import { cliTelemetry } from "../../lib/telemetry.js";
|
|
16
16
|
import { groupBanner, resourceLabel } from "../../lib/ui.js";
|
|
@@ -160,11 +160,10 @@ export async function resolveBatches(config, { only, selection }) {
|
|
|
160
160
|
}
|
|
161
161
|
export function buildBatches(deployments, only) {
|
|
162
162
|
return deployments.map((deployment) => {
|
|
163
|
-
assertReaderModelAcknowledgement(deployment.expectedMinReaderModel, `Deployment ${deployment.name}`);
|
|
164
163
|
const context = deployments.length > 1 ? `${deploymentLabel(deployment)} — ` : '';
|
|
165
164
|
const defs = selectDefinitions(deployment.definitions, { only, context });
|
|
166
165
|
validateOrFail(defs, context);
|
|
167
|
-
return { deployment, defs };
|
|
166
|
+
return { deployment: acknowledgeDeployment(deployment, defs), defs };
|
|
168
167
|
});
|
|
169
168
|
}
|
|
170
169
|
export async function reconcileBatches({ batches, log, processBatch, }) {
|
package/dist/lib/context.d.ts
CHANGED
|
@@ -16,13 +16,8 @@ export interface InstanceContext {
|
|
|
16
16
|
* `currentStage`; nuke's instance mode reads the terminal state. */
|
|
17
17
|
instance: WorkflowInstance;
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
* delete`, `definition diff`): discover the config, pick the deployment for
|
|
22
|
-
* `--deployment` or `--tag` (or the sole one), assert that deployment's
|
|
23
|
-
* reader-floor acknowledgement, and build an authenticated client for its
|
|
24
|
-
* resource. Instance-id commands resolve elsewhere and do not gate here.
|
|
25
|
-
*/
|
|
19
|
+
/** Resolve the selected deployment. Deploy, definition-diff, and blueprint provision compare
|
|
20
|
+
* its acknowledgement with submitted definitions; selection alone must not assert a floor. */
|
|
26
21
|
export declare function resolveContext(flags: {
|
|
27
22
|
deployment?: string | undefined;
|
|
28
23
|
tag?: string | undefined;
|
package/dist/lib/context.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertReadableModel,
|
|
1
|
+
import { assertReadableModel, resourceGdr, } from '@sanity/workflow-engine';
|
|
2
2
|
import { clientFor, resolveTokenOrFail } from "./client.js";
|
|
3
3
|
import { fail } from "./fail.js";
|
|
4
4
|
import { loadWorkflowConfig } from "./load-config.js";
|
|
@@ -7,7 +7,6 @@ import { resourceLabel } from "./ui.js";
|
|
|
7
7
|
export async function resolveContext(flags) {
|
|
8
8
|
const config = await loadWorkflowConfig();
|
|
9
9
|
const deployment = await selectDeployment(config, { name: flags.deployment, tag: flags.tag });
|
|
10
|
-
assertReaderModelAcknowledgement(deployment.expectedMinReaderModel, `Deployment ${deployment.name}`);
|
|
11
10
|
return { deployment, client: clientFor(deployment.workflowResource, await resolveTokenOrFail()) };
|
|
12
11
|
}
|
|
13
12
|
function targetsFor(resources, token) {
|
package/dist/lib/env.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export declare const ENV: {
|
|
|
2
2
|
readonly SANITY_AUTH_TOKEN: "SANITY_AUTH_TOKEN";
|
|
3
3
|
readonly SANITY_API_HOST: "SANITY_API_HOST";
|
|
4
4
|
};
|
|
5
|
-
/** The explicit env token, or undefined when unset/blank.
|
|
6
|
-
*
|
|
7
|
-
* recovery hint must never disagree on it. */
|
|
5
|
+
/** The explicit env token, or undefined when unset/blank. Token resolution
|
|
6
|
+
* and the auth recovery hint must agree on this. */
|
|
8
7
|
export declare function envAuthToken(): string | undefined;
|
package/dist/lib/fail.d.ts
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Render a user-facing error
|
|
3
|
-
*
|
|
4
|
-
* (validation, missing input, conflicting flags) read clean.
|
|
2
|
+
* Render a user-facing error to stderr with no oclif framing or Node stack,
|
|
3
|
+
* and exit non-zero.
|
|
5
4
|
*
|
|
6
|
-
* Exits
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* oclif's handler exits 1 without printing anything further. A raw
|
|
10
|
-
* `process.exit` here would silently drop the trace and every batched
|
|
11
|
-
* event (including already-logged events from earlier in the command).
|
|
12
|
-
*
|
|
13
|
-
* For unexpected failures (network, engine throw) prefer letting the
|
|
14
|
-
* error propagate so the stack is visible for debugging.
|
|
5
|
+
* Exits via oclif's `Errors.exit`, never `process.exit`: a raw `process.exit`
|
|
6
|
+
* would skip the command's `finally` hook, dropping the trace and any
|
|
7
|
+
* batched telemetry that hasn't flushed yet.
|
|
15
8
|
*/
|
|
16
9
|
export declare function fail(headline: string, detail?: string): never;
|
|
17
10
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DeployTarget, type WorkflowConfig, type WorkflowDeployment } from '@sanity/workflow-engine';
|
|
1
|
+
import { type AcknowledgedWorkflowDeployment, type DeployTarget, type WorkflowConfig, type WorkflowDefinition, type WorkflowDeployment } from '@sanity/workflow-engine';
|
|
2
2
|
export type ChooseDeploymentName = (deployments: WorkflowDeployment[]) => Promise<string>;
|
|
3
3
|
export interface DeploymentSelectionOptions {
|
|
4
4
|
name: string | undefined;
|
|
@@ -33,11 +33,8 @@ export declare function selectDeployment(config: WorkflowConfig, { name, tag, or
|
|
|
33
33
|
interactive?: boolean | undefined;
|
|
34
34
|
chooseName?: ChooseDeploymentName | undefined;
|
|
35
35
|
}): Promise<WorkflowDeployment>;
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* shared resolution for the callers that accept a whole tag group (deploy's
|
|
39
|
-
* tag-as-environment run, the read paths' resource narrowing).
|
|
40
|
-
*/
|
|
36
|
+
/** Every deployment carrying `tag`, failing when the tag matches none — the
|
|
37
|
+
* shared resolution for callers that accept a whole tag group. */
|
|
41
38
|
export declare function deploymentsForTag(config: WorkflowConfig, tag: string): WorkflowDeployment[];
|
|
42
39
|
/**
|
|
43
40
|
* The deployments a `deploy` run acts on: every one with `--all-tags`, one
|
|
@@ -48,9 +45,11 @@ export declare function deploymentsForTag(config: WorkflowConfig, tag: string):
|
|
|
48
45
|
* explicit opt-in — never a default.
|
|
49
46
|
*/
|
|
50
47
|
export declare function selectDeployments(config: WorkflowConfig, { name, tag, allTags, interactive, chooseName }: DeploymentSelectionOptions): Promise<WorkflowDeployment[]>;
|
|
48
|
+
/** The shared acknowledgement boundary for the CLI's definition-submission paths. */
|
|
49
|
+
export declare function acknowledgeDeployment(deployment: WorkflowDeployment, definitions: readonly WorkflowDefinition[]): AcknowledgedWorkflowDeployment;
|
|
51
50
|
/**
|
|
52
51
|
* Project a deployment into the engine's {@link DeployTarget} — the shape the
|
|
53
52
|
* deploy/diff verbs (`deployDefinitions`, `computeDiffEntries`, `diffEntry`)
|
|
54
53
|
* consume — expanding its handle bindings into the alias map in the same step.
|
|
55
54
|
*/
|
|
56
|
-
export declare function deploymentToTarget(deployment:
|
|
55
|
+
export declare function deploymentToTarget(deployment: AcknowledgedWorkflowDeployment): DeployTarget;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertReaderModelAcknowledgement, resourceAliasesToMap, } from '@sanity/workflow-engine';
|
|
1
|
+
import { assertReaderModelAcknowledgement, requiredDefinitionReaderModel, resourceAliasesToMap, } from '@sanity/workflow-engine';
|
|
2
2
|
import { fail } from "./fail.js";
|
|
3
3
|
import { canPromptOnStderr, selectOnStderr } from "./prompt.js";
|
|
4
4
|
export function deploymentLabel({ name, tag }) {
|
|
@@ -69,8 +69,15 @@ async function chooseDeploymentName(deployments) {
|
|
|
69
69
|
function availableDeployments(config, deployments = config.deployments) {
|
|
70
70
|
return `Available deployments: ${deployments.map(deploymentLabel).join(', ')}`;
|
|
71
71
|
}
|
|
72
|
+
export function acknowledgeDeployment(deployment, definitions) {
|
|
73
|
+
const expectedMinReaderModel = deployment.expectedMinReaderModel;
|
|
74
|
+
assertReaderModelAcknowledgement(expectedMinReaderModel, {
|
|
75
|
+
context: `Deployment ${deployment.name}`,
|
|
76
|
+
requiredMinReaderModel: requiredDefinitionReaderModel(definitions),
|
|
77
|
+
});
|
|
78
|
+
return { ...deployment, expectedMinReaderModel };
|
|
79
|
+
}
|
|
72
80
|
export function deploymentToTarget(deployment) {
|
|
73
|
-
assertReaderModelAcknowledgement(deployment.expectedMinReaderModel, `Deployment ${deployment.name}`);
|
|
74
81
|
return {
|
|
75
82
|
expectedMinReaderModel: deployment.expectedMinReaderModel,
|
|
76
83
|
tag: deployment.tag,
|
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* CONTENT sharing, not telemetry: definitions carry customer-authored
|
|
4
|
-
* strings (names, titles, GROQ filters) that the telemetry payload policy
|
|
5
|
-
* bans, so the documents go to Sanity's first-party definition-feedback
|
|
6
|
-
* endpoint — one POST per deploy invocation — and telemetry carries only a
|
|
7
|
-
* content-free marker per shared definition plus a per-invocation decision
|
|
8
|
-
* event.
|
|
9
|
-
*
|
|
10
|
-
* Consent model: opt-OUT. A deploy that creates new definition versions
|
|
11
|
-
* donates by default. The choice is skipped by an explicit flag:
|
|
12
|
-
* `--share-defs` (donate, no prompt) or `--no-share-defs` (don't). Without a
|
|
13
|
-
* flag, the CLI shares. An interactive terminal gets a ONE-TIME notice
|
|
14
|
-
* (persisted in the shared Sanity user config) before the first donation;
|
|
15
|
-
* every later flagless deploy, and every unattended deploy, prints a concise
|
|
16
|
-
* reminder. CI, `DO_NOT_TRACK`, and non-TTY execution do not change the
|
|
17
|
-
* content-sharing default. Only `--no-share-defs` opts out.
|
|
18
|
-
*/
|
|
1
|
+
/** Consent model: opt-OUT. Sharing new definition versions defaults on; only
|
|
2
|
+
* --no-share-defs turns it off — CI, DO_NOT_TRACK, and non-TTY don't change that. */
|
|
19
3
|
import { type DeployDefinitionResult, type DeployedDefinition, type WorkflowResource } from '@sanity/workflow-engine';
|
|
20
4
|
import type { UserConfigStore } from './telemetry-setup.ts';
|
|
21
5
|
import { type WorkflowDefinitionSharedData } from './telemetry.ts';
|
|
@@ -66,7 +50,7 @@ export declare const SHARE_REMINDER: string;
|
|
|
66
50
|
/**
|
|
67
51
|
* The content-free telemetry marker for one shared definition — projected
|
|
68
52
|
* from the engine's own deploy-event derivation ({@link definitionDeployedData})
|
|
69
|
-
* so `
|
|
53
|
+
* so `Workflows Definition Shared` and `Workflows Definition Deployed` can
|
|
70
54
|
* never disagree about one definition's structure. Status is dropped:
|
|
71
55
|
* only newly created versions are ever shared.
|
|
72
56
|
*/
|
|
@@ -8,13 +8,13 @@ import { cliTelemetry, WorkflowDefinitionShared, WorkflowDefinitionSharingDecide
|
|
|
8
8
|
export const SHARE_ENDPOINT_URI = '/workflow/definition-feedback';
|
|
9
9
|
const SHARE_TAG = 'definition.share';
|
|
10
10
|
const SHARE_DECISION_KEY = 'workflowCliDefinitionSharing';
|
|
11
|
-
export const SHARE_FIRST_RUN_NOTICE = `${styleText('bold', 'Sharing new workflow definitions with Sanity')} to improve
|
|
11
|
+
export const SHARE_FIRST_RUN_NOTICE = `${styleText('bold', 'Sharing new workflow definitions with Sanity')} to improve Workflows.\n` +
|
|
12
12
|
'They are sent verbatim (structure, names, filters, effect configuration,\n' +
|
|
13
13
|
'seeded values) with their deployment coordinates, and kept — never your\n' +
|
|
14
14
|
'content documents, workflow instances, or Sanity auth token. This notice is\n' +
|
|
15
15
|
`shown once on this machine; opt out of any run with ${styleText('cyan', '--no-share-defs')}.\n`;
|
|
16
16
|
export const SHARE_REMINDER = `${styleText('bold', 'Definition sharing: ON (default)')}\n` +
|
|
17
|
-
'New workflow definition versions are being shared with Sanity to improve
|
|
17
|
+
'New workflow definition versions are being shared with Sanity to improve Workflows.\n' +
|
|
18
18
|
'Examples:\n' +
|
|
19
19
|
` ${styleText('dim', '$')} sanity-workflows deploy ${styleText('dim', '# share by default')}\n` +
|
|
20
20
|
` ${styleText('dim', '$')} sanity-workflows deploy ${styleText('cyan', '--share-defs')} ${styleText('dim', '# share explicitly; hide this warning')}\n` +
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* hook's whole job. Discovery is deliberately soft: telemetry must never
|
|
4
|
-
* break (or exit) a command, so a missing/broken config, missing token,
|
|
5
|
-
* or dataset-less config just leaves the invocation with telemetry off;
|
|
6
|
-
* the command itself surfaces those problems where they matter.
|
|
7
|
-
*/
|
|
1
|
+
/** Discovery is deliberately soft: telemetry must never break or exit a
|
|
2
|
+
* command — a missing/broken config, token, or dataset just leaves it off. */
|
|
8
3
|
import { processShellUserProperties, type TelemetryIntakeClient, type WorkflowResource } from '@sanity/workflow-engine';
|
|
9
4
|
/** The get/set slice of the shared Sanity user config (cli-core's
|
|
10
5
|
* `getUserConfig`) the shell persists flags into — narrow so tests fake
|
package/dist/lib/telemetry.d.ts
CHANGED
|
@@ -1,32 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* shell — no host to ride — so this module owns the store, the standard
|
|
4
|
-
* Sanity-intake consent/transport recipe (shared via
|
|
5
|
-
* `@sanity/workflow-engine`'s `createTelemetryIntake`), and the one-time
|
|
6
|
-
* disclosure. The `prerun` hook assembles it once per invocation and the
|
|
7
|
-
* `finally` hook completes the command trace and flushes.
|
|
8
|
-
*
|
|
9
|
-
* Consent recipe: CI / `DO_NOT_TRACK` → denied; not logged in → no store
|
|
10
|
-
* (undetermined, nothing sent); otherwise the account-level status the
|
|
11
|
-
* intake recipe fetches. Consent is managed account-wide by
|
|
12
|
-
* `sanity telemetry enable|disable|status` — the CLI inherits it and
|
|
13
|
-
* ships no consent UX of its own.
|
|
14
|
-
*
|
|
15
|
-
* Provided-implementation caveat: a `telemetry` logger on the workflow
|
|
16
|
-
* config replaces this shell wholesale — the built-in store is never
|
|
17
|
-
* constructed and none of its policy (consent, environment suppression,
|
|
18
|
-
* transport) applies; every event flows to the provided logger
|
|
19
|
-
* unconditionally. Gates live in the store, not at emission sites.
|
|
20
|
-
*
|
|
21
|
-
* Payload policy: no customer strings, ever. The command trace carries
|
|
22
|
-
* the command id, the NAMES of declared flags used, and a success flag —
|
|
23
|
-
* never flag values, arguments, or error text. `Editorial Workflows
|
|
24
|
-
* Definition Shared` is a content-free marker (hash + structural counts); the shared
|
|
25
|
-
* document itself rides the first-party feedback endpoint, never
|
|
26
|
-
* telemetry (see `share-definitions.ts`). `Editorial Workflows Definition
|
|
27
|
-
* Sharing Decided` records the per-invocation sharing decision (default /
|
|
28
|
-
* opt-in / opt-out and whether anything was donated) — also content-free.
|
|
29
|
-
*/
|
|
1
|
+
/** Payload policy: no customer strings, ever — flag NAMES only (never values,
|
|
2
|
+
* arguments, or error text); shared-definition events are content-free markers. */
|
|
30
3
|
import { type DefinedTelemetryTrace, type TelemetryStore } from '@sanity/telemetry';
|
|
31
4
|
import { type TelemetryIntakeClient, type WorkflowDefinitionDeployedData, type WorkflowTelemetryLogger } from '@sanity/workflow-engine';
|
|
32
5
|
export interface WorkflowCliCommandData {
|
package/dist/lib/telemetry.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { createBatchedStore, createSessionId, defineEvent, defineTrace, } from '@sanity/telemetry';
|
|
2
2
|
import { createTelemetryIntake, isTelemetryEnvDenied, noopTelemetry, } from '@sanity/workflow-engine';
|
|
3
3
|
export const WorkflowCliCommandExecuted = defineTrace({
|
|
4
|
-
name: '
|
|
4
|
+
name: 'Workflows CLI Command Executed',
|
|
5
5
|
version: 1,
|
|
6
6
|
description: 'A workflow CLI command was executed — payload is the command id, the names of declared flags used (never their values), and a success flag',
|
|
7
7
|
});
|
|
8
8
|
export const WorkflowDefinitionShared = defineEvent({
|
|
9
|
-
name: '
|
|
9
|
+
name: 'Workflows Definition Shared',
|
|
10
10
|
version: 1,
|
|
11
|
-
description: 'A newly created workflow definition version was donated to Sanity. Content-free marker: the content hash plus the same structural counts
|
|
11
|
+
description: 'A newly created workflow definition version was donated to Sanity. Content-free marker: the content hash plus the same structural counts Workflows Definition Deployed carries — the document itself goes to the first-party definition-feedback endpoint, never through telemetry.',
|
|
12
12
|
});
|
|
13
13
|
export const WorkflowDefinitionSharingDecided = defineEvent({
|
|
14
|
-
name: '
|
|
14
|
+
name: 'Workflows Definition Sharing Decided',
|
|
15
15
|
version: 2,
|
|
16
16
|
description: 'One per deploy invocation that created new definition versions: whether donation followed the default or an explicit flag, whether anything reached the endpoint, and how many versions were eligible. Content-free — measures the true opt-out rate without ever carrying the document.',
|
|
17
17
|
});
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workflow-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "Command-line tool for deploying, inspecting, and administering Sanity workflow definitions and instances.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -62,12 +62,12 @@
|
|
|
62
62
|
"@types/node": "^24.12.4",
|
|
63
63
|
"oclif": "^4.23.16",
|
|
64
64
|
"vitest": "^4.1.8",
|
|
65
|
-
"@sanity/workflow-engine": "0.
|
|
66
|
-
"@sanity/workflow-engine-test": "0.
|
|
67
|
-
"@sanity/workflow-examples": "0.
|
|
65
|
+
"@sanity/workflow-engine": "0.31.0",
|
|
66
|
+
"@sanity/workflow-engine-test": "0.31.0",
|
|
67
|
+
"@sanity/workflow-examples": "0.11.1"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@sanity/workflow-engine": "0.
|
|
70
|
+
"@sanity/workflow-engine": "0.31.0"
|
|
71
71
|
},
|
|
72
72
|
"oclif": {
|
|
73
73
|
"bin": "sanity-workflows",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"topicSeparator": " ",
|
|
85
85
|
"topics": {
|
|
86
86
|
"workflows": {
|
|
87
|
-
"description": "Deploy, inspect, and administer
|
|
87
|
+
"description": "Deploy, inspect, and administer Workflows definitions and instances",
|
|
88
88
|
"subtopics": {
|
|
89
89
|
"definition": {
|
|
90
90
|
"description": "Read and manage workflow definitions"
|