@sanity/workflow-cli 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +40 -39
  3. package/bin/run.js +3 -1
  4. package/dist/command-ids.d.ts +10 -0
  5. package/dist/command-ids.js +10 -0
  6. package/dist/commands/{editorial-workflows → workflows}/abort.d.ts +0 -1
  7. package/dist/commands/{editorial-workflows → workflows}/abort.js +2 -3
  8. package/dist/commands/{editorial-workflows → workflows}/definition/delete.d.ts +0 -1
  9. package/dist/commands/{editorial-workflows → workflows}/definition/delete.js +3 -4
  10. package/dist/commands/{editorial-workflows → workflows}/definition/diff.d.ts +0 -1
  11. package/dist/commands/{editorial-workflows → workflows}/definition/diff.js +2 -3
  12. package/dist/commands/{editorial-workflows → workflows}/definition/list.d.ts +0 -1
  13. package/dist/commands/{editorial-workflows → workflows}/definition/list.js +3 -4
  14. package/dist/commands/{editorial-workflows → workflows}/definition/show.d.ts +0 -1
  15. package/dist/commands/{editorial-workflows → workflows}/definition/show.js +0 -1
  16. package/dist/commands/{editorial-workflows → workflows}/deploy.d.ts +4 -3
  17. package/dist/commands/{editorial-workflows → workflows}/deploy.js +15 -9
  18. package/dist/commands/{editorial-workflows → workflows}/diagnose.d.ts +0 -1
  19. package/dist/commands/{editorial-workflows → workflows}/diagnose.js +3 -4
  20. package/dist/commands/{editorial-workflows → workflows}/fire-action.d.ts +0 -1
  21. package/dist/commands/{editorial-workflows → workflows}/fire-action.js +3 -4
  22. package/dist/commands/{editorial-workflows → workflows}/list.d.ts +0 -1
  23. package/dist/commands/{editorial-workflows → workflows}/list.js +6 -7
  24. package/dist/commands/{editorial-workflows → workflows}/nuke.d.ts +0 -1
  25. package/dist/commands/{editorial-workflows → workflows}/nuke.js +3 -4
  26. package/dist/commands/{editorial-workflows → workflows}/reset-activity.d.ts +0 -1
  27. package/dist/commands/{editorial-workflows → workflows}/reset-activity.js +2 -3
  28. package/dist/commands/{editorial-workflows → workflows}/set-stage.d.ts +0 -1
  29. package/dist/commands/{editorial-workflows → workflows}/set-stage.js +3 -4
  30. package/dist/commands/{editorial-workflows → workflows}/show.d.ts +0 -1
  31. package/dist/commands/{editorial-workflows → workflows}/show.js +3 -4
  32. package/dist/commands/{editorial-workflows → workflows}/start.d.ts +0 -1
  33. package/dist/commands/{editorial-workflows → workflows}/start.js +4 -5
  34. package/dist/commands/{editorial-workflows → workflows}/tail.d.ts +0 -1
  35. package/dist/commands/{editorial-workflows → workflows}/tail.js +1 -2
  36. package/dist/help.d.ts +9 -4
  37. package/dist/help.js +35 -8
  38. package/dist/hooks/finally/telemetry.d.ts +2 -1
  39. package/dist/hooks/prerun/telemetry.d.ts +2 -1
  40. package/dist/hooks/prerun/telemetry.js +7 -0
  41. package/dist/lib/base-command.d.ts +3 -3
  42. package/dist/lib/base-command.js +4 -0
  43. package/dist/lib/context.d.ts +5 -4
  44. package/dist/lib/context.js +2 -1
  45. package/dist/lib/select-deployment.js +2 -1
  46. package/dist/lib/share-definitions.js +2 -1
  47. package/dist/lib/telemetry.d.ts +1 -3
  48. package/dist/standalone-argv.d.ts +14 -0
  49. package/dist/standalone-argv.js +54 -0
  50. package/oclif.manifest.json +105 -135
  51. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,64 @@
1
1
  # @sanity/workflow-cli
2
2
 
