@darkclaw921/umgt 0.2.0 → 0.3.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 (40) hide show
  1. package/README.md +8 -0
  2. package/dist/server/agents/core-tools.d.ts +6 -2
  3. package/dist/server/agents/core-tools.js +8 -3
  4. package/dist/server/agents/core-tools.js.map +1 -1
  5. package/dist/server/agents/core.js +4 -3
  6. package/dist/server/agents/core.js.map +1 -1
  7. package/dist/server/asset-media.d.ts +2 -1
  8. package/dist/server/asset-media.js +1 -1
  9. package/dist/server/asset-media.js.map +1 -1
  10. package/dist/server/chat-computer.d.ts +3 -1
  11. package/dist/server/chat-computer.js +8 -3
  12. package/dist/server/chat-computer.js.map +1 -1
  13. package/dist/server/chat.js +4 -3
  14. package/dist/server/chat.js.map +1 -1
  15. package/dist/server/core-client.d.ts +4 -0
  16. package/dist/server/core-client.js +19 -0
  17. package/dist/server/core-client.js.map +1 -1
  18. package/dist/server/generated-media.d.ts +19 -0
  19. package/dist/server/generated-media.js +342 -0
  20. package/dist/server/generated-media.js.map +1 -0
  21. package/dist/server/routes.js +3 -1
  22. package/dist/server/routes.js.map +1 -1
  23. package/dist/shared/generated-media.d.ts +2 -0
  24. package/dist/shared/generated-media.js +3 -0
  25. package/dist/shared/generated-media.js.map +1 -0
  26. package/dist/web/assets/{AgentActivity-sYJeY5Yf.js → AgentActivity-DRuju8iC.js} +1 -1
  27. package/dist/web/assets/{AssetSelectionWizard-a43_6NO7.js → AssetSelectionWizard-7SBX7wym.js} +1 -1
  28. package/dist/web/assets/CoreAccount-BfH0gEKJ.js +1 -0
  29. package/dist/web/assets/{KidsApp-D-8t3HPy.js → KidsApp-ChVKRU9B.js} +2 -2
  30. package/dist/web/assets/{PlainChat-CMxYwKko.js → PlainChat-C4V_wRVc.js} +1 -1
  31. package/dist/web/assets/{WorkflowJournal-Did0sRta.js → WorkflowJournal-BlTNapOH.js} +1 -1
  32. package/dist/web/assets/{YandexGamesView-R64RSJRL.js → YandexGamesView-BAuOI0EI.js} +1 -1
  33. package/dist/web/assets/{index-sNciOZYG.js → index-B6_q6dBC.js} +2 -2
  34. package/dist/web/assets/{resources-DppXCagL.js → resources-xyl8IpX6.js} +1 -1
  35. package/dist/web/assets/{workflow-BrIKN5ER.js → workflow-CEkwrbrT.js} +4 -4
  36. package/dist/web/assets/workflow-s2TewWL6.css +1 -0
  37. package/dist/web/index.html +1 -1
  38. package/package.json +7 -7
  39. package/dist/web/assets/CoreAccount-D4ZC8CWv.js +0 -1
  40. package/dist/web/assets/workflow-BhcU9uvG.css +0 -1
