@simplysm/sd-claude 14.0.65 → 14.0.66

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 (227) hide show
  1. package/claude/references/sd-requirement-source-handling.md +64 -0
  2. package/claude/references/sd-simplysm14/README.md +44 -40
  3. package/claude/references/sd-simplysm14/apis/angular/README.md +95 -0
  4. package/claude/references/sd-simplysm14/apis/angular/app-structure.md +49 -0
  5. package/claude/references/sd-simplysm14/apis/angular/buttons.md +42 -0
  6. package/claude/references/sd-simplysm14/apis/angular/crud.md +35 -0
  7. package/claude/references/sd-simplysm14/apis/angular/forms.md +63 -0
  8. package/claude/references/sd-simplysm14/apis/angular/infrastructure.md +80 -0
  9. package/claude/references/sd-simplysm14/apis/angular/kanban.md +33 -0
  10. package/claude/references/sd-simplysm14/apis/angular/layout.md +41 -0
  11. package/claude/references/sd-simplysm14/apis/angular/modal.md +63 -0
  12. package/claude/references/sd-simplysm14/apis/angular/routing.md +45 -0
  13. package/claude/references/sd-simplysm14/apis/angular/select-dropdown.md +35 -0
  14. package/claude/references/sd-simplysm14/apis/angular/selection-managers.md +50 -0
  15. package/claude/references/sd-simplysm14/apis/angular/shared-data.md +42 -0
  16. package/claude/references/sd-simplysm14/apis/angular/sheet.md +52 -0
  17. package/claude/references/sd-simplysm14/apis/angular/toast.md +46 -0
  18. package/claude/references/sd-simplysm14/apis/angular/visual.md +41 -0
  19. package/claude/references/sd-simplysm14/apis/capacitor-plugin-auto-update/README.md +76 -0
  20. package/claude/references/sd-simplysm14/apis/capacitor-plugin-file-system/README.md +83 -0
  21. package/claude/references/sd-simplysm14/apis/capacitor-plugin-intent/README.md +80 -0
  22. package/claude/references/sd-simplysm14/apis/capacitor-plugin-usb-storage/README.md +39 -0
  23. package/claude/references/sd-simplysm14/apis/core-browser/README.md +112 -0
  24. package/claude/references/sd-simplysm14/apis/core-common/README.md +53 -0
  25. package/claude/references/sd-simplysm14/apis/core-common/extensions.md +123 -0
  26. package/claude/references/sd-simplysm14/apis/core-common/features.md +46 -0
  27. package/claude/references/sd-simplysm14/apis/core-common/types.md +114 -0
  28. package/claude/references/sd-simplysm14/apis/core-common/utils.md +158 -0
  29. package/claude/references/sd-simplysm14/apis/core-node/README.md +12 -0
  30. package/claude/references/sd-simplysm14/apis/core-node/consola.md +64 -0
  31. package/claude/references/sd-simplysm14/apis/core-node/cpx.md +52 -0
  32. package/claude/references/sd-simplysm14/apis/core-node/fs-watcher.md +53 -0
  33. package/claude/references/sd-simplysm14/apis/core-node/fsx.md +81 -0
  34. package/claude/references/sd-simplysm14/apis/core-node/pathx.md +55 -0
  35. package/claude/references/sd-simplysm14/apis/core-node/worker.md +111 -0
  36. package/claude/references/sd-simplysm14/apis/excel/README.md +81 -0
  37. package/claude/references/sd-simplysm14/apis/lint/README.md +80 -0
  38. package/claude/references/sd-simplysm14/apis/orm-common/README.md +33 -0
  39. package/claude/references/sd-simplysm14/apis/orm-common/db-context.md +77 -0
  40. package/claude/references/sd-simplysm14/apis/orm-common/executable.md +20 -0
  41. package/claude/references/sd-simplysm14/apis/orm-common/expr.md +92 -0
  42. package/claude/references/sd-simplysm14/apis/orm-common/queryable.md +98 -0
  43. package/claude/references/sd-simplysm14/apis/orm-common/schema-builders.md +128 -0
  44. package/claude/references/sd-simplysm14/apis/orm-node/README.md +59 -0
  45. package/claude/references/sd-simplysm14/apis/sd-claude/README.md +9 -0
  46. package/claude/references/sd-simplysm14/apis/sd-cli/README.md +50 -0
  47. package/claude/references/sd-simplysm14/apis/sd-cli/sd-config.md +155 -0
  48. package/claude/references/sd-simplysm14/apis/service-client/README.md +92 -0
  49. package/claude/references/sd-simplysm14/apis/service-common/README.md +29 -0
  50. package/claude/references/sd-simplysm14/apis/service-common/app-structure.md +63 -0
  51. package/claude/references/sd-simplysm14/apis/service-common/messages.md +56 -0
  52. package/claude/references/sd-simplysm14/apis/service-common/protocol.md +64 -0
  53. package/claude/references/sd-simplysm14/apis/service-common/service-types.md +43 -0
  54. package/claude/references/sd-simplysm14/apis/service-server/README.md +20 -0
  55. package/claude/references/sd-simplysm14/apis/service-server/auth.md +31 -0
  56. package/claude/references/sd-simplysm14/apis/service-server/builtin-services.md +47 -0
  57. package/claude/references/sd-simplysm14/apis/service-server/define-service.md +71 -0
  58. package/claude/references/sd-simplysm14/apis/service-server/internals.md +41 -0
  59. package/claude/references/sd-simplysm14/apis/service-server/server.md +66 -0
  60. package/claude/references/sd-simplysm14/apis/storage/README.md +69 -0
  61. package/claude/references/sd-simplysm14/{client-component.md → manuals/client-component.md} +133 -128
  62. package/claude/references/sd-simplysm14/manuals/client-crud.md +102 -0
  63. package/claude/references/sd-simplysm14/manuals/client-demo.md +128 -0
  64. package/claude/references/sd-simplysm14/manuals/client-rules.md +7 -0
  65. package/claude/references/sd-simplysm14/{client-setup.md → manuals/client-setup.md} +2 -2
  66. package/claude/references/sd-simplysm14/{client-tab.md → manuals/client-tab.md} +13 -11
  67. package/claude/references/sd-simplysm14/{orm-union.md → manuals/orm-union.md} +1 -1
  68. package/claude/references/sd-simplysm14/manuals/orm.md +75 -0
  69. package/claude/rules/sd-base-rules.md +172 -79
  70. package/claude/sd-check-bash.py +5 -0
  71. package/claude/sd-statusline.py +7 -12
  72. package/claude/skills/sd-commit/SKILL.md +7 -3
  73. package/claude/skills/sd-demo/SKILL.md +81 -62
  74. package/claude/skills/sd-demo/evals/fixtures/empty/.specs/260513120000_warehouse/spec.md +45 -0
  75. package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/.specs/260513120000_warehouse/spec.md +42 -0
  76. package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  77. package/claude/skills/sd-demo/evals/fixtures/with-master-screen/.specs/260513120000_warehouse/spec.md +45 -0
  78. package/claude/skills/sd-demo/evals/fixtures/with-master-screen/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  79. package/claude/skills/sd-demo/evals/fixtures/with-modal/.specs/260513120000_warehouse/spec.md +75 -0
  80. package/claude/skills/sd-demo/evals/fixtures/with-modal/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  81. package/claude/skills/sd-demo/evals/fixtures/with-screens/.specs/260513120000_warehouse/spec.md +45 -0
  82. package/claude/skills/sd-demo/evals/fixtures/with-screens/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  83. package/claude/skills/sd-demo/evals/golden.jsonl +5 -3
  84. package/claude/skills/sd-dev/SKILL.md +33 -63
  85. package/claude/skills/sd-dev/evals/fixtures/case-add/package.json +13 -0
  86. package/claude/skills/sd-dev/evals/fixtures/case-add/src/index.ts +10 -0
  87. package/claude/skills/sd-dev/evals/fixtures/case-add/tests/index.test.ts +11 -0
  88. package/claude/skills/sd-dev/evals/fixtures/case-add/tsconfig.json +12 -0
  89. package/claude/skills/sd-dev/evals/fixtures/case-bug/package.json +13 -0
  90. package/claude/skills/sd-dev/evals/fixtures/case-bug/src/index.ts +10 -0
  91. package/claude/skills/sd-dev/evals/fixtures/case-bug/tests/index.test.ts +11 -0
  92. package/claude/skills/sd-dev/evals/fixtures/case-bug/tsconfig.json +12 -0
  93. package/claude/skills/sd-dev/evals/fixtures/case-modify/package.json +13 -0
  94. package/claude/skills/sd-dev/evals/fixtures/case-modify/src/index.ts +10 -0
  95. package/claude/skills/sd-dev/evals/fixtures/case-modify/tests/index.test.ts +11 -0
  96. package/claude/skills/sd-dev/evals/fixtures/case-modify/tsconfig.json +12 -0
  97. package/claude/skills/sd-dev/evals/golden.jsonl +3 -3
  98. package/claude/skills/sd-docs/SKILL.md +53 -0
  99. package/claude/skills/sd-docs/evals/fixtures/new-write/.claude/references/sd-simplysm14/README.md +7 -0
  100. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/package.json +5 -0
  101. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/src/index.ts +3 -0
  102. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/package.json +6 -0
  103. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/src/index.ts +1 -0
  104. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/package.json +5 -0
  105. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/src/index.ts +8 -0
  106. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/README.md +7 -0
  107. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/apis/foo/README.md +3 -0
  108. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/package.json +5 -0
  109. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/src/index.ts +3 -0
  110. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/package.json +6 -0
  111. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/src/index.ts +1 -0
  112. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/package.json +5 -0
  113. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/src/index.ts +8 -0
  114. package/claude/skills/sd-docs/evals/golden.jsonl +2 -0
  115. package/claude/skills/sd-docs/references/subagent-prompt.md +100 -0
  116. package/claude/skills/sd-impl/SKILL.md +125 -46
  117. package/claude/skills/sd-impl/evals/fixtures/case-new/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +101 -0
  118. package/claude/skills/sd-impl/evals/fixtures/case-update/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +101 -0
  119. package/claude/skills/sd-impl/evals/fixtures/case-update/src//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/250/353/215/270.txt +1 -0
  120. package/claude/skills/sd-impl/evals/fixtures/case-update/src//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.txt +1 -0
  121. package/claude/skills/sd-impl/evals/golden.jsonl +2 -3
  122. package/claude/skills/sd-skill/SKILL.md +3 -3
  123. package/claude/skills/sd-skill/evals/golden.jsonl +0 -1
  124. package/claude/skills/sd-skill/references/eval-authoring.md +15 -0
  125. package/claude/skills/sd-skill/references/eval-run.md +1 -1
  126. package/claude/skills/sd-skill/references/skill-authoring.md +8 -5
  127. package/claude/skills/sd-skill/scripts/run_eval.py +39 -60
  128. package/claude/skills/sd-spec/SKILL.md +163 -105
  129. package/claude/skills/sd-spec/references/example-spec.md +585 -0
  130. package/claude/skills/sd-spec/references/spec-authoring.md +287 -0
  131. package/claude/skills/sd-spec/references/spec-md-template.md +15 -93
  132. package/claude/skills/sd-unpack/SKILL.md +7 -1
  133. package/claude/skills/sd-unpack/scripts/handlers/_common.py +10 -0
  134. package/claude/skills/sd-unpack/scripts/handlers/eml_handler.py +5 -13
  135. package/claude/skills/sd-unpack/scripts/handlers/msg_handler.py +3 -12
  136. package/claude/skills/sd-unpack/scripts/handlers/office_com.py +23 -37
  137. package/claude/skills/sd-unpack/scripts/handlers/office_worker.py +1 -4
  138. package/claude/skills/sd-unpack/scripts/handlers/pdf_handler.py +4 -13
  139. package/claude/skills/sd-unpack/scripts/unpack.py +4 -4
  140. package/claude/skills/sd-use/SKILL.md +1 -0
  141. package/claude/skills/sd-wip/SKILL.md +38 -0
  142. package/claude/skills/sd-wip/evals/fixtures/with-artifact/projects/acct/_wip.md +3 -0
  143. package/claude/skills/sd-wip/evals/fixtures/with-artifact/projects/acct/spec.md +15 -0
  144. package/claude/skills/sd-wip/evals/fixtures/with-existing-wip/.wips/260101120000_acct.md +6 -0
  145. package/claude/skills/sd-wip/evals/fixtures/with-existing-wip-for-compact/.wips/260101120000_acct.md +14 -0
  146. package/claude/skills/sd-wip/evals/golden.jsonl +4 -0
  147. package/claude/skills/sd-wip/references/compact.md +79 -0
  148. package/package.json +1 -1
  149. package/claude/references/sd-simplysm14/orm.md +0 -11
  150. package/claude/skills/sd-demo/evals/fixtures/basic-single-req/.specs/260503143025/REQ-001-/354/236/205/352/263/240/354/247/200/354/213/234/354/204/234/352/270/264/352/270/211/355/221/234/354/213/234/spec.md +0 -27
  151. package/claude/skills/sd-demo/evals/fixtures/basic-single-req/.specs/260503143025/overview.md +0 -12
  152. package/claude/skills/sd-demo/evals/fixtures/basic-single-req/src/components/Button.tsx +0 -12
  153. package/claude/skills/sd-demo/evals/fixtures/basic-single-req/src/components/Input.tsx +0 -27
  154. package/claude/skills/sd-demo/evals/fixtures/mock-data-policy/.specs/260503143025/REQ-001-/352/261/260/353/236/230/354/262/230/353/252/251/353/241/235/355/231/224/353/251/264/spec.md +0 -25
  155. package/claude/skills/sd-demo/evals/fixtures/mock-data-policy/.specs/260503143025/overview.md +0 -12
  156. package/claude/skills/sd-demo/evals/fixtures/mock-data-policy/src/components/Input.tsx +0 -25
  157. package/claude/skills/sd-demo/evals/fixtures/mock-data-policy/src/pages/.gitkeep +0 -0
  158. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/.specs/260503143025/REQ-001-RTP/354/236/205/353/240/245/355/231/224/353/251/264/spec.md +0 -19
  159. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/.specs/260503143025/REQ-002-RTP/354/266/234/353/240/245/355/231/224/353/251/264/spec.md +0 -20
  160. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/.specs/260503143025/overview.md +0 -16
  161. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/src/components/Button.tsx +0 -6
  162. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/src/components/Input.tsx +0 -15
  163. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/src/pages/.gitkeep +0 -0
  164. package/claude/skills/sd-demo/references/demo-md-template.md +0 -92
  165. package/claude/skills/sd-dev/evals/fixtures/multi-req-stop-after-spec/.docs/20260301_/352/263/240/352/260/235/354/202/254_/354/236/205/352/263/240/354/232/224/354/262/255.eml +0 -5
  166. package/claude/skills/sd-dev/evals/fixtures/multi-req-stop-after-spec/.docs/20260305_/352/263/240/352/260/235/354/202/254_/354/266/234/352/263/240/354/232/224/354/262/255.eml +0 -6
  167. package/claude/skills/sd-dev/evals/fixtures/multi-req-stop-after-spec/.docs/20260310_/352/263/240/352/260/235/354/202/254_/352/266/214/355/225/234.eml +0 -6
  168. package/claude/skills/sd-dev/evals/fixtures/single-req-auto-chain/src/lib/.gitkeep +0 -0
  169. package/claude/skills/sd-dev/evals/fixtures/start-from-plan/.specs/260503143025/REQ-001-/355/225/240/354/235/270/352/263/204/354/202/260/spec.md +0 -12
  170. package/claude/skills/sd-dev/evals/fixtures/start-from-plan/src/lib/.gitkeep +0 -0
  171. package/claude/skills/sd-impl/evals/fixtures/basic-single-r/.specs/260503143025/REQ-001-/354/236/205/352/263/240/354/247/200/354/213/234/354/204/234/352/270/264/352/270/211/355/221/234/354/213/234/plan.md +0 -28
  172. package/claude/skills/sd-impl/evals/fixtures/basic-single-r/.specs/260503143025/REQ-001-/354/236/205/352/263/240/354/247/200/354/213/234/354/204/234/352/270/264/352/270/211/355/221/234/354/213/234/spec.md +0 -14
  173. package/claude/skills/sd-impl/evals/fixtures/basic-single-r/src/components/Input.tsx +0 -6
  174. package/claude/skills/sd-impl/evals/fixtures/basic-single-r/src/pages/.gitkeep +0 -0
  175. package/claude/skills/sd-impl/evals/fixtures/multi-r/.specs/260503143025/REQ-001-/352/261/260/353/236/230/354/262/230/353/252/251/353/241/235/plan.md +0 -40
  176. package/claude/skills/sd-impl/evals/fixtures/multi-r/.specs/260503143025/REQ-001-/352/261/260/353/236/230/354/262/230/353/252/251/353/241/235/spec.md +0 -13
  177. package/claude/skills/sd-impl/evals/fixtures/multi-r/src/components/Input.tsx +0 -25
  178. package/claude/skills/sd-impl/evals/fixtures/multi-r/src/pages/.gitkeep +0 -0
  179. package/claude/skills/sd-impl/evals/fixtures/with-test-file/.specs/260503143025/REQ-001-/355/225/240/354/235/270/352/263/204/354/202/260/plan.md +0 -26
  180. package/claude/skills/sd-impl/evals/fixtures/with-test-file/.specs/260503143025/REQ-001-/355/225/240/354/235/270/352/263/204/354/202/260/spec.md +0 -12
  181. package/claude/skills/sd-impl/evals/fixtures/with-test-file/src/lib/.gitkeep +0 -0
  182. package/claude/skills/sd-impl/references/impl-md-template.md +0 -87
  183. package/claude/skills/sd-impl/references/modes-and-failure.md +0 -65
  184. package/claude/skills/sd-plan/SKILL.md +0 -130
  185. package/claude/skills/sd-plan/evals/fixtures/already-implemented/.specs/260503143025/REQ-001-/354/202/254/354/232/251/354/236/220/353/252/251/353/241/235/spec.md +0 -14
  186. package/claude/skills/sd-plan/evals/fixtures/already-implemented/src/api/user.ts +0 -13
  187. package/claude/skills/sd-plan/evals/fixtures/already-implemented/src/components/Input.tsx +0 -15
  188. package/claude/skills/sd-plan/evals/fixtures/already-implemented/src/pages/UserList.tsx +0 -29
  189. package/claude/skills/sd-plan/evals/fixtures/basic-greenfield/.specs/260503143025/REQ-001-/354/236/205/352/263/240/354/247/200/354/213/234/354/204/234/352/270/264/352/270/211/355/221/234/354/213/234/spec.md +0 -17
  190. package/claude/skills/sd-plan/evals/fixtures/basic-greenfield/src/components/Input.tsx +0 -6
  191. package/claude/skills/sd-plan/evals/fixtures/basic-greenfield/src/pages/.gitkeep +0 -0
  192. package/claude/skills/sd-plan/evals/fixtures/demo-built/.specs/260503143025/DEMO-001-/352/261/260/353/236/230/354/262/230/demo.md +0 -26
  193. package/claude/skills/sd-plan/evals/fixtures/demo-built/.specs/260503143025/REQ-001-/352/261/260/353/236/230/354/262/230/353/252/251/353/241/235/355/231/224/353/251/264/spec.md +0 -15
  194. package/claude/skills/sd-plan/evals/fixtures/demo-built/src/components/Input.tsx +0 -25
  195. package/claude/skills/sd-plan/evals/fixtures/demo-built/src/data/mock-customer.ts +0 -16
  196. package/claude/skills/sd-plan/evals/fixtures/demo-built/src/pages/CustomerList.tsx +0 -25
  197. package/claude/skills/sd-plan/evals/golden.jsonl +0 -3
  198. package/claude/skills/sd-plan/references/plan-md-template.md +0 -138
  199. package/claude/skills/sd-spec/evals/fixtures/bulk-multi-source/.docs/20260122_/352/263/240/352/260/235/354/202/254_/354/236/205/352/263/240/354/247/200/354/213/234/354/204/234/352/260/234/354/204/240/354/232/224/354/262/255.eml +0 -20
  200. package/claude/skills/sd-spec/evals/fixtures/bulk-multi-source/.docs/20260205_/352/263/240/352/260/235/354/202/254_/354/266/234/352/263/240/355/231/224/353/251/264/352/264/200/353/240/250.eml +0 -17
  201. package/claude/skills/sd-spec/evals/fixtures/bulk-multi-source/.docs/20260301_/352/263/240/352/260/235/354/202/254_/352/266/214/355/225/234/354/262/264/352/263/204.eml +0 -18
  202. package/claude/skills/sd-spec/evals/fixtures/conflict-detection/.docs/20260317_/352/263/240/352/260/235/354/202/254_/352/270/264/352/270/211/354/262/230/353/246/254/353/260/251/354/271/250.eml +0 -17
  203. package/claude/skills/sd-spec/evals/fixtures/conflict-detection/.docs//355/232/214/354/235/230/353/214/200/353/263/270_20260320.txt +0 -13
  204. package/claude/skills/sd-spec/evals/fixtures/direct-simple/.gitkeep +0 -0
  205. package/claude/skills/sd-spec/evals/fixtures/spec-md-input/.specs/260101120000/REQ-001-test/spec.md +0 -19
  206. package/claude/skills/sd-spec/evals/fixtures/spec-md-input/.specs/260101120000/overview.md +0 -18
  207. package/claude/skills/sd-spec/evals/golden.jsonl +0 -4
  208. package/claude/skills/sd-spec/references/overview-md-template.md +0 -89
  209. package/claude/skills/sd-spec/references/raw-input-handling.md +0 -96
  210. package/claude/skills/sd-verify/SKILL.md +0 -96
  211. package/claude/skills/sd-verify/evals/fixtures/all-satisfied/.specs/260503143025/REQ-001-/355/225/240/354/235/270/352/263/204/354/202/260/impl.md +0 -20
  212. package/claude/skills/sd-verify/evals/fixtures/all-satisfied/.specs/260503143025/REQ-001-/355/225/240/354/235/270/352/263/204/354/202/260/plan.md +0 -14
  213. package/claude/skills/sd-verify/evals/fixtures/all-satisfied/.specs/260503143025/REQ-001-/355/225/240/354/235/270/352/263/204/354/202/260/spec.md +0 -12
  214. package/claude/skills/sd-verify/evals/fixtures/all-satisfied/src/lib/discount.test.ts +0 -11
  215. package/claude/skills/sd-verify/evals/fixtures/all-satisfied/src/lib/discount.ts +0 -7
  216. package/claude/skills/sd-verify/evals/fixtures/partial-mismatch/.specs/260503143025/REQ-001-/354/202/254/354/232/251/354/236/220/353/252/251/353/241/235/impl.md +0 -21
  217. package/claude/skills/sd-verify/evals/fixtures/partial-mismatch/.specs/260503143025/REQ-001-/354/202/254/354/232/251/354/236/220/353/252/251/353/241/235/plan.md +0 -21
  218. package/claude/skills/sd-verify/evals/fixtures/partial-mismatch/.specs/260503143025/REQ-001-/354/202/254/354/232/251/354/236/220/353/252/251/353/241/235/spec.md +0 -12
  219. package/claude/skills/sd-verify/evals/fixtures/partial-mismatch/src/pages/UserList.tsx +0 -19
  220. package/claude/skills/sd-verify/evals/fixtures/tdd-only/.specs/260503143025/REQ-001-/352/270/210/354/225/241/352/262/200/354/246/235/impl.md +0 -19
  221. package/claude/skills/sd-verify/evals/fixtures/tdd-only/.specs/260503143025/REQ-001-/352/270/210/354/225/241/352/262/200/354/246/235/plan.md +0 -14
  222. package/claude/skills/sd-verify/evals/fixtures/tdd-only/.specs/260503143025/REQ-001-/352/270/210/354/225/241/352/262/200/354/246/235/spec.md +0 -12
  223. package/claude/skills/sd-verify/evals/fixtures/tdd-only/src/lib/validate-amount.test.ts +0 -10
  224. package/claude/skills/sd-verify/evals/fixtures/tdd-only/src/lib/validate-amount.ts +0 -7
  225. package/claude/skills/sd-verify/evals/golden.jsonl +0 -3
  226. package/claude/skills/sd-verify/references/verify-md-template.md +0 -99
  227. /package/claude/skills/{sd-demo/evals/fixtures/basic-single-req/src/pages → sd-wip/evals/fixtures/empty}/.gitkeep +0 -0
