create-nx-workspace 22.4.2 → 22.4.4

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <p style="text-align: center;">
2
2
  <picture>
3
3
  <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
4
- <img alt="Nx - Smart Repos · Fast Builds" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
4
+ <img alt="Nx - Smart Monorepos · Fast Builds" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
5
5
  </picture>
6
6
  </p>
7
7
 
@@ -66,5 +66,5 @@ npx nx@latest init
66
66
  - [Blog Posts About Nx](https://nx.dev/blog)
67
67
 
68
68
  <p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-courses-and-videos.svg"
69
- width="100%" alt="Nx - Smart Repos · Fast Builds"></a></p>
69
+ width="100%" alt="Nx - Smart Monorepos · Fast Builds"></a></p>
70
70
 
@@ -1 +1 @@
1
- {"version":3,"file":"create-nx-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/bin/create-nx-workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-nx-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/bin/create-nx-workspace.ts"],"names":[],"mappings":"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"}
@@ -300,20 +300,13 @@ async function normalizeArgsMiddleware(argv) {
300
300
  const ghAvailable = (0, git_1.isGhCliAvailable)();
301
301
  let nxCloud;
302
302
  let completionMessageKey;
303
- const flowVariant = (0, ab_testing_1.getFlowVariant)();
304
303
  if (argv.skipGit === true) {
305
304
  nxCloud = 'skip';
306
305
  completionMessageKey = undefined;
307
306
  }
308
- else if (flowVariant === '2') {
309
- // Variant 2: Skip cloud prompt, auto-connect
310
- // Respect --nxCloud=skip if explicitly provided
311
- nxCloud = argv.nxCloud === 'skip' ? 'skip' : 'yes';
312
- completionMessageKey =
313
- nxCloud === 'skip' ? undefined : (0, ab_testing_1.getCompletionMessageKeyForVariant)();
314
- }
315
307
  else {
316
- // Variants 0 & 1: Show cloud prompt (different copy based on variant)
308
+ // Always show cloud prompt with "full platform" message (CLOUD-4147)
309
+ // Flow variant only affects completion banners, not this prompt
317
310
  nxCloud = await (0, prompts_1.determineNxCloudV2)(argv);
318
311
  completionMessageKey =
319
312
  nxCloud === 'skip' ? undefined : (0, ab_testing_1.getCompletionMessageKeyForVariant)();
@@ -327,7 +320,6 @@ async function normalizeArgsMiddleware(argv) {
327
320
  defaultBase: 'main',
328
321
  aiAgents,
329
322
  ghAvailable,
330
- skipCloudConnect: flowVariant === '2',
331
323
  });
332
324
  await (0, ab_testing_1.recordStat)({
333
325
  nxVersion: nx_version_1.nxVersion,
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "create-nx-workspace",
3
- "version": "22.4.2",
3
+ "version": "22.4.4",
4
4
  "private": false,
5
- "description": "Smart Repos · Fast Builds",
5
+ "description": "Smart Monorepos · Fast Builds",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/nrwl/nx.git",
@@ -1 +1 @@
1
- {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/src/create-workspace.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAGL,aAAa,EACd,MAAM,iBAAiB,CAAC;AAsBzB,wBAAgB,4BAA4B,IAAI;IAC9C,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAEA;AAED,wBAAsB,eAAe,CAAC,CAAC,SAAS,sBAAsB,EACpE,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,EACV,OAAO,CAAC,EAAE,CAAC;;;;;GA0LZ;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D"}
1
+ {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/src/create-workspace.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAGL,aAAa,EACd,MAAM,iBAAiB,CAAC;AA0BzB,wBAAgB,4BAA4B,IAAI;IAC9C,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAEA;AAED,wBAAsB,eAAe,CAAC,CAAC,SAAS,sBAAsB,EACpE,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,EACV,OAAO,CAAC,EAAE,CAAC;;;;;GA6MZ;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D"}
@@ -16,6 +16,7 @@ const output_1 = require("./utils/output");
16
16
  const get_third_party_preset_1 = require("./utils/preset/get-third-party-preset");
17
17
  const preset_1 = require("./utils/preset/preset");
18
18
  const clone_template_1 = require("./utils/template/clone-template");
19
+ const update_readme_1 = require("./utils/template/update-readme");
19
20
  const child_process_utils_1 = require("./utils/child-process-utils");
20
21
  const package_manager_1 = require("./utils/package-manager");
21
22
  // State for SIGINT handler - only set after workspace is fully installed
@@ -140,9 +141,25 @@ async function createWorkspace(preset, options, rawArgs) {
140
141
  connectUrl = await (0, nx_cloud_1.createNxCloudOnboardingUrl)(nxCloud, token, directory, useGitHub);
141
142
  // Store for SIGINT handler
142
143
  cloudConnectUrl = connectUrl;
144
+ // Update README with connect URL (strips markers, adds connect section)
145
+ // Then commit the change - amend if not pushed, new commit if already pushed
146
+ if (isTemplate) {
147
+ const readmeUpdated = (0, update_readme_1.addConnectUrlToReadme)(directory, connectUrl);
148
+ if (readmeUpdated && !skipGit && commit) {
149
+ const alreadyPushed = pushedToVcs === git_1.VcsPushStatus.PushedToVcs;
150
+ await (0, update_readme_1.amendOrCommitReadme)(directory, alreadyPushed);
151
+ }
152
+ }
143
153
  nxCloudInfo = await (0, nx_cloud_1.getNxCloudInfo)(connectUrl, pushedToVcs, options.completionMessageKey, name);
144
154
  }
145
155
  else if (isTemplate && nxCloud === 'skip') {
156
+ // Strip marker comments from README even when cloud is skipped
157
+ // so users don't see raw <!-- BEGIN/END: nx-cloud --> markers
158
+ const readmeUpdated = (0, update_readme_1.addConnectUrlToReadme)(directory, undefined);
159
+ if (readmeUpdated && !skipGit && commit) {
160
+ const alreadyPushed = pushedToVcs === git_1.VcsPushStatus.PushedToVcs;
161
+ await (0, update_readme_1.amendOrCommitReadme)(directory, alreadyPushed);
162
+ }
146
163
  // Show nx connect message when user skips cloud in template flow
147
164
  nxCloudInfo = (0, nx_cloud_1.getSkippedNxCloudInfo)();
148
165
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../packages/create-nx-workspace/src/internal-utils/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B,OAAO,EAEL,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EACL,KAAK,EAGN,MAAM,6BAA6B,CAAC;AAGrC,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,GAChD,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACvE,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,CAsD5B;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACrE,OAAO,CAAC,OAAO,CAAC,CAelB;AA4BD,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC,GACD,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,CA4C5B;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACzE,OAAO,CAAC,KAAK,EAAE,CAAC,CAElB;AAqBD,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,GACtD,OAAO,CAAC,cAAc,CAAC,CAiCzB"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../packages/create-nx-workspace/src/internal-utils/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,EAEL,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EACL,KAAK,EAGN,MAAM,6BAA6B,CAAC;AAGrC,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,GAChD,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACvE,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,CAgC5B;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACrE,OAAO,CAAC,OAAO,CAAC,CAelB;AA4BD,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC,GACD,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,CA4C5B;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACzE,OAAO,CAAC,KAAK,EAAE,CAAC,CAElB;AAqBD,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,GACtD,OAAO,CAAC,cAAc,CAAC,CAiCzB"}
@@ -37,36 +37,19 @@ async function determineNxCloudV2(parsedArgs) {
37
37
  if (!parsedArgs.interactive || (0, is_ci_1.isCI)()) {
38
38
  return 'skip';
39
39
  }
40
- // Variant 2: Skip prompt and auto-connect
41
- if (!(0, ab_testing_1.shouldShowCloudPrompt)()) {
42
- return 'github';
43
- }
44
- // Variants 0 & 1: Show cloud prompt with different copy
45
- const variant = (0, ab_testing_1.getFlowVariant)();
46
- const promptConfig = variant === '1'
47
- ? {
48
- name: 'nxCloud',
49
- message: 'Would you like remote caching to make your build faster?',
50
- type: 'autocomplete',
51
- choices: [
52
- { value: 'yes', name: 'Yes' },
53
- { value: 'skip', name: 'Skip' },
54
- ],
55
- initial: 0,
56
- hint: () => chalk.dim('\n(can be disabled any time)'),
57
- footer: () => chalk.dim('\nRead more about remote caching at https://nx.dev/ci/features/remote-cache'),
58
- }
59
- : {
60
- name: 'nxCloud',
61
- message: 'Try the full Nx platform?',
62
- type: 'autocomplete',
63
- choices: [
64
- { value: 'yes', name: 'Yes' },
65
- { value: 'skip', name: 'Skip' },
66
- ],
67
- initial: 0,
68
- footer: () => chalk.dim('\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud'),
69
- };
40
+ // Locked to "full platform" messaging (CLOUD-4147)
41
+ // Flow variant only affects completion banners, not this prompt
42
+ const promptConfig = {
43
+ name: 'nxCloud',
44
+ message: 'Try the full Nx platform?',
45
+ type: 'autocomplete',
46
+ choices: [
47
+ { value: 'yes', name: 'Yes' },
48
+ { value: 'skip', name: 'Skip' },
49
+ ],
50
+ initial: 0,
51
+ footer: () => chalk.dim('\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud'),
52
+ };
70
53
  const result = await enquirer.prompt([
71
54
  promptConfig,
72
55
  ]);
@@ -1,21 +1,34 @@
1
- import type { CompletionMessageKey } from './messages';
1
+ import type { BannerVariant, CompletionMessageKey } from './messages';
2
2
  /**
3
3
  * Returns the flow variant for tracking (0 = preset, 1 = template).
4
4
  */
5
5
  export declare function getFlowVariant(): string;
6
6
  /**
7
- * Returns the completion message key based on the current flow variant.
8
- * - Variant 0: 'platform-setup' (shows "Try the full Nx platform?" prompt)
9
- * - Variant 1: 'cache-setup' (shows "Would you like remote caching..." prompt)
10
- * - Variant 2: 'platform-promo' (skips prompt, auto-connects, shows promo message)
7
+ * Returns the completion message key.
8
+ * Now locked to 'platform-setup' after concluding the prompt A/B test.
11
9
  */
12
10
  export declare function getCompletionMessageKeyForVariant(): CompletionMessageKey;
13
11
  /**
14
12
  * Returns whether the cloud prompt should be shown.
15
- * Variants 0 and 1 show prompts (with different copy).
16
- * Variant 2 skips the prompt and auto-connects.
13
+ * Now always returns true since we've locked in the prompt flow.
17
14
  */
18
15
  export declare function shouldShowCloudPrompt(): boolean;
16
+ /**
17
+ * Check if the given cloud URL is an enterprise URL.
18
+ * Enterprise URLs are anything other than cloud.nx.app, eu.nx.app, staging.nx.app, or snapshot.nx.app.
19
+ */
20
+ export declare function isEnterpriseCloudUrl(cloudUrl?: string): boolean;
21
+ /**
22
+ * Get the banner variant for completion messages.
23
+ * Uses NX_CNW_FLOW_VARIANT to determine which banner to show.
24
+ * - Variant 0: Plain link (control) - always used for enterprise URLs
25
+ * - Variant 1: "Try the full Nx platform" banner
26
+ * - Variant 2: "Unlock 70% faster CI" banner
27
+ * - Variant 3: "Reclaim your team's focus" banner
28
+ *
29
+ * @param cloudUrl - The Nx Cloud URL. If enterprise, always returns '0'.
30
+ */
31
+ export declare function getBannerVariant(cloudUrl?: string): BannerVariant;
19
32
  export declare const NxCloudChoices: string[];
20
33
  declare const messageOptions: Record<string, MessageData[]>;
21
34
  export type MessageKey = keyof typeof messageOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"ab-testing.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/ab-testing.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAqEvD;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAKvC;AAED;;;;;GAKG;AACH,wBAAgB,iCAAiC,IAAI,oBAAoB,CASxE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAG/C;AAED,eAAO,MAAM,cAAc,UAQ1B,CAAC;AAEF,QAAA,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAsGjD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,cAAc,CAAC;AACrD,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,UAAU,CAAA;KAAE,CAAC;IAC9C,iBAAiB,EAAE,oBAAoB,CAAC;CACzC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,gBAAgB,CAAwC;IAEhE,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW;IAavC,2BAA2B,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM;IAQpD,iCAAiC,CAAC,GAAG,EAAE,UAAU,GAAG,oBAAoB;CAQzE;AAED,eAAO,MAAM,QAAQ,gBAAuB,CAAC;AAS7C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,cAAc,GACtB,mBAAmB,GACnB,sBAAsB,GACtB,mBAAmB,GACnB,oBAAoB,GACpB,uBAAuB,CAAC;AAE5B;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;CACtB,iBAuBA"}
1
+ {"version":3,"file":"ab-testing.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/ab-testing.ts"],"names":[],"mappings":"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"}
@@ -4,13 +4,16 @@ exports.messages = exports.PromptMessages = exports.NxCloudChoices = void 0;
4
4
  exports.getFlowVariant = getFlowVariant;
5
5
  exports.getCompletionMessageKeyForVariant = getCompletionMessageKeyForVariant;
6
6
  exports.shouldShowCloudPrompt = shouldShowCloudPrompt;
7
+ exports.isEnterpriseCloudUrl = isEnterpriseCloudUrl;
8
+ exports.getBannerVariant = getBannerVariant;
7
9
  exports.recordStat = recordStat;
8
10
  const node_child_process_1 = require("node:child_process");
9
11
  const node_fs_1 = require("node:fs");
10
12
  const node_path_1 = require("node:path");
11
13
  const node_os_1 = require("node:os");
12
14
  const is_ci_1 = require("../ci/is-ci");
13
- // TODO(jack): Remove flow variant logic after A/B testing is complete
15
+ // Flow variant controls both tracking and banner display (CLOUD-4147)
16
+ // Variants: 0 = plain link, 1-3 = decorative banners
14
17
  const FLOW_VARIANT_CACHE_FILE = (0, node_path_1.join)((0, node_os_1.tmpdir)(), 'nx-cnw-flow-variant');
15
18
  const FLOW_VARIANT_EXPIRY_MS = 7 * 24 * 60 * 60 * 1000; // 1 week
16
19
  // In-memory cache to ensure consistency within a single run
@@ -31,7 +34,7 @@ function readCachedFlowVariant() {
31
34
  return null;
32
35
  }
33
36
  const value = (0, node_fs_1.readFileSync)(FLOW_VARIANT_CACHE_FILE, 'utf-8').trim();
34
- return value === '0' || value === '1' || value === '2' ? value : null;
37
+ return ['0', '1', '2', '3'].includes(value) ? value : null;
35
38
  }
36
39
  catch {
37
40
  return null;
@@ -47,11 +50,13 @@ function writeCachedFlowVariant(variant) {
47
50
  }
48
51
  function selectRandomVariant() {
49
52
  const rand = Math.random();
50
- if (rand < 0.33)
53
+ if (rand < 0.25)
51
54
  return '0';
52
- if (rand < 0.66)
55
+ if (rand < 0.5)
53
56
  return '1';
54
- return '2';
57
+ if (rand < 0.75)
58
+ return '2';
59
+ return '3';
55
60
  }
56
61
  /**
57
62
  * Internal function to determine and cache the flow variant.
@@ -81,29 +86,64 @@ function getFlowVariant() {
81
86
  return flowVariantCache ?? getFlowVariantInternal();
82
87
  }
83
88
  /**
84
- * Returns the completion message key based on the current flow variant.
85
- * - Variant 0: 'platform-setup' (shows "Try the full Nx platform?" prompt)
86
- * - Variant 1: 'cache-setup' (shows "Would you like remote caching..." prompt)
87
- * - Variant 2: 'platform-promo' (skips prompt, auto-connects, shows promo message)
89
+ * Returns the completion message key.
90
+ * Now locked to 'platform-setup' after concluding the prompt A/B test.
88
91
  */
89
92
  function getCompletionMessageKeyForVariant() {
90
- const variant = getFlowVariant();
91
- if (variant === '1') {
92
- return 'cache-setup';
93
- }
94
- if (variant === '2') {
95
- return 'platform-promo';
96
- }
97
93
  return 'platform-setup';
98
94
  }
99
95
  /**
100
96
  * Returns whether the cloud prompt should be shown.
101
- * Variants 0 and 1 show prompts (with different copy).
102
- * Variant 2 skips the prompt and auto-connects.
97
+ * Now always returns true since we've locked in the prompt flow.
103
98
  */
104
99
  function shouldShowCloudPrompt() {
105
- const variant = getFlowVariant();
106
- return variant !== '2';
100
+ return true;
101
+ }
102
+ // ============================================================================
103
+ // Banner Variant A/B Testing (CLOUD-4147)
104
+ // ============================================================================
105
+ /**
106
+ * Standard Nx Cloud URLs that should participate in banner A/B testing.
107
+ * Enterprise URLs (any other URL) always get the plain link (variant 0).
108
+ */
109
+ const STANDARD_NX_CLOUD_HOSTS = [
110
+ 'cloud.nx.app',
111
+ 'eu.nx.app',
112
+ 'staging.nx.app',
113
+ 'snapshot.nx.app',
114
+ ];
115
+ /**
116
+ * Check if the given cloud URL is an enterprise URL.
117
+ * Enterprise URLs are anything other than cloud.nx.app, eu.nx.app, staging.nx.app, or snapshot.nx.app.
118
+ */
119
+ function isEnterpriseCloudUrl(cloudUrl) {
120
+ if (!cloudUrl)
121
+ return false;
122
+ try {
123
+ const url = new URL(cloudUrl);
124
+ return !STANDARD_NX_CLOUD_HOSTS.includes(url.hostname);
125
+ }
126
+ catch {
127
+ return false;
128
+ }
129
+ }
130
+ /**
131
+ * Get the banner variant for completion messages.
132
+ * Uses NX_CNW_FLOW_VARIANT to determine which banner to show.
133
+ * - Variant 0: Plain link (control) - always used for enterprise URLs
134
+ * - Variant 1: "Try the full Nx platform" banner
135
+ * - Variant 2: "Unlock 70% faster CI" banner
136
+ * - Variant 3: "Reclaim your team's focus" banner
137
+ *
138
+ * @param cloudUrl - The Nx Cloud URL. If enterprise, always returns '0'.
139
+ */
140
+ function getBannerVariant(cloudUrl) {
141
+ // Enterprise URLs always get plain link (variant 0)
142
+ if (isEnterpriseCloudUrl(cloudUrl)) {
143
+ return '0';
144
+ }
145
+ // Use the flow variant (which handles docs generation, env var, and caching)
146
+ return getFlowVariant();
107
147
  }
108
148
  exports.NxCloudChoices = [
109
149
  'github',
@@ -138,23 +178,20 @@ const messageOptions = {
138
178
  ],
139
179
  /**
140
180
  * These messages are a fallback for setting up CI as well as when migrating major versions
181
+ * Locked to "full platform" messaging (CLOUD-4147)
141
182
  */
142
183
  setupNxCloud: [
143
184
  {
144
- code: 'enable-caching2',
145
- message: `Would you like remote caching to make your build faster?`,
185
+ code: 'cloud-v2-full-platform-visit',
186
+ message: 'Try the full Nx platform?',
146
187
  initial: 0,
147
188
  choices: [
148
189
  { value: 'yes', name: 'Yes' },
149
- {
150
- value: 'skip',
151
- name: 'No - I would not like remote caching',
152
- },
190
+ { value: 'skip', name: 'Skip' },
153
191
  ],
154
- footer: '\nRead more about remote caching at https://nx.dev/ci/features/remote-cache',
155
- hint: `\n(can be disabled any time).`,
192
+ footer: '\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud',
156
193
  fallback: undefined,
157
- completionMessage: 'cache-setup',
194
+ completionMessage: 'platform-setup',
158
195
  },
159
196
  ],
160
197
  /**
@@ -1,4 +1,12 @@
1
1
  import { VcsPushStatus } from '../git/git';
2
+ /**
3
+ * Banner variants for the completion message experiment (CLOUD-4147).
4
+ * - '0': Plain link (control) - always used for enterprise URLs
5
+ * - '1': "Try the full Nx platform" decorative banner
6
+ * - '2': "Unlock 70% faster CI" decorative banner
7
+ * - '3': "Reclaim your team's focus" decorative banner
8
+ */
9
+ export type BannerVariant = '0' | '1' | '2' | '3';
2
10
  /**
3
11
  * Completion messages shown after workspace creation.
4
12
  * Keys are referenced by ab-testing.ts prompts via completionMessage field.
@@ -13,13 +21,9 @@ declare const completionMessages: {
13
21
  readonly 'platform-setup': {
14
22
  readonly title: "Your platform setup is almost complete.";
15
23
  };
16
- readonly 'platform-promo': {
17
- readonly title: "Want faster builds?";
18
- readonly subtext: "Remote caching · Self-healing CI · Task distribution";
19
- };
20
24
  };
21
25
  export type CompletionMessageKey = keyof typeof completionMessages;
22
- export declare function getCompletionMessage(completionMessageKey: CompletionMessageKey | undefined, url: string | null, pushedToVcs: VcsPushStatus, workspaceName?: string): {
26
+ export declare function getCompletionMessage(completionMessageKey: CompletionMessageKey | undefined, url: string | null, pushedToVcs: VcsPushStatus, workspaceName?: string, bannerVariant?: BannerVariant): {
23
27
  title: string;
24
28
  bodyLines: string[];
25
29
  };
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAoC3C;;;GAGG;AACH,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;CAcd,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEnE,wBAAgB,oBAAoB,CAClC,oBAAoB,EAAE,oBAAoB,GAAG,SAAS,EACtD,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,WAAW,EAAE,aAAa,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAgBxC;AAED,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAUA"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAuFlD;;;GAGG;AACH,QAAA,MAAM,kBAAkB;;;;;;;;;;CAUd,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEnE,wBAAgB,oBAAoB,CAClC,oBAAoB,EAAE,oBAAoB,GAAG,SAAS,EACtD,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,WAAW,EAAE,aAAa,EAC1B,aAAa,CAAC,EAAE,MAAM,EACtB,aAAa,CAAC,EAAE,aAAa,GAC5B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBxC;AAED,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAUA"}
@@ -3,20 +3,53 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCompletionMessage = getCompletionMessage;
4
4
  exports.getSkippedCloudMessage = getSkippedCloudMessage;
5
5
  const git_1 = require("../git/git");
6
- function getSetupMessage(url, pushedToVcs, workspaceName, isPromo) {
6
+ /**
7
+ * Generates the decorative ASCII art banner for Nx Cloud.
8
+ * Line widths are carefully calculated to align properly.
9
+ */
10
+ function generateDecorativeBanner(headline, url, subtext) {
11
+ // Fixed banner structure - pad content to fit within the box
12
+ // Total inner width is 60 characters
13
+ const innerWidth = 60;
14
+ const padCenter = (text, width) => {
15
+ const padding = width - text.length;
16
+ const leftPad = Math.floor(padding / 2);
17
+ const rightPad = padding - leftPad;
18
+ return ' '.repeat(leftPad) + text + ' '.repeat(rightPad);
19
+ };
20
+ const line1 = padCenter('', innerWidth);
21
+ const line2 = padCenter(`- ${headline} -`, innerWidth);
22
+ const line3 = padCenter(url, innerWidth);
23
+ const line4 = padCenter(subtext, innerWidth);
24
+ return [
25
+ ` ${'_'.repeat(innerWidth + 1)} ____ ___ __ `,
26
+ ` \\${line1}\\ \\ \\ \\ \\ \\ \\`,
27
+ ` \\${line2}\\ \\ \\ \\ \\ \\ \\`,
28
+ ` \\${line3}\\ \\ \\ \\ \\ \\ \\`,
29
+ ` \\${line4}\\ \\ \\ \\ \\ \\ \\ `,
30
+ ` \\${'_'.repeat(innerWidth)}\\ \\___\\ \\__\\ \\_\\`,
31
+ ];
32
+ }
33
+ /**
34
+ * Get banner lines based on the variant.
35
+ * Returns empty array for variant 0 (plain link).
36
+ */
37
+ function getBannerLines(variant, url) {
38
+ switch (variant) {
39
+ case '1':
40
+ return generateDecorativeBanner('Try the full Nx platform', url, 'Remote caching * Distribution * Self-healing CI');
41
+ case '2':
42
+ return generateDecorativeBanner('Unlock 70% faster CI', url, 'Remote caching & Distribution');
43
+ case '3':
44
+ return generateDecorativeBanner("Reclaim your team's focus", url, 'Self-healing CI + Remote caching');
45
+ default:
46
+ return [];
47
+ }
48
+ }
49
+ function getSetupMessage(url, pushedToVcs, workspaceName) {
7
50
  const githubUrl = workspaceName
8
51
  ? `https://github.com/new?name=${encodeURIComponent(workspaceName)}`
9
52
  : 'https://github.com/new';
10
- if (isPromo) {
11
- if (pushedToVcs === git_1.VcsPushStatus.PushedToVcs) {
12
- return url
13
- ? `Connect your repo to enable remote caching and self-healing CI at: ${url}`
14
- : 'Connect your repo at https://cloud.nx.app to enable remote caching and self-healing CI.';
15
- }
16
- return url
17
- ? `Connect your repo (${githubUrl}) to enable remote caching and self-healing CI at: ${url}`
18
- : `Connect your repo (${githubUrl}) to enable remote caching and self-healing CI at https://cloud.nx.app`;
19
- }
20
53
  if (pushedToVcs === git_1.VcsPushStatus.PushedToVcs) {
21
54
  return url
22
55
  ? `Go to Nx Cloud and finish the setup: ${url}`
@@ -41,20 +74,23 @@ const completionMessages = {
41
74
  'platform-setup': {
42
75
  title: 'Your platform setup is almost complete.',
43
76
  },
44
- 'platform-promo': {
45
- title: 'Want faster builds?',
46
- subtext: 'Remote caching \u00b7 Self-healing CI \u00b7 Task distribution',
47
- },
48
77
  };
49
- function getCompletionMessage(completionMessageKey, url, pushedToVcs, workspaceName) {
78
+ function getCompletionMessage(completionMessageKey, url, pushedToVcs, workspaceName, bannerVariant) {
50
79
  const key = completionMessageKey ?? 'ci-setup';
51
80
  const messageConfig = completionMessages[key];
52
- const isPromo = key === 'platform-promo';
53
- const bodyLines = [getSetupMessage(url, pushedToVcs, workspaceName, isPromo)];
54
- if ('subtext' in messageConfig && messageConfig.subtext) {
55
- bodyLines.push('');
56
- bodyLines.push(messageConfig.subtext);
81
+ const variant = bannerVariant ?? '0';
82
+ // For decorative banner variants (1, 2, 3), show the banner instead of plain text
83
+ if (variant !== '0' && url) {
84
+ const bannerLines = getBannerLines(variant, url);
85
+ if (bannerLines.length > 0) {
86
+ return {
87
+ title: messageConfig.title,
88
+ bodyLines: [...bannerLines, ''],
89
+ };
90
+ }
57
91
  }
92
+ // Variant 0 (control) or fallback: plain link message
93
+ const bodyLines = [getSetupMessage(url, pushedToVcs, workspaceName)];
58
94
  return {
59
95
  title: messageConfig.title,
60
96
  bodyLines,
@@ -1 +1 @@
1
- {"version":3,"file":"nx-cloud.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/nx-cloud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAGL,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,OAAO,GACf,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,qBAAqB,GACrB,UAAU,GACV,MAAM,CAAC;AAEX,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BxB;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,UAgBjD;AAED,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED,wBAAsB,cAAc,CAClC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,aAAa,EAC1B,oBAAoB,CAAC,EAAE,oBAAoB,EAC3C,aAAa,CAAC,EAAE,MAAM,mBAWvB;AAED,wBAAgB,qBAAqB,WAIpC"}
1
+ {"version":3,"file":"nx-cloud.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/nx-cloud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAGL,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,OAAO,GACf,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,qBAAqB,GACrB,UAAU,GACV,MAAM,CAAC;AAEX,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BxB;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,UAgBjD;AAED,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED,wBAAsB,cAAc,CAClC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,aAAa,EAC1B,oBAAoB,CAAC,EAAE,oBAAoB,EAC3C,aAAa,CAAC,EAAE,MAAM,mBAevB;AAED,wBAAgB,qBAAqB,WAIpC"}
@@ -60,7 +60,10 @@ async function createNxCloudOnboardingUrl(nxCloud, token, directory, useGitHub)
60
60
  }
61
61
  async function getNxCloudInfo(connectCloudUrl, pushedToVcs, completionMessageKey, workspaceName) {
62
62
  const out = new output_1.CLIOutput(false);
63
- const message = (0, messages_1.getCompletionMessage)(completionMessageKey, connectCloudUrl, pushedToVcs, workspaceName);
63
+ // Get the banner variant based on the cloud URL
64
+ // Enterprise URLs automatically get variant 0 (plain link)
65
+ const bannerVariant = (0, ab_testing_1.getBannerVariant)(connectCloudUrl);
66
+ const message = (0, messages_1.getCompletionMessage)(completionMessageKey, connectCloudUrl, pushedToVcs, workspaceName, bannerVariant);
64
67
  out.success(message);
65
68
  return out.getOutput();
66
69
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Updates README content by processing the nx-cloud marker section.
3
+ * - If connectUrl is provided: replaces markers and content with the connect URL section
4
+ * - If connectUrl is undefined: removes markers and their content entirely
5
+ *
6
+ * This ensures users never see the raw <!-- BEGIN/END: nx-cloud --> markers in their README.
7
+ *
8
+ * @param readmeContent - The current README content
9
+ * @param connectUrl - The Nx Cloud connect URL (optional)
10
+ * @returns The updated README content with markers processed, or original if markers not found
11
+ */
12
+ export declare function updateReadmeContent(readmeContent: string, connectUrl: string | undefined): string;
13
+ /**
14
+ * Updates the README.md file in the given directory with the Nx Cloud connect URL.
15
+ * This is a convenience wrapper around updateReadmeContent that handles file I/O.
16
+ *
17
+ * @param directory - The workspace directory containing README.md
18
+ * @param connectUrl - The Nx Cloud connect URL
19
+ * @returns true if the file was modified, false otherwise
20
+ */
21
+ export declare function addConnectUrlToReadme(directory: string, connectUrl: string | undefined): boolean;
22
+ /**
23
+ * Commits README.md changes, either by amending the initial commit or creating a new one.
24
+ * - If already pushed to VCS: creates a new commit (to avoid requiring force push)
25
+ * - If not pushed: amends the initial commit (cleaner history)
26
+ *
27
+ * @param directory - The workspace directory
28
+ * @param alreadyPushed - Whether the repo was already pushed to VCS
29
+ */
30
+ export declare function amendOrCommitReadme(directory: string, alreadyPushed: boolean): Promise<void>;
31
+ //# sourceMappingURL=update-readme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-readme.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/template/update-readme.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,CAuCR;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAeT;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC,CAWf"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateReadmeContent = updateReadmeContent;
4
+ exports.addConnectUrlToReadme = addConnectUrlToReadme;
5
+ exports.amendOrCommitReadme = amendOrCommitReadme;
6
+ const node_fs_1 = require("node:fs");
7
+ const path_1 = require("path");
8
+ const child_process_utils_1 = require("../child-process-utils");
9
+ const BEGIN_MARKER = '<!-- BEGIN: nx-cloud -->';
10
+ const END_MARKER = '<!-- END: nx-cloud -->';
11
+ const CLOUD_SETUP_SECTION = `## Finish your Nx platform setup
12
+
13
+ 🚀 [Finish setting up your workspace]({{CONNECT_URL}}) to get faster builds with remote caching, distributed task execution, and self-healing CI. [Learn more about Nx Cloud](https://nx.dev/ci/intro/why-nx-cloud).
14
+ `;
15
+ /**
16
+ * Updates README content by processing the nx-cloud marker section.
17
+ * - If connectUrl is provided: replaces markers and content with the connect URL section
18
+ * - If connectUrl is undefined: removes markers and their content entirely
19
+ *
20
+ * This ensures users never see the raw <!-- BEGIN/END: nx-cloud --> markers in their README.
21
+ *
22
+ * @param readmeContent - The current README content
23
+ * @param connectUrl - The Nx Cloud connect URL (optional)
24
+ * @returns The updated README content with markers processed, or original if markers not found
25
+ */
26
+ function updateReadmeContent(readmeContent, connectUrl) {
27
+ const beginIndex = readmeContent.indexOf(BEGIN_MARKER);
28
+ const endIndex = readmeContent.indexOf(END_MARKER);
29
+ if (beginIndex === -1 || endIndex === -1 || beginIndex >= endIndex) {
30
+ return readmeContent;
31
+ }
32
+ // If no connect URL, remove the markers and placeholder content entirely
33
+ if (!connectUrl) {
34
+ // Remove the marker section and surrounding newlines to avoid extra blank lines
35
+ // Skip one newline before BEGIN marker (if present)
36
+ const beforeBegin = beginIndex > 0 && readmeContent[beginIndex - 1] === '\n'
37
+ ? beginIndex - 1
38
+ : beginIndex;
39
+ // Skip one newline after END marker (if present)
40
+ const afterEnd = endIndex + END_MARKER.length;
41
+ const skipTrailing = readmeContent[afterEnd] === '\n' ? afterEnd + 1 : afterEnd;
42
+ return (readmeContent.slice(0, beforeBegin) + readmeContent.slice(skipTrailing));
43
+ }
44
+ const section = CLOUD_SETUP_SECTION.replace('{{CONNECT_URL}}', connectUrl);
45
+ // Strip the markers - only include the section content
46
+ // Also skip one trailing newline after END marker since section already has one
47
+ const afterEnd = endIndex + END_MARKER.length;
48
+ const skipNewline = readmeContent[afterEnd] === '\n' ? afterEnd + 1 : afterEnd;
49
+ return (readmeContent.slice(0, beginIndex) +
50
+ section +
51
+ readmeContent.slice(skipNewline));
52
+ }
53
+ /**
54
+ * Updates the README.md file in the given directory with the Nx Cloud connect URL.
55
+ * This is a convenience wrapper around updateReadmeContent that handles file I/O.
56
+ *
57
+ * @param directory - The workspace directory containing README.md
58
+ * @param connectUrl - The Nx Cloud connect URL
59
+ * @returns true if the file was modified, false otherwise
60
+ */
61
+ function addConnectUrlToReadme(directory, connectUrl) {
62
+ const readmePath = (0, path_1.join)(directory, 'README.md');
63
+ if (!(0, node_fs_1.existsSync)(readmePath)) {
64
+ return false;
65
+ }
66
+ const content = (0, node_fs_1.readFileSync)(readmePath, 'utf-8');
67
+ const updated = updateReadmeContent(content, connectUrl);
68
+ if (updated !== content) {
69
+ (0, node_fs_1.writeFileSync)(readmePath, updated);
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ /**
75
+ * Commits README.md changes, either by amending the initial commit or creating a new one.
76
+ * - If already pushed to VCS: creates a new commit (to avoid requiring force push)
77
+ * - If not pushed: amends the initial commit (cleaner history)
78
+ *
79
+ * @param directory - The workspace directory
80
+ * @param alreadyPushed - Whether the repo was already pushed to VCS
81
+ */
82
+ async function amendOrCommitReadme(directory, alreadyPushed) {
83
+ await (0, child_process_utils_1.execAndWait)('git add README.md', directory);
84
+ if (alreadyPushed) {
85
+ await (0, child_process_utils_1.execAndWait)('git commit -m "chore: add Nx Cloud setup link to README"', directory);
86
+ await (0, child_process_utils_1.execAndWait)('git push', directory);
87
+ }
88
+ else {
89
+ await (0, child_process_utils_1.execAndWait)('git commit --amend --no-edit', directory);
90
+ }
91
+ }