@@ -1 +1 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CdVFa8IP.js";import{i,t as a}from"./AssetMediaPreview-D2cd6oQO.js";import{t as o}from"./ArrowUpRight.es-BmIrpjWN.js";import{t as s}from"./CheckCircle.es-D5B3hdvz.js";import{a as c,i as l,n as u,o as d,r as f,t as p}from"./ui-wHE_yBK0.js";import{t as m}from"./DownloadSimple.es-DwOWFbs2.js";import{a as h,i as g,r as _,t as v}from"./dist-7vx7MTaJ.js";import{t as y}from"./MagnifyingGlass.es-rkdOU2rH.js";import{t as b}from"./Sparkle.es-CmGpvnNm.js";import{t as x}from"./UploadSimple.es-DxIuxpCC.js";import{t as S}from"./WarningCircle.es-D63H8cL9.js";import{A as C,E as ee,H as w,M as T,N as E,R as D,U as O,j as k}from"./index-sNciOZYG.js";import{CoreAccount as te}from"./CoreAccount-D4ZC8CWv.js";var A=t(n(),1),j=new Map([[`bold`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,36c-20.09,0-37.92,7.93-50,21.56C115.92,43.93,98.09,36,78,36a66.08,66.08,0,0,0-66,66c0,72.34,105.81,130.14,110.31,132.57a12,12,0,0,0,11.38,0C138.19,232.14,244,174.34,244,102A66.08,66.08,0,0,0,178,36Zm-5.49,142.36A328.69,328.69,0,0,1,128,210.16a328.69,328.69,0,0,1-44.51-31.8C61.82,159.77,36,131.42,36,102A42,42,0,0,1,78,60c17.8,0,32.7,9.4,38.89,24.54a12,12,0,0,0,22.22,0C145.3,69.4,160.2,60,178,60a42,42,0,0,1,42,42C220,131.42,194.18,159.77,172.51,178.36Z`}))],[`duotone`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M232,102c0,66-104,122-104,122S24,168,24,102A54,54,0,0,1,78,48c22.59,0,41.94,12.31,50,32,8.06-19.69,27.41-32,50-32A54,54,0,0,1,232,102Z`,opacity:`0.2`}),A.createElement(`path`,{d:`M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z`}))],[`fill`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M240,102c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,228.66,16,172,16,102A62.07,62.07,0,0,1,78,40c20.65,0,38.73,8.88,50,23.89C139.27,48.88,157.35,40,178,40A62.07,62.07,0,0,1,240,102Z`}))],[`light`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,42c-21,0-39.26,9.47-50,25.34C117.26,51.47,99,42,78,42a60.07,60.07,0,0,0-60,60c0,29.2,18.2,59.59,54.1,90.31a334.68,334.68,0,0,0,53.06,37,6,6,0,0,0,5.68,0,334.68,334.68,0,0,0,53.06-37C219.8,161.59,238,131.2,238,102A60.07,60.07,0,0,0,178,42ZM128,217.11C111.59,207.64,30,157.72,30,102A48.05,48.05,0,0,1,78,54c20.28,0,37.31,10.83,44.45,28.27a6,6,0,0,0,11.1,0C140.69,64.83,157.72,54,178,54a48.05,48.05,0,0,1,48,48C226,157.72,144.41,207.64,128,217.11Z`}))],[`regular`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z`}))],[`thin`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,44c-21.44,0-39.92,10.19-50,27.07C117.92,54.19,99.44,44,78,44a58.07,58.07,0,0,0-58,58c0,28.59,18,58.47,53.4,88.79a333.81,333.81,0,0,0,52.7,36.73,4,4,0,0,0,3.8,0,333.81,333.81,0,0,0,52.7-36.73C218,160.47,236,130.59,236,102A58.07,58.07,0,0,0,178,44ZM128,219.42c-14-8-100-59.35-100-117.42A50.06,50.06,0,0,1,78,52c21.11,0,38.85,11.31,46.3,29.51a4,4,0,0,0,7.4,0C139.15,63.31,156.89,52,178,52a50.06,50.06,0,0,1,50,50C228,160,142,211.46,128,219.42Z`}))]]),M=A.forwardRef((t,n)=>A.createElement(e,{ref:n,...t,weights:j}));M.displayName=`HeartIcon`;var N=M,P=r(),F={all:`Все источники`,roblox:`Roblox Creator Store`,polyhaven:`Poly Haven`,ambientcg:`ambientCG`,kenney:`Kenney`,opengameart:`OpenGameArt`,blender:`Blender Open Movies`},I={all:`Всё`,models:`3D-модели`,textures:`Материалы`,hdris:`HDRI`,"2d":`2D`,ui:`Интерфейс`,audio:`Звук`,video:`Видео`,texture:`Текстуры`},L=e=>`${e.provider}:${e.sourceId??e.id}`;function ne(){try{return JSON.parse(localStorage.getItem(`lmgh-favourites`)??`[]`)}catch{return[]}}function R({project:e,onImported:t,selection:n,onSelection:r}){let[i,s]=(0,A.useState)(``),[h,b]=(0,A.useState)(e?.engine===`roblox`?`roblox`:`all`),[C,ee]=(0,A.useState)(`all`),[D,te]=(0,A.useState)(`catalog`),[j,M]=(0,A.useState)([]),[R,ie]=(0,A.useState)([]),[z,ae]=(0,A.useState)([]),[B,oe]=(0,A.useState)(``),[V,se]=(0,A.useState)(!1),[H,ce]=(0,A.useState)(ne),[U,le]=(0,A.useState)([]),[ue,de]=(0,A.useState)(!1),[W,G]=(0,A.useState)(``),[K,q]=(0,A.useState)(null),[J,Y]=(0,A.useState)(``),[fe,X]=(0,A.useState)(``),[pe,Z]=(0,A.useState)(!1),[me,he]=(0,A.useState)(),Q=(0,A.useRef)(0),ge=async(t=i)=>{let n=++Q.current;de(!0),G(``);try{let r=await k(h===`roblox`&&e?.engine===`roblox`?`/projects/${e.id}/roblox/assets?${new URLSearchParams({q:t,type:C})}`:`/assets?${new URLSearchParams({q:t,provider:h,type:C})}`);if(n!==Q.current)return;M(r.assets),le(r.warnings)}catch(e){n===Q.current&&G(T(e))}finally{n===Q.current&&de(!1)}},$=async()=>{if(!e)return;let t=await k(`/projects/${e.id}`);ie(t.assets);let n=t.plans.toSorted((e,t)=>t.version-e.version)[0];ae(t.tasks.filter(e=>e.planId===n?.id&&[`open`,`failed`].includes(e.status))),se(E(t.run))};(0,A.useEffect)(()=>(ge(),()=>{Q.current++}),[h,C]),(0,A.useEffect)(()=>{$().catch(e=>G(T(e)))},[e?.id]),(0,A.useEffect)(()=>{oe(``),K&&$().catch(e=>G(T(e)))},[K?.id,K?.provider]),(0,A.useEffect)(()=>{if(!J||!e)return;let t=new EventSource(`/api/v1/events?projectId=${encodeURIComponent(e.id)}`);return t.addEventListener(`hub`,e=>{let t=JSON.parse(e.data);if(t.type===`asset.progress`){let e=t.payload.downloaded??t.payload.received??t.payload.bytes;e!==void 0&&t.payload.total&&he(e/t.payload.total*100)}}),()=>t.close()},[J,e?.id]);let _e=e=>{ce(t=>{let n=t.some(t=>L(t)===L(e))?t.filter(t=>L(t)!==L(e)):[...t,e];return localStorage.setItem(`lmgh-favourites`,JSON.stringify(n)),n})},ve=async()=>{if(e&&K){Y(`Загружаем ${K.name}`),G(``),X(``),he(void 0);try{await k(K.provider===`roblox`?`/projects/${e.id}/roblox/assets`:`/projects/${e.id}/assets`,`POST`,K.provider===`roblox`?{id:K.id}:{provider:K.provider,id:K.id}),await $(),await t(),X(`«${K.name}» добавлен в проект.`),q(null)}catch(e){G(T(e))}finally{Y(``)}}},ye=async()=>{if(e&&K&&B){Y(`Прикрепляем ресурс к задаче`),G(``),he(void 0);try{await k(`/projects/${e.id}/tasks/${B}/assets`,`POST`,{provider:K.provider,id:K.id}),await $(),await t(),X(`«${K.name}» прикреплён к задаче. Агент получит выбранный ресурс при её выполнении.`),q(null)}catch(e){G(T(e))}finally{Y(``)}}},be=D===`favourites`?H:D===`project`?R:j;return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(c,{title:`Бесплатно для ваших миров`,description:`Модели, текстуры и детали, из которых складывается игра.`,action:(0,P.jsxs)(u,{disabled:!e,onClick:()=>Z(!0),children:[(0,P.jsx)(x,{size:17}),`Импорт файла`]})}),n&&(0,P.jsxs)(`div`,{className:`selection-reopen-panel`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Ассеты по плану игры`}),(0,P.jsx)(`p`,{children:n.status===`confirmed`?`Выбранный набор сохранён в проекте.`:`Подбор сохранён. Завершите выбор перед разработкой.`})]}),(0,P.jsxs)(u,{onClick:r,"data-testid":`assets-open-selection`,children:[`Открыть подбор `,(0,P.jsx)(o,{size:16})]})]}),(0,P.jsxs)(`div`,{className:`asset-catalog-intro`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(w,{size:27}),(0,P.jsxs)(`span`,{children:[`Открытые коллекции`,(0,P.jsx)(`small`,{children:`Проверяйте лицензию у каждого ресурса`})]})]}),(0,P.jsxs)(`div`,{className:`source-list`,children:[(0,P.jsx)(`span`,{children:`Poly Haven`}),(0,P.jsx)(`span`,{children:`ambientCG`}),(0,P.jsx)(`span`,{children:`Kenney`})]})]}),(0,P.jsx)(v,{value:D,onValueChange:te,children:(0,P.jsxs)(_,{"aria-label":`Коллекции ассетов`,className:`tabs-list`,children:[(0,P.jsx)(g,{value:`catalog`,children:`Каталог`}),(0,P.jsxs)(g,{value:`favourites`,children:[`Избранное`,H.length>0&&(0,P.jsx)(`span`,{children:H.length})]}),(0,P.jsxs)(g,{value:`project`,disabled:!e,children:[`В проекте`,R.length>0&&(0,P.jsx)(`span`,{children:R.length})]})]})}),D===`catalog`&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsxs)(`form`,{className:`asset-search`,onSubmit:e=>{e.preventDefault(),ge()},children:[(0,P.jsxs)(`div`,{className:`search-input`,children:[(0,P.jsx)(y,{size:20}),(0,P.jsx)(`input`,{"aria-label":`Поиск ассетов`,value:i,onChange:e=>s(e.target.value),placeholder:`Лес, камень, персонаж…`})]}),(0,P.jsx)(`select`,{"aria-label":`Источник ассетов`,value:h,onChange:e=>b(e.target.value),children:Object.entries(F).map(([e,t])=>(0,P.jsx)(`option`,{value:e,children:t},e))}),(0,P.jsx)(u,{type:`submit`,tone:`primary`,busy:ue,children:`Найти`})]}),(0,P.jsx)(`div`,{className:`asset-types`,"aria-label":`Тип ассета`,children:Object.entries(I).map(([e,t])=>(0,P.jsx)(`button`,{className:C===e?`selected`:``,"aria-pressed":C===e,onClick:()=>ee(e),children:t},e))})]}),W&&!K&&(0,P.jsx)(p,{children:W}),fe&&(0,P.jsx)(p,{type:`success`,children:fe}),U.length>0&&D===`catalog`&&(0,P.jsxs)(`details`,{className:`provider-warnings`,children:[(0,P.jsxs)(`summary`,{children:[(0,P.jsx)(S,{size:15}),`Часть источников недоступна (`,U.length,`)`]}),U.map((e,t)=>(0,P.jsx)(`p`,{children:e},t))]}),ue&&D===`catalog`?(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(d,{label:`Ищем ресурсы в открытых каталогах`}),(0,P.jsx)(`div`,{className:`asset-grid`,children:Array.from({length:6},(e,t)=>(0,P.jsxs)(`div`,{className:`asset-skeleton`,children:[(0,P.jsx)(`div`,{}),(0,P.jsx)(`span`,{}),(0,P.jsx)(`span`,{})]},t))})]}):be.length===0?(0,P.jsx)(f,{icon:D===`favourites`?(0,P.jsx)(N,{size:30}):(0,P.jsx)(w,{size:30}),title:D===`favourites`?`Сохраните то, что понравилось`:D===`project`?`Коллекция проекта пока пуста`:`Подходящих ресурсов не найдено`,children:D===`favourites`?`Нажмите на сердце у ассета. Избранное сохраняется в этом браузере.`:D===`project`?`Добавьте ресурс из каталога или импортируйте скачанный файл.`:`Попробуйте другой запрос или источник. Для международных каталогов лучше использовать английские слова.`}):(0,P.jsx)(`div`,{className:`asset-grid`,children:be.map(e=>(0,P.jsxs)(`article`,{className:`asset-card`,children:[(0,P.jsx)(a,{asset:e,compact:!0}),(0,P.jsxs)(`div`,{className:`asset-card-info`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h3`,{children:(0,P.jsx)(`button`,{"data-testid":`open-asset-detail`,"aria-label":`Подробнее: ${e.name}`,onClick:()=>{q(e),G(``)},children:e.name})}),(0,P.jsxs)(`p`,{children:[F[e.provider]??e.provider,` `,(0,P.jsx)(`span`,{children:`·`}),` `,e.license]})]}),(0,P.jsx)(`button`,{className:`icon-button favourite ${H.some(t=>L(t)===L(e))?`is-favourite`:``}`,"aria-label":`${H.some(t=>L(t)===L(e))?`Убрать из избранного`:`В избранное`}: ${e.name}`,onClick:()=>_e(e),children:(0,P.jsx)(N,{size:19,weight:H.some(t=>L(t)===L(e))?`fill`:`regular`})})]}),(0,P.jsxs)(`div`,{className:`asset-card-footer`,children:[(0,P.jsx)(`span`,{children:I[e.type]??e.type}),(0,P.jsxs)(`span`,{children:[e.importMode===`automatic`?`Прямой импорт`:`На сайте автора`,(0,P.jsx)(o,{size:12})]})]})]},L(e)))}),D===`catalog`&&(0,P.jsxs)(`div`,{className:`more-sources`,children:[(0,P.jsx)(`h3`,{children:`Ещё больше ресурсов`}),(0,P.jsx)(`p`,{children:`У этих каталогов разные лицензии. Скачайте подходящий файл и импортируйте его в проект.`}),(0,P.jsxs)(`div`,{children:[(0,P.jsxs)(`a`,{href:`https://opengameart.org/art-search-advanced?keys=${encodeURIComponent(i)}`,target:`_blank`,rel:`noreferrer`,children:[`OpenGameArt`,(0,P.jsx)(o,{size:17})]}),(0,P.jsxs)(`a`,{href:`https://itch.io/game-assets/free?q=${encodeURIComponent(i)}`,target:`_blank`,rel:`noreferrer`,children:[`itch.io · Free assets`,(0,P.jsx)(o,{size:17})]})]})]}),(0,P.jsx)(l,{open:!!K,onOpenChange:e=>{!e&&!J&&q(null)},title:K?.name??`Ассет`,description:`${F[K?.provider??``]??K?.provider??``} · ${K?.license??``}`,children:K&&(0,P.jsxs)(`div`,{className:`asset-detail`,children:[(0,P.jsx)(a,{asset:K}),(0,P.jsxs)(`dl`,{children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`dt`,{children:`Автор`}),(0,P.jsx)(`dd`,{children:K.author||`Указан на странице источника`})]}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`dt`,{children:`Форматы`}),(0,P.jsx)(`dd`,{children:K.formats?.join(`, `)||`Зависят от выбранного ресурса`})]}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`dt`,{children:`Лицензия`}),(0,P.jsx)(`dd`,{children:K.license})]})]}),(0,P.jsx)(`div`,{className:`asset-tags`,children:K.tags.slice(0,8).map(e=>(0,P.jsx)(`span`,{className:`badge`,children:e},e))}),W&&(0,P.jsx)(p,{children:W}),J&&(0,P.jsx)(d,{label:J,value:J.startsWith(`Загружаем`)?me:void 0}),!e&&(0,P.jsx)(p,{type:`info`,children:`Выберите или создайте проект, чтобы импортировать ассет.`}),e&&z.length>0&&(0,P.jsxs)(`section`,{className:`attach-asset`,children:[(0,P.jsxs)(`label`,{children:[`Ресурс для задачи`,(0,P.jsxs)(`select`,{"aria-label":`Задача для ассета`,value:B,onChange:e=>oe(e.target.value),disabled:!!J||V,children:[(0,P.jsx)(`option`,{value:``,children:`Выберите задачу`}),z.map(e=>(0,P.jsx)(`option`,{value:e.id,children:e.title},e.id))]})]}),(0,P.jsx)(`small`,{children:V?`Приостановите работу агента, чтобы изменить ресурсы задачи.`:`Агент получит ссылку и лицензию. Если ресурс уже импортирован, он также получит путь к файлам.`}),(0,P.jsx)(u,{"data-testid":`attach-asset`,disabled:!B||V||!!J,onClick:()=>void ye(),children:`Прикрепить к задаче`})]}),(0,P.jsxs)(`div`,{className:`modal-actions`,children:[/^https?:\/\//.test(K.sourceUrl)&&(0,P.jsxs)(`a`,{href:K.sourceUrl,target:`_blank`,rel:`noreferrer`,className:`button button-default`,children:[`Страница автора`,(0,P.jsx)(o,{size:16})]}),R.some(e=>L(e)===L(K))?(0,P.jsxs)(`span`,{className:`badge badge-success`,children:[(0,P.jsx)(O,{size:14}),`В проекте`]}):K.importMode===`automatic`?(0,P.jsxs)(u,{tone:`primary`,disabled:!e||!!J,busy:!!J,onClick:()=>void ve(),children:[(0,P.jsx)(m,{size:17}),`Добавить в проект`]}):(0,P.jsx)(u,{tone:`primary`,disabled:!e||!!J,onClick:()=>{q(null),Z(!0)},children:`Импортировать файл`})]})]})}),e&&(0,P.jsx)(re,{open:pe,onOpenChange:Z,project:e,onDone:async()=>{await $(),await t(),X(`Файл импортирован в проект.`)}})]})}function re({open:e,onOpenChange:t,project:n,onDone:r}){let[i,a]=(0,A.useState)(null),[o,s]=(0,A.useState)(``),[c,f]=(0,A.useState)(``),[m,h]=(0,A.useState)(``),[g,_]=(0,A.useState)(!1),[v,y]=(0,A.useState)(),[b,S]=(0,A.useState)(``);return(0,P.jsx)(l,{open:e,onOpenChange:e=>{g||t(e)},title:`Импорт ассета`,description:`Добавьте скачанный ресурс и сохраните информацию об авторе.`,children:(0,P.jsxs)(`form`,{onSubmit:e=>{if(e.preventDefault(),!i)return;_(!0),S(``);let s=new FormData;s.append(`sourceUrl`,o),s.append(`license`,c),s.append(`author`,m),s.append(`file`,i);let l=new XMLHttpRequest;l.open(`POST`,`/api/v1/projects/${n.id}/assets/upload`),l.upload.onprogress=e=>{e.lengthComputable&&y(e.loaded/e.total*100)},l.onerror=()=>{S(`Не удалось загрузить файл. Проверьте подключение к локальному серверу.`),_(!1)},l.onload=()=>{(async()=>{try{let e=JSON.parse(l.responseText);if(l.status<200||l.status>=300)throw Error(e.message??`Ошибка импорта`);await r(),t(!1),a(null)}catch(e){S(T(e))}finally{_(!1)}})()},l.send(s)},className:`project-form`,children:[(0,P.jsxs)(`label`,{children:[`Файл`,(0,P.jsx)(`input`,{type:`file`,required:!0,onChange:e=>a(e.target.files?.[0]??null)}),(0,P.jsx)(`small`,{children:`Архив ZIP или отдельный ресурс, до 512 МБ.`})]}),(0,P.jsxs)(`label`,{children:[`Ссылка на источник`,(0,P.jsx)(`input`,{type:`url`,value:o,onChange:e=>s(e.target.value),placeholder:`https://…`})]}),(0,P.jsxs)(`div`,{className:`form-columns`,children:[(0,P.jsxs)(`label`,{children:[`Автор`,(0,P.jsx)(`input`,{value:m,onChange:e=>h(e.target.value)})]}),(0,P.jsxs)(`label`,{children:[`Лицензия`,(0,P.jsx)(`input`,{required:!0,value:c,onChange:e=>f(e.target.value),placeholder:`Например, CC0-1.0`})]})]}),g&&(0,P.jsx)(d,{label:v===100?`Распаковываем и импортируем`:`Загружаем файл`,value:v===100?void 0:v}),b&&(0,P.jsx)(p,{children:b}),(0,P.jsxs)(`div`,{className:`modal-actions`,children:[(0,P.jsx)(u,{type:`button`,disabled:g,onClick:()=>t(!1),children:`Отмена`}),(0,P.jsxs)(u,{tone:`primary`,type:`submit`,busy:g,disabled:!i,children:[(0,P.jsx)(x,{size:16}),`Импортировать`]})]})]})})}function ie({project:e}){let[t,n]=(0,A.useState)([]),[r,i]=(0,A.useState)([]),[a,s]=(0,A.useState)(!0),[l,f]=(0,A.useState)(!1),[m,h]=(0,A.useState)(``),[g,_]=(0,A.useState)(``);(0,A.useEffect)(()=>{let t=!0;return s(!0),Promise.all([k(e?`/extensions?projectId=${encodeURIComponent(e.id)}`:`/extensions`),e?k(`/projects/${e.id}`):Promise.resolve(null)]).then(([e,r])=>{t&&(n(e),i(r?.extensions??[]))}).catch(e=>{t&&h(T(e))}).finally(()=>{t&&s(!1)}),()=>{t=!1}},[e?.id]);let v=async t=>{if(e){f(!0),h(``);try{i(await k(`/projects/${e.id}/extensions/install`,`POST`,t?{ids:[t]}:{})),_(`Рекомендованные навыки установлены в проект.`)}catch(e){h(T(e))}finally{f(!1)}}};return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(c,{title:`Нужные навыки под рукой`,description:`Инструкции и инструменты, которые помогают агенту создавать вашу игру.`,action:(0,P.jsxs)(u,{tone:`primary`,disabled:!e,busy:l,onClick:()=>void v(),children:[(0,P.jsx)(D,{size:17}),`Подключить рекомендованные`]})}),m&&(0,P.jsx)(p,{children:m}),g&&(0,P.jsx)(p,{type:`success`,children:g}),(a||l)&&(0,P.jsx)(d,{label:l?`Устанавливаем навыки в проект`:`Загружаем каталог расширений`}),!e&&(0,P.jsx)(p,{type:`info`,children:`Создайте проект, чтобы автоматически подобрать навыки под движок и размерность.`}),(0,P.jsxs)(`div`,{className:`extension-intro`,children:[(0,P.jsx)(b,{size:24}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h3`,{children:`Подбор по вашему проекту`}),(0,P.jsxs)(`p`,{children:[`Базовые навыки `,e?e.engine===`html5`?`HTML5`:e.engine===`godot`?`Godot`:e.engine:`выбранного движка`,` устанавливаются при создании проекта. Версии и источники сохраняются локально.`]})]})]}),[`skill`,`mcp`,`plugin`].map(n=>{let i=t.filter(e=>e.type===n);return(0,P.jsxs)(`section`,{className:`extension-section`,children:[(0,P.jsxs)(`div`,{className:`section-label`,children:[(0,P.jsx)(`h2`,{children:{skill:`Навыки агента`,mcp:`MCP-инструменты`,plugin:`Плагины редактора`}[n]}),(0,P.jsx)(`span`,{children:i.length})]}),i.length?(0,P.jsx)(`div`,{className:`extension-list`,children:i.map(t=>(0,P.jsxs)(`article`,{className:`extension-row`,children:[(0,P.jsx)(`div`,{className:`extension-icon`,children:n===`skill`?(0,P.jsx)(z,{}):(0,P.jsx)(D,{size:22})}),(0,P.jsxs)(`div`,{children:[(0,P.jsxs)(`div`,{className:`extension-title`,children:[(0,P.jsx)(`h3`,{children:t.name}),(0,P.jsxs)(`span`,{className:`mono muted`,children:[`v`,t.version]})]}),(0,P.jsx)(`p`,{children:t.description}),/^https?:\/\//.test(t.source)?(0,P.jsxs)(`a`,{href:t.source,target:`_blank`,rel:`noreferrer`,children:[`Источник`,(0,P.jsx)(o,{size:12})]}):(0,P.jsx)(`span`,{className:`license-text`,children:t.source}),t.reference&&(0,P.jsxs)(`a`,{className:`extension-reference`,href:t.reference,target:`_blank`,rel:`noreferrer`,children:[`Документация`,(0,P.jsx)(o,{size:12})]}),(0,P.jsx)(`span`,{className:`license-text`,children:t.license})]}),r.some(e=>e.id===t.id)?(0,P.jsxs)(`span`,{className:`badge badge-success`,children:[(0,P.jsx)(O,{size:14}),`Подключён`]}):(0,P.jsx)(u,{disabled:!e||l,onClick:()=>void v(t.id),children:`Подключить`})]},t.id))}):(0,P.jsx)(`p`,{className:`section-empty`,children:n===`plugin`?`Плагины редактора подключаются, когда этого требует проект.`:`Инструменты ассетов доступны агенту во время разработки.`})]},n)})]})}function z(){return(0,P.jsx)(b,{size:22})}function ae({settings:e,onSave:t,project:n,onProjectChange:r}){let[a,o]=(0,A.useState)(e),[l,f]=(0,A.useState)(!1),[m,g]=(0,A.useState)(!1),[_,v]=(0,A.useState)(!1),[y,b]=(0,A.useState)(null),[x,E]=(0,A.useState)(``),[j,M]=(0,A.useState)(``);(0,A.useEffect)(()=>o(e),[e]);let N=async()=>{if(!(l||m)){E(``),M(``),g(!0);try{let e=(await k(`/dialogs/directory`,`POST`,{})).path;e!==null&&o(t=>({...t,projectsDirectory:e}))}catch(e){E(T(e))}finally{g(!1)}}},F=async e=>{if(e.preventDefault(),!(l||m)){f(!0),E(``),M(``);try{let e={...a,agents:Object.fromEntries(Object.entries(a.agents).map(([e,t])=>[e,{...t,executable:t.executable?.trim()||e,model:t.model?.trim()??``,...e===`codex`?{reasoningEffort:t.reasoningEffort?.trim()||`medium`}:{}}]))};t(await k(`/settings`,`PUT`,e)),M(`Настройки сохранены.`)}catch(e){E(T(e))}finally{f(!1)}}},I=async()=>{v(!0),E(``);try{b(await k(`/diagnostics`))}catch(e){E(T(e))}finally{v(!1)}};return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(c,{title:`Подключения и рабочая среда`,description:`Подключения, рабочая среда и внешний вид мастерской.`}),x&&(0,P.jsx)(p,{children:x}),j&&(0,P.jsx)(p,{type:`success`,children:j}),(0,P.jsx)(te,{}),(0,P.jsxs)(`form`,{onSubmit:F,className:`settings-form`,children:[(0,P.jsxs)(`section`,{className:`settings-section`,children:[(0,P.jsxs)(`div`,{className:`settings-description`,children:[(0,P.jsx)(`h2`,{children:`Внешний вид`}),(0,P.jsx)(`p`,{children:`Выберите комфортную тему.`})]}),(0,P.jsxs)(`div`,{className:`settings-fields`,children:[(0,P.jsxs)(`label`,{children:[`Тема`,(0,P.jsxs)(`select`,{"data-testid":`theme-select`,value:a.theme,onChange:e=>o(t=>({...t,theme:e.target.value})),children:[(0,P.jsx)(`option`,{value:`system`,children:`Как в системе`}),(0,P.jsx)(`option`,{value:`light`,children:`Светлая`}),(0,P.jsx)(`option`,{value:`dark`,children:`Тёмная`})]})]}),(0,P.jsxs)(`label`,{children:[`Интерфейс`,(0,P.jsxs)(`select`,{"data-testid":`interface-select`,value:a.interfaceMode??`robot`,onChange:e=>o(t=>({...t,interfaceMode:e.target.value})),children:[(0,P.jsx)(`option`,{value:`robot`,children:`Робот-помощник (для детей)`}),(0,P.jsx)(`option`,{value:`road`,children:`Дорожка (для детей)`})]})]})]})]}),(0,P.jsxs)(`section`,{className:`settings-section`,children:[(0,P.jsxs)(`div`,{className:`settings-description`,children:[(0,P.jsx)(`h2`,{children:`Разрешения агента`}),(0,P.jsx)(`p`,{children:`Команды и инструменты во время работы над игрой.`})]}),(0,P.jsxs)(`div`,{className:`settings-fields`,children:[(0,P.jsxs)(`label`,{className:`agent-permission-setting`,children:[(0,P.jsx)(`input`,{type:`checkbox`,"data-testid":`auto-approve-actions`,checked:a.autoApproveActions===!0,disabled:e.autoApproveActions===void 0||l,onChange:e=>o(t=>({...t,autoApproveActions:e.target.checked}))}),(0,P.jsx)(`span`,{children:`Автоматически разрешать действия агента`})]}),(0,P.jsx)(`small`,{"data-testid":`agent-permission-mode`,children:e.autoApproveActions===void 0?`Настройка появится после обновления запущенного сервера.`:a.autoApproveActions?`Разрешения агента: автоматически`:`Разрешения агента: запрашивать`}),(0,P.jsxs)(`p`,{className:`settings-permission-hint`,children:[e.autoApproveActions===void 0?`Режим разрешений определяется запущенным сервером.`:a.autoApproveActions?`Команды и инструменты разрешаются без отдельного подтверждения.`:`Команды и инструменты требуют вашего подтверждения.`,` На вопросы об игре вы отвечаете сами. Изменение применяется после сохранения настроек.`]})]})]}),(0,P.jsxs)(`section`,{className:`settings-section`,children:[(0,P.jsxs)(`div`,{className:`settings-description`,children:[(0,P.jsx)(`h2`,{children:`Рабочая среда`}),(0,P.jsx)(`p`,{children:`Редактор и папка для новых проектов.`})]}),(0,P.jsxs)(`div`,{className:`settings-fields`,children:[(0,P.jsxs)(`label`,{children:[`Путь к Godot`,(0,P.jsx)(`input`,{value:a.godotPath??``,onChange:e=>o(t=>({...t,godotPath:e.target.value})),placeholder:`Автоматическое обнаружение`})]}),n?.engine===`roblox`&&(0,P.jsx)(ee,{project:n}),(0,P.jsxs)(`details`,{children:[(0,P.jsx)(`summary`,{children:`Дополнительные пути Roblox Studio`}),[[`robloxStudioPath`,`Путь к Roblox Studio`],[`robloxMcpPath`,`Путь к StudioMCP`]].map(([e,t])=>(0,P.jsxs)(`label`,{children:[t,(0,P.jsx)(`input`,{value:a[e]??``,onChange:t=>o(n=>({...n,[e]:t.target.value})),placeholder:`Автоматическое обнаружение`})]},e)),(0,P.jsx)(`small`,{children:`Studio ID определяется по идентификатору проекта автоматически. Сохраните изменённые пути перед проверкой подключения.`})]}),(0,P.jsxs)(`div`,{className:`directory-picker-field`,children:[(0,P.jsx)(`label`,{htmlFor:`settings-projects-directory`,children:`Папка проектов`}),(0,P.jsxs)(`div`,{className:`directory-picker-row`,children:[(0,P.jsx)(`input`,{id:`settings-projects-directory`,"data-testid":`settings-projects-directory`,readOnly:!0,value:a.projectsDirectory??``,title:a.projectsDirectory||void 0,placeholder:`Папка ещё не выбрана`,"aria-describedby":`settings-directory-hint`}),(0,P.jsxs)(u,{type:`button`,"data-testid":`choose-settings-directory`,busy:m,disabled:l||m,onClick:()=>void N(),children:[(0,P.jsx)(h,{size:18}),`Выбрать папку`]})]}),(0,P.jsx)(`small`,{id:`settings-directory-hint`,children:`Выберите папку в системном окне, затем сохраните настройки.`}),m&&(0,P.jsx)(d,{label:`Ожидаем выбор папки в системном окне`})]})]})]}),(0,P.jsx)(`div`,{className:`settings-actions`,children:(0,P.jsxs)(u,{tone:`primary`,type:`submit`,busy:l,disabled:m,children:[(0,P.jsx)(O,{size:17}),`Сохранить настройки`]})})]}),(0,P.jsxs)(`section`,{className:`diagnostics-section`,children:[(0,P.jsxs)(`div`,{className:`row-between`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h2`,{children:`Проверка подключений`}),(0,P.jsx)(`p`,{children:`Проверяются сохранённые пути и доступность инструментов.`})]}),(0,P.jsxs)(u,{busy:_,onClick:()=>void I(),children:[(0,P.jsx)(i,{size:17}),`Проверить`]})]}),_&&(0,P.jsx)(d,{label:`Проверяем локальные CLI и движки`}),y&&(0,P.jsxs)(`div`,{className:`diagnostics-list`,children:[y.agents.map(e=>{let t=e.available&&e.protocol!==`failed`&&e.authentication!==`required`,n=e.available?e.protocol===`failed`?`Ошибка протокола`:e.authentication===`required`?`Нужен вход`:e.authentication===`ready`?`Готов`:`Ядро подключено`:`Не найден`;return(0,P.jsxs)(`div`,{className:`diagnostic-row`,children:[t?(0,P.jsx)(s,{size:20,className:`success-text`}):(0,P.jsx)(S,{size:20,className:`warning-text`}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:C[e.id]}),(0,P.jsx)(`small`,{children:e.error||(e.available?[e.version,e.authentication===`unknown`?`Авторизация проверяется при первом запросе.`:``].filter(Boolean).join(` · `):`Подключите аккаунт UMGT и повторите проверку.`)})]}),(0,P.jsx)(`span`,{className:`badge ${t?`badge-success`:``}`,children:n})]},e.id)}),y.roblox&&(0,P.jsxs)(`article`,{className:`diagnostic-item`,children:[(0,P.jsx)(w,{size:22}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Roblox Studio`}),(0,P.jsx)(`small`,{children:y.roblox.executable??y.roblox.message}),(0,P.jsx)(`small`,{children:y.roblox.available?y.roblox.message:``})]}),(0,P.jsx)(`span`,{className:`badge ${y.roblox.available?`badge-success`:``}`,children:y.roblox.available?`Найдена`:`Недоступна`})]}),y.robloxMcp&&(0,P.jsxs)(`article`,{className:`diagnostic-item`,children:[(0,P.jsx)(D,{size:22}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Studio MCP`}),(0,P.jsx)(`small`,{children:y.robloxMcp.message})]}),(0,P.jsx)(`span`,{className:`badge ${y.robloxMcp.available?`badge-success`:``}`,children:y.robloxMcp.available?`Отвечает`:`Не подключён`})]}),y.godot&&(0,P.jsxs)(`div`,{className:`diagnostic-row`,children:[y.godot.available?(0,P.jsx)(s,{size:20,className:`success-text`}):(0,P.jsx)(S,{size:20,className:`warning-text`}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Godot`}),(0,P.jsx)(`small`,{children:y.godot.version??y.godot.error??y.godot.message??`Укажите путь к редактору.`}),y.godot.available&&y.godot.message&&(0,P.jsx)(`small`,{children:y.godot.message})]}),(0,P.jsx)(`span`,{className:`badge ${y.godot.available?`badge-success`:``}`,children:y.godot.available?`Найден`:`Недоступен`})]})]})]})]})}export{R as AssetsView,ie as ExtensionsView,ae as SettingsView};
1
+ import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CdVFa8IP.js";import{i,t as a}from"./AssetMediaPreview-D2cd6oQO.js";import{t as o}from"./ArrowUpRight.es-BmIrpjWN.js";import{t as s}from"./CheckCircle.es-D5B3hdvz.js";import{a as c,i as l,n as u,o as d,r as f,t as p}from"./ui-wHE_yBK0.js";import{t as m}from"./DownloadSimple.es-DwOWFbs2.js";import{a as h,i as g,r as _,t as v}from"./dist-7vx7MTaJ.js";import{t as y}from"./MagnifyingGlass.es-rkdOU2rH.js";import{t as b}from"./Sparkle.es-CmGpvnNm.js";import{t as x}from"./UploadSimple.es-DxIuxpCC.js";import{t as S}from"./WarningCircle.es-D63H8cL9.js";import{A as C,E as ee,H as w,M as T,N as E,R as D,U as O,j as k}from"./index-B6_q6dBC.js";import{CoreAccount as te}from"./CoreAccount-BfH0gEKJ.js";var A=t(n(),1),j=new Map([[`bold`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,36c-20.09,0-37.92,7.93-50,21.56C115.92,43.93,98.09,36,78,36a66.08,66.08,0,0,0-66,66c0,72.34,105.81,130.14,110.31,132.57a12,12,0,0,0,11.38,0C138.19,232.14,244,174.34,244,102A66.08,66.08,0,0,0,178,36Zm-5.49,142.36A328.69,328.69,0,0,1,128,210.16a328.69,328.69,0,0,1-44.51-31.8C61.82,159.77,36,131.42,36,102A42,42,0,0,1,78,60c17.8,0,32.7,9.4,38.89,24.54a12,12,0,0,0,22.22,0C145.3,69.4,160.2,60,178,60a42,42,0,0,1,42,42C220,131.42,194.18,159.77,172.51,178.36Z`}))],[`duotone`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M232,102c0,66-104,122-104,122S24,168,24,102A54,54,0,0,1,78,48c22.59,0,41.94,12.31,50,32,8.06-19.69,27.41-32,50-32A54,54,0,0,1,232,102Z`,opacity:`0.2`}),A.createElement(`path`,{d:`M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z`}))],[`fill`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M240,102c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,228.66,16,172,16,102A62.07,62.07,0,0,1,78,40c20.65,0,38.73,8.88,50,23.89C139.27,48.88,157.35,40,178,40A62.07,62.07,0,0,1,240,102Z`}))],[`light`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,42c-21,0-39.26,9.47-50,25.34C117.26,51.47,99,42,78,42a60.07,60.07,0,0,0-60,60c0,29.2,18.2,59.59,54.1,90.31a334.68,334.68,0,0,0,53.06,37,6,6,0,0,0,5.68,0,334.68,334.68,0,0,0,53.06-37C219.8,161.59,238,131.2,238,102A60.07,60.07,0,0,0,178,42ZM128,217.11C111.59,207.64,30,157.72,30,102A48.05,48.05,0,0,1,78,54c20.28,0,37.31,10.83,44.45,28.27a6,6,0,0,0,11.1,0C140.69,64.83,157.72,54,178,54a48.05,48.05,0,0,1,48,48C226,157.72,144.41,207.64,128,217.11Z`}))],[`regular`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z`}))],[`thin`,A.createElement(A.Fragment,null,A.createElement(`path`,{d:`M178,44c-21.44,0-39.92,10.19-50,27.07C117.92,54.19,99.44,44,78,44a58.07,58.07,0,0,0-58,58c0,28.59,18,58.47,53.4,88.79a333.81,333.81,0,0,0,52.7,36.73,4,4,0,0,0,3.8,0,333.81,333.81,0,0,0,52.7-36.73C218,160.47,236,130.59,236,102A58.07,58.07,0,0,0,178,44ZM128,219.42c-14-8-100-59.35-100-117.42A50.06,50.06,0,0,1,78,52c21.11,0,38.85,11.31,46.3,29.51a4,4,0,0,0,7.4,0C139.15,63.31,156.89,52,178,52a50.06,50.06,0,0,1,50,50C228,160,142,211.46,128,219.42Z`}))]]),M=A.forwardRef((t,n)=>A.createElement(e,{ref:n,...t,weights:j}));M.displayName=`HeartIcon`;var N=M,P=r(),F={all:`Все источники`,roblox:`Roblox Creator Store`,polyhaven:`Poly Haven`,ambientcg:`ambientCG`,kenney:`Kenney`,opengameart:`OpenGameArt`,blender:`Blender Open Movies`},I={all:`Всё`,models:`3D-модели`,textures:`Материалы`,hdris:`HDRI`,"2d":`2D`,ui:`Интерфейс`,audio:`Звук`,video:`Видео`,texture:`Текстуры`},L=e=>`${e.provider}:${e.sourceId??e.id}`;function ne(){try{return JSON.parse(localStorage.getItem(`lmgh-favourites`)??`[]`)}catch{return[]}}function R({project:e,onImported:t,selection:n,onSelection:r}){let[i,s]=(0,A.useState)(``),[h,b]=(0,A.useState)(e?.engine===`roblox`?`roblox`:`all`),[C,ee]=(0,A.useState)(`all`),[D,te]=(0,A.useState)(`catalog`),[j,M]=(0,A.useState)([]),[R,ie]=(0,A.useState)([]),[z,ae]=(0,A.useState)([]),[B,oe]=(0,A.useState)(``),[V,se]=(0,A.useState)(!1),[H,ce]=(0,A.useState)(ne),[U,le]=(0,A.useState)([]),[ue,de]=(0,A.useState)(!1),[W,G]=(0,A.useState)(``),[K,q]=(0,A.useState)(null),[J,Y]=(0,A.useState)(``),[fe,X]=(0,A.useState)(``),[pe,Z]=(0,A.useState)(!1),[me,he]=(0,A.useState)(),Q=(0,A.useRef)(0),ge=async(t=i)=>{let n=++Q.current;de(!0),G(``);try{let r=await k(h===`roblox`&&e?.engine===`roblox`?`/projects/${e.id}/roblox/assets?${new URLSearchParams({q:t,type:C})}`:`/assets?${new URLSearchParams({q:t,provider:h,type:C})}`);if(n!==Q.current)return;M(r.assets),le(r.warnings)}catch(e){n===Q.current&&G(T(e))}finally{n===Q.current&&de(!1)}},$=async()=>{if(!e)return;let t=await k(`/projects/${e.id}`);ie(t.assets);let n=t.plans.toSorted((e,t)=>t.version-e.version)[0];ae(t.tasks.filter(e=>e.planId===n?.id&&[`open`,`failed`].includes(e.status))),se(E(t.run))};(0,A.useEffect)(()=>(ge(),()=>{Q.current++}),[h,C]),(0,A.useEffect)(()=>{$().catch(e=>G(T(e)))},[e?.id]),(0,A.useEffect)(()=>{oe(``),K&&$().catch(e=>G(T(e)))},[K?.id,K?.provider]),(0,A.useEffect)(()=>{if(!J||!e)return;let t=new EventSource(`/api/v1/events?projectId=${encodeURIComponent(e.id)}`);return t.addEventListener(`hub`,e=>{let t=JSON.parse(e.data);if(t.type===`asset.progress`){let e=t.payload.downloaded??t.payload.received??t.payload.bytes;e!==void 0&&t.payload.total&&he(e/t.payload.total*100)}}),()=>t.close()},[J,e?.id]);let _e=e=>{ce(t=>{let n=t.some(t=>L(t)===L(e))?t.filter(t=>L(t)!==L(e)):[...t,e];return localStorage.setItem(`lmgh-favourites`,JSON.stringify(n)),n})},ve=async()=>{if(e&&K){Y(`Загружаем ${K.name}`),G(``),X(``),he(void 0);try{await k(K.provider===`roblox`?`/projects/${e.id}/roblox/assets`:`/projects/${e.id}/assets`,`POST`,K.provider===`roblox`?{id:K.id}:{provider:K.provider,id:K.id}),await $(),await t(),X(`«${K.name}» добавлен в проект.`),q(null)}catch(e){G(T(e))}finally{Y(``)}}},ye=async()=>{if(e&&K&&B){Y(`Прикрепляем ресурс к задаче`),G(``),he(void 0);try{await k(`/projects/${e.id}/tasks/${B}/assets`,`POST`,{provider:K.provider,id:K.id}),await $(),await t(),X(`«${K.name}» прикреплён к задаче. Агент получит выбранный ресурс при её выполнении.`),q(null)}catch(e){G(T(e))}finally{Y(``)}}},be=D===`favourites`?H:D===`project`?R:j;return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(c,{title:`Бесплатно для ваших миров`,description:`Модели, текстуры и детали, из которых складывается игра.`,action:(0,P.jsxs)(u,{disabled:!e,onClick:()=>Z(!0),children:[(0,P.jsx)(x,{size:17}),`Импорт файла`]})}),n&&(0,P.jsxs)(`div`,{className:`selection-reopen-panel`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Ассеты по плану игры`}),(0,P.jsx)(`p`,{children:n.status===`confirmed`?`Выбранный набор сохранён в проекте.`:`Подбор сохранён. Завершите выбор перед разработкой.`})]}),(0,P.jsxs)(u,{onClick:r,"data-testid":`assets-open-selection`,children:[`Открыть подбор `,(0,P.jsx)(o,{size:16})]})]}),(0,P.jsxs)(`div`,{className:`asset-catalog-intro`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(w,{size:27}),(0,P.jsxs)(`span`,{children:[`Открытые коллекции`,(0,P.jsx)(`small`,{children:`Проверяйте лицензию у каждого ресурса`})]})]}),(0,P.jsxs)(`div`,{className:`source-list`,children:[(0,P.jsx)(`span`,{children:`Poly Haven`}),(0,P.jsx)(`span`,{children:`ambientCG`}),(0,P.jsx)(`span`,{children:`Kenney`})]})]}),(0,P.jsx)(v,{value:D,onValueChange:te,children:(0,P.jsxs)(_,{"aria-label":`Коллекции ассетов`,className:`tabs-list`,children:[(0,P.jsx)(g,{value:`catalog`,children:`Каталог`}),(0,P.jsxs)(g,{value:`favourites`,children:[`Избранное`,H.length>0&&(0,P.jsx)(`span`,{children:H.length})]}),(0,P.jsxs)(g,{value:`project`,disabled:!e,children:[`В проекте`,R.length>0&&(0,P.jsx)(`span`,{children:R.length})]})]})}),D===`catalog`&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsxs)(`form`,{className:`asset-search`,onSubmit:e=>{e.preventDefault(),ge()},children:[(0,P.jsxs)(`div`,{className:`search-input`,children:[(0,P.jsx)(y,{size:20}),(0,P.jsx)(`input`,{"aria-label":`Поиск ассетов`,value:i,onChange:e=>s(e.target.value),placeholder:`Лес, камень, персонаж…`})]}),(0,P.jsx)(`select`,{"aria-label":`Источник ассетов`,value:h,onChange:e=>b(e.target.value),children:Object.entries(F).map(([e,t])=>(0,P.jsx)(`option`,{value:e,children:t},e))}),(0,P.jsx)(u,{type:`submit`,tone:`primary`,busy:ue,children:`Найти`})]}),(0,P.jsx)(`div`,{className:`asset-types`,"aria-label":`Тип ассета`,children:Object.entries(I).map(([e,t])=>(0,P.jsx)(`button`,{className:C===e?`selected`:``,"aria-pressed":C===e,onClick:()=>ee(e),children:t},e))})]}),W&&!K&&(0,P.jsx)(p,{children:W}),fe&&(0,P.jsx)(p,{type:`success`,children:fe}),U.length>0&&D===`catalog`&&(0,P.jsxs)(`details`,{className:`provider-warnings`,children:[(0,P.jsxs)(`summary`,{children:[(0,P.jsx)(S,{size:15}),`Часть источников недоступна (`,U.length,`)`]}),U.map((e,t)=>(0,P.jsx)(`p`,{children:e},t))]}),ue&&D===`catalog`?(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(d,{label:`Ищем ресурсы в открытых каталогах`}),(0,P.jsx)(`div`,{className:`asset-grid`,children:Array.from({length:6},(e,t)=>(0,P.jsxs)(`div`,{className:`asset-skeleton`,children:[(0,P.jsx)(`div`,{}),(0,P.jsx)(`span`,{}),(0,P.jsx)(`span`,{})]},t))})]}):be.length===0?(0,P.jsx)(f,{icon:D===`favourites`?(0,P.jsx)(N,{size:30}):(0,P.jsx)(w,{size:30}),title:D===`favourites`?`Сохраните то, что понравилось`:D===`project`?`Коллекция проекта пока пуста`:`Подходящих ресурсов не найдено`,children:D===`favourites`?`Нажмите на сердце у ассета. Избранное сохраняется в этом браузере.`:D===`project`?`Добавьте ресурс из каталога или импортируйте скачанный файл.`:`Попробуйте другой запрос или источник. Для международных каталогов лучше использовать английские слова.`}):(0,P.jsx)(`div`,{className:`asset-grid`,children:be.map(e=>(0,P.jsxs)(`article`,{className:`asset-card`,children:[(0,P.jsx)(a,{asset:e,compact:!0}),(0,P.jsxs)(`div`,{className:`asset-card-info`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h3`,{children:(0,P.jsx)(`button`,{"data-testid":`open-asset-detail`,"aria-label":`Подробнее: ${e.name}`,onClick:()=>{q(e),G(``)},children:e.name})}),(0,P.jsxs)(`p`,{children:[F[e.provider]??e.provider,` `,(0,P.jsx)(`span`,{children:`·`}),` `,e.license]})]}),(0,P.jsx)(`button`,{className:`icon-button favourite ${H.some(t=>L(t)===L(e))?`is-favourite`:``}`,"aria-label":`${H.some(t=>L(t)===L(e))?`Убрать из избранного`:`В избранное`}: ${e.name}`,onClick:()=>_e(e),children:(0,P.jsx)(N,{size:19,weight:H.some(t=>L(t)===L(e))?`fill`:`regular`})})]}),(0,P.jsxs)(`div`,{className:`asset-card-footer`,children:[(0,P.jsx)(`span`,{children:I[e.type]??e.type}),(0,P.jsxs)(`span`,{children:[e.importMode===`automatic`?`Прямой импорт`:`На сайте автора`,(0,P.jsx)(o,{size:12})]})]})]},L(e)))}),D===`catalog`&&(0,P.jsxs)(`div`,{className:`more-sources`,children:[(0,P.jsx)(`h3`,{children:`Ещё больше ресурсов`}),(0,P.jsx)(`p`,{children:`У этих каталогов разные лицензии. Скачайте подходящий файл и импортируйте его в проект.`}),(0,P.jsxs)(`div`,{children:[(0,P.jsxs)(`a`,{href:`https://opengameart.org/art-search-advanced?keys=${encodeURIComponent(i)}`,target:`_blank`,rel:`noreferrer`,children:[`OpenGameArt`,(0,P.jsx)(o,{size:17})]}),(0,P.jsxs)(`a`,{href:`https://itch.io/game-assets/free?q=${encodeURIComponent(i)}`,target:`_blank`,rel:`noreferrer`,children:[`itch.io · Free assets`,(0,P.jsx)(o,{size:17})]})]})]}),(0,P.jsx)(l,{open:!!K,onOpenChange:e=>{!e&&!J&&q(null)},title:K?.name??`Ассет`,description:`${F[K?.provider??``]??K?.provider??``} · ${K?.license??``}`,children:K&&(0,P.jsxs)(`div`,{className:`asset-detail`,children:[(0,P.jsx)(a,{asset:K}),(0,P.jsxs)(`dl`,{children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`dt`,{children:`Автор`}),(0,P.jsx)(`dd`,{children:K.author||`Указан на странице источника`})]}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`dt`,{children:`Форматы`}),(0,P.jsx)(`dd`,{children:K.formats?.join(`, `)||`Зависят от выбранного ресурса`})]}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`dt`,{children:`Лицензия`}),(0,P.jsx)(`dd`,{children:K.license})]})]}),(0,P.jsx)(`div`,{className:`asset-tags`,children:K.tags.slice(0,8).map(e=>(0,P.jsx)(`span`,{className:`badge`,children:e},e))}),W&&(0,P.jsx)(p,{children:W}),J&&(0,P.jsx)(d,{label:J,value:J.startsWith(`Загружаем`)?me:void 0}),!e&&(0,P.jsx)(p,{type:`info`,children:`Выберите или создайте проект, чтобы импортировать ассет.`}),e&&z.length>0&&(0,P.jsxs)(`section`,{className:`attach-asset`,children:[(0,P.jsxs)(`label`,{children:[`Ресурс для задачи`,(0,P.jsxs)(`select`,{"aria-label":`Задача для ассета`,value:B,onChange:e=>oe(e.target.value),disabled:!!J||V,children:[(0,P.jsx)(`option`,{value:``,children:`Выберите задачу`}),z.map(e=>(0,P.jsx)(`option`,{value:e.id,children:e.title},e.id))]})]}),(0,P.jsx)(`small`,{children:V?`Приостановите работу агента, чтобы изменить ресурсы задачи.`:`Агент получит ссылку и лицензию. Если ресурс уже импортирован, он также получит путь к файлам.`}),(0,P.jsx)(u,{"data-testid":`attach-asset`,disabled:!B||V||!!J,onClick:()=>void ye(),children:`Прикрепить к задаче`})]}),(0,P.jsxs)(`div`,{className:`modal-actions`,children:[/^https?:\/\//.test(K.sourceUrl)&&(0,P.jsxs)(`a`,{href:K.sourceUrl,target:`_blank`,rel:`noreferrer`,className:`button button-default`,children:[`Страница автора`,(0,P.jsx)(o,{size:16})]}),R.some(e=>L(e)===L(K))?(0,P.jsxs)(`span`,{className:`badge badge-success`,children:[(0,P.jsx)(O,{size:14}),`В проекте`]}):K.importMode===`automatic`?(0,P.jsxs)(u,{tone:`primary`,disabled:!e||!!J,busy:!!J,onClick:()=>void ve(),children:[(0,P.jsx)(m,{size:17}),`Добавить в проект`]}):(0,P.jsx)(u,{tone:`primary`,disabled:!e||!!J,onClick:()=>{q(null),Z(!0)},children:`Импортировать файл`})]})]})}),e&&(0,P.jsx)(re,{open:pe,onOpenChange:Z,project:e,onDone:async()=>{await $(),await t(),X(`Файл импортирован в проект.`)}})]})}function re({open:e,onOpenChange:t,project:n,onDone:r}){let[i,a]=(0,A.useState)(null),[o,s]=(0,A.useState)(``),[c,f]=(0,A.useState)(``),[m,h]=(0,A.useState)(``),[g,_]=(0,A.useState)(!1),[v,y]=(0,A.useState)(),[b,S]=(0,A.useState)(``);return(0,P.jsx)(l,{open:e,onOpenChange:e=>{g||t(e)},title:`Импорт ассета`,description:`Добавьте скачанный ресурс и сохраните информацию об авторе.`,children:(0,P.jsxs)(`form`,{onSubmit:e=>{if(e.preventDefault(),!i)return;_(!0),S(``);let s=new FormData;s.append(`sourceUrl`,o),s.append(`license`,c),s.append(`author`,m),s.append(`file`,i);let l=new XMLHttpRequest;l.open(`POST`,`/api/v1/projects/${n.id}/assets/upload`),l.upload.onprogress=e=>{e.lengthComputable&&y(e.loaded/e.total*100)},l.onerror=()=>{S(`Не удалось загрузить файл. Проверьте подключение к локальному серверу.`),_(!1)},l.onload=()=>{(async()=>{try{let e=JSON.parse(l.responseText);if(l.status<200||l.status>=300)throw Error(e.message??`Ошибка импорта`);await r(),t(!1),a(null)}catch(e){S(T(e))}finally{_(!1)}})()},l.send(s)},className:`project-form`,children:[(0,P.jsxs)(`label`,{children:[`Файл`,(0,P.jsx)(`input`,{type:`file`,required:!0,onChange:e=>a(e.target.files?.[0]??null)}),(0,P.jsx)(`small`,{children:`Архив ZIP или отдельный ресурс, до 512 МБ.`})]}),(0,P.jsxs)(`label`,{children:[`Ссылка на источник`,(0,P.jsx)(`input`,{type:`url`,value:o,onChange:e=>s(e.target.value),placeholder:`https://…`})]}),(0,P.jsxs)(`div`,{className:`form-columns`,children:[(0,P.jsxs)(`label`,{children:[`Автор`,(0,P.jsx)(`input`,{value:m,onChange:e=>h(e.target.value)})]}),(0,P.jsxs)(`label`,{children:[`Лицензия`,(0,P.jsx)(`input`,{required:!0,value:c,onChange:e=>f(e.target.value),placeholder:`Например, CC0-1.0`})]})]}),g&&(0,P.jsx)(d,{label:v===100?`Распаковываем и импортируем`:`Загружаем файл`,value:v===100?void 0:v}),b&&(0,P.jsx)(p,{children:b}),(0,P.jsxs)(`div`,{className:`modal-actions`,children:[(0,P.jsx)(u,{type:`button`,disabled:g,onClick:()=>t(!1),children:`Отмена`}),(0,P.jsxs)(u,{tone:`primary`,type:`submit`,busy:g,disabled:!i,children:[(0,P.jsx)(x,{size:16}),`Импортировать`]})]})]})})}function ie({project:e}){let[t,n]=(0,A.useState)([]),[r,i]=(0,A.useState)([]),[a,s]=(0,A.useState)(!0),[l,f]=(0,A.useState)(!1),[m,h]=(0,A.useState)(``),[g,_]=(0,A.useState)(``);(0,A.useEffect)(()=>{let t=!0;return s(!0),Promise.all([k(e?`/extensions?projectId=${encodeURIComponent(e.id)}`:`/extensions`),e?k(`/projects/${e.id}`):Promise.resolve(null)]).then(([e,r])=>{t&&(n(e),i(r?.extensions??[]))}).catch(e=>{t&&h(T(e))}).finally(()=>{t&&s(!1)}),()=>{t=!1}},[e?.id]);let v=async t=>{if(e){f(!0),h(``);try{i(await k(`/projects/${e.id}/extensions/install`,`POST`,t?{ids:[t]}:{})),_(`Рекомендованные навыки установлены в проект.`)}catch(e){h(T(e))}finally{f(!1)}}};return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(c,{title:`Нужные навыки под рукой`,description:`Инструкции и инструменты, которые помогают агенту создавать вашу игру.`,action:(0,P.jsxs)(u,{tone:`primary`,disabled:!e,busy:l,onClick:()=>void v(),children:[(0,P.jsx)(D,{size:17}),`Подключить рекомендованные`]})}),m&&(0,P.jsx)(p,{children:m}),g&&(0,P.jsx)(p,{type:`success`,children:g}),(a||l)&&(0,P.jsx)(d,{label:l?`Устанавливаем навыки в проект`:`Загружаем каталог расширений`}),!e&&(0,P.jsx)(p,{type:`info`,children:`Создайте проект, чтобы автоматически подобрать навыки под движок и размерность.`}),(0,P.jsxs)(`div`,{className:`extension-intro`,children:[(0,P.jsx)(b,{size:24}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h3`,{children:`Подбор по вашему проекту`}),(0,P.jsxs)(`p`,{children:[`Базовые навыки `,e?e.engine===`html5`?`HTML5`:e.engine===`godot`?`Godot`:e.engine:`выбранного движка`,` устанавливаются при создании проекта. Версии и источники сохраняются локально.`]})]})]}),[`skill`,`mcp`,`plugin`].map(n=>{let i=t.filter(e=>e.type===n);return(0,P.jsxs)(`section`,{className:`extension-section`,children:[(0,P.jsxs)(`div`,{className:`section-label`,children:[(0,P.jsx)(`h2`,{children:{skill:`Навыки агента`,mcp:`MCP-инструменты`,plugin:`Плагины редактора`}[n]}),(0,P.jsx)(`span`,{children:i.length})]}),i.length?(0,P.jsx)(`div`,{className:`extension-list`,children:i.map(t=>(0,P.jsxs)(`article`,{className:`extension-row`,children:[(0,P.jsx)(`div`,{className:`extension-icon`,children:n===`skill`?(0,P.jsx)(z,{}):(0,P.jsx)(D,{size:22})}),(0,P.jsxs)(`div`,{children:[(0,P.jsxs)(`div`,{className:`extension-title`,children:[(0,P.jsx)(`h3`,{children:t.name}),(0,P.jsxs)(`span`,{className:`mono muted`,children:[`v`,t.version]})]}),(0,P.jsx)(`p`,{children:t.description}),/^https?:\/\//.test(t.source)?(0,P.jsxs)(`a`,{href:t.source,target:`_blank`,rel:`noreferrer`,children:[`Источник`,(0,P.jsx)(o,{size:12})]}):(0,P.jsx)(`span`,{className:`license-text`,children:t.source}),t.reference&&(0,P.jsxs)(`a`,{className:`extension-reference`,href:t.reference,target:`_blank`,rel:`noreferrer`,children:[`Документация`,(0,P.jsx)(o,{size:12})]}),(0,P.jsx)(`span`,{className:`license-text`,children:t.license})]}),r.some(e=>e.id===t.id)?(0,P.jsxs)(`span`,{className:`badge badge-success`,children:[(0,P.jsx)(O,{size:14}),`Подключён`]}):(0,P.jsx)(u,{disabled:!e||l,onClick:()=>void v(t.id),children:`Подключить`})]},t.id))}):(0,P.jsx)(`p`,{className:`section-empty`,children:n===`plugin`?`Плагины редактора подключаются, когда этого требует проект.`:`Инструменты ассетов доступны агенту во время разработки.`})]},n)})]})}function z(){return(0,P.jsx)(b,{size:22})}function ae({settings:e,onSave:t,project:n,onProjectChange:r}){let[a,o]=(0,A.useState)(e),[l,f]=(0,A.useState)(!1),[m,g]=(0,A.useState)(!1),[_,v]=(0,A.useState)(!1),[y,b]=(0,A.useState)(null),[x,E]=(0,A.useState)(``),[j,M]=(0,A.useState)(``);(0,A.useEffect)(()=>o(e),[e]);let N=async()=>{if(!(l||m)){E(``),M(``),g(!0);try{let e=(await k(`/dialogs/directory`,`POST`,{})).path;e!==null&&o(t=>({...t,projectsDirectory:e}))}catch(e){E(T(e))}finally{g(!1)}}},F=async e=>{if(e.preventDefault(),!(l||m)){f(!0),E(``),M(``);try{let e={...a,agents:Object.fromEntries(Object.entries(a.agents).map(([e,t])=>[e,{...t,executable:t.executable?.trim()||e,model:t.model?.trim()??``,...e===`codex`?{reasoningEffort:t.reasoningEffort?.trim()||`medium`}:{}}]))};t(await k(`/settings`,`PUT`,e)),M(`Настройки сохранены.`)}catch(e){E(T(e))}finally{f(!1)}}},I=async()=>{v(!0),E(``);try{b(await k(`/diagnostics`))}catch(e){E(T(e))}finally{v(!1)}};return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(c,{title:`Подключения и рабочая среда`,description:`Подключения, рабочая среда и внешний вид мастерской.`}),x&&(0,P.jsx)(p,{children:x}),j&&(0,P.jsx)(p,{type:`success`,children:j}),(0,P.jsx)(te,{}),(0,P.jsxs)(`form`,{onSubmit:F,className:`settings-form`,children:[(0,P.jsxs)(`section`,{className:`settings-section`,children:[(0,P.jsxs)(`div`,{className:`settings-description`,children:[(0,P.jsx)(`h2`,{children:`Внешний вид`}),(0,P.jsx)(`p`,{children:`Выберите комфортную тему.`})]}),(0,P.jsxs)(`div`,{className:`settings-fields`,children:[(0,P.jsxs)(`label`,{children:[`Тема`,(0,P.jsxs)(`select`,{"data-testid":`theme-select`,value:a.theme,onChange:e=>o(t=>({...t,theme:e.target.value})),children:[(0,P.jsx)(`option`,{value:`system`,children:`Как в системе`}),(0,P.jsx)(`option`,{value:`light`,children:`Светлая`}),(0,P.jsx)(`option`,{value:`dark`,children:`Тёмная`})]})]}),(0,P.jsxs)(`label`,{children:[`Интерфейс`,(0,P.jsxs)(`select`,{"data-testid":`interface-select`,value:a.interfaceMode??`robot`,onChange:e=>o(t=>({...t,interfaceMode:e.target.value})),children:[(0,P.jsx)(`option`,{value:`robot`,children:`Робот-помощник (для детей)`}),(0,P.jsx)(`option`,{value:`road`,children:`Дорожка (для детей)`})]})]})]})]}),(0,P.jsxs)(`section`,{className:`settings-section`,children:[(0,P.jsxs)(`div`,{className:`settings-description`,children:[(0,P.jsx)(`h2`,{children:`Разрешения агента`}),(0,P.jsx)(`p`,{children:`Команды и инструменты во время работы над игрой.`})]}),(0,P.jsxs)(`div`,{className:`settings-fields`,children:[(0,P.jsxs)(`label`,{className:`agent-permission-setting`,children:[(0,P.jsx)(`input`,{type:`checkbox`,"data-testid":`auto-approve-actions`,checked:a.autoApproveActions===!0,disabled:e.autoApproveActions===void 0||l,onChange:e=>o(t=>({...t,autoApproveActions:e.target.checked}))}),(0,P.jsx)(`span`,{children:`Автоматически разрешать действия агента`})]}),(0,P.jsx)(`small`,{"data-testid":`agent-permission-mode`,children:e.autoApproveActions===void 0?`Настройка появится после обновления запущенного сервера.`:a.autoApproveActions?`Разрешения агента: автоматически`:`Разрешения агента: запрашивать`}),(0,P.jsxs)(`p`,{className:`settings-permission-hint`,children:[e.autoApproveActions===void 0?`Режим разрешений определяется запущенным сервером.`:a.autoApproveActions?`Команды и инструменты разрешаются без отдельного подтверждения.`:`Команды и инструменты требуют вашего подтверждения.`,` На вопросы об игре вы отвечаете сами. Изменение применяется после сохранения настроек.`]})]})]}),(0,P.jsxs)(`section`,{className:`settings-section`,children:[(0,P.jsxs)(`div`,{className:`settings-description`,children:[(0,P.jsx)(`h2`,{children:`Рабочая среда`}),(0,P.jsx)(`p`,{children:`Редактор и папка для новых проектов.`})]}),(0,P.jsxs)(`div`,{className:`settings-fields`,children:[(0,P.jsxs)(`label`,{children:[`Путь к Godot`,(0,P.jsx)(`input`,{value:a.godotPath??``,onChange:e=>o(t=>({...t,godotPath:e.target.value})),placeholder:`Автоматическое обнаружение`})]}),n?.engine===`roblox`&&(0,P.jsx)(ee,{project:n}),(0,P.jsxs)(`details`,{children:[(0,P.jsx)(`summary`,{children:`Дополнительные пути Roblox Studio`}),[[`robloxStudioPath`,`Путь к Roblox Studio`],[`robloxMcpPath`,`Путь к StudioMCP`]].map(([e,t])=>(0,P.jsxs)(`label`,{children:[t,(0,P.jsx)(`input`,{value:a[e]??``,onChange:t=>o(n=>({...n,[e]:t.target.value})),placeholder:`Автоматическое обнаружение`})]},e)),(0,P.jsx)(`small`,{children:`Studio ID определяется по идентификатору проекта автоматически. Сохраните изменённые пути перед проверкой подключения.`})]}),(0,P.jsxs)(`div`,{className:`directory-picker-field`,children:[(0,P.jsx)(`label`,{htmlFor:`settings-projects-directory`,children:`Папка проектов`}),(0,P.jsxs)(`div`,{className:`directory-picker-row`,children:[(0,P.jsx)(`input`,{id:`settings-projects-directory`,"data-testid":`settings-projects-directory`,readOnly:!0,value:a.projectsDirectory??``,title:a.projectsDirectory||void 0,placeholder:`Папка ещё не выбрана`,"aria-describedby":`settings-directory-hint`}),(0,P.jsxs)(u,{type:`button`,"data-testid":`choose-settings-directory`,busy:m,disabled:l||m,onClick:()=>void N(),children:[(0,P.jsx)(h,{size:18}),`Выбрать папку`]})]}),(0,P.jsx)(`small`,{id:`settings-directory-hint`,children:`Выберите папку в системном окне, затем сохраните настройки.`}),m&&(0,P.jsx)(d,{label:`Ожидаем выбор папки в системном окне`})]})]})]}),(0,P.jsx)(`div`,{className:`settings-actions`,children:(0,P.jsxs)(u,{tone:`primary`,type:`submit`,busy:l,disabled:m,children:[(0,P.jsx)(O,{size:17}),`Сохранить настройки`]})})]}),(0,P.jsxs)(`section`,{className:`diagnostics-section`,children:[(0,P.jsxs)(`div`,{className:`row-between`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h2`,{children:`Проверка подключений`}),(0,P.jsx)(`p`,{children:`Проверяются сохранённые пути и доступность инструментов.`})]}),(0,P.jsxs)(u,{busy:_,onClick:()=>void I(),children:[(0,P.jsx)(i,{size:17}),`Проверить`]})]}),_&&(0,P.jsx)(d,{label:`Проверяем локальные CLI и движки`}),y&&(0,P.jsxs)(`div`,{className:`diagnostics-list`,children:[y.agents.map(e=>{let t=e.available&&e.protocol!==`failed`&&e.authentication!==`required`,n=e.available?e.protocol===`failed`?`Ошибка протокола`:e.authentication===`required`?`Нужен вход`:e.authentication===`ready`?`Готов`:`Ядро подключено`:`Не найден`;return(0,P.jsxs)(`div`,{className:`diagnostic-row`,children:[t?(0,P.jsx)(s,{size:20,className:`success-text`}):(0,P.jsx)(S,{size:20,className:`warning-text`}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:C[e.id]}),(0,P.jsx)(`small`,{children:e.error||(e.available?[e.version,e.authentication===`unknown`?`Авторизация проверяется при первом запросе.`:``].filter(Boolean).join(` · `):`Подключите аккаунт UMGT и повторите проверку.`)})]}),(0,P.jsx)(`span`,{className:`badge ${t?`badge-success`:``}`,children:n})]},e.id)}),y.roblox&&(0,P.jsxs)(`article`,{className:`diagnostic-item`,children:[(0,P.jsx)(w,{size:22}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Roblox Studio`}),(0,P.jsx)(`small`,{children:y.roblox.executable??y.roblox.message}),(0,P.jsx)(`small`,{children:y.roblox.available?y.roblox.message:``})]}),(0,P.jsx)(`span`,{className:`badge ${y.roblox.available?`badge-success`:``}`,children:y.roblox.available?`Найдена`:`Недоступна`})]}),y.robloxMcp&&(0,P.jsxs)(`article`,{className:`diagnostic-item`,children:[(0,P.jsx)(D,{size:22}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Studio MCP`}),(0,P.jsx)(`small`,{children:y.robloxMcp.message})]}),(0,P.jsx)(`span`,{className:`badge ${y.robloxMcp.available?`badge-success`:``}`,children:y.robloxMcp.available?`Отвечает`:`Не подключён`})]}),y.godot&&(0,P.jsxs)(`div`,{className:`diagnostic-row`,children:[y.godot.available?(0,P.jsx)(s,{size:20,className:`success-text`}):(0,P.jsx)(S,{size:20,className:`warning-text`}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`strong`,{children:`Godot`}),(0,P.jsx)(`small`,{children:y.godot.version??y.godot.error??y.godot.message??`Укажите путь к редактору.`}),y.godot.available&&y.godot.message&&(0,P.jsx)(`small`,{children:y.godot.message})]}),(0,P.jsx)(`span`,{className:`badge ${y.godot.available?`badge-success`:``}`,children:y.godot.available?`Найден`:`Недоступен`})]})]})]})]})}export{R as AssetsView,ie as ExtensionsView,ae as SettingsView};