blockmine 1.23.4 → 1.25.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 (954) hide show
  1. package/CHANGELOG.md +82 -32
  2. package/README.en.md +427 -0
  3. package/README.md +40 -0
  4. package/backend/cli.js +1 -1
  5. package/backend/src/ai/plugin-assistant-system-prompt.md +725 -6
  6. package/backend/src/api/routes/aiAssistant.js +562 -103
  7. package/backend/src/api/routes/botUsers.js +30 -10
  8. package/backend/src/api/routes/bots.js +112 -21
  9. package/backend/src/api/routes/servers.js +14 -2
  10. package/backend/src/core/BotProcess.js +139 -7
  11. package/backend/src/core/GraphExecutionEngine.js +9 -2
  12. package/backend/src/core/PluginHooks.js +221 -0
  13. package/backend/src/core/PluginLoader.js +83 -3
  14. package/backend/src/core/PluginManager.js +85 -5
  15. package/backend/src/core/node-registries/container.js +162 -0
  16. package/backend/src/core/node-registries/furnace.js +143 -0
  17. package/backend/src/core/node-registries/inventory.js +181 -0
  18. package/backend/src/core/node-registries/navigation.js +111 -0
  19. package/backend/src/core/nodes/container/close.js +26 -0
  20. package/backend/src/core/nodes/container/deposit.js +88 -0
  21. package/backend/src/core/nodes/container/deposit_all.js +71 -0
  22. package/backend/src/core/nodes/container/find_item.js +77 -0
  23. package/backend/src/core/nodes/container/get_items.js +51 -0
  24. package/backend/src/core/nodes/container/open.js +111 -0
  25. package/backend/src/core/nodes/container/withdraw.js +91 -0
  26. package/backend/src/core/nodes/furnace/close.js +24 -0
  27. package/backend/src/core/nodes/furnace/get_status.js +74 -0
  28. package/backend/src/core/nodes/furnace/open.js +110 -0
  29. package/backend/src/core/nodes/furnace/put_fuel.js +64 -0
  30. package/backend/src/core/nodes/furnace/put_input.js +64 -0
  31. package/backend/src/core/nodes/furnace/take_output.js +69 -0
  32. package/backend/src/core/nodes/inventory/count_item.js +28 -0
  33. package/backend/src/core/nodes/inventory/drop.js +65 -0
  34. package/backend/src/core/nodes/inventory/equip.js +45 -0
  35. package/backend/src/core/nodes/inventory/find_item.js +55 -0
  36. package/backend/src/core/nodes/inventory/get_all.js +45 -0
  37. package/backend/src/core/nodes/inventory/get_held_item.js +63 -0
  38. package/backend/src/core/nodes/inventory/get_slot.js +46 -0
  39. package/backend/src/core/nodes/inventory/has_item.js +35 -0
  40. package/backend/src/core/nodes/inventory/select_slot.js +46 -0
  41. package/backend/src/core/nodes/navigation/follow.js +51 -0
  42. package/backend/src/core/nodes/navigation/go_to.js +53 -0
  43. package/backend/src/core/nodes/navigation/go_to_entity.js +69 -0
  44. package/backend/src/core/nodes/navigation/go_to_player.js +70 -0
  45. package/backend/src/core/nodes/navigation/stop.js +26 -0
  46. package/backend/src/core/services/BotLifecycleService.js +186 -2
  47. package/backend/src/core/services/MinecraftViewerService.js +2 -0
  48. package/backend/src/server.js +11 -1
  49. package/frontend/dist/assets/browser-ponyfill-DN7pwmHT.js +2 -0
  50. package/frontend/dist/assets/index-LSy71uwm.js +11261 -0
  51. package/frontend/dist/assets/index-SfhKxI4-.css +32 -0
  52. package/frontend/dist/flags/en.svg +32 -0
  53. package/frontend/dist/flags/ru.svg +5 -0
  54. package/frontend/dist/index.html +2 -2
  55. package/frontend/dist/locales/en/admin.json +100 -0
  56. package/frontend/dist/locales/en/api-keys.json +58 -0
  57. package/frontend/dist/locales/en/bots.json +110 -0
  58. package/frontend/dist/locales/en/common.json +47 -0
  59. package/frontend/dist/locales/en/configuration.json +22 -0
  60. package/frontend/dist/locales/en/console.json +10 -0
  61. package/frontend/dist/locales/en/dashboard.json +85 -0
  62. package/frontend/dist/locales/en/dialogs.json +70 -0
  63. package/frontend/dist/locales/en/event-graphs.json +50 -0
  64. package/frontend/dist/locales/en/graph-store.json +70 -0
  65. package/frontend/dist/locales/en/login.json +34 -0
  66. package/frontend/dist/locales/en/management.json +114 -0
  67. package/frontend/dist/locales/en/minecraft-viewer.json +27 -0
  68. package/frontend/dist/locales/en/nodes.json +1077 -0
  69. package/frontend/dist/locales/en/permissions.json +50 -0
  70. package/frontend/dist/locales/en/plugin-detail.json +49 -0
  71. package/frontend/dist/locales/en/plugins.json +110 -0
  72. package/frontend/dist/locales/en/proxies.json +81 -0
  73. package/frontend/dist/locales/en/servers.json +39 -0
  74. package/frontend/dist/locales/en/setup.json +17 -0
  75. package/frontend/dist/locales/en/sidebar.json +27 -0
  76. package/frontend/dist/locales/en/tasks.json +62 -0
  77. package/frontend/dist/locales/en/visual-editor.json +219 -0
  78. package/frontend/dist/locales/en/websocket.json +86 -0
  79. package/frontend/dist/locales/ru/admin.json +100 -0
  80. package/frontend/dist/locales/ru/api-keys.json +58 -0
  81. package/frontend/dist/locales/ru/bots.json +110 -0
  82. package/frontend/dist/locales/ru/common.json +49 -0
  83. package/frontend/dist/locales/ru/configuration.json +22 -0
  84. package/frontend/dist/locales/ru/console.json +10 -0
  85. package/frontend/dist/locales/ru/dashboard.json +85 -0
  86. package/frontend/dist/locales/ru/dialogs.json +70 -0
  87. package/frontend/dist/locales/ru/event-graphs.json +50 -0
  88. package/frontend/dist/locales/ru/graph-store.json +70 -0
  89. package/frontend/dist/locales/ru/login.json +34 -0
  90. package/frontend/dist/locales/ru/management.json +114 -0
  91. package/frontend/dist/locales/ru/minecraft-viewer.json +27 -0
  92. package/frontend/dist/locales/ru/nodes.json +1077 -0
  93. package/frontend/dist/locales/ru/permissions.json +50 -0
  94. package/frontend/dist/locales/ru/plugin-detail.json +49 -0
  95. package/frontend/dist/locales/ru/plugins.json +110 -0
  96. package/frontend/dist/locales/ru/proxies.json +81 -0
  97. package/frontend/dist/locales/ru/servers.json +39 -0
  98. package/frontend/dist/locales/ru/setup.json +17 -0
  99. package/frontend/dist/locales/ru/sidebar.json +27 -0
  100. package/frontend/dist/locales/ru/tasks.json +62 -0
  101. package/frontend/dist/locales/ru/visual-editor.json +221 -0
  102. package/frontend/dist/locales/ru/websocket.json +86 -0
  103. package/frontend/dist/minecraft-assets/items/acacia_boat.png +0 -0
  104. package/frontend/dist/minecraft-assets/items/acacia_chest_boat.png +0 -0
  105. package/frontend/dist/minecraft-assets/items/acacia_door.png +0 -0
  106. package/frontend/dist/minecraft-assets/items/acacia_hanging_sign.png +0 -0
  107. package/frontend/dist/minecraft-assets/items/acacia_sign.png +0 -0
  108. package/frontend/dist/minecraft-assets/items/amethyst_shard.png +0 -0
  109. package/frontend/dist/minecraft-assets/items/angler_pottery_sherd.png +0 -0
  110. package/frontend/dist/minecraft-assets/items/apple.png +0 -0
  111. package/frontend/dist/minecraft-assets/items/archer_pottery_sherd.png +0 -0
  112. package/frontend/dist/minecraft-assets/items/armor_stand.png +0 -0
  113. package/frontend/dist/minecraft-assets/items/arms_up_pottery_sherd.png +0 -0
  114. package/frontend/dist/minecraft-assets/items/arrow.png +0 -0
  115. package/frontend/dist/minecraft-assets/items/axolotl_bucket.png +0 -0
  116. package/frontend/dist/minecraft-assets/items/baked_potato.png +0 -0
  117. package/frontend/dist/minecraft-assets/items/bamboo.png +0 -0
  118. package/frontend/dist/minecraft-assets/items/bamboo_chest_raft.png +0 -0
  119. package/frontend/dist/minecraft-assets/items/bamboo_door.png +0 -0
  120. package/frontend/dist/minecraft-assets/items/bamboo_hanging_sign.png +0 -0
  121. package/frontend/dist/minecraft-assets/items/bamboo_raft.png +0 -0
  122. package/frontend/dist/minecraft-assets/items/bamboo_sign.png +0 -0
  123. package/frontend/dist/minecraft-assets/items/barrier.png +0 -0
  124. package/frontend/dist/minecraft-assets/items/beef.png +0 -0
  125. package/frontend/dist/minecraft-assets/items/beetroot.png +0 -0
  126. package/frontend/dist/minecraft-assets/items/beetroot_seeds.png +0 -0
  127. package/frontend/dist/minecraft-assets/items/beetroot_soup.png +0 -0
  128. package/frontend/dist/minecraft-assets/items/bell.png +0 -0
  129. package/frontend/dist/minecraft-assets/items/birch_boat.png +0 -0
  130. package/frontend/dist/minecraft-assets/items/birch_chest_boat.png +0 -0
  131. package/frontend/dist/minecraft-assets/items/birch_door.png +0 -0
  132. package/frontend/dist/minecraft-assets/items/birch_hanging_sign.png +0 -0
  133. package/frontend/dist/minecraft-assets/items/birch_sign.png +0 -0
  134. package/frontend/dist/minecraft-assets/items/black_candle.png +0 -0
  135. package/frontend/dist/minecraft-assets/items/black_dye.png +0 -0
  136. package/frontend/dist/minecraft-assets/items/blade_pottery_sherd.png +0 -0
  137. package/frontend/dist/minecraft-assets/items/blaze_powder.png +0 -0
  138. package/frontend/dist/minecraft-assets/items/blaze_rod.png +0 -0
  139. package/frontend/dist/minecraft-assets/items/blue_candle.png +0 -0
  140. package/frontend/dist/minecraft-assets/items/blue_dye.png +0 -0
  141. package/frontend/dist/minecraft-assets/items/bone.png +0 -0
  142. package/frontend/dist/minecraft-assets/items/bone_meal.png +0 -0
  143. package/frontend/dist/minecraft-assets/items/book.png +0 -0
  144. package/frontend/dist/minecraft-assets/items/bow.png +0 -0
  145. package/frontend/dist/minecraft-assets/items/bow_pulling_0.png +0 -0
  146. package/frontend/dist/minecraft-assets/items/bow_pulling_1.png +0 -0
  147. package/frontend/dist/minecraft-assets/items/bow_pulling_2.png +0 -0
  148. package/frontend/dist/minecraft-assets/items/bowl.png +0 -0
  149. package/frontend/dist/minecraft-assets/items/bread.png +0 -0
  150. package/frontend/dist/minecraft-assets/items/brewer_pottery_sherd.png +0 -0
  151. package/frontend/dist/minecraft-assets/items/brewing_stand.png +0 -0
  152. package/frontend/dist/minecraft-assets/items/brick.png +0 -0
  153. package/frontend/dist/minecraft-assets/items/broken_elytra.png +0 -0
  154. package/frontend/dist/minecraft-assets/items/brown_candle.png +0 -0
  155. package/frontend/dist/minecraft-assets/items/brown_dye.png +0 -0
  156. package/frontend/dist/minecraft-assets/items/brush.png +0 -0
  157. package/frontend/dist/minecraft-assets/items/bucket.png +0 -0
  158. package/frontend/dist/minecraft-assets/items/bundle.png +0 -0
  159. package/frontend/dist/minecraft-assets/items/bundle_filled.png +0 -0
  160. package/frontend/dist/minecraft-assets/items/burn_pottery_sherd.png +0 -0
  161. package/frontend/dist/minecraft-assets/items/cake.png +0 -0
  162. package/frontend/dist/minecraft-assets/items/campfire.png +0 -0
  163. package/frontend/dist/minecraft-assets/items/candle.png +0 -0
  164. package/frontend/dist/minecraft-assets/items/carrot.png +0 -0
  165. package/frontend/dist/minecraft-assets/items/carrot_on_a_stick.png +0 -0
  166. package/frontend/dist/minecraft-assets/items/cauldron.png +0 -0
  167. package/frontend/dist/minecraft-assets/items/chain.png +0 -0
  168. package/frontend/dist/minecraft-assets/items/chainmail_boots.png +0 -0
  169. package/frontend/dist/minecraft-assets/items/chainmail_chestplate.png +0 -0
  170. package/frontend/dist/minecraft-assets/items/chainmail_helmet.png +0 -0
  171. package/frontend/dist/minecraft-assets/items/chainmail_leggings.png +0 -0
  172. package/frontend/dist/minecraft-assets/items/charcoal.png +0 -0
  173. package/frontend/dist/minecraft-assets/items/cherry_boat.png +0 -0
  174. package/frontend/dist/minecraft-assets/items/cherry_chest_boat.png +0 -0
  175. package/frontend/dist/minecraft-assets/items/cherry_door.png +0 -0
  176. package/frontend/dist/minecraft-assets/items/cherry_hanging_sign.png +0 -0
  177. package/frontend/dist/minecraft-assets/items/cherry_sign.png +0 -0
  178. package/frontend/dist/minecraft-assets/items/chest_minecart.png +0 -0
  179. package/frontend/dist/minecraft-assets/items/chicken.png +0 -0
  180. package/frontend/dist/minecraft-assets/items/chorus_fruit.png +0 -0
  181. package/frontend/dist/minecraft-assets/items/clay_ball.png +0 -0
  182. package/frontend/dist/minecraft-assets/items/clock_00.png +0 -0
  183. package/frontend/dist/minecraft-assets/items/clock_01.png +0 -0
  184. package/frontend/dist/minecraft-assets/items/clock_02.png +0 -0
  185. package/frontend/dist/minecraft-assets/items/clock_03.png +0 -0
  186. package/frontend/dist/minecraft-assets/items/clock_04.png +0 -0
  187. package/frontend/dist/minecraft-assets/items/clock_05.png +0 -0
  188. package/frontend/dist/minecraft-assets/items/clock_06.png +0 -0
  189. package/frontend/dist/minecraft-assets/items/clock_07.png +0 -0
  190. package/frontend/dist/minecraft-assets/items/clock_08.png +0 -0
  191. package/frontend/dist/minecraft-assets/items/clock_09.png +0 -0
  192. package/frontend/dist/minecraft-assets/items/clock_10.png +0 -0
  193. package/frontend/dist/minecraft-assets/items/clock_11.png +0 -0
  194. package/frontend/dist/minecraft-assets/items/clock_12.png +0 -0
  195. package/frontend/dist/minecraft-assets/items/clock_13.png +0 -0
  196. package/frontend/dist/minecraft-assets/items/clock_14.png +0 -0
  197. package/frontend/dist/minecraft-assets/items/clock_15.png +0 -0
  198. package/frontend/dist/minecraft-assets/items/clock_16.png +0 -0
  199. package/frontend/dist/minecraft-assets/items/clock_17.png +0 -0
  200. package/frontend/dist/minecraft-assets/items/clock_18.png +0 -0
  201. package/frontend/dist/minecraft-assets/items/clock_19.png +0 -0
  202. package/frontend/dist/minecraft-assets/items/clock_20.png +0 -0
  203. package/frontend/dist/minecraft-assets/items/clock_21.png +0 -0
  204. package/frontend/dist/minecraft-assets/items/clock_22.png +0 -0
  205. package/frontend/dist/minecraft-assets/items/clock_23.png +0 -0
  206. package/frontend/dist/minecraft-assets/items/clock_24.png +0 -0
  207. package/frontend/dist/minecraft-assets/items/clock_25.png +0 -0
  208. package/frontend/dist/minecraft-assets/items/clock_26.png +0 -0
  209. package/frontend/dist/minecraft-assets/items/clock_27.png +0 -0
  210. package/frontend/dist/minecraft-assets/items/clock_28.png +0 -0
  211. package/frontend/dist/minecraft-assets/items/clock_29.png +0 -0
  212. package/frontend/dist/minecraft-assets/items/clock_30.png +0 -0
  213. package/frontend/dist/minecraft-assets/items/clock_31.png +0 -0
  214. package/frontend/dist/minecraft-assets/items/clock_32.png +0 -0
  215. package/frontend/dist/minecraft-assets/items/clock_33.png +0 -0
  216. package/frontend/dist/minecraft-assets/items/clock_34.png +0 -0
  217. package/frontend/dist/minecraft-assets/items/clock_35.png +0 -0
  218. package/frontend/dist/minecraft-assets/items/clock_36.png +0 -0
  219. package/frontend/dist/minecraft-assets/items/clock_37.png +0 -0
  220. package/frontend/dist/minecraft-assets/items/clock_38.png +0 -0
  221. package/frontend/dist/minecraft-assets/items/clock_39.png +0 -0
  222. package/frontend/dist/minecraft-assets/items/clock_40.png +0 -0
  223. package/frontend/dist/minecraft-assets/items/clock_41.png +0 -0
  224. package/frontend/dist/minecraft-assets/items/clock_42.png +0 -0
  225. package/frontend/dist/minecraft-assets/items/clock_43.png +0 -0
  226. package/frontend/dist/minecraft-assets/items/clock_44.png +0 -0
  227. package/frontend/dist/minecraft-assets/items/clock_45.png +0 -0
  228. package/frontend/dist/minecraft-assets/items/clock_46.png +0 -0
  229. package/frontend/dist/minecraft-assets/items/clock_47.png +0 -0
  230. package/frontend/dist/minecraft-assets/items/clock_48.png +0 -0
  231. package/frontend/dist/minecraft-assets/items/clock_49.png +0 -0
  232. package/frontend/dist/minecraft-assets/items/clock_50.png +0 -0
  233. package/frontend/dist/minecraft-assets/items/clock_51.png +0 -0
  234. package/frontend/dist/minecraft-assets/items/clock_52.png +0 -0
  235. package/frontend/dist/minecraft-assets/items/clock_53.png +0 -0
  236. package/frontend/dist/minecraft-assets/items/clock_54.png +0 -0
  237. package/frontend/dist/minecraft-assets/items/clock_55.png +0 -0
  238. package/frontend/dist/minecraft-assets/items/clock_56.png +0 -0
  239. package/frontend/dist/minecraft-assets/items/clock_57.png +0 -0
  240. package/frontend/dist/minecraft-assets/items/clock_58.png +0 -0
  241. package/frontend/dist/minecraft-assets/items/clock_59.png +0 -0
  242. package/frontend/dist/minecraft-assets/items/clock_60.png +0 -0
  243. package/frontend/dist/minecraft-assets/items/clock_61.png +0 -0
  244. package/frontend/dist/minecraft-assets/items/clock_62.png +0 -0
  245. package/frontend/dist/minecraft-assets/items/clock_63.png +0 -0
  246. package/frontend/dist/minecraft-assets/items/coal.png +0 -0
  247. package/frontend/dist/minecraft-assets/items/coast_armor_trim_smithing_template.png +0 -0
  248. package/frontend/dist/minecraft-assets/items/cocoa_beans.png +0 -0
  249. package/frontend/dist/minecraft-assets/items/cod.png +0 -0
  250. package/frontend/dist/minecraft-assets/items/cod_bucket.png +0 -0
  251. package/frontend/dist/minecraft-assets/items/command_block_minecart.png +0 -0
  252. package/frontend/dist/minecraft-assets/items/comparator.png +0 -0
  253. package/frontend/dist/minecraft-assets/items/compass_00.png +0 -0
  254. package/frontend/dist/minecraft-assets/items/compass_01.png +0 -0
  255. package/frontend/dist/minecraft-assets/items/compass_02.png +0 -0
  256. package/frontend/dist/minecraft-assets/items/compass_03.png +0 -0
  257. package/frontend/dist/minecraft-assets/items/compass_04.png +0 -0
  258. package/frontend/dist/minecraft-assets/items/compass_05.png +0 -0
  259. package/frontend/dist/minecraft-assets/items/compass_06.png +0 -0
  260. package/frontend/dist/minecraft-assets/items/compass_07.png +0 -0
  261. package/frontend/dist/minecraft-assets/items/compass_08.png +0 -0
  262. package/frontend/dist/minecraft-assets/items/compass_09.png +0 -0
  263. package/frontend/dist/minecraft-assets/items/compass_10.png +0 -0
  264. package/frontend/dist/minecraft-assets/items/compass_11.png +0 -0
  265. package/frontend/dist/minecraft-assets/items/compass_12.png +0 -0
  266. package/frontend/dist/minecraft-assets/items/compass_13.png +0 -0
  267. package/frontend/dist/minecraft-assets/items/compass_14.png +0 -0
  268. package/frontend/dist/minecraft-assets/items/compass_15.png +0 -0
  269. package/frontend/dist/minecraft-assets/items/compass_16.png +0 -0
  270. package/frontend/dist/minecraft-assets/items/compass_17.png +0 -0
  271. package/frontend/dist/minecraft-assets/items/compass_18.png +0 -0
  272. package/frontend/dist/minecraft-assets/items/compass_19.png +0 -0
  273. package/frontend/dist/minecraft-assets/items/compass_20.png +0 -0
  274. package/frontend/dist/minecraft-assets/items/compass_21.png +0 -0
  275. package/frontend/dist/minecraft-assets/items/compass_22.png +0 -0
  276. package/frontend/dist/minecraft-assets/items/compass_23.png +0 -0
  277. package/frontend/dist/minecraft-assets/items/compass_24.png +0 -0
  278. package/frontend/dist/minecraft-assets/items/compass_25.png +0 -0
  279. package/frontend/dist/minecraft-assets/items/compass_26.png +0 -0
  280. package/frontend/dist/minecraft-assets/items/compass_27.png +0 -0
  281. package/frontend/dist/minecraft-assets/items/compass_28.png +0 -0
  282. package/frontend/dist/minecraft-assets/items/compass_29.png +0 -0
  283. package/frontend/dist/minecraft-assets/items/compass_30.png +0 -0
  284. package/frontend/dist/minecraft-assets/items/compass_31.png +0 -0
  285. package/frontend/dist/minecraft-assets/items/cooked_beef.png +0 -0
  286. package/frontend/dist/minecraft-assets/items/cooked_chicken.png +0 -0
  287. package/frontend/dist/minecraft-assets/items/cooked_cod.png +0 -0
  288. package/frontend/dist/minecraft-assets/items/cooked_mutton.png +0 -0
  289. package/frontend/dist/minecraft-assets/items/cooked_porkchop.png +0 -0
  290. package/frontend/dist/minecraft-assets/items/cooked_rabbit.png +0 -0
  291. package/frontend/dist/minecraft-assets/items/cooked_salmon.png +0 -0
  292. package/frontend/dist/minecraft-assets/items/cookie.png +0 -0
  293. package/frontend/dist/minecraft-assets/items/copper_ingot.png +0 -0
  294. package/frontend/dist/minecraft-assets/items/creeper_banner_pattern.png +0 -0
  295. package/frontend/dist/minecraft-assets/items/crimson_door.png +0 -0
  296. package/frontend/dist/minecraft-assets/items/crimson_hanging_sign.png +0 -0
  297. package/frontend/dist/minecraft-assets/items/crimson_sign.png +0 -0
  298. package/frontend/dist/minecraft-assets/items/crossbow_arrow.png +0 -0
  299. package/frontend/dist/minecraft-assets/items/crossbow_firework.png +0 -0
  300. package/frontend/dist/minecraft-assets/items/crossbow_pulling_0.png +0 -0
  301. package/frontend/dist/minecraft-assets/items/crossbow_pulling_1.png +0 -0
  302. package/frontend/dist/minecraft-assets/items/crossbow_pulling_2.png +0 -0
  303. package/frontend/dist/minecraft-assets/items/crossbow_standby.png +0 -0
  304. package/frontend/dist/minecraft-assets/items/cyan_candle.png +0 -0
  305. package/frontend/dist/minecraft-assets/items/cyan_dye.png +0 -0
  306. package/frontend/dist/minecraft-assets/items/danger_pottery_sherd.png +0 -0
  307. package/frontend/dist/minecraft-assets/items/dark_oak_boat.png +0 -0
  308. package/frontend/dist/minecraft-assets/items/dark_oak_chest_boat.png +0 -0
  309. package/frontend/dist/minecraft-assets/items/dark_oak_door.png +0 -0
  310. package/frontend/dist/minecraft-assets/items/dark_oak_hanging_sign.png +0 -0
  311. package/frontend/dist/minecraft-assets/items/dark_oak_sign.png +0 -0
  312. package/frontend/dist/minecraft-assets/items/diamond.png +0 -0
  313. package/frontend/dist/minecraft-assets/items/diamond_axe.png +0 -0
  314. package/frontend/dist/minecraft-assets/items/diamond_boots.png +0 -0
  315. package/frontend/dist/minecraft-assets/items/diamond_chestplate.png +0 -0
  316. package/frontend/dist/minecraft-assets/items/diamond_helmet.png +0 -0
  317. package/frontend/dist/minecraft-assets/items/diamond_hoe.png +0 -0
  318. package/frontend/dist/minecraft-assets/items/diamond_horse_armor.png +0 -0
  319. package/frontend/dist/minecraft-assets/items/diamond_leggings.png +0 -0
  320. package/frontend/dist/minecraft-assets/items/diamond_pickaxe.png +0 -0
  321. package/frontend/dist/minecraft-assets/items/diamond_shovel.png +0 -0
  322. package/frontend/dist/minecraft-assets/items/diamond_sword.png +0 -0
  323. package/frontend/dist/minecraft-assets/items/disc_fragment_5.png +0 -0
  324. package/frontend/dist/minecraft-assets/items/dragon_breath.png +0 -0
  325. package/frontend/dist/minecraft-assets/items/dried_kelp.png +0 -0
  326. package/frontend/dist/minecraft-assets/items/dune_armor_trim_smithing_template.png +0 -0
  327. package/frontend/dist/minecraft-assets/items/echo_shard.png +0 -0
  328. package/frontend/dist/minecraft-assets/items/egg.png +0 -0
  329. package/frontend/dist/minecraft-assets/items/elytra.png +0 -0
  330. package/frontend/dist/minecraft-assets/items/emerald.png +0 -0
  331. package/frontend/dist/minecraft-assets/items/empty_armor_slot_boots.png +0 -0
  332. package/frontend/dist/minecraft-assets/items/empty_armor_slot_chestplate.png +0 -0
  333. package/frontend/dist/minecraft-assets/items/empty_armor_slot_helmet.png +0 -0
  334. package/frontend/dist/minecraft-assets/items/empty_armor_slot_leggings.png +0 -0
  335. package/frontend/dist/minecraft-assets/items/empty_armor_slot_shield.png +0 -0
  336. package/frontend/dist/minecraft-assets/items/empty_slot_amethyst_shard.png +0 -0
  337. package/frontend/dist/minecraft-assets/items/empty_slot_axe.png +0 -0
  338. package/frontend/dist/minecraft-assets/items/empty_slot_diamond.png +0 -0
  339. package/frontend/dist/minecraft-assets/items/empty_slot_emerald.png +0 -0
  340. package/frontend/dist/minecraft-assets/items/empty_slot_hoe.png +0 -0
  341. package/frontend/dist/minecraft-assets/items/empty_slot_ingot.png +0 -0
  342. package/frontend/dist/minecraft-assets/items/empty_slot_lapis_lazuli.png +0 -0
  343. package/frontend/dist/minecraft-assets/items/empty_slot_pickaxe.png +0 -0
  344. package/frontend/dist/minecraft-assets/items/empty_slot_quartz.png +0 -0
  345. package/frontend/dist/minecraft-assets/items/empty_slot_redstone_dust.png +0 -0
  346. package/frontend/dist/minecraft-assets/items/empty_slot_shovel.png +0 -0
  347. package/frontend/dist/minecraft-assets/items/empty_slot_smithing_template_armor_trim.png +0 -0
  348. package/frontend/dist/minecraft-assets/items/empty_slot_smithing_template_netherite_upgrade.png +0 -0
  349. package/frontend/dist/minecraft-assets/items/empty_slot_sword.png +0 -0
  350. package/frontend/dist/minecraft-assets/items/enchanted_book.png +0 -0
  351. package/frontend/dist/minecraft-assets/items/end_crystal.png +0 -0
  352. package/frontend/dist/minecraft-assets/items/ender_eye.png +0 -0
  353. package/frontend/dist/minecraft-assets/items/ender_pearl.png +0 -0
  354. package/frontend/dist/minecraft-assets/items/experience_bottle.png +0 -0
  355. package/frontend/dist/minecraft-assets/items/explorer_pottery_sherd.png +0 -0
  356. package/frontend/dist/minecraft-assets/items/eye_armor_trim_smithing_template.png +0 -0
  357. package/frontend/dist/minecraft-assets/items/feather.png +0 -0
  358. package/frontend/dist/minecraft-assets/items/fermented_spider_eye.png +0 -0
  359. package/frontend/dist/minecraft-assets/items/filled_map.png +0 -0
  360. package/frontend/dist/minecraft-assets/items/filled_map_markings.png +0 -0
  361. package/frontend/dist/minecraft-assets/items/fire_charge.png +0 -0
  362. package/frontend/dist/minecraft-assets/items/firework_rocket.png +0 -0
  363. package/frontend/dist/minecraft-assets/items/firework_star.png +0 -0
  364. package/frontend/dist/minecraft-assets/items/firework_star_overlay.png +0 -0
  365. package/frontend/dist/minecraft-assets/items/fishing_rod.png +0 -0
  366. package/frontend/dist/minecraft-assets/items/fishing_rod_cast.png +0 -0
  367. package/frontend/dist/minecraft-assets/items/flint.png +0 -0
  368. package/frontend/dist/minecraft-assets/items/flint_and_steel.png +0 -0
  369. package/frontend/dist/minecraft-assets/items/flower_banner_pattern.png +0 -0
  370. package/frontend/dist/minecraft-assets/items/flower_pot.png +0 -0
  371. package/frontend/dist/minecraft-assets/items/friend_pottery_sherd.png +0 -0
  372. package/frontend/dist/minecraft-assets/items/furnace_minecart.png +0 -0
  373. package/frontend/dist/minecraft-assets/items/ghast_tear.png +0 -0
  374. package/frontend/dist/minecraft-assets/items/glass_bottle.png +0 -0
  375. package/frontend/dist/minecraft-assets/items/glistering_melon_slice.png +0 -0
  376. package/frontend/dist/minecraft-assets/items/globe_banner_pattern.png +0 -0
  377. package/frontend/dist/minecraft-assets/items/glow_berries.png +0 -0
  378. package/frontend/dist/minecraft-assets/items/glow_ink_sac.png +0 -0
  379. package/frontend/dist/minecraft-assets/items/glow_item_frame.png +0 -0
  380. package/frontend/dist/minecraft-assets/items/glowstone_dust.png +0 -0
  381. package/frontend/dist/minecraft-assets/items/goat_horn.png +0 -0
  382. package/frontend/dist/minecraft-assets/items/gold_ingot.png +0 -0
  383. package/frontend/dist/minecraft-assets/items/gold_nugget.png +0 -0
  384. package/frontend/dist/minecraft-assets/items/golden_apple.png +0 -0
  385. package/frontend/dist/minecraft-assets/items/golden_axe.png +0 -0
  386. package/frontend/dist/minecraft-assets/items/golden_boots.png +0 -0
  387. package/frontend/dist/minecraft-assets/items/golden_carrot.png +0 -0
  388. package/frontend/dist/minecraft-assets/items/golden_chestplate.png +0 -0
  389. package/frontend/dist/minecraft-assets/items/golden_helmet.png +0 -0
  390. package/frontend/dist/minecraft-assets/items/golden_hoe.png +0 -0
  391. package/frontend/dist/minecraft-assets/items/golden_horse_armor.png +0 -0
  392. package/frontend/dist/minecraft-assets/items/golden_leggings.png +0 -0
  393. package/frontend/dist/minecraft-assets/items/golden_pickaxe.png +0 -0
  394. package/frontend/dist/minecraft-assets/items/golden_shovel.png +0 -0
  395. package/frontend/dist/minecraft-assets/items/golden_sword.png +0 -0
  396. package/frontend/dist/minecraft-assets/items/gray_candle.png +0 -0
  397. package/frontend/dist/minecraft-assets/items/gray_dye.png +0 -0
  398. package/frontend/dist/minecraft-assets/items/green_candle.png +0 -0
  399. package/frontend/dist/minecraft-assets/items/green_dye.png +0 -0
  400. package/frontend/dist/minecraft-assets/items/gunpowder.png +0 -0
  401. package/frontend/dist/minecraft-assets/items/heart_of_the_sea.png +0 -0
  402. package/frontend/dist/minecraft-assets/items/heart_pottery_sherd.png +0 -0
  403. package/frontend/dist/minecraft-assets/items/heartbreak_pottery_sherd.png +0 -0
  404. package/frontend/dist/minecraft-assets/items/honey_bottle.png +0 -0
  405. package/frontend/dist/minecraft-assets/items/honeycomb.png +0 -0
  406. package/frontend/dist/minecraft-assets/items/hopper.png +0 -0
  407. package/frontend/dist/minecraft-assets/items/hopper_minecart.png +0 -0
  408. package/frontend/dist/minecraft-assets/items/host_armor_trim_smithing_template.png +0 -0
  409. package/frontend/dist/minecraft-assets/items/howl_pottery_sherd.png +0 -0
  410. package/frontend/dist/minecraft-assets/items/ink_sac.png +0 -0
  411. package/frontend/dist/minecraft-assets/items/iron_axe.png +0 -0
  412. package/frontend/dist/minecraft-assets/items/iron_boots.png +0 -0
  413. package/frontend/dist/minecraft-assets/items/iron_chestplate.png +0 -0
  414. package/frontend/dist/minecraft-assets/items/iron_door.png +0 -0
  415. package/frontend/dist/minecraft-assets/items/iron_helmet.png +0 -0
  416. package/frontend/dist/minecraft-assets/items/iron_hoe.png +0 -0
  417. package/frontend/dist/minecraft-assets/items/iron_horse_armor.png +0 -0
  418. package/frontend/dist/minecraft-assets/items/iron_ingot.png +0 -0
  419. package/frontend/dist/minecraft-assets/items/iron_leggings.png +0 -0
  420. package/frontend/dist/minecraft-assets/items/iron_nugget.png +0 -0
  421. package/frontend/dist/minecraft-assets/items/iron_pickaxe.png +0 -0
  422. package/frontend/dist/minecraft-assets/items/iron_shovel.png +0 -0
  423. package/frontend/dist/minecraft-assets/items/iron_sword.png +0 -0
  424. package/frontend/dist/minecraft-assets/items/item_frame.png +0 -0
  425. package/frontend/dist/minecraft-assets/items/jungle_boat.png +0 -0
  426. package/frontend/dist/minecraft-assets/items/jungle_chest_boat.png +0 -0
  427. package/frontend/dist/minecraft-assets/items/jungle_door.png +0 -0
  428. package/frontend/dist/minecraft-assets/items/jungle_hanging_sign.png +0 -0
  429. package/frontend/dist/minecraft-assets/items/jungle_sign.png +0 -0
  430. package/frontend/dist/minecraft-assets/items/kelp.png +0 -0
  431. package/frontend/dist/minecraft-assets/items/knowledge_book.png +0 -0
  432. package/frontend/dist/minecraft-assets/items/lantern.png +0 -0
  433. package/frontend/dist/minecraft-assets/items/lapis_lazuli.png +0 -0
  434. package/frontend/dist/minecraft-assets/items/lava_bucket.png +0 -0
  435. package/frontend/dist/minecraft-assets/items/lead.png +0 -0
  436. package/frontend/dist/minecraft-assets/items/leather.png +0 -0
  437. package/frontend/dist/minecraft-assets/items/leather_boots.png +0 -0
  438. package/frontend/dist/minecraft-assets/items/leather_boots_overlay.png +0 -0
  439. package/frontend/dist/minecraft-assets/items/leather_chestplate.png +0 -0
  440. package/frontend/dist/minecraft-assets/items/leather_chestplate_overlay.png +0 -0
  441. package/frontend/dist/minecraft-assets/items/leather_helmet.png +0 -0
  442. package/frontend/dist/minecraft-assets/items/leather_helmet_overlay.png +0 -0
  443. package/frontend/dist/minecraft-assets/items/leather_horse_armor.png +0 -0
  444. package/frontend/dist/minecraft-assets/items/leather_leggings.png +0 -0
  445. package/frontend/dist/minecraft-assets/items/leather_leggings_overlay.png +0 -0
  446. package/frontend/dist/minecraft-assets/items/light.png +0 -0
  447. package/frontend/dist/minecraft-assets/items/light_00.png +0 -0
  448. package/frontend/dist/minecraft-assets/items/light_01.png +0 -0
  449. package/frontend/dist/minecraft-assets/items/light_02.png +0 -0
  450. package/frontend/dist/minecraft-assets/items/light_03.png +0 -0
  451. package/frontend/dist/minecraft-assets/items/light_04.png +0 -0
  452. package/frontend/dist/minecraft-assets/items/light_05.png +0 -0
  453. package/frontend/dist/minecraft-assets/items/light_06.png +0 -0
  454. package/frontend/dist/minecraft-assets/items/light_07.png +0 -0
  455. package/frontend/dist/minecraft-assets/items/light_08.png +0 -0
  456. package/frontend/dist/minecraft-assets/items/light_09.png +0 -0
  457. package/frontend/dist/minecraft-assets/items/light_10.png +0 -0
  458. package/frontend/dist/minecraft-assets/items/light_11.png +0 -0
  459. package/frontend/dist/minecraft-assets/items/light_12.png +0 -0
  460. package/frontend/dist/minecraft-assets/items/light_13.png +0 -0
  461. package/frontend/dist/minecraft-assets/items/light_14.png +0 -0
  462. package/frontend/dist/minecraft-assets/items/light_15.png +0 -0
  463. package/frontend/dist/minecraft-assets/items/light_blue_candle.png +0 -0
  464. package/frontend/dist/minecraft-assets/items/light_blue_dye.png +0 -0
  465. package/frontend/dist/minecraft-assets/items/light_gray_candle.png +0 -0
  466. package/frontend/dist/minecraft-assets/items/light_gray_dye.png +0 -0
  467. package/frontend/dist/minecraft-assets/items/lime_candle.png +0 -0
  468. package/frontend/dist/minecraft-assets/items/lime_dye.png +0 -0
  469. package/frontend/dist/minecraft-assets/items/lingering_potion.png +0 -0
  470. package/frontend/dist/minecraft-assets/items/magenta_candle.png +0 -0
  471. package/frontend/dist/minecraft-assets/items/magenta_dye.png +0 -0
  472. package/frontend/dist/minecraft-assets/items/magma_cream.png +0 -0
  473. package/frontend/dist/minecraft-assets/items/mangrove_boat.png +0 -0
  474. package/frontend/dist/minecraft-assets/items/mangrove_chest_boat.png +0 -0
  475. package/frontend/dist/minecraft-assets/items/mangrove_door.png +0 -0
  476. package/frontend/dist/minecraft-assets/items/mangrove_hanging_sign.png +0 -0
  477. package/frontend/dist/minecraft-assets/items/mangrove_propagule.png +0 -0
  478. package/frontend/dist/minecraft-assets/items/mangrove_sign.png +0 -0
  479. package/frontend/dist/minecraft-assets/items/map.png +0 -0
  480. package/frontend/dist/minecraft-assets/items/melon_seeds.png +0 -0
  481. package/frontend/dist/minecraft-assets/items/melon_slice.png +0 -0
  482. package/frontend/dist/minecraft-assets/items/milk_bucket.png +0 -0
  483. package/frontend/dist/minecraft-assets/items/minecart.png +0 -0
  484. package/frontend/dist/minecraft-assets/items/miner_pottery_sherd.png +0 -0
  485. package/frontend/dist/minecraft-assets/items/mojang_banner_pattern.png +0 -0
  486. package/frontend/dist/minecraft-assets/items/mourner_pottery_sherd.png +0 -0
  487. package/frontend/dist/minecraft-assets/items/mushroom_stew.png +0 -0
  488. package/frontend/dist/minecraft-assets/items/music_disc_11.png +0 -0
  489. package/frontend/dist/minecraft-assets/items/music_disc_13.png +0 -0
  490. package/frontend/dist/minecraft-assets/items/music_disc_5.png +0 -0
  491. package/frontend/dist/minecraft-assets/items/music_disc_blocks.png +0 -0
  492. package/frontend/dist/minecraft-assets/items/music_disc_cat.png +0 -0
  493. package/frontend/dist/minecraft-assets/items/music_disc_chirp.png +0 -0
  494. package/frontend/dist/minecraft-assets/items/music_disc_far.png +0 -0
  495. package/frontend/dist/minecraft-assets/items/music_disc_mall.png +0 -0
  496. package/frontend/dist/minecraft-assets/items/music_disc_mellohi.png +0 -0
  497. package/frontend/dist/minecraft-assets/items/music_disc_otherside.png +0 -0
  498. package/frontend/dist/minecraft-assets/items/music_disc_pigstep.png +0 -0
  499. package/frontend/dist/minecraft-assets/items/music_disc_relic.png +0 -0
  500. package/frontend/dist/minecraft-assets/items/music_disc_stal.png +0 -0
  501. package/frontend/dist/minecraft-assets/items/music_disc_strad.png +0 -0
  502. package/frontend/dist/minecraft-assets/items/music_disc_wait.png +0 -0
  503. package/frontend/dist/minecraft-assets/items/music_disc_ward.png +0 -0
  504. package/frontend/dist/minecraft-assets/items/mutton.png +0 -0
  505. package/frontend/dist/minecraft-assets/items/name_tag.png +0 -0
  506. package/frontend/dist/minecraft-assets/items/nautilus_shell.png +0 -0
  507. package/frontend/dist/minecraft-assets/items/nether_brick.png +0 -0
  508. package/frontend/dist/minecraft-assets/items/nether_sprouts.png +0 -0
  509. package/frontend/dist/minecraft-assets/items/nether_star.png +0 -0
  510. package/frontend/dist/minecraft-assets/items/nether_wart.png +0 -0
  511. package/frontend/dist/minecraft-assets/items/netherite_axe.png +0 -0
  512. package/frontend/dist/minecraft-assets/items/netherite_boots.png +0 -0
  513. package/frontend/dist/minecraft-assets/items/netherite_chestplate.png +0 -0
  514. package/frontend/dist/minecraft-assets/items/netherite_helmet.png +0 -0
  515. package/frontend/dist/minecraft-assets/items/netherite_hoe.png +0 -0
  516. package/frontend/dist/minecraft-assets/items/netherite_ingot.png +0 -0
  517. package/frontend/dist/minecraft-assets/items/netherite_leggings.png +0 -0
  518. package/frontend/dist/minecraft-assets/items/netherite_pickaxe.png +0 -0
  519. package/frontend/dist/minecraft-assets/items/netherite_scrap.png +0 -0
  520. package/frontend/dist/minecraft-assets/items/netherite_shovel.png +0 -0
  521. package/frontend/dist/minecraft-assets/items/netherite_sword.png +0 -0
  522. package/frontend/dist/minecraft-assets/items/netherite_upgrade_smithing_template.png +0 -0
  523. package/frontend/dist/minecraft-assets/items/oak_boat.png +0 -0
  524. package/frontend/dist/minecraft-assets/items/oak_chest_boat.png +0 -0
  525. package/frontend/dist/minecraft-assets/items/oak_door.png +0 -0
  526. package/frontend/dist/minecraft-assets/items/oak_hanging_sign.png +0 -0
  527. package/frontend/dist/minecraft-assets/items/oak_sign.png +0 -0
  528. package/frontend/dist/minecraft-assets/items/orange_candle.png +0 -0
  529. package/frontend/dist/minecraft-assets/items/orange_dye.png +0 -0
  530. package/frontend/dist/minecraft-assets/items/painting.png +0 -0
  531. package/frontend/dist/minecraft-assets/items/paper.png +0 -0
  532. package/frontend/dist/minecraft-assets/items/phantom_membrane.png +0 -0
  533. package/frontend/dist/minecraft-assets/items/piglin_banner_pattern.png +0 -0
  534. package/frontend/dist/minecraft-assets/items/pink_candle.png +0 -0
  535. package/frontend/dist/minecraft-assets/items/pink_dye.png +0 -0
  536. package/frontend/dist/minecraft-assets/items/pink_petals.png +0 -0
  537. package/frontend/dist/minecraft-assets/items/pitcher_plant.png +0 -0
  538. package/frontend/dist/minecraft-assets/items/pitcher_pod.png +0 -0
  539. package/frontend/dist/minecraft-assets/items/plenty_pottery_sherd.png +0 -0
  540. package/frontend/dist/minecraft-assets/items/pointed_dripstone.png +0 -0
  541. package/frontend/dist/minecraft-assets/items/poisonous_potato.png +0 -0
  542. package/frontend/dist/minecraft-assets/items/popped_chorus_fruit.png +0 -0
  543. package/frontend/dist/minecraft-assets/items/porkchop.png +0 -0
  544. package/frontend/dist/minecraft-assets/items/potato.png +0 -0
  545. package/frontend/dist/minecraft-assets/items/potion.png +0 -0
  546. package/frontend/dist/minecraft-assets/items/potion_overlay.png +0 -0
  547. package/frontend/dist/minecraft-assets/items/powder_snow_bucket.png +0 -0
  548. package/frontend/dist/minecraft-assets/items/prismarine_crystals.png +0 -0
  549. package/frontend/dist/minecraft-assets/items/prismarine_shard.png +0 -0
  550. package/frontend/dist/minecraft-assets/items/prize_pottery_sherd.png +0 -0
  551. package/frontend/dist/minecraft-assets/items/pufferfish.png +0 -0
  552. package/frontend/dist/minecraft-assets/items/pufferfish_bucket.png +0 -0
  553. package/frontend/dist/minecraft-assets/items/pumpkin_pie.png +0 -0
  554. package/frontend/dist/minecraft-assets/items/pumpkin_seeds.png +0 -0
  555. package/frontend/dist/minecraft-assets/items/purple_candle.png +0 -0
  556. package/frontend/dist/minecraft-assets/items/purple_dye.png +0 -0
  557. package/frontend/dist/minecraft-assets/items/quartz.png +0 -0
  558. package/frontend/dist/minecraft-assets/items/rabbit.png +0 -0
  559. package/frontend/dist/minecraft-assets/items/rabbit_foot.png +0 -0
  560. package/frontend/dist/minecraft-assets/items/rabbit_hide.png +0 -0
  561. package/frontend/dist/minecraft-assets/items/rabbit_stew.png +0 -0
  562. package/frontend/dist/minecraft-assets/items/raiser_armor_trim_smithing_template.png +0 -0
  563. package/frontend/dist/minecraft-assets/items/raw_copper.png +0 -0
  564. package/frontend/dist/minecraft-assets/items/raw_gold.png +0 -0
  565. package/frontend/dist/minecraft-assets/items/raw_iron.png +0 -0
  566. package/frontend/dist/minecraft-assets/items/recovery_compass_00.png +0 -0
  567. package/frontend/dist/minecraft-assets/items/recovery_compass_01.png +0 -0
  568. package/frontend/dist/minecraft-assets/items/recovery_compass_02.png +0 -0
  569. package/frontend/dist/minecraft-assets/items/recovery_compass_03.png +0 -0
  570. package/frontend/dist/minecraft-assets/items/recovery_compass_04.png +0 -0
  571. package/frontend/dist/minecraft-assets/items/recovery_compass_05.png +0 -0
  572. package/frontend/dist/minecraft-assets/items/recovery_compass_06.png +0 -0
  573. package/frontend/dist/minecraft-assets/items/recovery_compass_07.png +0 -0
  574. package/frontend/dist/minecraft-assets/items/recovery_compass_08.png +0 -0
  575. package/frontend/dist/minecraft-assets/items/recovery_compass_09.png +0 -0
  576. package/frontend/dist/minecraft-assets/items/recovery_compass_10.png +0 -0
  577. package/frontend/dist/minecraft-assets/items/recovery_compass_11.png +0 -0
  578. package/frontend/dist/minecraft-assets/items/recovery_compass_12.png +0 -0
  579. package/frontend/dist/minecraft-assets/items/recovery_compass_13.png +0 -0
  580. package/frontend/dist/minecraft-assets/items/recovery_compass_14.png +0 -0
  581. package/frontend/dist/minecraft-assets/items/recovery_compass_15.png +0 -0
  582. package/frontend/dist/minecraft-assets/items/recovery_compass_16.png +0 -0
  583. package/frontend/dist/minecraft-assets/items/recovery_compass_17.png +0 -0
  584. package/frontend/dist/minecraft-assets/items/recovery_compass_18.png +0 -0
  585. package/frontend/dist/minecraft-assets/items/recovery_compass_19.png +0 -0
  586. package/frontend/dist/minecraft-assets/items/recovery_compass_20.png +0 -0
  587. package/frontend/dist/minecraft-assets/items/recovery_compass_21.png +0 -0
  588. package/frontend/dist/minecraft-assets/items/recovery_compass_22.png +0 -0
  589. package/frontend/dist/minecraft-assets/items/recovery_compass_23.png +0 -0
  590. package/frontend/dist/minecraft-assets/items/recovery_compass_24.png +0 -0
  591. package/frontend/dist/minecraft-assets/items/recovery_compass_25.png +0 -0
  592. package/frontend/dist/minecraft-assets/items/recovery_compass_26.png +0 -0
  593. package/frontend/dist/minecraft-assets/items/recovery_compass_27.png +0 -0
  594. package/frontend/dist/minecraft-assets/items/recovery_compass_28.png +0 -0
  595. package/frontend/dist/minecraft-assets/items/recovery_compass_29.png +0 -0
  596. package/frontend/dist/minecraft-assets/items/recovery_compass_30.png +0 -0
  597. package/frontend/dist/minecraft-assets/items/recovery_compass_31.png +0 -0
  598. package/frontend/dist/minecraft-assets/items/red_candle.png +0 -0
  599. package/frontend/dist/minecraft-assets/items/red_dye.png +0 -0
  600. package/frontend/dist/minecraft-assets/items/redstone.png +0 -0
  601. package/frontend/dist/minecraft-assets/items/repeater.png +0 -0
  602. package/frontend/dist/minecraft-assets/items/rib_armor_trim_smithing_template.png +0 -0
  603. package/frontend/dist/minecraft-assets/items/rotten_flesh.png +0 -0
  604. package/frontend/dist/minecraft-assets/items/saddle.png +0 -0
  605. package/frontend/dist/minecraft-assets/items/salmon.png +0 -0
  606. package/frontend/dist/minecraft-assets/items/salmon_bucket.png +0 -0
  607. package/frontend/dist/minecraft-assets/items/scute.png +0 -0
  608. package/frontend/dist/minecraft-assets/items/sea_pickle.png +0 -0
  609. package/frontend/dist/minecraft-assets/items/seagrass.png +0 -0
  610. package/frontend/dist/minecraft-assets/items/sentry_armor_trim_smithing_template.png +0 -0
  611. package/frontend/dist/minecraft-assets/items/shaper_armor_trim_smithing_template.png +0 -0
  612. package/frontend/dist/minecraft-assets/items/sheaf_pottery_sherd.png +0 -0
  613. package/frontend/dist/minecraft-assets/items/shears.png +0 -0
  614. package/frontend/dist/minecraft-assets/items/shelter_pottery_sherd.png +0 -0
  615. package/frontend/dist/minecraft-assets/items/shulker_shell.png +0 -0
  616. package/frontend/dist/minecraft-assets/items/silence_armor_trim_smithing_template.png +0 -0
  617. package/frontend/dist/minecraft-assets/items/skull_banner_pattern.png +0 -0
  618. package/frontend/dist/minecraft-assets/items/skull_pottery_sherd.png +0 -0
  619. package/frontend/dist/minecraft-assets/items/slime_ball.png +0 -0
  620. package/frontend/dist/minecraft-assets/items/sniffer_egg.png +0 -0
  621. package/frontend/dist/minecraft-assets/items/snort_pottery_sherd.png +0 -0
  622. package/frontend/dist/minecraft-assets/items/snout_armor_trim_smithing_template.png +0 -0
  623. package/frontend/dist/minecraft-assets/items/snowball.png +0 -0
  624. package/frontend/dist/minecraft-assets/items/soul_campfire.png +0 -0
  625. package/frontend/dist/minecraft-assets/items/soul_lantern.png +0 -0
  626. package/frontend/dist/minecraft-assets/items/spawn_egg.png +0 -0
  627. package/frontend/dist/minecraft-assets/items/spawn_egg_overlay.png +0 -0
  628. package/frontend/dist/minecraft-assets/items/spectral_arrow.png +0 -0
  629. package/frontend/dist/minecraft-assets/items/spider_eye.png +0 -0
  630. package/frontend/dist/minecraft-assets/items/spire_armor_trim_smithing_template.png +0 -0
  631. package/frontend/dist/minecraft-assets/items/splash_potion.png +0 -0
  632. package/frontend/dist/minecraft-assets/items/spruce_boat.png +0 -0
  633. package/frontend/dist/minecraft-assets/items/spruce_chest_boat.png +0 -0
  634. package/frontend/dist/minecraft-assets/items/spruce_door.png +0 -0
  635. package/frontend/dist/minecraft-assets/items/spruce_hanging_sign.png +0 -0
  636. package/frontend/dist/minecraft-assets/items/spruce_sign.png +0 -0
  637. package/frontend/dist/minecraft-assets/items/spyglass.png +0 -0
  638. package/frontend/dist/minecraft-assets/items/spyglass_model.png +0 -0
  639. package/frontend/dist/minecraft-assets/items/stick.png +0 -0
  640. package/frontend/dist/minecraft-assets/items/stone_axe.png +0 -0
  641. package/frontend/dist/minecraft-assets/items/stone_hoe.png +0 -0
  642. package/frontend/dist/minecraft-assets/items/stone_pickaxe.png +0 -0
  643. package/frontend/dist/minecraft-assets/items/stone_shovel.png +0 -0
  644. package/frontend/dist/minecraft-assets/items/stone_sword.png +0 -0
  645. package/frontend/dist/minecraft-assets/items/string.png +0 -0
  646. package/frontend/dist/minecraft-assets/items/structure_void.png +0 -0
  647. package/frontend/dist/minecraft-assets/items/sugar.png +0 -0
  648. package/frontend/dist/minecraft-assets/items/sugar_cane.png +0 -0
  649. package/frontend/dist/minecraft-assets/items/suspicious_stew.png +0 -0
  650. package/frontend/dist/minecraft-assets/items/sweet_berries.png +0 -0
  651. package/frontend/dist/minecraft-assets/items/tadpole_bucket.png +0 -0
  652. package/frontend/dist/minecraft-assets/items/tide_armor_trim_smithing_template.png +0 -0
  653. package/frontend/dist/minecraft-assets/items/tipped_arrow_base.png +0 -0
  654. package/frontend/dist/minecraft-assets/items/tipped_arrow_head.png +0 -0
  655. package/frontend/dist/minecraft-assets/items/tnt_minecart.png +0 -0
  656. package/frontend/dist/minecraft-assets/items/torchflower_seeds.png +0 -0
  657. package/frontend/dist/minecraft-assets/items/totem_of_undying.png +0 -0
  658. package/frontend/dist/minecraft-assets/items/trident.png +0 -0
  659. package/frontend/dist/minecraft-assets/items/tropical_fish.png +0 -0
  660. package/frontend/dist/minecraft-assets/items/tropical_fish_bucket.png +0 -0
  661. package/frontend/dist/minecraft-assets/items/turtle_egg.png +0 -0
  662. package/frontend/dist/minecraft-assets/items/turtle_helmet.png +0 -0
  663. package/frontend/dist/minecraft-assets/items/vex_armor_trim_smithing_template.png +0 -0
  664. package/frontend/dist/minecraft-assets/items/ward_armor_trim_smithing_template.png +0 -0
  665. package/frontend/dist/minecraft-assets/items/warped_door.png +0 -0
  666. package/frontend/dist/minecraft-assets/items/warped_fungus_on_a_stick.png +0 -0
  667. package/frontend/dist/minecraft-assets/items/warped_hanging_sign.png +0 -0
  668. package/frontend/dist/minecraft-assets/items/warped_sign.png +0 -0
  669. package/frontend/dist/minecraft-assets/items/water_bucket.png +0 -0
  670. package/frontend/dist/minecraft-assets/items/wayfinder_armor_trim_smithing_template.png +0 -0
  671. package/frontend/dist/minecraft-assets/items/wheat.png +0 -0
  672. package/frontend/dist/minecraft-assets/items/wheat_seeds.png +0 -0
  673. package/frontend/dist/minecraft-assets/items/white_candle.png +0 -0
  674. package/frontend/dist/minecraft-assets/items/white_dye.png +0 -0
  675. package/frontend/dist/minecraft-assets/items/wild_armor_trim_smithing_template.png +0 -0
  676. package/frontend/dist/minecraft-assets/items/wooden_axe.png +0 -0
  677. package/frontend/dist/minecraft-assets/items/wooden_hoe.png +0 -0
  678. package/frontend/dist/minecraft-assets/items/wooden_pickaxe.png +0 -0
  679. package/frontend/dist/minecraft-assets/items/wooden_shovel.png +0 -0
  680. package/frontend/dist/minecraft-assets/items/wooden_sword.png +0 -0
  681. package/frontend/dist/minecraft-assets/items/writable_book.png +0 -0
  682. package/frontend/dist/minecraft-assets/items/written_book.png +0 -0
  683. package/frontend/dist/minecraft-assets/items/yellow_candle.png +0 -0
  684. package/frontend/dist/minecraft-assets/items/yellow_dye.png +0 -0
  685. package/frontend/dist/monacoeditorwork/css.worker.bundle.js +7 -7
  686. package/frontend/dist/monacoeditorwork/html.worker.bundle.js +7 -7
  687. package/frontend/dist/monacoeditorwork/json.worker.bundle.js +7 -7
  688. package/frontend/dist/monacoeditorwork/ts.worker.bundle.js +3 -3
  689. package/frontend/package.json +4 -0
  690. package/package.json +1 -1
  691. package/screen/3dviewer.png +0 -0
  692. package/screen/console.png +0 -0
  693. package/screen/language_selector.png +0 -0
  694. package/.claude/agents/README.md +0 -469
  695. package/.claude/agents/auth-route-debugger.md +0 -118
  696. package/.claude/agents/auth-route-tester.md +0 -93
  697. package/.claude/agents/auto-error-resolver.md +0 -97
  698. package/.claude/agents/build-optimizer.md +0 -236
  699. package/.claude/agents/code-architect.md +0 -34
  700. package/.claude/agents/code-architecture-reviewer.md +0 -83
  701. package/.claude/agents/code-explorer.md +0 -51
  702. package/.claude/agents/code-refactor-master.md +0 -94
  703. package/.claude/agents/code-reviewer.md +0 -46
  704. package/.claude/agents/cost-optimizer.md +0 -134
  705. package/.claude/agents/deployment-orchestrator.md +0 -113
  706. package/.claude/agents/documentation-architect.md +0 -82
  707. package/.claude/agents/frontend-error-fixer.md +0 -77
  708. package/.claude/agents/iac-code-generator.md +0 -71
  709. package/.claude/agents/incident-responder.md +0 -346
  710. package/.claude/agents/infrastructure-architect.md +0 -31
  711. package/.claude/agents/kubernetes-specialist.md +0 -56
  712. package/.claude/agents/migration-planner.md +0 -181
  713. package/.claude/agents/network-architect.md +0 -196
  714. package/.claude/agents/plan-reviewer.md +0 -52
  715. package/.claude/agents/refactor-planner.md +0 -63
  716. package/.claude/agents/security-scanner.md +0 -102
  717. package/.claude/agents/web-research-specialist.md +0 -78
  718. package/.claude/commands/cost-analysis.md +0 -315
  719. package/.claude/commands/dev-docs-update.md +0 -55
  720. package/.claude/commands/dev-docs.md +0 -51
  721. package/.claude/commands/feature-dev.md +0 -125
  722. package/.claude/commands/incident-debug.md +0 -247
  723. package/.claude/commands/infra-plan.md +0 -81
  724. package/.claude/commands/migration-plan.md +0 -478
  725. package/.claude/commands/route-research-for-testing.md +0 -37
  726. package/.claude/commands/security-review.md +0 -66
  727. package/.claude/hooks/CONFIG.md +0 -448
  728. package/.claude/hooks/README.md +0 -163
  729. package/.claude/hooks/SKILL_ACTIVATION_COMPLETE.md +0 -226
  730. package/.claude/hooks/WINDOWS_HOOKS_README.md +0 -151
  731. package/.claude/hooks/add-skill-activation-banners.ts +0 -132
  732. package/.claude/hooks/comprehensive-skill-test.ts +0 -1315
  733. package/.claude/hooks/error-handling-reminder.sh +0 -12
  734. package/.claude/hooks/error-handling-reminder.ts +0 -222
  735. package/.claude/hooks/k8s-manifest-validator.sh +0 -56
  736. package/.claude/hooks/package-lock.json +0 -556
  737. package/.claude/hooks/package.json +0 -16
  738. package/.claude/hooks/post-tool-use-tracker.ps1 +0 -174
  739. package/.claude/hooks/post-tool-use-tracker.sh +0 -183
  740. package/.claude/hooks/security-policy-check.sh +0 -247
  741. package/.claude/hooks/skill-activation-prompt.ps1 +0 -10
  742. package/.claude/hooks/skill-activation-prompt.sh +0 -10
  743. package/.claude/hooks/skill-activation-prompt.ts +0 -141
  744. package/.claude/hooks/stop-build-check-enhanced.sh +0 -130
  745. package/.claude/hooks/terraform-validator.sh +0 -53
  746. package/.claude/hooks/test-input.json +0 -7
  747. package/.claude/hooks/test-skill-activation.ts +0 -427
  748. package/.claude/hooks/trigger-build-resolver.sh +0 -79
  749. package/.claude/hooks/tsc-check.sh +0 -173
  750. package/.claude/hooks/tsconfig.json +0 -19
  751. package/.claude/settings.json +0 -59
  752. package/.claude/settings.local.json +0 -47
  753. package/.claude/skills/README.md +0 -507
  754. package/.claude/skills/api-engineering/SKILL.md +0 -63
  755. package/.claude/skills/api-engineering/resources/api-versioning.md +0 -88
  756. package/.claude/skills/api-engineering/resources/graphql-patterns.md +0 -106
  757. package/.claude/skills/api-engineering/resources/rate-limiting.md +0 -118
  758. package/.claude/skills/api-engineering/resources/rest-api-design.md +0 -105
  759. package/.claude/skills/backend-dev-guidelines/SKILL.md +0 -306
  760. package/.claude/skills/backend-dev-guidelines/resources/architecture-overview.md +0 -451
  761. package/.claude/skills/backend-dev-guidelines/resources/async-and-errors.md +0 -307
  762. package/.claude/skills/backend-dev-guidelines/resources/complete-examples.md +0 -638
  763. package/.claude/skills/backend-dev-guidelines/resources/configuration.md +0 -275
  764. package/.claude/skills/backend-dev-guidelines/resources/database-patterns.md +0 -224
  765. package/.claude/skills/backend-dev-guidelines/resources/middleware-guide.md +0 -213
  766. package/.claude/skills/backend-dev-guidelines/resources/routing-and-controllers.md +0 -756
  767. package/.claude/skills/backend-dev-guidelines/resources/sentry-and-monitoring.md +0 -336
  768. package/.claude/skills/backend-dev-guidelines/resources/services-and-repositories.md +0 -789
  769. package/.claude/skills/backend-dev-guidelines/resources/testing-guide.md +0 -235
  770. package/.claude/skills/backend-dev-guidelines/resources/validation-patterns.md +0 -754
  771. package/.claude/skills/budget-and-cost-management/SKILL.md +0 -850
  772. package/.claude/skills/build-engineering/SKILL.md +0 -431
  773. package/.claude/skills/build-engineering/resources/artifact-repositories.md +0 -72
  774. package/.claude/skills/build-engineering/resources/build-caching.md +0 -96
  775. package/.claude/skills/build-engineering/resources/build-pipelines.md +0 -105
  776. package/.claude/skills/build-engineering/resources/build-security.md +0 -95
  777. package/.claude/skills/build-engineering/resources/build-systems.md +0 -389
  778. package/.claude/skills/build-engineering/resources/compilation-optimization.md +0 -201
  779. package/.claude/skills/build-engineering/resources/dependency-management.md +0 -73
  780. package/.claude/skills/build-engineering/resources/monorepo-builds.md +0 -110
  781. package/.claude/skills/build-engineering/resources/performance-optimization.md +0 -113
  782. package/.claude/skills/build-engineering/resources/reproducible-builds.md +0 -82
  783. package/.claude/skills/cloud-engineering/SKILL.md +0 -675
  784. package/.claude/skills/cloud-engineering/resources/aws-patterns.md +0 -742
  785. package/.claude/skills/cloud-engineering/resources/azure-patterns.md +0 -714
  786. package/.claude/skills/cloud-engineering/resources/cleared-cloud-environments.md +0 -987
  787. package/.claude/skills/cloud-engineering/resources/cloud-cost-optimization.md +0 -757
  788. package/.claude/skills/cloud-engineering/resources/cloud-networking.md +0 -1058
  789. package/.claude/skills/cloud-engineering/resources/cloud-security-tools.md +0 -1530
  790. package/.claude/skills/cloud-engineering/resources/cloud-security.md +0 -990
  791. package/.claude/skills/cloud-engineering/resources/gcp-patterns.md +0 -758
  792. package/.claude/skills/cloud-engineering/resources/migration-strategies.md +0 -820
  793. package/.claude/skills/cloud-engineering/resources/multi-cloud-strategies.md +0 -670
  794. package/.claude/skills/cloud-engineering/resources/oci-patterns.md +0 -1198
  795. package/.claude/skills/cloud-engineering/resources/serverless-patterns.md +0 -795
  796. package/.claude/skills/cloud-engineering/resources/well-architected-frameworks.md +0 -966
  797. package/.claude/skills/cybersecurity/SKILL.md +0 -409
  798. package/.claude/skills/cybersecurity/resources/security-architecture.md +0 -266
  799. package/.claude/skills/database-engineering/SKILL.md +0 -61
  800. package/.claude/skills/database-engineering/resources/backup-and-recovery.md +0 -72
  801. package/.claude/skills/database-engineering/resources/database-replication.md +0 -63
  802. package/.claude/skills/database-engineering/resources/postgresql-fundamentals.md +0 -70
  803. package/.claude/skills/database-engineering/resources/query-optimization.md +0 -68
  804. package/.claude/skills/devsecops/SKILL.md +0 -374
  805. package/.claude/skills/devsecops/resources/ci-cd-security.md +0 -204
  806. package/.claude/skills/devsecops/resources/compliance-automation.md +0 -530
  807. package/.claude/skills/devsecops/resources/compliance-frameworks.md +0 -2322
  808. package/.claude/skills/devsecops/resources/container-security.md +0 -915
  809. package/.claude/skills/devsecops/resources/cspm-integration.md +0 -1440
  810. package/.claude/skills/devsecops/resources/policy-enforcement.md +0 -619
  811. package/.claude/skills/devsecops/resources/secrets-management.md +0 -755
  812. package/.claude/skills/devsecops/resources/security-monitoring.md +0 -146
  813. package/.claude/skills/devsecops/resources/security-scanning.md +0 -887
  814. package/.claude/skills/devsecops/resources/security-testing.md +0 -203
  815. package/.claude/skills/devsecops/resources/supply-chain-security.md +0 -518
  816. package/.claude/skills/devsecops/resources/vulnerability-management.md +0 -481
  817. package/.claude/skills/devsecops/resources/zero-trust-architecture.md +0 -177
  818. package/.claude/skills/documentation-as-code/SKILL.md +0 -323
  819. package/.claude/skills/documentation-as-code/resources/api-documentation.md +0 -90
  820. package/.claude/skills/documentation-as-code/resources/changelog-management.md +0 -79
  821. package/.claude/skills/documentation-as-code/resources/diagram-generation.md +0 -44
  822. package/.claude/skills/documentation-as-code/resources/docs-as-code-workflow.md +0 -99
  823. package/.claude/skills/documentation-as-code/resources/documentation-automation.md +0 -68
  824. package/.claude/skills/documentation-as-code/resources/documentation-sites.md +0 -79
  825. package/.claude/skills/documentation-as-code/resources/markdown-best-practices.md +0 -162
  826. package/.claude/skills/documentation-as-code/resources/openapi-specification.md +0 -77
  827. package/.claude/skills/documentation-as-code/resources/readme-engineering.md +0 -60
  828. package/.claude/skills/documentation-as-code/resources/technical-writing-guide.md +0 -202
  829. package/.claude/skills/engineering-management/SKILL.md +0 -356
  830. package/.claude/skills/engineering-management/resources/career-ladders.md +0 -609
  831. package/.claude/skills/engineering-management/resources/hiring-and-assessment.md +0 -555
  832. package/.claude/skills/engineering-management/resources/one-on-one-guides.md +0 -609
  833. package/.claude/skills/engineering-management/resources/resource-planning.md +0 -557
  834. package/.claude/skills/engineering-management/resources/team-organization-patterns.md +0 -491
  835. package/.claude/skills/engineering-management/resources/technical-interviews.md +0 -474
  836. package/.claude/skills/engineering-operations-management/SKILL.md +0 -817
  837. package/.claude/skills/error-tracking/SKILL.md +0 -379
  838. package/.claude/skills/frontend-design/SKILL.md +0 -42
  839. package/.claude/skills/frontend-dev-guidelines/SKILL.md +0 -403
  840. package/.claude/skills/frontend-dev-guidelines/resources/common-patterns.md +0 -331
  841. package/.claude/skills/frontend-dev-guidelines/resources/complete-examples.md +0 -872
  842. package/.claude/skills/frontend-dev-guidelines/resources/component-patterns.md +0 -502
  843. package/.claude/skills/frontend-dev-guidelines/resources/data-fetching.md +0 -767
  844. package/.claude/skills/frontend-dev-guidelines/resources/file-organization.md +0 -502
  845. package/.claude/skills/frontend-dev-guidelines/resources/loading-and-error-states.md +0 -501
  846. package/.claude/skills/frontend-dev-guidelines/resources/performance.md +0 -406
  847. package/.claude/skills/frontend-dev-guidelines/resources/routing-guide.md +0 -364
  848. package/.claude/skills/frontend-dev-guidelines/resources/styling-guide.md +0 -428
  849. package/.claude/skills/frontend-dev-guidelines/resources/typescript-standards.md +0 -418
  850. package/.claude/skills/general-it-engineering/SKILL.md +0 -393
  851. package/.claude/skills/general-it-engineering/resources/asset-management.md +0 -712
  852. package/.claude/skills/general-it-engineering/resources/automation-orchestration.md +0 -817
  853. package/.claude/skills/general-it-engineering/resources/business-continuity.md +0 -786
  854. package/.claude/skills/general-it-engineering/resources/change-management.md +0 -715
  855. package/.claude/skills/general-it-engineering/resources/enterprise-monitoring.md +0 -729
  856. package/.claude/skills/general-it-engineering/resources/help-desk-operations.md +0 -738
  857. package/.claude/skills/general-it-engineering/resources/incident-service-management.md +0 -834
  858. package/.claude/skills/general-it-engineering/resources/it-governance.md +0 -753
  859. package/.claude/skills/general-it-engineering/resources/itil-framework.md +0 -503
  860. package/.claude/skills/general-it-engineering/resources/service-management.md +0 -669
  861. package/.claude/skills/infrastructure-architecture/SKILL.md +0 -328
  862. package/.claude/skills/infrastructure-architecture/resources/architecture-decision-records.md +0 -505
  863. package/.claude/skills/infrastructure-architecture/resources/architecture-patterns.md +0 -528
  864. package/.claude/skills/infrastructure-architecture/resources/capacity-planning.md +0 -453
  865. package/.claude/skills/infrastructure-architecture/resources/cleared-environment-architecture.md +0 -773
  866. package/.claude/skills/infrastructure-architecture/resources/cost-architecture.md +0 -499
  867. package/.claude/skills/infrastructure-architecture/resources/data-architecture.md +0 -501
  868. package/.claude/skills/infrastructure-architecture/resources/disaster-recovery.md +0 -535
  869. package/.claude/skills/infrastructure-architecture/resources/migration-architecture.md +0 -512
  870. package/.claude/skills/infrastructure-architecture/resources/multi-region-design.md +0 -608
  871. package/.claude/skills/infrastructure-architecture/resources/reference-architectures.md +0 -562
  872. package/.claude/skills/infrastructure-architecture/resources/security-architecture.md +0 -538
  873. package/.claude/skills/infrastructure-architecture/resources/system-design-principles.md +0 -489
  874. package/.claude/skills/infrastructure-architecture/resources/workload-classification.md +0 -1000
  875. package/.claude/skills/infrastructure-strategy/SKILL.md +0 -924
  876. package/.claude/skills/network-engineering/SKILL.md +0 -385
  877. package/.claude/skills/network-engineering/resources/dns-management.md +0 -738
  878. package/.claude/skills/network-engineering/resources/load-balancing.md +0 -820
  879. package/.claude/skills/network-engineering/resources/network-architecture.md +0 -546
  880. package/.claude/skills/network-engineering/resources/network-security.md +0 -921
  881. package/.claude/skills/network-engineering/resources/network-troubleshooting.md +0 -749
  882. package/.claude/skills/network-engineering/resources/routing-switching.md +0 -373
  883. package/.claude/skills/network-engineering/resources/sdn-networking.md +0 -695
  884. package/.claude/skills/network-engineering/resources/service-mesh-networking.md +0 -777
  885. package/.claude/skills/network-engineering/resources/tcp-ip-protocols.md +0 -444
  886. package/.claude/skills/network-engineering/resources/vpn-connectivity.md +0 -672
  887. package/.claude/skills/observability-engineering/SKILL.md +0 -101
  888. package/.claude/skills/observability-engineering/resources/apm-tools.md +0 -97
  889. package/.claude/skills/observability-engineering/resources/correlation-strategies.md +0 -87
  890. package/.claude/skills/observability-engineering/resources/distributed-tracing.md +0 -98
  891. package/.claude/skills/observability-engineering/resources/logs-aggregation.md +0 -118
  892. package/.claude/skills/observability-engineering/resources/observability-cost-optimization.md +0 -141
  893. package/.claude/skills/observability-engineering/resources/opentelemetry.md +0 -110
  894. package/.claude/skills/platform-engineering/SKILL.md +0 -555
  895. package/.claude/skills/platform-engineering/resources/architecture-overview.md +0 -600
  896. package/.claude/skills/platform-engineering/resources/container-orchestration.md +0 -916
  897. package/.claude/skills/platform-engineering/resources/cost-optimization.md +0 -634
  898. package/.claude/skills/platform-engineering/resources/developer-platforms.md +0 -670
  899. package/.claude/skills/platform-engineering/resources/gitops-automation.md +0 -650
  900. package/.claude/skills/platform-engineering/resources/infrastructure-as-code.md +0 -778
  901. package/.claude/skills/platform-engineering/resources/infrastructure-standards.md +0 -708
  902. package/.claude/skills/platform-engineering/resources/multi-tenancy.md +0 -602
  903. package/.claude/skills/platform-engineering/resources/platform-security.md +0 -711
  904. package/.claude/skills/platform-engineering/resources/resource-management.md +0 -592
  905. package/.claude/skills/platform-engineering/resources/service-mesh.md +0 -628
  906. package/.claude/skills/release-engineering/SKILL.md +0 -393
  907. package/.claude/skills/release-engineering/resources/artifact-management.md +0 -108
  908. package/.claude/skills/release-engineering/resources/build-optimization.md +0 -84
  909. package/.claude/skills/release-engineering/resources/ci-cd-pipelines.md +0 -411
  910. package/.claude/skills/release-engineering/resources/deployment-strategies.md +0 -197
  911. package/.claude/skills/release-engineering/resources/pipeline-security.md +0 -62
  912. package/.claude/skills/release-engineering/resources/progressive-delivery.md +0 -83
  913. package/.claude/skills/release-engineering/resources/release-automation.md +0 -68
  914. package/.claude/skills/release-engineering/resources/release-orchestration.md +0 -77
  915. package/.claude/skills/release-engineering/resources/rollback-strategies.md +0 -66
  916. package/.claude/skills/release-engineering/resources/versioning-strategies.md +0 -59
  917. package/.claude/skills/route-tester/SKILL.md +0 -392
  918. package/.claude/skills/skill-developer/ADVANCED.md +0 -197
  919. package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +0 -306
  920. package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +0 -152
  921. package/.claude/skills/skill-developer/SKILL.md +0 -430
  922. package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +0 -315
  923. package/.claude/skills/skill-developer/TRIGGER_TYPES.md +0 -305
  924. package/.claude/skills/skill-developer/TROUBLESHOOTING.md +0 -514
  925. package/.claude/skills/skill-rules.json +0 -2940
  926. package/.claude/skills/sre/SKILL.md +0 -464
  927. package/.claude/skills/sre/resources/alerting-best-practices.md +0 -282
  928. package/.claude/skills/sre/resources/capacity-planning.md +0 -226
  929. package/.claude/skills/sre/resources/chaos-engineering.md +0 -193
  930. package/.claude/skills/sre/resources/disaster-recovery.md +0 -232
  931. package/.claude/skills/sre/resources/incident-management.md +0 -436
  932. package/.claude/skills/sre/resources/observability-stack.md +0 -240
  933. package/.claude/skills/sre/resources/on-call-runbooks.md +0 -167
  934. package/.claude/skills/sre/resources/performance-optimization.md +0 -108
  935. package/.claude/skills/sre/resources/reliability-patterns.md +0 -183
  936. package/.claude/skills/sre/resources/slo-sli-sla.md +0 -464
  937. package/.claude/skills/sre/resources/toil-reduction.md +0 -145
  938. package/.claude/skills/systems-engineering/SKILL.md +0 -648
  939. package/.claude/skills/systems-engineering/resources/automation-patterns.md +0 -771
  940. package/.claude/skills/systems-engineering/resources/configuration-management.md +0 -998
  941. package/.claude/skills/systems-engineering/resources/linux-administration.md +0 -672
  942. package/.claude/skills/systems-engineering/resources/networking-fundamentals.md +0 -982
  943. package/.claude/skills/systems-engineering/resources/performance-tuning.md +0 -871
  944. package/.claude/skills/systems-engineering/resources/powershell-scripting.md +0 -482
  945. package/.claude/skills/systems-engineering/resources/security-hardening.md +0 -739
  946. package/.claude/skills/systems-engineering/resources/shell-scripting.md +0 -915
  947. package/.claude/skills/systems-engineering/resources/storage-management.md +0 -628
  948. package/.claude/skills/systems-engineering/resources/system-monitoring.md +0 -787
  949. package/.claude/skills/systems-engineering/resources/troubleshooting-guide.md +0 -753
  950. package/.claude/skills/systems-engineering/resources/windows-administration.md +0 -738
  951. package/.claude/skills/technical-leadership/SKILL.md +0 -728
  952. package/backend/docs/SECRETS_DOCUMENTATION.md +0 -327
  953. package/frontend/dist/assets/index-DqzDkFsP.js +0 -11210
  954. package/frontend/dist/assets/index-t6K1u4OV.css +0 -32
