@bobfrankston/npmglobalize 1.0.213 → 1.0.214

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +4 -4
  2. package/lib.d.ts +8 -2
  3. package/lib.js +64 -27
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -298,10 +298,10 @@ reachable `repository.url` in `package.json`. If found, it offers two paths:
298
298
  ```
299
299
  How would you like to set up git?
300
300
  1) Adopt history from existing remote (recommended)
301
- 2) Initialize fresh git repository
302
- a) Adopt ALL (don't ask again for remaining deps)
303
- 3) Use local install only (skip git/publish)
304
- 4) Abort
301
+ 2) Adopt for ALL remaining deps (don't ask again)
302
+ 3) Initialize fresh git repository
303
+ 4) Use local install only (skip git/publish)
304
+ 5) Abort
305
305
  ```
306
306
 
307
307
  **Adopt** runs:
package/lib.d.ts CHANGED
@@ -589,8 +589,14 @@ export declare function validatePackageJson(pkg: any): string[];
589
589
  export declare function confirm(message: string, defaultYes?: boolean): Promise<boolean>;
590
590
  /** Prompt user for free text input */
591
591
  export declare function promptText(message: string, defaultValue?: string): Promise<string>;
592
- /** Prompt user for multiple choice */
593
- export declare function promptChoice(message: string, choices: string[]): Promise<string | null>;
592
+ /**
593
+ * Prompt user for multiple choice. Re-asks until the answer is one of `choices`.
594
+ *
595
+ * 2026-09-01 — Claude Code (Fable 5.1), at Bob's direction. Previously an unrecognized
596
+ * answer resolved null and every caller fell through to its default action, so a typo
597
+ * silently did something. Now it says what it didn't understand and asks again.
598
+ */
599
+ export declare function promptChoice(message: string, choices: string[]): Promise<string>;
594
600
  /** Initialize a local git repo by adopting history from an existing remote.
595
601
  * Preserves the working tree — local files appear as uncommitted changes
596
602
  * on top of the remote's HEAD. No force-push is required. */
package/lib.js CHANGED
@@ -4995,23 +4995,46 @@ export async function promptText(message, defaultValue) {
4995
4995
  });
4996
4996
  });
4997
4997
  }
