@skilly-hand/skilly-hand 0.29.1 → 0.29.3

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 (29) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/catalog/README.md +2 -2
  3. package/catalog/skills/figma-mcp-0to1/SKILL.md +13 -14
  4. package/catalog/skills/figma-mcp-0to1/agents/canvas-creation-playbook.md +15 -2
  5. package/catalog/skills/figma-mcp-0to1/agents/install-auth.md +8 -8
  6. package/catalog/skills/figma-mcp-0to1/agents/tool-function-catalog.md +11 -5
  7. package/catalog/skills/figma-mcp-0to1/agents/troubleshooting-ops.md +8 -4
  8. package/catalog/skills/figma-mcp-0to1/assets/client-config-snippets.md +3 -8
  9. package/catalog/skills/figma-mcp-0to1/assets/prompt-recipes.md +19 -4
  10. package/catalog/skills/figma-mcp-0to1/manifest.json +3 -3
  11. package/catalog/skills/figma-mcp-0to1/references/official-tools-matrix.md +27 -28
  12. package/catalog/skills/spec-driven-development/SKILL.md +95 -144
  13. package/catalog/skills/spec-driven-development/agents/apply.md +30 -15
  14. package/catalog/skills/spec-driven-development/agents/orchestrate.md +23 -14
  15. package/catalog/skills/spec-driven-development/agents/plan.md +19 -17
  16. package/catalog/skills/spec-driven-development/agents/verify.md +40 -19
  17. package/catalog/skills/spec-driven-development/assets/delta-spec-template.md +50 -15
  18. package/catalog/skills/spec-driven-development/assets/design-template.md +20 -14
  19. package/catalog/skills/spec-driven-development/assets/spec-template.md +41 -20
  20. package/catalog/skills/spec-driven-development/assets/validation-checklist.md +28 -21
  21. package/catalog/skills/spec-driven-development/manifest.json +4 -4
  22. package/catalog/skills/test-driven-development/SKILL.md +92 -117
  23. package/catalog/skills/test-driven-development/assets/tdd-cycle.md +63 -447
  24. package/catalog/skills/test-driven-development/manifest.json +5 -5
  25. package/package.json +1 -1
  26. package/packages/catalog/package.json +1 -1
  27. package/packages/cli/package.json +1 -1
  28. package/packages/core/package.json +1 -1
  29. package/packages/detectors/package.json +1 -1
@@ -1,487 +1,103 @@
1
- # TDD Templates: RED → GREEN → REFACTOR Cycles
1
+ # Portable TDD Cycle Examples
2
2
 
3
- Real examples of the RED GREEN REFACTOR TDD cycle for implementing components, services, and pipes.
3
+ These examples use pseudocode so the cycle can be translated to the project's language, test runner, and conventions.
4
4
 
5
- **Pattern**: Write failing test → Write minimum code to pass → Refactor while tests stay green
5
+ ## Example 1: New Behavior
6
6
 
7
- ---
7
+ Behavior: normalize surrounding whitespace from a user-provided label.
8
8
 
9
- ## Example 1: Simple Pipe Component
9
+ ### RED
10
10
 
