@simplysm/sd-claude 14.0.42 → 14.0.44

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 (67) hide show
  1. package/claude/references/sd-simplysm14/angular/docs/directives.md +74 -3
  2. package/claude/references/sd-simplysm14/angular/docs/features.md +64 -14
  3. package/claude/references/sd-simplysm14/angular/docs/plugins.md +2 -90
  4. package/claude/references/sd-simplysm14/angular/docs/providers.md +2 -2
  5. package/claude/references/sd-simplysm14/angular/docs/type-utilities.md +1 -2
  6. package/claude/references/sd-simplysm14/angular/docs/ui-data.md +103 -23
  7. package/claude/references/sd-simplysm14/angular/docs/ui-form.md +173 -28
  8. package/claude/references/sd-simplysm14/angular/docs/ui-layout.md +19 -4
  9. package/claude/references/sd-simplysm14/angular/docs/ui-navigation.md +20 -2
  10. package/claude/references/sd-simplysm14/angular/docs/ui-overlay.md +23 -14
  11. package/claude/references/sd-simplysm14/angular/docs/ui-visual.md +15 -7
  12. package/claude/references/sd-simplysm14/angular/docs/utils.md +1 -1
  13. package/claude/references/sd-simplysm14/angular/usage.md +59 -15
  14. package/claude/references/sd-simplysm14/capacitor-plugin-auto-update/usage.md +1 -1
  15. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/file-operations.md +154 -0
  16. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/permissions.md +84 -0
  17. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/storage-paths.md +107 -0
  18. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/types.md +83 -0
  19. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/usage.md +83 -128
  20. package/claude/references/sd-simplysm14/capacitor-plugin-usb-storage/usage.md +99 -1
  21. package/claude/references/sd-simplysm14/core-node/docs/child-process.md +182 -0
  22. package/claude/references/sd-simplysm14/core-node/docs/features.md +1 -1
  23. package/claude/references/sd-simplysm14/core-node/docs/file-system.md +509 -0
  24. package/claude/references/sd-simplysm14/core-node/docs/file-watching.md +139 -0
  25. package/claude/references/sd-simplysm14/core-node/docs/logging.md +180 -0
  26. package/claude/references/sd-simplysm14/core-node/docs/path.md +176 -0
  27. package/claude/references/sd-simplysm14/core-node/docs/worker-threads.md +334 -0
  28. package/claude/references/sd-simplysm14/core-node/usage.md +192 -96
  29. package/claude/references/sd-simplysm14/excel/docs/core-classes.md +33 -14
  30. package/claude/references/sd-simplysm14/excel/usage.md +47 -45
  31. package/claude/references/sd-simplysm14/lint/usage.md +3 -2
  32. package/claude/references/sd-simplysm14/orm-common/docs/queryable-executable.md +30 -35
  33. package/claude/references/sd-simplysm14/orm-common/usage.md +9 -8
  34. package/claude/references/sd-simplysm14/sd-claude/docs/assets.md +43 -34
  35. package/claude/references/sd-simplysm14/sd-claude/docs/cli.md +1 -1
  36. package/claude/references/sd-simplysm14/sd-claude/docs/hooks.md +20 -2
  37. package/claude/references/sd-simplysm14/sd-claude/docs/scripts.md +5 -18
  38. package/claude/references/sd-simplysm14/sd-claude/usage.md +6 -5
  39. package/claude/references/sd-simplysm14/sd-cli/usage.md +176 -1
  40. package/claude/references/sd-simplysm14/service-client/usage.md +126 -61
  41. package/claude/references/sd-simplysm14/service-common/usage.md +28 -28
  42. package/claude/references/sd-simplysm14/storage/usage.md +123 -30
  43. package/claude/{rules → references}/sd-simplysm14.md +1 -1
  44. package/claude/references/sd-testing.md +100 -4
  45. package/claude/rules/sd-claude-rules.md +21 -5
  46. package/claude/sd-check-write.py +1 -1
  47. package/claude/skills/sd-check/SKILL.md +7 -4
  48. package/claude/skills/sd-claude-docs/SKILL.md +7 -4
  49. package/claude/skills/sd-claude-docs/references/package-doc-gen.md +30 -7
  50. package/claude/skills/sd-commit/SKILL.md +2 -0
  51. package/claude/skills/sd-debug/SKILL.md +1 -1
  52. package/claude/skills/sd-deliverable/SKILL.md +2 -0
  53. package/claude/skills/sd-dev/SKILL.md +1 -1
  54. package/claude/skills/sd-doc-extract/SKILL.md +2 -0
  55. package/claude/{references/sd-debug.md → skills/sd-inner-debug/SKILL.md} +16 -20
  56. package/claude/{references/sd-review.md → skills/sd-inner-review/SKILL.md} +9 -4
  57. package/claude/skills/sd-issue/SKILL.md +2 -0
  58. package/claude/skills/sd-outlook/SKILL.md +2 -0
  59. package/claude/skills/sd-plan/SKILL.md +1 -1
  60. package/claude/skills/sd-prompt/SKILL.md +2 -2
  61. package/claude/skills/sd-refactor/SKILL.md +2 -2
  62. package/claude/skills/sd-review/SKILL.md +1 -1
  63. package/claude/skills/sd-tdd/SKILL.md +7 -7
  64. package/claude/skills/sd-use/SKILL.md +2 -0
  65. package/claude/skills/sd-wbs/SKILL.md +41 -18
  66. package/package.json +1 -1
  67. /package/claude/{references → rules}/sd-clarify.md +0 -0
