@kaitranntt/ccs 4.4.0 → 5.0.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.md +98 -7
- package/VERSION +1 -1
- package/config/base-agy.settings.json +10 -0
- package/config/base-codex.settings.json +10 -0
- package/config/base-gemini.settings.json +10 -0
- package/dist/auth/auth-commands.d.ts +52 -0
- package/dist/auth/auth-commands.d.ts.map +1 -0
- package/dist/auth/auth-commands.js +479 -0
- package/dist/auth/auth-commands.js.map +1 -0
- package/dist/auth/profile-detector.d.ts +68 -0
- package/dist/auth/profile-detector.d.ts.map +1 -0
- package/dist/auth/profile-detector.js +209 -0
- package/dist/auth/profile-detector.js.map +1 -0
- package/dist/auth/profile-registry.d.ts +60 -0
- package/dist/auth/profile-registry.d.ts.map +1 -0
- package/dist/auth/profile-registry.js +188 -0
- package/dist/auth/profile-registry.js.map +1 -0
- package/dist/ccs.d.ts +10 -0
- package/dist/ccs.d.ts.map +1 -0
- package/dist/ccs.js +320 -0
- package/dist/ccs.js.map +1 -0
- package/dist/cliproxy/auth-handler.d.ts +95 -0
- package/dist/cliproxy/auth-handler.d.ts.map +1 -0
- package/dist/cliproxy/auth-handler.js +443 -0
- package/dist/cliproxy/auth-handler.js.map +1 -0
- package/dist/cliproxy/base-config-loader.d.ts +42 -0
- package/dist/cliproxy/base-config-loader.d.ts.map +1 -0
- package/dist/cliproxy/base-config-loader.js +123 -0
- package/dist/cliproxy/base-config-loader.js.map +1 -0
- package/dist/cliproxy/binary-manager.d.ts +104 -0
- package/dist/cliproxy/binary-manager.d.ts.map +1 -0
- package/dist/cliproxy/binary-manager.js +567 -0
- package/dist/cliproxy/binary-manager.js.map +1 -0
- package/dist/cliproxy/cliproxy-executor.d.ts +33 -0
- package/dist/cliproxy/cliproxy-executor.d.ts.map +1 -0
- package/dist/cliproxy/cliproxy-executor.js +297 -0
- package/dist/cliproxy/cliproxy-executor.js.map +1 -0
- package/dist/cliproxy/config-generator.d.ts +89 -0
- package/dist/cliproxy/config-generator.d.ts.map +1 -0
- package/dist/cliproxy/config-generator.js +263 -0
- package/dist/cliproxy/config-generator.js.map +1 -0
- package/dist/cliproxy/index.d.ts +13 -0
- package/dist/cliproxy/index.d.ts.map +1 -0
- package/dist/cliproxy/index.js +62 -0
- package/dist/cliproxy/index.js.map +1 -0
- package/dist/cliproxy/platform-detector.d.ts +48 -0
- package/dist/cliproxy/platform-detector.d.ts.map +1 -0
- package/dist/cliproxy/platform-detector.js +118 -0
- package/dist/cliproxy/platform-detector.js.map +1 -0
- package/dist/cliproxy/types.d.ts +169 -0
- package/dist/cliproxy/types.d.ts.map +1 -0
- package/dist/cliproxy/types.js +7 -0
- package/dist/cliproxy/types.js.map +1 -0
- package/dist/commands/doctor-command.d.ts +10 -0
- package/dist/commands/doctor-command.d.ts.map +1 -0
- package/dist/commands/doctor-command.js +44 -0
- package/dist/commands/doctor-command.js.map +1 -0
- package/dist/commands/help-command.d.ts +5 -0
- package/dist/commands/help-command.d.ts.map +1 -0
- package/dist/commands/help-command.js +104 -0
- package/dist/commands/help-command.js.map +1 -0
- package/dist/commands/install-command.d.ts +14 -0
- package/dist/commands/install-command.d.ts.map +1 -0
- package/dist/commands/install-command.js +39 -0
- package/dist/commands/install-command.js.map +1 -0
- package/dist/commands/shell-completion-command.d.ts +10 -0
- package/dist/commands/shell-completion-command.d.ts.map +1 -0
- package/dist/commands/shell-completion-command.js +85 -0
- package/dist/commands/shell-completion-command.js.map +1 -0
- package/dist/commands/sync-command.d.ts +10 -0
- package/dist/commands/sync-command.d.ts.map +1 -0
- package/dist/commands/sync-command.js +59 -0
- package/dist/commands/sync-command.js.map +1 -0
- package/dist/commands/update-command.d.ts +12 -0
- package/dist/commands/update-command.d.ts.map +1 -0
- package/dist/commands/update-command.js +295 -0
- package/dist/commands/update-command.js.map +1 -0
- package/dist/commands/version-command.d.ts +10 -0
- package/dist/commands/version-command.d.ts.map +1 -0
- package/dist/commands/version-command.js +100 -0
- package/dist/commands/version-command.js.map +1 -0
- package/dist/delegation/delegation-handler.d.ts +60 -0
- package/dist/delegation/delegation-handler.d.ts.map +1 -0
- package/dist/delegation/delegation-handler.js +174 -0
- package/dist/delegation/delegation-handler.js.map +1 -0
- package/dist/delegation/headless-executor.d.ts +114 -0
- package/dist/delegation/headless-executor.d.ts.map +1 -0
- package/dist/delegation/headless-executor.js +562 -0
- package/dist/delegation/headless-executor.js.map +1 -0
- package/dist/delegation/result-formatter.d.ts +108 -0
- package/dist/delegation/result-formatter.d.ts.map +1 -0
- package/dist/delegation/result-formatter.js +391 -0
- package/dist/delegation/result-formatter.js.map +1 -0
- package/dist/delegation/session-manager.d.ts +58 -0
- package/dist/delegation/session-manager.d.ts.map +1 -0
- package/dist/delegation/session-manager.js +153 -0
- package/dist/delegation/session-manager.js.map +1 -0
- package/dist/delegation/settings-parser.d.ts +31 -0
- package/dist/delegation/settings-parser.d.ts.map +1 -0
- package/dist/delegation/settings-parser.js +107 -0
- package/dist/delegation/settings-parser.js.map +1 -0
- package/dist/glmt/delta-accumulator.d.ts +210 -0
- package/dist/glmt/delta-accumulator.d.ts.map +1 -0
- package/dist/glmt/delta-accumulator.js +351 -0
- package/dist/glmt/delta-accumulator.js.map +1 -0
- package/dist/glmt/glmt-proxy.d.ts +72 -0
- package/dist/glmt/glmt-proxy.d.ts.map +1 -0
- package/dist/glmt/glmt-proxy.js +427 -0
- package/dist/glmt/glmt-proxy.js.map +1 -0
- package/dist/glmt/glmt-transformer.d.ts +265 -0
- package/dist/glmt/glmt-transformer.d.ts.map +1 -0
- package/dist/glmt/glmt-transformer.js +832 -0
- package/dist/glmt/glmt-transformer.js.map +1 -0
- package/dist/glmt/locale-enforcer.d.ts +38 -0
- package/dist/glmt/locale-enforcer.d.ts.map +1 -0
- package/dist/glmt/locale-enforcer.js +69 -0
- package/dist/glmt/locale-enforcer.js.map +1 -0
- package/dist/glmt/reasoning-enforcer.d.ts +52 -0
- package/dist/glmt/reasoning-enforcer.d.ts.map +1 -0
- package/dist/glmt/reasoning-enforcer.js +151 -0
- package/dist/glmt/reasoning-enforcer.js.map +1 -0
- package/dist/glmt/sse-parser.d.ts +47 -0
- package/dist/glmt/sse-parser.d.ts.map +1 -0
- package/dist/glmt/sse-parser.js +93 -0
- package/dist/glmt/sse-parser.js.map +1 -0
- package/dist/management/doctor.d.ts +104 -0
- package/dist/management/doctor.d.ts.map +1 -0
- package/dist/management/doctor.js +673 -0
- package/dist/management/doctor.js.map +1 -0
- package/dist/management/instance-manager.d.ts +57 -0
- package/dist/management/instance-manager.d.ts.map +1 -0
- package/dist/management/instance-manager.js +195 -0
- package/dist/management/instance-manager.js.map +1 -0
- package/dist/management/recovery-manager.d.ts +39 -0
- package/dist/management/recovery-manager.d.ts.map +1 -0
- package/dist/management/recovery-manager.js +141 -0
- package/dist/management/recovery-manager.js.map +1 -0
- package/dist/management/shared-manager.d.ts +47 -0
- package/dist/management/shared-manager.d.ts.map +1 -0
- package/dist/management/shared-manager.js +388 -0
- package/dist/management/shared-manager.js.map +1 -0
- package/dist/types/cli.d.ts +50 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +16 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/config.d.ts +51 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +26 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/delegation.d.ts +61 -0
- package/dist/types/delegation.d.ts.map +1 -0
- package/dist/types/delegation.js +6 -0
- package/dist/types/delegation.js.map +1 -0
- package/dist/types/glmt.d.ts +95 -0
- package/dist/types/glmt.d.ts.map +1 -0
- package/dist/types/glmt.js +7 -0
- package/dist/types/glmt.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +16 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/utils.d.ts +36 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +22 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/utils/claude-detector.d.ts +14 -0
- package/dist/utils/claude-detector.d.ts.map +1 -0
- package/dist/utils/claude-detector.js +112 -0
- package/dist/utils/claude-detector.js.map +1 -0
- package/dist/utils/claude-dir-installer.d.ts +46 -0
- package/dist/utils/claude-dir-installer.d.ts.map +1 -0
- package/dist/utils/claude-dir-installer.js +289 -0
- package/dist/utils/claude-dir-installer.js.map +1 -0
- package/dist/utils/claude-symlink-manager.d.ts +61 -0
- package/dist/utils/claude-symlink-manager.d.ts.map +1 -0
- package/dist/utils/claude-symlink-manager.js +291 -0
- package/dist/utils/claude-symlink-manager.js.map +1 -0
- package/dist/utils/config-manager.d.ts +32 -0
- package/dist/utils/config-manager.d.ts.map +1 -0
- package/dist/utils/config-manager.js +143 -0
- package/dist/utils/config-manager.js.map +1 -0
- package/dist/utils/delegation-validator.d.ts +39 -0
- package/dist/utils/delegation-validator.d.ts.map +1 -0
- package/dist/utils/delegation-validator.js +161 -0
- package/dist/utils/delegation-validator.js.map +1 -0
- package/dist/utils/error-codes.d.ts +36 -0
- package/dist/utils/error-codes.d.ts.map +1 -0
- package/dist/utils/error-codes.js +63 -0
- package/dist/utils/error-codes.js.map +1 -0
- package/dist/utils/error-manager.d.ts +59 -0
- package/dist/utils/error-manager.d.ts.map +1 -0
- package/dist/utils/error-manager.js +228 -0
- package/dist/utils/error-manager.js.map +1 -0
- package/dist/utils/helpers.d.ts +27 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +150 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/package-manager-detector.d.ts +14 -0
- package/dist/utils/package-manager-detector.d.ts.map +1 -0
- package/dist/utils/package-manager-detector.js +162 -0
- package/dist/utils/package-manager-detector.js.map +1 -0
- package/dist/utils/progress-indicator.d.ts +52 -0
- package/dist/utils/progress-indicator.d.ts.map +1 -0
- package/dist/utils/progress-indicator.js +102 -0
- package/dist/utils/progress-indicator.js.map +1 -0
- package/dist/utils/prompt.d.ts +29 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +116 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/shell-completion.d.ts +52 -0
- package/dist/utils/shell-completion.d.ts.map +1 -0
- package/dist/utils/shell-completion.js +231 -0
- package/dist/utils/shell-completion.js.map +1 -0
- package/dist/utils/shell-executor.d.ts +15 -0
- package/dist/utils/shell-executor.d.ts.map +1 -0
- package/dist/utils/shell-executor.js +57 -0
- package/dist/utils/shell-executor.js.map +1 -0
- package/dist/utils/update-checker.d.ts +48 -0
- package/dist/utils/update-checker.d.ts.map +1 -0
- package/dist/utils/update-checker.js +241 -0
- package/dist/utils/update-checker.js.map +1 -0
- package/lib/ccs +21 -1907
- package/lib/ccs.ps1 +26 -1800
- package/lib/error-codes.ps1 +2 -1
- package/lib/prompt.ps1 +2 -2
- package/package.json +31 -11
- package/scripts/add-shebang.js +39 -0
- package/scripts/bump-version.sh +25 -37
- package/scripts/dev-install.sh +32 -11
- package/scripts/postinstall.js +29 -29
- package/bin/auth/auth-commands.js +0 -499
- package/bin/auth/profile-detector.js +0 -204
- package/bin/auth/profile-registry.js +0 -225
- package/bin/ccs.js +0 -1034
- package/bin/delegation/README.md +0 -191
- package/bin/delegation/delegation-handler.js +0 -212
- package/bin/delegation/headless-executor.js +0 -618
- package/bin/delegation/result-formatter.js +0 -485
- package/bin/delegation/session-manager.js +0 -157
- package/bin/delegation/settings-parser.js +0 -109
- package/bin/glmt/delta-accumulator.js +0 -276
- package/bin/glmt/glmt-proxy.js +0 -495
- package/bin/glmt/glmt-transformer.js +0 -999
- package/bin/glmt/locale-enforcer.js +0 -72
- package/bin/glmt/reasoning-enforcer.js +0 -173
- package/bin/glmt/sse-parser.js +0 -96
- package/bin/management/doctor.js +0 -721
- package/bin/management/instance-manager.js +0 -202
- package/bin/management/recovery-manager.js +0 -135
- package/bin/management/shared-manager.js +0 -402
- package/bin/utils/claude-detector.js +0 -73
- package/bin/utils/claude-dir-installer.js +0 -283
- package/bin/utils/claude-symlink-manager.js +0 -289
- package/bin/utils/config-manager.js +0 -103
- package/bin/utils/delegation-validator.js +0 -154
- package/bin/utils/error-codes.js +0 -59
- package/bin/utils/error-manager.js +0 -165
- package/bin/utils/helpers.js +0 -136
- package/bin/utils/progress-indicator.js +0 -111
- package/bin/utils/prompt.js +0 -134
- package/bin/utils/shell-completion.js +0 -256
- package/bin/utils/update-checker.js +0 -243
|
@@ -1,499 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { spawn } = require('child_process');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const ProfileRegistry = require('./profile-registry');
|
|
7
|
-
const InstanceManager = require('../management/instance-manager');
|
|
8
|
-
const { colored } = require('../utils/helpers');
|
|
9
|
-
const { detectClaudeCli } = require('../utils/claude-detector');
|
|
10
|
-
const { InteractivePrompt } = require('../utils/prompt');
|
|
11
|
-
const CCS_VERSION = require('../../package.json').version;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Auth Commands (Simplified)
|
|
15
|
-
*
|
|
16
|
-
* CLI interface for CCS multi-account management.
|
|
17
|
-
* Commands: create, list, show, remove, default
|
|
18
|
-
*
|
|
19
|
-
* Login-per-profile model: Each profile is an isolated Claude instance.
|
|
20
|
-
* Users login directly in each instance (no credential copying).
|
|
21
|
-
*/
|
|
22
|
-
class AuthCommands {
|
|
23
|
-
constructor() {
|
|
24
|
-
this.registry = new ProfileRegistry();
|
|
25
|
-
this.instanceMgr = new InstanceManager();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Show help for auth commands
|
|
30
|
-
*/
|
|
31
|
-
showHelp() {
|
|
32
|
-
console.log(colored('CCS Concurrent Account Management', 'bold'));
|
|
33
|
-
console.log('');
|
|
34
|
-
console.log(colored('Usage:', 'cyan'));
|
|
35
|
-
console.log(` ${colored('ccs auth', 'yellow')} <command> [options]`);
|
|
36
|
-
console.log('');
|
|
37
|
-
console.log(colored('Commands:', 'cyan'));
|
|
38
|
-
console.log(` ${colored('create <profile>', 'yellow')} Create new profile and login`);
|
|
39
|
-
console.log(` ${colored('list', 'yellow')} List all saved profiles`);
|
|
40
|
-
console.log(` ${colored('show <profile>', 'yellow')} Show profile details`);
|
|
41
|
-
console.log(` ${colored('remove <profile>', 'yellow')} Remove saved profile`);
|
|
42
|
-
console.log(` ${colored('default <profile>', 'yellow')} Set default profile`);
|
|
43
|
-
console.log('');
|
|
44
|
-
console.log(colored('Examples:', 'cyan'));
|
|
45
|
-
console.log(` ${colored('ccs auth create work', 'yellow')} # Create & login to work profile`);
|
|
46
|
-
console.log(` ${colored('ccs auth default work', 'yellow')} # Set work as default`);
|
|
47
|
-
console.log(` ${colored('ccs auth list', 'yellow')} # List all profiles`);
|
|
48
|
-
console.log(` ${colored('ccs work "review code"', 'yellow')} # Use work profile`);
|
|
49
|
-
console.log(` ${colored('ccs "review code"', 'yellow')} # Use default profile`);
|
|
50
|
-
console.log('');
|
|
51
|
-
console.log(colored('Options:', 'cyan'));
|
|
52
|
-
console.log(` ${colored('--force', 'yellow')} Allow overwriting existing profile (create)`);
|
|
53
|
-
console.log(` ${colored('--yes, -y', 'yellow')} Skip confirmation prompts (remove)`);
|
|
54
|
-
console.log(` ${colored('--json', 'yellow')} Output in JSON format (list, show)`);
|
|
55
|
-
console.log(` ${colored('--verbose', 'yellow')} Show additional details (list)`);
|
|
56
|
-
console.log('');
|
|
57
|
-
console.log(colored('Note:', 'cyan'));
|
|
58
|
-
console.log(` By default, ${colored('ccs', 'yellow')} uses Claude CLI defaults from ~/.claude/`);
|
|
59
|
-
console.log(` Use ${colored('ccs auth default <profile>', 'yellow')} to change the default profile.`);
|
|
60
|
-
console.log('');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create new profile and prompt for login
|
|
65
|
-
* @param {Array} args - Command arguments
|
|
66
|
-
*/
|
|
67
|
-
async handleCreate(args) {
|
|
68
|
-
const profileName = args.find(arg => !arg.startsWith('--'));
|
|
69
|
-
const force = args.includes('--force');
|
|
70
|
-
|
|
71
|
-
if (!profileName) {
|
|
72
|
-
console.error('[X] Profile name is required');
|
|
73
|
-
console.log('');
|
|
74
|
-
console.log(`Usage: ${colored('ccs auth create <profile> [--force]', 'yellow')}`);
|
|
75
|
-
console.log('');
|
|
76
|
-
console.log('Example:');
|
|
77
|
-
console.log(` ${colored('ccs auth create work', 'yellow')}`);
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Check if profile already exists
|
|
82
|
-
if (!force && this.registry.hasProfile(profileName)) {
|
|
83
|
-
console.error(`[X] Profile already exists: ${profileName}`);
|
|
84
|
-
console.log(` Use ${colored('--force', 'yellow')} to overwrite`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
// Create instance directory
|
|
90
|
-
console.log(`[i] Creating profile: ${profileName}`);
|
|
91
|
-
const instancePath = this.instanceMgr.ensureInstance(profileName);
|
|
92
|
-
|
|
93
|
-
// Create/update profile entry
|
|
94
|
-
if (this.registry.hasProfile(profileName)) {
|
|
95
|
-
this.registry.updateProfile(profileName, {
|
|
96
|
-
type: 'account'
|
|
97
|
-
});
|
|
98
|
-
} else {
|
|
99
|
-
this.registry.createProfile(profileName, {
|
|
100
|
-
type: 'account'
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
console.log(`[i] Instance directory: ${instancePath}`);
|
|
105
|
-
console.log('');
|
|
106
|
-
console.log(colored('[i] Starting Claude in isolated instance...', 'yellow'));
|
|
107
|
-
console.log(colored('[i] You will be prompted to login with your account.', 'yellow'));
|
|
108
|
-
console.log('');
|
|
109
|
-
|
|
110
|
-
// Detect Claude CLI
|
|
111
|
-
const claudeCli = detectClaudeCli();
|
|
112
|
-
if (!claudeCli) {
|
|
113
|
-
console.error('[X] Claude CLI not found');
|
|
114
|
-
console.log('');
|
|
115
|
-
console.log('Please install Claude CLI first:');
|
|
116
|
-
console.log(' https://claude.ai/download');
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Execute Claude in isolated instance (will auto-prompt for login if no credentials)
|
|
121
|
-
const child = spawn(claudeCli, [], {
|
|
122
|
-
stdio: 'inherit',
|
|
123
|
-
env: { ...process.env, CLAUDE_CONFIG_DIR: instancePath }
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
child.on('exit', (code) => {
|
|
127
|
-
if (code === 0) {
|
|
128
|
-
console.log('');
|
|
129
|
-
console.log(colored('[OK] Profile created successfully', 'green'));
|
|
130
|
-
console.log('');
|
|
131
|
-
console.log(` Profile: ${profileName}`);
|
|
132
|
-
console.log(` Instance: ${instancePath}`);
|
|
133
|
-
console.log('');
|
|
134
|
-
console.log('Usage:');
|
|
135
|
-
console.log(` ${colored(`ccs ${profileName} "your prompt here"`, 'yellow')} # Use this specific profile`);
|
|
136
|
-
console.log('');
|
|
137
|
-
console.log('To set as default (so you can use just "ccs"):');
|
|
138
|
-
console.log(` ${colored(`ccs auth default ${profileName}`, 'yellow')}`);
|
|
139
|
-
console.log('');
|
|
140
|
-
process.exit(0);
|
|
141
|
-
} else {
|
|
142
|
-
console.log('');
|
|
143
|
-
console.error('[X] Login failed or cancelled');
|
|
144
|
-
console.log('');
|
|
145
|
-
console.log('To retry:');
|
|
146
|
-
console.log(` ${colored(`ccs auth create ${profileName} --force`, 'yellow')}`);
|
|
147
|
-
console.log('');
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
child.on('error', (err) => {
|
|
153
|
-
console.error(`[X] Failed to execute Claude CLI: ${err.message}`);
|
|
154
|
-
process.exit(1);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
} catch (error) {
|
|
158
|
-
console.error(`[X] Failed to create profile: ${error.message}`);
|
|
159
|
-
process.exit(1);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* List all saved profiles
|
|
165
|
-
* @param {Array} args - Command arguments
|
|
166
|
-
*/
|
|
167
|
-
async handleList(args) {
|
|
168
|
-
const verbose = args.includes('--verbose');
|
|
169
|
-
const json = args.includes('--json');
|
|
170
|
-
|
|
171
|
-
try {
|
|
172
|
-
const profiles = this.registry.getAllProfiles();
|
|
173
|
-
const defaultProfile = this.registry.getDefaultProfile();
|
|
174
|
-
const profileNames = Object.keys(profiles);
|
|
175
|
-
|
|
176
|
-
// JSON output mode
|
|
177
|
-
if (json) {
|
|
178
|
-
const output = {
|
|
179
|
-
version: CCS_VERSION,
|
|
180
|
-
profiles: profileNames.map(name => {
|
|
181
|
-
const profile = profiles[name];
|
|
182
|
-
const isDefault = name === defaultProfile;
|
|
183
|
-
const instancePath = this.instanceMgr.getInstancePath(name);
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
name: name,
|
|
187
|
-
type: profile.type || 'account',
|
|
188
|
-
is_default: isDefault,
|
|
189
|
-
created: profile.created,
|
|
190
|
-
last_used: profile.last_used || null,
|
|
191
|
-
instance_path: instancePath
|
|
192
|
-
};
|
|
193
|
-
})
|
|
194
|
-
};
|
|
195
|
-
console.log(JSON.stringify(output, null, 2));
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Human-readable output
|
|
200
|
-
if (profileNames.length === 0) {
|
|
201
|
-
console.log(colored('No account profiles found', 'yellow'));
|
|
202
|
-
console.log('');
|
|
203
|
-
console.log('To create your first profile:');
|
|
204
|
-
console.log(` ${colored('ccs auth create <profile>', 'yellow')} # Create and login to profile`);
|
|
205
|
-
console.log('');
|
|
206
|
-
console.log('Example:');
|
|
207
|
-
console.log(` ${colored('ccs auth create work', 'yellow')}`);
|
|
208
|
-
console.log('');
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
console.log(colored('Saved Account Profiles:', 'bold'));
|
|
213
|
-
console.log('');
|
|
214
|
-
|
|
215
|
-
// Sort by last_used (descending), then alphabetically
|
|
216
|
-
const sorted = profileNames.sort((a, b) => {
|
|
217
|
-
const aProfile = profiles[a];
|
|
218
|
-
const bProfile = profiles[b];
|
|
219
|
-
|
|
220
|
-
// Default first
|
|
221
|
-
if (a === defaultProfile) return -1;
|
|
222
|
-
if (b === defaultProfile) return 1;
|
|
223
|
-
|
|
224
|
-
// Then by last_used
|
|
225
|
-
if (aProfile.last_used && bProfile.last_used) {
|
|
226
|
-
return new Date(bProfile.last_used) - new Date(aProfile.last_used);
|
|
227
|
-
}
|
|
228
|
-
if (aProfile.last_used) return -1;
|
|
229
|
-
if (bProfile.last_used) return 1;
|
|
230
|
-
|
|
231
|
-
// Then alphabetically
|
|
232
|
-
return a.localeCompare(b);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
sorted.forEach(name => {
|
|
236
|
-
const profile = profiles[name];
|
|
237
|
-
const isDefault = name === defaultProfile;
|
|
238
|
-
const indicator = isDefault ? colored('[*]', 'green') : '[ ]';
|
|
239
|
-
|
|
240
|
-
console.log(`${indicator} ${colored(name, 'cyan')}${isDefault ? colored(' (default)', 'green') : ''}`);
|
|
241
|
-
|
|
242
|
-
console.log(` Type: ${profile.type || 'account'}`);
|
|
243
|
-
|
|
244
|
-
if (verbose) {
|
|
245
|
-
console.log(` Created: ${new Date(profile.created).toLocaleString()}`);
|
|
246
|
-
if (profile.last_used) {
|
|
247
|
-
console.log(` Last used: ${new Date(profile.last_used).toLocaleString()}`);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
console.log('');
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
console.log(`Total profiles: ${profileNames.length}`);
|
|
255
|
-
console.log('');
|
|
256
|
-
|
|
257
|
-
} catch (error) {
|
|
258
|
-
console.error(`[X] Failed to list profiles: ${error.message}`);
|
|
259
|
-
process.exit(1);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Show details for a specific profile
|
|
265
|
-
* @param {Array} args - Command arguments
|
|
266
|
-
*/
|
|
267
|
-
async handleShow(args) {
|
|
268
|
-
const profileName = args.find(arg => !arg.startsWith('--'));
|
|
269
|
-
const json = args.includes('--json');
|
|
270
|
-
|
|
271
|
-
if (!profileName) {
|
|
272
|
-
console.error('[X] Profile name is required');
|
|
273
|
-
console.log('');
|
|
274
|
-
console.log(`Usage: ${colored('ccs auth show <profile> [--json]', 'yellow')}`);
|
|
275
|
-
process.exit(1);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
try {
|
|
279
|
-
const profile = this.registry.getProfile(profileName);
|
|
280
|
-
const defaultProfile = this.registry.getDefaultProfile();
|
|
281
|
-
const isDefault = profileName === defaultProfile;
|
|
282
|
-
const instancePath = this.instanceMgr.getInstancePath(profileName);
|
|
283
|
-
|
|
284
|
-
// Count sessions
|
|
285
|
-
let sessionCount = 0;
|
|
286
|
-
try {
|
|
287
|
-
const sessionsDir = path.join(instancePath, 'session-env');
|
|
288
|
-
if (fs.existsSync(sessionsDir)) {
|
|
289
|
-
const files = fs.readdirSync(sessionsDir);
|
|
290
|
-
sessionCount = files.filter(f => f.endsWith('.json')).length;
|
|
291
|
-
}
|
|
292
|
-
} catch (e) {
|
|
293
|
-
// Ignore errors counting sessions
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// JSON output mode
|
|
297
|
-
if (json) {
|
|
298
|
-
const output = {
|
|
299
|
-
name: profileName,
|
|
300
|
-
type: profile.type || 'account',
|
|
301
|
-
is_default: isDefault,
|
|
302
|
-
created: profile.created,
|
|
303
|
-
last_used: profile.last_used || null,
|
|
304
|
-
instance_path: instancePath,
|
|
305
|
-
session_count: sessionCount
|
|
306
|
-
};
|
|
307
|
-
console.log(JSON.stringify(output, null, 2));
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// Human-readable output
|
|
312
|
-
console.log(colored(`Profile: ${profileName}`, 'bold'));
|
|
313
|
-
console.log('');
|
|
314
|
-
console.log(` Type: ${profile.type || 'account'}`);
|
|
315
|
-
console.log(` Default: ${isDefault ? 'Yes' : 'No'}`);
|
|
316
|
-
console.log(` Instance: ${instancePath}`);
|
|
317
|
-
console.log(` Created: ${new Date(profile.created).toLocaleString()}`);
|
|
318
|
-
|
|
319
|
-
if (profile.last_used) {
|
|
320
|
-
console.log(` Last used: ${new Date(profile.last_used).toLocaleString()}`);
|
|
321
|
-
} else {
|
|
322
|
-
console.log(` Last used: Never`);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
console.log('');
|
|
326
|
-
|
|
327
|
-
} catch (error) {
|
|
328
|
-
console.error(`[X] ${error.message}`);
|
|
329
|
-
process.exit(1);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Remove a saved profile
|
|
335
|
-
* @param {Array} args - Command arguments
|
|
336
|
-
*/
|
|
337
|
-
async handleRemove(args) {
|
|
338
|
-
const profileName = args.find(arg => !arg.startsWith('--') && !arg.startsWith('-'));
|
|
339
|
-
|
|
340
|
-
if (!profileName) {
|
|
341
|
-
console.error('[X] Profile name is required');
|
|
342
|
-
console.log('');
|
|
343
|
-
console.log(`Usage: ${colored('ccs auth remove <profile> [--yes]', 'yellow')}`);
|
|
344
|
-
process.exit(1);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (!this.registry.hasProfile(profileName)) {
|
|
348
|
-
console.error(`[X] Profile not found: ${profileName}`);
|
|
349
|
-
process.exit(1);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
try {
|
|
353
|
-
// Get instance path and session count for impact display
|
|
354
|
-
const instancePath = this.instanceMgr.getInstancePath(profileName);
|
|
355
|
-
let sessionCount = 0;
|
|
356
|
-
|
|
357
|
-
try {
|
|
358
|
-
const sessionsDir = path.join(instancePath, 'session-env');
|
|
359
|
-
if (fs.existsSync(sessionsDir)) {
|
|
360
|
-
const files = fs.readdirSync(sessionsDir);
|
|
361
|
-
sessionCount = files.filter(f => f.endsWith('.json')).length;
|
|
362
|
-
}
|
|
363
|
-
} catch (e) {
|
|
364
|
-
// Ignore errors counting sessions
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Display impact
|
|
368
|
-
console.log('');
|
|
369
|
-
console.log(`Profile '${colored(profileName, 'cyan')}' will be permanently deleted.`);
|
|
370
|
-
console.log(` Instance path: ${instancePath}`);
|
|
371
|
-
console.log(` Sessions: ${sessionCount} conversation${sessionCount !== 1 ? 's' : ''}`);
|
|
372
|
-
console.log('');
|
|
373
|
-
|
|
374
|
-
// Interactive confirmation (or --yes flag)
|
|
375
|
-
const confirmed = await InteractivePrompt.confirm(
|
|
376
|
-
'Delete this profile?',
|
|
377
|
-
{ default: false } // Default to NO (safe)
|
|
378
|
-
);
|
|
379
|
-
|
|
380
|
-
if (!confirmed) {
|
|
381
|
-
console.log('[i] Cancelled');
|
|
382
|
-
process.exit(0);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// Delete instance
|
|
386
|
-
this.instanceMgr.deleteInstance(profileName);
|
|
387
|
-
|
|
388
|
-
// Delete profile
|
|
389
|
-
this.registry.deleteProfile(profileName);
|
|
390
|
-
|
|
391
|
-
console.log(colored('[OK] Profile removed successfully', 'green'));
|
|
392
|
-
console.log(` Profile: ${profileName}`);
|
|
393
|
-
console.log('');
|
|
394
|
-
|
|
395
|
-
} catch (error) {
|
|
396
|
-
console.error(`[X] Failed to remove profile: ${error.message}`);
|
|
397
|
-
process.exit(1);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Set default profile
|
|
403
|
-
* @param {Array} args - Command arguments
|
|
404
|
-
*/
|
|
405
|
-
async handleDefault(args) {
|
|
406
|
-
const profileName = args.find(arg => !arg.startsWith('--'));
|
|
407
|
-
|
|
408
|
-
if (!profileName) {
|
|
409
|
-
console.error('[X] Profile name is required');
|
|
410
|
-
console.log('');
|
|
411
|
-
console.log(`Usage: ${colored('ccs auth default <profile>', 'yellow')}`);
|
|
412
|
-
process.exit(1);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
try {
|
|
416
|
-
this.registry.setDefaultProfile(profileName);
|
|
417
|
-
|
|
418
|
-
console.log(colored('[OK] Default profile set', 'green'));
|
|
419
|
-
console.log(` Profile: ${profileName}`);
|
|
420
|
-
console.log('');
|
|
421
|
-
console.log('Now you can use:');
|
|
422
|
-
console.log(` ${colored('ccs "your prompt"', 'yellow')} # Uses ${profileName} profile`);
|
|
423
|
-
console.log('');
|
|
424
|
-
|
|
425
|
-
} catch (error) {
|
|
426
|
-
console.error(`[X] ${error.message}`);
|
|
427
|
-
process.exit(1);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* Route auth command to appropriate handler
|
|
433
|
-
* @param {Array} args - Command arguments
|
|
434
|
-
*/
|
|
435
|
-
async route(args) {
|
|
436
|
-
if (args.length === 0 || args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
|
|
437
|
-
this.showHelp();
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
const command = args[0];
|
|
442
|
-
const commandArgs = args.slice(1);
|
|
443
|
-
|
|
444
|
-
switch (command) {
|
|
445
|
-
case 'create':
|
|
446
|
-
await this.handleCreate(commandArgs);
|
|
447
|
-
break;
|
|
448
|
-
|
|
449
|
-
case 'save':
|
|
450
|
-
// Deprecated - redirect to create
|
|
451
|
-
console.log(colored('[!] Command "save" is deprecated', 'yellow'));
|
|
452
|
-
console.log(` Use: ${colored('ccs auth create <profile>', 'yellow')} instead`);
|
|
453
|
-
console.log('');
|
|
454
|
-
await this.handleCreate(commandArgs);
|
|
455
|
-
break;
|
|
456
|
-
|
|
457
|
-
case 'list':
|
|
458
|
-
await this.handleList(commandArgs);
|
|
459
|
-
break;
|
|
460
|
-
|
|
461
|
-
case 'show':
|
|
462
|
-
await this.handleShow(commandArgs);
|
|
463
|
-
break;
|
|
464
|
-
|
|
465
|
-
case 'remove':
|
|
466
|
-
await this.handleRemove(commandArgs);
|
|
467
|
-
break;
|
|
468
|
-
|
|
469
|
-
case 'default':
|
|
470
|
-
await this.handleDefault(commandArgs);
|
|
471
|
-
break;
|
|
472
|
-
|
|
473
|
-
case 'current':
|
|
474
|
-
console.log(colored('[!] Command "current" has been removed', 'yellow'));
|
|
475
|
-
console.log('');
|
|
476
|
-
console.log('Each profile has its own login in an isolated instance.');
|
|
477
|
-
console.log('Use "ccs auth list" to see all profiles.');
|
|
478
|
-
console.log('');
|
|
479
|
-
break;
|
|
480
|
-
|
|
481
|
-
case 'cleanup':
|
|
482
|
-
console.log(colored('[!] Command "cleanup" has been removed', 'yellow'));
|
|
483
|
-
console.log('');
|
|
484
|
-
console.log('No cleanup needed - no separate vault files.');
|
|
485
|
-
console.log('Use "ccs auth list" to see all profiles.');
|
|
486
|
-
console.log('');
|
|
487
|
-
break;
|
|
488
|
-
|
|
489
|
-
default:
|
|
490
|
-
console.error(`[X] Unknown command: ${command}`);
|
|
491
|
-
console.log('');
|
|
492
|
-
console.log('Run for help:');
|
|
493
|
-
console.log(` ${colored('ccs auth --help', 'yellow')}`);
|
|
494
|
-
process.exit(1);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
module.exports = AuthCommands;
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const os = require('os');
|
|
6
|
-
const { findSimilarStrings } = require('../utils/helpers');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Profile Detector
|
|
10
|
-
*
|
|
11
|
-
* Determines profile type (settings-based vs account-based) for routing.
|
|
12
|
-
* Priority: settings-based profiles (glm/kimi) checked FIRST for backward compatibility.
|
|
13
|
-
*/
|
|
14
|
-
class ProfileDetector {
|
|
15
|
-
constructor() {
|
|
16
|
-
this.configPath = path.join(os.homedir(), '.ccs', 'config.json');
|
|
17
|
-
this.profilesPath = path.join(os.homedir(), '.ccs', 'profiles.json');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Read settings-based config (config.json)
|
|
22
|
-
* @returns {Object} Config data
|
|
23
|
-
*/
|
|
24
|
-
_readConfig() {
|
|
25
|
-
if (!fs.existsSync(this.configPath)) {
|
|
26
|
-
return { profiles: {} };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const data = fs.readFileSync(this.configPath, 'utf8');
|
|
31
|
-
return JSON.parse(data);
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.warn(`[!] Warning: Could not read config.json: ${error.message}`);
|
|
34
|
-
return { profiles: {} };
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Read account-based profiles (profiles.json)
|
|
40
|
-
* @returns {Object} Profiles data
|
|
41
|
-
*/
|
|
42
|
-
_readProfiles() {
|
|
43
|
-
if (!fs.existsSync(this.profilesPath)) {
|
|
44
|
-
return { profiles: {}, default: null };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
const data = fs.readFileSync(this.profilesPath, 'utf8');
|
|
49
|
-
return JSON.parse(data);
|
|
50
|
-
} catch (error) {
|
|
51
|
-
console.warn(`[!] Warning: Could not read profiles.json: ${error.message}`);
|
|
52
|
-
return { profiles: {}, default: null };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Detect profile type and return routing information
|
|
58
|
-
* @param {string} profileName - Profile name to detect
|
|
59
|
-
* @returns {Object} {type: 'settings'|'account'|'default', ...info}
|
|
60
|
-
*/
|
|
61
|
-
detectProfileType(profileName) {
|
|
62
|
-
// Special case: 'default' means use default profile
|
|
63
|
-
if (profileName === 'default' || profileName === null || profileName === undefined) {
|
|
64
|
-
return this._resolveDefaultProfile();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Priority 1: Check settings-based profiles (glm, kimi) - BACKWARD COMPATIBILITY
|
|
68
|
-
const config = this._readConfig();
|
|
69
|
-
|
|
70
|
-
if (config.profiles && config.profiles[profileName]) {
|
|
71
|
-
return {
|
|
72
|
-
type: 'settings',
|
|
73
|
-
name: profileName,
|
|
74
|
-
settingsPath: config.profiles[profileName]
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Priority 2: Check account-based profiles (work, personal)
|
|
79
|
-
const profiles = this._readProfiles();
|
|
80
|
-
|
|
81
|
-
if (profiles.profiles && profiles.profiles[profileName]) {
|
|
82
|
-
return {
|
|
83
|
-
type: 'account',
|
|
84
|
-
name: profileName,
|
|
85
|
-
profile: profiles.profiles[profileName]
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Not found - generate suggestions
|
|
90
|
-
const allProfiles = this.getAllProfiles();
|
|
91
|
-
const allProfileNames = [...allProfiles.settings, ...allProfiles.accounts];
|
|
92
|
-
const suggestions = findSimilarStrings(profileName, allProfileNames);
|
|
93
|
-
|
|
94
|
-
const error = new Error(`Profile not found: ${profileName}`);
|
|
95
|
-
error.profileName = profileName;
|
|
96
|
-
error.suggestions = suggestions;
|
|
97
|
-
error.availableProfiles = this._listAvailableProfiles();
|
|
98
|
-
throw error;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Resolve default profile
|
|
103
|
-
* @returns {Object} Default profile info
|
|
104
|
-
*/
|
|
105
|
-
_resolveDefaultProfile() {
|
|
106
|
-
// Check if account-based default exists
|
|
107
|
-
const profiles = this._readProfiles();
|
|
108
|
-
|
|
109
|
-
if (profiles.default && profiles.profiles[profiles.default]) {
|
|
110
|
-
return {
|
|
111
|
-
type: 'account',
|
|
112
|
-
name: profiles.default,
|
|
113
|
-
profile: profiles.profiles[profiles.default]
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Check if settings-based default exists
|
|
118
|
-
const config = this._readConfig();
|
|
119
|
-
|
|
120
|
-
if (config.profiles && config.profiles['default']) {
|
|
121
|
-
return {
|
|
122
|
-
type: 'settings',
|
|
123
|
-
name: 'default',
|
|
124
|
-
settingsPath: config.profiles['default']
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// No default profile configured, use Claude's own defaults
|
|
129
|
-
return {
|
|
130
|
-
type: 'default',
|
|
131
|
-
name: 'default',
|
|
132
|
-
message: 'No profile configured. Using Claude CLI defaults from ~/.claude/'
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* List available profiles (for error messages)
|
|
138
|
-
* @returns {string} Formatted list
|
|
139
|
-
*/
|
|
140
|
-
_listAvailableProfiles() {
|
|
141
|
-
const lines = [];
|
|
142
|
-
|
|
143
|
-
// Settings-based profiles
|
|
144
|
-
const config = this._readConfig();
|
|
145
|
-
const settingsProfiles = Object.keys(config.profiles || {});
|
|
146
|
-
|
|
147
|
-
if (settingsProfiles.length > 0) {
|
|
148
|
-
lines.push('Settings-based profiles (GLM, Kimi, etc.):');
|
|
149
|
-
settingsProfiles.forEach(name => {
|
|
150
|
-
lines.push(` - ${name}`);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Account-based profiles
|
|
155
|
-
const profiles = this._readProfiles();
|
|
156
|
-
const accountProfiles = Object.keys(profiles.profiles || {});
|
|
157
|
-
|
|
158
|
-
if (accountProfiles.length > 0) {
|
|
159
|
-
lines.push('Account-based profiles:');
|
|
160
|
-
accountProfiles.forEach(name => {
|
|
161
|
-
const isDefault = name === profiles.default;
|
|
162
|
-
lines.push(` - ${name}${isDefault ? ' [DEFAULT]' : ''}`);
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (lines.length === 0) {
|
|
167
|
-
return ' (no profiles configured)\n' +
|
|
168
|
-
' Run "ccs auth save <profile>" to create your first account profile.';
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return lines.join('\n');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Check if profile exists (any type)
|
|
176
|
-
* @param {string} profileName - Profile name
|
|
177
|
-
* @returns {boolean} True if exists
|
|
178
|
-
*/
|
|
179
|
-
hasProfile(profileName) {
|
|
180
|
-
try {
|
|
181
|
-
this.detectProfileType(profileName);
|
|
182
|
-
return true;
|
|
183
|
-
} catch {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Get all available profile names
|
|
190
|
-
* @returns {Object} {settings: [...], accounts: [...]}
|
|
191
|
-
*/
|
|
192
|
-
getAllProfiles() {
|
|
193
|
-
const config = this._readConfig();
|
|
194
|
-
const profiles = this._readProfiles();
|
|
195
|
-
|
|
196
|
-
return {
|
|
197
|
-
settings: Object.keys(config.profiles || {}),
|
|
198
|
-
accounts: Object.keys(profiles.profiles || {}),
|
|
199
|
-
default: profiles.default
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
module.exports = ProfileDetector;
|