11
- ### Scenario: AsyncCachePipe
12
- Cache hot observables to prevent resubscription overhead.
13
-
14
- #### Step 1: RED — Write Failing Test
15
-
16
- ```typescript
17
- // async-cache.pipe.test.ts
18
- import { TestBed } from '@angular/core/testing';
19
- import { Subject, take } from 'rxjs';
20
- import { AsyncCachePipe } from './async-cache.pipe';
21
-
22
- describe('AsyncCachePipe', () => {
23
- let pipe: AsyncCachePipe;
24
-
25
- beforeEach(() => {
26
- TestBed.configureTestingModule({});
27
- pipe = TestBed.runInInjectionContext(() => new AsyncCachePipe());
28
- });
29
-
30
- it('should cache async values and replay on late subscriptions', (done) => {
31
- // GIVEN: An observable that emits after 100ms
32
- let emitCount = 0;
33
- const source$ = new Subject<number>();
34
-
35
- // WHEN: First subscription
36
- const result$ = pipe.transform(source$);
37
- const values: number[] = [];
38
-
39
- const sub1 = result$.subscribe((val) => {
40
- emitCount++;
41
- values.push(val);
42
- });
43
-
44
- setTimeout(() => {
45
- source$.next(42);
46
- }, 100);
47
-
48
- // WHEN: Second subscription arrives after value is cached
49
- setTimeout(() => {
50
- const sub2 = result$.pipe(take(1)).subscribe(() => {
51
- // THEN: Second subscriber gets cached value immediately
52
- expect(emitCount).toBe(1);
53
- expect(values[0]).toBe(42);
54
-
55
- sub1.unsubscribe();
56
- sub2.unsubscribe();
57
- source$.complete();
58
- done();
59
- });
60
- }, 200);
61
- });
62
-
63
- // ❌ TEST FAILS HERE - transform() not implemented yet
64
- });
11
+ ```text
12
+ test "normalizes surrounding whitespace":
13
+ result = normalize_label(" Ready ")
14
+ expect result equals "Ready"
65
15
  ```
66
16
 
67
- **Run**: `npm test -- async-cache.pipe.test.ts`
68
- ```
69
- FAIL async-cache.pipe.test.ts
70
- should cache async values and replay on late subscriptions
71
- TypeError: pipe.transform is not a function
72
- ```
17
+ Run the project's focused test command. Confirm it fails because normalization is missing, not because the test cannot load or compile.
73
18
 
74
- Test fails as expected (proves test is meaningful)
75
-
76
- ---
77
-
78
- #### Step 2: GREEN — Write Minimum Code
79
-
80
- ```typescript
81
- // async-cache.pipe.ts
82
- import { Pipe, PipeTransform } from '@angular/core';
83
- import { Observable, ReplaySubject } from 'rxjs';
84
- import { tap } from 'rxjs/operators';
85
-
86
- @Pipe({
87
- name: 'asyncCache',
88
- standalone: true,
89
- })
90
- export class AsyncCachePipe implements PipeTransform {
91
- // ✅ MINIMUM: Just make the test pass
92
- transform<T>(source: Observable<T>): Observable<T> {
93
- const cached$ = new ReplaySubject<T>(1);
94
- source.pipe(tap((val) => cached$.next(val))).subscribe();
95
- return cached$.asObservable();
96
- }
97
- }
98
- ```
19
+ ### GREEN
99
20
 
100
- **Run**: `npm test -- async-cache.pipe.test.ts`
21
+ ```text
22
+ function normalize_label(value):
23
+ return trim(value)
101
24
  ```
102
- PASS async-cache.pipe.test.ts
103
- should cache async values and replay on late subscriptions ✓
104
25
 
105
- Tests: 1 passed, 1 total
106
- ```
26
+ Run the focused test and relevant nearby tests. They pass.
107
27
 
108
- Test passes (behavior is correct, but code needs cleanup)
109
-
110
- ---
111
-
112
- #### Step 3: REFACTOR — Improve Without Changing Behavior
113
-
114
- ```typescript
115
- // async-cache.pipe.ts (refactored)
116
- import { Pipe, PipeTransform } from '@angular/core';
117
- import { Observable, ReplaySubject, Subject, takeUntil } from 'rxjs';
118
- import { tap } from 'rxjs/operators';
119
-
120
- @Pipe({
121
- name: 'asyncCache',
122
- standalone: true,
123
- })
124
- export class AsyncCachePipe implements PipeTransform {
125
- private destroy$ = new Subject<void>();
126
-
127
- // ✅ REFACTORED: Cleaner, adds cleanup
128
- transform<T>(source: Observable<T>): Observable<T> {
129
- const cacheSize = 1;
130
- const cached$ = new ReplaySubject<T>(cacheSize);
131
-
132
- source
133
- .pipe(
134
- tap((val) => cached$.next(val)),
135
- takeUntil(this.destroy$)
136
- )
137
- .subscribe();
138
-
139
- return cached$.asObservable();
140
- }
141
-
142
- ngOnDestroy(): void {
143
- this.destroy$.next();
144
- this.destroy$.complete();
145
- }
146
- }
147
- ```
28
+ ### REFACTOR
148
29
 
