@coreframe/scripts 0.1.15 → 0.1.16
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/managed-dev.js +1 -1
- package/package.json +1 -1
package/dist/managed-dev.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{managedDevTokenEnv as e,managedDevUrlEnv as t}from"./managed-dev-protocol.js";import{createRequire as n}from"node:module";import{createHash as r,randomBytes as i}from"node:crypto";import{copyFile as a,mkdir as o,mkdtemp as s,open as c,readFile as l,realpath as u,rm as d,unlink as f}from"node:fs/promises";import p from"node:path";import m,{SubprocessError as h}from"nano-spawn";import{pathToFileURL as g}from"node:url";import _ from"node:process";import{watch as v}from"node:fs";import{createServer as ee}from"node:http";const y=`refs/heads/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i;async function b(e=_.cwd()){return(await x(e)).primary}async function x(e){let t=await u(await H(e,[`rev-parse`,`--show-toplevel`])),n=await u(e),r=p.resolve(t,await H(e,[`rev-parse`,`--git-dir`])),i=p.resolve(t,await H(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function S({config:n,cwd:r=_.cwd(),env:a=_.env,onRestart:o=()=>void 0,remoteCheckInterval:s=6e4}){let c=i(32).toString(`base64url`),l=a,u={mode:`waiting`,warnings:[]},d,f=!1,h=!1,g=!1,v=!1,b=!1,x,S,C,T,E,D=[],O,k,A=new Promise((e,t)=>{k=t}),j=e=>{let t=e instanceof Error?e:Error(String(e));u={...u,busy:void 0,message:t.message,mode:`error`},k(t)},M=async({fetch:e=!1}={})=>{if(!(!h||f||!S)){if(v){b=!0;return}try{if(await H(r,[`rev-parse`,`HEAD`])!==x){await P(`HEAD changed outside Coreframe; managed synchronization is disabled until restart.`);return}if(e){let e=await U(r,[`for-each-ref`,`--format=%(upstream:short)`,y]);if(e){let t=e.indexOf(`/`);if(t>0){let n=e.slice(0,t),i=e.slice(t+1);await V(r,[`fetch`,n,`+refs/heads/${i}:refs/remotes/${n}/${i}`])}}}let t=await H(r,[`rev-parse`,y]),n=await U(r,[`for-each-ref`,`--format=%(upstream:short)`,y]),i=n?await U(r,[`rev-parse`,`refs/remotes/${n}`]):void 0,a=i&&!await W(r,i,t)?i:t;u={...u,currentCommit:x,draft:u.target?.commit===a?u.draft:void 0,message:void 0,mode:`managed`,proposal:u.target?.commit===a?u.proposal:void 0,target:a===x?void 0:await ue(r,a,a===i?`upstream`:`local`)}}catch(e){u={...u,message:J(e),warnings:[J(e)]}}}},N=()=>{clearTimeout(E),E=setTimeout(()=>void M(),50),E.unref()},P=async e=>{h=!1,g=!0,clearInterval(T),clearTimeout(E);for(let e of D)e.close();D=[],await B(C),C=void 0,u={message:e,mode:`unmanaged`,warnings:[]}},F=async()=>{if(h||f||g)return;let e=await re(r);if(!e.primary){u={message:`Managed development only runs from the primary checkout.`,mode:`unmanaged`,warnings:[]};return}if(e.branch&&(e.branch!==`main`||e.status.length>0)){let t=e.branch===`main`?`Managed development requires a clean primary checkout on main. Dirty paths:\n${e.status}`:`Managed development requires the primary checkout on main; current branch is ${e.branch}.`;console.warn(`Coreframe managed development disabled: ${t}`),u={message:t,mode:`unmanaged`,warnings:[]};return}if(!e.branch&&!await W(r,e.head,e.main))throw Error(`Detached HEAD ${e.head.slice(0,12)} is not part of local main's history.`);C=p.join(e.commonDir,`coreframe-managed-dev.lock`),await R(C),e.branch===`main`&&await V(r,[`switch`,`--detach`,e.head]),S={...e,branch:void 0},x=e.head,h=!0,u={currentCommit:e.head,mode:`managed`,warnings:[]},D=await ie(e,N),T=setInterval(()=>void M({fetch:!0}),s),T.unref(),await M(),M({fetch:!0})},I=async e=>{if(!h||u.mode!==`managed`)throw Error(`Managed development is not active.`);if(v)throw Error(`Another managed development action is already running.`);v=!0,u={...u,busy:fe(e),message:void 0};try{if(e.type===`reject`)u={...u,draft:void 0,proposal:void 0};else if(e.type===`prepare`){z(e.target);let t=await w(r);t.tracked||t.untracked.length>0?u={...u,draft:t,proposal:Y(t.fingerprint)}:await Q({target:e.target})}else if(e.type===`message`){let t=await Z(e.fingerprint,e.untracked),n=Y(t.fingerprint);if(n===void 0){try{n=await ae(r,l,t.context)}catch(e){n=``,u={...u,warnings:[...u.warnings,`Codex could not generate a commit message: ${J(e)}`]}}O={fingerprint:t.fingerprint,message:n}}u={...u,draft:t,proposal:n}}else{z(e.target);let t=await w(r);if(t.tracked||t.untracked.length>0){if(!e.fingerprint||!e.untracked)throw Error(`Refresh requires the current working-tree confirmation.`);if(await Z(e.fingerprint,e.untracked),!e.message||!te.test(de(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await Q({fingerprint:e.fingerprint,message:e.message,target:e.target,untracked:e.untracked})}}finally{v=!1,u={...u,busy:void 0},b&&(b=!1,N())}return{status:u}},z=e=>{if(!u.target||u.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`)},Y=e=>O?.fingerprint===e?O.message:void 0,Z=async(e,t)=>{let n=await w(r);if(n.fingerprint!==e)throw O=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!G(n.untracked,t))throw Error(`Include every untracked file or remove it before refreshing.`);return n},Q=async({fingerprint:e,message:t,target:i,untracked:a=[]})=>{z(i);let s=await H(r,[`rev-parse`,`HEAD`]),c=await H(r,[`rev-parse`,y]),d,f,p=await w(r);if(p.tracked||p.untracked.length>0){if(!e||p.fingerprint!==e||!G(p.untracked,a))throw Error(`Working-tree changes changed; review them before refreshing.`);await V(r,[`add`,`--update`]),a.length>0&&await V(r,[`add`,`--`,...a]),await V(r,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}}),d=await H(r,[`rev-parse`,`HEAD`]),x=d,f=`refs/coreframe/recovery/${Date.now()}-${d.slice(0,12)}`,await V(r,[`update-ref`,f,d])}let h=d??s,g;try{if(g=await oe({cwd:r,developerCommit:d,env:l,localMain:c,target:i}),await H(r,[`rev-parse`,`HEAD`])!==h)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await H(r,[`rev-parse`,y])!==c)throw Error(`Local main changed while the accepted update was being prepared.`);await V(r,[`switch`,`--detach`,g.commit]);try{await V(r,[`update-ref`,y,g.commit,c])}catch(e){throw await V(r,[`switch`,`--detach`,h]),e}x=g.commit;let e=K(await H(r,[`diff`,`--name-only`,`-z`,s,g.commit]));L(e)&&await m(q(),[`install`,`--frozen-lockfile`],{cwd:r,env:l,stdio:`inherit`}),g.hadConflicts&&(u={...u,warnings:[...u.warnings,...await se(r,l)]});try{await ce({config:n,cwd:r,env:l})}catch(e){throw await V(r,[`switch`,`--detach`,h]),x=h,u={...u,currentCommit:h},Error(`Database migration failed; the database and preview were restored. ${J(e)}`)}le(e)&&o(),O=void 0,f&&await V(r,[`update-ref`,`-d`,f]),u={...u,currentCommit:g.commit,draft:void 0,proposal:void 0,target:void 0}}catch(e){g?.commit&&x===g.commit&&(await V(r,[`switch`,`--detach`,h]).catch(()=>void 0),x=h);let t=f?` Recovery commit: ${f}.`:``;throw u={...u,currentCommit:x,message:`${J(e)}${t}`},e}};d=ee((e,t)=>{ne(e,t,{action:I,activate:F,getStatus:()=>u,token:c}).catch(n=>{t.headersSent||X(t,400,{error:J(n),status:u}),e.url===`/handshake`&&j(n)})}),await pe(d);let $=d.address();if(!$||typeof $==`string`)throw Error(`Managed dev server failed to listen.`);return{env:{...a,[t]:`http://127.0.0.1:${$.port}`,[e]:c},failure:A,setRuntimeEnv(e){l=e},async close(){f=!0,clearInterval(T),clearTimeout(E);for(let e of D)e.close();await B(C),await me(d)}}}async function ne(e,t,n){if(e.headers.authorization!==`Bearer ${n.token}`){X(t,401,{error:`Invalid managed development capability.`});return}if(e.method===`POST`&&e.url===`/handshake`){await n.activate(),X(t,200,{status:n.getStatus()});return}if(e.method===`GET`&&e.url===`/status`){X(t,200,{status:n.getStatus()});return}if(e.method===`POST`&&e.url===`/action`){let r=await Y(e);X(t,200,await n.action(r));return}X(t,404,{error:`Unknown managed development endpoint.`})}async function re(e){let t=await x(e);return{branch:C(await H(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await H(e,[`rev-parse`,`HEAD`]),main:await H(e,[`rev-parse`,y]),primary:t.primary,status:await H(e,[`status`,`--porcelain`])}}function C(e){return e===`HEAD`?void 0:e}async function ie(e,t){let n=[e.gitDir,p.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(v(e,{persistent:!1},t))}catch{}return r}async function w(e){let[t,n,i]=await Promise.all([H(e,[`status`,`--porcelain`,`--untracked-files=no`]),H(e,[`diff`,`HEAD`,`--binary`]),H(e,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),a=K(i).sort(),o=r(`sha256`).update(n),s=[`Tracked changes:`,n];for(let t of a){let n=await l(p.join(e,t));o.update(t).update(n),s.push(`\nUntracked file: ${t}\n`,n.toString(`utf8`))}return{context:s.join(`
|
|
1
|
+
import{managedDevTokenEnv as e,managedDevUrlEnv as t}from"./managed-dev-protocol.js";import{createRequire as n}from"node:module";import{createHash as r,randomBytes as i}from"node:crypto";import{copyFile as a,mkdir as o,mkdtemp as s,open as c,readFile as l,realpath as u,rm as d,unlink as f}from"node:fs/promises";import p from"node:path";import m,{SubprocessError as h}from"nano-spawn";import{pathToFileURL as g}from"node:url";import _ from"node:process";import{watch as v}from"node:fs";import{createServer as ee}from"node:http";const y=`refs/heads/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i;async function b(e=_.cwd()){return(await x(e)).primary}async function x(e){let t=await u(await H(e,[`rev-parse`,`--show-toplevel`])),n=await u(e),r=p.resolve(t,await H(e,[`rev-parse`,`--git-dir`])),i=p.resolve(t,await H(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function S({config:n,cwd:r=_.cwd(),env:a=_.env,onRestart:o=()=>void 0,remoteCheckInterval:s=6e4}){let c=i(32).toString(`base64url`),l=a,u={mode:`waiting`,warnings:[]},d,f=!1,h=!1,g=!1,v=!1,b=!1,x,S,C,T,E,D=[],O,k,A=new Promise((e,t)=>{k=t}),j=e=>{let t=e instanceof Error?e:Error(String(e));u={...u,busy:void 0,message:t.message,mode:`error`},k(t)},M=async({fetch:e=!1}={})=>{if(!(!h||f||!S)){if(v){b=!0;return}try{if(await H(r,[`rev-parse`,`HEAD`])!==x){await P(`HEAD changed outside Coreframe; managed synchronization is disabled until restart.`);return}if(e){let e=await U(r,[`for-each-ref`,`--format=%(upstream:short)`,y]);if(e){let t=e.indexOf(`/`);if(t>0){let n=e.slice(0,t),i=e.slice(t+1);await V(r,[`fetch`,n,`+refs/heads/${i}:refs/remotes/${n}/${i}`])}}}let t=await H(r,[`rev-parse`,y]),n=await U(r,[`for-each-ref`,`--format=%(upstream:short)`,y]),i=n?await U(r,[`rev-parse`,`refs/remotes/${n}`]):void 0,a=i&&!await W(r,i,t)?i:t;u={...u,currentCommit:x,draft:u.target?.commit===a?u.draft:void 0,message:void 0,mode:`managed`,proposal:u.target?.commit===a?u.proposal:void 0,target:a===x?void 0:await ue(r,a,a===i?`upstream`:`local`)}}catch(e){u={...u,message:J(e),warnings:[J(e)]}}}},N=()=>{clearTimeout(E),E=setTimeout(()=>void M(),50),E.unref()},P=async e=>{h=!1,g=!0,clearInterval(T),clearTimeout(E);for(let e of D)e.close();D=[],await B(C),C=void 0,u={message:e,mode:`unmanaged`,warnings:[]}},F=async()=>{if(h||f||g)return;let e=await re(r);if(!e.primary){u={message:`Managed development only runs from the primary checkout.`,mode:`unmanaged`,warnings:[]};return}if(e.branch&&(e.branch!==`main`||e.status.length>0)){let t=e.branch===`main`?`Managed development requires a clean primary checkout on main. Dirty paths:\n${e.status}`:`Managed development requires the primary checkout on main; current branch is ${e.branch}.`;console.warn(`Coreframe managed development disabled: ${t}`),u={message:t,mode:`unmanaged`,warnings:[]};return}if(!e.branch&&!await W(r,e.head,e.main))throw Error(`Detached HEAD ${e.head.slice(0,12)} is not part of local main's history.`);C=p.join(e.commonDir,`coreframe-managed-dev.lock`),await R(C),e.branch===`main`&&await V(r,[`switch`,`--detach`,e.head]),S={...e,branch:void 0},x=e.head,h=!0,u={currentCommit:e.head,mode:`managed`,warnings:[]},D=await ie(e,N),T=setInterval(()=>void M({fetch:!0}),s),T.unref(),await M(),M({fetch:!0})},I=async e=>{if(!h||u.mode!==`managed`)throw Error(`Managed development is not active.`);if(v)throw Error(`Another managed development action is already running.`);v=!0,u={...u,busy:fe(e),message:void 0};try{if(e.type===`reject`)u={...u,draft:void 0,proposal:void 0};else if(e.type===`prepare`){z(e.target);let t=await w(r);t.tracked||t.untracked.length>0?u={...u,draft:t,proposal:Y(t.fingerprint)}:await Q({target:e.target})}else if(e.type===`message`){let t=await Z(e.fingerprint,e.untracked),n=Y(t.fingerprint);if(n===void 0){try{n=await ae(r,l,t.context)}catch(e){n=``,u={...u,warnings:[...u.warnings,`Codex could not generate a commit message: ${J(e)}`]}}O={fingerprint:t.fingerprint,message:n}}u={...u,draft:t,proposal:n}}else{z(e.target);let t=await w(r);if(t.tracked||t.untracked.length>0){if(!e.fingerprint||!e.untracked)throw Error(`Refresh requires the current working-tree confirmation.`);if(await Z(e.fingerprint,e.untracked),!e.message||!te.test(de(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await Q({fingerprint:e.fingerprint,message:e.message,target:e.target,untracked:e.untracked})}}finally{v=!1,u={...u,busy:void 0},b&&(b=!1,N())}return{status:u}},z=e=>{if(!u.target||u.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`)},Y=e=>O?.fingerprint===e?O.message:void 0,Z=async(e,t)=>{let n=await w(r);if(n.fingerprint!==e)throw O=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!G(n.untracked,t))throw Error(`Include every untracked file or remove it before refreshing.`);return n},Q=async({fingerprint:e,message:t,target:i,untracked:a=[]})=>{z(i);let s=await H(r,[`rev-parse`,`HEAD`]),c=await H(r,[`rev-parse`,y]),d,f,p=await w(r);if(p.tracked||p.untracked.length>0){if(!e||p.fingerprint!==e||!G(p.untracked,a))throw Error(`Working-tree changes changed; review them before refreshing.`);await V(r,[`add`,`--update`]),a.length>0&&await V(r,[`add`,`--`,...a]),await V(r,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}}),d=await H(r,[`rev-parse`,`HEAD`]),x=d,f=`refs/coreframe/recovery/${Date.now()}-${d.slice(0,12)}`,await V(r,[`update-ref`,f,d])}let h=d??s,g;try{if(g=await oe({cwd:r,developerCommit:d,env:l,localMain:c,target:i}),await H(r,[`rev-parse`,`HEAD`])!==h)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await H(r,[`rev-parse`,y])!==c)throw Error(`Local main changed while the accepted update was being prepared.`);await V(r,[`switch`,`--detach`,g.commit]);try{await V(r,[`update-ref`,y,g.commit,c])}catch(e){throw await V(r,[`switch`,`--detach`,h]),e}x=g.commit;let e=K(await H(r,[`diff`,`--name-only`,`-z`,s,g.commit]));L(e)&&await m(q(),[`install`,`--frozen-lockfile`],{cwd:r,env:l,stdio:`inherit`}),g.hadConflicts&&(u={...u,warnings:[...u.warnings,...await se(r,l)]});try{await ce({config:n,cwd:r,env:l})}catch(e){throw await V(r,[`switch`,`--detach`,h]),x=h,u={...u,currentCommit:h},Error(`Database migration failed; the database and preview were restored. ${J(e)}`)}le(e)&&o(),O=void 0,f&&await V(r,[`update-ref`,`-d`,f]),u={...u,currentCommit:g.commit,draft:void 0,proposal:void 0,target:void 0}}catch(e){g?.commit&&x===g.commit&&(await V(r,[`switch`,`--detach`,h]).catch(()=>void 0),x=h);let t=f?` Recovery commit: ${f}.`:``;throw u={...u,currentCommit:x,message:`${J(e)}${t}`},e}};d=ee((e,t)=>{ne(e,t,{action:I,activate:F,getStatus:()=>u,token:c}).catch(n=>{t.headersSent||X(t,400,{error:J(n),status:u}),e.url===`/handshake`&&j(n)})}),await pe(d);let $=d.address();if(!$||typeof $==`string`)throw Error(`Managed dev server failed to listen.`);return{env:{...a,[t]:`http://127.0.0.1:${$.port}`,[e]:c},failure:A,setRuntimeEnv(e){l=e},async close(){f=!0,clearInterval(T),clearTimeout(E);for(let e of D)e.close();try{h&&await H(r,[`rev-parse`,`HEAD`])===await H(r,[`rev-parse`,y])&&await V(r,[`switch`,`main`])}finally{await B(C),await me(d)}}}}async function ne(e,t,n){if(e.headers.authorization!==`Bearer ${n.token}`){X(t,401,{error:`Invalid managed development capability.`});return}if(e.method===`POST`&&e.url===`/handshake`){await n.activate(),X(t,200,{status:n.getStatus()});return}if(e.method===`GET`&&e.url===`/status`){X(t,200,{status:n.getStatus()});return}if(e.method===`POST`&&e.url===`/action`){let r=await Y(e);X(t,200,await n.action(r));return}X(t,404,{error:`Unknown managed development endpoint.`})}async function re(e){let t=await x(e);return{branch:C(await H(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await H(e,[`rev-parse`,`HEAD`]),main:await H(e,[`rev-parse`,y]),primary:t.primary,status:await H(e,[`status`,`--porcelain`])}}function C(e){return e===`HEAD`?void 0:e}async function ie(e,t){let n=[e.gitDir,p.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(v(e,{persistent:!1},t))}catch{}return r}async function w(e){let[t,n,i]=await Promise.all([H(e,[`status`,`--porcelain`,`--untracked-files=no`]),H(e,[`diff`,`HEAD`,`--binary`]),H(e,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),a=K(i).sort(),o=r(`sha256`).update(n),s=[`Tracked changes:`,n];for(let t of a){let n=await l(p.join(e,t));o.update(t).update(n),s.push(`\nUntracked file: ${t}\n`,n.toString(`utf8`))}return{context:s.join(`
|
|
2
2
|
`),fingerprint:o.digest(`hex`),tracked:t.length>0,untracked:a}}async function ae(e,t,n){let{stdout:r}=await m(`codex`,[`exec`,`--ephemeral`,`--ignore-user-config`,`--sandbox`,`read-only`,`--cd`,e,`Return only a concise Conventional Commits message for the supplied working-tree changes. Use a body only when it adds material context.`],{cwd:e,env:t,stdin:{string:n}});return r.trim().replace(/^```(?:text)?\s*|\s*```$/g,``)}async function oe({cwd:e,developerCommit:t,env:n,localMain:r,target:a}){let s=p.resolve(e,await H(e,[`rev-parse`,`--git-common-dir`])),c=p.join(s,`coreframe-managed-dev`);await o(c,{recursive:!0});let l=p.join(c,`integration-${i(8).toString(`hex`)}`),u=!1;try{if(await V(e,[`worktree`,`add`,`--detach`,l,r]),r!==a){let e=await U(l,[`merge-base`,r,a]);u=await T(l,n,e?[`rebase`,`--onto`,a,e]:[`rebase`,`--root`,`--onto`,a],`rebase`)||u}return t&&(u=await T(l,n,[`cherry-pick`,t],`cherry-pick`)||u),{commit:await H(l,[`rev-parse`,`HEAD`]),hadConflicts:u}}finally{await V(e,[`worktree`,`remove`,`--force`,l]).catch(()=>void 0),await d(l,{force:!0,recursive:!0})}}async function T(e,t,n,r){try{return await V(e,n,{env:{GIT_EDITOR:`true`}}),!1}catch(n){let i=await D(e);if(i.length===0)throw n;console.warn(`Git ${r} conflicts occurred; Codex is resolving them.`);try{for(;i.length>0;){await E(e,t,r,i),await V(e,[`diff`,`--check`]),await V(e,[`add`,`--all`]);let n=await D(e);if(n.length>0)throw Error(`Codex left unresolved paths: ${n.join(`, `)}`);try{await V(e,[r,`--continue`],{env:{GIT_EDITOR:`true`}})}catch(t){if(i=await D(e),i.length===0)throw t;continue}i=await D(e)}return!0}catch(t){throw await V(e,[r,`--abort`]).catch(()=>void 0),Error(`Codex could not resolve ${r} conflicts: ${J(t)}`)}}}async function E(e,t,n,r){await m(`codex`,[`exec`,`--ephemeral`,`--ignore-user-config`,`--sandbox`,`workspace-write`,`--cd`,e,`Resolve the current Git ${n} conflicts cleanly. Edit only files needed for the resolution, preserve intended behavior from both sides, remove all conflict markers, and do not stage files or run Git continuation commands. Conflicted paths: ${r.join(`, `)}`],{cwd:e,env:t,stdio:`inherit`})}async function D(e){return K(await H(e,[`diff`,`--name-only`,`--diff-filter=U`,`-z`]))}async function se(e,t){let n=[];for(let r of[`test`,`typecheck`,`lint`])try{await m(q(),[r],{cwd:e,env:t,stdio:`inherit`})}catch(e){n.push(`${r} failed after Codex conflict resolution: ${J(e)}`)}return n}async function ce({config:e,cwd:t,env:n}){if(!e.database)return;let r=await O({config:e,cwd:t,env:n});try{await m(q(),[`db`,`migrate`],{cwd:t,env:n,stdio:`inherit`})}catch(e){throw await r.restore(),e}await r.discard().catch(e=>{console.warn(`Could not remove the managed-development database snapshot: ${J(e)}`)}),await d(r.directory,{force:!0,recursive:!0})}async function O({config:e,cwd:t,env:n}){let r=p.join(t,`.coreframe`,`managed-dev-backups`);await o(r,{recursive:!0});let i=await s(p.join(r,`refresh-`));if(e.database?.dialect===`sqlite`){let e=[`turso.db`,`turso.db-wal`,`turso.db-shm`],n=new Set;for(let r of e)await k(p.join(t,`.coreframe`,r),p.join(i,r))&&n.add(r);return{directory:i,async discard(){},async restore(){for(let r of e){let e=p.join(t,`.coreframe`,r);n.has(r)?await a(p.join(i,r),e):await d(e,{force:!0})}}}}if(!n.DATABASE_URL)throw Error(`DATABASE_URL is required to snapshot local PostgreSQL.`);let c=await A(t);if(c)return j({directory:i,connectionString:n.DATABASE_URL,postgres:c});let l=p.join(i,`database.dump`),u=I(n,n.DATABASE_URL);return await m(`pg_dump`,[`--format=custom`,`--file`,l],{cwd:t,env:u,stdin:`ignore`}),{directory:i,async discard(){},async restore(){await m(`pg_restore`,[`--clean`,`--if-exists`,`--no-owner`,`--dbname`,u.PGDATABASE,l],{cwd:t,env:u,stdin:`ignore`})}}}async function k(e,t){try{return await a(e,t),!0}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e;return!1}}async function A(e){let t=JSON.parse(await l(p.join(e,`package.json`),`utf8`));if(!(!t.dependencies?.pg&&!t.devDependencies?.pg&&!t.optionalDependencies?.pg))try{return await import(g(n(p.join(e,`package.json`)).resolve(`pg`)).href)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`MODULE_NOT_FOUND`)return;throw e}}async function j({directory:e,connectionString:t,postgres:n}){let r=new URL(t),a=decodeURIComponent(r.pathname.slice(1));if(!a)throw Error(`DATABASE_URL must name a PostgreSQL database to snapshot.`);let o=`coreframe_backup_${i(6).toString(`hex`)}`,s=`${o}_failed`,c=new URL(r);c.pathname=a===`postgres`?`/template1`:`/postgres`;let l=new n.Client({connectionString:c.href});await l.connect();try{await N(l,a,!1),await P(l,a),await l.query(`CREATE DATABASE ${F(o)} WITH TEMPLATE ${F(a)}`),await N(l,o,!0)}finally{await N(l,a,!0).catch(()=>void 0),await l.end()}return{directory:e,async discard(){await M(n,c.href,async e=>{await P(e,o),await e.query(`DROP DATABASE ${F(o)}`)})},async restore(){await M(n,c.href,async e=>{await N(e,a,!1),await P(e,a),await e.query(`ALTER DATABASE ${F(a)} RENAME TO ${F(s)}`);try{await e.query(`ALTER DATABASE ${F(o)} RENAME TO ${F(a)}`)}catch(t){throw await e.query(`ALTER DATABASE ${F(s)} RENAME TO ${F(a)}`).catch(()=>void 0),await N(e,a,!0).catch(()=>void 0),t}await P(e,s),await e.query(`DROP DATABASE ${F(s)}`)})}}}async function M(e,t,n){let r=new e.Client({connectionString:t});await r.connect();try{return await n(r)}finally{await r.end()}}async function N(e,t,n){await e.query(`ALTER DATABASE ${F(t)} ALLOW_CONNECTIONS ${n?`true`:`false`}`)}async function P(e,t){await e.query(`SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()`,[t])}function F(e){return`"${e.replaceAll(`"`,`""`)}"`}function I(e,t){let n=new URL(t);return{...e,PGDATABASE:decodeURIComponent(n.pathname.slice(1)),PGHOST:n.hostname,PGPASSWORD:decodeURIComponent(n.password),PGPORT:n.port||`5432`,PGUSER:decodeURIComponent(n.username)}}function L(e){return e.some(e=>p.basename(e)===`package.json`||p.basename(e).endsWith(`lock.yaml`)||p.basename(e)===`pnpm-workspace.yaml`)}function le(e){return e.some(e=>L([e])||/(^|\/)(vite|coreframe|tsconfig|drizzle)\.[^/]+$/.test(e)||/(^|\/)(drizzle|scripts|src\/api|tauri)(\/|$)/.test(e))}async function ue(e,t,n){return{commit:t,shortCommit:t.slice(0,12),source:n,subject:await H(e,[`show`,`-s`,`--format=%s`,t])}}async function R(e){try{let t=await c(e,`wx`);await t.writeFile(`${_.pid}\n`),await t.close()}catch(t){if(!(t instanceof Error&&`code`in t&&t.code===`EEXIST`))throw t;let n=(await l(e,`utf8`).catch(()=>`unknown`)).trim(),r=Number(n);if(Number.isInteger(r)&&!z(r)){await f(e).catch(()=>void 0),await R(e);return}throw Error(`Managed development is already owned by PID ${n}.`)}}function z(e){try{return _.kill(e,0),!0}catch(e){return!(e instanceof Error&&`code`in e&&e.code===`ESRCH`)}}async function B(e){e&&(await l(e,`utf8`).catch(()=>void 0))?.trim()===String(_.pid)&&await f(e).catch(()=>void 0)}async function V(e,t,{env:n}={}){return m(`git`,t,{cwd:e,env:n,stdin:`ignore`})}async function H(e,t){return(await V(e,t)).stdout.trim()}async function U(e,t){try{return await H(e,t)||void 0}catch(e){if(e instanceof h&&e.exitCode&&e.exitCode>0)return;throw e}}async function W(e,t,n){try{return await V(e,[`merge-base`,`--is-ancestor`,t,n]),!0}catch(e){if(e instanceof h&&e.exitCode===1)return!1;throw e}}function G(e,t){return e.length===t.length&&[...e].sort().every((e,n)=>e===[...t].sort()[n])}function K(e){return e.split(`\0`).filter(Boolean)}function de(e){return e.split(/\r?\n/,1)[0]??``}function fe(e){return e.type===`message`?`Generating commit message`:e.type===`apply`?`Integrating accepted update`:e.type===`prepare`?`Reviewing working tree`:`Aborting refresh`}function q(){return _.platform===`win32`?`pnpm.cmd`:`pnpm`}function J(e){return e instanceof Error?e.message:String(e)}async function Y(e){let t=``;for await(let n of e)if(t+=String(n),t.length>1e6)throw Error(`Managed development request is too large.`);return t?JSON.parse(t):{}}function X(e,t,n){let r=JSON.stringify(n);e.statusCode=t,e.setHeader(`Content-Type`,`application/json`),e.setHeader(`Content-Length`,Buffer.byteLength(r)),e.end(r)}async function pe(e){await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)})}async function me(e){e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}export{b as isPrimaryGitCheckout,S as startManagedDevSession};
|