@simplysm/sd-claude 14.0.65 → 14.0.68

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 (241) 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} +134 -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 +191 -79
  70. package/claude/scripts/sd_paths.py +22 -0
  71. package/claude/sd-check-bash.py +19 -0
  72. package/claude/sd-statusline.py +7 -12
  73. package/claude/skills/sd-commit/SKILL.md +8 -3
  74. package/claude/skills/sd-demo/SKILL.md +103 -62
  75. package/claude/skills/sd-demo/evals/fixtures/empty/.specs/260513120000_warehouse/spec.md +45 -0
  76. package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/.specs/260513120000_warehouse/spec.md +42 -0
  77. package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  78. package/claude/skills/sd-demo/evals/fixtures/with-master-screen/.specs/260513120000_warehouse/spec.md +45 -0
  79. package/claude/skills/sd-demo/evals/fixtures/with-master-screen/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  80. package/claude/skills/sd-demo/evals/fixtures/with-modal/.specs/260513120000_warehouse/spec.md +75 -0
  81. package/claude/skills/sd-demo/evals/fixtures/with-modal/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  82. package/claude/skills/sd-demo/evals/fixtures/with-screens/.specs/260513120000_warehouse/spec.md +45 -0
  83. package/claude/skills/sd-demo/evals/fixtures/with-screens/packages/app/src/screens/dashboard/dashboard.view.ts +33 -0
  84. package/claude/skills/sd-demo/evals/golden.jsonl +5 -3
  85. package/claude/skills/sd-dev/SKILL.md +33 -63
  86. package/claude/skills/sd-dev/evals/fixtures/case-add/package.json +13 -0
  87. package/claude/skills/sd-dev/evals/fixtures/case-add/src/index.ts +10 -0
  88. package/claude/skills/sd-dev/evals/fixtures/case-add/tests/index.test.ts +11 -0
  89. package/claude/skills/sd-dev/evals/fixtures/case-add/tsconfig.json +12 -0
  90. package/claude/skills/sd-dev/evals/fixtures/case-bug/package.json +13 -0
  91. package/claude/skills/sd-dev/evals/fixtures/case-bug/src/index.ts +10 -0
  92. package/claude/skills/sd-dev/evals/fixtures/case-bug/tests/index.test.ts +11 -0
  93. package/claude/skills/sd-dev/evals/fixtures/case-bug/tsconfig.json +12 -0
  94. package/claude/skills/sd-dev/evals/fixtures/case-modify/package.json +13 -0
  95. package/claude/skills/sd-dev/evals/fixtures/case-modify/src/index.ts +10 -0
  96. package/claude/skills/sd-dev/evals/fixtures/case-modify/tests/index.test.ts +11 -0
  97. package/claude/skills/sd-dev/evals/fixtures/case-modify/tsconfig.json +12 -0
  98. package/claude/skills/sd-dev/evals/golden.jsonl +3 -3
  99. package/claude/skills/sd-docs/SKILL.md +53 -0
  100. package/claude/skills/sd-docs/evals/fixtures/new-write/.claude/references/sd-simplysm14/README.md +7 -0
  101. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/package.json +5 -0
  102. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/bar/src/index.ts +3 -0
  103. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/package.json +6 -0
  104. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/baz/src/index.ts +1 -0
  105. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/package.json +5 -0
  106. package/claude/skills/sd-docs/evals/fixtures/new-write/packages/foo/src/index.ts +8 -0
  107. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/README.md +7 -0
  108. package/claude/skills/sd-docs/evals/fixtures/update-mixed/.claude/references/sd-simplysm14/apis/foo/README.md +3 -0
  109. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/package.json +5 -0
  110. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/bar/src/index.ts +3 -0
  111. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/package.json +6 -0
  112. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/baz/src/index.ts +1 -0
  113. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/package.json +5 -0
  114. package/claude/skills/sd-docs/evals/fixtures/update-mixed/packages/foo/src/index.ts +8 -0
  115. package/claude/skills/sd-docs/evals/golden.jsonl +2 -0
  116. package/claude/skills/sd-docs/references/subagent-prompt.md +100 -0
  117. package/claude/skills/sd-impl/SKILL.md +149 -46
  118. package/claude/skills/sd-impl/evals/fixtures/case-001-new-screen/spec.md +55 -0
  119. package/claude/skills/sd-impl/evals/fixtures/case-002-auto-process/spec.md +55 -0
  120. package/claude/skills/sd-impl/evals/fixtures/case-003-update-screen/packages/client/src/pages/book-list.ts +22 -0
  121. package/claude/skills/sd-impl/evals/fixtures/case-003-update-screen/spec.md +57 -0
  122. package/claude/skills/sd-impl/evals/fixtures/case-004-ambiguous-spec/spec.md +58 -0
  123. package/claude/skills/sd-impl/evals/fixtures/case-005-id-mismatch/spec.md +52 -0
  124. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/client/src/pages//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.test.ts +10 -0
  125. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/client/src/pages//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.ts +11 -0
  126. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/server/src/data-access//352/261/260/353/236/230/354/262/230-/354/240/221/352/267/274.ts +12 -0
  127. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/server/src/models//352/261/260/353/236/230/354/262/230.ts +8 -0
  128. package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/spec.md +77 -0
  129. package/claude/skills/sd-impl/evals/fixtures/case-new/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +101 -0
  130. package/claude/skills/sd-impl/evals/fixtures/case-update/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +101 -0
  131. 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
  132. 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
  133. package/claude/skills/sd-impl/evals/golden.jsonl +6 -3
  134. package/claude/skills/sd-impl/references/spec-cross-check.md +82 -0
  135. package/claude/skills/sd-skill/SKILL.md +4 -4
  136. package/claude/skills/sd-skill/evals/golden.jsonl +1 -2
  137. package/claude/skills/sd-skill/references/eval-authoring.md +31 -0
  138. package/claude/skills/sd-skill/references/eval-run.md +1 -1
  139. package/claude/skills/sd-skill/references/skill-authoring.md +8 -5
  140. package/claude/skills/sd-skill/scripts/run_eval.py +39 -60
  141. package/claude/skills/sd-spec/SKILL.md +163 -105
  142. package/claude/skills/sd-spec/references/example-spec.md +585 -0
  143. package/claude/skills/sd-spec/references/spec-authoring.md +287 -0
  144. package/claude/skills/sd-spec/references/spec-md-template.md +15 -93
  145. package/claude/skills/sd-unpack/SKILL.md +7 -1
  146. package/claude/skills/sd-unpack/scripts/handlers/_common.py +10 -0
  147. package/claude/skills/sd-unpack/scripts/handlers/eml_handler.py +5 -13
  148. package/claude/skills/sd-unpack/scripts/handlers/msg_handler.py +3 -12
  149. package/claude/skills/sd-unpack/scripts/handlers/office_com.py +23 -37
  150. package/claude/skills/sd-unpack/scripts/handlers/office_worker.py +1 -4
  151. package/claude/skills/sd-unpack/scripts/handlers/pdf_handler.py +4 -13
  152. package/claude/skills/sd-unpack/scripts/unpack.py +4 -4
  153. package/claude/skills/sd-use/SKILL.md +1 -0
  154. package/claude/skills/sd-wip/SKILL.md +38 -0
  155. package/claude/skills/sd-wip/evals/fixtures/with-artifact/projects/acct/_wip.md +3 -0
  156. package/claude/skills/sd-wip/evals/fixtures/with-artifact/projects/acct/spec.md +15 -0
  157. package/claude/skills/sd-wip/evals/fixtures/with-existing-wip/.wips/260101120000_acct.md +6 -0
  158. package/claude/skills/sd-wip/evals/fixtures/with-existing-wip-for-compact/.wips/260101120000_acct.md +14 -0
  159. package/claude/skills/sd-wip/evals/golden.jsonl +4 -0
  160. package/claude/skills/sd-wip/references/compact.md +79 -0
  161. package/package.json +1 -1
  162. package/scripts/sd-entries.mjs +2 -2
  163. package/claude/references/sd-simplysm14/orm.md +0 -11
  164. 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
  165. package/claude/skills/sd-demo/evals/fixtures/basic-single-req/.specs/260503143025/overview.md +0 -12
  166. package/claude/skills/sd-demo/evals/fixtures/basic-single-req/src/components/Button.tsx +0 -12
  167. package/claude/skills/sd-demo/evals/fixtures/basic-single-req/src/components/Input.tsx +0 -27
  168. 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
  169. package/claude/skills/sd-demo/evals/fixtures/mock-data-policy/.specs/260503143025/overview.md +0 -12
  170. package/claude/skills/sd-demo/evals/fixtures/mock-data-policy/src/components/Input.tsx +0 -25
  171. package/claude/skills/sd-demo/evals/fixtures/mock-data-policy/src/pages/.gitkeep +0 -0
  172. 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
  173. 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
  174. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/.specs/260503143025/overview.md +0 -16
  175. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/src/components/Button.tsx +0 -6
  176. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/src/components/Input.tsx +0 -15
  177. package/claude/skills/sd-demo/evals/fixtures/multi-req-domain/src/pages/.gitkeep +0 -0
  178. package/claude/skills/sd-demo/references/demo-md-template.md +0 -92
  179. 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
  180. 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
  181. 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
  182. package/claude/skills/sd-dev/evals/fixtures/single-req-auto-chain/src/lib/.gitkeep +0 -0
  183. 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
  184. package/claude/skills/sd-dev/evals/fixtures/start-from-plan/src/lib/.gitkeep +0 -0
  185. 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
  186. 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
  187. package/claude/skills/sd-impl/evals/fixtures/basic-single-r/src/components/Input.tsx +0 -6
  188. package/claude/skills/sd-impl/evals/fixtures/basic-single-r/src/pages/.gitkeep +0 -0
  189. 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
  190. 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
  191. package/claude/skills/sd-impl/evals/fixtures/multi-r/src/components/Input.tsx +0 -25
  192. package/claude/skills/sd-impl/evals/fixtures/multi-r/src/pages/.gitkeep +0 -0
  193. 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
  194. 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
  195. package/claude/skills/sd-impl/evals/fixtures/with-test-file/src/lib/.gitkeep +0 -0
  196. package/claude/skills/sd-impl/references/impl-md-template.md +0 -87
  197. package/claude/skills/sd-impl/references/modes-and-failure.md +0 -65
  198. package/claude/skills/sd-plan/SKILL.md +0 -130
  199. 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
  200. package/claude/skills/sd-plan/evals/fixtures/already-implemented/src/api/user.ts +0 -13
  201. package/claude/skills/sd-plan/evals/fixtures/already-implemented/src/components/Input.tsx +0 -15
  202. package/claude/skills/sd-plan/evals/fixtures/already-implemented/src/pages/UserList.tsx +0 -29
  203. 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
  204. package/claude/skills/sd-plan/evals/fixtures/basic-greenfield/src/components/Input.tsx +0 -6
  205. package/claude/skills/sd-plan/evals/fixtures/basic-greenfield/src/pages/.gitkeep +0 -0
  206. 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
  207. 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
  208. package/claude/skills/sd-plan/evals/fixtures/demo-built/src/components/Input.tsx +0 -25
  209. package/claude/skills/sd-plan/evals/fixtures/demo-built/src/data/mock-customer.ts +0 -16
  210. package/claude/skills/sd-plan/evals/fixtures/demo-built/src/pages/CustomerList.tsx +0 -25
  211. package/claude/skills/sd-plan/evals/golden.jsonl +0 -3
  212. package/claude/skills/sd-plan/references/plan-md-template.md +0 -138
  213. 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
  214. 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
  215. 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
  216. 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
  217. 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
  218. package/claude/skills/sd-spec/evals/fixtures/direct-simple/.gitkeep +0 -0
  219. package/claude/skills/sd-spec/evals/fixtures/spec-md-input/.specs/260101120000/REQ-001-test/spec.md +0 -19
  220. package/claude/skills/sd-spec/evals/fixtures/spec-md-input/.specs/260101120000/overview.md +0 -18
  221. package/claude/skills/sd-spec/evals/golden.jsonl +0 -4
  222. package/claude/skills/sd-spec/references/overview-md-template.md +0 -89
  223. package/claude/skills/sd-spec/references/raw-input-handling.md +0 -96
  224. package/claude/skills/sd-verify/SKILL.md +0 -96
  225. 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
  226. 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
  227. 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
  228. package/claude/skills/sd-verify/evals/fixtures/all-satisfied/src/lib/discount.test.ts +0 -11
  229. package/claude/skills/sd-verify/evals/fixtures/all-satisfied/src/lib/discount.ts +0 -7
  230. 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
  231. 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
  232. 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
  233. package/claude/skills/sd-verify/evals/fixtures/partial-mismatch/src/pages/UserList.tsx +0 -19
  234. 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
  235. 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
  236. 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
  237. package/claude/skills/sd-verify/evals/fixtures/tdd-only/src/lib/validate-amount.test.ts +0 -10
  238. package/claude/skills/sd-verify/evals/fixtures/tdd-only/src/lib/validate-amount.ts +0 -7
  239. package/claude/skills/sd-verify/evals/golden.jsonl +0 -3
  240. package/claude/skills/sd-verify/references/verify-md-template.md +0 -99
  241. /package/claude/skills/{sd-demo/evals/fixtures/basic-single-req/src/pages → sd-wip/evals/fixtures/empty}/.gitkeep +0 -0