149
- **Run**: `npm test -- async-cache.pipe.test.ts`
150
- ```
151
- PASS async-cache.pipe.test.ts
152
- should cache async values and replay on late subscriptions ✓
153
- ```
154
-
155
- ✅ Test still passes
156
-
157
- **What improved**:
158
- - Constants extracted (`cacheSize`)
159
- - Cleanup logic added (`takeUntil`, `ngOnDestroy`)
160
-
161
- ---
162
-
163
- ## Example 2: Component with Input/Output
164
-
165
- ### Scenario: AlertComponent
166
- Display a dismissible alert with a message.
167
-
168
- #### Step 1: RED — Write Failing Test
169
-
170
- ```typescript
171
- // alert.component.test.ts
172
- import { TestBed, ComponentFixture } from '@angular/core/testing';
173
- import { AlertComponent } from './alert.component';
30
+ No structural improvement is needed. Record `NOT_NEEDED`; REFACTOR is an opportunity, not a quota.
174
31
 
175
- describe('AlertComponent', () => {
176
- let component: AlertComponent;
177
- let fixture: ComponentFixture<AlertComponent>;
32
+ ### Next Behavior Is a New Cycle
178
33
 
179
- beforeEach(async () => {
180
- await TestBed.configureTestingModule({
181
- imports: [AlertComponent],
182
- }).compileComponents();
34
+ Rejecting an empty normalized label would be new observable behavior. Do not add it during REFACTOR. Write a failing empty-label test first.
183
35
 
184
- fixture = TestBed.createComponent(AlertComponent);
185
- component = fixture.componentInstance;
186
- });
36
+ ## Example 2: Regression
187
37
 
188
- it('should display the alert message', () => {
189
- // GIVEN: Component with message input
190
- component.message = 'Error: Invalid input';
191
- fixture.detectChanges();
38
+ Defect: a retry policy performs one extra attempt.
192
39
 
193
- // WHEN: Component renders
194
- const messageEl = fixture.debugElement.nativeElement.querySelector('[data-testid="alert-message"]');
40
+ ### RED
195
41
 
196
- // THEN: Message is visible
197
- expect(messageEl?.textContent).toBe('Error: Invalid input');
198
- });
199
-
200
- // FAILS - Component doesn't exist yet
201
- });
42
+ ```text
43
+ test "stops after configured attempts":
44
+ dependency = failing_fake()
45
+ retry(dependency, attempts = 3)
46
+ expect dependency call_count equals 3
202
47
  ```
203
48
 
204
- **Run**: `npm test -- alert.component.test.ts`
205
- ```
206
- FAIL alert.component.test.ts
207
- Cannot find component 'AlertComponent'
208
- ```
49
+ Confirm the faulty baseline reports four calls. A load error or unrelated exception is not valid RED evidence.
209
50
 
210
- ---
51
+ ### GREEN
211
52
 
212
- #### Step 2: GREEN Write Minimum Implementation
53
+ Change only the attempt boundary. Confirm the regression test now reports three calls and nearby retry tests still pass.
213
54
 
214
- ```typescript
215
- // alert.component.ts
216
- import { Component, input } from '@angular/core';
55
+ ### REFACTOR
217
56
 
