legacyver 2.1.0 → 2.1.2

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.
Files changed (126) hide show
  1. package/.agent/skills/openspec-apply-change/SKILL.md +156 -0
  2. package/.agent/skills/openspec-archive-change/SKILL.md +114 -0
  3. package/.agent/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  4. package/.agent/skills/openspec-continue-change/SKILL.md +118 -0
  5. package/.agent/skills/openspec-explore/SKILL.md +290 -0
  6. package/.agent/skills/openspec-ff-change/SKILL.md +101 -0
  7. package/.agent/skills/openspec-new-change/SKILL.md +74 -0
  8. package/.agent/skills/openspec-onboard/SKILL.md +529 -0
  9. package/.agent/skills/openspec-sync-specs/SKILL.md +138 -0
  10. package/.agent/skills/openspec-verify-change/SKILL.md +168 -0
  11. package/.agent/workflows/opsx-apply.md +149 -0
  12. package/.agent/workflows/opsx-archive.md +154 -0
  13. package/.agent/workflows/opsx-bulk-archive.md +239 -0
  14. package/.agent/workflows/opsx-continue.md +111 -0
  15. package/.agent/workflows/opsx-explore.md +171 -0
  16. package/.agent/workflows/opsx-ff.md +91 -0
  17. package/.agent/workflows/opsx-new.md +66 -0
  18. package/.agent/workflows/opsx-onboard.md +522 -0
  19. package/.agent/workflows/opsx-sync.md +131 -0
  20. package/.agent/workflows/opsx-verify.md +161 -0
  21. package/.github/prompts/opsx-apply.prompt.md +149 -0
  22. package/.github/prompts/opsx-archive.prompt.md +154 -0
  23. package/.github/prompts/opsx-bulk-archive.prompt.md +239 -0
  24. package/.github/prompts/opsx-continue.prompt.md +111 -0
  25. package/.github/prompts/opsx-explore.prompt.md +171 -0
  26. package/.github/prompts/opsx-ff.prompt.md +91 -0
  27. package/.github/prompts/opsx-new.prompt.md +66 -0
  28. package/.github/prompts/opsx-onboard.prompt.md +522 -0
  29. package/.github/prompts/opsx-sync.prompt.md +131 -0
  30. package/.github/prompts/opsx-verify.prompt.md +161 -0
  31. package/.github/skills/openspec-apply-change/SKILL.md +156 -0
  32. package/.github/skills/openspec-archive-change/SKILL.md +114 -0
  33. package/.github/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  34. package/.github/skills/openspec-continue-change/SKILL.md +118 -0
  35. package/.github/skills/openspec-explore/SKILL.md +290 -0
  36. package/.github/skills/openspec-ff-change/SKILL.md +101 -0
  37. package/.github/skills/openspec-new-change/SKILL.md +74 -0
  38. package/.github/skills/openspec-onboard/SKILL.md +529 -0
  39. package/.github/skills/openspec-sync-specs/SKILL.md +138 -0
  40. package/.github/skills/openspec-verify-change/SKILL.md +168 -0
  41. package/.legacyverignore.example +43 -0
  42. package/.legacyverrc +7 -0
  43. package/.opencode/command/opsx-apply.md +149 -0
  44. package/.opencode/command/opsx-archive.md +154 -0
  45. package/.opencode/command/opsx-bulk-archive.md +239 -0
  46. package/.opencode/command/opsx-continue.md +111 -0
  47. package/.opencode/command/opsx-explore.md +171 -0
  48. package/.opencode/command/opsx-ff.md +91 -0
  49. package/.opencode/command/opsx-new.md +66 -0
  50. package/.opencode/command/opsx-onboard.md +522 -0
  51. package/.opencode/command/opsx-sync.md +131 -0
  52. package/.opencode/command/opsx-verify.md +161 -0
  53. package/.opencode/skills/openspec-apply-change/SKILL.md +156 -0
  54. package/.opencode/skills/openspec-archive-change/SKILL.md +114 -0
  55. package/.opencode/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  56. package/.opencode/skills/openspec-continue-change/SKILL.md +118 -0
  57. package/.opencode/skills/openspec-explore/SKILL.md +290 -0
  58. package/.opencode/skills/openspec-ff-change/SKILL.md +101 -0
  59. package/.opencode/skills/openspec-new-change/SKILL.md +74 -0
  60. package/.opencode/skills/openspec-onboard/SKILL.md +529 -0
  61. package/.opencode/skills/openspec-sync-specs/SKILL.md +138 -0
  62. package/.opencode/skills/openspec-verify-change/SKILL.md +168 -0
  63. package/LICENSE +1 -1
  64. package/README.md +128 -83
  65. package/bin/legacyver.js +48 -25
  66. package/legacyver-docs/SUMMARY.md +3 -0
  67. package/legacyver-docs/components.md +57 -0
  68. package/legacyver-docs/index.md +15 -0
  69. package/nul +2 -0
  70. package/package.json +23 -25
  71. package/src/cache/hash.js +9 -10
  72. package/src/cache/index.js +43 -65
  73. package/src/cli/commands/analyze.js +212 -190
  74. package/src/cli/commands/cache.js +15 -35
  75. package/src/cli/commands/init.js +63 -107
  76. package/src/cli/commands/providers.js +56 -81
  77. package/src/cli/commands/version.js +7 -10
  78. package/src/cli/ui.js +58 -77
  79. package/src/crawler/filters.js +41 -40
  80. package/src/crawler/index.js +52 -36
  81. package/src/crawler/manifest.js +31 -43
  82. package/src/crawler/walk.js +32 -38
  83. package/src/llm/chunker.js +34 -56
  84. package/src/llm/cost-estimator.js +68 -51
  85. package/src/llm/free-model.js +67 -0
  86. package/src/llm/index.js +22 -43
  87. package/src/llm/prompts.js +45 -33
  88. package/src/llm/providers/gemini.js +94 -0
  89. package/src/llm/providers/groq.js +55 -40
  90. package/src/llm/providers/ollama.js +38 -65
  91. package/src/llm/providers/openrouter.js +67 -0
  92. package/src/llm/queue.js +59 -88
  93. package/src/llm/re-prompter.js +41 -0
  94. package/src/llm/validator.js +72 -0
  95. package/src/parser/ast/generic.js +45 -222
  96. package/src/parser/ast/go.js +86 -205
  97. package/src/parser/ast/java.js +76 -146
  98. package/src/parser/ast/javascript.js +173 -241
  99. package/src/parser/ast/laravel/blade.js +56 -0
  100. package/src/parser/ast/laravel/classifier.js +30 -0
  101. package/src/parser/ast/laravel/controller.js +35 -0
  102. package/src/parser/ast/laravel/index.js +54 -0
  103. package/src/parser/ast/laravel/model.js +41 -0
  104. package/src/parser/ast/laravel/provider.js +28 -0
  105. package/src/parser/ast/laravel/routes.js +45 -0
  106. package/src/parser/ast/php.js +129 -0
  107. package/src/parser/ast/python.js +76 -199
  108. package/src/parser/ast/typescript.js +10 -244
  109. package/src/parser/body-extractor.js +40 -0
  110. package/src/parser/call-graph.js +50 -67
  111. package/src/parser/complexity-scorer.js +59 -0
  112. package/src/parser/index.js +61 -86
  113. package/src/parser/pattern-detector.js +71 -0
  114. package/src/parser/pkg-builder.js +36 -83
  115. package/src/renderer/html.js +63 -135
  116. package/src/renderer/index.js +23 -35
  117. package/src/renderer/json.js +17 -35
  118. package/src/renderer/markdown.js +83 -117
  119. package/src/utils/config.js +52 -53
  120. package/src/utils/errors.js +26 -41
  121. package/src/utils/logger.js +32 -53
  122. package/src/cli/flags.js +0 -87
  123. package/src/llm/providers/anthropic.js +0 -57
  124. package/src/llm/providers/google.js +0 -65
  125. package/src/llm/providers/openai.js +0 -52
  126. package/src/parser/ast/tree-sitter-init.js +0 -80
