popeye-cli 1.0.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/.env.example +25 -0
- package/.prettierrc +8 -0
- package/README.md +320 -0
- package/dist/adapters/claude.d.ts +82 -0
- package/dist/adapters/claude.d.ts.map +1 -0
- package/dist/adapters/claude.js +230 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/openai.d.ts +48 -0
- package/dist/adapters/openai.d.ts.map +1 -0
- package/dist/adapters/openai.js +257 -0
- package/dist/adapters/openai.js.map +1 -0
- package/dist/auth/claude.d.ts +44 -0
- package/dist/auth/claude.d.ts.map +1 -0
- package/dist/auth/claude.js +139 -0
- package/dist/auth/claude.js.map +1 -0
- package/dist/auth/index.d.ts +61 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +141 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/keychain.d.ts +66 -0
- package/dist/auth/keychain.d.ts.map +1 -0
- package/dist/auth/keychain.js +125 -0
- package/dist/auth/keychain.js.map +1 -0
- package/dist/auth/openai-entry.d.ts +9 -0
- package/dist/auth/openai-entry.d.ts.map +1 -0
- package/dist/auth/openai-entry.js +410 -0
- package/dist/auth/openai-entry.js.map +1 -0
- package/dist/auth/openai.d.ts +71 -0
- package/dist/auth/openai.d.ts.map +1 -0
- package/dist/auth/openai.js +212 -0
- package/dist/auth/openai.js.map +1 -0
- package/dist/auth/server.d.ts +32 -0
- package/dist/auth/server.d.ts.map +1 -0
- package/dist/auth/server.js +213 -0
- package/dist/auth/server.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +10 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +162 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/config.d.ts +10 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +215 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/create.d.ts +10 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +240 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/index.d.ts +10 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +10 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/resume.d.ts +18 -0
- package/dist/cli/commands/resume.d.ts.map +1 -0
- package/dist/cli/commands/resume.js +241 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/status.d.ts +18 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +154 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +71 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/interactive.d.ts +9 -0
- package/dist/cli/interactive.d.ts.map +1 -0
- package/dist/cli/interactive.js +330 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/output.d.ts +182 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +355 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/config/defaults.d.ts +57 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +103 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +138 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +244 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +220 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +141 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/generators/index.d.ts +101 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +200 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/python.d.ts +48 -0
- package/dist/generators/python.d.ts.map +1 -0
- package/dist/generators/python.js +262 -0
- package/dist/generators/python.js.map +1 -0
- package/dist/generators/templates/index.d.ts +6 -0
- package/dist/generators/templates/index.d.ts.map +1 -0
- package/dist/generators/templates/index.js +6 -0
- package/dist/generators/templates/index.js.map +1 -0
- package/dist/generators/templates/python.d.ts +53 -0
- package/dist/generators/templates/python.d.ts.map +1 -0
- package/dist/generators/templates/python.js +454 -0
- package/dist/generators/templates/python.js.map +1 -0
- package/dist/generators/templates/typescript.d.ts +53 -0
- package/dist/generators/templates/typescript.d.ts.map +1 -0
- package/dist/generators/templates/typescript.js +394 -0
- package/dist/generators/templates/typescript.js.map +1 -0
- package/dist/generators/typescript.d.ts +64 -0
- package/dist/generators/typescript.d.ts.map +1 -0
- package/dist/generators/typescript.js +271 -0
- package/dist/generators/typescript.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/state/index.d.ts +168 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +338 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/persistence.d.ts +91 -0
- package/dist/state/persistence.d.ts.map +1 -0
- package/dist/state/persistence.js +201 -0
- package/dist/state/persistence.js.map +1 -0
- package/dist/types/cli.d.ts +132 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +17 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/consensus.d.ts +111 -0
- package/dist/types/consensus.d.ts.map +1 -0
- package/dist/types/consensus.js +29 -0
- package/dist/types/consensus.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +13 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/project.d.ts +73 -0
- package/dist/types/project.d.ts.map +1 -0
- package/dist/types/project.js +55 -0
- package/dist/types/project.js.map +1 -0
- package/dist/types/workflow.d.ts +236 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +74 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/workflow/consensus.d.ts +89 -0
- package/dist/workflow/consensus.d.ts.map +1 -0
- package/dist/workflow/consensus.js +220 -0
- package/dist/workflow/consensus.js.map +1 -0
- package/dist/workflow/execution-mode.d.ts +82 -0
- package/dist/workflow/execution-mode.d.ts.map +1 -0
- package/dist/workflow/execution-mode.js +346 -0
- package/dist/workflow/execution-mode.js.map +1 -0
- package/dist/workflow/index.d.ts +110 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +283 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/plan-mode.d.ts +83 -0
- package/dist/workflow/plan-mode.d.ts.map +1 -0
- package/dist/workflow/plan-mode.js +241 -0
- package/dist/workflow/plan-mode.js.map +1 -0
- package/dist/workflow/test-runner.d.ts +87 -0
- package/dist/workflow/test-runner.d.ts.map +1 -0
- package/dist/workflow/test-runner.js +273 -0
- package/dist/workflow/test-runner.js.map +1 -0
- package/eslint.config.js +25 -0
- package/package.json +66 -0
- package/src/adapters/claude.ts +298 -0
- package/src/adapters/openai.ts +300 -0
- package/src/auth/claude.ts +166 -0
- package/src/auth/index.ts +171 -0
- package/src/auth/keychain.ts +138 -0
- package/src/auth/openai-entry.ts +410 -0
- package/src/auth/openai.ts +260 -0
- package/src/auth/server.ts +252 -0
- package/src/cli/commands/auth.ts +194 -0
- package/src/cli/commands/config.ts +241 -0
- package/src/cli/commands/create.ts +308 -0
- package/src/cli/commands/index.ts +10 -0
- package/src/cli/commands/resume.ts +304 -0
- package/src/cli/commands/status.ts +189 -0
- package/src/cli/index.ts +90 -0
- package/src/cli/interactive.ts +418 -0
- package/src/cli/output.ts +410 -0
- package/src/config/defaults.ts +114 -0
- package/src/config/index.ts +315 -0
- package/src/config/schema.ts +164 -0
- package/src/generators/index.ts +251 -0
- package/src/generators/python.ts +318 -0
- package/src/generators/templates/index.ts +6 -0
- package/src/generators/templates/python.ts +465 -0
- package/src/generators/templates/typescript.ts +417 -0
- package/src/generators/typescript.ts +340 -0
- package/src/index.ts +13 -0
- package/src/state/index.ts +454 -0
- package/src/state/persistence.ts +230 -0
- package/src/types/cli.ts +146 -0
- package/src/types/consensus.ts +116 -0
- package/src/types/index.ts +64 -0
- package/src/types/project.ts +85 -0
- package/src/types/workflow.ts +149 -0
- package/src/workflow/consensus.ts +299 -0
- package/src/workflow/execution-mode.ts +517 -0
- package/src/workflow/index.ts +396 -0
- package/src/workflow/plan-mode.ts +356 -0
- package/src/workflow/test-runner.ts +345 -0
- package/tests/adapters/openai.test.ts +145 -0
- package/tests/config/config.test.ts +208 -0
- package/tests/generators/generators.test.ts +185 -0
- package/tests/types/consensus.test.ts +152 -0
- package/tests/types/project.test.ts +134 -0
- package/tests/workflow/consensus.test.ts +221 -0
- package/tests/workflow/test-runner.test.ts +214 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +22 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication orchestration module
|
|
3
|
+
* Coordinates authentication for both Claude CLI and OpenAI API
|
|
4
|
+
*/
|
|
5
|
+
import { checkClaudeCLIAuth, authenticateClaude, logoutClaude } from './claude.js';
|
|
6
|
+
import { checkOpenAIAuth, authenticateOpenAI, logoutOpenAI } from './openai.js';
|
|
7
|
+
import { clearAllCredentials } from './keychain.js';
|
|
8
|
+
// Re-export individual auth modules
|
|
9
|
+
export * from './claude.js';
|
|
10
|
+
export * from './openai.js';
|
|
11
|
+
export * from './keychain.js';
|
|
12
|
+
export * from './server.js';
|
|
13
|
+
/**
|
|
14
|
+
* Get the authentication status for both services
|
|
15
|
+
*/
|
|
16
|
+
export async function getAuthStatus() {
|
|
17
|
+
const [claudeStatus, openaiStatus] = await Promise.all([
|
|
18
|
+
checkClaudeCLIAuth(),
|
|
19
|
+
checkOpenAIAuth(),
|
|
20
|
+
]);
|
|
21
|
+
return {
|
|
22
|
+
claude: claudeStatus,
|
|
23
|
+
openai: openaiStatus,
|
|
24
|
+
fullyAuthenticated: claudeStatus.authenticated && openaiStatus.authenticated,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get auth status formatted for CLI display
|
|
29
|
+
*/
|
|
30
|
+
export async function getAuthStatusForDisplay() {
|
|
31
|
+
const status = await getAuthStatus();
|
|
32
|
+
return {
|
|
33
|
+
claude: {
|
|
34
|
+
authenticated: status.claude.authenticated,
|
|
35
|
+
user: status.claude.user,
|
|
36
|
+
expires: status.claude.expires,
|
|
37
|
+
},
|
|
38
|
+
openai: {
|
|
39
|
+
authenticated: status.openai.authenticated,
|
|
40
|
+
keyLastFour: status.openai.keyLastFour,
|
|
41
|
+
modelAccess: status.openai.modelAccess,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Ensure both services are authenticated
|
|
47
|
+
* Prompts for authentication if either is missing
|
|
48
|
+
*
|
|
49
|
+
* @returns True if both services are authenticated
|
|
50
|
+
*/
|
|
51
|
+
export async function ensureAuthenticated() {
|
|
52
|
+
const status = await getAuthStatus();
|
|
53
|
+
if (status.fullyAuthenticated) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
let success = true;
|
|
57
|
+
// Authenticate Claude if needed
|
|
58
|
+
if (!status.claude.authenticated) {
|
|
59
|
+
console.log('\n--- Claude CLI Authentication ---\n');
|
|
60
|
+
const claudeSuccess = await authenticateClaude();
|
|
61
|
+
if (!claudeSuccess) {
|
|
62
|
+
success = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Authenticate OpenAI if needed
|
|
66
|
+
if (!status.openai.authenticated) {
|
|
67
|
+
console.log('\n--- OpenAI API Authentication ---\n');
|
|
68
|
+
const openaiSuccess = await authenticateOpenAI();
|
|
69
|
+
if (!openaiSuccess) {
|
|
70
|
+
success = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return success;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Authenticate a specific service
|
|
77
|
+
*
|
|
78
|
+
* @param service - The service to authenticate ('claude', 'openai', or 'all')
|
|
79
|
+
* @returns True if authentication was successful
|
|
80
|
+
*/
|
|
81
|
+
export async function authenticateService(service) {
|
|
82
|
+
switch (service) {
|
|
83
|
+
case 'claude':
|
|
84
|
+
return authenticateClaude();
|
|
85
|
+
case 'openai':
|
|
86
|
+
return authenticateOpenAI();
|
|
87
|
+
case 'all':
|
|
88
|
+
return ensureAuthenticated();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Logout from a specific service or all services
|
|
93
|
+
*
|
|
94
|
+
* @param service - The service to logout from ('claude', 'openai', or 'all')
|
|
95
|
+
*/
|
|
96
|
+
export async function logout(service) {
|
|
97
|
+
switch (service) {
|
|
98
|
+
case 'claude':
|
|
99
|
+
await logoutClaude();
|
|
100
|
+
break;
|
|
101
|
+
case 'openai':
|
|
102
|
+
await logoutOpenAI();
|
|
103
|
+
break;
|
|
104
|
+
case 'all':
|
|
105
|
+
await clearAllCredentials();
|
|
106
|
+
console.log('All credentials removed.');
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if a specific service is authenticated
|
|
112
|
+
*
|
|
113
|
+
* @param service - The service to check
|
|
114
|
+
* @returns True if the service is authenticated
|
|
115
|
+
*/
|
|
116
|
+
export async function isAuthenticated(service) {
|
|
117
|
+
const status = await getAuthStatus();
|
|
118
|
+
switch (service) {
|
|
119
|
+
case 'claude':
|
|
120
|
+
return status.claude.authenticated;
|
|
121
|
+
case 'openai':
|
|
122
|
+
return status.openai.authenticated;
|
|
123
|
+
case 'both':
|
|
124
|
+
return status.fullyAuthenticated;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Require authentication, throwing an error if not authenticated
|
|
129
|
+
*
|
|
130
|
+
* @throws Error if not authenticated
|
|
131
|
+
*/
|
|
132
|
+
export async function requireAuth() {
|
|
133
|
+
const status = await getAuthStatus();
|
|
134
|
+
if (!status.claude.authenticated) {
|
|
135
|
+
throw new Error('Claude CLI authentication required. Run: popeye-cli auth claude');
|
|
136
|
+
}
|
|
137
|
+
if (!status.openai.authenticated) {
|
|
138
|
+
throw new Error('OpenAI API authentication required. Run: popeye-cli auth openai');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keychain wrapper for secure credential storage
|
|
3
|
+
* Uses keytar for cross-platform keychain access (macOS Keychain, Windows Credential Vault, Linux Secret Service)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Get a credential from the system keychain
|
|
7
|
+
* Falls back to environment variable if keychain is unavailable
|
|
8
|
+
*
|
|
9
|
+
* @param account - The account name (e.g., 'claude-cli', 'openai-api')
|
|
10
|
+
* @returns The stored credential or null if not found
|
|
11
|
+
*/
|
|
12
|
+
export declare function getCredential(account: string): Promise<string | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Store a credential in the system keychain
|
|
15
|
+
*
|
|
16
|
+
* @param account - The account name
|
|
17
|
+
* @param password - The credential to store
|
|
18
|
+
*/
|
|
19
|
+
export declare function setCredential(account: string, password: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Delete a credential from the system keychain
|
|
22
|
+
*
|
|
23
|
+
* @param account - The account name
|
|
24
|
+
* @returns True if the credential was deleted, false if it didn't exist
|
|
25
|
+
*/
|
|
26
|
+
export declare function deleteCredential(account: string): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a credential exists in the keychain
|
|
29
|
+
*
|
|
30
|
+
* @param account - The account name
|
|
31
|
+
* @returns True if the credential exists
|
|
32
|
+
*/
|
|
33
|
+
export declare function hasCredential(account: string): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Get the Claude CLI credential
|
|
36
|
+
*/
|
|
37
|
+
export declare function getClaudeCredential(): Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Set the Claude CLI credential
|
|
40
|
+
*/
|
|
41
|
+
export declare function setClaudeCredential(token: string): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Delete the Claude CLI credential
|
|
44
|
+
*/
|
|
45
|
+
export declare function deleteClaudeCredential(): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the OpenAI API credential
|
|
48
|
+
*/
|
|
49
|
+
export declare function getOpenAICredential(): Promise<string | null>;
|
|
50
|
+
/**
|
|
51
|
+
* Set the OpenAI API credential
|
|
52
|
+
*/
|
|
53
|
+
export declare function setOpenAICredential(apiKey: string): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Delete the OpenAI API credential
|
|
56
|
+
*/
|
|
57
|
+
export declare function deleteOpenAICredential(): Promise<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* Clear all stored credentials
|
|
60
|
+
*/
|
|
61
|
+
export declare function clearAllCredentials(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Get the last 4 characters of a credential for display purposes
|
|
64
|
+
*/
|
|
65
|
+
export declare function maskCredential(credential: string): string;
|
|
66
|
+
//# sourceMappingURL=keychain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../../src/auth/keychain.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoB3E;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGrE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAElE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE/D;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAElE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE/D;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGzD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKzD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keychain wrapper for secure credential storage
|
|
3
|
+
* Uses keytar for cross-platform keychain access (macOS Keychain, Windows Credential Vault, Linux Secret Service)
|
|
4
|
+
*/
|
|
5
|
+
import * as keytar from 'keytar';
|
|
6
|
+
import { SERVICE_NAME, KEYCHAIN_ACCOUNTS, ENV_VARS } from '../config/defaults.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get a credential from the system keychain
|
|
9
|
+
* Falls back to environment variable if keychain is unavailable
|
|
10
|
+
*
|
|
11
|
+
* @param account - The account name (e.g., 'claude-cli', 'openai-api')
|
|
12
|
+
* @returns The stored credential or null if not found
|
|
13
|
+
*/
|
|
14
|
+
export async function getCredential(account) {
|
|
15
|
+
try {
|
|
16
|
+
const password = await keytar.getPassword(SERVICE_NAME, account);
|
|
17
|
+
if (password) {
|
|
18
|
+
return password;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Keychain unavailable, fall back to environment variables
|
|
23
|
+
console.warn(`Keychain unavailable for ${account}, checking environment variables`);
|
|
24
|
+
}
|
|
25
|
+
// Fallback to environment variables
|
|
26
|
+
if (account === KEYCHAIN_ACCOUNTS.OPENAI) {
|
|
27
|
+
return process.env[ENV_VARS.OPENAI_KEY] || null;
|
|
28
|
+
}
|
|
29
|
+
if (account === KEYCHAIN_ACCOUNTS.CLAUDE) {
|
|
30
|
+
return process.env[ENV_VARS.ANTHROPIC_KEY] || null;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Store a credential in the system keychain
|
|
36
|
+
*
|
|
37
|
+
* @param account - The account name
|
|
38
|
+
* @param password - The credential to store
|
|
39
|
+
*/
|
|
40
|
+
export async function setCredential(account, password) {
|
|
41
|
+
try {
|
|
42
|
+
await keytar.setPassword(SERVICE_NAME, account, password);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new Error(`Failed to store credential in keychain: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Delete a credential from the system keychain
|
|
50
|
+
*
|
|
51
|
+
* @param account - The account name
|
|
52
|
+
* @returns True if the credential was deleted, false if it didn't exist
|
|
53
|
+
*/
|
|
54
|
+
export async function deleteCredential(account) {
|
|
55
|
+
try {
|
|
56
|
+
return await keytar.deletePassword(SERVICE_NAME, account);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.warn(`Failed to delete credential from keychain: ${error}`);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if a credential exists in the keychain
|
|
65
|
+
*
|
|
66
|
+
* @param account - The account name
|
|
67
|
+
* @returns True if the credential exists
|
|
68
|
+
*/
|
|
69
|
+
export async function hasCredential(account) {
|
|
70
|
+
const credential = await getCredential(account);
|
|
71
|
+
return credential !== null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the Claude CLI credential
|
|
75
|
+
*/
|
|
76
|
+
export async function getClaudeCredential() {
|
|
77
|
+
return getCredential(KEYCHAIN_ACCOUNTS.CLAUDE);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Set the Claude CLI credential
|
|
81
|
+
*/
|
|
82
|
+
export async function setClaudeCredential(token) {
|
|
83
|
+
return setCredential(KEYCHAIN_ACCOUNTS.CLAUDE, token);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Delete the Claude CLI credential
|
|
87
|
+
*/
|
|
88
|
+
export async function deleteClaudeCredential() {
|
|
89
|
+
return deleteCredential(KEYCHAIN_ACCOUNTS.CLAUDE);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get the OpenAI API credential
|
|
93
|
+
*/
|
|
94
|
+
export async function getOpenAICredential() {
|
|
95
|
+
return getCredential(KEYCHAIN_ACCOUNTS.OPENAI);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Set the OpenAI API credential
|
|
99
|
+
*/
|
|
100
|
+
export async function setOpenAICredential(apiKey) {
|
|
101
|
+
return setCredential(KEYCHAIN_ACCOUNTS.OPENAI, apiKey);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Delete the OpenAI API credential
|
|
105
|
+
*/
|
|
106
|
+
export async function deleteOpenAICredential() {
|
|
107
|
+
return deleteCredential(KEYCHAIN_ACCOUNTS.OPENAI);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Clear all stored credentials
|
|
111
|
+
*/
|
|
112
|
+
export async function clearAllCredentials() {
|
|
113
|
+
await deleteClaudeCredential();
|
|
114
|
+
await deleteOpenAICredential();
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get the last 4 characters of a credential for display purposes
|
|
118
|
+
*/
|
|
119
|
+
export function maskCredential(credential) {
|
|
120
|
+
if (credential.length <= 4) {
|
|
121
|
+
return '****';
|
|
122
|
+
}
|
|
123
|
+
return `****${credential.slice(-4)}`;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=keychain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/auth/keychain.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACjE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;QAC3D,OAAO,CAAC,IAAI,CAAC,4BAA4B,OAAO,kCAAkC,CAAC,CAAC;IACtF,CAAC;IAED,oCAAoC;IACpC,IAAI,OAAO,KAAK,iBAAiB,CAAC,MAAM,EAAE,CAAC;QACzC,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;IAClD,CAAC;IACD,IAAI,OAAO,KAAK,iBAAiB,CAAC,MAAM,EAAE,CAAC;QACzC,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,QAAgB;IACnE,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,2CAA2C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CACtG,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe;IACpD,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,8CAA8C,KAAK,EAAE,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,UAAU,KAAK,IAAI,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,OAAO,aAAa,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAa;IACrD,OAAO,aAAa,CAAC,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,OAAO,gBAAgB,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,OAAO,aAAa,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAc;IACtD,OAAO,aAAa,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,OAAO,gBAAgB,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,sBAAsB,EAAE,CAAC;IAC/B,MAAM,sBAAsB,EAAE,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI API key entry HTML page
|
|
3
|
+
* Served by the local auth server for browser-based token entry
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generate the HTML for the OpenAI token entry page
|
|
7
|
+
*/
|
|
8
|
+
export declare function getOpenAIEntryHTML(_port: number): string;
|
|
9
|
+
//# sourceMappingURL=openai-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-entry.d.ts","sourceRoot":"","sources":["../../src/auth/openai-entry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiZxD"}
|