@bobfrankston/npmglobalize 1.0.137 → 1.0.138

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/colors.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Functional color module for npmglobalize.
3
+ * Uses semantic names (success, warn, error, info, muted) instead of raw colors.
4
+ * Adapts to light/dark terminal backgrounds.
5
+ */
6
+ /** Semantic color functions — use these instead of raw colors */
7
+ export declare const colors: {
8
+ /** Success: green on both themes */
9
+ success: (text: string) => string;
10
+ /** Warning: yellow on dark, magenta on light */
11
+ warn: (text: string) => string;
12
+ /** Error: red on both themes */
13
+ error: (text: string) => string;
14
+ /** Info: blue on both themes */
15
+ info: (text: string) => string;
16
+ /** Accent: cyan on both themes */
17
+ accent: (text: string) => string;
18
+ /** Muted/dim text */
19
+ muted: (text: string) => string;
20
+ /** Italic */
21
+ italic: (text: string) => string;
22
+ red: (text: string) => string;
23
+ yellow: (text: string) => string;
24
+ green: (text: string) => string;
25
+ blue: (text: string) => string;
26
+ cyan: (text: string) => string;
27
+ dim: (text: string) => string;
28
+ };
29
+ //# sourceMappingURL=colors.d.ts.map
package/colors.js ADDED
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Functional color module for npmglobalize.
3
+ * Uses semantic names (success, warn, error, info, muted) instead of raw colors.
4
+ * Adapts to light/dark terminal backgrounds.
5
+ */
6
+ import { styleText } from 'util';
7
+ /** Detect terminal theme from environment or default to dark */
8
+ function detectTheme() {
9
+ // COLORFGBG is set by some terminals: "fg;bg" — high bg = light theme
10
+ const colorfgbg = process.env.COLORFGBG;
11
+ if (colorfgbg) {
12
+ const bg = parseInt(colorfgbg.split(';').pop() || '0', 10);
13
+ if (bg > 8)
14
+ return 'light';
15
+ }
16
+ // Explicit override
17
+ if (process.env.NPMG_THEME === 'light')
18
+ return 'light';
19
+ if (process.env.NPMG_THEME === 'dark')
20
+ return 'dark';
21
+ return 'dark';
22
+ }
23
+ const theme = detectTheme();
24
+ // Raw ANSI colors per theme — semantic → [dark, light]
25
+ const themeMap = {
26
+ success: ['green', 'green'],
27
+ warn: ['yellow', 'magenta'], // yellow is invisible on light bg
28
+ error: ['red', 'red'],
29
+ info: ['blue', 'blue'],
30
+ accent: ['cyan', 'cyan'],
31
+ muted: ['dim', 'dim'],
32
+ italic: ['italic', 'italic'],
33
+ };
34
+ function pick(semantic) {
35
+ const entry = themeMap[semantic];
36
+ if (!entry)
37
+ return semantic;
38
+ return theme === 'light' ? entry[1] : entry[0];
39
+ }
40
+ /** Semantic color functions — use these instead of raw colors */
41
+ export const colors = {
42
+ /** Success: green on both themes */
43
+ success: (text) => styleText(pick('success'), text),
44
+ /** Warning: yellow on dark, magenta on light */
45
+ warn: (text) => styleText(pick('warn'), text),
46
+ /** Error: red on both themes */
47
+ error: (text) => styleText(pick('error'), text),
48
+ /** Info: blue on both themes */
49
+ info: (text) => styleText(pick('info'), text),
50
+ /** Accent: cyan on both themes */
51
+ accent: (text) => styleText(pick('accent'), text),
52
+ /** Muted/dim text */
53
+ muted: (text) => styleText(pick('muted'), text),
54
+ /** Italic */
55
+ italic: (text) => styleText('italic', text),
56
+ // Legacy aliases for gradual migration
57
+ red: (text) => styleText(pick('error'), text),
58
+ yellow: (text) => styleText(pick('warn'), text),
59
+ green: (text) => styleText(pick('success'), text),
60
+ blue: (text) => styleText(pick('info'), text),
61
+ cyan: (text) => styleText(pick('accent'), text),
62
+ dim: (text) => styleText(pick('muted'), text),
63
+ };
64
+ //# sourceMappingURL=colors.js.map
@@ -35,6 +35,7 @@
35
35
  // Auto-added silently (security-sensitive)
