legacyver 2.1.2 → 2.1.3

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.
@@ -1,3 +1,5 @@
1
1
  # Summary
2
2
 
3
- * [components.tsx](components.md)
3
+ * [errors.js](errors.md)
4
+ * [config.js](config.md)
5
+ * [logger.js](logger.md)
@@ -1,57 +1,55 @@
1
1
  ## Overview
2
- This file contains React components and a utility function for formatting currency amounts.
2
+ The provided code is a collection of React components and a utility function written in TypeScript. It contains two React components, `Button` and `UserCard`, and a function `formatCurrency` for formatting currency.
3
3
 
4
4
  ## Functions
5
-
6
- ### formatCurrency
7
-
8
- #### Description
9
- Formats a given amount as a string in a specified currency.
10
-
11
- #### Params Table
12
-
13
- | Name | Type |
14
- | --- | --- |
15
- | `amount` | `number` |
16
- | `currency` | `string`, defaults to `'USD'` |
17
-
18
- #### Return Value
19
- A formatted string representing the currency amount.
20
-
21
- ```typescript
22
- export function formatCurrency(amount: number, currency: string = 'USD'): string {
23
- return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount);
24
- }
25
- ```
26
-
27
- ## Dependencies
28
-
29
- * `react`
30
- * `intl`
31
-
32
- ## Overview
33
- This file appears to contain UI components, with buttons and cards used for user representation.
34
-
35
- ## Functions
36
-
37
5
  ### Button
38
- #### Description
39
- A button component that can trigger an action.
40
- #### Params Table
41
- | Param | Type | Required |
6
+ The `Button` component is a React functional component that takes in several props and returns a `button` element.
7
+ #### Parameters
8
+ | Name | Type | Description |
42
9
  | --- | --- | --- |
43
- | - | - | No |
10
+ | label | string | The text to be displayed on the button |
11
+ | onClick | () => void | The function to be called when the button is clicked |
12
+ | disabled | boolean | Whether the button is disabled (optional) |
13
+ | variant | 'primary' | 'secondary' | 'danger' | The style variant of the button (optional) |
44
14
  #### Return Value
45
- N/A
15
+ The `Button` component returns a `button` element with the specified props.
46
16
 
47
17
  ### UserCard
48
- #### Description
49
- A card component representing a user.
50
- #### Params Table
51
- | Param | Type | Required |
18
+ The `UserCard` component is a React functional component that takes in several props and returns a user card.
19
+ #### Parameters
20
+ | Name | Type | Description |
52
21
  | --- | --- | --- |
53
- | - | - | Yes |
22
+ | userId | number | The ID of the user |
23
+ | onClose | () => void | The function to be called when the close button is clicked |
24
+ #### Return Value
25
+ The `UserCard` component returns a `div` element containing the user's information, or a loading message if the data is not available.
26
+
27
+ ### formatCurrency
28
+ The `formatCurrency` function formats a given amount as a currency string.
29
+ #### Parameters
30
+ | Name | Type | Description |
31
+ | --- | --- | --- |
32
+ | amount | number | The amount to be formatted |
33
+ | currency | string | The currency of the amount (optional, defaults to 'USD') |
34
+ #### Return Value
35
+ The `formatCurrency` function returns a string representing the formatted currency.
54
36
 
55
37
  ## Dependencies
