feature-architect-agent 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/README.md +704 -0
- package/bin/feature-architect.js +2 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +63 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +125 -0
- package/dist/commands/plan.d.ts +6 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +147 -0
- package/dist/commands/verify.d.ts +2 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +101 -0
- package/dist/config/api.config.d.ts +49 -0
- package/dist/config/api.config.d.ts.map +1 -0
- package/dist/config/api.config.js +78 -0
- package/dist/llm/Claude.d.ts +8 -0
- package/dist/llm/Claude.d.ts.map +1 -0
- package/dist/llm/Claude.js +44 -0
- package/dist/llm/OpenAI.d.ts +8 -0
- package/dist/llm/OpenAI.d.ts.map +1 -0
- package/dist/llm/OpenAI.js +43 -0
- package/dist/llm/factory.d.ts +9 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +36 -0
- package/dist/llm/types.d.ts +8 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +2 -0
- package/dist/services/Analyzer.d.ts +18 -0
- package/dist/services/Analyzer.d.ts.map +1 -0
- package/dist/services/Analyzer.js +235 -0
- package/dist/services/ContextManager.d.ts +16 -0
- package/dist/services/ContextManager.d.ts.map +1 -0
- package/dist/services/ContextManager.js +82 -0
- package/dist/services/Planner.d.ts +16 -0
- package/dist/services/Planner.d.ts.map +1 -0
- package/dist/services/Planner.js +181 -0
- package/dist/services/Scanner.d.ts +17 -0
- package/dist/services/Scanner.d.ts.map +1 -0
- package/dist/services/Scanner.js +75 -0
- package/dist/types/index.d.ts +90 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/utils/logger.d.ts +22 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +56 -0
- package/package.json +48 -0
- package/src/config/api.config.ts +79 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ScanConfig } from '../types/index.js';
|
|
2
|
+
export declare class ScannerService {
|
|
3
|
+
private defaultExclude;
|
|
4
|
+
private defaultInclude;
|
|
5
|
+
scan(config?: Partial<ScanConfig>): Promise<string[]>;
|
|
6
|
+
scanWithStats(config?: Partial<ScanConfig>): Promise<{
|
|
7
|
+
files: string[];
|
|
8
|
+
stats: ScanStats;
|
|
9
|
+
}>;
|
|
10
|
+
private getLanguage;
|
|
11
|
+
}
|
|
12
|
+
export interface ScanStats {
|
|
13
|
+
total: number;
|
|
14
|
+
byLanguage: Record<string, number>;
|
|
15
|
+
byDirectory: Record<string, number>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=Scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.d.ts","sourceRoot":"","sources":["../../src/services/Scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAapB;IAEF,OAAO,CAAC,cAAc,CAOpB;IAEI,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBrD,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IAwBjG,OAAO,CAAC,WAAW;CAWpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ScannerService = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const glob_1 = require("glob");
|
|
9
|
+
class ScannerService {
|
|
10
|
+
defaultExclude = [
|
|
11
|
+
'node_modules/**',
|
|
12
|
+
'.git/**',
|
|
13
|
+
'dist/**',
|
|
14
|
+
'build/**',
|
|
15
|
+
'coverage/**',
|
|
16
|
+
'.next/**',
|
|
17
|
+
'out/**',
|
|
18
|
+
'**/*.test.ts',
|
|
19
|
+
'**/*.test.js',
|
|
20
|
+
'**/*.spec.ts',
|
|
21
|
+
'**/*.spec.js',
|
|
22
|
+
'**/.*'
|
|
23
|
+
];
|
|
24
|
+
defaultInclude = [
|
|
25
|
+
'**/*.ts',
|
|
26
|
+
'**/*.tsx',
|
|
27
|
+
'**/*.js',
|
|
28
|
+
'**/*.jsx',
|
|
29
|
+
'**/*.sql',
|
|
30
|
+
'**/*.prisma'
|
|
31
|
+
];
|
|
32
|
+
async scan(config) {
|
|
33
|
+
const root = config?.root || process.cwd();
|
|
34
|
+
const include = config?.include || this.defaultInclude;
|
|
35
|
+
const exclude = config?.exclude || this.defaultExclude;
|
|
36
|
+
const patterns = include.map(p => `!(${exclude.map(e => e.replace(/\*\*/g, '')).join('|')})/${p}`);
|
|
37
|
+
const files = await (0, glob_1.glob)(include, {
|
|
38
|
+
cwd: root,
|
|
39
|
+
ignore: exclude,
|
|
40
|
+
absolute: true,
|
|
41
|
+
nodir: true
|
|
42
|
+
});
|
|
43
|
+
return files.sort();
|
|
44
|
+
}
|
|
45
|
+
async scanWithStats(config) {
|
|
46
|
+
const files = await this.scan(config);
|
|
47
|
+
const stats = {
|
|
48
|
+
total: files.length,
|
|
49
|
+
byLanguage: {},
|
|
50
|
+
byDirectory: {}
|
|
51
|
+
};
|
|
52
|
+
for (const file of files) {
|
|
53
|
+
const ext = path_1.default.extname(file);
|
|
54
|
+
const lang = this.getLanguage(ext);
|
|
55
|
+
stats.byLanguage[lang] = (stats.byLanguage[lang] || 0) + 1;
|
|
56
|
+
const dir = path_1.default.relative(process.cwd(), path_1.default.dirname(file));
|
|
57
|
+
const dirParts = dir.split(path_1.default.sep);
|
|
58
|
+
const topLevel = dirParts[0] || 'root';
|
|
59
|
+
stats.byDirectory[topLevel] = (stats.byDirectory[topLevel] || 0) + 1;
|
|
60
|
+
}
|
|
61
|
+
return { files, stats };
|
|
62
|
+
}
|
|
63
|
+
getLanguage(ext) {
|
|
64
|
+
const map = {
|
|
65
|
+
'.ts': 'TypeScript',
|
|
66
|
+
'.tsx': 'TypeScript React',
|
|
67
|
+
'.js': 'JavaScript',
|
|
68
|
+
'.jsx': 'JavaScript React',
|
|
69
|
+
'.sql': 'SQL',
|
|
70
|
+
'.prisma': 'Prisma'
|
|
71
|
+
};
|
|
72
|
+
return map[ext] || 'Other';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.ScannerService = ScannerService;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export interface ScanConfig {
|
|
2
|
+
root: string;
|
|
3
|
+
include: string[];
|
|
4
|
+
exclude: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface CodebasePatterns {
|
|
7
|
+
apiRoutes: APIRoute[];
|
|
8
|
+
databaseSchemas: DatabaseSchema[];
|
|
9
|
+
components: Component[];
|
|
10
|
+
types: TypeDefinition[];
|
|
11
|
+
utilities: Utility[];
|
|
12
|
+
}
|
|
13
|
+
export interface APIRoute {
|
|
14
|
+
file: string;
|
|
15
|
+
line: number;
|
|
16
|
+
method: string;
|
|
17
|
+
path: string;
|
|
18
|
+
handler: string;
|
|
19
|
+
}
|
|
20
|
+
export interface DatabaseSchema {
|
|
21
|
+
file: string;
|
|
22
|
+
line: number;
|
|
23
|
+
type: 'table' | 'view' | 'migration';
|
|
24
|
+
name: string;
|
|
25
|
+
definition?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface Component {
|
|
28
|
+
file: string;
|
|
29
|
+
line: number;
|
|
30
|
+
name: string;
|
|
31
|
+
type: string;
|
|
32
|
+
props?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface TypeDefinition {
|
|
35
|
+
file: string;
|
|
36
|
+
line: number;
|
|
37
|
+
name: string;
|
|
38
|
+
kind: 'interface' | 'type' | 'enum';
|
|
39
|
+
}
|
|
40
|
+
export interface Utility {
|
|
41
|
+
file: string;
|
|
42
|
+
line: number;
|
|
43
|
+
name: string;
|
|
44
|
+
exportType: 'named' | 'default';
|
|
45
|
+
}
|
|
46
|
+
export interface CodebaseContext {
|
|
47
|
+
project: {
|
|
48
|
+
name: string;
|
|
49
|
+
type: string;
|
|
50
|
+
root: string;
|
|
51
|
+
};
|
|
52
|
+
summary: {
|
|
53
|
+
totalFiles: number;
|
|
54
|
+
languages: Record<string, number>;
|
|
55
|
+
frameworks: string[];
|
|
56
|
+
patterns: number;
|
|
57
|
+
};
|
|
58
|
+
frameworks: {
|
|
59
|
+
backend?: string;
|
|
60
|
+
frontend?: string;
|
|
61
|
+
database?: string;
|
|
62
|
+
orm?: string;
|
|
63
|
+
};
|
|
64
|
+
patterns: CodebasePatterns;
|
|
65
|
+
metadata: {
|
|
66
|
+
version: string;
|
|
67
|
+
analyzedAt: string;
|
|
68
|
+
hash: string;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface FeaturePlan {
|
|
72
|
+
id: string;
|
|
73
|
+
feature: string;
|
|
74
|
+
slug: string;
|
|
75
|
+
createdAt: string;
|
|
76
|
+
markdown: string;
|
|
77
|
+
}
|
|
78
|
+
export interface AIConfig {
|
|
79
|
+
provider: 'claude' | 'openai' | 'gemini' | 'opencode' | 'ollama';
|
|
80
|
+
model?: string;
|
|
81
|
+
apiKey?: string;
|
|
82
|
+
endpoint?: string;
|
|
83
|
+
temperature?: number;
|
|
84
|
+
maxTokens?: number;
|
|
85
|
+
}
|
|
86
|
+
export interface GenerateOptions {
|
|
87
|
+
temperature?: number;
|
|
88
|
+
maxTokens?: number;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const colors: {
|
|
2
|
+
reset: string;
|
|
3
|
+
red: string;
|
|
4
|
+
green: string;
|
|
5
|
+
yellow: string;
|
|
6
|
+
blue: string;
|
|
7
|
+
magenta: string;
|
|
8
|
+
cyan: string;
|
|
9
|
+
gray: string;
|
|
10
|
+
bright: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function log(message: string): void;
|
|
13
|
+
export declare function info(message: string): void;
|
|
14
|
+
export declare function success(message: string): void;
|
|
15
|
+
export declare function warn(message: string): void;
|
|
16
|
+
export declare function error(message: string): void;
|
|
17
|
+
export declare function dim(message: string): void;
|
|
18
|
+
export declare function header(message: string): void;
|
|
19
|
+
export declare function bullet(message: string, indent?: number): void;
|
|
20
|
+
export declare function check(message: string): void;
|
|
21
|
+
export declare function cross(message: string): void;
|
|
22
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;;;;;;;;;;CAUlB,CAAC;AAEF,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,IAAI,CAGhE;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Simple logger utilities (chalk replacement for minimal dependencies)
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.colors = void 0;
|
|
5
|
+
exports.log = log;
|
|
6
|
+
exports.info = info;
|
|
7
|
+
exports.success = success;
|
|
8
|
+
exports.warn = warn;
|
|
9
|
+
exports.error = error;
|
|
10
|
+
exports.dim = dim;
|
|
11
|
+
exports.header = header;
|
|
12
|
+
exports.bullet = bullet;
|
|
13
|
+
exports.check = check;
|
|
14
|
+
exports.cross = cross;
|
|
15
|
+
exports.colors = {
|
|
16
|
+
reset: '\x1b[0m',
|
|
17
|
+
red: '\x1b[31m',
|
|
18
|
+
green: '\x1b[32m',
|
|
19
|
+
yellow: '\x1b[33m',
|
|
20
|
+
blue: '\x1b[34m',
|
|
21
|
+
magenta: '\x1b[35m',
|
|
22
|
+
cyan: '\x1b[36m',
|
|
23
|
+
gray: '\x1b[90m',
|
|
24
|
+
bright: '\x1b[1m'
|
|
25
|
+
};
|
|
26
|
+
function log(message) {
|
|
27
|
+
console.log(message);
|
|
28
|
+
}
|
|
29
|
+
function info(message) {
|
|
30
|
+
console.log(`${exports.colors.blue}${message}${exports.colors.reset}`);
|
|
31
|
+
}
|
|
32
|
+
function success(message) {
|
|
33
|
+
console.log(`${exports.colors.green}${message}${exports.colors.reset}`);
|
|
34
|
+
}
|
|
35
|
+
function warn(message) {
|
|
36
|
+
console.log(`${exports.colors.yellow}${message}${exports.colors.reset}`);
|
|
37
|
+
}
|
|
38
|
+
function error(message) {
|
|
39
|
+
console.error(`${exports.colors.red}${message}${exports.colors.reset}`);
|
|
40
|
+
}
|
|
41
|
+
function dim(message) {
|
|
42
|
+
console.log(`${exports.colors.gray}${message}${exports.colors.reset}`);
|
|
43
|
+
}
|
|
44
|
+
function header(message) {
|
|
45
|
+
console.log(`\n${exports.colors.bright}${exports.colors.cyan}${message}${exports.colors.reset}\n`);
|
|
46
|
+
}
|
|
47
|
+
function bullet(message, indent = 0) {
|
|
48
|
+
const prefix = ' '.repeat(indent);
|
|
49
|
+
console.log(`${prefix}${exports.colors.cyan}•${exports.colors.reset} ${message}`);
|
|
50
|
+
}
|
|
51
|
+
function check(message) {
|
|
52
|
+
console.log(`${exports.colors.green}✓${exports.colors.reset} ${message}`);
|
|
53
|
+
}
|
|
54
|
+
function cross(message) {
|
|
55
|
+
console.log(`${exports.colors.red}✗${exports.colors.reset} ${message}`);
|
|
56
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "feature-architect-agent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI-powered feature planning agent - generates complete technical specifications",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"feature-architect": "./bin/feature-architect.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"bin",
|
|
12
|
+
"src/config"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"start": "node bin/feature-architect.js",
|
|
18
|
+
"plan": "node bin/feature-architect.js plan",
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"prepack": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"cli",
|
|
24
|
+
"ai",
|
|
25
|
+
"feature-planning",
|
|
26
|
+
"architecture",
|
|
27
|
+
"documentation",
|
|
28
|
+
"codebase-analysis"
|
|
29
|
+
],
|
|
30
|
+
"author": "sahilshaikh-cyber",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"commander": "^12.1.0",
|
|
34
|
+
"chalk": "^5.4.1",
|
|
35
|
+
"ora": "^8.1.1",
|
|
36
|
+
"inquirer": "^9.3.7",
|
|
37
|
+
"glob": "^11.0.0",
|
|
38
|
+
"dotenv": "^16.4.7"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^22.10.5",
|
|
42
|
+
"@types/inquirer": "^9.0.7",
|
|
43
|
+
"typescript": "^5.7.3"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in API Configuration for Internal Team Use
|
|
3
|
+
*
|
|
4
|
+
* This file contains the pre-configured API key for team use.
|
|
5
|
+
* The package is published to a private registry for internal team access.
|
|
6
|
+
*
|
|
7
|
+
* SECURITY: This file is included in the published package.
|
|
8
|
+
* Only publish to PRIVATE npm registries (GitHub Packages, npm private, etc.)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const API_CONFIG = {
|
|
12
|
+
/**
|
|
13
|
+
* Built-in OpenAI API Key for team use
|
|
14
|
+
* Replace with your actual team API key
|
|
15
|
+
*/
|
|
16
|
+
openai: {
|
|
17
|
+
apiKey: process.env.TEAM_OPENAI_API_KEY || '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',
|
|
18
|
+
baseURL: 'https://api.openai.com/v1',
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Built-in Anthropic API Key (optional)
|
|
23
|
+
*/
|
|
24
|
+
anthropic: {
|
|
25
|
+
apiKey: process.env.TEAM_ANTHROPIC_API_KEY || '',
|
|
26
|
+
baseURL: 'https://api.anthropic.com',
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Built-in Google API Key (optional)
|
|
31
|
+
*/
|
|
32
|
+
google: {
|
|
33
|
+
apiKey: process.env.TEAM_GOOGLE_API_KEY || '',
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Default provider to use when no user key is set
|
|
38
|
+
*/
|
|
39
|
+
defaultProvider: 'openai' as const,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get the built-in API key for a provider
|
|
44
|
+
*/
|
|
45
|
+
export function getBuiltinKey(provider: 'openai' | 'anthropic' | 'google'): string | undefined {
|
|
46
|
+
switch (provider) {
|
|
47
|
+
case 'openai':
|
|
48
|
+
return API_CONFIG.openai.apiKey || undefined;
|
|
49
|
+
case 'anthropic':
|
|
50
|
+
return API_CONFIG.anthropic.apiKey || undefined;
|
|
51
|
+
case 'google':
|
|
52
|
+
return API_CONFIG.google.apiKey || undefined;
|
|
53
|
+
default:
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Check if a built-in key is available
|
|
60
|
+
*/
|
|
61
|
+
export function hasBuiltinKey(provider: 'openai' | 'anthropic' | 'google'): boolean {
|
|
62
|
+
const key = getBuiltinKey(provider);
|
|
63
|
+
return !!key && key !== '' && !key.startsWith('sk-');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get the best available API key (user env var first, then built-in)
|
|
68
|
+
*/
|
|
69
|
+
export function getApiKey(provider: 'openai' | 'anthropic' | 'google'): string | undefined {
|
|
70
|
+
// First check user's environment variable
|
|
71
|
+
const userKey = process.env[`${provider.toUpperCase()}_API_KEY`];
|
|
72
|
+
if (userKey) return userKey;
|
|
73
|
+
|
|
74
|
+
// Then check generic AI_API_KEY
|
|
75
|
+
if (process.env.AI_API_KEY) return process.env.AI_API_KEY;
|
|
76
|
+
|
|
77
|
+
// Finally fall back to built-in key
|
|
78
|
+
return getBuiltinKey(provider);
|
|
79
|
+
}
|