@simplysm/sd-claude 14.0.41 → 14.0.43

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 +16 -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/references/sd-testing.md +100 -4
  44. package/claude/rules/sd-claude-rules.md +19 -4
  45. package/claude/sd-check-write.py +1 -1
  46. package/claude/skills/sd-check/SKILL.md +7 -4
  47. package/claude/skills/sd-claude-docs/SKILL.md +7 -4
  48. package/claude/skills/sd-claude-docs/references/package-doc-gen.md +30 -7
  49. package/claude/skills/sd-commit/SKILL.md +2 -0
  50. package/claude/skills/sd-debug/SKILL.md +1 -1
  51. package/claude/skills/sd-deliverable/SKILL.md +2 -0
  52. package/claude/skills/sd-dev/SKILL.md +1 -1
  53. package/claude/skills/sd-doc-extract/SKILL.md +2 -0
  54. package/claude/{references/sd-debug.md → skills/sd-inner-debug/SKILL.md} +16 -20
  55. package/claude/{references/sd-review.md → skills/sd-inner-review/SKILL.md} +9 -4
  56. package/claude/skills/sd-issue/SKILL.md +2 -0
  57. package/claude/skills/sd-outlook/SKILL.md +2 -0
  58. package/claude/skills/sd-plan/SKILL.md +1 -1
  59. package/claude/skills/sd-prompt/SKILL.md +2 -2
  60. package/claude/skills/sd-refactor/SKILL.md +2 -2
  61. package/claude/skills/sd-review/SKILL.md +1 -1
  62. package/claude/skills/sd-tdd/SKILL.md +7 -7
  63. package/claude/skills/sd-use/SKILL.md +2 -0
  64. package/claude/skills/sd-wbs/SKILL.md +41 -18
  65. package/package.json +1 -1
  66. /package/claude/{rules → references}/sd-simplysm14.md +0 -0
  67. /package/claude/{references → rules}/sd-clarify.md +0 -0
@@ -1,6 +1,6 @@
1
1
  # @simplysm/capacitor-plugin-file-system
2
2
 
3
- Capacitor 파일 시스템 접근 플러그인. Android에서는 외부 저장소 전체 접근 및 앱 전용 디렉토리 접근을 제공하며, 브라우저에서는 IndexedDB 기반 가상 파일 시스템으로 에뮬레이션한다.
3
+ Capacitor 플러그인으로 Android 파일 시스템 접근을 제공합니다. 외부 저장소 전체 접근 및 앱 전용 디렉토리 접근을 지원하며, 브라우저 환경에서는 IndexedDB 기반 가상 파일 시스템으로 에뮬레이션합니다.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,169 +10,124 @@ npm install @simplysm/capacitor-plugin-file-system
10
10
 
11
11
  ## API Overview
12
12
 
13
- ### 파일 시스템
13
+ ### Core File System Operations
14
14
 
15
15
  | API | Type | Description |
16
16
  |-----|------|-------------|
17
- | `StorageType` | type | 저장소 유형 (external, externalFiles, externalCache 등 7종) |
18
- | `FileInfo` | interface | 파일/디렉토리 정보 (이름, 디렉토리 여부) |
19
- | `FileSystemPlugin` | interface | Capacitor 네이티브 플러그인 인터페이스 |
20
- | `FileSystem` | abstract class | 파일 시스템 접근 정적 파사드 |
17
+ | `FileSystem.readdir` | function | 디렉토리의 파일/폴더 목록 조회 |
18
+ | `FileSystem.writeFile` | function | 파일 쓰기 (문자열 또는 Bytes) |
19
+ | `FileSystem.readFile` | function | 파일 읽기 (기본: Bytes, encoding="utf8" 시: string) |
20
+ | `FileSystem.remove` | function | 파일/디렉토리 삭제 (재귀) |
21
+ | `FileSystem.mkdir` | function | 디렉토리 생성 (재귀) |
22
+ | `FileSystem.exists` | function | 파일/디렉토리 존재 여부 확인 |
21
23
 
22
- ---
24
+ → See [docs/file-operations.md](./docs/file-operations.md) for details.
23
25
 
24
- ## `StorageType`
26
+ ### Storage & Paths
25
27
 
