crewly 1.8.9 → 1.8.11

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/config/constants.d.ts.map +1 -0
  2. package/config/index.d.ts.map +1 -0
  3. package/config/roles/_common/memory-instructions.md +6 -5
  4. package/config/roles/_common/wiki-instructions.md +49 -0
  5. package/config/roles/architect/prompt.md +2 -2
  6. package/config/roles/backend-developer/prompt.md +2 -2
  7. package/config/roles/designer/prompt.md +2 -2
  8. package/config/roles/developer/prompt.md +2 -2
  9. package/config/roles/frontend-developer/prompt.md +2 -2
  10. package/config/roles/fullstack-dev/prompt.md +2 -2
  11. package/config/roles/generalist/prompt.md +2 -2
  12. package/config/roles/ops/prompt.md +2 -2
  13. package/config/roles/orchestrator/prompt.md +135 -11
  14. package/config/roles/product-manager/prompt.md +2 -2
  15. package/config/roles/qa/prompt.md +2 -2
  16. package/config/roles/qa-engineer/prompt.md +2 -2
  17. package/config/roles/researcher/prompt.md +15 -6
  18. package/config/roles/sales/prompt.md +2 -2
  19. package/config/roles/support/prompt.md +2 -2
  20. package/config/roles/team-leader/prompt.md +17 -2
  21. package/config/roles/tpm/prompt.md +2 -2
  22. package/config/roles/ux-designer/prompt.md +2 -2
  23. package/config/skills/orchestrator/wiki-cleanup/SKILL.md +89 -0
  24. package/config/skills/orchestrator/wiki-cleanup/execute.sh +139 -0
  25. package/config/skills/orchestrator/wiki-lint/SKILL.md +75 -0
  26. package/config/skills/orchestrator/wiki-lint/execute.sh +66 -0
  27. package/config/skills/orchestrator/wiki-migrate/SKILL.md +103 -0
  28. package/config/skills/orchestrator/wiki-migrate/execute.sh +82 -0
  29. package/config/skills/orchestrator/wiki-process-queue/SKILL.md +9 -1
  30. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +169 -0
  31. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -0
  32. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +1779 -0
  33. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -0
  34. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +18 -0
  35. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  36. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +63 -0
  37. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  38. package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.d.ts.map +1 -1
  39. package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.js +5 -1
  40. package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.js.map +1 -1
  41. package/dist/backend/backend/src/controllers/wiki/wiki.controller.d.ts +109 -0
  42. package/dist/backend/backend/src/controllers/wiki/wiki.controller.d.ts.map +1 -1
  43. package/dist/backend/backend/src/controllers/wiki/wiki.controller.js +418 -4
  44. package/dist/backend/backend/src/controllers/wiki/wiki.controller.js.map +1 -1
  45. package/dist/backend/backend/src/controllers/wiki/wiki.routes.d.ts.map +1 -1
  46. package/dist/backend/backend/src/controllers/wiki/wiki.routes.js +11 -1
  47. package/dist/backend/backend/src/controllers/wiki/wiki.routes.js.map +1 -1
  48. package/dist/backend/backend/src/index.d.ts.map +1 -1
  49. package/dist/backend/backend/src/index.js +64 -0
  50. package/dist/backend/backend/src/index.js.map +1 -1
  51. package/dist/backend/backend/src/index.js.orc-bak-20260529 +3130 -0
  52. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +513 -0
  53. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -0
  54. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +1568 -0
  55. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -0
  56. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts +86 -0
  57. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts.map +1 -0
  58. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js +147 -0
  59. package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js.map +1 -0
  60. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts +68 -0
  61. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js +131 -0
  63. package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js.map +1 -0
  64. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts +130 -0
  65. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts.map +1 -0
  66. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js +263 -0
  67. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js.map +1 -0
  68. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts +74 -0
  69. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts.map +1 -0
  70. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js +140 -0
  71. package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js.map +1 -0
  72. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts +29 -0
  73. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +1 -0
  74. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +279 -0
  75. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +1 -0
  76. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +340 -0
  77. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -0
  78. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +1176 -0
  79. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -0
  80. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts +79 -0
  81. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts.map +1 -0
  82. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js +145 -0
  83. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js.map +1 -0
  84. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts +79 -0
  85. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts.map +1 -0
  86. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js +218 -0
  87. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js.map +1 -0
  88. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +16 -0
  89. package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +1 -0
  90. package/dist/backend/backend/src/services/agent/crewly-agent/index.js +16 -0
  91. package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +1 -0
  92. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts +135 -0
  93. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts.map +1 -0
  94. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js +185 -0
  95. package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js.map +1 -0
  96. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +141 -0
  97. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -0
  98. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +310 -0
  99. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -0
  100. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts +91 -0
  101. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts.map +1 -0
  102. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js +143 -0
  103. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js.map +1 -0
  104. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts +103 -0
  105. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts.map +1 -0
  106. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js +256 -0
  107. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js.map +1 -0
  108. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts +143 -0
  109. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts.map +1 -0
  110. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js +264 -0
  111. package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js.map +1 -0
  112. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts +13 -0
  113. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts.map +1 -0
  114. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +91 -0
  115. package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js.map +1 -0
  116. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +135 -0
  117. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -0
  118. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +1937 -0
  119. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -0
  120. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +1 -1
  121. package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts +429 -0
  122. package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts.map +1 -0
  123. package/dist/backend/backend/src/services/autonomous/auto-assign.service.js +852 -0
  124. package/dist/backend/backend/src/services/autonomous/auto-assign.service.js.map +1 -0
  125. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +171 -0
  126. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -0
  127. package/dist/backend/backend/src/services/project/task-tracking.service.js +725 -0
  128. package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -0
  129. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  130. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +50 -0
  131. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  132. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
  133. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  134. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +45 -0
  135. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  136. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
  137. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +34 -1
  138. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
  139. package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts +118 -0
  140. package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts.map +1 -0
  141. package/dist/backend/backend/src/services/v3/project-task-watcher.service.js +326 -0
  142. package/dist/backend/backend/src/services/v3/project-task-watcher.service.js.map +1 -0
  143. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.d.ts +72 -0
  144. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.d.ts.map +1 -0
  145. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js +186 -0
  146. package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js.map +1 -0
  147. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts +4 -1
  148. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts.map +1 -1
  149. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js +24 -1
  150. package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js.map +1 -1
  151. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts +74 -0
  152. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts.map +1 -0
  153. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js +154 -0
  154. package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js.map +1 -0
  155. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.d.ts +160 -0
  156. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.d.ts.map +1 -0
  157. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js +399 -0
  158. package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js.map +1 -0
  159. package/dist/backend/backend/src/services/wiki/wiki-lint.service.d.ts +182 -0
  160. package/dist/backend/backend/src/services/wiki/wiki-lint.service.d.ts.map +1 -0
  161. package/dist/backend/backend/src/services/wiki/wiki-lint.service.js +505 -0
  162. package/dist/backend/backend/src/services/wiki/wiki-lint.service.js.map +1 -0
  163. package/dist/backend/backend/src/services/wiki/wiki-migrate.service.d.ts +232 -0
  164. package/dist/backend/backend/src/services/wiki/wiki-migrate.service.d.ts.map +1 -0
  165. package/dist/backend/backend/src/services/wiki/wiki-migrate.service.js +1416 -0
  166. package/dist/backend/backend/src/services/wiki/wiki-migrate.service.js.map +1 -0
  167. package/dist/backend/backend/src/services/wiki/wiki-recent.service.d.ts +51 -0
  168. package/dist/backend/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -0
  169. package/dist/backend/backend/src/services/wiki/wiki-recent.service.js +102 -0
  170. package/dist/backend/backend/src/services/wiki/wiki-recent.service.js.map +1 -0
  171. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.d.ts +84 -0
  172. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.d.ts.map +1 -0
  173. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.js +156 -0
  174. package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.js.map +1 -0
  175. package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts +90 -0
  176. package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -0
  177. package/dist/backend/backend/src/services/wiki/wiki-search.service.js +190 -0
  178. package/dist/backend/backend/src/services/wiki/wiki-search.service.js.map +1 -0
  179. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.d.ts +164 -0
  180. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.d.ts.map +1 -0
  181. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js +675 -0
  182. package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js.map +1 -0
  183. package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
  184. package/dist/backend/backend/src/services/workflow/cron-task.service.js +65 -0
  185. package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
  186. package/dist/backend/backend/src/types/auto-assign.types.d.ts +271 -0
  187. package/dist/backend/backend/src/types/auto-assign.types.d.ts.map +1 -0
  188. package/dist/backend/backend/src/types/auto-assign.types.js +136 -0
  189. package/dist/backend/backend/src/types/auto-assign.types.js.map +1 -0
  190. package/dist/backend/backend/src/types/cron-task.types.d.ts +16 -1
  191. package/dist/backend/backend/src/types/cron-task.types.d.ts.map +1 -1
  192. package/dist/backend/backend/src/utils/esm-require.utils.d.ts +111 -0
  193. package/dist/backend/backend/src/utils/esm-require.utils.d.ts.map +1 -0
  194. package/dist/backend/backend/src/utils/esm-require.utils.js +124 -0
  195. package/dist/backend/backend/src/utils/esm-require.utils.js.map +1 -0
  196. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +220 -0
  197. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -0
  198. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js +37 -0
  199. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -0
  200. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts +56 -0
  201. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts.map +1 -0
  202. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js +91 -0
  203. package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js.map +1 -0
  204. package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
  205. package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
  206. package/dist/cli/backend/src/services/knowledge/learnings-index.service.js +304 -0
  207. package/dist/cli/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
  208. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts +115 -0
  209. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts.map +1 -0
  210. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js +215 -0
  211. package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js.map +1 -0
  212. package/dist/cli/backend/src/services/memory/embedding-provider.d.ts +78 -0
  213. package/dist/cli/backend/src/services/memory/embedding-provider.d.ts.map +1 -0
  214. package/dist/cli/backend/src/services/memory/embedding-provider.js +179 -0
  215. package/dist/cli/backend/src/services/memory/embedding-provider.js.map +1 -0
  216. package/dist/cli/backend/src/services/memory/vector-store.service.d.ts +331 -0
  217. package/dist/cli/backend/src/services/memory/vector-store.service.d.ts.map +1 -0
  218. package/dist/cli/backend/src/services/memory/vector-store.service.js +814 -0
  219. package/dist/cli/backend/src/services/memory/vector-store.service.js.map +1 -0
  220. package/dist/cli/backend/src/services/project/task-tracking.service.d.ts +171 -0
  221. package/dist/cli/backend/src/services/project/task-tracking.service.d.ts.map +1 -0
  222. package/dist/cli/backend/src/services/project/task-tracking.service.js +725 -0
  223. package/dist/cli/backend/src/services/project/task-tracking.service.js.map +1 -0
  224. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
  225. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  226. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +45 -0
  227. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  228. package/dist/cli/backend/src/types/auto-assign.types.d.ts +271 -0
  229. package/dist/cli/backend/src/types/auto-assign.types.d.ts.map +1 -0
  230. package/dist/cli/backend/src/types/auto-assign.types.js +136 -0
  231. package/dist/cli/backend/src/types/auto-assign.types.js.map +1 -0
  232. package/dist/cli/cli/src/index.js +0 -0
  233. package/frontend/dist/assets/{index-db3f5041.css → index-068bb4f6.css} +10 -1
  234. package/frontend/dist/assets/index-c24ceb15.js +4960 -0
  235. package/frontend/dist/index.html +2 -2
  236. package/package.json +1 -1
  237. package/config/skills/agent/core/query-knowledge/SKILL.md +0 -87
  238. package/config/skills/agent/core/query-knowledge/execute.sh +0 -30
  239. package/config/skills/orchestrator/query-knowledge/SKILL.md +0 -75
  240. package/config/skills/orchestrator/query-knowledge/execute.sh +0 -30
  241. package/frontend/dist/assets/index-cc115bb4.js +0 -4926
