@simplysm/sd-cli 13.0.69 → 13.0.71

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 (201) hide show
  1. package/README.md +10 -957
  2. package/dist/builders/BaseBuilder.d.ts +23 -23
  3. package/dist/builders/BaseBuilder.d.ts.map +1 -1
  4. package/dist/builders/BaseBuilder.js +15 -15
  5. package/dist/builders/DtsBuilder.d.ts +4 -4
  6. package/dist/builders/DtsBuilder.js +1 -1
  7. package/dist/builders/LibraryBuilder.d.ts +3 -3
  8. package/dist/builders/types.d.ts +10 -10
  9. package/dist/capacitor/capacitor.d.ts +36 -36
  10. package/dist/capacitor/capacitor.js +63 -63
  11. package/dist/capacitor/capacitor.js.map +1 -1
  12. package/dist/commands/add-client.d.ts +8 -8
  13. package/dist/commands/add-client.js +15 -15
  14. package/dist/commands/add-client.js.map +1 -1
  15. package/dist/commands/add-server.d.ts +9 -9
  16. package/dist/commands/add-server.js +13 -13
  17. package/dist/commands/add-server.js.map +1 -1
  18. package/dist/commands/build.d.ts +9 -9
  19. package/dist/commands/check.js +3 -3
  20. package/dist/commands/check.js.map +1 -1
  21. package/dist/commands/dev.d.ts +9 -9
  22. package/dist/commands/device.d.ts +9 -9
  23. package/dist/commands/device.d.ts.map +1 -1
  24. package/dist/commands/device.js +17 -17
  25. package/dist/commands/device.js.map +1 -1
  26. package/dist/commands/init.d.ts +6 -6
  27. package/dist/commands/init.js +12 -12
  28. package/dist/commands/init.js.map +1 -1
  29. package/dist/commands/lint.d.ts +23 -23
  30. package/dist/commands/lint.d.ts.map +1 -1
  31. package/dist/commands/lint.js +25 -25
  32. package/dist/commands/lint.js.map +1 -1
  33. package/dist/commands/publish.d.ts +13 -13
  34. package/dist/commands/publish.d.ts.map +1 -1
  35. package/dist/commands/publish.js +61 -61
  36. package/dist/commands/publish.js.map +1 -1
  37. package/dist/commands/replace-deps.d.ts +3 -3
  38. package/dist/commands/replace-deps.d.ts.map +1 -1
  39. package/dist/commands/replace-deps.js +1 -1
  40. package/dist/commands/replace-deps.js.map +1 -1
  41. package/dist/commands/typecheck.d.ts +20 -20
  42. package/dist/commands/typecheck.d.ts.map +1 -1
  43. package/dist/commands/typecheck.js +20 -20
  44. package/dist/commands/typecheck.js.map +1 -1
  45. package/dist/commands/watch.d.ts +7 -7
  46. package/dist/electron/electron.d.ts +27 -27
  47. package/dist/electron/electron.js +32 -32
  48. package/dist/electron/electron.js.map +1 -1
  49. package/dist/infra/ResultCollector.d.ts +9 -9
  50. package/dist/infra/ResultCollector.js +5 -5
  51. package/dist/infra/SignalHandler.d.ts +7 -7
  52. package/dist/infra/SignalHandler.js +4 -4
  53. package/dist/infra/WorkerManager.d.ts +14 -14
  54. package/dist/infra/WorkerManager.js +11 -11
  55. package/dist/orchestrators/BuildOrchestrator.d.ts +19 -19
  56. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  57. package/dist/orchestrators/BuildOrchestrator.js +26 -26
  58. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  59. package/dist/orchestrators/DevOrchestrator.d.ts +25 -25
  60. package/dist/orchestrators/DevOrchestrator.d.ts.map +1 -1
  61. package/dist/orchestrators/DevOrchestrator.js +30 -30
  62. package/dist/orchestrators/DevOrchestrator.js.map +1 -1
  63. package/dist/orchestrators/WatchOrchestrator.d.ts +13 -13
  64. package/dist/orchestrators/WatchOrchestrator.js +17 -17
  65. package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
  66. package/dist/sd-cli-entry.d.ts +2 -2
  67. package/dist/sd-cli-entry.js +38 -38
  68. package/dist/sd-cli-entry.js.map +1 -1
  69. package/dist/sd-cli.d.ts +2 -2
  70. package/dist/sd-cli.js +1 -1
  71. package/dist/sd-cli.js.map +1 -1
  72. package/dist/sd-config.types.d.ts +84 -84
  73. package/dist/sd-config.types.d.ts.map +1 -1
  74. package/dist/utils/build-env.d.ts +1 -1
  75. package/dist/utils/config-editor.d.ts +5 -5
  76. package/dist/utils/config-editor.js +2 -2
  77. package/dist/utils/config-editor.js.map +1 -1
  78. package/dist/utils/copy-public.d.ts +9 -9
  79. package/dist/utils/copy-src.d.ts +9 -9
  80. package/dist/utils/esbuild-config.d.ts +30 -30
  81. package/dist/utils/esbuild-config.d.ts.map +1 -1
  82. package/dist/utils/output-utils.d.ts +6 -6
  83. package/dist/utils/package-utils.d.ts +6 -6
  84. package/dist/utils/package-utils.js +1 -1
  85. package/dist/utils/package-utils.js.map +1 -1
  86. package/dist/utils/rebuild-manager.js +3 -3
  87. package/dist/utils/rebuild-manager.js.map +1 -1
  88. package/dist/utils/replace-deps.d.ts +25 -25
  89. package/dist/utils/replace-deps.js +3 -3
  90. package/dist/utils/replace-deps.js.map +1 -1
  91. package/dist/utils/sd-config.d.ts +3 -3
  92. package/dist/utils/sd-config.js +3 -3
  93. package/dist/utils/sd-config.js.map +1 -1
  94. package/dist/utils/tailwind-config-deps.d.ts +3 -3
  95. package/dist/utils/template.d.ts +8 -8
  96. package/dist/utils/tsconfig.d.ts +16 -16
  97. package/dist/utils/tsconfig.js +2 -2
  98. package/dist/utils/tsconfig.js.map +1 -1
  99. package/dist/utils/typecheck-serialization.d.ts +8 -8
  100. package/dist/utils/vite-config.d.ts +8 -8
  101. package/dist/utils/vite-config.d.ts.map +1 -1
  102. package/dist/utils/vite-config.js +3 -3
  103. package/dist/utils/worker-events.d.ts +12 -12
  104. package/dist/utils/worker-events.d.ts.map +1 -1
  105. package/dist/utils/worker-utils.d.ts +3 -3
  106. package/dist/utils/worker-utils.js +2 -2
  107. package/dist/utils/worker-utils.js.map +1 -1
  108. package/dist/workers/client.worker.d.ts +14 -14
  109. package/dist/workers/client.worker.d.ts.map +1 -1
  110. package/dist/workers/client.worker.js +1 -1
  111. package/dist/workers/client.worker.js.map +1 -1
  112. package/dist/workers/dts.worker.d.ts +13 -13
  113. package/dist/workers/dts.worker.d.ts.map +1 -1
  114. package/dist/workers/dts.worker.js +3 -3
  115. package/dist/workers/dts.worker.js.map +1 -1
  116. package/dist/workers/library.worker.d.ts +12 -12
  117. package/dist/workers/library.worker.js +1 -1
  118. package/dist/workers/library.worker.js.map +1 -1
  119. package/dist/workers/lint.worker.d.ts +1 -1
  120. package/dist/workers/server-runtime.worker.d.ts +6 -6
  121. package/dist/workers/server-runtime.worker.js +6 -6
  122. package/dist/workers/server-runtime.worker.js.map +1 -1
  123. package/dist/workers/server.worker.d.ts +20 -20
  124. package/dist/workers/server.worker.d.ts.map +1 -1
  125. package/dist/workers/server.worker.js +6 -6
  126. package/dist/workers/server.worker.js.map +1 -1
  127. package/package.json +8 -7
  128. package/src/builders/BaseBuilder.ts +33 -33
  129. package/src/builders/DtsBuilder.ts +5 -5
  130. package/src/builders/LibraryBuilder.ts +9 -9
  131. package/src/builders/types.ts +10 -10
  132. package/src/capacitor/capacitor.ts +119 -119
  133. package/src/commands/add-client.ts +31 -31
  134. package/src/commands/add-server.ts +34 -34
  135. package/src/commands/build.ts +9 -9
  136. package/src/commands/check.ts +5 -5
  137. package/src/commands/dev.ts +9 -9
  138. package/src/commands/device.ts +30 -30
  139. package/src/commands/init.ts +25 -25
  140. package/src/commands/lint.ts +64 -64
  141. package/src/commands/publish.ts +139 -139
  142. package/src/commands/replace-deps.ts +4 -4
  143. package/src/commands/typecheck.ts +74 -74
  144. package/src/commands/watch.ts +7 -7
  145. package/src/electron/electron.ts +51 -51
  146. package/src/infra/ResultCollector.ts +9 -9
  147. package/src/infra/SignalHandler.ts +7 -7
  148. package/src/infra/WorkerManager.ts +14 -14
  149. package/src/orchestrators/BuildOrchestrator.ts +76 -76
  150. package/src/orchestrators/DevOrchestrator.ts +88 -88
  151. package/src/orchestrators/WatchOrchestrator.ts +39 -39
  152. package/src/sd-cli-entry.ts +43 -43
  153. package/src/sd-cli.ts +15 -15
  154. package/src/sd-config.types.ts +85 -85
  155. package/src/utils/build-env.ts +1 -1
  156. package/src/utils/config-editor.ts +19 -19
  157. package/src/utils/copy-public.ts +17 -17
  158. package/src/utils/copy-src.ts +11 -11
  159. package/src/utils/esbuild-config.ts +33 -33
  160. package/src/utils/output-utils.ts +11 -11
  161. package/src/utils/package-utils.ts +12 -12
  162. package/src/utils/rebuild-manager.ts +3 -3
  163. package/src/utils/replace-deps.ts +361 -361
  164. package/src/utils/sd-config.ts +44 -44
  165. package/src/utils/tailwind-config-deps.ts +98 -98
  166. package/src/utils/template.ts +56 -56
  167. package/src/utils/tsconfig.ts +127 -127
  168. package/src/utils/typecheck-serialization.ts +86 -86
  169. package/src/utils/vite-config.ts +341 -341
  170. package/src/utils/worker-events.ts +16 -16
  171. package/src/utils/worker-utils.ts +45 -45
  172. package/src/workers/client.worker.ts +34 -34
  173. package/src/workers/dts.worker.ts +467 -467
  174. package/src/workers/library.worker.ts +314 -314
  175. package/src/workers/lint.worker.ts +16 -16
  176. package/src/workers/server-runtime.worker.ts +157 -157
  177. package/src/workers/server.worker.ts +572 -572
  178. package/templates/add-client/__CLIENT__/package.json.hbs +1 -1
  179. package/templates/add-server/__SERVER__/package.json.hbs +2 -2
  180. package/templates/init/package.json.hbs +3 -3
  181. package/tests/config-editor.spec.ts +160 -0
  182. package/tests/copy-src.spec.ts +50 -0
  183. package/tests/get-compiler-options-for-package.spec.ts +139 -0
  184. package/tests/get-package-source-files.spec.ts +181 -0
  185. package/tests/get-types-from-package-json.spec.ts +107 -0
  186. package/tests/infra/ResultCollector.spec.ts +39 -0
  187. package/tests/infra/SignalHandler.spec.ts +38 -0
  188. package/tests/infra/WorkerManager.spec.ts +97 -0
  189. package/tests/load-ignore-patterns.spec.ts +188 -0
  190. package/tests/load-sd-config.spec.ts +137 -0
  191. package/tests/package-utils.spec.ts +188 -0
  192. package/tests/parse-root-tsconfig.spec.ts +89 -0
  193. package/tests/replace-deps.spec.ts +308 -0
  194. package/tests/run-lint.spec.ts +415 -0
  195. package/tests/run-typecheck.spec.ts +653 -0
  196. package/tests/run-watch.spec.ts +75 -0
  197. package/tests/sd-cli.spec.ts +330 -0
  198. package/tests/tailwind-config-deps.spec.ts +30 -0
  199. package/tests/template.spec.ts +70 -0
  200. package/tests/utils/rebuild-manager.spec.ts +43 -0
  201. package/tests/write-changed-output-files.spec.ts +97 -0
