@tkpdx01/ccc 1.3.3 → 1.3.4
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 +1 -0
- package/package.json +1 -1
- package/src/commands/edit.js +6 -9
- package/src/profiles.js +53 -18
package/README.md
CHANGED
|
@@ -60,6 +60,7 @@ ccc webdav status # View sync status / 查看同步状态
|
|
|
60
60
|
- **Template Support / 模板**: Based on `~/.claude/settings.json`
|
|
61
61
|
- **Smart Import / 智能导入**: Auto-detect API URL and token
|
|
62
62
|
- **Sync Settings / 同步**: Update from template, preserve credentials
|
|
63
|
+
- **Claude Env Defaults / Claude 环境变量默认值**: Auto-ensure `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`, `CLAUDE_CODE_ATTRIBUTION_HEADER=0`, and `DISABLE_INSTALLATION_CHECKS=1` in both template and profiles
|
|
63
64
|
- **WebDAV Cloud Sync / 云同步**: Encrypted sync across devices
|
|
64
65
|
|
|
65
66
|
## Sync Command / 同步命令
|
package/package.json
CHANGED
package/src/commands/edit.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
resolveProfile,
|
|
14
14
|
getProfileCredentials,
|
|
15
15
|
getClaudeSettingsTemplate,
|
|
16
|
-
|
|
16
|
+
ensureRequiredClaudeEnvSettings
|
|
17
17
|
} from '../profiles.js';
|
|
18
18
|
|
|
19
19
|
export function editCommand(program) {
|
|
@@ -96,13 +96,11 @@ export function editCommand(program) {
|
|
|
96
96
|
currentProfile.env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
97
97
|
currentProfile.env.ANTHROPIC_BASE_URL = apiUrl;
|
|
98
98
|
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
currentProfile.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1';
|
|
105
|
-
}
|
|
99
|
+
// 确保主配置(~/.claude/settings.json)与 profile 都包含必要 env 设置
|
|
100
|
+
ensureRequiredClaudeEnvSettings();
|
|
101
|
+
currentProfile.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1';
|
|
102
|
+
currentProfile.env.CLAUDE_CODE_ATTRIBUTION_HEADER = '0';
|
|
103
|
+
currentProfile.env.DISABLE_INSTALLATION_CHECKS = '1';
|
|
106
104
|
|
|
107
105
|
// 如果重命名
|
|
108
106
|
if (newName && newName !== profile) {
|
|
@@ -126,4 +124,3 @@ export function editCommand(program) {
|
|
|
126
124
|
}
|
|
127
125
|
});
|
|
128
126
|
}
|
|
129
|
-
|
package/src/profiles.js
CHANGED
|
@@ -2,6 +2,11 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { CONFIG_DIR, PROFILES_DIR, DEFAULT_FILE, CLAUDE_SETTINGS_PATH } from './config.js';
|
|
4
4
|
|
|
5
|
+
function stringifyClaudeSettings(settings) {
|
|
6
|
+
// Claude Code 默认 settings.json 使用 2 空格缩进,并以换行结尾(便于 diff/兼容各平台编辑器)
|
|
7
|
+
return `${JSON.stringify(settings, null, 2)}\n`;
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
// 确保目录存在
|
|
6
11
|
export function ensureDirs() {
|
|
7
12
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
@@ -86,29 +91,53 @@ export function getClaudeSettingsTemplate() {
|
|
|
86
91
|
return null;
|
|
87
92
|
}
|
|
88
93
|
|
|
89
|
-
|
|
90
|
-
// 如果没有则添加,并返回更新后的模板
|
|
91
|
-
export function ensureDisableNonessentialTraffic() {
|
|
94
|
+
function ensureClaudeEnvSettings(envUpdates) {
|
|
92
95
|
const template = getClaudeSettingsTemplate();
|
|
93
96
|
if (!template) {
|
|
94
97
|
return null;
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
// 确保 env 对象存在
|
|
98
|
-
if (!template.env) {
|
|
101
|
+
if (!template.env || typeof template.env !== 'object' || Array.isArray(template.env)) {
|
|
99
102
|
template.env = {};
|
|
100
103
|
}
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
template.env
|
|
105
|
+
let changed = false;
|
|
106
|
+
for (const [key, value] of Object.entries(envUpdates)) {
|
|
107
|
+
if (template.env[key] !== value) {
|
|
108
|
+
template.env[key] = value;
|
|
109
|
+
changed = true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (changed) {
|
|
105
114
|
// 保存回主配置
|
|
106
|
-
fs.writeFileSync(CLAUDE_SETTINGS_PATH,
|
|
115
|
+
fs.writeFileSync(CLAUDE_SETTINGS_PATH, stringifyClaudeSettings(template));
|
|
107
116
|
}
|
|
108
117
|
|
|
109
118
|
return template;
|
|
110
119
|
}
|
|
111
120
|
|
|
121
|
+
// 确保主配置中有 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 设置
|
|
122
|
+
// 如果没有则添加,并返回更新后的模板
|
|
123
|
+
export function ensureDisableNonessentialTraffic() {
|
|
124
|
+
return ensureClaudeEnvSettings({ CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1' });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 确保主配置中禁用 Attribution Header(Claude Code env 变量)
|
|
128
|
+
export function ensureDisableAttributionHeader() {
|
|
129
|
+
return ensureClaudeEnvSettings({ CLAUDE_CODE_ATTRIBUTION_HEADER: '0' });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 一次性确保主配置包含本工具需要的 env 设置
|
|
133
|
+
export function ensureRequiredClaudeEnvSettings() {
|
|
134
|
+
return ensureClaudeEnvSettings({
|
|
135
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
136
|
+
CLAUDE_CODE_ATTRIBUTION_HEADER: '0',
|
|
137
|
+
DISABLE_INSTALLATION_CHECKS: '1'
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
112
141
|
// 读取 profile 配置
|
|
113
142
|
export function readProfile(name) {
|
|
114
143
|
const profilePath = getProfilePath(name);
|
|
@@ -126,21 +155,25 @@ export function readProfile(name) {
|
|
|
126
155
|
export function saveProfile(name, settings) {
|
|
127
156
|
ensureDirs();
|
|
128
157
|
const profilePath = getProfilePath(name);
|
|
129
|
-
fs.writeFileSync(profilePath,
|
|
158
|
+
fs.writeFileSync(profilePath, stringifyClaudeSettings(settings));
|
|
130
159
|
}
|
|
131
160
|
|
|
132
161
|
// 创建基于主配置的 profile(复制 ~/.claude/settings.json 并设置 env)
|
|
133
162
|
export function createProfileFromTemplate(name, apiUrl, apiKey) {
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const template = getClaudeSettingsTemplate() || {};
|
|
163
|
+
// 先确保主配置包含必要 env 设置(也会写回 ~/.claude/settings.json)
|
|
164
|
+
const ensuredTemplate = ensureRequiredClaudeEnvSettings();
|
|
165
|
+
const template = ensuredTemplate || getClaudeSettingsTemplate() || {};
|
|
138
166
|
|
|
139
167
|
// 确保 env 对象存在
|
|
140
168
|
if (!template.env) {
|
|
141
169
|
template.env = {};
|
|
142
170
|
}
|
|
143
171
|
|
|
172
|
+
// 确保 profile 也包含相同设置
|
|
173
|
+
template.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1';
|
|
174
|
+
template.env.CLAUDE_CODE_ATTRIBUTION_HEADER = '0';
|
|
175
|
+
template.env.DISABLE_INSTALLATION_CHECKS = '1';
|
|
176
|
+
|
|
144
177
|
// 只设置 API 凭证到 env
|
|
145
178
|
template.env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
146
179
|
template.env.ANTHROPIC_BASE_URL = apiUrl;
|
|
@@ -151,10 +184,8 @@ export function createProfileFromTemplate(name, apiUrl, apiKey) {
|
|
|
151
184
|
|
|
152
185
|
// 同步主配置到 profile(保留 profile 的 API 凭证)
|
|
153
186
|
export function syncProfileWithTemplate(name) {
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const template = getClaudeSettingsTemplate();
|
|
187
|
+
// 先确保主配置包含必要 env 设置(也会写回 ~/.claude/settings.json)
|
|
188
|
+
const template = ensureRequiredClaudeEnvSettings() || getClaudeSettingsTemplate();
|
|
158
189
|
if (!template) {
|
|
159
190
|
return null;
|
|
160
191
|
}
|
|
@@ -175,6 +206,11 @@ export function syncProfileWithTemplate(name) {
|
|
|
175
206
|
// 确保 env 对象存在并保留 API 凭证
|
|
176
207
|
newProfile.env = { ...(template.env || {}), ANTHROPIC_AUTH_TOKEN: apiKey, ANTHROPIC_BASE_URL: apiUrl };
|
|
177
208
|
|
|
209
|
+
// 确保 profile 也包含相同设置
|
|
210
|
+
newProfile.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1';
|
|
211
|
+
newProfile.env.CLAUDE_CODE_ATTRIBUTION_HEADER = '0';
|
|
212
|
+
newProfile.env.DISABLE_INSTALLATION_CHECKS = '1';
|
|
213
|
+
|
|
178
214
|
saveProfile(name, newProfile);
|
|
179
215
|
return newProfile;
|
|
180
216
|
}
|
|
@@ -208,4 +244,3 @@ export function clearDefaultProfile() {
|
|
|
208
244
|
fs.unlinkSync(DEFAULT_FILE);
|
|
209
245
|
}
|
|
210
246
|
}
|
|
211
|
-
|