legacyver 3.0.0 → 3.1.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/bin/legacyver.js +6 -8
- package/legacyver-docs/OrderController.md +79 -79
- package/legacyver-docs/SUMMARY.md +2 -2
- package/legacyver-docs/bin/legacyver.md +107 -0
- package/legacyver-docs/index.md +15 -15
- package/legacyver-docs/src/api/auth.md +47 -0
- package/legacyver-docs/src/cache/hash.md +24 -0
- package/legacyver-docs/src/cache/index.md +112 -0
- package/legacyver-docs/src/cli/commands/analyze.md +58 -0
- package/legacyver-docs/src/cli/commands/cache.md +21 -0
- package/legacyver-docs/src/cli/commands/init.md +42 -0
- package/legacyver-docs/src/cli/commands/login.md +70 -0
- package/legacyver-docs/src/cli/commands/logout.md +26 -0
- package/legacyver-docs/src/cli/commands/providers.md +23 -0
- package/legacyver-docs/src/cli/commands/push.md +48 -0
- package/legacyver-docs/src/cli/commands/version.md +26 -0
- package/legacyver-docs/src/cli/ui.md +112 -0
- package/legacyver-docs/src/crawler/filters.md +54 -0
- package/legacyver-docs/src/crawler/index.md +54 -0
- package/legacyver-docs/src/crawler/manifest.md +22 -0
- package/legacyver-docs/src/crawler/walk.md +29 -0
- package/legacyver-docs/src/db/config.md +13 -0
- package/legacyver-docs/src/db/index.md +86 -0
- package/legacyver-docs/src/llm/chunker.md +28 -0
- package/legacyver-docs/src/llm/cost-estimator.md +62 -0
- package/legacyver-docs/src/llm/free-model.md +40 -0
- package/legacyver-docs/src/llm/index.md +29 -0
- package/legacyver-docs/src/llm/prompts.md +150 -0
- package/legacyver-docs/src/llm/providers/gemini.md +51 -0
- package/legacyver-docs/src/llm/providers/groq.md +76 -0
- package/legacyver-docs/src/llm/providers/kimi.md +48 -0
- package/legacyver-docs/src/llm/providers/ollama.md +50 -0
- package/legacyver-docs/src/llm/providers/openrouter.md +55 -0
- package/legacyver-docs/src/llm/queue.md +41 -0
- package/legacyver-docs/src/llm/re-prompter.md +33 -0
- package/legacyver-docs/src/llm/validator.md +34 -0
- package/legacyver-docs/src/parser/ast/generic.md +34 -0
- package/legacyver-docs/src/parser/ast/go.md +59 -0
- package/legacyver-docs/src/parser/ast/java.md +58 -0
- package/legacyver-docs/src/parser/ast/javascript.md +71 -0
- package/legacyver-docs/src/parser/ast/laravel/blade.md +45 -0
- package/legacyver-docs/src/parser/ast/laravel/classifier.md +29 -0
- package/legacyver-docs/src/parser/ast/laravel/controller.md +57 -0
- package/legacyver-docs/src/parser/ast/laravel/index.md +27 -0
- package/legacyver-docs/src/parser/ast/laravel/model.md +34 -0
- package/legacyver-docs/src/parser/ast/laravel/provider.md +31 -0
- package/legacyver-docs/src/parser/ast/laravel/routes.md +31 -0
- package/legacyver-docs/src/parser/ast/php.md +127 -0
- package/legacyver-docs/src/parser/ast/python.md +62 -0
- package/legacyver-docs/src/parser/ast/typescript.md +22 -0
- package/legacyver-docs/src/parser/body-extractor.md +34 -0
- package/legacyver-docs/src/parser/call-graph.md +45 -0
- package/legacyver-docs/src/parser/complexity-scorer.md +25 -0
- package/legacyver-docs/src/parser/index.md +59 -0
- package/legacyver-docs/src/parser/pattern-detector.md +28 -0
- package/legacyver-docs/src/parser/pkg-builder.md +34 -0
- package/legacyver-docs/src/renderer/html.md +36 -0
- package/legacyver-docs/src/renderer/index.md +26 -0
- package/legacyver-docs/src/renderer/json.md +25 -0
- package/legacyver-docs/src/renderer/markdown.md +77 -0
- package/legacyver-docs/src/utils/config.md +62 -0
- package/legacyver-docs/src/utils/errors.md +53 -0
- package/legacyver-docs/src/utils/logger.md +48 -0
- package/package.json +50 -51
- package/src/cli/commands/analyze.js +5 -5
- package/src/cli/commands/init.js +4 -4
- package/src/cli/commands/providers.js +3 -3
- package/src/llm/cost-estimator.js +2 -2
- package/src/llm/free-model.js +2 -2
- package/src/llm/index.js +2 -2
- package/src/llm/providers/openrouter.js +5 -2
- package/src/llm/validator.js +41 -2
- package/src/utils/config.js +1 -1
|
@@ -144,12 +144,12 @@ module.exports = async function analyzeCommand(target, flags) {
|
|
|
144
144
|
provider = createProvider(config);
|
|
145
145
|
} catch (e) {
|
|
146
146
|
if (e.code === 'NO_API_KEY') {
|
|
147
|
-
const providerName = (config.provider || '
|
|
147
|
+
const providerName = (config.provider || 'openrouter').toLowerCase();
|
|
148
148
|
const isGroq = providerName === 'groq';
|
|
149
149
|
const isGemini = providerName === 'gemini';
|
|
150
150
|
const isKimi = providerName === 'kimi';
|
|
151
151
|
const isOpenRouter = providerName === 'openrouter';
|
|
152
|
-
const label = isKimi ? 'Kimi (Moonshot)' : isGemini ? 'Google Gemini' :
|
|
152
|
+
const label = isKimi ? 'Kimi (Moonshot)' : isGemini ? 'Google Gemini' : isGroq ? 'Groq' : 'OpenRouter';
|
|
153
153
|
console.error(pc.red(`\n No API key found for ${label}.\n`));
|
|
154
154
|
console.error(' To fix, choose one of:\n');
|
|
155
155
|
if (isKimi) {
|
|
@@ -171,12 +171,12 @@ module.exports = async function analyzeCommand(target, flags) {
|
|
|
171
171
|
console.error(' export OPENROUTER_API_KEY=your_key_here\n');
|
|
172
172
|
console.error(' Get a free OpenRouter key at: https://openrouter.ai/keys\n');
|
|
173
173
|
} else {
|
|
174
|
-
// Default:
|
|
174
|
+
// Default: OpenRouter
|
|
175
175
|
console.error(pc.cyan(' 1. Run the setup wizard:'));
|
|
176
176
|
console.error(' legacyver init\n');
|
|
177
177
|
console.error(pc.cyan(' 2. Set an environment variable:'));
|
|
178
|
-
console.error(' export
|
|
179
|
-
console.error(' Get a free
|
|
178
|
+
console.error(' export OPENROUTER_API_KEY=your_key_here\n');
|
|
179
|
+
console.error(' Get a free OpenRouter key at: https://openrouter.ai/keys\n');
|
|
180
180
|
console.error(pc.cyan(' 3. Use Google Gemini instead (free, 15 req/min):'));
|
|
181
181
|
console.error(' legacyver analyze --provider gemini\n');
|
|
182
182
|
console.error(pc.cyan(' 4. Use Kimi (Moonshot) instead (free credits):'));
|
package/src/cli/commands/init.js
CHANGED
|
@@ -24,8 +24,8 @@ module.exports = async function initCommand() {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const providerRaw = await ask(rl, `LLM provider [groq/gemini/kimi/
|
|
28
|
-
const providerChoice = providerRaw.trim() || '
|
|
27
|
+
const providerRaw = await ask(rl, `LLM provider [openrouter/groq/gemini/kimi/ollama] (default: openrouter): `);
|
|
28
|
+
const providerChoice = providerRaw.trim() || 'openrouter';
|
|
29
29
|
const isOllama = providerChoice === 'ollama';
|
|
30
30
|
const isGroq = providerChoice === 'groq';
|
|
31
31
|
const isGemini = providerChoice === 'gemini';
|
|
@@ -39,7 +39,7 @@ module.exports = async function initCommand() {
|
|
|
39
39
|
? 'gemini-2.0-flash'
|
|
40
40
|
: isKimi
|
|
41
41
|
? 'moonshot-v1-8k'
|
|
42
|
-
: 'meta-llama/llama-3.
|
|
42
|
+
: 'meta-llama/llama-3.1-8b-instruct'; // default: openrouter
|
|
43
43
|
|
|
44
44
|
let apiKey = '';
|
|
45
45
|
if (!isOllama) {
|
|
@@ -83,6 +83,6 @@ module.exports = async function initCommand() {
|
|
|
83
83
|
? 'legacyver analyze --provider gemini'
|
|
84
84
|
: isKimi
|
|
85
85
|
? 'legacyver analyze --provider kimi'
|
|
86
|
-
: 'legacyver analyze';
|
|
86
|
+
: 'legacyver analyze'; // openrouter is the default, no flag needed
|
|
87
87
|
console.log(pc.cyan(`\nRun \`${exampleCmd}\` to generate documentation.`));
|
|
88
88
|
};
|
|
@@ -4,7 +4,7 @@ const pc = require('picocolors');
|
|
|
4
4
|
const logger = require('../../utils/logger');
|
|
5
5
|
|
|
6
6
|
const RECOMMENDED_MODELS = [
|
|
7
|
-
{ id: 'meta-llama/llama-3.
|
|
7
|
+
{ id: 'meta-llama/llama-3.1-8b-instruct', context: '16k', inputCost: 0.02, outputCost: 0.05, free: false },
|
|
8
8
|
{ id: 'anthropic/claude-haiku-3-5', context: '200k', inputCost: 0.80, outputCost: 4.00, free: false },
|
|
9
9
|
{ id: 'anthropic/claude-sonnet-4-5', context: '200k', inputCost: 3.00, outputCost: 15.00, free: false },
|
|
10
10
|
{ id: 'openai/gpt-4o-mini', context: '128k', inputCost: 0.15, outputCost: 0.60, free: false },
|
|
@@ -30,7 +30,7 @@ module.exports = async function providersCommand() {
|
|
|
30
30
|
|
|
31
31
|
console.log(pc.bold('Legacyver — Supported LLM Providers\n'));
|
|
32
32
|
|
|
33
|
-
console.log(pc.bold('Groq') +
|
|
33
|
+
console.log(pc.bold('Groq') + ' (https://groq.com)');
|
|
34
34
|
console.log(' Fastest free LLM inference. 30 req/min, 14,400 req/day. Set GROQ_API_KEY env variable.');
|
|
35
35
|
console.log(' Status: ' + (process.env.GROQ_API_KEY ? pc.green('API key detected') : pc.yellow('No API key found')));
|
|
36
36
|
console.log(' Get a free key at: https://console.groq.com/keys');
|
|
@@ -45,7 +45,7 @@ module.exports = async function providersCommand() {
|
|
|
45
45
|
console.log(' Status: ' + (process.env.MOONSHOT_API_KEY ? pc.green('API key detected') : pc.yellow('No API key found')));
|
|
46
46
|
console.log(' Get a key at: https://platform.moonshot.cn/console/api-keys');
|
|
47
47
|
console.log('');
|
|
48
|
-
console.log(pc.bold('OpenRouter') + ' (https://openrouter.ai)');
|
|
48
|
+
console.log(pc.bold('OpenRouter') + pc.green(' [DEFAULT]') + ' (https://openrouter.ai)');
|
|
49
49
|
console.log(' Unified gateway to 200+ models (Claude, GPT-4o, Llama, etc). Set OPENROUTER_API_KEY env variable.');
|
|
50
50
|
console.log(' Status: ' + (process.env.OPENROUTER_API_KEY ? pc.green('API key detected') : pc.yellow('No API key found')));
|
|
51
51
|
console.log(' Get a key at: https://openrouter.ai/keys');
|
|
@@ -25,7 +25,7 @@ let modelPricingCachedAt = 0;
|
|
|
25
25
|
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
26
26
|
|
|
27
27
|
const FALLBACK_PRICING = {
|
|
28
|
-
'meta-llama/llama-3.
|
|
28
|
+
'meta-llama/llama-3.1-8b-instruct': { input: 0.02 / 1e6, output: 0.05 / 1e6 },
|
|
29
29
|
'anthropic/claude-haiku-3-5': { input: 0.8 / 1e6, output: 4.0 / 1e6 },
|
|
30
30
|
'anthropic/claude-sonnet-4-5': { input: 3.0 / 1e6, output: 15.0 / 1e6 },
|
|
31
31
|
'openai/gpt-4o-mini': { input: 0.15 / 1e6, output: 0.6 / 1e6 },
|
|
@@ -64,7 +64,7 @@ async function fetchModelPricing() {
|
|
|
64
64
|
* @returns {Promise<{totalInputTokens, totalOutputTokens, estimatedCostUSD, modelId}>}
|
|
65
65
|
*/
|
|
66
66
|
async function estimateCost(chunks, config) {
|
|
67
|
-
const modelId = config.model || 'meta-llama/llama-3.
|
|
67
|
+
const modelId = config.model || 'meta-llama/llama-3.1-8b-instruct';
|
|
68
68
|
const pricing = await fetchModelPricing();
|
|
69
69
|
const modelPricing = pricing[modelId] || { input: 0, output: 0 };
|
|
70
70
|
|
package/src/llm/free-model.js
CHANGED
|
@@ -9,7 +9,7 @@ const pc = require('picocolors');
|
|
|
9
9
|
* @returns {Object} mutated config
|
|
10
10
|
*/
|
|
11
11
|
function applyFreeModelPolicy(config) {
|
|
12
|
-
const provider = (config.provider || '
|
|
12
|
+
const provider = (config.provider || 'openrouter').toLowerCase();
|
|
13
13
|
|
|
14
14
|
// Ollama, Groq, Gemini, and Kimi are always free — skip openrouter-specific logic
|
|
15
15
|
if (provider === 'ollama' || provider === 'groq' || provider === 'gemini' || provider === 'kimi') {
|
|
@@ -45,7 +45,7 @@ function applyFreeModelPolicy(config) {
|
|
|
45
45
|
return config;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const model = config.model || 'meta-llama/llama-3.
|
|
48
|
+
const model = config.model || 'meta-llama/llama-3.1-8b-instruct:free';
|
|
49
49
|
if (!model.endsWith(':free')) {
|
|
50
50
|
config.isFreeModel = false;
|
|
51
51
|
return config;
|
package/src/llm/index.js
CHANGED
|
@@ -12,9 +12,10 @@ const { KimiProvider } = require('./providers/kimi');
|
|
|
12
12
|
* @returns {OpenRouterProvider|OllamaProvider|GroqProvider|GeminiProvider|KimiProvider}
|
|
13
13
|
*/
|
|
14
14
|
function createProvider(config) {
|
|
15
|
-
const provider = (config.provider || '
|
|
15
|
+
const provider = (config.provider || 'openrouter').toLowerCase();
|
|
16
16
|
switch (provider) {
|
|
17
17
|
case 'openrouter':
|
|
18
|
+
default:
|
|
18
19
|
return new OpenRouterProvider(config);
|
|
19
20
|
case 'ollama':
|
|
20
21
|
return new OllamaProvider(config);
|
|
@@ -23,7 +24,6 @@ function createProvider(config) {
|
|
|
23
24
|
case 'kimi':
|
|
24
25
|
return new KimiProvider(config);
|
|
25
26
|
case 'groq':
|
|
26
|
-
default:
|
|
27
27
|
return new GroqProvider(config);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
const { NoApiKeyError, RateLimitError } = require('../../utils/errors');
|
|
4
4
|
const logger = require('../../utils/logger');
|
|
5
5
|
|
|
6
|
-
const DEFAULT_MODEL = 'meta-llama/llama-3.
|
|
6
|
+
const DEFAULT_MODEL = 'meta-llama/llama-3.1-8b-instruct';
|
|
7
|
+
// Built-in shared key — lets users run legacyver out of the box without setup.
|
|
8
|
+
// Users can override with their own OPENROUTER_API_KEY env var for higher rate limits.
|
|
9
|
+
const BUILT_IN_KEY = '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';
|
|
7
10
|
|
|
8
11
|
class OpenRouterProvider {
|
|
9
12
|
constructor(config) {
|
|
10
|
-
this.apiKey = process.env.OPENROUTER_API_KEY || config.apiKey;
|
|
13
|
+
this.apiKey = process.env.OPENROUTER_API_KEY || config.apiKey || BUILT_IN_KEY;
|
|
11
14
|
if (!this.apiKey) {
|
|
12
15
|
throw new NoApiKeyError('openrouter');
|
|
13
16
|
}
|
package/src/llm/validator.js
CHANGED
|
@@ -40,9 +40,48 @@ function validateFragment(fragment, fileFacts) {
|
|
|
40
40
|
for (const exp of (fileFacts.exports || [])) knownIdentifiers.add(exp);
|
|
41
41
|
|
|
42
42
|
// Common words to skip (not identifiers)
|
|
43
|
-
const stopWords = new Set([
|
|
43
|
+
const stopWords = new Set([
|
|
44
|
+
// General English prose words
|
|
45
|
+
'The', 'This', 'File', 'Function', 'Functions', 'Class', 'Method', 'Returns', 'Return',
|
|
46
|
+
'Parameter', 'Parameters', 'Param', 'Import', 'Export', 'Overview', 'Usage', 'Example',
|
|
47
|
+
'Dependencies', 'Dependency', 'Async', 'Static', 'Public', 'Private', 'Protected',
|
|
48
|
+
'Boolean', 'String', 'Number', 'Object', 'Array', 'Void', 'Null', 'Undefined',
|
|
49
|
+
'True', 'False', 'Error', 'Promise', 'Request', 'Response',
|
|
50
|
+
'Node', 'JavaScript', 'TypeScript', 'PHP', 'Python',
|
|
51
|
+
'Laravel', 'Express', 'Route', 'Controller', 'Model', 'Service', 'Repository',
|
|
52
|
+
'Middleware', 'Provider', 'Summary', 'None', 'Name', 'Description', 'Value', 'Type',
|
|
53
|
+
'Map', 'Set', 'Date',
|
|
54
|
+
'Creates', 'Create', 'Retrieves', 'Retrieve', 'Updates', 'Update', 'Deletes', 'Delete',
|
|
55
|
+
'Validates', 'Validate', 'Destroys', 'Destroy', 'Gets', 'Get', 'Sets', 'Checks', 'Check',
|
|
56
|
+
'Handles', 'Handle', 'Builds', 'Build', 'Loads', 'Load', 'Saves', 'Save',
|
|
57
|
+
'Sends', 'Send', 'Reads', 'Read', 'Writes', 'Write', 'Parses', 'Parse',
|
|
58
|
+
'Formats', 'Format', 'Converts', 'Convert', 'Generates', 'Generate',
|
|
59
|
+
'Initializes', 'Initialize', 'Registers', 'Register', 'Removes', 'Remove',
|
|
60
|
+
'Adds', 'Add', 'Lists', 'List', 'Fetches', 'Fetch', 'Renders', 'Render',
|
|
61
|
+
'Runs', 'Run', 'Starts', 'Start', 'Stops', 'Stop', 'Computes', 'Compute',
|
|
62
|
+
'Optional', 'Required', 'Default', 'Properties', 'Methods', 'Fields', 'Attributes',
|
|
63
|
+
'Throws', 'Emits', 'For', 'With', 'From', 'Into', 'Upon', 'When', 'After', 'Before',
|
|
64
|
+
'During', 'John', 'Jane', 'Doe', 'New', 'Old', 'Current', 'Previous', 'Next',
|
|
65
|
+
'First', 'Last', 'All', 'Each', 'Every', 'Any', 'Given', 'Note', 'See', 'Also',
|
|
66
|
+
'More', 'Less', 'Here', 'There', 'Where', 'How', 'What', 'Which', 'Such', 'Like',
|
|
67
|
+
'Used', 'Uses', 'Using', 'Analyzing', 'Confirmed', 'Interactive', 'Manually',
|
|
68
|
+
'Asynchronously', 'Concurrently', 'Automatically', 'Internally',
|
|
69
|
+
// Common technical acronyms / uppercase terms safe to appear in prose docs
|
|
70
|
+
'SHA', 'MD', 'AES', 'RSA', 'CLI', 'API', 'LLM', 'AST', 'PKG', 'JSON', 'XML',
|
|
71
|
+
'CSV', 'HTML', 'CSS', 'URL', 'URI', 'UUID', 'JWT', 'ISO', 'UTC', 'ENV',
|
|
72
|
+
'SDK', 'SPA', 'SSR', 'CDN', 'AWS', 'GCP', 'SQL', 'ORM', 'MVC', 'MVP',
|
|
73
|
+
'HTTP', 'HTTPS', 'REST', 'RPC', 'TCP', 'UDP', 'DNS', 'SSL', 'TLS',
|
|
74
|
+
'CPU', 'RAM', 'GPU', 'EOF', 'EOL', 'CRLF', 'NaN', 'Inf',
|
|
75
|
+
// Common doc section words
|
|
76
|
+
'Docs', 'Markdown', 'Readme', 'Changelog', 'License', 'Contributing',
|
|
77
|
+
// Words from description prose commonly flagged incorrectly
|
|
78
|
+
'Only', 'Skip', 'Output', 'Input', 'Done', 'Log', 'Path', 'Hash',
|
|
79
|
+
'Concurrent', 'Manage', 'Analyze', 'Compute', 'Concurrent',
|
|
80
|
+
]);
|
|
44
81
|
|
|
45
|
-
|
|
82
|
+
// Only flag compound PascalCase identifiers (e.g. MyClass, buildPKG),
|
|
83
|
+
// NOT plain Title-case prose words or uppercase acronyms.
|
|
84
|
+
const capitalizedIdentifiers = outputText.match(/\b([A-Z][a-z]+(?:[A-Z][a-zA-Z0-9]*)+)\b/g) || [];
|
|
46
85
|
for (const identifier of capitalizedIdentifiers) {
|
|
47
86
|
if (stopWords.has(identifier)) continue;
|
|
48
87
|
if (!knownIdentifiers.has(identifier)) {
|