create-nx-workspace 22.4.1 → 22.4.3

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.
@@ -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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"}
@@ -19,6 +19,7 @@ const ab_testing_1 = require("../src/utils/nx/ab-testing");
19
19
  const error_utils_1 = require("../src/utils/error-utils");
20
20
  const fs_1 = require("fs");
21
21
  const is_ci_1 = require("../src/utils/ci/is-ci");
22
+ const git_1 = require("../src/utils/git/git");
22
23
  function extractErrorFile(error) {
23
24
  if (!error.stack)
24
25
  return undefined;
@@ -208,6 +209,9 @@ process.on('uncaughtException', (error) => {
208
209
  process.on('SIGINT', async () => {
209
210
  const { directory, connectUrl } = (0, create_workspace_1.getInterruptedWorkspaceState)();
210
211
  if (directory) {
212
+ const path = require('path');
213
+ const workspaceName = path.basename(directory);
214
+ const githubUrl = `https://github.com/new?name=${encodeURIComponent(workspaceName)}`;
211
215
  console.log(''); // New line after ^C
212
216
  output_1.output.log({
213
217
  title: 'Workspace creation interrupted',
@@ -215,7 +219,7 @@ process.on('SIGINT', async () => {
215
219
  `Your workspace was created at: ${directory}`,
216
220
  '',
217
221
  'To complete the setup:',
218
- ' 1. Ensure your repo is pushed (e.g. https://github.com/new)',
222
+ ` 1. Ensure your repo is pushed (e.g. ${githubUrl})`,
219
223
  connectUrl
220
224
  ? ` 2. Connect to Nx Cloud: ${connectUrl}`
221
225
  : ' 2. Connect to Nx Cloud: Run "nx connect"',
@@ -292,10 +296,28 @@ async function normalizeArgsMiddleware(argv) {
292
296
  // Template flow - respects CLI arg, otherwise uses detected package manager (from invoking command)
293
297
  argv.template = template;
294
298
  const aiAgents = await (0, prompts_1.determineAiAgents)(argv);
295
- const nxCloud = argv.skipGit === true ? 'skip' : await (0, prompts_1.determineNxCloudV2)(argv);
296
- const completionMessageKey = nxCloud === 'skip'
297
- ? undefined
298
- : ab_testing_1.messages.completionMessageOfSelectedPrompt('setupNxCloudV2');
299
+ // Track GH CLI availability for telemetry
300
+ const ghAvailable = (0, git_1.isGhCliAvailable)();
301
+ let nxCloud;
302
+ let completionMessageKey;
303
+ const flowVariant = (0, ab_testing_1.getFlowVariant)();
304
+ if (argv.skipGit === true) {
305
+ nxCloud = 'skip';
306
+ completionMessageKey = undefined;
307
+ }
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
+ else {
316
+ // Variants 0 & 1: Show cloud prompt (different copy based on variant)
317
+ nxCloud = await (0, prompts_1.determineNxCloudV2)(argv);
318
+ completionMessageKey =
319
+ nxCloud === 'skip' ? undefined : (0, ab_testing_1.getCompletionMessageKeyForVariant)();
320
+ }
299
321
  packageManager = argv.packageManager ?? (0, package_manager_1.detectInvokedPackageManager)();
300
322
  Object.assign(argv, {
301
323
  nxCloud,
@@ -304,6 +326,8 @@ async function normalizeArgsMiddleware(argv) {
304
326
  packageManager,
305
327
  defaultBase: 'main',
306
328
  aiAgents,
329
+ ghAvailable,
330
+ skipCloudConnect: flowVariant === '2',
307
331
  });
308
332
  await (0, ab_testing_1.recordStat)({
309
333
  nxVersion: nx_version_1.nxVersion,
@@ -316,6 +340,7 @@ async function normalizeArgsMiddleware(argv) {
316
340
  preset: '',
317
341
  nodeVersion: process.versions.node ?? '',
318
342
  packageManager,
343
+ ghAvailable: ghAvailable ? 'true' : 'false',
319
344
  },
320
345
  });
321
346
  }
@@ -360,9 +385,7 @@ async function normalizeArgsMiddleware(argv) {
360
385
  nxCloud = await (0, prompts_1.determineNxCloudV2)(argv);
361
386
  useGitHub = nxCloud !== 'skip';
362
387
  completionMessageKey =
363
- nxCloud === 'skip'
364
- ? undefined
365
- : ab_testing_1.messages.completionMessageOfSelectedPrompt('setupNxCloudV2');
388
+ nxCloud === 'skip' ? undefined : (0, ab_testing_1.getCompletionMessageKeyForVariant)();
366
389
  }
367
390
  Object.assign(argv, {
368
391
  nxCloud,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nx-workspace",
3
- "version": "22.4.1",
3
+ "version": "22.4.3",
4
4
  "private": false,
5
5
  "description": "Smart Repos · Fast Builds",
6
6
  "repository": {
@@ -40,6 +40,15 @@ export interface CreateWorkspaceOptions {
40
40
  };
41
41
  cliName?: string;
42
42
  aiAgents?: Agent[];
43
+ /**
44
+ * @description Skip cloud connection (variant 1 experiment - NXC-3628)
45
+ * @default false
46
+ */
47
+ skipCloudConnect?: boolean;
48
+ /**
49
+ * @description Whether GitHub CLI (gh) is available on the system (for telemetry)
50
+ */
51
+ ghAvailable?: boolean;
43
52
  }
44
53
  export declare const supportedAgents: readonly ["claude", "codex", "copilot", "cursor", "gemini"];
45
54
  export type Agent = (typeof supportedAgents)[number];
@@ -1 +1 @@
1
- {"version":3,"file":"create-workspace-options.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/src/create-workspace-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,eAAe,6DAMlB,CAAC;AACX,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAMjD,CAAC"}
1
+ {"version":3,"file":"create-workspace-options.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/src/create-workspace-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,6DAMlB,CAAC;AACX,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAMjD,CAAC"}
@@ -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;;;;;GAgLZ;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
@@ -62,7 +63,8 @@ async function createWorkspace(preset, options, rawArgs) {
62
63
  throw e;
63
64
  }
64
65
  // Connect to Nx Cloud for template flow
65
- if (nxCloud !== 'skip') {
66
+ // For variant 1 (NXC-3628): Skip connection, use GitHub flow for URL generation
67
+ if (nxCloud !== 'skip' && !options.skipCloudConnect) {
66
68
  await (0, nx_cloud_1.connectToNxCloudForTemplate)(directory, 'create-nx-workspace', useGitHub);
67
69
  }
68
70
  }
@@ -127,13 +129,37 @@ async function createWorkspace(preset, options, rawArgs) {
127
129
  let connectUrl;
128
130
  let nxCloudInfo;
129
131
  if (nxCloud !== 'skip') {
130
- const token = (0, nx_cloud_1.readNxCloudToken)(directory);
132
+ // For variant 1 (skipCloudConnect=true): Skip readNxCloudToken() entirely
133
+ // - We didn't call connectToNxCloudForTemplate(), so no token exists
134
+ // - The spinner message "Checking Nx Cloud setup" would be misleading
135
+ // - createNxCloudOnboardingUrl() uses GitHub flow which sends accessToken: null
136
+ //
137
+ // For variant 0: Read the token as before (cloud was connected)
138
+ const token = options.skipCloudConnect
139
+ ? undefined
140
+ : (0, nx_cloud_1.readNxCloudToken)(directory);
131
141
  connectUrl = await (0, nx_cloud_1.createNxCloudOnboardingUrl)(nxCloud, token, directory, useGitHub);
132
142
  // Store for SIGINT handler
133
143
  cloudConnectUrl = connectUrl;
134
- nxCloudInfo = await (0, nx_cloud_1.getNxCloudInfo)(connectUrl, pushedToVcs, options.completionMessageKey);
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
+ }
153
+ nxCloudInfo = await (0, nx_cloud_1.getNxCloudInfo)(connectUrl, pushedToVcs, options.completionMessageKey, name);
135
154
  }
136
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
+ }
137
163
  // Show nx connect message when user skips cloud in template flow
138
164
  nxCloudInfo = (0, nx_cloud_1.getSkippedNxCloudInfo)();
139
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;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,CAiC5B;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;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"}
@@ -37,21 +37,36 @@ async function determineNxCloudV2(parsedArgs) {
37
37
  if (!parsedArgs.interactive || (0, is_ci_1.isCI)()) {
38
38
  return 'skip';
39
39
  }
40
- // Show simplified prompt
41
- const { message, choices, initial, footer, hint } = ab_testing_1.messages.getPrompt('setupNxCloudV2');
42
- const promptConfig = {
43
- name: 'nxCloud',
44
- message,
45
- type: 'autocomplete',
46
- choices,
47
- initial,
48
- }; // types in enquirer are not up to date
49
- if (footer) {
50
- promptConfig.footer = () => footer;
51
- }
52
- if (hint) {
53
- promptConfig.hint = () => hint;
40
+ // Variant 2: Skip prompt and auto-connect
41
+ if (!(0, ab_testing_1.shouldShowCloudPrompt)()) {
42
+ return 'github';
54
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
+ };
55
70
  const result = await enquirer.prompt([
56
71
  promptConfig,
57
72
  ]);
@@ -14,6 +14,11 @@ export declare function checkGitVersion(): Promise<string | null | undefined>;
14
14
  * Returns true if git command can be executed, false otherwise.
15
15
  */
16
16
  export declare function isGitAvailable(): boolean;
17
+ /**
18
+ * Synchronously checks if GitHub CLI (gh) is available on the system.
19
+ * Returns true if gh command can be executed, false otherwise.
20
+ */
21
+ export declare function isGhCliAvailable(): boolean;
17
22
  export declare function initializeGitRepo(directory: string, options: {
18
23
  defaultBase: string;
19
24
  commit?: {
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/git/git.ts"],"names":[],"mappings":"AAMA,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,UAAU,eAAe;CAC1B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,SAAgB,KAAK,yBAAyB;gBAElC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAQ1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAOxC;AA0ED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,iBAsDF;AAED,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACA,OAAO,CAAC,aAAa,CAAC,CAuHxB"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/git/git.ts"],"names":[],"mappings":"AAMA,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,UAAU,eAAe;CAC1B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,SAAgB,KAAK,yBAAyB;gBAElC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAQ1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAOxC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAO1C;AA0ED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,iBAsDF;AAED,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACA,OAAO,CAAC,aAAa,CAAC,CAuGxB"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GitHubPushSkippedError = exports.VcsPushStatus = void 0;
4
4
  exports.checkGitVersion = checkGitVersion;
5
5
  exports.isGitAvailable = isGitAvailable;
6
+ exports.isGhCliAvailable = isGhCliAvailable;
6
7
  exports.initializeGitRepo = initializeGitRepo;
7
8
  exports.pushToGitHub = pushToGitHub;
8
9
  const child_process_1 = require("child_process");
@@ -48,6 +49,19 @@ function isGitAvailable() {
48
49
  return false;
49
50
  }
50
51
  }
52
+ /**
53
+ * Synchronously checks if GitHub CLI (gh) is available on the system.
54
+ * Returns true if gh command can be executed, false otherwise.
55
+ */
56
+ function isGhCliAvailable() {
57
+ try {
58
+ (0, child_process_1.execSync)('gh --version', { stdio: 'ignore' });
59
+ return true;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
51
65
  async function getGitHubUsername(directory) {
52
66
  const result = await (0, child_process_utils_1.execAndWait)('gh api user --jq .login', directory);
53
67
  const username = result.stdout.trim();
@@ -221,24 +235,12 @@ async function pushToGitHub(directory, options) {
221
235
  return VcsPushStatus.PushedToVcs;
222
236
  }
223
237
  catch (e) {
224
- const isVerbose = options.verbose || process.env.NX_VERBOSE_LOGGING === 'true';
225
- const errorMessage = e instanceof Error ? e.message : String(e);
226
238
  // Error code 127 means gh wasn't installed
227
239
  // GitHubPushSkippedError means user hasn't opted in or we couldn't authenticate
228
240
  const title = e instanceof GitHubPushSkippedError || e?.code === 127
229
241
  ? 'Push your workspace to GitHub.'
230
- : 'Could not push. Push repo to complete setup.';
231
- const createRepoUrl = `https://github.com/new?name=${encodeURIComponent(options.name)}`;
232
- output_1.output.log({
233
- title,
234
- bodyLines: isVerbose
235
- ? [
236
- `Go to ${createRepoUrl} and push this workspace.`,
237
- 'Error details:',
238
- errorMessage,
239
- ]
240
- : [`Go to ${createRepoUrl} and push this workspace.`],
241
- });
242
+ : 'Could not push.';
243
+ output_1.output.log({ title });
242
244
  return VcsPushStatus.FailedToPushToVcs;
243
245
  }
244
246
  }
@@ -3,6 +3,19 @@ import type { CompletionMessageKey } from './messages';
3
3
  * Returns the flow variant for tracking (0 = preset, 1 = template).
4
4
  */
5
5
  export declare function getFlowVariant(): string;
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)
11
+ */
12
+ export declare function getCompletionMessageKeyForVariant(): CompletionMessageKey;
13
+ /**
14
+ * 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.
17
+ */
18
+ export declare function shouldShowCloudPrompt(): boolean;
6
19
  export declare const NxCloudChoices: string[];
7
20
  declare const messageOptions: Record<string, MessageData[]>;
8
21
  export type MessageKey = keyof typeof messageOptions;
@@ -59,6 +72,7 @@ export interface RecordStatMetaPrecreate {
59
72
  preset: string;
60
73
  nodeVersion: string;
61
74
  packageManager: string;
75
+ ghAvailable?: string;
62
76
  }
63
77
  export type RecordStatMeta = RecordStatMetaStart | RecordStatMetaComplete | RecordStatMetaError | RecordStatMetaCancel | RecordStatMetaPrecreate;
64
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ab-testing.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/ab-testing.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAsDvD;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAKvC;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;CACxB;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":"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"}
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.messages = exports.PromptMessages = exports.NxCloudChoices = void 0;
4
4
  exports.getFlowVariant = getFlowVariant;
5
+ exports.getCompletionMessageKeyForVariant = getCompletionMessageKeyForVariant;
6
+ exports.shouldShowCloudPrompt = shouldShowCloudPrompt;
5
7
  exports.recordStat = recordStat;
6
8
  const node_child_process_1 = require("node:child_process");
7
9
  const node_fs_1 = require("node:fs");
@@ -18,10 +20,18 @@ function readCachedFlowVariant() {
18
20
  if (!(0, node_fs_1.existsSync)(FLOW_VARIANT_CACHE_FILE))
19
21
  return null;
20
22
  const stats = (0, node_fs_1.statSync)(FLOW_VARIANT_CACHE_FILE);
21
- if (Date.now() - stats.mtimeMs > FLOW_VARIANT_EXPIRY_MS)
23
+ if (Date.now() - stats.mtimeMs > FLOW_VARIANT_EXPIRY_MS) {
24
+ // Delete expired file so a new variant can be written
25
+ try {
26
+ (0, node_fs_1.unlinkSync)(FLOW_VARIANT_CACHE_FILE);
27
+ }
28
+ catch {
29
+ // Ignore delete errors
30
+ }
22
31
  return null;
32
+ }
23
33
  const value = (0, node_fs_1.readFileSync)(FLOW_VARIANT_CACHE_FILE, 'utf-8').trim();
24
- return value === '0' || value === '1' ? value : null;
34
+ return value === '0' || value === '1' || value === '2' ? value : null;
25
35
  }
26
36
  catch {
27
37
  return null;
@@ -35,6 +45,14 @@ function writeCachedFlowVariant(variant) {
35
45
  // Ignore write errors
36
46
  }
37
47
  }
48
+ function selectRandomVariant() {
49
+ const rand = Math.random();
50
+ if (rand < 0.33)
51
+ return '0';
52
+ if (rand < 0.66)
53
+ return '1';
54
+ return '2';
55
+ }
38
56
  /**
39
57
  * Internal function to determine and cache the flow variant.
40
58
  */
@@ -43,7 +61,7 @@ function getFlowVariantInternal() {
43
61
  return flowVariantCache;
44
62
  const variant = process.env.NX_CNW_FLOW_VARIANT ??
45
63
  readCachedFlowVariant() ??
46
- (Math.random() < 0.5 ? '0' : '1');
64
+ selectRandomVariant();
47
65
  flowVariantCache = variant;
48
66
  // Only write to cache if we randomly assigned a variant and no cache exists yet
49
67
  // This ensures the cache expiry is based on original creation time, not last access
@@ -62,6 +80,31 @@ function getFlowVariant() {
62
80
  }
63
81
  return flowVariantCache ?? getFlowVariantInternal();
64
82
  }
83
+ /**
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)
88
+ */
89
+ 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
+ return 'platform-setup';
98
+ }
99
+ /**
100
+ * 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.
103
+ */
104
+ function shouldShowCloudPrompt() {
105
+ const variant = getFlowVariant();
106
+ return variant !== '2';
107
+ }
65
108
  exports.NxCloudChoices = [
66
109
  'github',
67
110
  'gitlab',
@@ -13,9 +13,13 @@ declare const completionMessages: {
13
13
  readonly 'platform-setup': {
14
14
  readonly title: "Your platform setup is almost complete.";
15
15
  };
16
+ readonly 'platform-promo': {
17
+ readonly title: "Want faster builds?";
18
+ readonly subtext: "Remote caching · Self-healing CI · Task distribution";
19
+ };
16
20
  };
17
21
  export type CompletionMessageKey = keyof typeof completionMessages;
18
- export declare function getCompletionMessage(completionMessageKey: CompletionMessageKey | undefined, url: string | null, pushedToVcs: VcsPushStatus): {
22
+ export declare function getCompletionMessage(completionMessageKey: CompletionMessageKey | undefined, url: string | null, pushedToVcs: VcsPushStatus, workspaceName?: string): {
19
23
  title: string;
20
24
  bodyLines: string[];
21
25
  };
@@ -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;AAkB3C;;;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,GACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAOxC;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;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"}
@@ -3,16 +3,29 @@ 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) {
6
+ function getSetupMessage(url, pushedToVcs, workspaceName, isPromo) {
7
+ const githubUrl = workspaceName
8
+ ? `https://github.com/new?name=${encodeURIComponent(workspaceName)}`
9
+ : '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
+ }
7
20
  if (pushedToVcs === git_1.VcsPushStatus.PushedToVcs) {
8
21
  return url
9
22
  ? `Go to Nx Cloud and finish the setup: ${url}`
10
23
  : 'Return to Nx Cloud and finish the setup.';
11
24
  }
12
- // Default case: FailedToPushToVcs
25
+ // User needs to push first
13
26
  const action = url ? 'go' : 'return';
14
27
  const urlSuffix = url ? `: ${url}` : '.';
15
- return `Push your repo, then ${action} to Nx Cloud and finish the setup${urlSuffix}`;
28
+ return `Push your repo (${githubUrl}), then ${action} to Nx Cloud and finish the setup${urlSuffix}`;
16
29
  }
17
30
  /**
18
31
  * Completion messages shown after workspace creation.
@@ -28,12 +41,23 @@ const completionMessages = {
28
41
  'platform-setup': {
29
42
  title: 'Your platform setup is almost complete.',
30
43
  },
44
+ 'platform-promo': {
45
+ title: 'Want faster builds?',
46
+ subtext: 'Remote caching \u00b7 Self-healing CI \u00b7 Task distribution',
47
+ },
31
48
  };
32
- function getCompletionMessage(completionMessageKey, url, pushedToVcs) {
49
+ function getCompletionMessage(completionMessageKey, url, pushedToVcs, workspaceName) {
33
50
  const key = completionMessageKey ?? 'ci-setup';
51
+ 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);
57
+ }
34
58
  return {
35
- title: completionMessages[key].title,
36
- bodyLines: [getSetupMessage(url, pushedToVcs)],
59
+ title: messageConfig.title,
60
+ bodyLines,
37
61
  };
38
62
  }
39
63
  function getSkippedCloudMessage() {
@@ -3,7 +3,7 @@ import { CompletionMessageKey } from './messages';
3
3
  export type NxCloud = 'yes' | 'github' | 'gitlab' | 'azure' | 'bitbucket-pipelines' | 'circleci' | 'skip';
4
4
  export declare function connectToNxCloudForTemplate(directory: string, installationSource: string, useGitHub?: boolean): Promise<string | null>;
5
5
  export declare function readNxCloudToken(directory: string): string;
6
- export declare function createNxCloudOnboardingUrl(nxCloud: NxCloud, token: string, directory: string, useGitHub?: boolean): Promise<string>;
7
- export declare function getNxCloudInfo(connectCloudUrl: string, pushedToVcs: VcsPushStatus, completionMessageKey?: CompletionMessageKey): Promise<string>;
6
+ export declare function createNxCloudOnboardingUrl(nxCloud: NxCloud, token: string | undefined, directory: string, useGitHub?: boolean): Promise<string>;
7
+ export declare function getNxCloudInfo(connectCloudUrl: string, pushedToVcs: VcsPushStatus, completionMessageKey?: CompletionMessageKey, workspaceName?: string): Promise<string>;
8
8
  export declare function getSkippedNxCloudInfo(): string;
9
9
  //# sourceMappingURL=nx-cloud.d.ts.map
@@ -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,EACb,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,mBAU5C;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,mBAWvB;AAED,wBAAgB,qBAAqB,WAIpC"}
@@ -54,13 +54,13 @@ async function createNxCloudOnboardingUrl(nxCloud, token, directory, useGitHub)
54
54
  const source = nxCloud === 'yes'
55
55
  ? 'create-nx-workspace-success-cache-setup'
56
56
  : 'create-nx-workspace-success-ci-setup';
57
- const meta = ab_testing_1.messages.codeOfSelectedPromptMessage('setupNxCloudV2');
57
+ const meta = `variant-${(0, ab_testing_1.getFlowVariant)()}`;
58
58
  return createNxCloudOnboardingURL(source, token, meta, false, useGitHub ??
59
59
  (nxCloud === 'yes' || nxCloud === 'github' || nxCloud === 'circleci'), directory);
60
60
  }
61
- async function getNxCloudInfo(connectCloudUrl, pushedToVcs, completionMessageKey) {
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);
63
+ const message = (0, messages_1.getCompletionMessage)(completionMessageKey, connectCloudUrl, pushedToVcs, workspaceName);
64
64
  out.success(message);
65
65
  return out.getOutput();
66
66
  }
@@ -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
+ }