ccconfig 1.5.0 → 1.5.1

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
@@ -264,6 +264,46 @@ Do you want to set ANTHROPIC_SMALL_FAST_MODEL? (y/N) [n]:
264
264
  - Use `ccconfig start work` to launch Claude Code with the updated profile
265
265
  - Or use `ccconfig use work` to activate it in current shell
266
266
 
267
+ ### Copy Configuration (fork)
268
+
269
+ If you need to create a new configuration based on an existing one, use the `fork` command:
270
+
271
+ ```bash
272
+ # Fork a configuration interactively
273
+ ccconfig fork work
274
+
275
+ # The tool will:
276
+ # 1. Ask for a new configuration name
277
+ # 2. Copy all environment variables from the source
278
+ # 3. Allow you to update values (press Enter to keep current value)
279
+ ```
280
+
281
+ **Example:**
282
+ ```bash
283
+ $ ccconfig fork work
284
+ Please enter source configuration name to copy from: work
285
+ Please enter new configuration name: work-dev
286
+ Creating configuration 'work-dev' from 'work'...
287
+ Press Enter to keep current value/default, or enter new value to update
288
+
289
+ ANTHROPIC_BASE_URL [https://api.company.com]: https://dev-api.company.com
290
+ ANTHROPIC_AUTH_TOKEN [sk-ant-api...]: <press Enter to keep>
291
+ ANTHROPIC_API_KEY [sk-...]: <press Enter to keep>
292
+ ANTHROPIC_MODEL [claude-sonnet-4-5-20250929]: <press Enter to keep>
293
+
294
+ ✓ Configuration 'work-dev' created from 'work'
295
+ Environment variables:
296
+ ANTHROPIC_BASE_URL=https://dev-api.company.com
297
+ ANTHROPIC_AUTH_TOKEN=sk-ant-api...
298
+ ANTHROPIC_API_KEY=sk-...
299
+ ANTHROPIC_MODEL=claude-sonnet-4-5-20250929
300
+
301
+ Run the following command to activate:
302
+ ccconfig use work-dev
303
+ ```
304
+
305
+ This is useful when you need similar configurations with slight variations (e.g., production vs development endpoints).
306
+
267
307
  ### Shell Completion
268
308
 
269
309
  ccconfig supports shell completion for commands, profile names, and options. This makes it easier to discover and use commands.
package/README_zh.md CHANGED
@@ -264,6 +264,46 @@ Do you want to set ANTHROPIC_SMALL_FAST_MODEL? (y/N) [n]:
264
264
  - 使用 `ccconfig start work` 以更新后的配置启动 Claude Code
265
265
  - 或使用 `ccconfig use work` 在当前 shell 中激活配置
266
266
 
267
+ ### 复制配置 (fork)
268
+
269
+ 如果您需要基于现有配置创建新配置,使用 `fork` 命令:
270
+
271
+ ```bash
272
+ # 交互式复制配置
273
+ ccconfig fork work
274
+
275
+ # 工具会:
276
+ # 1. 要求输入新配置名称
277
+ # 2. 从源配置复制所有环境变量
278
+ # 3. 允许您更新值(按 Enter 保持当前值)
279
+ ```
280
+
281
+ **示例:**
282
+ ```bash
283
+ $ ccconfig fork work
284
+ Please enter source configuration name to copy from: work
285
+ Please enter new configuration name: work-dev
286
+ Creating configuration 'work-dev' from 'work'...
287
+ Press Enter to keep current value/default, or enter new value to update
288
+
289
+ ANTHROPIC_BASE_URL [https://api.company.com]: https://dev-api.company.com
290
+ ANTHROPIC_AUTH_TOKEN [sk-ant-api...]: <按 Enter 保持不变>
291
+ ANTHROPIC_API_KEY [sk-...]: <按 Enter 保持不变>
292
+ ANTHROPIC_MODEL [claude-sonnet-4-5-20250929]: <按 Enter 保持不变>
293
+
294
+ ✓ Configuration 'work-dev' created from 'work'
295
+ Environment variables:
296
+ ANTHROPIC_BASE_URL=https://dev-api.company.com
297
+ ANTHROPIC_AUTH_TOKEN=sk-ant-api...
298
+ ANTHROPIC_API_KEY=sk-...
299
+ ANTHROPIC_MODEL=claude-sonnet-4-5-20250929
300
+
301
+ Run the following command to activate:
302
+ ccconfig use work-dev
303
+ ```
304
+
305
+ 当您需要相似配置但略有差异时很有用(例如生产环境与开发环境端点)。
306
+
267
307
  ### Shell 自动补全
