@simplysm/sd-cli 14.0.48 → 14.0.51

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 (133) hide show
  1. package/README.md +22 -679
  2. package/dist/engines/EsbuildClientEngine.d.ts.map +1 -1
  3. package/dist/engines/EsbuildClientEngine.js +1 -2
  4. package/dist/engines/EsbuildClientEngine.js.map +1 -1
  5. package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -1
  6. package/dist/lint/lint-core.js.map +1 -1
  7. package/dist/orchestrators/DevOrchestrator.js.map +1 -1
  8. package/dist/orchestrators/ServerRuntimeManager.d.ts.map +1 -1
  9. package/dist/orchestrators/ServerRuntimeManager.js +2 -4
  10. package/dist/orchestrators/ServerRuntimeManager.js.map +1 -1
  11. package/dist/ts-compiler/SdTsCompiler.d.ts +1 -7
  12. package/dist/ts-compiler/SdTsCompiler.d.ts.map +1 -1
  13. package/dist/ts-compiler/SdTsCompiler.js +109 -116
  14. package/dist/ts-compiler/SdTsCompiler.js.map +1 -1
  15. package/dist/utils/package-utils.d.ts.map +1 -1
  16. package/dist/utils/package-utils.js.map +1 -1
  17. package/docs/angular-vite-plugin/sd-angular-plugin.md +54 -0
  18. package/docs/config/build-target.md +31 -0
  19. package/docs/config/npm-config.md +27 -0
  20. package/docs/config/sd-browser-support-config.md +19 -0
  21. package/docs/config/sd-build-package-config.md +21 -0
  22. package/docs/config/sd-capacitor-config.md +109 -0
  23. package/docs/config/sd-client-package-config.md +33 -0
  24. package/docs/config/sd-config.md +73 -0
  25. package/docs/config/sd-electron-config.md +27 -0
  26. package/docs/config/sd-package-config.md +18 -0
  27. package/docs/config/sd-post-publish-script-config.md +19 -0
  28. package/docs/config/sd-publish-config.md +72 -0
  29. package/docs/config/sd-pwa-config.md +41 -0
  30. package/docs/config/sd-scripts-package-config.md +19 -0
  31. package/docs/config/sd-server-package-config.md +32 -0
  32. package/docs/config/sd-watch-hook-config.md +19 -0
  33. package/docs/ts-compiler/sd-ts-compiler.md +152 -0
  34. package/package.json +7 -6
  35. package/src/engines/EsbuildClientEngine.ts +1 -2
  36. package/src/esbuild/esbuild-angular-compiler-plugin.ts +1 -1
  37. package/src/lint/lint-core.ts +1 -1
  38. package/src/orchestrators/DevOrchestrator.ts +3 -3
  39. package/src/orchestrators/ServerRuntimeManager.ts +2 -5
  40. package/src/ts-compiler/SdTsCompiler.ts +136 -154
  41. package/src/utils/package-utils.ts +1 -2
  42. package/tests/angular/angular-compiler-hmr-removal.verify.md +12 -12
  43. package/tests/angular/onbuild-lint-removal.verify.md +4 -4
  44. package/tests/angular/vite-angular-plugin-sdtscompiler.verify.md +9 -9
  45. package/tests/angular/vite-angular-plugin-vitest.verify.md +16 -16
  46. package/tests/capacitor/capacitor-android-exports.verify.md +7 -7
  47. package/tests/commands/publish-npm-local-split.verify.md +5 -5
  48. package/tests/commands/publish-responsibility-split.verify.md +9 -9
  49. package/tests/commands/publish-set.verify.md +3 -3
  50. package/tests/commands/publish-storage-split.verify.md +4 -4
  51. package/tests/commands/slice3-severity-cleanup.verify.md +8 -8
  52. package/tests/deps/deps-directory-separation.verify.md +11 -11
  53. package/tests/deps/replace-deps/replace-deps-perf.verify.md +6 -6
  54. package/tests/deps/server-externals/mise-toml-parse-intent.verify.md +8 -8
  55. package/tests/electron/electron-symlink-cleanup.verify.md +4 -4
  56. package/tests/engines/engine-duplicate-output-removal.verify.md +6 -6
  57. package/tests/engines/engine-typecheck-selection.verify.md +4 -4
  58. package/tests/engines/esbuild-client-engine.verify.md +11 -11
  59. package/tests/engines/normalize-result.verify.md +5 -5
  60. package/tests/engines/vite-dependency-cleanup.verify.md +11 -11
  61. package/tests/esbuild/esbuild-angular-compiler-plugin-hmr.verify.md +10 -10
  62. package/tests/esbuild/esbuild-angular-compiler-plugin-onload.verify.md +17 -17
  63. package/tests/esbuild/esbuild-angular-compiler-plugin-onstart-extraction.verify.md +12 -12
  64. package/tests/esbuild/esbuild-angular-compiler-plugin-sdtscompiler.verify.md +11 -11
  65. package/tests/esbuild/esbuild-angular-compiler-plugin-stylesheet.verify.md +13 -13
  66. package/tests/esbuild/esbuild-angular-compiler-plugin-worker.verify.md +32 -32
  67. package/tests/esbuild/esbuild-angular-compiler-plugin.spec.ts +1 -1
  68. package/tests/esbuild/esbuild-angular-compiler-plugin.verify.md +9 -9
  69. package/tests/esbuild/esbuild-postcss-plugin-chunking.verify.md +3 -3
  70. package/tests/esbuild/esbuild-postcss-plugin.acc.spec.ts +1 -1
  71. package/tests/esbuild/esbuild-tsc-plugin-imports.verify.md +9 -9
  72. package/tests/esbuild/esbuild-tsc-plugin.acc.spec.ts +2 -2
  73. package/tests/esbuild/esbuild-tsc-plugin.spec.ts +3 -3
  74. package/tests/esbuild/esbuild-worker-plugin-node.verify.md +7 -7
  75. package/tests/esbuild/esbuild-worker-plugin.spec.ts +1 -1
  76. package/tests/esbuild/esbuild-worker-plugin.verify.md +3 -3
  77. package/tests/orchestrators/build-orchestrator.spec.ts +9 -9
  78. package/tests/orchestrators/dev-orchestrator.spec.ts +4 -4
  79. package/tests/orchestrators/dist-delete-watcher.verify.md +6 -6
  80. package/tests/orchestrators/orchestrator-baseenv.verify.md +6 -6
  81. package/tests/orchestrators/orchestrator-diagnostic-formatting.verify.md +6 -6
  82. package/tests/orchestrators/orchestrator-initializemode-signature.verify.md +5 -5
  83. package/tests/orchestrators/slice1-stdout-to-consola.verify.md +6 -6
  84. package/tests/orchestrators/watch-orchestrator.spec.ts +2 -2
  85. package/tests/sd-cli-catch-all.verify.md +3 -3
  86. package/tests/sd-cli-log-tag.verify.md +7 -7
  87. package/tests/ts-compiler/SdTsCompiler-affected-files.verify.md +4 -4
  88. package/tests/ts-compiler/SdTsCompiler-crash-handling.verify.md +24 -0
  89. package/tests/ts-compiler/SdTsCompiler-diagnostics.verify.md +8 -8
  90. package/tests/ts-compiler/SdTsCompiler-emit.verify.md +5 -5
  91. package/tests/ts-compiler/SdTsCompiler.verify.md +20 -20
  92. package/tests/ts-compiler/scss-lint-integration.verify.md +10 -10
  93. package/tests/utils/copy-public-outdir.verify.md +4 -4
  94. package/tests/utils/copy-src.spec.ts +5 -5
  95. package/tests/utils/dev-http-server.verify.md +4 -4
  96. package/tests/utils/engine-watch-events.verify.md +8 -8
  97. package/tests/utils/esbuild-client-config-integration.verify.md +5 -5
  98. package/tests/utils/esbuild-client-config-postcss.verify.md +2 -2
  99. package/tests/utils/esbuild-client-config.acc.spec.ts +1 -1
  100. package/tests/utils/esbuild-client-config.spec.ts +4 -4
  101. package/tests/utils/esbuild-client-config.verify.md +16 -16
  102. package/tests/utils/esbuild-config.spec.ts +3 -3
  103. package/tests/utils/esbuild-index-html.verify.md +6 -6
  104. package/tests/utils/esbuild-postcss-plugin.spec.ts +1 -1
  105. package/tests/utils/esbuild-pwa.verify.md +5 -5
  106. package/tests/utils/esbuild-scss-plugin.verify.md +4 -4
  107. package/tests/utils/hmr-client-script.acc.spec.ts +1 -1
  108. package/tests/utils/hmr-service.verify.md +10 -10
  109. package/tests/utils/lint-core-import-paths.verify.md +6 -6
  110. package/tests/utils/ngtsc-build-core.spec.ts +1 -1
  111. package/tests/utils/package-utils.spec.ts +6 -6
  112. package/tests/utils/replace-deps-split.verify.md +11 -11
  113. package/tests/utils/replace-deps-watch.verify.md +5 -5
  114. package/tests/utils/server-production-files-import-paths.verify.md +10 -10
  115. package/tests/utils/vite-config-cleanup.verify.md +3 -3
  116. package/tests/workers/build-watch-paths-library.verify.md +6 -6
  117. package/tests/workers/build-watch-paths-ngtsc-server.verify.md +8 -8
  118. package/tests/workers/client-worker-browser-support.verify.md +3 -3
  119. package/tests/workers/client-worker-cleanup.verify.md +4 -4
  120. package/tests/workers/client-worker-initial-build-error.verify.md +3 -3
  121. package/tests/workers/client-worker-initial-build-warnings.verify.md +3 -3
  122. package/tests/workers/client-worker-mtime-incremental.verify.md +6 -6
  123. package/tests/workers/client-worker-onend-sync.verify.md +3 -3
  124. package/tests/workers/client-worker-refactor.verify.md +18 -18
  125. package/tests/workers/client-worker-ts-cache-invalidation.verify.md +8 -8
  126. package/tests/workers/dev-port-file.verify.md +3 -3
  127. package/tests/workers/ngtsc-build-rootnames-refresh.verify.md +4 -4
  128. package/tests/workers/server-build-context-dispose.verify.md +4 -4
  129. package/tests/workers/server-build-worker-plugin.verify.md +5 -5
  130. package/tests/workers/server-build-worker-refactoring.verify.md +10 -10
  131. package/tests/workers/server-build-worker.spec.ts +1 -1
  132. package/tests/workers/server-esbuild-context-integration.verify.md +6 -6
  133. package/tests/workers/server-esbuild-context-tsc.verify.md +3 -3
