@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,311 +0,0 @@
1
- import { GuidelineMapping } from '../embedded-data.js';
2
- import { Language } from '../models/project.js';
3
- import { InstructionLevel, ArchitectureType, DatasourceType } from '../models/profile.js';
4
- import { homedir } from 'os';
5
- import { join } from 'path';
6
- import {
7
- DataSource,
8
- HybridDataSource,
9
- FileSystemDataSource,
10
- CustomMappingsDataSource,
11
- EmbeddedDataSource,
12
- GuidelineData
13
- } from './data-source.js';
14
- import { CONFIG } from '../config.js';
15
-
16
- export type { GuidelineMapping };
17
-
18
- export class GuidelineLoader {
19
- private mappings: Record<string, GuidelineMapping>;
20
- private guidelines: Record<string, string>;
21
- private version: string;
22
-
23
- static async create(dataSource?: DataSource): Promise<GuidelineLoader> {
24
- const source = dataSource || GuidelineLoader.createDefaultDataSource();
25
- const data = await source.load();
26
- return new GuidelineLoader(data);
27
- }
28
-
29
- private static createDefaultDataSource(): DataSource {
30
- const homeDir = homedir();
31
- const userDataPath = join(homeDir, CONFIG.CACHE_DIR_NAME, CONFIG.DATA_DIR);
32
- const officialCachePath = join(homeDir, CONFIG.CACHE_DIR_NAME, CONFIG.CACHE_DIR);
33
-
34
- return new HybridDataSource([
35
- new CustomMappingsDataSource(userDataPath), // Highest priority
36
- new FileSystemDataSource(officialCachePath), // Official updates
37
- new EmbeddedDataSource() // Fallback
38
- ]);
39
- }
40
-
41
- private constructor(data: GuidelineData) {
42
- this.mappings = data.mappings;
43
- this.guidelines = data.guidelines;
44
- this.version = data.version || 'unknown';
45
- }
46
-
47
- getVersion(): string {
48
- return this.version;
49
- }
50
-
51
- getAllGuidelines(): Array<{ id: string; mapping: GuidelineMapping }> {
52
- return Object.entries(this.mappings).map(([id, mapping]) => ({
53
- id,
54
- mapping
55
- }));
56
- }
57
-
58
- getGuidelinesForProfile(
59
- language: Language,
60
- level: InstructionLevel,
61
- architecture: ArchitectureType,
62
- datasource?: DatasourceType
63
- ): string[] {
64
- const matchingGuidelines: string[] = [];
65
-
66
- for (const [guidelineId, mapping] of Object.entries(this.mappings)) {
67
- // Language filter
68
- if (mapping.languages && !mapping.languages.includes(language)) {
69
- continue;
70
- }
71
-
72
- // Level filter
73
- if (mapping.levels && !mapping.levels.includes(level)) {
74
- continue;
75
- }
76
-
77
- // Architecture filter - SKIP for "full" level (include all architectures)
78
- if (level !== 'full' && mapping.architectures && !mapping.architectures.includes(architecture)) {
79
- continue;
80
- }
81
-
82
- // Datasource filter - skip if guideline requires specific datasource that doesn't match
83
- if (datasource && mapping.datasources && !mapping.datasources.includes(datasource)) {
84
- continue;
85
- }
86
-
87
- // Skip database guidelines entirely if datasource is 'none'
88
- if (datasource === 'none' && mapping.category === 'Database') {
89
- continue;
90
- }
91
-
92
- matchingGuidelines.push(guidelineId);
93
- }
94
-
95
- return matchingGuidelines;
96
- }
97
-
98
- loadGuideline(guidelineId: string): string {
99
- const mapping = this.mappings[guidelineId];
100
- if (!mapping) {
101
- throw new Error(`Guideline not found: ${guidelineId}`);
102
- }
103
-
104
- const content = this.guidelines[mapping.path];
105
- if (!content) {
106
- throw new Error(`Guideline content not found: ${mapping.path}`);
107
- }
108
-
109
- return content;
110
- }
111
-
112
- getMapping(guidelineId: string): GuidelineMapping | undefined {
113
- return this.mappings[guidelineId];
114
- }
115
-
116
- assembleProfile(
117
- language: Language,
118
- level: InstructionLevel,
119
- architecture: ArchitectureType,
120
- datasource?: DatasourceType
121
- ): string {
122
- const guidelineIds = this.getGuidelinesForProfile(language, level, architecture, datasource);
123
-
124
- if (guidelineIds.length === 0) {
125
- throw new Error(`No guidelines found for profile: ${language}-${level}-${architecture}`);
126
- }
127
-
128
- const guidelineContents = guidelineIds.map(id => this.loadGuideline(id));
129
- return guidelineContents.join('\n\n---\n\n');
130
- }
131
-
132
- getGuidelinesByCategory(language?: Language, level?: InstructionLevel, architecture?: ArchitectureType, datasource?: DatasourceType): Record<string, string[]> {
133
- const byCategory: Record<string, string[]> = {};
134
-
135
- for (const [guidelineId, mapping] of Object.entries(this.mappings)) {
136
- if (language && mapping.languages && !mapping.languages.includes(language)) {
137
- continue;
138
- }
139
-
140
- if (level && mapping.levels && !mapping.levels.includes(level)) {
141
- continue;
142
- }
143
-
144
- // Architecture filter - SKIP for "full" level (include all architectures)
145
- if (level !== 'full' && architecture && mapping.architectures && !mapping.architectures.includes(architecture)) {
146
- continue;
147
- }
148
-
149
- if (datasource && mapping.datasources && !mapping.datasources.includes(datasource)) {
150
- continue;
151
- }
152
-
153
- if (datasource === 'none' && mapping.category === 'Database') {
154
- continue;
155
- }
156
-
157
- const category = mapping.category || 'General';
158
- if (!byCategory[category]) {
159
- byCategory[category] = [];
160
- }
161
- byCategory[category].push(guidelineId);
162
- }
163
-
164
- return byCategory;
165
- }
166
-
167
- getCategoryTree(language?: Language, level?: InstructionLevel, architecture?: ArchitectureType, datasource?: DatasourceType): CategoryNode[] {
168
- const byCategory = this.getGuidelinesByCategory(language, level, architecture, datasource);
169
-
170
- return Object.entries(byCategory)
171
- .map(([name, guidelineIds]) => ({
172
- name,
173
- count: guidelineIds.length,
174
- guidelines: guidelineIds.map(id => ({
175
- id,
176
- name: this.mappings[id].path.split('/').pop()?.replace('.md', '') || id,
177
- path: this.mappings[id].path
178
- }))
179
- }))
180
- .sort((a, b) => a.name.localeCompare(b.name));
181
- }
182
-
183
- getMetrics(guidelineIds: string[]): ProfileMetrics {
184
- const categories: Record<string, number> = {};
185
-
186
- for (const id of guidelineIds) {
187
- const mapping = this.mappings[id];
188
- if (mapping) {
189
- const category = mapping.category || 'General';
190
- categories[category] = (categories[category] || 0) + 1;
191
- }
192
- }
193
-
194
- return {
195
- guidelineCount: guidelineIds.length,
196
- hooksCount: this.estimateHooks(guidelineIds),
197
- subAgentsCount: this.estimateSubAgents(guidelineIds),
198
- estimatedSize: this.estimateSize(guidelineIds),
199
- categories: Object.entries(categories).map(([name, count]) => ({ name, count }))
200
- };
201
- }
202
-
203
- private estimateHooks(guidelineIds: string[]): number {
204
- const hasFormatting = guidelineIds.some(id => id.includes('style') || id.includes('typescript') || id.includes('python'));
205
- const hasSecurity = guidelineIds.some(id => id.includes('security'));
206
- const hasTesting = guidelineIds.some(id => id.includes('testing'));
207
-
208
- let count = 0;
209
- if (hasFormatting) count += 1;
210
- if (hasSecurity) count += 2;
211
- if (hasTesting) count += 1;
212
- return count;
213
- }
214
-
215
- private estimateSubAgents(guidelineIds: string[]): number {
216
- const hasArchitecture = guidelineIds.some(id => id.includes('architecture'));
217
- const hasSecurity = guidelineIds.some(id => id.includes('security'));
218
- const hasStyle = guidelineIds.some(id => id.includes('style'));
219
-
220
- let count = 1;
221
- if (hasArchitecture) count += 1;
222
- if (hasSecurity) count += 1;
223
- if (hasStyle && guidelineIds.length > 10) count += 1;
224
- return count;
225
- }
226
-
227
- private estimateSize(guidelineIds: string[]): string {
228
- const avgSizePerGuideline = 2.5;
229
- const totalKB = guidelineIds.length * avgSizePerGuideline;
230
-
231
- if (totalKB < 1) return '<1 KB';
232
- if (totalKB < 10) return `~${Math.round(totalKB)} KB`;
233
- return `~${Math.round(totalKB / 10) * 10} KB`;
234
- }
235
-
236
- getStats(): {
237
- totalGuidelines: number;
238
- byLanguage: Record<string, number>;
239
- byLevel: Record<string, number>;
240
- byArchitecture: Record<string, number>;
241
- byCategory: Record<string, number>;
242
- byTag: Record<string, number>;
243
- } {
244
- const stats = {
245
- totalGuidelines: Object.keys(this.mappings).length,
246
- byLanguage: {} as Record<string, number>,
247
- byLevel: {} as Record<string, number>,
248
- byArchitecture: {} as Record<string, number>,
249
- byCategory: {} as Record<string, number>,
250
- byTag: {} as Record<string, number>
251
- };
252
-
253
- for (const mapping of Object.values(this.mappings)) {
254
- if (mapping.languages) {
255
- for (const lang of mapping.languages) {
256
- stats.byLanguage[lang] = (stats.byLanguage[lang] || 0) + 1;
257
- }
258
- } else {
259
- stats.byLanguage['all'] = (stats.byLanguage['all'] || 0) + 1;
260
- }
261
-
262
- if (mapping.levels) {
263
- for (const lvl of mapping.levels) {
264
- stats.byLevel[lvl] = (stats.byLevel[lvl] || 0) + 1;
265
- }
266
- } else {
267
- stats.byLevel['all'] = (stats.byLevel['all'] || 0) + 1;
268
- }
269
-
270
- if (mapping.architectures) {
271
- for (const arch of mapping.architectures) {
272
- stats.byArchitecture[arch] = (stats.byArchitecture[arch] || 0) + 1;
273
- }
274
- } else {
275
- stats.byArchitecture['all'] = (stats.byArchitecture['all'] || 0) + 1;
276
- }
277
-
278
- const category = mapping.category || 'General';
279
- stats.byCategory[category] = (stats.byCategory[category] || 0) + 1;
280
-
281
- if (mapping.tags) {
282
- for (const tag of mapping.tags) {
283
- stats.byTag[tag] = (stats.byTag[tag] || 0) + 1;
284
- }
285
- }
286
- }
287
-
288
- return stats;
289
- }
290
- }
291
-
292
- export interface CategoryNode {
293
- name: string;
294
- count: number;
295
- guidelines: {
296
- id: string;
297
- name: string;
298
- path: string;
299
- }[];
300
- }
301
-
302
- export interface ProfileMetrics {
303
- guidelineCount: number;
304
- hooksCount: number;
305
- subAgentsCount: number;
306
- estimatedSize: string;
307
- categories: {
308
- name: string;
309
- count: number;
310
- }[];
311
- }
@@ -1,178 +0,0 @@
1
- export interface HookEntry {
2
- matcher?: string;
3
- hooks?: HookEntry[];
4
- type?: string;
5
- command?: string;
6
- prompt?: string;
7
- timeout?: number;
8
- }
9
-
10
- export type HookEventMap = Record<string, HookEntry[]>;
11
-
12
- export interface HookConfig {
13
- name: string;
14
- description: string;
15
- hooks: HookEventMap;
16
- }
17
-
18
- const EMBEDDED_HOOKS: Record<string, HookConfig> = {
19
- formatting: {
20
- name: 'Auto-format on file write',
21
- description: 'Automatically format code files after writing',
22
- hooks: {
23
- PostToolUse: [
24
- {
25
- matcher: 'Write(src/**/*.ts)',
26
- hooks: [
27
- {
28
- type: 'command',
29
- command: 'npx prettier --write "${CLAUDE_FILE}" 2>/dev/null || true'
30
- }
31
- ]
32
- },
33
- {
34
- matcher: 'Write(src/**/*.tsx)',
35
- hooks: [
36
- {
37
- type: 'command',
38
- command: 'npx prettier --write "${CLAUDE_FILE}" 2>/dev/null || true'
39
- }
40
- ]
41
- }
42
- ]
43
- }
44
- },
45
- security: {
46
- name: 'Block sensitive file access',
47
- description: 'Prevent reading or modifying sensitive files',
48
- hooks: {
49
- PreToolUse: [
50
- {
51
- matcher: 'Read(.env*)',
52
- hooks: [
53
- {
54
- type: 'command',
55
- command: "echo 'Blocked: Sensitive file access not allowed' && exit 2"
56
- }
57
- ]
58
- },
59
- {
60
- matcher: 'Read(secrets/**)',
61
- hooks: [
62
- {
63
- type: 'command',
64
- command: "echo 'Blocked: Secrets directory is protected' && exit 2"
65
- }
66
- ]
67
- },
68
- {
69
- matcher: 'Write(.env*)',
70
- hooks: [
71
- {
72
- type: 'command',
73
- command: "echo 'Blocked: Cannot modify environment files' && exit 2"
74
- }
75
- ]
76
- }
77
- ]
78
- }
79
- },
80
- testing: {
81
- name: 'Verify tests before completion',
82
- description: 'Ensure tests pass before task completion',
83
- hooks: {
84
- Stop: [
85
- {
86
- hooks: [
87
- {
88
- type: 'prompt',
89
- prompt:
90
- 'Before completing this task, verify that:\n1. All tests pass\n2. No new failing tests were introduced\n3. Test coverage meets requirements\n\nIs the task truly complete with passing tests?',
91
- timeout: 15
92
- }
93
- ]
94
- }
95
- ]
96
- }
97
- }
98
- };
99
-
100
- export class HookGenerator {
101
- async generateHooks(guidelineIds: string[]): Promise<HookEventMap> {
102
- const mergedHooks: HookEventMap = {};
103
-
104
- const hasFormatting = guidelineIds.some(
105
- (id) => id.includes('style') || id.includes('typescript') || id.includes('python')
106
- );
107
- const hasSecurity = guidelineIds.some((id) => id.includes('security'));
108
- const hasTesting = guidelineIds.some((id) => id.includes('testing'));
109
-
110
- if (hasFormatting) {
111
- this.mergeHooks(mergedHooks, EMBEDDED_HOOKS.formatting.hooks);
112
- }
113
-
114
- if (hasSecurity) {
115
- this.mergeHooks(mergedHooks, EMBEDDED_HOOKS.security.hooks);
116
- }
117
-
118
- if (hasTesting) {
119
- this.mergeHooks(mergedHooks, EMBEDDED_HOOKS.testing.hooks);
120
- }
121
-
122
- return mergedHooks;
123
- }
124
-
125
- private mergeHooks(target: HookEventMap, source: HookEventMap): void {
126
- for (const [event, hooks] of Object.entries(source)) {
127
- if (!target[event]) {
128
- target[event] = [];
129
- }
130
- target[event].push(...hooks);
131
- }
132
- }
133
-
134
- generateClaudeCodeSettings(
135
- hooks: HookEventMap,
136
- projectPath: string,
137
- level: 'basic' | 'standard' | 'expert' | 'full' = 'standard'
138
- ): string {
139
- // Base permissions for all levels
140
- const baseAllow = [
141
- 'Bash(npm run:*)',
142
- 'Bash(yarn:*)',
143
- 'Bash(pnpm:*)',
144
- 'Bash(bun:*)',
145
- 'Bash(git:*)',
146
- 'Bash(npx:*)',
147
- 'Read(src/**)',
148
- 'Read(package.json)',
149
- 'Read(tsconfig.json)',
150
- 'Read(CLAUDE.md)',
151
- 'Read(.claude/**)',
152
- 'Write(src/**)',
153
- 'Write(.claude/**)'
154
- ];
155
-
156
- // Network permissions only for expert/full levels (least-privilege)
157
- const allowInternet = level === 'expert' || level === 'full';
158
- const allowWebSearch = level === 'expert' || level === 'full';
159
-
160
- const allow = allowWebSearch ? [...baseAllow, 'WebSearch'] : baseAllow;
161
-
162
- const settings = {
163
- alwaysThinkingEnabled: true,
164
- hooks,
165
- permissions: {
166
- allow,
167
- deny: ['Read(.env*)', 'Read(secrets/**)', 'Bash(rm:*)', 'Bash(sudo:*)'],
168
- ask: ['Write(package.json)', 'Write(.gitignore)', 'Write(.env.example)']
169
- },
170
- sandbox: {
171
- allowInternetAccess: allowInternet,
172
- workingDirectory: projectPath
173
- }
174
- };
175
-
176
- return JSON.stringify(settings, null, 2);
177
- }
178
- }