268
308
 
269
309
  ccconfig 支持命令、配置名称和选项的 shell 自动补全,让您更容易发现和使用命令。
package/ccconfig.js CHANGED
@@ -89,7 +89,7 @@ function ensureProfileAvailable(
89
89
 
90
90
  // All supported commands
91
91
  const COMMANDS = [
92
- 'list', 'ls', 'add', 'update', 'use', 'start', 'safe-start', 'remove', 'rm',
92
+ 'list', 'ls', 'add', 'update', 'fork', 'use', 'start', 'safe-start', 'remove', 'rm',
93
93
  'current', 'mode', 'env', 'completion'
94
94
  ];
95
95
 
@@ -819,6 +819,88 @@ async function update(name) {
819
819
  }
820
820
  }
821
821
 
822
+ /**
823
+ * Fork (copy) existing configuration
824
+ */
825
+ async function fork(sourceName) {
826
+ initIfNeeded();
827
+ requireInteractive('forking configurations');
828
+
829
+ const helper = new ReadlineHelper();
830
+
831
+ try {
832
+ if (!sourceName) {
833
+ sourceName = await helper.ask('Please enter source configuration name to copy from');
834
+ }
835
+
836
+ validateConfigName(sourceName);
837
+
838
+ const {profile: sourceProfile} = ensureProfileAvailable(sourceName, {
839
+ allowEmptyEnv: true,
840
+ onEmptyProfiles: () => {
841
+ console.error('Error: Configuration file does not exist');
842
+ },
843
+ onMissingProfile: () => {
844
+ console.error(`Error: Configuration '${sourceName}' does not exist`);
845
+ console.error('');
846
+ console.error('Run ccconfig list to see available configurations');
847
+ }
848
+ });
849
+
850
+ const profiles = loadProfiles() || {profiles: {}};
851
+ const profilesMap = getProfilesMap(profiles);
852
+
853
+ // Ask for new name with validation loop (default to source name)
854
+ let newName = '';
855
+ while (true) {
856
+ newName = await helper.ask(
857
+ `Please enter new configuration name`, sourceName);
858
+
859
+ // Validate name format
860
+ try {
861
+ validateConfigName(newName);
862
+ } catch (error) {
863
+ // validateConfigName calls process.exit, but just in case
864
+ continue;
865
+ }
866
+
867
+ // Check if name already exists
868
+ if (profilesMap[newName]) {
869
+ console.error(`Error: Configuration '${newName}' already exists`);
870
+ console.error('Please choose a different name.');
871
+ console.error('');
872
+ continue;
873
+ }
874
+
875
+ // Name is valid and unique
876
+ break;
877
+ }
878
+
879
+ console.log(`Creating configuration '${newName}' from '${sourceName}'...`);
880
+ console.log('Press Enter to keep current value/default, or enter new value to update');
881
+ console.log('');
882
+
883
+ // Get environment variables (inherited from source)
884
+ const existingEnv = sourceProfile.env || {};
885
+ const envVars = await helper.askEnvVars(existingEnv);
886
+
887
+ // Now save everything at once
888
+ profilesMap[newName] = {env: envVars};
889
+ saveProfiles(profiles);
890
+
891
+ console.log(`✓ Configuration '${newName}' created from '${sourceName}'`);
892
+ console.log('');
893
+ console.log('Environment variables:');
894
+ displayEnvVars(envVars);
895
+ console.log('');
896
+ console.log('Run the following command to activate:');
897
+ console.log(` ccconfig use ${newName}`);
898
+
899
+ } finally {
900
+ helper.close();
901
+ }
902
+ }
903
+
822
904
  /**
823
905
  * Remove configuration
824
906
  */