@@ -2,6 +2,7 @@ import path from "path";
2
2
  import { createHash } from "crypto";
3
3
  import ts from "typescript";
4
4
  import { consola, type ConsolaInstance } from "consola";
5
+ import { SdError } from "@simplysm/core-common";
5
6
  import { pathx } from "@simplysm/core-node";
6
7
  import type { ISdTsCompilerOptions, ISdTsCompilerEmitOptions } from "./sd-ts-compiler-options";
7
8
  import type { ISdTsCompilerResult } from "./sd-ts-compiler-result";
@@ -104,6 +105,21 @@ export class SdTsCompiler {
104
105
  return ctx.stage;
105
106
  }
106
107
 
108
+ private _createCrashDiagnostic(e: unknown): SerializedDiagnostic {
109
+ const contextLabel = this._formatCrashContext();
110
+ const sdError =
111
+ e instanceof Error
112
+ ? new SdError(e, `TsCompiler 내부 크래시 @${contextLabel}`)
113
+ : new SdError(`TsCompiler 내부 크래시 @${contextLabel}`, String(e));
114
+ const message = sdError.stack ?? sdError.message;
115
+ this._logger.debug(message);
116
+ return {
117
+ category: ts.DiagnosticCategory.Error,
118
+ code: 0,
119
+ messageText: message,
120
+ };
121
+ }
122
+
107
123
  private _getScssLoadPaths(): string[] {
108
124
  const { pkgDir, cwd } = this._options;
109
125
  return [path.join(pkgDir, "scss"), path.join(cwd, "node_modules")];
@@ -251,29 +267,40 @@ export class SdTsCompiler {
251
267
  program = builderProgram.getProgram();
252
268
  }
253
269
 
254
- // 9. 위험 구간 (체커 진입TsCompiler 내부 크래시 단일 catch)
270
+ // 9. 위험 구간 (단계별 catch부분 복구)
271
+ const crashDiagnostics: SerializedDiagnostic[] = [];
272
+
255
273
  try {
274
+ // 9-0. analyzeAsync (Angular only)
256
275
  if (isForAngular) {
257
- this._setCrashContext("analyzeAsync");
258
- this._logger.debug(`[${pkgName}] AOT analyzeAsync 시작`);
259
- await angularProgram!.compiler.analyzeAsync();
260
- this._logger.debug(`[${pkgName}] AOT analyzeAsync 완료`);
261
- this._ngtscProgram = angularProgram;
276
+ try {
277
+ this._setCrashContext("analyzeAsync");
278
+ this._logger.debug(`[${pkgName}] AOT analyzeAsync 시작`);
279
+ await angularProgram!.compiler.analyzeAsync();
280
+ this._logger.debug(`[${pkgName}] AOT analyzeAsync 완료`);
281
+ this._ngtscProgram = angularProgram;
282
+ } catch (e) {
283
+ crashDiagnostics.push(this._createCrashDiagnostic(e));
284
+ }
262
285
  }
263
286
 
264
287
  // 9-1. affected files 추적
265
- this._setCrashContext("findAffectedFiles");
266
288
  let affectedFiles: ReadonlySet<string> | undefined;
267
- if (isForAngular) {
268
- const result = this._findAffectedFilesForAngular(
269
- builderProgram,
270
- this._ngtscProgram!.compiler,
271
- this._sourceFileCache,
272
- );
273
- this._affectedSourceFiles = result.affectedSourceFiles;
274
- affectedFiles = result.affectedPaths;
275
- } else {
276
- affectedFiles = this._findAffectedFilesForTsc(builderProgram);
289
+ try {
290
+ this._setCrashContext("findAffectedFiles");
291
+ if (isForAngular && this._ngtscProgram != null) {
292
+ const result = this._findAffectedFilesForAngular(
293
+ builderProgram,
294
+ this._ngtscProgram.compiler,
295
+ this._sourceFileCache,
296
+ );
297
+ this._affectedSourceFiles = result.affectedSourceFiles;
298
+ affectedFiles = result.affectedPaths;
299
+ } else if (!isForAngular) {
300
+ affectedFiles = this._findAffectedFilesForTsc(builderProgram);
301
+ }
302
+ } catch (e) {
303
+ crashDiagnostics.push(this._createCrashDiagnostic(e));
277
304
  }
278
305
 
279
306
  if (affectedFiles != null) {
@@ -289,51 +316,83 @@ export class SdTsCompiler {
289
316
  }
290
317
 
291
318
  // 9-2. emit 처리
292
- this._setCrashContext("emit");
293
319
  let emitResults: EmitResult[] | undefined;
294
- if (isForAngular) {
295
- emitResults = this._emitAngular(
296
- this._ngtscProgram!,
297
- builderProgram,
298
- this._affectedSourceFiles,
299
- emitOptions,
300
- );
301
- } else {
302
- this._emitTsc(builderProgram);
320
+ try {
321
+ this._setCrashContext("emit");
322
+ if (isForAngular && this._ngtscProgram != null) {
323
+ emitResults = this._emitAngular(
324
+ this._ngtscProgram,
325
+ builderProgram,
326
+ this._affectedSourceFiles,
327
+ emitOptions,
328
+ );
329
+ } else if (!isForAngular) {
330
+ this._emitTsc(builderProgram);
331
+ }
332
+ } catch (e) {
333
+ crashDiagnostics.push(this._createCrashDiagnostic(e));
303
334
  }
304
335
 
305
336
  // 9-3. 진단 수집
306
- this._setCrashContext("collectDiagnostics");
307
- const rawDiagnostics = isForAngular
308
- ? this._collectDiagnosticsForAngular(
309
- this._ngtscProgram!,
310
- builderProgram,
311
- this._affectedSourceFiles,
312
- )
313
- : this._collectDiagnosticsForTsc(builderProgram);
314
- const diagResult = this._finalizeDiagnostics(rawDiagnostics);
337
+ let diagResult:
338
+ | {
339
+ diagnostics: SerializedDiagnostic[];
340
+ errorCount: number;
341
+ warningCount: number;
342
+ errors?: string[];
343
+ }
344
+ | undefined;
345
+ try {
346
+ this._setCrashContext("collectDiagnostics");
347
+ const rawDiagnostics =
348
+ isForAngular && this._ngtscProgram != null
349
+ ? this._collectDiagnosticsForAngular(
350
+ this._ngtscProgram,
351
+ builderProgram,
352
+ this._affectedSourceFiles,
353
+ )
354
+ : this._collectDiagnosticsForTsc(builderProgram);
355
+ diagResult = this._finalizeDiagnostics(rawDiagnostics);
356
+ } catch (e) {
357
+ crashDiagnostics.push(this._createCrashDiagnostic(e));
358
+ }
315
359
 
316
360
  // 9-4. 글로벌 SCSS + lint 병렬 실행
317
- this._setCrashContext("lintAndGlobalScss");
318
- const [, lintResult] = await Promise.all([
319
- // globalScss
320
- this._options.globalScss === true
321
- ? Promise.resolve().then(() => {
322
- const loadPaths = this._getScssLoadPaths();
323
- const globalScssErrors = compileGlobalScss(pkgDir, loadPaths);
324
- this._scssErrors.push(...globalScssErrors);
325
- })
326
- : Promise.resolve(),
327
- // lint
328
- this._options.lint === true
329
- ? this._runLint(program, affectedFiles)
330
- : Promise.resolve(undefined),
331
- ]);
361
+ let lintResult: LintWithProgramResult | undefined;
362
+ try {
363
+ this._setCrashContext("lintAndGlobalScss");
364
+ const [, lr] = await Promise.all([
365
+ // globalScss
366
+ this._options.globalScss === true
367
+ ? Promise.resolve().then(() => {
368
+ const loadPaths = this._getScssLoadPaths();
369
+ const globalScssErrors = compileGlobalScss(pkgDir, loadPaths);
370
+ this._scssErrors.push(...globalScssErrors);
371
+ })
372
+ : Promise.resolve(),
373
+ // lint
374
+ this._options.lint === true
375
+ ? this._runLint(program, affectedFiles)
376
+ : Promise.resolve(undefined),
377
+ ]);
378
+ lintResult = lr;
379
+ } catch (e) {
380
+ crashDiagnostics.push(this._createCrashDiagnostic(e));
381
+ }
332
382
 
333
383
  // 9-5. 상태 저장
334
384
  this._builderProgram = builderProgram;
335
385
  this._crashContext = undefined;
336
386
 
387
+ // 결과 조립 (crashDiagnostics 합산)
388
+ const finalDiagnostics = [...(diagResult?.diagnostics ?? []), ...crashDiagnostics];
389
+ const finalErrorCount = (diagResult?.errorCount ?? 0) + crashDiagnostics.length;
390
+ const finalWarningCount = diagResult?.warningCount ?? 0;
391
+ const crashErrors = crashDiagnostics.map((d) =>
392
+ typeof d.messageText === "string" ? d.messageText : "TsCompiler 내부 크래시",
393
+ );
394
+ const finalErrors = [...(diagResult?.errors ?? []), ...crashErrors];
395
+
337
396
  this._logger.debug(`[${pkgName}] compileAsync 완료`);
338
397
 
339
398
  return {
@@ -341,10 +400,10 @@ export class SdTsCompiler {
341
400
  builderProgram,
342
401
  isForAngular,
343
402
  affectedFiles,
344
- diagnostics: diagResult.diagnostics,
345
- errorCount: diagResult.errorCount,
346
- warningCount: diagResult.warningCount,
347
- errors: diagResult.errors,
403
+ diagnostics: finalDiagnostics,
404
+ errorCount: finalErrorCount,
405
+ warningCount: finalWarningCount,
406
+ errors: finalErrors.length > 0 ? finalErrors : undefined,
348
407
  ngtscProgram: this._ngtscProgram,
349
408
  emitResults,
350
409
  lint: lintResult,
@@ -352,35 +411,8 @@ export class SdTsCompiler {
352
411
  scssDependencies: new Map(this._scssDependencies),
353
412
  };
354
413
  } catch (e) {
355
- // TsCompiler 내부 크래시 (TS 5.9 overload 버그 등) — 단일 에러 진단으로 degrade
356
- const contextLabel = this._formatCrashContext();
357
- const rawMsg = e instanceof Error ? (e.stack ?? e.message) : String(e);
358
- this._logger.debug(`[${pkgName}] crash @${contextLabel}: ${rawMsg}`);
359
-
360
- // per-file 프로브: affected 파일 각각을 개별 try-catch로 재체크하여 재현 파일 특정
361
- const probeReport = isForAngular
362
- ? this._probeCrashPerFileAngular(
363
- this._ngtscProgram,
364
- builderProgram,
365
- this._affectedSourceFiles,
366
- )
367
- : this._probeCrashPerFileTsc(builderProgram, this._affectedSourceFiles);
368
-
369
- const parts: string[] = [
370
- `TsCompiler 내부 크래시 @${contextLabel}`,
371
- "",
372
- rawMsg,
373
- ];
374
- if (probeReport.length > 0) {
375
- parts.push("", "크래시 재현 파일 (per-file 프로브):", ...probeReport);
376
- }
377
- const message = parts.join("\n");
378
-
379
- const crashDiag: SerializedDiagnostic = {
380
- category: ts.DiagnosticCategory.Error,
381
- code: 0,
382
- messageText: message,
383
- };
414
+ // 최종 안전망 단계별 catch를 우회한 예상치 못한 에러
415
+ const crashDiag = this._createCrashDiagnostic(e);
384
416
  return {
385
417
  program,
386
418
  builderProgram,
@@ -389,7 +421,11 @@ export class SdTsCompiler {
389
421
  diagnostics: [crashDiag],
390
422
  errorCount: 1,
391
423
  warningCount: 0,
392
- errors: [message],
424
+ errors: [
425
+ typeof crashDiag.messageText === "string"
426
+ ? crashDiag.messageText
427
+ : "TsCompiler 내부 크래시",
428
+ ],
393
429
  ngtscProgram: this._ngtscProgram,
394
430
  emitResults: undefined,
395
431
  lint: undefined,
@@ -399,72 +435,6 @@ export class SdTsCompiler {
399
435
  }
400
436
  }
401
437
 
402
- /**
403
- * 크래시 발생 후, affected sourceFile을 개별 try-catch로 재검사하여 원인 파일을 특정한다.
404
- * Angular: `getDiagnosticsForFile(sf, SingleFile)` + `builderProgram.getSemanticDiagnostics(sf)` 개별 호출.
405
- * 각 파일별로 크래시 재현 여부를 기록. 프로브 자체 크래시는 흡수한다.
406
- */
407
- private _probeCrashPerFileAngular(
408
- ngtscProgram: NgtscProgram | undefined,
409
- builderProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram,
410
- affectedSourceFiles: ReadonlySet<ts.SourceFile>,
411
- ): string[] {
412
- const report: string[] = [];
413
- const angularCompiler = ngtscProgram?.compiler;
414
- const { cwd } = this._options;
415
-
416
- for (const sf of affectedSourceFiles) {
417
- if (angularCompiler?.ignoreForDiagnostics.has(sf) === true) continue;
418
-
419
- const rel = path.relative(cwd, sf.fileName);
420
-
421
- try {
422
- builderProgram.getSemanticDiagnostics(sf);
423
- } catch (e) {
424
- report.push(
425
- ` - ${rel} [getSemanticDiagnostics]: ${e instanceof Error ? e.message : String(e)}`,
426
- );
427
- continue;
428
- }
429
-
430
- if (angularCompiler != null && !sf.isDeclarationFile) {
431
- try {
432
- angularCompiler.getDiagnosticsForFile(sf, OptimizeFor.SingleFile);
433
- } catch (e) {
434
- report.push(
435
- ` - ${rel} [getDiagnosticsForFile]: ${e instanceof Error ? e.message : String(e)}`,
436
- );
437
- }
438
- }
439
- }
440
- return report;
441
- }
442
-
443
- private _probeCrashPerFileTsc(
444
- builderProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram,
445
- affectedSourceFiles: ReadonlySet<ts.SourceFile>,
446
- ): string[] {
447
- const report: string[] = [];
448
- const { cwd } = this._options;
449
-
450
- const targets =
451
- affectedSourceFiles.size > 0
452
- ? affectedSourceFiles
453
- : new Set(builderProgram.getSourceFiles());
454
-
455
- for (const sf of targets) {
456
- try {
457
- builderProgram.getSemanticDiagnostics(sf);
458
- } catch (e) {
459
- const rel = path.relative(cwd, sf.fileName);
460
- report.push(
461
- ` - ${rel} [getSemanticDiagnostics]: ${e instanceof Error ? e.message : String(e)}`,
462
- );
463
- }
464
- }
465
- return report;
466
- }
467
-
468
438
  private async _runLint(
469
439
  program: ts.Program,
470
440
  affectedFiles?: ReadonlySet<string>,
@@ -615,11 +585,16 @@ export class SdTsCompiler {
615
585
  ): ts.Diagnostic[] {
616
586
  const diagnostics: ts.Diagnostic[] = [
617
587
  ...builderProgram.getConfigFileParsingDiagnostics(),
618
- ...builderProgram.getSyntacticDiagnostics(),
619
588
  ...builderProgram.getOptionsDiagnostics(),
620
589
  ...builderProgram.getGlobalDiagnostics(),
621
- ...builderProgram.getSemanticDiagnostics(),
622
590
  ];
591
+
592
+ for (const sourceFile of builderProgram.getSourceFiles()) {
593
+ this._setCrashContext("collectDiagnostics", sourceFile.fileName);
594
+ diagnostics.push(...builderProgram.getSyntacticDiagnostics(sourceFile));
595
+ diagnostics.push(...builderProgram.getSemanticDiagnostics(sourceFile));
596
+ }
597
+
623
598
  if (!this._options.output.dts) {
624
599
  diagnostics.push(...builderProgram.getProgram().getDeclarationDiagnostics());
625
600
  }
@@ -802,7 +777,13 @@ export class SdTsCompiler {
802
777
  ): ReadonlySet<string> | undefined {
803
778
  const affectedFiles = new Set<string>();
804
779
  while (true) {
805
- const result = builderProgram.getSemanticDiagnosticsOfNextAffectedFile();
780
+ const result = builderProgram.getSemanticDiagnosticsOfNextAffectedFile(
781
+ undefined,
782
+ (sourceFile) => {
783
+ this._setCrashContext("findAffectedFiles", sourceFile.fileName);
784
+ return false;
785
+ },
786
+ );
806
787
  if (result == null) break;
807
788
  if ("fileName" in result.affected) {
808
789
  affectedFiles.add(pathx.posix(result.affected.fileName));
@@ -829,6 +810,7 @@ export class SdTsCompiler {
829
810
  const result = builderProgram.getSemanticDiagnosticsOfNextAffectedFile(
830
811
  undefined,
831
812
  (sourceFile) => {
813
+ this._setCrashContext("findAffectedFiles", sourceFile.fileName);
832
814
  if (
833
815
  angularCompiler.ignoreForDiagnostics.has(sourceFile) &&
834
816
  sourceFile.fileName.endsWith(".ngtypecheck.ts")
@@ -4,7 +4,6 @@ import { SdError } from "@simplysm/core-common";
4
4
  import { pathx } from "@simplysm/core-node";
5
5
  import { createLazyLogger } from "../runtime/lazy-logger";
6
6
  import type {
7
- SdBuildPackageConfig,
8
7
  SdPackageConfig,
9
8
  } from "../sd-config.types";
10
9
 
@@ -90,7 +89,7 @@ export function mergeTestsPackagesIntoConfig(
90
89
  );
91
90
  }
92
91
 
93
- merged[name] = { target: "node" } as SdBuildPackageConfig;
92
+ merged[name] = { target: "node" };
94
93
  pathMap.set(name, relPath);
95
94
  }
96
95
 
@@ -2,15 +2,15 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] enableHmr 프로퍼티가 AngularCompilerOptions에서 제거됨: `angular-compiler.ts` 인터페이스에 `enableHmr` 없음 확인
6
- - [x] HMR_MODIFIED_FILE_LIMIT 상수가 제거됨: `angular-compiler.ts`에서 해당 상수 없음 확인
7
- - [x] collectHmrCandidates import가 제거됨: `angular-compiler.ts`에서 `hmr-candidates` import 없음 확인
8
- - [x] stale source file 수집 로직이 제거됨: `angular-compiler.ts`에서 `staleSourceFiles`, `useHmr` 변수 없음 확인
9
- - [x] enableHmr 프로퍼티가 AngularBuildPipelineOptions에서 제거됨: `angular-build-pipeline.ts` 인터페이스에 `enableHmr` 없음 확인
10
- - [x] templateUpdates 프로퍼티가 PipelineResult에서 제거됨: `angular-build-pipeline.ts` 인터페이스에 `templateUpdates` 없음 확인
11
- - [x] vite-angular-plugin.ts의 `enableHmr: false` 제거됨: Pipeline 생성 시 `enableHmr` 옵션 없음 확인
12
- - [x] hmr-candidates.ts 파일 삭제됨: `src/utils/hmr-candidates.ts` 파일 존재하지 않음
13
- - [x] angular-compiler-hmr.spec.ts 삭제됨: `tests/angular/angular-compiler-hmr.spec.ts` 파일 존재하지 않음
14
- - [x] hmr-candidates.spec.ts 삭제됨: `tests/angular/hmr-candidates.spec.ts` 파일 존재하지 않음
15
- - [x] client.worker.ts 변경 없음: `client.worker.ts`는 `createCompilerPlugin` 경로를 사용하며 AngularCompiler를 직접 참조하지 않음
16
- - [x] hmr-service.ts, hmr-client-script.ts, esbuild-client-config.ts 변경 없음: client.worker.ts 경로의 HMR 인프라는 그대로 유지됨
5
+ - enableHmr 프로퍼티가 AngularCompilerOptions에서 제거됨: `angular-compiler.ts` 인터페이스에 `enableHmr` 없음 확인
6
+ - HMR_MODIFIED_FILE_LIMIT 상수가 제거됨: `angular-compiler.ts`에서 해당 상수 없음 확인
7
+ - collectHmrCandidates import가 제거됨: `angular-compiler.ts`에서 `hmr-candidates` import 없음 확인
8
+ - stale source file 수집 로직이 제거됨: `angular-compiler.ts`에서 `staleSourceFiles`, `useHmr` 변수 없음 확인
9
+ - enableHmr 프로퍼티가 AngularBuildPipelineOptions에서 제거됨: `angular-build-pipeline.ts` 인터페이스에 `enableHmr` 없음 확인
10
+ - templateUpdates 프로퍼티가 PipelineResult에서 제거됨: `angular-build-pipeline.ts` 인터페이스에 `templateUpdates` 없음 확인
11
+ - vite-angular-plugin.ts의 `enableHmr: false` 제거됨: Pipeline 생성 시 `enableHmr` 옵션 없음 확인
12
+ - hmr-candidates.ts 파일 삭제됨: `src/utils/hmr-candidates.ts` 파일 존재하지 않음
13
+ - angular-compiler-hmr.spec.ts 삭제됨: `tests/angular/angular-compiler-hmr.spec.ts` 파일 존재하지 않음
14
+ - hmr-candidates.spec.ts 삭제됨: `tests/angular/hmr-candidates.spec.ts` 파일 존재하지 않음
15
+ - client.worker.ts 변경 없음: `client.worker.ts`는 `createCompilerPlugin` 경로를 사용하며 AngularCompiler를 직접 참조하지 않음
16
+ - hmr-service.ts, hmr-client-script.ts, esbuild-client-config.ts 변경 없음: client.worker.ts 경로의 HMR 인프라는 그대로 유지됨
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] `SdAngularPluginOptions.onBuild` 타입에서 `lint?` 필드가 제거됨: `vite-angular-plugin.ts:32-35` — `result` 타입이 `{ success: boolean; errors?: string[]; warnings?: string[] }` 으로 변경됨, `lint?` 없음
6
- - [x] `CreateClientViteConfigOptions.onBuild` 타입에서 `lint?` 필드가 제거됨: `vite-config.ts:34-37` — 동일하게 `lint?` 없음
7
- - [x] `vite-angular-plugin.ts`에서 `LintWithProgramResult` import 제거됨: import 목록에 해당 import 없음
8
- - [x] `vite-angular-plugin.ts`의 3개 `onBuild` 호출 지점(buildStart:321, handleHotUpdate:409, handleHotUpdate:433)에서 lint 미전달 — 기존에도 전달하지 않았으므로 변경 없음, 타입 정합
5
+ - `SdAngularPluginOptions.onBuild` 타입에서 `lint?` 필드가 제거됨: `vite-angular-plugin.ts:32-35` — `result` 타입이 `{ success: boolean; errors?: string[]; warnings?: string[] }` 으로 변경됨, `lint?` 없음
6
+ - `CreateClientViteConfigOptions.onBuild` 타입에서 `lint?` 필드가 제거됨: `vite-config.ts:34-37` — 동일하게 `lint?` 없음
7
+ - `vite-angular-plugin.ts`에서 `LintWithProgramResult` import 제거됨: import 목록에 해당 import 없음
8
+ - `vite-angular-plugin.ts`의 3개 `onBuild` 호출 지점(buildStart:321, handleHotUpdate:409, handleHotUpdate:433)에서 lint 미전달 — 기존에도 전달하지 않았으므로 변경 없음, 타입 정합
@@ -2,12 +2,12 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] AngularBuildPipeline import 제거: `vite-angular-plugin.ts:6` — `SdTsCompiler` import으로 교체, `AngularBuildPipeline` 미사용
6
- - [x] SdTsCompiler 인스턴스 생성: `:69-81` — `new SdTsCompiler({ pkgDir, cwd, output: { js: true, dts: false }, sourceFileCache, compilerOptionsTransformer })` 올바르게 구성
7
- - [x] compileAsync 호출: `:90` — `sdTsCompiler.compileAsync(modifiedFiles)` 호출, modifiedFiles는 pendingWatchChanges에서 수집
8
- - [x] emitResults → emittedFilesBySource 매핑: `:93-95` — `pathx.posix(sourceFileName)` 키로 저장
9
- - [x] transform 훅: `:107-124` — `emittedFilesBySource.get(normalizedId)` 조회, 인라인 소스맵 분리 유지
10
- - [x] buildEnd에서 sdTsCompiler 참조 해제: `:127` — `sdTsCompiler = undefined`
11
- - [x] watch 모드 증분 빌드: `:61-66` — pendingWatchChanges를 modifiedFiles로 전달, compileAsync에서 증분 처리
12
- - [x] 이미 초기화됐고 변경 없으면 건너뜀: `:84-87` — `emittedFilesBySource.size > 0 && modifiedFiles == null` 조건
13
- - [x] 기존 테스트 회귀: vite-angular-plugin.spec.ts 6개, vite-angular-plugin-vitest.spec.ts + legacy-watch.spec.ts 5개 모두 통과
5
+ - AngularBuildPipeline import 제거: `vite-angular-plugin.ts:6` — `SdTsCompiler` import으로 교체, `AngularBuildPipeline` 미사용
6
+ - SdTsCompiler 인스턴스 생성: `:69-81` — `new SdTsCompiler({ pkgDir, cwd, output: { js: true, dts: false }, sourceFileCache, compilerOptionsTransformer })` 올바르게 구성
7
+ - compileAsync 호출: `:90` — `sdTsCompiler.compileAsync(modifiedFiles)` 호출, modifiedFiles는 pendingWatchChanges에서 수집
8
+ - emitResults → emittedFilesBySource 매핑: `:93-95` — `pathx.posix(sourceFileName)` 키로 저장
9
+ - transform 훅: `:107-124` — `emittedFilesBySource.get(normalizedId)` 조회, 인라인 소스맵 분리 유지
10
+ - buildEnd에서 sdTsCompiler 참조 해제: `:127` — `sdTsCompiler = undefined`
11
+ - watch 모드 증분 빌드: `:61-66` — pendingWatchChanges를 modifiedFiles로 전달, compileAsync에서 증분 처리
12
+ - 이미 초기화됐고 변경 없으면 건너뜀: `:84-87` — `emittedFilesBySource.size > 0 && modifiedFiles == null` 조건
13
+ - 기존 테스트 회귀: vite-angular-plugin.spec.ts 6개, vite-angular-plugin-vitest.spec.ts + legacy-watch.spec.ts 5개 모두 통과
@@ -2,19 +2,19 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] vite-config.ts 삭제됨: `ls packages/sd-cli/src/utils/vite-config.ts` → 파일 없음 확인
6
- - [x] vite-scope-watch-plugin.ts 삭제됨: `ls packages/sd-cli/src/utils/vite-scope-watch-plugin.ts` → 파일 없음 확인
7
- - [x] vite-postcss-inline-plugin.ts 삭제됨: `ls packages/sd-cli/src/angular/vite-postcss-inline-plugin.ts` → 파일 없음 확인
8
- - [x] vite-pwa-plugin.ts 삭제됨: `ls packages/sd-cli/src/utils/vite-pwa-plugin.ts` → 파일 없음 확인
9
- - [x] vite-angular-plugin.ts에서 config() 훅 유지: config()는 isDev, pkgConfig, resolvedPkgDir 초기화에 필수. Vitest가 Vite plugin lifecycle을 호출하므로 유지. 단, optimizeDeps/define 반환값 제거됨
10
- - [x] vite-angular-plugin.ts에서 configResolved() 훅 유지: enableSourcemap 설정에 필요. 단, prebundleTransformer 생성 제거됨
11
- - [x] handleHotUpdate() 제거됨: HMR 배칭(pendingHmrFiles, hmrBatchTimer, processHmrBatch) 모두 제거됨
12
- - [x] configureServer() 제거됨: devServer, isDevServer, angularComponentMiddleware 모두 제거됨
13
- - [x] onBuildStart/onBuild 콜백 제거됨: SdAngularPluginOptions에서 onBuildStart, onBuild 필드 삭제됨. buildStart()에서 options.onBuild 호출 제거됨
14
- - [x] resolveReplaceDeps() 제거됨: scope watch 관련 replaceDepDistPaths, resolveReplaceDepEntries import 모두 제거됨
15
- - [x] watchChange(id) 유지됨: pendingWatchChanges에 파일 경로 수집. Vitest watch 모드에서 캐시 무효화에 사용
16
- - [x] buildStart() 유지됨: tsconfig 파싱, AngularSourceFileCache 생성/재사용, AngularBuildPipeline 초기화, 전체/증분 컴파일 수행. enableHmr: false로 고정 (Vitest에서 HMR 불필요)
17
- - [x] transform() 유지됨: .ts 파일에 대해 Pipeline emit JS 반환 + JavaScriptTransformer 적용. query param 제거 및 인라인 소스맵 분리 로직 유지
18
- - [x] buildEnd() 간소화됨: isDev 분기 제거. 항상 jsTransformer.close() + pipeline 해제. prebundleTransformer 제거
19
- - [x] Vite 타입 import 축소: `ModuleNode`, `ViteDevServer` import 제거됨. `Plugin` 타입만 유지
20
- - [x] 미사용 import 제거: `createHash`, `fsp`, `fs`, `IncomingMessage`, `ServerResponse`, `SdConfig`, `resolveReplaceDepEntries` 제거됨
5
+ - vite-config.ts 삭제됨: `ls packages/sd-cli/src/utils/vite-config.ts` → 파일 없음 확인
6
+ - vite-scope-watch-plugin.ts 삭제됨: `ls packages/sd-cli/src/utils/vite-scope-watch-plugin.ts` → 파일 없음 확인
7
+ - vite-postcss-inline-plugin.ts 삭제됨: `ls packages/sd-cli/src/angular/vite-postcss-inline-plugin.ts` → 파일 없음 확인
8
+ - vite-pwa-plugin.ts 삭제됨: `ls packages/sd-cli/src/utils/vite-pwa-plugin.ts` → 파일 없음 확인
9
+ - vite-angular-plugin.ts에서 config() 훅 유지: config()는 isDev, pkgConfig, resolvedPkgDir 초기화에 필수. Vitest가 Vite plugin lifecycle을 호출하므로 유지. 단, optimizeDeps/define 반환값 제거됨
10
+ - vite-angular-plugin.ts에서 configResolved() 훅 유지: enableSourcemap 설정에 필요. 단, prebundleTransformer 생성 제거됨
11
+ - handleHotUpdate() 제거됨: HMR 배칭(pendingHmrFiles, hmrBatchTimer, processHmrBatch) 모두 제거됨
12
+ - configureServer() 제거됨: devServer, isDevServer, angularComponentMiddleware 모두 제거됨
13
+ - onBuildStart/onBuild 콜백 제거됨: SdAngularPluginOptions에서 onBuildStart, onBuild 필드 삭제됨. buildStart()에서 options.onBuild 호출 제거됨
14
+ - resolveReplaceDeps() 제거됨: scope watch 관련 replaceDepDistPaths, resolveReplaceDepEntries import 모두 제거됨
15
+ - watchChange(id) 유지됨: pendingWatchChanges에 파일 경로 수집. Vitest watch 모드에서 캐시 무효화에 사용
16
+ - buildStart() 유지됨: tsconfig 파싱, AngularSourceFileCache 생성/재사용, AngularBuildPipeline 초기화, 전체/증분 컴파일 수행. enableHmr: false로 고정 (Vitest에서 HMR 불필요)
17
+ - transform() 유지됨: .ts 파일에 대해 Pipeline emit JS 반환 + JavaScriptTransformer 적용. query param 제거 및 인라인 소스맵 분리 로직 유지
18
+ - buildEnd() 간소화됨: isDev 분기 제거. 항상 jsTransformer.close() + pipeline 해제. prebundleTransformer 제거
19
+ - Vite 타입 import 축소: `ModuleNode`, `ViteDevServer` import 제거됨. `Plugin` 타입만 유지
20
+ - 미사용 import 제거: `createHash`, `fsp`, `fs`, `IncomingMessage`, `ServerResponse`, `SdConfig`, `resolveReplaceDepEntries` 제거됨
@@ -2,10 +2,10 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] configureAndroid이 capacitor-android.ts에서 export된다: line 13 `export async function configureAndroid`
6
- - [x] findJava21이 capacitor-android.ts에서 export된다: line 53 `export async function findJava21`
7
- - [x] findAndroidSdk가 capacitor-android.ts에서 export된다: line 76 `export async function findAndroidSdk`
8
- - [x] 내부 configure 함수들(_configureJavaHomePath 등)은 export되지 않는다: `^export` 검색 결과 3개만 확인
9
- - [x] Capacitor 클래스의 _validateTools가 findAndroidSdk/findJava21을 import하여 사용한다: line 8 import, line 217/229 호출
10
- - [x] Capacitor 클래스에서 9개 Android 설정 private 메서드가 삭제되었다: `_configureAndroid` 등 검색 결과 0건
11
- - [x] capacitor.ts에서 env import가 제거되었다: `import.*env.*from` 검색 결과 0건
5
+ - configureAndroid이 capacitor-android.ts에서 export된다: line 13 `export async function configureAndroid`
6
+ - findJava21이 capacitor-android.ts에서 export된다: line 53 `export async function findJava21`
7
+ - findAndroidSdk가 capacitor-android.ts에서 export된다: line 76 `export async function findAndroidSdk`
8
+ - 내부 configure 함수들(_configureJavaHomePath 등)은 export되지 않는다: `^export` 검색 결과 3개만 확인
9
+ - Capacitor 클래스의 _validateTools가 findAndroidSdk/findJava21을 import하여 사용한다: line 8 import, line 217/229 호출
10
+ - Capacitor 클래스에서 9개 Android 설정 private 메서드가 삭제되었다: `_configureAndroid` 등 검색 결과 0건
11
+ - capacitor.ts에서 env import가 제거되었다: `import.*env.*from` 검색 결과 0건
@@ -2,8 +2,8 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] npm 배포 로직(publishNpm)이 npm-publisher.ts에 위치: `src/commands/publish/npm-publisher.ts:9`
6
- - [x] 로컬 복사 로직(publishToLocal)이 local-publisher.ts에 위치: `src/commands/publish/local-publisher.ts:9`
7
- - [x] index.ts의 publishPackage가 각 publisher 호출로 교체됨: `src/commands/publish/index.ts:163-171` — type별 분기가 publishNpm, publishToLocal, publishToStorage 호출
8
- - [x] export 경로 불변: `import { runPublish } from "./commands/publish"` — sd-cli-entry.ts에서 동일 경로로 resolve됨 (commands/publish/index.ts)
9
- - [x] 버전 업그레이드, Git, 빌드 로직은 index.ts에 유지: upgradeVersion(:99), Git commit/tag/push(:487-499), runBuild 호출(:459)
5
+ - npm 배포 로직(publishNpm)이 npm-publisher.ts에 위치: `src/commands/publish/npm-publisher.ts:9`
6
+ - 로컬 복사 로직(publishToLocal)이 local-publisher.ts에 위치: `src/commands/publish/local-publisher.ts:9`
7
+ - index.ts의 publishPackage가 각 publisher 호출로 교체됨: `src/commands/publish/index.ts:163-171` — type별 분기가 publishNpm, publishToLocal, publishToStorage 호출
8
+ - export 경로 불변: `import { runPublish } from "./commands/publish"` — sd-cli-entry.ts에서 동일 경로로 resolve됨 (commands/publish/index.ts)
9
+ - 버전 업그레이드, Git, 빌드 로직은 index.ts에 유지: upgradeVersion(:99), Git commit/tag/push(:487-499), runBuild 호출(:459)
@@ -2,12 +2,12 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] version-upgrade.ts에 upgradeVersion, computePublishLevels, PackageJson이 export됨: `src/commands/publish/version-upgrade.ts` 확인 완료
6
- - [x] env-utils.ts에 replaceEnvVariables, waitWithCountdown이 export됨: `src/commands/publish/env-utils.ts` 확인 완료
7
- - [x] index.ts에서 추출 함수가 제거되고 import로 대체됨: `index.ts:14-15`에서 version-upgrade, env-utils import 확인
8
- - [x] index.ts export 불변 — runPublish, PublishOptions만 export: `index.ts:22` PublishOptions, `index.ts:76` runPublish 확인
9
- - [x] sd-cli-entry.ts의 import 경로 불변: `sd-cli-entry.ts:12` `import { runPublish } from "./commands/publish"` 유지
10
- - [x] 함수 시그니처 불변: upgradeVersion(cwd, allPkgPaths, dryRun), computePublishLevels(publishPkgs), replaceEnvVariables(str, version, projectPath), waitWithCountdown(message, seconds) 모두 원본과 동일
11
- - [x] index.ts LOC 축소: 639 → 455 LOC (목표 ~300 이하는 미달이나, 오케스트레이션 자체가 ~280 LOC이므로 적정)
12
- - [x] 총 LOC 보존: 631 total ≈ 639 original (import/export 차이)
13
- - [x] 기존 테스트 40개 전량 통과: vitest run 결과 40 passed
5
+ - version-upgrade.ts에 upgradeVersion, computePublishLevels, PackageJson이 export됨: `src/commands/publish/version-upgrade.ts` 확인 완료
6
+ - env-utils.ts에 replaceEnvVariables, waitWithCountdown이 export됨: `src/commands/publish/env-utils.ts` 확인 완료
7
+ - index.ts에서 추출 함수가 제거되고 import로 대체됨: `index.ts:14-15`에서 version-upgrade, env-utils import 확인
8
+ - index.ts export 불변 — runPublish, PublishOptions만 export: `index.ts:22` PublishOptions, `index.ts:76` runPublish 확인
9
+ - sd-cli-entry.ts의 import 경로 불변: `sd-cli-entry.ts:12` `import { runPublish } from "./commands/publish"` 유지
10
+ - 함수 시그니처 불변: upgradeVersion(cwd, allPkgPaths, dryRun), computePublishLevels(publishPkgs), replaceEnvVariables(str, version, projectPath), waitWithCountdown(message, seconds) 모두 원본과 동일
11
+ - index.ts LOC 축소: 639 → 455 LOC (목표 ~300 이하는 미달이나, 오케스트레이션 자체가 ~280 LOC이므로 적정)
12
+ - 총 LOC 보존: 631 total ≈ 639 original (import/export 차이)
13
+ - 기존 테스트 40개 전량 통과: vitest run 결과 40 passed
@@ -2,6 +2,6 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] Set 생성: `publish.ts:773` — `const publishedSet = new Set(publishedPackages)` 확인
6
- - [x] Set.has() 사용: `publish.ts:774` — `allPkgNames.filter(n => !publishedSet.has(n))` 확인
7
- - [x] 동작 동등성: `Array.includes()` → `Set.has()` 변환은 동일한 boolean 결과를 반환하���로 기능 동등
5
+ - Set 생성: `publish.ts:773` — `const publishedSet = new Set(publishedPackages)` 확인
6
+ - Set.has() 사용: `publish.ts:774` — `allPkgNames.filter(n => !publishedSet.has(n))` 확인
7
+ - 동작 동등성: `Array.includes()` → `Set.has()` 변환은 동일한 boolean 결과를 반환하���로 기능 동등
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] SSH 인증 로직(ensureSshAuth, testSshKeyAuth, registerSshPublicKey)이 storage-publisher.ts에 위치: `src/commands/publish/storage-publisher.ts:55` (ensureSshAuth), `:128` (testSshKeyAuth), `:157` (registerSshPublicKey)
6
- - [x] 스토리지 배포 로직(publishToStorage)이 storage-publisher.ts에 위치: `src/commands/publish/storage-publisher.ts:17`
7
- - [x] index.ts에서 ensureSshAuth와 publishToStorage를 import하여 사용: `src/commands/publish/index.ts:13`
8
- - [x] import 경로 "./commands/publish"가 디렉토리 구조 변환 후에도 동일하게 resolve: `publish/index.ts`가 Node.js 모듈 resolution에 의해 `commands/publish`로 resolve됨
5
+ - SSH 인증 로직(ensureSshAuth, testSshKeyAuth, registerSshPublicKey)이 storage-publisher.ts에 위치: `src/commands/publish/storage-publisher.ts:55` (ensureSshAuth), `:128` (testSshKeyAuth), `:157` (registerSshPublicKey)
6
+ - 스토리지 배포 로직(publishToStorage)이 storage-publisher.ts에 위치: `src/commands/publish/storage-publisher.ts:17`
7
+ - index.ts에서 ensureSshAuth와 publishToStorage를 import하여 사용: `src/commands/publish/index.ts:13`
8
+ - import 경로 "./commands/publish"가 디렉토리 구조 변환 후에도 동일하게 resolve: `publish/index.ts`가 Node.js 모듈 resolution에 의해 `commands/publish`로 resolve됨
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## 검증 항목
4
4
 
5
- - [x] replace-deps.ts:5 — `const logger = consola.withTag("sd:cli:replace-deps")` 모듈-레벨 로거 추가 확인
6
- - [x] replace-deps.ts:24 — `consola.warn(...)` → `logger.warn(...)` 변경 확인
7
- - [x] deployment-phase.ts:66-70 — DRY-RUN 성공 메시지 `debug` → `info` 전환 확인: `dryRun ? logger.info("[DRY-RUN] ...") : logger.debug(...)`
8
- - [x] deployment-phase.ts:76-80 — DRY-RUN 재시도 메시지 `debug` → `info` 전환 확인: 동일 패턴
9
- - [x] deployment-phase.ts:102 — `logger.fail(...)` → `logger.error(...)` 전환 확인
10
- - [x] BuildOrchestrator.ts:251 — `this._logger.success("빌드 실행 완료")` 행 제거 확인: 250행 뒤에 바로 `return` 문
11
- - [x] BuildOrchestrator.ts:477 — `this._logger.info("빌드 완료")` → `this._logger.success("빌드 완료")` 전환 확인
12
- - [x] BuildOrchestrator.ts:232-233 — `this._logger.start("빌드 실행 중...")` 유지 확인: start(232)/success(477) 쌍 정상화
5
+ - replace-deps.ts:5 — `const logger = consola.withTag("sd:cli:replace-deps")` 모듈-레벨 로거 추가 확인
6
+ - replace-deps.ts:24 — `consola.warn(...)` → `logger.warn(...)` 변경 확인
7
+ - deployment-phase.ts:66-70 — DRY-RUN 성공 메시지 `debug` → `info` 전환 확인: `dryRun ? logger.info("[DRY-RUN] ...") : logger.debug(...)`
8
+ - deployment-phase.ts:76-80 — DRY-RUN 재시도 메시지 `debug` → `info` 전환 확인: 동일 패턴
9
+ - deployment-phase.ts:102 — `logger.fail(...)` → `logger.error(...)` 전환 확인
10
+ - BuildOrchestrator.ts:251 — `this._logger.success("빌드 실행 완료")` 행 제거 확인: 250행 뒤에 바로 `return` 문
11
+ - BuildOrchestrator.ts:477 — `this._logger.info("빌드 완료")` → `this._logger.success("빌드 완료")` 전환 확인
12
+ - BuildOrchestrator.ts:232-233 — `this._logger.start("빌드 실행 중...")` 유지 확인: start(232)/success(477) 쌍 정상화