@sanity/workflow-cli 0.20.0 → 0.21.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 +34 -0
- package/README.md +4 -3
- package/dist/commands/editorial-workflows/list.d.ts +20 -7
- package/dist/commands/editorial-workflows/list.js +40 -10
- package/dist/commands/editorial-workflows/reset-activity.d.ts +25 -4
- package/dist/commands/editorial-workflows/reset-activity.js +56 -6
- package/dist/help.d.ts +8 -0
- package/dist/help.js +23 -0
- package/dist/lib/fail.js +1 -1
- package/dist/lib/ui.d.ts +2 -1
- package/dist/lib/ui.js +4 -3
- package/oclif.manifest.json +25 -8
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @sanity/workflow-cli
|
|
2
2
|
|
|
3
|
+
## 0.21.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9273d55: List the nested `definition` commands (`list`, `show`, `diff`, `delete`) in the
|
|
8
|
+
standalone binary's flat `--help` output. A custom oclif help class surfaces the
|
|
9
|
+
bare `definition <verb>` aliases at the root instead of burying them under the
|
|
10
|
+
`editorial-workflows` topic, so `sanity-workflows --help` shows every command
|
|
11
|
+
without topic-digging. `help --all` still prints the full canonical tree.
|
|
12
|
+
- e7392af: Add the `resetActivity` admin verb — reset a failed (or otherwise terminal) activity in an instance's current stage back to `active` (re-run) or `skipped` (bypass), then cascade so a `$allActivitiesDone`-gated exit transition can fire. `workflow.diagnose` now marks its `reset-activity` remediation `available`, and the CLI ships the real `reset-activity <instanceId> <activity> [--skip]` command in place of the stub. Emits the `Editorial Workflows Activity Reset` adoption event on every attempt (`changed: false` on a no-op), matching the `set-stage` and `abort` overrides.
|
|
13
|
+
|
|
14
|
+
Writes strictly within the existing model-3 grammar: it reuses the `activityStatusChanged` history variant and the existing activity statuses, so it adds no persisted shape — there is no data-model version bump and no reader-floor change.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- b248789: CLI error detail lines now render in the terminal's default colour instead of red. The red headline with its `✖` still signals the failure; the detail beneath it (validation output, auth hints, wrapped errors) is the information the user has to read, and long runs of red text were hard to read.
|
|
19
|
+
- f4bc057: **BREAKING:** `list_workflow_instances` now returns one page with `has_more` and an optional `next_cursor`; callers that need every match must continue with the cursor. The optional `limit` accepts 1–100 rows and defaults to 25.
|
|
20
|
+
|
|
21
|
+
Bound instance and definition list reads with lake-side filtering and consumer-specific projections.
|
|
22
|
+
|
|
23
|
+
Document filtering now excludes exited-stage references and includes live unresolved child-workflow references. Definition discovery selects and model-gates only the latest deployed version of each workflow name; historical versions remain stored and available to history-oriented APIs.
|
|
24
|
+
|
|
25
|
+
The MCP eval suite now verifies that agents follow list cursors to find a target beyond the first default page, including in persisted Braintrust runs.
|
|
26
|
+
|
|
27
|
+
MCP tool telemetry reports a `cursorUsed` boolean so continued list-page adoption is measurable without sending cursor values, arguments, or results.
|
|
28
|
+
|
|
29
|
+
- Updated dependencies [d9394e5]
|
|
30
|
+
- Updated dependencies [92e28bd]
|
|
31
|
+
- Updated dependencies [f4bc057]
|
|
32
|
+
- Updated dependencies [bcc30fe]
|
|
33
|
+
- Updated dependencies [e7392af]
|
|
34
|
+
- Updated dependencies [fa9c796]
|
|
35
|
+
- @sanity/workflow-engine@0.21.0
|
|
36
|
+
|
|
3
37
|
## 0.20.0
|
|
4
38
|
|
|
5
39
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ import {articleReview, urlDraft} from './src/workflows.ts'
|
|
|
60
60
|
export default defineWorkflowConfig({
|
|
61
61
|
deployments: [
|
|
62
62
|
{
|
|
63
|
-
expectedMinReaderModel:
|
|
63
|
+
expectedMinReaderModel: 4,
|
|
64
64
|
name: 'production', // the deployment's unique identity (lowercase letters, digits, dashes)
|
|
65
65
|
tag: 'prod', // the environment partition the engine's docs are scoped to
|
|
66
66
|
workflowResource: {type: 'dataset', id: 'acme.workflows'}, // where those docs live
|
|
@@ -89,8 +89,8 @@ tag names exactly one deployment — on `deploy` it targets every deployment
|
|
|
89
89
|
carrying the tag (a tag is an environment group). With several configured, a
|
|
90
90
|
bare interactive run presents a keyboard-driven deployment selector (by name,
|
|
91
91
|
tag alongside) — on `deploy`, `start`, and `definition diff`/`delete`, and on
|
|
92
|
-
the instance-targeted commands (`abort`, `set-stage`, `
|
|
93
|
-
`diagnose`) when the config spans several resources. In CI or another
|
|
92
|
+
the instance-targeted commands (`abort`, `set-stage`, `reset-activity`,
|
|
93
|
+
`fire-action`, `diagnose`) when the config spans several resources. In CI or another
|
|
94
94
|
non-interactive shell, the command fails asking for `--deployment` or `--tag`
|
|
95
95
|
(`deploy` also suggests `--all-tags`) instead of blocking for input.
|
|
96
96
|
`--all-tags` deploys every deployment in the config in one run: a failure in one doesn't
|
|
@@ -170,6 +170,7 @@ stale compiled output.
|
|
|
170
170
|
| `tail <instance-id>` | wired — `client.listen()` over the instance, prints new history entries |
|
|
171
171
|
| `abort <instance-id>` | wired — calls `workflow.abortInstance` (hard stop: cancels pending effects, removes guards) |
|
|
172
172
|
| `set-stage <instance-id> --to <stage>` | wired — calls `workflow.setStage` (admin override: skips declared transitions/filters; enter lifecycle + cascade still run) |
|
|
173
|
+
| `reset-activity <instance-id> <activity>` | wired — calls `workflow.resetActivity` (recovery override: reset a failed activity to `active`, or `--skip` to bypass it; then cascade) |
|
|
173
174
|
| `fire-action <instance-id>` | wired — `workflow.availableActions` lists actions; `workflow.fireAction` fires one |
|
|
174
175
|
| `definition list` | wired — `client.fetch` over `sanity.workflow.definition` documents |
|
|
175
176
|
| `definition show <name>` | wired — `client.fetch`, latest version unless `--version` |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type TerminalState } from '@sanity/workflow-engine';
|
|
1
|
+
import { type GdrUri, type TerminalState } from '@sanity/workflow-engine';
|
|
2
2
|
import { WorkflowCommand } from '../../lib/base-command.ts';
|
|
3
3
|
interface InstanceRow {
|
|
4
4
|
_id: string;
|
|
@@ -19,17 +19,19 @@ interface ListFlags {
|
|
|
19
19
|
tag?: string | undefined;
|
|
20
20
|
limit: number;
|
|
21
21
|
}
|
|
22
|
+
interface ListQueryClient {
|
|
23
|
+
fetch<T>(groq: string, params: Record<string, unknown>, options: {
|
|
24
|
+
tag: string;
|
|
25
|
+
}): Promise<T>;
|
|
26
|
+
}
|
|
22
27
|
/**
|
|
23
28
|
* Build the GROQ query + params for `list` from its flags. Pure so the
|
|
24
29
|
* filter combinations can be asserted without a live dataset. `--tag` is an
|
|
25
30
|
* optional filter: omit it and the listing spans every partition.
|
|
26
31
|
*
|
|
27
|
-
* With `--document` the lake filter is the engine's
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* documents (the narrowing reads fields/stages/ancestors) and UNCAPPED: a
|
|
31
|
-
* capped superset could silently hide matches. The display limit applies
|
|
32
|
-
* after narrowing.
|
|
32
|
+
* With `--document` the lake filter is the engine's exact watch-set arm. The
|
|
33
|
+
* projection keeps its ref-bearing fields for a defensive JS recheck while
|
|
34
|
+
* omitting the instance's unbounded ledgers and definition snapshot.
|
|
33
35
|
*/
|
|
34
36
|
export declare function buildListQuery(flags: ListFlags): {
|
|
35
37
|
groq: string;
|
|
@@ -58,4 +60,15 @@ export default class List extends WorkflowCommand {
|
|
|
58
60
|
};
|
|
59
61
|
run(): Promise<void>;
|
|
60
62
|
}
|
|
63
|
+
/** Fetch one target's projected rows, defensively rechecking document refs. */
|
|
64
|
+
export declare function fetchRows({ client, groq, params, document, limit, }: {
|
|
65
|
+
client: ListQueryClient;
|
|
66
|
+
groq: string;
|
|
67
|
+
params: Record<string, unknown>;
|
|
68
|
+
document: GdrUri | undefined;
|
|
69
|
+
limit: number;
|
|
70
|
+
}): Promise<{
|
|
71
|
+
rows: InstanceRow[];
|
|
72
|
+
hasMore: boolean;
|
|
73
|
+
}>;
|
|
61
74
|
export {};
|
|
@@ -7,6 +7,23 @@ import { failOnThrow } from "../../lib/fail.js";
|
|
|
7
7
|
import { tagFlags } from "../../lib/flags.js";
|
|
8
8
|
import { runReadAcrossTargets } from "../../lib/read-fanout.js";
|
|
9
9
|
import { formatAge, logClippedTable } from "../../lib/ui.js";
|
|
10
|
+
const DOCUMENT_LIST_PROJECTION = `{
|
|
11
|
+
_type,
|
|
12
|
+
_id,
|
|
13
|
+
workflowResource,
|
|
14
|
+
modelVersion,
|
|
15
|
+
minReaderModel,
|
|
16
|
+
definition,
|
|
17
|
+
tag,
|
|
18
|
+
currentStage,
|
|
19
|
+
fields,
|
|
20
|
+
stages,
|
|
21
|
+
ancestors,
|
|
22
|
+
subworkflows,
|
|
23
|
+
completedAt,
|
|
24
|
+
abortedAt,
|
|
25
|
+
lastChangedAt
|
|
26
|
+
}`;
|
|
10
27
|
export function buildListQuery(flags) {
|
|
11
28
|
const filters = [`_type == "${WORKFLOW_INSTANCE_TYPE}"`];
|
|
12
29
|
const params = {};
|
|
@@ -26,7 +43,11 @@ export function buildListQuery(flags) {
|
|
|
26
43
|
const armParams = {};
|
|
27
44
|
filters.push(`(${documentPrefilter([flags.document], armParams)})`);
|
|
28
45
|
Object.assign(params, armParams);
|
|
29
|
-
|
|
46
|
+
params['limit'] = flags.limit + 1;
|
|
47
|
+
return {
|
|
48
|
+
groq: `*[${filters.join(' && ')}] | order(lastChangedAt desc)[0...$limit]${DOCUMENT_LIST_PROJECTION}`,
|
|
49
|
+
params,
|
|
50
|
+
};
|
|
30
51
|
}
|
|
31
52
|
params['limit'] = flags.limit + 1;
|
|
32
53
|
const groq = `*[${filters.join(' && ')}] | order(lastChangedAt desc) [0...$limit]{
|
|
@@ -96,14 +117,20 @@ export default class List extends WorkflowCommand {
|
|
|
96
117
|
targets,
|
|
97
118
|
log: (line) => this.log(line),
|
|
98
119
|
run: async ({ client }) => {
|
|
99
|
-
const fetched = await fetchRows({ client, groq, params, document });
|
|
100
|
-
if (fetched.length === 0) {
|
|
101
|
-
|
|
120
|
+
const fetched = await fetchRows({ client, groq, params, document, limit: flags.limit });
|
|
121
|
+
if (fetched.rows.length === 0) {
|
|
122
|
+
if (fetched.hasMore) {
|
|
123
|
+
this.log(`${logSymbols.info} no matches in the first ${flags.limit} candidates — raise --limit to search further`);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.log(`${logSymbols.info} no instances match`);
|
|
127
|
+
}
|
|
102
128
|
return;
|
|
103
129
|
}
|
|
104
130
|
logClippedTable({
|
|
105
|
-
rows: fetched,
|
|
131
|
+
rows: fetched.rows,
|
|
106
132
|
limit: flags.limit,
|
|
133
|
+
moreAvailable: fetched.hasMore,
|
|
107
134
|
headers: ['instance', 'workflow', 'tag', 'stage', 'status', 'updated'],
|
|
108
135
|
toCells: (r) => {
|
|
109
136
|
const row = instanceRow(r);
|
|
@@ -125,13 +152,16 @@ export default class List extends WorkflowCommand {
|
|
|
125
152
|
}
|
|
126
153
|
}
|
|
127
154
|
}
|
|
128
|
-
async function fetchRows({ client, groq, params, document, }) {
|
|
155
|
+
export async function fetchRows({ client, groq, params, document, limit, }) {
|
|
129
156
|
if (document === undefined) {
|
|
130
157
|
const rows = await client.fetch(groq, params, { tag: 'list' });
|
|
131
|
-
return rows.map(assertReadableModel);
|
|
158
|
+
return { rows: rows.map(assertReadableModel), hasMore: rows.length > limit };
|
|
132
159
|
}
|
|
133
160
|
const candidates = await client.fetch(groq, params, { tag: 'list' });
|
|
134
|
-
return
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
return {
|
|
162
|
+
rows: candidates
|
|
163
|
+
.map(assertReadableModel)
|
|
164
|
+
.filter((instance) => instanceWatchesDocument(instance, document)),
|
|
165
|
+
hasMore: candidates.length > limit,
|
|
166
|
+
};
|
|
137
167
|
}
|
|
@@ -1,10 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { type ResetActivityTarget, type WorkflowInstance } from '@sanity/workflow-engine';
|
|
2
|
+
import { WorkflowCommand } from '../../lib/base-command.ts';
|
|
3
|
+
import { type WriteOutcome, type WriteReport } from '../../lib/ops-report.ts';
|
|
4
|
+
export default class ResetActivity extends WorkflowCommand {
|
|
5
|
+
static aliases: string[];
|
|
5
6
|
static description: string;
|
|
7
|
+
static examples: string[];
|
|
6
8
|
static args: {
|
|
7
9
|
instanceId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
10
|
activity: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
9
11
|
};
|
|
12
|
+
static flags: {
|
|
13
|
+
skip: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
};
|
|
16
|
+
run(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/** {@link WriteOutcome} with the terminal stamp the no-op copy reads. */
|
|
19
|
+
interface ResetActivityOutcome extends WriteOutcome {
|
|
20
|
+
instance: Pick<WorkflowInstance, 'currentStage' | 'completedAt'>;
|
|
10
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Turn a `resetActivity` result into the spinner message. Pure so the
|
|
24
|
+
* skipped / re-run / already-at-target / terminal / cascaded permutations can
|
|
25
|
+
* be asserted without driving a real reset.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resetActivityReport(result: ResetActivityOutcome, { activity, to }: {
|
|
28
|
+
activity: string;
|
|
29
|
+
to: ResetActivityTarget;
|
|
30
|
+
}): WriteReport;
|
|
31
|
+
export {};
|
|
@@ -1,11 +1,61 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { styleText } from 'node:util';
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { workflow } from '@sanity/workflow-engine';
|
|
4
|
+
import { WorkflowCommand } from "../../lib/base-command.js";
|
|
5
|
+
import { resolveInstanceContext } from "../../lib/context.js";
|
|
6
|
+
import { tagFlags } from "../../lib/flags.js";
|
|
7
|
+
import { buildOperationArgs } from "../../lib/operation-args.js";
|
|
8
|
+
import { cascadeTail, runWriteVerb, } from "../../lib/ops-report.js";
|
|
9
|
+
export default class ResetActivity extends WorkflowCommand {
|
|
10
|
+
static aliases = ['reset-activity'];
|
|
11
|
+
static description = 'Reset a failed activity on an in-flight instance — back to active to re-run it, or --skip to bypass it (mark it skipped) so a gated exit transition can fire.';
|
|
12
|
+
static examples = [
|
|
13
|
+
'<%= config.bin %> reset-activity wf-instance.abc123 legal-review',
|
|
14
|
+
'<%= config.bin %> reset-activity wf-instance.abc123 legal-review --skip',
|
|
15
|
+
];
|
|
7
16
|
static args = {
|
|
8
17
|
instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
|
|
9
18
|
activity: Args.string({ required: true, description: 'Activity name within the current stage.' }),
|
|
10
19
|
};
|
|
20
|
+
static flags = {
|
|
21
|
+
...tagFlags,
|
|
22
|
+
skip: Flags.boolean({
|
|
23
|
+
default: false,
|
|
24
|
+
description: 'Bypass the activity (mark it skipped) instead of re-running it (back to active).',
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
const { args, flags } = await this.parse(ResetActivity);
|
|
29
|
+
const { client, scope } = await resolveInstanceContext(flags, args.instanceId);
|
|
30
|
+
const to = flags.skip ? 'skipped' : 'active';
|
|
31
|
+
await runWriteVerb({
|
|
32
|
+
startLabel: `Resetting ${args.activity} on ${args.instanceId}…`,
|
|
33
|
+
failLabel: 'Reset rejected',
|
|
34
|
+
failHeadline: 'reset-activity error:',
|
|
35
|
+
run: () => workflow.resetActivity({
|
|
36
|
+
client,
|
|
37
|
+
...buildOperationArgs({ scope, instanceId: args.instanceId, reason: undefined }),
|
|
38
|
+
activity: args.activity,
|
|
39
|
+
to,
|
|
40
|
+
}),
|
|
41
|
+
report: (result) => resetActivityReport(result, { activity: args.activity, to }),
|
|
42
|
+
log: (line) => this.log(line),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function resetActivityReport(result, { activity, to }) {
|
|
47
|
+
const name = styleText('bold', activity);
|
|
48
|
+
if (!result.changed) {
|
|
49
|
+
const { completedAt } = result.instance;
|
|
50
|
+
const message = completedAt !== undefined
|
|
51
|
+
? `reset-activity changed nothing — instance is terminal (since ${completedAt})`
|
|
52
|
+
: `reset-activity changed nothing — ${name} is already ${to}`;
|
|
53
|
+
return { changed: false, message };
|
|
54
|
+
}
|
|
55
|
+
const stage = styleText('bold', result.instance.currentStage);
|
|
56
|
+
const verb = to === 'skipped' ? 'Skipped' : 'Reset';
|
|
57
|
+
return {
|
|
58
|
+
changed: true,
|
|
59
|
+
message: `${verb} ${name} — now at ${stage}${cascadeTail(result.cascaded)}`,
|
|
60
|
+
};
|
|
11
61
|
}
|
package/dist/help.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Help } from '@oclif/core';
|
|
2
|
+
export declare const isBareSurface: (idOrName: string) => boolean;
|
|
3
|
+
export declare const keepCommandAtRoot: (id: string) => boolean;
|
|
4
|
+
/** Standalone-binary help that lists the nested `definition` commands flat in
|
|
5
|
+
* `--help` rather than under a topic. A mounted host governs its own root help. */
|
|
6
|
+
export default class WorkflowHelp extends Help {
|
|
7
|
+
protected showRootHelp(): Promise<void>;
|
|
8
|
+
}
|
package/dist/help.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Help } from '@oclif/core';
|
|
2
|
+
export const isBareSurface = (idOrName) => !idOrName.startsWith('editorial-workflows');
|
|
3
|
+
export const keepCommandAtRoot = (id) => id !== '' && isBareSurface(id);
|
|
4
|
+
export default class WorkflowHelp extends Help {
|
|
5
|
+
async showRootHelp() {
|
|
6
|
+
if (this.opts.all) {
|
|
7
|
+
await super.showRootHelp();
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
this.log(this.formatRoot());
|
|
11
|
+
this.log('');
|
|
12
|
+
const topics = this.sortedTopics.filter((topic) => isBareSurface(topic.name));
|
|
13
|
+
if (topics.length > 0) {
|
|
14
|
+
this.log(this.formatTopics(topics));
|
|
15
|
+
this.log('');
|
|
16
|
+
}
|
|
17
|
+
const commands = this.sortedCommands.filter((command) => keepCommandAtRoot(command.id));
|
|
18
|
+
if (commands.length > 0) {
|
|
19
|
+
this.log(this.formatCommands(commands));
|
|
20
|
+
this.log('');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
package/dist/lib/fail.js
CHANGED
|
@@ -8,7 +8,7 @@ export function fail(headline, detail) {
|
|
|
8
8
|
process.stderr.write(`${styleText('red', `${logSymbols.error} ${headline}`)}\n`);
|
|
9
9
|
if (detail !== undefined && detail !== '') {
|
|
10
10
|
for (const line of detail.split('\n')) {
|
|
11
|
-
process.stderr.write(` ${
|
|
11
|
+
process.stderr.write(` ${line}\n`);
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
return Errors.exit(1);
|
package/dist/lib/ui.d.ts
CHANGED
|
@@ -37,9 +37,10 @@ export declare function clipToLimit<T>(rows: T[], limit: number): {
|
|
|
37
37
|
* rows, render them through {@link formatTable}, print every line, and print
|
|
38
38
|
* the clip note (when present) beneath the table.
|
|
39
39
|
*/
|
|
40
|
-
export declare function logClippedTable<T>({ rows, limit, headers, toCells, log, }: {
|
|
40
|
+
export declare function logClippedTable<T>({ rows, limit, moreAvailable, headers, toCells, log, }: {
|
|
41
41
|
rows: T[];
|
|
42
42
|
limit: number;
|
|
43
|
+
moreAvailable?: boolean;
|
|
43
44
|
headers: string[];
|
|
44
45
|
toCells: (row: T) => string[];
|
|
45
46
|
log: (line: string) => void;
|
package/dist/lib/ui.js
CHANGED
|
@@ -31,13 +31,14 @@ export function clipToLimit(rows, limit) {
|
|
|
31
31
|
note: styleText('dim', `showing the first ${limit} — raise --limit to see more`),
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
-
export function logClippedTable({ rows, limit, headers, toCells, log, }) {
|
|
34
|
+
export function logClippedTable({ rows, limit, moreAvailable, headers, toCells, log, }) {
|
|
35
35
|
const { rows: clipped, note } = clipToLimit(rows, limit);
|
|
36
36
|
for (const line of formatTable(headers, clipped.map(toCells))) {
|
|
37
37
|
log(line);
|
|
38
38
|
}
|
|
39
|
-
if (note) {
|
|
40
|
-
log(note
|
|
39
|
+
if (note || moreAvailable) {
|
|
40
|
+
log(note ??
|
|
41
|
+
styleText('dim', `searched the first ${limit} candidates — raise --limit to see more`));
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
export function groupBanner({ label, index, total, }) {
|
package/oclif.manifest.json
CHANGED
|
@@ -408,7 +408,9 @@
|
|
|
408
408
|
]
|
|
409
409
|
},
|
|
410
410
|
"editorial-workflows:reset-activity": {
|
|
411
|
-
"aliases": [
|
|
411
|
+
"aliases": [
|
|
412
|
+
"reset-activity"
|
|
413
|
+
],
|
|
412
414
|
"args": {
|
|
413
415
|
"instanceId": {
|
|
414
416
|
"description": "Workflow instance id.",
|
|
@@ -421,13 +423,28 @@
|
|
|
421
423
|
"required": true
|
|
422
424
|
}
|
|
423
425
|
},
|
|
424
|
-
"description": "Reset a failed activity on an in-flight instance — back to
|
|
425
|
-
"
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
"hiddenAliases": [
|
|
429
|
-
"reset-activity"
|
|
426
|
+
"description": "Reset a failed activity on an in-flight instance — back to active to re-run it, or --skip to bypass it (mark it skipped) so a gated exit transition can fire.",
|
|
427
|
+
"examples": [
|
|
428
|
+
"<%= config.bin %> reset-activity wf-instance.abc123 legal-review",
|
|
429
|
+
"<%= config.bin %> reset-activity wf-instance.abc123 legal-review --skip"
|
|
430
430
|
],
|
|
431
|
+
"flags": {
|
|
432
|
+
"tag": {
|
|
433
|
+
"description": "Workflow environment tag (e.g. prod, test) — an optional query filter, and the resource disambiguator when the config spans several.",
|
|
434
|
+
"name": "tag",
|
|
435
|
+
"hasDynamicHelp": false,
|
|
436
|
+
"multiple": false,
|
|
437
|
+
"type": "option"
|
|
438
|
+
},
|
|
439
|
+
"skip": {
|
|
440
|
+
"description": "Bypass the activity (mark it skipped) instead of re-running it (back to active).",
|
|
441
|
+
"name": "skip",
|
|
442
|
+
"allowNo": false,
|
|
443
|
+
"type": "boolean"
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
"hasDynamicHelp": false,
|
|
447
|
+
"hiddenAliases": [],
|
|
431
448
|
"id": "editorial-workflows:reset-activity",
|
|
432
449
|
"pluginAlias": "@sanity/workflow-cli",
|
|
433
450
|
"pluginName": "@sanity/workflow-cli",
|
|
@@ -913,5 +930,5 @@
|
|
|
913
930
|
]
|
|
914
931
|
}
|
|
915
932
|
},
|
|
916
|
-
"version": "0.
|
|
933
|
+
"version": "0.21.0"
|
|
917
934
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workflow-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Command-line tool for deploying, inspecting, and administering Sanity workflow definitions and instances.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -62,17 +62,18 @@
|
|
|
62
62
|
"@types/node": "^24.12.4",
|
|
63
63
|
"oclif": "^4.23.16",
|
|
64
64
|
"vitest": "^4.1.8",
|
|
65
|
-
"@sanity/workflow-engine": "0.
|
|
66
|
-
"@sanity/workflow-engine-test": "0.
|
|
67
|
-
"@sanity/workflow-examples": "0.
|
|
65
|
+
"@sanity/workflow-engine": "0.21.0",
|
|
66
|
+
"@sanity/workflow-engine-test": "0.21.0",
|
|
67
|
+
"@sanity/workflow-examples": "0.10.0"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@sanity/workflow-engine": "0.
|
|
70
|
+
"@sanity/workflow-engine": "0.21.0"
|
|
71
71
|
},
|
|
72
72
|
"oclif": {
|
|
73
73
|
"bin": "sanity-workflows",
|
|
74
74
|
"commands": "./dist/commands",
|
|
75
75
|
"dirname": "sanity-workflows",
|
|
76
|
+
"helpClass": "./dist/help",
|
|
76
77
|
"hooks": {
|
|
77
78
|
"finally": "./dist/hooks/finally/telemetry",
|
|
78
79
|
"prerun": "./dist/hooks/prerun/telemetry"
|