@sanity/workflow-cli 0.8.1 → 0.10.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 +485 -0
- package/README.md +145 -63
- package/bin/run.js +0 -4
- package/dist/commands/abort.d.ts +8 -12
- package/dist/commands/abort.js +24 -34
- package/dist/commands/definition/delete.d.ts +6 -6
- package/dist/commands/definition/delete.js +17 -33
- package/dist/commands/definition/diff.d.ts +10 -3
- package/dist/commands/definition/diff.js +21 -29
- package/dist/commands/definition/list.d.ts +5 -6
- package/dist/commands/definition/list.js +44 -50
- package/dist/commands/definition/show.d.ts +22 -13
- package/dist/commands/definition/show.js +25 -36
- package/dist/commands/deploy.d.ts +67 -8
- package/dist/commands/deploy.js +136 -32
- package/dist/commands/diagnose.d.ts +22 -4
- package/dist/commands/diagnose.js +45 -61
- package/dist/commands/fire-action.d.ts +7 -30
- package/dist/commands/fire-action.js +42 -115
- package/dist/commands/list.d.ts +9 -10
- package/dist/commands/list.js +49 -62
- package/dist/commands/{retry-activity.d.ts → reset-activity.d.ts} +1 -1
- package/dist/commands/{retry-activity.js → reset-activity.js} +2 -3
- package/dist/commands/set-stage.d.ts +27 -3
- package/dist/commands/set-stage.js +63 -12
- package/dist/commands/show.d.ts +3 -2
- package/dist/commands/show.js +15 -21
- package/dist/commands/start.d.ts +56 -0
- package/dist/commands/start.js +133 -0
- package/dist/commands/tail.d.ts +5 -2
- package/dist/commands/tail.js +25 -26
- package/dist/hooks/finally/telemetry.d.ts +8 -0
- package/dist/hooks/finally/telemetry.js +13 -0
- package/dist/hooks/prerun/telemetry.d.ts +5 -0
- package/dist/hooks/prerun/telemetry.js +5 -0
- package/dist/index.js +0 -3
- package/dist/lib/base-command.d.ts +14 -0
- package/dist/lib/base-command.js +10 -0
- package/dist/lib/client.d.ts +11 -14
- package/dist/lib/client.js +29 -34
- package/dist/lib/context.d.ts +98 -0
- package/dist/lib/context.js +83 -0
- package/dist/lib/definitions.d.ts +38 -29
- package/dist/lib/definitions.js +34 -93
- package/dist/lib/diff.d.ts +5 -2
- package/dist/lib/diff.js +62 -20
- package/dist/lib/env.d.ts +4 -6
- package/dist/lib/env.js +4 -9
- package/dist/lib/fail.d.ts +12 -0
- package/dist/lib/fail.js +25 -16
- package/dist/lib/flags.d.ts +7 -2
- package/dist/lib/flags.js +7 -3
- package/dist/lib/load-config.d.ts +15 -0
- package/dist/lib/load-config.js +89 -0
- package/dist/lib/operation-args.d.ts +20 -15
- package/dist/lib/operation-args.js +9 -40
- package/dist/lib/ops-report.d.ts +29 -13
- package/dist/lib/ops-report.js +20 -17
- package/dist/lib/params.d.ts +7 -0
- package/dist/lib/params.js +18 -0
- package/dist/lib/read-fanout.d.ts +22 -0
- package/dist/lib/read-fanout.js +28 -0
- package/dist/lib/select-deployment.d.ts +31 -0
- package/dist/lib/select-deployment.js +37 -0
- package/dist/lib/share-definitions.d.ts +86 -0
- package/dist/lib/share-definitions.js +106 -0
- package/dist/lib/stub.js +0 -7
- package/dist/lib/telemetry-setup.d.ts +66 -0
- package/dist/lib/telemetry-setup.js +92 -0
- package/dist/lib/telemetry.d.ts +100 -0
- package/dist/lib/telemetry.js +89 -0
- package/dist/lib/ui.d.ts +33 -1
- package/dist/lib/ui.js +32 -21
- package/oclif.manifest.json +133 -113
- package/package.json +16 -8
- package/dist/commands/move-stage.d.ts +0 -52
- package/dist/commands/move-stage.js +0 -86
- package/dist/lib/config.d.ts +0 -18
- package/dist/lib/config.js +0 -50
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
# @sanity/workflow-cli
|
|
2
|
+
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d4fd8e6: Deploy grows an explicit definition-sharing opt-in — content sharing, not telemetry, opted into by flag alone with nothing persisted and never a prompt. `deploy --share-definitions-with-sanity` shares the definition documents that deploy newly created, verbatim — the full document: structure, names, titles, GROQ filters, effect configuration, and seeded values, plus its deployment coordinates (project and dataset, or resource id); never content documents, workflow instances, or Sanity auth tokens — for that invocation only. Without the flag, an interactive deploy that created new versions logs a one-line stderr hint pointing at it (CI / non-TTY runs stay silent); telemetry consent and `DO_NOT_TRACK` play no part. Shared documents ride one POST per invocation to Sanity's first-party definition-feedback endpoint — never the telemetry pipeline — and a failed share only warns, never failing a completed deploy. Telemetry keeps a content-free `Editorial Workflows Definition Shared` marker per shared definition, projected from the same structural derivation as `Editorial Workflows Definition Deployed`; unchanged re-deploys neither hint nor share.
|
|
8
|
+
- 5cb0850: `diagnose` renders insight under each unsatisfied exit transition — the transition line gains a dim `↳ Needs: …` summary from the evaluation's derived state, so "stuck" reads as "stuck until X" in the definition's own vocabulary. `--json` gains the RAW derived state instead (`transitions[].blockedBy` with each atom's GROQ and solvable requirement) — structure for scripts, language for humans.
|
|
9
|
+
- 15337f1: Request-tag CLI traffic: clients carry the `sanity.workflows.cli` request-tag prefix — the workflows-owned family with the runtime as its segment, never another team's family. The family identifies the traffic, so per-request tags are bare command ops (`list`, `show`, `definition.list`, `definition.show`, `definition.load`, `instance.load`, `tail` — the tail listener passes a per-request tag because a prefix alone never tags listen requests) and engine verbs strip their `workflow.` root under the family prefix, so everything lands as `sanity.workflows.cli.<op>` in request logs.
|
|
10
|
+
- ced40e4: The CLI is now its own telemetry app shell. A `prerun` hook builds a batched store over the standard Sanity-intake recipe (CI or `DO_NOT_TRACK` deny without a network call; not logged in or no dataset-backed deployment → nothing is sent; otherwise the account-level consent status), shows a one-time stderr disclosure, and threads the store's logger into every engine write verb so engine adoption events flow from CLI-driven operations. A `finally` hook completes the `Editorial Workflows CLI Command Executed` trace — command id, names of declared flags used (never values), success flag — and flushes with a deadline. A `telemetry` logger on the workflow config replaces the built-in shell wholesale: every event flows to it unconditionally and consent/suppression/transport become its business.
|
|
11
|
+
- 0709ab1: De-duplicate the write-verb scaffolding and adopt the engine's canonical helpers:
|
|
12
|
+
- Every write command (`abort`, `set-stage`, `fire-action`, `start`, `definition delete`) now runs through one `runWriteVerb` helper owning the spinner start / report emit / fail-and-exit catch shape, and the ", then cascaded N auto-transition(s)" suffix comes from one `cascadeTail` helper.
|
|
13
|
+
- The CLI's local `errorMessage` copy is gone — all error rendering uses the engine's exported `errorMessage` (same control-character stripping as before).
|
|
14
|
+
- Instance status in `list` and the aborted/completed header in `show` derive from the engine's `terminalState`.
|
|
15
|
+
- History entries in `tail` and `show --include history` now print the engine's display titles (e.g. "Transition fired") instead of raw discriminators (`transitionFired`).
|
|
16
|
+
- `fire-action`'s list mode renders the engine's new `instance-aborted` verdict ("instance aborted at …") for actions on aborted instances.
|
|
17
|
+
|
|
18
|
+
- adf32f7: **BREAKING:** the `--as` / `--as-role` impersonation flags and the pinned `workflow-cli` system actor are removed. Every write is attributed to the user behind the configured token (`/users/me`); impersonation means running with a different token. The CLI declares `executionContext {kind: 'cli', id: 'workflow-cli'}` on its engine scope, so history records the environment without forging identity.
|
|
19
|
+
- 91540de: **BREAKING:** every shell-defined telemetry event name now carries the product name — `Editorial Workflows CLI Command Executed`, `Editorial Workflows Definition Shared` (workflow-cli), `Editorial Workflows MCP Tool Called` (workflow-mcp), `Editorial Workflows Session Started` (workflow-react) — replacing the bare `Workflow <X>` forms, which never shipped. Event names are matched verbatim downstream.
|
|
20
|
+
|
|
21
|
+
Shell context parity: every self-owned telemetry shell now attaches its execution environment, following the sanity CLI and Studio precedents. User identity stays sink-side — the intake service resolves the sender from the authenticated session on every event.
|
|
22
|
+
- CLI: `updateUserProperties` with the sanity CLI's set (cliVersion, platform, architecture, runtime, runtime version, projectId, dataset) plus `surface: 'cli'` and `orgId` resolved once per invocation from the projects API (deadline-capped, degrade-soft — a failed lookup omits the property, never blocks a command).
|
|
23
|
+
- SDK: Studio-style context enrichment on every posted event — `surface: 'sdk'`, package version, environment, userAgent, project coordinates.
|
|
24
|
+
- MCP: `updateUserProperties` on store initialization — `surface: 'mcp'`, package version, runtime info, the addressed project coordinates; the server handshake now reports the real package version instead of `0.0.0`.
|
|
25
|
+
- React hosts (Studio, SDK, custom): the session layer pushes `{surface: host}` into the HOST's own session stream via `updateUserProperties` — Studio-hosted events get an explicit surface marker without touching Studio's transport.
|
|
26
|
+
- The `Editorial Workflows Definition Shared` marker carries the deploy run's `deployId`, so donated definitions group with the deploy events that minted them.
|
|
27
|
+
|
|
28
|
+
- d6e92ed: Now published with public npm access (previously restricted) — installable without `@sanity` org membership.
|
|
29
|
+
- 23cf131: Render the engine's new `subject-permission-denied` disabled reason — the actor lacks write permission on a subject document in that subject's own resource.
|
|
30
|
+
- 0a8baa4: Untagged reads now fan out across every distinct resource the config mentions instead of failing with "Config spans multiple resources — pass --tag to choose one": `list` and `definition list` query each dataset and group output under per-resource banners (an unreadable resource is noted in place, the rest still render, and the command exits non-zero), `show` and `tail` look the instance id up across resources (erroring if it exists in several), and `definition show` errors when the name is deployed to more than one dataset. `--tag` still narrows any read to that deployment's resource.
|
|
31
|
+
- f580319: Match the Sanity CLI's output styling: `list` and `definition list` render borderless column tables (lowercase cyan header row, three-space gutters, uncolored cells) instead of boxed tables, and the detail lines under an error headline render in muted red. `definition list` gains a `created` column showing when each definition version was deployed and drops the `startable` column to keep rows scannable, and both list commands print a dim "showing the first N — raise --limit" note when results exceed the limit instead of truncating silently.
|
|
32
|
+
- ced40e4: Request tags move to workflows-owned families with the runtime as the segment: `sanity.workflows.cli`, `sanity.workflows.studio`, `sanity.workflows.sdk` — never another team's family (`sanity.cli.*`, `sanity.studio.*`) — and platform analysis zero-rates `sanity.workflows.*`. The MCP server deliberately sits outside that family as `sanity.workflows-mcp` (no dot boundary), so agent-driven traffic bills. Under any workflows-family prefix the engine's tag wrapper strips the now-redundant `workflow.` root from every relative op tag — stamped fallback and explicit alike — so traffic lands as `sanity.workflows.cli.deploy` with exactly one workflows segment; on raw consumer clients and under foreign host prefixes the root stays, since there it is what identifies the traffic. The Studio adapter's engine and resource-router clients and the SDK telemetry shell's intake client now set their family prefix themselves instead of riding the host's.
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- e374155: Auth rejections (HTTP 401) now exit through the CLI's clean error path with a recovery hint — re-run `sanity login` when the session token has lapsed, or check `SANITY_AUTH_TOKEN` when the env token is set — instead of surfacing a raw oclif error.
|
|
37
|
+
- 9f5a40f: Document that the CLI's token must span every resource the workflow references — runtime commands build one client from the deployment descriptor, and the engine reaches foreign datasets/resources through sibling clients derived from that same token. Cross-resource runtime routing (`show`, `diagnose`, `fire-action`) is now covered against a subject document living in a different dataset than the workflow resource, with no resolver wiring.
|
|
38
|
+
- 109f900: `workflow deploy` now prints the advisory effect-output lint warnings returned on each deploy result, indented beneath the definition they belong to, so the producer/consumer hints are visible on the CLI deploy path (previously only carried on the result object).
|
|
39
|
+
- 5cb0850: Type-only: the diagnose renderer consumes the engine's narrowed `DiagnosedTransition` slice instead of the full `TransitionEvaluation`, matching what the classifier actually reads. No behavior change.
|
|
40
|
+
- 1045843: `definition diff` and `deploy --dry-run` now show only the authored fields that differ. The deploy envelope (`_id`, `_type`, `tag`, `version`, `contentHash`) is stripped from both sides before diffing — version and document id already appear on the Summary line — and long runs of unchanged context collapse to a dim `… N unchanged lines` marker with three lines of context around each change. Net-new definitions still render in full; the deploy-generated-fields footnote is gone along with the noise it explained.
|
|
41
|
+
- 8077858: The build now cleans `dist/` before compiling, so removed commands can no longer ship as orphaned artifacts in a locally packed tarball (`tsc` never deletes outputs for deleted sources, and `files: ["dist"]` ships the whole directory). A packaging smoke test guards the packed output: the tarball must contain exactly the command modules that exist in `src`, and the built bin must load and register every command — catching broken specifier rewrites and stale workspace-dependency builds that stay green in unit tests and only surface for a consumer.
|
|
42
|
+
- 6c21009: Correct public TSDoc and README claims that contradicted the implementation: CLI auth precedence (an explicit `SANITY_AUTH_TOKEN` wins over the `sanity login` session), the real CLI verbs (`workflow.diagnose`, `workflow.availableActions`) and document types (`sanity.workflow.instance` / `sanity.workflow.definition`), guard predicates reading the delta-mode `before()`/`after()` natives, glob patterns supporting multiple `*`s, where `$can` actually binds (requirements and the editField gate, not action filters alone), the editField target contract (any-scope match with activity-first precedence), guard observation fan-out across the engine dataset plus each watched subject's dataset, the object value expression being op-payload-only, and the MCP descriptor / SDK observer export pointers. The deploy-time `$can` rejection error now states where `$can` actually binds (the caller-bound projection: action filters, requirements, editable predicates) instead of claiming action filters are its only home.
|
|
43
|
+
- 7ffdc77: New `clientConfigFromResource(resource)` export — the `@sanity/client`-config
|
|
44
|
+
fragment addressing a `WorkflowResource` (dataset via the classic
|
|
45
|
+
`{projectId, dataset}` config, other resource types passed through as
|
|
46
|
+
`resource`). The one home for that branch: hosts spread it into their own
|
|
47
|
+
`createClient` call, and the CLI's `clientFor` now derives its config through
|
|
48
|
+
it instead of a private copy.
|
|
49
|
+
- 72bd7ef: The packaging suite (subprocess dependency-chain build + `pnpm pack` + spawning the built bin) no longer runs in the default vitest run — it starved sibling suites into nondeterministic timeouts on loaded machines. CI runs it explicitly; opt in locally with `pnpm --filter @sanity/workflow-cli test:packaging`.
|
|
50
|
+
- dc64968: Published tarballs no longer include sourcemaps (whose `sourcesContent` embedded the complete TypeScript source) or inline code comments in the compiled JS — license markers and bundler annotations (`/*@__PURE__*/`-style tree-shaking hints) are preserved. Types and TSDoc in `.d.ts` files ship unchanged, and the tarballs shrink accordingly (workflow-engine: ~3× smaller). Each tarball now ships its `CHANGELOG.md`, so release notes reach consumers who can install the package but cannot see the repository.
|
|
51
|
+
- Updated dependencies [4ca17bb]
|
|
52
|
+
- Updated dependencies [5143707]
|
|
53
|
+
- Updated dependencies [0709ab1]
|
|
54
|
+
- Updated dependencies [6bbf3ca]
|
|
55
|
+
- Updated dependencies [9f5a40f]
|
|
56
|
+
- Updated dependencies [d192d68]
|
|
57
|
+
- Updated dependencies [6c21009]
|
|
58
|
+
- Updated dependencies [109f900]
|
|
59
|
+
- Updated dependencies [109f900]
|
|
60
|
+
- Updated dependencies [444b0e6]
|
|
61
|
+
- Updated dependencies [2511bb5]
|
|
62
|
+
- Updated dependencies [d4fd8e6]
|
|
63
|
+
- Updated dependencies [30ed0e8]
|
|
64
|
+
- Updated dependencies [2834704]
|
|
65
|
+
- Updated dependencies [2511bb5]
|
|
66
|
+
- Updated dependencies [2511bb5]
|
|
67
|
+
- Updated dependencies [2511bb5]
|
|
68
|
+
- Updated dependencies [4607d59]
|
|
69
|
+
- Updated dependencies [52f6024]
|
|
70
|
+
- Updated dependencies [a8f1cb9]
|
|
71
|
+
- Updated dependencies [adf32f7]
|
|
72
|
+
- Updated dependencies [5cb0850]
|
|
73
|
+
- Updated dependencies [70a136c]
|
|
74
|
+
- Updated dependencies [91540de]
|
|
75
|
+
- Updated dependencies [8455fbb]
|
|
76
|
+
- Updated dependencies [325c2d1]
|
|
77
|
+
- Updated dependencies [d6e92ed]
|
|
78
|
+
- Updated dependencies [6c21009]
|
|
79
|
+
- Updated dependencies [7ffdc77]
|
|
80
|
+
- Updated dependencies [325c2d1]
|
|
81
|
+
- Updated dependencies [7ffdc77]
|
|
82
|
+
- Updated dependencies [ced40e4]
|
|
83
|
+
- Updated dependencies [9b1b40d]
|
|
84
|
+
- Updated dependencies [8c319b2]
|
|
85
|
+
- Updated dependencies [dc64968]
|
|
86
|
+
- Updated dependencies [23cf131]
|
|
87
|
+
- Updated dependencies [d192d68]
|
|
88
|
+
- Updated dependencies [15337f1]
|
|
89
|
+
- Updated dependencies [2d1a8e1]
|
|
90
|
+
- Updated dependencies [12cdbd6]
|
|
91
|
+
- Updated dependencies [437b544]
|
|
92
|
+
- Updated dependencies [ced40e4]
|
|
93
|
+
- @sanity/workflow-engine@0.15.0
|
|
94
|
+
|
|
95
|
+
## 0.9.0
|
|
96
|
+
|
|
97
|
+
### Minor Changes
|
|
98
|
+
|
|
99
|
+
- a0443c4: **BREAKING:** Configure the CLI via a discovered `sanity.workflow.ts` instead of `WORKFLOW_*` environment variables. Every command now loads `defineWorkflowConfig({deployments: [...]})`, selects a deployment by `--tag` (or the sole deployment when only one is configured), and authenticates via the `sanity login` session (falling back to `SANITY_AUTH_TOKEN` for CI). Definitions and resource-handle bindings come from the selected deployment; `deploy` expands the bindings via `resourceAliases` at deploy time.
|
|
100
|
+
|
|
101
|
+
Removed env vars: `WORKFLOW_RESOURCE_TYPE`, `WORKFLOW_RESOURCE_ID`, `WORKFLOW_TAG`, `WORKFLOW_DEFS`, `SANITY_PROJECT_ID`, `SANITY_DATASET` (project/dataset are now derived from the deployment's resource).
|
|
102
|
+
|
|
103
|
+
Read commands (`list`, `definition list`, `definition show`, `show`, `tail`) inspect everything in the Content Lake resource — the config only locates which resource to read and authenticates; it never filters results to the config's tag or definitions. `--tag` is an optional query filter (omit it to span all partitions). The config selects the resource automatically when all deployments share one, and needs `--tag` only to disambiguate a config that spans multiple resources.
|
|
104
|
+
|
|
105
|
+
- 83d5924: **BREAKING:** One vocabulary with the engine across the command surface, plus instance start.
|
|
106
|
+
- `move-stage` is renamed `set-stage`, matching the engine verb it calls (`workflow.setStage`), with help text that states the semantics honestly: an admin override that skips the definition's declared transitions and filters, while the target stage's enter lifecycle and the post-move cascade still run. Its no-op report now distinguishes a terminal instance from an already-at-target one.
|
|
107
|
+
- The hidden `set-stage` guard-bypass stub is deleted — its name promised the opposite of the engine verb's semantics, and no bypass path exists in the engine. The hidden `retry-activity` stub is renamed `reset-activity` to match the engine's remediation verb.
|
|
108
|
+
- One noun for definition identity: `definition diff` takes `<name>` (matching `show`/`delete`), `list --workflow-name` becomes `list --definition <name>`, and `definition list --workflow-name` becomes `definition list --name`.
|
|
109
|
+
- `diagnose` renders remediation verbs under their engine names, so human output and `--json` share one vocabulary; write-command errors are prefixed with the command's own name (`set-stage error:`, `fire-action error:`, `abort error:`, `definition delete error:`) instead of engine verb spellings.
|
|
110
|
+
|
|
111
|
+
New: `start <name>` starts an instance from a deployed definition — `--field name=value` supplies the workflow's input-sourced fields (typed against the deployed definition's declared entries; a value for a non-input field is rejected rather than silently ignored), `--version` pins a version, `--as` / `--as-role` attribute the start to a real user, and `--json` emits structured output. Spawn-only (`lifecycle: 'child'`) definitions are refused with an explanation, so the `definition list` Startable column points at a real affordance. Write-path error output is routed through the control-character-stripping `errorMessage` helper across all commands.
|
|
112
|
+
|
|
113
|
+
- 845266e: `deploy` gains an `--all-tags` flag to deploy every deployment in the config in one run. The default stays a single target: `--tag <tag>` selects a deployment (omittable when only one is configured), and an ambiguous bare `deploy` against a multi-deployment config fails asking for `--tag` or `--all-tags` — deploying everything is always an explicit opt-in, never a default.
|
|
114
|
+
|
|
115
|
+
Definitions are validated up front, so a bad definition fails before anything is written — attributed to its deployment when the run spans several. During an `--all-tags` run, deployments are independent and idempotent, so a failure in one doesn't strand the rest: the run continues, then prints a summary of which deployments failed and exits non-zero (a single-target failure propagates directly instead). Deploys stay idempotent — an unchanged, content-addressed definition deploys as a no-op — and `--check` / `--dry-run` compose with both `--tag` and `--all-tags`. Output is labelled per deployment when a run spans more than one.
|
|
116
|
+
|
|
117
|
+
- 5c69928: **BREAKING:** runtime API coherence pass — one result shape, one session noun, nameable engine args.
|
|
118
|
+
- `DispatchResult` → `OperationResult`, and its `fired` flag → `changed` with one meaning honored by every verb: this call changed the instance's workflow state (`false` = successful no-op — an idempotent re-fire, a tick that wrote nothing, a `setStage` already at the target, an abort of an already-terminal instance; failures still throw). `tick` derives it from the instance revision, so a persisted activity-gate flip that didn't unlock a transition still reports `changed: true`. `abortInstance` documents its always-`0` cascade (a terminal instance doesn't cascade; ancestor propagation reports on the ancestors).
|
|
119
|
+
- `startInstance` now returns `OperationResult` instead of a bare `WorkflowInstance` — its cascade is finally observable. Reach the instance via `result.instance`.
|
|
120
|
+
- Engine argument types are exported and nameable: the exported `*Args` shapes are now exactly what `Engine` methods take, and the raw `workflow.*` namespace takes `<Verb>Args & EngineScopeArgs` (the new exported scope type: `client` / `tag` / `workflowResource` / `resourceClients`). New named args for the read/housekeeping verbs: `InstanceRefArgs`, `ChildrenArgs`, `GuardsForDefinitionArgs`, `InstancesForDocumentArgs`, `QueryArgs`, `QueryInScopeArgs`, `FindPendingEffectsArgs`, `DrainEffectsArgs`, `SessionArgs`. `EvaluateArgs` is likewise scope-free now.
|
|
121
|
+
- Verb-surface parity between `Engine` and `workflow.*` is exact and documented: `Engine.evaluateInstance` → `Engine.evaluate` (matching `workflow.evaluate`); engine-only members (`session`, `subscriptionDocumentsForInstance`, `drainEffects`, `verifyDeployedDefinitions`) and the namespace-only `workflow.permissions` are called out as deliberate.
|
|
122
|
+
- One noun for the reactive session handle: `engine.instance(doc, opts?)` → `engine.session({instance, access?, grantsFromPath?})` (args object — no positional outlier), still returning `InstanceSession`; workflow-react's `WorkflowInstanceController` → `WorkflowSession`; the studio/sdk hooks `useWorkflowInstance` → `useWorkflowSession`. "Instance" now always means the document.
|
|
123
|
+
- Test bench mirrors the engine: `bench.startInstance` returns `OperationResult`, and the `Bench*Args` types are the engine-bound shapes minus `access`.
|
|
124
|
+
- CLI reports follow the rename: the report objects for `fire-action` / `move-stage` / `abort` (and `fire-action`'s `--json` payload) now say `changed` instead of `fired`.
|
|
125
|
+
|
|
126
|
+
- 6ee9068: **BREAKING:** follow the engine's vocabulary sweep. `definition list` projects the stored `lifecycle` key (was `role`) to flag spawn-only definitions — definitions deployed before the rename show as startable until redeployed. `fire-action --as` attributes the fire as a `person` actor (was `user`).
|
|
127
|
+
|
|
128
|
+
### Patch Changes
|
|
129
|
+
|
|
130
|
+
- a0443c4: `definition diff` (and `deploy --dry-run`) now footnote the detail diff to explain that `_id`, `version`, and `contentHash` are deploy-generated — they change as a function of the content, so their `+`/`-` lines reflect the content change rather than fields the author edited. Without the note an operator could read a bumped `version` as a field they'd set themselves.
|
|
131
|
+
- 2f081a3: Render a `mutation-guard-denied` verdict from its `denied` payload via the engine's shared `deniedGuardLabels` (guard name over id), following the unified guard-denial shape.
|
|
132
|
+
- a0443c4: Instance-targeted commands (`diagnose`, `abort`, `move-stage`, `fire-action`) now derive their tag partition from the instance itself rather than from the config's declared deployments. An instance id is globally unique and carries its own `tag`, so naming one acts on that instance regardless of which tags `sanity.workflow.ts` happens to deploy — the config only locates the resource and authenticates, the same read-context model `show`/`tail` already use. This removes a self-lockout: a `trial`-only config previously could not `diagnose` or `abort` an instance in another partition (e.g. a `bench`- or `prod`-tagged one), failing with "not visible to this engine (tag mismatch)". On these commands `--tag` is now only used to disambiguate a config that spans multiple resources.
|
|
133
|
+
|
|
134
|
+
Only `deploy`, `definition diff`, and `definition delete` remain scoped to a declared deployment — they act on the authored definition set or a definition name, which (unlike an instance id) isn't unique across tags.
|
|
135
|
+
|
|
136
|
+
- df00bbb: The client's API version now comes from the engine's exported `ENGINE_API_VERSION` pin instead of a hand-copied literal, so every client bound to the engine stays on one version by construction.
|
|
137
|
+
- a0443c4: `show` no longer crashes on a workflow instance whose stage omits its `activities` array (an activity-less stage, or an older-shape / raw-client-written document). Such a stage now renders with no activities instead of throwing `activities is not iterable`.
|
|
138
|
+
- Updated dependencies [a0443c4]
|
|
139
|
+
- Updated dependencies [a0443c4]
|
|
140
|
+
- Updated dependencies [ad9b6f6]
|
|
141
|
+
- Updated dependencies [83d5924]
|
|
142
|
+
- Updated dependencies [7a655bd]
|
|
143
|
+
- Updated dependencies [d9c8179]
|
|
144
|
+
- Updated dependencies [0a7979a]
|
|
145
|
+
- Updated dependencies [df00bbb]
|
|
146
|
+
- Updated dependencies [5c69928]
|
|
147
|
+
- Updated dependencies [2f081a3]
|
|
148
|
+
- Updated dependencies [df00bbb]
|
|
149
|
+
- Updated dependencies [113a796]
|
|
150
|
+
- Updated dependencies [df00bbb]
|
|
151
|
+
- Updated dependencies [2829643]
|
|
152
|
+
- Updated dependencies [6ee9068]
|
|
153
|
+
- Updated dependencies [2829643]
|
|
154
|
+
- Updated dependencies [a0443c4]
|
|
155
|
+
- @sanity/workflow-engine@0.14.0
|
|
156
|
+
|
|
157
|
+
## 0.8.1
|
|
158
|
+
|
|
159
|
+
### Patch Changes
|
|
160
|
+
|
|
161
|
+
- 5bbc3f0: Internal refactor: functions that took 3+ positional parameters now take a single named options object. No public API or behavior change — the package's exported surface (and, for the CLI, its commands and output) is unchanged.
|
|
162
|
+
- Updated dependencies [416d4c9]
|
|
163
|
+
- Updated dependencies [4dfe72a]
|
|
164
|
+
- Updated dependencies [5bbc3f0]
|
|
165
|
+
- Updated dependencies [0bf7503]
|
|
166
|
+
- Updated dependencies [6e51913]
|
|
167
|
+
- Updated dependencies [3229f41]
|
|
168
|
+
- @sanity/workflow-engine@0.13.0
|
|
169
|
+
|
|
170
|
+
## 0.8.0
|
|
171
|
+
|
|
172
|
+
### Minor Changes
|
|
173
|
+
|
|
174
|
+
- d850aef: **BREAKING:** Workflow definitions are now immutable and content-addressed — the author no longer writes a `version`.
|
|
175
|
+
|
|
176
|
+
A definition's `version` (and a new `contentHash` fingerprint) are stamped onto the deployed _document_ at deploy time, derived from the content itself — the same envelope as `_id`/`_type`/`tag`. `defineWorkflow` no longer accepts a `version` (the authoring schema rejects it), and the `WorkflowDefinition` type no longer carries one.
|
|
177
|
+
|
|
178
|
+
`deployDefinitions` is now create-only: it hashes the authored content and compares it to the latest deployed version of that name. Identical content is a no-op (`unchanged`); any change mints the next version (`created`). It never patches a deployed version in place, so a definition can no longer change out from under the instances pinned to it. (Engine-side only — true immutability of the deployed document still requires a Content Lake guard; the engine enforces nothing.) Deploying two definitions with the same name in one batch is now rejected.
|
|
179
|
+
|
|
180
|
+
Instances pin `pinnedContentHash` alongside `pinnedVersion`, so a consumer can detect a deployed definition that has drifted from what an instance started on.
|
|
181
|
+
|
|
182
|
+
API changes:
|
|
183
|
+
- `defineWorkflow({ version })` / `WorkflowDefinition.version` removed — drop `version` from authored definitions.
|
|
184
|
+
- `DeployDefinitionResult.status` drops `'updated'` (now `'created' | 'unchanged'`); `DiffEntry.status` drops `'update'` (now `'create' | 'unchanged'`) — a content change is always a new version.
|
|
185
|
+
- `isDefinitionUnchanged` removed; the content fingerprint is now exposed as `hashDefinitionContent`. `DeployedDefinition` is exported for consumers reading deployed documents.
|
|
186
|
+
- Spawn refs (`task.subworkflows.definition.version`) are unchanged — you can still pin another definition's deployed version.
|
|
187
|
+
|
|
188
|
+
- 9519c76: **BREAKING:** Rename the structural `Task` node in the workflow DSL to `Activity`. The node holds multiple Actions, its own scoped Fields, and a status lifecycle — it is not atomic, so in process-modelling terms it is an _Activity_ (BPMN: Activity is the umbrella for work, Task the atomic kind). This frees the word "task" so it never appears in the model — "Tasks" is now purely a product/UI worklist view, not a model entity.
|
|
189
|
+
|
|
190
|
+
`Action` (the actor-fired command) is unchanged.
|
|
191
|
+
|
|
192
|
+
The rename cascades across the whole surface:
|
|
193
|
+
- Authoring: `defineTask` → `defineActivity`; the `tasks:` array on a stage → `activities:`; `Task`/`AuthoringTask` types → `Activity`/`AuthoringActivity`.
|
|
194
|
+
- Classification: `TASK_KINDS` → `ACTIVITY_KINDS`, `TaskKind` → `ActivityKind`, `deriveTaskKind`/`taskKind` → `deriveActivityKind`/`activityKind` (kind values `user`/`service`/`script`/`manual`/`receive` are unchanged). The shipped "task kinds" surface is retitled "Activity kinds".
|
|
195
|
+
- Status: `TASK_STATUSES`/`TaskStatus` → `ACTIVITY_STATUSES`/`ActivityStatus` (and the terminal-status counterparts); status _values_ are unchanged.
|
|
196
|
+
- Predicate sentinels: `$tasks` → `$activities`, `$allTasksDone` → `$allActivitiesDone`, `$anyTaskFailed` → `$anyActivityFailed`, `$requiredTasksDone` → `$requiredActivitiesDone`, `$task` → `$activity`. Authored GROQ filters referencing the old names must be updated.
|
|
197
|
+
- Persisted/wire format: the `'task'` field scope value → `'activity'`, history entry types (`taskActivated`/`taskStatusChanged` → `activityActivated`/`activityStatusChanged`), and engine result/diagnostic codes (`failed-task` → `failed-activity`, `task-not-active` → `activity-not-active`, `reset-task` → `reset-activity`, etc.).
|
|
198
|
+
- `workflow-react`: the `fireAction` argument `{task}` → `{activity}`.
|
|
199
|
+
|
|
200
|
+
Nothing referencing "task" remains in the model. This is a deliberate pre-customer breaking change to land the correct, permanent vocabulary.
|
|
201
|
+
|
|
202
|
+
- 6aa682e: **BREAKING:** Rename the `--workflow-id` filter to `--workflow-name` on `list` and `definition list`. The flag always filtered by definition name, not an id, so the new name matches both its behaviour and how definitions are referenced everywhere else (`definition show <name>`, etc.). `--workflow-id` is no longer accepted.
|
|
203
|
+
|
|
204
|
+
### Patch Changes
|
|
205
|
+
|
|
206
|
+
- Updated dependencies [5b10863]
|
|
207
|
+
- Updated dependencies [ae1434e]
|
|
208
|
+
- Updated dependencies [d850aef]
|
|
209
|
+
- Updated dependencies [9519c76]
|
|
210
|
+
- Updated dependencies [9233cd3]
|
|
211
|
+
- Updated dependencies [3ea4953]
|
|
212
|
+
- Updated dependencies [e5a862a]
|
|
213
|
+
- @sanity/workflow-engine@0.12.0
|
|
214
|
+
|
|
215
|
+
## 0.7.1
|
|
216
|
+
|
|
217
|
+
### Patch Changes
|
|
218
|
+
|
|
219
|
+
- Updated dependencies [3b8f3de]
|
|
220
|
+
- @sanity/workflow-engine@0.11.0
|
|
221
|
+
|
|
222
|
+
## 0.7.0
|
|
223
|
+
|
|
224
|
+
### Minor Changes
|
|
225
|
+
|
|
226
|
+
- fae3553: **BREAKING:** Rename the domain concept **state → fields** across the whole API and persisted data model.
|
|
227
|
+
|
|
228
|
+
"State" was too easily conflated with "stage". The typed, valued data attached to workflows, stages, and tasks is now called **fields** — clearer, and aligned with Sanity schemas: the fields on a workflow, stage, and task can have typed values. This is a clean break (no migration, no back-compat); already-deployed definitions and instances must be redeployed/recreated.
|
|
229
|
+
|
|
230
|
+
**Authoring DSL**
|
|
231
|
+
- `defineState(...)` → `defineField(...)`
|
|
232
|
+
- The `state: [...]` array on a workflow / stage / task → `fields: [...]`
|
|
233
|
+
- The `$state.<name>` GROQ scope token → `$fields.<name>`
|
|
234
|
+
- A `claim` action's `state:` reference → `field:`
|
|
235
|
+
- A `stateRead` source → `fieldRead`; its `state:` (entry name) → `field:`
|
|
236
|
+
- Op targets address the entry by `field:` instead of `state:`
|
|
237
|
+
|
|
238
|
+
**Persisted / wire format**
|
|
239
|
+
- Op type strings `state.set` / `state.unset` / `state.append` / `state.updateWhere` / `state.removeWhere` → `field.*`
|
|
240
|
+
- The stored `state[]` array on instances, stage entries, and task entries → `fields[]`
|
|
241
|
+
- `startInstance({ initialState })` → `startInstance({ initialFields })`
|
|
242
|
+
|
|
243
|
+
**Types & functions** (engine)
|
|
244
|
+
|
|
245
|
+
`StateEntry`→`FieldEntry`, `AuthoringStateEntry`→`AuthoringFieldEntry`, `ResolvedStateEntry`→`ResolvedFieldEntry`, `InitialStateValue`→`InitialFieldValue`, `StateKind`→`FieldKind`, `StateValueMap`→`FieldValueMap`, `StateScope`→`FieldScope`, `StoredStateRef`→`StoredFieldRef`, `STATE_SLOT_DISPLAY`→`FIELD_SLOT_DISPLAY`, `EditStateArgs`→`EditFieldArgs`, `EditStateTarget`→`EditFieldTarget`, `EditStateDeniedError`→`EditFieldDeniedError`, `ConcurrentEditStateError`→`ConcurrentEditFieldError`, `RequiredStateNotProvidedError`→`RequiredFieldNotProvidedError`, and the `editState` verb → `editField`.
|
|
246
|
+
|
|
247
|
+
Unchanged: runtime/lifecycle instance "state" (stage moves, `WorkflowStateDivergedError`, the projected instance snapshot), the `field`/`fields` JSON-matching primitives in `updateWhere`/`removeWhere` predicates and object Sources, and the Content Lake release `state`.
|
|
248
|
+
|
|
249
|
+
### Patch Changes
|
|
250
|
+
|
|
251
|
+
- Updated dependencies [fae3553]
|
|
252
|
+
- @sanity/workflow-engine@0.10.0
|
|
253
|
+
|
|
254
|
+
## 0.6.1
|
|
255
|
+
|
|
256
|
+
### Patch Changes
|
|
257
|
+
|
|
258
|
+
- Updated dependencies [2e4c980]
|
|
259
|
+
- Updated dependencies [fd6b866]
|
|
260
|
+
- @sanity/workflow-engine@0.9.0
|
|
261
|
+
|
|
262
|
+
## 0.6.0
|
|
263
|
+
|
|
264
|
+
### Minor Changes
|
|
265
|
+
|
|
266
|
+
- d798521: Align CLI output with Sanity CLI conventions.
|
|
267
|
+
- Instance display (`show`, `diagnose`, `fire-action`): the boxed header is
|
|
268
|
+
replaced by a plain `styleText` key-value block (bold workflow + id title,
|
|
269
|
+
dim aligned rows) and task states show colored status glyphs. An aborted
|
|
270
|
+
instance shows its abort line in place of a misleading green "Completed".
|
|
271
|
+
`diagnose` and `fire-action` bodies use the same Title-Case section
|
|
272
|
+
headings as `show` (e.g. `Tasks`, `Exit transitions`, `Why it's stuck`,
|
|
273
|
+
`Suggested fix`, `Actions on stage '…'`).
|
|
274
|
+
- `diagnose`: the rendered "Suggested fix" block now lists only remediations
|
|
275
|
+
the CLI can actually run (`move-stage`, `abort`); planned verbs the engine
|
|
276
|
+
names but the CLI can't yet perform are no longer shown there (they remain
|
|
277
|
+
in `--json`).
|
|
278
|
+
- `definition show`: drops the boxed header for the same plain `styleText`
|
|
279
|
+
key-value block (bold name + version title, dim `Title` / `Description` /
|
|
280
|
+
`Tag` rows — the deploy partition is now shown), and the stage/task/action
|
|
281
|
+
tree uses a bold `Stages` heading with dim secondary text and a cyan
|
|
282
|
+
`[initial]` marker. Long descriptions now soft-wrap in the terminal instead
|
|
283
|
+
of being pre-wrapped to a fixed box width.
|
|
284
|
+
- `list`: drops the `failed` count column and the never-implemented `--subject`
|
|
285
|
+
flag; adds a relative `Updated` column (`lastChangedAt`) and a `Tag` column
|
|
286
|
+
(the listing spans partitions); adds an optional `--tag` filter to match
|
|
287
|
+
`definition list`; colors the `Status` column; orders by most-recently-changed.
|
|
288
|
+
- `definition list`: narrows the table — folds the version into the `Workflow`
|
|
289
|
+
column as `name vN` (this CLI's identifier format), drops the redundant
|
|
290
|
+
`Definition ID` column (the doc `_id` is just `tag.name.vN`, which the
|
|
291
|
+
Workflow + Tag columns already show, and no command takes a raw `_id`), and
|
|
292
|
+
shortens the count headers (`Total stages` → `Stages`, `Instances in flight`
|
|
293
|
+
→ `In flight`, `Total instances` → `Instances`).
|
|
294
|
+
- `definition diff`: the report colors move from `picocolors` to `styleText`
|
|
295
|
+
and the summary heading uses the shared `sectionHeader` (`Summary:`) for
|
|
296
|
+
consistency with the rest of the CLI.
|
|
297
|
+
- Write verbs (`abort`, `move-stage`, `definition delete`), `tail`, and the
|
|
298
|
+
shared `lib/fail` / `lib/ops-report` helpers move their colors from
|
|
299
|
+
`picocolors` to `styleText` too. With that the `picocolors` dependency is
|
|
300
|
+
removed — the CLI now colors output entirely through `node:util`.
|
|
301
|
+
- Timestamps now go through `date-fns` like the Sanity CLI — absolute
|
|
302
|
+
`yyyy-MM-dd HH:mm:ss` for detail views (`show`, `diagnose`, `tail`), relative
|
|
303
|
+
"… ago" for list tables. A missing or unparseable timestamp falls back to its
|
|
304
|
+
raw value rather than throwing, so one bad document field can't crash a command.
|
|
305
|
+
- New `lib/ui.ts` mirrors the Sanity CLI's `sectionHeader` / `formatKeyValue`
|
|
306
|
+
helpers so they fold into the shared ones when this CLI merges in.
|
|
307
|
+
- Bumps the `engines.node` floor to `>=20.12`, the first release where
|
|
308
|
+
`node:util`'s `styleText` (which now owns all coloring) is available.
|
|
309
|
+
|
|
310
|
+
- 8bf467e: Add a definition `role` and a `required` flag on state entries — so spawn-only child workflows can be kept out of standalone-start surfaces, and a load-bearing init slot fails fast instead of silently defaulting.
|
|
311
|
+
- **`role: 'workflow' | 'child'` on a definition (default `'workflow'`).** A `'child'` definition is spawn-only — instantiated by a parent's `task.subworkflows`, never started cold by a human. The exported `isStartableDefinition(definition)` predicate (plus the `WorkflowRole` type) is the single place that decides "can a human start this", so every consumer filters its start picker the same way. Advisory: the engine does **not** refuse a `startInstance` on a `'child'` def — it's a discoverability flag, not a gate. `@sanity/workflow-cli`'s `definition list` gains a **Startable** column derived from the predicate.
|
|
312
|
+
- **`required?: boolean` on a state entry — the start/spawn counterpart to action-param validation.** A missing `init`-sourced value previously resolved silently to `null`/`[]`, which is what let a cold-started child come up structurally incomplete (a review with no subject, no assignee). A `required` entry the caller doesn't supply — via `initialState` at start, or the parent's `subworkflows.with` at spawn — now throws the exported `RequiredStateNotProvidedError` and creates nothing, exactly as a missing `required` action param already does. Valid only on a workflow-scope `init` entry; `required` on any other scope or source is a deploy error (`defineWorkflow` rejects it with the offending field path).
|
|
313
|
+
|
|
314
|
+
The two compose: `role` keeps a child out of pickers; `required` stops the engine from constructing an incomplete instance if a UI (or a human) starts one anyway.
|
|
315
|
+
|
|
316
|
+
### Patch Changes
|
|
317
|
+
|
|
318
|
+
- Updated dependencies [c298ee2]
|
|
319
|
+
- Updated dependencies [8131dd5]
|
|
320
|
+
- Updated dependencies [8bf467e]
|
|
321
|
+
- @sanity/workflow-engine@0.8.0
|
|
322
|
+
|
|
323
|
+
## 0.5.2
|
|
324
|
+
|
|
325
|
+
### Patch Changes
|
|
326
|
+
|
|
327
|
+
- e618a5f: Fix the release pipeline so `workflow-cli` can publish via CI. `oclif manifest`
|
|
328
|
+
`import()`s the package's compiled commands, which import the built
|
|
329
|
+
`@sanity/workflow-engine`; running it inside the publish-time `prepack` depended
|
|
330
|
+
on a sibling's `dist` being present at that moment and failed `changeset publish`
|
|
331
|
+
deterministically. The manifest is now generated as an explicit release step
|
|
332
|
+
after the full workspace build and dropped from `prepack` — it stays gitignored
|
|
333
|
+
and is still shipped via the package's `files`.
|
|
334
|
+
|
|
335
|
+
## 0.5.1
|
|
336
|
+
|
|
337
|
+
### Patch Changes
|
|
338
|
+
|
|
339
|
+
- 07134ae: Give the `StubCommand` exit-code test generous timeout headroom. A full `Config.load` is fast alone but gets starved past the 5s default on a cold CI runner running every package's suite in parallel, so the test flaked with a timeout.
|
|
340
|
+
|
|
341
|
+
## 0.5.0
|
|
342
|
+
|
|
343
|
+
### Minor Changes
|
|
344
|
+
|
|
345
|
+
- fb3c98a: Make the workflow CLI publishable — both metadata and runtime.
|
|
346
|
+
|
|
347
|
+
Metadata: the package drops `private` / `UNLICENSED` and gains the publish fields the other published packages carry — an `MIT` license, `repository`, `homepage`, `bugs`, `author`, `keywords`, an `engines` floor, and a `publishConfig` that resolves the published `exports` to `dist/` only (stripping the `development` / `source` conditions used for in-repo source resolution). Published with `access: restricted`, matching the rest of the workspace.
|
|
348
|
+
|
|
349
|
+
Runtime: the previous build was a library bundle (one `dist/index.js` re-exporting `execute`) and never emitted the oclif commands, so a published host had nothing to run. The build now compiles the whole `src/` tree with `tsc` — emitting `dist/commands/**` and rewriting the repo's explicit `.ts` import specifiers to `.js` via `rewriteRelativeImportExtensions` — and the package ships a production `bin/run.js`, an `oclif.manifest.json` generated at pack time, and an ESM-only `exports` map. `oclif.commands` points at `./dist/commands`; dev (`bin/dev.js`) keeps loading the TS sources via oclif's dist→src resolution.
|
|
350
|
+
|
|
351
|
+
### Patch Changes
|
|
352
|
+
|
|
353
|
+
- 32f5e64: Name the remediations that would unstick a stuck instance from the engine, not the CLI.
|
|
354
|
+
|
|
355
|
+
`workflow.diagnose` now returns `remediations` alongside the diagnosis — a `SuggestedRemediation[]`, empty unless the instance is `stuck`. Each entry names a surface-neutral `RemediationVerb` (`retry-effect` | `drain-effects` | `reset-task` | `set-stage` | `abort`), whether it's runnable as an engine operation today (`available`), and a one-line rationale. The new `remediationsFor` reasoning plus the `SuggestedRemediation` / `RemediationVerb` types are exported. Previously the cause→fix mapping — including which repair verbs exist versus are still planned — lived only in the CLI, so every other consumer (MCP, a future UI) would have had to re-derive it.
|
|
356
|
+
|
|
357
|
+
The CLI `diagnose` command now renders its "suggested fix" block from these remediations — a not-yet-runnable verb is dimmed and marked `(planned)` — instead of hardcoding the prose, and includes `remediations` in `--json` output.
|
|
358
|
+
|
|
359
|
+
- df7582f: Fix two stacked bugs that let a threshold-gated workflow auto-advance past a review it couldn't actually evaluate.
|
|
360
|
+
- **Filters fail closed on unevaluable operands.** A `task.filter` / `transition.filter` that evaluates to GROQ `null` (a referenced operand was missing or incomparable, e.g. `$state.subject.amount > 10000` when the subject isn't loaded) is no longer coerced to `false`. A `null` gate previously _skipped_ the task / fell through the transition — fail-open. Now an unevaluable `task.filter` keeps the task in scope (the stage holds rather than cascading through), an unevaluable transition filter halts selection, and the undecidability is recorded on `TaskEntry.filterEvaluation.unevaluable` so the audit trail distinguishes "genuinely below threshold" from "couldn't read the field". Unevaluability also propagates through nullary predicates (an unevaluable predicate binds `null`, not `false`).
|
|
361
|
+
- **Content hydration is draft-preferring.** When an instance has no explicit release perspective, content reads now use a drafts-preferring perspective (drafts overlay published) instead of a published-only point read — uniformly across `doc.ref`/`doc.refs` hydration, `type: "query"` state-entry resolution, and `subworkflows.forEach` discovery (single-sourced as `DEFAULT_CONTENT_PERSPECTIVE`). A subject that exists only as a draft — or whose in-flight edits live in the draft — is now what filters evaluate. Instance / ancestor / `system.release` documents continue to read raw. The reactive App SDK adapter (`@sanity/workflow-sdk`) matches: a content doc with no release is read under the `drafts` perspective instead of relying on the SDK's default, so a reactive session and the engine cascade resolve the same draft-aware view. (The Studio adapter already preferred `version ?? draft ?? published`.)
|
|
362
|
+
- **Diagnostics tell an undecidable hold from a dead-end.** `TransitionEvaluation` now carries `unevaluable`, and `diagnose` reports a new `transition-unevaluable` stuck cause when every task is resolved but an exit filter can't be evaluated (a recoverable hold — the cascade re-fires once the operand resolves) rather than mislabeling it the permanent `no-transition-fires` routing dead-end. `@sanity/workflow-cli`'s `diagnose` renders the distinct cause.
|
|
363
|
+
- **Single-document writes commit `visibility: 'sync'`.** `create` and `patch().commit()` now set `visibility: 'sync'` explicitly (via the new `WorkflowCommitOptions`) so the engine never reads a stale value back through a query. Adds `WorkflowCommitOptions` / `WorkflowVisibility` to the public client surface.
|
|
364
|
+
|
|
365
|
+
- 129258c: Add task `requirements` — a readiness axis for visible-but-not-yet-executable tasks, distinct from ACL and guards.
|
|
366
|
+
|
|
367
|
+
A task definition can now declare `requirements: { <name>: <groq-condition> }`: preconditions over the rendered scope that gate _executability_ without affecting visibility. While a requirement is unmet the task stays visible, and every action on it is reported disabled with a new `requirements-unmet` verdict that names the unmet requirements; `TaskEvaluation.unmetRequirements` summarises the same set at the task level so a consumer can explain why the whole task is gated. Requirements are all-of (express any-of inside a single condition), evaluated in the same scope as `filter`, and — like every engine-side check — advisory; the lake remains the enforcement point.
|
|
368
|
+
|
|
369
|
+
Diagnostics gain a `blocked` state: an active task held by an unmet requirement is reported as visible-but-not-yet-executable (healthy and transient), distinct from `stuck`, and a requirements-held task no longer masks an actionable sibling in the `waiting` verdict.
|
|
370
|
+
|
|
371
|
+
The CLI `fire-action` listing and the MCP server's disabled-reason copy both render the new reason; the CLI `diagnose` command renders the new `blocked` state.
|
|
372
|
+
|
|
373
|
+
- Updated dependencies [ef927bc]
|
|
374
|
+
- Updated dependencies [32f5e64]
|
|
375
|
+
- Updated dependencies [df7582f]
|
|
376
|
+
- Updated dependencies [ed4174c]
|
|
377
|
+
- Updated dependencies [129258c]
|
|
378
|
+
- @sanity/workflow-engine@0.7.0
|
|
379
|
+
|
|
380
|
+
## 0.4.1
|
|
381
|
+
|
|
382
|
+
### Patch Changes
|
|
383
|
+
|
|
384
|
+
- Updated dependencies [c6d1762]
|
|
385
|
+
- @sanity/workflow-engine@0.6.0
|
|
386
|
+
|
|
387
|
+
## 0.4.0
|
|
388
|
+
|
|
389
|
+
### Minor Changes
|
|
390
|
+
|
|
391
|
+
- e2a6d5d: Implement `definition delete` (previously a stub): delete a deployed workflow definition by name — every version by default, one via `--version`. Refuses while non-terminal instances exist unless `--cascade` aborts them first (instances are aborted in place, never deleted; `--reason` lands on each abort's history entry), and refuses while any surviving deployed definition spawn-references the target. Reports the deleted versions, cascade-abort count, and orphaned-guard cleanup.
|
|
392
|
+
- b8e364d: Add a `definition diff` command that diffs an in-code definition against the deployed version — the latest deployed version of the workflow by default (so a version bump shows what actually changed), or a specific one via `--version`. Remove the `definition enable` and `definition disable` stubs; no engine semantics back them yet.
|
|
393
|
+
- 4805d29: Add the `diagnose` command: a read-only check that explains why a workflow instance is or isn't progressing, and what would unstick it. It runs a single `workflow.evaluate` and classifies the instance as `progressing`, `waiting` (an active task awaiting a human action — healthy, not stuck), `completed`, `aborted`, or `stuck` with a specific cause (a failed effect, a hung effect, a failed task, or no exit transition firing), printing the evidence and a suggested fix. Supports `--json` for scripting and `--tag` for the environment partition.
|
|
394
|
+
- 1cd93d2: Add the `fire-action` command — fire an action on an instance to unstick a waiting task. Omit `--action` to list the actions available on the current stage (with their allowed/disabled state and params); pass `--task` + `--action` to fire one, with `--param key=value` for action params and `--as <userId>` / `--as-role <role>` to attribute the fire to a real user so assignee- and role-gated filters pass. Honors `--tag` and `--json`. The shared "ops applied" report block is factored out and reused by `move-stage`.
|
|
395
|
+
|
|
396
|
+
### Patch Changes
|
|
397
|
+
|
|
398
|
+
- dbc4afa: Move the instance-reasoning behind the CLI's read commands into the engine so every consumer shares one implementation rather than re-deriving it. The engine now exports the stuck-instance classifier (`diagnoseInstance` with `Diagnosis` / `StuckCause` / `DiagnoseInput`, plus `abortReason`, `openStage`, `assigneesOf`, `diagnoseInputFromEvaluation`), the available-actions projection (`availableActions` with `AvailableAction`), and definition-diff classification (`diffEntry` / `computeDiffEntries` with `DiffEntry` / `DeployTarget`) — all reusing the engine's own doc-id minting and no-op verdict. Two instance-id-keyed verbs compose this with `evaluate`: `workflow.diagnose` and `workflow.availableActions` (also on the `Engine` wrapper).
|
|
399
|
+
|
|
400
|
+
The CLI's `diagnose`, `fire-action`, `deploy`, and `definition diff` commands keep only their rendering and now call the engine for the reasoning, and the MCP's `get_workflow_state` projects its action verdicts through the same shared `availableActions`. No behavioural change to the CLI or MCP surfaces.
|
|
401
|
+
|
|
402
|
+
- 4805d29: Fix the boxed instance header (shared by `show` and `diagnose`) so the first row's right border aligns with the rest. The id row now uses a plain `instance:` label instead of a width-ambiguous `ℹ` symbol that `boxen`/`string-width` mis-measured, which had been drifting that line's border.
|
|
403
|
+
- Updated dependencies [dbc4afa]
|
|
404
|
+
- Updated dependencies [e2a6d5d]
|
|
405
|
+
- Updated dependencies [aa87a1c]
|
|
406
|
+
- @sanity/workflow-engine@0.5.0
|
|
407
|
+
|
|
408
|
+
## 0.3.0
|
|
409
|
+
|
|
410
|
+
### Minor Changes
|
|
411
|
+
|
|
412
|
+
- 4b5f59a: Wire the `abort` command to the engine's new `workflow.abortInstance`: hard-stop an in-flight instance with an optional `--reason` recorded in history. Already-terminal instances report a warning instead of erroring. Aborted instances surface across the read commands too — `list` shows an `aborted` status (instead of `completed`), and `show`'s header carries the abort timestamp plus the recorded reason.
|
|
413
|
+
- fcf938a: Migrate to the new workflow authoring DSL: name identity (`name` /
|
|
414
|
+
`initialStage` / `currentStage` / `instance.definition`), bare state kinds,
|
|
415
|
+
type-tagged sources, bare op types with `{scope, state}` targets, GROQ-string
|
|
416
|
+
conditions and effect bindings, `predicates` as a name→GROQ map, explicit task
|
|
417
|
+
`activation`, action `status` sugar, claim pairs and audit ops, and
|
|
418
|
+
`subworkflows` fan-out. The example definitions showcase the new sugar; the
|
|
419
|
+
CLI and MCP projections read the new stored shapes (terminal = stage with no
|
|
420
|
+
transitions); the React controller's `fireAction` takes `task` instead of
|
|
421
|
+
`taskId`; the MCP wire names things what they are — `definition` (the
|
|
422
|
+
definition's `name`) on the `list_workflow_instances` filter and instance
|
|
423
|
+
projections, and `task` / `action` (names, not ids) on `fire_action` and
|
|
424
|
+
the per-task projections, replacing `workflow_id` / `task_id` /
|
|
425
|
+
`action_id`.
|
|
426
|
+
|
|
427
|
+
### Patch Changes
|
|
428
|
+
|
|
429
|
+
- Updated dependencies [4b5f59a]
|
|
430
|
+
- Updated dependencies [fcf938a]
|
|
431
|
+
- Updated dependencies [6c4e0a0]
|
|
432
|
+
- Updated dependencies [12e23b0]
|
|
433
|
+
- Updated dependencies [12e23b0]
|
|
434
|
+
- @sanity/workflow-engine@0.4.0
|
|
435
|
+
|
|
436
|
+
## 0.2.0
|
|
437
|
+
|
|
438
|
+
### Minor Changes
|
|
439
|
+
|
|
440
|
+
- 440be47: Add a `definition show` command that displays a single deployed workflow definition. Pass a workflow id to show its latest version, or pin one with `--version`, and scope to an environment with `--tag`. Renders a boxed header (workflow id, version, title, description) followed by a stage → task → action breakdown, marking the initial stage and each stage's kind.
|
|
441
|
+
|
|
442
|
+
### Patch Changes
|
|
443
|
+
|
|
444
|
+
- 0c6ccde: Extract shared definition-query primitives so the "tag-scoped, latest-or-pinned `workflow.definition`" query lives in one place instead of being hand-written at each call site.
|
|
445
|
+
|
|
446
|
+
The engine now exports two reusable GROQ primitives:
|
|
447
|
+
- `WORKFLOW_DEFINITION_TYPE` / `WORKFLOW_INSTANCE_TYPE` — the lake document-type constants, replacing scattered string literals.
|
|
448
|
+
- `tagScopeFilter(param?)` — the tag-partition GROQ predicate (`count(tags[@ in $engineTags]) > 0`), defaulting to the `engineTags` parameter the `workflow.query` guard expects.
|
|
449
|
+
|
|
450
|
+
Internally these compose into a single `definitionLookupGroq` selector for the "latest-or-pinned definition" query. The engine's own lookups (`deploy`, `spawn`, `drain`) and the CLI (`definition show`/`list`, `list`, `deploy`) now build on these primitives, and every tag-scoped query in those paths standardizes on the `$engineTags` parameter — removing the prior `$tags`/`$engineTags` drift.
|
|
451
|
+
|
|
452
|
+
- Updated dependencies [41ddd80]
|
|
453
|
+
- Updated dependencies [0c6ccde]
|
|
454
|
+
- @sanity/workflow-engine@0.3.0
|
|
455
|
+
|
|
456
|
+
## 0.1.0
|
|
457
|
+
|
|
458
|
+
### Minor Changes
|
|
459
|
+
|
|
460
|
+
- e24fe7f: Add a `definition list` command that lists deployed workflow definitions as a table. Filter with `--workflow-id`, or scope to an environment with `--tag` (omit `--tag` to list across all partitions). Each row shows the definition's stage count plus in-flight and total instance counts.
|
|
461
|
+
|
|
462
|
+
### Patch Changes
|
|
463
|
+
|
|
464
|
+
- eff2a77: Commands that contact the dataset (`deploy`, `list`, `show`, `tail`, `move-stage`) now fail with a clean, single-line error when a required `SANITY_*` env var is missing, instead of dumping a raw Node stack trace. Missing client config is funnelled through the same `fail()` path that `WORKFLOW_*` config validation already uses.
|
|
465
|
+
- eff2a77: `deploy` no longer hardcodes its definitions to `@sanity/workflow-examples`. The
|
|
466
|
+
source is now resolved at runtime from a required `WORKFLOW_DEFS` env var — a
|
|
467
|
+
module path or package name whose `allDefinitions` export holds the
|
|
468
|
+
`WorkflowDefinition[]` to deploy — so the CLI is agnostic about which
|
|
469
|
+
definitions it ships. There is no default: an unset source fails hard rather
|
|
470
|
+
than silently falling back to a built-in set. This also fixes a latent bug
|
|
471
|
+
where a built/published CLI would throw, since `@sanity/workflow-examples` was only
|
|
472
|
+
ever a dev dependency.
|
|
473
|
+
- 9d434a1: `deploy` and `move-stage` take a `--tag` flag selecting the engine environment partition (e.g. `--tag prod`). The tag resolves `--tag` → `WORKFLOW_TAG` env → required: commands fail hard when no tag is set rather than silently defaulting. This replaces the previous comma-separated `WORKFLOW_TAGS` env var with a single `WORKFLOW_TAG`.
|
|
474
|
+
- Updated dependencies [d04cbea]
|
|
475
|
+
- Updated dependencies [870188e]
|
|
476
|
+
- Updated dependencies [a4f6d81]
|
|
477
|
+
- Updated dependencies [eff2a77]
|
|
478
|
+
- Updated dependencies [ce6960d]
|
|
479
|
+
- Updated dependencies [dff88ff]
|
|
480
|
+
- Updated dependencies [782272a]
|
|
481
|
+
- Updated dependencies [2b800a8]
|
|
482
|
+
- Updated dependencies [0432670]
|
|
483
|
+
- Updated dependencies [53a0598]
|
|
484
|
+
- Updated dependencies [c2ad7a9]
|
|
485
|
+
- @sanity/workflow-engine@0.2.0
|