26
- 저장소 유형을 나타내는 유니온 타입.
28
+ | API | Type | Description |
29
+ |-----|------|-------------|
30
+ | `FileSystem.getStoragePath` | function | 저장소 유형별 경로 조회 (external, externalFiles, appCache 등) |
31
+ | `FileSystem.getUri` | function | 파일 URI 조회 (FileProvider Blob URL) |
32
+ | `StorageType` | type | 저장소 유형 (external, externalFiles, externalCache, externalMedia, appData, appFiles, appCache) |
27
33
 
28
- ```typescript
29
- export type StorageType =
30
- | "external"
31
- | "externalFiles"
32
- | "externalCache"
33
- | "externalMedia"
34
- | "appData"
35
- | "appFiles"
36
- | "appCache";
37
- ```
34
+ → See [docs/storage-paths.md](./docs/storage-paths.md) for details.
38
35
 
39
- | Value | Android 경로 | Description |
40
- |-------|-------------|-------------|
41
- | `"external"` | `Environment.getExternalStorageDirectory()` | 외부 저장소 루트 |
42
- | `"externalFiles"` | `getExternalFilesDir(null)` | 앱 전용 외부 파일 디렉토리 |
43
- | `"externalCache"` | `externalCacheDir` | 앱 전용 외부 캐시 디렉토리 |
44
- | `"externalMedia"` | `externalMediaDirs[0]` | 앱 전용 외부 미디어 디렉토리 |
45
- | `"appData"` | `applicationInfo.dataDir` | 앱 데이터 디렉토리 |
46
- | `"appFiles"` | `filesDir` | 앱 파일 디렉토리 |
47
- | `"appCache"` | `cacheDir` | 앱 캐시 디렉토리 |
36
+ ### Permissions
48
37
 
49
- ## `FileInfo`
38
+ | API | Type | Description |
39
+ |-----|------|-------------|
40
+ | `FileSystem.checkPermissions` | function | 파일 시스템 접근 권한 확인 |
41
+ | `FileSystem.requestPermissions` | function | 파일 시스템 접근 권한 요청 |
50
42
 
51
- 파일 또는 디렉토리 정보를 나타내는 인터페이스.
43
+ See [docs/permissions.md](./docs/permissions.md) for details.
52
44
 
53
- ```typescript
54
- export interface FileInfo {
55
- name: string;
56
- isDirectory: boolean;
57
- }
58
- ```
45
+ ### Types
59
46
 
60
- | Field | Type | Description |
61
- |-------|------|-------------|
62
- | `name` | `string` | 파일 또는 디렉토리 이름 |
63
- | `isDirectory` | `boolean` | 디렉토리 여부 |
47
+ | API | Type | Description |
48
+ |-----|------|-------------|
49
+ | `FileInfo` | interface | 파일/디렉토리 정보 (name, isDirectory) |
64
50
 
65
- ## `FileSystemPlugin`
51
+ See [docs/types.md](./docs/types.md) for details.
66
52
 
67
- Capacitor 네이티브 플러그인 인터페이스. 직접 사용하지 않고 `FileSystem` 파사드를 통해 접근한다.
53
+ ## Usage Examples
68
54
 
69
- ```typescript
70
- export interface FileSystemPlugin {
71
- checkPermissions(): Promise<{ granted: boolean }>;
72
- requestPermissions(): Promise<void>;
73
- readdir(options: { path: string }): Promise<{ files: FileInfo[] }>;
74
- getStoragePath(options: { type: StorageType }): Promise<{ path: string }>;
75
- getUri(options: { path: string }): Promise<{ uri: string }>;
76
- writeFile(options: { path: string; data: string; encoding?: "utf8" | "base64" }): Promise<void>;
77
- readFile(options: { path: string; encoding?: "utf8" | "base64" }): Promise<{ data: string }>;
78
- remove(options: { path: string }): Promise<void>;
79
- mkdir(options: { path: string }): Promise<void>;
80
- exists(options: { path: string }): Promise<{ exists: boolean }>;
81
- }
82
- ```
55
+ ### 권한 확인 후 파일 읽기
83
56
 
