ai-account-switch 1.9.0 → 1.12.0
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/.playwright-mcp/grid-view-before.png +0 -0
- package/.playwright-mcp/list-view.png +0 -0
- package/CLAUDE.md +338 -0
- package/README.md +3 -1
- package/package.json +45 -45
- package/src/accounts/base-account.js +39 -0
- package/src/accounts/ccr-account.js +118 -0
- package/src/accounts/claude-account.js +62 -0
- package/src/accounts/codex-account.js +192 -0
- package/src/accounts/droids-account.js +80 -0
- package/src/accounts/index.js +29 -0
- package/src/commands/account.js +68 -0
- package/src/commands/env.js +728 -0
- package/src/commands/helpers.js +32 -0
- package/src/commands/index.js +22 -1
- package/src/commands/mcp.js +71 -13
- package/src/config/global-config.js +266 -0
- package/src/config/project-config.js +255 -0
- package/src/config.js +129 -1300
- package/src/config.js.bak +1593 -0
- package/src/constants.js +86 -0
- package/src/generators/base-generator.js +124 -0
- package/src/generators/ccr-generator.js +113 -0
- package/src/generators/claude-generator.js +124 -0
- package/src/generators/codex-generator.js +207 -0
- package/src/generators/droids-generator.js +49 -0
- package/src/generators/index.js +29 -0
- package/src/index.js +63 -1
- package/src/mcp/mcp-manager.js +309 -0
- package/src/ui-server.js +1093 -9
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Configuration Manager
|
|
3
|
+
* Handles project-specific configuration operations
|
|
4
|
+
*/
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
class ProjectConfigManager {
|
|
9
|
+
constructor(globalConfig) {
|
|
10
|
+
this.globalConfig = globalConfig;
|
|
11
|
+
this.projectConfigFilename = '.ais-project-config';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get project configuration file path
|
|
16
|
+
*/
|
|
17
|
+
getProjectConfigPath(projectRoot = process.cwd()) {
|
|
18
|
+
return path.join(projectRoot, this.projectConfigFilename);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Read project configuration
|
|
23
|
+
*/
|
|
24
|
+
read(projectRoot = process.cwd()) {
|
|
25
|
+
const projectConfigFile = this.getProjectConfigPath(projectRoot);
|
|
26
|
+
if (!fs.existsSync(projectConfigFile)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const data = fs.readFileSync(projectConfigFile, 'utf8');
|
|
32
|
+
return JSON.parse(data);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Save project configuration
|
|
40
|
+
*/
|
|
41
|
+
save(projectConfig, projectRoot = process.cwd()) {
|
|
42
|
+
const projectConfigFile = this.getProjectConfigPath(projectRoot);
|
|
43
|
+
fs.writeFileSync(projectConfigFile, JSON.stringify(projectConfig, null, 2), 'utf8');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Set current project's active account
|
|
48
|
+
*/
|
|
49
|
+
setAccount(accountName, projectRoot = process.cwd()) {
|
|
50
|
+
const projectConfigFile = this.getProjectConfigPath(projectRoot);
|
|
51
|
+
|
|
52
|
+
// Read existing project config to preserve enabledMcpServers
|
|
53
|
+
let existingConfig = {};
|
|
54
|
+
if (fs.existsSync(projectConfigFile)) {
|
|
55
|
+
try {
|
|
56
|
+
const data = fs.readFileSync(projectConfigFile, 'utf8');
|
|
57
|
+
existingConfig = JSON.parse(data);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
// If parsing fails, start fresh
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const projectConfig = {
|
|
64
|
+
activeAccount: accountName,
|
|
65
|
+
projectPath: projectRoot,
|
|
66
|
+
setAt: new Date().toISOString(),
|
|
67
|
+
enabledMcpServers: existingConfig.enabledMcpServers || []
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
this.save(projectConfig, projectRoot);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get current project's active account with full details
|
|
76
|
+
*/
|
|
77
|
+
getAccount(projectRoot = process.cwd()) {
|
|
78
|
+
try {
|
|
79
|
+
const projectConfig = this.read(projectRoot);
|
|
80
|
+
if (!projectConfig) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Get the full account details from global config
|
|
85
|
+
const account = this.globalConfig.getAccount(projectConfig.activeAccount);
|
|
86
|
+
if (account) {
|
|
87
|
+
return {
|
|
88
|
+
name: projectConfig.activeAccount,
|
|
89
|
+
...account,
|
|
90
|
+
setAt: projectConfig.setAt,
|
|
91
|
+
projectRoot: projectRoot
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// MCP Server methods for project
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get project's enabled MCP servers
|
|
104
|
+
*/
|
|
105
|
+
getMcpServers(projectRoot = process.cwd()) {
|
|
106
|
+
try {
|
|
107
|
+
const projectConfig = this.read(projectRoot);
|
|
108
|
+
if (!projectConfig) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
return projectConfig.enabledMcpServers || [];
|
|
112
|
+
} catch (error) {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Check if MCP server is enabled in current project
|
|
119
|
+
*/
|
|
120
|
+
isMcpServerEnabled(serverName, projectRoot = process.cwd()) {
|
|
121
|
+
try {
|
|
122
|
+
const projectConfig = this.read(projectRoot);
|
|
123
|
+
if (!projectConfig) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return projectConfig.enabledMcpServers &&
|
|
128
|
+
projectConfig.enabledMcpServers.includes(serverName);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Enable MCP server for current project with scope
|
|
136
|
+
*/
|
|
137
|
+
enableMcpServer(serverName, scope, projectRoot = process.cwd()) {
|
|
138
|
+
const projectConfigFile = this.getProjectConfigPath(projectRoot);
|
|
139
|
+
if (!fs.existsSync(projectConfigFile)) {
|
|
140
|
+
throw new Error('Project not configured. Run "ais use" first.');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const data = fs.readFileSync(projectConfigFile, 'utf8');
|
|
144
|
+
const projectConfig = JSON.parse(data);
|
|
145
|
+
|
|
146
|
+
// Update server scope in global config
|
|
147
|
+
const globalConfig = this.globalConfig.read();
|
|
148
|
+
if (globalConfig.mcpServers[serverName]) {
|
|
149
|
+
globalConfig.mcpServers[serverName].scope = scope;
|
|
150
|
+
this.globalConfig.save(globalConfig);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Handle different scopes
|
|
154
|
+
const { MCP_SCOPES } = require('../constants');
|
|
155
|
+
if (scope === MCP_SCOPES.LOCAL) {
|
|
156
|
+
if (!projectConfig.enabledMcpServers) projectConfig.enabledMcpServers = [];
|
|
157
|
+
if (!projectConfig.enabledMcpServers.includes(serverName)) {
|
|
158
|
+
projectConfig.enabledMcpServers.push(serverName);
|
|
159
|
+
}
|
|
160
|
+
} else if (scope === MCP_SCOPES.PROJECT) {
|
|
161
|
+
if (!projectConfig.projectMcpServers) projectConfig.projectMcpServers = {};
|
|
162
|
+
const server = this.globalConfig.getMcpServer(serverName);
|
|
163
|
+
projectConfig.projectMcpServers[serverName] = {
|
|
164
|
+
...server,
|
|
165
|
+
scope: MCP_SCOPES.PROJECT
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
if (!projectConfig.enabledMcpServers) projectConfig.enabledMcpServers = [];
|
|
169
|
+
if (!projectConfig.enabledMcpServers.includes(serverName)) {
|
|
170
|
+
projectConfig.enabledMcpServers.push(serverName);
|
|
171
|
+
}
|
|
172
|
+
} else if (scope === MCP_SCOPES.USER) {
|
|
173
|
+
if (!projectConfig.enabledMcpServers) projectConfig.enabledMcpServers = [];
|
|
174
|
+
if (!projectConfig.enabledMcpServers.includes(serverName)) {
|
|
175
|
+
projectConfig.enabledMcpServers.push(serverName);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
this.save(projectConfig, projectRoot);
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Disable MCP server for current project
|
|
185
|
+
*/
|
|
186
|
+
disableMcpServer(serverName, projectRoot = process.cwd()) {
|
|
187
|
+
const projectConfig = this.read(projectRoot);
|
|
188
|
+
if (!projectConfig) {
|
|
189
|
+
throw new Error('Project not configured. Run "ais use" first.');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!projectConfig.enabledMcpServers) return false;
|
|
193
|
+
|
|
194
|
+
const index = projectConfig.enabledMcpServers.indexOf(serverName);
|
|
195
|
+
if (index > -1) {
|
|
196
|
+
projectConfig.enabledMcpServers.splice(index, 1);
|
|
197
|
+
this.save(projectConfig, projectRoot);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Remove MCP server from current project's enabled list
|
|
205
|
+
*/
|
|
206
|
+
removeMcpServer(serverName, projectRoot = process.cwd()) {
|
|
207
|
+
try {
|
|
208
|
+
const projectConfig = this.read(projectRoot);
|
|
209
|
+
if (!projectConfig) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (!projectConfig.enabledMcpServers) return false;
|
|
214
|
+
|
|
215
|
+
const index = projectConfig.enabledMcpServers.indexOf(serverName);
|
|
216
|
+
if (index > -1) {
|
|
217
|
+
projectConfig.enabledMcpServers.splice(index, 1);
|
|
218
|
+
this.save(projectConfig, projectRoot);
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
} catch (error) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Get all available MCP servers including project-scoped ones
|
|
229
|
+
*/
|
|
230
|
+
getAllMcpServers(projectRoot = process.cwd()) {
|
|
231
|
+
const globalServers = this.globalConfig.getAllMcpServers();
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
const projectConfig = this.read(projectRoot);
|
|
235
|
+
if (!projectConfig) {
|
|
236
|
+
return globalServers;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Merge global and project servers
|
|
240
|
+
const allServers = { ...globalServers };
|
|
241
|
+
|
|
242
|
+
if (projectConfig.projectMcpServers) {
|
|
243
|
+
Object.entries(projectConfig.projectMcpServers).forEach(([name, server]) => {
|
|
244
|
+
allServers[name] = server;
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return allServers;
|
|
249
|
+
} catch (error) {
|
|
250
|
+
return globalServers;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
module.exports = ProjectConfigManager;
|