ccconfig 1.4.3 → 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 +40 -0
- package/README_zh.md +40 -0
- package/ccconfig.js +219 -59
- package/package.json +1 -1
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,8 +89,8 @@ function ensureProfileAvailable(
|
|
|
89
89
|
|
|
90
90
|
// All supported commands
|
|
91
91
|
const COMMANDS = [
|
|
92
|
-
'list', 'ls', 'add', 'update', 'use', 'start', 'safe-start', 'remove', 'rm',
|
|
93
|
-
'current', 'mode', 'env', '
|
|
92
|
+
'list', 'ls', 'add', 'update', 'fork', 'use', 'start', 'safe-start', 'remove', 'rm',
|
|
93
|
+
'current', 'mode', 'env', 'completion'
|
|
94
94
|
];
|
|
95
95
|
|
|
96
96
|
// ccconfig markers for shell config files
|
|
@@ -688,9 +688,8 @@ async function add(name) {
|
|
|
688
688
|
if (profilesMap[name]) {
|
|
689
689
|
console.error(`Error: Configuration '${name}' already exists`);
|
|
690
690
|
console.error('');
|
|
691
|
-
console.error('To modify this configuration, use
|
|
692
|
-
console.error(` ccconfig update ${name}
|
|
693
|
-
console.error(` ccconfig edit # Manual edit`);
|
|
691
|
+
console.error('To modify this configuration, use:');
|
|
692
|
+
console.error(` ccconfig update ${name}`);
|
|
694
693
|
process.exit(1);
|
|
695
694
|
}
|
|
696
695
|
|
|
@@ -704,18 +703,60 @@ async function add(name) {
|
|
|
704
703
|
|
|
705
704
|
console.log(`✓ Configuration '${name}' added`);
|
|
706
705
|
console.log('');
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
706
|
+
|
|
707
|
+
// Check if claude binary exists before offering to start
|
|
708
|
+
let claudeAvailable = false;
|
|
709
|
+
try {
|
|
710
|
+
const command =
|
|
711
|
+
process.platform === 'win32' ? 'where claude' : 'which claude';
|
|
712
|
+
execSync(command, {stdio: 'pipe'});
|
|
713
|
+
claudeAvailable = true;
|
|
714
|
+
} catch (err) {
|
|
715
|
+
// Claude not found, don't offer to start
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// Ask if user wants to start Claude Code with this profile immediately
|
|
719
|
+
const shouldStart = claudeAvailable ?
|
|
720
|
+
await helper.ask(`Start Claude Code with ${name} now? (yes/no)`, 'no') :
|
|
721
|
+
'no';
|
|
722
|
+
const normalized = shouldStart.trim().toLowerCase();
|
|
723
|
+
|
|
712
724
|
console.log('');
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
725
|
+
|
|
726
|
+
// Create auto-execute output manager (RAII-style)
|
|
727
|
+
const output = (() => {
|
|
728
|
+
let executed = false;
|
|
729
|
+
return {
|
|
730
|
+
execute: () => {
|
|
731
|
+
if (!executed) {
|
|
732
|
+
console.log('');
|
|
733
|
+
console.log(`Configuration '${name}' summary:`);
|
|
734
|
+
console.log('');
|
|
735
|
+
console.log('Saved environment variables:');
|
|
736
|
+
displayEnvVars(envVars);
|
|
737
|
+
console.log('');
|
|
738
|
+
console.log(`To start Claude Code with this configuration:`);
|
|
739
|
+
console.log(` ccconfig start ${name}`);
|
|
740
|
+
console.log('');
|
|
741
|
+
console.log('To update this configuration:');
|
|
742
|
+
console.log(` ccconfig update ${name}`);
|
|
743
|
+
console.log('');
|
|
744
|
+
console.log('Configuration saved to:');
|
|
745
|
+
console.log(` ${PROFILES_FILE}`);
|
|
746
|
+
executed = true;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
})();
|
|
751
|
+
|
|
752
|
+
// Attempt to start Claude (if user chose yes), deferring output to exit
|
|
753
|
+
const shouldStartClaude = normalized === 'yes' || normalized === 'y';
|
|
754
|
+
if (shouldStartClaude) {
|
|
755
|
+
start(name, [], {onExit: output.execute});
|
|
756
|
+
} else {
|
|
757
|
+
// If not starting Claude, show output immediately
|
|
758
|
+
output.execute();
|
|
759
|
+
}
|
|
719
760
|
} finally {
|
|
720
761
|
helper.close();
|
|
721
762
|
}
|
|
@@ -778,20 +819,105 @@ async function update(name) {
|
|
|
778
819
|
}
|
|
779
820
|
}
|
|
780
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
|
+
|
|
781
904
|
/**
|
|
782
905
|
* Remove configuration
|
|
783
906
|
*/
|
|
784
|
-
function remove(name) {
|
|
907
|
+
async function remove(name) {
|
|
785
908
|
if (!name) {
|
|
786
909
|
console.error('Error: Missing configuration name');
|
|
787
910
|
console.error('Usage: ccconfig remove <name>');
|
|
788
911
|
process.exit(1);
|
|
789
912
|
}
|
|
790
913
|
|
|
914
|
+
// Check if terminal is interactive before proceeding
|
|
915
|
+
requireInteractive('removing configurations');
|
|
916
|
+
|
|
791
917
|
// Validate configuration name
|
|
792
918
|
validateConfigName(name);
|
|
793
919
|
|
|
794
|
-
const {profiles} = ensureProfileAvailable(name, {
|
|
920
|
+
const {profile, profiles} = ensureProfileAvailable(name, {
|
|
795
921
|
allowEmptyEnv: true,
|
|
796
922
|
onEmptyProfiles: () => {
|
|
797
923
|
console.error('Error: Configuration file does not exist');
|
|
@@ -801,9 +927,45 @@ function remove(name) {
|
|
|
801
927
|
}
|
|
802
928
|
});
|
|
803
929
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
console.log(
|
|
930
|
+
// Display profile information before removal
|
|
931
|
+
console.log('');
|
|
932
|
+
console.log('WARNING: PERMANENT DELETION');
|
|
933
|
+
console.log('═══════════════════════════════════════════════════════════');
|
|
934
|
+
console.log('');
|
|
935
|
+
console.log(`Configuration to be removed: ${name}`);
|
|
936
|
+
console.log('');
|
|
937
|
+
console.log('Profile details:');
|
|
938
|
+
if (profile.env && Object.keys(profile.env).length > 0) {
|
|
939
|
+
displayEnvVars(profile.env, true, ' ');
|
|
940
|
+
} else {
|
|
941
|
+
console.log(' (no environment variables configured)');
|
|
942
|
+
}
|
|
943
|
+
console.log('');
|
|
944
|
+
console.log('This action CANNOT be undone!');
|
|
945
|
+
console.log('All configuration data for this profile will be \x1b[1mpermanently deleted\x1b[0m.');
|
|
946
|
+
console.log('');
|
|
947
|
+
|
|
948
|
+
// Ask for confirmation
|
|
949
|
+
const helper = new ReadlineHelper();
|
|
950
|
+
try {
|
|
951
|
+
const confirmation = await helper.ask(
|
|
952
|
+
`Are you sure you want to remove '${name}'? (yes/no)`, 'no');
|
|
953
|
+
const normalized = confirmation.trim().toLowerCase();
|
|
954
|
+
|
|
955
|
+
if (normalized !== 'yes' && normalized !== 'y') {
|
|
956
|
+
console.log('');
|
|
957
|
+
console.log('Operation cancelled.');
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// Proceed with removal
|
|
962
|
+
delete getProfilesMap(profiles)[name];
|
|
963
|
+
saveProfiles(profiles);
|
|
964
|
+
console.log('');
|
|
965
|
+
console.log(`✓ Configuration '${name}' removed`);
|
|
966
|
+
} finally {
|
|
967
|
+
helper.close();
|
|
968
|
+
}
|
|
807
969
|
}
|
|
808
970
|
|
|
809
971
|
/**
|
|
@@ -1262,25 +1424,6 @@ function current(showSecret = false) {
|
|
|
1262
1424
|
console.log('═══════════════════════════════════════════');
|
|
1263
1425
|
}
|
|
1264
1426
|
|
|
1265
|
-
/**
|
|
1266
|
-
* Show configuration file path
|
|
1267
|
-
*/
|
|
1268
|
-
function edit() {
|
|
1269
|
-
if (!fs.existsSync(PROFILES_FILE)) {
|
|
1270
|
-
console.error('Error: Configuration file does not exist');
|
|
1271
|
-
console.error('Please add a configuration first: ccconfig add <name>');
|
|
1272
|
-
process.exit(1);
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
const editor = process.env.EDITOR || process.env.VISUAL || 'vim';
|
|
1276
|
-
|
|
1277
|
-
console.log('Configuration file path:');
|
|
1278
|
-
console.log(` ${PROFILES_FILE}`);
|
|
1279
|
-
console.log('');
|
|
1280
|
-
console.log('Open it with your preferred editor, for example:');
|
|
1281
|
-
console.log(` ${editor} ${PROFILES_FILE}`);
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
1427
|
/**
|
|
1285
1428
|
* Switch/view mode
|
|
1286
1429
|
*/
|
|
@@ -1376,9 +1519,10 @@ function env(format = 'bash') {
|
|
|
1376
1519
|
* @param {Array} extraArgs - Additional arguments to pass to Claude
|
|
1377
1520
|
* @param {Object} options - Options object
|
|
1378
1521
|
* @param {boolean} options.safe - Whether to run in safe mode (default: false)
|
|
1522
|
+
* @param {Function} options.onExit - Callback to execute before process exits
|
|
1379
1523
|
*/
|
|
1380
1524
|
function startClaude(name, extraArgs = [], options = {}) {
|
|
1381
|
-
const {safe = false} = options;
|
|
1525
|
+
const {safe = false, onExit = null} = options;
|
|
1382
1526
|
const commandName = safe ? 'safe-start' : 'start';
|
|
1383
1527
|
|
|
1384
1528
|
if (!name) {
|
|
@@ -1531,6 +1675,11 @@ function startClaude(name, extraArgs = [], options = {}) {
|
|
|
1531
1675
|
process.removeListener('SIGINT', signalHandler);
|
|
1532
1676
|
process.removeListener('SIGTERM', signalHandler);
|
|
1533
1677
|
|
|
1678
|
+
// Execute onExit callback before showing promotion message
|
|
1679
|
+
if (typeof onExit === 'function') {
|
|
1680
|
+
onExit();
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1534
1683
|
// Show project promotion message on exit
|
|
1535
1684
|
console.log('');
|
|
1536
1685
|
console.log('──────────────────────────────────────────');
|
|
@@ -1566,16 +1715,16 @@ function startClaude(name, extraArgs = [], options = {}) {
|
|
|
1566
1715
|
/**
|
|
1567
1716
|
* Start Claude Code with specified profile (auto-approve mode)
|
|
1568
1717
|
*/
|
|
1569
|
-
function start(name, extraArgs = []) {
|
|
1570
|
-
return startClaude(name, extraArgs, {safe: false});
|
|
1718
|
+
function start(name, extraArgs = [], options = {}) {
|
|
1719
|
+
return startClaude(name, extraArgs, {safe: false, ...options});
|
|
1571
1720
|
}
|
|
1572
1721
|
|
|
1573
1722
|
/**
|
|
1574
1723
|
* Start Claude Code with specified profile (safe mode - requires permission
|
|
1575
1724
|
* confirmation)
|
|
1576
1725
|
*/
|
|
1577
|
-
function safeStart(name, extraArgs = []) {
|
|
1578
|
-
return startClaude(name, extraArgs, {safe: true});
|
|
1726
|
+
function safeStart(name, extraArgs = [], options = {}) {
|
|
1727
|
+
return startClaude(name, extraArgs, {safe: true, ...options});
|
|
1579
1728
|
}
|
|
1580
1729
|
|
|
1581
1730
|
/**
|
|
@@ -1618,7 +1767,7 @@ _ccconfig_completions() {
|
|
|
1618
1767
|
;;
|
|
1619
1768
|
2)
|
|
1620
1769
|
case "\${prev}" in
|
|
1621
|
-
use|start|safe-start|update|remove|rm)
|
|
1770
|
+
use|start|safe-start|update|fork|remove|rm)
|
|
1622
1771
|
COMPREPLY=( $(compgen -W "\${profiles}" -- \${cur}) )
|
|
1623
1772
|
;;
|
|
1624
1773
|
mode)
|
|
@@ -1627,6 +1776,9 @@ _ccconfig_completions() {
|
|
|
1627
1776
|
env)
|
|
1628
1777
|
COMPREPLY=( $(compgen -W "bash zsh fish sh powershell pwsh dotenv" -- \${cur}) )
|
|
1629
1778
|
;;
|
|
1779
|
+
completion)
|
|
1780
|
+
COMPREPLY=( $(compgen -W "bash zsh fish powershell pwsh" -- \${cur}) )
|
|
1781
|
+
;;
|
|
1630
1782
|
esac
|
|
1631
1783
|
;;
|
|
1632
1784
|
3)
|
|
@@ -1655,6 +1807,7 @@ _ccconfig() {
|
|
|
1655
1807
|
'ls:List all configurations'
|
|
1656
1808
|
'add:Add new configuration'
|
|
1657
1809
|
'update:Update existing configuration'
|
|
1810
|
+
'fork:Copy existing configuration and update'
|
|
1658
1811
|
'use:Switch to specified configuration'
|
|
1659
1812
|
'start:Start Claude Code (auto-approve mode)'
|
|
1660
1813
|
'safe-start:Start Claude Code (safe mode, requires confirmation)'
|
|
@@ -1663,7 +1816,6 @@ _ccconfig() {
|
|
|
1663
1816
|
'current:Display current configuration'
|
|
1664
1817
|
'mode:View or switch mode'
|
|
1665
1818
|
'env:Output environment variables'
|
|
1666
|
-
'edit:Show configuration file location'
|
|
1667
1819
|
)
|
|
1668
1820
|
|
|
1669
1821
|
modes=('settings' 'env')
|
|
@@ -1680,7 +1832,7 @@ _ccconfig() {
|
|
|
1680
1832
|
;;
|
|
1681
1833
|
3)
|
|
1682
1834
|
case $words[2] in
|
|
1683
|
-
use|start|safe-start|update|remove|rm)
|
|
1835
|
+
use|start|safe-start|update|fork|remove|rm)
|
|
1684
1836
|
_describe 'profile' profiles
|
|
1685
1837
|
;;
|
|
1686
1838
|
mode)
|
|
@@ -1689,6 +1841,11 @@ _ccconfig() {
|
|
|
1689
1841
|
env)
|
|
1690
1842
|
_describe 'format' formats
|
|
1691
1843
|
;;
|
|
1844
|
+
completion)
|
|
1845
|
+
local -a shells
|
|
1846
|
+
shells=('bash' 'zsh' 'fish' 'powershell' 'pwsh')
|
|
1847
|
+
_describe 'shell' shells
|
|
1848
|
+
;;
|
|
1692
1849
|
esac
|
|
1693
1850
|
;;
|
|
1694
1851
|
4)
|
|
@@ -1716,6 +1873,7 @@ complete -c ccconfig -f -n "__fish_use_subcommand" -a "list" -d "List all config
|
|
|
1716
1873
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "ls" -d "List all configurations"
|
|
1717
1874
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "add" -d "Add new configuration"
|
|
1718
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"
|
|
1719
1877
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "use" -d "Switch to specified configuration"
|
|
1720
1878
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "start" -d "Start Claude Code (auto-approve mode)"
|
|
1721
1879
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "safe-start" -d "Start Claude Code (safe mode, requires confirmation)"
|
|
@@ -1724,7 +1882,6 @@ complete -c ccconfig -f -n "__fish_use_subcommand" -a "rm" -d "Remove configurat
|
|
|
1724
1882
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "current" -d "Display current configuration"
|
|
1725
1883
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "mode" -d "View or switch mode"
|
|
1726
1884
|
complete -c ccconfig -f -n "__fish_use_subcommand" -a "env" -d "Output environment variables"
|
|
1727
|
-
complete -c ccconfig -f -n "__fish_use_subcommand" -a "edit" -d "Show configuration file location"
|
|
1728
1885
|
|
|
1729
1886
|
# Get profile names dynamically
|
|
1730
1887
|
function __ccconfig_profiles
|
|
@@ -1733,8 +1890,8 @@ function __ccconfig_profiles
|
|
|
1733
1890
|
end
|
|
1734
1891
|
end
|
|
1735
1892
|
|
|
1736
|
-
# Profile name completion for use, start, safe-start, update, remove
|
|
1737
|
-
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)"
|
|
1738
1895
|
|
|
1739
1896
|
# Mode options
|
|
1740
1897
|
complete -c ccconfig -f -n "__fish_seen_subcommand_from mode" -a "settings env"
|
|
@@ -1742,6 +1899,9 @@ complete -c ccconfig -f -n "__fish_seen_subcommand_from mode" -a "settings env"
|
|
|
1742
1899
|
# Env format options
|
|
1743
1900
|
complete -c ccconfig -f -n "__fish_seen_subcommand_from env" -a "bash zsh fish sh powershell pwsh dotenv"
|
|
1744
1901
|
|
|
1902
|
+
# Completion shell options
|
|
1903
|
+
complete -c ccconfig -f -n "__fish_seen_subcommand_from completion" -a "bash zsh fish powershell pwsh"
|
|
1904
|
+
|
|
1745
1905
|
# Flags for use command
|
|
1746
1906
|
complete -c ccconfig -f -n "__fish_seen_subcommand_from use" -s p -l permanent -d "Write permanently to shell config"
|
|
1747
1907
|
|
|
@@ -1776,7 +1936,7 @@ function Get-CconfigProfiles {
|
|
|
1776
1936
|
Register-ArgumentCompleter -Native -CommandName ccconfig -ScriptBlock {
|
|
1777
1937
|
param($wordToComplete, $commandAst, $cursorPosition)
|
|
1778
1938
|
|
|
1779
|
-
$commands = @('list', 'ls', 'add', 'update', 'use', 'start', 'safe-start', 'remove', 'rm', 'current', 'mode', 'env', '
|
|
1939
|
+
$commands = @('list', 'ls', 'add', 'update', 'fork', 'use', 'start', 'safe-start', 'remove', 'rm', 'current', 'mode', 'env', 'completion')
|
|
1780
1940
|
$modes = @('settings', 'env')
|
|
1781
1941
|
$formats = @('bash', 'zsh', 'fish', 'sh', 'powershell', 'pwsh', 'dotenv')
|
|
1782
1942
|
|
|
@@ -1798,7 +1958,7 @@ Register-ArgumentCompleter -Native -CommandName ccconfig -ScriptBlock {
|
|
|
1798
1958
|
# Second argument completions based on command
|
|
1799
1959
|
if ($position -eq 2 -or ($position -eq 3 -and $wordToComplete)) {
|
|
1800
1960
|
switch ($command) {
|
|
1801
|
-
{ $_ -in 'use', 'start', 'safe-start', 'update', 'remove', 'rm' } {
|
|
1961
|
+
{ $_ -in 'use', 'start', 'safe-start', 'update', 'fork', 'remove', 'rm' } {
|
|
1802
1962
|
Get-CconfigProfiles | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1803
1963
|
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
1804
1964
|
}
|
|
@@ -1875,6 +2035,8 @@ function help() {
|
|
|
1875
2035
|
' add [name] Add new configuration (interactive)');
|
|
1876
2036
|
console.log(
|
|
1877
2037
|
' update [name] Update existing configuration (interactive)');
|
|
2038
|
+
console.log(
|
|
2039
|
+
' fork [source-name] Copy existing configuration and update (interactive)');
|
|
1878
2040
|
console.log(
|
|
1879
2041
|
' use <name> [-p|--permanent] Switch to specified configuration');
|
|
1880
2042
|
console.log(
|
|
@@ -1889,8 +2051,6 @@ function help() {
|
|
|
1889
2051
|
' mode [settings|env] View or switch mode');
|
|
1890
2052
|
console.log(
|
|
1891
2053
|
' env [format] Output environment variables (env mode)');
|
|
1892
|
-
console.log(
|
|
1893
|
-
' edit Show configuration file location');
|
|
1894
2054
|
console.log(
|
|
1895
2055
|
' completion <bash|zsh|fish|pwsh> Generate shell completion script');
|
|
1896
2056
|
console.log('');
|
|
@@ -1999,9 +2159,12 @@ async function main() {
|
|
|
1999
2159
|
case 'update':
|
|
2000
2160
|
await update(filteredArgs[1]);
|
|
2001
2161
|
break;
|
|
2162
|
+
case 'fork':
|
|
2163
|
+
await fork(filteredArgs[1]);
|
|
2164
|
+
break;
|
|
2002
2165
|
case 'remove':
|
|
2003
2166
|
case 'rm':
|
|
2004
|
-
remove(filteredArgs[1]);
|
|
2167
|
+
await remove(filteredArgs[1]);
|
|
2005
2168
|
break;
|
|
2006
2169
|
case 'current':
|
|
2007
2170
|
current(showSecret);
|
|
@@ -2012,9 +2175,6 @@ async function main() {
|
|
|
2012
2175
|
case 'env':
|
|
2013
2176
|
env(filteredArgs[1] || 'bash');
|
|
2014
2177
|
break;
|
|
2015
|
-
case 'edit':
|
|
2016
|
-
edit();
|
|
2017
|
-
break;
|
|
2018
2178
|
case 'start':
|
|
2019
2179
|
if (!filteredArgs[1]) {
|
|
2020
2180
|
console.error('Error: Missing configuration name');
|