@fps-games/editor-deployment 0.2.3-beta.8 → 0.2.3-beta.9

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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{createHash as Se,randomUUID as k}from"node:crypto";import{constants as be,createReadStream as K}from"node:fs";import{access as Re,readFile as G,realpath as B,stat as U}from"node:fs/promises";import R from"node:path";import{Readable as Ee}from"node:stream";var F="/__fps_editor_agent/v1/asset-source-grants";var Ye=8*1024*1024,ee=128,te=256*1024;var d=Object.freeze({ok:0,usage:2,discovery:3,unavailable:4,conflict:5,execution:6,running:7,interrupted:130}),W=1024*1024,Q=3e4,ne=R.join(".fps-editor","state","agent-runtime.json"),D=Object.freeze({kind:"fps-editor-agent-deadline"}),q=!1,M=Number.POSITIVE_INFINITY,ce=Q,E=new AbortController;process.once("SIGINT",()=>{q=!0,E.abort(),process.exitCode=d.interrupted,setTimeout(()=>process.exit(d.interrupted),25).unref?.()});Te().catch(e=>{let t=q?L():we(e);S(t.result??{ok:!1,error:{code:t.code,message:t.message}}),t.log!==!1&&process.stderr.write(`[fps-editor-agent] ${t.message}
3
- `),process.exitCode=t.exitCode});async function Te(){let e=Be(process.argv.slice(2)),t=e.argv,n=e.projectRoot??process.cwd(),i=e.projectRoot!==void 0;if(ce=e.deadlineMs,M=Date.now()+e.deadlineMs,t.length===0||t.includes("--help")||t[0]==="help"){S({ok:!0,usage:ze()});return}if(t.includes("--version")){let s=JSON.parse(await G(new URL("../package.json",import.meta.url),"utf8"));S({ok:!0,package:s.name,version:s.version,protocolVersion:2});return}let o=t.shift();if(o==="doctor"){let s=await le(n,{validateService:!1,exactProjectRoot:i}),l=await fe(s),r=await(await se(n,{exactProjectRoot:i})).request({kind:"status"});S({ok:!0,descriptorPath:s.descriptorPath,projectRoot:s.projectRoot,checks:l,status:r.status});return}let a=await se(n,{exactProjectRoot:i});if(o==="status"){S(await a.request({kind:"status"}));return}if(o==="commands"){await Oe(a,t);return}if(o==="command"){await _e(a,t);return}if(o==="transaction"){await Ae(a,t);return}if(o==="apply"){await Ne(a,t);return}if(o==="operation"){await De(a,t);return}if(o==="trace"){await Ce(a,t);return}throw c(`Unknown command: ${String(o)}`)}async function Oe(e,t){let n=t.shift();if(n==="describe"){let s=j(t,"command id");Ie(t),S(await e.request({kind:"commands.describe",commandId:s}));return}let i=A(t,new Set(["--cursor","--limit"])),o=g(i.options,"--cursor"),a=T(i.options,"--limit",{minimum:1});if(n==="list"){if(i.positionals.length)throw c("commands list does not accept positional arguments.");S(await e.request({kind:"commands.list",...o?{cursor:o}:{},...a?{limit:a}:{}}));return}if(n==="search"){let s=j(i.positionals,"search query");if(i.positionals.length)throw c("commands search accepts one query.");S(await e.request({kind:"commands.search",query:s,...o?{cursor:o}:{},...a?{limit:a}:{}}));return}throw c("commands requires list, search, or describe.")}async function _e(e,t){let n=A(t,new Set(["--stdin","--input-file","--input-json","--expected-revision","--idempotency-key","--request-id","--timeout","--trace-id","--client-id","--source-file"]),new Set(["--stdin"])),i=j(n.positionals,"command id");if(n.positionals.length)throw c("command accepts one command id.");let o=await Me(n.options),a=await e.request({kind:"commands.describe",commandId:i}),s=a.ok&&a.kind==="command"?a.command:null;if(!s)throw I(d.unavailable,"command.unknown",`Editor command is not registered: ${i}`);if(!s.availability.available)throw I(d.unavailable,"command.unavailable",s.availability.reasons.map(p=>p.message).join("; ")||`Editor command is unavailable: ${i}`);let l=g(n.options,"--source-file"),u=null;if(l){if(i!=="asset.import")throw c("--source-file is only valid for asset.import.");if(!o||typeof o!="object"||Array.isArray(o))throw c("asset.import input must be a JSON object.");if(Object.prototype.hasOwnProperty.call(o,"sourceGrantId"))throw c("Do not combine --source-file with input.sourceGrantId.");let p=await e.uploadAssetSource(R.resolve(l));u=p.sourceGrantId,o={...o,sourceGrantId:p.sourceGrantId}}let r=!1,m=!1,w=null;try{let p=T(n.options,"--expected-revision",{minimum:0}),h=e.serviceInstanceId;if(s.manifest.access==="write"&&p===void 0){let b=await e.request({kind:"status"});p=b.status.documentRevision,h=b.status.serviceInstanceId}let f=g(n.options,"--request-id")??k(),v=g(n.options,"--idempotency-key")??(s.manifest.access==="write"?k():void 0),y=T(n.options,"--timeout",{minimum:0});r=!0;let N=await e.request({kind:"command.invoke",invocation:{commandId:i,input:o,requestId:f,...v?{idempotencyKey:v}:{},...p!==void 0?{expectedRevision:{serviceInstanceId:h,document:p}}:{},principal:{type:"agent",id:"fps-editor-agent"},source:"agent-cli",...g(n.options,"--trace-id")?{traceId:g(n.options,"--trace-id")}:{},...g(n.options,"--client-id")?{clientId:g(n.options,"--client-id")}:{}},...y!==void 0?{timeoutMs:y}:{}});m=!0,S(N),H(N.operation)}catch(p){throw w=p,p}finally{let p=r&&!m&&["cli.deadlineExceeded","cli.interrupted","service.unreachable"].includes(w?.code);u&&!p&&await e.revokeAssetSource(u).catch(()=>{})}}async function Ae(e,t){let n=t.shift();if(n==="begin"){let s=A(t,new Set(["--expected-revision","--label","--transaction-id","--trace-id","--service-instance-id"]));if(s.positionals.length)throw c("transaction begin does not accept positional arguments.");let l=await de(e),u=g(s.options,"--transaction-id")??k(),r=await e.request({kind:"transaction.begin",serviceInstanceId:g(s.options,"--service-instance-id")??l.serviceInstanceId,expectedDocumentRevision:T(s.options,"--expected-revision",{minimum:0})??l.documentRevision,...g(s.options,"--label")?{label:g(s.options,"--label")}:{},transactionId:u,...g(s.options,"--trace-id")?{traceId:g(s.options,"--trace-id")}:{}});S(r),P(r.transaction);return}let i=A(t,new Set(["--service-instance-id","--sequence","--stdin","--input-file","--cursor","--limit"]),new Set(["--stdin"])),o=j(i.positionals,"transaction id");if(i.positionals.length)throw c(`transaction ${String(n)} accepts one transaction id.`);let a=g(i.options,"--service-instance-id")??e.serviceInstanceId;if(n==="append"){z(i.options,new Set(["--service-instance-id","--sequence","--stdin","--input-file"]));let s=T(i.options,"--sequence",{minimum:0});s===void 0&&(s=(await e.request({kind:"transaction.get",transactionId:o,serviceInstanceId:a,limit:1})).transaction.acceptedOperations);let l,u=ue(i.options);await pe({client:e,source:u,transactionId:o,serviceInstanceId:a,sequence:s,maxOperations:e.status.transactions.maxOperationsPerAppend,maxBytes:e.status.transactions.maxBytesPerAppend,onAppend(r){l=r,S(r)}}),P(l?.transaction);return}if(n==="preflight"||n==="commit"||n==="abort"){z(i.options,new Set(["--service-instance-id"]));let s=await e.request({kind:`transaction.${n}`,transactionId:o,serviceInstanceId:a});S(s),P(s.transaction,{abortedIsSuccess:n==="abort"});return}if(n==="get"){z(i.options,new Set(["--service-instance-id","--cursor","--limit"]));let s=await e.request({kind:"transaction.get",transactionId:o,serviceInstanceId:a,...g(i.options,"--cursor")?{cursor:g(i.options,"--cursor")}:{},...T(i.options,"--limit",{minimum:1})?{limit:T(i.options,"--limit",{minimum:1})}:{}});S(s),P(s.transaction);return}throw c("transaction requires begin, append, preflight, commit, get, or abort.")}async function Ne(e,t){let n=A(t,new Set(["--stdin","--input-file","--save","--expected-revision","--label","--transaction-id","--trace-id","--service-instance-id","--timeout"]),new Set(["--stdin","--save"]));if(n.positionals.length)throw c("apply does not accept positional arguments.");let i=await de(e),o=g(n.options,"--service-instance-id")??i.serviceInstanceId,a=T(n.options,"--expected-revision",{minimum:0})??i.documentRevision,s=T(n.options,"--timeout",{minimum:0}),l=g(n.options,"--transaction-id")??k(),u=g(n.options,"--trace-id"),r,m="begin";try{r=(await e.request({kind:"transaction.begin",serviceInstanceId:o,expectedDocumentRevision:a,transactionId:l,...g(n.options,"--label")?{label:g(n.options,"--label")}:{},...u?{traceId:u}:{}})).transaction,$("begin",r),m="append";let p=ue(n.options);if(await pe({client:e,source:p,transactionId:r.transactionId,serviceInstanceId:r.serviceInstanceId,sequence:r.acceptedOperations,maxOperations:i.transactions.maxOperationsPerAppend,maxBytes:i.transactions.maxBytesPerAppend,onAppend(ve){r=ve.transaction,$("append",r)}}),m="commit",r=(await e.request({kind:"transaction.commit",transactionId:r.transactionId,serviceInstanceId:r.serviceInstanceId})).transaction,$("commit",r),r.state!=="working_committed"){O(!1,"commit_failed",r),P(r);return}if(!n.options.has("--save")){O(!0,"working_committed",r);return}m="document.export";let f=await ie(e,{commandId:"document.export",input:{},expectedDocumentRevision:r.workingDocumentRevision,serviceInstanceId:r.serviceInstanceId,transactionId:r.transactionId,traceId:u,timeoutMs:s});if(oe("document.export",r,f.operation),f.operation?.status==="accepted"||f.operation?.status==="running"){O(!1,"awaiting_export_operation",r,{operation:_(f.operation),allowedActions:["operation.get","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),process.exitCode=d.running;return}if(f.operation?.status!=="completed"){O(!1,"save_failed",r,{operation:_(f.operation),allowedActions:["command document.export","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),H(f.operation);return}let v=f.operation.output;if(!v||typeof v!="object"||Array.isArray(v))throw I(d.execution,"document.exportReceiptInvalid","document.export returned an invalid receipt.");if(v.persistedByEditor===!1){O(!1,"awaiting_persistence_confirmation",r,{operation:_(f.operation),allowedActions:["operation.get","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),process.exitCode=d.running;return}let y=typeof v.transactionId=="string"&&v.transactionId.trim()?v.transactionId:null;if(!y)throw I(d.execution,"document.exportReceiptInvalid","document.export receipt is missing transactionId.");m="document.commit";let N=Number.isSafeInteger(v.documentRevision)?v.documentRevision:r.workingDocumentRevision,b=await ie(e,{commandId:"document.commit",input:{transactionId:y},expectedDocumentRevision:N,serviceInstanceId:r.serviceInstanceId,transactionId:r.transactionId,traceId:u,timeoutMs:s});if(oe("document.commit",r,b.operation),b.operation?.status==="accepted"||b.operation?.status==="running"){O(!1,"awaiting_commit_operation",r,{saveTransactionId:y,operation:_(b.operation),allowedActions:["operation.get","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),process.exitCode=d.running;return}if(b.operation?.status!=="completed"){O(!1,"save_commit_failed",r,{saveTransactionId:y,operation:_(b.operation),allowedActions:["command document.commit","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),H(b.operation);return}O(!0,"saved",r,{saveTransactionId:y,operation:_(b.operation),receipt:ke(b.operation.output)})}catch(w){let p=we(w);if(p.result?.kind==="cli.deadline"){S({...p.result,kind:"apply.result",phase:m,...r?{transaction:x(r)}:{}}),process.exitCode=p.exitCode;return}let h;if(r&&(r.state==="open"||r.state==="preflighted"))try{r=(await e.request({kind:"transaction.abort",transactionId:r.transactionId,serviceInstanceId:r.serviceInstanceId})).transaction,h=x(r),$("abort",r)}catch{}S({ok:!1,kind:"apply.result",state:r?.state==="working_committed"?"save_failed":"failed",phase:m,...r?{transaction:x(r)}:{},...h?{aborted:h}:{},error:{code:p.code,message:p.message},allowedActions:r?.state==="working_committed"?["command document.export","transaction.get"]:["status"],retry:{retryable:r?.state==="working_committed",requiresRebase:/revision|serviceInstance/i.test(p.code)}}),process.exitCode=p.exitCode}}async function de(e){let t=await e.request({kind:"status"});if(t.kind!=="status"||!t.status)throw I(d.discovery,"protocol.statusInvalid","Editor Service returned an invalid status response.");return t.status}function ue(e){if(["--stdin","--input-file"].filter(i=>e.has(i)).length>1)throw c("Use only one of --stdin or --input-file.");let n=g(e,"--input-file");return!n||n==="-"?process.stdin:K(R.resolve(n),{encoding:"utf8"})}async function pe(e){let t=re(e.maxOperations,ee),n=re(e.maxBytes,te),i=[],o=2,a=e.sequence,s=0,l=0,u=async()=>{if(i.length===0)return;let r=i.length,m=await e.client.request({kind:"transaction.append",transactionId:e.transactionId,serviceInstanceId:e.serviceInstanceId,sequence:a,operations:i});if(m.kind!=="transaction"||m.transaction.acceptedOperations<a+r)throw I(d.execution,"transaction.appendReceiptInvalid","Editor Service returned an invalid append receipt.");a=m.transaction.acceptedOperations,s+=r,e.onAppend(m),i=[],o=2};for await(let r of Fe(e.source,E.signal,n)){l+=1;let m=r.endsWith("\r")?r.slice(0,-1):r;if(!m.trim())continue;let w;try{w=JSON.parse(m)}catch(v){throw c(`NDJSON line ${l} is not valid JSON: ${v instanceof Error?v.message:String(v)}`)}xe(w,l);let p=JSON.stringify(w),h=Buffer.byteLength(p);if(h+2>n)throw c(`NDJSON line ${l} exceeds the ${n}-byte transaction append limit.`);let f=o+h+(i.length?1:0);i.length&&(i.length>=t||f>n)&&await u(),i.push(w),o+=h+(i.length>1?1:0),(i.length>=t||o>=n)&&await u()}if(await u(),s===0)throw c("Transaction input must contain at least one NDJSON operation.");return{acceptedOperations:s,nextSequence:a}}function xe(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw c(`NDJSON line ${t} must be a transaction operation object.`);if(typeof e.opId!="string"||!e.opId.trim())throw c(`NDJSON line ${t} requires a non-empty opId.`);if(typeof e.commandId!="string"||!e.commandId.trim())throw c(`NDJSON line ${t} requires a non-empty commandId.`);if(e.as!==void 0&&(typeof e.as!="string"||!e.as.trim()))throw c(`NDJSON line ${t} as must be a non-empty string.`)}async function ie(e,t){let n=await e.request({kind:"commands.describe",commandId:t.commandId}),i=n.kind==="command"?n.command:null;if(!i)throw I(d.unavailable,"command.unknown",`Editor command is not registered: ${t.commandId}`);if(!i.availability.available)throw I(d.unavailable,"command.unavailable",i.availability.reasons.map(s=>s.message).join("; ")||`Editor command is unavailable: ${t.commandId}`);let o=await e.request({kind:"command.invoke",invocation:{commandId:t.commandId,input:t.input,requestId:k(),idempotencyKey:k(),expectedRevision:{serviceInstanceId:t.serviceInstanceId,...t.expectedDocumentRevision===void 0?{}:{document:t.expectedDocumentRevision}},principal:{type:"agent",id:"fps-editor-agent"},source:"agent-cli",transactionId:t.transactionId,...t.traceId?{traceId:t.traceId}:{}},...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}),a=o.operation;return a&&!ge(a.status)&&(a=(await e.request({kind:"operation.get",operationId:a.operationId})).operation??a),{response:o,operation:a}}function $(e,t){S({ok:t.state!=="failed",kind:"apply.event",phase:e,state:t.state,transaction:x(t)})}function oe(e,t,n){S({ok:n?.status!=="failed"&&n?.status!=="cancelled",kind:"apply.event",phase:e,state:n?.status??"unavailable",transaction:x(t),operation:_(n)})}function O(e,t,n,i={}){S({ok:e,kind:"apply.result",state:t,phase:t==="saved"?"complete":n.phase,transaction:x(n),...i.allowedActions?{}:{allowedActions:n.allowedActions},...i.retry?{}:{retry:n.retry},...i})}function x(e){return{transactionId:e.transactionId,serviceInstanceId:e.serviceInstanceId,state:e.state,phase:e.phase,baseDocumentRevision:e.baseDocumentRevision,...e.workingDocumentRevision===void 0?{}:{workingDocumentRevision:e.workingDocumentRevision},dirty:e.dirty,acceptedOperations:e.acceptedOperations,acceptedBytes:e.acceptedBytes,processedOperations:e.processedOperations,allowedActions:e.allowedActions,retry:e.retry,diagnostics:e.diagnostics,results:{offset:e.results.offset,returned:e.results.returned,total:e.results.total,...e.results.nextCursor?{nextCursor:e.results.nextCursor}:{}}}}function _(e){return e?{operationId:e.operationId,requestId:e.requestId,commandId:e.commandId,status:e.status,...e.transactionId?{transactionId:e.transactionId}:{},...e.traceId?{traceId:e.traceId}:{},...e.output===void 0?{}:{output:e.output},...e.diagnostics?{diagnostics:e.diagnostics}:{}}:null}function ke(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function re(e,t){return Number.isSafeInteger(e)&&e>0?e:t}async function De(e,t){let n=t.shift();if(n==="get"){let i=A(t,new Set(["--request-id","--service-instance-id"])),o=i.positionals.shift();if(i.positionals.length)throw c("operation get accepts at most one operation id.");let a=g(i.options,"--request-id");if(!o&&!a||o&&a)throw c("operation get requires exactly one operation id or --request-id.");let s=g(i.options,"--service-instance-id");if(s&&s!==e.serviceInstanceId)throw I(d.conflict,"operation.serviceInstanceChanged",`Expected Editor Service ${s}, received ${e.serviceInstanceId}.`);let l=await e.request(o?{kind:"operation.get",operationId:o}:{kind:"operation.get",requestId:a});S(l),l.operation?H(l.operation):process.exitCode=d.unavailable;return}if(n==="cancel"){let i=j(t,"operation id");Ie(t);let o=await e.request({kind:"operation.cancel",operationId:i});S(o),o.operation?!o.cancelled&&!ge(o.operation.status)&&(process.exitCode=d.running):process.exitCode=d.unavailable;return}throw c("operation requires get or cancel.")}async function Ce(e,t){if(t.shift()!=="get")throw c("trace requires get.");let i=A(t,new Set(["--cursor","--limit"])),o=i.positionals.shift();if(i.positionals.length)throw c("trace get accepts at most one trace id.");S(await e.request({kind:"trace.get",...o?{traceId:o}:{},...g(i.options,"--cursor")?{cursor:g(i.options,"--cursor")}:{},...T(i.options,"--limit",{minimum:1})?{limit:T(i.options,"--limit",{minimum:1})}:{}}))}async function se(e,t={}){let n=await le(e,{validateService:!0,...t}),i=me(process.env.FPS_EDITOR_AGENT_ENDPOINT?.trim()||n.descriptor.endpoint),o=process.env.FPS_EDITOR_AGENT_TOKEN?.trim()||n.descriptor.token,a=async r=>{if(q)throw I(d.interrupted,"cli.interrupted","Interrupted.");let m=M-Date.now();if(m<=0)throw C(n,r);let w=new AbortController,p=()=>w.abort(E.signal.reason);E.signal.addEventListener("abort",p,{once:!0});let h=setTimeout(()=>w.abort(D),m);h.unref?.();try{let f=await fetch(i,{method:"POST",headers:{authorization:`Bearer ${o}`,"content-type":"application/json"},body:JSON.stringify(r),signal:w.signal}),v=await X(f),y;try{y=JSON.parse(v)}catch{throw I(d.discovery,"protocol.invalidJson","Editor Service returned invalid JSON.")}if(f.status===401||f.status===403)throw I(d.discovery,"auth.invalidToken",he(y)||"Editor Service authentication failed.");if(!y?.ok)throw Y(y);return y}catch(f){throw q||E.signal.aborted?L():w.signal.reason===D?C(n,r):f&&Number.isInteger(f.exitCode)?f:I(d.discovery,"service.unreachable",`Editor Service is unreachable: ${f instanceof Error?f.message:String(f)}`)}finally{clearTimeout(h),E.signal.removeEventListener("abort",p)}},s=await a({kind:"status"});Ue(n,s);let l=async r=>{let m=await Pe(r),w=new URL(F,i),p=new AbortController,h=M-Date.now();if(h<=0)throw C(n,{kind:"asset.sourceGrant"});let f=()=>p.abort(E.signal.reason);E.signal.addEventListener("abort",f,{once:!0});let v=setTimeout(()=>p.abort(D),h);v.unref?.();try{let y=await fetch(w,{method:"POST",headers:{authorization:`Bearer ${o}`,"content-type":"application/vnd.fps-editor.asset-source-bundle-v1"},body:Ee.from(je(m)),duplex:"half",signal:p.signal}),N=await X(y),b;try{b=JSON.parse(N)}catch{throw I(d.discovery,"protocol.invalidJson","Editor Service returned invalid JSON for asset source upload.")}if(!y.ok||!b?.ok||b.kind!=="asset.sourceGrant"||!b.grant?.sourceGrantId)throw Y(b);return b.grant}catch(y){throw q||E.signal.aborted?L():p.signal.reason===D?C(n,{kind:"asset.sourceGrant"}):y&&Number.isInteger(y.exitCode)?y:I(d.discovery,"asset.sourceUploadFailed",`Asset source upload failed: ${y instanceof Error?y.message:String(y)}`)}finally{clearTimeout(v),E.signal.removeEventListener("abort",f)}},u=async r=>{let m=M-Date.now();if(m<=0)throw C(n,{kind:"asset.sourceGrant.revoke"});let w=new AbortController,p=setTimeout(()=>w.abort(D),m);p.unref?.();try{let h=new URL(F,i);h.searchParams.set("sourceGrantId",r);let f=await fetch(h,{method:"DELETE",headers:{authorization:`Bearer ${o}`},signal:w.signal}),v=await X(f),y;try{y=JSON.parse(v)}catch{throw I(d.discovery,"protocol.invalidJson","Editor Service returned invalid JSON for asset source revocation.")}if(!f.ok||!y?.ok)throw Y(y);return y}finally{clearTimeout(p)}};return Object.freeze({discovery:n,serviceInstanceId:n.descriptor.serviceInstanceId,status:s.status,request:a,uploadAssetSource:l,revokeAssetSource:u})}async function Pe(e){let t;try{t=await B(e)}catch(u){throw I(d.usage,"asset.sourceNotFound",`Asset source is unavailable: ${u instanceof Error?u.message:String(u)}`)}let n=await U(t);if(!n.isFile())throw c("Asset source must be a regular file.");let i=R.extname(t).toLowerCase();if(![".glb",".gltf",".png",".jpg",".jpeg",".env"].includes(i))throw c("Asset source must be GLB, glTF, PNG, JPG, JPEG, or Babylon ENV.");let o=R.dirname(t),a=new Map([[R.basename(t),t]]);if(i===".gltf"){if(n.size>16*1024*1024)throw c("glTF JSON source exceeds the 16 MiB manifest limit.");let u;try{u=JSON.parse(await G(t,"utf8"))}catch(m){throw c(`glTF source is not valid JSON: ${m instanceof Error?m.message:String(m)}`)}let r=[...Array.isArray(u?.buffers)?u.buffers:[],...Array.isArray(u?.images)?u.images:[]];for(let m of r){let w=typeof m?.uri=="string"?m.uri:null;if(!w||w.startsWith("data:"))continue;if(/^[a-z][a-z0-9+.-]*:/i.test(w)||w.startsWith("//"))throw c("glTF dependencies must use local relative URIs.");let p;try{p=decodeURIComponent(w.split(/[?#]/,1)[0])}catch{throw c(`glTF dependency URI is malformed: ${w}`)}let h=R.posix.normalize(p.replaceAll("\\","/"));if(!h||h==="."||h===".."||h.startsWith("../")||R.posix.isAbsolute(h))throw c(`glTF dependency escapes the source directory: ${w}`);let f;try{f=await B(R.resolve(o,...h.split("/")))}catch{throw c(`glTF dependency is missing: ${h}`)}if(Le(o,f,h),!(await U(f)).isFile())throw c(`glTF dependency is not a regular file: ${h}`);a.set(h,f)}}let s=[];for(let[u,r]of a){let m=await U(r);if(m.size<1||m.size>256*1024*1024)throw c(`Asset source file size is outside the supported range: ${u}`);s.push({path:u,filePath:r,byteSize:m.size,contentHash:await qe(r)})}let l=s.reduce((u,r)=>u+r.byteSize,0);if(s.length>128||l>512*1024*1024)throw c("Asset source bundle exceeds the supported file-count or total-size limit.");return{primaryPath:R.basename(t),files:s}}async function qe(e){let t=Se("sha256");for await(let n of K(e))t.update(n);return`sha256:${t.digest("hex")}`}async function*je(e){let t=Buffer.from(JSON.stringify({schemaVersion:1,primaryPath:e.primaryPath,files:e.files.map(({path:i,byteSize:o,contentHash:a})=>({path:i,byteSize:o,contentHash:a}))}),"utf8"),n=Buffer.allocUnsafe(4);n.writeUInt32BE(t.length,0),yield n,yield t;for(let i of e.files)for await(let o of K(i.filePath))yield o}function Le(e,t,n){let i=R.relative(e,t);if(!i||i===".."||i.startsWith(`..${R.sep}`)||R.isAbsolute(i))throw c(`glTF dependency escapes the source directory: ${n}`)}async function le(e,t={}){let n;try{n=await B(R.resolve(e))}catch(i){throw I(d.discovery,"projectRoot.invalid",`Project root is unavailable: ${i instanceof Error?i.message:String(i)}`)}for(;;){let i=R.join(n,ne);if(await Je(i)){let a=await $e(i),s=await B(n);if(a.canonicalProjectRoot!==s)throw I(d.discovery,"descriptor.projectMismatch",`Runtime descriptor does not own ${s}.`);let l={descriptorPath:i,projectRoot:s,descriptor:a};return t.validateService!==!1&&await fe(l),l}if(t.exactProjectRoot===!0)break;let o=R.dirname(n);if(o===n)break;n=o}throw I(d.discovery,"descriptor.notFound",`No ${ne} was found from ${e}.`)}async function $e(e){let t;try{t=JSON.parse(await G(e,"utf8"))}catch(n){throw I(d.discovery,"descriptor.invalid",`Runtime descriptor is unreadable: ${n instanceof Error?n.message:String(n)}`)}if(t?.schemaVersion!==1||t?.protocolVersion!==2||t?.packageName!=="@fps-games/editor"||typeof t?.serviceInstanceId!="string"||typeof t?.canonicalProjectRoot!="string"||typeof t?.endpoint!="string"||typeof t?.token!="string"||!Number.isSafeInteger(t?.pid))throw I(d.discovery,"descriptor.incompatible","Runtime descriptor schema or protocol is incompatible.");if(me(t.endpoint),process.platform!=="win32"){let n=(await U(e)).mode&511;if(n&63)throw I(d.discovery,"descriptor.permissions",`Runtime descriptor permissions must be 0600; received ${n.toString(8)}.`)}return t}function me(e){let t;try{t=new URL(e)}catch{throw I(d.discovery,"descriptor.endpoint","Runtime descriptor endpoint is invalid.")}if(t.protocol!=="http:"||!["127.0.0.1","localhost","[::1]"].includes(t.hostname))throw I(d.discovery,"descriptor.endpoint","Runtime descriptor endpoint must be project-local loopback HTTP.");return t.toString()}async function fe(e){let t=[];t.push({id:"descriptor.schema",ok:e.descriptor.schemaVersion===1}),t.push({id:"descriptor.protocol",ok:e.descriptor.protocolVersion===2}),t.push({id:"descriptor.project",ok:e.descriptor.canonicalProjectRoot===e.projectRoot});let n=He(e.descriptor.pid);if(t.push({id:"descriptor.process",ok:n,pid:e.descriptor.pid}),!n)throw I(d.discovery,"descriptor.stale",`Editor Service process is not alive: ${e.descriptor.pid}.`);return t}function Ue(e,t){let n=t?.kind==="status"?t.status:null;if(!n||n.protocolVersion!==2)throw I(d.discovery,"protocol.incompatible","Editor Service status protocol is incompatible.");if(n.serviceInstanceId!==e.descriptor.serviceInstanceId||n.canonicalProjectRoot!==e.projectRoot||n.packageVersion!==e.descriptor.packageVersion||n.buildKey!==e.descriptor.buildKey)throw I(d.discovery,"service.identityMismatch","Editor Service identity does not match the project runtime descriptor.")}async function Me(e){if(["--stdin","--input-file","--input-json"].filter(o=>e.has(o)).length>1)throw c("Use only one of --stdin, --input-file, or --input-json.");if(e.has("--stdin"))return V(await Ge(process.stdin,E.signal),"--stdin");let n=g(e,"--input-file");if(n)return V(await G(R.resolve(n),"utf8"),"--input-file");let i=g(e,"--input-json");return i===void 0?{}:V(i,"--input-json")}function V(e,t){try{return JSON.parse(e)}catch(n){throw c(`${t} is not valid JSON: ${n instanceof Error?n.message:String(n)}`)}}function A(e,t,n=new Set){let i=new Map,o=[];for(;e.length;){let a=e.shift();if(!a.startsWith("--")){o.push(a);continue}let[s,l]=a.split("=",2);if(!t.has(s))throw c(`Unknown option: ${s}`);if(i.has(s))throw c(`Option may only be provided once: ${s}`);if(n.has(s)){if(l!==void 0)throw c(`${s} does not accept a value.`);i.set(s,!0);continue}let u=l??e.shift();if(u===void 0||u.startsWith("--"))throw c(`${s} requires a value.`);i.set(s,u)}return{options:i,positionals:o}}function g(e,t){let n=e.get(t);if(n!==void 0){if(typeof n!="string"||!n.trim())throw c(`${t} requires a non-empty value.`);return n.trim()}}function Be(e){let t=[],n=Q,i=!1,o;for(let a=0;a<e.length;a+=1){let s=e[a];if(s==="--project-root"||s.startsWith("--project-root=")){if(o!==void 0)throw c("--project-root may only be provided once.");let r=s==="--project-root"?e[++a]:s.slice(15);if(r===void 0||!r.trim()||r.startsWith("--"))throw c("--project-root requires a non-empty path.");o=R.resolve(process.cwd(),r);continue}if(s!=="--deadline"&&!s.startsWith("--deadline=")){t.push(s);continue}if(i)throw c("--deadline may only be provided once.");i=!0;let l=s==="--deadline"?e[++a]:s.slice(11);if(l===void 0||l.startsWith("--"))throw c("--deadline requires a value.");let u=Number(l);if(!Number.isSafeInteger(u)||u<1)throw c("--deadline must be an integer >= 1.");n=u}return{argv:t,deadlineMs:n,projectRoot:o}}function T(e,t,{minimum:n}){let i=g(e,t);if(i===void 0)return;let o=Number(i);if(!Number.isSafeInteger(o)||o<n)throw c(`${t} must be an integer >= ${n}.`);return o}function j(e,t){let n=e.shift();if(!n)throw c(`Missing ${t}.`);return n}function Ie(e){if(e.length)throw c(`Unexpected argument: ${e[0]}`)}function z(e,t){for(let n of e.keys())if(!t.has(n))throw c(`Option is not valid for this action: ${n}`)}function H(e){if(!e){process.exitCode=d.unavailable;return}if(e.status==="accepted"||e.status==="running"){process.exitCode=d.running;return}(e.status==="failed"||e.status==="cancelled")&&(process.exitCode=Z(e.diagnostics))}function P(e,t={}){if(!e){process.exitCode=d.unavailable;return}if(e.state==="preflighting"||e.state==="committing"){process.exitCode=d.running;return}if(e.state==="failed"){process.exitCode=Z(e.diagnostics);return}e.state==="aborted"&&t.abortedIsSuccess!==!0&&(process.exitCode=d.execution)}function Z(e=[]){let t=e.map(n=>n?.code??"");return t.some(n=>/revision|idempotency|conflict|serviceInstance/i.test(n))?d.conflict:t.some(n=>/unknown|unavailable|notFound|sessionUnavailable/i.test(n))?d.unavailable:d.execution}function Y(e){let t=Array.isArray(e?.diagnostics)?e.diagnostics:[];return I(Z(t),t[0]?.code??"service.requestFailed",he(e)||"Editor Service request failed.")}function he(e){return Array.isArray(e?.diagnostics)?e.diagnostics.map(t=>t?.message).filter(Boolean).join("; "):""}function He(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}function ge(e){return e==="completed"||e==="failed"||e==="cancelled"}async function X(e){let t=Number(e.headers.get("content-length"));if(Number.isFinite(t)&&t>W)throw I(d.execution,"response.tooLarge","Editor Service response exceeds 1 MiB.");let n=await e.text();if(Buffer.byteLength(n)>W)throw I(d.execution,"response.tooLarge","Editor Service response exceeds 1 MiB.");return n}async function Je(e){try{return await Re(e,be.R_OK),!0}catch{return!1}}async function Ge(e,t){let n=[];for await(let i of ye(e,t))n.push(Buffer.isBuffer(i)?i:Buffer.from(i));return Buffer.concat(n).toString("utf8")}async function*Fe(e,t,n=Number.POSITIVE_INFINITY){let i="";for await(let o of ye(e,t)){i+=o.toString();let a;for(;(a=i.indexOf(`
2
+ import{createHash as Se,randomUUID as k}from"node:crypto";import{constants as Re,createReadStream as K}from"node:fs";import{access as Te,readFile as J,realpath as H,stat as M}from"node:fs/promises";import T from"node:path";import{Readable as Ee}from"node:stream";var F="/__fps_editor_agent/v1/asset-source-grants";var Ye=32*1024;var Xe=8*1024*1024,ee=128,te=256*1024;var d=Object.freeze({ok:0,usage:2,discovery:3,unavailable:4,conflict:5,execution:6,running:7,interrupted:130}),W=1024*1024,Q=3e4,ne=T.join(".fps-editor","state","agent-runtime.json"),C=Object.freeze({kind:"fps-editor-agent-deadline"}),q=!1,U=Number.POSITIVE_INFINITY,ce=Q,E=new AbortController;process.once("SIGINT",()=>{q=!0,E.abort(),process.exitCode=d.interrupted,setTimeout(()=>process.exit(d.interrupted),25).unref?.()});Oe().catch(e=>{let t=q?L():we(e);S(t.result??{ok:!1,error:{code:t.code,message:t.message}}),t.log!==!1&&process.stderr.write(`[fps-editor-agent] ${t.message}
3
+ `),process.exitCode=t.exitCode});async function Oe(){let e=He(process.argv.slice(2)),t=e.argv,n=e.projectRoot??process.cwd(),i=e.projectRoot!==void 0;if(ce=e.deadlineMs,U=Date.now()+e.deadlineMs,t.length===0||t.includes("--help")||t[0]==="help"){S({ok:!0,usage:ze()});return}if(t.includes("--version")){let s=JSON.parse(await J(new URL("../package.json",import.meta.url),"utf8"));S({ok:!0,package:s.name,version:s.version,protocolVersion:2});return}let o=t.shift();if(o==="doctor"){let s=await le(n,{validateService:!1,exactProjectRoot:i}),l=await fe(s),r=await(await se(n,{exactProjectRoot:i})).request({kind:"status"});S({ok:!0,descriptorPath:s.descriptorPath,projectRoot:s.projectRoot,checks:l,status:r.status});return}let a=await se(n,{exactProjectRoot:i});if(o==="status"){S(await a.request({kind:"status"}));return}if(o==="commands"){await be(a,t);return}if(o==="command"){await _e(a,t);return}if(o==="transaction"){await Ae(a,t);return}if(o==="apply"){await Ne(a,t);return}if(o==="operation"){await Ce(a,t);return}if(o==="trace"){await De(a,t);return}throw c(`Unknown command: ${String(o)}`)}async function be(e,t){let n=t.shift();if(n==="describe"){let s=j(t,"command id");Ie(t),S(await e.request({kind:"commands.describe",commandId:s}));return}let i=A(t,new Set(["--cursor","--limit"])),o=g(i.options,"--cursor"),a=O(i.options,"--limit",{minimum:1});if(n==="list"){if(i.positionals.length)throw c("commands list does not accept positional arguments.");S(await e.request({kind:"commands.list",...o?{cursor:o}:{},...a?{limit:a}:{}}));return}if(n==="search"){let s=j(i.positionals,"search query");if(i.positionals.length)throw c("commands search accepts one query.");S(await e.request({kind:"commands.search",query:s,...o?{cursor:o}:{},...a?{limit:a}:{}}));return}throw c("commands requires list, search, or describe.")}async function _e(e,t){let n=A(t,new Set(["--stdin","--input-file","--input-json","--expected-revision","--idempotency-key","--request-id","--timeout","--trace-id","--client-id","--source-file"]),new Set(["--stdin"])),i=j(n.positionals,"command id");if(n.positionals.length)throw c("command accepts one command id.");let o=await Ue(n.options),a=await e.request({kind:"commands.describe",commandId:i}),s=a.ok&&a.kind==="command"?a.command:null;if(!s)throw I(d.unavailable,"command.unknown",`Editor command is not registered: ${i}`);if(!s.availability.available)throw I(d.unavailable,"command.unavailable",s.availability.reasons.map(p=>p.message).join("; ")||`Editor command is unavailable: ${i}`);let l=g(n.options,"--source-file"),u=null;if(l){if(i!=="asset.import")throw c("--source-file is only valid for asset.import.");if(!o||typeof o!="object"||Array.isArray(o))throw c("asset.import input must be a JSON object.");if(Object.prototype.hasOwnProperty.call(o,"sourceGrantId"))throw c("Do not combine --source-file with input.sourceGrantId.");let p=await e.uploadAssetSource(T.resolve(l));u=p.sourceGrantId,o={...o,sourceGrantId:p.sourceGrantId}}let r=!1,m=!1,w=null;try{let p=O(n.options,"--expected-revision",{minimum:0}),h=e.serviceInstanceId;if(s.manifest.access==="write"&&p===void 0){let R=await e.request({kind:"status"});p=R.status.documentRevision,h=R.status.serviceInstanceId}let f=g(n.options,"--request-id")??k(),v=g(n.options,"--idempotency-key")??(s.manifest.access==="write"?k():void 0),y=O(n.options,"--timeout",{minimum:0});r=!0;let N=await e.request({kind:"command.invoke",invocation:{commandId:i,input:o,requestId:f,...v?{idempotencyKey:v}:{},...p!==void 0?{expectedRevision:{serviceInstanceId:h,document:p}}:{},principal:{type:"agent",id:"fps-editor-agent"},source:"agent-cli",...g(n.options,"--trace-id")?{traceId:g(n.options,"--trace-id")}:{},...g(n.options,"--client-id")?{clientId:g(n.options,"--client-id")}:{}},...y!==void 0?{timeoutMs:y}:{}});m=!0,S(N),B(N.operation)}catch(p){throw w=p,p}finally{let p=r&&!m&&["cli.deadlineExceeded","cli.interrupted","service.unreachable"].includes(w?.code);u&&!p&&await e.revokeAssetSource(u).catch(()=>{})}}async function Ae(e,t){let n=t.shift();if(n==="begin"){let s=A(t,new Set(["--expected-revision","--label","--transaction-id","--trace-id","--service-instance-id"]));if(s.positionals.length)throw c("transaction begin does not accept positional arguments.");let l=await de(e),u=g(s.options,"--transaction-id")??k(),r=await e.request({kind:"transaction.begin",serviceInstanceId:g(s.options,"--service-instance-id")??l.serviceInstanceId,expectedDocumentRevision:O(s.options,"--expected-revision",{minimum:0})??l.documentRevision,...g(s.options,"--label")?{label:g(s.options,"--label")}:{},transactionId:u,...g(s.options,"--trace-id")?{traceId:g(s.options,"--trace-id")}:{}});S(r),P(r.transaction);return}let i=A(t,new Set(["--service-instance-id","--sequence","--stdin","--input-file","--cursor","--limit"]),new Set(["--stdin"])),o=j(i.positionals,"transaction id");if(i.positionals.length)throw c(`transaction ${String(n)} accepts one transaction id.`);let a=g(i.options,"--service-instance-id")??e.serviceInstanceId;if(n==="append"){z(i.options,new Set(["--service-instance-id","--sequence","--stdin","--input-file"]));let s=O(i.options,"--sequence",{minimum:0});s===void 0&&(s=(await e.request({kind:"transaction.get",transactionId:o,serviceInstanceId:a,limit:1})).transaction.acceptedOperations);let l,u=ue(i.options);await pe({client:e,source:u,transactionId:o,serviceInstanceId:a,sequence:s,maxOperations:e.status.transactions.maxOperationsPerAppend,maxBytes:e.status.transactions.maxBytesPerAppend,onAppend(r){l=r,S(r)}}),P(l?.transaction);return}if(n==="preflight"||n==="commit"||n==="abort"){z(i.options,new Set(["--service-instance-id"]));let s=await e.request({kind:`transaction.${n}`,transactionId:o,serviceInstanceId:a});S(s),P(s.transaction,{abortedIsSuccess:n==="abort"});return}if(n==="get"){z(i.options,new Set(["--service-instance-id","--cursor","--limit"]));let s=await e.request({kind:"transaction.get",transactionId:o,serviceInstanceId:a,...g(i.options,"--cursor")?{cursor:g(i.options,"--cursor")}:{},...O(i.options,"--limit",{minimum:1})?{limit:O(i.options,"--limit",{minimum:1})}:{}});S(s),P(s.transaction);return}throw c("transaction requires begin, append, preflight, commit, get, or abort.")}async function Ne(e,t){let n=A(t,new Set(["--stdin","--input-file","--save","--expected-revision","--label","--transaction-id","--trace-id","--service-instance-id","--timeout"]),new Set(["--stdin","--save"]));if(n.positionals.length)throw c("apply does not accept positional arguments.");let i=await de(e),o=g(n.options,"--service-instance-id")??i.serviceInstanceId,a=O(n.options,"--expected-revision",{minimum:0})??i.documentRevision,s=O(n.options,"--timeout",{minimum:0}),l=g(n.options,"--transaction-id")??k(),u=g(n.options,"--trace-id"),r,m="begin";try{r=(await e.request({kind:"transaction.begin",serviceInstanceId:o,expectedDocumentRevision:a,transactionId:l,...g(n.options,"--label")?{label:g(n.options,"--label")}:{},...u?{traceId:u}:{}})).transaction,$("begin",r),m="append";let p=ue(n.options);if(await pe({client:e,source:p,transactionId:r.transactionId,serviceInstanceId:r.serviceInstanceId,sequence:r.acceptedOperations,maxOperations:i.transactions.maxOperationsPerAppend,maxBytes:i.transactions.maxBytesPerAppend,onAppend(ve){r=ve.transaction,$("append",r)}}),m="commit",r=(await e.request({kind:"transaction.commit",transactionId:r.transactionId,serviceInstanceId:r.serviceInstanceId})).transaction,$("commit",r),r.state!=="working_committed"){b(!1,"commit_failed",r),P(r);return}if(!n.options.has("--save")){b(!0,"working_committed",r);return}m="document.export";let f=await ie(e,{commandId:"document.export",input:{},expectedDocumentRevision:r.workingDocumentRevision,serviceInstanceId:r.serviceInstanceId,transactionId:r.transactionId,traceId:u,timeoutMs:s});if(oe("document.export",r,f.operation),f.operation?.status==="accepted"||f.operation?.status==="running"){b(!1,"awaiting_export_operation",r,{operation:_(f.operation),allowedActions:["operation.get","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),process.exitCode=d.running;return}if(f.operation?.status!=="completed"){b(!1,"save_failed",r,{operation:_(f.operation),allowedActions:["command document.export","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),B(f.operation);return}let v=f.operation.output;if(!v||typeof v!="object"||Array.isArray(v))throw I(d.execution,"document.exportReceiptInvalid","document.export returned an invalid receipt.");if(v.persistedByEditor===!1){b(!1,"awaiting_persistence_confirmation",r,{operation:_(f.operation),allowedActions:["operation.get","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),process.exitCode=d.running;return}let y=typeof v.transactionId=="string"&&v.transactionId.trim()?v.transactionId:null;if(!y)throw I(d.execution,"document.exportReceiptInvalid","document.export receipt is missing transactionId.");m="document.commit";let N=Number.isSafeInteger(v.documentRevision)?v.documentRevision:r.workingDocumentRevision,R=await ie(e,{commandId:"document.commit",input:{transactionId:y},expectedDocumentRevision:N,serviceInstanceId:r.serviceInstanceId,transactionId:r.transactionId,traceId:u,timeoutMs:s});if(oe("document.commit",r,R.operation),R.operation?.status==="accepted"||R.operation?.status==="running"){b(!1,"awaiting_commit_operation",r,{saveTransactionId:y,operation:_(R.operation),allowedActions:["operation.get","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),process.exitCode=d.running;return}if(R.operation?.status!=="completed"){b(!1,"save_commit_failed",r,{saveTransactionId:y,operation:_(R.operation),allowedActions:["command document.commit","transaction.get"],retry:{retryable:!0,requiresRebase:!1}}),B(R.operation);return}b(!0,"saved",r,{saveTransactionId:y,operation:_(R.operation),receipt:ke(R.operation.output)})}catch(w){let p=we(w);if(p.result?.kind==="cli.deadline"){S({...p.result,kind:"apply.result",phase:m,...r?{transaction:x(r)}:{}}),process.exitCode=p.exitCode;return}let h;if(r&&(r.state==="open"||r.state==="preflighted"))try{r=(await e.request({kind:"transaction.abort",transactionId:r.transactionId,serviceInstanceId:r.serviceInstanceId})).transaction,h=x(r),$("abort",r)}catch{}S({ok:!1,kind:"apply.result",state:r?.state==="working_committed"?"save_failed":"failed",phase:m,...r?{transaction:x(r)}:{},...h?{aborted:h}:{},error:{code:p.code,message:p.message},allowedActions:r?.state==="working_committed"?["command document.export","transaction.get"]:["status"],retry:{retryable:r?.state==="working_committed",requiresRebase:/revision|serviceInstance/i.test(p.code)}}),process.exitCode=p.exitCode}}async function de(e){let t=await e.request({kind:"status"});if(t.kind!=="status"||!t.status)throw I(d.discovery,"protocol.statusInvalid","Editor Service returned an invalid status response.");return t.status}function ue(e){if(["--stdin","--input-file"].filter(i=>e.has(i)).length>1)throw c("Use only one of --stdin or --input-file.");let n=g(e,"--input-file");return!n||n==="-"?process.stdin:K(T.resolve(n),{encoding:"utf8"})}async function pe(e){let t=re(e.maxOperations,ee),n=re(e.maxBytes,te),i=[],o=2,a=e.sequence,s=0,l=0,u=async()=>{if(i.length===0)return;let r=i.length,m=await e.client.request({kind:"transaction.append",transactionId:e.transactionId,serviceInstanceId:e.serviceInstanceId,sequence:a,operations:i});if(m.kind!=="transaction"||m.transaction.acceptedOperations<a+r)throw I(d.execution,"transaction.appendReceiptInvalid","Editor Service returned an invalid append receipt.");a=m.transaction.acceptedOperations,s+=r,e.onAppend(m),i=[],o=2};for await(let r of Fe(e.source,E.signal,n)){l+=1;let m=r.endsWith("\r")?r.slice(0,-1):r;if(!m.trim())continue;let w;try{w=JSON.parse(m)}catch(v){throw c(`NDJSON line ${l} is not valid JSON: ${v instanceof Error?v.message:String(v)}`)}xe(w,l);let p=JSON.stringify(w),h=Buffer.byteLength(p);if(h+2>n)throw c(`NDJSON line ${l} exceeds the ${n}-byte transaction append limit.`);let f=o+h+(i.length?1:0);i.length&&(i.length>=t||f>n)&&await u(),i.push(w),o+=h+(i.length>1?1:0),(i.length>=t||o>=n)&&await u()}if(await u(),s===0)throw c("Transaction input must contain at least one NDJSON operation.");return{acceptedOperations:s,nextSequence:a}}function xe(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw c(`NDJSON line ${t} must be a transaction operation object.`);if(typeof e.opId!="string"||!e.opId.trim())throw c(`NDJSON line ${t} requires a non-empty opId.`);if(typeof e.commandId!="string"||!e.commandId.trim())throw c(`NDJSON line ${t} requires a non-empty commandId.`);if(e.as!==void 0&&(typeof e.as!="string"||!e.as.trim()))throw c(`NDJSON line ${t} as must be a non-empty string.`)}async function ie(e,t){let n=await e.request({kind:"commands.describe",commandId:t.commandId}),i=n.kind==="command"?n.command:null;if(!i)throw I(d.unavailable,"command.unknown",`Editor command is not registered: ${t.commandId}`);if(!i.availability.available)throw I(d.unavailable,"command.unavailable",i.availability.reasons.map(s=>s.message).join("; ")||`Editor command is unavailable: ${t.commandId}`);let o=await e.request({kind:"command.invoke",invocation:{commandId:t.commandId,input:t.input,requestId:k(),idempotencyKey:k(),expectedRevision:{serviceInstanceId:t.serviceInstanceId,...t.expectedDocumentRevision===void 0?{}:{document:t.expectedDocumentRevision}},principal:{type:"agent",id:"fps-editor-agent"},source:"agent-cli",transactionId:t.transactionId,...t.traceId?{traceId:t.traceId}:{}},...t.timeoutMs===void 0?{}:{timeoutMs:t.timeoutMs}}),a=o.operation;return a&&!ge(a.status)&&(a=(await e.request({kind:"operation.get",operationId:a.operationId})).operation??a),{response:o,operation:a}}function $(e,t){S({ok:t.state!=="failed",kind:"apply.event",phase:e,state:t.state,transaction:x(t)})}function oe(e,t,n){S({ok:n?.status!=="failed"&&n?.status!=="cancelled",kind:"apply.event",phase:e,state:n?.status??"unavailable",transaction:x(t),operation:_(n)})}function b(e,t,n,i={}){S({ok:e,kind:"apply.result",state:t,phase:t==="saved"?"complete":n.phase,transaction:x(n),...i.allowedActions?{}:{allowedActions:n.allowedActions},...i.retry?{}:{retry:n.retry},...i})}function x(e){return{transactionId:e.transactionId,serviceInstanceId:e.serviceInstanceId,state:e.state,phase:e.phase,baseDocumentRevision:e.baseDocumentRevision,...e.workingDocumentRevision===void 0?{}:{workingDocumentRevision:e.workingDocumentRevision},dirty:e.dirty,acceptedOperations:e.acceptedOperations,acceptedBytes:e.acceptedBytes,processedOperations:e.processedOperations,allowedActions:e.allowedActions,retry:e.retry,diagnostics:e.diagnostics,results:{offset:e.results.offset,returned:e.results.returned,total:e.results.total,...e.results.nextCursor?{nextCursor:e.results.nextCursor}:{}}}}function _(e){return e?{operationId:e.operationId,requestId:e.requestId,commandId:e.commandId,status:e.status,...e.transactionId?{transactionId:e.transactionId}:{},...e.traceId?{traceId:e.traceId}:{},...e.output===void 0?{}:{output:e.output},...e.diagnostics?{diagnostics:e.diagnostics}:{}}:null}function ke(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function re(e,t){return Number.isSafeInteger(e)&&e>0?e:t}async function Ce(e,t){let n=t.shift();if(n==="get"){let i=A(t,new Set(["--request-id","--service-instance-id"])),o=i.positionals.shift();if(i.positionals.length)throw c("operation get accepts at most one operation id.");let a=g(i.options,"--request-id");if(!o&&!a||o&&a)throw c("operation get requires exactly one operation id or --request-id.");let s=g(i.options,"--service-instance-id");if(s&&s!==e.serviceInstanceId)throw I(d.conflict,"operation.serviceInstanceChanged",`Expected Editor Service ${s}, received ${e.serviceInstanceId}.`);let l=await e.request(o?{kind:"operation.get",operationId:o}:{kind:"operation.get",requestId:a});S(l),l.operation?B(l.operation):process.exitCode=d.unavailable;return}if(n==="cancel"){let i=j(t,"operation id");Ie(t);let o=await e.request({kind:"operation.cancel",operationId:i});S(o),o.operation?!o.cancelled&&!ge(o.operation.status)&&(process.exitCode=d.running):process.exitCode=d.unavailable;return}throw c("operation requires get or cancel.")}async function De(e,t){if(t.shift()!=="get")throw c("trace requires get.");let i=A(t,new Set(["--cursor","--limit"])),o=i.positionals.shift();if(i.positionals.length)throw c("trace get accepts at most one trace id.");S(await e.request({kind:"trace.get",...o?{traceId:o}:{},...g(i.options,"--cursor")?{cursor:g(i.options,"--cursor")}:{},...O(i.options,"--limit",{minimum:1})?{limit:O(i.options,"--limit",{minimum:1})}:{}}))}async function se(e,t={}){let n=await le(e,{validateService:!0,...t}),i=me(process.env.FPS_EDITOR_AGENT_ENDPOINT?.trim()||n.descriptor.endpoint),o=process.env.FPS_EDITOR_AGENT_TOKEN?.trim()||n.descriptor.token,a=async r=>{if(q)throw I(d.interrupted,"cli.interrupted","Interrupted.");let m=U-Date.now();if(m<=0)throw D(n,r);let w=new AbortController,p=()=>w.abort(E.signal.reason);E.signal.addEventListener("abort",p,{once:!0});let h=setTimeout(()=>w.abort(C),m);h.unref?.();try{let f=await fetch(i,{method:"POST",headers:{authorization:`Bearer ${o}`,"content-type":"application/json"},body:JSON.stringify(r),signal:w.signal}),v=await X(f),y;try{y=JSON.parse(v)}catch{throw I(d.discovery,"protocol.invalidJson","Editor Service returned invalid JSON.")}if(f.status===401||f.status===403)throw I(d.discovery,"auth.invalidToken",he(y)||"Editor Service authentication failed.");if(!y?.ok)throw Y(y);return y}catch(f){throw q||E.signal.aborted?L():w.signal.reason===C?D(n,r):f&&Number.isInteger(f.exitCode)?f:I(d.discovery,"service.unreachable",`Editor Service is unreachable: ${f instanceof Error?f.message:String(f)}`)}finally{clearTimeout(h),E.signal.removeEventListener("abort",p)}},s=await a({kind:"status"});Me(n,s);let l=async r=>{let m=await Pe(r),w=new URL(F,i),p=new AbortController,h=U-Date.now();if(h<=0)throw D(n,{kind:"asset.sourceGrant"});let f=()=>p.abort(E.signal.reason);E.signal.addEventListener("abort",f,{once:!0});let v=setTimeout(()=>p.abort(C),h);v.unref?.();try{let y=await fetch(w,{method:"POST",headers:{authorization:`Bearer ${o}`,"content-type":"application/vnd.fps-editor.asset-source-bundle-v1"},body:Ee.from(je(m)),duplex:"half",signal:p.signal}),N=await X(y),R;try{R=JSON.parse(N)}catch{throw I(d.discovery,"protocol.invalidJson","Editor Service returned invalid JSON for asset source upload.")}if(!y.ok||!R?.ok||R.kind!=="asset.sourceGrant"||!R.grant?.sourceGrantId)throw Y(R);return R.grant}catch(y){throw q||E.signal.aborted?L():p.signal.reason===C?D(n,{kind:"asset.sourceGrant"}):y&&Number.isInteger(y.exitCode)?y:I(d.discovery,"asset.sourceUploadFailed",`Asset source upload failed: ${y instanceof Error?y.message:String(y)}`)}finally{clearTimeout(v),E.signal.removeEventListener("abort",f)}},u=async r=>{let m=U-Date.now();if(m<=0)throw D(n,{kind:"asset.sourceGrant.revoke"});let w=new AbortController,p=setTimeout(()=>w.abort(C),m);p.unref?.();try{let h=new URL(F,i);h.searchParams.set("sourceGrantId",r);let f=await fetch(h,{method:"DELETE",headers:{authorization:`Bearer ${o}`},signal:w.signal}),v=await X(f),y;try{y=JSON.parse(v)}catch{throw I(d.discovery,"protocol.invalidJson","Editor Service returned invalid JSON for asset source revocation.")}if(!f.ok||!y?.ok)throw Y(y);return y}finally{clearTimeout(p)}};return Object.freeze({discovery:n,serviceInstanceId:n.descriptor.serviceInstanceId,status:s.status,request:a,uploadAssetSource:l,revokeAssetSource:u})}async function Pe(e){let t;try{t=await H(e)}catch(u){throw I(d.usage,"asset.sourceNotFound",`Asset source is unavailable: ${u instanceof Error?u.message:String(u)}`)}let n=await M(t);if(!n.isFile())throw c("Asset source must be a regular file.");let i=T.extname(t).toLowerCase();if(![".glb",".gltf",".png",".jpg",".jpeg",".env"].includes(i))throw c("Asset source must be GLB, glTF, PNG, JPG, JPEG, or Babylon ENV.");let o=T.dirname(t),a=new Map([[T.basename(t),t]]);if(i===".gltf"){if(n.size>16*1024*1024)throw c("glTF JSON source exceeds the 16 MiB manifest limit.");let u;try{u=JSON.parse(await J(t,"utf8"))}catch(m){throw c(`glTF source is not valid JSON: ${m instanceof Error?m.message:String(m)}`)}let r=[...Array.isArray(u?.buffers)?u.buffers:[],...Array.isArray(u?.images)?u.images:[]];for(let m of r){let w=typeof m?.uri=="string"?m.uri:null;if(!w||w.startsWith("data:"))continue;if(/^[a-z][a-z0-9+.-]*:/i.test(w)||w.startsWith("//"))throw c("glTF dependencies must use local relative URIs.");let p;try{p=decodeURIComponent(w.split(/[?#]/,1)[0])}catch{throw c(`glTF dependency URI is malformed: ${w}`)}let h=T.posix.normalize(p.replaceAll("\\","/"));if(!h||h==="."||h===".."||h.startsWith("../")||T.posix.isAbsolute(h))throw c(`glTF dependency escapes the source directory: ${w}`);let f;try{f=await H(T.resolve(o,...h.split("/")))}catch{throw c(`glTF dependency is missing: ${h}`)}if(Le(o,f,h),!(await M(f)).isFile())throw c(`glTF dependency is not a regular file: ${h}`);a.set(h,f)}}let s=[];for(let[u,r]of a){let m=await M(r);if(m.size<1||m.size>256*1024*1024)throw c(`Asset source file size is outside the supported range: ${u}`);s.push({path:u,filePath:r,byteSize:m.size,contentHash:await qe(r)})}let l=s.reduce((u,r)=>u+r.byteSize,0);if(s.length>128||l>512*1024*1024)throw c("Asset source bundle exceeds the supported file-count or total-size limit.");return{primaryPath:T.basename(t),files:s}}async function qe(e){let t=Se("sha256");for await(let n of K(e))t.update(n);return`sha256:${t.digest("hex")}`}async function*je(e){let t=Buffer.from(JSON.stringify({schemaVersion:1,primaryPath:e.primaryPath,files:e.files.map(({path:i,byteSize:o,contentHash:a})=>({path:i,byteSize:o,contentHash:a}))}),"utf8"),n=Buffer.allocUnsafe(4);n.writeUInt32BE(t.length,0),yield n,yield t;for(let i of e.files)for await(let o of K(i.filePath))yield o}function Le(e,t,n){let i=T.relative(e,t);if(!i||i===".."||i.startsWith(`..${T.sep}`)||T.isAbsolute(i))throw c(`glTF dependency escapes the source directory: ${n}`)}async function le(e,t={}){let n;try{n=await H(T.resolve(e))}catch(i){throw I(d.discovery,"projectRoot.invalid",`Project root is unavailable: ${i instanceof Error?i.message:String(i)}`)}for(;;){let i=T.join(n,ne);if(await Ge(i)){let a=await $e(i),s=await H(n);if(a.canonicalProjectRoot!==s)throw I(d.discovery,"descriptor.projectMismatch",`Runtime descriptor does not own ${s}.`);let l={descriptorPath:i,projectRoot:s,descriptor:a};return t.validateService!==!1&&await fe(l),l}if(t.exactProjectRoot===!0)break;let o=T.dirname(n);if(o===n)break;n=o}throw I(d.discovery,"descriptor.notFound",`No ${ne} was found from ${e}.`)}async function $e(e){let t;try{t=JSON.parse(await J(e,"utf8"))}catch(n){throw I(d.discovery,"descriptor.invalid",`Runtime descriptor is unreadable: ${n instanceof Error?n.message:String(n)}`)}if(t?.schemaVersion!==1||t?.protocolVersion!==2||t?.packageName!=="@fps-games/editor"||typeof t?.serviceInstanceId!="string"||typeof t?.canonicalProjectRoot!="string"||typeof t?.endpoint!="string"||typeof t?.token!="string"||!Number.isSafeInteger(t?.pid))throw I(d.discovery,"descriptor.incompatible","Runtime descriptor schema or protocol is incompatible.");if(me(t.endpoint),process.platform!=="win32"){let n=(await M(e)).mode&511;if(n&63)throw I(d.discovery,"descriptor.permissions",`Runtime descriptor permissions must be 0600; received ${n.toString(8)}.`)}return t}function me(e){let t;try{t=new URL(e)}catch{throw I(d.discovery,"descriptor.endpoint","Runtime descriptor endpoint is invalid.")}if(t.protocol!=="http:"||!["127.0.0.1","localhost","[::1]"].includes(t.hostname))throw I(d.discovery,"descriptor.endpoint","Runtime descriptor endpoint must be project-local loopback HTTP.");return t.toString()}async function fe(e){let t=[];t.push({id:"descriptor.schema",ok:e.descriptor.schemaVersion===1}),t.push({id:"descriptor.protocol",ok:e.descriptor.protocolVersion===2}),t.push({id:"descriptor.project",ok:e.descriptor.canonicalProjectRoot===e.projectRoot});let n=Be(e.descriptor.pid);if(t.push({id:"descriptor.process",ok:n,pid:e.descriptor.pid}),!n)throw I(d.discovery,"descriptor.stale",`Editor Service process is not alive: ${e.descriptor.pid}.`);return t}function Me(e,t){let n=t?.kind==="status"?t.status:null;if(!n||n.protocolVersion!==2)throw I(d.discovery,"protocol.incompatible","Editor Service status protocol is incompatible.");if(n.serviceInstanceId!==e.descriptor.serviceInstanceId||n.canonicalProjectRoot!==e.projectRoot||n.packageVersion!==e.descriptor.packageVersion||n.buildKey!==e.descriptor.buildKey)throw I(d.discovery,"service.identityMismatch","Editor Service identity does not match the project runtime descriptor.")}async function Ue(e){if(["--stdin","--input-file","--input-json"].filter(o=>e.has(o)).length>1)throw c("Use only one of --stdin, --input-file, or --input-json.");if(e.has("--stdin"))return V(await Je(process.stdin,E.signal),"--stdin");let n=g(e,"--input-file");if(n)return V(await J(T.resolve(n),"utf8"),"--input-file");let i=g(e,"--input-json");return i===void 0?{}:V(i,"--input-json")}function V(e,t){try{return JSON.parse(e)}catch(n){throw c(`${t} is not valid JSON: ${n instanceof Error?n.message:String(n)}`)}}function A(e,t,n=new Set){let i=new Map,o=[];for(;e.length;){let a=e.shift();if(!a.startsWith("--")){o.push(a);continue}let[s,l]=a.split("=",2);if(!t.has(s))throw c(`Unknown option: ${s}`);if(i.has(s))throw c(`Option may only be provided once: ${s}`);if(n.has(s)){if(l!==void 0)throw c(`${s} does not accept a value.`);i.set(s,!0);continue}let u=l??e.shift();if(u===void 0||u.startsWith("--"))throw c(`${s} requires a value.`);i.set(s,u)}return{options:i,positionals:o}}function g(e,t){let n=e.get(t);if(n!==void 0){if(typeof n!="string"||!n.trim())throw c(`${t} requires a non-empty value.`);return n.trim()}}function He(e){let t=[],n=Q,i=!1,o;for(let a=0;a<e.length;a+=1){let s=e[a];if(s==="--project-root"||s.startsWith("--project-root=")){if(o!==void 0)throw c("--project-root may only be provided once.");let r=s==="--project-root"?e[++a]:s.slice(15);if(r===void 0||!r.trim()||r.startsWith("--"))throw c("--project-root requires a non-empty path.");o=T.resolve(process.cwd(),r);continue}if(s!=="--deadline"&&!s.startsWith("--deadline=")){t.push(s);continue}if(i)throw c("--deadline may only be provided once.");i=!0;let l=s==="--deadline"?e[++a]:s.slice(11);if(l===void 0||l.startsWith("--"))throw c("--deadline requires a value.");let u=Number(l);if(!Number.isSafeInteger(u)||u<1)throw c("--deadline must be an integer >= 1.");n=u}return{argv:t,deadlineMs:n,projectRoot:o}}function O(e,t,{minimum:n}){let i=g(e,t);if(i===void 0)return;let o=Number(i);if(!Number.isSafeInteger(o)||o<n)throw c(`${t} must be an integer >= ${n}.`);return o}function j(e,t){let n=e.shift();if(!n)throw c(`Missing ${t}.`);return n}function Ie(e){if(e.length)throw c(`Unexpected argument: ${e[0]}`)}function z(e,t){for(let n of e.keys())if(!t.has(n))throw c(`Option is not valid for this action: ${n}`)}function B(e){if(!e){process.exitCode=d.unavailable;return}if(e.status==="accepted"||e.status==="running"){process.exitCode=d.running;return}(e.status==="failed"||e.status==="cancelled")&&(process.exitCode=Z(e.diagnostics))}function P(e,t={}){if(!e){process.exitCode=d.unavailable;return}if(e.state==="preflighting"||e.state==="committing"){process.exitCode=d.running;return}if(e.state==="failed"){process.exitCode=Z(e.diagnostics);return}e.state==="aborted"&&t.abortedIsSuccess!==!0&&(process.exitCode=d.execution)}function Z(e=[]){let t=e.map(n=>n?.code??"");return t.some(n=>/revision|idempotency|conflict|serviceInstance/i.test(n))?d.conflict:t.some(n=>/unknown|unavailable|notFound|sessionUnavailable/i.test(n))?d.unavailable:d.execution}function Y(e){let t=Array.isArray(e?.diagnostics)?e.diagnostics:[];return I(Z(t),t[0]?.code??"service.requestFailed",he(e)||"Editor Service request failed.")}function he(e){return Array.isArray(e?.diagnostics)?e.diagnostics.map(t=>t?.message).filter(Boolean).join("; "):""}function Be(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}function ge(e){return e==="completed"||e==="failed"||e==="cancelled"}async function X(e){let t=Number(e.headers.get("content-length"));if(Number.isFinite(t)&&t>W)throw I(d.execution,"response.tooLarge","Editor Service response exceeds 1 MiB.");let n=await e.text();if(Buffer.byteLength(n)>W)throw I(d.execution,"response.tooLarge","Editor Service response exceeds 1 MiB.");return n}async function Ge(e){try{return await Te(e,Re.R_OK),!0}catch{return!1}}async function Je(e,t){let n=[];for await(let i of ye(e,t))n.push(Buffer.isBuffer(i)?i:Buffer.from(i));return Buffer.concat(n).toString("utf8")}async function*Fe(e,t,n=Number.POSITIVE_INFINITY){let i="";for await(let o of ye(e,t)){i+=o.toString();let a;for(;(a=i.indexOf(`
4
4
  `))>=0;){let s=i.slice(0,a);if(Buffer.byteLength(s)>n)throw c(`NDJSON line exceeds the ${n}-byte transaction append limit.`);yield s,i=i.slice(a+1)}if(Buffer.byteLength(i)>n)throw c(`NDJSON line exceeds the ${n}-byte transaction append limit.`)}i&&(yield i)}async function*ye(e,t){let n=e[Symbol.asyncIterator]();for(;;){let i=await Ve(n,t);if(i.done)return;yield i.value}}function Ve(e,t){return t.aborted?Promise.reject(L()):new Promise((n,i)=>{let o=()=>i(L());t.addEventListener("abort",o,{once:!0}),e.next().then(n,i).finally(()=>t.removeEventListener("abort",o))})}function S(e){let t=JSON.stringify(e);if(Buffer.byteLength(t)>W)throw I(d.execution,"output.tooLarge","CLI output exceeds 1 MiB.");process.stdout.write(`${t}
5
- `)}function ze(){return{globalOptions:{deadline:`End-to-end CLI deadline in milliseconds (default ${Q}).`,projectRoot:"Exact target project root. Required for deployment-owned usage from outside the project."},commands:["status","commands list [--cursor CURSOR] [--limit N]","commands search QUERY [--cursor CURSOR] [--limit N]","commands describe COMMAND_ID","command COMMAND_ID [--stdin|--input-file FILE|--input-json JSON] [--source-file FILE for asset.import] [--expected-revision N] [--idempotency-key KEY] [--request-id ID] [--trace-id ID] [--client-id ID] [--timeout MS]","apply [--stdin|--input-file FILE] [--save] [--expected-revision N] [--transaction-id ID] [--label TEXT] [--trace-id ID] [--timeout MS]","transaction begin [--expected-revision N] [--transaction-id ID] [--label TEXT] [--trace-id ID]","transaction append TRANSACTION_ID [--stdin|--input-file FILE] [--sequence N] [--service-instance-id ID]","transaction preflight TRANSACTION_ID [--service-instance-id ID]","transaction commit TRANSACTION_ID [--service-instance-id ID]","transaction get TRANSACTION_ID [--service-instance-id ID] [--cursor CURSOR] [--limit N]","transaction abort TRANSACTION_ID [--service-instance-id ID]","operation get OPERATION_ID [--service-instance-id ID]","operation get --request-id REQUEST_ID [--service-instance-id ID]","operation cancel OPERATION_ID","trace get [TRACE_ID] [--cursor CURSOR] [--limit N]","doctor"],exitCodes:d}}function c(e){return I(d.usage,"cli.usage",e)}function I(e,t,n,i=!0,o){return Object.assign(new Error(n),{exitCode:e,code:t,log:i,...o?{result:o}:{}})}function C(e,t){let n=t?.kind==="command.invoke"?t.invocation:null,i=t?.kind?.startsWith("transaction.")?t.transactionId:n?.transactionId,o=!!n||typeof t?.kind=="string"&&/^transaction\.(begin|append|preflight|commit|abort)$/.test(t.kind),a=n?.requestId,s=a?`operation get --request-id ${a} --service-instance-id ${e.descriptor.serviceInstanceId}`:null,l=i?`transaction get ${i} --service-instance-id ${e.descriptor.serviceInstanceId}`:null,u=[s,l].filter(Boolean);u.length||u.push("status");let r=`Agent CLI exceeded its ${ce}ms end-to-end deadline.`;return I(d.running,"cli.deadlineExceeded",r,!0,{ok:!1,kind:"cli.deadline",state:o?"outcome_unknown":"timed_out",serviceInstanceId:e.descriptor.serviceInstanceId,...n?.commandId?{commandId:n.commandId}:{},...a?{requestId:a}:{},...i?{transactionId:i}:{},error:{code:"cli.deadlineExceeded",message:r},allowedActions:u,retry:{retryable:!o,requiresOperationQuery:o}})}function L(){return I(d.interrupted,"cli.interrupted","Interrupted.")}function we(e){return e&&Number.isInteger(e.exitCode)&&typeof e.code=="string"?e:I(d.execution,"cli.failure",e instanceof Error?e.message:String(e))}
5
+ `)}function ze(){return{globalOptions:{deadline:`End-to-end CLI deadline in milliseconds (default ${Q}).`,projectRoot:"Exact target project root. Required for deployment-owned usage from outside the project."},commands:["status","commands list [--cursor CURSOR] [--limit N]","commands search QUERY [--cursor CURSOR] [--limit N]","commands describe COMMAND_ID","command COMMAND_ID [--stdin|--input-file FILE|--input-json JSON] [--source-file FILE for asset.import] [--expected-revision N] [--idempotency-key KEY] [--request-id ID] [--trace-id ID] [--client-id ID] [--timeout MS]","apply [--stdin|--input-file FILE] [--save] [--expected-revision N] [--transaction-id ID] [--label TEXT] [--trace-id ID] [--timeout MS]","transaction begin [--expected-revision N] [--transaction-id ID] [--label TEXT] [--trace-id ID]","transaction append TRANSACTION_ID [--stdin|--input-file FILE] [--sequence N] [--service-instance-id ID]","transaction preflight TRANSACTION_ID [--service-instance-id ID]","transaction commit TRANSACTION_ID [--service-instance-id ID]","transaction get TRANSACTION_ID [--service-instance-id ID] [--cursor CURSOR] [--limit N]","transaction abort TRANSACTION_ID [--service-instance-id ID]","operation get OPERATION_ID [--service-instance-id ID]","operation get --request-id REQUEST_ID [--service-instance-id ID]","operation cancel OPERATION_ID","trace get [TRACE_ID] [--cursor CURSOR] [--limit N]","doctor"],exitCodes:d}}function c(e){return I(d.usage,"cli.usage",e)}function I(e,t,n,i=!0,o){return Object.assign(new Error(n),{exitCode:e,code:t,log:i,...o?{result:o}:{}})}function D(e,t){let n=t?.kind==="command.invoke"?t.invocation:null,i=t?.kind?.startsWith("transaction.")?t.transactionId:n?.transactionId,o=!!n||typeof t?.kind=="string"&&/^transaction\.(begin|append|preflight|commit|abort)$/.test(t.kind),a=n?.requestId,s=a?`operation get --request-id ${a} --service-instance-id ${e.descriptor.serviceInstanceId}`:null,l=i?`transaction get ${i} --service-instance-id ${e.descriptor.serviceInstanceId}`:null,u=[s,l].filter(Boolean);u.length||u.push("status");let r=`Agent CLI exceeded its ${ce}ms end-to-end deadline.`;return I(d.running,"cli.deadlineExceeded",r,!0,{ok:!1,kind:"cli.deadline",state:o?"outcome_unknown":"timed_out",serviceInstanceId:e.descriptor.serviceInstanceId,...n?.commandId?{commandId:n.commandId}:{},...a?{requestId:a}:{},...i?{transactionId:i}:{},error:{code:"cli.deadlineExceeded",message:r},allowedActions:u,retry:{retryable:!o,requiresOperationQuery:o}})}function L(){return I(d.interrupted,"cli.interrupted","Interrupted.")}function we(e){return e&&Number.isInteger(e.exitCode)&&typeof e.code=="string"?e:I(d.execution,"cli.failure",e instanceof Error?e.message:String(e))}
@@ -1,6 +1,6 @@
1
1
  FPS Game Editor deployment npm package
2
- Version: 0.2.3-beta.8
3
- Commit: 94761bfe7e4a4c0c3cff4c8c44cc1b86e1ccb6a7
2
+ Version: 0.2.3-beta.9
3
+ Commit: 7a57b64dd3963c9e558c773b03bae9c8270827a3
4
4
 
5
5
  This package contains compiled third-party dependencies declared by the source repository.
6
6
  The authoritative dependency names, versions, notices, and license metadata are recorded in
package/manifest.json CHANGED
@@ -2,17 +2,17 @@
2
2
  "schemaVersion": 2,
3
3
  "artifactKind": "fps-editor-deployment-package",
4
4
  "packageName": "@fps-games/editor-deployment",
5
- "version": "0.2.3-beta.8",
6
- "commitSha": "94761bfe7e4a4c0c3cff4c8c44cc1b86e1ccb6a7",
5
+ "version": "0.2.3-beta.9",
6
+ "commitSha": "7a57b64dd3963c9e558c773b03bae9c8270827a3",
7
7
  "node": {
8
8
  "range": ">=24 <27",
9
9
  "bundled": false
10
10
  },
11
11
  "build": {
12
12
  "packageName": "@fps-games/editor",
13
- "version": "0.2.3-beta.8",
14
- "buildId": "0.2.3-beta.8-38e799499926",
15
- "distHash": "38e79949992676f61dafa1e176afdacfc07f174f221d3fc74c954e3529e04a82"
13
+ "version": "0.2.3-beta.9",
14
+ "buildId": "0.2.3-beta.9-a5563f8d585d",
15
+ "distHash": "a5563f8d585d08daca09a8a4a7e5caaf9c8d0dbc4349ef35348ba3720f2641d5"
16
16
  },
17
17
  "binaries": {
18
18
  "prepare": "bin/fps-editor-prepare.mjs",
@@ -30,8 +30,8 @@
30
30
  "files": [
31
31
  {
32
32
  "path": "bin/fps-editor-agent.mjs",
33
- "size": 33172,
34
- "sha256": "d4973c920b437ee09a4687aefbbf1cf84400a84fd630c66927dc56cdb12dd395"
33
+ "size": 33187,
34
+ "sha256": "5dd5641f16928b74849b415075b46da21c86db2221ecc0b0e4e538b7b18232dd"
35
35
  },
36
36
  {
37
37
  "path": "bin/fps-editor-prepare.mjs",
@@ -51,7 +51,7 @@
51
51
  {
52
52
  "path": "licenses/THIRD_PARTY_NOTICES.txt",
53
53
  "size": 360,
54
- "sha256": "a18067b648e9a9616f853a9e8ad8f9771a735c121378e774516bb6347a9cc073"
54
+ "sha256": "9ccb08bb12d5cddede253fe14bf7727d36b9d6dfffe14dfcd9da64b3e98484ac"
55
55
  },
56
56
  {
57
57
  "path": "public/assets/abstractAudioBus-BRAC2GY2.js",
@@ -1633,6 +1633,21 @@
1633
1633
  "size": 1247,
1634
1634
  "sha256": "ef43cc998fb44480b8e97a07ecd0e61e18dfaf55282f8466e0492790a5fefbf9"
1635
1635
  },
1636
+ {
1637
+ "path": "public/assets/index-CdqIKk65.js",
1638
+ "size": 51097,
1639
+ "sha256": "bdab011303388ae32b1dd97c5c817dd390796640cb5adba89b0e063e9a8d6310"
1640
+ },
1641
+ {
1642
+ "path": "public/assets/index-CdqIKk65.js.br",
1643
+ "size": 13816,
1644
+ "sha256": "47512d82fb555f9fd1809cf74b7e7b0489a2e1c567bd08af2e0141b0d44d8151"
1645
+ },
1646
+ {
1647
+ "path": "public/assets/index-CdqIKk65.js.gz",
1648
+ "size": 15569,
1649
+ "sha256": "f7c21fc2a72d5daef6cb6590c57cd88fb33048fb612caa2c4c1d5f0e87fd1e67"
1650
+ },
1636
1651
  {
1637
1652
  "path": "public/assets/index-CiIoJ8v1.js",
1638
1653
  "size": 251212,
@@ -1648,21 +1663,6 @@
1648
1663
  "size": 55953,
1649
1664
  "sha256": "1cfd56c207e0fb0975535590403278aeccef29acdc9092a14c7c59f7d63fde42"
1650
1665
  },
1651
- {
1652
- "path": "public/assets/index-DsjoVi0a.js",
1653
- "size": 51097,
1654
- "sha256": "b7a386da5f36464f1e4496f2056af5267576eb315b7f326b96869b30e851ceeb"
1655
- },
1656
- {
1657
- "path": "public/assets/index-DsjoVi0a.js.br",
1658
- "size": 13807,
1659
- "sha256": "388fcbf8b75ad4c87768e347627552b16e79bf11bbb41e1b1adcb9c45fd5bfa4"
1660
- },
1661
- {
1662
- "path": "public/assets/index-DsjoVi0a.js.gz",
1663
- "size": 15567,
1664
- "sha256": "f1b36766beaa7cc3036f17742b5940b78d528b9645d43c66b0b92002b8e687ee"
1665
- },
1666
1666
  {
1667
1667
  "path": "public/assets/instancesDeclaration-B2a0VuuR.js",
1668
1668
  "size": 1008,
@@ -2124,34 +2124,34 @@
2124
2124
  "sha256": "038c7bf00dc9bbfc77dff114c278333817b36c81bf1b1a1e30cddf8aa9f22fcd"
2125
2125
  },
2126
2126
  {
2127
- "path": "public/assets/playable-sdk-BhG9wmjo.js",
2128
- "size": 189141,
2129
- "sha256": "72dec0e2f36f936282036691f182776d053442b94ea6ddcff3377a4e553d2f48"
2127
+ "path": "public/assets/playable-sdk-zyPm5JCa.js",
2128
+ "size": 191453,
2129
+ "sha256": "3b13aa270efb704cfdf79048f61090034bfdcb871925fc7af6a77da72acc069a"
2130
2130
  },
2131
2131
  {
2132
- "path": "public/assets/playable-sdk-BhG9wmjo.js.br",
2133
- "size": 44492,
2134
- "sha256": "9ac31056db42a1624818aab231f431b0bb75db76a28cfd6b55206374693a39d8"
2132
+ "path": "public/assets/playable-sdk-zyPm5JCa.js.br",
2133
+ "size": 44454,
2134
+ "sha256": "8b5a91ca8318b3ba2b2f529753bd67ff21165fb968e634f6f4b9207451a2325a"
2135
2135
  },
2136
2136
  {
2137
- "path": "public/assets/playable-sdk-BhG9wmjo.js.gz",
2138
- "size": 53355,
2139
- "sha256": "c708a13bcc796677159f49ff68a273f26ffb75ac27e1a0b5b6ece3db7f0872b5"
2137
+ "path": "public/assets/playable-sdk-zyPm5JCa.js.gz",
2138
+ "size": 53182,
2139
+ "sha256": "000548e36e5429b7c9ce51ed4c3fd1c33ea5e635fb77ed32cb7bdeb8bed52070"
2140
2140
  },
2141
2141
  {
2142
- "path": "public/assets/playable-standard-project-BMleU1jU.js",
2143
- "size": 3202688,
2144
- "sha256": "b0a8c609bc607d0f10e16116a11b75aaad1835a6d75a4940f545f38f8d343cf7"
2142
+ "path": "public/assets/playable-standard-project-BA5pc2TZ.js",
2143
+ "size": 3356970,
2144
+ "sha256": "844a567411afd363481cb9baf4fd1505514e69ecc88767839f7bab12f7051026"
2145
2145
  },
2146
2146
  {
2147
- "path": "public/assets/playable-standard-project-BMleU1jU.js.br",
2148
- "size": 679077,
2149
- "sha256": "6072fdaba074c1e01b19e6dea2ebaf3e3197ba955eab7dc76b70024a06701113"
2147
+ "path": "public/assets/playable-standard-project-BA5pc2TZ.js.br",
2148
+ "size": 705381,
2149
+ "sha256": "94a16651ad20776b75a013ba223d6c19a0e7fa1a7bafc5afc6c5a742a06782da"
2150
2150
  },
2151
2151
  {
2152
- "path": "public/assets/playable-standard-project-BMleU1jU.js.gz",
2153
- "size": 868521,
2154
- "sha256": "b7a07c7ea59af38981b111cee59a05005b8506c3d85aaf1622c5351b84d01f52"
2152
+ "path": "public/assets/playable-standard-project-BA5pc2TZ.js.gz",
2153
+ "size": 904719,
2154
+ "sha256": "2a4c77bf48a2af4da4237e9811dbbd3f9e2bbeb4c071e4805a0869ece8142eb8"
2155
2155
  },
2156
2156
  {
2157
2157
  "path": "public/assets/rgbdDecode.fragment-BQ16CsAv.js",
@@ -2651,38 +2651,38 @@
2651
2651
  {
2652
2652
  "path": "public/index.html",
2653
2653
  "size": 1065,
2654
- "sha256": "fa66990b0d50e2ffe8d8db4dd6f7704f8ed514dbebf2beafed0a424e32c7b0ee"
2654
+ "sha256": "0c94fe5fb8977f92438436556ec3308e8f437b4abd71cc6f2bb57a10673bc510"
2655
2655
  },
2656
2656
  {
2657
2657
  "path": "public/index.html.br",
2658
- "size": 401,
2659
- "sha256": "903505f63c2b4cec32b85ed9743407e5e98eec306349878881dbb7b2626bc3fb"
2658
+ "size": 402,
2659
+ "sha256": "783e0c6720a5a96e394445d2679e6a375f2bb09e8a3224c74a1ac13d0cf323ed"
2660
2660
  },
2661
2661
  {
2662
2662
  "path": "public/index.html.gz",
2663
- "size": 565,
2664
- "sha256": "5771b84232be8f1579bdad44a3b55edde2a9a07596f35c00d5bcb80298433a93"
2663
+ "size": 570,
2664
+ "sha256": "1860da33ada4b95f63d5b0bb148c1877ff0329ab033e49a2a1fade11c79b0b73"
2665
2665
  },
2666
2666
  {
2667
2667
  "path": "runtime/editor-control-plane.mjs",
2668
- "size": 18038,
2669
- "sha256": "c806959f075bdf6fd88ee038204d34a2ea1f3dc83724b42903601f8269179a71"
2668
+ "size": 18275,
2669
+ "sha256": "4c096d42e954bb0428640b5ac14fe426ae829b3cd81e7c766f53f7e0a42474b6"
2670
2670
  },
2671
2671
  {
2672
2672
  "path": "runtime/runtime-debug-authoring-bridge.mjs",
2673
- "size": 3228,
2674
- "sha256": "b07d53f68901cc9b5901d3ab5b83b9f90394cf84ed73d7ee367ecd2cbeb67e82"
2673
+ "size": 3242,
2674
+ "sha256": "689c5dce9f0db86285650fe24238df0872dc29d10b6c415f60dfb75b7b1c5080"
2675
2675
  },
2676
2676
  {
2677
2677
  "path": "worker/editor-service-worker.mjs",
2678
- "size": 1093675,
2679
- "sha256": "d6e1c43820a057f0108c049ed9ceed113f1128529b5f704197e0fc92d148b6b8"
2678
+ "size": 1193187,
2679
+ "sha256": "573b99a31b5804e2bb6e3a83748979ca315654fc7d2219f06aa47b530c46f227"
2680
2680
  }
2681
2681
  ],
2682
2682
  "sizes": {
2683
- "packagePayloadBytes": 16838021,
2684
- "browserRawBytes": 10761177,
2685
- "browserGzipBytes": 2622792,
2686
- "browserBrotliBytes": 2054317
2683
+ "packagePayloadBytes": 17156701,
2684
+ "browserRawBytes": 10917771,
2685
+ "browserGzipBytes": 2658824,
2686
+ "browserBrotliBytes": 2080593
2687
2687
  }
2688
2688
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@fps-games/editor-deployment",
3
- "version": "0.2.3-beta.8",
3
+ "version": "0.2.3-beta.9",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@fps-games/editor-deployment",
9
- "version": "0.2.3-beta.8",
9
+ "version": "0.2.3-beta.9",
10
10
  "bin": {
11
11
  "fps-editor-prepare": "bin/fps-editor-prepare.mjs",
12
12
  "fps-editor-server": "bin/fps-editor-server.mjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fps-games/editor-deployment",
3
- "version": "0.2.3-beta.8",
3
+ "version": "0.2.3-beta.9",
4
4
  "type": "module",
5
5
  "description": "Prebuilt FPS Game Editor control plane, browser client, and project preparation tools.",
6
6
  "repository": {
@@ -31,11 +31,11 @@
31
31
  "node": ">=24 <27"
32
32
  },
33
33
  "devDependencies": {
34
- "@fps-games/editor": "0.2.3-beta.8",
35
- "@fps-games/editor-core": "0.2.3-beta.8",
36
- "@fps-games/editor-protocol": "0.2.3-beta.8",
34
+ "@fps-games/editor": "0.2.3-beta.9",
35
+ "@fps-games/editor-core": "0.2.3-beta.9",
36
+ "@fps-games/editor-protocol": "0.2.3-beta.9",
37
37
  "@fps-games/engine": "0.0.1-beta.19",
38
- "@fps-games/plugin-hierarchy": "0.2.3-beta.8",
38
+ "@fps-games/plugin-hierarchy": "0.2.3-beta.9",
39
39
  "@fps-games/plugin-sdk": "0.1.0-beta.2"
40
40
  },
41
41
  "publishConfig": {