@sudocode-ai/cli 0.1.18-dev.0 → 0.1.19
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 +1299 -0
- package/dist/auth/claude.d.ts +19 -0
- package/dist/auth/claude.d.ts.map +1 -0
- package/dist/auth/claude.js +179 -0
- package/dist/auth/claude.js.map +1 -0
- package/dist/auth/clear.d.ts +17 -0
- package/dist/auth/clear.d.ts.map +1 -0
- package/dist/auth/clear.js +68 -0
- package/dist/auth/clear.js.map +1 -0
- package/dist/auth/credentials.d.ts +93 -0
- package/dist/auth/credentials.d.ts.map +1 -0
- package/dist/auth/credentials.js +255 -0
- package/dist/auth/credentials.js.map +1 -0
- package/dist/auth/index.d.ts +13 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +19 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/status.d.ts +17 -0
- package/dist/auth/status.d.ts.map +1 -0
- package/dist/auth/status.js +132 -0
- package/dist/auth/status.js.map +1 -0
- package/dist/cli/auth-commands.d.ts +34 -0
- package/dist/cli/auth-commands.d.ts.map +1 -0
- package/dist/cli/auth-commands.js +28 -0
- package/dist/cli/auth-commands.js.map +1 -0
- package/dist/cli/remote-commands.d.ts +59 -0
- package/dist/cli/remote-commands.d.ts.map +1 -0
- package/dist/cli/remote-commands.js +391 -0
- package/dist/cli/remote-commands.js.map +1 -0
- package/dist/cli/update-commands.d.ts.map +1 -1
- package/dist/cli/update-commands.js +56 -0
- package/dist/cli/update-commands.js.map +1 -1
- package/dist/cli.js +130 -0
- package/dist/cli.js.map +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +2 -2
- package/dist/db.js.map +1 -1
- package/dist/remote/claude-auth.d.ts +65 -0
- package/dist/remote/claude-auth.d.ts.map +1 -0
- package/dist/remote/claude-auth.js +100 -0
- package/dist/remote/claude-auth.js.map +1 -0
- package/dist/remote/config.d.ts +83 -0
- package/dist/remote/config.d.ts.map +1 -0
- package/dist/remote/config.js +266 -0
- package/dist/remote/config.js.map +1 -0
- package/dist/remote/errors.d.ts +18 -0
- package/dist/remote/errors.d.ts.map +1 -0
- package/dist/remote/errors.js +27 -0
- package/dist/remote/errors.js.map +1 -0
- package/dist/remote/git-context.d.ts +51 -0
- package/dist/remote/git-context.d.ts.map +1 -0
- package/dist/remote/git-context.js +107 -0
- package/dist/remote/git-context.js.map +1 -0
- package/dist/remote/spawn-service.d.ts +86 -0
- package/dist/remote/spawn-service.d.ts.map +1 -0
- package/dist/remote/spawn-service.js +248 -0
- package/dist/remote/spawn-service.js.map +1 -0
- package/dist/remote/types.d.ts +82 -0
- package/dist/remote/types.d.ts.map +1 -0
- package/dist/remote/types.js +5 -0
- package/dist/remote/types.js.map +1 -0
- package/package.json +4 -7
- package/dist/better-sqlite3-loader.d.ts +0 -9
- package/dist/better-sqlite3-loader.d.ts.map +0 -1
- package/dist/better-sqlite3-loader.js +0 -24
- package/dist/better-sqlite3-loader.js.map +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code interactive authentication command
|
|
3
|
+
*
|
|
4
|
+
* Wraps the Claude CLI's OAuth flow and stores the resulting token securely
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Options for Claude auth command
|
|
8
|
+
*/
|
|
9
|
+
export interface ClaudeAuthOptions {
|
|
10
|
+
force?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Handle Claude authentication command
|
|
14
|
+
* Interactive command that wraps Claude CLI OAuth flow and stores token
|
|
15
|
+
*
|
|
16
|
+
* @param options Command options
|
|
17
|
+
*/
|
|
18
|
+
export declare function handleClaudeAuth(options?: ClaudeAuthOptions): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/auth/claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAwHD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ErF"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code interactive authentication command
|
|
3
|
+
*
|
|
4
|
+
* Wraps the Claude CLI's OAuth flow and stores the resulting token securely
|
|
5
|
+
*/
|
|
6
|
+
import { spawn } from "child_process";
|
|
7
|
+
import * as readline from "readline";
|
|
8
|
+
import { setClaudeToken, hasClaudeToken } from "./credentials.js";
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
/**
|
|
11
|
+
* Prompt user for confirmation
|
|
12
|
+
* @param message Message to display
|
|
13
|
+
* @returns true if user confirms (y/yes), false otherwise
|
|
14
|
+
*/
|
|
15
|
+
async function promptConfirmation(message) {
|
|
16
|
+
const rl = readline.createInterface({
|
|
17
|
+
input: process.stdin,
|
|
18
|
+
output: process.stdout
|
|
19
|
+
});
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
rl.question(message, (answer) => {
|
|
22
|
+
rl.close();
|
|
23
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Check if Claude CLI is installed
|
|
29
|
+
* @returns Promise that resolves to true if installed, false otherwise
|
|
30
|
+
*/
|
|
31
|
+
async function checkClaudeCLI() {
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
const claudeCheck = spawn('claude', ['--version']);
|
|
34
|
+
claudeCheck.on('error', (err) => {
|
|
35
|
+
if (err.code === 'ENOENT') {
|
|
36
|
+
resolve(false);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Other errors still mean CLI exists but something else went wrong
|
|
40
|
+
resolve(true);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
claudeCheck.on('close', (code) => {
|
|
44
|
+
// If we got here, the command executed (even if it failed)
|
|
45
|
+
resolve(true);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validate Claude token format
|
|
51
|
+
* @param token Token to validate
|
|
52
|
+
* @returns true if token format is valid
|
|
53
|
+
*/
|
|
54
|
+
function validateTokenFormat(token) {
|
|
55
|
+
return token.startsWith('sk-ant-');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Prompt user to paste their token
|
|
59
|
+
* @returns Promise that resolves to the user-provided token
|
|
60
|
+
*/
|
|
61
|
+
async function promptForToken() {
|
|
62
|
+
const rl = readline.createInterface({
|
|
63
|
+
input: process.stdin,
|
|
64
|
+
output: process.stdout
|
|
65
|
+
});
|
|
66
|
+
return new Promise((resolve) => {
|
|
67
|
+
rl.question(chalk.yellow('\nPlease paste your OAuth token from above: '), (answer) => {
|
|
68
|
+
rl.close();
|
|
69
|
+
resolve(answer.trim());
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Run Claude CLI OAuth flow
|
|
75
|
+
* @returns Promise that resolves to the user-provided token
|
|
76
|
+
*/
|
|
77
|
+
async function runClaudeOAuthFlow() {
|
|
78
|
+
return new Promise((resolve, reject) => {
|
|
79
|
+
console.log(chalk.blue('\nStarting OAuth flow...'));
|
|
80
|
+
console.log(chalk.dim('(Claude CLI will open your browser for authentication)\n'));
|
|
81
|
+
// Run fully interactively - no output capture
|
|
82
|
+
const claudeProcess = spawn('claude', ['setup-token'], {
|
|
83
|
+
stdio: 'inherit'
|
|
84
|
+
});
|
|
85
|
+
// Handle process completion
|
|
86
|
+
claudeProcess.on('close', async (code) => {
|
|
87
|
+
if (code !== 0) {
|
|
88
|
+
reject(new Error('OAuth flow failed or was cancelled'));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// Prompt user to paste the token
|
|
92
|
+
console.log('\n' + chalk.blue('━'.repeat(60)));
|
|
93
|
+
const token = await promptForToken();
|
|
94
|
+
if (!token) {
|
|
95
|
+
reject(new Error('No token provided'));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!validateTokenFormat(token)) {
|
|
99
|
+
reject(new Error('Invalid token format. Token must start with "sk-ant-"'));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
resolve(token);
|
|
103
|
+
});
|
|
104
|
+
// Handle spawn errors
|
|
105
|
+
claudeProcess.on('error', (err) => {
|
|
106
|
+
reject(new Error(`Failed to spawn Claude CLI: ${err.message}`));
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Handle Claude authentication command
|
|
112
|
+
* Interactive command that wraps Claude CLI OAuth flow and stores token
|
|
113
|
+
*
|
|
114
|
+
* @param options Command options
|
|
115
|
+
*/
|
|
116
|
+
export async function handleClaudeAuth(options = {}) {
|
|
117
|
+
console.log(chalk.blue('\nClaude Code Authentication\n'));
|
|
118
|
+
// Check if already authenticated (before doing any other checks)
|
|
119
|
+
if (!options.force && await hasClaudeToken()) {
|
|
120
|
+
console.log(chalk.yellow('⚠ Claude Code is already configured.\n'));
|
|
121
|
+
const confirmed = await promptConfirmation('Overwrite existing token? (y/N): ');
|
|
122
|
+
if (!confirmed) {
|
|
123
|
+
console.log('\nCancelled. No changes made.');
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
console.log('');
|
|
127
|
+
}
|
|
128
|
+
// Check if Claude CLI is installed (only after user confirms or if force flag is set)
|
|
129
|
+
console.log('Checking for Claude CLI...');
|
|
130
|
+
const isInstalled = await checkClaudeCLI();
|
|
131
|
+
if (!isInstalled) {
|
|
132
|
+
console.error(chalk.red('✗ Error: claude CLI not found\n'));
|
|
133
|
+
console.error('The Claude CLI is required for authentication.');
|
|
134
|
+
console.error('Install: npm install -g @anthropic-ai/claude-cli\n');
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
console.log(chalk.green('✓ Found Claude CLI\n'));
|
|
138
|
+
try {
|
|
139
|
+
// Run OAuth flow
|
|
140
|
+
const token = await runClaudeOAuthFlow();
|
|
141
|
+
// Store token
|
|
142
|
+
await setClaudeToken(token);
|
|
143
|
+
// Success message
|
|
144
|
+
console.log(chalk.green('\n✓ Authentication successful'));
|
|
145
|
+
console.log(chalk.green('✓ Token stored securely at ~/.config/sudocode/user_credentials.json\n'));
|
|
146
|
+
console.log(chalk.dim('Run \'sudocode auth status\' to verify configuration.\n'));
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
// Handle different error types
|
|
150
|
+
if (error.message.includes('cancelled')) {
|
|
151
|
+
console.error(chalk.yellow('\n✗ OAuth flow was cancelled\n'));
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
if (error.message.includes('No token provided')) {
|
|
155
|
+
console.error(chalk.red('\n✗ No token provided\n'));
|
|
156
|
+
console.error('You must paste the OAuth token to complete authentication.\n');
|
|
157
|
+
console.error(chalk.dim('Please try again.\n'));
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
if (error.message.includes('Invalid token format')) {
|
|
161
|
+
console.error(chalk.red('\n✗ Invalid token format\n'));
|
|
162
|
+
console.error('The token must start with "sk-ant-".');
|
|
163
|
+
console.error('Please ensure you copied the complete token.\n');
|
|
164
|
+
console.error(chalk.dim('Please try again.\n'));
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
if (error.message.includes('permission')) {
|
|
168
|
+
console.error(chalk.red('\n✗ Permission error\n'));
|
|
169
|
+
console.error('Failed to write credentials file.');
|
|
170
|
+
console.error('Ensure you have write permissions for:');
|
|
171
|
+
console.error(' ~/.config/sudocode/user_credentials.json\n');
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
// Generic error
|
|
175
|
+
console.error(chalk.red(`\n✗ Authentication failed: ${error.message}\n`));
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/auth/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth clear command - removes all stored credentials with confirmation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Options for auth clear command
|
|
6
|
+
*/
|
|
7
|
+
export interface ClearOptions {
|
|
8
|
+
force?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Handle auth clear command
|
|
12
|
+
* Removes all stored authentication credentials with user confirmation
|
|
13
|
+
*
|
|
14
|
+
* @param options Command options
|
|
15
|
+
*/
|
|
16
|
+
export declare function handleAuthClear(options: ClearOptions): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=clear.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../src/auth/clear.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAqBD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C1E"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth clear command - removes all stored credentials with confirmation
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as readline from "readline";
|
|
6
|
+
import { getCredentialsFilePath, getConfiguredCredentialTypes } from "./credentials.js";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
/**
|
|
9
|
+
* Prompt user for confirmation
|
|
10
|
+
* @param message Message to display
|
|
11
|
+
* @returns true if user confirms (y/yes), false otherwise
|
|
12
|
+
*/
|
|
13
|
+
async function promptConfirmation(message) {
|
|
14
|
+
const rl = readline.createInterface({
|
|
15
|
+
input: process.stdin,
|
|
16
|
+
output: process.stdout
|
|
17
|
+
});
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
rl.question(message, (answer) => {
|
|
20
|
+
rl.close();
|
|
21
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Handle auth clear command
|
|
27
|
+
* Removes all stored authentication credentials with user confirmation
|
|
28
|
+
*
|
|
29
|
+
* @param options Command options
|
|
30
|
+
*/
|
|
31
|
+
export async function handleAuthClear(options) {
|
|
32
|
+
const credentialsFile = getCredentialsFilePath();
|
|
33
|
+
// Check if credentials file exists
|
|
34
|
+
if (!fs.existsSync(credentialsFile)) {
|
|
35
|
+
console.log('No credentials configured. Nothing to clear.');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Get configured types for display
|
|
39
|
+
const configuredTypes = await getConfiguredCredentialTypes();
|
|
40
|
+
if (configuredTypes.length === 0) {
|
|
41
|
+
console.log('No credentials configured. Nothing to clear.');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Force mode - skip confirmation
|
|
45
|
+
if (options.force) {
|
|
46
|
+
fs.unlinkSync(credentialsFile);
|
|
47
|
+
console.log(chalk.green('✓ All credentials cleared'));
|
|
48
|
+
console.log(chalk.dim(`✓ Removed ${credentialsFile}`));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Interactive confirmation
|
|
52
|
+
console.log(chalk.yellow('\n⚠ Warning: This will delete all stored authentication credentials.\n'));
|
|
53
|
+
console.log('Current credentials:');
|
|
54
|
+
configuredTypes.forEach(type => {
|
|
55
|
+
console.log(` • ${type} (configured)`);
|
|
56
|
+
});
|
|
57
|
+
console.log('');
|
|
58
|
+
const confirmed = await promptConfirmation('Delete all credentials? (y/N): ');
|
|
59
|
+
if (confirmed) {
|
|
60
|
+
fs.unlinkSync(credentialsFile);
|
|
61
|
+
console.log(chalk.green('\n✓ All credentials cleared'));
|
|
62
|
+
console.log(chalk.dim(`✓ Removed ${credentialsFile}`));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.log('\nCancelled. No changes made.');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=clear.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../src/auth/clear.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAAC,OAAe;IAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAqB;IACzD,MAAM,eAAe,GAAG,sBAAsB,EAAE,CAAC;IAEjD,mCAAmC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,mCAAmC;IACnC,MAAM,eAAe,GAAG,MAAM,4BAA4B,EAAE,CAAC;IAE7D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,iCAAiC;IACjC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,eAAe,EAAE,CAAC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,2BAA2B;IAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wEAAwE,CAAC,CAAC,CAAC;IACpG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAEpC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,eAAe,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,iCAAiC,CAAC,CAAC;IAE9E,IAAI,SAAS,EAAE,CAAC;QACd,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,eAAe,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared credentials module for extensible auth storage
|
|
3
|
+
*
|
|
4
|
+
* Stores and retrieves authentication credentials for multiple AI services
|
|
5
|
+
* in a secure, extensible manner.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Configuration directory path (exported for testing compatibility)
|
|
9
|
+
* Note: This is evaluated at module load time. For tests that modify XDG_CONFIG_HOME,
|
|
10
|
+
* use getCredentialsFilePath() instead which evaluates dynamically.
|
|
11
|
+
*/
|
|
12
|
+
export declare const CONFIG_DIR: string;
|
|
13
|
+
/**
|
|
14
|
+
* Credentials file path (exported for testing compatibility)
|
|
15
|
+
* Note: This is evaluated at module load time. For tests that modify XDG_CONFIG_HOME,
|
|
16
|
+
* use getCredentialsFilePath() instead which evaluates dynamically.
|
|
17
|
+
*/
|
|
18
|
+
export declare const CREDENTIALS_FILE: string;
|
|
19
|
+
/**
|
|
20
|
+
* Get credentials file path dynamically (for testing)
|
|
21
|
+
* This evaluates the path each time it's called, respecting environment changes
|
|
22
|
+
*/
|
|
23
|
+
export declare function getCredentialsFilePath(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Credentials interface representing all supported credential types
|
|
26
|
+
*/
|
|
27
|
+
export interface Credentials {
|
|
28
|
+
claudeToken: string | null;
|
|
29
|
+
llmKey: string | null;
|
|
30
|
+
litellmCredentials: any | null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Retrieve all configured credentials
|
|
34
|
+
* @returns Object with all credential types (null for unconfigured)
|
|
35
|
+
*/
|
|
36
|
+
export declare function getAllCredentials(): Promise<Credentials>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if at least one credential is configured
|
|
39
|
+
* Required for deployment - ensures some AI service is available
|
|
40
|
+
* @returns true if any credential exists
|
|
41
|
+
*/
|
|
42
|
+
export declare function hasAnyCredential(): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Get count of configured credentials
|
|
45
|
+
* @returns Number of configured credentials
|
|
46
|
+
*/
|
|
47
|
+
export declare function getConfiguredCredentialCount(): Promise<number>;
|
|
48
|
+
/**
|
|
49
|
+
* Get list of configured credential types
|
|
50
|
+
* @returns Array of service names with configured credentials
|
|
51
|
+
*/
|
|
52
|
+
export declare function getConfiguredCredentialTypes(): Promise<string[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Get Claude Code OAuth token
|
|
55
|
+
* @returns Claude token or null if not configured
|
|
56
|
+
*/
|
|
57
|
+
export declare function getClaudeToken(): Promise<string | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Check if Claude Code token is configured
|
|
60
|
+
* @returns true if Claude token exists
|
|
61
|
+
*/
|
|
62
|
+
export declare function hasClaudeToken(): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* Get LLM API key (OpenAI/LiteLLM)
|
|
65
|
+
* @returns LLM key or null if not configured
|
|
66
|
+
*/
|
|
67
|
+
export declare function getLLMKey(): Promise<string | null>;
|
|
68
|
+
/**
|
|
69
|
+
* Check if LLM key is configured
|
|
70
|
+
* @returns true if LLM key exists
|
|
71
|
+
*/
|
|
72
|
+
export declare function hasLLMKey(): Promise<boolean>;
|
|
73
|
+
/**
|
|
74
|
+
* Get LiteLLM credentials
|
|
75
|
+
* @returns LiteLLM credentials object or null if not configured
|
|
76
|
+
*/
|
|
77
|
+
export declare function getLiteLLMCredentials(): Promise<any | null>;
|
|
78
|
+
/**
|
|
79
|
+
* Check if LiteLLM credentials are configured
|
|
80
|
+
* @returns true if LiteLLM credentials exist
|
|
81
|
+
*/
|
|
82
|
+
export declare function hasLiteLLMCredentials(): Promise<boolean>;
|
|
83
|
+
/**
|
|
84
|
+
* Set Claude Code OAuth token
|
|
85
|
+
* @param token Claude Code OAuth token
|
|
86
|
+
*/
|
|
87
|
+
export declare function setClaudeToken(token: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Clear all stored credentials
|
|
90
|
+
* Removes the credentials file
|
|
91
|
+
*/
|
|
92
|
+
export declare function clearAllCredentials(): Promise<void>;
|
|
93
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/auth/credentials.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH;;;;GAIG;AACH,eAAO,MAAM,UAAU,QAAiB,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAuB,CAAC;AAErD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kBAAkB,EAAE,GAAG,GAAG,IAAI,CAAC;CAChC;AA+GD;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CAQ9D;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAGzD;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,MAAM,CAAC,CAGpE;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAStE;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAG7D;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAGvD;AAED;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxD;AAED;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAGlD;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAGjE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAG9D;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjE;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUzD"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared credentials module for extensible auth storage
|
|
3
|
+
*
|
|
4
|
+
* Stores and retrieves authentication credentials for multiple AI services
|
|
5
|
+
* in a secure, extensible manner.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from "fs/promises";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
import * as os from "os";
|
|
10
|
+
/**
|
|
11
|
+
* Get configuration directory path
|
|
12
|
+
* Uses XDG_CONFIG_HOME if set, otherwise ~/.config/sudocode
|
|
13
|
+
*/
|
|
14
|
+
function getConfigDir() {
|
|
15
|
+
return process.env.XDG_CONFIG_HOME
|
|
16
|
+
? path.join(process.env.XDG_CONFIG_HOME, "sudocode")
|
|
17
|
+
: path.join(os.homedir(), ".config", "sudocode");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get credentials file path
|
|
21
|
+
*/
|
|
22
|
+
function getCredentialsFile() {
|
|
23
|
+
return path.join(getConfigDir(), "user_credentials.json");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuration directory path (exported for testing compatibility)
|
|
27
|
+
* Note: This is evaluated at module load time. For tests that modify XDG_CONFIG_HOME,
|
|
28
|
+
* use getCredentialsFilePath() instead which evaluates dynamically.
|
|
29
|
+
*/
|
|
30
|
+
export const CONFIG_DIR = getConfigDir();
|
|
31
|
+
/**
|
|
32
|
+
* Credentials file path (exported for testing compatibility)
|
|
33
|
+
* Note: This is evaluated at module load time. For tests that modify XDG_CONFIG_HOME,
|
|
34
|
+
* use getCredentialsFilePath() instead which evaluates dynamically.
|
|
35
|
+
*/
|
|
36
|
+
export const CREDENTIALS_FILE = getCredentialsFile();
|
|
37
|
+
/**
|
|
38
|
+
* Get credentials file path dynamically (for testing)
|
|
39
|
+
* This evaluates the path each time it's called, respecting environment changes
|
|
40
|
+
*/
|
|
41
|
+
export function getCredentialsFilePath() {
|
|
42
|
+
return getCredentialsFile();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Ensure config directory exists with correct permissions (700)
|
|
46
|
+
*/
|
|
47
|
+
async function ensureConfigDir() {
|
|
48
|
+
const configDir = getConfigDir();
|
|
49
|
+
try {
|
|
50
|
+
await fs.mkdir(configDir, { recursive: true, mode: 0o700 });
|
|
51
|
+
// Always check and fix permissions (mkdir with recursive doesn't throw if dir exists)
|
|
52
|
+
const stats = await fs.stat(configDir);
|
|
53
|
+
const mode = stats.mode & 0o777;
|
|
54
|
+
if (mode !== 0o700) {
|
|
55
|
+
console.warn(`Warning: Config directory has incorrect permissions (${mode.toString(8)}), fixing to 700`);
|
|
56
|
+
await fs.chmod(configDir, 0o700);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new Error(`Failed to create config directory: ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validate and auto-correct file permissions
|
|
65
|
+
* @param filePath Path to the credentials file
|
|
66
|
+
*/
|
|
67
|
+
async function validateFilePermissions(filePath) {
|
|
68
|
+
try {
|
|
69
|
+
const stats = await fs.stat(filePath);
|
|
70
|
+
const mode = stats.mode & 0o777;
|
|
71
|
+
if (mode !== 0o600) {
|
|
72
|
+
console.warn(`Warning: Credentials file has incorrect permissions (${mode.toString(8)}), fixing to 600`);
|
|
73
|
+
await fs.chmod(filePath, 0o600);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// File doesn't exist, that's okay
|
|
78
|
+
if (error.code !== 'ENOENT') {
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Read credentials from storage
|
|
85
|
+
* @returns Parsed credentials or empty object if file doesn't exist
|
|
86
|
+
*/
|
|
87
|
+
async function readCredentialsStorage() {
|
|
88
|
+
const credentialsFile = getCredentialsFile();
|
|
89
|
+
try {
|
|
90
|
+
// Ensure directory exists
|
|
91
|
+
await ensureConfigDir();
|
|
92
|
+
// Validate file permissions if file exists
|
|
93
|
+
await validateFilePermissions(credentialsFile);
|
|
94
|
+
// Read file
|
|
95
|
+
const content = await fs.readFile(credentialsFile, "utf-8");
|
|
96
|
+
return JSON.parse(content);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
// File doesn't exist
|
|
100
|
+
if (error.code === 'ENOENT') {
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
// Parse error
|
|
104
|
+
if (error instanceof SyntaxError) {
|
|
105
|
+
console.warn(`Warning: Failed to parse credentials file, returning empty credentials: ${error.message}`);
|
|
106
|
+
return {};
|
|
107
|
+
}
|
|
108
|
+
// Permission or other error
|
|
109
|
+
throw new Error(`Failed to read credentials: ${error.message}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Write credentials to storage with atomic write and secure permissions
|
|
114
|
+
* @param credentials Credentials to write
|
|
115
|
+
*/
|
|
116
|
+
async function writeCredentialsStorage(credentials) {
|
|
117
|
+
const credentialsFile = getCredentialsFile();
|
|
118
|
+
try {
|
|
119
|
+
// Ensure directory exists
|
|
120
|
+
await ensureConfigDir();
|
|
121
|
+
// Write to temp file first (atomic write)
|
|
122
|
+
const tempFile = `${credentialsFile}.tmp`;
|
|
123
|
+
await fs.writeFile(tempFile, JSON.stringify(credentials, null, 2), {
|
|
124
|
+
mode: 0o600,
|
|
125
|
+
});
|
|
126
|
+
// Atomic rename
|
|
127
|
+
await fs.rename(tempFile, credentialsFile);
|
|
128
|
+
// Ensure correct permissions (in case umask interfered)
|
|
129
|
+
await fs.chmod(credentialsFile, 0o600);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new Error(`Failed to write credentials: ${error.message}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Retrieve all configured credentials
|
|
137
|
+
* @returns Object with all credential types (null for unconfigured)
|
|
138
|
+
*/
|
|
139
|
+
export async function getAllCredentials() {
|
|
140
|
+
const storage = await readCredentialsStorage();
|
|
141
|
+
return {
|
|
142
|
+
claudeToken: storage.claudeCodeOAuthToken || null,
|
|
143
|
+
llmKey: storage.llmKey || null,
|
|
144
|
+
litellmCredentials: storage.litellmCredentials || null,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Check if at least one credential is configured
|
|
149
|
+
* Required for deployment - ensures some AI service is available
|
|
150
|
+
* @returns true if any credential exists
|
|
151
|
+
*/
|
|
152
|
+
export async function hasAnyCredential() {
|
|
153
|
+
const creds = await getAllCredentials();
|
|
154
|
+
return Object.values(creds).some(val => val !== null);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get count of configured credentials
|
|
158
|
+
* @returns Number of configured credentials
|
|
159
|
+
*/
|
|
160
|
+
export async function getConfiguredCredentialCount() {
|
|
161
|
+
const creds = await getAllCredentials();
|
|
162
|
+
return Object.values(creds).filter(val => val !== null).length;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get list of configured credential types
|
|
166
|
+
* @returns Array of service names with configured credentials
|
|
167
|
+
*/
|
|
168
|
+
export async function getConfiguredCredentialTypes() {
|
|
169
|
+
const creds = await getAllCredentials();
|
|
170
|
+
const types = [];
|
|
171
|
+
if (creds.claudeToken)
|
|
172
|
+
types.push('Claude Code');
|
|
173
|
+
if (creds.llmKey)
|
|
174
|
+
types.push('LLM Key');
|
|
175
|
+
if (creds.litellmCredentials)
|
|
176
|
+
types.push('LiteLLM');
|
|
177
|
+
return types;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get Claude Code OAuth token
|
|
181
|
+
* @returns Claude token or null if not configured
|
|
182
|
+
*/
|
|
183
|
+
export async function getClaudeToken() {
|
|
184
|
+
const creds = await getAllCredentials();
|
|
185
|
+
return creds.claudeToken;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if Claude Code token is configured
|
|
189
|
+
* @returns true if Claude token exists
|
|
190
|
+
*/
|
|
191
|
+
export async function hasClaudeToken() {
|
|
192
|
+
const token = await getClaudeToken();
|
|
193
|
+
return token !== null && token.length > 0;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get LLM API key (OpenAI/LiteLLM)
|
|
197
|
+
* @returns LLM key or null if not configured
|
|
198
|
+
*/
|
|
199
|
+
export async function getLLMKey() {
|
|
200
|
+
const creds = await getAllCredentials();
|
|
201
|
+
return creds.llmKey;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Check if LLM key is configured
|
|
205
|
+
* @returns true if LLM key exists
|
|
206
|
+
*/
|
|
207
|
+
export async function hasLLMKey() {
|
|
208
|
+
const key = await getLLMKey();
|
|
209
|
+
return key !== null && key.length > 0;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get LiteLLM credentials
|
|
213
|
+
* @returns LiteLLM credentials object or null if not configured
|
|
214
|
+
*/
|
|
215
|
+
export async function getLiteLLMCredentials() {
|
|
216
|
+
const creds = await getAllCredentials();
|
|
217
|
+
return creds.litellmCredentials;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Check if LiteLLM credentials are configured
|
|
221
|
+
* @returns true if LiteLLM credentials exist
|
|
222
|
+
*/
|
|
223
|
+
export async function hasLiteLLMCredentials() {
|
|
224
|
+
const creds = await getLiteLLMCredentials();
|
|
225
|
+
return creds !== null;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Set Claude Code OAuth token
|
|
229
|
+
* @param token Claude Code OAuth token
|
|
230
|
+
*/
|
|
231
|
+
export async function setClaudeToken(token) {
|
|
232
|
+
if (!token || token.length === 0) {
|
|
233
|
+
throw new Error('Token cannot be empty');
|
|
234
|
+
}
|
|
235
|
+
const storage = await readCredentialsStorage();
|
|
236
|
+
storage.claudeCodeOAuthToken = token;
|
|
237
|
+
await writeCredentialsStorage(storage);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Clear all stored credentials
|
|
241
|
+
* Removes the credentials file
|
|
242
|
+
*/
|
|
243
|
+
export async function clearAllCredentials() {
|
|
244
|
+
const credentialsFile = getCredentialsFile();
|
|
245
|
+
try {
|
|
246
|
+
await fs.unlink(credentialsFile);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
// File doesn't exist, that's okay
|
|
250
|
+
if (error.code !== 'ENOENT') {
|
|
251
|
+
throw new Error(`Failed to clear credentials: ${error.message}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/auth/credentials.ts"],"names":[],"mappings":"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"}
|