3
+ ## 0.29.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 8bb6a85: The workflow CLI README lists commands with operator-facing descriptions instead of implementation status.
8
+
9
+ **No upgrade action required.** Command behavior is unchanged.
10
+
11
+ **Docs impact:** `packages/workflow-cli` README — the former Command status table is now Command list.
12
+
13
+ - 772876b: When this package is mounted inside the official `sanity` CLI, its telemetry prerun hook no longer installs a store for host commands outside the `workflows` topic (the finally hook already no-ops when telemetry was never installed). Previously every `sanity` command in a directory with a `sanity.workflow.ts` could load workflow config, show the workflow-cli disclosure, and emit an `Editorial Workflows CLI Command Executed` event for unrelated commands such as `sanity dataset list`. Standalone `sanity-workflows` behaviour is unchanged.
14
+
15
+ **No upgrade action required** for standalone users. Hosts that already mount this package as an oclif plugin pick up the safer hook scope on upgrade — no config change.
16
+
17
+ **Docs impact:** None — host-mount telemetry scoping only; documented invoke paths are unchanged.
18
+
19
+ - 772876b: The `workflows` topic help description no longer uses an em dash. It now reads "Deploy, inspect, and administer Editorial Workflows definitions and instances", matching the plain phrasing of other product CLI topics.
20
+
21
+ **No upgrade action required.**
22
+
23
+ **Docs impact:** None — help copy only; documented invoke paths are unchanged.
24
+
25
+ - Updated dependencies [f44fc33]
26
+ - Updated dependencies [26f25e0]
27
+ - Updated dependencies [25bd1fb]
28
+ - Updated dependencies [3fd04f1]
29
+ - @sanity/workflow-engine@0.29.0
30
+
31
+ ## 0.28.0
32
+
33
+ ### Minor Changes
34
+
35
+ - 5050b06: **BREAKING:** Authoring a deployment now types through `WorkflowDeploymentInput` / `WorkflowConfigInput`, which require `expectedMinReaderModel` as the current reader-floor literal. Passing a parsed `WorkflowDeployment` / `WorkflowConfig` (where the floor is optional/unverified) into `defineWorkflowConfig` or `defineWorkflows` is a type error — share the authored deployment object instead of `config.deployments[n]`. The same pin shows up on the blueprint resource: `EditorialWorkflowsResource.deployment` and `parseWorkflowDeployment`'s return type are now `AcknowledgedDeployment` (floor asserted to the current literal), so a hand-constructed provider resource must carry that literal too.
36
+
37
+ At runtime, config parse no longer rejects a stale or missing floor on an untargeted deployment. Only deployment-scoped commands assert, and only the selected deployment: definition deploy, `--check` / `--dry-run`, blueprint provision, `start`, `definition delete`, and `definition diff` (the last is a deployment-scoped read). Instance-id commands (`fire-action`, `abort`, `set-stage`, `reset-activity`) deliberately do not assert — they resolve by instance id, not by a declared deployment's acknowledgement — so an unacknowledged floor does not stop those instance commits.
38
+
39
+ Upgrade TypeScript configs and blueprint manifests that fed a parsed deployment into those helpers: keep a shared authored object (`satisfies WorkflowDeploymentInput`) for both `defineWorkflowConfig` and `defineWorkflows`, and give any hand-built `EditorialWorkflowsResource` the current floor literal on `deployment`. Existing configs that already acknowledge the current floor keep working at runtime; a stale selected deployment still fails with `ReaderModelAcknowledgementError` (headline + short steps; the CLI renders it through the clean styled-error path).
40
+
41
+ **Docs impact:** Update the CLI / blueprint authoring examples and the prerelease reader-floor guidance so they name `WorkflowConfigInput` / `WorkflowDeploymentInput` / `AcknowledgedDeployment`, forbid passing `config.deployments[n]` into `defineWorkflows`, state that instance-id writes are outside the acknowledgement gate, and stop implying whole-config parse-time rejection for commands that never select a deployment.
42
+
43
+ - cc50d58: **BREAKING:** Canonical oclif command ids move from the `editorial-workflows` topic to `workflows`. A future host mount therefore surfaces `sanity workflows deploy` (and the same shape for every other command) instead of `sanity editorial-workflows …`. Standalone short forms (`sanity-workflows deploy`, `definition list`, …) are unchanged — the bin still rewrites them onto the topic before resolution.
44
+
45
+ Anyone invoking the previous topic-scoped ids (`sanity-workflows editorial-workflows deploy`, or a host/plugin that hard-coded those ids) must switch to `workflows …`. Continuing to call `editorial-workflows …` fails with command-not-found.
46
+
47
+ **Docs impact:** When the host mount ships, update Editorial Workflows CLI getting-started and invocation docs so the documented host path is `sanity workflows …`, and refresh any topic-scoped examples that still say `editorial-workflows`. Until then the standalone short forms remain the documented surface.
48
+
49
+ ### Patch Changes
50
+
51
+ - 4403e66: Short command forms (`deploy`, `definition list`, …) are no longer registered as oclif root aliases. The standalone `sanity-workflows` binary still accepts those forms by rewriting argv onto the `workflows` topic before command resolution, so day-to-day usage is unchanged. Removing the aliases makes the package safe to mount inside the official `sanity` CLI without colliding with host commands such as `sanity deploy`.
52
+
53
+ **No upgrade action required** for standalone `sanity-workflows` / `npx @sanity/workflow-cli` users. Anyone who embedded this package as an oclif plugin and relied on the root aliases must invoke the topic-scoped ids (`workflows deploy`, …) or perform equivalent argv rewriting in the host.
54
+
55
+ **Docs impact:** Update Editorial Workflows CLI getting-started and invocation docs when the host mount ships so the primary path is `sanity workflows …`; until then the standalone short forms remain the documented surface in this package README.
56
+
57
+ - Updated dependencies [1e4a5da]
58
+ - Updated dependencies [5050b06]
59
+ - Updated dependencies [a044ba5]
60
+ - @sanity/workflow-engine@0.28.0
61
+
3
62
  ## 0.27.0
