@coreframe/dev 0.1.29 → 3.0.0-beta.1
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/bamboo-codegen.js +1 -0
- package/dist/managed-dev.d.ts +2 -2
- package/dist/managed-dev.js +7 -7
- package/dist/supervisor.js +1 -1
- package/package.json +6 -6
- package/dist/panda-codegen.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"node:process";import{access as t,mkdir as n,readFile as r,readdir as i,writeFile as a}from"node:fs/promises";import{createHash as o}from"node:crypto";import s from"node:path";import c from"nano-spawn";const l=/^bamboo\.config\.(?:[cm]?[jt]sx?)$/,u=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`],d=new Set([`.coreframe`,`.git`,`.react-router`,`.wrangler`,`.wxt`,`build`,`dist`,`node_modules`,`platforms`,`styled-system`,`target`]),f=`.coreframe/bamboo-codegen.json`;async function p({cwd:t=e.cwd(),env:r=e.env,runCodegen:i=()=>m(t,r)}={}){let o=await h(t);if(o.length===0)return{applicable:!1,ran:!1};let c=await _(t,o),l=await x(t);if(l?.schemaVersion===1&&l.fingerprint===c&&await S(t,o))return{applicable:!0,fingerprint:c,ran:!1};if(await i(),!await S(t,o))throw Error(`Bamboo codegen completed without producing the expected generated output.`);return await n(s.dirname(s.join(t,f)),{recursive:!0}),await a(s.join(t,f),`${JSON.stringify({fingerprint:c,schemaVersion:1})}\n`,{mode:384}),{applicable:!0,fingerprint:c,ran:!0}}async function m(t,n){await c(e.platform===`win32`?`pnpm.cmd`:`pnpm`,[`codegen`],{cwd:t,env:n})}async function h(e){let t=[];return await g(e,``,t),t.sort((e,t)=>e.path.localeCompare(t.path)),t}async function g(e,t,n){let a=await i(e,{withFileTypes:!0});for(let i of a){let a=t?s.join(t,i.name):i.name;if(i.isDirectory()){d.has(i.name)||await g(s.join(e,i.name),a,n);continue}if(i.isFile()&&l.test(i.name)){let t=await r(s.join(e,i.name),`utf8`);n.push({content:t,path:a})}}}async function _(e,t){let n=await v(e);return o(`sha256`).update(JSON.stringify({dependencies:n,configs:t.map(({content:e,path:t})=>({content:e,path:t})),schemaVersion:1})).digest(`hex`)}async function v(e){let t=JSON.parse(await r(s.join(e,`package.json`),`utf8`)),n=[];for(let r of u){let i=t[r];if(!(!i||typeof i!=`object`||Array.isArray(i)))for(let t of Object.keys(i).sort())y(t)&&n.push({name:t,section:r,spec:i[t],version:await b(e,t)})}return n}function y(e){return e===`bamboo`||e.startsWith(`@bamboocss/`)||/bamboo/i.test(e)}async function b(e,t){try{return JSON.parse(await r(s.join(e,`node_modules`,t,`package.json`),`utf8`)).version}catch{return}}async function x(e){try{let t=JSON.parse(await r(s.join(e,f),`utf8`));if(!t||typeof t!=`object`)return;let n=t;return typeof n.fingerprint==`string`&&typeof n.schemaVersion==`number`?{fingerprint:n.fingerprint,schemaVersion:n.schemaVersion}:void 0}catch{return}}async function S(e,t){return(await Promise.all(t.map(t=>C(e,t)))).every(Boolean)}async function C(e,n){let r=w(e,n);try{return await Promise.all([t(s.join(r,`css/index.js`)),t(s.join(r,`types/index.d.ts`))]),!0}catch{return!1}}function w(e,t){let n=/\boutdir\s*:\s*["'`]([^"'`]+)["'`]/s.exec(t.content)?.[1];return s.resolve(e,s.dirname(t.path),n??`styled-system`)}export{f as bambooCodegenStateFile,p as ensureBambooCodegen};
|
package/dist/managed-dev.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ type ManagedDevSessionOptions = {
|
|
|
8
8
|
cwd?: string;
|
|
9
9
|
env?: NodeJS.ProcessEnv;
|
|
10
10
|
localCheckInterval?: number;
|
|
11
|
-
|
|
11
|
+
onNativeRestart?(): Promise<void> | void;
|
|
12
12
|
onRestart?(): void;
|
|
13
13
|
onStatusChange?(status: ManagedDevStatus): void;
|
|
14
14
|
remoteCheckInterval?: number;
|
|
@@ -39,7 +39,7 @@ declare function startManagedDevSession({
|
|
|
39
39
|
cwd,
|
|
40
40
|
env,
|
|
41
41
|
localCheckInterval,
|
|
42
|
-
|
|
42
|
+
onNativeRestart,
|
|
43
43
|
onRestart,
|
|
44
44
|
onStatusChange,
|
|
45
45
|
remoteCheckInterval,
|
package/dist/managed-dev.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{managedDevCodexArgs as e,managedDevCodexAuthor as t,managedDevCodexHighArgs as n,requireManagedDevCodexOptions as r}from"./codex-model.js";import{ensurePandaCodegen as i}from"./panda-codegen.js";import a from"node:process";import{access as o,copyFile as s,mkdir as c,mkdtemp as l,open as u,readFile as d,realpath as f,rm as p,unlink as m,writeFile as h}from"node:fs/promises";import{pathToFileURL as g}from"node:url";import{createHash as _,randomBytes as v}from"node:crypto";import{constants as y,watch as b}from"node:fs";import x from"node:path";import{stripVTControlCharacters as S}from"node:util";import{managedDevCodexEfforts as C,managedDevCodexModels as w}from"@coreframe/dev-contracts/managed-dev";import{resolve as T}from"import-meta-resolve";import E,{SubprocessError as D}from"nano-spawn";const O=`refs/heads/main`,k=`refs/heads/dev`,ee=`refs/remotes/origin/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i,ne=`coreframe-managed-dev-codex-completion.json`,re=`coreframe-managed-dev-codex-options.json`,ie=`coreframe-managed-dev-setup-failure.json`;async function A(e=a.cwd()){let t=await fe(e);return t.primary&&t.branch===`main`&&t.head===t.main}async function j(e=a.cwd()){try{let{commonDir:t,gitDir:n}=await M(e);return n===t}catch{return!1}}async function M(e){let t=await f(await Z(e,[`rev-parse`,`--show-toplevel`])),n=await f(e),r=x.resolve(n,await Z(e,[`rev-parse`,`--git-dir`])),i=x.resolve(n,await Z(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function N({config:e,cwd:t=a.cwd(),env:n=a.env,localCheckInterval:o=1e3,onFlutterRestart:s=()=>void 0,onRestart:c=()=>void 0,onStatusChange:l=()=>void 0,remoteCheckInterval:u=6e4,runCheck:d=e=>Se(t,n,e),watchState:f=pe}){let p=n,g={mode:`waiting`,warnings:[]},_=!1,y=!1,b=!1,S,C,w=!1,T,D,A,j,M,N,oe=[],P,ce,le=Promise.resolve(),F=()=>{_||l(g)},I=async({fetch:e=!1}={})=>{if(!(!y||_||!D)){if(b){w=!0;return}try{let[n,r,i]=await Promise.all([Z(t,[`rev-parse`,`--abbrev-ref`,`HEAD`]),Z(t,[`rev-parse`,`HEAD`]),Z(t,[`rev-parse`,O])]);if(n!==`main`||r!==i){g={message:`Managed synchronization is paused until the primary checkout is back on local main.`,mode:`waiting`,warnings:[]};return}r!==T&&(T=r,P=void 0);let a=await L(t);if(a.tracked||a.untracked.length>0){g={...g,currentCommit:T,draft:a,message:void 0,mode:`managed`,proposal:V(a.fingerprint),target:void 0};return}if(e&&await Q(t,[`remote`,`get-url`,`origin`]))try{await X(t,[`fetch`,`origin`,`+refs/heads/main:${ee}`])}catch{}let o=await Q(t,[`rev-parse`,k]),s=await Q(t,[`rev-parse`,ee]),c=[...o?[{commit:o,source:`dev`}]:[],...s?[{commit:s,source:`upstream`}]:[]],l;for(let e of c)if(!await Le(t,e.commit,T)){l=e;break}g={...g,currentCommit:T,draft:void 0,message:void 0,mode:`managed`,proposal:void 0,target:l===void 0?void 0:await Ne(t,T,l.commit,l.source)}}catch(e){g={...g,message:$(e),warnings:[$(e)]}}finally{F()}}},R=()=>{clearTimeout(N),N=setTimeout(()=>void I(),50),N.unref()},ve=(e,t)=>{let n=async()=>{let n=[{command:`pnpm typecheck`,status:`running`},{command:`pnpm test`,status:`pending`}],r=()=>{g={...g,checks:{commit:e,commands:structuredClone(n),trigger:t}},F()};r();for(let[e,t]of[`typecheck`,`test`].entries()){e>0&&(n[e].status=`running`,r());try{await d(t),n[e].status=`passed`}catch(t){n[e].status=`failed`,n[e].failureId=v(12).toString(`hex`),n[e].output=Ce(t)}r()}};le=le.then(n,n)},ye=async()=>{if(y||_)return;let e=await fe(t);if(!e.primary){g={message:`Managed development only runs from the primary checkout.`,mode:`unmanaged`,warnings:[]},F();return}if(e.branch!==`main`||e.head!==e.main){let t=`Managed development requires the primary checkout on local main; current branch is ${e.branch??`detached HEAD`}.`;console.warn(`Coreframe managed development disabled: ${t}`),g={message:t,mode:`unmanaged`,warnings:[]},F();return}A=x.join(e.commonDir,`coreframe-managed-dev.lock`),await Pe(A),await Q(t,[`rev-parse`,`--verify`,k])||await X(t,[`branch`,`dev`,e.head]),D=e,T=e.head,y=!0,g={codexCompletion:await se(e.commonDir),codexOptions:await ae(e.commonDir),currentCommit:e.head,mode:`managed`,setupFailure:await de(e.commonDir,e.head),warnings:[]},g.setupFailure||await W({commit:e.head,flutterRestartRequired:!1,restartRequired:!1}),F(),oe=await f(e,R),j=setInterval(()=>{g.draft&&I()},o),j.unref(),M=setInterval(()=>void I({fetch:!0}),u),M.unref(),await I(),I({fetch:!0})},be=async(e,{onCodexEvent:n=()=>void 0}={})=>{if(!y||g.mode!==`managed`)throw Error(`Managed development is not active.`);if(e.type===`cancel-codex`){let e=S;if(!e)throw Error(`There is no Codex conflict resolution to cancel.`);return e(),{status:g}}if(b)throw Error(`Another managed development action is already running.`);let i=[],a=[],o,s,c=e=>{e.phase===`start`?(a=e.commits,o=e.totalCommits,i.splice(0,i.length,e.message)):e.phase===`message`?i.push(e.message):e.phase===`complete`?s=e.finalMessage:e.phase===`progress`&&(a=e.commits,o=e.totalCommits??o),n(e)};b=!0,g={...g,busy:Ve(e),message:void 0};try{if(F(),e.type===`acknowledge-codex`)g.codexCompletion?.id===e.id&&await Ue();else if(e.type===`dismiss-check`)g.checks&&(g={...g,checks:{...g.checks,commands:g.checks.commands.map(t=>t.failureId===e.failureId?{...t,dismissed:!0}:t)}});else if(e.type===`reject`)g={...g,draft:void 0,proposal:void 0};else if(e.type===`configure-codex`)await Fe(r(e.codex));else if(e.type===`decline-rebase`){if(!g.pendingRebase)throw Error(`There is no pending rebase to decline.`);g={...g,pendingRebase:void 0}}else if(e.type===`resolve-rebase`){let t=g.pendingRebase;if(!t)throw Error(`There is no pending rebase to resolve.`);await U({codex:e.codex,codexApproved:!0,onCodexEvent:c,source:t.target.source,target:t.target.commit})}else if(e.type===`prepare`){let n=B(e.target),r=await L(t);r.tracked||r.untracked.length>0?g={...g,draft:r,proposal:V(r.fingerprint)}:await U({codex:e.codex,onCodexEvent:c,source:n.source,target:e.target})}else if(e.type===`message`){let n=await H(e.fingerprint,e.untracked),r=V(n.fingerprint);if(r===void 0){try{if(ce??=he(`codex`,p),!await ce)throw Error("Codex CLI is not installed or is unavailable on PATH. Install it with `npm install -g @openai/codex`, then restart the dev server.");r=await me(t,p,n.untracked)}catch(e){r=``,g={...g,warnings:[...g.warnings,`Codex could not generate a commit message: ${$(e)}`]}}P={fingerprint:n.fingerprint,message:r}}g={...g,draft:n,proposal:r}}else if(e.type===`commit`){let t=await xe(e);g={...g,currentCommit:t,draft:void 0,message:void 0,proposal:void 0,target:void 0},R()}else if(e.type===`retry-install`)await Te();else if(e.type===`retry-codegen`)await Ee();else if(e.type===`reset-database`)await De();else{let n=B(e.target),r=await L(t);if(r.tracked||r.untracked.length>0){if(!e.fingerprint||!e.untracked)throw Error(`Refresh requires the current working-tree confirmation.`);if(await H(e.fingerprint,e.untracked),!e.message||!te.test(Be(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await U({codex:e.codex,fingerprint:e.fingerprint,message:e.message,onCodexEvent:c,source:n.source,target:e.target,untracked:e.untracked})}}finally{b=!1,g={...g,busy:void 0},F(),w&&(w=!1,R())}return s&&await ke(s,i,a,o),{status:g}},B=e=>{if(!g.target||g.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`);return g.target},V=e=>P?.fingerprint===e?P.message:void 0,H=async(e,n)=>{let r=await L(t);if(r.fingerprint!==e)throw P=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!Re(r.untracked,n))throw Error(`Include every untracked file or remove it before refreshing.`);return r},xe=async({fingerprint:e,message:n,untracked:r})=>{let i=await H(e,r);if(!n||!te.test(Be(n)))throw Error(`Enter a commit message with a valid Conventional Commits header.`);await X(t,[`add`,`--update`]),i.untracked.length>0&&await X(t,[`add`,`--`,...r]),await X(t,[`commit`,`--message`,n],{env:{GIT_EDITOR:`true`}});let a=await Z(t,[`rev-parse`,`HEAD`]);return T=a,P=void 0,a},U=async({codex:e,codexApproved:n=!1,fingerprint:i,message:a,onCodexEvent:o=()=>void 0,source:s,target:c,untracked:l=[]})=>{let u=r(e);e&&await Fe(u);let d=n&&g.pendingRebase?.target.commit===c?g.pendingRebase:void 0;d?g={...g,pendingRebase:void 0}:B(c);let f=await Z(t,[`rev-parse`,`HEAD`]),m,h,_=await L(t);if(_.tracked||_.untracked.length>0){if(!i||_.fingerprint!==i||!Re(_.untracked,l))throw Error(`Working-tree changes changed; review them before refreshing.`);await X(t,[`add`,`--update`]),l.length>0&&await X(t,[`add`,`--`,...l]),await X(t,[`commit`,`--message`,a],{env:{GIT_EDITOR:`true`}}),m=await Z(t,[`rev-parse`,`HEAD`]),T=m,h=`refs/coreframe/recovery/${Date.now()}-${m.slice(0,12)}`,await X(t,[`update-ref`,h,m])}let v=m??f,y,b=new AbortController;S=()=>b.abort();try{try{y=await ge({codex:u,codexApproved:n,cwd:t,env:p,localMain:v,onCodexEvent:o,resume:d,signal:b.signal,source:s,target:c})}finally{S=void 0}if(z(b.signal),await Z(t,[`rev-parse`,`HEAD`])!==v)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await Z(t,[`rev-parse`,O])!==v)throw Error(`Local main changed while the accepted update was being prepared.`);let e=y.pause?{applied:y.pause.applied,commits:y.pause.commits,files:y.pause.files,target:await Ne(t,v,c,s)}:void 0,r=y.commit;if(r===void 0){g={...g,pendingRebase:e},h&&await X(t,[`update-ref`,`-d`,h]);return}await _e(t,{commit:r,devTarget:y.devTarget},v),w=!0,T=r,await X(t,[`reset`,`--hard`,r]);let i=ze(await Z(t,[`diff`,`--name-only`,`-z`,f,r])),a=je(i),l=Me(i);P=void 0,e&&h&&(C=h,h=void 0),h&&await X(t,[`update-ref`,`-d`,h]),C&&!y.pause&&(await X(t,[`update-ref`,`-d`,C]),C=void 0),g={...g,currentCommit:r,draft:void 0,pendingRebase:e,proposal:void 0,setupFailure:void 0,target:void 0},await G({installDependencies:Ae(i),flutterRestartRequired:l,restartRequired:a,trigger:`synchronization`})}catch(e){let t=h?` Recovery commit: ${h}.`:``;throw g={...g,currentCommit:T,message:`${$(e)}${t}`,pendingRebase:d??g.pendingRebase},e}},W=async({commit:e,flutterRestartRequired:n,restartRequired:r})=>{try{return await i({cwd:t,env:p}),!0}catch(t){return await q({command:`pnpm codegen`,commit:e,error:t,message:`Panda generated code could not be prepared. Fix the Panda configuration or dependencies, then retry codegen.`,flutterRestartRequired:n,restartRequired:r,stage:`codegen`}),!1}},G=async({flutterRestartRequired:n,installDependencies:r,restartRequired:i,trigger:a})=>{let o=T;if(r)try{await Oe([`install`,`--frozen-lockfile`])}catch(e){await q({command:`pnpm install --frozen-lockfile`,commit:o,error:e,message:`The project was synchronized, but dependency installation failed. Fix the package or lockfile issue, then retry the install.`,flutterRestartRequired:n,restartRequired:i,stage:`dependencies`});return}if(await W({commit:o,flutterRestartRequired:n,restartRequired:i})){try{await we({config:e,cwd:t,env:p})}catch(e){await q({command:`pnpm db migrate-local`,commit:o,error:e,message:`The project was synchronized, but its database migration failed. The previous database was restored. Reset the database to recreate the current schema and rerun seed scripts.`,flutterRestartRequired:n,restartRequired:i,stage:`migration`});return}await J(),ve(o,a),n&&await s(),i&&c()}},Te=async()=>{let e=K(`dependencies`);await J(),await G({flutterRestartRequired:e.flutterRestartRequired===!0,installDependencies:!0,restartRequired:e.restartRequired,trigger:`dependency-recovery`})},Ee=async()=>{let e=K(`codegen`);await J(),await G({flutterRestartRequired:e.flutterRestartRequired===!0,installDependencies:!1,restartRequired:e.restartRequired,trigger:`codegen-recovery`})},De=async()=>{let e=K(`migration`);try{await Oe([`db`,`setup`])}catch(t){await q({command:`pnpm db setup`,commit:e.commit,error:t,message:`The project remains synchronized, but the database reset failed. Review the diagnostics, fix the reported problem, and try the reset again.`,flutterRestartRequired:e.flutterRestartRequired===!0,restartRequired:e.restartRequired,stage:`migration`});return}await J(),ve(e.commit,`database-recovery`),e.flutterRestartRequired===!0&&await s(),e.restartRequired&&c()},K=e=>{if(!g.setupFailure||g.setupFailure.stage!==e)throw Error(`There is no failed ${e} setup step to recover.`);return g.setupFailure},Oe=async e=>{await E(He(),e,{cwd:t,env:p})},q=async({command:e,commit:t,error:n,flutterRestartRequired:r,message:i,restartRequired:a,stage:o})=>{let s=Ce(n).slice(-1e5),c={command:e,commit:t,message:i,output:s,...r?{flutterRestartRequired:!0}:void 0,restartRequired:a,stage:o};g={...g,setupFailure:c,target:void 0},console.error(`Coreframe managed development setup failed (${e}): ${i}\n${s}`);let l=Y();l&&await h(l,`${JSON.stringify(c)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development setup failure: ${$(e)}`)})},J=async()=>{g={...g,setupFailure:void 0};let e=Y();e&&await m(e).catch(e=>{e instanceof Error&&`code`in e&&e.code===`ENOENT`||console.warn(`Could not clear the managed-development setup failure: ${$(e)}`)})},Y=()=>D?x.join(D.commonDir,ie):void 0,ke=async(e,t,n,r)=>{let i={commits:n,finalMessage:e,id:v(16).toString(`hex`),messages:ue(t),...r===void 0?void 0:{totalCommits:r}};g={...g,codexCompletion:i},D&&await h(x.join(D.commonDir,ne),`${JSON.stringify(i)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex result: ${$(e)}`)}),F()},Fe=async e=>{g={...g,codexOptions:e},D&&await h(x.join(D.commonDir,re),`${JSON.stringify(e)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex options: ${$(e)}`)})},Ue=async()=>{g={...g,codexCompletion:void 0},D&&await m(x.join(D.commonDir,ne)).catch(e=>{if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e})};return{action:be,activate:ye,getStatus:()=>g,async close(){if(!_){_=!0,clearInterval(j),clearInterval(M),clearTimeout(N);for(let e of oe)e.close();await Ie(A)}}}}async function ae(e){let t=x.join(e,re);try{let e=JSON.parse(await d(t,`utf8`));if(oe(e))return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development Codex options: ${$(e)}`)}await m(t).catch(()=>void 0)}function oe(e){if(!e||typeof e!=`object`)return!1;let{effort:t,model:n}=e;return(t===void 0||C.includes(t))&&(n===void 0||w.includes(n))}async function se(e){let t=x.join(e,ne);try{let e=JSON.parse(await d(t,`utf8`));if(P(e))return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development Codex result: ${$(e)}`)}await m(t).catch(()=>void 0)}function P(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.finalMessage==`string`&&typeof t.id==`string`&&Array.isArray(t.messages)&&t.messages.every(le)&&(t.totalCommits===void 0||Number.isInteger(t.totalCommits)&&t.totalCommits>=0)&&(t.commits===void 0||Array.isArray(t.commits)&&t.commits.every(ce))}function ce(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.commit==`string`&&typeof t.shortCommit==`string`&&typeof t.subject==`string`}function le(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.kind===`agent`||t.kind===`thought`||t.kind===`user`)&&(t.author===void 0||typeof t.author==`string`)&&typeof t.text==`string`}function ue(e){let t=new Set(e.filter(e=>e.kind===`user`)),n=[...t].reduce((e,t)=>e+t.text.length,0),r=!1;for(let i of[...e].reverse())if(i.kind!==`user`){if(n+i.text.length>1e5&&r)break;t.add(i),r=!0,n+=i.text.length}return e.filter(e=>t.has(e))}async function de(e,t){let n=x.join(e,ie);try{let e=JSON.parse(await d(n,`utf8`));if(F(e)&&e.commit===t)return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development setup failure: ${$(e)}`)}await m(n).catch(()=>void 0)}function F(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.command===`pnpm codegen`||t.command===`pnpm db migrate-local`||t.command===`pnpm db setup`||t.command===`pnpm install --frozen-lockfile`)&&typeof t.commit==`string`&&typeof t.message==`string`&&typeof t.output==`string`&&(t.flutterRestartRequired===void 0||typeof t.flutterRestartRequired==`boolean`)&&typeof t.restartRequired==`boolean`&&(t.stage===`codegen`||t.stage===`dependencies`||t.stage===`migration`)}async function fe(e){let t=await M(e);return{branch:I(await Z(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await Z(e,[`rev-parse`,`HEAD`]),main:await Z(e,[`rev-parse`,O]),primary:t.primary}}function I(e){return e===`HEAD`?void 0:e}async function pe(e,t){let n=[e.gitDir,x.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(b(e,{persistent:!1},t))}catch{}return r}async function L(e){let[t,n,r]=await Promise.all([Z(e,[`status`,`--porcelain`,`--untracked-files=no`]),Z(e,[`diff`,`HEAD`,`--binary`]),Z(e,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),i=ze(r).sort(),a=_(`sha256`).update(n);for(let e of i)a.update(`\0`).update(e);return{fingerprint:a.digest(`hex`),tracked:t.length>0,untracked:i}}async function me(e,t,r){let i=[`Tracked changes:`,await Z(e,[`diff`,`HEAD`,`--binary`])];for(let t of r){let n=await d(x.join(e,t));i.push(`\nUntracked file: ${t}\n`,n.toString(`utf8`))}let{stdout:a}=await E(`codex`,[`exec`,...n,`--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,stderr:`ignore`,stdin:{string:i.join(`
|
|
2
|
-
`)}});return a.trim().replace(/^```(?:text)?\s*|\s*```$/g,``)}async function
|
|
3
|
-
`)}\n`}})};try{await r(!0)}catch(i){if(!t.devTarget)throw i;let a;try{a=await Promise.all([Z(e,[`rev-parse`,
|
|
4
|
-
`).trim();throw t?Error(`${$(e)}\n${t}`):e}finally{s?.removeEventListener(`abort`,d)}return l}async function
|
|
5
|
-
`).map(e=>{let[t,n=``]=e.split(`\0`,2);return{commit:t,shortCommit:t.slice(0,12),subject:n}}):[]}function
|
|
6
|
-
`):void 0}async function
|
|
7
|
-
`).filter(Boolean).map(e=>{let[t,n]=e.split(`\0`);return{commit:t,shortCommit:t.slice(0,12),subject:n}}),shortCommit:n.slice(0,12),source:r,subject:await Z(e,[`show`,`-s`,`--format=%s`,n])}}async function
|
|
1
|
+
import{ensureBambooCodegen as e}from"./bamboo-codegen.js";import{managedDevCodexArgs as t,managedDevCodexAuthor as n,managedDevCodexHighArgs as r,requireManagedDevCodexOptions as i}from"./codex-model.js";import a from"node:process";import{access as o,copyFile as s,mkdir as c,mkdtemp as l,open as u,readFile as d,realpath as f,rm as p,unlink as m,writeFile as h}from"node:fs/promises";import{pathToFileURL as g}from"node:url";import{createHash as _,randomBytes as v}from"node:crypto";import{constants as y,watch as b}from"node:fs";import x from"node:path";import{stripVTControlCharacters as S}from"node:util";import{managedDevCodexEfforts as C,managedDevCodexModels as w,managedDevNativeRestartRootsEnv as T}from"@coreframe/dev-contracts/managed-dev";import{resolve as E}from"import-meta-resolve";import D,{SubprocessError as O}from"nano-spawn";const k=`refs/heads/main`,A=`refs/heads/dev`,ee=`refs/remotes/origin/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i,ne=`coreframe-managed-dev-codex-completion.json`,re=`coreframe-managed-dev-codex-options.json`,ie=`coreframe-managed-dev-setup-failure.json`;async function ae(e=a.cwd()){let t=await pe(e);return t.primary&&t.branch===`main`&&t.head===t.main}async function j(e=a.cwd()){try{let{commonDir:t,gitDir:n}=await M(e);return n===t}catch{return!1}}async function M(e){let t=await f(await Z(e,[`rev-parse`,`--show-toplevel`])),n=await f(e),r=x.resolve(n,await Z(e,[`rev-parse`,`--git-dir`])),i=x.resolve(n,await Z(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function oe({config:t,cwd:n=a.cwd(),env:r=a.env,localCheckInterval:o=1e3,onNativeRestart:s=()=>void 0,onRestart:c=()=>void 0,onStatusChange:l=()=>void 0,remoteCheckInterval:u=6e4,runCheck:d=e=>Se(n,r,e),watchState:f=me}){let p=r,g={mode:`waiting`,warnings:[]},_=!1,y=!1,b=!1,S,C,w=!1,T,E,O,ae,j,M,oe=[],N,le,ue=Promise.resolve(),P=()=>{_||l(g)},F=async({fetch:e=!1}={})=>{if(!(!y||_||!E)){if(b){w=!0;return}try{let[t,r,i]=await Promise.all([Z(n,[`rev-parse`,`--abbrev-ref`,`HEAD`]),Z(n,[`rev-parse`,`HEAD`]),Z(n,[`rev-parse`,k])]);if(t!==`main`||r!==i){g={message:`Managed synchronization is paused until the primary checkout is back on local main.`,mode:`waiting`,warnings:[]};return}r!==T&&(T=r,N=void 0);let a=await L(n);if(a.tracked||a.untracked.length>0){g={...g,currentCommit:T,draft:a,message:void 0,mode:`managed`,proposal:V(a.fingerprint),target:void 0};return}if(e&&await Q(n,[`remote`,`get-url`,`origin`]))try{await X(n,[`fetch`,`origin`,`+refs/heads/main:${ee}`])}catch{}let o=await Q(n,[`rev-parse`,A]),s=await Q(n,[`rev-parse`,ee]),c=[...o?[{commit:o,source:`dev`}]:[],...s?[{commit:s,source:`upstream`}]:[]],l;for(let e of c)if(!await ze(n,e.commit,T)){l=e;break}g={...g,currentCommit:T,draft:void 0,message:void 0,mode:`managed`,proposal:void 0,target:l===void 0?void 0:await Fe(n,T,l.commit,l.source)}}catch(e){g={...g,message:$(e),warnings:[$(e)]}}finally{P()}}},I=()=>{clearTimeout(M),M=setTimeout(()=>void F(),50),M.unref()},R=(e,t)=>{let n=async()=>{let n=[{command:`pnpm typecheck`,status:`running`},{command:`pnpm test`,status:`pending`}],r=()=>{g={...g,checks:{commit:e,commands:structuredClone(n),trigger:t}},P()};r();for(let[e,t]of[`typecheck`,`test`].entries()){e>0&&(n[e].status=`running`,r());try{await d(t),n[e].status=`passed`}catch(t){n[e].status=`failed`,n[e].failureId=v(12).toString(`hex`),n[e].output=Ce(t)}r()}};ue=ue.then(n,n)},ye=async()=>{if(y||_)return;let e=await pe(n);if(!e.primary){g={message:`Managed development only runs from the primary checkout.`,mode:`unmanaged`,warnings:[]},P();return}if(e.branch!==`main`||e.head!==e.main){let t=`Managed development requires the primary checkout on local main; current branch is ${e.branch??`detached HEAD`}.`;console.warn(`Coreframe managed development disabled: ${t}`),g={message:t,mode:`unmanaged`,warnings:[]},P();return}O=x.join(e.commonDir,`coreframe-managed-dev.lock`),await Ie(O),await Q(n,[`rev-parse`,`--verify`,A])||await X(n,[`branch`,`dev`,e.head]),E=e,T=e.head,y=!0,g={codexCompletion:await ce(e.commonDir),codexOptions:await se(e.commonDir),currentCommit:e.head,mode:`managed`,setupFailure:await fe(e.commonDir,e.head),warnings:[]},g.setupFailure||await xe({commit:e.head,nativeRestartRequired:!1,restartRequired:!1}),P(),oe=await f(e,I),ae=setInterval(()=>{g.draft&&F()},o),ae.unref(),j=setInterval(()=>void F({fetch:!0}),u),j.unref(),await F(),F({fetch:!0})},be=async(e,{onCodexEvent:t=()=>void 0}={})=>{if(!y||g.mode!==`managed`)throw Error(`Managed development is not active.`);if(e.type===`cancel-codex`){let e=S;if(!e)throw Error(`There is no Codex conflict resolution to cancel.`);return e(),{status:g}}if(b)throw Error(`Another managed development action is already running.`);let r=[],a=[],o,s,c=e=>{e.phase===`start`?(a=e.commits,o=e.totalCommits,r.splice(0,r.length,e.message)):e.phase===`message`?r.push(e.message):e.phase===`complete`?s=e.finalMessage:e.phase===`progress`&&(a=e.commits,o=e.totalCommits??o),t(e)};b=!0,g={...g,busy:Ue(e),message:void 0};try{if(P(),e.type===`acknowledge-codex`)g.codexCompletion?.id===e.id&&await Pe();else if(e.type===`dismiss-check`)g.checks&&(g={...g,checks:{...g.checks,commands:g.checks.commands.map(t=>t.failureId===e.failureId?{...t,dismissed:!0}:t)}});else if(e.type===`reject`)g={...g,draft:void 0,proposal:void 0};else if(e.type===`configure-codex`)await Ae(i(e.codex));else if(e.type===`decline-rebase`){if(!g.pendingRebase)throw Error(`There is no pending rebase to decline.`);g={...g,pendingRebase:void 0}}else if(e.type===`resolve-rebase`){let t=g.pendingRebase;if(!t)throw Error(`There is no pending rebase to resolve.`);await W({codex:e.codex,codexApproved:!0,onCodexEvent:c,source:t.target.source,target:t.target.commit})}else if(e.type===`prepare`){let t=B(e.target),r=await L(n);r.tracked||r.untracked.length>0?g={...g,draft:r,proposal:V(r.fingerprint)}:await W({codex:e.codex,onCodexEvent:c,source:t.source,target:e.target})}else if(e.type===`message`){let t=await H(e.fingerprint,e.untracked),r=V(t.fingerprint);if(r===void 0){try{if(le??=ge(`codex`,p),!await le)throw Error("Codex CLI is not installed or is unavailable on PATH. Install it with `npm install -g @openai/codex`, then restart the dev server.");r=await he(n,p,t.untracked)}catch(e){r=``,g={...g,warnings:[...g.warnings,`Codex could not generate a commit message: ${$(e)}`]}}N={fingerprint:t.fingerprint,message:r}}g={...g,draft:t,proposal:r}}else if(e.type===`commit`){let t=await U(e);g={...g,currentCommit:t,draft:void 0,message:void 0,proposal:void 0,target:void 0},I()}else if(e.type===`retry-install`)await we();else if(e.type===`retry-codegen`)await Ee();else if(e.type===`reset-database`)await De();else{let t=B(e.target),r=await L(n);if(r.tracked||r.untracked.length>0){if(!e.fingerprint||!e.untracked)throw Error(`Refresh requires the current working-tree confirmation.`);if(await H(e.fingerprint,e.untracked),!e.message||!te.test(He(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await W({codex:e.codex,fingerprint:e.fingerprint,message:e.message,onCodexEvent:c,source:t.source,target:e.target,untracked:e.untracked})}}finally{b=!1,g={...g,busy:void 0},P(),w&&(w=!1,I())}return s&&await Y(s,r,a,o),{status:g}},B=e=>{if(!g.target||g.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`);return g.target},V=e=>N?.fingerprint===e?N.message:void 0,H=async(e,t)=>{let r=await L(n);if(r.fingerprint!==e)throw N=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!Be(r.untracked,t))throw Error(`Include every untracked file or remove it before refreshing.`);return r},U=async({fingerprint:e,message:t,untracked:r})=>{let i=await H(e,r);if(!t||!te.test(He(t)))throw Error(`Enter a commit message with a valid Conventional Commits header.`);await X(n,[`add`,`--update`]),i.untracked.length>0&&await X(n,[`add`,`--`,...r]),await X(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}});let a=await Z(n,[`rev-parse`,`HEAD`]);return T=a,N=void 0,a},W=async({codex:e,codexApproved:t=!1,fingerprint:a,message:o,onCodexEvent:s=()=>void 0,source:c,target:l,untracked:u=[]})=>{let d=i(e);e&&await Ae(d);let f=t&&g.pendingRebase?.target.commit===l?g.pendingRebase:void 0;f?g={...g,pendingRebase:void 0}:B(l);let m=await Z(n,[`rev-parse`,`HEAD`]),h,_,v=await L(n);if(v.tracked||v.untracked.length>0){if(!a||v.fingerprint!==a||!Be(v.untracked,u))throw Error(`Working-tree changes changed; review them before refreshing.`);await X(n,[`add`,`--update`]),u.length>0&&await X(n,[`add`,`--`,...u]),await X(n,[`commit`,`--message`,o],{env:{GIT_EDITOR:`true`}}),h=await Z(n,[`rev-parse`,`HEAD`]),T=h,_=`refs/coreframe/recovery/${Date.now()}-${h.slice(0,12)}`,await X(n,[`update-ref`,_,h])}let y=h??m,b,x=new AbortController;S=()=>x.abort();try{try{b=await _e({codex:d,codexApproved:t,cwd:n,env:p,localMain:y,onCodexEvent:s,resume:f,signal:x.signal,source:c,target:l})}finally{S=void 0}if(z(x.signal),await Z(n,[`rev-parse`,`HEAD`])!==y)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await Z(n,[`rev-parse`,k])!==y)throw Error(`Local main changed while the accepted update was being prepared.`);let e=b.pause?{applied:b.pause.applied,commits:b.pause.commits,files:b.pause.files,target:await Fe(n,y,l,c)}:void 0,i=b.commit;if(i===void 0){g={...g,pendingRebase:e},_&&await X(n,[`update-ref`,`-d`,_]);return}await ve(n,{commit:i,devTarget:b.devTarget},y),w=!0,T=i,await X(n,[`reset`,`--hard`,i]);let a=Ve(await Z(n,[`diff`,`--name-only`,`-z`,m,i])),o=Me(a),u=Ne(a,r);N=void 0,e&&_&&(C=_,_=void 0),_&&await X(n,[`update-ref`,`-d`,_]),C&&!b.pause&&(await X(n,[`update-ref`,`-d`,C]),C=void 0),g={...g,currentCommit:i,draft:void 0,pendingRebase:e,proposal:void 0,setupFailure:void 0,target:void 0},await G({installDependencies:je(a),nativeRestartRequired:u,restartRequired:o,trigger:`synchronization`})}catch(e){let t=_?` Recovery commit: ${_}.`:``;throw g={...g,currentCommit:T,message:`${$(e)}${t}`,pendingRebase:f??g.pendingRebase},e}},xe=async({commit:t,nativeRestartRequired:r,restartRequired:i})=>{try{return await e({cwd:n,env:p}),!0}catch(e){return await K({command:`pnpm codegen`,commit:t,error:e,message:`Bamboo generated code could not be prepared. Fix the Bamboo configuration or dependencies, then retry codegen.`,nativeRestartRequired:r,restartRequired:i,stage:`codegen`}),!1}},G=async({nativeRestartRequired:e,installDependencies:r,restartRequired:i,trigger:a})=>{let o=T;if(r)try{await ke([`install`,`--frozen-lockfile`])}catch(t){await K({command:`pnpm install --frozen-lockfile`,commit:o,error:t,message:`The project was synchronized, but dependency installation failed. Fix the package or lockfile issue, then retry the install.`,nativeRestartRequired:e,restartRequired:i,stage:`dependencies`});return}if(await xe({commit:o,nativeRestartRequired:e,restartRequired:i})){try{await Te({config:t,cwd:n,env:p})}catch(t){await K({command:`pnpm db migrate-local`,commit:o,error:t,message:`The project was synchronized, but its database migration failed. The previous database was restored. Reset the database to recreate the current schema and rerun seed scripts.`,nativeRestartRequired:e,restartRequired:i,stage:`migration`});return}await q(),R(o,a),e&&await s(),i&&c()}},we=async()=>{let e=Oe(`dependencies`);await q(),await G({nativeRestartRequired:e.nativeRestartRequired===!0,installDependencies:!0,restartRequired:e.restartRequired,trigger:`dependency-recovery`})},Ee=async()=>{let e=Oe(`codegen`);await q(),await G({nativeRestartRequired:e.nativeRestartRequired===!0,installDependencies:!1,restartRequired:e.restartRequired,trigger:`codegen-recovery`})},De=async()=>{let e=Oe(`migration`);try{await ke([`db`,`setup`])}catch(t){await K({command:`pnpm db setup`,commit:e.commit,error:t,message:`The project remains synchronized, but the database reset failed. Review the diagnostics, fix the reported problem, and try the reset again.`,nativeRestartRequired:e.nativeRestartRequired===!0,restartRequired:e.restartRequired,stage:`migration`});return}await q(),R(e.commit,`database-recovery`),e.nativeRestartRequired===!0&&await s(),e.restartRequired&&c()},Oe=e=>{if(!g.setupFailure||g.setupFailure.stage!==e)throw Error(`There is no failed ${e} setup step to recover.`);return g.setupFailure},ke=async e=>{await D(We(),e,{cwd:n,env:p})},K=async({command:e,commit:t,error:n,nativeRestartRequired:r,message:i,restartRequired:a,stage:o})=>{let s=Ce(n).slice(-1e5),c={command:e,commit:t,message:i,output:s,...r?{nativeRestartRequired:!0}:void 0,restartRequired:a,stage:o};g={...g,setupFailure:c,target:void 0},console.error(`Coreframe managed development setup failed (${e}): ${i}\n${s}`);let l=J();l&&await h(l,`${JSON.stringify(c)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development setup failure: ${$(e)}`)})},q=async()=>{g={...g,setupFailure:void 0};let e=J();e&&await m(e).catch(e=>{e instanceof Error&&`code`in e&&e.code===`ENOENT`||console.warn(`Could not clear the managed-development setup failure: ${$(e)}`)})},J=()=>E?x.join(E.commonDir,ie):void 0,Y=async(e,t,n,r)=>{let i={commits:n,finalMessage:e,id:v(16).toString(`hex`),messages:de(t),...r===void 0?void 0:{totalCommits:r}};g={...g,codexCompletion:i},E&&await h(x.join(E.commonDir,ne),`${JSON.stringify(i)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex result: ${$(e)}`)}),P()},Ae=async e=>{g={...g,codexOptions:e},E&&await h(x.join(E.commonDir,re),`${JSON.stringify(e)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex options: ${$(e)}`)})},Pe=async()=>{g={...g,codexCompletion:void 0},E&&await m(x.join(E.commonDir,ne)).catch(e=>{if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e})};return{action:be,activate:ye,getStatus:()=>g,async close(){if(!_){_=!0,clearInterval(ae),clearInterval(j),clearTimeout(M);for(let e of oe)e.close();await Re(O)}}}}async function se(e){let t=x.join(e,re);try{let e=JSON.parse(await d(t,`utf8`));if(N(e))return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development Codex options: ${$(e)}`)}await m(t).catch(()=>void 0)}function N(e){if(!e||typeof e!=`object`)return!1;let{effort:t,model:n}=e;return(t===void 0||C.includes(t))&&(n===void 0||w.includes(n))}async function ce(e){let t=x.join(e,ne);try{let e=JSON.parse(await d(t,`utf8`));if(le(e))return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development Codex result: ${$(e)}`)}await m(t).catch(()=>void 0)}function le(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.finalMessage==`string`&&typeof t.id==`string`&&Array.isArray(t.messages)&&t.messages.every(P)&&(t.totalCommits===void 0||Number.isInteger(t.totalCommits)&&t.totalCommits>=0)&&(t.commits===void 0||Array.isArray(t.commits)&&t.commits.every(ue))}function ue(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.commit==`string`&&typeof t.shortCommit==`string`&&typeof t.subject==`string`}function P(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.kind===`agent`||t.kind===`thought`||t.kind===`user`)&&(t.author===void 0||typeof t.author==`string`)&&typeof t.text==`string`}function de(e){let t=new Set(e.filter(e=>e.kind===`user`)),n=[...t].reduce((e,t)=>e+t.text.length,0),r=!1;for(let i of[...e].reverse())if(i.kind!==`user`){if(n+i.text.length>1e5&&r)break;t.add(i),r=!0,n+=i.text.length}return e.filter(e=>t.has(e))}async function fe(e,t){let n=x.join(e,ie);try{let e=JSON.parse(await d(n,`utf8`));if(F(e)&&e.commit===t)return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development setup failure: ${$(e)}`)}await m(n).catch(()=>void 0)}function F(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.command===`pnpm codegen`||t.command===`pnpm db migrate-local`||t.command===`pnpm db setup`||t.command===`pnpm install --frozen-lockfile`)&&typeof t.commit==`string`&&typeof t.message==`string`&&typeof t.output==`string`&&(t.nativeRestartRequired===void 0||typeof t.nativeRestartRequired==`boolean`)&&typeof t.restartRequired==`boolean`&&(t.stage===`codegen`||t.stage===`dependencies`||t.stage===`migration`)}async function pe(e){let t=await M(e);return{branch:I(await Z(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await Z(e,[`rev-parse`,`HEAD`]),main:await Z(e,[`rev-parse`,k]),primary:t.primary}}function I(e){return e===`HEAD`?void 0:e}async function me(e,t){let n=[e.gitDir,x.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(b(e,{persistent:!1},t))}catch{}return r}async function L(e){let[t,n,r]=await Promise.all([Z(e,[`status`,`--porcelain`,`--untracked-files=no`]),Z(e,[`diff`,`HEAD`,`--binary`]),Z(e,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),i=Ve(r).sort(),a=_(`sha256`).update(n);for(let e of i)a.update(`\0`).update(e);return{fingerprint:a.digest(`hex`),tracked:t.length>0,untracked:i}}async function he(e,t,n){let i=[`Tracked changes:`,await Z(e,[`diff`,`HEAD`,`--binary`])];for(let t of n){let n=await d(x.join(e,t));i.push(`\nUntracked file: ${t}\n`,n.toString(`utf8`))}let{stdout:a}=await D(`codex`,[`exec`,...r,`--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,stderr:`ignore`,stdin:{string:i.join(`
|
|
2
|
+
`)}});return a.trim().replace(/^```(?:text)?\s*|\s*```$/g,``)}async function ge(e,t){let n=t.PATH??t.Path??t.path??``,r=a.platform===`win32`?(t.PATHEXT??`.COM;.EXE;.BAT;.CMD`).split(`;`):[``];for(let t of n.split(x.delimiter))for(let n of r)try{return await o(x.join(t||`.`,`${e}${n}`),y.X_OK),!0}catch{}return!1}async function _e({codex:e,codexApproved:t=!1,cwd:n,env:r,localMain:i,onCodexEvent:a,resume:o,signal:s,source:l,target:u}){if(l===`dev`&&await ze(n,i,u))return{commit:u,devTarget:u};let d=x.resolve(n,await Z(n,[`rev-parse`,`--git-common-dir`])),f=x.join(d,`coreframe-managed-dev`);await c(f,{recursive:!0});let m=v(8).toString(`hex`),h=x.join(f,`integration-${m}`);try{if(await X(n,[`worktree`,`add`,`--detach`,h,i]),i!==u)if(l===`dev`)await R(h,r,[`merge`,`--no-edit`,`--no-ff`,`--allow-unrelated-histories`,`--message`,`Merge dev into main`,u],`merge`,a,{codex:e,signal:s});else if(o&&o.applied>0){let n=o.commits[0],c=o.commits.at(-1);await R(h,r,await Q(h,[`rev-parse`,`--verify`,`${n.commit}^`])?[`rebase`,`--onto`,`HEAD`,`${n.commit}^`,c.commit]:[`rebase`,`--root`,`--onto`,`HEAD`,c.commit],`rebase`,a,{codex:e,codexApproved:t,rebaseBase:i,signal:s,totalCommits:o.commits.length})}else{let n=await Q(h,[`merge-base`,i,u]),o=Number(await Z(h,[`rev-list`,`--count`,n?`${n}..HEAD`:`HEAD`])),c=await R(h,r,n?[`rebase`,`--onto`,u,n]:[`rebase`,`--root`,`--onto`,u],`rebase`,a,{codex:e,codexApproved:t,rebaseBase:u,rebaseStart:n,signal:s,totalCommits:o});if(c)return{commit:c.applied>0?c.partial:void 0,pause:{applied:c.applied,commits:c.commits,files:c.files}}}return z(s),{commit:await Z(h,[`rev-parse`,`HEAD`]),devTarget:l===`dev`?u:void 0}}finally{await X(n,[`worktree`,`remove`,`--force`,h]).catch(()=>void 0),await p(h,{force:!0,recursive:!0})}}async function ve(e,t,n){let r=async r=>{let i=[`start`,`update ${k} ${t.commit} ${n}`];r&&t.devTarget&&i.push(t.devTarget===t.commit?`verify ${A} ${t.devTarget}`:`update ${A} ${t.commit} ${t.devTarget}`),i.push(`prepare`,`commit`),await D(`git`,[`update-ref`,`--stdin`],{cwd:e,stdin:{string:`${i.join(`
|
|
3
|
+
`)}\n`}})};try{await r(!0)}catch(i){if(!t.devTarget)throw i;let a;try{a=await Promise.all([Z(e,[`rev-parse`,k]),Q(e,[`rev-parse`,A])])}catch{throw i}let[o,s]=a;if(o!==n||s===t.devTarget)throw i;await r(!1)}}async function R(e,t,n,r,i,{codex:a,codexApproved:o=!0,rebaseBase:s,rebaseStart:c,signal:l,totalCommits:u=0}={}){try{await X(e,n,{env:{GIT_EDITOR:`true`}});return}catch(n){let d=await G(e);if(d.length===0)throw n;if(!o&&r===`rebase`){let t=await ye(e,d,s,c);return await X(e,[r,`--abort`]).catch(()=>void 0),t}try{for(;d.length>0;){z(l),await B(e,t,r,d,s?await U(e,s):[],u,i,l,a),await X(e,[`diff`,`--check`]),await X(e,[`add`,`--all`]);let n=await G(e);if(n.length>0)throw Error(`Codex left unresolved paths: ${n.join(`, `)}`);try{await X(e,[r,`--continue`],{env:{GIT_EDITOR:`true`}})}catch(t){if(d=await G(e),d.length===0)throw t;i({commits:s?await U(e,s):[],phase:`progress`,totalCommits:u});continue}i({commits:s?await U(e,s):[],phase:`progress`,totalCommits:u}),d=await G(e)}try{r===`rebase`&&await V(e,t,r,i,l,a)}catch(e){throw z(l),Error(`Codex could not verify the ${r} result: ${$(e)}`)}return}catch(t){throw await X(e,[r,`--abort`]).catch(()=>void 0),z(l),Error(`Codex could not resolve ${r} conflicts: ${$(t)}`)}}}async function ye(e,t,n,r){let i=n?await U(e,n):[],a=await H(e,r,`ORIG_HEAD`);return{applied:i.length,commits:a.slice(i.length),files:t,partial:await Z(e,[`rev-parse`,`HEAD`])}}function z(e){if(e?.aborted)throw Error(`The update integration was cancelled.`)}async function be(e,r,i,a,o,s){let c=D(`codex`,[`exec`,...t(a),`--ephemeral`,`--ignore-user-config`,`--json`,`--sandbox`,`workspace-write`,`--cd`,e,i],{cwd:e,env:{...r,GIT_AUTHOR_EMAIL:r.GIT_AUTHOR_EMAIL??`codex@managed-dev.local`,GIT_AUTHOR_NAME:r.GIT_AUTHOR_NAME??`Codex`,GIT_COMMITTER_EMAIL:r.GIT_COMMITTER_EMAIL??`codex@managed-dev.local`,GIT_COMMITTER_NAME:r.GIT_COMMITTER_NAME??`Codex`},stdin:`ignore`}),l=``,u=[],d=()=>{c.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0)};s?.addEventListener(`abort`,d);try{await Promise.all([xe(c.stdout,e=>{let t=W(e,n(a));t&&(t.kind===`agent`&&(l=t.text),o({message:t,phase:`message`}))}),xe(c.stderr,e=>u.push(e))]),z(s)}catch(e){o({phase:`error`}),z(s);let t=u.join(`
|
|
4
|
+
`).trim();throw t?Error(`${$(e)}\n${t}`):e}finally{s?.removeEventListener(`abort`,d)}return l}async function B(e,t,n,r,i,a,o,s,c){z(s);let l=`Resolve the current Git ${n} conflicts cleanly. Edit only files needed for the resolution, preserve intended behavior from both sides, and remove all conflict markers. Do not run tests, typecheck, lint, format, or other slow checks; the managed development session runs them once after the ${n} finishes. Do not stage files or run Git continuation commands. Conflicted paths: ${r.join(`, `)}`;o({commits:i,message:{kind:`user`,text:l},phase:`start`,totalCommits:a}),o({finalMessage:await be(e,t,l,c,o,s)||`Codex resolved the conflicts.`,phase:`complete`})}async function V(e,t,n,r,i,a){z(i);let o=`The Git ${n} finished replaying every commit. Verify the result by running the project's checks once each: pnpm test and pnpm typecheck, plus lint or format checks if the project defines them. If a check fails, apply the smallest safe fix and commit it with a conventional-commit message that describes the fix. Do not rewrite Git history, rebase, or amend existing commits. If a failure cannot be fixed safely, describe it in your final response instead of committing a broken fix.`;r({message:{kind:`user`,text:o},phase:`message`}),r({finalMessage:await be(e,t,o,a,r,i)||`Codex finished verifying the result.`,phase:`complete`})}async function H(e,t,n){let r=await Z(e,[`log`,`--reverse`,`--format=%H%x00%s`,t?`${t}..${n}`:n]);return r?r.split(`
|
|
5
|
+
`).map(e=>{let[t,n=``]=e.split(`\0`,2);return{commit:t,shortCommit:t.slice(0,12),subject:n}}):[]}function U(e,t){return H(e,t,`HEAD`)}function W(e,t){let n;try{n=JSON.parse(e)}catch{throw Error(`Codex emitted invalid JSONL output.`)}if(!n||typeof n!=`object`)return;let r=n.item;if(n.type!==`item.completed`||!r||typeof r!=`object`)return;let{text:i,type:a}=r;if(!(typeof i!=`string`||!i.trim())){if(a===`reasoning`)return{kind:`thought`,text:i};if(a===`agent_message`)return{author:t,kind:`agent`,text:i}}}async function xe(e,t){for await(let n of e)t(n)}async function G(e){return Ve(await Z(e,[`diff`,`--name-only`,`--diff-filter=U`,`-z`]))}async function Se(e,t,n){await D(We(),[n],{cwd:e,env:t})}function Ce(e){let t=we(e);if(t){let e=S(t).trim();if(e)return e}return S($(e))}function we(e){if(typeof e!=`object`||!e)return;let t=e;if(typeof t.output==`string`&&t.output.trim())return t.output;let n=[t.stdout,t.stderr].filter(e=>typeof e==`string`&&e.length>0);return n.length>0?n.join(`
|
|
6
|
+
`):void 0}async function Te({config:e,cwd:t,env:n}){if(!e.database)return;let r=await Ee({config:e,cwd:t,env:n});try{await D(We(),[`db`,`migrate-local`],{cwd:t,env:n})}catch(e){throw await r.restore(),e}await r.discard().catch(e=>{console.warn(`Could not remove the managed-development database snapshot: ${$(e)}`)}),await p(r.directory,{force:!0,recursive:!0})}async function Ee({config:e,cwd:t,env:n}){let r=x.join(t,`.coreframe`,`managed-dev-backups`);await c(r,{recursive:!0});let i=await l(x.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 De(x.join(t,`.coreframe`,r),x.join(i,r))&&n.add(r);return{directory:i,async discard(){},async restore(){for(let r of e){let e=x.join(t,`.coreframe`,r);n.has(r)?await s(x.join(i,r),e):await p(e,{force:!0})}}}}if(!n.DATABASE_URL)throw Error(`DATABASE_URL is required to snapshot local PostgreSQL.`);let a=await Oe(t);if(a)return ke({directory:i,connectionString:n.DATABASE_URL,postgres:a});let o=x.join(i,`database.dump`),u=Ae(n,n.DATABASE_URL);return await D(`pg_dump`,[`--format=custom`,`--file`,o],{cwd:t,env:u,stdin:`ignore`}),{directory:i,async discard(){},async restore(){await D(`pg_restore`,[`--clean`,`--if-exists`,`--no-owner`,`--dbname`,u.PGDATABASE,o],{cwd:t,env:u,stdin:`ignore`})}}}async function De(e,t){try{return await s(e,t),!0}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e;return!1}}async function Oe(e){let t=JSON.parse(await d(x.join(e,`package.json`),`utf8`));if(!(!t.dependencies?.pg&&!t.devDependencies?.pg&&!t.optionalDependencies?.pg))try{return await import(E(`pg`,g(x.join(e,`package.json`)).href))}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ERR_MODULE_NOT_FOUND`)return;throw e}}async function ke({directory:e,connectionString:t,postgres:n}){let r=new URL(t),i=decodeURIComponent(r.pathname.slice(1));if(!i)throw Error(`DATABASE_URL must name a PostgreSQL database to snapshot.`);let a=`coreframe_backup_${v(6).toString(`hex`)}`,o=`${a}_failed`,s=new URL(r);s.pathname=i===`postgres`?`/template1`:`/postgres`;let c=new n.Client({connectionString:s.href});await c.connect();try{await q(c,i,!1),await J(c,i),await c.query(`CREATE DATABASE ${Y(a)} WITH TEMPLATE ${Y(i)}`),await q(c,a,!0)}finally{await q(c,i,!0).catch(()=>void 0),await c.end()}return{directory:e,async discard(){await K(n,s.href,async e=>{await J(e,a),await e.query(`DROP DATABASE ${Y(a)}`)})},async restore(){await K(n,s.href,async e=>{await q(e,i,!1),await J(e,i),await e.query(`ALTER DATABASE ${Y(i)} RENAME TO ${Y(o)}`);try{await e.query(`ALTER DATABASE ${Y(a)} RENAME TO ${Y(i)}`)}catch(t){throw await e.query(`ALTER DATABASE ${Y(o)} RENAME TO ${Y(i)}`).catch(()=>void 0),await q(e,i,!0).catch(()=>void 0),t}await J(e,o),await e.query(`DROP DATABASE ${Y(o)}`)})}}}async function K(e,t,n){let r=new e.Client({connectionString:t});await r.connect();try{return await n(r)}finally{await r.end()}}async function q(e,t,n){await e.query(`ALTER DATABASE ${Y(t)} ALLOW_CONNECTIONS ${n?`true`:`false`}`)}async function J(e,t){await e.query(`SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()`,[t])}function Y(e){return`"${e.replaceAll(`"`,`""`)}"`}function Ae(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 je(e){return e.some(e=>x.basename(e)===`package.json`||x.basename(e).endsWith(`lock.yaml`)||x.basename(e)===`pnpm-workspace.yaml`)}function Me(e){return e.some(e=>je([e])||/(^|\/)(bamboo\.config|vite|coreframe|tsconfig|drizzle)\.[^/]+$/.test(e)||/(^|\/)(drizzle|scripts|src\/api)(\/|$)/.test(e))}function Ne(e,t){let n=Pe(t);return e.some(e=>n.some(t=>e===t||e.startsWith(`${t}/`)))}function Pe(e){let t=e[T];return t===void 0?[]:t.split(`,`).map(e=>e.trim().replace(/\/+$/,``)).filter(e=>e.length>0)}async function Fe(e,t,n,r){return{commit:n,commits:(await Z(e,[`log`,`--reverse`,`--format=%H%x00%s`,`${t}..${n}`])).split(`
|
|
7
|
+
`).filter(Boolean).map(e=>{let[t,n]=e.split(`\0`);return{commit:t,shortCommit:t.slice(0,12),subject:n}}),shortCommit:n.slice(0,12),source:r,subject:await Z(e,[`show`,`-s`,`--format=%s`,n])}}async function Ie(e){try{let t=await u(e,`wx`);await t.writeFile(`${a.pid}\n`),await t.close()}catch(t){if(!(t instanceof Error&&`code`in t&&t.code===`EEXIST`))throw t;let n=(await d(e,`utf8`).catch(()=>`unknown`)).trim(),r=Number(n);if(Number.isInteger(r)&&!Le(r)){await m(e).catch(()=>void 0),await Ie(e);return}throw Error(`Managed development is already owned by PID ${n}.`)}}function Le(e){try{return a.kill(e,0),!0}catch(e){return!(e instanceof Error&&`code`in e&&e.code===`ESRCH`)}}async function Re(e){e&&(await d(e,`utf8`).catch(()=>void 0))?.trim()===String(a.pid)&&await m(e).catch(()=>void 0)}async function X(e,t,{env:n}={}){return D(`git`,t,{cwd:e,env:n,stdin:`ignore`})}async function Z(e,t){return(await X(e,t)).stdout.trim()}async function Q(e,t){try{return await Z(e,t)||void 0}catch(e){if(e instanceof O&&e.exitCode&&e.exitCode>0)return;throw e}}async function ze(e,t,n){try{return await X(e,[`merge-base`,`--is-ancestor`,t,n]),!0}catch(e){if(e instanceof O&&e.exitCode===1)return!1;throw e}}function Be(e,t){return e.length===t.length&&[...e].sort().every((e,n)=>e===[...t].sort()[n])}function Ve(e){return e.split(`\0`).filter(Boolean)}function He(e){return e.split(/\r?\n/,1)[0]??``}function Ue(e){return e.type===`acknowledge-codex`?`Acknowledging Codex result`:e.type===`cancel-codex`?`Cancelling conflict resolution`:e.type===`configure-codex`?`Saving Codex preferences`:e.type===`decline-rebase`?`Declining Codex conflict resolution`:e.type===`resolve-rebase`?`Resolving update conflicts with Codex`:e.type===`dismiss-check`?`Dismissing managed development check`:e.type===`message`?`Generating commit message`:e.type===`commit`?`Committing local changes`:e.type===`apply`?`Integrating accepted update`:e.type===`prepare`?`Reviewing working tree`:e.type===`retry-codegen`?`Retrying Bamboo codegen`:e.type===`retry-install`?`Retrying dependency installation`:e.type===`reset-database`?`Resetting local database`:`Aborting refresh`}function We(){return a.platform===`win32`?`pnpm.cmd`:`pnpm`}function $(e){return e instanceof Error?e.message:String(e)}export{ae as isManagedDevCheckout,j as isPrimaryCheckout,oe as startManagedDevSession};
|
package/dist/supervisor.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{startManagedDevSession as e}from"./managed-dev.js";import{access as t}from"node:fs/promises";import{fileURLToPath as n}from"node:url";import{readProjectConfig as r}from"@coreframe/config";import{startProjectPostgres as i,startProjectTurso as a}from"@coreframe/db";import{connectDevSupervisor as o,runDevSupervisorProcess as s}from"@coreframe/dev-supervisor";export*from"@coreframe/dev-supervisor";async function c({cwd:e=process.cwd(),env:t=process.env,requiredResources:n=[]}={}){return o({cwd:e,env:t,requiredResources:n,supervisorEntry:await u()})}function l({cwd:t=process.cwd()}={}){return s({cwd:t,startManagedDev:async({cwd:t,env:n,
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{startManagedDevSession as e}from"./managed-dev.js";import{access as t}from"node:fs/promises";import{fileURLToPath as n}from"node:url";import{readProjectConfig as r}from"@coreframe/config";import{startProjectPostgres as i,startProjectTurso as a}from"@coreframe/db";import{connectDevSupervisor as o,runDevSupervisorProcess as s}from"@coreframe/dev-supervisor";export*from"@coreframe/dev-supervisor";async function c({cwd:e=process.cwd(),env:t=process.env,requiredResources:n=[]}={}){return o({cwd:e,env:t,requiredResources:n,supervisorEntry:await u()})}function l({cwd:t=process.cwd()}={}){return s({cwd:t,startManagedDev:async({cwd:t,env:n,onNativeRestart:i,onRestart:a,onStatusChange:o})=>e({config:await r({cwd:t}),cwd:t,env:{...n,COREFRAME_MANAGED_DEV:`1`,COREFRAME_PLATFORM:`web`},onNativeRestart:i,onRestart:a,onStatusChange:o}),startPostgres:i,startSqlite:a})}async function u(){let e=n(new URL(`./dev-supervisor-process.js`,import.meta.url));try{return await t(e),e}catch{return n(new URL(`./dev-supervisor-process.ts`,import.meta.url))}}export{c as connectDevSupervisor,l as runDevSupervisorProcess};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreframe/dev",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "3.0.0-beta.1",
|
|
4
4
|
"description": "Development workflow utilities for Coreframe apps",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"@coreframe/config": "3.0.0-beta.1",
|
|
38
|
+
"@coreframe/db": "3.0.0-beta.1",
|
|
39
|
+
"@coreframe/dev-contracts": "3.0.0-beta.1",
|
|
40
|
+
"@coreframe/dev-supervisor": "3.0.0-beta.1",
|
|
37
41
|
"import-meta-resolve": "^4.2.0",
|
|
38
|
-
"nano-spawn": "^2.1.0"
|
|
39
|
-
"@coreframe/dev-contracts": "^0.1.10",
|
|
40
|
-
"@coreframe/db": "^0.1.24",
|
|
41
|
-
"@coreframe/config": "^0.1.17",
|
|
42
|
-
"@coreframe/dev-supervisor": "^0.1.20"
|
|
42
|
+
"nano-spawn": "^2.1.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^26.1.0",
|
package/dist/panda-codegen.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import e from"node:process";import{access as t,mkdir as n,readFile as r,readdir as i,writeFile as a}from"node:fs/promises";import{createHash as o}from"node:crypto";import s from"node:path";import c from"nano-spawn";const l=/^panda\.config\.(?:[cm]?[jt]sx?)$/,u=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`],d=new Set([`.coreframe`,`.git`,`.react-router`,`.wrangler`,`.wxt`,`build`,`dist`,`node_modules`,`styled-system`,`target`]),f=`.coreframe/panda-codegen.json`;async function p({cwd:t=e.cwd(),env:r=e.env,runCodegen:i=()=>m(t,r)}={}){let o=await h(t);if(o.length===0)return{applicable:!1,ran:!1};let c=await _(t,o),l=await x(t);if(l?.schemaVersion===1&&l.fingerprint===c&&await S(t,o))return{applicable:!0,fingerprint:c,ran:!1};if(await i(),!await S(t,o))throw Error(`Panda codegen completed without producing the expected generated output.`);return await n(s.dirname(s.join(t,f)),{recursive:!0}),await a(s.join(t,f),`${JSON.stringify({fingerprint:c,schemaVersion:1})}\n`,{mode:384}),{applicable:!0,fingerprint:c,ran:!0}}async function m(t,n){await c(e.platform===`win32`?`pnpm.cmd`:`pnpm`,[`codegen`],{cwd:t,env:n})}async function h(e){let t=[];return await g(e,``,t),t.sort((e,t)=>e.path.localeCompare(t.path)),t}async function g(e,t,n){let a=await i(e,{withFileTypes:!0});for(let i of a){let a=t?s.join(t,i.name):i.name;if(i.isDirectory()){d.has(i.name)||await g(s.join(e,i.name),a,n);continue}if(i.isFile()&&l.test(i.name)){let t=await r(s.join(e,i.name),`utf8`);n.push({content:t,path:a})}}}async function _(e,t){let n=await v(e);return o(`sha256`).update(JSON.stringify({dependencies:n,configs:t.map(({content:e,path:t})=>({content:e,path:t})),schemaVersion:1})).digest(`hex`)}async function v(e){let t=JSON.parse(await r(s.join(e,`package.json`),`utf8`)),n=[];for(let r of u){let i=t[r];if(!(!i||typeof i!=`object`||Array.isArray(i)))for(let t of Object.keys(i).sort())y(t)&&n.push({name:t,section:r,spec:i[t],version:await b(e,t)})}return n}function y(e){return e===`panda`||e.startsWith(`@pandacss/`)||/panda/i.test(e)}async function b(e,t){try{return JSON.parse(await r(s.join(e,`node_modules`,t,`package.json`),`utf8`)).version}catch{return}}async function x(e){try{let t=JSON.parse(await r(s.join(e,f),`utf8`));if(!t||typeof t!=`object`)return;let n=t;return typeof n.fingerprint==`string`&&typeof n.schemaVersion==`number`?{fingerprint:n.fingerprint,schemaVersion:n.schemaVersion}:void 0}catch{return}}async function S(e,t){return(await Promise.all(t.map(t=>C(e,t)))).every(Boolean)}async function C(e,n){let r=w(e,n);try{return await Promise.all([t(s.join(r,`css/index.js`)),t(s.join(r,`types/index.d.ts`))]),!0}catch{return!1}}function w(e,t){let n=/\boutdir\s*:\s*["'`]([^"'`]+)["'`]/s.exec(t.content)?.[1];return s.resolve(e,s.dirname(t.path),n??`styled-system`)}export{p as ensurePandaCodegen,f as pandaCodegenStateFile};
|