218
- @Component({
219
- selector: 'app-alert',
220
- standalone: true,
221
- template: `<div data-testid="alert-message">{{ message() }}</div>`,
222
- })
223
- export class AlertComponent {
224
- // ✅ MINIMUM: Just the message input
225
- message = input<string>('');
226
- }
227
- ```
57
+ Rename the internal loop counter if that improves clarity. Do not add backoff, logging, or a new error type without separate RED tests.
228
58
 
229
- **Run**: `npm test -- alert.component.test.ts`
230
- ```
231
- PASS alert.component.test.ts
232
- should display the alert message ✓
233
- ```
59
+ ## Example 3: Test Already Passes
234
60
 
235
- ---
236
-
237
- #### Step 3: REFACTOR — Add Accessibility and Dismiss
238
-
239
- ```typescript
240
- // alert.component.ts (refactored)
241
- import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';
242
-
243
- @Component({
244
- selector: 'app-alert',
245
- standalone: true,
246
- template: `
247
- <div
248
- class="alert"
249
- role="alert"
250
- aria-live="polite"
251
- [attr.data-testid]="'alert-message'"
252
- [class]="'alert--' + severity()">
253
- <p class="alert__message">{{ message() }}</p>
254
- <button class="alert__close" aria-label="Dismiss alert" (click)="onDismiss()">✕</button>
255
- </div>
256
- `,
257
- changeDetection: ChangeDetectionStrategy.OnPush,
258
- })
259
- export class AlertComponent {
260
- message = input<string>('');
261
- severity = input<'success' | 'error' | 'warning' | 'info'>('info');
262
- dismissed = output<void>();
263
-
264
- onDismiss(): void {
265
- this.dismissed.emit();
266
- }
267
- }
268
- ```
61
+ When a proposed RED test passes:
269
62
 
270
- **Run**: `npm test -- alert.component.test.ts`
271
- ```
272
- PASS alert.component.test.ts
273
- should display the alert message
274
- ```
275
-
276
- ✅ Test still passes
277
-
278
- **What improved**:
279
- - Accessibility attributes (`role="alert"`, `aria-live`, `aria-label`)
280
- - Dismiss output and handler
281
- - Severity levels
282
- - `ChangeDetectionStrategy.OnPush`
283
-
284
- ---
285
-
286
- ## Example 3: Service with State Management
287
-
288
- ### Scenario: TodoService
289
- Manage a todo list with add and complete operations.
290
-
291
- #### Step 1: RED — Multiple Scenarios
292
-
293
- ```typescript
294
- // todo.service.test.ts
295
- import { TestBed } from '@angular/core/testing';
296
- import { TodoService } from './todo.service';
297
-
298
- describe('TodoService', () => {
299
- let service: TodoService;
300
-
301
- beforeEach(() => {
302
- TestBed.configureTestingModule({ providers: [TodoService] });
303
- service = TestBed.inject(TodoService);
304
- });
305
-
306
- it('should add a todo and update the list', () => {
307
- // GIVEN: Empty list
308
- // WHEN: Add todo
309
- service.addTodo('Buy milk');
310
-
311
- // THEN: Todo appears
312
- expect(service.todos()).toContainEqual(
313
- jasmine.objectContaining({ text: 'Buy milk', done: false })
314
- );
315
- });
316
-
317
- it('should mark a todo as complete', () => {
318
- // GIVEN: A todo in the list
319
- service.addTodo('Buy milk');
320
- const firstTodo = service.todos()[0];
321
-
322
- // WHEN: Mark as complete
323
- service.completeTodo(firstTodo.id);
324
-
325
- // THEN: Todo is done
326
- expect(service.todos()[0].done).toBe(true);
327
- });
328
-
329
- // ❌ FAILS - Service methods don't exist
330
- });
331
- ```
332
-
333
- **Run**: `npm test -- todo.service.test.ts`
334
- ```
335
- FAIL todo.service.test.ts
336
- service.addTodo is not a function
337
- ```
338
-
339
- ---
340
-
341
- #### Step 2: GREEN — Write Minimum Implementation
342
-
343
- ```typescript
344
- // todo.service.ts
345
- import { Injectable, signal } from '@angular/core';
346
-
347
- interface Todo { id: number; text: string; done: boolean; }
63
+ 1. Run it against the unchanged baseline again.
64
+ 2. Check whether the behavior already exists.
65
+ 3. Check whether the assertion observes the intended public outcome.
66
+ 4. Check whether setup bypasses the relevant code path.
67
+ 5. Revise the scenario only when the requirement was misunderstood.
348
68
 