@@ -13,6 +13,122 @@ const { botManager } = require('../../core/services');
13
13
  // Хранилище истории чатов в памяти: Map<"botId_pluginName", messages[]>
14
14
  const chatHistoryStore = new Map();
15
15
 
16
+ const MAX_HISTORY_MESSAGES = 300;
17
+
18
+ /**
19
+ * Обрезает историю сообщений до MAX_HISTORY_MESSAGES (защита от memory leak)
20
+ * @param {Array} history - Массив сообщений
21
+ * @param {string} chatKey - Ключ чата для логирования
22
+ */
23
+ function trimHistory(history, chatKey) {
24
+ if (history.length > MAX_HISTORY_MESSAGES) {
25
+ history.splice(0, history.length - MAX_HISTORY_MESSAGES);
26
+ console.log(`[AI Chat] History trimmed to ${MAX_HISTORY_MESSAGES} messages for ${chatKey}`);
27
+ }
28
+ }
29
+
30
+ const rateLimitStore = new Map();
31
+ const RATE_LIMIT_MAX_REQUESTS = 30;
32
+ const RATE_LIMIT_WINDOW_MS = 60 * 1000;
33
+
34
+ // Очистка устаревших записей каждые 5 минут (защита от утечки памяти)
35
+ setInterval(() => {
36
+ const now = Date.now();
37
+ for (const [key, record] of rateLimitStore.entries()) {
38
+ if (now > record.resetTime) {
39
+ rateLimitStore.delete(key);
40
+ }
41
+ }
42
+ }, 5 * 60 * 1000);
43
+
44
+ /**
45
+ * Проверка rate limit для AI запросов
46
+ * @param {string} key - Ключ (например, "botId_pluginName")
47
+ * @returns {boolean} - true если запрос разрешен, false если превышен лимит
48
+ */
49
+ function checkRateLimit(key) {
50
+ const now = Date.now();
51
+ const record = rateLimitStore.get(key);
52
+
53
+ if (!record || now > record.resetTime) {
54
+ rateLimitStore.set(key, {
55
+ count: 1,
56
+ resetTime: now + RATE_LIMIT_WINDOW_MS
57
+ });
58
+ return true;
59
+ }
60
+
61
+ if (record.count >= RATE_LIMIT_MAX_REQUESTS) {
62
+ return false;
63
+ }
64
+
65
+ record.count += 1;
66
+ return true;
67
+ }
68
+
69
+ /**
70
+ * Получить оставшееся время до сброса rate limit (в секундах)
71
+ */
72
+ function getRateLimitResetTime(key) {
73
+ const record = rateLimitStore.get(key);
74
+ if (!record) return 0;
75
+
76
+ const now = Date.now();
77
+ const remaining = Math.max(0, record.resetTime - now);
78
+ return Math.ceil(remaining / 1000);
79
+ }
80
+
81
+ /**
82
+ * Валидация и нормализация AI параметров (temperature, maxTokens)
83
+ */
84
+ function validateAIParams(temperature, maxTokens, maxTokenLimit = 4096) {
85
+ let effectiveTemperature = 0.7;
86
+ if (temperature !== undefined) {
87
+ const temp = Number(temperature);
88
+ if (!isFinite(temp) || temp < 0 || temp > 2) {
89
+ return { error: 'Temperature must be a number between 0 and 2.' };
90
+ }
91
+ effectiveTemperature = temp;
92
+ }
93
+ let effectiveMaxTokens = 4096;
94
+ if (maxTokens !== undefined) {
95
+ const tokens = Number(maxTokens);
96
+ if (!isFinite(tokens) || tokens < 256) {
97
+ return { error: 'maxTokens must be a number >= 256.' };
98
+ }
99
+ effectiveMaxTokens = Math.min(tokens, maxTokenLimit);
100
+ }
101
+
102
+ return { effectiveTemperature, effectiveMaxTokens };
103
+ }
104
+
105
+ /**
106
+ * Простое форматирование JS кода
107
+ * - Нормализует line endings (CRLF -> LF)
108
+ * - Убирает trailing whitespace
109
+ * - Обеспечивает newline в конце файла
110
+ * - Убирает множественные пустые строки (оставляет максимум 2)
111
+ */
112
+ function simpleFormatCode(content, filePath) {
113
+ // Только для JS файлов
114
+ if (!filePath.endsWith('.js') && !filePath.endsWith('.mjs') && !filePath.endsWith('.cjs')) {
115
+ return content;
116
+ }
117
+
118
+ let formatted = content;
119
+ formatted = formatted.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
120
+
121
+ formatted = formatted.split('\n').map(line => line.trimEnd()).join('\n');
122
+
123
+ formatted = formatted.replace(/\n{4,}/g, '\n\n\n');
124
+
125
+ if (!formatted.endsWith('\n')) {
126
+ formatted += '\n';
127
+ }
128
+
129
+ return formatted;
130
+ }
131
+
16
132
  /**
17
133
  * Конвертирует JSON Schema параметры в формат Gemini
18
134
  */