84
- | Method | Parameters | Return | Description |
85
- |--------|-----------|--------|-------------|
86
- | `checkPermissions` | 없음 | `Promise<{ granted: boolean }>` | 파일 시스템 권한 확인 |
87
- | `requestPermissions` | 없음 | `Promise<void>` | 파일 시스템 권한 요청 |
88
- | `readdir` | `{ path }` | `Promise<{ files: FileInfo[] }>` | 디렉토리 내용 읽기 |
89
- | `getStoragePath` | `{ type: StorageType }` | `Promise<{ path: string }>` | 저장소 경로 조회 |
90
- | `getUri` | `{ path }` | `Promise<{ uri: string }>` | FileProvider URI 조회 |
91
- | `writeFile` | `{ path, data, encoding? }` | `Promise<void>` | 파일 쓰기 |
92
- | `readFile` | `{ path, encoding? }` | `Promise<{ data: string }>` | 파일 읽기 |
93
- | `remove` | `{ path }` | `Promise<void>` | 파일/디렉토리 삭제 (재귀) |
94
- | `mkdir` | `{ path }` | `Promise<void>` | 디렉토리 생성 (재귀) |
95
- | `exists` | `{ path }` | `Promise<{ exists: boolean }>` | 존재 여부 확인 |
57
+ ```typescript
58
+ import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
96
59
 
97
- ## `FileSystem`
60
+ async function readAppFile() {
61
+ // 권한 확인
62
+ const hasPermission = await FileSystem.checkPermissions();
63
+ if (!hasPermission) {
64
+ await FileSystem.requestPermissions();
65
+ }
98
66
 
99
- 파일 시스템 접근 정적 파사드 클래스. Android 11+에서는 MANAGE_EXTERNAL_STORAGE 권한, Android 10-에서는 READ/WRITE_EXTERNAL_STORAGE 권한을 사용한다. 브라우저에서는 IndexedDB 기반으로 에뮬레이션된다.
67
+ // 파일 디렉토리 경로 조회
68
+ const appFilesPath = await FileSystem.getStoragePath("appFiles");
100
69
 
101
- ```typescript
102
- export abstract class FileSystem {
103
- static async checkPermissions(): Promise<boolean>;
104
- static async requestPermissions(): Promise<void>;
105
- static async readdir(dirPath: string): Promise<FileInfo[]>;
106
- static async getStoragePath(type: StorageType): Promise<string>;
107
- static async getUri(filePath: string): Promise<string>;
108
- static async writeFile(filePath: string, data: string | Bytes): Promise<void>;
109
- static async readFile(filePath: string): Promise<Bytes>;
110
- static async readFile(filePath: string, encoding: "utf8"): Promise<string>;
111
- static async remove(targetPath: string): Promise<void>;
112
- static async mkdir(targetPath: string): Promise<void>;
113
- static async exists(targetPath: string): Promise<boolean>;
70
+ // 파일 읽기 (문자열)
71
+ const content = await FileSystem.readFile(appFilesPath + "/config.json", "utf8");
72
+ console.log(content);
114
73
  }
115
74
  ```
116
75
 
117
- | Method | Parameters | Return | Description |
118
- |--------|-----------|--------|-------------|
119
- | `checkPermissions` | 없음 | `Promise<boolean>` | 파일 시스템 권한 보유 여부 |
120
- | `requestPermissions` | 없음 | `Promise<void>` | 권한 요청 (Android 11+: 설정 화면, Android 10-: 대화상자) |
121
- | `readdir` | `dirPath: string` | `Promise<FileInfo[]>` | 디렉토리 내용 읽기 |
122
- | `getStoragePath` | `type: StorageType` | `Promise<string>` | 저장소 유형별 경로 조회 |
123
- | `getUri` | `filePath: string` | `Promise<string>` | FileProvider URI 조회. 브라우저에서는 Blob URL 반환 (사용 후 `URL.revokeObjectURL()` 필요) |
124
- | `writeFile` | `filePath: string, data: string \| Bytes` | `Promise<void>` | 파일 쓰기. `string` 전달 시 UTF-8, `Bytes`(Uint8Array) 전달 시 Base64 인코딩하여 전송 |
125
- | `readFile` | `filePath: string` | `Promise<Bytes>` | 파일을 바이너리로 읽기 |
126
- | `readFile` | `filePath: string, encoding: "utf8"` | `Promise<string>` | 파일을 UTF-8 문자열로 읽기 |
127
- | `remove` | `targetPath: string` | `Promise<void>` | 파일 또는 디렉토리 재귀 삭제 |
128
- | `mkdir` | `targetPath: string` | `Promise<void>` | 디렉토리 재귀 생성 |
129
- | `exists` | `targetPath: string` | `Promise<boolean>` | 파일/디렉토리 존재 여부 확인 |
130
-
131
- ## Usage Examples
132
-
133
- ### 파일 읽기/쓰기
76
+ ### Bytes 데이터 쓰기
134
77
 
135
78
  ```typescript
