anchi-kit 1.2.0 → 1.2.1

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 (80) hide show
  1. package/.antigravity/skills/article-extractor/SKILL.md +52 -0
  2. package/.antigravity/skills/artifacts-builder/SKILL.md +63 -0
  3. package/.antigravity/skills/aws-deployment/SKILL.md +85 -0
  4. package/.antigravity/skills/brainstorming/SKILL.md +73 -0
  5. package/.antigravity/skills/canvas-design/SKILL.md +62 -0
  6. package/.antigravity/skills/changelog-generator/SKILL.md +149 -0
  7. package/.antigravity/skills/changelog-generator/assets/changelog-template.md +60 -0
  8. package/.antigravity/skills/changelog-generator/scripts/generate-changelog.js +181 -0
  9. package/.antigravity/skills/claude-code/references/advanced-features.md +399 -0
  10. package/.antigravity/skills/claude-code/references/agent-skills.md +399 -0
  11. package/.antigravity/skills/claude-code/references/api-reference.md +498 -0
  12. package/.antigravity/skills/claude-code/references/best-practices.md +447 -0
  13. package/.antigravity/skills/claude-code/references/cicd-integration.md +428 -0
  14. package/.antigravity/skills/claude-code/references/common-workflows.md +119 -0
  15. package/.antigravity/skills/claude-code/references/configuration.md +480 -0
  16. package/.antigravity/skills/claude-code/references/enterprise-features.md +472 -0
  17. package/.antigravity/skills/claude-code/references/getting-started.md +252 -0
  18. package/.antigravity/skills/claude-code/references/hooks-and-plugins.md +444 -0
  19. package/.antigravity/skills/claude-code/references/hooks-comprehensive.md +622 -0
  20. package/.antigravity/skills/claude-code/references/ide-integration.md +316 -0
  21. package/.antigravity/skills/claude-code/references/mcp-integration.md +386 -0
  22. package/.antigravity/skills/claude-code/references/slash-commands.md +489 -0
  23. package/.antigravity/skills/claude-code/references/troubleshooting.md +456 -0
  24. package/.antigravity/skills/claude-code/skill.md +60 -0
  25. package/.antigravity/skills/code-quality/SKILL.md +273 -0
  26. package/.antigravity/skills/comprehensive-review/complexity.md +11 -0
  27. package/.antigravity/skills/comprehensive-review/index.yaml +19 -0
  28. package/.antigravity/skills/comprehensive-review/maintainability.md +12 -0
  29. package/.antigravity/skills/comprehensive-review/readability.md +12 -0
  30. package/.antigravity/skills/content-research-writer/SKILL.md +65 -0
  31. package/.antigravity/skills/csv-data-analyzer/SKILL.md +91 -0
  32. package/.antigravity/skills/d3-visualization/SKILL.md +65 -0
  33. package/.antigravity/skills/debugging/references/root-cause-analysis-methods.md +140 -0
  34. package/.antigravity/skills/engineering-discipline/incremental-change.md +15 -0
  35. package/.antigravity/skills/engineering-discipline/index.yaml +30 -0
  36. package/.antigravity/skills/engineering-discipline/planning-first.md +18 -0
  37. package/.antigravity/skills/engineering-discipline/reasoning-clarity.md +19 -0
  38. package/.antigravity/skills/engineering-discipline/verify-before-commit.md +17 -0
  39. package/.antigravity/skills/file-organizer/SKILL.md +64 -0
  40. package/.antigravity/skills/git-automation/SKILL.md +68 -0
  41. package/.antigravity/skills/git-automation/references/branch-finishing.md +64 -0
  42. package/.antigravity/skills/impact-scoring/SKILL.md +219 -0
  43. package/.antigravity/skills/kaizen/SKILL.md +94 -0
  44. package/.antigravity/skills/performance-patterns/SKILL.md +209 -0
  45. package/.antigravity/skills/playwright-testing/SKILL.md +115 -0
  46. package/.antigravity/skills/playwright-testing/references/playwright-patterns.md +122 -0
  47. package/.antigravity/skills/prompt-engineering/SKILL.md +126 -0
  48. package/.antigravity/skills/prompt-engineering/references/anthropic-best-practices.md +160 -0
  49. package/.antigravity/skills/pypict-testing/SKILL.md +79 -0
  50. package/.antigravity/skills/review-implementing/SKILL.md +287 -0
  51. package/.antigravity/skills/security-audit/SKILL.md +263 -0
  52. package/.antigravity/skills/software-architecture/SKILL.md +91 -0
  53. package/.antigravity/skills/software-architecture/references/solid-principles.md +293 -0
  54. package/.antigravity/skills/subagent-driven-development/SKILL.md +237 -0
  55. package/.antigravity/skills/test-driven-development/SKILL.md +130 -0
  56. package/.antigravity/skills/test-driven-development/references/tdd-patterns.md +124 -0
  57. package/.antigravity/skills/test-driven-development/references/testing-strategies.md +131 -0
  58. package/.antigravity/skills/test-fixing/SKILL.md +256 -0
  59. package/.antigravity/skills/theme-factory/SKILL.md +63 -0
  60. package/.antigravity/workflows/clean.md +333 -0
  61. package/.antigravity/workflows/health.md +228 -0
  62. package/.cursor/skills/_packs/common/pack-architecture.md +40 -0
  63. package/.cursor/skills/_packs/common/pack-devops.md +43 -0
  64. package/.cursor/skills/_packs/common/pack-productivity.md +37 -0
  65. package/.cursor/skills/_packs/common/pack-quality.md +41 -0
  66. package/.cursor/skills/_packs/data/pack-ai.md +41 -0
  67. package/.cursor/skills/_packs/data/pack-data-science.md +36 -0
  68. package/.cursor/skills/_packs/mobile/pack-mobile.md +40 -0
  69. package/.cursor/skills/_packs/web/pack-backend.md +61 -0
  70. package/.cursor/skills/_packs/web/pack-frontend.md +66 -0
  71. package/.cursor/skills/_packs/web3/pack-blockchain.md +37 -0
  72. package/.cursor/skills/advanced-coding/references/getting-started.md +93 -0
  73. package/.cursor/skills/advanced-coding/skill.md +34 -0
  74. package/.cursor/skills/template-skill/SKILL.md +6 -0
  75. package/README.md +1 -1
  76. package/docs/reference/SECURITY.md +1 -1
  77. package/package.json +2 -2
  78. package/src/cli.js +5 -5
  79. package/src/commands/dashboard.js +3 -3
  80. package/src/commands/init.js +15 -3
