@aicgen/aicgen 1.0.0-beta.1 → 1.0.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/{.claude/guidelines → .agent/rules}/api-design.md +5 -1
- package/{.claude/guidelines → .agent/rules}/architecture.md +5 -1
- package/{.claude/guidelines → .agent/rules}/best-practices.md +5 -1
- package/{.claude/guidelines → .agent/rules}/code-style.md +5 -1
- package/{.claude/guidelines → .agent/rules}/design-patterns.md +5 -1
- package/{.claude/guidelines → .agent/rules}/devops.md +5 -1
- package/{.claude/guidelines → .agent/rules}/error-handling.md +5 -1
- package/.agent/rules/instructions.md +28 -0
- package/{.claude/guidelines → .agent/rules}/language.md +5 -1
- package/{.claude/guidelines → .agent/rules}/performance.md +5 -1
- package/{.claude/guidelines → .agent/rules}/security.md +5 -1
- package/{.claude/guidelines → .agent/rules}/testing.md +5 -1
- package/.agent/workflows/add-documentation.md +10 -0
- package/.agent/workflows/generate-integration-tests.md +10 -0
- package/.agent/workflows/generate-unit-tests.md +11 -0
- package/.agent/workflows/performance-audit.md +11 -0
- package/.agent/workflows/refactor-extract-module.md +12 -0
- package/.agent/workflows/security-audit.md +12 -0
- package/.gemini/instructions.md +4843 -0
- package/.vs/ProjectSettings.json +2 -2
- package/.vs/VSWorkspaceState.json +15 -15
- package/.vs/aicgen.slnx/v18/DocumentLayout.json +53 -53
- package/AGENTS.md +9 -11
- package/assets/icon.svg +33 -33
- package/bun.lock +734 -26
- package/{CLAUDE.md → claude.md} +2 -2
- package/config.example.yml +129 -0
- package/config.yml +38 -0
- package/data/architecture/microservices/api-gateway.md +56 -56
- package/data/devops/observability.md +73 -73
- package/data/guideline-mappings.yml +128 -0
- package/data/language/dart/async.md +289 -0
- package/data/language/dart/basics.md +280 -0
- package/data/language/dart/error-handling.md +355 -0
- package/data/language/dart/index.md +10 -0
- package/data/language/dart/testing.md +352 -0
- package/data/language/swift/basics.md +477 -0
- package/data/language/swift/concurrency.md +654 -0
- package/data/language/swift/error-handling.md +679 -0
- package/data/language/swift/swiftui-mvvm.md +795 -0
- package/data/language/swift/testing.md +708 -0
- package/data/version.json +10 -8
- package/dist/index.js +50153 -28959
- package/jest.config.js +46 -0
- package/package.json +14 -3
- package/.claude/agents/architecture-reviewer.md +0 -88
- package/.claude/agents/guideline-checker.md +0 -73
- package/.claude/agents/security-auditor.md +0 -108
- package/.claude/settings.json +0 -98
- package/.claude/settings.local.json +0 -8
- package/.eslintrc.json +0 -28
- package/.github/workflows/release.yml +0 -180
- package/.github/workflows/test.yml +0 -81
- package/CONTRIBUTING.md +0 -821
- package/dist/commands/init.d.ts +0 -8
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -46
- package/dist/commands/init.js.map +0 -1
- package/dist/config/profiles.d.ts +0 -4
- package/dist/config/profiles.d.ts.map +0 -1
- package/dist/config/profiles.js +0 -30
- package/dist/config/profiles.js.map +0 -1
- package/dist/config/settings.d.ts +0 -7
- package/dist/config/settings.d.ts.map +0 -1
- package/dist/config/settings.js +0 -7
- package/dist/config/settings.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/models/guideline.d.ts +0 -15
- package/dist/models/guideline.d.ts.map +0 -1
- package/dist/models/guideline.js +0 -2
- package/dist/models/guideline.js.map +0 -1
- package/dist/models/preference.d.ts +0 -9
- package/dist/models/preference.d.ts.map +0 -1
- package/dist/models/preference.js +0 -2
- package/dist/models/preference.js.map +0 -1
- package/dist/models/profile.d.ts +0 -9
- package/dist/models/profile.d.ts.map +0 -1
- package/dist/models/profile.js +0 -2
- package/dist/models/profile.js.map +0 -1
- package/dist/models/project.d.ts +0 -13
- package/dist/models/project.d.ts.map +0 -1
- package/dist/models/project.js +0 -2
- package/dist/models/project.js.map +0 -1
- package/dist/services/ai/anthropic.d.ts +0 -7
- package/dist/services/ai/anthropic.d.ts.map +0 -1
- package/dist/services/ai/anthropic.js +0 -39
- package/dist/services/ai/anthropic.js.map +0 -1
- package/dist/services/generator.d.ts +0 -2
- package/dist/services/generator.d.ts.map +0 -1
- package/dist/services/generator.js +0 -4
- package/dist/services/generator.js.map +0 -1
- package/dist/services/learner.d.ts +0 -2
- package/dist/services/learner.d.ts.map +0 -1
- package/dist/services/learner.js +0 -4
- package/dist/services/learner.js.map +0 -1
- package/dist/services/scanner.d.ts +0 -3
- package/dist/services/scanner.d.ts.map +0 -1
- package/dist/services/scanner.js +0 -54
- package/dist/services/scanner.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -15
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -27
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/file.d.ts +0 -7
- package/dist/utils/file.d.ts.map +0 -1
- package/dist/utils/file.js +0 -32
- package/dist/utils/file.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -6
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -17
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/path.d.ts +0 -6
- package/dist/utils/path.d.ts.map +0 -1
- package/dist/utils/path.js +0 -14
- package/dist/utils/path.js.map +0 -1
- package/docs/planning/memory-lane.md +0 -83
- package/packaging/linux/aicgen.spec +0 -23
- package/packaging/linux/control +0 -9
- package/packaging/macos/scripts/postinstall +0 -12
- package/packaging/windows/setup.nsi +0 -92
- package/scripts/add-categories.ts +0 -87
- package/scripts/build-binary.ts +0 -46
- package/scripts/embed-data.ts +0 -105
- package/scripts/generate-version.ts +0 -150
- package/scripts/test-decompress.ts +0 -27
- package/scripts/test-extract.ts +0 -31
- package/src/__tests__/services/assistant-file-writer.test.ts +0 -400
- package/src/__tests__/services/guideline-loader.test.ts +0 -281
- package/src/__tests__/services/tarball-extraction.test.ts +0 -125
- package/src/commands/add-guideline.ts +0 -296
- package/src/commands/clear.ts +0 -61
- package/src/commands/guideline-selector.ts +0 -123
- package/src/commands/init.ts +0 -645
- package/src/commands/quick-add.ts +0 -586
- package/src/commands/remove-guideline.ts +0 -152
- package/src/commands/stats.ts +0 -49
- package/src/commands/update.ts +0 -240
- package/src/config.ts +0 -82
- package/src/embedded-data.ts +0 -1492
- package/src/index.ts +0 -67
- package/src/models/profile.ts +0 -24
- package/src/models/project.ts +0 -43
- package/src/services/assistant-file-writer.ts +0 -612
- package/src/services/config-generator.ts +0 -150
- package/src/services/config-manager.ts +0 -70
- package/src/services/data-source.ts +0 -248
- package/src/services/first-run-init.ts +0 -148
- package/src/services/guideline-loader.ts +0 -311
- package/src/services/hook-generator.ts +0 -178
- package/src/services/subagent-generator.ts +0 -310
- package/src/utils/banner.ts +0 -66
- package/src/utils/errors.ts +0 -27
- package/src/utils/file.ts +0 -67
- package/src/utils/formatting.ts +0 -172
- package/src/utils/logger.ts +0 -89
- package/src/utils/path.ts +0 -17
- package/src/utils/wizard-state.ts +0 -132
- package/tsconfig.json +0 -25
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
export interface SubAgentTemplate {
|
|
2
|
-
name: string;
|
|
3
|
-
content: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
const EMBEDDED_AGENTS: Record<string, string> = {
|
|
7
|
-
'guideline-checker': `---
|
|
8
|
-
model: "claude-opus-4-5"
|
|
9
|
-
description: "Verifies code changes comply with project guidelines"
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Guideline Compliance Checker
|
|
13
|
-
|
|
14
|
-
You are an automated code review agent that verifies code changes follow the project's established guidelines.
|
|
15
|
-
|
|
16
|
-
## Your Responsibilities
|
|
17
|
-
|
|
18
|
-
When code changes are made, automatically verify:
|
|
19
|
-
|
|
20
|
-
### Code Style Compliance
|
|
21
|
-
- Naming conventions match project standards
|
|
22
|
-
- File organization follows project structure
|
|
23
|
-
- No redundant or commented-out code
|
|
24
|
-
- Proper indentation and formatting
|
|
25
|
-
|
|
26
|
-
### TypeScript/JavaScript Standards
|
|
27
|
-
- TypeScript strict mode compliance
|
|
28
|
-
- No \`any\` types (use \`unknown\` with type guards)
|
|
29
|
-
- Proper interface/type definitions
|
|
30
|
-
- Async/await patterns used correctly
|
|
31
|
-
|
|
32
|
-
### Best Practices
|
|
33
|
-
- Functions under 50 lines
|
|
34
|
-
- Maximum 3 levels of nesting
|
|
35
|
-
- Complex conditionals extracted to named functions
|
|
36
|
-
- Error handling implemented properly
|
|
37
|
-
- No magic numbers (use named constants)
|
|
38
|
-
|
|
39
|
-
### Testing Requirements
|
|
40
|
-
- New functions have corresponding tests
|
|
41
|
-
- Test coverage maintained or improved
|
|
42
|
-
- Tests follow AAA pattern (Arrange, Act, Assert)
|
|
43
|
-
|
|
44
|
-
## Output Format
|
|
45
|
-
|
|
46
|
-
Report findings in this format:
|
|
47
|
-
|
|
48
|
-
\`\`\`
|
|
49
|
-
✅ Guideline Compliance Report
|
|
50
|
-
|
|
51
|
-
Files checked: X
|
|
52
|
-
|
|
53
|
-
⚠️ Issues Found:
|
|
54
|
-
|
|
55
|
-
src/services/example.ts:45
|
|
56
|
-
- Uses \`any\` type instead of \`unknown\`
|
|
57
|
-
- Function exceeds 50 lines (65 lines)
|
|
58
|
-
|
|
59
|
-
src/utils/helper.ts:12
|
|
60
|
-
- Magic number 3600 should be named constant
|
|
61
|
-
|
|
62
|
-
src/commands/init.ts:120
|
|
63
|
-
- Missing error handling for async operation
|
|
64
|
-
|
|
65
|
-
📋 Recommendations:
|
|
66
|
-
1. Replace \`any\` with \`unknown\` and add type guard
|
|
67
|
-
2. Extract SECONDS_IN_HOUR = 3600 as constant
|
|
68
|
-
3. Add try-catch block for async operation
|
|
69
|
-
|
|
70
|
-
Overall: 3 issues require attention
|
|
71
|
-
\`\`\`
|
|
72
|
-
|
|
73
|
-
## Guidelines
|
|
74
|
-
|
|
75
|
-
- Be specific with file paths and line numbers
|
|
76
|
-
- Explain WHY each issue matters
|
|
77
|
-
- Provide actionable recommendations
|
|
78
|
-
- Prioritize by severity (critical, important, minor)
|
|
79
|
-
- Acknowledge good practices when found
|
|
80
|
-
`,
|
|
81
|
-
|
|
82
|
-
'architecture-reviewer': `---
|
|
83
|
-
model: "claude-sonnet-4-5"
|
|
84
|
-
description: "Reviews architectural decisions and patterns"
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
# Architecture Reviewer
|
|
88
|
-
|
|
89
|
-
You are an architecture review agent ensuring code changes align with the project's architectural principles and patterns.
|
|
90
|
-
|
|
91
|
-
## Your Responsibilities
|
|
92
|
-
|
|
93
|
-
### Architectural Compliance
|
|
94
|
-
- Verify changes follow established architecture pattern (layered, hexagonal, microservices, etc.)
|
|
95
|
-
- Check dependency directions are correct
|
|
96
|
-
- Ensure proper separation of concerns
|
|
97
|
-
- Validate module boundaries
|
|
98
|
-
|
|
99
|
-
### Design Patterns
|
|
100
|
-
- Identify appropriate use of design patterns
|
|
101
|
-
- Flag anti-patterns (God objects, tight coupling, etc.)
|
|
102
|
-
- Suggest pattern improvements when beneficial
|
|
103
|
-
- Verify SOLID principles adherence
|
|
104
|
-
|
|
105
|
-
### Technical Debt
|
|
106
|
-
- Identify potential technical debt introduced
|
|
107
|
-
- Flag shortcuts that may cause future issues
|
|
108
|
-
- Suggest refactoring opportunities
|
|
109
|
-
- Assess long-term maintainability impact
|
|
110
|
-
|
|
111
|
-
## Review Checklist
|
|
112
|
-
|
|
113
|
-
- [ ] Does this change respect the existing architecture?
|
|
114
|
-
- [ ] Are dependencies pointing in the correct direction?
|
|
115
|
-
- [ ] Is there proper separation between layers/modules?
|
|
116
|
-
- [ ] Are interfaces/contracts well-defined?
|
|
117
|
-
- [ ] Is the change introducing tight coupling?
|
|
118
|
-
- [ ] Could this be simplified using existing patterns?
|
|
119
|
-
- [ ] Does this create technical debt?
|
|
120
|
-
- [ ] Is this scalable and maintainable?
|
|
121
|
-
|
|
122
|
-
## Output Format
|
|
123
|
-
|
|
124
|
-
\`\`\`
|
|
125
|
-
🏗️ Architecture Review
|
|
126
|
-
|
|
127
|
-
Files reviewed: X
|
|
128
|
-
Architecture: [Layered/Hexagonal/Microservices/etc.]
|
|
129
|
-
|
|
130
|
-
✅ Strengths:
|
|
131
|
-
- Proper dependency injection in ServiceFactory
|
|
132
|
-
- Clean interface boundaries in API layer
|
|
133
|
-
|
|
134
|
-
⚠️ Concerns:
|
|
135
|
-
|
|
136
|
-
1. Dependency Violation (Critical)
|
|
137
|
-
- File: src/ui/components/UserForm.tsx:23
|
|
138
|
-
- Issue: Direct database access from UI layer
|
|
139
|
-
- Impact: Violates layered architecture
|
|
140
|
-
- Solution: Access data through service layer
|
|
141
|
-
|
|
142
|
-
2. Tight Coupling (Important)
|
|
143
|
-
- File: src/services/email-service.ts:45
|
|
144
|
-
- Issue: Hard-coded dependency on specific SMTP library
|
|
145
|
-
- Impact: Difficult to swap email providers
|
|
146
|
-
- Solution: Use adapter pattern with EmailProvider interface
|
|
147
|
-
|
|
148
|
-
3. Potential Debt (Minor)
|
|
149
|
-
- File: src/utils/cache.ts:12
|
|
150
|
-
- Issue: In-memory cache without eviction strategy
|
|
151
|
-
- Impact: May cause memory issues at scale
|
|
152
|
-
- Solution: Implement LRU eviction or use Redis
|
|
153
|
-
|
|
154
|
-
📊 Summary:
|
|
155
|
-
- Critical issues: 1
|
|
156
|
-
- Important issues: 1
|
|
157
|
-
- Minor issues: 1
|
|
158
|
-
- Technical debt score: Medium
|
|
159
|
-
|
|
160
|
-
Recommendation: Address critical dependency violation before merging
|
|
161
|
-
\`\`\`
|
|
162
|
-
|
|
163
|
-
## Guidelines
|
|
164
|
-
|
|
165
|
-
- Focus on architectural implications, not minor style issues
|
|
166
|
-
- Consider both immediate and long-term impacts
|
|
167
|
-
- Provide specific, actionable solutions
|
|
168
|
-
- Explain the "why" behind each concern
|
|
169
|
-
- Balance idealism with pragmatism
|
|
170
|
-
`,
|
|
171
|
-
|
|
172
|
-
'security-auditor': `---
|
|
173
|
-
model: "claude-opus-4-5"
|
|
174
|
-
temperature: 0.3
|
|
175
|
-
description: "Identifies security vulnerabilities and risks"
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
# Security Auditor
|
|
179
|
-
|
|
180
|
-
You are a security-focused code review agent that identifies vulnerabilities, security risks, and unsafe practices.
|
|
181
|
-
|
|
182
|
-
## Your Responsibilities
|
|
183
|
-
|
|
184
|
-
### OWASP Top 10 Checks
|
|
185
|
-
- SQL Injection vulnerabilities
|
|
186
|
-
- Cross-Site Scripting (XSS)
|
|
187
|
-
- Authentication and session management flaws
|
|
188
|
-
- Insecure direct object references
|
|
189
|
-
- Security misconfiguration
|
|
190
|
-
- Sensitive data exposure
|
|
191
|
-
- Missing access control
|
|
192
|
-
- Cross-Site Request Forgery (CSRF)
|
|
193
|
-
- Using components with known vulnerabilities
|
|
194
|
-
- Insufficient logging and monitoring
|
|
195
|
-
|
|
196
|
-
### Code Security
|
|
197
|
-
- Input validation and sanitization
|
|
198
|
-
- Output encoding
|
|
199
|
-
- Parameterized queries
|
|
200
|
-
- Secure random number generation
|
|
201
|
-
- Cryptographic best practices
|
|
202
|
-
- Secrets and credential management
|
|
203
|
-
- API key and token handling
|
|
204
|
-
|
|
205
|
-
### Common Vulnerabilities
|
|
206
|
-
- Path traversal attacks
|
|
207
|
-
- Command injection
|
|
208
|
-
- XML/XXE injection
|
|
209
|
-
- Deserialization vulnerabilities
|
|
210
|
-
- Race conditions
|
|
211
|
-
- Buffer overflows (in applicable languages)
|
|
212
|
-
|
|
213
|
-
## Review Process
|
|
214
|
-
|
|
215
|
-
1. Scan for obvious security issues
|
|
216
|
-
2. Check data flow from user input to storage/output
|
|
217
|
-
3. Verify authentication and authorization
|
|
218
|
-
4. Review cryptographic usage
|
|
219
|
-
5. Check dependency versions for known vulnerabilities
|
|
220
|
-
6. Assess error handling and information disclosure
|
|
221
|
-
|
|
222
|
-
## Output Format
|
|
223
|
-
|
|
224
|
-
\`\`\`
|
|
225
|
-
🔒 Security Audit Report
|
|
226
|
-
|
|
227
|
-
Files audited: X
|
|
228
|
-
Risk Level: [Low/Medium/High/Critical]
|
|
229
|
-
|
|
230
|
-
🚨 Critical Vulnerabilities:
|
|
231
|
-
|
|
232
|
-
1. SQL Injection Risk
|
|
233
|
-
- File: src/database/user-repository.ts:34
|
|
234
|
-
- Code: \`db.query(\\\`SELECT * FROM users WHERE id = \${userId}\\\`)\`
|
|
235
|
-
- Risk: Allows arbitrary SQL execution
|
|
236
|
-
- Fix: Use parameterized query: \`db.query('SELECT * FROM users WHERE id = ?', [userId])\`
|
|
237
|
-
- CWE: CWE-89
|
|
238
|
-
|
|
239
|
-
⚠️ High Risk Issues:
|
|
240
|
-
|
|
241
|
-
2. Sensitive Data Exposure
|
|
242
|
-
- File: src/api/auth-controller.ts:89
|
|
243
|
-
- Code: User password returned in API response
|
|
244
|
-
- Risk: Password hash exposed to clients
|
|
245
|
-
- Fix: Remove password from response object
|
|
246
|
-
|
|
247
|
-
🔔 Medium Risk Issues:
|
|
248
|
-
|
|
249
|
-
3. Missing Input Validation
|
|
250
|
-
- File: src/api/upload-controller.ts:12
|
|
251
|
-
- Code: File upload without type validation
|
|
252
|
-
- Risk: Malicious file upload
|
|
253
|
-
- Fix: Validate file type and size before processing
|
|
254
|
-
|
|
255
|
-
💡 Security Recommendations:
|
|
256
|
-
|
|
257
|
-
- Enable Content Security Policy headers
|
|
258
|
-
- Implement rate limiting on authentication endpoints
|
|
259
|
-
- Add CSRF tokens to state-changing operations
|
|
260
|
-
- Use secure HTTP-only cookies for sessions
|
|
261
|
-
- Enable security headers (X-Frame-Options, etc.)
|
|
262
|
-
|
|
263
|
-
📊 Summary:
|
|
264
|
-
- Critical: 1
|
|
265
|
-
- High: 1
|
|
266
|
-
- Medium: 1
|
|
267
|
-
- Low: 0
|
|
268
|
-
|
|
269
|
-
⚠️ Action Required: Fix critical SQL injection before deployment
|
|
270
|
-
\`\`\`
|
|
271
|
-
|
|
272
|
-
## Guidelines
|
|
273
|
-
|
|
274
|
-
- Prioritize by actual risk, not theoretical scenarios
|
|
275
|
-
- Provide clear, actionable fixes with code examples
|
|
276
|
-
- Reference CWE/CVE numbers when applicable
|
|
277
|
-
- Consider the application's threat model
|
|
278
|
-
- Balance security with usability
|
|
279
|
-
- Don't create false positives unnecessarily
|
|
280
|
-
`
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
export class SubAgentGenerator {
|
|
284
|
-
async generateSubAgents(guidelineIds: string[]): Promise<SubAgentTemplate[]> {
|
|
285
|
-
const agents: SubAgentTemplate[] = [];
|
|
286
|
-
|
|
287
|
-
agents.push({
|
|
288
|
-
name: 'guideline-checker',
|
|
289
|
-
content: EMBEDDED_AGENTS['guideline-checker']
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
const hasArchitecture = guidelineIds.some((id) => id.includes('architecture'));
|
|
293
|
-
if (hasArchitecture) {
|
|
294
|
-
agents.push({
|
|
295
|
-
name: 'architecture-reviewer',
|
|
296
|
-
content: EMBEDDED_AGENTS['architecture-reviewer']
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const hasSecurity = guidelineIds.some((id) => id.includes('security'));
|
|
301
|
-
if (hasSecurity) {
|
|
302
|
-
agents.push({
|
|
303
|
-
name: 'security-auditor',
|
|
304
|
-
content: EMBEDDED_AGENTS['security-auditor']
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return agents;
|
|
309
|
-
}
|
|
310
|
-
}
|
package/src/utils/banner.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { CONFIG } from '../config.js';
|
|
3
|
-
|
|
4
|
-
// Color palette matching logo.svg
|
|
5
|
-
const colors = {
|
|
6
|
-
cyan: chalk.hex('#06b6d4'), // Neural nodes
|
|
7
|
-
purple: chalk.hex('#8b5cf6'), // Box and flow end
|
|
8
|
-
green: chalk.hex('#10b981'), // Success indicator
|
|
9
|
-
gray: chalk.hex('#94a3b8'), // Subtitle
|
|
10
|
-
white: chalk.white.bold, // Title
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export function showBanner() {
|
|
14
|
-
// ASCII art matching the new logo design with exact SVG colors
|
|
15
|
-
const logo = `
|
|
16
|
-
${colors.cyan('(●)')}
|
|
17
|
-
${colors.cyan('╲')}
|
|
18
|
-
${colors.cyan('(●)')} ${colors.cyan('───')}${colors.purple('▶')} ${colors.purple('╔═════════════════════════════╗')}
|
|
19
|
-
${colors.cyan('╱')} ${colors.purple('║')} ${colors.white('AI CONFIG GENERATOR')} ${colors.purple('║')}
|
|
20
|
-
${colors.cyan('(●)')} ${colors.purple('║')} ${colors.gray('for better coding')} ${colors.purple('║')}
|
|
21
|
-
${colors.purple('╚═════════════════════════════╝')}
|
|
22
|
-
`;
|
|
23
|
-
|
|
24
|
-
console.log(logo);
|
|
25
|
-
console.log(colors.gray(` v${CONFIG.APP_VERSION} · MIT License\n`));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function showInstructions() {
|
|
29
|
-
console.log(chalk.gray(' Navigation:'));
|
|
30
|
-
console.log(chalk.gray(' ↑↓ arrows - Navigate options'));
|
|
31
|
-
console.log(chalk.gray(' Space - Select/deselect (checkboxes)'));
|
|
32
|
-
console.log(chalk.gray(' Enter - Confirm selection'));
|
|
33
|
-
console.log(chalk.gray(' Ctrl+C - Cancel anytime\n'));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function showCheckboxInstructions() {
|
|
37
|
-
console.log(chalk.gray('\n 💡 Tip: Uncheck a category to uncheck all items in that category'));
|
|
38
|
-
console.log(chalk.gray(' Use Space to toggle, Enter to confirm\n'));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function getLogoPrefix(animated: boolean = false): string {
|
|
42
|
-
if (!animated) {
|
|
43
|
-
return `${colors.cyan('(●)')} ${colors.cyan('─')}${colors.purple('▶')} ${colors.purple('▢')}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const frames = [
|
|
47
|
-
`${colors.cyan('(●)')} ${colors.cyan('─')}${colors.purple('▶')} ${colors.gray('▢')}`,
|
|
48
|
-
`${colors.cyan('(●)')} ${colors.cyan('──')}${colors.purple('▶')} ${colors.gray('▢')}`,
|
|
49
|
-
`${colors.cyan('(●)')} ${colors.cyan('───')}${colors.purple('▶')} ${colors.gray('▢')}`,
|
|
50
|
-
`${colors.cyan('(●)')} ${colors.cyan('───')}${colors.purple('▶')} ${colors.purple('▣')}`,
|
|
51
|
-
`${colors.cyan('(●)')} ${colors.cyan('───')}${colors.purple('▶')} ${colors.green('✓')}`
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
const index = Math.floor(Date.now() / 200) % frames.length;
|
|
55
|
-
return frames[index];
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function showSmallLogo() {
|
|
59
|
-
console.log(`
|
|
60
|
-
${colors.cyan('(●)')}
|
|
61
|
-
${colors.cyan('╲')}
|
|
62
|
-
${colors.cyan('(●)')} ${colors.cyan('─')}${colors.purple('▶')} ${colors.purple('╔═══════╗')}
|
|
63
|
-
${colors.cyan('╱')} ${colors.purple('║')} ${colors.white('aicgen')} ${colors.purple('║')}
|
|
64
|
-
${colors.cyan('(●)')} ${colors.purple('╚═══════╝')}
|
|
65
|
-
`);
|
|
66
|
-
}
|
package/src/utils/errors.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export class AicgenError extends Error {
|
|
2
|
-
constructor(
|
|
3
|
-
message: string,
|
|
4
|
-
public code: string,
|
|
5
|
-
public details?: unknown
|
|
6
|
-
) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = this.constructor.name;
|
|
9
|
-
Error.captureStackTrace(this, this.constructor);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class ProjectNotFoundError extends AicgenError {
|
|
14
|
-
constructor(path: string) {
|
|
15
|
-
super(`Project not found at: ${path}`, 'PROJECT_NOT_FOUND', { path });
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class ConfigExistsError extends AicgenError {
|
|
20
|
-
constructor(path: string) {
|
|
21
|
-
super(
|
|
22
|
-
`Configuration already exists at: ${path}. Use --force to overwrite.`,
|
|
23
|
-
'CONFIG_EXISTS',
|
|
24
|
-
{ path }
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
package/src/utils/file.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from 'fs';
|
|
2
|
-
import { dirname } from 'path';
|
|
3
|
-
|
|
4
|
-
export async function exists(path: string): Promise<boolean> {
|
|
5
|
-
try {
|
|
6
|
-
await fs.access(path);
|
|
7
|
-
return true;
|
|
8
|
-
} catch {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export async function readFile(path: string): Promise<string> {
|
|
14
|
-
return fs.readFile(path, 'utf-8');
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export async function writeFile(path: string, content: string): Promise<void> {
|
|
18
|
-
await ensureDir(dirname(path));
|
|
19
|
-
const tempPath = `${path}.tmp`;
|
|
20
|
-
await fs.writeFile(tempPath, content, 'utf-8');
|
|
21
|
-
await fs.rename(tempPath, path);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export async function ensureDir(path: string): Promise<void> {
|
|
25
|
-
await fs.mkdir(path, { recursive: true });
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export async function readJSON<T>(path: string): Promise<T> {
|
|
29
|
-
const content = await readFile(path);
|
|
30
|
-
return JSON.parse(content);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function writeJSON<T>(path: string, data: T): Promise<void> {
|
|
34
|
-
const content = JSON.stringify(data, null, 2);
|
|
35
|
-
await writeFile(path, content);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface FileToWrite {
|
|
39
|
-
path: string;
|
|
40
|
-
content: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export async function writeFiles(files: FileToWrite[]): Promise<void> {
|
|
44
|
-
const tempFiles: string[] = [];
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
for (const file of files) {
|
|
48
|
-
await ensureDir(dirname(file.path));
|
|
49
|
-
const tempPath = `${file.path}.tmp`;
|
|
50
|
-
await fs.writeFile(tempPath, file.content, 'utf-8');
|
|
51
|
-
tempFiles.push(tempPath);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
for (let i = 0; i < files.length; i++) {
|
|
55
|
-
await fs.rename(tempFiles[i], files[i].path);
|
|
56
|
-
}
|
|
57
|
-
} catch (error) {
|
|
58
|
-
for (const tempPath of tempFiles) {
|
|
59
|
-
try {
|
|
60
|
-
await fs.unlink(tempPath);
|
|
61
|
-
} catch {
|
|
62
|
-
// Ignore cleanup errors
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
throw error;
|
|
66
|
-
}
|
|
67
|
-
}
|
package/src/utils/formatting.ts
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
export interface BoxOptions {
|
|
4
|
-
title?: string;
|
|
5
|
-
padding?: number;
|
|
6
|
-
width?: number;
|
|
7
|
-
borderColor?: 'cyan' | 'magenta' | 'gray' | 'white';
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function drawBox(content: string[], options: BoxOptions = {}): string {
|
|
11
|
-
const {
|
|
12
|
-
title,
|
|
13
|
-
padding = 1,
|
|
14
|
-
width = 60,
|
|
15
|
-
borderColor = 'cyan'
|
|
16
|
-
} = options;
|
|
17
|
-
|
|
18
|
-
const color = {
|
|
19
|
-
cyan: chalk.cyan,
|
|
20
|
-
magenta: chalk.magenta,
|
|
21
|
-
gray: chalk.gray,
|
|
22
|
-
white: chalk.white
|
|
23
|
-
}[borderColor];
|
|
24
|
-
|
|
25
|
-
const lines: string[] = [];
|
|
26
|
-
const contentWidth = width - 2;
|
|
27
|
-
|
|
28
|
-
// Top border
|
|
29
|
-
if (title) {
|
|
30
|
-
const titleText = ` ${title} `;
|
|
31
|
-
const leftPad = Math.floor((width - titleText.length - 2) / 2);
|
|
32
|
-
const rightPad = width - titleText.length - leftPad - 2;
|
|
33
|
-
lines.push(color('╭' + '─'.repeat(leftPad) + titleText + '─'.repeat(rightPad) + '╮'));
|
|
34
|
-
} else {
|
|
35
|
-
lines.push(color('╭' + '─'.repeat(contentWidth) + '╮'));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Padding top
|
|
39
|
-
for (let i = 0; i < padding; i++) {
|
|
40
|
-
lines.push(color('│') + ' '.repeat(contentWidth) + color('│'));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Content
|
|
44
|
-
for (const line of content) {
|
|
45
|
-
const stripped = stripAnsi(line);
|
|
46
|
-
const lineWidth = stripped.length;
|
|
47
|
-
const spacesNeeded = contentWidth - lineWidth;
|
|
48
|
-
lines.push(color('│') + line + ' '.repeat(Math.max(0, spacesNeeded)) + color('│'));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Padding bottom
|
|
52
|
-
for (let i = 0; i < padding; i++) {
|
|
53
|
-
lines.push(color('│') + ' '.repeat(contentWidth) + color('│'));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Bottom border
|
|
57
|
-
lines.push(color('╰' + '─'.repeat(contentWidth) + '╯'));
|
|
58
|
-
|
|
59
|
-
return lines.join('\n');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function drawSeparator(width: number = 60, char: string = '─', color: 'cyan' | 'magenta' | 'gray' = 'gray'): string {
|
|
63
|
-
const colorFn = {
|
|
64
|
-
cyan: chalk.cyan,
|
|
65
|
-
magenta: chalk.magenta,
|
|
66
|
-
gray: chalk.gray
|
|
67
|
-
}[color];
|
|
68
|
-
|
|
69
|
-
return colorFn(char.repeat(width));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function drawTable(headers: string[], rows: string[][], options: { borderColor?: 'cyan' | 'magenta' | 'gray' } = {}): string {
|
|
73
|
-
const borderColor = options.borderColor || 'cyan';
|
|
74
|
-
const color = {
|
|
75
|
-
cyan: chalk.cyan,
|
|
76
|
-
magenta: chalk.magenta,
|
|
77
|
-
gray: chalk.gray
|
|
78
|
-
}[borderColor];
|
|
79
|
-
|
|
80
|
-
// Calculate column widths
|
|
81
|
-
const colWidths = headers.map((header, i) => {
|
|
82
|
-
const headerWidth = stripAnsi(header).length;
|
|
83
|
-
const maxRowWidth = Math.max(...rows.map(row => stripAnsi(row[i] || '').length));
|
|
84
|
-
return Math.max(headerWidth, maxRowWidth) + 2;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const lines: string[] = [];
|
|
88
|
-
// const totalWidth = colWidths.reduce((sum, w) => sum + w, 0) + colWidths.length + 1;
|
|
89
|
-
|
|
90
|
-
// Top border
|
|
91
|
-
lines.push(color('╭' + colWidths.map(w => '─'.repeat(w)).join('┬') + '╮'));
|
|
92
|
-
|
|
93
|
-
// Headers
|
|
94
|
-
const headerLine = color('│') + headers.map((h, i) => {
|
|
95
|
-
const stripped = stripAnsi(h);
|
|
96
|
-
const padding = colWidths[i] - stripped.length;
|
|
97
|
-
return h + ' '.repeat(padding);
|
|
98
|
-
}).join(color('│')) + color('│');
|
|
99
|
-
lines.push(headerLine);
|
|
100
|
-
|
|
101
|
-
// Header separator
|
|
102
|
-
lines.push(color('├' + colWidths.map(w => '─'.repeat(w)).join('┼') + '┤'));
|
|
103
|
-
|
|
104
|
-
// Rows
|
|
105
|
-
for (const row of rows) {
|
|
106
|
-
const rowLine = color('│') + row.map((cell, i) => {
|
|
107
|
-
const stripped = stripAnsi(cell);
|
|
108
|
-
const padding = colWidths[i] - stripped.length;
|
|
109
|
-
return cell + ' '.repeat(padding);
|
|
110
|
-
}).join(color('│')) + color('│');
|
|
111
|
-
lines.push(rowLine);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Bottom border
|
|
115
|
-
lines.push(color('╰' + colWidths.map(w => '─'.repeat(w)).join('┴') + '╯'));
|
|
116
|
-
|
|
117
|
-
return lines.join('\n');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function padLeft(text: string, width: number, char: string = ' '): string {
|
|
121
|
-
const stripped = stripAnsi(text);
|
|
122
|
-
const padding = Math.max(0, width - stripped.length);
|
|
123
|
-
return char.repeat(padding) + text;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function padRight(text: string, width: number, char: string = ' '): string {
|
|
127
|
-
const stripped = stripAnsi(text);
|
|
128
|
-
const padding = Math.max(0, width - stripped.length);
|
|
129
|
-
return text + char.repeat(padding);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export function center(text: string, width: number): string {
|
|
133
|
-
const stripped = stripAnsi(text);
|
|
134
|
-
const padding = Math.max(0, width - stripped.length);
|
|
135
|
-
const leftPad = Math.floor(padding / 2);
|
|
136
|
-
const rightPad = padding - leftPad;
|
|
137
|
-
return ' '.repeat(leftPad) + text + ' '.repeat(rightPad);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Simple ANSI strip function (basic implementation)
|
|
141
|
-
function stripAnsi(str: string): string {
|
|
142
|
-
// eslint-disable-next-line no-control-regex
|
|
143
|
-
return str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export function createSummaryBox(title: string, items: { label: string; value: string }[]): string {
|
|
147
|
-
const maxLabelWidth = Math.max(...items.map(i => i.label.length));
|
|
148
|
-
const content = items.map(({ label, value }) => {
|
|
149
|
-
const paddedLabel = padRight(chalk.gray(label + ':'), maxLabelWidth + 2);
|
|
150
|
-
return ` ${paddedLabel} ${chalk.white(value)}`;
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
return drawBox(content, {
|
|
154
|
-
title,
|
|
155
|
-
padding: 1,
|
|
156
|
-
width: 60,
|
|
157
|
-
borderColor: 'cyan'
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function createMetricsBox(metrics: { label: string; value: string | number }[]): string {
|
|
162
|
-
const content = metrics.map(({ label, value }) => {
|
|
163
|
-
return ` ${chalk.gray('•')} ${chalk.white(value)} ${chalk.gray(label)}`;
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
return drawBox(content, {
|
|
167
|
-
title: '📊 Configuration Preview',
|
|
168
|
-
padding: 1,
|
|
169
|
-
width: 50,
|
|
170
|
-
borderColor: 'magenta'
|
|
171
|
-
});
|
|
172
|
-
}
|