36
36
  security: [
37
37
  "node_modules/",
38
+ "*.tgz",
38
39
  ".claude/",
39
40
  ".env*",
40
41
  "token*",
package/lib/git.js CHANGED
@@ -659,12 +659,36 @@ export function showPushProtectionGuidance(ppInfo) {
659
659
  /** Push to git with push-protection detection and auto-bypass for installed OAuth.
660
660
  * Returns true if push succeeded (possibly after auto-bypass). */
661
661
  export function pushWithProtection(cwd, verbose) {
662
- const pushResult = runCommand('git', ['push'], { cwd, silent: true });
662
+ let pushResult = runCommand('git', ['push'], { cwd, silent: true });
663
663
  if (pushResult.success) {
664
664
  if (verbose)
665
665
  console.log(colors.green(' ✓ Pushed to remote'));
666
666
  return true;
667
667
  }
668
+ // Check for "Everything up-to-date" — git sometimes returns non-zero
669
+ // alongside transient errors even though there's nothing to push
670
+ const combined = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
671
+ if (combined.includes('everything up-to-date')) {
672
+ if (verbose)
673
+ console.log(colors.green(' ✓ Already up-to-date'));
674
+ return true;
675
+ }
676
+ // Transient network errors (HTTP 408, RPC failed, unexpected disconnect) — retry once
677
+ if (/rpc failed|curl \d+|unexpected disconnect|hung up unexpectedly/i.test(pushResult.stderr)) {
678
+ console.log(colors.yellow('Git push failed with transient error — retrying...'));
679
+ pushResult = runCommand('git', ['push'], { cwd, silent: true });
680
+ if (pushResult.success) {
681
+ if (verbose)
682
+ console.log(colors.green(' ✓ Pushed to remote (retry)'));
683
+ return true;
684
+ }
685
+ const retryCombo = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
686
+ if (retryCombo.includes('everything up-to-date')) {
687
+ if (verbose)
688
+ console.log(colors.green(' ✓ Already up-to-date'));
689
+ return true;
690
+ }
691
+ }
668
692
  const ppInfo = parsePushProtection(pushResult.stderr, cwd);
669
693
  if (!ppInfo.detected) {
670
694
  console.error(colors.red('Git push failed:'));
package/lib.js CHANGED
@@ -30,17 +30,9 @@ import readline from 'readline';
30
30
  import libversion from 'libnpmversion';
31
31
  import JSON5 from 'json5';
32
32
  import { fileURLToPath } from 'url';
33
- import { styleText } from 'util';
34
- /** Color/style helpers using Node.js styleText (Node 24+) */
35
- const colors = {
36
- red: (text) => styleText('red', text),
37
- yellow: (text) => styleText('yellow', text),
38
- green: (text) => styleText('green', text),
39
- italic: (text) => styleText('italic', text),
40
- blue: (text) => styleText('blue', text),
41
- cyan: (text) => styleText('cyan', text),
42
- dim: (text) => styleText('dim', text),
43
- };
33
+ import { themeColors } from '@bobfrankston/themecolors';
34
+ /** Semantic color functions adapts to terminal light/dark theme */
35
+ const colors = themeColors();
44
36
  /**
45
37
  * Remove 'nul' files from a directory tree (Windows reserved name issue).
46
38
  * These files break git and npm on Windows. Uses \\?\ prefix to bypass name validation.
@@ -1641,12 +1633,36 @@ function showPushProtectionGuidance(ppInfo) {
1641
1633
  /** Push to git with push-protection detection and auto-bypass for installed OAuth.
1642
1634
  * Returns true if push succeeded (possibly after auto-bypass). */
1643
1635
  function pushWithProtection(cwd, verbose) {
1644
- const pushResult = runCommand('git', ['push'], { cwd, silent: true });
1636
+ let pushResult = runCommand('git', ['push'], { cwd, silent: true });
1645
1637
  if (pushResult.success) {
1646
1638
  if (verbose)
1647
1639
  console.log(colors.green(' ✓ Pushed to remote'));
1648
1640
  return true;
1649
1641
  }
1642
+ // Check for "Everything up-to-date" — git sometimes returns non-zero
1643
+ // alongside transient errors even though there's nothing to push
1644
+ const combined = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
1645
+ if (combined.includes('everything up-to-date')) {
1646
+ if (verbose)
1647
+ console.log(colors.green(' ✓ Already up-to-date'));
1648
+ return true;
1649
+ }
1650
+ // Transient network errors (HTTP 408, RPC failed, unexpected disconnect) — retry once
1651
+ if (/rpc failed|curl \d+|unexpected disconnect|hung up unexpectedly/i.test(pushResult.stderr)) {
1652
+ console.log(colors.yellow('Git push failed with transient error — retrying...'));
1653
+ pushResult = runCommand('git', ['push'], { cwd, silent: true });
1654
+ if (pushResult.success) {
1655
+ if (verbose)
1656
+ console.log(colors.green(' ✓ Pushed to remote (retry)'));
1657
+ return true;
1658
+ }
1659
+ const retryCombo = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
1660
+ if (retryCombo.includes('everything up-to-date')) {
1661
+ if (verbose)
1662
+ console.log(colors.green(' ✓ Already up-to-date'));
1663
+ return true;
1664
+ }
1665
+ }
1650
1666
  const ppInfo = parsePushProtection(pushResult.stderr, cwd);
1651
1667
  if (!ppInfo.detected) {
1652
1668
  console.error(colors.red('Git push failed:'));
@@ -2035,9 +2051,17 @@ export async function initGit(cwd, visibility, dryRun) {
2035
2051
  const createResult = runCommand('gh', ['repo', 'create', repoName, visFlag, '--source=.', '--push'], { cwd, silent: true });
2036
2052
  if (!createResult.success) {
2037
2053
  const errText = createResult.stderr + createResult.output;
2038
- if (errText.includes('Name already exists')) {
2054
+ // Check if repo was created but push failed (GitHub propagation delay)
2055
+ const repoCreatedButPushFailed = /repository not found|hung up unexpectedly|rpc failed/i.test(errText)
2056
+ && /https?:\/\/github\.com\//i.test(errText);
2057
+ if (errText.includes('Name already exists') || repoCreatedButPushFailed) {
2039
2058
  // Repo exists on GitHub — look up the owner and add as remote
2040
- console.log(colors.yellow(` GitHub repo '${repoName}' already exists — linking as remote...`));
2059
+ if (repoCreatedButPushFailed) {
2060
+ console.log(colors.yellow(` GitHub repo created but initial push failed — retrying...`));
2061
+ }
2062
+ else {
2063
+ console.log(colors.yellow(` GitHub repo '${repoName}' already exists — linking as remote...`));
2064
+ }
2041
2065
  const whoResult = runCommand('gh', ['api', 'user', '--jq', '.login'], { cwd, silent: true });
2042
2066
  const ghUser = (whoResult.output || '').trim();
2043
2067
  if (!ghUser) {
@@ -2050,9 +2074,22 @@ export async function initGit(cwd, visibility, dryRun) {
2050
2074
  // Remote might already exist with wrong URL
2051
2075
  runCommand('git', ['remote', 'set-url', 'origin', remoteUrl], { cwd, silent: true });
2052
2076
  }
2053
- // Push existing commits
2054
- runCommand('git', ['push', '-u', 'origin', 'master'], { cwd, silent: true });
2055
- console.log(colors.green(` ✓ Linked to existing repo: ${remoteUrl}`));
2077
+ // Push existing commits (retry up to 2 times for propagation delay)
2078
+ let pushed = false;
2079
+ for (let attempt = 0; attempt < 2 && !pushed; attempt++) {
2080
+ if (attempt > 0) {
2081
+ console.log(colors.yellow(' Retrying push...'));
2082
+ spawnSafe(process.platform === 'win32' ? 'timeout' : 'sleep', process.platform === 'win32' ? ['\t', '3', '\nobreak'] : ['3'], { stdio: 'pipe' }); // brief delay for GitHub propagation
2083
+ }
2084
+ const pushRes = runCommand('git', ['push', '-u', 'origin', 'master'], { cwd, silent: true });
2085
+ pushed = pushRes.success;
2086
+ }
2087
+ if (pushed) {
2088
+ console.log(colors.green(` ✓ Linked to repo: ${remoteUrl}`));
2089
+ }
2090
+ else {
2091
+ console.log(colors.yellow(` ✓ Repo created but push failed — push manually: git push -u origin master`));
2092
+ }
2056
2093
  }
2057
2094
  else {
2058
2095
  console.error(colors.red(`Failed to create GitHub repo: ${errText}`));
@@ -3641,12 +3678,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3641
3678
  }
3642
3679
  }
3643
3680
  else if (error.message?.includes('unknown git error')) {
3644
- console.error(colors.yellow('\nPossible causes:'));
3645
- console.error(' • Git hooks (pre-commit, commit-msg) might be failing');
3646
- console.error(' • GPG signing might be required but not configured');
3647
- console.error(' • Git config issues (user.name, user.email)');
3648
- console.error(' • Disk space or permissions issues');
3649
- console.error(colors.yellow('\nTry running with --verbose or check git status manually'));
3681
+ console.error(colors.yellow('Unknown git error — check git hooks, signing, or permissions'));
3650
3682
  }
3651
3683
  else if (combinedOutput.includes('gh013') || combinedOutput.includes('push protection') || combinedOutput.includes('push declined due to repository rule')) {
3652
3684
  // GitHub push protection blocked a push (from postversion script)
@@ -3694,29 +3726,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3694
3726
  // Check npm authentication right before publishing
3695
3727
  const authStatus = checkNpmAuth();
3696
3728
  if (!authStatus.authenticated) {
3697
- console.error(colors.red('ERROR: npm authentication required'));
3698
- console.error('');
3699
- if (authStatus.error === 'token expired') {
3700
- console.error('Your npm access token has expired or been revoked.');
3701
- console.error('');
3702
- console.error('To fix this, run:');
3703
- console.error(colors.yellow(' npm logout'));
3704
- console.error(colors.yellow(' npm login'));
3705
- }
3706
- else if (authStatus.error === 'not logged in') {
3707
- console.error('You are not logged in to npm.');
3708
- console.error('');
3709
- console.error('To fix this, run:');
3710
- console.error(colors.yellow(' npm login'));
3711
- }
3712
- else {
3713
- console.error(`Authentication error: ${authStatus.error}`);
3714
- console.error('');
3715
- console.error('Try running:');
3716
- console.error(colors.yellow(' npm whoami'));
3717
- }
3718
- console.error('');
3719
- console.error('After logging in, try running this command again.');
3729
+ console.error(colors.red(`Not authenticated to npm (${authStatus.error}) — run: npm login`));
3720
3730
  return false;
3721
3731
  }
3722
3732
  if (verbose) {
@@ -3738,9 +3748,40 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3738
3748
  return false;
3739
3749
  }
3740
3750
  const tarballPath = path.join(cwd, tarballName);
3741
- if (verbose) {
3742
- console.log(`Created tarball: ${tarballName}`);
3751
+ // Check tarball size — warn if suspiciously large
3752
+ try {
3753
+ const tarballSize = fs.statSync(tarballPath).size;
3754
+ const sizeMB = tarballSize / (1024 * 1024);
3755
+ if (sizeMB > 50) {
3756
+ console.error(colors.red(`\n⚠ Tarball is ${sizeMB.toFixed(0)}MB — something large is being included!`));
3757
+ // Show biggest files in the tarball
3758
+ const listResult = runCommand('npm', ['pack', '--dry-run'], { cwd, silent: true });
3759
+ if (listResult.success) {
3760
+ const lines = listResult.output.trim().split('\n')
3761
+ .filter(l => l.includes('B '))
3762
+ .map(l => { const m = l.match(/([\d.]+[kMG]?B)\s+(.*)/); return m ? { size: m[1], file: m[2] } : null; })
3763
+ .filter(Boolean)
3764
+ .filter((e) => e.size.includes('M') || e.size.includes('G'))
3765
+ .slice(0, 10);
3766
+ if (lines.length > 0) {
3767
+ console.error(colors.yellow(' Large files in tarball:'));
3768
+ for (const e of lines)
3769
+ console.error(colors.yellow(` ${e.size}\t${e.file}`));
3770
+ }
3771
+ }
3772
+ console.error(colors.yellow(' Check .npmignore — you may need to exclude large files or directories.'));
3773
+ // Clean up and abort
3774
+ try {
3775
+ fs.unlinkSync(tarballPath);
3776
+ }
3777
+ catch { /* */ }
3778
+ return false;
3779
+ }
3780
+ if (verbose) {
3781
+ console.log(` Tarball: ${tarballName} (${sizeMB.toFixed(1)}MB)`);
3782
+ }
3743
3783
  }
3784
+ catch { /* proceed if stat fails */ }
3744
3785
  // Publish the tarball
3745
3786
  const npmArgs = ['publish', tarballName];
3746
3787
  // Determine access level (use effectiveNpmVisibility which accounts for current npm status)
@@ -3789,78 +3830,22 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3789
3830
  }
3790
3831
  if (!publishResult.success) {
3791
3832
  console.error(colors.red('\nERROR: npm publish failed\n'));
3792
- // Show the actual error output
3793
- if (publishResult.stderr && publishResult.stderr.trim()) {
3794
- console.error('npm error output:');
3795
- console.error(publishResult.stderr.trim());
3796
- console.error('');
3797
- }
3798
- else if (publishResult.output && publishResult.output.trim()) {
3799
- console.error('npm output:');
3800
- console.error(publishResult.output.trim());
3801
- console.error('');
3802
- }
3803
- // Check for E409 conflict (publishing too fast)
3833
+ // Check for specific error types
3804
3834
  const output = (publishResult.output + '\n' + publishResult.stderr).toLowerCase();
3805
- if (output.includes('e409') || output.includes('409 conflict')) {
3806
- console.error(colors.yellow(' Publishing too quickly'));
3807
- console.error('');
3808
- console.error('npm is still processing the previous version after multiple retries.');
3809
- console.error(colors.green('Solution: Wait a few more minutes and try again'));
3810
- console.error('');
3811
- }
3812
- else if (output.includes('403') || output.includes('forbidden') || output.includes('cannot publish over')) {
3813
- // Check if it's the "version already published" case
3814
- if (output.includes('cannot publish over') || output.includes('previously published')) {
3815
- // Extract the version number from the error if possible
3816
- const versionMatch = output.match(/versions?[:\s]+(\d+\.\d+\.\d+)/);
3817
- const failedVersion = versionMatch ? versionMatch[1] : null;
3818
- // Check if this is the version we just bumped to
3819
- const currentPkgVersion = readPackageJson(cwd).version;
3820
- const isCurrentVersion = failedVersion === currentPkgVersion;
3821
- console.error(colors.yellow('⚠ Version already published to npm'));
3822
- console.error('');
3823
- if (isCurrentVersion) {
3824
- console.error(colors.green('✓ Good news: This version was already published (possibly just now)'));
3825
- console.error('');
3826
- console.error('The git commit and tag were created, but npm says this version exists.');
3827
- console.error('This is actually SUCCESS - your package is published!');
3828
- console.error('');
3829
- console.error('Verify with: ' + colors.yellow(`npm view ${pkg.name}@${currentPkgVersion}`));
3830
- console.error('');
3831
- console.error(colors.yellow('Note: You may have a postversion script that auto-publishes.'));
3832
- console.error(colors.yellow('npmglobalize will now skip that hook to prevent this issue.'));
3833
- console.error('');
3834
- // Treat as success and continue
3835
- console.log(colors.green('✓ Treating as successful publish'));
3836
- // Don't return false - let it continue to push git tags
3837
- }
3838
- else {
3839
- console.error('Version ' + colors.yellow(failedVersion || 'unknown') + ' is already on npm.');
3840
- console.error('This shouldn\'t happen - the version was bumped but publish failed.');
3841
- console.error('');
3842
- console.error(colors.yellow('To recover:'));
3843
- console.error(' Just run npmglobalize again (it will bump to next version)');
3844
- console.error('');
3845
- if (transformResult.transformed) {
3846
- console.log('Restoring file: dependencies...');
3847
- const failPkg = readPackageJson(cwd);
3848
- restoreDeps(failPkg, verbose);
3849
- writePackageJson(cwd, failPkg);
3850
- runCommand('git', ['add', 'package.json'], { cwd, silent: true });
3851
- gitCommit('Restore file: dependencies', cwd);
3852
- }
3853
- return false;
3854
- }
3835
+ if (output.includes('err_string_too_long') || output.includes('string longer than')) {
3836
+ console.error(colors.red('Tarball too large — check .npmignore. Run: npm pack --dry-run'));
3837
+ }
3838
+ else if (output.includes('e409') || output.includes('409 conflict')) {
3839
+ console.error(colors.yellow('npm still processing previous version wait and retry'));
3840
+ }
3841
+ else if (output.includes('cannot publish over') || output.includes('previously published')) {
3842
+ const currentPkgVersion = readPackageJson(cwd).version;
3843
+ if (output.includes(currentPkgVersion)) {
3844
+ console.log(colors.green(' Already published continuing'));
3855
3845
  }
3856
3846
  else {
3857
- console.error(colors.yellow('Common causes:'));
3858
- console.error(' 1. Package name already taken by another user');
3859
- console.error(' 2. No publish access to this package');
3860
- console.error(' 3. Scope (@username) requires authentication');
3861
- console.error('');
3847
+ console.error(colors.yellow('Version conflict — run npmglobalize again'));
3862
3848
  if (transformResult.transformed) {
3863
- console.log('Restoring file: dependencies...');
3864
3849
  const failPkg = readPackageJson(cwd);
3865
3850
  restoreDeps(failPkg, verbose);
3866
3851
  writePackageJson(cwd, failPkg);
@@ -3870,18 +3855,22 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3870
3855
  return false;
3871
3856
  }
3872
3857
  }
3858
+ else if (output.includes('403') || output.includes('forbidden')) {
3859
+ console.error(colors.yellow('Publish forbidden — check npm login and package access'));
3860
+ if (transformResult.transformed) {
3861
+ const failPkg = readPackageJson(cwd);
3862
+ restoreDeps(failPkg, verbose);
3863
+ writePackageJson(cwd, failPkg);
3864
+ runCommand('git', ['add', 'package.json'], { cwd, silent: true });
3865
+ gitCommit('Restore file: dependencies', cwd);
3866
+ }
3867
+ return false;
3868
+ }
3873
3869
  else if (output.includes('402') || output.includes('payment required')) {
3874
- console.error(colors.yellow('Private packages require a paid npm account'));
3875
- console.error(' • Use --npm public to publish as public');
3876
- console.error(' • Or upgrade your npm account for private packages');
3877
- console.error('');
3870
+ console.error(colors.yellow('Private packages need paid npm account — use --npm public'));
3878
3871
  }
3879
3872
  else {
3880
- console.error(colors.yellow('Common causes:'));
3881
- console.error(' 1. Not logged in - run: npm login');
3882
- console.error(' 2. Version already published');
3883
- console.error(' 3. Authentication token expired');
3884
- console.error('');
3873
+ console.error(colors.yellow('Publish failed — run npm login or check npm whoami'));
3885
3874
  }
3886
3875
  if (transformResult.transformed) {
3887
3876
  console.log('Restoring file: dependencies...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.137",
3
+ "version": "1.0.138",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -31,8 +31,9 @@
31
31
  "url": "https://github.com/BobFrankston/npmglobalize.git"
32
32
  },
33
33
  "dependencies": {
34
- "@bobfrankston/freezepak": "^0.1.5",
35
- "@bobfrankston/importgen": "^0.1.31",
34
+ "@bobfrankston/freezepak": "^0.1.6",
35
+ "@bobfrankston/importgen": "^0.1.32",
36
+ "@bobfrankston/themecolors": "^0.1.0",
36
37
  "@bobfrankston/userconfig": "^1.0.5",
37
38
  "@npmcli/package-json": "^7.0.4",
38
39
  "json5": "^2.2.3",
@@ -47,6 +48,7 @@
47
48
  ".dependencies": {
48
49
  "@bobfrankston/freezepak": "file:../freezepak",
49
50
  "@bobfrankston/importgen": "file:../importgen",
51
+ "@bobfrankston/themecolors": "file:../themecolors",
50
52
  "@bobfrankston/userconfig": "file:../userconfig",
51
53
  "@npmcli/package-json": "^7.0.4",
52
54
  "json5": "^2.2.3",