@@ -0,0 +1,263 @@
1
+ # Security Audit Skill
2
+
3
+ > Domain knowledge for writing secure code and preventing vulnerabilities.
4
+
5
+ ---
6
+
7
+ ## 🔐 OWASP Top 10 Prevention
8
+
9
+ ### 1. Injection (SQL, NoSQL, Command)
10
+
11
+ **❌ Vulnerable:**
12
+
13
+ ```typescript
14
+ // SQL Injection
15
+ const user = await db.query(`SELECT * FROM users WHERE id = ${id}`);
16
+
17
+ // Command Injection
18
+ exec(`ls ${userInput}`);
19
+ ```
20
+
21
+ **✅ Secure:**
22
+
23
+ ```typescript
24
+ // Parameterized queries
25
+ const user = await prisma.user.findUnique({ where: { id } });
26
+
27
+ // Avoid shell commands, use libraries
28
+ import { readdir } from "fs/promises";
29
+ const files = await readdir(safeDirectory);
30
+ ```
31
+
32
+ ---
33
+
34
+ ### 2. Broken Authentication
35
+
36
+ **Checklist:**
37
+
38
+ - [ ] Passwords hashed with bcrypt/argon2 (cost ≥ 10)
39
+ - [ ] Session tokens are random and long (≥ 32 bytes)
40
+ - [ ] Sessions expire (max 24h for sensitive, 30d for remember-me)
41
+ - [ ] Rate limiting on login (5 attempts/minute)
42
+ - [ ] Account lockout after repeated failures
43
+ - [ ] MFA available for sensitive accounts
44
+
45
+ ```typescript
46
+ // Password hashing
47
+ import bcrypt from "bcrypt";
48
+ const hash = await bcrypt.hash(password, 12);
49
+ const valid = await bcrypt.compare(password, hash);
50
+
51
+ // Secure session
52
+ import { randomBytes } from "crypto";
53
+ const sessionToken = randomBytes(32).toString("hex");
54
+ ```
55
+
56
+ ---
57
+
58
+ ### 3. Sensitive Data Exposure
59
+
60
+ **Checklist:**
61
+
62
+ - [ ] HTTPS everywhere (no HTTP)
63
+ - [ ] Sensitive data encrypted at rest
64
+ - [ ] API keys in environment variables, never in code
65
+ - [ ] Passwords never logged
66
+ - [ ] PII masked in logs
67
+
68
+ ```typescript
69
+ // Never log sensitive data
70
+ console.log(`User login: ${email}`); // ❌
71
+ console.log(`User login: ${maskEmail(email)}`); // ✅
72
+
73
+ // Environment variables
74
+ const apiKey = process.env.STRIPE_SECRET_KEY; // ✅
75
+ const apiKey = "sk_live_abc123"; // ❌ NEVER
76
+ ```
77
+
78
+ ---
79
+
80
+ ### 4. Cross-Site Scripting (XSS)
81
+
82
+ **❌ Vulnerable:**
83
+
84
+ ```typescript
85
+ // React dangerouslySetInnerHTML
86
+ <div dangerouslySetInnerHTML={{ __html: userContent }} />;
87
+
88
+ // Direct DOM manipulation
89
+ document.getElementById("output").innerHTML = userInput;
90
+ ```
91
+
92
+ **✅ Secure:**
93
+
94
+ ```typescript
95
+ // React auto-escapes
96
+ <div>{userContent}</div>;
97
+
98
+ // Sanitize HTML if needed
99
+ import DOMPurify from "dompurify";
100
+ <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} />;
101
+
102
+ // CSP Headers
103
+ res.setHeader("Content-Security-Policy", "default-src 'self'");
104
+ ```
105
+
106
+ ---
107
+
108
+ ### 5. Cross-Site Request Forgery (CSRF)
109
+
110
+ **Protection:**
111
+
112
+ ```typescript
113
+ // 1. CSRF Token (forms)
114
+ <input type="hidden" name="_csrf" value={csrfToken} />;
115
+
116
+ // 2. SameSite cookies
117
+ res.cookie("session", token, {
118
+ httpOnly: true,
119
+ secure: true,
120
+ sameSite: "lax", // or 'strict' for sensitive
121
+ });
122
+
123
+ // 3. Verify origin header
124
+ const origin = req.headers.origin;
125
+ if (!allowedOrigins.includes(origin)) {
126
+ return res.status(403).json({ error: "Forbidden" });
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ### 6. Security Misconfiguration
133
+
134
+ **Checklist:**
135
+
136
+ - [ ] Debug mode OFF in production
137
+ - [ ] Default credentials changed
138
+ - [ ] Unnecessary features disabled
139
+ - [ ] Error messages don't leak stack traces
140
+ - [ ] Security headers configured
141
+
142
+ ```typescript
143
+ // Security headers (Helmet.js)
144
+ import helmet from "helmet";
145
+ app.use(helmet());
146
+
147
+ // Custom error handler
148
+ app.use((err, req, res, next) => {
149
+ console.error(err); // Log full error
150
+ res.status(500).json({
151
+ error: "Internal Server Error", // Generic message to user
152
+ });
153
+ });
154
+ ```
155
+
156
+ ---
157
+
158
+ ## 🛡️ API Security
159
+
160
+ ### Rate Limiting
161
+
162
+ ```typescript
163
+ import rateLimit from "express-rate-limit";
164
+
165
+ const limiter = rateLimit({
166
+ windowMs: 15 * 60 * 1000, // 15 minutes
167
+ max: 100, // 100 requests per window
168
+ message: "Too many requests",
169
+ });
170
+
171
+ app.use("/api/", limiter);
172
+
173
+ // Stricter for auth endpoints
174
+ const authLimiter = rateLimit({
175
+ windowMs: 60 * 1000,
176
+ max: 5,
177
+ });
178
+ app.use("/api/auth/", authLimiter);
179
+ ```
180
+
181
+ ---
182
+
183
+ ### Input Validation
184
+
185
+ ```typescript
186
+ import { z } from "zod";
187
+
188
+ const UserSchema = z.object({
189
+ email: z.string().email(),
190
+ password: z.string().min(8).max(128),
191
+ age: z.number().int().min(13).max(120).optional(),
192
+ });
193
+
194
+ // Validate
195
+ const result = UserSchema.safeParse(req.body);
196
+ if (!result.success) {
197
+ return res.status(400).json({ errors: result.error.issues });
198
+ }
199
+ ```
200
+
201
+ ---
202
+
203
+ ### Authorization
204
+
205
+ ```typescript
206
+ // Role-based access
207
+ const requireRole = (roles: string[]) => {
208
+ return (req, res, next) => {
209
+ if (!roles.includes(req.user.role)) {
210
+ return res.status(403).json({ error: "Forbidden" });
211
+ }
212
+ next();
213
+ };
214
+ };
215
+
216
+ app.delete("/api/users/:id", requireRole(["admin"]), deleteUser);
217
+
218
+ // Resource ownership
219
+ app.put("/api/posts/:id", async (req, res) => {
220
+ const post = await prisma.post.findUnique({ where: { id: req.params.id } });
221
+ if (post.authorId !== req.user.id && req.user.role !== "admin") {
222
+ return res.status(403).json({ error: "Forbidden" });
223
+ }
224
+ // proceed with update
225
+ });
226
+ ```
227
+
228
+ ---
229
+
230
+ ## 🔑 Secrets Management
231
+
232
+ ```typescript
233
+ // ✅ Environment variables
234
+ DATABASE_URL=postgresql://...
235
+ STRIPE_SECRET_KEY=sk_live_...
236
+
237
+ // ✅ .env files (gitignored)
238
+ // .env.local, .env.production
239
+
240
+ // ✅ Secret managers (production)
241
+ // AWS Secrets Manager, HashiCorp Vault, Doppler
242
+
243
+ // ❌ NEVER commit secrets
244
+ // ❌ NEVER log secrets
245
+ // ❌ NEVER hardcode in source
246
+ ```
247
+
248
+ ---
249
+
250
+ ## 📋 Quick Security Checklist
251
+
252
+ Before any implementation:
253
+
254
+ - [ ] All inputs validated and sanitized
255
+ - [ ] Authentication on protected routes
256
+ - [ ] Authorization checks (ownership, roles)
257
+ - [ ] No SQL/command injection
258
+ - [ ] XSS prevention (escape output)
259
+ - [ ] CSRF tokens for forms
260
+ - [ ] Rate limiting on sensitive endpoints
261
+ - [ ] Secrets in env vars, not code
262
+ - [ ] HTTPS enforced
263
+ - [ ] Security headers configured
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: software-architecture
3
+ description: Clean Architecture, SOLID principles, and design patterns for building maintainable software. Use when designing system architecture, refactoring codebases, conducting code reviews, or implementing complex features that require architectural decisions.
4
+ ---
5
+
6
+ # Software Architecture
7
+
8
+ Comprehensive guide to software architecture principles, patterns, and best practices.
9
+
10
+ ## When to Use
11
+
12
+ - Designing system architecture
13
+ - Refactoring existing codebase
14
+ - Code reviews focusing on architecture
15
+ - Implementing complex features
16
+ - Making architectural decisions
17
+ - Solving scalability challenges
18
+
19
+ ## Core Principles
20
+
21
+ ### SOLID Principles
22
+
23
+ See [references/solid-principles.md](references/solid-principles.md) for detailed explanations and examples.
24
+
25
+ **Quick Reference:**
26
+
27
+ - **S**ingle Responsibility - One class, one reason to change
28
+ - **O**pen/Closed - Open for extension, closed for modification
29
+ - **L**iskov Substitution - Subclasses should be substitutable
30
+ - **I**nterface Segregation - Many specific interfaces over one general
31
+ - **D**ependency Inversion - Depend on abstractions, not concretions
32
+
33
+ ### Clean Architecture
34
+
35
+ See [references/clean-architecture.md](references/clean-architecture.md) for layer-by-layer guide.
36
+
37
+ **Layers (outer to inner):**
38
+
39
+ 1. Frameworks & Drivers (UI, DB, External APIs)
40
+ 2. Interface Adapters (Controllers, Presenters, Gateways)
41
+ 3. Application Business Rules (Use Cases)
42
+ 4. Enterprise Business Rules (Entities)
43
+
44
+ **Rule:** Dependencies point inward only
45
+
46
+ ## Common Design Patterns
47
+
48
+ See [references/design-patterns.md](references/design-patterns.md) for full catalog.
49
+
50
+ ### Creational Patterns
51
+
52
+ - Factory Pattern - Object creation
53
+ - Builder Pattern - Complex object construction
54
+ - Singleton Pattern - Single instance
55
+
56
+ ### Structural Patterns
57
+
58
+ - Adapter Pattern - Interface compatibility
59
+ - Decorator Pattern - Add behavior dynamically
60
+ - Repository Pattern - Data access abstraction
61
+
62
+ ### Behavioral Patterns
63
+
64
+ - Strategy Pattern - Interchangeable algorithms
65
+ - Observer Pattern - Event notification
66
+ - Command Pattern - Encapsulate requests
67
+
68
+ ## Architecture Best Practices
69
+
70
+ 1. **Separation of Concerns** - Each module has distinct responsibility
71
+ 2. **Dependency Injection** - Inject dependencies, don't create them
72
+ 3. **Interface Programming** - Code to interfaces, not implementations
73
+ 4. **Single Source of Truth** - One canonical source for each data type
74
+ 5. **Test-Driven Design** - Design for testability from the start
75
+ 6. **Incremental Refactoring** - Improve architecture continuously
76
+
77
+ ## Code Organization
78
+
79
+ ```
80
+ src/
81
+ ├── domain/ # Business logic (entities, use cases)
82
+ ├── infrastructure/ # External concerns (DB, API clients)
83
+ ├── application/ # Application services
84
+ └── presentation/ # UI, controllers, views
85
+ ```
86
+
87
+ ## References
88
+
89
+ - [SOLID Principles](references/solid-principles.md) - Detailed examples
90
+ - [Clean Architecture](references/clean-architecture.md) - Layer guide
91
+ - [Design Patterns](references/design-patterns.md) - Pattern catalog
@@ -0,0 +1,293 @@
1
+ # SOLID Principles
2
+
3
+ ## S - Single Responsibility Principle (SRP)
4
+
5
+ **A class should have only one reason to change.**
6
+
7
+ ### ❌ Violation
8
+
9
+ ```javascript
10
+ class User {
11
+ constructor(name, email) {
12
+ this.name = name;
13
+ this.email = email;
14
+ }
15
+
16
+ // Database logic - reason #1 to change
17
+ save() {
18
+ database.insert("users", this);
19
+ }
20
+
21
+ // Email logic - reason #2 to change
22
+ sendWelcomeEmail() {
23
+ emailService.send(this.email, "Welcome!");
24
+ }
25
+
26
+ // Validation - reason #3 to change
27
+ validate() {
28
+ return this.email.includes("@");
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### ✅ Solution
34
+
35
+ ```javascript
36
+ class User {
37
+ constructor(name, email) {
38
+ this.name = name;
39
+ this.email = email;
40
+ }
41
+ }
42
+
43
+ class UserRepository {
44
+ save(user) {
45
+ database.insert("users", user);
46
+ }
47
+ }
48
+
49
+ class UserNotification {
50
+ sendWelcome(user) {
51
+ emailService.send(user.email, "Welcome!");
52
+ }
53
+ }
54
+
55
+ class UserValidator {
56
+ validate(user) {
57
+ return user.email.includes("@");
58
+ }
59
+ }
60
+ ```
61
+
62
+ ## O - Open/Closed Principle (OCP)
63
+
64
+ **Open for extension, closed for modification.**
65
+
66
+ ### ❌ Violation
67
+
68
+ ```javascript
69
+ class PaymentProcessor {
70
+ process(payment) {
71
+ if (payment.type === "credit-card") {
72
+ // Process credit card
73
+ } else if (payment.type === "paypal") {
74
+ // Process PayPal
75
+ }
76
+ // Adding new payment type requires modifying this class
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### ✅ Solution
82
+
83
+ ```javascript
84
+ class PaymentProcessor {
85
+ constructor(strategy) {
86
+ this.strategy = strategy;
87
+ }
88
+
89
+ process(payment) {
90
+ return this.strategy.process(payment);
91
+ }
92
+ }
93
+
94
+ class CreditCardStrategy {
95
+ process(payment) {
96
+ // Process credit card
97
+ }
98
+ }
99
+
100
+ class PayPalStrategy {
101
+ process(payment) {
102
+ // Process PayPal
103
+ }
104
+ }
105
+
106
+ // Usage - extend without modification
107
+ const processor = new PaymentProcessor(new CreditCardStrategy());
108
+ ```
109
+
110
+ ## L - Liskov Substitution Principle (LSP)
111
+
112
+ **Subclasses should be substitutable for their base classes.**
113
+
114
+ ### ❌ Violation
115
+
116
+ ```javascript
117
+ class Rectangle {
118
+ setWidth(width) {
119
+ this.width = width;
120
+ }
121
+ setHeight(height) {
122
+ this.height = height;
123
+ }
124
+ getArea() {
125
+ return this.width * this.height;
126
+ }
127
+ }
128
+
129
+ class Square extends Rectangle {
130
+ setWidth(width) {
131
+ this.width = width;
132
+ this.height = width; // Breaks expectation
133
+ }
134
+ setHeight(height) {
135
+ this.width = height;
136
+ this.height = height;
137
+ }
138
+ }
139
+ ```
140
+
141
+ ### ✅ Solution
142
+
143
+ ```javascript
144
+ class Shape {
145
+ getArea() {
146
+ throw new Error("Must implement getArea");
147
+ }
148
+ }
149
+
150
+ class Rectangle extends Shape {
151
+ constructor(width, height) {
152
+ super();
153
+ this.width = width;
154
+ this.height = height;
155
+ }
156
+ getArea() {
157
+ return this.width * this.height;
158
+ }
159
+ }
160
+
161
+ class Square extends Shape {
162
+ constructor(side) {
163
+ super();
164
+ this.side = side;
165
+ }
166
+ getArea() {
167
+ return this.side * this.side;
168
+ }
169
+ }
170
+ ```
171
+
172
+ ## I - Interface Segregation Principle (ISP)
173
+
174
+ **Many specific interfaces are better than one general interface.**
175
+
176
+ ### ❌ Violation
177
+
178
+ ```javascript
179
+ class Worker {
180
+ work() {}
181
+ eat() {}
182
+ sleep() {}
183
+ }
184
+
185
+ class Robot extends Worker {
186
+ work() {
187
+ /* OK */
188
+ }
189
+ eat() {
190
+ throw new Error("Robots don't eat");
191
+ }
192
+ sleep() {
193
+ throw new Error("Robots don't sleep");
194
+ }
195
+ }
196
+ ```
197
+
198
+ ### ✅ Solution
199
+
200
+ ```javascript
201
+ class Workable {
202
+ work() {}
203
+ }
204
+
205
+ class Eatable {
206
+ eat() {}
207
+ }
208
+
209
+ class Sleepable {
210
+ sleep() {}
211
+ }
212
+
213
+ class Human extends Workable {
214
+ work() {
215
+ /* ... */
216
+ }
217
+ eat() {
218
+ /* via Eatable */
219
+ }
220
+ sleep() {
221
+ /* via Sleepable */
222
+ }
223
+ }
224
+
225
+ class Robot extends Workable {
226
+ work() {
227
+ /* ... */
228
+ }
229
+ // Doesn't implement eat/sleep
230
+ }
231
+ ```
232
+
233
+ ## D - Dependency Inversion Principle (DIP)
234
+
235
+ **Depend on abstractions, not concretions.**
236
+
237
+ ### ❌ Violation
238
+
239
+ ```javascript
240
+ class EmailService {
241
+ send(to, message) {
242
+ /* Send email */
243
+ }
244
+ }
245
+
246
+ class UserService {
247
+ constructor() {
248
+ this.emailService = new EmailService(); // Tight coupling
249
+ }
250
+
251
+ register(user) {
252
+ this.emailService.send(user.email, "Welcome");
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### ✅ Solution
258
+
259
+ ```javascript
260
+ // Abstraction
261
+ class NotificationService {
262
+ send(to, message) {
263
+ throw new Error("Must implement");
264
+ }
265
+ }
266
+
267
+ // Implementations
268
+ class EmailService extends NotificationService {
269
+ send(to, message) {
270
+ /* Send email */
271
+ }
272
+ }
273
+
274
+ class SMSService extends NotificationService {
275
+ send(to, message) {
276
+ /* Send SMS */
277
+ }
278
+ }
279
+
280
+ // Depend on abstraction
281
+ class UserService {
282
+ constructor(notificationService) {
283
+ this.notificationService = notificationService;
284
+ }
285
+
286
+ register(user) {
287
+ this.notificationService.send(user.email, "Welcome");
288
+ }
289
+ }
290
+
291
+ // Usage - easily swap implementations
292
+ const userService = new UserService(new EmailService());
293
+ ```