@weppy/roblox-mcp 2.12.2 → 2.12.3

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.
package/CHANGELOG.md CHANGED
@@ -24,6 +24,13 @@ All notable changes to this project will be documented in this file.
24
24
 
25
25
 
26
26
 
27
+
28
+
29
+ ## [2.12.3] - 2026-08-12
30
+
31
+ ### Bug Fixes
32
+
33
+ - **Correct spatial results for rotated objects** — `bounds`, `spatial_map`, `collision`, and `find_space` now include each object's rotation and all descendant parts when calculating world-space bounds. AI agents will no longer overlook collisions or blocked space around rotated parts, models, and folders. No tool schema or configuration changes are required.
27
34
 
28
35
  ## [2.12.2] - 2026-08-10
29
36
 
package/dist/index.js CHANGED
@@ -527,7 +527,7 @@ Used by: toggle_ui_preview (optional).
527
527
  ${k5}
528
528
  `:`${k5}
529
529
  `}async function nve(t,e){let n=`${t}.${process.pid}.${Date.now()}.tmp`;await dm.mkdir(R5.dirname(t),{recursive:!0});try{await dm.writeFile(n,e,"utf8"),await dm.rename(n,t)}finally{await dm.rm(n,{force:!0})}}function E5(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}Lr();Gf();import{createHash as rve}from"crypto";import Nt from"path";import{promises as Wr}from"fs";$s();var ive={readFile:t=>Wr.readFile(t),writeFileAtomic:async(t,e)=>{await vn(t,typeof e=="string"?e:e.toString("utf8"))},copyFile:async(t,e)=>{await Wr.mkdir(Nt.dirname(e),{recursive:!0}),await Wr.copyFile(t,e)},unlink:async t=>{await Wr.unlink(t)},mkdir:async t=>{await Wr.mkdir(t,{recursive:!0})}},ia=class extends Error{constructor(n,r,i=r){super(i);this.statusCode=n;this.code=r;this.name="SyncMigrationError"}},B_=class{constructor(e,n=ive){this.ctx=e;this.fileOps=n}async preview(e){let{operations:n,...r}=await this.buildPlan(e);return{...r,generatedAt:new Date().toISOString()}}async apply(e){let n=await this.buildPlan(e.placeId);if(n.previewFingerprint!==e.previewFingerprint)throw new ia(409,"preview_stale");if(n.status==="blocked")throw new ia(409,"migration_blocked");if(n.status==="not_required")return this.preview(e.placeId);let r=this.ctx.places.get(e.placeId);if(!r)throw new ia(404,"place_not_found");let i=this.ctx.config.getSyncRoot(),a=Nt.dirname(r.index.getExplorerRoot()),o=Nt.join(a,".sync-index.json"),s=Nt.join(a,".sync-meta.json"),c=Nt.join(a,".sync-migration-backups",`v2-to-v3-${n.previewFingerprint}`),l=await this.captureOriginals(i,n.changes,o,s),u={studioHashes:r.index.getAllHashes(),fileHashes:r.index.getAllFileHashes()},d=await D5(r.index.getExplorerRoot());await this.writeBackup(i,c,l),r.fileWatcher?.beginFullSyncReplacement();try{await this.applyOperations(i,r,n,l),await this.assertUserSourcesUnchanged(r.index.getExplorerRoot(),d);let p={version:1,syncFormatVersion:Ot,placeId:r.placeId,placeName:r.placeName,lastFullSync:r.lastFullSync??null,lastIncrementalSync:r.lastIncrementalSync??null,instanceCount:r.instanceCount??0,scriptCount:r.scriptCount??0,syncMode:"mirror"};await this.fileOps.writeFileAtomic(s,JSON.stringify(p,null,2)+`
