@sanity/workflow-studio-plugin 0.2.0 → 0.4.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 CHANGED
@@ -1,5 +1,186 @@
1
1
  # @sanity/workflow-studio-plugin
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0f50aed: Activity rows carry their tags beside the title instead of pinned to the row's end, as tight default-chrome badges that keep the row height and explain themselves on hover: "Automated" (default tone) on truly hands-off activities, and "Blocked" (caution tone) when every rendered action is disallowed. The "Awaiting decision" and "Failed" chips are gone — a multi-way decision reads as open work, and a failed activity's status glyph carries the outcome. The row's end cluster keeps only controls: terminal actions and the assignees.
8
+ - 0f50aed: Activity status glyphs get a clearer vocabulary. Active rows wear the dashed dial (EmptyIcon) instead of an outline circle that read as an unchecked checkbox. Done rows wear a new filled checkmark-circle — a filled counterpart @sanity/icons doesn't ship, drawn to the set's filled-variant conventions with the outline icon's exact checkmark knocked out — rendered neutral rather than green, since completion is a fact, not a success banner. Failed rows wear ErrorFilledIcon in the critical tone, the one toned glyph in the set.
9
+ - c8fa0b1: **BREAKING:** Remove the per-mapping `mandatory` option and the
10
+ `MandatoryWorkflowGate` it drove. A content type "requiring" a workflow is
11
+ extrinsic to the workflow definition and unenforceable from the client — any
12
+ raw write bypasses the Studio — so form-gating is dropped in favour of
13
+ `autoStart`.
14
+
15
+ Add `autoStart`: a plugin option mapping document `_type` to the deployed
16
+ workflow definition name(s) to start when an editor opens a fresh document of
17
+ that type, so the document is born with its workflow. The gate materializes the
18
+ document (like `performStart`, in the Studio's active perspective — the selected
19
+ release's version or the draft) and seeds it as each workflow's subject; when
20
+ several workflows share an input beyond the subject, one mandatory dialog
21
+ collects that union once and feeds each (started silently when nothing is
22
+ needed), and the form is revealed once the instance is live. Several workflows
23
+ for one type start in parallel, best-effort — a failure of one is surfaced
24
+ without rolling back the others. Studio-only — a floor, not enforcement.
25
+ Accepts a function form to vary the map by workspace name or schema.
26
+
27
+ - 7276702: Editor-facing copy no longer leaks implementation vocabulary. Failure toasts show the human reason without the error class name (`describeError` maps typed engine rejections to their reason sentences); the document-action lock title names only the owning workflow, never guard machine names; activity chip hints drop the "settle"/"fired" jargon; the automation row's hover lead reads "Runs automatically"; the pending-work badge counts "automations" instead of "effects" and lists each queued effect on hover — declared title, or the registry name in code face when untitled; the superseded-definition badge reads "Older version"; the first-evaluation row reads "Loading…"; the unreadable-definition notice drops "definition"/"raw names"; field consequence hints say "set off automatic work" and "Saving will advance"; and the start-success toast shows the stage's declared title instead of its name.
28
+
29
+ An expanded Workflows-view section also gets breathing room below its body before the next section's header; collapsed sections keep their tight spacing. The Overview tab's empty state and the no-workflow pane state (previously a bare line with one start button per mapping) render in the same bordered card as the For-me tab's ("No active workflows" with a timeline icon), carrying the same "Start workflow" control as the header's "+" — button or menu, with its full gating and hints; when no mapping is startable the card carries no action row. Failed action fires log the raw error to the console — the toast keeps only the editor-facing reason. Empty-state and empty-list copy drops trailing full stops (interface copy, not prose); reason sentences keep theirs.
30
+
31
+ When a workflow completes, the spine's current-stage chip wears a checkmark instead of the stage glyph, and its hover card shows "Completed at …" (the instant the terminal stage was entered). Aborted instances keep the plain chip — abort is not a finish.
32
+
33
+ Icon-only buttons that had only an aria-label now hover-hint it: the header "+" menu face ("Start a workflow" / its label override), the instance overflow menu ("More views"), the tool's filter toggle ("Filter"), task-group menu ("Group actions"), and the instance-detail back arrow ("Back to workflows").
34
+
35
+ Every toast the plugin pushes is closable — an editor can dismiss one instead of waiting out its timeout.
36
+
37
+ - 0f50aed: The "N automations pending" badge (and its hover list of queued effects) is removed from every surface that showed it: the Workflows-view instance accordion header, the tool dashboard rows, and the instance detail header.
38
+
39
+ The instance status chip now flags only the aborted outcome: completed instances wear no chip (done is not an alert), and the tool dashboard's in-flight rows drop the current-stage chip the status badge used to carry. `InstanceStatusBadge` is renamed `AbortedBadge` accordingly.
40
+
41
+ - 0f50aed: The For me tab renders one flat list of assigned tasks — activity rows and to-do items across every instance — instead of nesting them in per-instance accordion groups. With no group header naming the workflow, each row carries a muted "workflow › stage" breadcrumb (chevron-separated) beside its label, which truncates to an ellipsis when space runs short. Activity and to-do labels now always truncate instead of wrapping the row taller.
42
+ - 0f50aed: Settled activities stay in the For me list as dimmed receipts, the same way checked-off to-do items stay struck through — finishing an activity reads as an acknowledgment instead of the row vanishing. Receipts never count toward the "For me" badge or the "N assigned tasks" metric, and they clear when the stage advances.
43
+ - cd03973: **BREAKING:** Reject initial workflow field values that cannot be consumed and expose structured preflight issues.
44
+
45
+ Calls that supplied unknown, wrong-kind, non-input, non-workflow-scope, or duplicate initial field rows previously succeeded while discarding those rows. They now fail before creating an instance with structured remediation details.
46
+
47
+ Deploy also rejects `spawn.with` keys that the resolved child definition cannot consume because the workflow field is missing or is not input-sourced. `SpawnContractsInvalidError` exposes every rejected parent/child row for machine-readable remediation.
48
+
49
+ - 0f50aed: The Workflows view's "Active Workflows" and "Finished Workflows" headings carry a muted count of their instances, in the exact treatment the "For me" tab count uses — and like it, a zero shows no count.
50
+ - b1d6801: **BREAKING:** `WorkflowMapping.subjectGdrType` and `WorkflowMapping.subjectKind` are removed. The subject reference's document type is derived from the row's `docType` — the subject is always the document the flow was opened from, whose schema type is `docType` by construction, so `subjectGdrType` could only ever restate that or misdescribe the subject; `subjectKind` was a required field nothing consumed. Delete both fields from each mapping row — rows that stamped `subjectGdrType` with their `docType` (the only correct value) behave identically.
51
+
52
+ Mapping validation now checks the document types a row's start would seed: a local `doc.ref`/`doc.refs` value whose GDR `type` the Studio schema doesn't declare as a content document type is rejected. The seeded type is what subject previews resolve against, so a type the schema can't preview — including the intrinsic `document` base, which resolves in the schema registry but carries no preview config — silently rendered every subject pill as "Untitled". Foreign-resource refs are exempt (their types live in another resource's schema). The verdict surfaces like other mapping issues: a console error plus a blocked start row.
53
+
54
+ - 0f50aed: Field pills sit transparent at rest — outlined only — and light their regular background on hover and press, so the pill rows read quieter until pointed at. One chrome drives every field pill, workflow- and stage-scope alike.
55
+ - 0f50aed: The Overview section's stage card leads with the spine alone. The spine band sits on a muted face so it reads as chrome rather than content; non-current stage pills render transparent on it with a hairline ring, and no pill changes background on hover — the hover card is a pill's one response. The current-stage pill is a primary-toned card with a deeper inset, carrying the round as a muted note after its label ("Round N", second visit on), and its hover card shows when the stage was entered ("Entered …"), the same way past stages show their exit. The stage header under the band ("<title> · Current stage · Round N") is gone — the spine now carries everything it said. The form strip renders the current stage as the chip's bare face — glyph and title without the pill — so the strip keeps its slim line height.
56
+ - 0f50aed: The Workflows-view spine band renders on a neutral-toned card instead of the default-toned one.
57
+ - 0f50aed: The spine pill's hover card is split in two by a full-bleed hairline: the stage title and its authored description above, live run state below (advance hint, history stamp). Hover hints gain a `flush` content mode for this — the content owns all padding so a divider can reach the tooltip's edges.
58
+
59
+ The advance hint renders on a primary-toned inset card, and on a conditionally-gated single-transition stage it now phrases the actual conditions as a live condition checklist read from the evaluation's transition insight, adding an undecidable-hold note when the `when` evaluated to GROQ null (a value it depends on is missing). Without a live evaluation it keeps the generic "when its conditions are met" phrasing.
60
+
61
+ History stamps drop the seconds and read relative-first, the absolute instant on its own line ("Entered about 3 hours ago" over "16 Jul 2026, 13:43"). The terminal stage a workflow finished in stamps "Completed"; a previously-visited stage that lies ahead again after a send-back shows no stamp at all — a past date there would read as schedule, not history. The activity count is gone.
62
+
63
+ - 0f50aed: A branching stage's hover card now shows an advance hint for its forward route — the transition targeting the next stage in authored order, the node the spine draws beside it — phrased with the same live condition list as a single-transition stage. Sibling routes (send-backs, detours) stay undrawn, matching the band's linear reading. No hint renders when no route targets the authored-adjacent stage or the stage is authored last. The phrased conditions are what the forward route requires; the engine still fires the first truthy transition in declaration order.
64
+
65
+ The advance card also drops its leading arrow, renders the target stage name in medium weight, and lists conditions as neutral bullets — no ✗/✓ marks, and an all-of root's "All of:" label is hoisted since the card's "when:" lead already carries the conjunction. The stage's authored description renders in italics, so it reads as description rather than a statement about the run.
66
+
67
+ - 5cd8ffd: **BREAKING:** Effect handlers now receive each host's concrete Sanity client unchanged, preserving its complete runtime and type surface. Handler traffic is no longer automatically tagged as `workflow.effect` or pinned to the engine API version; handlers own that configuration.
68
+ - 0f50aed: Hovering a document-strip line now previews the user's open assigned tasks under an "Assigned tasks" heading — bare task names behind their status faces (glyph or read-only checkbox), with no action buttons, assignee controls, or breadcrumbs: the glance names the work, and the view the line opens carries the full context. Settled receipts don't earn a preview — they stay in the For me tab. The glance caps at three rows with an "and N more" tail and rides a wider tooltip cap so long names keep room. With nothing open, the tooltip keeps its "Open the Workflows view" affordance copy plus a "Nothing here is assigned to you" note once the user's identity has resolved to back that claim.
69
+ - 0f50aed: The form strip's assigned-task slot shows an inline spinner while identity and evaluations are still landing, instead of the "Loading…" text. The spinner sits outside the line's clickable card, so a cursor parked on it doesn't light the hover face; the count and the stale-window "Updating…" text stay inside as before.
70
+ - 5244335: **BREAKING:** Require Sanity Studio v6. The Studio validation harness now installs the workflow CLI alongside the plugin and builds that combined package set, guarding the shared Vite 8 toolchain.
71
+ - 55a54b3: Surfaces understand the new `subject` field kind. Studio plugin: the start dialog's default subject seed lands on a definition's `subject`-kind entry whatever it is named (the doc.ref-named-`subject` convention stays the fallback), subject entries get the document picker / read-only face / state-panel preview / document pill, and mapping validation checks the subject entry's `types` facet. MCP: the subject lookup behind title enrichment prefers the `subject`-kind entry and keeps the name convention as fallback; the authoring guide teaches the kind. Test bench — **BREAKING:** `subjectField` now builds a `subject`-KIND entry value (matching its name and the engine's subject rule); a definition declaring the doc.ref convention needs the new `docRefField(documentId, {name})` instead. `instancesForSubject` matches both single-ref kinds.
72
+ - b82bda4: Add the opt-in `$subjectHasInFlightInstance` start variable for composing subject-exclusive visibility and permission rules.
73
+ - 0f50aed: An activity-scope to-do item's breadcrumb now ends with its activity's title ("workflow › stage › activity"), naming the parent that a flat list can't show. When a row runs out of room, the breadcrumb yields before the title — task names keep their space and the context truncates first.
74
+ - 4490442: Add inclusive validation.min/max bounds for workflow string, text, and number declarations, with Studio input constraints and MCP authoring guidance.
75
+ - 1540dce: **BREAKING:** Definitions and instances written by this release require a model-2 engine reader; upgrade every reader before deploying its writers.
76
+
77
+ Workflow fields, nested field shapes, effect outputs, and action parameters can declare typed scalar choices with `options.list`. The engine validates authored lists and rejects runtime values outside them, Studio renders one shared select control and displays each selected choice by its title, and the MCP authoring guide explains the syntax.
78
+
79
+ ### Patch Changes
80
+
81
+ - 0f50aed: Breadcrumb chevrons now center on the text's cap band instead of the x-height band (which sat them visibly low beside mixed-case segments) and render slightly dimmed everywhere, so they read as punctuation rather than content. To-do item labels render in medium weight, matching the activity rows they sit between.
82
+ - 6351232: Add reusable member, assignee, and date controls for Studio and App SDK integrations.
83
+ - 0f50aed: The assign control no longer renders on a field the actor can't edit — previously a settled activity's row (and its dialog) showed a picker trigger that took the click, flashed its pressed face, and did nothing, since the engine closes an activity-scope field's edit window once the activity settles. A non-editable assignees field now shows its assignees as plain display: the row keeps the avatar stack when anyone was assigned and shows nothing otherwise.
84
+ - d26cc1a: Add the engine-owned Actor resolution contract with client-backed resolution for server, CLI, and MCP runtimes; add native Studio and App SDK project-user integrations; and migrate the Studio plugin member picker to the shared directory.
85
+ - 9126299: **BREAKING:** Delete persisted stage guard documents when their stage exits, and remove the lifted-record `GUARD_LIFTED_PREDICATE` and `isGuardLifted` exports.
86
+
87
+ Guard deletion now uses the observed document revision so stale exit reconciliation cannot delete a guard reactivated by a newer stage visit. Reactive guard streams contain only active persisted guards.
88
+
89
+ - d526887: The start dialog no longer flashes the "A previous start of this workflow didn't finish" resume card during a normal start. A start lands as separate create/prime commits, and the live list echoes the attempt's own instance mid-flight; the dialog now holds the presentation the attempt began with (the input form for a fresh start, the resume card for a continue) until the attempt settles, instead of re-deriving it from that echo. A start that fails after its create commit still surfaces the resume card once the attempt is over.
90
+ - b06a45c: Document links (previews and the task list's "Open document" item) now gate on the target's actual `_type`: a probe resolves the real type from the lake, and only a target whose type is a concrete document type in the workspace schema gets an edit link. A target whose type can't back a document form here renders a no-link notice instead of navigating into a Studio error, the linked preview uses the actual type rather than the stored reference type, and the "Open document" menu item applies the same locality and existence gates as preview links.
91
+ - b06a45c: Document links in workflow surfaces navigate by document id only and let the Studio resolve the target's real `_type`. Previously the stored GDR `type` was passed as the edit intent's `type` param, and the Studio trusts that value verbatim — when it wasn't the target's concrete schema type (e.g. the generic `document`), the document pane built a form for a fieldless type and crashed the Studio.
92
+ - 0f50aed: A to-do checkbox that can't be toggled now explains why on hover — the tooltip rides the checkbox itself, not the whole row. The row derivation carries the owning field's edit-disabled reason, and the row surfaces it with the same lines the field pills use — in the For me list, the Overview, and the activity dialog's checklist alike. Those reason lines are retuned as single-line interface copy: no trailing full stops, no "field" vocabulary (the same line shows on checkboxes outside any field context), and the closed-window case names the actual cause: "Can only be edited while its activity is active".
93
+ - Updated dependencies [239d9f6]
94
+ - Updated dependencies [775fb3c]
95
+ - Updated dependencies [3af2ca0]
96
+ - Updated dependencies [7276702]
97
+ - Updated dependencies [7276702]
98
+ - Updated dependencies [6351232]
99
+ - Updated dependencies [58f8211]
100
+ - Updated dependencies [00c089d]
101
+ - Updated dependencies [f1fbedd]
102
+ - Updated dependencies [71cd58e]
103
+ - Updated dependencies [cd03973]
104
+ - Updated dependencies [d26cc1a]
105
+ - Updated dependencies [9126299]
106
+ - Updated dependencies [f02d026]
107
+ - Updated dependencies [72018af]
108
+ - Updated dependencies [5cd8ffd]
109
+ - Updated dependencies [b82bda4]
110
+ - Updated dependencies [5244335]
111
+ - Updated dependencies [55a54b3]
112
+ - Updated dependencies [b82bda4]
113
+ - Updated dependencies [4490442]
114
+ - Updated dependencies [1540dce]
115
+ - Updated dependencies [b341a7d]
116
+ - @sanity/workflow-engine@0.18.0
117
+ - @sanity/workflow-components@0.1.0
118
+ - @sanity/workflow-diagram@0.4.0
119
+ - @sanity/workflow-studio@0.9.0
120
+ - @sanity/workflow-react@0.13.0
121
+
122
+ ## 0.3.0
123
+
124
+ ### Minor Changes
125
+
126
+ - 50269b7: Every activity-row chip explains itself on hover: "Awaiting decision" ("More than one action can settle this activity — someone needs to decide"), "Blocked" ("None of its actions can be fired right now — open the activity to see why"), and "Failed" ("This activity settled as failed"), matching the "Automated" pill's hover. The hint copy is keyed on the chip vocabulary, so a new chip fails typecheck until it carries one.
127
+ - 000297c: Redesigned activity detail dialog, and one date/reference editing model across the plugin.
128
+ - The activity dialog is now a form-like surface: a sticky meta block (description, status, and the non-terminal action strip) above a separator, then every declared field in declaration order — assignees included — each with its label, declared description, and editor (or read-only face). The meta block stays in reach while the fields scroll. All edits stay real-time (text commits on blur/Enter, single-gesture widgets commit on change).
129
+ - Actions split into two buckets. Actions that leave the activity's status alone (field writes, effects, cross-activity nudges) render as a quiet strip in the meta block; actions that write the activity's own status live in the footer beside a Cancel button — the first as the solid primary (critical tone for a failed-settling back-out), the rest behind the split button's chevron menu segment.
130
+ - Terminal actions also fire straight from the activity list rows (Overview and For me): each open row carries a quiet ghost cluster — one outline around the primary and the chevron menu segment — so routine advances don't require opening the dialog. Settled rows stay control-free.
131
+ - Uniform action model: every rendered action is a button. Actions with params — a single actor or document pick included — open a confirm dialog from an ellipsis-suffixed button; the assignment and fire-on-pick row treatments are gone (one extra confirm click for those flows).
132
+ - Cascade-fired actions render in the top action row as caution-toned automation rows; clicking opens an explainer that puts the trigger into plain language with live outcome marks. The off-system manual link rides the same row with the same caution tone.
133
+ - Fields whose change can advance the workflow or fire an activity's automation carry an info affordance beside their label explaining the consequence; the lightning-bolt hot-field badge is gone.
134
+ - `doc.ref` fields are now editable inline through the document picker, scoped to the field's declared accepted types.
135
+ - Every date/datetime editing surface (dialog fields, field-pill popovers, action params, the start form) uses the shared DatePicker input — no native browser date inputs remain.
136
+ - Every field in the dialog renders through its input face: read-only fields keep the same chrome inert (read-only text inputs, a disabled switch, a disabled date picker, reference previews without their Change affordance, an inert search face for empty references) with no "Read-only" caption, and empty values render as empty inputs, never an em-dash.
137
+ - The activity status label reads "Active" (was "Open"), matching the engine's status vocabulary.
138
+ - Quieter surfaces: the dialog's "Pending on you" callout is gone, and a done or skipped activity shows no status chip in the activities list (its status icon carries it) — the chip column is reserved for Failed, Blocked, and Awaiting decision.
139
+ - The stage spine tells the truth about send-backs: a visited stage that lies AHEAD of the current one again no longer wears the completed checkmark or a "Completed at" tooltip — it reads as a plain upcoming pill whose hover card says "Last exited …" and counts its activities like upcoming work.
140
+
141
+ - 000297c: Activity rows drop the "Skipped" chip — the status icon already carries that state — and hovering any row's status icon now shows the status name in a tooltip.
142
+ - 000297c: The singular `assignee` kind is now editable everywhere it renders. The Overview's field pills and the activity dialog's inline fields both open the same roles-and-members picker as the plural `assignees` editor, in single-select form: a pick replaces the value and closes the picker, and picking the current holder clears the field. Previously the kind had no editing surface at all — an editable assignee rendered as a read-only pill, and the dialog fell back to a free-text input over the stringified value.
143
+ - 50269b7: Activity list rows (Overview and For me) mark truly hands-off activities with an "Automated" pill, so editors scanning a stage can tell which rows need a person and which the system resolves on its own. The pill keys on two engine facets agreeing: every action is cascade-fired (executor classification `autonomous`) AND the causal autonomy analysis is certain the activity completes without a caller — a mechanically autonomous activity whose triggers read caller-written state is progressed by the person doing that work, and shows no pill. Undecidable verdicts render nothing (quiet over wrong), and settled rows show no pill. Hovering the pill explains it: "Completes on its own — no user action is needed".
144
+ - 50269b7: The activity dialog's cascade-fired automation rows are inert with an explanatory hover, replacing the click-to-open explainer dialog. The button is permanently disabled and default-toned (nothing needs attention — the engine has it); hovering shows a "Fired by the system" lead, the action's declared description when it has one, then the trigger's reason — one plain-language sentence for a single-atom trigger, the marked checklist lines for a compound one, the raw GROQ while the definition is still resolving. Constant triggers phrase as the rule they follow ("Runs automatically each time the stage is entered") rather than the checklist's bare "always"/"never". The rows also tighten the gap between the bolt icon and the action label by one spacing step.
145
+ - 000297c: Counts shed their parenthesized suffixes for a muted count after the label: the Workflows view's "For me" tab and the pill rows' "Show more" toggle.
146
+ - d0c62ea: The plugin renders the reactive layer's `invalid` state instead of an eternal spinner: an unreadable engine-owned document (a `model-ahead` doc needing a newer `@sanity/workflow-engine`, or a corrupt one) surfaces a remediation notice in the form strip and the Workflows view — both for a live session's instance and for a wholesale-invalid discovery read, which now also stops reading as "loading" while keeping already-resolved entries rendered.
147
+ - 000297c: Instance headers (the Overview's sections and For me's, which share the same accordion) mark an instance whose pinned definition version has been superseded by a newer deploy: an "Older definition" chip with a hover hint naming the pinned and latest versions. Advisory only — an instance keeps the definition it started on, so the chip explains why a fresh deploy isn't reflected rather than offering an action. The comparison reads the same deployed-definitions query mapping validation already runs (provider mount and every start-dialog open), so it can lag a deploy made since.
148
+ - 5a1a9fe: The plugin's direct `engine.query` reads adopt the data-model gate. The two definition reads (mapping validation, the start dialog's definition lookup) surface a newer-model definition through their existing error paths ("upgrade `@sanity/workflow-engine`") instead of rendering it unchecked; the start-filter pre-flight's instance-slice read gates each row too, with a gate failure riding its declared fail-open posture (log and keep the start control shown — the verdict is a visibility hint, not a gate).
149
+ - c3eed2e: Add the dedicated Workflows tool — a Studio navbar tab with a Tasks view (My tasks / All tasks segments over every open activity, grouped by document with sub-workflow folding), a dashboard of the newest workflow instances (capped, settled runs folded behind a toggle), and a deep-linkable per-instance detail view rendering the stage diagram (`@sanity/workflow-diagram`) plus the same activities/action-items lists and activity detail dialog as the Workflows document view. Both tabs mount a five-category filter panel (document, status, assignee, workflow, date — the date arm bounds ANY date/datetime a task carries; dates are plain facts, the model has no deadline property): tag inputs with pills inside the field, options in overlays anchored under each field, multi-value within a category, and active filters mirrored as dismissible chips. "New workflow" starts any deployed startable definition through a searchable picker feeding the existing start dialog; the tool claims a `workflow` intent, and the instance header's overflow menu links into it.
150
+
151
+ Display faces no longer flip through wrong values while data resolves: the document-list stage pill reads its title from the instance's embedded definition snapshot (instead of flashing the raw stage name until the live evaluation lands), document previews hold a placeholder skeleton instead of painting "Untitled" first, and filter pill/chip labels hold a neutral pending face until preview titles and member names resolve.
152
+
153
+ - 1321ba5: The start control pre-flights both start predicates: `start.filter` (visibility — evaluated browse-time-pure, no `$fields`) and the new `start.allowed` (permission — `$fields` bound from the seeded subject and selected release; the row disables with a reason only on a definitive refusal, and only when every entry the predicate reads is bindable up front). The start dialog surfaces a `StartNotAllowedError` from `startInstance` as its own warning toast instead of a generic failure.
154
+ - 000297c: The plugin speaks the engine's todo-list vocabulary end to end: the todo failure toast reads "Updating to-dos failed" and the add-item placeholder reads "New to-do" — both previously said "action item(s)".
155
+ - e3a7ba2: The start dialog now holds a per-attempt instance id — start's idempotency key — so a retry after a failed start resumes the same instance instead of minting a duplicate; editing inputs after a failure deliberately starts a new one. An unfinished start already on the subject is adopted when the dialog opens: the input form is replaced by a "continue that attempt" note (its inputs were pinned at create) with an explicit "start a new workflow instead" opt-out. A start whose first auto-advance fails (`StartNotSettledError`) reports "started, but didn't finish auto-advancing" and closes — the run exists, so a failure toast would contradict the live list. Unfinished starts (created, never primed) are named where they render: a "Start incomplete" badge in the form strip and on document-list preview rows, and a Workflows-view notice instead of a normal run at its initial stage. The start control's advisory `start.filter`/`start.allowed` pre-flights stand down when an unfinished start exists on the subject — the flow resumes it, and a dedupe-style `allowed` would otherwise refuse because of the very husk the start needs to finish.
156
+ - 092a0d4: `WorkflowPluginConfig` takes `resourceClients` — a cross-resource read-routing resolver passed through to the Studio engine. A served resource is also part of the declared surface for refs written into field state, so this is how a Studio deployment admits media-library/canvas refs written through the plugin.
157
+ - 000297c: The Workflows view's Overview / For me tab now rides the pane's URL params, so a reload or bookmark restores the selected tab. The param is written only for For me — Overview URLs stay unchanged — and an unrecognized value falls back to Overview.
158
+
159
+ ### Patch Changes
160
+
161
+ - 50269b7: The activity detail dialog drops its empty body panel for activities with no declared fields: the meta block's bottom separator and the padded field area render only when there are fields (or a blocked notice) to show below them.
162
+ - 000297c: The spine's stage-overview hint drops the extra inner padding that made it visibly fatter than every other tooltip. All hints now render through one seam that pins the tooltip chrome (padding, radius, width cap, open delay), and a lint rule keeps raw Tooltip imports out of the plugin so the chrome can't drift per surface.
163
+ - Updated dependencies [f9389e5]
164
+ - Updated dependencies [f9389e5]
165
+ - Updated dependencies [d0c62ea]
166
+ - Updated dependencies [c3eed2e]
167
+ - Updated dependencies [df4bd80]
168
+ - Updated dependencies [b43de49]
169
+ - Updated dependencies [092a0d4]
170
+ - Updated dependencies [5a1a9fe]
171
+ - Updated dependencies [5a1a9fe]
172
+ - Updated dependencies [5a1a9fe]
173
+ - Updated dependencies [e3a7ba2]
174
+ - Updated dependencies [30fed9e]
175
+ - Updated dependencies [c3eed2e]
176
+ - Updated dependencies [1321ba5]
177
+ - Updated dependencies [e683875]
178
+ - Updated dependencies [a8ace4d]
179
+ - @sanity/workflow-diagram@0.3.0
180
+ - @sanity/workflow-engine@0.17.0
181
+ - @sanity/workflow-studio@0.8.0
182
+ - @sanity/workflow-react@0.12.0
183
+
3
184
  ## 0.2.0