349
- @Injectable({ providedIn: 'root' })
350
- export class TodoService {
351
- todos = signal<Todo[]>([]);
352
- private nextId = 1;
69
+ Do not intentionally break production code merely to manufacture a RED result.
353
70
 
354
- addTodo(text: string): void {
355
- this.todos.update((current) => [...current, { id: this.nextId++, text, done: false }]);
356
- }
71
+ ## Evidence Template
357
72
 
358
- completeTodo(id: number): void {
359
- this.todos.update((current) =>
360
- current.map((todo) => todo.id === id ? { ...todo, done: true } : todo)
361
- );
362
- }
363
- }
364
- ```
73
+ ```markdown
74
+ ### TDD Evidence: [Behavior]
365
75
 
366
- **Run**: `npm test -- todo.service.test.ts`
367
- ```
368
- PASS todo.service.test.ts
369
- should add a todo and update the list ✓
370
- should mark a todo as complete
76
+ - Test level: [unit | integration | contract | end-to-end | characterization]
77
+ - Focused check: [project-discovered command or procedure]
78
+ - RED: `FAIL` - [expected failure reason]
79
+ - GREEN: `PASS` - [minimum behavior implemented]
80
+ - REFACTOR: `PASS` or `NOT_NEEDED` - [structural change only]
81
+ - Regression: `PASS`, `FAIL`, or `NOT_RUN` - [scope and reason]
82
+ - Notes: [test doubles, manual checks, or limitations]
371
83
  ```
372
84
 
373
- ---
374
-
375
- #### Step 3: REFACTOR — Add Validation and Persistence
376
-
377
- ```typescript
378
- // todo.service.ts (refactored)
379
- import { Injectable, signal } from '@angular/core';
380
-
381
- interface Todo {
382
- id: number;
383
- text: string;
384
- done: boolean;
385
- createdAt: Date;
386
- completedAt?: Date;
387
- }
388
-
389
- @Injectable({ providedIn: 'root' })
390
- export class TodoService {
391
- todos = signal<Todo[]>([]);
392
- private nextId = 1;
393
- private readonly MAX_TODOS = 100;
394
-
395
- constructor() {
396
- this.loadFromStorage();
397
- }
398
-
399
- addTodo(text: string): void {
400
- if (!text?.trim()) throw new Error('Todo text cannot be empty');
401
- if (this.todos().length >= this.MAX_TODOS) throw new Error(`Cannot exceed ${this.MAX_TODOS} todos`);
402
-
403
- this.todos.update((current) => [
404
- ...current,
405
- { id: this.nextId++, text: text.trim(), done: false, createdAt: new Date() },
406
- ]);
407
- this.saveToStorage();
408
- }
409
-
410
- completeTodo(id: number): void {
411
- if (!this.todos().find((t) => t.id === id)) throw new Error(`Todo with id ${id} not found`);
412
-
413
- this.todos.update((current) =>
414
- current.map((t) => t.id === id ? { ...t, done: true, completedAt: new Date() } : t)
415
- );
416
- this.saveToStorage();
417
- }
418
-
419
- deleteTodo(id: number): void {
420
- this.todos.update((current) => current.filter((t) => t.id !== id));
421
- this.saveToStorage();
422
- }
423
-
424
- private loadFromStorage(): void {
425
- try {
426
- const stored = localStorage.getItem('todos');
427
- if (stored) this.todos.set(JSON.parse(stored));
428
- } catch (e) {
429
- console.error('Failed to load todos from storage', e);
430
- }
431
- }
432
-
433
- private saveToStorage(): void {
434
- try {
435
- localStorage.setItem('todos', JSON.stringify(this.todos()));
436
- } catch (e) {
437
- console.error('Failed to save todos to storage', e);
438
- }
439
- }
440
- }
441
- ```
85
+ ## Cycle Checklist
442
86
 
443
- **Run**: `npm test -- todo.service.test.ts`
444
- ```
445
- PASS todo.service.test.ts
446
- should add a todo and update the list ✓
447
- should mark a todo as complete ✓
448
- ```
87
+ ### RED
449
88
 