4
63
 
5
64
  ### Patch Changes
package/README.md CHANGED
@@ -21,17 +21,16 @@ pnpm --filter @sanity/workflow-cli dev show wf-instance.abc123
21
21
  ```
22
22
 
23
23
  The package is an [oclif](https://oclif.io) plugin: every command's canonical
24
- id nests under the `editorial-workflows` topic
25
- (`sanity-workflows editorial-workflows deploy`), so mounting the package into
24
+ id nests under the `workflows` topic
25
+ (`sanity-workflows workflows deploy`), so mounting the package into
26
26
  the `sanity` CLI's plugin list surfaces the same commands as
27
- `sanity editorial-workflows …` without its canonical ids colliding with the
28
- host's own commands (the sanity CLI already has a `deploy`). The bare forms
29
- used throughout this README (`deploy`, `definition list`, …) are aliases of
30
- the nested ids and are the standalone binary's stable surface. oclif registers
31
- plugin aliases in a host unconditionally (an id collision resolves by plugin
32
- priority, host first), so a host mount would also surface these bare aliases
33
- at its root trimming or hiding them for the mounted context is part of the
34
- host-side mount work, not something a host can configure away.
27
+ `sanity workflows …` without colliding with the host's own root
28
+ commands (the sanity CLI already has a `deploy`). The short forms used
29
+ throughout this README (`deploy`, `definition list`, …) are the standalone
30
+ binary's stable surface its production and development entrypoints
31
+ (`bin/run.js` and `bin/dev.js`) rewrite them onto the topic before oclif
32
+ resolves the command. Those short forms are **not** registered as oclif aliases,
33
+ so a host mount does not pollute the host root.
35
34
 
36
35
  Authenticate once with `sanity login` (the CLI reads that session token); for
37
36
  CI, set `SANITY_AUTH_TOKEN` instead. Then create a `sanity.workflow.ts` in the
@@ -154,30 +153,32 @@ stale compiled output.
154
153
  > `--dry-run` and `--only` don't collide with pnpm flags and work
155
154
  > through the normal `pnpm --filter … dev …` invocation.
156
155
 
157
- ## Command status
158
-
159
- | Command | Status |
160
- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
161
- | `deploy` | wired — calls `workflow.deployDefinitions` over the selected deployment's definitions |
162
- | `deploy --all-tags` | wired — deploys every deployment in the config, continuing past per-deployment failures |
163
- | `deploy --check` | wired runs `validateDefinition` over the local batch + a duplicate-name check |
164
- | `deploy --dry-run` | wired fetches existing docs and renders a coloured JSON diff per change |
165
- | `deploy --only <name>` | wired filters deploy/check/dry-run to one definition by `name` |
166
- | `start <name>` | wired calls `workflow.startInstance` (`--field` for input fields) |
167
- | `list` | wired `client.fetch` over `sanity.workflow.instance` documents (`--definition <name>` to filter) |
168
- | `show <instance-id>` | wired `client.getDocument` |
169
- | `diagnose <instance-id>` | wired calls `workflow.diagnose`, classifies why the instance is/isn't progressing |
170
- | `tail <instance-id>` | wired `client.listen()` over the instance, prints new history entries |
171
- | `abort <instance-id>` | wired calls `workflow.abortInstance` (hard stop: cancels pending effects, removes guards) |
172
- | `set-stage <instance-id> --to <stage>` | wired calls `workflow.setStage` (admin override: skips declared transitions/filters; enter lifecycle + cascade still run) |
173
- | `reset-activity <instance-id> <activity>` | wired calls `workflow.resetActivity` (recovery override: reset a failed activity to `active`, or `--skip` to bypass it; then cascade) |
174
- | `fire-action <instance-id>` | wired `workflow.availableActions` lists actions; `workflow.fireAction` fires one |
175
- | `definition list` | wired `client.fetch` over `sanity.workflow.definition` documents |
176
- | `definition show <name>` | wired `client.fetch`, latest version unless `--version` |
177
- | `definition diff <name>` | wired — diffs the in-code definition against the deployed latest (`--version` to pin) |
178
- | `definition delete <name>` | wired calls `workflow.deleteDefinition` (refuses on live instances unless `--cascade`) |
179
- | `nuke --deployment <name>` / `nuke --tag <tag>` | wired — dev-period reset (exists only until the versioned upgrade framework): deletes every engine-owned doc for the deployment's tag (instances, definitions, guards across resources); exactly one of these two selectors required; refuses while another same-tag deployment sweeps an overlapping resource (guard ids embed only the tag); plan + typed confirm |
180
- | `nuke --instance <id>` | wired dev-period reset, same fence as the tag mode above: deletes ONE terminal instance plus the guards it owns, swept across every alias-bound resource (matched by `sourceInstanceId`, with an id-prefix leg as redundant cover; matching provenance rather than the live instance set is what catches a partial-delete orphan); definitions are never in scope; refuses an in-flight instance (abort it first) and anything that is not an engine instance document; takes no `--tag`, and `--deployment` only to disambiguate a tag spanning deployments; plan + `y/N` confirm |
156
+ ## Command list
157
+
158
+ Invoke as `sanity-workflows <command>` (or `sanity workflows <command>` once the host CLI mount lands).
159
+
160
+ | Command | Description |
161
+ | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
162
+ | `deploy` | Validate and deploy the definitions in the selected deployment. |
163
+ | `deploy --all-tags` | Deploy every deployment in the config. A failure in one does not stop the rest. |
164
+ | `deploy --check` | Validate local definitions without contacting the dataset. |
165
+ | `deploy --dry-run` | Show a diff against what is already deployed, without writing. |
166
+ | `deploy --only <name>` | Limit deploy, check, or dry-run to one definition. |
167
+ | `start <name>` | Start an instance from a deployed definition. Pass `--field` for input values. |
168
+ | `list` | List instances (in-flight by default). Filter with `--definition`. |
169
+ | `show <instance-id>` | Show an instance's state, activities, and effects. |
170
+ | `diagnose <instance-id>` | Explain why an instance is or isn't progressing, and what would unstick it. |
171
+ | `tail <instance-id>` | Stream new history entries as they land. |
172
+ | `abort <instance-id>` | Stop an in-flight instance. Pending effects cancel; the instance stays where it is. |
173
+ | `set-stage <instance-id> --to <stage>` | Move an instance to a stage, skipping declared transitions. The target stage's enter lifecycle still runs. |
174
+ | `reset-activity <instance-id> <activity>` | Re-run a failed activity, or `--skip` it so a gated transition can fire. |
175
+ | `fire-action <instance-id>` | Fire an action on a waiting activity. Omit `--action` to list what can be fired. |
176
+ | `definition list` | List deployed definitions. |
177
+ | `definition show <name>` | Show a deployed definition (latest version, or `--version`). |
178
+ | `definition diff <name>` | Diff the in-code definition against what is deployed. |
179
+ | `definition delete <name>` | Delete a deployed definition. Refuses while live instances exist unless `--cascade`. |
180
+ | `nuke --deployment <name>` / `nuke --tag <tag>` | Dev reset: delete every engine-owned document for that tag (instances, definitions, guards). Prints a plan, then asks for confirmation. Content documents are never touched. |
181
+ | `nuke --instance <id>` | Dev reset: delete one finished instance and its guards. Refuses in-flight instances (abort first). |
181
182
 
182
183
  ## Telemetry
183
184
 
@@ -224,11 +225,11 @@ only warns, never failing a completed deploy.
224
225
  ## Known gaps
225
226
 
226
227
  - **Not mounted in the `sanity` CLI yet.** The package side is mount-ready —
227
- commands nest under the `editorial-workflows` oclif topic (see
228
- [Run](#run)) — but the `sanity` CLI does not list this package in its
229
- plugin array, so the commands ship only through the standalone
230
- `sanity-workflows` binary today. The host-side mount (and what happens to
231
- the bare aliases inside a host) is a separate piece of work.
228
+ commands nest under the `workflows` oclif topic with no root
229
+ aliases (see [Run](#run)) — but the `sanity` CLI does not list this package
230
+ in its plugin array, so the commands ship only through the standalone
231
+ `sanity-workflows` binary today. The host-side mount is a separate piece of
232
+ work.
232
233
  - **No true bypass.** `set-stage` is the engine's `setStage` admin
233
234
  override: it skips the definition's declared transitions and filters, but
234
235
  the target stage's enter lifecycle and the post-move cascade still run. A
package/bin/run.js CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import {execute} from '@oclif/core'
3
3
 
4
- await execute({dir: import.meta.url})
4
+ import {rewriteStandaloneArgv} from '../dist/standalone-argv.js'
5
+
6
+ await execute({args: rewriteStandaloneArgv(process.argv.slice(2)), dir: import.meta.url})
@@ -0,0 +1,10 @@
1
+ export declare const WORKFLOWS_TOPIC = "workflows";
2
+ export declare const WORKFLOWS_TOPIC_PREFIX = "workflows:";
3
+ export declare const WORKFLOWS_DEPLOY_COMMAND_ID = "workflows:deploy";
4
+ /** Standalone binary name from package.json `oclif.bin` / `bin`. */
5
+ export declare const STANDALONE_BIN = "sanity-workflows";
6
+ /** True on `sanity-workflows`, or on a host only for `workflows` / `workflows:*`. */
7
+ export declare function shouldRunWorkflowCliTelemetry(args: {
8
+ bin: string;
9
+ commandId: string | undefined;
10
+ }): boolean;
@@ -0,0 +1,10 @@
1
+ export const WORKFLOWS_TOPIC = 'workflows';
2
+ export const WORKFLOWS_TOPIC_PREFIX = `${WORKFLOWS_TOPIC}:`;
3
+ export const WORKFLOWS_DEPLOY_COMMAND_ID = `${WORKFLOWS_TOPIC}:deploy`;
4
+ export const STANDALONE_BIN = 'sanity-workflows';
5
+ export function shouldRunWorkflowCliTelemetry(args) {
6
+ const { bin, commandId } = args;
7
+ return (bin === STANDALONE_BIN ||
8
+ commandId === WORKFLOWS_TOPIC ||
9
+ commandId?.startsWith(WORKFLOWS_TOPIC_PREFIX) === true);
10
+ }
@@ -2,7 +2,6 @@ import { type WorkflowInstance } from '@sanity/workflow-engine';
2
2
  import { WorkflowCommand } from '../../lib/base-command.ts';
3
3
  import { type WriteReport } from '../../lib/ops-report.ts';
4
4
  export default class Abort extends WorkflowCommand {
5
- static aliases: string[];
6
5
  static description: string;
7
6
  static examples: string[];
8
7
  static args: {
@@ -7,11 +7,10 @@ import { instanceFlags } from "../../lib/flags.js";
7
7
  import { buildOperationArgs } from "../../lib/operation-args.js";
8
8
  import { runWriteVerb } from "../../lib/ops-report.js";
9
9
  export default class Abort extends WorkflowCommand {
10
- static aliases = ['abort'];
11
10
  static description = 'Abort an in-flight workflow instance — a hard stop: pending effects are cancelled, stage guards removed, and the instance is marked terminal where it stands.';
12
11
  static examples = [
13
- '<%= config.bin %> abort wf-instance.abc123',
14
- "<%= config.bin %> abort wf-instance.abc123 --reason 'superseded by relaunch'",
12
+ '<%= config.bin %> workflows abort wf-instance.abc123',
13
+ "<%= config.bin %> workflows abort wf-instance.abc123 --reason 'superseded by relaunch'",
15
14
  ];
16
15
  static args = {
17
16
  instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
@@ -2,7 +2,6 @@ import { type DeleteDefinitionArgs, type DeleteDefinitionResult } from '@sanity/
2
2
  import { WorkflowCommand } from '../../../lib/base-command.ts';
3
3
  import { type EngineScope } from '../../../lib/operation-args.ts';
4
4
  export default class DefinitionDelete extends WorkflowCommand {
5
- static aliases: string[];
6
5
  static description: string;
7
6
  static examples: string[];
8
7
  static args: {
@@ -7,14 +7,13 @@ import { deploymentFlags } from "../../../lib/flags.js";
7
7
  import { baseEngineArgs } from "../../../lib/operation-args.js";
8
8
  import { runWriteVerb } from "../../../lib/ops-report.js";
9
9
  export default class DefinitionDelete extends WorkflowCommand {
10
- static aliases = ['definition:delete'];
11
10
  static description = 'Delete a deployed workflow definition (every version, or one via --version). ' +
12
11
  'Refuses while non-terminal instances exist unless --cascade aborts them first — ' +
13
12
  'instances are aborted in place, never deleted.';
14
13
  static examples = [
15
- '<%= config.bin %> definition delete my-workflow',
16
- '<%= config.bin %> definition delete my-workflow --version 2',
17
- "<%= config.bin %> definition delete my-workflow --cascade --reason 'workflow retired'",
14
+ '<%= config.bin %> workflows definition delete my-workflow',
15
+ '<%= config.bin %> workflows definition delete my-workflow --version 2',
16
+ "<%= config.bin %> workflows definition delete my-workflow --cascade --reason 'workflow retired'",
18
17
  ];
19
18
  static args = {
20
19
  name: Args.string({ required: true, description: 'Workflow definition name.' }),
@@ -1,7 +1,6 @@
1
1
  import { type WorkflowDefinition } from '@sanity/workflow-engine';
2
2
  import { WorkflowCommand } from '../../../lib/base-command.ts';
3
3
  export default class DefinitionDiff extends WorkflowCommand {
4
- static aliases: string[];
5
4
  static description: string;
6
5
  static examples: string[];
7
6
  static args: {
@@ -8,11 +8,10 @@ import { diffReport } from "../../../lib/diff.js";
8
8
  import { deploymentFlags } from "../../../lib/flags.js";
9
9
  import { deploymentToTarget } from "../../../lib/select-deployment.js";
10
10
  export default class DefinitionDiff extends WorkflowCommand {
11
- static aliases = ['definition:diff'];
12
11
  static description = 'Diff an in-code definition against the deployed version (latest by default).';
13
12
  static examples = [
14
- '<%= config.bin %> definition diff productLaunch',
15
- '<%= config.bin %> definition diff productLaunch --version 2',
13
+ '<%= config.bin %> workflows definition diff productLaunch',
14
+ '<%= config.bin %> workflows definition diff productLaunch --version 2',
16
15
  ];
17
16
  static args = {
18
17
  name: Args.string({ required: true, description: 'Workflow definition name.' }),
@@ -22,7 +22,6 @@ export declare function buildDefinitionListQuery(flags: DefinitionListFlags): {
22
22
  params: Record<string, unknown>;
23
23
  };
24
24
  export default class DefinitionList extends WorkflowCommand {
25
- static aliases: string[];
26
25
  static description: string;
27
26
  static examples: string[];
28
27
  static flags: {
@@ -40,12 +40,11 @@ export function buildDefinitionListQuery(flags) {
40
40
  return { groq, params };
41
41
  }
42
42
  export default class DefinitionList extends WorkflowCommand {
43
- static aliases = ['definition:list'];
44
43
  static description = 'List deployed workflow definitions.';
45
44
  static examples = [
46
- '<%= config.bin %> definition list',
47
- '<%= config.bin %> definition list --tag prod',
48
- '<%= config.bin %> definition list --json',
45
+ '<%= config.bin %> workflows definition list',
46
+ '<%= config.bin %> workflows definition list --tag prod',
47
+ '<%= config.bin %> workflows definition list --json',
49
48
  ];
50
49
  static flags = {
51
50
  ...tagFlags,
@@ -2,7 +2,6 @@ import { type DeployedDefinition, type WorkflowDefinition, type WorkflowResource
2
2
  import { WorkflowCommand } from '../../../lib/base-command.ts';
3
3
  import { type ReadTarget } from '../../../lib/context.ts';
4
4
  export default class DefinitionShow extends WorkflowCommand {
5
- static aliases: string[];
6
5
  static description: string;
7
6
  static args: {
8
7
  name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
@@ -9,7 +9,6 @@ import { fail } from "../../../lib/fail.js";
9
9
  import { jsonFlags, tagFlags } from "../../../lib/flags.js";
10
10
  import { formatKeyValue, resourceLabel, sectionHeader } from "../../../lib/ui.js";
11
11
  export default class DefinitionShow extends WorkflowCommand {
12
- static aliases = ['definition:show'];
13
12
  static description = 'Show a deployed workflow definition.';
14
13
  static args = {
15
14
  name: Args.string({ required: true, description: 'Workflow definition name.' }),
@@ -12,7 +12,6 @@ interface DeployFailure {
12
12
  message: string;
13
13
  }
14
14
  export default class Deploy extends WorkflowCommand {
15
- static aliases: string[];
16
15
  static description: string;
17
16
  static examples: string[];
18
17
  static flags: {
@@ -47,8 +46,10 @@ export declare function resolveBatches(config: WorkflowConfig, { only, selection
47
46
  * Select and validate every deployment's definitions up front. Validation runs
48
47
  * before any network write ({@link validateOrFail} exits on a bad definition),
49
48
  * so a whole-config deploy can never leave a partial reconcile behind a broken
50
- * batch. In a multi-deployment run the failure names its deployment it exits
51
- * before any banner could attribute it.
49
+ * batch. Also asserts each selected deployment's reader-floor acknowledgement
50
+ * including `--check`, which never reaches {@link deploymentToTarget}. In a
51
+ * multi-deployment run the failure names its deployment — it exits before any
52
+ * banner could attribute it.
52
53
  */
53
54
  export declare function buildBatches(deployments: WorkflowDeployment[], only: string | undefined): DeployBatch[];
54
55
  /**
@@ -1,6 +1,6 @@
1
1
  import { styleText } from 'node:util';
2
2
  import { Flags } from '@oclif/core';
3
- import { computeDiffEntries, errorMessage, workflow, } from '@sanity/workflow-engine';
3
+ import { assertReaderModelAcknowledgement, 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";
@@ -15,15 +15,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";
17
17
  export default class Deploy extends WorkflowCommand {
18
- static aliases = ['deploy'];
19
18
  static description = 'Validate, diff, and deploy workflow definitions to the resource bound by the selected deployment.';
20
19
  static examples = [
21
- '<%= config.bin %> deploy --deployment review-prod',
22
- '<%= config.bin %> deploy --tag prod',
23
- '<%= config.bin %> deploy --all-tags',
24
- '<%= config.bin %> deploy --check',
25
- '<%= config.bin %> deploy --dry-run',
26
- '<%= config.bin %> deploy --only productLaunch',
20
+ '<%= config.bin %> workflows deploy --deployment review-prod',
21
+ '<%= config.bin %> workflows deploy --tag prod',
22
+ '<%= config.bin %> workflows deploy --all-tags',
23
+ '<%= config.bin %> workflows deploy --check',
24
+ '<%= config.bin %> workflows deploy --dry-run',
25
+ '<%= config.bin %> workflows deploy --only productLaunch',
27
26
  ];
28
27
  static flags = {
29
28
  ...deploymentFlags,
@@ -161,6 +160,7 @@ export async function resolveBatches(config, { only, selection }) {
161
160
  }
162
161
  export function buildBatches(deployments, only) {
163
162
  return deployments.map((deployment) => {
163
+ assertReaderModelAcknowledgement(deployment.expectedMinReaderModel, `Deployment ${deployment.name}`);
164
164
  const context = deployments.length > 1 ? `${deploymentLabel(deployment)} — ` : '';
165
165
  const defs = selectDefinitions(deployment.definitions, { only, context });
166
166
  validateOrFail(defs, context);
@@ -193,7 +193,13 @@ export function deploySummary({ total, failures, }) {
193
193
  return [
194
194
  '',
195
195
  styleText('bold', `${total - failures.length} of ${total} deployments succeeded — ${failures.length} failed:`),
196
- ...failures.map((f) => styleText('red', ` ${logSymbols.error} ${deploymentLabel(f.deployment)} — ${f.message}`)),
196
+ ...failures.flatMap((f) => {
197
+ const [first = '', ...rest] = f.message.split('\n');
198
+ return [
199
+ styleText('red', ` ${logSymbols.error} ${deploymentLabel(f.deployment)} — ${first}`),
200
+ ...rest.map((line) => styleText('red', ` ${line}`)),
201
+ ];
202
+ }),
197
203
  ];
198
204
  }
199
205
  export function deploymentBanner({ deployment, index, total, }) {
@@ -32,7 +32,6 @@ export declare function renderDiagnosis({ diagnosis, input, remediations, explan
32
32
  explanations?: ReadonlyMap<string, string> | undefined;
33
33
  }): string[];
34
34
  export default class Diagnose extends WorkflowCommand {
35
- static aliases: string[];
36
35
  static description: string;
37
36
  static examples: string[];
38
37
  static args: {
@@ -212,12 +212,11 @@ export function renderDiagnosis({ diagnosis, input, remediations, explanations,
212
212
  return lines;
213
213
  }
214
214
  export default class Diagnose extends WorkflowCommand {
215
- static aliases = ['diagnose'];
216
215
  static description = "Explain why a workflow instance is or isn't progressing, and what would unstick it.";
217
216
  static examples = [
218
- '<%= config.bin %> diagnose wf-instance.abc123',
219
- '<%= config.bin %> diagnose wf-instance.abc123 --tag prod',
220
- '<%= config.bin %> diagnose wf-instance.abc123 --json',
217
+ '<%= config.bin %> workflows diagnose wf-instance.abc123',
218
+ '<%= config.bin %> workflows diagnose wf-instance.abc123 --tag prod',
219
+ '<%= config.bin %> workflows diagnose wf-instance.abc123 --json',
221
220
  ];
222
221
  static args = {
223
222
  instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
@@ -30,7 +30,6 @@ export declare function fireActionReport({ result, activity, action, }: {
30
30
  action: string;
31
31
  }): WriteReport;
32
32
  export default class FireAction extends WorkflowCommand {
33
- static aliases: string[];
34
33
  static description: string;
35
34
  static examples: string[];
36
35
  static args: {
@@ -82,12 +82,11 @@ export function fireActionReport({ result, activity, action, }) {
82
82
  };
83
83
  }
84
84
  export default class FireAction extends WorkflowCommand {
85
- static aliases = ['fire-action'];
86
85
  static description = 'Fire an action on an instance to unstick a waiting activity — the write acts as the configured token. Omit --action to list what can be fired.';
87
86
  static examples = [
88
- '<%= config.bin %> fire-action wf-instance.abc123',
89
- '<%= config.bin %> fire-action wf-instance.abc123 --activity approve --action approve',
90
- '<%= config.bin %> fire-action wf-instance.abc123 --activity publish --action publish --param note=shipping',
87
+ '<%= config.bin %> workflows fire-action wf-instance.abc123',
88
+ '<%= config.bin %> workflows fire-action wf-instance.abc123 --activity approve --action approve',
89
+ '<%= config.bin %> workflows fire-action wf-instance.abc123 --activity publish --action publish --param note=shipping',
91
90
  ];
92
91
  static args = {
93
92
  instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
@@ -47,7 +47,6 @@ export declare function instanceRow(r: InstanceRow): {
47
47
  lastChangedAt: string;
48
48
  };
49
49
  export default class List extends WorkflowCommand {
50
- static aliases: string[];
51
50
  static description: string;
52
51
  static examples: string[];
53
52
  static flags: {
@@ -77,15 +77,14 @@ export function instanceRow(r) {
77
77
  };
78
78
  }
79
79
  export default class List extends WorkflowCommand {
80
- static aliases = ['list'];
81
80
  static description = 'List workflow instances in the configured dataset (in-flight by default).';
82
81
  static examples = [
83
- '<%= config.bin %> list',
84
- '<%= config.bin %> list --include-completed',
85
- '<%= config.bin %> list --definition productLaunch',
86
- '<%= config.bin %> list --document dataset:proj:ds:article-1',
87
- '<%= config.bin %> list --tag prod',
88
- '<%= config.bin %> list --json',
82
+ '<%= config.bin %> workflows list',
83
+ '<%= config.bin %> workflows list --include-completed',
84
+ '<%= config.bin %> workflows list --definition productLaunch',
85
+ '<%= config.bin %> workflows list --document dataset:proj:ds:article-1',
86
+ '<%= config.bin %> workflows list --tag prod',
87
+ '<%= config.bin %> workflows list --json',
89
88
  ];
90
89
  static flags = {
91
90
  ...tagFlags,
@@ -1,7 +1,6 @@
1
1
  import { type WorkflowConfig, type WorkflowDeployment, type WorkflowInstance, type WorkflowResource } from '@sanity/workflow-engine';
2
2
  import { WorkflowCommand } from '../../lib/base-command.ts';
3
3
  export default class Nuke extends WorkflowCommand {
4
- static aliases: string[];
5
4
  static summary: string;
6
5
  static description: string;
7
6
  static examples: string[];
@@ -16,7 +16,6 @@ function planApiHost() {
16
16
  return resolveApiHost() ?? 'https://api.sanity.io (production default)';
17
17
  }
18
18
  export default class Nuke extends WorkflowCommand {
19
- static aliases = ['nuke'];
20
19
  static summary = 'Delete engine-owned documents — a whole deployment tag, or a single instance.';
21
20
  static description = 'The reset for a dataset holding engine documents the versioned upgrade framework cannot yet ' +
22
21
  "migrate: deletes the tag's instances, definitions, and guards (across every alias-bound " +
@@ -24,9 +23,9 @@ export default class Nuke extends WorkflowCommand {
24
23
  'documents are never touched. Prints a dry-run plan, then confirms (--force skips the prompt; ' +
25
24
  'the plan still prints).';
26
25
  static examples = [
27
- '<%= config.bin %> nuke --deployment plugin-dev',
28
- '<%= config.bin %> nuke --tag plugin-dev --force',
29
- '<%= config.bin %> nuke --instance plugin-dev.wf-instance.abc123',
26
+ '<%= config.bin %> workflows nuke --deployment plugin-dev',
27
+ '<%= config.bin %> workflows nuke --tag plugin-dev --force',
28
+ '<%= config.bin %> workflows nuke --instance plugin-dev.wf-instance.abc123',
30
29
  ];
31
30
  static flags = {
32
31
  deployment: Flags.string({
@@ -2,7 +2,6 @@ import { type ResetActivityTarget, type WorkflowInstance } from '@sanity/workflo
2
2
  import { WorkflowCommand } from '../../lib/base-command.ts';
3
3
  import { type WriteOutcome, type WriteReport } from '../../lib/ops-report.ts';
4
4
  export default class ResetActivity extends WorkflowCommand {
5
- static aliases: string[];
6
5
  static description: string;
7
6
  static examples: string[];
8
7
  static args: {
@@ -7,11 +7,10 @@ import { instanceFlags } from "../../lib/flags.js";
7
7
  import { buildOperationArgs } from "../../lib/operation-args.js";
8
8
  import { cascadeTail, runWriteVerb, } from "../../lib/ops-report.js";
9
9
  export default class ResetActivity extends WorkflowCommand {
10
- static aliases = ['reset-activity'];
11
10
  static description = 'Reset a failed activity on an in-flight instance — back to active to re-run it, or --skip to bypass it (mark it skipped) so a gated exit transition can fire.';
12
11
  static examples = [
13
- '<%= config.bin %> reset-activity wf-instance.abc123 legal-review',
14
- '<%= config.bin %> reset-activity wf-instance.abc123 legal-review --skip',
12
+ '<%= config.bin %> workflows reset-activity wf-instance.abc123 legal-review',
13
+ '<%= config.bin %> workflows reset-activity wf-instance.abc123 legal-review --skip',
15
14
  ];
16
15
  static args = {
17
16
  instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
@@ -3,7 +3,6 @@ import { WorkflowCommand } from '../../lib/base-command.ts';
3
3
  import { type EngineScope } from '../../lib/operation-args.ts';
4
4
  import { type WriteOutcome, type WriteReport } from '../../lib/ops-report.ts';
5
5
  export default class SetStage extends WorkflowCommand {
6
- static aliases: string[];
7
6
  static description: string;
8
7
  static examples: string[];
9
8
  static args: {
@@ -9,12 +9,11 @@ import { buildOperationArgs } from "../../lib/operation-args.js";
9
9
  import { cascadeTail, opsAppliedLines, runWriteVerb, } from "../../lib/ops-report.js";
10
10
  import { canPromptOnStderr, selectOnStderr } from "../../lib/prompt.js";
11
11
  export default class SetStage extends WorkflowCommand {
12
- static aliases = ['set-stage'];
13
12
  static description = "Force an instance into a stage, regardless of its declared transitions and filters — the engine's setStage admin override. The target stage's enter lifecycle still runs (auto-activities start, stage guards reconcile), and the post-move cascade can immediately auto-transition the instance onward.";
14
13
  static examples = [
15
- '<%= config.bin %> set-stage wf-instance.abc123 --to ready',
16
- '<%= config.bin %> set-stage wf-instance.abc123',
17
- "<%= config.bin %> set-stage wf-instance.abc123 --to ready --reason 'unblock for demo'",
14
+ '<%= config.bin %> workflows set-stage wf-instance.abc123 --to ready',
15
+ '<%= config.bin %> workflows set-stage wf-instance.abc123',
16
+ "<%= config.bin %> workflows set-stage wf-instance.abc123 --to ready --reason 'unblock for demo'",
18
17
  ];
19
18
  static args = {
20
19
  instanceId: Args.string({