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,106 +1,106 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- UI/UX Pro Max Search - BM25 search engine for UI/UX style guides
5
- Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-results 3]
6
- python search.py "<query>" --design-system [-p "Project Name"]
7
- python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]
8
-
9
- Domains: style, prompt, color, chart, landing, product, ux, typography
10
- Stacks: html-tailwind, react, nextjs
11
-
12
- Persistence (Master + Overrides pattern):
13
- --persist Save design system to design-system/MASTER.md
14
- --page Also create a page-specific override file in design-system/pages/
15
- """
16
-
17
- import argparse
18
- from core import CSV_CONFIG, AVAILABLE_STACKS, MAX_RESULTS, search, search_stack
19
- from design_system import generate_design_system, persist_design_system
20
-
21
-
22
- def format_output(result):
23
- """Format results for Claude consumption (token-optimized)"""
24
- if "error" in result:
25
- return f"Error: {result['error']}"
26
-
27
- output = []
28
- if result.get("stack"):
29
- output.append(f"## UI Pro Max Stack Guidelines")
30
- output.append(f"**Stack:** {result['stack']} | **Query:** {result['query']}")
31
- else:
32
- output.append(f"## UI Pro Max Search Results")
33
- output.append(f"**Domain:** {result['domain']} | **Query:** {result['query']}")
34
- output.append(f"**Source:** {result['file']} | **Found:** {result['count']} results\n")
35
-
36
- for i, row in enumerate(result['results'], 1):
37
- output.append(f"### Result {i}")
38
- for key, value in row.items():
39
- value_str = str(value)
40
- if len(value_str) > 300:
41
- value_str = value_str[:300] + "..."
42
- output.append(f"- **{key}:** {value_str}")
43
- output.append("")
44
-
45
- return "\n".join(output)
46
-
47
-
48
- if __name__ == "__main__":
49
- parser = argparse.ArgumentParser(description="UI Pro Max Search")
50
- parser.add_argument("query", help="Search query")
51
- parser.add_argument("--domain", "-d", choices=list(CSV_CONFIG.keys()), help="Search domain")
52
- parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs)")
53
- parser.add_argument("--max-results", "-n", type=int, default=MAX_RESULTS, help="Max results (default: 3)")
54
- parser.add_argument("--json", action="store_true", help="Output as JSON")
55
- # Design system generation
56
- parser.add_argument("--design-system", "-ds", action="store_true", help="Generate complete design system recommendation")
57
- parser.add_argument("--project-name", "-p", type=str, default=None, help="Project name for design system output")
58
- parser.add_argument("--format", "-f", choices=["ascii", "markdown"], default="ascii", help="Output format for design system")
59
- # Persistence (Master + Overrides pattern)
60
- parser.add_argument("--persist", action="store_true", help="Save design system to design-system/MASTER.md (creates hierarchical structure)")
61
- parser.add_argument("--page", type=str, default=None, help="Create page-specific override file in design-system/pages/")
62
- parser.add_argument("--output-dir", "-o", type=str, default=None, help="Output directory for persisted files (default: current directory)")
63
-
64
- args = parser.parse_args()
65
-
66
- # Design system takes priority
67
- if args.design_system:
68
- result = generate_design_system(
69
- args.query,
70
- args.project_name,
71
- args.format,
72
- persist=args.persist,
73
- page=args.page,
74
- output_dir=args.output_dir
75
- )
76
- print(result)
77
-
78
- # Print persistence confirmation
79
- if args.persist:
80
- project_slug = args.project_name.lower().replace(' ', '-') if args.project_name else "default"
81
- print("\n" + "=" * 60)
82
- print(f"✅ Design system persisted to design-system/{project_slug}/")
83
- print(f" 📄 design-system/{project_slug}/MASTER.md (Global Source of Truth)")
84
- if args.page:
85
- page_filename = args.page.lower().replace(' ', '-')
86
- print(f" 📄 design-system/{project_slug}/pages/{page_filename}.md (Page Overrides)")
87
- print("")
88
- print(f"📖 Usage: When building a page, check design-system/{project_slug}/pages/[page].md first.")
89
- print(f" If exists, its rules override MASTER.md. Otherwise, use MASTER.md.")
90
- print("=" * 60)
91
- # Stack search
92
- elif args.stack:
93
- result = search_stack(args.query, args.stack, args.max_results)
94
- if args.json:
95
- import json
96
- print(json.dumps(result, indent=2, ensure_ascii=False))
97
- else:
98
- print(format_output(result))
99
- # Domain search
100
- else:
101
- result = search(args.query, args.domain, args.max_results)
102
- if args.json:
103
- import json
104
- print(json.dumps(result, indent=2, ensure_ascii=False))
105
- else:
106
- print(format_output(result))
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ UI/UX Pro Max Search - BM25 search engine for UI/UX style guides
5
+ Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-results 3]
6
+ python search.py "<query>" --design-system [-p "Project Name"]
7
+ python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]
8
+
9
+ Domains: style, prompt, color, chart, landing, product, ux, typography
10
+ Stacks: html-tailwind, react, nextjs
11
+
12
+ Persistence (Master + Overrides pattern):
13
+ --persist Save design system to design-system/MASTER.md
14
+ --page Also create a page-specific override file in design-system/pages/
15
+ """
16
+
17
+ import argparse
18
+ from core import CSV_CONFIG, AVAILABLE_STACKS, MAX_RESULTS, search, search_stack
19
+ from design_system import generate_design_system, persist_design_system
20
+
21
+
22
+ def format_output(result):
23
+ """Format results for Claude consumption (token-optimized)"""
24
+ if "error" in result:
25
+ return f"Error: {result['error']}"
26
+
27
+ output = []
28
+ if result.get("stack"):
29
+ output.append(f"## UI Pro Max Stack Guidelines")
30
+ output.append(f"**Stack:** {result['stack']} | **Query:** {result['query']}")
31
+ else:
32
+ output.append(f"## UI Pro Max Search Results")
33
+ output.append(f"**Domain:** {result['domain']} | **Query:** {result['query']}")
34
+ output.append(f"**Source:** {result['file']} | **Found:** {result['count']} results\n")
35
+
36
+ for i, row in enumerate(result['results'], 1):
37
+ output.append(f"### Result {i}")
38
+ for key, value in row.items():
39
+ value_str = str(value)
40
+ if len(value_str) > 300:
41
+ value_str = value_str[:300] + "..."
42
+ output.append(f"- **{key}:** {value_str}")
43
+ output.append("")
44
+
45
+ return "\n".join(output)
46
+
47
+
48
+ if __name__ == "__main__":
49
+ parser = argparse.ArgumentParser(description="UI Pro Max Search")
50
+ parser.add_argument("query", help="Search query")
51
+ parser.add_argument("--domain", "-d", choices=list(CSV_CONFIG.keys()), help="Search domain")
52
+ parser.add_argument("--stack", "-s", choices=AVAILABLE_STACKS, help="Stack-specific search (html-tailwind, react, nextjs)")
53
+ parser.add_argument("--max-results", "-n", type=int, default=MAX_RESULTS, help="Max results (default: 3)")
54
+ parser.add_argument("--json", action="store_true", help="Output as JSON")
55
+ # Design system generation
56
+ parser.add_argument("--design-system", "-ds", action="store_true", help="Generate complete design system recommendation")
57
+ parser.add_argument("--project-name", "-p", type=str, default=None, help="Project name for design system output")
58
+ parser.add_argument("--format", "-f", choices=["ascii", "markdown"], default="ascii", help="Output format for design system")
59
+ # Persistence (Master + Overrides pattern)
60
+ parser.add_argument("--persist", action="store_true", help="Save design system to design-system/MASTER.md (creates hierarchical structure)")
61
+ parser.add_argument("--page", type=str, default=None, help="Create page-specific override file in design-system/pages/")
62
+ parser.add_argument("--output-dir", "-o", type=str, default=None, help="Output directory for persisted files (default: current directory)")
63
+
64
+ args = parser.parse_args()
65
+
66
+ # Design system takes priority
67
+ if args.design_system:
68
+ result = generate_design_system(
69
+ args.query,
70
+ args.project_name,
71
+ args.format,
72
+ persist=args.persist,
73
+ page=args.page,
74
+ output_dir=args.output_dir
75
+ )
76
+ print(result)
77
+
78
+ # Print persistence confirmation
79
+ if args.persist:
80
+ project_slug = args.project_name.lower().replace(' ', '-') if args.project_name else "default"
81
+ print("\n" + "=" * 60)
82
+ print(f"✅ Design system persisted to design-system/{project_slug}/")
83
+ print(f" 📄 design-system/{project_slug}/MASTER.md (Global Source of Truth)")
84
+ if args.page:
85
+ page_filename = args.page.lower().replace(' ', '-')
86
+ print(f" 📄 design-system/{project_slug}/pages/{page_filename}.md (Page Overrides)")
87
+ print("")
88
+ print(f"📖 Usage: When building a page, check design-system/{project_slug}/pages/[page].md first.")
89
+ print(f" If exists, its rules override MASTER.md. Otherwise, use MASTER.md.")
90
+ print("=" * 60)
91
+ # Stack search
92
+ elif args.stack:
93
+ result = search_stack(args.query, args.stack, args.max_results)
94
+ if args.json:
95
+ import json
96
+ print(json.dumps(result, indent=2, ensure_ascii=False))
97
+ else:
98
+ print(format_output(result))
99
+ # Domain search
100
+ else:
101
+ result = search(args.query, args.domain, args.max_results)
102
+ if args.json:
103
+ import json
104
+ print(json.dumps(result, indent=2, ensure_ascii=False))
105
+ else:
106
+ print(format_output(result))
package/lib/cli.js CHANGED
@@ -76,6 +76,29 @@ function prepareCodexHome(p, flags) {
76
76
 
77
77
  function nodeOk() { return Number(process.versions.node.split('.')[0]) >= MIN_NODE; }
78
78
 
79
+ const samePath = (a, b) => {
80
+ const n = (x) => path.resolve(String(x || '')).replace(/\\/g, '/');
81
+ return process.platform === 'win32' ? n(a).toLowerCase() === n(b).toLowerCase() : n(a) === n(b);
82
+ };
83
+
84
+ /** Stop the kenaz-server running from exactly binPath (never by name). Returns the PIDs stopped. */
85
+ function stopOwnServer(binPath, adapter) {
86
+ if (!binPath || !adapter || typeof adapter.procs !== 'function') return [];
87
+ const pids = adapter.procs().filter((pr) => pr.exe && samePath(pr.exe, binPath)).map((pr) => pr.pid);
88
+ for (const pid of pids) { try { (adapter.kill || process.kill)(pid); } catch (_) { /* already gone */ } }
89
+ return pids;
90
+ }
91
+
92
+ /** Windows keeps an exe locked for a moment after its process exits: retry the copy briefly. */
93
+ function retryBusy(fn, tries = 10) {
94
+ for (let i = 1; ; i++) {
95
+ try { return fn(); } catch (e) {
96
+ if (i >= tries || !['EBUSY', 'EPERM', 'EPIPE', 'EACCES', 'ETXTBSY'].includes(e.code)) throw e;
97
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 500);
98
+ }
99
+ }
100
+ }
101
+
79
102
  function install(p, flags, out, deps = {}) {
80
103
  const dry = !!flags['dry-run'];
81
104
  const tag = dry ? '[dry-run] ' : '';
@@ -96,11 +119,22 @@ function install(p, flags, out, deps = {}) {
96
119
  else { out(`server: no @kenazai/server-${process.platform}-${process.arch} package installed (npm install it, or pass --server-bin)`); rc = 1; }
97
120
  }
98
121
  if (!dry) {
122
+ if (srv) {
123
+ // Reinstall/upgrade: the kenaz-server this install manages may be running from p.bin. Windows
124
+ // locks a running exe (field report: "EPIPE ... being used by another process" on
125
+ // `npx kenaz@latest install`) and Linux refuses to overwrite one (ETXTBSY). Stop exactly that
126
+ // binary (exe path match, by PID); the service step below starts the new one.
127
+ const stopped = stopOwnServer(binPath, deps.dashboard || dash.realAdapter(p.home));
128
+ if (stopped.length) log(`server: stopped the running kenaz-server (PID ${stopped.join(', ')}) to replace it`);
129
+ }
99
130
  fs.rmSync(p.core, { recursive: true, force: true });
100
131
  fs.cpSync(srcCore, p.core, { recursive: true });
101
132
  if (srv) {
102
133
  fs.mkdirSync(p.bin, { recursive: true });
103
- fs.cpSync(srv.dir, p.bin, { recursive: true });
134
+ // Unix: unlink first. A running binary can be unlinked (its process keeps the old inode) but not
135
+ // overwritten (ETXTBSY), so this works even when the running server was not found above.
136
+ if (process.platform !== 'win32') fs.rmSync(binPath, { force: true });
137
+ retryBusy(() => fs.cpSync(srv.dir, p.bin, { recursive: true }));
104
138
  fs.chmodSync(binPath, 0o755);
105
139
  }
106
140
  fs.writeFileSync(p.meta, JSON.stringify({ version: PKG.version, server: srv ? srv.version : null, serverBin: binPath, installedAt: new Date().toISOString() }, null, 2));
@@ -248,4 +282,4 @@ function run(argv, out = console.log, deps = {}) {
248
282
  catch (e) { out('kenaz ' + cmd + ': ERROR ' + e.message); return 1; }
249
283
  }
250
284
 
251
- module.exports = { run, parseArgs, platformServer, paths };
285
+ module.exports = { run, parseArgs, platformServer, paths, stopOwnServer, retryBusy };
package/lib/cli.test.js CHANGED
@@ -57,3 +57,27 @@ test('kenaz ygg / init pass through to the core scripts with the remaining args'
57
57
  assert.match(calls[1][0].split(path.sep).join('/'), /plugins\/kenaz\/scripts\/kenaz-mode\.js$/);
58
58
  assert.deepStrictEqual(calls[1].slice(1), ['init']);
59
59
  });
60
+
61
+ test('reinstall stops only the kenaz-server running from the managed path (exact exe match, by PID)', () => {
62
+ const { stopOwnServer } = require('./cli');
63
+ const killed = [];
64
+ const bin = path.join(os.tmpdir(), 'kh', '.kenaz', 'bin', process.platform === 'win32' ? 'kenaz-server.exe' : 'kenaz-server');
65
+ const adapter = {
66
+ procs: () => [
67
+ { pid: 11, exe: bin },
68
+ { pid: 12, exe: path.join(os.tmpdir(), 'other', 'kenaz-server.exe') }, // same name, different path: untouched
69
+ { pid: 13, exe: '' },
70
+ ],
71
+ kill: (pid) => killed.push(pid),
72
+ };
73
+ assert.deepStrictEqual(stopOwnServer(bin, adapter), [11]);
74
+ assert.deepStrictEqual(killed, [11]);
75
+ });
76
+
77
+ test('retryBusy retries a locked copy and then succeeds; other errors are thrown at once', () => {
78
+ const { retryBusy } = require('./cli');
79
+ let n = 0;
80
+ assert.strictEqual(retryBusy(() => { if (++n < 3) { const e = new Error('busy'); e.code = 'EBUSY'; throw e; } return 'ok'; }, 5), 'ok');
81
+ assert.strictEqual(n, 3);
82
+ assert.throws(() => retryBusy(() => { const e = new Error('nope'); e.code = 'ENOENT'; throw e; }, 5), /nope/);
83
+ });
package/lib/dashboard.js CHANGED
@@ -29,6 +29,16 @@ function realAdapter(home) {
29
29
  if (r.status !== 0) return [];
30
30
  try { const v = JSON.parse(r.stdout); return (Array.isArray(v) ? v : [v]).map((x) => ({ pid: x.ProcessId, name: x.Name || '', exe: x.ExecutablePath || '' })); } catch (_) { return []; }
31
31
  }
32
+ if (process.platform === 'linux') {
33
+ // /proc is always there; `ps` is not (node:22-slim has no procps, so a reinstall could not
34
+ // find the running kenaz-server and failed with ETXTBSY).
35
+ const out = [];
36
+ for (const d of fs.readdirSync('/proc')) {
37
+ if (!/^\d+$/.test(d)) continue;
38
+ try { const exe = fs.readlinkSync('/proc/' + d + '/exe'); out.push({ pid: Number(d), name: path.basename(exe), exe }); } catch (_) { /* gone or not ours */ }
39
+ }
40
+ return out;
41
+ }
32
42
  const r = sh('ps', ['-eo', 'pid=,args=']);
33
43
  return String(r.stdout || '').split('\n').map((l) => /^\s*(\d+)\s+(.+)$/.exec(l)).filter(Boolean)
34
44
  .map((m) => ({ pid: Number(m[1]), name: path.basename(m[2].split(' ')[0]), exe: m[2].split(' ')[0] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kenaz",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Install Kenaz (plugin, hooks, kenaz-server) for Claude Code and Codex: npx kenaz install",
5
5
  "bin": {
6
6
  "kenaz": "bin/kenaz.js"
@@ -20,11 +20,11 @@
20
20
  "test": "node --test lib/cli.test.js"
21
21
  },
22
22
  "optionalDependencies": {
23
- "@kenazai/server-darwin-arm64": "0.3.2",
24
- "@kenazai/server-darwin-x64": "0.3.2",
25
- "@kenazai/server-linux-arm64": "0.3.2",
26
- "@kenazai/server-linux-x64": "0.3.2",
27
- "@kenazai/server-win32-x64": "0.3.2"
23
+ "@kenazai/server-win32-x64": "0.3.3",
24
+ "@kenazai/server-darwin-arm64": "0.3.3",
25
+ "@kenazai/server-darwin-x64": "0.3.3",
26
+ "@kenazai/server-linux-x64": "0.3.3",
27
+ "@kenazai/server-linux-arm64": "0.3.3"
28
28
  },
29
29
  "license": "UNLICENSED"
30
30
  }
@@ -1,99 +0,0 @@
1
- // TASK_1863 — boot ghost-lease fix: re-running ansuz-boot-fast.js within the SAME
2
- // conversation must reuse the existing stream lease (via stream-lease register's
3
- // findLeaseByConversationId reuse path), not mint a new boot-<ts>-<pid> ghost.
4
- // Isolated sandbox via CLAUDE_PROJECT_DIR (stream-lease resolveBase honors it);
5
- // never touches the real repo's leases.
6
- //
7
- // Arms:
8
- // 1 (AC#2): 3 consecutive boots, same conversation id -> readAllLeases must hold
9
- // exactly ONE lease for that conversation; boots 2/3 must not print a
10
- // [Multi-Ansuz] banner (no self-ghost).
11
- // 2 (control): a boot under a DIFFERENT conversation id still creates its own
12
- // new lease (reuse is conversation-scoped, not a global singleton).
13
- //
14
- // Usage: node .specialist/tools/__tests__/task-1863-boot-lease-reuse.test.js
15
- // Exit 0=all pass, non-zero=at least one failure.
16
-
17
- const { spawnSync } = require('child_process');
18
- const fs = require('fs');
19
- const path = require('path');
20
- const os = require('os');
21
-
22
- function resolveRoot() {
23
- var d = path.resolve(__dirname);
24
- for (var i = 0; i < 10; i++) {
25
- if (fs.existsSync(path.join(d, '.kenaz')) && fs.existsSync(path.join(d, '.specialist'))) return d;
26
- var parent = path.dirname(d); if (parent === d) break; d = parent;
27
- }
28
- if (process.env.CLAUDE_PROJECT_DIR) return process.env.CLAUDE_PROJECT_DIR;
29
- throw new Error('Cannot resolve repo root from ' + __dirname);
30
- }
31
- const WT = resolveRoot();
32
- const SB = path.join(os.tmpdir(), 't1863_boot_' + process.pid);
33
- const BOOT = path.join(WT, '.specialist/tools/ansuz-boot-fast.js');
34
- const STREAM_LEASE = path.join(WT, '.specialist/tools/stream-lease.js');
35
- const CONV1 = 'conv-t1863-boot';
36
- const CONV2 = 'conv-t1863-other';
37
-
38
- for (const d of [
39
- '.kenaz/tasks/backlog', '.kenaz/tasks/active', '.kenaz/tasks/done',
40
- '.kenaz/tasks/blocked', '.kenaz/tasks/cancel',
41
- '.kenaz/specialist/sessions/leases',
42
- ]) fs.mkdirSync(path.join(SB, d), { recursive: true });
43
-
44
- const env = { ...process.env, CLAUDE_PROJECT_DIR: SB };
45
-
46
- const boot = (convId) => spawnSync(process.execPath, [
47
- BOOT,
48
- '--project-path=' + SB,
49
- '--conversation-id=' + convId,
50
- '--mcp-base-url=http://127.0.0.1:1', // dead port: preamble arm fails instantly, offline-safe
51
- ], { encoding: 'utf8', env, windowsHide: true, cwd: SB, timeout: 30000 });
52
-
53
- // Count via the exported readAllLeases (card: do NOT re-implement lease scanning).
54
- // Child process so resolveBase picks up CLAUDE_PROJECT_DIR=SB at module load.
55
- const readLeases = () => {
56
- const r = spawnSync(process.execPath, ['-e',
57
- 'const sl=require(' + JSON.stringify(STREAM_LEASE) + ');process.stdout.write(JSON.stringify(sl.readAllLeases()));',
58
- ], { encoding: 'utf8', env, windowsHide: true });
59
- return JSON.parse(r.stdout || '[]');
60
- };
61
-
62
- let pass = 0, fail = 0;
63
- const check = (name, cond, detail) => {
64
- console.log((cond ? 'PASS' : 'FAIL') + ' | ' + name + (cond ? '' : ' | ' + detail));
65
- cond ? pass++ : fail++;
66
- };
67
-
68
- // ── Arm 1: 3 boots, same conversation ──
69
- const outs = [];
70
- for (let i = 0; i < 3; i++) {
71
- const r = boot(CONV1);
72
- outs.push((r.stdout || '') + (r.stderr || ''));
73
- check('boot#' + (i + 1) + ' runs (banner printed)', (r.stdout || '').includes('Ansuz'),
74
- 'status=' + r.status + ' | ' + ((r.stdout || '') + (r.stderr || '')).slice(0, 300));
75
- }
76
- const all = readLeases();
77
- const mine = all.filter((l) => l.conversation_id === CONV1);
78
- check('AC#2: exactly ONE lease for the conversation after 3 boots', mine.length === 1,
79
- 'count=' + mine.length + ' sids=' + all.map((l) => l.session_id).join(','));
80
- check('boots 2+3 show no [Multi-Ansuz] self-ghost',
81
- !outs[1].includes('[Multi-Ansuz]') && !outs[2].includes('[Multi-Ansuz]'),
82
- 'boot2/3 banner: ' + (outs[1] + outs[2]).split(String.fromCharCode(10)).filter((l) => l.includes('Multi-Ansuz') || l.includes('[live]') || l.includes('[stale]')).join(' / '));
83
-
84
- // ── Arm 2 (control): different conversation still gets its OWN new lease ──
85
- const r2 = boot(CONV2);
86
- const all2 = readLeases();
87
- const mine2 = all2.filter((l) => l.conversation_id === CONV2);
88
- const mine1 = all2.filter((l) => l.conversation_id === CONV1);
89
- check('control: new conversation creates a NEW lease (reuse is conversation-scoped)',
90
- mine2.length === 1 && mine1.length === 1 && all2.length === 2,
91
- 'conv2=' + mine2.length + ' conv1=' + mine1.length + ' total=' + all2.length);
92
- check('control: second conversation SEES the first as a live peer (banner intact)',
93
- ((r2.stdout || '')).includes('[Multi-Ansuz]'),
94
- 'no peer banner: ' + (r2.stdout || '').slice(0, 400));
95
-
96
- fs.rmSync(SB, { recursive: true, force: true });
97
- console.log('---');
98
- console.log('RESULT: ' + pass + ' pass, ' + fail + ' fail');
99
- process.exit(fail ? 1 : 0);
@@ -1,129 +0,0 @@
1
- // TASK_1977 R3/R4(d) — ansuz-boot-fast.js handoff banner fan-out cap.
2
- //
3
- // MEASURED 2026-09-20: a run of 19 accumulated handoff slots printed 33.8 KB
4
- // into the fast-boot banner, most repeating the same pending_decisions text.
5
- // Fix: sort newest-first, print at most 3 full slots (deduped by topic
6
- // prefix), fold the rest into one summary line. Archiving must still touch
7
- // EVERY slot regardless of what gets rendered.
8
- //
9
- // Arms:
10
- // 1. 5 distinct-topic fixture slots -> 3 printed in full + 1 summary line
11
- // naming the other 2 topics; all 5 archived.
12
- // 2. dedup case: several slots share a topic prefix -> duplicates fold
13
- // into the summary instead of eating a "printed" slot.
14
- //
15
- // Usage: node .specialist/tools/__tests__/task-1977-banner-cap.test.js
16
- // Exit 0=all pass, non-zero=at least one failure.
17
-
18
- const { spawnSync } = require('child_process');
19
- const fs = require('fs');
20
- const os = require('os');
21
- const path = require('path');
22
-
23
- function resolveRoot() {
24
- let d = path.resolve(__dirname);
25
- for (let i = 0; i < 10; i++) {
26
- if (fs.existsSync(path.join(d, '.kenaz')) && fs.existsSync(path.join(d, '.specialist'))) return d;
27
- const parent = path.dirname(d);
28
- if (parent === d) break;
29
- d = parent;
30
- }
31
- if (process.env.CLAUDE_PROJECT_DIR) return process.env.CLAUDE_PROJECT_DIR;
32
- throw new Error('Cannot resolve repo root from ' + __dirname);
33
- }
34
- const WT = resolveRoot();
35
- const BOOT = path.join(WT, '.specialist/tools/ansuz-boot-fast.js');
36
-
37
- let pass = 0, fail = 0;
38
- function check(name, cond, detail) {
39
- console.log((cond ? 'PASS' : 'FAIL') + ' | ' + name + (cond ? '' : ' | ' + detail));
40
- cond ? pass++ : fail++;
41
- }
42
-
43
- function makeSandbox(prefix) {
44
- const sb = path.join(os.tmpdir(), prefix + '_' + process.pid + '_' + Date.now());
45
- for (const d of [
46
- '.kenaz/tasks/backlog', '.kenaz/tasks/active', '.kenaz/tasks/done',
47
- '.kenaz/tasks/blocked', '.kenaz/tasks/cancel',
48
- '.kenaz/specialist/sessions/leases',
49
- '.kenaz/specialist/handoffs',
50
- ]) fs.mkdirSync(path.join(sb, d), { recursive: true });
51
- return sb;
52
- }
53
-
54
- function writeSlot(sb, name, topic, generatedAt) {
55
- const p = path.join(sb, '.kenaz/specialist/handoffs', name);
56
- fs.writeFileSync(p, JSON.stringify({
57
- generated_at: generatedAt,
58
- isbar: {
59
- situation: { current_topic: topic, pending_decisions: 'pending for ' + topic },
60
- recommendation: { first_action: 'continue ' + topic },
61
- assessment: { unfinished: 'unfinished ' + topic },
62
- },
63
- }));
64
- }
65
-
66
- function boot(sb) {
67
- return spawnSync(process.execPath, [
68
- BOOT,
69
- '--project-path=' + sb,
70
- '--conversation-id=t1977-banner-' + path.basename(sb),
71
- '--mcp-base-url=http://127.0.0.1:1', // dead port: preamble arm fails instantly, offline-safe
72
- ], { encoding: 'utf8', env: { ...process.env, CLAUDE_PROJECT_DIR: sb }, windowsHide: true, cwd: sb, timeout: 30000 });
73
- }
74
-
75
- // ── Arm 1: 5 distinct-topic slots, oldest to newest ──
76
- const sb1 = makeSandbox('t1977_banner_distinct');
77
- writeSlot(sb1, 'slot-1.json', 'Topic ONE', '2026-09-15T00:00:00.000Z');
78
- writeSlot(sb1, 'slot-2.json', 'Topic TWO', '2026-09-16T00:00:00.000Z');
79
- writeSlot(sb1, 'slot-3.json', 'Topic THREE', '2026-09-17T00:00:00.000Z');
80
- writeSlot(sb1, 'slot-4.json', 'Topic FOUR', '2026-09-18T00:00:00.000Z');
81
- writeSlot(sb1, 'slot-5.json', 'Topic FIVE', '2026-09-19T00:00:00.000Z'); // newest
82
- const r1 = boot(sb1);
83
- const out1 = (r1.stdout || '') + (r1.stderr || '');
84
- check('arm1: boot runs (banner printed)', out1.includes('Ansuz'), 'status=' + r1.status + ' | ' + out1.slice(0, 300));
85
- // TASK_2280: the banner prints String(slot_file).slice(0, 8) (TASK_1988 diet),
86
- // so "slot-5.json" shows as "[slot-5.j]" -- match the 8-char prefix, not the filename.
87
- const fullBlocks1 =(out1.match(/📜 Handoff \[slot-\d\.j\]:/g) || []).length;
88
- check('arm1: exactly 3 full slots printed', fullBlocks1 === 3, 'count=' + fullBlocks1 + '\n' + out1);
89
- check('arm1: newest 3 topics printed in full (FIVE, FOUR, THREE)',
90
- out1.includes('Topic FIVE') && out1.includes('Topic FOUR') && out1.includes('Topic THREE'),
91
- out1);
92
- check('arm1: one summary line for the remaining 2, naming their topics',
93
- /2 more handoff slots archived \(topics: Topic TWO; Topic ONE\)/.test(out1),
94
- out1);
95
- const archiveDir1 = path.join(sb1, '.kenaz/specialist/handoff_archive');
96
- const archived1 = fs.existsSync(archiveDir1) ? fs.readdirSync(archiveDir1) : [];
97
- check('arm1: ALL 5 slots archived regardless of banner selection', archived1.length === 5, 'archived=' + JSON.stringify(archived1));
98
- const remaining1 = fs.readdirSync(path.join(sb1, '.kenaz/specialist/handoffs'));
99
- check('arm1: handoffs dir drained after archiving', remaining1.length === 0, 'remaining=' + JSON.stringify(remaining1));
100
-
101
- // ── Arm 2: dedup -- 4 slots share a topic prefix, 1 is distinct ──
102
- const sb2 = makeSandbox('t1977_banner_dedup');
103
- const REPEATED_TOPIC = 'Repeated handoff topic used verbatim across several stale Codex sessions that keeps recurring';
104
- writeSlot(sb2, 'dup-1.json', REPEATED_TOPIC, '2026-09-16T00:00:00.000Z');
105
- writeSlot(sb2, 'dup-2.json', REPEATED_TOPIC, '2026-09-17T00:00:00.000Z');
106
- writeSlot(sb2, 'dup-3.json', REPEATED_TOPIC, '2026-09-18T00:00:00.000Z'); // newest of the dupes
107
- writeSlot(sb2, 'unique.json', 'A distinct one-off topic', '2026-09-15T00:00:00.000Z'); // oldest overall
108
- const r2 = boot(sb2);
109
- const out2 = (r2.stdout || '') + (r2.stderr || '');
110
- check('arm2: boot runs (banner printed)', out2.includes('Ansuz'), 'status=' + r2.status + ' | ' + out2.slice(0, 300));
111
- const fullBlocks2 = (out2.match(/📜 Handoff \[(dup-\d\.js|unique\.j)\]:/g) || []).length;
112
- check('arm2: only 2 full slots printed (one per distinct topic prefix, dupes folded)', fullBlocks2 === 2, 'count=' + fullBlocks2 + '\n' + out2);
113
- check('arm2: newest dupe (dup-3) is the one printed in full, not dup-1/dup-2',
114
- out2.includes('📜 Handoff [dup-3.js]:') && !out2.includes('📜 Handoff [dup-1.js]:') && !out2.includes('📜 Handoff [dup-2.js]:'),
115
- out2);
116
- check('arm2: the distinct topic is also printed in full', out2.includes('📜 Handoff [unique.j]:'), out2);
117
- check('arm2: summary line folds the 2 duplicate slots', /2 more handoff slots archived/.test(out2), out2);
118
- const archiveDir2 = path.join(sb2, '.kenaz/specialist/handoff_archive');
119
- const archived2 = fs.existsSync(archiveDir2) ? fs.readdirSync(archiveDir2) : [];
120
- check('arm2: ALL 4 slots archived regardless of dedup folding', archived2.length === 4, 'archived=' + JSON.stringify(archived2));
121
-
122
- // ── cleanup ──
123
- for (const sb of [sb1, sb2]) {
124
- try { fs.rmSync(sb, { recursive: true, force: true }); } catch { /* best-effort */ }
125
- }
126
-
127
- console.log('---');
128
- console.log('RESULT: ' + pass + ' pass, ' + fail + ' fail');
129
- process.exit(fail > 0 ? 1 : 0);