@@ -0,0 +1,160 @@
1
+ /**
2
+ * WikiCleanupService — detect + remove low-quality pages from a wiki vault.
3
+ *
4
+ * Origin: the 2026-05-27 migration dumped every agent's `memory.json`
5
+ * roleKnowledge entries as their own wiki page (~3,277 pages across 6
6
+ * project vaults). Many are stream-of-consciousness daily memory rather
7
+ * than team-level patterns. Symptom: each project vault has 500+ pages
8
+ * under `patterns/`, most low-quality (confidence < 0.5, verbatim memory
9
+ * dump shape). Karpathy's wiki spec says "frequently-read distilled
10
+ * knowledge" — 500 stream-of-consciousness pages violates that.
11
+ *
12
+ * Detection is **rule-based + mechanical** (OSS does this). The actual
13
+ * keep/delete decision can be deferred to an agent via the bridge —
14
+ * this service exposes both `scan(rules)` (mechanical candidate list)
15
+ * and `apply(pages)` (executes the explicit page list provided).
16
+ *
17
+ * Design rules (mirror WikiMigrateService):
18
+ * - Default DRY-RUN. Caller must pass `{ apply: true }` to delete.
19
+ * - Idempotent + reversible. Every deleted page body + frontmatter is
20
+ * archived to `<vault>/.wiki-cleanup-archive.json` BEFORE the file
21
+ * is removed. Re-running with the same input is a no-op.
22
+ * - Migrate manifest is updated so the SAME source entry is not
23
+ * re-imported by the next `wiki-migrate --apply` (would defeat the
24
+ * cleanup).
25
+ * - LEGACY FILES (`memory.json`, `.crewly/knowledge/*`) are NEVER
26
+ * touched. The cleanup ONLY removes pages from the wiki vault.
27
+ * - Frozen folders (`memory/`, `sop/`, `sop-overrides/`, `okr/`,
28
+ * `decisions/manual/`) are never scanned.
29
+ *
30
+ * @module services/wiki/wiki-cleanup.service
31
+ */
32
+ export declare const WIKI_CLEANUP_ARCHIVE_FILENAME = ".wiki-cleanup-archive.json";
33
+ export declare const WIKI_CLEANUP_ARCHIVE_VERSION = 1;
34
+ export interface WikiCleanupRules {
35
+ /** Drop pages whose frontmatter `confidence` is below this. Default 0.5. */
36
+ minConfidence?: number;
37
+ /** Drop pages whose `migrated_from` starts with `agent/`. Default true. */
38
+ dropAgentMemoryDumps?: boolean;
39
+ /**
40
+ * Keep at most N pages per `original_author`. Pages outside the top-N
41
+ * (sorted by confidence desc, then original_date desc) are flagged.
42
+ * Default: 0 (cap disabled).
43
+ */
44
+ maxPerAgent?: number;
45
+ }
46
+ export interface WikiCleanupCandidate {
47
+ /** Path relative to the vault root (e.g. `llm-curated/patterns/x.md`). */
48
+ relPath: string;
49
+ /** Why this page is a cleanup candidate (one or more rule names). */
50
+ reasons: string[];
51
+ /** Parsed `confidence` (if present in frontmatter), used for ranking. */
52
+ confidence: number | null;
53
+ /** Parsed `original_author` (if present), used by the per-agent cap. */
54
+ originalAuthor: string | null;
55
+ /** Parsed `migrated_from` (if present), used to invalidate manifest entry. */
56
+ migratedFrom: string | null;
57
+ /** Parsed `original_id` (if present), used to invalidate manifest entry. */
58
+ originalId: string | null;
59
+ /** File size in bytes. */
60
+ bytes: number;
61
+ }
62
+ export interface WikiCleanupScanInput {
63
+ /** Absolute vault path (the dir containing `SCHEMA.md`). */
64
+ vaultPath: string;
65
+ /** Rule overrides; defaults applied for any missing key. */
66
+ rules?: WikiCleanupRules;
67
+ }
68
+ export interface WikiCleanupScanResult {
69
+ ok: true;
70
+ vaultPath: string;
71
+ /** Pages flagged by at least one rule. Capped at {@link SCAN_HARD_CAP}. */
72
+ candidates: WikiCleanupCandidate[];
73
+ /** Total pages walked (whether candidate or not). */
74
+ scannedCount: number;
75
+ /** Did the scan hit {@link SCAN_HARD_CAP}? */
76
+ truncated: boolean;
77
+ /** Per-reason counts for quick eyeballing. */
78
+ summary: {
79
+ lowConfidence: number;
80
+ agentMemoryDump: number;
81
+ perAgentCapped: number;
82
+ };
83
+ }
84
+ export interface WikiCleanupApplyInput {
85
+ vaultPath: string;
86
+ /**
87
+ * Explicit list of relative paths to delete. The bridge / agent passes
88
+ * this in after deciding which scan candidates to actually act on. We
89
+ * deliberately do NOT take a rule set here — `apply` is the mechanical
90
+ * deletion step, the decision happened upstream.
91
+ */
92
+ pages: string[];
93
+ }
94
+ export interface WikiCleanupApplyResult {
95
+ ok: true;
96
+ vaultPath: string;
97
+ /** Pages actually deleted in this run. */
98
+ deleted: string[];
99
+ /** Pages requested but not deleted (missing on disk, already archived, etc). */
100
+ skipped: Array<{
101
+ relPath: string;
102
+ reason: 'not_found' | 'outside_vault' | 'frozen';
103
+ }>;
104
+ archivePath: string;
105
+ /** Migrate manifest entries removed so cleanup-deleted pages don't get re-migrated. */
106
+ manifestEntriesInvalidated: number;
107
+ }
108
+ export type WikiCleanupOutcome = WikiCleanupScanResult | WikiCleanupApplyResult | {
109
+ ok: false;
110
+ reason: 'invalid_input' | 'vault_missing';
111
+ message: string;
112
+ };
113
+ export declare class WikiCleanupService {
114
+ private static instance;
115
+ private readonly logger;
116
+ constructor();
117
+ static getInstance(): WikiCleanupService;
118
+ /** Test-only reset. */
119
+ static resetInstance(): void;
120
+ /**
121
+ * Walk the vault's `llm-curated/` tree, parse frontmatter, return all
122
+ * pages matching at least one cleanup rule. Pure read — no writes.
123
+ */
124
+ scan(input: WikiCleanupScanInput): Promise<WikiCleanupOutcome>;
125
+ /**
126
+ * Delete the listed pages from the vault, archive each one (body +
127
+ * frontmatter) to `.wiki-cleanup-archive.json`, and invalidate the
128
+ * corresponding entry in the migrate manifest so the same source can't
129
+ * resurrect the page on the next `wiki-migrate --apply`.
130
+ */
131
+ apply(input: WikiCleanupApplyInput): Promise<WikiCleanupOutcome>;
132
+ private validateVault;
133
+ /**
134
+ * Best-effort safe-rel normalisation. Returns null if the path would
135
+ * resolve outside the vault (`..` traversal etc).
136
+ */
137
+ private normalizeRelPath;
138
+ /**
139
+ * Walk the vault tree, parsing frontmatter on each `.md` file. Skips
140
+ * frozen folders + non-md files. Returns true if the scan was truncated
141
+ * by the hard cap.
142
+ */
143
+ private walkPages;
144
+ }
145
+ /**
146
+ * Parse `confidence` from frontmatter into a number, or null if absent /
147
+ * unparseable. Accepts both numeric (`0.3`) and string (`"0.3"`) shapes
148
+ * because YAML quoting is inconsistent across older migrated pages.
149
+ */
150
+ export declare function parseConfidence(raw: unknown): number | null;
151
+ /**
152
+ * Minimal YAML frontmatter parser. Handles the shapes our migrate service
153
+ * emits — `key: value` lines, with optional quotes around values. NOT a
154
+ * general YAML parser. Returns `{}` when no frontmatter is present.
155
+ */
156
+ export declare function parseFrontmatter(raw: string): {
157
+ frontmatter: Record<string, unknown>;
158
+ body: string;
159
+ };
160
+ //# sourceMappingURL=wiki-cleanup.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiki-cleanup.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-cleanup.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,399 @@
1
+ /**
2
+ * WikiCleanupService — detect + remove low-quality pages from a wiki vault.
3
+ *
4
+ * Origin: the 2026-05-27 migration dumped every agent's `memory.json`
5
+ * roleKnowledge entries as their own wiki page (~3,277 pages across 6
6
+ * project vaults). Many are stream-of-consciousness daily memory rather
7
+ * than team-level patterns. Symptom: each project vault has 500+ pages
8
+ * under `patterns/`, most low-quality (confidence < 0.5, verbatim memory
9
+ * dump shape). Karpathy's wiki spec says "frequently-read distilled
10
+ * knowledge" — 500 stream-of-consciousness pages violates that.
11
+ *
12
+ * Detection is **rule-based + mechanical** (OSS does this). The actual
13
+ * keep/delete decision can be deferred to an agent via the bridge —
14
+ * this service exposes both `scan(rules)` (mechanical candidate list)
15
+ * and `apply(pages)` (executes the explicit page list provided).
16
+ *
17
+ * Design rules (mirror WikiMigrateService):
18
+ * - Default DRY-RUN. Caller must pass `{ apply: true }` to delete.
19
+ * - Idempotent + reversible. Every deleted page body + frontmatter is
20
+ * archived to `<vault>/.wiki-cleanup-archive.json` BEFORE the file
21
+ * is removed. Re-running with the same input is a no-op.
22
+ * - Migrate manifest is updated so the SAME source entry is not
23
+ * re-imported by the next `wiki-migrate --apply` (would defeat the
24
+ * cleanup).
25
+ * - LEGACY FILES (`memory.json`, `.crewly/knowledge/*`) are NEVER
26
+ * touched. The cleanup ONLY removes pages from the wiki vault.
27
+ * - Frozen folders (`memory/`, `sop/`, `sop-overrides/`, `okr/`,
28
+ * `decisions/manual/`) are never scanned.
29
+ *
30
+ * @module services/wiki/wiki-cleanup.service
31
+ */
32
+ import * as fs from 'fs/promises';
33
+ import * as path from 'path';
34
+ import { existsSync } from 'fs';
35
+ import { LoggerService } from '../core/logger.service.js';
36
+ import { atomicWriteJson, safeReadJson, ensureDir } from '../../utils/file-io.utils.js';
37
+ // ---------------------------------------------------------------------------
38
+ // Constants
39
+ // ---------------------------------------------------------------------------
40
+ export const WIKI_CLEANUP_ARCHIVE_FILENAME = '.wiki-cleanup-archive.json';
41
+ export const WIKI_CLEANUP_ARCHIVE_VERSION = 1;
42
+ /** Folders we never scan — managed by OSS code path, not LLM-editable. */
43
+ const FROZEN_FOLDERS = new Set([
44
+ 'memory',
45
+ 'sop',
46
+ 'sop-overrides',
47
+ 'okr',
48
+ ]);
49
+ /** Folder under the vault where llm-curated pages live. */
50
+ const LLM_CURATED_DIR = 'llm-curated';
51
+ /** Hard cap on candidates returned per scan — defensive (prevents OOM on a
52
+ * corrupted vault with 100k+ files). */
53
+ const SCAN_HARD_CAP = 5_000;
54
+ // ---------------------------------------------------------------------------
55
+ // Service
56
+ // ---------------------------------------------------------------------------
57
+ export class WikiCleanupService {
58
+ static instance = null;
59
+ logger;
60
+ constructor() {
61
+ this.logger = LoggerService.getInstance().createComponentLogger('WikiCleanup');
62
+ }
63
+ static getInstance() {
64
+ if (!this.instance)
65
+ this.instance = new WikiCleanupService();
66
+ return this.instance;
67
+ }
68
+ /** Test-only reset. */
69
+ static resetInstance() {
70
+ this.instance = null;
71
+ }
72
+ /**
73
+ * Walk the vault's `llm-curated/` tree, parse frontmatter, return all
74
+ * pages matching at least one cleanup rule. Pure read — no writes.
75
+ */
76
+ async scan(input) {
77
+ const validation = this.validateVault(input.vaultPath);
78
+ if (!validation.ok)
79
+ return validation;
80
+ const rules = {
81
+ minConfidence: input.rules?.minConfidence ?? 0.5,
82
+ dropAgentMemoryDumps: input.rules?.dropAgentMemoryDumps ?? true,
83
+ maxPerAgent: input.rules?.maxPerAgent ?? 0,
84
+ };
85
+ const llmCuratedRoot = path.join(input.vaultPath, LLM_CURATED_DIR);
86
+ const allPages = [];
87
+ let truncated = false;
88
+ if (existsSync(llmCuratedRoot)) {
89
+ truncated = await this.walkPages(llmCuratedRoot, input.vaultPath, allPages, SCAN_HARD_CAP);
90
+ }
91
+ const flagged = new Map();
92
+ const summary = { lowConfidence: 0, agentMemoryDump: 0, perAgentCapped: 0 };
93
+ for (const page of allPages) {
94
+ const fm = page.frontmatter;
95
+ const reasons = [];
96
+ const conf = parseConfidence(fm['confidence']);
97
+ if (conf !== null && conf < rules.minConfidence) {
98
+ reasons.push(`confidence ${conf} < ${rules.minConfidence}`);
99
+ summary.lowConfidence++;
100
+ }
101
+ const migratedFrom = typeof fm['migrated_from'] === 'string' ? fm['migrated_from'] : null;
102
+ if (rules.dropAgentMemoryDumps && migratedFrom?.startsWith('agent/') && migratedFrom.endsWith('/memory.json')) {
103
+ reasons.push('migrated from agent memory.json');
104
+ summary.agentMemoryDump++;
105
+ }
106
+ if (reasons.length > 0) {
107
+ flagged.set(page.relPath, {
108
+ reasons,
109
+ meta: {
110
+ confidence: conf,
111
+ originalAuthor: typeof fm['original_author'] === 'string' ? fm['original_author'] : null,
112
+ originalDate: typeof fm['original_date'] === 'string' ? fm['original_date'] : null,
113
+ },
114
+ });
115
+ }
116
+ }
117
+ // Second pass — per-agent cap. Only considers pages NOT already flagged
118
+ // by other rules (so a low-confidence page doesn't take a "cap slot").
119
+ if (rules.maxPerAgent > 0) {
120
+ const byAuthor = new Map();
121
+ for (const page of allPages) {
122
+ if (flagged.has(page.relPath))
123
+ continue;
124
+ const fm = page.frontmatter;
125
+ const author = typeof fm['original_author'] === 'string' ? fm['original_author'] : null;
126
+ if (!author)
127
+ continue;
128
+ const conf = parseConfidence(fm['confidence']) ?? 0;
129
+ const date = typeof fm['original_date'] === 'string' ? fm['original_date'] : '';
130
+ const arr = byAuthor.get(author) ?? [];
131
+ arr.push({ relPath: page.relPath, confidence: conf, date });
132
+ byAuthor.set(author, arr);
133
+ }
134
+ for (const [author, arr] of byAuthor) {
135
+ if (arr.length <= rules.maxPerAgent)
136
+ continue;
137
+ // Keep top-N by confidence desc, then date desc.
138
+ arr.sort((a, b) => (b.confidence - a.confidence) || b.date.localeCompare(a.date));
139
+ for (const overflow of arr.slice(rules.maxPerAgent)) {
140
+ const existing = flagged.get(overflow.relPath);
141
+ if (existing) {
142
+ existing.reasons.push(`per-agent cap (${author}: keep ${rules.maxPerAgent})`);
143
+ }
144
+ else {
145
+ flagged.set(overflow.relPath, {
146
+ reasons: [`per-agent cap (${author}: keep ${rules.maxPerAgent})`],
147
+ meta: { confidence: overflow.confidence, originalAuthor: author, originalDate: overflow.date },
148
+ });
149
+ }
150
+ summary.perAgentCapped++;
151
+ }
152
+ }
153
+ }
154
+ const candidates = [];
155
+ for (const page of allPages) {
156
+ const flag = flagged.get(page.relPath);
157
+ if (!flag)
158
+ continue;
159
+ const fm = page.frontmatter;
160
+ candidates.push({
161
+ relPath: page.relPath,
162
+ reasons: flag.reasons,
163
+ confidence: flag.meta.confidence,
164
+ originalAuthor: flag.meta.originalAuthor,
165
+ migratedFrom: typeof fm['migrated_from'] === 'string' ? fm['migrated_from'] : null,
166
+ originalId: typeof fm['original_id'] === 'string' ? fm['original_id'] : null,
167
+ bytes: page.bytes,
168
+ });
169
+ if (candidates.length >= SCAN_HARD_CAP) {
170
+ truncated = true;
171
+ break;
172
+ }
173
+ }
174
+ this.logger.info('Wiki cleanup scan complete', {
175
+ vaultPath: input.vaultPath,
176
+ scannedCount: allPages.length,
177
+ candidateCount: candidates.length,
178
+ truncated,
179
+ summary,
180
+ });
181
+ return {
182
+ ok: true,
183
+ vaultPath: input.vaultPath,
184
+ candidates,
185
+ scannedCount: allPages.length,
186
+ truncated,
187
+ summary,
188
+ };
189
+ }
190
+ /**
191
+ * Delete the listed pages from the vault, archive each one (body +
192
+ * frontmatter) to `.wiki-cleanup-archive.json`, and invalidate the
193
+ * corresponding entry in the migrate manifest so the same source can't
194
+ * resurrect the page on the next `wiki-migrate --apply`.
195
+ */
196
+ async apply(input) {
197
+ const validation = this.validateVault(input.vaultPath);
198
+ if (!validation.ok)
199
+ return validation;
200
+ if (!Array.isArray(input.pages) || input.pages.length === 0) {
201
+ return { ok: false, reason: 'invalid_input', message: 'pages must be a non-empty array' };
202
+ }
203
+ const archivePath = path.join(input.vaultPath, WIKI_CLEANUP_ARCHIVE_FILENAME);
204
+ const archive = await safeReadJson(archivePath, { version: WIKI_CLEANUP_ARCHIVE_VERSION, entries: [] }, this.logger);
205
+ if (archive.version !== WIKI_CLEANUP_ARCHIVE_VERSION) {
206
+ // Migrate-style: don't trust an unknown version, just start fresh.
207
+ archive.version = WIKI_CLEANUP_ARCHIVE_VERSION;
208
+ archive.entries = [];
209
+ }
210
+ const deleted = [];
211
+ const skipped = [];
212
+ for (const relPath of input.pages) {
213
+ const safe = this.normalizeRelPath(relPath);
214
+ if (!safe) {
215
+ skipped.push({ relPath, reason: 'outside_vault' });
216
+ continue;
217
+ }
218
+ // Defence: even if the caller passes a frozen-folder path, refuse.
219
+ // The top-level segment is the folder name (`memory/secret.md` →
220
+ // `memory`); pages directly under the vault root are never frozen.
221
+ const segments = safe.split('/');
222
+ if (segments.length >= 2 && FROZEN_FOLDERS.has(segments[0])) {
223
+ skipped.push({ relPath, reason: 'frozen' });
224
+ continue;
225
+ }
226
+ const abs = path.join(input.vaultPath, safe);
227
+ if (!existsSync(abs)) {
228
+ skipped.push({ relPath, reason: 'not_found' });
229
+ continue;
230
+ }
231
+ // Read + parse before delete so we can archive shape.
232
+ const raw = await fs.readFile(abs, 'utf8');
233
+ const { frontmatter, body } = parseFrontmatter(raw);
234
+ archive.entries.push({
235
+ relPath: safe,
236
+ archivedAt: new Date().toISOString(),
237
+ reasons: ['apply-list'],
238
+ body,
239
+ frontmatter,
240
+ });
241
+ await fs.unlink(abs);
242
+ deleted.push(safe);
243
+ }
244
+ // Persist archive — the rollback source of truth.
245
+ //
246
+ // **Manifest is deliberately NOT modified** (2026-05-28 fix). Earlier
247
+ // versions removed the matching entries from `.migration-state.json`
248
+ // on the theory "now nothing pins the page in place." That was
249
+ // exactly backwards: the migrate manifest is what makes
250
+ // `wiki-migrate --apply` IDEMPOTENT. With the entry present + hash
251
+ // match, migrate sees "already migrated" → skips. With the entry
252
+ // removed, migrate sees "new content" → re-imports → the
253
+ // just-deleted page reappears on the next bridge tick. Symptom seen
254
+ // 2026-05-28 ~05:30: 20 pages deleted, then 20 re-imported by the
255
+ // next migrate tick, candidate count never dropped. The page on
256
+ // disk is gone; that is sufficient. Manifest stays intact.
257
+ await ensureDir(input.vaultPath);
258
+ await atomicWriteJson(archivePath, archive);
259
+ this.logger.info('Wiki cleanup apply complete', {
260
+ vaultPath: input.vaultPath,
261
+ requested: input.pages.length,
262
+ deleted: deleted.length,
263
+ skipped: skipped.length,
264
+ archivePath,
265
+ });
266
+ return {
267
+ ok: true,
268
+ vaultPath: input.vaultPath,
269
+ deleted,
270
+ skipped,
271
+ archivePath,
272
+ manifestEntriesInvalidated: 0,
273
+ };
274
+ }
275
+ // -------------------------------------------------------------------------
276
+ // Internals
277
+ // -------------------------------------------------------------------------
278
+ validateVault(vaultPath) {
279
+ if (!vaultPath || !path.isAbsolute(vaultPath)) {
280
+ return { ok: false, reason: 'invalid_input', message: 'vaultPath must be an absolute path' };
281
+ }
282
+ if (!existsSync(vaultPath)) {
283
+ return { ok: false, reason: 'vault_missing', message: `vault not found: ${vaultPath}` };
284
+ }
285
+ return { ok: true };
286
+ }
287
+ /**
288
+ * Best-effort safe-rel normalisation. Returns null if the path would
289
+ * resolve outside the vault (`..` traversal etc).
290
+ */
291
+ normalizeRelPath(rel) {
292
+ const normalised = path.posix.normalize(rel.replace(/\\/g, '/'));
293
+ if (normalised.startsWith('..') || path.isAbsolute(normalised))
294
+ return null;
295
+ return normalised;
296
+ }
297
+ /**
298
+ * Walk the vault tree, parsing frontmatter on each `.md` file. Skips
299
+ * frozen folders + non-md files. Returns true if the scan was truncated
300
+ * by the hard cap.
301
+ */
302
+ async walkPages(dir, vaultPath, accumulator, cap) {
303
+ let entries;
304
+ try {
305
+ entries = await fs.readdir(dir, { withFileTypes: true });
306
+ }
307
+ catch {
308
+ return false;
309
+ }
310
+ for (const entry of entries) {
311
+ if (accumulator.length >= cap)
312
+ return true;
313
+ // Skip frozen folders only at the vault-root level (`llm-curated/`
314
+ // sits next to them, so we never recurse INTO sibling frozen dirs
315
+ // — but defence-in-depth this check covers anyone who calls
316
+ // `walkPages` with the vault root directly).
317
+ if (entry.isDirectory()) {
318
+ const relParent = path.relative(vaultPath, path.join(dir, entry.name));
319
+ const topLevel = relParent.split(path.sep)[0];
320
+ if (FROZEN_FOLDERS.has(topLevel))
321
+ continue;
322
+ const truncated = await this.walkPages(path.join(dir, entry.name), vaultPath, accumulator, cap);
323
+ if (truncated)
324
+ return true;
325
+ continue;
326
+ }
327
+ if (!entry.isFile() || !entry.name.endsWith('.md'))
328
+ continue;
329
+ const abs = path.join(dir, entry.name);
330
+ try {
331
+ const stat = await fs.stat(abs);
332
+ const raw = await fs.readFile(abs, 'utf8');
333
+ const { frontmatter } = parseFrontmatter(raw);
334
+ accumulator.push({
335
+ relPath: path.relative(vaultPath, abs).split(path.sep).join('/'),
336
+ frontmatter,
337
+ bytes: stat.size,
338
+ });
339
+ }
340
+ catch (err) {
341
+ this.logger.debug('walkPages: skipping unreadable file', {
342
+ path: abs,
343
+ error: err instanceof Error ? err.message : String(err),
344
+ });
345
+ }
346
+ }
347
+ return false;
348
+ }
349
+ }
350
+ // ---------------------------------------------------------------------------
351
+ // Helpers (module-private, exported for tests)
352
+ // ---------------------------------------------------------------------------
353
+ /**
354
+ * Parse `confidence` from frontmatter into a number, or null if absent /
355
+ * unparseable. Accepts both numeric (`0.3`) and string (`"0.3"`) shapes
356
+ * because YAML quoting is inconsistent across older migrated pages.
357
+ */
358
+ export function parseConfidence(raw) {
359
+ if (typeof raw === 'number' && Number.isFinite(raw))
360
+ return raw;
361
+ if (typeof raw === 'string') {
362
+ const parsed = parseFloat(raw);
363
+ if (Number.isFinite(parsed))
364
+ return parsed;
365
+ }
366
+ return null;
367
+ }
368
+ /**
369
+ * Minimal YAML frontmatter parser. Handles the shapes our migrate service
370
+ * emits — `key: value` lines, with optional quotes around values. NOT a
371
+ * general YAML parser. Returns `{}` when no frontmatter is present.
372
+ */
373
+ export function parseFrontmatter(raw) {
374
+ const match = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
375
+ if (!match)
376
+ return { frontmatter: {}, body: raw };
377
+ const fm = {};
378
+ for (const line of match[1].split('\n')) {
379
+ const lineMatch = line.match(/^([A-Za-z_][A-Za-z0-9_]*):\s*(.*)$/);
380
+ if (!lineMatch)
381
+ continue;
382
+ let value = lineMatch[2].trim();
383
+ // Strip wrapping quotes.
384
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
385
+ value = value.slice(1, -1);
386
+ }
387
+ // Coerce a few common scalar shapes.
388
+ if (value === 'true')
389
+ fm[lineMatch[1]] = true;
390
+ else if (value === 'false')
391
+ fm[lineMatch[1]] = false;
392
+ else if (/^-?\d+(\.\d+)?$/.test(value))
393
+ fm[lineMatch[1]] = parseFloat(value);
394
+ else
395
+ fm[lineMatch[1]] = value;
396
+ }
397
+ return { frontmatter: fm, body: match[2] };
398
+ }
399
+ //# sourceMappingURL=wiki-cleanup.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiki-cleanup.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-cleanup.service.ts"],"names":[],"mappings":"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"}