136
79
  import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
137
-
138
- // 앱 캐시 디렉토리에 텍스트 파일 쓰기
139
- const cachePath = await FileSystem.getStoragePath("appCache");
140
- await FileSystem.writeFile(cachePath + "/config.json", '{"key": "value"}');
141
-
142
- // 텍스트 파일 읽기
143
- const text = await FileSystem.readFile(cachePath + "/config.json", "utf8");
144
-
145
- // 바이너리 파일 읽기
146
- const data: Bytes = await FileSystem.readFile(cachePath + "/image.png");
80
+ import { bytes } from "@simplysm/core-common";
81
+
82
+ async function writeAppDataAsBytes() {
83
+ const appCachePath = await FileSystem.getStoragePath("appCache");
84
+
85
+ // Uint8Array로 작성
86
+ const data = new Uint8Array([0x89, 0x50, 0x4e, 0x47]); // PNG header
87
+ await FileSystem.writeFile(appCachePath + "/image.png", data);
88
+ }
147
89
  ```
148
90
 
149
- ### 권한 확인 및 외부 저장소 접근
91
+ ### 디렉토리 탐색
150
92
 
151
93
  ```typescript
152
94
  import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
153
95
 
154
- const granted = await FileSystem.checkPermissions();
155
- if (!granted) {
156
- await FileSystem.requestPermissions();
96
+ async function listDirectory(dirPath: string) {
97
+ const files = await FileSystem.readdir(dirPath);
98
+
99
+ for (const file of files) {
100
+ console.log(`${file.name} ${file.isDirectory ? "(dir)" : "(file)"}`);
101
+ }
102
+
103
+ // 삭제 전 존재 여부 확인
104
+ const exists = await FileSystem.exists(dirPath);
105
+ if (exists) {
106
+ await FileSystem.remove(dirPath);
107
+ }
157
108
  }
158
-
159
- const externalPath = await FileSystem.getStoragePath("external");
160
- const files = await FileSystem.readdir(externalPath + "/Documents");
161
109
  ```
162
110
 
163
- ### 디렉토리 관리
111
+ ### 브라우저에서 Blob URL 사용
164
112
 
165
113
  ```typescript
166
114
  import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
167
115
 
168
- const filesPath = await FileSystem.getStoragePath("appFiles");
169
-
170
- // 디렉토리 생성
171
- await FileSystem.mkdir(filesPath + "/downloads/images");
172
-
173
- // 존재 여부 확인
174
- const exists = await FileSystem.exists(filesPath + "/downloads/images");
175
-
176
- // 재귀 삭제
177
- await FileSystem.remove(filesPath + "/downloads");
116
+ async function showImageInBrowser() {
117
+ const appFilesPath = await FileSystem.getStoragePath("appFiles");
118
+ const imagePath = appFilesPath + "/photo.jpg";
119
+
120
+ // Blob URL 획득
121
+ const uri = await FileSystem.getUri(imagePath);
122
+
123
+ // DOM에서 사용
124
+ const img = document.createElement("img");
125
+ img.src = uri;
126
+ document.body.appendChild(img);
127
+
128
+ // 사용 완료 후 URL 해제 (메모리 누수 방지)
129
+ img.onload = () => {
130
+ URL.revokeObjectURL(uri);
131
+ };
132
+ }
178
133
  ```
@@ -10,7 +10,7 @@ npm install @simplysm/capacitor-plugin-usb-storage
10
10
 
11
11
  ## API Overview
12
12
 
13
- ### USB 저장소
13
+ ### USB 저장소 - 공개 API
14
14
 
15
15
  | API | Type | Description |
16
16
  |-----|------|-------------|
@@ -122,6 +122,72 @@ export abstract class UsbStorage {
122
122
  | `readdir` | `filter: UsbDeviceFilter, dirPath: string` | `Promise<UsbFileInfo[]>` | USB 저장 장치의 디렉토리 내용 읽기 |
123
123
  | `readFile` | `filter: UsbDeviceFilter, filePath: string` | `Promise<Bytes \| undefined>` | USB 저장 장치에서 파일 읽기. 파일이 없으면 `undefined` 반환. 최대 100MB |
124
124
 
125
+ ## Browser-Only Testing API (`UsbStorageWeb`)
126
+
127
+ 브라우저 환경에서 테스트 및 개발 목적으로 사용하는 API. `UsbStorage` 정적 파사드로는 접근할 수 없으며, `UsbStorageWeb` 인스턴스를 직접 사용할 때만 호출 가능하다.
128
+
129
+ ### `addVirtualDevice(device)`
130
+
131
+ 가상 USB 장치를 IndexedDB에 등록한다. (테스트/개발용)
132
+
133
+ ```typescript
134
+ async addVirtualDevice(device: {
135
+ vendorId: number;
136
+ productId: number;
137
+ deviceName: string;
138
+ manufacturerName: string;
139
+ productName: string;
140
+ }): Promise<void>
141
+ ```
142
+
143
+ | Parameter | Type | Description |
144
+ |-----------|------|-------------|
145
+ | `device.vendorId` | `number` | USB Vendor ID |
146
+ | `device.productId` | `number` | USB Product ID |
147
+ | `device.deviceName` | `string` | 장치 이름 |
148
+ | `device.manufacturerName` | `string` | 제조사 이름 |
149
+ | `device.productName` | `string` | 제품 이름 |
150
+
151
+ ### `addVirtualFile(filter, filePath, data)`
152
+
153
+ 가상 USB 장치에 파일을 추가한다. (테스트/개발용)
154
+
155
+ ```typescript
156
+ async addVirtualFile(
157
+ filter: UsbDeviceFilter,
158
+ filePath: string,
159
+ data: Uint8Array,
160
+ ): Promise<void>
161
+ ```
162
+
163
+ | Parameter | Type | Description |
164
+ |-----------|------|-------------|
165
+ | `filter.vendorId` | `number` | 대상 장치의 USB Vendor ID |
166
+ | `filter.productId` | `number` | 대상 장치의 USB Product ID |
167
+ | `filePath` | `string` | 파일 경로 (예: `/updates/config.json`) |
168
+ | `data` | `Uint8Array` | 파일 바이너리 데이터 |
169
+
170
+ **주의**: 파일이 위치할 부모 디렉토리가 존재하지 않으면 자동으로 생성된다.
171
+
172
+ ### `addVirtualDirectory(filter, dirPath)`
173
+
174
+ 가상 USB 장치에 디렉토리를 추가한다. (테스트/개발용)
175
+
176
+ ```typescript
177
+ async addVirtualDirectory(
178
+ filter: UsbDeviceFilter,
179
+ dirPath: string,
180
+ ): Promise<void>
181
+ ```
182
+
183
+ | Parameter | Type | Description |
184
+ |-----------|------|-------------|
185
+ | `filter.vendorId` | `number` | 대상 장치의 USB Vendor ID |
186
+ | `filter.productId` | `number` | 대상 장치의 USB Product ID |
187
+ | `dirPath` | `string` | 생성할 디렉토리 경로 (예: `/updates`) |
188
+
189
+ ---
190
+
125
191
  ## Usage Examples
126
192
 
127
193
  ### USB 장치 열거 및 권한 요청
@@ -158,3 +224,35 @@ if (data != null) {
158
224
  const text = new TextDecoder().decode(data);
159
225
  }
160
226
  ```
227
+
228
+ ### 브라우저 테스트 - 가상 USB 장치 설정
229
+
230
+ 브라우저 환경에서 테스트할 때, `UsbStorageWeb`을 직접 import하여 가상 USB 저장소를 설정한다. `UsbStorageWeb`은 패키지 공개 API(`index.ts`)에서 export되지 않으므로, 소스 경로를 직접 참조한다.
231
+
232
+ ```typescript
233
+ import { UsbStorageWeb } from "@simplysm/capacitor-plugin-usb-storage/src/web/UsbStorageWeb";
234
+ import { UsbStorage } from "@simplysm/capacitor-plugin-usb-storage";
235
+
236
+ const usbStorageWeb = new UsbStorageWeb();
237
+
238
+ // 가상 장치 등록
239
+ await usbStorageWeb.addVirtualDevice({
240
+ vendorId: 1234,
241
+ productId: 5678,
242
+ deviceName: "Test Device",
243
+ manufacturerName: "Test Manufacturer",
244
+ productName: "Test Product",
245
+ });
246
+
247
+ // 가상 파일 추가
248
+ const fileData = new TextEncoder().encode("Hello, USB!");
249
+ await usbStorageWeb.addVirtualFile(
250
+ { vendorId: 1234, productId: 5678 },
251
+ "/updates/config.json",
252
+ fileData,
253
+ );
254
+
255
+ // UsbStorage 정적 API로 접근 (Capacitor가 브라우저에서 UsbStorageWeb 인스턴스를 사용)
256
+ const files = await UsbStorage.readdir({ vendorId: 1234, productId: 5678 }, "/updates");
257
+ const data = await UsbStorage.readFile({ vendorId: 1234, productId: 5678 }, "/updates/config.json");
258
+ ```
@@ -0,0 +1,182 @@
1
+ # Child Process (cpx)
2
+
3
+ ## `spawn`
4
+
5
+ 자식 프로세스를 실행한다 (비동기).
6
+
7
+ SpawnProcess를 반환하며, await로 결과를 기다리거나 kill()로 프로세스를 종료할 수 있다.
8
+
9
+ ```typescript
10
+ export function spawn(
11
+ cmd: string,
12
+ args: string[],
13
+ options?: SpawnOptions & { reject?: boolean },
14
+ ): SpawnProcess
15
+ ```
16
+
17
+ | Parameter | Type | Description |
18
+ |-----------|------|-------------|
19
+ | `cmd` | string | 실행할 명령어 |
20
+ | `args` | string[] | 명령어 인자 배열 |
21
+ | `options` | SpawnOptions & { reject?: boolean } (optional) | spawn 옵션. `reject: false`를 지정하면 exitCode !== 0일 때도 reject되지 않음 (기본값: true) |
22
+
23
+ **Return**: SpawnProcess (PromiseLike + kill() 메서드)
24
+
25
+ **Note**: 기본적으로 `exitCode !== 0`이면 reject된다. `options.reject: false`를 지정하면 항상 resolve된다.
26
+
27
+ ---
28
+
29
+ ## `spawnSync`
30
+
31
+ 자식 프로세스를 동기로 실행한다.
32
+
33
+ ```typescript
34
+ export function spawnSync(
35
+ cmd: string,
36
+ args: string[],
37
+ options?: SpawnSyncOptions & { reject?: boolean },
38
+ ): SpawnResult
39
+ ```
40
+
41
+ | Parameter | Type | Description |
42
+ |-----------|------|-------------|
43
+ | `cmd` | string | 실행할 명령어 |
44
+ | `args` | string[] | 명령어 인자 배열 |
45
+ | `options` | SpawnSyncOptions & { reject?: boolean } (optional) | spawn 옵션. `reject: false`를 지정하면 exitCode !== 0일 때도 throw되지 않음 (기본값: true) |
46
+
47
+ **Return**: SpawnResult
48
+
49
+ **Note**: 기본적으로 `exitCode !== 0`이면 throw된다. `options.reject: false`를 지정하면 항상 반환된다.
50
+
51
+ ---
52
+
53
+ ## `SpawnProcess`
54
+
55
+ spawn() 반환 타입. PromiseLike를 구현하므로 await로 사용 가능하며, kill() 메서드로 프로세스를 종료할 수 있다.
56
+
57
+ ```typescript
58
+ export class SpawnProcess implements PromiseLike<SpawnResult> {
59
+ get pid(): number | undefined
60
+ then<TResult1 = SpawnResult, TResult2 = never>(
61
+ onfulfilled?: ((value: SpawnResult) => TResult1 | PromiseLike<TResult1>) | null,
62
+ onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,
63
+ ): Promise<TResult1 | TResult2>
64
+ catch<TResult = never>(
65
+ onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
66
+ ): Promise<SpawnResult | TResult>
67
+ kill(signal?: NodeJS.Signals | number): boolean
68
+ }
69
+ ```
70
+
71
+ ### Properties
72
+
73
+ | Name | Type | Description |
74
+ |------|------|-------------|
75
+ | `pid` | number \| undefined | 자식 프로세스의 PID |
76
+
77
+ ### Methods
78
+
79
+ | Name | Signature | Description |
80
+ |------|-----------|-------------|
81
+ | `then` | `<TResult1, TResult2>(onfulfilled?, onrejected?): Promise` | Promise의 then 메서드 |
82
+ | `catch` | `<TResult>(onrejected?): Promise` | Promise의 catch 메서드 |
83
+ | `kill` | `(signal?): boolean` | 프로세스에 신호를 보낸다 (기본값: SIGTERM) |
84
+
85
+ ---
86
+
87
+ ## `SpawnResult`
88
+
89
+ spawn/spawnSync 결과.
90
+
91
+ ```typescript
92
+ export interface SpawnResult {
93
+ stdout: string;
94
+ stderr: string;
95
+ exitCode: number;
96
+ }
97
+ ```
98
+
99
+ | Field | Type | Description |
100
+ |-------|------|-------------|
101
+ | `stdout` | string | 표준 출력 내용 |
102
+ | `stderr` | string | 표준 에러 내용 |
103
+ | `exitCode` | number | 프로세스 종료 코드 |
104
+
105
+ ---
106
+
107
+ ## `getSystemEncoding`
108
+
109
+ 시스템의 기본 인코딩을 감지한다.
110
+
111
+ ```typescript
112
+ export function getSystemEncoding(): string
113
+ ```
114
+
115
+ **Return**: 시스템 인코딩 (예: "utf-8", "euc-kr")
116
+
117
+ **Note**: 결과는 캐시되므로 반복 호출은 빠르다. 캐시를 초기화하려면 resetEncodingCache()를 호출한다.
118
+
119
+ ---
120
+
121
+ ## `codePageToEncoding`
122
+
123
+ Windows 코드 페이지 번호를 인코딩 이름으로 변환한다.
124
+
125
+ ```typescript
126
+ export function codePageToEncoding(codePage: number): string
127
+ ```
128
+
129
+ | Parameter | Type | Description |
130
+ |-----------|------|-------------|
131
+ | `codePage` | number | Windows 코드 페이지 번호 (예: 65001 = UTF-8, 949 = EUC-KR) |
132
+
133
+ **Return**: 인코딩 이름 (예: "utf-8"). 미지의 코드 페이지는 "utf-8"으로 폴백된다.
134
+
135
+ ---
136
+
137
+ ## `resetEncodingCache`
138
+
139
+ 캐시된 시스템 인코딩을 초기화한다.
140
+
141
+ ```typescript
142
+ export function resetEncodingCache(): void
143
+ ```
144
+
145
+ ---
146
+
147
+ ## `decodeBytes`
148
+
149
+ Uint8Array를 문자열로 디코딩한다.
150
+
151
+ ```typescript
152
+ export function decodeBytes(raw: Uint8Array, systemEncoding?: string): string
153
+ ```
154
+
155
+ | Parameter | Type | Description |
156
+ |-----------|------|-------------|
157
+ | `raw` | Uint8Array | 디코딩할 바이트 배열 |
158
+ | `systemEncoding` | string (optional) | 인코딩 이름. 생략하면 getSystemEncoding()의 결과를 사용한다. |
159
+
160
+ **Return**: 디코딩된 문자열
161
+
162
+ **Note**: UTF-8이 아닌 인코딩인 경우, 먼저 UTF-8로 디코딩을 시도하고 실패하면 지정된 인코딩으로 시도한다.
163
+
164
+ ---
165
+
166
+ ## `resolveStdioPipe`
167
+
168
+ stdio 옵션에서 stdout/stderr의 pipe 여부를 추출한다.
169
+
170
+ ```typescript
171
+ export function resolveStdioPipe(
172
+ stdio: SpawnOptions["stdio"],
173
+ ): { stdout: boolean; stderr: boolean }
174
+ ```
175
+
176
+ | Parameter | Type | Description |
177
+ |-----------|------|-------------|
178
+ | `stdio` | SpawnOptions["stdio"] | spawn 옵션의 stdio 설정 |
179
+
180
+ **Return**: `{ stdout: boolean, stderr: boolean }` - 각 스트림이 pipe인지 여부
181
+
182
+ **Note**: stdio가 배열이 아니면, "pipe"(또는 undefined)일 때 true, 그 외엔 false를 반환한다.
@@ -183,7 +183,7 @@ export interface SetupConsolaOptions {
183
183
 
184
184
  | Field | Type | Description |
185
185
  |-------|------|-------------|
186
- | `cli` | `boolean` | true이면 CLI 모드. 항상 PrettyReporter를 사용하고 FileReporter 사용하지 않는다 |
186
+ | `cli` | `boolean` | true이면 CLI 모드. 프로덕션 경로를 건너뛰고 개발 경로로 진입한다. `SD_DEBUG`가 없으면 `FileReporter` + `PrettyReporter`(info 이하) 조합 사용 |
187
187
 
188
188
  ---
189
189