@ngockhoale/ukit 1.1.6

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 (344) hide show
  1. package/CHANGELOG.md +179 -0
  2. package/LICENSE +21 -0
  3. package/README.md +189 -0
  4. package/bin/ukit +30 -0
  5. package/manifests/platform.full.yaml +1194 -0
  6. package/package.json +71 -0
  7. package/scripts/bug/triage.mjs +37 -0
  8. package/scripts/index/build-index.mjs +35 -0
  9. package/scripts/index/query-index.mjs +92 -0
  10. package/scripts/index/refresh-index.mjs +85 -0
  11. package/scripts/release/verify-release.mjs +56 -0
  12. package/src/bug/triageBug.js +123 -0
  13. package/src/cli/adapters.js +148 -0
  14. package/src/cli/commands/diff.js +51 -0
  15. package/src/cli/commands/doctor.js +125 -0
  16. package/src/cli/commands/indexArgs.js +73 -0
  17. package/src/cli/commands/indexTools.js +509 -0
  18. package/src/cli/commands/install.js +293 -0
  19. package/src/cli/commands/memory.js +126 -0
  20. package/src/cli/commands/status.js +8 -0
  21. package/src/cli/commands/uninstall.js +51 -0
  22. package/src/cli/index.js +109 -0
  23. package/src/context/detectProjectContext.js +49 -0
  24. package/src/context/detectProviders.js +12 -0
  25. package/src/core/applyPlan.js +89 -0
  26. package/src/core/buildPlan.js +228 -0
  27. package/src/core/compact/index.js +294 -0
  28. package/src/core/compact/threshold.js +936 -0
  29. package/src/core/diffPlan.js +73 -0
  30. package/src/core/ensureGitignore.js +117 -0
  31. package/src/core/fileOps.js +188 -0
  32. package/src/core/memory/hygiene.js +160 -0
  33. package/src/core/memory/index.js +2 -0
  34. package/src/core/memory/retrieval.js +476 -0
  35. package/src/core/memory/store.js +202 -0
  36. package/src/core/metadata.js +132 -0
  37. package/src/core/migrateLegacy.js +139 -0
  38. package/src/core/output/index.js +1309 -0
  39. package/src/core/paths.js +13 -0
  40. package/src/core/report.js +17 -0
  41. package/src/core/router/advisor.js +42 -0
  42. package/src/core/router/index.js +2 -0
  43. package/src/core/router/router.js +164 -0
  44. package/src/core/runInstallPipeline.js +365 -0
  45. package/src/core/runtimeConfig.js +190 -0
  46. package/src/core/runtimePaths.js +24 -0
  47. package/src/core/status.js +186 -0
  48. package/src/core/token/index.js +328 -0
  49. package/src/core/uninstall.js +246 -0
  50. package/src/core/validation/confidence.js +89 -0
  51. package/src/core/validation/index.js +2 -0
  52. package/src/core/validation/validator.js +165 -0
  53. package/src/index/buildIndex.js +1392 -0
  54. package/src/index/gitHooks.js +109 -0
  55. package/src/index/importResolution.js +377 -0
  56. package/src/index/languageTools.js +127 -0
  57. package/src/index/paths.js +27 -0
  58. package/src/index/queryIndex.js +637 -0
  59. package/src/index/relatedTests.js +237 -0
  60. package/src/index/resolveContext.js +345 -0
  61. package/src/index/routeCatalog.js +258 -0
  62. package/src/index/taskRouting.js +677 -0
  63. package/src/index/verificationPlan.js +437 -0
  64. package/src/manifest/loadManifest.js +22 -0
  65. package/src/manifest/selectItems.js +78 -0
  66. package/src/manifest/validateManifest.js +115 -0
  67. package/src/render/buildVariables.js +39 -0
  68. package/src/render/renderTemplate.js +44 -0
  69. package/src/stack/detectStack.js +213 -0
  70. package/templates/.claude/agents/bug-debugger.md +57 -0
  71. package/templates/.claude/agents/feature-implementer.md +55 -0
  72. package/templates/.claude/config/providers.md +25 -0
  73. package/templates/.claude/hooks/auto-allow-bash.sh +155 -0
  74. package/templates/.claude/hooks/auto-prune-bash.sh +75 -0
  75. package/templates/.claude/hooks/block-dangerous.sh +54 -0
  76. package/templates/.claude/hooks/compress-output.sh +17 -0
  77. package/templates/.claude/hooks/protect-files.sh +37 -0
  78. package/templates/.claude/hooks/reinject-context.sh +28 -0
  79. package/templates/.claude/hooks/session-start.md +13 -0
  80. package/templates/.claude/hooks/skill-router.sh +1681 -0
  81. package/templates/.claude/hooks/verification-guard.sh +271 -0
  82. package/templates/.claude/settings.json +144 -0
  83. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  84. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  85. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  86. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  87. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  88. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  89. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  90. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  91. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  92. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  93. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  94. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  95. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  96. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  97. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  98. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  99. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  100. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  101. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  102. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  103. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  104. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  105. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  106. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  107. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  108. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  109. package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  110. package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  111. package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  112. package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  113. package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  114. package/templates/.claude/skills/_shared/ooxml/schemas/mce/mc.xsd +75 -0
  115. package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  116. package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  117. package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  118. package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  119. package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  120. package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  121. package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  122. package/templates/.claude/skills/_shared/ooxml/scripts/pack.py +159 -0
  123. package/templates/.claude/skills/_shared/ooxml/scripts/unpack.py +29 -0
  124. package/templates/.claude/skills/_shared/ooxml/scripts/validate.py +69 -0
  125. package/templates/.claude/skills/_shared/ooxml/scripts/validation/__init__.py +15 -0
  126. package/templates/.claude/skills/_shared/ooxml/scripts/validation/base.py +951 -0
  127. package/templates/.claude/skills/_shared/ooxml/scripts/validation/docx.py +274 -0
  128. package/templates/.claude/skills/_shared/ooxml/scripts/validation/pptx.py +315 -0
  129. package/templates/.claude/skills/_shared/ooxml/scripts/validation/redlining.py +279 -0
  130. package/templates/.claude/skills/backend-api/SKILL.md +26 -0
  131. package/templates/.claude/skills/canvas-design/LICENSE.txt +202 -0
  132. package/templates/.claude/skills/canvas-design/SKILL.md +130 -0
  133. package/templates/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  134. package/templates/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  135. package/templates/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  136. package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  137. package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  138. package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  139. package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  140. package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  141. package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  142. package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  143. package/templates/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  144. package/templates/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  145. package/templates/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  146. package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  147. package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  148. package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  149. package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  150. package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  151. package/templates/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  152. package/templates/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  153. package/templates/.claude/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  154. package/templates/.claude/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  155. package/templates/.claude/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  156. package/templates/.claude/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  157. package/templates/.claude/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  158. package/templates/.claude/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  159. package/templates/.claude/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  160. package/templates/.claude/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  161. package/templates/.claude/skills/code-review/SKILL.md +97 -0
  162. package/templates/.claude/skills/debugging-toolkit/SKILL.md +156 -0
  163. package/templates/.claude/skills/delivery/SKILL.md +92 -0
  164. package/templates/.claude/skills/discover-security/SKILL.md +86 -0
  165. package/templates/.claude/skills/docker-packaging/SKILL.md +60 -0
  166. package/templates/.claude/skills/docs-manager/SKILL.md +465 -0
  167. package/templates/.claude/skills/docs-manager/init-project-docs.sh +70 -0
  168. package/templates/.claude/skills/docs-manager/templates/README.md.template +50 -0
  169. package/templates/.claude/skills/docs-manager/templates/agent-roles.md.template +24 -0
  170. package/templates/.claude/skills/docs-manager/templates/coding-conventions.md.template +28 -0
  171. package/templates/.claude/skills/docs-manager/templates/memory.md.template +30 -0
  172. package/templates/.claude/skills/docs-manager/templates/onboarding.md.template +20 -0
  173. package/templates/.claude/skills/docs-manager/templates/project.md.template +26 -0
  174. package/templates/.claude/skills/docs-quality/SKILL.md +148 -0
  175. package/templates/.claude/skills/docx/LICENSE.txt +30 -0
  176. package/templates/.claude/skills/docx/SKILL.md +197 -0
  177. package/templates/.claude/skills/docx/docx-js.md +350 -0
  178. package/templates/.claude/skills/docx/ooxml.md +610 -0
  179. package/templates/.claude/skills/docx/scripts/__init__.py +1 -0
  180. package/templates/.claude/skills/docx/scripts/document.py +1276 -0
  181. package/templates/.claude/skills/docx/scripts/templates/comments.xml +3 -0
  182. package/templates/.claude/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  183. package/templates/.claude/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  184. package/templates/.claude/skills/docx/scripts/templates/commentsIds.xml +3 -0
  185. package/templates/.claude/skills/docx/scripts/templates/people.xml +3 -0
  186. package/templates/.claude/skills/docx/scripts/utilities.py +374 -0
  187. package/templates/.claude/skills/duraone/SKILL.md +204 -0
  188. package/templates/.claude/skills/duraone/references/backend.md +636 -0
  189. package/templates/.claude/skills/duraone/references/frontend.md +1506 -0
  190. package/templates/.claude/skills/duraone/references/sql.md +631 -0
  191. package/templates/.claude/skills/duraone/references/workflow.md +520 -0
  192. package/templates/.claude/skills/executing-plans/SKILL.md +76 -0
  193. package/templates/.claude/skills/file-organizer/SKILL.md +433 -0
  194. package/templates/.claude/skills/frontend/SKILL.md +26 -0
  195. package/templates/.claude/skills/frontend-design/LICENSE.txt +177 -0
  196. package/templates/.claude/skills/frontend-design/SKILL.md +42 -0
  197. package/templates/.claude/skills/frontend-vue/SKILL.md +127 -0
  198. package/templates/.claude/skills/frontend-vue/components/Control/Box.vue +137 -0
  199. package/templates/.claude/skills/frontend-vue/components/Control/Button.vue +93 -0
  200. package/templates/.claude/skills/frontend-vue/components/Control/ButtonBar.vue +29 -0
  201. package/templates/.claude/skills/frontend-vue/components/Control/ButtonFloat.vue +62 -0
  202. package/templates/.claude/skills/frontend-vue/components/Control/CheckButton.vue +75 -0
  203. package/templates/.claude/skills/frontend-vue/components/Control/Checkbox.vue +58 -0
  204. package/templates/.claude/skills/frontend-vue/components/Control/Datetime.vue +148 -0
  205. package/templates/.claude/skills/frontend-vue/components/Control/Dropdownlist.vue +156 -0
  206. package/templates/.claude/skills/frontend-vue/components/Control/Input.vue +106 -0
  207. package/templates/.claude/skills/frontend-vue/components/Control/Label.vue +38 -0
  208. package/templates/.claude/skills/frontend-vue/components/Control/Master/BoxColumn.vue +24 -0
  209. package/templates/.claude/skills/frontend-vue/components/Control/Popup/Confirm.vue +33 -0
  210. package/templates/.claude/skills/frontend-vue/components/Control/Popup/Info.vue +32 -0
  211. package/templates/.claude/skills/frontend-vue/components/Control/Popup/ModalInfo.vue +39 -0
  212. package/templates/.claude/skills/frontend-vue/components/Control/Popup/Reject.vue +64 -0
  213. package/templates/.claude/skills/frontend-vue/components/Control/Tag.vue +82 -0
  214. package/templates/.claude/skills/frontend-vue/components/Control/Upload.vue +61 -0
  215. package/templates/.claude/skills/frontend-vue/components/ControlMobile/Dropdownlist.vue +103 -0
  216. package/templates/.claude/skills/frontend-vue/components/ControlMobile/PagingBar.vue +108 -0
  217. package/templates/.claude/skills/frontend-vue/components/ControlMobile/UploadImage.vue +137 -0
  218. package/templates/.claude/skills/frontend-vue/components/Grid/AG.vue +806 -0
  219. package/templates/.claude/skills/frontend-vue/components/Grid/AntTable.vue +253 -0
  220. package/templates/.claude/skills/frontend-vue/components/Grid/CustomDropdownEditor.vue +43 -0
  221. package/templates/.claude/skills/frontend-vue/components/Grid/CustomDropdownEditorEnable.vue +55 -0
  222. package/templates/.claude/skills/frontend-vue/components/Grid/HtmlTable.vue +40 -0
  223. package/templates/.claude/skills/frontend-vue/components/PDFViewer.vue +25 -0
  224. package/templates/.claude/skills/frontend-vue/components/Panel/FormView.vue +309 -0
  225. package/templates/.claude/skills/frontend-vue/components/Partial/Footer.vue +23 -0
  226. package/templates/.claude/skills/frontend-vue/components/Partial/Header.vue +265 -0
  227. package/templates/.claude/skills/frontend-vue/components/Partial/Sidebar.vue +122 -0
  228. package/templates/.claude/skills/frontend-vue/components/Template.vue +16 -0
  229. package/templates/.claude/skills/frontend-vue/components/View/Form.vue +89 -0
  230. package/templates/.claude/skills/frontend-vue/composables/indexDBStore.js +140 -0
  231. package/templates/.claude/skills/frontend-vue/composables/masterApi.js +362 -0
  232. package/templates/.claude/skills/frontend-vue/composables/state.js +578 -0
  233. package/templates/.claude/skills/frontend-vue/composables/useRequest.js +221 -0
  234. package/templates/.claude/skills/frontend-vue/composables/useSession.js +179 -0
  235. package/templates/.claude/skills/frontend-vue/composables/useTranslation.js +54 -0
  236. package/templates/.claude/skills/frontend-vue/composables/useWebSocket.js +257 -0
  237. package/templates/.claude/skills/frontend-vue/composables/userObj.js +111 -0
  238. package/templates/.claude/skills/frontend-vue/composables/utils.js +322 -0
  239. package/templates/.claude/skills/frontend-vue/reference/composables-example.vue +320 -0
  240. package/templates/.claude/skills/frontend-vue/reference/form-example.vue +183 -0
  241. package/templates/.claude/skills/frontend-vue/reference/grid-example.vue +147 -0
  242. package/templates/.claude/skills/frontend-vue/reference/masterdata-example/[id].vue +106 -0
  243. package/templates/.claude/skills/frontend-vue/reference/masterdata-example/index.vue +58 -0
  244. package/templates/.claude/skills/frontend-vue/reference/popup-example.vue +159 -0
  245. package/templates/.claude/skills/pdf/LICENSE.txt +30 -0
  246. package/templates/.claude/skills/pdf/SKILL.md +294 -0
  247. package/templates/.claude/skills/pdf/forms.md +205 -0
  248. package/templates/.claude/skills/pdf/reference.md +612 -0
  249. package/templates/.claude/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  250. package/templates/.claude/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  251. package/templates/.claude/skills/pdf/scripts/check_fillable_fields.py +12 -0
  252. package/templates/.claude/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  253. package/templates/.claude/skills/pdf/scripts/create_validation_image.py +41 -0
  254. package/templates/.claude/skills/pdf/scripts/extract_form_field_info.py +152 -0
  255. package/templates/.claude/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  256. package/templates/.claude/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  257. package/templates/.claude/skills/pdf-processing/SKILL.md +107 -0
  258. package/templates/.claude/skills/pdf-processing-pro/FORMS.md +610 -0
  259. package/templates/.claude/skills/pdf-processing-pro/OCR.md +137 -0
  260. package/templates/.claude/skills/pdf-processing-pro/SKILL.md +296 -0
  261. package/templates/.claude/skills/pdf-processing-pro/TABLES.md +626 -0
  262. package/templates/.claude/skills/pdf-processing-pro/scripts/analyze_form.py +307 -0
  263. package/templates/.claude/skills/postgres/SKILL.md +69 -0
  264. package/templates/.claude/skills/postgres/reference/fn_get_examples.sql +208 -0
  265. package/templates/.claude/skills/postgres/reference/fn_rpt_examples.sql +239 -0
  266. package/templates/.claude/skills/postgres/reference/utility_functions.sql +94 -0
  267. package/templates/.claude/skills/pptx/LICENSE.txt +30 -0
  268. package/templates/.claude/skills/pptx/SKILL.md +484 -0
  269. package/templates/.claude/skills/pptx/html2pptx.md +625 -0
  270. package/templates/.claude/skills/pptx/ooxml.md +427 -0
  271. package/templates/.claude/skills/pptx/scripts/html2pptx.js +979 -0
  272. package/templates/.claude/skills/pptx/scripts/inventory.py +1020 -0
  273. package/templates/.claude/skills/pptx/scripts/rearrange.py +231 -0
  274. package/templates/.claude/skills/pptx/scripts/replace.py +385 -0
  275. package/templates/.claude/skills/pptx/scripts/thumbnail.py +450 -0
  276. package/templates/.claude/skills/repo-maintenance/SKILL.md +97 -0
  277. package/templates/.claude/skills/research/EXAMPLES.md +434 -0
  278. package/templates/.claude/skills/research/REFERENCE.md +399 -0
  279. package/templates/.claude/skills/research/SKILL.md +136 -0
  280. package/templates/.claude/skills/root-cause-tracing/SKILL.md +174 -0
  281. package/templates/.claude/skills/root-cause-tracing/find-polluter.sh +63 -0
  282. package/templates/.claude/skills/sharing-skills/SKILL.md +194 -0
  283. package/templates/.claude/skills/sql-optimization-patterns/SKILL.md +493 -0
  284. package/templates/.claude/skills/subagent-driven-development/SKILL.md +189 -0
  285. package/templates/.claude/skills/systematic-debugging/CREATION-LOG.md +119 -0
  286. package/templates/.claude/skills/systematic-debugging/SKILL.md +295 -0
  287. package/templates/.claude/skills/systematic-debugging/test-academic.md +14 -0
  288. package/templates/.claude/skills/systematic-debugging/test-pressure-1.md +58 -0
  289. package/templates/.claude/skills/systematic-debugging/test-pressure-2.md +68 -0
  290. package/templates/.claude/skills/systematic-debugging/test-pressure-3.md +69 -0
  291. package/templates/.claude/skills/test-driven-development/SKILL.md +364 -0
  292. package/templates/.claude/skills/testing-anti-patterns/SKILL.md +302 -0
  293. package/templates/.claude/skills/testing-quality/SKILL.md +97 -0
  294. package/templates/.claude/skills/verification-before-completion/SKILL.md +139 -0
  295. package/templates/.claude/skills/webapp-testing/LICENSE.txt +202 -0
  296. package/templates/.claude/skills/webapp-testing/SKILL.md +96 -0
  297. package/templates/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
  298. package/templates/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
  299. package/templates/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
  300. package/templates/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
  301. package/templates/.claude/ukit/index/build-index.mjs +28 -0
  302. package/templates/.claude/ukit/index/cache-utils.mjs +140 -0
  303. package/templates/.claude/ukit/index/lib/index-core.mjs +2800 -0
  304. package/templates/.claude/ukit/index/query-index.mjs +150 -0
  305. package/templates/.claude/ukit/index/refresh-index.mjs +57 -0
  306. package/templates/.claude/ukit/index/reset-auto-permissions.mjs +76 -0
  307. package/templates/.claude/ukit/index/resolve-context.mjs +279 -0
  308. package/templates/.claude/ukit/index/route-catalog.mjs +258 -0
  309. package/templates/.claude/ukit/index/route-task.mjs +1994 -0
  310. package/templates/.claude/ukit/index/triage.mjs +133 -0
  311. package/templates/.claude/ukit/index/verify-context.mjs +689 -0
  312. package/templates/.claude/ukit/runtime/compact-threshold.mjs +1013 -0
  313. package/templates/.claude/ukit/runtime/output-compression.mjs +1340 -0
  314. package/templates/.claude/ukit/runtime/reinject-context.mjs +874 -0
  315. package/templates/.claude/ukit/runtime/token-utils.mjs +500 -0
  316. package/templates/.codex/README.md +83 -0
  317. package/templates/.codex/settings.json +187 -0
  318. package/templates/.gitignore +75 -0
  319. package/templates/AGENTS.md +116 -0
  320. package/templates/CLAUDE.md +93 -0
  321. package/templates/adapter-presets/antigravity/README.md +22 -0
  322. package/templates/adapter-presets/antigravity/rules.md +49 -0
  323. package/templates/adapter-presets/claude/settings.local.json +42 -0
  324. package/templates/adapter-presets/codex/settings.local.json +6 -0
  325. package/templates/adapter-presets/opencode/opencode.template.json +1 -0
  326. package/templates/docs/BUGFIX.md +20 -0
  327. package/templates/docs/BUG_INDEX.md +12 -0
  328. package/templates/docs/BUG_METRICS.md +7 -0
  329. package/templates/docs/BUG_TEMPLATE.md +13 -0
  330. package/templates/docs/CODE_MAP.md +35 -0
  331. package/templates/docs/INSTALL.md +113 -0
  332. package/templates/docs/MEMORY.md +49 -0
  333. package/templates/docs/PROJECT.md +50 -0
  334. package/templates/docs/UKIT_USAGE_GUIDE.md +147 -0
  335. package/templates/docs/WORKLOG.md +10 -0
  336. package/templates/ukit/README.md +14 -0
  337. package/templates/ukit/storage/cache/compact-history.json +3 -0
  338. package/templates/ukit/storage/cache/compact-pressure.json +1 -0
  339. package/templates/ukit/storage/cache/output-history.json +3 -0
  340. package/templates/ukit/storage/cache/prompt-cache.json +3 -0
  341. package/templates/ukit/storage/config.json +37 -0
  342. package/templates/ukit/storage/memory/projects/.gitkeep +2 -0
  343. package/templates/ukit/storage/memory/sessions/.gitkeep +0 -0
  344. package/templates/ukit/storage/memory/user.json +5 -0
