ai-account-switch 1.3.0 → 1.4.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_ZH.md +69 -5
- package/package.json +1 -1
- package/src/commands.js +23 -12
- package/src/config.js +72 -5
- package/src/index.js +11 -1
- package/src/ui-server.js +1219 -0
package/README_ZH.md
CHANGED
|
@@ -11,7 +11,15 @@
|
|
|
11
11
|
- **项目级配置**:每个项目可以使用不同的账户
|
|
12
12
|
- **智能目录检测**:在项目的任何子目录中都能工作(类似 git)
|
|
13
13
|
- **Claude Code 集成**:自动生成 `.claude/settings.local.json` 配置文件
|
|
14
|
-
-
|
|
14
|
+
- **Web UI 管理界面**:
|
|
15
|
+
- 🎨 现代化单页面应用,支持深色/浅色主题
|
|
16
|
+
- 🌍 中英文双语支持,一键切换
|
|
17
|
+
- ⚙️ 可视化管理账号:增删改查一目了然
|
|
18
|
+
- 📤 导入/导出功能:批量管理账号配置
|
|
19
|
+
- 🔍 实时搜索过滤账号
|
|
20
|
+
- 💾 自定义环境变量配置
|
|
21
|
+
- 🎯 主题自动跟随系统设置
|
|
22
|
+
- **安全存储**:账户凭证仅存储在本地
|
|
15
23
|
- **交互式命令行**:所有操作都有易用的交互式提示
|
|
16
24
|
- **多种账户类型**:支持 Claude、Codex 和其他 AI 服务
|
|
17
25
|
|
|
@@ -214,6 +222,7 @@ npm link
|
|
|
214
222
|
| `ais paths` | - | 显示配置文件路径 |
|
|
215
223
|
| `ais doctor` | - | 诊断 Claude Code 配置问题 |
|
|
216
224
|
| `ais export <name>` | - | 导出账户为 JSON 格式 |
|
|
225
|
+
| `ais ui` | - | 启动 Web UI 管理界面 |
|
|
217
226
|
| `ais help` | - | 显示帮助信息 |
|
|
218
227
|
| `ais --version` | - | 显示版本号 |
|
|
219
228
|
|
|
@@ -237,7 +246,6 @@ ais add my-claude-account
|
|
|
237
246
|
- 账户类型(Claude、Codex、其他)
|
|
238
247
|
- API Key
|
|
239
248
|
- API URL(可选)
|
|
240
|
-
- Organization ID(可选)
|
|
241
249
|
- Email(可选)
|
|
242
250
|
- 描述(可选)
|
|
243
251
|
- 自定义环境变量(可选)
|
|
@@ -272,6 +280,7 @@ ais use
|
|
|
272
280
|
```
|
|
273
281
|
|
|
274
282
|
**注意**:此命令会自动生成 `.claude/settings.local.json` 文件用于 Claude Code CLI 集成。
|
|
283
|
+
如果检测到当前项目是 Git 仓库,还会自动将配置文件添加到 `.gitignore` 中,避免将敏感信息提交到版本控制。
|
|
275
284
|
你可以在项目的任何子目录中运行此命令 - 它会自动找到项目根目录。
|
|
276
285
|
|
|
277
286
|
#### 4. 查看当前项目信息
|
|
@@ -290,7 +299,40 @@ ais current
|
|
|
290
299
|
|
|
291
300
|
**注意**:这些命令可以在项目的任何子目录中使用,类似 git 命令的工作方式。
|
|
292
301
|
|
|
293
|
-
#### 5.
|
|
302
|
+
#### 5. 使用 Web UI 管理界面
|
|
303
|
+
|
|
304
|
+
启动可视化管理界面:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
ais ui
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
这将在浏览器中打开 Web UI,服务器会自动使用一个随机的高位端口(49152-65535)。如果端口被占用,会自动尝试其他端口,提供以下功能:
|
|
311
|
+
|
|
312
|
+
**界面特性:**
|
|
313
|
+
- **账号管理**: 可视化的卡片界面,显示所有账号信息
|
|
314
|
+
- **添加/编辑账号**: 友好的表单界面,支持所有配置项
|
|
315
|
+
- **删除账号**: 一键删除,带确认提示
|
|
316
|
+
- **搜索过滤**: 实时搜索账号名称、邮箱或类型
|
|
317
|
+
- **批量操作**:
|
|
318
|
+
- 导出所有账号为 JSON 文件
|
|
319
|
+
- 从 JSON 文件导入账号(支持覆盖选项)
|
|
320
|
+
- **主题切换**:
|
|
321
|
+
- iOS 风格的 Switch 开关
|
|
322
|
+
- 支持浅色和深色主题
|
|
323
|
+
- 默认跟随系统主题设置
|
|
324
|
+
- **多语言支持**:
|
|
325
|
+
- 中文/英文一键切换
|
|
326
|
+
- 界面默认使用中文
|
|
327
|
+
- 语言设置自动保存
|
|
328
|
+
|
|
329
|
+
**UI 使用提示:**
|
|
330
|
+
- 所有修改实时同步到本地配置
|
|
331
|
+
- 关闭浏览器窗口不影响数据
|
|
332
|
+
- 按 `Ctrl+C` 停止 Web 服务器
|
|
333
|
+
- 支持在任何浏览器中使用
|
|
334
|
+
|
|
335
|
+
#### 6. 删除账户
|
|
294
336
|
|
|
295
337
|
删除不再需要的账户:
|
|
296
338
|
|
|
@@ -361,7 +403,6 @@ ais export my-claude-account
|
|
|
361
403
|
"env": {
|
|
362
404
|
"ANTHROPIC_AUTH_TOKEN": "your-api-key",
|
|
363
405
|
"ANTHROPIC_BASE_URL": "your-api-url",
|
|
364
|
-
"ANTHROPIC_ORGANIZATION_ID": "your-org-id",
|
|
365
406
|
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
|
|
366
407
|
},
|
|
367
408
|
"permissions": {
|
|
@@ -469,7 +510,10 @@ ais use correct-account
|
|
|
469
510
|
|
|
470
511
|
- API 密钥仅存储在本地机器上
|
|
471
512
|
- 全局配置文件包含敏感凭证
|
|
472
|
-
-
|
|
513
|
+
- `ais use` 命令会自动将配置文件添加到 `.gitignore` (如果项目是 Git 仓库)
|
|
514
|
+
- 始终验证 `.gitignore` 包含以下文件:
|
|
515
|
+
- `.ais-project-config`
|
|
516
|
+
- `.claude/settings.local.json`
|
|
473
517
|
- 切勿将账户凭证提交到版本控制
|
|
474
518
|
- 显示 API 密钥时会进行掩码处理(仅显示前 4 位和后 4 位字符)
|
|
475
519
|
|
|
@@ -581,6 +625,26 @@ MIT License - 欢迎在你的项目中使用此工具!
|
|
|
581
625
|
|
|
582
626
|
## 更新日志
|
|
583
627
|
|
|
628
|
+
### v1.4.0
|
|
629
|
+
- **添加 Web UI 管理界面**:
|
|
630
|
+
- 现代化单页面应用,支持深色/浅色主题
|
|
631
|
+
- 中英文双语支持,默认中文
|
|
632
|
+
- 可视化账号管理:增删改查一目了然
|
|
633
|
+
- 导入/导出功能:批量管理账号配置
|
|
634
|
+
- 实时搜索过滤账号
|
|
635
|
+
- 自定义环境变量配置
|
|
636
|
+
- 主题自动跟随系统设置
|
|
637
|
+
- iOS 风格的主题切换开关
|
|
638
|
+
- **端口优化**:
|
|
639
|
+
- UI 服务器使用随机高位端口(49152-65535)
|
|
640
|
+
- 自动检测端口冲突并重试
|
|
641
|
+
- **界面改进**:
|
|
642
|
+
- 修复账号卡片按钮位置不一致问题
|
|
643
|
+
- 按钮始终固定在卡片底部
|
|
644
|
+
- **移除组织 ID 配置**:
|
|
645
|
+
- 简化账号配置流程
|
|
646
|
+
- 移除 CLI 和 UI 中的组织 ID 选项
|
|
647
|
+
|
|
584
648
|
### v1.3.0
|
|
585
649
|
- **改进自定义环境变量输入**:
|
|
586
650
|
- 支持单行 `KEY=VALUE` 格式输入(例如:`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`)
|
package/package.json
CHANGED
package/src/commands.js
CHANGED
|
@@ -59,12 +59,6 @@ async function addAccount(name, options) {
|
|
|
59
59
|
message: 'Enter API URL (optional):',
|
|
60
60
|
default: ''
|
|
61
61
|
},
|
|
62
|
-
{
|
|
63
|
-
type: 'input',
|
|
64
|
-
name: 'organizationId',
|
|
65
|
-
message: 'Enter Organization ID (optional):',
|
|
66
|
-
default: ''
|
|
67
|
-
},
|
|
68
62
|
{
|
|
69
63
|
type: 'input',
|
|
70
64
|
name: 'email',
|
|
@@ -252,9 +246,19 @@ async function useAccount(name) {
|
|
|
252
246
|
|
|
253
247
|
const success = config.setProjectAccount(name);
|
|
254
248
|
if (success) {
|
|
249
|
+
const fs = require('fs');
|
|
250
|
+
const path = require('path');
|
|
251
|
+
|
|
255
252
|
console.log(chalk.green(`✓ Switched to account '${name}' for current project.`));
|
|
256
253
|
console.log(chalk.yellow(`Project: ${process.cwd()}`));
|
|
257
254
|
console.log(chalk.cyan(`✓ Claude configuration generated at: .claude/settings.local.json`));
|
|
255
|
+
|
|
256
|
+
// Check if .gitignore was updated
|
|
257
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
258
|
+
const gitDir = path.join(process.cwd(), '.git');
|
|
259
|
+
if (fs.existsSync(gitDir) && fs.existsSync(gitignorePath)) {
|
|
260
|
+
console.log(chalk.cyan(`✓ Updated .gitignore to exclude AIS configuration files`));
|
|
261
|
+
}
|
|
258
262
|
} else {
|
|
259
263
|
console.log(chalk.red('✗ Failed to set account.'));
|
|
260
264
|
}
|
|
@@ -278,7 +282,6 @@ function showInfo() {
|
|
|
278
282
|
console.log(`${chalk.cyan('Type:')} ${projectAccount.type}`);
|
|
279
283
|
console.log(`${chalk.cyan('API Key:')} ${maskApiKey(projectAccount.apiKey)}`);
|
|
280
284
|
if (projectAccount.apiUrl) console.log(`${chalk.cyan('API URL:')} ${projectAccount.apiUrl}`);
|
|
281
|
-
if (projectAccount.organizationId) console.log(`${chalk.cyan('Organization ID:')} ${projectAccount.organizationId}`);
|
|
282
285
|
if (projectAccount.email) console.log(`${chalk.cyan('Email:')} ${projectAccount.email}`);
|
|
283
286
|
if (projectAccount.description) console.log(`${chalk.cyan('Description:')} ${projectAccount.description}`);
|
|
284
287
|
if (projectAccount.customEnv && Object.keys(projectAccount.customEnv).length > 0) {
|
|
@@ -473,10 +476,6 @@ function doctor() {
|
|
|
473
476
|
if (claudeConfig.env && claudeConfig.env.ANTHROPIC_BASE_URL) {
|
|
474
477
|
console.log(` API URL: ${claudeConfig.env.ANTHROPIC_BASE_URL}`);
|
|
475
478
|
}
|
|
476
|
-
|
|
477
|
-
if (claudeConfig.env && claudeConfig.env.ANTHROPIC_ORGANIZATION_ID) {
|
|
478
|
-
console.log(` Org ID: ${claudeConfig.env.ANTHROPIC_ORGANIZATION_ID}`);
|
|
479
|
-
}
|
|
480
479
|
} catch (e) {
|
|
481
480
|
console.log(chalk.red(` ✗ Error reading Claude config: ${e.message}`));
|
|
482
481
|
}
|
|
@@ -532,6 +531,17 @@ function doctor() {
|
|
|
532
531
|
console.log('');
|
|
533
532
|
}
|
|
534
533
|
|
|
534
|
+
/**
|
|
535
|
+
* Start Web UI server
|
|
536
|
+
*/
|
|
537
|
+
function startUI() {
|
|
538
|
+
const UIServer = require('./ui-server');
|
|
539
|
+
const server = new UIServer();
|
|
540
|
+
|
|
541
|
+
console.log(chalk.cyan('\n🌐 Starting AIS Web UI...\n'));
|
|
542
|
+
server.start();
|
|
543
|
+
}
|
|
544
|
+
|
|
535
545
|
module.exports = {
|
|
536
546
|
addAccount,
|
|
537
547
|
listAccounts,
|
|
@@ -541,5 +551,6 @@ module.exports = {
|
|
|
541
551
|
showCurrent,
|
|
542
552
|
showPaths,
|
|
543
553
|
exportAccount,
|
|
544
|
-
doctor
|
|
554
|
+
doctor,
|
|
555
|
+
startUI
|
|
545
556
|
};
|
package/src/config.js
CHANGED
|
@@ -145,6 +145,78 @@ class ConfigManager {
|
|
|
145
145
|
// Generate Claude Code project-level configuration
|
|
146
146
|
this.generateClaudeConfig(account, projectRoot);
|
|
147
147
|
|
|
148
|
+
// Add to .gitignore if git is initialized
|
|
149
|
+
this.addToGitignore(projectRoot);
|
|
150
|
+
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Add AIS config files to .gitignore if git repository exists
|
|
156
|
+
*/
|
|
157
|
+
addToGitignore(projectRoot = process.cwd()) {
|
|
158
|
+
const gitDir = path.join(projectRoot, '.git');
|
|
159
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
160
|
+
|
|
161
|
+
// Check if this is a git repository
|
|
162
|
+
if (!fs.existsSync(gitDir)) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Files to add to .gitignore
|
|
167
|
+
const filesToIgnore = [
|
|
168
|
+
this.projectConfigFilename,
|
|
169
|
+
'.claude/settings.local.json'
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
let gitignoreContent = '';
|
|
173
|
+
let needsUpdate = false;
|
|
174
|
+
|
|
175
|
+
// Read existing .gitignore if it exists
|
|
176
|
+
if (fs.existsSync(gitignorePath)) {
|
|
177
|
+
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Split into lines for easier processing
|
|
181
|
+
const lines = gitignoreContent.split('\n');
|
|
182
|
+
const existingEntries = new Set(lines.map(line => line.trim()));
|
|
183
|
+
|
|
184
|
+
// Check which files need to be added
|
|
185
|
+
const entriesToAdd = [];
|
|
186
|
+
for (const file of filesToIgnore) {
|
|
187
|
+
if (!existingEntries.has(file)) {
|
|
188
|
+
entriesToAdd.push(file);
|
|
189
|
+
needsUpdate = true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!needsUpdate) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Add AIS section header if adding new entries
|
|
198
|
+
let newContent = gitignoreContent;
|
|
199
|
+
|
|
200
|
+
// Ensure file ends with newline if it has content
|
|
201
|
+
if (newContent.length > 0 && !newContent.endsWith('\n')) {
|
|
202
|
+
newContent += '\n';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Add section header and entries
|
|
206
|
+
if (entriesToAdd.length > 0) {
|
|
207
|
+
// Add blank line before section if file has content
|
|
208
|
+
if (newContent.length > 0) {
|
|
209
|
+
newContent += '\n';
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
newContent += '# AIS (AI Account Switch) - Local configuration files\n';
|
|
213
|
+
entriesToAdd.forEach(entry => {
|
|
214
|
+
newContent += entry + '\n';
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Write updated .gitignore
|
|
219
|
+
fs.writeFileSync(gitignorePath, newContent, 'utf8');
|
|
148
220
|
return true;
|
|
149
221
|
}
|
|
150
222
|
|
|
@@ -186,11 +258,6 @@ class ConfigManager {
|
|
|
186
258
|
claudeConfig.env.ANTHROPIC_BASE_URL = account.apiUrl;
|
|
187
259
|
}
|
|
188
260
|
|
|
189
|
-
// Add organization ID if specified
|
|
190
|
-
if (account.organizationId) {
|
|
191
|
-
claudeConfig.env.ANTHROPIC_ORGANIZATION_ID = account.organizationId;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
261
|
// Add custom environment variables if specified
|
|
195
262
|
if (account.customEnv && typeof account.customEnv === 'object') {
|
|
196
263
|
Object.keys(account.customEnv).forEach(key => {
|
package/src/index.js
CHANGED
|
@@ -11,7 +11,8 @@ const {
|
|
|
11
11
|
showCurrent,
|
|
12
12
|
showPaths,
|
|
13
13
|
exportAccount,
|
|
14
|
-
doctor
|
|
14
|
+
doctor,
|
|
15
|
+
startUI
|
|
15
16
|
} = require('./commands');
|
|
16
17
|
|
|
17
18
|
// Package info
|
|
@@ -78,6 +79,12 @@ program
|
|
|
78
79
|
.description('Diagnose Claude Code configuration issues')
|
|
79
80
|
.action(doctor);
|
|
80
81
|
|
|
82
|
+
// Web UI command
|
|
83
|
+
program
|
|
84
|
+
.command('ui')
|
|
85
|
+
.description('Start web-based account manager UI')
|
|
86
|
+
.action(startUI);
|
|
87
|
+
|
|
81
88
|
// Help command
|
|
82
89
|
program
|
|
83
90
|
.command('help')
|
|
@@ -97,6 +104,7 @@ program
|
|
|
97
104
|
console.log(' paths Show configuration file paths');
|
|
98
105
|
console.log(' doctor Diagnose Claude Code configuration issues');
|
|
99
106
|
console.log(' export <name> Export account as JSON');
|
|
107
|
+
console.log(' ui Start web-based account manager UI');
|
|
100
108
|
console.log(' help Display this help message');
|
|
101
109
|
console.log(' version Show version number\n');
|
|
102
110
|
|
|
@@ -115,6 +123,8 @@ program
|
|
|
115
123
|
console.log(' ais doctor\n');
|
|
116
124
|
console.log(chalk.gray(' # Remove an account'));
|
|
117
125
|
console.log(' ais remove my-old-account\n');
|
|
126
|
+
console.log(chalk.gray(' # Start web UI for managing accounts'));
|
|
127
|
+
console.log(' ais ui\n');
|
|
118
128
|
|
|
119
129
|
console.log(chalk.bold('FEATURES:'));
|
|
120
130
|
console.log(' • Custom environment variables support');
|