450
- Tests still pass
89
+ - [ ] One observable behavior is defined.
90
+ - [ ] The test was added before production behavior changed.
91
+ - [ ] The test fails for the expected reason.
451
92
 
452
- **What improved**:
453
- - Input validation (empty check, max limit)
454
- - Timestamps (`createdAt`, `completedAt`)
455
- - Persistence via `localStorage`
456
- - `deleteTodo` added for completeness
93
+ ### GREEN
457
94
 
458
- ---
95
+ - [ ] The smallest required behavior was implemented.
96
+ - [ ] The focused test passes.
97
+ - [ ] Relevant regression checks pass or are honestly marked `NOT_RUN`.
459
98
 
460
- ## Quick Checklist: RED → GREEN → REFACTOR
99
+ ### REFACTOR
461
100
 
462
- ```markdown
463
- ### For Each Task Using TDD
464
-
465
- #### RED Phase
466
- - [ ] Write test that describes the feature
467
- - [ ] Test has explicit GIVEN / WHEN / THEN
468
- - [ ] Run tests — FAILS as expected
469
- - [ ] Failure proves test is meaningful
470
-
471
- #### GREEN Phase
472
- - [ ] Write minimum code to pass
473
- - [ ] No extra features beyond test requirement
474
- - [ ] Run tests — PASSES
475
-
476
- #### REFACTOR Phase
477
- - [ ] Improve code structure / naming
478
- - [ ] Extract constants, simplify logic
479
- - [ ] Run tests — STILL PASSES
480
- - [ ] No behavior changes, only improvements
481
-
482
- #### Verify
483
- - [ ] All tests pass: `npm test`
484
- - [ ] Lint passes: `npm run lint`
485
- - [ ] Type check: `npx tsc --noEmit`
486
- - [ ] Build succeeds: `npm run build`
487
- ```
101
+ - [ ] Structural changes preserve observable behavior.
102
+ - [ ] No untested feature or edge case was added.
103
+ - [ ] Tests remain green, or refactoring is recorded as `NOT_NEEDED`.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "test-driven-development",
3
3
  "title": "Test-Driven Development",
4
- "description": "Guide implementation using the RED GREEN REFACTOR TDD cycle: write a failing test first, write the minimum code to pass, then refactor while tests stay green.",
4
+ "description": "Guide implementation through evidence-based RED, GREEN, and REFACTOR cycles without assuming a language, framework, or test runner. Trigger: implementing testable behavior or reproducing a regression with tests first.",
5
5
  "portable": true,
6
6
  "tags": ["testing", "workflow", "quality", "core"],
7
7
  "detectors": ["always"],
@@ -10,11 +10,11 @@
10
10
  "agentSupport": ["codex", "claude", "cursor", "gemini", "copilot", "antigravity", "windsurf", "trae"],
11
11
  "skillMetadata": {
12
12
  "author": "skilly-hand",
13
- "last-edit": "2026-04-04",
13
+ "last-edit": "2026-06-20",
14
14
  "license": "Apache-2.0",
15
- "version": "1.0.0",
16
- "changelog": "Initial TDD skill ported from legacy scannlab-sdd tdd-templates; enables RED→GREEN→REFACTOR workflow across any stack; affects catalog skill coverage for test-first development",
17
- "auto-invoke": "Implementing features, services, or components using test-driven development (TDD) or RED→GREEN→REFACTOR cycles",
15
+ "version": "1.1.0",
16
+ "changelog": "Rebuilt TDD guidance around portable cycle evidence, expected RED failures, behavior-preserving refactors, and project-discovered test conventions; prevents framework assumptions and untested behavior during refactor; affects core workflow, examples, and verification guidance",
17
+ "auto-invoke": "Implementing testable behavior or reproducing a regression with tests first",
18
18
  "allowed-tools": ["Read", "Edit", "Write", "Glob", "Grep", "Bash"]
19
19
  },
20
20
  "files": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/skilly-hand",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/catalog",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/cli",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/core",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/detectors",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }