@tkpdx01/ccc 1.2.5 → 1.2.7
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/.claude/settings.local.json +34 -0
- package/Claude Code settings.txt +776 -776
- package/index.js +4 -4
- package/nul +1 -0
- package/package.json +39 -39
- package/settings-sample.json +4 -0
- package/src/commands/delete.js +66 -66
- package/src/commands/edit.js +120 -106
- package/src/commands/help.js +50 -52
- package/src/commands/import.js +356 -365
- package/src/commands/index.js +10 -10
- package/src/commands/list.js +46 -58
- package/src/commands/new.js +109 -143
- package/src/commands/show.js +68 -68
- package/src/commands/sync.js +93 -168
- package/src/commands/use.js +19 -19
- package/src/config.js +9 -9
- package/src/launch.js +69 -69
- package/src/parsers.js +154 -154
- package/src/profiles.js +182 -123
- package/src/utils.js +67 -82
package/src/commands/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { listCommand } from './list.js';
|
|
2
|
-
export { useCommand } from './use.js';
|
|
3
|
-
export { showCommand } from './show.js';
|
|
4
|
-
export { importCommand } from './import.js';
|
|
5
|
-
export { newCommand } from './new.js';
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export { helpCommand, showHelp } from './help.js';
|
|
10
|
-
|
|
1
|
+
export { listCommand } from './list.js';
|
|
2
|
+
export { useCommand } from './use.js';
|
|
3
|
+
export { showCommand } from './show.js';
|
|
4
|
+
export { importCommand } from './import.js';
|
|
5
|
+
export { newCommand } from './new.js';
|
|
6
|
+
export { editCommand } from './edit.js';
|
|
7
|
+
export { deleteCommand } from './delete.js';
|
|
8
|
+
export { syncCommand } from './sync.js';
|
|
9
|
+
export { helpCommand, showHelp } from './help.js';
|
|
10
|
+
|
package/src/commands/list.js
CHANGED
|
@@ -1,58 +1,46 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
.
|
|
9
|
-
.
|
|
10
|
-
.
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
console.log(chalk.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
head: [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const num = isDefault ? chalk.green(`${index + 1}`) : chalk.gray(`${index + 1}`);
|
|
49
|
-
const name = isDefault ? chalk.green(`${p} *`) : p;
|
|
50
|
-
table.push([num, name, baseUrl]);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
console.log();
|
|
54
|
-
console.log(table.toString());
|
|
55
|
-
console.log(chalk.gray(`\n 共 ${profiles.length} 个配置,* 表示默认,可用序号或名称启动\n`));
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import Table from 'cli-table3';
|
|
3
|
+
import { getProfiles, getDefaultProfile, getProfileCredentials } from '../profiles.js';
|
|
4
|
+
|
|
5
|
+
export function listCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('list')
|
|
8
|
+
.alias('ls')
|
|
9
|
+
.description('列出所有 profiles')
|
|
10
|
+
.action(() => {
|
|
11
|
+
const profiles = getProfiles();
|
|
12
|
+
const defaultProfile = getDefaultProfile();
|
|
13
|
+
|
|
14
|
+
if (profiles.length === 0) {
|
|
15
|
+
console.log(chalk.yellow('没有可用的 profiles'));
|
|
16
|
+
console.log(chalk.gray('使用 "ccc import" 导入配置'));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const table = new Table({
|
|
21
|
+
head: [chalk.cyan('#'), chalk.cyan('Profile'), chalk.cyan('ANTHROPIC_BASE_URL')],
|
|
22
|
+
style: { head: [], border: [] },
|
|
23
|
+
chars: {
|
|
24
|
+
'top': '─', 'top-mid': '┬', 'top-left': '┌', 'top-right': '┐',
|
|
25
|
+
'bottom': '─', 'bottom-mid': '┴', 'bottom-left': '└', 'bottom-right': '┘',
|
|
26
|
+
'left': '│', 'left-mid': '├', 'mid': '─', 'mid-mid': '┼',
|
|
27
|
+
'right': '│', 'right-mid': '┤', 'middle': '│'
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
profiles.forEach((p, index) => {
|
|
32
|
+
const isDefault = p === defaultProfile;
|
|
33
|
+
const { apiUrl } = getProfileCredentials(p);
|
|
34
|
+
const baseUrl = apiUrl || chalk.gray('(未设置)');
|
|
35
|
+
|
|
36
|
+
const num = isDefault ? chalk.green(`${index + 1}`) : chalk.gray(`${index + 1}`);
|
|
37
|
+
const name = isDefault ? chalk.green(`${p} *`) : p;
|
|
38
|
+
table.push([num, name, baseUrl]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
console.log();
|
|
42
|
+
console.log(table.toString());
|
|
43
|
+
console.log(chalk.gray(`\n 共 ${profiles.length} 个配置,* 表示默认,可用序号或名称启动\n`));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
package/src/commands/new.js
CHANGED
|
@@ -1,143 +1,109 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
|
-
import {
|
|
4
|
-
ensureDirs,
|
|
5
|
-
getProfiles,
|
|
6
|
-
profileExists,
|
|
7
|
-
|
|
8
|
-
setDefaultProfile
|
|
9
|
-
|
|
10
|
-
} from '../
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// 合并设置:保留模板中的其他设置,覆盖 API 相关设置
|
|
111
|
-
const newSettings = {
|
|
112
|
-
...baseSettings,
|
|
113
|
-
apiUrl,
|
|
114
|
-
apiKey
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
ensureDirs();
|
|
118
|
-
saveProfile(finalName, newSettings);
|
|
119
|
-
console.log(chalk.green(`\n✓ 配置 "${finalName}" 已创建`));
|
|
120
|
-
|
|
121
|
-
// 如果是第一个 profile,设为默认
|
|
122
|
-
const profiles = getProfiles();
|
|
123
|
-
if (profiles.length === 1) {
|
|
124
|
-
setDefaultProfile(finalName);
|
|
125
|
-
console.log(chalk.green(`✓ 已设为默认配置`));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 询问是否立即使用
|
|
129
|
-
const { useNow } = await inquirer.prompt([
|
|
130
|
-
{
|
|
131
|
-
type: 'confirm',
|
|
132
|
-
name: 'useNow',
|
|
133
|
-
message: '是否立即启动 Claude?',
|
|
134
|
-
default: false
|
|
135
|
-
}
|
|
136
|
-
]);
|
|
137
|
-
|
|
138
|
-
if (useNow) {
|
|
139
|
-
launchClaude(finalName);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import {
|
|
4
|
+
ensureDirs,
|
|
5
|
+
getProfiles,
|
|
6
|
+
profileExists,
|
|
7
|
+
createProfileFromTemplate,
|
|
8
|
+
setDefaultProfile
|
|
9
|
+
} from '../profiles.js';
|
|
10
|
+
import { launchClaude } from '../launch.js';
|
|
11
|
+
|
|
12
|
+
export function newCommand(program) {
|
|
13
|
+
program
|
|
14
|
+
.command('new [name]')
|
|
15
|
+
.description('创建新的配置(基于 ~/.claude/settings.json,在 env 中设置 API 凭证)')
|
|
16
|
+
.action(async (name) => {
|
|
17
|
+
// 如果没有提供名称,询问
|
|
18
|
+
if (!name) {
|
|
19
|
+
const { profileName } = await inquirer.prompt([
|
|
20
|
+
{
|
|
21
|
+
type: 'input',
|
|
22
|
+
name: 'profileName',
|
|
23
|
+
message: '配置名称:',
|
|
24
|
+
validate: (input) => input.trim() ? true : '请输入配置名称'
|
|
25
|
+
}
|
|
26
|
+
]);
|
|
27
|
+
name = profileName;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 检查是否已存在
|
|
31
|
+
if (profileExists(name)) {
|
|
32
|
+
const { overwrite } = await inquirer.prompt([
|
|
33
|
+
{
|
|
34
|
+
type: 'confirm',
|
|
35
|
+
name: 'overwrite',
|
|
36
|
+
message: `配置 "${name}" 已存在,是否覆盖?`,
|
|
37
|
+
default: false
|
|
38
|
+
}
|
|
39
|
+
]);
|
|
40
|
+
if (!overwrite) {
|
|
41
|
+
console.log(chalk.yellow('已取消'));
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { apiUrl, apiKey, finalName } = await inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'apiUrl',
|
|
50
|
+
message: 'ANTHROPIC_BASE_URL:',
|
|
51
|
+
default: 'https://api.anthropic.com'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'input',
|
|
55
|
+
name: 'apiKey',
|
|
56
|
+
message: 'ANTHROPIC_AUTH_TOKEN:',
|
|
57
|
+
default: ''
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'input',
|
|
61
|
+
name: 'finalName',
|
|
62
|
+
message: 'Profile 名称:',
|
|
63
|
+
default: name
|
|
64
|
+
}
|
|
65
|
+
]);
|
|
66
|
+
|
|
67
|
+
// 如果名称改变了,检查新名称是否存在
|
|
68
|
+
if (finalName !== name && profileExists(finalName)) {
|
|
69
|
+
const { overwriteNew } = await inquirer.prompt([
|
|
70
|
+
{
|
|
71
|
+
type: 'confirm',
|
|
72
|
+
name: 'overwriteNew',
|
|
73
|
+
message: `配置 "${finalName}" 已存在,是否覆盖?`,
|
|
74
|
+
default: false
|
|
75
|
+
}
|
|
76
|
+
]);
|
|
77
|
+
if (!overwriteNew) {
|
|
78
|
+
console.log(chalk.yellow('已取消'));
|
|
79
|
+
process.exit(0);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
ensureDirs();
|
|
84
|
+
createProfileFromTemplate(finalName, apiUrl, apiKey);
|
|
85
|
+
console.log(chalk.green(`\n✓ 配置 "${finalName}" 已创建(基于 ~/.claude/settings.json)`));
|
|
86
|
+
|
|
87
|
+
// 如果是第一个 profile,设为默认
|
|
88
|
+
const profiles = getProfiles();
|
|
89
|
+
if (profiles.length === 1) {
|
|
90
|
+
setDefaultProfile(finalName);
|
|
91
|
+
console.log(chalk.green(`✓ 已设为默认配置`));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 询问是否立即使用
|
|
95
|
+
const { useNow } = await inquirer.prompt([
|
|
96
|
+
{
|
|
97
|
+
type: 'confirm',
|
|
98
|
+
name: 'useNow',
|
|
99
|
+
message: '是否立即启动 Claude?',
|
|
100
|
+
default: false
|
|
101
|
+
}
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
if (useNow) {
|
|
105
|
+
launchClaude(finalName);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
package/src/commands/show.js
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
|
-
import {
|
|
4
|
-
getProfiles,
|
|
5
|
-
getDefaultProfile,
|
|
6
|
-
profileExists,
|
|
7
|
-
getProfilePath,
|
|
8
|
-
readProfile
|
|
9
|
-
} from '../profiles.js';
|
|
10
|
-
import { formatValue } from '../utils.js';
|
|
11
|
-
|
|
12
|
-
export function showCommand(program) {
|
|
13
|
-
program
|
|
14
|
-
.command('show [profile]')
|
|
15
|
-
.description('显示 profile 的完整配置')
|
|
16
|
-
.action(async (profile) => {
|
|
17
|
-
const profiles = getProfiles();
|
|
18
|
-
|
|
19
|
-
if (profiles.length === 0) {
|
|
20
|
-
console.log(chalk.yellow('没有可用的 profiles'));
|
|
21
|
-
process.exit(0);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// 如果没有指定 profile,交互选择
|
|
25
|
-
if (!profile) {
|
|
26
|
-
const defaultProfile = getDefaultProfile();
|
|
27
|
-
const { selectedProfile } = await inquirer.prompt([
|
|
28
|
-
{
|
|
29
|
-
type: 'list',
|
|
30
|
-
name: 'selectedProfile',
|
|
31
|
-
message: '选择要查看的配置:',
|
|
32
|
-
choices: profiles,
|
|
33
|
-
default: defaultProfile
|
|
34
|
-
}
|
|
35
|
-
]);
|
|
36
|
-
profile = selectedProfile;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!profileExists(profile)) {
|
|
40
|
-
console.log(chalk.red(`Profile "${profile}" 不存在`));
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const profilePath = getProfilePath(profile);
|
|
45
|
-
const settings = readProfile(profile);
|
|
46
|
-
const isDefault = getDefaultProfile() === profile;
|
|
47
|
-
|
|
48
|
-
console.log(chalk.cyan.bold(`\n Profile: ${profile}`) + (isDefault ? chalk.green(' (默认)') : ''));
|
|
49
|
-
console.log(chalk.gray(` 路径: ${profilePath}\n`));
|
|
50
|
-
|
|
51
|
-
// 格式化显示配置
|
|
52
|
-
Object.entries(settings).forEach(([key, value]) => {
|
|
53
|
-
const formattedValue = formatValue(key, value);
|
|
54
|
-
if (key === 'apiKey' && value) {
|
|
55
|
-
console.log(` ${chalk.cyan(key)}: ${chalk.yellow(formattedValue)}`);
|
|
56
|
-
} else if (typeof value === 'boolean') {
|
|
57
|
-
console.log(` ${chalk.cyan(key)}: ${value ? chalk.green(formattedValue) : chalk.red(formattedValue)}`);
|
|
58
|
-
} else if (typeof value === 'object') {
|
|
59
|
-
console.log(` ${chalk.cyan(key)}: ${chalk.gray(formattedValue)}`);
|
|
60
|
-
} else {
|
|
61
|
-
console.log(` ${chalk.cyan(key)}: ${chalk.white(formattedValue)}`);
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
console.log();
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import {
|
|
4
|
+
getProfiles,
|
|
5
|
+
getDefaultProfile,
|
|
6
|
+
profileExists,
|
|
7
|
+
getProfilePath,
|
|
8
|
+
readProfile
|
|
9
|
+
} from '../profiles.js';
|
|
10
|
+
import { formatValue } from '../utils.js';
|
|
11
|
+
|
|
12
|
+
export function showCommand(program) {
|
|
13
|
+
program
|
|
14
|
+
.command('show [profile]')
|
|
15
|
+
.description('显示 profile 的完整配置')
|
|
16
|
+
.action(async (profile) => {
|
|
17
|
+
const profiles = getProfiles();
|
|
18
|
+
|
|
19
|
+
if (profiles.length === 0) {
|
|
20
|
+
console.log(chalk.yellow('没有可用的 profiles'));
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 如果没有指定 profile,交互选择
|
|
25
|
+
if (!profile) {
|
|
26
|
+
const defaultProfile = getDefaultProfile();
|
|
27
|
+
const { selectedProfile } = await inquirer.prompt([
|
|
28
|
+
{
|
|
29
|
+
type: 'list',
|
|
30
|
+
name: 'selectedProfile',
|
|
31
|
+
message: '选择要查看的配置:',
|
|
32
|
+
choices: profiles,
|
|
33
|
+
default: defaultProfile
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
profile = selectedProfile;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!profileExists(profile)) {
|
|
40
|
+
console.log(chalk.red(`Profile "${profile}" 不存在`));
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const profilePath = getProfilePath(profile);
|
|
45
|
+
const settings = readProfile(profile);
|
|
46
|
+
const isDefault = getDefaultProfile() === profile;
|
|
47
|
+
|
|
48
|
+
console.log(chalk.cyan.bold(`\n Profile: ${profile}`) + (isDefault ? chalk.green(' (默认)') : ''));
|
|
49
|
+
console.log(chalk.gray(` 路径: ${profilePath}\n`));
|
|
50
|
+
|
|
51
|
+
// 格式化显示配置
|
|
52
|
+
Object.entries(settings).forEach(([key, value]) => {
|
|
53
|
+
const formattedValue = formatValue(key, value);
|
|
54
|
+
if ((key === 'apiKey' || key === 'ANTHROPIC_AUTH_TOKEN') && value) {
|
|
55
|
+
console.log(` ${chalk.cyan(key)}: ${chalk.yellow(formattedValue)}`);
|
|
56
|
+
} else if (typeof value === 'boolean') {
|
|
57
|
+
console.log(` ${chalk.cyan(key)}: ${value ? chalk.green(formattedValue) : chalk.red(formattedValue)}`);
|
|
58
|
+
} else if (typeof value === 'object') {
|
|
59
|
+
console.log(` ${chalk.cyan(key)}: ${chalk.gray(formattedValue)}`);
|
|
60
|
+
} else {
|
|
61
|
+
console.log(` ${chalk.cyan(key)}: ${chalk.white(formattedValue)}`);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
console.log();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|