blun-king-cli 9.0.0 → 9.1.0

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 (238) hide show
  1. package/LIESMICH.txt +32 -13
  2. package/README.md +39 -20
  3. package/bin/blun.js +248 -160
  4. package/bin/core-bootstrap.js +47 -0
  5. package/bin/king.js +277 -1
  6. package/bin/launcher-mode.js +15 -3
  7. package/bin/launcher-runtime.js +293 -0
  8. package/bin/plugin-bootstrap.js +11 -4
  9. package/bin/private-paths.js +1577 -10
  10. package/bin/update-lease.js +399 -0
  11. package/bin/update-notice.js +1245 -0
  12. package/blun.mjs +26606 -25239
  13. package/dist-web/assets/{CodeBlockNode-Bsvp6ZEy.js → CodeBlockNode-CXnTLMNr.js} +1 -1
  14. package/dist-web/assets/{CodeBlockShell.vue_vue_type_style_index_0_lang-ta7hLjia.js → CodeBlockShell.vue_vue_type_style_index_0_lang-CCF8Ntnq.js} +1 -1
  15. package/dist-web/assets/{DesignSystemView-BmDDe28A.js → DesignSystemView-BbMOu-XO.js} +1 -1
  16. package/dist-web/assets/{Tooltip-nEEfaYVY.js → Tooltip-CFQEzqC-.js} +1 -1
  17. package/dist-web/assets/abnfDiagram-N423BO3Z-CsByy-GW.js +1 -0
  18. package/dist-web/assets/abnfDiagram-N423BO3Z-Z1APZG5m.js +1 -0
  19. package/dist-web/assets/arc-C-LXCaja.js +1 -0
  20. package/dist-web/assets/arc-C4VyWloT.js +1 -0
  21. package/dist-web/assets/architectureDiagram-T3A2C74G-DZq4L18e.js +36 -0
  22. package/dist-web/assets/architectureDiagram-T3A2C74G-DpddbUcM.js +36 -0
  23. package/dist-web/assets/blockDiagram-VBNYF7ZC-BV4sIf98.js +132 -0
  24. package/dist-web/assets/blockDiagram-VBNYF7ZC-BqccOSMr.js +132 -0
  25. package/dist-web/assets/{c4Diagram-AAUBKEIU-DtzacMnD.js → c4Diagram-5PPSVZJV-0MRkZlgP.js} +1 -1
  26. package/dist-web/assets/{c4Diagram-AAUBKEIU-D1VdMx8d.js → c4Diagram-5PPSVZJV-OHAcJrTy.js} +1 -1
  27. package/dist-web/assets/channel-B2VOQOI-.js +1 -0
  28. package/dist-web/assets/channel-DKjwM05G.js +1 -0
  29. package/dist-web/assets/{chunk-ND2GUHAM-DJoY9wNJ.js → chunk-2GRJ4B5K-DqJHs8Fw.js} +1 -1
  30. package/dist-web/assets/{chunk-ND2GUHAM-C4-rwdcv.js → chunk-2GRJ4B5K-oO6nqeLA.js} +1 -1
  31. package/dist-web/assets/{chunk-QZHKN3VN-C7YGaShq.js → chunk-2Q5K7J3B-B1nCd91o.js} +1 -1
  32. package/dist-web/assets/{chunk-QZHKN3VN-_Rz9_NuS.js → chunk-2Q5K7J3B-BC0Hsfqy.js} +1 -1
  33. package/dist-web/assets/chunk-5RXB4S5H-BfZa4yDH.js +231 -0
  34. package/dist-web/assets/chunk-5RXB4S5H-neG70kZx.js +231 -0
  35. package/dist-web/assets/{chunk-FMBD7UC4-DlLNDUx6.js → chunk-5VM5RSS4-l7biGqeH.js} +1 -1
  36. package/dist-web/assets/{chunk-FMBD7UC4-B2zs_Y-d.js → chunk-5VM5RSS4-u00AcpiJ.js} +1 -1
  37. package/dist-web/assets/chunk-6Q2QTUOP-BO-F11Gs.js +88 -0
  38. package/dist-web/assets/chunk-6Q2QTUOP-RUVRPBzG.js +88 -0
  39. package/dist-web/assets/{chunk-727SXJPM-Dn5wkDO_.js → chunk-GF5L2VYU-Ba-86KTd.js} +5 -5
  40. package/dist-web/assets/{chunk-727SXJPM-Dk2Xa3bA.js → chunk-GF5L2VYU-BtC69fw0.js} +5 -5
  41. package/dist-web/assets/{chunk-4BX2VUAB-DxZViaHS.js → chunk-JWPE2WC7-DIOubEqr.js} +1 -1
  42. package/dist-web/assets/{chunk-4BX2VUAB-WqrE2gaw.js → chunk-JWPE2WC7-u8Pcfhwh.js} +1 -1
  43. package/dist-web/assets/{chunk-2J33WTMH-Dm_s0_4f.js → chunk-KBJHAD2P-DDUeH_Ba.js} +1 -1
  44. package/dist-web/assets/{chunk-2J33WTMH-w4sdiKFO.js → chunk-KBJHAD2P-DS3BL64y.js} +1 -1
  45. package/dist-web/assets/chunk-RYQCIY6F-B9gFMVbS.js +1 -0
  46. package/dist-web/assets/chunk-RYQCIY6F-xg3EO0le.js +1 -0
  47. package/dist-web/assets/{chunk-55IACEB6-B5dE1-Um.js → chunk-XXDRQBXY-B60H0rRC.js} +1 -1
  48. package/dist-web/assets/{chunk-55IACEB6-B12zGIFz.js → chunk-XXDRQBXY-Bn1Xz6TQ.js} +1 -1
  49. package/dist-web/assets/classDiagram-JCYQIIEL-BA1TjAxj.js +1 -0
  50. package/dist-web/assets/classDiagram-JCYQIIEL-BNU7Qn4k.js +1 -0
  51. package/dist-web/assets/classDiagram-v2-OCEON4UE-BA1TjAxj.js +1 -0
  52. package/dist-web/assets/classDiagram-v2-OCEON4UE-BNU7Qn4k.js +1 -0
  53. package/dist-web/assets/{cose-bilkent-S5V4N54A-Bi19n8m-.js → cose-bilkent-JH36ORCC-4Ybddg08.js} +1 -1
  54. package/dist-web/assets/{cose-bilkent-S5V4N54A-c8o8NFp5.js → cose-bilkent-JH36ORCC-DqigO3T4.js} +1 -1
  55. package/dist-web/assets/cynefin-VYW2F7L2-C-EfYT07.js +178 -0
  56. package/dist-web/assets/cynefin-VYW2F7L2-rpD93tQ-.js +178 -0
  57. package/dist-web/assets/cynefinDiagram-MW4NZA55-DWZPLJcD.js +62 -0
  58. package/dist-web/assets/cynefinDiagram-MW4NZA55-DbTqnkVJ.js +62 -0
  59. package/dist-web/assets/dagre-VZM6K2ZE-DcM8aEVY.js +4 -0
  60. package/dist-web/assets/dagre-VZM6K2ZE-M_HVNtqP.js +4 -0
  61. package/dist-web/assets/diagram-7IWD3JNH-DoNximNF.js +30 -0
  62. package/dist-web/assets/diagram-7IWD3JNH-UymgsBNa.js +30 -0
  63. package/dist-web/assets/{diagram-KO2AKTUF-CFQs13i5.js → diagram-B4RE2ZJO-BVA2EhnC.js} +3 -3
  64. package/dist-web/assets/{diagram-KO2AKTUF-agFIuPJW.js → diagram-B4RE2ZJO-BiYu5WPF.js} +3 -3
  65. package/dist-web/assets/{diagram-LMA3HP47-TMIXizxR.js → diagram-LBJQPF4R-BD3kkgOO.js} +2 -2
  66. package/dist-web/assets/{diagram-LMA3HP47-He5zlyMt.js → diagram-LBJQPF4R-m3a1Euj3.js} +2 -2
  67. package/dist-web/assets/diagram-Q27KOJAE-D1mYQ_cI.js +24 -0
  68. package/dist-web/assets/diagram-Q27KOJAE-hy_T73PK.js +24 -0
  69. package/dist-web/assets/diagram-UB23O5K3-BWkoQZ4A.js +41 -0
  70. package/dist-web/assets/diagram-UB23O5K3-BtX8u6HG.js +41 -0
  71. package/dist-web/assets/ebnfDiagram-BXEA7PRR-BKs9JUHW.js +1 -0
  72. package/dist-web/assets/ebnfDiagram-BXEA7PRR-CBAnFkRF.js +1 -0
  73. package/dist-web/assets/erDiagram-JOGREHBK-3vKcWsxm.js +85 -0
  74. package/dist-web/assets/erDiagram-JOGREHBK-BIpd6dTf.js +85 -0
  75. package/dist-web/assets/flowDiagram-UKHOOZJN-D9wBbHm2.js +156 -0
  76. package/dist-web/assets/flowDiagram-UKHOOZJN-Z83i2UWI.js +156 -0
  77. package/dist-web/assets/ganttDiagram-PKOTCBZU-Cd_dViF-.js +292 -0
  78. package/dist-web/assets/ganttDiagram-PKOTCBZU-DFrb_S1d.js +292 -0
  79. package/dist-web/assets/{gitGraphDiagram-PVQCEYII-BSDFfwdY.js → gitGraphDiagram-DS77QQ5N-BiEEtTo7.js} +3 -3
  80. package/dist-web/assets/{gitGraphDiagram-PVQCEYII-DMbTATyw.js → gitGraphDiagram-DS77QQ5N-Dp3Ar-hi.js} +3 -3
  81. package/dist-web/assets/{graph-BwjfAU3j.js → graph-CAUpWmoK.js} +1 -1
  82. package/dist-web/assets/{graph--OzhPTMs.js → graph-DOmOIIwC.js} +1 -1
  83. package/dist-web/assets/{index-W6VnSrkB.js → index-Ba1OvLjf.js} +2 -2
  84. package/dist-web/assets/{index-CkVgGDpx.js → index-CiPA8Kex.js} +4 -4
  85. package/dist-web/assets/{index-BzK4vJBu.js → index-DdEakFJM.js} +1 -1
  86. package/dist-web/assets/{index10-Czg_oF-W.js → index10-CNr4U-Nw.js} +1 -1
  87. package/dist-web/assets/{index11-BjzCZuCr.js → index11-Dto_yZNz.js} +1 -1
  88. package/dist-web/assets/{index5-DlVoNkCD.js → index5-B2PldaO2.js} +1 -1
  89. package/dist-web/assets/{index6-BxiXA2yo.js → index6-CBdZmmyx.js} +1 -1
  90. package/dist-web/assets/{index7-BPdza6d1.js → index7-Dz9oCsUF.js} +1 -1
  91. package/dist-web/assets/{index8-Q_XzGC1Z.js → index8-B6k25jtU.js} +2 -2
  92. package/dist-web/assets/{infoDiagram-5YYISTIA-2JF3XEdD.js → infoDiagram-6WML65LV-BSa2g04G.js} +1 -1
  93. package/dist-web/assets/{infoDiagram-5YYISTIA-UrQusrJq.js → infoDiagram-6WML65LV-D4ph2sIH.js} +1 -1
  94. package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-7RVUL-vB.js → ishikawaDiagram-WSZJBQD7-DjKjbMm9.js} +5 -5
  95. package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-C5OstRVV.js → ishikawaDiagram-WSZJBQD7-Hm36UOQe.js} +5 -5
  96. package/dist-web/assets/{journeyDiagram-JHISSGLW-B34fCMu9.js → journeyDiagram-NVQOT4AX-DttHDfPQ.js} +1 -1
  97. package/dist-web/assets/{journeyDiagram-JHISSGLW-yctdo4bX.js → journeyDiagram-NVQOT4AX-MvWWPNDV.js} +1 -1
  98. package/dist-web/assets/{kanban-definition-UN3LZRKU-BS4FBZsQ.js → kanban-definition-27J2QSJJ-C5gB-W0d.js} +7 -7
  99. package/dist-web/assets/{kanban-definition-UN3LZRKU-CxBCv27E.js → kanban-definition-27J2QSJJ-Cu-E_cXA.js} +5 -5
  100. package/dist-web/assets/layout-CvP6o9AK.js +1 -0
  101. package/dist-web/assets/layout-D-LzfAck.js +1 -0
  102. package/dist-web/assets/{linear-3mB6q2-g.js → linear-B3HWgQI2.js} +1 -1
  103. package/dist-web/assets/{linear-BKCnUo31.js → linear-BRGe4-d6.js} +1 -1
  104. package/dist-web/assets/map-CWKZqZjr.js +1 -0
  105. package/dist-web/assets/map-DxJ2ADlA.js +1 -0
  106. package/dist-web/assets/mermaid.core-D-9Sx1No.js +314 -0
  107. package/dist-web/assets/mermaidParser.worker-PTFfzpoB.js +318 -0
  108. package/dist-web/assets/{mindmap-definition-RKZ34NQL-BmJZpjh6.js → mindmap-definition-FAOFIHXS-C4vnms3i.js} +2 -2
  109. package/dist-web/assets/{mindmap-definition-RKZ34NQL-1mjWUcf6.js → mindmap-definition-FAOFIHXS-Cg_hoVIq.js} +1 -1
  110. package/dist-web/assets/pegDiagram-VL7TDLO6-B2fFEFUH.js +1 -0
  111. package/dist-web/assets/pegDiagram-VL7TDLO6-CSX9hitD.js +1 -0
  112. package/dist-web/assets/pieDiagram-7S7Q4E2Y-0L0mxahZ.js +39 -0
  113. package/dist-web/assets/pieDiagram-7S7Q4E2Y-C7T0Cmw1.js +39 -0
  114. package/dist-web/assets/{quadrantDiagram-W4KKPZXB-BmT_qM09.js → quadrantDiagram-CIZ2JOQS-BBy7w4kD.js} +3 -3
  115. package/dist-web/assets/{quadrantDiagram-W4KKPZXB-C0kPuyNP.js → quadrantDiagram-CIZ2JOQS-U483z0er.js} +3 -3
  116. package/dist-web/assets/railroadDiagram-AXF67PYL-D80a2_DJ.js +1 -0
  117. package/dist-web/assets/railroadDiagram-AXF67PYL-DX8y0MzW.js +1 -0
  118. package/dist-web/assets/{requirementDiagram-4Y6WPE33-C0YP_Amt.js → requirementDiagram-LRYGKXZP-CeyHfq8t.js} +3 -3
  119. package/dist-web/assets/{requirementDiagram-4Y6WPE33-CZrxH1Y2.js → requirementDiagram-LRYGKXZP-DGD5J_4k.js} +3 -3
  120. package/dist-web/assets/sankeyDiagram-W5VNT64P-CCISkkrR.js +40 -0
  121. package/dist-web/assets/sankeyDiagram-W5VNT64P-CT5PdZz2.js +40 -0
  122. package/dist-web/assets/sequenceDiagram-SI44F4Z6-BeMzHWXI.js +162 -0
  123. package/dist-web/assets/sequenceDiagram-SI44F4Z6-jQfm2XS7.js +162 -0
  124. package/dist-web/assets/sizeCapture-X5ZJPWSS-BQsTdtrv.js +1 -0
  125. package/dist-web/assets/sizeCapture-X5ZJPWSS-lRZsmCoS.js +1 -0
  126. package/dist-web/assets/stateDiagram-OKZ733FA-ClCgTdUm.js +1 -0
  127. package/dist-web/assets/stateDiagram-OKZ733FA-Cv59z5YT.js +1 -0
  128. package/dist-web/assets/stateDiagram-v2-UEYNNEHI-R8jTc--F.js +1 -0
  129. package/dist-web/assets/stateDiagram-v2-UEYNNEHI-fi_lrTAx.js +1 -0
  130. package/dist-web/assets/swimlanes-SLNWSIFB-BCdOUN05.js +2 -0
  131. package/dist-web/assets/swimlanes-SLNWSIFB-Cu5l7SuR.js +1 -0
  132. package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-BUd_uYK3.js +8 -0
  133. package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-CalrsgPK.js +8 -0
  134. package/dist-web/assets/{timeline-definition-PNZ67QCA-DsVZdrZa.js → timeline-definition-Z64GVDOM-CMjnh4bu.js} +4 -4
  135. package/dist-web/assets/{timeline-definition-PNZ67QCA-DnB6Usl0.js → timeline-definition-Z64GVDOM-DpWutSKa.js} +4 -4
  136. package/dist-web/assets/vennDiagram-T6HMQDX7-DKJW_8oU.js +34 -0
  137. package/dist-web/assets/vennDiagram-T6HMQDX7-DVC5JVsc.js +34 -0
  138. package/dist-web/assets/{vue.runtime.esm-bundler-pgHGheCW.js → vue.runtime.esm-bundler-BwwRtQwQ.js} +1 -1
  139. package/dist-web/assets/{wardleyDiagram-YWT4CUSO-oBauTCEw.js → wardleyDiagram-T6FBY63Y-BK2mrq7L.js} +3 -3
  140. package/dist-web/assets/{wardleyDiagram-YWT4CUSO-DCiyDQNB.js → wardleyDiagram-T6FBY63Y-oUvgepFn.js} +3 -3
  141. package/dist-web/assets/xychartDiagram-ELKLHX3M-DI6n79q0.js +7 -0
  142. package/dist-web/assets/xychartDiagram-ELKLHX3M-DUJu9F7-.js +7 -0
  143. package/dist-web/index.html +1 -1
  144. package/dist-web/vis/index.html.gz +0 -0
  145. package/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  146. package/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  147. package/package.json +9 -11
  148. package/skills/screenshot-lesen/SKILL.md +0 -1
  149. package/skills/web-lesen/SKILL.md +0 -1
  150. package/telegram-plugin/dist/bridge.mjs +7 -25
  151. package/telegram-plugin/dist/mcp-server.mjs +236 -71
  152. package/dist-web/assets/arc-4xPfymbf.js +0 -1
  153. package/dist-web/assets/arc-Doj0wRZ0.js +0 -1
  154. package/dist-web/assets/architectureDiagram-3BPJPVTR-BGih283a.js +0 -36
  155. package/dist-web/assets/architectureDiagram-3BPJPVTR-CQ09RrbH.js +0 -36
  156. package/dist-web/assets/blockDiagram-GPEHLZMM-3ShMf1gu.js +0 -132
  157. package/dist-web/assets/blockDiagram-GPEHLZMM-CAtDjkJt.js +0 -132
  158. package/dist-web/assets/channel-DNkUo9e6.js +0 -1
  159. package/dist-web/assets/channel-DcnUTIGB.js +0 -1
  160. package/dist-web/assets/chunk-AQP2D5EJ-FS8-f8lF.js +0 -231
  161. package/dist-web/assets/chunk-AQP2D5EJ-UKhb4V4r.js +0 -231
  162. package/dist-web/assets/classDiagram-4FO5ZUOK-B1ZO8EbE.js +0 -1
  163. package/dist-web/assets/classDiagram-4FO5ZUOK-xk6cM9Kq.js +0 -1
  164. package/dist-web/assets/classDiagram-v2-Q7XG4LA2-B1ZO8EbE.js +0 -1
  165. package/dist-web/assets/classDiagram-v2-Q7XG4LA2-xk6cM9Kq.js +0 -1
  166. package/dist-web/assets/dagre-BM42HDAG-CmUO9qKN.js +0 -4
  167. package/dist-web/assets/dagre-BM42HDAG-DLMfLCoV.js +0 -4
  168. package/dist-web/assets/diagram-2AECGRRQ-DQTst0OH.js +0 -43
  169. package/dist-web/assets/diagram-2AECGRRQ-L74iLMqd.js +0 -43
  170. package/dist-web/assets/diagram-5GNKFQAL-BiBm7CJR.js +0 -10
  171. package/dist-web/assets/diagram-5GNKFQAL-DoE6q7H1.js +0 -10
  172. package/dist-web/assets/diagram-OG6HWLK6-BHCt1E0n.js +0 -24
  173. package/dist-web/assets/diagram-OG6HWLK6-DRyxjFMa.js +0 -24
  174. package/dist-web/assets/erDiagram-TEJ5UH35-BoDczjGG.js +0 -85
  175. package/dist-web/assets/erDiagram-TEJ5UH35-yd6SOv_7.js +0 -85
  176. package/dist-web/assets/flowDiagram-I6XJVG4X-DHoceI7r.js +0 -162
  177. package/dist-web/assets/flowDiagram-I6XJVG4X-DkYNQv0R.js +0 -162
  178. package/dist-web/assets/ganttDiagram-6RSMTGT7-Cg1TQBc0.js +0 -292
  179. package/dist-web/assets/ganttDiagram-6RSMTGT7-Z6klo7KK.js +0 -292
  180. package/dist-web/assets/layout-C1ojF0zw.js +0 -1
  181. package/dist-web/assets/layout-SsrduOYp.js +0 -1
  182. package/dist-web/assets/mermaid.core-D_lKT0dR.js +0 -309
  183. package/dist-web/assets/mermaidParser.worker-Dx4jPi9z.js +0 -313
  184. package/dist-web/assets/pieDiagram-4H26LBE5-BU41t2A_.js +0 -30
  185. package/dist-web/assets/pieDiagram-4H26LBE5-BkwDAvbt.js +0 -30
  186. package/dist-web/assets/sankeyDiagram-5OEKKPKP-De_o7hDr.js +0 -40
  187. package/dist-web/assets/sankeyDiagram-5OEKKPKP-Dvuj6bMA.js +0 -40
  188. package/dist-web/assets/sequenceDiagram-3UESZ5HK-DuCrgPyA.js +0 -162
  189. package/dist-web/assets/sequenceDiagram-3UESZ5HK-VAxffBe7.js +0 -162
  190. package/dist-web/assets/stateDiagram-AJRCARHV-CYLupxM7.js +0 -1
  191. package/dist-web/assets/stateDiagram-AJRCARHV-nDExQydZ.js +0 -1
  192. package/dist-web/assets/stateDiagram-v2-BHNVJYJU-BhEc7Thx.js +0 -1
  193. package/dist-web/assets/stateDiagram-v2-BHNVJYJU-BzwD_BIl.js +0 -1
  194. package/dist-web/assets/vennDiagram-CIIHVFJN-BBHQmCFf.js +0 -34
  195. package/dist-web/assets/vennDiagram-CIIHVFJN-Cfj-K9NW.js +0 -34
  196. package/dist-web/assets/wardley-L42UT6IY-BJFn8eDD.js +0 -173
  197. package/dist-web/assets/wardley-L42UT6IY-BSu8-4hg.js +0 -173
  198. package/dist-web/assets/xychartDiagram-2RQKCTM6-C2iZpl9I.js +0 -7
  199. package/dist-web/assets/xychartDiagram-2RQKCTM6-Db_VoDBV.js +0 -7
  200. package/mnemo/access_routes.js +0 -692
  201. package/mnemo/agent_governance.js +0 -4242
  202. package/mnemo/agent_mail.js +0 -901
  203. package/mnemo/bootstrap_auto.js +0 -137
  204. package/mnemo/brief_coordination.js +0 -226
  205. package/mnemo/code_read_tools.js +0 -375
  206. package/mnemo/context_preview_tools.js +0 -603
  207. package/mnemo/embeddings.js +0 -66
  208. package/mnemo/external_repo_ops.js +0 -575
  209. package/mnemo/facts/example-project-rules.json +0 -90
  210. package/mnemo/facts/example.json +0 -34
  211. package/mnemo/identity_schema.sql +0 -139
  212. package/mnemo/journal_schema.js +0 -561
  213. package/mnemo/loop_doctor_tools.js +0 -661
  214. package/mnemo/mail_secret_refs.js +0 -150
  215. package/mnemo/mcp.js +0 -9309
  216. package/mnemo/memory_consolidation.js +0 -1914
  217. package/mnemo/memory_health_tools.js +0 -165
  218. package/mnemo/package.json +0 -79
  219. package/mnemo/protected_scope_gate.js +0 -627
  220. package/mnemo/resource_access_control.js +0 -684
  221. package/mnemo/runtime_governance.js +0 -1256
  222. package/mnemo/runtime_turn_gate.js +0 -862
  223. package/mnemo/sandbox.js +0 -143
  224. package/mnemo/schema.sql +0 -389
  225. package/mnemo/shared_utils.js +0 -763
  226. package/mnemo/skills/agent-auto-resume/SKILL.md +0 -56
  227. package/mnemo/skills/agent_hand/SKILL.md +0 -43
  228. package/mnemo/skills/agent_hand/run.js +0 -63
  229. package/mnemo/skills/book_flight/SKILL.md +0 -34
  230. package/mnemo/skills/external_repo_review/SKILL.md +0 -43
  231. package/mnemo/skills/external_repo_review/run.js +0 -73
  232. package/mnemo/skills/pay_invoice/SKILL.md +0 -34
  233. package/mnemo/team_quality_ops.js +0 -944
  234. package/mnemo/timeline_report_tools.js +0 -810
  235. package/mnemo/write_gate_risk.js +0 -80
  236. package/mnemo/writer_health.js +0 -152
  237. package/skills/doku-ingestion/SKILL.md +0 -48
  238. package/skills/doku-ingestion/ingest_docs.py +0 -133
