@coreframe/scripts 0.1.40 → 0.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  //#region coreframe.d.ts
2
- declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register> & {
3
- parse(context: import("cmd-ts/dist/cjs/argparser").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser").ParsingResult<{
2
+ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").Register> & {
3
+ parse(context: import("@alloc/cmd-ts/dist/cjs/argparser").ParseContext): Promise<import("@alloc/cmd-ts/dist/cjs/argparser").ParsingResult<{
4
4
  command: "assets";
5
5
  args: {
6
6
  command: "configure";
@@ -206,7 +206,7 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
206
206
  args: {};
207
207
  };
208
208
  }>>;
209
- } & import("cmd-ts/dist/cjs/helpdoc").Named & Partial<import("cmd-ts/dist/cjs/helpdoc").Descriptive & import("cmd-ts/dist/cjs/helpdoc").Versioned> & import("cmd-ts/dist/cjs/helpdoc").PrintHelp & Partial<import("cmd-ts/dist/cjs/helpdoc").Versioned> & import("cmd-ts/dist/cjs/argparser").Register & import("cmd-ts/dist/cjs/runner").Handling<{
209
+ } & import("@alloc/cmd-ts/dist/cjs/helpdoc").Named & Partial<import("@alloc/cmd-ts/dist/cjs/helpdoc").Descriptive & import("@alloc/cmd-ts/dist/cjs/helpdoc").Versioned> & import("@alloc/cmd-ts/dist/cjs/helpdoc").PrintHelp & Partial<import("@alloc/cmd-ts/dist/cjs/helpdoc").Versioned> & import("@alloc/cmd-ts/dist/cjs/argparser").Register & import("@alloc/cmd-ts/dist/cjs/runner").Handling<{
210
210
  command: "assets";
211
211
  args: {
212
212
  command: "configure";
@@ -526,7 +526,7 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
526
526
  value: Promise<void>;
527
527
  };
528
528
  }> & {
529
- run(context: import("cmd-ts/dist/cjs/argparser").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser").ParsingResult<{
529
+ run(context: import("@alloc/cmd-ts/dist/cjs/argparser").ParseContext): Promise<import("@alloc/cmd-ts/dist/cjs/argparser").ParsingResult<{
530
530
  command: "assets";
531
531
  value: {
532
532
  command: "configure";
package/dist/coreframe.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{assertAssetCredentialProfile as e,configureAssetCredentials as t}from"./assets/credentials.js";import{addAsset as n,buildAssets as r,checkAssets as i,printAssetResult as a,publishAssets as o}from"./assets/workflows.js";import"./assets.js";import{runDrizzleKitCommand as s}from"./db/drizzle-kit.js";import{seedLocalDb as c}from"./db/seed.js";import{migrateLocalDb as l}from"./db/migrate.js";import{resetLocalDb as u}from"./db/reset.js";import{setupLocalDb as d}from"./db/setup.js";import{ensureLocalDb as f}from"./db/ensure.js";import{formatDbErrorMessage as p}from"./db/error.js";import{migrateHeldMigrations as m}from"./db/migrate-held.js";import{checkSchemaPush as h}from"./db/schema-check.js";import{rotateAccessTokenSigningSecret as g}from"./deploy/access-token-secret.js";import{deployEnvironments as _,tauriReleasePlatforms as v}from"./deploy/config.js";import{discoverStagingUrl as y,reassignStagingHostname as b}from"./staging.js";import{discardPendingWorkerSecret as ee,inspectWorkerEnvironment as te,queueWorkerSecret as x}from"./worker-environment.js";import{deployProject as S}from"./deploy.js";import{checkDeployMigrations as C}from"./deploy/check-migrations.js";import{devDebugFeatures as ne,devPlatforms as w,runDevServer as re}from"./dev.js";import{validateRecipeName as ie}from"./recipes/manifest.js";import{ensureTemplateRemote as T}from"./upgrade/ensure-template-remote.js";import{applyRecipe as E,printAppliedRecipe as D}from"./recipes/apply.js";import{listRecipes as O,printRecipeCatalog as k}from"./recipes/list.js";import{run as A}from"./runner.js";import{typecheckProject as j}from"./typecheck.js";import{checkUpgradeSkillCurrent as M}from"./upgrade/check-skill-current.js";import{fastForwardTemplateFiles as N}from"./upgrade/fast-forward-template-files.js";import{syncCoreframePackages as P}from"./upgrade/sync-coreframe-packages.js";import*as F from"@clack/prompts";import{array as I,command as L,extendType as R,flag as z,multioption as B,number as V,oneOf as H,option as U,optional as W,positional as G,rest as K,string as q,subcommands as J}from"cmd-ts";const Y=R(H(ne),{displayName:`feature`,from:async e=>e}),X=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],Z=[`Use a B2 Multi-Bucket Application Key restricted to the configured private source and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),ae=R(q,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),oe=R(q,{displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return ie(e)}}),se=R(q,{displayName:`profile`,async from(t){return e(t)}}),Q=R(q,{displayName:`pack`,description:`Asset pack name, such as training-videos.`,async from(e){if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e))throw Error(`Asset pack names must use lowercase hyphen-separated segments.`);return e}}),$=J({name:`coreframe`,cmds:{assets:J({name:`assets`,cmds:{configure:L({name:`configure`,description:`Store a Backblaze B2 asset key in the operating system credential store. ${Z}`,args:{profile:G({type:se,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{F.note(Z,`Required B2 key access`);let n=await F.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(F.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);let r=await F.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(F.isCancel(r))throw Error(`Asset credential configuration was cancelled.`);await t({applicationKey:r,applicationKeyId:n.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:L({name:`add`,args:{file:G({type:q,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:U({long:`id`,type:q,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:U({long:`alt`,type:W(q),description:`Required alt text for raster image and SVG assets.`}),pack:U({long:`pack`,type:W(Q),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:U({long:`widths`,type:W(ae),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:r,json:i,pack:o,variantWidths:s})=>a(await n({alt:e,file:t,id:r,pack:o,variantWidths:s}),i)}),build:L({name:`build`,args:{id:U({long:`id`,type:W(q),description:`Build only one logical asset ID.`}),pack:U({long:`pack`,type:W(Q),description:`Build only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>a(await r({id:e,pack:n}),t)}),check:L({name:`check`,args:{fix:z({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:U({long:`pack`,type:W(Q),description:`Check only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await i({fix:e,pack:n});a(r,t),r.ok||(process.exitCode=1)}}),publish:L({name:`publish`,args:{pack:U({long:`pack`,type:W(Q),description:`Publish only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await o({pack:t});a(n,e),n.ok||(process.exitCode=1)}}),status:L({name:`status`,args:{pack:U({long:`pack`,type:W(Q),description:`Report status for only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await i({pack:t});a(n,e),n.ok||(process.exitCode=1)}})}}),deploy:L({name:`deploy`,args:{environment:G({type:H(_),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:z({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:z({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:z({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:B({long:`tauri-local-platform`,type:I(H(v)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:U({long:`tauri-workflow-name`,type:W(q),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:B({long:`tauri-workflow-platform`,type:I(H(v)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:U({long:`tauri-workflow-ref`,type:W(q),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:z({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,tauriLocalPlatforms:i,tauriWorkflowName:a,tauriWorkflowPlatforms:o,tauriWorkflowRef:s,yes:c})=>S([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),staging:J({name:`staging`,cmds:{reassign:L({name:`reassign`,args:{json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await b();if(e){console.log(JSON.stringify({...t,notices:X}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${X.join(` `)}`)}}),url:L({name:`url`,args:{json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await y();console.log(e?JSON.stringify({url:t}):t)}})}}),secrets:J({name:`secrets`,cmds:{"rotate-access-token":L({name:`rotate-access-token`,args:{environment:G({type:H(_),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:z({long:`yes`,short:`y`,description:`Confirm immediate signing-secret replacement and invalidation of outstanding access JWTs.`,defaultValue:()=>!1})},handler:async({environment:e,yes:t})=>{if(!t)throw Error(`Access-token signing-secret rotation requires --yes because it immediately invalidates outstanding access JWTs.`);await g({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:L({name:`status`,args:{environment:G({type:W(H(_)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await te({environment:e});console.log(t?JSON.stringify(n):ce(n))}}),set:L({name:`set`,args:{environment:G({type:H(_),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:G({type:q,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{await x({environment:e,name:t,value:await le(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`)}}),discard:L({name:`discard`,args:{environment:G({type:H(_),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:G({type:q,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await ee({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),typecheck:L({name:`typecheck`,args:{},handler:j}),dev:L({name:`dev`,args:{debug:U({long:`debug`,type:W(Y),description:`Launch a development feature in isolated debug mode.`}),https:z({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),host:U({long:`host`,type:W(q),description:`Host address for the web development server.`}),managed:z({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:z({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),platform:G({type:W(H(w)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:G({type:W(q),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:U({long:`port`,type:W(V),description:`Port for the web development server.`}),verbose:z({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o,port:s,verbose:c})=>re({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o??`web`,verbose:c,webPort:s})}),upgrade:J({name:`upgrade`,cmds:{"ensure-template-remote":L({name:`ensure-template-remote`,args:{remote:U({long:`remote`,type:q,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:z({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>T({fetch:!e,remote:t})}),"check-skill-current":L({name:`check-skill-current`,args:{target:U({long:`target`,type:q,description:`Target Coreframe template git ref.`}),apply:z({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=M({apply:e,target:t})}}),"fast-forward-template-files":L({name:`fast-forward-template-files`,args:{target:U({long:`target`,type:q,description:`Target Coreframe template git ref.`}),base:U({long:`base`,type:W(q),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:z({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>N({apply:e,base:t,target:n})}),"sync-coreframe-packages":L({name:`sync-coreframe-packages`,args:{target:U({long:`target`,type:q,description:`Target Coreframe template git ref.`}),apply:z({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>P({apply:e,target:t})})}}),recipes:J({name:`recipes`,cmds:{apply:L({name:`apply`,args:{recipe:G({type:oe,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:U({long:`target`,type:W(q),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:U({long:`remote`,type:q,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:z({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>D(E({fetch:!e,name:t,remote:n,target:r}))}),list:L({name:`list`,args:{target:U({long:`target`,type:W(q),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:U({long:`remote`,type:q,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:z({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>k(O({fetch:!e,remote:t,target:n}))})}}),db:J({name:`db`,cmds:{ensure:L({name:`ensure`,args:{},handler:f}),generate:L({name:`generate`,args:{args:K({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>s(`generate`,e)}),migrate:L({name:`migrate`,args:{args:K({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>s(`migrate`,e)}),"migrate-held":L({name:`migrate-held`,args:{confirm:U({long:`confirm`,type:W(H([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>m({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":L({name:`migrate-local`,args:{},handler:l}),"migrations-check":L({name:`migrations-check`,args:{},handler:C}),reset:L({name:`reset`,args:{},handler:u}),seed:L({name:`seed`,args:{},handler:()=>c()}),"schema-check":L({name:`schema-check`,args:{seed:z({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>h({seed:e})}),setup:L({name:`setup`,args:{},handler:()=>d()}),studio:L({name:`studio`,args:{args:K({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>s(`studio`,e)})}})}});import.meta.main&&A($,{formatMessage:process.argv[2]===`db`?p:void 0});function ce(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
3
- `)}async function le(e){if(!process.stdin.isTTY){let e=``;for await(let t of process.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await F.password({message:`Enter the new value for ${e}`});if(F.isCancel(t))throw F.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}export{$ as coreframeCli};
2
+ import{assertAssetCredentialProfile as e,configureAssetCredentials as t}from"./assets/credentials.js";import{addAsset as n,buildAssets as r,checkAssets as i,printAssetResult as a,publishAssets as o}from"./assets/workflows.js";import"./assets.js";import{runDrizzleKitCommand as s}from"./db/drizzle-kit.js";import{seedLocalDb as c}from"./db/seed.js";import{migrateLocalDb as l}from"./db/migrate.js";import{resetLocalDb as u}from"./db/reset.js";import{setupLocalDb as d}from"./db/setup.js";import{ensureLocalDb as f}from"./db/ensure.js";import{formatDbErrorMessage as p}from"./db/error.js";import{migrateHeldMigrations as m}from"./db/migrate-held.js";import{checkSchemaPush as h}from"./db/schema-check.js";import{rotateAccessTokenSigningSecret as g}from"./deploy/access-token-secret.js";import{deployEnvironments as _,tauriReleasePlatforms as v}from"./deploy/config.js";import{discoverStagingUrl as y,reassignStagingHostname as b}from"./staging.js";import{discardPendingWorkerSecret as ee,inspectWorkerEnvironment as te,queueWorkerSecret as x}from"./worker-environment.js";import{deployProject as S}from"./deploy.js";import{checkDeployMigrations as C}from"./deploy/check-migrations.js";import{devDebugFeatures as w,devPlatforms as T,runDevServer as ne}from"./dev.js";import{validateRecipeName as re}from"./recipes/manifest.js";import{ensureTemplateRemote as E}from"./upgrade/ensure-template-remote.js";import{applyRecipe as D,printAppliedRecipe as O}from"./recipes/apply.js";import{listRecipes as k,printRecipeCatalog as A}from"./recipes/list.js";import{run as j}from"./runner.js";import{typecheckProject as M}from"./typecheck.js";import{checkUpgradeSkillCurrent as N}from"./upgrade/check-skill-current.js";import{fastForwardTemplateFiles as P}from"./upgrade/fast-forward-template-files.js";import{syncCoreframePackages as F}from"./upgrade/sync-coreframe-packages.js";import{array as I,command as L,extendType as R,flag as z,multioption as B,number as ie,oneOf as V,option as H,optional as U,positional as W,rest as G,string as K,subcommands as q}from"@alloc/cmd-ts";import*as J from"@clack/prompts";const Y=R(V(w),{displayName:`feature`,from:async e=>e}),X=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],Z=[`Use a B2 Multi-Bucket Application Key restricted to the configured private source and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),ae=R(K,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),oe=R(K,{displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return re(e)}}),se=R(K,{displayName:`profile`,async from(t){return e(t)}}),Q=R(K,{displayName:`pack`,description:`Asset pack name, such as training-videos.`,async from(e){if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e))throw Error(`Asset pack names must use lowercase hyphen-separated segments.`);return e}}),$=q({name:`coreframe`,cmds:{assets:q({name:`assets`,cmds:{configure:L({name:`configure`,description:`Store a Backblaze B2 asset key in the operating system credential store. ${Z}`,args:{profile:W({type:se,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{J.note(Z,`Required B2 key access`);let n=await J.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(J.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);let r=await J.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(J.isCancel(r))throw Error(`Asset credential configuration was cancelled.`);await t({applicationKey:r,applicationKeyId:n.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:L({name:`add`,args:{file:W({type:K,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:H({long:`id`,type:K,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:H({long:`alt`,type:U(K),description:`Required alt text for raster image and SVG assets.`}),pack:H({long:`pack`,type:U(Q),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:H({long:`widths`,type:U(ae),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:r,json:i,pack:o,variantWidths:s})=>a(await n({alt:e,file:t,id:r,pack:o,variantWidths:s}),i)}),build:L({name:`build`,args:{id:H({long:`id`,type:U(K),description:`Build only one logical asset ID.`}),pack:H({long:`pack`,type:U(Q),description:`Build only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>a(await r({id:e,pack:n}),t)}),check:L({name:`check`,args:{fix:z({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:H({long:`pack`,type:U(Q),description:`Check only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await i({fix:e,pack:n});a(r,t),r.ok||(process.exitCode=1)}}),publish:L({name:`publish`,args:{pack:H({long:`pack`,type:U(Q),description:`Publish only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await o({pack:t});a(n,e),n.ok||(process.exitCode=1)}}),status:L({name:`status`,args:{pack:H({long:`pack`,type:U(Q),description:`Report status for only one named asset pack.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await i({pack:t});a(n,e),n.ok||(process.exitCode=1)}})}}),deploy:L({name:`deploy`,args:{environment:W({type:V(_),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:z({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:z({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:z({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:B({long:`tauri-local-platform`,type:I(V(v)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:H({long:`tauri-workflow-name`,type:U(K),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:B({long:`tauri-workflow-platform`,type:I(V(v)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:H({long:`tauri-workflow-ref`,type:U(K),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:z({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,tauriLocalPlatforms:i,tauriWorkflowName:a,tauriWorkflowPlatforms:o,tauriWorkflowRef:s,yes:c})=>S([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),staging:q({name:`staging`,cmds:{reassign:L({name:`reassign`,args:{json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await b();if(e){console.log(JSON.stringify({...t,notices:X}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${X.join(` `)}`)}}),url:L({name:`url`,args:{json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await y();console.log(e?JSON.stringify({url:t}):t)}})}}),secrets:q({name:`secrets`,cmds:{"rotate-access-token":L({name:`rotate-access-token`,args:{environment:W({type:V(_),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:z({long:`yes`,short:`y`,description:`Confirm immediate signing-secret replacement and invalidation of outstanding access JWTs.`,defaultValue:()=>!1})},handler:async({environment:e,yes:t})=>{if(!t)throw Error(`Access-token signing-secret rotation requires --yes because it immediately invalidates outstanding access JWTs.`);await g({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:L({name:`status`,args:{environment:W({type:U(V(_)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await te({environment:e});console.log(t?JSON.stringify(n):ce(n))}}),set:L({name:`set`,args:{environment:W({type:V(_),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:W({type:K,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{await x({environment:e,name:t,value:await le(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`)}}),discard:L({name:`discard`,args:{environment:W({type:V(_),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:W({type:K,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await ee({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),typecheck:L({name:`typecheck`,args:{},handler:M}),dev:L({name:`dev`,args:{debug:H({long:`debug`,type:U(Y),description:`Launch a development feature in isolated debug mode.`}),https:z({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),host:H({long:`host`,type:U(K),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),managed:z({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:z({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),platform:W({type:U(V(T)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:W({type:U(K),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:H({long:`port`,type:U(ie),description:`Port for the web development server.`}),verbose:z({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o,port:s,verbose:c})=>ne({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o??`web`,verbose:c,webPort:s})}),upgrade:q({name:`upgrade`,cmds:{"ensure-template-remote":L({name:`ensure-template-remote`,args:{remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:z({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>E({fetch:!e,remote:t})}),"check-skill-current":L({name:`check-skill-current`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:z({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=N({apply:e,target:t})}}),"fast-forward-template-files":L({name:`fast-forward-template-files`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),base:H({long:`base`,type:U(K),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:z({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>P({apply:e,base:t,target:n})}),"sync-coreframe-packages":L({name:`sync-coreframe-packages`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:z({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>F({apply:e,target:t})})}}),recipes:q({name:`recipes`,cmds:{apply:L({name:`apply`,args:{recipe:W({type:oe,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:z({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>O(D({fetch:!e,name:t,remote:n,target:r}))}),list:L({name:`list`,args:{target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:z({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>A(k({fetch:!e,remote:t,target:n}))})}}),db:q({name:`db`,cmds:{ensure:L({name:`ensure`,args:{},handler:f}),generate:L({name:`generate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>s(`generate`,e)}),migrate:L({name:`migrate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>s(`migrate`,e)}),"migrate-held":L({name:`migrate-held`,args:{confirm:H({long:`confirm`,type:U(V([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>m({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":L({name:`migrate-local`,args:{},handler:l}),"migrations-check":L({name:`migrations-check`,args:{},handler:C}),reset:L({name:`reset`,args:{},handler:u}),seed:L({name:`seed`,args:{},handler:()=>c()}),"schema-check":L({name:`schema-check`,args:{seed:z({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>h({seed:e})}),setup:L({name:`setup`,args:{},handler:()=>d()}),studio:L({name:`studio`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>s(`studio`,e)})}})}});import.meta.main&&j($,{formatMessage:process.argv[2]===`db`?p:void 0});function ce(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
3
+ `)}async function le(e){if(!process.stdin.isTTY){let e=``;for await(let t of process.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await J.password({message:`Enter the new value for ${e}`});if(J.isCancel(t))throw J.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}export{$ as coreframeCli};
package/dist/dev.d.ts CHANGED
@@ -8,7 +8,6 @@ type DevServerOptions = {
8
8
  env?: NodeJS.ProcessEnv;
9
9
  host?: string | true;
10
10
  https?: boolean;
11
- input?: NodeJS.ReadableStream;
12
11
  interactive?: boolean;
13
12
  managed?: boolean;
14
13
  noManaged?: boolean;
@@ -29,7 +28,6 @@ declare function runDevServer({
29
28
  env,
30
29
  host,
31
30
  https,
32
- input,
33
31
  interactive,
34
32
  managed,
35
33
  noManaged,
package/dist/dev.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{readProjectConfig as e}from"./config.js";import{fs as t,net as n}from"./environment.js";import{ProjectPostgresAlreadyRunningError as r,startProjectPostgres as i,stopProjectPostgres as a}from"./db/local-postgres.js";import{resolveMobileDevHost as o,selectMobileDevDevice as s}from"./dev-device.js";import{devHttpsCertEnv as ee,devHttpsKeyEnv as c,prepareDevHttps as l}from"./dev-https.js";import{acquireDevLock as u}from"./dev-lock.js";import{managedDevEnv as te}from"./managed-dev-protocol.js";import{isManagedDevCheckout as d,isPrimaryCheckout as ne}from"./managed-dev.js";import{createTauriDevOutput as f}from"./tauri-dev-output.js";import p from"node:path";import re from"nano-spawn";import*as m from"@clack/prompts";import h from"node:process";import*as ie from"node:readline";import{createPrefixStream as g,supervise as _}from"procband";const v=[`web`,`desktop`,`ios`,`android`],y=[`managed-dev-overlay`],b=`VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG`;function x(e){let t=e.dev?.platforms??[`web`];for(let e of t)if(!v.includes(e))throw Error(`Invalid development platform "${String(e)}". Expected one of: ${v.join(`, `)}.`);return[...new Set(t)]}const S=p.resolve(`node_modules`,`.bin`),C=h.platform===`win32`?`pnpm.cmd`:`pnpm`,ae=h.platform===`win32`?`portless.cmd`:`portless`,oe=h.platform===`win32`?`react-router.cmd`:`react-router`,se=h.platform===`win32`?`turso.cmd`:`turso`;async function w({cwd:r=h.cwd(),debug:i,device:a,env:v=h.env,host:y,https:x=!1,input:w=h.stdin,interactive:M=h.stdin.isTTY===!0,managed:N=!1,noManaged:P=!1,platform:F=`web`,verbose:I=!1,webPort:L}={}){let R=v.PATH??v.Path??``,z=F===`web`?j(L??v.COREFRAME_WEB_PORT):void 0,B,V,H,U,W,G=!1,K,q=v;if(N&&P)throw Error(`Cannot use --managed and --no-managed together.`);if(i===`managed-dev-overlay`&&N)throw Error(`Cannot use --managed with --debug managed-dev-overlay.`);if(x&&F!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(a!==void 0&&F!==`ios`&&F!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);if(F===`web`&&v.TAURI_ENV_PLATFORM!==void 0&&v.COREFRAME_TAURI_DEV!==`1`){let e=v.TAURI_ENV_PLATFORM===`ios`||v.TAURI_ENV_PLATFORM===`android`?v.TAURI_ENV_PLATFORM:`desktop`;throw Error(`Direct Tauri development is not supported. Run \`pnpm dev ${e}\` instead.`)}let J=await u({cwd:r,interactive:M});if(!J)return;let Y=()=>{G||(G=!0,V?.kill(`SIGTERM`),W?.kill(`SIGTERM`),B?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),U?.kill(`SIGTERM`))},X=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>{K??=e,Y()};return h.on(e,t),{handler:t,signal:e}}),Z=async e=>{let t=_(e);V=t;try{await t.expectSuccess()}catch(e){if(!G)throw e}finally{V===t&&(V=void 0)}};try{let u=F===`ios`||F===`android`?F:void 0,T=u?await s({env:v,interactive:M,platform:u,target:a}):void 0,j=u&&T?await o({device:T,host:y,interactive:M,platform:u}):void 0,L=j?!0:y,V=await e({cwd:r}),K=F===`web`&&v.PORTLESS!==`0`&&v.TAURI_ENV_PLATFORM===void 0&&await ne(r),X=x&&!K?await l({cwd:r}):void 0;q={...v,...i===`managed-dev-overlay`?{[b]:`1`}:void 0,...F===`web`?void 0:{COREFRAME_TAURI_DEV:`1`,TAURI_ENV_PLATFORM:k(F),...j?{TAURI_DEV_HOST:j}:void 0},...X?{[ee]:X.cert,[c]:X.key}:void 0};let Q=async()=>{let e=!1,t=M?ie.createInterface({input:w}):void 0;t?.on(`line`,t=>{t.trim().toLowerCase()!==`r`||!W||e||(e=!0,W.kill(`SIGTERM`)?m.log.info(`Restarting the Vite development server.`):e=!1)}),t&&m.log.info(`Press r + Enter to restart the Vite development server.`);try{for(;;){e=!1,W=_({name:`web`,command:K?ae:oe,args:K?ce({host:L,port:z}):A({host:L,port:z}),cwd:r,env:{...q,CLOUDFLARE_ENV:`development`,PATH:S+p.delimiter+R}}),await W.wait();let t=W;if(W=void 0,!e){G||await t.expectSuccess();return}}}finally{t?.close()}},$=async()=>{if(F===`web`){await Q();return}let e=Q().then(()=>{if(!G)throw Error(`The Vite development server stopped while Tauri was still running.`)}),t,n;if(F===`ios`&&!I){n=g({label:`ios`}),n.pipe(h.stdout,{end:!1});try{t=await f({output:n}),m.log.info(`Full iOS log: ${t.logFile}`)}catch{n.end(),n=void 0,m.log.warn(`Could not create the temporary iOS log; showing full Tauri output.`)}}B=re(C,O(F,T?.name,j),{cwd:r,env:v,stdio:t?[`inherit`,`pipe`,`pipe`]:`inherit`});let i=t?.consume(B),a=B.catch(async e=>{throw G||(await i,await t?.reportFailure()),e});try{await Promise.race([e,a])}finally{Y(),await Promise.allSettled([e,B,i]),await t?.close(),n?.end(),B=void 0}};if(i!==`managed-dev-overlay`&&(N||M&&!P)&&await d(r)&&(q={...q,[te]:`1`}),G)return;if(V.database?.dialect===`sqlite`){let e=await n.getAvailablePort(),i=p.resolve(r,`.coreframe`),a=p.join(i,`turso.db`);if(await t.mkdir(i,{recursive:!0}),q={...q,TURSO_DATABASE_URL:`http://127.0.0.1:${e}`,TURSO_AUTH_TOKEN:`dev`},U=_({name:`turso`,command:se,args:[`dev`,`--port`,String(e),`--db-file`,a],cwd:r,env:v}),await U.waitFor(`listening`),await Z({name:`db`,command:C,args:[`db`,`ensure`],cwd:r,env:q,prefix:!1}),G)return}if(D(V)){let e=g({label:`postgres`});e.pipe(h.stdout,{end:!1});try{let t=await E({config:V,cwd:r,env:q,failIfRunning:!0,interactive:M,isStopping:()=>G,postgresOutput:e,takeoverApproved:J.takeoverApproved});if(!t)return;H=t,q=t.env;try{G||await Z({name:`db`,command:C,args:[`db`,`ensure`],cwd:r,env:q,prefix:!1}),G||await $()}finally{await t[Symbol.asyncDispose](),H===t&&(H=void 0)}}finally{e.end()}return}await $()}finally{Y();let e;try{await H?.[Symbol.asyncDispose]()}catch(t){e=t}finally{for(let{handler:e,signal:t}of X)h.off(t,e);K&&(h.exitCode??=K===`SIGINT`?130:143)}T(e),await J.release()}}function T(e){if(e)throw e}async function E({interactive:e,isStopping:t,takeoverApproved:n,...o}){try{return await i(o)}catch(s){if(!(s instanceof r)||!e)throw s;if(!n){let e=await m.confirm({initialValue:!1,message:`PostgreSQL is already running for this project (PID ${s.pid}). Stop it and start here?`});if(m.isCancel(e)||!e){m.cancel(`Keeping the existing PostgreSQL process.`);return}}return await a(s),t()?void 0:i(o)}}function D(e){return(e.database?.dialect??`postgres`)===`postgres`}function O(e,t,n){return[`exec`,`tauri`,...e===`desktop`?[]:[e],`dev`,`--config`,JSON.stringify({build:{beforeDevCommand:``}}),...n===void 0?[]:[`--host=${n}`],...t===void 0?[]:[t]]}function k(e){return e===`desktop`?h.platform===`win32`?`windows`:h.platform:e}function A({host:e,port:t}){return[`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)]]}function ce({host:e,port:t}){return[`run`,...t===void 0?[]:[`--app-port`,String(t)],`react-router`,...A({host:e,port:void 0})]}function j(e){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw Error(`COREFRAME_WEB_PORT must be a valid TCP port.`);return t}export{y as devDebugFeatures,v as devPlatforms,b as managedDevOverlayDebugEnv,x as resolveDevPlatforms,w as runDevServer};
2
+ import{readProjectConfig as e}from"./config.js";import{fs as t,net as n}from"./environment.js";import{ProjectPostgresAlreadyRunningError as r,startProjectPostgres as i,stopProjectPostgres as a}from"./db/local-postgres.js";import{resolveMobileDevHost as o,selectMobileDevDevice as s}from"./dev-device.js";import{devHttpsCertEnv as ee,devHttpsKeyEnv as te,prepareDevHttps as ne}from"./dev-https.js";import{acquireDevLock as c}from"./dev-lock.js";import{managedDevEnv as l}from"./managed-dev-protocol.js";import{isManagedDevCheckout as re,isPrimaryCheckout as ie}from"./managed-dev.js";import{createTauriDevOutput as u}from"./tauri-dev-output.js";import d from"node:path";import f from"nano-spawn";import{finished as p}from"node:stream/promises";import*as m from"@clack/prompts";import h from"node:process";import{once as g}from"node:events";import{determineAgent as ae}from"@vercel/detect-agent";import{createPrefixStream as _,supervise as v}from"procband";const y=[`web`,`desktop`,`ios`,`android`],b=[`managed-dev-overlay`],x=`VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG`;function S(e){let t=e.dev?.platforms??[`web`];for(let e of t)if(!y.includes(e))throw Error(`Invalid development platform "${String(e)}". Expected one of: ${y.join(`, `)}.`);return[...new Set(t)]}const C=d.resolve(`node_modules`,`.bin`),w=h.platform===`win32`?`pnpm.cmd`:`pnpm`,T=h.platform===`win32`?`portless.cmd`:`portless`,oe=h.platform===`win32`?`react-router.cmd`:`react-router`,se=h.platform===`win32`?`turso.cmd`:`turso`;async function E({cwd:r=h.cwd(),debug:i,device:a,env:g=h.env,host:y,https:b=!1,interactive:S=h.stdin.isTTY===!0,managed:E=!1,noManaged:P=!1,platform:F=`web`,verbose:I=!1,webPort:L}={}){let R=g.PATH??g.Path??``,z=F===`web`?N(L??g.COREFRAME_WEB_PORT):void 0,B,V,H,U,W,G=!1,K,q=g;if(E&&P)throw Error(`Cannot use --managed and --no-managed together.`);if(i===`managed-dev-overlay`&&E)throw Error(`Cannot use --managed with --debug managed-dev-overlay.`);if(b&&F!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(a!==void 0&&F!==`ios`&&F!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);if(F===`web`&&g.TAURI_ENV_PLATFORM!==void 0&&g.COREFRAME_TAURI_DEV!==`1`){let e=g.TAURI_ENV_PLATFORM===`ios`||g.TAURI_ENV_PLATFORM===`android`?g.TAURI_ENV_PLATFORM:`desktop`;throw Error(`Direct Tauri development is not supported. Run \`pnpm dev ${e}\` instead.`)}let J=await c({cwd:r,interactive:S});if(!J)return;let Y=()=>{G||(G=!0,V?.kill(`SIGTERM`),W?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),B?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),U?.kill(`SIGTERM`))},X=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>{K??=e,Y()};return h.on(e,t),{handler:t,signal:e}}),Z=async e=>{let t=v(e);V=t;try{await t.expectSuccess()}catch(e){if(!G)throw e}finally{V===t&&(V=void 0)}};try{let c=F===`ios`||F===`android`?F:void 0,O=c?await s({env:g,interactive:S,platform:c,target:a}):void 0,N=c&&O?await o({device:O,host:y,interactive:S,platform:c}):void 0,L=N?!0:y,V=await e({cwd:r}),K=F===`web`&&g.PORTLESS!==`0`&&g.TAURI_ENV_PLATFORM===void 0&&!(await ae()).isAgent&&await ie(r),X=b&&!K?await ne({cwd:r}):void 0;q={...g,...i===`managed-dev-overlay`?{[x]:`1`}:void 0,...F===`web`?void 0:{COREFRAME_TAURI_DEV:`1`,TAURI_ENV_PLATFORM:le(F),...N?{TAURI_DEV_HOST:N}:void 0},...X?{[ee]:X.cert,[te]:X.key}:void 0};let Q=async()=>{let e=_({label:`web`}),t=_({color:`red`,label:`web`});e.pipe(h.stdout,{end:!1}),t.pipe(h.stderr,{end:!1}),W=f(K?T:oe,K?M({host:L,port:z}):j({host:L,port:z}),{cwd:r,env:{...q,CLOUDFLARE_ENV:`development`,PATH:C+d.delimiter+R},stdin:`inherit`});let n=Promise.allSettled([D(W.stdout,e),D(W.stderr,t)]);try{await W;let e=(await n).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!G)throw e}finally{await n,e.end(),t.end(),await Promise.allSettled([p(e),p(t)]),W=void 0}},$=async()=>{if(F===`web`){await Q();return}let e=Q().then(()=>{if(!G)throw Error(`The Vite development server stopped while Tauri was still running.`)}),t,n;if(F===`ios`&&!I){n=_({label:`ios`}),n.pipe(h.stdout,{end:!1});try{t=await u({output:n}),m.log.info(`Full iOS log: ${t.logFile}`)}catch{n.end(),n=void 0,m.log.warn(`Could not create the temporary iOS log; showing full Tauri output.`)}}B=f(w,ce(F,O?.name,N),{cwd:r,env:g,stdio:t?[`inherit`,`pipe`,`pipe`]:`inherit`});let i=t?.consume(B),a=B.catch(async e=>{throw G||(await i,await t?.reportFailure()),e});try{await Promise.race([e,a])}finally{Y(),await Promise.allSettled([e,B,i]),await t?.close(),n?.end(),B=void 0}};if(i!==`managed-dev-overlay`&&(E||S&&!P)&&await re(r)&&(q={...q,[l]:`1`}),G)return;if(V.database?.dialect===`sqlite`){let e=await n.getAvailablePort(),i=d.resolve(r,`.coreframe`),a=d.join(i,`turso.db`);if(await t.mkdir(i,{recursive:!0}),q={...q,TURSO_DATABASE_URL:`http://127.0.0.1:${e}`,TURSO_AUTH_TOKEN:`dev`},U=v({name:`turso`,command:se,args:[`dev`,`--port`,String(e),`--db-file`,a],cwd:r,env:g}),await U.waitFor(`listening`),await Z({name:`db`,command:w,args:[`db`,`ensure`],cwd:r,env:q,prefix:!1}),G)return}if(A(V)){let e=_({label:`postgres`});e.pipe(h.stdout,{end:!1});try{let t=await k({config:V,cwd:r,env:q,failIfRunning:!0,interactive:S,isStopping:()=>G,postgresOutput:e,takeoverApproved:J.takeoverApproved});if(!t)return;H=t,q=t.env;try{G||await Z({name:`db`,command:w,args:[`db`,`ensure`],cwd:r,env:q,prefix:!1}),G||await $()}finally{await t[Symbol.asyncDispose](),H===t&&(H=void 0)}}finally{e.end()}return}await $()}finally{Y();let e;try{await H?.[Symbol.asyncDispose]()}catch(t){e=t}finally{for(let{handler:e,signal:t}of X)h.off(t,e);K&&(h.exitCode??=K===`SIGINT`?130:143)}O(e),await J.release()}}async function D(e,t){for await(let n of e)t.write(`${n}\n`)||await g(t,`drain`)}function O(e){if(e)throw e}async function k({interactive:e,isStopping:t,takeoverApproved:n,...o}){try{return await i(o)}catch(s){if(!(s instanceof r)||!e)throw s;if(!n){let e=await m.confirm({initialValue:!1,message:`PostgreSQL is already running for this project (PID ${s.pid}). Stop it and start here?`});if(m.isCancel(e)||!e){m.cancel(`Keeping the existing PostgreSQL process.`);return}}return await a(s),t()?void 0:i(o)}}function A(e){return(e.database?.dialect??`postgres`)===`postgres`}function ce(e,t,n){return[`exec`,`tauri`,...e===`desktop`?[]:[e],`dev`,`--config`,JSON.stringify({build:{beforeDevCommand:``}}),...n===void 0?[]:[`--host=${n}`],...t===void 0?[]:[t]]}function le(e){return e===`desktop`?h.platform===`win32`?`windows`:h.platform:e}function j({host:e,port:t}){return[`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)]]}function M({host:e,port:t}){return[`run`,...t===void 0?[]:[`--app-port`,String(t)],`react-router`,...j({host:e,port:void 0})]}function N(e){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw Error(`COREFRAME_WEB_PORT must be a valid TCP port.`);return t}export{b as devDebugFeatures,y as devPlatforms,x as managedDevOverlayDebugEnv,S as resolveDevPlatforms,E as runDevServer};
@@ -20,12 +20,16 @@ type ManagedDevDraft = {
20
20
  };
21
21
  type ManagedDevCheck = {
22
22
  command: "pnpm test" | "pnpm typecheck";
23
+ dismissed?: boolean;
24
+ failureId?: string;
23
25
  output?: string;
24
26
  status: "failed" | "passed" | "pending" | "running";
25
27
  };
28
+ type ManagedDevCheckTrigger = "database-recovery" | "dependency-recovery" | "synchronization";
26
29
  type ManagedDevChecks = {
27
30
  commit: string;
28
31
  commands: ManagedDevCheck[];
32
+ trigger: ManagedDevCheckTrigger;
29
33
  };
30
34
  type ManagedDevSetupFailure = {
31
35
  command: "pnpm db migrate" | "pnpm db setup" | "pnpm install --frozen-lockfile";
@@ -51,6 +55,9 @@ type ManagedDevStatus = {
51
55
  type ManagedDevAction = {
52
56
  id: string;
53
57
  type: "acknowledge-codex";
58
+ } | {
59
+ failureId: string;
60
+ type: "dismiss-check";
54
61
  } | {
55
62
  type: "apply";
56
63
  fingerprint?: string;
@@ -83,12 +90,19 @@ type ManagedDevCodexMessage = {
83
90
  kind: "agent" | "thought" | "user";
84
91
  text: string;
85
92
  };
93
+ type ManagedDevRebasedCommit = {
94
+ commit: string;
95
+ shortCommit: string;
96
+ subject: string;
97
+ };
86
98
  type ManagedDevCodexCompletion = {
99
+ commits?: ManagedDevRebasedCommit[];
87
100
  finalMessage: string;
88
101
  id: string;
89
102
  messages: ManagedDevCodexMessage[];
90
103
  };
91
104
  type ManagedDevCodexEvent = {
105
+ commits: ManagedDevRebasedCommit[];
92
106
  message: ManagedDevCodexMessage;
93
107
  phase: "start";
94
108
  } | {
@@ -97,6 +111,9 @@ type ManagedDevCodexEvent = {
97
111
  } | {
98
112
  finalMessage: string;
99
113
  phase: "complete";
114
+ } | {
115
+ commits: ManagedDevRebasedCommit[];
116
+ phase: "progress";
100
117
  } | {
101
118
  phase: "error";
102
119
  };
@@ -115,4 +132,4 @@ type ManagedDevStatusResponse = {
115
132
  status: ManagedDevStatus;
116
133
  };
117
134
  //#endregion
118
- export { ManagedDevAction, ManagedDevActionRequest, ManagedDevActionResponse, ManagedDevActionResult, ManagedDevCheck, ManagedDevChecks, ManagedDevCodexCompletion, ManagedDevCodexEvent, ManagedDevCodexMessage, ManagedDevCodexResponse, ManagedDevDraft, ManagedDevSetupFailure, ManagedDevStatus, ManagedDevStatusResponse, ManagedDevTarget, managedDevEnv, managedDevEvents };
135
+ export { ManagedDevAction, ManagedDevActionRequest, ManagedDevActionResponse, ManagedDevActionResult, ManagedDevCheck, ManagedDevCheckTrigger, ManagedDevChecks, ManagedDevCodexCompletion, ManagedDevCodexEvent, ManagedDevCodexMessage, ManagedDevCodexResponse, ManagedDevDraft, ManagedDevRebasedCommit, ManagedDevSetupFailure, ManagedDevStatus, ManagedDevStatusResponse, ManagedDevTarget, managedDevEnv, managedDevEvents };
@@ -1,4 +1,5 @@
1
- import{createHash as e,randomBytes as t}from"node:crypto";import{access as n,copyFile as r,mkdir as i,mkdtemp as a,open as o,readFile as s,realpath as c,rm as l,unlink as u,writeFile as d}from"node:fs/promises";import f from"node:path";import p,{SubprocessError as m}from"nano-spawn";import{pathToFileURL as h}from"node:url";import{constants as g,watch as _}from"node:fs";import v from"node:process";import{resolve as y}from"import-meta-resolve";const b=`refs/heads/main`,x=`refs/heads/dev`,ee=`refs/remotes/origin/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i,S=`coreframe-managed-dev-codex-completion.json`,C=`coreframe-managed-dev-setup-failure.json`;async function w(e=v.cwd()){let t=await ae(e);return t.primary&&t.branch===`main`&&t.head===t.main}async function T(e=v.cwd()){try{let{commonDir:t,gitDir:n}=await E(e);return n===t}catch{return!1}}async function E(e){let t=await c(await q(e,[`rev-parse`,`--show-toplevel`])),n=await c(e),r=f.resolve(n,await q(e,[`rev-parse`,`--git-dir`])),i=f.resolve(n,await q(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function D({config:e,cwd:n=v.cwd(),env:r=v.env,onRestart:i=()=>void 0,onStatusChange:a=()=>void 0,remoteCheckInterval:o=6e4,runCheck:s=e=>de(n,r,e),watchState:c=oe}){let l=r,m={mode:`waiting`,warnings:[]},h=!1,g=!1,_=!1,y=!1,w,T,E,D,O,k=[],A,j,P=Promise.resolve(),F=()=>{h||a(m)},I=async({fetch:e=!1}={})=>{if(!(!g||h||!T)){if(_){y=!0;return}try{let[t,r,i]=await Promise.all([q(n,[`rev-parse`,`--abbrev-ref`,`HEAD`]),q(n,[`rev-parse`,`HEAD`]),q(n,[`rev-parse`,b])]);if(t!==`main`||r!==i){m={message:`Managed synchronization is paused until the primary checkout is back on local main.`,mode:`waiting`,warnings:[]};return}r!==w&&(w=r,A=void 0);let a=await M(n);if(a.tracked||a.untracked.length>0){m={...m,currentCommit:w,draft:a,message:void 0,mode:`managed`,proposal:V(a.fingerprint),target:void 0};return}e&&await J(n,[`remote`,`get-url`,`origin`])&&await K(n,[`fetch`,`origin`,`+refs/heads/main:${ee}`]);let o=await J(n,[`rev-parse`,x]),s=await J(n,[`rev-parse`,ee]),c=[...s?[{commit:s,source:`upstream`}]:[],...o?[{commit:o,source:`dev`}]:[]],l;for(let e of c)if(!await Se(n,e.commit,w)){l=e;break}m={...m,currentCommit:w,draft:void 0,message:void 0,mode:`managed`,proposal:void 0,target:l===void 0?void 0:await ve(n,l.commit,l.source)}}catch(e){m={...m,message:Z(e),warnings:[Z(e)]}}finally{F()}}},L=()=>{clearTimeout(O),O=setTimeout(()=>void I(),50),O.unref()},R=e=>{let t=async()=>{let t=[{command:`pnpm typecheck`,status:`running`},{command:`pnpm test`,status:`pending`}],n=()=>{m={...m,checks:{commit:e,commands:structuredClone(t)}},F()};n();for(let[e,r]of[`typecheck`,`test`].entries()){e>0&&(t[e].status=`running`,n());try{await s(r),t[e].status=`passed`}catch(n){t[e].status=`failed`,t[e].output=fe(n)}n()}};P=P.then(t,t)},z=async()=>{if(g||h)return;let e=await ae(n);if(!e.primary){m={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}`),m={message:t,mode:`unmanaged`,warnings:[]},F();return}E=f.join(e.commonDir,`coreframe-managed-dev.lock`),await ye(E),await J(n,[`rev-parse`,`--verify`,x])||await K(n,[`branch`,`dev`,e.head]),T=e,w=e.head,g=!0,m={codexCompletion:await ne(e.commonDir),currentCommit:e.head,mode:`managed`,setupFailure:await ie(e.commonDir,e.head),warnings:[]},F(),k=await c(e,L),D=setInterval(()=>void I({fetch:!0}),o),D.unref(),await I(),I({fetch:!0})},me=async(e,{onCodexEvent:t=()=>void 0}={})=>{if(!g||m.mode!==`managed`)throw Error(`Managed development is not active.`);if(_)throw Error(`Another managed development action is already running.`);let r=[],i,a=e=>{e.phase===`start`||e.phase===`message`?r.push(e.message):e.phase===`complete`&&(i=e.finalMessage),t(e)};_=!0,m={...m,busy:Te(e),message:void 0},F();try{if(e.type===`acknowledge-codex`)m.codexCompletion?.id===e.id&&await Ae();else if(e.type===`reject`)m={...m,draft:void 0,proposal:void 0};else if(e.type===`prepare`){let t=B(e.target),r=await M(n);r.tracked||r.untracked.length>0?m={...m,draft:r,proposal:V(r.fingerprint)}:await W({onCodexEvent:a,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(j??=ce(`codex`,l),!await j)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 se(n,l,t.context)}catch(e){r=``,m={...m,warnings:[...m.warnings,`Codex could not generate a commit message: ${Z(e)}`]}}A={fingerprint:t.fingerprint,message:r}}m={...m,draft:t,proposal:r}}else if(e.type===`commit`){let t=await U(e);m={...m,currentCommit:t,draft:void 0,message:void 0,proposal:void 0,target:void 0},L()}else if(e.type===`retry-install`)await he();else if(e.type===`reset-database`)await be();else{let t=B(e.target),r=await M(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(we(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await W({fingerprint:e.fingerprint,message:e.message,onCodexEvent:a,source:t.source,target:e.target,untracked:e.untracked})}}finally{_=!1,m={...m,busy:void 0},F(),y&&(y=!1,L())}return i&&await ke(i,r),{status:m}},B=e=>{if(!m.target||m.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`);return m.target},V=e=>A?.fingerprint===e?A.message:void 0,H=async(e,t)=>{let r=await M(n);if(r.fingerprint!==e)throw A=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!Ce(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(we(t)))throw Error(`Enter a commit message with a valid Conventional Commits header.`);await K(n,[`add`,`--update`]),i.untracked.length>0&&await K(n,[`add`,`--`,...r]),await K(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}});let a=await q(n,[`rev-parse`,`HEAD`]);return w=a,A=void 0,a},W=async({fingerprint:e,message:t,onCodexEvent:r=()=>void 0,source:i,target:a,untracked:o=[]})=>{B(a);let s=await q(n,[`rev-parse`,`HEAD`]),c,u,d=await M(n);if(d.tracked||d.untracked.length>0){if(!e||d.fingerprint!==e||!Ce(d.untracked,o))throw Error(`Working-tree changes changed; review them before refreshing.`);await K(n,[`add`,`--update`]),o.length>0&&await K(n,[`add`,`--`,...o]),await K(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}}),c=await q(n,[`rev-parse`,`HEAD`]),w=c,u=`refs/coreframe/recovery/${Date.now()}-${c.slice(0,12)}`,await K(n,[`update-ref`,u,c])}let f=c??s,p;try{if(p=await le({cwd:n,env:l,localMain:f,onCodexEvent:r,source:i,target:a}),await q(n,[`rev-parse`,`HEAD`])!==f)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await q(n,[`rev-parse`,b])!==f)throw Error(`Local main changed while the accepted update was being prepared.`);await ue(n,p,f),w=p.commit,await K(n,[`reset`,`--hard`,p.commit]);let e=Y(await q(n,[`diff`,`--name-only`,`-z`,s,p.commit]));A=void 0,u&&await K(n,[`update-ref`,`-d`,u]),m={...m,currentCommit:p.commit,draft:void 0,proposal:void 0,setupFailure:void 0,target:void 0},await G({installDependencies:ge(e),restartRequired:_e(e)})}catch(e){e instanceof N&&(y=!0);let t=u?` Recovery commit: ${u}.`:``;throw m={...m,currentCommit:w,message:`${Z(e)}${t}`},e}},G=async({installDependencies:t,restartRequired:r})=>{let a=w;if(t)try{await De([`install`,`--frozen-lockfile`])}catch(e){await Q({command:`pnpm install --frozen-lockfile`,commit:a,error:e,message:`The project was synchronized, but dependency installation failed. Fix the package or lockfile issue, then retry the install.`,restartRequired:r,stage:`dependencies`});return}try{await pe({config:e,cwd:n,env:l})}catch(e){await Q({command:`pnpm db migrate`,commit:a,error:e,message:`The project was synchronized, but its database migration failed. The previous database was restored. Reset the database to recreate it, apply migrations, and rerun seed scripts.`,restartRequired:r,stage:`migration`});return}await $(),R(a),r&&i()},he=async()=>{let e=Ee(`dependencies`);await $(),await G({installDependencies:!0,restartRequired:e.restartRequired})},be=async()=>{let e=Ee(`migration`);try{await De([`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.`,restartRequired:e.restartRequired,stage:`migration`});return}await $(),R(e.commit),e.restartRequired&&i()},Ee=e=>{if(!m.setupFailure||m.setupFailure.stage!==e)throw Error(`There is no failed ${e} setup step to recover.`);return m.setupFailure},De=async e=>{await p(X(),e,{cwd:n,env:l})},Q=async({command:e,commit:t,error:n,message:r,restartRequired:i,stage:a})=>{let o=fe(n).slice(-1e5),s={command:e,commit:t,message:r,output:o,restartRequired:i,stage:a};m={...m,setupFailure:s,target:void 0},console.error(`Coreframe managed development setup failed (${e}): ${r}\n${o}`);let c=Oe();c&&await d(c,`${JSON.stringify(s)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development setup failure: ${Z(e)}`)})},$=async()=>{m={...m,setupFailure:void 0};let e=Oe();e&&await u(e).catch(e=>{e instanceof Error&&`code`in e&&e.code===`ENOENT`||console.warn(`Could not clear the managed-development setup failure: ${Z(e)}`)})},Oe=()=>T?f.join(T.commonDir,C):void 0,ke=async(e,n)=>{let r={finalMessage:e,id:t(16).toString(`hex`),messages:re(n)};m={...m,codexCompletion:r},T&&await d(f.join(T.commonDir,S),`${JSON.stringify(r)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex result: ${Z(e)}`)}),F()},Ae=async()=>{m={...m,codexCompletion:void 0},T&&await u(f.join(T.commonDir,S)).catch(e=>{if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e})};return{action:me,activate:z,getStatus:()=>m,async close(){if(!h){h=!0,clearInterval(D),clearTimeout(O);for(let e of k)e.close();await xe(E)}}}}async function ne(e){let t=f.join(e,S);try{let e=JSON.parse(await s(t,`utf8`));if(O(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: ${Z(e)}`)}await u(t).catch(()=>void 0)}function O(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(k)}function k(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.kind===`agent`||t.kind===`thought`||t.kind===`user`)&&typeof t.text==`string`}function re(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 ie(e,t){let n=f.join(e,C);try{let e=JSON.parse(await s(n,`utf8`));if(A(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: ${Z(e)}`)}await u(n).catch(()=>void 0)}function A(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.command===`pnpm db migrate`||t.command===`pnpm db setup`||t.command===`pnpm install --frozen-lockfile`)&&typeof t.commit==`string`&&typeof t.message==`string`&&typeof t.output==`string`&&typeof t.restartRequired==`boolean`&&(t.stage===`dependencies`||t.stage===`migration`)}async function ae(e){let t=await E(e);return{branch:j(await q(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await q(e,[`rev-parse`,`HEAD`]),main:await q(e,[`rev-parse`,b]),primary:t.primary}}function j(e){return e===`HEAD`?void 0:e}async function oe(e,t){let n=[e.gitDir,f.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(_(e,{persistent:!1},t))}catch{}return r}async function M(t){let[n,r,i]=await Promise.all([q(t,[`status`,`--porcelain`,`--untracked-files=no`]),q(t,[`diff`,`HEAD`,`--binary`]),q(t,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),a=Y(i).sort(),o=e(`sha256`).update(r),c=[`Tracked changes:`,r];for(let e of a){let n=await s(f.join(t,e));o.update(e).update(n),c.push(`\nUntracked file: ${e}\n`,n.toString(`utf8`))}return{context:c.join(`
2
- `),fingerprint:o.digest(`hex`),tracked:n.length>0,untracked:a}}async function se(e,t,n){let{stdout:r}=await p(`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,stderr:`ignore`,stdin:{string:n}});return r.trim().replace(/^```(?:text)?\s*|\s*```$/g,``)}async function ce(e,t){let r=t.PATH??t.Path??t.path??``,i=v.platform===`win32`?(t.PATHEXT??`.COM;.EXE;.BAT;.CMD`).split(`;`):[``];for(let t of r.split(f.delimiter))for(let r of i)try{return await n(f.join(t||`.`,`${e}${r}`),g.X_OK),!0}catch{}return!1}var N=class extends Error{constructor(){super(`Local dev advanced while this update was being prepared. Nothing was changed. Review the latest update and try again.`)}};async function le({cwd:e,env:n,localMain:r,onCodexEvent:a,source:o,target:s}){if(o===`dev`&&await Se(e,r,s))return{commit:s,devTarget:s};let c=f.resolve(e,await q(e,[`rev-parse`,`--git-common-dir`])),u=f.join(c,`coreframe-managed-dev`);await i(u,{recursive:!0});let d=t(8).toString(`hex`),p=f.join(u,`integration-${d}`);try{let t=o===`dev`?s:r,i=o===`dev`?r:s;if(await K(e,[`worktree`,`add`,`--detach`,p,t]),r!==s){let e=await J(p,[`merge-base`,r,s]);await P(p,n,e?[`rebase`,`--onto`,i,e]:[`rebase`,`--root`,`--onto`,i],`rebase`,a)}return{commit:await q(p,[`rev-parse`,`HEAD`]),devTarget:o===`dev`?s:void 0}}finally{await K(e,[`worktree`,`remove`,`--force`,p]).catch(()=>void 0),await l(p,{force:!0,recursive:!0})}}async function ue(e,t,n){let r=[`start`,`update ${b} ${t.commit} ${n}`];t.devTarget&&r.push(t.devTarget===t.commit?`verify ${x} ${t.devTarget}`:`update ${x} ${t.commit} ${t.devTarget}`),r.push(`prepare`,`commit`);try{await p(`git`,[`update-ref`,`--stdin`],{cwd:e,stdin:{string:`${r.join(`
3
- `)}\n`}})}catch(r){if(t.devTarget)try{let[r,i]=await Promise.all([q(e,[`rev-parse`,b]),J(e,[`rev-parse`,x])]);if(r===n&&i!==t.devTarget)throw new N}catch(e){if(e instanceof N)throw e}throw r}}async function P(e,t,n,r,i){try{await K(e,n,{env:{GIT_EDITOR:`true`}});return}catch(n){let a=await R(e);if(a.length===0)throw n;try{for(;a.length>0;){await F(e,t,r,a,i),await K(e,[`diff`,`--check`]),await K(e,[`add`,`--all`]);let n=await R(e);if(n.length>0)throw Error(`Codex left unresolved paths: ${n.join(`, `)}`);try{await K(e,[r,`--continue`],{env:{GIT_EDITOR:`true`}})}catch(t){if(a=await R(e),a.length===0)throw t;continue}a=await R(e)}return}catch(t){throw await K(e,[r,`--abort`]).catch(()=>void 0),Error(`Codex could not resolve ${r} conflicts: ${Z(t)}`)}}}async function F(e,t,n,r,i){let a=`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(`, `)}`;i({message:{kind:`user`,text:a},phase:`start`});let o=p(`codex`,[`exec`,`--ephemeral`,`--ignore-user-config`,`--json`,`--config`,`model_reasoning_effort="low"`,`--sandbox`,`workspace-write`,`--cd`,e,a],{cwd:e,env:t,stdin:`ignore`}),s=``,c=[];try{await Promise.all([L(o.stdout,e=>{let t=I(e);t&&(t.kind===`agent`&&(s=t.text),i({message:t,phase:`message`}))}),L(o.stderr,e=>c.push(e))])}catch(e){i({phase:`error`});let t=c.join(`
4
- `).trim();throw t?Error(`${Z(e)}\n${t}`):e}i({finalMessage:s||`Codex resolved the conflicts.`,phase:`complete`})}function I(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Codex emitted invalid JSONL output.`)}if(!t||typeof t!=`object`)return;let n=t.item;if(t.type!==`item.completed`||!n||typeof n!=`object`)return;let{text:r,type:i}=n;if(!(typeof r!=`string`||!r.trim())){if(i===`reasoning`)return{kind:`thought`,text:r};if(i===`agent_message`)return{kind:`agent`,text:r}}}async function L(e,t){for await(let n of e)t(n)}async function R(e){return Y(await q(e,[`diff`,`--name-only`,`--diff-filter=U`,`-z`]))}async function de(e,t,n){await p(X(),[n],{cwd:e,env:t})}function fe(e){if(e instanceof m){let t=e.output.trim();if(t)return t}return Z(e)}async function pe({config:e,cwd:t,env:n}){if(!e.database)return;let r=await z({config:e,cwd:t,env:n});try{await p(X(),[`db`,`migrate`],{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: ${Z(e)}`)}),await l(r.directory,{force:!0,recursive:!0})}async function z({config:e,cwd:t,env:n}){let o=f.join(t,`.coreframe`,`managed-dev-backups`);await i(o,{recursive:!0});let s=await a(f.join(o,`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 me(f.join(t,`.coreframe`,r),f.join(s,r))&&n.add(r);return{directory:s,async discard(){},async restore(){for(let i of e){let e=f.join(t,`.coreframe`,i);n.has(i)?await r(f.join(s,i),e):await l(e,{force:!0})}}}}if(!n.DATABASE_URL)throw Error(`DATABASE_URL is required to snapshot local PostgreSQL.`);let c=await B(t);if(c)return V({directory:s,connectionString:n.DATABASE_URL,postgres:c});let u=f.join(s,`database.dump`),d=he(n,n.DATABASE_URL);return await p(`pg_dump`,[`--format=custom`,`--file`,u],{cwd:t,env:d,stdin:`ignore`}),{directory:s,async discard(){},async restore(){await p(`pg_restore`,[`--clean`,`--if-exists`,`--no-owner`,`--dbname`,d.PGDATABASE,u],{cwd:t,env:d,stdin:`ignore`})}}}async function me(e,t){try{return await r(e,t),!0}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e;return!1}}async function B(e){let t=JSON.parse(await s(f.join(e,`package.json`),`utf8`));if(!(!t.dependencies?.pg&&!t.devDependencies?.pg&&!t.optionalDependencies?.pg))try{return await import(y(`pg`,h(f.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 V({directory:e,connectionString:n,postgres:r}){let i=new URL(n),a=decodeURIComponent(i.pathname.slice(1));if(!a)throw Error(`DATABASE_URL must name a PostgreSQL database to snapshot.`);let o=`coreframe_backup_${t(6).toString(`hex`)}`,s=`${o}_failed`,c=new URL(i);c.pathname=a===`postgres`?`/template1`:`/postgres`;let l=new r.Client({connectionString:c.href});await l.connect();try{await U(l,a,!1),await W(l,a),await l.query(`CREATE DATABASE ${G(o)} WITH TEMPLATE ${G(a)}`),await U(l,o,!0)}finally{await U(l,a,!0).catch(()=>void 0),await l.end()}return{directory:e,async discard(){await H(r,c.href,async e=>{await W(e,o),await e.query(`DROP DATABASE ${G(o)}`)})},async restore(){await H(r,c.href,async e=>{await U(e,a,!1),await W(e,a),await e.query(`ALTER DATABASE ${G(a)} RENAME TO ${G(s)}`);try{await e.query(`ALTER DATABASE ${G(o)} RENAME TO ${G(a)}`)}catch(t){throw await e.query(`ALTER DATABASE ${G(s)} RENAME TO ${G(a)}`).catch(()=>void 0),await U(e,a,!0).catch(()=>void 0),t}await W(e,s),await e.query(`DROP DATABASE ${G(s)}`)})}}}async function H(e,t,n){let r=new e.Client({connectionString:t});await r.connect();try{return await n(r)}finally{await r.end()}}async function U(e,t,n){await e.query(`ALTER DATABASE ${G(t)} ALLOW_CONNECTIONS ${n?`true`:`false`}`)}async function W(e,t){await e.query(`SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()`,[t])}function G(e){return`"${e.replaceAll(`"`,`""`)}"`}function he(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 ge(e){return e.some(e=>f.basename(e)===`package.json`||f.basename(e).endsWith(`lock.yaml`)||f.basename(e)===`pnpm-workspace.yaml`)}function _e(e){return e.some(e=>ge([e])||/(^|\/)(vite|coreframe|tsconfig|drizzle)\.[^/]+$/.test(e)||/(^|\/)(drizzle|scripts|src\/api|tauri)(\/|$)/.test(e))}async function ve(e,t,n){return{commit:t,shortCommit:t.slice(0,12),source:n,subject:await q(e,[`show`,`-s`,`--format=%s`,t])}}async function ye(e){try{let t=await o(e,`wx`);await t.writeFile(`${v.pid}\n`),await t.close()}catch(t){if(!(t instanceof Error&&`code`in t&&t.code===`EEXIST`))throw t;let n=(await s(e,`utf8`).catch(()=>`unknown`)).trim(),r=Number(n);if(Number.isInteger(r)&&!be(r)){await u(e).catch(()=>void 0),await ye(e);return}throw Error(`Managed development is already owned by PID ${n}.`)}}function be(e){try{return v.kill(e,0),!0}catch(e){return!(e instanceof Error&&`code`in e&&e.code===`ESRCH`)}}async function xe(e){e&&(await s(e,`utf8`).catch(()=>void 0))?.trim()===String(v.pid)&&await u(e).catch(()=>void 0)}async function K(e,t,{env:n}={}){return p(`git`,t,{cwd:e,env:n,stdin:`ignore`})}async function q(e,t){return(await K(e,t)).stdout.trim()}async function J(e,t){try{return await q(e,t)||void 0}catch(e){if(e instanceof m&&e.exitCode&&e.exitCode>0)return;throw e}}async function Se(e,t,n){try{return await K(e,[`merge-base`,`--is-ancestor`,t,n]),!0}catch(e){if(e instanceof m&&e.exitCode===1)return!1;throw e}}function Ce(e,t){return e.length===t.length&&[...e].sort().every((e,n)=>e===[...t].sort()[n])}function Y(e){return e.split(`\0`).filter(Boolean)}function we(e){return e.split(/\r?\n/,1)[0]??``}function Te(e){return e.type===`acknowledge-codex`?`Acknowledging Codex result`: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-install`?`Retrying dependency installation`:e.type===`reset-database`?`Resetting local database`:`Aborting refresh`}function X(){return v.platform===`win32`?`pnpm.cmd`:`pnpm`}function Z(e){return e instanceof Error?e.message:String(e)}export{w as isManagedDevCheckout,T as isPrimaryCheckout,D as startManagedDevSession};
1
+ import{createHash as e,randomBytes as t}from"node:crypto";import{access as n,copyFile as r,mkdir as i,mkdtemp as a,open as o,readFile as s,realpath as c,rm as l,unlink as u,writeFile as d}from"node:fs/promises";import f from"node:path";import p,{SubprocessError as m}from"nano-spawn";import{pathToFileURL as h}from"node:url";import{constants as g,watch as _}from"node:fs";import v from"node:process";import{resolve as y}from"import-meta-resolve";const b=`refs/heads/main`,x=`refs/heads/dev`,ee=`refs/remotes/origin/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i,S=`coreframe-managed-dev-codex-completion.json`,ne=`coreframe-managed-dev-setup-failure.json`;async function C(e=v.cwd()){let t=await se(e);return t.primary&&t.branch===`main`&&t.head===t.main}async function w(e=v.cwd()){try{let{commonDir:t,gitDir:n}=await T(e);return n===t}catch{return!1}}async function T(e){let t=await c(await Y(e,[`rev-parse`,`--show-toplevel`])),n=await c(e),r=f.resolve(n,await Y(e,[`rev-parse`,`--git-dir`])),i=f.resolve(n,await Y(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function E({config:e,cwd:n=v.cwd(),env:r=v.env,onRestart:i=()=>void 0,onStatusChange:a=()=>void 0,remoteCheckInterval:o=6e4,runCheck:s=e=>pe(n,r,e),watchState:c=ce}){let l=r,m={mode:`waiting`,warnings:[]},h=!1,g=!1,_=!1,y=!1,C,w,T,E,D,ie=[],O,k,A=Promise.resolve(),N=()=>{h||a(m)},P=async({fetch:e=!1}={})=>{if(!(!g||h||!w)){if(_){y=!0;return}try{let[t,r,i]=await Promise.all([Y(n,[`rev-parse`,`--abbrev-ref`,`HEAD`]),Y(n,[`rev-parse`,`HEAD`]),Y(n,[`rev-parse`,b])]);if(t!==`main`||r!==i){m={message:`Managed synchronization is paused until the primary checkout is back on local main.`,mode:`waiting`,warnings:[]};return}r!==C&&(C=r,O=void 0);let a=await j(n);if(a.tracked||a.untracked.length>0){m={...m,currentCommit:C,draft:a,message:void 0,mode:`managed`,proposal:B(a.fingerprint),target:void 0};return}e&&await X(n,[`remote`,`get-url`,`origin`])&&await J(n,[`fetch`,`origin`,`+refs/heads/main:${ee}`]);let o=await X(n,[`rev-parse`,x]),s=await X(n,[`rev-parse`,ee]),c=[...s?[{commit:s,source:`upstream`}]:[],...o?[{commit:o,source:`dev`}]:[]],l;for(let e of c)if(!await Se(n,e.commit,C)){l=e;break}m={...m,currentCommit:C,draft:void 0,message:void 0,mode:`managed`,proposal:void 0,target:l===void 0?void 0:await ye(n,l.commit,l.source)}}catch(e){m={...m,message:Q(e),warnings:[Q(e)]}}finally{N()}}},F=()=>{clearTimeout(D),D=setTimeout(()=>void P(),50),D.unref()},I=(e,n)=>{let r=async()=>{let r=[{command:`pnpm typecheck`,status:`running`},{command:`pnpm test`,status:`pending`}],i=()=>{m={...m,checks:{commit:e,commands:structuredClone(r),trigger:n}},N()};i();for(let[e,n]of[`typecheck`,`test`].entries()){e>0&&(r[e].status=`running`,i());try{await s(n),r[e].status=`passed`}catch(n){r[e].status=`failed`,r[e].failureId=t(12).toString(`hex`),r[e].output=me(n)}i()}};A=A.then(r,r)},L=async()=>{if(g||h)return;let e=await se(n);if(!e.primary){m={message:`Managed development only runs from the primary checkout.`,mode:`unmanaged`,warnings:[]},N();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}`),m={message:t,mode:`unmanaged`,warnings:[]},N();return}T=f.join(e.commonDir,`coreframe-managed-dev.lock`),await be(T),await X(n,[`rev-parse`,`--verify`,x])||await J(n,[`branch`,`dev`,e.head]),w=e,C=e.head,g=!0,m={codexCompletion:await re(e.commonDir),currentCommit:e.head,mode:`managed`,setupFailure:await oe(e.commonDir,e.head),warnings:[]},N(),ie=await c(e,F),E=setInterval(()=>void P({fetch:!0}),o),E.unref(),await P(),P({fetch:!0})},R=async(e,{onCodexEvent:t=()=>void 0}={})=>{if(!g||m.mode!==`managed`)throw Error(`Managed development is not active.`);if(_)throw Error(`Another managed development action is already running.`);let r=[],i=[],a,o=e=>{e.phase===`start`?(i=e.commits,r.splice(0,r.length,e.message)):e.phase===`message`?r.push(e.message):e.phase===`complete`?a=e.finalMessage:e.phase===`progress`&&(i=e.commits),t(e)};_=!0,m={...m,busy:Te(e),message:void 0},N();try{if(e.type===`acknowledge-codex`)m.codexCompletion?.id===e.id&&await Ae();else if(e.type===`dismiss-check`)m.checks&&(m={...m,checks:{...m.checks,commands:m.checks.commands.map(t=>t.failureId===e.failureId?{...t,dismissed:!0}:t)}});else if(e.type===`reject`)m={...m,draft:void 0,proposal:void 0};else if(e.type===`prepare`){let t=z(e.target),r=await j(n);r.tracked||r.untracked.length>0?m={...m,draft:r,proposal:B(r.fingerprint)}:await H({onCodexEvent:o,source:t.source,target:e.target})}else if(e.type===`message`){let t=await V(e.fingerprint,e.untracked),r=B(t.fingerprint);if(r===void 0){try{if(k??=ue(`codex`,l),!await k)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 le(n,l,t.untracked)}catch(e){r=``,m={...m,warnings:[...m.warnings,`Codex could not generate a commit message: ${Q(e)}`]}}O={fingerprint:t.fingerprint,message:r}}m={...m,draft:t,proposal:r}}else if(e.type===`commit`){let t=await ge(e);m={...m,currentCommit:t,draft:void 0,message:void 0,proposal:void 0,target:void 0},F()}else if(e.type===`retry-install`)await W();else if(e.type===`reset-database`)await G();else{let t=z(e.target),r=await j(n);if(r.tracked||r.untracked.length>0){if(!e.fingerprint||!e.untracked)throw Error(`Refresh requires the current working-tree confirmation.`);if(await V(e.fingerprint,e.untracked),!e.message||!te.test(we(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await H({fingerprint:e.fingerprint,message:e.message,onCodexEvent:o,source:t.source,target:e.target,untracked:e.untracked})}}finally{_=!1,m={...m,busy:void 0},N(),y&&(y=!1,F())}return a&&await ke(a,r,i),{status:m}},z=e=>{if(!m.target||m.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`);return m.target},B=e=>O?.fingerprint===e?O.message:void 0,V=async(e,t)=>{let r=await j(n);if(r.fingerprint!==e)throw O=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!Ce(r.untracked,t))throw Error(`Include every untracked file or remove it before refreshing.`);return r},ge=async({fingerprint:e,message:t,untracked:r})=>{let i=await V(e,r);if(!t||!te.test(we(t)))throw Error(`Enter a commit message with a valid Conventional Commits header.`);await J(n,[`add`,`--update`]),i.untracked.length>0&&await J(n,[`add`,`--`,...r]),await J(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}});let a=await Y(n,[`rev-parse`,`HEAD`]);return C=a,O=void 0,a},H=async({fingerprint:e,message:t,onCodexEvent:r=()=>void 0,source:i,target:a,untracked:o=[]})=>{z(a);let s=await Y(n,[`rev-parse`,`HEAD`]),c,u,d=await j(n);if(d.tracked||d.untracked.length>0){if(!e||d.fingerprint!==e||!Ce(d.untracked,o))throw Error(`Working-tree changes changed; review them before refreshing.`);await J(n,[`add`,`--update`]),o.length>0&&await J(n,[`add`,`--`,...o]),await J(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}}),c=await Y(n,[`rev-parse`,`HEAD`]),C=c,u=`refs/coreframe/recovery/${Date.now()}-${c.slice(0,12)}`,await J(n,[`update-ref`,u,c])}let f=c??s,p;try{if(p=await de({cwd:n,env:l,localMain:f,onCodexEvent:r,source:i,target:a}),await Y(n,[`rev-parse`,`HEAD`])!==f)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await Y(n,[`rev-parse`,b])!==f)throw Error(`Local main changed while the accepted update was being prepared.`);await fe(n,p,f),C=p.commit,await J(n,[`reset`,`--hard`,p.commit]);let e=Z(await Y(n,[`diff`,`--name-only`,`-z`,s,p.commit]));O=void 0,u&&await J(n,[`update-ref`,`-d`,u]),m={...m,currentCommit:p.commit,draft:void 0,proposal:void 0,setupFailure:void 0,target:void 0},await U({installDependencies:_e(e),restartRequired:ve(e),trigger:`synchronization`})}catch(e){e instanceof M&&(y=!0);let t=u?` Recovery commit: ${u}.`:``;throw m={...m,currentCommit:C,message:`${Q(e)}${t}`},e}},U=async({installDependencies:t,restartRequired:r,trigger:a})=>{let o=C;if(t)try{await q([`install`,`--frozen-lockfile`])}catch(e){await De({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.`,restartRequired:r,stage:`dependencies`});return}try{await he({config:e,cwd:n,env:l})}catch(e){await De({command:`pnpm db migrate`,commit:o,error:e,message:`The project was synchronized, but its database migration failed. The previous database was restored. Reset the database to recreate it, apply migrations, and rerun seed scripts.`,restartRequired:r,stage:`migration`});return}await $(),I(o,a),r&&i()},W=async()=>{let e=K(`dependencies`);await $(),await U({installDependencies:!0,restartRequired:e.restartRequired,trigger:`dependency-recovery`})},G=async()=>{let e=K(`migration`);try{await q([`db`,`setup`])}catch(t){await De({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.`,restartRequired:e.restartRequired,stage:`migration`});return}await $(),I(e.commit,`database-recovery`),e.restartRequired&&i()},K=e=>{if(!m.setupFailure||m.setupFailure.stage!==e)throw Error(`There is no failed ${e} setup step to recover.`);return m.setupFailure},q=async e=>{await p(Ee(),e,{cwd:n,env:l})},De=async({command:e,commit:t,error:n,message:r,restartRequired:i,stage:a})=>{let o=me(n).slice(-1e5),s={command:e,commit:t,message:r,output:o,restartRequired:i,stage:a};m={...m,setupFailure:s,target:void 0},console.error(`Coreframe managed development setup failed (${e}): ${r}\n${o}`);let c=Oe();c&&await d(c,`${JSON.stringify(s)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development setup failure: ${Q(e)}`)})},$=async()=>{m={...m,setupFailure:void 0};let e=Oe();e&&await u(e).catch(e=>{e instanceof Error&&`code`in e&&e.code===`ENOENT`||console.warn(`Could not clear the managed-development setup failure: ${Q(e)}`)})},Oe=()=>w?f.join(w.commonDir,ne):void 0,ke=async(e,n,r)=>{let i={commits:r,finalMessage:e,id:t(16).toString(`hex`),messages:ae(n)};m={...m,codexCompletion:i},w&&await d(f.join(w.commonDir,S),`${JSON.stringify(i)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex result: ${Q(e)}`)}),N()},Ae=async()=>{m={...m,codexCompletion:void 0},w&&await u(f.join(w.commonDir,S)).catch(e=>{if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e})};return{action:R,activate:L,getStatus:()=>m,async close(){if(!h){h=!0,clearInterval(E),clearTimeout(D);for(let e of ie)e.close();await xe(T)}}}}async function re(e){let t=f.join(e,S);try{let e=JSON.parse(await s(t,`utf8`));if(D(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: ${Q(e)}`)}await u(t).catch(()=>void 0)}function D(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(O)&&(t.commits===void 0||Array.isArray(t.commits)&&t.commits.every(ie))}function ie(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 O(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.kind===`agent`||t.kind===`thought`||t.kind===`user`)&&typeof t.text==`string`}function ae(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 oe(e,t){let n=f.join(e,ne);try{let e=JSON.parse(await s(n,`utf8`));if(k(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: ${Q(e)}`)}await u(n).catch(()=>void 0)}function k(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.command===`pnpm db migrate`||t.command===`pnpm db setup`||t.command===`pnpm install --frozen-lockfile`)&&typeof t.commit==`string`&&typeof t.message==`string`&&typeof t.output==`string`&&typeof t.restartRequired==`boolean`&&(t.stage===`dependencies`||t.stage===`migration`)}async function se(e){let t=await T(e);return{branch:A(await Y(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await Y(e,[`rev-parse`,`HEAD`]),main:await Y(e,[`rev-parse`,b]),primary:t.primary}}function A(e){return e===`HEAD`?void 0:e}async function ce(e,t){let n=[e.gitDir,f.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(_(e,{persistent:!1},t))}catch{}return r}async function j(t){let[n,r,i]=await Promise.all([Y(t,[`status`,`--porcelain`,`--untracked-files=no`]),Y(t,[`diff`,`HEAD`,`--binary`]),Y(t,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),a=Z(i).sort(),o=e(`sha256`).update(r);for(let e of a)o.update(`\0`).update(e);return{fingerprint:o.digest(`hex`),tracked:n.length>0,untracked:a}}async function le(e,t,n){let r=[`Tracked changes:`,await Y(e,[`diff`,`HEAD`,`--binary`])];for(let t of n){let n=await s(f.join(e,t));r.push(`\nUntracked file: ${t}\n`,n.toString(`utf8`))}let{stdout:i}=await p(`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,stderr:`ignore`,stdin:{string:r.join(`
2
+ `)}});return i.trim().replace(/^```(?:text)?\s*|\s*```$/g,``)}async function ue(e,t){let r=t.PATH??t.Path??t.path??``,i=v.platform===`win32`?(t.PATHEXT??`.COM;.EXE;.BAT;.CMD`).split(`;`):[``];for(let t of r.split(f.delimiter))for(let r of i)try{return await n(f.join(t||`.`,`${e}${r}`),g.X_OK),!0}catch{}return!1}var M=class extends Error{constructor(){super(`Local dev advanced while this update was being prepared. Nothing was changed. Review the latest update and try again.`)}};async function de({cwd:e,env:n,localMain:r,onCodexEvent:a,source:o,target:s}){if(o===`dev`&&await Se(e,r,s))return{commit:s,devTarget:s};let c=f.resolve(e,await Y(e,[`rev-parse`,`--git-common-dir`])),u=f.join(c,`coreframe-managed-dev`);await i(u,{recursive:!0});let d=t(8).toString(`hex`),p=f.join(u,`integration-${d}`);try{if(await J(e,[`worktree`,`add`,`--detach`,p,r]),r!==s)if(o===`dev`)await N(p,n,[`merge`,`--no-edit`,`--no-ff`,`--allow-unrelated-histories`,`--message`,`Merge dev into main`,s],`merge`,a);else{let e=await X(p,[`merge-base`,r,s]);await N(p,n,e?[`rebase`,`--onto`,s,e]:[`rebase`,`--root`,`--onto`,s],`rebase`,a,s)}return{commit:await Y(p,[`rev-parse`,`HEAD`]),devTarget:o===`dev`?s:void 0}}finally{await J(e,[`worktree`,`remove`,`--force`,p]).catch(()=>void 0),await l(p,{force:!0,recursive:!0})}}async function fe(e,t,n){let r=[`start`,`update ${b} ${t.commit} ${n}`];t.devTarget&&r.push(t.devTarget===t.commit?`verify ${x} ${t.devTarget}`:`update ${x} ${t.commit} ${t.devTarget}`),r.push(`prepare`,`commit`);try{await p(`git`,[`update-ref`,`--stdin`],{cwd:e,stdin:{string:`${r.join(`
3
+ `)}\n`}})}catch(r){if(t.devTarget)try{let[r,i]=await Promise.all([Y(e,[`rev-parse`,b]),X(e,[`rev-parse`,x])]);if(r===n&&i!==t.devTarget)throw new M}catch(e){if(e instanceof M)throw e}throw r}}async function N(e,t,n,r,i,a){try{await J(e,n,{env:{GIT_EDITOR:`true`}});return}catch(n){let o=await R(e);if(o.length===0)throw n;try{for(;o.length>0;){await P(e,t,r,o,a?await F(e,a):[],i),await J(e,[`diff`,`--check`]),await J(e,[`add`,`--all`]);let n=await R(e);if(n.length>0)throw Error(`Codex left unresolved paths: ${n.join(`, `)}`);try{await J(e,[r,`--continue`],{env:{GIT_EDITOR:`true`}})}catch(t){if(o=await R(e),o.length===0)throw t;i({commits:a?await F(e,a):[],phase:`progress`});continue}i({commits:a?await F(e,a):[],phase:`progress`}),o=await R(e)}return}catch(t){throw await J(e,[r,`--abort`]).catch(()=>void 0),Error(`Codex could not resolve ${r} conflicts: ${Q(t)}`)}}}async function P(e,t,n,r,i,a){let o=`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(`, `)}`;a({commits:i,message:{kind:`user`,text:o},phase:`start`});let s=p(`codex`,[`exec`,`--ephemeral`,`--ignore-user-config`,`--json`,`--config`,`model_reasoning_effort="low"`,`--sandbox`,`workspace-write`,`--cd`,e,o],{cwd:e,env:t,stdin:`ignore`}),c=``,l=[];try{await Promise.all([L(s.stdout,e=>{let t=I(e);t&&(t.kind===`agent`&&(c=t.text),a({message:t,phase:`message`}))}),L(s.stderr,e=>l.push(e))])}catch(e){a({phase:`error`});let t=l.join(`
4
+ `).trim();throw t?Error(`${Q(e)}\n${t}`):e}a({finalMessage:c||`Codex resolved the conflicts.`,phase:`complete`})}async function F(e,t){let n=await Y(e,[`log`,`--reverse`,`--format=%H%x00%s`,`${t}..HEAD`]);return n?n.split(`
5
+ `).map(e=>{let[t,n=``]=e.split(`\0`,2);return{commit:t,shortCommit:t.slice(0,12),subject:n}}):[]}function I(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Codex emitted invalid JSONL output.`)}if(!t||typeof t!=`object`)return;let n=t.item;if(t.type!==`item.completed`||!n||typeof n!=`object`)return;let{text:r,type:i}=n;if(!(typeof r!=`string`||!r.trim())){if(i===`reasoning`)return{kind:`thought`,text:r};if(i===`agent_message`)return{kind:`agent`,text:r}}}async function L(e,t){for await(let n of e)t(n)}async function R(e){return Z(await Y(e,[`diff`,`--name-only`,`--diff-filter=U`,`-z`]))}async function pe(e,t,n){await p(Ee(),[n],{cwd:e,env:t})}function me(e){if(e instanceof m){let t=e.output.trim();if(t)return t}return Q(e)}async function he({config:e,cwd:t,env:n}){if(!e.database)return;let r=await z({config:e,cwd:t,env:n});try{await p(Ee(),[`db`,`migrate`],{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: ${Q(e)}`)}),await l(r.directory,{force:!0,recursive:!0})}async function z({config:e,cwd:t,env:n}){let o=f.join(t,`.coreframe`,`managed-dev-backups`);await i(o,{recursive:!0});let s=await a(f.join(o,`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 B(f.join(t,`.coreframe`,r),f.join(s,r))&&n.add(r);return{directory:s,async discard(){},async restore(){for(let i of e){let e=f.join(t,`.coreframe`,i);n.has(i)?await r(f.join(s,i),e):await l(e,{force:!0})}}}}if(!n.DATABASE_URL)throw Error(`DATABASE_URL is required to snapshot local PostgreSQL.`);let c=await V(t);if(c)return ge({directory:s,connectionString:n.DATABASE_URL,postgres:c});let u=f.join(s,`database.dump`),d=K(n,n.DATABASE_URL);return await p(`pg_dump`,[`--format=custom`,`--file`,u],{cwd:t,env:d,stdin:`ignore`}),{directory:s,async discard(){},async restore(){await p(`pg_restore`,[`--clean`,`--if-exists`,`--no-owner`,`--dbname`,d.PGDATABASE,u],{cwd:t,env:d,stdin:`ignore`})}}}async function B(e,t){try{return await r(e,t),!0}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e;return!1}}async function V(e){let t=JSON.parse(await s(f.join(e,`package.json`),`utf8`));if(!(!t.dependencies?.pg&&!t.devDependencies?.pg&&!t.optionalDependencies?.pg))try{return await import(y(`pg`,h(f.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 ge({directory:e,connectionString:n,postgres:r}){let i=new URL(n),a=decodeURIComponent(i.pathname.slice(1));if(!a)throw Error(`DATABASE_URL must name a PostgreSQL database to snapshot.`);let o=`coreframe_backup_${t(6).toString(`hex`)}`,s=`${o}_failed`,c=new URL(i);c.pathname=a===`postgres`?`/template1`:`/postgres`;let l=new r.Client({connectionString:c.href});await l.connect();try{await U(l,a,!1),await W(l,a),await l.query(`CREATE DATABASE ${G(o)} WITH TEMPLATE ${G(a)}`),await U(l,o,!0)}finally{await U(l,a,!0).catch(()=>void 0),await l.end()}return{directory:e,async discard(){await H(r,c.href,async e=>{await W(e,o),await e.query(`DROP DATABASE ${G(o)}`)})},async restore(){await H(r,c.href,async e=>{await U(e,a,!1),await W(e,a),await e.query(`ALTER DATABASE ${G(a)} RENAME TO ${G(s)}`);try{await e.query(`ALTER DATABASE ${G(o)} RENAME TO ${G(a)}`)}catch(t){throw await e.query(`ALTER DATABASE ${G(s)} RENAME TO ${G(a)}`).catch(()=>void 0),await U(e,a,!0).catch(()=>void 0),t}await W(e,s),await e.query(`DROP DATABASE ${G(s)}`)})}}}async function H(e,t,n){let r=new e.Client({connectionString:t});await r.connect();try{return await n(r)}finally{await r.end()}}async function U(e,t,n){await e.query(`ALTER DATABASE ${G(t)} ALLOW_CONNECTIONS ${n?`true`:`false`}`)}async function W(e,t){await e.query(`SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()`,[t])}function G(e){return`"${e.replaceAll(`"`,`""`)}"`}function K(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 _e(e){return e.some(e=>f.basename(e)===`package.json`||f.basename(e).endsWith(`lock.yaml`)||f.basename(e)===`pnpm-workspace.yaml`)}function ve(e){return e.some(e=>_e([e])||/(^|\/)(vite|coreframe|tsconfig|drizzle)\.[^/]+$/.test(e)||/(^|\/)(drizzle|scripts|src\/api|tauri)(\/|$)/.test(e))}async function ye(e,t,n){return{commit:t,shortCommit:t.slice(0,12),source:n,subject:await Y(e,[`show`,`-s`,`--format=%s`,t])}}async function be(e){try{let t=await o(e,`wx`);await t.writeFile(`${v.pid}\n`),await t.close()}catch(t){if(!(t instanceof Error&&`code`in t&&t.code===`EEXIST`))throw t;let n=(await s(e,`utf8`).catch(()=>`unknown`)).trim(),r=Number(n);if(Number.isInteger(r)&&!q(r)){await u(e).catch(()=>void 0),await be(e);return}throw Error(`Managed development is already owned by PID ${n}.`)}}function q(e){try{return v.kill(e,0),!0}catch(e){return!(e instanceof Error&&`code`in e&&e.code===`ESRCH`)}}async function xe(e){e&&(await s(e,`utf8`).catch(()=>void 0))?.trim()===String(v.pid)&&await u(e).catch(()=>void 0)}async function J(e,t,{env:n}={}){return p(`git`,t,{cwd:e,env:n,stdin:`ignore`})}async function Y(e,t){return(await J(e,t)).stdout.trim()}async function X(e,t){try{return await Y(e,t)||void 0}catch(e){if(e instanceof m&&e.exitCode&&e.exitCode>0)return;throw e}}async function Se(e,t,n){try{return await J(e,[`merge-base`,`--is-ancestor`,t,n]),!0}catch(e){if(e instanceof m&&e.exitCode===1)return!1;throw e}}function Ce(e,t){return e.length===t.length&&[...e].sort().every((e,n)=>e===[...t].sort()[n])}function Z(e){return e.split(`\0`).filter(Boolean)}function we(e){return e.split(/\r?\n/,1)[0]??``}function Te(e){return e.type===`acknowledge-codex`?`Acknowledging Codex result`: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-install`?`Retrying dependency installation`:e.type===`reset-database`?`Resetting local database`:`Aborting refresh`}function Ee(){return v.platform===`win32`?`pnpm.cmd`:`pnpm`}function Q(e){return e instanceof Error?e.message:String(e)}export{C as isManagedDevCheckout,w as isPrimaryCheckout,E as startManagedDevSession};
package/dist/runner.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as cmdts from "cmd-ts";
1
+ import * as cmdts from "@alloc/cmd-ts";
2
2
 
3
3
  //#region runner.d.ts
4
4
  type CliErrorReporterOptions = {
package/dist/runner.js CHANGED
@@ -1 +1 @@
1
- import{join as e}from"node:path";import{mkdtempSync as t,writeFileSync as n}from"node:fs";import{tmpdir as r}from"node:os";import*as i from"cmd-ts";import{inspect as a}from"node:util";function o(i,{formatMessage:a,temporaryDirectory:o=r(),write:s=e=>console.error(e)}={}){let u=f(i),d=m(c(i,a),u);try{let r=e(t(e(o,`coreframe-error-`)),`error.log`);return n(r,`${m(l(i),u)}\n`,{mode:384}),s(`Error: ${d}\nFull diagnostic: ${r}`),r}catch{s(`Error: ${d}\nThe full diagnostic could not be written to the temporary directory.`);return}}function s(e,t={}){let n=typeof e==`function`?e:()=>i.run(i.binary(e),process.argv),r=!1,a=e=>{r||(r=!0,o(e,t),process.exit(1))};process.once(`uncaughtException`,a),process.once(`unhandledRejection`,a),Promise.resolve().then(n).catch(a)}function c(e,t){try{return t?.(e)||(e instanceof Error?e.message:String(e)).split(/\r?\n/,1)[0]||`Unknown error`}catch{return`Unknown error`}}function l(e){try{let t=u(e);if(!(e instanceof Error)||!d(t))return a(t,{customInspect:!1,depth:10});let n=typeof t.stack==`string`?t.stack:`${e.name}: ${e.message}`;return delete t.name,delete t.message,delete t.stack,`${n}${Reflect.ownKeys(t).length?`\n${a(t,{customInspect:!1,depth:10})}`:``}`}catch{return`The thrown value could not be inspected.`}}function u(e,t=new WeakMap){if((typeof e!=`object`||!e)&&typeof e!=`function`)return e;let n=e,r=t.get(n);if(r)return r;if(typeof e==`function`)return`[Function${e.name?`: ${e.name}`:``}]`;let i=Array.isArray(e)?[]:{};t.set(n,i),e instanceof Error&&(i.name=e.name,i.message=e.message,i.stack=e.stack??`${e.name}: ${e.message}`);for(let r of Reflect.ownKeys(n)){if(typeof r!=`string`||r.toLowerCase()===`env`||Array.isArray(e)&&r===`length`||e instanceof Error&&(r===`name`||r===`message`||r===`stack`))continue;let a=Object.getOwnPropertyDescriptor(n,r);!a||!(`value`in a)||Object.defineProperty(i,r,{configurable:!0,enumerable:!0,value:u(a.value,t),writable:!0})}return i}function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e,t=new WeakSet){let n=new Set;function r(e){if((typeof e!=`object`||!e)&&typeof e!=`function`)return;let i=e;if(!t.has(i)){t.add(i);for(let e of Reflect.ownKeys(i)){if(typeof e!=`string`)continue;let t=Object.getOwnPropertyDescriptor(i,e);!t||!(`value`in t)||(e.toLowerCase()===`env`?p(t.value,n):r(t.value))}}}try{r(e)}catch{}return n}function p(e,t){if(!(typeof e!=`object`||!e))for(let n of Reflect.ownKeys(e)){let r=Object.getOwnPropertyDescriptor(e,n);r&&`value`in r&&typeof r.value==`string`&&r.value&&t.add(r.value)}}function m(e,t){return[...t].sort((e,t)=>t.length-e.length).reduce((e,t)=>e.replaceAll(t,`[redacted environment value]`),e)}export{o as reportCliError,s as run};
1
+ import{join as e}from"node:path";import{mkdtempSync as t,writeFileSync as n}from"node:fs";import{tmpdir as r}from"node:os";import*as i from"@alloc/cmd-ts";import{inspect as a}from"node:util";function o(i,{formatMessage:a,temporaryDirectory:o=r(),write:s=e=>console.error(e)}={}){let u=f(i),d=m(c(i,a),u);try{let r=e(t(e(o,`coreframe-error-`)),`error.log`);return n(r,`${m(l(i),u)}\n`,{mode:384}),s(`Error: ${d}\nFull diagnostic: ${r}`),r}catch{s(`Error: ${d}\nThe full diagnostic could not be written to the temporary directory.`);return}}function s(e,t={}){let n=typeof e==`function`?e:()=>i.run(i.binary(e),process.argv),r=!1,a=e=>{r||(r=!0,o(e,t),process.exit(1))};process.once(`uncaughtException`,a),process.once(`unhandledRejection`,a),Promise.resolve().then(n).catch(a)}function c(e,t){try{return t?.(e)||(e instanceof Error?e.message:String(e)).split(/\r?\n/,1)[0]||`Unknown error`}catch{return`Unknown error`}}function l(e){try{let t=u(e);if(!(e instanceof Error)||!d(t))return a(t,{customInspect:!1,depth:10});let n=typeof t.stack==`string`?t.stack:`${e.name}: ${e.message}`;return delete t.name,delete t.message,delete t.stack,`${n}${Reflect.ownKeys(t).length?`\n${a(t,{customInspect:!1,depth:10})}`:``}`}catch{return`The thrown value could not be inspected.`}}function u(e,t=new WeakMap){if((typeof e!=`object`||!e)&&typeof e!=`function`)return e;let n=e,r=t.get(n);if(r)return r;if(typeof e==`function`)return`[Function${e.name?`: ${e.name}`:``}]`;let i=Array.isArray(e)?[]:{};t.set(n,i),e instanceof Error&&(i.name=e.name,i.message=e.message,i.stack=e.stack??`${e.name}: ${e.message}`);for(let r of Reflect.ownKeys(n)){if(typeof r!=`string`||r.toLowerCase()===`env`||Array.isArray(e)&&r===`length`||e instanceof Error&&(r===`name`||r===`message`||r===`stack`))continue;let a=Object.getOwnPropertyDescriptor(n,r);!a||!(`value`in a)||Object.defineProperty(i,r,{configurable:!0,enumerable:!0,value:u(a.value,t),writable:!0})}return i}function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e,t=new WeakSet){let n=new Set;function r(e){if((typeof e!=`object`||!e)&&typeof e!=`function`)return;let i=e;if(!t.has(i)){t.add(i);for(let e of Reflect.ownKeys(i)){if(typeof e!=`string`)continue;let t=Object.getOwnPropertyDescriptor(i,e);!t||!(`value`in t)||(e.toLowerCase()===`env`?p(t.value,n):r(t.value))}}}try{r(e)}catch{}return n}function p(e,t){if(!(typeof e!=`object`||!e))for(let n of Reflect.ownKeys(e)){let r=Object.getOwnPropertyDescriptor(e,n);r&&`value`in r&&typeof r.value==`string`&&r.value&&t.add(r.value)}}function m(e,t){return[...t].sort((e,t)=>t.length-e.length).reduce((e,t)=>e.replaceAll(t,`[redacted environment value]`),e)}export{o as reportCliError,s as run};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreframe/scripts",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/airlock-labs/coreframe.git",
@@ -21,9 +21,10 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
+ "@alloc/cmd-ts": "0.17.1",
24
25
  "@aws-sdk/client-s3": "^3.1090.0",
25
26
  "@clack/prompts": "^1.6.0",
26
- "cmd-ts": "0.15.0",
27
+ "@vercel/detect-agent": "^1.2.3",
27
28
  "cross-keychain": "1.1.0",
28
29
  "drizzle-orm": "1.0.0-rc.4",
29
30
  "import-meta-resolve": "^4.2.0",
@@ -31,7 +32,7 @@
31
32
  "mp4box": "^2.4.1",
32
33
  "music-metadata": "^11.14.0",
33
34
  "nano-spawn": "^2.1.0",
34
- "procband": "^0.3.7",
35
+ "procband": "^0.3.8",
35
36
  "saxes": "^6.0.0",
36
37
  "tinyglobby": "^0.2.17",
37
38
  "yaml": "^2.9.0"