@@ -0,0 +1,112 @@
1
+ # @simplysm/core-browser
2
+
3
+ 브라우저 전용 보강 — `Element`/`HTMLElement` 프로토타입 확장(import 사이드 이펙트) + DOM/파일/네트워크/IndexedDB 헬퍼.
4
+
5
+ > 이 패키지를 import 만 해도 `Element`/`HTMLElement` 프로토타입이 확장된다. SSR 환경에서는 import 자체를 피한다.
6
+
7
+ ## 사용 트리거 인덱스
8
+
9
+ - **DOM 탐색/가시성** (`Element` 확장: `findAll`/`findFirst`/`prependChild`/`getParents`/`isOffsetElement`/`isVisible`) — DOM 트리 탐색·삽입·가시성 판정 필요 시.
10
+ - **포커스/탭 이동** (`Element` 확장: `findTabbableParent`/`findFirstTabbableChild`) — 키보드 포커스 흐름 제어 시.
11
+ - **레이아웃/스크롤** (`HTMLElement` 확장: `repaint`/`getRelativeOffset`/`scrollIntoViewIfNeeded`) — 드롭다운/팝업 위치 계산, 고정 헤더 가림 스크롤 보정 시.
12
+ - **클립보드/측정 헬퍼** (`copyElement`/`pasteToElement`/`getBounds`, `ElementBounds`) — copy/paste 이벤트 처리, 다수 요소 경계 일괄 측정 시.
13
+ - **파일 다이얼로그/다운로드** (`openFileDialog`/`downloadBlob`) — 파일 선택 UI, Blob 다운로드 트리거 시.
14
+ - **진행률 fetch** (`fetchUrlBytes`, `DownloadProgress`) — 큰 바이너리 다운로드 + 진행률 콜백 필요 시.
15
+ - **IndexedDB 저장소** (`IndexedDbStore`, `StoreConfig`) — 브라우저 영속 키/값 저장소 (트랜잭션 보장).
16
+ - **IndexedDB 가상 파일시스템** (`IndexedDbVirtualFs`, `VirtualFsEntry`) — `IndexedDbStore` 위에 경로(`/a/b/c`) 기반 파일/디렉토리 모델링.
17
+
18
+ ## DOM 탐색/가시성 — `Element` 확장
19
+
20
+ ```ts
21
+ el.findAll<T extends Element = Element>(selector: string): T[] // 빈 선택자 → []
22
+ el.findFirst<T extends Element = Element>(selector: string): T | undefined // 빈 선택자 → undefined
23
+ el.prependChild<T extends Element>(child: T): T // 첫 자식으로 삽입
24
+ el.getParents(): Element[] // 가까운 순서
25
+ el.isOffsetElement(): boolean // position: relative/absolute/fixed/sticky
26
+ el.isVisible(): boolean // clientRects 존재 + visibility != hidden + opacity != "0"
27
+ ```
28
+
29
+ ## 포커스/탭 이동 — `Element` 확장
30
+
31
+ ```ts
32
+ el.findTabbableParent(): HTMLElement | undefined // tabbable 라이브러리 사용
33
+ el.findFirstTabbableChild(): HTMLElement | undefined // TreeWalker로 첫 매치
34
+ ```
35
+
36
+ ## 레이아웃/스크롤 — `HTMLElement` 확장
37
+
38
+ ```ts
39
+ el.repaint(): void // offsetHeight 접근으로 강제 reflow
40
+ el.getRelativeOffset(parent: HTMLElement | string): { top; left } // CSS top/left 즉시 사용 가능. transform/border/스크롤 보정. 못 찾으면 ArgumentError
41
+ el.scrollIntoViewIfNeeded(target: { top; left }, offset?): void // 상단/좌측 가림만 보정. 하단/우측은 브라우저 기본
42
+ ```
43
+
44
+ `getRelativeOffset` 은 드롭다운/팝업의 absolute 위치 지정 표준 경로. `parent` 는 가장 가까운 offset parent 또는 selector.
45
+
46
+ ## 클립보드/측정 헬퍼
47
+
48
+ ```ts
49
+ function copyElement(event: ClipboardEvent): void // 대상 내 첫 input/textarea.value → clipboard
50
+ function pasteToElement(event: ClipboardEvent): void // clipboard → 첫 input/textarea.value 교체 + input 이벤트 dispatch
51
+ function getBounds(els: Element[], timeout = 5000): Promise<ElementBounds[]> // IntersectionObserver 기반. 입력 순서 유지. timeout 초과 시 TimeoutError
52
+
53
+ interface ElementBounds { target: Element; top: number; left: number; width: number; height: number; }
54
+ ```
55
+
56
+ `copyElement`/`pasteToElement` 는 `<element @copy=... @paste=...>` 이벤트 핸들러로 직결. 커서/선택 영역은 무시하고 전체 값 교체.
57
+
58
+ ## 파일 다이얼로그/다운로드
59
+
60
+ ```ts
61
+ function openFileDialog(options?: { accept?: string; multiple?: boolean }): Promise<File[] | undefined>
62
+ // 취소 시 undefined, 빈 선택 시 undefined.
63
+ function downloadBlob(blob: Blob, fileName: string): void
64
+ // 파일명: sanitize-filename + 대괄호 제거. 빈 결과는 "download". ObjectURL 1초 후 해제.
65
+ ```
66
+
67
+ ## 진행률 fetch
68
+
69
+ ```ts
70
+ interface DownloadProgress { receivedLength: number; contentLength: number; }
71
+ function fetchUrlBytes(url: string, options?: { onProgress?: (p: DownloadProgress) => void }): Promise<Uint8Array>
72
+ ```
73
+
74
+ `Content-Length` 가 있으면 사전 할당(메모리 효율) + 초과/부족 검출, 없으면 청크 수집 후 `bytes.concat`. HTTP 오류·본문 없음·길이 불일치는 모두 throw.
75
+
76
+ ## IndexedDB 저장소 — `IndexedDbStore`
77
+
78
+ ```ts
79
+ interface StoreConfig { name: string; keyPath: string; }
80
+
81
+ class IndexedDbStore {
82
+ constructor(dbName: string, dbVersion: number, storeConfigs: StoreConfig[]);
83
+ open(): Promise<IDBDatabase>; // versionchange/close 시 자동 무효화
84
+ withStore<R>(name, mode: IDBTransactionMode, fn: (s: IDBObjectStore) => Promise<R>): Promise<R>; // fn throw 시 tx.abort
85
+ get<T>(name, key: IDBValidKey): Promise<T | undefined>;
86
+ put(name, value): Promise<void>;
87
+ delete(name, key: IDBValidKey): Promise<void>;
88
+ getAll<T>(name): Promise<T[]>;
89
+ close(): void;
90
+ }
91
+ ```
92
+
93
+ `open()` 은 중복 호출 안전(병행 호출 단일화). `withStore` 의 `fn` 내부 에러는 트랜잭션 abort 후 원본 에러로 reject.
94
+
95
+ ## IndexedDB 가상 파일시스템 — `IndexedDbVirtualFs`
96
+
97
+ `IndexedDbStore` 위에 경로 키(`/a/b/c`) 기반 파일/디렉토리 모델. 데이터는 base64 문자열로 저장.
98
+
99
+ ```ts
100
+ interface VirtualFsEntry { kind: "file" | "dir"; dataBase64?: string; }
101
+
102
+ class IndexedDbVirtualFs {
103
+ constructor(db: IndexedDbStore, storeName: string, keyField: string);
104
+ getEntry(fullKey: string): Promise<VirtualFsEntry | undefined>;
105
+ putEntry(fullKey: string, kind: "file" | "dir", dataBase64?: string): Promise<void>;
106
+ deleteByPrefix(keyPrefix: string): Promise<boolean>; // 자기 자신 + "/" 하위 재귀 삭제
107
+ listChildren(prefix: string): Promise<{ name: string; isDirectory: boolean }[]>; // 직속 자식만, 중간 경로도 dir 로 노출
108
+ ensureDir(fullKeyBuilder: (path: string) => string, dirPath: string): Promise<void>; // 중간 디렉토리 모두 생성
109
+ }
110
+ ```
111
+
112
+ `fullKey`/`keyField`/`fullKeyBuilder` 분리로 멀티 테넌트(예: 사용자별 prefix) 키 스킴을 호출 측에서 결정.
@@ -0,0 +1,53 @@
1
+ # @simplysm/core-common
2
+
3
+ 공통 유틸리티(타입·에러·큐·이벤트·변환·확장 메서드·환경변수). simplysm 모든 패키지의 공용 기반.
4
+
5
+ ## 사용 트리거 인덱스
6
+
7
+ - **에러 클래스** — throw 시 트리 메시지/원인 체인 필요할 때. `SdError`, `ArgumentError`, `NotImplementedError`, `TimeoutError`.
8
+ - **날짜/시간/UUID/캐시 타입** — `DateTime`, `DateOnly`, `Time`, `Uuid`, `LazyGcMap` 사용 시. (자세히: [types.md](./types.md))
9
+ - **큐·이벤트 features** — 디바운스·직렬 큐, 타입 안전 EventEmitter. (자세히: [features.md](./features.md))
10
+ - **유틸리티 네임스페이스** — `obj`, `str`, `num`, `bytes`, `path`, `json`, `xml`, `wait`, `transfer`, `err`, `dt`, `primitive`. (자세히: [utils.md](./utils.md))
11
+ - **Array/Set/Map 전역 확장 메서드** — `.single()`, `.toMap()`, `.toTree()`, `.distinct()`, `Set.adds()`, `Map.getOrCreate()` 등. (자세히: [extensions.md](./extensions.md))
12
+ - **환경변수** — `env(key)`, `env(key, value)`, `parseBoolEnv(v)`. `process.env` 우선, fallback `import.meta.env`.
13
+ - **템플릿 문자열 태그** — IDE 하이라이팅 + indent trim. `js`, `ts`, `html`, `tsql`, `mysql`, `pgsql`. 동작은 모두 동일(문자열 결합 + 들여쓰기 정규화).
14
+ - **ZIP 처리** — `ZipArchive(data?)`: `get/exists/write/extractAll/compress/close`. 사용 후 반드시 `await archive.close()`.
15
+ - **공통 타입** — `Bytes` (= `Uint8Array`), `PrimitiveTypeMap/Str/Type` (string/number/boolean/DateTime/DateOnly/Time/Uuid/Bytes), `DeepPartial<T>`, `Type<T>` (생성자 타입).
16
+
17
+ ## 에러 클래스
18
+
19
+ ```typescript
20
+ new SdError(cause: Error, ...messages: string[])
21
+ new SdError(...messages: string[])
22
+ // 메시지는 역순 결합: "상위 => 하위 => 원인". cause stack을 현재 stack에 append.
23
+
24
+ new ArgumentError(argObj)
25
+ new ArgumentError(message, argObj)
26
+ // 인자 객체를 YAML 형식으로 메시지에 포함.
27
+
28
+ new NotImplementedError(message?) // "미구현: <message>"
29
+ new TimeoutError(count?, message?) // "대기 시간 초과(N회 시도): <message>". wait.until 에서 자동 throw.
30
+ ```
31
+
32
+ 모두 `SdError` 상속. `name` 자동 설정.
33
+
34
+ ## 환경변수
35
+
36
+ ```typescript
37
+ env("PORT") // string | undefined (process.env → import.meta.env)
38
+ env("PORT", "3000") // void (process.env 에 기록, process 없으면 무시)
39
+ parseBoolEnv(v) // "true"|"1"|"yes"|"on" → true (대소문자 무시)
40
+ ```
41
+
42
+ ## 템플릿 문자열 태그
43
+
44
+ ```typescript
45
+ import { js, ts, html, tsql, mysql, pgsql } from "@simplysm/core-common";
46
+
47
+ const code = ts`
48
+ interface User { name: string; }
49
+ `;
50
+ // → "interface User { name: string; }" (앞뒤 빈 줄·공통 들여쓰기 제거)
51
+ ```
52
+
53
+ 모두 동일 함수, IDE 하이라이팅 차별화 목적.
@@ -0,0 +1,123 @@
1
+ # @simplysm/core-common — extensions
2
+
3
+ `index.ts` 가 import 되면 자동으로 `Array.prototype`, `Set.prototype`, `Map.prototype` 에 메서드를 정의 (`enumerable: false`).
4
+
5
+ ## Array (Readonly — 새 배열/값 반환)
6
+
7
+ ### 조회
8
+
9
+ ```typescript
10
+ arr.single(pred?) // 0 or 1개. 2개 이상이면 ArgumentError. 없으면 undefined.
11
+ arr.first(pred?) // pred 면 find, 없으면 [0]
12
+ arr.last(pred?) // pred 면 역방향 find, 없으면 [length-1]
13
+ arr.filterExists() // null/undefined 제거 → NonNullable<T>[]
14
+ arr.ofType("string"|"number"|"boolean"|"DateTime"|"DateOnly"|"Time"|"Uuid"|"Bytes")
15
+ arr.ofType(SomeClass) // instanceof 또는 constructor 일치
16
+ ```
17
+
18
+ ### 비동기
19
+
20
+ ```typescript
21
+ await arr.filterAsync(asyncPred) // 순차
22
+ await arr.mapAsync(asyncSelector) // 순차
23
+ await arr.mapManyAsync(asyncSelector) // 순차 + 평탄화
24
+ await arr.parallelAsync(fn) // Promise.all (하나 reject 시 전체 reject)
25
+ ```
26
+
27
+ ### 매핑·평탄화
28
+
29
+ ```typescript
30
+ arr.mapMany() // 중첩 배열 1단계 flatten + filterExists
31
+ arr.mapMany(selector) // 매핑 후 flatten
32
+ ```
33
+
34
+ ### 변환
35
+
36
+ ```typescript
37
+ arr.groupBy(keyFn) // [{ key, values }, ...] (객체 key 시 O(n²), 원시 key 는 O(n))
38
+ arr.groupBy(keyFn, valueFn)
39
+ arr.toMap(keyFn) / toMap(keyFn, valFn) // 중복 key 시 ArgumentError
40
+ await arr.toMapAsync(...)
41
+ arr.toArrayMap(keyFn[, valFn]) // Map<K, V[]> (원시 key 권장 — O(n))
42
+ arr.toSetMap(keyFn[, valFn]) // Map<K, Set<V>>
43
+ arr.toMapValues(keyFn, (items) => aggregated)
44
+ arr.toObject(strKeyFn[, valFn]) // 중복 key 시 ArgumentError
45
+ arr.toTree("id", "parentId") // 평면 → 트리 ({...item, children: []}), O(n).
46
+ // parentKey 가 null/undefined 면 루트.
47
+ ```
48
+
49
+ ### 중복·정렬
50
+
51
+ ```typescript
52
+ arr.distinct() // 깊은 equal 비교 (객체 array 는 O(n²))
53
+ arr.distinct(true) // matchAddress: 참조 비교 (Set 기반, O(n))
54
+ arr.distinct({ matchAddress?, keyFn? }) // keyFn 권장 — O(n)
55
+ arr.orderBy(selector?) // 오름차순. string/number/DateTime/DateOnly/Time/undefined 지원
56
+ arr.orderByDesc(selector?)
57
+ arr.shuffle() // Fisher-Yates
58
+ ```
59
+
60
+ ### 비교·병합
61
+
62
+ ```typescript
63
+ arr.diffs(target) // INSERT/DELETE/UPDATE 결과
64
+ arr.diffs(target, { keys: ["id"], excludes? }) // key 기반 매칭 (Map 인덱싱 O(n+m))
65
+ arr.diffs(target, { excludes: [...] })
66
+ // 결과 타입:
67
+ // { source: undefined, target: T } // INSERT
68
+ // { source: T, target: undefined } // DELETE
69
+ // { source: T, target: T } // UPDATE
70
+
71
+ arr.oneWayDiffs(orgItems | Map, keyPropOrFn, {
72
+ includeSame?, excludes?, includes?,
73
+ })
74
+ // 결과: { type: "create"|"update"|"same", item, orgItem }
75
+
76
+ arr.merge(target[, { keys?, excludes? }]) // diffs 후 source 기반에 target 병합·신규 push
77
+ ```
78
+
79
+ ### 집계
80
+
81
+ ```typescript
82
+ arr.sum(selector?) // 숫자 아니면 ArgumentError. 빈 배열 → 0.
83
+ arr.min(selector?) / max(selector?) // string|number. 빈 배열 → undefined
84
+ ```
85
+
86
+ ### TreeArray 타입
87
+
88
+ ```typescript
89
+ type TreeArray<T> = T & { children: TreeArray<T>[] };
90
+ ```
91
+
92
+ ## Array (Mutable — 원본 변경, `@mutates`)
93
+
94
+ ```typescript
95
+ arr.distinctThis(options?) // 원본에서 중복 제거 (역순 splice, O(n))
96
+ arr.orderByThis(selector?) / orderByDescThis(selector?)
97
+ arr.insert(index, ...items)
98
+ arr.remove(itemOrSelector) // 일치 항목 모두 제거. 역순 순회.
99
+ arr.toggle(item) // 있으면 remove, 없으면 push
100
+ arr.clear()
101
+ ```
102
+
103
+ 모두 `this` 반환 (체이닝 가능, `clear/distinctThis/orderBy*This` 는 변경된 자기 자신).
104
+
105
+ ## Set
106
+
107
+ ```typescript
108
+ set.adds(...values) // 다중 add, this 반환
109
+ set.toggle(value) // 자동 토글
110
+ set.toggle(value, "add" | "del") // 강제 추가/제거
111
+ ```
112
+
113
+ ## Map
114
+
115
+ ```typescript
116
+ map.getOrCreate(key, defaultValue) // 없으면 set 후 반환
117
+ map.getOrCreate(key, () => expensiveCompute()) // 팩토리 (값이 함수이면 항상 호출됨 — 함수 값을 저장하려면 `() => fn` 으로 한 번 더 감쌀 것)
118
+ map.update(key, (v|undefined) => newV) // 없는 key 도 호출됨 (카운터·배열 push 패턴)
119
+ ```
120
+
121
+ ## ComparableType
122
+
123
+ `orderBy*` 의 selector 반환 타입: `string | number | boolean | DateTime | DateOnly | Time | undefined`.
@@ -0,0 +1,46 @@
1
+ # @simplysm/core-common — features
2
+
3
+ 비동기 큐와 타입 안전 이벤트 이미터.
4
+
5
+ ## EventEmitter\<TEvents\>
6
+
7
+ 브라우저·Node 공용 (내부 `EventTarget`). 타입 안전.
8
+
9
+ ```typescript
10
+ interface MyEvents { data: string; error: Error; done: void; }
11
+ class MyEmitter extends EventEmitter<MyEvents> {}
12
+
13
+ const e = new MyEmitter();
14
+ e.on("data", (d) => ...); // d: string
15
+ e.emit("data", "hello");
16
+ e.emit("done"); // void 이벤트는 인자 없이
17
+ e.off("data", handler);
18
+ e.listenerCount("data"); // 등록된 수
19
+ e.dispose(); // 모든 리스너 제거
20
+ ```
21
+
22
+ 같은 이벤트에 같은 리스너 중복 등록은 무시.
23
+
24
+ ## DebounceQueue extends EventEmitter\<{ error: SdError }\>
25
+
26
+ 연속 호출 중 마지막 작업만 실행.
27
+
28
+ ```typescript
29
+ const q = new DebounceQueue(300); // 300ms 지연 (생략 시 다음 이벤트 루프)
30
+ q.run(fn); // 이전 대기 함수 교체
31
+ q.on("error", (e) => ...); // 작업 throw 시. 리스너 없으면 logger.error
32
+ q.dispose(); // 타이머·대기 함수 정리
33
+ ```
34
+
35
+ 실행 도중 들어온 새 요청은 지연 없이 실행 완료 직후 즉시 처리 (놓침 방지).
36
+
37
+ ## SerialQueue extends EventEmitter\<{ error: SdError }\>
38
+
39
+ 순차 실행, 작업 사이 간격 옵션.
40
+
41
+ ```typescript
42
+ const q = new SerialQueue(0); // gap ms (기본 0)
43
+ q.run(asyncFn); // 큐에 추가, 자동 실행
44
+ q.on("error", ...); // 에러는 다음 작업에 영향 X (계속 실행)
45
+ q.dispose(); // 대기 큐 비움 (현재 작업은 완료됨)
46
+ ```
@@ -0,0 +1,114 @@
1
+ # @simplysm/core-common — types
2
+
3
+ 날짜·시간·UUID·만료 캐시 타입.
4
+
5
+ ## DateTime (불변)
6
+
7
+ 밀리초 정밀도, 로컬 타임존. 모든 변환/산술 메서드는 새 인스턴스 반환.
8
+
9
+ ```typescript
10
+ new DateTime() // 현재
11
+ new DateTime(year, month, day, h?, m?, s?, ms?) // month 는 1-12
12
+ new DateTime(tick) // ms epoch
13
+ new DateTime(date) // Date 복사
14
+ DateTime.parse(str) // "yyyy-MM-dd HH:mm:ss" / "yyyyMMddHHmmss" /
15
+ // "yyyy-MM-dd AM|PM HH:mm:ss" / "오전|오후" / ISO 8601
16
+ // 실패 시 ArgumentError
17
+ ```
18
+
19
+ Getters: `year/month/day/hour/minute/second/millisecond/tick/dayOfWeek/timezoneOffsetMinutes/isValid` (month 는 1-12, dayOfWeek 는 0-6 일~토).
20
+
21
+ 변환: `setYear/setMonth/setDay/setHour/setMinute/setSecond/setMillisecond` — 새 인스턴스. `setMonth` 는 대상 월 일수 초과 시 마지막 일로 클램프. `setDay` 는 JS Date 동작에 따라 월 경계 자동 조정.
22
+
23
+ 산술: `addYears/addMonths/addDays/addHours/addMinutes/addSeconds/addMilliseconds`.
24
+
25
+ 포맷: `toFormatString(formatStr)` ([date-format 토큰](#date-format-토큰)). `toString()` = `"yyyy-MM-ddTHH:mm:ss.fffzzz"`.
26
+
27
+ ## DateOnly (불변)
28
+
29
+ 날짜만(yyyy-MM-dd), 로컬 타임존.
30
+
31
+ ```typescript
32
+ new DateOnly() // 오늘
33
+ new DateOnly(year, month, day)
34
+ new DateOnly(tick) / new DateOnly(date)
35
+ DateOnly.parse(str) // "yyyy-MM-dd" / "yyyyMMdd" (타임존 무관) /
36
+ // ISO 8601 (UTC → 로컬 변환). 실패 시 ArgumentError
37
+ ```
38
+
39
+ Getters: `year/month/day/tick/dayOfWeek/isValid`.
40
+ 변환·산술: `setYear/setMonth/setDay`, `addYears/addMonths/addDays`.
41
+ 포맷: `toFormatString`, `toString()` = `"yyyy-MM-dd"`.
42
+
43
+ 주차 API (ISO 8601 기본: 월요일 시작, 첫 주 최소 4일):
44
+
45
+ ```typescript
46
+ d.getWeekSeqOfYear(weekStartDay=1, minDaysInFirstWeek=4) // { year, weekSeq }
47
+ d.getWeekSeqOfMonth(...) // { year, monthSeq, weekSeq }
48
+ d.getWeekSeqStartDate(...) // DateOnly
49
+ d.getBaseYearMonthSeqForWeekSeq(...) // { year, monthSeq }
50
+ DateOnly.getDateByYearWeekSeq({ year, month?, weekSeq }, ...) // 해당 주 시작일
51
+ ```
52
+
53
+ ## Time (불변)
54
+
55
+ 시간만(HH:mm:ss.fff). 24h 순환 — 음수/24h+ 자동 정규화.
56
+
57
+ ```typescript
58
+ new Time() // 현재 시각의 시간 부분
59
+ new Time(hour, minute, second?, ms?)
60
+ new Time(tick) / new Time(date)
61
+ Time.parse(str) // "HH:mm:ss[.fff]" / "AM|PM HH:mm:ss[.fff]" / ISO 8601 시간 부분
62
+ ```
63
+
64
+ Getters/Setters/Add 메서드는 DateTime 시간부와 유사. `addHours/Minutes/Seconds/Milliseconds` 는 24h 순환.
65
+
66
+ ## Uuid
67
+
68
+ UUID v4, `crypto.getRandomValues` 기반.
69
+
70
+ ```typescript
71
+ Uuid.generate() // 새 v4
72
+ new Uuid("xxxxxxxx-...") // 형식 검증, 실패 시 ArgumentError
73
+ Uuid.fromBytes(bytes16) // 16바이트 → Uuid (길이 ≠ 16 시 ArgumentError)
74
+ u.toString() // "xxxxxxxx-xxxx-..."
75
+ u.toBytes() // 16바이트 Uint8Array
76
+ ```
77
+
78
+ ## LazyGcMap
79
+
80
+ LRU 자동 만료 Map. **사용 후 반드시 `dispose()` 호출** — 안 하면 GC 타이머가 살아 메모리 누수.
81
+
82
+ ```typescript
83
+ const m = new LazyGcMap<K, V>({
84
+ expireTime: 60_000, // 마지막 접근 이후 ms
85
+ gcInterval?: 6_000, // 기본: expireTime/10, 최소 1000ms
86
+ onExpire?: (k, v) => ... , // 비동기 가능, 에러는 로그
87
+ });
88
+
89
+ m.size; m.has(k); m.get(k); m.set(k, v); m.delete(k); m.clear(); m.dispose();
90
+ m.getOrCreate(k, factory); // dispose 후 호출 시 throw
91
+ m.keys() / m.values() / m.entries(); // Iterator
92
+ ```
93
+
94
+ `get`/`getOrCreate` 만 접근시간 갱신(LRU). `has` 는 갱신 X. GC 실행 중 같은 key 재등록 시 새 항목 보존.
95
+
96
+ ## date-format 토큰
97
+
98
+ `DateTime/DateOnly/Time#toFormatString(formatStr)` 에서 사용. C# 호환.
99
+
100
+ | 토큰 | 의미 | 예 |
101
+ |------|------|----|
102
+ | `yyyy`/`yy` | 연도 4/2자리 | 2024 / 24 |
103
+ | `MM`/`M` | 월 패딩/미패딩 | 01 / 1 |
104
+ | `ddd` | 한글 요일 | 일~토 |
105
+ | `dd`/`d` | 일 패딩/미패딩 | 01 / 1 |
106
+ | `tt` | AM/PM | AM |
107
+ | `hh`/`h` | 12시간 패딩/미패딩 | 01 / 1 |
108
+ | `HH`/`H` | 24시간 패딩/미패딩 | 14 / 14 |
109
+ | `mm`/`m` | 분 | 30 / 30 |
110
+ | `ss`/`s` | 초 | 45 / 45 |
111
+ | `fff`/`ff`/`f` | 밀리초 3/2/1자리 | 123 / 12 / 1 |
112
+ | `zzz`/`zz`/`z` | 타임존 ±HH:mm / ±HH / ±H | +09:00 |
113
+
114
+ 긴 토큰이 먼저 매칭 → 부분 매칭 방지.
@@ -0,0 +1,158 @@
1
+ # @simplysm/core-common — utils
2
+
3
+ 네임스페이스 import: `import { obj, str, num, bytes, path, json, xml, wait, transfer, err, dt, primitive } from "@simplysm/core-common";`
4
+
5
+ ## obj — 객체 조작
6
+
7
+ ### 복사·비교·병합
8
+
9
+ ```typescript
10
+ obj.clone(src) // 깊은 복사. 순환 참조·DateTime/DateOnly/Time/Uuid/
11
+ // Uint8Array/Date/RegExp/Error(cause)/Map/Set 지원.
12
+ // 함수/Symbol 은 참조 유지, WeakMap/WeakSet 미지원.
13
+ obj.equal(a, b, opt?) // 깊은 동등. opt: { topLevelIncludes?, topLevelExcludes?,
14
+ // ignoreArrayIndex?, shallow? }
15
+ // include/exclude 는 최상위 객체 키에만 적용. shallow=true 면 1단계 참조 비교.
16
+ obj.merge(source, target, opt?) // 깊은 병합 (불변, 새 객체). opt:
17
+ // { arrayProcess?: "replace"|"concat", useDelTargetNull? }
18
+ obj.merge3(source, origin, target, optionsObj?) // 3-way merge. { conflict, result }
19
+ // optionsObj 는 key별 { keys?, excludes?, ignoreArrayIndex? }
20
+ ```
21
+
22
+ ### 키 조작
23
+
24
+ ```typescript
25
+ obj.omit(o, ["k1","k2"])
26
+ obj.omitByFilter(o, (k) => k.startsWith("_"))
27
+ obj.pick(o, ["k1","k2"])
28
+ obj.keys(o) / obj.entries(o) / obj.fromEntries(pairs) // 타입 안전 Object.* 래퍼
29
+ obj.map(o, (k, v) => [newK | null, newV]) // entry 변환 (newK=null 이면 원래 키 유지)
30
+ ```
31
+
32
+ ### 체인 경로 (`"a.b[0].c"` 형식)
33
+
34
+ ```typescript
35
+ obj.getChainValue(o, "a.b[0].c")
36
+ obj.getChainValue(o, "a.b[0].c", true) // optional: 중간 null 만나면 undefined
37
+ obj.setChainValue(o, "a.b.c", v) // 중간 객체 자동 생성
38
+ obj.deleteChainValue(o, "a.b.c")
39
+ obj.getChainValueByDepth(o, key, depth, optional?) // 같은 key 로 N단계 하강
40
+ ```
41
+
42
+ ### 변환 (원본 변형 — `@mutates`)
43
+
44
+ ```typescript
45
+ obj.clearUndefined(o) // null/undefined 값 키 제거
46
+ obj.clear(o) // 모든 키 제거
47
+ obj.nullToUndefined(o) // 재귀, null → undefined
48
+ obj.unflatten({ "a.b.c": 1 }) // → { a: { b: { c: 1 } } }
49
+ ```
50
+
51
+ ### 타입 유틸
52
+
53
+ ```typescript
54
+ obj.UndefToOptional<T> // { a: string|undefined } → { a?: string|undefined }
55
+ obj.OptionalToUndef<T> // { a?: string } → { a: string|undefined }
56
+ ```
57
+
58
+ ## str — 문자열
59
+
60
+ ```typescript
61
+ str.getKoreanSuffix(text, "을"|"은"|"이"|"와"|"랑"|"로"|"라")
62
+ // 받침 유무로 조사 결정. "로" 는 ㄹ 받침이면 "로".
63
+ str.replaceFullWidth(s) // 전각 영숫자/공백/괄호 → 반각
64
+ str.toPascalCase(s) / toCamelCase(s) / toKebabCase(s) / toSnakeCase(s)
65
+ // case 함수는 기존 -/_ 구분자 보존, 연속 대문자 개별 분리 ("XMLParser" → "x-m-l-parser")
66
+ str.isNullOrEmpty(s) // null|undefined|"" 타입 가드
67
+ str.insert(s, idx, insertStr)
68
+ ```
69
+
70
+ ## num — 숫자
71
+
72
+ ```typescript
73
+ num.parseInt(text) // 비숫자 제거 후 정수 파싱. 선행 - 만 음수 부호, 중간 - 제거. 소수점은 trunc.
74
+ num.parseFloat(text)
75
+ num.parseRoundedInt(text) // float 후 반올림
76
+ num.isNullOrEmpty(v) // null|undefined|0 타입 가드
77
+ num.format(v, { max?, min? }) // 천 단위 + 소수점 자릿수. toLocaleString 기반
78
+ ```
79
+
80
+ ## bytes — Uint8Array
81
+
82
+ ```typescript
83
+ bytes.concat([a, b, ...])
84
+ bytes.toHex(u8) / bytes.fromHex(hex) // 소문자 hex. 홀수 길이/잘못된 문자 시 ArgumentError
85
+ bytes.toBase64(u8) / bytes.fromBase64(b64) // 표준 base64 (+/, = 패딩). 공백 자동 제거
86
+ ```
87
+
88
+ ## path — POSIX 경로 (브라우저용)
89
+
90
+ ```typescript
91
+ path.join(...segs) // 슬래시만 지원, 백슬래시 X
92
+ path.basename(p, ext?)
93
+ path.extname(p) // 숨김 파일(".gitignore")은 빈 문자열
94
+ ```
95
+
96
+ ## json — 커스텀 타입 지원 JSON
97
+
98
+ ```typescript
99
+ json.stringify(obj, { space?, replacer?, redactBytes? })
100
+ // Date/DateTime/DateOnly/Time/Uuid/Set/Map/Error/Uint8Array 를 { __type__, data } 로.
101
+ // redactBytes=true 면 Uint8Array 내용을 "__hidden__"로 (parse 복원 불가).
102
+ // 순환 참조 시 TypeError. 전역 prototype 미수정 (Worker 안전).
103
+ json.parse<T>(str) // __type__ 마커 복원. 모든 null → undefined (simplysm null-free 규칙).
104
+ // 에러 시 SdError. DEV 환경에서만 메시지에 전체 JSON 포함.
105
+ ```
106
+
107
+ ## xml — fast-xml-parser 래퍼
108
+
109
+ ```typescript
110
+ xml.parse(str, { stripTagPrefix? })
111
+ // 결과: 속성은 `$` 객체, 텍스트는 `_` 키, 자식 요소는 배열 (루트 제외).
112
+ // stripTagPrefix=true 면 "ns:tag" → "tag" (속성은 유지).
113
+ xml.stringify(obj, options?) // fast-xml-parser XmlBuilderOptions
114
+ ```
115
+
116
+ ## wait — 대기
117
+
118
+ ```typescript
119
+ await wait.time(ms)
120
+ await wait.until(() => cond, intervalMs=100, maxCount?) // maxCount 초과 시 TimeoutError
121
+ ```
122
+
123
+ ## transfer — Worker 전송
124
+
125
+ `structuredClone` 미지원 타입 처리. Date/DateTime/DateOnly/Time/Uuid/RegExp/Error(cause/code/detail)/Uint8Array/Map/Set/Array/Object.
126
+
127
+ ```typescript
128
+ const { result, transferList } = transfer.encode(data);
129
+ worker.postMessage(result, transferList); // Uint8Array.buffer 가 transferList 에 zero-copy
130
+ const decoded = transfer.decode(event.data);
131
+ ```
132
+
133
+ 순환 참조 시 `TypeError("순환 참조 감지됨: <path>")`. 같은 객체 다중 참조는 인코딩 결과 캐싱.
134
+
135
+ ## err — 에러 메시지
136
+
137
+ ```typescript
138
+ err.message(unknownErr) // Error 면 .message, 아니면 String(err)
139
+ ```
140
+
141
+ ## dt — date-format 저수준
142
+
143
+ `DateTime/DateOnly/Time#toFormatString` 내부에서 사용. 직접 사용 드묾.
144
+
145
+ ```typescript
146
+ dt.format(formatStr, { year?, month?, day?, hour?, minute?, second?, millisecond?, timezoneOffsetMinutes? })
147
+ // 토큰은 types.md 의 "date-format 토큰" 참조
148
+ dt.normalizeMonth(year, month, day) // 월 1-12 정규화 + 일 클램프
149
+ dt.convert12To24(rawHour, isPM) // 12시간 → 24시간
150
+ ```
151
+
152
+ ## primitive — 런타임 타입 추론
153
+
154
+ ```typescript
155
+ primitive.typeStr(value)
156
+ // string/number/boolean/DateTime/DateOnly/Time/Uuid/Bytes 중 하나 반환.
157
+ // 미지원 타입은 ArgumentError.
158
+ ```
@@ -0,0 +1,12 @@
1
+ ## @simplysm/core-node
2
+
3
+ Node.js 전용 유틸·기능 묶음. 파일 IO/glob, 경로 변환, 자식 프로세스 spawn, 파일 시스템 감시, consola 리포터 셋업, worker_threads 타입 안전 래퍼.
4
+
5
+ ## 사용 트리거 인덱스
6
+
7
+ - **`fsx` 네임스페이스** — 파일/디렉토리 존재 확인·생성·복사·삭제·읽기·쓰기·JSON·glob·재귀 유틸. 자세히: [fsx.md](./fsx.md)
8
+ - **`pathx` 네임스페이스** — POSIX 경로 변환, 하위 경로 판정, 디렉토리 치환, target 필터링. 자세히: [pathx.md](./pathx.md)
9
+ - **`cpx` 네임스페이스** — 시스템 인코딩 감지 + 자식 프로세스 spawn/spawnSync (인코딩 자동 디코딩, exitCode 기반 reject). 자세히: [cpx.md](./cpx.md)
10
+ - **`FsWatcher`** — chokidar 기반 디바운스/이벤트 병합 + Windows EPERM 자동 복구 파일 감시. 자세히: [fs-watcher.md](./fs-watcher.md)
11
+ - **`setupConsola` / `PrettyReporter` / `createFileReporter` / `withMaxLevel`** — Node 앱 consola 셋업, 컬러 콘솔/JSON 파일 회전 리포터. 자세히: [consola.md](./consola.md)
12
+ - **`Worker` / `createWorker` / `WorkerProxy` / `WorkerModule` / `PromisifyMethods`** — worker_threads 위 타입 안전 RPC 래퍼 (메서드 호출 + 이벤트 send/on). 자세히: [worker.md](./worker.md)