@sanity/workflow-cli 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +45 -26
  3. package/dist/commands/{abort.d.ts → editorial-workflows/abort.d.ts} +3 -2
  4. package/dist/commands/{abort.js → editorial-workflows/abort.js} +7 -6
  5. package/dist/commands/{definition → editorial-workflows/definition}/delete.d.ts +3 -2
  6. package/dist/commands/{definition → editorial-workflows/definition}/delete.js +6 -5
  7. package/dist/commands/{definition → editorial-workflows/definition}/diff.d.ts +2 -1
  8. package/dist/commands/{definition → editorial-workflows/definition}/diff.js +7 -6
  9. package/dist/commands/{definition → editorial-workflows/definition}/list.d.ts +2 -1
  10. package/dist/commands/{definition → editorial-workflows/definition}/list.js +21 -21
  11. package/dist/commands/{definition → editorial-workflows/definition}/show.d.ts +3 -2
  12. package/dist/commands/{definition → editorial-workflows/definition}/show.js +7 -6
  13. package/dist/commands/{deploy.d.ts → editorial-workflows/deploy.d.ts} +2 -1
  14. package/dist/commands/{deploy.js → editorial-workflows/deploy.js} +14 -13
  15. package/dist/commands/{diagnose.d.ts → editorial-workflows/diagnose.d.ts} +2 -1
  16. package/dist/commands/{diagnose.js → editorial-workflows/diagnose.js} +7 -6
  17. package/dist/commands/{fire-action.d.ts → editorial-workflows/fire-action.d.ts} +3 -2
  18. package/dist/commands/{fire-action.js → editorial-workflows/fire-action.js} +8 -7
  19. package/dist/commands/{list.d.ts → editorial-workflows/list.d.ts} +2 -1
  20. package/dist/commands/{list.js → editorial-workflows/list.js} +24 -24
  21. package/dist/commands/{nuke.d.ts → editorial-workflows/nuke.d.ts} +2 -1
  22. package/dist/commands/{nuke.js → editorial-workflows/nuke.js} +10 -9
  23. package/dist/commands/{reset-activity.d.ts → editorial-workflows/reset-activity.d.ts} +2 -1
  24. package/dist/commands/{reset-activity.js → editorial-workflows/reset-activity.js} +2 -1
  25. package/dist/commands/{set-stage.d.ts → editorial-workflows/set-stage.d.ts} +4 -3
  26. package/dist/commands/{set-stage.js → editorial-workflows/set-stage.js} +6 -5
  27. package/dist/commands/{show.d.ts → editorial-workflows/show.d.ts} +2 -1
  28. package/dist/commands/{show.js → editorial-workflows/show.js} +40 -26
  29. package/dist/commands/{start.d.ts → editorial-workflows/start.d.ts} +3 -2
  30. package/dist/commands/{start.js → editorial-workflows/start.js} +9 -8
  31. package/dist/commands/{tail.d.ts → editorial-workflows/tail.d.ts} +2 -1
  32. package/dist/commands/{tail.js → editorial-workflows/tail.js} +6 -5
  33. package/dist/hooks/finally/telemetry.js +2 -2
  34. package/dist/hooks/prerun/telemetry.d.ts +4 -3
  35. package/dist/lib/base-command.d.ts +4 -6
  36. package/dist/lib/base-command.js +6 -0
  37. package/dist/lib/flags.d.ts +4 -3
  38. package/dist/lib/prompt.d.ts +3 -2
  39. package/dist/lib/select-deployment.d.ts +12 -7
  40. package/dist/lib/select-deployment.js +26 -1
  41. package/dist/lib/share-definitions.d.ts +23 -28
  42. package/dist/lib/share-definitions.js +26 -38
  43. package/dist/lib/telemetry-setup.d.ts +2 -2
  44. package/dist/lib/telemetry.d.ts +18 -10
  45. package/dist/lib/telemetry.js +5 -2
  46. package/dist/lib/ui.d.ts +12 -0
  47. package/dist/lib/ui.js +9 -0
  48. package/oclif.manifest.json +93 -48
  49. package/package.json +11 -9
