@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
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,28 @@
1
+ <!doctype html>
2
+ <html lang="ru">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta name="theme-color" content="#12142B" />
7
+ <link rel="icon" href="/favicon.ico" sizes="48x48" />
8
+ <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png" />
9
+ <link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16.png" />
10
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
11
+ <link rel="manifest" href="/manifest.webmanifest" />
12
+ <meta name="application-name" content="Game Hub" />
13
+ <meta name="apple-mobile-web-app-title" content="Game Hub" />
14
+ <meta name="mobile-web-app-capable" content="yes" />
15
+ <meta
16
+ name="description"
17
+ content="Локальная мастерская игр. От идеи и плана до работающей игры с вашим AI-агентом."
18
+ />
19
+ <title>Game Hub — мастерская игр</title>
20
+ <script type="module" crossorigin src="/assets/index-sNciOZYG.js"></script>
21
+ <link rel="modulepreload" crossorigin href="/assets/jsx-runtime-CdVFa8IP.js">
22
+ <link rel="modulepreload" crossorigin href="/assets/ui-wHE_yBK0.js">
23
+ <link rel="stylesheet" crossorigin href="/assets/index-Izzbh11U.css">
24
+ </head>
25
+ <body>
26
+ <div id="root"></div>
27
+ </body>
28
+ </html>
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "/",
3
+ "name": "UMGT Game Hub",
4
+ "short_name": "Game Hub",
5
+ "description": "Локальная мастерская игр: расскажи идею, а робот-помощник напишет код.",
6
+ "lang": "ru",
7
+ "dir": "ltr",
8
+ "start_url": "/",
9
+ "scope": "/",
10
+ "display": "standalone",
11
+ "background_color": "#0E1024",
12
+ "theme_color": "#12142B",
13
+ "icons": [
14
+ {"src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any"},
15
+ {"src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any"},
16
+ {"src": "/icons/maskable-192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable"},
17
+ {"src": "/icons/maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable"}
18
+ ]
19
+ }
package/dist/web/sw.js ADDED
@@ -0,0 +1,25 @@
1
+ // Service worker for the installable Hub: push notifications only, no offline cache
2
+ // (the Hub is a live local server, stale cached screens would be misleading).
3
+ self.addEventListener('install', () => self.skipWaiting());
4
+ self.addEventListener('activate', event => event.waitUntil(self.clients.claim()));
5
+ self.addEventListener('fetch', () => {});
6
+
7
+ self.addEventListener('push', event => {
8
+ let message = { title: 'Game Hub', body: '', tag: 'hub' };
9
+ try { message = { ...message, ...event.data.json() }; } catch { /* Keep the generic text. */ }
10
+ event.waitUntil((async () => {
11
+ const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
12
+ // The open, focused Hub already shows the change on screen.
13
+ if (message.tag !== 'hub:test' && windows.some(client => client.focused)) return;
14
+ await self.registration.showNotification(message.title, { body: message.body, tag: message.tag, icon: '/icons/icon-192.png', badge: '/icons/favicon-32.png', lang: 'ru' });
15
+ })());
16
+ });
17
+
18
+ self.addEventListener('notificationclick', event => {
19
+ event.notification.close();
20
+ event.waitUntil((async () => {
21
+ const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
22
+ if (windows.length) return windows[0].focus();
23
+ return self.clients.openWindow('/');
24
+ })());
25
+ });
@@ -0,0 +1,33 @@
1
+ # Agent activity in the workspace
2
+
3
+ The compact strip under the workspace header shows provider-reported actions rather than rotating timer labels. Thinking, answer preparation, command execution, search, reading, writing and other tools use fixed Russian labels. Only a short safe detail is shown. The server supplies executable/file/tool names, not command arguments, stdout or private reasoning. The browser additionally removes control/bidirectional characters, masks obvious credentials and limits the detail to 160 characters. Details are plain React text, never HTML.
4
+
5
+ `AgentActivityStrip` is loaded lazily. It remains visible in all project sections; chat/task labels and the open plan dialog use the same presentation. A small icon opacity animation and short label transition respect reduced motion. The polite live region contains only the action label and concurrent-tool count, not answer text or token deltas. Answer streaming remains in the existing chat message.
6
+
7
+ Pending decisions override concurrent tools and stop the live animation. The existing permission banner and its single navigation action remain unchanged. When the connection drops, the strip stops animation and says it is reconnecting rather than presenting the last action as fresh activity. Terminal runs show a final summary without animation, while their bounded history remains inspectable.
8
+
9
+ The Actions disclosure lists up to 40 real actions in chronological start order with status and timestamps. Completion updates a row in place; it does not append a duplicate. A bounded overlay scrolls independently, preserving the chat viewport height on desktop and mobile. Escape closes it and returns focus to its summary. Changing project/run closes the disclosure.
10
+
11
+ The chat Stop row is a nonshrinking sibling of the scrollable message history, immediately above the composer. It stays fully visible and clickable while long answers stream or the user scrolls earlier messages. This corrects clipping observed in a real 1440 × 900 conversation; the browser regression includes twelve long prior messages, a long streamed answer, mobile 390 × 844, and a hit-test of the Stop button above the composer.
12
+
13
+ ## Snapshot and event reconciliation
14
+
15
+ `src/web/activity.ts` owns `ActivityState`. It selects an explicit project and initially waits for an authoritative workspace snapshot. `agent.activity` and `run.updated` events received during that fetch are buffered, then reconciled. Items use stable IDs and monotonic per-run sequence values; older/equal revisions cannot replace newer state. A newer run discards the previous run's history. Retired IDs, run start/update ordering and terminal-run precedence prevent old snapshots or replay events from restarting completed activity. Resume creates a new run ID.
16
+
17
+ The store accepts only the selected project's events. Other-project responses are ignored after a switch. Snapshot items must match the current run. Activity preceding its run event is held until the run is known. Terminal runs project any still-open item as completed, failed or cancelled, so a missing final tool event cannot leave a live animation. Active items are retained ahead of completed entries when the history limit is reached.
18
+
19
+ `App` merges workspace `activities` (or the optional singular `activity`) and normalized SSE into the controller. The existing event cursor still deduplicates transport replay. Old servers that omit activity fields use the honest fallback “Ожидает ответа” while a run is active; no synthetic thinking/tool events are invented. Raw protocol logs remain separate from the product activity view.
20
+
21
+ ## Verification
22
+
23
+ `tests/activity-ui.test.ts` exercises replay before a snapshot, overlapping stale snapshots, reconnect, terminal precedence, project/run isolation, events arriving before a run, permission priority with parallel tools, bounded chronological history, stop without final tool event, old-server fallback and credential/control-character handling.
24
+
25
+ `tests/e2e/activity.spec.ts` runs the compiled browser UI against real local HTTP, SSE, workflow normalization and SQLite with an explicitly injected provider fixture. Its command/read/write/search events are controlled test signals, not actual model tool calls. The browser verifies all labels, a pending permission and its existing CTA, streamed answer visibility, active-command reload, project switching, task/plan visibility, reduced-motion behavior, terminal replay and old-run rejection. Desktop/mobile history overlays preserve viewport dimensions. Actual installed-model verification is performed separately by the root agent and must not be inferred from fixture coverage.
26
+
27
+ ## Installed Codex acceptance — 7 October 2026
28
+
29
+ Root verified the final compiled UI using background headless Chromium and the installed Codex (`gpt-6.1-sol`, medium) in a read-only discussion of the existing test project. No commands, game-file edits, plan changes or development-task changes were requested. The actual run showed waiting → thinking → answer preparation → completed. Reload during the active run restored thinking; the final reload restored `idle`, `data-live=false` and an active connection. The mobile history disclosure showed the three completed actions. Provider user messages no longer appeared as tool calls.
30
+
31
+ Actual long-history desktop geometry was 1440 × 900 for both document and viewport. The Stop button occupied y=610–646, above the composer at y=658, and passed a real hit-test. At 390 × 844, document and viewport matched; Stop occupied y=546–582, above the composer at y=594, and remained visible/clickable. Thinking and answering were both captured with the control fully available. The evidence is recorded in `.artifacts/agent-activity-20261007/ui-verification.json` and its `screenshots/live-*.png` captures. Fixture captures remain separately named `.artifacts/activity-fixture-*.png`.
32
+
33
+ Final source validation: typecheck and production build passed; 160 unit/integration checks in 18 files passed in 23.98 seconds, and all seven browser scenarios passed in 22.5 seconds. Live Codex acceptance confirms the actual thinking/answering lifecycle and restoration. Command/search/read/write/tool categories and permission transitions in this feature's browser suite were exercised through the explicit provider fixture, not live Codex tool execution.
@@ -0,0 +1,43 @@
1
+ # Активность агента
2
+
3
+ Hub передаёт краткие состояния из фактических событий локальных Codex, Claude Code и Kimi. Поток ответа `agent.delta` и журнал инструментов сохраняются отдельно. Для начала запроса отображается ожидание; «Думает» появляется после подтверждения принятого turn Codex или при настоящем reasoning/thinking-сигнале, «Готовит ответ» — при генерации текста. Текст внутренних размышлений не копируется ни в activity, ни в журнал.
4
+
5
+ ## Контракт
6
+
7
+ `agent.activity` — обычное сохранённое SSE-событие Hub с `projectId`. Его payload:
8
+
9
+ ```ts
10
+ interface AgentActivity {
11
+ id: string;
12
+ runId: string;
13
+ kind: 'waiting' | 'thinking' | 'answering' | 'command' | 'search' | 'read' | 'write' | 'tool';
14
+ status: 'running' | 'waiting_permission' | 'completed' | 'failed' | 'cancelled';
15
+ label: string;
16
+ detail?: string;
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ sequence: number;
20
+ }
21
+ ```
22
+
23
+ Идентификатор стабилен при обновлениях действия: run ID + отдельный ID обращения к провайдеру + ID item/tool. Повторная попытка задачи не сталкивается с прежним ID. `sequence` увеличивается при каждом изменении в рамках run; дубликаты состояния не создают события. Сотни reasoning/text deltas не создают сотни activity-записей: меняется только фаза.
24
+
25
+ GET `/api/v1/projects/:id` включает `activities` и необязательное `activity`. SQLite хранит до 40 последних действий текущего run; при ограничении места сначала удаляются терминальные записи. Snapshot не требует восстановления из первых 1000 записей большого журнала. Следующий run очищает текущую проекцию, но сохраняет прежние SSE-события в журнале. Клиент фильтрует project/run, объединяет записи по ID и sequence и не оживляет завершённый run старыми replay-событиями.
26
+
27
+ Текущее действие выбирается с приоритетом разрешения, затем выполняющегося инструмента, затем фазы ответа/размышления/ожидания. Несколько инструментов могут оставаться активными параллельно. При завершении, ошибке, остановке или восстановлении после прерывания все незаконченные записи получают терминальное состояние. Если провайдер не сообщил окончание инструмента, окончание запроса само по себе не считается доказательством успеха этого инструмента: такая запись отменяется. Проверка Godot, выполняемая самим Hub после задачи, также имеет отдельное действие `tool` с `detail: "Godot: verify"`.
28
+
29
+ ## Провайдеры
30
+
31
+ - Codex: подтверждённый `turn/started` / успешный `turn/start` означает обработку запроса даже без reasoning stream; ожидание до принятия turn остаётся отдельной фазой. Поздний RPC ACK не откатывает активный ответ или уже завершённый turn. `item/started`, `item/completed`, reasoning-сигналы и agentMessage deltas обновляют дальнейшие действия. `userMessage`, `functionCallOutput` и прочие служебные item не считаются новыми инструментами. Команды учитывают `exitCode` и status; fileChange, webSearch, MCP/dynamic tools получают собственные категории. Модель `gpt-6.1-sol` и effort `medium` по умолчанию передаются по прежнему явному контракту.
32
+ - Claude SDK: thinking/text content blocks, tool_use и фактический tool_result. Закрытие блока аргументов не завершает инструмент. Detached tool_result означает продолжающуюся работу и также не считается успехом.
33
+ - Kimi ACP: agent_thought_chunk, agent_message_chunk, tool_call и частичные tool_call_update. Обновления без kind/title сохраняют известную категорию инструмента. История session/load не превращается в новую активность.
34
+
35
+ Adapter emit-контракт: `emit('agent.activity', {id, kind, status, detail?})`. Workflow добавляет run, время, sequence и фиксированную подпись. Запрос разрешения создаёт отдельное действие `waiting_permission`; ответ/отмена завершают его, а окончание самого инструмента определяется событиями провайдера.
36
+
37
+ ## Краткие детали и ограничения
38
+
39
+ Детали ограничены безопасными идентификаторами: имя исполняемой команды без аргументов, имя файла или инструмента. Вывод команд, поисковый запрос, ввод инструмента и содержимое файла в status не передаются. Простой `rg`/`grep` классифицируется как поиск, `cat`/`head` как чтение; shell pipelines и неоднозначные команды остаются категорией command. Полный журнал реальных инструментов сохраняет прежнее поведение. Нормализованные подписи не являются пересказом скрытой цепочки рассуждений.
40
+
41
+ В автоматических проверках используются настоящие RPC subprocess fixtures для Codex/Kimi и mocked Claude SDK; это доказательство протокола, а не живого вызова моделей. Backend-тесты проверяют bounded storage, 1100 записей журнала перед snapshot, разрешения, отказ, остановку, recovery, поздние события, смену run и отсутствие thought-содержимого. Живой Codex и browser E2E описываются отдельно в validation.
42
+
43
+ Контракты сверены с JSON Schema установленного Codex (`codex app-server generate-json-schema`) и [официальной документацией Claude SDK streaming](https://code.claude.com/docs/en/agent-sdk/streaming-output). Завершение аргументов и завершение исполнения различаются намеренно.
@@ -0,0 +1,15 @@
1
+ # Автоматические разрешения агента
2
+
3
+ Пользователь разрешил автоматически подтверждать действия агента. Новый backend нормализует `HubSettings.autoApproveActions` в `true` по умолчанию; интерфейс не добавляет согласий или подтверждений перед включением. Settings показывает checkbox «Автоматически разрешать действия агента» и явный режим. Изменение черновика применяется существующей кнопкой «Сохранить настройки». Его можно отключить, сохранив ручные карточки. Вопросы об игре требуют настоящих ответов пользователя; UI не подставляет ответы.
4
+
5
+ Политика централизована в backend. Frontend не вызывает разрешение каждого запроса и не меняет sandbox/ограничения провайдера. Подтверждённое `permission.auto_approved` отображается отдельной строкой журнала B: фактическое количество недавних разрешённых запросов. События фильтруются по проекту и соответствующему run, дедуплицируются по HubEvent.id; история не создаёт pending-состояния или повторной анимации. Основной журнал событий хранится сервером, UI использует существующие последние 300 событий. Смена проекта и посторонние run не добавляют чужих разрешений в текущий журнал.
6
+
7
+ Frontend совместим с ещё работающим старым backend: отсутствие поля в GET/settings сохраняется явно, несмотря на новые клиентские defaults. Контрол в этом случае недоступен с пояснением об обновлении сервера; автоматическое разрешение не обещается. Существующие permission cards продолжают работать. Это важно при обновлении статических файлов без прерывания пользовательской работы.
8
+
9
+ ## Проверки
10
+
11
+ `tests/auto-approval-ui.test.ts` проверяет отображение true/false/unsupported и фильтрацию, дедупликацию и неактивность исторического автоматического разрешения. Вместе с `tests/workflow-journal.test.ts` проходят 10 focused tests; typecheck PASS.
12
+
13
+ `tests/e2e/auto-approval.spec.ts` использует настоящий API/SSE, сохранение, production UI и подставленную модель/verifier: default automatic, завершение без карточки, фактическая строка журнала после reload, сохранение ручного режима и старый runtime без поля. Существующие E2E, проверяющие именно ручное подтверждение (`activity.spec.ts` и journal latency/permission), явно задают false. Они не изменяют production default.
14
+
15
+ Изолированный `createJournalHub` принимает optional `autoApproveActions`. При отсутствии значения применяется production default true; для ручной демонстрации укажите false. Все файлы и данные временные, реальные команды и LLM не запускаются. Итоговые полные тесты/сборка/активация фиксируются root отдельно.
package/docs/api.md ADDED
@@ -0,0 +1,145 @@
1
+ # Local API v1
2
+
3
+ All requests use same-origin session cookie established by opening CLI URL with `#token=...` then POST /api/v1/session `{token}`. JSON errors have `message`. GET /api/v1/events is SSE; reconnect sends Last-Event-ID. Events have `{id,type,projectId?,payload,createdAt}`.
4
+
5
+ ## Hub
6
+ - GET /api/v1/projects → `Project[]`
7
+ - POST /api/v1/projects `{name,path,dimension:'2d'|'3d',platforms:['desktop'|'web'],agent:'codex'|'claude'|'kimi',description?,engine:'godot'}` → Project
8
+ - POST /api/v1/dialogs/directory (no body) → `{path:string|null}`. Opens the native directory chooser on the server's desktop; returns an existing canonical absolute directory path or `null` when cancelled. Paths preserve whitespace. One dialog per server; concurrent requests receive 409, unavailable graphical tools receive 503 and a five-minute timeout receives 504. Disconnect/server shutdown aborts the dialog. Requires the same session, Origin and Host checks as other API calls. Choosing does not create a project or bypass empty-directory validation.
9
+ - GET /api/v1/settings → `{id:'settings',agents:{codex:{executable,model,reasoningEffort},claude:{executable,model?},kimi:{executable,model?}},godotPath?,theme?}`
10
+ - PUT /api/v1/settings same shape (agents optional). Provider fields merge with saved values. Omitted or blank Codex model/effort resolves to `gpt-6.1-sol` / `medium`; explicit nonblank selections survive. `reasoningEffort` is a string (at most 40 characters), permitting levels advertised by the installed CLI; model compatibility is validated by Codex. An explicitly empty value resets that field to the application default.
11
+ - GET /api/v1/diagnostics → `{agents:[{id,available,version?,error?,capabilities,protocol?,authentication?}],godot?}`. Godot includes matching `exportTemplates:{version,directory,web,desktop}` and guidance when templates are absent.
12
+
13
+ ## Ordinary chat
14
+
15
+ - GET /api/v1/chats → conversation summaries for the connected UMGT account.
16
+ - POST /api/v1/chats `{}` → 201 new conversation; no game project is needed.
17
+ - GET /api/v1/chats/:id → `{id,title,model,createdAt,updatedAt,status,error?,messages,games}`; status is `idle`, `running`, `stopped` or `error`. While running, snapshots include the current partial answer; the UI polls every 700 ms.
18
+ - POST /api/v1/chats/:id/messages `{text,requestId,voiceEnabled?:boolean}` → 202 snapshot. Text is trimmed and limited to 30,000 characters; requestId must be a UUID. Repeating the same accepted message ID does not start another model call; a different message while that dialog is running returns 409.
19
+ - POST /api/v1/chats/:id/stop `{}` → snapshot; cancellation is forwarded to Core.
20
+
21
+ Voice output uses Google Gemini TTS / Autonoe through Core. The authenticated local `POST /api/v1/speech` endpoint accepts `{requestId:UUID,text:string}` (1–240 characters) and returns `{audio:base64,mime:"audio/wav",operationId,billing:"paid"|"pending",tokens?}`. Pending provider metadata is reconciled and settled by Core asynchronously. Browser dictation remains native.
22
+
23
+ Messages contain optional `speech` (a brief voice summary generated only when voice is enabled), plus `{id,role:'user'|'assistant',content,createdAt,status:'complete'|'interrupted'}`. Model selection is controlled exclusively by the Core administrator. Legacy local model overrides are ignored; PUT /api/v1/core/model returns 403. Each conversation uses a separate Core session with `create_game`, `update_game`, `open_game` workflow tools and local file/command tools and retains context across studio restarts. History is stored in Hub's database, scoped by Core origin and UMGT user ID; another account receives 404 for the conversation ID. Responses do not expose owner identifiers or remote session IDs. An interrupted request is never automatically replayed. Normal Core subscription checks and usage accounting apply. These routes require local Hub authentication and a connected UMGT account.
24
+
25
+ Conversation snapshots also include `launches:[{id,requestId,gameId,status:"running"|"ready"|"error",url?,error?,createdAt}]`. The `open_game` tool prepares the latest ready HTML game asynchronously. The UI reserves a window for an explicit open request and navigates it when ready; historical actions are never replayed on reload.
26
+
27
+ Games are scoped to the owning chat. POST `/api/v1/chats/:id/games/:gameId/stop` stops that workflow; POST `/api/v1/chats/:id/games/:gameId/launch` builds a ready HTML5 game and returns `{url}` for a loopback preview in a new window. Other accounts/chats receive 404. HTML prototypes use one approved epic/task, no external assets and the normal execution and independent build verification. Explicit Godot/Roblox requests use standard planning and asset selection; any required choices remain available in the project. A restart stops unfinished chat jobs without replaying AI calls; history and completed projects remain available.
28
+
29
+ ## Project workspace
30
+ - GET /api/v1/projects/:id → `{project,messages,plans,tasks,epics,run,activity?,activities,permissions,extensions,assets}`
31
+ - PATCH /api/v1/projects/:id `{agent?,description?}` between operations
32
+ - POST /api/v1/projects/:id/messages `{text,mode:'interview'|'chat'}` → 202 `{run}`; LLM answers asynchronously and persists messages. This never writes game files.
33
+ - POST /api/v1/projects/:id/plan `{brief?}` → 202 `{run}` generates draft using interview history.
34
+ - PUT /api/v1/projects/:id/plan `{markdown}` → Plan (new unapproved version).
35
+ - POST /api/v1/projects/:id/plan/approve `{planId}` → 202 `{run}` approves and starts concurrent task decomposition and asset discovery. Execution waits for explicit asset-selection confirmation and successful import.
36
+ - POST /api/v1/projects/:id/tasks/:taskId/assets `{provider,id}` → Task; attaches a known catalog asset or an asset already imported into this project. Requires idle workflow and unfinished task. Deduplicated by provider/id, maximum 20 references; manual catalog resources still require upload/import.
37
+ - POST /api/v1/projects/:id/tasks/:taskId/retry `{}` → Task; resets a failed task for an explicitly requested new attempt.
38
+ - GET /api/v1/projects/:id/tasks/export → `{epics,tasks}`
39
+ - POST /api/v1/projects/:id/run `{}` → 202 `{run}` sequentially executes approved tasks.
40
+ - POST /api/v1/projects/:id/control `{action:'pause'|'stop'|'resume'}` → `{run}`
41
+ - POST /api/v1/projects/:id/permissions/:permissionId `{allow:boolean,answers?:Record<string,string[]>}` → `{ok:true}`
42
+
43
+ `Project`: `{id,name,path,engine,dimension,platforms,agent,description,createdAt,updatedAt}`.
44
+ `Message`: `{id,role:'user'|'assistant'|'system',content,createdAt}`.
45
+ `Plan`: `{id,version,markdown,approvedAt?:string,createdAt}`.
46
+ `Epic`: `{id,title,description,phase:number,planId}`.
47
+ `Task`: `{id,epicId,title,description,acceptance:string[],dependencies:string[],status:'open'|'running'|'done'|'failed',attempts:number,planId,priority:number,estimateMinutes:number,assetRefs?:Array<Asset & {directory?:string}>,verification?:string,error?:string}`.
48
+ `Run`: `{id,kind:'interview'|'chat'|'planning'|'decomposition'|'asset_selection'|'execution',status:'running'|'pausing'|'paused'|'stopped'|'completed'|'failed'|'interrupted',startedAt,updatedAt,taskId?,error?}`.
49
+ `Permission`: `{id,method,details,createdAt}`; pending only.
50
+
51
+ SSE event types: `agent.delta {text}`, `agent.tool {method,details}`, `permission.requested Permission`, `permission.resolved {id}`, `message.created Message`, `plan.created Plan`, `plan.approved Plan`, `tasks.created {epics,tasks}`, `task.updated Task`, `run.updated Run`, `log {text}`. Refetch snapshot on state-changing events; append `agent.delta` to transient streaming output. Single active operation per project; conflicting mutation returns 409.
52
+
53
+ ## Engine, extensions and assets
54
+ - POST /api/v1/projects/:id/engine/editor, /run, /verify, /export (export body `{platform:'desktop'|'web'}`) → 202 `{operationId,status:'running'}`. Missing selected-platform release templates return 422 `{error:'export_templates_missing',message}` before export starts; the message includes matching version, searched directory and installation instructions. Discovery supports standard and marker-enabled self-contained Steam/macOS installations. Existing project configuration is preserved; an exporter log containing `ERROR` remains unsuccessful even with exit code 0.
55
+ - POST /api/v1/projects/:id/engine/stop → `{ok:true}`.
56
+ - Engine SSE: `engine.log {operationId,text}`, `engine.completed {operationId,ok,outputPath?,url?,error?}`. Export URL opens the local Web preview.
57
+ - GET /api/v1/extensions → `SkillPackManifest[]`.
58
+ - POST /api/v1/projects/:id/extensions/install `{ids?:string[]}` → installed manifest array. Omitting IDs installs recommendations; explicit IDs add selected skills or the pinned optional GUT plugin while preserving existing extensions.
59
+ - GET /api/v1/assets?q=&provider=all|polyhaven|ambientcg|kenney&type= → `{assets:Asset[],warnings:string[]}`; upstream failures are partial warnings.
60
+ - GET /api/v1/assets/:provider/:id → `Asset` details.
61
+ - POST /api/v1/projects/:id/assets `{provider,id}` → imported asset metadata.
62
+ - POST /api/v1/projects/:id/assets/upload multipart file plus optional sourceUrl/author/license fields → imported metadata.
63
+
64
+ `Asset`: `{id,provider,name,type,thumbnail?,sourceUrl,license,author?,tags:string[],downloadUrl?,formats?:string[],importMode:'automatic'|'manual',previewAudioUrl?,licenseUrl?,attribution?,provenanceUrl?,verifiedAt?}`. Automatically downloadable verified CC0/CC-BY items use protected import; manual cards link to source and support local upload. Search alone never imports files.
65
+ `SkillPackManifest`: `{id,name,description,version,engine,type:'skill'|'plugin'|'mcp',source,license,dimensions?}`.
66
+
67
+ `agent.activity` events carry `{id,runId,kind,status,label,detail?,createdAt,updatedAt,sequence}`. Categories and lifecycle are documented in [agent activity](agent-activity.md). Workspace snapshots include at most40 current-run activity records, independent of journal replay length. Detail contains identifiers, not arguments/output/hidden reasoning. Sequence is monotonic per run; clients must ignore stale project/run and sequence updates.
68
+
69
+ ## Interactive interview
70
+
71
+ Workspace snapshots include `interviewRounds: InterviewRound[]` and optional latest `interviewRound`; messages may have `interviewRoundId`. Round and answer contracts, validation limits and legacy handling are documented in [structured interview](interactive-interview.md).
72
+
73
+ - POST `/api/v1/projects/:id/interview/:roundId/answers` `{answers:[{questionId,value?:string|string[]|number,customText?:string}]}` →202 `{run}`. Invalid answers return400; stale/closed/concurrent submissions return409.
74
+ - `interview.updated` carries the full persisted round. Refetch the workspace after changes.
75
+ - Interview model protocol JSON is not emitted as `agent.delta`; validated public text arrives in `message.created` linked to a round. Ordinary chat continues streaming.
76
+ - Natural-language messages supersede a pending form. `complete` round status does not generate or approve a plan.
77
+
78
+ After a complete interview, bounded explicit whole-message planning/development requests to `/messages` return a `planning` run instead of another interview turn. The browser opens plan review from this returned kind. The new plan remains unapproved. `Plan.interviewRoundId?:string` records its interview provenance; workspace `planNeedsUpdate:boolean` identifies plans predating the current brief. Approval, run and resume return409 for stale plans. Manual PUT `/plan` stamps current provenance. See [explicit planning transition](interactive-interview.md#explicit-transition-to-planning).
79
+
80
+ ## Approval journal
81
+
82
+ `Run.stages?:WorkflowStage[]` records real decomposition boundaries; workspace `decomposition?:Run` retains the latest preparation run when current `run` advances to execution. `workflow.stage` SSE carries `{id,runId,planId,kind,status,label,createdAt,updatedAt,sequence,counts?}`. Kinds: `approval|skills|generation|validation|saving`; status: `running|completed|failed|cancelled`. Counts may include `skills`, `epics`, `tasks`, only after their actual operations complete. Reconcile stage IDs and monotonic sequence; no percentage or raw model output is part of this contract. See [approval journal](approval-journal.md).
83
+
84
+ ## Automatic action approval
85
+
86
+ Settings include normalized `autoApproveActions:boolean`, default `true` for fresh and legacy missing values. PUT `/api/v1/settings` accepts it; enabling it resolves this server's existing pending action requests while leaving interactive input questions pending. `permission.auto_approved` carries `{id,runId,method,createdAt}` without raw permission details. Newly autoapproved actions have no `permission.requested` event or pending row; promotion of an existing manual request also emits its usual `permission.resolved`. Provider read-only denials and real user-input requests remain distinct. See [automatic approvals](automatic-approvals.md).
87
+
88
+ On macOS, POST `/api/v1/projects/:id/engine/run` now uses the installed `.app` with native background activation (`open -g -n -W`). The visible game remains interactive when selected. Stop tracks and revalidates the separately launched game PID; stderr/stdout still reach `engine.log`. Editor requests and headless verification/export are unchanged. Other desktop foreground behavior remains OS-dependent. See [background game launch](background-game-launch.md).
89
+
90
+ ## Plan-bound asset selection
91
+
92
+ Workspace snapshots expose `assetSelection?:AssetSelection` and `assetReadiness:{tasksReady,assetsReady,canExecute,reason?}`. The new gate applies to plans with a selection; legacy plans without one retain their existing execution behavior. Even an empty list of needs requires explicit confirmation. `Task.assetNeedIds?:string[]` links requirements to tasks; imported files are also available through existing `assetRefs`.
93
+
94
+ - GET `/api/v1/projects/:id/asset-selection` → `{selection?,readiness}`.
95
+ - POST `/api/v1/projects/:id/asset-selection` `{planId?}` →202 `{selection,run?}`; starts discovery for an existing current approved plan without replacing its task DAG.
96
+ - PATCH `/api/v1/projects/:id/asset-selection/:selectionId/needs/:needId` `{revision,choice:{kind:'candidate',candidateId}|{kind:'skip'}}` → selection. Required needs cannot be skipped.
97
+ - POST `.../needs/:needId/search` `{revision,query}` → selection; replaces the alternatives for that need and clears its earlier choice.
98
+ - POST `.../needs/:needId/upload` multipart `file`, `revision`, optional `candidateId`, `license`, `sourceUrl`, `author`, `licenseUrl` → selection. Fields precede the file. Files stage outside the game until finalization.
99
+ - POST `.../:selectionId/confirm` `{revision}` → selection; records confirmation, then prepares files once decomposition completes. Manual-source candidates require an uploaded file.
100
+ - POST `.../:selectionId/retry` → selection; explicitly continues a failed/cancelled selection.
101
+ - POST `.../:selectionId/cancel` → selection; cancels an unconfirmed selection. Active import uses the project stop control.
102
+
103
+ Selections persist `id,planId,runId,status,needs,revision,createdAt,updatedAt,confirmationRequestedAt?,confirmedAt?,error?`. Status is `discovering|choosing|importing|confirmed|failed|cancelled`. A need stores `id,title,type,query,rationale,required,taskHints,candidates,choice?,status,importedAsset?,warnings?,error?`. Candidate metadata comes from the catalog; LLM ranking can only refer to supplied IDs.
104
+
105
+ `asset.selection.updated` publishes the persisted selection. Refetch the workspace to reconcile readiness and task changes. Each update advances `revision`; stale edits and wrong-plan identifiers return409. Invalid or incomplete choices return400. Final confirmation is distinct from import completion, and server run/resume checks cannot be bypassed by a disabled UI button. See [selection workflow](asset-selection.md).
106
+
107
+
108
+ ## Превью медиа
109
+
110
+ `Asset` сохраняет совместимость с обложкой и audio URL, дополнительно возвращает `media: AssetMedia[]`, `mediaTotal`, `mediaGalleryUrl` и `previewVideoUrl`. Элемент содержит `kind` (`image|audio|video`), `url`, опциональные `name`, `mime`, `poster`.
111
+
112
+ - `GET /api/v1/assets/:provider/:assetId/media?offset=0&limit=60` — индекс проверенного архива провайдера.
113
+ - `GET|HEAD /api/v1/assets/:provider/:assetId/media/files/:index` — конкретный файл из индекса.
114
+ - `GET /api/v1/projects/:id/asset-media/:kind/:assetId` — staged/imported галерея проекта.
115
+ - `GET|HEAD /api/v1/projects/:id/asset-media/:kind/:assetId/files/:index` — файл этой галереи.
116
+
117
+ Ответ галереи: `{media,total,nextOffset?}`. Файлы требуют авторизованной сессии, поддерживают single byte Range (206/416), сигнатурный MIME и sandbox CSP. URL и файловые пути клиента не используются для произвольного доступа. Форматы и ограничения: [asset-media.md](asset-media.md).
118
+
119
+ ## HTML5 и Яндекс Игры
120
+
121
+ Создание проекта принимает `engine: "html5"` или `"godot"`; `platforms` может включать `"yandex-games"` вместе с `"web"`. HTML5 не поддерживает Desktop-экспорт. Опциональная `yandexGames` содержит ID приложения, устройства, ориентацию, языки, рекламу, облачные сохранения, авторизацию, продукты с числовыми выдачами и технические имена лидербордов. Покупки требуют облачных сохранений и продуктов. Существующие Godot-запросы остаются совместимыми.
122
+
123
+ - `GET /api/v1/extensions?projectId=...` возвращает подходящие движку, платформе, жанру и размерности навыки. Без параметра возвращается общий каталог.
124
+ - `GET|PUT /api/v1/projects/:id/yandex-games/config` читает или обновляет SDK-настройки; изменение требует новой сборки.
125
+ - `POST /api/v1/projects/:id/engine/export` принимает `platform: "yandex-games"`; общий engine lifecycle сохраняет остановку, события и проверку результатов.
126
+ - `GET /api/v1/projects/:id/builds`, `GET /api/v1/projects/:id/builds/:buildId/download`, `POST /api/v1/projects/:id/builds/:buildId/validate` обслуживают неизменяемые ZIP и результаты проверки. Подготовка публикации повторно сверяет ZIP, содержимое превью и конфигурацию.
127
+ - `GET|PUT /api/v1/browser/config`, `POST /api/v1/browser/diagnostics` управляют отдельным loopback Chrome MCP. Доступность расширения ChatGPT не считается доступностью этого подключения.
128
+ - `GET /api/v1/projects/:id/publication`, `POST .../publication/start` с `{buildId?,metadata}`, `POST .../publication/control` с `{action:"pause"|"resume"|"stop",draftUrl?}` и `POST .../publication/submit` с `{runId}` управляют сохраняемой публикацией. Только последний endpoint явно разрешает отправку на модерацию; глобальное auto-approve её не разрешает.
129
+ - `GET|POST /api/v1/projects/:id/publication/materials` читает изображения или импортирует multipart-файл с назначением `icon`/`screenshot`. `GET .../materials/:materialId/file`, `DELETE .../materials/:materialId`, `POST .../materials/capture` с `{buildId}` обслуживают проверенные изображения. Захват работает только через подключённый Chrome на одобренном превью. Полное декодирование PNG/JPEG/WebP удаляет метаданные; лимиты — 10 МиБ, 4096 × 4096 и 10 материалов проекта.
130
+
131
+ `publication.updated` и `publication.materials` передаются через SSE. Браузерный MCP capability действует только для текущего активного запуска; его внутренний endpoint не предназначен для общего использования. Отсутствие расширения, необходимость входа, CAPTCHA и ручной проверки Canvas явно отделяются от успешной загрузки и модерации. Подробности: [Яндекс Игры](yandex-games.md).
132
+
133
+ ## Roblox Studio
134
+
135
+ Projects also accept `engine: "roblox", dimension: "3d", platforms: ["roblox"]`. Other combinations are rejected. Settings accept `robloxStudioPath?`, `robloxMcpPath?` and `robloxStudioId?`; GET diagnostics includes a `roblox` installation diagnostic. POST engine/verify checks local manifest/source packaging; POST engine/export `{platform:"roblox"}` builds `builds/game.rbxlx`. POST engine/editor or engine/run rebuilds and hands the file to Studio; Play is performed in Studio. Completion returns local `outputPath`, with no Web URL. Static success is not Luau compilation or gameplay evidence. StudioMCP is supplied to task agents only with an explicit target ID, and never to read-only planning. See [Roblox documentation](roblox.md) for supported manifest features, skill provenance and the playable prototype.
136
+
137
+
138
+ The local GET `/api/v1/core` response includes optional `profile: {name, avatar_url}` from Core's authenticated GET `/api/v1/profile`. Only the current account's display fields are returned. Avatar paths from UMGT are resolved against the cabinet origin; profile failure does not prevent balances and limits from loading.
139
+
140
+ Core entitlements may include `ai_budget: {status:'active'|'inactive'|'unavailable',currency:'USD',timezone:'Europe/Moscow',daily?,weekly?,monthly?,message?}`. Each window contains `{limit,used,left,starts_at,resets_at,pending_costs}` in actual provider USD. The active monthly allowance is 50% of the subscription tariff before payment fees; day = month / calendar days in the current month, week = day × 7, with Moscow resets. The Studio uses these windows instead of legacy token windows, shows only remaining/used percentages, and marks figures as approximate when provider costs are missing. Core rejects new text/TTS calls at exhausted allowances with `daily_budget_exceeded`, `weekly_budget_exceeded`, or `monthly_budget_exceeded`. An inactive/unavailable budget is shown explicitly, without falling back to unrelated token percentages.
141
+
142
+
143
+ PATCH `/api/v1/chats/:id` `{title:string}` (1–120 characters) renames an owned dialog. DELETE moves it to trash and cancels active generation; games remain registered projects. GET `/api/v1/chats?deleted=true` lists owned trashed dialogs; POST `/api/v1/chats/:id/restore` restores history. Renamed titles and trash state survive background completion and restart. Ordinary GET/send/game endpoints return 404 for trashed or foreign dialogs.
144
+
145
+ Chat sessions also expose local file/command tools. Commands execute in a separate per-dialog workspace on Hub, never on the Core server. Settings control automatic approval; pending `permissions` are returned by the chat snapshot and answered at POST `/api/v1/chats/:id/permissions/:permissionId` `{allow:boolean,answers?:Record<string,string[]>}`. Only the owning account can answer; stop/delete cancels pending permission requests.
@@ -0,0 +1,13 @@
1
+ # Approval and decomposition journal
2
+
3
+ Approving a current plan persists its approval and starts decomposition. The server records five real boundaries: approval saved, skill preparation, model generation of the complete epic/task graph, JSON/DAG validation, and atomic task persistence. Generation is one potentially long model call; the server cannot truthfully report partial epic/task totals or a percentage before a validated graph exists. Provider thinking/answering/tool activity and pending permissions remain independent signals alongside this stage.
4
+
5
+ `Run.stages?: WorkflowStage[]` stores a bounded five-stage projection in the existing project run document. A stage contains stable `id`, `runId`, `planId`, `kind`, `status`, `label`, `createdAt`, `updatedAt`, monotonic `sequence`, and optional `counts`. Kinds are `approval|skills|generation|validation|saving`; statuses are `running|completed|failed|cancelled`. Labels are fixed application text rather than raw model output. A stage has one stable ID per run/kind; terminal stages are immutable. Counts for installed skills appear after installation. Epic/task counts appear only on completed saving, after the SQLite transaction and `tasks.created` event.
6
+
7
+ Each transition saves the updated run, emits `run.updated` and then `workflow.stage` carrying the full stage. Workspace snapshots include optional `decomposition`, the latest decomposition run, separately from the current `run`. This preserves the completed preparation journal after the existing automatic execution path starts and current provider activity is reset for execution. Clients reconcile by project/run/stage ID and sequence; replayed events are history, not new approvals. Old runs without stages remain valid and must not receive invented stage completions.
8
+
9
+ Failure marks the active stage failed. Stop marks it cancelled synchronously and rejects late adapter results before graph validation/persistence. On server recovery, running decomposition stages become cancelled and the run becomes interrupted. Pending permissions retain the existing resolution and priority behavior; a stage is not evidence that a permission was granted. Completed stages remain available after errors or reload.
10
+
11
+ The journal itself does not introduce an execution action. New plan approvals also start concurrent asset discovery, and automatic execution now waits for the explicit asset-selection confirmation and successful imports. The injectable `autoExecute:false` option still prevents automatic execution after readiness. Workspace `assetSelection` supplies additional real discovery/search/choice/import states without inventing decomposition stages or percentages. The journal offers a button to reopen the desktop wizard; waiting for a user's choice is distinguished from a running model request. Plan freshness, explicit approval, dependency validation, project serialization and independent engine verification remain enforced. See [asset selection](asset-selection.md).
12
+
13
+ Focused backend regressions verify ordering, persistence, counts after task commit, invalid JSON failure, slow-model cancellation, ignored late successful results, interrupted recovery, and retention after execution becomes the current run. These use isolated project fixtures; reading journal state does not alter an active user project.
@@ -0,0 +1,27 @@
1
+ # Предпросмотр настоящих медиа
2
+
3
+ Каталог, окно подробностей, мастер выбора и коллекция проекта используют один `AssetMediaPreview`. Изображение показывается как изображение; звук и видео имеют встроенные плееры. Воспроизведение запускает пользователь. Начало нового плеера останавливает предыдущий, а смена файла, закрытие окна и размонтирование освобождают старый плеер. После секунды ожидания появляется индикатор; ошибки сохраняют возможность повторной загрузки.
4
+
5
+ ## Метаданные и галереи
6
+
7
+ `Asset.media` содержит элементы `{kind:'image'|'audio'|'video',url,name?,mime?,poster?}`. `mediaTotal` и `mediaGalleryUrl` описывают реальные файлы набора. Старые `thumbnail`, `previewAudioUrl` и новый `previewVideoUrl` сохраняют совместимость с каталогом. Обложка и удалённое демо не считаются первым файлом архива: первая загрузка галереи начинается с `offset=0`.
8
+
9
+ Импортированные и временно загруженные ресурсы получают ссылки на реальные файлы. Legacy записи импорта также обогащаются метаданными при чтении workspace. В галерее показывается один выбранный файл; страницы по 60 элементов позволяют просмотреть весь поддерживаемый набор без одновременной загрузки сотен картинок или аудио. Загрузка в мастере доступна для просмотра до подтверждения и переноса файлов в игру.
10
+
11
+ Поддерживаются PNG/JPEG/WebP/BMP/GIF/SVG, WAV/OGG/MP3/FLAC, MP4/WebM/OGV. Для HDR/EXR, моделей, шрифтов и других форматов остаются обложка каталога и переход к источнику: браузерный просмотр этих файлов не заявляется. Поддержка контейнера видео не гарантирует поддержку любого кодека; плеер объясняет ошибку воспроизведения.
12
+
13
+ ## Серверная граница
14
+
15
+ `asset-media.ts` обслуживает авторизованные проектные, staged/imported и провайдерские галереи. Клиент передаёт зарегистрированный ID и числовой индекс, а не путь файла или произвольный URL. Manifest определяет файлы, staged handle привязан к проекту. Проверяются канонические пути, каждый компонент на symlink, расширение и сигнатура содержимого. Политика loopback, Origin и session действует и для медиа.
16
+
17
+ GET/HEAD поддерживают одиночные byte ranges: 206 с `Content-Range`, 416 для недопустимого диапазона. Файлы передаются потоком. Ответы содержат `nosniff`, private/no-store, same-origin resource policy и sandbox CSP без скриптов/внешних ссылок. SVG отображается как изображение; CSP защищает и прямое открытие файла, а не выдаётся за XML sanitizer.
18
+
19
+ Просмотр файлов официального пакета создаёт отдельный кэш вне игровых проектов. Скачивание ограничено доверенными точными источниками и 64 MiB сжатого пакета; действуют прежние лимиты распаковки, запрет traversal/symlink и фильтрация macOS-метаданных. Большие пакеты доступны по исходной странице, а ошибку предварительной загрузки можно повторить.
20
+
21
+ ## Реальный пример: Idle Farm
22
+
23
+ Проверяемые материалы: [Background Elements](https://kenney.nl/assets/background-elements), [Tiny Farm](https://kenney.nl/assets/tiny-farm), [UI Pack](https://kenney.nl/assets/ui-pack), [Interface Sounds](https://kenney.nl/assets/interface-sounds) и [Other Center](https://opengameart.org/content/other-center). Для проверки видеоплеера используется [Big Buck Bunny Trailer](https://peach.blender.org/trailer-page/) с лицензией CC-BY-3.0; это необязательный пример видео, не обязательная часть художественного оформления фермы.
24
+
25
+ Файлы скачаны с настоящих источников; размеры, SHA256, авторы и лицензии сохранены в `.artifacts/real-assets-20261008/downloads.json`. Live E2E запускается отдельно: `LMGH_LIVE_ASSETS=1 npx playwright test tests/e2e/real-assets.spec.ts --output=.artifacts/real-assets-20261008/playwright-results`. Контролируется только планирующий ответ модели; каталог, архивы, изображения, звук, видео, импорт и HTTP media endpoints настоящие. Игровые проекты пользователя и реализация игры этим сценарием не изменяются.
26
+
27
+ Обычные тесты покрывают безопасность/ошибки и используют отдельные явно тестовые ресурсы. Одновременные прогоны Playwright должны иметь разные `--output`, чтобы не удалять traces друг друга. Фактические результаты и снимки находятся в [журнале проверки](validation.md).
@@ -0,0 +1,34 @@
1
+ # Источники бесплатных игровых ассетов
2
+
3
+ API подключения проверены 6 октября 2026; каталог Kenney/OpenGameArt расширен с проверкой карточек 8 октября 2026. Ниже описано фактическое подключение Hub.
4
+
5
+ | Источник | Для чего подходит | Подключение в Hub | Лицензия |
6
+ | --- | --- | --- | --- |
7
+ | Poly Haven | 3D модели, PBR текстуры, HDRI | Поиск, метаданные и автоматическое скачивание через API | CC0 для ассетов; отдельные условия сервиса API |
8
+ | ambientCG | Материалы, текстуры, HDRI и модели | Поиск и автоматический импорт из API v2 | CC0 |
9
+ | Kenney | 2D тайлы, игровые наборы, UI и звуки | Проверяемый каталог пакетов с превью, переход к источнику, ручной импорт | CC0 для выбранных пакетов |
10
+ | OpenGameArt | Музыка и звуки в подключённом каталоге; другие материалы через сайт | Проверенные карточки с аудиопревью и загрузкой; остальные источники добавляются вручную | CC0 и CC-BY для проверенных карточек |
11
+ | itch.io | Авторские игровые наборы разных стилей | Внешний поиск бесплатных ассетов, ручной импорт | Определяется автором пакета |
12
+
13
+ ## Почему выбраны эти способы подключения
14
+
15
+ Poly Haven публикует CC0 модели, текстуры и HDRI. Условия live API требуют идентифицирующего User-Agent/Referer и видимого указания источника. Hub использует собственный User-Agent, именует провайдера в карточках и показывает кредит рядом с каталогом. Поиск и скачивание обращаются к API, файлы модели импортируются вместе с зависимостями. Источники: [лицензия ассетов](https://polyhaven.com/license), [официальный API](https://github.com/Poly-Haven/Public-API), [условия API](https://github.com/Poly-Haven/Public-API/blob/master/ToS.md).
16
+
17
+ ambientCG предоставляет API для программного поиска и загрузки, а ассеты и материальные превью распространяет под CC0. Hub использует `full_json` v2 для метаданных и вариантов загрузки; выбирает доступный небольшой архив и сохраняет происхождение. Документация также содержит v3; переход между версиями требует отдельной проверки контрактов. Источники: [API](https://docs.ambientcg.com/api/), [лицензия](https://docs.ambientcg.com/license/), [full_json v2](https://docs.ambientcg.com/api/v2/full_json/).
18
+
19
+ Kenney удобен для небольших игр благодаря готовым стилистически согласованным наборам. Каталог Hub включает ресурсы для окружения и персонажей 2D, природы 3D, интерфейса и звуков. Пользователь открывает страницу выбранного пакета, скачивает архив и импортирует его через Hub. Устаревшая карточка Platformer Pack Redux заменена проверенным Pixel Platformer. Пример официальной карточки с лицензией и бесплатной загрузкой: [Tiny Town](https://kenney.nl/assets/tiny-town).
20
+
21
+ OpenGameArt требует учитывать лицензию и атрибуцию конкретного материала. Hub содержит проверенные карточки аудио с точными ссылками на источник, автора, лицензию, превью и файл; внешний поиск остаётся доступен для ресурсов вне этой подборки. Это каталог конкретных проверенных ресурсов, а не общий API сайта. Источник: [официальный FAQ](https://opengameart.org/content/faq).
22
+
23
+ Официальный серверный API itch.io работает с учётной записью и API key; документация отдельно описывает публичные RSS ленты. Для первого релиза выбран внешний поиск и ручной импорт без добавления авторизации itch.io в Hub. Это решение реализации; отсутствие подходящего общего API не утверждается. Источник: [официальный обзор API](https://itch.io/docs/api/overview).
24
+
25
+ ## Общий путь ресурсов
26
+
27
+ Пользователь и агент используют один серверный каталог. MCP-инструменты `assets.search`, `assets.details`, `assets.download`, `assets.import` доступны выбранному агенту в контексте проекта; запись разрешена при утверждённом исполнении. Пользователь может прикрепить ресурс к открытой задаче, и её контекст содержит выбранные метаданные и папку уже импортированного ассета.
28
+
29
+ Импорт сохраняет источник, автора, лицензию и список файлов. Загрузки ограничены по размеру, разрешённым доменам и редиректам; ZIP распаковывается во временную папку с проверкой путей, типов файлов и лимита распаковки. Ошибка отдельного провайдера возвращается предупреждением и не удаляет результаты остальных. Ручные файлы с неизвестной лицензией сохраняют это состояние; Hub не присваивает им CC0 автоматически.
30
+
31
+ При утверждении нового плана эти источники используются в [параллельном подборе](asset-selection.md). Мастер предлагает реальные альтернативы, сохраняет выбор и ждёт подготовки настоящих файлов перед реализацией. CC-BY импорт сохраняет текст атрибуции и сведения для титров; пользовательские загрузки до подтверждения хранятся вне папки игры.
32
+
33
+
34
+ Медиа-превью: наборы могут содержать image/audio/video. Скачиваемый архив провайдера имеет защищённую индексированную галерею с ленивым получением конкретных файлов; пользователь видит содержимое до импорта. Добавлены реальные Background Elements, Tiny Farm (Kenney) и Big Buck Bunny Trailer (Blender Foundation, CC-BY-3.0). Для Blender сохраняются автор, лицензия и ссылка на происхождение; экспорт/использование требует атрибуции. [Контракт и ограничения](asset-media.md), [реальная проверка](validation.md).
@@ -0,0 +1,31 @@
1
+ # Подбор ассетов перед реализацией
2
+
3
+ При утверждении новой версии плана Hub параллельно создаёт эпики/задачи и подбирает внешние ресурсы. Это две ветви одной подготовки: создание задач не ждёт окончания поиска, а реализация ждёт подтверждённого выбора и успешной подготовки файлов.
4
+
5
+ ## Пользовательский сценарий
6
+
7
+ Desktop-мастер открывается после утверждения плана. Выбранная в проекте локальная LLM определяет потребности из плана; каталог предоставляет реальные ресурсы и сведения об источниках. Для каждой потребности показываются доступные варианты с объяснением соответствия, форматом, лицензией и превью. Рекомендация не означает автоматического выбора.
8
+
9
+ Пользователь выбирает вариант, уточняет запрос, повторяет поиск или загружает собственный файл. Ненужную необязательную потребность можно пропустить. Не найденный обязательный ресурс остаётся незавершённым: Hub не заменяет его незаметно заглушкой или генерируемой графикой. Если внешние ресурсы не нужны, итоговый шаг объясняет это и всё равно требует подтверждения.
10
+
11
+ Закрытие мастера не отменяет подготовку. Выбор хранится в проектной SQLite, восстанавливается после обновления страницы, а мастер доступен из журнала и вкладки ассетов. В конце пользователь подтверждает подборку. Автоматические источники скачиваются через существующий защищённый импорт; ручные источники требуют загрузки настоящего файла. Ссылка на страницу не считается импортированным ассетом.
12
+
13
+ ## Workflow и сохранение
14
+
15
+ Подборка привязана к проекту и конкретному `planId`, содержит потребности, кандидатов, выбор, состояния поиска/импорта и ревизию. Snapshot и SSE передают сохраняемое состояние отдельно от временного потока ответа модели. Независимые LLM-запросы подготовки остаются read-only; каталог вызывается сервером. Текст источников рассматривается как данные, а не инструкции агенту.
16
+
17
+ Перед запуском, возобновлением и автоматическим исполнением сервер проверяет готовность задач и подборки. Подтверждение во время создания задач сохраняется, но не обходит готовность графа. Выбранные ресурсы попадают в контекст соответствующих задач с реальными путями. Повторные действия не должны дублировать импорты и запуски.
18
+
19
+ Новая версия плана получает отдельную подборку; история предыдущей сохраняется. Старые проекты без подборки продолжают существующий workflow, пока пользователь отдельно не запускает подбор. Остановка отменяет незавершённую подготовку и исключает автоматический старт. Перезапуск сохраняет результаты и требует явного продолжения прерванной работы.
20
+
21
+ ## Источники и лицензии
22
+
23
+ Предложения ограничены проверенными бесплатными CC0 и CC-BY с известными авторством и условиями. Сведения об атрибуции, лицензии, исходном ресурсе и изменениях сохраняются вместе с импортом для титров. Собственный файл сохраняет указанное пользователем происхождение; неизвестная лицензия не превращается автоматически в CC0.
24
+
25
+ Каталог Kenney/OpenGameArt дополняет API Poly Haven и ambientCG для графики 2D, интерфейса, звуков и музыки. Результаты могут быть ограничены доступностью источника и количеством подходящих ресурсов; мастер показывает фактическое число вариантов. Подключения и ограничения описаны в [источниках ассетов](asset-providers.md).
26
+
27
+ ## Индикация и проверка
28
+
29
+ Журнал отдельно показывает определение потребностей, поиск, ожидание выбора и импорт. Ожидание пользователя не отображается как работающая команда агента. Поиск показывает этапы и завершённые потребности; проценты загрузки вычисляются только при известном размере файла. Ошибка отдельного источника не уничтожает другие результаты. Выбор сохраняется при ошибке импорта и доступен для повторной попытки.
30
+
31
+ Для приёмки нужны проверки параллельности, серверного запрета преждевременного запуска, восстановления, смены плана, отмены, повторного подтверждения и реальной связи файлов с задачами. Сквозные UI-проверки используют изолированные проекты: контролируемые модель/верификатор отдельно от проверок установленной LLM и живых источников. Фактические результаты публикуются в [журнале проверки](validation.md).
@@ -0,0 +1,15 @@
1
+ # Automatic local-agent action approvals
2
+
3
+ `HubSettings.autoApproveActions` controls action approval inside Game Hub. The normalized default is `true` for fresh settings and older stored settings without the field; an explicit `false` preserves manual action approval. `PUT /api/v1/settings` accepts a boolean and persists it without changing provider models, global CLI configuration, operating-system permissions or browser security policy.
4
+
5
+ All three provider bridges use the same workflow permission callback: Codex command/file-change approval, Claude tool authorization, and Kimi ACP permission requests. In automatic mode a current non-aborted action request immediately receives `{allow:true}`. No pending permission row or waiting-permission activity is created. The provider still controls its own sandbox and tool execution, and action authorization does not imply that the command or game task succeeded. Existing provider read-only denials continue to apply before this callback.
6
+
7
+ `permission.auto_approved` records `{id,runId,method,createdAt}`. It contains no command arguments, file contents, query values or raw permission payload. The UI may show this actual decision in the journal. It must not fabricate a waiting card for a request already resolved automatically. The normal activity and task verification lifecycle determines success/failure.
8
+
9
+ Interactive input is distinct: Codex `item/tool/requestUserInput` and Claude `AskUserQuestion` still require genuine user answers. Matching these method families keeps them in the existing question/permission path; the app never selects an answer or invents user preferences. Structured interview forms also remain explicit user input.
10
+
11
+ Enabling the setting while this server owns an active run applies the policy to its existing pending action requests exactly once. It invokes the existing answer resolver, removes the pending row, emits `permission.resolved`, and emits the automatic-decision event. Input questions stay pending. Future callbacks read the current setting, so disabling automatic approval affects subsequent actions. No new task or run is started merely by changing the policy.
12
+
13
+ An aborted run always denies a late callback. Startup recovery clears abandoned permission records and marks interrupted work; it cannot approve a dead provider process or replay an old action. A previous deployed server does not acquire this behavior just because the browser bundle changes: backend activation must respect active project work.
14
+
15
+ Backend regressions cover Codex/Claude/Kimi callback families, no pending rows or wait states, real question answers, live policy enablement with exact-once resolution, persisted defaults/manual overrides, invalid input, command failure, post-stop callbacks and recovery. Existing subprocess Codex/Kimi protocol tests and Claude SDK mapping tests verify accept/deny response formats and read-only restrictions separately. No unrestricted provider flag or global CLI security setting is introduced.
@@ -0,0 +1,17 @@
1
+ # Background game windows during development
2
+
3
+ On macOS, the game Run action launches the installed Godot app through `/usr/bin/open -g -n -W`: `-g` requests no foreground activation, `-n` creates a separate instance, and `-W` keeps the launcher waiting for that instance. The actual game remains visible and can receive keyboard input when the user selects it. Explicitly opening the editor keeps its existing behavior. Automated imports, script/runtime checks and exports remain headless.
4
+
5
+ The installed Steam Godot 4.7.2 `--headless --help` was checked: it does not advertise a `--no-focus` CLI option. Godot ignores unknown options, so adding that string would not establish background behavior. The project setting `display/window/size/no_focus` disables window focus/input; it is not used because the user must still be able to play the game. No project configuration is rewritten for background launch.
6
+
7
+ `src/server/game-launch.ts` resolves the executable, validates its `.app/Contents/MacOS/<binary>` layout and builds argv without shell interpolation. A missing app bundle fails with an actionable error instead of launching an unrelated foreground program. Non-macOS platforms retain their existing direct process path: foreground policy there depends on the window manager, and guaranteed focus protection is not claimed.
8
+
9
+ The macOS launcher creates a private temporary directory and passes a unique `--log-file` path as a supported Godot argument. Native stdout and stderr are redirected to separate private files through `open --stdout/--stderr`; the hub tails them with bounded buffers and UTF-8 decoding. Only captured output is emitted, never the process table used for ownership checks. The accumulated result is limited to2 MB. These temporary files are removed after completion/cleanup; user game files are not removed.
10
+
11
+ LaunchServices owns the native game separately from the `open -W` child. The hub records process IDs present before launch and identifies only a new PID with the exact resolved executable and unique log argument. Before every TERM/KILL it rereads and validates that identity. PID reuse, other Godot windows, unmatched markers, current process and system PIDs cannot be targeted. Stop waits for native-process disappearance and uses a bounded escalation, while retaining the existing exclusive game-operation controller and single completion event. It never kills all Godot processes. LaunchServices errors and captured engine stderr remain visible; the launcher exit code is not represented as an independently observed native game exit code. Automated acceptance still uses directly owned headless engine processes.
12
+
13
+ Every future implementation request includes the same development launch policy. Newly installed/refreshed managed `AGENTS.md` and `CLAUDE.md` sections include it too: automated tests headless, macOS visible game/exported-app smoke tests through `open -g -n -W`, no application activation/raising or global keyboard injection. Existing arbitrary agent shell commands are not rewritten. An already running model turn retains its previous prompt; a subsequent task request or safe pause/restart/resume receives the new policy.
14
+
15
+ Focused tests use a controlled OS/process adapter rather than opening native windows. They verify argv boundaries with spaces/Cyrillic paths, exclusion of unsupported flags, normal log/cleanup behavior, owned cancellation, protection against PID reuse/unrelated processes, launch errors and instruction scope. Live focus/keyboard behavior is a separate acceptance check.
16
+
17
+ References: installed macOS `man open` documents `-g`, `-n`, `-W` and output redirection; the [official Godot command-line tutorial](https://docs.godotengine.org/en/stable/tutorials/editor/command_line_tutorial.html) describes supported CLI behavior and unknown options; [Godot Window documentation](https://docs.godotengine.org/en/stable/classes/class_window.html) distinguishes no-focus windows from ordinary interactive game windows.