package/bin/king.js CHANGED
@@ -1,4 +1,280 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- require('./blun');
4
+ // This public entry must stay self-contained. Package-local modules are loaded
5
+ // only after the update owner proves that the package root is not being replaced.
6
+ const { createHash } = require('node:crypto');
7
+ const fs = require('node:fs');
8
+ const net = require('node:net');
9
+ const os = require('node:os');
10
+ const path = require('node:path');
11
+
12
+ const LEASE_PROTOCOL_VERSION = 'BLUN_UPDATE_LEASE_V3';
13
+ const LEASE_PROBE_TIMEOUT_MS = 500;
14
+ const MAX_POSIX_SOCKET_PATH_BYTES = 96;
15
+ const PACKAGE_ROOT = path.resolve(__dirname, '..');
16
+
17
+ function deriveLeaseEndpoint(role) {
18
+ const realpath = fs.realpathSync.native || fs.realpathSync;
19
+ let identity = realpath(PACKAGE_ROOT);
20
+ if (!fs.statSync(identity).isDirectory()) throw new Error('INVALID_PACKAGE_ROOT');
21
+ identity = identity.replaceAll('\\', '/');
22
+ if (process.platform === 'win32') identity = identity.toLowerCase();
23
+ const digest = createHash('sha256')
24
+ .update(`blun-update-v3\0${role}\0${identity}`)
25
+ .digest('hex');
26
+ const magic = `${LEASE_PROTOCOL_VERSION} ${digest}\n`;
27
+ if (process.platform === 'win32') {
28
+ return {
29
+ magic,
30
+ path: `\\\\.\\pipe\\blun-update-v3-${digest.slice(0, 32)}`,
31
+ platform: 'win32',
32
+ };
33
+ }
34
+
35
+ const uid = typeof process.getuid === 'function' ? process.getuid() : undefined;
36
+ const directoryName = `blun-update-${uid ?? digest.slice(0, 12)}`;
37
+ let directory = path.posix.join(os.tmpdir().replaceAll('\\', '/'), directoryName);
38
+ let socketPath = path.posix.join(directory, `lease-${digest.slice(0, 24)}.sock`);
39
+ if (Buffer.byteLength(socketPath, 'utf8') > MAX_POSIX_SOCKET_PATH_BYTES) {
40
+ directory = path.posix.join('/tmp', directoryName);
41
+ socketPath = path.posix.join(directory, `lease-${digest.slice(0, 24)}.sock`);
42
+ }
43
+ if (Buffer.byteLength(socketPath, 'utf8') > MAX_POSIX_SOCKET_PATH_BYTES) {
44
+ throw new Error('UPDATE_LEASE_SOCKET_PATH_TOO_LONG');
45
+ }
46
+ return { directory, magic, path: socketPath, platform: process.platform };
47
+ }
48
+
49
+ function ensurePrivateSocketDirectory(endpoint) {
50
+ if (endpoint.platform === 'win32') return;
51
+ fs.mkdirSync(endpoint.directory, { recursive: true, mode: 0o700 });
52
+ const stat = fs.lstatSync(endpoint.directory);
53
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
54
+ throw new Error('INVALID_UPDATE_LEASE_DIRECTORY');
55
+ }
56
+ if (typeof process.getuid === 'function'
57
+ && Number.isInteger(stat.uid)
58
+ && stat.uid !== process.getuid()) {
59
+ throw new Error('INVALID_UPDATE_LEASE_DIRECTORY_OWNER');
60
+ }
61
+ fs.chmodSync(endpoint.directory, 0o700);
62
+ }
63
+
64
+ function closeServer(server) {
65
+ return new Promise((resolve) => {
66
+ if (!server.listening) {
67
+ resolve();
68
+ return;
69
+ }
70
+ try {
71
+ server.close(() => resolve());
72
+ } catch {
73
+ resolve();
74
+ }
75
+ });
76
+ }
77
+
78
+ function listenForLease(endpoint) {
79
+ return new Promise((resolve, reject) => {
80
+ const server = net.createServer((socket) => {
81
+ socket.on('error', () => {});
82
+ socket.end(endpoint.magic);
83
+ });
84
+ const onError = (error) => {
85
+ server.removeListener('error', onError);
86
+ reject(error);
87
+ };
88
+ server.once('error', onError);
89
+ server.listen({ path: endpoint.path, exclusive: true }, () => {
90
+ server.removeListener('error', onError);
91
+ resolve(server);
92
+ });
93
+ });
94
+ }
95
+
96
+ function probeLease(endpoint) {
97
+ return new Promise((resolve) => {
98
+ let received = '';
99
+ let settled = false;
100
+ let socket;
101
+ const finish = (state) => {
102
+ if (settled) return;
103
+ settled = true;
104
+ clearTimeout(timer);
105
+ try {
106
+ socket?.destroy();
107
+ } catch {}
108
+ // oxlint-disable-next-line promise/no-multiple-resolved -- settled is the idempotence guard.
109
+ resolve(state);
110
+ };
111
+ const timer = setTimeout(() => finish('foreign'), LEASE_PROBE_TIMEOUT_MS);
112
+ timer.unref?.();
113
+ try {
114
+ socket = net.createConnection({ path: endpoint.path });
115
+ socket.setEncoding('utf8');
116
+ socket.on('data', (chunk) => {
117
+ received += String(chunk);
118
+ if (Buffer.byteLength(received, 'utf8') > Buffer.byteLength(endpoint.magic, 'utf8')) {
119
+ finish('foreign');
120
+ }
121
+ });
122
+ socket.once('end', () => finish(received === endpoint.magic ? 'owner' : 'foreign'));
123
+ socket.once('error', (error) => {
124
+ finish(error?.code === 'ECONNREFUSED' || error?.code === 'ENOENT'
125
+ ? 'stale'
126
+ : 'foreign');
127
+ });
128
+ socket.once('close', () => {
129
+ if (!settled) finish(received === endpoint.magic ? 'owner' : 'foreign');
130
+ });
131
+ } catch (error) {
132
+ finish(error?.code === 'ECONNREFUSED' || error?.code === 'ENOENT'
133
+ ? 'stale'
134
+ : 'foreign');
135
+ }
136
+ });
137
+ }
138
+
139
+ function observeSocket(endpoint) {
140
+ if (endpoint.platform === 'win32') return { state: 'not_applicable' };
141
+ try {
142
+ const stat = fs.lstatSync(endpoint.path);
143
+ if (!stat.isSocket() || stat.isSymbolicLink()) return { state: 'unsafe' };
144
+ return { dev: stat.dev, ino: stat.ino, state: 'socket' };
145
+ } catch (error) {
146
+ return error?.code === 'ENOENT' ? { state: 'missing' } : { state: 'unsafe' };
147
+ }
148
+ }
149
+
150
+ function removeObservedSocket(endpoint, observed) {
151
+ if (endpoint.platform === 'win32') return false;
152
+ try {
153
+ const stat = fs.lstatSync(endpoint.path);
154
+ if (observed.state !== 'socket'
155
+ || !stat.isSocket()
156
+ || stat.isSymbolicLink()
157
+ || stat.dev !== observed.dev
158
+ || stat.ino !== observed.ino) {
159
+ return false;
160
+ }
161
+ fs.unlinkSync(endpoint.path);
162
+ return true;
163
+ } catch (error) {
164
+ return error?.code === 'ENOENT' && observed.state === 'missing';
165
+ }
166
+ }
167
+
168
+ function recordSocket(endpoint) {
169
+ if (endpoint.platform === 'win32') return undefined;
170
+ const stat = fs.lstatSync(endpoint.path);
171
+ if (!stat.isSocket() || stat.isSymbolicLink()) throw new Error('INVALID_UPDATE_LEASE_SOCKET');
172
+ fs.chmodSync(endpoint.path, 0o600);
173
+ return { dev: stat.dev, ino: stat.ino };
174
+ }
175
+
176
+ function removeOwnedSocket(endpoint, identity) {
177
+ if (endpoint.platform === 'win32' || !identity) return;
178
+ try {
179
+ const stat = fs.lstatSync(endpoint.path);
180
+ if (stat.isSocket()
181
+ && !stat.isSymbolicLink()
182
+ && stat.dev === identity.dev
183
+ && stat.ino === identity.ino) {
184
+ fs.unlinkSync(endpoint.path);
185
+ }
186
+ } catch {}
187
+ }
188
+
189
+ async function acquireNoticeLease() {
190
+ let endpoint;
191
+ try {
192
+ endpoint = deriveLeaseEndpoint('notice');
193
+ ensurePrivateSocketDirectory(endpoint);
194
+ } catch {
195
+ return { acquired: false, reason: 'unavailable' };
196
+ }
197
+
198
+ let server;
199
+ for (let attempt = 0; attempt < 2; attempt += 1) {
200
+ try {
201
+ server = await listenForLease(endpoint);
202
+ break;
203
+ } catch (error) {
204
+ if (error?.code !== 'EADDRINUSE') return { acquired: false, reason: 'unavailable' };
205
+ const observed = observeSocket(endpoint);
206
+ const state = await probeLease(endpoint);
207
+ if (state === 'owner') return { acquired: false, reason: 'busy' };
208
+ if (state !== 'stale' || attempt > 0) return { acquired: false, reason: 'unavailable' };
209
+ if (endpoint.platform === 'win32') continue;
210
+ if (!removeObservedSocket(endpoint, observed)) {
211
+ return { acquired: false, reason: 'unavailable' };
212
+ }
213
+ }
214
+ }
215
+ if (!server) return { acquired: false, reason: 'unavailable' };
216
+
217
+ let identity;
218
+ try {
219
+ identity = recordSocket(endpoint);
220
+ } catch {
221
+ await closeServer(server);
222
+ return { acquired: false, reason: 'unavailable' };
223
+ }
224
+
225
+ let owned = true;
226
+ let released = false;
227
+ server.on('error', () => { owned = false; });
228
+ server.on('close', () => { owned = false; });
229
+ return {
230
+ acquired: true,
231
+ lease: Object.freeze({
232
+ assertOwned() {
233
+ if (!owned || !server.listening) throw new Error('UPDATE_LEASE_LOST');
234
+ },
235
+ async release() {
236
+ if (released) return;
237
+ released = true;
238
+ owned = false;
239
+ await closeServer(server);
240
+ removeOwnedSocket(endpoint, identity);
241
+ },
242
+ }),
243
+ };
244
+ }
245
+
246
+ async function installLeaseIsClear() {
247
+ try {
248
+ const endpoint = deriveLeaseEndpoint('install');
249
+ ensurePrivateSocketDirectory(endpoint);
250
+ return await probeLease(endpoint) === 'stale';
251
+ } catch {
252
+ return false;
253
+ }
254
+ }
255
+
256
+ async function main() {
257
+ const result = await acquireNoticeLease();
258
+ if (!result.acquired) return;
259
+ try {
260
+ if (!await installLeaseIsClear()) return;
261
+ result.lease.assertOwned();
262
+ const { runLauncher } = require('./launcher-runtime');
263
+ result.lease.assertOwned();
264
+ const filename = path.basename(__filename).toLowerCase();
265
+ await runLauncher({
266
+ mode: filename.startsWith('king') ? 'king' : 'blun',
267
+ noticeLease: result.lease,
268
+ });
269
+ } finally {
270
+ await result.lease.release();
271
+ }
272
+ }
273
+
274
+ // oxlint-disable-next-line unicorn/prefer-top-level-await -- Public npm bins are CommonJS.
275
+ void main().catch((error) => {
276
+ // oxlint-disable-next-line no-console -- Fatal launcher errors belong on stderr.
277
+ console.error('BLUN Start fehlgeschlagen: '
278
+ + (error && error.message ? error.message : String(error)));
279
+ process.exitCode = 1;
280
+ });
@@ -5,7 +5,14 @@ const LAUNCHER_MODES = Object.freeze({
5
5
  KING: 'king',
6
6
  });