@@ -0,0 +1,109 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ const HOOK_NAMES = ['post-commit', 'post-merge', 'post-checkout'];
5
+ const BEGIN = '# UKit index auto-refresh (begin)';
6
+ const END = '# UKit index auto-refresh (end)';
7
+
8
+ export async function installIndexRefreshHooks({ projectRoot }) {
9
+ const hooksDir = path.join(projectRoot, '.git', 'hooks');
10
+ await ensureHooksDir(hooksDir);
11
+
12
+ let installed = 0;
13
+ let unchanged = 0;
14
+
15
+ for (const hookName of HOOK_NAMES) {
16
+ const hookPath = path.join(hooksDir, hookName);
17
+ const existing = await readTextOrEmpty(hookPath);
18
+ const base = existing || '#!/bin/sh\n';
19
+
20
+ if (hasManagedBlock(base)) {
21
+ unchanged += 1;
22
+ continue;
23
+ }
24
+
25
+ const next = `${base.trimEnd()}\n\n${buildManagedBlock()}\n`;
26
+ await fs.writeFile(hookPath, next, { mode: 0o755 });
27
+ await fs.chmod(hookPath, 0o755);
28
+ installed += 1;
29
+ }
30
+
31
+ return {
32
+ hookNames: HOOK_NAMES,
33
+ installed,
34
+ unchanged,
35
+ };
36
+ }
37
+
38
+ export async function removeIndexRefreshHooks({ projectRoot }) {
39
+ const hooksDir = path.join(projectRoot, '.git', 'hooks');
40
+ await ensureHooksDir(hooksDir);
41
+
42
+ let removed = 0;
43
+ let unchanged = 0;
44
+
45
+ for (const hookName of HOOK_NAMES) {
46
+ const hookPath = path.join(hooksDir, hookName);
47
+ const existing = await readTextOrEmpty(hookPath);
48
+ if (!existing || !hasManagedBlock(existing)) {
49
+ unchanged += 1;
50
+ continue;
51
+ }
52
+
53
+ const next = removeManagedBlock(existing);
54
+ const cleaned = next.trim().length === 0 ? '#!/bin/sh\n' : `${next.trimEnd()}\n`;
55
+ await fs.writeFile(hookPath, cleaned, { mode: 0o755 });
56
+ await fs.chmod(hookPath, 0o755);
57
+ removed += 1;
58
+ }
59
+
60
+ return {
61
+ hookNames: HOOK_NAMES,
62
+ removed,
63
+ unchanged,
64
+ };
65
+ }
66
+
67
+ function buildManagedBlock() {
68
+ return [
69
+ BEGIN,
70
+ 'ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || exit 0',
71
+ 'SCRIPT="$ROOT/.claude/ukit/index/refresh-index.mjs"',
72
+ '[ -f "$SCRIPT" ] || exit 0',
73
+ 'node "$SCRIPT" >/dev/null 2>&1 || true',
74
+ END,
75
+ ].join('\n');
76
+ }
77
+
78
+ function hasManagedBlock(content) {
79
+ return content.includes(BEGIN) && content.includes(END);
80
+ }
81
+
82
+ function removeManagedBlock(content) {
83
+ const pattern = new RegExp(`${escapeRegExp(BEGIN)}[\\s\\S]*?${escapeRegExp(END)}\\n?`, 'g');
84
+ return content.replace(pattern, '').replace(/\n{3,}/g, '\n\n');
85
+ }
86
+
87
+ function escapeRegExp(input) {
88
+ return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
89
+ }
90
+
91
+ async function ensureHooksDir(hooksDir) {
92
+ try {
93
+ const stat = await fs.stat(hooksDir);
94
+ if (!stat.isDirectory()) {
95
+ throw new Error();
96
+ }
97
+ } catch {
98
+ throw new Error('No .git/hooks directory found. Run this inside a git project.');
99
+ }
100
+ }
101
+
102
+ async function readTextOrEmpty(filePath) {
103
+ try {
104
+ return await fs.readFile(filePath, 'utf8');
105
+ } catch {
106
+ return '';
107
+ }
108
+ }
109
+
@@ -0,0 +1,377 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ import { normalizeRelative } from './paths.js';
5
+
6
+ const RESOLUTION_SUFFIXES = [
7
+ '',
8
+ '.js',
9
+ '.ts',
10
+ '.jsx',
11
+ '.tsx',
12
+ '.mjs',
13
+ '.cjs',
14
+ '.vue',
15
+ '/index.js',
16
+ '/index.ts',
17
+ '/index.jsx',
18
+ '/index.tsx',
19
+ '/index.mjs',
20
+ '/index.cjs',
21
+ '/index.vue',
22
+ ];
23
+
24
+ const DEFAULT_ALIAS_RULES = [
25
+ { pattern: '@/*', targets: ['src/*', '*'] },
26
+ { pattern: '~/*', targets: ['*', 'src/*'] },
27
+ ];
28
+ const ALIAS_CONTEXT_CACHE = new Map();
29
+ const ROOT_ALIAS_CONFIG_FILES = ['tsconfig.json', 'jsconfig.json'];
30
+
31
+ export async function loadImportAliasContext({ rootDir }) {
32
+ const loaded = await loadImportAliasContextState({ rootDir });
33
+ return loaded.context;
34
+ }
35
+
36
+ export async function loadImportAliasContextState({ rootDir }) {
37
+ const absoluteRoot = path.resolve(rootDir);
38
+ const cached = ALIAS_CONTEXT_CACHE.get(absoluteRoot);
39
+ if (cached) {
40
+ const cachedEntry = await cached;
41
+ if (await isAliasSnapshotValid(cachedEntry.snapshot)) {
42
+ return cachedEntry;
43
+ }
44
+ ALIAS_CONTEXT_CACHE.delete(absoluteRoot);
45
+ }
46
+
47
+ const contextPromise = loadFreshImportAliasContext(absoluteRoot)
48
+ .catch((error) => {
49
+ ALIAS_CONTEXT_CACHE.delete(absoluteRoot);
50
+ throw error;
51
+ });
52
+ ALIAS_CONTEXT_CACHE.set(absoluteRoot, contextPromise);
53
+
54
+ return contextPromise;
55
+ }
56
+
57
+ export function importsNeedAliasContext(imports = []) {
58
+ return imports.some((entry) => specifierNeedsAliasContext(entry?.to));
59
+ }
60
+
61
+ async function loadFreshImportAliasContext(rootDir) {
62
+ const tracker = new Map();
63
+ const tsconfigPath = path.join(rootDir, 'tsconfig.json');
64
+ const jsconfigPath = path.join(rootDir, 'jsconfig.json');
65
+ const config = await loadAliasConfig(tsconfigPath, new Set(), tracker)
66
+ ?? await loadAliasConfig(jsconfigPath, new Set(), tracker);
67
+
68
+ for (const configName of ROOT_ALIAS_CONFIG_FILES) {
69
+ const configPath = path.resolve(rootDir, configName);
70
+ if (!tracker.has(configPath)) {
71
+ tracker.set(configPath, await readPathSnapshot(configPath));
72
+ }
73
+ }
74
+
75
+ const configuredRules = config?.pathRules ?? [];
76
+ const configuredBaseUrls = config?.baseUrlDirs ?? [];
77
+
78
+ return {
79
+ context: {
80
+ rootDir,
81
+ pathRules: [
82
+ ...configuredRules,
83
+ ...DEFAULT_ALIAS_RULES.map((rule) => buildAliasRule({
84
+ pattern: rule.pattern,
85
+ targets: rule.targets,
86
+ rootDir,
87
+ baseDir: rootDir,
88
+ })),
89
+ ],
90
+ baseUrlDirs: dedupe(configuredBaseUrls),
91
+ },
92
+ snapshot: [...tracker.values()].sort((a, b) => a.filePath.localeCompare(b.filePath)),
93
+ };
94
+ }
95
+
96
+ export function resolveImportSpecifier({
97
+ rootDir,
98
+ fromFilePath,
99
+ specifier,
100
+ indexedFileSet,
101
+ aliasContext,
102
+ }) {
103
+ if (!specifier?.trim()) {
104
+ return null;
105
+ }
106
+
107
+ if (specifier.startsWith('.')) {
108
+ const fromDir = path.posix.dirname(fromFilePath);
109
+ const base = path.posix.normalize(path.posix.join(fromDir, specifier));
110
+ return resolveCandidateBase(base, indexedFileSet);
111
+ }
112
+
113
+ if (specifier.startsWith('/')) {
114
+ return resolveCandidateBase(specifier.slice(1), indexedFileSet);
115
+ }
116
+
117
+ for (const rule of aliasContext?.pathRules ?? []) {
118
+ const wildcardValue = matchAliasPattern(specifier, rule.pattern);
119
+ if (wildcardValue === null) {
120
+ continue;
121
+ }
122
+
123
+ for (const targetPattern of rule.targets) {
124
+ const replacedTarget = wildcardValue === null
125
+ ? targetPattern
126
+ : targetPattern.replaceAll('*', wildcardValue);
127
+ const absoluteBase = path.resolve(rule.baseDir, replacedTarget);
128
+ const relativeBase = normalizeRelative(rootDir, absoluteBase);
129
+ const resolved = resolveCandidateBase(relativeBase, indexedFileSet);
130
+ if (resolved) {
131
+ return resolved;
132
+ }
133
+ }
134
+ }
135
+
136
+ for (const baseUrlDir of aliasContext?.baseUrlDirs ?? []) {
137
+ const absoluteBase = path.resolve(baseUrlDir, specifier);
138
+ const relativeBase = normalizeRelative(rootDir, absoluteBase);
139
+ const resolved = resolveCandidateBase(relativeBase, indexedFileSet);
140
+ if (resolved) {
141
+ return resolved;
142
+ }
143
+ }
144
+
145
+ return null;
146
+ }
147
+
148
+ function resolveCandidateBase(relativeBase, indexedFileSet) {
149
+ const normalizedBase = relativeBase.replace(/\\/g, '/');
150
+
151
+ for (const suffix of RESOLUTION_SUFFIXES) {
152
+ const candidate = path.posix.normalize(`${normalizedBase}${suffix}`);
153
+ if (indexedFileSet.has(candidate)) {
154
+ return candidate;
155
+ }
156
+ }
157
+
158
+ return null;
159
+ }
160
+
161
+ function specifierNeedsAliasContext(specifier) {
162
+ const normalized = String(specifier ?? '').trim();
163
+ if (!normalized) {
164
+ return false;
165
+ }
166
+
167
+ return !normalized.startsWith('.') && !normalized.startsWith('/');
168
+ }
169
+
170
+ function matchAliasPattern(specifier, pattern) {
171
+ if (!pattern.includes('*')) {
172
+ return specifier === pattern ? '' : null;
173
+ }
174
+
175
+ const [prefix, suffix] = pattern.split('*');
176
+ if (!specifier.startsWith(prefix)) {
177
+ return null;
178
+ }
179
+ if (suffix && !specifier.endsWith(suffix)) {
180
+ return null;
181
+ }
182
+
183
+ return specifier.slice(prefix.length, specifier.length - suffix.length);
184
+ }
185
+
186
+ function buildAliasRule({ pattern, targets, rootDir, baseDir }) {
187
+ return {
188
+ pattern,
189
+ targets: targets.map((target) => target.replace(/\\/g, '/')),
190
+ rootDir,
191
+ baseDir,
192
+ };
193
+ }
194
+
195
+ async function loadAliasConfig(configPath, visited = new Set(), tracker = null) {
196
+ const resolvedPath = path.resolve(configPath);
197
+ if (visited.has(resolvedPath)) {
198
+ return null;
199
+ }
200
+ visited.add(resolvedPath);
201
+
202
+ const snapshot = await readPathSnapshot(resolvedPath);
203
+ if (tracker) {
204
+ tracker.set(resolvedPath, snapshot);
205
+ }
206
+ if (!snapshot.exists) {
207
+ return null;
208
+ }
209
+
210
+ let raw;
211
+ try {
212
+ raw = await fs.readFile(resolvedPath, 'utf8');
213
+ } catch {
214
+ return null;
215
+ }
216
+
217
+ let parsed;
218
+ try {
219
+ parsed = parseJsonc(raw);
220
+ } catch {
221
+ return null;
222
+ }
223
+ const configDir = path.dirname(resolvedPath);
224
+ const compilerOptions = parsed?.compilerOptions ?? {};
225
+
226
+ let inherited = null;
227
+ const extendsValue = typeof parsed?.extends === 'string' ? parsed.extends.trim() : '';
228
+ if (extendsValue && (extendsValue.startsWith('.') || extendsValue.startsWith('/'))) {
229
+ const inheritedPath = resolveExtendedConfigPath(configDir, extendsValue);
230
+ inherited = await loadAliasConfig(inheritedPath, visited, tracker);
231
+ }
232
+
233
+ const inheritedRules = inherited?.pathRules ?? [];
234
+ const inheritedBaseUrls = inherited?.baseUrlDirs ?? [];
235
+ const currentRules = buildPathRules({
236
+ rootDir: configDir,
237
+ compilerOptions,
238
+ });
239
+ const currentBaseUrls = buildBaseUrlDirs({
240
+ rootDir: configDir,
241
+ compilerOptions,
242
+ });
243
+
244
+ const pathRuleMap = new Map(inheritedRules.map((rule) => [rule.pattern, rule]));
245
+ for (const rule of currentRules) {
246
+ pathRuleMap.set(rule.pattern, rule);
247
+ }
248
+
249
+ return {
250
+ pathRules: [...pathRuleMap.values()],
251
+ baseUrlDirs: dedupe([...currentBaseUrls, ...inheritedBaseUrls]),
252
+ };
253
+ }
254
+
255
+ function buildPathRules({ rootDir, compilerOptions }) {
256
+ const paths = compilerOptions?.paths;
257
+ if (!paths || typeof paths !== 'object') {
258
+ return [];
259
+ }
260
+
261
+ const baseDir = path.resolve(rootDir, String(compilerOptions?.baseUrl ?? '.'));
262
+
263
+ return Object.entries(paths)
264
+ .filter(([pattern, targets]) => typeof pattern === 'string' && Array.isArray(targets) && targets.length > 0)
265
+ .map(([pattern, targets]) => buildAliasRule({
266
+ pattern,
267
+ targets: targets.filter((target) => typeof target === 'string'),
268
+ rootDir,
269
+ baseDir,
270
+ }));
271
+ }
272
+
273
+ function buildBaseUrlDirs({ rootDir, compilerOptions }) {
274
+ const baseUrl = String(compilerOptions?.baseUrl ?? '').trim();
275
+ if (!baseUrl) {
276
+ return [];
277
+ }
278
+
279
+ return [path.resolve(rootDir, baseUrl)];
280
+ }
281
+
282
+ function resolveExtendedConfigPath(configDir, extendsValue) {
283
+ const withExtension = extendsValue.endsWith('.json')
284
+ ? extendsValue
285
+ : `${extendsValue}.json`;
286
+ return path.resolve(configDir, withExtension);
287
+ }
288
+
289
+ async function isAliasSnapshotValid(snapshot = []) {
290
+ const current = await Promise.all(snapshot.map((entry) => readPathSnapshot(entry.filePath)));
291
+ return current.every((entry, index) => isSameSnapshotEntry(entry, snapshot[index]));
292
+ }
293
+
294
+ async function readPathSnapshot(filePath) {
295
+ try {
296
+ const stat = await fs.stat(filePath);
297
+ return {
298
+ filePath,
299
+ exists: true,
300
+ size: stat.size,
301
+ mtimeMs: stat.mtimeMs,
302
+ };
303
+ } catch {
304
+ return {
305
+ filePath,
306
+ exists: false,
307
+ size: null,
308
+ mtimeMs: null,
309
+ };
310
+ }
311
+ }
312
+
313
+ function isSameSnapshotEntry(current, previous) {
314
+ return current.filePath === previous.filePath
315
+ && current.exists === previous.exists
316
+ && current.size === previous.size
317
+ && current.mtimeMs === previous.mtimeMs;
318
+ }
319
+
320
+ function parseJsonc(raw) {
321
+ const withoutBom = raw.replace(/^\uFEFF/, '');
322
+ const withoutBlockComments = withoutBom.replace(/\/\*[\s\S]*?\*\//g, '');
323
+ const withoutLineComments = stripLineComments(withoutBlockComments);
324
+ const withoutTrailingCommas = withoutLineComments.replace(/,\s*([}\]])/g, '$1');
325
+
326
+ return JSON.parse(withoutTrailingCommas);
327
+ }
328
+
329
+ function stripLineComments(raw) {
330
+ let result = '';
331
+ let inString = false;
332
+ let stringQuote = '';
333
+ let isEscaped = false;
334
+
335
+ for (let index = 0; index < raw.length; index += 1) {
336
+ const char = raw[index];
337
+ const nextChar = raw[index + 1];
338
+
339
+ if (inString) {
340
+ result += char;
341
+ if (isEscaped) {
342
+ isEscaped = false;
343
+ } else if (char === '\\') {
344
+ isEscaped = true;
345
+ } else if (char === stringQuote) {
346
+ inString = false;
347
+ stringQuote = '';
348
+ }
349
+ continue;
350
+ }
351
+
352
+ if (char === '"' || char === '\'') {
353
+ inString = true;
354
+ stringQuote = char;
355
+ result += char;
356
+ continue;
357
+ }
358
+
359
+ if (char === '/' && nextChar === '/') {
360
+ while (index < raw.length && raw[index] !== '\n') {
361
+ index += 1;
362
+ }
363
+ if (index < raw.length) {
364
+ result += '\n';
365
+ }
366
+ continue;
367
+ }
368
+
369
+ result += char;
370
+ }
371
+
372
+ return result;
373
+ }
374
+
375
+ function dedupe(values) {
376
+ return [...new Set(values)];
377
+ }
@@ -0,0 +1,127 @@
1
+ const GENERIC_STOPWORDS = new Set([
2
+ 'a', 'an', 'and', 'as', 'at', 'be', 'by', 'do', 'for', 'from', 'help', 'i', 'in', 'into',
3
+ 'is', 'it', 'me', 'my', 'of', 'on', 'or', 'please', 'the', 'this', 'that', 'to', 'with',
4
+ 'ban', 'cho', 'cua', 'di', 'dung', 'giup', 'hay', 'khong', 'la', 'lam', 'luon', 'mot', 'nay',
5
+ 'neu', 'nhung', 'nua', 'roi', 'toi', 'tren', 'truoc', 'va', 'voi',
6
+ ]);
7
+
8
+ const VIETNAMESE_PHRASE_ALIASES = [
9
+ { regex: /\bbo nho dem\b/gu, expansions: ['cache'] },
10
+ { regex: /\bduong dan\b/gu, expansions: ['route', 'path'] },
11
+ { regex: /\bxac thuc\b/gu, expansions: ['auth', 'authentication'] },
12
+ { regex: /\bdang nhap\b/gu, expansions: ['login', 'signin', 'auth'] },
13
+ { regex: /\bquyen truy cap\b/gu, expansions: ['permission', 'access'] },
14
+ { regex: /\bkiem tra\b/gu, expansions: ['review', 'check', 'verify'] },
15
+ { regex: /\bbao mat\b/gu, expansions: ['security'] },
16
+ { regex: /\bco so du lieu\b/gu, expansions: ['database'] },
17
+ { regex: /\btai lieu\b/gu, expansions: ['docs', 'documentation'] },
18
+ { regex: /\bgiao dien\b/gu, expansions: ['ui', 'interface', 'frontend'] },
19
+ { regex: /\bthanh phan\b/gu, expansions: ['component'] },
20
+ { regex: /\bkiem thu\b/gu, expansions: ['test', 'testing'] },
21
+ { regex: /\bbo cuc\b/gu, expansions: ['layout'] },
22
+ ];
23
+
24
+ const VIETNAMESE_TOKEN_ALIASES = new Map([
25
+ ['sua', ['fix']],
26
+ ['loi', ['bug', 'error']],
27
+ ['them', ['add']],
28
+ ['xoa', ['delete', 'remove']],
29
+ ['quyen', ['permission', 'access']],
30
+ ['token', ['token']],
31
+ ['cache', ['cache']],
32
+ ['route', ['route', 'path']],
33
+ ['path', ['path', 'route']],
34
+ ['helper', ['helper']],
35
+ ['docker', ['docker']],
36
+ ['compose', ['compose']],
37
+ ['page', ['page']],
38
+ ['component', ['component']],
39
+ ['test', ['test', 'testing']],
40
+ ['soat', ['review', 'audit']],
41
+ ['trien', ['implement', 'build', 'ship']],
42
+ ['khai', ['implement', 'build', 'ship']],
43
+ ]);
44
+
45
+ export function buildRouteSignalText(...values) {
46
+ const baseText = values
47
+ .map((value) => String(value || '').trim())
48
+ .filter(Boolean)
49
+ .join('\n');
50
+
51
+ if (!baseText) {
52
+ return '';
53
+ }
54
+
55
+ const withCamelBoundaries = addCamelBoundaries(baseText);
56
+ const foldedLower = foldTextForSearch(withCamelBoundaries);
57
+ const baseTokens = tokenizeFoldedText(foldedLower);
58
+ const aliasTokens = collectVietnameseAliasTokens(foldedLower, baseTokens);
59
+
60
+ return [
61
+ String(baseText).toLowerCase(),
62
+ foldedLower,
63
+ [...new Set([...baseTokens, ...aliasTokens])].join(' '),
64
+ ].filter(Boolean).join('\n');
65
+ }
66
+
67
+ export function buildSearchDescriptor(value, { expandVietnameseAliases = false } = {}) {
68
+ const withCamelBoundaries = addCamelBoundaries(value);
69
+ const foldedLower = foldTextForSearch(withCamelBoundaries);
70
+ const tokens = new Set(tokenizeFoldedText(foldedLower));
71
+
72
+ if (expandVietnameseAliases) {
73
+ for (const token of collectVietnameseAliasTokens(foldedLower, tokens)) {
74
+ tokens.add(token);
75
+ }
76
+ }
77
+
78
+ return {
79
+ rawLower: foldedLower,
80
+ tokens,
81
+ compact: [...tokens].join(''),
82
+ };
83
+ }
84
+
85
+ function addCamelBoundaries(value) {
86
+ return String(value || '')
87
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
88
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
89
+ }
90
+
91
+ function tokenizeFoldedText(value) {
92
+ return String(value || '')
93
+ .split(/[^\p{L}\p{N}]+/u)
94
+ .map((token) => token.trim())
95
+ .filter((token) => token.length >= 2 && !GENERIC_STOPWORDS.has(token));
96
+ }
97
+
98
+ function collectVietnameseAliasTokens(foldedLower, baseTokens) {
99
+ const aliases = [];
100
+
101
+ for (const entry of VIETNAMESE_PHRASE_ALIASES) {
102
+ entry.regex.lastIndex = 0;
103
+ if (!entry.regex.test(foldedLower)) {
104
+ continue;
105
+ }
106
+ aliases.push(...entry.expansions);
107
+ }
108
+
109
+ for (const token of baseTokens) {
110
+ aliases.push(...(VIETNAMESE_TOKEN_ALIASES.get(token) ?? []));
111
+ }
112
+
113
+ return [...new Set(
114
+ aliases
115
+ .map((token) => foldTextForSearch(token))
116
+ .filter((token) => token.length >= 2 && !GENERIC_STOPWORDS.has(token)),
117
+ )];
118
+ }
119
+
120
+ function foldTextForSearch(value) {
121
+ return String(value || '')
122
+ .replaceAll('đ', 'd')
123
+ .replaceAll('Đ', 'D')
124
+ .normalize('NFD')
125
+ .replace(/\p{M}+/gu, '')
126
+ .toLowerCase();
127
+ }
@@ -0,0 +1,27 @@
1
+ import path from 'node:path';
2
+
3
+ export const INDEX_ARTIFACTS = {
4
+ meta: 'meta.json',
5
+ files: 'files.json',
6
+ symbols: 'symbols.json',
7
+ imports: 'imports.json',
8
+ testsMap: 'tests-map.json',
9
+ hotspots: 'hotspots.json',
10
+ archetypes: 'archetypes.json',
11
+ relations: 'relations.json',
12
+ analogs: 'analogs.json',
13
+ };
14
+
15
+ export const INDEX_SCHEMA_VERSION = 6;
16
+
17
+ export function getIndexDir(rootDir) {
18
+ return path.join(rootDir, '.cache', 'index');
19
+ }
20
+
21
+ export function getArtifactPath(rootDir, artifactName) {
22
+ return path.join(getIndexDir(rootDir), artifactName);
23
+ }
24
+
25
+ export function normalizeRelative(rootDir, absolutePath) {
26
+ return path.relative(rootDir, absolutePath).replace(/\\/g, '/');
27
+ }