@@ -0,0 +1,64 @@
1
+ ## @simplysm/core-node — consola
2
+
3
+ `consola` 전역 인스턴스 셋업 + 컬러 콘솔 리포터 + JSON 파일 회전 리포터. Node 앱(서버·CLI) 진입점에서 `setupConsola()` 1회 호출하면 환경에 맞게 reporter 가 구성됨.
4
+
5
+ ### setupConsola
6
+
7
+ ```ts
8
+ interface SetupConsolaOptions { cli?: boolean; }
9
+ setupConsola(opts?: SetupConsolaOptions): void;
10
+ ```
11
+
12
+ - `cli: true` 또는 `env.DEV` 가 truthy → dev 모드.
13
+ - `SD_DEBUG` truthy: `PrettyReporter` 하나만, debug 까지.
14
+ - 아니면: `createFileReporter()` + `withMaxLevel(new PrettyReporter(), LogLevels.info)` — 파일에는 debug 까지, 콘솔에는 info 이상만.
15
+ - 그 외 (prod): `createFileReporter()` 하나만, debug 까지.
16
+
17
+ 모든 경로에서 `consola.level = LogLevels.debug`.
18
+
19
+ ### PrettyReporter
20
+
21
+ ```ts
22
+ class PrettyReporter implements ConsolaReporter {}
23
+ ```
24
+
25
+ - 색상 자동 감지: `NO_COLOR` 있으면 off, `FORCE_COLOR` 있으면 on, TTY 면 on, win32 면 on.
26
+ - 타입별 아이콘/색 (info=cyan, success/ready=green, warn=yellow, error/fatal/fail=red, start=magenta, debug=gear, trace=arrow).
27
+ - `logObj.type === "box"` 면 `> tag`, `> title`, `> 각 줄` 형태로 박스 렌더.
28
+ - `logObj.tag !== ""` 면 `[tag]` 가 회색으로 prefix.
29
+ - level < 2 (error/fatal/warn) 는 `stderr`, 그 외 `stdout` 으로 출력. 추가로 badge 처리(앞뒤 빈 줄).
30
+ - args 중 `Error.stack` 가진 객체는 재귀적으로 cause 체인까지 풀어서 stack 정리 (cwd 제거, `file://` 제거, 들여쓰기).
31
+ - `type === "trace"` 면 즉시 stack 첨부.
32
+
33
+ ### createFileReporter
34
+
35
+ ```ts
36
+ interface FileReporterOptions {
37
+ maxSize?: number; // default 20MB
38
+ maxDays?: number; // default 14
39
+ }
40
+ createFileReporter(options?: FileReporterOptions): ConsolaReporter;
41
+ ```
42
+
43
+ - 출력 디렉토리: `<cwd>/.logs` (자동 mkdir).
44
+ - 파일명: `app.<YYYY-MM-DD>.log` → 크기 초과 시 `app.<YYYY-MM-DD>.<n>.log` 로 순번.
45
+ - 로그 1줄 = JSON: `{ time(ISO), level, tag?, err?: {message,stack}, msg? }`. `Error` arg 는 `err` 필드로, 그 외는 모두 `String` 화 후 공백 조인되어 `msg`.
46
+ - 날짜 바뀌면 회전 + 그날 첫 write 에서 `maxDays` 이전 `app.YYYY-MM-DD.*.log` 정리.
47
+
48
+ ### withMaxLevel
49
+
50
+ ```ts
51
+ withMaxLevel(reporter: ConsolaReporter, maxLevel: number): ConsolaReporter;
52
+ ```
53
+
54
+ `logObj.level > maxLevel` 인 항목을 drop. `setupConsola` 가 dev 콘솔 리포터에 `LogLevels.info` 로 적용.
55
+
56
+ ### 사용 예
57
+
58
+ ```ts
59
+ import { setupConsola } from "@simplysm/core-node";
60
+
61
+ setupConsola({ cli: true }); // 진입점 1회
62
+ consola.info("server started");
63
+ consola.withTag("db").debug({ sql, params });
64
+ ```
@@ -0,0 +1,52 @@
1
+ ## @simplysm/core-node — cpx
2
+
3
+ `import { cpx } from "@simplysm/core-node"` — 자식 프로세스 spawn + 시스템 인코딩 감지. Windows `chcp` 코드 페이지 또는 POSIX `LANG/LC_ALL` 의 charset 부분을 보고 stdout/stderr 를 적절히 디코딩.
4
+
5
+ ### 인코딩 감지
6
+
7
+ ```ts
8
+ cpx.getSystemEncoding(): string // 최초 1회 감지 후 모듈 캐시
9
+ cpx.resetEncodingCache(): void
10
+ cpx.codePageToEncoding(codePage: number): string // 65001→utf-8, 949→euc-kr, 932→shift-jis, 936→gbk, 950→big5, 1252/1251/1250/874→windows-* / 그 외 utf-8
11
+ ```
12
+
13
+ 감지 실패 시 `utf-8` fallback.
14
+
15
+ ### 디코딩
16
+
17
+ ```ts
18
+ cpx.decodeBytes(raw: Uint8Array, systemEncoding?: string): string
19
+ // utf-8 이면 바로 디코딩.
20
+ // 그 외 인코딩이면 먼저 utf-8 strict 시도 → 실패 시 systemEncoding 으로 fallback.
21
+ ```
22
+
23
+ ### spawn / spawnSync
24
+
25
+ ```ts
26
+ interface SpawnResult { stdout: string; stderr: string; exitCode: number; }
27
+
28
+ cpx.spawn(cmd, args, opts?: SpawnOptions & { reject?: boolean }): SpawnProcess
29
+ cpx.spawnSync(cmd, args, opts?: SpawnSyncOptions & { reject?: boolean }): SpawnResult
30
+ ```
31
+
32
+ - 기본 `stdio: "pipe"`. `process.env` 와 `opts.env` 머지해 자식에 전달.
33
+ - stdout/stderr 가 pipe 면 모아서 `decodeBytes` 로 문자열화.
34
+ - `exitCode !== 0` 이고 `reject !== false` 면 throw (`Command failed: <cmd> <args>`).
35
+ - `cpx.spawn` 은 `SpawnProcess` 반환 (PromiseLike + `pid` + `kill(signal?)`).
36
+
37
+ ```ts
38
+ const r = await cpx.spawn("git", ["status", "--porcelain"]);
39
+ console.log(r.stdout);
40
+
41
+ const proc = cpx.spawn("pnpm", ["watch"], { reject: false });
42
+ process.on("SIGINT", () => proc.kill());
43
+ const { exitCode } = await proc;
44
+ ```
45
+
46
+ ### resolveStdioPipe
47
+
48
+ ```ts
49
+ cpx.resolveStdioPipe(stdio): { stdout: boolean; stderr: boolean }
50
+ ```
51
+
52
+ stdio 값(`"pipe"`, `"inherit"`, 배열, `undefined`)에서 stdout/stderr 각각 pipe 여부 판정. spawn 자체가 내부 사용하므로 사용자 호출 거의 없음.
@@ -0,0 +1,53 @@
1
+ ## @simplysm/core-node — FsWatcher
2
+
3
+ chokidar 래퍼. 짧은 시간 내 이벤트를 병합해서 콜백 1회만 호출하고, Windows 의 EPERM (감시 디렉토리 사라짐 등) 발생 시 watcher 자동 재시작. 모듈 로드 시 `fs.FSWatcher.prototype.emit` 을 한 번 패치해서, listener 없는 인스턴스의 orphan `error` 이벤트로 인한 uncaughtException 도 swallow.
4
+
5
+ ### 시그니처
6
+
7
+ ```ts
8
+ type FsWatcherEvent = "add" | "addDir" | "change" | "unlink" | "unlinkDir";
9
+
10
+ interface FsWatcherChangeInfo {
11
+ event: FsWatcherEvent;
12
+ path: PosixPath; // 항상 슬래시 경로
13
+ }
14
+
15
+ class FsWatcher {
16
+ static watch(paths: string[], options?: chokidar.ChokidarOptions): Promise<FsWatcher>;
17
+
18
+ onChange(
19
+ opt: { delay?: number },
20
+ cb: (changes: FsWatcherChangeInfo[]) => void | Promise<void>,
21
+ ): this;
22
+
23
+ close(): Promise<void>;
24
+ }
25
+ ```
26
+
27
+ ### 동작 디테일
28
+
29
+ - `paths` 의 각 원소에서 glob 메타문자(`* ? { [ ]`) 이전 부분을 `chokidar.watch` 대상 디렉토리로 추출하고, 실제 변경 알림은 원래 패턴에 대해 `minimatch(path, p, { dot: true })` 또는 `minimatch(path, p + "/**")` 매칭만 통과.
30
+ - 항상 `ignoreInitial: true` 로 chokidar 호출. 사용자가 `options.ignoreInitial: false` 를 주면 첫 콜백을 빈 배열로 1회 호출 (실제 파일 목록은 포함하지 않음 — 이벤트 병합 모델과의 충돌 방지).
31
+ - `onChange` 의 `delay` 로 `DebounceQueue` 생성. 윈도우 내 같은 파일의 이벤트는 lookup 테이블로 병합:
32
+ - `add+change` → `add`
33
+ - `add+unlink` → 제거 (생성 직후 삭제 상쇄)
34
+ - `addDir+unlinkDir` → 제거
35
+ - `unlink+add` → `add`
36
+ - `unlink+change` → `change`
37
+ - `unlinkDir+addDir` → `addDir`
38
+ - 미정의 조합은 뒤 이벤트로 덮어쓰기.
39
+ - `error` 의 code 가 `EPERM` 이면 watcher 종료 → 1초 대기 → 재생성 → 등록된 모든 핸들러 재부착 → ready 대기. 최대 3회 시도 후 포기 (에러 로그만).
40
+
41
+ ### 사용 예
42
+
43
+ ```ts
44
+ const watcher = await FsWatcher.watch(["src/**/*.ts", "tests/**/*.ts"]);
45
+ watcher.onChange({ delay: 300 }, (changes) => {
46
+ for (const { event, path } of changes) {
47
+ consola.info(`${event}: ${path}`);
48
+ }
49
+ });
50
+
51
+ // 종료
52
+ await watcher.close();
53
+ ```
@@ -0,0 +1,81 @@
1
+ ## @simplysm/core-node — fsx
2
+
3
+ `import { fsx } from "@simplysm/core-node"` — 파일/디렉토리 IO 헬퍼. 동기·비동기 쌍으로 제공. 모든 함수는 오류를 `SdError(원본, targetPath)` 로 wrap 해서 throw.
4
+
5
+ ### 존재/생성/삭제
6
+
7
+ ```ts
8
+ fsx.existsSync(p): boolean
9
+ fsx.exists(p): Promise<boolean>
10
+ fsx.mkdirSync(p): void // recursive
11
+ fsx.mkdir(p): Promise<void> // recursive
12
+ fsx.rmSync(p): void // recursive, force, 재시도 없음
13
+ fsx.rm(p): Promise<void> // recursive, force, 6회/500ms 재시도 (파일 잠금 대응)
14
+ ```
15
+
16
+ 동기 rm 은 재시도 없음 — Windows 잠금 가능성 있으면 비동기 `rm` 사용.
17
+
18
+ ### 복사
19
+
20
+ ```ts
21
+ fsx.copySync(src, dst, filter?): void
22
+ fsx.copy(src, dst, filter?): Promise<void>
23
+ ```
24
+
25
+ - `src` 없으면 no-op.
26
+ - `filter(absolutePath): boolean` — 각 하위 항목 절대 경로로 호출. 최상위 `src` 자체는 필터 대상 아님. 디렉토리에 false 반환 시 그 하위 전체 스킵.
27
+ - 파일 복사 6회/500ms 재시도 (sync 는 busy-wait).
28
+
29
+ ### 읽기/쓰기
30
+
31
+ ```ts
32
+ fsx.readSync(p): string // utf-8
33
+ fsx.read(p): Promise<string>
34
+ fsx.readBytesSync(p): Uint8Array
35
+ fsx.readBytes(p): Promise<Uint8Array>
36
+ fsx.readJsonSync<T>(p): T // @simplysm/core-common json.parse
37
+ fsx.readJson<T>(p): Promise<T>
38
+
39
+ fsx.writeSync(p, data: string|Uint8Array): void // 상위 디렉토리 자동 생성, flush:true
40
+ fsx.write(p, data): Promise<void>
41
+ fsx.writeJsonSync(p, data, { replacer?, space? }?): void
42
+ fsx.writeJson(p, data, { replacer?, space? }?): Promise<void>
43
+ ```
44
+
45
+ JSON 파싱 실패 시 `SdError` 메시지에 파일 경로 + 본문 500자 미리보기 포함.
46
+
47
+ ### 디렉토리/정보
48
+
49
+ ```ts
50
+ fsx.readdirSync(p): string[]
51
+ fsx.readdir(p): Promise<string[]>
52
+ fsx.statSync(p): fs.Stats // 심볼릭 링크 따라감
53
+ fsx.stat(p): Promise<fs.Stats>
54
+ fsx.lstatSync(p): fs.Stats // 심볼릭 링크 따라가지 않음
55
+ fsx.lstat(p): Promise<fs.Stats>
56
+ ```
57
+
58
+ ### Glob / 트리 유틸
59
+
60
+ ```ts
61
+ fsx.globSync(pattern, options?: GlobOptions): string[] // 항상 절대 경로, 백슬래시 → 슬래시
62
+ fsx.glob(pattern, options?): Promise<string[]>
63
+
64
+ fsx.clearEmptyDirectory(dirPath): Promise<void> // 빈 디렉토리 재귀 삭제
65
+
66
+ fsx.findAllParentChildPathsSync(childGlob, fromPath, rootPath?): string[]
67
+ fsx.findAllParentChildPaths(childGlob, fromPath, rootPath?): Promise<string[]>
68
+ ```
69
+
70
+ `findAllParentChildPaths*`: `fromPath` 에서 루트 방향으로 부모를 순회하며 각 디렉토리에 `childGlob` 적용. `rootPath` 미지정 또는 `fromPath` 가 `rootPath` 하위가 아니면 파일 시스템 루트까지 진행. `pnpm-workspace.yaml` 같은 ancestor 설정 파일 탐색에 사용.
71
+
72
+ 사용 예:
73
+
74
+ ```ts
75
+ import { fsx } from "@simplysm/core-node";
76
+
77
+ await fsx.mkdir(path.resolve(out, "dist"));
78
+ const tsFiles = await fsx.glob("src/**/*.ts");
79
+ const cfg = await fsx.readJson<MyConfig>("sd.config.json");
80
+ await fsx.copy(src, dst, (p) => !p.includes(`${path.sep}node_modules${path.sep}`));
81
+ ```
@@ -0,0 +1,55 @@
1
+ ## @simplysm/core-node — pathx
2
+
3
+ `import { pathx } from "@simplysm/core-node"` — 경로 변환·비교 유틸. POSIX 스타일 통일과 cwd 기준 target 필터링용.
4
+
5
+ ### PosixPath 브랜드 타입
6
+
7
+ ```ts
8
+ type PosixPath = string & { [POSIX]: never };
9
+ ```
10
+
11
+ `posix()` 또는 `posixResolve()` 결과에만 부여. 슬래시 경로임을 타입으로 보장.
12
+
13
+ ### 변환
14
+
15
+ ```ts
16
+ pathx.posix(p: string): PosixPath
17
+ // 백슬래시 → 슬래시 만. resolve 안 함.
18
+ // posix("C:\\Users\\test") === "C:/Users/test"
19
+
20
+ pathx.posixResolve(...args: string[]): PosixPath
21
+ // path.resolve 후 슬래시화. 항상 절대 경로.
22
+ ```
23
+
24
+ ### 비교/판정
25
+
26
+ ```ts
27
+ pathx.isChildPath(child, parent): boolean
28
+ // posixResolve 정규화 후 비교. 동일 경로면 false.
29
+
30
+ pathx.changeFileDirectory(filePath, fromDir, toDir): string
31
+ // filePath 의 fromDir 부분을 toDir 로 치환.
32
+ // filePath === fromDir 이면 toDir 반환.
33
+ // filePath 가 fromDir 하위가 아니면 ArgumentError throw.
34
+
35
+ pathx.basenameWithoutExt(filePath): string
36
+ // path.basename(p, path.extname(p)). "a/b/c.spec.ts" → "c.spec"
37
+ ```
38
+
39
+ ### target 필터링
40
+
41
+ ```ts
42
+ pathx.filterByTargets(files: string[], targets: string[], cwd: string): string[]
43
+ ```
44
+
45
+ - `targets` 가 비면 `files` 그대로 반환.
46
+ - 각 `target` 은 cwd 기준 상대 경로 (POSIX 권장).
47
+ - `files` 각 원소를 cwd 기준 상대 POSIX 로 변환 후 `relative === target || relative.startsWith(target + "/")` 매칭.
48
+ - `files` 는 cwd 하위 절대 경로 가정 — 외부 경로는 `../` 로 변환되어 매칭에서 빠짐.
49
+
50
+ CLI 의 `-t <project>` 처럼 사용자 지정 부분 경로로 후보를 좁힐 때 사용.
51
+
52
+ ```ts
53
+ const files = ["/proj/src/a.ts", "/proj/tests/c.ts"];
54
+ pathx.filterByTargets(files, ["src"], "/proj"); // ["/proj/src/a.ts"]
55
+ ```
@@ -0,0 +1,111 @@
1
+ ## @simplysm/core-node — Worker
2
+
3
+ `worker_threads` 위의 타입 안전 RPC. 워커 측에서 `createWorker(methods)` 로 default export 하면, 메인 측에서 `Worker.create<typeof import("./worker")>(path)` 로 메서드 직접 호출 + 이벤트 수신 가능한 Proxy 를 얻는다. 메시지 인코딩은 `@simplysm/core-common` 의 `transfer.encode/decode` 사용 (Uint8Array 등 transferable 자동 처리).
4
+
5
+ ### 타입
6
+
7
+ ```ts
8
+ interface WorkerModule {
9
+ default: {
10
+ __methods: Record<string, (...args: any[]) => unknown>;
11
+ __events: Record<string, unknown>;
12
+ };
13
+ }
14
+
15
+ type PromisifyMethods<T> = {
16
+ [K in keyof T]: T[K] extends (...args: infer P) => infer R
17
+ ? (...args: P) => Promise<Awaited<R>>
18
+ : never;
19
+ };
20
+
21
+ type WorkerProxy<TModule extends WorkerModule> =
22
+ PromisifyMethods<TModule["default"]["__methods"]> & {
23
+ on<E extends keyof TModule["default"]["__events"] & string>(
24
+ event: E, listener: (data: TModule["default"]["__events"][E]) => void,
25
+ ): void;
26
+ off<E extends keyof TModule["default"]["__events"] & string>(event: E, listener): void;
27
+ terminate(): Promise<void>;
28
+ };
29
+ ```
30
+
31
+ 메서드는 항상 `Promise<Awaited<R>>` 로 노출. `on`/`off`/`terminate` 는 예약어 — 워커 메서드명으로 사용 금지.
32
+
33
+ ### Worker.create (메인 측)
34
+
35
+ ```ts
36
+ Worker.create<TModule extends WorkerModule>(
37
+ filePath: string,
38
+ opt?: Omit<WorkerOptions, "stdout" | "stderr">,
39
+ ): WorkerProxy<TModule>;
40
+ ```
41
+
42
+ - `filePath`: `file://` URL 또는 절대 경로.
43
+ - 실행 모드는 `import.meta.filename` 확장자로 결정:
44
+ - `.ts` (개발/tsx) → 내부 `lib/worker-dev-proxy.js` 를 띄우고 워커 파일을 argv 로 전달, tsx 로 동적 로드.
45
+ - `.js` (프로덕션) → 워커 파일을 그대로 `new Worker(workerPath, ...)`.
46
+ - 항상 `stdout: true, stderr: true` 로 워커 띄우고 메인의 stdout/stderr 로 pipe. 워커 내부의 `process.stdout.write` 도 메시지 프로토콜(`type: "log"`)로 메인에 전달되어 그대로 stdout 에 출력 — 워커의 `console.log` 가 메인 터미널에 보임.
47
+ - `opt.env` 는 `process.env` 와 머지되어 워커에 전달.
48
+ - 워커 비정상 종료(`exit code !== 0`) 또는 `error` 발생 시 대기 중 모든 호출이 reject. `terminate()` 호출 시에도 in-flight 요청은 모두 reject.
49
+
50
+ ### createWorker (워커 측)
51
+
52
+ ```ts
53
+ function createWorker<
54
+ TMethods extends Record<string, (...args: any[]) => unknown>,
55
+ TEvents extends Record<string, unknown> = Record<string, never>,
56
+ >(methods: TMethods): {
57
+ send<E extends keyof TEvents & string>(event: E, data?: TEvents[E]): void;
58
+ __methods: TMethods;
59
+ __events: TEvents;
60
+ };
61
+ ```
62
+
63
+ - 워커 스레드에서만 호출 (`parentPort == null` 이면 `SdError` throw).
64
+ - `methods` 의 각 함수는 메인에서 `worker.<name>(...args)` 로 호출되어 결과/throw 가 그대로 전달됨. async 함수도 await 처리됨.
65
+ - 알 수 없는 메서드/잘못된 메시지 형식 호출 시 `SdError` 로 응답.
66
+ - 반환값 객체에 `send(event, data?)` 가 있어 워커 → 메인 단방향 이벤트 가능. `TEvents` 제네릭으로 이벤트 이름·페이로드 타입 보장. 반환값은 반드시 `export default` 해야 메인의 `typeof import(...)` 추론이 동작.
67
+
68
+ ### WorkerRequest / WorkerResponse
69
+
70
+ 내부 메시지 프로토콜 (사용자가 직접 다룰 일 없음).
71
+
72
+ ```ts
73
+ interface WorkerRequest { id: string; method: string; params: unknown[]; }
74
+
75
+ type WorkerResponse =
76
+ | { request: WorkerRequest; type: "return"; body?: unknown }
77
+ | { request: WorkerRequest; type: "error"; body: Error }
78
+ | { type: "event"; event: string; body?: unknown }
79
+ | { type: "log"; body: string };
80
+ ```
81
+
82
+ ### 사용 예
83
+
84
+ ```ts
85
+ // worker.ts
86
+ import { createWorker } from "@simplysm/core-node";
87
+
88
+ interface Events { progress: number; }
89
+
90
+ const methods = {
91
+ async heavy(x: number) {
92
+ sender.send("progress", 50);
93
+ return x * 2;
94
+ },
95
+ };
96
+
97
+ const sender = createWorker<typeof methods, Events>(methods);
98
+ export default sender;
99
+ ```
100
+
101
+ ```ts
102
+ // main.ts
103
+ import { Worker } from "@simplysm/core-node";
104
+
105
+ const worker = Worker.create<typeof import("./worker")>(
106
+ new URL("./worker.ts", import.meta.url).href,
107
+ );
108
+ worker.on("progress", (p) => consola.info(`${p}%`));
109
+ const result = await worker.heavy(21); // 42
110
+ await worker.terminate();
111
+ ```
@@ -0,0 +1,81 @@
1
+ # @simplysm/excel
2
+
3
+ OOXML(xlsx) 워크북을 lazy-load 로 읽고 쓰는 클래스 묶음. ZIP 내부 XML 을 접근 시점에만 파싱한다.
4
+
5
+ ## 사용 트리거 인덱스
6
+ - **`ExcelWorkbook`** — xlsx 바이트/Blob 을 열거나 새 워크북을 만들 때. 사용 후 `close()` 필수.
7
+ - **`ExcelWorksheet`** — 시트 단위로 셀/행/열 접근, 데이터테이블 입출력, 틀 고정/줌, 조건부 서식, 이미지 삽입.
8
+ - **`ExcelCell` / `ExcelRow` / `ExcelCol`** — 단일 셀 값·수식·스타일·병합, 행/열 전체 셀 일괄 접근, 열 너비.
9
+ - **`ExcelWrapper`** — Zod 스키마로 헤더·타입을 정의해 레코드 배열로 read/write.
10
+ - **`ExcelUtils`** — `"A1"`↔좌표, 범위 주소, Excel 직렬 날짜 ↔ 타임스탬프, numFmt 변환.
11
+ - **타입 (`ExcelValueType`, `ExcelStyleOptions`, `ExcelFont`, `ExcelConditionalRule` 등)** — 입력 옵션·반환값 정의.
12
+
13
+ ## ExcelWorkbook
14
+ ```typescript
15
+ new ExcelWorkbook(arg?: Blob | Bytes)
16
+ getWorksheetNames(): Promise<string[]>
17
+ addWorksheet(name): Promise<ExcelWorksheet>
18
+ getWorksheet(nameOrIndex: string | number): Promise<ExcelWorksheet> // 인덱스 0 기반
19
+ setDefaultStyle(opts: ExcelStyleOptions): Promise<void> // cellXfs[0] 덮어쓰기
20
+ toBytes(): Promise<Bytes>
21
+ toBlob(): Promise<Blob> // xlsx MIME
22
+ close(): Promise<void> // 멱등, 이후 모든 메서드는 throw
23
+ ```
24
+ 패턴: `const wb = new ExcelWorkbook(bytes); try { ... } finally { await wb.close(); }`. 인자 생략 시 빈 워크북.
25
+
26
+ ## ExcelWorksheet
27
+ ```typescript
28
+ getName() / setName(newName)
29
+ row(r) / col(c) / cell(r, c) // 모두 0 기반, 동기 반환
30
+ getRange(): Promise<ExcelAddressRangePoint>
31
+ getCells(): Promise<ExcelCell[][]> // 전체 2D
32
+ getDataTable(opt?: { headerRowIndex?; checkEndColIndex?; usableHeaderNameFn? })
33
+ // 레코드 배열. 중복 헤더면 throw
34
+ setDataMatrix(matrix: ExcelValueType[][]) // 0,0 부터
35
+ setRecords(records: Record<string, ExcelValueType>[]) // 첫 행 헤더 자동
36
+ copyCell / copyRow / copyCellStyle / copyRowStyle / insertCopyRow
37
+ setZoom(percent) / freezeAt({ r?, c? })
38
+ addConditionalFormat({ ref, rules: ExcelConditionalRule[] }) // 호출마다 priority 누적
39
+ addImage({ bytes, ext, from, to? }) // ext 는 mime lookup. to 생략 시 from+1,+1
40
+ ```
41
+
42
+ ## ExcelCell / ExcelRow / ExcelCol
43
+ ```typescript
44
+ // ExcelCell
45
+ cell.addr // { r, c }
46
+ getValue() / setValue(val: ExcelValueType) // string/number/boolean/DateOnly/DateTime/Time/undefined
47
+ getFormula() / setFormula(val) // 셀 타입 "str" 로 설정
48
+ merge(endR, endC) // 현재 셀부터 (endR,endC) 까지
49
+ getStyleId() / setStyleId(id)
50
+ setStyle(opts: ExcelStyleOptions) // 기존 스타일에 clone-merge
51
+
52
+ // ExcelRow / ExcelCol
53
+ row.cell(c) / col.cell(r)
54
+ row.getCells() / col.getCells()
55
+ col.setWidth(size)
56
+ ```
57
+ 값 setter 에 `undefined` → 셀 삭제. Date/Time 계열은 numFmt 자동 설정.
58
+
59
+ ## ExcelWrapper
60
+ ```typescript
61
+ new ExcelWrapper(schema: z.ZodObject) // .describe() 가 Excel 헤더명
62
+ read(file, wsNameOrIndex = 0, { excludes? }?): Promise<z.infer<S>[]> // 내부에서 워크북 close
63
+ write(wsName, records, { excludes? }?): Promise<ExcelWorkbook> // 호출자가 close 필수
64
+ ```
65
+ write: 모든 셀 테두리, 필수(non-optional/nullable/default) 비-boolean 필드 헤더는 노란 배경, 첫 행 freeze, 줌 85%.
66
+
67
+ ## ExcelUtils
68
+ ```typescript
69
+ stringifyAddr({r,c}) / parseCellAddr("B3") // {r:2,c:1}
70
+ stringifyColAddr(0) // "A" parseColAddr("AA") // 26
71
+ stringifyRangeAddr / parseRangeAddr("A1:C3")
72
+ convertTimeTickToNumber(tick) / convertNumberToTimeTick(serial) // Excel 1899-12-30 기준
73
+ convertNumFmtIdToName / convertNumFmtCodeToName / convertNumFmtNameToId
74
+ ```
75
+
76
+ ## 타입 요약
77
+ - `ExcelValueType` = `number | string | DateOnly | DateTime | Time | boolean | undefined`.
78
+ - `ExcelStyleOptions`: `background`(ARGB 8자리), `border: ExcelBorderPosition[]`, `horizontalAlign`, `verticalAlign`, `numberFormat` (`"number"|"string"|"DateOnly"|"DateTime"|"Time"`), `numberFormatCode` (커스텀, 우선), `font: ExcelFont`.
79
+ - `ExcelFont`: `size, family, bold, italic, underline, color(ARGB), strike`. 미지정 속성은 OOXML 에 emit 안 됨 → Excel 기본값.
80
+ - `ExcelConditionalRule`: `{type:"cellIs", op, value, style}` | `{type:"text", op:"contains"|"notContains"|"beginsWith"|"endsWith", value, style}` | `{type:"expression", formula, style}`. `style` = `ExcelConditionalRuleStyle` (`background`, `fontColor`, `fontWeight`).
81
+ - `ExcelAddressPoint = {r,c}` / `ExcelAddressRangePoint = {s,e}` 모두 0 기반.
@@ -0,0 +1,80 @@
1
+ # @simplysm/lint
2
+
3
+ Simplysm 컨벤션용 ESLint 플러그인 패키지. 커스텀 규칙 묶음(`./eslint-plugin`)과 typescript-eslint·angular-eslint 통합 flat config 프리셋(`./eslint-recommended`)을 제공한다.
4
+
5
+ ## 사용 트리거 인덱스
6
+
7
+ - **`./eslint-recommended` (default export)** — 프로젝트 `eslint.config.{js,mjs,cjs}` 에서 그대로 spread 해 simplysm 표준 lint 규칙을 적용할 때.
8
+ - **`./eslint-plugin` (default export)** — recommended 를 사용하지 않고 개별 규칙만 골라 쓰거나, 다른 flat config 에서 `@simplysm/<rule>` 로 참조할 때.
9
+
10
+ ## `./eslint-recommended`
11
+
12
+ ```ts
13
+ // eslint.config.mjs
14
+ import recommended from "@simplysm/lint/eslint-recommended";
15
+ export default recommended;
16
+ // 또는 추가 config 와 함께
17
+ export default [...recommended, { /* overrides */ }];
18
+ ```
19
+
20
+ `typescript-eslint.config(...)` 결과(flat config 배열). 다음을 합쳐 export 한다:
21
+
22
+ - `ignores`: `**/node_modules/**`, `**/dist/**`, `**/.*/**` (디렉터리 단위 스킵).
23
+ - `**/*.{js,mjs,cjs}` 블록: globals=node, 플러그인 `import`/`@simplysm`/`unused-imports`, `import/no-extraneous-dependencies` 예외 경로 = `**/lib/**`, `**/eslint.config.{js,cjs,mjs}`, `**/simplysm.{js,cjs,mjs}`, `**/vitest.config.{js,cjs,mjs}`.
24
+ - `angular.configs.tsRecommended` + `**/*.ts` 블록: `tseslint.parser` + `parserOptions.project: true`, `angular.processInlineTemplates` processor, `eslint-import-resolver-typescript` resolver(`alwaysTryTypes: true`).
25
+ - `**/*.html` 블록: `angular.configs.templateRecommended` + `templateAccessibility` extends, `@angular-eslint/template/eqeqeq` 는 `allowNullOrUndefined: true`, `label-has-associated-control` off, `template/no-any` error.
26
+ - `**/tests/**/*.ts` override: `no-console`, `import/no-extraneous-dependencies`, `@simplysm/ts-no-throw-not-implemented-error` off.
27
+ - `**/vitest.config.ts` override: `no-restricted-properties` off (vitest 가 `process` 접근 필요).
28
+
29
+ 공통으로 강제되는 simplysm 컨벤션:
30
+
31
+ - `Buffer`/`buffer`/`events`/`eventemitter3` 금지 → `Uint8Array`/`@simplysm/core-common` 사용 유도.
32
+ - `process.env`/`import.meta.env` 직접 접근 금지 → `env("...")` 호출 강제. `env("NODE_ENV")` 자체 금지.
33
+ - `=== undefined` / `!== undefined` 금지 → `== null` / `!= null` 통일.
34
+ - TS 블록 전용: `naming-convention` 으로 `private` 멤버에 leading underscore(`_foo`) 강제, `strict-boolean-expressions` (nullable boolean/object 허용), `ban-ts-comment` (`ts-expect-error` 는 3자 이상 설명 필수), `only-throw-error`, `no-floating-promises` 등.
35
+
36
+ ## `./eslint-plugin`
37
+
38
+ ```ts
39
+ // eslint.config.mjs
40
+ import simplysm from "@simplysm/lint/eslint-plugin";
41
+ export default [{
42
+ plugins: { "@simplysm": simplysm },
43
+ rules: { "@simplysm/no-hard-private": "error" },
44
+ }];
45
+ ```
46
+
47
+ `{ rules: { ... } }` 형태의 ESLint 플러그인 객체. 노출 규칙(전부 `@simplysm/<name>` 으로 참조):
48
+
49
+ ### `ng-no-async-effect` (problem)
50
+ `@angular/core`에서 import 한 `effect()` 1번째 인자가 async 함수면 보고. named/aliased/namespace import 모두 추적. `await` 이후 signal read 가 의존성 추적 밖으로 빠지는 문제 방지. 안내: 비동기 작업은 `void untracked(async () => { ... })` 로 감쌀 것.
51
+
52
+ ### `ng-template-no-strict-null-check` (problem)
53
+ HTML 템플릿 바인딩에서 `=== null|undefined`, `!== null|undefined` 사용 시 보고. `== null`/`!= null` 로 통일 유도. autofix 없음(인라인 템플릿 offset 매핑 문제).
54
+
55
+ ### `ng-template-no-todo-comments` (problem, recommended=warn)
56
+ HTML 주석 `<!-- TODO: ... -->` 를 정규식으로 탐지해 본문을 메시지로 보고. AST 방문자 없이 raw text 스캔.
57
+
58
+ ### `ng-template-sd-require-binding-attrs` (problem, fixable)
59
+ `sd-*` 접두사 컴포넌트의 plain attribute 사용을 제한하고 property binding 으로 변환.
60
+ - 옵션: `selectorPrefixes`(기본 `["sd-"]`), `allowAttributes`(기본 `["id","class","style","title","tabindex","role"]`), `allowAttributePrefixes`(기본 `["aria-","data-","sd-"]`).
61
+ - Autofix: `foo="bar"` → `[foo]="'bar'"`, 값 없으면 `[foo]="true"`.
62
+
63
+ ### `no-hard-private` (problem, fixable)
64
+ ES private 필드(`#field`, `#method()`, `accessor #field`, `this.#field`) 금지. TypeScript `private _field` 스타일 강제. Autofix 로 `#x` → `_x` 치환 + 선언부에 `private` 키워드 삽입(데코레이터/`static`/`async`/`readonly` 순서 보존). 동일 클래스에 `_x` 멤버가 이미 있으면 `nameConflict` 로 보고만(자동 수정 안 함).
65
+
66
+ ### `no-subpath-imports-from-simplysm` (problem, fixable)
67
+ `@simplysm/<pkg>/src/...` 형태 import 금지. 정적 `import`, 동적 `import()`, `export ... from`, `export * from` 모두 검사. Autofix: `@simplysm/<pkg>` 로 단축.
68
+
69
+ ### `ts-no-throw-not-implemented-error` (suggestion, recommended=warn)
70
+ `@simplysm/core-common` 에서 import 한 `NotImplementedError` 의 `new` 호출 보고. named/aliased/namespace import 추적. 인자가 비어있지 않은 문자열 리터럴이면 메시지에 그대로 노출(없으면 `"미구현"`). 동적 import 는 미지원. `**/tests/**/*.ts` 에서는 off.
71
+
72
+ ### `ts-no-unused-injects` (problem, fixable)
73
+ 클래스 내 `inject()` 로 초기화된 PropertyDefinition 중 같은 클래스 본문에서 식별자로 단 한 번도 참조되지 않는 필드 보고. Autofix 로 해당 필드 라인 제거.
74
+
75
+ ### `ts-no-unused-protected-readonly` (problem, fixable)
76
+ `@Component({ template: "..." })` 클래스의 `protected readonly` 인스턴스 필드(=static 제외) 중 인라인 템플릿과 클래스 본문 모두에서 미참조면 보고·자동 제거. `templateUrl` 만 있는 경우(=`template` 프로퍼티 없음) 검사 스킵. 템플릿은 `@angular/compiler` 의 `parseTemplate` 로 파싱하며 `*ngFor` 로컬 변수, `@let`, `@if as alias`, `@for item/context`, `@switch`/`@defer` 트리거까지 스코프 처리.
77
+
78
+ ## 규칙 작성용 유틸 (내부)
79
+
80
+ `createRule` 은 패키지 내부 규칙 정의 전용 헬퍼(`ESLintUtils.RuleCreator` 래퍼)로, 외부 export 표면(`exports` 필드) 에 노출되지 않는다. 소비자 코드에서 직접 사용하지 않음.
@@ -0,0 +1,33 @@
1
+ # @simplysm/orm-common
2
+
3
+ Dialect 독립 ORM 코어. `DbContext` 상속으로 테이블/뷰/프로시저를 등록하고, fluent builder + Expr AST 로 쿼리를 구성하면, 각 DBMS(MySQL/MSSQL/PostgreSQL) QueryBuilder 가 SQL 로 렌더한다. 실제 connect/execute 는 외부 executor 가 구현 (서버=`@simplysm/orm-node`, 클라이언트=`@simplysm/service-client` 의 OrmServiceClient).
4
+
5
+ ## 사용 트리거 인덱스
6
+
7
+ - **`DbContext` (abstract class)** — DB 1개에 매핑되는 서브클래스를 만들 때. `protected queryable(Builder)` / `executable(Builder)` 로 테이블·뷰·프로시저를 인스턴스 프로퍼티로 등록, `connect()`/`transaction()` 로 실행 경계 잡고, DDL/`initialize()` 로 스키마 만들 때. 자세히: [db-context.md](./db-context.md)
8
+ - **Schema Builders** — `Table(name)`, `View(name)`, `Procedure(name)` 로 스키마 객체 정의할 때. Column / Index / Relation factory 포함. 자세히: [schema-builders.md](./schema-builders.md)
9
+ - **`Queryable` / `queryable()`** — `DbContext` 에 등록된 테이블/뷰에서 SELECT/INSERT/UPDATE/DELETE/UPSERT 빌더 체이닝, JOIN/include/recursive CTE/UNION/search 할 때. 자세히: [queryable.md](./queryable.md)
10
+ - **`Executable` / `executable()`** — 등록된 프로시저 호출 결과 받을 때. 자세히: [executable.md](./executable.md)
11
+ - **`expr` namespace + `ExprUnit`/`WhereExprUnit`** — `where`/`select`/`groupBy`/`having`/`update` 콜백 안에서 비교·논리·문자열·날짜·집계·윈도우·CASE·subquery 등 SQL 표현식 만들 때. dialect 독립 AST. 자세히: [expr.md](./expr.md)
12
+ - **`parseSearchQuery(text)`** — `Queryable.search()` 내부에서 쓰는 OR/`+`AND/`-`NOT/`"…"`/`*` 구문 파서. 직접 LIKE 패턴이 필요할 때만 외부 사용.
13
+ - **`QueryBuilder` (`createQueryBuilder(dialect)`, `QueryBuilderBase`, `ExprRendererBase`, `*QueryBuilder`, `*ExprRenderer`)** — executor 측에서 `QueryDef` 를 dialect SQL 로 렌더할 때. 응용 코드는 직접 호출 X.
14
+ - **`QueryDef` 타입군 (`./types/query-def`)** — executor·테스트에서 빌더가 만든 AST 를 직접 다룰 때. `QueryDef`, `SelectQueryDef`, `InsertQueryDef`, ..., `QueryDefObjectName`, `DDL_TYPES`, `DdlType`.
15
+ - **`Expr` 타입군 (`./types/expr`)** — Expr AST 노드 타입(`ExprColumn`/`ExprValue`/`ExprRaw`/`ExprEq`/...`ExprWindow`/`ExprSubquery`). `DateUnit`. ExprRenderer 구현·검사에서 사용.
16
+ - **`DataType` / `ColumnPrimitive*` (`./types/column`)** — SQL DataType union(`int`/`bigint`/`varchar`/`datetime`/`uuid`/...) 과 TS 타입 매핑(`ColumnPrimitiveMap`/`ColumnPrimitiveStr`/`ColumnPrimitive`/`ColumnMeta`). `dataTypeStrToColumnPrimitiveStr` 상수, `InferColumnPrimitiveFromDataType<T>` / `inferColumnPrimitiveStr(value)` 런타임 추론.
17
+ - **`Dialect` / `dialects` / `DataRecord` / `DbContextExecutor` / `ResultMeta` / `IsolationLevel` / `Migration` / `QueryBuildResult` (`./types/db`)** — executor 구현·DbContext 외부 인터페이스. `Migration[]` 은 DbContext 서브클래스의 `migrations` 프로퍼티로 오버라이드해 `initialize()` 에서 적용.
18
+ - **`DbContextBase` / `DbContextStatus` / `DbContextDdlMethods` (`./types/db-context-def`)** — 외부에서 DbContext 를 인터페이스로 다룰 때 (Queryable/Executable/ViewBuilder 가 의존).
19
+ - **`DbTransactionError` / `DbErrorCode`** — executor 가 트랜잭션 에러를 표준화해 throw, 호출측은 `instanceof` 로 분기. 코드: `NO_ACTIVE_TRANSACTION`, `TRANSACTION_ALREADY_STARTED`, `DEADLOCK`, `LOCK_TIMEOUT`.
20
+ - **`parseResults(rows, meta)` / `pickResultSets(rawResults, buildResult)` (`./utils/*`)** — executor 측 raw 결과 가공. `parseResults` 는 flat row → 중첩 객체(JOIN 그룹핑 + 타입 파싱). `pickResultSets(raw, { resultSetIndex, resultSetStride })` 는 다중 결과 셋에서 필요한 셋만 추출 (예: MySQL 배치 INSERT 의 OUTPUT SELECT).
21
+ - **`_Migration` / `SD_BUILDER`** — 내부용. `_Migration` 은 `_migration(code PK)` 시스템 테이블, `SD_BUILDER` 는 `queryable()`/`executable()` 팩토리 함수에 붙는 메타 심볼 (`initialize()` 가 DbContext 의 프로퍼티에서 builder 를 회수할 때 사용).
22
+
23
+ ## QueryBuilder (인라인)
24
+
25
+ ```ts
26
+ import { createQueryBuilder } from "@simplysm/orm-common";
27
+ const qb = createQueryBuilder("mysql"); // | "mssql" | "postgresql"
28
+ const { sql, resultSetIndex, resultSetStride } = qb.build(queryDef);
29
+ ```
30
+
31
+ `QueryBuilderBase.build(def)` 가 `def.type` 으로 동적 dispatch 하여 dialect 별 메서드 호출. 결과는 `QueryBuildResult { sql; resultSetIndex?; resultSetStride? }` — 여러 result set 이 돌아오는 dialect 별 패턴(MySQL OUTPUT INSERT 등)을 위해 추출 인덱스/스트라이드 동봉. executor 는 받은 raw set 배열을 `pickResultSets(raw, buildResult)` 로 좁힌다.
32
+
33
+ `createQueryBuilder(dialect)` 외에 dialect 클래스(`MysqlQueryBuilder`/`MssqlQueryBuilder`/`PostgresqlQueryBuilder` 와 대응 `*ExprRenderer`)도 export. 일반적으로 `createQueryBuilder` 만 쓰면 충분, 커스텀 확장 시 `QueryBuilderBase`/`ExprRendererBase` 상속.