4998
- /** Prompt user for multiple choice */
4999
- export async function promptChoice(message, choices) {
4998
+ /**
4999
+ * Prompt user for multiple choice. Re-asks until the answer is one of `choices`.
5000
+ *
5001
+ * 2026-09-01 — Claude Code (Fable 5.1), at Bob's direction. Previously an unrecognized
5002
+ * answer resolved null and every caller fell through to its default action, so a typo
5003
+ * silently did something. Now it says what it didn't understand and asks again.
5004
+ */
5005
+ export function promptChoice(message, choices) {
5000
5006
  const rl = readline.createInterface({
5001
5007
  input: process.stdin,
5002
5008
  output: process.stdout
5003
5009
  });
5010
+ const shown = choices.filter(c => c !== '').join(', ');
5011
+ // A 'line' listener rather than repeated rl.question(): when stdin is piped, several
5012
+ // lines can arrive in one chunk and a line landing between two question() calls is
5013
+ // dropped. The listener sees every line.
5004
5014
  return new Promise((resolve) => {
5005
- rl.question(`${message} `, (answer) => {
5015
+ let done = false;
5016
+ const finish = (value) => {
5017
+ done = true;
5006
5018
  rl.close();
5019
+ resolve(value);
5020
+ };
5021
+ rl.setPrompt(`${message} `);
5022
+ rl.prompt();
5023
+ rl.on('line', (answer) => {
5024
+ if (done)
5025
+ return;
5007
5026
  const a = answer.trim().toLowerCase();
5008
- if (choices.includes(a)) {
5009
- resolve(a);
5010
- }
5011
- else {
5012
- resolve(null);
5013
- }
5027
+ if (choices.includes(a))
5028
+ return finish(a);
5029
+ console.log(colors.yellow(`Unrecognized choice "${a}" — expected one of: ${shown}`));
5030
+ rl.prompt();
5014
5031
  });
5032
+ // EOF with no valid answer: behave as "just pressed Enter" ('' is the default where
5033
+ // a default exists; callers without one treat '' as abort).
5034
+ rl.on('close', () => { if (!done) {
5035
+ done = true;
5036
+ resolve('');
5037
+ } });
5015
5038
  });
5016
5039
  }
5017
5040
  /** Check npm authentication status */
@@ -6393,51 +6416,60 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
6393
6416
  justInitialized = true;
6394
6417
  }
6395
6418
  else if (!init && !options.autoInit && !publishDepsYes) {
6419
+ // 2026-09-01 — Claude Code (Fable 5.1), at Bob's direction. These menus were
6420
+ // numbered "1 a 2 3": the "ALL" option was lettered and sat between 1 and 2, so
6421
+ // a reader who wanted the second line typed 2 and got something else. Bob:
6422
+ // "I type 2 when I mean a because that's what humans do." Options are now
6423
+ // numbered in display order; the ALL variant is 2, directly under the single.
6396
6424
  let choice;
6397
6425
  if (adoptable) {
6398
6426
  choice = await promptChoice('How would you like to set up git?\n'
6399
6427
  + ' 1) Adopt history from existing remote (recommended)\n'
6400
- + ' a) Adopt ALL (don\'t ask again for remaining deps)\n'
6401
- + ' 2) Initialize fresh git repository\n'
6402
- + ' 3) Use local install only (skip git/publish)\n'
6403
- + ' 4) Abort\nChoice:', ['1', 'a', '2', '3', '4', '']);
6404
- if (choice === '3') {
6428
+ + ' 2) Adopt for ALL remaining deps (don\'t ask again)\n'
6429
+ + ' 3) Initialize fresh git repository\n'
6430
+ + ' 4) Use local install only (skip git/publish)\n'
6431
+ + ' 5) Abort\nChoice [1]:', ['1', '2', '3', '4', '5', '']);
6432
+ if (choice === '4') {
6405
6433
  console.log(colors.dim('Switching to local-only mode...'));
6406
6434
  writeConfig(cwd, { ...configOptions, local: true }, new Set(['local']));
6407
6435
  return doLocalInstall(cwd, options);
6408
6436
  }
6409
- if (choice === '4') {
6437
+ if (choice === '5') {
6410
6438
  console.log('Aborted. Run with --init to initialize.');
6411
6439
  return false;
6412
6440
  }
6413
- if (choice === 'a')
6441
+ if (choice === '2')
6414
6442
  options.autoInit = true;
6415
- if (choice === '2') {
6443
+ if (choice === '3') {
6416
6444
  const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
6417
6445
  if (!success)
6418
6446
  return false;
6419
6447
  }
6420
6448
  else {
6421
- // '1', 'a', '' default → adopt
6449
+ // '1', '2', '' default → adopt
6422
6450
  const success = await adoptExistingRemote(cwd, adoptable.url, adoptable.defaultBranch, dryRun);
6423
6451
  if (!success)
6424
6452
  return false;
6425
6453
  }
6426
6454
  }
6427
6455
  else {
6428
- choice = await promptChoice('No git repository found. What would you like to do?\n 1) Initialize git repository (default)\n a) Initialize ALL (don\'t ask again for remaining deps)\n 2) Use local install only (skip git/publish)\n 3) Abort\nChoice:', ['1', 'a', '2', '3', '']);
6429
- if (choice === '2') {
6456
+ choice = await promptChoice('No git repository found. What would you like to do?\n'
6457
+ + ' 1) Initialize git repository\n'
6458
+ + ' 2) Initialize for ALL remaining deps (don\'t ask again)\n'
6459
+ + ' 3) Use local install only (skip git/publish)\n'
6460
+ + ' 4) Abort\nChoice [1]:', ['1', '2', '3', '4', '']);
6461
+ if (choice === '3') {
6430
6462
  console.log(colors.dim('Switching to local-only mode...'));
6431
6463
  writeConfig(cwd, { ...configOptions, local: true }, new Set(['local']));
6432
6464
  return doLocalInstall(cwd, options);
6433
6465
  }
6434
- if (choice === '3') {
6466
+ if (choice === '4') {
6435
6467
  console.log('Aborted. Run with --init to initialize.');
6436
6468
  return false;
6437
6469
  }
6438
- if (choice === 'a')
6470
+ if (choice === '2')
6439
6471
  options.autoInit = true;
6440
- // choice is '1', 'a', or '' (default)
6472
+ // choice is '1', '2', or '' (default) → init
6441
6473
  const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
6442
6474
  if (!success)
6443
6475
  return false;
@@ -6463,17 +6495,22 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
6463
6495
  else if (!gitStatus.hasRemote) {
6464
6496
  // Git repo exists but no remote - need to create GitHub repo
6465
6497
  if (!init && !options.autoInit && !publishDepsYes) {
6466
- const choice = await promptChoice('No git remote configured. What would you like to do?\n 1) Create GitHub repository (default)\n a) Initialize ALL (don\'t ask again for remaining deps)\n 2) Use local install only (skip git/publish)\n 3) Abort\nChoice:', ['1', 'a', '2', '3', '']);
6467
- if (choice === '2') {
6498
+ // 2026-09-01 Claude Code (Fable 5.1): renumbered from "1 a 2 3" (see note above).
6499
+ const choice = await promptChoice('No git remote configured. What would you like to do?\n'
6500
+ + ' 1) Create GitHub repository\n'
6501
+ + ' 2) Create for ALL remaining deps (don\'t ask again)\n'
6502
+ + ' 3) Use local install only (skip git/publish)\n'
6503
+ + ' 4) Abort\nChoice [1]:', ['1', '2', '3', '4', '']);
6504
+ if (choice === '3') {
6468
6505
  console.log(colors.dim('Switching to local-only mode...'));
6469
6506
  writeConfig(cwd, { ...configOptions, local: true }, new Set(['local']));
6470
6507
  return doLocalInstall(cwd, options);
6471
6508
  }
6472
- if (choice === '3') {
6509
+ if (choice === '4') {
6473
6510
  console.log('Aborted. Run with --init to set up GitHub repository.');
6474
6511
  return false;
6475
6512
  }
6476
- if (choice === 'a') {
6513
+ if (choice === '2') {
6477
6514
  options.autoInit = true;
6478
6515
  }
6479
6516
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.213",
3
+ "version": "1.0.214",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",