@darkclaw921/umgt 0.0.0-stage → 0.2.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 (295) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -2
  3. package/architecture.md +105 -0
  4. package/bin/lm-game-hub.js +7 -0
  5. package/dist/server/activity.d.ts +17 -0
  6. package/dist/server/activity.js +55 -0
  7. package/dist/server/activity.js.map +1 -0
  8. package/dist/server/agents/activity.d.ts +36 -0
  9. package/dist/server/agents/activity.js +117 -0
  10. package/dist/server/agents/activity.js.map +1 -0
  11. package/dist/server/agents/claude.d.ts +5 -0
  12. package/dist/server/agents/claude.js +107 -0
  13. package/dist/server/agents/claude.js.map +1 -0
  14. package/dist/server/agents/codex.d.ts +5 -0
  15. package/dist/server/agents/codex.js +128 -0
  16. package/dist/server/agents/codex.js.map +1 -0
  17. package/dist/server/agents/core-tools.d.ts +23 -0
  18. package/dist/server/agents/core-tools.js +298 -0
  19. package/dist/server/agents/core-tools.js.map +1 -0
  20. package/dist/server/agents/core.d.ts +9 -0
  21. package/dist/server/agents/core.js +106 -0
  22. package/dist/server/agents/core.js.map +1 -0
  23. package/dist/server/agents/index.d.ts +5 -0
  24. package/dist/server/agents/index.js +41 -0
  25. package/dist/server/agents/index.js.map +1 -0
  26. package/dist/server/agents/kimi.d.ts +5 -0
  27. package/dist/server/agents/kimi.js +123 -0
  28. package/dist/server/agents/kimi.js.map +1 -0
  29. package/dist/server/agents/rpc.d.ts +19 -0
  30. package/dist/server/agents/rpc.js +102 -0
  31. package/dist/server/agents/rpc.js.map +1 -0
  32. package/dist/server/agents/types.d.ts +51 -0
  33. package/dist/server/agents/types.js +7 -0
  34. package/dist/server/agents/types.js.map +1 -0
  35. package/dist/server/app.d.ts +21 -0
  36. package/dist/server/app.js +38 -0
  37. package/dist/server/app.js.map +1 -0
  38. package/dist/server/asset-catalog.d.ts +5 -0
  39. package/dist/server/asset-catalog.js +525 -0
  40. package/dist/server/asset-catalog.js.map +1 -0
  41. package/dist/server/asset-media.d.ts +16 -0
  42. package/dist/server/asset-media.js +170 -0
  43. package/dist/server/asset-media.js.map +1 -0
  44. package/dist/server/asset-selection.d.ts +71 -0
  45. package/dist/server/asset-selection.js +273 -0
  46. package/dist/server/asset-selection.js.map +1 -0
  47. package/dist/server/assets.d.ts +69 -0
  48. package/dist/server/assets.js +669 -0
  49. package/dist/server/assets.js.map +1 -0
  50. package/dist/server/browser-gateway.d.ts +82 -0
  51. package/dist/server/browser-gateway.js +285 -0
  52. package/dist/server/browser-gateway.js.map +1 -0
  53. package/dist/server/chat-computer.d.ts +13 -0
  54. package/dist/server/chat-computer.js +29 -0
  55. package/dist/server/chat-computer.js.map +1 -0
  56. package/dist/server/chat-games.d.ts +38 -0
  57. package/dist/server/chat-games.js +202 -0
  58. package/dist/server/chat-games.js.map +1 -0
  59. package/dist/server/chat.d.ts +42 -0
  60. package/dist/server/chat.js +318 -0
  61. package/dist/server/chat.js.map +1 -0
  62. package/dist/server/cli.d.ts +14 -0
  63. package/dist/server/cli.js +117 -0
  64. package/dist/server/cli.js.map +1 -0
  65. package/dist/server/core-client.d.ts +69 -0
  66. package/dist/server/core-client.js +357 -0
  67. package/dist/server/core-client.js.map +1 -0
  68. package/dist/server/directory-picker.d.ts +14 -0
  69. package/dist/server/directory-picker.js +113 -0
  70. package/dist/server/directory-picker.js.map +1 -0
  71. package/dist/server/engine.d.ts +36 -0
  72. package/dist/server/engine.js +507 -0
  73. package/dist/server/engine.js.map +1 -0
  74. package/dist/server/events.d.ts +12 -0
  75. package/dist/server/events.js +137 -0
  76. package/dist/server/events.js.map +1 -0
  77. package/dist/server/game-launch.d.ts +16 -0
  78. package/dist/server/game-launch.js +143 -0
  79. package/dist/server/game-launch.js.map +1 -0
  80. package/dist/server/html5.d.ts +9 -0
  81. package/dist/server/html5.js +107 -0
  82. package/dist/server/html5.js.map +1 -0
  83. package/dist/server/interview.d.ts +241 -0
  84. package/dist/server/interview.js +190 -0
  85. package/dist/server/interview.js.map +1 -0
  86. package/dist/server/mcp.d.ts +27 -0
  87. package/dist/server/mcp.js +91 -0
  88. package/dist/server/mcp.js.map +1 -0
  89. package/dist/server/plugins.d.ts +8 -0
  90. package/dist/server/plugins.js +144 -0
  91. package/dist/server/plugins.js.map +1 -0
  92. package/dist/server/process.d.ts +15 -0
  93. package/dist/server/process.js +89 -0
  94. package/dist/server/process.js.map +1 -0
  95. package/dist/server/publication-materials.d.ts +18 -0
  96. package/dist/server/publication-materials.js +104 -0
  97. package/dist/server/publication-materials.js.map +1 -0
  98. package/dist/server/publication-mcp.d.ts +3 -0
  99. package/dist/server/publication-mcp.js +43 -0
  100. package/dist/server/publication-mcp.js.map +1 -0
  101. package/dist/server/publication.d.ts +54 -0
  102. package/dist/server/publication.js +334 -0
  103. package/dist/server/publication.js.map +1 -0
  104. package/dist/server/push.d.ts +81 -0
  105. package/dist/server/push.js +122 -0
  106. package/dist/server/push.js.map +1 -0
  107. package/dist/server/reports.d.ts +4 -0
  108. package/dist/server/reports.js +40 -0
  109. package/dist/server/reports.js.map +1 -0
  110. package/dist/server/roblox-assets.d.ts +41 -0
  111. package/dist/server/roblox-assets.js +131 -0
  112. package/dist/server/roblox-assets.js.map +1 -0
  113. package/dist/server/roblox-connection.d.ts +54 -0
  114. package/dist/server/roblox-connection.js +331 -0
  115. package/dist/server/roblox-connection.js.map +1 -0
  116. package/dist/server/roblox-install.d.ts +4 -0
  117. package/dist/server/roblox-install.js +170 -0
  118. package/dist/server/roblox-install.js.map +1 -0
  119. package/dist/server/roblox-mcp.d.ts +2 -0
  120. package/dist/server/roblox-mcp.js +34 -0
  121. package/dist/server/roblox-mcp.js.map +1 -0
  122. package/dist/server/roblox-play.d.ts +23 -0
  123. package/dist/server/roblox-play.js +84 -0
  124. package/dist/server/roblox-play.js.map +1 -0
  125. package/dist/server/roblox-project-tools.d.ts +11 -0
  126. package/dist/server/roblox-project-tools.js +119 -0
  127. package/dist/server/roblox-project-tools.js.map +1 -0
  128. package/dist/server/roblox-setup.d.ts +37 -0
  129. package/dist/server/roblox-setup.js +206 -0
  130. package/dist/server/roblox-setup.js.map +1 -0
  131. package/dist/server/roblox-skills.d.ts +15 -0
  132. package/dist/server/roblox-skills.js +15 -0
  133. package/dist/server/roblox-skills.js.map +1 -0
  134. package/dist/server/roblox.d.ts +30 -0
  135. package/dist/server/roblox.js +248 -0
  136. package/dist/server/roblox.js.map +1 -0
  137. package/dist/server/routes.d.ts +11 -0
  138. package/dist/server/routes.js +223 -0
  139. package/dist/server/routes.js.map +1 -0
  140. package/dist/server/security.d.ts +4 -0
  141. package/dist/server/security.js +64 -0
  142. package/dist/server/security.js.map +1 -0
  143. package/dist/server/skills.d.ts +4 -0
  144. package/dist/server/skills.js +123 -0
  145. package/dist/server/skills.js.map +1 -0
  146. package/dist/server/store.d.ts +25 -0
  147. package/dist/server/store.js +89 -0
  148. package/dist/server/store.js.map +1 -0
  149. package/dist/server/templates/roblox-coin-run.d.ts +2 -0
  150. package/dist/server/templates/roblox-coin-run.js +326 -0
  151. package/dist/server/templates/roblox-coin-run.js.map +1 -0
  152. package/dist/server/templates/roblox-skills.json +55 -0
  153. package/dist/server/templates/yandex-sdk.d.ts +3 -0
  154. package/dist/server/templates/yandex-sdk.js +177 -0
  155. package/dist/server/templates/yandex-sdk.js.map +1 -0
  156. package/dist/server/updates.d.ts +28 -0
  157. package/dist/server/updates.js +99 -0
  158. package/dist/server/updates.js.map +1 -0
  159. package/dist/server/video-media.d.ts +47 -0
  160. package/dist/server/video-media.js +224 -0
  161. package/dist/server/video-media.js.map +1 -0
  162. package/dist/server/video-routes.d.ts +7 -0
  163. package/dist/server/video-routes.js +91 -0
  164. package/dist/server/video-routes.js.map +1 -0
  165. package/dist/server/video.d.ts +214 -0
  166. package/dist/server/video.js +301 -0
  167. package/dist/server/video.js.map +1 -0
  168. package/dist/server/web-build.d.ts +16 -0
  169. package/dist/server/web-build.js +232 -0
  170. package/dist/server/web-build.js.map +1 -0
  171. package/dist/server/workflow.d.ts +221 -0
  172. package/dist/server/workflow.js +826 -0
  173. package/dist/server/workflow.js.map +1 -0
  174. package/dist/server/yandex-config.d.ts +33 -0
  175. package/dist/server/yandex-config.js +12 -0
  176. package/dist/server/yandex-config.js.map +1 -0
  177. package/dist/server/yandex-godot.d.ts +5 -0
  178. package/dist/server/yandex-godot.js +107 -0
  179. package/dist/server/yandex-godot.js.map +1 -0
  180. package/dist/shared/aspects.d.ts +48 -0
  181. package/dist/shared/aspects.js +22 -0
  182. package/dist/shared/aspects.js.map +1 -0
  183. package/dist/shared/assistant.d.ts +7 -0
  184. package/dist/shared/assistant.js +36 -0
  185. package/dist/shared/assistant.js.map +1 -0
  186. package/dist/shared/chat.d.ts +46 -0
  187. package/dist/shared/chat.js +2 -0
  188. package/dist/shared/chat.js.map +1 -0
  189. package/dist/shared/settings.d.ts +11 -0
  190. package/dist/shared/settings.js +25 -0
  191. package/dist/shared/settings.js.map +1 -0
  192. package/dist/shared/types.d.ts +510 -0
  193. package/dist/shared/types.js +2 -0
  194. package/dist/shared/types.js.map +1 -0
  195. package/dist/web/apple-touch-icon.png +0 -0
  196. package/dist/web/assets/AgentActivity-sYJeY5Yf.js +9 -0
  197. package/dist/web/assets/ArrowRight.es-9w41WqD8.js +1 -0
  198. package/dist/web/assets/ArrowUpRight.es-BmIrpjWN.js +1 -0
  199. package/dist/web/assets/AssetMediaPreview-D2cd6oQO.js +1 -0
  200. package/dist/web/assets/AssetSelectionWizard-a43_6NO7.js +1 -0
  201. package/dist/web/assets/CaretDown.es-Cq33NYip.js +1 -0
  202. package/dist/web/assets/CheckCircle.es-D5B3hdvz.js +1 -0
  203. package/dist/web/assets/CoreAccount-D4ZC8CWv.js +1 -0
  204. package/dist/web/assets/DownloadSimple.es-DwOWFbs2.js +1 -0
  205. package/dist/web/assets/FileText.es-D83IIiOG.js +1 -0
  206. package/dist/web/assets/ImageSquare.es-DxCFt99_.js +1 -0
  207. package/dist/web/assets/KidsApp-BXWaALoK.css +1 -0
  208. package/dist/web/assets/KidsApp-D-8t3HPy.js +2 -0
  209. package/dist/web/assets/MagnifyingGlass.es-rkdOU2rH.js +1 -0
  210. package/dist/web/assets/PaperPlaneRight.es-U0twumpP.js +1 -0
  211. package/dist/web/assets/PencilSimple.es-JVHwRvGx.js +1 -0
  212. package/dist/web/assets/PlainChat-BC4K_tmj.css +1 -0
  213. package/dist/web/assets/PlainChat-CMxYwKko.js +1 -0
  214. package/dist/web/assets/Sparkle.es-CmGpvnNm.js +1 -0
  215. package/dist/web/assets/Square.es-BjNN9Ypc.js +1 -0
  216. package/dist/web/assets/UploadSimple.es-DxIuxpCC.js +1 -0
  217. package/dist/web/assets/WarningCircle.es-D63H8cL9.js +1 -0
  218. package/dist/web/assets/WorkflowJournal-Did0sRta.js +1 -0
  219. package/dist/web/assets/YandexConfigFields-DDL22Bfw.js +1 -0
  220. package/dist/web/assets/YandexGamesView-R64RSJRL.js +2 -0
  221. package/dist/web/assets/bg-build-DIalyCDw.svg +3 -0
  222. package/dist/web/assets/bg-idea-DHcE-Dhs.svg +3 -0
  223. package/dist/web/assets/bg-materials-UDVFaueI.svg +3 -0
  224. package/dist/web/assets/bg-plan-DpfwIsqJ.svg +3 -0
  225. package/dist/web/assets/bg-play-CNc1QZFK.svg +3 -0
  226. package/dist/web/assets/dist-7vx7MTaJ.js +1 -0
  227. package/dist/web/assets/index-Izzbh11U.css +1 -0
  228. package/dist/web/assets/index-sNciOZYG.js +13 -0
  229. package/dist/web/assets/jsx-runtime-CdVFa8IP.js +1 -0
  230. package/dist/web/assets/manrope-cyrillic-wght-normal-Dvxsihut.woff2 +0 -0
  231. package/dist/web/assets/manrope-greek-wght-normal-DL7QRZyv.woff2 +0 -0
  232. package/dist/web/assets/manrope-latin-ext-wght-normal-Ch3YOpNY.woff2 +0 -0
  233. package/dist/web/assets/manrope-latin-wght-normal-DHIcAJRg.woff2 +0 -0
  234. package/dist/web/assets/manrope-vietnamese-wght-normal-usUDDRr7.woff2 +0 -0
  235. package/dist/web/assets/resources-DppXCagL.js +1 -0
  236. package/dist/web/assets/robot-happy-B6YvlU94.svg +24 -0
  237. package/dist/web/assets/robot-hello-CCsQgsS-.svg +24 -0
  238. package/dist/web/assets/robot-listen-Buuz9xII.svg +24 -0
  239. package/dist/web/assets/robot-sad-CRtiNVWs.svg +24 -0
  240. package/dist/web/assets/robot-think-CJ5fDBTm.svg +24 -0
  241. package/dist/web/assets/star-big-CSFDKjws.svg +22 -0
  242. package/dist/web/assets/star-empty-CC-5vioJ.svg +3 -0
  243. package/dist/web/assets/star-next-ztuDjOHU.svg +9 -0
  244. package/dist/web/assets/star-on-l_krO3aV.svg +10 -0
  245. package/dist/web/assets/ui-wHE_yBK0.js +41 -0
  246. package/dist/web/assets/umgt-logo-DAOkTN9u.png +0 -0
  247. package/dist/web/assets/unbounded-cyrillic-wght-normal-C627f1f8.woff2 +0 -0
  248. package/dist/web/assets/unbounded-latin-ext-wght-normal-D6H-S6MW.woff2 +0 -0
  249. package/dist/web/assets/unbounded-latin-wght-normal-D5afBTBx.woff2 +0 -0
  250. package/dist/web/assets/unbounded-vietnamese-wght-normal-rat7GD3o.woff2 +0 -0
  251. package/dist/web/assets/workflow-BhcU9uvG.css +1 -0
  252. package/dist/web/assets/workflow-BrIKN5ER.js +34 -0
  253. package/dist/web/favicon.ico +0 -0
  254. package/dist/web/icons/favicon-16.png +0 -0
  255. package/dist/web/icons/favicon-32.png +0 -0
  256. package/dist/web/icons/icon-192.png +0 -0
  257. package/dist/web/icons/icon-512.png +0 -0
  258. package/dist/web/icons/maskable-192.png +0 -0
  259. package/dist/web/icons/maskable-512.png +0 -0
  260. package/dist/web/index.html +28 -0
  261. package/dist/web/manifest.webmanifest +19 -0
  262. package/dist/web/sw.js +25 -0
  263. package/docs/agent-activity-ui.md +33 -0
  264. package/docs/agent-activity.md +43 -0
  265. package/docs/agent-permissions-ui.md +15 -0
  266. package/docs/api.md +145 -0
  267. package/docs/approval-journal.md +13 -0
  268. package/docs/asset-media.md +27 -0
  269. package/docs/asset-providers.md +34 -0
  270. package/docs/asset-selection.md +31 -0
  271. package/docs/automatic-approvals.md +15 -0
  272. package/docs/background-game-launch.md +17 -0
  273. package/docs/billing-validation.md +23 -0
  274. package/docs/core-isolation.md +37 -0
  275. package/docs/core.md +45 -0
  276. package/docs/generated-text-ui.md +41 -0
  277. package/docs/interactive-interview-ui.md +29 -0
  278. package/docs/interactive-interview.md +52 -0
  279. package/docs/local-codex.md +51 -0
  280. package/docs/local-meshy.md +13 -0
  281. package/docs/markdown.md +11 -0
  282. package/docs/permission-ui.md +11 -0
  283. package/docs/plan.md +47 -0
  284. package/docs/remote-core-deployment.md +47 -0
  285. package/docs/roblox.md +90 -0
  286. package/docs/validation.md +228 -0
  287. package/docs/video-reference.md +35 -0
  288. package/docs/workflow-journal-ui.md +21 -0
  289. package/docs/yandex-foundation.md +27 -0
  290. package/docs/yandex-games.md +45 -0
  291. package/package.json +95 -4
  292. package/scripts/create-roblox-demo.mjs +31 -0
  293. package/scripts/diagnose-roblox-mcp.mjs +45 -0
  294. package/scripts/open-hub-chrome.mjs +60 -0
  295. package/scripts/smoke-agent.mjs +91 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 igor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,162 @@