@@ -1685,7 +1767,7 @@ _ccconfig_completions() {
1685
1767
  ;;
1686
1768
  2)
1687
1769
  case "\${prev}" in
1688
- use|start|safe-start|update|remove|rm)
1770
+ use|start|safe-start|update|fork|remove|rm)
1689
1771
  COMPREPLY=( $(compgen -W "\${profiles}" -- \${cur}) )
1690
1772
  ;;
1691
1773
  mode)
@@ -1694,6 +1776,9 @@ _ccconfig_completions() {
1694
1776
  env)
1695
1777
  COMPREPLY=( $(compgen -W "bash zsh fish sh powershell pwsh dotenv" -- \${cur}) )
1696
1778
  ;;
1779
+ completion)
1780
+ COMPREPLY=( $(compgen -W "bash zsh fish powershell pwsh" -- \${cur}) )
1781
+ ;;
1697
1782
  esac
1698
1783
  ;;
1699
1784
  3)
@@ -1722,6 +1807,7 @@ _ccconfig() {
1722
1807
  'ls:List all configurations'
1723
1808
  'add:Add new configuration'
1724
1809
  'update:Update existing configuration'
1810
+ 'fork:Copy existing configuration and update'
1725
1811
  'use:Switch to specified configuration'
1726
1812
  'start:Start Claude Code (auto-approve mode)'
1727
1813
  'safe-start:Start Claude Code (safe mode, requires confirmation)'
@@ -1746,7 +1832,7 @@ _ccconfig() {
1746
1832
  ;;
1747
1833
  3)
1748
1834
  case $words[2] in
1749
- use|start|safe-start|update|remove|rm)
1835
+ use|start|safe-start|update|fork|remove|rm)
1750
1836
  _describe 'profile' profiles
1751
1837
  ;;
1752
1838
  mode)
@@ -1755,6 +1841,11 @@ _ccconfig() {
1755
1841
  env)
1756
1842
  _describe 'format' formats
1757
1843
  ;;
1844
+ completion)
1845
+ local -a shells
1846
+ shells=('bash' 'zsh' 'fish' 'powershell' 'pwsh')
1847
+ _describe 'shell' shells
1848
+ ;;
1758
1849
  esac
1759
1850
  ;;
1760
1851
  4)
@@ -1782,6 +1873,7 @@ complete -c ccconfig -f -n "__fish_use_subcommand" -a "list" -d "List all config
1782
1873
  complete -c ccconfig -f -n "__fish_use_subcommand" -a "ls" -d "List all configurations"
1783
1874
  complete -c ccconfig -f -n "__fish_use_subcommand" -a "add" -d "Add new configuration"
1784
1875
  complete -c ccconfig -f -n "__fish_use_subcommand" -a "update" -d "Update existing configuration"
1876
+ complete -c ccconfig -f -n "__fish_use_subcommand" -a "fork" -d "Copy existing configuration and update"
1785
1877
  complete -c ccconfig -f -n "__fish_use_subcommand" -a "use" -d "Switch to specified configuration"
1786
1878
  complete -c ccconfig -f -n "__fish_use_subcommand" -a "start" -d "Start Claude Code (auto-approve mode)"
1787
1879
  complete -c ccconfig -f -n "__fish_use_subcommand" -a "safe-start" -d "Start Claude Code (safe mode, requires confirmation)"
@@ -1798,8 +1890,8 @@ function __ccconfig_profiles
1798
1890
  end