4
185
 
5
186
  ### Minor Changes
package/README.md CHANGED
@@ -9,8 +9,10 @@ stages like _Drafting → Review → Approved_, and the actions that move work
9
9
  between them — deploy it to your dataset, and this plugin gives editors the
10
10
  UI: a **workflow strip** above the editor form of mapped documents (the
11
11
  current stage, your task count, and a **Start workflow** button), and a
12
- **Workflows tab** next to the editor with the stage's activities and action
13
- items, where they fire actions and read the history.
12
+ **Workflows tab** next to the editor with the stage's activities and to-dos,
13
+ where they fire actions and read the history, and a **Workflows tool** in the
14
+ Studio navbar — a tasks view, a dashboard of the newest workflow instances,
15
+ and a deep-linkable per-workflow detail view.
14
16
 
15
17
  Four ideas cover everything in this guide:
16
18
 
@@ -34,7 +36,7 @@ treat plugin-side checks as a security boundary.
34
36
  npm install @sanity/workflow-studio-plugin @sanity/workflow-engine @sanity/workflow-cli
35
37
  ```
36
38
 
37
- Requires a Studio v5 project (`sanity ^5.30`, `react ^19`,
39
+ Requires a Studio v6 project (`sanity ^6`, `react ^19`,
38
40
  `styled-components ^6`, `@sanity/sdk ^2.12` — the usual studio peers).
39
41
 
40
42
  ## 2. Define a workflow
@@ -54,7 +56,7 @@ export const articleReview = defineWorkflow({
54
56
  fields: [
55
57
  // The document this workflow is about. The plugin fills it in when an
56
58
  // editor starts the workflow from a document.
57
- {type: 'doc.ref', name: 'subject', title: 'Article', initialValue: {type: 'input'}},
59
+ {type: 'subject', name: 'subject', title: 'Article', initialValue: {type: 'input'}},
58
60
  ],
59
61
  stages: [
60
62
  {
@@ -101,6 +103,7 @@ import {articleReview} from './workflows/article-review'
101
103
  export default defineWorkflowConfig({
102
104
  deployments: [
103
105
  {
106
+ expectedMinReaderModel: 2,
104
107
  name: 'production',
105
108
  // The tag namespaces all workflow data — the plugin only sees
106
109
  // definitions and instances deployed under the tag it's configured with.
@@ -138,8 +141,6 @@ const workflowMappings: readonly WorkflowMapping[] = [
138
141
  {
139
142
  docType: 'article', // your schema type
140
143
  definition: 'article-review', // the deployed definition's `name`
141
- subjectKind: 'document',
142
- subjectGdrType: 'article',
143
144
  label: 'Article review',
144
145
  },
145
146
  ]
@@ -191,11 +192,68 @@ export const article = defineType({
191
192
  })
192
193
  ```