@@ -10,7 +10,7 @@ import { findPackageRoot } from "../utils/package-utils";
10
10
  //#region Types
11
11
 
12
12
  /**
13
- * Add-client 명령 옵션
13
+ * Add-client command options
14
14
  */
15
15
  export interface AddClientOptions {}
16
16
 
@@ -22,56 +22,56 @@ export interface AddClientOptions {}
22
22
  //#region Main
23
23
 
24
24
  /**
25
- * 클라이언트 패키지를 프로젝트에 추가한다.
25
+ * Add client package to the project.
26
26
  *
27
- * 1. 프로젝트 루트 확인 (sd.config.ts 존재)
28
- * 2. 대화형 프롬프트 (이름 접미사, 라우터 사용 여부)
29
- * 3. 패키지 디렉토리 중복 확인
30
- * 4. Handlebars 템플릿 렌더링
31
- * 5. sd.config.ts 패키지 항목 추가 (ts-morph)
32
- * 6. eslint.config.ts tailwind 설정 추가 ( 클라이언트인 경우)
27
+ * 1. Verify project root (sd.config.ts exists)
28
+ * 2. Interactive prompt (name suffix, router usage)
29
+ * 3. Check for duplicate package directory
30
+ * 4. Render Handlebars template
31
+ * 5. Add package entry to sd.config.ts (ts-morph)
32
+ * 6. Add tailwind configuration to eslint.config.ts (if first client)
33
33
  * 7. pnpm install
34
34
  */
