@enhance-eng/enhance-dev 0.1.14-dev.sha-27e2a0fdb751 → 0.1.15-dev.sha-1895395f1119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-output-identity.lib-DiyUPF-a.mjs +25 -0
- package/dist/main.mjs +20 -11
- package/dist/mcp-main.mjs +1 -1
- package/dist/mcp-server.adapter-7LLa2h2J.mjs +4 -0
- package/dist/mcp.mjs +1 -1
- package/dist/mutation-key.adapter-DSHM0rrk.mjs +2 -0
- package/package.json +2 -1
- package/dist/cli-output-identity.lib-BWqF7ZU7.mjs +0 -25
- package/dist/mcp-server.adapter-sauxsS06.mjs +0 -4
- package/dist/mutation-key.adapter-BgQ-bZF1.mjs +0 -2
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import{$ as e,B as t,C as n,F as r,H as i,I as a,K as o,L as s,M as c,N as l,P as u,R as ee,S as te,V as ne,Y as re,_ as ie,at as ae,b as oe,ct as se,g as ce,h as le,j as ue,lt as de,nt as fe,ot as pe,st as me,tt as he,v as ge,w as _e,x as ve,y as ye,z as be}from"./cli-output-identity.lib-BWqF7ZU7.mjs";import{z as d}from"zod";import{homedir as xe,tmpdir as Se}from"node:os";import f from"node:process";import{chmodSync as p,createReadStream as m,createWriteStream as Ce,mkdirSync as we,writeFileSync as Te}from"node:fs";import h from"node:path";import{createHash as g,randomBytes as Ee,randomUUID as _}from"node:crypto";import{setTimeout as De}from"node:timers/promises";import{chmod as v,mkdir as Oe,mkdtemp as ke,readFile as Ae,realpath as je,rename as Me,rm as y,stat as b,unlink as Ne,writeFile as Pe}from"node:fs/promises";import{Readable as Fe,Transform as x}from"node:stream";import{pipeline as Ie}from"node:stream/promises";import{ZipFile as Le}from"yazl";import{createTRPCUntypedClient as Re,httpLink as ze}from"@trpc/client";import{spawn as Be}from"node:child_process";import{createServer as Ve}from"node:http";const He=/^enh_[\w-]{43}$/,S=e=>{let r=t.parse(e);if(r.authentication.kind!==`agent`||r.person===null)throw new n(`UNAUTHORIZED`,`The credential is missing, expired, revoked, or invalid.`,`Run 'enhance auth login' and complete authentication in the browser.`);return{authenticated:!0,personId:r.person.id,displayName:r.person.displayName,tokenId:r.authentication.tokenId,tokenLabel:r.authentication.tokenLabel,expiresAt:r.authentication.expiresAt}},Ue=(e,t,r)=>({loginWithToken:async r=>{if(!He.test(r))throw new n(`BAD_REQUEST`,`Agent tokens begin with enh_ and contain 32 base64url bytes.`,`Pass a manual token from Settings to 'enhance auth login' through stdin.`);let i=S(await t.queryWithToken(`person.me`,{},r));return await e.write(r),i},loginWithBrowser:async a=>{let o=ne.parse(await t.authenticationConfig());if(o.method===`token`)throw new n(`BAD_REQUEST`,`Browser authentication is not configured for this Enhance environment.`,`Ask an administrator to configure CLI OAuth, or pass an agent token to 'enhance auth login --token'.`);let s=await r.authorize({issuer:o.issuer,clientId:o.clientId,scope:o.scope,openBrowser:a.openBrowser,onReady:a.onReady,...a.signal!==void 0&&{signal:a.signal}});a.signal?.throwIfAborted();let c=i.parse(await t.mutateWithToken(`person.createAgentToken`,{label:a.label,expiresAt:null},s)),l=S(await t.queryWithToken(`person.me`,{},c.token));return a.signal?.throwIfAborted(),await e.write(c.token),l},status:async()=>{if(await e.read()===null)throw new n(`UNAUTHORIZED`,`No credential exists at ${e.path}.`,`A human must run 'enhance auth login'.`);return S(await t.query(`person.me`,{}))},logout:async()=>({loggedOut:await e.remove()})}),We=Uint8Array.from(globalThis.atob(`iVBORw0KGgo=`),e=>e.codePointAt(0)??0),Ge=e=>{if(e.byteLength<24||We.some((t,n)=>e[n]!==t))return null;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);return{width:t.getUint32(16),height:t.getUint32(20)}},Ke=async(e,t)=>{let r=me.safeParse(await e.query(`canvas.render.download`,{jobId:t.id}));if(!r.success)throw new n(`INTERNAL`,`The API returned an invalid render download response.`,"Run `enhance doctor`; report the API and CLI versions if they differ.");let i=await e.download(r.data.download.url),a=Ge(i);if(a===null||i.byteLength!==t.result.bytes||a.width!==t.result.width||a.height!==t.result.height)throw new n(`INTERNAL`,`The downloaded render did not match its completed job metadata.`,`Do not use the image. Report render job ${t.id}.`);return i},qe=[`canvas.render.create`,`canvas.render.get`],C=e=>new n(`INTERNAL`,`The API returned an invalid ${e} response.`,"Run `enhance doctor`; report the API and CLI versions if they differ."),Je=e=>{let t=e.failure;if(t===null)return C(`render job`);let r=t.reason===`VERSION_CHANGED`?`CONFLICT`:t.reason===`TARGET_NOT_FOUND`?`NOT_FOUND`:t.reason===`TARGET_INVALID`||t.reason===`OUTPUT_TOO_LARGE`?`BAD_REQUEST`:`INTERNAL`,i=t.reason===`VERSION_CHANGED`?`Run 'enhance canvas inspect --canvas ${e.canvasId}', then render its returned version.`:t.reason===`TARGET_NOT_FOUND`?`Run 'enhance canvas tree --canvas ${e.canvasId}' and choose a current node id.`:t.retryable?"Retry the render. If it repeats, run `enhance doctor` and report the job id.":`Change the target or scale using the failure details, then retry.`;return new n(r,t.message,i,{jobId:e.id,reason:t.reason,phase:t.phase})},Ye=async e=>new Promise(t=>{globalThis.setTimeout(t,e)}),Xe=async(e,t)=>{let n=se.safeParse(await e.query(qe[1],{jobId:t}));if(!n.success)throw C(`render status`);return n.data.job},Ze=async(e,t)=>{let r=Date.now(),i=0,a=``,o=t.initial;for(;o.state===`queued`||o.state===`running`;){let s=Date.now(),c=`${o.state}:${o.phase}`;if((c!==a||s-i>=5e3)&&(t.progress({event:`render.progress`,jobId:o.id,state:o.state,phase:o.phase,elapsedMs:s-r,timeoutMs:t.timeoutMs,retryClientToken:t.retryClientToken}),i=s,a=c),s>=t.deadline)throw new n(`INTERNAL`,`Render ${o.id} did not finish before the local timeout.`,`Retry the exact command with --client-token ${t.retryClientToken} and a larger --timeout-ms. If the render remains unavailable, run \`enhance doctor\` and report the job id.`,{jobId:o.id,phase:o.phase});await Ye(250),o=await Xe(e,o.id)}if(o.state!==`succeeded`)throw Je(o);return o},Qe=e=>{let t=`enhance canvas inspect --canvas ${e.canvasId}`;return e.result.sourceState===void 0?e.target.kind===`node`?[t,`enhance canvas node --canvas ${e.canvasId} --node-id ${e.target.nodeId}`]:[t]:[`Inspect the PNG at path before persisting this moment.`,`enhance recording snapshot --canvas ${e.canvasId} --recording-id ${e.result.sourceState.recordingId} --at-ms ${String(e.result.sourceState.settledAtMs)}`,t]},$e=(e,t)=>({jobId:e.id,canvasId:e.canvasId,requestedVersion:e.requestedVersion,loadedVersion:e.result.loadedVersion,target:e.target,sourceState:e.result.sourceState??null,bounds:e.result.bounds,width:e.result.width,height:e.result.height,scale:e.result.scale,contentType:e.result.contentType,bytes:e.result.bytes,warnings:e.result.warnings,path:t.path,sensitive:!0,cleanup:t.temporary?`unlink-after-use`:`caller-owned`,...t.deleteAfter!==null&&{deleteAfter:t.deleteAfter.toISOString()},next:Qe(e)}),et=async(e,t)=>{let n=ae.safeParse(await e.remote.mutate(qe[0],{canvasId:t.canvasId,...t.expectedVersion!==null&&{expectedVersion:t.expectedVersion},target:t.target,...t.sourceState!==null&&{sourceState:t.sourceState},scale:t.scale,format:`png`}));if(!n.success)throw C(`render creation`);let r=await Ze(e.remote,{initial:n.data.job,deadline:Date.now()+t.timeoutMs,timeoutMs:t.timeoutMs,retryClientToken:t.retryClientToken,progress:e.progress}),i=await Ke(e.remote,r),a=e.files.write({body:i,outputPath:t.outputPath,overwrite:t.overwrite,at:e.now()});return $e(r,a)},w=(e,t,n,r=()=>null)=>({execute:async i=>et({remote:e,files:t,now:n,progress:r},i)}),T={begin:`canvas.realtime.activity.begin`,renew:`canvas.realtime.activity.renew`,end:`canvas.realtime.activity.end`},E=async e=>{try{return await e(),!0}catch{return!1}},tt=(e,t,n,r)=>{let i=t,a=!1,o=!1,s=async()=>{a||o||(o=!0,await E(async()=>e.mutate(T.renew,{...i,nodeIds:[...i.nodeIds],activityId:n})),o=!1)},c=setInterval(()=>void s(),r);return{activityId:n,update:async e=>{a||(i={...i,...e},await s())},finish:async()=>{a||(a=!0,clearInterval(c),await E(async()=>e.mutate(T.end,{canvasId:i.canvasId,activityId:n})))}}},D=e=>({begin:async t=>{try{let n=o.safeParse(await e.mutate(T.begin,{...t,nodeIds:[...t.nodeIds]}));return n.success?tt(e,t,n.data.activityId,n.data.renewAfterMs):null}catch{return null}},finish:async(t,n)=>E(async()=>e.mutate(T.end,{canvasId:t,activityId:n}))}),nt=new Set([`insertPrototype`,`insertText`,`setBox`]),rt=e=>nt.has(e.op),it=e=>e.operations.some(e=>e.op===`insertNode`||e.op===`insertText`)?`creating`:e.operations.some(e=>e.op===`remove`)?`deleting`:`writing`,at=e=>e.op===`insertConvertedSubtree`?Object.keys(e.nodes):e.op===`insertNode`?[e.node.id]:[e.nodeId],ot=e=>[...new Set(e.operations.flatMap(e=>at(e)))].slice(0,100),st=e=>e.op===`insertConvertedSubtree`?e.nodes[e.rootNodeId]?.box??null:e.op===`insertNode`?e.node.box??null:rt(e)?e.box==="default"?null:e.box:null,ct=e=>{let t=e[0];if(t===void 0)return null;let n=t.x,r=t.y,i=t.x+t.width,a=t.y+t.height;for(let t of e.slice(1))n=Math.min(n,t.x),r=Math.min(r,t.y),i=Math.max(i,t.x+t.width),a=Math.max(a,t.y+t.height);return{x:n,y:r,width:i-n,height:a-r}},O=async(e,t)=>{let r=await e.mutate(`canvas.applyOperations`,{...t,documentFormatVersion:3}),i=re.safeParse(r);if(!i.success)throw new n(`INTERNAL`,`The API returned an invalid canvas apply response.`,"Run `enhance doctor`; report the API and CLI versions if they differ.");return i.data},k=e=>({execute:async(t,n)=>{if(n?.activity===!1)return O(e,t);let r=await D(e).begin({canvasId:t.canvasId,phase:it(t),nodeIds:ot(t),bounds:ct(t.operations.flatMap(e=>{let t=st(e);return t===null?[]:[t]}))});try{return await O(e,t)}finally{await r?.finish()}}}),A=e=>new n(`INTERNAL`,`The API returned an invalid ${e} response.`,"Run `enhance doctor`; report the API and CLI versions if they differ."),lt=async e=>new Promise(t=>{globalThis.setTimeout(t,e)}),ut=e=>{let t=e.failure;return new n(t.reason===`VERSION_CHANGED`?`CONFLICT`:t.reason===`TARGET_NOT_FOUND`?`NOT_FOUND`:t.reason===`TARGET_INVALID`||t.reason===`CONVERSION_FAILED`?`BAD_REQUEST`:`INTERNAL`,t.message,t.retryable?"Retry the exact write. If it repeats, run `enhance doctor` and report the job id.":`Inspect the current canvas tree and correct the HTML or destination before retrying.`,{jobId:e.id,phase:t.phase,reason:t.reason})},dt=async(e,t)=>{let n=fe.safeParse(await e.query(`canvas.render.getImport`,{jobId:t}));if(!n.success)throw A(`HTML import status`);return n.data.job},ft=async(e,t,r)=>{let i=Date.now()+r,a=t;for(;a.state===`queued`||a.state===`running`;){if(Date.now()>=i)throw new n(`INTERNAL`,`HTML import ${a.id} did not finish before the local timeout.`,"Retry the exact command with a larger --timeout-ms. If the queue remains stuck, run `enhance doctor`.",{jobId:a.id,phase:a.phase});await lt(250),a=await dt(e,a.id)}if(a.state!==`succeeded`)throw ut(a);return a},pt=async(e,t)=>{let n=he.safeParse(await e.mutate(`canvas.render.importSource`,{canvasId:t.canvasId,expectedVersion:t.baseVersion,source:{kind:`html`,html:t.html,label:`Agent-authored HTML`,...t.idPrefix!==void 0&&{idPrefix:t.idPrefix}},destination:{kind:t.mode,targetNodeId:t.targetNodeId}}));if(!n.success)throw A(`HTML import creation`);return ft(e,n.data.job,t.renderTimeoutMs)},mt=(e,t,r)=>({state:`failed`,mutationCommitted:!0,requestedVersion:r,...e instanceof n?{code:e.code,message:e.message,remediation:e.remediation,...e.fields!==void 0&&{fields:e.fields}}:{code:`INTERNAL`,message:`The post-write review render failed.`,remediation:`Read the current canvas version, then render the affected area again.`},next:[`enhance canvas inspect --canvas ${t.canvasId}`,`enhance canvas render --canvas ${t.canvasId} --expected-version ${String(r)}`,`Do not replay the committed write with a new mutation id.`]}),ht=async(e,t,n)=>{try{return await e.execute({canvasId:t.canvasId,expectedVersion:n.result.version,target:{kind:`node`,nodeId:n.result.rootNodeId},sourceState:null,scale:t.renderScale,outputPath:t.renderOutputPath,overwrite:t.overwriteRender,timeoutMs:t.renderTimeoutMs,retryClientToken:t.renderClientToken})}catch(e){return mt(e,t,n.result.version)}},gt=async(t,n)=>{let r=e.safeParse(await t.query(`canvas.document.get`,{canvasId:n.canvasId}));if(!r.success)throw A(`canvas document`);let i=de.safeParse(r.data.document);if(!i.success)throw A(`editable canvas document`);return n.result.insertedNodeIds.map(e=>{let t=i.data.nodes[e];return{id:e,name:t?.label??``,component:t?.component??``}})},_t=async(e,t,n,r)=>({canvasId:t.canvasId,mutationCommitted:!0,mode:t.mode,targetNodeId:t.targetNodeId,previousVersion:n.result.previousVersion,version:n.result.version,createdNodes:await gt(e,n),removedNodeIds:n.result.removedNodeIds,affectedBounds:n.result.affectedBounds,review:r,next:[`enhance canvas tree --canvas ${t.canvasId}`,`Inspect the review PNG before continuing.`]}),j=(e,t)=>({execute:async n=>{let r=await D(e).begin({canvasId:n.canvasId,phase:`creating`,nodeIds:[n.targetNodeId],bounds:null});try{let i=await pt(e,n);await r?.update({phase:`rendering`,nodeIds:i.result.insertedNodeIds.slice(0,100),bounds:i.result.affectedBounds});let a=await ht(t,n,i);return await _t(e,n,i,a)}finally{await r?.finish()}}}),M=(e,t,r)=>{try{Te(e,t,{flag:r?`w`:`wx`,mode:384}),p(e,384)}catch(t){let r=typeof t==`object`&&t&&Reflect.get(t,`code`)===`EEXIST`?`CONFLICT`:`INTERNAL`;throw new n(r,r===`CONFLICT`?`Refusing to replace ${e}.`:`Could not write ${e}.`,r===`CONFLICT`?`Choose another --output path or pass --force deliberately.`:`Create the parent directory and verify it is writable, then retry.`)}},N=e=>({write:t=>{if(t.outputPath!==null){let e=h.resolve(t.outputPath);return M(e,t.body,t.overwrite),{path:e,temporary:!1,deleteAfter:null}}let n=h.join(e,`sensitive`);we(n,{recursive:!0,mode:448}),p(n,448);let r=h.join(n,`render-${globalThis.crypto.randomUUID()}.png`);return M(r,t.body,!1),{path:r,temporary:!0,deleteAfter:new Date(t.at.getTime()+36e5)}}}),P=[`prototype.getArtifactCapabilities`,`prototype.createArtifact`,`prototype.submitArtifact`,`prototype.getPublishStatus`,`prototype.attach`],F=e=>new n(`INTERNAL`,`The API returned an invalid prototype ${e} response.`,"Run `enhance doctor`; report the API and CLI versions if they differ."),vt=async(e,t)=>{let r=Date.now()+3e5,i=50;for(;Date.now()<r;){let r=a.safeParse(await e.query(P[3],t));if(!r.success)throw F(`status`);if(r.data.state===`ready`||r.data.state===`failed`)return r.data;if(r.data.state===`abandoned`)throw new n(`NOT_FOUND`,`Prototype deployment ${t.deploymentId} was abandoned.`,`Publish the directory again with a new client token.`);await De(i),i=Math.min(i*2,1e3)}throw Error(`prototype ingestion is still running`)},yt=async(e,t,n,r)=>{let i=l.safeParse(await e.mutate(P[1],{canvasId:t.canvasId,...t.prototypeId!==null&&{prototypeId:t.prototypeId},clientToken:t.clientToken,nodeId:t.nodeId,title:t.title,entryPath:n.manifest.entryPath,artifact:n.identity,box:t.box}));if(!i.success)throw F(`artifact creation`);if(r(i.data.deploymentId),i.data.state===`uploading`&&await e.upload({url:i.data.upload.url,headers:i.data.upload.headers,body:n.open()}),(i.data.state===`uploading`||i.data.state===`queued`)&&!be.safeParse(await e.mutate(P[2],{canvasId:t.canvasId,deploymentId:i.data.deploymentId})).success)throw F(`artifact submission`);return i.data},bt=e=>{if(e.state!==`failed`)return;let{failure:t}=e;throw new n(`BAD_REQUEST`,t.message,`Fix the build and publish it with a new client token.`,t.path===void 0?void 0:{path:t.path})},xt=async(e,t,i)=>{let a=r.safeParse(await e.query(P[0],{}));if(!a.success)throw F(`capabilities`);let o=await t.package({directory:i.directory,entryPath:i.entryPath,limits:a.data.limits}),s={deploymentId:null};try{let t=await yt(e,i,o,e=>{s.deploymentId=e}),n=await vt(e,{canvasId:i.canvasId,deploymentId:t.deploymentId});bt(n);let r=c.safeParse(await e.mutate(P[4],{canvasId:i.canvasId,deploymentId:t.deploymentId,baseVersion:i.baseVersion}));if(!r.success)throw F(`attachment`);return{...r.data,fileCount:n.fileCount,totalBytes:n.totalBytes,alreadyExists:t.alreadyExists,next:[r.data.openUrl,`enhance canvas render --canvas ${i.canvasId} --node-id ${r.data.nodeId} --expected-version ${String(r.data.version)}`]}}catch(e){throw e instanceof n&&(e.code===`BAD_REQUEST`||e.code===`NOT_FOUND`)||s.deploymentId===null?e:new te(`Prototype deployment ${s.deploymentId} was created, but publishing did not complete.`,`Retry 'enhance prototype publish' with the same --client-token ${i.clientToken}.`)}finally{await o.dispose()}},St=(e,t)=>({execute:async n=>xt(e,t,n)}),Ct=[`transcript.get`],wt=(e,t,n)=>[...new Set(n)].slice(0,3).map(n=>`enhance canvas render --canvas ${e} --node-id rec_${t} --at-ms ${String(n)}`),Tt=e=>({execute:async t=>{let r=_e.safeParse(await e.query(Ct[0],t));if(!r.success)throw new n(`INTERNAL`,`The API returned an invalid transcript response.`,"Run `enhance doctor`; report the API and CLI versions if they differ.");return r.data.state===`ready`?{...r.data,guidance:`Cue times describe speech, not guaranteed visual transitions. Shortlist moments, render candidate timestamps, and inspect each PNG before creating a screen.`,next:wt(t.canvasId,t.recordingId,r.data.cues.map(e=>e.startMs))}:r.data}}),I=[`canvas.render.get`,`canvas.render.snapshot`],Et=async()=>new Promise(e=>{globalThis.setTimeout(e,250)}),Dt=e=>new n(e.failure?.reason===`VERSION_CHANGED`?`CONFLICT`:e.failure?.reason===`TARGET_NOT_FOUND`?`NOT_FOUND`:e.failure?.reason===`TARGET_INVALID`||e.failure?.reason===`OUTPUT_TOO_LARGE`?`BAD_REQUEST`:`INTERNAL`,e.failure?.message??`The snapshot job ended without a result.`,`Run 'enhance canvas tree --canvas ${e.canvasId}' and retry the exact snapshot if its recording node still exists.`,{jobId:e.id,phase:e.phase}),Ot=async(e,t)=>{let r=se.safeParse(await e.query(I[0],{jobId:t}));if(!r.success)throw new n(`INTERNAL`,`The API returned an invalid snapshot status response.`,`Run \`enhance doctor\` and report snapshot job ${t}.`);return r.data.job},kt=async(e,t,r,i)=>{let a=Date.now()+r.timeoutMs,o=Date.now(),s=t,c=0,l=``;for(;s.state===`queued`||s.state===`running`;){let t=Date.now(),u=`${s.state}:${s.phase}`;if((u!==l||t-c>=5e3)&&(i({event:`snapshot.progress`,jobId:s.id,state:s.state,phase:s.phase,elapsedMs:t-o,timeoutMs:r.timeoutMs,retryClientToken:r.retryClientToken}),c=t,l=u),t>=a)throw new n(`INTERNAL`,`Snapshot ${s.id} did not finish before the local timeout.`,`Retry this exact command with --client-token ${r.retryClientToken} and a larger --timeout-ms.`,{jobId:s.id,phase:s.phase});await Et(),s=await Ot(e,s.id)}if(s.state!==`succeeded`||s.result.snapshot===void 0)throw Dt(s);return{...s,result:{...s.result,snapshot:s.result.snapshot}}},At=async(e,t,r)=>{let i=pe.safeParse(await e.mutate(I[1],{canvasId:r.canvasId,recordingId:r.recordingId,atMs:r.atMs}));if(!i.success)throw new n(`INTERNAL`,`The API returned an invalid snapshot creation response.`,"Run `enhance doctor` and report the API and CLI versions.");let a=await kt(e,i.data.job,r,t),o=a.result.snapshot;return{jobId:a.id,canvasId:a.canvasId,...o,warnings:a.result.warnings,retryClientToken:r.retryClientToken,next:[`enhance canvas node --canvas ${a.canvasId} --node-id ${o.screenNodeId}`,`enhance canvas render --canvas ${a.canvasId} --node-id ${o.screenNodeId} --expected-version ${String(o.version)}`]}},jt=(e,t)=>({execute:async n=>At(e,t,n)}),L=new Date(`1980-01-01T00:00:00.000Z`),R=33188,z=(e,t)=>new n(`BAD_REQUEST`,e,t),Mt=(e,t)=>{let n=g(`sha256`),r=0;return new x({transform:(e,t,i)=>{r+=e.byteLength,n.update(e),i(null,e)},flush:i=>{if(r!==e.bytes){i(Error(`prototype file ${e.path} changed while it was packaged`));return}t({path:e.path,contentType:e.contentType,bytes:r,sha256:n.digest(`hex`)}),i()}})},Nt=e=>{let t=s.parse({version:1,entryPath:e.entryPath,files:e.files.map(t=>e.completed.get(t.path))}),n=Buffer.from(JSON.stringify(t),`utf8`);if(n.byteLength>e.limits.manifestBytes)throw z(`The prototype manifest is too large.`,`Shorten paths or reduce metadata below ${String(e.limits.manifestBytes)} bytes.`);return e.zip.addBuffer(n,ue,{mtime:L,mode:R,compress:!0,forceDosTimestamp:!0}),e.zip.end({forceZip64Format:e.files.length>=65535,comment:``}),t},Pt=async e=>{let t=new Le,n=g(`sha256`),r=new x({transform:(e,t,r)=>{n.update(e),r(null,e)}}),i=new Map,a={manifest:null},o=Ie(t.outputStream,r,Ce(e.artifactPath));t.on(`error`,e=>r.destroy(e instanceof Error?e:Error(`prototype ZIP failed`)));let s=n=>{i.set(n.path,n),a.manifest===null&&i.size===e.files.length&&(a.manifest=Nt({zip:t,completed:i,...e}))};for(let n of e.files)t.addReadStreamLazy(n.path,{size:n.bytes,mtime:L,mode:R,compress:!0,forceDosTimestamp:!0},e=>{e(null,m(n.absolutePath).pipe(Mt(n,s)))});if(await o,a.manifest===null)throw Error(`prototype ZIP completed without a manifest`);let c=await b(e.artifactPath);if(c.size>e.limits.artifactBytes)throw z(`The packaged prototype artifact is too large.`,`This environment accepts ${String(e.limits.artifactBytes)} compressed bytes.`);return{manifest:a.manifest,bytes:c.size,sha256:n.digest(`hex`)}},Ft={".avif":`image/avif`,".css":`text/css; charset=utf-8`,".gif":`image/gif`,".html":`text/html; charset=utf-8`,".ico":`image/x-icon`,".jpeg":`image/jpeg`,".jpg":`image/jpeg`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".map":`application/json; charset=utf-8`,".mjs":`text/javascript; charset=utf-8`,".mp3":`audio/mpeg`,".mp4":`video/mp4`,".ogg":`audio/ogg`,".otf":`font/otf`,".png":`image/png`,".svg":`image/svg+xml`,".ttf":`font/ttf`,".txt":`text/plain; charset=utf-8`,".wasm":`application/wasm`,".webm":`video/webm`,".webp":`image/webp`,".woff":`font/woff`,".woff2":`font/woff2`,".xml":`application/xml`},It=e=>Ft[h.extname(e).toLowerCase()]??`application/octet-stream`,B=async e=>{try{return await b(e)}catch{return null}},Lt=e=>Buffer.byteLength(e,`utf8`),V=(e,t)=>new n(`BAD_REQUEST`,e,t),H=(e,t)=>{if(!ee.safeParse(e).success)throw V(`Cannot package the prototype path ${e}.`,`Use portable relative NFC paths outside the reserved __enhance directory.`);if(Lt(e)>t.pathBytes)throw V(`The prototype path ${e} is too long.`,`Shorten it to at most ${String(t.pathBytes)} UTF-8 bytes.`)},U=async(e,t,n,r)=>{let i=await je(t);if(n.has(i))throw V(`Cannot package the circular directory link at ${t}.`,`Pass a directory tree that can be read once from top to bottom.`);let a=new Set(n).add(i),{readdir:o}=await import(`node:fs/promises`),s=await o(t,{withFileTypes:!0}),c=[],l=s.toSorted((e,t)=>e.name.localeCompare(t.name));for(let n of l){let i=h.join(t,n.name),o=await B(i);if(o?.isDirectory()===!0){c.push(...await U(e,i,a,r));continue}if(o?.isFile()!==!0)throw V(`Cannot read ${i} as a prototype file.`,`Pass a directory containing only regular files and directory links.`);let s=h.relative(e,i).split(h.sep).join(`/`).normalize(`NFC`);H(s,r),c.push({absolutePath:i,path:s,bytes:Number(o.size),contentType:It(i)})}return c},Rt=(e,t,n)=>{if(e.length===0)throw V(`The prototype build is empty.`,`Build the app before publishing it.`);if(e.length>n.fileCount)throw V(`The prototype has ${String(e.length)} files.`,`This environment currently accepts ${String(n.fileCount)} files per deployment.`);let r=new Set,i=0;for(let t of e){let e=u(t.path);if(r.has(e))throw V(`The prototype path ${t.path} collides by case or Unicode normalization.`,`Rename one of the colliding files so the build is portable.`);if(r.add(e),t.bytes>n.fileBytes)throw V(`The prototype file ${t.path} is too large.`,`This environment accepts ${String(n.fileBytes)} bytes in one runtime file.`);if(i+=t.bytes,i>n.expandedBytes)throw V(`The prototype build is too large.`,`This environment accepts ${String(n.expandedBytes)} expanded bytes.`)}let a=e.find(e=>e.path===t);if(a===void 0)throw V(`The prototype entry ${t} is missing.`,`Pass --entry with an HTML file inside the build directory.`);if(!a.contentType.startsWith(`text/html`))throw V(`The prototype entry ${t} is not HTML.`,`Pass an HTML entry file such as index.html.`)},zt=async e=>{let t=h.resolve(e.directory),r=await B(t);if(r===null)throw new n(`NOT_FOUND`,`The prototype directory ${t} does not exist.`,`Build the app or pass the correct unpacked build directory.`);if(!r.isDirectory())throw V(`${t} is not an unpacked build directory.`,`Pass the build directory; the CLI creates the ZIP artifact automatically.`);let i=e.entryPath.split(h.sep).join(`/`).normalize(`NFC`);H(i,e.limits);let a=await U(t,t,new Set,e.limits);Rt(a,i,e.limits);let o=await ke(h.join(Se(),`enhance-prototype-artifact-`)),s=h.join(o,`artifact.zip`);try{let t=await Pt({artifactPath:s,files:a,entryPath:i,limits:e.limits});return{identity:{protocolVersion:1,format:`zip`,bytes:t.bytes,sha256:t.sha256,fileCount:t.manifest.files.length,expandedBytes:t.manifest.files.reduce((e,t)=>e+t.bytes,0)},manifest:t.manifest,open:()=>m(s),dispose:async()=>y(o,{recursive:!0})}}catch(e){throw await y(o,{recursive:!0}),e}},Bt=()=>({package:zt}),W=e=>w(e.remote,N(e.configDirectory),e.now??(()=>new Date),e.progress??(()=>null)),Vt=async(e,t)=>{let n=le.parse(t);return k(e.remote).execute({...n,mutationId:e.mutationKey.current(`canvas.applyOperations`,n)})},Ht=async(e,t,n)=>{let r=ce.parse(t);return W(e).execute({...r,retryClientToken:n})},Ut=async(e,t)=>{let n=ie.parse(t);return j(e.remote,W(e)).execute({...n,renderClientToken:e.mutationKey.current(`canvas.render.create`,{purpose:`write-html-review`})})},Wt=async(e,t)=>{let n=ge.parse(t);return e.remote.query(`comment.list`,{canvasId:n.canvasId,filter:`open`,agentActionable:!1})},Gt=async(e,t,n)=>{let r=ye.parse(t);return St(e.remote,Bt()).execute({...r,clientToken:n})},Kt=async(e,t,n)=>{let r=oe.parse(t);return jt(e.remote,e.progress??(()=>null)).execute({...r,retryClientToken:n})},qt=async(e,t)=>{let n=ve.parse(t);return Tt(e.remote).execute(n)},Jt=async(e,t,n,r)=>{switch(t){case`canvas.apply`:return Vt(e,n);case`canvas.render`:return Ht(e,n,r);case`canvas.writeHtml`:return Ut(e,n);case`comment.attention`:return Wt(e,n);case`prototype.publish`:return Gt(e,n,r);case`recording.snapshot`:return Kt(e,n,r);case`transcript.read`:return qt(e,n);default:throw TypeError(`${t} has no composite execution`)}},Yt=e=>({invoke:async({capability:t,arguments:n,clientToken:r})=>{let i=t.inputSchema.parse(n),a=r??_();return e.mutationKey.select(a,t.idempotency===`composite`),t.execution.kind===`composite`?Jt(e,t.id,i,a):t.operation===`query`?e.remote.query(t.execution.procedure,i):e.remote.mutate(t.execution.procedure,i)}}),G=`/callback`,Xt=(e,t)=>new URL(t,e.endsWith(`/`)?e:`${e}/`),Zt=e=>{let t=f.platform===`darwin`?{executable:`open`,arguments:[e]}:f.platform===`win32`?{executable:`rundll32.exe`,arguments:[`url.dll,FileProtocolHandler`,e]}:{executable:`xdg-open`,arguments:[e]},n=Be(t.executable,t.arguments,{detached:!0,stdio:`ignore`});n.once(`error`,()=>!1),n.unref()},Qt=(e,t,n)=>{let r=new URL(t.url??`/`,`http://127.0.0.1`);if(t.method!==`GET`||r.pathname!==G){n.writeHead(404).end();return}if(r.searchParams.get(`state`)!==e.state){n.writeHead(400).end(`The OAuth state did not match. Return to the terminal and retry.`);return}let i=r.searchParams.get(`error`),a=r.searchParams.get(`code`);if(i!==null||a===null||a===``){n.writeHead(400).end(`Enhance authentication was not approved.`),e.completion.reject(Error(i??`the authorization response carried no code`));return}n.writeHead(200,{"content-type":`text/html; charset=utf-8`}).end(`<!doctype html><meta charset="utf-8"><title>Enhance authenticated</title><p>Enhance is authenticated. You can close this window.</p>`),e.completion.resolve(a)},$t=e=>{let t=Xt(e.issuer,`oauth/authorize`);return t.search=new URLSearchParams({response_type:`code`,client_id:e.clientId,redirect_uri:e.redirectUri,scope:e.scope,state:e.state,code_challenge:e.challenge,code_challenge_method:`S256`}).toString(),t.href},en=async e=>{e.signal?.throwIfAborted();let t=Promise.withResolvers(),n=Ve((n,r)=>{Qt({state:e.state,completion:t},n,r)});await new Promise((e,t)=>{n.once(`error`,t),n.listen(0,`127.0.0.1`,e)});let r=n.address();if(r===null||typeof r==`string`)throw n.close(),Error(`the OAuth callback listener has no TCP port`);let i=`http://127.0.0.1:${String(r.port)}${G}`,a=$t({...e,redirectUri:i}),o=()=>{t.reject(Error(`browser authorization cancelled`))};e.signal?.addEventListener(`abort`,o,{once:!0});let s=setTimeout(()=>{t.reject(Error(`browser authorization timed out`))},12e4);try{return e.signal?.throwIfAborted(),e.onReady(a),e.openBrowser&&Zt(a),{code:await t.promise,redirectUri:i}}finally{clearTimeout(s),e.signal?.removeEventListener(`abort`,o),await new Promise(e=>{n.close(()=>{e()})})}},tn=e=>({authorize:async t=>{try{let n=Ee(32).toString(`base64url`),r=g(`sha256`).update(n).digest(`base64url`),i=Ee(32).toString(`base64url`),a=await en({...t,challenge:r,state:i});return await e.exchangeOauthCode({issuer:t.issuer,clientId:t.clientId,code:a.code,redirectUri:a.redirectUri,verifier:n})}catch(e){throw new n(`UNAUTHORIZED`,e instanceof Error?`Browser authentication failed: ${e.message}.`:`Browser authentication failed.`,`Run 'enhance auth login' again, complete the browser consent, and keep the terminal open.`)}}}),K=e=>e===void 0||e===``?void 0:e,nn=((e,t,n)=>{let r=K(e.ENHANCE3_ENVIRONMENT);if(r!==void 0&&r!==n.environment)throw TypeError(`the Enhance ${n.environment} CLI cannot target ${r}`);let i=K(e.ENHANCE3_API_URL),a=h.join(t,`.config`,n.configDirectoryName),o=K(e.ENHANCE3_CONFIG_DIR);if(n.environment===`development`){if(i!==void 0&&i!==n.apiUrl)throw TypeError(`Enhance development cannot use ${i}`);if(o!==void 0&&h.resolve(o)!==h.resolve(a))throw TypeError(`Enhance development credentials must stay in ${a}`)}return{apiUrl:i??n.apiUrl,commandName:n.commandName,configDirectory:o??a,mcpServiceName:n.mcpServiceName}})(f.env,xe(),{apiUrl:`https://api.enhance3.karunalabs.ai`,commandName:`enhance-dev`,configDirectoryName:`enhance-development`,environment:`development`,mcpServiceName:`enhance-dev-mcp`}),rn=d.object({token:d.string().startsWith(`enh_`)}),an=e=>{let t=h.join(e,`credentials.json`);return{path:t,read:async()=>{try{let e=JSON.parse(await Ae(t,`utf8`));return rn.parse(e).token}catch(e){if(typeof e==`object`&&e&&Reflect.get(e,`code`)===`ENOENT`)return null;throw e}},write:async n=>{await Oe(e,{recursive:!0,mode:448}),await v(e,448);let r=h.join(e,`credentials.${String(f.pid)}.tmp`);await Pe(r,`${JSON.stringify({token:n})}\n`,{mode:384,flag:`wx`}),await Me(r,t),await v(t,384)},remove:async()=>{try{return await Ne(t),!0}catch(e){if(typeof e==`object`&&e&&Reflect.get(e,`code`)===`ENOENT`)return!1;throw e}}}},on=d.object({access_token:d.string().min(1)}),sn=d.object({code:d.string().regex(/^[A-Z][A-Z_0-9]+$/u)}),q=`Check network access and proxy settings for this API, then run enhance doctor again.`,J=e=>new URL(typeof e==`string`?e:e instanceof URL?e.href:e.url).origin,Y=e=>{let t=sn.safeParse(e);return t.success?t.data.code:e instanceof Error&&e.cause!==void 0?Y(e.cause):e instanceof Error?e.name:`Network request failed`},X=(e,t)=>new n(`INTERNAL`,`${J(e)} answered HTTP ${String(t)}.`,q),Z=async(e,t)=>{try{return await fetch(e,t)}catch(t){throw new n(`INTERNAL`,`Could not reach ${J(e)}: ${Y(t)}.`,q)}},cn=async(e,t)=>{let n=await Z(e,t);if(!n.ok&&n.headers.get(`content-type`)?.includes(`application/json`)!==!0)throw X(e,n.status);return n},Q=(e,t,n=null)=>Re({links:[ze({url:`${e}/trpc`,fetch:async(e,t)=>cn(e,{...t,signal:t?.signal??null}),headers:{...t!==null&&{authorization:`Bearer ${t}`},...n!==null&&{"x-enhance-idempotency-key":n}}})]}),ln=async e=>{let t=await fetch(e);if(!t.ok)throw new n(t.status===404||t.status===403?`NOT_FOUND`:`INTERNAL`,`Render download answered HTTP ${String(t.status)}.`,`The result may have expired. Request a new render.`);return new Uint8Array(await t.arrayBuffer())},un=async e=>{let t=await Z(`${e}/v1/cli-auth`);if(!t.ok)throw t.status===404?new n(`BAD_REQUEST`,`This Enhance API does not support browser authentication.`,`Deploy a compatible API, or pass an agent token to 'enhance auth login --token'.`):new n(`INTERNAL`,`${J(e)} CLI authentication discovery answered HTTP ${String(t.status)}.`,q);return t.json()},dn=async e=>{let t=e.endsWith(`/`)?e:`${e}/`,n=await Z(new URL(`.well-known/oauth-authorization-server`,t));if(!n.ok)throw X(e,n.status);return n.json()},fn=async e=>{let t=await Z(new URL(`oauth/token`,e.issuer.endsWith(`/`)?e.issuer:`${e.issuer}/`),{method:`POST`,headers:{"content-type":`application/x-www-form-urlencoded`},body:new URLSearchParams({grant_type:`authorization_code`,client_id:e.clientId,code:e.code,redirect_uri:e.redirectUri,code_verifier:e.verifier})});if(!t.ok)throw new n(`INTERNAL`,`${J(e.issuer)} token exchange answered HTTP ${String(t.status)}`,q);return on.parse(await t.json()).access_token},pn=async e=>{try{let t=await Z(`${e}/health`,{signal:AbortSignal.timeout(4e3)});return{url:e,reachable:t.ok,status:t.status,...!t.ok&&{error:X(e,t.status).message}}}catch(t){return{url:e,reachable:!1,status:null,error:t instanceof Error?t.message:`Could not reach ${J(e)}.`}}},mn=(e,t,r)=>{let i=e.replace(/\/$/,``);return{authenticationConfig:async()=>un(i),oauthMetadata:dn,exchangeOauthCode:fn,query:async(e,n)=>Q(i,await t.read()).query(e,n),queryWithToken:async(e,t,n)=>Q(i,n).query(e,t),mutate:async(e,n)=>Q(i,await t.read(),r.current(e,n)).mutation(e,n),mutateWithToken:async(e,t,n)=>Q(i,n).mutation(e,t),download:ln,upload:async e=>{let t=!(e.body instanceof Uint8Array),r=t?Fe.toWeb(e.body):e.body,i={method:`PUT`,headers:e.headers,body:r,...t&&{duplex:`half`}},a=await fetch(e.url,i);if(!a.ok)throw new n(`INTERNAL`,`Signed upload answered HTTP ${String(a.status)}.`,`Retry the fixture command with the same source file.`);let o=a.headers.get(`etag`);if(o===null||o===``)throw new n(`INTERNAL`,`Signed upload returned no ETag.`,`Report the storage response and stop.`);return o.replaceAll(`"`,``)},health:async()=>pn(i)}},$=e=>Array.isArray(e)?e.map(e=>$(e)):typeof e!=`object`||!e?e:Object.fromEntries(Object.entries(e).toSorted(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,$(t)])),hn=(e,t,n)=>g(`sha256`).update(`${e}\0${t}\0${JSON.stringify($(n))}`).digest(`hex`).replace(/^(.{8})(.{4}).(.{3}).(.{3})(.{12}).*$/u,`$1-$2-5$3-8$4-$5`),gn=()=>{let e=_(),t=!1;return{current:(n,r)=>t?hn(e,n,r):e,select:(n,r)=>{e=n??_(),t=r}}};export{tn as a,j as c,w as d,Ue as f,nn as i,k as l,mn as n,Yt as o,an as r,N as s,gn as t,D as u};
|