193
194
 
195
+ ### Auto-start a workflow on new documents
196
+
197
+ `autoStart` starts a workflow the moment an editor opens a **fresh** document
198
+ of a given type — the document is born with its workflow instead of relying on
199
+ someone to press "Start". It's a map of document `_type` to the deployed
200
+ definition name(s) to start:
201
+
202
+ ```ts
203
+ workflowStudioPlugin({
204
+ tag: 'production',
205
+ mappings: [
206
+ /* ... */
207
+ ],
208
+ autoStart: {
209
+ article: 'article-review', // one workflow
210
+ campaign: ['legal-review', 'brand-review'], // several, started together
211
+ },
212
+ })
213
+ ```
214
+
215
+ Pass a function instead of a map to vary it by workspace (its name, or the
216
+ schema):
217
+
218
+ ```ts
219
+ autoStart: ({workspaceName}) => (workspaceName === 'editorial' ? {article: 'article-review'} : {})
220
+ ```
221
+
222
+ How it behaves:
223
+
224
+ - **Fresh only.** Studio doesn't persist a new document until its first edit,
225
+ so "fresh" means never-persisted (no `_createdAt`). The gate takes over that
226
+ first form render and never touches a document that already exists.
227
+ - **The document is the subject.** The gate materializes the document (like
228
+ pressing "Start workflow" does) in the Studio's **active perspective** — the
229
+ selected release's version, or the draft when none is selected — and seeds it
230
+ as each workflow's subject. When
231
+ several workflows share an input beyond the subject, one dialog collects that
232
+ union once and feeds every workflow; when nothing is needed, they start
233
+ silently. The dialog is **mandatory** — auto-start means the workflow will
234
+ start, so there's no skip; the required inputs must be filled. The form is
235
+ revealed once the workflow instance is live.
236
+ - **Best-effort with several workflows.** When a type maps to more than one
237
+ workflow they start in parallel, and the form stays held until they've all
238
+ started. A failure is never a dead end: the takeover shows the error with a
239
+ **Try again** (re-attempts only the workflows that didn't start — never
240
+ double-starting one) and a **Continue editing without it**. There's no
241
+ automatic rollback — the document is left created, its workflows as they
242
+ landed.
243
+ - **A floor, not a guarantee.** A raw client or any non-Studio write bypasses it
244
+ entirely; enforcing "this type must have a workflow" needs a service in front
245
+ of the Content Lake, which is out of scope. A misconfigured entry (unknown
246
+ type, undeployed or spawn-only workflow, a subject that doesn't accept the
247
+ type) is dropped with a `console.warn`, never a crash.
248
+
249
+ Naming a workflow here doesn't require a `mappings` entry — the inputs come
250
+ from the deployed definition itself — but pairing the two is common, so the
251
+ same document also carries the workflow strip and views.
252
+
194
253
  Plugin options, for later: `workflowDataset` (keep workflow state in a
195
254
  separate dataset), `effectHandlers` (run effect side-effects in the browser
196
- — the runtime below is usually the better home), and per-mapping `mandatory`
197
- (gate the editor form until a workflow is attached), `initialStateBuilder`,
198
- and `perspectiveField` (bind a release to the workflow).
255
+ — the runtime below is usually the better home), and per-mapping
256
+ `initialStateBuilder` and `perspectiveField` (bind a release to the workflow).
199
257
 
200
258
  ## 5. Add the runtime (two Sanity Functions)
201
259