diff --git a/CHANGELOG.md b/CHANGELOG.md index 9801ae4d..d806797c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ Each released version has a section headed with its version, such as `## 3.4.0 - 2026-09-23`. The section holds a summary paragraph and then one bullet per change a user, integrator or operator would notice. The release workflow copies that section onto the GitHub Release page and stops if it is missing, empty or still says Unreleased. Work that has merged but not shipped goes under `## Unreleased`; the version bump pull request renames that heading to the new version. +## 3.6.0 - 2026-09-27 + +The menu bar now shows what Slopcamera is doing instead of only listing outputs: the render or generation in progress, how the last job ended, and your last known credits balance. Its login item moves to the shared desktop-foundation helper, and the agent support verbs move out of root help onto their own page. + +- The menu opens with a status row for the current render or generation and a warning row when the last job failed, a credits row that flags a low balance, the three newest outputs, "Open outputs folder", Open at login, "Updates & support…" and Quit. Diagnostics sit behind the Option alternate and the tray icon shows an attention tone only when something needs you. +- `slopcamera menubar install|uninstall|status|start` manage the menu bar's login item through the shared LaunchAgent helper. Install retires the old `com.hraness.slopcamera.menubar` plist only when it is exactly the file earlier releases wrote, explains the macOS login-item notice before it appears, and refuses a copy another user or program could change. +- `slopcamera menubar` stays off root help while released packages don't include the companion; `slopcamera help menubar` and `docs/menubar-release.md` still document building and installing it from source. +- Root help drops the agent `slopcamera support` verb list for a single optional-support line; the same verbs are documented under `slopcamera help advanced` and keep working. + ## 3.5.0 - 2026-09-26 Browser overlay scenes with post-processing, bloom, depth of field or emissive standard materials render as written, and local vectorization keeps its deadline on loaded machines. The menu bar, the face analyzer build and root help now explain themselves in plain words: an already-running menu bar counts as success, and macOS notices are explained before they appear. diff --git a/apps/desktop/application/operation.ts b/apps/desktop/application/operation.ts index 13e5d40f..4ddf20c1 100644 --- a/apps/desktop/application/operation.ts +++ b/apps/desktop/application/operation.ts @@ -4,7 +4,7 @@ import type { z } from "zod"; import type { ApplicationContext } from "./context"; -export const SLOPCAMERA_APPLICATION_TOOL_VERSION = "slopcamera-3.5.0" as const; +export const SLOPCAMERA_APPLICATION_TOOL_VERSION = "slopcamera-3.6.0" as const; export const OPERATION_KINDS = [ "scene.audit", diff --git a/apps/desktop/application/operations/media/html-overlay.test.ts b/apps/desktop/application/operations/media/html-overlay.test.ts index ea5197bd..0a0b807d 100644 --- a/apps/desktop/application/operations/media/html-overlay.test.ts +++ b/apps/desktop/application/operations/media/html-overlay.test.ts @@ -580,7 +580,7 @@ describe("media.html-overlay application operation", () => { version: 1, }); const output = HtmlOverlayOutputSchema.parse(result.output); - expect(observedGeneratorVersion).toBe("slopcamera-3.5.0"); + expect(observedGeneratorVersion).toBe("slopcamera-3.6.0"); expect(result.receiptReference).toBe(output.receipt.path); const receipt = HtmlOverlayReceiptSchema.parse(JSON.parse( await readFile(join(root, output.receipt.path), "utf8"), diff --git a/apps/desktop/application/registry.test.ts b/apps/desktop/application/registry.test.ts index c9bca09f..c45cea61 100644 --- a/apps/desktop/application/registry.test.ts +++ b/apps/desktop/application/registry.test.ts @@ -86,7 +86,7 @@ describe("operation registry", () => { const descriptions = registry.list().map(operation => ( registry.describe(operation.kind, operation.version) )); - expect(SLOPCAMERA_APPLICATION_TOOL_VERSION).toBe("slopcamera-3.5.0"); + expect(SLOPCAMERA_APPLICATION_TOOL_VERSION).toBe("slopcamera-3.6.0"); expect(registry.list().every(operation => ( operation.inputSchemaId.startsWith("slopcamera.operation.") && operation.outputSchemaId.startsWith("slopcamera.operation.") diff --git a/apps/desktop/cli/commands.ts b/apps/desktop/cli/commands.ts index c6eeb5bc..3365bd7e 100644 --- a/apps/desktop/cli/commands.ts +++ b/apps/desktop/cli/commands.ts @@ -363,7 +363,7 @@ import { workflowRunStore, } from "./workflow-runs"; -export const SLOPCAMERA_VERSION = "3.5.0"; +export const SLOPCAMERA_VERSION = "3.6.0"; // Legacy direct renders predate per-target output contracts. Keep them // bounded generously enough for long-form production while preventing one diff --git a/apps/desktop/dist/cli/main.js b/apps/desktop/dist/cli/main.js index 1782f31b..3a160224 100755 --- a/apps/desktop/dist/cli/main.js +++ b/apps/desktop/dist/cli/main.js @@ -1570,7 +1570,7 @@ ${H}`.trim();return{exitCode:J,output:W}}async function jA($,Q,_){b3(_);let Z=aw for (const url of urls.keys()) nativeRevokeUrl(url); urls.clear(); liveBytes = 0; }, { once: true }]); - }`);return H$0(Q,"return securityViolations;","return securityViolations + (sparkWorkerFailure === null ? 0 : 1);")}var hx=rH.string().regex(/^[a-f0-9]{64}$/u),nx0=rH.strictObject({key:rH.string().min(1).max(512),sha256:hx}),r9=rH.strictObject({algorithm:rH.literal("sha256-merkle-v1"),leaves:rH.array(nx0).min(4).max(256).superRefine(($,Q)=>{for(let _=1;_<$.length;_+=1)if($[_-1].key>=$[_].key)Q.addIssue({code:"custom",message:"HTML-overlay integrity leaves must have unique ASCII-sorted keys.",path:[_,"key"]})}),rootSha256:hx,runtimeSha256:hx,schemaVersion:rH.literal(1)}),d8=Object.freeze({browser:"playwright-chromium",browserVersion:sx0.version,browserContext:Object.freeze({acceptDownloads:!1,colorScheme:"light",locale:"en-US",offline:!0,permissions:Object.freeze([]),reducedMotion:"no-preference",serviceWorkers:"block",timezoneId:"UTC"}),contentSecurityPolicy:Object.freeze(["default-src 'none'","base-uri 'none'","connect-src 'none'","font-src https://slopcamera-overlay.invalid data:","form-action 'none'","frame-src 'none'","img-src https://slopcamera-overlay.invalid data:","media-src https://slopcamera-overlay.invalid data:","object-src 'none'","script-src 'unsafe-inline' https://slopcamera-overlay.invalid","style-src 'unsafe-inline'","worker-src 'none'"]),documentUrl:"https://slopcamera-overlay.invalid/slopcamera-overlay/document",environment:Object.freeze({fixed:Object.freeze({LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8",PATH:"/usr/bin:/bin",TZ:"UTC"}),inherited:Object.freeze([]),privateDirectories:Object.freeze(["HOME","TMPDIR"])}),launch:Object.freeze({args:Object.freeze(["--disable-background-networking","--disable-breakpad","--disable-component-update","--disable-default-apps","--disable-domain-reliability","--disable-extensions","--disable-features=Translate,MediaRouter,OptimizationHints","--disable-quic","--disable-sync","--enable-unsafe-swiftshader","--force-webrtc-ip-handling-policy=disable_non_proxied_udp","--metrics-recording-only","--mute-audio","--no-default-browser-check","--no-first-run","--no-proxy-server","--use-angle=swiftshader"]),headless:!0,libraryArgs:Object.freeze({vgpu:Object.freeze(["--enable-unsafe-webgpu","--use-webgpu-adapter=swiftshader"])})}),routing:Object.freeze({allowedOrigin:"https://slopcamera-overlay.invalid",declaredResourcesOnly:!0,remoteNetworkDenied:!0}),runtimeSnapshot:Object.freeze({macosAnchor:"/private/tmp",macosAnchorPolicy:"physical-root-owned-sticky-direct-child",cleanupIdentity:"container-direct-children-and-complete-runtime-manifest",copyBufferBytes:4194304,filesystemGuard:"anchor-basename-and-recursive-parent-watch-with-path-identities",orphanRecovery:"active-to-released-lease-last-atomic-quarantine-double-open-proof",verifiedMacosFilesystemFlags:"user-immutable-recursive"}),schemaVersion:1,screenshot:Object.freeze({omitBackground:!0,scale:"css",type:"png"})}),rx0=Object.freeze({...d8.launch,args:Object.freeze([...d8.launch.args.filter(($)=>$!=="--enable-unsafe-swiftshader"&&$!=="--use-angle=swiftshader"),"--use-angle=metal","--disable-software-rasterizer"])});function ox0($){if($===void 0)return d8;let Q=wQ.parse($);return Object.freeze({...d8,contentSecurityPolicy:Q==="three-spark-webgl2-hardware-v1"?Object.freeze(d8.contentSecurityPolicy.map((_)=>{if(_==="worker-src 'none'")return"worker-src blob:";if(_==="connect-src 'none'")return"connect-src https://slopcamera-overlay.invalid data:";if(_.startsWith("script-src "))return`${_} 'wasm-unsafe-eval'`;return _})):d8.contentSecurityPolicy,executionProfile:Q,launch:rx0,gpu:Object.freeze({admission:"matching-active-webgl2-and-cdp-angle-metal-v1",capture:"host-held-native-context-health-before-and-after-every-screenshot",fallback:"reject-software-or-unknown",platform:"darwin",receipt:"bounded-context-device-driver-os-evidence-per-batch"}),schemaVersion:2})}function OA($,Q=[]){let _=ox0($),F=I3.parse(Q).filter((X)=>X.transport==="fetch").map((X)=>`${d8.routing.allowedOrigin}${NQ(X)}`);if(F.length===0||!_.contentSecurityPolicy.includes("connect-src 'none'"))return _;return Object.freeze({..._,contentSecurityPolicy:Object.freeze(_.contentSecurityPolicy.map((X)=>X==="connect-src 'none'"?`connect-src ${F.join(" ")}`:X)),schemaVersion:3})}function ZO($,Q){if(Q===void 0)return;wQ.parse(Q);let _=Q==="three-webgl2-hardware-v1"?["three"]:["@sparkjsdev/spark","three","three/addons/postprocessing/Pass.js"];if(R([...$].sort())!==R(_))throw Error("Hardware execution profile requires its exact approved scene library set.")}function _O($){return px0("sha256").update($).digest("hex")}function ix0($,Q){return _O(R({domain:"slopcamera.html-overlay-integrity-leaf/v1",key:$,value:Q}))}function ax0($){let Q=$.map((_)=>_O(["slopcamera.html-overlay-integrity-node/v1","leaf",_.key,_.sha256].join("\x00")));while(Q.length>1){let _=[];for(let Z=0;Z({key:`library:${G.specifier}`,value:G})),...Z.resources.map((G)=>({key:`resource:${G.name}`,value:G}))].map((G)=>({key:G.key,sha256:ix0(G.key,G.value)})).sort((G,D)=>G.keyD.key?1:0),N=r9.parse({algorithm:"sha256-merkle-v1",leaves:V,rootSha256:ax0(V),runtimeSha256:K,schemaVersion:1});return Object.freeze({importMap:Y,integrity:Object.freeze(N),libraryLocks:Object.freeze(X),runtimeSource:H})}var LV="slopcamera-3.5.0",FO=["scene.audit","scene.inspect","scene.patch","scene.evaluate","scene.render","scene.render-audit","scene.review","scene.direction.check","scene.direction.compile","scene.direction.gallery","scene.effects.check","scene.effects.plan","scene.behavior.check","scene.behavior.bake","scene.behavior.gallery","scene.behavior.audit","scene.temporal-audit","slopcamera.studio.run","spatial.project.snapshot","spatial.project.migrate","spatial.project.patch","spatial.project.restore","spatial.project.add-shot","spatial.project.add-candidate","spatial.project.select-candidate","spatial.project.reconcile","project.snapshot","analysis.project-inactivity","analysis.faces","analysis.music","analysis.scenes","analysis.project-auto-zooms","derive.edit-batch","project.commit-edits","derive.follow-faces","edit.create-revision","edit.create-candidate-revision","edit.bind-candidate-revision","edit.freeze-revision","iteration.create-candidate","iteration.create-matrix","iteration.select","project.promote-selection","render.bind-candidate-output","render.project-plan","render.project","render.materialize-selection","media.ingest","media.overlay","media.html-overlay","media.audio-effects","media.color-grade","gateway.image","gateway.video","gateway.speech","gateway.transcription","slopcamera.diagram.check","slopcamera.diagram.render","slopcamera.image.vectorize","slopcamera.image.generate"],XO=["cpu","local-io","ffmpeg","vision","whisper","network","paid-call","project-render","project-publication","output-publication","capture-device","browser"];import{isAbsolute as tx0,relative as gx,resolve as W$0}from"path";import{z as v1}from"zod";var ex0=v1.strictObject({path:w0}),oH=536870912,LA=v1.union([ex0,Vj,q0]),wA=v1.strictObject({endBehavior:v1.enum(["hide","loop","freeze-end"]).default("hide"),playbackRate:v1.number().finite().positive().max(64).default(1),sourceInUs:v1.number().int().safe().nonnegative().default(0),sourceOutUs:v1.number().int().safe().positive().optional()}).prefault({}),mx=v1.strictObject({artifact:q0,id:v1.string().min(1).max(256),provider:v1.enum(["apple-emoji-pack","brand-catalog"]),selector:UP,variant:v1.enum(["color","duotone"])}),$v0=v1.discriminatedUnion("kind",[v1.strictObject({artifact:LA,kind:v1.literal("image")}),v1.strictObject({artifact:LA,kind:v1.literal("svg")}),v1.strictObject({artifact:LA,kind:v1.literal("gif"),playback:wA}),v1.strictObject({artifact:LA,audioPolicy:dB.default({kind:"mute"}),kind:v1.literal("video"),playback:wA}),v1.strictObject({kind:v1.literal("emoji"),provider:v1.enum(["apple-emoji-pack","brand-catalog","auto"]).default("auto"),query:v1.string().min(1).max(256),resolved:mx.optional(),variant:v1.enum(["color","duotone"]).optional()})]),V$0=v1.discriminatedUnion("kind",[v1.strictObject({artifact:q0,kind:v1.literal("image")}),v1.strictObject({artifact:q0,kind:v1.literal("svg")}),v1.strictObject({artifact:q0,kind:v1.literal("gif"),playback:wA}),v1.strictObject({artifact:q0,audioPolicy:dB,kind:v1.literal("video"),playback:wA}),v1.strictObject({kind:v1.literal("emoji"),provider:v1.enum(["apple-emoji-pack","brand-catalog","auto"]),query:v1.string().min(1).max(256),resolved:mx,variant:v1.enum(["color","duotone"]).optional()})]),ux=v1.strictObject({anchor:MP.default("center"),blendMode:v1.enum(["normal","addition","darken","lighten","multiply","overlay","screen"]).default("normal"),crop:TP.default({kind:"none"}),entrance:pN.default({kind:"none"}),exit:pN.default({kind:"none"}),fit:v1.enum(["contain","cover","fill"]).default("fill"),mask:RP.default({kind:"none"}),motion:kP.default({kind:"none"}),opacity:v1.number().finite().min(0).max(1).default(1),position:p6.default({x:0,y:0}),rotationDegrees:v1.number().finite().min(-3600).max(3600).default(0),scale:v1.number().finite().positive().max(128).default(1),size:AP.default({kind:"intrinsic"}),zIndex:v1.number().int().safe().default(0)}).prefault({}),iH=v1.strictObject({capabilityBindings:p4.optional(),identityKey:v1.string().min(1).max(128).optional(),layout:ux,project:K2,range:m0,source:$v0}),lx=iH.extend({source:V$0}).strict(),WY=v1.strictObject({artifact:q0,created:v1.boolean(),operation:B5,receipt:q0}),dx=v1.strictObject({artifact:q0,createdAt:v1.string().datetime({offset:!0}),exactInputSha256:h,ffprobeVersion:v1.string().min(1).max(256).nullable(),kind:v1.union([v1.literal("slopcamera.local-overlay-preparation-receipt"),v1.literal("studio.local-overlay-preparation-receipt")]),operationSha256:h,overlayId:v1.string().min(1).max(128),projectGenerationSha256:h,projectId:K2,schemaVersion:v1.literal(1)});function Qv0($){let Q=$.trim().toLocaleLowerCase().replaceAll("u+","").replaceAll(/[_\s]+/gu,"-");if(/^[a-f0-9]+(?:-[a-f0-9]+)*$/u.test(Q))return{kind:"id",value:Q};if([...$].length<=16&&/[^\p{L}\p{N}\p{P}\p{Z}]/u.test($))return{kind:"unicode",value:$};return{kind:"name",value:$}}function _v0($){if(!("bytes"in $))return $;return q0.parse({bytes:$.bytes,path:$.path,sha256:$.sha256})}function G$0($){return $.kind==="image"||$.kind==="gif"||$.kind==="video"?["ffprobe"]:[]}async function Zv0($,Q,_,Z){let F=await Z($.paths.repositoryRoot,Q.query,Q.variant,Q.provider),X=gx($.paths.repositoryRoot,F.path),Y=await r1($,{path:X},_,oH);if(Y.artifact.sha256!==F.sha256)throw new j("conflict","Resolved emoji bytes disagree with the checked emoji catalog.");let J=mx.parse({artifact:Y.artifact,id:F.id,provider:F.provider,selector:Qv0(Q.query),variant:F.variant});if(Q.resolved!==void 0&&R(Q.resolved)!==R(J))throw new j("conflict","The checked emoji asset changed after exact node planning.");return V$0.parse({...Q,resolved:J})}async function cx($,Q,_,Z={}){let F=iH.parse(Q),X=G$0(F.source),Y=F.source.kind==="emoji"?Zv0($,F.source,_,Z.resolveEmoji??DV):r1($,_v0(F.source.artifact),_,oH).then((K)=>({...F.source,artifact:K.artifact})),[J,H]=await Promise.all([Y,w5($,X,F.capabilityBindings)]);return lx.parse({...F,capabilityBindings:H,source:J})}function Fv0($,Q){let _=W$0($,Q),Z=gx(W$0($),_);if(Z===""||Z.startsWith("..")||tx0(Z))throw new j("unsafe-path","Prepared overlay asset escaped its project bundle.");return _}function Xv0($,Q,_){let Z=zP.parse(Q),F={bytes:Z.asset.bytes,mediaType:Z.asset.mediaType,sha256:Z.asset.sha256},X=Z.kind==="image"||Z.kind==="svg"?{asset:F,kind:Z.kind}:Z.kind==="emoji"?{asset:F,kind:Z.kind,provider:Z.provider,selector:Z.selector}:{asset:F,audioPolicy:Z.audioPolicy,kind:Z.kind,playback:Z.playback};return`overlay_${m({domain:"studio.media-overlay-operation/v1",identityKey:$.identityKey??null,intrinsicSize:_,layout:$.layout,project:$.project,range:$.range,source:X}).slice(0,32)}`}function Yv0($={}){let Q=$.ingestFile??YA,_=$.ingestEmoji??JA,Z=$.inspectPng??sH,F=$.inspectSvg??KY,X=$.probe??M3,Y=$.resolveEmoji??DV;return{inputSchema:iH,inputSchemaId:"slopcamera.operation.media.overlay.input/v1",kind:"media.overlay",lifecycle:{kind:"local-artifact",execute:async(J,H)=>{a(J.abortSignal);let K=await cx(J.application,H,J.abortSignal,{resolveEmoji:Y}),W=G$0(K.source);await s9(J,J.application,K.capabilityBindings,W);let V=K.capabilityBindings??await HF(J.application,W),N=await n2(J.application,K.project);if(m8(J.expectedProjectGeneration,N.generation),K.range.endUs>N.plan.timelineDurationUs)throw new j("usage","Overlay range exceeds the project timeline.");let G=oQ(rQ(N.plan),K.range).reduce((B,C)=>B+C.output.endUs-C.output.startUs,0);if(G<=0)throw new j("conflict","Overlay range has no visible kept output time.");let D=K.source.kind==="emoji"?void 0:await r1(J.application,K.source.artifact,J.abortSignal,oH),L=K.source.kind==="emoji"?K.source:void 0,O=L===void 0?void 0:await Y(J.application.paths.repositoryRoot,L.query,L.variant,L.provider);if(O!==void 0&&L!==void 0&&(O.id!==L.resolved.id||O.provider!==L.resolved.provider||O.variant!==L.resolved.variant||O.sha256!==L.resolved.artifact.sha256))throw new j("conflict","Resolved emoji changed immediately before preparation.");let w=await $5(J);try{await J.workflow?.beforePublication(),a(J.abortSignal);let B=O===void 0?await Q(N.openProject.directory.path,D.absolutePath,K.source.kind):await _(N.openProject.directory.path,O),C=D?.artifact??L.resolved.artifact;if(B.bytes!==C.bytes||B.sha256!==C.sha256||B.provenance.sourceSha256!==C.sha256)throw new j("conflict","Prepared overlay bytes disagree with the exact bound source.");let U=Fv0(N.openProject.directory.path,B.path),z=(await r1(J.application,{path:gx(J.application.paths.repositoryRoot,U)},J.abortSignal,oH)).artifact;if(z.bytes!==B.bytes||z.sha256!==B.sha256)throw new j("conflict","Prepared project asset disagrees with its published bytes.");let M=B.mediaType==="image/svg+xml"?{...await F(U),audioEndUs:null,audioStartUs:0,audioStreamIndex:null,durationUs:null,hasAudio:!1,videoStartUs:0,videoStreamIndex:null}:K.source.kind==="emoji"?{...await Z(U),audioEndUs:null,audioStartUs:0,audioStreamIndex:null,durationUs:null,hasAudio:!1,videoStartUs:0,videoStreamIndex:null}:await X(F5(V,"ffprobe"),new X8(l8(J.application,V),J.abortSignal),U),T={height:"pixelHeight"in M?M.pixelHeight:M.height,width:"pixelWidth"in M?M.pixelWidth:M.width},q={bytes:B.bytes,mediaType:B.mediaType,path:B.path,provenance:B.provenance,sha256:B.sha256},E;if(K.source.kind==="image"||K.source.kind==="svg")E={asset:q,kind:K.source.kind};else if(K.source.kind==="emoji")E={asset:q,kind:"emoji",provider:K.source.resolved.provider,selector:K.source.resolved.selector};else{if(M.durationUs===null||M.durationUs<=0)throw new j("invalid-data","Animated overlay media must report a positive duration.");let x=OV({mediaDurationUs:M.durationUs,outputDurationUs:G,playbackRate:K.source.playback.playbackRate,sourceInUs:K.source.playback.sourceInUs,sourceOutUs:K.source.playback.sourceOutUs}),b={audioEndUs:M.audioEndUs,audioStartUs:M.audioStartUs,audioStreamIndex:M.audioStreamIndex,endBehavior:K.source.playback.endBehavior,playbackRate:K.source.playback.playbackRate,streamStartUs:M.videoStartUs,videoStreamIndex:M.videoStreamIndex,...x};if(K.source.kind==="gif")E={asset:q,audioPolicy:{kind:"mute"},kind:"gif",playback:b};else{if(K.source.audioPolicy.kind!=="mute"&&!M.hasAudio)throw new j("conflict","The selected video overlay audio policy requires an audio stream.");E={asset:q,audioPolicy:K.source.audioPolicy,kind:"video",playback:b}}}let A=B5.parse({...K.layout,coordinateSpace:"output-pixels",intrinsicSize:T,overlayId:Xv0(K,E,T),range:K.range,source:E}),k=dx.parse({artifact:z,createdAt:J.application.clock.now().toISOString(),exactInputSha256:m(K),ffprobeVersion:W.length===0?null:n9(V,"ffprobe"),kind:"slopcamera.local-overlay-preparation-receipt",operationSha256:m(A),overlayId:A.overlayId,projectGenerationSha256:N.generation.generationSha256,projectId:N.project.projectId,schemaVersion:1}),P=await D6({context:J,receipt:k,workspace:w}),I=WY.parse({artifact:z,created:B.created,operation:A,receipt:P});return await g5(J,{inputSchemaId:"slopcamera.operation.media.overlay.input/v1",kind:"media.overlay",outputSchemaId:"slopcamera.operation.media.overlay.output/v1",version:1},I),I}finally{await w.dispose()}}},outputSchema:WY,outputSchemaId:"slopcamera.operation.media.overlay.output/v1",policy:{cache:"exact-run",cancellable:!0,effect:"local-derived-write",maxDurationMs:3600000,maxFanOut:0,maxInputBytes:262144,maxOutputBytes:2097152,preparation:["project-state","local-media"],resources:[{amount:1,resource:"cpu"},{amount:1,resource:"local-io"},{amount:1,resource:"output-publication"}],resume:"verified-receipt"},receiptReference:(J)=>J.receipt.path,summarize:(J)=>({fields:{bytes:J.artifact.bytes,created:J.created,kind:J.operation.source.kind,overlayId:J.operation.overlayId,receipt:J.receipt.path,sha256:J.artifact.sha256},kind:"media.overlay"}),version:1}}var N$0=Yv0();var BA=2097152,CA=134217728,nx=536870912,sx=["ffmpeg","ffprobe","html-browser"],Gv0=s4.union([jV,s4.strictObject({path:w0}),q0]),Nv0=s4.union([jV,q0]),jv0=s4.union([b5,Vj]),Dv0=DQ.omit({bytes:!0,sha256:!0}).extend({artifact:jv0}).strict(),Ov0=DQ.extend({artifact:q0}).strict(),YO=s4.strictObject({canvas:WF,capabilityBindings:p4.optional(),document:Gv0,identityKey:s4.string().min(1).max(128).optional(),layout:ux,libraries:q3.default([]),parameters:XY.default({}),project:K2,range:m0,resources:s4.array(Dv0).max(64).default([]),seed:s4.number().int().min(0).max(4294967295).default(0),timing:C_}),rx=YO.omit({document:!0,resources:!0}).extend({document:Nv0,resources:s4.array(Ov0).max(64)}).strict(),ox=s4.strictObject({artifact:q0,browserVersion:s4.string().min(1).max(512),createdAt:s4.string().datetime({offset:!0}),executionIntegrity:r9.optional(),exactInputSha256:h,ffmpegVersion:s4.string().min(1).max(512),ffprobeVersion:s4.string().min(1).max(512),frameCount:s4.number().int().safe().positive(),kind:s4.union([s4.literal("slopcamera.html-overlay-preparation-receipt"),s4.literal("studio.html-overlay-preparation-receipt")]),libraryLocks:Zx,libraryLocksSha256:h,operationSha256:h,overlayId:s4.string().min(1).max(128),projectGenerationSha256:h,projectId:K2,schemaVersion:s4.literal(1)}),D$0=WY;function Lv0($){if(!("mediaType"in $.artifact))return $.artifact;if($.artifact.mediaType!==$.mediaType)throw new j("invalid-data",`HTML overlay resource ${$.name} declares ${$.mediaType} but its generated artifact is ${$.artifact.mediaType}.`);return q0.parse({bytes:$.artifact.bytes,path:$.artifact.path,sha256:$.artifact.sha256})}async function wv0($,Q,_){if("html"in Q)return Q;return(await r1($,Q,_,BA)).artifact}function Bv0($,Q){return oQ(rQ($),Q).reduce((_,Z)=>_+Z.output.endUs-Z.output.startUs,0)}async function ix($,Q,_){let Z=YO.parse(Q),[F,X,Y]=await Promise.all([wv0($,Z.document,_),Promise.all(Z.resources.map(async(K)=>({...K,artifact:(await r1($,Lv0(K),_,CA)).artifact}))),w5($,sx,Z.capabilityBindings)]),J=I3.parse(X.map(({artifact:K,...W})=>({...W,bytes:K.bytes,sha256:K.sha256}))),H=new Map(X.map((K)=>[K.name,K.artifact]));return rx.parse({...Z,capabilityBindings:Y,document:F,resources:J.map((K)=>({...K,artifact:H.get(K.name)}))})}function Cv0($){let Q;try{Q=new TextDecoder("utf-8",{fatal:!0}).decode($)}catch{throw new j("invalid-data","The HTML overlay document must be valid UTF-8.")}if(Q.trim()==="")throw new j("invalid-data","The HTML overlay document is empty.");return Q}async function Uv0($,Q){let _=await Kv0($,j$0.O_RDONLY|(j$0.O_NOFOLLOW??0));try{let Z=await _.stat();if(!Z.isFile()||Z.size<=0)throw new j("invalid-data","Rendered HTML overlay is empty.");let F=Jv0("sha256"),X=Buffer.allocUnsafe(1048576),Y=0;while(Y{a(X.abortSignal);let J=await ix(X.application,Y,X.abortSignal);await s9(X,X.application,J.capabilityBindings,sx);let H=J.capabilityBindings??await HF(X.application,sx),K=X.application.htmlOverlayRenderer;if(K===void 0)throw new j("unavailable","This Slopcamera host does not provide an HTML-overlay browser renderer.");let W=await n2(X.application,J.project);if(m8(X.expectedProjectGeneration,W.generation),J.range.endUs>W.plan.timelineDurationUs)throw new j("usage","HTML overlay range exceeds the project timeline.");let V=Bv0(W.plan,J.range);if(V<=0)throw new j("conflict","HTML overlay range has no visible kept output time.");if(J.timing.durationUs!==V)throw new j("conflict","HTML overlay timing duration must equal the range's visible output duration.",{actualDurationUs:J.timing.durationUs,expectedDurationUs:V});let[N,G]=await Promise.all(["html"in J.document?Promise.resolve(J.document.html):B4(X.application,J.document,X.abortSignal,BA).then((w)=>Cv0(w.data)),Promise.all(J.resources.map(async(w)=>({...w,absolutePath:(await r1(X.application,w.artifact,X.abortSignal,CA)).absolutePath})))]),D=OQ.parse({canvas:J.canvas,html:N,kind:"slopcamera.html-overlay",libraries:J.libraries,parameters:J.parameters,resources:G.map((w)=>({bytes:w.bytes,mediaType:w.mediaType,name:w.name,sha256:w.sha256,...w.transport===void 0?{}:{transport:w.transport},urlPath:w.urlPath})),schemaVersion:1,seed:J.seed,timing:J.timing}),L=await $5(X),O=await Hv0(px(L.path,"html-overlay-"));try{let w=await Z(m5(H,"html-browser"),X.abortSignal),B=o9(D,w).integrity,C=await K.renderFrames({authoring:D,browserRuntime:w,outputDirectory:O,resources:G},X.abortSignal),U=r9.parse(C.executionIntegrity);if(m(U)!==m(B))throw new j("conflict","HTML-overlay renderer returned integrity evidence that does not match the planned browser execution.");let z=rD.parse(C.libraryLocks),M=D.libraries.map(E3);if(m(z)!==m(M))throw new j("conflict","HTML-overlay renderer returned library locks that do not exactly match the authoring selection.");let T=M6(D.timing);if(C.frameCount!==T)throw new j("conflict","HTML-overlay renderer returned an unexpected frame count.");let q=px(O,"overlay.mov"),E=[F5(H,"ffmpeg"),"-hide_banner","-loglevel","error","-nostdin","-n","-framerate",String(D.timing.fps),"-start_number","0","-i",C.framePattern,"-frames:v",String(C.frameCount),"-an","-c:v","qtrle","-pix_fmt","argb","-movflags","+faststart",q],A=await new X8(l8(X.application,H),X.abortSignal).run(E,{cwd:O,maxOutputBytes:1048576,stdin:"ignore",timeoutMs:3600000});if(A.exitCode!==0)throw new j("invalid-data",`FFmpeg could not encode the HTML overlay: ${A.stderr.slice(0,2000)}`);await Mv0(X.application,H,q,D.canvas,X.abortSignal);let k=await Uv0(q,X.abortSignal);await X.workflow?.beforePublication(),a(X.abortSignal);let P=await Q(W.openProject.directory.path,{command:E,generator:"slopcamera-html-overlay",generatorVersion:F,path:q,sourceSha256:k}),I=px(W.openProject.directory.path,P.path),x=(await r1(X.application,{path:Vv0(X.application.paths.repositoryRoot,I)},X.abortSignal,nx)).artifact,b=await _(F5(H,"ffprobe"),new X8(l8(X.application,H),X.abortSignal),I);if(b.durationUs===null||b.durationUs<=0||b.hasAudio||b.pixelWidth!==D.canvas.width||b.pixelHeight!==D.canvas.height)throw new j("invalid-data","Generated HTML overlay has invalid duration, dimensions, or audio streams.");let y=OV({mediaDurationUs:b.durationUs,outputDurationUs:V,playbackRate:1,sourceInUs:0,sourceOutUs:void 0}),r={asset:{bytes:P.bytes,mediaType:P.mediaType,path:P.path,provenance:P.provenance,sha256:P.sha256},audioPolicy:{kind:"mute"},kind:"video",playback:{audioEndUs:null,audioStartUs:0,audioStreamIndex:null,endBehavior:"hide",playbackRate:1,streamStartUs:b.videoStartUs,videoStreamIndex:b.videoStreamIndex,...y}},g=B5.parse({...J.layout,coordinateSpace:"output-pixels",intrinsicSize:{height:D.canvas.height,width:D.canvas.width},overlayId:Av0(J,D,x.sha256),range:J.range,source:r}),p=ox.parse({artifact:x,browserVersion:n9(H,"html-browser"),createdAt:X.application.clock.now().toISOString(),executionIntegrity:U,exactInputSha256:m(J),ffmpegVersion:n9(H,"ffmpeg"),ffprobeVersion:n9(H,"ffprobe"),frameCount:C.frameCount,kind:"slopcamera.html-overlay-preparation-receipt",libraryLocks:z,libraryLocksSha256:m(z),operationSha256:m(g),overlayId:g.overlayId,projectGenerationSha256:W.generation.generationSha256,projectId:W.project.projectId,schemaVersion:1}),S=await D6({context:X,receipt:p,workspace:L}),i=WY.parse({artifact:x,created:P.created,operation:g,receipt:S});return await g5(X,{inputSchemaId:"slopcamera.operation.media.html-overlay.input/v1",kind:"media.html-overlay",outputSchemaId:"slopcamera.operation.media.html-overlay.output/v1",version:1},i),i}finally{await Wv0(O,{force:!0,recursive:!0}),await L.dispose()}}},outputSchema:WY,outputSchemaId:"slopcamera.operation.media.html-overlay.output/v1",policy:{cache:"exact-run",cancellable:!0,effect:"local-derived-write",maxDurationMs:3600000,maxFanOut:0,maxInputBytes:3145728,maxOutputBytes:2097152,preparation:["project-state","local-media"],resources:[{amount:1,resource:"browser"},{amount:1,resource:"cpu"},{amount:1,resource:"ffmpeg"},{amount:1,resource:"local-io"},{amount:1,resource:"network"},{amount:1,resource:"output-publication"}],resume:"verified-receipt"},receiptReference:(X)=>X.receipt.path,summarize:(X)=>({fields:{bytes:X.artifact.bytes,created:X.created,kind:"html",overlayId:X.operation.overlayId,receipt:X.receipt.path,sha256:X.artifact.sha256},kind:"media.html-overlay"}),version:1}}var uB1=ax();var Rv0=["media.ingest","media.html-overlay","media.overlay","media.audio-effects","media.color-grade"],oB1=Tv0.enum(Rv0);async function O$0($,Q,_,Z=new AbortController().signal){switch(Q){case"media.ingest":return await u40($,NV.parse(_),Z);case"media.overlay":return await cx($,iH.parse(_),Z);case"media.html-overlay":return await ix($,YO.parse(_),Z);case"media.audio-effects":return await f40($,VV.parse(_),Z);case"media.color-grade":return await v40($,GV.parse(_),Z)}}import{z as JO}from"zod";import{lstat as bv0,realpath as B$0}from"fs/promises";import{isAbsolute as Sv0,join as fv0,relative as yv0,sep as xv0}from"path";import{z as S3}from"zod";var UA=4096,tx=4,kv0=16777216,ex=Object.freeze({maximumCount:64,maximumTotalPixels:67108864,maximumTotalSvgBytes:67108864});function L$0($){let Q=1;while(Q<$)Q*=2;return Q}function qv0($){let Q=[],_=0,Z=[],F=0,X=0,Y=0,J=0,H=()=>{if(Z.length===0)return;let K=L$0(X+Y),W=L$0(J),V=W*K;if(Q.length>=ex.maximumCount||_+V>ex.maximumTotalPixels)throw RangeError("Generated caption sprites exceed the cumulative raster resource bound.");Q.push({cards:Z,height:K,width:W}),_+=V,Z=[],F=0,X=0,Y=0,J=0};for(let K of $){let{intrinsicHeight:W,intrinsicWidth:V}=K.rendered;if(V>UA||W>UA)throw RangeError("A social caption card exceeds the sprite dimension bound.");if(F>0&&F+V>UA)F=0,X+=Y+tx,Y=0;if(X>0&&X+W>UA)H();Z.push({...K,x:F,y:X}),F+=V+tx,Y=Math.max(Y,W),J=Math.max(J,F-tx)}return H(),Q}function Ev0($){let Q=$.indexOf(">");if(!$.startsWith(""))throw TypeError("Social caption renderer returned an unsupported SVG document.");return $.slice(Q+1,-6)}function Pv0($){let Q=$.cards.map((F)=>`${Ev0(F.rendered.svg)}`).join(""),_=[``,Q,` + }`);return H$0(Q,"return securityViolations;","return securityViolations + (sparkWorkerFailure === null ? 0 : 1);")}var hx=rH.string().regex(/^[a-f0-9]{64}$/u),nx0=rH.strictObject({key:rH.string().min(1).max(512),sha256:hx}),r9=rH.strictObject({algorithm:rH.literal("sha256-merkle-v1"),leaves:rH.array(nx0).min(4).max(256).superRefine(($,Q)=>{for(let _=1;_<$.length;_+=1)if($[_-1].key>=$[_].key)Q.addIssue({code:"custom",message:"HTML-overlay integrity leaves must have unique ASCII-sorted keys.",path:[_,"key"]})}),rootSha256:hx,runtimeSha256:hx,schemaVersion:rH.literal(1)}),d8=Object.freeze({browser:"playwright-chromium",browserVersion:sx0.version,browserContext:Object.freeze({acceptDownloads:!1,colorScheme:"light",locale:"en-US",offline:!0,permissions:Object.freeze([]),reducedMotion:"no-preference",serviceWorkers:"block",timezoneId:"UTC"}),contentSecurityPolicy:Object.freeze(["default-src 'none'","base-uri 'none'","connect-src 'none'","font-src https://slopcamera-overlay.invalid data:","form-action 'none'","frame-src 'none'","img-src https://slopcamera-overlay.invalid data:","media-src https://slopcamera-overlay.invalid data:","object-src 'none'","script-src 'unsafe-inline' https://slopcamera-overlay.invalid","style-src 'unsafe-inline'","worker-src 'none'"]),documentUrl:"https://slopcamera-overlay.invalid/slopcamera-overlay/document",environment:Object.freeze({fixed:Object.freeze({LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8",PATH:"/usr/bin:/bin",TZ:"UTC"}),inherited:Object.freeze([]),privateDirectories:Object.freeze(["HOME","TMPDIR"])}),launch:Object.freeze({args:Object.freeze(["--disable-background-networking","--disable-breakpad","--disable-component-update","--disable-default-apps","--disable-domain-reliability","--disable-extensions","--disable-features=Translate,MediaRouter,OptimizationHints","--disable-quic","--disable-sync","--enable-unsafe-swiftshader","--force-webrtc-ip-handling-policy=disable_non_proxied_udp","--metrics-recording-only","--mute-audio","--no-default-browser-check","--no-first-run","--no-proxy-server","--use-angle=swiftshader"]),headless:!0,libraryArgs:Object.freeze({vgpu:Object.freeze(["--enable-unsafe-webgpu","--use-webgpu-adapter=swiftshader"])})}),routing:Object.freeze({allowedOrigin:"https://slopcamera-overlay.invalid",declaredResourcesOnly:!0,remoteNetworkDenied:!0}),runtimeSnapshot:Object.freeze({macosAnchor:"/private/tmp",macosAnchorPolicy:"physical-root-owned-sticky-direct-child",cleanupIdentity:"container-direct-children-and-complete-runtime-manifest",copyBufferBytes:4194304,filesystemGuard:"anchor-basename-and-recursive-parent-watch-with-path-identities",orphanRecovery:"active-to-released-lease-last-atomic-quarantine-double-open-proof",verifiedMacosFilesystemFlags:"user-immutable-recursive"}),schemaVersion:1,screenshot:Object.freeze({omitBackground:!0,scale:"css",type:"png"})}),rx0=Object.freeze({...d8.launch,args:Object.freeze([...d8.launch.args.filter(($)=>$!=="--enable-unsafe-swiftshader"&&$!=="--use-angle=swiftshader"),"--use-angle=metal","--disable-software-rasterizer"])});function ox0($){if($===void 0)return d8;let Q=wQ.parse($);return Object.freeze({...d8,contentSecurityPolicy:Q==="three-spark-webgl2-hardware-v1"?Object.freeze(d8.contentSecurityPolicy.map((_)=>{if(_==="worker-src 'none'")return"worker-src blob:";if(_==="connect-src 'none'")return"connect-src https://slopcamera-overlay.invalid data:";if(_.startsWith("script-src "))return`${_} 'wasm-unsafe-eval'`;return _})):d8.contentSecurityPolicy,executionProfile:Q,launch:rx0,gpu:Object.freeze({admission:"matching-active-webgl2-and-cdp-angle-metal-v1",capture:"host-held-native-context-health-before-and-after-every-screenshot",fallback:"reject-software-or-unknown",platform:"darwin",receipt:"bounded-context-device-driver-os-evidence-per-batch"}),schemaVersion:2})}function OA($,Q=[]){let _=ox0($),F=I3.parse(Q).filter((X)=>X.transport==="fetch").map((X)=>`${d8.routing.allowedOrigin}${NQ(X)}`);if(F.length===0||!_.contentSecurityPolicy.includes("connect-src 'none'"))return _;return Object.freeze({..._,contentSecurityPolicy:Object.freeze(_.contentSecurityPolicy.map((X)=>X==="connect-src 'none'"?`connect-src ${F.join(" ")}`:X)),schemaVersion:3})}function ZO($,Q){if(Q===void 0)return;wQ.parse(Q);let _=Q==="three-webgl2-hardware-v1"?["three"]:["@sparkjsdev/spark","three","three/addons/postprocessing/Pass.js"];if(R([...$].sort())!==R(_))throw Error("Hardware execution profile requires its exact approved scene library set.")}function _O($){return px0("sha256").update($).digest("hex")}function ix0($,Q){return _O(R({domain:"slopcamera.html-overlay-integrity-leaf/v1",key:$,value:Q}))}function ax0($){let Q=$.map((_)=>_O(["slopcamera.html-overlay-integrity-node/v1","leaf",_.key,_.sha256].join("\x00")));while(Q.length>1){let _=[];for(let Z=0;Z({key:`library:${G.specifier}`,value:G})),...Z.resources.map((G)=>({key:`resource:${G.name}`,value:G}))].map((G)=>({key:G.key,sha256:ix0(G.key,G.value)})).sort((G,D)=>G.keyD.key?1:0),N=r9.parse({algorithm:"sha256-merkle-v1",leaves:V,rootSha256:ax0(V),runtimeSha256:K,schemaVersion:1});return Object.freeze({importMap:Y,integrity:Object.freeze(N),libraryLocks:Object.freeze(X),runtimeSource:H})}var LV="slopcamera-3.6.0",FO=["scene.audit","scene.inspect","scene.patch","scene.evaluate","scene.render","scene.render-audit","scene.review","scene.direction.check","scene.direction.compile","scene.direction.gallery","scene.effects.check","scene.effects.plan","scene.behavior.check","scene.behavior.bake","scene.behavior.gallery","scene.behavior.audit","scene.temporal-audit","slopcamera.studio.run","spatial.project.snapshot","spatial.project.migrate","spatial.project.patch","spatial.project.restore","spatial.project.add-shot","spatial.project.add-candidate","spatial.project.select-candidate","spatial.project.reconcile","project.snapshot","analysis.project-inactivity","analysis.faces","analysis.music","analysis.scenes","analysis.project-auto-zooms","derive.edit-batch","project.commit-edits","derive.follow-faces","edit.create-revision","edit.create-candidate-revision","edit.bind-candidate-revision","edit.freeze-revision","iteration.create-candidate","iteration.create-matrix","iteration.select","project.promote-selection","render.bind-candidate-output","render.project-plan","render.project","render.materialize-selection","media.ingest","media.overlay","media.html-overlay","media.audio-effects","media.color-grade","gateway.image","gateway.video","gateway.speech","gateway.transcription","slopcamera.diagram.check","slopcamera.diagram.render","slopcamera.image.vectorize","slopcamera.image.generate"],XO=["cpu","local-io","ffmpeg","vision","whisper","network","paid-call","project-render","project-publication","output-publication","capture-device","browser"];import{isAbsolute as tx0,relative as gx,resolve as W$0}from"path";import{z as v1}from"zod";var ex0=v1.strictObject({path:w0}),oH=536870912,LA=v1.union([ex0,Vj,q0]),wA=v1.strictObject({endBehavior:v1.enum(["hide","loop","freeze-end"]).default("hide"),playbackRate:v1.number().finite().positive().max(64).default(1),sourceInUs:v1.number().int().safe().nonnegative().default(0),sourceOutUs:v1.number().int().safe().positive().optional()}).prefault({}),mx=v1.strictObject({artifact:q0,id:v1.string().min(1).max(256),provider:v1.enum(["apple-emoji-pack","brand-catalog"]),selector:UP,variant:v1.enum(["color","duotone"])}),$v0=v1.discriminatedUnion("kind",[v1.strictObject({artifact:LA,kind:v1.literal("image")}),v1.strictObject({artifact:LA,kind:v1.literal("svg")}),v1.strictObject({artifact:LA,kind:v1.literal("gif"),playback:wA}),v1.strictObject({artifact:LA,audioPolicy:dB.default({kind:"mute"}),kind:v1.literal("video"),playback:wA}),v1.strictObject({kind:v1.literal("emoji"),provider:v1.enum(["apple-emoji-pack","brand-catalog","auto"]).default("auto"),query:v1.string().min(1).max(256),resolved:mx.optional(),variant:v1.enum(["color","duotone"]).optional()})]),V$0=v1.discriminatedUnion("kind",[v1.strictObject({artifact:q0,kind:v1.literal("image")}),v1.strictObject({artifact:q0,kind:v1.literal("svg")}),v1.strictObject({artifact:q0,kind:v1.literal("gif"),playback:wA}),v1.strictObject({artifact:q0,audioPolicy:dB,kind:v1.literal("video"),playback:wA}),v1.strictObject({kind:v1.literal("emoji"),provider:v1.enum(["apple-emoji-pack","brand-catalog","auto"]),query:v1.string().min(1).max(256),resolved:mx,variant:v1.enum(["color","duotone"]).optional()})]),ux=v1.strictObject({anchor:MP.default("center"),blendMode:v1.enum(["normal","addition","darken","lighten","multiply","overlay","screen"]).default("normal"),crop:TP.default({kind:"none"}),entrance:pN.default({kind:"none"}),exit:pN.default({kind:"none"}),fit:v1.enum(["contain","cover","fill"]).default("fill"),mask:RP.default({kind:"none"}),motion:kP.default({kind:"none"}),opacity:v1.number().finite().min(0).max(1).default(1),position:p6.default({x:0,y:0}),rotationDegrees:v1.number().finite().min(-3600).max(3600).default(0),scale:v1.number().finite().positive().max(128).default(1),size:AP.default({kind:"intrinsic"}),zIndex:v1.number().int().safe().default(0)}).prefault({}),iH=v1.strictObject({capabilityBindings:p4.optional(),identityKey:v1.string().min(1).max(128).optional(),layout:ux,project:K2,range:m0,source:$v0}),lx=iH.extend({source:V$0}).strict(),WY=v1.strictObject({artifact:q0,created:v1.boolean(),operation:B5,receipt:q0}),dx=v1.strictObject({artifact:q0,createdAt:v1.string().datetime({offset:!0}),exactInputSha256:h,ffprobeVersion:v1.string().min(1).max(256).nullable(),kind:v1.union([v1.literal("slopcamera.local-overlay-preparation-receipt"),v1.literal("studio.local-overlay-preparation-receipt")]),operationSha256:h,overlayId:v1.string().min(1).max(128),projectGenerationSha256:h,projectId:K2,schemaVersion:v1.literal(1)});function Qv0($){let Q=$.trim().toLocaleLowerCase().replaceAll("u+","").replaceAll(/[_\s]+/gu,"-");if(/^[a-f0-9]+(?:-[a-f0-9]+)*$/u.test(Q))return{kind:"id",value:Q};if([...$].length<=16&&/[^\p{L}\p{N}\p{P}\p{Z}]/u.test($))return{kind:"unicode",value:$};return{kind:"name",value:$}}function _v0($){if(!("bytes"in $))return $;return q0.parse({bytes:$.bytes,path:$.path,sha256:$.sha256})}function G$0($){return $.kind==="image"||$.kind==="gif"||$.kind==="video"?["ffprobe"]:[]}async function Zv0($,Q,_,Z){let F=await Z($.paths.repositoryRoot,Q.query,Q.variant,Q.provider),X=gx($.paths.repositoryRoot,F.path),Y=await r1($,{path:X},_,oH);if(Y.artifact.sha256!==F.sha256)throw new j("conflict","Resolved emoji bytes disagree with the checked emoji catalog.");let J=mx.parse({artifact:Y.artifact,id:F.id,provider:F.provider,selector:Qv0(Q.query),variant:F.variant});if(Q.resolved!==void 0&&R(Q.resolved)!==R(J))throw new j("conflict","The checked emoji asset changed after exact node planning.");return V$0.parse({...Q,resolved:J})}async function cx($,Q,_,Z={}){let F=iH.parse(Q),X=G$0(F.source),Y=F.source.kind==="emoji"?Zv0($,F.source,_,Z.resolveEmoji??DV):r1($,_v0(F.source.artifact),_,oH).then((K)=>({...F.source,artifact:K.artifact})),[J,H]=await Promise.all([Y,w5($,X,F.capabilityBindings)]);return lx.parse({...F,capabilityBindings:H,source:J})}function Fv0($,Q){let _=W$0($,Q),Z=gx(W$0($),_);if(Z===""||Z.startsWith("..")||tx0(Z))throw new j("unsafe-path","Prepared overlay asset escaped its project bundle.");return _}function Xv0($,Q,_){let Z=zP.parse(Q),F={bytes:Z.asset.bytes,mediaType:Z.asset.mediaType,sha256:Z.asset.sha256},X=Z.kind==="image"||Z.kind==="svg"?{asset:F,kind:Z.kind}:Z.kind==="emoji"?{asset:F,kind:Z.kind,provider:Z.provider,selector:Z.selector}:{asset:F,audioPolicy:Z.audioPolicy,kind:Z.kind,playback:Z.playback};return`overlay_${m({domain:"studio.media-overlay-operation/v1",identityKey:$.identityKey??null,intrinsicSize:_,layout:$.layout,project:$.project,range:$.range,source:X}).slice(0,32)}`}function Yv0($={}){let Q=$.ingestFile??YA,_=$.ingestEmoji??JA,Z=$.inspectPng??sH,F=$.inspectSvg??KY,X=$.probe??M3,Y=$.resolveEmoji??DV;return{inputSchema:iH,inputSchemaId:"slopcamera.operation.media.overlay.input/v1",kind:"media.overlay",lifecycle:{kind:"local-artifact",execute:async(J,H)=>{a(J.abortSignal);let K=await cx(J.application,H,J.abortSignal,{resolveEmoji:Y}),W=G$0(K.source);await s9(J,J.application,K.capabilityBindings,W);let V=K.capabilityBindings??await HF(J.application,W),N=await n2(J.application,K.project);if(m8(J.expectedProjectGeneration,N.generation),K.range.endUs>N.plan.timelineDurationUs)throw new j("usage","Overlay range exceeds the project timeline.");let G=oQ(rQ(N.plan),K.range).reduce((B,C)=>B+C.output.endUs-C.output.startUs,0);if(G<=0)throw new j("conflict","Overlay range has no visible kept output time.");let D=K.source.kind==="emoji"?void 0:await r1(J.application,K.source.artifact,J.abortSignal,oH),L=K.source.kind==="emoji"?K.source:void 0,O=L===void 0?void 0:await Y(J.application.paths.repositoryRoot,L.query,L.variant,L.provider);if(O!==void 0&&L!==void 0&&(O.id!==L.resolved.id||O.provider!==L.resolved.provider||O.variant!==L.resolved.variant||O.sha256!==L.resolved.artifact.sha256))throw new j("conflict","Resolved emoji changed immediately before preparation.");let w=await $5(J);try{await J.workflow?.beforePublication(),a(J.abortSignal);let B=O===void 0?await Q(N.openProject.directory.path,D.absolutePath,K.source.kind):await _(N.openProject.directory.path,O),C=D?.artifact??L.resolved.artifact;if(B.bytes!==C.bytes||B.sha256!==C.sha256||B.provenance.sourceSha256!==C.sha256)throw new j("conflict","Prepared overlay bytes disagree with the exact bound source.");let U=Fv0(N.openProject.directory.path,B.path),z=(await r1(J.application,{path:gx(J.application.paths.repositoryRoot,U)},J.abortSignal,oH)).artifact;if(z.bytes!==B.bytes||z.sha256!==B.sha256)throw new j("conflict","Prepared project asset disagrees with its published bytes.");let M=B.mediaType==="image/svg+xml"?{...await F(U),audioEndUs:null,audioStartUs:0,audioStreamIndex:null,durationUs:null,hasAudio:!1,videoStartUs:0,videoStreamIndex:null}:K.source.kind==="emoji"?{...await Z(U),audioEndUs:null,audioStartUs:0,audioStreamIndex:null,durationUs:null,hasAudio:!1,videoStartUs:0,videoStreamIndex:null}:await X(F5(V,"ffprobe"),new X8(l8(J.application,V),J.abortSignal),U),T={height:"pixelHeight"in M?M.pixelHeight:M.height,width:"pixelWidth"in M?M.pixelWidth:M.width},q={bytes:B.bytes,mediaType:B.mediaType,path:B.path,provenance:B.provenance,sha256:B.sha256},E;if(K.source.kind==="image"||K.source.kind==="svg")E={asset:q,kind:K.source.kind};else if(K.source.kind==="emoji")E={asset:q,kind:"emoji",provider:K.source.resolved.provider,selector:K.source.resolved.selector};else{if(M.durationUs===null||M.durationUs<=0)throw new j("invalid-data","Animated overlay media must report a positive duration.");let x=OV({mediaDurationUs:M.durationUs,outputDurationUs:G,playbackRate:K.source.playback.playbackRate,sourceInUs:K.source.playback.sourceInUs,sourceOutUs:K.source.playback.sourceOutUs}),b={audioEndUs:M.audioEndUs,audioStartUs:M.audioStartUs,audioStreamIndex:M.audioStreamIndex,endBehavior:K.source.playback.endBehavior,playbackRate:K.source.playback.playbackRate,streamStartUs:M.videoStartUs,videoStreamIndex:M.videoStreamIndex,...x};if(K.source.kind==="gif")E={asset:q,audioPolicy:{kind:"mute"},kind:"gif",playback:b};else{if(K.source.audioPolicy.kind!=="mute"&&!M.hasAudio)throw new j("conflict","The selected video overlay audio policy requires an audio stream.");E={asset:q,audioPolicy:K.source.audioPolicy,kind:"video",playback:b}}}let A=B5.parse({...K.layout,coordinateSpace:"output-pixels",intrinsicSize:T,overlayId:Xv0(K,E,T),range:K.range,source:E}),k=dx.parse({artifact:z,createdAt:J.application.clock.now().toISOString(),exactInputSha256:m(K),ffprobeVersion:W.length===0?null:n9(V,"ffprobe"),kind:"slopcamera.local-overlay-preparation-receipt",operationSha256:m(A),overlayId:A.overlayId,projectGenerationSha256:N.generation.generationSha256,projectId:N.project.projectId,schemaVersion:1}),P=await D6({context:J,receipt:k,workspace:w}),I=WY.parse({artifact:z,created:B.created,operation:A,receipt:P});return await g5(J,{inputSchemaId:"slopcamera.operation.media.overlay.input/v1",kind:"media.overlay",outputSchemaId:"slopcamera.operation.media.overlay.output/v1",version:1},I),I}finally{await w.dispose()}}},outputSchema:WY,outputSchemaId:"slopcamera.operation.media.overlay.output/v1",policy:{cache:"exact-run",cancellable:!0,effect:"local-derived-write",maxDurationMs:3600000,maxFanOut:0,maxInputBytes:262144,maxOutputBytes:2097152,preparation:["project-state","local-media"],resources:[{amount:1,resource:"cpu"},{amount:1,resource:"local-io"},{amount:1,resource:"output-publication"}],resume:"verified-receipt"},receiptReference:(J)=>J.receipt.path,summarize:(J)=>({fields:{bytes:J.artifact.bytes,created:J.created,kind:J.operation.source.kind,overlayId:J.operation.overlayId,receipt:J.receipt.path,sha256:J.artifact.sha256},kind:"media.overlay"}),version:1}}var N$0=Yv0();var BA=2097152,CA=134217728,nx=536870912,sx=["ffmpeg","ffprobe","html-browser"],Gv0=s4.union([jV,s4.strictObject({path:w0}),q0]),Nv0=s4.union([jV,q0]),jv0=s4.union([b5,Vj]),Dv0=DQ.omit({bytes:!0,sha256:!0}).extend({artifact:jv0}).strict(),Ov0=DQ.extend({artifact:q0}).strict(),YO=s4.strictObject({canvas:WF,capabilityBindings:p4.optional(),document:Gv0,identityKey:s4.string().min(1).max(128).optional(),layout:ux,libraries:q3.default([]),parameters:XY.default({}),project:K2,range:m0,resources:s4.array(Dv0).max(64).default([]),seed:s4.number().int().min(0).max(4294967295).default(0),timing:C_}),rx=YO.omit({document:!0,resources:!0}).extend({document:Nv0,resources:s4.array(Ov0).max(64)}).strict(),ox=s4.strictObject({artifact:q0,browserVersion:s4.string().min(1).max(512),createdAt:s4.string().datetime({offset:!0}),executionIntegrity:r9.optional(),exactInputSha256:h,ffmpegVersion:s4.string().min(1).max(512),ffprobeVersion:s4.string().min(1).max(512),frameCount:s4.number().int().safe().positive(),kind:s4.union([s4.literal("slopcamera.html-overlay-preparation-receipt"),s4.literal("studio.html-overlay-preparation-receipt")]),libraryLocks:Zx,libraryLocksSha256:h,operationSha256:h,overlayId:s4.string().min(1).max(128),projectGenerationSha256:h,projectId:K2,schemaVersion:s4.literal(1)}),D$0=WY;function Lv0($){if(!("mediaType"in $.artifact))return $.artifact;if($.artifact.mediaType!==$.mediaType)throw new j("invalid-data",`HTML overlay resource ${$.name} declares ${$.mediaType} but its generated artifact is ${$.artifact.mediaType}.`);return q0.parse({bytes:$.artifact.bytes,path:$.artifact.path,sha256:$.artifact.sha256})}async function wv0($,Q,_){if("html"in Q)return Q;return(await r1($,Q,_,BA)).artifact}function Bv0($,Q){return oQ(rQ($),Q).reduce((_,Z)=>_+Z.output.endUs-Z.output.startUs,0)}async function ix($,Q,_){let Z=YO.parse(Q),[F,X,Y]=await Promise.all([wv0($,Z.document,_),Promise.all(Z.resources.map(async(K)=>({...K,artifact:(await r1($,Lv0(K),_,CA)).artifact}))),w5($,sx,Z.capabilityBindings)]),J=I3.parse(X.map(({artifact:K,...W})=>({...W,bytes:K.bytes,sha256:K.sha256}))),H=new Map(X.map((K)=>[K.name,K.artifact]));return rx.parse({...Z,capabilityBindings:Y,document:F,resources:J.map((K)=>({...K,artifact:H.get(K.name)}))})}function Cv0($){let Q;try{Q=new TextDecoder("utf-8",{fatal:!0}).decode($)}catch{throw new j("invalid-data","The HTML overlay document must be valid UTF-8.")}if(Q.trim()==="")throw new j("invalid-data","The HTML overlay document is empty.");return Q}async function Uv0($,Q){let _=await Kv0($,j$0.O_RDONLY|(j$0.O_NOFOLLOW??0));try{let Z=await _.stat();if(!Z.isFile()||Z.size<=0)throw new j("invalid-data","Rendered HTML overlay is empty.");let F=Jv0("sha256"),X=Buffer.allocUnsafe(1048576),Y=0;while(Y{a(X.abortSignal);let J=await ix(X.application,Y,X.abortSignal);await s9(X,X.application,J.capabilityBindings,sx);let H=J.capabilityBindings??await HF(X.application,sx),K=X.application.htmlOverlayRenderer;if(K===void 0)throw new j("unavailable","This Slopcamera host does not provide an HTML-overlay browser renderer.");let W=await n2(X.application,J.project);if(m8(X.expectedProjectGeneration,W.generation),J.range.endUs>W.plan.timelineDurationUs)throw new j("usage","HTML overlay range exceeds the project timeline.");let V=Bv0(W.plan,J.range);if(V<=0)throw new j("conflict","HTML overlay range has no visible kept output time.");if(J.timing.durationUs!==V)throw new j("conflict","HTML overlay timing duration must equal the range's visible output duration.",{actualDurationUs:J.timing.durationUs,expectedDurationUs:V});let[N,G]=await Promise.all(["html"in J.document?Promise.resolve(J.document.html):B4(X.application,J.document,X.abortSignal,BA).then((w)=>Cv0(w.data)),Promise.all(J.resources.map(async(w)=>({...w,absolutePath:(await r1(X.application,w.artifact,X.abortSignal,CA)).absolutePath})))]),D=OQ.parse({canvas:J.canvas,html:N,kind:"slopcamera.html-overlay",libraries:J.libraries,parameters:J.parameters,resources:G.map((w)=>({bytes:w.bytes,mediaType:w.mediaType,name:w.name,sha256:w.sha256,...w.transport===void 0?{}:{transport:w.transport},urlPath:w.urlPath})),schemaVersion:1,seed:J.seed,timing:J.timing}),L=await $5(X),O=await Hv0(px(L.path,"html-overlay-"));try{let w=await Z(m5(H,"html-browser"),X.abortSignal),B=o9(D,w).integrity,C=await K.renderFrames({authoring:D,browserRuntime:w,outputDirectory:O,resources:G},X.abortSignal),U=r9.parse(C.executionIntegrity);if(m(U)!==m(B))throw new j("conflict","HTML-overlay renderer returned integrity evidence that does not match the planned browser execution.");let z=rD.parse(C.libraryLocks),M=D.libraries.map(E3);if(m(z)!==m(M))throw new j("conflict","HTML-overlay renderer returned library locks that do not exactly match the authoring selection.");let T=M6(D.timing);if(C.frameCount!==T)throw new j("conflict","HTML-overlay renderer returned an unexpected frame count.");let q=px(O,"overlay.mov"),E=[F5(H,"ffmpeg"),"-hide_banner","-loglevel","error","-nostdin","-n","-framerate",String(D.timing.fps),"-start_number","0","-i",C.framePattern,"-frames:v",String(C.frameCount),"-an","-c:v","qtrle","-pix_fmt","argb","-movflags","+faststart",q],A=await new X8(l8(X.application,H),X.abortSignal).run(E,{cwd:O,maxOutputBytes:1048576,stdin:"ignore",timeoutMs:3600000});if(A.exitCode!==0)throw new j("invalid-data",`FFmpeg could not encode the HTML overlay: ${A.stderr.slice(0,2000)}`);await Mv0(X.application,H,q,D.canvas,X.abortSignal);let k=await Uv0(q,X.abortSignal);await X.workflow?.beforePublication(),a(X.abortSignal);let P=await Q(W.openProject.directory.path,{command:E,generator:"slopcamera-html-overlay",generatorVersion:F,path:q,sourceSha256:k}),I=px(W.openProject.directory.path,P.path),x=(await r1(X.application,{path:Vv0(X.application.paths.repositoryRoot,I)},X.abortSignal,nx)).artifact,b=await _(F5(H,"ffprobe"),new X8(l8(X.application,H),X.abortSignal),I);if(b.durationUs===null||b.durationUs<=0||b.hasAudio||b.pixelWidth!==D.canvas.width||b.pixelHeight!==D.canvas.height)throw new j("invalid-data","Generated HTML overlay has invalid duration, dimensions, or audio streams.");let y=OV({mediaDurationUs:b.durationUs,outputDurationUs:V,playbackRate:1,sourceInUs:0,sourceOutUs:void 0}),r={asset:{bytes:P.bytes,mediaType:P.mediaType,path:P.path,provenance:P.provenance,sha256:P.sha256},audioPolicy:{kind:"mute"},kind:"video",playback:{audioEndUs:null,audioStartUs:0,audioStreamIndex:null,endBehavior:"hide",playbackRate:1,streamStartUs:b.videoStartUs,videoStreamIndex:b.videoStreamIndex,...y}},g=B5.parse({...J.layout,coordinateSpace:"output-pixels",intrinsicSize:{height:D.canvas.height,width:D.canvas.width},overlayId:Av0(J,D,x.sha256),range:J.range,source:r}),p=ox.parse({artifact:x,browserVersion:n9(H,"html-browser"),createdAt:X.application.clock.now().toISOString(),executionIntegrity:U,exactInputSha256:m(J),ffmpegVersion:n9(H,"ffmpeg"),ffprobeVersion:n9(H,"ffprobe"),frameCount:C.frameCount,kind:"slopcamera.html-overlay-preparation-receipt",libraryLocks:z,libraryLocksSha256:m(z),operationSha256:m(g),overlayId:g.overlayId,projectGenerationSha256:W.generation.generationSha256,projectId:W.project.projectId,schemaVersion:1}),S=await D6({context:X,receipt:p,workspace:L}),i=WY.parse({artifact:x,created:P.created,operation:g,receipt:S});return await g5(X,{inputSchemaId:"slopcamera.operation.media.html-overlay.input/v1",kind:"media.html-overlay",outputSchemaId:"slopcamera.operation.media.html-overlay.output/v1",version:1},i),i}finally{await Wv0(O,{force:!0,recursive:!0}),await L.dispose()}}},outputSchema:WY,outputSchemaId:"slopcamera.operation.media.html-overlay.output/v1",policy:{cache:"exact-run",cancellable:!0,effect:"local-derived-write",maxDurationMs:3600000,maxFanOut:0,maxInputBytes:3145728,maxOutputBytes:2097152,preparation:["project-state","local-media"],resources:[{amount:1,resource:"browser"},{amount:1,resource:"cpu"},{amount:1,resource:"ffmpeg"},{amount:1,resource:"local-io"},{amount:1,resource:"network"},{amount:1,resource:"output-publication"}],resume:"verified-receipt"},receiptReference:(X)=>X.receipt.path,summarize:(X)=>({fields:{bytes:X.artifact.bytes,created:X.created,kind:"html",overlayId:X.operation.overlayId,receipt:X.receipt.path,sha256:X.artifact.sha256},kind:"media.html-overlay"}),version:1}}var uB1=ax();var Rv0=["media.ingest","media.html-overlay","media.overlay","media.audio-effects","media.color-grade"],oB1=Tv0.enum(Rv0);async function O$0($,Q,_,Z=new AbortController().signal){switch(Q){case"media.ingest":return await u40($,NV.parse(_),Z);case"media.overlay":return await cx($,iH.parse(_),Z);case"media.html-overlay":return await ix($,YO.parse(_),Z);case"media.audio-effects":return await f40($,VV.parse(_),Z);case"media.color-grade":return await v40($,GV.parse(_),Z)}}import{z as JO}from"zod";import{lstat as bv0,realpath as B$0}from"fs/promises";import{isAbsolute as Sv0,join as fv0,relative as yv0,sep as xv0}from"path";import{z as S3}from"zod";var UA=4096,tx=4,kv0=16777216,ex=Object.freeze({maximumCount:64,maximumTotalPixels:67108864,maximumTotalSvgBytes:67108864});function L$0($){let Q=1;while(Q<$)Q*=2;return Q}function qv0($){let Q=[],_=0,Z=[],F=0,X=0,Y=0,J=0,H=()=>{if(Z.length===0)return;let K=L$0(X+Y),W=L$0(J),V=W*K;if(Q.length>=ex.maximumCount||_+V>ex.maximumTotalPixels)throw RangeError("Generated caption sprites exceed the cumulative raster resource bound.");Q.push({cards:Z,height:K,width:W}),_+=V,Z=[],F=0,X=0,Y=0,J=0};for(let K of $){let{intrinsicHeight:W,intrinsicWidth:V}=K.rendered;if(V>UA||W>UA)throw RangeError("A social caption card exceeds the sprite dimension bound.");if(F>0&&F+V>UA)F=0,X+=Y+tx,Y=0;if(X>0&&X+W>UA)H();Z.push({...K,x:F,y:X}),F+=V+tx,Y=Math.max(Y,W),J=Math.max(J,F-tx)}return H(),Q}function Ev0($){let Q=$.indexOf(">");if(!$.startsWith(""))throw TypeError("Social caption renderer returned an unsupported SVG document.");return $.slice(Q+1,-6)}function Pv0($){let Q=$.cards.map((F)=>`${Ev0(F.rendered.svg)}`).join(""),_=[``,Q,` `].join(""),Z=Buffer.byteLength(_,"utf8");if(Z>kv0)throw RangeError("A generated caption sprite exceeds the 16 MiB SVG bound.");return{bytes:Z,contents:_}}function Iv0($){let Q=$.overlays.reduce((_,Z)=>Math.max(_,Z.operation.zIndex),-1);if(Q>=Number.MAX_SAFE_INTEGER)throw RangeError("Existing overlay z-index leaves no safe caption layer.");return Q+1}function w$0($){let Q=hX($.plan),_=h.parse($.sourceSha256),Z=pP.parse($.style);if($.cues.length===0)throw TypeError("Captioned render planning requires at least one visible cue.");let F=$.cues.map((V)=>({cue:V,rendered:ue(V,Q.output)})),X=Iv0(Q),Y=[],J=[],H=0;for(let[V,N]of qv0(F).entries()){let{bytes:G,contents:D}=Pv0(N),L=Y0(D);if(H+=G,H>ex.maximumTotalSvgBytes)throw RangeError("Generated caption sprites exceed the cumulative SVG byte bound.");let O=`renders/caption-assets/${L}.svg`,w=`overlay_caption_${m({domain:"slopcamera.social-caption-sprite/v1",sha256:L,sourceSha256:_,spriteIndex:V,style:Z}).slice(0,32)}`,B={asset:{bytes:G,mediaType:"image/svg+xml",path:O,provenance:{command:["slopcamera","caption",Z],generator:"slopcamera-social-caption-sprite",generatorVersion:"1",kind:"generated",sourceSha256:_},sha256:L},kind:"svg"};Y.push({contents:D,path:O,sha256:L});for(let C of N.cards){let U={bottom:(N.height-C.y-C.rendered.intrinsicHeight)/N.height,kind:"normalized-insets",left:C.x/N.width,right:(N.width-C.x-C.rendered.intrinsicWidth)/N.width,top:C.y/N.height},z=B5.parse({anchor:"bottom",crop:U,entrance:{kind:"none"},exit:{kind:"none"},intrinsicSize:{height:N.height,width:N.width},opacity:1,overlayId:w,position:{x:0,y:-C.rendered.bottomSafeMargin},range:C.cue.projectRange,rotationDegrees:0,scale:1,size:{height:C.rendered.intrinsicHeight,kind:"pixels",width:C.rendered.intrinsicWidth},source:B,zIndex:X});J.push({operation:z,outputRange:C.cue.outputRange,playbackOffsetUs:0,projectRange:C.cue.projectRange,visibleDurationUs:C.cue.outputRange.endUs-C.cue.outputRange.startUs})}}let K=mQ.parse({...Q,overlays:[...Q.overlays,...J],planSha256:"0".repeat(64)}),W=hX(mQ.parse({...K,planSha256:Kf(K)}));return{artifacts:Y,plan:W}}var vv0=268435456,C$0=S3.strictObject({background:S3.string().regex(/^#[0-9a-fA-F]{8}$/u).optional(),frameRate:S3.number().finite().positive().max(240).optional()}),hv0=C$0.extend({captions:vK}).strict(),U$0=S3.strictObject({analysisId:vK.shape.analysisId,analysisPath:w0,analysisSha256:h,assetId:x$,placementId:J2,placementSyncSha256:h,streamId:D5,subjectIntegritySha256:h,wordCount:S3.number().int().safe().positive().max(1e6)}),_v=S3.strictObject({eventsSha256:h,manifestSha256:h,placementId:J2,recordingId:P5}),$v=S3.strictObject({metadataBindings:S3.array(_v).max(256).optional(),revision:Ky,settings:C$0.optional()}).superRefine(($,Q)=>{if($.metadataBindings===void 0)return;for(let _=0;_<$.metadataBindings.length;_+=1){let Z=$.metadataBindings[_],F=$.metadataBindings[_-1];if(F!==void 0&&F.placementId.localeCompare(Z.placementId)>=0)Q.addIssue({code:"custom",message:"Render metadata bindings must have unique sorted placement IDs.",path:["metadataBindings",_,"placementId"]})}}),Qv=S3.strictObject({captionBinding:U$0.optional(),metadataBindings:S3.array(_v).max(256).optional(),revision:Ky,settings:hv0}).superRefine(($,Q)=>{if($.metadataBindings===void 0)return;for(let _=0;_<$.metadataBindings.length;_+=1){let Z=$.metadataBindings[_],F=$.metadataBindings[_-1];if(F!==void 0&&F.placementId.localeCompare(Z.placementId)>=0)Q.addIssue({code:"custom",message:"Render metadata bindings must have unique sorted placement IDs.",path:["metadataBindings",_,"placementId"]})}}),z$0=H8;function gv0($){return m({...$,domain:"slopcamera.social-caption-source/v1"})}function mv0($,Q){let _=yv0($,Q);return _===""||_!==".."&&!_.startsWith(`..${xv0}`)&&!Sv0(_)}async function wV($,Q){let _;try{_=await B$0($.paths.projectRoot)}catch{throw new j("not-found","The project root does not exist.")}let Z=fv0(_,Q),F;try{F=await bv0(Z)}catch{throw new j("not-found",`Project does not exist: ${Q}`)}if(F.isSymbolicLink()||!F.isDirectory())throw new j("unsafe-path",`Project must be a physical directory: ${Q}`);let X=await B$0(Z);if(!mv0(_,X)||X===_)throw new j("unsafe-path",`Project directory escapes the configured project root: ${Q}`);return X}function uv0($){return U6.parse({artifact:$.artifact,baseGeneration:$.baseGeneration,kind:$.kind,outputGeometrySha256:$.outputGeometrySha256,pixelHeight:$.pixelHeight,pixelWidth:$.pixelWidth,planId:$.planId,projectEditPlanSha256:$.projectEditPlanSha256,projectId:$.projectId,projectSha256:$.projectSha256,projectStructureSha256:$.projectStructureSha256,revisionSha256:$.revisionSha256,schemaVersion:$.schemaVersion})}function Zv($,Q){try{return JSON.parse($)}catch{throw new j("invalid-data",`${Q} is not valid JSON.`)}}function Fv($){return new TextEncoder().encode($).byteLength}async function zA($,Q){let _=uv0(Q),Z=await wV($,_.projectId),F=x0(Z),X=await F.readText(_.artifact.path);if(Fv(X)!==_.artifact.bytes||Y0(X)!==_.artifact.sha256)throw new j("conflict","Immutable project edit revision artifact failed its byte and SHA-256 identity.");let Y=L9.parse(Zv(X,"Project edit revision artifact"));if(X!==`${R(Y)} `)throw new j("conflict","Immutable project edit revision artifact is not its canonical document.");if(Y.project.projectId!==_.projectId||Y.projectEditPlan.planId!==_.planId||Y.projectSha256!==_.projectSha256||Y.projectEditPlanSha256!==_.projectEditPlanSha256||Y.revisionSha256!==_.revisionSha256||H2(Y.project)!==_.projectStructureSha256)throw new j("conflict","Immutable project edit revision reference does not match its frozen documents.");return{directory:Z,document:Y,fileSystem:F,reference:_}}function M$0($,Q,_){return{...$?.background===void 0?{}:{background:$.background},...$?.frameRate===void 0?{}:{frameRate:$.frameRate},metadata:_,pixelHeight:Q.pixelHeight,pixelWidth:Q.pixelWidth}}async function MA($,Q,_){let Z=new Set(_.zooms.map((X)=>X.placementId));if((_.effects.clicks.enabled||_.effects.cursor.enabled||_.effects.keystrokes.enabled||_.effects.typedText.enabled)&&_.effects.metadataPlacementId!==null)Z.add(_.effects.metadataPlacementId);let F=await Promise.all([...Z].sort().map(async(X)=>{let Y=Q.placements.find((W)=>W.placementId===X);if(Y===void 0)throw new j("not-found",`Unknown project metadata placement: ${X}`);let J=Q.assets.find((W)=>W.assetId===Y.assetId);if(J?.source.kind!=="recording")throw new j("conflict",`Placement ${Y.placementId} is not backed by a Slopcamera recording with window and input metadata.`);let H=await M$($,J.source.recordingId),K=await tZ(H);return{binding:_v.parse({eventsSha256:m(K),manifestSha256:m(H.manifest),placementId:Y.placementId,recordingId:J.source.recordingId}),context:{events:K,manifest:H.manifest,placementId:Y.placementId}}}));return{bindings:F.map((X)=>X.binding),contexts:F.map((X)=>X.context)}}async function A$0($,Q){let _=vK.parse(Q),Z=$.document.project,F=Z.analyses.find((N)=>N.kind==="speech"&&N.analysisId===_.analysisId);if(F===void 0||F.kind!=="speech")throw new j("not-found",`Unknown project speech analysis: ${_.analysisId}`);let X=Z.placements.find((N)=>N.placementId===_.placementId);if(X===void 0)throw new j("not-found",`Unknown caption placement: ${_.placementId}`);if(!X.enabled||X.assetId!==F.assetId)throw new j("conflict","Caption placement must be enabled and contain the analyzed audio asset.");if(X.audio.find((N)=>N.streamId===F.streamId)?.presentation.enabled!==!0)throw new j("conflict","Caption source audio must be enabled and audible on the selected placement.");let J=Z.assets.find((N)=>N.assetId===F.assetId),H=J?.streams.find((N)=>N.streamId===F.streamId);if(J===void 0||H?.kind!=="audio")throw new j("conflict","Caption speech analysis no longer identifies a project audio stream.");let K,W;try{K=await $.fileSystem.readText(F.path),W=I8.parse(Zv(K,"Speech analysis artifact"))}catch(N){if(N instanceof j)throw N;throw new j("invalid-data",`Speech analysis ${F.analysisId} is unreadable or invalid.`)}if(K!==`${R(W)} `||Y0(K)!==F.sha256||W.analysisId!==F.analysisId||W.subject.assetId!==F.assetId||W.subject.streamId!==F.streamId||W.durationUs!==J.durationUs)throw new j("conflict",`Speech analysis ${F.analysisId} is stale or failed its exact identity check.`);let V=m({assetDurationUs:J.durationUs,stream:H});if(W.subject.integritySha256!==V)throw new j("conflict",`Speech analysis ${F.analysisId} no longer matches its audio stream.`);if(W.result.status!=="transcribed"||W.result.words.length===0)throw new j("unsupported-plan","Caption export requires a speech analysis with timed words.");if(F.wordCount!==W.result.words.length||F.fillerCount!==W.result.fillers.length)throw new j("invalid-data",`Speech analysis reference ${F.analysisId} disagrees with its artifact counts.`);return{analysis:W,binding:U$0.parse({analysisId:F.analysisId,analysisPath:F.path,analysisSha256:F.sha256,assetId:F.assetId,placementId:X.placementId,placementSyncSha256:S5(X),streamId:F.streamId,subjectIntegritySha256:V,wordCount:W.result.words.length})}}async function AA($,Q){let _=$v.parse(Q),Z=await zA($,_.revision),F=await MA($.paths.artifactRoot,Z.document.project,Z.document.projectEditPlan);return $v.parse({..._,metadataBindings:F.bindings})}async function T$0($,Q){let _=Qv.parse(Q),Z=await zA($,_.revision),[F,X]=await Promise.all([MA($.paths.artifactRoot,Z.document.project,Z.document.projectEditPlan),A$0(Z,_.settings.captions)]);return Qv.parse({..._,captionBinding:X.binding,metadataBindings:F.bindings})}function lv0($,Q,_){return hD.parse({kind:"slopcamera.project-render-plan-document",outputGeometrySha256:_.outputGeometrySha256,plan:hX($),projectEditPlanSha256:Q.projectEditPlanSha256,projectSha256:Q.projectSha256,renderPlanSha256:m($),revisionSha256:Q.revisionSha256,schemaVersion:1})}async function GF($,Q){let _=H8.parse(Q),Z=await wV($,_.projectId),F=x0(Z),X=await F.readText(_.artifact.path);if(Fv(X)!==_.artifact.bytes||Y0(X)!==_.artifact.sha256)throw new j("conflict","Immutable project render plan artifact failed its byte and SHA-256 identity.");let Y=hD.parse(Zv(X,"Project render plan artifact"));if(X!==`${R(Y)} @@ -2097,7 +2097,7 @@ ${H}${K}trailer startxref ${J} %%EOF -`);let W=Buffer.from(X.join(""));if(W.length>33554432)throw Error("Drawing PDF exceeds output byte limit");return W}var YL="3.5.0";var Q_0="patent-line-art-v1",dT=1048576,jg=9.070866141732283;class sT extends Error{constructor($){super(`Invalid drawing source: ${$}`);this.name="DrawingValidationError"}}function E2($){throw new sT($)}var pT=($)=>ad0("sha256").update($).digest("hex"),aQ0=($)=>Fc0($)?$:Xc0(new URL($,import.meta.url)),Dg=[aQ0(sA),aQ0(jY)],Jc0={background:"#ffffff",foreground:"#000000",muted:"#000000",stroke:"#000000",tones:Object.fromEntries(["neutral","blue","orange","green","red","purple","yellow"].map(($)=>[$,{fill:"#ffffff",stroke:"#000000",text:"#000000"}]))},Hc0={font:{family:"Nebula Sans",files:[{path:Dg[0],weight:400},{path:Dg[1],weight:700}]},theme:{light:Jc0}},Kc0=($)=>$.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""");function Lg($){if($!=="us-letter"&&$!=="a4")E2("paper must be us-letter or a4");let Q=$==="us-letter"?612:595.2755905511812,_=$==="us-letter"?792:841.8897637795276,Z={left:70.86614173228347,top:70.86614173228347,right:42.51968503937008,bottom:28.34645669291339};return{width:Q,height:_,margins:Z,numberingHeight:30,body:{x:Z.left,y:Z.top+30,width:Q-Z.left-Z.right,height:_-Z.top-Z.bottom-60}}}function kF($,Q,_){if(typeof $!=="object"||$===null||Array.isArray($))E2(`${_} must be an object`);let Z=$;for(let F of Object.keys(Z))if(!Q.includes(F))E2(`${_}.${F} is unsupported`);return Z}function Wc0($){let Q=kF($,["$schema","version","name","canvas","layout","shapes","edges"],"diagram"),_=(Z)=>{for(let F of Object.values(Z)){if(typeof F==="number"&&(!Number.isFinite(F)||Math.abs(F)>1e4))E2("numeric drawing values must be finite and within 10000 points");if(typeof F==="string"&&F.length>1024)E2("drawing strings exceed the bounded text limit")}};if(_(Q),_(kF(Q.canvas,["width","height","padding"],"canvas")),Q.layout!==void 0)_(kF(Q.layout,["type","direction","gap","align"],"layout"));if(!Array.isArray(Q.shapes)||Q.shapes.length<1||Q.shapes.length>100)E2("each sheet needs 1 to 100 shapes");for(let Z of Q.shapes){let F=kF(Z,["id","type","x","y","tone","opacity","width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap","text","fontSize","fontFamily","weight","align","x2","y2"],"shape");_(F);let X=["id","type","x","y","tone","opacity"],Y=F.type==="text"?["text","width","fontSize","fontFamily","weight","align"]:F.type==="line"?["x2","y2","strokeWidth"]:["width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap"];if(kF(Z,[...X,...Y],"shape"),F.labelRows!==void 0){if(!Array.isArray(F.labelRows)||F.labelRows.length>4)E2("labelRows must be bounded");for(let J of F.labelRows)_(kF(J,["text","fontSize","fontFamily","weight"],"label row"))}for(let J of["label","text"])if(typeof F[J]==="string"&&F[J].length>500)E2("label exceeds text limit")}if(Q.edges!==void 0){if(!Array.isArray(Q.edges)||Q.edges.length>150)E2("at most 150 edges are supported");for(let Z of Q.edges)_(kF(Z,["id","from","to","label","tone","start","end","bend","arrowhead","startPosition","endPosition","labelFontSize","labelFontFamily","labelWeight","labelPosition","labelOffset"],"edge"))}}function nT($){let Q=kF($,["$schema","version","name","title","paper","sheets"],"drawing");if(Q.version!==1)E2("version must be 1");if(typeof Q.name!=="string"||Q.name.length>100||!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(Q.name))E2("name must be a bounded lowercase hyphenated name");if(Q.paper!=="us-letter"&&Q.paper!=="a4")E2("paper must be us-letter or a4");if(Q.title!==void 0&&(typeof Q.title!=="string"||Q.title.length<1||Buffer.byteLength(Q.title)>1024||/[\u0000-\u001f]/u.test(Q.title)))E2("title must be a bounded metadata string");if(Q.$schema!==void 0&&typeof Q.$schema!=="string")E2("$schema must be a string");if(!Array.isArray(Q.sheets)||Q.sheets.length<1||Q.sheets.length>20)E2("sheets must contain 1 to 20 sheets");let _=Q.sheets.map((F,X)=>{let Y=kF(F,["figure","diagram"],`sheets[${X}]`);if(Y.figure!==X+1)E2("figure numbers must be consecutive beginning at 1");Wc0(Y.diagram);let J=MO(Y.diagram),H=A6(J);if(H.shapes.length<1||H.shapes.length>100||(H.edges?.length??0)>150)E2("each sheet needs 1 to 100 shapes and at most 150 edges");return{figure:X+1,diagram:J}}),Z={version:1,name:Q.name,paper:Q.paper,sheets:_,...Q.title===void 0?{}:{title:Q.title},...Q.$schema===void 0?{}:{$schema:Q.$schema}};if(Buffer.byteLength(JSON.stringify(Z))>dT)E2("source exceeds 1MiB byte limit");return Z}function cT($){return new Yc0($,{font:{fontFiles:Dg,loadSystemFonts:!1,defaultFontFamily:"Nebula Sans"},logLevel:"off"})}function Og($){let Q=$.getBBox();if(Q===void 0)E2("empty drawing ink");return{x:Q.x,y:Q.y,width:Q.width,height:Q.height}}function tQ0($,Q,_){if($.xQ.x+Q.width+0.01||$.y+$.height>Q.y+Q.height+0.01)E2(`${_} ink extends beyond its bounds`)}async function eQ0($){return(await U9($,"light",Hc0,{edgeStrokeWidth:1})).svg.replace('',"")}function __0($,Q,_){let Z=`${Kc0($)}`;return Og(cT(Z)).height}function Vc0($,Q){let _=1/0,Z=(F,X,Y,J)=>{if(F.length<1||F.length>500||!Array.from(F).every((H)=>/^[A-Z0-9 \n]$/u.test(H)||".,:;()[]/+=_*'!?%-".includes(H)))E2("visible labels must be uppercase ASCII letters, numbers, spaces, or supported punctuation; labels are never rewritten");if(J!==void 0&&J!=="default")E2("only the bundled default font is supported");if(!Number.isFinite(X)||X<=0||X>18)E2("authored font size must be positive and at most 18 points, below the 20 point sheet numbering");for(let H of new Set(F.match(/[A-Z0-9]/gu)??[])){let K=`${H}:${X}:${Y}`,W=Q.get(K)??__0(H,X,Y);if(Q.set(K,W),Q.size>4096)E2("glyph measurement limit exceeded");if(_=Math.min(_,W),W+0.0014)E2("stroke width must be 0.5 to 4 points");for(let X of DY(F).rows)Z(X.text,X.fontSize,X.weight,X.fontFamily)}else if(F.type==="text")Z(F.text,F.fontSize??24,F.weight??500,F.fontFamily);else if((F.strokeWidth??3)<0.5||(F.strokeWidth??3)>4)E2("stroke width must be 0.5 to 4 points")}for(let F of $.edges??[]){if(F.tone!==void 0&&F.tone!=="neutral")E2("colored edge tones are unsupported");if(F.label!==void 0)Z(F.label,F.labelFontSize??18,F.labelWeight??600,F.labelFontFamily)}return _}async function rT($,Q){let _=nT($),Z=Q??pT(JSON.stringify(_));if(!/^[a-f0-9]{64}$/u.test(Z))E2("source SHA-256 is invalid");let F=Lg(_.paper),X=[],Y=new Map,J=1/0;for(let K of _.sheets){let W=A6(K.diagram);if(W.canvas.width>F.body.width+0.001||W.canvas.height>F.body.height+0.001)E2(`figure ${K.figure} canvas exceeds ${F.body.width.toFixed(3)} by ${F.body.height.toFixed(3)}pt body; no automatic scaling is performed`);J=Math.min(J,Vc0(W,Y));let V=await eQ0(W);tQ0(Og(cT(V)),{x:0,y:0,width:W.canvas.width,height:W.canvas.height},`figure ${K.figure}`);for(let B of W.shapes)if((B.type==="rect"||B.type==="ellipse")&&(B.label!==void 0||B.labelRows!==void 0)){let C=(B.strokeWidth??2)/2,U=await eQ0({...W,shapes:[B],edges:[]});tQ0(Og(cT(U)),{x:B.x-C,y:B.y-C,width:B.width+C*2,height:B.height+C*2},`shape ${B.id} label`)}let N=V.replace(/^]*>/u,"").replace(/<\/svg>$/u,""),G=F.body.x+(F.body.width-W.canvas.width)/2,D=`${K.figure}/${_.sheets.length}`,L=_.sheets.length===1?"":`FIG. ${K.figure}`,O=`${D}${N}${L}`,w=cT(O).toString().replace(/width="[^"]+" height="[^"]+" viewBox="[^"]+"/u,`width="${F.width}pt" height="${F.height}pt" viewBox="0 0 ${F.width} ${F.height}"`);if(Buffer.byteLength(w)>2097152)E2("sheet SVG exceeds output byte limit");X.push({svg:w,width:F.width,height:F.height,figure:K.figure})}for(let K of"FIG0123456789")J=Math.min(J,__0(K,20,400));if(J+0.001dT)E2("source exceeds 1MiB byte limit");let Y=Buffer.alloc(dT+1),J=0;while(JdT)E2("source exceeds 1MiB byte limit");Z=Y.subarray(0,J)}finally{await _.close()}let F=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(Z));return{absolutePath:Q,source:nT(F),sourceSha256:pT(Z)}}async function Z_0($){let{source:Q,sourceSha256:_}=await oT($.filePath);return(await rT(Q,_)).checks}async function Ng($,Q){let _=`${$}.tmp-${process.pid}-${crypto.randomUUID()}`;try{await _c0(_,Q),await $c0(_,$)}catch(Z){throw await Qc0(_,{force:!0}),Z}}async function F_0($){let{absolutePath:Q,source:_,sourceSha256:Z}=await oT($.filePath),F=await rT(_,Z),X=$_0($.outDirectory??Zc0(Q)),Y={source:Q,pdf:Gg(X,`${_.name}.pdf`),sheets:F.sheets.map((H,K)=>Gg(X,`${_.name}.sheet-${String(K+1).padStart(3,"0")}.svg`)),receipt:Gg(X,`${_.name}.drawing-receipt.json`)},J={version:1,profile:Q_0,rendererVersion:YL,sourceSha256:Z,paper:_.paper,minGlyphHeightPt:F.checks.minGlyphHeightPt,sheets:F.sheets.map((H)=>({figure:H.figure,widthPt:H.width,heightPt:H.height,sha256:pT(H.svg)})),pdfSha256:pT(F.pdf)};await td0(X,{recursive:!0});for(let[H,K]of F.sheets.entries())await Ng(Y.sheets[H],K.svg);return await Ng(Y.pdf,F.pdf),await Ng(Y.receipt,`${JSON.stringify(J,null,2)} +`);let W=Buffer.from(X.join(""));if(W.length>33554432)throw Error("Drawing PDF exceeds output byte limit");return W}var YL="3.6.0";var Q_0="patent-line-art-v1",dT=1048576,jg=9.070866141732283;class sT extends Error{constructor($){super(`Invalid drawing source: ${$}`);this.name="DrawingValidationError"}}function E2($){throw new sT($)}var pT=($)=>ad0("sha256").update($).digest("hex"),aQ0=($)=>Fc0($)?$:Xc0(new URL($,import.meta.url)),Dg=[aQ0(sA),aQ0(jY)],Jc0={background:"#ffffff",foreground:"#000000",muted:"#000000",stroke:"#000000",tones:Object.fromEntries(["neutral","blue","orange","green","red","purple","yellow"].map(($)=>[$,{fill:"#ffffff",stroke:"#000000",text:"#000000"}]))},Hc0={font:{family:"Nebula Sans",files:[{path:Dg[0],weight:400},{path:Dg[1],weight:700}]},theme:{light:Jc0}},Kc0=($)=>$.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""");function Lg($){if($!=="us-letter"&&$!=="a4")E2("paper must be us-letter or a4");let Q=$==="us-letter"?612:595.2755905511812,_=$==="us-letter"?792:841.8897637795276,Z={left:70.86614173228347,top:70.86614173228347,right:42.51968503937008,bottom:28.34645669291339};return{width:Q,height:_,margins:Z,numberingHeight:30,body:{x:Z.left,y:Z.top+30,width:Q-Z.left-Z.right,height:_-Z.top-Z.bottom-60}}}function kF($,Q,_){if(typeof $!=="object"||$===null||Array.isArray($))E2(`${_} must be an object`);let Z=$;for(let F of Object.keys(Z))if(!Q.includes(F))E2(`${_}.${F} is unsupported`);return Z}function Wc0($){let Q=kF($,["$schema","version","name","canvas","layout","shapes","edges"],"diagram"),_=(Z)=>{for(let F of Object.values(Z)){if(typeof F==="number"&&(!Number.isFinite(F)||Math.abs(F)>1e4))E2("numeric drawing values must be finite and within 10000 points");if(typeof F==="string"&&F.length>1024)E2("drawing strings exceed the bounded text limit")}};if(_(Q),_(kF(Q.canvas,["width","height","padding"],"canvas")),Q.layout!==void 0)_(kF(Q.layout,["type","direction","gap","align"],"layout"));if(!Array.isArray(Q.shapes)||Q.shapes.length<1||Q.shapes.length>100)E2("each sheet needs 1 to 100 shapes");for(let Z of Q.shapes){let F=kF(Z,["id","type","x","y","tone","opacity","width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap","text","fontSize","fontFamily","weight","align","x2","y2"],"shape");_(F);let X=["id","type","x","y","tone","opacity"],Y=F.type==="text"?["text","width","fontSize","fontFamily","weight","align"]:F.type==="line"?["x2","y2","strokeWidth"]:["width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap"];if(kF(Z,[...X,...Y],"shape"),F.labelRows!==void 0){if(!Array.isArray(F.labelRows)||F.labelRows.length>4)E2("labelRows must be bounded");for(let J of F.labelRows)_(kF(J,["text","fontSize","fontFamily","weight"],"label row"))}for(let J of["label","text"])if(typeof F[J]==="string"&&F[J].length>500)E2("label exceeds text limit")}if(Q.edges!==void 0){if(!Array.isArray(Q.edges)||Q.edges.length>150)E2("at most 150 edges are supported");for(let Z of Q.edges)_(kF(Z,["id","from","to","label","tone","start","end","bend","arrowhead","startPosition","endPosition","labelFontSize","labelFontFamily","labelWeight","labelPosition","labelOffset"],"edge"))}}function nT($){let Q=kF($,["$schema","version","name","title","paper","sheets"],"drawing");if(Q.version!==1)E2("version must be 1");if(typeof Q.name!=="string"||Q.name.length>100||!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(Q.name))E2("name must be a bounded lowercase hyphenated name");if(Q.paper!=="us-letter"&&Q.paper!=="a4")E2("paper must be us-letter or a4");if(Q.title!==void 0&&(typeof Q.title!=="string"||Q.title.length<1||Buffer.byteLength(Q.title)>1024||/[\u0000-\u001f]/u.test(Q.title)))E2("title must be a bounded metadata string");if(Q.$schema!==void 0&&typeof Q.$schema!=="string")E2("$schema must be a string");if(!Array.isArray(Q.sheets)||Q.sheets.length<1||Q.sheets.length>20)E2("sheets must contain 1 to 20 sheets");let _=Q.sheets.map((F,X)=>{let Y=kF(F,["figure","diagram"],`sheets[${X}]`);if(Y.figure!==X+1)E2("figure numbers must be consecutive beginning at 1");Wc0(Y.diagram);let J=MO(Y.diagram),H=A6(J);if(H.shapes.length<1||H.shapes.length>100||(H.edges?.length??0)>150)E2("each sheet needs 1 to 100 shapes and at most 150 edges");return{figure:X+1,diagram:J}}),Z={version:1,name:Q.name,paper:Q.paper,sheets:_,...Q.title===void 0?{}:{title:Q.title},...Q.$schema===void 0?{}:{$schema:Q.$schema}};if(Buffer.byteLength(JSON.stringify(Z))>dT)E2("source exceeds 1MiB byte limit");return Z}function cT($){return new Yc0($,{font:{fontFiles:Dg,loadSystemFonts:!1,defaultFontFamily:"Nebula Sans"},logLevel:"off"})}function Og($){let Q=$.getBBox();if(Q===void 0)E2("empty drawing ink");return{x:Q.x,y:Q.y,width:Q.width,height:Q.height}}function tQ0($,Q,_){if($.xQ.x+Q.width+0.01||$.y+$.height>Q.y+Q.height+0.01)E2(`${_} ink extends beyond its bounds`)}async function eQ0($){return(await U9($,"light",Hc0,{edgeStrokeWidth:1})).svg.replace('',"")}function __0($,Q,_){let Z=`${Kc0($)}`;return Og(cT(Z)).height}function Vc0($,Q){let _=1/0,Z=(F,X,Y,J)=>{if(F.length<1||F.length>500||!Array.from(F).every((H)=>/^[A-Z0-9 \n]$/u.test(H)||".,:;()[]/+=_*'!?%-".includes(H)))E2("visible labels must be uppercase ASCII letters, numbers, spaces, or supported punctuation; labels are never rewritten");if(J!==void 0&&J!=="default")E2("only the bundled default font is supported");if(!Number.isFinite(X)||X<=0||X>18)E2("authored font size must be positive and at most 18 points, below the 20 point sheet numbering");for(let H of new Set(F.match(/[A-Z0-9]/gu)??[])){let K=`${H}:${X}:${Y}`,W=Q.get(K)??__0(H,X,Y);if(Q.set(K,W),Q.size>4096)E2("glyph measurement limit exceeded");if(_=Math.min(_,W),W+0.0014)E2("stroke width must be 0.5 to 4 points");for(let X of DY(F).rows)Z(X.text,X.fontSize,X.weight,X.fontFamily)}else if(F.type==="text")Z(F.text,F.fontSize??24,F.weight??500,F.fontFamily);else if((F.strokeWidth??3)<0.5||(F.strokeWidth??3)>4)E2("stroke width must be 0.5 to 4 points")}for(let F of $.edges??[]){if(F.tone!==void 0&&F.tone!=="neutral")E2("colored edge tones are unsupported");if(F.label!==void 0)Z(F.label,F.labelFontSize??18,F.labelWeight??600,F.labelFontFamily)}return _}async function rT($,Q){let _=nT($),Z=Q??pT(JSON.stringify(_));if(!/^[a-f0-9]{64}$/u.test(Z))E2("source SHA-256 is invalid");let F=Lg(_.paper),X=[],Y=new Map,J=1/0;for(let K of _.sheets){let W=A6(K.diagram);if(W.canvas.width>F.body.width+0.001||W.canvas.height>F.body.height+0.001)E2(`figure ${K.figure} canvas exceeds ${F.body.width.toFixed(3)} by ${F.body.height.toFixed(3)}pt body; no automatic scaling is performed`);J=Math.min(J,Vc0(W,Y));let V=await eQ0(W);tQ0(Og(cT(V)),{x:0,y:0,width:W.canvas.width,height:W.canvas.height},`figure ${K.figure}`);for(let B of W.shapes)if((B.type==="rect"||B.type==="ellipse")&&(B.label!==void 0||B.labelRows!==void 0)){let C=(B.strokeWidth??2)/2,U=await eQ0({...W,shapes:[B],edges:[]});tQ0(Og(cT(U)),{x:B.x-C,y:B.y-C,width:B.width+C*2,height:B.height+C*2},`shape ${B.id} label`)}let N=V.replace(/^]*>/u,"").replace(/<\/svg>$/u,""),G=F.body.x+(F.body.width-W.canvas.width)/2,D=`${K.figure}/${_.sheets.length}`,L=_.sheets.length===1?"":`FIG. ${K.figure}`,O=`${D}${N}${L}`,w=cT(O).toString().replace(/width="[^"]+" height="[^"]+" viewBox="[^"]+"/u,`width="${F.width}pt" height="${F.height}pt" viewBox="0 0 ${F.width} ${F.height}"`);if(Buffer.byteLength(w)>2097152)E2("sheet SVG exceeds output byte limit");X.push({svg:w,width:F.width,height:F.height,figure:K.figure})}for(let K of"FIG0123456789")J=Math.min(J,__0(K,20,400));if(J+0.001dT)E2("source exceeds 1MiB byte limit");let Y=Buffer.alloc(dT+1),J=0;while(JdT)E2("source exceeds 1MiB byte limit");Z=Y.subarray(0,J)}finally{await _.close()}let F=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(Z));return{absolutePath:Q,source:nT(F),sourceSha256:pT(Z)}}async function Z_0($){let{source:Q,sourceSha256:_}=await oT($.filePath);return(await rT(Q,_)).checks}async function Ng($,Q){let _=`${$}.tmp-${process.pid}-${crypto.randomUUID()}`;try{await _c0(_,Q),await $c0(_,$)}catch(Z){throw await Qc0(_,{force:!0}),Z}}async function F_0($){let{absolutePath:Q,source:_,sourceSha256:Z}=await oT($.filePath),F=await rT(_,Z),X=$_0($.outDirectory??Zc0(Q)),Y={source:Q,pdf:Gg(X,`${_.name}.pdf`),sheets:F.sheets.map((H,K)=>Gg(X,`${_.name}.sheet-${String(K+1).padStart(3,"0")}.svg`)),receipt:Gg(X,`${_.name}.drawing-receipt.json`)},J={version:1,profile:Q_0,rendererVersion:YL,sourceSha256:Z,paper:_.paper,minGlyphHeightPt:F.checks.minGlyphHeightPt,sheets:F.sheets.map((H)=>({figure:H.figure,widthPt:H.width,heightPt:H.height,sha256:pT(H.svg)})),pdfSha256:pT(F.pdf)};await td0(X,{recursive:!0});for(let[H,K]of F.sheets.entries())await Ng(Y.sheets[H],K.svg);return await Ng(Y.pdf,F.pdf),await Ng(Y.receipt,`${JSON.stringify(J,null,2)} `),{artifacts:Y,checks:F.checks,receipt:J}}function X_0(){return{$schema:"https://raw.githubusercontent.com/hraness/slopcamera/main/schema/drawing.schema.json",version:1,name:"sensor-control",title:"Fictional sensor and controller drawings",paper:"us-letter",sheets:[{figure:1,diagram:{version:1,name:"sensor-system",canvas:{width:480,height:500},shapes:[{id:"sensor",type:"rect",x:105,y:40,width:280,height:100,radius:0,label:"SENSOR 100",labelFontSize:16},{id:"controller",type:"rect",x:105,y:280,width:280,height:100,radius:0,label:"CONTROLLER 200",labelFontSize:16}],edges:[{id:"signal",from:"sensor",to:"controller",label:"SIGNAL",labelFontSize:16}]}},{figure:2,diagram:{version:1,name:"control-flow",canvas:{width:480,height:500},shapes:[{id:"receive",type:"rect",x:105,y:40,width:280,height:100,radius:0,label:"RECEIVE SIGNAL 210",labelFontSize:16},{id:"actuate",type:"rect",x:105,y:280,width:280,height:100,radius:0,label:"SET OUTPUT 220",labelFontSize:16}],edges:[{id:"next",from:"receive",to:"actuate"}]}}]}}import{randomUUID as Yp0}from"crypto";import{mkdir as Jp0,readFile as Hp0,rename as Kp0,rm as Wp0,writeFile as Vp0}from"fs/promises";import{dirname as v_0,join as eV,resolve as h_0}from"path";mV();FL();MQ();import{createHash as zc0,randomBytes as j_0}from"crypto";import{chmodSync as Mc0,closeSync as a9,constants as TY,fchmodSync as Ac0,fstatSync as d3,ftruncateSync as Tc0,fsyncSync as D_0,lstatSync as C7,mkdirSync as Rc0,openSync as Ug,readSync as kc0,readdirSync as O_0,realpathSync as qc0,renameSync as Ec0,statSync as Pc0,unlinkSync as tT,writeSync as Ic0}from"fs";import{availableParallelism as bc0,homedir as Sc0}from"os";import{isAbsolute as zg,join as l3}from"path";import{performance as VL}from"perf_hooks";import{readFileSync as Gc0}from"fs";import{createRequire as Nc0}from"module";var jc0=2,Dc0=4,Oc0=8,H_0=4,aV,Y_0=[],Lc0=Nc0(import.meta.url);function wc0(){return Lc0("bun:ffi")}function J_0($,Q=process.arch){let _=[],Z=(F)=>{if(!_.includes(F))_.push(F)};for(let F of $.split(` `)){let X=F.indexOf("/");if(X<0||F.endsWith(" (deleted)"))continue;let Y=F.slice(X).replace(/\\([0-7]{3})/gu,(J,H)=>String.fromCodePoint(Number.parseInt(H,8)));if(/\/(?:libc(?:-[^/]+)?\.so(?:\.[0-9]+)*|libc\.musl-[^/]+\.so(?:\.[0-9]+)*|ld-musl-[^/]+\.so(?:\.[0-9]+)*)$/u.test(Y))Z(Y)}if(Z("libc.so.6"),Q==="x64")Z("/lib/ld-musl-x86_64.so.1");if(Q==="arm64")Z("/lib/ld-musl-aarch64.so.1");return _}function Bc0(){try{return J_0(Gc0("/proc/self/maps","utf8"))}catch{return J_0("")}}function K_0(){if(aV!==void 0)return aV;let{dlopen:$,FFIType:Q,read:_}=wc0();if(process.platform==="darwin"){let Z=$("/usr/lib/libSystem.B.dylib",{__error:{args:[],returns:Q.ptr},flock:{args:[Q.i32,Q.i32],returns:Q.i32}});return Y_0.push(Z),aV={errnoLocation:Z.symbols.__error,flock:Z.symbols.flock,readInt32:_.i32},aV}if(process.platform==="linux"){let Z=[];for(let F of Bc0())try{let X=$(F,{__errno_location:{args:[],returns:Q.ptr},flock:{args:[Q.i32,Q.i32],returns:Q.i32}});return Y_0.push(X),aV={errnoLocation:X.symbols.__errno_location,flock:X.symbols.flock,readInt32:_.i32},aV}catch(X){Z.push(`${F}: ${X instanceof Error?X.message:String(X)}`)}throw Error(`Slopcamera could not load host flock support (${Z.join("; ")}).`)}throw Error(`Slopcamera host-resource coordination is unsupported on ${process.platform}.`)}function W_0($){let Q=$.errnoLocation();if(Q===null)throw Error("Slopcamera could not read the host flock error.");return $.readInt32(Q)}function Cc0($){return process.platform==="darwin"?$===35:$===11}var Uc0=Object.freeze(["darwin","linux"]);function iT($){return Uc0.some((Q)=>Q===$)}function JL($){let Q=K_0();for(;;){if(Q.flock($,jc0|Dc0)===0)return!0;let _=W_0(Q);if(_===H_0)continue;if(Cc0(_))return!1;throw Error(`Slopcamera host-resource flock failed with errno ${_}.`)}}function HL($){let Q=K_0();for(;;){if(Q.flock($,Oc0)===0)return;let _=W_0(Q);if(_===H_0)continue;throw Error(`Slopcamera host-resource unlock failed with errno ${_}.`)}}var fc0=/^[a-z0-9][a-z0-9._/-]{0,119}$/u,yc0=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u,xc0=/^[0-9a-f]{32}$/u,L_0=/^[1-9][0-9]{0,19}$/u,Mg=/^lease-([0-9]{20})-([0-9a-f]{32})\.lock$/u,vc0=/^\.host-resources-[0-9a-f]{32}\.tmp$/u,Ag="state.json",w_0="control.lock",B_0="initialized.lock",V_0=64,hc0=64,gc0=1024,C_0=65536,U_0=4096,z_0=1e6,Tg=0xffff_ffff_ffff_ffffn,M_0=25,A_0=35000,mc0=250,uc0=4,G_0=8,TQ=86400000,dq1=Object.freeze(["cpu","local-io","ffmpeg","video-encode","vision","whisper","network","paid-call","browser","capture-device"]);class P2 extends Error{code;constructor($,Q,_){super(`[${$}] ${Q}`,_===void 0?void 0:{cause:_});this.name="HostResourceError",this.code=$}}function GL($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function eT($,Q){let _=Object.keys($).sort(),Z=[...Q].sort();return _.length===Z.length&&_.every((F,X)=>F===Z[X])}function Rg($,Q){return Number.isSafeInteger($)&&$>=1&&$<=Q}function kg($){if(typeof $!=="object"||$===null||Object.isFrozen($))return $;for(let Q of Object.values($))kg(Q);return Object.freeze($)}function T_0($,Q,_){let Z=_==="INVALID_CLAIMS"?0:1;if(!Array.isArray($)||$.lengthV_0)throw new P2(_,`Host-resource ${Q==="limit"?"capacities":"claims"} must contain ${Z} through ${V_0} entries.`);let F=new Set;return $.map((Y)=>{if(!GL(Y)||!eT(Y,["resource",Q])||typeof Y.resource!=="string"||!yc0.test(Y.resource)||!Rg(Y[Q],z_0)||F.has(Y.resource))throw new P2(_,`Host-resource ${Q==="limit"?"capacities":"claims"} are malformed or duplicated.`);return F.add(Y.resource),{resource:Y.resource,value:Y[Q]}}).sort((Y,J)=>Y.resourceJ.resource?1:0)}function NL($){if(!GL($)||!eT($,["id","capacities"])||typeof $.id!=="string"||!fc0.test($.id))throw new P2("INVALID_PROFILE","Host-resource profile identity is invalid.");let Q=T_0($.capacities,"limit","INVALID_PROFILE").map(({resource:_,value:Z})=>({resource:_,limit:Z}));return kg({id:$.id,capacities:Q})}function qg($,Q){let _=NL(Q),Z=new Map(_.capacities.map(({resource:X,limit:Y})=>[X,Y])),F=T_0($,"amount","INVALID_CLAIMS").map(({resource:X,value:Y})=>{let J=Z.get(X);if(J===void 0||Y>J)throw new P2("INVALID_CLAIMS",`Host-resource claim ${X} is unavailable or exceeds its profile limit.`);return{resource:X,amount:Y}});return kg(F)}function R_0($=bc0()){if(!Rg($,z_0))throw new P2("INVALID_PROFILE","Host parallelism must be a positive safe integer.");let Q=$>=6?2:$>=2?1:0;return NL({id:"slopcamera.host-resources/v1",capacities:[{resource:"cpu",limit:Math.max(1,$-Q)},{resource:"local-io",limit:2},{resource:"ffmpeg",limit:2},{resource:"video-encode",limit:1},{resource:"vision",limit:1},{resource:"whisper",limit:1},{resource:"network",limit:4},{resource:"paid-call",limit:1},{resource:"browser",limit:1},{resource:"capture-device",limit:1}]})}function lc0($=process.platform,Q=process.env,_=Sc0()){if(!iT($))throw new P2("UNSUPPORTED_PLATFORM","Slopcamera host-resource coordination requires Darwin or Linux.");if($==="darwin")return l3(_,"Library","Application Support","Slopcamera","cli","host-resources-v1");let Z=Q.XDG_STATE_HOME,F=Z!==void 0&&zg(Z)?Z:l3(_,".local","state");return l3(F,"slopcamera","host-resources-v1")}function KL($){return JSON.stringify($)}function Eg($){return zc0("sha256").update($).digest("hex")}function u2($,Q){return new P2("UNSAFE_STATE",$,Q)}function jL($,Q){return GL($)&&$.code===Q}function k_0(){let $=process.geteuid?.()??process.getuid?.();if($===void 0)throw u2("Host-resource owner identity is unavailable.");return $}function q_0($){return{device:$.dev,inode:$.ino}}function WL($,Q){let _="device"in Q?Q.device:Q.dev,Z="inode"in Q?Q.inode:Q.ino;return $.device===_&&$.inode===Z}function Bg($){return $.isDirectory()&&!$.isSymbolicLink()&&$.uid===k_0()&&($.mode&511)===448}function qF($){return $.isFile()&&!$.isSymbolicLink()&&$.nlink===1&&$.uid===k_0()&&($.mode&511)===384}function B7($){try{return C7($)}catch(Q){if(jL(Q,"ENOENT"))return null;throw Q}}function dc0($){if(!zg($)||$.includes("\x00")||Buffer.byteLength($,"utf8")>U_0)throw u2("Host-resource state root must be a bounded absolute path.");let Q=!1,_=B7($);if(_===null){try{Rc0($,{recursive:!0,mode:448}),Q=!0}catch(F){if(!jL(F,"EEXIST"))throw u2("Host-resource state root could not be created.",F)}if(_=C7($),Q)Mc0($,448)}if(!Bg(_))throw u2("Host-resource state root is not one private owned directory.");let Z=qc0($);if(!Bg(Pc0(Z)))throw u2("Host-resource state root canonicalization is unsafe.");return{path:Z}}function u3($,Q=!1){let _=B7($);if(_!==null&&!qF(_))throw u2("Host-resource state contains an unsafe file.");let Z=TY.O_RDWR|TY.O_CREAT|TY.O_NOFOLLOW|(Q?TY.O_EXCL:0),F=Ug($,Z,384);try{Ac0(F,384);let X=d3(F),Y=C7($);if(!qF(X)||!qF(Y)||X.dev!==Y.dev||X.ino!==Y.ino)throw u2("Host-resource file identity changed while opening.");return F}catch(X){throw a9(F),X}}function E_0($){let Q=d3($);if(!qF(Q)||Q.size>C_0)throw u2("Host-resource state file is malformed.");let _=Buffer.alloc(Q.size),Z=0;while(Z<_.length){let F=kc0($,_,Z,_.length-Z,Z);if(F===0)break;Z+=F}if(Z!==_.length)throw u2("Host-resource state read was incomplete.");return _.toString("utf8")}function Pg($,Q){let _=Buffer.from(Q,"utf8");if(_.length>C_0)throw u2("Host-resource state write exceeds its bound.");Tc0($,0);let Z=0;while(Z<_.length){let F=Ic0($,_,Z,_.length-Z,Z);if(F<1)throw u2("Host-resource state write was incomplete.");Z+=F}D_0($)}function P_0($){return JSON.stringify({version:$.version,profile:$.profile,nextTicket:$.nextTicket})}function RY($){return JSON.stringify({version:$.version,owner:$.owner,profileSha256:$.profileSha256,ticket:$.ticket,phase:$.phase,claims:$.claims})}function Cg($){let Q=Ug($,TY.O_RDONLY|TY.O_DIRECTORY|TY.O_NOFOLLOW);try{if(!Bg(d3(Q)))throw u2("Host-resource state root changed identity.");D_0(Q)}finally{a9(Q)}}function I_0($,Q){let _=`.host-resources-${j_0(16).toString("hex")}.tmp`,Z=l3($,_),F=l3($,Ag),X;try{X=u3(Z,!0),Pg(X,P_0(Q)),a9(X),X=void 0;let Y=B7(F);if(Y!==null&&!qF(Y))throw u2("Host-resource profile state is unsafe.");Ec0(Z,F);let J=C7(F);if(!qF(J))throw u2("Host-resource profile state was not published safely.");Cg($)}finally{if(X!==void 0)a9(X);try{tT(Z)}catch(Y){if(!jL(Y,"ENOENT"));}}}function cc0($){let Q;try{Q=JSON.parse($)}catch(X){throw u2("Host-resource profile state is not valid JSON.",X)}if(!GL(Q)||!eT(Q,["version","profile","nextTicket"])||Q.version!==1||typeof Q.nextTicket!=="string"||!L_0.test(Q.nextTicket))throw u2("Host-resource profile state is malformed.");let _;try{_=NL(Q.profile)}catch(X){throw u2("Host-resource profile state is malformed.",X)}if(BigInt(Q.nextTicket)>Tg+1n)throw u2("Host-resource ticket state exceeds its bound.");let F={version:1,profile:_,nextTicket:Q.nextTicket};if(P_0(F)!==$)throw u2("Host-resource profile state is not normalized.");return F}function pc0($,Q){let _=l3($,Ag),Z=l3($,B_0);if(B7(_)===null){if(B7(Z)!==null||O_0($).some((J)=>Mg.test(J)))throw u2("Host-resource profile state is missing.");let X={version:1,profile:Q,nextTicket:"1"};I_0($,X);let Y=u3(Z,!0);return a9(Y),Cg($),X}let F=u3(_);try{let X=cc0(E_0(F)),Y=B7(Z)===null,J=Y?u3(Z,!0):u3(Z);try{if(d3(J).size!==0)throw u2("Host-resource initialization state is malformed.")}finally{a9(J)}if(Y)Cg($);return X}finally{a9(F)}}function $R($,Q){if(KL($.profile)===KL(Q))return;throw new P2("PROFILE_MISMATCH","The machine-global Slopcamera host-resource profile does not match this process.")}function sc0($,Q){let _=BigInt(Q.nextTicket);if(_>Tg)throw u2("Host-resource tickets are exhausted.");return I_0($,{...Q,nextTicket:String(_+1n)}),String(_)}function tV($,Q,_,Z,F){let X=$??Q;if(!Rg(X,_))throw new P2(Z,`${F} is outside its supported bound.`);return X}function aT($,Q){if($?.aborted===!0)throw new P2("WAIT_ABORTED","Host-resource admission was cancelled before execution.");if(VL.now()>=Q)throw new P2("WAIT_TIMEOUT","Host-resource admission exceeded its bounded wait.")}async function b_0($,Q,_){aT(Q,_);let Z=Math.max(1,Math.ceil(_-VL.now()));await new Promise((F,X)=>{let Y=!1,J=()=>{if(Y)return;Y=!0,Q?.removeEventListener("abort",H),F()},H=()=>{if(Y)return;Y=!0,clearTimeout(K),Q?.removeEventListener("abort",H),X(new P2("WAIT_ABORTED","Host-resource admission was cancelled before execution."))},K=setTimeout(J,Math.min($,Z));if(Q?.addEventListener("abort",H,{once:!0}),Q?.aborted===!0)H()}),aT(Q,_)}function nc0($,Q){let _=0xffff_ffff_ffff_ffffn,Z=BigInt($)+BigInt(Q+1)*0x9e37_79b9_7f4a_7c15n&_;return Z=(Z^Z>>30n)*0xbf58_476d_1ce4_e5b9n&_,Z=(Z^Z>>27n)*0x94d0_49bb_1331_11ebn&_,(Z^Z>>31n)&_}function rc0($,Q,_){let Z=$<=uc0?$:Math.max($,Math.min(mc0,$*G_0)),F=Math.min(_,Math.ceil(Math.log2(G_0))),X=Math.min(Z,$*2**F),Y=Math.max(1,Math.ceil(X/2)),J=X-Y+1,H=Number(nc0(Q,_)%BigInt(J));return Y+H}async function QR($,Q,_,Z,F){let X=u3(l3($,w_0)),Y=!1;try{while(!(Y=JL(X)))await b_0(Q,_,Z);return aT(_,Z),F()}catch(J){if(J instanceof P2)throw J;throw u2("Host-resource control locking failed.",J)}finally{if(Y)try{HL(X)}catch{}a9(X)}}function S_0($){return $.padStart(20,"0")}function oc0($,Q,_,Z){let F=Mg.exec($),X;try{X=JSON.parse(Q)}catch(H){throw u2("A live host-resource marker is not valid JSON.",H)}if(F===null||!GL(X)||!eT(X,["version","owner","profileSha256","ticket","phase","claims"])||X.version!==1||typeof X.owner!=="string"||!xc0.test(X.owner)||typeof X.profileSha256!=="string"||!/^[0-9a-f]{64}$/u.test(X.profileSha256)||typeof X.ticket!=="string"||!L_0.test(X.ticket)||X.phase!=="A"&&X.phase!=="W"||S_0(X.ticket)!==F[1]||X.owner!==F[2])throw u2("A live host-resource marker is malformed.");if(X.profileSha256!==Z)throw new P2("PROFILE_MISMATCH","A live lease belongs to a different host-resource profile.");let Y;try{Y=qg(X.claims,_)}catch(H){throw u2("A live host-resource marker has invalid claims.",H)}let J={version:1,owner:X.owner,profileSha256:X.profileSha256,ticket:X.ticket,phase:X.phase,claims:Y};if(RY(J)!==Q)throw u2("A live host-resource marker is not normalized.");return J}function f_0($,Q){let _=C7($);if(!qF(_)||!WL(Q,_))throw new P2("OWNERSHIP_LOST","Host-resource marker identity changed before cleanup.");tT($)}function ic0($){let Q=u3($);try{let _=d3(Q),Z=C7($);if(_.dev!==Z.dev||_.ino!==Z.ino)throw u2("Host-resource temporary state changed identity.");tT($)}finally{a9(Q)}}function Ig($,Q,_){let Z=O_0($,{withFileTypes:!0});if(Z.length>gc0)throw u2("Host-resource state contains too many entries.");let F=[],X=new Set,Y=new Set;for(let J of Z){if(J.name===w_0||J.name===Ag||J.name===B_0)continue;let H=l3($,J.name);if(vc0.test(J.name)){if(!J.isFile()||J.isSymbolicLink())throw u2("Host-resource temporary state is unsafe.");ic0(H);continue}if(!Mg.test(J.name))throw u2("Host-resource state contains an unknown entry.");let K=u3(H),W=!1;try{let V=d3(K),N=q_0(V);if(W=JL(K),W){f_0(H,N);continue}let G=oc0(J.name,E_0(K),Q,_);if(X.has(G.ticket)||Y.has(G.owner))throw u2("Live host-resource marker identity is duplicated.");X.add(G.ticket),Y.add(G.owner),F.push({document:G,identity:N,name:J.name,path:H})}finally{if(W)try{HL(K)}catch{}a9(K)}}return F.sort((J,H)=>{let K=BigInt(J.document.ticket),W=BigInt(H.document.ticket);return KW?1:0})}function y_0($){if($.released)throw new P2("OWNERSHIP_LOST","Host-resource lease is no longer active.");let Q,_;try{Q=d3($.descriptor),_=C7($.path)}catch(Z){throw new P2("OWNERSHIP_LOST","Host-resource marker is no longer reachable.",Z)}if(!qF(Q)||!qF(_)||!WL($.identity,Q)||!WL($.identity,_))throw new P2("OWNERSHIP_LOST","Host-resource descriptor no longer owns its published inode.")}function ac0($,Q,_,Z){let F=sc0($,Q),X=j_0(16).toString("hex"),Y=`lease-${S_0(F)}-${X}.lock`,J=l3($,Y),H;try{if(H=u3(J,!0),!JL(H))throw u2("A new host-resource marker could not be locked.");let K={version:1,owner:X,profileSha256:Z,ticket:F,phase:"W",claims:_};return Pg(H,RY(K)),{descriptor:H,document:K,identity:q_0(d3(H)),name:Y,path:J,released:!1}}catch(K){if(H!==void 0){try{HL(H)}catch{}a9(H)}try{tT(J)}catch(W){if(!jL(W,"ENOENT"));}throw K}}function bg($,Q){return $.name===Q.name&&$.document.owner===Q.document.owner&&$.document.ticket===Q.document.ticket&&WL($.identity,Q.identity)}function Sg($,Q){let _=new Set($.map(({resource:Z})=>Z));return Q.some(({resource:Z})=>_.has(Z))}function x_0($,Q,_){let Z=new Map;for(let F of Q)for(let X of F.document.claims)Z.set(X.resource,(Z.get(X.resource)??0)+X.amount);for(let{resource:F,limit:X}of $.capacities)if((Z.get(F)??0)>X)throw u2("Live host-resource leases exceed the declared profile.");return _.every(({resource:F,amount:X})=>{let Y=$.capacities.find((J)=>J.resource===F)?.limit;return Y!==void 0&&(Z.get(F)??0)+X<=Y})}function N_0($,Q){let _=BigInt($.document.ticket),Z=Q.filter((F)=>{if(bg(F,$))return!1;if(!Sg(F.document.claims,$.document.claims))return!1;return F.document.phase==="A"||BigInt(F.document.ticket)<_});return Eg(Z.map((F)=>`${F.name}\x00${RY(F.document)}`).join(` `))}function tc0($,Q,_){y_0($);let Z=Q.find((H)=>bg(H,$));if(Z===void 0||Z.document.phase!==$.document.phase||RY(Z.document)!==RY($.document))throw new P2("OWNERSHIP_LOST","Host-resource lease marker no longer matches its descriptor.");let F=BigInt($.document.ticket);if(Q.some((H)=>H.document.phase==="W"&&BigInt(H.document.ticket)H.document.phase==="A");if(!x_0(_,Y,$.document.claims))return{admitted:!1,queueState:N_0($,Q)};let J={...$.document,phase:"A"};return Pg($.descriptor,RY(J)),$.document=J,{admitted:!0,queueState:""}}function ec0($,Q){return bg($,Q)&&$.document.phase==="A"&&Q.document.phase==="A"&&RY($.document)===RY(Q.document)}async function $p0($,Q,_,Z,F,X){let Y,J=0;for(;;){let H=await QR(Q,_.pollIntervalMilliseconds,Z,F,()=>{let K=X();$R(K,_.profile);let W=Ig(Q,_.profile,_.profileSha256);return tc0($,W,_.profile)});if(H.admitted)return;if(H.queueState===Y)J+=1;else Y=H.queueState,J=0;await b_0(rc0(_.pollIntervalMilliseconds,$.document.ticket,J),Z,F)}}async function Qp0($,Q,_,Z){y_0($);let F=VL.now()+_.waitTimeoutMilliseconds;await QR(Q,_.pollIntervalMilliseconds,void 0,F,()=>{let X=Z();if($R(X,_.profile),!Ig(Q,_.profile,_.profileSha256).some((J)=>ec0(J,$)))throw new P2("OWNERSHIP_LOST","Host-resource lease is not backed by its exact active kernel lock.")})}async function _p0($,Q,_,Z){if($.released)return;$.released=!0;try{a9($.descriptor)}catch(X){if(!jL(X,"EBADF"))throw X}let F=VL.now()+_.waitTimeoutMilliseconds;await QR(Q,_.pollIntervalMilliseconds,void 0,F,()=>{let X=Z();if($R(X,_.profile),B7($.path)===null)return;let Y=u3($.path),J=!1;try{let H=d3(Y);if(!WL($.identity,H))throw new P2("OWNERSHIP_LOST","Host-resource marker inode changed before release.");if(J=JL(Y),!J)return;f_0($.path,$.identity)}finally{if(J)try{HL(Y)}catch{}a9(Y)}})}function Zp0($){if(!iT(process.platform))throw new P2("UNSUPPORTED_PLATFORM","Slopcamera host-resource coordination requires Darwin or Linux.");let Q=NL($.profile??R_0()),_=$.stateRoot??lc0();if(typeof _!=="string"||!zg(_)||_.includes("\x00")||Buffer.byteLength(_,"utf8")>U_0)throw u2("Host-resource state root must be a bounded absolute path.");return{pollIntervalMilliseconds:tV($.pollIntervalMilliseconds,M_0,1000,"INVALID_PROFILE","Host-resource poll interval"),profile:Q,profileSha256:Eg(KL(Q)),stateRoot:_,waitTimeoutMilliseconds:tV($.waitTimeoutMilliseconds,A_0,TQ,"INVALID_PROFILE","Host-resource wait timeout")}}function Fp0($={}){let Q=Zp0($),_,Z=()=>{if(_===void 0)_=dc0(Q.stateRoot);return _.path},F=()=>{return pc0(Z(),Q.profile)},X={profile:Q.profile,scope:"machine",async withLease(Y,J,H={}){let K=qg(Y,Q.profile);if(typeof J!=="function")throw new P2("INVALID_CLAIMS","Host-resource lease callback must be a function.");let W=tV(H.waitTimeoutMilliseconds,Q.waitTimeoutMilliseconds,TQ,"INVALID_CLAIMS","Host-resource lease wait timeout"),V=H.signal,N=VL.now()+W;aT(V,N);let G=Z(),D,L=!1,O,w;try{D=await QR(G,Q.pollIntervalMilliseconds,V,N,()=>{let U=F();return $R(U,Q.profile),Ig(G,Q.profile,Q.profileSha256),ac0(G,U,K,Q.profileSha256)}),await $p0(D,G,Q,V,N,F);let B=D,C=Object.freeze({claims:K,inheritedFileDescriptor:B.descriptor,profile:Q.profile,ticket:B.document.ticket,assertOwned:async()=>{await Qp0(B,G,Q,F)}});await C.assertOwned();try{O=await J(C),L=!0,await C.assertOwned()}catch(U){w=U}}finally{if(D!==void 0)try{await _p0(D,G,Q,F)}catch(B){if(w===void 0)w=B}}if(!L||w!==void 0)throw w;return O}};return Object.freeze(X)}var wg=new Map;function Xp0($={}){let Q=NL($.profile??R_0()),_=tV($.waitTimeoutMilliseconds,A_0,TQ,"INVALID_PROFILE","Host-resource wait timeout");if($.pollIntervalMilliseconds!==void 0)tV($.pollIntervalMilliseconds,M_0,1000,"INVALID_PROFILE","Host-resource poll interval");let Z=KL(Q),F=wg.get(Z);if(F===void 0){if(wg.size>=hc0)throw new P2("INVALID_PROFILE","This process already coordinates the maximum number of host-resource profiles.");F={active:new Map,nextTicket:1n,waiting:[]},wg.set(Z,F)}let{active:X,waiting:Y}=F,J=(V)=>{if(V.timeout!==void 0)clearTimeout(V.timeout);if(V.abortListener!==void 0)V.signal?.removeEventListener("abort",V.abortListener)},H=()=>[...X.values()].map((V)=>({document:{version:1,owner:V.ticket.padStart(32,"0").slice(-32),profileSha256:Eg(KL(Q)),ticket:V.ticket,phase:"A",claims:V.claims},identity:{device:0,inode:0},name:V.ticket,path:""})),K=()=>{for(let V=0;VSg(w.claims,N.claims))||!x_0(Q,H(),N.claims)){V+=1;continue}Y.splice(V,1),J(N);let D;try{D=Ug(process.platform==="win32"?"NUL":"/dev/null",TY.O_RDONLY)}catch(w){N.settled=!0,N.reject(new P2("UNSAFE_STATE","Process-local host-resource admission could not open its lease descriptor.",w));continue}N.active=!0,X.set(N.ticket,N),N.descriptor=D;let O=Object.freeze({assertOwned:async()=>{if(N.settled||!N.active||X.get(N.ticket)!==N||N.descriptor!==D)throw new P2("OWNERSHIP_LOST","Process-local host-resource lease is no longer active.");try{d3(D)}catch(w){throw new P2("OWNERSHIP_LOST","Process-local host-resource descriptor is no longer open.",w)}},claims:N.claims,inheritedFileDescriptor:D,profile:Q,ticket:N.ticket});(async()=>{let w=!1,B,C;try{await O.assertOwned(),B=await N.callback(O),await O.assertOwned(),w=!0}catch(U){C=U}finally{N.active=!1,N.settled=!0,X.delete(N.ticket);try{a9(D)}catch(U){if(C===void 0)C=U}K()}if(w&&C===void 0)N.resolve(B);else N.reject(C)})()}};return Object.freeze({profile:Q,scope:"process",async withLease(V,N,G={}){let D=qg(V,Q);if(typeof N!=="function")return Promise.reject(new P2("INVALID_CLAIMS","Host-resource lease callback must be a function."));if(F.nextTicket>Tg)return Promise.reject(u2("Host-resource tickets are exhausted."));let L=tV(G.waitTimeoutMilliseconds,_,TQ,"INVALID_CLAIMS","Host-resource lease wait timeout"),O=String(F.nextTicket);return F.nextTicket+=1n,await new Promise((w,B)=>{let C={active:!1,callback:N,claims:D,reject:B,resolve:w,settled:!1,signal:G.signal,ticket:O},U=(z)=>{if(C.active||C.settled)return;C.settled=!0;let M=Y.indexOf(C);if(M>=0)Y.splice(M,1);J(C),B(z),K()};if(C.abortListener=()=>U(new P2("WAIT_ABORTED","Host-resource admission was cancelled before execution.")),C.timeout=setTimeout(()=>U(new P2("WAIT_TIMEOUT","Host-resource admission exceeded its bounded wait.")),L),C.timeout.unref?.(),G.signal?.addEventListener("abort",C.abortListener,{once:!0}),G.signal?.aborted===!0){C.abortListener();return}Y.push(C),K()})}})}function c3($={},Q=process.platform){if(iT(Q))return Fp0($);let{profile:_,pollIntervalMilliseconds:Z,waitTimeoutMilliseconds:F}=$;return Xp0({..._===void 0?{}:{profile:_},...Z===void 0?{}:{pollIntervalMilliseconds:Z},...F===void 0?{}:{waitTimeoutMilliseconds:F}})}var $G=["slopcamera.diagram.check","slopcamera.diagram.render","slopcamera.image.vectorize","slopcamera.image.generate","slopcamera.image.icon","slopcamera.image.gallery"];class z9 extends Error{code;constructor($,Q){super(`[${$}] ${Q}`);this.name="SlopcameraOperationError",this.code=$}}var _R={type:"string",minLength:3,maxLength:256,pattern:"^[a-zA-Z0-9][a-zA-Z0-9._-]*/[a-zA-Z0-9][a-zA-Z0-9._:-]*$"},kY={type:"string",minLength:1,maxLength:4096};function g_0($){if(typeof $!=="object"||$===null||Object.isFrozen($))return $;for(let Q of Object.values($))g_0(Q);return Object.freeze($)}var LL=g_0([{code:"slopcamera.diagram.check",title:"Check diagram",description:"Parse and lint a checked Slopcamera diagram source without changing its files.",execution:"local",authentication:"none",destructive:!1,idempotent:!0,inputSchema:{type:"object",additionalProperties:!1,required:["path"],properties:{path:kY}},resources:[{resource:"cpu",amount:1},{resource:"local-io",amount:1}]},{code:"slopcamera.diagram.render",title:"Render diagram",description:"Render a checked Slopcamera diagram source to its replaceable light, dark, PNG, SVG, and tldraw artifacts.",execution:"local",authentication:"none",destructive:!0,idempotent:!0,inputSchema:{type:"object",additionalProperties:!1,required:["path"],properties:{path:kY,outDirectory:kY,scale:{type:"number",exclusiveMinimum:0,maximum:4}}},resources:[{resource:"cpu",amount:1},{resource:"local-io",amount:1}]},{code:"slopcamera.image.vectorize",title:"Vectorize image",description:"Convert a local caller-owned raster into a bounded inert SVG without authentication or network access.",execution:"local",authentication:"none",destructive:!0,idempotent:!1,inputSchema:{type:"object",additionalProperties:!1,required:["inputPath","outputPath"],properties:{inputPath:kY,outputPath:kY,duotone:{type:"array",minItems:2,maxItems:2,items:{type:"string",pattern:"^#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$"}},alphaCutoff:{type:"integer",minimum:1,maximum:64},timeoutMs:{type:"integer",minimum:1,maximum:300000}}},resources:[{resource:"cpu",amount:1},{resource:"local-io",amount:1}]},{code:"slopcamera.image.generate",title:"Generate image",description:"Generate one bounded image directly through Vercel AI Gateway with an environment credential and no client retry.",execution:"gateway",authentication:"environment",destructive:!0,idempotent:!1,inputSchema:{type:"object",additionalProperties:!1,required:["model","prompt","outputPath"],properties:{model:_R,prompt:{type:"string",minLength:1,maxLength:nF},outputPath:kY}},resources:[{resource:"local-io",amount:1},{resource:"network",amount:1},{resource:"paid-call",amount:1}],transport:{method:"POST",authority:"https://ai-gateway.vercel.sh/v4/ai",authorization:"bearer",retry:"never"}},{code:"slopcamera.image.icon",title:"Generate line-art icon",description:"Generate one isometric line-art SVG icon: a style-locked Vercel AI Gateway raster normalized to canonical ink-on-transparent pixels, traced locally, and optionally critiqued by a vision model across bounded rounds.",execution:"gateway",authentication:"environment",destructive:!0,idempotent:!1,inputSchema:{type:"object",additionalProperties:!1,required:["subject","outputPath"],properties:{subject:{type:"string",minLength:1,maxLength:nV},outputPath:kY,model:_R,critiqueModel:_R,ink:{type:"string",pattern:"^#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$"},purpose:{type:"string",enum:["mark","illustration"]},rounds:{type:"integer",minimum:1,maximum:sV},keepRaster:{type:"boolean"}}},resources:[{resource:"cpu",amount:1},{resource:"local-io",amount:1},{resource:"network",amount:1},{resource:"paid-call",amount:1}],transport:{method:"POST",authority:"https://ai-gateway.vercel.sh/v4/ai",authorization:"bearer",retry:"never"}},{code:"slopcamera.image.gallery",title:"Generate image gallery",description:"Generate several bounded Vercel AI Gateway image candidates in parallel and compose a labelled contact sheet with per-candidate provenance for explicit review and selection.",execution:"gateway",authentication:"environment",destructive:!0,idempotent:!1,inputSchema:{type:"object",additionalProperties:!1,required:["subject","outputDir"],properties:{subject:{type:"string",minLength:1,maxLength:O1.subjectBytes},outputDir:kY,kind:{type:"string",enum:[...VZ]},model:_R,count:{type:"integer",minimum:1,maximum:O1.candidates},vary:{type:"array",maxItems:H6.length,items:{anyOf:[{type:"string",enum:[...H6]},{type:"object",additionalProperties:!1,required:["axis"],properties:{axis:{type:"string",enum:[...H6]},values:{type:"array",minItems:1,maxItems:O1.candidates,items:{type:"string",minLength:1,maxLength:O1.variantBytes}}}}]}},candidates:{type:"array",minItems:1,maxItems:O1.candidates,items:{type:"object",additionalProperties:!1,required:["id"],properties:{id:{type:"string",minLength:1,maxLength:O1.idLength},prompt:{type:"string",minLength:1,maxLength:O1.candidatePromptBytes},variant:{type:"string",minLength:1,maxLength:O1.variantBytes}}}},cellEdge:{type:"integer",minimum:O1.cellEdgeMin,maximum:O1.cellEdgeMax},tiled:{type:"boolean"},timeoutMs:{type:"integer",minimum:1000,maximum:1800000}}},resources:[{resource:"cpu",amount:1},{resource:"local-io",amount:1},{resource:"network",amount:1},{resource:"paid-call",amount:1}],transport:{method:"POST",authority:"https://ai-gateway.vercel.sh/v4/ai",authorization:"bearer",retry:"never"}}]);function v4($){throw new z9("INVALID_OPERATION_INPUT",$)}function Gp0($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function QG($,Q){if(!Gp0($))v4("Operation input must be an object.");let _=Object.keys($).filter((Z)=>!Q.includes(Z));if(_.length>0)v4(`Unsupported operation input field: ${_[0]}.`);return $}function qY($,Q){if(typeof $!=="string"||$.length<1||$.length>4096||$.includes("\x00"))v4(`${Q} must be a non-empty bounded local path.`);return $}function Np0($){let Q=QG($,["path"]);return{path:qY(Q.path,"path")}}function jp0($){let Q=QG($,["path","outDirectory","scale"]),_=Q.scale;if(_!==void 0&&(typeof _!=="number"||!Number.isFinite(_)||_<=0||_>4))v4("scale must be greater than zero and no more than 4.");return{path:qY(Q.path,"path"),...Q.outDirectory===void 0?{}:{outDirectory:qY(Q.outDirectory,"outDirectory")},..._===void 0?{}:{scale:_}}}function Dp0($){let Q=QG($,["inputPath","outputPath","duotone","alphaCutoff","timeoutMs"]),_=qY(Q.inputPath,"inputPath"),Z=qY(Q.outputPath,"outputPath");if(!Z.toLowerCase().endsWith(".svg"))v4("outputPath must end in .svg.");let F=Q.duotone;if(F!==void 0&&(!Array.isArray(F)||F.length!==2||F.some((J)=>typeof J!=="string"||!/^#[a-f0-9]{3}(?:[a-f0-9]{3})?$/iu.test(J))))v4("duotone must contain exactly two #rgb or #rrggbb colors.");let X=Q.alphaCutoff;if(X!==void 0&&(!Number.isInteger(X)||X<1||X>64))v4("alphaCutoff must be an integer from 1 through 64.");let Y=Q.timeoutMs;if(Y!==void 0&&(!Number.isInteger(Y)||Y<1||Y>300000))v4("timeoutMs must be an integer from 1 through 300000.");return{inputPath:_,outputPath:Z,...F===void 0?{}:{duotone:F},...X===void 0?{}:{alphaCutoff:X},...Y===void 0?{}:{timeoutMs:Y}}}function Op0($){let Q=QG($,["model","prompt","outputPath"]);if(typeof Q.model!=="string"||Q.model.length>256||!/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._:-]*$/iu.test(Q.model))v4("model must be a bounded Vercel AI Gateway provider/model id.");if(typeof Q.prompt!=="string"||Q.prompt.trim().length<1||/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/u.test(Q.prompt)||Buffer.byteLength(Q.prompt,"utf8")>nF)v4(`prompt must be non-empty and no more than ${nF} UTF-8 bytes.`);let _=qY(Q.outputPath,"outputPath");if(!/\.(?:jpe?g|png|webp)$/iu.test(_))v4("outputPath must end in .png, .jpg, .jpeg, or .webp.");return{model:Q.model,prompt:Q.prompt,outputPath:_}}function Lp0($){let Q=QG($,["subject","outputPath","model","critiqueModel","ink","rounds","keepRaster"]);if(typeof Q.subject!=="string"||Q.subject.trim().length<1||/[\u0000-\u001f\u007f]/u.test(Q.subject)||Buffer.byteLength(Q.subject,"utf8")>nV)v4(`subject must be non-empty and no more than ${nV} UTF-8 bytes.`);let _=qY(Q.outputPath,"outputPath");if(!_.toLowerCase().endsWith(".svg"))v4("outputPath must end in .svg.");for(let F of["model","critiqueModel"]){let X=Q[F];if(X!==void 0&&(typeof X!=="string"||X.length>256||!/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._:-]*$/iu.test(X)))v4(`${F} must be a bounded Vercel AI Gateway provider/model id.`)}if(Q.ink!==void 0&&(typeof Q.ink!=="string"||!/^#[a-f0-9]{3}(?:[a-f0-9]{3})?$/iu.test(Q.ink)))v4("ink must be a #rgb or #rrggbb color.");let Z=Q.rounds;if(Z!==void 0&&(!Number.isInteger(Z)||Z<1||Z>sV))v4(`rounds must be an integer from 1 through ${sV}.`);if(Q.keepRaster!==void 0&&typeof Q.keepRaster!=="boolean")v4("keepRaster must be a boolean.");return{subject:Q.subject,outputPath:_,...Q.model===void 0?{}:{model:Q.model},...Q.critiqueModel===void 0?{}:{critiqueModel:Q.critiqueModel},...Q.ink===void 0?{}:{ink:Q.ink},...Z===void 0?{}:{rounds:Z},...Q.keepRaster===void 0?{}:{keepRaster:Q.keepRaster}}}function wp0($){let Q=QG($,["subject","outputDir","kind","model","count","vary","candidates","cellEdge","tiled","timeoutMs"]);if(typeof Q.subject!=="string"||Q.subject.trim().length<1||/[\u0000-\u001f\u007f]/u.test(Q.subject)||Buffer.byteLength(Q.subject,"utf8")>O1.subjectBytes)v4(`subject must be non-empty and no more than ${O1.subjectBytes} UTF-8 bytes.`);if(Q.kind!==void 0&&(typeof Q.kind!=="string"||!VZ.includes(Q.kind)))v4(`kind must be one of: ${VZ.join(", ")}.`);if(Q.model!==void 0&&(typeof Q.model!=="string"||Q.model.length>256||!/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._:-]*$/iu.test(Q.model)))v4("model must be a bounded Vercel AI Gateway provider/model id.");if(Q.count!==void 0&&(!Number.isInteger(Q.count)||Q.count<1||Q.count>O1.candidates))v4(`count must be an integer from 1 through ${O1.candidates}.`);if(Q.vary!==void 0&&(!Array.isArray(Q.vary)||Q.vary.length<1||Q.vary.length>H6.length))v4(`vary must be a list of at most ${H6.length} axes.`);if(Q.candidates!==void 0&&(!Array.isArray(Q.candidates)||Q.candidates.length<1||Q.candidates.length>O1.candidates))v4(`candidates must contain 1 through ${O1.candidates} entries.`);if(Q.vary!==void 0&&Q.candidates!==void 0)v4("vary and candidates are mutually exclusive.");if(Q.count!==void 0&&Q.candidates!==void 0)v4("count and candidates are mutually exclusive.");let _=Q.cellEdge;if(_!==void 0&&(!Number.isInteger(_)||_O1.cellEdgeMax))v4(`cellEdge must be an integer from ${O1.cellEdgeMin} through ${O1.cellEdgeMax}.`);let Z=Q.timeoutMs;if(Z!==void 0&&(!Number.isInteger(Z)||Z<1000||Z>1800000))v4("timeoutMs must be an integer from 1000 through 1800000.");if(Q.tiled!==void 0&&typeof Q.tiled!=="boolean")v4("tiled must be a boolean when set.");return{subject:Q.subject,outputDir:qY(Q.outputDir,"outputDir"),...Q.kind===void 0?{}:{kind:Q.kind},...Q.model===void 0?{}:{model:Q.model},...Q.count===void 0?{}:{count:Q.count},...Q.vary===void 0?{}:{vary:Q.vary},...Q.candidates===void 0?{}:{candidates:Q.candidates},..._===void 0?{}:{cellEdge:_},...Q.tiled===void 0?{}:{tiled:Q.tiled},...Z===void 0?{}:{timeoutMs:Z}}}function RQ($,Q){switch($){case"slopcamera.diagram.check":return Np0(Q);case"slopcamera.diagram.render":return jp0(Q);case"slopcamera.image.vectorize":return Dp0(Q);case"slopcamera.image.generate":return Op0(Q);case"slopcamera.image.icon":return Lp0(Q);case"slopcamera.image.gallery":return wp0(Q);default:throw new z9("INVALID_OPERATION","Unknown Slopcamera operation code.")}}function m_0($){return $G.includes($)}function ZR($){let Q=LL.find((_)=>_.code===$);if(Q===void 0)throw new z9("INVALID_OPERATION","Unknown Slopcamera operation code.");return Q.resources}function FR($="",Q=LL.length){if(typeof $!=="string"||$.length>200||/[\u0000-\u001f\u007f]/u.test($)||!Number.isInteger(Q)||Q<1||Q>20)throw new z9("INVALID_SEARCH","Search requires a bounded query and a limit from 1 through 20.");let _=$.toLowerCase().split(/\s+/u).filter((Z)=>Z.length>0);return LL.filter((Z)=>{let F=`${Z.code} ${Z.title} ${Z.description}`.toLowerCase();return _.every((X)=>F.includes(X))}).slice(0,Q)}function u_0($,Q){let _=[...$.inheritedFileDescriptors??[],Q.inheritedFileDescriptor].filter((J,H,K)=>K.indexOf(J)===H);if(_.length>16||_.some((J)=>!Number.isSafeInteger(J)||J<0||J>2147483647))throw new z9("INVALID_OPERATION_INPUT","Operation host-resource inheritance exceeds its descriptor bound.");let{hostResourceCoordinator:Z,signal:F,waitTimeoutMilliseconds:X,...Y}=$;return{...Y,inheritedFileDescriptors:_}}async function fg($,Q,_={}){return await(_.hostResourceCoordinator??c3()).withLease(ZR($),async(F)=>{return await F.assertOwned(),await Q(F)},{..._.signal===void 0?{}:{signal:_.signal},..._.waitTimeoutMilliseconds===void 0?{}:{waitTimeoutMilliseconds:_.waitTimeoutMilliseconds}})}var DL=Object.freeze({icons:C9});async function l_0($){let Q=h_0($),_;try{_=JSON.parse(await Hp0(Q,"utf8"))}catch(F){throw new z9("INVALID_OPERATION_INPUT","Diagram source could not be read as JSON.")}let Z=A6(_);for(let F of Z.shapes)if((F.type==="rect"||F.type==="ellipse")&&F.icon!==void 0&&!Object.hasOwn(C9,F.icon))throw new z9("INVALID_OPERATION_INPUT","Diagram requests an unavailable built-in icon.");return{absolutePath:Q,spec:Z}}async function OL($,Q){let _=eV(v_0($),`.${Yp0()}.slopcamera-operation.tmp`);try{await Vp0(_,Q,{flag:"wx"}),await Kp0(_,$)}finally{await Wp0(_,{force:!0}).catch(()=>{return})}}async function Bp0($){let{spec:Q}=await l_0($);return{findings:q_(Q),configPath:null}}async function Cp0($){let{absolutePath:Q,spec:_}=await l_0($.path),Z=h_0($.outDirectory??v_0(Q)),F=$.scale??2,[X,Y]=await Promise.all([U9(_,"light",DL),U9(_,"dark",DL)]),[J,H]=[A_(X,DL,F),A_(Y,DL,F)],K={spec:Q,tldr:eV(Z,`${_.name}.tldr`),lightSvg:eV(Z,`${_.name}.light.svg`),darkSvg:eV(Z,`${_.name}.dark.svg`),lightPng:eV(Z,`${_.name}.light.png`),darkPng:eV(Z,`${_.name}.dark.png`)};return await Jp0(Z,{recursive:!0}),await Promise.all([OL(K.tldr,CY(_,DL)),OL(K.lightSvg,X.svg),OL(K.darkSvg,Y.svg),OL(K.lightPng,J),OL(K.darkPng,H)]),{artifacts:K,findings:q_(_),configPath:null}}async function d_0($,Q,_={}){let Z=RQ($,Q);switch($){case"slopcamera.diagram.check":return await Bp0(Z.path);case"slopcamera.diagram.render":return await Cp0(Z);case"slopcamera.image.vectorize":{let F=Z,X=await E_(F.inputPath,{outputPath:F.outputPath,...F.duotone===void 0?{}:{duotone:F.duotone},...F.alphaCutoff===void 0?{}:{alphaCutoff:F.alphaCutoff},...F.timeoutMs===void 0?{}:{limits:{maxDurationMs:F.timeoutMs}},..._.inheritedFileDescriptors===void 0?{}:{inheritedFileDescriptors:_.inheritedFileDescriptors}});if(X.outputPath===null)throw new z9("INVALID_OPERATION_INPUT","Vectorization did not publish its required output.");return{outputPath:X.outputPath,receipt:X.receipt}}case"slopcamera.image.generate":return await BK({...Z,..._.signal===void 0?{}:{signal:_.signal}},_);case"slopcamera.image.icon":return await lT({...Z,..._.signal===void 0?{}:{signal:_.signal},..._.inheritedFileDescriptors===void 0?{}:{inheritedFileDescriptors:_.inheritedFileDescriptors}},_);case"slopcamera.image.gallery":return await CK({...Z,..._.signal===void 0?{}:{signal:_.signal}},_);default:throw new z9("INVALID_OPERATION","Unknown Slopcamera operation code.")}}async function U7($,Q,_,Z={}){await _.assertOwned();let F=new Map;for(let Y of _.claims){if(typeof Y.resource!=="string"||!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(Y.resource)||!Number.isSafeInteger(Y.amount)||Y.amount<1)throw new z9("INVALID_OPERATION","The active host-resource lease contains invalid claims.");let J=(F.get(Y.resource)??0)+Y.amount;if(!Number.isSafeInteger(J))throw new z9("INVALID_OPERATION","The active host-resource lease contains invalid claims.");F.set(Y.resource,J)}let X=ZR($).filter((Y)=>(F.get(Y.resource)??0)0)throw new z9("INVALID_OPERATION",`The active host-resource lease does not cover ${X.map((Y)=>`${Y.resource}:${String(Y.amount)}`).join(", ")}.`);return await d_0($,Q,u_0(Z,_))}async function z7($,Q,_={}){let Z=RQ($,Q);return await fg($,async(F)=>await d_0($,Z,u_0(_,F)),_)}import{rename as n_0,rm as r_0,writeFile as qp0}from"fs/promises";import{dirname as Ep0,join as _G}from"path";import{open as Up0,mkdir as zp0,realpath as wL,stat as yg}from"fs/promises";import{basename as Mp0,dirname as c_0,isAbsolute as p_0,join as Ap0,relative as s_0,resolve as XR,win32 as Tp0}from"path";var p3=1048576;class r2 extends Error{code;constructor($,Q){super(Q);this.name="WorkspaceBoundaryError",this.code=$}}function JR($){if(typeof $==="object"&&$!==null&&"code"in $&&typeof $.code==="string")return $.code;return}function YR($,Q){if($.length===0||$.includes("\x00"))throw new r2("INVALID_PATH","Path must be a non-empty root-relative path.");if(p_0($)||Tp0.isAbsolute($)||/^[A-Za-z]:/.test($))throw new r2("INVALID_PATH","Absolute paths are not allowed.");let _=$.split(/[\\/]/).filter((Z)=>Z!==""&&Z!==".");if(_.includes(".."))throw new r2("INVALID_PATH","Parent-directory traversal is not allowed.");if(_.length===0){if(!Q.allowRoot)throw new r2("INVALID_PATH","Path must identify a file below the root.");return{native:".",portable:"."}}return{native:_.join("/"),portable:_.join("/")}}function Rp0($,Q){let _=s_0($,Q);return _===""||!_.startsWith("..")&&!p_0(_)}async function kp0($,Q){let _;try{_=await Up0($,"r");let Z=await _.stat();if(!Z.isFile())throw new r2("SOURCE_NOT_FILE",`${Q} must be a regular file.`);if(Z.size>p3)throw new r2("SOURCE_TOO_LARGE",`${Q} exceeds the ${p3}-byte limit.`);let F=Buffer.allocUnsafe(p3+1),X=0;while(X<=p3){let Y=await _.read(F,X,p3+1-X,null);if(Y.bytesRead===0)break;X+=Y.bytesRead}if(X>p3)throw new r2("SOURCE_TOO_LARGE",`${Q} exceeds the ${p3}-byte limit.`);try{return new TextDecoder("utf-8",{fatal:!0}).decode(F.subarray(0,X))}catch{throw new r2("SOURCE_ENCODING",`${Q} must contain valid UTF-8.`)}}catch(Z){if(Z instanceof r2)throw Z;if(JR(Z)==="ENOENT")throw new r2("SOURCE_NOT_FOUND",`${Q} does not exist.`);throw new r2("FILESYSTEM_ERROR",`${Q} could not be read.`)}finally{await _?.close()}}class M7{rootDirectory;constructor($){this.rootDirectory=$}static async create($){let Q;try{if(Q=await wL(XR($)),!(await yg(Q)).isDirectory())throw new r2("OUTPUT_NOT_DIRECTORY","MCP root must be a directory.")}catch(_){if(_ instanceof r2)throw _;throw new r2("FILESYSTEM_ERROR","MCP root could not be opened.")}return new M7(Q)}assertConfined($){if(!Rp0(this.rootDirectory,$))throw new r2("PATH_OUTSIDE_ROOT","Path resolves outside the MCP root.")}toRelativePath($){this.assertConfined($);let Q=s_0(this.rootDirectory,$);return Q===""?".":Q.split("\\").join("/")}async readSource($,Q="Diagram source"){let _=YR($,{allowRoot:!1}),Z=XR(this.rootDirectory,_.native);this.assertConfined(Z);let F;try{F=await wL(Z)}catch(X){if(JR(X)==="ENOENT")throw new r2("SOURCE_NOT_FOUND",`${Q} does not exist.`);throw new r2("FILESYSTEM_ERROR",`${Q} could not be resolved.`)}return this.assertConfined(F),{absolutePath:F,relativePath:this.toRelativePath(F),text:await kp0(F,Q)}}async resolveInputFile($,Q){let _=YR($,{allowRoot:!1}),Z=XR(this.rootDirectory,_.native);this.assertConfined(Z);let F;try{F=await wL(Z),this.assertConfined(F);let X=await yg(F);if(!X.isFile())throw new r2("SOURCE_NOT_FILE","Input must be a regular file.");if(!Number.isSafeInteger(Q)||Q<1||X.size>Q)throw new r2("SOURCE_TOO_LARGE",`Input exceeds the ${Q}-byte limit.`)}catch(X){if(X instanceof r2)throw X;if(JR(X)==="ENOENT")throw new r2("SOURCE_NOT_FOUND","Input does not exist.");throw new r2("FILESYSTEM_ERROR","Input could not be resolved.")}return{absolutePath:F,relativePath:this.toRelativePath(F)}}async prepareOutputFile($){let Q=YR($,{allowRoot:!1}),_=Mp0(Q.native);if(_==="."||_===".."||_.length===0)throw new r2("INVALID_PATH","Output path must identify a file below the root.");let Z=await this.prepareOutputDirectory(c_0(Q.native)),F=Ap0(Z.absolutePath,_);return this.assertConfined(F),{absolutePath:F,relativePath:this.toRelativePath(F)}}async prepareOutputDirectory($){let Q=YR($,{allowRoot:!0}),_=XR(this.rootDirectory,Q.native);this.assertConfined(_);let Z=_;for(;;)try{let F=await wL(Z);this.assertConfined(F);break}catch(F){if(F instanceof r2)throw F;if(JR(F)!=="ENOENT")throw new r2("FILESYSTEM_ERROR","Output directory could not be resolved.");let X=c_0(Z);if(X===Z)throw new r2("PATH_OUTSIDE_ROOT","Output directory resolves outside the MCP root.");Z=X}try{await zp0(_,{recursive:!0});let F=await wL(_);if(this.assertConfined(F),!(await yg(F)).isDirectory())throw new r2("OUTPUT_NOT_DIRECTORY","Output path must be a directory.");return{absolutePath:F,relativePath:this.toRelativePath(F)}}catch(F){if(F instanceof r2)throw F;throw new r2("FILESYSTEM_ERROR","Output directory could not be created.")}}}var ZG=4,zL=16777216,ML=64,AL=128,PY=40,HR=256,Z30=8192,F30=1024,vg=2,Pp0=12,BL=Object.freeze({icons:C9}),o_0={type:"object",additionalProperties:!1,required:["code","message","shapeIds"],properties:{code:{type:"string"},message:{type:"string"},shapeIds:{type:"array",items:{type:"string"}}}},kQ={type:"string",description:"Root-relative path to a spatial scene JSON source (1 MiB maximum)."},CL={type:"string",maxLength:128,pattern:"^camera_[a-zA-Z0-9][a-zA-Z0-9_-]*$",description:"Identifier of a camera declared by the scene (camera_\u2026)."},i_0={type:"object",additionalProperties:!1,required:["entityCount","returnedEntityCount","entitiesTruncated"],properties:{entityCount:{type:"integer",minimum:0},returnedEntityCount:{type:"integer",minimum:0},entitiesTruncated:{type:"boolean"}}};function X30($){if(typeof $!=="object"||$===null||Object.isFrozen($))return $;for(let Q of Object.values($))X30(Q);return Object.freeze($)}var IY=X30([{name:"check_diagram",title:"Check diagram",description:"Parse and lint one root-relative Slopcamera diagram source without changing files. Uses only built-in icons and themes.",inputSchema:{type:"object",additionalProperties:!1,required:["path"],properties:{path:{type:"string",description:"Root-relative path to a diagram JSON source (1 MiB maximum)."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","findings","summary"],properties:{ok:{const:!0},source:{type:"string"},findings:{type:"array",items:o_0},summary:{type:"object",additionalProperties:!1,required:["shapeCount","edgeCount","findingCount","returnedFindingCount","findingsTruncated"],properties:{shapeCount:{type:"integer",minimum:0},edgeCount:{type:"integer",minimum:0},findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"}}}}},annotations:{title:"Check diagram",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"render_diagram",title:"Render diagram",description:"Render one root-relative Slopcamera diagram source with built-in icons and themes, overwriting its paired .tldr, light/dark SVG, and light/dark PNG artifacts.",inputSchema:{type:"object",additionalProperties:!1,required:["path"],properties:{path:{type:"string",description:"Root-relative path to a diagram JSON source (1 MiB maximum)."},out_dir:{type:"string",description:"Optional root-relative output directory. Defaults to the source directory."},scale:{type:"number",exclusiveMinimum:0,maximum:ZG,default:vg,description:"PNG scale. The scaled canvas may contain at most 16,777,216 pixels."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","scale","findings","artifacts","summary"],properties:{ok:{const:!0},source:{type:"string"},scale:{type:"number"},findings:{type:"array",items:o_0},artifacts:{type:"object",additionalProperties:!1,required:["tldr","lightSvg","darkSvg","lightPng","darkPng"],properties:{tldr:{type:"string"},lightSvg:{type:"string"},darkSvg:{type:"string"},lightPng:{type:"string"},darkPng:{type:"string"}}},summary:{type:"object",additionalProperties:!1,required:["shapeCount","edgeCount","findingCount","returnedFindingCount","findingsTruncated"],properties:{shapeCount:{type:"integer",minimum:0},edgeCount:{type:"integer",minimum:0},findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"}}}}},annotations:{title:"Render diagram",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!0,openWorldHint:!1}},{name:"search_slopcamera",title:"Search Slopcamera operations",description:"Search the fixed semantic Slopcamera operation registry by bounded text. This never executes code or changes files.",inputSchema:{type:"object",additionalProperties:!1,properties:{query:{type:"string",maxLength:200,description:"Optional terms matched against operation codes and descriptions."},limit:{type:"integer",minimum:1,maximum:20,default:4}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","operations"],properties:{ok:{const:!0},operations:{type:"array",maxItems:20,items:{type:"object",required:["code","title","description","execution","authentication","inputSchema"]}}}},annotations:{title:"Search Slopcamera operations",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"execute_slopcamera",title:"Execute Slopcamera operation",description:"Execute one exact operation code with typed JSON input. Never accepts or evaluates source code. Local paths remain confined to the configured workspace root.",inputSchema:{type:"object",additionalProperties:!1,required:["operation","input"],properties:{operation:{type:"string",enum:$G},input:{type:"object",description:"Typed input matching the selected operation's registry schema."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","operation","result"],properties:{ok:{const:!0},operation:{type:"string",enum:$G},result:{type:"object"}}},annotations:{title:"Execute Slopcamera operation",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1,openWorldHint:!0}},{name:"check_scene",title:"Check scene",description:"Parse and validate one root-relative Slopcamera spatial scene JSON source without changing files.",inputSchema:{type:"object",additionalProperties:!1,required:["path"],properties:{path:kQ}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","sceneId","sceneSha256","summary"],properties:{ok:{const:!0},source:{type:"string"},sceneId:{type:"string"},sceneSha256:{type:"string"},summary:{type:"object",additionalProperties:!1,required:["durationUs","entityCount","cameraCount","assetCount","animationCount","generatorCount","overrideCount"],properties:{durationUs:{type:"integer",minimum:0},entityCount:{type:"integer",minimum:0},cameraCount:{type:"integer",minimum:0},assetCount:{type:"integer",minimum:0},animationCount:{type:"integer",minimum:0},generatorCount:{type:"integer",minimum:0},overrideCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"inspect_scene",title:"Inspect scene",description:"Snapshot one root-relative spatial scene's entities, editable controls, placements, assets, and generators without changing files.",inputSchema:{type:"object",additionalProperties:!1,required:["path"],properties:{path:kQ}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","inspection","summary"],properties:{ok:{const:!0},source:{type:"string"},inspection:{type:"object"},summary:i_0}},annotations:{title:"Inspect scene",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"audit_scene",title:"Audit scene",description:"Sample one root-relative spatial scene against a camera and report per-entity geometric coverage, visibility findings, and bounds gaps. Optional asset_bounds accepts a Record map, a slopcamera.spatial-asset-admission document, a {manifest,facts} pair, or an array of those.",inputSchema:{type:"object",additionalProperties:!1,required:["path","camera_id"],properties:{path:kQ,camera_id:CL,times_us:{type:"array",items:{type:"integer",minimum:0,maximum:O0.durationUs},minItems:1,maxItems:O$.samples,description:"Optional sample times in microseconds. Defaults to evenly spaced coverage of the scene duration."},asset_bounds:{description:"Optional decoded scene-space asset bounds: a Record map, a slopcamera.spatial-asset-admission document, a {manifest,facts} pair, or an array of those documents."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","report","summary"],properties:{ok:{const:!0},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["findingCount","returnedFindingCount","findingsTruncated","entityCount","returnedEntityCount","entitiesTruncated"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},entityCount:{type:"integer",minimum:0},returnedEntityCount:{type:"integer",minimum:0},entitiesTruncated:{type:"boolean"}}}}},annotations:{title:"Audit scene",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"diff_scenes",title:"Diff scenes",description:"Compare two root-relative spatial scene JSON sources and report added, removed, and changed collection entries without changing files.",inputSchema:{type:"object",additionalProperties:!1,required:["path","other"],properties:{path:kQ,other:{type:"string",description:"Root-relative path to the second spatial scene JSON source (1 MiB maximum)."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","other","sceneSha256","otherSha256","diff","summary"],properties:{ok:{const:!0},source:{type:"string"},other:{type:"string"},sceneSha256:{type:"string"},otherSha256:{type:"string"},diff:{type:"array"},summary:{type:"object",additionalProperties:!1,required:["entryCount","returnedEntryCount","diffTruncated"],properties:{entryCount:{type:"integer",minimum:0},returnedEntryCount:{type:"integer",minimum:0},diffTruncated:{type:"boolean"}}}}},annotations:{title:"Diff scenes",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"evaluate_scene",title:"Evaluate scene",description:"Evaluate one root-relative spatial scene at one camera and integer microsecond time into an immutable snapshot without changing files.",inputSchema:{type:"object",additionalProperties:!1,required:["path","camera_id","time_us"],properties:{path:kQ,camera_id:CL,time_us:{type:"integer",minimum:0,maximum:O0.durationUs,description:"Evaluation time in integer microseconds."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","snapshot","summary"],properties:{ok:{const:!0},source:{type:"string"},snapshot:{type:"object"},summary:i_0}},annotations:{title:"Evaluate scene",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"check_scene_direction",title:"Check scene direction",description:"Validate one authored direction document against one root-relative spatial scene: stale project digests, unresolved entity references, and intervals outside scene duration report as errors without compiling or changing files.",inputSchema:{type:"object",additionalProperties:!1,required:["scene","direction"],properties:{scene:{...kQ,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},direction:{type:"string",description:"Root-relative path to the slopcamera.spatial-direction JSON document."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","report","summary"],properties:{ok:{const:!0},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["findingCount","returnedFindingCount","findingsTruncated","errorCount","warningCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},errorCount:{type:"integer",minimum:0},warningCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene direction",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"plan_scene_direction",title:"Plan scene direction",description:"Compile one authored direction document into a deterministic, unverified proposal document \u2014 performance actions, camera rigs, shots and looks bound to the actual scene digest. Proposals are advisory only; nothing is applied to the scene.",inputSchema:{type:"object",additionalProperties:!1,required:["scene","direction"],properties:{scene:{...kQ,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},direction:{type:"string",description:"Root-relative path to the slopcamera.spatial-direction JSON document."},camera_id:{...CL,description:"Optional camera used to resolve coverage; defaults to the sole or first sorted scene camera."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","compilation","summary"],properties:{ok:{const:!0},source:{type:"string"},compilation:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["advisoryCount","unresolvedIntentCount","proposalCounts"],properties:{advisoryCount:{type:"integer",minimum:0},unresolvedIntentCount:{type:"integer",minimum:0},proposalCounts:{type:"object",additionalProperties:!1,required:["performance","cameraRigs","shots","lookIntents"],properties:{performance:{type:"integer",minimum:0},cameraRigs:{type:"integer",minimum:0},shots:{type:"integer",minimum:0},lookIntents:{type:"integer",minimum:0}}}}}}},annotations:{title:"Plan scene direction",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"plan_scene_gallery",title:"Plan scene gallery",description:"Compile a bounded set of single-axis direction variants into separate content-addressed candidate compilations plus a preview-reel plan. The planner never selects or promotes a candidate.",inputSchema:{type:"object",additionalProperties:!1,required:["scene","direction","axis"],properties:{scene:{...kQ,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},direction:{type:"string",description:"Root-relative path to the slopcamera.spatial-direction JSON document."},axis:{type:"string",enum:[...V3.options],description:"Variation axis for the bounded candidate set."},camera_id:{...CL,description:"Optional camera used to resolve coverage."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","gallery","summary"],properties:{ok:{const:!0},source:{type:"string"},gallery:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["axis","candidateCount","selected"],properties:{axis:{type:"string"},candidateCount:{type:"integer",minimum:0},selected:{const:!1}}}}},annotations:{title:"Plan scene gallery",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"check_scene_effects",title:"Check scene effects",description:"Validate one slopcamera.spatial-render-effects document or {document, documentSha256} binding against one scene: scene-digest bindings, entity and asset closure, and nested plan/particle/simulation digests report as findings before any host work.",inputSchema:{type:"object",additionalProperties:!1,required:["scene","effects"],properties:{scene:{...kQ,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},effects:{type:"string",description:"Root-relative path to the render-effects document or binding JSON."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","report","summary"],properties:{ok:{const:!0},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["findingCount","returnedFindingCount","findingsTruncated","errorCount","warningCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},errorCount:{type:"integer",minimum:0},warningCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene effects",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"plan_scene_effects",title:"Plan scene effects",description:"Assemble a canonical {document, documentSha256} render-effects binding for one scene from a draft JSON naming renderPlan, particleSystems and simulationBakes. Entity and asset closure rejects before the document is formed; the scene digest binds here, never by caller assertion.",inputSchema:{type:"object",additionalProperties:!1,required:["scene","draft"],properties:{scene:{...kQ,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},draft:{type:"string",description:"Root-relative path to the effects draft JSON ({renderPlan, particleSystems?, simulationBakes?})."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","binding","summary"],properties:{ok:{const:!0},source:{type:"string"},binding:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["documentSha256","particleSystemCount","simulationBakeCount"],properties:{documentSha256:{type:"string"},particleSystemCount:{type:"integer",minimum:0},simulationBakeCount:{type:"integer",minimum:0}}}}},annotations:{title:"Plan scene effects",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"check_scene_behavior",title:"Check scene behavior",description:"Validate one slopcamera.spatial-behavior document against one scene: bake-safe organism profile (input/const/fn/repeat/each/organism cells only), manifest-closure digests, entity and scene-digest bindings, channel declarations, fn-catalog resolution, wiring, and budget bounds report as findings before any host work.",inputSchema:{type:"object",additionalProperties:!1,required:["scene","behavior"],properties:{scene:{...kQ,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},behavior:{type:"string",description:"Root-relative path to the spatial behavior document JSON."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","report","summary"],properties:{ok:{const:!0},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["findingCount","returnedFindingCount","findingsTruncated","errorCount","warningCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},errorCount:{type:"integer",minimum:0},warningCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene behavior",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"audit_scene_behavior",title:"Audit scene behavior trace",description:"Analyze a baked behavior trace for pathological patterns: state thrash (rapid transitions), exact periodicity (trivially cyclic channels), dead channels (constant-valued), and unreachable states (declared in transitions but never visited). Advisory findings for gallery review \u2014 never selects or promotes.",inputSchema:{type:"object",additionalProperties:!1,required:["bake"],properties:{bake:{type:"string",description:"Root-relative path to the behavior bake JSON (slopcamera.spatial-behavior-bake)."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","report","summary"],properties:{ok:{const:!0},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["findingCount","channelCount","emittedCount"],properties:{findingCount:{type:"integer",minimum:0},channelCount:{type:"integer",minimum:0},emittedCount:{type:"integer",minimum:0}}}}},annotations:{title:"Audit scene behavior trace",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"audit_scene_temporal",title:"Audit scene temporal evidence",description:"Evaluate one root-relative spatial scene at bounded sample times under one camera and report deterministic temporal findings: visibility flicker, transform discontinuity, foot-slide against declared contact windows, camera acceleration/jerk/angular velocity, exposure and focus jumps, and resource spikes.",inputSchema:{type:"object",additionalProperties:!1,required:["path","camera_id"],properties:{path:kQ,camera_id:CL,times_us:{type:"array",items:{type:"integer",minimum:0,maximum:O0.durationUs},minItems:2,maxItems:D9.samples,description:"Optional sample times in microseconds (2\u2013256). Defaults to evenly spaced coverage of the scene duration."},contacts:{type:"string",description:"Optional root-relative path to a {contacts: [...]} ground-contact evidence JSON."},cut_before_us:{type:"array",items:{type:"integer",minimum:0,maximum:O0.durationUs},maxItems:D9.cutBoundaries,description:"Optional intentional cut boundaries; discontinuities exactly at a cut are not findings."}}},outputSchema:{type:"object",additionalProperties:!1,required:["ok","source","report","summary"],properties:{ok:{const:!0},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:!1,required:["findingCount","returnedFindingCount","findingsTruncated","sampleCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},sampleCount:{type:"integer",minimum:2}}}}},annotations:{title:"Audit scene temporal evidence",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}}]);class k2 extends Error{code;issues;constructor($,Q,_){super(Q);if(this.name="ToolFailure",this.code=$,_!==void 0)this.issues=_}}function c8($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function M9($,Q=160){return $.replace(/[\u0000-\u001f\u007f]/g," ").replace(/\s+/g," ").trim().slice(0,Q)}function a_0($){return $.slice(0,24).map((Q)=>M9(Q,240))}function q6($,Q){let _=Object.keys($).filter((Z)=>!Q.has(Z));if(_.length>0)throw new k2("INVALID_ARGUMENTS",`Unsupported argument: ${M9(_[0]??"unknown")}.`)}function Y30($){if(typeof $!=="string"||$.length===0)throw new k2("INVALID_ARGUMENTS","path must be a non-empty root-relative string.");if(!$.toLowerCase().endsWith(".diagram.json"))throw new k2("INVALID_ARGUMENTS","path must end in .diagram.json.");return $}function Ip0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");return q6($,new Set(["path"])),{path:Y30($.path)}}function bp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");q6($,new Set(["path","out_dir","scale"]));let Q=$.out_dir;if(Q!==void 0&&(typeof Q!=="string"||Q.length===0))throw new k2("INVALID_ARGUMENTS","out_dir must be a non-empty root-relative string when present.");let _=$.scale??vg;if(typeof _!=="number"||!Number.isFinite(_)||_<=0||_>ZG)throw new k2("RENDER_LIMIT",`scale must be greater than zero and no more than ${ZG}.`);return{path:Y30($.path),...Q===void 0?{}:{outDirectory:Q},scale:_}}function Sp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");q6($,new Set(["query","limit"]));let Q=$.query??"",_=$.limit??$G.length;if(typeof Q!=="string"||Q.length>200||/[\u0000-\u001f\u007f]/u.test(Q)||!Number.isInteger(_)||_<1||_>20)throw new k2("INVALID_ARGUMENTS","query must be a bounded string and limit must be an integer from 1 through 20.");return{query:Q,limit:_}}function fp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");if(q6($,new Set(["operation","input"])),typeof $.operation!=="string"||!$G.includes($.operation)||!c8($.input))throw new k2("INVALID_ARGUMENTS","operation must be an exact Slopcamera operation code and input must be an object.");return{operation:$.operation,input:$.input}}var yp0=/^camera_[a-zA-Z0-9][a-zA-Z0-9_-]*$/u;function t9($,Q){if(typeof $!=="string"||$.length===0)throw new k2("INVALID_ARGUMENTS",`${Q} must be a non-empty root-relative string.`);if(!$.toLowerCase().endsWith(".json"))throw new k2("INVALID_ARGUMENTS",`${Q} must end in .json.`);return $}function KR($){if(typeof $!=="string"||$.length>128||!yp0.test($))throw new k2("INVALID_ARGUMENTS","camera_id must be a scene camera identifier (camera_ followed by letters, digits, _ or -).");return $}function t_0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");return q6($,new Set(["path"])),{path:t9($.path,"path")}}function xp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");q6($,new Set(["path","camera_id","times_us","asset_bounds"]));let Q;if($.times_us!==void 0){if(!Array.isArray($.times_us)||$.times_us.length===0||$.times_us.length>O$.samples||$.times_us.some((_)=>!Number.isSafeInteger(_)||_<0||_>O0.durationUs))throw new k2("INVALID_ARGUMENTS",`times_us must be an array of 1\u2013${O$.samples} integer microsecond times within the scene duration bound.`);Q=[...$.times_us]}return{path:t9($.path,"path"),cameraId:KR($.camera_id),...Q===void 0?{}:{timesUs:Q},..."asset_bounds"in $?{assetBounds:$.asset_bounds}:{}}}function vp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");return q6($,new Set(["path","other"])),{path:t9($.path,"path"),other:t9($.other,"other")}}function hp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");q6($,new Set(["path","camera_id","time_us"]));let Q=$.time_us;if(typeof Q!=="number"||!Number.isSafeInteger(Q)||Q<0||Q>O0.durationUs)throw new k2("INVALID_ARGUMENTS",`time_us must be an integer microsecond time from 0 through ${O0.durationUs}.`);return{path:t9($.path,"path"),cameraId:KR($.camera_id),timeUs:Q}}function xg($,Q){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");if(q6($,new Set(["scene","direction","camera_id","axis"])),Q&&!V3.safeParse($.axis).success)throw new k2("INVALID_ARGUMENTS",`axis must be one of ${V3.options.join(", ")}.`);if(!Q&&$.axis!==void 0)throw new k2("INVALID_ARGUMENTS","axis is only valid for plan_scene_gallery.");return{scene:t9($.scene,"scene"),direction:t9($.direction,"direction"),...$.camera_id===void 0?{}:{cameraId:KR($.camera_id)},...$.axis===void 0?{}:{axis:$.axis}}}function e_0($,Q){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");return q6($,new Set(["scene",Q])),{scene:t9($.scene,"scene"),effects:t9($[Q],Q)}}function gp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");return q6($,new Set(["scene","behavior"])),{scene:t9($.scene,"scene"),behavior:t9($.behavior,"behavior")}}function mp0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");return q6($,new Set(["bake"])),{bake:t9($.bake,"bake")}}function up0($){if(!c8($))throw new k2("INVALID_ARGUMENTS","Tool arguments must be an object.");q6($,new Set(["path","camera_id","times_us","contacts","cut_before_us"]));let Q=(F,X)=>{let Y=$[F];if(Y===void 0)return;if(!Array.isArray(Y)||Y.length===0||Y.length>X||Y.some((J)=>!Number.isSafeInteger(J)||J<0||J>O0.durationUs))throw new k2("INVALID_ARGUMENTS",`${F} must be an array of 1\u2013${X} integer microsecond times within the scene duration bound.`);return[...Y]},_=Q("times_us",D9.samples),Z=Q("cut_before_us",D9.cutBoundaries);if(_!==void 0&&_.length<2)throw new k2("INVALID_ARGUMENTS","times_us must contain at least 2 sample times.");return{path:t9($.path,"path"),cameraId:KR($.camera_id),..._===void 0?{}:{timesUs:_},...$.contacts===void 0?{}:{contacts:t9($.contacts,"contacts")},...Z===void 0?{}:{cutBeforeUs:Z}}}function lp0($){for(let Q of $.shapes)if((Q.type==="rect"||Q.type==="ellipse")&&Q.icon!==void 0&&!Object.hasOwn(C9,Q.icon))throw new k2("UNKNOWN_ICON",`Shape ${M9(Q.id)} requests unavailable built-in icon ${M9(Q.icon)}.`)}function dp0($){let Q=$.edges?.length??0;if($.shapes.length>ML||Q>AL)throw new k2("COMPLEXITY_LIMIT",`Diagram may contain at most ${ML} shapes and ${AL} edges in MCP mode.`)}function cp0($){if(!c8($))return;let Q=Array.isArray($.shapes)?$.shapes.length:0,_=Array.isArray($.edges)?$.edges.length:0;if(Q>ML||_>AL)throw new k2("COMPLEXITY_LIMIT",`Diagram may contain at most ${ML} shapes and ${AL} edges in MCP mode.`)}function pp0($,Q){let _=$.canvas.width*Q,Z=$.canvas.height*Q,F=Math.ceil(_)*Math.ceil(Z);if(!Number.isFinite(F)||_<1||Z<1||F>zL)throw new k2("RENDER_LIMIT",`Scaled canvas must be at least 1 pixel on each axis and no more than ${zL.toLocaleString("en-US")} pixels total.`)}function EF($,Q){return $.length>Q?$.slice(0,Q):$}function sp0($){return{code:M9($.code,64),message:M9($.message,240),shapeIds:$.shapeIds.slice(0,Pp0).map((Q)=>M9(Q,120))}}function $30($){return $.slice(0,PY).map(sp0)}function Q30($,Q,_){return{shapeCount:$.shapes.length,edgeCount:$.edges?.length??0,findingCount:Q,returnedFindingCount:_,findingsTruncated:_typeof X==="string"))Q="INVALID_LAYOUT",_="Diagram layout could not be resolved.",Z=a_0($.issues);let F=Z===void 0||Z.length===0?"":` @@ -5599,7 +5599,7 @@ export default defineWorkflow({ `)}async function bq($,Q){let _=R1(yq($),`.replace-${fq()}`);await ZJ(_,Q);try{await W$1(_,$),await v6(yq($))}catch(Z){throw await QK(_).catch(()=>{return}),Z}}async function hq($,Q=t70){if(!Number.isSafeInteger(Q)||Q<0||Q>t70)throw new j("invalid-data","Run artifact byte bound is invalid.");let _;try{_=await b$($)}catch(F){if(v_(F,"ENOENT"))throw new j("not-found",`Run artifact does not exist: ${$}`);throw F}if(!Ad(_)||!Number.isSafeInteger(_.size)||_.size<0||_.size>Q)throw new j("unsafe-path",`Run artifact must be a bounded private physical file: ${$}`);let Z=await mq($,h_.O_NOFOLLOW|h_.O_RDONLY|h_.O_NONBLOCK);try{let F=XJ(_),X,Y,J=Buffer.alloc(_.size+1);for(let H of[1,2]){let K=XJ(await Z.stat());if(!JN(F,K)||X!==void 0&&!_K(X,K))throw new j("conflict",`Run artifact changed before read: ${$}`);let W=0;while(Wxq)throw new j("invalid-data",`Run journal exceeds ${String(xq)} entries: ${Q}`);return Object.freeze(F.map((X,Y)=>{try{return _.parse(JSON.parse(X))}catch(J){throw new j("invalid-data",`Invalid run journal entry ${String(Y+1)} (${Q}): ${String(J)}`)}}))}async function Ud($,Q){return OK0(await hq($,Sq),$,Q)}async function KK0($,Q,_,Z,F,X){let Y=await b$($);if(!Ad(Y)||Y.size>Sq)throw new j("unsafe-path",`Run journal must be a bounded private physical file: ${$}`);let J=await mq($,h_.O_NOFOLLOW|h_.O_RDWR);try{let H=await J.stat();if(!FJ(E9(Y),E9(H)))throw new j("conflict",`Run journal changed before append: ${$}`);let K=X!==void 0&&_K(X.snapshot,XJ(Y))&&_K(X.snapshot,XJ(H)),W,V,N;if(K)W=H.size,V=X.cursor,N=X.entryCount;else{let B=new Uint8Array(await J.readFile());if(B.byteLength>Sq)throw new j("invalid-data",`Run journal exceeds its byte limit: ${$}`);let C=DK0(B),U=OK0(B,$,Q);if(V=_(U),N=U.length,W=C.byteLength,B.byteLength!==W)await J.truncate(W),await J.sync()}if(N>=xq)throw new j("conflict",`Run journal already contains ${String(xq)} entries.`);let G=Z({cursor:V,entryCount:N}),D=Q.parse(G.entry),L=new TextEncoder().encode(`${R(D)} `);if(L.byteLength>N$1)throw new j("invalid-data","Run journal entry exceeds its byte limit.");if(W+L.byteLength>Sq)throw new j("conflict","Run journal has reached its byte limit.");let O=0;while(OQ.status==="cancelled").length,completed:$.filter((Q)=>Q.status==="completed").length,failed:$.filter((Q)=>Q.status==="failed"||Q.status==="incompatible"||Q.status==="ambiguous").length,pending:$.filter((Q)=>Q.status==="pending"||Q.status==="ready"||Q.status==="preparing"||Q.status==="running"||Q.status==="approval-required"||Q.status==="ambiguous-code").length,skipped:$.filter((Q)=>Q.status==="skipped").length}}function S$1($){return typeof $==="object"&&$!==null&&!Array.isArray($)&&Object.hasOwn($,"$ref")}function f$1($){return Array.isArray($)}function gq($,Q,_){if(S$1($)){let F=Q.get($.$ref.nodeKey);if(F?.status!=="completed"||F.output===void 0)return;return _[F.nodeKey]=F.output.digestSha256,bw($,F.output.value)}if(f$1($)){let F=[];for(let X of $){let Y=gq(X,Q,_);if(Y===void 0)return;F.push(Y)}return F}let Z={};for(let[F,X]of Object.entries($).sort(([Y],[J])=>Y.localeCompare(J))){let Y=gq(X,Q,_);if(Y===void 0)return;Z[F]=Y}return Z}function VK0($){if($.some((_)=>_.status==="approval-required"))return"approval-required";if($.some((_)=>_.status==="ambiguous-code"))return"ambiguous-code";if($.some((_)=>_.status==="pending"||_.status==="ready"||_.status==="preparing"||_.status==="running"))return"running";let Q=Md($);if(Q.cancelled>0)return"cancelled";if(Q.failed===0&&Q.skipped===0&&Q.completed===$.length)return"completed";if($.some((_)=>_.status==="incompatible")&&Q.completed===0)return"incompatible";if(Q.completed>0)return"partial";return"failed"}class Td{#$=new Map;#Q=0;#Z;#X;constructor($){let Q=$.claimSessionCacheBudgetBytes??wd;if(!Number.isSafeInteger(Q)||Q<0||Q>wd)throw new j("usage",`Run claim-session cache budget must be a safe integer from 0 through ${String(wd)}.`);this.#Z=Q,this.#X=G$1($.root)}async#F(){let $=this.#X,Q=V$1($),_=$.slice(Q.root.length).split("/").filter(Boolean),Z=Q.root;for(let X of _){Z=R1(Z,X);let Y;try{Y=await b$(Z)}catch(J){if(!v_(J,"ENOENT"))throw J;try{await Sw(Z,{mode:448})}catch(H){if(!v_(H,"EEXIST"))throw H}Y=await b$(Z)}if(Y.isSymbolicLink()||!Y.isDirectory())throw new j("unsafe-path",`Run root crosses a non-physical directory component: ${Z}`)}let F=await b$($);if(!Pq(F))throw new j("unsafe-path",`Run root must be an owner-only physical directory (0700): ${$}`);if(await jd($)!==$)throw new j("unsafe-path",`Run root crosses a symbolic link: ${$}`);return $}async#Y($,Q=!0){let _=Z6.shape.runId.parse($),Z=await this.#F(),F=R1(Z,_);if(Q){let X=await b$(F).catch((Y)=>{if(v_(Y,"ENOENT"))throw new j("not-found",`Workflow run does not exist: ${_}`);throw Y});if(!Pq(X)||await jd(F)!==F)throw new j("unsafe-path",`Workflow run must be an owner-only physical directory (0700): ${_}`)}return F}async#H($){return await this.#W($,"nodes")}async#W($,Q){let _=R1($,Q),Z=await b$(_);if(!Pq(Z)||await jd(_)!==_)throw new j("unsafe-path",`Run ${Q} storage must be a physical 0700 directory.`);return _}async#J($,Q){let _=R1($,Q);try{await Sw(_,{mode:448})}catch(Z){if(!v_(Z,"EEXIST"))throw Z}return await this.#W($,Q)}async#V($,Q){let _=await this.#Y($),Z=R1(_,U$1),F=Bd.parse({acquiredAt:new Date().toISOString(),hostname:qq(),pid:process.pid,token:fq(),version:_6}),X=Date.now()+j$1,Y;while(Y===void 0)try{await Iq(Z,F),Y=E9(await b$(Z))}catch(J){if(!v_(J,"EEXIST"))throw J;let H,K;try{K=await b$(Z),H=await H$(Z,Bd)}catch(W){let V=await b$(Z).catch(()=>{return});if(K===void 0||V===void 0||!FJ(E9(K),E9(V))){if(Date.now()>=X)throw new j("conflict",`Timed out waiting for run serialization: ${$}`);await Dd(Ld);continue}if(v_(W,"ENOENT")||W instanceof j&&(W.code==="not-found"||W.code==="conflict")){if(Date.now()>=X)throw new j("conflict",`Timed out waiting for run serialization: ${$}`);await Dd(Ld);continue}throw new j("unsafe-path",`Run serialization lock is malformed: ${String(W)}`)}if(H.hostname===qq()&&!XK0(H.pid)){let W=await b$(Z).catch(()=>{return});if(W!==void 0&&FJ(E9(K),E9(W))){await QK(Z),await v6(_);continue}}if(Date.now()>=X)throw new j("conflict",`Timed out waiting for run serialization: ${$}`);await Dd(Ld)}try{return await Q(_)}finally{let J=await b$(Z).catch(()=>{return});if(J!==void 0&&FJ(Y,E9(J))){if((await H$(Z,Bd).catch(()=>{return}))?.token===F.token)await QK(Z).catch(()=>{return}),await v6(_).catch(()=>{return})}}}async#j($,Q,_){await this.#W($,"staging");let Z;try{Z=El(await jK0(R1($,"graph-plan.json"),_))}catch(W){if(W instanceof j)throw W;throw new j("invalid-data",`Persisted graph plan is invalid: ${String(W)}`)}let F=await H$(R1($,Eq),FK0,_);if(F.runId!==Q||F.graphPlanSha256!==Z.graphPlanSha256)throw new j("invalid-data","Run initialization identity is inconsistent.");let X=await H$(R1($,"graph.json"),u6,_);if(!M4(X,Z.graph))throw new j("invalid-data","Persisted authored graph differs from its graph plan.");let Y=await H$(R1($,"workflow.json"),Vd,_);if(!M4(Y.bundle,Z.bundle)||!M4(Y.workflow,Z.graph.workflow))throw new j("invalid-data","Persisted workflow identity differs from its graph plan.");let J=await H$(R1($,"runtime.json"),Bq,_);if(!M4(J.runtime,Z.runtime)||!M4(J.computes,JK0(Z))||!M4(J.operations,YK0(Z)))throw new j("invalid-data","Persisted runtime identity differs from its graph plan.");let H=await hq(R1($,"workflow.bundle.js"),Od),K=fw("sha256").update(H).digest("hex");if(_?.set(R1($,"workflow.bundle.js"),K),H.byteLength!==Z.bundle.bytes||K!==Z.bundle.bundleSha256)throw new j("invalid-data","Persisted workflow bundle bytes changed.");return{bundleBytes:H,directory:$,graphPlan:Z,runtime:J,workflow:Y}}#A($){return[R1($,"graph-plan.json"),R1($,Eq),R1($,"graph.json"),R1($,"workflow.json"),R1($,"runtime.json"),R1($,"workflow.bundle.js")]}async#_($){let Q=await Promise.all(this.#A($).map(async(_)=>{let Z=await b$(_);if(!Ad(Z))throw new j("unsafe-path",`Run identity must be stored in a private physical file: ${_}`);return[_,XJ(Z)]}));return new Map(Q)}#C($,Q){if($.size!==Q.size)return!1;for(let[_,Z]of $){let F=Q.get(_);if(F===void 0||!_K(Z,F))return!1}return!0}async#D($){let Q=new Map;for(let[_,Z]of $){let F=await hq(_,Z.size);Q.set(_,fw("sha256").update(F).digest("hex"))}return Q}async#O($,Q){let _=await this.#_($),Z=new Map,F=await this.#j($,Q,Z),X=await this.#_($);if(!this.#C(_,X)){for(let[K,W]of _){let V=X.get(K);if(V===void 0||!JN(W,V))throw new j("conflict",`Run identity changed while it was validated: ${Q}`)}let J=await this.#D(X),H=await this.#_($);if(!this.#C(X,H)||[...Z].some(([K,W])=>J.get(K)!==W))throw new j("conflict",`Run identity changed while it was validated: ${Q}`);X=H}let Y={directory:F.directory,graphPlan:F.graphPlan,runtime:F.runtime,workflow:F.workflow};return{identity:Y,retainedBytes:k$1(Y,X),sha256ByPath:Z,snapshots:X}}#K($){let Q=this.#$.get($.runId);if(Q===void 0||Q.fenceGeneration!==$.generation||Q.fenceToken!==$.token)return;return this.#$.delete($.runId),this.#$.set($.runId,Q),Q}#N($){let Q=this.#$.get($);if(Q===void 0)return;this.#$.delete($),this.#Q=Math.max(0,this.#Q-Q.retainedBytes)}#w($,Q){let _=this.#K($),Z={..._?.eventJournal===void 0?{}:{eventJournal:_.eventJournal},..._?.grantJournal===void 0?{}:{grantJournal:_.grantJournal},..._?.identity===void 0?{}:{identity:_.identity},...Q,fenceGeneration:$.generation,fenceToken:$.token},F=q$1($.runId,Z);if(this.#N($.runId),F>O$1||F>this.#Z)return;this.#$.set($.runId,{...Z,retainedBytes:F}),this.#Q=YJ(this.#Q,F);while(this.#$.size>D$1||this.#Q>this.#Z){let X=this.#$.keys().next().value;if(X===void 0)break;this.#N(X)}}#q($){let Q=this.#$.get($.runId);if(Q?.fenceGeneration===$.generation&&Q.fenceToken===$.token)this.#N($.runId)}async#M($,Q){let _=this.#K(Q)?.identity;if(_!==void 0)try{let F=await this.#_($);if(this.#C(_.snapshots,F))return _.identity;for(let[J,H]of _.snapshots){let K=F.get(J);if(K===void 0||!JN(H,K))throw new j("conflict",`Run identity metadata changed: ${J}`)}let X=await this.#D(F),Y=await this.#_($);if(!this.#C(F,Y))throw new j("conflict","Run identity changed during revalidation.");for(let[J,H]of _.sha256ByPath)if(X.get(J)!==H)throw new j("conflict",`Run identity bytes changed: ${J}`);return this.#w(Q,{identity:{..._,snapshots:Y}}),_.identity}catch(F){throw this.#q(Q),new j("conflict",`Run identity changed while its claim was active: ${Q.runId} (${String(F)})`)}let Z=await this.#O($,Q.runId);return this.#w(Q,{identity:Z}),Z.identity}async#L($){let Q=await this.#Y($);return await this.#j(Q,$)}async create($){let Q=i70.parse($),_=El(Q.graphPlan);if(Q.bundleBytes.byteLength>Od)throw new j("invalid-data",`Workflow bundle exceeds ${String(Od)} bytes.`);let Z=fw("sha256").update(Q.bundleBytes).digest("hex");if(Q.bundleBytes.byteLength!==_.bundle.bytes||Z!==_.bundle.bundleSha256||!M4(Q.workflow.bundle,_.bundle))throw new j("invalid-data","Workflow bundle identity or bytes do not match.");if(!M4(Q.workflow.workflow,_.graph.workflow)||Q.workflow.sourceLocator!==Q.sourceLocator)throw new j("invalid-data","Workflow source identity does not match the graph plan.");if(!M4(Q.runtime.runtime,_.runtime)||!M4(Q.runtime.computes,JK0(_))||!M4(Q.runtime.operations,YK0(_)))throw new j("invalid-data","Workflow runtime or operation identities do not match.");let F=await this.#Y(Q.runId,!1),X=yq(F);try{await Sw(F,{mode:448})}catch(K){if(v_(K,"EEXIST"))throw new j("conflict",`Workflow run already exists: ${Q.runId}`);throw K}if(await v6(X),!Pq(await b$(F)))throw new j("unsafe-path","New workflow run directory is not private.");await Sw(R1(F,"nodes"),{mode:448}),await Sw(R1(F,"staging"),{mode:448}),await ZJ(R1(F,"runtime.json"),Q.runtime),await ZJ(R1(F,"workflow.json"),Q.workflow),await xw(R1(F,"workflow.bundle.js"),Q.bundleBytes),await ZJ(R1(F,"graph.json"),_.graph),await ZJ(R1(F,"graph-plan.json"),_),await xw(R1(F,"events.jsonl"),""),await xw(R1(F,"grants.jsonl"),"");let Y=await this.#H(F);for(let K of _.graph.nodes){let W=F6.parse({attempt:0,dependencies:K.dependencies,executor:K.executor,nodeKey:K.key,status:K.dependencies.length===0?"ready":"pending",version:$J});await ZJ(R1(Y,QJ(K.key)),W)}let J=new Date().toISOString(),H=mF.parse({counts:{cancelled:0,completed:0,failed:0,pending:_.graph.nodes.length,skipped:0},graphPlanSha256:_.graphPlanSha256,runId:Q.runId,status:"planned",updatedAt:J,version:_6});return await ZJ(R1(F,"summary.json"),H),await ZJ(R1(F,Eq),{graphPlanSha256:_.graphPlanSha256,runId:Q.runId,version:_6}),await v6(Y),await v6(R1(F,"staging")),await v6(F),H}async list(){let $=await this.#F(),Q=await K$1($,{withFileTypes:!0}),_=[];for(let Z of Q.sort((F,X)=>F.name.localeCompare(X.name))){if(!Z.isDirectory()||!Z.name.startsWith("run_"))continue;try{let F=await this.#Y(Z.name),X=await H$(R1(F,Eq),FK0),Y=await H$(R1(F,"summary.json"),mF);if(X.runId!==Y.runId||X.graphPlanSha256!==Y.graphPlanSha256)continue;_.push(Y)}catch{}}return Object.freeze(_.sort((Z,F)=>F.updatedAt.localeCompare(Z.updatedAt)))}async graphPlan($){return(await this.#L($)).graphPlan}async graph($){return(await this.#L($)).graphPlan.graph}async workflow($){return(await this.#L($)).workflow}async runtime($){return(await this.#L($)).runtime}async bundle($){return new Uint8Array((await this.#L($)).bundleBytes)}async stagingDirectory($,Q,_){let Z=Z6.parse($),F=m4.parse(Q),X=G2.parse(_);return await this.#V(Z.runId,async(Y)=>{await this.#z(Y,Z);let J=await this.#M(Y,Z),H=await H$(R1(await this.#H(Y),QJ(F)),F6);if(H.nodeKey!==F||H.executionPlan?.nodePlanSha256!==X)throw new j("conflict",`Node staging identity does not match its exact execution plan: ${F}`);let K=await this.#W(J.directory,"staging"),W=QJ(F).slice(0,-5),V=await this.#J(K,W),N=await this.#J(V,X);return await v6(V),await v6(K),N})}async summary($){let Q=await this.#L($),_=await H$(R1(Q.directory,"summary.json"),mF);if(_.runId!==$||_.graphPlanSha256!==Q.graphPlan.graphPlanSha256)throw new j("invalid-data","Run summary identity is inconsistent.");if(_.outputs!==void 0){let Z=await this.outputs($);if(Z===void 0||!M4(Z.outputs,_.outputs))throw new j("invalid-data","Run summary output identity is inconsistent.")}if(Cd.has(_.status)){let Z=await this.#U(Q);if(!M4(_.counts,Md(Z))||_.status!==VK0(Z)||_.finishedAt===void 0)throw new j("invalid-data","Terminal run summary is inconsistent with node state.")}return _}async#U($){let Q=await this.#H($.directory),_=await Promise.all($.graphPlan.graph.nodes.map(async(F)=>await H$(R1(Q,QJ(F.key)),F6))),Z=new Map(_.map((F)=>[F.nodeKey,F]));if(Z.size!==$.graphPlan.graph.nodes.length)throw new j("invalid-data","Run node identities are duplicated or missing.");for(let F of $.graphPlan.graph.nodes){let X=Z.get(F.key);if(X===void 0)throw new j("invalid-data",`Run is missing authored node ${F.key}.`);this.#T($.graphPlan,F,X,Z)}return Object.freeze(_)}async#P($,Q){let _=$.graphPlan.graph.nodes.find((V)=>V.key===Q);if(_===void 0)throw new j("not-found",`Workflow run node does not exist: ${Q}`);let Z=await this.#H($.directory),F=new Map($.graphPlan.graph.nodes.map((V)=>[V.key,V])),X=new Set,Y=[_.key];while(Y.length>0){let V=Y.pop();if(V===void 0||X.has(V))continue;let N=F.get(V);if(N===void 0)throw new j("invalid-data",`Run graph is missing dependency ${V}.`);X.add(V),Y.push(...N.dependencies)}let J=[...X],H=await Promise.all(J.map(async(V)=>await H$(R1(Z,QJ(V)),F6))),K=new Map(H.map((V)=>[V.nodeKey,V]));if(K.size!==J.length)throw new j("invalid-data",`Run node context contains duplicated or missing identities: ${Q}`);for(let V of J){let N=K.get(V),G=F.get(V);if(N===void 0||G===void 0)throw new j("invalid-data",`Run is missing authored node ${V}.`);this.#T($.graphPlan,G,N,K)}let W=K.get(_.key);if(W===void 0)throw new j("invalid-data",`Run is missing authored node ${_.key}.`);return{authored:_,record:W,recordsByKey:K}}#T($,Q,_,Z){if(_.nodeKey!==Q.key||!M4(_.dependencies,Q.dependencies)||!M4(_.executor,Q.executor))throw new j("invalid-data",`Persisted node identity changed: ${Q.key}`);let F=HK0($,Q);if(_.executionPlan!==void 0&&_.preparationPlan===void 0)throw new j("invalid-data",`Execution plan has no preparation plan for node ${Q.key}.`);if(_.preparationPlan!==void 0){let{preparationPlanSha256:X,...Y}=_.preparationPlan;if(_.preparationPlan.version!==Rw||X!==qw(Y)||_.preparationPlan.graphPlanSha256!==$.graphPlanSha256||_.preparationPlan.nodeKey!==Q.key||!M4(_.preparationPlan.executor,Q.executor)||!M4(_.preparationPlan.requestedPreparation,[...F.preparation].sort((J,H)=>J.localeCompare(H)))||_.preparationPlan.upperDurationMs>F.maxDurationMs||_.preparationPlan.upperInputBytes>F.maxInputBytes)throw new j("invalid-data",`Preparation plan digest or identity is invalid for node ${Q.key}.`)}if(_.executionPlan!==void 0){let{nodePlanSha256:X,...Y}=_.executionPlan,J=Object.fromEntries([...Q.dependencies].sort((K,W)=>K.localeCompare(W)).map((K)=>{let W=Z.get(K);if(W?.status!=="completed"||W.output===void 0)throw new j("invalid-data",`Execution plan for ${Q.key} references incomplete dependency ${K}.`);return[K,W.output.digestSha256]})),H=[..._.executionPlan.publicationKeys].sort((K,W)=>K.localeCompare(W));if(_.executionPlan.version!==kw||X!==Ew(Y)||_.executionPlan.inputSha256!==r70(_.executionPlan.exactInput)||_.executionPlan.graphPlanSha256!==$.graphPlanSha256||_.executionPlan.nodeKey!==Q.key||_.executionPlan.preparationPlanSha256!==_.preparationPlan?.preparationPlanSha256||!M4(_.executionPlan.executor,Q.executor)||!M4(_.executionPlan.policy,E$1(F))||!M4(_.executionPlan.dependencyOutputDigests,J)||!M4(_.executionPlan.publicationKeys,H)||new Set(H).size!==H.length)throw new j("invalid-data",`Execution plan digest or identity is invalid for node ${Q.key}.`)}if(_.output!==void 0&&_.output.digestSha256!==o70(_.output.value))throw new j("invalid-data",`Output digest is invalid for node ${Q.key}.`)}async node($,Q){let _=m4.parse(Q),Z=await this.#L($);return(await this.#P(Z,_)).record}async nodes($){let Q=await this.#L($);return await this.#U(Q)}async events($){let Q=await this.#Y($),_=await Ud(R1(Q,"events.jsonl"),Rq);return WK0(_,$),_}async grants($){let Q=await this.#L($),_=await Ud(R1(Q.directory,"grants.jsonl"),Pw);return zd(_,$,Q.graphPlan.graphPlanSha256),_}async outputs($){let Q=await this.#L($),_=R1(Q.directory,"outputs.json"),Z=await H$(_,kq).catch((H)=>{if(H instanceof j&&H.code==="not-found")return;throw H});if(Z===void 0)return;if(Z.runId!==$||Z.graphPlanSha256!==Q.graphPlan.graphPlanSha256||Z.outputsSha256!==Nd(Z.outputs))throw new j("invalid-data","Persisted run outputs have an invalid identity.");let F=await this.#U(Q),X=new Map(F.map((H)=>[H.nodeKey,H])),Y={},J=gq(Q.graphPlan.graph.outputs,X,Y);if(J===void 0||!M4(Z.outputs,J)||!M4(Z.nodeOutputDigests,Y))throw new j("invalid-data","Persisted run outputs differ from completed nodes.");return Z}async#R($){let Q=R1($,_J),_;try{_=await b$(Q)}catch(F){if(v_(F,"ENOENT"))return;throw F}return{fence:await H$(Q,Z6),snapshot:E9(_)}}async#z($,Q){let _=Z6.parse(Q),Z=await this.#R($);if(Z===void 0||Z.fence.generation!==_.generation||Z.fence.token!==_.token||Z.fence.owner!==_.owner||Z.fence.runId!==_.runId)throw this.#q(_),new j("conflict",`Workflow run fence is stale: ${_.runId}`);return _}async#E($,Q,_){let Z=this.#K(Q)?.eventJournal,F=await KK0(R1($,"events.jsonl"),Rq,(X)=>WK0(X,Q.runId),({cursor:X})=>{if(Q.generation({lastFenceGeneration:Y.fenceGeneration,lastSequence:Y.sequence}),Z);return this.#w(Q,{eventJournal:F.state}),F.result}async acquireClaim($,Q){return await this.#V($,async(_)=>{let Z=await this.#O(_,$),F=(Q.now??(()=>new Date))(),X=Q.staleAfterMs??30000;if(!Number.isSafeInteger(X)||X<0)throw new j("usage","Run claim stale interval must be a nonnegative safe integer.");let Y=await this.#R(_),J=Y?.fence.generation??0;if(Y!==void 0){let V=F.getTime()-Date.parse(Y.fence.acquiredAt),N=Y.fence.hostname!==qq()||(Q.processAlive??XK0)(Y.fence.pid);if(V{return});if(G===void 0||!FJ(Y.snapshot,E9(G)))throw new j("conflict",`Workflow run claim changed during reclaim: ${$}`);await QK(R1(_,_J)),await v6(_)}this.#N($);let H=await H$(R1(_,ZK0),z$1).catch((V)=>{if(V instanceof j&&V.code==="not-found")return;throw V});J=Math.max(J,H?.generation??0);let K=J+1,W=Z6.parse({acquiredAt:F.toISOString(),generation:K,hostname:qq(),owner:Q.owner,pid:process.pid,runId:$,token:fq(),version:Hd});await bq(R1(_,ZK0),{generation:K,version:_6});try{return await Iq(R1(_,_J),W),await this.#E(_,W,{details:{owner:W.owner},kind:"run-claimed",timestamp:W.acquiredAt}),this.#w(W,{identity:Z}),W}catch(V){this.#q(W);let N=await this.#R(_).catch(()=>{return});if(N?.fence.token===W.token&&N.fence.generation===W.generation){let G=await b$(R1(_,_J)).catch(()=>{return});if(G!==void 0&&FJ(N.snapshot,E9(G)))await QK(R1(_,_J)).catch(()=>{return}),await v6(_).catch(()=>{return})}throw V}})}async assertFence($){let Q=Z6.parse($);await this.#z(await this.#Y(Q.runId),Q)}async releaseClaim($){let Q=Z6.parse($);await this.#V(Q.runId,async(_)=>{await this.#z(_,Q);let Z=await this.#R(_);if(Z===void 0)throw new j("conflict",`Workflow run fence is stale: ${Q.runId}`);let F=await b$(R1(_,_J));if(!FJ(Z.snapshot,E9(F)))throw new j("conflict",`Workflow run claim changed during release: ${Q.runId}`);await QK(R1(_,_J)),await v6(_),this.#q(Q)})}async appendEvent($,Q){let _=Z6.parse($);return await this.#V(_.runId,async(Z)=>{if(await this.#z(Z,_),Q.nodeKey!==void 0){if(!(await this.#M(Z,_)).graphPlan.graph.nodes.some((X)=>X.key===Q.nodeKey))throw new j("invalid-data",`Run event names an unknown node: ${Q.nodeKey}`)}return await this.#E(Z,_,Q)})}#B($,Q,_,Z,F){if(M$1.has(_.status)){if(!M4(_,Z))throw new j("conflict",`Terminal run node ${_.nodeKey} is immutable.`);return}if(!A$1[_.status].has(Z.status))throw new j("invalid-data",`Illegal run node transition ${_.status} -> ${Z.status} for ${_.nodeKey}.`);let X=_.status==="ready"&&Z.status==="running"?_.attempt+1:_.attempt;if(Z.attempt!==X)throw new j("invalid-data",`Run node attempt changed outside ready -> running for ${_.nodeKey}.`);if(_.preparationPlan!==void 0&&!M4(_.preparationPlan,Z.preparationPlan))throw new j("conflict",`Preparation plan changed for ${_.nodeKey}.`);if(_.executionPlan!==void 0&&!M4(_.executionPlan,Z.executionPlan))throw new j("conflict",`Execution plan changed for ${_.nodeKey}.`);if(!(_.status==="ready"&&Z.status==="running")&&_.startedAt!==Z.startedAt)throw new j("invalid-data",`Run node startedAt changed illegally: ${_.nodeKey}`);if(_.status==="ready"&&Z.status==="running"&&_.startedAt!==void 0&&Date.parse(Z.startedAt)F.get(Y)?.status!=="completed"))throw new j("invalid-data",`Run node ${_.nodeKey} became ready before all dependencies completed.`);if(_.status==="running"&&Z.status==="ready"){let Y=HK0($,Q).resume;if(Y!=="deterministic"&&Y!=="verified-receipt"&&Y!=="recoverable-transaction")throw new j("conflict",`Interrupted node ${_.nodeKey} cannot be retried under ${Y}.`)}}async writeNode($,Q){let _=Z6.parse($);await this.#V(_.runId,async(Z)=>{await this.#z(Z,_);let F=F6.parse(Q),X=await this.#M(Z,_),Y=await this.#P(X,F.nodeKey),J=new Map(Y.recordsByKey);J.set(F.nodeKey,F),this.#B(X.graphPlan,Y.authored,Y.record,F,J),this.#T(X.graphPlan,Y.authored,F,J);let H=await this.#H(Z);await bq(R1(H,QJ(F.nodeKey)),F)})}async writeSummary($,Q){let _=Z6.parse($);await this.#V(_.runId,async(Z)=>{await this.#z(Z,_);let F=mF.parse(Q),X=await this.#M(Z,_);if(F.runId!==_.runId||F.graphPlanSha256!==X.graphPlan.graphPlanSha256)throw new j("invalid-data","Run summary identity is inconsistent.");let Y=await H$(R1(Z,"summary.json"),mF);if(Cd.has(Y.status)){if(!M4(Y,F))throw new j("conflict","Terminal run summary is immutable.");return}if(Date.parse(F.updatedAt)[D.nodeKey,D])),N=gq(X.graphPlan.graph.outputs,V,W);if(N===void 0||F.outputs===void 0||!M4(F.outputs,N))throw new j("invalid-data","Completed run outputs do not match the authored output bindings.");let G=kq.parse({graphPlanSha256:X.graphPlan.graphPlanSha256,nodeOutputDigests:W,outputs:N,outputsSha256:Nd(N),runId:_.runId,version:Kd});try{await Iq(R1(Z,"outputs.json"),G)}catch(D){if(!v_(D,"EEXIST"))throw D;let L=await H$(R1(Z,"outputs.json"),kq);if(!M4(L,G))throw new j("conflict","Run outputs were already published differently.")}}else if(F.outputs!==void 0)throw new j("invalid-data","Only completed runs may publish outputs.");await bq(R1(Z,"summary.json"),F)})}async appendGrant($,Q){let _=Z6.parse($);return await this.#V(_.runId,async(Z)=>{await this.#z(Z,_);let F=await this.#M(Z,_),X=Pw.parse({...Q,runId:_.runId,version:Jd});if(X.graphPlanSha256!==F.graphPlan.graphPlanSha256)throw new j("invalid-data","Run grant targets a different graph plan.");if("nodeKey"in X&&!F.graphPlan.graph.nodes.some((H)=>H.key===X.nodeKey))throw new j("invalid-data",`Run grant targets unknown node ${X.nodeKey}.`);if(X.kind==="compute-replay"&&X.bundleSha256!==F.graphPlan.bundle.bundleSha256)throw new j("invalid-data","Compute replay grant targets a different bundle.");if(X.kind==="compute-replay"){let H=F.graphPlan.graph.nodes.find((V)=>V.key===X.nodeKey);if(H===void 0||!_8(H))throw new j("invalid-data",`Compute replay grant targets a non-compute node: ${X.nodeKey}`);let W=(await this.#U(F)).find((V)=>V.nodeKey===X.nodeKey);if(W?.status!=="ambiguous-code"||W.executionPlan===void 0||X.computeKey!==H.executor.compute.key||X.nodePlanSha256!==W.executionPlan.nodePlanSha256||X.attempt!==W.attempt+1)throw new j("conflict",`Compute replay grant does not match the exact next attempt for ${X.nodeKey}.`)}let Y=this.#K(_)?.grantJournal,J=await KK0(R1(Z,"grants.jsonl"),Pw,(H)=>zd(H,_.runId,F.graphPlan.graphPlanSha256),({cursor:H})=>{if(H.grantIds.has(X.grantId))throw new j("conflict",`Run grant already exists: ${X.grantId}`);return{entry:X,result:X}},(H,K)=>{return H.grantIds.add(K.grantId),H},Y);return this.#w(_,{grantJournal:J.state}),J.result})}async reopenComputeNode($,Q){let _=Z6.parse($),Z=m4.parse(Q);return await this.#V(_.runId,async(F)=>{await this.#z(F,_);let X=await this.#M(F,_),Y=X.graphPlan.graph.nodes.find((D)=>D.key===Z);if(Y===void 0||!_8(Y))throw new j("invalid-data",`Only a trusted compute node may be reopened: ${Z}`);let J=await this.#U(X),H=J.find((D)=>D.nodeKey===Z);if(H?.status!=="ambiguous-code"||H.executionPlan===void 0)throw new j("conflict",`Compute node is not awaiting an explicit replay: ${Z}`);let K=await Ud(R1(F,"grants.jsonl"),Pw);if(zd(K,_.runId,X.graphPlan.graphPlanSha256),!K.some((D)=>D.kind==="compute-replay"&&D.nodeKey===Z&&D.attempt===H.attempt+1&&D.bundleSha256===X.graphPlan.bundle.bundleSha256&&D.computeKey===Y.executor.compute.key&&D.nodePlanSha256===H.executionPlan?.nodePlanSha256))throw new j("authorization-required",`Compute node ${Z} requires an exact replay grant for attempt ${String(H.attempt+1)}.`);let V={...H};delete V.failure,delete V.finishedAt;let N=F6.parse({...V,status:"ready"}),G=new Map(J.map((D)=>[D.nodeKey,D.nodeKey===Z?N:D]));return this.#T(X.graphPlan,Y,N,G),await bq(R1(await this.#H(F),QJ(Z)),N),N})}async requestCancellation($,Q,_=new Date){return await this.#V($,async(Z)=>{await this.#j(Z,$);let F=R1(Z,"cancel-request.json"),X=await H$(F,Iw).catch((J)=>{if(J instanceof j&&J.code==="not-found")return;throw J});if(X!==void 0)return X;let Y=Iw.parse({requestedAt:_.toISOString(),requestedBy:Q,runId:$,version:_6});try{return await Iq(F,Y),Y}catch(J){let H=await H$(F,Iw).catch(()=>{return});if(H!==void 0)return H;throw J}})}async cancellation($){let Q=await this.#Y($);return await H$(R1(Q,"cancel-request.json"),Iw).then((_)=>{if(_.runId!==$)throw new j("invalid-data","Cancellation request targets a different run.");return _}).catch((_)=>{if(_ instanceof j&&_.code==="not-found")return;throw _})}}import{Deferred as dq,Effect as d1,Either as vw,Exit as LK0,Fiber as y$1,Queue as Rd}from"effect";import{randomUUID as kd}from"crypto";import{performance as JJ}from"perf_hooks";var x$1=32,v$1=128,h$1=2000,g$1=4000,m$1=100,u$1=Object.freeze({browser:1,"capture-device":1,cpu:4,ffmpeg:2,"local-io":4,network:4,"output-publication":4,"paid-call":1,"project-render":1,"project-publication":1,vision:1,whisper:1});function wK0($,Q){return Q>Number.MAX_SAFE_INTEGER-$?Number.MAX_SAFE_INTEGER:$+Q}function Id($){return d1.suspend(()=>{let Q=$-JJ.now();return Q<=0?d1.void:d1.zipRight(d1.sleep(Math.min(Q,2147483647)),Id($))})}class AK0{#$=new AbortController;deadlineMonotonicMs;#Q;#Z;#X;#F;#Y;constructor($,Q,_){this.#X=$,this.deadlineMonotonicMs=Q,this.#Z=_,this.#Q=$.deferred(),this.#F=$.watch(d1.zipRight(Id(Q),d1.sync(()=>{this.interrupt("deadline",new j("cancelled","Workflow exceeded the host wall-clock bound."))})))}get interruption(){return this.#Y}get signal(){return this.#$.signal}interrupt($,Q){if(this.#Y!==void 0)return;let _={error:Q,kind:$};this.#Y=_,this.#$.abort(Q),this.#Z(_),dq.unsafeDone(this.#Q,d1.fail(_Z(Q,"monitor")))}assertActive(){if(this.#Y!==void 0)throw this.#Y.error}async race($){return this.assertActive(),await this.#X.run(d1.raceFirst(T1("authority",$),dq.await(this.#Q)))}async custody($){return await this.#X.custody($)}async runNative($){return await this.#X.run($)}async stop(){await this.#F()}}function hw($,Q){if(!Number.isSafeInteger($)||$<1)throw new j("usage",`${Q} must be a positive safe integer.`);return $}function l$1($,Q){if(!Number.isSafeInteger($)||$<0)throw new j("usage",`${Q} must be a nonnegative safe integer.`);return $}function d$1($){let Q=hw($.hostLimits?.maxJobs??4,"Host job limit"),_=$.jobs===void 0?Q:hw($.jobs,"Requested job limit"),Z=$.hostLimits?.resources??{},F=Object.fromEntries(XO.map((X)=>[X,l$1(Z[X]??u$1[X],`Host ${X} limit`)]));return{cancellationPollMs:hw($.cancellationPollMs??m$1,"Cancellation poll interval"),jobs:Math.min(Q,_),maxNodes:hw($.hostLimits?.maxNodes??4096,"Host node limit"),maxWallClockMs:hw($.hostLimits?.maxWallClockMs??86400000,"Host workflow wall-clock limit"),resources:F}}function c$1($){return Tq($).sha256}function TK0($){return typeof $==="object"&&$!==null&&!Array.isArray($)&&Object.hasOwn($,"$ref")}function p$1($){return Array.isArray($)}function s$1($){return Array.isArray($)}function bd($){if($.status!=="completed"||$.output===void 0)throw new j("invalid-data",`Dependency ${$.nodeKey} does not have a completed output.`);let Q=w1.parse($.output.value);if(c$1(Q)!==$.output.digestSha256)throw new j("invalid-data",`Completed output digest does not match for node ${$.nodeKey}.`);return $.output}function Ed($,Q){if(TK0($)){let _=Q.get($.$ref.nodeKey);if(_===void 0)throw new j("invalid-data",`Node input references unavailable output ${$.$ref.nodeKey}.`);return bw($,_.value)}if(p$1($))return $.map((_)=>Ed(_,Q));if(typeof $==="object"&&$!==null)return Object.fromEntries(Object.entries($).sort(([_],[Z])=>_.localeCompare(Z)).map(([_,Z])=>[_,Ed(Z,Q)]));return $}function BK0($,Q){let _=new Map,Z={};for(let F of[...$.dependencies].sort((X,Y)=>X.localeCompare(Y))){let X=Q.get(F);if(X===void 0)throw new j("invalid-data",`Missing dependency node ${F}.`);let Y=bd(X);_.set(F,Y),Z[F]=Y}return{dependencyOutputs:Z,input:w1.parse(Ed($.input,_))}}function Sd($){return KK.parse({...$,preparation:[...$.preparation].sort((Q,_)=>Q.localeCompare(_)),resources:[...$.resources].sort((Q,_)=>Q.resource.localeCompare(_.resource))})}function CK0($){return{...$,inputSchemaId:$.inputSchemaId.replace(/^studio\./u,"slopcamera."),outputSchemaId:$.outputSchemaId.replace(/^studio\./u,"slopcamera."),policy:HK.parse(Sd($.policy))}}function gw($,Q,_){let Z=Q.executor.operation,F=_.get(Z.kind,Z.version),X=$.registry.discovery.find((Y)=>Y.kind===Z.kind&&Y.version===Z.version);if(X===void 0)throw new j("incompatible",`Graph plan omits operation ${Z.kind}@${String(Z.version)}.`);if(R(CK0(F.discovery))!==R(CK0(X)))throw new j("incompatible",`Registered operation changed after planning: ${Z.kind}@${String(Z.version)}.`);return F}function UK0($,Q,_){if(A4(Q)){let Z=gw($,Q,_);return{kind:"operation",operation:Z,policy:Z.discovery.policy}}if(_8(Q))return{compute:Q.executor.compute,kind:"compute",policy:WK(Q.executor.compute)};throw new j("internal",`Unknown node executor for ${Q.key}.`)}function RK0($){if($.length>64)throw new j("invalid-data","A node may claim at most 64 publication keys.");let Q=[...$].map((_)=>{if(_.length<1||_.length>512)throw new j("invalid-data","Publication keys must contain between 1 and 512 characters.");return _}).sort((_,Z)=>_.localeCompare(Z));if(new Set(Q).size!==Q.length)throw new j("invalid-data","A node cannot claim a publication key twice.");return Q}function n$1($){let Q=JZ($.input,"studio.workflow.compute-input-descriptor/v1\x00");return{inputDescriptors:w1.parse({bytes:Q.bytes,inputSha256:Q.sha256}),upperInputBytes:Q.bytes}}function r$1($,Q,_,Z){let F=Z.upperDurationMs??_.maxDurationMs,X=Z.upperInputBytes??_.maxInputBytes;if(!Number.isSafeInteger(F)||F<0||F>_.maxDurationMs)throw new j("invalid-data",`Preparation duration bound exceeds policy for node ${Q.key}.`);if(!Number.isSafeInteger(X)||X<0||X>_.maxInputBytes)throw new j("invalid-data",`Preparation input bound exceeds policy for node ${Q.key}.`);let Y=Cq.parse({exactInputBound:!0,executor:Q.executor,graphPlanSha256:$.graphPlanSha256,inputDescriptors:w1.parse(Z.inputDescriptors),nodeKey:Q.key,requestedPreparation:[..._.preparation].sort((J,H)=>J.localeCompare(H)),upperDurationMs:F,upperInputBytes:X,version:Rw});return Uq.parse({...Y,preparationPlanSha256:qw(Y)})}function o$1($,Q,_,Z,F,X){let Y=w1.parse(X.exactInput),J=Aq(Y),H=J.bytes,K=Z.exactInputBound===!0?Z.upperInputBytes:_.maxInputBytes;if(H>K)throw new j("invalid-data",`Exact input for node ${Q.key} uses ${String(H)} canonical JSON bytes; the ${Z.exactInputBound===!0?"prepared upper bound":"operation input limit"} is ${String(K)}.`);let W=Object.fromEntries(Object.entries(F.dependencyOutputs).sort(([N],[G])=>N.localeCompare(G)).map(([N,G])=>[N,G.digestSha256])),V=zq.parse({dependencyOutputDigests:W,executor:Q.executor,exactInput:Y,...X.expectedProjectGeneration===void 0?{}:{expectedProjectGeneration:X.expectedProjectGeneration},graphPlanSha256:$.graphPlanSha256,inputSha256:J.sha256,nodeKey:Q.key,policy:Sd(_),preparationPlanSha256:Z.preparationPlanSha256,publicationKeys:RK0(X.publicationKeys),version:kw});return Mq.parse({...V,nodePlanSha256:Ew(V)})}function i$1($,Q,_,Z){let F=Uq.parse($),{preparationPlanSha256:X,...Y}=F;if(X!==qw(Y)||F.graphPlanSha256!==Q.graphPlanSha256||F.nodeKey!==_.key||R(F.executor)!==R(_.executor)||F.upperDurationMs>Z.maxDurationMs||F.upperInputBytes>Z.maxInputBytes||R(F.requestedPreparation)!==R([...Z.preparation].sort((J,H)=>J.localeCompare(H))))throw new j("invalid-data",`Persisted preparation plan no longer matches node ${_.key}.`)}function a$1($,Q,_,Z,F,X){let Y=Mq.parse($),{nodePlanSha256:J,...H}=Y,K=Aq(Y.exactInput),W=K.bytes,V=F.exactInputBound===!0?F.upperInputBytes:Z.maxInputBytes,N=Object.fromEntries(Object.entries(X.dependencyOutputs).sort(([G],[D])=>G.localeCompare(D)).map(([G,D])=>[G,D.digestSha256]));if(J!==Ew(H)||W>V||Y.inputSha256!==K.sha256||Y.graphPlanSha256!==Q.graphPlanSha256||Y.nodeKey!==_.key||Y.preparationPlanSha256!==F.preparationPlanSha256||R(Y.executor)!==R(_.executor)||R(Y.policy)!==R(Sd(Z))||R(Y.dependencyOutputDigests)!==R(N)||R(Y.publicationKeys)!==R(RK0(Y.publicationKeys)))throw new j("invalid-data",`Persisted execution plan no longer matches node ${_.key}.`)}function zK0($){return typeof $==="boolean"?$:$.allowed}function t$1($,Q,_,Z){return $.some((F)=>F.kind==="preparation"&&F.graphPlanSha256===Q&&F.nodeKey===_&&F.preparationPlanSha256===Z)}function e$1($,Q,_,Z){return $.some((F)=>F.kind==="effect"&&F.graphPlanSha256===Q&&F.nodeKey===_&&F.nodePlanSha256===Z)}function $81($){return($.length===0?"Unknown scheduler failure.":$).slice(0,g$1)}function t8($,Q=!1){let _=zJ($),Z=G8.safeParse(_.details?.spatialPublication);return{code:(()=>{switch(_.code){case"authorization-required":case"cancelled":case"conflict":case"incompatible":case"invalid-data":case"subprocess":case"unavailable":case"unsupported-plan":case"ambiguous":case"internal":return _.code;case"not-found":case"unsafe-path":case"usage":return"invalid-data"}})(),message:$81(_.message),retryable:Q,...Z.success?{spatialPublication:Z.data}:{}}}function Q81($){let Q=Object.entries($).sort(([_],[Z])=>_.localeCompare(Z));if(Q.length>x$1)throw new j("internal","Operation summary exceeds the scheduler field limit.");return Object.fromEntries(Q.map(([_,Z])=>{if(_.length<1||_.length>v$1)throw new j("internal","Operation summary contains an invalid field name.");if(typeof Z==="number"&&!Number.isFinite(Z))throw new j("internal","Operation summary contains a non-finite number.");if(typeof Z==="string"&&Z.length>h$1)throw new j("internal","Operation summary contains an oversized string.");return[_,Z]}))}function qd($,Q,_,Z){let F=w1.parse($),X=Tq(F),Y=X.bytes;if(Y>_)throw new j("invalid-data",`Operation output uses ${String(Y)} bytes; the limit is ${String(_)}.`);return{digestSha256:X.sha256,...Z===void 0?{}:{receiptReference:Z},summary:Q81(Q),value:F}}function _81($){return["ambiguous","cancelled","failed","incompatible","skipped"].includes($.status)}function Z81($){return $.status==="pending"||$.status==="ready"||$.status==="preparing"||$.status==="approval-required"}class kK0{#$;#Q;#Z=new Set;#X;#F=0;constructor($){this.#$=$.jobs,this.#Q=$.resources,this.#X=Object.fromEntries(XO.map((Q)=>[Q,0]))}impossible($){return $.some((Q)=>Q.amount>this.#Q[Q.resource])}acquire($,Q){if(this.#F>=this.#$)return!1;if(Q.some((_)=>this.#Z.has(_)))return!1;if($.some((_)=>this.#X[_.resource]+_.amount>this.#Q[_.resource]))return!1;this.#F+=1;for(let _ of $)this.#X[_.resource]+=_.amount;for(let _ of Q)this.#Z.add(_);return!0}release($,Q){this.#F-=1;for(let _ of $)this.#X[_.resource]-=_.amount;for(let _ of Q)this.#Z.delete(_)}}function uq($,Q){return{...$,hostResourceLease:{assertOwned:async()=>await Q.assertOwned(),claims:Q.claims,inheritedFileDescriptor:Q.inheritedFileDescriptor,inheritedFileDescriptors:[Q.inheritedFileDescriptor],profile:Q.profile,ticket:Q.ticket},runner:{run:async(_,Z={})=>{await Q.assertOwned();let F=[...Z.inheritedFileDescriptors??[],Q.inheritedFileDescriptor].filter((X,Y,J)=>J.indexOf(X)===Y);if(F.length>16)throw new j("incompatible","A workflow subprocess cannot inherit more than 16 file descriptors.");return await $.runner.run(_,{...Z,inheritedFileDescriptors:F})}}}}function F81($){if(!($ instanceof P2))return zJ($);switch($.code){case"WAIT_ABORTED":return new j("cancelled",$.message);case"WAIT_TIMEOUT":return new j("unavailable",$.message);case"OWNERSHIP_LOST":return new j("conflict",$.message);case"INVALID_CLAIMS":case"INVALID_PROFILE":case"PROFILE_MISMATCH":case"UNSAFE_STATE":case"UNSUPPORTED_PLATFORM":return new j("incompatible",$.message);default:return $.code}}function qK0($){return{cancelled:$.filter((Q)=>Q.status==="cancelled").length,completed:$.filter((Q)=>Q.status==="completed").length,failed:$.filter((Q)=>Q.status==="failed"||Q.status==="incompatible"||Q.status==="ambiguous").length,pending:$.filter((Q)=>Q.status==="pending"||Q.status==="ready"||Q.status==="preparing"||Q.status==="running"||Q.status==="approval-required"||Q.status==="ambiguous-code").length,skipped:$.filter((Q)=>Q.status==="skipped").length}}function MK0($,Q,_){if(Q.pause!==void 0)return"approval-required";if($.some((F)=>F.status==="approval-required"))return"approval-required";if($.some((F)=>F.status==="ambiguous-code"))return"ambiguous-code";if(_>0||$.some((F)=>F.status==="running")||$.some(Z81))return"running";let Z=qK0($);if(Z.cancelled>0)return"cancelled";if(Z.failed===0&&Z.skipped===0&&Z.completed===$.length)return"completed";if(Q.cancelled)return"cancelled";if($.some((F)=>F.status==="incompatible")&&Z.completed===0)return"incompatible";if(Z.completed>0)return"partial";return"failed"}function lq($){return $==="cancelled"||$==="completed"||$==="failed"||$==="incompatible"||$==="partial"}function Pd($,Q){if(TK0($)){let Z=Q.get($.$ref.nodeKey);if(Z===void 0||Z.status!=="completed")return;return bw($,bd(Z).value)}if(s$1($)){let Z=[];for(let F of $){let X=Pd(F,Q);if(X===void 0)return;Z.push(X)}return Z}let _={};for(let[Z,F]of Object.entries($).sort(([X],[Y])=>X.localeCompare(Y))){let X=Pd(F,Q);if(X===void 0)return;_[Z]=X}return _}class fd{#$;#Q;#Z;#X;#F;#Y;#H;#W;#J;#V;#j;#A=new Set;#_;constructor($){if($.owner.length<1||$.owner.length>256)throw new j("usage","Scheduler owner must contain between 1 and 256 characters.");if($.authorization.grantedBy.length<1||$.authorization.grantedBy.length>256)throw new j("usage","Authorization owner must contain between 1 and 256 characters.");if(this.#$=$.application,this.#Q=$.authorization,this.#Z=$.compute,this.#X=$.compute?.kind==="fresh"?$.compute.executor:void 0,$.currentApplicationBuild.length<1||$.currentApplicationBuild.length>160)throw new j("usage","Current application build must contain between 1 and 160 characters.");this.#F=$.currentApplicationBuild,this.#Y=$.hostResourceCoordinator,this.#H=d$1($),this.#W=$.nodePlanner,this.#J=$.now??(()=>new Date),this.#V=$.owner,this.#j=$.registry,this.#_=$.store}async run($){let Q=new Xd;try{return await Q.run(this.#C($,Q))}finally{await Q.stop()}}#C($,Q){return m70(d1.gen(this,function*(){let _=yield*T1("authority",()=>this.#_.graphPlan($));if(_.graph.nodes.length>this.#H.maxNodes)return yield*d1.fail(_Z(new j("incompatible",`Workflow has ${String(_.graph.nodes.length)} nodes; the host limit is ${String(this.#H.maxNodes)}.`)));let Z=!0,F=yield*Fd(T1("admission",()=>this.#_.acquireClaim($,{owner:this.#V})),(w)=>Z?this.#D(w):d1.void),X;yield*Fd(d1.void,()=>T1("cleanup",()=>X?.release()));let Y=wK0(JJ.now(),this.#H.maxWallClockMs),H={cancelled:!1,monitorError:void 0,pause:void 0,reconciliationDeferred:!1,startedAt:(yield*T1("authority",()=>this.#O($))).startedAt??this.#J().toISOString()},K=new Map,W=yield*Rd.unbounded(),V=new Map,N=new kK0(this.#H),G=new AK0(Q,Y,(w)=>{if(w.kind==="monitor")H.monitorError=w.error;else H.cancelled=!0;if(w.kind!=="deadline"){for(let B of K.values())if(B.admissionAbortController.abort(),B.cancellable)B.abortController.abort()}}),D=Q.watch(d1.forever(d1.gen(this,function*(){yield*d1.sleep(this.#H.cancellationPollMs);let w=yield*d1.either(T1("monitor",()=>this.#K($)));if(vw.isLeft(w))G.interrupt("monitor",zJ(w.left.cause));else if(w.right!==void 0)G.interrupt("cancellation",new j("cancelled","Workflow cancellation requested."))}))),L=yield*d1.exit(d1.catchAll(d1.gen(this,function*(){yield*T1("authority",()=>this.#_.assertFence(F)),yield*T1("authority",()=>this.#_.appendEvent(F,{details:{status:"running"},kind:"run-status",timestamp:this.#J().toISOString()}));let w=yield*d1.either(d1.gen(this,function*(){yield*T1("authority",()=>this.#q($,_)),X=yield*T1("authority",()=>this.#M(F,_,H,G))}));if(vw.isLeft(w)){let B=w.left.cause,C=zJ(B);if(C.code!=="incompatible"&&C.code!=="unsupported-plan")return yield*d1.fail(_Z(B));yield*T1("authority",()=>this.#x(F,_,H,C));let U=yield*T1("authority",()=>this.#k(F,_,H,0));return yield*T1("authority",()=>this.#_.appendEvent(F,{details:{status:U.status},kind:"run-finalized",timestamp:this.#J().toISOString()})),yield*T1("authority",()=>this.#_.releaseClaim(F)),Z=!1,{summary:U}}if(yield*T1("authority",()=>this.#L(F,_,H,G)),yield*T1("authority",()=>this.#k(F,_,H,K.size)),H.reconciliationDeferred){let B=yield*T1("authority",()=>this.#k(F,_,H,0));return yield*T1("authority",()=>this.#_.appendEvent(F,{details:{status:B.status},kind:"run-status",timestamp:this.#J().toISOString()})),yield*T1("authority",()=>this.#_.releaseClaim(F)),Z=!1,{summary:B}}while(!0){if(H.monitorError!==void 0)return yield*d1.fail(_Z(H.monitorError));if(yield*T1("authority",()=>this.#_.assertFence(F)),(yield*T1("authority",()=>this.#K($)))!==void 0){H.cancelled=!0;for(let z of K.values())if(z.admissionAbortController.abort(),z.cancellable)z.abortController.abort()}if(JJ.now()>=Y){H.cancelled=!0;for(let z of K.values())if(z.admissionAbortController.abort(),z.cancellable)z.abortController.abort()}if(yield*T1("authority",()=>this.#T(F,_,H)),H.cancelled)yield*T1("authority",()=>this.#I(F,_));else if(H.pause===void 0){if(yield*T1("authority",()=>this.#R(F,_,H,G,V)),H.pause===void 0){if(yield*T1("authority",()=>this.#B(F,V,K,N,Y,G,Q,W)),H.cancelled)yield*T1("authority",()=>this.#I(F,_))}}if(K.size>0){let z=yield*Rd.take(W),M=K.get(z.nodeKey);if(M===void 0)continue;let T={item:M,outcome:yield*z.outcome};K.delete(T.item.nodeKey),N.release(T.item.resources,T.item.publicationKeys);let q=yield*T1("authority",()=>this.#S(F,_,T.item,T.outcome,G));if(yield*T1("authority",()=>this.#k(F,_,H,K.size)),q){H.reconciliationDeferred=!0;let E=yield*T1("authority",()=>this.#k(F,_,H,K.size));return yield*T1("authority",()=>this.#_.appendEvent(F,{details:{status:E.status},kind:"run-status",timestamp:this.#J().toISOString()})),yield*T1("authority",()=>this.#_.releaseClaim(F)),Z=!1,{summary:E}}continue}let B=yield*T1("authority",()=>this.#_.nodes($));if(MK0(B,H,0)==="running"){if(yield*T1("authority",()=>this.#b(F,_,N)))continue;return yield*d1.fail(_Z(new j("internal","Workflow scheduler reached a nonterminal state without runnable work.")))}let U=yield*T1("authority",()=>this.#k(F,_,H,0));return yield*T1("authority",()=>this.#_.appendEvent(F,{details:{status:U.status},kind:lq(U.status)?"run-finalized":"run-status",timestamp:this.#J().toISOString()})),yield*T1("authority",()=>this.#_.releaseClaim(F)),Z=!1,{...H.pause===void 0?{}:{pause:H.pause},summary:U}}}),(w)=>d1.gen(this,function*(){let B=w.cause;if(Z&&(G.interruption?.kind==="cancellation"||G.interruption?.kind==="deadline")){let C=[...K.values()].sort((z,M)=>z.nodeKey.localeCompare(M.nodeKey));if(C.length>0){let z=yield*d1.forEach(C,(M)=>d1.flatMap(y$1.join(M.fiber),(T)=>d1.map(T,(q)=>({item:M,outcome:q}))),{concurrency:"unbounded"});K.clear();for(let M of z){N.release(M.item.resources,M.item.publicationKeys);let T=yield*T1("authority",()=>this.#S(F,_,M.item,M.outcome,G));H.reconciliationDeferred||=T}}yield*T1("authority",()=>this.#I(F,_));let U=yield*T1("authority",()=>this.#k(F,_,H,K.size));return yield*T1("authority",()=>this.#_.appendEvent(F,{details:{status:U.status},kind:lq(U.status)?"run-finalized":"run-status",timestamp:this.#J().toISOString()})),yield*T1("authority",()=>this.#_.releaseClaim(F)),Z=!1,{summary:U}}if(Z){let C=zJ(B);if(C.code!=="conflict")yield*T1("authority",()=>this.#y(F,_,H,C).catch(()=>{return}))}return yield*d1.fail(_Z(B))}))),O=yield*d1.exit(d1.gen(this,function*(){yield*T1("authority",()=>D()),yield*T1("authority",()=>G.stop())}));return yield*LK0.zipLeft(L,O)}))}#D($){return d1.gen(this,function*(){let Q=yield*d1.either(T1("cleanup",()=>this.#_.assertFence($)));if(vw.isLeft(Q)){if(Q.left.cause instanceof j&&Q.left.cause.code==="conflict")return;return yield*d1.fail(Q.left)}let _=yield*d1.either(T1("cleanup",()=>this.#_.releaseClaim($)));if(vw.isRight(_))return;if(_.left.cause instanceof j&&_.left.cause.code==="conflict"){let Z=yield*d1.either(T1("cleanup",()=>this.#_.assertFence($)));if(vw.isLeft(Z)&&Z.left.cause instanceof j&&Z.left.cause.code==="conflict")return}return yield*d1.fail(_.left)})}async#O($){return await this.#_.summary($)}async#K($){let Q;for(let _=0;_<4;_+=1)try{return await this.#_.cancellation($)}catch(Z){let F=zJ(Z);if(F.code!=="conflict")throw Z;Q=F,await Promise.resolve()}throw Q??new j("conflict",`Could not read a stable cancellation marker for ${$}.`)}async#N($,Q){if(Q.assertActive(),await Q.race(async()=>await this.#K($.runId))!==void 0)Q.interrupt("cancellation",new j("cancelled","Workflow cancellation requested.")),Q.assertActive()}async#w($,Q,_){await this.#N($,Q);let Z=await Q.race(_);return Q.assertActive(),Z}async#q($,Q){if(Q.runtime.applicationBuild!==this.#F)throw new j("incompatible","Persisted workflow application build differs from the current host build.");let _=await this.#_.runtime($);if(R(_.runtime)!==R(Q.runtime))throw new j("incompatible","Persisted workflow runtime identity changed.");let Z=[...new Set(Q.graph.nodes.filter(A4).map((Y)=>`${Y.executor.operation.kind}@${String(Y.executor.operation.version)}`))].sort((Y,J)=>Y.localeCompare(J)),F=_.operations.map((Y)=>`${Y.kind}@${String(Y.version)}`).sort((Y,J)=>Y.localeCompare(J));if(R(Z)!==R(F))throw new j("incompatible","Persisted operation runtime set changed.");let X=[...new Map(Q.graph.nodes.filter(_8).map((Y)=>[Y.executor.compute.key,Y.executor.compute])).values()].sort((Y,J)=>Y.key.localeCompare(J.key));if(R(X)!==R(_.computes))throw new j("incompatible","Persisted compute runtime set changed.");for(let Y of Q.graph.nodes)if(A4(Y))gw(Q,Y,this.#j)}async#M($,Q,_,Z){let F=this.#Z;if(F===void 0)return;if(F.kind==="fresh"){if(F.executor.bundleSha256!==Q.bundle.bundleSha256)throw new j("incompatible","Fresh code worker bundle does not match the persisted graph plan.");this.#X=F.executor;return}let X=[...new Set(F.nodeKeys.map((N)=>m4.parse(N)))].sort((N,G)=>N.localeCompare(G));if(X.length===0)throw new j("usage","A compute replay requires at least one exact node key.");if(await this.#K($.runId)!==void 0){_.cancelled=!0;return}let Y=await this.#_.nodes($.runId),J=new Map(Q.graph.nodes.map((N)=>[N.key,N])),H=[];for(let N of X){let G=J.get(N),D=Y.find((L)=>L.nodeKey===N);if(G===void 0||!_8(G)||D?.status!=="ambiguous-code"||D.executionPlan===void 0)throw new j("conflict",`Compute node is not awaiting exact replay: ${N}`);H.push({attempt:D.attempt+1,bundleSha256:Q.bundle.bundleSha256,computeKey:G.executor.compute.key,createdAt:this.#J().toISOString(),graphPlanSha256:Q.graphPlanSha256,grantedBy:this.#Q.grantedBy,grantId:kd(),kind:"compute-replay",nodeKey:N,nodePlanSha256:D.executionPlan.nodePlanSha256})}for(let N of H){if(await this.#K($.runId)!==void 0){_.cancelled=!0;return}await this.#_.appendGrant($,N)}if(await this.#K($.runId)!==void 0){_.cancelled=!0;return}await this.#N($,Z);let K=Z.deadlineMonotonicMs-JJ.now();if(K<=0)Z.interrupt("deadline",new j("cancelled","Workflow exceeded the host wall-clock bound.")),Z.assertActive();let W=F.load({signal:Z.signal,waitTimeoutMilliseconds:Math.min(TQ,Math.max(1,Math.ceil(K)))}),V;try{V=await Z.race(async()=>await W)}catch(N){throw W.then(async(G)=>await G.release(),()=>{return}).catch(()=>{return}),N}try{if(Z.assertActive(),V.executor.bundleSha256!==Q.bundle.bundleSha256)throw new j("incompatible","Replay code worker bundle does not match the persisted graph plan.");this.#X=V.executor;for(let N of X)this.#A.add(N);for(let N of X)await this.#_.reopenComputeNode($,N);return V}catch(N){throw await V.release().catch(()=>{return}),N}}async#L($,Q,_,Z){let F=await this.#_.nodes($.runId),X=new Map(F.map((Y)=>[Y.nodeKey,Y]));for(let Y of[...Q.graph.nodes].sort((J,H)=>J.key.localeCompare(H.key))){let J=X.get(Y.key);if(J===void 0)throw new j("invalid-data",`Run is missing node ${Y.key}.`);if(J.status==="completed"){bd(J),await this.#_.appendEvent($,{details:{digestSha256:J.output?.digestSha256??""},kind:"node-reused",nodeKey:Y.key,timestamp:this.#J().toISOString()});continue}if(J.status==="approval-required")continue;if(J.status==="preparing"){await this.#G($,{...J,status:"ready"});continue}if(J.status!=="running")continue;if(_8(Y)){await this.#G($,{...J,failure:t8(new j("ambiguous","Interrupted trusted compute requires an explicit exact-bundle replay.")),finishedAt:this.#J().toISOString(),status:"ambiguous-code"});continue}if(!A4(Y))throw new j("internal",`Unknown node executor for ${Y.key}.`);let H=gw(Q,Y,this.#j).discovery.policy.resume;if(H==="deterministic"){await this.#G($,{...J,failure:void 0,finishedAt:void 0,status:"ready"});continue}let K=await this.#U($,Q,Y,J,X,Z);if(K.deferred){if(_.reconciliationDeferred=!0,Z.interruption!==void 0)break;continue}if(K.reconciliation?.kind==="ambiguous"&&H==="non-resumable-live")_.cancelled=!1}}async#U($,Q,_,Z,F,X){let Y=gw(Q,_,this.#j),J=BK0(_,F),H=Y.discovery.policy.resume;await this.#_.assertFence($);let K=Z.executionPlan===void 0?void 0:await this.#_.stagingDirectory($,_.key,Z.executionPlan.nodePlanSha256),W;try{let V=this.#W.reconcile,N=this.#W.reconcileEffect;W=V===void 0&&N===void 0?void 0:await this.#w($,X,async()=>{let G=async()=>await this.#Y.withLease(i3(Y.discovery.policy.resources,this.#Y),async(D)=>{await D.assertOwned();let L=async()=>{if(await D.assertOwned(),X.assertActive(),X.signal.aborted)throw new j("cancelled","Workflow reconciliation was cancelled before publication.");await this.#_.assertFence($),await this.#N($,X),await this.#_.assertFence($),X.assertActive(),await D.assertOwned()},O={abortSignal:X.signal,application:uq(this.#$,D),beforePublication:L,dependencyOutputs:J.dependencyOutputs,executionPlan:Z.executionPlan,graphPlan:Q,node:_,operation:Y.discovery,preparationPlan:Z.preparationPlan,previous:Z,resolvedInput:J.input,resumeClass:H,runId:$.runId,...K===void 0?{}:{workspaceDirectory:K}};return N===void 0?await V.call(this.#W,O):await X.runNative(N.call(this.#W,O))},{signal:X.signal,waitTimeoutMilliseconds:TQ});return N===void 0?await G():await X.custody(T1("authority",G))})}catch{return await this.#_.assertFence($),{deferred:!0,reconciliation:void 0}}return await this.#_.assertFence($),await this.#P($,Z,Y,H,W),{deferred:!1,reconciliation:W}}async#P($,Q,_,Z,F){if(F?.kind==="completed"){let H=qd(F.output,F.summary,_.discovery.policy.maxOutputBytes,F.receiptReference);await this.#G($,{...Q,failure:void 0,finishedAt:this.#J().toISOString(),output:H,status:"completed"});return}let X=Z==="verified-receipt"||Z==="recoverable-transaction";if(F?.kind==="retry"&&X){await this.#G($,{...Q,failure:void 0,finishedAt:void 0,status:"ready"});return}if(F?.kind==="incompatible"){await this.#G($,{...Q,failure:t8(new j("incompatible",F.message)),finishedAt:this.#J().toISOString(),status:"incompatible"});return}let Y=F?.kind==="ambiguous"?F.message:Z==="non-resumable-live"?"Interrupted live operation requires explicit operator reconciliation.":Z==="ambiguous-after-dispatch"?"Interrupted paid operation has an ambiguous dispatch outcome.":"Interrupted operation has no compatible reconciliation implementation.",J=Z==="verified-receipt"||Z==="recoverable-transaction"?"incompatible":"ambiguous";await this.#G($,{...Q,failure:t8(new j(J==="incompatible"?"incompatible":"ambiguous",Y)),finishedAt:this.#J().toISOString(),status:J})}async#T($,Q,_){let Z=!0;while(Z){Z=!1;let F=await this.#_.nodes($.runId),X=new Map(F.map((Y)=>[Y.nodeKey,Y]));for(let Y of[...Q.graph.nodes].sort((J,H)=>J.key.localeCompare(H.key))){let J=X.get(Y.key);if(J===void 0||J.status!=="pending")continue;let H=Y.dependencies.map((K)=>X.get(K));if(H.some((K)=>K===void 0))throw new j("invalid-data",`Node ${Y.key} has a missing dependency.`);if(H.some((K)=>K!==void 0&&_81(K))){let K={...J,finishedAt:this.#J().toISOString(),status:_.cancelled?"cancelled":"skipped"};await this.#G($,K),X.set(Y.key,K),Z=!0;continue}if(H.every((K)=>K?.status==="completed")){let K={...J,status:"ready"};await this.#G($,K),X.set(Y.key,K),Z=!0}}}}async#R($,Q,_,Z,F){let X=await this.#_.nodes($.runId),Y=new Map(X.map((H)=>[H.nodeKey,H])),J=new Map(Q.graph.nodes.map((H)=>[H.key,H]));for(let H of X.filter((K)=>K.status==="ready"||K.status==="approval-required").sort((K,W)=>K.nodeKey.localeCompare(W.nodeKey))){if(_.pause!==void 0||_.cancelled)break;if(F.has(H.nodeKey))continue;await this.#N($,Z);let K=J.get(H.nodeKey);if(K===void 0)throw new j("invalid-data",`Run contains unknown node ${H.nodeKey}.`);let W=UK0(Q,K,this.#j),V=BK0(K,Y),N;if(W.kind==="operation"){if(!A4(K))throw new j("internal",`Node executor classification changed for ${K.key}.`);N={dependencyOutputs:V.dependencyOutputs,graphPlan:Q,node:K,operation:W.operation.discovery,resolvedInput:V.input,runId:$.runId}}let G=H.preparationPlan;if(G===void 0){await this.#G($,{...H,status:"preparing"}),await this.#_.assertFence($);let B=N===void 0?n$1(V):await this.#w($,Z,async()=>await this.#W.prepare(N));G=r$1(Q,K,W.policy,B)}else i$1(G,Q,K,W.policy);if(!await this.#z($,Q,K,W,G,Z)){let B=F6.parse({...H,preparationPlan:G,status:"approval-required",version:$J});await this.#G($,B),_.pause={nodeKey:K.key,phase:"preparation",planSha256:G.preparationPlanSha256},await this.#_.appendEvent($,{details:{phase:"preparation",planSha256:G.preparationPlanSha256},kind:"approval-required",nodeKey:K.key,timestamp:this.#J().toISOString()});break}let L=H.executionPlan;if(L===void 0){await this.#_.assertFence($);let B=N===void 0?{exactInput:V.input,publicationKeys:[]}:await this.#w($,Z,async()=>{if(N.operation.kind!=="slopcamera.studio.run")return await this.#W.plan({...N,preparationPlan:G});return await this.#Y.withLease(i3(N.operation.policy.resources,this.#Y),async(C)=>{let U=async()=>{await C.assertOwned(),await this.#_.assertFence($),await this.#N($,Z),await this.#_.assertFence($),await C.assertOwned()};return await U(),await this.#W.plan({...N,preparationPlan:G,application:uq(this.#$,C),abortSignal:Z.signal,beforePublication:U})},{signal:Z.signal})});L=o$1(Q,K,W.policy,G,V,B)}else a$1(L,Q,K,W.policy,G,V);if(!await this.#E($,Q,K,W,L,Z)){let B=F6.parse({...H,executionPlan:L,preparationPlan:G,status:"approval-required",version:$J});await this.#G($,B),_.pause={nodeKey:K.key,phase:"effect",planSha256:L.nodePlanSha256},await this.#_.appendEvent($,{details:{phase:"effect",planSha256:L.nodePlanSha256},kind:"approval-required",nodeKey:K.key,timestamp:this.#J().toISOString()});break}let w=F6.parse({...H,executionPlan:L,failure:void 0,preparationPlan:G,status:"ready",version:$J});if(H.status!=="ready"||H.preparationPlan===void 0||H.executionPlan===void 0||H.failure!==void 0)await this.#G($,w);Y.set(K.key,w),F.set(K.key,{executionPlan:L,executor:W,record:w,resolved:V})}}async#z($,Q,_,Z,F,X){if(F.requestedPreparation.length===0)return!0;let Y=await this.#_.grants($.runId);if(t$1(Y,Q.graphPlanSha256,F.nodeKey,F.preparationPlanSha256))return!0;if(!zK0(await this.#w($,X,async()=>await this.#Q.authorizePreparation({executor:_.executor,graphPlanSha256:Q.graphPlanSha256,nodeKey:F.nodeKey,...Z.kind==="operation"?{operation:Z.operation.discovery}:{},policy:Z.policy,preparationPlan:F,runId:$.runId}))))return!1;let H={createdAt:this.#J().toISOString(),graphPlanSha256:Q.graphPlanSha256,grantedBy:this.#Q.grantedBy,grantId:kd(),kind:"preparation",nodeKey:F.nodeKey,preparationPlanSha256:F.preparationPlanSha256};return await this.#N($,X),await this.#_.appendGrant($,H),!0}async#E($,Q,_,Z,F,X){if(Z.kind==="operation"&&Z.operation.discovery.kind==="slopcamera.studio.run"){let K=this.#$.studioAuthorization;if(K===void 0||!await this.#w($,X,async()=>await K.authorize(Mm(F.exactInput))))return!1}let Y=await this.#_.grants($.runId);if(e$1(Y,Q.graphPlanSha256,F.nodeKey,F.nodePlanSha256))return!0;if(!zK0(await this.#w($,X,async()=>await this.#Q.authorizeEffect({executor:_.executor,executionPlan:F,graphPlanSha256:Q.graphPlanSha256,nodeKey:F.nodeKey,...Z.kind==="operation"?{operation:Z.operation.discovery}:{},policy:Z.policy,runId:$.runId}))))return!1;let H={createdAt:this.#J().toISOString(),graphPlanSha256:Q.graphPlanSha256,grantedBy:this.#Q.grantedBy,grantId:kd(),kind:"effect",nodeKey:F.nodeKey,nodePlanSha256:F.nodePlanSha256};return await this.#N($,X),await this.#_.appendGrant($,H),!0}async#B($,Q,_,Z,F,X,Y,J){for(let H of[...Q.values()].sort((K,W)=>K.record.nodeKey.localeCompare(W.record.nodeKey))){if(JJ.now()>=F){X.interrupt("deadline",new j("cancelled","Workflow exceeded the host wall-clock bound."));break}let K=H.executor.policy.resources;if(Z.impossible(K)){await this.#G($,{...H.record,failure:t8(new j("incompatible",`Node ${H.record.nodeKey} exceeds the host resource ceiling.`)),finishedAt:this.#J().toISOString(),status:"incompatible"}),Q.delete(H.record.nodeKey);continue}if(!Z.acquire(K,H.executionPlan.publicationKeys))continue;try{if(await this.#_.assertFence($),await this.#K($.runId)!==void 0){Z.release(K,H.executionPlan.publicationKeys),X.interrupt("cancellation",new j("cancelled","Workflow cancellation requested."));break}let W=new AbortController,V=new AbortController,N=F6.parse({...H.record,attempt:H.record.attempt+1,startedAt:this.#J().toISOString(),status:"running",version:$J});await this.#G($,N),Q.delete(H.record.nodeKey);let G={admissionAbortController:W,abortController:V,cancellable:H.executor.policy.cancellable,executionPlan:H.executionPlan,nodeKey:H.record.nodeKey,fiber:Y.fork(d1.exit(this.#f($,H,W,V,F,Y)).pipe(d1.tap((D)=>Rd.offer(J,{nodeKey:H.record.nodeKey,outcome:D})))),publicationKeys:H.executionPlan.publicationKeys,resources:K};_.set(H.record.nodeKey,G)}catch(W){throw Z.release(K,H.executionPlan.publicationKeys),W}}}#f($,Q,_,Z,F,X){return d1.gen(this,function*(){let Y=!1,J,H=!1,K=!1,W=wK0(JJ.now(),Q.executor.policy.maxDurationMs),V=Math.min(W,F),N=F<=W?"workflow":"node",G=X.deferred(),D=()=>new j("unavailable",N==="workflow"?"Workflow exceeded the host wall-clock bound.":"Operation exceeded its registered duration bound."),L=X.watch(d1.zipRight(Id(V),d1.sync(()=>{if(Y=!0,J=N,dq.unsafeDone(G,d1.fail(_Z(D(),"admission"))),_.abort(),Q.executor.policy.cancellable)Z.abort()})),!0),O=async(U)=>{if(Y)throw D();return await X.run(d1.raceFirst(T1("authority",U),dq.await(G)))},w=()=>{if(Y)throw new j("cancelled","Workflow node deadline expired before publication.")},B=yield*d1.exit(d1.catchAll(d1.gen(this,function*(){if(yield*T1("operation",()=>O(async()=>await this.#_.assertFence($))),(yield*T1("operation",()=>O(async()=>await this.#K($.runId))))!==void 0)return yield*d1.fail(_Z(new j("cancelled","Workflow cancellation requested."),"operation"));if(Q.executor.policy.effect==="paid-cloud"||Q.executionPlan.publicationKeys.length>0){if(yield*T1("operation",()=>O(async()=>await this.#_.assertFence($))),(yield*T1("operation",()=>O(async()=>await this.#K($.runId))))!==void 0)return yield*d1.fail(_Z(new j("cancelled","Workflow cancellation requested before dispatch or publication."),"operation"))}let U=this.#$,z=async(E,A=U)=>{if(Q.executor.kind!=="operation")throw new j("internal",`Compute node ${Q.record.nodeKey} entered operation execution.`);if(await O(async()=>await this.#_.assertFence($)),await O(async()=>await this.#_.cancellation($.runId))!==void 0)throw new j("cancelled","Workflow cancellation requested before project publication.");let k=await O(async()=>await this.#_.stagingDirectory($,Q.record.nodeKey,Q.executionPlan.nodePlanSha256));await E.assertOwned();let P=uq(A,E),I=Q.executor.operation,x={abortSignal:Z.signal,application:P,...Q.executionPlan.expectedProjectGeneration===void 0?{}:{expectedProjectGeneration:Q.executionPlan.expectedProjectGeneration},runFence:{generation:$.generation,owner:$.owner,token:$.token},workflow:{beforePublication:async()=>{if(w(),await E.assertOwned(),await O(async()=>await this.#_.assertFence($)),w(),await O(async()=>await this.#K($.runId))!==void 0)throw new j("cancelled","Workflow cancellation requested before publication.");w(),H=!0},nodeKey:Q.record.nodeKey,nodePlanSha256:Q.executionPlan.nodePlanSha256,runId:$.runId,workspaceDirectory:k}},b=I.executeEffect===void 0?await I.execute(x,Q.executionPlan.exactInput):Uj(await X.run(d1.exit(I.executeEffect(x,Q.executionPlan.exactInput))));if(I.discovery.kind.startsWith("spatial.project.")&&I.discovery.kind!=="spatial.project.snapshot"){let y=b.output;if(y.kind!=="completed")throw new j(y.kind==="ambiguous"?"ambiguous":"conflict",y.message??"Spatial publication did not complete.",{spatialPublication:b.output})}return b},M=i3(Q.executor.policy.resources,this.#Y),T={signal:_.signal,waitTimeoutMilliseconds:Math.min(TQ,Math.max(1,Math.floor(V-JJ.now())))},q;if(Q.executor.kind==="compute"){let E=Q.executor.compute,A=this.#X,k=this.#Z?.kind!=="replay"||this.#A.has(Q.record.nodeKey);if(A===void 0||!k)return{failure:t8(new j("ambiguous","Trusted compute requires explicit authorization to reload its exact persisted bundle.")),kind:"ambiguous-code"};let P=X.custody(T1("admission",()=>this.#Y.withLease(M,async(x)=>{return await x.assertOwned(),K=!0,await A.execute({abortSignal:Z.signal,computeKey:E.key,...x.inheritedFileDescriptor<3?{}:{inheritedHostResourceFileDescriptor:x.inheritedFileDescriptor},input:Q.executionPlan.exactInput,nodeKey:Q.record.nodeKey,replayAcknowledged:this.#Z?.kind==="replay",timeoutMs:Math.max(1,Math.floor(V-JJ.now()))})},T))),I=yield*T1("operation",()=>O(async()=>await P));yield*T1("operation",()=>O(async()=>await this.#_.assertFence($))),q=yield*FN("operation",()=>qd(I,{computeKey:E.key,trustedCode:!0},Q.executor.policy.maxOutputBytes))}else{let E=Q.executor.operation,A=Q.executionPlan.publicationKeys.some((I)=>I.startsWith("project:")),k=X.custody(T1("admission",()=>this.#Y.withLease(M,async(I)=>E.discovery.kind.startsWith("spatial.project.")?await f7(uq(this.#$,I),String(Q.executionPlan.exactInput.project),async(x)=>await z(I,x),async()=>{if(w(),await I.assertOwned(),Z.signal.aborted)throw new j("cancelled","Spatial project custody was cancelled before publication.");if(await O(async()=>await this.#_.assertFence($)),await O(async()=>await this.#K($.runId))!==void 0)throw new j("cancelled","Workflow cancellation requested before spatial publication.");if(w(),Z.signal.aborted)throw new j("cancelled","Spatial project custody was cancelled before publication.");await I.assertOwned()},E.discovery.kind==="spatial.project.migrate"?"mutation":"read"):A?await gW(this.#$,E.discovery.kind,Q.executionPlan.exactInput,async()=>await z(I)):await z(I),T))),P=yield*T1("operation",()=>O(async()=>await k));yield*T1("operation",()=>O(async()=>await this.#_.assertFence($))),q=yield*FN("operation",()=>qd(P.output,P.summary.fields,Q.executor.policy.maxOutputBytes,P.receiptReference))}return{kind:"completed",output:q}}),(U)=>FN("operation",()=>{let z=U.cause,M=F81(z);if(Q.executor.kind==="compute"){if(M.code==="cancelled"&&!K)return{failure:t8(new j("cancelled","Workflow node was cancelled.")),kind:"cancelled"};if(M.code==="invalid-data"||M.code==="unsupported-plan"||M.code==="incompatible")return{failure:t8(M),kind:"failed"};return{failure:t8(new j("ambiguous",Y?J==="workflow"?"Trusted compute exceeded the workflow wall-clock bound and requires explicit replay.":"Trusted compute exceeded its duration bound and requires explicit replay.":`Trusted compute was interrupted and requires explicit replay: ${M.message}`)),kind:"ambiguous-code"}}let T=M.details?.spatialPublication;if(Q.executor.operation.discovery.kind.startsWith("spatial.project.")&&T!==void 0){let E=G8.safeParse(T);if(E.success&&E.data.kind!=="completed")return{failure:t8(M),kind:E.data.kind==="ambiguous"?"ambiguous":"failed"}}if(H&&(Q.executor.policy.resume==="verified-receipt"||Q.executor.policy.resume==="recoverable-transaction"))return{failure:t8(new j("ambiguous",Y?J==="workflow"?"Recoverable publication exceeded the workflow wall-clock bound.":"Recoverable publication exceeded its duration bound.":`Recoverable publication requires reconciliation: ${M.message}`,M.details)),kind:"interrupted"};if(M.code==="cancelled"||Z.signal.aborted&&!Y)return{failure:t8(new j("cancelled","Workflow node was cancelled.")),kind:"cancelled"};if(Q.executor.policy.resume==="ambiguous-after-dispatch"||Q.executor.policy.resume==="non-resumable-live")return{failure:t8(new j("ambiguous",Y?J==="workflow"?"Operation exceeded the workflow wall-clock bound after dispatch.":"Operation exceeded its duration bound after dispatch.":M.message,M.details)),kind:"ambiguous"};return{failure:t8(Y?new j("unavailable",J==="workflow"?"Operation exceeded the workflow wall-clock bound.":"Operation exceeded its registered duration bound."):M,M.code==="unavailable"||M.code==="subprocess"),kind:"failed"}}))),C=yield*d1.exit(d1.gen(this,function*(){yield*T1("operation",()=>L())}));return yield*LK0.zipLeft(B,C)})}async#S($,Q,_,Z,F){await this.#_.assertFence($);let X=await this.#_.node($.runId,_.nodeKey);if(Z.kind==="completed")return await this.#G($,{...X,failure:void 0,finishedAt:this.#J().toISOString(),output:Z.output,status:"completed"}),!1;if(Z.kind==="interrupted"){let Y=Q.graph.nodes.find((W)=>W.key===_.nodeKey);if(Y===void 0||!A4(Y))throw new j("invalid-data",`Missing recoverable operation node ${_.nodeKey}.`);let J=await this.#_.nodes($.runId),H=new Map(J.map((W)=>[W.nodeKey,W]));return(await this.#U($,Q,Y,X,H,F)).deferred}if(await this.#G($,{...X,failure:Z.failure,finishedAt:this.#J().toISOString(),status:Z.kind}),Z.kind==="ambiguous"){if(Q.graph.nodes.find((J)=>J.key===_.nodeKey)===void 0)throw new j("invalid-data",`Missing graph node ${_.nodeKey}.`)}return!1}async#I($,Q){let _=await this.#_.nodes($.runId),Z=new Set(Q.graph.nodes.map((F)=>F.key));for(let F of _.filter((X)=>X.status==="pending"||X.status==="ready"||X.status==="preparing"||X.status==="approval-required"||X.status==="ambiguous-code").sort((X,Y)=>X.nodeKey.localeCompare(Y.nodeKey))){if(!Z.has(F.nodeKey))continue;await this.#G($,{...F,finishedAt:this.#J().toISOString(),status:"cancelled"})}}async#b($,Q,_){let Z=await this.#_.nodes($.runId),F=new Map(Q.graph.nodes.map((Y)=>[Y.key,Y])),X=!1;for(let Y of Z.filter((J)=>J.status==="ready").sort((J,H)=>J.nodeKey.localeCompare(H.nodeKey))){let J=F.get(Y.nodeKey);if(J===void 0)continue;let H=UK0(Q,J,this.#j);if(!_.impossible(H.policy.resources))continue;await this.#G($,{...Y,failure:t8(new j("incompatible",`Node ${J.key} exceeds the host resource ceiling.`)),finishedAt:this.#J().toISOString(),status:"incompatible"}),X=!0}return X}async#G($,Q){let _=F6.parse(Q),Z=F6.parse({attempt:_.attempt,dependencies:_.dependencies,..._.executionPlan===void 0?{}:{executionPlan:_.executionPlan},..._.failure===void 0?{}:{failure:_.failure},..._.finishedAt===void 0?{}:{finishedAt:_.finishedAt},executor:_.executor,nodeKey:_.nodeKey,..._.output===void 0?{}:{output:_.output},..._.preparationPlan===void 0?{}:{preparationPlan:_.preparationPlan},..._.startedAt===void 0?{}:{startedAt:_.startedAt},status:_.status,version:_.version});await this.#_.assertFence($),await this.#_.writeNode($,Z),await this.#_.appendEvent($,{details:{status:Z.status},kind:"node-status",nodeKey:Z.nodeKey,timestamp:this.#J().toISOString()})}async#k($,Q,_,Z){let F=await this.#_.summary($.runId);if(lq(F.status))return F;let X=await this.#_.nodes($.runId),Y=new Map(X.map((V)=>[V.nodeKey,V])),J=MK0(X,_,Z),H=this.#J().toISOString(),K=J==="completed"?Pd(Q.graph.outputs,Y):void 0,W=mF.parse({counts:qK0(X),...lq(J)?{finishedAt:H}:{},graphPlanSha256:Q.graphPlanSha256,...K===void 0?{}:{outputs:K},runId:$.runId,startedAt:_.startedAt,status:J,updatedAt:H,version:_6});return await this.#_.writeSummary($,W),W}async#y($,Q,_,Z){let X=(await this.#_.nodes($.runId)).filter((Y)=>Y.status==="ready"||Y.status==="preparing"||Y.status==="running").sort((Y,J)=>Y.nodeKey.localeCompare(J.nodeKey))[0];if(X!==void 0){let Y=Q.graph.nodes.find((K)=>K.key===X.nodeKey),J=Y!==void 0&&A4(Y)?gw(Q,Y,this.#j).discovery.policy.resume:void 0;if(X.status==="running"&&(J==="verified-receipt"||J==="recoverable-transaction")){await this.#k($,Q,_,0);return}await this.#G($,{...X,failure:t8(Z),finishedAt:this.#J().toISOString(),status:Z.code==="incompatible"?"incompatible":"failed"})}await this.#k($,Q,_,0)}async#x($,Q,_,Z){let F=await this.#_.nodes($.runId);for(let X of[...F].sort((Y,J)=>Y.nodeKey.localeCompare(J.nodeKey))){if(X.status==="approval-required")await this.#G($,{...X,status:"ready"});let Y=X.status==="approval-required"?await this.#_.node($.runId,X.nodeKey):X;if(Y.status!=="ready"&&Y.status!=="preparing"&&Y.status!=="running"&&Y.status!=="ambiguous-code")continue;await this.#G($,{...Y,failure:t8(new j("incompatible",Z.message)),finishedAt:this.#J().toISOString(),status:"incompatible"})}await this.#T($,Q,_)}}var Y81="workflow-runs",J81=100;async function EK0($,Q,_={}){try{return await $.withLease(gG($),async(Z)=>{return await Z.assertOwned(),await Q(Z)},{..._.signal===void 0?{}:{signal:_.signal},waitTimeoutMilliseconds:_.waitTimeoutMilliseconds??TQ})}catch(Z){if(!(Z instanceof P2))throw Z;switch(Z.code){case"WAIT_ABORTED":throw new j("cancelled",Z.message);case"OWNERSHIP_LOST":throw new j("conflict",Z.message);case"INVALID_CLAIMS":case"INVALID_PROFILE":case"PROFILE_MISMATCH":case"UNSAFE_STATE":case"UNSUPPORTED_PLATFORM":case"WAIT_TIMEOUT":throw new j("unavailable",Z.message,{hostResourceCode:Z.code})}}}async function H81($){let[Q,_]=await Promise.all([$.store.graphPlan($.runId),$.store.bundle($.runId)]);if(Q.runtime.externals.kind==="deny-all"&&Q.runtime.externals.modules.length!==0)throw new j("incompatible","A deny-all trusted-code runtime cannot contain external modules.");let Z=rH0({bundle:Q.bundle,bytes:_,externalModules:Q.runtime.externals.modules}),F=await zw({applicationBuild:$.currentApplicationBuild,bundle:Z});if(R(F)!==R(Q.runtime))throw new j("incompatible","The trusted-code runtime changed since this run was planned.",{current:F,planned:Q.runtime});let X=tY({bundle:Q.bundle,graph:Q.graph,limits:Q.limits,registry:$.registry,runtime:F,staticBindings:Q.staticBindings,workflowInput:Q.workflowInput});if(R(X)!==R(Q))throw new j("incompatible","Persisted trusted code no longer compiles to the exact authorized graph plan.");return await Dq({bundle:Z,expectedBuild:{graph:Q.graph,input:Q.workflowInput},...$.inheritedHostResourceFileDescriptor===void 0?{}:{inheritedHostResourceFileDescriptor:$.inheritedHostResourceFileDescriptor},maximumWorkers:$.maximumWorkers,registry:$.registry,temporaryRoot:$.application.paths.privateRoot,workflowInput:Q.workflowInput,workflowInputMode:"parsed"})}function PK0(){return`slopcamera-cli:${String(process.pid)}:${yd()}`}function K81(){return`run_${yd().replaceAll("-","")}`}function W81($){let Q=new Map;for(let _ of $.graph.nodes){if(!A4(_))continue;let Z=_.executor.operation;Q.set(`${Z.kind}@${String(Z.version)}`,Z)}return[...Q.entries()].sort(([_],[Z])=>_.localeCompare(Z)).map(([,_])=>_)}function V81($){let Q=new Map;for(let _ of $.graph.nodes)if(_8(_))Q.set(_.executor.compute.key,_.executor.compute);return[...Q.entries()].sort(([_],[Z])=>_.localeCompare(Z)).map(([,_])=>_)}function HJ($){return new Td({root:X81($.paths.privateRoot,Y81)})}async function xd($){let Q=HJ($.application),_=K81(),Z=await Q.create({bundleBytes:new Uint8Array($.bundleBytes),graphPlan:$.graphPlan,runId:_,runtime:{computes:V81($.graphPlan),operations:W81($.graphPlan),runtime:$.graphPlan.runtime,version:_6},sourceLocator:$.sourceLocator,workflow:{bundle:$.graphPlan.bundle,sourceLocator:$.sourceLocator,workflow:$.graphPlan.graph.workflow}});return{runId:_,store:Q,summary:Z}}function G81($){let Q=new Set(["local-media","project-state"]);return $.preparation.every((_)=>Q.has(_))}function N81($){return $.effect!=="paid-cloud"&&$.effect!=="live-control"}function j81(){return{authorizeEffect:($)=>Promise.resolve(N81($.policy)),authorizePreparation:($)=>Promise.resolve(G81($.policy)),grantedBy:"slopcamera-local-cli"}}async function D81($,Q,_,Z){let F;try{F=await $.events(Q)}catch(Y){if(Y instanceof j&&Y.code==="conflict")return _;throw Y}let X=_;for(let Y of F){if(Y.sequence<=_)continue;Z(Y),X=Math.max(X,Y.sequence)}return X}async function cq($){let Q=$.store??HJ($.application),_=$.hostResourceCoordinator??c3(),Z=await EK0(_,async(W)=>await Uw($.application,W.inheritedFileDescriptor<3?{}:{inheritedFileDescriptors:[W.inheritedFileDescriptor]})),F=$.replayAmbiguousCode??[];if($.compute!==void 0&&F.length>0)throw new j("usage","A workflow run cannot use a fresh code worker and persisted compute replay together.");let X=!1,Y=F.length===0?$.compute:{kind:"replay",load:async({signal:W,waitTimeoutMilliseconds:V})=>{if(X)throw new j("conflict","The persisted trusted-code worker pool was already loaded.");X=!0;let N=await EK0(_,async(G)=>await H81({application:$.application,currentApplicationBuild:Z,inheritedHostResourceFileDescriptor:G.inheritedFileDescriptor,maximumWorkers:CY0($.jobs,F,_),registry:$.registry,runId:$.runId,store:Q}),{signal:W,waitTimeoutMilliseconds:V});return{executor:N,release:async()=>await N.close()}},nodeKeys:F},J=new fd({application:$.application,authorization:j81(),currentApplicationBuild:Z,...Y===void 0?{}:{compute:Y},hostLimits:{maxJobs:$.jobs},hostResourceCoordinator:_,jobs:$.jobs,nodePlanner:p70($.application),owner:PK0(),registry:$.registry,store:Q});if($.onEvent===void 0)return await J.run($.runId);let H=J.run($.runId).then((W)=>({kind:"result",result:W}),(W)=>({error:W,kind:"error"})),K=0;while(!0){let W=await Promise.race([H,new Promise((V)=>{setTimeout(V,J81)})]);if(K=await D81(Q,$.runId,K,$.onEvent),W===void 0)continue;if(W.kind==="error")throw W.error;return W.result}}async function IK0($){let Q=HJ($.application),_=PK0(),Z=await Q.acquireClaim($.runId,{owner:_});try{let[F,X]=await Promise.all([Q.graphPlan($.runId),Q.node($.runId,$.nodeKey)]);if(X.status!=="approval-required")throw new j("conflict",`Node ${$.nodeKey} is not awaiting approval.`);let Y={createdAt:new Date().toISOString(),graphPlanSha256:F.graphPlanSha256,grantedBy:"slopcamera-local-cli",grantId:yd(),nodeKey:$.nodeKey},J;if($.planKind==="preparation"){let H=X.preparationPlan?.preparationPlanSha256;if(H!==$.planHash)throw new j("conflict","The preparation approval hash does not match the pending node plan.",{actual:H,requested:$.planHash});J={...Y,kind:"preparation",preparationPlanSha256:$.planHash}}else{let H=X.executionPlan?.nodePlanSha256;if(H!==$.planHash)throw new j("conflict","The effect approval hash does not match the pending node plan.",{actual:H,requested:$.planHash});J={...Y,kind:"effect",nodePlanSha256:$.planHash}}return await Q.appendGrant(Z,J)}finally{await Q.releaseClaim(Z).catch(()=>{return})}}async function bK0($){return await HJ($.application).requestCancellation($.runId,"slopcamera-local-cli")}async function SK0($,Q){return(await HJ($).list()).slice(0,Q)}async function fK0($){let Q=HJ($.application),[_,Z,F,X]=await Promise.all([Q.summary($.runId),Q.workflow($.runId),Q.nodes($.runId),Q.outputs($.runId)]),Y=$.nodes==="all"?F:F.filter((J)=>["ambiguous","ambiguous-code","approval-required","failed","incompatible"].includes(J.status));return{graphPlanSha256:_.graphPlanSha256,nodes:Y,outputs:X?.outputs??null,summary:_,workflow:Z.workflow}}function pq($){let Q=$.summary,_=[`${Q.runId} ${Q.status} ${Q.graphPlanSha256}`,`nodes completed=${String(Q.counts.completed)} failed=${String(Q.counts.failed)} skipped=${String(Q.counts.skipped)} pending=${String(Q.counts.pending)} cancelled=${String(Q.counts.cancelled)}`];if($.pause!==void 0){let Z=$.pause.phase==="effect"?"--node-plan":"--preparation-plan";_.push(`next slopcamera runs approve ${Q.runId} ${$.pause.nodeKey} ${Z} ${$.pause.planSha256}`,`then slopcamera runs resume ${Q.runId}`)}else if(Q.status!=="completed"&&Q.status!=="cancelled")_.push(`next slopcamera runs show ${Q.runId} --nodes failed`);return _.join(` -`)}var mw="3.5.0",B81=34359738368,nK0=34359738368;function C81($,Q){return hd($,{assertOwned:async()=>await Q.assertOwned(),claims:Q.claims,inheritedFileDescriptor:Q.inheritedFileDescriptor,inheritedFileDescriptors:[Q.inheritedFileDescriptor],profile:Q.profile,ticket:Q.ticket})}function hd($,Q){let _=$.hostResourceLease,Z=_?.inheritedFileDescriptors??[],F=Q.inheritedFileDescriptors.every((K)=>Z.includes(K)),X=Z.every((K)=>Q.inheritedFileDescriptors.includes(K));if(_!==void 0&&(_.profile.id!==Q.profile.id||_.profile.capacities.length!==Q.profile.capacities.length||_.profile.capacities.some((K)=>{return Q.profile.capacities.find((V)=>V.resource===K.resource)?.limit!==K.limit})))throw new j("unavailable","Nested host-resource phases must use the same machine profile.");let Y=[...Z,...Q.inheritedFileDescriptors].filter((K,W,V)=>V.indexOf(K)===W);if(Y.length>16)throw new j("unavailable","A direct Slopcamera subprocess cannot inherit more than 16 file descriptors.");let J=_===void 0||X?Q:F?_:{assertOwned:async()=>{await _.assertOwned(),await Q.assertOwned()},claims:BY0(_.claims,Q.claims),inheritedFileDescriptor:Q.inheritedFileDescriptor,inheritedFileDescriptors:Y,profile:Q.profile,ticket:Q.ticket},H=(K=[])=>[...K,...J.inheritedFileDescriptors].filter((W,V,N)=>N.indexOf(W)===V);return{...$,capabilities:async(K)=>await $.capabilities(H(K)),capability:async(K,W,V)=>await $.capability(K,W,H(V)),hostResourceLease:J,runner:{run:async(K,W={})=>{await J.assertOwned();let V=H(W.inheritedFileDescriptors);if(V.length>16)throw new j("unavailable","A direct Slopcamera subprocess cannot inherit more than 16 file descriptors.");return await $.runner.run(K,{...W,inheritedFileDescriptors:V})}}}}function U81($){switch($.code){case"WAIT_ABORTED":return new j("cancelled",$.message);case"OWNERSHIP_LOST":return new j("conflict",$.message);case"INVALID_CLAIMS":case"INVALID_PROFILE":case"PROFILE_MISMATCH":case"UNSAFE_STATE":case"UNSUPPORTED_PLATFORM":case"WAIT_TIMEOUT":return new j("unavailable",$.message,{hostResourceCode:$.code})}}async function z81($,Q,_){let Z=UY0(Q,$.hostResourceCoordinator);await GJ($,Z,_,$.abortSignal)}async function GJ($,Q,_,Z){if(Q.length===0)return await _($);try{return await $.hostResourceCoordinator.withLease(Q,async(F)=>{return await F.assertOwned(),await _(C81($,F))},{...Z===void 0?{}:{signal:Z},waitTimeoutMilliseconds:TQ})}catch(F){if(F instanceof P2)throw U81(F);throw F}}async function vd($,Q,_){let Z=i3([{amount:1,resource:"cpu"},{amount:1,resource:"ffmpeg"},{amount:1,resource:"local-io"}],$.hostResourceCoordinator);if($.hostResourceLease!==void 0){if(await $.hostResourceLease.assertOwned(),pu($.hostResourceLease.claims,Z))return await _(X4($))}return await GJ($,Bk($.hostResourceLease?.claims??[],Z),async(F)=>await _(X4(F)),Q)}function X4($,Q){let _=(F)=>({available:F.available,...F.command===void 0?{}:{command:F.command},name:F.name,...F.reason===void 0?{}:{reason:F.reason},...F.version===void 0?{}:{version:F.version}}),Z={capabilities:async(F)=>(await $.capabilities(F)).map(_),capability:async(F)=>_(await $.capability(F)),clock:{now:()=>new Date($.clock()),timestampMilliseconds:$.clock},htmlOverlayRenderer:new Iu({cacheRoot:V5($.paths.privateRoot,"html-overlay-modules-v1"),fetch:$.fetch}),...$.hostResourceLease===void 0?{}:{hostResourceLease:$.hostResourceLease},machineStateRoot:$.stateRoot,paths:$.paths,runner:$.runner,spatialReviewProvider:$.spatialReviewProviderFactory({credential:()=>_U($.io.env),fetch:$.fetch,transport:$.gatewayCatalogTransport})};return{...Z,gatewayPort:GH0({application:Z,createService:async(F,X)=>await jW0(X===void 0?$:hd($,X),F),inspectMedia:async(F,X,Y)=>{let J=Y===void 0?$:hd($,Y);return(await GN(J,F.map((K)=>({data:K.data,mediaType:K.mediaType,path:K.path})),X)).map((K)=>{if(K.url!==void 0)throw new j("internal","Gateway workflow preparation unexpectedly produced a remote media input.");let W=K.facts;return{...W?.durationSeconds===void 0?{}:{durationSeconds:W.durationSeconds},...W?.height===void 0?{}:{height:W.height},...W?.width===void 0?{}:{width:W.width}}})},now:$.io.now,resolveProviderOptions:(F,X)=>{if(X.aborted)throw new j("cancelled","Gateway provider-options resolution was cancelled.");return Promise.resolve(Q)}})}}function h6($){if($<1000)return`${$}us`;if($<1e6)return`${($/1000).toFixed(1).replace(/\.0$/u,"")}ms`;return`${($/1e6).toFixed(3).replace(/0+$/u,"").replace(/\.$/u,"")}s`}function z8($,Q){let _=gY($,Q);if((!_.available||_.command===void 0)&&Q==="face-analyzer")throw new j("unavailable","Face analysis needs a small helper that isn't built on this Mac yet. In a Slopcamera checkout, run bun run build:desktop:analysis:macos; it uses Apple's command line tools and asks before installing them.",{capability:Q,..._.reason===void 0?{}:{reason:_.reason}});if(!_.available||_.command===void 0)throw new j("unavailable",`${Q} is unavailable${_.reason===void 0?".":`: ${_.reason}`}`,{capability:Q});return _.command}async function FK($,Q){return await Promise.all(Q.map(async(_)=>await $.capability(_)))}async function OJ($,Q){return z8([await $.capability(Q)],Q)}function u0($,Q,_,Z){if(Q)v9($,_);else K9($,Z())}function rK0($,Q,_){let Z=hX0(J5({toolVersion:_}),_);u0($,Q,Z,()=>Z.modules.map((F)=>`${F.moduleId}@${F.version} ${F.trust} operations=${F.operations.length} workflows=${F.workflows.length} tools=${F.tools.length} ${F.title}`).join(` +`)}var mw="3.6.0",B81=34359738368,nK0=34359738368;function C81($,Q){return hd($,{assertOwned:async()=>await Q.assertOwned(),claims:Q.claims,inheritedFileDescriptor:Q.inheritedFileDescriptor,inheritedFileDescriptors:[Q.inheritedFileDescriptor],profile:Q.profile,ticket:Q.ticket})}function hd($,Q){let _=$.hostResourceLease,Z=_?.inheritedFileDescriptors??[],F=Q.inheritedFileDescriptors.every((K)=>Z.includes(K)),X=Z.every((K)=>Q.inheritedFileDescriptors.includes(K));if(_!==void 0&&(_.profile.id!==Q.profile.id||_.profile.capacities.length!==Q.profile.capacities.length||_.profile.capacities.some((K)=>{return Q.profile.capacities.find((V)=>V.resource===K.resource)?.limit!==K.limit})))throw new j("unavailable","Nested host-resource phases must use the same machine profile.");let Y=[...Z,...Q.inheritedFileDescriptors].filter((K,W,V)=>V.indexOf(K)===W);if(Y.length>16)throw new j("unavailable","A direct Slopcamera subprocess cannot inherit more than 16 file descriptors.");let J=_===void 0||X?Q:F?_:{assertOwned:async()=>{await _.assertOwned(),await Q.assertOwned()},claims:BY0(_.claims,Q.claims),inheritedFileDescriptor:Q.inheritedFileDescriptor,inheritedFileDescriptors:Y,profile:Q.profile,ticket:Q.ticket},H=(K=[])=>[...K,...J.inheritedFileDescriptors].filter((W,V,N)=>N.indexOf(W)===V);return{...$,capabilities:async(K)=>await $.capabilities(H(K)),capability:async(K,W,V)=>await $.capability(K,W,H(V)),hostResourceLease:J,runner:{run:async(K,W={})=>{await J.assertOwned();let V=H(W.inheritedFileDescriptors);if(V.length>16)throw new j("unavailable","A direct Slopcamera subprocess cannot inherit more than 16 file descriptors.");return await $.runner.run(K,{...W,inheritedFileDescriptors:V})}}}}function U81($){switch($.code){case"WAIT_ABORTED":return new j("cancelled",$.message);case"OWNERSHIP_LOST":return new j("conflict",$.message);case"INVALID_CLAIMS":case"INVALID_PROFILE":case"PROFILE_MISMATCH":case"UNSAFE_STATE":case"UNSUPPORTED_PLATFORM":case"WAIT_TIMEOUT":return new j("unavailable",$.message,{hostResourceCode:$.code})}}async function z81($,Q,_){let Z=UY0(Q,$.hostResourceCoordinator);await GJ($,Z,_,$.abortSignal)}async function GJ($,Q,_,Z){if(Q.length===0)return await _($);try{return await $.hostResourceCoordinator.withLease(Q,async(F)=>{return await F.assertOwned(),await _(C81($,F))},{...Z===void 0?{}:{signal:Z},waitTimeoutMilliseconds:TQ})}catch(F){if(F instanceof P2)throw U81(F);throw F}}async function vd($,Q,_){let Z=i3([{amount:1,resource:"cpu"},{amount:1,resource:"ffmpeg"},{amount:1,resource:"local-io"}],$.hostResourceCoordinator);if($.hostResourceLease!==void 0){if(await $.hostResourceLease.assertOwned(),pu($.hostResourceLease.claims,Z))return await _(X4($))}return await GJ($,Bk($.hostResourceLease?.claims??[],Z),async(F)=>await _(X4(F)),Q)}function X4($,Q){let _=(F)=>({available:F.available,...F.command===void 0?{}:{command:F.command},name:F.name,...F.reason===void 0?{}:{reason:F.reason},...F.version===void 0?{}:{version:F.version}}),Z={capabilities:async(F)=>(await $.capabilities(F)).map(_),capability:async(F)=>_(await $.capability(F)),clock:{now:()=>new Date($.clock()),timestampMilliseconds:$.clock},htmlOverlayRenderer:new Iu({cacheRoot:V5($.paths.privateRoot,"html-overlay-modules-v1"),fetch:$.fetch}),...$.hostResourceLease===void 0?{}:{hostResourceLease:$.hostResourceLease},machineStateRoot:$.stateRoot,paths:$.paths,runner:$.runner,spatialReviewProvider:$.spatialReviewProviderFactory({credential:()=>_U($.io.env),fetch:$.fetch,transport:$.gatewayCatalogTransport})};return{...Z,gatewayPort:GH0({application:Z,createService:async(F,X)=>await jW0(X===void 0?$:hd($,X),F),inspectMedia:async(F,X,Y)=>{let J=Y===void 0?$:hd($,Y);return(await GN(J,F.map((K)=>({data:K.data,mediaType:K.mediaType,path:K.path})),X)).map((K)=>{if(K.url!==void 0)throw new j("internal","Gateway workflow preparation unexpectedly produced a remote media input.");let W=K.facts;return{...W?.durationSeconds===void 0?{}:{durationSeconds:W.durationSeconds},...W?.height===void 0?{}:{height:W.height},...W?.width===void 0?{}:{width:W.width}}})},now:$.io.now,resolveProviderOptions:(F,X)=>{if(X.aborted)throw new j("cancelled","Gateway provider-options resolution was cancelled.");return Promise.resolve(Q)}})}}function h6($){if($<1000)return`${$}us`;if($<1e6)return`${($/1000).toFixed(1).replace(/\.0$/u,"")}ms`;return`${($/1e6).toFixed(3).replace(/0+$/u,"").replace(/\.$/u,"")}s`}function z8($,Q){let _=gY($,Q);if((!_.available||_.command===void 0)&&Q==="face-analyzer")throw new j("unavailable","Face analysis needs a small helper that isn't built on this Mac yet. In a Slopcamera checkout, run bun run build:desktop:analysis:macos; it uses Apple's command line tools and asks before installing them.",{capability:Q,..._.reason===void 0?{}:{reason:_.reason}});if(!_.available||_.command===void 0)throw new j("unavailable",`${Q} is unavailable${_.reason===void 0?".":`: ${_.reason}`}`,{capability:Q});return _.command}async function FK($,Q){return await Promise.all(Q.map(async(_)=>await $.capability(_)))}async function OJ($,Q){return z8([await $.capability(Q)],Q)}function u0($,Q,_,Z){if(Q)v9($,_);else K9($,Z())}function rK0($,Q,_){let Z=hX0(J5({toolVersion:_}),_);u0($,Q,Z,()=>Z.modules.map((F)=>`${F.moduleId}@${F.version} ${F.trust} operations=${F.operations.length} workflows=${F.workflows.length} tools=${F.tools.length} ${F.title}`).join(` `))}function ZZ($,Q){let _=lF($,Q);return _===""||!_.startsWith("..")&&!tq(_)}async function gd($,Q){let _=await g$($.directory.path,Q);if(!GM($,_).startsWith("renders/"))throw new j("unsafe-path","Render outputs must remain under the bundle's renders/ directory so raw capture files stay immutable.");let F=await g$($.directory.path,"renders");await l1(F),await l1(PQ(_));let[X,Y]=await Promise.all([EQ(F),EQ(PQ(_))]);if(!ZZ(X,Y))throw new j("unsafe-path",`Render output crosses a symlink outside renders/: ${Q}`);try{if((await FZ(_)).isSymbolicLink())throw new j("unsafe-path",`Render output may not be a symlink: ${Q}`)}catch(J){if(J instanceof j)throw J;if(!(J instanceof Error&&("code"in J)&&J.code==="ENOENT"))throw J}return _}async function M81($,Q,_){let Z=await gd($,Q),F=GM($,Z),X=F.toLowerCase();if(DJ(F).toLowerCase()!==".json")throw new j("usage","A resolved render plan output must use a .json path under renders/.");if(X.endsWith(".mp4.plan.json"))throw new j("unsafe-path",`A render plan alias may not overwrite a video receipt: ${Q}`);if(/^renders\/resolved-[a-f0-9]{64}\.json$/u.test(X)&&F!==_)throw new j("unsafe-path",`A render plan alias may not use the canonical resolved-plan namespace: ${Q}`);return{absolute:Z,relative:F}}async function uw($,Q,_={}){let Z=await g$($,Q),F=lF($,Z);if(!F.startsWith("renders/")||tq(F))throw new j("unsafe-path","Project render artifacts must remain under the project's renders/ directory.");if(_.videoOutput){let H=F.split("/"),K=H.at(-1),W=new Set([".filter-graphs",".overlay-cache","derived","plans"]);if(H[0]!=="renders"||W.has(H[1]?.toLowerCase()??""))throw new j("unsafe-path",`Project video output may not use a reserved render-artifact subtree: ${Q}`);if(K===void 0||K.toLowerCase()===".mp4"||DJ(K).toLowerCase()!==".mp4")throw new j("usage","Project render output must be a final .mp4 file under renders/.")}let X=V5($,"renders");await l1(X),await l1(PQ(Z));let[Y,J]=await Promise.all([EQ(X),EQ(PQ(Z))]);if(!ZZ(Y,J))throw new j("unsafe-path",`Project render path crosses a symlink outside renders/: ${Q}`);try{let H=await FZ(Z);if(H.isSymbolicLink()||!H.isFile())throw new j("unsafe-path",`Project render leaf must be a physical regular file: ${Q}`)}catch(H){if(H instanceof j)throw H;if(!(H instanceof Error&&("code"in H)&&H.code==="ENOENT"))throw H}return{absolute:Z,relative:F}}async function eq($){return await tZ($)}function oK0($,Q,_){return{operation:Q,planHash:sZ(_),planId:_.planId,planPath:iX,recordingId:$.manifest.recordingId}}async function yK0($,Q,_,Z,F){let X=R2(_);await l1(V5($.directory.path,"edits")),await Nj($.fileSystem,X,iX);let Y=oK0($,Q,X);u0(F,Z,Y,()=>`${Q} ${_.planId} ${String(Y.planHash)}`)}function NJ($){if($!=="linear"&&$!=="ease-in"&&$!=="ease-out"&&$!=="ease-in-out"&&$!=="spring")throw new j("usage",`Unsupported easing: ${$}`);return{kind:$}}function xK0($,Q,_,Z,F,X){let Y=$??"none";if(Y==="none")return{kind:"none"};let J=E4(Q??_);if(Y==="fade")return{durationUs:J,easing:NJ(Z),kind:Y};if(Y==="scale")return{durationUs:J,easing:NJ(Z),fromScale:F,kind:Y};let H=/^slide-(up|down|left|right)$/u.exec(Y);if(H?.[1]==="up"||H?.[1]==="down"||H?.[1]==="left"||H?.[1]==="right")return{direction:H[1],distancePx:X,durationUs:J,easing:NJ(Z),kind:"slide"};throw new j("usage",`Unsupported overlay animation: ${Y}`)}function A81($){let Q=$.trim().toLocaleLowerCase().replaceAll("u+","").replaceAll(/[_\s]+/gu,"-");if(/^[a-f0-9]+(?:-[a-f0-9]+)*$/u.test(Q))return{kind:"id",value:Q};if([...$].length<=16&&/[^\p{L}\p{N}\p{P}\p{Z}]/u.test($))return{kind:"unicode",value:$};return{kind:"name",value:$}}function uF($,Q,_){let Z=E4($,_),F=E4(Q,_);if(F<=Z)throw new j("usage",`Time range must increase: ${$}..${Q}`);return{endUs:F,startUs:Z}}function T81($){let Q=$.length+1;while($.some(({overlayId:_})=>_===`overlay_manual${String(Q).padStart(4,"0")}`))Q+=1;return`overlay_manual${String(Q).padStart(4,"0")}`}function R81($){let Q=$.length+1;while($.includes(`zoom_manual${String(Q).padStart(4,"0")}`))Q+=1;return`zoom_manual${String(Q).padStart(4,"0")}`}async function iK0($,Q,_,Z,F,X){let{startUs:Y,endUs:J}=uF(Z.from,Z.to,F),H=X?.({endUs:J,startUs:Y})??J-Y;if(H<=0)throw new j("conflict","Overlay range has no visible kept output time.");let K=Z.overlayKind==="emoji"?await DV($.paths.repositoryRoot,Z.source,Z.variant,Z.provider):void 0,W=Z.overlayKind==="emoji"?await JA(Q,K):await YA(Q,Z.source,Z.overlayKind),{created:V,...N}=W,G=async()=>{let D=_.some((L)=>L.source.asset.path===N.path);if(V&&!D)await VN(V5(Q,N.path),{force:!0})};try{let D=await g$(Q,N.path),L=N.mediaType==="image/svg+xml"?{...await KY(D),audioEndUs:null,audioStartUs:0,audioStreamIndex:null,durationUs:null,hasAudio:!1,videoStartUs:0,videoStreamIndex:null}:await M3(await OJ($,"ffprobe"),$.runner,D),O={height:"pixelHeight"in L?L.pixelHeight:L.height,width:"pixelWidth"in L?L.pixelWidth:L.width},w;if(Z.overlayKind==="image"||Z.overlayKind==="svg")w={asset:N,kind:Z.overlayKind};else if(Z.overlayKind==="emoji")w={asset:N,kind:"emoji",provider:K.provider,selector:A81(Z.source)};else{if(Z.loop&&Z.freezeEnd)throw new j("usage","Use only one of --loop and --freeze-end.");let C=E4(Z.sourceIn??"0us",F),U=Z.sourceOut===void 0?void 0:E4(Z.sourceOut,F);if(L.durationUs===null||L.durationUs<=0)throw new j("invalid-data","Animated overlay media must report a positive finite duration.");if(Z.overlayKind==="video"&&Z.animatedAudio!=="mute"&&!L.hasAudio)throw new j("conflict",`Video overlay audio policy ${Z.animatedAudio} requires an audio stream in the source media.`);let z=OV({mediaDurationUs:L.durationUs,outputDurationUs:H,playbackRate:Z.playbackRate,sourceInUs:C,sourceOutUs:U}),M={audioEndUs:L.audioEndUs,audioStartUs:L.audioStartUs,audioStreamIndex:L.audioStreamIndex,endBehavior:Z.loop?"loop":Z.freezeEnd?"freeze-end":"hide",playbackRate:Z.playbackRate,streamStartUs:L.videoStartUs,videoStreamIndex:L.videoStreamIndex,...z};if(Z.overlayKind==="gif")w={asset:N,audioPolicy:{kind:"mute"},kind:"gif",playback:M};else{let T=Z.animatedAudio==="mute"?{kind:"mute"}:Z.animatedAudio==="mix"?{kind:"mix",volume:Z.audioVolume}:{duckPrimaryTo:Z.duckPrimaryTo,kind:"duck-primary",volume:Z.audioVolume};w={asset:N,audioPolicy:T,kind:"video",playback:M}}}if(Z.width===void 0!==(Z.height===void 0))throw new j("usage","Overlay pixel size requires both --width and --height.");let B=B5.safeParse({anchor:Z.anchor,blendMode:Z.blendMode,coordinateSpace:"output-pixels",crop:Z.crop===void 0?{kind:"none"}:{bottom:Z.crop[3],kind:"normalized-insets",left:Z.crop[0],right:Z.crop[2],top:Z.crop[1]},entrance:xK0(Z.entrance,Z.entranceDuration,"250ms",Z.easing,Z.entranceFromScale,Z.slideDistance),exit:xK0(Z.exit,Z.exitDuration,"250ms",Z.easing,Z.exitToScale,Z.slideDistance),fit:Z.fit,intrinsicSize:O,mask:Z.cornerRadius===void 0?{kind:"none"}:{kind:"rounded-rectangle",radiusPx:Z.cornerRadius},motion:Z.motionKeyframes.length===0?{kind:"none"}:{keyframes:Z.motionKeyframes.map((C)=>({easing:NJ(Z.easing),offset:C.offset,opacityMultiplier:C.opacity,positionOffset:{x:C.position[0],y:C.position[1]},rotationOffsetDegrees:C.rotation,scaleMultiplier:C.scale})),kind:"keyframes",timeline:"visible-output"},opacity:Z.opacity,overlayId:T81(_),position:{x:Z.position[0],y:Z.position[1]},range:{endUs:J,startUs:Y},rotationDegrees:Z.rotation,scale:Z.scale,size:Z.width===void 0||Z.height===void 0?{kind:"intrinsic"}:{height:Z.height,kind:"pixels",width:Z.width},source:w,zIndex:Z.zIndex});if(!B.success)throw new j("usage",`Invalid overlay: ${B.error.issues[0]?.message??"unknown error"}`);return{operation:B.data,rollback:G}}catch(D){throw await G(),D}}function k81($,Q,_,Z){let F=aK0($,Q,void 0,Z),X=F.displayId??_.sources.displays.find(({isPrimary:Y})=>Y)?.displayId;if(X===void 0)throw new j("not-found","Manual zoom requires a selected or primary display.");return BZ.parse({...F,displayId:X,kind:"manual"})}function aK0($,Q,_,Z){let{startUs:F,endUs:X}=uF($.from,$.to,Z),Y=$.target==="rect"?{kind:"rect",rect:{height:$.rect[3],width:$.rect[2],x:$.rect[0],y:$.rect[1]}}:$.target==="point"?{kind:"point",point:{x:$.point[0],y:$.point[1]}}:$.target==="cursor"?{kind:"cursor",sampling:"interpolated"}:$.target==="focused-input"?{kind:"focused-input",paddingPx:24}:$.window==="frontmost"?{kind:"window",paddingPx:24,selector:{kind:"frontmost"}}:$.window.startsWith("bundle:")?{kind:"window",paddingPx:24,selector:{applicationBundleId:$.window.slice(7),kind:"application"}}:{kind:"window",paddingPx:24,selector:{kind:"window-id",windowId:$.window}},J=X-F,H=Math.min(300000,Math.max(0,Math.floor(J/2))),K=$.enterDuration===void 0?H:E4($.enterDuration,Z),W=$.exitDuration===void 0?H:E4($.exitDuration,Z),V=Xy.safeParse({...$.display===void 0?{}:{displayId:$.display},easing:NJ($.easing),enterDurationUs:K,exitDurationUs:W,..._===void 0?{}:{placementId:_},range:{endUs:X,startUs:F},scale:$.scale,target:Y,zoomId:R81(Q)});if(!V.success)throw new j("usage",`Invalid zoom: ${V.error.issues[0]?.message??"unknown error"}`);return V.data}async function q81($,Q){let _=await M$($.paths.artifactRoot,Q.recording);if(_.manifest.state!=="stopped")throw new j("conflict","Editing requires a stopped recording with an immutable timeline, media, and events.");if(Q.edit.operation==="init"){let J=await tf(_),H=J??Ve(_.manifest,c10(_.manifest),$.io.now().toISOString());await yK0(_,J===null?"init":"init-existing",H,Q.json,$.io);return}let Z=await fD(_);if(Q.edit.operation==="show"){u0($.io,Q.json,Z,()=>`${Z.planId} ${sZ(Z)} keep=${Z.keep.length} speed=${Z.speed.length} zooms=${Z.zooms.length} overlays=${Z.overlays.length}`);return}let F=$.io.now().toISOString(),X,Y=Q.edit;switch(Y.operation){case"trim":X=Ge(Z,uF(Y.from,Y.to,Q.fps),F);break;case"cut":X=Tz(Z,uF(Y.from,Y.to,Q.fps),F);break;case"speed":X=aS(Z,uF(Y.from,Y.to,Q.fps),Y.rate,F);break;case"zoom-add":X=Ne(Z,k81(Y,Z.zooms.map((J)=>J.zoomId),_.manifest,Q.fps),F);break;case"zoom-remove":X=je(Z,Y.id,F);break;case"overlay-add":{let J=await iK0($,_.directory.path,Z.overlays,Y,Q.fps,(K)=>TH(mz(Z),K).reduce((W,V)=>W+V.output.endUs-V.output.startUs,0));try{X=R2(De(Z,J.operation,F)),await l1(V5(_.directory.path,"edits")),await Nj(_.fileSystem,X,iX)}catch(K){throw await J.rollback(),K}let H=oK0(_,Y.operation,X);u0($.io,Q.json,H,()=>`${Y.operation} ${X.planId} ${String(H.planHash)}`);return}case"overlay-remove":X=Oe(Z,Y.id,F);break;case"cursor":X=vX({...Z,effects:{...Z.effects,...Y.clickHighlight===void 0?{}:{clicks:Y.clickHighlight?{color:"#ffcc00cc",durationUs:350000,enabled:!0,radiusPx:28,style:"pulse"}:{enabled:!1}},cursor:Y.enabled?{enabled:!0,scale:1,smoothing:{algorithm:"exponential",strength:Y.smoothing??0.7},style:"captured"}:{enabled:!1}},updatedAt:F});break;case"clicks":X=vX({...Z,effects:{...Z.effects,clicks:Y.enabled?{color:Y.color,durationUs:E4(Y.duration,Q.fps),enabled:!0,radiusPx:Y.radius,style:Y.style}:{enabled:!1}},updatedAt:F});break;case"keystrokes":X=vX({...Z,effects:{...Z.effects,keystrokes:Y.enabled?{enabled:!0,holdUs:E4(Y.stopAfter??"1200ms",Q.fps),maxKeys:8,position:"bottom-right",secureText:"hide"}:{enabled:!1}},updatedAt:F});break;case"typed-text":if(Y.enabled&&_.manifest.capture.typedText!=="enabled")throw new j("conflict","Typed-text rendering cannot be enabled because typed-text capture was disabled for this recording.");X=vX({...Z,effects:{...Z.effects,typedText:Y.enabled?{enabled:!0,idleTimeoutUs:E4(Y.idleTimeout,Q.fps),maxCharacters:Y.maxCharacters,placement:Y.placement,secureText:"hide"}:{enabled:!1}},updatedAt:F});break}await yK0(_,Y.operation,X,Q.json,$.io)}async function tK0($,Q,_){if(Q.manifest.state!=="stopped")throw new j("conflict","Inactivity analysis requires a stopped recording with immutable media and events.");let Z=await FK($,["ffmpeg","ffprobe"]),F=z8(Z,"ffmpeg"),X=z8(Z,"ffprobe"),Y=new yD({ffmpeg:F,ffprobe:X,runner:$.runner}),J=Q.manifest.tracks.filter((L)=>L.enabled&&L.kind==="display-video");if(J.length===0)throw new j("invalid-data","Recording has no enabled display tracks to analyze.");let H=await L3(J,4,async(L)=>{let O=[];for(let w of L.segments){if(w.integrity.state!=="verified"||w.integrity.bytes<=0)throw new j("invalid-data",`Inactivity media ${w.path} does not have verified integrity.`);let B=await a1({expected:w.integrity,label:`Inactivity media ${w.path}:${w.streamIndex}`,path:w.path,repositoryRoot:Q.directory.path}),C=await Y.freeze(B,w.streamIndex,_.minDurationUs,_.motionThreshold,w.startUs);O.push(...C.filter(({startUs:U,endUs:z})=>Uw.startUs).map(({startUs:U,endUs:z})=>({confidence:1,meanFrameDifference:_.motionThreshold,range:{startUs:Math.max(U,w.startUs),endUs:Math.min(z,w.endUs)}})))}return{intervals:O,trackId:L.trackId}}),K=_.protectAudio?Q.manifest.tracks.filter((L)=>L.enabled&&(L.kind==="system-audio"||L.kind==="microphone-audio")):[],W=await L3(K,4,async(L)=>{let O=[];for(let w of L.segments){if(w.integrity.state!=="verified"||w.integrity.bytes<=0)throw new j("invalid-data",`Inactivity media ${w.path} does not have verified integrity.`);let B=await a1({expected:w.integrity,label:`Inactivity media ${w.path}:${w.streamIndex}`,path:w.path,repositoryRoot:Q.directory.path}),C=await Y.silence(B,w.streamIndex,_.minDurationUs,w.startUs);O.push(...C.filter(({startUs:U,endUs:z})=>Uw.startUs).map(({startUs:U,endUs:z})=>({peakDb:-45,range:{startUs:Math.max(U,w.startUs),endUs:Math.min(z,w.endUs)}})))}return{intervals:O,trackId:L.trackId}}),V=gY(Z,"ffmpeg").version??"unknown",N=pB.parse({audio:W,displays:H,kind:"slopcamera.analyzer-evidence",schemaVersion:1,sourceDurationUs:Q.manifest.timeline.durationUs,tool:{name:"ffmpeg-freezedetect-silencedetect",version:V.slice(0,128)}});await l1(V5(Q.directory.path,"analysis")),await Q.fileSystem.writeTextAtomic("analysis/inactivity-v1.json",`${R(N)} `);let G=await eq(Q),D=Ye(N,G,{edgeHandleUs:250000,interactionHandleUs:750000,minimumCutUs:_.minDurationUs,cursorMovementThresholdPx:2,requireAudioSilence:_.protectAudio});return{evidence:N,result:D}}async function E81($,Q){let _=await M$($.paths.artifactRoot,Q.recording);if(_.manifest.state!=="stopped")throw new j("conflict","Inactivity analysis requires a stopped recording with immutable media and events.");let Z=await fD(_),F=await tK0($,_,{minDurationUs:E4(Q.minDuration),motionThreshold:Q.motionThreshold,protectAudio:Q.protectAudio}),X=Z;if(Q.apply&&Q.handle!=="keep"){for(let J of F.result.cuts)X=Q.handle==="cut"?Tz(X,J,$.io.now().toISOString()):aS(X,J,Q.speedRate,$.io.now().toISOString());X=R2(X),await l1(V5(_.directory.path,"edits")),await Nj(_.fileSystem,X,iX)}let Y={applied:Q.apply&&Q.handle!=="keep",candidateCount:F.result.candidateCount,cuts:F.result.cuts,evidencePath:"analysis/inactivity-v1.json",handle:Q.handle,planHash:sZ(X),protectedInteractionCount:F.result.protectedInteractionCount,recordingId:_.manifest.recordingId};u0($.io,Q.json,Y,()=>`${Y.cuts.length} inactivity range(s), ${Y.applied?"applied":"dry-run"}; plan ${Y.planHash}`)}async function P81($,Q){let _=await o4($.paths.projectRoot,Q.recording);if(Q.apply&&Q.handle!=="keep")$W0(_.project,"Automated project inactivity edits");let Z=await FK($,["ffmpeg","ffprobe"]),F=z8(Z,"ffmpeg"),X=z8(Z,"ffprobe"),Y=gY(Z,"ffmpeg").version??"unknown",J=await Z20({artifactRoot:$.paths.artifactRoot,config:{...aX,minimumCutUs:E4(Q.minDuration),motionThreshold:Q.motionThreshold,requireAudioSilence:Q.protectAudio},ffmpeg:F,ffmpegVersion:Y,ffprobe:X,now:$.io.now(),project:_,repositoryRoot:$.paths.repositoryRoot,runner:$.runner,toolVersion:$.version}),H=await g8(_),K=Q.apply&&Q.handle!=="keep"&&J.analysis.result.recommendedRanges.length>0;if(K){let V=$.io.now().toISOString(),N=le({analysis:J.analysis,decisionIds:J.analysis.result.recommendedRanges.map(()=>`decision_${g_().replaceAll("-","")}`),operation:Q.handle==="cut"?"cut":"speed",plan:H,project:J.project,speedRate:Q.speedRate,updatedAt:V});if(N.status==="rejected")throw new j("conflict",`Inactivity application was rejected: ${N.reason}`,N);H=R2(N.plan),await dQ(_.fileSystem,H)}let W={analysisId:J.analysis.analysisId,applied:K,candidateCount:J.analysis.result.candidateCount,cuts:J.analysis.result.recommendedRanges,evidencePath:J.analysisPath,handle:Q.handle,planHash:h2(H),projectId:J.project.projectId,protectedInteractionCount:J.analysis.result.protectedInteractionCount,referenceRecording:J.analysis.referenceRecording?.recordingId??null};u0($.io,Q.json,W,()=>`${W.cuts.length} project inactivity range(s), ${W.applied?"applied":"evidence only"}; analysis ${W.analysisId}; plan ${W.planHash}`)}async function I81($,Q){if(Q.recording.startsWith("project_")){await P81($,Q);return}await E81($,Q)}async function b81($,Q){let _=await M$($.paths.artifactRoot,Q.recording);if(_.manifest.state!=="stopped")throw new j("conflict","Automatic zoom analysis requires a stopped recording with immutable events.");let Z=await fD(_);if(Q.plan!==void 0&&Q.plan!=="current"&&Q.plan!==Z.planId)throw new j("not-found",`Only current (${Z.planId}) is available; requested ${Q.plan}.`);let F=Oz(await eq(_),Z.sourceDurationUs,{enterDurationUs:300000,exitDurationUs:300000,intentMergeGapUs:750000,maxDurationUs:8000000,maxScale:3,minDurationUs:1500000,postHandleUs:1e6,preHandleUs:500000,scale:2}),X=Z;if(Q.apply)X=vX({...Z,updatedAt:$.io.now().toISOString(),zooms:[...Z.zooms.filter(({kind:J})=>J!=="automatic"),...F]}),X=R2(X),await l1(V5(_.directory.path,"edits")),await Nj(_.fileSystem,X,iX);let Y={applied:Q.apply,planHash:sZ(X),recordingId:_.manifest.recordingId,suggestions:F.map((J)=>({confidence:J.confidence,range:J.range,reason:J.reason,scale:J.scale,target:J.target,zoomId:J.zoomId}))};u0($.io,Q.json,Y,()=>`${F.length} automatic zoom suggestion(s), ${Q.apply?"applied":"dry-run"}; plan ${Y.planHash}`)}function S81($,Q){let _=$.tracks.filter((F)=>F.enabled&&F.kind==="display-video"),Z=Q==="primary"?_.find((F)=>$.sources.displays.some((X)=>X.isPrimary&&X.displayId===F.source.displayId)):_.find((F)=>F.source.displayId===Q||F.trackId===Q);if(Z===void 0)throw new j("not-found",`No enabled display track matches ${Q}.`);return Z}async function f81($,Q,_,Z,F){let X=_;if(Z){let W=await tK0($,Q,{minDurationUs:3000000,motionThreshold:0.003,protectAudio:!0});for(let V of W.result.cuts)X=Tz(X,V,_.updatedAt)}let Y=S81(Q.manifest,F),J=Q.manifest.sources.displays.find(({displayId:W})=>W===Y.source.displayId),H=await eq(Q),K=Q.manifest.tracks.filter((W)=>W.enabled&&(W.kind==="system-audio"||W.kind==="microphone-audio")).map(({trackId:W})=>W);return{effectivePlan:X,renderPlan:j00(Q.manifest,X,H,{audioTrackIds:K,camera:{kind:"none"},displayTrackId:Y.trackId,frameRate:Math.min(60,J.refreshRateHz),pixelHeight:J.pixelSize.height,pixelWidth:J.pixelSize.width})}}async function y81($,Q){let _=await M$($.paths.artifactRoot,Q.recording);if(_.manifest.state!=="stopped")throw new j("conflict","Rendering requires a stopped recording with immutable media and events.");let Z=await fD(_),F=await f81($,_,Z,Q.autoInactivity,Q.display),X=Y0(R(F.renderPlan)),Y=`renders/resolved-${X}.json`,J=`renders/${X}.mp4`;await l1(V5(_.directory.path,"renders"));let H=Q.kind==="render-plan"&&Q.output!==void 0?await M81(_,Q.output,Y):void 0;if(await _.fileSystem.writeTextAtomic(Y,`${R(F.renderPlan)} `),Q.kind==="render-plan"){if(H!==void 0&&H.relative!==Y)await _.fileSystem.writeTextAtomic(H.relative,`${R(F.renderPlan)} diff --git a/dist/cli.js b/dist/cli.js index bcbc68e0..b58ffc0f 100755 --- a/dist/cli.js +++ b/dist/cli.js @@ -1,6 +1,6 @@ #!/usr/bin/env bun // @bun -import{SLOPCAMERA_VERSION,VISUAL_STYLE_PROFILES,artifactSummary,checkDiagramFile,checkDrawingFile,createVisualStyleDirection,getVisualStyleProfile,renderDiagramFile,renderDrawingFile,runMcpServer,starterDrawingSource}from"./index-z2xp9jaq.js";import{installSkill,pathExists}from"./index-grk47tgs.js";import"./index-z1kd1x8j.js";import"./index-3cxf2c58.js";import"./index-4z9y2wa2.js";import{executeSlopcameraOperation,generateSlopcameraIcon,generateSlopcameraImageGallery,isSlopcameraOperationCode,parseSlopcameraGalleryVary,searchSlopcameraOperations,slopcameraGalleryKinds,slopcameraGalleryLimits,slopcameraIconMaximumRounds,slopcameraOperationCodes,withSlopcameraOperationHostAdmission}from"./index-fevf4ppk.js";import{vectorizeImage}from"./index-mnp0bftq.js";import{generateSlopcameraImageFile,slopcameraGatewayCredentialStatus,slopcameraImageModels}from"./index-nxtmy18t.js";import"./index-b3geqczn.js";import{__require}from"./index-80a36bc0.js";import{readFile,writeFile}from"fs/promises";import{resolve}from"path";function reportUsefulResult(observer){try{if(observer!==undefined)Promise.resolve(observer()).catch(()=>{return})}catch{}}import{maybeShowSupportInvitation,runSupportCommand,supportAdvancedHelp,supportHelpLine}from"@hraness/support-foundation/node";var slopcameraSupportHelpLine=()=>supportHelpLine({command:["slopcamera"]});var slopcameraSupportAdvancedHelp=()=>supportAdvancedHelp({command:["slopcamera"]});var supportProfile={id:"slopcamera",name:"Slopcamera",valueProposition:"Support ongoing development of local media tools for agents.",updates:false};function standaloneSupportEnvironment(){const env={...process.env};process.env.HRANESS_SUPPORT_AUDIENCE="off";process.env.HRANESS_SUPPORT_EMAIL="off";return env}async function runProductSupportCommand(args,options={}){const result=await runSupportCommand(supportProfile,args,{command:["slopcamera"],...options,gitEmail:false});if(result.stdout!=="")process.stdout.write(result.stdout);if(result.stderr!=="")process.stderr.write(result.stderr);return result.exitCode}async function showProductSupportInvitation(options={}){try{await maybeShowSupportInvitation(supportProfile,{usefulResult:true,command:["slopcamera"],...options,gitEmail:false})}catch{}}var slopcameraCliVersion=SLOPCAMERA_VERSION;var help=()=>`slopcamera ${slopcameraCliVersion} +import{SLOPCAMERA_VERSION,VISUAL_STYLE_PROFILES,artifactSummary,checkDiagramFile,checkDrawingFile,createVisualStyleDirection,getVisualStyleProfile,renderDiagramFile,renderDrawingFile,runMcpServer,starterDrawingSource}from"./index-qxfexvj3.js";import{installSkill,pathExists}from"./index-grk47tgs.js";import"./index-z1kd1x8j.js";import"./index-3cxf2c58.js";import"./index-4z9y2wa2.js";import{executeSlopcameraOperation,generateSlopcameraIcon,generateSlopcameraImageGallery,isSlopcameraOperationCode,parseSlopcameraGalleryVary,searchSlopcameraOperations,slopcameraGalleryKinds,slopcameraGalleryLimits,slopcameraIconMaximumRounds,slopcameraOperationCodes,withSlopcameraOperationHostAdmission}from"./index-fevf4ppk.js";import{vectorizeImage}from"./index-mnp0bftq.js";import{generateSlopcameraImageFile,slopcameraGatewayCredentialStatus,slopcameraImageModels}from"./index-nxtmy18t.js";import"./index-b3geqczn.js";import{__require}from"./index-80a36bc0.js";import{readFile,writeFile}from"fs/promises";import{resolve}from"path";function reportUsefulResult(observer){try{if(observer!==undefined)Promise.resolve(observer()).catch(()=>{return})}catch{}}import{maybeShowSupportInvitation,runSupportCommand,supportAdvancedHelp,supportHelpLine}from"@hraness/support-foundation/node";var slopcameraSupportHelpLine=()=>supportHelpLine({command:["slopcamera"]});var slopcameraSupportAdvancedHelp=()=>supportAdvancedHelp({command:["slopcamera"]});var supportProfile={id:"slopcamera",name:"Slopcamera",valueProposition:"Support ongoing development of local media tools for agents.",updates:false};function standaloneSupportEnvironment(){const env={...process.env};process.env.HRANESS_SUPPORT_AUDIENCE="off";process.env.HRANESS_SUPPORT_EMAIL="off";return env}async function runProductSupportCommand(args,options={}){const result=await runSupportCommand(supportProfile,args,{command:["slopcamera"],...options,gitEmail:false});if(result.stdout!=="")process.stdout.write(result.stdout);if(result.stderr!=="")process.stderr.write(result.stderr);return result.exitCode}async function showProductSupportInvitation(options={}){try{await maybeShowSupportInvitation(supportProfile,{usefulResult:true,command:["slopcamera"],...options,gitEmail:false})}catch{}}var slopcameraCliVersion=SLOPCAMERA_VERSION;var help=()=>`slopcamera ${slopcameraCliVersion} Turn source material into deterministic diagrams, images, and canvas assets. diff --git a/dist/index-z2xp9jaq.js b/dist/index-qxfexvj3.js similarity index 99% rename from dist/index-z2xp9jaq.js rename to dist/index-qxfexvj3.js index 2dcc9504..439d1073 100644 --- a/dist/index-z2xp9jaq.js +++ b/dist/index-qxfexvj3.js @@ -20,7 +20,7 @@ ${freeEntry}${usedEntries}trailer startxref ${offset} %%EOF -`);const bytes=Buffer.from(chunks.join(""));if(bytes.length>32*1024*1024)throw new Error("Drawing PDF exceeds output byte limit");return bytes}var SLOPCAMERA_VERSION="3.5.0";var drawingProfile="patent-line-art-v1";var drawingSourceByteLimit=1024*1024;var drawingMinimumGlyphHeightPt=3.2*72/25.4;class DrawingValidationError extends Error{constructor(message){super(`Invalid drawing source: ${message}`);this.name="DrawingValidationError"}}function fail2(message){throw new DrawingValidationError(message)}var sha256=(value)=>createHash("sha256").update(value).digest("hex");var assetPath=(asset)=>isAbsolute2(asset)?asset:fileURLToPath(new URL(asset,import.meta.url));var fontFiles=[assetPath(NebulaSans_Book_default),assetPath(NebulaSans_Bold_default)];var monochrome={background:"#ffffff",foreground:"#000000",muted:"#000000",stroke:"#000000",tones:Object.fromEntries(["neutral","blue","orange","green","red","purple","yellow"].map((tone)=>[tone,{fill:"#ffffff",stroke:"#000000",text:"#000000"}]))};var config={font:{family:"Nebula Sans",files:[{path:fontFiles[0],weight:400},{path:fontFiles[1],weight:700}]},theme:{light:monochrome}};var escapeXml=(value)=>value.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""");function drawingPageGeometry(paper){if(paper!=="us-letter"&&paper!=="a4")fail2("paper must be us-letter or a4");const width=paper==="us-letter"?612:210*72/25.4;const height=paper==="us-letter"?792:297*72/25.4;const margins={left:25*72/25.4,top:25*72/25.4,right:15*72/25.4,bottom:10*72/25.4};return{width,height,margins,numberingHeight:30,body:{x:margins.left,y:margins.top+30,width:width-margins.left-margins.right,height:height-margins.top-margins.bottom-60}}}function record(value,keys,at){if(typeof value!=="object"||value===null||Array.isArray(value))fail2(`${at} must be an object`);const result=value;for(const key of Object.keys(result))if(!keys.includes(key))fail2(`${at}.${key} is unsupported`);return result}function checkDiagramEnvelope(value){const diagram=record(value,["$schema","version","name","canvas","layout","shapes","edges"],"diagram");const bounded=(object)=>{for(const value2 of Object.values(object)){if(typeof value2==="number"&&(!Number.isFinite(value2)||Math.abs(value2)>1e4))fail2("numeric drawing values must be finite and within 10000 points");if(typeof value2==="string"&&value2.length>1024)fail2("drawing strings exceed the bounded text limit")}};bounded(diagram);bounded(record(diagram.canvas,["width","height","padding"],"canvas"));if(diagram.layout!==undefined)bounded(record(diagram.layout,["type","direction","gap","align"],"layout"));if(!Array.isArray(diagram.shapes)||diagram.shapes.length<1||diagram.shapes.length>100)fail2("each sheet needs 1 to 100 shapes");for(const value2 of diagram.shapes){const shape=record(value2,["id","type","x","y","tone","opacity","width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap","text","fontSize","fontFamily","weight","align","x2","y2"],"shape");bounded(shape);const common=["id","type","x","y","tone","opacity"];const extras=shape.type==="text"?["text","width","fontSize","fontFamily","weight","align"]:shape.type==="line"?["x2","y2","strokeWidth"]:["width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap"];record(value2,[...common,...extras],"shape");if(shape.labelRows!==undefined){if(!Array.isArray(shape.labelRows)||shape.labelRows.length>4)fail2("labelRows must be bounded");for(const row of shape.labelRows)bounded(record(row,["text","fontSize","fontFamily","weight"],"label row"))}for(const key of["label","text"])if(typeof shape[key]==="string"&&shape[key].length>500)fail2("label exceeds text limit")}if(diagram.edges!==undefined){if(!Array.isArray(diagram.edges)||diagram.edges.length>150)fail2("at most 150 edges are supported");for(const edge of diagram.edges)bounded(record(edge,["id","from","to","label","tone","start","end","bend","arrowhead","startPosition","endPosition","labelFontSize","labelFontFamily","labelWeight","labelPosition","labelOffset"],"edge"))}}function parseDrawingSource(value){const raw=record(value,["$schema","version","name","title","paper","sheets"],"drawing");if(raw.version!==1)fail2("version must be 1");if(typeof raw.name!=="string"||raw.name.length>100||!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(raw.name))fail2("name must be a bounded lowercase hyphenated name");if(raw.paper!=="us-letter"&&raw.paper!=="a4")fail2("paper must be us-letter or a4");if(raw.title!==undefined&&(typeof raw.title!=="string"||raw.title.length<1||Buffer.byteLength(raw.title)>1024||/[\u0000-\u001f]/u.test(raw.title)))fail2("title must be a bounded metadata string");if(raw.$schema!==undefined&&typeof raw.$schema!=="string")fail2("$schema must be a string");if(!Array.isArray(raw.sheets)||raw.sheets.length<1||raw.sheets.length>20)fail2("sheets must contain 1 to 20 sheets");const sheets=raw.sheets.map((sheet,index)=>{const entry=record(sheet,["figure","diagram"],`sheets[${index}]`);if(entry.figure!==index+1)fail2("figure numbers must be consecutive beginning at 1");checkDiagramEnvelope(entry.diagram);const diagram=parseDiagramSource(entry.diagram);const spec=parseDiagramSpec(diagram);if(spec.shapes.length<1||spec.shapes.length>100||(spec.edges?.length??0)>150)fail2("each sheet needs 1 to 100 shapes and at most 150 edges");return{figure:index+1,diagram}});const source={version:1,name:raw.name,paper:raw.paper,sheets,...raw.title===undefined?{}:{title:raw.title},...raw.$schema===undefined?{}:{$schema:raw.$schema}};if(Buffer.byteLength(JSON.stringify(source))>drawingSourceByteLimit)fail2("source exceeds 1MiB byte limit");return source}function renderer(svg){return new Resvg(svg,{font:{fontFiles,loadSystemFonts:false,defaultFontFamily:"Nebula Sans"},logLevel:"off"})}function bounds(engine){const box=engine.getBBox();if(box===undefined)fail2("empty drawing ink");return{x:box.x,y:box.y,width:box.width,height:box.height}}function inside(ink,box,label){const epsilon=0.01;if(ink.xbox.x+box.width+epsilon||ink.y+ink.height>box.y+box.height+epsilon)fail2(`${label} ink extends beyond its bounds`)}async function sceneSvg(spec){return(await renderSvg(spec,"light",config,{edgeStrokeWidth:1})).svg.replace('',"")}function glyphHeight(character,fontSize,weight){const svg=`${escapeXml(character)}`;return bounds(renderer(svg)).height}function inspectLabels(spec,glyphCache){let minimum=Infinity;const inspect=(text,fontSize,weight,family)=>{if(text.length<1||text.length>500||!Array.from(text).every((character)=>/^[A-Z0-9 \n]$/u.test(character)||".,:;()[]/+=_*'!?%-".includes(character)))fail2("visible labels must be uppercase ASCII letters, numbers, spaces, or supported punctuation; labels are never rewritten");if(family!==undefined&&family!=="default")fail2("only the bundled default font is supported");if(!Number.isFinite(fontSize)||fontSize<=0||fontSize>18)fail2("authored font size must be positive and at most 18 points, below the 20 point sheet numbering");for(const character of new Set(text.match(/[A-Z0-9]/gu)??[])){const key=`${character}:${fontSize}:${weight}`;const measured=glyphCache.get(key)??glyphHeight(character,fontSize,weight);glyphCache.set(key,measured);if(glyphCache.size>4096)fail2("glyph measurement limit exceeded");minimum=Math.min(minimum,measured);if(measured+0.0014)fail2("stroke width must be 0.5 to 4 points");for(const row of layoutBoxContent(shape).rows)inspect(row.text,row.fontSize,row.weight,row.fontFamily)}else if(shape.type==="text")inspect(shape.text,shape.fontSize??24,shape.weight??500,shape.fontFamily);else if((shape.strokeWidth??3)<0.5||(shape.strokeWidth??3)>4)fail2("stroke width must be 0.5 to 4 points")}for(const edge of spec.edges??[]){if(edge.tone!==undefined&&edge.tone!=="neutral")fail2("colored edge tones are unsupported");if(edge.label!==undefined)inspect(edge.label,edge.labelFontSize??18,edge.labelWeight??600,edge.labelFontFamily)}return minimum}async function renderDrawing(input,sourceSha256){const source=parseDrawingSource(input);const sourceDigest=sourceSha256??sha256(JSON.stringify(source));if(!/^[a-f0-9]{64}$/u.test(sourceDigest))fail2("source SHA-256 is invalid");const geometry=drawingPageGeometry(source.paper);const sheets=[];const cache=new Map;let minGlyphHeightPt=Infinity;for(const sheet of source.sheets){const spec=parseDiagramSpec(sheet.diagram);if(spec.canvas.width>geometry.body.width+0.001||spec.canvas.height>geometry.body.height+0.001)fail2(`figure ${sheet.figure} canvas exceeds ${geometry.body.width.toFixed(3)} by ${geometry.body.height.toFixed(3)}pt body; no automatic scaling is performed`);minGlyphHeightPt=Math.min(minGlyphHeightPt,inspectLabels(spec,cache));const sourceSvg=await sceneSvg(spec);inside(bounds(renderer(sourceSvg)),{x:0,y:0,width:spec.canvas.width,height:spec.canvas.height},`figure ${sheet.figure}`);for(const shape of spec.shapes){if((shape.type==="rect"||shape.type==="ellipse")&&(shape.label!==undefined||shape.labelRows!==undefined)){const inset=(shape.strokeWidth??2)/2;const single=await sceneSvg({...spec,shapes:[shape],edges:[]});inside(bounds(renderer(single)),{x:shape.x-inset,y:shape.y-inset,width:shape.width+inset*2,height:shape.height+inset*2},`shape ${shape.id} label`)}}const diagramBody=sourceSvg.replace(/^]*>/u,"").replace(/<\/svg>$/u,"");const x=geometry.body.x+(geometry.body.width-spec.canvas.width)/2;const counter=`${sheet.figure}/${source.sheets.length}`;const figureLabel=source.sheets.length===1?"":`FIG. ${sheet.figure}`;const page=`${counter}${diagramBody}${figureLabel}`;const outlined=renderer(page).toString().replace(/width="[^"]+" height="[^"]+" viewBox="[^"]+"/u,`width="${geometry.width}pt" height="${geometry.height}pt" viewBox="0 0 ${geometry.width} ${geometry.height}"`);if(Buffer.byteLength(outlined)>2*1024*1024)fail2("sheet SVG exceeds output byte limit");sheets.push({svg:outlined,width:geometry.width,height:geometry.height,figure:sheet.figure})}for(const character of"FIG0123456789")minGlyphHeightPt=Math.min(minGlyphHeightPt,glyphHeight(character,20,400));if(minGlyphHeightPt+0.001drawingSourceByteLimit)fail2("source exceeds 1MiB byte limit");const buffer=Buffer.alloc(drawingSourceByteLimit+1);let cursor=0;while(cursordrawingSourceByteLimit)fail2("source exceeds 1MiB byte limit");bytes=buffer.subarray(0,cursor)}finally{await descriptor.close()}const raw=JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(bytes));return{absolutePath,source:parseDrawingSource(raw),sourceSha256:sha256(bytes)}}async function checkDrawingFile(options){const{source,sourceSha256}=await readDrawingFile(options.filePath);return(await renderDrawing(source,sourceSha256)).checks}async function atomicWrite2(filePath,data){const temporary=`${filePath}.tmp-${process.pid}-${crypto.randomUUID()}`;try{await writeFile2(temporary,data);await rename2(temporary,filePath)}catch(error){await rm2(temporary,{force:true});throw error}}async function renderDrawingFile(options){const{absolutePath,source,sourceSha256}=await readDrawingFile(options.filePath);const result=await renderDrawing(source,sourceSha256);const outDirectory=resolve3(options.outDirectory??dirname3(absolutePath));const artifacts={source:absolutePath,pdf:join2(outDirectory,`${source.name}.pdf`),sheets:result.sheets.map((_,index)=>join2(outDirectory,`${source.name}.sheet-${String(index+1).padStart(3,"0")}.svg`)),receipt:join2(outDirectory,`${source.name}.drawing-receipt.json`)};const receipt={version:1,profile:drawingProfile,rendererVersion:SLOPCAMERA_VERSION,sourceSha256,paper:source.paper,minGlyphHeightPt:result.checks.minGlyphHeightPt,sheets:result.sheets.map((sheet)=>({figure:sheet.figure,widthPt:sheet.width,heightPt:sheet.height,sha256:sha256(sheet.svg)})),pdfSha256:sha256(result.pdf)};await mkdir2(outDirectory,{recursive:true});for(const[index,sheet]of result.sheets.entries())await atomicWrite2(artifacts.sheets[index],sheet.svg);await atomicWrite2(artifacts.pdf,result.pdf);await atomicWrite2(artifacts.receipt,`${JSON.stringify(receipt,null,2)} +`);const bytes=Buffer.from(chunks.join(""));if(bytes.length>32*1024*1024)throw new Error("Drawing PDF exceeds output byte limit");return bytes}var SLOPCAMERA_VERSION="3.6.0";var drawingProfile="patent-line-art-v1";var drawingSourceByteLimit=1024*1024;var drawingMinimumGlyphHeightPt=3.2*72/25.4;class DrawingValidationError extends Error{constructor(message){super(`Invalid drawing source: ${message}`);this.name="DrawingValidationError"}}function fail2(message){throw new DrawingValidationError(message)}var sha256=(value)=>createHash("sha256").update(value).digest("hex");var assetPath=(asset)=>isAbsolute2(asset)?asset:fileURLToPath(new URL(asset,import.meta.url));var fontFiles=[assetPath(NebulaSans_Book_default),assetPath(NebulaSans_Bold_default)];var monochrome={background:"#ffffff",foreground:"#000000",muted:"#000000",stroke:"#000000",tones:Object.fromEntries(["neutral","blue","orange","green","red","purple","yellow"].map((tone)=>[tone,{fill:"#ffffff",stroke:"#000000",text:"#000000"}]))};var config={font:{family:"Nebula Sans",files:[{path:fontFiles[0],weight:400},{path:fontFiles[1],weight:700}]},theme:{light:monochrome}};var escapeXml=(value)=>value.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""");function drawingPageGeometry(paper){if(paper!=="us-letter"&&paper!=="a4")fail2("paper must be us-letter or a4");const width=paper==="us-letter"?612:210*72/25.4;const height=paper==="us-letter"?792:297*72/25.4;const margins={left:25*72/25.4,top:25*72/25.4,right:15*72/25.4,bottom:10*72/25.4};return{width,height,margins,numberingHeight:30,body:{x:margins.left,y:margins.top+30,width:width-margins.left-margins.right,height:height-margins.top-margins.bottom-60}}}function record(value,keys,at){if(typeof value!=="object"||value===null||Array.isArray(value))fail2(`${at} must be an object`);const result=value;for(const key of Object.keys(result))if(!keys.includes(key))fail2(`${at}.${key} is unsupported`);return result}function checkDiagramEnvelope(value){const diagram=record(value,["$schema","version","name","canvas","layout","shapes","edges"],"diagram");const bounded=(object)=>{for(const value2 of Object.values(object)){if(typeof value2==="number"&&(!Number.isFinite(value2)||Math.abs(value2)>1e4))fail2("numeric drawing values must be finite and within 10000 points");if(typeof value2==="string"&&value2.length>1024)fail2("drawing strings exceed the bounded text limit")}};bounded(diagram);bounded(record(diagram.canvas,["width","height","padding"],"canvas"));if(diagram.layout!==undefined)bounded(record(diagram.layout,["type","direction","gap","align"],"layout"));if(!Array.isArray(diagram.shapes)||diagram.shapes.length<1||diagram.shapes.length>100)fail2("each sheet needs 1 to 100 shapes");for(const value2 of diagram.shapes){const shape=record(value2,["id","type","x","y","tone","opacity","width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap","text","fontSize","fontFamily","weight","align","x2","y2"],"shape");bounded(shape);const common=["id","type","x","y","tone","opacity"];const extras=shape.type==="text"?["text","width","fontSize","fontFamily","weight","align"]:shape.type==="line"?["x2","y2","strokeWidth"]:["width","height","radius","icon","iconSize","strokeWidth","fill","label","labelFontSize","labelFontFamily","labelWeight","labelRows","labelRowGap"];record(value2,[...common,...extras],"shape");if(shape.labelRows!==undefined){if(!Array.isArray(shape.labelRows)||shape.labelRows.length>4)fail2("labelRows must be bounded");for(const row of shape.labelRows)bounded(record(row,["text","fontSize","fontFamily","weight"],"label row"))}for(const key of["label","text"])if(typeof shape[key]==="string"&&shape[key].length>500)fail2("label exceeds text limit")}if(diagram.edges!==undefined){if(!Array.isArray(diagram.edges)||diagram.edges.length>150)fail2("at most 150 edges are supported");for(const edge of diagram.edges)bounded(record(edge,["id","from","to","label","tone","start","end","bend","arrowhead","startPosition","endPosition","labelFontSize","labelFontFamily","labelWeight","labelPosition","labelOffset"],"edge"))}}function parseDrawingSource(value){const raw=record(value,["$schema","version","name","title","paper","sheets"],"drawing");if(raw.version!==1)fail2("version must be 1");if(typeof raw.name!=="string"||raw.name.length>100||!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(raw.name))fail2("name must be a bounded lowercase hyphenated name");if(raw.paper!=="us-letter"&&raw.paper!=="a4")fail2("paper must be us-letter or a4");if(raw.title!==undefined&&(typeof raw.title!=="string"||raw.title.length<1||Buffer.byteLength(raw.title)>1024||/[\u0000-\u001f]/u.test(raw.title)))fail2("title must be a bounded metadata string");if(raw.$schema!==undefined&&typeof raw.$schema!=="string")fail2("$schema must be a string");if(!Array.isArray(raw.sheets)||raw.sheets.length<1||raw.sheets.length>20)fail2("sheets must contain 1 to 20 sheets");const sheets=raw.sheets.map((sheet,index)=>{const entry=record(sheet,["figure","diagram"],`sheets[${index}]`);if(entry.figure!==index+1)fail2("figure numbers must be consecutive beginning at 1");checkDiagramEnvelope(entry.diagram);const diagram=parseDiagramSource(entry.diagram);const spec=parseDiagramSpec(diagram);if(spec.shapes.length<1||spec.shapes.length>100||(spec.edges?.length??0)>150)fail2("each sheet needs 1 to 100 shapes and at most 150 edges");return{figure:index+1,diagram}});const source={version:1,name:raw.name,paper:raw.paper,sheets,...raw.title===undefined?{}:{title:raw.title},...raw.$schema===undefined?{}:{$schema:raw.$schema}};if(Buffer.byteLength(JSON.stringify(source))>drawingSourceByteLimit)fail2("source exceeds 1MiB byte limit");return source}function renderer(svg){return new Resvg(svg,{font:{fontFiles,loadSystemFonts:false,defaultFontFamily:"Nebula Sans"},logLevel:"off"})}function bounds(engine){const box=engine.getBBox();if(box===undefined)fail2("empty drawing ink");return{x:box.x,y:box.y,width:box.width,height:box.height}}function inside(ink,box,label){const epsilon=0.01;if(ink.xbox.x+box.width+epsilon||ink.y+ink.height>box.y+box.height+epsilon)fail2(`${label} ink extends beyond its bounds`)}async function sceneSvg(spec){return(await renderSvg(spec,"light",config,{edgeStrokeWidth:1})).svg.replace('',"")}function glyphHeight(character,fontSize,weight){const svg=`${escapeXml(character)}`;return bounds(renderer(svg)).height}function inspectLabels(spec,glyphCache){let minimum=Infinity;const inspect=(text,fontSize,weight,family)=>{if(text.length<1||text.length>500||!Array.from(text).every((character)=>/^[A-Z0-9 \n]$/u.test(character)||".,:;()[]/+=_*'!?%-".includes(character)))fail2("visible labels must be uppercase ASCII letters, numbers, spaces, or supported punctuation; labels are never rewritten");if(family!==undefined&&family!=="default")fail2("only the bundled default font is supported");if(!Number.isFinite(fontSize)||fontSize<=0||fontSize>18)fail2("authored font size must be positive and at most 18 points, below the 20 point sheet numbering");for(const character of new Set(text.match(/[A-Z0-9]/gu)??[])){const key=`${character}:${fontSize}:${weight}`;const measured=glyphCache.get(key)??glyphHeight(character,fontSize,weight);glyphCache.set(key,measured);if(glyphCache.size>4096)fail2("glyph measurement limit exceeded");minimum=Math.min(minimum,measured);if(measured+0.0014)fail2("stroke width must be 0.5 to 4 points");for(const row of layoutBoxContent(shape).rows)inspect(row.text,row.fontSize,row.weight,row.fontFamily)}else if(shape.type==="text")inspect(shape.text,shape.fontSize??24,shape.weight??500,shape.fontFamily);else if((shape.strokeWidth??3)<0.5||(shape.strokeWidth??3)>4)fail2("stroke width must be 0.5 to 4 points")}for(const edge of spec.edges??[]){if(edge.tone!==undefined&&edge.tone!=="neutral")fail2("colored edge tones are unsupported");if(edge.label!==undefined)inspect(edge.label,edge.labelFontSize??18,edge.labelWeight??600,edge.labelFontFamily)}return minimum}async function renderDrawing(input,sourceSha256){const source=parseDrawingSource(input);const sourceDigest=sourceSha256??sha256(JSON.stringify(source));if(!/^[a-f0-9]{64}$/u.test(sourceDigest))fail2("source SHA-256 is invalid");const geometry=drawingPageGeometry(source.paper);const sheets=[];const cache=new Map;let minGlyphHeightPt=Infinity;for(const sheet of source.sheets){const spec=parseDiagramSpec(sheet.diagram);if(spec.canvas.width>geometry.body.width+0.001||spec.canvas.height>geometry.body.height+0.001)fail2(`figure ${sheet.figure} canvas exceeds ${geometry.body.width.toFixed(3)} by ${geometry.body.height.toFixed(3)}pt body; no automatic scaling is performed`);minGlyphHeightPt=Math.min(minGlyphHeightPt,inspectLabels(spec,cache));const sourceSvg=await sceneSvg(spec);inside(bounds(renderer(sourceSvg)),{x:0,y:0,width:spec.canvas.width,height:spec.canvas.height},`figure ${sheet.figure}`);for(const shape of spec.shapes){if((shape.type==="rect"||shape.type==="ellipse")&&(shape.label!==undefined||shape.labelRows!==undefined)){const inset=(shape.strokeWidth??2)/2;const single=await sceneSvg({...spec,shapes:[shape],edges:[]});inside(bounds(renderer(single)),{x:shape.x-inset,y:shape.y-inset,width:shape.width+inset*2,height:shape.height+inset*2},`shape ${shape.id} label`)}}const diagramBody=sourceSvg.replace(/^]*>/u,"").replace(/<\/svg>$/u,"");const x=geometry.body.x+(geometry.body.width-spec.canvas.width)/2;const counter=`${sheet.figure}/${source.sheets.length}`;const figureLabel=source.sheets.length===1?"":`FIG. ${sheet.figure}`;const page=`${counter}${diagramBody}${figureLabel}`;const outlined=renderer(page).toString().replace(/width="[^"]+" height="[^"]+" viewBox="[^"]+"/u,`width="${geometry.width}pt" height="${geometry.height}pt" viewBox="0 0 ${geometry.width} ${geometry.height}"`);if(Buffer.byteLength(outlined)>2*1024*1024)fail2("sheet SVG exceeds output byte limit");sheets.push({svg:outlined,width:geometry.width,height:geometry.height,figure:sheet.figure})}for(const character of"FIG0123456789")minGlyphHeightPt=Math.min(minGlyphHeightPt,glyphHeight(character,20,400));if(minGlyphHeightPt+0.001drawingSourceByteLimit)fail2("source exceeds 1MiB byte limit");const buffer=Buffer.alloc(drawingSourceByteLimit+1);let cursor=0;while(cursordrawingSourceByteLimit)fail2("source exceeds 1MiB byte limit");bytes=buffer.subarray(0,cursor)}finally{await descriptor.close()}const raw=JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(bytes));return{absolutePath,source:parseDrawingSource(raw),sourceSha256:sha256(bytes)}}async function checkDrawingFile(options){const{source,sourceSha256}=await readDrawingFile(options.filePath);return(await renderDrawing(source,sourceSha256)).checks}async function atomicWrite2(filePath,data){const temporary=`${filePath}.tmp-${process.pid}-${crypto.randomUUID()}`;try{await writeFile2(temporary,data);await rename2(temporary,filePath)}catch(error){await rm2(temporary,{force:true});throw error}}async function renderDrawingFile(options){const{absolutePath,source,sourceSha256}=await readDrawingFile(options.filePath);const result=await renderDrawing(source,sourceSha256);const outDirectory=resolve3(options.outDirectory??dirname3(absolutePath));const artifacts={source:absolutePath,pdf:join2(outDirectory,`${source.name}.pdf`),sheets:result.sheets.map((_,index)=>join2(outDirectory,`${source.name}.sheet-${String(index+1).padStart(3,"0")}.svg`)),receipt:join2(outDirectory,`${source.name}.drawing-receipt.json`)};const receipt={version:1,profile:drawingProfile,rendererVersion:SLOPCAMERA_VERSION,sourceSha256,paper:source.paper,minGlyphHeightPt:result.checks.minGlyphHeightPt,sheets:result.sheets.map((sheet)=>({figure:sheet.figure,widthPt:sheet.width,heightPt:sheet.height,sha256:sha256(sheet.svg)})),pdfSha256:sha256(result.pdf)};await mkdir2(outDirectory,{recursive:true});for(const[index,sheet]of result.sheets.entries())await atomicWrite2(artifacts.sheets[index],sheet.svg);await atomicWrite2(artifacts.pdf,result.pdf);await atomicWrite2(artifacts.receipt,`${JSON.stringify(receipt,null,2)} `);return{artifacts,checks:result.checks,receipt}}function starterDrawingSource(){return{$schema:"https://raw.githubusercontent.com/hraness/slopcamera/main/schema/drawing.schema.json",version:1,name:"sensor-control",title:"Fictional sensor and controller drawings",paper:"us-letter",sheets:[{figure:1,diagram:{version:1,name:"sensor-system",canvas:{width:480,height:500},shapes:[{id:"sensor",type:"rect",x:105,y:40,width:280,height:100,radius:0,label:"SENSOR 100",labelFontSize:16},{id:"controller",type:"rect",x:105,y:280,width:280,height:100,radius:0,label:"CONTROLLER 200",labelFontSize:16}],edges:[{id:"signal",from:"sensor",to:"controller",label:"SIGNAL",labelFontSize:16}]}},{figure:2,diagram:{version:1,name:"control-flow",canvas:{width:480,height:500},shapes:[{id:"receive",type:"rect",x:105,y:40,width:280,height:100,radius:0,label:"RECEIVE SIGNAL 210",labelFontSize:16},{id:"actuate",type:"rect",x:105,y:280,width:280,height:100,radius:0,label:"SET OUTPUT 220",labelFontSize:16}],edges:[{id:"next",from:"receive",to:"actuate"}]}}]}}import{rename as rename3,rm as rm3,writeFile as writeFile3}from"fs/promises";import{dirname as dirname5,join as join4}from"path";import{open as open2,mkdir as mkdir3,realpath,stat}from"fs/promises";import{basename as basename2,dirname as dirname4,isAbsolute as isAbsolute3,join as join3,relative,resolve as resolve4,win32}from"path";var mcpSourceByteLimit=1024*1024;class WorkspaceBoundaryError extends Error{code;constructor(code,message){super(message);this.name="WorkspaceBoundaryError";this.code=code}}function filesystemCode(error){if(typeof error==="object"&&error!==null&&"code"in error&&typeof error.code==="string"){return error.code}return}function normalizeRelativePath(value,options){if(value.length===0||value.includes("\x00")){throw new WorkspaceBoundaryError("INVALID_PATH","Path must be a non-empty root-relative path.")}if(isAbsolute3(value)||win32.isAbsolute(value)||/^[A-Za-z]:/.test(value)){throw new WorkspaceBoundaryError("INVALID_PATH","Absolute paths are not allowed.")}const segments=value.split(/[\\/]/).filter((segment)=>segment!==""&&segment!==".");if(segments.includes("..")){throw new WorkspaceBoundaryError("INVALID_PATH","Parent-directory traversal is not allowed.")}if(segments.length===0){if(!options.allowRoot){throw new WorkspaceBoundaryError("INVALID_PATH","Path must identify a file below the root.")}return{native:".",portable:"."}}return{native:segments.join("/"),portable:segments.join("/")}}function isConfined(rootDirectory,target){const fromRoot=relative(rootDirectory,target);return fromRoot===""||!fromRoot.startsWith("..")&&!isAbsolute3(fromRoot)}async function readUtf8WithCap(filePath,sourceLabel){let handle;try{handle=await open2(filePath,"r");const metadata=await handle.stat();if(!metadata.isFile()){throw new WorkspaceBoundaryError("SOURCE_NOT_FILE",`${sourceLabel} must be a regular file.`)}if(metadata.size>mcpSourceByteLimit){throw new WorkspaceBoundaryError("SOURCE_TOO_LARGE",`${sourceLabel} exceeds the ${mcpSourceByteLimit}-byte limit.`)}const buffer=Buffer.allocUnsafe(mcpSourceByteLimit+1);let bytesRead=0;while(bytesRead<=mcpSourceByteLimit){const next=await handle.read(buffer,bytesRead,mcpSourceByteLimit+1-bytesRead,null);if(next.bytesRead===0)break;bytesRead+=next.bytesRead}if(bytesRead>mcpSourceByteLimit){throw new WorkspaceBoundaryError("SOURCE_TOO_LARGE",`${sourceLabel} exceeds the ${mcpSourceByteLimit}-byte limit.`)}try{return new TextDecoder("utf-8",{fatal:true}).decode(buffer.subarray(0,bytesRead))}catch{throw new WorkspaceBoundaryError("SOURCE_ENCODING",`${sourceLabel} must contain valid UTF-8.`)}}catch(error){if(error instanceof WorkspaceBoundaryError)throw error;const code=filesystemCode(error);if(code==="ENOENT"){throw new WorkspaceBoundaryError("SOURCE_NOT_FOUND",`${sourceLabel} does not exist.`)}throw new WorkspaceBoundaryError("FILESYSTEM_ERROR",`${sourceLabel} could not be read.`)}finally{await handle?.close()}}class WorkspaceBoundary{rootDirectory;constructor(rootDirectory){this.rootDirectory=rootDirectory}static async create(rootDirectory){let resolvedRoot;try{resolvedRoot=await realpath(resolve4(rootDirectory));if(!(await stat(resolvedRoot)).isDirectory()){throw new WorkspaceBoundaryError("OUTPUT_NOT_DIRECTORY","MCP root must be a directory.")}}catch(error){if(error instanceof WorkspaceBoundaryError)throw error;throw new WorkspaceBoundaryError("FILESYSTEM_ERROR","MCP root could not be opened.")}return new WorkspaceBoundary(resolvedRoot)}assertConfined(target){if(!isConfined(this.rootDirectory,target)){throw new WorkspaceBoundaryError("PATH_OUTSIDE_ROOT","Path resolves outside the MCP root.")}}toRelativePath(absolutePath){this.assertConfined(absolutePath);const fromRoot=relative(this.rootDirectory,absolutePath);return fromRoot===""?".":fromRoot.split("\\").join("/")}async readSource(value,sourceLabel="Diagram source"){const normalized=normalizeRelativePath(value,{allowRoot:false});const lexicalPath=resolve4(this.rootDirectory,normalized.native);this.assertConfined(lexicalPath);let canonicalPath;try{canonicalPath=await realpath(lexicalPath)}catch(error){if(filesystemCode(error)==="ENOENT"){throw new WorkspaceBoundaryError("SOURCE_NOT_FOUND",`${sourceLabel} does not exist.`)}throw new WorkspaceBoundaryError("FILESYSTEM_ERROR",`${sourceLabel} could not be resolved.`)}this.assertConfined(canonicalPath);return{absolutePath:canonicalPath,relativePath:this.toRelativePath(canonicalPath),text:await readUtf8WithCap(canonicalPath,sourceLabel)}}async resolveInputFile(value,maximumBytes){const normalized=normalizeRelativePath(value,{allowRoot:false});const lexicalPath=resolve4(this.rootDirectory,normalized.native);this.assertConfined(lexicalPath);let canonicalPath;try{canonicalPath=await realpath(lexicalPath);this.assertConfined(canonicalPath);const metadata=await stat(canonicalPath);if(!metadata.isFile()){throw new WorkspaceBoundaryError("SOURCE_NOT_FILE","Input must be a regular file.")}if(!Number.isSafeInteger(maximumBytes)||maximumBytes<1||metadata.size>maximumBytes){throw new WorkspaceBoundaryError("SOURCE_TOO_LARGE",`Input exceeds the ${maximumBytes}-byte limit.`)}}catch(error){if(error instanceof WorkspaceBoundaryError)throw error;if(filesystemCode(error)==="ENOENT"){throw new WorkspaceBoundaryError("SOURCE_NOT_FOUND","Input does not exist.")}throw new WorkspaceBoundaryError("FILESYSTEM_ERROR","Input could not be resolved.")}return{absolutePath:canonicalPath,relativePath:this.toRelativePath(canonicalPath)}}async prepareOutputFile(value){const normalized=normalizeRelativePath(value,{allowRoot:false});const fileName=basename2(normalized.native);if(fileName==="."||fileName===".."||fileName.length===0){throw new WorkspaceBoundaryError("INVALID_PATH","Output path must identify a file below the root.")}const directory=await this.prepareOutputDirectory(dirname4(normalized.native));const absolutePath=join3(directory.absolutePath,fileName);this.assertConfined(absolutePath);return{absolutePath,relativePath:this.toRelativePath(absolutePath)}}async prepareOutputDirectory(value){const normalized=normalizeRelativePath(value,{allowRoot:true});const lexicalPath=resolve4(this.rootDirectory,normalized.native);this.assertConfined(lexicalPath);let ancestor=lexicalPath;for(;;){try{const canonicalAncestor=await realpath(ancestor);this.assertConfined(canonicalAncestor);break}catch(error){if(error instanceof WorkspaceBoundaryError)throw error;if(filesystemCode(error)!=="ENOENT"){throw new WorkspaceBoundaryError("FILESYSTEM_ERROR","Output directory could not be resolved.")}const parent=dirname4(ancestor);if(parent===ancestor){throw new WorkspaceBoundaryError("PATH_OUTSIDE_ROOT","Output directory resolves outside the MCP root.")}ancestor=parent}}try{await mkdir3(lexicalPath,{recursive:true});const canonicalPath=await realpath(lexicalPath);this.assertConfined(canonicalPath);if(!(await stat(canonicalPath)).isDirectory()){throw new WorkspaceBoundaryError("OUTPUT_NOT_DIRECTORY","Output path must be a directory.")}return{absolutePath:canonicalPath,relativePath:this.toRelativePath(canonicalPath)}}catch(error){if(error instanceof WorkspaceBoundaryError)throw error;throw new WorkspaceBoundaryError("FILESYSTEM_ERROR","Output directory could not be created.")}}}var mcpMaximumScale=4;var mcpMaximumRenderedPixels=16777216;var mcpMaximumShapes=64;var mcpMaximumEdges=128;var mcpMaximumReturnedFindings=40;var mcpMaximumReturnedEntities=256;var mcpMaximumReturnedAuditSamples=8192;var mcpMaximumReturnedDiffEntries=1024;var defaultScale=2;var maximumShapeIdsPerFinding=12;var builtInConfig=Object.freeze({icons:builtInIcons});var findingSchema={type:"object",additionalProperties:false,required:["code","message","shapeIds"],properties:{code:{type:"string"},message:{type:"string"},shapeIds:{type:"array",items:{type:"string"}}}};var scenePathSchema={type:"string",description:"Root-relative path to a spatial scene JSON source (1 MiB maximum)."};var sceneCameraIdSchema={type:"string",maxLength:128,pattern:"^camera_[a-zA-Z0-9][a-zA-Z0-9_-]*$",description:"Identifier of a camera declared by the scene (camera_\u2026)."};var entityTruncationSummarySchema={type:"object",additionalProperties:false,required:["entityCount","returnedEntityCount","entitiesTruncated"],properties:{entityCount:{type:"integer",minimum:0},returnedEntityCount:{type:"integer",minimum:0},entitiesTruncated:{type:"boolean"}}};function deepFreeze(value){if(typeof value!=="object"||value===null||Object.isFrozen(value)){return value}for(const nested of Object.values(value))deepFreeze(nested);return Object.freeze(value)}var slopcameraMcpTools=deepFreeze([{name:"check_diagram",title:"Check diagram",description:"Parse and lint one root-relative Slopcamera diagram source without changing files. Uses only built-in icons and themes.",inputSchema:{type:"object",additionalProperties:false,required:["path"],properties:{path:{type:"string",description:"Root-relative path to a diagram JSON source (1 MiB maximum)."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","findings","summary"],properties:{ok:{const:true},source:{type:"string"},findings:{type:"array",items:findingSchema},summary:{type:"object",additionalProperties:false,required:["shapeCount","edgeCount","findingCount","returnedFindingCount","findingsTruncated"],properties:{shapeCount:{type:"integer",minimum:0},edgeCount:{type:"integer",minimum:0},findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"}}}}},annotations:{title:"Check diagram",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"render_diagram",title:"Render diagram",description:"Render one root-relative Slopcamera diagram source with built-in icons and themes, overwriting its paired .tldr, light/dark SVG, and light/dark PNG artifacts.",inputSchema:{type:"object",additionalProperties:false,required:["path"],properties:{path:{type:"string",description:"Root-relative path to a diagram JSON source (1 MiB maximum)."},out_dir:{type:"string",description:"Optional root-relative output directory. Defaults to the source directory."},scale:{type:"number",exclusiveMinimum:0,maximum:mcpMaximumScale,default:defaultScale,description:"PNG scale. The scaled canvas may contain at most 16,777,216 pixels."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","scale","findings","artifacts","summary"],properties:{ok:{const:true},source:{type:"string"},scale:{type:"number"},findings:{type:"array",items:findingSchema},artifacts:{type:"object",additionalProperties:false,required:["tldr","lightSvg","darkSvg","lightPng","darkPng"],properties:{tldr:{type:"string"},lightSvg:{type:"string"},darkSvg:{type:"string"},lightPng:{type:"string"},darkPng:{type:"string"}}},summary:{type:"object",additionalProperties:false,required:["shapeCount","edgeCount","findingCount","returnedFindingCount","findingsTruncated"],properties:{shapeCount:{type:"integer",minimum:0},edgeCount:{type:"integer",minimum:0},findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"}}}}},annotations:{title:"Render diagram",readOnlyHint:false,destructiveHint:true,idempotentHint:true,openWorldHint:false}},{name:"search_slopcamera",title:"Search Slopcamera operations",description:"Search the fixed semantic Slopcamera operation registry by bounded text. This never executes code or changes files.",inputSchema:{type:"object",additionalProperties:false,properties:{query:{type:"string",maxLength:200,description:"Optional terms matched against operation codes and descriptions."},limit:{type:"integer",minimum:1,maximum:20,default:4}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","operations"],properties:{ok:{const:true},operations:{type:"array",maxItems:20,items:{type:"object",required:["code","title","description","execution","authentication","inputSchema"]}}}},annotations:{title:"Search Slopcamera operations",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"execute_slopcamera",title:"Execute Slopcamera operation",description:"Execute one exact operation code with typed JSON input. Never accepts or evaluates source code. Local paths remain confined to the configured workspace root.",inputSchema:{type:"object",additionalProperties:false,required:["operation","input"],properties:{operation:{type:"string",enum:slopcameraOperationCodes},input:{type:"object",description:"Typed input matching the selected operation's registry schema."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","operation","result"],properties:{ok:{const:true},operation:{type:"string",enum:slopcameraOperationCodes},result:{type:"object"}}},annotations:{title:"Execute Slopcamera operation",readOnlyHint:false,destructiveHint:true,idempotentHint:false,openWorldHint:true}},{name:"check_scene",title:"Check scene",description:"Parse and validate one root-relative Slopcamera spatial scene JSON source without changing files.",inputSchema:{type:"object",additionalProperties:false,required:["path"],properties:{path:scenePathSchema}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","sceneId","sceneSha256","summary"],properties:{ok:{const:true},source:{type:"string"},sceneId:{type:"string"},sceneSha256:{type:"string"},summary:{type:"object",additionalProperties:false,required:["durationUs","entityCount","cameraCount","assetCount","animationCount","generatorCount","overrideCount"],properties:{durationUs:{type:"integer",minimum:0},entityCount:{type:"integer",minimum:0},cameraCount:{type:"integer",minimum:0},assetCount:{type:"integer",minimum:0},animationCount:{type:"integer",minimum:0},generatorCount:{type:"integer",minimum:0},overrideCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"inspect_scene",title:"Inspect scene",description:"Snapshot one root-relative spatial scene's entities, editable controls, placements, assets, and generators without changing files.",inputSchema:{type:"object",additionalProperties:false,required:["path"],properties:{path:scenePathSchema}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","inspection","summary"],properties:{ok:{const:true},source:{type:"string"},inspection:{type:"object"},summary:entityTruncationSummarySchema}},annotations:{title:"Inspect scene",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"audit_scene",title:"Audit scene",description:"Sample one root-relative spatial scene against a camera and report per-entity geometric coverage, visibility findings, and bounds gaps. Optional asset_bounds accepts a Record map, a slopcamera.spatial-asset-admission document, a {manifest,facts} pair, or an array of those.",inputSchema:{type:"object",additionalProperties:false,required:["path","camera_id"],properties:{path:scenePathSchema,camera_id:sceneCameraIdSchema,times_us:{type:"array",items:{type:"integer",minimum:0,maximum:SPATIAL_SCENE_LIMITS.durationUs},minItems:1,maxItems:SPATIAL_AUDIT_LIMITS.samples,description:"Optional sample times in microseconds. Defaults to evenly spaced coverage of the scene duration."},asset_bounds:{description:"Optional decoded scene-space asset bounds: a Record map, a slopcamera.spatial-asset-admission document, a {manifest,facts} pair, or an array of those documents."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","report","summary"],properties:{ok:{const:true},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:false,required:["findingCount","returnedFindingCount","findingsTruncated","entityCount","returnedEntityCount","entitiesTruncated"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},entityCount:{type:"integer",minimum:0},returnedEntityCount:{type:"integer",minimum:0},entitiesTruncated:{type:"boolean"}}}}},annotations:{title:"Audit scene",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"diff_scenes",title:"Diff scenes",description:"Compare two root-relative spatial scene JSON sources and report added, removed, and changed collection entries without changing files.",inputSchema:{type:"object",additionalProperties:false,required:["path","other"],properties:{path:scenePathSchema,other:{type:"string",description:"Root-relative path to the second spatial scene JSON source (1 MiB maximum)."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","other","sceneSha256","otherSha256","diff","summary"],properties:{ok:{const:true},source:{type:"string"},other:{type:"string"},sceneSha256:{type:"string"},otherSha256:{type:"string"},diff:{type:"array"},summary:{type:"object",additionalProperties:false,required:["entryCount","returnedEntryCount","diffTruncated"],properties:{entryCount:{type:"integer",minimum:0},returnedEntryCount:{type:"integer",minimum:0},diffTruncated:{type:"boolean"}}}}},annotations:{title:"Diff scenes",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"evaluate_scene",title:"Evaluate scene",description:"Evaluate one root-relative spatial scene at one camera and integer microsecond time into an immutable snapshot without changing files.",inputSchema:{type:"object",additionalProperties:false,required:["path","camera_id","time_us"],properties:{path:scenePathSchema,camera_id:sceneCameraIdSchema,time_us:{type:"integer",minimum:0,maximum:SPATIAL_SCENE_LIMITS.durationUs,description:"Evaluation time in integer microseconds."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","snapshot","summary"],properties:{ok:{const:true},source:{type:"string"},snapshot:{type:"object"},summary:entityTruncationSummarySchema}},annotations:{title:"Evaluate scene",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"check_scene_direction",title:"Check scene direction",description:"Validate one authored direction document against one root-relative spatial scene: stale project digests, unresolved entity references, and intervals outside scene duration report as errors without compiling or changing files.",inputSchema:{type:"object",additionalProperties:false,required:["scene","direction"],properties:{scene:{...scenePathSchema,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},direction:{type:"string",description:"Root-relative path to the slopcamera.spatial-direction JSON document."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","report","summary"],properties:{ok:{const:true},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:false,required:["findingCount","returnedFindingCount","findingsTruncated","errorCount","warningCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},errorCount:{type:"integer",minimum:0},warningCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene direction",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"plan_scene_direction",title:"Plan scene direction",description:"Compile one authored direction document into a deterministic, unverified proposal document \u2014 performance actions, camera rigs, shots and looks bound to the actual scene digest. Proposals are advisory only; nothing is applied to the scene.",inputSchema:{type:"object",additionalProperties:false,required:["scene","direction"],properties:{scene:{...scenePathSchema,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},direction:{type:"string",description:"Root-relative path to the slopcamera.spatial-direction JSON document."},camera_id:{...sceneCameraIdSchema,description:"Optional camera used to resolve coverage; defaults to the sole or first sorted scene camera."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","compilation","summary"],properties:{ok:{const:true},source:{type:"string"},compilation:{type:"object"},summary:{type:"object",additionalProperties:false,required:["advisoryCount","unresolvedIntentCount","proposalCounts"],properties:{advisoryCount:{type:"integer",minimum:0},unresolvedIntentCount:{type:"integer",minimum:0},proposalCounts:{type:"object",additionalProperties:false,required:["performance","cameraRigs","shots","lookIntents"],properties:{performance:{type:"integer",minimum:0},cameraRigs:{type:"integer",minimum:0},shots:{type:"integer",minimum:0},lookIntents:{type:"integer",minimum:0}}}}}}},annotations:{title:"Plan scene direction",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"plan_scene_gallery",title:"Plan scene gallery",description:"Compile a bounded set of single-axis direction variants into separate content-addressed candidate compilations plus a preview-reel plan. The planner never selects or promotes a candidate.",inputSchema:{type:"object",additionalProperties:false,required:["scene","direction","axis"],properties:{scene:{...scenePathSchema,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},direction:{type:"string",description:"Root-relative path to the slopcamera.spatial-direction JSON document."},axis:{type:"string",enum:[...SpatialGalleryAxisSchema.options],description:"Variation axis for the bounded candidate set."},camera_id:{...sceneCameraIdSchema,description:"Optional camera used to resolve coverage."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","gallery","summary"],properties:{ok:{const:true},source:{type:"string"},gallery:{type:"object"},summary:{type:"object",additionalProperties:false,required:["axis","candidateCount","selected"],properties:{axis:{type:"string"},candidateCount:{type:"integer",minimum:0},selected:{const:false}}}}},annotations:{title:"Plan scene gallery",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"check_scene_effects",title:"Check scene effects",description:"Validate one slopcamera.spatial-render-effects document or {document, documentSha256} binding against one scene: scene-digest bindings, entity and asset closure, and nested plan/particle/simulation digests report as findings before any host work.",inputSchema:{type:"object",additionalProperties:false,required:["scene","effects"],properties:{scene:{...scenePathSchema,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},effects:{type:"string",description:"Root-relative path to the render-effects document or binding JSON."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","report","summary"],properties:{ok:{const:true},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:false,required:["findingCount","returnedFindingCount","findingsTruncated","errorCount","warningCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},errorCount:{type:"integer",minimum:0},warningCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene effects",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"plan_scene_effects",title:"Plan scene effects",description:"Assemble a canonical {document, documentSha256} render-effects binding for one scene from a draft JSON naming renderPlan, particleSystems and simulationBakes. Entity and asset closure rejects before the document is formed; the scene digest binds here, never by caller assertion.",inputSchema:{type:"object",additionalProperties:false,required:["scene","draft"],properties:{scene:{...scenePathSchema,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},draft:{type:"string",description:"Root-relative path to the effects draft JSON ({renderPlan, particleSystems?, simulationBakes?})."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","binding","summary"],properties:{ok:{const:true},source:{type:"string"},binding:{type:"object"},summary:{type:"object",additionalProperties:false,required:["documentSha256","particleSystemCount","simulationBakeCount"],properties:{documentSha256:{type:"string"},particleSystemCount:{type:"integer",minimum:0},simulationBakeCount:{type:"integer",minimum:0}}}}},annotations:{title:"Plan scene effects",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"check_scene_behavior",title:"Check scene behavior",description:"Validate one slopcamera.spatial-behavior document against one scene: bake-safe organism profile (input/const/fn/repeat/each/organism cells only), manifest-closure digests, entity and scene-digest bindings, channel declarations, fn-catalog resolution, wiring, and budget bounds report as findings before any host work.",inputSchema:{type:"object",additionalProperties:false,required:["scene","behavior"],properties:{scene:{...scenePathSchema,description:"Root-relative path to the spatial scene JSON source (1 MiB maximum)."},behavior:{type:"string",description:"Root-relative path to the spatial behavior document JSON."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","report","summary"],properties:{ok:{const:true},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:false,required:["findingCount","returnedFindingCount","findingsTruncated","errorCount","warningCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},errorCount:{type:"integer",minimum:0},warningCount:{type:"integer",minimum:0}}}}},annotations:{title:"Check scene behavior",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"audit_scene_behavior",title:"Audit scene behavior trace",description:"Analyze a baked behavior trace for pathological patterns: state thrash (rapid transitions), exact periodicity (trivially cyclic channels), dead channels (constant-valued), and unreachable states (declared in transitions but never visited). Advisory findings for gallery review \u2014 never selects or promotes.",inputSchema:{type:"object",additionalProperties:false,required:["bake"],properties:{bake:{type:"string",description:"Root-relative path to the behavior bake JSON (slopcamera.spatial-behavior-bake)."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","report","summary"],properties:{ok:{const:true},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:false,required:["findingCount","channelCount","emittedCount"],properties:{findingCount:{type:"integer",minimum:0},channelCount:{type:"integer",minimum:0},emittedCount:{type:"integer",minimum:0}}}}},annotations:{title:"Audit scene behavior trace",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}},{name:"audit_scene_temporal",title:"Audit scene temporal evidence",description:"Evaluate one root-relative spatial scene at bounded sample times under one camera and report deterministic temporal findings: visibility flicker, transform discontinuity, foot-slide against declared contact windows, camera acceleration/jerk/angular velocity, exposure and focus jumps, and resource spikes.",inputSchema:{type:"object",additionalProperties:false,required:["path","camera_id"],properties:{path:scenePathSchema,camera_id:sceneCameraIdSchema,times_us:{type:"array",items:{type:"integer",minimum:0,maximum:SPATIAL_SCENE_LIMITS.durationUs},minItems:2,maxItems:SPATIAL_TEMPORAL_AUDIT_LIMITS.samples,description:"Optional sample times in microseconds (2\u2013256). Defaults to evenly spaced coverage of the scene duration."},contacts:{type:"string",description:"Optional root-relative path to a {contacts: [...]} ground-contact evidence JSON."},cut_before_us:{type:"array",items:{type:"integer",minimum:0,maximum:SPATIAL_SCENE_LIMITS.durationUs},maxItems:SPATIAL_TEMPORAL_AUDIT_LIMITS.cutBoundaries,description:"Optional intentional cut boundaries; discontinuities exactly at a cut are not findings."}}},outputSchema:{type:"object",additionalProperties:false,required:["ok","source","report","summary"],properties:{ok:{const:true},source:{type:"string"},report:{type:"object"},summary:{type:"object",additionalProperties:false,required:["findingCount","returnedFindingCount","findingsTruncated","sampleCount"],properties:{findingCount:{type:"integer",minimum:0},returnedFindingCount:{type:"integer",minimum:0},findingsTruncated:{type:"boolean"},sampleCount:{type:"integer",minimum:2}}}}},annotations:{title:"Audit scene temporal evidence",readOnlyHint:true,destructiveHint:false,idempotentHint:true,openWorldHint:false}}]);class ToolFailure extends Error{code;issues;constructor(code,message,issues){super(message);this.name="ToolFailure";this.code=code;if(issues!==undefined)this.issues=issues}}function isRecord2(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function safeFragment(value,maximumLength=160){return value.replace(/[\u0000-\u001f\u007f]/g," ").replace(/\s+/g," ").trim().slice(0,maximumLength)}function safeIssues(issues){return issues.slice(0,24).map((issue)=>safeFragment(issue,240))}function rejectUnknownKeys(value,allowed){const unknown=Object.keys(value).filter((key)=>!allowed.has(key));if(unknown.length>0){throw new ToolFailure("INVALID_ARGUMENTS",`Unsupported argument: ${safeFragment(unknown[0]??"unknown")}.`)}}function parsePath(value){if(typeof value!=="string"||value.length===0){throw new ToolFailure("INVALID_ARGUMENTS","path must be a non-empty root-relative string.")}if(!value.toLowerCase().endsWith(".diagram.json")){throw new ToolFailure("INVALID_ARGUMENTS","path must end in .diagram.json.")}return value}function parseCheckArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["path"]));return{path:parsePath(value.path)}}function parseRenderArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["path","out_dir","scale"]));const outDirectory=value.out_dir;if(outDirectory!==undefined&&(typeof outDirectory!=="string"||outDirectory.length===0)){throw new ToolFailure("INVALID_ARGUMENTS","out_dir must be a non-empty root-relative string when present.")}const scale=value.scale??defaultScale;if(typeof scale!=="number"||!Number.isFinite(scale)||scale<=0||scale>mcpMaximumScale){throw new ToolFailure("RENDER_LIMIT",`scale must be greater than zero and no more than ${mcpMaximumScale}.`)}return{path:parsePath(value.path),...outDirectory===undefined?{}:{outDirectory},scale}}function parseSearchArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["query","limit"]));const query=value.query??"";const limit=value.limit??slopcameraOperationCodes.length;if(typeof query!=="string"||query.length>200||/[\u0000-\u001f\u007f]/u.test(query)||!Number.isInteger(limit)||limit<1||limit>20){throw new ToolFailure("INVALID_ARGUMENTS","query must be a bounded string and limit must be an integer from 1 through 20.")}return{query,limit}}function parseExecuteArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["operation","input"]));if(typeof value.operation!=="string"||!slopcameraOperationCodes.includes(value.operation)||!isRecord2(value.input)){throw new ToolFailure("INVALID_ARGUMENTS","operation must be an exact Slopcamera operation code and input must be an object.")}return{operation:value.operation,input:value.input}}var sceneCameraIdPattern=/^camera_[a-zA-Z0-9][a-zA-Z0-9_-]*$/u;function parseScenePath(value,label){if(typeof value!=="string"||value.length===0){throw new ToolFailure("INVALID_ARGUMENTS",`${label} must be a non-empty root-relative string.`)}if(!value.toLowerCase().endsWith(".json")){throw new ToolFailure("INVALID_ARGUMENTS",`${label} must end in .json.`)}return value}function parseSceneCameraId(value){if(typeof value!=="string"||value.length>128||!sceneCameraIdPattern.test(value)){throw new ToolFailure("INVALID_ARGUMENTS","camera_id must be a scene camera identifier (camera_ followed by letters, digits, _ or -).")}return value}function parseSceneSourceArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["path"]));return{path:parseScenePath(value.path,"path")}}function parseAuditSceneArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["path","camera_id","times_us","asset_bounds"]));let timesUs;if(value.times_us!==undefined){if(!Array.isArray(value.times_us)||value.times_us.length===0||value.times_us.length>SPATIAL_AUDIT_LIMITS.samples||value.times_us.some((timeUs)=>!Number.isSafeInteger(timeUs)||timeUs<0||timeUs>SPATIAL_SCENE_LIMITS.durationUs)){throw new ToolFailure("INVALID_ARGUMENTS",`times_us must be an array of 1\u2013${SPATIAL_AUDIT_LIMITS.samples} integer microsecond times within the scene duration bound.`)}timesUs=[...value.times_us]}return{path:parseScenePath(value.path,"path"),cameraId:parseSceneCameraId(value.camera_id),...timesUs===undefined?{}:{timesUs},..."asset_bounds"in value?{assetBounds:value.asset_bounds}:{}}}function parseDiffScenesArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["path","other"]));return{path:parseScenePath(value.path,"path"),other:parseScenePath(value.other,"other")}}function parseEvaluateSceneArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["path","camera_id","time_us"]));const timeUs=value.time_us;if(typeof timeUs!=="number"||!Number.isSafeInteger(timeUs)||timeUs<0||timeUs>SPATIAL_SCENE_LIMITS.durationUs){throw new ToolFailure("INVALID_ARGUMENTS",`time_us must be an integer microsecond time from 0 through ${SPATIAL_SCENE_LIMITS.durationUs}.`)}return{path:parseScenePath(value.path,"path"),cameraId:parseSceneCameraId(value.camera_id),timeUs}}function parseSceneDirectionArguments(value,requireAxis){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["scene","direction","camera_id","axis"]));if(requireAxis&&!SpatialGalleryAxisSchema.safeParse(value.axis).success){throw new ToolFailure("INVALID_ARGUMENTS",`axis must be one of ${SpatialGalleryAxisSchema.options.join(", ")}.`)}if(!requireAxis&&value.axis!==undefined){throw new ToolFailure("INVALID_ARGUMENTS","axis is only valid for plan_scene_gallery.")}return{scene:parseScenePath(value.scene,"scene"),direction:parseScenePath(value.direction,"direction"),...value.camera_id===undefined?{}:{cameraId:parseSceneCameraId(value.camera_id)},...value.axis===undefined?{}:{axis:value.axis}}}function parseSceneEffectsArguments(value,effectsKey){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["scene",effectsKey]));return{scene:parseScenePath(value.scene,"scene"),effects:parseScenePath(value[effectsKey],effectsKey)}}function parseSceneBehaviorArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["scene","behavior"]));return{scene:parseScenePath(value.scene,"scene"),behavior:parseScenePath(value.behavior,"behavior")}}function parseSceneBehaviorAuditArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["bake"]));return{bake:parseScenePath(value.bake,"bake")}}function parseSceneTemporalArguments(value){if(!isRecord2(value)){throw new ToolFailure("INVALID_ARGUMENTS","Tool arguments must be an object.")}rejectUnknownKeys(value,new Set(["path","camera_id","times_us","contacts","cut_before_us"]));const boundedTimes=(key,maximum)=>{const entries=value[key];if(entries===undefined)return;if(!Array.isArray(entries)||entries.length===0||entries.length>maximum||entries.some((timeUs)=>!Number.isSafeInteger(timeUs)||timeUs<0||timeUs>SPATIAL_SCENE_LIMITS.durationUs)){throw new ToolFailure("INVALID_ARGUMENTS",`${key} must be an array of 1\u2013${maximum} integer microsecond times within the scene duration bound.`)}return[...entries]};const timesUs=boundedTimes("times_us",SPATIAL_TEMPORAL_AUDIT_LIMITS.samples);const cutBeforeUs=boundedTimes("cut_before_us",SPATIAL_TEMPORAL_AUDIT_LIMITS.cutBoundaries);if(timesUs!==undefined&×Us.length<2){throw new ToolFailure("INVALID_ARGUMENTS","times_us must contain at least 2 sample times.")}return{path:parseScenePath(value.path,"path"),cameraId:parseSceneCameraId(value.camera_id),...timesUs===undefined?{}:{timesUs},...value.contacts===undefined?{}:{contacts:parseScenePath(value.contacts,"contacts")},...cutBeforeUs===undefined?{}:{cutBeforeUs}}}function assertBuiltInIcons(spec){for(const shape of spec.shapes){if((shape.type==="rect"||shape.type==="ellipse")&&shape.icon!==undefined&&!Object.hasOwn(builtInIcons,shape.icon)){throw new ToolFailure("UNKNOWN_ICON",`Shape ${safeFragment(shape.id)} requests unavailable built-in icon ${safeFragment(shape.icon)}.`)}}}function assertComplexityLimits(spec){const edgeCount=spec.edges?.length??0;if(spec.shapes.length>mcpMaximumShapes||edgeCount>mcpMaximumEdges){throw new ToolFailure("COMPLEXITY_LIMIT",`Diagram may contain at most ${mcpMaximumShapes} shapes and ${mcpMaximumEdges} edges in MCP mode.`)}}function assertRawComplexityLimits(value){if(!isRecord2(value))return;const shapeCount=Array.isArray(value.shapes)?value.shapes.length:0;const edgeCount=Array.isArray(value.edges)?value.edges.length:0;if(shapeCount>mcpMaximumShapes||edgeCount>mcpMaximumEdges){throw new ToolFailure("COMPLEXITY_LIMIT",`Diagram may contain at most ${mcpMaximumShapes} shapes and ${mcpMaximumEdges} edges in MCP mode.`)}}function assertRenderLimits(spec,scale){const scaledWidth=spec.canvas.width*scale;const scaledHeight=spec.canvas.height*scale;const pixels=Math.ceil(scaledWidth)*Math.ceil(scaledHeight);if(!Number.isFinite(pixels)||scaledWidth<1||scaledHeight<1||pixels>mcpMaximumRenderedPixels){throw new ToolFailure("RENDER_LIMIT",`Scaled canvas must be at least 1 pixel on each axis and no more than ${mcpMaximumRenderedPixels.toLocaleString("en-US")} pixels total.`)}}function boundedSlice(items,maximum){return items.length>maximum?items.slice(0,maximum):items}function publicFinding(finding){return{code:safeFragment(finding.code,64),message:safeFragment(finding.message,240),shapeIds:finding.shapeIds.slice(0,maximumShapeIdsPerFinding).map((shapeId)=>safeFragment(shapeId,120))}}function publicFindings(findings){return findings.slice(0,mcpMaximumReturnedFindings).map(publicFinding)}function diagramSummary(spec,findingCount,returnedFindingCount){return{shapeCount:spec.shapes.length,edgeCount:spec.edges?.length??0,findingCount,returnedFindingCount,findingsTruncated:returnedFindingCounttypeof issue==="string")){code="INVALID_LAYOUT";message="Diagram layout could not be resolved.";issues=safeIssues(error.issues)}const issueText=issues===undefined||issues.length===0?"":` ${issues.map((issue)=>`- ${issue}`).join(` `)}`;return{content:[{type:"text",text:`[${code}] ${message}${issueText}`}],isError:true}}function portableDirectory(filePath){const separator=filePath.lastIndexOf("/");return separator===-1?".":filePath.slice(0,separator)}async function atomicOverwrite(filePath,data){const temporaryPath=join4(dirname5(filePath),`.${crypto.randomUUID()}.slopcamera-mcp.tmp`);try{await writeFile3(temporaryPath,data,{flag:"wx"});try{await rename3(temporaryPath,filePath)}catch(error){const code=typeof error==="object"&&error!==null&&"code"in error&&typeof error.code==="string"?error.code:undefined;if(code!=="EEXIST"&&code!=="EPERM")throw error;await rm3(filePath,{force:true});await rename3(temporaryPath,filePath)}}finally{await rm3(temporaryPath,{force:true})}}async function loadDiagram(boundary,path){const source=await boundary.readSource(path);let parsed;try{parsed=JSON.parse(source.text)}catch{throw new ToolFailure("INVALID_JSON","Diagram source is not valid JSON.")}assertRawComplexityLimits(parsed);const spec=parseDiagramSpec(parsed);assertComplexityLimits(spec);assertBuiltInIcons(spec);return{source,spec}}async function loadScene(boundary,path){const source=await boundary.readSource(path,"Scene source");const parsed=parseJsonText(source.text);try{return{source,scene:parseSpatialScene(parsed)}}catch(error){if(error instanceof SpatialSceneError){const where=error.path==="scene"?"":` at ${error.path}`;throw new ToolFailure("INVALID_SCENE",`Scene source did not pass validation${where}: ${safeFragment(error.message,240)}`)}throw error}}function parseJsonText(text){try{return JSON.parse(text)}catch{throw new ToolFailure("INVALID_JSON","Source is not valid JSON.")}}async function loadJson(boundary,path,label){const source=await boundary.readSource(path,label);return{source,value:parseJsonText(source.text)}}class SlopcameraMcpToolRuntime{boundary;generateDependencies;hostResourceCoordinator;renderQueue=Promise.resolve();constructor(boundary,generateDependencies,hostResourceCoordinator){this.boundary=boundary;this.generateDependencies=generateDependencies;this.hostResourceCoordinator=hostResourceCoordinator}static async create(rootDirectory,generateDependencies={},hostResourceCoordinator){return new SlopcameraMcpToolRuntime(await WorkspaceBoundary.create(rootDirectory),generateDependencies,hostResourceCoordinator??createDefaultHostResourceCoordinator())}async withHostAdmission(operation,callback){return await withSlopcameraOperationHostAdmission(operation,callback,{hostResourceCoordinator:this.hostResourceCoordinator})}async withSceneAdmission(callback){return await this.hostResourceCoordinator.withLease([{resource:"cpu",amount:1},{resource:"local-io",amount:1}],async(lease)=>{await lease.assertOwned();return await callback(lease)})}enqueueRender(operation){const result=this.renderQueue.then(operation,operation);this.renderQueue=result.then(()=>{return},()=>{return});return result}async call(name,argumentsValue){try{if(name==="check_diagram"){const options=parseCheckArguments(argumentsValue);return await this.withHostAdmission("slopcamera.diagram.check",async()=>await this.check(options))}if(name==="render_diagram"){const options=parseRenderArguments(argumentsValue);return await this.enqueueRender(async()=>await this.withHostAdmission("slopcamera.diagram.render",async()=>await this.render(options)))}if(name==="search_slopcamera"){const options=parseSearchArguments(argumentsValue);const operations=searchSlopcameraOperations(options.query,options.limit);return successResult(`Found ${operations.length} Slopcamera operation${operations.length===1?"":"s"}.`,{ok:true,operations})}if(name==="execute_slopcamera"){const options=parseExecuteArguments(argumentsValue);return await this.execute(options)}if(name==="check_scene"){const options=parseSceneSourceArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.checkScene(options))}if(name==="inspect_scene"){const options=parseSceneSourceArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.inspectScene(options))}if(name==="audit_scene"){const options=parseAuditSceneArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.auditScene(options))}if(name==="diff_scenes"){const options=parseDiffScenesArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.diffScenes(options))}if(name==="evaluate_scene"){const options=parseEvaluateSceneArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.evaluateScene(options))}if(name==="check_scene_direction"){const options=parseSceneDirectionArguments(argumentsValue,false);return await this.withSceneAdmission(async()=>await this.checkSceneDirection(options))}if(name==="plan_scene_direction"){const options=parseSceneDirectionArguments(argumentsValue,false);return await this.withSceneAdmission(async()=>await this.planSceneDirection(options))}if(name==="plan_scene_gallery"){const options=parseSceneDirectionArguments(argumentsValue,true);return await this.withSceneAdmission(async()=>await this.planSceneGallery(options))}if(name==="check_scene_effects"){const options=parseSceneEffectsArguments(argumentsValue,"effects");return await this.withSceneAdmission(async()=>await this.checkSceneEffects(options))}if(name==="plan_scene_effects"){const options=parseSceneEffectsArguments(argumentsValue,"draft");return await this.withSceneAdmission(async()=>await this.planSceneEffects(options))}if(name==="check_scene_behavior"){const options=parseSceneBehaviorArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.checkSceneBehavior(options))}if(name==="audit_scene_behavior"){const options=parseSceneBehaviorAuditArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.auditSceneBehavior(options))}if(name==="audit_scene_temporal"){const options=parseSceneTemporalArguments(argumentsValue);return await this.withSceneAdmission(async()=>await this.auditSceneTemporal(options))}throw new ToolFailure("UNKNOWN_TOOL","Requested tool is not available.")}catch(error){return failureResult(error)}}wrapSemanticResult(operation,result){if(result.isError===true)return result;return{content:result.content,structuredContent:{ok:true,operation,result:result.structuredContent??{}}}}async execute(options){if(options.operation==="slopcamera.diagram.check"){const input=parseSlopcameraOperationInput(options.operation,options.input);return this.wrapSemanticResult(options.operation,await this.withHostAdmission(options.operation,async()=>await this.check({path:input.path})))}if(options.operation==="slopcamera.diagram.render"){const input=parseSlopcameraOperationInput(options.operation,options.input);return this.enqueueRender(async()=>await this.withHostAdmission(options.operation,async()=>this.wrapSemanticResult(options.operation,await this.render({path:input.path,...input.outDirectory===undefined?{}:{outDirectory:input.outDirectory},scale:input.scale??defaultScale}))))}if(options.operation==="slopcamera.image.vectorize"){const input=parseSlopcameraOperationInput(options.operation,options.input);return this.enqueueRender(async()=>await this.withHostAdmission(options.operation,async(lease)=>{const source=await this.boundary.resolveInputFile(input.inputPath,vectorizeHardLimits.maxInputBytes);const output=await this.boundary.prepareOutputFile(input.outputPath);const result=await vectorizeImage(source.absolutePath,{outputPath:output.absolutePath,...input.duotone===undefined?{}:{duotone:input.duotone},...input.alphaCutoff===undefined?{}:{alphaCutoff:input.alphaCutoff},...input.timeoutMs===undefined?{}:{limits:{maxDurationMs:input.timeoutMs}},inheritedFileDescriptors:[lease.inheritedFileDescriptor]});return successResult(`Executed ${options.operation}: ${output.relativePath}`,{ok:true,operation:options.operation,result:{inputPath:source.relativePath,outputPath:output.relativePath,receipt:result.receipt}})}))}if(options.operation==="slopcamera.image.gallery"){const input=parseSlopcameraOperationInput(options.operation,options.input);return await this.withHostAdmission(options.operation,async()=>{const output=await this.boundary.prepareOutputDirectory(input.outputDir);const receipt=await generateSlopcameraImageGallery({...input,outputDir:output.absolutePath},this.generateDependencies);return successResult(`Executed ${options.operation}: ${receipt.counts.generated}/${receipt.counts.requested} candidates in ${output.relativePath}.`,{ok:true,operation:options.operation,result:{...receipt,outputDir:output.relativePath}})})}return await this.withHostAdmission(options.operation,async()=>{const input=parseSlopcameraOperationInput(options.operation,options.input);const output=await this.boundary.prepareOutputFile(input.outputPath);const generated=await generateSlopcameraImageFile({...input,outputPath:output.absolutePath},this.generateDependencies);return successResult(`Executed ${options.operation}: ${output.relativePath} (request ${safeFragment(generated.requestId,256)}).`,{ok:true,operation:options.operation,result:{bytes:generated.bytes,mediaType:generated.mediaType,model:generated.model,outputPath:output.relativePath,provider:generated.provider,requestId:generated.requestId,sha256:generated.sha256,warnings:generated.warnings}})})}async check(options){const{source,spec}=await loadDiagram(this.boundary,options.path);const allFindings=lintDiagram(spec);const findings=publicFindings(allFindings);const summary=diagramSummary(spec,allFindings.length,findings.length);const text=allFindings.length===0?`Checked ${source.relativePath}: no findings.`:`Checked ${source.relativePath}: ${allFindings.length} finding${allFindings.length===1?"":"s"}; ${findings.length} returned in structured content${findings.length`- ${artifact}`)].join(` diff --git a/dist/index.js b/dist/index.js index 504a7151..e28f92f8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,2 +1,2 @@ // @bun -import{DrawingValidationError,SLOPCAMERA_CAPABILITY_MANIFEST_LIMITS,SLOPCAMERA_PORTABLE_CAPABILITY_VERSION,SLOPCAMERA_VERSION,STUDIO_LIMITS,SlopcameraCapabilityCommandSchema,SlopcameraCapabilityEffectSchema,SlopcameraCapabilityManifestSchema,SlopcameraCapabilityModuleDeclarationSchema,SlopcameraCapabilityModuleSchema,SlopcameraCapabilityOperationSchema,SlopcameraCapabilityPreparationSchema,SlopcameraCapabilityProfileSchema,SlopcameraCapabilityQualificationSchema,SlopcameraCapabilityResourceSchema,SlopcameraCapabilityResumeSchema,SlopcameraCapabilityToolSchema,SlopcameraCapabilityWorkflowSchema,SlopcameraMcpToolRuntime,SlopcameraSceneVariantsSchema,StudioCapabilityNameSchema,StudioDigestSchema,StudioEngineOptionsSchema,StudioEngineSchema,StudioExecutionProfileSchema,StudioJobSchema,StudioOutputArtifactSchema,StudioOutputFormatSchema,StudioOutputInterpretationSchema,StudioOutputRoleSchema,StudioOutputSpecSchema,StudioPathSchema,StudioPlanSchema,StudioReceiptSchema,StudioRenderSchema,StudioRuntimeIdentitySchema,StudioSourceBundleSchema,StudioSourceSpaceSchema,VISUAL_STYLE_IDS,VISUAL_STYLE_PROFILES,VISUAL_STYLE_VARIATION_ALGORITHM,VisualStyleIdSchema,VisualStyleProfileSchema,WorkspaceBoundary,WorkspaceBoundaryError,artifactSummary,checkDiagramFile,checkDrawingFile,compileSlopcameraCapabilityManifest,createPortableSlopcameraCapabilityManifest,createVisualStyleDirection,defineSlopcameraCapabilityModule,diagramApi,drawingMinimumGlyphHeightPt,drawingPageGeometry,drawingProfile,drawingSourceByteLimit,getVisualStyleProfile,inspectStudioBundle,inspectStudioPlan,mcpMaximumRenderedPixels,mcpMaximumScale,mcpSourceByteLimit,parseDrawingSource,parseSlopcameraCapabilityManifest,parseSlopcameraSceneVariants,parseStudioJob,parseStudioPlan,parseStudioReceipt,parseStudioRuntimeIdentity,parseStudioSourceBundle,planSlopcameraSceneGallery,planStudioJob,readDiagramFile,readDrawingFile,renderDiagramFile,renderDrawing,renderDrawingFile,runMcpServer,sampleVisualStyleExposure,slopcameraApi,slopcameraMcpProtocolVersion,slopcameraMcpServerName,slopcameraMcpTools,slopcameraPortableCapabilityManifest,slopcameraSceneGalleryLimits,starterDrawingSource,studioJobSha256,studioOutputPath,studioRuntimeSha256,studioSourceBundleSha256,summarizeSceneVariantPatch,validateStudioReceipt,visualStyleFrameVariation}from"./index-z2xp9jaq.js";import{bundledSkillPath,installSkill}from"./index-grk47tgs.js";import"./index-z1kd1x8j.js";import"./index-3cxf2c58.js";import{SlopcameraWorkflowError,defineSlopcameraWorkflow,runSlopcameraWorkflow}from"./index-4z9y2wa2.js";import{DiagramValidationError,SlopcameraOperationError,StackLayoutError,builtInIcons,composeSlopcameraImageGallery,critiqueIconRaster,executeSlopcameraOperation,executeSlopcameraOperationWithLease,extractIconLineArt,galleryCandidateId,galleryPromptFor,generateSlopcameraIcon,generateSlopcameraImageGallery,iconPromptFor,iconVisualGateProblems,isSlopcameraOperationCode,lintDiagram,parseDiagramSource,parseDiagramSpec,parseSlopcameraGalleryVary,parseSlopcameraOperationInput,planSlopcameraGallery,renderPng,renderSvg,resolveDiagramSource,resolveEdge,resolveStackLayout,searchSlopcameraOperations,serializeTldr,slopcameraGalleryAxes,slopcameraGalleryKinds,slopcameraGalleryLimits,slopcameraIconCritiqueDefaultModel,slopcameraIconCritiqueTimeoutMs,slopcameraIconDefaultInk,slopcameraIconDefaultRounds,slopcameraIconMaximumRounds,slopcameraIconPanel,slopcameraIconSubjectMaximumBytes,slopcameraOperationCodes,slopcameraOperationHostResourceClaims,slopcameraOperationRegistry,stackLayoutDefaults,withSlopcameraOperationHostAdmission}from"./index-fevf4ppk.js";import{VTRACER_VERSION,VectorizeError,vectorizeDefaultLimits,vectorizeHardLimits,vectorizeImage,vectorizeProfileNames,vtracerReleases}from"./index-mnp0bftq.js";import{SlopcameraCloudError,createFixedGatewayFetch,generateSlopcameraImage,generateSlopcameraImageFile,resolveSlopcameraGatewayCredential,slopcameraGatewayApiBaseUrl,slopcameraGatewayCredentialStatus,slopcameraImageModels,slopcameraMaximumPromptBytes,slopcameraMaximumRawImageBytes,slopcameraResponseMediaTypes}from"./index-nxtmy18t.js";import{HOST_RESOURCE_MAX_WAIT_MILLISECONDS,HostResourceError,createDefaultHostResourceCoordinator,createHostResourceCoordinator,createProcessLocalHostResourceCoordinator,defaultSlopcameraHostResourceProfile,defaultSlopcameraHostResourceStateRoot,normalizeHostResourceClaims,normalizeHostResourceProfile,slopcameraHostResourceNames}from"./index-b3geqczn.js";import"./index-80a36bc0.js";export{withSlopcameraOperationHostAdmission,vtracerReleases,visualStyleFrameVariation,vectorizeProfileNames,vectorizeImage,vectorizeHardLimits,vectorizeDefaultLimits,validateStudioReceipt,summarizeSceneVariantPatch,studioSourceBundleSha256,studioRuntimeSha256,studioOutputPath,studioJobSha256,starterDrawingSource,stackLayoutDefaults,slopcameraSceneGalleryLimits,slopcameraResponseMediaTypes,slopcameraPortableCapabilityManifest,slopcameraOperationRegistry,slopcameraOperationHostResourceClaims,slopcameraOperationCodes,slopcameraMcpTools,slopcameraMcpServerName,slopcameraMcpProtocolVersion,slopcameraMaximumRawImageBytes,slopcameraMaximumPromptBytes,slopcameraImageModels,slopcameraIconSubjectMaximumBytes,slopcameraIconPanel,slopcameraIconMaximumRounds,slopcameraIconDefaultRounds,slopcameraIconDefaultInk,slopcameraIconCritiqueTimeoutMs,slopcameraIconCritiqueDefaultModel,slopcameraHostResourceNames,slopcameraGatewayCredentialStatus,slopcameraGatewayApiBaseUrl,slopcameraGalleryLimits,slopcameraGalleryKinds,slopcameraGalleryAxes,slopcameraApi,serializeTldr,searchSlopcameraOperations,sampleVisualStyleExposure,runSlopcameraWorkflow,runMcpServer,resolveStackLayout,resolveSlopcameraGatewayCredential,resolveEdge,resolveDiagramSource,renderSvg,renderPng,renderDrawingFile,renderDrawing,renderDiagramFile,readDrawingFile,readDiagramFile,planStudioJob,planSlopcameraSceneGallery,planSlopcameraGallery,parseStudioSourceBundle,parseStudioRuntimeIdentity,parseStudioReceipt,parseStudioPlan,parseStudioJob,parseSlopcameraSceneVariants,parseSlopcameraOperationInput,parseSlopcameraGalleryVary,parseSlopcameraCapabilityManifest,parseDrawingSource,parseDiagramSpec,parseDiagramSource,normalizeHostResourceProfile,normalizeHostResourceClaims,mcpSourceByteLimit,mcpMaximumScale,mcpMaximumRenderedPixels,lintDiagram,isSlopcameraOperationCode,installSkill,inspectStudioPlan,inspectStudioBundle,iconVisualGateProblems,iconPromptFor,getVisualStyleProfile,generateSlopcameraImageGallery,generateSlopcameraImageFile,generateSlopcameraImage,generateSlopcameraIcon,galleryPromptFor,galleryCandidateId,extractIconLineArt,executeSlopcameraOperationWithLease,executeSlopcameraOperation,drawingSourceByteLimit,drawingProfile,drawingPageGeometry,drawingMinimumGlyphHeightPt,diagramApi,defineSlopcameraWorkflow,defineSlopcameraCapabilityModule,defaultSlopcameraHostResourceStateRoot,defaultSlopcameraHostResourceProfile,critiqueIconRaster,createVisualStyleDirection,createProcessLocalHostResourceCoordinator,createPortableSlopcameraCapabilityManifest,createHostResourceCoordinator,createFixedGatewayFetch,createDefaultHostResourceCoordinator,composeSlopcameraImageGallery,compileSlopcameraCapabilityManifest,checkDrawingFile,checkDiagramFile,bundledSkillPath,builtInIcons,artifactSummary,WorkspaceBoundaryError,WorkspaceBoundary,VisualStyleProfileSchema,VisualStyleIdSchema,VectorizeError,VTRACER_VERSION,VISUAL_STYLE_VARIATION_ALGORITHM,VISUAL_STYLE_PROFILES,VISUAL_STYLE_IDS,StudioSourceSpaceSchema,StudioSourceBundleSchema,StudioRuntimeIdentitySchema,StudioRenderSchema,StudioReceiptSchema,StudioPlanSchema,StudioPathSchema,StudioOutputSpecSchema,StudioOutputRoleSchema,StudioOutputInterpretationSchema,StudioOutputFormatSchema,StudioOutputArtifactSchema,StudioJobSchema,StudioExecutionProfileSchema,StudioEngineSchema,StudioEngineOptionsSchema,StudioDigestSchema,StudioCapabilityNameSchema,StackLayoutError,SlopcameraWorkflowError,SlopcameraSceneVariantsSchema,SlopcameraOperationError,SlopcameraMcpToolRuntime,SlopcameraCloudError,SlopcameraCapabilityWorkflowSchema,SlopcameraCapabilityToolSchema,SlopcameraCapabilityResumeSchema,SlopcameraCapabilityResourceSchema,SlopcameraCapabilityQualificationSchema,SlopcameraCapabilityProfileSchema,SlopcameraCapabilityPreparationSchema,SlopcameraCapabilityOperationSchema,SlopcameraCapabilityModuleSchema,SlopcameraCapabilityModuleDeclarationSchema,SlopcameraCapabilityManifestSchema,SlopcameraCapabilityEffectSchema,SlopcameraCapabilityCommandSchema,STUDIO_LIMITS,SLOPCAMERA_VERSION,SLOPCAMERA_PORTABLE_CAPABILITY_VERSION,SLOPCAMERA_CAPABILITY_MANIFEST_LIMITS,HostResourceError,HOST_RESOURCE_MAX_WAIT_MILLISECONDS,DrawingValidationError,DiagramValidationError}; +import{DrawingValidationError,SLOPCAMERA_CAPABILITY_MANIFEST_LIMITS,SLOPCAMERA_PORTABLE_CAPABILITY_VERSION,SLOPCAMERA_VERSION,STUDIO_LIMITS,SlopcameraCapabilityCommandSchema,SlopcameraCapabilityEffectSchema,SlopcameraCapabilityManifestSchema,SlopcameraCapabilityModuleDeclarationSchema,SlopcameraCapabilityModuleSchema,SlopcameraCapabilityOperationSchema,SlopcameraCapabilityPreparationSchema,SlopcameraCapabilityProfileSchema,SlopcameraCapabilityQualificationSchema,SlopcameraCapabilityResourceSchema,SlopcameraCapabilityResumeSchema,SlopcameraCapabilityToolSchema,SlopcameraCapabilityWorkflowSchema,SlopcameraMcpToolRuntime,SlopcameraSceneVariantsSchema,StudioCapabilityNameSchema,StudioDigestSchema,StudioEngineOptionsSchema,StudioEngineSchema,StudioExecutionProfileSchema,StudioJobSchema,StudioOutputArtifactSchema,StudioOutputFormatSchema,StudioOutputInterpretationSchema,StudioOutputRoleSchema,StudioOutputSpecSchema,StudioPathSchema,StudioPlanSchema,StudioReceiptSchema,StudioRenderSchema,StudioRuntimeIdentitySchema,StudioSourceBundleSchema,StudioSourceSpaceSchema,VISUAL_STYLE_IDS,VISUAL_STYLE_PROFILES,VISUAL_STYLE_VARIATION_ALGORITHM,VisualStyleIdSchema,VisualStyleProfileSchema,WorkspaceBoundary,WorkspaceBoundaryError,artifactSummary,checkDiagramFile,checkDrawingFile,compileSlopcameraCapabilityManifest,createPortableSlopcameraCapabilityManifest,createVisualStyleDirection,defineSlopcameraCapabilityModule,diagramApi,drawingMinimumGlyphHeightPt,drawingPageGeometry,drawingProfile,drawingSourceByteLimit,getVisualStyleProfile,inspectStudioBundle,inspectStudioPlan,mcpMaximumRenderedPixels,mcpMaximumScale,mcpSourceByteLimit,parseDrawingSource,parseSlopcameraCapabilityManifest,parseSlopcameraSceneVariants,parseStudioJob,parseStudioPlan,parseStudioReceipt,parseStudioRuntimeIdentity,parseStudioSourceBundle,planSlopcameraSceneGallery,planStudioJob,readDiagramFile,readDrawingFile,renderDiagramFile,renderDrawing,renderDrawingFile,runMcpServer,sampleVisualStyleExposure,slopcameraApi,slopcameraMcpProtocolVersion,slopcameraMcpServerName,slopcameraMcpTools,slopcameraPortableCapabilityManifest,slopcameraSceneGalleryLimits,starterDrawingSource,studioJobSha256,studioOutputPath,studioRuntimeSha256,studioSourceBundleSha256,summarizeSceneVariantPatch,validateStudioReceipt,visualStyleFrameVariation}from"./index-qxfexvj3.js";import{bundledSkillPath,installSkill}from"./index-grk47tgs.js";import"./index-z1kd1x8j.js";import"./index-3cxf2c58.js";import{SlopcameraWorkflowError,defineSlopcameraWorkflow,runSlopcameraWorkflow}from"./index-4z9y2wa2.js";import{DiagramValidationError,SlopcameraOperationError,StackLayoutError,builtInIcons,composeSlopcameraImageGallery,critiqueIconRaster,executeSlopcameraOperation,executeSlopcameraOperationWithLease,extractIconLineArt,galleryCandidateId,galleryPromptFor,generateSlopcameraIcon,generateSlopcameraImageGallery,iconPromptFor,iconVisualGateProblems,isSlopcameraOperationCode,lintDiagram,parseDiagramSource,parseDiagramSpec,parseSlopcameraGalleryVary,parseSlopcameraOperationInput,planSlopcameraGallery,renderPng,renderSvg,resolveDiagramSource,resolveEdge,resolveStackLayout,searchSlopcameraOperations,serializeTldr,slopcameraGalleryAxes,slopcameraGalleryKinds,slopcameraGalleryLimits,slopcameraIconCritiqueDefaultModel,slopcameraIconCritiqueTimeoutMs,slopcameraIconDefaultInk,slopcameraIconDefaultRounds,slopcameraIconMaximumRounds,slopcameraIconPanel,slopcameraIconSubjectMaximumBytes,slopcameraOperationCodes,slopcameraOperationHostResourceClaims,slopcameraOperationRegistry,stackLayoutDefaults,withSlopcameraOperationHostAdmission}from"./index-fevf4ppk.js";import{VTRACER_VERSION,VectorizeError,vectorizeDefaultLimits,vectorizeHardLimits,vectorizeImage,vectorizeProfileNames,vtracerReleases}from"./index-mnp0bftq.js";import{SlopcameraCloudError,createFixedGatewayFetch,generateSlopcameraImage,generateSlopcameraImageFile,resolveSlopcameraGatewayCredential,slopcameraGatewayApiBaseUrl,slopcameraGatewayCredentialStatus,slopcameraImageModels,slopcameraMaximumPromptBytes,slopcameraMaximumRawImageBytes,slopcameraResponseMediaTypes}from"./index-nxtmy18t.js";import{HOST_RESOURCE_MAX_WAIT_MILLISECONDS,HostResourceError,createDefaultHostResourceCoordinator,createHostResourceCoordinator,createProcessLocalHostResourceCoordinator,defaultSlopcameraHostResourceProfile,defaultSlopcameraHostResourceStateRoot,normalizeHostResourceClaims,normalizeHostResourceProfile,slopcameraHostResourceNames}from"./index-b3geqczn.js";import"./index-80a36bc0.js";export{withSlopcameraOperationHostAdmission,vtracerReleases,visualStyleFrameVariation,vectorizeProfileNames,vectorizeImage,vectorizeHardLimits,vectorizeDefaultLimits,validateStudioReceipt,summarizeSceneVariantPatch,studioSourceBundleSha256,studioRuntimeSha256,studioOutputPath,studioJobSha256,starterDrawingSource,stackLayoutDefaults,slopcameraSceneGalleryLimits,slopcameraResponseMediaTypes,slopcameraPortableCapabilityManifest,slopcameraOperationRegistry,slopcameraOperationHostResourceClaims,slopcameraOperationCodes,slopcameraMcpTools,slopcameraMcpServerName,slopcameraMcpProtocolVersion,slopcameraMaximumRawImageBytes,slopcameraMaximumPromptBytes,slopcameraImageModels,slopcameraIconSubjectMaximumBytes,slopcameraIconPanel,slopcameraIconMaximumRounds,slopcameraIconDefaultRounds,slopcameraIconDefaultInk,slopcameraIconCritiqueTimeoutMs,slopcameraIconCritiqueDefaultModel,slopcameraHostResourceNames,slopcameraGatewayCredentialStatus,slopcameraGatewayApiBaseUrl,slopcameraGalleryLimits,slopcameraGalleryKinds,slopcameraGalleryAxes,slopcameraApi,serializeTldr,searchSlopcameraOperations,sampleVisualStyleExposure,runSlopcameraWorkflow,runMcpServer,resolveStackLayout,resolveSlopcameraGatewayCredential,resolveEdge,resolveDiagramSource,renderSvg,renderPng,renderDrawingFile,renderDrawing,renderDiagramFile,readDrawingFile,readDiagramFile,planStudioJob,planSlopcameraSceneGallery,planSlopcameraGallery,parseStudioSourceBundle,parseStudioRuntimeIdentity,parseStudioReceipt,parseStudioPlan,parseStudioJob,parseSlopcameraSceneVariants,parseSlopcameraOperationInput,parseSlopcameraGalleryVary,parseSlopcameraCapabilityManifest,parseDrawingSource,parseDiagramSpec,parseDiagramSource,normalizeHostResourceProfile,normalizeHostResourceClaims,mcpSourceByteLimit,mcpMaximumScale,mcpMaximumRenderedPixels,lintDiagram,isSlopcameraOperationCode,installSkill,inspectStudioPlan,inspectStudioBundle,iconVisualGateProblems,iconPromptFor,getVisualStyleProfile,generateSlopcameraImageGallery,generateSlopcameraImageFile,generateSlopcameraImage,generateSlopcameraIcon,galleryPromptFor,galleryCandidateId,extractIconLineArt,executeSlopcameraOperationWithLease,executeSlopcameraOperation,drawingSourceByteLimit,drawingProfile,drawingPageGeometry,drawingMinimumGlyphHeightPt,diagramApi,defineSlopcameraWorkflow,defineSlopcameraCapabilityModule,defaultSlopcameraHostResourceStateRoot,defaultSlopcameraHostResourceProfile,critiqueIconRaster,createVisualStyleDirection,createProcessLocalHostResourceCoordinator,createPortableSlopcameraCapabilityManifest,createHostResourceCoordinator,createFixedGatewayFetch,createDefaultHostResourceCoordinator,composeSlopcameraImageGallery,compileSlopcameraCapabilityManifest,checkDrawingFile,checkDiagramFile,bundledSkillPath,builtInIcons,artifactSummary,WorkspaceBoundaryError,WorkspaceBoundary,VisualStyleProfileSchema,VisualStyleIdSchema,VectorizeError,VTRACER_VERSION,VISUAL_STYLE_VARIATION_ALGORITHM,VISUAL_STYLE_PROFILES,VISUAL_STYLE_IDS,StudioSourceSpaceSchema,StudioSourceBundleSchema,StudioRuntimeIdentitySchema,StudioRenderSchema,StudioReceiptSchema,StudioPlanSchema,StudioPathSchema,StudioOutputSpecSchema,StudioOutputRoleSchema,StudioOutputInterpretationSchema,StudioOutputFormatSchema,StudioOutputArtifactSchema,StudioJobSchema,StudioExecutionProfileSchema,StudioEngineSchema,StudioEngineOptionsSchema,StudioDigestSchema,StudioCapabilityNameSchema,StackLayoutError,SlopcameraWorkflowError,SlopcameraSceneVariantsSchema,SlopcameraOperationError,SlopcameraMcpToolRuntime,SlopcameraCloudError,SlopcameraCapabilityWorkflowSchema,SlopcameraCapabilityToolSchema,SlopcameraCapabilityResumeSchema,SlopcameraCapabilityResourceSchema,SlopcameraCapabilityQualificationSchema,SlopcameraCapabilityProfileSchema,SlopcameraCapabilityPreparationSchema,SlopcameraCapabilityOperationSchema,SlopcameraCapabilityModuleSchema,SlopcameraCapabilityModuleDeclarationSchema,SlopcameraCapabilityManifestSchema,SlopcameraCapabilityEffectSchema,SlopcameraCapabilityCommandSchema,STUDIO_LIMITS,SLOPCAMERA_VERSION,SLOPCAMERA_PORTABLE_CAPABILITY_VERSION,SLOPCAMERA_CAPABILITY_MANIFEST_LIMITS,HostResourceError,HOST_RESOURCE_MAX_WAIT_MILLISECONDS,DrawingValidationError,DiagramValidationError}; diff --git a/package.json b/package.json index ee1887ac..d3dedb5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hraness/slopcamera", - "version": "3.5.0", + "version": "3.6.0", "description": "Slopcamera lets your coding agent make images, diagrams, animation, 3D scenes, and video from source files it can keep revising.", "license": "MIT", "type": "module", diff --git a/scripts/check-standalone.ts b/scripts/check-standalone.ts index 8917d5f4..482524a8 100644 --- a/scripts/check-standalone.ts +++ b/scripts/check-standalone.ts @@ -103,7 +103,7 @@ const TEXT_EXTENSIONS = new Set([ const CANONICAL_TEXT_SENTINELS = [ { path: "src/version.ts", - values: ['export const SLOPCAMERA_VERSION = "3.5.0" as const'], + values: ['export const SLOPCAMERA_VERSION = "3.6.0" as const'], }, { path: "src/operations.ts", @@ -125,7 +125,7 @@ const CANONICAL_TEXT_SENTINELS = [ { path: "apps/desktop/dist/cli/main.js", values: [ - '"3.5.0"', + '"3.6.0"', '"slopcamera.diagram.check"', '"slopcamera.edit-plan"', '"slopcamera.video-project"', @@ -388,8 +388,8 @@ if ( const packageVersion = rootPackage.version; if (typeof packageVersion !== "string") { problems.push("package.json version must be a string"); -} else if (packageVersion !== "3.5.0") { - problems.push("package.json version must be 3.5.0 for this source candidate; it does not identify a published Slopcamera release"); +} else if (packageVersion !== "3.6.0") { + problems.push("package.json version must be 3.6.0 for this source candidate; it does not identify a published Slopcamera release"); } else { const versionContracts = [ [ diff --git a/scripts/legacy-identity.inventory.json b/scripts/legacy-identity.inventory.json index 3c78c31d..cce8e5ea 100644 --- a/scripts/legacy-identity.inventory.json +++ b/scripts/legacy-identity.inventory.json @@ -1296,7 +1296,7 @@ }, { "identityLineCount": 86, - "identityLinesSha256": "b65d45d8280e6d158d7cfa8068f5950cb1b30a072a6dede0a2f9e64b6c0d7d90", + "identityLinesSha256": "d64000a8f382d8ce193e74d2160ef9183c90aa864678fa19e0658513919fe2d0", "occurrenceCount": 453, "path": "apps/desktop/dist/cli/main.js", "categories": [ @@ -1796,14 +1796,14 @@ "identityLineCount": 2, "identityLinesSha256": "eb3056c69a99340d4906c251f906d7bf0456e4f496d34175b00adb21c107986e", "occurrenceCount": 233, - "path": "dist/index-z2xp9jaq.js", + "path": "dist/index-qxfexvj3.js", "categories": [ "generated" ] }, { "identityLineCount": 1, - "identityLinesSha256": "857dd191dd95ebeaf53f912fcd3cf53d3e3511a1274fec2e7b8b53f99c1ab25e", + "identityLinesSha256": "76ac5233c11271ae80de2d0a8e944d3973cbe123bbd82b7ca5e20fa870d230e0", "occurrenceCount": 64, "path": "dist/index.js", "categories": [ diff --git a/scripts/release-workflow.test.ts b/scripts/release-workflow.test.ts index 23dee119..3d59c303 100644 --- a/scripts/release-workflow.test.ts +++ b/scripts/release-workflow.test.ts @@ -1111,7 +1111,7 @@ test("Slopcamera source installs stay distinct from historical Atet archives", a readFile(join(packageRoot, "apps", "web", "src", "index.html"), "utf8"), ]) - expect(manifest.version).toBe("3.5.0") + expect(manifest.version).toBe("3.6.0") expect(manifest.bin).toEqual({ slopcamera: "./apps/desktop/dist/cli/main.js", }) diff --git a/src/cli.test.ts b/src/cli.test.ts index 3d05a565..20260839 100644 --- a/src/cli.test.ts +++ b/src/cli.test.ts @@ -55,11 +55,11 @@ async function runCli( } describe("Slopcamera CLI", () => { - test("reports v3.5.0 and documents namespaced media surfaces", async () => { + test("reports v3.6.0 and documents namespaced media surfaces", async () => { const version = await runCli(["--version"], process.cwd()) expect(version).toEqual({ exitCode: 0, - stdout: "3.5.0\n", + stdout: "3.6.0\n", stderr: "", }) const help = await runCli(["--help"], process.cwd()) diff --git a/src/mcp/server.test.ts b/src/mcp/server.test.ts index 2880d0d7..d1707e9b 100644 --- a/src/mcp/server.test.ts +++ b/src/mcp/server.test.ts @@ -130,7 +130,7 @@ describe("Slopcamera MCP stdio server", () => { expect(responses[0]?.result).toMatchObject({ protocolVersion: "2025-11-25", capabilities: { tools: { listChanged: false } }, - serverInfo: { name: "hraness-slopcamera", version: "3.5.0" }, + serverInfo: { name: "hraness-slopcamera", version: "3.6.0" }, }) const listed = responses[2]?.result as { readonly tools: readonly Readonly>[] diff --git a/src/version.ts b/src/version.ts index 44965a2b..5161cddf 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const SLOPCAMERA_VERSION = "3.5.0" as const +export const SLOPCAMERA_VERSION = "3.6.0" as const