1799
1891
  end
1800
1892
 
1801
- # Profile name completion for use, start, safe-start, update, remove
1802
- complete -c ccconfig -f -n "__fish_seen_subcommand_from use start safe-start update remove rm" -a "(__ccconfig_profiles)"
1893
+ # Profile name completion for use, start, safe-start, update, fork, remove
1894
+ complete -c ccconfig -f -n "__fish_seen_subcommand_from use start safe-start update fork remove rm" -a "(__ccconfig_profiles)"
1803
1895
 
1804
1896
  # Mode options
1805
1897
  complete -c ccconfig -f -n "__fish_seen_subcommand_from mode" -a "settings env"
@@ -1807,6 +1899,9 @@ complete -c ccconfig -f -n "__fish_seen_subcommand_from mode" -a "settings env"
1807
1899
  # Env format options
1808
1900
  complete -c ccconfig -f -n "__fish_seen_subcommand_from env" -a "bash zsh fish sh powershell pwsh dotenv"
1809
1901
 
1902
+ # Completion shell options
1903
+ complete -c ccconfig -f -n "__fish_seen_subcommand_from completion" -a "bash zsh fish powershell pwsh"
1904
+
1810
1905
  # Flags for use command
1811
1906
  complete -c ccconfig -f -n "__fish_seen_subcommand_from use" -s p -l permanent -d "Write permanently to shell config"
1812
1907
 
@@ -1841,7 +1936,7 @@ function Get-CconfigProfiles {
1841
1936
  Register-ArgumentCompleter -Native -CommandName ccconfig -ScriptBlock {
1842
1937
  param($wordToComplete, $commandAst, $cursorPosition)
1843
1938
 
1844
- $commands = @('list', 'ls', 'add', 'update', 'use', 'start', 'safe-start', 'remove', 'rm', 'current', 'mode', 'env', 'completion')
1939
+ $commands = @('list', 'ls', 'add', 'update', 'fork', 'use', 'start', 'safe-start', 'remove', 'rm', 'current', 'mode', 'env', 'completion')
1845
1940
  $modes = @('settings', 'env')
1846
1941
  $formats = @('bash', 'zsh', 'fish', 'sh', 'powershell', 'pwsh', 'dotenv')
1847
1942
 
@@ -1863,7 +1958,7 @@ Register-ArgumentCompleter -Native -CommandName ccconfig -ScriptBlock {
1863
1958
  # Second argument completions based on command
1864
1959
  if ($position -eq 2 -or ($position -eq 3 -and $wordToComplete)) {
1865
1960
  switch ($command) {
1866
- { $_ -in 'use', 'start', 'safe-start', 'update', 'remove', 'rm' } {
1961
+ { $_ -in 'use', 'start', 'safe-start', 'update', 'fork', 'remove', 'rm' } {
1867
1962
  Get-CconfigProfiles | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
1868
1963
  [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
1869
1964
  }
@@ -1940,6 +2035,8 @@ function help() {
1940
2035
  ' add [name] Add new configuration (interactive)');
1941
2036
  console.log(
1942
2037
  ' update [name] Update existing configuration (interactive)');
2038
+ console.log(
2039
+ ' fork [source-name] Copy existing configuration and update (interactive)');
1943
2040
  console.log(
1944
2041
  ' use <name> [-p|--permanent] Switch to specified configuration');
1945
2042
  console.log(
@@ -2062,6 +2159,9 @@ async function main() {
2062
2159
  case 'update':
2063
2160
  await update(filteredArgs[1]);
2064
2161
  break;
2162
+ case 'fork':
2163
+ await fork(filteredArgs[1]);
2164
+ break;
2065
2165
  case 'remove':
2066
2166
  case 'rm':
2067
2167
  await remove(filteredArgs[1]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccconfig",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Cross-platform Claude Code configuration switching tool",
5
5
  "main": "ccconfig.js",
6
6
  "bin": {