@@ -1,57 +0,0 @@
1
- /**
2
- * Anthropic LLM provider adapter.
3
- * Uses @anthropic-ai/sdk.
4
- * Default model: claude-haiku-3-5.
5
- */
6
-
7
- import Anthropic from '@anthropic-ai/sdk';
8
- import { NoApiKeyError, RateLimitError } from '../../utils/errors.js';
9
-
10
- export class AnthropicProvider {
11
- constructor(config = {}) {
12
- this.name = 'anthropic';
13
- this.model = config.model || 'claude-3-5-haiku-latest';
14
-
15
- const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;
16
- if (!apiKey) {
17
- throw new NoApiKeyError('anthropic');
18
- }
19
-
20
- this.client = new Anthropic({ apiKey });
21
- }
22
-
23
- /**
24
- * Send a completion request.
25
- * @param {object} request - { systemPrompt, userMessage }
26
- * @returns {Promise<{ content: string, tokensUsed: { input: number, output: number } }>}
27
- */
28
- async complete(request) {
29
- try {
30
- const response = await this.client.messages.create({
31
- model: this.model,
32
- max_tokens: 4096,
33
- system: request.systemPrompt,
34
- messages: [
35
- { role: 'user', content: request.userMessage },
36
- ],
37
- });
38
-
39
- return {
40
- content: response.content[0].text,
41
- tokensUsed: {
42
- input: response.usage.input_tokens,
43
- output: response.usage.output_tokens,
44
- },
45
- };
46
- } catch (err) {
47
- if (err.status === 429) {
48
- throw new RateLimitError('anthropic', err.headers?.['retry-after'] * 1000);
49
- }
50
- throw err;
51
- }
52
- }
53
-
54
- estimateCost(inputTokens, outputTokens) {
55
- return (inputTokens * 0.00025 + outputTokens * 0.00125) / 1000;
56
- }
57
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * Google AI LLM provider adapter.
3
- * Uses @google/generative-ai SDK.
4
- * Default model: gemini-1.5-flash.
5
- */
6
-
7
- import { GoogleGenerativeAI } from '@google/generative-ai';
8
- import { NoApiKeyError, RateLimitError } from '../../utils/errors.js';
9
-
10
- export class GoogleProvider {
11
- constructor(config = {}) {
12
- this.name = 'google';
13
- this.model = config.model || 'gemini-1.5-flash';
14
-
15
- const apiKey = config.apiKey || process.env.GOOGLE_API_KEY;
16
- if (!apiKey) {
17
- throw new NoApiKeyError('google');
18
- }
19
-
20
- this.genAI = new GoogleGenerativeAI(apiKey);
21
- }
22
-
23
- async complete(request) {
24
- try {
25
- const model = this.genAI.getGenerativeModel({ model: this.model });
26
-
27
- const result = await model.generateContent({
28
- contents: [
29
- {
30
- role: 'user',
31
- parts: [
32
- { text: request.systemPrompt + '\n\n' + request.userMessage },
33
- ],
34
- },
35
- ],
36
- generationConfig: {
37
- maxOutputTokens: 4096,
38
- },
39
- });
40
-
41
- const response = result.response;
42
- const text = response.text();
43
-
44
- // Google doesn't always return exact token counts
45
- const usageMetadata = response.usageMetadata || {};
46
-
47
- return {
48
- content: text,
49
- tokensUsed: {
50
- input: usageMetadata.promptTokenCount || 0,
51
- output: usageMetadata.candidatesTokenCount || 0,
52
- },
53
- };
54
- } catch (err) {
55
- if (err.status === 429 || err.message?.includes('RESOURCE_EXHAUSTED')) {
56
- throw new RateLimitError('google');
57
- }
58
- throw err;
59
- }
60
- }
61
-
62
- estimateCost(inputTokens, outputTokens) {
63
- return (inputTokens * 0.000075 + outputTokens * 0.0003) / 1000;
64
- }
65
- }
@@ -1,52 +0,0 @@
1
- /**
2
- * OpenAI LLM provider adapter.
3
- * Uses openai SDK.
4
- * Default model: gpt-4o-mini.
5
- */
6
-
7
- import OpenAI from 'openai';
8
- import { NoApiKeyError, RateLimitError } from '../../utils/errors.js';
9
-
10
- export class OpenAIProvider {
11
- constructor(config = {}) {
12
- this.name = 'openai';
13
- this.model = config.model || 'gpt-4o-mini';
14
-
15
- const apiKey = config.apiKey || process.env.OPENAI_API_KEY;
16
- if (!apiKey) {
17
- throw new NoApiKeyError('openai');
18
- }
19
-
20
- this.client = new OpenAI({ apiKey });
21
- }
22
-
23
- async complete(request) {
24
- try {
25
- const response = await this.client.chat.completions.create({
26
- model: this.model,
27
- max_tokens: 4096,
28
- messages: [
29
- { role: 'system', content: request.systemPrompt },
30
- { role: 'user', content: request.userMessage },
31
- ],
32
- });
33
-
34
- return {
35
- content: response.choices[0].message.content,
36
- tokensUsed: {
37
- input: response.usage.prompt_tokens,
38
- output: response.usage.completion_tokens,
39
- },
40
- };
41
- } catch (err) {
42
- if (err.status === 429) {
43
- throw new RateLimitError('openai');
44
- }
45
- throw err;
46
- }
47
- }
48
-
49
- estimateCost(inputTokens, outputTokens) {
50
- return (inputTokens * 0.00015 + outputTokens * 0.0006) / 1000;
51
- }
52
- }
@@ -1,80 +0,0 @@
1
- /**
2
- * Tree-sitter initialization helper.
3
- * Handles WASM loading for web-tree-sitter.
4
- */
5
-
6
- import { createRequire } from 'node:module';
7
- import { existsSync } from 'node:fs';
8
- import { join, dirname } from 'node:path';
9
- import { fileURLToPath } from 'node:url';
10
-
11
- const __dirname = dirname(fileURLToPath(import.meta.url));
12
-
13
- let Parser = null;
14
- let initialized = false;
15
-
16
- /**
17
- * Initialize web-tree-sitter. Must be called once before using any parsers.
18
- */
19
- export async function initTreeSitter() {
20
- if (initialized) return Parser;
21
-
22
- try {
23
- const TreeSitter = (await import('web-tree-sitter')).default;
24
- await TreeSitter.init();
25
- Parser = TreeSitter;
26
- initialized = true;
27
- return Parser;
28
- } catch (err) {
29
- // Tree-sitter not available
30
- return null;
31
- }
32
- }
33
-
34
- /**
35
- * Load a language grammar WASM file.
36
- * Looks for .wasm files in common locations.
37
- * @param {string} languageName - e.g., 'javascript', 'typescript', 'python'
38
- * @returns {Promise<object|null>} Language object or null
39
- */
40
- export async function loadLanguage(languageName) {
41
- if (!Parser) return null;
42
-
43
- const wasmName = `tree-sitter-${languageName}.wasm`;
44
-
45
- // Search paths for WASM files
46
- const searchPaths = [
47
- join(__dirname, '..', '..', '..', 'grammars', wasmName),
48
- join(__dirname, '..', '..', '..', 'node_modules', `tree-sitter-${languageName}`, wasmName),
49
- join(__dirname, '..', '..', '..', 'node_modules', 'web-tree-sitter', wasmName),
50
- join(process.cwd(), 'grammars', wasmName),
51
- ];
52
-
53
- for (const wasmPath of searchPaths) {
54
- if (existsSync(wasmPath)) {
55
- try {
56
- const language = await Parser.Language.load(wasmPath);
57
- return language;
58
- } catch {
59
- continue;
60
- }
61
- }
62
- }
63
-
64
- return null;
65
- }
66
-
67
- /**
68
- * Create a parser instance with the given language.
69
- * @param {object} language - Language object from loadLanguage
70
- * @returns {object|null} Parser instance
71
- */
72
- export function createParser(language) {
73
- if (!Parser || !language) return null;
74
-
75
- const parser = new Parser();
76
- parser.setLanguage(language);
77
- return parser;
78
- }
79
-
80
- export { Parser };