@@ -0,0 +1,509 @@
1
+ # File System (fsx)
2
+
3
+ ## `exists`
4
+
5
+ 파일 또는 디렉토리가 존재하는지 확인 (비동기).
6
+
7
+ ```typescript
8
+ export async function exists(targetPath: string): Promise<boolean>
9
+ ```
10
+
11
+ | Parameter | Type | Description |
12
+ |-----------|------|-------------|
13
+ | `targetPath` | string | 확인할 경로 |
14
+
15
+ **Return**: 파일/디렉토리가 존재하면 true, 없으면 false
16
+
17
+ ---
18
+
19
+ ## `existsSync`
20
+
21
+ 파일 또는 디렉토리가 존재하는지 확인 (동기).
22
+
23
+ ```typescript
24
+ export function existsSync(targetPath: string): boolean
25
+ ```
26
+
27
+ | Parameter | Type | Description |
28
+ |-----------|------|-------------|
29
+ | `targetPath` | string | 확인할 경로 |
30
+
31
+ **Return**: 파일/디렉토리가 존재하면 true, 없으면 false
32
+
33
+ ---
34
+
35
+ ## `mkdir`
36
+
37
+ 디렉토리를 생성한다 (재귀적, 비동기).
38
+
39
+ ```typescript
40
+ export async function mkdir(targetPath: string): Promise<void>
41
+ ```
42
+
43
+ | Parameter | Type | Description |
44
+ |-----------|------|-------------|
45
+ | `targetPath` | string | 생성할 디렉토리 경로 |
46
+
47
+ ---
48
+
49
+ ## `mkdirSync`
50
+
51
+ 디렉토리를 생성한다 (재귀적, 동기).
52
+
53
+ ```typescript
54
+ export function mkdirSync(targetPath: string): void
55
+ ```
56
+
57
+ | Parameter | Type | Description |
58
+ |-----------|------|-------------|
59
+ | `targetPath` | string | 생성할 디렉토리 경로 |
60
+
61
+ ---
62
+
63
+ ## `rm`
64
+
65
+ 파일 또는 디렉토리를 삭제한다 (비동기).
66
+
67
+ 파일 잠금 등 일시적 오류에 대해 최대 6회(500ms 간격) 재시도한다.
68
+
69
+ ```typescript
70
+ export async function rm(targetPath: string): Promise<void>
71
+ ```
72
+
73
+ | Parameter | Type | Description |
74
+ |-----------|------|-------------|
75
+ | `targetPath` | string | 삭제할 경로 |
76
+
77
+ ---
78
+
79
+ ## `rmSync`
80
+
81
+ 파일 또는 디렉토리를 삭제한다 (동기).
82
+
83
+ 동기 버전은 재시도 없이 즉시 실패한다. 파일 잠금 등 일시적 오류가 발생할 수 있는 경우 `rm`을 사용하라.
84
+
85
+ ```typescript
86
+ export function rmSync(targetPath: string): void
87
+ ```
88
+
89
+ | Parameter | Type | Description |
90
+ |-----------|------|-------------|
91
+ | `targetPath` | string | 삭제할 경로 |
92
+
93
+ ---
94
+
95
+ ## `copy`
96
+
97
+ 파일 또는 디렉토리를 복사한다 (비동기).
98
+
99
+ sourcePath가 존재하지 않으면 아무 작업도 수행하지 않고 반환한다.
100
+
101
+ ```typescript
102
+ export async function copy(
103
+ sourcePath: string,
104
+ targetPath: string,
105
+ filter?: (absolutePath: string) => boolean,
106
+ ): Promise<void>
107
+ ```
108
+
109
+ | Parameter | Type | Description |
110
+ |-----------|------|-------------|
111
+ | `sourcePath` | string | 복사할 원본 경로 |
112
+ | `targetPath` | string | 복사 대상 경로 |
113
+ | `filter` | function (optional) | 복사 여부를 결정하는 필터 함수. 각 파일/디렉토리의 절대 경로가 전달된다. true를 반환하면 복사, false를 반환하면 제외한다. 주의: 최상위 sourcePath는 필터링 대상이 아니며, 필터 함수는 모든 하위 항목(직접 및 간접)에 재귀적으로 적용된다. 디렉토리에 대해 false를 반환하면 해당 디렉토리와 모든 내용을 건너뛴다. |
114
+
115
+ ---
116
+
117
+ ## `copySync`
118
+
119
+ 파일 또는 디렉토리를 복사한다 (동기).
120
+
121
+ sourcePath가 존재하지 않으면 아무 작업도 수행하지 않고 반환한다.
122
+
123
+ ```typescript
124
+ export function copySync(
125
+ sourcePath: string,
126
+ targetPath: string,
127
+ filter?: (absolutePath: string) => boolean,
128
+ ): void
129
+ ```
130
+
131
+ | Parameter | Type | Description |
132
+ |-----------|------|-------------|
133
+ | `sourcePath` | string | 복사할 원본 경로 |
134
+ | `targetPath` | string | 복사 대상 경로 |
135
+ | `filter` | function (optional) | 복사 여부를 결정하는 필터 함수. 각 파일/디렉토리의 절대 경로가 전달된다. true를 반환하면 복사, false를 반환하면 제외한다. 주의: 최상위 sourcePath는 필터링 대상이 아니며, 필터 함수는 모든 하위 항목(직접 및 간접)에 재귀적으로 적용된다. 디렉토리에 대해 false를 반환하면 해당 디렉토리와 모든 내용을 건너뛴다. |
136
+
137
+ ---
138
+
139
+ ## `read`
140
+
141
+ 파일을 UTF-8 문자열로 읽는다 (비동기).
142
+
143
+ ```typescript
144
+ export async function read(targetPath: string): Promise<string>
145
+ ```
146
+
147
+ | Parameter | Type | Description |
148
+ |-----------|------|-------------|
149
+ | `targetPath` | string | 읽을 파일 경로 |
150
+
151
+ **Return**: 파일의 UTF-8 문자열 내용
152
+
153
+ ---
154
+
155
+ ## `readSync`
156
+
157
+ 파일을 UTF-8 문자열로 읽는다 (동기).
158
+
159
+ ```typescript
160
+ export function readSync(targetPath: string): string
161
+ ```
162
+
163
+ | Parameter | Type | Description |
164
+ |-----------|------|-------------|
165
+ | `targetPath` | string | 읽을 파일 경로 |
166
+
167
+ **Return**: 파일의 UTF-8 문자열 내용
168
+
169
+ ---
170
+
171
+ ## `readBytes`
172
+
173
+ 파일을 Uint8Array로 읽는다 (비동기).
174
+
175
+ ```typescript
176
+ export async function readBytes(targetPath: string): Promise<Uint8Array>
177
+ ```
178
+
179
+ | Parameter | Type | Description |
180
+ |-----------|------|-------------|
181
+ | `targetPath` | string | 읽을 파일 경로 |
182
+
183
+ **Return**: 파일의 바이너리 내용
184
+
185
+ ---
186
+
187
+ ## `readBytesSync`
188
+
189
+ 파일을 Uint8Array로 읽는다 (동기).
190
+
191
+ ```typescript
192
+ export function readBytesSync(targetPath: string): Uint8Array
193
+ ```
194
+
195
+ | Parameter | Type | Description |
196
+ |-----------|------|-------------|
197
+ | `targetPath` | string | 읽을 파일 경로 |
198
+
199
+ **Return**: 파일의 바이너리 내용
200
+
201
+ ---
202
+
203
+ ## `readJson`
204
+
205
+ JSON 파일을 읽는다 (비동기, JsonConvert 사용).
206
+
207
+ ```typescript
208
+ export async function readJson<TData = unknown>(targetPath: string): Promise<TData>
209
+ ```
210
+
211
+ | Parameter | Type | Description |
212
+ |-----------|------|-------------|
213
+ | `targetPath` | string | 읽을 JSON 파일 경로 |
214
+
215
+ **Return**: 파싱된 JSON 데이터
216
+
217
+ **Type Parameter**: `TData` - JSON 데이터의 타입
218
+
219
+ ---
220
+
221
+ ## `readJsonSync`
222
+
223
+ JSON 파일을 읽는다 (동기, JsonConvert 사용).
224
+
225
+ ```typescript
226
+ export function readJsonSync<TData = unknown>(targetPath: string): TData
227
+ ```
228
+
229
+ | Parameter | Type | Description |
230
+ |-----------|------|-------------|
231
+ | `targetPath` | string | 읽을 JSON 파일 경로 |
232
+
233
+ **Return**: 파싱된 JSON 데이터
234
+
235
+ **Type Parameter**: `TData` - JSON 데이터의 타입
236
+
237
+ ---
238
+
239
+ ## `write`
240
+
241
+ 파일에 데이터를 쓴다 (비동기).
242
+
243
+ 상위 디렉토리를 자동으로 생성한다.
244
+
245
+ ```typescript
246
+ export async function write(targetPath: string, data: string | Uint8Array): Promise<void>
247
+ ```
248
+
249
+ | Parameter | Type | Description |
250
+ |-----------|------|-------------|
251
+ | `targetPath` | string | 쓸 파일 경로 |
252
+ | `data` | string \| Uint8Array | 쓸 데이터 |
253
+
254
+ ---
255
+
256
+ ## `writeSync`
257
+
258
+ 파일에 데이터를 쓴다 (동기).
259
+
260
+ 상위 디렉토리를 자동으로 생성한다.
261
+
262
+ ```typescript
263
+ export function writeSync(targetPath: string, data: string | Uint8Array): void
264
+ ```
265
+
266
+ | Parameter | Type | Description |
267
+ |-----------|------|-------------|
268
+ | `targetPath` | string | 쓸 파일 경로 |
269
+ | `data` | string \| Uint8Array | 쓸 데이터 |
270
+
271
+ ---
272
+
273
+ ## `writeJson`
274
+
275
+ JSON 파일에 데이터를 쓴다 (비동기, JsonConvert 사용).
276
+
277
+ ```typescript
278
+ export async function writeJson(
279
+ targetPath: string,
280
+ data: unknown,
281
+ options?: {
282
+ replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;
283
+ space?: string | number;
284
+ },
285
+ ): Promise<void>
286
+ ```
287
+
288
+ | Parameter | Type | Description |
289
+ |-----------|------|-------------|
290
+ | `targetPath` | string | 쓸 JSON 파일 경로 |
291
+ | `data` | unknown | 쓸 데이터 |
292
+ | `options` | object (optional) | JSON 직렬화 옵션 (replacer, space) |
293
+
294
+ ---
295
+
296
+ ## `writeJsonSync`
297
+
298
+ JSON 파일에 데이터를 쓴다 (동기, JsonConvert 사용).
299
+
300
+ ```typescript
301
+ export function writeJsonSync(
302
+ targetPath: string,
303
+ data: unknown,
304
+ options?: {
305
+ replacer?: (this: unknown, key: string | undefined, value: unknown) => unknown;
306
+ space?: string | number;
307
+ },
308
+ ): void
309
+ ```
310
+
311
+ | Parameter | Type | Description |
312
+ |-----------|------|-------------|
313
+ | `targetPath` | string | 쓸 JSON 파일 경로 |
314
+ | `data` | unknown | 쓸 데이터 |
315
+ | `options` | object (optional) | JSON 직렬화 옵션 (replacer, space) |
316
+
317
+ ---
318
+
319
+ ## `readdir`
320
+
321
+ 디렉토리의 내용을 읽는다 (비동기).
322
+
323
+ ```typescript
324
+ export async function readdir(targetPath: string): Promise<string[]>
325
+ ```
326
+
327
+ | Parameter | Type | Description |
328
+ |-----------|------|-------------|
329
+ | `targetPath` | string | 읽을 디렉토리 경로 |
330
+
331
+ **Return**: 디렉토리 내 파일/폴더명 배열
332
+
333
+ ---
334
+
335
+ ## `readdirSync`
336
+
337
+ 디렉토리의 내용을 읽는다 (동기).
338
+
339
+ ```typescript
340
+ export function readdirSync(targetPath: string): string[]
341
+ ```
342
+
343
+ | Parameter | Type | Description |
344
+ |-----------|------|-------------|
345
+ | `targetPath` | string | 읽을 디렉토리 경로 |
346
+
347
+ **Return**: 디렉토리 내 파일/폴더명 배열
348
+
349
+ ---
350
+
351
+ ## `stat`
352
+
353
+ 파일/디렉토리 정보를 가져온다 (심볼릭 링크를 따라감, 비동기).
354
+
355
+ ```typescript
356
+ export async function stat(targetPath: string): Promise<fs.Stats>
357
+ ```
358
+
359
+ | Parameter | Type | Description |
360
+ |-----------|------|-------------|
361
+ | `targetPath` | string | 정보를 조회할 경로 |
362
+
363
+ **Return**: Node.js `fs.Stats` 객체
364
+
365
+ ---
366
+
367
+ ## `statSync`
368
+
369
+ 파일/디렉토리 정보를 가져온다 (심볼릭 링크를 따라감, 동기).
370
+
371
+ ```typescript
372
+ export function statSync(targetPath: string): fs.Stats
373
+ ```
374
+
375
+ | Parameter | Type | Description |
376
+ |-----------|------|-------------|
377
+ | `targetPath` | string | 정보를 조회할 경로 |
378
+
379
+ **Return**: Node.js `fs.Stats` 객체
380
+
381
+ ---
382
+
383
+ ## `lstat`
384
+
385
+ 파일/디렉토리 정보를 가져온다 (심볼릭 링크를 따라가지 않음, 비동기).
386
+
387
+ ```typescript
388
+ export async function lstat(targetPath: string): Promise<fs.Stats>
389
+ ```
390
+
391
+ | Parameter | Type | Description |
392
+ |-----------|------|-------------|
393
+ | `targetPath` | string | 정보를 조회할 경로 |
394
+
395
+ **Return**: Node.js `fs.Stats` 객체
396
+
397
+ ---
398
+
399
+ ## `lstatSync`
400
+
401
+ 파일/디렉토리 정보를 가져온다 (심볼릭 링크를 따라가지 않음, 동기).
402
+
403
+ ```typescript
404
+ export function lstatSync(targetPath: string): fs.Stats
405
+ ```
406
+
407
+ | Parameter | Type | Description |
408
+ |-----------|------|-------------|
409
+ | `targetPath` | string | 정보를 조회할 경로 |
410
+
411
+ **Return**: Node.js `fs.Stats` 객체
412
+
413
+ ---
414
+
415
+ ## `glob`
416
+
417
+ Glob 패턴을 사용하여 파일을 검색한다 (비동기).
418
+
419
+ ```typescript
420
+ export async function glob(pattern: string, options?: GlobOptions): Promise<string[]>
421
+ ```
422
+
423
+ | Parameter | Type | Description |
424
+ |-----------|------|-------------|
425
+ | `pattern` | string | Glob 패턴 (예: "**/*.ts") |
426
+ | `options` | GlobOptions (optional) | glob 옵션 |
427
+
428
+ **Return**: 매칭된 파일의 절대 경로 배열
429
+
430
+ ---
431
+
432
+ ## `globSync`
433
+
434
+ Glob 패턴을 사용하여 파일을 검색한다 (동기).
435
+
436
+ ```typescript
437
+ export function globSync(pattern: string, options?: GlobOptions): string[]
438
+ ```
439
+
440
+ | Parameter | Type | Description |
441
+ |-----------|------|-------------|
442
+ | `pattern` | string | Glob 패턴 (예: "**/*.ts") |
443
+ | `options` | GlobOptions (optional) | glob 옵션 |
444
+
445
+ **Return**: 매칭된 파일의 절대 경로 배열
446
+
447
+ ---
448
+
449
+ ## `clearEmptyDirectory`
450
+
451
+ 지정된 디렉토리 하위의 빈 디렉토리를 재귀적으로 검색하여 삭제한다.
452
+
453
+ 모든 하위 디렉토리가 삭제되어 상위 디렉토리가 비게 되면, 해당 디렉토리도 삭제된다.
454
+
455
+ ```typescript
456
+ export async function clearEmptyDirectory(dirPath: string): Promise<void>
457
+ ```
458
+
459
+ | Parameter | Type | Description |
460
+ |-----------|------|-------------|
461
+ | `dirPath` | string | 정리할 디렉토리 경로 |
462
+
463
+ ---
464
+
465
+ ## `findAllParentChildPathsSync`
466
+
467
+ 시작 경로에서 루트 방향으로 부모 디렉토리를 순회하며 glob 패턴에 매칭되는 파일을 검색한다.
468
+
469
+ 각 디렉토리에서 childGlob 패턴에 매칭되는 모든 파일 경로를 수집한다.
470
+
471
+ ```typescript
472
+ export function findAllParentChildPathsSync(
473
+ childGlob: string,
474
+ fromPath: string,
475
+ rootPath?: string,
476
+ ): string[]
477
+ ```
478
+
479
+ | Parameter | Type | Description |
480
+ |-----------|------|-------------|
481
+ | `childGlob` | string | 각 디렉토리에서 검색할 glob 패턴 |
482
+ | `fromPath` | string | 검색을 시작할 경로 |
483
+ | `rootPath` | string (optional) | 검색을 중단할 경로. 지정하지 않으면 파일 시스템 루트까지 검색. 주의: fromPath는 rootPath의 하위 경로여야 한다. 그렇지 않으면 파일 시스템 루트까지 검색한다. |
484
+
485
+ **Return**: 모든 매칭된 파일 경로 배열
486
+
487
+ ---
488
+
489
+ ## `findAllParentChildPaths`
490
+
491
+ 시작 경로에서 루트 방향으로 부모 디렉토리를 순회하며 glob 패턴에 매칭되는 파일을 검색한다 (비동기).
492
+
493
+ 각 디렉토리에서 childGlob 패턴에 매칭되는 모든 파일 경로를 수집한다.
494
+
495
+ ```typescript
496
+ export async function findAllParentChildPaths(
497
+ childGlob: string,
498
+ fromPath: string,
499
+ rootPath?: string,
500
+ ): Promise<string[]>
501
+ ```
502
+
503
+ | Parameter | Type | Description |
504
+ |-----------|------|-------------|
505
+ | `childGlob` | string | 각 디렉토리에서 검색할 glob 패턴 |
506
+ | `fromPath` | string | 검색을 시작할 경로 |
507
+ | `rootPath` | string (optional) | 검색을 중단할 경로. 지정하지 않으면 파일 시스템 루트까지 검색. 주의: fromPath는 rootPath의 하위 경로여야 한다. 그렇지 않으면 파일 시스템 루트까지 검색한다. |
508
+
509
+ **Return**: 모든 매칭된 파일 경로 배열
@@ -0,0 +1,139 @@
1
+ # File Watching (FsWatcher)
2
+
3
+ ## `FsWatcher`
4
+
5
+ Chokidar 기반 파일 시스템 감시 래퍼.
6
+
7
+ 짧은 시간 내에 발생하는 이벤트를 병합하여 콜백을 한 번만 호출한다.
8
+ EPERM 에러 발생 시 최대 3회까지 watcher를 자동 재시작한다.
9
+
10
+ ```typescript
11
+ export class FsWatcher {
12
+ static async watch(paths: string[], options?: ChokidarOptions): Promise<FsWatcher>
13
+ onChange(opt: { delay?: number }, cb: (changeInfos: FsWatcherChangeInfo[]) => void | Promise<void>): this
14
+ async close(): Promise<void>
15
+ }
16
+ ```
17
+
18
+ ### Static Methods
19
+
20
+ #### `watch`
21
+
22
+ 파일 또는 디렉토리의 변경을 감시하는 FsWatcher 인스턴스를 생성한다.
23
+
24
+ ```typescript
25
+ static async watch(
26
+ paths: string[],
27
+ options?: chokidar.ChokidarOptions,
28
+ ): Promise<FsWatcher>
29
+ ```
30
+
31
+ | Parameter | Type | Description |
32
+ |-----------|------|-------------|
33
+ | `paths` | string[] | 감시할 파일/디렉토리 경로 또는 glob 패턴 배열 |
34
+ | `options` | ChokidarOptions (optional) | Chokidar 옵션. `ignoreInitial: false`를 지정해도 첫 번째 onChange 호출 시 빈 배열이 콜백된다. 이는 이벤트 병합 로직과의 충돌을 방지하기 위한 의도적인 동작이다. |
35
+
36
+ **Return**: FsWatcher 인스턴스
37
+
38
+ **Example**:
39
+ ```typescript
40
+ const watcher = await FsWatcher.watch(["src/**/*.ts", "tests/**/*.ts"]);
41
+ ```
42
+
43
+ ### Instance Methods
44
+
45
+ #### `onChange`
46
+
47
+ 파일 변경 이벤트를 감시한다.
48
+
49
+ ```typescript
50
+ onChange(
51
+ opt: { delay?: number },
52
+ cb: (changeInfos: FsWatcherChangeInfo[]) => void | Promise<void>,
53
+ ): this
54
+ ```
55
+
56
+ | Parameter | Type | Description |
57
+ |-----------|------|-------------|
58
+ | `opt` | { delay?: number } | 이벤트 병합 설정. delay: 연속 이벤트를 병합하는 시간(ms). 생략 가능. |
59
+ | `cb` | function | 변경 이벤트 핸들러. 파일 변경 정보 배열이 전달된다. |
60
+
61
+ **Note**: delay 시간 내 발생한 여러 이벤트는 하나로 병합되어 한 번의 콜백만 호출된다.
62
+
63
+ **Example**:
64
+ ```typescript
65
+ watcher.onChange({ delay: 300 }, (changeInfos) => {
66
+ for (const { event, path } of changeInfos) {
67
+ console.log(`${event}: ${path}`);
68
+ }
69
+ });
70
+ ```
71
+
72
+ #### `close`
73
+
74
+ 파일 감시를 종료한다.
75
+
76
+ ```typescript
77
+ async close(): Promise<void>
78
+ ```
79
+
80
+ **Example**:
81
+ ```typescript
82
+ await watcher.close();
83
+ ```
84
+
85
+ ---
86
+
87
+ ## `FsWatcherEvent`
88
+
89
+ 파일 변경 이벤트 타입.
90
+
91
+ ```typescript
92
+ export type FsWatcherEvent = "add" | "addDir" | "change" | "unlink" | "unlinkDir"
93
+ ```
94
+
95
+ | Event | Description |
96
+ |-------|-------------|
97
+ | `"add"` | 새 파일이 추가됨 |
98
+ | `"addDir"` | 새 디렉토리가 추가됨 |
99
+ | `"change"` | 파일 내용이 변경됨 |
100
+ | `"unlink"` | 파일이 삭제됨 |
101
+ | `"unlinkDir"` | 디렉토리가 삭제됨 |
102
+
103
+ ---
104
+
105
+ ## `FsWatcherChangeInfo`
106
+
107
+ 파일 변경 정보.
108
+
109
+ ```typescript
110
+ export interface FsWatcherChangeInfo {
111
+ event: FsWatcherEvent;
112
+ path: PosixPath;
113
+ }
114
+ ```
115
+
116
+ | Field | Type | Description |
117
+ |-------|------|-------------|
118
+ | `event` | FsWatcherEvent | 변경 이벤트 타입 |
119
+ | `path` | PosixPath | 변경된 파일/디렉토리 경로 (정규화됨, POSIX 슬래시) |
120
+
121
+ ---
122
+
123
+ ## Event Merging
124
+
125
+ 연속적으로 발생하는 파일 변경 이벤트는 자동으로 병합된다.
126
+
127
+ 예를 들어, 파일을 생성하면 "add" 이벤트가 먼저 발생하고 그 직후 "change" 이벤트가 발생할 수 있지만, 지정된 delay 시간 내에 발생하면 다음과 같이 병합된다:
128
+
129
+ - `add` + `change` → `add` (마지막 change는 생략)
130
+ - `add` + `unlink` → `unlink` (파일이 최종적으로 삭제됨)
131
+ - `change` + `change` → `change` (중복 제거)
132
+
133
+ ---
134
+
135
+ ## Auto Recovery
136
+
137
+ EPERM(권한 거부) 에러가 발생하면 최대 3회까지 watcher를 자동으로 재시작한다.
138
+
139
+ 각 재시도 간격은 1000ms이다.