@bobfrankston/npmglobalize 1.0.154 → 1.0.156

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
@@ -301,6 +301,8 @@ Publishing requires being on a branch so commits and tags can be properly tracke
301
301
  -force-publish Republish dependencies even if version exists
302
302
  -fix Run npm audit fix after transformation
303
303
  -no-fix Don't run npm audit
304
+ -no-use-paths, -nup Declare package standalone; do not resolve file: deps
305
+ from sibling checkouts (see Configuration File)
304
306
  ```
305
307
 
306
308
  ### Install Options
@@ -323,10 +325,21 @@ Publishing requires being on a branch so commits and tags can be properly tracke
323
325
  -git private Set GitHub repo to private (default for new repos)
324
326
  -git public Set GitHub repo to public (requires confirmation)
325
327
  Works on both new and existing repos
326
- -npm private Mark npm package private (skip publish) (default)
327
- -npm public Publish to npm
328
+ -npm <values> Comma-separated list of npm options:
329
+ private (default) | public package visibility
330
+ ts — keep .ts source (and *.map,
331
+ tsconfig.json) in npm tarball
332
+ nts — exclude .ts source
333
+ (default for non-noEmit projects)
334
+ Example: -npm public,ts
328
335
  ```
329
336
 
337
+ `ts` is already the default on git (source is tracked). Pass `-npm ts` to ship
338
+ the same files to npm — useful for debugging installed packages or "source on
339
+ demand" packages. `noEmit` projects automatically ship `.ts` files (they *are*
340
+ the runtime); pass `-npm nts` to override. `allowTs` persists to
341
+ `.globalize.json5`.
342
+
330
343
  ### Workspace Options
331
344
  ```
332
345
  -w, -workspace <pkg> Filter to specific package (repeatable)
@@ -400,12 +413,26 @@ Settings can be saved in `.globalize.json5`:
400
413
  "fix": true, // Auto-run npm audit fix
401
414
  "verbose": false, // Show detailed output
402
415
  "gitVisibility": "private",
403
- "npmVisibility": "public"
416
+ "npmVisibility": "public",
417
+ "usePaths": true // Resolve file: deps from sibling checkouts (see below)
404
418
  }
405
419
  ```
406
420
 
407
421
  Configuration persists across runs. CLI flags override config file.
408
422
 
423
+ ### `usePaths` — Standalone packages
424
+
425
+ Default: `true`. Set to `false` (or pass `-no-use-paths` / `-nup`) to mark a
426
+ package as **standalone** — one that should be publishable/installable on a
427
+ machine that does not have sibling `file:` dep checkouts available. Example:
428
+ a backup/recovery utility you want to `npm install -g` on any host.
429
+
430
+ Currently this setting is **declarative** — it is parsed, persisted to
431
+ `.globalize.json5`, and surfaced in the settings banner, but the tool does
432
+ not yet change its behavior based on it. Behavior wiring (e.g. resolving
433
+ `file:` deps to the latest published npm version instead of walking siblings)
434
+ is planned.
435
+
409
436
  ## Common Workflows
410
437
 
411
438
  ### Standard Release
package/cli.js CHANGED
@@ -37,6 +37,9 @@ Dependency Options:
37
37
  -no-prescan, -nps Skip upfront dep-graph prescan
38
38
  -force-publish Republish dependencies even if version exists
39
39
  -fix Run npm audit fix after transformation
40
+ -no-use-paths, -nup Declare this package standalone — file: deps shouldn't
41
+ be resolved from sibling checkouts (persisted as
42
+ usePaths:false in .globalize.json5; FYI for now)
40
43
 
41
44
  Install Options:
42
45
  -install, -i Global install after publish (from registry)
@@ -57,8 +60,12 @@ Git/npm Visibility:
57
60
  -git private Set GitHub repo to private (default for new repos)
58
61
  -git public Set GitHub repo to public (requires confirmation)
59
62
  Works on both new and existing repos
60
- -npm private Mark npm package private (skip publish) (default)
61
- -npm public Publish to npm
63
+ -npm <values> Comma-separated list of npm options:
64
+ private (default) | public package visibility
65
+ ts — keep .ts source in npm tarball
66
+ nts — exclude .ts source (default for
67
+ non-noEmit projects)
68
+ Example: -npm public,ts
62
69
 
63
70
  Workspace Options:
64
71
  -w, -workspace <pkg> Filter to specific package (repeatable)
@@ -214,12 +221,30 @@ function parseArgs(args) {
214
221
  break;
215
222
  case '-npm':
216
223
  i++;
217
- if (args[i] === 'private' || args[i] === 'public') {
218
- options.npmVisibility = args[i];
219
- options.explicitKeys.add('npmVisibility');
224
+ if (!args[i]) {
225
+ options.error = `-npm requires a value (private|public, ts, nts — comma-separated)`;
226
+ break;
220
227
  }
221
- else {
222
- options.error = `-npm requires 'private' or 'public', got: ${args[i]}`;
228
+ {
229
+ const tokens = args[i].split(',').map(t => t.trim()).filter(t => t);
230
+ for (const tok of tokens) {
231
+ if (tok === 'private' || tok === 'public') {
232
+ options.npmVisibility = tok;
233
+ options.explicitKeys.add('npmVisibility');
234
+ }
235
+ else if (tok === 'ts') {
236
+ options.allowTs = true;
237
+ options.explicitKeys.add('allowTs');
238
+ }
239
+ else if (tok === 'nts') {
240
+ options.allowTs = false;
241
+ options.explicitKeys.add('allowTs');
242
+ }
243
+ else {
244
+ options.error = `-npm: unknown value '${tok}' (expected private|public|ts|nts)`;
245
+ break;
246
+ }
247
+ }
223
248
  }
224
249
  break;
225
250
  case '-message':
@@ -266,6 +291,11 @@ function parseArgs(args) {
266
291
  case '-npd':
267
292
  options.publishDeps = false; // Disable auto-publishing
268
293
  break;
294
+ case '-no-use-paths':
295
+ case '-nup':
296
+ options.usePaths = false; // Skip sibling-path resolution; use latest npm version for file: deps
297
+ options.explicitKeys.add('usePaths');
298
+ break;
269
299
  case '-no-prescan':
270
300
  case '-nps':
271
301
  options.noPrescan = true;
package/lib/config.js CHANGED
@@ -58,7 +58,8 @@ export function writeConfig(dir, config, explicitKeys) {
58
58
  wsl: false,
59
59
  force: false,
60
60
  verbose: false,
61
- freeze: false
61
+ freeze: false,
62
+ usePaths: true
62
63
  };
63
64
  // Read existing config to preserve values
64
65
  const existing = readConfig(dir);
@@ -119,6 +120,8 @@ export function writeConfig(dir, config, explicitKeys) {
119
120
  comment = ' // Transform but don\'t publish';
120
121
  else if (key === 'freeze')
121
122
  comment = ' // Freeze node_modules (replace symlinks with real copies)';
123
+ else if (key === 'usePaths')
124
+ comment = ' // Resolve file: deps from sibling checkouts (set false for standalone packages)';
122
125
  lines.push(` "${key}": ${jsonValue}${comma}${comment}`);
123
126
  });
124
127
  lines.push('');
@@ -139,6 +142,7 @@ export function writeConfig(dir, config, explicitKeys) {
139
142
  lines.push(' // "local": false // Local install only (skip transform/publish)');
140
143
  lines.push(' // "noPublish": false // Transform but don\'t publish');
141
144
  lines.push(' // "freeze": false // Freeze node_modules (replace symlinks with real copies)');
145
+ lines.push(' // "usePaths": true // Resolve file: deps from siblings; false = use latest npm version (standalone)');
142
146
  lines.push('}');
143
147
  fs.writeFileSync(configPath, lines.join('\n') + '\n');
144
148
  }
package/lib/types.d.ts CHANGED
@@ -78,6 +78,11 @@ export interface GlobalizeOptions {
78
78
  once?: boolean;
79
79
  /** Run importgen to update import maps before publishing */
80
80
  importgen?: boolean;
81
+ /** Use filesystem paths for `file:` deps (default true). Set false to
82
+ * mark a package as publishable/installable even when sibling checkouts
83
+ * are absent. Currently declarative (recorded in config and displayed);
84
+ * the actual conversion path is TODO. */
85
+ usePaths?: boolean;
81
86
  /** Local install only — skip transform/publish, just npm install -g . */
82
87
  local?: boolean;
83
88
  /** Freeze node_modules: replace symlinks/junctions with real copies for network share use */
package/lib.d.ts CHANGED
@@ -55,6 +55,10 @@ export interface GlobalizeOptions {
55
55
  gitVisibility?: 'private' | 'public';
56
56
  /** npm visibility: private (default) or public */
57
57
  npmVisibility?: 'private' | 'public';
58
+ /** Allow .ts source files (and *.map, tsconfig.json) in the published npm tarball.
59
+ * undefined: follow noEmit detection (noEmit → allow). true: always allow.
60
+ * false: always exclude via .npmignore. Set via `-npm ts` / `-npm nts`. */
61
+ allowTs?: boolean;
58
62
  /** Custom commit message */
59
63
  message?: string;
60
64
  /** Check and update ignore files to conform to best practices */
@@ -91,6 +95,11 @@ export interface GlobalizeOptions {
91
95
  once?: boolean;
92
96
  /** Run importgen to update import maps before publishing */
93
97
  importgen?: boolean;
98
+ /** Use filesystem paths for `file:` deps (default true). Set false to
99
+ * mark a package as publishable/installable even when sibling checkouts
100
+ * are absent. Currently declarative (recorded in config and displayed);
101
+ * the actual conversion path is TODO. */
102
+ usePaths?: boolean;
94
103
  /** Local install only — skip transform/publish, just npm install -g . */
95
104
  local?: boolean;
96
105
  /** Freeze node_modules: replace symlinks/junctions with real copies for network share use */
@@ -251,6 +260,15 @@ export declare function runCommand(cmd: string, args: string[], options?: {
251
260
  output: string;
252
261
  stderr: string;
253
262
  };
263
+ /** Install a package globally in WSL, auto-fixing the root-owned /usr/local/lib/node_modules
264
+ * EACCES case by switching npm to a user prefix (~/.npm-global) and retrying once.
265
+ * Output is captured (so we can scan for the error) and then mirrored to the terminal. */
266
+ export declare function installInWsl(wslArgs: string[], opts?: {
267
+ cwd?: string;
268
+ }): {
269
+ success: boolean;
270
+ fixed: boolean;
271
+ };
254
272
  /** Run a command and throw on failure */
255
273
  export declare function runCommandOrThrow(cmd: string, args: string[], options?: {
256
274
  silent?: boolean;
@@ -278,7 +296,7 @@ export declare function promptText(message: string, defaultValue?: string): Prom
278
296
  /** Prompt user for multiple choice */
279
297
  export declare function promptChoice(message: string, choices: string[]): Promise<string | null>;
280
298
  /** Initialize git repository */
281
- export declare function initGit(cwd: string, visibility: 'private' | 'public', dryRun: boolean): Promise<boolean>;
299
+ export declare function initGit(cwd: string, visibility: 'private' | 'public', dryRun: boolean, allowTs?: boolean): Promise<boolean>;
282
300
  /** Main globalize function */
283
301
  /** Run npm audit and optionally fix vulnerabilities */
284
302
  export declare function runNpmAudit(cwd: string, fix?: boolean, verbose?: boolean): {
package/lib.js CHANGED
@@ -230,7 +230,8 @@ export function writeConfig(dir, config, explicitKeys) {
230
230
  wsl: false,
231
231
  force: false,
232
232
  verbose: false,
233
- freeze: false
233
+ freeze: false,
234
+ usePaths: true
234
235
  };
235
236
  // Read existing config to preserve values
236
237
  const existing = readConfig(dir);
@@ -291,6 +292,10 @@ export function writeConfig(dir, config, explicitKeys) {
291
292
  comment = ' // Transform but don\'t publish';
292
293
  else if (key === 'freeze')
293
294
  comment = ' // Freeze node_modules (replace symlinks with real copies)';
295
+ else if (key === 'usePaths')
296
+ comment = ' // Resolve file: deps from sibling checkouts (set false for standalone packages)';
297
+ else if (key === 'allowTs')
298
+ comment = ' // Keep .ts source (and *.map, tsconfig.json) in the published npm tarball';
294
299
  lines.push(` "${key}": ${jsonValue}${comma}${comment}`);
295
300
  });
296
301
  lines.push('');
@@ -311,6 +316,8 @@ export function writeConfig(dir, config, explicitKeys) {
311
316
  lines.push(' // "local": false // Local install only (skip transform/publish)');
312
317
  lines.push(' // "noPublish": false // Transform but don\'t publish');
313
318
  lines.push(' // "freeze": false // Freeze node_modules (replace symlinks with real copies)');
319
+ lines.push(' // "usePaths": true // Resolve file: deps from siblings; false = use latest npm version (standalone)');
320
+ lines.push(' // "allowTs": false // Include .ts source in npm tarball (auto-true for noEmit projects)');
314
321
  lines.push('}');
315
322
  fs.writeFileSync(configPath, lines.join('\n') + '\n');
316
323
  }
@@ -1413,6 +1420,40 @@ export function runCommand(cmd, args, options = {}) {
1413
1420
  return { success: false, output: '', stderr: error.message };
1414
1421
  }
1415
1422
  }
1423
+ /** Install a package globally in WSL, auto-fixing the root-owned /usr/local/lib/node_modules
1424
+ * EACCES case by switching npm to a user prefix (~/.npm-global) and retrying once.
1425
+ * Output is captured (so we can scan for the error) and then mirrored to the terminal. */
1426
+ export function installInWsl(wslArgs, opts = {}) {
1427
+ console.log(colors.cyan(`> wsl ${wslArgs.join(' ')}`));
1428
+ let result = runCommand('wsl', wslArgs, { cwd: opts.cwd, silent: true });
1429
+ if (result.output)
1430
+ process.stdout.write(result.output);
1431
+ if (result.stderr)
1432
+ process.stderr.write(result.stderr);
1433
+ if (result.success)
1434
+ return { success: true, fixed: false };
1435
+ const combined = (result.output || '') + '\n' + (result.stderr || '');
1436
+ const permIssue = /EACCES/.test(combined) && /\/usr\/(?:local\/)?lib\/node_modules/.test(combined);
1437
+ if (!permIssue)
1438
+ return { success: false, fixed: false };
1439
+ console.log(colors.yellow('Detected root-owned npm prefix in WSL — switching to ~/.npm-global and retrying...'));
1440
+ const fix = `set -e; npm config set prefix "$HOME/.npm-global"; mkdir -p "$HOME/.npm-global/bin"; if ! grep -q '\\.npm-global/bin' "$HOME/.bashrc" 2>/dev/null; then printf '\\n# npm user-prefix bin (added by npmglobalize)\\nexport PATH="$HOME/.npm-global/bin:$PATH"\\n' >> "$HOME/.bashrc"; fi`;
1441
+ const fixResult = runCommand('wsl', ['bash', '-lc', fix], { silent: true });
1442
+ if (!fixResult.success) {
1443
+ console.error(colors.red('Failed to apply WSL npm prefix fix:'));
1444
+ if (fixResult.stderr)
1445
+ process.stderr.write(fixResult.stderr);
1446
+ return { success: false, fixed: false };
1447
+ }
1448
+ console.log(colors.green('✓ WSL npm prefix set to ~/.npm-global; PATH appended to ~/.bashrc'));
1449
+ console.log(colors.cyan(`> wsl ${wslArgs.join(' ')}`));
1450
+ result = runCommand('wsl', wslArgs, { cwd: opts.cwd, silent: true });
1451
+ if (result.output)
1452
+ process.stdout.write(result.output);
1453
+ if (result.stderr)
1454
+ process.stderr.write(result.stderr);
1455
+ return { success: result.success, fixed: result.success };
1456
+ }
1416
1457
  /** Diagnose common build/version failure patterns and print actionable hints.
1417
1458
  * Returns true if a diagnosis was printed. */
1418
1459
  function diagnoseBuildFailure(errorText, cwd) {
@@ -1858,9 +1899,16 @@ function isNoEmitProject(cwd) {
1858
1899
  return false;
1859
1900
  }
1860
1901
  }
1861
- /** Get applicable npmignore patterns, excluding TS patterns for noEmit projects */
1862
- function getApplicableNpmignorePatterns(cwd) {
1863
- if (isNoEmitProject(cwd)) {
1902
+ /** Resolve whether .ts source files should be kept in the published tarball.
1903
+ * Explicit allowTs wins; otherwise noEmit projects default to including .ts. */
1904
+ function resolveAllowTs(cwd, allowTs) {
1905
+ if (allowTs !== undefined)
1906
+ return allowTs;
1907
+ return isNoEmitProject(cwd);
1908
+ }
1909
+ /** Get applicable npmignore patterns, excluding TS patterns when .ts files should ship */
1910
+ function getApplicableNpmignorePatterns(cwd, allowTs) {
1911
+ if (resolveAllowTs(cwd, allowTs)) {
1864
1912
  return ALL_NPMIGNORE.filter(p => !TS_NPMIGNORE_PATTERNS.has(p));
1865
1913
  }
1866
1914
  return ALL_NPMIGNORE;
@@ -2223,7 +2271,7 @@ function checkIgnoreFiles(cwd, options) {
2223
2271
  if (fs.existsSync(npmignorePath)) {
2224
2272
  const content = fs.readFileSync(npmignorePath, 'utf-8');
2225
2273
  const lines = content.split('\n').map(l => l.trim());
2226
- const applicableNpm = getApplicableNpmignorePatterns(cwd);
2274
+ const applicableNpm = getApplicableNpmignorePatterns(cwd, options.allowTs);
2227
2275
  for (const pattern of applicableNpm) {
2228
2276
  if (!lineHasPattern(lines, pattern)) {
2229
2277
  if (securityNpm.has(pattern)) {
@@ -2234,13 +2282,21 @@ function checkIgnoreFiles(cwd, options) {
2234
2282
  }
2235
2283
  }
2236
2284
  }
2285
+ // If .ts should ship, flag TS patterns already in .npmignore for removal
2286
+ if (resolveAllowTs(cwd, options.allowTs)) {
2287
+ for (const ts of TS_NPMIGNORE_PATTERNS) {
2288
+ if (lineHasPattern(lines, ts)) {
2289
+ changes.push(` .npmignore has (should remove): ${ts}`);
2290
+ }
2291
+ }
2292
+ }
2237
2293
  }
2238
2294
  const needsUpdate = changes.length > 0 || securityChanges.length > 0;
2239
2295
  return { needsUpdate, changes, securityChanges };
2240
2296
  }
2241
2297
  /** Update ignore files to conform to best practices.
2242
2298
  * securityOnly: if true, only add security patterns (auto-fix without prompting). */
2243
- function conformIgnoreFiles(cwd, securityOnly = false) {
2299
+ function conformIgnoreFiles(cwd, securityOnly = false, allowTs) {
2244
2300
  if (!securityOnly) {
2245
2301
  // Ensure .gitattributes for LF line endings (use proper helper)
2246
2302
  ensureGitattributes(cwd);
@@ -2259,8 +2315,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
2259
2315
  }
2260
2316
  }
2261
2317
  const patternsGit = securityOnly ? getSecurityGitignorePatterns() : getApplicableGitignorePatterns(cwd);
2262
- const patternsNpm = securityOnly ? getSecurityNpmignorePatterns() : getApplicableNpmignorePatterns(cwd);
2263
- const noEmit = isNoEmitProject(cwd);
2318
+ const patternsNpm = securityOnly ? getSecurityNpmignorePatterns() : getApplicableNpmignorePatterns(cwd, allowTs);
2319
+ const shipTs = resolveAllowTs(cwd, allowTs);
2264
2320
  // Update .gitignore
2265
2321
  const gitignorePath = path.join(cwd, '.gitignore');
2266
2322
  if (fs.existsSync(gitignorePath)) {
@@ -2287,8 +2343,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
2287
2343
  const lines = content.split('\n').map(l => l.trim());
2288
2344
  const newLines = new Set(lines.filter(l => l));
2289
2345
  let updated = false;
2290
- if (!securityOnly && !noEmit) {
2291
- // Add TypeScript exclusions (only in full conform, skip for noEmit projects)
2346
+ if (!securityOnly && !shipTs) {
2347
+ // Add TypeScript exclusions (only in full conform, skip when .ts should ship)
2292
2348
  for (const ts of ['*.ts', '!*.d.ts', '*.map']) {
2293
2349
  if (!newLines.has(ts)) {
2294
2350
  newLines.add(ts);
@@ -2296,8 +2352,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
2296
2352
  }
2297
2353
  }
2298
2354
  }
2299
- // For noEmit projects, remove TS patterns that shouldn't be ignored
2300
- if (noEmit) {
2355
+ // When .ts should ship (noEmit or allowTs=true), remove TS patterns
2356
+ if (shipTs) {
2301
2357
  for (const ts of TS_NPMIGNORE_PATTERNS) {
2302
2358
  if (newLines.has(ts)) {
2303
2359
  newLines.delete(ts);
@@ -2314,8 +2370,9 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
2314
2370
  if (updated) {
2315
2371
  const newContent = Array.from(newLines).join('\n') + '\n';
2316
2372
  fs.writeFileSync(npmignorePath, newContent);
2317
- if (noEmit) {
2318
- console.log(colors.cyan(' ✓ .npmignore updated (noEmit: kept *.ts files)'));
2373
+ if (shipTs) {
2374
+ const reason = allowTs === true ? 'allowTs' : 'noEmit';
2375
+ console.log(colors.cyan(` ✓ .npmignore updated (${reason}: kept *.ts files)`));
2319
2376
  }
2320
2377
  else {
2321
2378
  console.log(colors.cyan(' ✓ Auto-added security patterns to .npmignore'));
@@ -2374,11 +2431,11 @@ function ensureGitignore(cwd) {
2374
2431
  }
2375
2432
  }
2376
2433
  /** Ensure .npmignore exists with recommended patterns */
2377
- function ensureNpmignore(cwd) {
2434
+ function ensureNpmignore(cwd, allowTs) {
2378
2435
  const npmignorePath = path.join(cwd, '.npmignore');
2379
2436
  if (!fs.existsSync(npmignorePath)) {
2380
2437
  console.log(' Creating .npmignore...');
2381
- const patterns = getApplicableNpmignorePatterns(cwd);
2438
+ const patterns = getApplicableNpmignorePatterns(cwd, allowTs);
2382
2439
  const content = patterns.join('\n') + '\n';
2383
2440
  fs.writeFileSync(npmignorePath, content);
2384
2441
  console.log(colors.green(' ✓ .npmignore created'));
@@ -2405,7 +2462,7 @@ function ensureGitattributes(cwd) {
2405
2462
  }
2406
2463
  }
2407
2464
  /** Initialize git repository */
2408
- export async function initGit(cwd, visibility, dryRun) {
2465
+ export async function initGit(cwd, visibility, dryRun, allowTs) {
2409
2466
  const pkg = readPackageJson(cwd);
2410
2467
  const repoName = pkg.name.replace(/^@[^/]+\//, ''); // Remove scope
2411
2468
  console.log('Initializing git repository...');
@@ -2428,7 +2485,7 @@ export async function initGit(cwd, visibility, dryRun) {
2428
2485
  // Ensure .gitignore exists and includes node_modules
2429
2486
  ensureGitignore(cwd);
2430
2487
  // Ensure .npmignore exists with recommended patterns
2431
- ensureNpmignore(cwd);
2488
+ ensureNpmignore(cwd, allowTs);
2432
2489
  // Ensure .gitattributes exists for LF line endings
2433
2490
  ensureGitattributes(cwd);
2434
2491
  // git init
@@ -2693,7 +2750,7 @@ async function doLocalInstall(cwd, options) {
2693
2750
  export async function globalize(cwd, options = {}, configOptions = {}) {
2694
2751
  const { bump = 'patch', noPublish = false, cleanup = false, install = false, link = false, wsl = false, force = false, files = true, dryRun = false, quiet = true, verbose = false, init = false, gitVisibility = 'private', npmVisibility = 'private', message, conform = false, asis = false, updateDeps = false, updateMajor = false, publishDeps = true, // Default to publishing deps for safety
2695
2752
  publishDepsYes = false, // -pd: auto-yes to dep-cascade prompts (private only)
2696
- noPrescan = false, forcePublish = false, fix = true, fixTags = false, rebase = false, show = false, local = false, freeze = false } = options;
2753
+ noPrescan = false, forcePublish = false, fix = true, fixTags = false, rebase = false, show = false, local = false, freeze = false, usePaths = true, allowTs } = options;
2697
2754
  // Show tool version only for recursive dep calls (CLI already prints it at startup)
2698
2755
  const toolVersion = getToolVersion();
2699
2756
  if (!options._fromWorkspace && !options._fromCli) {
@@ -2752,6 +2809,12 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2752
2809
  settings.push('-local');
2753
2810
  if (configOptions.freeze)
2754
2811
  settings.push('-freeze');
2812
+ if (configOptions.usePaths === false)
2813
+ settings.push('--no-use-paths');
2814
+ if (configOptions.allowTs === true)
2815
+ settings.push('-npm ts');
2816
+ if (configOptions.allowTs === false)
2817
+ settings.push('-npm nts');
2755
2818
  if (settings.length > 0) {
2756
2819
  console.log(colors.dim(`Settings from .globalize.json5: ${settings.join(', ')}`));
2757
2820
  }
@@ -2832,7 +2895,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2832
2895
  }
2833
2896
  // Check ignore files first (unless cleanup mode)
2834
2897
  if (!cleanup && !asis) {
2835
- const checkResult = checkIgnoreFiles(cwd, { conform, asis, verbose });
2898
+ const checkResult = checkIgnoreFiles(cwd, { conform, asis, verbose, allowTs });
2836
2899
  // Auto-add security patterns without prompting
2837
2900
  if (checkResult.securityChanges.length > 0) {
2838
2901
  const secGit = [];
@@ -2845,7 +2908,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2845
2908
  secNpm.push(change.replace(' .npmignore missing: ', '').trim());
2846
2909
  }
2847
2910
  }
2848
- conformIgnoreFiles(cwd, true);
2911
+ conformIgnoreFiles(cwd, true, allowTs);
2849
2912
  if (secGit.length > 0) {
2850
2913
  console.log(colors.cyan(' .gitignore: auto-added ') + secGit.join(', '));
2851
2914
  }
@@ -2876,7 +2939,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2876
2939
  console.log('');
2877
2940
  if (conform) {
2878
2941
  console.log('Applying changes (--conform)...');
2879
- conformIgnoreFiles(cwd);
2942
+ conformIgnoreFiles(cwd, false, allowTs);
2880
2943
  console.log('');
2881
2944
  }
2882
2945
  else {
@@ -2888,7 +2951,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2888
2951
  const choice = await promptChoice('Your choice [ok/asis/abort]:', ['ok', 'asis', 'abort']);
2889
2952
  if (choice === 'ok') {
2890
2953
  console.log('Applying changes...');
2891
- conformIgnoreFiles(cwd);
2954
+ conformIgnoreFiles(cwd, false, allowTs);
2892
2955
  console.log(colors.green('✓ Ignore files updated'));
2893
2956
  console.log('');
2894
2957
  }
@@ -2946,13 +3009,13 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2946
3009
  options.autoInit = true;
2947
3010
  }
2948
3011
  // choice is '1', 'a', or '' (default)
2949
- const success = await initGit(cwd, gitVisibility, dryRun);
3012
+ const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
2950
3013
  if (!success)
2951
3014
  return false;
2952
3015
  justInitialized = true;
2953
3016
  }
2954
3017
  else {
2955
- const success = await initGit(cwd, gitVisibility, dryRun);
3018
+ const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
2956
3019
  if (!success)
2957
3020
  return false;
2958
3021
  justInitialized = true;
@@ -2975,7 +3038,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2975
3038
  options.autoInit = true;
2976
3039
  }
2977
3040
  }
2978
- const success = await initGit(cwd, gitVisibility, dryRun);
3041
+ const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
2979
3042
  if (!success)
2980
3043
  return false;
2981
3044
  justInitialized = true;
@@ -4643,10 +4706,10 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
4643
4706
  waitForNpmVersion(pkgName, pkgVersion);
4644
4707
  console.log(`Installing in WSL${useLocalWsl ? ' (local)' : ' from registry'}: ${pkgName}@${pkgVersion}...`);
4645
4708
  if (!dryRun) {
4646
- const wslResult = runCommand('wsl', wslArgs, { cwd, silent: false, showCommand: true });
4709
+ const wslResult = installInWsl(wslArgs, { cwd });
4647
4710
  if (wslResult.success) {
4648
4711
  wslInstallOk = true;
4649
- console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}`));
4712
+ console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}${wslResult.fixed ? ' (after prefix fix)' : ''}`));
4650
4713
  }
4651
4714
  else {
4652
4715
  console.error(colors.yellow('✗ WSL install failed (is npm installed in WSL?)'));
@@ -5047,9 +5110,9 @@ export async function globalizeWorkspace(rootDir, options = {}, configOptions =
5047
5110
  if (wsl) {
5048
5111
  console.log(`Installing ${pkgName} in WSL (local)...`);
5049
5112
  if (!dryRun) {
5050
- const wslResult = runCommand('wsl', ['npm', 'install', '-g', '.'], { cwd: rootDir, silent: false, showCommand: true });
5113
+ const wslResult = installInWsl(['npm', 'install', '-g', '.'], { cwd: rootDir });
5051
5114
  if (wslResult.success) {
5052
- console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}`));
5115
+ console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}${wslResult.fixed ? ' (after prefix fix)' : ''}`));
5053
5116
  }
5054
5117
  else {
5055
5118
  console.error(colors.yellow('✗ WSL install failed (is npm installed in WSL?)'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.154",
3
+ "version": "1.0.156",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",