@@ -1,5 +1,6 @@
1
- import { WorkflowCommand } from '../lib/base-command.ts';
1
+ import { WorkflowCommand } from '../../lib/base-command.ts';
2
2
  export default class Nuke extends WorkflowCommand {
3
+ static aliases: string[];
3
4
  static summary: string;
4
5
  static description: string;
5
6
  static examples: string[];
@@ -2,16 +2,17 @@ import { Flags } from '@oclif/core';
2
2
  import { input } from '@sanity/cli-core/ux';
3
3
  import { resourceGdr } from '@sanity/workflow-engine';
4
4
  import logSymbols from 'log-symbols';
5
- import { WorkflowCommand } from "../lib/base-command.js";
6
- import { clientFor, resolveApiHost, resolveTokenOrFail } from "../lib/client.js";
7
- import { dedupeResources } from "../lib/context.js";
8
- import { fail } from "../lib/fail.js";
9
- import { loadWorkflowConfig } from "../lib/load-config.js";
10
- import { confirmationMatches, executeNuke, formatNukeSummary, involvedTargets, planCounts, renderNukePlan, resolveNukePlan, } from "../lib/nuke.js";
11
- import { runWriteVerb } from "../lib/ops-report.js";
12
- import { canPromptOnStderr } from "../lib/prompt.js";
13
- import { selectDeployment } from "../lib/select-deployment.js";
5
+ import { WorkflowCommand } from "../../lib/base-command.js";
6
+ import { clientFor, resolveApiHost, resolveTokenOrFail } from "../../lib/client.js";
7
+ import { dedupeResources } from "../../lib/context.js";
8
+ import { fail } from "../../lib/fail.js";
9
+ import { loadWorkflowConfig } from "../../lib/load-config.js";
10
+ import { confirmationMatches, executeNuke, formatNukeSummary, involvedTargets, planCounts, renderNukePlan, resolveNukePlan, } from "../../lib/nuke.js";
11
+ import { runWriteVerb } from "../../lib/ops-report.js";
12
+ import { canPromptOnStderr } from "../../lib/prompt.js";
13
+ import { selectDeployment } from "../../lib/select-deployment.js";
14
14
  export default class Nuke extends WorkflowCommand {
15
+ static aliases = ['nuke'];
15
16
  static summary = 'Delete every engine-owned document for a deployment tag — the dev-period big red button.';
16
17
  static description = 'The reset for a dataset holding engine documents the versioned upgrade framework cannot yet ' +
17
18
  "migrate: deletes the tag's instances, definitions, and guards (across every alias-bound " +
@@ -1,5 +1,6 @@
1
- import { StubCommand } from '../lib/stub.ts';
1
+ import { StubCommand } from '../../lib/stub.ts';
2
2
  export default class ResetActivity extends StubCommand {
3
+ static hiddenAliases: string[];
3
4
  static hidden: boolean;
4
5
  static description: string;
5
6
  static args: {
@@ -1,6 +1,7 @@
1
1
  import { Args } from '@oclif/core';
2
- import { StubCommand } from "../lib/stub.js";
2
+ import { StubCommand } from "../../lib/stub.js";
3
3
  export default class ResetActivity extends StubCommand {
4
+ static hiddenAliases = ['reset-activity'];
4
5
  static hidden = true;
5
6
  static description = 'Reset a failed activity on an in-flight instance — back to pending (re-run) or to skipped (bypass).';
6
7
  static args = {
@@ -1,8 +1,9 @@
1
1
  import { type SetStageArgs, type WorkflowInstance } from '@sanity/workflow-engine';
2
- import { WorkflowCommand } from '../lib/base-command.ts';
3
- import { type EngineScope } from '../lib/operation-args.ts';
4
- import { type WriteOutcome, type WriteReport } from '../lib/ops-report.ts';
2
+ import { WorkflowCommand } from '../../lib/base-command.ts';
3
+ import { type EngineScope } from '../../lib/operation-args.ts';
4
+ import { type WriteOutcome, type WriteReport } from '../../lib/ops-report.ts';
5
5
  export default class SetStage extends WorkflowCommand {
6
+ static aliases: string[];
6
7
  static description: string;
7
8
  static examples: string[];
8
9
  static args: {
@@ -1,12 +1,13 @@
1
1
  import { styleText } from 'node:util';
2
2
  import { Args, Flags } from '@oclif/core';
3
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, opsAppliedLines, runWriteVerb, } from "../lib/ops-report.js";
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, opsAppliedLines, runWriteVerb, } from "../../lib/ops-report.js";
9
9
  export default class SetStage extends WorkflowCommand {
10
+ static aliases = ['set-stage'];
10
11
  static description = "Force an instance into a stage, regardless of its declared transitions and filters — the engine's setStage admin override. The target stage's enter lifecycle still runs (auto-activities start, stage guards reconcile), and the post-move cascade can immediately auto-transition the instance onward.";
11
12
  static examples = [
12
13
  '<%= config.bin %> set-stage wf-instance.abc123 --to ready',
@@ -1,6 +1,7 @@
1
1
  import { type WorkflowInstance } from '@sanity/workflow-engine';
2
- import { WorkflowCommand } from '../lib/base-command.ts';
2
+ import { WorkflowCommand } from '../../lib/base-command.ts';
3
3
  export default class Show extends WorkflowCommand {
4
+ static aliases: string[];
4
5
  static description: string;
5
6
  static examples: string[];
6
7
  static args: {
@@ -2,11 +2,12 @@ import { styleText } from 'node:util';
2
2
  import { Args, Flags } from '@oclif/core';
3
3
  import { abortReason, displayTitle, terminalState, } from '@sanity/workflow-engine';
4
4
  import logSymbols from 'log-symbols';
5
- import { WorkflowCommand } from "../lib/base-command.js";
6
- import { findInstance, resolveReadTargets } from "../lib/context.js";
7
- import { tagFlags } from "../lib/flags.js";
8
- import { formatKeyValue, formatTimestamp, sectionHeader, activityIcon } from "../lib/ui.js";
5
+ import { WorkflowCommand } from "../../lib/base-command.js";
6
+ import { findInstance, resolveReadTargets } from "../../lib/context.js";
7
+ import { tagFlags } from "../../lib/flags.js";
8
+ import { formatKeyValue, formatTimestamp, sectionHeader, activityIcon } from "../../lib/ui.js";
9
9
  export default class Show extends WorkflowCommand {
10
+ static aliases = ['show'];
10
11
  static description = 'Show the state, activities, and effects of a workflow instance.';
11
12
  static examples = [
12
13
  '<%= config.bin %> show wf-instance.abc123',
@@ -67,27 +68,40 @@ export function instanceHeader(instance) {
67
68
  return [title, ...rows].join('\n');
68
69
  }
69
70
  export function describeInstance(instance, options) {
70
- const lines = [sectionHeader('Stages')];
71
- for (const stage of instance.stages) {
72
- const marker = stage.exitedAt
73
- ? styleText('dim', ` (exited ${formatTimestamp(stage.exitedAt)})`)
74
- : styleText('cyan', ' (current)');
75
- lines.push(` • ${stage.name}${marker}`);
76
- for (const activity of stage.activities ?? []) {
77
- lines.push(` ${activityIcon[activity.status]} ${activity.name} ${styleText('dim', `[${activity.status}]`)}`);
78
- }
79
- }
80
- if (instance.pendingEffects.length > 0) {
81
- lines.push('', sectionHeader('Pending effects'));
82
- for (const eff of instance.pendingEffects) {
83
- lines.push(` • ${eff.name} ${styleText('dim', `(key=${eff._key})`)}`);
84
- }
85
- }
86
- if (options.includeHistory) {
87
- lines.push('', sectionHeader('History'));
88
- for (const entry of instance.history) {
89
- lines.push(` ${styleText('dim', `[${formatTimestamp(entry.at)}]`)} ${displayTitle(entry._type)}`);
90
- }
71
+ return [
72
+ ...stageLines(instance),
73
+ ...pendingEffectLines(instance),
74
+ ...(options.includeHistory ? historyLines(instance) : []),
75
+ ];
76
+ }
77
+ function stageLines(instance) {
78
+ return [
79
+ sectionHeader('Stages'),
80
+ ...instance.stages.flatMap((stage) => [
81
+ ` • ${stage.name}${stageMarker(stage)}`,
82
+ ...(stage.activities ?? []).map((activity) => ` ${activityIcon[activity.status]} ${activity.name} ${styleText('dim', `[${activity.status}]`)}`),
83
+ ]),
84
+ ];
85
+ }
86
+ function stageMarker(stage) {
87
+ return stage.exitedAt
88
+ ? styleText('dim', ` (exited ${formatTimestamp(stage.exitedAt)})`)
89
+ : styleText('cyan', ' (current)');
90
+ }
91
+ function pendingEffectLines(instance) {
92
+ if (instance.pendingEffects.length === 0) {
93
+ return [];
91
94
  }
92
- return lines;
95
+ return [
96
+ '',
97
+ sectionHeader('Pending effects'),
98
+ ...instance.pendingEffects.map((eff) => ` • ${eff.name} ${styleText('dim', `(key=${eff._key})`)}`),
99
+ ];
100
+ }
101
+ function historyLines(instance) {
102
+ return [
103
+ '',
104
+ sectionHeader('History'),
105
+ ...instance.history.map((entry) => ` ${styleText('dim', `[${formatTimestamp(entry.at)}]`)} ${displayTitle(entry._type)}`),
106
+ ];
93
107
  }
@@ -1,7 +1,8 @@
1
1
  import { StartNotSettledError, type InitialFieldValue, type StartInstanceArgs, type WorkflowInstance } from '@sanity/workflow-engine';
2
- import { WorkflowCommand } from '../lib/base-command.ts';
3
- import { type EngineScope } from '../lib/operation-args.ts';
2
+ import { WorkflowCommand } from '../../lib/base-command.ts';
3
+ import { type EngineScope } from '../../lib/operation-args.ts';
4
4
  export default class Start extends WorkflowCommand {
5
+ static aliases: string[];
5
6
  static description: string;
6
7
  static examples: string[];
7
8
  static args: {
@@ -1,15 +1,16 @@
1
1
  import { styleText } from 'node:util';
2
2
  import { Args, Flags } from '@oclif/core';
3
3
  import { buildInitialFields, errorMessage, StartNotPrimedError, StartNotSettledError, startRefusal, workflow, } from '@sanity/workflow-engine';
4
- import { WorkflowCommand } from "../lib/base-command.js";
5
- import { resolveContext } from "../lib/context.js";
6
- import { fetchDeployedDefinition } from "../lib/definitions.js";
7
- import { fail, failOnThrow, failureDetail } from "../lib/fail.js";
8
- import { jsonFlags, tagFlags } from "../lib/flags.js";
9
- import { baseEngineArgs } from "../lib/operation-args.js";
10
- import { runWriteVerb } from "../lib/ops-report.js";
11
- import { parseParams } from "../lib/params.js";
4
+ import { WorkflowCommand } from "../../lib/base-command.js";
5
+ import { resolveContext } from "../../lib/context.js";
6
+ import { fetchDeployedDefinition } from "../../lib/definitions.js";
7
+ import { fail, failOnThrow, failureDetail } from "../../lib/fail.js";
8
+ import { jsonFlags, tagFlags } from "../../lib/flags.js";
9
+ import { baseEngineArgs } from "../../lib/operation-args.js";
10
+ import { runWriteVerb } from "../../lib/ops-report.js";
11
+ import { parseParams } from "../../lib/params.js";
12
12
  export default class Start extends WorkflowCommand {
13
+ static aliases = ['start'];
13
14
  static description = 'Start a workflow instance from a deployed definition. Supply values for the ' +
14
15
  "workflow's input-sourced fields with --field (e.g. the subject document ref).";
15
16
  static examples = [
@@ -1,5 +1,6 @@
1
- import { WorkflowCommand } from '../lib/base-command.ts';
1
+ import { WorkflowCommand } from '../../lib/base-command.ts';
2
2
  export default class Tail extends WorkflowCommand {
3
+ static aliases: string[];
3
4
  static description: string;
4
5
  static examples: string[];
5
6
  static args: {
@@ -2,13 +2,14 @@ import { styleText } from 'node:util';
2
2
  import { Args } from '@oclif/core';
3
3
  import { assertReadableModel, displayTitle, errorMessage, } from '@sanity/workflow-engine';
4
4
  import logSymbols from 'log-symbols';
5
- import { WorkflowCommand } from "../lib/base-command.js";
6
- import { findInstance, resolveReadTargets } from "../lib/context.js";
7
- import { fail, failureDetail } from "../lib/fail.js";
8
- import { tagFlags } from "../lib/flags.js";
9
- import { formatTimestamp } from "../lib/ui.js";
5
+ import { WorkflowCommand } from "../../lib/base-command.js";
6
+ import { findInstance, resolveReadTargets } from "../../lib/context.js";
7
+ import { fail, failureDetail } from "../../lib/fail.js";
8
+ import { tagFlags } from "../../lib/flags.js";
9
+ import { formatTimestamp } from "../../lib/ui.js";
10
10
  const TAIL_TAG = 'tail';
11
11
  export default class Tail extends WorkflowCommand {
12
+ static aliases = ['tail'];
12
13
  static description = 'Stream new history entries on a workflow instance as they land in the dataset.';
13
14
  static examples = ['<%= config.bin %> tail wf-instance.abc123'];
14
15
  static args = {
@@ -1,8 +1,8 @@
1
- import { finishCliTelemetry, usedFlagNames } from "../../lib/telemetry.js";
1
+ import { finishCliTelemetry, traceCommandId, usedFlagNames } from "../../lib/telemetry.js";
2
2
  const hook = async function (options) {
3
3
  try {
4
4
  await finishCliTelemetry({
5
- command: options.id,
5
+ command: traceCommandId(options),
6
6
  flags: usedFlagNames(options.argv, options.Command?.flags),
7
7
  success: options.error === undefined,
8
8
  });
@@ -1,8 +1,9 @@
1
1
  import type { Hook } from '@oclif/core';
2
2
  /** Builds and installs the invocation's telemetry shell before the command
3
3
  * runs; the `finally` hook completes the trace and flushes. Never throws.
4
- * An explicit `--share-defs` forces the store to send despite CI /
5
- * `DO_NOT_TRACK` resolved from raw argv here, since the store is built
6
- * before oclif parses flags. */
4
+ * A deploy that may share definitions—flagless by default or explicitly
5
+ * enabledforces the store to send despite CI / `DO_NOT_TRACK`. This is
6
+ * resolved from raw argv because the store is built before oclif parses
7
+ * flags. */
7
8
  declare const hook: Hook<'prerun'>;
8
9
  export default hook;
@@ -1,11 +1,9 @@
1
1
  import { Command } from '@oclif/core';
2
2
  /**
3
- * Base for the API-backed workflow commands: the backstop that renders an
4
- * auth rejection (HTTP 401) escaping a command's `run` through the clean
5
- * {@link fail} path with {@link failureDetail}'s recovery hint — instead
6
- * of an oclif error dump. Errors caught inside commands render the same
7
- * detail at their own `fail` sites; every other error propagates to oclif
8
- * unchanged.
3
+ * Base for workflow commands: prompt interrupts exit with the conventional
4
+ * SIGINT code and no stack, while an auth rejection escaping `run` renders
5
+ * through the clean {@link fail} path with {@link failureDetail}'s recovery
6
+ * hint. Every other error propagates to oclif unchanged.
9
7
  */
10
8
  export declare abstract class WorkflowCommand extends Command {
11
9
  protected catch(err: Error & {
@@ -1,7 +1,13 @@
1
+ import { styleText } from 'node:util';
1
2
  import { Command } from '@oclif/core';
3
+ import { exitCodes } from '@sanity/cli-core';
2
4
  import { fail, failureDetail, isAuthRejection } from "./fail.js";
3
5
  export class WorkflowCommand extends Command {
4
6
  async catch(err) {
7
+ if (err.name === 'ExitPromptError' || err.message === 'SIGINT') {
8
+ this.logToStderr(`${styleText('yellow', '›')} Aborted by user`);
9
+ return this.exit(exitCodes.SIGINT);
10
+ }
5
11
  if (isAuthRejection(err)) {
6
12
  fail('Authentication failed:', failureDetail(err));
7
13
  }
@@ -1,7 +1,8 @@
1
1
  /** The environment tag (e.g. prod, test). For write commands it selects which
2
- * deployment in the discovered `sanity.workflow` config to act on (omittable
3
- * when only one is configured); for read commands it's an optional query
4
- * filter and the resource disambiguator when a config spans more than one. */
2
+ * deployment in the discovered `sanity.workflow` config to act on. A sole
3
+ * deployment needs no tag, and an interactive `deploy` asks when several are
4
+ * configured. For read commands it's an optional query filter and the
5
+ * resource disambiguator when a config spans more than one. */
5
6
  export declare const tagFlags: {
6
7
  tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
8
  };
@@ -4,7 +4,8 @@
4
4
  * `TERM` not dumb, no `CI` — so its `NonInteractiveError` can never escape a
5
5
  * caller that checked here first), adding stderr-TTY because this package's
6
6
  * prompts render on stderr: a redirected stderr must refuse rather than block
7
- * on stdin with the question swallowed. The one predicate every prompt site
8
- * (the deploy consent prompt, nuke's confirmation) shares.
7
+ * on stdin with the question swallowed. It classifies whether definition
8
+ * sharing can show its full first-run disclosure and guards interactive
9
+ * prompts such as nuke's confirmation.
9
10
  */
10
11
  export declare function canPromptOnStderr(): boolean;
@@ -1,4 +1,11 @@
1
1
  import { type DeployTarget, type WorkflowConfig, type WorkflowDeployment } from '@sanity/workflow-engine';
2
+ type ChooseDeploymentTag = (deployments: WorkflowDeployment[]) => Promise<string>;
3
+ interface DeploymentSelectionOptions {
4
+ tag: string | undefined;
5
+ allTags: boolean;
6
+ interactive?: boolean;
7
+ chooseTag?: ChooseDeploymentTag;
8
+ }
2
9
  /**
3
10
  * Pick the deployment for the requested `--tag`. Tags are unique across a
4
11
  * config (enforced by defineWorkflowConfig), so a tag names at most one
@@ -15,17 +22,15 @@ export declare function selectDeployment(config: WorkflowConfig, { tag, orAltern
15
22
  }): WorkflowDeployment;
16
23
  /**
17
24
  * The deployments a `deploy` run acts on: every one with `--all-tags`,
18
- * otherwise a single target via {@link selectDeployment} and its failure
19
- * modes. Deploying everything is an explicit opt-in never a default so an
20
- * ambiguous bare `deploy` can't fan a write out across environments.
25
+ * otherwise a single target via {@link selectDeployment}. An ambiguous bare
26
+ * interactive run asks for a tag; a run that cannot prompt keeps the explicit
27
+ * flag guidance. Deploying everything is an explicit opt-in never a default.
21
28
  */
22
- export declare function selectDeployments(config: WorkflowConfig, { tag, allTags }: {
23
- tag: string | undefined;
24
- allTags: boolean;
25
- }): WorkflowDeployment[];
29
+ export declare function selectDeployments(config: WorkflowConfig, { tag, allTags, interactive, chooseTag }: DeploymentSelectionOptions): Promise<WorkflowDeployment[]>;
26
30
  /**
27
31
  * Project a deployment into the engine's {@link DeployTarget} — the shape the
28
32
  * deploy/diff verbs (`deployDefinitions`, `computeDiffEntries`, `diffEntry`)
29
33
  * consume — expanding its handle bindings into the alias map in the same step.
30
34
  */
31
35
  export declare function deploymentToTarget(deployment: WorkflowDeployment): DeployTarget;
36
+ export {};
@@ -1,5 +1,7 @@
1
+ import { select } from '@sanity/cli-core/ux';
1
2
  import { resourceAliasesToMap, } from '@sanity/workflow-engine';
2
3
  import { fail } from "./fail.js";
4
+ import { canPromptOnStderr } from "./prompt.js";
3
5
  export function selectDeployment(config, { tag, orAlternative = '' }) {
4
6
  if (tag === undefined) {
5
7
  if (config.deployments.length > 1) {
@@ -17,19 +19,42 @@ export function selectDeployment(config, { tag, orAlternative = '' }) {
17
19
  }
18
20
  return deployment;
19
21
  }
20
- export function selectDeployments(config, { tag, allTags }) {
22
+ export async function selectDeployments(config, { tag, allTags, interactive, chooseTag = chooseDeploymentTag }) {
21
23
  if (allTags) {
22
24
  return config.deployments;
23
25
  }
26
+ if (tag === undefined && config.deployments.length > 1) {
27
+ if (!(interactive ?? canPromptOnStderr())) {
28
+ return [
29
+ selectDeployment(config, {
30
+ tag,
31
+ orAlternative: ', or --all-tags to deploy every deployment',
32
+ }),
33
+ ];
34
+ }
35
+ const selectedTag = await chooseTag(config.deployments);
36
+ return [selectDeployment(config, { tag: selectedTag })];
37
+ }
24
38
  return [
25
39
  selectDeployment(config, { tag, orAlternative: ', or --all-tags to deploy every deployment' }),
26
40
  ];
27
41
  }
42
+ async function chooseDeploymentTag(deployments) {
43
+ return select({
44
+ message: 'Select a deployment tag',
45
+ choices: deployments.map(({ name, tag }) => ({
46
+ name: tag,
47
+ value: tag,
48
+ description: name,
49
+ })),
50
+ }, { output: process.stderr });
51
+ }
28
52
  function availableTags(config) {
29
53
  return `Available tags: ${config.deployments.map((candidate) => candidate.tag).join(', ')}`;
30
54
  }
31
55
  export function deploymentToTarget(deployment) {
32
56
  return {
57
+ expectedMinReaderModel: deployment.expectedMinReaderModel,
33
58
  tag: deployment.tag,
34
59
  workflowResource: deployment.workflowResource,
35
60
  resourceAliases: resourceAliasesToMap(deployment.resourceAliases),
@@ -10,12 +10,11 @@
10
10
  * Consent model: opt-OUT. A deploy that creates new definition versions
11
11
  * donates by default. The choice is skipped by an explicit flag:
12
12
  * `--share-defs` (donate, no prompt) or `--no-share-defs` (don't). Without a
13
- * flag, an interactive terminal takes a ONE-TIME acknowledgement (persisted
14
- * in the shared Sanity user config, so it is asked once ever) before the
15
- * first donation notice must precede the send, since we cannot disclose
16
- * taking content after taking it. Unattended runs (CI / `DO_NOT_TRACK` / a
17
- * non-TTY pipe) can't prompt, so they donate nothing — the standard Sanity-CLI
18
- * "silent in CI / `DO_NOT_TRACK`" rule; opt in per run with `--share-defs`.
13
+ * flag, the CLI shares. An interactive terminal gets a ONE-TIME notice
14
+ * (persisted in the shared Sanity user config) before the first donation;
15
+ * every later flagless deploy, and every unattended deploy, prints a concise
16
+ * reminder. CI, `DO_NOT_TRACK`, and non-TTY execution do not change the
17
+ * content-sharing default. Only `--no-share-defs` opts out.
19
18
  */
20
19
  import { type DeployDefinitionResult, type DeployedDefinition, type WorkflowResource } from '@sanity/workflow-engine';
21
20
  import type { UserConfigStore } from './telemetry-setup.ts';
@@ -50,22 +49,20 @@ export interface ShareCandidate {
50
49
  * routed project-agnostically through the API gateway). */
51
50
  export declare const SHARE_ENDPOINT_URI = "/workflow/definition-feedback";
52
51
  /**
53
- * The first-run consent prompt — a product contract, pinned by test. It must
52
+ * The first-run disclosure — a product contract, pinned by test. It must
54
53
  * name the recipient (Sanity), state that the document ships VERBATIM with its
55
54
  * deployment coordinates and is kept, name what is never shared, and disclose
56
- * that the answer is remembered machine-wide (not just for this deploy) with
57
- * the per-run override. Shown once (persisted) before the first donation on an
58
- * interactive terminal; the answer decides and is remembered.
55
+ * that the notice is remembered machine-wide and name the per-run opt-out.
56
+ * This is a notice, not a choice: sharing is the default unless the invocation
57
+ * supplies `--no-share-defs`.
59
58
  */
60
- export declare const SHARE_CONSENT_PROMPT: string;
59
+ export declare const SHARE_FIRST_RUN_NOTICE: string;
61
60
  /**
62
- * The one-line reminders printed on every flagless interactive deploy after the
63
- * first product contracts, pinned by test. They keep an ongoing donation (or
64
- * a remembered decline) visible every run, never silent, and name the per-run
65
- * override. `_ON` shows when the remembered answer shares, `_OFF` when it does not.
61
+ * The status block printed on every flagless deploy that does not show the
62
+ * first-run disclosure. It keeps the default donation obvious in terminals and
63
+ * unattended logs and names both explicit controls.
66
64
  */
67
- export declare const SHARE_REMINDER_ON: string;
68
- export declare const SHARE_REMINDER_OFF: string;
65
+ export declare const SHARE_REMINDER: string;
69
66
  /**
70
67
  * The content-free telemetry marker for one shared definition — projected
71
68
  * from the engine's own deploy-event derivation ({@link definitionDeployedData})
@@ -80,9 +77,9 @@ export declare function definitionShareMarker(args: {
80
77
  }): WorkflowDefinitionSharedData;
81
78
  /**
82
79
  * Whether the invocation's telemetry should send despite the environment
83
- * denial (CI / `DO_NOT_TRACK`). Only an explicit `--share-defs` that actually
84
- * donates forces it a command-line arg beats env vars, and a `--share-defs`
85
- * donation must never be recorded-less. Account-level consent is never
80
+ * denial (CI / `DO_NOT_TRACK`). Every flagless or explicitly enabled deploy
81
+ * that can create versions forces it, because definition donation defaults on
82
+ * in those environments too. Account-level consent is never
86
83
  * overridden (the intake still reads `/intake/telemetry-status`).
87
84
  *
88
85
  * Computed from raw argv because the prerun hook builds the store before oclif
@@ -98,12 +95,12 @@ export declare function shouldForceShareTelemetry(args: {
98
95
  argv: string[];
99
96
  }): boolean;
100
97
  /**
101
- * The whole post-deploy sharing flow. Resolves the opt-out decision (explicit
102
- * flag, one-time acknowledgement, or standing policy), donates when it lands
103
- * on share, and always records the content-free per-invocation decision so
104
- * adoption dashboards can measure opt-out rate. No newly created versions
105
- * (unchanged re-deploys, dry runs, nothing succeeded) means no decision, no
106
- * prompt, and no POST.
98
+ * The whole post-deploy sharing flow. An explicit flag decides directly;
99
+ * otherwise sharing defaults on after emitting either the one-time disclosure
100
+ * or recurring reminder. It always records the content-free per-invocation
101
+ * decision so adoption dashboards can measure opt-out rate. No newly created
102
+ * versions (unchanged re-deploys, dry runs, nothing succeeded) means no
103
+ * decision, notice, or POST.
107
104
  *
108
105
  * The optional args exist for the flow's dependencies, mirroring
109
106
  * `setupCliTelemetry` — omitted, the real process surfaces apply.
@@ -113,8 +110,6 @@ export declare function shareDefinitionsAfterDeploy(args: {
113
110
  candidates: ShareCandidate[];
114
111
  warn: (message: string) => void;
115
112
  interactive?: boolean;
116
- envDenied?: boolean;
117
113
  writeStderr?: (message: string) => void;
118
114
  userConfig?: UserConfigStore;
119
- confirmShare?: () => Promise<boolean>;
120
115
  }): Promise<void>;