35
35
  export async function runAddClient(_options: AddClientOptions): Promise<void> {
36
36
  const cwd = process.cwd();
37
37
  const logger = consola.withTag("sd:cli:add-client");
38
38
 
39
- // 1. 프로젝트 루트 확인
39
+ // 1. Verify project root
40
40
  if (!fs.existsSync(path.join(cwd, "sd.config.ts"))) {
41
- consola.error("sd.config.ts 찾을 없습니다. 프로젝트 루트에서 실행해주세요.");
41
+ consola.error("Cannot find sd.config.ts. Please run from the project root.");
42
42
  process.exitCode = 1;
43
43
  return;
44
44
  }
45
45
 
46
- // 프로젝트명
46
+ // Project name
47
47
  const projectName = path.basename(cwd);
48
48
 
49
- // 2. 대화형 프롬프트
49
+ // 2. Interactive prompt
50
50
  const clientSuffix = await input({
51
- message: "클라이언트 이름을 입력하세요 (client-___):",
51
+ message: "Enter client name suffix (client-___):",
52
52
  validate: (value) => {
53
- if (!value.trim()) return "이름을 입력해주세요.";
54
- if (!/^[a-z][a-z0-9-]*$/.test(value)) return "소문자, 숫자, 하이픈만 사용 가능합니다.";
53
+ if (!value.trim()) return "Please enter a name.";
54
+ if (!/^[a-z][a-z0-9-]*$/.test(value)) return "Only lowercase letters, numbers, and hyphens are allowed.";
55
55
  return true;
56
56
  },
57
57
  });
58
58
 
59
59
  const useRouter = await confirm({
60
- message: "라우터를 사용하시겠습니까?",
60
+ message: "Do you want to use router?",
61
61
  default: true,
62
62
  });
63
63
 
64
64
  const clientName = `client-${clientSuffix}`;
65
65
 
66
- // 3. 패키지 디렉토리 중복 확인
66
+ // 3. Check for duplicate package directory
67
67
  const packageDir = path.join(cwd, "packages", clientName);
68
68
  if (fs.existsSync(packageDir)) {
69
- consola.error(`packages/${clientName} 디렉토리가 이미 존재합니다.`);
69
+ consola.error(`packages/${clientName} directory already exists.`);
70
70
  process.exitCode = 1;
71
71
  return;
72
72
  }
73
73
 
74
- // 4. 템플릿 렌더링
74
+ // 4. Render template
75
75
  const pkgRoot = findPackageRoot(import.meta.dirname);
76
76
  const templateDir = path.join(pkgRoot, "templates", "add-client");
77
77
 
@@ -86,39 +86,39 @@ export async function runAddClient(_options: AddClientOptions): Promise<void> {
86
86
  __CLIENT__: clientName,
87
87
  };
88
88
 
89
- logger.info(`${clientName} 패키지 생성 중...`);
89
+ logger.info(`Creating ${clientName} package...`);
90
90
  await renderTemplateDir(templateDir, path.join(cwd, "packages"), context, dirReplacements);
91
- logger.success(`packages/${clientName} 생성 완료`);
91
+ logger.success(`packages/${clientName} created successfully`);
92
92
 
93
- // 5. sd.config.ts 업데이트
93
+ // 5. Update sd.config.ts
94
94
  const sdConfigPath = path.join(cwd, "sd.config.ts");
95
95
  const added = addPackageToSdConfig(sdConfigPath, clientName, { target: "client" });
96
96
  if (added) {
97
- logger.success("sd.config.ts 업데이트 완료");
97
+ logger.success("sd.config.ts updated successfully");
98
98
  } else {
99
- consola.warn(`"${clientName}"이(가) sd.config.ts에 이미 존재합니다.`);
99
+ consola.warn(`"${clientName}" already exists in sd.config.ts.`);
100
100
  }
101
101
 
102
- // 6. eslint.config.ts tailwind 설정 추가 ( 클라이언트인 경우)
102
+ // 6. Add tailwind configuration to eslint.config.ts (if first client)
103
103
  const eslintConfigPath = path.join(cwd, "eslint.config.ts");
104
104
  if (fs.existsSync(eslintConfigPath)) {
105
105
  const tailwindAdded = addTailwindToEslintConfig(eslintConfigPath, clientName);
106
106
  if (tailwindAdded) {
107
- logger.success("eslint.config.ts에 tailwind 설정 추가");
107
+ logger.success("Added tailwind configuration to eslint.config.ts");
108
108
  }
109
109
  }
110
110
 
111
111
  // 7. pnpm install
112
- logger.info("pnpm install 실행 중...");
112
+ logger.info("Running pnpm install...");
113
113
  await execa("pnpm", ["install"], { cwd });
114
- logger.success("pnpm install 완료");
114
+ logger.success("pnpm install completed");
115
115
 
116
- // 완료
116
+ // Done
117
117
  consola.box(
118
118
  [
119
- `클라이언트 "${clientName}"이(가) 추가되었습니다!`,
119
+ `Client "${clientName}" has been added!`,
120
120
  "",
121
- ` pnpm dev ${clientName} 개발 서버 실행`,
121
+ ` pnpm dev ${clientName} Run development server`,
122
122
  ].join("\n"),
123
123
  );
124
124
  }