@@ -96,7 +212,7 @@ function parseProxyString(proxyString) {
96
212
 
97
213
  return {
98
214
  host: host,
99
- port: parseInt(port),
215
+ port: parseInt(port, 10),
100
216
  user: user,
101
217
  pass: pass
102
218
  };
@@ -106,7 +222,6 @@ function parseProxyString(proxyString) {
106
222
  }
107
223
  }
108
224
 
109
- // Список игнорируемых файлов/папок для сканирования проекта
110
225
  const IGNORE_LIST = [
111
226
  'node_modules/',
112
227
  'package-lock.json',
@@ -121,9 +236,41 @@ const IGNORE_LIST = [
121
236
  '.claude/'
122
237
  ];
123
238
 
124
- // Вспомогательная функция для проверки игнорирования
239
+ /**
240
+ * Строгая проверка безопасности пути (защита от path traversal)
241
+ * @param {string} basePath - Базовая директория (например, pluginPath)
242
+ * @param {string} userPath - Путь от пользователя
243
+ * @returns {string|null} - Безопасный абсолютный путь или null если небезопасно
244
+ */
245
+ function validateSafePath(basePath, userPath) {
246
+ // Проверяем что userPath не пустой
247
+ if (!userPath || typeof userPath !== 'string') {
248
+ return null;
249
+ }
250
+
251
+ // Проверяем на опасные символы
252
+ if (userPath.includes('\0') || userPath.includes('\x00')) {
253
+ return null;
254
+ }
255
+
256
+ // Нормализуем пути
257
+ const normalizedBase = path.normalize(basePath);
258
+ const resolvedPath = path.resolve(basePath, userPath);
259
+ const normalizedResolved = path.normalize(resolvedPath);
260
+
261
+ // Проверяем что путь начинается с базового пути
262
+ // Используем path.relative чтобы проверить что файл внутри базовой директории
263
+ const relativePath = path.relative(normalizedBase, normalizedResolved);
264
+
265
+ // Если relative path начинается с '..' или является абсолютным, значит файл вне базовой директории
266
+ if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
267
+ return null;
268
+ }
269
+
270
+ return normalizedResolved;
271
+ }
272
+
125
273
  function shouldIgnore(filePath, ignoreList) {
126
- // Нормализуем путь к forward slashes для кроссплатформенности
127
274
  const normalizedPath = filePath.replace(/\\/g, '/');
128
275
 
129
276
  return ignoreList.some(pattern => {
@@ -143,7 +290,6 @@ function shouldIgnore(filePath, ignoreList) {
143
290
  });
144
291
  }
145
292
 
146
- // Получить все файлы рекурсивно
147
293
  function getAllFilesRecursive(dir, basePath = dir, fileList = [], ignoreList = []) {
148
294
  const files = fse.readdirSync(dir);
149
295
 
@@ -165,7 +311,6 @@ function getAllFilesRecursive(dir, basePath = dir, fileList = [], ignoreList = [
165
311
  return fileList;
166
312
  }
167
313
 
168
- // Получить древовидную структуру
169
314
  function getTreeStructure(dir, basePath = dir, prefix = '', ignoreList = []) {
170
315
  const files = fse.readdirSync(dir);
171
316
  let result = '';
@@ -192,7 +337,6 @@ function getTreeStructure(dir, basePath = dir, prefix = '', ignoreList = []) {
192
337
  return result;
193
338
  }
194
339
 
195
- // Debug middleware
196
340
  router.use((req, res, next) => {
197
341
  console.log('[AI Assistant Router] Request:', req.method, req.path, 'Params:', req.params);
198
342
  next();
@@ -206,13 +350,24 @@ async function resolvePluginPath(req, res, next) {
206
350
  console.log('resolvePluginPath - botId:', req.params.botId, 'pluginName:', req.params.pluginName);
207
351
  const { botId, pluginName } = req.params;
208
352
 
353
+ // Валидация botId (защита от SQL Injection)
354
+ const botIdNum = parseInt(botId, 10);
355
+ if (isNaN(botIdNum) || botIdNum <= 0 || botIdNum.toString() !== botId) {
356
+ return res.status(400).json({ error: 'Invalid bot ID.' });
357
+ }
358
+
209
359
  if (!pluginName) {
210
360
  return res.status(400).json({ error: 'Имя плагина обязательно в пути.' });
211
361
  }
212
362
 
363
+ // Валидация pluginName (защита от path traversal в имени)
364
+ if (pluginName.includes('..') || pluginName.includes('/') || pluginName.includes('\\')) {
365
+ return res.status(400).json({ error: 'Invalid plugin name.' });
366
+ }
367
+
213
368
  const plugin = await prisma.installedPlugin.findFirst({
214
369
  where: {
215
- botId: parseInt(botId),
370
+ botId: botIdNum,
216
371
  name: pluginName
217
372
  }
218
373
  });
@@ -232,6 +387,7 @@ async function resolvePluginPath(req, res, next) {
232
387
 
233
388
  console.log('Plugin path found, proceeding to route handler');
234
389
  req.pluginPath = pluginPath;
390
+ req.botIdNum = botIdNum; // Сохраняем валидированный botId
235
391
  next();
236
392
  } catch (error) {
237
393
  console.error('Error in resolvePluginPath:', error);
@@ -239,10 +395,8 @@ async function resolvePluginPath(req, res, next) {
239
395
  }
240
396
  }
241
397
 
242
- // Создаем tools для AI ассистента
243
- function createPluginTools(pluginPath, res, botId) {
244
- return [
245
- // Tool 1: Получить древовидную структуру проекта
398
+ function createPluginTools(pluginPath, res, botId, applyMode = 'immediate', autoFormat = false) {
399
+ const baseTools = [
246
400
  {
247
401
  type: 'function',
248
402
  function: {
@@ -271,7 +425,6 @@ function createPluginTools(pluginPath, res, botId) {
271
425
  }
272
426
  },
273
427
 
274
- // Tool 2: Получить полный контекст проекта
275
428
  {
276
429
  type: 'function',
277
430
  function: {
@@ -294,9 +447,27 @@ function createPluginTools(pluginPath, res, botId) {
294
447
  result += `Всего файлов: ${allFiles.length}\n\n`;
295
448
  result += `Содержимое файлов:\n\n`;
296
449
 
450
+ // Ограничения для защиты от переполнения памяти
451
+ const MAX_FILE_SIZE = 100 * 1024; // 100KB на файл
452
+ const MAX_TOTAL_SIZE = 1024 * 1024; // 1MB общий размер
453
+ let totalSize = 0;
454
+
297
455
  for (const file of allFiles) {
298
456
  const fullPath = path.join(pluginPath, file);
457
+
458
+ const stats = await fse.stat(fullPath);
459
+ if (stats.size > MAX_FILE_SIZE) {
460
+ result += `=== Файл: ${file} === (пропущен: размер ${stats.size} байт превышает лимит ${MAX_FILE_SIZE})\n\n`;
461
+ continue;
462
+ }
463
+
464
+ if (totalSize + stats.size > MAX_TOTAL_SIZE) {
465
+ result += `\n(достигнут лимит размера ответа ${MAX_TOTAL_SIZE} байт, остальные файлы пропущены)\n`;
466
+ break;
467
+ }
468
+
299
469
  const fileContent = await fse.readFile(fullPath, 'utf8');
470
+ totalSize += fileContent.length;
300
471
  result += `=== Файл: ${file} ===\n${fileContent}\n\n`;
301
472
  }
302
473
 
@@ -307,7 +478,6 @@ function createPluginTools(pluginPath, res, botId) {
307
478
  }
308
479
  },
309
480
 
310
- // Tool 2: Прочитать конкретный файл
311
481
  {
312
482
  type: 'function',
313
483
  function: {
@@ -327,12 +497,10 @@ function createPluginTools(pluginPath, res, botId) {
327
497
  execute: async (args) => {
328
498
  console.log('readFile called with:', args.filePath);
329
499
  try {
330
- const safePath = path.resolve(pluginPath, args.filePath);
331
-
332
- // Проверка безопасности - файл должен быть внутри pluginPath
333
- const normalizedPluginPath = pluginPath.endsWith(path.sep) ? pluginPath : pluginPath + path.sep;
334
- if (!safePath.startsWith(normalizedPluginPath) && safePath !== pluginPath) {
335
- return `Ошибка: Доступ запрещен. Файл находится за пределами плагина.`;
500
+ // Используем строгую проверку безопасности (защита от path traversal)
501
+ const safePath = validateSafePath(pluginPath, args.filePath);
502
+ if (!safePath) {
503
+ return `Ошибка: Доступ запрещен. Недопустимый путь к файлу.`;
336
504
  }
337
505
 
338
506
  if (!await fse.pathExists(safePath)) {
@@ -347,7 +515,6 @@ function createPluginTools(pluginPath, res, botId) {
347
515
  }
348
516
  },
349
517
 
350
- // Tool 3: Обновить содержимое файла
351
518
  {
352
519
  type: 'function',
353
520
  function: {
@@ -369,14 +536,19 @@ function createPluginTools(pluginPath, res, botId) {
369
536
  }
370
537
  },
371
538
  execute: async (args, context) => {
372
- console.log('updateFile called for:', args.filePath);
373
- try {
374
- const safePath = path.resolve(pluginPath, args.filePath);
539
+ console.log('updateFile called for:', args.filePath, 'applyMode:', applyMode, 'autoFormat:', autoFormat);
540
+
541
+ let content = args.content;
542
+ if (autoFormat) {
543
+ content = simpleFormatCode(content, args.filePath);
544
+ console.log('Auto-formatted content for:', args.filePath);
545
+ }
375
546
 
376
- // Проверка безопасности - файл должен быть внутри pluginPath
377
- const normalizedPluginPath = pluginPath.endsWith(path.sep) ? pluginPath : pluginPath + path.sep;
378
- if (!safePath.startsWith(normalizedPluginPath) && safePath !== pluginPath) {
379
- return `Ошибка: Доступ запрещен. Файл находится за пределами плагина.`;
547
+ try {
548
+ // Используем строгую проверку безопасности (защита от path traversal)
549
+ const safePath = validateSafePath(pluginPath, args.filePath);
550
+ if (!safePath) {
551
+ return `Ошибка: Доступ запрещен. Недопустимый путь к файлу.`;
380
552
  }
381
553
 
382
554
  // Читаем старое содержимое для подсчёта diff
@@ -390,34 +562,24 @@ function createPluginTools(pluginPath, res, botId) {
390
562
  } else {
391
563
  isNewFile = true;
392
564
  }
393
-
394
- // Создаем директорию если не существует
395
- await fse.ensureDir(path.dirname(safePath));
396
-
397
- // Записываем новое содержимое
398
- await fse.writeFile(safePath, args.content, 'utf8');
399
-
400
- // Вычисляем реальные изменённые строки используя diff
401
- const newLines = args.content.split('\n');
565
+
566
+ const newLines = content.split('\n');
402
567
  let linesAdded = 0;
403
568
  let linesRemoved = 0;
404
569
  let changedLineRanges = []; // Массив объектов { start: number, end: number }
405
570
 
406
571
  if (isNewFile) {
407
572
  linesAdded = newLines.length;
408
- // Все строки нового файла - это добавленные строки
409
573
  changedLineRanges = [{ start: 1, end: newLines.length }];
410
574
  } else {
411
- // Используем библиотеку diff для вычисления изменений
412
- const diffResult = Diff.diffLines(oldContent, args.content);
575
+ const diffResult = Diff.diffLines(oldContent, content);
413
576
 
414
- let currentLine = 1; // Текущая строка в новом файле
577
+ let currentLine = 1;
415
578
 
416
579
  diffResult.forEach(part => {
417
580
  const lineCount = part.count || 0;
418
581
 
419
582
  if (part.added) {
420
- // Добавленные строки
421
583
  linesAdded += lineCount;
422
584
  changedLineRanges.push({
423
585
  start: currentLine,
@@ -425,29 +587,58 @@ function createPluginTools(pluginPath, res, botId) {
425
587
  });
426
588
  currentLine += lineCount;
427
589
  } else if (part.removed) {
428
- // Удалённые строки (не увеличиваем currentLine)
429
590
  linesRemoved += lineCount;
430
591
  } else {
431
- // Неизменённые строки
432
592
  currentLine += lineCount;
433
593
  }
434
594
  });
435
595
  }
436
596
 
437
- // Отправляем событие на фронтенд для обновления редактора
597
+ if (applyMode === 'preview') {
598
+ const sseEvent = {
599
+ type: 'file_preview',
600
+ filePath: args.filePath,
601
+ newContent: content,
602
+ oldContent: oldContent,
603
+ linesAdded,
604
+ linesRemoved,
605
+ isNewFile,
606
+ changedLineRanges
607
+ };
608
+ console.log('Sending SSE event file_preview:', {
609
+ filePath: args.filePath,
610
+ contentLength: content.length,
611
+ linesAdded,
612
+ linesRemoved,
613
+ isNewFile
614
+ });
615
+ res.write(`data: ${JSON.stringify(sseEvent)}\n\n`);
616
+
617
+ if (isNewFile) {
618
+ return `[ОЖИДАЕТ ПОДТВЕРЖДЕНИЯ] Предложено создание файла "${args.filePath}" (${newLines.length} строк). Файл ЕЩЁ НЕ создан - пользователь должен нажать "Применить" чтобы подтвердить. В своём ответе пользователю скажи что ты ПРЕДЛАГАЕШЬ создать файл и жди его решения. НЕ говори что файл создан.`;
619
+ } else {
620
+ return `[ОЖИДАЕТ ПОДТВЕРЖДЕНИЯ] Предложено обновление файла "${args.filePath}" (+${linesAdded} -${linesRemoved} строк). Файл ЕЩЁ НЕ изменён - пользователь должен нажать "Применить" чтобы подтвердить. В своём ответе пользователю скажи что ты ПРЕДЛАГАЕШЬ изменения и жди его решения. НЕ говори что изменения применены.`;
621
+ }
622
+ }
623
+
624
+ // Immediate mode - записываем файл сразу
625
+ await fse.ensureDir(path.dirname(safePath));
626
+
627
+ await fse.writeFile(safePath, content, 'utf8');
628
+
438
629
  const sseEvent = {
439
630
  type: 'file_updated',
440
631
  filePath: args.filePath,
441
- newContent: args.content,
632
+ newContent: content,
442
633
  oldContent: oldContent,
443
634
  linesAdded,
444
635
  linesRemoved,
445
636
  isNewFile,
446
- changedLineRanges // Добавляем точные диапазоны изменённых строк
637
+ changedLineRanges
447
638
  };
448
639
  console.log('Sending SSE event file_updated:', {
449
640
  filePath: args.filePath,
450
- contentLength: args.content.length,
641
+ contentLength: content.length,
451
642
  linesAdded,
452
643
  linesRemoved,
453
644
  isNewFile,
@@ -457,7 +648,7 @@ function createPluginTools(pluginPath, res, botId) {
457
648
  console.log('SSE event sent successfully');
458
649
 
459
650
  if (isNewFile) {
460
- return `Создан новый файл "${args.filePath}". Размер: ${args.content.length} символов (${newLines.length} строк).`;
651
+ return `Создан новый файл "${args.filePath}". Размер: ${content.length} символов (${newLines.length} строк).`;
461
652
  } else {
462
653
  return `Успешно обновлен файл "${args.filePath}". +${linesAdded} -${linesRemoved} строк.`;
463
654
  }
@@ -468,7 +659,6 @@ function createPluginTools(pluginPath, res, botId) {
468
659
  }
469
660
  },
470
661
 
471
- // Tool 4: Прочитать логи бота (чат из игры и console.log)
472
662
  {
473
663
  type: 'function',
474
664
  function: {
@@ -499,10 +689,8 @@ function createPluginTools(pluginPath, res, botId) {
499
689
  return 'Логи бота пусты. Возможно бот ещё не запущен или не было активности.';
500
690
  }
501
691
 
502
- // Берём последние N записей
503
692
  let filteredLogs = logs.slice(-limit);
504
693
 
505
- // Применяем фильтр если указан
506
694
  if (args.filter) {
507
695
  const filterLower = args.filter.toLowerCase();
508
696
  filteredLogs = filteredLogs.filter(log => {
@@ -515,7 +703,6 @@ function createPluginTools(pluginPath, res, botId) {
515
703
  return `Логи не найдены${args.filter ? ` по фильтру "${args.filter}"` : ''}.`;
516
704
  }
517
705
 
518
- // Форматируем логи
519
706
  const formattedLogs = filteredLogs.map(log => {
520
707
  if (typeof log === 'string') {
521
708
  return log;
@@ -536,7 +723,6 @@ function createPluginTools(pluginPath, res, botId) {
536
723
  }
537
724
  },
538
725
 
539
- // Tool 5: Удалить файл
540
726
  {
541
727
  type: 'function',
542
728
  function: {
@@ -556,12 +742,10 @@ function createPluginTools(pluginPath, res, botId) {
556
742
  execute: async (args) => {
557
743
  console.log('deleteFile called for:', args.filePath);
558
744
  try {
559
- const safePath = path.resolve(pluginPath, args.filePath);
560
-
561
- // Проверка безопасности - файл должен быть внутри pluginPath
562
- const normalizedPluginPath = pluginPath.endsWith(path.sep) ? pluginPath : pluginPath + path.sep;
563
- if (!safePath.startsWith(normalizedPluginPath) && safePath !== pluginPath) {
564
- return `Ошибка: Доступ запрещен. Файл находится за пределами плагина.`;
745
+ // Используем строгую проверку безопасности (защита от path traversal)
746
+ const safePath = validateSafePath(pluginPath, args.filePath);
747
+ if (!safePath) {
748
+ return `Ошибка: Доступ запрещен. Недопустимый путь к файлу.`;
565
749
  }
566
750
 
567
751
  // Проверяем что путь существует
@@ -593,7 +777,122 @@ function createPluginTools(pluginPath, res, botId) {
593
777
  }
594
778
  },
595
779
 
596
- // Tool 6: Удалить папку
780
+ {
781
+ type: 'function',
782
+ function: {
783
+ name: 'searchCode',
784
+ description: 'Ищет текст или регулярное выражение в файлах плагина. Полезно для поиска функций, переменных, использований и паттернов в коде.',
785
+ parameters: {
786
+ type: 'object',
787
+ properties: {
788
+ query: {
789
+ type: 'string',
790
+ description: 'Текст или регулярное выражение для поиска'
791
+ },
792
+ type: {
793
+ type: 'string',
794
+ enum: ['text', 'regex'],
795
+ description: 'Тип поиска: text (точное совпадение) или regex (регулярное выражение). По умолчанию text.'
796
+ },
797
+ filePattern: {
798
+ type: 'string',
799
+ description: 'Паттерн файлов для поиска, например "*.js" или "*.json". По умолчанию ищет во всех файлах.'
800
+ },
801
+ maxResults: {
802
+ type: 'number',
803
+ description: 'Максимальное количество результатов (по умолчанию 20, максимум 50)'
804
+ }
805
+ },
806
+ required: ['query']
807
+ }
808
+ },
809
+ execute: async (args) => {
810
+ console.log('searchCode called:', args.query, 'type:', args.type || 'text');
811
+ try {
812
+ const searchType = args.type || 'text';
813
+ const maxResults = Math.min(args.maxResults || 20, 50);
814
+ const filePattern = args.filePattern || '*';
815
+
816
+ const allFiles = getAllFilesRecursive(pluginPath, pluginPath, [], IGNORE_LIST);
817
+
818
+ let filesToSearch = allFiles;
819
+ if (filePattern !== '*') {
820
+ // Полное экранирование спецсимволов regex, затем конвертация glob '*' в '.*'
821
+ const escaped = filePattern
822
+ .replace(/[.+?^${}()|[\]\\]/g, '\\$&')
823
+ .replace(/\*/g, '.*');
824
+ const patternRegex = new RegExp('^' + escaped + '$');
825
+ filesToSearch = allFiles.filter(f => patternRegex.test(path.basename(f)));
826
+ }
827
+
828
+ let searchRegex;
829
+ try {
830
+ // Защита от ReDoS: ограничение длины regex паттерна
831
+ const MAX_REGEX_LENGTH = 100;
832
+ if (searchType === 'regex') {
833
+ if (args.query.length > MAX_REGEX_LENGTH) {
834
+ return `Ошибка: регулярное выражение слишком длинное (максимум ${MAX_REGEX_LENGTH} символов)`;
835
+ }
836
+ searchRegex = new RegExp(args.query, 'gi');
837
+ } else {
838
+ const escaped = args.query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
839
+ searchRegex = new RegExp(escaped, 'gi');
840
+ }
841
+ } catch (regexError) {
842
+ return `Ошибка в регулярном выражении: ${regexError.message}`;
843
+ }
844
+
845
+ const results = [];
846
+
847
+ for (const file of filesToSearch) {
848
+ if (results.length >= maxResults) break;
849
+
850
+ const fullPath = path.join(pluginPath, file);
851
+
852
+ try {
853
+ const content = await fse.readFile(fullPath, 'utf8');
854
+ const lines = content.split('\n');
855
+
856
+ lines.forEach((line, index) => {
857
+ if (results.length >= maxResults) return;
858
+
859
+ if (searchRegex.test(line)) {
860
+ searchRegex.lastIndex = 0;
861
+
862
+ results.push({
863
+ file: file,
864
+ line: index + 1,
865
+ content: line.trim().substring(0, 200)
866
+ });
867
+ }
868
+ });
869
+ } catch (readError) {
870
+ continue;
871
+ }
872
+ }
873
+
874
+ if (results.length === 0) {
875
+ return `Поиск "${args.query}" не дал результатов в ${filesToSearch.length} файлах.`;
876
+ }
877
+
878
+ let response = `Найдено ${results.length} совпадений для "${args.query}":\n\n`;
879
+
880
+ results.forEach((r, i) => {
881
+ response += `${i + 1}. ${r.file}:${r.line}\n ${r.content}\n\n`;
882
+ });
883
+
884
+ if (results.length === maxResults) {
885
+ response += `\n(показаны первые ${maxResults} результатов)`;
886
+ }
887
+
888
+ return response;
889
+ } catch (error) {
890
+ console.error('Error in searchCode:', error);
891
+ return `Ошибка при поиске: ${error.message}`;
892
+ }
893
+ }
894
+ },
895
+
597
896
  {
598
897
  type: 'function',
599
898
  function: {
@@ -613,38 +912,30 @@ function createPluginTools(pluginPath, res, botId) {
613
912
  execute: async (args) => {
614
913
  console.log('deleteFolder called for:', args.folderPath);
615
914
  try {
616
- const safePath = path.resolve(pluginPath, args.folderPath);
617
-
618
- // Проверка безопасности - папка должна быть внутри pluginPath
619
- const normalizedPluginPath = pluginPath.endsWith(path.sep) ? pluginPath : pluginPath + path.sep;
620
- if (!safePath.startsWith(normalizedPluginPath) && safePath !== pluginPath) {
621
- return `Ошибка: Доступ запрещен. Папка находится за пределами плагина.`;
915
+ // Используем строгую проверку безопасности (защита от path traversal)
916
+ const safePath = validateSafePath(pluginPath, args.folderPath);
917
+ if (!safePath) {
918
+ return `Ошибка: Доступ запрещен. Недопустимый путь к папке.`;
622
919
  }
623
920
 
624
- // Защита от удаления корневой директории плагина
625
- if (safePath === pluginPath) {
921
+ if (safePath === path.normalize(pluginPath)) {
626
922
  return `Ошибка: Нельзя удалить корневую директорию плагина.`;
627
923
  }
628
924
 
629
- // Проверяем что путь существует
630
925
  if (!await fse.pathExists(safePath)) {
631
926
  return `Ошибка: Папка "${args.folderPath}" не найдена.`;
632
927
  }
633
928
 
634
- // Проверяем что это директория
635
929
  const stats = await fse.stat(safePath);
636
930
  if (!stats.isDirectory()) {
637
931
  return `Ошибка: "${args.folderPath}" является файлом. Используйте deleteFile для удаления файлов.`;
638
932
  }
639
933
 
640
- // Подсчитываем количество файлов и папок внутри
641
934
  const items = await fse.readdir(safePath);
642
935
  const itemCount = items.length;
643
936
 
644
- // Удаляем папку рекурсивно
645
937
  await fse.remove(safePath);
646
938
 
647
- // Отправляем событие на фронтенд
648
939
  const sseEvent = {
649
940
  type: 'folder_deleted',
650
941
  folderPath: args.folderPath
@@ -659,6 +950,8 @@ function createPluginTools(pluginPath, res, botId) {
659
950
  }
660
951
  }
661
952
  ];
953
+
954
+ return baseTools;
662
955
  }
663
956
 
664
957
  /**
@@ -668,9 +961,32 @@ function createPluginTools(pluginPath, res, botId) {
668
961
  router.post('/chat', resolvePluginPath, async (req, res) => {
669
962
  console.log('Route hit! botId:', req.params.botId, 'pluginName:', req.params.pluginName);
670
963
  try {
671
- const { message, provider, apiKey, apiEndpoint, model, history, includeFiles, proxy } = req.body;
964
+ const { message, provider, apiKey, apiEndpoint, model, history, includeFiles, proxy, applyMode, temperature, maxTokens, customSystemPrompt, aiMode, autoFormat } = req.body;
672
965
  const { botId, pluginName } = req.params;
673
966
 
967
+ // Проверка rate limit (защита от злоупотребления)
968
+ const rateLimitKey = `${botId}_${pluginName}`;
969
+ if (!checkRateLimit(rateLimitKey)) {
970
+ const resetTime = getRateLimitResetTime(rateLimitKey);
971
+ console.warn(`[AI Chat] Rate limit exceeded for ${rateLimitKey}. Reset in ${resetTime}s`);
972
+ return res.status(429).json({
973
+ error: 'Превышен лимит запросов к AI. Попробуйте позже.',
974
+ retryAfter: resetTime
975
+ });
976
+ }
977
+
978
+ const effectiveApplyMode = applyMode || 'immediate';
979
+
980
+ const effectiveAutoFormat = autoFormat === true;
981
+
982
+ const validation = validateAIParams(temperature, maxTokens, 4096);
983
+ if (validation.error) {
984
+ return res.status(400).json({ error: validation.error });
985
+ }
986
+ const { effectiveTemperature, effectiveMaxTokens } = validation;
987
+
988
+ console.log('Apply mode:', effectiveApplyMode);
989
+
674
990
  const aiProvider = provider || 'openrouter';
675
991
  console.log('AI Provider:', aiProvider);
676
992
  console.log('Proxy config:', proxy);
@@ -690,6 +1006,10 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
690
1006
  systemPrompt = await fse.readFile(systemPromptPath, 'utf8');
691
1007
  }
692
1008
 
1009
+ if (customSystemPrompt && customSystemPrompt.trim()) {
1010
+ systemPrompt += `\n\n## Дополнительные инструкции пользователя:\n${customSystemPrompt.trim()}`;
1011
+ }
1012
+
693
1013
  let context = '';
694
1014
 
695
1015
  const packageJsonPath = path.join(req.pluginPath, 'package.json');
@@ -698,12 +1018,15 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
698
1018
  context += `\n\n## Package.json плагина:\n\`\`\`json\n${JSON.stringify(packageJson, null, 2)}\n\`\`\`\n`;
699
1019
  }
700
1020
 
701
- // Добавляем файлы если запрошено
702
1021
  if (includeFiles && Array.isArray(includeFiles)) {
703
1022
  for (const fileName of includeFiles) {
704
- const filePath = path.join(req.pluginPath, fileName);
705
- if (await fse.pathExists(filePath)) {
706
- const fileContent = await fse.readFile(filePath, 'utf8');
1023
+ const safePath = validateSafePath(req.pluginPath, fileName);
1024
+ if (!safePath) {
1025
+ console.warn(`[AI Chat] Skipping unsafe path: ${fileName}`);
1026
+ continue;
1027
+ }
1028
+ if (await fse.pathExists(safePath)) {
1029
+ const fileContent = await fse.readFile(safePath, 'utf8');
707
1030
  context += `\n\n## Файл ${fileName}:\n\`\`\`javascript\n${fileContent}\n\`\`\`\n`;
708
1031
  }
709
1032
  }
@@ -729,35 +1052,34 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
729
1052
  console.log('Created Google Gemini client');
730
1053
  } else {
731
1054
  // OpenRouter
1055
+ const maxToolIterations = 30;
1056
+
732
1057
  const clientConfig = {
733
1058
  apiKey: apiKey,
734
1059
  model: model,
735
1060
  historyAdapter: new MemoryHistoryStorage(),
736
- debug: true
1061
+ maxToolCalls: maxToolIterations,
1062
+ debug: false
737
1063
  };
738
1064
 
739
- // Добавляем кастомный endpoint если указан
740
1065
  if (apiEndpoint && apiEndpoint !== 'https://openrouter.ai/api/v1') {
741
1066
  clientConfig.apiEndpoint = apiEndpoint;
742
1067
  }
743
1068
 
744
- // Добавляем прокси если указан
745
1069
  if (proxyConfig) {
746
1070
  clientConfig.proxy = proxyConfig;
747
1071
  }
748
1072
 
749
1073
  client = new OpenRouterClient(clientConfig);
750
- console.log('Created OpenRouter client');
1074
+ console.log('Created OpenRouter client with maxToolCalls:', maxToolIterations);
751
1075
  }
752
1076
 
753
- // Получаем или создаем историю для этого бота и плагина
754
1077
  const chatKey = `${botId}_${pluginName}`;
755
1078
  if (!chatHistoryStore.has(chatKey)) {
756
1079
  chatHistoryStore.set(chatKey, []);
757
1080
  }
758
1081
  const storedHistory = chatHistoryStore.get(chatKey);
759
1082
 
760
- // Формируем customMessages
761
1083
  const customMessages = [
762
1084
  {
763
1085
  role: 'system',
@@ -765,35 +1087,38 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
765
1087
  }
766
1088
  ];
767
1089
 
768
- // Добавляем сохранённую историю
769
1090
  customMessages.push(...storedHistory);
770
1091
 
771
- // Добавляем текущее сообщение
772
1092
  const userMessage = {
773
1093
  role: 'user',
774
1094
  content: message
775
1095
  };
776
1096
  customMessages.push(userMessage);
777
1097
 
778
- // Сохраняем сообщение пользователя в историю
779
1098
  storedHistory.push(userMessage);
780
1099
 
781
- // Создаем tools для этого плагина (только для OpenRouter пока)
782
- const pluginTools = createPluginTools(req.pluginPath, res, botId);
1100
+ // Ограничиваем размер истории (защита от memory leak)
1101
+ trimHistory(storedHistory, chatKey);
1102
+
1103
+ const pluginTools = createPluginTools(
1104
+ req.pluginPath,
1105
+ res,
1106
+ botId,
1107
+ effectiveApplyMode,
1108
+ effectiveAutoFormat
1109
+ );
1110
+ console.log('AutoFormat:', effectiveAutoFormat, 'Tools count:', pluginTools.length);
783
1111
 
784
1112
  let fullResponse = '';
785
1113
  let assistantMessage = { role: 'assistant', content: '' };
786
1114
 
787
- // Google Gemini использует другой API
788
1115
  if (aiProvider === 'google') {
789
- // Устанавливаем SSE заголовки
790
1116
  res.setHeader('Content-Type', 'text/event-stream');
791
1117
  res.setHeader('Cache-Control', 'no-cache');
792
1118
  res.setHeader('Connection', 'keep-alive');
793
1119
 
794
1120
  try {
795
1121
  console.log('[Google] Converting history...');
796
- // Конвертируем историю в формат Gemini
797
1122
  const geminiHistory = [];
798
1123
  storedHistory.forEach(msg => {
799
1124
  if (msg.role === 'user') {
@@ -804,7 +1129,6 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
804
1129
  });
805
1130
  console.log('[Google] History length:', geminiHistory.length);
806
1131
 
807
- // Конвертируем tools в формат Gemini с wrapper для SSE событий
808
1132
  console.log('[Google] Converting tools...');
809
1133
  const geminiTools = [{
810
1134
  functionDeclarations: pluginTools.map(tool => ({
@@ -812,7 +1136,6 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
812
1136
  description: tool.function.description,
813
1137
  parameters: convertToGeminiParameters(tool.function.parameters),
814
1138
  execute: async (args) => {
815
- // Отправляем событие начала выполнения tool
816
1139
  if (!res.writableEnded) {
817
1140
  res.write(`data: ${JSON.stringify({
818
1141
  type: 'tool_call',
@@ -837,12 +1160,13 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
837
1160
  }];
838
1161
  console.log('[Google] Converted', geminiTools[0].functionDeclarations.length, 'tools');
839
1162
 
840
- console.log('[Google] Creating chat...');
1163
+ const maxToolIterations = 30;
1164
+ console.log('[Google] Creating chat... maxToolCalls:', maxToolIterations);
841
1165
  const chat = client.chats.create({
842
1166
  systemInstruction: systemPrompt + context,
843
1167
  history: geminiHistory,
844
1168
  tools: geminiTools,
845
- maxToolCalls: 10
1169
+ maxToolCalls: maxToolIterations
846
1170
  });
847
1171
 
848
1172
  console.log('[Google] Sending message...');
@@ -859,6 +1183,9 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
859
1183
  assistantMessage.content = content;
860
1184
  storedHistory.push(assistantMessage);
861
1185
 
1186
+ // Ограничиваем размер истории (защита от memory leak)
1187
+ trimHistory(storedHistory, chatKey);
1188
+
862
1189
  console.log('[Google] Closing SSE stream');
863
1190
  res.end();
864
1191
  return;
@@ -877,10 +1204,11 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
877
1204
  res.setHeader('Connection', 'keep-alive');
878
1205
 
879
1206
  try {
1207
+ console.log(`Using temperature: ${effectiveTemperature}, maxTokens: ${effectiveMaxTokens}`);
880
1208
  await client.chatStream({
881
1209
  customMessages: customMessages,
882
- temperature: 0.7,
883
- maxTokens: 4096,
1210
+ temperature: effectiveTemperature,
1211
+ maxTokens: effectiveMaxTokens,
884
1212
  tools: pluginTools,
885
1213
  includeToolResultInReport: true,
886
1214
  streamCallbacks: {
@@ -911,6 +1239,9 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
911
1239
 
912
1240
  if (assistantMessage.content) {
913
1241
  storedHistory.push(assistantMessage);
1242
+
1243
+ trimHistory(storedHistory, chatKey);
1244
+
914
1245
  console.log(`Saved to history. Total messages: ${storedHistory.length}`);
915
1246
  }
916
1247
 
@@ -930,22 +1261,151 @@ router.post('/chat', resolvePluginPath, async (req, res) => {
930
1261
  } catch (error) {
931
1262
  console.error('[AI Assistant Error]:', error);
932
1263
 
933
- // Если заголовки еще не отправлены, отправляем JSON ошибку
934
1264
  if (!res.headersSent) {
935
1265
  res.status(500).json({
936
1266
  error: error.message || 'Failed to process AI request.'
937
1267
  });
938
1268
  } else {
939
- // Если стриминг уже начался, отправляем ошибку через SSE
940
1269
  res.write(`data: ${JSON.stringify({ type: 'error', error: error.message })}\n\n`);
941
1270
  res.end();
942
1271
  }
943
1272
  }
944
1273
  });
945
1274
 
1275
+ /**
1276
+ * POST /api/bots/:botId/plugins/ide/:pluginName/ai/inline
1277
+ * Inline AI запрос (для командной палитры в редакторе)
1278
+ */
1279
+ router.post('/inline', resolvePluginPath, async (req, res) => {
1280
+ try {
1281
+ const { prompt, systemInstruction, action, context, provider, apiKey, apiEndpoint, model, proxy, temperature, maxTokens } = req.body;
1282
+ const { botId, pluginName } = req.params;
1283
+
1284
+ const rateLimitKey = `${botId}_${pluginName}_inline`;
1285
+ if (!checkRateLimit(rateLimitKey)) {
1286
+ const resetTime = getRateLimitResetTime(rateLimitKey);
1287
+ console.warn(`[AI Inline] Rate limit exceeded for ${rateLimitKey}. Reset in ${resetTime}s`);
1288
+ return res.status(429).json({
1289
+ error: 'Превышен лимит запросов к AI. Попробуйте позже.',
1290
+ retryAfter: resetTime
1291
+ });
1292
+ }
1293
+
1294
+ if (!prompt) {
1295
+ return res.status(400).json({ error: 'Prompt is required' });
1296
+ }
1297
+
1298
+ if (!apiKey) {
1299
+ return res.status(400).json({ error: 'API key is required' });
1300
+ }
1301
+
1302
+ const aiProvider = provider || 'openrouter';
1303
+ const proxyConfig = parseProxyString(proxy);
1304
+
1305
+ const validation = validateAIParams(temperature, maxTokens, 4096);
1306
+ if (validation.error) {
1307
+ return res.status(400).json({ error: validation.error });
1308
+ }
1309
+ const { effectiveTemperature, effectiveMaxTokens } = validation;
1310
+
1311
+ let client;
1312
+ if (aiProvider === 'google') {
1313
+ const googleConfig = {
1314
+ apiKeys: [apiKey],
1315
+ defaultModel: model
1316
+ };
1317
+ if (proxyConfig) {
1318
+ googleConfig.proxy = proxyConfig;
1319
+ }
1320
+ client = new GeminiClient(googleConfig);
1321
+ } else {
1322
+ const clientConfig = {
1323
+ apiKey: apiKey,
1324
+ model: model,
1325
+ historyAdapter: new MemoryHistoryStorage()
1326
+ };
1327
+ if (apiEndpoint && apiEndpoint !== 'https://openrouter.ai/api/v1') {
1328
+ clientConfig.apiEndpoint = apiEndpoint;
1329
+ }
1330
+ if (proxyConfig) {
1331
+ clientConfig.proxy = proxyConfig;
1332
+ }
1333
+ client = new OpenRouterClient(clientConfig);
1334
+ }
1335
+
1336
+ let result;
1337
+
1338
+ if (aiProvider === 'google') {
1339
+ const chat = client.chats.create({
1340
+ systemInstruction: systemInstruction || 'Ты - AI помощник для разработчиков. Отвечай кратко и по делу.'
1341
+ });
1342
+ const response = await chat.sendMessage(prompt);
1343
+ result = response.text();
1344
+ } else {
1345
+ const response = await client.chat({
1346
+ customMessages: [
1347
+ { role: 'system', content: systemInstruction || 'Ты - AI помощник для разработчиков. Отвечай кратко и по делу.' },
1348
+ { role: 'user', content: prompt }
1349
+ ],
1350
+ temperature: effectiveTemperature,
1351
+ maxTokens: effectiveMaxTokens
1352
+ });
1353
+ result = response;
1354
+ }
1355
+
1356
+ console.log('[AI Inline] Response generated for action:', action);
1357
+ res.json({ result, action });
1358
+
1359
+ } catch (error) {
1360
+ console.error('[AI Inline Error]:', error);
1361
+ res.status(500).json({ error: error.message || 'Failed to process inline AI request' });
1362
+ }
1363
+ });
1364
+
1365
+ /**
1366
+ * POST /api/bots/:botId/plugins/ide/:pluginName/ai/apply-change
1367
+ * Применяет preview изменение (записывает файл на диск)
1368
+ */
1369
+ router.post('/apply-change', resolvePluginPath, async (req, res) => {
1370
+ try {
1371
+ const { filePath, content } = req.body;
1372
+ const { botId, pluginName } = req.params;
1373
+
1374
+ const rateLimitKey = `${botId}_${pluginName}_apply`;
1375
+ if (!checkRateLimit(rateLimitKey)) {
1376
+ const resetTime = getRateLimitResetTime(rateLimitKey);
1377
+ console.warn(`[AI Apply] Rate limit exceeded for ${rateLimitKey}. Reset in ${resetTime}s`);
1378
+ return res.status(429).json({
1379
+ error: 'Превышен лимит запросов к AI. Попробуйте позже.',
1380
+ retryAfter: resetTime
1381
+ });
1382
+ }
1383
+
1384
+ if (!filePath || content === undefined) {
1385
+ return res.status(400).json({ error: 'filePath and content are required' });
1386
+ }
1387
+
1388
+ // Используем строгую проверку безопасности (защита от path traversal)
1389
+ const safePath = validateSafePath(req.pluginPath, filePath);
1390
+ if (!safePath) {
1391
+ return res.status(403).json({ error: 'Access denied. Invalid file path.' });
1392
+ }
1393
+
1394
+ await fse.ensureDir(path.dirname(safePath));
1395
+
1396
+ await fse.writeFile(safePath, content, 'utf8');
1397
+
1398
+ console.log('[AI] Applied preview change:', filePath);
1399
+
1400
+ res.json({ success: true, filePath });
1401
+ } catch (error) {
1402
+ console.error('[AI] Error applying change:', error);
1403
+ res.status(500).json({ error: error.message });
1404
+ }
1405
+ });
1406
+
946
1407
  /**
947
1408
  * GET /api/bots/:botId/plugins/ide/:pluginName/ai/chat
948
- * Получает историю чата для конкретного бота и плагина
949
1409
  */
950
1410
  router.get('/chat', resolvePluginPath, async (req, res) => {
951
1411
  try {
@@ -967,7 +1427,6 @@ router.get('/chat', resolvePluginPath, async (req, res) => {
967
1427
 
968
1428
  /**
969
1429
  * DELETE /api/bots/:botId/plugins/ide/:pluginName/ai/chat
970
- * Очищает историю чата для конкретного бота и плагина
971
1430
  */
972
1431
  router.delete('/chat', resolvePluginPath, async (req, res) => {
973
1432
  try {