1
- # Temporary Holding Version
1
+ # Game Hub
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Локальное рабочее место для создания игр с Godot, HTML5 или Roblox Studio и серверным AI через отдельное ядро Game Hub Core. Приложение запускает web-интерфейс на вашем компьютере, сохраняет планы и задачи и управляет разработкой через выбранного агента. Для Яндекс Игр доступны SDK, проверка ZIP и помощник подготовки публикации через Chrome MCP.
4
+
5
+ AI-запросы выполняются отдельным [Game Hub Core](../game-hub-core/README.md). Для доступа подключите аккаунт UMGT: приложение использует токены подписки или купленные токены и показывает остатки лимитов. Файлы, команды и редакторы работают на вашем компьютере; ключ AI-провайдера хранится на сервере. Подробнее: [подписка и ядро](docs/core.md).
6
+
7
+ ## Установка и запуск одной командой
8
+
9
+ Установите **Node.js 24.13 или новее** (npm и npx входят в комплект). После публикации пакета `@darkclaw921/umgt` в npm откройте терминал и выполните одну команду на macOS, Linux или Windows:
10
+
11
+ ```sh
12
+ npx --yes @darkclaw921/umgt@latest
13
+ ```
14
+
15
+ Команда скачает готовую студию и её зависимости в кеш npm, запустит локальный сервер и откроет интерфейс в браузере. Для первого запуска нужен интернет. Git, доступ к исходному репозиторию и ручная сборка не требуются. Для следующих запусков используйте ту же команду; проекты и настройки сохраняются отдельно от кеша npm.
16
+
17
+ После запуска нажмите **Аккаунт UMGT** (в верхней панели нового интерфейса или в боковом меню классического). Вставьте свой личный API-ключ из кабинета **game.aircoding.ai** и нажмите **Подключить**. Адрес ядра **`https://umgt.aircoding.ai`** уже подставлен. После подключения отобразятся статус и срок подписки, рублёвый баланс, доступные и купленные токены, дневной и недельный лимиты со временем обновления. Здесь же можно обновить данные и посмотреть историю операций. Модель для всех запросов настраивает администратор ядра. Этот раздел также доступен через **Настройки → Подписка и доступ**. Файлы игры и команды выполняются на вашем компьютере, AI-запросы — через ядро.
18
+
19
+ Для HTML5-игр достаточно Node.js/npm. Для Godot-проектов дополнительно установите Godot 4.x. Для Roblox Hub автоматически установит Studio при первом открытии проекта на macOS/Windows; при первом запуске потребуется войти в аккаунт Roblox и включить Studio MCP, как описано ниже.
20
+
21
+ Студия работает, пока открыт её процесс в терминале. Чтобы остановить её, нажмите **Ctrl+C**. Для постоянной установки команды `umgt` можно выполнить:
22
+
23
+ ```sh
24
+ npm install --global @darkclaw921/umgt
25
+ umgt
26
+ ```
27
+
28
+ Обычный адрес студии — `http://127.0.0.1:4317/`. Если браузер не открылся автоматически, перейдите по полной ссылке из терминала: она содержит секрет подключения текущего запуска. Интерфейс обменивает его на HttpOnly cookie и удаляет из адресной строки. Не передавайте эту ссылку другим людям.
29
+
30
+ ### Дополнительные параметры запуска
31
+
32
+ ```sh
33
+ npx --yes @darkclaw921/umgt@latest --port 4317 --no-open
34
+ npx --yes @darkclaw921/umgt@latest doctor
35
+ npx --yes @darkclaw921/umgt@latest --help
36
+ ```
37
+
38
+ Пользовательские данные по умолчанию лежат в `~/.lm-game-hub`; альтернативная папка задаётся `--data-dir /путь/к/папке`. Прежняя команда `lm-game-hub` сохранена как совместимый псевдоним `umgt`.
39
+
40
+ ### Запуск из исходников
41
+
42
+ Для разработки установите также Git. Репозиторий пока приватный: нужны предоставленный доступ и настроенная авторизация Git в GitHub. В папке, где ещё нет каталога `lm-game-hub`, выполните:
43
+
44
+ ```sh
45
+ git clone --depth 1 https://github.com/darkClaw921/lm-game-hub.git && cd lm-game-hub && npm ci && npm run build && npm start
46
+ ```
47
+
48
+ Команда подходит для macOS, Linux и Windows с PowerShell 7 или Git Bash. Повторный запуск из папки репозитория — `npm start`; `npm link` после сборки добавляет команды `umgt` и `lm-game-hub`.
49
+
50
+ Если управление Chrome в Codex показывает `ERR_BLOCKED_BY_CLIENT`, хотя страница открывается вручную, на macOS можно открыть текущую сессию штатной командой Chrome:
51
+
52
+ ```sh
53
+ npm run open:chrome
54
+ # Для другого файла с выводом текущего запуска сервера:
55
+ npm run open:chrome -- --log /путь/к/server.log
56
+ ```
57
+
58
+ Скрипт берёт ссылку подключения из последнего `.artifacts/local-stack*.log`, проверяет сервер и открывает авторизованную вкладку. После этого агенту нужно подключиться к существующей вкладке, без `goto` или `reload`. Это временный способ работы с блокировкой автоматической навигации; исправление самого расширения не гарантируется.
59
+
60
+ ## Локальный тест ядра через подписку Codex
61
+
62
+ `npm run dev:core` поднимает отдельный локальный стенд: PostgreSQL, ядро, тестовый UMGT и мост к текущей подписке Codex. `npm run test:core:live` проверяет их совместную работу реальными вызовами модели. Команды и реквизиты доступа: [локальный стенд](docs/local-codex.md).
63
+
64
+ ## Работа над игрой
65
+
66
+ ### Чат
67
+
68
+ Нажмите **Чат** в верхней панели или боковом меню. Можно общаться с моделью без создания игрового проекта: задавать вопросы, обсуждать идеи, просить объяснения. Кнопка **Новый диалог** начинает отдельную беседу; история сохраняется локально и доступна после перезапуска студии. Диалоги разделены по аккаунтам UMGT. Enter отправляет сообщение, Shift+Enter добавляет строку; **Остановить ответ** прерывает генерацию. Ответы используют то же ядро и учитываются в лимитах подключённого аккаунта. Для новых ответов используется стандартная модель, настроенная администратором ядра. Чат открывается отдельным экраном в новом интерфейсе. Попросите «Создай игру змейку» — студия создаст локальный проект через обычный workflow. По умолчанию это быстрый HTML5-прототип: короткий план, одна задача, без внешних ассетов и платной генерации, с проверкой TypeScript и сборки. Карточка показывает прогресс, позволяет остановить создание и открыть проект. Когда игра готова, **Запустить** открывает её в новом окне. Можно явно выбрать Godot или Roblox; такие проекты используют обычное планирование и запускаются из проекта в соответствующем движке. Просьба изменить готовую игру продолжает последний проект в этом диалоге.
69
+
70
+ Рядом с полем ввода слева есть переключатель **Голосовые ответы**. Он включает короткие подтверждения и вопросы через Google Gemini TTS с голосом **Autonoe**; полный ответ остаётся текстом. Озвучка идёт в фоне и не останавливает создание игры. Кнопка «Проверить звук» проверяет воспроизведение, «Повторить реплику» повторно использует загруженное аудио. Фактические токены и стоимость озвучки учитывает ядро; задержанные метаданные провайдера сверяются автоматически. Микрофон запускает встроенную диктовку браузера: распознанный текст остаётся редактируемым. Новое сообщение прерывает реплику, выключение динамика прекращает озвучку. История автоматически не читается.
71
+
72
+ В списке диалогов значки карандаша и корзины позволяют переименовать или удалить беседу. Раздел «Удалённые диалоги» позволяет восстановить её вместе с историей. Удаление останавливает текущую генерацию, проекты игр сохраняются.
73
+
74
+ В чате можно просить выполнить локальную команду, открыть приложение, файл или ссылку, прочитать или записать файл. Ядро планирует действия, а команды выполняет локальный Hub на компьютере пользователя. Файловые инструменты используют отдельную рабочую папку каждого диалога. Разрешения соответствуют настройке автоматических действий студии; запросы подтверждения и вопросы агента появляются прямо в чате. Создание и изменение игр продолжают использовать игровой workflow.
75
+
76
+ ### Создание игры
77
+
78
+ Идею можно задать описанием, голосом или записью геймплея. На этапе идеи нажмите «Показать игру в видео»: Hub разберёт движение, правила, окружение, ассеты и звук, затем поможет уточнить неизвестное и составить план. Поддерживается один ролик до 10 ГБ без лимита длительности, с возобновлением загрузки и анализа. Подробнее: [создание игры по видео](docs/video-reference.md).
79
+
80
+ Готовые примеры: [визуальный эталон](examples/video-ritual-game/README.md) и [игра, созданная и доработанная через UI](examples/video-ritual-game-ui/README.md). Для второго примера сохранены исходники, материалы, функциональные тесты и отчёт визуальной проверки.
81
+
82
+ 1. Откройте настройки и проверьте пути к Godot и CLI. В разделе «Подписка и доступ» укажите адрес ядра и API-ключ UMGT, Модель задаётся администратором ядра.
83
+ 2. Нажмите «Выбрать папку» и выберите пустую папку проекта в системном окне; там же можно создать новую. Выберите Godot/GDScript или HTML5/TypeScript (Phaser для 2D, Three.js для 3D), затем платформы. Для Яндекс Игр включается Web и появляются настройки SDK. Интерфейс Hub настольный; создаваемая игра может поддерживать компьютер и телефон.
84
+ 3. Опишите игру или пройдите интерактивный опрос. Планирование не разрешает агенту изменять файлы игры.
85
+ 4. Откройте «План», проверьте и утвердите содержание. Приложение параллельно создаст эпики/задачи и подберёт ассеты. В мастере сравните варианты, при необходимости загрузите свой файл и подтвердите итоговый набор. Разработка начнётся после готовности задач и успешного импорта. Мастер можно закрыть и открыть снова без потери выбора.
86
+ 5. Наблюдайте выполнение в задачах и журнале. Работу можно приостановить или остановить. Вопросы агента появляются в интерфейсе; обычные разрешения автоматически одобряются по настройке приложения.
87
+ 6. Выбирайте бесплатные ассеты в каталоге, импортируйте их в проект и прикрепляйте к задачам. Перед изменением ресурсов активного проекта приостановите исполнение. Редактор Godot и ручное редактирование файлов открываются вне web-панели.
88
+
89
+ Токены подключения к ядру хранятся в `core-session.json` внутри папки данных Hub с правами 0600. Не включайте этот файл в публичные архивы.
90
+
91
+ Данные игровых проектов хранятся в `.lm-game-hub` внутри соответствующей папки. План экспортируется в Markdown, задачи доступны в JSON. Перед переносом или резервным копированием проекта остановите Hub, чтобы закрыть SQLite и дочерние процессы.
92
+
93
+ Выбор папки открывается на компьютере, где запущен Hub. В Linux нужен установленный `zenity` или `kdialog` и графическая сессия; в macOS и Windows используются системные диалоги. Отмена сохраняет прежний выбор, содержимое занятой папки не перезаписывается.
94
+
95
+ ## Источники ассетов
96
+
97
+ - **Poly Haven**: программный каталог и скачивание; Powered by Poly Haven. <https://polyhaven.com>
98
+ - **ambientCG**: программный каталог и скачивание. <https://ambientcg.com>
99
+ - **Kenney**: проверенная подборка пакетов с переходом к источнику и импортом архива. <https://kenney.nl/assets>
100
+ - **OpenGameArt**: проверенная подборка аудио с превью и автоматическим импортом; остальные ресурсы через поиск на сайте и ручную загрузку.
101
+ - **itch.io**: переход к поиску на сайте, затем ручной импорт.
102
+
103
+ Каталог сохраняет сведения об источнике и лицензии. Подбор предлагает проверенные CC0 и CC-BY; для CC-BY импорт сохраняет текст атрибуции для титров. Доступ к сетевым каталогам требует интернета, локальные проекты и сохранённые планы остаются доступны без него. Подробнее: [мастер подбора](docs/asset-selection.md).
104
+
105
+ ## Проверка и разработка
106
+
107
+ Пакет публикуется как `@darkclaw921/umgt`, команда CLI — `umgt`. Для публикации из корня репозитория после установки зависимостей и входа в npm выполните:
108
+
109
+ ```sh
110
+ npm publish --access public
111
+ ```
112
+
113
+ Перед упаковкой npm автоматически выполнит сборку через `prepack`.
114
+
115
+ ```sh
116
+ npm run typecheck
117
+ npm test
118
+ npm run build
119
+ npx playwright install chromium
120
+ npx playwright test
121
+ npm run test:package
122
+ ```
123
+
124
+ Можно использовать установленный Chrome: `PLAYWRIGHT_CHANNEL=chrome npx playwright test` (в PowerShell задайте переменную окружения отдельно). Тесты используют временные директории и не требуют платного вызова LLM. Проверки реальных CLI и экспортных шаблонов зависят от их установки и авторизации.
125
+
126
+ `npm run dev` запускает сервер с перезагрузкой. Для проверки интерфейса предпочтительна собранная версия с единым origin: `npm run build && npm start`.
127
+
128
+ `npm run test:package` устанавливает собранный пакет во временную папку и проверяет CLI, web-интерфейс и API. CI запускает проверки на трёх ОС с Godot 4.7.2, скачанным из официального релиза с проверкой SHA-512.
129
+
130
+ Для дополнительной проверки реального агента: `npm run smoke:agent -- codex` (или `kimi`, `claude`). Это реальный вызов установленного CLI для диагностики прежних адаптеров, с расходом его подписки; основной интерфейс приложения использует Game Hub Core. Проверка создаёт временную игру, проходит утверждение, декомпозицию, исполнение и Godot-проверки; при сбое сохраняет диагностические файлы и путь к ним.
131
+
132
+ ## Границы версии
133
+
134
+ Это локальное однопользовательское приложение. Генерация выполняется через отдельное ядро, которое проверяет доступ UMGT и учитывает фактические токены. При отключённом аккаунте локальные проекты остаются доступны, новые AI-запросы блокируются. Локально хранятся только собственные токены Hub, а ключ UMGT хранится в зашифрованном виде на сервере ядра. Unity предусмотрена архитектурой; рабочие интеграции доступны для Godot, HTML5 и Roblox Studio. Godot экспортирует только цели, для которых доступны подходящие шаблоны и инструменты; кросс-компиляция и подпись зависят от ОС.
135
+
136
+ Дизайн использует установленный [taste-skill](https://github.com/Leonxlnx/taste-skill); версия зафиксирована в `skills-lock.json`. Собственные игровые наборы инструкций поставляются с явными версиями и лицензиями.
137
+
138
+ См. [Яндекс Игры и подключение Chrome](docs/yandex-games.md), [план](docs/plan.md), [API](docs/api.md), [архитектуру](architecture.md), [разбор источников ассетов](docs/asset-providers.md) и [результаты проверки](docs/validation.md). `br` и `arhit` относятся к разработке самого Hub и не требуются пользователям приложения.
139
+
140
+ ## Roblox Studio
141
+
142
+ В новом проекте выберите **Roblox Studio**: Hub зафиксирует 3D и платформу Roblox. Создаются Luau-каталоги сервер/клиент/общие модули, `default.project.json`, локальная сборка `builds/game.rbxlx` и 23 skills из [EL4CTEO/roblox-skills](https://github.com/EL4CTEO/roblox-skills), включая справочники и MIT-лицензию. Набор включён в Hub и устанавливается без интернета; ревизия сохраняется в extensions-lock.json.
143
+
144
+ «Открыть Studio» автоматически находит или устанавливает редактор, открывает place и подключает встроенный StudioMCP. Уже открытый place этого проекта сохраняет своё состояние. При первом запуске войдите в Studio и включите Assistant → … → Manage MCP Servers → Enable Studio as MCP server, затем нажмите «Проверить подключение» в Hub. Путь и Studio ID определяются автоматически, а идентификатор проекта проверяется перед каждым вызовом агента. Для ручного Play нажмите Play в Studio. «Проверить проект» проверяет структуру и упаковку: это не компиляция Luau и не подтверждение gameplay. Сборка Roblox создаёт локальный place; автоматической публикации нет. Возможности нативной сборки и настройка встроенного StudioMCP описаны в [docs/roblox.md](docs/roblox.md).
145
+
146
+ Демонстрационная игра: бег, прыжки, 20 монет, checkpoint и финиш:
147
+
148
+ ```sh
149
+ npm run build
150
+ npm run demo:roblox
151
+ # Повторная сборка сохраняет правки исходников:
152
+ npm run demo:roblox -- --rebuild
153
+ npm start -- --data-dir .artifacts/roblox/demo-hub
154
+ ```
155
+
156
+ Откройте `examples/roblox-coin-run/builds/game.rbxlx` в Studio и нажмите Play. WASD/стрелки — движение, пробел — прыжок; на телефоне — штатные джойстик и кнопка прыжка. Прототип не сохраняет прогресс между игровыми сессиями.
157
+
158
+ ## Обновления студии
159
+
160
+ Студия автоматически проверяет новую стабильную версию `@darkclaw921/umgt` в npm при запуске и раз в час. Уведомление показывает номер версии, описание изменений и команды обновления для npx и глобальной установки. Проверка не требует аккаунта и не передаёт проекты или ключи. Уведомление можно отложить на сутки; обновление запускается пользователем после завершения задач.
161
+
162
+ При выпуске новой версии обновите `version` и `umgtReleaseNotes` (`title` и массив `changes`) в `package.json`, обновите lockfile, выполните проверки и опубликуйте пакет с тегом `latest`. Именно эти заметки увидят пользователи установленных версий.
@@ -0,0 +1,105 @@
1
+ # Game Hub architecture
2
+
3
+ The local CLI hosts a Fastify API and the built React interface on loopback. Shared DTOs cross the browser/server boundary; the remote Core adapter sends AI requests to a separate server, while local tools and engine adapters execute on the user computer.
4
+
5
+ - [CLI](src/server/cli.ts) parses startup options, starts the server, opens the browser, runs diagnostics and handles shutdown. [Executable](bin/lm-game-hub.js) loads the compiled CLI.
6
+ - [Application](src/server/app.ts) composes security, multipart upload support, health checks, SSE, domain routes and static hosting. Domain registration receives `HubContext` with the store and event bus.
7
+ - [Security](src/server/security.ts) enforces loopback Host and matching Origin, and exchanges a launch token for an HttpOnly SameSite cookie.
8
+ - [Store](src/server/store.ts) uses SQLite with WAL and prepared statements for JSON documents and ordered events. Global settings/project index reside under the configured data directory; each game stores its workflow documents under `.lm-game-hub/state.sqlite`.
9
+ - [Events](src/server/events.ts) persists events before broadcast and serves replayable SSE streams with monotonic IDs. Each connection uses one asynchronous writer that waits for `drain`, yields between history pages and reads missed events from SQLite. Early subscription and catch-up notifications preserve ordering during backpressure without an in-memory event queue; terminal streams release their interval, subscription and pending drain listener.
10
+ - [Shared types](src/shared/types.ts) define projects, agent/engine identifiers, plans, tasks, runs, settings, skill manifests and assets. [Shared settings](src/shared/settings.ts) supply consistent browser/server Codex defaults (gpt-6.1-sol, medium), resolve missing or blank legacy selections and preserve explicit provider choices without changing global CLI configuration.
11
+
12
+ Build output separates server modules (`dist/server`), shared modules (`dist/shared`) and the Vite browser bundle (`dist/web`). The package requires Node.js >=24.13 for built-in SQLite.
13
+
14
+ ## Engine and asset integration
15
+
16
+ - HTML5 uses [TypeScript/Vite scaffolds](src/server/html5.ts), Phaser for 2D and Three.js for 3D; engine operations and CLI diagnostics dispatch by engine. Yandex Games is a publishing platform that implies Web, not a substitute for the selected engine. [Validated platform settings](src/server/yandex-config.ts) feed scaffolds, planning and build configuration hashes.
17
+ - [Common Yandex runtime](src/server/templates/yandex-sdk.ts) ships into HTML5 and the [Godot JavaScriptBridge/custom shell](src/server/yandex-godot.ts). It initializes SDK once, tracks overlapping pause reasons, awaits asynchronous rewards and serializes cloud saves with token-ledger purchase recovery. UTF-8 limits and documented request quotas are enforced; local backups are namespaced by application ID or path and failed cloud writes remain explicit pending progress. Godot rewards await a retained acknowledgement callback after game-side persistence.
18
+ - [Web builds](src/server/web-build.ts) create bounded immutable ZIPs, check entrypoints/private files/SDK integration and retain configuration, ZIP and content hashes. Preview serves only approved build files on loopback and proxies the fixed official development SDK without opening a browser or imposing incompatible cross-origin isolation headers. Archive checks are separate from runtime and console validation.
19
+ - [Publication service](src/server/publication.ts) persists runs, stages and observed evidence independently of the game-development workflow. Start, resume and moderation revalidate the approved build; cancellation and restart never automatically replay external mutations. [Browser gateway](src/server/browser-gateway.ts) wraps a separately connected Chrome MCP, limits agents to owned background console/preview tabs and immutable uploads, and delegates login/CAPTCHA/legal actions to the user. [Scoped browser MCP](src/server/publication-mcp.ts) is supplied alongside assets through provider-specific multiple-MCP configurations; exact browser-tool approvals cannot authorize arbitrary commands or raw JavaScript. See [Yandex guide](docs/yandex-games.md).
20
+
21
+ - [Godot adapter](src/server/engine.ts) discovers installed Godot executables, scaffolds 2D/3D scenes and export presets, verifies imports/scripts/runtime, controls editor and game processes, and runs isolated static Web previews on a separate loopback port. Standalone script checks exclude only the project's root `res://addons` directory: addon internals load in their project context during full editor import, authored-script dependency loading and startup. Nested authored directories named `addons` remain checked. Editor sessions are tracked separately from exclusive game/build operations.
22
+ - [Background game launcher](src/server/game-launch.ts) uses macOS LaunchServices without activation, redirects native logs and tracks the exact new executable/nonce-tagged PID separately from the waiting launcher. Revalidated termination preserves other instances; bounded log reads and cleanup retain engine-operation lifecycle. The shared development policy is included in future task prompts and managed project instructions. Other desktop focus behavior remains OS-dependent.
23
+ - [Process runner](src/server/process.ts) executes binaries with argument arrays, bounded output, deadlines and cancellation of process groups. Shutdown stops managed child processes.
24
+ - [Skill packs](src/server/skills.ts) defines original versioned Godot guidance, chooses dimension/genre recommendations, installs additive explicit selections for Codex/Claude/Kimi project instructions, and maintains extension provenance in `.lm-game-hub/extensions-lock.json`.
25
+ - [Assets](src/server/assets.ts) normalizes Poly Haven/ambientCG API results and the [verified catalog](src/server/asset-catalog.ts) of Kenney packs/OpenGameArt audio. UI and agent tools share search/details/import functions. Downloads use a provider domain allowlist, bounded redirects and byte limits; ZIP extraction rejects unsafe paths/symlinks, skips validated macOS metadata and ignores unsupported executable formats. Imports stage in private project metadata folders before an atomic move into `assets/`, preserving source, author, license and file lists. CC-BY resources retain attribution and an import-owned credits file. User uploads can stage outside the game until final confirmation; project-bound handles and checked receipts make retries idempotent.
26
+ - [Asset selection](src/server/asset-selection.ts) stores plan-bound needs, catalog candidates, user choices and import state. A read-only discovery branch runs beside task decomposition; execution requires explicit selection confirmation and prepared files. Project snapshots and SSE restore the desktop wizard independently of transient model output. Uploads stage outside the game until finalization. See [selection workflow](docs/asset-selection.md).
27
+ - [Asset media](src/server/asset-media.ts) exposes authenticated indexed file galleries and streaming previews for project/staged/imported/provider resources. HEAD, bounded Range, canonical paths, symlink and signature checks, same-origin/private headers and sandbox CSP protect native browser previews. Official provider archives cache outside games. [Shared media UI](src/web/AssetMediaPreview.tsx) renders real image/audio/video files across catalog/details/wizard/imported resources with pagination, explicit playback, cancellation and failure feedback. See [media contract](docs/asset-media.md).
28
+ - [Optional plugins](src/server/plugins.ts) downloads checksum-pinned GUT sources, extracts only the plugin subtree and enables it in Godot settings while preserving existing configuration.
29
+
30
+ Generated games keep code, scenes, resources and asset folders separate. Web exports use compatibility rendering and a nonthreaded preset by default. Scaffolds enable S3TC/BPTC and ETC2/ASTC texture imports for desktop and ARM/Web targets. External editors can coexist with agent development, while domain-provided idle guards protect browser-driven project mutations during active agent operations.
31
+
32
+ ## Agent workflow
33
+
34
+ - [Domain routes](src/server/routes.ts) validate project/settings requests and compose the workflow with engine, extension and asset endpoints.
35
+ - [Directory picker](src/server/directory-picker.ts) opens a native directory chooser through fixed executable arguments: AppleScript on macOS, an encoded STA PowerShell Forms script on Windows, and zenity/kdialog on Linux. The authenticated route allows one dialog per server, canonicalizes existing directories, and cancels the child on disconnect, shutdown or deadline. Route composition accepts an injected `DirectoryPicker` adapter; directory selection and empty-project validation remain separate operations.
36
+ - [Workflow](src/server/workflow.ts) persists interviews, versioned plans, approvals, epics, dependency graphs, verification evidence and execution attempts. Separate read-only sessions handle discovery and decomposition; approved tasks execute sequentially. Recovery marks interrupted runs and retains completed work.
37
+ - [Core client](src/server/core-client.ts) stores only Hub tokens in a private file and exchanges/refreshes credentials against the separate game-hub-core service. [Core adapter](src/server/agents/core.ts) routes all default workflow and publication AI calls through that server; [local tools](src/server/agents/core-tools.ts) run approved commands, enforce file boundaries and expose scoped MCP tools. Read-only sessions omit mutation tools, and publication sessions expose only the scoped browser gateway. Legacy CLI adapters remain for compatibility and isolated adapter tests; production routes do not select them. The independent Core repository owns PostgreSQL, UMGT checks, encrypted UMGT keys, provider credentials, actual token accounting, billing retries and administrative audit. See [integration contract](docs/core.md).
38
+ - [Provider activity normalization](src/server/agents/activity.ts) maps observed reasoning/text/tool lifecycles to fixed safe labels and identifier-only details, deduplicating phase updates. [Activity projection](src/server/activity.ts) stores at most 40 current-run records with monotonic per-run sequence; workspace snapshots restore state independently of SSE replay length. Workflow namespaces provider item IDs by request, prioritizes permission waits, records independent Godot verification and terminates unfinished activity on stop/failure/recovery. Hidden reasoning content is excluded from activity and generic provider journals.
39
+ - [Asset MCP](src/server/mcp.ts) launches a stdio tool server as a child process. Project-scoped tokens permit only that project's asset endpoint; imports require active approved execution and use the application's import service.
40
+
41
+ [Structured interview](src/server/interview.ts) validates public LLM rounds and typed answers, derives conservative legacy A/B/C forms without GET writes, and formats answer context. Workflow atomically persists linked messages/rounds, rejects stale or concurrent submissions, suppresses protocol JSON deltas, and starts the next read-only turn. Completed rounds preserve explicit planning/approval gates. Bounded whole-message start requests after completion initiate a fresh reviewable plan; plan interview provenance and workspace freshness prevent approval or execution of old tasks against a changed brief. See [interview protocol](docs/interactive-interview.md).
42
+
43
+ Workflow persists a bounded five-stage approval/decomposition journal on each run. Workspace exposes the latest decomposition separately from current execution, preserving preparation history through handoff; stage SSE and sequence support reload/replay reconciliation. Counts reflect completed installation or committed task creation; cancellation/recovery terminate active stages. See [approval journal](docs/approval-journal.md).
44
+
45
+ The central workflow permission bridge applies the persisted automatic action policy across providers, records identifier-only decisions and resolves existing pending actions when enabled. Interactive questions remain explicit user input; provider read-only restrictions and task verification remain authoritative. See [automatic action approvals](docs/automatic-approvals.md).
46
+
47
+ ## Browser workspace
48
+
49
+ Agent permission settings expose the persisted automatic-action policy while preserving manual questions and older-runtime compatibility. The approval journal displays only matching factual auto-approval events; browser controls do not implement or bypass authorization. See [permission UI](docs/agent-permissions-ui.md).
50
+
51
+ [Workflow journal](src/web/WorkflowJournal.tsx) implements the selected expanding approval log in both plan modal and workspace. Its [projection](src/web/workflow-journal.ts) separates pending HTTP requests from accepted server runs and merges durable decomposition stages by sequence across snapshots/replay. Actual task counts and existing activity/permission state drive execution feedback; no estimated progress or new execution commands are introduced. See [journal UI](docs/workflow-journal-ui.md) and the isolated [QA fixture](tests/fixtures/journal-hub.ts).
52
+
53
+ - [App](src/web/App.tsx) owns launch-token exchange, project selection, SSE updates, navigation, engine controls and lazy views. [API client](src/web/api.ts) centralizes typed requests and errors.
54
+ - [Desktop asset wizard](src/web/AssetSelectionWizard.tsx) opens after plan approval and restores plan-bound needs/choices from workspace snapshots. It offers catalog alternatives, image/audio previews, editable queries, staged files, optional skips and explicit final confirmation. The journal and resource view reopen it; frontend start/resume controls share the server readiness gate. Supplied and skipped decisions are included in implementation prompts rather than inferred from opaque IDs.
55
+
56
+ [Activity state](src/web/activity.ts) reconciles authoritative run snapshots with normalized SSE by project, run, stable item ID and monotonic sequence. Terminal runs and newer snapshots cannot be reactivated by history. The lazy [activity strip](src/web/AgentActivity.tsx) shows actual current actions, safe short details and a bounded chronological disclosure across sections; pending permission takes priority, disconnected/terminal states stop animation, and reduced motion is respected. Chat, task and plan labels share this presentation. See [activity UI behavior and verification](docs/agent-activity-ui.md).
57
+
58
+ Pending agent requests are surfaced once in a sticky workspace notice outside section content. Its navigation action opens the agent conversation at the pending card; navigation badges and task/chat/log labels distinguish waiting for the user from active work. Permission cards display provider-supplied reason, command and working directory as escaped text, with the complete method/payload in collapsed technical details. Existing approval/decline requests and sandbox policy remain owned by the agent adapters and workflow.
59
+ - [Workflow views](src/web/workflow.tsx) implement project creation, chat/questions, plan versions and task controls. The shared `Markdown` renderer uses react-markdown and remark-gfm for semantic plan/chat content, escaped raw HTML, explicit safe links and scrollable code/table blocks. [Resource views](src/web/resources.tsx) implement asset search, browser favourites, file imports, extension installation and connection settings.
60
+
61
+ [Generated text state](src/web/generated-text.ts) tracks live project/run provenance and consumed source ranges. [Lightweight frost fragments](src/web/GeneratedText.tsx) apply the selected reveal to new content, bounded to 32 simultaneous effects and disabled for reduced motion or hidden documents. Inline-compatible text-shadow frost uses a900ms clock independent of appended tail length; short-lived clocks transfer unfinished reveals to canonical messages/plans. [Generated Markdown](src/web/GeneratedMarkdown.tsx) stays in the lazy workflow bundle, preserves semantic formatting during streaming and uses stable component identities so settled DOM is retained. Chat, live/canonical plans, task/epic prose and interview public text share the effect; static labels, user answers and technical logs remain plain. See [generated text UI](docs/generated-text-ui.md) for replay, handoff, resource limits and validation scope.
62
+
63
+ The [interview round view](src/web/InterviewRound.tsx) maps server-provided rounds, including recognized legacy questions, to native grouped choice/range/text controls inside chat. [Interview helpers](src/web/interview.ts) validate and restore browser drafts, serialize typed answers and format read-only accepted summaries. Answer submission persists through the workflow API and requests the next model round; the plan remains a separate user-controlled step. A completed-interview CTA creates a fresh draft, and a planning run returned from an explicit natural start request opens the review modal. Workspace plan freshness gates approval and task start/resume in every frontend entry point. See [interactive interview UI](docs/interactive-interview-ui.md).
64
+
65
+ Project creation starts without a selected directory. The browser requests the server-side native chooser and displays its result as read-only text, preserving filesystem whitespace. Pending selection blocks submission, closing and reentry; native cancellation preserves the previous selection and errors keep the form available for retry.
66
+ - [UI primitives](src/web/ui.tsx) use Radix dialogs and shared operation feedback. [Styles](src/web/styles.css) provide theme tokens, responsive layouts, focus states and reduced-motion behavior. [Entry](src/web/main.tsx) configures React and Motion.
67
+
68
+ ## Children's interface and interview orchestrator
69
+
70
+ `HubSettings.interfaceMode` selects the interface: `robot` (default for the redesigned UI), `road`, or `classic` (the full workspace). [Shared aspects](src/shared/aspects.ts) define the eight game-brief aspects, coverage statuses, interface modes and `normalizeCoverage`. When a mode is stored, [interview](src/server/interview.ts) `orchestratorInstructions` extends the interview prompt: every answer is checked against its aspect, vague answers keep the aspect `partial` and get a clarifying question, and each response reports `coverage`; questions carry an optional `aspect`. `orchestratedInterviewOutput` allows one question per round, and the children's modes instruct the model to ask exactly one in simple language. [Workflow](src/server/workflow.ts) stores the verdict as `InterviewRound.coverage`. Installations without a stored mode keep the original protocol.
71
+
72
+ - [Kids app](src/web/kids/KidsApp.tsx) replaces the classic shell in `robot` and `road` modes. Screens: first-run questionnaire (`ProfileFlow`), home with a greeting, a new-game tile and a widget per game (`Home`), step-by-step project creation (`CreateFlow`), project entry with the constellation, the working screen (`Stage`: collapsible `StarList` of steps on the left, question and answers in the centre, `Dock` with text, voice and send at the bottom), plan, materials, build and play stages, star celebration and `SettingsScreen`. It reuses the existing API, `PermissionCard`, the plan dialog and the asset wizard.
73
+ - [Progress](src/web/kids/progress.ts) derives the current stage and the twelve stars (eight aspects, four production stages) from workspace state.
74
+ - [Stars](src/web/kids/Stars.tsx) renders stars, the counter, the constellation, the robot and the brand logo. [Kids styles](src/web/kids/kids.css) hold the brand tokens and both layouts.
75
+ - [Voice](src/web/kids/voice.ts) wraps browser speech recognition (Russian) as `useVoice`. [Voice input](src/web/VoiceInput.tsx) adds dictation to the classic composer; [orchestrator panel](src/web/OrchestratorPanel.tsx) shows aspect coverage in the classic chat.
76
+ - `HubSettings.profile` (name, age) comes from the questionnaire; the settings route accepts `profile: null` to clear it, and `orchestratorInstructions` passes it to the interview prompt.
77
+ - [Push service](src/server/push.ts) keeps VAPID keys and browser subscriptions in the Hub store, exposes `/api/v1/push` routes and forwards workflow events (`pushMessage`) as Web Push. [Notifications](src/web/kids/notifications.ts) registers the [service worker](public/sw.js) and manages the browser subscription. [Manifest](public/manifest.webmanifest), favicon and icons in `public/` make the Hub installable.
78
+ - [Classic interface fixture](tests/fixtures/classic-interface.ts) pins end-to-end fixtures to the classic workspace.
79
+ - [Glossary](src/web/kids/Glossary.tsx) keeps game-development terms in build steps and materials and adds a "?" with a child-level explanation (`Explain`, `glossaryParts`). [Words](src/web/kids/words.ts) `kidWords` softens jargon only in server error texts.
80
+ - [i18n](src/web/kids/i18n.ts) translates the children's interface: Russian source text is the key (`T` tagged template, `N` for module-level tables, `tr`), English lives in [en](src/web/kids/en.ts) and [glossary-en](src/web/kids/glossary-en.ts). `HubSettings.language` selects the language; on the server `englishOutputNote` is appended to model prompts and push texts follow it.
81
+ - [Engines](src/web/kids/engines.tsx) lists the engines offered at creation (`ENGINES`: HTML5, Roblox, Godot; Unity and Unreal as coming soon), their logos (`EngineLogo`) and the play targets per engine (`platformChoices`).
82
+ - [Art](src/web/kids/art.ts) loads optional illustrations from [assets/kids](src/web/assets/kids/README.md) (robot poses, stars, stage backgrounds) with built-in vector fallbacks.
83
+ - [Brand logo](src/web/assets/umgt-logo.png) and self-hosted Manrope/Unbounded fonts are bundled by Vite; classic theme tokens in [styles](src/web/styles.css) use the same palette.
84
+
85
+ ## Distribution and toolchain
86
+
87
+ [Optional live smoke](scripts/smoke-agent.mjs) provides a command-line client for the approved-plan agent workflow and stores failure artifacts outside the generated project. [Godot setup](scripts/setup-godot.mjs) locates/downloads a CI toolchain and exposes its executable path. [Package checker](scripts/check-package.mjs) installs the packed artifact in an isolated prefix and invokes its installed executable/API boundary.
88
+
89
+ [CI](.github/workflows/ci.yml) defines macOS, Windows and Linux jobs for the Node/Godot toolchain and package pipeline. The npm package includes the CLI, compiled server/shared modules and browser assets; SQLite data and credentials remain outside the package.
90
+
91
+ [UI report generator](.artifacts/ui-report/generate.mjs) converts an explicit evidence manifest and local screenshots into a standalone Russian HTML document. It embeds image data, escapes text and supplies responsive navigation, image zoom and print styles; it consumes observations without executing application scenarios.
92
+
93
+ Project scaffolding is staged in a private directory and committed only after scene/configuration/skill generation succeeds. Failure removes generated entries and retains pre-existing files. Canonical project roots support filesystem aliases; managed skill and asset paths reject descendant symlinks before any write. Engine diagnostics report release-specific Web/Desktop export template availability separately from editor availability. Template discovery follows Godot self-contained markers, including the Steam editor_data directory outside the macOS .app bundle; unmarked adjacent directories are ignored. Export requests reject missing selected-platform templates before launching the exporter and preserve existing project configuration. Export process errors remain failures even when the process exits zero and writes output files. Managed operations reserve their project lock before executable discovery; cancellation propagates through discovery, verification and process shutdown, and server shutdown waits for operation completion before closing persistence.
94
+
95
+ Task asset selection is part of the workflow contract: `Task.assetRefs` holds resolved catalog metadata or imported project resources, including an optional project-relative directory. `Workflow.attachAsset(projectId, taskId, { provider, id })` permits up to 20 unique references on unfinished tasks, rechecks the idle state and task version after provider lookup, persists the updated task and emits `task.updated`. Execution prompts receive these exact references; a catalog selection is not treated as downloaded content.
96
+
97
+ Task completion requires a structured implementation result with evidence for every acceptance criterion and a separate engine verification pass controlled by the Hub. The independent pass imports resources, parses GDScript and starts Godot headlessly; it does not independently prove arbitrary gameplay or human playtesting criteria. Those criteria need their own recorded checks or explicit human validation, and missing export templates cannot count as a successful build.
98
+
99
+ Addon libraries may depend on initialization order and are not treated as independent script entrypoints. Import, authored-script checks and startup retain strict detection of engine errors, including errors originating in referenced addons. Unused or disabled addon internals are not individually executed; plugin-specific behavior needs the plugin's own tests.
100
+
101
+ ### Yandex publication materials and desktop UI
102
+
103
+ `src/server/publication-materials.ts` owns persisted PNG/JPEG/WebP upload decoding, canonical PNG normalization, content hashes, project/build provenance and bounded galleries. `sharp` validates full raster content; the browser gateway captures only owned game-preview tabs. Publication resolution validates immutable files immediately before exposing them to scoped MCP tools.
104
+
105
+ `src/web/YandexConfigFields.tsx` shares SDK configuration across creation and project settings. Lazy `YandexGamesView.tsx` coordinates configuration, diagnostics, current immutable builds, publication lifecycle and explicit moderation. `PublicationMaterials.tsx` implements real image previews, upload byte progress/cancel, download/delete, preview capture, provenance and SSE refresh. The Hub is desktop-only; mobile settings describe exported games.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../dist/server/cli.js';
3
+
4
+ main().catch(error => {
5
+ console.error(error instanceof Error ? error.message : error);
6
+ process.exitCode = 1;
7
+ });
@@ -0,0 +1,17 @@
1
+ import type { AgentActivity } from '../shared/types.js';
2
+ import type { DocumentStore } from './store.js';
3
+ import { type ActivitySignal } from './agents/activity.js';
4
+ export declare function activitySnapshot(db: DocumentStore, runId?: string): {
5
+ activities: AgentActivity[];
6
+ activity?: AgentActivity;
7
+ };
8
+ /** Bounded durable current-run projection; the existing event journal stays intact. */
9
+ export declare class ActivityLog {
10
+ private db;
11
+ readonly runId: string;
12
+ private publish;
13
+ private sequence;
14
+ constructor(db: DocumentStore, runId: string, publish: (activity: AgentActivity) => void);
15
+ record(signal: ActivitySignal): AgentActivity | undefined;
16
+ finish(status: 'completed' | 'failed' | 'cancelled', prefix?: string): void;
17
+ }
@@ -0,0 +1,55 @@
1
+ import { activityLabels, safeIdentifier } from './agents/activity.js';
2
+ const live = (status) => status === 'running' || status === 'waiting_permission';
3
+ export function activitySnapshot(db, runId) {
4
+ const activities = db.list('activities').filter(item => item.runId === runId).sort((a, b) => a.sequence - b.sequence).slice(-40);
5
+ const current = activities.filter(item => live(item.status));
6
+ const activity = current.filter(item => item.status === 'waiting_permission').at(-1)
7
+ ?? current.filter(item => ['command', 'search', 'read', 'write', 'tool'].includes(item.kind)).at(-1)
8
+ ?? current.at(-1) ?? activities.at(-1);
9
+ return { activities, activity };
10
+ }
11
+ /** Bounded durable current-run projection; the existing event journal stays intact. */
12
+ export class ActivityLog {
13
+ db;
14
+ runId;
15
+ publish;
16
+ sequence;
17
+ constructor(db, runId, publish) {
18
+ this.db = db;
19
+ this.runId = runId;
20
+ this.publish = publish;
21
+ this.sequence = Math.max(0, ...db.list('activities').filter(item => item.runId === runId).map(item => item.sequence));
22
+ }
23
+ record(signal) {
24
+ if (!signal || typeof signal.id !== 'string' || !signal.id || signal.id.length > 240 || !Object.hasOwn(activityLabels, signal.kind)
25
+ || !['running', 'waiting_permission', 'completed', 'failed', 'cancelled'].includes(signal.status))
26
+ return;
27
+ const id = `${this.runId}:${signal.id}`, previous = this.db.get('activities', id);
28
+ if (previous && !live(previous.status))
29
+ return previous;
30
+ const label = signal.status === 'waiting_permission' ? 'Ожидает разрешения' : activityLabels[signal.kind];
31
+ const detail = safeIdentifier(signal.detail);
32
+ if (previous?.status === signal.status && previous.kind === signal.kind && previous.detail === detail)
33
+ return previous;
34
+ const timestamp = new Date().toISOString();
35
+ const activity = { id, runId: this.runId, kind: signal.kind, status: signal.status, label, detail,
36
+ createdAt: previous?.createdAt ?? timestamp, updatedAt: timestamp, sequence: ++this.sequence };
37
+ this.db.put('activities', activity);
38
+ const all = this.db.list('activities').sort((a, b) => Number(live(a.status)) - Number(live(b.status)) || a.sequence - b.sequence);
39
+ for (const old of all.slice(0, Math.max(0, all.length - 40)))
40
+ this.db.delete('activities', old.id);
41
+ this.publish(activity);
42
+ return activity;
43
+ }
44
+ finish(status, prefix = '') {
45
+ for (const activity of this.db.list('activities')) {
46
+ const id = activity.id.slice(this.runId.length + 1);
47
+ if (activity.runId === this.runId && id.startsWith(prefix) && live(activity.status)) {
48
+ // Missing tool completion is not evidence of tool success.
49
+ const terminal = status === 'completed' && ['command', 'search', 'read', 'write', 'tool'].includes(activity.kind) ? 'cancelled' : status;
50
+ this.record({ id, kind: activity.kind, status: terminal, detail: activity.detail });
51
+ }
52
+ }
53
+ }
54
+ }
55
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/server/activity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { AgentActivityKind, AgentActivityStatus } from '../../shared/types.js';
2
+ export interface ActivitySignal {
3
+ id: string;
4
+ kind: AgentActivityKind;
5
+ status: AgentActivityStatus;
6
+ detail?: string;
7
+ }
8
+ export declare const activityLabels: Record<AgentActivityKind, string>;
9
+ /** Status detail is an identifier, never arguments, output, queries or reasoning. */
10
+ export declare function safeIdentifier(value: unknown): string | undefined;
11
+ export declare function commandActivity(command: unknown): {
12
+ kind: AgentActivityKind;
13
+ detail?: string;
14
+ };
15
+ export declare function toolActivity(name: unknown, input?: unknown): {
16
+ kind: AgentActivityKind;
17
+ detail?: string;
18
+ };
19
+ /** Deduplicates phase signals so token streams cannot flood persistence/SSE. */
20
+ export declare class ActivityReporter {
21
+ private emit;
22
+ private states;
23
+ private phaseId?;
24
+ private generation;
25
+ private generating;
26
+ constructor(emit: (type: string, payload: unknown) => void);
27
+ update(id: string, kind: AgentActivityKind, status: AgentActivityStatus, detail?: string): void;
28
+ phase(kind: 'thinking' | 'answering' | 'waiting', id?: string): void;
29
+ /** An accepted turn is processing even when private reasoning is not streamed. */
30
+ accepted(): void;
31
+ endPhase(): void;
32
+ tool(id: string, kind: AgentActivityKind, status?: AgentActivityStatus, detail?: string): void;
33
+ finish(id: string, status?: 'completed' | 'failed' | 'cancelled'): void;
34
+ progress(id: string, status: AgentActivityStatus): boolean;
35
+ private waitIfIdle;
36
+ }
@@ -0,0 +1,117 @@
1
+ export const activityLabels = {
2
+ waiting: 'Ожидает ответа агента', thinking: 'Думает', answering: 'Готовит ответ',
3
+ command: 'Выполняет команду', search: 'Ищет', read: 'Читает файл', write: 'Изменяет файлы', tool: 'Использует инструмент',
4
+ };
5
+ /** Status detail is an identifier, never arguments, output, queries or reasoning. */
6
+ export function safeIdentifier(value) {
7
+ if (typeof value !== 'string')
8
+ return undefined;
9
+ const name = value.replaceAll('\\', '/').split('/').at(-1)?.split(/[?#]/)[0];
10
+ if (!name || !/^[\p{L}\p{N}_.:+ @()-]{1,80}$/u.test(name) || /(?:bearer|token|password|secret|api[_-]?key)\s*[=:]/i.test(name))
11
+ return undefined;
12
+ return name;
13
+ }
14
+ export function commandActivity(command) {
15
+ if (typeof command !== 'string')
16
+ return { kind: 'command' };
17
+ // Conservatively classify only simple commands. Shell pipelines/redirections
18
+ // may do other work; arguments may contain credentials and are never shown.
19
+ const first = command.trim().match(/^(?:"([^"]+)"|'([^']+)'|([^\s]+))/);
20
+ const detail = safeIdentifier(first?.[1] ?? first?.[2] ?? first?.[3]);
21
+ const simple = !/[|&;<>`\n]|\$\(/.test(command);
22
+ const kind = simple && detail && ['rg', 'grep', 'find', 'fd'].includes(detail) ? 'search'
23
+ : simple && detail && ['cat', 'head', 'tail', 'less', 'more'].includes(detail) ? 'read' : 'command';
24
+ return { kind, detail };
25
+ }
26
+ export function toolActivity(name, input) {
27
+ const tool = typeof name === 'string' ? name : '';
28
+ const args = input && typeof input === 'object' ? input : {};
29
+ if (/^(?:bash|shell|execute|run_command|terminal)$/i.test(tool))
30
+ return commandActivity(args.command);
31
+ const kind = /^(?:read|read_file|readfile|view_file)$/i.test(tool) ? 'read'
32
+ : /^(?:write|write_file|edit|edit_file|notebookedit|apply_patch)$/i.test(tool) ? 'write'
33
+ : /(?:search|webfetch|web_fetch|^glob$|^grep$|^find$)/i.test(tool) ? 'search' : 'tool';
34
+ const detail = kind === 'read' || kind === 'write' ? safeIdentifier(args.file_path ?? args.path)
35
+ : /^[\p{L}\p{N}_.:+-]{1,80}$/u.test(tool) ? safeIdentifier(tool) : undefined;
36
+ return { kind, detail };
37
+ }
38
+ /** Deduplicates phase signals so token streams cannot flood persistence/SSE. */
39
+ export class ActivityReporter {
40
+ emit;
41
+ states = new Map();
42
+ phaseId;
43
+ generation = 0;
44
+ generating = false;
45
+ constructor(emit) {
46
+ this.emit = emit;
47
+ }
48
+ update(id, kind, status, detail) {
49
+ const previous = this.states.get(id);
50
+ if (previous && ['completed', 'failed', 'cancelled'].includes(previous.status))
51
+ return;
52
+ const signal = { id, kind, status, detail: safeIdentifier(detail) };
53
+ if (previous && previous.kind === kind && previous.status === status && previous.detail === signal.detail)
54
+ return;
55
+ this.states.set(id, signal);
56
+ this.emit('agent.activity', signal);
57
+ if (this.states.size > 160) {
58
+ const oldest = [...this.states].find(([, value]) => ['completed', 'failed', 'cancelled'].includes(value.status));
59
+ const key = oldest?.[0] ?? this.states.keys().next().value;
60
+ if (key)
61
+ this.states.delete(key);
62
+ }
63
+ }
64
+ phase(kind, id) {
65
+ const previous = this.phaseId ? this.states.get(this.phaseId) : undefined;
66
+ if (previous?.kind === kind && previous.status === 'running')
67
+ return;
68
+ this.endPhase();
69
+ this.phaseId = id ?? `phase-${++this.generation}`;
70
+ this.update(this.phaseId, kind, 'running');
71
+ }
72
+ /** An accepted turn is processing even when private reasoning is not streamed. */
73
+ accepted() {
74
+ this.generating = true;
75
+ const running = [...this.states.values()].filter(item => item.status === 'running');
76
+ if (!running.length || running.every(item => item.kind === 'waiting'))
77
+ this.phase('thinking');
78
+ }
79
+ endPhase() {
80
+ if (this.phaseId) {
81
+ const previous = this.states.get(this.phaseId);
82
+ if (previous?.status === 'running')
83
+ this.update(previous.id, previous.kind, 'completed', previous.detail);
84
+ }
85
+ this.phaseId = undefined;
86
+ }
87
+ tool(id, kind, status = 'running', detail) {
88
+ const previous = this.states.get(id);
89
+ if (previous?.kind === kind && previous.status === status && previous.detail === safeIdentifier(detail))
90
+ return;
91
+ if (status === 'running')
92
+ this.endPhase();
93
+ this.update(id, kind, status, detail);
94
+ if (status !== 'running')
95
+ this.waitIfIdle();
96
+ }
97
+ finish(id, status = 'completed') {
98
+ const previous = this.states.get(id);
99
+ if (previous)
100
+ this.update(id, previous.kind, status, previous.detail);
101
+ if (this.phaseId === id)
102
+ this.phaseId = undefined;
103
+ this.waitIfIdle();
104
+ }
105
+ progress(id, status) {
106
+ const previous = this.states.get(id);
107
+ if (!previous)
108
+ return false;
109
+ this.tool(id, previous.kind, status, previous.detail);
110
+ return true;
111
+ }
112
+ waitIfIdle() {
113
+ if (![...this.states.values()].some(item => item.status === 'running' || item.status === 'waiting_permission'))
114
+ this.phase(this.generating ? 'thinking' : 'waiting');
115
+ }
116
+ }
117
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/server/agents/activity.ts"],"names":[],"mappings":"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"}