@aicgen/aicgen 1.0.0-beta.1 → 1.0.0-beta.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 (136) hide show
  1. package/.vs/ProjectSettings.json +2 -2
  2. package/.vs/VSWorkspaceState.json +15 -15
  3. package/.vs/aicgen.slnx/v18/DocumentLayout.json +53 -53
  4. package/assets/icon.svg +33 -33
  5. package/bun.lock +0 -43
  6. package/data/architecture/microservices/api-gateway.md +56 -56
  7. package/data/devops/observability.md +73 -73
  8. package/dist/index.js +9299 -9299
  9. package/package.json +2 -2
  10. package/.claude/agents/architecture-reviewer.md +0 -88
  11. package/.claude/agents/guideline-checker.md +0 -73
  12. package/.claude/agents/security-auditor.md +0 -108
  13. package/.claude/guidelines/api-design.md +0 -645
  14. package/.claude/guidelines/architecture.md +0 -2503
  15. package/.claude/guidelines/best-practices.md +0 -618
  16. package/.claude/guidelines/code-style.md +0 -304
  17. package/.claude/guidelines/design-patterns.md +0 -573
  18. package/.claude/guidelines/devops.md +0 -226
  19. package/.claude/guidelines/error-handling.md +0 -413
  20. package/.claude/guidelines/language.md +0 -782
  21. package/.claude/guidelines/performance.md +0 -706
  22. package/.claude/guidelines/security.md +0 -583
  23. package/.claude/guidelines/testing.md +0 -568
  24. package/.claude/settings.json +0 -98
  25. package/.claude/settings.local.json +0 -8
  26. package/.eslintrc.json +0 -28
  27. package/.github/workflows/release.yml +0 -180
  28. package/.github/workflows/test.yml +0 -81
  29. package/CONTRIBUTING.md +0 -821
  30. package/dist/commands/init.d.ts +0 -8
  31. package/dist/commands/init.d.ts.map +0 -1
  32. package/dist/commands/init.js +0 -46
  33. package/dist/commands/init.js.map +0 -1
  34. package/dist/config/profiles.d.ts +0 -4
  35. package/dist/config/profiles.d.ts.map +0 -1
  36. package/dist/config/profiles.js +0 -30
  37. package/dist/config/profiles.js.map +0 -1
  38. package/dist/config/settings.d.ts +0 -7
  39. package/dist/config/settings.d.ts.map +0 -1
  40. package/dist/config/settings.js +0 -7
  41. package/dist/config/settings.js.map +0 -1
  42. package/dist/index.d.ts +0 -3
  43. package/dist/index.d.ts.map +0 -1
  44. package/dist/index.js.map +0 -1
  45. package/dist/models/guideline.d.ts +0 -15
  46. package/dist/models/guideline.d.ts.map +0 -1
  47. package/dist/models/guideline.js +0 -2
  48. package/dist/models/guideline.js.map +0 -1
  49. package/dist/models/preference.d.ts +0 -9
  50. package/dist/models/preference.d.ts.map +0 -1
  51. package/dist/models/preference.js +0 -2
  52. package/dist/models/preference.js.map +0 -1
  53. package/dist/models/profile.d.ts +0 -9
  54. package/dist/models/profile.d.ts.map +0 -1
  55. package/dist/models/profile.js +0 -2
  56. package/dist/models/profile.js.map +0 -1
  57. package/dist/models/project.d.ts +0 -13
  58. package/dist/models/project.d.ts.map +0 -1
  59. package/dist/models/project.js +0 -2
  60. package/dist/models/project.js.map +0 -1
  61. package/dist/services/ai/anthropic.d.ts +0 -7
  62. package/dist/services/ai/anthropic.d.ts.map +0 -1
  63. package/dist/services/ai/anthropic.js +0 -39
  64. package/dist/services/ai/anthropic.js.map +0 -1
  65. package/dist/services/generator.d.ts +0 -2
  66. package/dist/services/generator.d.ts.map +0 -1
  67. package/dist/services/generator.js +0 -4
  68. package/dist/services/generator.js.map +0 -1
  69. package/dist/services/learner.d.ts +0 -2
  70. package/dist/services/learner.d.ts.map +0 -1
  71. package/dist/services/learner.js +0 -4
  72. package/dist/services/learner.js.map +0 -1
  73. package/dist/services/scanner.d.ts +0 -3
  74. package/dist/services/scanner.d.ts.map +0 -1
  75. package/dist/services/scanner.js +0 -54
  76. package/dist/services/scanner.js.map +0 -1
  77. package/dist/utils/errors.d.ts +0 -15
  78. package/dist/utils/errors.d.ts.map +0 -1
  79. package/dist/utils/errors.js +0 -27
  80. package/dist/utils/errors.js.map +0 -1
  81. package/dist/utils/file.d.ts +0 -7
  82. package/dist/utils/file.d.ts.map +0 -1
  83. package/dist/utils/file.js +0 -32
  84. package/dist/utils/file.js.map +0 -1
  85. package/dist/utils/logger.d.ts +0 -6
  86. package/dist/utils/logger.d.ts.map +0 -1
  87. package/dist/utils/logger.js +0 -17
  88. package/dist/utils/logger.js.map +0 -1
  89. package/dist/utils/path.d.ts +0 -6
  90. package/dist/utils/path.d.ts.map +0 -1
  91. package/dist/utils/path.js +0 -14
  92. package/dist/utils/path.js.map +0 -1
  93. package/docs/planning/memory-lane.md +0 -83
  94. package/packaging/linux/aicgen.spec +0 -23
  95. package/packaging/linux/control +0 -9
  96. package/packaging/macos/scripts/postinstall +0 -12
  97. package/packaging/windows/setup.nsi +0 -92
  98. package/scripts/add-categories.ts +0 -87
  99. package/scripts/build-binary.ts +0 -46
  100. package/scripts/embed-data.ts +0 -105
  101. package/scripts/generate-version.ts +0 -150
  102. package/scripts/test-decompress.ts +0 -27
  103. package/scripts/test-extract.ts +0 -31
  104. package/src/__tests__/services/assistant-file-writer.test.ts +0 -400
  105. package/src/__tests__/services/guideline-loader.test.ts +0 -281
  106. package/src/__tests__/services/tarball-extraction.test.ts +0 -125
  107. package/src/commands/add-guideline.ts +0 -296
  108. package/src/commands/clear.ts +0 -61
  109. package/src/commands/guideline-selector.ts +0 -123
  110. package/src/commands/init.ts +0 -645
  111. package/src/commands/quick-add.ts +0 -586
  112. package/src/commands/remove-guideline.ts +0 -152
  113. package/src/commands/stats.ts +0 -49
  114. package/src/commands/update.ts +0 -240
  115. package/src/config.ts +0 -82
  116. package/src/embedded-data.ts +0 -1492
  117. package/src/index.ts +0 -67
  118. package/src/models/profile.ts +0 -24
  119. package/src/models/project.ts +0 -43
  120. package/src/services/assistant-file-writer.ts +0 -612
  121. package/src/services/config-generator.ts +0 -150
  122. package/src/services/config-manager.ts +0 -70
  123. package/src/services/data-source.ts +0 -248
  124. package/src/services/first-run-init.ts +0 -148
  125. package/src/services/guideline-loader.ts +0 -311
  126. package/src/services/hook-generator.ts +0 -178
  127. package/src/services/subagent-generator.ts +0 -310
  128. package/src/utils/banner.ts +0 -66
  129. package/src/utils/errors.ts +0 -27
  130. package/src/utils/file.ts +0 -67
  131. package/src/utils/formatting.ts +0 -172
  132. package/src/utils/logger.ts +0 -89
  133. package/src/utils/path.ts +0 -17
  134. package/src/utils/wizard-state.ts +0 -132
  135. package/tsconfig.json +0 -25
  136. /package/{CLAUDE.md → claude.md} +0 -0
