kenaz 0.3.2 → 0.3.3

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 (390) hide show
  1. package/core/.agents/skills/typesafe-ai/LICENSE +21 -21
  2. package/core/.agents/skills/typesafe-ai/SKILL.md +149 -149
  3. package/core/.claude/commands/Ansuz.md +19 -30
  4. package/core/.claude/hooks/_ansuz-conversation.js +1 -0
  5. package/core/.claude/hooks/_ansuz-conversation.test.js +6 -0
  6. package/core/.claude/hooks/_run-user-prompt.js +0 -4
  7. package/core/.claude/hooks/_run-user-prompt.test.js +2 -3
  8. package/core/.claude/hooks/session-init.ps1 +49 -49
  9. package/core/.claude/settings.json +0 -37
  10. package/core/.claude/skills/ui-ux-pro-max/data/charts.csv +26 -26
  11. package/core/.claude/skills/ui-ux-pro-max/data/colors.csv +97 -97
  12. package/core/.claude/skills/ui-ux-pro-max/data/icons.csv +101 -101
  13. package/core/.claude/skills/ui-ux-pro-max/data/landing.csv +31 -31
  14. package/core/.claude/skills/ui-ux-pro-max/data/products.csv +96 -96
  15. package/core/.claude/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  16. package/core/.claude/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  17. package/core/.claude/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  18. package/core/.claude/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  19. package/core/.claude/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  20. package/core/.claude/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  21. package/core/.claude/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  22. package/core/.claude/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  23. package/core/.claude/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
  24. package/core/.claude/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
  25. package/core/.claude/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  26. package/core/.claude/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  27. package/core/.claude/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  28. package/core/.claude/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  29. package/core/.claude/skills/ui-ux-pro-max/data/styles.csv +68 -68
  30. package/core/.claude/skills/ui-ux-pro-max/data/typography.csv +57 -57
  31. package/core/.claude/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
  32. package/core/.claude/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
  33. package/core/.claude/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
  34. package/core/.claude/skills/ui-ux-pro-max/scripts/core.py +253 -253
  35. package/core/.claude/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
  36. package/core/.claude/skills/ui-ux-pro-max/scripts/search.py +106 -106
  37. package/core/.collaboration/core/task-api.js +3 -8
  38. package/core/.formation/tests/hello.txt +2 -2
  39. package/core/.formation/tools/prompt.js +58 -5
  40. package/core/.formation/tools/prompt.test.js +29 -0
  41. package/core/.kenaz/claude-hooks-manifest.json +16 -16
  42. package/core/.kenaz/knowledge/ladybug_2c51da1e_shadow_file_frame_group.patch +163 -163
  43. package/core/.kenaz/knowledge/ladybug_30cf85690e_shadow_page_read_during_checkpoint.patch +393 -393
  44. package/core/.kenaz/knowledge/ladybug_7a17858d3a_node_group_delete_lock.patch +102 -102
  45. package/core/.kenaz/knowledge/ladybug_926a0ba1_column_checkpoint.patch +412 -412
  46. package/core/.kenaz/knowledge/ladybug_a346c4c4b6_pk_index_header_pages.patch +144 -144
  47. package/core/.kenaz/knowledge/ladybug_ba5f38815b_csr_node_group.patch +86 -86
  48. package/core/.kenaz/muninn_episode_write.ps1 +17 -17
  49. package/core/.kenaz/specialist/field_report_watermark.json +1 -1
  50. package/core/.kenaz/specialist/memory_guard_fired.json +1 -1
  51. package/core/.kenaz/specialist/memory_guard_trigger_cache.json +1 -1
  52. package/core/.kenaz/specialist/t1777_probe.txt +1 -1
  53. package/core/.matrix/index.matrix +5 -5
  54. package/core/.specialist/Ansuz/RULES.md +6 -10
  55. package/core/.specialist/tools/__tests__/task-2218-boot-session-id.test.js +17 -1
  56. package/core/.specialist/tools/__tests__/task-2222-session-identity-interleave.test.js +17 -1
  57. package/core/.specialist/tools/__tests__/task-2254-handoff-archive-contract.test.js +6 -5
  58. package/core/.specialist/tools/ansuz-boot-fast.js +44 -100
  59. package/core/.specialist/tools/ansuz-boot-fast.test.js +45 -1
  60. package/core/KENAZ_CORE_VERSION +1 -1
  61. package/core/dev/ANSUZ_STARTUP_INJECTION_REVIEW.md +355 -355
  62. package/core/dev/JEV_INTEGRATION_PLAN.md +189 -189
  63. package/core/dev/design/matrix_format_EXAMPLE_memory.matrix +13 -13
  64. package/core/dev/design/matrix_format_EXAMPLE_project_status.matrix +9 -9
  65. package/core/dev/design/matrix_format_EXAMPLE_tasks.matrix +14 -14
  66. package/core/dev/design/matrix_v2_EXAMPLE.matrix +67 -67
  67. package/core/dev/jev-eval/ACTIVE_CORRECTION.md +52 -52
  68. package/core/dev/jev-eval/CONTEXT_REVIEW.md +31 -31
  69. package/core/dev/jev-eval/EVALUATION_STATUS.md +39 -39
  70. package/core/dev/jev-eval/HISTORICAL_CORPUS.md +33 -33
  71. package/core/dev/jev-eval/README.md +99 -99
  72. package/core/dev/jev-eval/THALAMUS_RANKING.md +58 -58
  73. package/core/dev/jev-eval/reports/annotation-pilot-2026-09-20.json +32 -32
  74. package/core/dev/jev-eval/reports/context-review-2026-09-20.json +48 -48
  75. package/core/dev/jev-eval/reports/history-corpus-2026-09-20.json +52 -52
  76. package/core/dev/pipeline/SELF_ENHANCEMENT_STATUS.json.bak +47 -47
  77. package/core/dev/pipeline/tasks/.gitkeep +1 -1
  78. package/core/dev/pipeline/test_results/TASK_TEST_PARALLEL_002_result.txt +27 -27
  79. package/core/dev/plans/ANSUZ_SLIM_PLAN.md +68 -0
  80. package/core/dev/scripts/init_git.sh +0 -0
  81. package/core/dev/scripts/init_project.sh +0 -0
  82. package/core/dev/scripts/legacy/dev_agent_scheduler.ps1.bak +536 -536
  83. package/core/dev/scripts/legacy/multi_agent_scheduler.ps1.bak +1978 -1978
  84. package/core/dev/scripts/matrix/src/cli/commands/list-tags.ts.wip +140 -140
  85. package/core/dev/scripts/matrix/src/cli/commands/manage-tags.ts.wip +173 -173
  86. package/core/dev/scripts/matrix/src/cli/commands/stats.ts.wip +168 -168
  87. package/core/dev/scripts/matrix/src/cli/commands/tokens.ts.wip +126 -126
  88. package/core/dev/scripts/multi_agent_scheduler.sh +0 -0
  89. package/core/dev/scripts/run_once.sh +0 -0
  90. package/core/dev/scripts/setup_mcp.sh +0 -0
  91. package/core/dev/scripts/setup_rag.sh +0 -0
  92. package/core/dev/scripts/start_dev_agent.sh +0 -0
  93. package/core/dev/scripts/start_multi_agent.sh +0 -0
  94. package/core/dev/scripts/sync_task_queue.sh +0 -0
  95. package/core/k-cli/dist/alaya/run.js +91 -0
  96. package/core/k-cli/dist/core/output.js +24 -0
  97. package/core/k-cli/dist/core/process.js +38 -0
  98. package/core/k-cli/dist/core/project.js +80 -0
  99. package/core/k-cli/dist/core/spawn.js +268 -0
  100. package/core/k-cli/dist/core/types.js +2 -0
  101. package/core/k-cli/dist/dashboard/update.js +53 -0
  102. package/core/k-cli/dist/dashboard/version.js +20 -0
  103. package/core/k-cli/dist/dispatch/run.js +241 -0
  104. package/core/k-cli/dist/dispatch/status.js +103 -0
  105. package/core/k-cli/dist/index.js +283 -0
  106. package/core/k-cli/dist/project/initialize.js +301 -0
  107. package/core/k-cli/dist/project/install.js +89 -0
  108. package/core/k-cli/dist/project/status.js +138 -0
  109. package/core/k-cli/dist/specialist/list.js +100 -0
  110. package/core/k-cli/dist/specialist/run.js +93 -0
  111. package/core/k-cli/dist/task/create.js +194 -0
  112. package/core/k-cli/dist/task/delete.js +98 -0
  113. package/core/k-cli/dist/task/get.js +55 -0
  114. package/core/k-cli/dist/task/list.js +58 -0
  115. package/core/k-cli/dist/task/submit.js +156 -0
  116. package/core/k-cli/dist/ygg/run.js +51 -0
  117. package/core/k-cli/node_modules/.bin/yaml +16 -0
  118. package/core/k-cli/node_modules/.bin/yaml.cmd +17 -0
  119. package/core/k-cli/node_modules/.bin/yaml.ps1 +28 -0
  120. package/core/k-cli/node_modules/.package-lock.json +23 -0
  121. package/core/k-cli/node_modules/yaml/LICENSE +13 -0
  122. package/core/k-cli/node_modules/yaml/README.md +172 -0
  123. package/core/k-cli/node_modules/yaml/bin.mjs +11 -0
  124. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
  125. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
  126. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
  127. package/core/k-cli/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
  128. package/core/k-cli/node_modules/yaml/browser/dist/compose/composer.js +217 -0
  129. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
  130. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
  131. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
  132. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
  133. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
  134. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +223 -0
  135. package/core/k-cli/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
  136. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
  137. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
  138. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
  139. package/core/k-cli/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
  140. package/core/k-cli/node_modules/yaml/browser/dist/doc/Document.js +335 -0
  141. package/core/k-cli/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
  142. package/core/k-cli/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
  143. package/core/k-cli/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
  144. package/core/k-cli/node_modules/yaml/browser/dist/doc/directives.js +176 -0
  145. package/core/k-cli/node_modules/yaml/browser/dist/errors.js +57 -0
  146. package/core/k-cli/node_modules/yaml/browser/dist/index.js +17 -0
  147. package/core/k-cli/node_modules/yaml/browser/dist/log.js +11 -0
  148. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Alias.js +114 -0
  149. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
  150. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
  151. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
  152. package/core/k-cli/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
  153. package/core/k-cli/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
  154. package/core/k-cli/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
  155. package/core/k-cli/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
  156. package/core/k-cli/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
  157. package/core/k-cli/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
  158. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
  159. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
  160. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
  161. package/core/k-cli/node_modules/yaml/browser/dist/parse/cst.js +98 -0
  162. package/core/k-cli/node_modules/yaml/browser/dist/parse/lexer.js +717 -0
  163. package/core/k-cli/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
  164. package/core/k-cli/node_modules/yaml/browser/dist/parse/parser.js +967 -0
  165. package/core/k-cli/node_modules/yaml/browser/dist/public-api.js +102 -0
  166. package/core/k-cli/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
  167. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
  168. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
  169. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
  170. package/core/k-cli/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
  171. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
  172. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
  173. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
  174. package/core/k-cli/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
  175. package/core/k-cli/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
  176. package/core/k-cli/node_modules/yaml/browser/dist/schema/tags.js +96 -0
  177. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
  178. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
  179. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
  180. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
  181. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +64 -0
  182. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
  183. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
  184. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
  185. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
  186. package/core/k-cli/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
  187. package/core/k-cli/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
  188. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
  189. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
  190. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
  191. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
  192. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +24 -0
  193. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
  194. package/core/k-cli/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
  195. package/core/k-cli/node_modules/yaml/browser/dist/util.js +11 -0
  196. package/core/k-cli/node_modules/yaml/browser/dist/visit.js +233 -0
  197. package/core/k-cli/node_modules/yaml/browser/index.js +5 -0
  198. package/core/k-cli/node_modules/yaml/browser/package.json +3 -0
  199. package/core/k-cli/node_modules/yaml/dist/cli.d.ts +8 -0
  200. package/core/k-cli/node_modules/yaml/dist/cli.mjs +201 -0
  201. package/core/k-cli/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
  202. package/core/k-cli/node_modules/yaml/dist/compose/compose-collection.js +90 -0
  203. package/core/k-cli/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
  204. package/core/k-cli/node_modules/yaml/dist/compose/compose-doc.js +45 -0
  205. package/core/k-cli/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
  206. package/core/k-cli/node_modules/yaml/dist/compose/compose-node.js +112 -0
  207. package/core/k-cli/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
  208. package/core/k-cli/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
  209. package/core/k-cli/node_modules/yaml/dist/compose/composer.d.ts +63 -0
  210. package/core/k-cli/node_modules/yaml/dist/compose/composer.js +222 -0
  211. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
  212. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
  213. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
  214. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
  215. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
  216. package/core/k-cli/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
  217. package/core/k-cli/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
  218. package/core/k-cli/node_modules/yaml/dist/compose/resolve-end.js +39 -0
  219. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
  220. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
  221. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
  222. package/core/k-cli/node_modules/yaml/dist/compose/resolve-flow-scalar.js +225 -0
  223. package/core/k-cli/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
  224. package/core/k-cli/node_modules/yaml/dist/compose/resolve-props.js +148 -0
  225. package/core/k-cli/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
  226. package/core/k-cli/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
  227. package/core/k-cli/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
  228. package/core/k-cli/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
  229. package/core/k-cli/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
  230. package/core/k-cli/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
  231. package/core/k-cli/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
  232. package/core/k-cli/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
  233. package/core/k-cli/node_modules/yaml/dist/doc/Document.d.ts +141 -0
  234. package/core/k-cli/node_modules/yaml/dist/doc/Document.js +337 -0
  235. package/core/k-cli/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
  236. package/core/k-cli/node_modules/yaml/dist/doc/anchors.js +76 -0
  237. package/core/k-cli/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
  238. package/core/k-cli/node_modules/yaml/dist/doc/applyReviver.js +57 -0
  239. package/core/k-cli/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
  240. package/core/k-cli/node_modules/yaml/dist/doc/createNode.js +90 -0
  241. package/core/k-cli/node_modules/yaml/dist/doc/directives.d.ts +49 -0
  242. package/core/k-cli/node_modules/yaml/dist/doc/directives.js +178 -0
  243. package/core/k-cli/node_modules/yaml/dist/errors.d.ts +21 -0
  244. package/core/k-cli/node_modules/yaml/dist/errors.js +62 -0
  245. package/core/k-cli/node_modules/yaml/dist/index.d.ts +25 -0
  246. package/core/k-cli/node_modules/yaml/dist/index.js +50 -0
  247. package/core/k-cli/node_modules/yaml/dist/log.d.ts +3 -0
  248. package/core/k-cli/node_modules/yaml/dist/log.js +19 -0
  249. package/core/k-cli/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
  250. package/core/k-cli/node_modules/yaml/dist/nodes/Alias.js +116 -0
  251. package/core/k-cli/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
  252. package/core/k-cli/node_modules/yaml/dist/nodes/Collection.js +151 -0
  253. package/core/k-cli/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
  254. package/core/k-cli/node_modules/yaml/dist/nodes/Node.js +40 -0
  255. package/core/k-cli/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
  256. package/core/k-cli/node_modules/yaml/dist/nodes/Pair.js +39 -0
  257. package/core/k-cli/node_modules/yaml/dist/nodes/Scalar.d.ts +43 -0
  258. package/core/k-cli/node_modules/yaml/dist/nodes/Scalar.js +27 -0
  259. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
  260. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
  261. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
  262. package/core/k-cli/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
  263. package/core/k-cli/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
  264. package/core/k-cli/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
  265. package/core/k-cli/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
  266. package/core/k-cli/node_modules/yaml/dist/nodes/identity.js +53 -0
  267. package/core/k-cli/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
  268. package/core/k-cli/node_modules/yaml/dist/nodes/toJS.js +39 -0
  269. package/core/k-cli/node_modules/yaml/dist/options.d.ts +350 -0
  270. package/core/k-cli/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
  271. package/core/k-cli/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
  272. package/core/k-cli/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
  273. package/core/k-cli/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
  274. package/core/k-cli/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
  275. package/core/k-cli/node_modules/yaml/dist/parse/cst-visit.js +99 -0
  276. package/core/k-cli/node_modules/yaml/dist/parse/cst.d.ts +109 -0
  277. package/core/k-cli/node_modules/yaml/dist/parse/cst.js +112 -0
  278. package/core/k-cli/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
  279. package/core/k-cli/node_modules/yaml/dist/parse/lexer.js +719 -0
  280. package/core/k-cli/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
  281. package/core/k-cli/node_modules/yaml/dist/parse/line-counter.js +41 -0
  282. package/core/k-cli/node_modules/yaml/dist/parse/parser.d.ts +84 -0
  283. package/core/k-cli/node_modules/yaml/dist/parse/parser.js +972 -0
  284. package/core/k-cli/node_modules/yaml/dist/public-api.d.ts +44 -0
  285. package/core/k-cli/node_modules/yaml/dist/public-api.js +107 -0
  286. package/core/k-cli/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
  287. package/core/k-cli/node_modules/yaml/dist/schema/Schema.js +39 -0
  288. package/core/k-cli/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
  289. package/core/k-cli/node_modules/yaml/dist/schema/common/map.js +19 -0
  290. package/core/k-cli/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
  291. package/core/k-cli/node_modules/yaml/dist/schema/common/null.js +17 -0
  292. package/core/k-cli/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
  293. package/core/k-cli/node_modules/yaml/dist/schema/common/seq.js +19 -0
  294. package/core/k-cli/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
  295. package/core/k-cli/node_modules/yaml/dist/schema/common/string.js +16 -0
  296. package/core/k-cli/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
  297. package/core/k-cli/node_modules/yaml/dist/schema/core/bool.js +21 -0
  298. package/core/k-cli/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
  299. package/core/k-cli/node_modules/yaml/dist/schema/core/float.js +47 -0
  300. package/core/k-cli/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
  301. package/core/k-cli/node_modules/yaml/dist/schema/core/int.js +42 -0
  302. package/core/k-cli/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
  303. package/core/k-cli/node_modules/yaml/dist/schema/core/schema.js +25 -0
  304. package/core/k-cli/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
  305. package/core/k-cli/node_modules/yaml/dist/schema/json/schema.js +64 -0
  306. package/core/k-cli/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
  307. package/core/k-cli/node_modules/yaml/dist/schema/tags.d.ts +48 -0
  308. package/core/k-cli/node_modules/yaml/dist/schema/tags.js +99 -0
  309. package/core/k-cli/node_modules/yaml/dist/schema/types.d.ts +92 -0
  310. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
  311. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
  312. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
  313. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
  314. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
  315. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
  316. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
  317. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
  318. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
  319. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/merge.js +68 -0
  320. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
  321. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
  322. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
  323. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
  324. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
  325. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
  326. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
  327. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
  328. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
  329. package/core/k-cli/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
  330. package/core/k-cli/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
  331. package/core/k-cli/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
  332. package/core/k-cli/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
  333. package/core/k-cli/node_modules/yaml/dist/stringify/stringify.js +132 -0
  334. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
  335. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
  336. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
  337. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
  338. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
  339. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
  340. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
  341. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyNumber.js +26 -0
  342. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
  343. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
  344. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
  345. package/core/k-cli/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
  346. package/core/k-cli/node_modules/yaml/dist/test-events.d.ts +4 -0
  347. package/core/k-cli/node_modules/yaml/dist/test-events.js +134 -0
  348. package/core/k-cli/node_modules/yaml/dist/util.d.ts +16 -0
  349. package/core/k-cli/node_modules/yaml/dist/util.js +28 -0
  350. package/core/k-cli/node_modules/yaml/dist/visit.d.ts +102 -0
  351. package/core/k-cli/node_modules/yaml/dist/visit.js +236 -0
  352. package/core/k-cli/node_modules/yaml/package.json +97 -0
  353. package/core/k-cli/node_modules/yaml/util.js +2 -0
  354. package/core/plugins/kenaz/commands/Ansuz.md +19 -30
  355. package/core/plugins/kenaz/hooks/hooks.json +1 -5
  356. package/core/plugins/kenaz/hooks/kenaz-hook.js +0 -4
  357. package/core/plugins/kenaz/scripts/kenaz.test.js +1 -1
  358. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/charts.csv +26 -26
  359. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/colors.csv +97 -97
  360. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/icons.csv +101 -101
  361. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/landing.csv +31 -31
  362. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/products.csv +96 -96
  363. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  364. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  365. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  366. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
  367. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  368. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
  369. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  370. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  371. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
  372. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
  373. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  374. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
  375. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  376. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  377. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/styles.csv +68 -68
  378. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/typography.csv +57 -57
  379. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
  380. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
  381. package/core/plugins/kenaz/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
  382. package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/core.py +253 -253
  383. package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
  384. package/core/plugins/kenaz/skills/ui-ux-pro-max/scripts/search.py +106 -106
  385. package/lib/cli.js +36 -2
  386. package/lib/cli.test.js +24 -0
  387. package/lib/dashboard.js +10 -0
  388. package/package.json +6 -6
  389. package/core/.specialist/tools/__tests__/task-1863-boot-lease-reuse.test.js +0 -99
  390. package/core/.specialist/tools/__tests__/task-1977-banner-cap.test.js +0 -129
