@contentful/experience-design-system-cli 2.12.1-dev-build-c47114b.0 → 2.12.2-dev-build-4dc32df.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/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.12.1-dev-build-c47114b.0",
3
+ "version": "2.12.2-dev-build-4dc32df.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -49,7 +49,7 @@ import { checkAgentAuth } from '../../generate/agent-runner.js';
49
49
  import { normalizePath } from '../path-utils.js';
50
50
  import { DEFAULT_CONFIGURED_HOST, toConfiguredHost } from '../../host-utils.js';
51
51
  import { writeExperiencesCredentials } from '../../credentials-store.js';
52
- import { nextStepAfterScopeGate, nextStepAfterCredentialsValidated, shouldBypassPreview, buildSkippedPreviewTransition, shouldRefusePush, buildSkippedPushTransition, } from './wizard-state-transitions.js';
52
+ import { nextStepAfterScopeGate, nextStepAfterCredentialsValidated, shouldBypassPreview, buildSkippedPreviewTransition, shouldRefusePush, buildSkippedPushTransition, shouldSkipFinalReviewAfterCredentials, } from './wizard-state-transitions.js';
53
53
  function findCliPath() {
54
54
  return join(fileURLToPath(import.meta.url), '..', '..', '..', '..', '..', 'bin', 'cli.js');
55
55
  }
@@ -263,6 +263,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
263
263
  credentialsSkipped: false,
264
264
  lastRunId: null,
265
265
  finalizeErrorBanner: null,
266
+ finalReviewPassed: false,
266
267
  });
267
268
  useEffect(() => {
268
269
  sessionRef.current = {
@@ -806,10 +807,15 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
806
807
  // accepted components) or jumps straight to push-decision-gate (if scope
807
808
  // rejected everything but tokens/removals still need to be pushed).
808
809
  const advanceAfterCredentialsValidated = async () => {
809
- // If we already ran the generator (re-entering credentials from a late
810
- // 401/403 raised by runPreview), skip back to push-decision-gate rather
811
- // than re-running the LLM.
812
- if (state.generateSessionId) {
810
+ // If the operator already went through final-review once (re-entering
811
+ // credentials from a late 401/403 raised by runPreview), skip back to
812
+ // push-decision-gate rather than making them review again. We gate on
813
+ // `finalReviewPassed` specifically — NOT `generateSessionId` alone —
814
+ // because the scope-gate background prefetch also populates
815
+ // `generateSessionId` as soon as its LLM finishes, and if that lands
816
+ // while the operator is still typing credentials it would otherwise
817
+ // trip this shortcut and skip past `final-review` entirely.
818
+ if (shouldSkipFinalReviewAfterCredentials(state)) {
813
819
  update({ step: 'push-decision-gate' });
814
820
  return;
815
821
  }
@@ -1504,6 +1510,10 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
1504
1510
  case 'final-review': {
1505
1511
  return (_jsx(FinalReviewHost, { extractSessionId: state.extractSessionId, generatedCount: state.generatedCount, autoAccept: autoAcceptScope, livePreview: livePreview, spaceId: state.spaceId, environmentId: state.environmentId, cmaToken: state.cmaToken, host: state.host, tokensPath: state.tokensPath, initialFinalizeError: state.finalizeErrorBanner, onFinalize: (accepted, rejected, unresolved) => {
1506
1512
  process.stderr.write(`Accepted: ${accepted} Rejected: ${rejected} Unresolved: ${unresolved}\n`);
1513
+ // Mark the review as passed so a later re-entry to credentials
1514
+ // (e.g. late 401 raised by runPreview) short-circuits back to
1515
+ // push-decision-gate instead of re-rendering final-review.
1516
+ update({ finalReviewPassed: true });
1507
1517
  // INTEG-4411 refined: no `accepted === 0` up-front block here.
1508
1518
  // A zero-accepted finalize can still be a valid push when the
1509
1519
  // operator explicitly rejected component(s) that exist server-
@@ -43,6 +43,26 @@ export declare function nextStepAfterScopeGate(opts: {
43
43
  export declare function nextStepAfterCredentialsValidated(opts: {
44
44
  acceptedCount: number;
45
45
  }): WizardStepAfterCredentials;
46
+ /**
47
+ * Bug fix (2026-07): the "skip generator, jump to push-decision-gate" shortcut
48
+ * on the credentials → post-credentials edge was originally guarded by
49
+ * `state.generateSessionId != null`. That signal is ALSO set by the scope-gate
50
+ * background prefetch as soon as the LLM finishes — so when a fast prefetch
51
+ * completed while the operator was still typing credentials, submitting them
52
+ * skipped `final-review` entirely and jumped straight to `push-decision-gate`.
53
+ *
54
+ * The real invariant the guard wants is: has the operator already been through
55
+ * the final-review screen and finalized once? That's what `finalReviewPassed`
56
+ * captures — it flips true in `onFinalize` on the GenerateReviewStep, not on
57
+ * mere prefetch completion.
58
+ *
59
+ * Retained (and required) is `generateSessionId != null`, so we don't jump to
60
+ * push-decision-gate before generation is even complete.
61
+ */
62
+ export declare function shouldSkipFinalReviewAfterCredentials(state: {
63
+ generateSessionId: string | null;
64
+ finalReviewPassed: boolean;
65
+ }): boolean;
46
66
  /**
47
67
  * Skip-credentials spec — Task 2. When the operator pressed `s` on the
48
68
  * credentials screen, the wizard advanced without validating creds. That
@@ -43,6 +43,25 @@ export function nextStepAfterScopeGate(opts) {
43
43
  export function nextStepAfterCredentialsValidated(opts) {
44
44
  return opts.acceptedCount > 0 ? 'generating' : 'push-decision-gate';
45
45
  }
46
+ /**
47
+ * Bug fix (2026-07): the "skip generator, jump to push-decision-gate" shortcut
48
+ * on the credentials → post-credentials edge was originally guarded by
49
+ * `state.generateSessionId != null`. That signal is ALSO set by the scope-gate
50
+ * background prefetch as soon as the LLM finishes — so when a fast prefetch
51
+ * completed while the operator was still typing credentials, submitting them
52
+ * skipped `final-review` entirely and jumped straight to `push-decision-gate`.
53
+ *
54
+ * The real invariant the guard wants is: has the operator already been through
55
+ * the final-review screen and finalized once? That's what `finalReviewPassed`
56
+ * captures — it flips true in `onFinalize` on the GenerateReviewStep, not on
57
+ * mere prefetch completion.
58
+ *
59
+ * Retained (and required) is `generateSessionId != null`, so we don't jump to
60
+ * push-decision-gate before generation is even complete.
61
+ */
62
+ export function shouldSkipFinalReviewAfterCredentials(state) {
63
+ return state.finalReviewPassed && state.generateSessionId != null;
64
+ }
46
65
  /**
47
66
  * Skip-credentials spec — Task 2. When the operator pressed `s` on the
48
67
  * credentials screen, the wizard advanced without validating creds. That
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.12.1-dev-build-c47114b.0",
3
+ "version": "2.12.2-dev-build-4dc32df.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,7 +37,7 @@
37
37
  "svelte": "^5.56.4",
38
38
  "ts-morph": "^27.0.2",
39
39
  "typescript": "^5.9.3",
40
- "@contentful/experience-design-system-types": "2.12.1-dev-build-c47114b.0"
40
+ "@contentful/experience-design-system-types": "2.12.2-dev-build-4dc32df.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@tsconfig/node24": "^24.0.3",