530
- `),r.index.setFormatVersion(Ot);let f=As(r.index.toSyncIndexData());return await this.fileOps.writeFileAtomic(o,f),r.formatVersion=Ot,r.writer.setFormatVersion(Ot),await r.fileWatcher?.endFullSyncReplacement(),this.preview(e.placeId)}catch(p){throw await this.rollback(l,c,r,u),p}}async buildPlan(e){let n=this.ctx.places.get(e);if(!n)throw new ia(404,"place_not_found");let r=this.ctx.config.getSyncRoot(),i=Nt.dirname(n.index.getExplorerRoot()),a=n.index.getExplorerRoot();if(n.formatVersion!==gt){let _=$5(As({blockers:[],changes:[],fromVersion:gt,placeId:e,toVersion:Ot}));return{placeId:e,fromVersion:gt,toVersion:Ot,status:"not_required",previewFingerprint:_,userSourceModified:0,summary:{add:0,modify:0,delete:0,blocked:0},changes:[],blockers:[],operations:new Map}}let s=await ave(r,a),c=new Set(s.map(_=>_.absolutePath)),l=[],u=new Map;for(let _ of s){let x=await ove(_,c);x&&(l.push(x.change),u.set(x.change.path,x.after))}let d=await this.planManagedIgnore(r);d&&(l.push(d.change),u.set(d.change.path,d.after)),l.sort(lve);let p=await this.collectBlockers(r,n);p.sort(uve);let f=Nt.join(i,".sync-index.json"),m=await this.readFileOrNull(f),g=[...n.index.getAllFileHashes().keys()].map(_=>{let x=q_(r,_);if(Us(x)!=="canonical_mirror")return null;let I=n.index.getHashPair(_);return{path:x,fileHash:I.fileHash??null,studioHash:I.studioHash??null}}).filter(_=>_!==null).sort((_,x)=>_.path.localeCompare(x.path)),h=$5(As({blockers:p,changes:l,fromVersion:gt,indexHash:m?Ws(m):null,indexState:g,placeId:e,toVersion:Ot})),v={add:l.filter(_=>_.operation==="add").length,modify:l.filter(_=>_.operation==="modify").length,delete:l.filter(_=>_.operation==="delete").length,blocked:p.length};return{placeId:e,fromVersion:gt,toVersion:Ot,status:p.length>0?"blocked":"ready",previewFingerprint:h,userSourceModified:0,summary:v,changes:l,blockers:p,operations:u}}async planManagedIgnore(e){let n=Nt.join(e,".gitignore"),r=await this.readFileOrNull(n),i=r?.toString("utf8")??"",a=Buffer.from(SA(i),"utf8");return r?.equals(a)?null:{change:{path:".gitignore",ownership:"generated",operation:r===null?"add":"modify",reason:"runtime_ignore_policy",...r!==null?{beforeHash:Ws(r)}:{},afterHash:Ws(a)},after:a}}async readFileOrNull(e){return this.fileOps.readFile(e).catch(n=>{if(n.code==="ENOENT")return null;throw n})}async captureOriginals(e,n,r,i){let a=[];for(let o of n){let s=Nt.resolve(e,o.path);a.push({absolutePath:s,content:await this.readFileOrNull(s)})}return a.push({absolutePath:r,content:await this.readFileOrNull(r)}),a.push({absolutePath:i,content:await this.readFileOrNull(i)}),a}async writeBackup(e,n,r){await this.fileOps.mkdir(n);for(let i of r){if(i.content===null)continue;let a=q_(e,i.absolutePath);await this.fileOps.copyFile(i.absolutePath,Nt.join(n,"files",a))}}async applyOperations(e,n,r,i){let a=new Map(i.map(o=>[o.absolutePath,o.content]));for(let o of r.changes){let s=Nt.resolve(e,o.path),c=r.operations.get(o.path);if(c===void 0)throw new Error(`Missing migration operation content: ${o.path}`);if(n.fileWatcher?.suppressPath(s,c===null?"missing":n.index.computeHash(c.toString("utf8"))),c===null?await this.fileOps.unlink(s):await this.fileOps.writeFileAtomic(s,c),o.ownership!=="canonical_mirror")continue;if(c===null){n.index.removeHash(s);continue}let l=a.get(s);(l?n.index.getFileStatus(s,n.index.computeHash(l.toString("utf8"))):"synced")==="studio-modified"?n.index.updateFileHash(s,c.toString("utf8")):n.index.updateBothHashes(s,c.toString("utf8"))}}async assertUserSourcesUnchanged(e,n){let r=await D5(e);if(!pve(n,r))throw new ia(409,"source_mutation_detected")}async rollback(e,n,r,i){let a;for(let o of[...e].reverse())try{o.content===null?await this.fileOps.unlink(o.absolutePath).catch(s=>{if(s.code!=="ENOENT")throw s}):await this.fileOps.writeFileAtomic(o.absolutePath,o.content)}catch(s){a??=s}r.index.clearAllHashes();for(let[o,s]of i.studioHashes)r.index.updateHashByValue(o,s);for(let[o,s]of i.fileHashes)r.index.updateFileHashByValue(o,s);if(r.index.setFormatVersion(gt),r.formatVersion=gt,r.writer.setFormatVersion(gt),await Wr.rm(n,{recursive:!0,force:!0}),await r.fileWatcher?.endFullSyncReplacement(),a)throw a}async collectBlockers(e,n){let r=[];(n.fileWatcher?.getPendingCount()??0)>0&&r.push({reason:"reverse_pending"});for(let i of n.index.getAllFileHashes().keys()){let a=q_(e,i);if(Us(a)!=="canonical_mirror")continue;let o=await cve(i);if(o===null){r.push({path:a,reason:"local_canonical_change"});continue}let s=n.index.getFileStatus(i,n.index.computeHash(o.toString("utf8")));s==="conflict"?r.push({path:a,reason:"conflict"}):s==="file-modified"&&r.push({path:a,reason:"local_canonical_change"})}return dve(r)}};async function ave(t,e){let n=[];async function r(i){let a=await Wr.readdir(i,{withFileTypes:!0}).catch(o=>{if(o.code==="ENOENT")return[];throw o});for(let o of a){let s=Nt.join(i,o.name);if(o.isDirectory()){await r(s);continue}sve(o.name)&&n.push({absolutePath:s,relativePath:q_(t,s),content:await Wr.readFile(s)})}}return await r(e),n.sort((i,a)=>i.relativePath.localeCompare(a.relativePath))}async function ove(t,e){let n=JSON.parse(t.content.toString("utf8")),r=Ws(t.content);if(t.absolutePath.endsWith(".props.json")){let o=n,s=t.absolutePath.replace(/\.props\.json$/,".value.json");if(hA(o,e.has(s)))return{change:{path:t.relativePath,ownership:"canonical_mirror",operation:"delete",reason:"redundant_empty_metadata",beforeHash:r},after:null}}let i="serializer_regeneration";Nt.basename(t.absolutePath)==="_tree.json"&&n!==null&&typeof n=="object"&&!Array.isArray(n)&&Object.prototype.hasOwnProperty.call(n,"syncedAt")&&(delete n.syncedAt,i="volatile_metadata_removal");let a=Buffer.from(As(n),"utf8");return t.content.equals(a)?null:{change:{path:t.relativePath,ownership:"canonical_mirror",operation:"modify",reason:i,beforeHash:r,afterHash:Ws(a)},after:a}}function sve(t){return t==="_tree.json"||t.endsWith(".props.json")||t.endsWith(".value.json")}function q_(t,e){return Nt.relative(t,e).replaceAll(Nt.sep,"/")}function Ws(t){return rve("sha256").update(t).digest("hex")}function $5(t){return Ws(Buffer.from(t,"utf8"))}function cve(t){return Wr.readFile(t).catch(e=>{if(e.code==="ENOENT")return null;throw e})}function lve(t,e){return t.path.localeCompare(e.path)||t.operation.localeCompare(e.operation)||t.reason.localeCompare(e.reason)}function uve(t,e){return(t.path??"").localeCompare(e.path??"")||t.reason.localeCompare(e.reason)}function dve(t){let e=new Set;return t.filter(n=>{let r=`${n.path??""}\0${n.reason}`;return e.has(r)?!1:(e.add(r),!0)})}async function D5(t){let e=new Map;async function n(r){let i=await Wr.readdir(r,{withFileTypes:!0}).catch(a=>{if(a.code==="ENOENT")return[];throw a});for(let a of i){let o=Nt.join(r,a.name);a.isDirectory()?await n(o):(a.name.endsWith(".server.luau")||a.name.endsWith(".client.luau")||a.name.endsWith(".module.luau"))&&e.set(Nt.relative(t,o).replaceAll(Nt.sep,"/"),Ws(await Wr.readFile(o)))}}return await n(t),e}function pve(t,e){if(t.size!==e.size)return!1;for(let[n,r]of t)if(e.get(n)!==r)return!1;return!0}Lr();oe();var fve=5;function N5(t){if(!t||typeof t!="object")return;let e=t;if(Array.isArray(e.instances))for(let n of e.instances)Array.isArray(n.properties)&&n.properties.length===0&&(n.properties={}),Array.isArray(n.attributes)&&n.attributes.length===0&&(n.attributes={});if(Array.isArray(e.changes))for(let n of e.changes)Array.isArray(n.properties)&&n.properties.length===0&&(n.properties={}),Array.isArray(n.attributes)&&n.attributes.length===0&&(n.attributes={})}function mve(t){return t.type==="instanceAdded"||t.type==="instanceRemoved"||t.type==="instanceRenamed"||t.type==="instanceMoved"||t.type==="scriptSourceChanged"}var _i=class{config;places;apiHandler;changeProcessor;initHandler;reverseHandler;migrationService;reverseDetectorFactory;placeDisposals=new Map;activeFullSyncPlaceId=null;activeRuntimeSyncPlaceId=null;currentConnectedPlaceId=null;currentConnectedPlaceName=null;constructor(e,n={}){this.config=new Wx(e,n),this.reverseDetectorFactory=n.reverseDetectorFactory??(r=>new $_(r.explorerRoot,r.syncIndex,{placeId:r.placeId})),this.apiHandler=new L_(this),this.changeProcessor=new M_(this),this.initHandler=new z_(this),this.reverseHandler=new F_(this),this.places=new T_({max:fve,dispose:(r,i)=>{this.trackPlaceDisposal(r,i)}}),this.migrationService=new B_(this)}getSyncRoot(){return this.config.getSyncRoot()}async getOrCreatePlaceContext(e,n){let r=this.places.get(e);if(r&&n){let i=this.config.getPlaceRoot(e),a=await this.config.resolvePlaceRoot(e,n);a!==i&&(y.info("Place root migrated, recreating context",{placeId:e,from:i,to:a}),this.places.delete(e),r=void 0)}if(!r){await this.waitForPlaceDisposal(e);let i=await this.config.resolvePlaceRoot(e,n),a=wA.join(i,"explorer"),o=await WB(i),s=o.formatVersion;o.recovery&&y.warn("Recovered corrupt sync index",{indexPath:o.recovery.indexPath,quarantinePath:o.recovery.quarantinePath,formatVersion:o.recovery.formatVersion,reason:o.recovery.reason}),await IA.mkdir(i,{recursive:!0}),await IA.mkdir(a,{recursive:!0});let c=new hu(i,a,s);await c.loadFromDisk();let l=new yu(this.config,c,e,s),u=new O_(this.config,c,i);if(l.startChangeLogFlusher(),r={placeId:e,placeName:"",formatVersion:s,pendingIndexRecovery:o.recovery??null,index:c,writer:l,reader:u,fileWatcher:null,state:"idle",activeClientId:null,activeFullSyncSessionId:null,instanceCount:0,scriptCount:0,lastFullSync:null,lastIncrementalSync:null,tmpIndex:null,tmpWriter:null,incompleteSyncTimer:null,syncInitRequestsInFlight:0,changesSinceLastSave:0,directions:{...Rs},applyModes:{...Ts},autoApplyDeletes:!1,forwardRestoreQueue:[],syncProgress:null,collisionDirMap:null,activeSyncIdentityScope:null},this.places.set(e,r),r.pendingIndexRecovery){let d=r.pendingIndexRecovery;l.appendHistory({timestamp:new Date().toISOString(),type:"indexRecovery",direction:"forward",source:"studio",path:d.indexPath,details:JSON.stringify({quarantinePath:d.quarantinePath,formatVersion:d.formatVersion,reason:d.reason})}),await l.flushHistory(),r.pendingIndexRecovery=null}y.info("Created new place context",{placeId:e,placeRoot:i})}return r}async handleSyncInit(e,n){try{N5(e.body);let r=C5(e.body);if(!r.success){n.status(400).json({error:"Validation error",message:r.error});return}let i=r.data,a=i.phase==="start"?i.placeId??null:i.phase==="chunk"||i.phase==="complete"?this.activeFullSyncPlaceId:null;if(a==null){n.status(400).json({error:"Missing placeId",message:"placeId is required in start phase or must be set by previous start"});return}switch(i.phase){case"start":this.setCurrentConnectedPlace(a,i.placeName),await this.initHandler.handleInitStart(a,i,n);break;case"chunk":await this.initHandler.handleInitChunk(a,i,n);break;case"complete":await this.initHandler.handleInitComplete(a,i,n);break}}catch(r){this.sendError(n,r,"handleSyncInit")}}async handleSyncUpdate(e,n){try{N5(e.body);let r=P5(e.body);if(!r.success){n.status(400).json({error:"Validation error",message:r.error});return}let i=r.data,a=i.placeId??this.getDefaultRuntimePlaceId();if(a==null){n.status(400).json({error:"Missing placeId",message:"placeId is required in body or must have an active sync session"});return}let o=await this.getOrCreatePlaceContext(a);if(this.setCurrentConnectedPlace(a,o.placeName||this.currentConnectedPlaceName),o.activeFullSyncSessionId!==null||o.state==="initializing"){n.status(409).json({error:"Conflict",message:`Full sync in progress for place ${a}`});return}o.activeClientId=i.clientId,this.touchRuntimePlace(a);let s=S5(o,i.changes);y.info("Sync update received",{placeId:a,clientId:i.clientId,changeCount:s.length,receivedCount:i.changes.length,types:s.map(m=>m.type)});let c=[],l=[],u=0,d=!1,p=new Map;for(let m of s)try{let g=await this.changeProcessor.processChangeForPlace(o,m,p);g?l.push(g):(u++,mve(m)&&(d=!0))}catch(g){let h="path"in m?m.path:"oldPath"in m?m.oldPath:"unknown";c.push({path:h,error:g instanceof Error?g.message:String(g)})}for(let m of p.values())try{await D_(o,m)}catch(g){c.push({path:m.instancePath,error:g instanceof Error?g.message:String(g)})}if(d)try{let m=this.config.getSyncRoot(),g=this.config.getPlaceRoot(a);await Qx(m,g,o.formatVersion,o.writer),await eu(m,o.writer)}catch(m){y.warn("Failed to refresh sourcemaps after incremental sync update",{placeId:a,error:m instanceof Error?m.message:String(m)})}o.changesSinceLastSave+=u,o.changesSinceLastSave>=I5&&(await o.index.saveToDisk(),o.changesSinceLastSave=0),o.lastIncrementalSync=new Date().toISOString();let f={processed:u,failed:c.length,errors:c,syncedAt:o.lastIncrementalSync};l.length>0&&(f.conflicts=l),n.status(200).json(f)}catch(r){this.sendError(n,r,"handleSyncUpdate")}}getDefaultRuntimePlaceId(){return this.currentConnectedPlaceId}getDefaultRuntimePlaceName(){if(this.currentConnectedPlaceName)return this.currentConnectedPlaceName;if(this.currentConnectedPlaceId!==null&&this.currentConnectedPlaceId!==void 0){let e=this.places.get(this.currentConnectedPlaceId);if(e?.placeName)return e.placeName}return null}setCurrentConnectedPlace(e,n){if(this.currentConnectedPlaceId=e,e==null){this.currentConnectedPlaceName=null;return}if(typeof n=="string"&&n.length>0){this.currentConnectedPlaceName=n;let i=this.places.get(e);i&&(i.placeName=n);return}let r=this.places.get(e);r?.placeName&&(this.currentConnectedPlaceName=r.placeName)}clearCurrentConnectedPlaceIfMatch(e){this.currentConnectedPlaceId===e&&(this.currentConnectedPlaceId=null,this.currentConnectedPlaceName=null)}touchRuntimePlace(e){this.activeRuntimeSyncPlaceId=e}clearRuntimePlaceIfMatch(e){this.activeRuntimeSyncPlaceId===e&&(this.activeRuntimeSyncPlaceId=null)}resolveQueryPlaceId(e,n="runtime"){let r=e.query.placeId;if(r){let i=parseInt(r,10);if(!isNaN(i))return i}return n==="full"?this.activeFullSyncPlaceId:this.getDefaultRuntimePlaceId()}async handleSyncStatus(e,n){try{let r=u=>({state:"idle",instanceCount:0,scriptCount:0,lastFullSync:null,lastIncrementalSync:null,syncRoot:u,activeClientId:null,reverseSyncAvailable:!1,modifiedFileCount:0,autoApplyDeletes:!1,reverseDetectorActive:!1,reverseDetectorMode:_t,fileWatcherActive:!1}),i=this.resolveQueryPlaceId(e);if(i==null){let u=r(this.config.getSyncRoot());n.status(200).json(u);return}let a=this.places.get(i);if(!a){let u=r(this.config.getPlaceRoot(i));n.status(200).json(u);return}let o=a.fileWatcher?.getPendingCount()??0,s=a.fileWatcher?.isActivelyScanning()??!1,c=a.fileWatcher!==null;this.touchRuntimePlace(i);let l={state:a.state,instanceCount:a.instanceCount,scriptCount:a.scriptCount,lastFullSync:a.lastFullSync,lastIncrementalSync:a.lastIncrementalSync,syncRoot:this.config.getPlaceRoot(i),activeClientId:a.activeClientId,reverseSyncAvailable:o>0,modifiedFileCount:o,applyModes:a.applyModes,autoApplyDeletes:a.autoApplyDeletes,directions:a.directions,reverseDetectorActive:s,reverseDetectorMode:_t,fileWatcherActive:c,forwardOnlyClasses:[...Ql]};n.status(200).json(l)}catch(r){this.sendError(n,r,"handleSyncStatus")}}async handleSyncStop(e,n){try{let r=e.body,i=r.placeId??this.getDefaultRuntimePlaceId(),a=um(r);if(y.info("handleSyncStop requested",{placeId:i,clientId:r.clientId??null,identityScope:a,reason:r.reason??"requested"}),i==null){n.status(200).json({status:"idle",state:"idle",placeId:null,message:"No active sync place"});return}let o=this.places.get(i);if(!o){y.info("handleSyncStop no place context",{placeId:i,clientId:r.clientId??null}),n.status(200).json({status:"idle",state:"idle",placeId:i,message:`No sync context for place ${i}`});return}let s=!!(r.clientId&&o.activeClientId&&r.clientId!==o.activeClientId),c=o.activeFullSyncSessionId!==null||o.state==="syncing"||o.state==="initializing",l=!!(a&&o.activeSyncIdentityScope&&a===o.activeSyncIdentityScope);if(s&&c&&!l){y.warn("handleSyncStop rejected due to active client mismatch",{placeId:i,requestedClientId:r.clientId,activeClientId:o.activeClientId,requestedIdentityScope:a,activeIdentityScope:o.activeSyncIdentityScope,state:o.state,activeFullSyncSessionId:o.activeFullSyncSessionId}),n.status(409).json({error:"Conflict",message:`This sync session belongs to client ${o.activeClientId}`});return}s&&l&&y.info("handleSyncStop accepted stale client cleanup by identity scope",{placeId:i,requestedClientId:r.clientId,activeClientId:o.activeClientId,identityScope:a,state:o.state});let u=o.activeFullSyncSessionId,d=o.state,p=o.fileWatcher!==null;if(u&&(this.initHandler.clearPreserveLocalFiles(u),this.initHandler.clearPendingServiceTrees(u)),o.fileWatcher&&(y.info("handleSyncStop suspending reverse detector",{placeId:i,state:o.state,activeClientId:o.activeClientId,mode:_t}),o.fileWatcher.beginFullSyncReplacement()),o.incompleteSyncTimer&&(clearTimeout(o.incompleteSyncTimer),o.incompleteSyncTimer=null),u){let f=this.config.getPlaceRoot(i),m=wA.join(f,`explorer_tmp_${u}`);await IA.rm(m,{recursive:!0,force:!0}).catch(()=>{})}o.tmpWriter&&(o.tmpWriter.stopChangeLogFlusher(),o.tmpWriter=null),o.tmpIndex=null,o.collisionDirMap=null,o.activeSyncIdentityScope=null,o.syncInitRequestsInFlight=0,o.activeFullSyncSessionId=null,o.syncProgress=null,o.state="idle",o.activeClientId=null,o.instanceCount=0,o.scriptCount=0,o.forwardRestoreQueue=[],this.activeFullSyncPlaceId===i&&(this.activeFullSyncPlaceId=null),this.clearRuntimePlaceIfMatch(i),y.info("handleSyncStop responding idle",{placeId:i,previousState:d,activeFullSyncSessionId:u,hadWatcher:p}),y.info("Sync stopped",{placeId:i,reason:r.reason??"requested"}),n.status(200).json({status:"stopped",state:"idle",placeId:i})}catch(r){this.sendError(n,r,"handleSyncStop")}}async initialize(){try{await this.config.loadFromMeta(),await O5(this.config.getSyncRoot()),await this.initHandler.cleanupStaleTempDirs(),y.info("SyncController initialized")}catch(e){y.error("SyncController initialization failed",e instanceof Error?e:new Error(String(e)))}}async previewMigration(e){return this.migrationService.preview(e)}async applyMigration(e){return this.migrationService.apply(e)}async shutdown(){try{y.info("SyncController shutdown: clearing place contexts",{placeCount:this.places.size}),this.places.clear(),await Promise.all(this.placeDisposals.values()),y.info("SyncController shut down")}catch(e){y.error("SyncController shutdown error",e instanceof Error?e:new Error(String(e)))}}trackPlaceDisposal(e,n){let r=this.disposePlaceContext(e,n).catch(i=>{y.error("Place context dispose failed",i instanceof Error?i:new Error(String(i)))});this.placeDisposals.set(n,r),r.then(()=>{this.placeDisposals.get(n)===r&&this.placeDisposals.delete(n)})}async waitForPlaceDisposal(e){await this.placeDisposals.get(e)}async disposePlaceContext(e,n){y.info("Disposing place context (LRU eviction)",{placeId:n}),this.activeFullSyncPlaceId===n&&(this.activeFullSyncPlaceId=null);let r=e.index.toSyncIndexData(),i=e.fileWatcher,a=e.tmpWriter;e.fileWatcher=null,e.tmpWriter=null,e.incompleteSyncTimer&&(clearTimeout(e.incompleteSyncTimer),e.incompleteSyncTimer=null),e.activeFullSyncSessionId&&this.initHandler.clearPendingServiceTrees(e.activeFullSyncSessionId),e.tmpIndex=null,e.collisionDirMap=null,e.activeSyncIdentityScope=null,e.syncInitRequestsInFlight=0;let o=[e.index.savePersistenceStateToDisk(r).catch(s=>{y.error("Error saving index during dispose",s)}),e.writer.stopChangeLogFlusher().catch(s=>{y.error("LRU dispose \uC911 changelog flush \uC2E4\uD328",s)})];i&&(y.info("Disposing place context: stopping reverse detector",{placeId:n,reason:"lru-dispose",mode:_t}),o.push(i.stop("lru-dispose").catch(s=>{y.error("Error stopping reverse detector during dispose",s)}))),a&&o.push(a.stopChangeLogFlusher().catch(s=>{y.error("LRU dispose \uC911 \uC784\uC2DC changelog flush \uC2E4\uD328",s)})),await Promise.all(o),e.index.clearAllMaps()}async atomicWriteFile(e,n){await vn(e,n)}async handlePreCheck(e,n){try{await this.apiHandler.handlePreCheck(e,n)}catch(r){this.sendError(n,r,"handlePreCheck")}}async handleSyncDirections(e,n){try{await this.apiHandler.handleSyncDirections(e,n)}catch(r){this.sendError(n,r,"handleSyncDirections")}}async handleForwardRestoreList(e,n){try{await this.apiHandler.handleForwardRestoreList(e,n)}catch(r){this.sendError(n,r,"handleForwardRestoreList")}}async handleReversePending(e,n){try{await this.reverseHandler.handleReversePending(e,n)}catch(r){this.sendError(n,r,"handleReversePending")}}async handleReverseSyncChanges(e,n){try{await this.reverseHandler.handleReverseSyncChanges(e,n)}catch(r){this.sendError(n,r,"handleReverseSyncChanges")}}async handleReverseSyncResult(e,n){try{await this.reverseHandler.handleReverseSyncResult(e,n)}catch(r){this.sendError(n,r,"handleReverseSyncResult")}}async handleResolveConflict(e,n){try{await this.reverseHandler.handleResolveConflict(e,n)}catch(r){this.sendError(n,r,"handleResolveConflict")}}async handleReverseRescan(e,n){try{await this.reverseHandler.handleReverseRescan(e,n)}catch(r){this.sendError(n,r,"handleReverseRescan")}}async handleSyncHistory(e,n){try{await this.apiHandler.handleSyncHistory(e,n)}catch(r){this.sendError(n,r,"handleSyncHistory")}}async startFileWatcherForPlace(e){if(e.state!=="syncing"){y.debug("Skipping reverse detector start - place not syncing",{placeId:e.placeId,state:e.state});return}if(e.fileWatcher){if(e.fileWatcher.isActivelyScanning()){y.info("startFileWatcherForPlace: reusing active reverse detector",{placeId:e.placeId,mode:_t});return}y.info("startFileWatcherForPlace: resuming paused reverse detector",{placeId:e.placeId,mode:_t}),e.fileWatcher.endFullSyncReplacement();return}let n=this.createReverseChangeDetector(e);this.configureReverseChangeDetector(e,n),e.fileWatcher=n,n.start().then(()=>{e.fileWatcher===n&&y.info("Reverse detector started for reverse sync",{placeId:e.placeId,mode:_t})}).catch(r=>{y.warn("Failed to start reverse detector",{placeId:e.placeId,mode:_t,error:r instanceof Error?r.message:String(r)}),e.fileWatcher===n&&(e.fileWatcher=null)})}createReverseChangeDetector(e){return this.reverseDetectorFactory({explorerRoot:wA.join(this.config.getPlaceRoot(e.placeId),"explorer"),syncIndex:e.index,placeId:e.placeId})}configureReverseChangeDetector(e,n){e.writer.setOnWriteCallback((r,i,a)=>{n.suppressPath(r,i,a)}),n.setDirectionChecker(r=>{let i=VB(r);return e.directions[i]}),n.setOnForwardViolation(r=>{e.forwardRestoreQueue.includes(r)||(e.forwardRestoreQueue.push(r),y.info("Forward violation queued for restore",{placeId:e.placeId,relativePath:r,queueSize:e.forwardRestoreQueue.length}))})}getStatusSummary(){return this.apiHandler.getStatusSummary()}getDirectionForCategory(e){return this.apiHandler.getDirectionForCategory(e)}getStatusDirect(e){return this.apiHandler.getStatusDirect(e)}async getHistoryDirect(e,n){return this.apiHandler.getHistoryDirect(e,n)}getDirectionsDirect(e){return this.apiHandler.getDirectionsDirect(e)}getProgressDirect(e){return this.apiHandler.getProgressDirect(e)}async readSyncedFile(e,n){return this.apiHandler.readSyncedFile(e,n)}async readSyncedScriptSource(e,n){return await this.apiHandler.readSyncedScriptSource(e,n)}async writeSyncedFile(e,n,r){await this.apiHandler.writeSyncedFile(e,n,r)}async executeViaDisk(e,n){return this.apiHandler.executeViaDisk(e,n)}sendError(e,n,r){let i=n instanceof Error?n.message:String(n);if(i.includes("Path traversal detected")){e.status(403).json({error:"Forbidden",message:i});return}let a=n.code;if(a==="ENOSPC"||a==="EPERM"||a==="EACCES"){y.warn(`SyncController.${r} disk error`,{code:a,message:i}),e.status(500).json({error:"Disk error",message:i,code:a,operation:r});return}y.error(`SyncController.${r} failed`,n instanceof Error?n:new Error(i)),e.status(500).json({error:"Internal error",message:`${r}: ${i}`})}};import{randomUUID as gve}from"crypto";function j5(t,e){let n=gve(),r=n.replace(/-/g,"").substring(0,8).toUpperCase(),i=`${r.substring(0,4)}-${r.substring(4,8)}`;return{config:t,app:e,instanceId:n,sessionId:i,startTime:Date.now(),baseUrl:`http://${t.httpHost}:${t.httpPort}`,commandQueue:new Map,pendingCommands:new Map,globalPendingCommands:[],totalCommandsProcessed:0,pluginClients:new Map,pluginCommandSessionsByClientId:new Map,pluginCommandClientIdsByProcessToken:new Map,mcpInstances:new Map,cachedSelectionMap:new Map,studioRoutingMode:"recentPriority",pinnedTargetClientId:null,isClientMode:!1,clientModeHealthTimer:null,clientModeConsecutiveHealthFailures:0,clientModeUpstreamReachable:!0,clientModeUpstreamContextCaptureEnabled:!0,clientModeLastHealthSuccessAt:null,clientModeLastHealthFailureAt:null,clientModeLastHealthError:null,shuttingDown:!1,onUpstreamPermanentlyDown:null,clientModeIdleTimeoutMs:t.clientModeIdleTimeoutMs??36e5,clientModeIdleWatchdogTimer:null,shutdownFn:null,historyManager:null,analyticsManager:null,executionContextManager:null,licenseState:null,syncController:null,internalCommandExecutor:null,dashboardFolderPicker:null,assetLibraryOpenCloudServiceFactory:null,projectChangesCleanupScheduler:null,activeSyncOwnerInstanceId:null,activeProjectRoot:null,pendingDashboardSyncRootPin:null,playtestControlCommand:null,dashboardSyncRootSwitchInFlight:!1,uiStudioRecorders:new Map,aiClientName:"",pluginVersion:"",syncedSessionToken:null,serverLastCommandAt:null}}var M5=Ut(uo(),1);oe();function L5(t){let e=M5.default.json({limit:"5mb"});t.app.use((n,r,i)=>{if(n.path.startsWith("/sync/")){i();return}e(n,r,i)}),t.app.use((n,r,i)=>{r.setHeader("Access-Control-Allow-Origin","http://localhost:3002"),r.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),r.setHeader("Access-Control-Allow-Headers","Content-Type"),i()}),t.app.use((n,r,i)=>{y.debug(`${n.method} ${n.path}`,{ip:n.ip}),i()})}eo();import{randomUUID as _S}from"crypto";eo();oe();function hve(){let t=process.env.WEPPY_ROBLOX_MCP_VERSION?.trim();return t||null}var at=hve()??"2.12.2";Ki();Xn();gm();ho();ru();eo();ho();var V5="studio-",vve=/^studio-[1-9]\d*$/;function Z_(t){return vve.test(t)}function H5(t,e){let n=new Set;for(let r of t)e!==void 0&&r.clientId===e||r.targetAlias&&Z_(r.targetAlias)&&n.add(r.targetAlias);return n}function bve(t,e){let n=H5(t,e),r=1;for(;n.has(`${V5}${r}`);)r+=1;return`${V5}${r}`}function G_(t,e){let n=H5(t,e.clientId);return e.targetAlias&&Z_(e.targetAlias)&&!n.has(e.targetAlias)||(e.targetAlias=bve(t,e.clientId)),e.targetAlias}ru();function K_(t){for(let e of t)G_(t,e)}function J_(t){let e={clientId:t.clientId,targetAlias:t.targetAlias??t.clientId.slice(0,8),lastSeen:t.lastSeen,connectedAt:t.connectedAt,transport:"websocket",connectionState:t.commandSessionState??Ze.CONNECTED};return t.placeId!==void 0&&(e.placeId=t.placeId),t.placeName!==void 0&&(e.placeName=t.placeName),t.pluginVersion!==void 0&&(e.pluginVersion=t.pluginVersion),t.studioVersion!==void 0&&(e.studioVersion=t.studioVersion),t.lastRoutedAt!==void 0&&(e.lastRoutedAt=t.lastRoutedAt),t.processToken!==void 0&&(e.processToken=t.processToken),t.inFlightRequestId!==void 0&&(e.inFlightRequestId=t.inFlightRequestId),t.studioState!==void 0&&(e.studioState=t.studioState),t.studioStateSource!==void 0&&(e.studioStateSource=t.studioStateSource),t.studioStateUpdatedAt!==void 0&&(e.studioStateUpdatedAt=t.studioStateUpdatedAt),t.playtestMode!==void 0&&(e.playtestMode=t.playtestMode),e}function AA(t){let e=Un(t);return K_(e),em(e.map(J_),null)}function Y_(t){let e=new Set;t.aiClientName&&e.add(t.aiClientName);for(let n of t.mcpInstances.values())n.aiClientName&&e.add(n.aiClientName);return Array.from(e)}function W5(t){let n=Date.now();for(let[r,i]of t.mcpInstances)i.lastSeen&&n-i.lastSeen>15e3&&(t.mcpInstances.delete(r),i.sessionId&&t.executionContextManager?.endSession(i.sessionId),y.debug("Removed stale MCP instance",{instanceId:r,lastSeen:i.lastSeen}))}function Z5(t,e,n){let r=e.query.clientId;if(r&&t.pluginClients.has(r)){let i=t.pluginClients.get(r);i.lastSeen=Date.now()}try{let i=e.body;if(!i||!Array.isArray(i.selection)||typeof i.count!="number"){y.warn("Invalid selection update request",{body:i}),n.status(400).json({error:"Invalid request body"});return}let a=r||"unknown",o=Date.now();t.cachedSelectionMap.set(a,{selection:i.selection,count:i.count,timestamp:o,clientId:a}),y.debug("Selection cache updated",{count:i.count,clientId:a,timestamp:o}),n.json({status:"ok",timestamp:o})}catch(i){y.error("Error handling selection update",i),n.status(500).json({error:"Internal server error"})}}function G5(t,e,n){let r=parseInt(e.query.maxAge)||3e4,i=hm(t,r);i?n.json({cached:!0,...i}):n.json({cached:!1,message:"No cached selection available"})}function hm(t,e=3e4,n){if(t.cachedSelectionMap.size===0)return null;let r;if(n)r=t.cachedSelectionMap.get(n);else for(let a of t.cachedSelectionMap.values())(!r||a.timestamp>r.timestamp)&&(r=a);if(!r)return null;let i=Date.now()-r.timestamp;return e===0||i<=e?r:null}function OA(t,e){let n=t.pluginClients.get(e.clientId),r=Date.now(),i=[...t.pluginClients.values()].filter(c=>c.clientId===e.clientId||c.commandSessionState!==Ze.DISCONNECTED),a=n??{clientId:e.clientId,connectedAt:r,lastSeen:r,commandsProcessed:0,connectionType:"polling"},o=G_(i,a),s={clientId:e.clientId,targetAlias:o,projectName:e.projectName??n?.projectName,placeName:e.placeName??n?.placeName,placeId:e.placeId??n?.placeId,pluginVersion:e.pluginVersion??n?.pluginVersion,studioVersion:e.studioVersion??n?.studioVersion,connectedAt:n?.connectedAt||r,lastSeen:r,commandsProcessed:n?.commandsProcessed||0,connectionType:n?.connectionType||"polling",inFlightRequestId:n?.inFlightRequestId,studioState:n?.studioState,studioStateSource:n?.studioStateSource,studioStateUpdatedAt:n?.studioStateUpdatedAt,playtestMode:n?.playtestMode,...n?.commandSessionState?{commandSessionState:n.commandSessionState}:{},...n?.processToken?{processToken:n.processToken}:{}};return t.pluginClients.set(e.clientId,s),t.syncController&&typeof t.syncController.setCurrentConnectedPlace=="function"&&typeof e.placeId=="number"&&Number.isFinite(e.placeId)&&t.syncController.setCurrentConnectedPlace(e.placeId,e.placeName??null),t.pendingCommands.has(e.clientId)||t.pendingCommands.set(e.clientId,[]),e.pluginVersion&&(t.pluginVersion=e.pluginVersion),typeof s.placeId=="number"&&Number.isFinite(s.placeId)&&__(t,s.placeId,s.placeName??null),t.analyticsManager&&(e.pluginVersion&&t.analyticsManager.setPluginVersion(e.pluginVersion),t.analyticsManager.trackPluginConnected()),y.info("Plugin client registered",{clientId:e.clientId,targetAlias:o,projectName:e.projectName,placeName:e.placeName,isReconnect:!!n}),{clientInfo:s,sessionId:t.sessionId,mcpVersion:at,mcpInstanceCount:t.mcpInstances.size+1,aiClientNames:Y_(t)}}function $A(t,e){let n=t.pluginClients.get(e),r=t.pluginClients.has(e),i=n?.commandSessionState===Ze.CONNECTED;if(t.pluginClients.delete(e),t.pendingCommands.delete(e),r&&nu(t,e),r&&t.syncController&&typeof t.syncController.clearCurrentConnectedPlaceIfMatch=="function"&&typeof n?.placeId=="number"&&Number.isFinite(n.placeId)){let a=[...t.pluginClients.values()].filter(o=>typeof o.placeId=="number"&&Number.isFinite(o.placeId)).sort((o,s)=>s.lastSeen-o.lastSeen)[0];a?t.syncController.setCurrentConnectedPlace?.(a.placeId??null,a.placeName??null):t.syncController.clearCurrentConnectedPlaceIfMatch(n.placeId)}return i&&tm(t,e,"disconnected",n),y.info("Plugin client unregistered",{clientId:e,existed:r}),r}function X_(t,e,n){try{let r=e.body;if(!r.clientId){n.status(400).json({error:"Missing clientId"});return}let i=OA(t,{clientId:r.clientId,projectName:r.projectName,placeName:r.placeName,placeId:r.placeId,pluginVersion:r.pluginVersion,studioVersion:r.studioVersion});n.json({status:"ok",clientId:r.clientId,targetAlias:i.clientInfo.targetAlias,serverInstanceId:t.instanceId,sessionId:i.sessionId,mcpVersion:i.mcpVersion,connectedAt:i.clientInfo.connectedAt,aiClientNames:i.aiClientNames,serverStartTime:t.startTime,mcpInstanceCount:i.mcpInstanceCount})}catch(r){y.error("Error registering plugin client",r),n.status(500).json({error:"Internal server error"})}}function Q_(t,e,n){let r=e.body?.clientId;if(!r){n.status(400).json({error:"Missing clientId"});return}let i=$A(t,r);n.json({status:"ok",existed:i})}function K5(t,e,n){try{let r=e.body;if(!r.instanceId){n.status(400).json({error:"Missing instanceId"});return}let i=Date.now(),a={instanceId:r.instanceId,...typeof r.sessionId=="string"?{sessionId:r.sessionId}:{},pid:r.pid,connectedAt:i,isServer:!1,lastSeen:i};r.aiClientName&&(a.aiClientName=r.aiClientName),r.cwd&&(a.cwd=r.cwd),"projectRoot"in r&&(a.projectRoot=r.projectRoot),t.mcpInstances.set(r.instanceId,a),dt(t,"mcp_status",{aiClientName:a.aiClientName??"Unknown",instanceId:r.instanceId,status:"registered"}),cu(t,{timestamp:new Date().toISOString(),type:"mcp",status:"registered",instanceId:r.instanceId,message:`MCP registered \u2014 ${a.aiClientName??r.instanceId}`,...a.aiClientName?{aiClientName:a.aiClientName}:{}}),y.info("MCP instance registered (client mode)",{instanceId:r.instanceId,pid:r.pid,cwd:r.cwd}),n.json({status:"ok",instanceId:r.instanceId,serverInstanceId:t.instanceId,sessionId:t.sessionId,mcpVersion:at,mcpInstanceCount:t.mcpInstances.size+1})}catch(r){y.error("Error registering MCP instance",r),n.status(500).json({error:"Internal server error"})}}function J5(t,e,n){let r=e.body?.instanceId;if(!r){n.status(400).json({error:"Missing instanceId"});return}let i=t.mcpInstances.get(r),a=!!i;t.mcpInstances.delete(r),i?.sessionId&&t.executionContextManager?.endSession(i.sessionId),a&&(dt(t,"mcp_status",{aiClientName:i?.aiClientName??"Unknown",instanceId:r,status:"unregistered"}),cu(t,{timestamp:new Date().toISOString(),type:"mcp",status:"unregistered",instanceId:r,message:`MCP unregistered \u2014 ${i?.aiClientName??r}`,...i?.aiClientName?{aiClientName:i.aiClientName}:{}})),y.info("MCP instance unregistered",{instanceId:r,existed:a}),n.json({status:"ok",existed:a})}function Y5(t,e,n){let{instanceId:r,aiClientName:i}=e.body;if(r&&i){let a=t.mcpInstances.get(r);a&&(a.aiClientName=i)}n.json({status:"ok"})}function X5(t){let e=3e4,n=Date.now(),r=zr({appDataDir:t.config.appDataDir});for(let[a,o]of t.pluginClients)n-o.lastSeen>e&&(t.pluginClients.delete(a),t.pendingCommands.delete(a),nu(t,a));W5(t);let i=Un(t);return K_(i),{serverInstanceId:t.instanceId,sessionId:t.sessionId,mcpVersion:at,uptime:n-t.startTime,serverStartTime:t.startTime,serverExecutable:process.execPath,serverHost:t.config.httpHost,serverPort:t.config.httpPort,serverPid:process.pid,pluginClients:i.map(J_),studioRoutingMode:t.studioRoutingMode,pinnedTargetClientId:t.pinnedTargetClientId,mcpInstances:[{instanceId:t.instanceId,pid:process.pid,connectedAt:t.startTime,isServer:!0,cwd:process.cwd(),projectRoot:r,lastSeen:n,...t.aiClientName?{aiClientName:t.aiClientName}:{}},...Array.from(t.mcpInstances.values())],mcpInstanceCount:t.mcpInstances.size+1}}function eS(t,e){e.json(X5(t))}function tS(t,e,n){let r=e.query.instanceId;r&&t.mcpInstances.has(r)&&(t.mcpInstances.get(r).lastSeen=Date.now()),W5(t);let i=Un(t);K_(i);let s={...{status:"online",connectedClients:i.length,queuedCommands:A8(t),uptime:Date.now()-t.startTime,version:at,enableContextCapture:t.executionContextManager?.isEnabled()??t.config.enableContextCapture??!0,isClientMode:t.isClientMode,shuttingDown:t.shuttingDown,pid:process.pid,sessionId:t.sessionId,nodeVersion:process.version,studioRoutingMode:t.studioRoutingMode,pinnedTargetClientId:t.pinnedTargetClientId},instanceId:t.instanceId,mcpInstanceCount:t.mcpInstances.size+1,aiClientNames:Y_(t),pluginVersion:t.pluginVersion||void 0,dashboardSseClients:t.dashboardSseClients?.size??0,websocketClients:i.length,pluginClients:i.map(J_),...t.isClientMode?{upstream:{reachable:t.clientModeUpstreamReachable,consecutiveFailures:t.clientModeConsecutiveHealthFailures,lastSuccessAt:t.clientModeLastHealthSuccessAt,lastFailureAt:t.clientModeLastHealthFailureAt,lastError:t.clientModeLastHealthError,baseUrl:t.baseUrl}}:{}};n.json(s)}function Q5(t,e,n,r){let i=e.ip||e.socket.remoteAddress||"";if(!(i==="127.0.0.1"||i==="::1"||i==="::ffff:127.0.0.1"||i==="localhost")){y.warn("Shutdown request rejected from non-localhost",{ip:i}),n.status(403).json({error:"Forbidden: localhost only"});return}y.info("Shutdown request received, initiating graceful shutdown",{requestedBy:i,uptime:Date.now()-t.startTime}),n.json({status:"shutting_down",message:"Server will shutdown gracefully",pid:process.pid}),setTimeout(async()=>{try{await r(),y.info("Graceful shutdown completed"),process.exit(0)}catch(o){y.error("Error during graceful shutdown",o),process.exit(1)}},100)}async function nS(t){if(t.isClientMode)try{let e=await fetch(`${t.baseUrl}/connection-info`);if(e.ok)return await e.json()}catch(e){y.warn("Failed to fetch connection info from server",{error:e})}return X5(t)}ho();var St={bridgeRunTest:"manage_studio_run_test_bridge",placeInfo:"system_info_place_info",clearLogs:"manage_logs_clear",createScript:"manage_scripts_create",getLogs:"manage_logs_get",deleteScript:"manage_scripts_delete",canonical:{playStart:"manage_studio_play_start",playStop:"manage_studio_play_stop",playPause:"manage_studio_play_pause",playResume:"manage_studio_play_resume",playStatus:"manage_studio_play_status",runTest:"manage_studio_run_test"}},_ve=new Set([St.canonical.runTest]),Sve=new Set([St.canonical.playStop]),bqe=new Set([St.canonical.playStart,St.canonical.playStop,St.canonical.playPause,St.canonical.playResume,St.canonical.playStatus]);function Si(t){return _ve.has(t)}function ym(t){return Sve.has(t)}var wqe=St.canonical.playStop,e9=[5e3,15e3];ru();var wve=new Set(["manage_assets_export_selection_rbxm","manage_assets_export_path_rbxm","manage_assets_review_model","manage_assets_generate_model","manage_assets_import_rbxm","manage_assets_generate_thumbnail"]),xn=class t extends Error{code;routing;constructor(e,n,r){super(n),this.name="CommandTargetSelectionError",this.code=e,this.routing=r,Object.setPrototypeOf(this,t.prototype)}};function Ive(t={},e){let n={},r=t.clientId,i=t.targetAlias,a=t.placeId;if(r!==void 0){if(typeof r!="string"||r.trim().length===0)throw new xn("invalid_target_selector","clientId target selector must be a non-empty string",{selectionMode:"clientId",...typeof r=="string"?{requestedClientId:r.trim()}:{}});n.requestedClientId=r.trim()}if(i!==void 0){if(typeof i!="string"||i.trim().length===0)throw new xn("invalid_target_selector","targetAlias target selector must be a non-empty string",{selectionMode:"targetAlias",...typeof i=="string"?{requestedTargetAlias:i.trim()}:{}});n.requestedTargetAlias=i.trim()}if(a!==void 0&&Cve(e,t)){if(typeof a!="number"||!Number.isFinite(a))throw new xn("invalid_target_selector","placeId target selector must be a finite number",{selectionMode:"placeId"});n.requestedPlaceId=a}return n}function rS(t,e,n={},r){let i=Ive(n,r),a=o8(e,t.studioRoutingMode==="pinned"?t.pinnedTargetClientId:null);if(i.requestedClientId!==void 0)return Pve(a,i);if(i.requestedTargetAlias!==void 0)return kve(a,i);if(i.requestedPlaceId!==void 0)return Eve(a,i);if(t.studioRoutingMode==="pinned"&&t.pinnedTargetClientId!==null){let s=a.find(c=>c.clientId===t.pinnedTargetClientId);if(s)return{targetClientId:s.clientId,routing:Zr("pinnedTarget",i,s)}}let o=a[0];return o?{targetClientId:o.clientId,routing:Zr("recentPriority",i,o)}:{routing:{selectionMode:"globalQueue"}}}function Cve(t,e){return!t||!wve.has(t)?!0:e.scope==="shared"}function Pve(t,e){let n=t.find(r=>r.clientId===e.requestedClientId);if(!n)throw new xn("target_client_not_found",`Target client not found: ${e.requestedClientId}`,Zr("clientId",e));if(e.requestedTargetAlias!==void 0&&n.targetAlias!==e.requestedTargetAlias)throw new xn("target_selector_mismatch",`Target client ${n.clientId} does not match targetAlias ${e.requestedTargetAlias}`,Zr("clientId",e,n));return t9("clientId",e,n),{targetClientId:n.clientId,routing:Zr("clientId",e,n)}}function kve(t,e){let n=t.find(r=>r.targetAlias!==void 0&&Z_(r.targetAlias)&&r.targetAlias===e.requestedTargetAlias);if(!n)throw new xn("target_alias_not_found",`Target alias not found: ${e.requestedTargetAlias}`,Zr("targetAlias",e));return t9("targetAlias",e,n),{targetClientId:n.clientId,routing:Zr("targetAlias",e,n)}}function Eve(t,e){let n=t.filter(i=>i.placeId===e.requestedPlaceId);if(n.length===0)throw new xn("target_place_not_found",`Target place not found: ${e.requestedPlaceId}`,Zr("placeId",e));if(n.length>1)throw new xn("target_place_ambiguous",`Target place is ambiguous: ${e.requestedPlaceId}`,Zr("placeId",e));let r=n[0];return{targetClientId:r.clientId,routing:Zr("placeId",e,r)}}function t9(t,e,n){if(e.requestedPlaceId!==void 0&&n.placeId!==e.requestedPlaceId)throw new xn("target_selector_mismatch",`Target client ${n.clientId} is not connected to placeId ${e.requestedPlaceId}`,Zr(t,e,n))}function Zr(t,e,n){let r={selectionMode:t};return e.requestedClientId!==void 0&&(r.requestedClientId=e.requestedClientId),e.requestedTargetAlias!==void 0&&(r.requestedTargetAlias=e.requestedTargetAlias),e.requestedPlaceId!==void 0&&(r.requestedPlaceId=e.requestedPlaceId),n!==void 0&&(r.actualClientId=n.clientId,n.targetAlias!==void 0&&(r.actualTargetAlias=n.targetAlias),n.placeId!==void 0&&(r.actualPlaceId=n.placeId),n.placeName!==void 0&&(r.actualPlaceName=n.placeName)),r}jT();oe();pm();var Zs={query_instances:{discriminator:"action",validActions:new Set(["get","children","find_child","find_descendant","wait_for_child","class_info","search_name","search_class","search_property","search_tag","file_tree","project_structure","descendants","ancestors"]),allowedParams:{query_instances_get:new Set(["path","sessionDebugId","siblingIndex","placeId","clientId","targetAlias"]),query_instances_children:new Set(["path","sessionDebugId","siblingIndex","recursive","maxDepth","placeId","clientId","targetAlias"]),query_instances_find_child:new Set(["path","childName","placeId","clientId","targetAlias"]),query_instances_find_descendant:new Set(["path","descendantName","placeId","clientId","targetAlias"]),query_instances_wait_for_child:new Set(["path","childName","timeout","placeId","clientId","targetAlias"]),query_instances_class_info:new Set(["className","placeId","clientId","targetAlias"]),query_instances_search_name:new Set(["root","query","caseSensitive","maxResults","placeId","clientId","targetAlias"]),query_instances_search_class:new Set(["className","root","includeSubclasses","maxResults","placeId","clientId","targetAlias"]),query_instances_search_property:new Set(["root","propertyName","propertyValue","maxResults","placeId","clientId","targetAlias"]),query_instances_search_tag:new Set(["root","tag","maxResults","placeId","clientId","targetAlias"]),query_instances_file_tree:new Set(["maxDepth","root","includeServices","placeId","clientId","targetAlias"]),query_instances_project_structure:new Set(["root","depth","placeId","clientId","targetAlias"]),query_instances_descendants:new Set(["path","sessionDebugId","siblingIndex","maxResults","placeId","clientId","targetAlias"]),query_instances_ancestors:new Set(["path","sessionDebugId","siblingIndex","placeId","clientId","targetAlias"])},paramAliases:{query_instances_search_name:{query:"pattern"},query_instances_search_property:{root:"rootPath"},query_instances_search_tag:{root:"rootPath"},query_instances_project_structure:{root:"rootPath"}}},mutate_instances:{discriminator:"action",validActions:new Set(["create","create_with_props","delete","clone","move","rename","pivot","create_tree","mass_create","mass_delete","mass_duplicate","smart_duplicate","scatter"]),allowedParams:{mutate_instances_create:new Set(["className","parent","name","properties","placeId","clientId","targetAlias"]),mutate_instances_create_with_props:new Set(["className","parent","name","properties","placeId","clientId","targetAlias"]),mutate_instances_delete:new Set(["path","sessionDebugId","siblingIndex","placeId","clientId","targetAlias"]),mutate_instances_clone:new Set(["path","sourcePath","sessionDebugId","siblingIndex","targetParent","newName","placeId","clientId","targetAlias"]),mutate_instances_move:new Set(["path","sessionDebugId","siblingIndex","newParent","placeId","clientId","targetAlias"]),mutate_instances_rename:new Set(["path","sessionDebugId","siblingIndex","newName","placeId","clientId","targetAlias"]),mutate_instances_pivot:new Set(["path","sessionDebugId","siblingIndex","position","cframe","offset","placeId","clientId","targetAlias"]),mutate_instances_create_tree:new Set(["parent","tree","placeId","clientId","targetAlias"]),mutate_instances_mass_create:new Set(["instances","placeId","clientId","targetAlias"]),mutate_instances_mass_delete:new Set(["paths","placeId","clientId","targetAlias"]),mutate_instances_mass_duplicate:new Set(["targetParent","paths","placeId","clientId","targetAlias"]),mutate_instances_smart_duplicate:new Set(["path","sessionDebugId","siblingIndex","targetParent","offset","count","placeId","clientId","targetAlias"]),mutate_instances_scatter:new Set(["templatePaths","region","count","seed","maxSlope","avoidWater","alignToNormal","scaleJitter","minSpacing","parentName","placeId","clientId","targetAlias"])},paramAliases:{mutate_instances_clone:{path:"sourcePath"},mutate_instances_smart_duplicate:{spacing:"offset"}}},manage_properties:{discriminator:"action",validActions:new Set(["get","set","get_all","set_multiple","get_attr","set_attr","get_all_attrs","delete_attr","add_tag","remove_tag","check_tag","get_tags","get_tagged","set_calculated","set_relative","mass_set","mass_get","modify_children"]),allowedParams:{manage_properties_get:new Set(["path","property","placeId","clientId","targetAlias"]),manage_properties_set:new Set(["path","property","value","placeId","clientId","targetAlias"]),manage_properties_get_all:new Set(["path","includeReadOnly","placeId","clientId","targetAlias"]),manage_properties_set_multiple:new Set(["path","properties","placeId","clientId","targetAlias"]),manage_properties_get_attr:new Set(["path","attribute","placeId","clientId","targetAlias"]),manage_properties_set_attr:new Set(["path","value","attribute","placeId","clientId","targetAlias"]),manage_properties_get_all_attrs:new Set(["path","placeId","clientId","targetAlias"]),manage_properties_delete_attr:new Set(["path","attribute","placeId","clientId","targetAlias"]),manage_properties_add_tag:new Set(["path","tag","placeId","clientId","targetAlias"]),manage_properties_remove_tag:new Set(["path","tag","placeId","clientId","targetAlias"]),manage_properties_check_tag:new Set(["path","tag","placeId","clientId","targetAlias"]),manage_properties_get_tags:new Set(["path","placeId","clientId","targetAlias"]),manage_properties_get_tagged:new Set(["tagName","root","maxResults","placeId","clientId","targetAlias"]),manage_properties_set_calculated:new Set(["path","expression","variables","propertyName","placeId","clientId","targetAlias"]),manage_properties_set_relative:new Set(["path","value","operation","amount","propertyName","placeId","clientId","targetAlias"]),manage_properties_mass_set:new Set(["paths","propertyName","propertyValue","placeId","clientId","targetAlias"]),manage_properties_mass_get:new Set(["paths","propertyName","placeId","clientId","targetAlias"]),manage_properties_modify_children:new Set(["parentPath","modifications","propertyName","propertyValue","filter","recursive","placeId","clientId","targetAlias"])},paramAliases:{manage_properties_get_tagged:{tagName:"tag",root:"rootPath"},manage_properties_set_relative:{amount:"value"}}},manage_scripts:{discriminator:"action",validActions:new Set(["get_source","set_source","create","delete","edit_replace","edit_insert","edit_delete","search","replace","get_dependencies","validate"]),allowedParams:{manage_scripts_get_source:new Set(["path","startLine","endLine","placeId","clientId","targetAlias"]),manage_scripts_set_source:new Set(["path","source","validate","placeId","clientId","targetAlias"]),manage_scripts_create:new Set(["source","scriptType","parent","name","placeId","clientId","targetAlias"]),manage_scripts_delete:new Set(["path","placeId","clientId","targetAlias"]),manage_scripts_edit_replace:new Set(["path","startLine","endLine","newLines","validate","placeId","clientId","targetAlias"]),manage_scripts_edit_insert:new Set(["path","lines","afterLine","content","validate","placeId","clientId","targetAlias"]),manage_scripts_edit_delete:new Set(["path","startLine","endLine","validate","placeId","clientId","targetAlias"]),manage_scripts_search:new Set(["path","pattern","caseSensitive","wholeWord","usePattern","maxResults","placeId","clientId","targetAlias"]),manage_scripts_replace:new Set(["path","pattern","replacement","usePattern","dryRun","placeId","clientId","targetAlias"]),manage_scripts_get_dependencies:new Set(["path","placeId","clientId","targetAlias"]),manage_scripts_validate:new Set(["source","path","placeId","clientId","targetAlias"])},paramAliases:{manage_scripts_edit_replace:{newLines:"newContent"},manage_scripts_edit_insert:{lines:"content"},manage_scripts_replace:{pattern:"searchPattern"}}},manage_ui:{discriminator:"action",validActions:new Set(["design_brief","create_tree","update","delete","preview","check"]),allowedParams:{manage_ui_design_brief:new Set(["brief","placeId","clientId","targetAlias"]),manage_ui_create_tree:new Set(["briefId","tree","placeId","clientId","targetAlias"]),manage_ui_update:new Set(["targetPath","changes","briefId","placeId","clientId","targetAlias"]),manage_ui_delete:new Set(["targetPath","placeId","clientId","targetAlias"]),manage_ui_preview:new Set(["targetPath","briefId","placeId","clientId","targetAlias"]),manage_ui_check:new Set(["targetPath","briefId","includeVisualAnalysis","snapshotId","placeId","clientId","targetAlias"])}},manage_lighting:{discriminator:"action",validActions:new Set(["lighting","atmosphere","sky","terrain_props","time","mood"]),allowedParams:{manage_lighting_lighting:new Set(["properties","placeId","clientId","targetAlias"]),manage_lighting_atmosphere:new Set(["properties","createIfMissing","placeId","clientId","targetAlias"]),manage_lighting_sky:new Set(["properties","createIfMissing","placeId","clientId","targetAlias"]),manage_lighting_terrain_props:new Set(["properties","placeId","clientId","targetAlias"]),manage_lighting_time:new Set(["time","clockTime","placeId","clientId","targetAlias"]),manage_lighting_mood:new Set(["preset","overrides","placeId","clientId","targetAlias"])}},manage_selection:{discriminator:"action",validActions:new Set(["get","set","clear","cached","context","details","add","remove","watch"]),allowedParams:{manage_selection_get:new Set(["placeId","clientId","targetAlias"]),manage_selection_set:new Set(["paths","placeId","clientId","targetAlias"]),manage_selection_clear:new Set(["placeId","clientId","targetAlias"]),manage_selection_cached:new Set(["maxAge"]),manage_selection_context:new Set(["includeSource","includeProperties","includeChildren","placeId","clientId","targetAlias"]),manage_selection_details:new Set(["maxDepth","includeAncestors","placeId","clientId","targetAlias"]),manage_selection_add:new Set(["paths","placeId","clientId","targetAlias"]),manage_selection_remove:new Set(["paths","placeId","clientId","targetAlias"]),manage_selection_watch:new Set(["placeId","clientId","targetAlias"])}},manage_camera:{discriminator:"action",validActions:new Set(["info","focus_path","focus_position","suggest","screenshot"]),allowedParams:{manage_camera_info:new Set(["placeId","clientId","targetAlias"]),manage_camera_focus_path:new Set(["path","distance","duration","offset","respectAutoFocusSetting","placeId","clientId","targetAlias"]),manage_camera_focus_position:new Set(["position","distance","duration","offset","lookAt","respectAutoFocusSetting","placeId","clientId","targetAlias"]),manage_camera_suggest:new Set(["path","placeId","clientId","targetAlias"]),manage_camera_screenshot:new Set(["placeId","clientId","targetAlias"])},paramAliases:{manage_camera_suggest:{path:"targetPath"}}},manage_tween:{discriminator:"action",validActions:new Set(["create","play","pause","cancel"]),allowedParams:{manage_tween_create:new Set(["path","tweenInfo","properties","placeId","clientId","targetAlias"]),manage_tween_play:new Set(["tweenId","placeId","clientId","targetAlias"]),manage_tween_pause:new Set(["tweenId","placeId","clientId","targetAlias"]),manage_tween_cancel:new Set(["tweenId","placeId","clientId","targetAlias"])}},manage_audio:{discriminator:"action",validActions:new Set(["play","stop","pause","resume","set_listener"]),allowedParams:{manage_audio_play:new Set(["path","soundId","volume","looped","playbackSpeed","placeId","clientId","targetAlias"]),manage_audio_stop:new Set(["path","placeId","clientId","targetAlias"]),manage_audio_pause:new Set(["path","placeId","clientId","targetAlias"]),manage_audio_resume:new Set(["path","placeId","clientId","targetAlias"]),manage_audio_set_listener:new Set(["listenerType","listenerPath","placeId","clientId","targetAlias"])}},manage_animation:{discriminator:"action",validActions:new Set(["load","play","stop","get_tracks"]),allowedParams:{manage_animation_load:new Set(["path","animationId","placeId","clientId","targetAlias"]),manage_animation_play:new Set(["path","trackId","speed","fadeTime","weight","priority","placeId","clientId","targetAlias"]),manage_animation_stop:new Set(["path","trackId","fadeTime","placeId","clientId","targetAlias"]),manage_animation_get_tracks:new Set(["path","placeId","clientId","targetAlias"])}},manage_physics:{discriminator:"action",validActions:new Set(["register_group","set_collidable","get_groups"]),allowedParams:{manage_physics_register_group:new Set(["groupName","placeId","clientId","targetAlias"]),manage_physics_set_collidable:new Set(["group1","group2","collidable","placeId","clientId","targetAlias"]),manage_physics_get_groups:new Set(["placeId","clientId","targetAlias"])}},manage_effects:{discriminator:"action",validActions:new Set(["emit","clear","toggle"]),allowedParams:{manage_effects_emit:new Set(["path","count","placeId","clientId","targetAlias"]),manage_effects_clear:new Set(["path","placeId","clientId","targetAlias"]),manage_effects_toggle:new Set(["path","enabled","placeId","clientId","targetAlias"])}},manage_terrain:{discriminator:"action",validActions:new Set(["fill_block","fill_ball","fill_cylinder","fill_wedge","clear_region","clear_bounds","replace_material","colors_get","colors_set","read_voxel","read_voxels","write_voxels","generate","smooth"]),allowedParams:{manage_terrain_fill_block:new Set(["cframe","size","placeId","clientId","targetAlias"]),manage_terrain_fill_ball:new Set(["center","radius","placeId","clientId","targetAlias"]),manage_terrain_fill_cylinder:new Set(["cframe","radius","height","placeId","clientId","targetAlias"]),manage_terrain_fill_wedge:new Set(["cframe","size","placeId","clientId","targetAlias"]),manage_terrain_clear_region:new Set(["region","placeId","clientId","targetAlias"]),manage_terrain_clear_bounds:new Set(["min","max","placeId","clientId","targetAlias"]),manage_terrain_replace_material:new Set(["material","region","sourceMaterial","targetMaterial","placeId","clientId","targetAlias"]),manage_terrain_colors_get:new Set(["material","placeId","clientId","targetAlias"]),manage_terrain_colors_set:new Set(["material","color","placeId","clientId","targetAlias"]),manage_terrain_read_voxel:new Set(["position","placeId","clientId","targetAlias"]),manage_terrain_read_voxels:new Set(["region","resolution","placeId","clientId","targetAlias"]),manage_terrain_write_voxels:new Set(["region","resolution","materials","occupancy","placeId","clientId","targetAlias"]),manage_terrain_generate:new Set(["region","preset","seed","baseHeight","amplitude","frequency","octaves","persistence","waterLevel","edgeBlend","materialPalette","layers","placeId","clientId","targetAlias"]),manage_terrain_smooth:new Set(["region","intensity","placeId","clientId","targetAlias"])}},spatial_query:{discriminator:"action",validActions:new Set(["raycast","find_ground","check_placement","multi_raycast","scan_area","find_flat","find_spawn","analyze_walkable","spatial_map","find_space","bounds","snap_grid","collision"]),allowedParams:{spatial_query_raycast:new Set(["origin","direction","filterType","filterList","filterInstances","ignoreWater","placeId","clientId","targetAlias"]),spatial_query_find_ground:new Set(["maxDistance","position","filterList","filterInstances","offset","placeId","clientId","targetAlias"]),spatial_query_check_placement:new Set(["position","size","filterList","filterInstances","rotation","checkGround","placeId","clientId","targetAlias"]),spatial_query_multi_raycast:new Set(["filterType","filterList","filterInstances","ignoreWater","rays","placeId","clientId","targetAlias"]),spatial_query_scan_area:new Set(["size","filterList","filterInstances","center","resolution","maxResults","placeId","clientId","targetAlias"]),spatial_query_find_flat:new Set(["searchArea","minSize","maxSlope","tolerance","maxResults","placeId","clientId","targetAlias"]),spatial_query_find_spawn:new Set(["searchArea","spawnSize","minSpacing","preferOutdoor","count","placeId","clientId","targetAlias"]),spatial_query_analyze_walkable:new Set(["area","maxSlope","resolution","characterHeight","maxStepHeight","placeId","clientId","targetAlias"]),spatial_query_spatial_map:new Set(["path","rootPath","includeModels","maxResults","placeId","clientId","targetAlias"]),spatial_query_find_space:new Set(["size","searchArea","gridSize","gridSnap","padding","placeId","clientId","targetAlias"]),spatial_query_bounds:new Set(["path","paths","placeId","clientId","targetAlias"]),spatial_query_snap_grid:new Set(["gridSize","path","gridSnap","axes","placeId","clientId","targetAlias"]),spatial_query_collision:new Set(["position","path","ignorePaths","placeId","clientId","targetAlias"])},paramAliases:{spatial_query_spatial_map:{path:"rootPath"}}},manage_assets:{discriminator:"action",validActions:new Set(["insert","info","search","search_insert","insert_free","insert_package","export_selection_json","export_selection_rbxm","export_path_rbxm","review_model","generate_model","upload_asset","import_rbxm","generate_thumbnail"]),allowedParams:{manage_assets_insert:new Set(["assetId","parent","name","position","placeId","clientId","targetAlias"]),manage_assets_info:new Set(["assetId","placeId","clientId","targetAlias"]),manage_assets_search:new Set(["query","maxResults","category","sortType","placeId","clientId","targetAlias"]),manage_assets_search_insert:new Set(["parent","name","query","placeId","clientId","targetAlias"]),manage_assets_insert_free:new Set(["assetId","parent","name","position","placeId","clientId","targetAlias"]),manage_assets_insert_package:new Set(["assetId","parent","name","placeId","clientId","targetAlias"]),manage_assets_export_selection_json:new Set(["format","includeProperties","includeChildren","maxDepth","placeId","clientId","targetAlias"]),manage_assets_export_selection_rbxm:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","displayName","description","thumbnailMode","uploadMode","uploadTemporaryAssets","creatorType","creatorId","clientId","targetAlias"]),manage_assets_export_path_rbxm:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","sourcePath","displayName","description","thumbnailMode","uploadMode","uploadTemporaryAssets","creatorType","creatorId","clientId","targetAlias"]),manage_assets_review_model:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","sourcePath","displayName","description","thumbnailMode","uploadMode","uploadTemporaryAssets","creatorType","creatorId","exportToLibrary","expectedUse","expectedGroups","maxDescendants","maxDepth","readiness","clientId","targetAlias"]),manage_assets_generate_model:new Set(["contextId","contextSummary","replayMetadata","placeId","category","prompt","schemaMode","predefinedSchema","schemaGroups","size","maxTriangles","generateTextures","review","targetParent","name","displayName","expectedUse","expectedGroups","maxDescendants","maxDepth","readiness","anchorMode","clientId","targetAlias"]),manage_assets_upload_asset:new Set(["contextId","contextSummary","replayMetadata","placeId","category","assetType","sourcePath","displayName","description","creatorType","creatorId","clientId","targetAlias"]),manage_assets_import_rbxm:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","assetLibraryAssetId","targetParent","name","clientId","targetAlias"]),manage_assets_generate_thumbnail:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","assetLibraryAssetId","clientId","targetAlias"])},paramAliases:{manage_assets_search:{maxResults:"limit"}}},manage_open_cloud_assets:{discriminator:"action",validActions:new Set(["preflight","credential_status","capabilities","upload","update","info","operation_status"]),allowedParams:{manage_open_cloud_assets_preflight:new Set(["filePath","category","creatorType","creatorId"]),manage_open_cloud_assets_credential_status:new Set([]),manage_open_cloud_assets_capabilities:new Set([]),manage_open_cloud_assets_upload:new Set(["contextId","contextSummary","replayMetadata","filePath","category","displayName","description","creatorType","creatorId","expectedPrice","waitForOperation","operationPollTimeoutMs","operationPollIntervalMs"]),manage_open_cloud_assets_update:new Set(["contextId","contextSummary","replayMetadata","assetId","filePath","category","displayName","description","creatorType","creatorId","expectedPrice","updateMask","waitForOperation","operationPollTimeoutMs","operationPollIntervalMs"]),manage_open_cloud_assets_info:new Set(["assetId","readMask"]),manage_open_cloud_assets_operation_status:new Set(["operationId"])}},manage_sync:{discriminator:"action",validActions:new Set(["status_current_place","history","directions","read_file","write_file","progress"]),allowedParams:{manage_sync_status_current_place:new Set([]),manage_sync_history:new Set(["placeId","query"]),manage_sync_directions:new Set(["placeId"]),manage_sync_read_file:new Set(["placeId","instancePath"]),manage_sync_write_file:new Set(["placeId","instancePath","content"]),manage_sync_progress:new Set([])}},workspace_state:{discriminator:"action",validActions:new Set(["sync","snapshot","changes","viewport","clear_history","metadata","scripts","selection_info","clear_cache"]),allowedParams:{workspace_state_sync:new Set(["includeMetadata","placeId","clientId","targetAlias"]),workspace_state_snapshot:new Set(["placeId","clientId","targetAlias"]),workspace_state_changes:new Set(["limit","placeId","clientId","targetAlias"]),workspace_state_viewport:new Set(["includeCameraInfo","includeSelectionBounds","placeId","clientId","targetAlias"]),workspace_state_clear_history:new Set(["placeId","clientId","targetAlias"]),workspace_state_metadata:new Set(["placeId","clientId","targetAlias"]),workspace_state_scripts:new Set(["placeId","clientId","targetAlias"]),workspace_state_selection_info:new Set(["placeId","clientId","targetAlias"]),workspace_state_clear_cache:new Set(["placeId","clientId","targetAlias"])}},manage_logs:{discriminator:"action",validActions:new Set(["get","clear","errors"]),allowedParams:{manage_logs_get:new Set(["level","limit","pattern","since","sinceSeq","placeId","clientId","targetAlias"]),manage_logs_clear:new Set(["placeId","clientId","targetAlias"]),manage_logs_errors:new Set(["limit","placeId","clientId","targetAlias"])},paramAliases:{manage_logs_get:{level:"type"}}},system_info:{discriminator:"action",validActions:new Set(["ping","connection","usage","place_info","services","preflight"]),allowedParams:{system_info_ping:new Set(["message","placeId","clientId","targetAlias"]),system_info_connection:new Set([]),system_info_usage:new Set(["placeId","clientId","targetAlias"]),system_info_place_info:new Set(["placeId","clientId","targetAlias"]),system_info_services:new Set(["placeId","clientId","targetAlias"]),system_info_preflight:new Set(["placeId","clientId","targetAlias"])}},manage_studio:{discriminator:"action",validActions:new Set(["toggle_ui_preview","play_start","play_stop","play_pause","play_resume","play_status","run_test"]),allowedParams:{manage_studio_toggle_ui_preview:new Set(["enabled","placeId","clientId","targetAlias"]),manage_studio_play_start:new Set(["mode","placeId","clientId","targetAlias"]),manage_studio_play_stop:new Set(["placeId","clientId","targetAlias"]),manage_studio_play_pause:new Set(["placeId","clientId","targetAlias"]),manage_studio_play_resume:new Set(["placeId","clientId","targetAlias"]),manage_studio_play_status:new Set(["placeId","clientId","targetAlias"]),manage_studio_run_test:new Set(["mode","script","test_name","timeout","placeId","clientId","targetAlias","contextId","contextSummary","replayMetadata"])}}};var Rve={manage_scripts_validate:"internal",manage_selection_cached:"internal",manage_open_cloud_assets_preflight:"internal",manage_open_cloud_assets_credential_status:"internal",manage_open_cloud_assets_capabilities:"internal",manage_open_cloud_assets_upload:"internal",manage_open_cloud_assets_update:"internal",manage_open_cloud_assets_info:"internal",manage_open_cloud_assets_operation_status:"internal",manage_sync_status_current_place:"internal",manage_sync_history:"internal",manage_sync_directions:"internal",manage_sync_read_file:"internal",manage_sync_write_file:"internal",manage_sync_progress:"internal",system_info_connection:"internal",system_info_preflight:"internal",manage_studio_run_test:"internal"};function iS(t){return Rve[t]||"plugin"}var n9=new Set(["batch_execute","execute_luau","extended_call_method","extended_call_methods","extended_get_properties","extended_get_property","extended_set_properties","extended_set_property","manage_animation_get_tracks","manage_animation_load","manage_animation_play","manage_animation_stop","manage_assets_export_path_rbxm","manage_assets_export_selection_json","manage_assets_export_selection_rbxm","manage_assets_generate_model","manage_assets_generate_thumbnail","manage_assets_import_rbxm","manage_assets_info","manage_assets_insert","manage_assets_insert_free","manage_assets_insert_package","manage_assets_review_model","manage_assets_search","manage_assets_search_insert","manage_assets_upload_asset","manage_audio_pause","manage_audio_play","manage_audio_resume","manage_audio_set_listener","manage_audio_stop","manage_camera_screenshot","manage_effects_clear","manage_effects_emit","manage_effects_toggle","manage_lighting_atmosphere","manage_lighting_lighting","manage_lighting_mood","manage_lighting_sky","manage_lighting_terrain_props","manage_lighting_time","manage_open_cloud_assets_capabilities","manage_open_cloud_assets_credential_status","manage_open_cloud_assets_info","manage_open_cloud_assets_operation_status","manage_open_cloud_assets_preflight","manage_open_cloud_assets_update","manage_open_cloud_assets_upload","manage_physics_get_groups","manage_physics_register_group","manage_physics_set_collidable","manage_properties_mass_get","manage_properties_mass_set","manage_properties_modify_children","manage_properties_set_calculated","manage_properties_set_relative","manage_scripts_replace","manage_selection_add","manage_selection_context","manage_selection_details","manage_selection_remove","manage_selection_watch","manage_studio_play_pause","manage_studio_play_resume","manage_studio_play_start","manage_studio_play_status","manage_studio_play_stop","manage_studio_run_test","manage_studio_toggle_ui_preview","manage_sync_directions","manage_sync_history","manage_sync_progress","manage_sync_read_file","manage_sync_status_current_place","manage_sync_write_file","manage_terrain_clear_bounds","manage_terrain_clear_region","manage_terrain_colors_get","manage_terrain_colors_set","manage_terrain_fill_ball","manage_terrain_fill_block","manage_terrain_fill_cylinder","manage_terrain_fill_wedge","manage_terrain_generate","manage_terrain_read_voxel","manage_terrain_read_voxels","manage_terrain_replace_material","manage_terrain_smooth","manage_terrain_write_voxels","manage_tween_cancel","manage_tween_create","manage_tween_pause","manage_tween_play","manage_ui_check","manage_ui_create_tree","manage_ui_delete","manage_ui_design_brief","manage_ui_preview","manage_ui_update","mutate_instances_create_tree","mutate_instances_mass_create","mutate_instances_mass_delete","mutate_instances_mass_duplicate","mutate_instances_scatter","mutate_instances_smart_duplicate","query_instances_ancestors","query_instances_descendants","query_instances_file_tree","query_instances_project_structure","query_instances_search_property","query_instances_search_tag","spatial_query_analyze_walkable","spatial_query_bounds","spatial_query_check_placement","spatial_query_collision","spatial_query_find_flat","spatial_query_find_ground","spatial_query_find_space","spatial_query_find_spawn","spatial_query_multi_raycast","spatial_query_raycast","spatial_query_scan_area","spatial_query_snap_grid","spatial_query_spatial_map","system_info_place_info","system_info_services","workspace_state_changes","workspace_state_clear_cache","workspace_state_clear_history","workspace_state_metadata","workspace_state_scripts","workspace_state_selection_info","workspace_state_snapshot","workspace_state_sync","workspace_state_viewport"]),DA=new Set(["system_info_connection","system_info_ping","system_info_preflight","system_info_usage"]);function tr(t){return n9.has(t)?"pro":"basic"}bi();aS();import{readFile as Kve}from"node:fs/promises";import Jve from"node:path";import{createHash as Vve,randomUUID as LA}from"node:crypto";import{mkdir as wm,readFile as d9,readdir as p9,rename as f9,rm as Hve,stat as Wve,writeFile as pS}from"node:fs/promises";import Yt from"node:path";import{extname as $ve}from"node:path";import{constants as Dve}from"node:fs";import{access as Nve,stat as jve}from"node:fs/promises";var bm=20*1024*1024,cS=[{category:"image",assetType:"Image",folder:"images",extensions:[".png",".jpeg",".jpg",".bmp",".tga"],supportsContentUpdate:!1,contentTypes:{".png":"image/png",".jpeg":"image/jpeg",".jpg":"image/jpeg",".bmp":"image/bmp",".tga":"image/tga"}},{category:"decal",assetType:"Decal",folder:"decals",extensions:[".png",".jpeg",".jpg",".bmp",".tga"],supportsContentUpdate:!1,contentTypes:{".png":"image/png",".jpeg":"image/jpeg",".jpg":"image/jpeg",".bmp":"image/bmp",".tga":"image/tga"}},{category:"audio",assetType:"Audio",folder:"audio",extensions:[".mp3",".ogg",".wav",".flac"],supportsContentUpdate:!1,contentTypes:{".mp3":"audio/mpeg",".ogg":"audio/ogg",".wav":"audio/wav",".flac":"audio/flac"}},{category:"mesh",assetType:"Mesh",folder:"meshes",extensions:[".mesh"],supportsContentUpdate:!1,contentTypes:{".mesh":"application/octet-stream"}},{category:"model",assetType:"Model",folder:"models",extensions:[".fbx",".gltf",".glb",".rbxm",".rbxmx"],supportsContentUpdate:!0,contentTypes:{".fbx":"model/fbx",".gltf":"model/gltf+json",".glb":"model/gltf-binary",".rbxm":"model/x-rbxm",".rbxmx":"model/x-rbxm"}},{category:"video",assetType:"Video",folder:"videos",extensions:[".mp4",".mov"],supportsContentUpdate:!1,contentTypes:{".mp4":"video/mp4",".mov":"video/quicktime"}},{category:"animation",assetType:"Animation",folder:"animations",extensions:[".rbxm",".rbxmx"],supportsContentUpdate:!0,contentTypes:{".rbxm":"model/x-rbxm",".rbxmx":"model/x-rbxm"}}],Mve=new Map(cS.map(t=>[t.category,t]));function a9(t){if(!t)throw new Error("Open Cloud asset upload is disabled in WEPPY Dashboard settings.")}function oS(t,e){return t.split(e.apiKey).join("[redacted]")}function sS(t){let e=Mve.get(t);if(!e)throw new Error(`Unsupported asset category: ${t}`);return e}function lS(t){return sS(t)}async function jA(t,e,n=bm){let r=sS(t),i=$ve(e).toLowerCase(),a=r.contentTypes[i]??null,o=await jve(e),s=!0;try{await Nve(e,Dve.R_OK)}catch{s=!1}return{category:t,extension:i,contentType:a,formatValid:a!==null,sizeBytes:o.size,sizeValid:o.size<=n,maxFileSizeBytes:n,regularFile:o.isFile(),readable:s}}function o9(t,e){let n=t.creatorType??e.creatorType,r=t.creatorId??e.creatorId;if(!n||!r)throw new Error("creatorType and creatorId are required for Roblox Open Cloud asset upload/update.");return{...t,creatorType:n,creatorId:r}}async function s9(t,e,n){let r=await jA(t.category,e,n);if(!r.formatValid||!r.contentType)throw new Error(`Unsupported file extension ${r.extension||"(none)"} for ${t.category}.`);if(!r.regularFile)throw new Error("Asset path must reference a regular file.");if(!r.readable)throw new Error("Asset file is not readable.");if(!r.sizeValid)throw new Error(`Asset file is too large. Maximum size is ${n} bytes.`);return r.contentType}function c9(t){return typeof t.path=="string"&&t.path.startsWith("operations/")?t.path:null}function l9(t,e,n,r){let i={apiKey:t.apiKey,operationId:e};return n!==void 0&&(i.intervalMs=n),r!==void 0&&(i.timeoutMs=r),i}var wu=class{client;credentialStore;isOpenCloudUploadEnabled;maxFileSizeBytes;constructor(e){this.client=e.client,this.credentialStore=e.credentialStore,this.isOpenCloudUploadEnabled=e.isOpenCloudUploadEnabled,this.maxFileSizeBytes=e.maxFileSizeBytes??bm}getCapabilities(){return cS.map(({contentTypes:e,...n})=>n)}async uploadAsset(e){a9(this.isOpenCloudUploadEnabled());let n=await this.getRequiredCredential(),r=o9(e,n),i=sS(r.category),a=await s9(i,r.filePath,this.maxFileSizeBytes);try{let o={apiKey:n.apiKey,assetType:i.assetType,displayName:r.displayName,description:r.description??"",creatorType:r.creatorType,creatorId:r.creatorId,filePath:r.filePath,contentType:a};r.expectedPrice!==void 0&&(o.expectedPrice=r.expectedPrice);let s=await this.client.createAsset(o);if(r.waitForOperation){let c=c9(s);return c?await this.client.pollOperation(l9(n,c,r.operationPollIntervalMs,r.operationPollTimeoutMs)):s}return s}catch(o){throw new Error(oS(o instanceof Error?o.message:String(o),n))}}async updateAsset(e){a9(this.isOpenCloudUploadEnabled());let n=await this.getRequiredCredential(),r=o9(e,n),i=sS(r.category),a;if(r.filePath){if(!i.supportsContentUpdate)throw new Error(`${i.category} assets do not support content updates.`);a=await s9(i,r.filePath,this.maxFileSizeBytes)}try{let o={apiKey:n.apiKey,assetId:r.assetId,assetType:i.assetType,creatorType:r.creatorType,creatorId:r.creatorId};r.filePath&&(o.filePath=r.filePath),a!==void 0&&(o.contentType=a),r.displayName!==void 0&&(o.displayName=r.displayName),r.description!==void 0&&(o.description=r.description),r.updateMask!==void 0&&(o.updateMask=r.updateMask),r.expectedPrice!==void 0&&(o.expectedPrice=r.expectedPrice);let s=await this.client.updateAsset(o);if(r.waitForOperation){let c=c9(s);return c?await this.client.pollOperation(l9(n,c,r.operationPollIntervalMs,r.operationPollTimeoutMs)):s}return s}catch(o){throw new Error(oS(o instanceof Error?o.message:String(o),n))}}async getAsset(e){let n=await this.getRequiredCredential();try{let r={apiKey:n.apiKey,assetId:e.assetId};return e.readMask!==void 0&&(r.readMask=e.readMask),await this.client.getAsset(r)}catch(r){throw new Error(oS(r instanceof Error?r.message:String(r),n))}}async getOperation(e){let n=await this.getRequiredCredential();try{return await this.client.getOperation({apiKey:n.apiKey,operationId:e.operationId})}catch(r){throw new Error(oS(r instanceof Error?r.message:String(r),n))}}async getRequiredCredential(){let e=await this.credentialStore.getCredentialForUse();if(!e)throw new Error("Configure a Roblox Open Cloud API key in WEPPY Dashboard before using Open Cloud asset upload.");return e}};import u9 from"node:fs";import cn from"node:path";Zx();var Lve=/^asset_(image|decal|audio|mesh|model|video|animation)_\d+_[a-z0-9]+$/;function zve(t){if(!Number.isInteger(t)||t<0)throw new Error(`Invalid place ID: ${t}`)}function Uve(t,e){try{return u9.statSync(cn.join(t,e,".sync-meta.json")).isFile()}catch{return!1}}function Fve(t,e){zve(e.placeId);let n=`place_${e.placeId}`,r=e.placeName?Xl(e.placeName):"",i=r?`${n}_${r}`:n,a=[];try{let o=new RegExp(`^place_${e.placeId}(?:_.*)?$`);a=u9.readdirSync(t,{withFileTypes:!0}).filter(s=>s.isDirectory()&&o.test(s.name)).map(s=>s.name).sort()}catch{return i}return r&&a.includes(i)?i:a.find(o=>Uve(t,o))??(a.includes(i)?i:null)??a[0]??i}function MA(t){let e=cn.resolve(t.projectSyncRoot),n=lS(t.category).folder,r=t.scope.kind==="place"?cn.join(e,Fve(e,t.scope),"assets",n):cn.join(e,"shared-assets",n);return{root:r,inbox:cn.join(r,"inbox"),index:cn.join(r,".asset-library-index.json")}}function qve(t){let e=Lve.exec(t);return e?.[1]?e[1]:null}function xm(t,e){let n=qve(t);return n?e?n===e:!0:!1}function uS(t,e){if(!xm(t,e))throw new Error(`Invalid asset ID: ${t}`)}function wi(t,e){let n=cn.relative(cn.resolve(t),cn.resolve(e));return n===""||!n.startsWith("..")&&!cn.isAbsolute(n)}function Bve(t){uS(t.assetId,t.category);let e=MA(t),n=cn.resolve(e.root,t.assetId);if(!wi(e.root,n))throw new Error(`Invalid asset path for ${t.assetId}`);return n}function dS(t){let e=Bve(t),n=cn.resolve(e,t.relativeFileName);if(!wi(e,n))throw new Error(`Invalid asset file path for ${t.assetId}`);return n}function _m(t,e){return cn.relative(cn.resolve(t),cn.resolve(e)).split(cn.sep).join("/")}var m9=20*1024*1024,Zve=200;function g9(t,e){return t.kind!==e.kind?!1:t.kind==="shared"&&e.kind==="shared"?!0:t.kind==="place"&&e.kind==="place"&&t.placeId===e.placeId}function h9(t,e){let n=Yt.extname(t).toLowerCase(),r=lS(e);if(!r.extensions.includes(n))return null;let i=r.contentTypes[n];return i?{canonicalExt:n,mimeType:i}:null}function zA(t,e,n){if(e!=="image"&&e!=="decal")return!0;let r=Yt.extname(t).toLowerCase();return r===".png"?n.length>=8&&n[0]===137&&n[1]===80&&n[2]===78&&n[3]===71&&n[4]===13&&n[5]===10&&n[6]===26&&n[7]===10:r===".jpg"||r===".jpeg"?n.length>=3&&n[0]===255&&n[1]===216&&n[2]===255:r===".bmp"?n.length>=2&&n[0]===66&&n[1]===77:r===".tga"?n.length>0:!1}function y9(t){return Vve("sha256").update(t).digest("hex")}function fS(t){return t.now?.()??Date.now()}function Gve(t){return(t.randomId?.()??LA().replace(/-/g,"").slice(0,6)).toLowerCase().replace(/[^a-z0-9]/g,"").slice(0,12)||"asset"}function v9(t,e){let n=Math.floor(fS(t)/1e3);for(let r=0;r<20;r++){let i=Gve(t),a=r===0?`asset_${t.category}_${n}_${i}`:`asset_${t.category}_${n}_${i}${r}`;if(!e.has(a))return a}return`asset_${t.category}_${n}_${LA().replace(/-/g,"").slice(0,10)}`}function b9(t){let e=Yt.parse(t).name.trim();return e.length>0?e:t}function x9(t){if(t.mimeType!=="image/png")throw new Error("Asset Library preview must be an image/png thumbnail");if(Yt.basename(t.fileName).toLowerCase()!=="thumbnail.png")throw new Error("Asset Library preview file must be thumbnail.png");if(!zA("thumbnail.png","image",t.content))throw new Error("Asset Library preview is not a valid PNG file");return{fileName:"thumbnail.png",content:t.content}}async function UA(t,e){let n=`${t}.tmp.${LA().slice(0,8)}`;await pS(n,JSON.stringify(e,null,2),"utf8"),await f9(n,t)}async function _9(t,e){try{let n=await d9(Yt.join(e,"asset.json"),"utf8"),r=JSON.parse(n);return!xm(r.id,t.category)||r.category!==t.category||!g9(r.scope,t.scope)?null:r}catch{return null}}async function Sm(t,e){let n;try{n=await p9(e.root,{withFileTypes:!0})}catch(i){if(i?.code==="ENOENT")return[];throw i}let r=[];for(let i of n.sort((a,o)=>a.name.localeCompare(o.name))){if(!i.isDirectory()||!xm(i.name,t.category))continue;let a=Yt.join(e.root,i.name),o=await _9(t,a);o&&r.push(o)}return r.sort((i,a)=>a.createdAt.localeCompare(i.createdAt)||a.id.localeCompare(i.id))}async function Iu(t,e,n){if(uS(n.id,t.category),n.category!==t.category||!g9(n.scope,t.scope))throw new Error(`Asset metadata does not match library scope/category: ${n.id}`);let r=Yt.join(e.root,n.id);if(!wi(e.root,r))throw new Error(`Invalid asset path for ${n.id}`);await wm(r,{recursive:!0}),await UA(Yt.join(r,"asset.json"),n)}async function S9(t,e){await wm(t.root,{recursive:!0});let n={version:1,generatedAt:new Date().toISOString(),assets:e.map(r=>r.id)};await UA(t.index,n)}function aa(t,e,n){return{fileName:t,reason:e,message:n}}async function Ii(t){let e=MA(t);return await wm(e.inbox,{recursive:!0}),e}async function w9(t){let e=await Ii(t),n=await Sm(t,e);return await S9(e,n),n}async function Xt(t,e){uS(e,t.category);let n=await Ii(t),r=Yt.join(n.root,e);if(!wi(n.root,r))throw new Error(`Invalid asset path for ${e}`);let i=await _9(t,r);if(!i)throw new Error(`Asset not found: ${e}`);return i}async function Cu(t){let e=await Ii(t),n=await Sm(t,e),r={version:1,generatedAt:new Date().toISOString(),assets:n.map(i=>i.id)};return await UA(e.index,r),r}async function I9(t){let e=await Ii(t),n=await Sm(t,e),r=new Set(n.map(p=>p.id)),i=new Set(n.map(p=>p.file.sha256)),a=[],o=[],s=t.maxFileSizeBytes??m9,c=t.maxFilesPerRescan??Zve,l;try{l=await p9(e.inbox,{withFileTypes:!0})}catch(p){if(p?.code==="ENOENT")l=[];else throw p}let u=l.sort((p,f)=>p.name.localeCompare(f.name));for(let p=0;p<u.length;p++){let f=u[p];if(p>=c){o.push(aa(f.name,"maxFileCount","rescan file count limit exceeded"));continue}if(f.name.startsWith(".")){o.push(aa(f.name,"hidden","hidden or system file"));continue}if(f.isSymbolicLink()){o.push(aa(f.name,"symlink","symlink files are not followed"));continue}if(f.isDirectory()){o.push(aa(f.name,"nestedDirectory","nested directories are not scanned"));continue}if(!f.isFile()){o.push(aa(f.name,"unsupportedType","unsupported inbox entry type"));continue}let m=h9(f.name,t.category);if(!m){o.push(aa(f.name,"unsupportedType",`unsupported ${t.category} extension`));continue}let g=Yt.join(e.inbox,f.name),h=await Wve(g);if(h.size>s){o.push(aa(f.name,"oversized","asset file is larger than the configured limit"));continue}let v=await d9(g);if(!zA(f.name,t.category,v)){o.push(aa(f.name,"invalidSignature","file signature does not match the extension"));continue}let _=y9(v);if(i.has(_)){o.push(aa(f.name,"duplicate","asset content already exists in Asset Library"));continue}let x=v9(t,r);r.add(x),i.add(_);let w=Yt.join(e.root,x),I=`original${m.canonicalExt}`;await wm(w,{recursive:!0}),await f9(g,Yt.join(w,I));let N=new Date(fS(t)).toISOString(),E={version:1,id:x,category:t.category,scope:t.scope,status:"localOnly",displayName:b9(f.name),description:"",source:{kind:"generated",originalPath:_m(t.projectSyncRoot,g)},file:{original:I,preview:null,mimeType:m.mimeType,sha256:_,sizeBytes:h.size,width:null,height:null,durationMs:null},roblox:{uploaded:!1},usage:{lastScannedAt:null,scanSource:null,references:[]},createdAt:N,updatedAt:N};await Iu(t,e,E),a.push(E)}let d=await Sm(t,e);return await S9(e,d),{assets:d,adopted:a,skipped:o,adoptedCount:a.length,skippedCount:o.length}}async function C9(t){let e=await Ii(t),n=h9(t.originalFileName,t.category);if(!n)throw new Error(`Unsupported ${t.category} extension for Asset Library export`);let r=t.maxFileSizeBytes??m9;if(t.content.length>r)throw new Error("asset file is larger than the configured limit");if(!zA(t.originalFileName,t.category,t.content))throw new Error("file signature does not match the extension");let i=await Sm(t,e),a=y9(t.content),o=i.find(h=>h.file.sha256===a);if(o)return{asset:o,deduplicated:!0};let s=new Set(i.map(h=>h.id)),c=v9(t,s),l=Yt.join(e.root,c);if(!wi(e.root,l))throw new Error(`Invalid asset path for ${c}`);let u=`original${n.canonicalExt}`;await wm(l,{recursive:!0}),await pS(Yt.join(l,u),t.content);let d=null;if(t.preview){let h=x9(t.preview);d=h.fileName,await pS(Yt.join(l,h.fileName),h.content)}let p=new Date(fS(t)).toISOString(),f=t.roblox??{uploaded:!1},m=f.uploaded&&f.assetId?"uploaded":"localOnly",g={version:1,id:c,category:t.category,scope:t.scope,status:m,displayName:t.displayName?.trim()||b9(t.originalFileName),description:t.description??"",source:{...t.source,originalPath:_m(t.projectSyncRoot,Yt.join(l,u))},file:{original:u,preview:d,mimeType:n.mimeType,sha256:a,sizeBytes:t.content.length,width:null,height:null,durationMs:null},roblox:f,usage:{lastScannedAt:null,scanSource:null,references:[]},...t.rbxm?{rbxm:t.rbxm}:{},createdAt:p,updatedAt:p};return await Iu(t,e,g),await Cu(t),{asset:g,deduplicated:!1}}async function P9(t){let e=await Ii(t),n=await Xt(t,t.assetId),r=x9(t.preview),i=dS({...t,relativeFileName:r.fileName});await pS(i,r.content);let a={...n,file:{...n.file,preview:r.fileName},...n.rbxm&&t.rbxmThumbnail?{rbxm:{...n.rbxm,thumbnail:t.rbxmThumbnail}}:{},updatedAt:new Date(fS(t)).toISOString()};return await Iu(t,e,a),await Cu(t),{asset:a}}async function k9(t,e,n){let r=await Ii(t),i=await Xt(t,e),a={...i,displayName:typeof n.displayName=="string"?n.displayName:i.displayName,description:typeof n.description=="string"?n.description:i.description,source:{...i.source,...n.source?.agent!==void 0?{agent:n.source.agent}:{},...n.source?.contextId!==void 0?{contextId:n.source.contextId}:{},...n.source?.prompt!==void 0?{prompt:n.source.prompt}:{}},updatedAt:new Date().toISOString()};return await Iu(t,r,a),await Cu(t),a}async function E9(t,e,n){let r=await Ii(t),a={...await Xt(t,e),usage:n,updatedAt:new Date().toISOString()};return await Iu(t,r,a),await Cu(t),a}async function R9(t,e){let n=await Ii(t);await Xt(t,e);let r=Yt.join(n.root,e);if(!wi(n.root,r))throw new Error(`Invalid asset path for ${e}`);return await Hve(r,{recursive:!0}),await Cu(t),{assetId:e,removed:1}}async function wo(t){let e=await Ii(t);return await Iu(t,e,t.asset),await Cu(t),t.asset}async function Pu(t){let e=await Xt(t,t.assetId);return dS({...t,relativeFileName:e.file.original})}async function T9(t){let e=await Xt(t,t.assetId);return dS({...t,relativeFileName:e.file.preview??e.file.original})}var Yve="https://create.roblox.com/dashboard/creations/store",Xve="manage_assets_import_rbxm",qA="manage_assets_generate_thumbnail",Qve="manage_assets_review_model";var BA=new Set([Xve,qA]),VA=new Set(["manage_assets_export_selection_rbxm","manage_assets_export_path_rbxm",Qve]),ebe=new Set(["model","animation"]);function ot(t){return t&&typeof t=="object"?t:null}function tbe(t){if(typeof t!="string"||!ebe.has(t))throw new Error(`Unsupported Asset Library .rbxm round-trip category: ${String(t??"(missing)")}`);return t}function nbe(t){if(typeof t=="number"&&Number.isInteger(t)&&t>=0)return t;if(typeof t=="string"&&t.trim().length>0){let e=Number.parseInt(t,10);if(Number.isInteger(e)&&e>=0)return e}return null}function A9(t,e){for(let n of t.pluginClients.values())if(!(typeof n.placeId!="number"||!Number.isFinite(n.placeId))&&!(e!==void 0&&n.placeId!==e))return{placeId:n.placeId,...n.placeName?{placeName:n.placeName}:{}};return null}function HA(t,e){let n=Ct(t.config.dataDir),r=tbe(e.category),i=typeof e.scope=="string"?e.scope:"place",a=typeof e.assetLibraryAssetId=="string"&&e.assetLibraryAssetId.length>0?e.assetLibraryAssetId:void 0;if(i==="shared")return{projectSyncRoot:n,scope:{kind:"shared"},category:r,...a?{assetId:a}:{}};if(i!=="place")throw new Error(`Invalid Asset Library scope: ${i}`);let o=nbe(e.placeId),s=t.syncController?.getDefaultRuntimePlaceId()??null,c=o??s??A9(t)?.placeId??null;if(c===null)throw new Error("No placeId is available for Asset Library .rbxm round-trip.");let l=A9(t,c);return{projectSyncRoot:n,scope:{kind:"place",placeId:c,...l?.placeName?{placeName:l.placeName}:{}},category:r,...a?{assetId:a}:{}}}function rbe(t){if(Jve.extname(t.file.original).toLowerCase()!==".rbxm")throw new Error(`Asset Library Studio round-trip supports original.rbxm only. Unsupported original file: ${t.file.original}`)}function ibe(t,e){if(typeof t!="string"||t.trim().length===0)throw new Error(`${e} is missing`);return Buffer.from(t,"base64")}function abe(t,e){let n=ot(e),i={kind:n?.kind==="generation"||typeof t.prompt=="string"?"generated":"studioExport",originalPath:"studio:selection"};if(n){let a=typeof n.path=="string"?n.path:typeof n.kind=="string"?n.kind:void 0;a&&(i.originalPath=`studio:${a}`);let o=he(n.prompt,1e3);o&&(i.prompt=o)}if(!i.prompt){let a=he(t.prompt,1e3);a&&(i.prompt=a)}return typeof t.contextId=="string"&&(i.contextId=t.contextId),i}function N9(t){let e=ot(t);if(!e)return;let n={};typeof e.width=="number"&&(n.width=e.width),typeof e.height=="number"&&(n.height=e.height),typeof e.source=="string"&&(n.source=e.source),typeof e.error=="string"&&(n.error=e.error);let r=Im(e.attempts);return r.length>0&&(n.attempts=r),Object.keys(n).length>0?n:void 0}function he(t,e){return typeof t!="string"?null:t.slice(0,e)}function obe(t){if(typeof t!="string")return null;let e=t.trim();return/^\d+$/.test(e)?e:null}function O9(t){return`rbxassetid://${t}`}function $9(t){return`${Yve}/${t}/configure`}function D9(t){return`assets/${t}`}function br(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function j9(t){return Array.isArray(t)?t.slice(0,100).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.name,256),i=he(n.className,128),a=he(n.path,512);return r===null||i===null||a===null?[]:[{name:r,className:i,path:a}]}):[]}function sbe(t){let e=ot(t);if(!e)return{};let n={};for(let[r,i]of Object.entries(e).slice(0,100))typeof i!="number"||!Number.isFinite(i)||i<0||(n[r.slice(0,128)]=Math.floor(i));return n}function cbe(t){return Array.isArray(t)?t.slice(0,200).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.path,512),i=he(n.property,128),a=he(n.value,1024);if(r===null||i===null||a===null)return[];let o=he(n.assetId,64);return[{path:r,property:i,value:a,...o?{assetId:o}:{}}]}):[]}function Im(t){return Array.isArray(t)?t.slice(0,8).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.method,80),i=n.status==="success"||n.status==="failed"||n.status==="skipped"?n.status:null;if(r===null||i===null)return[];let a=he(n.message,512);return[{method:r,status:i,...a?{message:a}:{}}]}):[]}function lbe(t,e){let n=t.thumbnailMode==="auto"?"auto":"none";if(n==="none")return{mode:n,status:"skipped",message:"Thumbnail generation disabled"};let r=N9(e),i=ot(e),a=typeof i?.pngBase64=="string"&&i.pngBase64.length>0,o=typeof i?.base64Rgba=="string"&&i.base64Rgba.length>0&&i.format==="rgba8"&&typeof i.width=="number"&&typeof i.height=="number";if(r&&(a||o)){let s=br(r.width),c=br(r.height),l=Im(i?.attempts);return{mode:n,status:"generated",...s!==void 0?{width:s}:{},...c!==void 0?{height:c}:{},...typeof r.source=="string"?{source:r.source.slice(0,128)}:{},...l.length>0?{attempts:l}:{}}}if(r&&typeof r.error=="string"){let s=Im(ot(e)?.attempts);return{mode:n,status:"failed",message:r.error.slice(0,512),...s.length>0?{attempts:s}:{}}}return{mode:n,status:"skipped",message:"Thumbnail was not returned"}}function ube(t,e){let n=ot(t);if(!n)return e;let r=n.mode==="auto"||n.mode==="none"?n.mode:e.mode,i=n.status==="generated"||n.status==="skipped"||n.status==="failed"?n.status:e.status,a=he(n.message,512),o=br(n.width),s=br(n.height),c=he(n.source,128),l=Im(n.attempts);return{mode:r,status:i,...a?{message:a}:{},...o!==void 0?{width:o}:{},...s!==void 0?{height:s}:{},...c?{source:c}:{},...l.length>0?{attempts:l}:{}}}function FA(t,e=0){if(e>3)return;if(typeof t=="string")return t.slice(0,512);if(typeof t=="boolean")return t;if(typeof t=="number")return Number.isFinite(t)?t:void 0;if(Array.isArray(t))return t.slice(0,50).flatMap(i=>{let a=FA(i,e+1);return a===void 0?[]:[a]});let n=ot(t);if(!n)return;let r={};for(let[i,a]of Object.entries(n).slice(0,50)){let o=FA(a,e+1);o!==void 0&&(r[i.slice(0,128)]=o)}return r}function dbe(t){let e=ot(t),n=br(e?.x),r=br(e?.y),i=br(e?.z);if(!(n===void 0||r===void 0||i===void 0))return{x:n,y:r,z:i}}function pbe(t){return Array.isArray(t)?t.slice(0,100).flatMap(e=>{let n=ot(e);if(!n)return[];let r=n.severity==="info"||n.severity==="warning"||n.severity==="error"?n.severity:null,i=he(n.category,80),a=he(n.code,120),o=he(n.path,512),s=he(n.message,512);if(!r||i===null||a===null||o===null||s===null)return[];let c=he(n.suggestion,512);return[{severity:r,category:i,code:a,path:o,message:s,...c?{suggestion:c}:{}}]}):[]}function fbe(t){let e=ot(t);if(!e)return;let n=e.readiness==="ready"||e.readiness==="review"||e.readiness==="blocked"?e.readiness:null;if(!n)return;let r=FA(e.summary),i=he(e.reviewedAt,64),a=j9(e.roots);return{readiness:n,...i?{reviewedAt:i}:{},...a.length>0?{roots:a}:{},summary:ot(r)??{},findings:pbe(e.findings)}}function mbe(t){let e=ot(t);if(!e)return;let n={};for(let[r,i]of Object.entries(e).slice(0,16))typeof i=="string"&&(n[r.slice(0,128)]=i.slice(0,256)),typeof i=="number"&&Number.isFinite(i)&&(n[r.slice(0,128)]=i),typeof i=="boolean"&&(n[r.slice(0,128)]=i);return Object.keys(n).length>0?n:void 0}function gbe(t){let e=ot(t);if(!e)return;let n=he(e.provider,120);if(!n)return;let r=he(e.generatedAt,64),i=he(e.prompt,1e3),a=e.schemaMode==="predefined"||e.schemaMode==="custom"?e.schemaMode:void 0,o=e.predefinedSchema==="Body1"||e.predefinedSchema==="Car5"?e.predefinedSchema:void 0,s=Array.isArray(e.schemaGroups)?e.schemaGroups.slice(0,50).flatMap(f=>{let m=he(f,120);return m?[m]:[]}):void 0,c=dbe(e.requestedSize),l=br(e.maxTriangles),u=he(e.targetParent,512),d=he(e.path,512),p=mbe(e.metadata);return{provider:n,...r?{generatedAt:r}:{},...i?{prompt:i}:{},...a?{schemaMode:a}:{},...o?{predefinedSchema:o}:{},...s&&s.length>0?{schemaGroups:s}:{},...c?{requestedSize:c}:{},...l!==void 0?{maxTriangles:Math.floor(l)}:{},...typeof e.generateTextures=="boolean"?{generateTextures:e.generateTextures}:{},...u?{targetParent:u}:{},...d?{path:d}:{},...p?{metadata:p}:{}}}function hbe(t){return Array.isArray(t)?t.slice(0,100).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.path,512),i=n.assetType==="Mesh"||n.assetType==="Image"||n.assetType==="Model"?n.assetType:null,a=n.status==="uploaded"||n.status==="failed"?n.status:null;if(r===null||i===null||a===null)return[];let o=he(n.assetId,64),s=he(n.assetUri,128),c=n.creatorType==="user"||n.creatorType==="group"?n.creatorType:void 0,l=he(n.creatorId,64),u=he(n.sourceProperty,128),d=he(n.uploadedAt,64),p=he(n.message,512);return[{path:r,assetType:i,status:a,...o?{assetId:o}:{},...s?{assetUri:s}:{},...c?{creatorType:c}:{},...l?{creatorId:l}:{},...u?{sourceProperty:u}:{},...d?{uploadedAt:d}:{},...p?{message:p}:{}}]}):[]}function ybe(t){let e=ot(t);if(!e||e.uploaded!==!0)return;let n=obe(e.assetId);if(!n)return;let r=he(e.uploadedAt,64)??new Date().toISOString(),i=e.creatorType==="user"||e.creatorType==="group"?e.creatorType:void 0,a=he(e.creatorId,64);return{uploaded:!0,assetId:n,assetUri:O9(n),assetWebUrl:$9(n),remotePath:D9(n),uploadedAt:r,uploadAttempts:[{startedAt:r,finishedAt:r,status:"uploaded",assetRole:"primary",...i?{creatorType:i}:{},...a?{creatorId:a}:{},assetId:n,assetUri:O9(n),assetWebUrl:$9(n),remotePath:D9(n)}]}}function vbe(t){let e=ot(t.value),n=j9(e?.roots),r=sbe(e?.classCounts),i=cbe(e?.resourceReferences),a=fbe(e?.review),o=gbe(e?.generation),s=hbe(e?.studioUploads),c=br(e?.exportedCount)??br(t.exportedCount)??n.length;return{exportedCount:Math.max(0,Math.floor(c)),roots:n,classCounts:r,resourceReferences:i,thumbnail:ube(e?.thumbnail,t.fallbackThumbnail),...a?{review:a}:{},...o?{generation:o}:{},...s.length>0?{studioUploads:s}:{}}}function bbe(t){return t.length>=8&&t[0]===137&&t[1]===80&&t[2]===78&&t[3]===71&&t[4]===13&&t[5]===10&&t[6]===26&&t[7]===10}function M9(t){let e=ot(t);if(!e)return;let n=null;if(typeof e.pngBase64=="string"&&e.pngBase64.length>0?n=Buffer.from(e.pngBase64,"base64"):typeof e.base64Rgba=="string"&&e.base64Rgba.length>0&&e.format==="rgba8"&&typeof e.width=="number"&&typeof e.height=="number"&&(n=Buffer.from(i9(e.base64Rgba,e.width,e.height),"base64")),!!n){if(!bbe(n))throw new Error("Thumbnail payload is not a valid PNG image.");return{fileName:"thumbnail.png",content:n,mimeType:"image/png"}}}function xbe(t,e){let n=e instanceof Error?e.message:String(e);return t.thumbnail.status!=="generated"?t:{...t,thumbnail:{...t.thumbnail,status:"failed",message:`Thumbnail payload could not be stored: ${n}`.slice(0,512)}}}async function L9(t){if(!BA.has(t.command))return t.params;let e=HA(t.ctx,t.params);if(!e.assetId)throw new Error("assetLibraryAssetId is required for Asset Library .rbxm round-trip.");let n=await Xt(e,e.assetId);rbe(n);let r=await Pu({...e,assetId:n.id}),i=await Kve(r);return{...t.params,__assetLibraryRbxmBase64:i.toString("base64"),__assetLibraryOriginalFile:n.file.original}}async function z9(t){if(!VA.has(t.command)||!t.result.success)return t.result;let e=ot(t.result.data);if(!e||typeof e.rbxmBase64!="string"||e.rbxmBase64.trim().length===0)return t.result;let n=HA(t.ctx,t.params),r=ibe(e.rbxmBase64,"Asset Library .rbxm export payload"),i=typeof t.params.displayName=="string"?t.params.displayName:void 0,a=typeof t.params.description=="string"?t.params.description:void 0,o=`${i?.trim()||"studio-export"}.rbxm`,s,c=null;try{s=M9(e.thumbnail)}catch(f){c=f,s=void 0}let l=vbe({value:e.rbxm,exportedCount:e.exportedCount,fallbackThumbnail:lbe(t.params,e.thumbnail)});c&&(l=xbe(l,c));let u=ybe(e.roblox),d=await C9({projectSyncRoot:n.projectSyncRoot,scope:n.scope,category:n.category,originalFileName:o,content:r,...i!==void 0?{displayName:i}:{},...a!==void 0?{description:a}:{},source:abe(t.params,e.source),...s?{preview:s}:{},rbxm:l,...u?{roblox:u}:{}}),p=N9(e.thumbnail);return{...t.result,data:{asset:d.asset,deduplicated:d.deduplicated,...typeof e.byteLength=="number"?{byteLength:e.byteLength}:{},...typeof e.exportedCount=="number"?{exportedCount:e.exportedCount}:{},...e.source!==void 0?{source:e.source}:{},...p?{thumbnail:p}:{}}}}async function U9(t){if(!t.result.success)return t.result;let e=ot(t.result.data),n=ot(e?.thumbnail),r;try{r=M9(n)}catch(d){return{...t.result,success:!1,error:d instanceof Error?d.message:String(d)}}if(!n||!r)return{...t.result,success:!1,error:typeof n?.error=="string"?n.error:"Thumbnail payload is missing from Asset Library thumbnail generation result."};let i=br(n.width),a=br(n.height),o=he(n.source,128),s=Im(n.attempts),c={mode:"auto",status:"generated",...i!==void 0?{width:i}:{},...a!==void 0?{height:a}:{},...o?{source:o}:{},...s.length>0?{attempts:s}:{}},l=HA(t.ctx,t.params);if(!l.assetId)throw new Error("assetLibraryAssetId is required for Asset Library thumbnail generation.");let u=await P9({projectSyncRoot:l.projectSyncRoot,scope:l.scope,category:l.category,assetId:l.assetId,preview:r,rbxmThumbnail:c});return{...t.result,data:{asset:u.asset,...i!==void 0?{width:i}:{},...a!==void 0?{height:a}:{},...o?{source:o}:{}}}}function _be(t){if(t===null||typeof t!="object")return;let e=t.proFallback;if(e===null||typeof e!="object")return;let n=e;if(typeof n.executedCommand!="string")return;let r=Array.isArray(n.alternatives)?n.alternatives.filter(i=>typeof i=="string"):void 0;return{executedCommand:n.executedCommand,...typeof n.requestedCommand=="string"?{requestedCommand:n.requestedCommand}:{},...r?{alternatives:r}:{}}}var Sbe=/^Pro action '[^']+' is blocked in Basic mode\. Basic fallback '([^']+)' failed: (.*)$/s,wbe=/^Pro action '[^']+' is blocked in Basic mode\.(?! Basic fallback ')/,Ibe=/instance not found|not found in|parent not found/,Cbe=/is required|missing required/,Pbe=/unknown action|unknown command/,kbe=/must be|invalid|cannot/;function Ebe(t){let e=Sbe.exec(t);return e?{fallbackCommand:e[1],reason:e[2]}:null}function Rbe(t){return wbe.test(t)}function Tbe(t){let e=t.toLowerCase();return Ibe.test(e)?"not_found":Cbe.test(e)?"missing_param":Pbe.test(e)?"unknown_action":kbe.test(e)?"validation":"other"}function WA(t){return t.errorType==="bridge_error"||t.errorType==="command_timeout"||t.errorType==="plugin_runtime"||t.errorType==="exception"||t.errorType==="device_blocked"||t.failureOrigin==="bridge"||t.failureOrigin==="plugin_runtime"||t.failureOrigin==="server_exception"||t.failureOrigin==="product_bug"||t.failureOrigin==="unknown"||t.recoverability==="retry"||t.recoverability==="wait_connection"||t.recoverability==="unknown"?"error":"warning"}function ku(t){if(t.resultSuccess){let e=_be(t.resultData);return e?{kind:"success_fallback",fallbackCommand:e.executedCommand,...e.alternatives?{alternatives:e.alternatives}:{}}:{kind:"success_ok"}}if(!t.resultError)return{kind:"error"};if(t.tier==="pro"){let e=Ebe(t.resultError);if(e)return{kind:"blocked_fallback_failed",fallbackCommand:e.fallbackCommand,blockedDetail:Tbe(e.reason)};if(Rbe(t.resultError))return{kind:"blocked_unsupported"}}return t.failureClassification?{kind:WA(t.failureClassification)}:{kind:"error"}}function Se(t,e,n,r,i={}){return{errorType:t,errorDetail:e,failureOrigin:n,recoverability:r,...i}}function Abe(t){let e=t.toLowerCase();return/^\s*compilation error:/.test(e)?Se("execution_failed","compile_error","agent_request","code_fix",{validationStage:"plugin_handler"}):/^\s*result too large:/.test(e)?Se("execution_failed","result_too_large","agent_request","code_fix",{validationStage:"plugin_handler"}):/^\s*execution timed out after/.test(e)?Se("execution_failed","execution_timeout","agent_request","code_fix",{validationStage:"plugin_handler"}):/potentially dangerous infinite loop|blocked in sandbox|access to .* is blocked|forbidden|not allowed|cannot access/.test(e)?Se("execution_failed","blocked_source","roblox_policy","code_fix",{validationStage:"plugin_handler"}):null}function Obe(t){let e=t.toLowerCase();return/startline and endline must be provided together/.test(e)||/startline must be a positive integer/.test(e)||/endline must be a positive integer/.test(e)||/endline must be >= startline/.test(e)?Se("execution_failed","validation","agent_request","fix_params",{validationStage:"schema"}):null}function F9(t){let e=t.toLowerCase();return/upstream_server_down/.test(e)?Se("bridge_error","upstream_down","bridge","wait_connection"):/^http [45]\d\d/.test(e)?Se("bridge_error","http_error","bridge","retry"):/duplicate request\s*id/.test(e)?Se("bridge_error","duplicate_request_id","bridge","code_fix"):/timeout/.test(e)?Se("command_timeout","timeout","bridge","retry"):/econnrefused|socket hang up|econnreset|epipe|network/.test(e)?Se("bridge_error","connection","bridge","wait_connection"):/abort/.test(e)?Se("command_timeout","aborted","bridge","retry"):/runtime error|traceback|attempt to/.test(e)?Se("plugin_runtime","runtime_error","plugin_runtime","code_fix"):/created instance, but failed to set \d+ propert/.test(e)?Se("execution_failed","property_apply_failed","agent_request","fix_params",{validationStage:"plugin_handler",partialSuccess:"true"}):/failed to set property/.test(e)?Se("execution_failed","property_apply_failed","agent_request","fix_params",{validationStage:"plugin_handler"}):/parent(?: instance)? not found/.test(e)?Se("execution_failed","parent_not_found","agent_request","fix_params",{validationStage:"plugin_handler"}):/(?:instance|path|root|source instance|ancestor instance) not found|target\s+(?:path\s+)?(?:['"`][^'"`]+['"`]\s+)?not found|not found in|no synced file found for instance/.test(e)?Se("execution_failed","not_found","user_project_state","fix_params",{validationStage:"plugin_handler"}):/is required|missing required/.test(e)?Se("execution_failed","missing_param","agent_request","fix_params",{validationStage:"schema"}):/invalid classname|invalid class/.test(e)?Se("execution_failed","invalid_class","agent_request","fix_params",{validationStage:"plugin_handler"}):/unknown action|unknown command/.test(e)?Se("execution_failed","unknown_action","agent_request","fix_params",{validationStage:"dispatcher"}):/failed to insert asset/.test(e)?Se("execution_failed","asset_error","roblox_policy","fix_params",{validationStage:"roblox_api"}):/failed to read property|property access denied/.test(e)?Se("execution_failed","property_error","agent_request","fix_params",{validationStage:"plugin_handler"}):/forbidden (?:path|parent path)|exceeds (?:total lines|max(?:imum)?(?: length)?)|is not (?:a|an) /.test(e)?Se("execution_failed","validation","agent_request","fix_params",{validationStage:"plugin_handler"}):/sync controller not available|project sync is not initialized|no active sync place|not found in sync cache/.test(e)?Se("execution_failed","sync_not_ready","user_project_state","wait_connection",{validationStage:"preflight"}):/cannot capture edit-mode screenshot while a playtest is active|play-mode screenshot capture is not supported/.test(e)?Se("execution_failed","unsupported_context","roblox_policy","no_retry",{validationStage:"preflight"}):/editableimage api is not enabled|allow mesh \/ image apis|allow http requests/.test(e)?Se("execution_failed","feature_disabled","roblox_policy","no_retry",{validationStage:"preflight"}):/must be|invalid|cannot/.test(e)?Se("execution_failed","validation","agent_request","fix_params",{validationStage:"plugin_handler"}):Se("execution_failed","other","unknown","unknown")}function Eu(t,e){if(t==="manage_scripts_get_source"){let r=Obe(e);if(r)return r}if(t==="execute_luau"){let r=Abe(e);if(r)return r}let n=F9(e);return t==="execute_luau"&&n.errorDetail==="runtime_error"&&/^\s*runtime error:/i.test(e)?Se("execution_failed","runtime_error","agent_request","code_fix"):n}function q9(t){let n=(t instanceof Error?t.message:String(t)).toLowerCase();return/timeout/.test(n)?Se("command_timeout","timeout","bridge","retry"):/econnrefused|socket hang up|network|econnreset|epipe/.test(n)?Se("bridge_error","connection","bridge","wait_connection"):/eaddrinuse/.test(n)?Se("bridge_error","port_in_use","bridge","no_retry"):Se("exception","unexpected","server_exception","code_fix")}hS();import{randomBytes as zbe}from"node:crypto";var Ube=["manage_ui_create_tree","manage_ui_update","manage_ui_delete"],K9=["manage_ui_preview","manage_ui_check"],Fbe=["game_genre","ui_role","style_family","layout_family","device_policy","safe_area_policy","existing_ui_strategy"];function e1(t){return t&&typeof t=="object"?t:void 0}function XA(t){return typeof t=="number"&&Number.isFinite(t)?t:0}function yS(t){let e=e1(t);if(!e)return;let n={};for(let r of Fbe){let i=e[r];typeof i=="string"&&i.trim().length>0&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}function QA(t){let e=yS(t.qualityPlanSummary);if(e)return e;let n=e1(t.contextSummary),r=yS(n?.qualityPlanSummary);if(r)return r;let i=yS(n?.qualityPlan);if(i)return i;let a=yS(n?.quality_plan);if(a)return a}function J9(t,e){return e?{...t??{},...e}:t}function qbe(t){return typeof t=="string"?{snapshotId:t}:t&&typeof t=="object"?{snapshotId:typeof t.snapshotId=="string"?t.snapshotId:null,...t.designCheckSummary!==void 0&&{designCheckSummary:t.designCheckSummary},...t.capturedAt!==void 0&&{capturedAt:t.capturedAt}}:{snapshotId:null}}function Y9(t,e,n,r,i){if(!e)return;let a=XA(e.priority_high),o=XA(e.priority_medium),s=XA(e.priority_low),c=typeof e.total=="number"&&Number.isFinite(e.total)?e.total:a+o+s,l=n??(typeof e.target=="string"?e.target:void 0);return{source:t,...l!==void 0&&{targetPath:l},...typeof r=="string"&&{snapshotId:r},...i!==void 0&&{capturedAt:i},priority_high:a,priority_medium:o,priority_low:s,total:c}}function X9(t,e){if(!e)return t;if(!t)return e;let n=t.targetPath===e.targetPath?t.targetPath:void 0,r=t.snapshotId===e.snapshotId?t.snapshotId:void 0;return{source:e.source,...n!==void 0&&{targetPath:n},...r!==void 0&&{snapshotId:r},...e.capturedAt!==void 0&&{capturedAt:e.capturedAt},priority_high:t.priority_high+e.priority_high,priority_medium:t.priority_medium+e.priority_medium,priority_low:t.priority_low+e.priority_low,total:t.total+e.total}}function Bbe(t){let e=e1(t);if(e)for(let n of["userMessage","intent","expectedBehavior"]){let r=e[n];if(typeof r=="string"&&r.trim().length>0)return r.trim().slice(0,80)}}function Vbe(){return{source:"unavailable",priority_high:0,priority_medium:0,priority_low:0,total:0}}function Q9(t){let e=t.now??Date.now,n=null,r=null,i=u=>`${u}_${e()}_${zbe(3).toString("hex")}`,a=()=>{r&&(clearTimeout(r),r=null)},o=()=>{a(),r=setTimeout(()=>{c("idle_timeout")},t.idleMs)},s=async u=>{try{return qbe(await t.capturePreview(u))}catch{return{snapshotId:null}}},c=async u=>{if(!n)return;a();let d=n;n=null;let p={},f;for(let h of d.affectedPaths)if(d.afterSnapshotsPathPolicy[h]==="skip")p[h]=null;else{let v=await s(h);p[h]=v.snapshotId,f=X9(f,Y9("after_snapshot",v.designCheckSummary,h,v.snapshotId,v.capturedAt))}let m=f??d.latestDesignCheckSummary??Vbe(),g={requestId:d.requestId,...d.contextId!==void 0&&{contextId:d.contextId},...d.label!==void 0&&{label:d.label},startedAt:d.startedAtIso,closedAt:new Date(e()).toISOString(),closeReason:u,ok:d.ok,affectedPaths:Array.from(d.affectedPaths).sort(),mutationCount:d.mutationCount,beforeSnapshots:d.beforeSnapshots,afterSnapshots:p,childMutationIds:d.childMutationIds,...d.qualityPlanSummary!==void 0&&{qualityPlanSummary:d.qualityPlanSummary},postChangeDesignCheckSummary:m};await W9(t.placeDir,g)},l=u=>({requestId:i("req"),contextId:u.contextId,label:Bbe(u.contextSummary),startedAtIso:new Date(e()).toISOString(),startedAtMs:e(),affectedPaths:new Set,beforeSnapshots:{},afterSnapshotsPathPolicy:{},childMutationIds:[],mutationCount:0,ok:!0,qualityPlanSummary:QA(u),latestDesignCheckSummary:void 0,pendingMutation:void 0});return{async beforeMutation(u){if(K9.includes(u.command)){if(n){let p=i("mut");n.qualityPlanSummary=J9(n.qualityPlanSummary,QA(u)),n.pendingMutation={mutationId:p,startedMs:e(),args:u}}return}if(!Ube.includes(u.command))return;n&&n.contextId!==u.contextId?await c("context_change"):n&&a(),n||(n=l(u)),n.qualityPlanSummary=J9(n.qualityPlanSummary,QA(u)),u.targetPath&&!(u.targetPath in n.beforeSnapshots)&&(n.affectedPaths.add(u.targetPath),u.command==="manage_ui_create_tree"?n.beforeSnapshots[u.targetPath]=null:n.beforeSnapshots[u.targetPath]=(await s(u.targetPath)).snapshotId,u.command==="manage_ui_delete"?n.afterSnapshotsPathPolicy[u.targetPath]="skip":u.targetPath in n.afterSnapshotsPathPolicy||(n.afterSnapshotsPathPolicy[u.targetPath]="capture"));let d=i("mut");n.pendingMutation={mutationId:d,startedMs:e(),args:u}},async afterMutation(u){if(!n?.pendingMutation)return;let{mutationId:d,args:p}=n.pendingMutation,f={mutationId:d,requestId:n.requestId,ts:new Date(e()).toISOString(),command:p.command,origin:p.origin,...p.targetPath!==void 0&&{targetPath:p.targetPath},...p.briefId!==void 0&&{briefId:p.briefId},...u.diffSummary!==void 0&&{diffSummary:u.diffSummary},...u.changeDetails!==void 0&&{changeDetails:u.changeDetails},ok:u.ok,...u.error!==void 0&&{error:u.error},durationMs:u.durationMs};if(await Z9(t.placeDir,f),n.pendingMutation=void 0,K9.includes(p.command)){n.latestDesignCheckSummary=X9(n.latestDesignCheckSummary,Y9("check_results",u.designCheckSummary,p.targetPath,u.snapshotId,u.capturedAt));return}if(n.mutationCount++,n.childMutationIds.push(d),u.ok||(n.ok=!1),!n.contextId){await c("legacy_single");return}o()},async flushNow(){n&&await c("explicit")}}}var y3=100,Ixe=12e4,Cxe=15e3,v3=new Set(["manage_ui_create_tree","manage_ui_update","manage_ui_delete"]);function Pxe(t,e){return`License required for internal command ${t}. ${e??"Activate Pro license to use this feature."}`}var kxe={Text:{category:"text",label:"\uD14D\uC2A4\uD2B8"},PlaceholderText:{category:"text",label:"\uD50C\uB808\uC774\uC2A4\uD640\uB354"},TextColor3:{category:"color",label:"\uAE00\uC790\uC0C9"},BackgroundColor3:{category:"color",label:"\uBC30\uACBD\uC0C9"},BorderColor3:{category:"color",label:"\uD14C\uB450\uB9AC\uC0C9"},ImageColor3:{category:"color",label:"\uC774\uBBF8\uC9C0\uC0C9"},Size:{category:"size",label:"\uC0AC\uC774\uC988"},TextSize:{category:"size",label:"\uAE00\uC790 \uD06C\uAE30"},Position:{category:"layout",label:"\uC704\uCE58"},AnchorPoint:{category:"layout",label:"\uC575\uCEE4"},Rotation:{category:"layout",label:"\uD68C\uC804"},LayoutOrder:{category:"layout",label:"\uB808\uC774\uC544\uC6C3 \uC21C\uC11C"},Visible:{category:"state",label:"\uD45C\uC2DC \uC0C1\uD0DC"},Active:{category:"state",label:"\uD65C\uC131 \uC0C1\uD0DC"},Interactable:{category:"state",label:"\uC0C1\uD638\uC791\uC6A9 \uC0C1\uD0DC"},Selectable:{category:"state",label:"\uC120\uD0DD \uAC00\uB2A5"},Enabled:{category:"state",label:"\uD65C\uC131\uD654"},Image:{category:"asset",label:"\uC774\uBBF8\uC9C0"},Texture:{category:"asset",label:"\uD14D\uC2A4\uCC98"},SoundId:{category:"asset",label:"\uC0AC\uC6B4\uB4DC"}},Exe={text:"\uD14D\uC2A4\uD2B8",color:"\uCEEC\uB7EC",size:"\uC0AC\uC774\uC988",layout:"\uB808\uC774\uC544\uC6C3",state:"\uC0C1\uD0DC",asset:"\uC5D0\uC14B",property:"\uC18D\uC131"},Rxe=Object.entries(Zs).reduce((t,[e,n])=>{for(let r of n.validActions)t[`${e}_${r}`]=e;return t},{});function d3(t){return{toolName:Rxe[t]||t,commandName:t}}function p3(t,e){if(typeof t.contextId=="string"||!e||typeof e!="object")return t;let n=e.contextId;return typeof n=="string"?{...t,contextId:n}:t}function vS(t,e){if(t!=="manage_sync_status_current_place")return e;let{placeId:n,...r}=e;return r}function Txe(t,e){let n=e.routing;return{requestId:t,success:!1,error:e.message,errorCode:e.code,routing:n,data:{routing:n}}}async function Axe(t,e){let n=t.syncController;if(!n)return null;try{let r=e.placeId,i=n.getDefaultRuntimePlaceId(),a=null;if(typeof r=="number"&&Number.isFinite(r))a=r;else if(typeof r=="string"&&r.trim().length>0){let s=Number.parseInt(r,10);Number.isFinite(s)&&(a=s)}if(a===null&&(a=i),a===null||!Number.isFinite(a))return null;let o=a===i?n.getDefaultRuntimePlaceName():null;return typeof o=="string"&&o.length>0?await n.config.resolvePlaceRoot(a,o):n.config.getPlaceRoot(a)}catch{return null}}function Oxe(t){let e=t.tree;if(!e||typeof e!="object")return;let n=e,r=typeof n.name=="string"&&n.name.length>0?n.name:void 0;return r?`${typeof n.parent=="string"&&n.parent.length>0?n.parent:"StarterGui"}.${r}`:void 0}function $xe(t,e){let n=e.targetPath;if(typeof n=="string"&&n.length>0)return n;if(t==="manage_ui_create_tree")return Oxe(e)}function Dxe(t){let e=kxe[t];if(e)return e;let n=t.toLowerCase();return n.includes("color")?{category:"color",label:"\uC0C9\uC0C1"}:t==="Size"||n.endsWith("size")||n.includes("scale")?{category:"size",label:"\uC0AC\uC774\uC988"}:n.includes("position")||n.includes("anchor")||n.includes("rotation")||n.includes("layout")?{category:"layout",label:"\uB808\uC774\uC544\uC6C3"}:n.includes("visible")||n.includes("active")||n.includes("enabled")||n.includes("selectable")||n.includes("interactable")?{category:"state",label:"\uC0C1\uD0DC"}:n.includes("image")||n.includes("texture")||n.includes("sound")||n.includes("asset")?{category:"asset",label:"\uC5D0\uC14B"}:n.includes("text")||n.includes("placeholder")?{category:"text",label:"\uD14D\uC2A4\uD2B8"}:{category:"property",label:t}}function f3(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function Nxe(t){if(!t||typeof t!="object")return new Map;let e=t,n=e.changed_properties??e.changedProperties;if(!Array.isArray(n))return new Map;let r=new Map;for(let i of n){if(!i||typeof i!="object")continue;let a=i,o=a.property;if(typeof o!="string"||o.length===0)continue;let s=f3(a,"before"),c=f3(a,"after");r.set(o,{...s&&{before:a.before},...c&&{after:a.after},hasBefore:s,hasAfter:c})}return r}function b3(t,e){let r=t.changes?.properties;if(!r||typeof r!="object")return;let i=Nxe(e),a=Object.entries(r).map(([o,s])=>{let c=Dxe(o),l=i.get(o),u={property:o,category:c.category,label:c.label,after:l?.hasAfter?l.after:s};return l?.hasBefore&&(u.before=l.before),u});return a.length>0?a:void 0}function x3(t){if(!t||t.length===0)return;let e=new Map;for(let i of t)e.set(i.category,(e.get(i.category)??0)+1);let r=["text","color","size","layout","state","asset","property"].map(i=>{let a=e.get(i)??0;return a>0?`${Exe[i]} ${a}\uAC1C`:null}).filter(i=>i!==null);return r.length>0?`${r.join(", ")} \uBCC0\uACBD`:void 0}function m3(t,e){if(t==="manage_ui_update"){let n=e.changes,r=x3(b3(e));if(r)return r;let i=n?.properties?Object.keys(n.properties).length:0,a=Array.isArray(n?.addChildren)?n.addChildren.length:0,o=Array.isArray(n?.removeChildren)?n.removeChildren.length:0;return`${i} props, +${a}, -${o}`}if(t==="manage_ui_create_tree")return"tree \uC0DD\uC131";if(t==="manage_ui_delete")return"\uC81C\uAC70\uB428"}function Nm(t){return t&&typeof t=="object"?t:void 0}function bS(t,e){let n=t[e];return typeof n=="number"&&Number.isFinite(n)?n:0}function _3(t){let e=Nm(t),n=Nm(e?.design_check_summary);if(n)return{priority_high:bS(n,"priority_high"),priority_medium:bS(n,"priority_medium"),priority_low:bS(n,"priority_low"),total:bS(n,"total"),...typeof n.scope=="string"&&{scope:n.scope},...typeof n.target=="string"&&{target:n.target}}}function S3(t){let n=Nm(t)?.snapshot_id;return typeof n=="string"?n:null}function g3(t){if(typeof t=="string"&&t.trim().length>0)return t;if(typeof t=="number"&&Number.isFinite(t)){let e=t<1e10?t*1e3:t;return new Date(e).toISOString()}}function w3(t){let e=Nm(t),n=Nm(e?.meta);return g3(n?.captured_at)??g3(n?.evaluated_at)}function jxe(t,e){let n=t.uiStudioRecorders.get(e);if(n)return n;let r=Q9({placeDir:e,idleMs:Cxe,capturePreview:async i=>{try{let a=await xr(t,"manage_ui_preview",{targetPath:i},_S());if(!a.success||!a.data||typeof a.data!="object")return null;let o=_3(a.data),s=w3(a.data);return{snapshotId:S3(a.data),...o!==void 0&&{designCheckSummary:o},...s!==void 0&&{capturedAt:s}}}catch{return null}}});return t.uiStudioRecorders.set(e,r),r}async function Mxe(t,e,n){if(!v3.has(e))return null;let r=await Axe(t,n);if(!r)return null;let i=jxe(t,r),a=e,o=typeof n.contextId=="string"?n.contextId:void 0,s=n.contextSummary,c=s!==void 0&&typeof s=="object"?s:void 0,l=$xe(a,n),u=typeof n.briefId=="string"?n.briefId:void 0,d={command:a,...o!==void 0&&{contextId:o},...c!==void 0&&{contextSummary:c},...l!==void 0&&{targetPath:l},...u!==void 0&&{briefId:u},origin:n.__origin==="dashboard"?"dashboard":"ai"};try{return await i.beforeMutation(d),{recorder:i,command:a,params:n,startedAt:Date.now()}}catch(p){return y.debug("UI Studio recorder beforeMutation \uC2E4\uD328 (\uBB34\uC2DC)",{error:p}),null}}async function h3(t,e){if(t)try{let n=t.command==="manage_ui_update"?b3(t.params,e.data):void 0,r=t.command==="manage_ui_update"?x3(n)??m3(t.command,t.params):m3(t.command,t.params),i=_3(e.data),a=S3(e.data),o=w3(e.data);await t.recorder.afterMutation({ok:e.success,durationMs:Date.now()-t.startedAt,...r!==void 0&&{diffSummary:r},...n!==void 0&&{changeDetails:n},...e.error!==void 0&&{error:e.error},...i!==void 0&&{designCheckSummary:i},...a!==null&&{snapshotId:a},...o!==void 0&&{capturedAt:o}})}catch(n){y.debug("UI Studio recorder afterMutation \uC2E4\uD328 (\uBB34\uC2DC)",{error:n})}}async function xS(t,e,n,r,i,a){if(!t.historyManager)return;let o=!i.success&&i.error?Eu(n,i.error):void 0,s=ku({resultSuccess:i.success,resultData:i.data,resultError:i.error,tier:tr(n),...o?{failureClassification:o}:{}});if(i.success){let u=s.kind==="success_fallback"&&i.data&&typeof i.data=="object"?{...i.data,outcomeStatus:"fallback",requestedCommand:n,executedCommand:s.fallbackCommand,...s.alternatives?{alternatives:s.alternatives}:{}}:i.data,d=vS(n,r);i.routing?await t.historyManager.recordSuccess(e,d,u,a,n,void 0,i.routing):await t.historyManager.recordSuccess(e,d,u,a,n);return}if(s.kind==="blocked_unsupported"){await t.historyManager.recordBlockedOutcome(e,vS(n,r),i.error||"Pro action blocked in Basic mode","blocked_unsupported",{executionTimeMs:a,command:n,...i.routing?{routing:i.routing}:{}});return}if(s.kind==="blocked_fallback_failed"){await t.historyManager.recordBlockedOutcome(e,vS(n,r),i.error||"Pro action blocked in Basic mode","blocked_fallback_failed",{executionTimeMs:a,command:n,...s.fallbackCommand?{fallbackCommand:s.fallbackCommand}:{},...s.blockedDetail?{blockedDetail:s.blockedDetail}:{},...i.routing?{routing:i.routing}:{}});return}let c=s.kind==="warning"?t.historyManager.recordWarning.bind(t.historyManager):t.historyManager.recordFailure.bind(t.historyManager),l=vS(n,r);i.routing?await c(e,l,i.error||"Unknown error",a,i.errorCode??o?.errorType.toUpperCase(),n,void 0,i.routing):await c(e,l,i.error||"Unknown error",a,i.errorCode??o?.errorType.toUpperCase(),n)}function i1(t,e,n){let r=t.pendingCommands.get(e)||[];r.length>=y3&&r.shift(),r.push(n),t.pendingCommands.set(e,r)}function Lxe(t,e){t.globalPendingCommands.length>=y3&&t.globalPendingCommands.shift(),t.globalPendingCommands.push(e)}function I3(t,e,n){let r=_S(),i={requestId:r,command:e.command,params:e.params,timestamp:Date.now(),queueTimeoutMs:e.queueTimeoutMs,ackedTimeoutMs:e.ackedTimeoutMs,state:Dn.QUEUED,targetClientId:n,resolve:()=>{},reject:a=>{y.debug("Auxiliary playtest stop command ended without awaited response",{requestId:r,targetClientId:n,error:a.message})},timeoutId:null};return t.commandQueue.set(r,i),i.timeoutId=setTimeout(()=>{p_(t,i,i.queueTimeoutMs)},i.queueTimeoutMs),{event:"command",id:r,data:{command:i.command,requestId:r,params:i.params}}}function zxe(t,e,n,r){if(!ym(e.data.command))return;let i=t.commandQueue.get(e.data.requestId);if(!i)return;C3(t,i);let a=n.filter(o=>o.clientId!==r);for(let o of a){let s=I3(t,i,o.clientId);i1(t,o.clientId,s)}a.length>0&&y.info("Fan-out playtest stop command to active plugin clients",{requestId:e.data.requestId,primaryClientId:r,auxiliaryClientIds:a.map(o=>o.clientId)})}function C3(t,e,n){for(let r of e9)setTimeout(()=>{let a=n?[...new Set(n)]:[...new Set(Un(t).map(o=>o.clientId))];for(let o of a){if(!t.pluginClients.get(o))continue;let c=I3(t,e,o);i1(t,o,c)}y.info("Retry playtest stop command to active plugin clients",{sourceRequestId:e.requestId,delayMs:r,targetClientIds:a}),ou(t)},r).unref?.()}function P3(t){return t==="clientId"||t==="targetAlias"||t==="placeId"}function Uxe(t,e,n){if(!n||!ym(e.data.command))return!1;let r=t.commandQueue.get(e.data.requestId)?.routing?.selectionMode;return!P3(r)}function Fxe(t,e,n){y.debug("Broadcasting command",{command:e.data.command,requestId:e.data.requestId,targetClientId:n||"all",activeWebsocketClients:Un(t).length});let r=n;if(n){i1(t,n,e);let i=t.commandQueue.get(e.data.requestId),a=i?.routing?.selectionMode;if(i&&ym(e.data.command)&&P3(a))C3(t,i,[n]);else if(Uxe(t,e,n)){let o=Un(t).sort((s,c)=>c.lastSeen-s.lastSeen);zxe(t,e,o,n),r=void 0}}else Lxe(t,e);ou(t,r)}async function k3(t,e,n){let r=Date.now(),i="",a={};try{let o=e.body;i=o.command??"",a=o.params||{};let s=o.requestId;if(o.instanceId||(t.serverLastCommandAt=Date.now()),o.instanceId){let m=t.mcpInstances.get(o.instanceId);m&&(m.lastCommandAt=Date.now(),m.lastSeen=m.lastCommandAt)}let c=d3(i),l=typeof o.timeout=="number"&&Number.isFinite(o.timeout)&&o.timeout>0?{timeout:o.timeout}:void 0,u=o.instanceId?t.mcpInstances.get(o.instanceId)?.sessionId??t.sessionId:t.sessionId;if(!i){n.status(400).json({error:"Missing command"});return}if(y.debug("Received execute request",{command:i,requestId:s}),i==="manage_camera_play_screenshot"){let m="manage_camera.play_screenshot is not supported. Screenshot capture is available only in Edit mode via manage_camera.screenshot.",g=Date.now()-r;t.historyManager&&await t.historyManager.recordFailure("manage_camera",a,m,g,"UNSUPPORTED_COMMAND",i),n.json({requestId:s,success:!1,error:m});return}if(i==="get_cached_selection"){let m=a.maxAge,g=hm(t,m!==void 0?m:3e4),h=Date.now()-r;if(!g){let x={requestId:s,success:!0,data:{cached:!1,message:"No cached selection data available. The plugin may not be connected or no selection changes have occurred yet."}};t.historyManager&&await t.historyManager.recordSuccess(c.toolName,a,x.data,h,c.commandName),n.json(x);return}let v=Date.now()-g.timestamp,_={cached:!0,selection:g.selection,count:g.count,timestamp:g.timestamp,age:v};t.historyManager&&await t.historyManager.recordSuccess(c.toolName,a,_,h,c.commandName),n.json({requestId:s,success:!0,data:_});return}if(i==="get_connection_info"){let m=await nS(t),g=Date.now()-r;t.historyManager&&await t.historyManager.recordSuccess(c.toolName,a,m,g,c.commandName),n.json({requestId:s,success:!0,data:m});return}if(iS(i)==="internal"){if(!t.internalCommandExecutor){n.status(503).json({requestId:s,success:!1,error:`Internal command executor is not initialized for command: ${i}`});return}if(tr(i)==="pro"){if(!t.licenseState){n.status(503).json({requestId:s,success:!1,error:`License state manager is not initialized for internal command: ${i}`});return}let _=await t.licenseState.evaluateProAccess();if(!_.allowed){let x=Pxe(i,_.reason),w=Date.now()-r;t.historyManager&&await xS(t,c.toolName,c.commandName,a,{success:!1,error:x},w),n.json({requestId:s,success:!1,error:x});return}}let m={...a,__sessionId:u},g=await t.internalCommandExecutor(i,m),h=Date.now()-r,v=p3(m,g.data);t.historyManager&&await xS(t,c.toolName,c.commandName,v,{success:g.success,data:g.data,error:g.error||"Internal command failed"},h),n.json({requestId:s,...g});return}let d=await xr(t,i,a,s,l),p=Date.now()-r,f={...p3(a,d.data),__sessionId:u};t.historyManager&&await xS(t,c.toolName,c.commandName,f,d,p),n.json(d)}catch(o){let s=Date.now()-r,c=er(o);if(t.historyManager&&i){let l=d3(i);await t.historyManager.recordFailure(l.toolName,a,c,s,"EXCEPTION",l.commandName)}y.error("Execute request failed",o),n.status(500).json({success:!1,error:c})}}async function E3(t,e,n){let r=Date.now(),i=e.body,a=i.action;if(!a||typeof a!="string"){n.status(400).json({success:!1,error:"Missing required field: action"});return}if(!new Set(["get","set","get_all","set_multiple","get_attr","set_attr","get_all_attrs","delete_attr","add_tag","remove_tag","check_tag","get_tags","get_tagged"]).has(a)){n.status(400).json({success:!1,error:`Unsupported action: ${a}`});return}let s=`manage_properties_${a}`,c=_S(),{action:l,...u}=i;try{t.serverLastCommandAt=Date.now();let d=await xr(t,s,u,c),p=Date.now()-r;t.historyManager&&await xS(t,"manage_properties",s,u,d,p),n.json(d)}catch(d){let p=Date.now()-r,f=er(d);t.historyManager&&await t.historyManager.recordFailure("manage_properties",u,f,p,"EXCEPTION",s),y.error("/api/properties \uC694\uCCAD \uCC98\uB9AC \uC2E4\uD328",d),n.status(500).json({success:!1,error:f})}}async function xr(t,e,n,r,i){if(y.debug("Executing command locally",{command:e,requestId:r}),_8(t,r)){let d=`Duplicate requestId '${r}' for command '${e}'. Generate a unique requestId for each command.`;return y.warn("Duplicate execute request rejected",{command:e,requestId:r}),{requestId:r,success:!1,error:d}}let a;try{a=rS(t,Un(t),n,e)}catch(d){if(d instanceof xn)return y.warn("Command target selection failed",{command:e,requestId:r,errorCode:d.code,routing:d.routing}),Txe(r,d);throw d}let o=v3.has(e)?await Mxe(t,e,n):null,s=t.config.requestTimeout,c=i?.timeout??Math.max(t.config.requestTimeout,Ixe),l=BA.has(e)?await L9({ctx:t,command:e,params:n}):n,u=new Promise((d,p)=>{let f=Date.now(),m={requestId:r,command:e,params:l,timestamp:f,queueTimeoutMs:s,ackedTimeoutMs:c,state:Dn.QUEUED,...a.targetClientId?{targetClientId:a.targetClientId}:{},routing:a.routing,resolve:d,reject:p,timeoutId:null};t.commandQueue.set(r,m),s_(t,a.targetClientId,f),m.timeoutId=setTimeout(()=>{p_(t,m,s)},s)});return Fxe(t,{event:"command",id:_S(),data:{command:e,requestId:r,params:l}},a.targetClientId),u.then(async d=>{let p=d;if(e==="manage_ui_preview"&&d.success&&d.data)try{let{processPreviewResult:f,resolvePreviewPlaceDirFromCtx:m}=await Promise.resolve().then(()=>(r1(),n1)),g=await m(t,n),h=await f("manage_ui_preview",d.data,g);p={...d,data:h.data,...h.mcpContent?{mcpContent:h.mcpContent}:{}}}catch(f){y.warn("preview post-processing failed",{error:f instanceof Error?f.message:String(f)})}if(e==="manage_ui_check"&&d.success&&d.data&&n.includeVisualAnalysis===!0)try{let{resolvePreviewPlaceDirFromCtx:f}=await Promise.resolve().then(()=>(r1(),n1)),{processCheckResult:m}=await Promise.resolve().then(()=>(u3(),l3)),g=await f(t,n),h=await m("manage_ui_check",d.data,g,n);p={...p,data:h.data}}catch(f){y.warn("check visual post-processing failed",{error:f instanceof Error?f.message:String(f)})}return VA.has(e)?p=await z9({ctx:t,command:e,params:n,result:p}):e===qA&&(p=await U9({ctx:t,params:n,result:p})),p}).then(async d=>(await h3(o,{success:d.success,...d.data!==void 0&&{data:d.data},...d.error!==void 0&&{error:d.error}}),d),async d=>{throw await h3(o,{success:!1,error:er(d)}),d})}oe();Ki();function SS(t,e){let n={};e.provider!==void 0&&(n.provider=e.provider),e.tier!==void 0&&(n.tier=e.tier),e.status!==void 0&&(n.status=e.status),e.canUsePro!==void 0&&(n.canUsePro=e.canUsePro),e.cleared===!0&&(n.cleared=!0),dt(t,"license",n)}function Pi(t,e,n,r){t.status(e).json({success:!1,error:{code:n,message:r}})}function qxe(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();return e.length>0?e:void 0}function wS(t,e){if(e==="plugin")return t;let n={...t};return delete n.sessionToken,n}function jm(t,e,n,r){let i=qxe(r??e.query.provider)??"auto";return t.licenseState?.supportsProvider(i)===!1?(Pi(n,400,"LICENSE_PROVIDER_UNSUPPORTED",`provider "${i}" is not supported`),null):i}function Mm(t,e){return t.licenseState?!0:(Pi(e,503,"LICENSE_NOT_INITIALIZED","License system is not initialized"),!1)}function Bxe(t){if(!t||typeof t!="object")return!1;let e=t;return(e.canUsePro===!0||e.canUsePro===!1)&&typeof e.status=="string"&&typeof e.checkedAt=="number"}function Lm(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=e.body,a=typeof i?.licenseKey=="string"?i.licenseKey:"";if(!a.trim()){Pi(n,400,"LICENSE_KEY_REQUIRED","licenseKey is required");return}let o=jm(t,e,n,i?.provider);if(!o)return;let s=typeof i?.pluginClientId=="string"?i.pluginClientId:typeof e.query.clientId=="string"?e.query.clientId:void 0,c=typeof i?.deviceId=="string"?i.deviceId:void 0,l={licenseKey:a,provider:o,clientType:r};s&&(l.pluginClientId=s),c&&(l.deviceId=c),t.licenseState.activateGateway(l).then(u=>{t.analyticsManager?.setTier(u.canUsePro?"pro":"basic"),SS(t,{provider:u.provider,tier:u.canUsePro?"pro":"basic",status:u.status,canUsePro:u.canUsePro}),n.json(wS(u,r))}).catch(u=>{y.warn("License activate failed",{error:u instanceof Error?u.message:"unknown_error"}),Pi(n,502,"LICENSE_ACTIVATE_FAILED",u instanceof Error?u.message:"License activation failed")})}function zm(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=jm(t,e,n);if(i)try{let a=t.licenseState.getStatus(i);t.analyticsManager?.setTier(a.canUsePro?"pro":"basic"),n.json(wS(a,r))}catch(a){y.warn("License status check failed",{error:a instanceof Error?a.message:"unknown_error"}),Pi(n,502,"LICENSE_STATUS_FAILED",a instanceof Error?a.message:"License status check failed")}}function Um(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=e.body,a=jm(t,e,n,i?.provider);if(!a)return;let o={provider:a,clientType:r};r==="plugin"&&typeof i?.sessionToken=="string"&&i.sessionToken.trim()&&(o.sessionToken=i.sessionToken.trim()),typeof i?.pluginClientId=="string"&&(o.pluginClientId=i.pluginClientId),typeof i?.deviceId=="string"&&(o.deviceId=i.deviceId),t.licenseState.refreshGateway(o).then(s=>{t.analyticsManager?.setTier(s.canUsePro?"pro":"basic"),SS(t,{provider:s.provider,tier:s.canUsePro?"pro":"basic",status:s.status,canUsePro:s.canUsePro}),n.json(wS(s,r))}).catch(s=>{y.warn("License refresh failed",{error:s instanceof Error?s.message:"unknown_error"}),Pi(n,502,"LICENSE_REFRESH_FAILED",s instanceof Error?s.message:"License refresh failed")})}function Fm(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=e.body,a=jm(t,e,n,i?.provider);a&&t.licenseState.resetGateway({provider:a,clientType:r}).then(o=>{t.analyticsManager?.setTier("basic"),SS(t,{provider:o.provider,tier:"basic",status:o.status,canUsePro:o.canUsePro,cleared:!0}),n.json(wS(o,r))}).catch(o=>{y.warn("License reset failed",{error:o instanceof Error?o.message:"unknown_error"}),Pi(n,502,"LICENSE_RESET_FAILED",o instanceof Error?o.message:"License reset failed")})}function a1(t,e,n){if(!Mm(t,n))return;let r=e.body,i=jm(t,e,n,r?.provider);if(!i)return;if(r?.clientType!=="plugin"){Pi(n,400,"LICENSE_CLIENT_TYPE_INVALID","clientType must be plugin");return}let a=typeof r?.sessionToken=="string"&&r.sessionToken.trim()?r.sessionToken.trim():void 0,o=Bxe(r?.snapshot)?r.snapshot:void 0;if(!o&&!a){Pi(n,400,"LICENSE_BOOTSTRAP_REQUIRED","snapshot or sessionToken is required");return}let s={provider:i,clientType:"plugin"};o&&(s.snapshot=o),a&&(s.sessionToken=a),t.licenseState.bootstrap(s).then(c=>{t.analyticsManager?.setTier(c.canUsePro?"pro":"basic"),SS(t,{provider:c.provider,tier:c.canUsePro?"pro":"basic",status:c.status,canUsePro:c.canUsePro}),n.json({ok:!0})}).catch(c=>{y.warn("License bootstrap failed",{error:c instanceof Error?c.message:"unknown_error"}),Pi(n,502,"LICENSE_BOOTSTRAP_FAILED",c instanceof Error?c.message:"License bootstrap failed")})}function R3(t){t.app.post("/license/bootstrap",(e,n)=>a1(t,e,n)),t.app.post("/license/activate",(e,n)=>Lm(t,e,n,"plugin")),t.app.post("/license/refresh",(e,n)=>Um(t,e,n,"plugin")),t.app.post("/license/reset",(e,n)=>Fm(t,e,n,"plugin")),t.app.get("/license/status",(e,n)=>zm(t,e,n,"plugin"))}vt();oe();import{promises as IS}from"fs";import o1 from"path";function Vxe(t){let e=t.config.appDataDir??it();return o1.join(e,"observability","logs")}async function $u(t,e,n){let r=e.query.clientId;if(r&&t.pluginClients.has(r)){let i=t.pluginClients.get(r);i.lastSeen=Date.now()}try{let i=e.body;if(!i||!Array.isArray(i.logs)){y.warn("Invalid logs request",{body:i}),n.status(400).json({error:"Invalid request body"});return}let a=Vxe(t);await IS.mkdir(a,{recursive:!0});let c=`plugin-${new Date().toISOString().split("T")[0]}.log`,l=o1.join(a,c),u=o1.join(a,"current.log"),d=i.logs.map(p=>`[${new Date(p.timestamp*1e3).toISOString().replace("T"," ").substring(0,19)}] [${p.level}] ${p.message}`).join(`
530
+ `),r.index.setFormatVersion(Ot);let f=As(r.index.toSyncIndexData());return await this.fileOps.writeFileAtomic(o,f),r.formatVersion=Ot,r.writer.setFormatVersion(Ot),await r.fileWatcher?.endFullSyncReplacement(),this.preview(e.placeId)}catch(p){throw await this.rollback(l,c,r,u),p}}async buildPlan(e){let n=this.ctx.places.get(e);if(!n)throw new ia(404,"place_not_found");let r=this.ctx.config.getSyncRoot(),i=Nt.dirname(n.index.getExplorerRoot()),a=n.index.getExplorerRoot();if(n.formatVersion!==gt){let _=$5(As({blockers:[],changes:[],fromVersion:gt,placeId:e,toVersion:Ot}));return{placeId:e,fromVersion:gt,toVersion:Ot,status:"not_required",previewFingerprint:_,userSourceModified:0,summary:{add:0,modify:0,delete:0,blocked:0},changes:[],blockers:[],operations:new Map}}let s=await ave(r,a),c=new Set(s.map(_=>_.absolutePath)),l=[],u=new Map;for(let _ of s){let x=await ove(_,c);x&&(l.push(x.change),u.set(x.change.path,x.after))}let d=await this.planManagedIgnore(r);d&&(l.push(d.change),u.set(d.change.path,d.after)),l.sort(lve);let p=await this.collectBlockers(r,n);p.sort(uve);let f=Nt.join(i,".sync-index.json"),m=await this.readFileOrNull(f),g=[...n.index.getAllFileHashes().keys()].map(_=>{let x=q_(r,_);if(Us(x)!=="canonical_mirror")return null;let I=n.index.getHashPair(_);return{path:x,fileHash:I.fileHash??null,studioHash:I.studioHash??null}}).filter(_=>_!==null).sort((_,x)=>_.path.localeCompare(x.path)),h=$5(As({blockers:p,changes:l,fromVersion:gt,indexHash:m?Ws(m):null,indexState:g,placeId:e,toVersion:Ot})),v={add:l.filter(_=>_.operation==="add").length,modify:l.filter(_=>_.operation==="modify").length,delete:l.filter(_=>_.operation==="delete").length,blocked:p.length};return{placeId:e,fromVersion:gt,toVersion:Ot,status:p.length>0?"blocked":"ready",previewFingerprint:h,userSourceModified:0,summary:v,changes:l,blockers:p,operations:u}}async planManagedIgnore(e){let n=Nt.join(e,".gitignore"),r=await this.readFileOrNull(n),i=r?.toString("utf8")??"",a=Buffer.from(SA(i),"utf8");return r?.equals(a)?null:{change:{path:".gitignore",ownership:"generated",operation:r===null?"add":"modify",reason:"runtime_ignore_policy",...r!==null?{beforeHash:Ws(r)}:{},afterHash:Ws(a)},after:a}}async readFileOrNull(e){return this.fileOps.readFile(e).catch(n=>{if(n.code==="ENOENT")return null;throw n})}async captureOriginals(e,n,r,i){let a=[];for(let o of n){let s=Nt.resolve(e,o.path);a.push({absolutePath:s,content:await this.readFileOrNull(s)})}return a.push({absolutePath:r,content:await this.readFileOrNull(r)}),a.push({absolutePath:i,content:await this.readFileOrNull(i)}),a}async writeBackup(e,n,r){await this.fileOps.mkdir(n);for(let i of r){if(i.content===null)continue;let a=q_(e,i.absolutePath);await this.fileOps.copyFile(i.absolutePath,Nt.join(n,"files",a))}}async applyOperations(e,n,r,i){let a=new Map(i.map(o=>[o.absolutePath,o.content]));for(let o of r.changes){let s=Nt.resolve(e,o.path),c=r.operations.get(o.path);if(c===void 0)throw new Error(`Missing migration operation content: ${o.path}`);if(n.fileWatcher?.suppressPath(s,c===null?"missing":n.index.computeHash(c.toString("utf8"))),c===null?await this.fileOps.unlink(s):await this.fileOps.writeFileAtomic(s,c),o.ownership!=="canonical_mirror")continue;if(c===null){n.index.removeHash(s);continue}let l=a.get(s);(l?n.index.getFileStatus(s,n.index.computeHash(l.toString("utf8"))):"synced")==="studio-modified"?n.index.updateFileHash(s,c.toString("utf8")):n.index.updateBothHashes(s,c.toString("utf8"))}}async assertUserSourcesUnchanged(e,n){let r=await D5(e);if(!pve(n,r))throw new ia(409,"source_mutation_detected")}async rollback(e,n,r,i){let a;for(let o of[...e].reverse())try{o.content===null?await this.fileOps.unlink(o.absolutePath).catch(s=>{if(s.code!=="ENOENT")throw s}):await this.fileOps.writeFileAtomic(o.absolutePath,o.content)}catch(s){a??=s}r.index.clearAllHashes();for(let[o,s]of i.studioHashes)r.index.updateHashByValue(o,s);for(let[o,s]of i.fileHashes)r.index.updateFileHashByValue(o,s);if(r.index.setFormatVersion(gt),r.formatVersion=gt,r.writer.setFormatVersion(gt),await Wr.rm(n,{recursive:!0,force:!0}),await r.fileWatcher?.endFullSyncReplacement(),a)throw a}async collectBlockers(e,n){let r=[];(n.fileWatcher?.getPendingCount()??0)>0&&r.push({reason:"reverse_pending"});for(let i of n.index.getAllFileHashes().keys()){let a=q_(e,i);if(Us(a)!=="canonical_mirror")continue;let o=await cve(i);if(o===null){r.push({path:a,reason:"local_canonical_change"});continue}let s=n.index.getFileStatus(i,n.index.computeHash(o.toString("utf8")));s==="conflict"?r.push({path:a,reason:"conflict"}):s==="file-modified"&&r.push({path:a,reason:"local_canonical_change"})}return dve(r)}};async function ave(t,e){let n=[];async function r(i){let a=await Wr.readdir(i,{withFileTypes:!0}).catch(o=>{if(o.code==="ENOENT")return[];throw o});for(let o of a){let s=Nt.join(i,o.name);if(o.isDirectory()){await r(s);continue}sve(o.name)&&n.push({absolutePath:s,relativePath:q_(t,s),content:await Wr.readFile(s)})}}return await r(e),n.sort((i,a)=>i.relativePath.localeCompare(a.relativePath))}async function ove(t,e){let n=JSON.parse(t.content.toString("utf8")),r=Ws(t.content);if(t.absolutePath.endsWith(".props.json")){let o=n,s=t.absolutePath.replace(/\.props\.json$/,".value.json");if(hA(o,e.has(s)))return{change:{path:t.relativePath,ownership:"canonical_mirror",operation:"delete",reason:"redundant_empty_metadata",beforeHash:r},after:null}}let i="serializer_regeneration";Nt.basename(t.absolutePath)==="_tree.json"&&n!==null&&typeof n=="object"&&!Array.isArray(n)&&Object.prototype.hasOwnProperty.call(n,"syncedAt")&&(delete n.syncedAt,i="volatile_metadata_removal");let a=Buffer.from(As(n),"utf8");return t.content.equals(a)?null:{change:{path:t.relativePath,ownership:"canonical_mirror",operation:"modify",reason:i,beforeHash:r,afterHash:Ws(a)},after:a}}function sve(t){return t==="_tree.json"||t.endsWith(".props.json")||t.endsWith(".value.json")}function q_(t,e){return Nt.relative(t,e).replaceAll(Nt.sep,"/")}function Ws(t){return rve("sha256").update(t).digest("hex")}function $5(t){return Ws(Buffer.from(t,"utf8"))}function cve(t){return Wr.readFile(t).catch(e=>{if(e.code==="ENOENT")return null;throw e})}function lve(t,e){return t.path.localeCompare(e.path)||t.operation.localeCompare(e.operation)||t.reason.localeCompare(e.reason)}function uve(t,e){return(t.path??"").localeCompare(e.path??"")||t.reason.localeCompare(e.reason)}function dve(t){let e=new Set;return t.filter(n=>{let r=`${n.path??""}\0${n.reason}`;return e.has(r)?!1:(e.add(r),!0)})}async function D5(t){let e=new Map;async function n(r){let i=await Wr.readdir(r,{withFileTypes:!0}).catch(a=>{if(a.code==="ENOENT")return[];throw a});for(let a of i){let o=Nt.join(r,a.name);a.isDirectory()?await n(o):(a.name.endsWith(".server.luau")||a.name.endsWith(".client.luau")||a.name.endsWith(".module.luau"))&&e.set(Nt.relative(t,o).replaceAll(Nt.sep,"/"),Ws(await Wr.readFile(o)))}}return await n(t),e}function pve(t,e){if(t.size!==e.size)return!1;for(let[n,r]of t)if(e.get(n)!==r)return!1;return!0}Lr();oe();var fve=5;function N5(t){if(!t||typeof t!="object")return;let e=t;if(Array.isArray(e.instances))for(let n of e.instances)Array.isArray(n.properties)&&n.properties.length===0&&(n.properties={}),Array.isArray(n.attributes)&&n.attributes.length===0&&(n.attributes={});if(Array.isArray(e.changes))for(let n of e.changes)Array.isArray(n.properties)&&n.properties.length===0&&(n.properties={}),Array.isArray(n.attributes)&&n.attributes.length===0&&(n.attributes={})}function mve(t){return t.type==="instanceAdded"||t.type==="instanceRemoved"||t.type==="instanceRenamed"||t.type==="instanceMoved"||t.type==="scriptSourceChanged"}var _i=class{config;places;apiHandler;changeProcessor;initHandler;reverseHandler;migrationService;reverseDetectorFactory;placeDisposals=new Map;activeFullSyncPlaceId=null;activeRuntimeSyncPlaceId=null;currentConnectedPlaceId=null;currentConnectedPlaceName=null;constructor(e,n={}){this.config=new Wx(e,n),this.reverseDetectorFactory=n.reverseDetectorFactory??(r=>new $_(r.explorerRoot,r.syncIndex,{placeId:r.placeId})),this.apiHandler=new L_(this),this.changeProcessor=new M_(this),this.initHandler=new z_(this),this.reverseHandler=new F_(this),this.places=new T_({max:fve,dispose:(r,i)=>{this.trackPlaceDisposal(r,i)}}),this.migrationService=new B_(this)}getSyncRoot(){return this.config.getSyncRoot()}async getOrCreatePlaceContext(e,n){let r=this.places.get(e);if(r&&n){let i=this.config.getPlaceRoot(e),a=await this.config.resolvePlaceRoot(e,n);a!==i&&(y.info("Place root migrated, recreating context",{placeId:e,from:i,to:a}),this.places.delete(e),r=void 0)}if(!r){await this.waitForPlaceDisposal(e);let i=await this.config.resolvePlaceRoot(e,n),a=wA.join(i,"explorer"),o=await WB(i),s=o.formatVersion;o.recovery&&y.warn("Recovered corrupt sync index",{indexPath:o.recovery.indexPath,quarantinePath:o.recovery.quarantinePath,formatVersion:o.recovery.formatVersion,reason:o.recovery.reason}),await IA.mkdir(i,{recursive:!0}),await IA.mkdir(a,{recursive:!0});let c=new hu(i,a,s);await c.loadFromDisk();let l=new yu(this.config,c,e,s),u=new O_(this.config,c,i);if(l.startChangeLogFlusher(),r={placeId:e,placeName:"",formatVersion:s,pendingIndexRecovery:o.recovery??null,index:c,writer:l,reader:u,fileWatcher:null,state:"idle",activeClientId:null,activeFullSyncSessionId:null,instanceCount:0,scriptCount:0,lastFullSync:null,lastIncrementalSync:null,tmpIndex:null,tmpWriter:null,incompleteSyncTimer:null,syncInitRequestsInFlight:0,changesSinceLastSave:0,directions:{...Rs},applyModes:{...Ts},autoApplyDeletes:!1,forwardRestoreQueue:[],syncProgress:null,collisionDirMap:null,activeSyncIdentityScope:null},this.places.set(e,r),r.pendingIndexRecovery){let d=r.pendingIndexRecovery;l.appendHistory({timestamp:new Date().toISOString(),type:"indexRecovery",direction:"forward",source:"studio",path:d.indexPath,details:JSON.stringify({quarantinePath:d.quarantinePath,formatVersion:d.formatVersion,reason:d.reason})}),await l.flushHistory(),r.pendingIndexRecovery=null}y.info("Created new place context",{placeId:e,placeRoot:i})}return r}async handleSyncInit(e,n){try{N5(e.body);let r=C5(e.body);if(!r.success){n.status(400).json({error:"Validation error",message:r.error});return}let i=r.data,a=i.phase==="start"?i.placeId??null:i.phase==="chunk"||i.phase==="complete"?this.activeFullSyncPlaceId:null;if(a==null){n.status(400).json({error:"Missing placeId",message:"placeId is required in start phase or must be set by previous start"});return}switch(i.phase){case"start":this.setCurrentConnectedPlace(a,i.placeName),await this.initHandler.handleInitStart(a,i,n);break;case"chunk":await this.initHandler.handleInitChunk(a,i,n);break;case"complete":await this.initHandler.handleInitComplete(a,i,n);break}}catch(r){this.sendError(n,r,"handleSyncInit")}}async handleSyncUpdate(e,n){try{N5(e.body);let r=P5(e.body);if(!r.success){n.status(400).json({error:"Validation error",message:r.error});return}let i=r.data,a=i.placeId??this.getDefaultRuntimePlaceId();if(a==null){n.status(400).json({error:"Missing placeId",message:"placeId is required in body or must have an active sync session"});return}let o=await this.getOrCreatePlaceContext(a);if(this.setCurrentConnectedPlace(a,o.placeName||this.currentConnectedPlaceName),o.activeFullSyncSessionId!==null||o.state==="initializing"){n.status(409).json({error:"Conflict",message:`Full sync in progress for place ${a}`});return}o.activeClientId=i.clientId,this.touchRuntimePlace(a);let s=S5(o,i.changes);y.info("Sync update received",{placeId:a,clientId:i.clientId,changeCount:s.length,receivedCount:i.changes.length,types:s.map(m=>m.type)});let c=[],l=[],u=0,d=!1,p=new Map;for(let m of s)try{let g=await this.changeProcessor.processChangeForPlace(o,m,p);g?l.push(g):(u++,mve(m)&&(d=!0))}catch(g){let h="path"in m?m.path:"oldPath"in m?m.oldPath:"unknown";c.push({path:h,error:g instanceof Error?g.message:String(g)})}for(let m of p.values())try{await D_(o,m)}catch(g){c.push({path:m.instancePath,error:g instanceof Error?g.message:String(g)})}if(d)try{let m=this.config.getSyncRoot(),g=this.config.getPlaceRoot(a);await Qx(m,g,o.formatVersion,o.writer),await eu(m,o.writer)}catch(m){y.warn("Failed to refresh sourcemaps after incremental sync update",{placeId:a,error:m instanceof Error?m.message:String(m)})}o.changesSinceLastSave+=u,o.changesSinceLastSave>=I5&&(await o.index.saveToDisk(),o.changesSinceLastSave=0),o.lastIncrementalSync=new Date().toISOString();let f={processed:u,failed:c.length,errors:c,syncedAt:o.lastIncrementalSync};l.length>0&&(f.conflicts=l),n.status(200).json(f)}catch(r){this.sendError(n,r,"handleSyncUpdate")}}getDefaultRuntimePlaceId(){return this.currentConnectedPlaceId}getDefaultRuntimePlaceName(){if(this.currentConnectedPlaceName)return this.currentConnectedPlaceName;if(this.currentConnectedPlaceId!==null&&this.currentConnectedPlaceId!==void 0){let e=this.places.get(this.currentConnectedPlaceId);if(e?.placeName)return e.placeName}return null}setCurrentConnectedPlace(e,n){if(this.currentConnectedPlaceId=e,e==null){this.currentConnectedPlaceName=null;return}if(typeof n=="string"&&n.length>0){this.currentConnectedPlaceName=n;let i=this.places.get(e);i&&(i.placeName=n);return}let r=this.places.get(e);r?.placeName&&(this.currentConnectedPlaceName=r.placeName)}clearCurrentConnectedPlaceIfMatch(e){this.currentConnectedPlaceId===e&&(this.currentConnectedPlaceId=null,this.currentConnectedPlaceName=null)}touchRuntimePlace(e){this.activeRuntimeSyncPlaceId=e}clearRuntimePlaceIfMatch(e){this.activeRuntimeSyncPlaceId===e&&(this.activeRuntimeSyncPlaceId=null)}resolveQueryPlaceId(e,n="runtime"){let r=e.query.placeId;if(r){let i=parseInt(r,10);if(!isNaN(i))return i}return n==="full"?this.activeFullSyncPlaceId:this.getDefaultRuntimePlaceId()}async handleSyncStatus(e,n){try{let r=u=>({state:"idle",instanceCount:0,scriptCount:0,lastFullSync:null,lastIncrementalSync:null,syncRoot:u,activeClientId:null,reverseSyncAvailable:!1,modifiedFileCount:0,autoApplyDeletes:!1,reverseDetectorActive:!1,reverseDetectorMode:_t,fileWatcherActive:!1}),i=this.resolveQueryPlaceId(e);if(i==null){let u=r(this.config.getSyncRoot());n.status(200).json(u);return}let a=this.places.get(i);if(!a){let u=r(this.config.getPlaceRoot(i));n.status(200).json(u);return}let o=a.fileWatcher?.getPendingCount()??0,s=a.fileWatcher?.isActivelyScanning()??!1,c=a.fileWatcher!==null;this.touchRuntimePlace(i);let l={state:a.state,instanceCount:a.instanceCount,scriptCount:a.scriptCount,lastFullSync:a.lastFullSync,lastIncrementalSync:a.lastIncrementalSync,syncRoot:this.config.getPlaceRoot(i),activeClientId:a.activeClientId,reverseSyncAvailable:o>0,modifiedFileCount:o,applyModes:a.applyModes,autoApplyDeletes:a.autoApplyDeletes,directions:a.directions,reverseDetectorActive:s,reverseDetectorMode:_t,fileWatcherActive:c,forwardOnlyClasses:[...Ql]};n.status(200).json(l)}catch(r){this.sendError(n,r,"handleSyncStatus")}}async handleSyncStop(e,n){try{let r=e.body,i=r.placeId??this.getDefaultRuntimePlaceId(),a=um(r);if(y.info("handleSyncStop requested",{placeId:i,clientId:r.clientId??null,identityScope:a,reason:r.reason??"requested"}),i==null){n.status(200).json({status:"idle",state:"idle",placeId:null,message:"No active sync place"});return}let o=this.places.get(i);if(!o){y.info("handleSyncStop no place context",{placeId:i,clientId:r.clientId??null}),n.status(200).json({status:"idle",state:"idle",placeId:i,message:`No sync context for place ${i}`});return}let s=!!(r.clientId&&o.activeClientId&&r.clientId!==o.activeClientId),c=o.activeFullSyncSessionId!==null||o.state==="syncing"||o.state==="initializing",l=!!(a&&o.activeSyncIdentityScope&&a===o.activeSyncIdentityScope);if(s&&c&&!l){y.warn("handleSyncStop rejected due to active client mismatch",{placeId:i,requestedClientId:r.clientId,activeClientId:o.activeClientId,requestedIdentityScope:a,activeIdentityScope:o.activeSyncIdentityScope,state:o.state,activeFullSyncSessionId:o.activeFullSyncSessionId}),n.status(409).json({error:"Conflict",message:`This sync session belongs to client ${o.activeClientId}`});return}s&&l&&y.info("handleSyncStop accepted stale client cleanup by identity scope",{placeId:i,requestedClientId:r.clientId,activeClientId:o.activeClientId,identityScope:a,state:o.state});let u=o.activeFullSyncSessionId,d=o.state,p=o.fileWatcher!==null;if(u&&(this.initHandler.clearPreserveLocalFiles(u),this.initHandler.clearPendingServiceTrees(u)),o.fileWatcher&&(y.info("handleSyncStop suspending reverse detector",{placeId:i,state:o.state,activeClientId:o.activeClientId,mode:_t}),o.fileWatcher.beginFullSyncReplacement()),o.incompleteSyncTimer&&(clearTimeout(o.incompleteSyncTimer),o.incompleteSyncTimer=null),u){let f=this.config.getPlaceRoot(i),m=wA.join(f,`explorer_tmp_${u}`);await IA.rm(m,{recursive:!0,force:!0}).catch(()=>{})}o.tmpWriter&&(o.tmpWriter.stopChangeLogFlusher(),o.tmpWriter=null),o.tmpIndex=null,o.collisionDirMap=null,o.activeSyncIdentityScope=null,o.syncInitRequestsInFlight=0,o.activeFullSyncSessionId=null,o.syncProgress=null,o.state="idle",o.activeClientId=null,o.instanceCount=0,o.scriptCount=0,o.forwardRestoreQueue=[],this.activeFullSyncPlaceId===i&&(this.activeFullSyncPlaceId=null),this.clearRuntimePlaceIfMatch(i),y.info("handleSyncStop responding idle",{placeId:i,previousState:d,activeFullSyncSessionId:u,hadWatcher:p}),y.info("Sync stopped",{placeId:i,reason:r.reason??"requested"}),n.status(200).json({status:"stopped",state:"idle",placeId:i})}catch(r){this.sendError(n,r,"handleSyncStop")}}async initialize(){try{await this.config.loadFromMeta(),await O5(this.config.getSyncRoot()),await this.initHandler.cleanupStaleTempDirs(),y.info("SyncController initialized")}catch(e){y.error("SyncController initialization failed",e instanceof Error?e:new Error(String(e)))}}async previewMigration(e){return this.migrationService.preview(e)}async applyMigration(e){return this.migrationService.apply(e)}async shutdown(){try{y.info("SyncController shutdown: clearing place contexts",{placeCount:this.places.size}),this.places.clear(),await Promise.all(this.placeDisposals.values()),y.info("SyncController shut down")}catch(e){y.error("SyncController shutdown error",e instanceof Error?e:new Error(String(e)))}}trackPlaceDisposal(e,n){let r=this.disposePlaceContext(e,n).catch(i=>{y.error("Place context dispose failed",i instanceof Error?i:new Error(String(i)))});this.placeDisposals.set(n,r),r.then(()=>{this.placeDisposals.get(n)===r&&this.placeDisposals.delete(n)})}async waitForPlaceDisposal(e){await this.placeDisposals.get(e)}async disposePlaceContext(e,n){y.info("Disposing place context (LRU eviction)",{placeId:n}),this.activeFullSyncPlaceId===n&&(this.activeFullSyncPlaceId=null);let r=e.index.toSyncIndexData(),i=e.fileWatcher,a=e.tmpWriter;e.fileWatcher=null,e.tmpWriter=null,e.incompleteSyncTimer&&(clearTimeout(e.incompleteSyncTimer),e.incompleteSyncTimer=null),e.activeFullSyncSessionId&&this.initHandler.clearPendingServiceTrees(e.activeFullSyncSessionId),e.tmpIndex=null,e.collisionDirMap=null,e.activeSyncIdentityScope=null,e.syncInitRequestsInFlight=0;let o=[e.index.savePersistenceStateToDisk(r).catch(s=>{y.error("Error saving index during dispose",s)}),e.writer.stopChangeLogFlusher().catch(s=>{y.error("LRU dispose \uC911 changelog flush \uC2E4\uD328",s)})];i&&(y.info("Disposing place context: stopping reverse detector",{placeId:n,reason:"lru-dispose",mode:_t}),o.push(i.stop("lru-dispose").catch(s=>{y.error("Error stopping reverse detector during dispose",s)}))),a&&o.push(a.stopChangeLogFlusher().catch(s=>{y.error("LRU dispose \uC911 \uC784\uC2DC changelog flush \uC2E4\uD328",s)})),await Promise.all(o),e.index.clearAllMaps()}async atomicWriteFile(e,n){await vn(e,n)}async handlePreCheck(e,n){try{await this.apiHandler.handlePreCheck(e,n)}catch(r){this.sendError(n,r,"handlePreCheck")}}async handleSyncDirections(e,n){try{await this.apiHandler.handleSyncDirections(e,n)}catch(r){this.sendError(n,r,"handleSyncDirections")}}async handleForwardRestoreList(e,n){try{await this.apiHandler.handleForwardRestoreList(e,n)}catch(r){this.sendError(n,r,"handleForwardRestoreList")}}async handleReversePending(e,n){try{await this.reverseHandler.handleReversePending(e,n)}catch(r){this.sendError(n,r,"handleReversePending")}}async handleReverseSyncChanges(e,n){try{await this.reverseHandler.handleReverseSyncChanges(e,n)}catch(r){this.sendError(n,r,"handleReverseSyncChanges")}}async handleReverseSyncResult(e,n){try{await this.reverseHandler.handleReverseSyncResult(e,n)}catch(r){this.sendError(n,r,"handleReverseSyncResult")}}async handleResolveConflict(e,n){try{await this.reverseHandler.handleResolveConflict(e,n)}catch(r){this.sendError(n,r,"handleResolveConflict")}}async handleReverseRescan(e,n){try{await this.reverseHandler.handleReverseRescan(e,n)}catch(r){this.sendError(n,r,"handleReverseRescan")}}async handleSyncHistory(e,n){try{await this.apiHandler.handleSyncHistory(e,n)}catch(r){this.sendError(n,r,"handleSyncHistory")}}async startFileWatcherForPlace(e){if(e.state!=="syncing"){y.debug("Skipping reverse detector start - place not syncing",{placeId:e.placeId,state:e.state});return}if(e.fileWatcher){if(e.fileWatcher.isActivelyScanning()){y.info("startFileWatcherForPlace: reusing active reverse detector",{placeId:e.placeId,mode:_t});return}y.info("startFileWatcherForPlace: resuming paused reverse detector",{placeId:e.placeId,mode:_t}),e.fileWatcher.endFullSyncReplacement();return}let n=this.createReverseChangeDetector(e);this.configureReverseChangeDetector(e,n),e.fileWatcher=n,n.start().then(()=>{e.fileWatcher===n&&y.info("Reverse detector started for reverse sync",{placeId:e.placeId,mode:_t})}).catch(r=>{y.warn("Failed to start reverse detector",{placeId:e.placeId,mode:_t,error:r instanceof Error?r.message:String(r)}),e.fileWatcher===n&&(e.fileWatcher=null)})}createReverseChangeDetector(e){return this.reverseDetectorFactory({explorerRoot:wA.join(this.config.getPlaceRoot(e.placeId),"explorer"),syncIndex:e.index,placeId:e.placeId})}configureReverseChangeDetector(e,n){e.writer.setOnWriteCallback((r,i,a)=>{n.suppressPath(r,i,a)}),n.setDirectionChecker(r=>{let i=VB(r);return e.directions[i]}),n.setOnForwardViolation(r=>{e.forwardRestoreQueue.includes(r)||(e.forwardRestoreQueue.push(r),y.info("Forward violation queued for restore",{placeId:e.placeId,relativePath:r,queueSize:e.forwardRestoreQueue.length}))})}getStatusSummary(){return this.apiHandler.getStatusSummary()}getDirectionForCategory(e){return this.apiHandler.getDirectionForCategory(e)}getStatusDirect(e){return this.apiHandler.getStatusDirect(e)}async getHistoryDirect(e,n){return this.apiHandler.getHistoryDirect(e,n)}getDirectionsDirect(e){return this.apiHandler.getDirectionsDirect(e)}getProgressDirect(e){return this.apiHandler.getProgressDirect(e)}async readSyncedFile(e,n){return this.apiHandler.readSyncedFile(e,n)}async readSyncedScriptSource(e,n){return await this.apiHandler.readSyncedScriptSource(e,n)}async writeSyncedFile(e,n,r){await this.apiHandler.writeSyncedFile(e,n,r)}async executeViaDisk(e,n){return this.apiHandler.executeViaDisk(e,n)}sendError(e,n,r){let i=n instanceof Error?n.message:String(n);if(i.includes("Path traversal detected")){e.status(403).json({error:"Forbidden",message:i});return}let a=n.code;if(a==="ENOSPC"||a==="EPERM"||a==="EACCES"){y.warn(`SyncController.${r} disk error`,{code:a,message:i}),e.status(500).json({error:"Disk error",message:i,code:a,operation:r});return}y.error(`SyncController.${r} failed`,n instanceof Error?n:new Error(i)),e.status(500).json({error:"Internal error",message:`${r}: ${i}`})}};import{randomUUID as gve}from"crypto";function j5(t,e){let n=gve(),r=n.replace(/-/g,"").substring(0,8).toUpperCase(),i=`${r.substring(0,4)}-${r.substring(4,8)}`;return{config:t,app:e,instanceId:n,sessionId:i,startTime:Date.now(),baseUrl:`http://${t.httpHost}:${t.httpPort}`,commandQueue:new Map,pendingCommands:new Map,globalPendingCommands:[],totalCommandsProcessed:0,pluginClients:new Map,pluginCommandSessionsByClientId:new Map,pluginCommandClientIdsByProcessToken:new Map,mcpInstances:new Map,cachedSelectionMap:new Map,studioRoutingMode:"recentPriority",pinnedTargetClientId:null,isClientMode:!1,clientModeHealthTimer:null,clientModeConsecutiveHealthFailures:0,clientModeUpstreamReachable:!0,clientModeUpstreamContextCaptureEnabled:!0,clientModeLastHealthSuccessAt:null,clientModeLastHealthFailureAt:null,clientModeLastHealthError:null,shuttingDown:!1,onUpstreamPermanentlyDown:null,clientModeIdleTimeoutMs:t.clientModeIdleTimeoutMs??36e5,clientModeIdleWatchdogTimer:null,shutdownFn:null,historyManager:null,analyticsManager:null,executionContextManager:null,licenseState:null,syncController:null,internalCommandExecutor:null,dashboardFolderPicker:null,assetLibraryOpenCloudServiceFactory:null,projectChangesCleanupScheduler:null,activeSyncOwnerInstanceId:null,activeProjectRoot:null,pendingDashboardSyncRootPin:null,playtestControlCommand:null,dashboardSyncRootSwitchInFlight:!1,uiStudioRecorders:new Map,aiClientName:"",pluginVersion:"",syncedSessionToken:null,serverLastCommandAt:null}}var M5=Ut(uo(),1);oe();function L5(t){let e=M5.default.json({limit:"5mb"});t.app.use((n,r,i)=>{if(n.path.startsWith("/sync/")){i();return}e(n,r,i)}),t.app.use((n,r,i)=>{r.setHeader("Access-Control-Allow-Origin","http://localhost:3002"),r.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),r.setHeader("Access-Control-Allow-Headers","Content-Type"),i()}),t.app.use((n,r,i)=>{y.debug(`${n.method} ${n.path}`,{ip:n.ip}),i()})}eo();import{randomUUID as _S}from"crypto";eo();oe();function hve(){let t=process.env.WEPPY_ROBLOX_MCP_VERSION?.trim();return t||null}var at=hve()??"2.12.3";Ki();Xn();gm();ho();ru();eo();ho();var V5="studio-",vve=/^studio-[1-9]\d*$/;function Z_(t){return vve.test(t)}function H5(t,e){let n=new Set;for(let r of t)e!==void 0&&r.clientId===e||r.targetAlias&&Z_(r.targetAlias)&&n.add(r.targetAlias);return n}function bve(t,e){let n=H5(t,e),r=1;for(;n.has(`${V5}${r}`);)r+=1;return`${V5}${r}`}function G_(t,e){let n=H5(t,e.clientId);return e.targetAlias&&Z_(e.targetAlias)&&!n.has(e.targetAlias)||(e.targetAlias=bve(t,e.clientId)),e.targetAlias}ru();function K_(t){for(let e of t)G_(t,e)}function J_(t){let e={clientId:t.clientId,targetAlias:t.targetAlias??t.clientId.slice(0,8),lastSeen:t.lastSeen,connectedAt:t.connectedAt,transport:"websocket",connectionState:t.commandSessionState??Ze.CONNECTED};return t.placeId!==void 0&&(e.placeId=t.placeId),t.placeName!==void 0&&(e.placeName=t.placeName),t.pluginVersion!==void 0&&(e.pluginVersion=t.pluginVersion),t.studioVersion!==void 0&&(e.studioVersion=t.studioVersion),t.lastRoutedAt!==void 0&&(e.lastRoutedAt=t.lastRoutedAt),t.processToken!==void 0&&(e.processToken=t.processToken),t.inFlightRequestId!==void 0&&(e.inFlightRequestId=t.inFlightRequestId),t.studioState!==void 0&&(e.studioState=t.studioState),t.studioStateSource!==void 0&&(e.studioStateSource=t.studioStateSource),t.studioStateUpdatedAt!==void 0&&(e.studioStateUpdatedAt=t.studioStateUpdatedAt),t.playtestMode!==void 0&&(e.playtestMode=t.playtestMode),e}function AA(t){let e=Un(t);return K_(e),em(e.map(J_),null)}function Y_(t){let e=new Set;t.aiClientName&&e.add(t.aiClientName);for(let n of t.mcpInstances.values())n.aiClientName&&e.add(n.aiClientName);return Array.from(e)}function W5(t){let n=Date.now();for(let[r,i]of t.mcpInstances)i.lastSeen&&n-i.lastSeen>15e3&&(t.mcpInstances.delete(r),i.sessionId&&t.executionContextManager?.endSession(i.sessionId),y.debug("Removed stale MCP instance",{instanceId:r,lastSeen:i.lastSeen}))}function Z5(t,e,n){let r=e.query.clientId;if(r&&t.pluginClients.has(r)){let i=t.pluginClients.get(r);i.lastSeen=Date.now()}try{let i=e.body;if(!i||!Array.isArray(i.selection)||typeof i.count!="number"){y.warn("Invalid selection update request",{body:i}),n.status(400).json({error:"Invalid request body"});return}let a=r||"unknown",o=Date.now();t.cachedSelectionMap.set(a,{selection:i.selection,count:i.count,timestamp:o,clientId:a}),y.debug("Selection cache updated",{count:i.count,clientId:a,timestamp:o}),n.json({status:"ok",timestamp:o})}catch(i){y.error("Error handling selection update",i),n.status(500).json({error:"Internal server error"})}}function G5(t,e,n){let r=parseInt(e.query.maxAge)||3e4,i=hm(t,r);i?n.json({cached:!0,...i}):n.json({cached:!1,message:"No cached selection available"})}function hm(t,e=3e4,n){if(t.cachedSelectionMap.size===0)return null;let r;if(n)r=t.cachedSelectionMap.get(n);else for(let a of t.cachedSelectionMap.values())(!r||a.timestamp>r.timestamp)&&(r=a);if(!r)return null;let i=Date.now()-r.timestamp;return e===0||i<=e?r:null}function OA(t,e){let n=t.pluginClients.get(e.clientId),r=Date.now(),i=[...t.pluginClients.values()].filter(c=>c.clientId===e.clientId||c.commandSessionState!==Ze.DISCONNECTED),a=n??{clientId:e.clientId,connectedAt:r,lastSeen:r,commandsProcessed:0,connectionType:"polling"},o=G_(i,a),s={clientId:e.clientId,targetAlias:o,projectName:e.projectName??n?.projectName,placeName:e.placeName??n?.placeName,placeId:e.placeId??n?.placeId,pluginVersion:e.pluginVersion??n?.pluginVersion,studioVersion:e.studioVersion??n?.studioVersion,connectedAt:n?.connectedAt||r,lastSeen:r,commandsProcessed:n?.commandsProcessed||0,connectionType:n?.connectionType||"polling",inFlightRequestId:n?.inFlightRequestId,studioState:n?.studioState,studioStateSource:n?.studioStateSource,studioStateUpdatedAt:n?.studioStateUpdatedAt,playtestMode:n?.playtestMode,...n?.commandSessionState?{commandSessionState:n.commandSessionState}:{},...n?.processToken?{processToken:n.processToken}:{}};return t.pluginClients.set(e.clientId,s),t.syncController&&typeof t.syncController.setCurrentConnectedPlace=="function"&&typeof e.placeId=="number"&&Number.isFinite(e.placeId)&&t.syncController.setCurrentConnectedPlace(e.placeId,e.placeName??null),t.pendingCommands.has(e.clientId)||t.pendingCommands.set(e.clientId,[]),e.pluginVersion&&(t.pluginVersion=e.pluginVersion),typeof s.placeId=="number"&&Number.isFinite(s.placeId)&&__(t,s.placeId,s.placeName??null),t.analyticsManager&&(e.pluginVersion&&t.analyticsManager.setPluginVersion(e.pluginVersion),t.analyticsManager.trackPluginConnected()),y.info("Plugin client registered",{clientId:e.clientId,targetAlias:o,projectName:e.projectName,placeName:e.placeName,isReconnect:!!n}),{clientInfo:s,sessionId:t.sessionId,mcpVersion:at,mcpInstanceCount:t.mcpInstances.size+1,aiClientNames:Y_(t)}}function $A(t,e){let n=t.pluginClients.get(e),r=t.pluginClients.has(e),i=n?.commandSessionState===Ze.CONNECTED;if(t.pluginClients.delete(e),t.pendingCommands.delete(e),r&&nu(t,e),r&&t.syncController&&typeof t.syncController.clearCurrentConnectedPlaceIfMatch=="function"&&typeof n?.placeId=="number"&&Number.isFinite(n.placeId)){let a=[...t.pluginClients.values()].filter(o=>typeof o.placeId=="number"&&Number.isFinite(o.placeId)).sort((o,s)=>s.lastSeen-o.lastSeen)[0];a?t.syncController.setCurrentConnectedPlace?.(a.placeId??null,a.placeName??null):t.syncController.clearCurrentConnectedPlaceIfMatch(n.placeId)}return i&&tm(t,e,"disconnected",n),y.info("Plugin client unregistered",{clientId:e,existed:r}),r}function X_(t,e,n){try{let r=e.body;if(!r.clientId){n.status(400).json({error:"Missing clientId"});return}let i=OA(t,{clientId:r.clientId,projectName:r.projectName,placeName:r.placeName,placeId:r.placeId,pluginVersion:r.pluginVersion,studioVersion:r.studioVersion});n.json({status:"ok",clientId:r.clientId,targetAlias:i.clientInfo.targetAlias,serverInstanceId:t.instanceId,sessionId:i.sessionId,mcpVersion:i.mcpVersion,connectedAt:i.clientInfo.connectedAt,aiClientNames:i.aiClientNames,serverStartTime:t.startTime,mcpInstanceCount:i.mcpInstanceCount})}catch(r){y.error("Error registering plugin client",r),n.status(500).json({error:"Internal server error"})}}function Q_(t,e,n){let r=e.body?.clientId;if(!r){n.status(400).json({error:"Missing clientId"});return}let i=$A(t,r);n.json({status:"ok",existed:i})}function K5(t,e,n){try{let r=e.body;if(!r.instanceId){n.status(400).json({error:"Missing instanceId"});return}let i=Date.now(),a={instanceId:r.instanceId,...typeof r.sessionId=="string"?{sessionId:r.sessionId}:{},pid:r.pid,connectedAt:i,isServer:!1,lastSeen:i};r.aiClientName&&(a.aiClientName=r.aiClientName),r.cwd&&(a.cwd=r.cwd),"projectRoot"in r&&(a.projectRoot=r.projectRoot),t.mcpInstances.set(r.instanceId,a),dt(t,"mcp_status",{aiClientName:a.aiClientName??"Unknown",instanceId:r.instanceId,status:"registered"}),cu(t,{timestamp:new Date().toISOString(),type:"mcp",status:"registered",instanceId:r.instanceId,message:`MCP registered \u2014 ${a.aiClientName??r.instanceId}`,...a.aiClientName?{aiClientName:a.aiClientName}:{}}),y.info("MCP instance registered (client mode)",{instanceId:r.instanceId,pid:r.pid,cwd:r.cwd}),n.json({status:"ok",instanceId:r.instanceId,serverInstanceId:t.instanceId,sessionId:t.sessionId,mcpVersion:at,mcpInstanceCount:t.mcpInstances.size+1})}catch(r){y.error("Error registering MCP instance",r),n.status(500).json({error:"Internal server error"})}}function J5(t,e,n){let r=e.body?.instanceId;if(!r){n.status(400).json({error:"Missing instanceId"});return}let i=t.mcpInstances.get(r),a=!!i;t.mcpInstances.delete(r),i?.sessionId&&t.executionContextManager?.endSession(i.sessionId),a&&(dt(t,"mcp_status",{aiClientName:i?.aiClientName??"Unknown",instanceId:r,status:"unregistered"}),cu(t,{timestamp:new Date().toISOString(),type:"mcp",status:"unregistered",instanceId:r,message:`MCP unregistered \u2014 ${i?.aiClientName??r}`,...i?.aiClientName?{aiClientName:i.aiClientName}:{}})),y.info("MCP instance unregistered",{instanceId:r,existed:a}),n.json({status:"ok",existed:a})}function Y5(t,e,n){let{instanceId:r,aiClientName:i}=e.body;if(r&&i){let a=t.mcpInstances.get(r);a&&(a.aiClientName=i)}n.json({status:"ok"})}function X5(t){let e=3e4,n=Date.now(),r=zr({appDataDir:t.config.appDataDir});for(let[a,o]of t.pluginClients)n-o.lastSeen>e&&(t.pluginClients.delete(a),t.pendingCommands.delete(a),nu(t,a));W5(t);let i=Un(t);return K_(i),{serverInstanceId:t.instanceId,sessionId:t.sessionId,mcpVersion:at,uptime:n-t.startTime,serverStartTime:t.startTime,serverExecutable:process.execPath,serverHost:t.config.httpHost,serverPort:t.config.httpPort,serverPid:process.pid,pluginClients:i.map(J_),studioRoutingMode:t.studioRoutingMode,pinnedTargetClientId:t.pinnedTargetClientId,mcpInstances:[{instanceId:t.instanceId,pid:process.pid,connectedAt:t.startTime,isServer:!0,cwd:process.cwd(),projectRoot:r,lastSeen:n,...t.aiClientName?{aiClientName:t.aiClientName}:{}},...Array.from(t.mcpInstances.values())],mcpInstanceCount:t.mcpInstances.size+1}}function eS(t,e){e.json(X5(t))}function tS(t,e,n){let r=e.query.instanceId;r&&t.mcpInstances.has(r)&&(t.mcpInstances.get(r).lastSeen=Date.now()),W5(t);let i=Un(t);K_(i);let s={...{status:"online",connectedClients:i.length,queuedCommands:A8(t),uptime:Date.now()-t.startTime,version:at,enableContextCapture:t.executionContextManager?.isEnabled()??t.config.enableContextCapture??!0,isClientMode:t.isClientMode,shuttingDown:t.shuttingDown,pid:process.pid,sessionId:t.sessionId,nodeVersion:process.version,studioRoutingMode:t.studioRoutingMode,pinnedTargetClientId:t.pinnedTargetClientId},instanceId:t.instanceId,mcpInstanceCount:t.mcpInstances.size+1,aiClientNames:Y_(t),pluginVersion:t.pluginVersion||void 0,dashboardSseClients:t.dashboardSseClients?.size??0,websocketClients:i.length,pluginClients:i.map(J_),...t.isClientMode?{upstream:{reachable:t.clientModeUpstreamReachable,consecutiveFailures:t.clientModeConsecutiveHealthFailures,lastSuccessAt:t.clientModeLastHealthSuccessAt,lastFailureAt:t.clientModeLastHealthFailureAt,lastError:t.clientModeLastHealthError,baseUrl:t.baseUrl}}:{}};n.json(s)}function Q5(t,e,n,r){let i=e.ip||e.socket.remoteAddress||"";if(!(i==="127.0.0.1"||i==="::1"||i==="::ffff:127.0.0.1"||i==="localhost")){y.warn("Shutdown request rejected from non-localhost",{ip:i}),n.status(403).json({error:"Forbidden: localhost only"});return}y.info("Shutdown request received, initiating graceful shutdown",{requestedBy:i,uptime:Date.now()-t.startTime}),n.json({status:"shutting_down",message:"Server will shutdown gracefully",pid:process.pid}),setTimeout(async()=>{try{await r(),y.info("Graceful shutdown completed"),process.exit(0)}catch(o){y.error("Error during graceful shutdown",o),process.exit(1)}},100)}async function nS(t){if(t.isClientMode)try{let e=await fetch(`${t.baseUrl}/connection-info`);if(e.ok)return await e.json()}catch(e){y.warn("Failed to fetch connection info from server",{error:e})}return X5(t)}ho();var St={bridgeRunTest:"manage_studio_run_test_bridge",placeInfo:"system_info_place_info",clearLogs:"manage_logs_clear",createScript:"manage_scripts_create",getLogs:"manage_logs_get",deleteScript:"manage_scripts_delete",canonical:{playStart:"manage_studio_play_start",playStop:"manage_studio_play_stop",playPause:"manage_studio_play_pause",playResume:"manage_studio_play_resume",playStatus:"manage_studio_play_status",runTest:"manage_studio_run_test"}},_ve=new Set([St.canonical.runTest]),Sve=new Set([St.canonical.playStop]),bqe=new Set([St.canonical.playStart,St.canonical.playStop,St.canonical.playPause,St.canonical.playResume,St.canonical.playStatus]);function Si(t){return _ve.has(t)}function ym(t){return Sve.has(t)}var wqe=St.canonical.playStop,e9=[5e3,15e3];ru();var wve=new Set(["manage_assets_export_selection_rbxm","manage_assets_export_path_rbxm","manage_assets_review_model","manage_assets_generate_model","manage_assets_import_rbxm","manage_assets_generate_thumbnail"]),xn=class t extends Error{code;routing;constructor(e,n,r){super(n),this.name="CommandTargetSelectionError",this.code=e,this.routing=r,Object.setPrototypeOf(this,t.prototype)}};function Ive(t={},e){let n={},r=t.clientId,i=t.targetAlias,a=t.placeId;if(r!==void 0){if(typeof r!="string"||r.trim().length===0)throw new xn("invalid_target_selector","clientId target selector must be a non-empty string",{selectionMode:"clientId",...typeof r=="string"?{requestedClientId:r.trim()}:{}});n.requestedClientId=r.trim()}if(i!==void 0){if(typeof i!="string"||i.trim().length===0)throw new xn("invalid_target_selector","targetAlias target selector must be a non-empty string",{selectionMode:"targetAlias",...typeof i=="string"?{requestedTargetAlias:i.trim()}:{}});n.requestedTargetAlias=i.trim()}if(a!==void 0&&Cve(e,t)){if(typeof a!="number"||!Number.isFinite(a))throw new xn("invalid_target_selector","placeId target selector must be a finite number",{selectionMode:"placeId"});n.requestedPlaceId=a}return n}function rS(t,e,n={},r){let i=Ive(n,r),a=o8(e,t.studioRoutingMode==="pinned"?t.pinnedTargetClientId:null);if(i.requestedClientId!==void 0)return Pve(a,i);if(i.requestedTargetAlias!==void 0)return kve(a,i);if(i.requestedPlaceId!==void 0)return Eve(a,i);if(t.studioRoutingMode==="pinned"&&t.pinnedTargetClientId!==null){let s=a.find(c=>c.clientId===t.pinnedTargetClientId);if(s)return{targetClientId:s.clientId,routing:Zr("pinnedTarget",i,s)}}let o=a[0];return o?{targetClientId:o.clientId,routing:Zr("recentPriority",i,o)}:{routing:{selectionMode:"globalQueue"}}}function Cve(t,e){return!t||!wve.has(t)?!0:e.scope==="shared"}function Pve(t,e){let n=t.find(r=>r.clientId===e.requestedClientId);if(!n)throw new xn("target_client_not_found",`Target client not found: ${e.requestedClientId}`,Zr("clientId",e));if(e.requestedTargetAlias!==void 0&&n.targetAlias!==e.requestedTargetAlias)throw new xn("target_selector_mismatch",`Target client ${n.clientId} does not match targetAlias ${e.requestedTargetAlias}`,Zr("clientId",e,n));return t9("clientId",e,n),{targetClientId:n.clientId,routing:Zr("clientId",e,n)}}function kve(t,e){let n=t.find(r=>r.targetAlias!==void 0&&Z_(r.targetAlias)&&r.targetAlias===e.requestedTargetAlias);if(!n)throw new xn("target_alias_not_found",`Target alias not found: ${e.requestedTargetAlias}`,Zr("targetAlias",e));return t9("targetAlias",e,n),{targetClientId:n.clientId,routing:Zr("targetAlias",e,n)}}function Eve(t,e){let n=t.filter(i=>i.placeId===e.requestedPlaceId);if(n.length===0)throw new xn("target_place_not_found",`Target place not found: ${e.requestedPlaceId}`,Zr("placeId",e));if(n.length>1)throw new xn("target_place_ambiguous",`Target place is ambiguous: ${e.requestedPlaceId}`,Zr("placeId",e));let r=n[0];return{targetClientId:r.clientId,routing:Zr("placeId",e,r)}}function t9(t,e,n){if(e.requestedPlaceId!==void 0&&n.placeId!==e.requestedPlaceId)throw new xn("target_selector_mismatch",`Target client ${n.clientId} is not connected to placeId ${e.requestedPlaceId}`,Zr(t,e,n))}function Zr(t,e,n){let r={selectionMode:t};return e.requestedClientId!==void 0&&(r.requestedClientId=e.requestedClientId),e.requestedTargetAlias!==void 0&&(r.requestedTargetAlias=e.requestedTargetAlias),e.requestedPlaceId!==void 0&&(r.requestedPlaceId=e.requestedPlaceId),n!==void 0&&(r.actualClientId=n.clientId,n.targetAlias!==void 0&&(r.actualTargetAlias=n.targetAlias),n.placeId!==void 0&&(r.actualPlaceId=n.placeId),n.placeName!==void 0&&(r.actualPlaceName=n.placeName)),r}jT();oe();pm();var Zs={query_instances:{discriminator:"action",validActions:new Set(["get","children","find_child","find_descendant","wait_for_child","class_info","search_name","search_class","search_property","search_tag","file_tree","project_structure","descendants","ancestors"]),allowedParams:{query_instances_get:new Set(["path","sessionDebugId","siblingIndex","placeId","clientId","targetAlias"]),query_instances_children:new Set(["path","sessionDebugId","siblingIndex","recursive","maxDepth","placeId","clientId","targetAlias"]),query_instances_find_child:new Set(["path","childName","placeId","clientId","targetAlias"]),query_instances_find_descendant:new Set(["path","descendantName","placeId","clientId","targetAlias"]),query_instances_wait_for_child:new Set(["path","childName","timeout","placeId","clientId","targetAlias"]),query_instances_class_info:new Set(["className","placeId","clientId","targetAlias"]),query_instances_search_name:new Set(["root","query","caseSensitive","maxResults","placeId","clientId","targetAlias"]),query_instances_search_class:new Set(["className","root","includeSubclasses","maxResults","placeId","clientId","targetAlias"]),query_instances_search_property:new Set(["root","propertyName","propertyValue","maxResults","placeId","clientId","targetAlias"]),query_instances_search_tag:new Set(["root","tag","maxResults","placeId","clientId","targetAlias"]),query_instances_file_tree:new Set(["maxDepth","root","includeServices","placeId","clientId","targetAlias"]),query_instances_project_structure:new Set(["root","depth","placeId","clientId","targetAlias"]),query_instances_descendants:new Set(["path","sessionDebugId","siblingIndex","maxResults","placeId","clientId","targetAlias"]),query_instances_ancestors:new Set(["path","sessionDebugId","siblingIndex","placeId","clientId","targetAlias"])},paramAliases:{query_instances_search_name:{query:"pattern"},query_instances_search_property:{root:"rootPath"},query_instances_search_tag:{root:"rootPath"},query_instances_project_structure:{root:"rootPath"}}},mutate_instances:{discriminator:"action",validActions:new Set(["create","create_with_props","delete","clone","move","rename","pivot","create_tree","mass_create","mass_delete","mass_duplicate","smart_duplicate","scatter"]),allowedParams:{mutate_instances_create:new Set(["className","parent","name","properties","placeId","clientId","targetAlias"]),mutate_instances_create_with_props:new Set(["className","parent","name","properties","placeId","clientId","targetAlias"]),mutate_instances_delete:new Set(["path","sessionDebugId","siblingIndex","placeId","clientId","targetAlias"]),mutate_instances_clone:new Set(["path","sourcePath","sessionDebugId","siblingIndex","targetParent","newName","placeId","clientId","targetAlias"]),mutate_instances_move:new Set(["path","sessionDebugId","siblingIndex","newParent","placeId","clientId","targetAlias"]),mutate_instances_rename:new Set(["path","sessionDebugId","siblingIndex","newName","placeId","clientId","targetAlias"]),mutate_instances_pivot:new Set(["path","sessionDebugId","siblingIndex","position","cframe","offset","placeId","clientId","targetAlias"]),mutate_instances_create_tree:new Set(["parent","tree","placeId","clientId","targetAlias"]),mutate_instances_mass_create:new Set(["instances","placeId","clientId","targetAlias"]),mutate_instances_mass_delete:new Set(["paths","placeId","clientId","targetAlias"]),mutate_instances_mass_duplicate:new Set(["targetParent","paths","placeId","clientId","targetAlias"]),mutate_instances_smart_duplicate:new Set(["path","sessionDebugId","siblingIndex","targetParent","offset","count","placeId","clientId","targetAlias"]),mutate_instances_scatter:new Set(["templatePaths","region","count","seed","maxSlope","avoidWater","alignToNormal","scaleJitter","minSpacing","parentName","placeId","clientId","targetAlias"])},paramAliases:{mutate_instances_clone:{path:"sourcePath"},mutate_instances_smart_duplicate:{spacing:"offset"}}},manage_properties:{discriminator:"action",validActions:new Set(["get","set","get_all","set_multiple","get_attr","set_attr","get_all_attrs","delete_attr","add_tag","remove_tag","check_tag","get_tags","get_tagged","set_calculated","set_relative","mass_set","mass_get","modify_children"]),allowedParams:{manage_properties_get:new Set(["path","property","placeId","clientId","targetAlias"]),manage_properties_set:new Set(["path","property","value","placeId","clientId","targetAlias"]),manage_properties_get_all:new Set(["path","includeReadOnly","placeId","clientId","targetAlias"]),manage_properties_set_multiple:new Set(["path","properties","placeId","clientId","targetAlias"]),manage_properties_get_attr:new Set(["path","attribute","placeId","clientId","targetAlias"]),manage_properties_set_attr:new Set(["path","value","attribute","placeId","clientId","targetAlias"]),manage_properties_get_all_attrs:new Set(["path","placeId","clientId","targetAlias"]),manage_properties_delete_attr:new Set(["path","attribute","placeId","clientId","targetAlias"]),manage_properties_add_tag:new Set(["path","tag","placeId","clientId","targetAlias"]),manage_properties_remove_tag:new Set(["path","tag","placeId","clientId","targetAlias"]),manage_properties_check_tag:new Set(["path","tag","placeId","clientId","targetAlias"]),manage_properties_get_tags:new Set(["path","placeId","clientId","targetAlias"]),manage_properties_get_tagged:new Set(["tagName","root","maxResults","placeId","clientId","targetAlias"]),manage_properties_set_calculated:new Set(["path","expression","variables","propertyName","placeId","clientId","targetAlias"]),manage_properties_set_relative:new Set(["path","value","operation","amount","propertyName","placeId","clientId","targetAlias"]),manage_properties_mass_set:new Set(["paths","propertyName","propertyValue","placeId","clientId","targetAlias"]),manage_properties_mass_get:new Set(["paths","propertyName","placeId","clientId","targetAlias"]),manage_properties_modify_children:new Set(["parentPath","modifications","propertyName","propertyValue","filter","recursive","placeId","clientId","targetAlias"])},paramAliases:{manage_properties_get_tagged:{tagName:"tag",root:"rootPath"},manage_properties_set_relative:{amount:"value"}}},manage_scripts:{discriminator:"action",validActions:new Set(["get_source","set_source","create","delete","edit_replace","edit_insert","edit_delete","search","replace","get_dependencies","validate"]),allowedParams:{manage_scripts_get_source:new Set(["path","startLine","endLine","placeId","clientId","targetAlias"]),manage_scripts_set_source:new Set(["path","source","validate","placeId","clientId","targetAlias"]),manage_scripts_create:new Set(["source","scriptType","parent","name","placeId","clientId","targetAlias"]),manage_scripts_delete:new Set(["path","placeId","clientId","targetAlias"]),manage_scripts_edit_replace:new Set(["path","startLine","endLine","newLines","validate","placeId","clientId","targetAlias"]),manage_scripts_edit_insert:new Set(["path","lines","afterLine","content","validate","placeId","clientId","targetAlias"]),manage_scripts_edit_delete:new Set(["path","startLine","endLine","validate","placeId","clientId","targetAlias"]),manage_scripts_search:new Set(["path","pattern","caseSensitive","wholeWord","usePattern","maxResults","placeId","clientId","targetAlias"]),manage_scripts_replace:new Set(["path","pattern","replacement","usePattern","dryRun","placeId","clientId","targetAlias"]),manage_scripts_get_dependencies:new Set(["path","placeId","clientId","targetAlias"]),manage_scripts_validate:new Set(["source","path","placeId","clientId","targetAlias"])},paramAliases:{manage_scripts_edit_replace:{newLines:"newContent"},manage_scripts_edit_insert:{lines:"content"},manage_scripts_replace:{pattern:"searchPattern"}}},manage_ui:{discriminator:"action",validActions:new Set(["design_brief","create_tree","update","delete","preview","check"]),allowedParams:{manage_ui_design_brief:new Set(["brief","placeId","clientId","targetAlias"]),manage_ui_create_tree:new Set(["briefId","tree","placeId","clientId","targetAlias"]),manage_ui_update:new Set(["targetPath","changes","briefId","placeId","clientId","targetAlias"]),manage_ui_delete:new Set(["targetPath","placeId","clientId","targetAlias"]),manage_ui_preview:new Set(["targetPath","briefId","placeId","clientId","targetAlias"]),manage_ui_check:new Set(["targetPath","briefId","includeVisualAnalysis","snapshotId","placeId","clientId","targetAlias"])}},manage_lighting:{discriminator:"action",validActions:new Set(["lighting","atmosphere","sky","terrain_props","time","mood"]),allowedParams:{manage_lighting_lighting:new Set(["properties","placeId","clientId","targetAlias"]),manage_lighting_atmosphere:new Set(["properties","createIfMissing","placeId","clientId","targetAlias"]),manage_lighting_sky:new Set(["properties","createIfMissing","placeId","clientId","targetAlias"]),manage_lighting_terrain_props:new Set(["properties","placeId","clientId","targetAlias"]),manage_lighting_time:new Set(["time","clockTime","placeId","clientId","targetAlias"]),manage_lighting_mood:new Set(["preset","overrides","placeId","clientId","targetAlias"])}},manage_selection:{discriminator:"action",validActions:new Set(["get","set","clear","cached","context","details","add","remove","watch"]),allowedParams:{manage_selection_get:new Set(["placeId","clientId","targetAlias"]),manage_selection_set:new Set(["paths","placeId","clientId","targetAlias"]),manage_selection_clear:new Set(["placeId","clientId","targetAlias"]),manage_selection_cached:new Set(["maxAge"]),manage_selection_context:new Set(["includeSource","includeProperties","includeChildren","placeId","clientId","targetAlias"]),manage_selection_details:new Set(["maxDepth","includeAncestors","placeId","clientId","targetAlias"]),manage_selection_add:new Set(["paths","placeId","clientId","targetAlias"]),manage_selection_remove:new Set(["paths","placeId","clientId","targetAlias"]),manage_selection_watch:new Set(["placeId","clientId","targetAlias"])}},manage_camera:{discriminator:"action",validActions:new Set(["info","focus_path","focus_position","suggest","screenshot"]),allowedParams:{manage_camera_info:new Set(["placeId","clientId","targetAlias"]),manage_camera_focus_path:new Set(["path","distance","duration","offset","respectAutoFocusSetting","placeId","clientId","targetAlias"]),manage_camera_focus_position:new Set(["position","distance","duration","offset","lookAt","respectAutoFocusSetting","placeId","clientId","targetAlias"]),manage_camera_suggest:new Set(["path","placeId","clientId","targetAlias"]),manage_camera_screenshot:new Set(["placeId","clientId","targetAlias"])},paramAliases:{manage_camera_suggest:{path:"targetPath"}}},manage_tween:{discriminator:"action",validActions:new Set(["create","play","pause","cancel"]),allowedParams:{manage_tween_create:new Set(["path","tweenInfo","properties","placeId","clientId","targetAlias"]),manage_tween_play:new Set(["tweenId","placeId","clientId","targetAlias"]),manage_tween_pause:new Set(["tweenId","placeId","clientId","targetAlias"]),manage_tween_cancel:new Set(["tweenId","placeId","clientId","targetAlias"])}},manage_audio:{discriminator:"action",validActions:new Set(["play","stop","pause","resume","set_listener"]),allowedParams:{manage_audio_play:new Set(["path","soundId","volume","looped","playbackSpeed","placeId","clientId","targetAlias"]),manage_audio_stop:new Set(["path","placeId","clientId","targetAlias"]),manage_audio_pause:new Set(["path","placeId","clientId","targetAlias"]),manage_audio_resume:new Set(["path","placeId","clientId","targetAlias"]),manage_audio_set_listener:new Set(["listenerType","listenerPath","placeId","clientId","targetAlias"])}},manage_animation:{discriminator:"action",validActions:new Set(["load","play","stop","get_tracks"]),allowedParams:{manage_animation_load:new Set(["path","animationId","placeId","clientId","targetAlias"]),manage_animation_play:new Set(["path","trackId","speed","fadeTime","weight","priority","placeId","clientId","targetAlias"]),manage_animation_stop:new Set(["path","trackId","fadeTime","placeId","clientId","targetAlias"]),manage_animation_get_tracks:new Set(["path","placeId","clientId","targetAlias"])}},manage_physics:{discriminator:"action",validActions:new Set(["register_group","set_collidable","get_groups"]),allowedParams:{manage_physics_register_group:new Set(["groupName","placeId","clientId","targetAlias"]),manage_physics_set_collidable:new Set(["group1","group2","collidable","placeId","clientId","targetAlias"]),manage_physics_get_groups:new Set(["placeId","clientId","targetAlias"])}},manage_effects:{discriminator:"action",validActions:new Set(["emit","clear","toggle"]),allowedParams:{manage_effects_emit:new Set(["path","count","placeId","clientId","targetAlias"]),manage_effects_clear:new Set(["path","placeId","clientId","targetAlias"]),manage_effects_toggle:new Set(["path","enabled","placeId","clientId","targetAlias"])}},manage_terrain:{discriminator:"action",validActions:new Set(["fill_block","fill_ball","fill_cylinder","fill_wedge","clear_region","clear_bounds","replace_material","colors_get","colors_set","read_voxel","read_voxels","write_voxels","generate","smooth"]),allowedParams:{manage_terrain_fill_block:new Set(["cframe","size","placeId","clientId","targetAlias"]),manage_terrain_fill_ball:new Set(["center","radius","placeId","clientId","targetAlias"]),manage_terrain_fill_cylinder:new Set(["cframe","radius","height","placeId","clientId","targetAlias"]),manage_terrain_fill_wedge:new Set(["cframe","size","placeId","clientId","targetAlias"]),manage_terrain_clear_region:new Set(["region","placeId","clientId","targetAlias"]),manage_terrain_clear_bounds:new Set(["min","max","placeId","clientId","targetAlias"]),manage_terrain_replace_material:new Set(["material","region","sourceMaterial","targetMaterial","placeId","clientId","targetAlias"]),manage_terrain_colors_get:new Set(["material","placeId","clientId","targetAlias"]),manage_terrain_colors_set:new Set(["material","color","placeId","clientId","targetAlias"]),manage_terrain_read_voxel:new Set(["position","placeId","clientId","targetAlias"]),manage_terrain_read_voxels:new Set(["region","resolution","placeId","clientId","targetAlias"]),manage_terrain_write_voxels:new Set(["region","resolution","materials","occupancy","placeId","clientId","targetAlias"]),manage_terrain_generate:new Set(["region","preset","seed","baseHeight","amplitude","frequency","octaves","persistence","waterLevel","edgeBlend","materialPalette","layers","placeId","clientId","targetAlias"]),manage_terrain_smooth:new Set(["region","intensity","placeId","clientId","targetAlias"])}},spatial_query:{discriminator:"action",validActions:new Set(["raycast","find_ground","check_placement","multi_raycast","scan_area","find_flat","find_spawn","analyze_walkable","spatial_map","find_space","bounds","snap_grid","collision"]),allowedParams:{spatial_query_raycast:new Set(["origin","direction","filterType","filterList","filterInstances","ignoreWater","placeId","clientId","targetAlias"]),spatial_query_find_ground:new Set(["maxDistance","position","filterList","filterInstances","offset","placeId","clientId","targetAlias"]),spatial_query_check_placement:new Set(["position","size","filterList","filterInstances","rotation","checkGround","placeId","clientId","targetAlias"]),spatial_query_multi_raycast:new Set(["filterType","filterList","filterInstances","ignoreWater","rays","placeId","clientId","targetAlias"]),spatial_query_scan_area:new Set(["size","filterList","filterInstances","center","resolution","maxResults","placeId","clientId","targetAlias"]),spatial_query_find_flat:new Set(["searchArea","minSize","maxSlope","tolerance","maxResults","placeId","clientId","targetAlias"]),spatial_query_find_spawn:new Set(["searchArea","spawnSize","minSpacing","preferOutdoor","count","placeId","clientId","targetAlias"]),spatial_query_analyze_walkable:new Set(["area","maxSlope","resolution","characterHeight","maxStepHeight","placeId","clientId","targetAlias"]),spatial_query_spatial_map:new Set(["path","rootPath","includeModels","maxResults","placeId","clientId","targetAlias"]),spatial_query_find_space:new Set(["size","searchArea","gridSize","gridSnap","padding","placeId","clientId","targetAlias"]),spatial_query_bounds:new Set(["path","paths","placeId","clientId","targetAlias"]),spatial_query_snap_grid:new Set(["gridSize","path","gridSnap","axes","placeId","clientId","targetAlias"]),spatial_query_collision:new Set(["position","path","ignorePaths","placeId","clientId","targetAlias"])},paramAliases:{spatial_query_spatial_map:{path:"rootPath"}}},manage_assets:{discriminator:"action",validActions:new Set(["insert","info","search","search_insert","insert_free","insert_package","export_selection_json","export_selection_rbxm","export_path_rbxm","review_model","generate_model","upload_asset","import_rbxm","generate_thumbnail"]),allowedParams:{manage_assets_insert:new Set(["assetId","parent","name","position","placeId","clientId","targetAlias"]),manage_assets_info:new Set(["assetId","placeId","clientId","targetAlias"]),manage_assets_search:new Set(["query","maxResults","category","sortType","placeId","clientId","targetAlias"]),manage_assets_search_insert:new Set(["parent","name","query","placeId","clientId","targetAlias"]),manage_assets_insert_free:new Set(["assetId","parent","name","position","placeId","clientId","targetAlias"]),manage_assets_insert_package:new Set(["assetId","parent","name","placeId","clientId","targetAlias"]),manage_assets_export_selection_json:new Set(["format","includeProperties","includeChildren","maxDepth","placeId","clientId","targetAlias"]),manage_assets_export_selection_rbxm:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","displayName","description","thumbnailMode","uploadMode","uploadTemporaryAssets","creatorType","creatorId","clientId","targetAlias"]),manage_assets_export_path_rbxm:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","sourcePath","displayName","description","thumbnailMode","uploadMode","uploadTemporaryAssets","creatorType","creatorId","clientId","targetAlias"]),manage_assets_review_model:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","sourcePath","displayName","description","thumbnailMode","uploadMode","uploadTemporaryAssets","creatorType","creatorId","exportToLibrary","expectedUse","expectedGroups","maxDescendants","maxDepth","readiness","clientId","targetAlias"]),manage_assets_generate_model:new Set(["contextId","contextSummary","replayMetadata","placeId","category","prompt","schemaMode","predefinedSchema","schemaGroups","size","maxTriangles","generateTextures","review","targetParent","name","displayName","expectedUse","expectedGroups","maxDescendants","maxDepth","readiness","anchorMode","clientId","targetAlias"]),manage_assets_upload_asset:new Set(["contextId","contextSummary","replayMetadata","placeId","category","assetType","sourcePath","displayName","description","creatorType","creatorId","clientId","targetAlias"]),manage_assets_import_rbxm:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","assetLibraryAssetId","targetParent","name","clientId","targetAlias"]),manage_assets_generate_thumbnail:new Set(["contextId","contextSummary","replayMetadata","scope","placeId","category","assetLibraryAssetId","clientId","targetAlias"])},paramAliases:{manage_assets_search:{maxResults:"limit"}}},manage_open_cloud_assets:{discriminator:"action",validActions:new Set(["preflight","credential_status","capabilities","upload","update","info","operation_status"]),allowedParams:{manage_open_cloud_assets_preflight:new Set(["filePath","category","creatorType","creatorId"]),manage_open_cloud_assets_credential_status:new Set([]),manage_open_cloud_assets_capabilities:new Set([]),manage_open_cloud_assets_upload:new Set(["contextId","contextSummary","replayMetadata","filePath","category","displayName","description","creatorType","creatorId","expectedPrice","waitForOperation","operationPollTimeoutMs","operationPollIntervalMs"]),manage_open_cloud_assets_update:new Set(["contextId","contextSummary","replayMetadata","assetId","filePath","category","displayName","description","creatorType","creatorId","expectedPrice","updateMask","waitForOperation","operationPollTimeoutMs","operationPollIntervalMs"]),manage_open_cloud_assets_info:new Set(["assetId","readMask"]),manage_open_cloud_assets_operation_status:new Set(["operationId"])}},manage_sync:{discriminator:"action",validActions:new Set(["status_current_place","history","directions","read_file","write_file","progress"]),allowedParams:{manage_sync_status_current_place:new Set([]),manage_sync_history:new Set(["placeId","query"]),manage_sync_directions:new Set(["placeId"]),manage_sync_read_file:new Set(["placeId","instancePath"]),manage_sync_write_file:new Set(["placeId","instancePath","content"]),manage_sync_progress:new Set([])}},workspace_state:{discriminator:"action",validActions:new Set(["sync","snapshot","changes","viewport","clear_history","metadata","scripts","selection_info","clear_cache"]),allowedParams:{workspace_state_sync:new Set(["includeMetadata","placeId","clientId","targetAlias"]),workspace_state_snapshot:new Set(["placeId","clientId","targetAlias"]),workspace_state_changes:new Set(["limit","placeId","clientId","targetAlias"]),workspace_state_viewport:new Set(["includeCameraInfo","includeSelectionBounds","placeId","clientId","targetAlias"]),workspace_state_clear_history:new Set(["placeId","clientId","targetAlias"]),workspace_state_metadata:new Set(["placeId","clientId","targetAlias"]),workspace_state_scripts:new Set(["placeId","clientId","targetAlias"]),workspace_state_selection_info:new Set(["placeId","clientId","targetAlias"]),workspace_state_clear_cache:new Set(["placeId","clientId","targetAlias"])}},manage_logs:{discriminator:"action",validActions:new Set(["get","clear","errors"]),allowedParams:{manage_logs_get:new Set(["level","limit","pattern","since","sinceSeq","placeId","clientId","targetAlias"]),manage_logs_clear:new Set(["placeId","clientId","targetAlias"]),manage_logs_errors:new Set(["limit","placeId","clientId","targetAlias"])},paramAliases:{manage_logs_get:{level:"type"}}},system_info:{discriminator:"action",validActions:new Set(["ping","connection","usage","place_info","services","preflight"]),allowedParams:{system_info_ping:new Set(["message","placeId","clientId","targetAlias"]),system_info_connection:new Set([]),system_info_usage:new Set(["placeId","clientId","targetAlias"]),system_info_place_info:new Set(["placeId","clientId","targetAlias"]),system_info_services:new Set(["placeId","clientId","targetAlias"]),system_info_preflight:new Set(["placeId","clientId","targetAlias"])}},manage_studio:{discriminator:"action",validActions:new Set(["toggle_ui_preview","play_start","play_stop","play_pause","play_resume","play_status","run_test"]),allowedParams:{manage_studio_toggle_ui_preview:new Set(["enabled","placeId","clientId","targetAlias"]),manage_studio_play_start:new Set(["mode","placeId","clientId","targetAlias"]),manage_studio_play_stop:new Set(["placeId","clientId","targetAlias"]),manage_studio_play_pause:new Set(["placeId","clientId","targetAlias"]),manage_studio_play_resume:new Set(["placeId","clientId","targetAlias"]),manage_studio_play_status:new Set(["placeId","clientId","targetAlias"]),manage_studio_run_test:new Set(["mode","script","test_name","timeout","placeId","clientId","targetAlias","contextId","contextSummary","replayMetadata"])}}};var Rve={manage_scripts_validate:"internal",manage_selection_cached:"internal",manage_open_cloud_assets_preflight:"internal",manage_open_cloud_assets_credential_status:"internal",manage_open_cloud_assets_capabilities:"internal",manage_open_cloud_assets_upload:"internal",manage_open_cloud_assets_update:"internal",manage_open_cloud_assets_info:"internal",manage_open_cloud_assets_operation_status:"internal",manage_sync_status_current_place:"internal",manage_sync_history:"internal",manage_sync_directions:"internal",manage_sync_read_file:"internal",manage_sync_write_file:"internal",manage_sync_progress:"internal",system_info_connection:"internal",system_info_preflight:"internal",manage_studio_run_test:"internal"};function iS(t){return Rve[t]||"plugin"}var n9=new Set(["batch_execute","execute_luau","extended_call_method","extended_call_methods","extended_get_properties","extended_get_property","extended_set_properties","extended_set_property","manage_animation_get_tracks","manage_animation_load","manage_animation_play","manage_animation_stop","manage_assets_export_path_rbxm","manage_assets_export_selection_json","manage_assets_export_selection_rbxm","manage_assets_generate_model","manage_assets_generate_thumbnail","manage_assets_import_rbxm","manage_assets_info","manage_assets_insert","manage_assets_insert_free","manage_assets_insert_package","manage_assets_review_model","manage_assets_search","manage_assets_search_insert","manage_assets_upload_asset","manage_audio_pause","manage_audio_play","manage_audio_resume","manage_audio_set_listener","manage_audio_stop","manage_camera_screenshot","manage_effects_clear","manage_effects_emit","manage_effects_toggle","manage_lighting_atmosphere","manage_lighting_lighting","manage_lighting_mood","manage_lighting_sky","manage_lighting_terrain_props","manage_lighting_time","manage_open_cloud_assets_capabilities","manage_open_cloud_assets_credential_status","manage_open_cloud_assets_info","manage_open_cloud_assets_operation_status","manage_open_cloud_assets_preflight","manage_open_cloud_assets_update","manage_open_cloud_assets_upload","manage_physics_get_groups","manage_physics_register_group","manage_physics_set_collidable","manage_properties_mass_get","manage_properties_mass_set","manage_properties_modify_children","manage_properties_set_calculated","manage_properties_set_relative","manage_scripts_replace","manage_selection_add","manage_selection_context","manage_selection_details","manage_selection_remove","manage_selection_watch","manage_studio_play_pause","manage_studio_play_resume","manage_studio_play_start","manage_studio_play_status","manage_studio_play_stop","manage_studio_run_test","manage_studio_toggle_ui_preview","manage_sync_directions","manage_sync_history","manage_sync_progress","manage_sync_read_file","manage_sync_status_current_place","manage_sync_write_file","manage_terrain_clear_bounds","manage_terrain_clear_region","manage_terrain_colors_get","manage_terrain_colors_set","manage_terrain_fill_ball","manage_terrain_fill_block","manage_terrain_fill_cylinder","manage_terrain_fill_wedge","manage_terrain_generate","manage_terrain_read_voxel","manage_terrain_read_voxels","manage_terrain_replace_material","manage_terrain_smooth","manage_terrain_write_voxels","manage_tween_cancel","manage_tween_create","manage_tween_pause","manage_tween_play","manage_ui_check","manage_ui_create_tree","manage_ui_delete","manage_ui_design_brief","manage_ui_preview","manage_ui_update","mutate_instances_create_tree","mutate_instances_mass_create","mutate_instances_mass_delete","mutate_instances_mass_duplicate","mutate_instances_scatter","mutate_instances_smart_duplicate","query_instances_ancestors","query_instances_descendants","query_instances_file_tree","query_instances_project_structure","query_instances_search_property","query_instances_search_tag","spatial_query_analyze_walkable","spatial_query_bounds","spatial_query_check_placement","spatial_query_collision","spatial_query_find_flat","spatial_query_find_ground","spatial_query_find_space","spatial_query_find_spawn","spatial_query_multi_raycast","spatial_query_raycast","spatial_query_scan_area","spatial_query_snap_grid","spatial_query_spatial_map","system_info_place_info","system_info_services","workspace_state_changes","workspace_state_clear_cache","workspace_state_clear_history","workspace_state_metadata","workspace_state_scripts","workspace_state_selection_info","workspace_state_snapshot","workspace_state_sync","workspace_state_viewport"]),DA=new Set(["system_info_connection","system_info_ping","system_info_preflight","system_info_usage"]);function tr(t){return n9.has(t)?"pro":"basic"}bi();aS();import{readFile as Kve}from"node:fs/promises";import Jve from"node:path";import{createHash as Vve,randomUUID as LA}from"node:crypto";import{mkdir as wm,readFile as d9,readdir as p9,rename as f9,rm as Hve,stat as Wve,writeFile as pS}from"node:fs/promises";import Yt from"node:path";import{extname as $ve}from"node:path";import{constants as Dve}from"node:fs";import{access as Nve,stat as jve}from"node:fs/promises";var bm=20*1024*1024,cS=[{category:"image",assetType:"Image",folder:"images",extensions:[".png",".jpeg",".jpg",".bmp",".tga"],supportsContentUpdate:!1,contentTypes:{".png":"image/png",".jpeg":"image/jpeg",".jpg":"image/jpeg",".bmp":"image/bmp",".tga":"image/tga"}},{category:"decal",assetType:"Decal",folder:"decals",extensions:[".png",".jpeg",".jpg",".bmp",".tga"],supportsContentUpdate:!1,contentTypes:{".png":"image/png",".jpeg":"image/jpeg",".jpg":"image/jpeg",".bmp":"image/bmp",".tga":"image/tga"}},{category:"audio",assetType:"Audio",folder:"audio",extensions:[".mp3",".ogg",".wav",".flac"],supportsContentUpdate:!1,contentTypes:{".mp3":"audio/mpeg",".ogg":"audio/ogg",".wav":"audio/wav",".flac":"audio/flac"}},{category:"mesh",assetType:"Mesh",folder:"meshes",extensions:[".mesh"],supportsContentUpdate:!1,contentTypes:{".mesh":"application/octet-stream"}},{category:"model",assetType:"Model",folder:"models",extensions:[".fbx",".gltf",".glb",".rbxm",".rbxmx"],supportsContentUpdate:!0,contentTypes:{".fbx":"model/fbx",".gltf":"model/gltf+json",".glb":"model/gltf-binary",".rbxm":"model/x-rbxm",".rbxmx":"model/x-rbxm"}},{category:"video",assetType:"Video",folder:"videos",extensions:[".mp4",".mov"],supportsContentUpdate:!1,contentTypes:{".mp4":"video/mp4",".mov":"video/quicktime"}},{category:"animation",assetType:"Animation",folder:"animations",extensions:[".rbxm",".rbxmx"],supportsContentUpdate:!0,contentTypes:{".rbxm":"model/x-rbxm",".rbxmx":"model/x-rbxm"}}],Mve=new Map(cS.map(t=>[t.category,t]));function a9(t){if(!t)throw new Error("Open Cloud asset upload is disabled in WEPPY Dashboard settings.")}function oS(t,e){return t.split(e.apiKey).join("[redacted]")}function sS(t){let e=Mve.get(t);if(!e)throw new Error(`Unsupported asset category: ${t}`);return e}function lS(t){return sS(t)}async function jA(t,e,n=bm){let r=sS(t),i=$ve(e).toLowerCase(),a=r.contentTypes[i]??null,o=await jve(e),s=!0;try{await Nve(e,Dve.R_OK)}catch{s=!1}return{category:t,extension:i,contentType:a,formatValid:a!==null,sizeBytes:o.size,sizeValid:o.size<=n,maxFileSizeBytes:n,regularFile:o.isFile(),readable:s}}function o9(t,e){let n=t.creatorType??e.creatorType,r=t.creatorId??e.creatorId;if(!n||!r)throw new Error("creatorType and creatorId are required for Roblox Open Cloud asset upload/update.");return{...t,creatorType:n,creatorId:r}}async function s9(t,e,n){let r=await jA(t.category,e,n);if(!r.formatValid||!r.contentType)throw new Error(`Unsupported file extension ${r.extension||"(none)"} for ${t.category}.`);if(!r.regularFile)throw new Error("Asset path must reference a regular file.");if(!r.readable)throw new Error("Asset file is not readable.");if(!r.sizeValid)throw new Error(`Asset file is too large. Maximum size is ${n} bytes.`);return r.contentType}function c9(t){return typeof t.path=="string"&&t.path.startsWith("operations/")?t.path:null}function l9(t,e,n,r){let i={apiKey:t.apiKey,operationId:e};return n!==void 0&&(i.intervalMs=n),r!==void 0&&(i.timeoutMs=r),i}var wu=class{client;credentialStore;isOpenCloudUploadEnabled;maxFileSizeBytes;constructor(e){this.client=e.client,this.credentialStore=e.credentialStore,this.isOpenCloudUploadEnabled=e.isOpenCloudUploadEnabled,this.maxFileSizeBytes=e.maxFileSizeBytes??bm}getCapabilities(){return cS.map(({contentTypes:e,...n})=>n)}async uploadAsset(e){a9(this.isOpenCloudUploadEnabled());let n=await this.getRequiredCredential(),r=o9(e,n),i=sS(r.category),a=await s9(i,r.filePath,this.maxFileSizeBytes);try{let o={apiKey:n.apiKey,assetType:i.assetType,displayName:r.displayName,description:r.description??"",creatorType:r.creatorType,creatorId:r.creatorId,filePath:r.filePath,contentType:a};r.expectedPrice!==void 0&&(o.expectedPrice=r.expectedPrice);let s=await this.client.createAsset(o);if(r.waitForOperation){let c=c9(s);return c?await this.client.pollOperation(l9(n,c,r.operationPollIntervalMs,r.operationPollTimeoutMs)):s}return s}catch(o){throw new Error(oS(o instanceof Error?o.message:String(o),n))}}async updateAsset(e){a9(this.isOpenCloudUploadEnabled());let n=await this.getRequiredCredential(),r=o9(e,n),i=sS(r.category),a;if(r.filePath){if(!i.supportsContentUpdate)throw new Error(`${i.category} assets do not support content updates.`);a=await s9(i,r.filePath,this.maxFileSizeBytes)}try{let o={apiKey:n.apiKey,assetId:r.assetId,assetType:i.assetType,creatorType:r.creatorType,creatorId:r.creatorId};r.filePath&&(o.filePath=r.filePath),a!==void 0&&(o.contentType=a),r.displayName!==void 0&&(o.displayName=r.displayName),r.description!==void 0&&(o.description=r.description),r.updateMask!==void 0&&(o.updateMask=r.updateMask),r.expectedPrice!==void 0&&(o.expectedPrice=r.expectedPrice);let s=await this.client.updateAsset(o);if(r.waitForOperation){let c=c9(s);return c?await this.client.pollOperation(l9(n,c,r.operationPollIntervalMs,r.operationPollTimeoutMs)):s}return s}catch(o){throw new Error(oS(o instanceof Error?o.message:String(o),n))}}async getAsset(e){let n=await this.getRequiredCredential();try{let r={apiKey:n.apiKey,assetId:e.assetId};return e.readMask!==void 0&&(r.readMask=e.readMask),await this.client.getAsset(r)}catch(r){throw new Error(oS(r instanceof Error?r.message:String(r),n))}}async getOperation(e){let n=await this.getRequiredCredential();try{return await this.client.getOperation({apiKey:n.apiKey,operationId:e.operationId})}catch(r){throw new Error(oS(r instanceof Error?r.message:String(r),n))}}async getRequiredCredential(){let e=await this.credentialStore.getCredentialForUse();if(!e)throw new Error("Configure a Roblox Open Cloud API key in WEPPY Dashboard before using Open Cloud asset upload.");return e}};import u9 from"node:fs";import cn from"node:path";Zx();var Lve=/^asset_(image|decal|audio|mesh|model|video|animation)_\d+_[a-z0-9]+$/;function zve(t){if(!Number.isInteger(t)||t<0)throw new Error(`Invalid place ID: ${t}`)}function Uve(t,e){try{return u9.statSync(cn.join(t,e,".sync-meta.json")).isFile()}catch{return!1}}function Fve(t,e){zve(e.placeId);let n=`place_${e.placeId}`,r=e.placeName?Xl(e.placeName):"",i=r?`${n}_${r}`:n,a=[];try{let o=new RegExp(`^place_${e.placeId}(?:_.*)?$`);a=u9.readdirSync(t,{withFileTypes:!0}).filter(s=>s.isDirectory()&&o.test(s.name)).map(s=>s.name).sort()}catch{return i}return r&&a.includes(i)?i:a.find(o=>Uve(t,o))??(a.includes(i)?i:null)??a[0]??i}function MA(t){let e=cn.resolve(t.projectSyncRoot),n=lS(t.category).folder,r=t.scope.kind==="place"?cn.join(e,Fve(e,t.scope),"assets",n):cn.join(e,"shared-assets",n);return{root:r,inbox:cn.join(r,"inbox"),index:cn.join(r,".asset-library-index.json")}}function qve(t){let e=Lve.exec(t);return e?.[1]?e[1]:null}function xm(t,e){let n=qve(t);return n?e?n===e:!0:!1}function uS(t,e){if(!xm(t,e))throw new Error(`Invalid asset ID: ${t}`)}function wi(t,e){let n=cn.relative(cn.resolve(t),cn.resolve(e));return n===""||!n.startsWith("..")&&!cn.isAbsolute(n)}function Bve(t){uS(t.assetId,t.category);let e=MA(t),n=cn.resolve(e.root,t.assetId);if(!wi(e.root,n))throw new Error(`Invalid asset path for ${t.assetId}`);return n}function dS(t){let e=Bve(t),n=cn.resolve(e,t.relativeFileName);if(!wi(e,n))throw new Error(`Invalid asset file path for ${t.assetId}`);return n}function _m(t,e){return cn.relative(cn.resolve(t),cn.resolve(e)).split(cn.sep).join("/")}var m9=20*1024*1024,Zve=200;function g9(t,e){return t.kind!==e.kind?!1:t.kind==="shared"&&e.kind==="shared"?!0:t.kind==="place"&&e.kind==="place"&&t.placeId===e.placeId}function h9(t,e){let n=Yt.extname(t).toLowerCase(),r=lS(e);if(!r.extensions.includes(n))return null;let i=r.contentTypes[n];return i?{canonicalExt:n,mimeType:i}:null}function zA(t,e,n){if(e!=="image"&&e!=="decal")return!0;let r=Yt.extname(t).toLowerCase();return r===".png"?n.length>=8&&n[0]===137&&n[1]===80&&n[2]===78&&n[3]===71&&n[4]===13&&n[5]===10&&n[6]===26&&n[7]===10:r===".jpg"||r===".jpeg"?n.length>=3&&n[0]===255&&n[1]===216&&n[2]===255:r===".bmp"?n.length>=2&&n[0]===66&&n[1]===77:r===".tga"?n.length>0:!1}function y9(t){return Vve("sha256").update(t).digest("hex")}function fS(t){return t.now?.()??Date.now()}function Gve(t){return(t.randomId?.()??LA().replace(/-/g,"").slice(0,6)).toLowerCase().replace(/[^a-z0-9]/g,"").slice(0,12)||"asset"}function v9(t,e){let n=Math.floor(fS(t)/1e3);for(let r=0;r<20;r++){let i=Gve(t),a=r===0?`asset_${t.category}_${n}_${i}`:`asset_${t.category}_${n}_${i}${r}`;if(!e.has(a))return a}return`asset_${t.category}_${n}_${LA().replace(/-/g,"").slice(0,10)}`}function b9(t){let e=Yt.parse(t).name.trim();return e.length>0?e:t}function x9(t){if(t.mimeType!=="image/png")throw new Error("Asset Library preview must be an image/png thumbnail");if(Yt.basename(t.fileName).toLowerCase()!=="thumbnail.png")throw new Error("Asset Library preview file must be thumbnail.png");if(!zA("thumbnail.png","image",t.content))throw new Error("Asset Library preview is not a valid PNG file");return{fileName:"thumbnail.png",content:t.content}}async function UA(t,e){let n=`${t}.tmp.${LA().slice(0,8)}`;await pS(n,JSON.stringify(e,null,2),"utf8"),await f9(n,t)}async function _9(t,e){try{let n=await d9(Yt.join(e,"asset.json"),"utf8"),r=JSON.parse(n);return!xm(r.id,t.category)||r.category!==t.category||!g9(r.scope,t.scope)?null:r}catch{return null}}async function Sm(t,e){let n;try{n=await p9(e.root,{withFileTypes:!0})}catch(i){if(i?.code==="ENOENT")return[];throw i}let r=[];for(let i of n.sort((a,o)=>a.name.localeCompare(o.name))){if(!i.isDirectory()||!xm(i.name,t.category))continue;let a=Yt.join(e.root,i.name),o=await _9(t,a);o&&r.push(o)}return r.sort((i,a)=>a.createdAt.localeCompare(i.createdAt)||a.id.localeCompare(i.id))}async function Iu(t,e,n){if(uS(n.id,t.category),n.category!==t.category||!g9(n.scope,t.scope))throw new Error(`Asset metadata does not match library scope/category: ${n.id}`);let r=Yt.join(e.root,n.id);if(!wi(e.root,r))throw new Error(`Invalid asset path for ${n.id}`);await wm(r,{recursive:!0}),await UA(Yt.join(r,"asset.json"),n)}async function S9(t,e){await wm(t.root,{recursive:!0});let n={version:1,generatedAt:new Date().toISOString(),assets:e.map(r=>r.id)};await UA(t.index,n)}function aa(t,e,n){return{fileName:t,reason:e,message:n}}async function Ii(t){let e=MA(t);return await wm(e.inbox,{recursive:!0}),e}async function w9(t){let e=await Ii(t),n=await Sm(t,e);return await S9(e,n),n}async function Xt(t,e){uS(e,t.category);let n=await Ii(t),r=Yt.join(n.root,e);if(!wi(n.root,r))throw new Error(`Invalid asset path for ${e}`);let i=await _9(t,r);if(!i)throw new Error(`Asset not found: ${e}`);return i}async function Cu(t){let e=await Ii(t),n=await Sm(t,e),r={version:1,generatedAt:new Date().toISOString(),assets:n.map(i=>i.id)};return await UA(e.index,r),r}async function I9(t){let e=await Ii(t),n=await Sm(t,e),r=new Set(n.map(p=>p.id)),i=new Set(n.map(p=>p.file.sha256)),a=[],o=[],s=t.maxFileSizeBytes??m9,c=t.maxFilesPerRescan??Zve,l;try{l=await p9(e.inbox,{withFileTypes:!0})}catch(p){if(p?.code==="ENOENT")l=[];else throw p}let u=l.sort((p,f)=>p.name.localeCompare(f.name));for(let p=0;p<u.length;p++){let f=u[p];if(p>=c){o.push(aa(f.name,"maxFileCount","rescan file count limit exceeded"));continue}if(f.name.startsWith(".")){o.push(aa(f.name,"hidden","hidden or system file"));continue}if(f.isSymbolicLink()){o.push(aa(f.name,"symlink","symlink files are not followed"));continue}if(f.isDirectory()){o.push(aa(f.name,"nestedDirectory","nested directories are not scanned"));continue}if(!f.isFile()){o.push(aa(f.name,"unsupportedType","unsupported inbox entry type"));continue}let m=h9(f.name,t.category);if(!m){o.push(aa(f.name,"unsupportedType",`unsupported ${t.category} extension`));continue}let g=Yt.join(e.inbox,f.name),h=await Wve(g);if(h.size>s){o.push(aa(f.name,"oversized","asset file is larger than the configured limit"));continue}let v=await d9(g);if(!zA(f.name,t.category,v)){o.push(aa(f.name,"invalidSignature","file signature does not match the extension"));continue}let _=y9(v);if(i.has(_)){o.push(aa(f.name,"duplicate","asset content already exists in Asset Library"));continue}let x=v9(t,r);r.add(x),i.add(_);let w=Yt.join(e.root,x),I=`original${m.canonicalExt}`;await wm(w,{recursive:!0}),await f9(g,Yt.join(w,I));let N=new Date(fS(t)).toISOString(),E={version:1,id:x,category:t.category,scope:t.scope,status:"localOnly",displayName:b9(f.name),description:"",source:{kind:"generated",originalPath:_m(t.projectSyncRoot,g)},file:{original:I,preview:null,mimeType:m.mimeType,sha256:_,sizeBytes:h.size,width:null,height:null,durationMs:null},roblox:{uploaded:!1},usage:{lastScannedAt:null,scanSource:null,references:[]},createdAt:N,updatedAt:N};await Iu(t,e,E),a.push(E)}let d=await Sm(t,e);return await S9(e,d),{assets:d,adopted:a,skipped:o,adoptedCount:a.length,skippedCount:o.length}}async function C9(t){let e=await Ii(t),n=h9(t.originalFileName,t.category);if(!n)throw new Error(`Unsupported ${t.category} extension for Asset Library export`);let r=t.maxFileSizeBytes??m9;if(t.content.length>r)throw new Error("asset file is larger than the configured limit");if(!zA(t.originalFileName,t.category,t.content))throw new Error("file signature does not match the extension");let i=await Sm(t,e),a=y9(t.content),o=i.find(h=>h.file.sha256===a);if(o)return{asset:o,deduplicated:!0};let s=new Set(i.map(h=>h.id)),c=v9(t,s),l=Yt.join(e.root,c);if(!wi(e.root,l))throw new Error(`Invalid asset path for ${c}`);let u=`original${n.canonicalExt}`;await wm(l,{recursive:!0}),await pS(Yt.join(l,u),t.content);let d=null;if(t.preview){let h=x9(t.preview);d=h.fileName,await pS(Yt.join(l,h.fileName),h.content)}let p=new Date(fS(t)).toISOString(),f=t.roblox??{uploaded:!1},m=f.uploaded&&f.assetId?"uploaded":"localOnly",g={version:1,id:c,category:t.category,scope:t.scope,status:m,displayName:t.displayName?.trim()||b9(t.originalFileName),description:t.description??"",source:{...t.source,originalPath:_m(t.projectSyncRoot,Yt.join(l,u))},file:{original:u,preview:d,mimeType:n.mimeType,sha256:a,sizeBytes:t.content.length,width:null,height:null,durationMs:null},roblox:f,usage:{lastScannedAt:null,scanSource:null,references:[]},...t.rbxm?{rbxm:t.rbxm}:{},createdAt:p,updatedAt:p};return await Iu(t,e,g),await Cu(t),{asset:g,deduplicated:!1}}async function P9(t){let e=await Ii(t),n=await Xt(t,t.assetId),r=x9(t.preview),i=dS({...t,relativeFileName:r.fileName});await pS(i,r.content);let a={...n,file:{...n.file,preview:r.fileName},...n.rbxm&&t.rbxmThumbnail?{rbxm:{...n.rbxm,thumbnail:t.rbxmThumbnail}}:{},updatedAt:new Date(fS(t)).toISOString()};return await Iu(t,e,a),await Cu(t),{asset:a}}async function k9(t,e,n){let r=await Ii(t),i=await Xt(t,e),a={...i,displayName:typeof n.displayName=="string"?n.displayName:i.displayName,description:typeof n.description=="string"?n.description:i.description,source:{...i.source,...n.source?.agent!==void 0?{agent:n.source.agent}:{},...n.source?.contextId!==void 0?{contextId:n.source.contextId}:{},...n.source?.prompt!==void 0?{prompt:n.source.prompt}:{}},updatedAt:new Date().toISOString()};return await Iu(t,r,a),await Cu(t),a}async function E9(t,e,n){let r=await Ii(t),a={...await Xt(t,e),usage:n,updatedAt:new Date().toISOString()};return await Iu(t,r,a),await Cu(t),a}async function R9(t,e){let n=await Ii(t);await Xt(t,e);let r=Yt.join(n.root,e);if(!wi(n.root,r))throw new Error(`Invalid asset path for ${e}`);return await Hve(r,{recursive:!0}),await Cu(t),{assetId:e,removed:1}}async function wo(t){let e=await Ii(t);return await Iu(t,e,t.asset),await Cu(t),t.asset}async function Pu(t){let e=await Xt(t,t.assetId);return dS({...t,relativeFileName:e.file.original})}async function T9(t){let e=await Xt(t,t.assetId);return dS({...t,relativeFileName:e.file.preview??e.file.original})}var Yve="https://create.roblox.com/dashboard/creations/store",Xve="manage_assets_import_rbxm",qA="manage_assets_generate_thumbnail",Qve="manage_assets_review_model";var BA=new Set([Xve,qA]),VA=new Set(["manage_assets_export_selection_rbxm","manage_assets_export_path_rbxm",Qve]),ebe=new Set(["model","animation"]);function ot(t){return t&&typeof t=="object"?t:null}function tbe(t){if(typeof t!="string"||!ebe.has(t))throw new Error(`Unsupported Asset Library .rbxm round-trip category: ${String(t??"(missing)")}`);return t}function nbe(t){if(typeof t=="number"&&Number.isInteger(t)&&t>=0)return t;if(typeof t=="string"&&t.trim().length>0){let e=Number.parseInt(t,10);if(Number.isInteger(e)&&e>=0)return e}return null}function A9(t,e){for(let n of t.pluginClients.values())if(!(typeof n.placeId!="number"||!Number.isFinite(n.placeId))&&!(e!==void 0&&n.placeId!==e))return{placeId:n.placeId,...n.placeName?{placeName:n.placeName}:{}};return null}function HA(t,e){let n=Ct(t.config.dataDir),r=tbe(e.category),i=typeof e.scope=="string"?e.scope:"place",a=typeof e.assetLibraryAssetId=="string"&&e.assetLibraryAssetId.length>0?e.assetLibraryAssetId:void 0;if(i==="shared")return{projectSyncRoot:n,scope:{kind:"shared"},category:r,...a?{assetId:a}:{}};if(i!=="place")throw new Error(`Invalid Asset Library scope: ${i}`);let o=nbe(e.placeId),s=t.syncController?.getDefaultRuntimePlaceId()??null,c=o??s??A9(t)?.placeId??null;if(c===null)throw new Error("No placeId is available for Asset Library .rbxm round-trip.");let l=A9(t,c);return{projectSyncRoot:n,scope:{kind:"place",placeId:c,...l?.placeName?{placeName:l.placeName}:{}},category:r,...a?{assetId:a}:{}}}function rbe(t){if(Jve.extname(t.file.original).toLowerCase()!==".rbxm")throw new Error(`Asset Library Studio round-trip supports original.rbxm only. Unsupported original file: ${t.file.original}`)}function ibe(t,e){if(typeof t!="string"||t.trim().length===0)throw new Error(`${e} is missing`);return Buffer.from(t,"base64")}function abe(t,e){let n=ot(e),i={kind:n?.kind==="generation"||typeof t.prompt=="string"?"generated":"studioExport",originalPath:"studio:selection"};if(n){let a=typeof n.path=="string"?n.path:typeof n.kind=="string"?n.kind:void 0;a&&(i.originalPath=`studio:${a}`);let o=he(n.prompt,1e3);o&&(i.prompt=o)}if(!i.prompt){let a=he(t.prompt,1e3);a&&(i.prompt=a)}return typeof t.contextId=="string"&&(i.contextId=t.contextId),i}function N9(t){let e=ot(t);if(!e)return;let n={};typeof e.width=="number"&&(n.width=e.width),typeof e.height=="number"&&(n.height=e.height),typeof e.source=="string"&&(n.source=e.source),typeof e.error=="string"&&(n.error=e.error);let r=Im(e.attempts);return r.length>0&&(n.attempts=r),Object.keys(n).length>0?n:void 0}function he(t,e){return typeof t!="string"?null:t.slice(0,e)}function obe(t){if(typeof t!="string")return null;let e=t.trim();return/^\d+$/.test(e)?e:null}function O9(t){return`rbxassetid://${t}`}function $9(t){return`${Yve}/${t}/configure`}function D9(t){return`assets/${t}`}function br(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function j9(t){return Array.isArray(t)?t.slice(0,100).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.name,256),i=he(n.className,128),a=he(n.path,512);return r===null||i===null||a===null?[]:[{name:r,className:i,path:a}]}):[]}function sbe(t){let e=ot(t);if(!e)return{};let n={};for(let[r,i]of Object.entries(e).slice(0,100))typeof i!="number"||!Number.isFinite(i)||i<0||(n[r.slice(0,128)]=Math.floor(i));return n}function cbe(t){return Array.isArray(t)?t.slice(0,200).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.path,512),i=he(n.property,128),a=he(n.value,1024);if(r===null||i===null||a===null)return[];let o=he(n.assetId,64);return[{path:r,property:i,value:a,...o?{assetId:o}:{}}]}):[]}function Im(t){return Array.isArray(t)?t.slice(0,8).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.method,80),i=n.status==="success"||n.status==="failed"||n.status==="skipped"?n.status:null;if(r===null||i===null)return[];let a=he(n.message,512);return[{method:r,status:i,...a?{message:a}:{}}]}):[]}function lbe(t,e){let n=t.thumbnailMode==="auto"?"auto":"none";if(n==="none")return{mode:n,status:"skipped",message:"Thumbnail generation disabled"};let r=N9(e),i=ot(e),a=typeof i?.pngBase64=="string"&&i.pngBase64.length>0,o=typeof i?.base64Rgba=="string"&&i.base64Rgba.length>0&&i.format==="rgba8"&&typeof i.width=="number"&&typeof i.height=="number";if(r&&(a||o)){let s=br(r.width),c=br(r.height),l=Im(i?.attempts);return{mode:n,status:"generated",...s!==void 0?{width:s}:{},...c!==void 0?{height:c}:{},...typeof r.source=="string"?{source:r.source.slice(0,128)}:{},...l.length>0?{attempts:l}:{}}}if(r&&typeof r.error=="string"){let s=Im(ot(e)?.attempts);return{mode:n,status:"failed",message:r.error.slice(0,512),...s.length>0?{attempts:s}:{}}}return{mode:n,status:"skipped",message:"Thumbnail was not returned"}}function ube(t,e){let n=ot(t);if(!n)return e;let r=n.mode==="auto"||n.mode==="none"?n.mode:e.mode,i=n.status==="generated"||n.status==="skipped"||n.status==="failed"?n.status:e.status,a=he(n.message,512),o=br(n.width),s=br(n.height),c=he(n.source,128),l=Im(n.attempts);return{mode:r,status:i,...a?{message:a}:{},...o!==void 0?{width:o}:{},...s!==void 0?{height:s}:{},...c?{source:c}:{},...l.length>0?{attempts:l}:{}}}function FA(t,e=0){if(e>3)return;if(typeof t=="string")return t.slice(0,512);if(typeof t=="boolean")return t;if(typeof t=="number")return Number.isFinite(t)?t:void 0;if(Array.isArray(t))return t.slice(0,50).flatMap(i=>{let a=FA(i,e+1);return a===void 0?[]:[a]});let n=ot(t);if(!n)return;let r={};for(let[i,a]of Object.entries(n).slice(0,50)){let o=FA(a,e+1);o!==void 0&&(r[i.slice(0,128)]=o)}return r}function dbe(t){let e=ot(t),n=br(e?.x),r=br(e?.y),i=br(e?.z);if(!(n===void 0||r===void 0||i===void 0))return{x:n,y:r,z:i}}function pbe(t){return Array.isArray(t)?t.slice(0,100).flatMap(e=>{let n=ot(e);if(!n)return[];let r=n.severity==="info"||n.severity==="warning"||n.severity==="error"?n.severity:null,i=he(n.category,80),a=he(n.code,120),o=he(n.path,512),s=he(n.message,512);if(!r||i===null||a===null||o===null||s===null)return[];let c=he(n.suggestion,512);return[{severity:r,category:i,code:a,path:o,message:s,...c?{suggestion:c}:{}}]}):[]}function fbe(t){let e=ot(t);if(!e)return;let n=e.readiness==="ready"||e.readiness==="review"||e.readiness==="blocked"?e.readiness:null;if(!n)return;let r=FA(e.summary),i=he(e.reviewedAt,64),a=j9(e.roots);return{readiness:n,...i?{reviewedAt:i}:{},...a.length>0?{roots:a}:{},summary:ot(r)??{},findings:pbe(e.findings)}}function mbe(t){let e=ot(t);if(!e)return;let n={};for(let[r,i]of Object.entries(e).slice(0,16))typeof i=="string"&&(n[r.slice(0,128)]=i.slice(0,256)),typeof i=="number"&&Number.isFinite(i)&&(n[r.slice(0,128)]=i),typeof i=="boolean"&&(n[r.slice(0,128)]=i);return Object.keys(n).length>0?n:void 0}function gbe(t){let e=ot(t);if(!e)return;let n=he(e.provider,120);if(!n)return;let r=he(e.generatedAt,64),i=he(e.prompt,1e3),a=e.schemaMode==="predefined"||e.schemaMode==="custom"?e.schemaMode:void 0,o=e.predefinedSchema==="Body1"||e.predefinedSchema==="Car5"?e.predefinedSchema:void 0,s=Array.isArray(e.schemaGroups)?e.schemaGroups.slice(0,50).flatMap(f=>{let m=he(f,120);return m?[m]:[]}):void 0,c=dbe(e.requestedSize),l=br(e.maxTriangles),u=he(e.targetParent,512),d=he(e.path,512),p=mbe(e.metadata);return{provider:n,...r?{generatedAt:r}:{},...i?{prompt:i}:{},...a?{schemaMode:a}:{},...o?{predefinedSchema:o}:{},...s&&s.length>0?{schemaGroups:s}:{},...c?{requestedSize:c}:{},...l!==void 0?{maxTriangles:Math.floor(l)}:{},...typeof e.generateTextures=="boolean"?{generateTextures:e.generateTextures}:{},...u?{targetParent:u}:{},...d?{path:d}:{},...p?{metadata:p}:{}}}function hbe(t){return Array.isArray(t)?t.slice(0,100).flatMap(e=>{let n=ot(e);if(!n)return[];let r=he(n.path,512),i=n.assetType==="Mesh"||n.assetType==="Image"||n.assetType==="Model"?n.assetType:null,a=n.status==="uploaded"||n.status==="failed"?n.status:null;if(r===null||i===null||a===null)return[];let o=he(n.assetId,64),s=he(n.assetUri,128),c=n.creatorType==="user"||n.creatorType==="group"?n.creatorType:void 0,l=he(n.creatorId,64),u=he(n.sourceProperty,128),d=he(n.uploadedAt,64),p=he(n.message,512);return[{path:r,assetType:i,status:a,...o?{assetId:o}:{},...s?{assetUri:s}:{},...c?{creatorType:c}:{},...l?{creatorId:l}:{},...u?{sourceProperty:u}:{},...d?{uploadedAt:d}:{},...p?{message:p}:{}}]}):[]}function ybe(t){let e=ot(t);if(!e||e.uploaded!==!0)return;let n=obe(e.assetId);if(!n)return;let r=he(e.uploadedAt,64)??new Date().toISOString(),i=e.creatorType==="user"||e.creatorType==="group"?e.creatorType:void 0,a=he(e.creatorId,64);return{uploaded:!0,assetId:n,assetUri:O9(n),assetWebUrl:$9(n),remotePath:D9(n),uploadedAt:r,uploadAttempts:[{startedAt:r,finishedAt:r,status:"uploaded",assetRole:"primary",...i?{creatorType:i}:{},...a?{creatorId:a}:{},assetId:n,assetUri:O9(n),assetWebUrl:$9(n),remotePath:D9(n)}]}}function vbe(t){let e=ot(t.value),n=j9(e?.roots),r=sbe(e?.classCounts),i=cbe(e?.resourceReferences),a=fbe(e?.review),o=gbe(e?.generation),s=hbe(e?.studioUploads),c=br(e?.exportedCount)??br(t.exportedCount)??n.length;return{exportedCount:Math.max(0,Math.floor(c)),roots:n,classCounts:r,resourceReferences:i,thumbnail:ube(e?.thumbnail,t.fallbackThumbnail),...a?{review:a}:{},...o?{generation:o}:{},...s.length>0?{studioUploads:s}:{}}}function bbe(t){return t.length>=8&&t[0]===137&&t[1]===80&&t[2]===78&&t[3]===71&&t[4]===13&&t[5]===10&&t[6]===26&&t[7]===10}function M9(t){let e=ot(t);if(!e)return;let n=null;if(typeof e.pngBase64=="string"&&e.pngBase64.length>0?n=Buffer.from(e.pngBase64,"base64"):typeof e.base64Rgba=="string"&&e.base64Rgba.length>0&&e.format==="rgba8"&&typeof e.width=="number"&&typeof e.height=="number"&&(n=Buffer.from(i9(e.base64Rgba,e.width,e.height),"base64")),!!n){if(!bbe(n))throw new Error("Thumbnail payload is not a valid PNG image.");return{fileName:"thumbnail.png",content:n,mimeType:"image/png"}}}function xbe(t,e){let n=e instanceof Error?e.message:String(e);return t.thumbnail.status!=="generated"?t:{...t,thumbnail:{...t.thumbnail,status:"failed",message:`Thumbnail payload could not be stored: ${n}`.slice(0,512)}}}async function L9(t){if(!BA.has(t.command))return t.params;let e=HA(t.ctx,t.params);if(!e.assetId)throw new Error("assetLibraryAssetId is required for Asset Library .rbxm round-trip.");let n=await Xt(e,e.assetId);rbe(n);let r=await Pu({...e,assetId:n.id}),i=await Kve(r);return{...t.params,__assetLibraryRbxmBase64:i.toString("base64"),__assetLibraryOriginalFile:n.file.original}}async function z9(t){if(!VA.has(t.command)||!t.result.success)return t.result;let e=ot(t.result.data);if(!e||typeof e.rbxmBase64!="string"||e.rbxmBase64.trim().length===0)return t.result;let n=HA(t.ctx,t.params),r=ibe(e.rbxmBase64,"Asset Library .rbxm export payload"),i=typeof t.params.displayName=="string"?t.params.displayName:void 0,a=typeof t.params.description=="string"?t.params.description:void 0,o=`${i?.trim()||"studio-export"}.rbxm`,s,c=null;try{s=M9(e.thumbnail)}catch(f){c=f,s=void 0}let l=vbe({value:e.rbxm,exportedCount:e.exportedCount,fallbackThumbnail:lbe(t.params,e.thumbnail)});c&&(l=xbe(l,c));let u=ybe(e.roblox),d=await C9({projectSyncRoot:n.projectSyncRoot,scope:n.scope,category:n.category,originalFileName:o,content:r,...i!==void 0?{displayName:i}:{},...a!==void 0?{description:a}:{},source:abe(t.params,e.source),...s?{preview:s}:{},rbxm:l,...u?{roblox:u}:{}}),p=N9(e.thumbnail);return{...t.result,data:{asset:d.asset,deduplicated:d.deduplicated,...typeof e.byteLength=="number"?{byteLength:e.byteLength}:{},...typeof e.exportedCount=="number"?{exportedCount:e.exportedCount}:{},...e.source!==void 0?{source:e.source}:{},...p?{thumbnail:p}:{}}}}async function U9(t){if(!t.result.success)return t.result;let e=ot(t.result.data),n=ot(e?.thumbnail),r;try{r=M9(n)}catch(d){return{...t.result,success:!1,error:d instanceof Error?d.message:String(d)}}if(!n||!r)return{...t.result,success:!1,error:typeof n?.error=="string"?n.error:"Thumbnail payload is missing from Asset Library thumbnail generation result."};let i=br(n.width),a=br(n.height),o=he(n.source,128),s=Im(n.attempts),c={mode:"auto",status:"generated",...i!==void 0?{width:i}:{},...a!==void 0?{height:a}:{},...o?{source:o}:{},...s.length>0?{attempts:s}:{}},l=HA(t.ctx,t.params);if(!l.assetId)throw new Error("assetLibraryAssetId is required for Asset Library thumbnail generation.");let u=await P9({projectSyncRoot:l.projectSyncRoot,scope:l.scope,category:l.category,assetId:l.assetId,preview:r,rbxmThumbnail:c});return{...t.result,data:{asset:u.asset,...i!==void 0?{width:i}:{},...a!==void 0?{height:a}:{},...o?{source:o}:{}}}}function _be(t){if(t===null||typeof t!="object")return;let e=t.proFallback;if(e===null||typeof e!="object")return;let n=e;if(typeof n.executedCommand!="string")return;let r=Array.isArray(n.alternatives)?n.alternatives.filter(i=>typeof i=="string"):void 0;return{executedCommand:n.executedCommand,...typeof n.requestedCommand=="string"?{requestedCommand:n.requestedCommand}:{},...r?{alternatives:r}:{}}}var Sbe=/^Pro action '[^']+' is blocked in Basic mode\. Basic fallback '([^']+)' failed: (.*)$/s,wbe=/^Pro action '[^']+' is blocked in Basic mode\.(?! Basic fallback ')/,Ibe=/instance not found|not found in|parent not found/,Cbe=/is required|missing required/,Pbe=/unknown action|unknown command/,kbe=/must be|invalid|cannot/;function Ebe(t){let e=Sbe.exec(t);return e?{fallbackCommand:e[1],reason:e[2]}:null}function Rbe(t){return wbe.test(t)}function Tbe(t){let e=t.toLowerCase();return Ibe.test(e)?"not_found":Cbe.test(e)?"missing_param":Pbe.test(e)?"unknown_action":kbe.test(e)?"validation":"other"}function WA(t){return t.errorType==="bridge_error"||t.errorType==="command_timeout"||t.errorType==="plugin_runtime"||t.errorType==="exception"||t.errorType==="device_blocked"||t.failureOrigin==="bridge"||t.failureOrigin==="plugin_runtime"||t.failureOrigin==="server_exception"||t.failureOrigin==="product_bug"||t.failureOrigin==="unknown"||t.recoverability==="retry"||t.recoverability==="wait_connection"||t.recoverability==="unknown"?"error":"warning"}function ku(t){if(t.resultSuccess){let e=_be(t.resultData);return e?{kind:"success_fallback",fallbackCommand:e.executedCommand,...e.alternatives?{alternatives:e.alternatives}:{}}:{kind:"success_ok"}}if(!t.resultError)return{kind:"error"};if(t.tier==="pro"){let e=Ebe(t.resultError);if(e)return{kind:"blocked_fallback_failed",fallbackCommand:e.fallbackCommand,blockedDetail:Tbe(e.reason)};if(Rbe(t.resultError))return{kind:"blocked_unsupported"}}return t.failureClassification?{kind:WA(t.failureClassification)}:{kind:"error"}}function Se(t,e,n,r,i={}){return{errorType:t,errorDetail:e,failureOrigin:n,recoverability:r,...i}}function Abe(t){let e=t.toLowerCase();return/^\s*compilation error:/.test(e)?Se("execution_failed","compile_error","agent_request","code_fix",{validationStage:"plugin_handler"}):/^\s*result too large:/.test(e)?Se("execution_failed","result_too_large","agent_request","code_fix",{validationStage:"plugin_handler"}):/^\s*execution timed out after/.test(e)?Se("execution_failed","execution_timeout","agent_request","code_fix",{validationStage:"plugin_handler"}):/potentially dangerous infinite loop|blocked in sandbox|access to .* is blocked|forbidden|not allowed|cannot access/.test(e)?Se("execution_failed","blocked_source","roblox_policy","code_fix",{validationStage:"plugin_handler"}):null}function Obe(t){let e=t.toLowerCase();return/startline and endline must be provided together/.test(e)||/startline must be a positive integer/.test(e)||/endline must be a positive integer/.test(e)||/endline must be >= startline/.test(e)?Se("execution_failed","validation","agent_request","fix_params",{validationStage:"schema"}):null}function F9(t){let e=t.toLowerCase();return/upstream_server_down/.test(e)?Se("bridge_error","upstream_down","bridge","wait_connection"):/^http [45]\d\d/.test(e)?Se("bridge_error","http_error","bridge","retry"):/duplicate request\s*id/.test(e)?Se("bridge_error","duplicate_request_id","bridge","code_fix"):/timeout/.test(e)?Se("command_timeout","timeout","bridge","retry"):/econnrefused|socket hang up|econnreset|epipe|network/.test(e)?Se("bridge_error","connection","bridge","wait_connection"):/abort/.test(e)?Se("command_timeout","aborted","bridge","retry"):/runtime error|traceback|attempt to/.test(e)?Se("plugin_runtime","runtime_error","plugin_runtime","code_fix"):/created instance, but failed to set \d+ propert/.test(e)?Se("execution_failed","property_apply_failed","agent_request","fix_params",{validationStage:"plugin_handler",partialSuccess:"true"}):/failed to set property/.test(e)?Se("execution_failed","property_apply_failed","agent_request","fix_params",{validationStage:"plugin_handler"}):/parent(?: instance)? not found/.test(e)?Se("execution_failed","parent_not_found","agent_request","fix_params",{validationStage:"plugin_handler"}):/(?:instance|path|root|source instance|ancestor instance) not found|target\s+(?:path\s+)?(?:['"`][^'"`]+['"`]\s+)?not found|not found in|no synced file found for instance/.test(e)?Se("execution_failed","not_found","user_project_state","fix_params",{validationStage:"plugin_handler"}):/is required|missing required/.test(e)?Se("execution_failed","missing_param","agent_request","fix_params",{validationStage:"schema"}):/invalid classname|invalid class/.test(e)?Se("execution_failed","invalid_class","agent_request","fix_params",{validationStage:"plugin_handler"}):/unknown action|unknown command/.test(e)?Se("execution_failed","unknown_action","agent_request","fix_params",{validationStage:"dispatcher"}):/failed to insert asset/.test(e)?Se("execution_failed","asset_error","roblox_policy","fix_params",{validationStage:"roblox_api"}):/failed to read property|property access denied/.test(e)?Se("execution_failed","property_error","agent_request","fix_params",{validationStage:"plugin_handler"}):/forbidden (?:path|parent path)|exceeds (?:total lines|max(?:imum)?(?: length)?)|is not (?:a|an) /.test(e)?Se("execution_failed","validation","agent_request","fix_params",{validationStage:"plugin_handler"}):/sync controller not available|project sync is not initialized|no active sync place|not found in sync cache/.test(e)?Se("execution_failed","sync_not_ready","user_project_state","wait_connection",{validationStage:"preflight"}):/cannot capture edit-mode screenshot while a playtest is active|play-mode screenshot capture is not supported/.test(e)?Se("execution_failed","unsupported_context","roblox_policy","no_retry",{validationStage:"preflight"}):/editableimage api is not enabled|allow mesh \/ image apis|allow http requests/.test(e)?Se("execution_failed","feature_disabled","roblox_policy","no_retry",{validationStage:"preflight"}):/must be|invalid|cannot/.test(e)?Se("execution_failed","validation","agent_request","fix_params",{validationStage:"plugin_handler"}):Se("execution_failed","other","unknown","unknown")}function Eu(t,e){if(t==="manage_scripts_get_source"){let r=Obe(e);if(r)return r}if(t==="execute_luau"){let r=Abe(e);if(r)return r}let n=F9(e);return t==="execute_luau"&&n.errorDetail==="runtime_error"&&/^\s*runtime error:/i.test(e)?Se("execution_failed","runtime_error","agent_request","code_fix"):n}function q9(t){let n=(t instanceof Error?t.message:String(t)).toLowerCase();return/timeout/.test(n)?Se("command_timeout","timeout","bridge","retry"):/econnrefused|socket hang up|network|econnreset|epipe/.test(n)?Se("bridge_error","connection","bridge","wait_connection"):/eaddrinuse/.test(n)?Se("bridge_error","port_in_use","bridge","no_retry"):Se("exception","unexpected","server_exception","code_fix")}hS();import{randomBytes as zbe}from"node:crypto";var Ube=["manage_ui_create_tree","manage_ui_update","manage_ui_delete"],K9=["manage_ui_preview","manage_ui_check"],Fbe=["game_genre","ui_role","style_family","layout_family","device_policy","safe_area_policy","existing_ui_strategy"];function e1(t){return t&&typeof t=="object"?t:void 0}function XA(t){return typeof t=="number"&&Number.isFinite(t)?t:0}function yS(t){let e=e1(t);if(!e)return;let n={};for(let r of Fbe){let i=e[r];typeof i=="string"&&i.trim().length>0&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}function QA(t){let e=yS(t.qualityPlanSummary);if(e)return e;let n=e1(t.contextSummary),r=yS(n?.qualityPlanSummary);if(r)return r;let i=yS(n?.qualityPlan);if(i)return i;let a=yS(n?.quality_plan);if(a)return a}function J9(t,e){return e?{...t??{},...e}:t}function qbe(t){return typeof t=="string"?{snapshotId:t}:t&&typeof t=="object"?{snapshotId:typeof t.snapshotId=="string"?t.snapshotId:null,...t.designCheckSummary!==void 0&&{designCheckSummary:t.designCheckSummary},...t.capturedAt!==void 0&&{capturedAt:t.capturedAt}}:{snapshotId:null}}function Y9(t,e,n,r,i){if(!e)return;let a=XA(e.priority_high),o=XA(e.priority_medium),s=XA(e.priority_low),c=typeof e.total=="number"&&Number.isFinite(e.total)?e.total:a+o+s,l=n??(typeof e.target=="string"?e.target:void 0);return{source:t,...l!==void 0&&{targetPath:l},...typeof r=="string"&&{snapshotId:r},...i!==void 0&&{capturedAt:i},priority_high:a,priority_medium:o,priority_low:s,total:c}}function X9(t,e){if(!e)return t;if(!t)return e;let n=t.targetPath===e.targetPath?t.targetPath:void 0,r=t.snapshotId===e.snapshotId?t.snapshotId:void 0;return{source:e.source,...n!==void 0&&{targetPath:n},...r!==void 0&&{snapshotId:r},...e.capturedAt!==void 0&&{capturedAt:e.capturedAt},priority_high:t.priority_high+e.priority_high,priority_medium:t.priority_medium+e.priority_medium,priority_low:t.priority_low+e.priority_low,total:t.total+e.total}}function Bbe(t){let e=e1(t);if(e)for(let n of["userMessage","intent","expectedBehavior"]){let r=e[n];if(typeof r=="string"&&r.trim().length>0)return r.trim().slice(0,80)}}function Vbe(){return{source:"unavailable",priority_high:0,priority_medium:0,priority_low:0,total:0}}function Q9(t){let e=t.now??Date.now,n=null,r=null,i=u=>`${u}_${e()}_${zbe(3).toString("hex")}`,a=()=>{r&&(clearTimeout(r),r=null)},o=()=>{a(),r=setTimeout(()=>{c("idle_timeout")},t.idleMs)},s=async u=>{try{return qbe(await t.capturePreview(u))}catch{return{snapshotId:null}}},c=async u=>{if(!n)return;a();let d=n;n=null;let p={},f;for(let h of d.affectedPaths)if(d.afterSnapshotsPathPolicy[h]==="skip")p[h]=null;else{let v=await s(h);p[h]=v.snapshotId,f=X9(f,Y9("after_snapshot",v.designCheckSummary,h,v.snapshotId,v.capturedAt))}let m=f??d.latestDesignCheckSummary??Vbe(),g={requestId:d.requestId,...d.contextId!==void 0&&{contextId:d.contextId},...d.label!==void 0&&{label:d.label},startedAt:d.startedAtIso,closedAt:new Date(e()).toISOString(),closeReason:u,ok:d.ok,affectedPaths:Array.from(d.affectedPaths).sort(),mutationCount:d.mutationCount,beforeSnapshots:d.beforeSnapshots,afterSnapshots:p,childMutationIds:d.childMutationIds,...d.qualityPlanSummary!==void 0&&{qualityPlanSummary:d.qualityPlanSummary},postChangeDesignCheckSummary:m};await W9(t.placeDir,g)},l=u=>({requestId:i("req"),contextId:u.contextId,label:Bbe(u.contextSummary),startedAtIso:new Date(e()).toISOString(),startedAtMs:e(),affectedPaths:new Set,beforeSnapshots:{},afterSnapshotsPathPolicy:{},childMutationIds:[],mutationCount:0,ok:!0,qualityPlanSummary:QA(u),latestDesignCheckSummary:void 0,pendingMutation:void 0});return{async beforeMutation(u){if(K9.includes(u.command)){if(n){let p=i("mut");n.qualityPlanSummary=J9(n.qualityPlanSummary,QA(u)),n.pendingMutation={mutationId:p,startedMs:e(),args:u}}return}if(!Ube.includes(u.command))return;n&&n.contextId!==u.contextId?await c("context_change"):n&&a(),n||(n=l(u)),n.qualityPlanSummary=J9(n.qualityPlanSummary,QA(u)),u.targetPath&&!(u.targetPath in n.beforeSnapshots)&&(n.affectedPaths.add(u.targetPath),u.command==="manage_ui_create_tree"?n.beforeSnapshots[u.targetPath]=null:n.beforeSnapshots[u.targetPath]=(await s(u.targetPath)).snapshotId,u.command==="manage_ui_delete"?n.afterSnapshotsPathPolicy[u.targetPath]="skip":u.targetPath in n.afterSnapshotsPathPolicy||(n.afterSnapshotsPathPolicy[u.targetPath]="capture"));let d=i("mut");n.pendingMutation={mutationId:d,startedMs:e(),args:u}},async afterMutation(u){if(!n?.pendingMutation)return;let{mutationId:d,args:p}=n.pendingMutation,f={mutationId:d,requestId:n.requestId,ts:new Date(e()).toISOString(),command:p.command,origin:p.origin,...p.targetPath!==void 0&&{targetPath:p.targetPath},...p.briefId!==void 0&&{briefId:p.briefId},...u.diffSummary!==void 0&&{diffSummary:u.diffSummary},...u.changeDetails!==void 0&&{changeDetails:u.changeDetails},ok:u.ok,...u.error!==void 0&&{error:u.error},durationMs:u.durationMs};if(await Z9(t.placeDir,f),n.pendingMutation=void 0,K9.includes(p.command)){n.latestDesignCheckSummary=X9(n.latestDesignCheckSummary,Y9("check_results",u.designCheckSummary,p.targetPath,u.snapshotId,u.capturedAt));return}if(n.mutationCount++,n.childMutationIds.push(d),u.ok||(n.ok=!1),!n.contextId){await c("legacy_single");return}o()},async flushNow(){n&&await c("explicit")}}}var y3=100,Ixe=12e4,Cxe=15e3,v3=new Set(["manage_ui_create_tree","manage_ui_update","manage_ui_delete"]);function Pxe(t,e){return`License required for internal command ${t}. ${e??"Activate Pro license to use this feature."}`}var kxe={Text:{category:"text",label:"\uD14D\uC2A4\uD2B8"},PlaceholderText:{category:"text",label:"\uD50C\uB808\uC774\uC2A4\uD640\uB354"},TextColor3:{category:"color",label:"\uAE00\uC790\uC0C9"},BackgroundColor3:{category:"color",label:"\uBC30\uACBD\uC0C9"},BorderColor3:{category:"color",label:"\uD14C\uB450\uB9AC\uC0C9"},ImageColor3:{category:"color",label:"\uC774\uBBF8\uC9C0\uC0C9"},Size:{category:"size",label:"\uC0AC\uC774\uC988"},TextSize:{category:"size",label:"\uAE00\uC790 \uD06C\uAE30"},Position:{category:"layout",label:"\uC704\uCE58"},AnchorPoint:{category:"layout",label:"\uC575\uCEE4"},Rotation:{category:"layout",label:"\uD68C\uC804"},LayoutOrder:{category:"layout",label:"\uB808\uC774\uC544\uC6C3 \uC21C\uC11C"},Visible:{category:"state",label:"\uD45C\uC2DC \uC0C1\uD0DC"},Active:{category:"state",label:"\uD65C\uC131 \uC0C1\uD0DC"},Interactable:{category:"state",label:"\uC0C1\uD638\uC791\uC6A9 \uC0C1\uD0DC"},Selectable:{category:"state",label:"\uC120\uD0DD \uAC00\uB2A5"},Enabled:{category:"state",label:"\uD65C\uC131\uD654"},Image:{category:"asset",label:"\uC774\uBBF8\uC9C0"},Texture:{category:"asset",label:"\uD14D\uC2A4\uCC98"},SoundId:{category:"asset",label:"\uC0AC\uC6B4\uB4DC"}},Exe={text:"\uD14D\uC2A4\uD2B8",color:"\uCEEC\uB7EC",size:"\uC0AC\uC774\uC988",layout:"\uB808\uC774\uC544\uC6C3",state:"\uC0C1\uD0DC",asset:"\uC5D0\uC14B",property:"\uC18D\uC131"},Rxe=Object.entries(Zs).reduce((t,[e,n])=>{for(let r of n.validActions)t[`${e}_${r}`]=e;return t},{});function d3(t){return{toolName:Rxe[t]||t,commandName:t}}function p3(t,e){if(typeof t.contextId=="string"||!e||typeof e!="object")return t;let n=e.contextId;return typeof n=="string"?{...t,contextId:n}:t}function vS(t,e){if(t!=="manage_sync_status_current_place")return e;let{placeId:n,...r}=e;return r}function Txe(t,e){let n=e.routing;return{requestId:t,success:!1,error:e.message,errorCode:e.code,routing:n,data:{routing:n}}}async function Axe(t,e){let n=t.syncController;if(!n)return null;try{let r=e.placeId,i=n.getDefaultRuntimePlaceId(),a=null;if(typeof r=="number"&&Number.isFinite(r))a=r;else if(typeof r=="string"&&r.trim().length>0){let s=Number.parseInt(r,10);Number.isFinite(s)&&(a=s)}if(a===null&&(a=i),a===null||!Number.isFinite(a))return null;let o=a===i?n.getDefaultRuntimePlaceName():null;return typeof o=="string"&&o.length>0?await n.config.resolvePlaceRoot(a,o):n.config.getPlaceRoot(a)}catch{return null}}function Oxe(t){let e=t.tree;if(!e||typeof e!="object")return;let n=e,r=typeof n.name=="string"&&n.name.length>0?n.name:void 0;return r?`${typeof n.parent=="string"&&n.parent.length>0?n.parent:"StarterGui"}.${r}`:void 0}function $xe(t,e){let n=e.targetPath;if(typeof n=="string"&&n.length>0)return n;if(t==="manage_ui_create_tree")return Oxe(e)}function Dxe(t){let e=kxe[t];if(e)return e;let n=t.toLowerCase();return n.includes("color")?{category:"color",label:"\uC0C9\uC0C1"}:t==="Size"||n.endsWith("size")||n.includes("scale")?{category:"size",label:"\uC0AC\uC774\uC988"}:n.includes("position")||n.includes("anchor")||n.includes("rotation")||n.includes("layout")?{category:"layout",label:"\uB808\uC774\uC544\uC6C3"}:n.includes("visible")||n.includes("active")||n.includes("enabled")||n.includes("selectable")||n.includes("interactable")?{category:"state",label:"\uC0C1\uD0DC"}:n.includes("image")||n.includes("texture")||n.includes("sound")||n.includes("asset")?{category:"asset",label:"\uC5D0\uC14B"}:n.includes("text")||n.includes("placeholder")?{category:"text",label:"\uD14D\uC2A4\uD2B8"}:{category:"property",label:t}}function f3(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function Nxe(t){if(!t||typeof t!="object")return new Map;let e=t,n=e.changed_properties??e.changedProperties;if(!Array.isArray(n))return new Map;let r=new Map;for(let i of n){if(!i||typeof i!="object")continue;let a=i,o=a.property;if(typeof o!="string"||o.length===0)continue;let s=f3(a,"before"),c=f3(a,"after");r.set(o,{...s&&{before:a.before},...c&&{after:a.after},hasBefore:s,hasAfter:c})}return r}function b3(t,e){let r=t.changes?.properties;if(!r||typeof r!="object")return;let i=Nxe(e),a=Object.entries(r).map(([o,s])=>{let c=Dxe(o),l=i.get(o),u={property:o,category:c.category,label:c.label,after:l?.hasAfter?l.after:s};return l?.hasBefore&&(u.before=l.before),u});return a.length>0?a:void 0}function x3(t){if(!t||t.length===0)return;let e=new Map;for(let i of t)e.set(i.category,(e.get(i.category)??0)+1);let r=["text","color","size","layout","state","asset","property"].map(i=>{let a=e.get(i)??0;return a>0?`${Exe[i]} ${a}\uAC1C`:null}).filter(i=>i!==null);return r.length>0?`${r.join(", ")} \uBCC0\uACBD`:void 0}function m3(t,e){if(t==="manage_ui_update"){let n=e.changes,r=x3(b3(e));if(r)return r;let i=n?.properties?Object.keys(n.properties).length:0,a=Array.isArray(n?.addChildren)?n.addChildren.length:0,o=Array.isArray(n?.removeChildren)?n.removeChildren.length:0;return`${i} props, +${a}, -${o}`}if(t==="manage_ui_create_tree")return"tree \uC0DD\uC131";if(t==="manage_ui_delete")return"\uC81C\uAC70\uB428"}function Nm(t){return t&&typeof t=="object"?t:void 0}function bS(t,e){let n=t[e];return typeof n=="number"&&Number.isFinite(n)?n:0}function _3(t){let e=Nm(t),n=Nm(e?.design_check_summary);if(n)return{priority_high:bS(n,"priority_high"),priority_medium:bS(n,"priority_medium"),priority_low:bS(n,"priority_low"),total:bS(n,"total"),...typeof n.scope=="string"&&{scope:n.scope},...typeof n.target=="string"&&{target:n.target}}}function S3(t){let n=Nm(t)?.snapshot_id;return typeof n=="string"?n:null}function g3(t){if(typeof t=="string"&&t.trim().length>0)return t;if(typeof t=="number"&&Number.isFinite(t)){let e=t<1e10?t*1e3:t;return new Date(e).toISOString()}}function w3(t){let e=Nm(t),n=Nm(e?.meta);return g3(n?.captured_at)??g3(n?.evaluated_at)}function jxe(t,e){let n=t.uiStudioRecorders.get(e);if(n)return n;let r=Q9({placeDir:e,idleMs:Cxe,capturePreview:async i=>{try{let a=await xr(t,"manage_ui_preview",{targetPath:i},_S());if(!a.success||!a.data||typeof a.data!="object")return null;let o=_3(a.data),s=w3(a.data);return{snapshotId:S3(a.data),...o!==void 0&&{designCheckSummary:o},...s!==void 0&&{capturedAt:s}}}catch{return null}}});return t.uiStudioRecorders.set(e,r),r}async function Mxe(t,e,n){if(!v3.has(e))return null;let r=await Axe(t,n);if(!r)return null;let i=jxe(t,r),a=e,o=typeof n.contextId=="string"?n.contextId:void 0,s=n.contextSummary,c=s!==void 0&&typeof s=="object"?s:void 0,l=$xe(a,n),u=typeof n.briefId=="string"?n.briefId:void 0,d={command:a,...o!==void 0&&{contextId:o},...c!==void 0&&{contextSummary:c},...l!==void 0&&{targetPath:l},...u!==void 0&&{briefId:u},origin:n.__origin==="dashboard"?"dashboard":"ai"};try{return await i.beforeMutation(d),{recorder:i,command:a,params:n,startedAt:Date.now()}}catch(p){return y.debug("UI Studio recorder beforeMutation \uC2E4\uD328 (\uBB34\uC2DC)",{error:p}),null}}async function h3(t,e){if(t)try{let n=t.command==="manage_ui_update"?b3(t.params,e.data):void 0,r=t.command==="manage_ui_update"?x3(n)??m3(t.command,t.params):m3(t.command,t.params),i=_3(e.data),a=S3(e.data),o=w3(e.data);await t.recorder.afterMutation({ok:e.success,durationMs:Date.now()-t.startedAt,...r!==void 0&&{diffSummary:r},...n!==void 0&&{changeDetails:n},...e.error!==void 0&&{error:e.error},...i!==void 0&&{designCheckSummary:i},...a!==null&&{snapshotId:a},...o!==void 0&&{capturedAt:o}})}catch(n){y.debug("UI Studio recorder afterMutation \uC2E4\uD328 (\uBB34\uC2DC)",{error:n})}}async function xS(t,e,n,r,i,a){if(!t.historyManager)return;let o=!i.success&&i.error?Eu(n,i.error):void 0,s=ku({resultSuccess:i.success,resultData:i.data,resultError:i.error,tier:tr(n),...o?{failureClassification:o}:{}});if(i.success){let u=s.kind==="success_fallback"&&i.data&&typeof i.data=="object"?{...i.data,outcomeStatus:"fallback",requestedCommand:n,executedCommand:s.fallbackCommand,...s.alternatives?{alternatives:s.alternatives}:{}}:i.data,d=vS(n,r);i.routing?await t.historyManager.recordSuccess(e,d,u,a,n,void 0,i.routing):await t.historyManager.recordSuccess(e,d,u,a,n);return}if(s.kind==="blocked_unsupported"){await t.historyManager.recordBlockedOutcome(e,vS(n,r),i.error||"Pro action blocked in Basic mode","blocked_unsupported",{executionTimeMs:a,command:n,...i.routing?{routing:i.routing}:{}});return}if(s.kind==="blocked_fallback_failed"){await t.historyManager.recordBlockedOutcome(e,vS(n,r),i.error||"Pro action blocked in Basic mode","blocked_fallback_failed",{executionTimeMs:a,command:n,...s.fallbackCommand?{fallbackCommand:s.fallbackCommand}:{},...s.blockedDetail?{blockedDetail:s.blockedDetail}:{},...i.routing?{routing:i.routing}:{}});return}let c=s.kind==="warning"?t.historyManager.recordWarning.bind(t.historyManager):t.historyManager.recordFailure.bind(t.historyManager),l=vS(n,r);i.routing?await c(e,l,i.error||"Unknown error",a,i.errorCode??o?.errorType.toUpperCase(),n,void 0,i.routing):await c(e,l,i.error||"Unknown error",a,i.errorCode??o?.errorType.toUpperCase(),n)}function i1(t,e,n){let r=t.pendingCommands.get(e)||[];r.length>=y3&&r.shift(),r.push(n),t.pendingCommands.set(e,r)}function Lxe(t,e){t.globalPendingCommands.length>=y3&&t.globalPendingCommands.shift(),t.globalPendingCommands.push(e)}function I3(t,e,n){let r=_S(),i={requestId:r,command:e.command,params:e.params,timestamp:Date.now(),queueTimeoutMs:e.queueTimeoutMs,ackedTimeoutMs:e.ackedTimeoutMs,state:Dn.QUEUED,targetClientId:n,resolve:()=>{},reject:a=>{y.debug("Auxiliary playtest stop command ended without awaited response",{requestId:r,targetClientId:n,error:a.message})},timeoutId:null};return t.commandQueue.set(r,i),i.timeoutId=setTimeout(()=>{p_(t,i,i.queueTimeoutMs)},i.queueTimeoutMs),{event:"command",id:r,data:{command:i.command,requestId:r,params:i.params}}}function zxe(t,e,n,r){if(!ym(e.data.command))return;let i=t.commandQueue.get(e.data.requestId);if(!i)return;C3(t,i);let a=n.filter(o=>o.clientId!==r);for(let o of a){let s=I3(t,i,o.clientId);i1(t,o.clientId,s)}a.length>0&&y.info("Fan-out playtest stop command to active plugin clients",{requestId:e.data.requestId,primaryClientId:r,auxiliaryClientIds:a.map(o=>o.clientId)})}function C3(t,e,n){for(let r of e9)setTimeout(()=>{let a=n?[...new Set(n)]:[...new Set(Un(t).map(o=>o.clientId))];for(let o of a){if(!t.pluginClients.get(o))continue;let c=I3(t,e,o);i1(t,o,c)}y.info("Retry playtest stop command to active plugin clients",{sourceRequestId:e.requestId,delayMs:r,targetClientIds:a}),ou(t)},r).unref?.()}function P3(t){return t==="clientId"||t==="targetAlias"||t==="placeId"}function Uxe(t,e,n){if(!n||!ym(e.data.command))return!1;let r=t.commandQueue.get(e.data.requestId)?.routing?.selectionMode;return!P3(r)}function Fxe(t,e,n){y.debug("Broadcasting command",{command:e.data.command,requestId:e.data.requestId,targetClientId:n||"all",activeWebsocketClients:Un(t).length});let r=n;if(n){i1(t,n,e);let i=t.commandQueue.get(e.data.requestId),a=i?.routing?.selectionMode;if(i&&ym(e.data.command)&&P3(a))C3(t,i,[n]);else if(Uxe(t,e,n)){let o=Un(t).sort((s,c)=>c.lastSeen-s.lastSeen);zxe(t,e,o,n),r=void 0}}else Lxe(t,e);ou(t,r)}async function k3(t,e,n){let r=Date.now(),i="",a={};try{let o=e.body;i=o.command??"",a=o.params||{};let s=o.requestId;if(o.instanceId||(t.serverLastCommandAt=Date.now()),o.instanceId){let m=t.mcpInstances.get(o.instanceId);m&&(m.lastCommandAt=Date.now(),m.lastSeen=m.lastCommandAt)}let c=d3(i),l=typeof o.timeout=="number"&&Number.isFinite(o.timeout)&&o.timeout>0?{timeout:o.timeout}:void 0,u=o.instanceId?t.mcpInstances.get(o.instanceId)?.sessionId??t.sessionId:t.sessionId;if(!i){n.status(400).json({error:"Missing command"});return}if(y.debug("Received execute request",{command:i,requestId:s}),i==="manage_camera_play_screenshot"){let m="manage_camera.play_screenshot is not supported. Screenshot capture is available only in Edit mode via manage_camera.screenshot.",g=Date.now()-r;t.historyManager&&await t.historyManager.recordFailure("manage_camera",a,m,g,"UNSUPPORTED_COMMAND",i),n.json({requestId:s,success:!1,error:m});return}if(i==="get_cached_selection"){let m=a.maxAge,g=hm(t,m!==void 0?m:3e4),h=Date.now()-r;if(!g){let x={requestId:s,success:!0,data:{cached:!1,message:"No cached selection data available. The plugin may not be connected or no selection changes have occurred yet."}};t.historyManager&&await t.historyManager.recordSuccess(c.toolName,a,x.data,h,c.commandName),n.json(x);return}let v=Date.now()-g.timestamp,_={cached:!0,selection:g.selection,count:g.count,timestamp:g.timestamp,age:v};t.historyManager&&await t.historyManager.recordSuccess(c.toolName,a,_,h,c.commandName),n.json({requestId:s,success:!0,data:_});return}if(i==="get_connection_info"){let m=await nS(t),g=Date.now()-r;t.historyManager&&await t.historyManager.recordSuccess(c.toolName,a,m,g,c.commandName),n.json({requestId:s,success:!0,data:m});return}if(iS(i)==="internal"){if(!t.internalCommandExecutor){n.status(503).json({requestId:s,success:!1,error:`Internal command executor is not initialized for command: ${i}`});return}if(tr(i)==="pro"){if(!t.licenseState){n.status(503).json({requestId:s,success:!1,error:`License state manager is not initialized for internal command: ${i}`});return}let _=await t.licenseState.evaluateProAccess();if(!_.allowed){let x=Pxe(i,_.reason),w=Date.now()-r;t.historyManager&&await xS(t,c.toolName,c.commandName,a,{success:!1,error:x},w),n.json({requestId:s,success:!1,error:x});return}}let m={...a,__sessionId:u},g=await t.internalCommandExecutor(i,m),h=Date.now()-r,v=p3(m,g.data);t.historyManager&&await xS(t,c.toolName,c.commandName,v,{success:g.success,data:g.data,error:g.error||"Internal command failed"},h),n.json({requestId:s,...g});return}let d=await xr(t,i,a,s,l),p=Date.now()-r,f={...p3(a,d.data),__sessionId:u};t.historyManager&&await xS(t,c.toolName,c.commandName,f,d,p),n.json(d)}catch(o){let s=Date.now()-r,c=er(o);if(t.historyManager&&i){let l=d3(i);await t.historyManager.recordFailure(l.toolName,a,c,s,"EXCEPTION",l.commandName)}y.error("Execute request failed",o),n.status(500).json({success:!1,error:c})}}async function E3(t,e,n){let r=Date.now(),i=e.body,a=i.action;if(!a||typeof a!="string"){n.status(400).json({success:!1,error:"Missing required field: action"});return}if(!new Set(["get","set","get_all","set_multiple","get_attr","set_attr","get_all_attrs","delete_attr","add_tag","remove_tag","check_tag","get_tags","get_tagged"]).has(a)){n.status(400).json({success:!1,error:`Unsupported action: ${a}`});return}let s=`manage_properties_${a}`,c=_S(),{action:l,...u}=i;try{t.serverLastCommandAt=Date.now();let d=await xr(t,s,u,c),p=Date.now()-r;t.historyManager&&await xS(t,"manage_properties",s,u,d,p),n.json(d)}catch(d){let p=Date.now()-r,f=er(d);t.historyManager&&await t.historyManager.recordFailure("manage_properties",u,f,p,"EXCEPTION",s),y.error("/api/properties \uC694\uCCAD \uCC98\uB9AC \uC2E4\uD328",d),n.status(500).json({success:!1,error:f})}}async function xr(t,e,n,r,i){if(y.debug("Executing command locally",{command:e,requestId:r}),_8(t,r)){let d=`Duplicate requestId '${r}' for command '${e}'. Generate a unique requestId for each command.`;return y.warn("Duplicate execute request rejected",{command:e,requestId:r}),{requestId:r,success:!1,error:d}}let a;try{a=rS(t,Un(t),n,e)}catch(d){if(d instanceof xn)return y.warn("Command target selection failed",{command:e,requestId:r,errorCode:d.code,routing:d.routing}),Txe(r,d);throw d}let o=v3.has(e)?await Mxe(t,e,n):null,s=t.config.requestTimeout,c=i?.timeout??Math.max(t.config.requestTimeout,Ixe),l=BA.has(e)?await L9({ctx:t,command:e,params:n}):n,u=new Promise((d,p)=>{let f=Date.now(),m={requestId:r,command:e,params:l,timestamp:f,queueTimeoutMs:s,ackedTimeoutMs:c,state:Dn.QUEUED,...a.targetClientId?{targetClientId:a.targetClientId}:{},routing:a.routing,resolve:d,reject:p,timeoutId:null};t.commandQueue.set(r,m),s_(t,a.targetClientId,f),m.timeoutId=setTimeout(()=>{p_(t,m,s)},s)});return Fxe(t,{event:"command",id:_S(),data:{command:e,requestId:r,params:l}},a.targetClientId),u.then(async d=>{let p=d;if(e==="manage_ui_preview"&&d.success&&d.data)try{let{processPreviewResult:f,resolvePreviewPlaceDirFromCtx:m}=await Promise.resolve().then(()=>(r1(),n1)),g=await m(t,n),h=await f("manage_ui_preview",d.data,g);p={...d,data:h.data,...h.mcpContent?{mcpContent:h.mcpContent}:{}}}catch(f){y.warn("preview post-processing failed",{error:f instanceof Error?f.message:String(f)})}if(e==="manage_ui_check"&&d.success&&d.data&&n.includeVisualAnalysis===!0)try{let{resolvePreviewPlaceDirFromCtx:f}=await Promise.resolve().then(()=>(r1(),n1)),{processCheckResult:m}=await Promise.resolve().then(()=>(u3(),l3)),g=await f(t,n),h=await m("manage_ui_check",d.data,g,n);p={...p,data:h.data}}catch(f){y.warn("check visual post-processing failed",{error:f instanceof Error?f.message:String(f)})}return VA.has(e)?p=await z9({ctx:t,command:e,params:n,result:p}):e===qA&&(p=await U9({ctx:t,params:n,result:p})),p}).then(async d=>(await h3(o,{success:d.success,...d.data!==void 0&&{data:d.data},...d.error!==void 0&&{error:d.error}}),d),async d=>{throw await h3(o,{success:!1,error:er(d)}),d})}oe();Ki();function SS(t,e){let n={};e.provider!==void 0&&(n.provider=e.provider),e.tier!==void 0&&(n.tier=e.tier),e.status!==void 0&&(n.status=e.status),e.canUsePro!==void 0&&(n.canUsePro=e.canUsePro),e.cleared===!0&&(n.cleared=!0),dt(t,"license",n)}function Pi(t,e,n,r){t.status(e).json({success:!1,error:{code:n,message:r}})}function qxe(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();return e.length>0?e:void 0}function wS(t,e){if(e==="plugin")return t;let n={...t};return delete n.sessionToken,n}function jm(t,e,n,r){let i=qxe(r??e.query.provider)??"auto";return t.licenseState?.supportsProvider(i)===!1?(Pi(n,400,"LICENSE_PROVIDER_UNSUPPORTED",`provider "${i}" is not supported`),null):i}function Mm(t,e){return t.licenseState?!0:(Pi(e,503,"LICENSE_NOT_INITIALIZED","License system is not initialized"),!1)}function Bxe(t){if(!t||typeof t!="object")return!1;let e=t;return(e.canUsePro===!0||e.canUsePro===!1)&&typeof e.status=="string"&&typeof e.checkedAt=="number"}function Lm(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=e.body,a=typeof i?.licenseKey=="string"?i.licenseKey:"";if(!a.trim()){Pi(n,400,"LICENSE_KEY_REQUIRED","licenseKey is required");return}let o=jm(t,e,n,i?.provider);if(!o)return;let s=typeof i?.pluginClientId=="string"?i.pluginClientId:typeof e.query.clientId=="string"?e.query.clientId:void 0,c=typeof i?.deviceId=="string"?i.deviceId:void 0,l={licenseKey:a,provider:o,clientType:r};s&&(l.pluginClientId=s),c&&(l.deviceId=c),t.licenseState.activateGateway(l).then(u=>{t.analyticsManager?.setTier(u.canUsePro?"pro":"basic"),SS(t,{provider:u.provider,tier:u.canUsePro?"pro":"basic",status:u.status,canUsePro:u.canUsePro}),n.json(wS(u,r))}).catch(u=>{y.warn("License activate failed",{error:u instanceof Error?u.message:"unknown_error"}),Pi(n,502,"LICENSE_ACTIVATE_FAILED",u instanceof Error?u.message:"License activation failed")})}function zm(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=jm(t,e,n);if(i)try{let a=t.licenseState.getStatus(i);t.analyticsManager?.setTier(a.canUsePro?"pro":"basic"),n.json(wS(a,r))}catch(a){y.warn("License status check failed",{error:a instanceof Error?a.message:"unknown_error"}),Pi(n,502,"LICENSE_STATUS_FAILED",a instanceof Error?a.message:"License status check failed")}}function Um(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=e.body,a=jm(t,e,n,i?.provider);if(!a)return;let o={provider:a,clientType:r};r==="plugin"&&typeof i?.sessionToken=="string"&&i.sessionToken.trim()&&(o.sessionToken=i.sessionToken.trim()),typeof i?.pluginClientId=="string"&&(o.pluginClientId=i.pluginClientId),typeof i?.deviceId=="string"&&(o.deviceId=i.deviceId),t.licenseState.refreshGateway(o).then(s=>{t.analyticsManager?.setTier(s.canUsePro?"pro":"basic"),SS(t,{provider:s.provider,tier:s.canUsePro?"pro":"basic",status:s.status,canUsePro:s.canUsePro}),n.json(wS(s,r))}).catch(s=>{y.warn("License refresh failed",{error:s instanceof Error?s.message:"unknown_error"}),Pi(n,502,"LICENSE_REFRESH_FAILED",s instanceof Error?s.message:"License refresh failed")})}function Fm(t,e,n,r="plugin"){if(!Mm(t,n))return;let i=e.body,a=jm(t,e,n,i?.provider);a&&t.licenseState.resetGateway({provider:a,clientType:r}).then(o=>{t.analyticsManager?.setTier("basic"),SS(t,{provider:o.provider,tier:"basic",status:o.status,canUsePro:o.canUsePro,cleared:!0}),n.json(wS(o,r))}).catch(o=>{y.warn("License reset failed",{error:o instanceof Error?o.message:"unknown_error"}),Pi(n,502,"LICENSE_RESET_FAILED",o instanceof Error?o.message:"License reset failed")})}function a1(t,e,n){if(!Mm(t,n))return;let r=e.body,i=jm(t,e,n,r?.provider);if(!i)return;if(r?.clientType!=="plugin"){Pi(n,400,"LICENSE_CLIENT_TYPE_INVALID","clientType must be plugin");return}let a=typeof r?.sessionToken=="string"&&r.sessionToken.trim()?r.sessionToken.trim():void 0,o=Bxe(r?.snapshot)?r.snapshot:void 0;if(!o&&!a){Pi(n,400,"LICENSE_BOOTSTRAP_REQUIRED","snapshot or sessionToken is required");return}let s={provider:i,clientType:"plugin"};o&&(s.snapshot=o),a&&(s.sessionToken=a),t.licenseState.bootstrap(s).then(c=>{t.analyticsManager?.setTier(c.canUsePro?"pro":"basic"),SS(t,{provider:c.provider,tier:c.canUsePro?"pro":"basic",status:c.status,canUsePro:c.canUsePro}),n.json({ok:!0})}).catch(c=>{y.warn("License bootstrap failed",{error:c instanceof Error?c.message:"unknown_error"}),Pi(n,502,"LICENSE_BOOTSTRAP_FAILED",c instanceof Error?c.message:"License bootstrap failed")})}function R3(t){t.app.post("/license/bootstrap",(e,n)=>a1(t,e,n)),t.app.post("/license/activate",(e,n)=>Lm(t,e,n,"plugin")),t.app.post("/license/refresh",(e,n)=>Um(t,e,n,"plugin")),t.app.post("/license/reset",(e,n)=>Fm(t,e,n,"plugin")),t.app.get("/license/status",(e,n)=>zm(t,e,n,"plugin"))}vt();oe();import{promises as IS}from"fs";import o1 from"path";function Vxe(t){let e=t.config.appDataDir??it();return o1.join(e,"observability","logs")}async function $u(t,e,n){let r=e.query.clientId;if(r&&t.pluginClients.has(r)){let i=t.pluginClients.get(r);i.lastSeen=Date.now()}try{let i=e.body;if(!i||!Array.isArray(i.logs)){y.warn("Invalid logs request",{body:i}),n.status(400).json({error:"Invalid request body"});return}let a=Vxe(t);await IS.mkdir(a,{recursive:!0});let c=`plugin-${new Date().toISOString().split("T")[0]}.log`,l=o1.join(a,c),u=o1.join(a,"current.log"),d=i.logs.map(p=>`[${new Date(p.timestamp*1e3).toISOString().replace("T"," ").substring(0,19)}] [${p.level}] ${p.message}`).join(`
531
531
  `)+`
532
532
  `;await IS.appendFile(l,d,"utf-8");try{let p="";try{p=await IS.readFile(u,"utf-8")}catch{}let m=(p+d).split(`
533
533
  `).slice(-500).join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weppy/roblox-mcp",
3
- "version": "2.12.2",
3
+ "version": "2.12.3",
4
4
  "description": "MCP (Model Context Protocol) server for Roblox Studio integration - enables AI coding agents to interact with Roblox Studio in real-time",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
Binary file