56
- * `@ui-component/library` (UI components library)
57
- * `@utils/typography` (Typography utilities)
38
+ * React
39
+ * Intl.NumberFormat (for currency formatting)
40
+
41
+ ## Usage Example
42
+ No clear usage pattern is visible in the provided code. However, the components and function can be used as follows:
43
+ ```tsx
44
+ import { Button, UserCard, formatCurrency } from './components';
45
+
46
+ const Example = () => {
47
+ return (
48
+ <div>
49
+ <Button label="Click me" onClick={() => console.log('Button clicked')} />
50
+ <UserCard userId={1} onClose={() => console.log('User card closed')} />
51
+ <p>Formatted currency: {formatCurrency(1000, 'USD')}</p>
52
+ </div>
53
+ );
54
+ };
55
+ ```
@@ -0,0 +1,30 @@
1
+ ## Overview
2
+ This is a JavaScript module that exports a single function `loadConfig`, which loads configuration from a file and merges with CLI flags.
3
+
4
+ ## Functions
5
+ ### `loadConfig`
6
+
7
+ #### Description:
8
+ Load configuration from file and merge with CLI flags.
9
+ CLI flags always win over file config.
10
+
11
+ #### Params Table:
12
+
13
+ | Name | Type |
14
+ | --- | --- |
15
+ | `cliFlags` | Object |
16
+
17
+ #### Return Value:
18
+ Object
19
+
20
+ ```javascript
21
+ function loadConfig(cliFlags = {}) {
22
+ // ...
23
+ }
24
+ ```
25
+
26
+ ## Dependencies
27
+ * `cosmiconfig: cosmiconfigSync`
28
+
29
+ ## Usage Example
30
+ No clear pattern is visible in the code to demonstrate usage.
@@ -0,0 +1,74 @@
1
+ ## Overview
2
+ This file exports five custom error classes for use in a Legacyver application.
3
+
4
+ ## Functions
5
+
6
+ ### `LegacyverError`
7
+ #### Description
8
+ A base class for all custom errors in Legacyver.
9
+ #### Parameters
10
+ | Name | Type | Default Value |
11
+ | --- | --- | --- |
12
+ | message | string | |
13
+ | code | string | 'LEGACYVER_ERROR' |
14
+
15
+ #### Return Value
16
+ None.
17
+
18
+ ### `NoApiKeyError`
19
+ #### Description
20
+ Raised when no API key is found for a provider.
21
+ #### Parameters
22
+ | Name | Type | Required | Default Value |
23
+ | --- | --- | --- | --- |
24
+ | provider | string | | |
25
+
26
+ #### Return Value
27
+ None.
28
+
29
+ #### Detected Patterns:
30
+ - The error message includes a suggestion to set the `OPENROUTER_API_KEY` environment variable or run `legacyver init`.
31
+ - The error message includes a link to obtain an API key at https://openrouter.ai/keys.
32
+
33
+ ### `RateLimitError`
34
+ #### Description
35
+ Raised when the rate limit is exceeded for a provider.
36
+ #### Parameters
37
+ | Name | Type | Required | Default Value |
38
+ | --- | --- | --- | --- |
39
+ | provider | string | | |
40
+ | retryAfter | number | | 1000 |
41
+
42
+ #### Return Value
43
+ None.
44
+
45
+ #### Detected Patterns:
46
+ - The error message includes a suggestion to retry.
47
+ - The error message indicates the amount of time that must pass before retrying (1000ms by default).
48
+
49
+ ### `ParseError`
50
+ #### Description
51
+ Raised when there is an issue parsing a file.
52
+ #### Parameters
53
+ | Name | Type | Required | Default Value |
54
+ | --- | --- | --- | --- |
55
+ | filePath | string | | |
56
+ | originalError | Error | | |
57
+
58
+ #### Return Value
59
+ None.
60
+
61
+ ### `RenderError`
62
+ #### Description
63
+ Raised when there is an issue rendering a format.
64
+ #### Parameters
65
+ | Name | Type | Required | Default Value |
66
+ | --- | --- | --- | --- |
67
+ | format | string | | |
68
+ | originalError | Error | | |
69
+
70
+ #### Return Value
71
+ None.
72
+
73
+ ## Dependencies
74
+ * `Error`
@@ -1,12 +1,14 @@
1
- # src — Documentation
1
+ # utils — Documentation
2
2
 
3
- **Primary language:** typescript
4
- **Total files:** 1
5
- **Analyzed at:** 2026-02-21T07:52:12.371Z
3
+ **Primary language:** javascript
4
+ **Total files:** 3
5
+ **Analyzed at:** 2026-02-21T08:58:31.525Z
6
6
 