@@ -1,140 +1,140 @@
1
- /**
2
- * list-tags command - List all tags and their usage counts
3
- */
4
-
5
- import chalk from 'chalk';
6
- import { resolveFilePath } from '../utils/file-handler';
7
- import { parseMatrixFile } from '../../parser';
8
- import { TagIndexer } from '../../indexer/tag-indexer';
9
-
10
- interface ListTagsOptions {
11
- type?: string; // Filter by tag type: source, category, priority, domain, custom
12
- sort?: 'name' | 'count'; // Sort by name or count
13
- }
14
-
15
- export async function listTagsCommand(
16
- file: string,
17
- options: ListTagsOptions = {}
18
- ): Promise<void> {
19
- const filePath = resolveFilePath(file);
20
-
21
- // Parse file
22
- const matrixFile = parseMatrixFile(filePath);
23
-
24
- // Build tag index
25
- const indexer = new TagIndexer();
26
- indexer.buildIndex(matrixFile);
27
-
28
- // Get tag statistics
29
- let tagStats = indexer.getTagStats();
30
-
31
- // Filter by type if specified
32
- if (options.type) {
33
- const typePrefix = options.type.toLowerCase();
34
- tagStats = tagStats.filter((stat) => {
35
- if (typePrefix === 'custom') {
36
- return stat.tag.startsWith('#');
37
- }
38
- return stat.tag.startsWith(`${typePrefix}:`);
39
- });
40
- }
41
-
42
- // Sort by name if specified
43
- if (options.sort === 'name') {
44
- tagStats.sort((a, b) => a.tag.localeCompare(b.tag));
45
- }
46
- // Default: already sorted by count descending
47
-
48
- console.log(chalk.bold.cyan('\n🏷️ Tags\n'));
49
- console.log(chalk.gray(`File: ${filePath}\n`));
50
-
51
- if (tagStats.length === 0) {
52
- console.log(chalk.yellow('No tags found.'));
53
- console.log();
54
- return;
55
- }
56
-
57
- // Group tags by type
58
- const groupedTags = groupTagsByType(tagStats);
59
-
60
- // Display each group
61
- for (const [type, tags] of Object.entries(groupedTags)) {
62
- if (!options.type || options.type.toLowerCase() === type.toLowerCase()) {
63
- console.log(chalk.bold(`${getTypeEmoji(type)} ${type}:`));
64
-
65
- for (const stat of tags) {
66
- const tagDisplay = stat.tag.replace(`${type.toLowerCase()}:`, '');
67
- const bar = '█'.repeat(Math.min(stat.count, 20));
68
- console.log(
69
- ` ${chalk.cyan(tagDisplay.padEnd(20))} ${chalk.green(bar)} ${chalk.yellow(stat.count)}`
70
- );
71
- }
72
-
73
- console.log();
74
- }
75
- }
76
-
77
- // Summary
78
- console.log(chalk.bold('Summary:'));
79
- console.log(` Total tags: ${chalk.cyan(tagStats.length)}`);
80
- console.log(` Total tag types: ${chalk.cyan(Object.keys(groupedTags).length)}`);
81
- console.log();
82
- }
83
-
84
- /**
85
- * Group tags by type
86
- */
87
- function groupTagsByType(
88
- tagStats: { tag: string; count: number; ruleIds: string[] }[]
89
- ): Record<string, typeof tagStats> {
90
- const grouped: Record<string, typeof tagStats> = {
91
- Source: [],
92
- Category: [],
93
- Priority: [],
94
- Domain: [],
95
- Custom: [],
96
- };
97
-
98
- for (const stat of tagStats) {
99
- if (stat.tag.startsWith('source:')) {
100
- grouped.Source.push(stat);
101
- } else if (stat.tag.startsWith('category:')) {
102
- grouped.Category.push(stat);
103
- } else if (stat.tag.startsWith('priority:')) {
104
- grouped.Priority.push(stat);
105
- } else if (stat.tag.startsWith('domain:')) {
106
- grouped.Domain.push(stat);
107
- } else {
108
- grouped.Custom.push(stat);
109
- }
110
- }
111
-
112
- // Remove empty groups
113
- for (const key of Object.keys(grouped)) {
114
- if (grouped[key].length === 0) {
115
- delete grouped[key];
116
- }
117
- }
118
-
119
- return grouped;
120
- }
121
-
122
- /**
123
- * Get emoji for tag type
124
- */
125
- function getTypeEmoji(type: string): string {
126
- switch (type.toLowerCase()) {
127
- case 'source':
128
- return '📦';
129
- case 'category':
130
- return '📂';
131
- case 'priority':
132
- return '⚡';
133
- case 'domain':
134
- return '🌐';
135
- case 'custom':
136
- return '🏷️';
137
- default:
138
- return '•';
139
- }
140
- }
1
+ /**
2
+ * list-tags command - List all tags and their usage counts
3
+ */
4
+
5
+ import chalk from 'chalk';
6
+ import { resolveFilePath } from '../utils/file-handler';
7
+ import { parseMatrixFile } from '../../parser';
8
+ import { TagIndexer } from '../../indexer/tag-indexer';
9
+
10
+ interface ListTagsOptions {
11
+ type?: string; // Filter by tag type: source, category, priority, domain, custom
12
+ sort?: 'name' | 'count'; // Sort by name or count
13
+ }
14
+
15
+ export async function listTagsCommand(
16
+ file: string,
17
+ options: ListTagsOptions = {}
18
+ ): Promise<void> {
19
+ const filePath = resolveFilePath(file);
20
+
21
+ // Parse file
22
+ const matrixFile = parseMatrixFile(filePath);
23
+
24
+ // Build tag index
25
+ const indexer = new TagIndexer();
26
+ indexer.buildIndex(matrixFile);
27
+
28
+ // Get tag statistics
29
+ let tagStats = indexer.getTagStats();
30
+
31
+ // Filter by type if specified
32
+ if (options.type) {
33
+ const typePrefix = options.type.toLowerCase();
34
+ tagStats = tagStats.filter((stat) => {
35
+ if (typePrefix === 'custom') {
36
+ return stat.tag.startsWith('#');
37
+ }
38
+ return stat.tag.startsWith(`${typePrefix}:`);
39
+ });
40
+ }
41
+
42
+ // Sort by name if specified
43
+ if (options.sort === 'name') {
44
+ tagStats.sort((a, b) => a.tag.localeCompare(b.tag));
45
+ }
46
+ // Default: already sorted by count descending
47
+
48
+ console.log(chalk.bold.cyan('\n🏷️ Tags\n'));
49
+ console.log(chalk.gray(`File: ${filePath}\n`));
50
+
51
+ if (tagStats.length === 0) {
52
+ console.log(chalk.yellow('No tags found.'));
53
+ console.log();
54
+ return;
55
+ }
56
+
57
+ // Group tags by type
58
+ const groupedTags = groupTagsByType(tagStats);
59
+
60
+ // Display each group
61
+ for (const [type, tags] of Object.entries(groupedTags)) {
62
+ if (!options.type || options.type.toLowerCase() === type.toLowerCase()) {
63
+ console.log(chalk.bold(`${getTypeEmoji(type)} ${type}:`));
64
+
65
+ for (const stat of tags) {
66
+ const tagDisplay = stat.tag.replace(`${type.toLowerCase()}:`, '');
67
+ const bar = '█'.repeat(Math.min(stat.count, 20));
68
+ console.log(
69
+ ` ${chalk.cyan(tagDisplay.padEnd(20))} ${chalk.green(bar)} ${chalk.yellow(stat.count)}`
70
+ );
71
+ }
72
+
73
+ console.log();
74
+ }
75
+ }
76
+
77
+ // Summary
78
+ console.log(chalk.bold('Summary:'));
79
+ console.log(` Total tags: ${chalk.cyan(tagStats.length)}`);
80
+ console.log(` Total tag types: ${chalk.cyan(Object.keys(groupedTags).length)}`);
81
+ console.log();
82
+ }
83
+
84
+ /**
85
+ * Group tags by type
86
+ */
87
+ function groupTagsByType(
88
+ tagStats: { tag: string; count: number; ruleIds: string[] }[]
89
+ ): Record<string, typeof tagStats> {
90
+ const grouped: Record<string, typeof tagStats> = {
91
+ Source: [],
92
+ Category: [],
93
+ Priority: [],
94
+ Domain: [],
95
+ Custom: [],
96
+ };
97
+
98
+ for (const stat of tagStats) {
99
+ if (stat.tag.startsWith('source:')) {
100
+ grouped.Source.push(stat);
101
+ } else if (stat.tag.startsWith('category:')) {
102
+ grouped.Category.push(stat);
103
+ } else if (stat.tag.startsWith('priority:')) {
104
+ grouped.Priority.push(stat);
105
+ } else if (stat.tag.startsWith('domain:')) {
106
+ grouped.Domain.push(stat);
107
+ } else {
108
+ grouped.Custom.push(stat);
109
+ }
110
+ }
111
+
112
+ // Remove empty groups
113
+ for (const key of Object.keys(grouped)) {
114
+ if (grouped[key].length === 0) {
115
+ delete grouped[key];
116
+ }
117
+ }
118
+
119
+ return grouped;
120
+ }
121
+
122
+ /**
123
+ * Get emoji for tag type
124
+ */
125
+ function getTypeEmoji(type: string): string {
126
+ switch (type.toLowerCase()) {
127
+ case 'source':
128
+ return '📦';
129
+ case 'category':
130
+ return '📂';
131
+ case 'priority':
132
+ return '⚡';
133
+ case 'domain':
134
+ return '🌐';
135
+ case 'custom':
136
+ return '🏷️';
137
+ default:
138
+ return '•';
139
+ }
140
+ }
@@ -1,173 +1,173 @@
1
- /**
2
- * add-tag / remove-tag commands - Manage rule tags
3
- */
4
-
5
- import chalk from 'chalk';
6
- import * as fs from 'fs';
7
- import { resolveFilePath } from '../utils/file-handler';
8
- import { parseMatrixFile } from '../../parser';
9
- import { serializeMatrixFile } from '../../serializer';
10
- import { TagIndexer, buildTagIndex } from '../../indexer/tag-indexer';
11
-
12
- interface ManageTagsOptions {
13
- force?: boolean;
14
- }
15
-
16
- /**
17
- * Add tag to a rule
18
- */
19
- export async function addTagCommand(
20
- file: string,
21
- ruleId: string,
22
- tag: string,
23
- options: ManageTagsOptions = {}
24
- ): Promise<void> {
25
- const filePath = resolveFilePath(file);
26
-
27
- // Parse file
28
- const matrixFile = parseMatrixFile(filePath);
29
-
30
- // Find rule
31
- const rule = matrixFile.rules.find((r) => r.id === ruleId);
32
- if (!rule) {
33
- throw new Error(`Rule not found: ${ruleId}`);
34
- }
35
-
36
- // Ensure tag starts with # (for custom tags)
37
- const normalizedTag = tag.startsWith('#') ? tag : `#${tag}`;
38
-
39
- // Initialize tags array if not exists
40
- if (!rule.tags) {
41
- rule.tags = [];
42
- }
43
-
44
- // Check if tag already exists
45
- if (Array.isArray(rule.tags) && rule.tags.includes(normalizedTag)) {
46
- console.log(chalk.yellow(`Tag already exists: ${normalizedTag}`));
47
- return;
48
- }
49
-
50
- // Add tag
51
- if (Array.isArray(rule.tags)) {
52
- rule.tags.push(normalizedTag);
53
- } else {
54
- rule.tags = [normalizedTag];
55
- }
56
-
57
- // Save file
58
- const serialized = serializeMatrixFile(matrixFile);
59
- fs.writeFileSync(filePath, serialized, 'utf-8');
60
-
61
- // Rebuild tag index
62
- const indexPath = filePath.replace('.matrix', '.tags.json');
63
- buildTagIndex(matrixFile, indexPath);
64
-
65
- console.log(chalk.green(`✓ Tag added: ${normalizedTag} to ${ruleId}`));
66
- console.log(chalk.gray(` Index updated: ${indexPath}`));
67
- }
68
-
69
- /**
70
- * Remove tag from a rule
71
- */
72
- export async function removeTagCommand(
73
- file: string,
74
- ruleId: string,
75
- tag: string,
76
- options: ManageTagsOptions = {}
77
- ): Promise<void> {
78
- const filePath = resolveFilePath(file);
79
-
80
- // Parse file
81
- const matrixFile = parseMatrixFile(filePath);
82
-
83
- // Find rule
84
- const rule = matrixFile.rules.find((r) => r.id === ruleId);
85
- if (!rule) {
86
- throw new Error(`Rule not found: ${ruleId}`);
87
- }
88
-
89
- // Ensure tag starts with # (for custom tags)
90
- const normalizedTag = tag.startsWith('#') ? tag : `#${tag}`;
91
-
92
- // Check if rule has tags
93
- if (!rule.tags || !Array.isArray(rule.tags)) {
94
- console.log(chalk.yellow(`Rule has no tags: ${ruleId}`));
95
- return;
96
- }
97
-
98
- // Find tag index
99
- const tagIndex = rule.tags.indexOf(normalizedTag);
100
- if (tagIndex === -1) {
101
- console.log(chalk.yellow(`Tag not found: ${normalizedTag}`));
102
- return;
103
- }
104
-
105
- // Remove tag
106
- rule.tags.splice(tagIndex, 1);
107
-
108
- // Save file
109
- const serialized = serializeMatrixFile(matrixFile);
110
- fs.writeFileSync(filePath, serialized, 'utf-8');
111
-
112
- // Rebuild tag index
113
- const indexPath = filePath.replace('.matrix', '.tags.json');
114
- buildTagIndex(matrixFile, indexPath);
115
-
116
- console.log(chalk.green(`✓ Tag removed: ${normalizedTag} from ${ruleId}`));
117
- console.log(chalk.gray(` Index updated: ${indexPath}`));
118
- }
119
-
120
- /**
121
- * List tags for a specific rule
122
- */
123
- export async function showRuleTagsCommand(
124
- file: string,
125
- ruleId: string
126
- ): Promise<void> {
127
- const filePath = resolveFilePath(file);
128
-
129
- // Parse file
130
- const matrixFile = parseMatrixFile(filePath);
131
-
132
- // Find rule
133
- const rule = matrixFile.rules.find((r) => r.id === ruleId);
134
- if (!rule) {
135
- throw new Error(`Rule not found: ${ruleId}`);
136
- }
137
-
138
- console.log(chalk.bold.cyan(`\n🏷️ Tags for ${ruleId}\n`));
139
-
140
- // Collect all tags
141
- const allTags: string[] = [];
142
-
143
- if (rule.source) allTags.push(`source:${rule.source}`);
144
- if (rule.category) allTags.push(`category:${rule.category}`);
145
- if (rule.priority) allTags.push(`priority:${rule.priority}`);
146
- if (rule.domain) allTags.push(`domain:${rule.domain}`);
147
- if (rule.tags && Array.isArray(rule.tags)) {
148
- allTags.push(...rule.tags);
149
- }
150
-
151
- if (allTags.length === 0) {
152
- console.log(chalk.yellow('No tags found.'));
153
- } else {
154
- for (const tag of allTags) {
155
- const emoji = getTagEmoji(tag);
156
- console.log(` ${emoji} ${chalk.cyan(tag)}`);
157
- }
158
- }
159
-
160
- console.log();
161
- }
162
-
163
- /**
164
- * Get emoji for tag
165
- */
166
- function getTagEmoji(tag: string): string {
167
- if (tag.startsWith('source:')) return '📦';
168
- if (tag.startsWith('category:')) return '📂';
169
- if (tag.startsWith('priority:')) return '⚡';
170
- if (tag.startsWith('domain:')) return '🌐';
171
- if (tag.startsWith('#')) return '🏷️';
172
- return '•';
173
- }
1
+ /**
2
+ * add-tag / remove-tag commands - Manage rule tags
3
+ */
4
+
5
+ import chalk from 'chalk';
6
+ import * as fs from 'fs';
7
+ import { resolveFilePath } from '../utils/file-handler';
8
+ import { parseMatrixFile } from '../../parser';
9
+ import { serializeMatrixFile } from '../../serializer';
10
+ import { TagIndexer, buildTagIndex } from '../../indexer/tag-indexer';
11
+
12
+ interface ManageTagsOptions {
13
+ force?: boolean;
14
+ }
15
+
16
+ /**
17
+ * Add tag to a rule
18
+ */
19
+ export async function addTagCommand(
20
+ file: string,
21
+ ruleId: string,
22
+ tag: string,
23
+ options: ManageTagsOptions = {}
24
+ ): Promise<void> {
25
+ const filePath = resolveFilePath(file);
26
+
27
+ // Parse file
28
+ const matrixFile = parseMatrixFile(filePath);
29
+
30
+ // Find rule
31
+ const rule = matrixFile.rules.find((r) => r.id === ruleId);
32
+ if (!rule) {
33
+ throw new Error(`Rule not found: ${ruleId}`);
34
+ }
35
+
36
+ // Ensure tag starts with # (for custom tags)
37
+ const normalizedTag = tag.startsWith('#') ? tag : `#${tag}`;
38
+
39
+ // Initialize tags array if not exists
40
+ if (!rule.tags) {
41
+ rule.tags = [];
42
+ }
43
+
44
+ // Check if tag already exists
45
+ if (Array.isArray(rule.tags) && rule.tags.includes(normalizedTag)) {
46
+ console.log(chalk.yellow(`Tag already exists: ${normalizedTag}`));
47
+ return;
48
+ }
49
+
50
+ // Add tag
51
+ if (Array.isArray(rule.tags)) {
52
+ rule.tags.push(normalizedTag);
53
+ } else {
54
+ rule.tags = [normalizedTag];
55
+ }
56
+
57
+ // Save file
58
+ const serialized = serializeMatrixFile(matrixFile);
59
+ fs.writeFileSync(filePath, serialized, 'utf-8');
60
+
61
+ // Rebuild tag index
62
+ const indexPath = filePath.replace('.matrix', '.tags.json');
63
+ buildTagIndex(matrixFile, indexPath);
64
+
65
+ console.log(chalk.green(`✓ Tag added: ${normalizedTag} to ${ruleId}`));
66
+ console.log(chalk.gray(` Index updated: ${indexPath}`));
67
+ }
68
+
69
+ /**
70
+ * Remove tag from a rule
71
+ */
72
+ export async function removeTagCommand(
73
+ file: string,
74
+ ruleId: string,
75
+ tag: string,
76
+ options: ManageTagsOptions = {}
77
+ ): Promise<void> {
78
+ const filePath = resolveFilePath(file);
79
+
80
+ // Parse file
81
+ const matrixFile = parseMatrixFile(filePath);
82
+
83
+ // Find rule
84
+ const rule = matrixFile.rules.find((r) => r.id === ruleId);
85
+ if (!rule) {
86
+ throw new Error(`Rule not found: ${ruleId}`);
87
+ }
88
+
89
+ // Ensure tag starts with # (for custom tags)
90
+ const normalizedTag = tag.startsWith('#') ? tag : `#${tag}`;
91
+
92
+ // Check if rule has tags
93
+ if (!rule.tags || !Array.isArray(rule.tags)) {
94
+ console.log(chalk.yellow(`Rule has no tags: ${ruleId}`));
95
+ return;
96
+ }
97
+
98
+ // Find tag index
99
+ const tagIndex = rule.tags.indexOf(normalizedTag);
100
+ if (tagIndex === -1) {
101
+ console.log(chalk.yellow(`Tag not found: ${normalizedTag}`));
102
+ return;
103
+ }
104
+
105
+ // Remove tag
106
+ rule.tags.splice(tagIndex, 1);
107
+
108
+ // Save file
109
+ const serialized = serializeMatrixFile(matrixFile);
110
+ fs.writeFileSync(filePath, serialized, 'utf-8');
111
+
112
+ // Rebuild tag index
113
+ const indexPath = filePath.replace('.matrix', '.tags.json');
114
+ buildTagIndex(matrixFile, indexPath);
115
+
116
+ console.log(chalk.green(`✓ Tag removed: ${normalizedTag} from ${ruleId}`));
117
+ console.log(chalk.gray(` Index updated: ${indexPath}`));
118
+ }
119
+
120
+ /**
121
+ * List tags for a specific rule
122
+ */
123
+ export async function showRuleTagsCommand(
124
+ file: string,
125
+ ruleId: string
126
+ ): Promise<void> {
127
+ const filePath = resolveFilePath(file);
128
+
129
+ // Parse file
130
+ const matrixFile = parseMatrixFile(filePath);
131
+
132
+ // Find rule
133
+ const rule = matrixFile.rules.find((r) => r.id === ruleId);
134
+ if (!rule) {
135
+ throw new Error(`Rule not found: ${ruleId}`);
136
+ }
137
+
138
+ console.log(chalk.bold.cyan(`\n🏷️ Tags for ${ruleId}\n`));
139
+
140
+ // Collect all tags
141
+ const allTags: string[] = [];
142
+
143
+ if (rule.source) allTags.push(`source:${rule.source}`);
144
+ if (rule.category) allTags.push(`category:${rule.category}`);
145
+ if (rule.priority) allTags.push(`priority:${rule.priority}`);
146
+ if (rule.domain) allTags.push(`domain:${rule.domain}`);
147
+ if (rule.tags && Array.isArray(rule.tags)) {
148
+ allTags.push(...rule.tags);
149
+ }
150
+
151
+ if (allTags.length === 0) {
152
+ console.log(chalk.yellow('No tags found.'));
153
+ } else {
154
+ for (const tag of allTags) {
155
+ const emoji = getTagEmoji(tag);
156
+ console.log(` ${emoji} ${chalk.cyan(tag)}`);
157
+ }
158
+ }
159
+
160
+ console.log();
161
+ }
162
+
163
+ /**
164
+ * Get emoji for tag
165
+ */
166
+ function getTagEmoji(tag: string): string {
167
+ if (tag.startsWith('source:')) return '📦';
168
+ if (tag.startsWith('category:')) return '📂';
169
+ if (tag.startsWith('priority:')) return '⚡';
170
+ if (tag.startsWith('domain:')) return '🌐';
171
+ if (tag.startsWith('#')) return '🏷️';
172
+ return '•';
173
+ }