@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,73 @@
1
+ import fs from 'node:fs/promises';
2
+ import { isSymlinkTo } from './fileOps.js';
3
+
4
+ async function readFileOrNull(filePath, encoding = 'utf8') {
5
+ try {
6
+ if (encoding === null) {
7
+ return await fs.readFile(filePath);
8
+ }
9
+ return await fs.readFile(filePath, encoding);
10
+ } catch {
11
+ return null;
12
+ }
13
+ }
14
+
15
+ async function checkLinkStatus(targetPath, linkTarget) {
16
+ try {
17
+ const stat = await fs.lstat(targetPath);
18
+ if (!stat.isSymbolicLink()) {
19
+ return 'update'; // exists but is not a symlink — needs replacing
20
+ }
21
+ return (await isSymlinkTo(targetPath, linkTarget)) ? 'unchanged' : 'update';
22
+ } catch {
23
+ return 'create'; // does not exist
24
+ }
25
+ }
26
+
27
+ function resolveFileAction(entry, existingContent) {
28
+ const exists = existingContent !== null;
29
+ const binaryEntry = Buffer.isBuffer(entry.renderedContent);
30
+
31
+ let action;
32
+ if (!exists) {
33
+ action = 'create';
34
+ } else if (entry.mergeStrategy === 'append' && !binaryEntry) {
35
+ action = existingContent.endsWith(entry.renderedContent) ? 'unchanged' : 'update';
36
+ } else if (entry.mergeStrategy === 'prepend' && !binaryEntry) {
37
+ action = existingContent.startsWith(entry.renderedContent) ? 'unchanged' : 'update';
38
+ } else if (binaryEntry) {
39
+ action = Buffer.isBuffer(existingContent) && existingContent.equals(entry.renderedContent)
40
+ ? 'unchanged'
41
+ : entry.mergeStrategy === 'skip'
42
+ ? 'skip'
43
+ : 'update';
44
+ } else if (existingContent === entry.renderedContent) {
45
+ action = 'unchanged';
46
+ } else if (entry.mergeStrategy === 'skip') {
47
+ action = 'skip';
48
+ } else {
49
+ action = 'update';
50
+ }
51
+
52
+ return { ...entry, exists, action, existingContent };
53
+ }
54
+
55
+ export async function diffInstallPlan(plan) {
56
+ // Check all entries in parallel
57
+ const results = await Promise.all(
58
+ plan.entries.map(async (entry) => {
59
+ if (entry.type === 'link') {
60
+ const action = await checkLinkStatus(entry.targetPath, entry.linkTarget);
61
+ return { ...entry, exists: action !== 'create', action, existingContent: null };
62
+ }
63
+
64
+ const existingContent = await readFileOrNull(
65
+ entry.targetPath,
66
+ Buffer.isBuffer(entry.renderedContent) ? null : 'utf8',
67
+ );
68
+ return resolveFileAction(entry, existingContent);
69
+ }),
70
+ );
71
+
72
+ return results;
73
+ }
@@ -0,0 +1,117 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { escapeRegExp, writeFileAtomic } from './fileOps.js';
4
+
5
+ const UKIT_ENTRIES = [
6
+ '.cache/',
7
+ '.antigravity/',
8
+ '.claude/',
9
+ '.codex/',
10
+ '.ukit/',
11
+ 'opencode.json',
12
+ 'AGENTS.md',
13
+ 'CLAUDE.md',
14
+ '.claude/ukit/.ukit/',
15
+ '.claude/ukit/permission-usage.json',
16
+ '.claude/ukit/permission-audit.log',
17
+ '.codex/settings.local.json',
18
+ ];
19
+
20
+ const MARKER_START = '# UKit generated (do not edit)';
21
+ const MARKER_END = '# /UKit';
22
+
23
+ export async function ensureGitignore(projectRoot) {
24
+ const gitignorePath = path.join(projectRoot, '.gitignore');
25
+
26
+ let content = '';
27
+ try {
28
+ content = await fs.readFile(gitignorePath, 'utf8');
29
+ } catch {
30
+ // no .gitignore yet
31
+ }
32
+
33
+ const newBlock = [
34
+ MARKER_START,
35
+ ...UKIT_ENTRIES,
36
+ MARKER_END,
37
+ ].join('\n');
38
+
39
+ if (content.includes(MARKER_START)) {
40
+ // Replace existing UKit block with current entries
41
+ const blockPattern = new RegExp(
42
+ `${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}`,
43
+ );
44
+ const existingBlock = content.match(blockPattern)?.[0];
45
+ if (existingBlock === newBlock) {
46
+ return false; // already up to date
47
+ }
48
+ const updated = content.replace(blockPattern, newBlock);
49
+ await writeFileAtomic(gitignorePath, updated);
50
+ return true;
51
+ }
52
+
53
+ // No marker block — check if entries are already present as active (non-comment) lines.
54
+ // Must filter out comment lines to avoid false-negatives like "# placeholder .claude/ukit/.ukit/"
55
+ // matching the entry check and incorrectly skipping the block insertion.
56
+ const activeLines = content
57
+ .split('\n')
58
+ .map((l) => l.trim())
59
+ .filter((trimmed) => trimmed && !trimmed.startsWith('#') && !trimmed.startsWith('!'));
60
+ const missing = UKIT_ENTRIES.filter((e) => !activeLines.some((l) => l.includes(e)));
61
+ if (missing.length === 0) {
62
+ return false;
63
+ }
64
+
65
+ // Append marker block with missing entries
66
+ const block = ['', newBlock, ''].join('\n');
67
+ await writeFileAtomic(gitignorePath, content.trimEnd() + '\n' + block);
68
+ return true;
69
+ }
70
+
71
+ /**
72
+ * Remove the UKit-managed block from .gitignore.
73
+ * Called by uninstall to leave the project in a clean state.
74
+ * @returns {boolean} true if the block was found and removed
75
+ */
76
+ export async function removeGitignoreBlock(projectRoot) {
77
+ const gitignorePath = path.join(projectRoot, '.gitignore');
78
+
79
+ let content = '';
80
+ try {
81
+ content = await fs.readFile(gitignorePath, 'utf8');
82
+ } catch {
83
+ return false; // no .gitignore — nothing to remove
84
+ }
85
+
86
+ if (!content.includes(MARKER_START)) {
87
+ return false; // no UKit block present
88
+ }
89
+
90
+ // Walk lines and excise the block plus any leading blank line that
91
+ // ensureGitignore appended before the marker.
92
+ const lines = content.split('\n');
93
+ const result = [];
94
+ let inBlock = false;
95
+
96
+ for (const line of lines) {
97
+ if (line === MARKER_START) {
98
+ inBlock = true;
99
+ // Remove the blank separator line that ensureGitignore prepended.
100
+ if (result.length > 0 && result[result.length - 1] === '') {
101
+ result.pop();
102
+ }
103
+ continue;
104
+ }
105
+ if (inBlock) {
106
+ if (line === MARKER_END) {
107
+ inBlock = false;
108
+ }
109
+ continue;
110
+ }
111
+ result.push(line);
112
+ }
113
+
114
+ const joined = result.join('\n').trimEnd();
115
+ await writeFileAtomic(gitignorePath, joined ? joined + '\n' : '');
116
+ return true;
117
+ }
@@ -0,0 +1,188 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ export async function pathExists(targetPath) {
5
+ try {
6
+ await fs.access(targetPath);
7
+ return true;
8
+ } catch {
9
+ return false;
10
+ }
11
+ }
12
+
13
+ export async function readJsonIfExists(filePath) {
14
+ try {
15
+ const raw = await fs.readFile(filePath, 'utf8');
16
+ return JSON.parse(raw);
17
+ } catch {
18
+ return null;
19
+ }
20
+ }
21
+
22
+ export function escapeRegExp(str) {
23
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
24
+ }
25
+
26
+ export function resolveProjectRelativePath(projectRoot, relPath) {
27
+ if (typeof relPath !== 'string') {
28
+ return null;
29
+ }
30
+
31
+ const trimmed = relPath.trim();
32
+ if (!trimmed || trimmed === '.' || trimmed === '..') {
33
+ return null;
34
+ }
35
+
36
+ if (path.isAbsolute(trimmed)) {
37
+ return null;
38
+ }
39
+
40
+ const absolute = path.resolve(projectRoot, trimmed);
41
+ const root = path.resolve(projectRoot);
42
+ const relative = path.relative(root, absolute);
43
+
44
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
45
+ return null;
46
+ }
47
+
48
+ return absolute;
49
+ }
50
+
51
+ export async function ensureDir(dirPath) {
52
+ await fs.mkdir(dirPath, { recursive: true });
53
+ }
54
+
55
+ export async function writeFileAtomic(filePath, content) {
56
+ const dir = path.dirname(filePath);
57
+ await ensureDir(dir);
58
+
59
+ const tempPath = `${filePath}.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
60
+
61
+ try {
62
+ if (Buffer.isBuffer(content)) {
63
+ await fs.writeFile(tempPath, content);
64
+ } else {
65
+ await fs.writeFile(tempPath, content, 'utf8');
66
+ }
67
+ await fs.rename(tempPath, filePath);
68
+ } catch (error) {
69
+ try {
70
+ await fs.rm(tempPath, { force: true });
71
+ } catch {
72
+ // ignore cleanup errors
73
+ }
74
+
75
+ if (error?.code === 'EISDIR') {
76
+ throw new Error(
77
+ `Cannot write file ${filePath} because a directory already exists there. Remove or rename the directory and try again.`,
78
+ { cause: error },
79
+ );
80
+ }
81
+
82
+ throw error;
83
+ }
84
+ }
85
+
86
+ export async function copyFileSafe(fromPath, toPath) {
87
+ await ensureDir(path.dirname(toPath));
88
+ await fs.copyFile(fromPath, toPath);
89
+ }
90
+
91
+ export async function writeJson(filePath, data) {
92
+ await writeFileAtomic(filePath, `${JSON.stringify(data, null, 2)}\n`);
93
+ }
94
+
95
+ /**
96
+ * Create a directory symlink (macOS/Linux) or junction (Windows).
97
+ * Junctions on Windows don't require elevated privileges.
98
+ * @param {string} target - Absolute path to the link target directory
99
+ * @param {string} linkPath - Absolute path where the link will be created
100
+ */
101
+ export async function createDirectoryLink(target, linkPath) {
102
+ await ensureDir(path.dirname(linkPath));
103
+
104
+ if (process.platform === 'win32') {
105
+ // Junctions require absolute paths on Windows
106
+ await fs.symlink(path.resolve(target), linkPath, 'junction');
107
+ } else {
108
+ // Relative symlink for portability on macOS/Linux
109
+ const relTarget = path.relative(path.dirname(linkPath), target);
110
+ await fs.symlink(relTarget, linkPath);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Check if linkPath is a symlink/junction pointing to the expected target.
116
+ * @param {string} linkPath - Path to check
117
+ * @param {string} expectedTarget - Absolute path the link should resolve to
118
+ * @returns {boolean}
119
+ */
120
+ export async function isSymlinkTo(linkPath, expectedTarget) {
121
+ try {
122
+ const stat = await fs.lstat(linkPath);
123
+ if (!stat.isSymbolicLink()) return false;
124
+
125
+ const actual = await fs.readlink(linkPath);
126
+ const resolved = path.resolve(path.dirname(linkPath), actual);
127
+ return resolved === path.resolve(expectedTarget);
128
+ } catch {
129
+ return false;
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Remove a symlink or junction only — does NOT remove real directories.
135
+ * Safe to call on adapter link paths where a real directory means user content.
136
+ * @param {string} linkPath - Path to remove
137
+ * @returns {boolean} true if a symlink/junction was removed
138
+ */
139
+ export async function removeLinkOnly(linkPath) {
140
+ try {
141
+ const stat = await fs.lstat(linkPath);
142
+ if (!stat.isSymbolicLink()) return false;
143
+ await fs.unlink(linkPath);
144
+ return true;
145
+ } catch {
146
+ return false;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Remove a managed file or symlink only — does NOT remove real directories.
152
+ * Safe for adapter-managed config/readme files where a directory would imply user content.
153
+ * @param {string} targetPath - Path to remove
154
+ * @returns {boolean} true if a file/symlink was removed
155
+ */
156
+ export async function removeFileOrLinkOnly(targetPath) {
157
+ try {
158
+ const stat = await fs.lstat(targetPath);
159
+ if (stat.isDirectory() && !stat.isSymbolicLink()) {
160
+ return false;
161
+ }
162
+ await fs.unlink(targetPath);
163
+ return true;
164
+ } catch {
165
+ return false;
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Remove a symlink, junction, or directory at the given path.
171
+ * @param {string} linkPath - Path to remove
172
+ * @returns {boolean} true if something was removed
173
+ */
174
+ export async function removeLinkOrDir(linkPath) {
175
+ try {
176
+ const stat = await fs.lstat(linkPath);
177
+ if (stat.isSymbolicLink()) {
178
+ await fs.unlink(linkPath);
179
+ } else if (stat.isDirectory()) {
180
+ await fs.rm(linkPath, { recursive: true, force: true });
181
+ } else {
182
+ await fs.unlink(linkPath);
183
+ }
184
+ return true;
185
+ } catch {
186
+ return false;
187
+ }
188
+ }
@@ -0,0 +1,160 @@
1
+ const DEFAULT_CONFIG = {
2
+ archiveAfterDays: 30,
3
+ maxSessionsKept: 20,
4
+ conflictResolution: 'latest_wins',
5
+ redactPatterns: [
6
+ /sk-[a-z0-9_-]+/gi,
7
+ /api[_-]?key\s*[:=]\s*[^\s,;]+/gi,
8
+ /password\s*[:=]\s*[^\s,;]+/gi,
9
+ ],
10
+ };
11
+
12
+ const CATEGORY_KEYWORDS = {
13
+ database: ['postgresql', 'mysql', 'sqlite', 'mariadb', 'mongodb', 'redis'],
14
+ api_style: ['rest', 'graphql', 'grpc'],
15
+ auth: ['jwt', 'session', 'oauth', 'saml', 'apikey', 'api key'],
16
+ backend_framework: ['express', 'fastify', 'nestjs', 'koa', 'hono'],
17
+ frontend_framework: ['react', 'vue', 'svelte', 'angular'],
18
+ };
19
+
20
+ function clone(value) {
21
+ if (value === undefined || value === null) {
22
+ return {};
23
+ }
24
+
25
+ return JSON.parse(JSON.stringify(value));
26
+ }
27
+
28
+ function normalize(text) {
29
+ return String(text ?? '')
30
+ .toLowerCase()
31
+ .replace(/[^\p{L}\p{N}\s-]/gu, ' ')
32
+ .replace(/\s+/g, ' ')
33
+ .trim();
34
+ }
35
+
36
+ function uniqueStrings(values) {
37
+ return [...new Set((values ?? []).filter(Boolean))];
38
+ }
39
+
40
+ function redactString(text, patterns) {
41
+ let result = String(text ?? '');
42
+ for (const pattern of patterns) {
43
+ result = result.replace(pattern, '[REDACTED]');
44
+ }
45
+ return result;
46
+ }
47
+
48
+ function redactValue(value, patterns) {
49
+ if (typeof value === 'string') {
50
+ return redactString(value, patterns);
51
+ }
52
+
53
+ if (Array.isArray(value)) {
54
+ return value.map((entry) => redactValue(entry, patterns));
55
+ }
56
+
57
+ if (value && typeof value === 'object') {
58
+ return Object.fromEntries(
59
+ Object.entries(value).map(([key, entry]) => [key, redactValue(entry, patterns)]),
60
+ );
61
+ }
62
+
63
+ return value;
64
+ }
65
+
66
+ function inferDecisionCategory(decisionText) {
67
+ const normalized = normalize(decisionText);
68
+ for (const [category, keywords] of Object.entries(CATEGORY_KEYWORDS)) {
69
+ if (keywords.some((keyword) => normalized.includes(keyword))) {
70
+ return category;
71
+ }
72
+ }
73
+
74
+ return null;
75
+ }
76
+
77
+ export function detectConflict(newDecision, existingDecisions = []) {
78
+ const newCategory = inferDecisionCategory(newDecision?.what);
79
+ if (!newCategory) {
80
+ return null;
81
+ }
82
+
83
+ const normalizedNewWhat = normalize(newDecision?.what);
84
+ return existingDecisions.find((decision) => {
85
+ if (!decision || decision.id === newDecision?.id) {
86
+ return false;
87
+ }
88
+
89
+ const existingCategory = inferDecisionCategory(decision.what);
90
+ if (existingCategory !== newCategory) {
91
+ return false;
92
+ }
93
+
94
+ return normalize(decision.what) !== normalizedNewWhat;
95
+ }) ?? null;
96
+ }
97
+
98
+ function resolveDecisionConflicts(projectMemory, conflictResolution) {
99
+ const decisions = [...(projectMemory.decisions ?? [])].sort((left, right) => (left.when ?? 0) - (right.when ?? 0));
100
+ const conflicts = [];
101
+
102
+ for (let index = 0; index < decisions.length; index += 1) {
103
+ const current = decisions[index];
104
+ const prior = decisions.slice(0, index).filter((decision) => !decision.supersededBy);
105
+ const conflict = detectConflict(current, prior);
106
+ if (!conflict) {
107
+ continue;
108
+ }
109
+
110
+ conflicts.push({ oldDecisionId: conflict.id, newDecisionId: current.id });
111
+ if (conflictResolution === 'latest_wins') {
112
+ conflict.supersededBy = current.id;
113
+ }
114
+ }
115
+
116
+ projectMemory.decisions = decisions;
117
+ return conflicts;
118
+ }
119
+
120
+ function archiveSessions(projectMemory, config) {
121
+ const now = config.now ?? Date.now();
122
+ const maxAgeMs = config.archiveAfterDays * 24 * 60 * 60 * 1000;
123
+ const sessions = [...(projectMemory.sessions ?? [])].sort((left, right) => (right.endedAt ?? 0) - (left.endedAt ?? 0));
124
+
125
+ const retained = [];
126
+ const archived = [];
127
+
128
+ for (const session of sessions) {
129
+ const sessionEndedAt = session.endedAt ?? session.startedAt ?? 0;
130
+ const isExpired = sessionEndedAt > 0 ? (now - sessionEndedAt) > maxAgeMs : false;
131
+ const overLimit = retained.length >= config.maxSessionsKept;
132
+
133
+ if (isExpired || overLimit) {
134
+ archived.push(session);
135
+ } else {
136
+ retained.push(session);
137
+ }
138
+ }
139
+
140
+ projectMemory.sessions = retained;
141
+ return archived;
142
+ }
143
+
144
+ export function runHygiene(projectMemory, config = {}) {
145
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
146
+ const nextMemory = redactValue(clone(projectMemory), mergedConfig.redactPatterns);
147
+
148
+ nextMemory.conventions = uniqueStrings(nextMemory.conventions);
149
+ nextMemory.techStack = uniqueStrings(nextMemory.techStack);
150
+ nextMemory.activeRules = uniqueStrings(nextMemory.activeRules);
151
+
152
+ const conflicts = resolveDecisionConflicts(nextMemory, mergedConfig.conflictResolution);
153
+ const archivedSessions = archiveSessions(nextMemory, mergedConfig);
154
+
155
+ return {
156
+ projectMemory: nextMemory,
157
+ archivedSessions,
158
+ conflicts,
159
+ };
160
+ }
@@ -0,0 +1,2 @@
1
+ export { detectConflict, runHygiene } from './hygiene.js';
2
+ export { expand, getContextInjection, search } from './retrieval.js';