@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,77 @@
1
+ # @simplysm/orm-common — DbContext
2
+
3
+ DB 1개에 대응하는 추상 클래스. 서브클래싱하여 테이블/뷰/프로시저를 인스턴스 프로퍼티로 등록하고, connect/transaction/DDL/initialize 진입점을 제공한다. 실제 SQL 실행은 생성자에 주입된 `DbContextExecutor` 가 담당.
4
+
5
+ ## 생성·등록
6
+
7
+ ```ts
8
+ class MainDb extends DbContext {
9
+ user = this.queryable(User); // → () => Queryable<User.$inferSelect, typeof User>
10
+ vUser = this.queryable(UserSummary); // View 도 동일
11
+ getUserById = this.executable(GetUserById); // → () => Executable<TParams, TReturns>
12
+
13
+ migrations = [
14
+ { name: "001-init", up: async (db) => { await db.createTable(User); } },
15
+ ];
16
+ }
17
+
18
+ const db = new MainDb(executor, { database: "mydb", schema: "dbo" });
19
+ ```
20
+
21
+ - `protected queryable(builder)`: `TableBuilder | ViewBuilder` 를 받아 호출시마다 새 alias 가 할당된 `Queryable` 을 만드는 팩토리 함수를 반환. 반환 함수에는 `SD_BUILDER` 심볼로 원본 builder 가 부착됨 (initialize 가 회수).
22
+ - `protected executable(builder)`: `ProcedureBuilder` → `Executable` 팩토리. 동일하게 `SD_BUILDER` 부착.
23
+ - `_migration` 프로퍼티: 시스템 마이그레이션 테이블(`_migration(code PK varchar(255))`) 이 자동 등록됨.
24
+
25
+ ## 연결 / 트랜잭션
26
+
27
+ ```ts
28
+ await db.connect(async () => { ... }); // connect + tx (auto commit/rollback)
29
+ await db.connect(async () => { ... }, "REPEATABLE_READ"); // isolation level
30
+ await db.connectWithoutTransaction(async () => { ... }); // connect only
31
+ await db.transaction(async () => { ... }); // 이미 connect 인 상태에서 tx 만
32
+ ```
33
+
34
+ - `status: "ready" | "connect" | "transact"`. 잘못된 진입(중복 connect, 중복 tx)은 throw.
35
+ - `connect()` 진입시 1회 `validateRelationsImpl` 호출 (relation 무결성 검사 — 잘못된 FK 정의는 여기서 throw).
36
+ - 본문 throw 시 자동 rollback → `_executor.close()` 후 status `ready` 복귀. rollback 중 `DbTransactionError(NO_ACTIVE_TRANSACTION)` 는 무시.
37
+ - `transaction()` 단독은 `status==="connect"` 일 때만. 이미 transact 면 throw.
38
+ - `executeDefs(defs, resultMetas?)`: `_executor.executeDefs` 위임. `status==="transact"` 중 DDL 포함 시 throw.
39
+
40
+ ## DDL 실행
41
+
42
+ `createTable`, `dropTable`, `renameTable`, `createView`, `dropView`, `createProc`, `dropProc`, `addColumn`, `dropColumn`, `modifyColumn`, `renameColumn`, `addPrimaryKey`, `dropPrimaryKey`, `addForeignKey`, `addIndex`, `dropForeignKey`, `dropIndex`, `clearSchema({database, schema?})`, `schemaExists(database, schema?): Promise<boolean>`, `truncate(table)`, `switchFk(table, enabled)`.
43
+
44
+ 각각 `executeDefs([...QueryDef])` 로 1건씩 실행. 트랜잭션 내에서는 `switchFk` 외 모두 차단(`executeDefs` 에서 검사).
45
+
46
+ 대응 `getXxxQueryDef(...)` 형태의 *생성기* 메서드도 동일 시그니처로 제공 (실행 없이 `QueryDef` 만 반환). `initialize()` 가 배치 DDL 을 모을 때 사용.
47
+
48
+ `getCreateObjectQueryDef(builder)` — Table/View/Procedure 중 무엇이든 받아 알맞은 create DDL 반환.
49
+
50
+ ## initialize
51
+
52
+ ```ts
53
+ await db.initialize(); // 미적용 migration 만 실행
54
+ await db.initialize({ dbs: ["a", "b"] }); // 다중 DB
55
+ await db.initialize({ force: true }); // 스키마 clear + 전체 재생성 + 모든 migration 을 "적용됨" 등록
56
+ ```
57
+
58
+ 반환값: 실행된 migration 이 있으면 `true`, 아니면 `false`.
59
+
60
+ 동작:
61
+ - `force=true`: `clearSchema` → DbContext 의 모든 등록 객체(`queryable`/`executable` 프로퍼티에서 `SD_BUILDER` 로 회수) create → `_Migration` 에 모든 migration name 등록 → `false`.
62
+ - `force=false`:
63
+ - `_Migration` 테이블 없음 = 신규 DB → 전체 create + 모든 migration 등록 → `false`.
64
+ - 있음 → 미적용 migration 만 순차 실행 → 실행분 있으면 `true`.
65
+
66
+ 서브클래스가 `migrations: Migration[]` 를 오버라이드해 `{ name, up(db) }` 목록 제공.
67
+
68
+ ## 헬퍼
69
+
70
+ - `database`/`schema` getter — 생성자 옵션 노출.
71
+ - `getNextAlias(): string` — `T1`, `T2`, ... alias 카운터. `connect`/`connectWithoutTransaction` 진입시 reset.
72
+ - `resetAliasCounter()`.
73
+ - `getQueryDefObjectName(tableOrView)` — Table/View 메타에서 `{database, schema, name}` 산출 (없으면 DbContext 옵션 fallback).
74
+
75
+ ## 인터페이스
76
+
77
+ 외부에서 DbContext 를 의존성으로 다룰 때는 `DbContextBase`(코어) + `DbContextDdlMethods`(DDL) 인터페이스 사용 (`./types/db-context-def`). `DbContext` 가 둘 다 구현.
@@ -0,0 +1,20 @@
1
+ # @simplysm/orm-common — Executable
2
+
3
+ 저장 프로시저 호출 래퍼. `DbContext.executable(builder)` 가 만든 팩토리 호출(`db.getUserById()`)마다 새 인스턴스 반환.
4
+
5
+ ```ts
6
+ class Executable<TParams extends ColumnBuilderRecord, TReturns extends ColumnBuilderRecord> {
7
+ getExecProcQueryDef(params?: InferColumnExprs<TParams>): ExecProcQueryDef
8
+ async execute(params: InferColumnExprs<TParams>): Promise<InferColumnExprs<TReturns>[][]>
9
+ }
10
+ ```
11
+
12
+ - `params` 의 각 값은 `ExprInput<T>` (= `ExprUnit<T> | T`). 리터럴이면 `expr.val(meta.type, value)` 로 자동 래핑.
13
+ - 프로시저에 `params` 가 정의되지 않은 builder 에 인자를 넘기면 throw.
14
+ - 반환은 결과 셋의 배열 (프로시저가 여러 SELECT 를 반환할 수 있음).
15
+
16
+ ```ts
17
+ const [users] = await db.getUserById().execute({ userId: 1 });
18
+ ```
19
+
20
+ `executable(db, builder)` — 팩토리. `DbContext.executable` 의 내부 구현이며, `SD_BUILDER` 심볼로 builder 를 부착해야 `initialize()` 가 회수할 수 있다 (직접 쓰지 말고 `DbContext.executable` 사용 권장).
@@ -0,0 +1,92 @@
1
+ # @simplysm/orm-common — expr
2
+
3
+ Dialect 독립 SQL 표현식 빌더. SQL 문자열 대신 JSON AST(`Expr`/`WhereExpr`) 를 만들어 `Queryable` 메타에 누적되고, QueryBuilder 가 DBMS 별로 렌더.
4
+
5
+ ## 래퍼
6
+
7
+ - `ExprUnit<T extends ColumnPrimitive>` — `{ dataType: ColumnPrimitiveStr, expr: Expr }`. `.n` 게터로 `NonNullable<T>` 로 cast.
8
+ - `WhereExprUnit` — boolean 컨텍스트 (`where`/`having`/논리 연산자) 전용.
9
+ - `ExprInput<T> = ExprUnit<T> | T` — 리터럴도 받는 입력 타입.
10
+ - `expr.toExpr(value)` / `toExpr(value)` 헬퍼 — `ExprUnit` 이면 풀고, 아니면 `{type:"value", value}` 로 감쌈.
11
+
12
+ ## 카테고리별 API
13
+
14
+ ### 값 / 컬럼 / Raw
15
+ - `expr.val(dataType, value)` — 리터럴 → `ExprUnit`. `dataType ∈ "string"|"number"|"boolean"|"DateTime"|"DateOnly"|"Time"|"Uuid"|"Bytes"`.
16
+ - `expr.col(dataType, ...path)` — 컬럼 참조(주로 내부).
17
+ - `expr.raw(dataType)\`SQL ${interp}\`` — 태그드 템플릿. 보간값은 파라미터화. dialect 의존 함수 사용 시 escape hatch.
18
+
19
+ ### 비교 / NULL (→ `WhereExprUnit`)
20
+ - `eq`, `gt`, `lt`, `gte`, `lte`(source, target)
21
+ - `between(source, from?, to?)`
22
+ - `null(source)` — IS NULL
23
+ - `like(source, pattern)`, `regexp(source, pattern)`
24
+ - `in(source, values[])`, `inQuery(source, queryable)` — `queryable` 은 1-컬럼 select 여야 함. `exists(queryable)`.
25
+
26
+ ### 논리
27
+ - `not(WhereExprUnit)`, `and(WhereExprUnit[])`, `or(WhereExprUnit[])` — 빈 배열은 throw.
28
+
29
+ ### 문자열 (→ `ExprUnit<string ...>`)
30
+ - `concat(...args)`, `left(s, n)`, `right(s, n)`, `trim(s)`
31
+ - `padStart(s, length, fillString)`, `replace(s, from, to)`
32
+ - `upper(s)`, `lower(s)`
33
+ - `length(s)` → number, `byteLength(s)` → number
34
+ - `substring(s, start, length?)`, `indexOf(s, search)` → number
35
+
36
+ ### 숫자
37
+ - `abs`, `round(s, digits)`, `ceil`, `floor`.
38
+
39
+ ### 날짜 (`DateUnit = "year"|"month"|"day"|"hour"|"minute"|"second"`)
40
+ - `year/month/day/hour/minute/second(source)`
41
+ - `isoWeek(d)`, `isoWeekStartDate(d)`, `isoYearMonth(d)`
42
+ - `dateDiff(unit, from, to)` → number
43
+ - `dateAdd(unit, source, value)`
44
+ - `formatDate(source, format: string)` — format 문자열은 dialect 변환.
45
+
46
+ ### NULL 처리 / 조건
47
+ - `coalesce(...args)` — 첫 non-null. 마지막 인자가 NonNullable 이면 반환 타입도 NonNullable.
48
+ - `nullIf(source, value)`
49
+ - `is(WhereExprUnit)` → `ExprUnit<boolean>` (boolean 변환)
50
+ - `if(condition, then, else_)` → `ExprUnit<T>` — 결과 dataType 은 ExprUnit/non-null 리터럴에서 추론.
51
+ - `switch<T>()` → `SwitchExprBuilder<T>` — `.case(cond, then).case(...).default(value)` 체이닝.
52
+
53
+ ### 집계 (GROUP BY 컨텍스트)
54
+ - `count(arg?, distinct?)` → number
55
+ - `sum(arg)`, `avg(arg)` → `number | undefined`
56
+ - `max(arg)`, `min(arg)` → `T | undefined`
57
+ - `greatest(...args)`, `least(...args)` — 행 내 최대/최소.
58
+
59
+ ### 기타 스칼라
60
+ - `rowNum()` → number — MSSQL `ROW_NUMBER() OVER(...)` 가 아니라 dialect 별 row 식별 함수 (간단 시퀀스).
61
+ - `random()` → number, 0~1.
62
+ - `cast(source, targetType: DataType)` — 결과 dataType 은 `dataTypeStrToColumnPrimitiveStr` 매핑.
63
+ - `subquery(dataType, queryable)` — 1-컬럼 select 의 스칼라 서브쿼리.
64
+
65
+ ### 윈도우 함수 (`WinSpecInput = { partitionBy?: ExprInput[], orderBy?: [ExprInput, "ASC"|"DESC"?][] }`)
66
+ - 순위: `rowNumber(spec)`, `rank(spec)`, `denseRank(spec)`, `ntile(n, spec)`
67
+ - 시퀀스 비교: `lag(column, spec, { offset?, default? })`, `lead(column, spec, { offset?, default? })`
68
+ - 첫/끝: `firstValue(column, spec)`, `lastValue(column, spec)`
69
+ - 집계 윈도우: `sumOver(column, spec)`, `avgOver(column, spec)`, `countOver(spec, column?)`, `minOver(column, spec)`, `maxOver(column, spec)`
70
+
71
+ ## 예시
72
+
73
+ ```ts
74
+ db.user()
75
+ .where(u => [
76
+ expr.eq(u.status, "active"),
77
+ expr.between(u.age, 18, 65),
78
+ expr.or([expr.like(u.name, "%kim%"), expr.like(u.email, "%kim%")]),
79
+ ])
80
+ .select(u => ({
81
+ name: expr.concat(u.firstName, " ", u.lastName),
82
+ rank: expr.rowNumber({ partitionBy: [u.deptId], orderBy: [[u.score, "DESC"]] }),
83
+ label: expr.switch<string>()
84
+ .case(expr.gte(u.score, 90), "A")
85
+ .case(expr.gte(u.score, 80), "B")
86
+ .default("C"),
87
+ }))
88
+ ```
89
+
90
+ ## Expr AST 타입
91
+
92
+ 세부 노드 타입은 `./types/expr` 의 union (`ExprColumn`/`ExprValue`/`ExprRaw`/...`ExprWindow`/`ExprSubquery`). 일반 사용자는 직접 다룰 필요 없음 — ExprRenderer 구현이나 디버깅·검증 시만.
@@ -0,0 +1,98 @@
1
+ # @simplysm/orm-common — Queryable
2
+
3
+ 체이닝 SELECT/INSERT/UPDATE/DELETE/UPSERT 빌더. `DbContext.queryable(builder)` 가 만든 팩토리 호출(`db.user()`)마다 새 alias 가 할당된 새 `Queryable` 이 반환된다. 모든 체이닝 메서드는 새 인스턴스를 반환(immutable).
4
+
5
+ ```ts
6
+ class Queryable<TData extends DataRecord, TFrom extends TableBuilder | never>
7
+ ```
8
+ - `TData` — 결과 row 타입 (관계 include 포함).
9
+ - `TFrom` — CUD(INSERT/UPDATE/DELETE/UPSERT) 시 필요한 원본 TableBuilder. `select`/`join`/`union`/`wrap`/`groupBy`/`recursive`/`distinct` 한 후엔 `never` 가 되어 CUD 불가.
10
+
11
+ ## 옵션 체이닝
12
+
13
+ - `.select(fn: cols => mapped)` — SELECT 컬럼/표현식 재구성. 원시 리터럴은 자동 `ExprUnit` 으로 래핑. → `Queryable<UnwrapQueryableRecord<R>, never>`.
14
+ - `.distinct()` — DISTINCT.
15
+ - `.lock()` — FOR UPDATE.
16
+ - `.top(n)` — TOP N (ORDER BY 무관).
17
+ - `.limit(skip, take)` — `orderBy` 필수, 없으면 throw.
18
+ - `.orderBy(fn | "key.path", "ASC" | "DESC"?)` — 누적. 문자열 overload 는 `obj.getChainValue` 로 컬럼 검색 (동적 정렬용).
19
+ - `.where(predicate: cols => WhereExprUnit[])` — 누적, AND 결합.
20
+ - `.search(cols => ExprUnit<string|undefined>[], text)` — `parseSearchQuery` 의 OR/AND(`+`)/NOT(`-`)/`"…"`/`*` 구문을 컬럼들에 LIKE 로 적용 (소문자 비교).
21
+ - `.groupBy(cols => ExprUnit[])` — `TFrom` → never.
22
+ - `.having(predicate)` — GROUP BY 후 필터, 누적 AND.
23
+
24
+ ## JOIN / INCLUDE
25
+
26
+ ```ts
27
+ .join(as, (qr, cols) => Queryable) // 1:N — { ..., [as]?: R[] }
28
+ .joinSingle(as, (qr, cols) => Queryable) // N:1 또는 1:1 — { ..., [as]?: R }
29
+ .include(item => item.user.company) // PathProxy 기반 자동 JOIN (TableBuilder 기반만)
30
+ ```
31
+
32
+ - 콜백의 `qr: JoinQueryable` 은 `.from(table)` / `.select(customCols)` / `.union(...queries)` 제공.
33
+ - `.include` 는 `TableBuilder.relations` 정의를 따라 FK/RelationKey(=joinSingle) 또는 FKT/RelationKeyTarget(=join, `single:true` 면 joinSingle) 으로 풀림. 동일 경로 중복 호출은 무시. 다단계(`a.b.c`)는 부모 객체 안으로 nested 됨.
34
+ - PathProxy 는 ColumnPrimitive 필드 접근을 컴파일 에러로 막아 관계 키만 허용.
35
+
36
+ ## Subquery / UNION / Recursive CTE
37
+
38
+ - `.wrap()` — 현재 Queryable 을 서브쿼리로 감싼 새 Queryable. `distinct()`/`groupBy()` 후 `count()` 직전에 필요.
39
+ - `Queryable.union(q1, q2, ...)` (static) — UNION (중복 제거). 2개 미만 throw. 첫 query 의 컬럼 구조 사용.
40
+ - `.recursive(fn: (cte: RecursiveQueryable<TData>) => Queryable<TData>)` — WITH RECURSIVE 생성. 콜백 안에서 `cte.from(table)` 한 결과에 `self` 프로퍼티(현재 CTE 자기 참조)가 부여됨. `.union(...)` 도 가능.
41
+
42
+ ## 실행 (SELECT)
43
+
44
+ - `await qr.execute(): Promise<TData[]>`
45
+ - `await qr.single(): Promise<TData | undefined>` — 2개 이상이면 throw.
46
+ - `await qr.first(): Promise<TData | undefined>` — 내부 `top(1)`.
47
+ - `await qr.count(fn?): Promise<number>` — `distinct`/`groupBy` 후 직접 호출시 throw → `wrap()` 필요.
48
+ - `await qr.exists(): Promise<boolean>` — `top(1)` 으로 행 존재 확인.
49
+
50
+ ## CUD (TFrom = TableBuilder 필요)
51
+
52
+ ```ts
53
+ await q.insert(records);
54
+ const [{ id }] = await q.insert([{...}], ["id"]); // OUTPUT
55
+
56
+ await q.insertIfNotExists(record); // WHERE 조건과 결합
57
+ await q.insertIfNotExists(record, ["id"]); // 단건 반환
58
+
59
+ await q2.insertInto(TargetTable); // INSERT INTO ... SELECT
60
+ await q2.insertInto(TargetTable, ["id"]);
61
+
62
+ await q.update(cols => ({ name: expr.val("string", "x") }));
63
+ await q.update(cols => ({...}), ["id"]);
64
+
65
+ await q.delete();
66
+ await q.delete(["id", "name"]);
67
+
68
+ await q.upsert(updateFn); // UPDATE 또는 INSERT (existsSelectQuery=현재 where)
69
+ await q.upsert(updateFn, ["id"]);
70
+ await q.upsert(updateFn, insertFn);
71
+ await q.upsert(updateFn, insertFn, ["id"]);
72
+ ```
73
+
74
+ - `insert(records)` 는 records 0건이면 noop. MSSQL 1000행 제한을 위해 청크 분할(`CHUNK_SIZE=1000`) — 각 청크는 별도 `executeDefs` 호출, OUTPUT 도 누적.
75
+ - `insert` 의 records 에 autoIncrement 컬럼 값이 명시되면 자동으로 `overrideIdentity` 켜짐.
76
+ - CUD 는 `TFrom` 이 `TableBuilder` 일 때만 — 아니면 `_getCudOutputDef` 에서 throw. ViewBuilder/Queryable 합성/Union 후엔 사용 불가.
77
+ - `await q.switchFk(enabled)` — TableBuilder/ViewBuilder 기반에서 FK on/off (트랜잭션 내 사용 가능).
78
+
79
+ ## QueryDef 생성기 (실행 없이 def 만)
80
+
81
+ `getSelectQueryDef()`, `getInsertQueryDef(records, output?)`, `getInsertIfNotExistsQueryDef(record, output?)`, `getInsertIntoQueryDef(target, output?)`, `getUpdateQueryDef(recordFwd, output?)`, `getDeleteQueryDef(output?)`, `getUpsertQueryDef(updateFn, insertFn, output?)`, `getResultMeta(outputColumns?)`.
82
+
83
+ ## 타입
84
+
85
+ `QueryableRecord<TData>` — `TData` 의 원시 필드를 `ExprUnit<T>`, 중첩 객체/배열은 재귀로 감싼 형태. `where`/`select` 콜백 인자 타입.
86
+
87
+ `QueryableWriteRecord<TData>` — `ExprInput<T>` (= `ExprUnit<T> | T`) 으로, `update`/`upsert` 의 record 값 입력 타입.
88
+
89
+ `UnwrapQueryableRecord<R>` — `.select` 결과를 다시 DataRecord 로 역추론.
90
+
91
+ `PathProxy<T>` — `.include` 인자 타입. 비-ColumnPrimitive 필드만 노출.
92
+
93
+ ## 보조 함수
94
+
95
+ ```ts
96
+ queryable(db, tableOrView, as?) // Queryable factory 생성. DbContext.queryable 의 내부 구현
97
+ getMatchedPrimaryKeys(fkCols, targetTable) // include 가 FK 컬럼과 대상 PK 매칭
98
+ ```
@@ -0,0 +1,128 @@
1
+ # @simplysm/orm-common — Schema Builders
2
+
3
+ 테이블/뷰/프로시저를 fluent 로 정의하는 immutable 빌더. `DbContext` 의 `queryable()`/`executable()` 에 전달하여 등록한다. 모든 메서드는 `new Xxx({...this.meta, ...})` 형태로 새 인스턴스 반환.
4
+
5
+ ## Table / TableBuilder
6
+
7
+ ```ts
8
+ import { Table } from "@simplysm/orm-common";
9
+
10
+ const User = Table("User") // Table<TName>(name)
11
+ .database("mydb")
12
+ .schema("dbo") // MSSQL/PostgreSQL only
13
+ .description("사용자")
14
+ .columns((c) => ({
15
+ id: c.bigint().autoIncrement(),
16
+ name: c.varchar(100),
17
+ email: c.varchar(200).nullable(),
18
+ status: c.varchar(20).default("active"),
19
+ }))
20
+ .primaryKey("id") // 복합: .primaryKey("a","b")
21
+ .indexes((i) => [i.index("email").unique()])
22
+ .relations((r) => ({
23
+ posts: r.foreignKeyTarget(() => Post, "author"),
24
+ }));
25
+ ```
26
+
27
+ 타입 추론 프로퍼티 (`readonly $xxx!` — 런타임 값 X, 타입 추출용):
28
+ - `$inferSelect` — 컬럼 + (deep) 관계 (관계는 optional)
29
+ - `$inferColumns` — 컬럼만
30
+ - `$inferInsert` — `autoIncrement`/`nullable`/`default` 컬럼은 optional
31
+ - `$inferUpdate` — 모든 필드 optional
32
+ - `$columns`, `$relations` — 정의 자체
33
+
34
+ `meta`: `{ name; description?; database?; schema?; columns?; primaryKey?; relations?; indexes? }`.
35
+
36
+ ## View / ViewBuilder
37
+
38
+ ```ts
39
+ import { View } from "@simplysm/orm-common";
40
+
41
+ const ActiveUsers = View("ActiveUsers")
42
+ .database("mydb")
43
+ .query((db: MainDb) =>
44
+ db.user().where(u => [expr.eq(u.status, "active")])
45
+ .select(u => ({ id: u.id, name: u.name })))
46
+ .relations(r => ({ posts: r.relationKeyTarget(() => Post, "author") }));
47
+ ```
48
+
49
+ - `.query<TData>(viewFn: (db) => Queryable<TData>)` 의 viewFn 은 `queryable()` 호출시(=`createView` DDL 만들 때, `db.queryable(ViewBuilder)` 팩토리에서) 실행된다.
50
+ - View 의 관계는 `relationKey`/`relationKeyTarget` 만 사용 (DB FK 미생성).
51
+ - `$inferSelect: TData`.
52
+
53
+ ## Procedure / ProcedureBuilder
54
+
55
+ ```ts
56
+ import { Procedure } from "@simplysm/orm-common";
57
+
58
+ const GetUserById = Procedure("GetUserById")
59
+ .database("mydb")
60
+ .params(c => ({ userId: c.bigint() }))
61
+ .returns(c => ({ id: c.bigint(), name: c.varchar(100) }))
62
+ .body("SELECT id, name FROM User WHERE id = userId");
63
+ // MSSQL 본문은 @userId 사용. PostgreSQL 은 RETURN QUERY 필요.
64
+ ```
65
+
66
+ `$params`, `$returns` 타입 추론. `meta`: `{ name; description?; database?; schema?; params?; returns?; query? }`.
67
+
68
+ ## Column Factory (`columns((c) => ...)` 안에서 사용)
69
+
70
+ `createColumnFactory()` 반환 객체의 메서드 — 모두 `ColumnBuilder<TValue, TMeta>` 반환:
71
+
72
+ | 메서드 | TS 타입 | SQL 매핑 |
73
+ |---|---|---|
74
+ | `int()` | number | INT |
75
+ | `bigint()` | number | BIGINT |
76
+ | `float()` | number | FLOAT/REAL |
77
+ | `double()` | number | DOUBLE |
78
+ | `decimal(precision, scale?)` | number | DECIMAL(p,s) |
79
+ | `varchar(length)` | string | VARCHAR(n) |
80
+ | `char(length)` | string | CHAR(n) |
81
+ | `text()` | string | TEXT/LONGTEXT |
82
+ | `binary()` | Bytes | LONGBLOB/VARBINARY(MAX)/BYTEA |
83
+ | `boolean()` | boolean | TINYINT(1)/BIT/BOOLEAN |
84
+ | `datetime()` | DateTime | DATETIME |
85
+ | `date()` | DateOnly | DATE |
86
+ | `time()` | Time | TIME |
87
+ | `uuid()` | Uuid | BINARY(16)/UNIQUEIDENTIFIER/UUID |
88
+
89
+ `ColumnBuilder` 체이닝:
90
+ - `.autoIncrement()` — INSERT 시 자동 증가, `$inferInsert` 에서 optional.
91
+ - `.nullable()` — TS 타입에 `| undefined` 추가.
92
+ - `.default(value)` — 기본값. `$inferInsert` 에서 optional.
93
+ - `.description(text)` — DDL Comment.
94
+
95
+ 타입 유틸: `ColumnBuilderRecord`, `InferColumns<T>`, `InferColumnExprs<T>` (Executable params), `RequiredInsertKeys<T>`, `OptionalInsertKeys<T>`, `InferInsertColumns<T>`, `InferUpdateColumns<T>`, `DataToColumnBuilderRecord<TData>`.
96
+
97
+ ## Index Factory (`indexes((i) => ...)` 안에서)
98
+
99
+ ```ts
100
+ i.index("email").unique()
101
+ i.index("name", "createdAt").orderBy("ASC", "DESC")
102
+ i.index("createdAt").name("IX_Foo")
103
+ i.index("a").description("...")
104
+ ```
105
+
106
+ `IndexBuilder<TKeys>` 의 `meta`: `{ columns; name?; unique?; orderBy?; description? }`.
107
+
108
+ ## Relation Factory (`relations((r) => ...)` 안에서)
109
+
110
+ Table 은 4개 모두, View 는 `relationKey`/`relationKeyTarget` 만 노출.
111
+
112
+ ```ts
113
+ // N:1
114
+ r.foreignKey(["authorId"], () => User, { description?: string }) // DB FK 생성
115
+ r.relationKey(["companyId"], () => Company, { description?: string }) // 논리 관계 (FK X) — View 가능
116
+
117
+ // 1:N (기본) 또는 1:1 (single: true)
118
+ r.foreignKeyTarget(() => Post, "author")
119
+ r.foreignKeyTarget(() => Profile, "user", { single: true })
120
+ r.relationKeyTarget(() => UserSummary, "company", { single?, description? })
121
+ ```
122
+
123
+ - `foreignKey` 의 두 번째 인자는 *대상 테이블 factory* `() => TableBuilder` (순환 참조 회피).
124
+ - `foreignKeyTarget` 의 두 번째 인자 `relationName` 은 대상 테이블에 정의된 자기방향 FK 의 키 이름.
125
+ - 메서드 체이닝(`.description()`/`.single()`)은 TS 순환 참조 (TS7022) 회피용으로 *제거됨* — 옵션은 마지막 `opts` 객체로만 전달.
126
+ - 빌더 클래스: `ForeignKeyBuilder`, `ForeignKeyTargetBuilder`, `RelationKeyBuilder`, `RelationKeyTargetBuilder`.
127
+
128
+ 타입 유틸: `RelationBuilderRecord`, `ExtractRelationTarget<T>`, `ExtractRelationTargetResult<T>`, `InferDeepRelations<TRelations>` — 모두 관계를 optional 로 추론, 같은 테이블 재방문 시 더 깊이 들어가지 않음 (순환 끊김).
@@ -0,0 +1,59 @@
1
+ # @simplysm/orm-node
2
+
3
+ Node.js 환경에서 `@simplysm/orm-common` 의 `DbContext` 를 실제 DB(MSSQL/MySQL/PostgreSQL)에 붙여 실행하기 위한 어댑터. 드라이버 모듈(`tedious`/`mysql2`/`pg`/`pg-copy-streams`)은 dialect 선택 시점에 지연 import.
4
+
5
+ ## 사용 트리거 인덱스
6
+
7
+ - **`createOrm` / `Orm` / `OrmOptions`** — `DbContext` 서브클래스 + `DbConnConfig` 로 ORM 인스턴스를 만들고, 트랜잭션 유/무 콜백을 실행한다. 일반 ORM 사용의 진입점.
8
+ - **`createDbConn`** — `DbConnConfig` 만으로 저수준 `DbConn` 인스턴스를 직접 만든다. `DbContext` 없이 raw SQL/bulk insert 가 필요할 때.
9
+ - **`NodeDbContextExecutor`** — `DbContext` 의 executor 직접 주입이 필요할 때. 일반적으로는 `createOrm` 이 내부적으로 사용.
10
+ - **`MysqlDbConn` / `MssqlDbConn` / `PostgresqlDbConn`** — dialect별 `DbConn` 구현. 직접 `new` 하지 말고 `createDbConn` 사용. 타입 참조용으로만 import.
11
+ - **`DbConn` / `DbConnConfig` (+ `MysqlDbConnConfig` / `MssqlDbConnConfig` / `PostgresqlDbConnConfig`)** — 설정/연결 타입. 함수 시그니처·DI 토큰 등에서 참조.
12
+ - **`getDialectFromConfig`** — `DbConnConfig` → `Dialect` 변환(`mssql-azure` → `mssql`). 쿼리 빌더 선택 시.
13
+ - **`DB_CONN_CONNECT_TIMEOUT` (10s) / `DB_CONN_DEFAULT_TIMEOUT` (10m) / `DB_CONN_ERRORS`** — 타임아웃·에러 메시지 상수.
14
+
15
+ ## createOrm
16
+
17
+ ```ts
18
+ function createOrm<T extends DbContext>(
19
+ DbClass: new (executor: DbContextExecutor, opt: { database: string; schema?: string }) => T,
20
+ config: DbConnConfig,
21
+ options?: OrmOptions, // { database?: string; schema?: string } — config 보다 우선
22
+ ): Orm<T>;
23
+
24
+ interface Orm<T> {
25
+ connect<R>(cb: (db: T) => Promise<R>, isolationLevel?: IsolationLevel): Promise<R>; // 트랜잭션
26
+ connectWithoutTransaction<R>(cb: (db: T) => Promise<R>): Promise<R>; // 트랜잭션 없음
27
+ }
28
+ ```
29
+
30
+ `database` 가 `options` 와 `config` 양쪽 모두 없으면 throw. 매 `connect*` 호출마다 새 `DbContext` 인스턴스를 만들어 콜백 종료 시 연결을 닫는다.
31
+
32
+ ```ts
33
+ const orm = createOrm(MyDb, { dialect: "mysql", host, port, username, password, database });
34
+ await orm.connect(async (db) => db.user().execute());
35
+ ```
36
+
37
+ ## createDbConn
38
+
39
+ ```ts
40
+ function createDbConn(config: DbConnConfig): Promise<DbConn>;
41
+ ```
42
+
43
+ dialect 에 따라 드라이버 모듈을 lazy import 한 뒤 해당 `DbConn` 구현 반환. **반환된 객체는 미연결 상태** — 호출자가 `conn.connect()` → 사용 → `conn.close()` 까지 책임. `DbConn` 은 `EventEmitter<{ close: void }>` 이며 다음 메서드 제공: `connect`, `close`, `beginTransaction(isolationLevel?)`, `commitTransaction`, `rollbackTransaction`, `execute(queries: string[])`, `executeParametrized(query, params?)`, `bulkInsert(tableName, columnMetas, records)`. `bulkInsert` 는 dialect별 네이티브 경로 사용(MSSQL: tedious BulkLoad / MySQL: `LOAD DATA LOCAL INFILE` 임시파일 / PostgreSQL: `COPY FROM STDIN`).
44
+
45
+ ## DbConnConfig
46
+
47
+ dialect 분기 union. 공통 필드: `host`, `port?`, `username`, `password`, `database?`, `defaultIsolationLevel?`.
48
+
49
+ - `MysqlDbConnConfig` — `dialect: "mysql"`.
50
+ - `MssqlDbConnConfig` — `dialect: "mssql" | "mssql-azure"`, `schema?`. `mssql-azure` 는 `encrypt: true` 로 연결.
51
+ - `PostgresqlDbConnConfig` — `dialect: "postgresql"`, `schema?`.
52
+
53
+ ## NodeDbContextExecutor
54
+
55
+ ```ts
56
+ new NodeDbContextExecutor(config: DbConnConfig)
57
+ ```
58
+
59
+ `DbContextExecutor` 구현. `connect` 시 내부에서 `createDbConn` + `conn.connect()` 수행. `executeDefs(defs, resultMetas?)` 는 `@simplysm/orm-common` 의 `createQueryBuilder` + `parseQueryResult` 를 사용해 `QueryDef[]` → SQL → 파싱 결과. `resultMetas` 가 전부 `null` 인 경우 단일 결합 SQL 1회로 묶어 실행. 미연결 상태에서 메서드 호출 시 `DB_CONN_ERRORS.NOT_CONNECTED` SdError throw.
@@ -0,0 +1,9 @@
1
+ # @simplysm/sd-claude
2
+
3
+ Claude Code 셋업 자산(`.claude/` 의 sd-* 스킬·룰·훅) 배포 및 `sd-claude` CLI 제공 패키지.
4
+
5
+ 코드 API 없음 (npm 배포용). 외부에서 import 할 수 있는 라이브러리 심볼은 노출하지 않는다.
6
+
7
+ - `bin`: `sd-claude` — `auth save` / `auth switch` (저장된 Claude 계정 전환).
8
+ - `postinstall`: 설치 시 사용자 `~/.claude/` 로 자산 동기화.
9
+ - `prepack`: 배포 전 `.claude/` → `packages/sd-claude/claude/` 증분 복사.
@@ -0,0 +1,50 @@
1
+ # @simplysm/sd-cli
2
+
3
+ 워크스페이스 빌드/배포 오케스트레이터. 라이브러리 export 는 `sd.config.ts` 작성용 타입과 Vitest Angular 플러그인, 그리고 외부 도구가 재사용할 `SdTsCompiler` 다. CLI 서브커맨드는 이 문서 대상 아님 (`pnpm sd-cli --help`).
4
+
5
+ ## 사용 트리거 인덱스
6
+ - **`SdConfigFn` / `SdConfig` / `SdConfigParams`** — `sd.config.ts` 의 default export 타이핑. 자세히: [sd-config.md](./sd-config.md)
7
+ - **패키지별 설정 타입 (`SdBuildPackageConfig`, `SdClientPackageConfig`, `SdServerPackageConfig`, `SdScriptsPackageConfig`)** — `SdConfig.packages` 값 타이핑. 자세히: [sd-config.md](./sd-config.md)
8
+ - **`SdPublishConfig` / `SdPostPublishScriptConfig`** — `publish`·`postPublish` 항목 타이핑. 자세히: [sd-config.md](./sd-config.md)
9
+ - **`SdCapacitorConfig` / `SdElectronConfig` / `SdPwaConfig` / `SdBrowserSupportConfig`** — 클라이언트 패키지의 모바일/데스크톱/PWA/브라우저 지원 옵션. 자세히: [sd-config.md](./sd-config.md)
10
+ - **`sdAngularPlugin(options)`** — Vitest 의 `vite.config` (또는 `vitest.config`) 에서 Angular 패키지 AOT 컴파일이 필요할 때 plugin 으로 추가.
11
+ - **`SdTsCompiler` (+ `ISdTsCompilerOptions`, `ISdTsCompilerResult`)** — 사용자 코드에서 직접 호출할 일은 거의 없음. Angular/Non-Angular TS 패키지를 증분 컴파일·진단·lint·SCSS 통합 처리하는 엔진. `sd-cli` 내부 엔진(`engines/`, `orchestrators/`) 및 `sdAngularPlugin` 에서 사용. 외부에서 동일한 엔진을 재사용해야 할 때만 직접 import.
12
+
13
+ ## sdAngularPlugin
14
+
15
+ ```typescript
16
+ import { sdAngularPlugin, type SdAngularPluginOptions } from "@simplysm/sd-cli";
17
+
18
+ // vitest.config.ts
19
+ plugins: [sdAngularPlugin({ pkg: "angular" })]
20
+ ```
21
+
22
+ `pkg` 는 `sd.config.ts.packages` 키 (= `packages/<pkg>/` 디렉토리명). 패키지의 `.ts` 를 AOT 컴파일해 `transform` 훅에서 JS 로 치환한다. `tsconfig.json` 의 `angularCompilerOptions` 유무로 Angular 모드를 자동 감지. Vitest watch 의 `watchChange` 를 받아 증분 재컴파일. 첫 `buildStart` 전에 `config()` 호출 필수 (Vitest 가 자동 호출).
23
+
24
+ ## SdTsCompiler
25
+
26
+ ```typescript
27
+ import { SdTsCompiler } from "@simplysm/sd-cli";
28
+
29
+ const compiler = new SdTsCompiler({
30
+ pkgDir: "/abs/path/to/packages/foo",
31
+ cwd: "/abs/path/to/workspace",
32
+ output: { js: true, dts: false }, // 출력 제어 — 둘 다 false 면 typecheck only
33
+ includeTests: false, // true 면 tests/ 도 rootNames 에 포함
34
+ lint: false,
35
+ globalScss: false,
36
+ });
37
+ const result = await compiler.compileAsync(/* modifiedFiles? */);
38
+ // result.diagnostics, result.errorCount, result.emitResults (Angular), ...
39
+ ```
40
+
41
+ 특징:
42
+ - 인스턴스를 재사용해 호출 간 incremental 빌드 (`tsBuildInfoFile` 은 `<pkgDir>/.cache/` 하위).
43
+ - `compileAsync(modifiedFiles)` 의 modifiedFiles 는 watch 모드의 변경 파일. 미전달 시 전체 affected 탐색.
44
+ - Angular 패키지(`tsconfig.angularCompilerOptions`)는 자동으로 NgtscProgram 사용. 결과의 `emitResults: { filename, contents, sourceFileName }[]` 를 호출자가 디스크/번들러에 전달. Non-Angular 은 `host.writeFile` 로 디스크에 직접 emit (결과의 `emitResults` undefined).
45
+ - `compilerOptionsTransformer` 로 target/module/outDir 등을 후처리 override 가능.
46
+ - `transformStylesheet`, `externalStylesheets`, `sourceFileCache` 는 Angular 클라이언트 빌드 통합용 (esbuild 플러그인이 사용).
47
+ - 단계별 try/catch 로 부분 복구 — 한 단계 실패해도 다른 진단/emit 결과는 유지.
48
+ - 결과의 `affectedFiles` 가 `undefined` 면 전역 변경 (전체 리빌드 신호).
49
+
50
+ 전체 옵션·결과 필드 정의는 `packages/sd-cli/src/ts-compiler/sd-ts-compiler-options.ts`, `sd-ts-compiler-result.ts` 참조.