@su-record/vibe 2.7.13 → 2.7.15
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/.env.example +37 -37
- package/CLAUDE.md +134 -126
- package/LICENSE +21 -21
- package/README.md +449 -449
- package/agents/architect-low.md +41 -41
- package/agents/architect-medium.md +59 -59
- package/agents/architect.md +80 -80
- package/agents/build-error-resolver.md +115 -115
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/docs/api-documenter.md +99 -99
- package/agents/docs/changelog-writer.md +93 -93
- package/agents/e2e-tester.md +294 -294
- package/agents/explorer-low.md +42 -42
- package/agents/explorer-medium.md +59 -59
- package/agents/explorer.md +48 -48
- package/agents/implementer-low.md +43 -43
- package/agents/implementer-medium.md +52 -52
- package/agents/implementer.md +54 -54
- package/agents/junior-mentor.md +141 -141
- package/agents/planning/requirements-analyst.md +84 -84
- package/agents/planning/ux-advisor.md +83 -83
- package/agents/qa/acceptance-tester.md +86 -86
- package/agents/qa/edge-case-finder.md +93 -93
- package/agents/refactor-cleaner.md +143 -143
- package/agents/research/best-practices-agent.md +199 -199
- package/agents/research/codebase-patterns-agent.md +157 -157
- package/agents/research/framework-docs-agent.md +188 -188
- package/agents/research/security-advisory-agent.md +213 -213
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +150 -150
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +120 -120
- package/agents/tester.md +49 -49
- package/agents/ui/ui-a11y-auditor.md +93 -93
- package/agents/ui/ui-antipattern-detector.md +94 -94
- package/agents/ui/ui-dataviz-advisor.md +69 -69
- package/agents/ui/ui-design-system-gen.md +57 -57
- package/agents/ui/ui-industry-analyzer.md +49 -49
- package/agents/ui/ui-layout-architect.md +65 -65
- package/agents/ui/ui-stack-implementer.md +68 -68
- package/agents/ui/ux-compliance-reviewer.md +81 -81
- package/agents/ui-previewer.md +258 -260
- package/commands/vibe.analyze.md +11 -13
- package/commands/vibe.review.md +43 -1
- package/commands/vibe.run.md +2124 -2078
- package/commands/vibe.spec.md +9 -4
- package/commands/vibe.spec.review.md +569 -565
- package/commands/vibe.utils.md +413 -413
- package/commands/vibe.verify.md +33 -8
- package/dist/cli/collaborator.js +52 -52
- package/dist/cli/commands/evolution.js +12 -12
- package/dist/cli/commands/info.js +54 -54
- package/dist/cli/commands/init.js +5 -5
- package/dist/cli/commands/remove.js +14 -14
- package/dist/cli/commands/sentinel.js +27 -27
- package/dist/cli/commands/skills.js +5 -5
- package/dist/cli/commands/slack.js +10 -10
- package/dist/cli/commands/telegram.js +12 -12
- package/dist/cli/detect.js +32 -32
- package/dist/cli/index.js +51 -51
- package/dist/cli/llm/claude-commands.js +16 -16
- package/dist/cli/llm/config.js +19 -19
- package/dist/cli/llm/config.js.map +1 -1
- package/dist/cli/llm/gemini-commands.js +16 -16
- package/dist/cli/llm/gpt-commands.js +19 -19
- package/dist/cli/llm/help.js +21 -21
- package/dist/cli/postinstall/cursor-agents.js +32 -32
- package/dist/cli/postinstall/cursor-rules.js +83 -83
- package/dist/cli/postinstall/cursor-skills.js +743 -743
- package/dist/cli/setup/Provisioner.js +42 -42
- package/dist/cli/types.d.ts +0 -2
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/infra/lib/DeepInit.js +24 -24
- package/dist/infra/lib/IterationTracker.js +11 -11
- package/dist/infra/lib/PythonParser.js +108 -108
- package/dist/infra/lib/ReviewRace.js +96 -96
- package/dist/infra/lib/SkillFrontmatter.js +28 -28
- package/dist/infra/lib/SkillQualityGate.js +9 -9
- package/dist/infra/lib/SkillRepository.js +159 -159
- package/dist/infra/lib/UltraQA.js +99 -99
- package/dist/infra/lib/autonomy/AuditStore.js +41 -41
- package/dist/infra/lib/autonomy/ConfirmationStore.js +30 -30
- package/dist/infra/lib/autonomy/EventOutbox.js +38 -38
- package/dist/infra/lib/autonomy/PolicyEngine.js +18 -18
- package/dist/infra/lib/autonomy/SecuritySentinel.js +1 -1
- package/dist/infra/lib/autonomy/SuggestionStore.js +33 -33
- package/dist/infra/lib/embedding/VectorStore.js +22 -22
- package/dist/infra/lib/evolution/AgentAnalyzer.js +10 -10
- package/dist/infra/lib/evolution/DescriptionOptimizer.js +21 -21
- package/dist/infra/lib/evolution/GenerationRegistry.js +36 -36
- package/dist/infra/lib/evolution/InsightStore.js +90 -90
- package/dist/infra/lib/evolution/RollbackManager.js +5 -5
- package/dist/infra/lib/evolution/SkillBenchmark.js +23 -23
- package/dist/infra/lib/evolution/SkillEvalRunner.js +50 -50
- package/dist/infra/lib/evolution/SkillGapDetector.js +10 -10
- package/dist/infra/lib/evolution/UsageTracker.js +28 -28
- package/dist/infra/lib/gemini/orchestration.js +5 -5
- package/dist/infra/lib/gpt/orchestration.js +4 -4
- package/dist/infra/lib/memory/KnowledgeGraph.js +4 -4
- package/dist/infra/lib/memory/MemorySearch.js +57 -57
- package/dist/infra/lib/memory/MemoryStorage.js +181 -181
- package/dist/infra/lib/memory/ObservationStore.js +28 -28
- package/dist/infra/lib/memory/ReflectionStore.js +30 -30
- package/dist/infra/lib/memory/SessionRAGRetriever.js +7 -7
- package/dist/infra/lib/memory/SessionRAGStore.js +225 -225
- package/dist/infra/lib/memory/SessionSummarizer.js +9 -9
- package/dist/infra/orchestrator/AgentManager.js +12 -12
- package/dist/infra/orchestrator/AgentRegistry.js +65 -65
- package/dist/infra/orchestrator/MultiLlmResearch.js +8 -8
- package/dist/infra/orchestrator/SwarmOrchestrator.test.js +16 -16
- package/dist/infra/orchestrator/parallelResearch.js +24 -24
- package/dist/tools/convention/analyzeComplexity.test.js +115 -115
- package/dist/tools/convention/validateCodeQuality.test.js +104 -104
- package/dist/tools/memory/createMemoryTimeline.js +10 -10
- package/dist/tools/memory/getMemoryGraph.js +12 -12
- package/dist/tools/memory/getSessionContext.js +9 -9
- package/dist/tools/memory/linkMemories.js +14 -14
- package/dist/tools/memory/listMemories.js +4 -4
- package/dist/tools/memory/recallMemory.js +4 -4
- package/dist/tools/memory/saveMemory.js +4 -4
- package/dist/tools/memory/searchMemoriesAdvanced.js +23 -23
- package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
- package/dist/tools/semantic/astGrep.test.js +6 -6
- package/dist/tools/spec/prdParser.test.js +171 -171
- package/dist/tools/spec/specGenerator.js +169 -169
- package/dist/tools/spec/traceabilityMatrix.js +64 -64
- package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
- package/hooks/gemini-hooks.json +73 -73
- package/hooks/hooks.json +137 -137
- package/hooks/scripts/code-check.js +77 -70
- package/hooks/scripts/context-save.js +212 -212
- package/hooks/scripts/hud-status.js +291 -291
- package/hooks/scripts/keyword-detector.js +214 -214
- package/hooks/scripts/llm-orchestrate.js +475 -475
- package/hooks/scripts/post-edit.js +32 -32
- package/hooks/scripts/pre-tool-guard.js +125 -125
- package/hooks/scripts/prompt-dispatcher.js +185 -185
- package/hooks/scripts/sentinel-guard.js +104 -104
- package/hooks/scripts/session-start.js +106 -106
- package/hooks/scripts/stop-notify.js +209 -209
- package/hooks/scripts/utils.js +100 -100
- package/languages/csharp-unity.md +515 -515
- package/languages/gdscript-godot.md +470 -470
- package/languages/ruby-rails.md +489 -489
- package/languages/typescript-angular.md +433 -433
- package/languages/typescript-astro.md +416 -416
- package/languages/typescript-electron.md +406 -406
- package/languages/typescript-nestjs.md +524 -524
- package/languages/typescript-svelte.md +407 -407
- package/languages/typescript-tauri.md +365 -365
- package/package.json +121 -121
- package/skills/agents-md/SKILL.md +120 -120
- package/skills/arch-guard/SKILL.md +180 -180
- package/skills/brand-assets/SKILL.md +146 -146
- package/skills/capability-loop/SKILL.md +167 -167
- package/skills/characterization-test/SKILL.md +206 -206
- package/skills/commerce-patterns/SKILL.md +59 -59
- package/skills/commit-push-pr/SKILL.md +75 -75
- package/skills/context7-usage/SKILL.md +105 -105
- package/skills/core-capabilities/SKILL.md +48 -48
- package/skills/e2e-commerce/SKILL.md +57 -57
- package/skills/exec-plan/SKILL.md +147 -147
- package/skills/frontend-design/SKILL.md +73 -73
- package/skills/git-worktree/SKILL.md +72 -72
- package/skills/handoff/SKILL.md +109 -109
- package/skills/parallel-research/SKILL.md +87 -87
- package/skills/priority-todos/SKILL.md +63 -63
- package/skills/seo-checklist/SKILL.md +57 -57
- package/skills/techdebt/SKILL.md +122 -122
- package/skills/tool-fallback/SKILL.md +103 -103
- package/skills/typescript-advanced-types/SKILL.md +66 -65
- package/skills/ui-ux-pro-max/SKILL.md +206 -206
- package/skills/vercel-react-best-practices/SKILL.md +59 -59
- package/skills/video-production/SKILL.md +51 -51
- package/vibe/config.json +29 -29
- package/vibe/constitution.md +227 -227
- package/vibe/rules/principles/communication-guide.md +98 -98
- package/vibe/rules/principles/development-philosophy.md +52 -52
- package/vibe/rules/principles/quick-start.md +102 -102
- package/vibe/rules/quality/bdd-contract-testing.md +393 -393
- package/vibe/rules/quality/checklist.md +276 -276
- package/vibe/rules/quality/performance.md +236 -236
- package/vibe/rules/quality/testing-strategy.md +440 -440
- package/vibe/rules/standards/anti-patterns.md +541 -541
- package/vibe/rules/standards/code-structure.md +291 -291
- package/vibe/rules/standards/complexity-metrics.md +313 -313
- package/vibe/rules/standards/git-workflow.md +237 -237
- package/vibe/rules/standards/naming-conventions.md +198 -198
- package/vibe/rules/standards/security.md +305 -305
- package/vibe/rules/writing/document-style.md +74 -74
- package/vibe/setup.sh +31 -31
- package/vibe/templates/constitution-template.md +252 -252
- package/vibe/templates/contract-backend-template.md +526 -526
- package/vibe/templates/contract-frontend-template.md +599 -599
- package/vibe/templates/feature-template.md +96 -96
- package/vibe/templates/spec-template.md +221 -221
- package/vibe/ui-ux-data/charts.csv +26 -26
- package/vibe/ui-ux-data/colors.csv +97 -97
- package/vibe/ui-ux-data/icons.csv +101 -101
- package/vibe/ui-ux-data/landing.csv +31 -31
- package/vibe/ui-ux-data/products.csv +96 -96
- package/vibe/ui-ux-data/react-performance.csv +45 -45
- package/vibe/ui-ux-data/stacks/astro.csv +54 -54
- package/vibe/ui-ux-data/stacks/flutter.csv +53 -53
- package/vibe/ui-ux-data/stacks/html-tailwind.csv +56 -56
- package/vibe/ui-ux-data/stacks/jetpack-compose.csv +53 -53
- package/vibe/ui-ux-data/stacks/nextjs.csv +53 -53
- package/vibe/ui-ux-data/stacks/nuxt-ui.csv +51 -51
- package/vibe/ui-ux-data/stacks/nuxtjs.csv +59 -59
- package/vibe/ui-ux-data/stacks/react-native.csv +52 -52
- package/vibe/ui-ux-data/stacks/react.csv +54 -54
- package/vibe/ui-ux-data/stacks/shadcn.csv +61 -61
- package/vibe/ui-ux-data/stacks/svelte.csv +54 -54
- package/vibe/ui-ux-data/stacks/swiftui.csv +51 -51
- package/vibe/ui-ux-data/stacks/vue.csv +50 -50
- package/vibe/ui-ux-data/styles.csv +68 -68
- package/vibe/ui-ux-data/typography.csv +57 -57
- package/vibe/ui-ux-data/ui-reasoning.csv +101 -101
- package/vibe/ui-ux-data/ux-guidelines.csv +99 -99
- package/vibe/ui-ux-data/version.json +31 -31
- package/vibe/ui-ux-data/web-interface.csv +31 -31
|
@@ -1,313 +1,313 @@
|
|
|
1
|
-
# Software Engineering Complexity Measurement
|
|
2
|
-
|
|
3
|
-
## 4.1 Complexity Metrics
|
|
4
|
-
|
|
5
|
-
### Cyclomatic Complexity
|
|
6
|
-
|
|
7
|
-
**Definition**: Number of independent execution paths in code
|
|
8
|
-
|
|
9
|
-
**Target**: ≤ 10
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
// ❌ High cyclomatic complexity (6)
|
|
13
|
-
function processUser(user) {
|
|
14
|
-
if (user.isActive) { // +1
|
|
15
|
-
if (user.hasPermission) { // +1
|
|
16
|
-
if (user.email) { // +1
|
|
17
|
-
if (user.verified) { // +1
|
|
18
|
-
return processData();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// ✅ Low cyclomatic complexity (4) - Using early returns
|
|
27
|
-
function processUser(user) {
|
|
28
|
-
if (!user.isActive) return null; // +1
|
|
29
|
-
if (!user.hasPermission) return null; // +1
|
|
30
|
-
if (!user.email) return null; // +1
|
|
31
|
-
if (!user.verified) return null; // +1
|
|
32
|
-
|
|
33
|
-
return processData();
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Cognitive Complexity
|
|
38
|
-
|
|
39
|
-
**Definition**: Mental effort required to understand code
|
|
40
|
-
|
|
41
|
-
**Target**: ≤ 15
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
// ❌ High cognitive complexity
|
|
45
|
-
function calculateDiscount(user, items) {
|
|
46
|
-
let discount = 0;
|
|
47
|
-
if (user.isPremium) { // +1
|
|
48
|
-
for (let item of items) { // +1 (nesting)
|
|
49
|
-
if (item.category === 'electronics') { // +2 (nested if)
|
|
50
|
-
discount += item.price * 0.1;
|
|
51
|
-
} else if (item.category === 'books') { // +1
|
|
52
|
-
discount += item.price * 0.05;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return discount;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// ✅ Low cognitive complexity - Function separation
|
|
60
|
-
function calculateDiscount(user, items) {
|
|
61
|
-
if (!user.isPremium) return 0; // +1
|
|
62
|
-
return items.reduce((total, item) => total + getItemDiscount(item), 0);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function getItemDiscount(item) {
|
|
66
|
-
const discountRates = {
|
|
67
|
-
electronics: 0.1,
|
|
68
|
-
books: 0.05,
|
|
69
|
-
};
|
|
70
|
-
return item.price * (discountRates[item.category] || 0);
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Halstead Metrics
|
|
75
|
-
|
|
76
|
-
**Measurements**:
|
|
77
|
-
|
|
78
|
-
- **Operators**: Operators (=, +, -, *, if, for, etc.)
|
|
79
|
-
- **Operands**: Operands (variables, constants, function names)
|
|
80
|
-
- **Vocabulary**: Unique operators + unique operands
|
|
81
|
-
- **Length**: Total token count
|
|
82
|
-
- **Difficulty**: Code comprehension difficulty
|
|
83
|
-
- **Effort**: Mental effort required to write code
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
// Halstead metrics measurement example
|
|
87
|
-
function calculateArea(radius: number): number {
|
|
88
|
-
const pi = 3.14159;
|
|
89
|
-
return pi * radius * radius;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/*
|
|
93
|
-
Operators: =, *, const, function, :, return (6)
|
|
94
|
-
Operands: calculateArea, radius, number, pi, 3.14159 (5)
|
|
95
|
-
Vocabulary: 6 + 5 = 11
|
|
96
|
-
Length: Total token count
|
|
97
|
-
Difficulty: Calculated from Vocabulary and operand repetition
|
|
98
|
-
Effort: Difficulty × Volume
|
|
99
|
-
*/
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## 4.2 Coupling & Cohesion
|
|
103
|
-
|
|
104
|
-
### Loose Coupling
|
|
105
|
-
|
|
106
|
-
**Goal**: Minimize dependencies between modules
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
// ❌ Tight coupling - Direct dependencies
|
|
110
|
-
class UserService {
|
|
111
|
-
constructor() {
|
|
112
|
-
this.database = new PostgreSQLDatabase(); // Direct dependency
|
|
113
|
-
this.emailService = new SendGridEmail(); // Direct dependency
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// ✅ Loose coupling - Dependency injection
|
|
118
|
-
interface IDatabase {
|
|
119
|
-
save(data: unknown): Promise<void>;
|
|
120
|
-
load(id: string): Promise<unknown>;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
interface IEmailService {
|
|
124
|
-
send(to: string, message: string): Promise<void>;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
class UserService {
|
|
128
|
-
constructor(
|
|
129
|
-
private database: IDatabase,
|
|
130
|
-
private emailService: IEmailService
|
|
131
|
-
) {}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Usage
|
|
135
|
-
const userService = new UserService(
|
|
136
|
-
new PostgreSQLDatabase(),
|
|
137
|
-
new SendGridEmail()
|
|
138
|
-
);
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### High Cohesion
|
|
142
|
-
|
|
143
|
-
**Goal**: Group only related functions together
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
// ❌ Low cohesion - Unrelated functions
|
|
147
|
-
class Utils {
|
|
148
|
-
validateEmail(email: string) { /* */ }
|
|
149
|
-
formatCurrency(amount: number) { /* */ }
|
|
150
|
-
sendNotification(message: string) { /* */ }
|
|
151
|
-
calculateTax(income: number) { /* */ }
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// ✅ High cohesion - Only related functions
|
|
155
|
-
class EmailValidator {
|
|
156
|
-
validateFormat(email: string) { /* */ }
|
|
157
|
-
validateDomain(email: string) { /* */ }
|
|
158
|
-
validateMX(email: string) { /* */ }
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
class CurrencyFormatter {
|
|
162
|
-
formatKRW(amount: number) { /* */ }
|
|
163
|
-
formatUSD(amount: number) { /* */ }
|
|
164
|
-
parseAmount(formatted: string) { /* */ }
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
class TaxCalculator {
|
|
168
|
-
calculateIncomeTax(income: number) { /* */ }
|
|
169
|
-
calculateVAT(amount: number) { /* */ }
|
|
170
|
-
calculateTotal(income: number) { /* */ }
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## Complexity Reduction Strategies
|
|
175
|
-
|
|
176
|
-
### 1. Early Return Pattern
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
// ❌ Nested if statements
|
|
180
|
-
function processOrder(order: Order) {
|
|
181
|
-
if (order) {
|
|
182
|
-
if (order.isValid) {
|
|
183
|
-
if (order.items.length > 0) {
|
|
184
|
-
if (order.user.isActive) {
|
|
185
|
-
return processItems(order.items);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// ✅ Early return
|
|
194
|
-
function processOrder(order: Order) {
|
|
195
|
-
if (!order) return null;
|
|
196
|
-
if (!order.isValid) return null;
|
|
197
|
-
if (order.items.length === 0) return null;
|
|
198
|
-
if (!order.user.isActive) return null;
|
|
199
|
-
|
|
200
|
-
return processItems(order.items);
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### 2. Strategy Pattern
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
// ❌ Complex if-else chain
|
|
208
|
-
function calculateShipping(type: string, weight: number) {
|
|
209
|
-
if (type === 'express') {
|
|
210
|
-
return weight * 5 + 10;
|
|
211
|
-
} else if (type === 'standard') {
|
|
212
|
-
return weight * 3 + 5;
|
|
213
|
-
} else if (type === 'economy') {
|
|
214
|
-
return weight * 2;
|
|
215
|
-
}
|
|
216
|
-
return 0;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// ✅ Strategy pattern
|
|
220
|
-
interface ShippingStrategy {
|
|
221
|
-
calculate(weight: number): number;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
class ExpressShipping implements ShippingStrategy {
|
|
225
|
-
calculate(weight: number) {
|
|
226
|
-
return weight * 5 + 10;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
class StandardShipping implements ShippingStrategy {
|
|
231
|
-
calculate(weight: number) {
|
|
232
|
-
return weight * 3 + 5;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const strategies: Record<string, ShippingStrategy> = {
|
|
237
|
-
express: new ExpressShipping(),
|
|
238
|
-
standard: new StandardShipping(),
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
function calculateShipping(type: string, weight: number) {
|
|
242
|
-
const strategy = strategies[type];
|
|
243
|
-
return strategy ? strategy.calculate(weight) : 0;
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
### 3. Extract Function
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
// ❌ Long function
|
|
251
|
-
function processUserRegistration(userData: UserData) {
|
|
252
|
-
// 20 lines: Email validation
|
|
253
|
-
// 15 lines: Password hashing
|
|
254
|
-
// 10 lines: Database save
|
|
255
|
-
// 5 lines: Welcome email
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// ✅ Extract functions
|
|
259
|
-
function processUserRegistration(userData: UserData) {
|
|
260
|
-
validateEmail(userData.email);
|
|
261
|
-
const hashedPassword = hashPassword(userData.password);
|
|
262
|
-
const user = saveToDatabase({ ...userData, password: hashedPassword });
|
|
263
|
-
sendWelcomeEmail(user.email);
|
|
264
|
-
return user;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function validateEmail(email: string) { /* ... */ }
|
|
268
|
-
function hashPassword(password: string) { /* ... */ }
|
|
269
|
-
function saveToDatabase(data: UserData) { /* ... */ }
|
|
270
|
-
function sendWelcomeEmail(email: string) { /* ... */ }
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
## Measurement Tools
|
|
274
|
-
|
|
275
|
-
### TypeScript/JavaScript
|
|
276
|
-
|
|
277
|
-
```bash
|
|
278
|
-
# ESLint (complexity measurement plugin)
|
|
279
|
-
npm install eslint-plugin-complexity
|
|
280
|
-
|
|
281
|
-
# .eslintrc.js
|
|
282
|
-
{
|
|
283
|
-
"rules": {
|
|
284
|
-
"complexity": ["error", 10],
|
|
285
|
-
"max-depth": ["error", 3],
|
|
286
|
-
"max-lines-per-function": ["error", 20]
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Python
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
# Radon (complexity measurement tool)
|
|
295
|
-
pip install radon
|
|
296
|
-
|
|
297
|
-
# Cyclomatic Complexity
|
|
298
|
-
radon cc app/ -a -nc
|
|
299
|
-
|
|
300
|
-
# Maintainability Index
|
|
301
|
-
radon mi app/
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
## Target Metrics Summary
|
|
305
|
-
|
|
306
|
-
| Metric | Target | Description |
|
|
307
|
-
|--------|--------|-------------|
|
|
308
|
-
| Cyclomatic Complexity | ≤ 10 | Independent execution paths |
|
|
309
|
-
| Cognitive Complexity | ≤ 15 | Easy to understand |
|
|
310
|
-
| Function Length | ≤ 20 lines | Short, focused functions |
|
|
311
|
-
| Nesting Depth | ≤ 3 levels | Flat structure |
|
|
312
|
-
| Parameters | ≤ 5 | Function parameter limit |
|
|
313
|
-
| Dependencies | ≤ 7 | Module dependency limit |
|
|
1
|
+
# Software Engineering Complexity Measurement
|
|
2
|
+
|
|
3
|
+
## 4.1 Complexity Metrics
|
|
4
|
+
|
|
5
|
+
### Cyclomatic Complexity
|
|
6
|
+
|
|
7
|
+
**Definition**: Number of independent execution paths in code
|
|
8
|
+
|
|
9
|
+
**Target**: ≤ 10
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// ❌ High cyclomatic complexity (6)
|
|
13
|
+
function processUser(user) {
|
|
14
|
+
if (user.isActive) { // +1
|
|
15
|
+
if (user.hasPermission) { // +1
|
|
16
|
+
if (user.email) { // +1
|
|
17
|
+
if (user.verified) { // +1
|
|
18
|
+
return processData();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ✅ Low cyclomatic complexity (4) - Using early returns
|
|
27
|
+
function processUser(user) {
|
|
28
|
+
if (!user.isActive) return null; // +1
|
|
29
|
+
if (!user.hasPermission) return null; // +1
|
|
30
|
+
if (!user.email) return null; // +1
|
|
31
|
+
if (!user.verified) return null; // +1
|
|
32
|
+
|
|
33
|
+
return processData();
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Cognitive Complexity
|
|
38
|
+
|
|
39
|
+
**Definition**: Mental effort required to understand code
|
|
40
|
+
|
|
41
|
+
**Target**: ≤ 15
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// ❌ High cognitive complexity
|
|
45
|
+
function calculateDiscount(user, items) {
|
|
46
|
+
let discount = 0;
|
|
47
|
+
if (user.isPremium) { // +1
|
|
48
|
+
for (let item of items) { // +1 (nesting)
|
|
49
|
+
if (item.category === 'electronics') { // +2 (nested if)
|
|
50
|
+
discount += item.price * 0.1;
|
|
51
|
+
} else if (item.category === 'books') { // +1
|
|
52
|
+
discount += item.price * 0.05;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return discount;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ✅ Low cognitive complexity - Function separation
|
|
60
|
+
function calculateDiscount(user, items) {
|
|
61
|
+
if (!user.isPremium) return 0; // +1
|
|
62
|
+
return items.reduce((total, item) => total + getItemDiscount(item), 0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function getItemDiscount(item) {
|
|
66
|
+
const discountRates = {
|
|
67
|
+
electronics: 0.1,
|
|
68
|
+
books: 0.05,
|
|
69
|
+
};
|
|
70
|
+
return item.price * (discountRates[item.category] || 0);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Halstead Metrics
|
|
75
|
+
|
|
76
|
+
**Measurements**:
|
|
77
|
+
|
|
78
|
+
- **Operators**: Operators (=, +, -, *, if, for, etc.)
|
|
79
|
+
- **Operands**: Operands (variables, constants, function names)
|
|
80
|
+
- **Vocabulary**: Unique operators + unique operands
|
|
81
|
+
- **Length**: Total token count
|
|
82
|
+
- **Difficulty**: Code comprehension difficulty
|
|
83
|
+
- **Effort**: Mental effort required to write code
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// Halstead metrics measurement example
|
|
87
|
+
function calculateArea(radius: number): number {
|
|
88
|
+
const pi = 3.14159;
|
|
89
|
+
return pi * radius * radius;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/*
|
|
93
|
+
Operators: =, *, const, function, :, return (6)
|
|
94
|
+
Operands: calculateArea, radius, number, pi, 3.14159 (5)
|
|
95
|
+
Vocabulary: 6 + 5 = 11
|
|
96
|
+
Length: Total token count
|
|
97
|
+
Difficulty: Calculated from Vocabulary and operand repetition
|
|
98
|
+
Effort: Difficulty × Volume
|
|
99
|
+
*/
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 4.2 Coupling & Cohesion
|
|
103
|
+
|
|
104
|
+
### Loose Coupling
|
|
105
|
+
|
|
106
|
+
**Goal**: Minimize dependencies between modules
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// ❌ Tight coupling - Direct dependencies
|
|
110
|
+
class UserService {
|
|
111
|
+
constructor() {
|
|
112
|
+
this.database = new PostgreSQLDatabase(); // Direct dependency
|
|
113
|
+
this.emailService = new SendGridEmail(); // Direct dependency
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ✅ Loose coupling - Dependency injection
|
|
118
|
+
interface IDatabase {
|
|
119
|
+
save(data: unknown): Promise<void>;
|
|
120
|
+
load(id: string): Promise<unknown>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
interface IEmailService {
|
|
124
|
+
send(to: string, message: string): Promise<void>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
class UserService {
|
|
128
|
+
constructor(
|
|
129
|
+
private database: IDatabase,
|
|
130
|
+
private emailService: IEmailService
|
|
131
|
+
) {}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Usage
|
|
135
|
+
const userService = new UserService(
|
|
136
|
+
new PostgreSQLDatabase(),
|
|
137
|
+
new SendGridEmail()
|
|
138
|
+
);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### High Cohesion
|
|
142
|
+
|
|
143
|
+
**Goal**: Group only related functions together
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// ❌ Low cohesion - Unrelated functions
|
|
147
|
+
class Utils {
|
|
148
|
+
validateEmail(email: string) { /* */ }
|
|
149
|
+
formatCurrency(amount: number) { /* */ }
|
|
150
|
+
sendNotification(message: string) { /* */ }
|
|
151
|
+
calculateTax(income: number) { /* */ }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ✅ High cohesion - Only related functions
|
|
155
|
+
class EmailValidator {
|
|
156
|
+
validateFormat(email: string) { /* */ }
|
|
157
|
+
validateDomain(email: string) { /* */ }
|
|
158
|
+
validateMX(email: string) { /* */ }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
class CurrencyFormatter {
|
|
162
|
+
formatKRW(amount: number) { /* */ }
|
|
163
|
+
formatUSD(amount: number) { /* */ }
|
|
164
|
+
parseAmount(formatted: string) { /* */ }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
class TaxCalculator {
|
|
168
|
+
calculateIncomeTax(income: number) { /* */ }
|
|
169
|
+
calculateVAT(amount: number) { /* */ }
|
|
170
|
+
calculateTotal(income: number) { /* */ }
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Complexity Reduction Strategies
|
|
175
|
+
|
|
176
|
+
### 1. Early Return Pattern
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// ❌ Nested if statements
|
|
180
|
+
function processOrder(order: Order) {
|
|
181
|
+
if (order) {
|
|
182
|
+
if (order.isValid) {
|
|
183
|
+
if (order.items.length > 0) {
|
|
184
|
+
if (order.user.isActive) {
|
|
185
|
+
return processItems(order.items);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ✅ Early return
|
|
194
|
+
function processOrder(order: Order) {
|
|
195
|
+
if (!order) return null;
|
|
196
|
+
if (!order.isValid) return null;
|
|
197
|
+
if (order.items.length === 0) return null;
|
|
198
|
+
if (!order.user.isActive) return null;
|
|
199
|
+
|
|
200
|
+
return processItems(order.items);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### 2. Strategy Pattern
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// ❌ Complex if-else chain
|
|
208
|
+
function calculateShipping(type: string, weight: number) {
|
|
209
|
+
if (type === 'express') {
|
|
210
|
+
return weight * 5 + 10;
|
|
211
|
+
} else if (type === 'standard') {
|
|
212
|
+
return weight * 3 + 5;
|
|
213
|
+
} else if (type === 'economy') {
|
|
214
|
+
return weight * 2;
|
|
215
|
+
}
|
|
216
|
+
return 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ✅ Strategy pattern
|
|
220
|
+
interface ShippingStrategy {
|
|
221
|
+
calculate(weight: number): number;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
class ExpressShipping implements ShippingStrategy {
|
|
225
|
+
calculate(weight: number) {
|
|
226
|
+
return weight * 5 + 10;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
class StandardShipping implements ShippingStrategy {
|
|
231
|
+
calculate(weight: number) {
|
|
232
|
+
return weight * 3 + 5;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const strategies: Record<string, ShippingStrategy> = {
|
|
237
|
+
express: new ExpressShipping(),
|
|
238
|
+
standard: new StandardShipping(),
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
function calculateShipping(type: string, weight: number) {
|
|
242
|
+
const strategy = strategies[type];
|
|
243
|
+
return strategy ? strategy.calculate(weight) : 0;
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 3. Extract Function
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
// ❌ Long function
|
|
251
|
+
function processUserRegistration(userData: UserData) {
|
|
252
|
+
// 20 lines: Email validation
|
|
253
|
+
// 15 lines: Password hashing
|
|
254
|
+
// 10 lines: Database save
|
|
255
|
+
// 5 lines: Welcome email
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ✅ Extract functions
|
|
259
|
+
function processUserRegistration(userData: UserData) {
|
|
260
|
+
validateEmail(userData.email);
|
|
261
|
+
const hashedPassword = hashPassword(userData.password);
|
|
262
|
+
const user = saveToDatabase({ ...userData, password: hashedPassword });
|
|
263
|
+
sendWelcomeEmail(user.email);
|
|
264
|
+
return user;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function validateEmail(email: string) { /* ... */ }
|
|
268
|
+
function hashPassword(password: string) { /* ... */ }
|
|
269
|
+
function saveToDatabase(data: UserData) { /* ... */ }
|
|
270
|
+
function sendWelcomeEmail(email: string) { /* ... */ }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Measurement Tools
|
|
274
|
+
|
|
275
|
+
### TypeScript/JavaScript
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
# ESLint (complexity measurement plugin)
|
|
279
|
+
npm install eslint-plugin-complexity
|
|
280
|
+
|
|
281
|
+
# .eslintrc.js
|
|
282
|
+
{
|
|
283
|
+
"rules": {
|
|
284
|
+
"complexity": ["error", 10],
|
|
285
|
+
"max-depth": ["error", 3],
|
|
286
|
+
"max-lines-per-function": ["error", 20]
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Python
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Radon (complexity measurement tool)
|
|
295
|
+
pip install radon
|
|
296
|
+
|
|
297
|
+
# Cyclomatic Complexity
|
|
298
|
+
radon cc app/ -a -nc
|
|
299
|
+
|
|
300
|
+
# Maintainability Index
|
|
301
|
+
radon mi app/
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Target Metrics Summary
|
|
305
|
+
|
|
306
|
+
| Metric | Target | Description |
|
|
307
|
+
|--------|--------|-------------|
|
|
308
|
+
| Cyclomatic Complexity | ≤ 10 | Independent execution paths |
|
|
309
|
+
| Cognitive Complexity | ≤ 15 | Easy to understand |
|
|
310
|
+
| Function Length | ≤ 20 lines | Short, focused functions |
|
|
311
|
+
| Nesting Depth | ≤ 3 levels | Flat structure |
|
|
312
|
+
| Parameters | ≤ 5 | Function parameter limit |
|
|
313
|
+
| Dependencies | ≤ 7 | Module dependency limit |
|