@@ -10,7 +10,7 @@ import { findPackageRoot } from "../utils/package-utils";
10
10
  //#region Types
11
11
 
12
12
  /**
13
- * Add-server 명령 옵션
13
+ * Add-server command options
14
14
  */
15
15
  export interface AddServerOptions {}
16
16
 
@@ -19,13 +19,13 @@ export interface AddServerOptions {}
19
19
  //#region Utilities
20
20
 
21
21
  /**
22
- * sd.config.ts 읽어서 target "client"인 패키지명 목록을 반환한다.
22
+ * Reads sd.config.ts and returns a list of package names with target "client".
23
23
  */
24
24
  function findClientPackages(sdConfigPath: string): string[] {
25
25
  const content = fs.readFileSync(sdConfigPath, "utf-8");
26
26
  const clients: string[] = [];
27
27
 
28
- // 간단한 패턴 매칭으로 client 패키지 찾기
28
+ // Find client packages using simple pattern matching
29
29
  const regex = /"([^"]+)":\s*\{[^}]*target:\s*"client"/g;
30
30
  let match: RegExpExecArray | null;
31
31
  while ((match = regex.exec(content)) != null) {
@@ -39,62 +39,62 @@ function findClientPackages(sdConfigPath: string): string[] {
39
39
  //#region Main
40
40
 
41
41
  /**
42
- * 서버 패키지를 프로젝트에 추가한다.
42
+ * Adds a server package to the project.
43
43
  *
44
- * 1. 프로젝트 루트 확인
45
- * 2. 대화형 프롬프트 (이름 접미사, 클라이언트 선택)
46
- * 3. 패키지 디렉토리 중복 확인
47
- * 4. Handlebars 템플릿 렌더링
48
- * 5. sd.config.ts에 서버 패키지 항목 추가
49
- * 6. 선택된 클라이언트의 server 필드 업데이트
50
- * 7. pnpm install
44
+ * 1. Verify project root
45
+ * 2. Interactive prompts (name suffix, client selection)
46
+ * 3. Check for duplicate package directory
47
+ * 4. Render Handlebars template
48
+ * 5. Add server package entry to sd.config.ts
49
+ * 6. Update server field in selected clients
50
+ * 7. Run pnpm install
51
51
  */
52
52
  export async function runAddServer(_options: AddServerOptions): Promise<void> {
53
53
  const cwd = process.cwd();
54
54
  const logger = consola.withTag("sd:cli:add-server");
55
55
 
56
- // 1. 프로젝트 루트 확인
56
+ // 1. Verify project root
57
57
  const sdConfigPath = path.join(cwd, "sd.config.ts");
58
58
  if (!fs.existsSync(sdConfigPath)) {
59
- consola.error("sd.config.ts 찾을 없습니다. 프로젝트 루트에서 실행해주세요.");
59
+ consola.error("Cannot find sd.config.ts. Please run this from the project root.");
60
60
  process.exitCode = 1;
61
61
  return;
62
62
  }
63
63
 
64
64
  const projectName = path.basename(cwd);
65
65
 
66
- // 2. 대화형 프롬프트
66
+ // 2. Interactive prompts
67
67
  const serverSuffix = await input({
68
- message: '서버 이름 접미사 (비워두면 "server"):',
68
+ message: 'Server name suffix (leave empty for "server"):',
69
69
  validate: (value) => {
70
- if (value.trim() === "") return true; // 허용
71
- if (!/^[a-z][a-z0-9-]*$/.test(value)) return "소문자, 숫자, 하이픈만 사용 가능합니다.";
70
+ if (value.trim() === "") return true; // Allow empty value
71
+ if (!/^[a-z][a-z0-9-]*$/.test(value)) return "Only lowercase letters, numbers, and hyphens are allowed.";
72
72
  return true;
73
73
  },
74
74
  });
75
75
 
76
76
  const serverName = serverSuffix.trim() === "" ? "server" : `server-${serverSuffix}`;
77
77
 
78
- // 클라이언트 선택 (기존 클라이언트가 있는 경우)
78
+ // Client selection (if existing clients are present)
79
79
  const clientPackages = findClientPackages(sdConfigPath);
80
80
  let selectedClients: string[] = [];
81
81
 
82
82
  if (clientPackages.length > 0) {
83
83
  selectedClients = await checkbox({
84
- message: " 서버가 서비스할 클라이언트를 선택하세요:",
84
+ message: "Select the clients this server will serve:",
85
85
  choices: clientPackages.map((name) => ({ name, value: name })),
86
86
  });
87
87
  }
88
88
 
89
- // 3. 패키지 디렉토리 중복 확인
89
+ // 3. Check for duplicate package directory
90
90
  const packageDir = path.join(cwd, "packages", serverName);
91
91
  if (fs.existsSync(packageDir)) {
92
- consola.error(`packages/${serverName} 디렉토리가 이미 존재합니다.`);
92
+ consola.error(`packages/${serverName} directory already exists.`);
93
93
  process.exitCode = 1;
94
94
  return;
95
95
  }
96
96
 
97
- // 4. 템플릿 렌더링
97
+ // 4. Render template
98
98
  const pkgRoot = findPackageRoot(import.meta.dirname);
99
99
  const templateDir = path.join(pkgRoot, "templates", "add-server");
100
100
 
@@ -108,31 +108,31 @@ export async function runAddServer(_options: AddServerOptions): Promise<void> {
108
108
  __SERVER__: serverName,
109
109
  };
110
110
 
111
- logger.info(`${serverName} 패키지 생성 중...`);
111
+ logger.info(`Creating ${serverName} package...`);
112
112
  await renderTemplateDir(templateDir, path.join(cwd, "packages"), context, dirReplacements);
113
- logger.success(`packages/${serverName} 생성 완료`);
113
+ logger.success(`packages/${serverName} created successfully`);
114
114
 
115
- // 5. sd.config.ts에 서버 패키지 추가
115
+ // 5. Add server package to sd.config.ts
116
116
  const added = addPackageToSdConfig(sdConfigPath, serverName, { target: "server" });
117
117
  if (added) {
118
- logger.success("sd.config.ts에 서버 패키지 추가 완료");
118
+ logger.success("Server package added to sd.config.ts");
119
119
  } else {
120
- consola.warn(`"${serverName}"이(가) sd.config.ts에 이미 존재합니다.`);
120
+ consola.warn(`"${serverName}" already exists in sd.config.ts.`);
121
121
  }
122
122
 
123
- // 6. 선택된 클라이언트의 server 필드 업데이트
123
+ // 6. Update server field in selected clients
124
124
  for (const clientName of selectedClients) {
125
125
  setClientServerInSdConfig(sdConfigPath, clientName, serverName);
126
- logger.info(`${clientName} 서버를 "${serverName}"으로 설정`);
126
+ logger.info(`Set ${clientName} server to "${serverName}"`);
127
127
  }
128
128
 
129
- // 7. pnpm install
130
- logger.info("pnpm install 실행 중...");
129
+ // 7. Run pnpm install
130
+ logger.info("Running pnpm install...");
131
131
  await execa("pnpm", ["install"], { cwd });
132
- logger.success("pnpm install 완료");
132
+ logger.success("pnpm install completed");
133
133
 
134
- // 완료
135
- consola.box(`서버 "${serverName}"이(가) 추가되었습니다!`);
134
+ // Done
135
+ consola.box(`Server "${serverName}" has been added!`);
136
136
  }
137
137
 
138
138
  //#endregion
@@ -4,17 +4,17 @@ import {
4
4
  } from "../orchestrators/BuildOrchestrator";
5
5
 
6
6
  /**
7
- * 프로덕션 빌드를 실행한다.
7
+ * Run production build.
8
8
  *
9
- * - `sd.config.ts`를 로드하여 패키지별 빌드 타겟 정보 확인 (필수)
10
- * - lint 실행
11
- * - dist 폴더 정리 (clean build)
12
- * - `node`/`browser`/`neutral` 타겟: esbuild JS 빌드 + dts 생성 (타입체크 포함)
13
- * - `client` 타겟: Vite production 빌드 + typecheck (dts 불필요)
14
- * - 하나라도 실패하면 `process.exitCode = 1` 설정
9
+ * - Load `sd.config.ts` to check build target info per package (required)
10
+ * - Run lint
11
+ * - Clean dist folder (clean build)
12
+ * - `node`/`browser`/`neutral` target: esbuild JS build + dts generation (with type check)
13
+ * - `client` target: Vite production build + typecheck (dts not needed)
14
+ * - Set `process.exitCode = 1` if any step fails
15
15
  *
16
- * @param options - build 실행 옵션
17
- * @returns 완료 resolve
16
+ * @param options - build execution options
17
+ * @returns resolves on completion
18
18
  */
19
19
  export async function runBuild(options: BuildOrchestratorOptions): Promise<void> {
20
20
  const orchestrator = new BuildOrchestrator(options);
@@ -83,7 +83,7 @@ export async function runCheck(options: CheckOptions): Promise<void> {
83
83
  const { targets, types } = options;
84
84
  const logger = consola.withTag("sd:cli:check");
85
85
 
86
- logger.debug("check 시작", { targets, types });
86
+ logger.debug("start check", { targets, types });
87
87
 
88
88
  const tasks: Promise<CheckResult>[] = [];
89
89
 
@@ -129,11 +129,11 @@ export async function runCheck(options: CheckOptions): Promise<void> {
129
129
  tasks.push(spawnVitest(targets));
130
130
  }
131
131
 
132
- logger.start(`check 실행 중... (${types.join(", ")})`);
132
+ logger.start(`running check... (${types.join(", ")})`);
133
133
  const results = await Promise.allSettled(tasks);
134
- logger.success("check 실행 완료");
134
+ logger.success("check completed");
135
135
 
136
- // 결과 수집
136
+ // Collect results
137
137
  const checkResults: CheckResult[] = results.map((r) => {
138
138
  if (r.status === "fulfilled") return r.value;
139
139
  return {
@@ -145,7 +145,7 @@ export async function runCheck(options: CheckOptions): Promise<void> {
145
145
  };
146
146
  });
147
147
 
148
- // 섹션별 출력 (typecheck → lint → test 순서 보장)
148
+ // Output by section (guarantee order: typecheck → lint → test)
149
149
  const order = ["TYPECHECK", "LINT", "TEST"];
150
150
  checkResults.sort((a, b) => order.indexOf(a.name) - order.indexOf(b.name));
151
151
 
@@ -1,17 +1,17 @@
1
1
  import { DevOrchestrator, type DevOrchestratorOptions } from "../orchestrators/DevOrchestrator";
2
2
 
3
3
  /**
4
- * Client Server 패키지를 개발 모드로 실행한다.
4
+ * Run Client and Server packages in development mode.
5
5
  *
6
- * - `sd.config.ts`를 로드하여 패키지별 빌드 타겟 정보 확인 (필수)
7
- * - `client` 타겟: Vite dev server 시작
8
- * - `server` 타겟: Server Build Worker + Server Runtime Worker
9
- * - Server-Client 프록시 연결 지원
10
- * - Capacitor 초기화 지원
11
- * - SIGINT/SIGTERM 시그널로 종료
6
+ * - Load `sd.config.ts` to check build target info per package (required)
7
+ * - `client` target: Start Vite dev server
8
+ * - `server` target: Server Build Worker + Server Runtime Worker
9
+ * - Support Server-Client proxy connections
10
+ * - Support Capacitor initialization
11
+ * - Terminate with SIGINT/SIGTERM signals
12
12
  *
13
- * @param options - dev 실행 옵션
14
- * @returns 종료 시그널 수신 시 resolve
13
+ * @param options - dev execution options
14
+ * @returns resolves on termination signal
15
15
  */
16
16
  export async function runDev(options: DevOrchestratorOptions): Promise<void> {
17
17
  const orchestrator = new DevOrchestrator(options);
@@ -9,14 +9,14 @@ import { Electron } from "../electron/electron";
9
9
  //#region Types
10
10
 
11
11
  /**
12
- * Device 명령 옵션
12
+ * Device command options
13
13
  */
14
14
  export interface DeviceOptions {
15
- /** 패키지 이름 (필수) */
15
+ /** Package name (required) */
16
16
  package: string;
17
- /** 개발 서버 URL (선택, 미지정 sd.config.ts server 설정 사용) */
17
+ /** Development server URL (optional, uses server config from sd.config.ts if not specified) */
18
18
  url?: string;
19
- /** sd.config.ts 전달할 추가 옵션 */
19
+ /** Additional options to pass to sd.config.ts */
20
20
  options: string[];
21
21
  }
22
22
 
@@ -25,42 +25,42 @@ export interface DeviceOptions {
25
25
  //#region Main
26
26
 
27
27
  /**
28
- * Android 디바이스에서 앱을 실행한다.
28
+ * Runs an app on an Android device.
29
29
  *
30
- * - 연결된 Android 디바이스에서 실행
31
- * - 개발 서버 URL WebView 연결하여 Hot Reload 지원
30
+ * - Runs app on connected Android device
31
+ * - Connects development server URL to WebView to support Hot Reload
32
32
  *
33
- * @param options - device 실행 옵션
34
- * @returns 완료 resolve
33
+ * @param options - device execution options
34
+ * @returns resolves when complete
35
35
  */
36
36
  export async function runDevice(options: DeviceOptions): Promise<void> {
37
37
  const { package: packageName, url } = options;
38
38
  const cwd = process.cwd();
39
39
  const logger = consola.withTag("sd:cli:device");
40
40
 
41
- logger.debug("device 시작", { package: packageName, url });
41
+ logger.debug("device start", { package: packageName, url });
42
42
 
43
- // sd.config.ts 로드
43
+ // Load sd.config.ts
44
44
  let sdConfig: SdConfig;
45
45
  try {
46
46
  sdConfig = await loadSdConfig({ cwd, dev: true, opt: options.options });
47
- logger.debug("sd.config.ts 로드 완료");
47
+ logger.debug("sd.config.ts loaded");
48
48
  } catch (err) {
49
- logger.error(`sd.config.ts 로드 실패: ${err instanceof Error ? err.message : err}`);
49
+ logger.error(`Failed to load sd.config.ts: ${err instanceof Error ? err.message : err}`);
50
50
  process.exitCode = 1;
51
51
  return;
52
52
  }
53
53
 
54
- // 패키지 설정 확인
54
+ // Verify package config
55
55
  const pkgConfig = sdConfig.packages[packageName];
56
56
  if (pkgConfig == null) {
57
- logger.error(`패키지를 찾을 없습니다: ${packageName}`);
57
+ logger.error(`Package not found: ${packageName}`);
58
58
  process.exitCode = 1;
59
59
  return;
60
60
  }
61
61
 
62
62
  if (pkgConfig.target !== "client") {
63
- logger.error(`client 타겟 패키지만 지원합니다: ${packageName} (현재: ${pkgConfig.target})`);
63
+ logger.error(`Only client target packages are supported: ${packageName} (current: ${pkgConfig.target})`);
64
64
  process.exitCode = 1;
65
65
  return;
66
66
  }
@@ -69,40 +69,40 @@ export async function runDevice(options: DeviceOptions): Promise<void> {
69
69
  const pkgDir = path.join(cwd, "packages", packageName);
70
70
 
71
71
  if (clientConfig.electron != null) {
72
- // Electron 개발 실행
72
+ // Run Electron development
73
73
  let serverUrl = url;
74
74
  if (serverUrl == null) {
75
75
  if (typeof clientConfig.server === "number") {
76
76
  serverUrl = `http://localhost:${clientConfig.server}/${packageName}/`;
77
77
  } else {
78
78
  logger.error(
79
- `--url 옵션이 필요합니다. server 패키지명으로 설정되어 있습니다: ${clientConfig.server}`,
79
+ `--url option is required. server is set to package name: ${clientConfig.server}`,
80
80
  );
81
81
  process.exitCode = 1;
82
82
  return;
83
83
  }
84
84
  }
85
85
 
86
- logger.debug("개발 서버 URL", { serverUrl });
86
+ logger.debug("development server URL", { serverUrl });
87
87
 
88
- logger.start(`${packageName} (electron) 실행 중...`);
88
+ logger.start(`Running ${packageName} (electron)...`);
89
89
  try {
90
90
  const electron = await Electron.create(pkgDir, clientConfig.electron);
91
91
  await electron.run(serverUrl);
92
- logger.success("Electron 실행 완료");
92
+ logger.success("Electron execution completed");
93
93
  } catch (err) {
94
- logger.error(`Electron 실행 실패: ${err instanceof Error ? err.message : err}`);
94
+ logger.error(`Failed to run Electron: ${err instanceof Error ? err.message : err}`);
95
95
  process.exitCode = 1;
96
96
  }
97
97
  } else if (clientConfig.capacitor != null) {
98
- // Capacitor 디바이스 실행 (기존 로직)
98
+ // Run Capacitor device (existing logic)
99
99
  let serverUrl = url;
100
100
  if (serverUrl == null) {
101
101
  if (typeof clientConfig.server === "number") {
102
102
  serverUrl = `http://localhost:${clientConfig.server}/${packageName}/capacitor/`;
103
103
  } else {
104
104
  logger.error(
105
- `--url 옵션이 필요합니다. server 패키지명으로 설정되어 있습니다: ${clientConfig.server}`,
105
+ `--url option is required. server is set to package name: ${clientConfig.server}`,
106
106
  );
107
107
  process.exitCode = 1;
108
108
  return;
@@ -111,28 +111,28 @@ export async function runDevice(options: DeviceOptions): Promise<void> {
111
111
  serverUrl = `${serverUrl}/${packageName}/capacitor/`;
112
112
  }
113
113
 
114
- logger.debug("개발 서버 URL", { serverUrl });
114
+ logger.debug("development server URL", { serverUrl });
115
115
 
116
116
  const capPath = path.join(pkgDir, ".capacitor");
117
117
  if (!(await fsExists(capPath))) {
118
118
  logger.error(
119
- `Capacitor 프로젝트가 초기화되지 않았습니다. 먼저 'pnpm watch ${packageName}'를 실행하세요.`,
119
+ `Capacitor project is not initialized. First run 'pnpm watch ${packageName}'.`,
120
120
  );
121
121
  process.exitCode = 1;
122
122
  return;
123
123
  }
124
124
 
125
- logger.start(`${packageName} (device) 실행 중...`);
125
+ logger.start(`Running ${packageName} (device)...`);
126
126
  try {
127
127
  const cap = await Capacitor.create(pkgDir, clientConfig.capacitor);
128
128
  await cap.runOnDevice(serverUrl);
129
- logger.success("디바이스 실행 완료");
129
+ logger.success("Device execution completed");
130
130
  } catch (err) {
131
- logger.error(`디바이스 실행 실패: ${err instanceof Error ? err.message : err}`);
131
+ logger.error(`Failed to run device: ${err instanceof Error ? err.message : err}`);
132
132
  process.exitCode = 1;
133
133
  }
134
134
  } else {
135
- logger.error(`electron 또는 capacitor 설정이 없습니다: ${packageName}`);
135
+ logger.error(`No electron or capacitor config found: ${packageName}`);
136
136
  process.exitCode = 1;
137
137
  }
138
138
  }
@@ -8,7 +8,7 @@ import { findPackageRoot } from "../utils/package-utils";
8
8
  //#region Types
9
9
 
10
10
  /**
11
- * Init 명령 옵션
11
+ * Init command options
12
12
  */
13
13
  export interface InitOptions {}
14
14
 
@@ -17,7 +17,7 @@ export interface InitOptions {}
17
17
  //#region Utilities
18
18
 
19
19
  /**
20
- * npm 스코프 이름 유효성 검증
20
+ * Validates npm scope name validity
21
21
  */
22
22
  function isValidScopeName(name: string): boolean {
23
23
  return /^[a-z][a-z0-9-]*$/.test(name);
@@ -28,65 +28,65 @@ function isValidScopeName(name: string): boolean {
28
28
  //#region Main
29
29
 
30
30
  /**
31
- * Simplysm 프로젝트를 현재 디렉토리에 초기화한다.
31
+ * Initializes a new Simplysm project in the current directory.
32
32
  *
33
- * 1. 디렉토리 비어있는지 확인
34
- * 2. 프로젝트명(폴더명) 검증
35
- * 3. Handlebars 템플릿 렌더링
36
- * 4. pnpm install 실행
33
+ * 1. Check if directory is empty
34
+ * 2. Validate project name (folder name)
35
+ * 3. Render Handlebars template
36
+ * 4. Run pnpm install
37
37
  */
38
38
  export async function runInit(_options: InitOptions): Promise<void> {
39
39
  const cwd = process.cwd();
40
40
  const logger = consola.withTag("sd:cli:init");
41
41
 
42
- // 1. 디렉토리 비어있는지 확인 (dotfile/dotfolder 제외)
42
+ // 1. Check if directory is empty (exclude dotfiles/dotfolders)
43
43
  const entries = fs.readdirSync(cwd).filter((e) => !e.startsWith("."));
44
44
  if (entries.length > 0) {
45
- consola.error("디렉토리가 비어있지 않습니다. 디렉토리에서 실행해주세요.");
45
+ consola.error("Directory is not empty. Please run this from an empty directory.");
46
46
  process.exitCode = 1;
47
47
  return;
48
48
  }
49
49
 
50
- // 2. 프로젝트명 검증
50
+ // 2. Validate project name
51
51
  const projectName = path.basename(cwd);
52
52
  if (!isValidScopeName(projectName)) {
53
53
  consola.error(
54
- `프로젝트 이름 "${projectName}"이(가) 유효하지 않습니다. 소문자, 숫자, 하이픈만 사용 가능합니다.`,
54
+ `Project name "${projectName}" is not valid. Only lowercase letters, numbers, and hyphens are allowed.`,
55
55
  );
56
56
  process.exitCode = 1;
57
57
  return;
58
58
  }
59
59
 
60
- // 3. 템플릿 렌더링
60
+ // 3. Render template
61
61
  const pkgRoot = findPackageRoot(import.meta.dirname);
62
62
  const templateDir = path.join(pkgRoot, "templates", "init");
63
63
 
64
64
  const context = { projectName };
65
65
 
66
- logger.info("프로젝트 파일 생성 중...");
66
+ logger.info("Creating project files...");
67
67
  await renderTemplateDir(templateDir, cwd, context);
68
- logger.success("프로젝트 파일 생성 완료");
68
+ logger.success("Project files created successfully");
69
69
 
70
- // 4. pnpm install
71
- logger.info("pnpm install 실행 중...");
70
+ // 4. Run pnpm install
71
+ logger.info("Running pnpm install...");
72
72
  await execa("pnpm", ["install"], { cwd });
73
- logger.success("pnpm install 완료");
73
+ logger.success("pnpm install completed");
74
74
 
75
- // 5. git 초기화
76
- logger.info("git 저장소 초기화 중...");
75
+ // 5. Initialize git repository
76
+ logger.info("Initializing git repository...");
77
77
  await execa("git", ["init"], { cwd });
78
78
  await execa("git", ["add", "."], { cwd });
79
79
  await execa("git", ["commit", "-m", "init"], { cwd });
80
- logger.success("git 저장소 초기화 완료");
80
+ logger.success("git repository initialized");
81
81
 
82
- // 6. 완료 메시지
82
+ // 6. Completion message
83
83
  consola.box(
84
84
  [
85
- "프로젝트가 생성되었습니다!",
85
+ "Project created!",
86
86
  "",
87
- "다음 단계:",
88
- " sd-cli add client 클라이언트 패키지 추가",
89
- " sd-cli add server 서버 패키지 추가",
87
+ "Next steps:",
88
+ " sd-cli add client Add a client package",
89
+ " sd-cli add server Add a server package",
90
90
  ].join("\n"),
91
91
  );
92
92
  }