@@ -1,152 +0,0 @@
1
- import { select, checkbox, confirm } from '@inquirer/prompts';
2
- import chalk from 'chalk';
3
- import { homedir } from 'os';
4
- import { join } from 'path';
5
- import { readFile, writeFile, rm } from 'fs/promises';
6
- import { existsSync } from 'fs';
7
- import YAML from 'yaml';
8
- import { CONFIG } from '../config.js';
9
- import { showBanner } from '../utils/banner.js';
10
- import { addBackOption, BACK_VALUE } from '../utils/wizard-state.js';
11
- import { GuidelineMapping } from '../services/guideline-loader.js';
12
-
13
- export async function removeGuidelineCommand() {
14
- showBanner();
15
- console.log(chalk.cyan('🗑️ Remove Custom Guidelines\n'));
16
-
17
- const userDataPath = join(homedir(), CONFIG.CACHE_DIR_NAME, CONFIG.DATA_DIR);
18
- const mappingsPath = join(userDataPath, 'custom-mappings.yml');
19
-
20
- if (!existsSync(mappingsPath)) {
21
- console.log(chalk.gray('No custom guidelines found.'));
22
- console.log(chalk.gray('Use `aicgen add-guideline` to create custom guidelines.\n'));
23
- return;
24
- }
25
-
26
- // Load custom mappings
27
- const mappingsContent = await readFile(mappingsPath, 'utf-8');
28
- const mappings = YAML.parse(mappingsContent) as Record<string, GuidelineMapping>;
29
-
30
- const guidelineIds = Object.keys(mappings);
31
-
32
- if (guidelineIds.length === 0) {
33
- console.log(chalk.gray('No custom guidelines found.\n'));
34
- return;
35
- }
36
-
37
- console.log(chalk.cyan(`Found ${guidelineIds.length} custom guideline(s):\n`));
38
-
39
- let continueLoop = true;
40
- while (continueLoop) {
41
- // Ask user what to do
42
- const action = await select({
43
- message: 'What would you like to do?',
44
- choices: [
45
- { value: 'select', name: 'Select specific guidelines to remove', description: 'Choose which ones to delete' },
46
- { value: 'all', name: 'Remove ALL custom guidelines', description: 'Delete everything' },
47
- { value: 'cancel', name: 'Cancel', description: 'Exit without changes' }
48
- ]
49
- });
50
-
51
- if (action === 'cancel') {
52
- console.log(chalk.gray('\nCancelled.'));
53
- return;
54
- }
55
-
56
- let toRemove: string[] = [];
57
-
58
- if (action === 'all') {
59
- const confirmAll = await confirm({
60
- message: chalk.yellow(`Remove ALL ${guidelineIds.length} custom guidelines?`),
61
- default: false
62
- });
63
-
64
- if (!confirmAll) {
65
- continue;
66
- }
67
-
68
- toRemove = guidelineIds;
69
- } else {
70
- // Let user select which to remove
71
- const choices = addBackOption(guidelineIds.map(id => {
72
- const mapping = mappings[id];
73
- return {
74
- name: `${id} (${mapping.category || 'General'})`,
75
- value: id,
76
- checked: false
77
- };
78
- }), true);
79
-
80
- const selected = await checkbox({
81
- message: 'Select guidelines to remove (Space to toggle, Enter to confirm):',
82
- choices,
83
- loop: false
84
- }) as string[];
85
-
86
- // Check if Back was selected (it comes as a string in the array if selected, though checkbox UI usually handles it differently if we mix types, but here we treat it as value)
87
- // Actually checkbox returns array of values. If BACK_VALUE is in there, we should go back.
88
- if (selected.includes(BACK_VALUE)) {
89
- continue;
90
- }
91
-
92
- if (selected.length === 0) {
93
- console.log(chalk.gray('\nNo guidelines selected.'));
94
- continue;
95
- }
96
-
97
- toRemove = selected;
98
- }
99
-
100
- // Remove selected guidelines
101
- let removedCount = 0;
102
- const errors: string[] = [];
103
-
104
- for (const id of toRemove) {
105
- try {
106
- const mapping = mappings[id];
107
-
108
- // Delete the guideline file
109
- const guidelinePath = join(userDataPath, 'guidelines', mapping.path);
110
- if (existsSync(guidelinePath)) {
111
- await rm(guidelinePath);
112
- }
113
-
114
- // Remove from mappings
115
- delete mappings[id];
116
- removedCount++;
117
-
118
- console.log(chalk.green(`✓ Removed: ${id}`));
119
- } catch (error) {
120
- errors.push(`Failed to remove ${id}: ${error}`);
121
- console.log(chalk.red(`✗ Failed: ${id}`));
122
- }
123
- }
124
-
125
- // Update mappings file
126
- if (removedCount > 0) {
127
- if (Object.keys(mappings).length === 0) {
128
- // No guidelines left, remove the file
129
- await rm(mappingsPath);
130
- console.log(chalk.gray('\n (No custom guidelines remaining, removed mappings file)'));
131
- return; // Exit as nothing left
132
- } else {
133
- // Update mappings file
134
- await writeFile(mappingsPath, YAML.stringify(mappings), 'utf-8');
135
- }
136
- }
137
-
138
- // Summary
139
- console.log(chalk.green(`\n✅ Removed ${removedCount} custom guideline(s)`));
140
-
141
- if (errors.length > 0) {
142
- console.log(chalk.red(`\n❌ Errors:`));
143
- errors.forEach(err => console.log(chalk.red(` ${err}`)));
144
- }
145
-
146
- // Refresh list for next loop iteration
147
- const remainingIds = Object.keys(mappings);
148
- if (remainingIds.length === 0) {
149
- continueLoop = false;
150
- }
151
- }
152
- }
@@ -1,49 +0,0 @@
1
- import chalk from 'chalk';
2
- import { GuidelineLoader } from '../services/guideline-loader.js';
3
-
4
- export async function statsCommand() {
5
- console.log(chalk.blue.bold('\n📊 Guideline Statistics\n'));
6
-
7
- const loader = await GuidelineLoader.create();
8
- const stats = loader.getStats();
9
-
10
- console.log(chalk.cyan('Total Guidelines:'), chalk.white(stats.totalGuidelines));
11
-
12
- console.log(chalk.cyan('\n📋 By Language:'));
13
- Object.entries(stats.byLanguage)
14
- .sort((a, b) => b[1] - a[1])
15
- .forEach(([lang, count]) => {
16
- console.log(` ${chalk.gray(lang.padEnd(15))} ${chalk.white(count)}`);
17
- });
18
-
19
- console.log(chalk.cyan('\n🎯 By Level:'));
20
- Object.entries(stats.byLevel)
21
- .sort((a, b) => b[1] - a[1])
22
- .forEach(([level, count]) => {
23
- console.log(` ${chalk.gray(level.padEnd(15))} ${chalk.white(count)}`);
24
- });
25
-
26
- console.log(chalk.cyan('\n🏗️ By Architecture:'));
27
- Object.entries(stats.byArchitecture)
28
- .sort((a, b) => b[1] - a[1])
29
- .forEach(([arch, count]) => {
30
- console.log(` ${chalk.gray(arch.padEnd(20))} ${chalk.white(count)}`);
31
- });
32
-
33
- console.log(chalk.cyan('\n📚 By Category:'));
34
- Object.entries(stats.byCategory)
35
- .sort((a, b) => b[1] - a[1])
36
- .forEach(([category, count]) => {
37
- console.log(` ${chalk.gray(category.padEnd(20))} ${chalk.white(count)}`);
38
- });
39
-
40
- console.log(chalk.cyan('\n🏷️ Top Tags:'));
41
- Object.entries(stats.byTag)
42
- .sort((a, b) => b[1] - a[1])
43
- .slice(0, 15)
44
- .forEach(([tag, count]) => {
45
- console.log(` ${chalk.gray(tag.padEnd(25))} ${chalk.white(count)}`);
46
- });
47
-
48
- console.log();
49
- }
@@ -1,240 +0,0 @@
1
- import ora from 'ora';
2
- import chalk from 'chalk';
3
- import { homedir } from 'os';
4
- import { join } from 'path';
5
- import { mkdir, writeFile, rm, readdir, cp } from 'fs/promises';
6
- import { GuidelineLoader } from '../services/guideline-loader.js';
7
- import { createSummaryBox } from '../utils/formatting.js';
8
- import { CONFIG, GITHUB_RELEASES_URL } from '../config.js';
9
-
10
- const DOWNLOAD_TIMEOUT_MS = 30000;
11
- const MAX_TARBALL_SIZE_BYTES = 10 * 1024 * 1024;
12
-
13
- interface GitHubRelease {
14
- tag_name: string;
15
- name: string;
16
- body: string;
17
- zipball_url: string;
18
- tarball_url: string;
19
- published_at: string;
20
- }
21
-
22
- interface VersionInfo {
23
- version: string;
24
- downloadUrl: string;
25
- changes: string[];
26
- publishedAt: string;
27
- }
28
-
29
- export async function updateCommand(options: { force?: boolean } = {}) {
30
- const spinner = ora('Checking for updates...').start();
31
-
32
- try {
33
- // 1. Get current version
34
- const loader = await GuidelineLoader.create();
35
- const currentVersion = loader.getVersion();
36
-
37
- // 2. Fetch latest version from GitHub
38
- const latestVersion = await fetchLatestVersion();
39
-
40
- spinner.stop();
41
-
42
- // Show current vs latest
43
- console.log('\n' + createSummaryBox('📦 Update Check', [
44
- { label: 'Current', value: currentVersion },
45
- { label: 'Latest', value: latestVersion.version }
46
- ]));
47
-
48
- // 3. Check if update needed
49
- if (!options.force && !needsUpdate(currentVersion, latestVersion.version)) {
50
- console.log(chalk.green('\n✓ Already up to date!'));
51
- return;
52
- }
53
-
54
- if (options.force) {
55
- console.log(chalk.yellow('\n⚠️ Force update requested'));
56
- } else {
57
- console.log(chalk.cyan('\n📋 What\'s new:'));
58
- latestVersion.changes.slice(0, 10).forEach(change => {
59
- console.log(` ${chalk.gray('•')} ${change}`);
60
- });
61
- if (latestVersion.changes.length > 10) {
62
- console.log(chalk.gray(` ... and ${latestVersion.changes.length - 10} more changes`));
63
- }
64
- }
65
-
66
- // 4. Download and install
67
- spinner.start('Downloading guidelines...');
68
-
69
- const cacheDir = join(homedir(), CONFIG.CACHE_DIR_NAME, CONFIG.CACHE_DIR);
70
-
71
- // Clear existing cache
72
- try {
73
- await rm(cacheDir, { recursive: true, force: true });
74
- } catch {
75
- // Directory might not exist
76
- }
77
-
78
- await mkdir(cacheDir, { recursive: true });
79
-
80
- // Download from GitHub
81
- await downloadGuidelines(latestVersion.downloadUrl, cacheDir);
82
-
83
- // Write version file
84
- await writeFile(
85
- join(cacheDir, 'version.json'),
86
- JSON.stringify({ version: latestVersion.version, updatedAt: new Date().toISOString() }, null, 2),
87
- 'utf-8'
88
- );
89
-
90
- spinner.succeed(`Updated to v${latestVersion.version}`);
91
-
92
- console.log(chalk.green('\n✅ Guidelines updated successfully!'));
93
- console.log(chalk.gray(` Location: ${cacheDir}`));
94
- console.log(chalk.cyan(`\n ℹ️ Your custom guidelines are safe (stored separately in ~/.aicgen/data/)`));
95
- console.log(chalk.gray(`\n Run ${chalk.white('aicgen init')} to use the latest guidelines`));
96
-
97
- } catch (error) {
98
- spinner.fail('Update failed');
99
-
100
- if ((error as Error).message.includes('rate limit')) {
101
- console.error(chalk.red('\n❌ GitHub API rate limit exceeded'));
102
- console.log(chalk.yellow(' Try again later or authenticate with GitHub'));
103
- } else if ((error as Error).message.includes('ENOTFOUND') || (error as Error).message.includes('fetch')) {
104
- console.error(chalk.red('\n❌ Network error - check your internet connection'));
105
- } else {
106
- console.error(chalk.red(`\n❌ ${(error as Error).message}`));
107
- }
108
-
109
- process.exit(1);
110
- }
111
- }
112
-
113
- async function fetchLatestVersion(): Promise<VersionInfo> {
114
- const controller = new AbortController();
115
- const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
116
-
117
- try {
118
- const response = await fetch(GITHUB_RELEASES_URL, {
119
- headers: {
120
- 'Accept': 'application/vnd.github+json',
121
- 'User-Agent': CONFIG.USER_AGENT
122
- },
123
- signal: controller.signal
124
- });
125
-
126
- if (!response.ok) {
127
- if (response.status === 404) {
128
- throw new Error('Guidelines repository not found. The repository may not exist yet.');
129
- } else if (response.status === 403) {
130
- throw new Error('GitHub API rate limit exceeded');
131
- }
132
- throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
133
- }
134
-
135
- const data = await response.json() as GitHubRelease;
136
-
137
- // Parse changelog from body
138
- const changes = data.body
139
- .split('\n')
140
- .filter(line => line.trim().startsWith('-') || line.trim().startsWith('*'))
141
- .map(line => line.replace(/^[-*]\s*/, '').trim())
142
- .filter(line => line.length > 0);
143
-
144
- return {
145
- version: data.tag_name.replace(/^v/, ''),
146
- downloadUrl: data.tarball_url,
147
- changes,
148
- publishedAt: data.published_at
149
- };
150
- } finally {
151
- clearTimeout(timeout);
152
- }
153
- }
154
-
155
- async function downloadGuidelines(url: string, targetDir: string): Promise<void> {
156
- const controller = new AbortController();
157
- const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
158
-
159
- try {
160
- const response = await fetch(url, { signal: controller.signal });
161
-
162
- if (!response.ok) {
163
- throw new Error(`Failed to download: ${response.status} ${response.statusText}`);
164
- }
165
-
166
- // Check content-length if available
167
- const contentLength = response.headers.get('content-length');
168
- if (contentLength && parseInt(contentLength, 10) > MAX_TARBALL_SIZE_BYTES) {
169
- throw new Error(`Tarball too large: ${contentLength} bytes (max ${MAX_TARBALL_SIZE_BYTES})`);
170
- }
171
-
172
- const tarballBuffer = Buffer.from(await response.arrayBuffer());
173
-
174
- // Verify size after download
175
- if (tarballBuffer.length > MAX_TARBALL_SIZE_BYTES) {
176
- throw new Error(`Downloaded tarball too large: ${tarballBuffer.length} bytes`);
177
- }
178
-
179
- // Extract tarball to temp directory
180
- const tempDir = join(targetDir, '.temp-extract');
181
- await mkdir(tempDir, { recursive: true });
182
-
183
- try {
184
- const tarballPath = join(tempDir, 'archive.tar.gz');
185
- await writeFile(tarballPath, tarballBuffer);
186
-
187
- const decompress = (await import('decompress')).default;
188
- await decompress(tarballPath, tempDir);
189
-
190
- const entries = await readdir(tempDir);
191
- const expectedPrefix = `${CONFIG.GITHUB_REPO_OWNER}-${CONFIG.GITHUB_REPO_NAME}-`;
192
- const rootDir = entries.find(entry => entry.startsWith(expectedPrefix));
193
-
194
- if (!rootDir) {
195
- throw new Error(`Could not find extracted repository directory (expected ${expectedPrefix}*)`);
196
- }
197
-
198
- const extractedPath = join(tempDir, rootDir);
199
- const guidelinesTarget = join(targetDir, 'guidelines');
200
- await mkdir(guidelinesTarget, { recursive: true });
201
-
202
- const extractedEntries = await readdir(extractedPath, { withFileTypes: true });
203
- for (const entry of extractedEntries) {
204
- const sourcePath = join(extractedPath, entry.name);
205
- const targetPath = join(guidelinesTarget, entry.name);
206
-
207
- if (entry.name === 'guideline-mappings.yml') {
208
- await cp(sourcePath, join(targetDir, entry.name));
209
- } else if (entry.isDirectory() || entry.name.endsWith('.md')) {
210
- await cp(sourcePath, targetPath, { recursive: true });
211
- }
212
- }
213
- } finally {
214
- await rm(tempDir, { recursive: true, force: true });
215
- }
216
- } finally {
217
- clearTimeout(timeout);
218
- }
219
- }
220
-
221
- function needsUpdate(current: string, latest: string): boolean {
222
- // If current is embedded or unknown, always update
223
- if (current === 'embedded' || current === 'unknown' || current === 'custom') {
224
- return true;
225
- }
226
-
227
- // Simple version comparison (assumes semver)
228
- const currentParts = current.split('.').map(Number);
229
- const latestParts = latest.split('.').map(Number);
230
-
231
- for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
232
- const curr = currentParts[i] || 0;
233
- const lat = latestParts[i] || 0;
234
-
235
- if (lat > curr) return true;
236
- if (lat < curr) return false;
237
- }
238
-
239
- return false;
240
- }
package/src/config.ts DELETED
@@ -1,82 +0,0 @@
1
- import { readFileSync, existsSync } from 'fs';
2
- import { join, dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { homedir } from 'os';
5
- import YAML from 'yaml';
6
-
7
- function getPackageVersion(): string {
8
- try {
9
- const __dirname = dirname(fileURLToPath(import.meta.url));
10
- const packageJsonPath = join(__dirname, '..', 'package.json');
11
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
12
- return packageJson.version || '1.0.0-beta.1';
13
- } catch {
14
- // In compiled binary, package.json is not available
15
- // Version will be injected at build time via APP_VERSION env var
16
- return process.env.APP_VERSION || '1.0.0-beta.1';
17
- }
18
- }
19
-
20
- function getPackageName(): string {
21
- try {
22
- const __dirname = dirname(fileURLToPath(import.meta.url));
23
- const packageJsonPath = join(__dirname, '..', 'package.json');
24
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
25
- return packageJson.name || 'aicgen';
26
- } catch {
27
- return 'aicgen';
28
- }
29
- }
30
-
31
- interface UserConfig {
32
- github?: {
33
- owner?: string;
34
- repo?: string;
35
- };
36
- }
37
-
38
- function loadUserConfig(): UserConfig {
39
- try {
40
- const configPath = join(homedir(), '.aicgen', 'config.yml');
41
- if (existsSync(configPath)) {
42
- const content = readFileSync(configPath, 'utf-8');
43
- return YAML.parse(content) as UserConfig;
44
- }
45
- } catch {
46
- // Config file doesn't exist or is invalid - use defaults
47
- }
48
- return {};
49
- }
50
-
51
- const userConfig = loadUserConfig();
52
-
53
- export const CONFIG = {
54
- APP_VERSION: getPackageVersion(),
55
-
56
- APP_NAME: getPackageName(),
57
-
58
- // Priority: ENV > User Config > Default
59
- GITHUB_REPO_OWNER:
60
- process.env.AICGEN_GITHUB_OWNER ||
61
- userConfig.github?.owner ||
62
- 'aicgen',
63
-
64
- GITHUB_REPO_NAME:
65
- process.env.AICGEN_GITHUB_REPO ||
66
- userConfig.github?.repo ||
67
- 'aicgen-data',
68
-
69
- GITHUB_API_BASE: 'https://api.github.com',
70
-
71
- USER_AGENT: 'aicgen-cli',
72
-
73
- CACHE_DIR_NAME: '.aicgen',
74
-
75
- DATA_DIR: 'data',
76
-
77
- CACHE_DIR: 'cache/official',
78
- } as const;
79
-
80
- export const GITHUB_REPO_URL = `${CONFIG.GITHUB_API_BASE}/repos/${CONFIG.GITHUB_REPO_OWNER}/${CONFIG.GITHUB_REPO_NAME}`;
81
-
82
- export const GITHUB_RELEASES_URL = `${GITHUB_REPO_URL}/releases/latest`;