7
7
 
8
- const NPM_PACKAGE_UPDATE_COMMAND = 'npm install -g blun-king-cli@latest';
8
+ const LAUNCHER_HELP_TEXT = [
9
+ '',
10
+ 'Launchers:',
11
+ ' blun Starts the CLI without automatically attaching Telegram.',
12
+ ' king Starts the same CLI and automatically attaches the configured Telegram channel.',
13
+ ' Both use the same version, account, model, and commands.',
14
+ '',
15
+ ].join('\n');
9
16
 
10
17
  function launcherModeFromArgv(argv) {
11
18
  const entry = argv[1] || '';
@@ -14,10 +21,11 @@ function launcherModeFromArgv(argv) {
14
21
  return command === LAUNCHER_MODES.KING ? LAUNCHER_MODES.KING : LAUNCHER_MODES.BLUN;
15
22
  }
16
23
 
17
- function createLauncherEnvironment(sourceEnv, mode) {
24
+ function createLauncherEnvironment(sourceEnv, mode, publicPackageVersion) {
18
25
  return {
19
26
  ...sourceEnv,
20
27
  BLUN_NO_AUTO_UPDATE: '1',
28
+ BLUN_PUBLIC_PACKAGE_VERSION: publicPackageVersion,
21
29
  BLUN_TELEGRAM_ATTACH: mode === LAUNCHER_MODES.KING ? 'on' : 'off',
22
30
  BLUN_TELEGRAM_HEADLESS: 'off',
23
31
  };
@@ -29,10 +37,14 @@ function isNpmPackageUpdateRequest(args) {
29
37
  return command === 'update' || command === 'upgrade';
30
38
  }
31
39
 
40
+ function launcherHelpText() {
41
+ return LAUNCHER_HELP_TEXT;
42
+ }
43
+
32
44
  module.exports = {
33
45
  LAUNCHER_MODES,
34
- NPM_PACKAGE_UPDATE_COMMAND,
35
46
  createLauncherEnvironment,
36
47
  isNpmPackageUpdateRequest,
48
+ launcherHelpText,
37
49
  launcherModeFromArgv,
38
50
  };
@@ -0,0 +1,293 @@
1
+ 'use strict';
2
+ /*
3
+ * BLUN CLI Launcher (npm) — Erststart richtet alles ein:
4
+ * 1. King richtet das Telegram-Plugin im BLUN_HOME ein
5
+ * Danach: TUI starten. Anmeldung und Modellkatalog kommen ueber BLUN OAuth.
6
+ */
7
+ const fs = require('node:fs');
8
+ const path = require('node:path');
9
+ const os = require('node:os');
10
+ const { spawn } = require('node:child_process');
11
+ const {
12
+ LAUNCHER_MODES,
13
+ createLauncherEnvironment,
14
+ isNpmPackageUpdateRequest,
15
+ launcherHelpText,
16
+ launcherModeFromArgv,
17
+ } = require('./launcher-mode');
18
+ const { installManagedTelegramPlugin } = require('./plugin-bootstrap');
19
+ const { CORE_LOADED_MESSAGE } = require('./core-bootstrap');
20
+ const { tryAcquireUpdateLease } = require('./update-lease');
21
+ const { runExplicitUpdate, runUpdateNotice } = require('./update-notice');
22
+ const {
23
+ ensurePrivateDirectory,
24
+ securePrivateFile,
25
+ securePrivateTree,
26
+ writePrivateFile,
27
+ } = require('./private-paths');
28
+
29
+ const PKG = path.resolve(__dirname, '..');
30
+ const ARGS = process.argv.slice(2);
31
+ const CORE_LOAD_TIMEOUT_MS = 30_000;
32
+
33
+ function normalizeWindowsPath(value) {
34
+ return path.win32.normalize(value).replace(/\\+$/u, '').toLowerCase();
35
+ }
36
+
37
+ function resolveLauncherPrivatePaths(options = {}) {
38
+ const env = options.env || process.env;
39
+ const platform = options.platform || process.platform;
40
+ const configuredHome = String(env.BLUN_HOME || '').trim();
41
+ if (platform !== 'win32') {
42
+ const userHome = (options.homedir || os.homedir)();
43
+ return {
44
+ blunHome: configuredHome ? path.resolve(configuredHome) : path.join(userHome, '.blun'),
45
+ userHome,
46
+ };
47
+ }
48
+
49
+ const fsImpl = options.fsImpl || fs;
50
+ const userInfo = (options.userInfo || os.userInfo)();
51
+ const reportedHome = String(userInfo?.homedir || '').trim();
52
+ if (!path.win32.isAbsolute(reportedHome) || reportedHome.startsWith('\\\\')) {
53
+ throw new Error('Das lokale Windows-Benutzerprofil konnte nicht sicher bestimmt werden.');
54
+ }
55
+ const resolvedHome = path.win32.resolve(reportedHome);
56
+ const stat = fsImpl.lstatSync(resolvedHome);
57
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
58
+ throw new Error('Das lokale Windows-Benutzerprofil ist kein vertrauenswuerdiges Verzeichnis.');
59
+ }
60
+ const realpath = fsImpl.realpathSync.native || fsImpl.realpathSync;
61
+ const userHome = path.win32.normalize(realpath(resolvedHome));
62
+ const volumeRoot = path.win32.parse(userHome).root;
63
+ if (!/^[A-Za-z]:\\$/u.test(volumeRoot)
64
+ || normalizeWindowsPath(userHome) !== normalizeWindowsPath(resolvedHome)) {
65
+ throw new Error('Das lokale Windows-Benutzerprofil ist kein kanonischer lokaler Pfad.');
66
+ }
67
+
68
+ const blunHome = path.win32.join(userHome, '.blun');
69
+ if (configuredHome
70
+ && normalizeWindowsPath(path.win32.resolve(configuredHome)) !== normalizeWindowsPath(blunHome)) {
71
+ throw new Error(`BLUN_HOME muss unter Windows exakt im Windows-Benutzerprofil liegen: ${blunHome}`);
72
+ }
73
+ return { blunHome, userHome };
74
+ }
75
+
76
+ function readPackageVersion() {
77
+ const { version } = JSON.parse(fs.readFileSync(path.join(PKG, 'package.json'), 'utf8'));
78
+ if (typeof version !== 'string' || version.length === 0) {
79
+ throw new Error('Ungueltige Paketversion in package.json');
80
+ }
81
+ return version;
82
+ }
83
+
84
+ function spawnProtectedCore(args, env, cwd) {
85
+ const child = spawn(
86
+ process.execPath,
87
+ [path.join(PKG, 'bin', 'core-bootstrap.js'), ...args],
88
+ {
89
+ cwd,
90
+ detached: true,
91
+ env,
92
+ stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
93
+ windowsHide: true,
94
+ },
95
+ );
96
+ let loadedSettled = false;
97
+ let completedSettled = false;
98
+ let resolveLoaded;
99
+ let resolveCompleted;
100
+ const loadTimer = setTimeout(() => {
101
+ try {
102
+ child.kill();
103
+ } catch {}
104
+ }, CORE_LOAD_TIMEOUT_MS);
105
+ const loaded = new Promise((resolve) => { resolveLoaded = resolve; });
106
+ const completed = new Promise((resolve) => { resolveCompleted = resolve; });
107
+ const settleLoaded = (value) => {
108
+ if (loadedSettled) return;
109
+ loadedSettled = true;
110
+ clearTimeout(loadTimer);
111
+ resolveLoaded(value);
112
+ };
113
+ const settleCompleted = (result) => {
114
+ if (completedSettled) return;
115
+ completedSettled = true;
116
+ for (const [signal, handler] of signalHandlers) process.removeListener(signal, handler);
117
+ settleLoaded(false);
118
+ resolveCompleted(result);
119
+ };
120
+ const signalHandlers = new Map();
121
+ for (const signal of ['SIGHUP', 'SIGINT', 'SIGTERM']) {
122
+ const handler = () => {
123
+ try {
124
+ child.kill(signal);
125
+ } catch {}
126
+ };
127
+ signalHandlers.set(signal, handler);
128
+ process.once(signal, handler);
129
+ }
130
+ child.on('message', (message) => {
131
+ if (message?.type !== CORE_LOADED_MESSAGE) return;
132
+ settleLoaded(true);
133
+ try {
134
+ child.disconnect();
135
+ } catch {}
136
+ });
137
+ child.once('error', (error) => settleCompleted({ error }));
138
+ child.once('exit', (code, signal) => settleCompleted({ code, signal }));
139
+ return { child, completed, loaded };
140
+ }
141
+
142
+ async function superviseProtectedCore(args, env, cwd, releaseNotice) {
143
+ const core = spawnProtectedCore(args, env, cwd);
144
+ const loaded = await core.loaded;
145
+ await releaseNotice();
146
+ const result = await core.completed;
147
+ if (result.error) throw result.error;
148
+ return exitCodeForChild(result, loaded);
149
+ }
150
+
151
+ function exitCodeForChild(result, loaded) {
152
+ if (!loaded && result.code === 75) return 0;
153
+ if (Number.isInteger(result.code)) return result.code;
154
+ if (result.signal === 'SIGINT') return 130;
155
+ if (result.signal === 'SIGTERM') return 143;
156
+ return 1;
157
+ }
158
+
159
+ async function runLauncher(options = {}) {
160
+ const callerCwd = process.cwd();
161
+ const mode = options.mode || launcherModeFromArgv(process.argv);
162
+ const explicitUpdateRequest = isNpmPackageUpdateRequest(ARGS);
163
+ const noticeResult = options.noticeLease
164
+ ? { acquired: true, lease: options.noticeLease }
165
+ : await tryAcquireUpdateLease({ packageRoot: PKG, role: 'notice' });
166
+ if (!noticeResult.acquired) {
167
+ if (explicitUpdateRequest) {
168
+ process.stderr.write('Das Update konnte nicht verifiziert werden.\n');
169
+ process.exitCode = 1;
170
+ }
171
+ return;
172
+ }
173
+ const noticeLease = noticeResult.lease;
174
+ let noticeReleased = false;
175
+ const releaseNotice = async () => {
176
+ if (noticeReleased) return;
177
+ noticeReleased = true;
178
+ await noticeLease.release();
179
+ };
180
+
181
+ try {
182
+ const installProbe = await tryAcquireUpdateLease({ packageRoot: PKG, role: 'install' });
183
+ if (!installProbe.acquired) {
184
+ if (explicitUpdateRequest) {
185
+ process.stderr.write('Das Update konnte nicht verifiziert werden.\n');
186
+ process.exitCode = 1;
187
+ }
188
+ return;
189
+ }
190
+ await installProbe.lease.release();
191
+
192
+ if (ARGS.some((arg) => arg === '--version' || arg === '-V')) {
193
+ process.stdout.write(`${readPackageVersion()}\n`);
194
+ return;
195
+ }
196
+
197
+ if (explicitUpdateRequest) {
198
+ const privatePaths = resolveLauncherPrivatePaths();
199
+ const result = await runExplicitUpdate({
200
+ currentVersion: readPackageVersion(),
201
+ env: process.env,
202
+ stdin: process.stdin,
203
+ stdout: process.stdout,
204
+ stderr: process.stderr,
205
+ blunDir: privatePaths.blunHome,
206
+ packageRoot: PKG,
207
+ noticeLease,
208
+ request: ARGS[0],
209
+ });
210
+ if (result.kind === 'failed') process.exitCode = result.exitCode || 1;
211
+ return;
212
+ }
213
+
214
+ if (ARGS.some((arg) => arg === '--help' || arg === '-h')) {
215
+ process.stdout.write(launcherHelpText());
216
+ const env = createLauncherEnvironment(process.env, mode, readPackageVersion());
217
+ const informationalEnv = { ...process.env };
218
+ delete informationalEnv.BLUN_HOME;
219
+ env.BLUN_HOME = resolveLauncherPrivatePaths({ env: informationalEnv }).blunHome;
220
+ process.exitCode = await superviseProtectedCore(ARGS, env, callerCwd, releaseNotice);
221
+ return;
222
+ }
223
+
224
+ const privatePaths = resolveLauncherPrivatePaths();
225
+ const blunDir = privatePaths.blunHome;
226
+ ensurePrivateDirectory(blunDir);
227
+
228
+ // --- 1. Oeffentlicher npm-Update-Dialog. -------------------------------
229
+ const updateResult = await runUpdateNotice({
230
+ currentVersion: readPackageVersion(),
231
+ argv: ARGS,
232
+ env: process.env,
233
+ stdin: process.stdin,
234
+ stdout: process.stdout,
235
+ stderr: process.stderr,
236
+ blunDir,
237
+ packageRoot: PKG,
238
+ noticeLease,
239
+ });
240
+ if (updateResult.kind === 'installed' || updateResult.kind === 'update_in_progress') return;
241
+
242
+ // --- 2. Bestehende Konfiguration absichern -------------------------------
243
+ // Ein frischer Start bleibt absichtlich ohne statischen Anbieter. /login
244
+ // provisioniert King ueber den BLUN-OAuth-Server.
245
+ const cfgFile = path.join(blunDir, 'config.toml');
246
+ if (fs.existsSync(cfgFile)) securePrivateFile(cfgFile);
247
+
248
+ // --- 3. Telegram-Plugin + Token-Vorlage (nur King) -----------------------
249
+ if (mode === LAUNCHER_MODES.KING) {
250
+ installManagedTelegramPlugin({ packageRoot: PKG, blunDir });
251
+ const channelsDir = path.join(blunDir, 'channels');
252
+ const channelDir = path.join(channelsDir, 'telegram');
253
+ ensurePrivateDirectory(channelsDir);
254
+ ensurePrivateDirectory(channelDir);
255
+ const envFile = path.join(channelDir, '.env');
256
+ if (!fs.existsSync(envFile)) {
257
+ writePrivateFile(envFile, 'BLUN_TELEGRAM_BOT_TOKEN=HIER_DEIN_BOT_TOKEN_EINFUEGEN\n');
258
+ } else {
259
+ securePrivateFile(envFile);
260
+ }
261
+ }
262
+
263
+ // --- 3b. Built-in-Skills installieren (fehlende ergaenzen, nie
264
+ // vorhandene ueberschreiben — User-Anpassungen bleiben) -----------
265
+ const skillsSrc = path.join(PKG, 'skills');
266
+ const skillsDst = path.join(blunDir, 'skills');
267
+ if (fs.existsSync(skillsSrc)) {
268
+ if (fs.existsSync(skillsDst)) securePrivateTree(skillsDst);
269
+ else ensurePrivateDirectory(skillsDst);
270
+ for (const entry of fs.readdirSync(skillsSrc)) {
271
+ const dst = path.join(skillsDst, entry);
272
+ if (!fs.existsSync(dst)) {
273
+ fs.cpSync(path.join(skillsSrc, entry), dst, { recursive: true });
274
+ }
275
+ }
276
+ }
277
+
278
+ // --- 4. Start -----------------------------------------------------------
279
+ const env = createLauncherEnvironment(process.env, mode, readPackageVersion());
280
+ env.BLUN_HOME = blunDir;
281
+ env.BLUN_MODEL_MAX_COMPLETION_TOKENS = env.BLUN_MODEL_MAX_COMPLETION_TOKENS || '32768';
282
+ process.exitCode = await superviseProtectedCore(
283
+ ['--yolo', ...ARGS],
284
+ env,
285
+ callerCwd,
286
+ releaseNotice,
287
+ );
288
+ } finally {
289
+ await releaseNotice();
290
+ }
291
+ }
292
+
293
+ module.exports = { resolveLauncherPrivatePaths, runLauncher };
@@ -4,7 +4,11 @@ const { randomUUID } = require('node:crypto');
4
4
  const fs = require('node:fs');
5
5
  const path = require('node:path');
6
6
 
7
- const { ensurePrivateDirectory, writePrivateFile } = require('./private-paths');
7
+ const {
8
+ ensurePrivateDirectory,
9
+ securePrivateFile,
10
+ writePrivateFile,
11
+ } = require('./private-paths');
8
12
 
9
13
  function isObject(value) {
10
14
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -81,10 +85,10 @@ function installManagedTelegramPlugin({ packageRoot, blunDir, now = new Date().t
81
85
  const pluginRoot = path.join(managedDir, 'telegram');
82
86
  const installedFile = path.join(pluginsDir, 'installed.json');
83
87
 
88
+ ensurePrivateDirectory(pluginsDir);
89
+ if (fs.existsSync(installedFile)) securePrivateFile(installedFile);
84
90
  const installed = readInstalledPlugins(installedFile);
85
91
  const updatedInstalled = updatedInstalledPlugins(installed, pluginRoot, now);
86
-
87
- ensurePrivateDirectory(pluginsDir);
88
92
  ensurePrivateDirectory(managedDir);
89
93
  const nonce = `${process.pid}-${randomUUID()}`;
90
94
  const stagingRoot = path.join(managedDir, `.telegram-${nonce}.tmp`);
@@ -92,8 +96,11 @@ function installManagedTelegramPlugin({ packageRoot, blunDir, now = new Date().t
92
96
  let hadPreviousPlugin = false;
93
97
  let installedNewPlugin = false;
94
98
  try {
99
+ if (fs.existsSync(pluginRoot)) {
100
+ ensurePrivateDirectory(pluginRoot);
101
+ hadPreviousPlugin = true;
102
+ }
95
103
  fs.cpSync(sourceRoot, stagingRoot, { recursive: true, force: true });
96
- hadPreviousPlugin = fs.existsSync(pluginRoot);
97
104
  if (hadPreviousPlugin) fs.renameSync(pluginRoot, backupRoot);
98
105
  try {
99
106
  fs.renameSync(stagingRoot, pluginRoot);