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 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
- - 始终将 `.ais-project-config` 添加到 `.gitignore`
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-account-switch",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "A cross-platform CLI tool to manage and switch Claude/Codex account configurations",
5
5
  "main": "src/index.js",
6
6
  "bin": {
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');