7
7
  ## Files
8
8
 
9
- - [components.tsx](components.md)
9
+ - [errors.js](errors.md)
10
+ - [config.js](config.md)
11
+ - [logger.js](logger.md)
10
12
 
11
13
  ## Dependency Graph
12
14
 
@@ -0,0 +1,83 @@
1
+ ## Overview
2
+ This module provides a logging system with configurable log levels and colorful output.
3
+
4
+ ## Functions
5
+
6
+ ### `setLevel(level)`
7
+ #### Params | Description
8
+ ----------|-------------
9
+ `level` | The desired log level
10
+
11
+ #### Returns
12
+ None
13
+
14
+ Sets the current log level to the specified `level`.
15
+
16
+ ### `setCI(val)`
17
+ #### Params | Description
18
+ ----------|-------------
19
+ `val` | A boolean indicating whether CI mode is enabled
20
+
21
+ #### Returns
22
+ None
23
+
24
+ Toggles the CI mode on or off.
25
+
26
+ ### `shouldLog(level)`
27
+ #### Params | Description
28
+ ----------|-------------
29
+ `level` | The log level to check for
30
+
31
+ #### Returns
32
+ Boolean
33
+ Determines whether the current log level allows logging at the specified `level`.
34
+
35
+ ### `debug(...args)`
36
+ #### Params | Description
37
+ ----------|-------------
38
+ `...args` | Variable number of arguments to be logged as debug output
39
+
40
+ #### Returns
41
+ None
42
+ Logs the provided `args` to the console with a gray '[debug]' prefix if the current log level allows it.
43
+
44
+ ### `info(...args)`
45
+ #### Params | Description
46
+ ----------|-------------
47
+ `...args` | Variable number of arguments to be logged as info output
48
+
49
+ #### Returns
50
+ None
51
+ Logs the provided `args` to the console with a cyan '[info]' prefix if the current log level allows it.
52
+
53
+ ### `warn(...args)`
54
+ #### Params | Description
55
+ ----------|-------------
56
+ `...args` | Variable number of arguments to be logged as warn output
57
+
58
+ #### Returns
59
+ None
60
+ Logs the provided `args` to the console with a yellow '[warn]' prefix if the current log level allows it.
61
+
62
+ ### `error(...args)`
63
+ #### Params | Description
64
+ ----------|-------------
65
+ `...args` | Variable number of arguments to be logged as error output
66
+
67
+ #### Returns
68
+ None
69
+ Logs the provided `args` to the console with a red '[error]' prefix if the current log level allows it.
70
+
71
+ ## Dependencies
72
+ * picocolors (`pc`)
73
+
74
+ ## Usage Example
75
+ ```javascript
76
+ const logger = require('./logger');
77
+
78
+ logger.debug('This is a debug message');
79
+ logger.info('This is an info message');
80
+ logger.warn('This is a warn message');
81
+ logger.error('This is an error message');
82
+ ```
83
+ Note: This example demonstrates the usage of the `debug`, `info`, `warn`, and `error` functions, which are exported from the logger module.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "legacyver",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "AI-powered CLI tool to auto-generate technical documentation from legacy/undocumented codebases",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -1,34 +1,98 @@
1
1
  'use strict';
2
2
 
3
- const SYSTEM_PROMPT = `You are a technical documentation writer. You will be given:
4
- 1. Extracted structural facts about a source file (JSON)
5
- 2. The raw source code of that file
6
-
7
- Your job is to write clear, accurate Markdown documentation based ONLY on what is present in the code.
3
+ const SYSTEM_PROMPT = `You are a technical documentation writer. Given a file's structure and source code, write accurate Markdown documentation based ONLY on what is present.
8
4
 
9
5
  Rules:
10
- - Do NOT infer behavior not explicitly shown in the code
11
- - Do NOT mention external systems unless they appear in imports
12
- - Do NOT fabricate function descriptions
13
- - If a function's purpose is unclear from its body, say so honestly
14
- - Do not mention any function, class, parameter, or behavior that does not appear in the FileFacts JSON or bodySnippet above
15
- - For each function with complexityClass "moderate" or "complex", explain the logic described in the bodySnippet in plain language
16
- - For each function with detectedPatterns[] non-empty, explicitly describe what that pattern does in context
17
-
18
- Temperature: use 0.1 — factual output only.
6
+ - Do NOT infer behavior not shown in the code
7
+ - Do NOT fabricate descriptions
8
+ - For complex functions, explain the logic from the bodySnippet
9
+ - For functions with detectedPatterns, describe what each pattern does
19
10
 
20
- Output format (strict Markdown):
11
+ Output format:
21
12
  ## Overview
22
- [1-2 sentences about what this file does]
13
+ [1-2 sentences]
23
14
 
24
15
  ## Functions
25
- [One ### subsection per exported function with: description, params table, return value]
16
+ [### per function: description, params table, return value]
26
17
 
27
18
  ## Dependencies
28
- [Bullet list of imports with one-line description of each]
19
+ [Bullet list of imports]
29
20
 
30
21
  ## Usage Example
31
- [Only include if a clear usage pattern is visible in the code itself]`;
22
+ [Only if a clear pattern is visible in the code]`;
23
+
24
+ /**
25
+ * Strip null/undefined values and empty arrays from an object (shallow).
26
+ */
27
+ function stripEmpty(obj) {
28
+ const result = {};
29
+ for (const [k, v] of Object.entries(obj)) {
30
+ if (v === null || v === undefined) continue;
31
+ if (Array.isArray(v) && v.length === 0) continue;
32
+ result[k] = v;
33
+ }
34
+ return result;
35
+ }
36
+
37
+ /**
38
+ * Build a slim version of FileFacts for the prompt — remove noise, keep signal.
39
+ */
40
+ function slimFacts(fileFacts) {
41
+ const slim = {
42
+ file: fileFacts.relativePath,
43
+ lang: fileFacts.language,
44
+ lines: fileFacts.linesOfCode,
45
+ };
46
+
47
+ // Functions — only include useful fields
48
+ if (fileFacts.functions && fileFacts.functions.length > 0) {
49
+ slim.functions = fileFacts.functions.map(fn => {
50
+ const entry = { name: fn.name };
51
+ if (fn.params && fn.params.length > 0) {
52
+ entry.params = fn.params.map(p => p.type ? `${p.name}:${p.type}` : p.name);
53
+ }
54
+ if (fn.returnType) entry.returns = fn.returnType;
55
+ if (fn.isExported) entry.exported = true;
56
+ if (fn.isAsync) entry.async = true;
57
+ if (fn.complexityClass && fn.complexityClass !== 'simple') {
58
+ entry.complexity = fn.complexityClass;
59
+ }
60
+ if (fn.detectedPatterns && fn.detectedPatterns.length > 0) {
61
+ entry.patterns = fn.detectedPatterns;
62
+ }
63
+ if (fn.bodySnippet) entry.body = fn.bodySnippet;
64
+ if (fn.calls && fn.calls.length > 0) entry.calls = fn.calls;
65
+ return entry;
66
+ });
67
+ }
68
+
69
+ // Classes
70
+ if (fileFacts.classes && fileFacts.classes.length > 0) {
71
+ slim.classes = fileFacts.classes.map(c => {
72
+ const entry = { name: c.name };
73
+ if (c.superClass) entry.extends = c.superClass;
74
+ if (c.methods && c.methods.length > 0) entry.methods = c.methods.map(m => m.name || m);
75
+ return entry;
76
+ });
77
+ }
78
+
79
+ // Imports — compact
80
+ if (fileFacts.imports && fileFacts.imports.length > 0) {
81
+ slim.imports = fileFacts.imports.map(i => {
82
+ if (i.specifiers && i.specifiers.length > 0) {
83
+ return `${i.module}: ${i.specifiers.join(', ')}`;
84
+ }
85
+ return i.module;
86
+ });
87
+ }
88
+
89
+ // Exports
90
+ if (fileFacts.exports && fileFacts.exports.length > 0) {
91
+ slim.exports = fileFacts.exports;
92
+ }
93
+
94
+ return slim;
95
+ }
32
96
 
33
97
  /**
34
98
  * Build the user message for a single file.
@@ -37,28 +101,22 @@ Output format (strict Markdown):
37
101
  * @returns {string}
38
102
  */
39
103
  function buildUserMessage(fileFacts, rawSource) {
40
- // Include bodySnippets inline in the facts JSON for moderate/complex functions
41
- const factsForPrompt = {
42
- ...fileFacts,
43
- functions: (fileFacts.functions || []).map(fn => {
44
- const entry = { ...fn };
45
- if (fn.complexityClass === 'moderate' || fn.complexityClass === 'complex') {
46
- entry._promptHint = `Explain this function's logic in plain language based on its bodySnippet.`;
47
- }
48
- if (fn.detectedPatterns && fn.detectedPatterns.length > 0) {
49
- entry._patternHint = `This function uses patterns: ${fn.detectedPatterns.join(', ')}. Describe what each does in context.`;
50
- }
51
- return entry;
52
- }),
53
- };
104
+ const slim = slimFacts(fileFacts);
105
+
106
+ // Truncate source to ~150 lines to keep prompt small
107
+ const lines = rawSource.split('\n');
108
+ let source = rawSource;
109
+ if (lines.length > 150) {
110
+ source = lines.slice(0, 150).join('\n') + '\n// ... truncated';
111
+ }
54
112
 
55
- return `FILE FACTS (extracted by static analysis):
56
- ${JSON.stringify(factsForPrompt, null, 2)}
113
+ return `STRUCTURE:
114
+ ${JSON.stringify(slim)}
57
115
 
58
- SOURCE CODE:
59
- ${rawSource}
116
+ CODE:
117
+ ${source}
60
118
 
61
- Generate documentation for this file following the system instructions.`;
119
+ Generate documentation following the system instructions.`;
62
120
  }
63
121
 
64
122
  module.exports = { SYSTEM_PROMPT, buildUserMessage };
@@ -7,7 +7,7 @@ const DEFAULT_MODEL = 'gemini-2.0-flash';
7
7
 
8
8
  class GeminiProvider {
9
9
  constructor(config) {
10
- this.apiKey = config.geminiApiKey || process.env.GEMINI_API_KEY;
10
+ this.apiKey = process.env.GEMINI_API_KEY || config.geminiApiKey;
11
11
  if (!this.apiKey) throw new NoApiKeyError('gemini');
12
12
  this.model = config.model || DEFAULT_MODEL;
13
13
  this.name = 'gemini';
@@ -7,7 +7,7 @@ const DEFAULT_MODEL = 'llama-3.3-70b-versatile';
7
7
 
8
8
  class GroqProvider {
9
9
  constructor(config) {
10
- this.apiKey = config.groqApiKey || process.env.GROQ_API_KEY;
10
+ this.apiKey = process.env.GROQ_API_KEY || config.groqApiKey;
11
11
  if (!this.apiKey) throw new NoApiKeyError('groq');
12
12
  this.model = config.model || DEFAULT_MODEL;
13
13
  this.name = 'groq';
@@ -7,7 +7,7 @@ const DEFAULT_MODEL = 'meta-llama/llama-3.3-70b-instruct:free';
7
7
 
8
8
  class OpenRouterProvider {
9
9
  constructor(config) {
10
- this.apiKey = config.apiKey || process.env.OPENROUTER_API_KEY;
10
+ this.apiKey = process.env.OPENROUTER_API_KEY || config.apiKey;
11
11
  if (!this.apiKey) {
12
12
  throw new NoApiKeyError('openrouter');
13
13
  }