@coreframe/scripts 0.2.8 → 0.2.10

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.
@@ -271,7 +271,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
271
271
  } | {
272
272
  command: "migrate-held";
273
273
  args: {
274
- confirm: "run-held-migrations" | undefined;
274
+ local: boolean;
275
275
  };
276
276
  } | {
277
277
  command: "migrate-local";
@@ -566,7 +566,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
566
566
  } | {
567
567
  command: "migrate-held";
568
568
  args: {
569
- confirm: "run-held-migrations" | undefined;
569
+ local: boolean;
570
570
  };
571
571
  } | {
572
572
  command: "migrate-local";
package/dist/coreframe.js CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import*as e from"@alloc/cmd-ts";import{array as t,command as n,extendType as r,flag as i,multioption as a,number as o,oneOf as s,option as c,optional as l,positional as u,rest as d,string as f,subcommands as p}from"@alloc/cmd-ts";import{ProjectPostgresAlreadyRunningError as m,checkDeployMigrations as h,checkSchemaPush as g,collectDeployMigrationFiles as _,createProjectDeployDatabase as v,ensureLocalDb as y,filterPendingMigrations as b,formatDbErrorMessage as x,formatMigrationList as S,formatMigrationScanFailures as C,migrateHeldMigrations as w,migrateLocalDb as T,readAppliedMigrationNames as E,resetLocalDb as ee,runDrizzleKitCommand as te,scanDeployMigrationFiles as D,seedLocalDb as O,setupLocalDb as ne,startProjectPostgres as re,stopProjectPostgres as k}from"@coreframe/db";import{checkFlutterClient as A,ensureFlutterDevAssetDirectories as ie,flutterPlatforms as j,generateFlutterNativeBridge as ae,prepareFlutterClient as M,prepareFlutterDevOutput as oe,productionApiOrigin as N,runFlutterAcceptance as se}from"@coreframe/flutter-tools";import P,{dirname as F,isAbsolute as ce,join as I,posix as le,resolve as L,sep as ue}from"node:path";import R from"nano-spawn";import*as z from"@clack/prompts";import{addAsset as de,buildAssets as fe,checkAssets as pe,printAssetResult as me,publishAssets as he}from"@coreframe/assets";import{assertAssetCredentialProfile as ge,configureAssetCredentials as _e,createB2PrivateObjectStore as ve}from"@coreframe/object-storage";import{access as ye,chmod as be,copyFile as xe,cp as Se,link as Ce,mkdir as B,mkdtemp as we,readFile as V,readdir as Te,realpath as Ee,rename as De,rm as H,stat as Oe,unlink as ke,writeFile as U}from"node:fs/promises";import{homedir as Ae,networkInterfaces as je,tmpdir as Me}from"node:os";import{importProjectDependency as Ne,importProjectModule as Pe,normalizeWorkerEnvironment as Fe,readProjectConfig as Ie,wranglerEnvironmentNames as Le}from"@coreframe/config";import{createHash as Re,randomUUID as W}from"node:crypto";import G from"node:process";import{spawnSync as K}from"node:child_process";import{chmodSync as ze,existsSync as q,lstatSync as Be,mkdirSync as Ve,mkdtempSync as He,readFileSync as J,readlinkSync as Ue,rmSync as We,symlinkSync as Ge,writeFileSync as Ke}from"node:fs";import{parse as qe,stringify as Je}from"yaml";import{accessTokenSigningSecretName as Ye,clearAppliedPendingWorkerSecrets as Xe,deployEnvironments as Ze,discardPendingWorkerSecret as Qe,discoverStagingUrl as $e,inspectWorkerEnvironment as et,materializePrimaryWorkerConfig as tt,materializePrimaryWorkerTypeConfig as nt,parseDeclaredWorkerSecretEnv as rt,parseTauriReleasePlatform as it,prepareAccessTokenSigningSecret as at,prepareTauriRelease as ot,queueWorkerSecret as st,queueWorkerSecrets as ct,readDeclaredWorkerSecrets as lt,readPackageJson as ut,readPendingWorkerSecretSnapshot as dt,reassignStagingHostname as ft,releaseName as pt,resolveDeployConfig as mt,resolveReleaseVersion as ht,resolveTauriReleasePlan as gt,restoreTauriReleaseMetadata as _t,rotateAccessTokenSigningSecret as vt,runAfterWorkerDeploy as yt,runPostDeployChecks as bt,tauriReleasePlatforms as xt,uploadTauriReleaseToB2 as St,validateTauriReleasePlan as Ct,validateWorkerEnvironmentForDeploy as wt,verifyAccessTokenSigningSecret as Tt,writePackageVersion as Et,writeTauriReleaseMetadata as Dt}from"@coreframe/deploy";import{connectDevSupervisor as Ot,createDevStartupTiming as kt,devHttpsCertEnv as At,devHttpsKeyEnv as jt,isManagedDevCheckout as Mt,isPrimaryCheckout as Nt,prepareDevHttps as Pt,stopDevSupervisor as Ft}from"@coreframe/dev";import{inspect as It,parseEnv as Lt}from"node:util";import{once as Rt}from"node:events";import{finished as zt}from"node:stream/promises";import{codexTaskEnv as Bt}from"@coreframe/dev-contracts/codex-task";import{managedDevEnv as Vt}from"@coreframe/dev-contracts/managed-dev";import{createPrefixStream as Y,supervise as Ht}from"procband";import{createConnection as Ut,createServer as Wt}from"node:net";import{setTimeout as Gt}from"node:timers/promises";import{determineAgent as Kt}from"@vercel/detect-agent";import{runPreview as qt}from"@coreframe/preview";const Jt=[`web`,...j];function Yt(e=`web`,{apiOrigin:t,cwd:n=process.cwd(),simulator:r=!1}={}){if(en(e,r),e===`web`)return[nn(`pnpm`,[`build`],n,{COREFRAME_PLATFORM:`web`})];let i=N(t);return[{kind:`prepare`,platform:e},nn(`flutter`,Xt(e,i,{simulator:r}),L(n,`src-flutter`),{COREFRAME_API_ORIGIN:i})]}function Xt(e,t,{noCodesign:n=e===`macos`,simulator:r=!1}={}){en(e,r);let i=N(t);return[`build`,e===`android`?`apk`:e,`--release`,...r?[`--simulator`]:[],...n?[`--no-codesign`]:[],`--dart-define=COREFRAME_API_ORIGIN=${i}`]}function Zt(e){let t=L(e,`src-flutter/build/app/outputs/flutter-apk/app-release.apk`),n=JSON.stringify(t);return[`Android release build succeeded.`,``,`Install it on a connected Android device:`,` 1. Enable Developer options and USB debugging, connect the device, and accept the authorization prompt.`,` 2. Verify the device is visible:`,` adb devices`,` 3. Install or update the APK:`,` adb install -r ${n}`,``,`If multiple devices are connected, use:`,` adb -s <device-id> install -r ${n}`].join(`
3
- `)}function Qt(e,{simulator:t=!1}={}){let n=L(e,`src-flutter/build/ios/${t?`iphonesimulator`:`iphoneos`}/Runner.app`),r=JSON.stringify(n);return t?[`iOS Simulator release build succeeded.`,``,`Install it on a booted iOS Simulator:`,` 1. Verify available simulators:`,` xcrun simctl list devices`,` 2. Install the app:`,` xcrun simctl install booted ${r}`,``,"If multiple simulators are available, replace `booted` with the simulator UDID."].join(`
2
+ import*as e from"@alloc/cmd-ts";import{array as t,command as n,extendType as r,flag as i,multioption as a,number as o,oneOf as s,option as c,optional as l,positional as u,rest as d,string as f,subcommands as p}from"@alloc/cmd-ts";import{ProjectPostgresAlreadyRunningError as m,checkDeployMigrations as h,checkSchemaPush as g,collectDeployMigrationFiles as _,createProjectPostgresDatabaseAdapter as v,createProjectSqliteDatabaseAdapter as y,ensureLocalDb as b,filterPendingMigrations as x,formatDbErrorMessage as S,formatMigrationList as C,formatMigrationScanFailures as w,migrateHeldMigrations as T,migrateLocalDb as E,readAppliedMigrationNames as ee,resetLocalDb as D,runDrizzleKitCommand as O,scanDeployMigrationFiles as k,seedLocalDb as A,setupLocalDb as te,startProjectPostgres as j,startProjectTurso as ne,stopProjectPostgres as M}from"@coreframe/db";import{checkFlutterClient as re,ensureFlutterDevAssetDirectories as ie,flutterPlatforms as N,generateFlutterNativeBridge as ae,prepareFlutterClient as oe,prepareFlutterDevOutput as se,productionApiOrigin as P,runFlutterAcceptance as ce}from"@coreframe/flutter-tools";import F,{dirname as I,isAbsolute as le,join as L,posix as ue,resolve as R,sep as de}from"node:path";import z from"nano-spawn";import*as B from"@clack/prompts";import{addAsset as fe,buildAssets as pe,checkAssets as me,printAssetResult as he,publishAssets as ge}from"@coreframe/assets";import{assertAssetCredentialProfile as _e,configureAssetCredentials as ve,createB2PrivateObjectStore as ye}from"@coreframe/object-storage";import{access as be,chmod as xe,copyFile as Se,cp as Ce,link as we,mkdir as V,mkdtemp as Te,readFile as H,readdir as Ee,realpath as De,rename as Oe,rm as U,stat as ke,unlink as Ae,writeFile as W}from"node:fs/promises";import{homedir as je,networkInterfaces as Me,tmpdir as Ne}from"node:os";import{importProjectDependency as Pe,importProjectModule as Fe,normalizeWorkerEnvironment as Ie,readProjectConfig as Le,wranglerEnvironmentNames as Re}from"@coreframe/config";import{createHash as ze,randomUUID as G}from"node:crypto";import K from"node:process";import{spawnSync as q}from"node:child_process";import{chmodSync as Be,existsSync as J,lstatSync as Ve,mkdirSync as He,mkdtempSync as Ue,readFileSync as Y,readlinkSync as We,rmSync as Ge,symlinkSync as Ke,writeFileSync as qe}from"node:fs";import{parse as Je,stringify as Ye}from"yaml";import{accessTokenSigningSecretName as Xe,clearAppliedPendingWorkerSecrets as Ze,deployEnvironments as Qe,discardPendingWorkerSecret as $e,discoverStagingUrl as et,inspectWorkerEnvironment as tt,materializePrimaryWorkerConfig as nt,materializePrimaryWorkerTypeConfig as rt,parseDeclaredWorkerSecretEnv as it,parseTauriReleasePlatform as at,prepareAccessTokenSigningSecret as ot,prepareTauriRelease as st,queueWorkerSecret as ct,queueWorkerSecrets as lt,readDeclaredWorkerSecrets as ut,readPackageJson as dt,readPendingWorkerSecretSnapshot as ft,reassignStagingHostname as pt,releaseName as mt,resolveDeployConfig as ht,resolveReleaseVersion as gt,resolveTauriReleasePlan as _t,restoreTauriReleaseMetadata as vt,rotateAccessTokenSigningSecret as yt,runAfterWorkerDeploy as bt,runPostDeployChecks as xt,tauriReleasePlatforms as St,uploadTauriReleaseToB2 as Ct,validateTauriReleasePlan as wt,validateWorkerEnvironmentForDeploy as Tt,verifyAccessTokenSigningSecret as Et,writePackageVersion as Dt,writeTauriReleaseMetadata as Ot}from"@coreframe/deploy";import{connectDevSupervisor as kt,createDevStartupTiming as At,devHttpsCertEnv as jt,devHttpsKeyEnv as Mt,isManagedDevCheckout as Nt,isPrimaryCheckout as Pt,prepareDevHttps as Ft,stopDevSupervisor as It}from"@coreframe/dev";import{inspect as Lt,parseEnv as Rt}from"node:util";import{once as zt}from"node:events";import{finished as Bt}from"node:stream/promises";import{codexTaskEnv as Vt}from"@coreframe/dev-contracts/codex-task";import{managedDevEnv as Ht}from"@coreframe/dev-contracts/managed-dev";import{createPrefixStream as Ut,supervise as Wt}from"procband";import{createConnection as Gt,createServer as Kt}from"node:net";import{setTimeout as qt}from"node:timers/promises";import{determineAgent as Jt}from"@vercel/detect-agent";import{runPreview as Yt}from"@coreframe/preview";const Xt=[`web`,...N];function Zt(e=`web`,{apiOrigin:t,cwd:n=process.cwd(),simulator:r=!1}={}){if(nn(e,r),e===`web`)return[an(`pnpm`,[`build`],n,{COREFRAME_PLATFORM:`web`})];let i=P(t);return[{kind:`prepare`,platform:e},an(`flutter`,Qt(e,i,{simulator:r}),R(n,`src-flutter`),{COREFRAME_API_ORIGIN:i})]}function Qt(e,t,{noCodesign:n=e===`macos`,simulator:r=!1}={}){nn(e,r);let i=P(t);return[`build`,e===`android`?`apk`:e,`--release`,...r?[`--simulator`]:[],...n?[`--no-codesign`]:[],`--dart-define=COREFRAME_API_ORIGIN=${i}`]}function $t(e){let t=R(e,`src-flutter/build/app/outputs/flutter-apk/app-release.apk`),n=JSON.stringify(t);return[`Android release build succeeded.`,``,`Install it on a connected Android device:`,` 1. Enable Developer options and USB debugging, connect the device, and accept the authorization prompt.`,` 2. Verify the device is visible:`,` adb devices`,` 3. Install or update the APK:`,` adb install -r ${n}`,``,`If multiple devices are connected, use:`,` adb -s <device-id> install -r ${n}`].join(`
3
+ `)}function en(e,{simulator:t=!1}={}){let n=R(e,`src-flutter/build/ios/${t?`iphonesimulator`:`iphoneos`}/Runner.app`),r=JSON.stringify(n);return t?[`iOS Simulator release build succeeded.`,``,`Install it on a booted iOS Simulator:`,` 1. Verify available simulators:`,` xcrun simctl list devices`,` 2. Install the app:`,` xcrun simctl install booted ${r}`,``,"If multiple simulators are available, replace `booted` with the simulator UDID."].join(`
4
4
  `):[`iOS release build succeeded.`,``,`Install it on a connected iOS device:`,` 1. Enable Developer Mode, connect the device, and trust this Mac if prompted.`,` 2. Verify the device is visible:`,` xcrun devicectl list devices`,` 3. Install the signed app:`,` xcrun devicectl device install app --device <device-id> ${r}`,``,`If multiple devices are connected, use the device UDID shown by devicectl.`].join(`
5
- `)}async function $t({apiOrigin:e,cwd:t=process.cwd(),environment:n=process.env,platform:r=`web`,simulator:i=!1,prepareClient:a=M,runCommand:o=tn}={}){en(r,i);let s={...n};delete s.COREFRAME_PLATFORM,delete s.TAURI_ENV_PLATFORM;let c=r===`web`?void 0:N(e??n.COREFRAME_API_ORIGIN);for(let e of Yt(r,{apiOrigin:c,cwd:t,simulator:i})){if(e.kind===`prepare`){if(!c)throw Error(`A production API origin is required for the Flutter ${e.platform} build.`);await a({apiOrigin:c,cwd:t,environment:s,platform:e.platform});continue}await o(e.command,e.args,{cwd:e.cwd,env:{...s,...e.environment}})}r===`android`?console.log(Zt(t)):r===`ios`&&console.log(Qt(t,{simulator:i}))}function en(e,t){if(t&&e!==`ios`)throw Error(`The --simulator flag is only supported for the iOS build target.`)}async function tn(e,t,{cwd:n,env:r}){await R(e,t,{cwd:n,env:r,stdio:`inherit`})}function nn(e,t,n,r){return{kind:`command`,command:e,args:t,cwd:n,...r===void 0?{}:{environment:r}}}const rn=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in a packaged Flutter client.`,async from(e){return N(e)}}),an=n({name:`build`,description:`Build the web client or a release Flutter app. Tauri is not built.`,args:{platform:u({type:l(s(Jt)),displayName:`platform`,description:`Build target: web, iOS, Android, or macOS. Defaults to web.`}),apiOrigin:c({long:`api-origin`,type:l(rn),description:`Exact production HTTPS API origin for a Flutter build. Defaults to COREFRAME_API_ORIGIN.`}),simulator:i({long:`simulator`,description:`Build iOS for the simulator instead of a physical device.`,defaultValue:()=>!1})},handler:({apiOrigin:e,platform:t,simulator:n})=>$t({apiOrigin:e,platform:t,simulator:n})}),on=/^[a-f0-9]{64}$/,sn=/^[a-f0-9]{40}$/,cn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function ln(e){if(!on.test(e))throw Error(`Invalid SHA-256 digest "${e}".`);return e}function un(e){if(!sn.test(e))throw Error(`Invalid full Git revision "${e}".`);return e}function dn(e,t){if(!cn.test(e))throw Error(`${t} must contain only letters, numbers, dots, underscores, or hyphens.`);return e}function fn(e){return`projects/${dn(e,`Project ID`)}/i18n/v1`}function pn(e,t){return ln(t),`${fn(e)}/objects/sha256/${t.slice(0,2)}/${t}`}function mn(e,t){return un(t),`${fn(e)}/commits/${t}.json`}function hn(e,t){return gn(t),`${fn(e)}/releases/${encodeURIComponent(t)}.json`}function gn(e){if(!e.startsWith(`v`)||e.length<2||e.length>128||/\s/.test(e)||e.includes(`..`))throw Error(`Release tag "${e}" must be a valid v-prefixed tag.`);return e}function X(e,t){if(!t||t.startsWith(`/`)||t.includes(`\0`))throw Error(`Unsafe i18n artifact path "${t}".`);let n=L(e),r=L(n,t);if(r!==n&&!r.startsWith(`${n}${ue}`))throw Error(`Unsafe i18n artifact path "${t}".`);return r}function Z(e,t,n){return`${e.directory}/${t}/${n}.json`}function _n(e,t,n){return`${e.directory}/${t}/${n}.mjs`}async function vn(e){await R(`pnpm`,[`exec`,`lingui`,`extract`],{cwd:e,stdio:`inherit`})}async function yn({config:e,cwd:t,strict:n,temporaryDirectory:r}){let i=[];try{for(let n of e.locales)for(let a of e.catalogs){let o=X(t,Z(e,n,a)),s=await wn(o),c=Object.fromEntries(Object.entries(s).filter(([,e])=>!e.obsolete)),l=I(r,`${n}-${a}.json`);await B(F(l),{recursive:!0}),await xe(o,l),i.push({path:o,backup:l}),await Tn(o,c)}await R(`pnpm`,[`exec`,`lingui`,`compile`,...n?[`--strict`]:[]],{cwd:t,stdio:`inherit`})}finally{try{for(let{path:e,backup:t}of i)await xe(t,e)}finally{for(let n of e.locales)for(let r of e.catalogs)await H(X(t,_n(e,n,r)),{force:!0})}}}async function bn({config:e,cwd:t}){let n=[];for(let r of e.locales)if(r!==e.sourceLocale)for(let i of e.catalogs){let a=await wn(X(t,Z(e,r,i)));for(let[e,t]of Object.entries(a)){if(t.obsolete||t.translation?.trim())continue;let a=t.message;if(typeof a!=`string`||!a)throw Error(`Missing source message metadata for ${r}:${e}.`);n.push({catalog:i,comments:t.comments?.filter(e=>typeof e==`string`)??[],context:t.context,id:e,locale:r,message:a,origins:t.origin?.map(([e,t])=>t?`${e}:${t}`:e)??[],placeholders:Object.keys(t.placeholders??{}).sort()})}}return n.sort((e,t)=>An(e).localeCompare(An(t)))}async function xn({config:e,cwd:t,messages:n,env:r=process.env}){if(n.length===0)return{translations:[],version:1};if(!e.generator)throw Error(`I18n preparation found ${n.length} missing translations, but no generator is configured.`);let i={messages:n,sourceLocale:e.sourceLocale,version:1};return En(await Dn({args:e.generator.args??[],command:e.generator.command,cwd:t,env:r,input:JSON.stringify(i)}))}async function Sn({config:e,cwd:t,missing:n,response:r}){let i=new Map(n.map(e=>[An(e),e])),a=new Map;for(let e of r.translations){let t=An(e);if(!i.has(t))throw Error(`Translation generator returned unexpected entry ${e.locale}:${e.catalog}:${e.id}.`);if(a.has(t))throw Error(`Translation generator returned duplicate entry ${e.locale}:${e.catalog}:${e.id}.`);if(!e.translation.trim())throw Error(`Translation generator returned an empty entry ${e.locale}:${e.id}.`);a.set(t,e.translation)}let o=[...i.keys()].filter(e=>!a.has(e));if(o.length>0)throw Error(`Translation generator omitted ${o.length} required entries.`);let s=await Ne(`@lingui/message-utils/compileMessage`,t);for(let e of n){let t=a.get(An(e));On({compileMessage:s,id:e.id,locale:e.locale,source:e.message,translation:t})}for(let n of e.locales)if(n!==e.sourceLocale)for(let r of e.catalogs){let i=X(t,Z(e,n,r)),o=await wn(i),s=!1;for(let[e,t]of Object.entries(o)){let i=a.get(An({catalog:r,id:e,locale:n}));if(i!==void 0){if(t.translation?.trim())throw Error(`Refusing to overwrite preserved translation ${n}:${e}.`);t.translation=i,s=!0}}s&&await Tn(i,o)}}async function Cn({config:e,cwd:t}){let n=await bn({config:e,cwd:t});if(n.length>0)throw Error(`I18n catalogs remain incomplete: ${n.length} translations are missing.`);let r=await Ne(`@lingui/message-utils/compileMessage`,t);for(let n of e.locales)if(n!==e.sourceLocale)for(let i of e.catalogs){let a=await wn(X(t,Z(e,n,i)));for(let[e,t]of Object.entries(a))if(!t.obsolete){if(typeof t.message!=`string`||typeof t.translation!=`string`)throw Error(`Incomplete source metadata for active translation ${n}:${e}.`);On({compileMessage:r,id:e,locale:n,source:t.message,translation:t.translation})}}}async function wn(e){let t=JSON.parse(await V(e,`utf8`));if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Lingui rich JSON catalog must be an object: ${e}.`);for(let[n,r]of Object.entries(t)){if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`Invalid Lingui rich JSON message ${n} in ${e}.`);let t=r;if(t.translation!==void 0&&typeof t.translation!=`string`)throw Error(`Invalid translation value for ${n} in ${e}.`);if(t.message!==void 0&&t.message!==null&&typeof t.message!=`string`)throw Error(`Invalid source message value for ${n} in ${e}.`);if(t.context!==void 0&&typeof t.context!=`string`)throw Error(`Invalid context value for ${n} in ${e}.`);if(t.obsolete!==void 0&&typeof t.obsolete!=`boolean`)throw Error(`Invalid obsolete marker for ${n} in ${e}.`);if(t.comments!==void 0&&(!Array.isArray(t.comments)||t.comments.some(e=>typeof e!=`string`)))throw Error(`Invalid comments for ${n} in ${e}.`);if(t.origin!==void 0&&(!Array.isArray(t.origin)||t.origin.some(e=>!Array.isArray(e)||typeof e[0]!=`string`||e[1]!==void 0&&typeof e[1]!=`number`)))throw Error(`Invalid origins for ${n} in ${e}.`);if(t.placeholders!==void 0&&(!t.placeholders||typeof t.placeholders!=`object`||Array.isArray(t.placeholders)))throw Error(`Invalid placeholders for ${n} in ${e}.`)}return t}async function Tn(e,t){await B(F(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;await U(n,`${JSON.stringify(t,null,2)}\n`),await De(n,e)}function En(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Translation generator returned invalid JSON.`)}if(!t||typeof t!=`object`||t.version!==1||!Array.isArray(t.translations))throw Error(`Translation generator returned an invalid response envelope.`);for(let e of t.translations)if(!e||typeof e!=`object`||typeof e.id!=`string`||typeof e.catalog!=`string`||typeof e.locale!=`string`||typeof e.translation!=`string`)throw Error(`Translation generator returned an invalid translation entry.`);return t}function Dn({args:e,command:t,cwd:n,env:r,input:i}){return R(t,e,{cwd:n,env:r,stdio:[{string:i},`pipe`,`ignore`]}).then(({stdout:e})=>{if(Buffer.byteLength(e)>10*1024*1024)throw Error(`Translation generator output exceeded 10 MiB.`);return e}).catch(()=>{throw Error(`Translation generator exited unsuccessfully.`)})}function On({compileMessage:e,id:t,locale:n,source:r,translation:i}){let a,o;try{a=e.compileMessageOrThrow(r),o=e.compileMessageOrThrow(i)}catch{throw Error(`Translation ${n}:${t} is not valid ICU MessageFormat.`)}let s=kn(a),c=kn(o);if(s.length!==c.length||s.some((e,t)=>e!==c[t]))throw Error(`Translation ${n}:${t} does not preserve source ICU placeholders.`)}function kn(e){let t=[];function n(e){for(let r of e){if(typeof r==`string`)continue;let[e,i=`argument`,a]=r;if(t.push(`${e}:${i}`),a&&typeof a==`object`&&!Array.isArray(a))for(let e of Object.values(a))Array.isArray(e)&&n(e)}}return n(e),t.sort()}function An(e){return`${e.locale}\0${e.catalog}\0${e.id}`}function jn(e){return Re(`sha256`).update(e).digest(`hex`)}async function Mn(e){return jn(await V(e))}function Nn(e){return Buffer.from(`${JSON.stringify(e,null,2)}\n`)}async function Pn({bucket:e,digest:t,projectId:n,source:r,store:i}){if(ln(t),await Mn(r)!==t)throw Error(`I18n object source does not match declared SHA-256 digest ${t}.`);let a=pn(n,t);await i.has(e,a)||await i.upload(e,a,r,`application/octet-stream`);let o=`${r}.${process.pid}.${W()}.verify`;try{if(await i.download(e,a,o),await Mn(o)!==t)throw Error(`Existing immutable i18n object ${a} failed integrity verification.`)}finally{await H(o,{force:!0})}}async function Fn({bucket:e,key:t,reference:n,store:r,temporaryDirectory:i}){let a=Nn(n),o=I(i,`reference-${W()}.json`);if(await r.has(e,t))try{if(await r.download(e,t,o),!(await V(o)).equals(a))throw Error(`Immutable i18n reference ${t} already resolves to different snapshot data.`);return}finally{await H(o,{force:!0})}await U(o,a,{flag:`wx`});try{await r.upload(e,t,o,`application/json`)}finally{await H(o,{force:!0})}let s=I(i,`reference-${W()}.verify.json`);try{if(await r.download(e,t,s),!(await V(s)).equals(a))throw Error(`Uploaded immutable i18n reference ${t} failed verification.`)}finally{await H(s,{force:!0})}}async function In({bucket:e,manifest:t,projectId:n,store:r,temporaryDirectory:i}){let a=Nn(t),o=jn(a),s=I(i,`manifest-${o}.json`);await U(s,a,{flag:`wx`});try{await Pn({bucket:e,digest:o,projectId:n,source:s,store:r})}finally{await H(s,{force:!0})}return o}async function Ln({bucket:e,key:t,store:n,temporaryDirectory:r}){if(!await n.has(e,t))return;let i=I(r,`reference-${W()}.json`);try{await n.download(e,t,i);let r=JSON.parse(await V(i,`utf8`));if(r.version!==1||typeof r.revision!=`string`||typeof r.snapshot!=`string`)throw Error(`Invalid i18n reference at ${t}.`);return un(r.revision),ln(r.snapshot),r}finally{await H(i,{force:!0})}}async function Rn({bucket:e,projectId:t,revision:n,store:r,temporaryDirectory:i}){let a=await Ln({bucket:e,key:mn(t,n),store:r,temporaryDirectory:i});if(a&&a.revision!==n)throw Error(`I18n commit reference does not match requested revision ${n}.`);return a}async function zn({bucket:e,projectId:t,reference:n,store:r,tag:i,temporaryDirectory:a}){await Fn({bucket:e,key:mn(t,n.revision),reference:n,store:r,temporaryDirectory:a}),i&&await Fn({bucket:e,key:hn(t,i),reference:n,store:r,temporaryDirectory:a})}async function Bn({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:a}){ln(n);let o=I(L(t),`v1`,`sha256`,n.slice(0,2),n);if(await Hn(o,n)===!1){await B(F(o),{recursive:!0});let t=`${o}.${process.pid}.${W()}.tmp`;try{if(await i.download(e,pn(r,n),t),await Mn(t)!==n)throw Error(`Downloaded i18n object failed SHA-256 verification: ${n}.`);await H(o,{force:!0}),await De(t,o)}finally{await H(t,{force:!0})}}await B(F(a),{recursive:!0});let s=`${a}.${process.pid}.${W()}.tmp`;try{if(await xe(o,s),await Mn(s)!==n)throw Error(`Cached i18n object failed SHA-256 verification: ${n}.`);await H(a,{force:!0}),await De(s,a)}finally{await H(s,{force:!0})}}async function Vn({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,temporaryDirectory:a}){let o=I(a,`manifest-${n}.json`);await Bn({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:o});let s=JSON.parse(await V(o,`utf8`));if(s.version!==1||s.projectId!==r||typeof s.revision!=`string`||!Array.isArray(s.files)||!Array.isArray(s.catalogs)||s.catalogs.some(e=>typeof e!=`string`)||!Array.isArray(s.locales)||s.locales.some(e=>typeof e!=`string`)||typeof s.sourceLocale!=`string`||typeof s.generator!=`string`||typeof s.linguiVersion!=`string`)throw Error(`Invalid i18n snapshot manifest ${n}.`);un(s.revision),s.baseline!==void 0&&ln(s.baseline);for(let e of s.files){if(!e||typeof e!=`object`||typeof e.path!=`string`||typeof e.digest!=`string`||typeof e.size!=`number`)throw Error(`Invalid file entry in i18n snapshot manifest ${n}.`);ln(e.digest)}return s}async function Hn(e,t){try{return(await Oe(e)).isFile()&&await Mn(e)===t}catch{return!1}}async function Un({cwd:e=process.cwd(),env:t=process.env}={}){if((await Ie({cwd:e})).i18n){if(t.COREFRAME_I18N_RELEASE_REVISION){await Kn({cwd:e,env:t,revision:t.COREFRAME_I18N_RELEASE_REVISION});return}await vn(e)}}async function Wn({cwd:e=process.cwd(),projectConfig:t}={}){let n=t??await Ie({cwd:e});if(!n.i18n)return;let r=qn(n.i18n),i=X(e,r.directory);try{if(!(await Oe(i)).isDirectory())throw Error(`I18n catalog path is not a directory: ${i}.`)}catch(t){if(t.code!==`ENOENT`)throw t;await vn(e);return}for(let t of r.locales)for(let n of r.catalogs)try{if(!(await Oe(X(e,Z(r,t,n)))).isFile())throw Error(`I18n catalog path is not a file: ${t}/${n}.json.`)}catch(t){if(t.code!==`ENOENT`)throw t;await vn(e);return}}async function Gn({cwd:e=process.cwd(),env:t=process.env,store:n,tag:r}){gn(r);let i=await Jn({cwd:e,env:t,store:n});await nr(e);let a=await tr(e);await rr(e,r,a);let o=await we(I(Me(),`coreframe-i18n-prepare-`));try{let n=await Rn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,revision:a,store:i.store,temporaryDirectory:o});if(n){let e=await Vn({bucket:i.assets.sourceBucket,cacheRoot:i.cacheRoot,digest:n.snapshot,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return er(i,e,a),await Xn(i,e),await zn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:n,store:i.store,tag:r,temporaryDirectory:o}),{reused:!0,snapshot:n.snapshot}}return await $n(i,o,async()=>{let n=await Yn(i,a,o);n||await Qn(i),await vn(e);let s=await bn({config:i.config,cwd:e}),c=await xn({config:i.config,cwd:e,env:t,messages:s});await Sn({config:i.config,cwd:e,missing:s,response:c}),await Cn({config:i.config,cwd:e}),await yn({config:i.config,cwd:e,strict:!0,temporaryDirectory:o});let l=await Zn(i),u={...n?{baseline:n}:{},catalogs:i.config.catalogs,files:l,generator:s.length>0?i.config.generator?.id??`unconfigured`:`none`,linguiVersion:await ir(e),locales:i.config.locales,projectId:i.assets.projectId,revision:a,sourceLocale:i.config.sourceLocale,version:1},d=await In({bucket:i.assets.sourceBucket,manifest:u,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return await zn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:{revision:a,snapshot:d,version:1},store:i.store,tag:r,temporaryDirectory:o}),{reused:!1,snapshot:d}})}finally{await H(o,{force:!0,recursive:!0})}}async function Kn({cwd:e=process.cwd(),env:t=process.env,revision:n,store:r}={}){let i=await Ie({cwd:e});if(!i.i18n)return;let a=await Jn({cwd:e,env:t,store:r,projectConfig:i}),o=un(n??await tr(e)),s=await we(I(Me(),`coreframe-i18n-materialize-`));try{let e=await Rn({bucket:a.assets.sourceBucket,projectId:a.assets.projectId,revision:o,store:a.store,temporaryDirectory:s});if(!e)throw Error(`No prepared i18n snapshot exists for commit ${o}. Push a v* tag for this commit and wait for the translation gate.`);let t=await Vn({bucket:a.assets.sourceBucket,cacheRoot:a.cacheRoot,digest:e.snapshot,projectId:a.assets.projectId,store:a.store,temporaryDirectory:s});return er(a,t,o),await Xn(a,t),{revision:o,snapshot:e.snapshot}}finally{await H(s,{force:!0,recursive:!0})}}function qn(e){let t=dn(e.sourceLocale,`Source locale`),n=[...new Set(e.locales.map(e=>dn(e,`Locale`)))],r=[...new Set(e.catalogs.map(e=>dn(e,`Catalog`)))];if(n.length===0||!n.includes(t))throw Error(`I18n locales must include the source locale.`);if(r.length===0)throw Error(`I18n configuration requires at least one catalog.`);if(e.generator&&(!e.generator.command.trim()||!e.generator.id.trim()))throw Error(`I18n generator command and ID must be non-empty.`);return{catalogs:r,directory:e.directory??`locales`,generator:e.generator,locales:n,sourceLocale:t}}async function Jn({cwd:e=process.cwd(),env:t=process.env,projectConfig:n,store:r}){let i=n??await Ie({cwd:e});if(!i.i18n)throw Error(`Missing i18n configuration in coreframe.config.ts.`);if(!i.assets)throw Error(`I18n snapshots require the existing private build bucket configured under assets.`);let a=i.assets;return{assets:a,cacheRoot:L(e,`.coreframe`,`i18n`,`cache`),config:qn(i.i18n),cwd:L(e),env:t,store:r??ve({config:a,env:t})}}async function Yn(e,t,n){let{stdout:r}=await R(`git`,[`rev-list`,`--first-parent`,`--skip=1`,t],{cwd:e.cwd,stdin:`ignore`});for(let t of r.split(/\r?\n/).filter(Boolean)){let r=await Rn({bucket:e.assets.sourceBucket,projectId:e.assets.projectId,revision:un(t),store:e.store,temporaryDirectory:n});if(!r)continue;let i=await Vn({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:r.snapshot,projectId:e.assets.projectId,store:e.store,temporaryDirectory:n});return er(e,i,t),await Xn(e,i),r.snapshot}}async function Xn(e,t){for(let n of t.files)if(await Bn({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:n.digest,projectId:e.assets.projectId,store:e.store,target:X(e.cwd,n.path)}),(await Oe(X(e.cwd,n.path))).size!==n.size)throw Error(`Materialized i18n artifact size does not match manifest: ${n.path}.`)}async function Zn(e){let t=[];for(let n of e.config.locales)for(let r of e.config.catalogs){let i=Z(e.config,n,r),a=X(e.cwd,i),o=await Mn(a);await Pn({bucket:e.assets.sourceBucket,digest:o,projectId:e.assets.projectId,source:a,store:e.store}),t.push({digest:o,path:i,size:(await Oe(a)).size})}return t.sort((e,t)=>e.path.localeCompare(t.path))}async function Qn(e){let{stdout:t}=await R(`git`,[`rev-parse`,`--show-prefix`],{cwd:e.cwd,stdin:`ignore`}),n=t.trim(),{stdout:r}=await R(`git`,[`log`,`-1`,`--format=%H`,`--diff-filter=AM`,`--`,`:(top)${`${n}${e.config.directory}/${e.config.sourceLocale}/${e.config.catalogs[0]}.po`}`],{cwd:e.cwd,stdin:`ignore`}),i=r.trim();if(!i)return!1;let a=(await Ne(`@lingui/format-po`,e.cwd)).formatter({lineNumbers:!1}),o=!1;for(let t of e.config.locales)for(let r of e.config.catalogs){let s=`${n}${`${e.config.directory}/${t}/${r}.po`}`;try{let{stdout:n}=await R(`git`,[`show`,`${i}:${s}`],{cwd:e.cwd,stdin:`ignore`});await Tn(X(e.cwd,Z(e.config,t,r)),a.parse(n)),o=!0}catch{}}return o}async function $n(e,t,n){let r=[];for(let n of e.config.locales)for(let i of e.config.catalogs){let a=Z(e.config,n,i),o=X(e.cwd,a);try{await ye(o)}catch{continue}let s=I(t,`previous-catalogs`,a);await B(F(s),{recursive:!0}),await De(o,s),r.push({backup:s,path:o})}try{let e=await n();return await H(I(t,`previous-catalogs`),{force:!0,recursive:!0}),e}catch(t){for(let t of e.config.locales)for(let n of e.config.catalogs)await H(X(e.cwd,Z(e.config,t,n)),{force:!0});for(let{backup:e,path:t}of r)await B(F(t),{recursive:!0}),await De(e,t);throw t}}function er(e,t,n){if(t.revision!==n||t.projectId!==e.assets.projectId||t.sourceLocale!==e.config.sourceLocale||JSON.stringify(t.locales)!==JSON.stringify(e.config.locales)||JSON.stringify(t.catalogs)!==JSON.stringify(e.config.catalogs))throw Error(`I18n snapshot does not match commit or project configuration.`);let r=e.config.locales.flatMap(t=>e.config.catalogs.map(n=>Z(e.config,t,n))),i=t.files.map(e=>e.path);if(new Set(i).size!==i.length||JSON.stringify(i.sort())!==JSON.stringify(r.sort()))throw Error(`I18n snapshot has an incomplete or unexpected artifact set.`)}async function tr(e){let{stdout:t}=await R(`git`,[`rev-parse`,`HEAD`],{cwd:e,stdin:`ignore`});return un(t.trim())}async function nr(e){let{stdout:t}=await R(`git`,[`status`,`--porcelain`],{cwd:e,stdin:`ignore`});if(t.trim())throw Error(`Tagged i18n preparation requires a clean Git tree.`)}async function rr(e,t,n){let{stdout:r}=await R(`git`,[`rev-parse`,`${t}^{commit}`],{cwd:e,stdin:`ignore`});if(r.trim()!==n)throw Error(`Release tag ${t} does not point to checked-out commit ${n}.`)}async function ir(e){let{stdout:t}=await R(`pnpm`,[`exec`,`lingui`,`--version`],{cwd:e,stdin:`ignore`});return t.trim()}const ar=[`Use a B2 Multi-Bucket Application Key restricted to the configured private build-object and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),or=r(f,{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}}),sr=r(f,{displayName:`profile`,async from(e){return ge(e)}}),cr=r(f,{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}}),lr=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in the packaged Flutter client.`,async from(e){return N(e)}}),ur=p({name:`assets`,cmds:{configure:n({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${ar}`,args:{profile:u({type:sr,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{z.note(ar,`Required B2 key access`);let t=await z.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(z.isCancel(t))throw Error(`Asset credential configuration was cancelled.`);let n=await z.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(z.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);await _e({applicationKey:n,applicationKeyId:t.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:n({name:`add`,args:{file:u({type:f,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:c({long:`id`,type:f,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:c({long:`alt`,type:l(f),description:`Required alt text for raster image and SVG assets.`}),pack:c({long:`pack`,type:l(cr),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:c({long:`widths`,type:l(or),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:n,json:r,pack:i,variantWidths:a})=>me(await de({alt:e,file:t,id:n,pack:i,variantWidths:a}),r)}),build:n({name:`build`,args:{id:c({long:`id`,type:l(f),description:`Build only one logical asset ID.`}),pack:c({long:`pack`,type:l(cr),description:`Build only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>me(await fe({id:e,pack:n}),t)}),check:n({name:`check`,args:{fix:i({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:c({long:`pack`,type:l(cr),description:`Check only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await pe({fix:e,pack:n});me(r,t),r.ok||(process.exitCode=1)}}),publish:n({name:`publish`,args:{pack:c({long:`pack`,type:l(cr),description:`Publish only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await he({pack:t});me(n,e),n.ok||(process.exitCode=1)}}),status:n({name:`status`,args:{pack:c({long:`pack`,type:l(cr),description:`Report status for only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await pe({pack:t});me(n,e),n.ok||(process.exitCode=1)}})}}),dr=p({name:`flutter`,cmds:{acceptance:n({name:`acceptance`,description:`Run the complete packaged Flutter conformance gate on macOS.`,args:{apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:lr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e})=>se({environment:{...process.env,COREFRAME_API_ORIGIN:e}})}),codegen:n({name:`codegen`,description:`Generate Flutter bridge contracts and Panda-backed Mix theme tokens.`,args:{check:i({long:`check`,description:`Fail when generated Flutter artifacts are missing or stale.`,defaultValue:()=>!1})},handler:({check:e})=>ae({check:e})}),prepare:n({name:`prepare`,description:`Build and package the React client for one Flutter platform.`,args:{platform:u({type:s(j),displayName:`platform`,description:`Flutter platform whose packaged client should be prepared.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:lr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>M({apiOrigin:e,platform:t})}),check:n({name:`check`,description:`Reject missing, stale, modified, or incorrectly targeted Flutter assets.`,args:{platform:u({type:s(j),displayName:`platform`,description:`Flutter platform whose packaged client should be checked.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:lr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>A({apiOrigin:e,platform:t})})}}),fr=p({name:`i18n`,cmds:{build:n({name:`build`,description:`Extract source messages or materialize an exact release catalog snapshot.`,args:{},handler:async()=>{await Un()}}),materialize:n({name:`materialize`,description:`Materialize the immutable i18n snapshot for an exact commit.`,args:{revision:c({long:`revision`,type:l(f),description:`Full commit SHA. Defaults to the checked-out commit.`})},handler:async({revision:e})=>{let t=await Kn({revision:e});t&&console.log(`Materialized i18n snapshot ${t.snapshot}.`)}}),prepare:n({name:`prepare`,description:`Fill missing translations, strictly compile, and publish an immutable tagged snapshot.`,args:{tag:c({long:`tag`,type:f,description:`Pushed v* release tag that points to the checked-out commit.`})},handler:async({tag:e})=>{let t=await Gn({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),pr=G.platform===`win32`?`react-router.cmd`:`react-router`,mr=G.platform===`win32`?`panda.cmd`:`panda`;async function hr(e=G.cwd()){await vr(e),await _r(e,[`typegen`])}async function gr(e=G.cwd(),t=G.env,n){if((t.COREFRAME_PLATFORM??t.TAURI_ENV_PLATFORM??`web`)!==`web`)return;let r=P.resolve(e,`.coreframe/dashboard-build`),i=P.join(r,`client`),a=P.resolve(e,`dist/client/__dashboard`);await H(r,{force:!0,recursive:!0}),await yr(e,mr,[`build`],t),await _r(e,[`build`,...n?[`--mode`,n]:[]],t),await H(a,{force:!0,recursive:!0}),await B(P.dirname(a),{recursive:!0}),await Se(i,a,{recursive:!0})}async function _r(e,t,n=G.env){await yr(e,pr,t,n)}async function vr(e){await H(P.resolve(e,`dashboard/.react-router`),{force:!0,recursive:!0})}async function yr(e,t,n,r=G.env){await R(t,n,{cwd:P.resolve(e,`dashboard`),env:{...r,PATH:P.resolve(e,`node_modules/.bin`)+P.delimiter+(r.PATH??r.Path??``)},stdio:`inherit`})}const br=p({name:`dashboard`,cmds:{build:n({name:`build`,args:{mode:c({long:`mode`,type:l(f),description:`Vite environment mode used for the dashboard build.`})},handler:({mode:e})=>gr(void 0,void 0,e)}),typegen:n({name:`typegen`,args:{},handler:()=>hr()})}}),xr=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function Sr(e,t){let n=wr(e,t);if(!Tr(n)||!Er(n,[`description`,`requires`,`routes`,`verifier`])||!Or(n.description)||n.requires!==void 0&&(!Array.isArray(n.requires)||!n.requires.every(Or))||n.verifier!==void 0&&!Or(n.verifier)||!Array.isArray(n.routes))throw Error(`${t} must contain a description string, routes array, and optional requires and verifier fields.`);let r=(n.requires??[]).map(e=>Cr(e));if(new Set(r).size!==r.length)throw Error(`${t} contains duplicate recipe requirements.`);let i=n.routes.map((e,n)=>{if(!Tr(e)||!Dr(e,[`path`,`router`,`when`])||!Or(e.path)||!Or(e.router)||!Or(e.when))throw Error(`${t} route ${n+1} must contain router, path, and when strings.`);return{path:e.path,router:e.router,when:e.when}}),a=i.map(e=>`${e.router}\0${e.path}`);if(new Set(a).size!==a.length)throw Error(`${t} contains a duplicate router and path pair.`);return{description:n.description,requires:r,routes:i,verifier:n.verifier}}function Cr(e){if(!xr.test(e))throw Error(`Recipe names use lowercase letters, numbers, and single hyphens.`);return e}function wr(e,t){try{return qe(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Tr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Er(e,t){return Object.keys(e).every(e=>t.includes(e))}function Dr(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function Or(e){return typeof e==`string`&&e.length>0}const kr=`https://github.com/airlock-labs/coreframe.git`;function Ar(e,t){return K(`git`,e,{cwd:t,encoding:`utf8`})}function jr(e,t){let n=Ar(e,t);if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${t?`\n${t}`:``}`)}return n.stdout}function Mr(e,t){let n=Ar([`remote`,`get-url`,e],t);if(n.status===2)return null;if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Could not inspect remote ${e}.${t?`\n${t}`:``}`)}return n.stdout.trim()}function Nr({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`}={}){if(n.length===0)throw Error(`Remote name must not be empty.`);jr([`rev-parse`,`--show-toplevel`],e);let r=Mr(n,e);if(r===null)jr([`remote`,`add`,n,kr],e),console.log(`Added ${n} remote: ${kr}`);else if(r===kr)console.log(`${n} remote already points at ${kr}`);else throw Error(`${n} remote points at ${r}, not ${kr}.\nChoose the intended template source before continuing, then update or rename the remote manually.`);t&&(jr([`fetch`,n,`--tags`,`--prune`],e),console.log(`Fetched ${n}.`))}const Pr=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;function Fr(e){return Pr.test(e)?`v${e}`:e}function Ir(e){return`${Fr(e)}:template`}function Lr(e,t){return`${Ir(e)}/${t}`}function Rr({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`,target:r}={}){let i=Hr(e),a=Kr(i,[`rev-parse`,`--show-toplevel`]),o=Fr(r??Ur(i));return Nr({cwd:a,fetch:t,remote:n}),{projectRoot:i,ref:o,repositoryRoot:a}}function zr(e,t,n){return Br(e,t,n).toString(`utf8`)}function Br(e,t,n){let r=`${t}:${n}`,i=K(`git`,[`show`,r],{cwd:e,encoding:`buffer`});if(i.status!==0)throw Error(`Could not read ${r}. ${qr([`show`,r],i)}`);return i.stdout}function Vr(e,t,n){let r=K(`git`,[`ls-tree`,`-r`,`--name-only`,`-z`,t,`--`,n],{cwd:e,encoding:`buffer`});if(r.status!==0)throw Error(qr([`ls-tree`,t,n],r));return r.stdout.toString(`utf8`).split(`\0`).filter(Boolean)}function Hr(e){let t=L(e);for(;;){let e=I(t,`package.json`),n=Gr(e);if(n!==void 0&&Wr(n,e).engines?.coreframe)return t;let r=F(t);if(r===t)throw Error(`Could not find a package.json with engines.coreframe.`);t=r}}function Ur(e){let t=I(e,`package.json`),n=Gr(t);if(n===void 0)throw Error(`Required file package.json does not exist.`);let r=Wr(n,t).engines?.coreframe;if(!r)throw Error(`package.json must declare an exact engines.coreframe recipe baseline.`);return r}function Wr(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Gr(e){try{return J(e,`utf8`)}catch(e){if(Jr(e)&&e.code===`ENOENT`)return;throw e}}function Kr(e,t){let n=K(`git`,t,{cwd:e,encoding:`utf8`});if(n.status!==0)throw Error(qr(t,n));return n.stdout.trim()}function qr(e,t){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();return`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`}function Jr(e){return e instanceof Error&&`code`in e}const Yr=[{path:`package.json`,requirement:`retain the Coreframe Flutter JavaScript runtime used by src-flutter`,test:e=>e.includes(`"@coreframe/flutter-js"`)},{path:`coreframe.config.ts`,requirement:`enable web and at least one Flutter development platform`,test:Qr},{path:`src/api/client/app-origin.ts`,requirement:`allow the Flutter shell to provide its exact API origin`,test:e=>Zr(e,[`@coreframe/flutter-js/client`,`resolveAppOrigin`,`browserOrigin: location?.origin`])},{path:`src/api/worker/auth-config.ts`,requirement:`trust the exact Flutter authentication origins`,test:e=>Zr(e,[`appendFlutterAuthOrigins`,`appendFlutterAuthOrigins([], development)`])},{path:`src/api/worker/middleware/auth.ts`,requirement:`broker Flutter access tokens and accept only Flutter bearer origins`,test:e=>Zr(e,[`createFlutterAccessTokenResponse`,`isFlutterAuthOrigin(origin, import.meta.env.DEV)`,`readFlutterBearerToken`,`native && ctx.request.method !== "GET"`])&&!e.includes(`isNativeOrigin`)},{path:`src/api/worker/middleware/flutter-cors.ts`,requirement:`provide the Flutter packaged-origin CORS boundary`,test:e=>Zr(e,[`applyFlutterCors`,`handleFlutterCorsPreflight`,`flutterCorsMiddleware`])},{path:`src/api/worker/middleware/index.ts`,requirement:`apply Flutter CORS to ordinary Worker responses`,test:e=>e.includes(`flutterCorsMiddleware`)},{path:`src/web/app/flutter-shell/application.ts`,requirement:`configure the Flutter shell's app-owned query and session hooks`,test:e=>Zr(e,[`configureShellQueryFocus`,`authSessionHint`])},{path:`src/web/dev/flutter-devtools.ts`,requirement:`install the Flutter development tools bridge`,test:e=>e.includes(`installFlutterDevTools`)},{path:`src/web/entry.client.tsx`,requirement:`load Flutter development tools only for non-browser development`,test:e=>Zr(e,[`./dev/flutter-devtools.ts`,`import.meta.env.PLATFORM !== "web"`])}];function Xr(e){let t=[];for(let n of Yr){let r=I(e,n.path);if(!q(r)){t.push(`${n.path} is missing; it must ${n.requirement}.`);continue}let i=J(r,`utf8`);n.test(i)||t.push(`${n.path} must ${n.requirement}.`)}return t}function Zr(e,t){return t.every(t=>e.includes(t))}function Qr(e){let t=e.match(/\bplatforms\s*:\s*\[([\s\S]*?)\]/)?.[1];if(!t)return!1;let n=new Set([...t.matchAll(/(["'`])([^"'`]*)\1/g)].map(e=>e[2]));return n.has(`web`)&&[`ios`,`android`,`macos`].some(e=>n.has(e))}const $r=[{path:`package.json`,requirement:`declare the Tauri CLI, plugin-log, and Coreframe Tauri runtime packages`,test:e=>Q(e,[`"@tauri-apps/cli"`,`"@tauri-apps/plugin-log"`,`"@coreframe/tauri-js"`,`"@coreframe/tauri-plugin-auth-session"`])},{path:`src-tauri/Cargo.toml`,requirement:`declare Tauri, plugin-log, and Coreframe auth-session Rust dependencies`,test:e=>Q(e,[`tauri-build`,`tauri-plugin-log`,`coreframe-tauri-plugin-auth-session`])},{path:`src-tauri/src/main.rs`,requirement:`launch the project-owned Tauri Rust library`,test:e=>e.includes(`::run();`)},{path:`src-tauri/src/lib.rs`,requirement:`register plugin-log and the Coreframe auth-session broker`,test:e=>Q(e,[`tauri_plugin_log::Builder`,`coreframe_tauri_plugin_auth_session::init`,`VITE_APP_ORIGIN`])},{path:`src-tauri/build.rs`,requirement:`forward VITE_APP_ORIGIN and TAURI_DEV_HOST into the Rust build`,test:e=>Q(e,[`VITE_APP_ORIGIN`,`TAURI_DEV_HOST`])},{path:`src-tauri/capabilities/default.json`,requirement:`grant log and auth-session permissions to the main window`,test:e=>Q(e,[`"windows": ["main"]`,`"log:default"`,`"coreframe-tauri-plugin-auth-session:default"`])},{path:`vite.config.ts`,requirement:`define the Tauri runtime and platform environment and fixed native dev server`,test:e=>Q(e,[`env.host === "tauri"`,`"import.meta.env.TAURI"`,`"import.meta.env.PLATFORM"`,`TAURI_DEV_HOST`,`strictPort: true`])},{path:`src/vite-env.d.ts`,requirement:`type the Tauri runtime, platform, development origin, and packaged app origin`,test:e=>Q(e,[`PLATFORM: import("@coreframe/lib/shell").ShellPlatform`,`TAURI: boolean`,`TAURI_DEV_ORIGIN`,`VITE_APP_ORIGIN`])},{path:`react-router.config.ts`,requirement:`skip service-worker generation for non-browser hosts`,test:e=>Q(e,[`resolveCoreframeHost`,`resolveCoreframeHost() === "browser"`])},{path:`src/api/client/app-origin.ts`,requirement:`resolve browser and packaged application origins through the Tauri runtime`,test:e=>Q(e,[`@coreframe/tauri-js/client`,`browserOrigin: location?.origin`,`development: import.meta.env.DEV`,`packagedAppOrigin: import.meta.env.VITE_APP_ORIGIN`,`tauri: import.meta.env.TAURI`,`tauriDevelopmentOrigin: import.meta.env.TAURI_DEV_ORIGIN`])&&!e.includes(`resolveAppOrigin(import.meta.env`)},{path:`src/api/client/auth-fetch.ts`,requirement:`call the selected framework authentication composition`,test:e=>Q(e,[`createAuthenticatedFetch`,`refreshAccess`,`sessionHint: authSessionHint`])},{path:`src/api/client/auth-session-hint.ts`,requirement:`keep native session hints in memory until the credential broker revalidates`,test:e=>Q(e,[`import.meta.env.PLATFORM !== "web"`,`persistence: browserPersistence`,`return false`])},{path:`src/api/client/tauri-auth.ts`,requirement:`compose native API and Better Auth transports behind the virtual auth contract`,test:e=>Q(e,[`createAuthenticatedFetch`,`createTauriAuthenticatedFetch`,`authSessionHint: options.sessionHint`,`mintAccessToken`,`createAuthClient`,`createAuthFetch`,`onSessionChange: options.onSessionChange`])},{path:`src/web/auth/client.ts`,requirement:`call the selected framework Better Auth composition`,test:e=>Q(e,[`createAuthClient as createCoreframeAuthClient`,`createCoreframeAuthClient`,`authFetch`,`customFetchImpl`])},{path:`src/api/worker/middleware/auth.ts`,requirement:`mint and accept bearer access tokens only across the fixed native origin boundary`,test:e=>Q(e,[`appendTauriAppOrigins`,`createTauriAccessTokenResponse`,`isTauriAppOrigin`,`readTauriBearerToken`])},{path:`src/api/worker/fetch.ts`,requirement:`apply native CORS at every Worker response boundary`,test:e=>Q(e,[`handleTauriCorsPreflight`,`applyTauriCors`])},{path:`coreframe.config.ts`,requirement:`enable web and desktop development platforms`,test:e=>Q(e,[`platforms: ["web", "desktop"]`])&&!e.includes(`"ios"`)&&!e.includes(`"android"`)},{path:`src/web/entry.client.tsx`,requirement:`attach native development logs and skip service-worker registration in Tauri`,test:e=>Q(e,[`import "./dev/tauri-log.ts"`,`import.meta.env.TAURI`])},{path:`.env.example`,requirement:`document the packaged VITE_APP_ORIGIN build value`,test:e=>e.includes(`VITE_APP_ORIGIN`)},{path:`.gitignore`,requirement:`ignore the Tauri Cargo target directory`,test:e=>e.includes(`src-tauri/target`)},{path:`.oxfmtrc.json`,requirement:`ignore generated Tauri schemas and target output`,test:e=>Q(e,[`src-tauri/gen/schemas`,`src-tauri/target`])},{path:`src-tauri/AGENTS.md`,requirement:`route native work to owner-local rules and documentation`,test:e=>Q(e,[`.agents/rules/tauri.md`,`docs/authentication.md`,`docs/deployment.md`])},{path:`src-tauri/.agents/rules/tauri.md`,requirement:`install the owner-local durable Tauri native-boundary rule`,test:e=>Q(e,[`## Native Boundary`,`## Security`,`## Documentation`])},{path:`.agents/rules/integrations.yaml`,requirement:`route cross-boundary Tauri work to the owner-local native rule`,test:e=>e.includes(`src-tauri/.agents/rules/tauri.md`)},{path:`src-tauri/docs/authentication.md`,requirement:`document the native credential broker and bearer-token boundary`,test:e=>Q(e,[`@coreframe/tauri-js`,`@coreframe/tauri-plugin-auth-session`,`VITE_APP_ORIGIN`])},{path:`src-tauri/docs/development.md`,requirement:`document native development asset delivery and Leylines scopes`,test:e=>Q(e,[`dev.tauri`,`browser.tauri`,`managed asset`])},{path:`src-tauri/docs/deployment.md`,requirement:`document native release topology, signing, token recovery, and provider setup`,test:e=>Q(e,[`VITE_APP_ORIGIN`,`native-auth`,`access-token signing-secret`])},{path:`src-tauri/docs/privacy-security.md`,requirement:`record the shipped Tauri remote API and secure-storage boundary`,test:e=>Q(e,[`## Remote API Boundary`,`platform secure storage`])},{path:`.github/workflows/tauri-release-artifacts.yml`,requirement:`provide a desktop-only Tauri release-artifact workflow`,test:e=>Q(e,[`Build Tauri Release Artifacts`,`pnpm exec tauri`])&&!e.toLowerCase().includes(`ios`)&&!e.toLowerCase().includes(`android`)}],ei=[`CoreframeTemplateProject7A91C`,`coreframe-template-project-7a91c`,`coreframe_template_project_7a91c`,`com.example.coreframetemplateproject7a91c`];function ti(e){let t=[];for(let n of $r){let r=I(e,n.path);if(!q(r)){t.push(`${n.path} is missing; it must ${n.requirement}.`);continue}let i=J(r,`utf8`);n.test(i)||t.push(`${n.path} must ${n.requirement}.`)}let n=I(e,`src-tauri/tauri.conf.json`);q(n)?ni(n,t):t.push(`src-tauri/tauri.conf.json is missing.`);for(let n of[`src-tauri/Cargo.toml`,`src-tauri/src/main.rs`,`src-tauri/tauri.conf.json`]){let r=I(e,n);q(r)&&ei.some(e=>J(r,`utf8`).includes(e))&&t.push(`${n} must replace the Coreframe template identity sentinel.`)}return t}function ni(e,t){let n;try{n=JSON.parse(J(e,`utf8`))}catch{t.push(`src-tauri/tauri.conf.json must contain valid JSON.`);return}(typeof n.identifier!=`string`||!/^[a-z0-9]+(?:\.[a-z0-9]+){2,}$/.test(n.identifier)||n.identifier.startsWith(`com.example.`))&&t.push(`src-tauri/tauri.conf.json must use an organization-owned reverse-domain identifier.`)}function Q(e,t){return t.every(t=>e.includes(t))}function ri({name:e,...t}){let n=Rr(t),r=`recipes/${e}/recipe.yaml`,i=oi(Sr(zr(n.repositoryRoot,n.ref,r),r).verifier,n.projectRoot);if(i.length>0)throw Error(`Recipe ${e} verification failed:\n${i.map(e=>`- ${e}`).join(`
6
- `)}`);return{name:e,ref:n.ref}}function ii(e){console.log(`Verified Coreframe recipe ${e.name} from ${e.ref}.`)}function ai(e,t){for(let n of e){let e=`recipes/${n}/recipe.yaml`,r=oi(Sr(zr(t.repositoryRoot,t.ref,e),e).verifier,t.projectRoot);if(r.length>0)throw Error(`Recipe ${n} is required but is not fully applied:\n${r.map(e=>`- ${e}`).join(`
7
- `)}\nApply and verify ${n} before continuing.`)}}function oi(e,t){if(!e)throw Error(`Required recipe does not declare a verifier.`);if(e===`tauri`)return ti(t);if(e===`flutter`)return Xr(t);throw Error(`Unknown recipe verifier ${JSON.stringify(e)}.`)}function si({cwd:e=process.cwd(),fetch:t=!0,name:n,remote:r=`template`,target:i}){Cr(n);let a=Rr({cwd:e,fetch:t,remote:r,target:i}),{projectRoot:o,ref:s,repositoryRoot:c}=a,l=`recipes/${n}`,u=`${l}/recipe.yaml`,d=Sr(zr(c,s,u),u);ai(d.requires,a);let f=zr(c,s,`${l}/RECIPE.md`),p=Vr(c,s,`${l}/files`),m=Vr(c,s,`${l}/patches`),h=Vr(c,s,`${l}/.agents`),g=new Map,_=new Map,v=[],y=[],b=[],x=[],S=[],C=[];for(let e of p){let t=e.slice(`${l}/files/`.length);if(mi(t,`Recipe file ${e}`),t.startsWith(`.agents/`))throw Error(`Recipe file ${e} must be stored in the recipe's .agents directory.`);g.set(t,Br(c,s,e)),_.set(t,e)}for(let e of h){let t=e.slice(`${l}/`.length);if(di(t,`Recipe asset ${e}`),g.has(t))throw Error(`Recipe declares ${t} as both a file and an agent asset.`);g.set(t,Br(c,s,e)),_.set(t,e)}for(let e of m){let t=hi(e,l);if(g.has(t))throw Error(`Recipe declares ${t} as both a file and a patch.`);let n=Br(c,s,e);gi(n.toString(`utf8`),t,e),pi(o,t),_i(o,n,!1)?(v.push({contents:n,destinationPath:t}),x.push(t)):_i(o,n,!0)?S.push(t):b.push({destination:t,source:e})}let w=new Map;for(let[e,t]of g){let r=bi(pi(o,e));if(r===void 0)w.set(e,t),y.push(e);else if(r.equals(t))S.push(e);else if(e.startsWith(`.agents/`))throw Error(`Recipe ${n} cannot replace modified ${e}. Reconcile that agent asset manually.`);else b.push({destination:e,source:_.get(e)})}let T=new Map;for(let e of d.routes){if(di(e.router,`Recipe route router`),fi(e.path,`Recipe route path`),g.has(e.router))throw Error(`Recipe cannot replace its destination router ${e.router}.`);if(!g.has(e.path)&&!q(pi(o,e.path)))throw Error(`Recipe route target ${e.path} does not exist.`);let t=T.get(e.router)??li(xi(pi(o,e.router),e.router),e.router);T.set(e.router,t);let r=t.routes.find(t=>t.path===e.path);if(r){if(r.when!==e.when)throw Error(`Recipe ${n} route ${e.path} conflicts with the existing trigger in ${e.router}.`);continue}t.routes.push({path:e.path,when:e.when})}for(let[e,t]of T){t.routes.sort((e,t)=>e.path<t.path?-1:+(e.path>t.path));let n=xi(pi(o,e),e),r=Je(t,{lineWidth:0});r===n?S.push(e):(w.set(e,r),C.push(e))}for(let{destinationPath:e}of v)if(w.has(e))throw Error(`Recipe cannot both write and patch ${e}.`);for(let[e,t]of w){let n=pi(o,e);Ve(F(n),{recursive:!0}),Ke(n,t)}return v.length>0&&vi(o,v.map(({contents:e})=>e)),{created:y.sort(),instructions:f,mergeRequired:b.sort((e,t)=>e.destination.localeCompare(t.destination)),name:n,patched:x.sort(),ref:s,unchanged:[...new Set(S)].sort(),updated:C.sort()}}function ci(e){console.log(`Prepared Coreframe recipe ${e.name} from ${e.ref}.`);for(let t of e.created)console.log(`created: ${t}`);for(let t of e.updated)console.log(`updated: ${t}`);for(let t of e.patched)console.log(`patched: ${t}`);for(let t of e.mergeRequired)console.log(`merge-required: ${t.destination} (source: ${e.ref}:${t.source})`);for(let t of e.unchanged)console.log(`unchanged: ${t}`);console.log(`\nContinue by following ${e.ref}:recipes/${e.name}/RECIPE.md:\n`),console.log(e.instructions.trimEnd())}function li(e,t){let n=ui(e,t);if(!Si(n)||!Ci(n,[`routes`,`rules`])||!Array.isArray(n.rules)||!n.rules.every(wi)||!Array.isArray(n.routes))throw Error(`${t} must contain only string rules and a routes array.`);let r=n.routes.map((e,n)=>{if(!Si(e)||!Ci(e,[`path`,`when`])||!wi(e.path)||!wi(e.when))throw Error(`${t} route ${n+1} must contain path and when strings.`);return{path:e.path,when:e.when}}),i=r.map(e=>e.path);if(new Set(i).size!==i.length)throw Error(`${t} contains duplicate route paths.`);return{rules:n.rules,routes:r}}function ui(e,t){try{return qe(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function di(e,t){if(!e.startsWith(`.agents/`))throw Error(`${t} must be a normalized project-relative path beneath .agents/.`);mi(e,t)}function fi(e,t){if(mi(e,t),!/(?:^|\/)\.agents\/rules\/.+\.md$/u.test(e))throw Error(`${t} must point to a Markdown rule beneath an .agents/rules directory.`)}function pi(e,t){mi(t,`Recipe destination`);let n=I(e,t),r=e;for(let e of t.split(`/`))if(r=I(r,e),q(r)&&Be(r).isSymbolicLink())throw Error(`Recipe destination ${t} crosses symbolic link ${r}.`);return n}function mi(e,t){if(e.length===0||ce(e)||e===`..`||e.startsWith(`../`)||e.includes(`\\`)||le.normalize(e)!==e)throw Error(`${t} must be a normalized project-relative path.`)}function hi(e,t){let n=e.slice(`${t}/patches/`.length);if(!n.endsWith(`.patch`))throw Error(`Recipe patch ${e} must use a .patch suffix.`);let r=n.slice(0,-6);return mi(r,`Recipe patch ${e}`),r}function gi(e,t,n){let r=e.match(/^diff --git .+$/gmu)??[],i=e.match(/^--- .+$/gmu)??[],a=e.match(/^\+\+\+ .+$/gmu)??[];if(r.length!==1||r[0]!==`diff --git a/${t} b/${t}`||i.length!==1||a.length!==1||i[0]!==`--- a/${t}`||a[0]!==`+++ b/${t}`||/^(?:deleted file mode |GIT binary patch$|new file mode |rename from |rename to )/mu.test(e))throw Error(`Recipe patch ${n} must modify only ${t}.`)}function _i(e,t,n){let r=[`apply`,`--check`,`--whitespace=nowarn`];return n&&r.push(`--reverse`),r.push(`-`),K(`git`,r,{cwd:e,input:t}).status===0}function vi(e,t){let n=K(`git`,[`apply`,`--whitespace=nowarn`,`-`],{cwd:e,input:Buffer.concat(t.flatMap(e=>[e,Buffer.from(e.at(-1)===10?``:`
8
- `)])),encoding:`utf8`});if(n.status!==0){let e=n.stderr.trim()||n.stdout.trim();throw Error(`Could not apply recipe patches.${e?`\n${e}`:``}`)}}function yi(e){return bi(e)?.toString(`utf8`)}function bi(e){try{return J(e)}catch(e){if(Ti(e)&&e.code===`ENOENT`)return;throw e}}function xi(e,t){let n=yi(e);if(n===void 0)throw Error(`Required file ${t} does not exist.`);return n}function Si(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ci(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function wi(e){return typeof e==`string`&&e.length>0}function Ti(e){return e instanceof Error&&`code`in e}function Ei(e={}){let{ref:t,repositoryRoot:n}=Rr(e),r=Vr(n,t,`recipes`).filter(e=>/^recipes\/[^/]+\/recipe\.yaml$/u.test(e)).map(e=>{let r=e.split(`/`)[1];return Cr(r),{description:Sr(zr(n,t,e),e).description,name:r}});return r.sort((e,t)=>e.name.localeCompare(t.name)),{recipes:r,ref:t}}function Di(e){console.log(`Coreframe recipes at ${e.ref}:`);for(let t of e.recipes)console.log(`${t.name} — ${t.description}`)}const Oi=`.agents/skills/coreframe-upgrade/SKILL.md`;function ki(e,t={}){return K(`git`,e,t)}function Ai(e){return e.stderr.toString(`utf8`).trim()||e.stdout.toString(`utf8`).trim()}function ji(e,t){let n=Lr(e,t),r=ki([`show`,n],{encoding:`utf8`});if(r.status!==0){let e=Ai(r);throw Error(`Could not read ${n}.${e?` ${e}`:``}`)}return r.stdout.toString()}function Mi(){let e=ki([`rev-parse`,`--show-toplevel`],{encoding:`utf8`});if(e.status!==0){let t=Ai(e);throw Error(`Could not find git repository root.${t?` ${t}`:``}`)}return e.stdout.toString().trim()}function Ni(e,t){let n=He(I(Me(),`coreframe-upgrade-skill-`)),r=I(n,`SKILL.md`);try{Ke(r,t);let n=Ai(ki([`--no-pager`,`diff`,`--no-index`,`--color=never`,`--`,e,r]));n&&console.log(n)}finally{We(n,{force:!0,recursive:!0})}}function Pi({apply:e,target:t}){let n=I(Mi(),Oi),r=Fr(t);if(!q(n))throw Error(`Local ${Oi} does not exist.`);let i=J(n,`utf8`),a=ji(t,Oi);return i===a?(console.log(`Coreframe upgrade skill matches ${r}:template/${Oi}.`),0):e?(Ke(n,a),console.error(`Updated ${Oi} from ${r}:template. Reread it before continuing the upgrade.`),20):(console.error(`Coreframe upgrade skill differs from ${r}:template/${Oi}.`),console.error(`Run again with --apply to update it, then reread ${Oi} before continuing.`),Ni(n,a),20)}const Fi=[{matches:e=>e===`drizzle`||e.startsWith(`drizzle/`),reason:`project-owned migration history`},{matches:e=>e===`drizzle-hold`||e.startsWith(`drizzle-hold/`),reason:`project-owned migration history`},{matches:e=>e===`src/web/routes.ts`||e.startsWith(`src/web/app/routes/`),reason:`downstream-owned demonstration routes`},{matches:e=>e===`pnpm-lock.yaml`||e===`src-tauri/Cargo.lock`,reason:`downstream-owned dependency lockfile`}],Ii=new Set([`100644`,`100755`,`120000`]);function Li(e,t={}){return K(`git`,e,t)}function Ri(e){let t=Li(e,{encoding:`utf8`});if(t.status!==0){let n=t.stderr.toString().trim()||t.stdout.toString().trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout.toString()}function zi(e){let t=Li(e);if(t.status!==0){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout}function Bi(){return Ri([`rev-parse`,`--show-toplevel`]).trim()}function Vi(e){let t=I(e,`package.json`);if(!q(t))throw Error(`Missing --base <git-ref>, and package.json does not exist.`);let n=JSON.parse(J(t,`utf8`)).engines?.coreframe;if(typeof n!=`string`||n.length===0)throw Error(`Missing --base <git-ref>, and package.json engines.coreframe is not set.`);return n}function Hi(e){let t=[],n=0;for(let r=0;r<e.length;r+=1)e[r]===0&&(t.push(e.subarray(n,r).toString(`utf8`)),n=r+1);return t.filter(e=>e.length>0)}function Ui(e,t){let n=Hi(zi([`diff`,`--name-status`,`-z`,`--no-renames`,Ir(e),Ir(t),`--`])),r=[];for(let e=0;e<n.length;e+=2){let t=n[e],i=n[e+1];if(!t||!i)throw Error(`Could not parse git diff --name-status output.`);r.push({path:i,status:t})}return r}function Wi(e,t){let n=zi([`ls-tree`,`-z`,Ir(e),`--`,t]);if(n.length===0)return null;let r=Hi(n)[0],i=r.indexOf(` `);if(i===-1)throw Error(`Could not parse git ls-tree output for ${e}:${t}.`);let[a,o,s]=r.slice(0,i).split(` `);if(!a||!o||!s)throw Error(`Could not parse git ls-tree metadata for ${e}:${t}.`);return{mode:a,object:s,path:t,type:o}}function Gi(e){return zi([`cat-file`,`blob`,e.object])}function Ki(e,t){let n=L(e,t),r=e.endsWith(ue)?e:`${e}${ue}`;if(n!==e&&!n.startsWith(r))throw Error(`Refusing to access path outside repository: ${t}`);return n}function qi(e){try{return Be(e),!0}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return!1;throw e}}function Ji(e){return(e.mode&73)!=0}function Yi(e){return e===null||e.type===`blob`&&Ii.has(e.mode)}function Xi(e){return Fi.find(t=>t.matches(e))?.reason}function Zi(e,t,n){let r=Ki(e,t);if(n===null)return{matches:!qi(r)};if(!Yi(n))return{matches:!1,reason:`unsupported template entry mode ${n.mode} ${n.type}`};let i;try{i=Be(r)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{matches:!1,reason:`path is missing from worktree`};throw e}let a=Gi(n);return n.mode===`120000`?i.isSymbolicLink()?{matches:Buffer.from(Ue(r),`utf8`).equals(a)}:{matches:!1,reason:`worktree path is not a symlink`}:i.isFile()?(n.mode===`100755`?Ji(i):!Ji(i))?{matches:J(r).equals(a)}:{matches:!1,reason:`worktree executable bit differs from template`}:{matches:!1,reason:`worktree path is not a regular file`}}function Qi(e){qi(e)&&We(e,{force:!0,recursive:!1})}function $i(e,t,n){let r=Ki(e,t);if(n===null){Qi(r);return}if(Ve(F(r),{recursive:!0}),n.mode===`120000`){Qi(r),Ge(Gi(n).toString(`utf8`),r);return}let i=qi(r)?Be(r):null;i&&!i.isFile()&&Qi(r),Ke(r,Gi(n)),ze(r,n.mode===`100755`?493:420)}function ea(e,t){return e===null&&t!==null?`add`:e!==null&&t===null?`delete`:`update`}function ta(e,t){if(t.length!==0){console.log(`${e}:`);for(let e of t){let t=e.reason?` (${e.reason})`:``;console.log(` ${e.action}: ${e.path}${t}`)}console.log(``)}}function na(e){let t=Bi(),n=Fr(e.base??Vi(t)),r=Fr(e.target),i=Ui(n,r),a=[],o=[],s=[],c=[];for(let e of i){let i=Xi(e.path);if(i){o.push({action:`ignored`,path:e.path,reason:i});continue}let l=Wi(n,e.path),u=Wi(r,e.path),d=ea(l,u);if(!Yi(l)||!Yi(u)){s.push({action:d,path:e.path,reason:`unsupported template entry type`});continue}if(Zi(t,e.path,u).matches){c.push({action:`unchanged`,path:e.path});continue}let f=Zi(t,e.path,l);if(!f.matches){s.push({action:d,path:e.path,reason:f.reason??`downstream differs from base template`});continue}a.push({action:d,path:e.path,targetEntry:u})}if(e.apply)for(let e of a)$i(t,e.path,e.targetEntry??null);console.log(`Coreframe template fast-forward: ${n} -> ${r}`),console.log(``),ta(e.apply?`Applied clean template updates`:`Would apply clean template updates`,a),ta(`Ignored downstream-owned paths`,o),ta(`Skipped for agent review`,s),c.length>0&&console.log(`${c.length} changed template path(s) already matched the target state.`),i.length===0&&console.log(`No template file changes found in the requested range.`),!e.apply&&a.length>0&&(console.log(``),console.log(`Run with --apply to write the ${a.length} clean update(s).`))}const ra=[`dependencies`,`devDependencies`];function ia(e){let t=K(`git`,e,{encoding:`utf8`});if(t.status!==0){let n=t.stderr.trim()||t.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout}function aa(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}: ${e instanceof Error?e.message:e}`)}}function oa(e,t){let n=`${Fr(e)}:${t}`;return aa(ia([`show`,n]),n)}function sa(e){return e.startsWith(`@coreframe/`)}function ca(e){return e.startsWith(`file:`)||e.startsWith(`link:`)||e.startsWith(`workspace:`)}function la(e){return e.startsWith(`file:`)||e.startsWith(`link:`)}function ua(e,t){let n=e.indexOf(`:`),r=e.slice(n+1),i=le.normalize(le.join(`template`,r,`package.json`));if(r.length===0||le.isAbsolute(r)||i===`..`||i.startsWith(`../`))throw Error(`Invalid local template dependency for ${t}: ${e}`);return i}function da(e){let t=oa(e,`template/package.json`),n=[],r=new Set;for(let i of ra)for(let[a,o]of Object.entries(t[i]??{})){if(!sa(a)||!la(o))continue;if(r.has(a))throw Error(`Target template declares ${a} more than once.`);let t=ua(o,a),s=oa(e,t);if(s.name!==a||typeof s.version!=`string`)throw Error(`${Fr(e)}:${t} must declare ${a} with a version.`);n.push({group:i,name:a,spec:`^${s.version}`}),r.add(a)}return n}function fa(e,t){for(let n of ra){let r=e[n]?.[t];if(r)return{group:n,spec:r}}}function pa(e,t,n){let r=t.match(/\n([\t ]+)"/u)?.[1]??` `,i=t.endsWith(`
5
+ `)}async function tn({apiOrigin:e,cwd:t=process.cwd(),environment:n=process.env,platform:r=`web`,simulator:i=!1,prepareClient:a=oe,runCommand:o=rn}={}){nn(r,i);let s={...n};delete s.COREFRAME_PLATFORM,delete s.TAURI_ENV_PLATFORM;let c=r===`web`?void 0:P(e??n.COREFRAME_API_ORIGIN);for(let e of Zt(r,{apiOrigin:c,cwd:t,simulator:i})){if(e.kind===`prepare`){if(!c)throw Error(`A production API origin is required for the Flutter ${e.platform} build.`);await a({apiOrigin:c,cwd:t,environment:s,platform:e.platform});continue}await o(e.command,e.args,{cwd:e.cwd,env:{...s,...e.environment}})}r===`android`?console.log($t(t)):r===`ios`&&console.log(en(t,{simulator:i}))}function nn(e,t){if(t&&e!==`ios`)throw Error(`The --simulator flag is only supported for the iOS build target.`)}async function rn(e,t,{cwd:n,env:r}){await z(e,t,{cwd:n,env:r,stdio:`inherit`})}function an(e,t,n,r){return{kind:`command`,command:e,args:t,cwd:n,...r===void 0?{}:{environment:r}}}const on=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in a packaged Flutter client.`,async from(e){return P(e)}}),sn=n({name:`build`,description:`Build the web client or a release Flutter app. Tauri is not built.`,args:{platform:u({type:l(s(Xt)),displayName:`platform`,description:`Build target: web, iOS, Android, or macOS. Defaults to web.`}),apiOrigin:c({long:`api-origin`,type:l(on),description:`Exact production HTTPS API origin for a Flutter build. Defaults to COREFRAME_API_ORIGIN.`}),simulator:i({long:`simulator`,description:`Build iOS for the simulator instead of a physical device.`,defaultValue:()=>!1})},handler:({apiOrigin:e,platform:t,simulator:n})=>tn({apiOrigin:e,platform:t,simulator:n})}),cn=/^[a-f0-9]{64}$/,ln=/^[a-f0-9]{40}$/,un=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function dn(e){if(!cn.test(e))throw Error(`Invalid SHA-256 digest "${e}".`);return e}function fn(e){if(!ln.test(e))throw Error(`Invalid full Git revision "${e}".`);return e}function pn(e,t){if(!un.test(e))throw Error(`${t} must contain only letters, numbers, dots, underscores, or hyphens.`);return e}function mn(e){return`projects/${pn(e,`Project ID`)}/i18n/v1`}function hn(e,t){return dn(t),`${mn(e)}/objects/sha256/${t.slice(0,2)}/${t}`}function gn(e,t){return fn(t),`${mn(e)}/commits/${t}.json`}function _n(e,t){return vn(t),`${mn(e)}/releases/${encodeURIComponent(t)}.json`}function vn(e){if(!e.startsWith(`v`)||e.length<2||e.length>128||/\s/.test(e)||e.includes(`..`))throw Error(`Release tag "${e}" must be a valid v-prefixed tag.`);return e}function X(e,t){if(!t||t.startsWith(`/`)||t.includes(`\0`))throw Error(`Unsafe i18n artifact path "${t}".`);let n=R(e),r=R(n,t);if(r!==n&&!r.startsWith(`${n}${de}`))throw Error(`Unsafe i18n artifact path "${t}".`);return r}function Z(e,t,n){return`${e.directory}/${t}/${n}.json`}function yn(e,t,n){return`${e.directory}/${t}/${n}.mjs`}async function bn(e){await z(`pnpm`,[`exec`,`lingui`,`extract`],{cwd:e,stdio:`inherit`})}async function xn({config:e,cwd:t,strict:n,temporaryDirectory:r}){let i=[];try{for(let n of e.locales)for(let a of e.catalogs){let o=X(t,Z(e,n,a)),s=await En(o),c=Object.fromEntries(Object.entries(s).filter(([,e])=>!e.obsolete)),l=L(r,`${n}-${a}.json`);await V(I(l),{recursive:!0}),await Se(o,l),i.push({path:o,backup:l}),await Dn(o,c)}await z(`pnpm`,[`exec`,`lingui`,`compile`,...n?[`--strict`]:[]],{cwd:t,stdio:`inherit`})}finally{try{for(let{path:e,backup:t}of i)await Se(t,e)}finally{for(let n of e.locales)for(let r of e.catalogs)await U(X(t,yn(e,n,r)),{force:!0})}}}async function Sn({config:e,cwd:t}){let n=[];for(let r of e.locales)if(r!==e.sourceLocale)for(let i of e.catalogs){let a=await En(X(t,Z(e,r,i)));for(let[e,t]of Object.entries(a)){if(t.obsolete||t.translation?.trim())continue;let a=t.message;if(typeof a!=`string`||!a)throw Error(`Missing source message metadata for ${r}:${e}.`);n.push({catalog:i,comments:t.comments?.filter(e=>typeof e==`string`)??[],context:t.context,id:e,locale:r,message:a,origins:t.origin?.map(([e,t])=>t?`${e}:${t}`:e)??[],placeholders:Object.keys(t.placeholders??{}).sort()})}}return n.sort((e,t)=>Mn(e).localeCompare(Mn(t)))}async function Cn({config:e,cwd:t,messages:n,env:r=process.env}){if(n.length===0)return{translations:[],version:1};if(!e.generator)throw Error(`I18n preparation found ${n.length} missing translations, but no generator is configured.`);let i={messages:n,sourceLocale:e.sourceLocale,version:1};return On(await kn({args:e.generator.args??[],command:e.generator.command,cwd:t,env:r,input:JSON.stringify(i)}))}async function wn({config:e,cwd:t,missing:n,response:r}){let i=new Map(n.map(e=>[Mn(e),e])),a=new Map;for(let e of r.translations){let t=Mn(e);if(!i.has(t))throw Error(`Translation generator returned unexpected entry ${e.locale}:${e.catalog}:${e.id}.`);if(a.has(t))throw Error(`Translation generator returned duplicate entry ${e.locale}:${e.catalog}:${e.id}.`);if(!e.translation.trim())throw Error(`Translation generator returned an empty entry ${e.locale}:${e.id}.`);a.set(t,e.translation)}let o=[...i.keys()].filter(e=>!a.has(e));if(o.length>0)throw Error(`Translation generator omitted ${o.length} required entries.`);let s=await Pe(`@lingui/message-utils/compileMessage`,t);for(let e of n){let t=a.get(Mn(e));An({compileMessage:s,id:e.id,locale:e.locale,source:e.message,translation:t})}for(let n of e.locales)if(n!==e.sourceLocale)for(let r of e.catalogs){let i=X(t,Z(e,n,r)),o=await En(i),s=!1;for(let[e,t]of Object.entries(o)){let i=a.get(Mn({catalog:r,id:e,locale:n}));if(i!==void 0){if(t.translation?.trim())throw Error(`Refusing to overwrite preserved translation ${n}:${e}.`);t.translation=i,s=!0}}s&&await Dn(i,o)}}async function Tn({config:e,cwd:t}){let n=await Sn({config:e,cwd:t});if(n.length>0)throw Error(`I18n catalogs remain incomplete: ${n.length} translations are missing.`);let r=await Pe(`@lingui/message-utils/compileMessage`,t);for(let n of e.locales)if(n!==e.sourceLocale)for(let i of e.catalogs){let a=await En(X(t,Z(e,n,i)));for(let[e,t]of Object.entries(a))if(!t.obsolete){if(typeof t.message!=`string`||typeof t.translation!=`string`)throw Error(`Incomplete source metadata for active translation ${n}:${e}.`);An({compileMessage:r,id:e,locale:n,source:t.message,translation:t.translation})}}}async function En(e){let t=JSON.parse(await H(e,`utf8`));if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Lingui rich JSON catalog must be an object: ${e}.`);for(let[n,r]of Object.entries(t)){if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`Invalid Lingui rich JSON message ${n} in ${e}.`);let t=r;if(t.translation!==void 0&&typeof t.translation!=`string`)throw Error(`Invalid translation value for ${n} in ${e}.`);if(t.message!==void 0&&t.message!==null&&typeof t.message!=`string`)throw Error(`Invalid source message value for ${n} in ${e}.`);if(t.context!==void 0&&typeof t.context!=`string`)throw Error(`Invalid context value for ${n} in ${e}.`);if(t.obsolete!==void 0&&typeof t.obsolete!=`boolean`)throw Error(`Invalid obsolete marker for ${n} in ${e}.`);if(t.comments!==void 0&&(!Array.isArray(t.comments)||t.comments.some(e=>typeof e!=`string`)))throw Error(`Invalid comments for ${n} in ${e}.`);if(t.origin!==void 0&&(!Array.isArray(t.origin)||t.origin.some(e=>!Array.isArray(e)||typeof e[0]!=`string`||e[1]!==void 0&&typeof e[1]!=`number`)))throw Error(`Invalid origins for ${n} in ${e}.`);if(t.placeholders!==void 0&&(!t.placeholders||typeof t.placeholders!=`object`||Array.isArray(t.placeholders)))throw Error(`Invalid placeholders for ${n} in ${e}.`)}return t}async function Dn(e,t){await V(I(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;await W(n,`${JSON.stringify(t,null,2)}\n`),await Oe(n,e)}function On(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Translation generator returned invalid JSON.`)}if(!t||typeof t!=`object`||t.version!==1||!Array.isArray(t.translations))throw Error(`Translation generator returned an invalid response envelope.`);for(let e of t.translations)if(!e||typeof e!=`object`||typeof e.id!=`string`||typeof e.catalog!=`string`||typeof e.locale!=`string`||typeof e.translation!=`string`)throw Error(`Translation generator returned an invalid translation entry.`);return t}function kn({args:e,command:t,cwd:n,env:r,input:i}){return z(t,e,{cwd:n,env:r,stdio:[{string:i},`pipe`,`ignore`]}).then(({stdout:e})=>{if(Buffer.byteLength(e)>10*1024*1024)throw Error(`Translation generator output exceeded 10 MiB.`);return e}).catch(()=>{throw Error(`Translation generator exited unsuccessfully.`)})}function An({compileMessage:e,id:t,locale:n,source:r,translation:i}){let a,o;try{a=e.compileMessageOrThrow(r),o=e.compileMessageOrThrow(i)}catch{throw Error(`Translation ${n}:${t} is not valid ICU MessageFormat.`)}let s=jn(a),c=jn(o);if(s.length!==c.length||s.some((e,t)=>e!==c[t]))throw Error(`Translation ${n}:${t} does not preserve source ICU placeholders.`)}function jn(e){let t=[];function n(e){for(let r of e){if(typeof r==`string`)continue;let[e,i=`argument`,a]=r;if(t.push(`${e}:${i}`),a&&typeof a==`object`&&!Array.isArray(a))for(let e of Object.values(a))Array.isArray(e)&&n(e)}}return n(e),t.sort()}function Mn(e){return`${e.locale}\0${e.catalog}\0${e.id}`}function Nn(e){return ze(`sha256`).update(e).digest(`hex`)}async function Pn(e){return Nn(await H(e))}function Fn(e){return Buffer.from(`${JSON.stringify(e,null,2)}\n`)}async function In({bucket:e,digest:t,projectId:n,source:r,store:i}){if(dn(t),await Pn(r)!==t)throw Error(`I18n object source does not match declared SHA-256 digest ${t}.`);let a=hn(n,t);await i.has(e,a)||await i.upload(e,a,r,`application/octet-stream`);let o=`${r}.${process.pid}.${G()}.verify`;try{if(await i.download(e,a,o),await Pn(o)!==t)throw Error(`Existing immutable i18n object ${a} failed integrity verification.`)}finally{await U(o,{force:!0})}}async function Ln({bucket:e,key:t,reference:n,store:r,temporaryDirectory:i}){let a=Fn(n),o=L(i,`reference-${G()}.json`);if(await r.has(e,t))try{if(await r.download(e,t,o),!(await H(o)).equals(a))throw Error(`Immutable i18n reference ${t} already resolves to different snapshot data.`);return}finally{await U(o,{force:!0})}await W(o,a,{flag:`wx`});try{await r.upload(e,t,o,`application/json`)}finally{await U(o,{force:!0})}let s=L(i,`reference-${G()}.verify.json`);try{if(await r.download(e,t,s),!(await H(s)).equals(a))throw Error(`Uploaded immutable i18n reference ${t} failed verification.`)}finally{await U(s,{force:!0})}}async function Rn({bucket:e,manifest:t,projectId:n,store:r,temporaryDirectory:i}){let a=Fn(t),o=Nn(a),s=L(i,`manifest-${o}.json`);await W(s,a,{flag:`wx`});try{await In({bucket:e,digest:o,projectId:n,source:s,store:r})}finally{await U(s,{force:!0})}return o}async function zn({bucket:e,key:t,store:n,temporaryDirectory:r}){if(!await n.has(e,t))return;let i=L(r,`reference-${G()}.json`);try{await n.download(e,t,i);let r=JSON.parse(await H(i,`utf8`));if(r.version!==1||typeof r.revision!=`string`||typeof r.snapshot!=`string`)throw Error(`Invalid i18n reference at ${t}.`);return fn(r.revision),dn(r.snapshot),r}finally{await U(i,{force:!0})}}async function Bn({bucket:e,projectId:t,revision:n,store:r,temporaryDirectory:i}){let a=await zn({bucket:e,key:gn(t,n),store:r,temporaryDirectory:i});if(a&&a.revision!==n)throw Error(`I18n commit reference does not match requested revision ${n}.`);return a}async function Vn({bucket:e,projectId:t,reference:n,store:r,tag:i,temporaryDirectory:a}){await Ln({bucket:e,key:gn(t,n.revision),reference:n,store:r,temporaryDirectory:a}),i&&await Ln({bucket:e,key:_n(t,i),reference:n,store:r,temporaryDirectory:a})}async function Hn({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:a}){dn(n);let o=L(R(t),`v1`,`sha256`,n.slice(0,2),n);if(await Wn(o,n)===!1){await V(I(o),{recursive:!0});let t=`${o}.${process.pid}.${G()}.tmp`;try{if(await i.download(e,hn(r,n),t),await Pn(t)!==n)throw Error(`Downloaded i18n object failed SHA-256 verification: ${n}.`);await U(o,{force:!0}),await Oe(t,o)}finally{await U(t,{force:!0})}}await V(I(a),{recursive:!0});let s=`${a}.${process.pid}.${G()}.tmp`;try{if(await Se(o,s),await Pn(s)!==n)throw Error(`Cached i18n object failed SHA-256 verification: ${n}.`);await U(a,{force:!0}),await Oe(s,a)}finally{await U(s,{force:!0})}}async function Un({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,temporaryDirectory:a}){let o=L(a,`manifest-${n}.json`);await Hn({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:o});let s=JSON.parse(await H(o,`utf8`));if(s.version!==1||s.projectId!==r||typeof s.revision!=`string`||!Array.isArray(s.files)||!Array.isArray(s.catalogs)||s.catalogs.some(e=>typeof e!=`string`)||!Array.isArray(s.locales)||s.locales.some(e=>typeof e!=`string`)||typeof s.sourceLocale!=`string`||typeof s.generator!=`string`||typeof s.linguiVersion!=`string`)throw Error(`Invalid i18n snapshot manifest ${n}.`);fn(s.revision),s.baseline!==void 0&&dn(s.baseline);for(let e of s.files){if(!e||typeof e!=`object`||typeof e.path!=`string`||typeof e.digest!=`string`||typeof e.size!=`number`)throw Error(`Invalid file entry in i18n snapshot manifest ${n}.`);dn(e.digest)}return s}async function Wn(e,t){try{return(await ke(e)).isFile()&&await Pn(e)===t}catch{return!1}}async function Gn({cwd:e=process.cwd(),env:t=process.env}={}){if((await Le({cwd:e})).i18n){if(t.COREFRAME_I18N_RELEASE_REVISION){await Jn({cwd:e,env:t,revision:t.COREFRAME_I18N_RELEASE_REVISION});return}await bn(e)}}async function Kn({cwd:e=process.cwd(),projectConfig:t}={}){let n=t??await Le({cwd:e});if(!n.i18n)return;let r=Yn(n.i18n),i=X(e,r.directory);try{if(!(await ke(i)).isDirectory())throw Error(`I18n catalog path is not a directory: ${i}.`)}catch(t){if(t.code!==`ENOENT`)throw t;await bn(e);return}for(let t of r.locales)for(let n of r.catalogs)try{if(!(await ke(X(e,Z(r,t,n)))).isFile())throw Error(`I18n catalog path is not a file: ${t}/${n}.json.`)}catch(t){if(t.code!==`ENOENT`)throw t;await bn(e);return}}async function qn({cwd:e=process.cwd(),env:t=process.env,store:n,tag:r}){vn(r);let i=await Xn({cwd:e,env:t,store:n});await ir(e);let a=await rr(e);await ar(e,r,a);let o=await Te(L(Ne(),`coreframe-i18n-prepare-`));try{let n=await Bn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,revision:a,store:i.store,temporaryDirectory:o});if(n){let e=await Un({bucket:i.assets.sourceBucket,cacheRoot:i.cacheRoot,digest:n.snapshot,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return nr(i,e,a),await Qn(i,e),await Vn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:n,store:i.store,tag:r,temporaryDirectory:o}),{reused:!0,snapshot:n.snapshot}}return await tr(i,o,async()=>{let n=await Zn(i,a,o);n||await er(i),await bn(e);let s=await Sn({config:i.config,cwd:e}),c=await Cn({config:i.config,cwd:e,env:t,messages:s});await wn({config:i.config,cwd:e,missing:s,response:c}),await Tn({config:i.config,cwd:e}),await xn({config:i.config,cwd:e,strict:!0,temporaryDirectory:o});let l=await $n(i),u={...n?{baseline:n}:{},catalogs:i.config.catalogs,files:l,generator:s.length>0?i.config.generator?.id??`unconfigured`:`none`,linguiVersion:await or(e),locales:i.config.locales,projectId:i.assets.projectId,revision:a,sourceLocale:i.config.sourceLocale,version:1},d=await Rn({bucket:i.assets.sourceBucket,manifest:u,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return await Vn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:{revision:a,snapshot:d,version:1},store:i.store,tag:r,temporaryDirectory:o}),{reused:!1,snapshot:d}})}finally{await U(o,{force:!0,recursive:!0})}}async function Jn({cwd:e=process.cwd(),env:t=process.env,revision:n,store:r}={}){let i=await Le({cwd:e});if(!i.i18n)return;let a=await Xn({cwd:e,env:t,store:r,projectConfig:i}),o=fn(n??await rr(e)),s=await Te(L(Ne(),`coreframe-i18n-materialize-`));try{let e=await Bn({bucket:a.assets.sourceBucket,projectId:a.assets.projectId,revision:o,store:a.store,temporaryDirectory:s});if(!e)throw Error(`No prepared i18n snapshot exists for commit ${o}. Push a v* tag for this commit and wait for the translation gate.`);let t=await Un({bucket:a.assets.sourceBucket,cacheRoot:a.cacheRoot,digest:e.snapshot,projectId:a.assets.projectId,store:a.store,temporaryDirectory:s});return nr(a,t,o),await Qn(a,t),{revision:o,snapshot:e.snapshot}}finally{await U(s,{force:!0,recursive:!0})}}function Yn(e){let t=pn(e.sourceLocale,`Source locale`),n=[...new Set(e.locales.map(e=>pn(e,`Locale`)))],r=[...new Set(e.catalogs.map(e=>pn(e,`Catalog`)))];if(n.length===0||!n.includes(t))throw Error(`I18n locales must include the source locale.`);if(r.length===0)throw Error(`I18n configuration requires at least one catalog.`);if(e.generator&&(!e.generator.command.trim()||!e.generator.id.trim()))throw Error(`I18n generator command and ID must be non-empty.`);return{catalogs:r,directory:e.directory??`locales`,generator:e.generator,locales:n,sourceLocale:t}}async function Xn({cwd:e=process.cwd(),env:t=process.env,projectConfig:n,store:r}){let i=n??await Le({cwd:e});if(!i.i18n)throw Error(`Missing i18n configuration in coreframe.config.ts.`);if(!i.assets)throw Error(`I18n snapshots require the existing private build bucket configured under assets.`);let a=i.assets;return{assets:a,cacheRoot:R(e,`.coreframe`,`i18n`,`cache`),config:Yn(i.i18n),cwd:R(e),env:t,store:r??ye({config:a,env:t})}}async function Zn(e,t,n){let{stdout:r}=await z(`git`,[`rev-list`,`--first-parent`,`--skip=1`,t],{cwd:e.cwd,stdin:`ignore`});for(let t of r.split(/\r?\n/).filter(Boolean)){let r=await Bn({bucket:e.assets.sourceBucket,projectId:e.assets.projectId,revision:fn(t),store:e.store,temporaryDirectory:n});if(!r)continue;let i=await Un({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:r.snapshot,projectId:e.assets.projectId,store:e.store,temporaryDirectory:n});return nr(e,i,t),await Qn(e,i),r.snapshot}}async function Qn(e,t){for(let n of t.files)if(await Hn({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:n.digest,projectId:e.assets.projectId,store:e.store,target:X(e.cwd,n.path)}),(await ke(X(e.cwd,n.path))).size!==n.size)throw Error(`Materialized i18n artifact size does not match manifest: ${n.path}.`)}async function $n(e){let t=[];for(let n of e.config.locales)for(let r of e.config.catalogs){let i=Z(e.config,n,r),a=X(e.cwd,i),o=await Pn(a);await In({bucket:e.assets.sourceBucket,digest:o,projectId:e.assets.projectId,source:a,store:e.store}),t.push({digest:o,path:i,size:(await ke(a)).size})}return t.sort((e,t)=>e.path.localeCompare(t.path))}async function er(e){let{stdout:t}=await z(`git`,[`rev-parse`,`--show-prefix`],{cwd:e.cwd,stdin:`ignore`}),n=t.trim(),{stdout:r}=await z(`git`,[`log`,`-1`,`--format=%H`,`--diff-filter=AM`,`--`,`:(top)${`${n}${e.config.directory}/${e.config.sourceLocale}/${e.config.catalogs[0]}.po`}`],{cwd:e.cwd,stdin:`ignore`}),i=r.trim();if(!i)return!1;let a=(await Pe(`@lingui/format-po`,e.cwd)).formatter({lineNumbers:!1}),o=!1;for(let t of e.config.locales)for(let r of e.config.catalogs){let s=`${n}${`${e.config.directory}/${t}/${r}.po`}`;try{let{stdout:n}=await z(`git`,[`show`,`${i}:${s}`],{cwd:e.cwd,stdin:`ignore`});await Dn(X(e.cwd,Z(e.config,t,r)),a.parse(n)),o=!0}catch{}}return o}async function tr(e,t,n){let r=[];for(let n of e.config.locales)for(let i of e.config.catalogs){let a=Z(e.config,n,i),o=X(e.cwd,a);try{await be(o)}catch{continue}let s=L(t,`previous-catalogs`,a);await V(I(s),{recursive:!0}),await Oe(o,s),r.push({backup:s,path:o})}try{let e=await n();return await U(L(t,`previous-catalogs`),{force:!0,recursive:!0}),e}catch(t){for(let t of e.config.locales)for(let n of e.config.catalogs)await U(X(e.cwd,Z(e.config,t,n)),{force:!0});for(let{backup:e,path:t}of r)await V(I(t),{recursive:!0}),await Oe(e,t);throw t}}function nr(e,t,n){if(t.revision!==n||t.projectId!==e.assets.projectId||t.sourceLocale!==e.config.sourceLocale||JSON.stringify(t.locales)!==JSON.stringify(e.config.locales)||JSON.stringify(t.catalogs)!==JSON.stringify(e.config.catalogs))throw Error(`I18n snapshot does not match commit or project configuration.`);let r=e.config.locales.flatMap(t=>e.config.catalogs.map(n=>Z(e.config,t,n))),i=t.files.map(e=>e.path);if(new Set(i).size!==i.length||JSON.stringify(i.sort())!==JSON.stringify(r.sort()))throw Error(`I18n snapshot has an incomplete or unexpected artifact set.`)}async function rr(e){let{stdout:t}=await z(`git`,[`rev-parse`,`HEAD`],{cwd:e,stdin:`ignore`});return fn(t.trim())}async function ir(e){let{stdout:t}=await z(`git`,[`status`,`--porcelain`],{cwd:e,stdin:`ignore`});if(t.trim())throw Error(`Tagged i18n preparation requires a clean Git tree.`)}async function ar(e,t,n){let{stdout:r}=await z(`git`,[`rev-parse`,`${t}^{commit}`],{cwd:e,stdin:`ignore`});if(r.trim()!==n)throw Error(`Release tag ${t} does not point to checked-out commit ${n}.`)}async function or(e){let{stdout:t}=await z(`pnpm`,[`exec`,`lingui`,`--version`],{cwd:e,stdin:`ignore`});return t.trim()}const sr=[`Use a B2 Multi-Bucket Application Key restricted to the configured private build-object and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),cr=r(f,{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}}),lr=r(f,{displayName:`profile`,async from(e){return _e(e)}}),ur=r(f,{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}}),dr=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in the packaged Flutter client.`,async from(e){return P(e)}}),fr=p({name:`assets`,cmds:{configure:n({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${sr}`,args:{profile:u({type:lr,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{B.note(sr,`Required B2 key access`);let t=await B.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(B.isCancel(t))throw Error(`Asset credential configuration was cancelled.`);let n=await B.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(B.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);await ve({applicationKey:n,applicationKeyId:t.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:n({name:`add`,args:{file:u({type:f,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:c({long:`id`,type:f,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:c({long:`alt`,type:l(f),description:`Required alt text for raster image and SVG assets.`}),pack:c({long:`pack`,type:l(ur),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:c({long:`widths`,type:l(cr),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:n,json:r,pack:i,variantWidths:a})=>he(await fe({alt:e,file:t,id:n,pack:i,variantWidths:a}),r)}),build:n({name:`build`,args:{id:c({long:`id`,type:l(f),description:`Build only one logical asset ID.`}),pack:c({long:`pack`,type:l(ur),description:`Build only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>he(await pe({id:e,pack:n}),t)}),check:n({name:`check`,args:{fix:i({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:c({long:`pack`,type:l(ur),description:`Check only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await me({fix:e,pack:n});he(r,t),r.ok||(process.exitCode=1)}}),publish:n({name:`publish`,args:{pack:c({long:`pack`,type:l(ur),description:`Publish only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await ge({pack:t});he(n,e),n.ok||(process.exitCode=1)}}),status:n({name:`status`,args:{pack:c({long:`pack`,type:l(ur),description:`Report status for only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await me({pack:t});he(n,e),n.ok||(process.exitCode=1)}})}}),pr=p({name:`flutter`,cmds:{acceptance:n({name:`acceptance`,description:`Run the complete packaged Flutter conformance gate on macOS.`,args:{apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:dr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e})=>ce({environment:{...process.env,COREFRAME_API_ORIGIN:e}})}),codegen:n({name:`codegen`,description:`Generate Flutter bridge contracts and Panda-backed Mix theme tokens.`,args:{check:i({long:`check`,description:`Fail when generated Flutter artifacts are missing or stale.`,defaultValue:()=>!1})},handler:({check:e})=>ae({check:e})}),prepare:n({name:`prepare`,description:`Build and package the React client for one Flutter platform.`,args:{platform:u({type:s(N),displayName:`platform`,description:`Flutter platform whose packaged client should be prepared.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:dr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>oe({apiOrigin:e,platform:t})}),check:n({name:`check`,description:`Reject missing, stale, modified, or incorrectly targeted Flutter assets.`,args:{platform:u({type:s(N),displayName:`platform`,description:`Flutter platform whose packaged client should be checked.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:dr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>re({apiOrigin:e,platform:t})})}}),mr=p({name:`i18n`,cmds:{build:n({name:`build`,description:`Extract source messages or materialize an exact release catalog snapshot.`,args:{},handler:async()=>{await Gn()}}),materialize:n({name:`materialize`,description:`Materialize the immutable i18n snapshot for an exact commit.`,args:{revision:c({long:`revision`,type:l(f),description:`Full commit SHA. Defaults to the checked-out commit.`})},handler:async({revision:e})=>{let t=await Jn({revision:e});t&&console.log(`Materialized i18n snapshot ${t.snapshot}.`)}}),prepare:n({name:`prepare`,description:`Fill missing translations, strictly compile, and publish an immutable tagged snapshot.`,args:{tag:c({long:`tag`,type:f,description:`Pushed v* release tag that points to the checked-out commit.`})},handler:async({tag:e})=>{let t=await qn({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),hr=K.platform===`win32`?`react-router.cmd`:`react-router`,gr=K.platform===`win32`?`panda.cmd`:`panda`;async function _r(e=K.cwd()){await br(e),await yr(e,[`typegen`])}async function vr(e=K.cwd(),t=K.env,n){if((t.COREFRAME_PLATFORM??t.TAURI_ENV_PLATFORM??`web`)!==`web`)return;let r=F.resolve(e,`.coreframe/dashboard-build`),i=F.join(r,`client`),a=F.resolve(e,`dist/client/__dashboard`);await U(r,{force:!0,recursive:!0}),await xr(e,gr,[`build`],t),await yr(e,[`build`,...n?[`--mode`,n]:[]],t),await U(a,{force:!0,recursive:!0}),await V(F.dirname(a),{recursive:!0}),await Ce(i,a,{recursive:!0})}async function yr(e,t,n=K.env){await xr(e,hr,t,n)}async function br(e){await U(F.resolve(e,`dashboard/.react-router`),{force:!0,recursive:!0})}async function xr(e,t,n,r=K.env){await z(t,n,{cwd:F.resolve(e,`dashboard`),env:{...r,PATH:F.resolve(e,`node_modules/.bin`)+F.delimiter+(r.PATH??r.Path??``)},stdio:`inherit`})}const Sr=p({name:`dashboard`,cmds:{build:n({name:`build`,args:{mode:c({long:`mode`,type:l(f),description:`Vite environment mode used for the dashboard build.`})},handler:({mode:e})=>vr(void 0,void 0,e)}),typegen:n({name:`typegen`,args:{},handler:()=>_r()})}}),Cr=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function wr(e,t){let n=Er(e,t);if(!Dr(n)||!Or(n,[`description`,`requires`,`routes`,`verifier`])||!Ar(n.description)||n.requires!==void 0&&(!Array.isArray(n.requires)||!n.requires.every(Ar))||n.verifier!==void 0&&!Ar(n.verifier)||!Array.isArray(n.routes))throw Error(`${t} must contain a description string, routes array, and optional requires and verifier fields.`);let r=(n.requires??[]).map(e=>Tr(e));if(new Set(r).size!==r.length)throw Error(`${t} contains duplicate recipe requirements.`);let i=n.routes.map((e,n)=>{if(!Dr(e)||!kr(e,[`path`,`router`,`when`])||!Ar(e.path)||!Ar(e.router)||!Ar(e.when))throw Error(`${t} route ${n+1} must contain router, path, and when strings.`);return{path:e.path,router:e.router,when:e.when}}),a=i.map(e=>`${e.router}\0${e.path}`);if(new Set(a).size!==a.length)throw Error(`${t} contains a duplicate router and path pair.`);return{description:n.description,requires:r,routes:i,verifier:n.verifier}}function Tr(e){if(!Cr.test(e))throw Error(`Recipe names use lowercase letters, numbers, and single hyphens.`);return e}function Er(e,t){try{return Je(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Dr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Or(e,t){return Object.keys(e).every(e=>t.includes(e))}function kr(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function Ar(e){return typeof e==`string`&&e.length>0}const jr=`https://github.com/airlock-labs/coreframe.git`;function Mr(e,t){return q(`git`,e,{cwd:t,encoding:`utf8`})}function Nr(e,t){let n=Mr(e,t);if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${t?`\n${t}`:``}`)}return n.stdout}function Pr(e,t){let n=Mr([`remote`,`get-url`,e],t);if(n.status===2)return null;if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Could not inspect remote ${e}.${t?`\n${t}`:``}`)}return n.stdout.trim()}function Fr({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`}={}){if(n.length===0)throw Error(`Remote name must not be empty.`);Nr([`rev-parse`,`--show-toplevel`],e);let r=Pr(n,e);if(r===null)Nr([`remote`,`add`,n,jr],e),console.log(`Added ${n} remote: ${jr}`);else if(r===jr)console.log(`${n} remote already points at ${jr}`);else throw Error(`${n} remote points at ${r}, not ${jr}.\nChoose the intended template source before continuing, then update or rename the remote manually.`);t&&(Nr([`fetch`,n,`--tags`,`--prune`],e),console.log(`Fetched ${n}.`))}const Ir=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;function Lr(e){return Ir.test(e)?`v${e}`:e}function Rr(e){return`${Lr(e)}:template`}function zr(e,t){return`${Rr(e)}/${t}`}function Br({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`,target:r}={}){let i=Wr(e),a=Jr(i,[`rev-parse`,`--show-toplevel`]),o=Lr(r??Gr(i));return Fr({cwd:a,fetch:t,remote:n}),{projectRoot:i,ref:o,repositoryRoot:a}}function Vr(e,t,n){return Hr(e,t,n).toString(`utf8`)}function Hr(e,t,n){let r=`${t}:${n}`,i=q(`git`,[`show`,r],{cwd:e,encoding:`buffer`});if(i.status!==0)throw Error(`Could not read ${r}. ${Yr([`show`,r],i)}`);return i.stdout}function Ur(e,t,n){let r=q(`git`,[`ls-tree`,`-r`,`--name-only`,`-z`,t,`--`,n],{cwd:e,encoding:`buffer`});if(r.status!==0)throw Error(Yr([`ls-tree`,t,n],r));return r.stdout.toString(`utf8`).split(`\0`).filter(Boolean)}function Wr(e){let t=R(e);for(;;){let e=L(t,`package.json`),n=qr(e);if(n!==void 0&&Kr(n,e).engines?.coreframe)return t;let r=I(t);if(r===t)throw Error(`Could not find a package.json with engines.coreframe.`);t=r}}function Gr(e){let t=L(e,`package.json`),n=qr(t);if(n===void 0)throw Error(`Required file package.json does not exist.`);let r=Kr(n,t).engines?.coreframe;if(!r)throw Error(`package.json must declare an exact engines.coreframe recipe baseline.`);return r}function Kr(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function qr(e){try{return Y(e,`utf8`)}catch(e){if(Xr(e)&&e.code===`ENOENT`)return;throw e}}function Jr(e,t){let n=q(`git`,t,{cwd:e,encoding:`utf8`});if(n.status!==0)throw Error(Yr(t,n));return n.stdout.trim()}function Yr(e,t){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();return`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`}function Xr(e){return e instanceof Error&&`code`in e}const Zr=[{path:`package.json`,requirement:`retain the Coreframe Flutter JavaScript runtime used by src-flutter`,test:e=>e.includes(`"@coreframe/flutter-js"`)},{path:`coreframe.config.ts`,requirement:`enable web and at least one Flutter development platform`,test:ei},{path:`src/api/client/app-origin.ts`,requirement:`allow the Flutter shell to provide its exact API origin`,test:e=>$r(e,[`@coreframe/flutter-js/client`,`resolveAppOrigin`,`browserOrigin: location?.origin`])},{path:`src/api/worker/auth-config.ts`,requirement:`trust the exact Flutter authentication origins`,test:e=>$r(e,[`appendFlutterAuthOrigins`,`appendFlutterAuthOrigins([], development)`])},{path:`src/api/worker/middleware/auth.ts`,requirement:`broker Flutter access tokens and accept only Flutter bearer origins`,test:e=>$r(e,[`createFlutterAccessTokenResponse`,`isFlutterAuthOrigin(origin, import.meta.env.DEV)`,`readFlutterBearerToken`,`native && ctx.request.method !== "GET"`])&&!e.includes(`isNativeOrigin`)},{path:`src/api/worker/middleware/flutter-cors.ts`,requirement:`provide the Flutter packaged-origin CORS boundary`,test:e=>$r(e,[`applyFlutterCors`,`handleFlutterCorsPreflight`,`flutterCorsMiddleware`])},{path:`src/api/worker/middleware/index.ts`,requirement:`apply Flutter CORS to ordinary Worker responses`,test:e=>e.includes(`flutterCorsMiddleware`)},{path:`src/web/app/flutter-shell/application.ts`,requirement:`configure the Flutter shell's app-owned query and session hooks`,test:e=>$r(e,[`configureShellQueryFocus`,`authSessionHint`])},{path:`src/web/entry.client.tsx`,requirement:`load the package-owned Flutter development tools only for non-browser development`,test:e=>$r(e,[`@coreframe/vite/flutter-devtools`,`import.meta.env.PLATFORM !== "web"`])}];function Qr(e){let t=[];for(let n of Zr){let r=L(e,n.path);if(!J(r)){t.push(`${n.path} is missing; it must ${n.requirement}.`);continue}let i=Y(r,`utf8`);n.test(i)||t.push(`${n.path} must ${n.requirement}.`)}return t}function $r(e,t){return t.every(t=>e.includes(t))}function ei(e){let t=e.match(/\bplatforms\s*:\s*\[([\s\S]*?)\]/)?.[1];if(!t)return!1;let n=new Set([...t.matchAll(/(["'`])([^"'`]*)\1/g)].map(e=>e[2]));return n.has(`web`)&&[`ios`,`android`,`macos`].some(e=>n.has(e))}const ti=[{path:`package.json`,requirement:`declare the Tauri CLI, plugin-log, and Coreframe Tauri runtime packages`,test:e=>Q(e,[`"@tauri-apps/cli"`,`"@tauri-apps/plugin-log"`,`"@coreframe/tauri-js"`,`"@coreframe/tauri-plugin-auth-session"`])},{path:`src-tauri/Cargo.toml`,requirement:`declare Tauri, plugin-log, and Coreframe auth-session Rust dependencies`,test:e=>Q(e,[`tauri-build`,`tauri-plugin-log`,`coreframe-tauri-plugin-auth-session`])},{path:`src-tauri/src/main.rs`,requirement:`launch the project-owned Tauri Rust library`,test:e=>e.includes(`::run();`)},{path:`src-tauri/src/lib.rs`,requirement:`register plugin-log and the Coreframe auth-session broker`,test:e=>Q(e,[`tauri_plugin_log::Builder`,`coreframe_tauri_plugin_auth_session::init`,`VITE_APP_ORIGIN`])},{path:`src-tauri/build.rs`,requirement:`forward VITE_APP_ORIGIN and TAURI_DEV_HOST into the Rust build`,test:e=>Q(e,[`VITE_APP_ORIGIN`,`TAURI_DEV_HOST`])},{path:`src-tauri/capabilities/default.json`,requirement:`grant log and auth-session permissions to the main window`,test:e=>Q(e,[`"windows": ["main"]`,`"log:default"`,`"coreframe-tauri-plugin-auth-session:default"`])},{path:`vite.config.ts`,requirement:`define the Tauri runtime and platform environment and fixed native dev server`,test:e=>Q(e,[`env.host === "tauri"`,`"import.meta.env.TAURI"`,`"import.meta.env.PLATFORM"`,`TAURI_DEV_HOST`,`strictPort: true`])},{path:`src/vite-env.d.ts`,requirement:`type the Tauri runtime, platform, development origin, and packaged app origin`,test:e=>Q(e,[`PLATFORM: import("@coreframe/lib/shell").ShellPlatform`,`TAURI: boolean`,`TAURI_DEV_ORIGIN`,`VITE_APP_ORIGIN`])},{path:`react-router.config.ts`,requirement:`skip service-worker generation for non-browser hosts`,test:e=>Q(e,[`resolveCoreframeHost`,`resolveCoreframeHost() === "browser"`])},{path:`src/api/client/app-origin.ts`,requirement:`resolve browser and packaged application origins through the Tauri runtime`,test:e=>Q(e,[`@coreframe/tauri-js/client`,`browserOrigin: location?.origin`,`development: import.meta.env.DEV`,`packagedAppOrigin: import.meta.env.VITE_APP_ORIGIN`,`tauri: import.meta.env.TAURI`,`tauriDevelopmentOrigin: import.meta.env.TAURI_DEV_ORIGIN`])&&!e.includes(`resolveAppOrigin(import.meta.env`)},{path:`src/api/client/auth-fetch.ts`,requirement:`call the selected framework authentication composition`,test:e=>Q(e,[`createAuthenticatedFetch`,`refreshAccess`,`sessionHint: authSessionHint`])},{path:`src/api/client/auth-session-hint.ts`,requirement:`keep native session hints in memory until the credential broker revalidates`,test:e=>Q(e,[`import.meta.env.PLATFORM !== "web"`,`persistence: browserPersistence`,`return false`])},{path:`src/api/client/tauri-auth.ts`,requirement:`compose native API and Better Auth transports behind the virtual auth contract`,test:e=>Q(e,[`createAuthenticatedFetch`,`createTauriAuthenticatedFetch`,`authSessionHint: options.sessionHint`,`mintAccessToken`,`createAuthClient`,`createAuthFetch`,`onSessionChange: options.onSessionChange`])},{path:`src/web/auth/client.ts`,requirement:`call the selected framework Better Auth composition`,test:e=>Q(e,[`createAuthClient as createCoreframeAuthClient`,`createCoreframeAuthClient`,`authFetch`,`customFetchImpl`])},{path:`src/api/worker/middleware/auth.ts`,requirement:`mint and accept bearer access tokens only across the fixed native origin boundary`,test:e=>Q(e,[`appendTauriAppOrigins`,`createTauriAccessTokenResponse`,`isTauriAppOrigin`,`readTauriBearerToken`])},{path:`src/api/worker/fetch.ts`,requirement:`apply native CORS at every Worker response boundary`,test:e=>Q(e,[`handleTauriCorsPreflight`,`applyTauriCors`])},{path:`coreframe.config.ts`,requirement:`enable web and desktop development platforms`,test:e=>Q(e,[`platforms: ["web", "desktop"]`])&&!e.includes(`"ios"`)&&!e.includes(`"android"`)},{path:`src/web/entry.client.tsx`,requirement:`attach native development logs and skip service-worker registration in Tauri`,test:e=>Q(e,[`import "./dev/tauri-log.ts"`,`import.meta.env.TAURI`])},{path:`.env.example`,requirement:`document the packaged VITE_APP_ORIGIN build value`,test:e=>e.includes(`VITE_APP_ORIGIN`)},{path:`.gitignore`,requirement:`ignore the Tauri Cargo target directory`,test:e=>e.includes(`src-tauri/target`)},{path:`.oxfmtrc.json`,requirement:`ignore generated Tauri schemas and target output`,test:e=>Q(e,[`src-tauri/gen/schemas`,`src-tauri/target`])},{path:`src-tauri/AGENTS.md`,requirement:`route native work to owner-local rules and documentation`,test:e=>Q(e,[`.agents/rules/tauri.md`,`docs/authentication.md`,`docs/deployment.md`])},{path:`src-tauri/.agents/rules/tauri.md`,requirement:`install the owner-local durable Tauri native-boundary rule`,test:e=>Q(e,[`## Native Boundary`,`## Security`,`## Documentation`])},{path:`.agents/rules/integrations.yaml`,requirement:`route cross-boundary Tauri work to the owner-local native rule`,test:e=>e.includes(`src-tauri/.agents/rules/tauri.md`)},{path:`src-tauri/docs/authentication.md`,requirement:`document the native credential broker and bearer-token boundary`,test:e=>Q(e,[`@coreframe/tauri-js`,`@coreframe/tauri-plugin-auth-session`,`VITE_APP_ORIGIN`])},{path:`src-tauri/docs/development.md`,requirement:`document native development asset delivery and Leylines scopes`,test:e=>Q(e,[`dev.tauri`,`browser.tauri`,`managed asset`])},{path:`src-tauri/docs/deployment.md`,requirement:`document native release topology, signing, token recovery, and provider setup`,test:e=>Q(e,[`VITE_APP_ORIGIN`,`native-auth`,`access-token signing-secret`])},{path:`src-tauri/docs/privacy-security.md`,requirement:`record the shipped Tauri remote API and secure-storage boundary`,test:e=>Q(e,[`## Remote API Boundary`,`platform secure storage`])},{path:`.github/workflows/tauri-release-artifacts.yml`,requirement:`provide a desktop-only Tauri release-artifact workflow`,test:e=>Q(e,[`Build Tauri Release Artifacts`,`pnpm exec tauri`])&&!e.toLowerCase().includes(`ios`)&&!e.toLowerCase().includes(`android`)}],ni=[`CoreframeTemplateProject7A91C`,`coreframe-template-project-7a91c`,`coreframe_template_project_7a91c`,`com.example.coreframetemplateproject7a91c`];function ri(e){let t=[];for(let n of ti){let r=L(e,n.path);if(!J(r)){t.push(`${n.path} is missing; it must ${n.requirement}.`);continue}let i=Y(r,`utf8`);n.test(i)||t.push(`${n.path} must ${n.requirement}.`)}let n=L(e,`src-tauri/tauri.conf.json`);J(n)?ii(n,t):t.push(`src-tauri/tauri.conf.json is missing.`);for(let n of[`src-tauri/Cargo.toml`,`src-tauri/src/main.rs`,`src-tauri/tauri.conf.json`]){let r=L(e,n);J(r)&&ni.some(e=>Y(r,`utf8`).includes(e))&&t.push(`${n} must replace the Coreframe template identity sentinel.`)}return t}function ii(e,t){let n;try{n=JSON.parse(Y(e,`utf8`))}catch{t.push(`src-tauri/tauri.conf.json must contain valid JSON.`);return}(typeof n.identifier!=`string`||!/^[a-z0-9]+(?:\.[a-z0-9]+){2,}$/.test(n.identifier)||n.identifier.startsWith(`com.example.`))&&t.push(`src-tauri/tauri.conf.json must use an organization-owned reverse-domain identifier.`)}function Q(e,t){return t.every(t=>e.includes(t))}function ai({name:e,...t}){let n=Br(t),r=`recipes/${e}/recipe.yaml`,i=ci(wr(Vr(n.repositoryRoot,n.ref,r),r).verifier,n.projectRoot);if(i.length>0)throw Error(`Recipe ${e} verification failed:\n${i.map(e=>`- ${e}`).join(`
6
+ `)}`);return{name:e,ref:n.ref}}function oi(e){console.log(`Verified Coreframe recipe ${e.name} from ${e.ref}.`)}function si(e,t){for(let n of e){let e=`recipes/${n}/recipe.yaml`,r=ci(wr(Vr(t.repositoryRoot,t.ref,e),e).verifier,t.projectRoot);if(r.length>0)throw Error(`Recipe ${n} is required but is not fully applied:\n${r.map(e=>`- ${e}`).join(`
7
+ `)}\nApply and verify ${n} before continuing.`)}}function ci(e,t){if(!e)throw Error(`Required recipe does not declare a verifier.`);if(e===`tauri`)return ri(t);if(e===`flutter`)return Qr(t);throw Error(`Unknown recipe verifier ${JSON.stringify(e)}.`)}function li({cwd:e=process.cwd(),fetch:t=!0,name:n,remote:r=`template`,target:i}){Tr(n);let a=Br({cwd:e,fetch:t,remote:r,target:i}),{projectRoot:o,ref:s,repositoryRoot:c}=a,l=`recipes/${n}`,u=`${l}/recipe.yaml`,d=wr(Vr(c,s,u),u);si(d.requires,a);let f=Vr(c,s,`${l}/RECIPE.md`),p=Ur(c,s,`${l}/files`),m=Ur(c,s,`${l}/patches`),h=Ur(c,s,`${l}/.agents`),g=new Map,_=new Map,v=[],y=[],b=[],x=[],S=[],C=[];for(let e of p){let t=e.slice(`${l}/files/`.length);if(gi(t,`Recipe file ${e}`),t.startsWith(`.agents/`))throw Error(`Recipe file ${e} must be stored in the recipe's .agents directory.`);g.set(t,Hr(c,s,e)),_.set(t,e)}for(let e of h){let t=e.slice(`${l}/`.length);if(pi(t,`Recipe asset ${e}`),g.has(t))throw Error(`Recipe declares ${t} as both a file and an agent asset.`);g.set(t,Hr(c,s,e)),_.set(t,e)}for(let e of m){let t=_i(e,l);if(g.has(t))throw Error(`Recipe declares ${t} as both a file and a patch.`);let n=Hr(c,s,e);vi(n.toString(`utf8`),t,e),hi(o,t),yi(o,n,!1)?(v.push({contents:n,destinationPath:t}),x.push(t)):yi(o,n,!0)?S.push(t):b.push({destination:t,source:e})}let w=new Map;for(let[e,t]of g){let r=Si(hi(o,e));if(r===void 0)w.set(e,t),y.push(e);else if(r.equals(t))S.push(e);else if(e.startsWith(`.agents/`))throw Error(`Recipe ${n} cannot replace modified ${e}. Reconcile that agent asset manually.`);else b.push({destination:e,source:_.get(e)})}let T=new Map;for(let e of d.routes){if(pi(e.router,`Recipe route router`),mi(e.path,`Recipe route path`),g.has(e.router))throw Error(`Recipe cannot replace its destination router ${e.router}.`);if(!g.has(e.path)&&!J(hi(o,e.path)))throw Error(`Recipe route target ${e.path} does not exist.`);let t=T.get(e.router)??di(Ci(hi(o,e.router),e.router),e.router);T.set(e.router,t);let r=t.routes.find(t=>t.path===e.path);if(r){if(r.when!==e.when)throw Error(`Recipe ${n} route ${e.path} conflicts with the existing trigger in ${e.router}.`);continue}t.routes.push({path:e.path,when:e.when})}for(let[e,t]of T){t.routes.sort((e,t)=>e.path<t.path?-1:+(e.path>t.path));let n=Ci(hi(o,e),e),r=Ye(t,{lineWidth:0});r===n?S.push(e):(w.set(e,r),C.push(e))}for(let{destinationPath:e}of v)if(w.has(e))throw Error(`Recipe cannot both write and patch ${e}.`);for(let[e,t]of w){let n=hi(o,e);He(I(n),{recursive:!0}),qe(n,t)}return v.length>0&&bi(o,v.map(({contents:e})=>e)),{created:y.sort(),instructions:f,mergeRequired:b.sort((e,t)=>e.destination.localeCompare(t.destination)),name:n,patched:x.sort(),ref:s,unchanged:[...new Set(S)].sort(),updated:C.sort()}}function ui(e){console.log(`Prepared Coreframe recipe ${e.name} from ${e.ref}.`);for(let t of e.created)console.log(`created: ${t}`);for(let t of e.updated)console.log(`updated: ${t}`);for(let t of e.patched)console.log(`patched: ${t}`);for(let t of e.mergeRequired)console.log(`merge-required: ${t.destination} (source: ${e.ref}:${t.source})`);for(let t of e.unchanged)console.log(`unchanged: ${t}`);console.log(`\nContinue by following ${e.ref}:recipes/${e.name}/RECIPE.md:\n`),console.log(e.instructions.trimEnd())}function di(e,t){let n=fi(e,t);if(!wi(n)||!Ti(n,[`routes`,`rules`])||!Array.isArray(n.rules)||!n.rules.every(Ei)||!Array.isArray(n.routes))throw Error(`${t} must contain only string rules and a routes array.`);let r=n.routes.map((e,n)=>{if(!wi(e)||!Ti(e,[`path`,`when`])||!Ei(e.path)||!Ei(e.when))throw Error(`${t} route ${n+1} must contain path and when strings.`);return{path:e.path,when:e.when}}),i=r.map(e=>e.path);if(new Set(i).size!==i.length)throw Error(`${t} contains duplicate route paths.`);return{rules:n.rules,routes:r}}function fi(e,t){try{return Je(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function pi(e,t){if(!e.startsWith(`.agents/`))throw Error(`${t} must be a normalized project-relative path beneath .agents/.`);gi(e,t)}function mi(e,t){if(gi(e,t),!/(?:^|\/)\.agents\/rules\/.+\.md$/u.test(e))throw Error(`${t} must point to a Markdown rule beneath an .agents/rules directory.`)}function hi(e,t){gi(t,`Recipe destination`);let n=L(e,t),r=e;for(let e of t.split(`/`))if(r=L(r,e),J(r)&&Ve(r).isSymbolicLink())throw Error(`Recipe destination ${t} crosses symbolic link ${r}.`);return n}function gi(e,t){if(e.length===0||le(e)||e===`..`||e.startsWith(`../`)||e.includes(`\\`)||ue.normalize(e)!==e)throw Error(`${t} must be a normalized project-relative path.`)}function _i(e,t){let n=e.slice(`${t}/patches/`.length);if(!n.endsWith(`.patch`))throw Error(`Recipe patch ${e} must use a .patch suffix.`);let r=n.slice(0,-6);return gi(r,`Recipe patch ${e}`),r}function vi(e,t,n){let r=e.match(/^diff --git .+$/gmu)??[],i=e.match(/^--- .+$/gmu)??[],a=e.match(/^\+\+\+ .+$/gmu)??[];if(r.length!==1||r[0]!==`diff --git a/${t} b/${t}`||i.length!==1||a.length!==1||i[0]!==`--- a/${t}`||a[0]!==`+++ b/${t}`||/^(?:deleted file mode |GIT binary patch$|new file mode |rename from |rename to )/mu.test(e))throw Error(`Recipe patch ${n} must modify only ${t}.`)}function yi(e,t,n){let r=[`apply`,`--check`,`--whitespace=nowarn`];return n&&r.push(`--reverse`),r.push(`-`),q(`git`,r,{cwd:e,input:t}).status===0}function bi(e,t){let n=q(`git`,[`apply`,`--whitespace=nowarn`,`-`],{cwd:e,input:Buffer.concat(t.flatMap(e=>[e,Buffer.from(e.at(-1)===10?``:`
8
+ `)])),encoding:`utf8`});if(n.status!==0){let e=n.stderr.trim()||n.stdout.trim();throw Error(`Could not apply recipe patches.${e?`\n${e}`:``}`)}}function xi(e){return Si(e)?.toString(`utf8`)}function Si(e){try{return Y(e)}catch(e){if(Di(e)&&e.code===`ENOENT`)return;throw e}}function Ci(e,t){let n=xi(e);if(n===void 0)throw Error(`Required file ${t} does not exist.`);return n}function wi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ti(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function Ei(e){return typeof e==`string`&&e.length>0}function Di(e){return e instanceof Error&&`code`in e}function Oi(e={}){let{ref:t,repositoryRoot:n}=Br(e),r=Ur(n,t,`recipes`).filter(e=>/^recipes\/[^/]+\/recipe\.yaml$/u.test(e)).map(e=>{let r=e.split(`/`)[1];return Tr(r),{description:wr(Vr(n,t,e),e).description,name:r}});return r.sort((e,t)=>e.name.localeCompare(t.name)),{recipes:r,ref:t}}function ki(e){console.log(`Coreframe recipes at ${e.ref}:`);for(let t of e.recipes)console.log(`${t.name} — ${t.description}`)}const Ai=`.agents/skills/coreframe-upgrade/SKILL.md`;function ji(e,t={}){return q(`git`,e,t)}function Mi(e){return e.stderr.toString(`utf8`).trim()||e.stdout.toString(`utf8`).trim()}function Ni(e,t){let n=zr(e,t),r=ji([`show`,n],{encoding:`utf8`});if(r.status!==0){let e=Mi(r);throw Error(`Could not read ${n}.${e?` ${e}`:``}`)}return r.stdout.toString()}function Pi(){let e=ji([`rev-parse`,`--show-toplevel`],{encoding:`utf8`});if(e.status!==0){let t=Mi(e);throw Error(`Could not find git repository root.${t?` ${t}`:``}`)}return e.stdout.toString().trim()}function Fi(e,t){let n=Ue(L(Ne(),`coreframe-upgrade-skill-`)),r=L(n,`SKILL.md`);try{qe(r,t);let n=Mi(ji([`--no-pager`,`diff`,`--no-index`,`--color=never`,`--`,e,r]));n&&console.log(n)}finally{Ge(n,{force:!0,recursive:!0})}}function Ii({apply:e,target:t}){let n=L(Pi(),Ai),r=Lr(t);if(!J(n))throw Error(`Local ${Ai} does not exist.`);let i=Y(n,`utf8`),a=Ni(t,Ai);return i===a?(console.log(`Coreframe upgrade skill matches ${r}:template/${Ai}.`),0):e?(qe(n,a),console.error(`Updated ${Ai} from ${r}:template. Reread it before continuing the upgrade.`),20):(console.error(`Coreframe upgrade skill differs from ${r}:template/${Ai}.`),console.error(`Run again with --apply to update it, then reread ${Ai} before continuing.`),Fi(n,a),20)}const Li=[{matches:e=>e===`drizzle`||e.startsWith(`drizzle/`),reason:`project-owned migration history`},{matches:e=>e===`drizzle-hold`||e.startsWith(`drizzle-hold/`),reason:`project-owned migration history`},{matches:e=>e===`src/web/routes.ts`||e.startsWith(`src/web/app/routes/`),reason:`downstream-owned demonstration routes`},{matches:e=>e===`pnpm-lock.yaml`||e===`src-tauri/Cargo.lock`,reason:`downstream-owned dependency lockfile`}],Ri=new Set([`100644`,`100755`,`120000`]);function zi(e,t={}){return q(`git`,e,t)}function Bi(e){let t=zi(e,{encoding:`utf8`});if(t.status!==0){let n=t.stderr.toString().trim()||t.stdout.toString().trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout.toString()}function Vi(e){let t=zi(e);if(t.status!==0){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout}function Hi(){return Bi([`rev-parse`,`--show-toplevel`]).trim()}function Ui(e){let t=L(e,`package.json`);if(!J(t))throw Error(`Missing --base <git-ref>, and package.json does not exist.`);let n=JSON.parse(Y(t,`utf8`)).engines?.coreframe;if(typeof n!=`string`||n.length===0)throw Error(`Missing --base <git-ref>, and package.json engines.coreframe is not set.`);return n}function Wi(e){let t=[],n=0;for(let r=0;r<e.length;r+=1)e[r]===0&&(t.push(e.subarray(n,r).toString(`utf8`)),n=r+1);return t.filter(e=>e.length>0)}function Gi(e,t){let n=Wi(Vi([`diff`,`--name-status`,`-z`,`--no-renames`,Rr(e),Rr(t),`--`])),r=[];for(let e=0;e<n.length;e+=2){let t=n[e],i=n[e+1];if(!t||!i)throw Error(`Could not parse git diff --name-status output.`);r.push({path:i,status:t})}return r}function Ki(e,t){let n=Vi([`ls-tree`,`-z`,Rr(e),`--`,t]);if(n.length===0)return null;let r=Wi(n)[0],i=r.indexOf(` `);if(i===-1)throw Error(`Could not parse git ls-tree output for ${e}:${t}.`);let[a,o,s]=r.slice(0,i).split(` `);if(!a||!o||!s)throw Error(`Could not parse git ls-tree metadata for ${e}:${t}.`);return{mode:a,object:s,path:t,type:o}}function qi(e){return Vi([`cat-file`,`blob`,e.object])}function Ji(e,t){let n=R(e,t),r=e.endsWith(de)?e:`${e}${de}`;if(n!==e&&!n.startsWith(r))throw Error(`Refusing to access path outside repository: ${t}`);return n}function Yi(e){try{return Ve(e),!0}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return!1;throw e}}function Xi(e){return(e.mode&73)!=0}function Zi(e){return e===null||e.type===`blob`&&Ri.has(e.mode)}function Qi(e){return Li.find(t=>t.matches(e))?.reason}function $i(e,t,n){let r=Ji(e,t);if(n===null)return{matches:!Yi(r)};if(!Zi(n))return{matches:!1,reason:`unsupported template entry mode ${n.mode} ${n.type}`};let i;try{i=Ve(r)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{matches:!1,reason:`path is missing from worktree`};throw e}let a=qi(n);return n.mode===`120000`?i.isSymbolicLink()?{matches:Buffer.from(We(r),`utf8`).equals(a)}:{matches:!1,reason:`worktree path is not a symlink`}:i.isFile()?(n.mode===`100755`?Xi(i):!Xi(i))?{matches:Y(r).equals(a)}:{matches:!1,reason:`worktree executable bit differs from template`}:{matches:!1,reason:`worktree path is not a regular file`}}function ea(e){Yi(e)&&Ge(e,{force:!0,recursive:!1})}function ta(e,t,n){let r=Ji(e,t);if(n===null){ea(r);return}if(He(I(r),{recursive:!0}),n.mode===`120000`){ea(r),Ke(qi(n).toString(`utf8`),r);return}let i=Yi(r)?Ve(r):null;i&&!i.isFile()&&ea(r),qe(r,qi(n)),Be(r,n.mode===`100755`?493:420)}function na(e,t){return e===null&&t!==null?`add`:e!==null&&t===null?`delete`:`update`}function ra(e,t){if(t.length!==0){console.log(`${e}:`);for(let e of t){let t=e.reason?` (${e.reason})`:``;console.log(` ${e.action}: ${e.path}${t}`)}console.log(``)}}function ia(e){let t=Hi(),n=Lr(e.base??Ui(t)),r=Lr(e.target),i=Gi(n,r),a=[],o=[],s=[],c=[];for(let e of i){let i=Qi(e.path);if(i){o.push({action:`ignored`,path:e.path,reason:i});continue}let l=Ki(n,e.path),u=Ki(r,e.path),d=na(l,u);if(!Zi(l)||!Zi(u)){s.push({action:d,path:e.path,reason:`unsupported template entry type`});continue}if($i(t,e.path,u).matches){c.push({action:`unchanged`,path:e.path});continue}let f=$i(t,e.path,l);if(!f.matches){s.push({action:d,path:e.path,reason:f.reason??`downstream differs from base template`});continue}a.push({action:d,path:e.path,targetEntry:u})}if(e.apply)for(let e of a)ta(t,e.path,e.targetEntry??null);console.log(`Coreframe template fast-forward: ${n} -> ${r}`),console.log(``),ra(e.apply?`Applied clean template updates`:`Would apply clean template updates`,a),ra(`Ignored downstream-owned paths`,o),ra(`Skipped for agent review`,s),c.length>0&&console.log(`${c.length} changed template path(s) already matched the target state.`),i.length===0&&console.log(`No template file changes found in the requested range.`),!e.apply&&a.length>0&&(console.log(``),console.log(`Run with --apply to write the ${a.length} clean update(s).`))}const aa=[`dependencies`,`devDependencies`];function oa(e){let t=q(`git`,e,{encoding:`utf8`});if(t.status!==0){let n=t.stderr.trim()||t.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout}function sa(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}: ${e instanceof Error?e.message:e}`)}}function ca(e,t){let n=`${Lr(e)}:${t}`;return sa(oa([`show`,n]),n)}function la(e){return e.startsWith(`@coreframe/`)}function ua(e){return e.startsWith(`file:`)||e.startsWith(`link:`)||e.startsWith(`workspace:`)}function da(e){return e.startsWith(`file:`)||e.startsWith(`link:`)}function fa(e,t){let n=e.indexOf(`:`),r=e.slice(n+1),i=ue.normalize(ue.join(`template`,r,`package.json`));if(r.length===0||ue.isAbsolute(r)||i===`..`||i.startsWith(`../`))throw Error(`Invalid local template dependency for ${t}: ${e}`);return i}function pa(e){let t=ca(e,`template/package.json`),n=[],r=new Set;for(let i of aa)for(let[a,o]of Object.entries(t[i]??{})){if(!la(a)||!da(o))continue;if(r.has(a))throw Error(`Target template declares ${a} more than once.`);let t=fa(o,a),s=ca(e,t);if(s.name!==a||typeof s.version!=`string`)throw Error(`${Lr(e)}:${t} must declare ${a} with a version.`);n.push({group:i,name:a,spec:`^${s.version}`}),r.add(a)}return n}function ma(e,t){for(let n of aa){let r=e[n]?.[t];if(r)return{group:n,spec:r}}}function ha(e,t,n){let r=t.match(/\n([\t ]+)"/u)?.[1]??` `,i=t.endsWith(`
9
9
  `)?`
10
- `:``;Ke(e,`${JSON.stringify(n,null,r)}${i}`)}function ma(e,t){if(t.length!==0){console.log(`${e}:`);for(let e of t)console.log(` ${e}`);console.log(``)}}function ha(e){let t=L(ia([`rev-parse`,`--show-toplevel`]).trim(),`package.json`),n=J(t,`utf8`),r=aa(n,t),i=Fr(e.target),a=da(i),o=new Set(a.map(({name:e})=>e)),s=[],c=[],l=[],u=0;for(let e of a){let t=fa(r,e.name);if(!t){c.push(`missing: ${e.name} ${e.spec} (${e.group})`);continue}if(ca(t.spec)){l.push(`linked: ${e.name} ${t.spec}`);continue}if(t.spec===e.spec){u+=1;continue}s.push({...e,currentGroup:t.group,currentSpec:t.spec})}let d=ra.flatMap(e=>Object.entries(r[e]??{}).filter(([e])=>sa(e)&&!o.has(e)).map(([t,n])=>`review: ${t} ${n} (${e})`));if(e.apply&&s.length>0){for(let e of s)r[e.currentGroup][e.name]=e.spec;pa(t,n,r)}console.log(`Coreframe package sync: ${i}`),console.log(``),ma(e.apply?`Updated Coreframe packages`:`Would update Coreframe packages`,s.map(({currentSpec:e,name:t,spec:n})=>`update: ${t} ${e} -> ${n}`)),ma(`Missing target Coreframe packages`,c),ma(`Locally linked Coreframe packages`,l),ma(`Downstream-only Coreframe packages`,d),u>0&&console.log(`${u} Coreframe package(s) already match the target versions.`),s.length===0?console.log(`No Coreframe package version updates found.`):e.apply||(console.log(``),console.log(`Run with --apply to write the ${s.length} package update(s).`))}const ga={...f,displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return Cr(e)}},_a=p({name:`upgrade`,cmds:{"ensure-template-remote":n({name:`ensure-template-remote`,args:{remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:i({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>Nr({fetch:!e,remote:t})}),"check-skill-current":n({name:`check-skill-current`,args:{target:c({long:`target`,type:f,description:`Target Coreframe template git ref.`}),apply:i({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=Pi({apply:e,target:t})}}),"fast-forward-template-files":n({name:`fast-forward-template-files`,args:{target:c({long:`target`,type:f,description:`Target Coreframe template git ref.`}),base:c({long:`base`,type:l(f),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:i({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>na({apply:e,base:t,target:n})}),"sync-coreframe-packages":n({name:`sync-coreframe-packages`,args:{target:c({long:`target`,type:f,description:`Target Coreframe template git ref.`}),apply:i({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>ha({apply:e,target:t})})}}),va=p({name:`recipes`,cmds:{apply:n({name:`apply`,args:{recipe:u({type:ga,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:c({long:`target`,type:l(f),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:i({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>ci(si({fetch:!e,name:t,remote:n,target:r}))}),list:n({name:`list`,args:{target:c({long:`target`,type:l(f),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:i({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>Di(Ei({fetch:!e,remote:t,target:n}))}),verify:n({name:`verify`,args:{recipe:u({type:ga,displayName:`recipe`,description:`Recipe adoption to verify.`}),target:c({long:`target`,type:l(f),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:i({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>ii(ri({fetch:!e,name:t,remote:n,target:r}))})}}),ya=p({name:`db`,cmds:{ensure:n({name:`ensure`,args:{},handler:y}),generate:n({name:`generate`,args:{args:d({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>te(`generate`,e)}),migrate:n({name:`migrate`,args:{args:d({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>te(`migrate`,e)}),"migrate-held":n({name:`migrate-held`,args:{confirm:c({long:`confirm`,type:l(s([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>w({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":n({name:`migrate-local`,args:{},handler:T}),"migrations-check":n({name:`migrations-check`,args:{},handler:h}),reset:n({name:`reset`,args:{},handler:ee}),seed:n({name:`seed`,args:{},handler:()=>O()}),"schema-check":n({name:`schema-check`,args:{seed:i({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>g({seed:e})}),setup:n({name:`setup`,args:{},handler:()=>ne()}),studio:n({name:`studio`,args:{args:d({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>te(`studio`,e)})}}),ba=`package.json`;async function xa(e=process.argv.slice(2),t=process.env){let n=Sa(e);Aa(n);let{packageJson:r,source:i}=await ut(ba),a=await Ie(),o=mt(a.deploy??{},n.environment,t);Fa(t,[`POSTHOG_API_KEY`,`POSTHOG_PROJECT_ID`]);let s=await ja(o,n.environment,()=>$e({env:t})),c=gt({args:n,config:n.environment===`production`?o.tauriRelease:{},env:t});Pa(n.environment,c.enabled),await Ct(c);let l=await dt({environment:n.environment}),u=l.values.DASHBOARD_PASSWORD??await Ia(t,n.environment);wt(await et({environment:n.environment}),n.environment,{availableNames:[...Object.keys(l.values),...u?[`DASHBOARD_PASSWORD`]:[]]});let d=await at({environment:n.environment}),f=await ka();await Kn({env:t,revision:f});let p=f.slice(0,12),m=ht(n.environment,r.version,p),h=pt(r.name,m),g={...za(t,n.environment,h,r.name,m),COREFRAME_I18N_RELEASE_REVISION:f},_=n.environment===`production`,y=!1,b={files:[]};z.intro(`Deploy ${h} to ${n.environment}`);let x=Object.keys(l.values).sort();x.length>0&&z.note(x.join(`
11
- `),`Pending Worker secret updates`),d.provisioned&&z.log.info(`Provisioning Coreframe-managed access-token signing material.`),await Na(n);let S=await Ea(await v({config:a.database,env:t})),w=await D(S);if(w.length>0)throw Error(`Pending deploy migrations contain unsafe SQL. Move unsafe statements to held migrations.\n${C(w)}`);let T=await Oa(n,S);try{_&&(await Et(ba,r,m),b=await Dt(c,m)),z.log.step(`Running pre-deploy build`),await R(`pnpm`,[`build`],{env:Ba(g),stdio:`inherit`});let e=c.enabled?await ot({env:Ba(g),plan:c,releaseName:h,version:m}):void 0;z.log.step(`Running release build and uploading PostHog source maps`),y=!0,await R(`pnpm`,[`build`],{env:g,stdio:`inherit`}),T&&(z.log.step(`Running deploy-safe database migrations`),await R(`pnpm`,[`db`,`migrate`],{env:g,stdio:`inherit`})),z.log.step(`Deploying Worker and static assets to Cloudflare`);let t={...u?{DASHBOARD_PASSWORD:u}:{},...d.value?{[Ye]:d.value}:{},...l.values},i=Object.keys(t).length>0?await La(t):void 0,f=await tt({coreframeConfig:a,environment:n.environment,contributions:{generatedValues:{DEPLOY_ENV:n.environment,POSTHOG_RELEASE:h}}});try{await R(`pnpm`,[`exec`,`wrangler`,`deploy`,`--config`,f.path,`--env`,n.environment,`--strict`,`--keep-vars`,`--tag`,h,`--message`,`Deploy ${h}`,...i?[`--secrets-file`,i.path]:[]],{env:g,stdio:`inherit`}),await Xe(l),await Tt({environment:n.environment})}finally{await f.dispose(),await i?.dispose()}let p={environment:n.environment,releaseName:h,url:s,version:m};o.afterWorkerDeploy&&(z.log.step(`Running required after-Worker deploy hook`),await yt(o,p)),n.skipPostDeployChecks||(z.log.step(`Running post-deploy checks`),await bt(o,p)),e&&(z.log.step(`Uploading Tauri release artifacts to Backblaze B2`),await St(c,e)),z.outro(`Deployed ${h} to ${n.environment}`)}catch(e){throw!y&&_&&(await U(ba,i),await _t(b)),e}}function Sa(e){return{environment:Ca(e[0]),runMigrations:e.includes(`--run-migrations`),skipMigrations:e.includes(`--skip-migrations`),skipPostDeployChecks:e.includes(`--skip-post-deploy-checks`),tauriLocalPlatforms:wa(e,`--tauri-local-platform`).map(e=>it(e)),tauriWorkflowName:Ta(e,`--tauri-workflow-name`),tauriWorkflowPlatforms:wa(e,`--tauri-workflow-platform`).map(e=>it(e)),tauriWorkflowRef:Ta(e,`--tauri-workflow-ref`),yes:e.includes(`--yes`)}}function Ca(e){if(e&&Ze.includes(e))return e;throw Error(`Deploy environment must be one of: ${Ze.join(`, `)}.`)}function wa(e,t){let n=[];for(let r=0;r<e.length;r+=1){let i=e[r];if(i===t){let i=e[r+1];if(!i||i.startsWith(`--`))throw Error(`${t} requires a value.`);n.push(...i.split(`,`).filter(Boolean)),r+=1;continue}i.startsWith(`${t}=`)&&n.push(...i.slice(t.length+1).split(`,`).filter(Boolean))}return n}function Ta(e,t){let n=wa(e,t);if(n.length>1)throw Error(`${t} can only be provided once.`);return n[0]}async function Ea(e){try{return await Da(e)}finally{await e.close?.()}}async function Da(e){return b(await _(),await E(e))}async function Oa(e,t){if(t.length===0)return z.log.info(`No pending deploy migrations.`),!1;if(z.note(S(t),`Pending deploy migrations`),e.runMigrations)return!0;if(e.skipMigrations)return!1;if(!process.stdout.isTTY)throw Error(`Pending migrations require --run-migrations or --skip-migrations in noninteractive deploys.`);let n=await z.confirm({initialValue:!0,message:`Run these deploy-safe database migrations before Cloudflare deploy?`});if(z.isCancel(n))throw z.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`);return n}async function ka(){let{stdout:e}=await R(`git`,[`status`,`--porcelain`],{stdin:`ignore`});if(e.trim().length>0)throw Error(`Deploy requires a clean git tree.`);let{stdout:t}=await R(`git`,[`rev-parse`,`HEAD`],{stdin:`ignore`});return t.trim()}function Aa(e){if(e.runMigrations&&e.skipMigrations)throw Error(`Use only one of --run-migrations or --skip-migrations.`)}async function ja(e,t,n=$e){return e.url?Ma(e.url,t):t===`staging`&&e.stagingHostname?Ma(await n(),t):Ma(void 0,t)}function Ma(e,t){if(!e)throw Error(`Missing ${t} deploy URL. Set DEPLOY_URL or deploy.environments.${t}.url in coreframe.config.ts.`);let n;try{n=new URL(e)}catch{throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`);return n.toString()}async function Na(e){if(e.environment!==`production`||e.yes)return;if(!process.stdout.isTTY)throw Error(`Production deploys require --yes in noninteractive environments.`);let t=await z.confirm({initialValue:!1,message:`Deploy to production?`});if(z.isCancel(t)||!t)throw z.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`)}function Pa(e,t){if(e===`staging`&&t)throw Error(`Tauri releases can only be published from production deploys.`)}function Fa(e,t){let n=t.filter(t=>!e[t]);if(n.length>0)throw Error(`Missing required deploy environment variables: ${n.join(`, `)}`);return Object.fromEntries(t.map(t=>[t,e[t]]))}async function Ia(e,t){let n=e.DASHBOARD_PASSWORD?.trim();if(n)return n;let r;try{r=Lt(await V(`.env`,`utf8`))}catch(e){throw Ra(e)&&e.code===`ENOENT`?Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`):e}let i=r.DASHBOARD_PASSWORD?.trim();if(!i)throw Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`);return i}async function La(e){let t=await we(I(Me(),`coreframe-deploy-secrets-`)),n=I(t,`secrets.json`);return await U(n,JSON.stringify(e),{mode:384}),{path:n,dispose:()=>H(t,{force:!0,recursive:!0})}}function Ra(e){return e instanceof Error&&`code`in e}function za(e,t,n,r,i){return{...e,CLOUDFLARE_ENV:t,DEPLOY_ENV:t,POSTHOG_RELEASE:n,POSTHOG_RELEASE_NAME:e.POSTHOG_RELEASE_NAME??r,POSTHOG_RELEASE_VERSION:e.POSTHOG_RELEASE_VERSION??i}}function Ba(e){let{POSTHOG_API_KEY:t,POSTHOG_PROJECT_ID:n,...r}=e;return r}const $={access:ye,chmod:be,mkdir:B,mkdtemp:we,readFile:V,readFileSync:J,rm:H,writeFile:U},Va={getAvailablePort:Ua},Ha={homedir:Ae,kill:G.kill,networkInterfaces:je,tmpdir:Me};async function Ua(){let e=Wt();try{await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)});let t=e.address();if(!t||typeof t==`string`)throw Error(`Could not allocate an available TCP port.`);return t.port}finally{e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}}async function Wa(){let e=await Ka();return typeof e.mobileDevHost==`string`?{mobileDevHost:e.mobileDevHost}:{}}async function Ga(e){let t=await Ka(),n=qa();await $.mkdir(P.dirname(n),{recursive:!0}),await $.writeFile(n,`${JSON.stringify({...t,...e},void 0,2)}\n`)}async function Ka(){try{let e=await $.readFile(qa(),`utf8`),t=JSON.parse(e);return Ja(t)?t:{}}catch{return{}}}function qa(){return P.join(Ha.homedir(),`.coreframe`,`preferences.json`)}function Ja(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Ya({env:e=G.env,interactive:t=G.stdin.isTTY===!0,platform:n,target:r}){let i=await eo(n,e).catch(()=>[]),a=r?vo(i,r):void 0;if(a)return a;if(!r&&i.length>0)return $a(i,n,t);let o=r?vo(await no(e).catch(()=>[]),r):void 0;if(o&&o.platform===n)return ro(o,n,e,t);let s=await to(n,e),c=r?vo(s,r):void 0;if(c)return c;if(!r&&s.length>0)return $a(s,n,t);let l=n===`ios`?`iOS`:`Android`;throw Error(r?`Could not find a ${l} device matching "${r}".`:`No connected ${l} devices or available ${l} ${n===`ios`?`simulators`:`emulators`} were detected.`)}async function Xa(e){let{device:t,host:n,interactive:r=G.stdin.isTTY===!0}=e;if(!t.physical&&n===void 0)return;if(typeof n==`string`&&n!==`0.0.0.0`&&n!==`::`)return n;let i=bo();if(i.length===0)throw Error(`No external IP address was detected. Pass one explicitly with --host.`);let a=await Za();if(a&&i.includes(a))return a;if(i.length===1)return await Qa(i[0]),i[0];if(!r)throw Error(`Multiple external IP addresses were detected (${i.join(`, `)}). Pass one explicitly with --host.`);let o=await z.select({message:`Which IP address should the mobile device use to reach the development server?`,options:i.map(e=>({label:e,value:e}))});if(z.isCancel(o))throw Error(`Mobile development IP selection was cancelled.`);return await Qa(o),o}async function Za(){return(await Wa()).mobileDevHost}async function Qa(e){try{await Ga({mobileDevHost:e})}catch(e){z.log.warn(`Could not remember the mobile development IP address: ${e instanceof Error?e.message:String(e)}`)}}async function $a(e,t,n){if(e.length===1)return e[0];if(!n)throw Error(`Multiple ${t===`ios`?`iOS`:`Android`} devices were detected. Pass a device name explicitly.`);let r=await z.select({message:`Which ${t===`ios`?`iOS`:`Android`} device should Coreframe use?`,options:e.map(e=>({label:e.label,value:e,hint:e.id}))});if(z.isCancel(r))throw Error(`Mobile development device selection was cancelled.`);return r}async function eo(e,t){return e===`android`?ao(t):so(t)}async function to(e,t){return e===`android`?oo(t):co(t)}async function no(e){let{stdout:t}=await R(`flutter`,[`emulators`],{env:e});return t.split(/\r?\n/).flatMap(e=>{let[t,n,,r]=e.split(/\s*•\s*/).map(e=>e.trim());return t&&n&&(r===`android`||r===`ios`)?[{id:t,label:n,name:n,physical:!1,platform:r}]:[]})}async function ro(e,t,n,r){let i=await io(t,n).catch(()=>[]),{stdout:a}=await R(`flutter`,[`emulators`,`--launch`,e.id],{env:n});if(/No emulator found|More than one emulator matches/i.test(a))throw Error(a.trim());let o=Date.now()+3e4;do{let a=await io(t,n).catch(()=>[]),o=vo(a,e.id);if(o)return o;let s=a.filter(e=>!i.some(t=>t.id===e.id));if(s.length>0)return $a(s,t,r);if(a.length===1)return a[0];await Gt(250)}while(Date.now()<o);let s=t===`ios`?`iOS simulator`:`Android emulator`;throw Error(`Flutter launched "${e.id}", but no ${s} became available.`)}async function io(e,t){return e===`ios`?co(t,`booted`):(await ao(t)).filter(e=>!e.physical)}async function ao(e){let t=await uo(e,`platform-tools`,G.platform===`win32`?`adb.exe`:`adb`),{stdout:n}=await R(t,[`devices`],{env:e}),r=n.split(/\r?\n/).map(e=>e.match(/^(\S+)\s+device(?:\s|$)/)?.[1]).filter(e=>e!==void 0);return(await Promise.all(r.map(async n=>{let r=await po(t,e,n,`ro.product.model`),i=n.startsWith(`emulator-`),a=i?await ho(t,e,n,r):await go(t,e,n,r);return{id:n,label:a===r?a:`${a} (${r})`,name:a,physical:!i}}))).sort(xo)}async function oo(e){let{stdout:t}=await R(await uo(e,`emulator`,G.platform===`win32`?`emulator.exe`:`emulator`),[`-list-avds`],{env:e});return t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0&&!/^(INFO|WARNING|ERROR)\s+\|/.test(e)).map(e=>({id:e,label:e,name:e,physical:!1}))}async function so(e){let t=await $.mkdtemp(P.join(Ha.tmpdir(),`coreframe-ios-devices-`)),n=P.join(t,`devices.json`);try{return await $.writeFile(n,``),await R(`xcrun`,[`devicectl`,`list`,`devices`,`--json-output`,n],{env:e}),(JSON.parse(await $.readFile(n,`utf8`)).result?.devices??[]).filter(lo).map(e=>({id:e.hardwareProperties.udid,label:`${e.deviceProperties.name} (${e.hardwareProperties.productType})`,name:e.deviceProperties.name,physical:!0})).sort(xo)}finally{await $.rm(t,{force:!0,recursive:!0})}}async function co(e,t=`available`){let{stdout:n}=await R(`xcrun`,[`simctl`,`list`,`--json`,`devices`,t],{env:e}),r=JSON.parse(n);return Object.entries(r.devices??{}).filter(([e])=>e.includes(`iOS-`)).flatMap(([,e])=>e).flatMap(e=>e.name&&e.udid?[{id:e.udid,label:e.name,name:e.name,physical:!1}]:[]).sort(xo)}function lo(e){return e.connectionProperties?.tunnelState!==`unavailable`&&typeof e.hardwareProperties?.platform==`string`&&(e.hardwareProperties.platform.includes(`iOS`)||e.hardwareProperties.platform.includes(`xrOS`))&&typeof e.deviceProperties?.name==`string`&&typeof e.hardwareProperties.productType==`string`&&typeof e.hardwareProperties.udid==`string`}async function uo(e,t,n){let r=e.ANDROID_HOME??e.ANDROID_SDK_ROOT,i=r?[r]:fo(e);for(let e of i){let r=P.join(e,t,n);try{return await $.access(r),r}catch{}}return n}function fo(e){return G.platform===`darwin`?[P.join(Ha.homedir(),`Library`,`Android`,`sdk`)]:G.platform===`win32`&&e.LOCALAPPDATA?[P.join(e.LOCALAPPDATA,`Android`,`Sdk`)]:[P.join(Ha.homedir(),`Android`,`Sdk`)]}async function po(e,t,n,r){return(await mo(e,t,[`-s`,n,`shell`,`getprop`,r])).trim()}async function mo(e,t,n){return(await R(e,n,{env:t,timeout:3e3})).stdout}async function ho(e,t,n,r){return mo(e,t,[`-s`,n,`emu`,`avd`,`name`]).then(e=>e.split(/\r?\n/)[0]?.trim()||r).catch(()=>r)}async function go(e,t,n,r){return mo(e,t,[`-s`,n,`shell`,`dumpsys`,`bluetooth_manager`]).then(e=>_o(e)||r).catch(()=>r)}function _o(e){return e.match(/\bname: (.+)/)?.[1]?.trim()}function vo(e,t){let n=e.map(e=>({device:e,score:Math.max(yo(t,e.name),yo(t,e.id))})).sort((e,t)=>t.score-e.score)[0];return n&&n.score>0?n.device:void 0}function yo(e,t){let n=e.toLowerCase(),r=t.toLowerCase();if(r===n)return 1e4;let i=r.indexOf(n);if(i>=0)return 5e3-i;let a=0,o=0;for(let e of n){let t=r.indexOf(e,o);if(t<0)return 0;a+=t===o?2:1,o=t+1}return a}function bo(){return[...new Set(Object.values(Ha.networkInterfaces()).flatMap(e=>e??[]).filter(e=>!e.internal&&e.family===`IPv4`).map(e=>e.address))].sort()}function xo(e,t){return e.label.localeCompare(t.label)}function So({host:e=`127.0.0.1`,port:t,start:n}){let r,i=!1,a=!1,o=!1,s,c,l,u,d,f=new Set,p=new Promise((e,t)=>{u=e,d=t}),m=e=>{a||o||(o=!0,d(e))},h=()=>(s||=Promise.resolve().then(n).catch(e=>{throw m(e),e}),s),g=e=>{f.add(e),e.once(`close`,()=>f.delete(e)),e.pause(),_(e).catch(t=>{m(t),e.destroy()})},_=async e=>{let t=await h();if(a||e.destroyed)return;let n=await Co(t,()=>a);if(a||e.destroyed){n.destroy();return}f.add(n),n.once(`close`,()=>f.delete(n)),n.on(`error`,()=>e.destroy()),n.once(`close`,()=>e.destroy()),e.on(`error`,()=>n.destroy()),e.once(`close`,()=>n.destroy()),e.pipe(n),n.pipe(e)};return{close:async()=>l||(l=(async()=>{a=!0,o||(o=!0,u());for(let e of f)e.destroy();f.clear(),c&&!i&&await Promise.allSettled([c]),!(!r||!i)&&(await new Promise(e=>{r.close(()=>e())}),i=!1)})(),l),fail:m,listen:async()=>c||(r=Wt(g),c=new Promise((n,a)=>{let o=e=>{if(i){m(e);return}a(e)};r.once(`error`,o),r.once(`listening`,()=>{i=!0,r.off(`error`,o),r.on(`error`,m),n()}),r.listen(t,e)}),c),wait:()=>p}}async function Co(e,t){let n=Date.now()+1e4,r;for(;!t();)try{return await wo(e)}catch(e){if(r=e,Date.now()>=n)break;await new Promise(e=>setTimeout(e,50))}throw r instanceof Error?r:Error(`Could not connect to the dashboard.`)}function wo({host:e=`127.0.0.1`,port:t}){return new Promise((n,r)=>{let i=Ut({host:e,port:t}),a=e=>{i.off(`connect`,o),i.destroy(),r(e)},o=()=>{i.off(`error`,a),n(i)};i.once(`error`,a),i.once(`connect`,o)})}const To={command:Vo,isRunning:Mo,stop(e){try{G.kill(e,`SIGTERM`)}catch(e){if(!Fo(e))throw e}},waitForExit:No};async function Eo({confirmStop:e=ko,cwd:t=G.cwd(),interactive:n=G.stdin.isTTY===!0,pid:r=G.pid,platform:i=`web`,processes:a=To}={}){let o=await Wo(t,i),s=o.file,c={pid:r,platform:i,repository:o.repository,token:W()},l=`${JSON.stringify(c)}\n`,u=`${s}.${c.token}.tmp`,d=await Lo({confirmStop:e,file:P.resolve(t,`.coreframe/dev.lock`),interactive:n,owner:c,processes:a});if(d===void 0)return;let f=d;await B(P.dirname(s),{recursive:!0}),await U(u,l,{flag:`wx`,mode:384});try{for(;;){try{return await Ce(u,s),{owner:c,async release(){await jo(s,l)},takeoverApproved:f}}catch(e){if(!Po(e))throw e}let t=await Oo({confirmStop:e,file:s,interactive:n,owner:c,processes:a});if(t===void 0)return;f||=t}}finally{await ke(u).catch(()=>void 0)}}async function Do({cwd:e=G.cwd(),platform:t=`web`}={}){let{file:n}=await Wo(e,t);return(await Ao(n))?.owner}async function Oo({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await Ao(t);if(!a||!Jo(a.owner,r)||!i.isRunning(a.owner.pid))return await jo(t,a?.source),!1;if(!n)throw Error(`Coreframe dev is already running for this project (PID ${a.owner.pid}). Stop it before starting another.`);if(await e(a.owner.pid))return i.stop(a.owner.pid),await i.waitForExit(a.owner.pid),await jo(t,a.source),!0}async function ko(e){let t=await z.confirm({initialValue:!1,message:`Coreframe dev is already running for this project (PID ${e}). Stop it and start here?`});return z.isCancel(t)||!t?(z.cancel(`Keeping the existing Coreframe dev process.`),!1):!0}async function Ao(e){try{let t=await V(e,`utf8`),n=JSON.parse(t);return!Number.isSafeInteger(n.pid)||Number(n.pid)<=0||typeof n.platform!=`string`||n.platform.length===0||typeof n.repository!=`string`||n.repository.length===0||typeof n.token!=`string`||n.token.length===0?void 0:{owner:n,source:t}}catch{return}}async function jo(e,t){let n=await V(e,`utf8`).catch(()=>void 0);(t===void 0||n===t)&&await ke(e).catch(()=>void 0)}function Mo(e){try{return G.kill(e,0),!0}catch(e){return!Fo(e)}}async function No(e){let t=Date.now()+1e4;for(;Mo(e);){if(Date.now()>=t)throw Error(`Coreframe dev process ${e} did not stop within 10 seconds.`);await new Promise(e=>setTimeout(e,50))}}function Po(e){return Io(e)&&e.code===`EEXIST`}function Fo(e){return Io(e)&&e.code===`ESRCH`}function Io(e){return e instanceof Error}async function Lo({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await Ro(t);if(!a||!i.isRunning(a.owner.pid))return await jo(t,a?.source),!1;let o=i.command?.(a.owner.pid);if(!o||!zo(o,r.platform))return!1;if(!n)throw Error(`Coreframe dev is already running for this project (PID ${a.owner.pid}). Stop it before starting another.`);if(await e(a.owner.pid))return i.stop(a.owner.pid),await i.waitForExit(a.owner.pid),await jo(t,a.source),!0}async function Ro(e){try{let t=await V(e,`utf8`),n=JSON.parse(t);return!Number.isSafeInteger(n.pid)||Number(n.pid)<=0||typeof n.token!=`string`||n.token.length===0?void 0:{owner:n,source:t}}catch{return}}function zo(e,t){let n=e.trim().split(/\s+/u),r=n.findIndex(e=>{let t=e.split(/[\\/]/u).at(-1);return t===`coreframe`||t===`coreframe.js`||t===`coreframe.ts`});if(r<0)return!1;let i=n.indexOf(`dev`,r+1);return i<0?!1:Bo(n.slice(i+1))===t}function Bo(e){let t=new Set([`android`,`desktop`,`ios`,`macos`,`web`]),n=new Set([`--debug`,`--host`,`--port`]),r=!1;for(let i of e){if(r){r=!1;continue}if(n.has(i)){r=!0;continue}if(!i.startsWith(`-`))return t.has(i)?i:`web`}return`web`}function Vo(e){let t=G.platform===`win32`?Uo(e):Ho(e);if(t.status===0)return t.stdout.trim()||void 0}function Ho(e){return K(`ps`,[`-p`,String(e),`-o`,`command=`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}function Uo(e){return K(`powershell.exe`,[`-NoProfile`,`-NonInteractive`,`-Command`,`(Get-CimInstance Win32_Process -Filter 'ProcessId = ${e}').CommandLine`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}async function Wo(e,t){let n=await Go(P.resolve(e)),r=n.gitCommonDir?P.join(n.path,`coreframe-dev`):P.join(n.path,`.coreframe`);return{file:P.join(r,`dev.${t}.lock`),repository:n.path}}async function Go(e){let t=Ko(e);return t?{gitCommonDir:!0,path:await qo(P.resolve(e,t))}:{gitCommonDir:!1,path:await qo(e)}}function Ko(e){let t=K(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]});if(t.status===0)return t.stdout.trim()||void 0}async function qo(e){return Ee(e).catch(()=>P.resolve(e))}function Jo(e,t){return e.platform===t.platform&&e.repository===t.repository}function Yo(e,t){let n={...e};return t===`desktop`?delete n.COREFRAME_PLATFORM:t===`web`||t===`webext`?n.COREFRAME_PLATFORM=`web`:n.COREFRAME_PLATFORM=t,n}const Xo=G.platform===`win32`?`portless.cmd`:`portless`;async function Zo({cwd:e,env:t,platform:n}){return n!==`web`||t.PORTLESS===`0`||t.TAURI_ENV_PLATFORM!==void 0||(await Kt()).isAgent?!1:Nt(e)}async function Qo({cwd:e,env:t,lan:n=!1}){let r=P.join(`node_modules`,`.bin`,Xo),i=[`proxy`,`start`,...n?[`--lan`]:[]];await R(P.resolve(e,r),i,{cwd:e,env:t,stdio:`inherit`})}function $o({host:e,lan:t=!1,port:n}){return[...t?[`--lan`]:[],`run`,...n===void 0?[]:[`--app-port`,String(n)],`react-router`,`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e]]}async function es({cwd:e=G.cwd(),platform:t}){let n=await ts({cwd:e});if(!n||!us(n.platform)||!ds(n.platform,t)||!ps(n.owner.pid))return;let r=await Do({cwd:e,platform:n.platform});if(!(!r||!ms(n.owner,r))&&!(n.postgres?.pid!==void 0&&!ps(n.postgres.pid)))return n}async function ts({cwd:e=G.cwd()}={}){let t;try{t=JSON.parse(await V(is(e),`utf8`))}catch{return}return as(t)&&t.cwd===P.resolve(e)?t:void 0}async function ns({cwd:e=G.cwd(),owner:t,platform:n,postgres:r,vitePort:i}){let a=is(e),o=P.dirname(a),s=`${a}.${W()}.tmp`,c={cwd:P.resolve(e),owner:t,platform:n,...r?{postgres:r}:void 0,version:1,vite:{port:i}};await B(o,{recursive:!0});try{await U(s,`${JSON.stringify(c)}\n`,{flag:`wx`,mode:384}),await De(s,a)}finally{await ke(s).catch(()=>void 0)}}async function rs({cwd:e=G.cwd(),owner:t}){let n=is(e),r=await ts({cwd:e});!r||!ms(r.owner,t)||await ke(n).catch(()=>void 0)}function is(e){return P.resolve(e,`.coreframe/dev.session.json`)}function as(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.version===1&&typeof t.cwd==`string`&&os(t.owner)&&cs(t.platform)&&fs(t.vite?.port)&&(t.postgres===void 0||ss(t.postgres))}function os(e){if(!e||typeof e!=`object`)return!1;let t=e,n=t.pid;return typeof n==`number`&&Number.isSafeInteger(n)&&n>0&&typeof t.token==`string`}function ss(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.dataDir==`string`&&(t.pid===void 0||Number.isSafeInteger(t.pid)&&t.pid>0)}function cs(e){return e===`android`||e===`desktop`||e===`ios`||e===`macos`||e===`web`}function ls(e){return e===`android`||e===`ios`||e===`macos`}function us(e){return e===`web`||ls(e)}function ds(e,t){return t===void 0?ls(e):e===t}function fs(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0&&e<=65535}function ps(e){try{return G.kill(e,0),!0}catch(e){return e instanceof Error&&e.code===`EPERM`}}function ms(e,t){return e.pid===t.pid&&e.token===t.token}const hs=G.platform===`win32`?`pnpm.cmd`:`pnpm`,gs=G.platform===`win32`?`portless.cmd`:`portless`,_s=G.platform===`win32`?`react-router.cmd`:`react-router`,vs=G.platform===`win32`?`turso.cmd`:`turso`;async function ys({cwd:e=G.cwd(),debug:t,device:n,env:r=G.env,host:i,https:a=!1,interactive:o=G.stdin.isTTY===!0,lan:s=!1,managed:c=!1,noManaged:l=!1,platform:u=`web`,portless:d,fresh:f=!1,reuseVite:p=!1,verbose:m=!1,webPort:h,supervisor:g}){let _=kt({env:r}),v=Ts(u)?u:void 0,y=Es(u),b=u===`ios`||u===`android`?u:void 0,x=b?await Ya({env:r,interactive:o,platform:b,target:n}):void 0,S=b&&x?await Xa({device:x,host:i,interactive:o,platform:b}):void 0,C=v?!0:i,w=await _.measure(`config`,()=>Ie({cwd:e})),T=await _.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(c||o&&!l)&&await Mt(e));await _.measure(`i18n`,()=>Wn({cwd:e,projectConfig:w}));let E=await _.measure(`routing`,async()=>d??await Zo({cwd:e,env:r,platform:u})),ee=await _.measure(`https`,async()=>a&&!E?Pt({cwd:e}):void 0),te=Yo(r,u),D={...te,..._.environment,...T?{[Bt]:`1`,[Vt]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...v?{COREFRAME_PLATFORM:v}:void 0,...ee?{[At]:ee.cert,[jt]:ee.key}:void 0},O=!1,ne,re,k,A,j,ae,M,oe=new Map,N=[`postgres`,y];for(let e of N){let t=e===`postgres`?`postgres`:e.startsWith(`vite:flutter`)?`flutter`:`web`,n=Y({label:t}),r=Y({color:`red`,label:t});n.pipe(G.stdout,{end:!1}),r.pipe(G.stderr,{end:!1}),oe.set(e,{stderr:r,stdout:n})}let se=g.onEvent(e=>{e.event===`log`?(oe.get(e.resource)?.[e.stream])?.write(e.data):e.event===`service`&&e.resource===y&&e.state===`failed`&&(M=Error(e.error??`${y} development failed.`),F())}),F=()=>{O||(O=!0,k?.kill(`SIGTERM`),A?.kill(`SIGTERM`),re?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0))},ce=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>{ne??=e,F()};return G.on(e,t),{handler:t,signal:e}}),I=async e=>{let t=Ht(e);k=t;try{await t.expectSuccess()}catch(e){if(!O)throw e}finally{k===t&&(k=void 0)}};try{if(await g.subscribe(N),ws(w)){let e=await g.acquirePostgres({config:w,env:D});j=e.leaseId,D={...D,...e.env}}if(w.database?.dialect===`sqlite`){let t=await Va.getAvailablePort(),n=P.resolve(e,`.coreframe`),r=P.join(n,`turso.db`);await $.mkdir(n,{recursive:!0}),D={...D,TURSO_DATABASE_URL:`http://127.0.0.1:${t}`,TURSO_AUTH_TOKEN:`dev`},A=Ht({name:`turso`,command:vs,args:[`dev`,`--port`,String(t),`--db-file`,r],cwd:e,env:D}),await A.waitFor(`listening`)}(ws(w)||w.database?.dialect===`sqlite`)&&await _.measure(`schema`,()=>I({name:`db`,command:hs,args:[`db`,`ensure`],cwd:e,env:D,prefix:!1}));let t=Cs(h??r.COREFRAME_WEB_PORT),n=await g.status(),i=n.resources?.find(e=>e.resource===y),c=i!==void 0&&!f&&t===void 0?void 0:t??5173,l=c??i?.endpoint?.port??5173;if(c!==void 0&&n.resources?.some(e=>e.resource!==y&&e.endpoint?.port===l)){if(t!==void 0)throw Error(`Port ${l} is already used by another Coreframe development shell.`);l=await Va.getAvailablePort()}if(!p){let t={...D,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[D.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:P.join(e,`node_modules`,`.bin`)+P.delimiter+(D.PATH??``)},n=[{args:E?$o({host:C,lan:s,port:l}):[`dev`,...C===void 0?[]:[`--host`,C===!0?`0.0.0.0`:C],`--port`,String(l),...v?[`--strictPort`]:[]],command:E?gs:_s,cwd:e,env:t},{args:[`exec`,`panda`,`dev`,`--no-color`],command:hs,cwd:e,env:D}],r=await g.acquireVite({configFingerprint:Ss({cwd:e,host:C,lan:s,https:a,portless:E,resource:y}),endpoint:{host:C===!0?`0.0.0.0`:C??`127.0.0.1`,port:l},processes:n,resource:y},f);ae=r.leaseId,l=r.endpoint.port}if(_.report(),O)return;if(u===`web`?await xs(g,y,()=>M):(await ie({cwd:e}),await bs({cwd:e,env:te,interactive:o,mobileHost:S,platform:u,port:l,requestStop:F,selectedDevice:x,isStopping:()=>O,setActiveNative:e=>{re=e},verbose:m})),M)throw M}finally{F(),ae&&await g.release(ae).catch(()=>void 0),j&&await g.release(j).catch(()=>void 0),se();for(let{handler:e,signal:t}of ce)G.off(t,e);for(let e of oe.values())e.stdout.end(),e.stderr.end();ne&&(G.exitCode??=ne===`SIGINT`?130:143),g.close()}}async function bs({cwd:e,env:t,interactive:n,mobileHost:r,platform:i,port:a,requestStop:o,selectedDevice:s,isStopping:c,setActiveNative:l,verbose:u}){for(;;){let d=i===`android`&&!u?await oe():void 0,f=R(`flutter`,[`run`,`-d`,s?.id??`macos`,`--dart-define=COREFRAME_DEV_SERVER_URL=${Ds(i,r,a)}`,...u?[`--verbose`]:[]],{cwd:P.join(e,`src-flutter`),env:t,stdio:d?[`inherit`,`pipe`,`pipe`]:`inherit`});l(f);try{await Promise.all([f,d?.capture(f)]);return}catch(e){if(c()||i===`desktop`||!n)throw e;let t=await z.confirm({initialValue:!0,message:`Flutter failed. Retry?`});if(z.isCancel(t)||!t){o();return}}finally{l(void 0)}}}async function xs(e,t,n){await e.waitForServiceExit(t);let r=n();if(r)throw r}function Ss({cwd:e,host:t,lan:n,https:r,portless:i,resource:a}){return Re(`sha256`).update(JSON.stringify({cwd:P.resolve(e),host:t??null,lan:n,https:r,portless:i,resource:a})).digest(`hex`)}function Cs(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}function ws(e){return(e.database?.dialect??`postgres`)===`postgres`}function Ts(e){return e===`android`||e===`ios`||e===`macos`}function Es(e){if(e===`web`)return`vite:web`;if(Ts(e))return`vite:flutter:${e}`;throw Error(`Unsupported supervised development platform: ${e}.`)}function Ds(e,t,n){let r=t??(e===`android`?`10.0.2.2`:`127.0.0.1`);return`http://${r.includes(`:`)&&!r.startsWith(`[`)?`[${r}]`:r}:${n}`}const Os=`extension:dev`;function ks(e){if(!q(I(e,`src-webext/wxt.config.ts`)))throw Error("No WXT configuration found at src-webext/wxt.config.ts. Apply the wxt recipe or add that convention before running `coreframe dev webext`.");let t=I(e,`package.json`),n;try{n=JSON.parse(J(t,`utf8`))}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}if(!n||typeof n!=`object`||!(`scripts`in n)||!n.scripts||typeof n.scripts!=`object`||!(`extension:dev`in n.scripts)||typeof n.scripts[`extension:dev`]!=`string`)throw Error(`package.json must define scripts.${Os} for \`coreframe dev webext\`. Apply the wxt recipe and add its named extension lifecycle scripts.`)}function As({host:e,port:t}){let n=[...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)]];return[`run`,Os,...n.length>0?[`--`,...n]:[]]}const js=[`web`,`webext`,`desktop`,`ios`,`android`,`macos`],Ms=[`managed-dev-overlay`],Ns=P.resolve(`node_modules`,`.bin`),Ps=G.platform===`win32`?`pnpm.cmd`:`pnpm`,Fs=G.platform===`win32`?`portless.cmd`:`portless`,Is=G.platform===`win32`?`react-router.cmd`:`react-router`,Ls=G.platform===`win32`?`turso.cmd`:`turso`;async function Rs({cwd:e=G.cwd(),debug:t,device:n,env:r=G.env,host:i,https:a=!1,interactive:o=G.stdin.isTTY===!0,lan:s=!1,managed:c=!1,noManaged:l=!1,platform:u=`web`,fresh:d=!1,reuseVite:f=!1,supervisor:p,verbose:m=!1,webPort:h}={}){let g=kt({env:r}),_=r.PATH??r.Path??``,v=u===`ios`||u===`android`||u===`macos`?u:void 0,y=u===`web`||v!==void 0;if(d&&f)throw Error(`Cannot use --fresh and --reuse-vite together.`);let b=!d&&(v||u===`web`)?await g.measure(`dev-session`,()=>es({cwd:e,platform:u})):void 0,x=f||b!==void 0,S=u===`desktop`?void 0:Xs(h??r.COREFRAME_WEB_PORT);if(b&&S!==void 0&&S!==b.vite.port)throw Error(`The active development session uses port ${b.vite.port}. Omit --port or use that port when reusing it.`);let C=u===`ios`||u===`android`||u===`macos`?b?.vite.port??S??5173:u===`web`||u===`webext`?b?.vite.port??S:void 0,w,T,E,ee,te,D,O,ne,re,k=!1,A,j=r,ae,M;if(c&&l)throw Error(`Cannot use --managed and --no-managed together.`);if(t===`managed-dev-overlay`&&c)throw Error(`Cannot use --managed with --debug managed-dev-overlay.`);if(f&&v===void 0)throw Error(`The --reuse-vite option is only supported for Flutter development platforms (iOS, Android, and macOS).`);if(u===`webext`){if(c||l||t!==void 0||m)throw Error(`Managed development, debug features, and verbose native output are only supported for the main web or native development platforms.`);ks(e)}if(a&&u!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(n!==void 0&&u!==`ios`&&u!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);if(u===`web`&&r.TAURI_ENV_PLATFORM!==void 0&&r.COREFRAME_TAURI_DEV!==`1`)throw Error("Direct Tauri development is not supported. Run `pnpm dev desktop` instead.");let N=await g.measure(`routing`,()=>Zo({cwd:e,env:r,platform:u}));if(N&&await g.measure(`portless`,()=>Qo({cwd:e,env:r,lan:s})),y&&r.COREFRAME_DEV_SUPERVISOR!==`0`){let g=p??await Ot({cwd:e,env:r});if(g)return ys({cwd:e,debug:t,device:n,env:r,fresh:d,host:i,https:a,interactive:o,lan:s,managed:c,noManaged:l,platform:u,portless:N,reuseVite:f,supervisor:g,verbose:m,webPort:h})}let se=x?void 0:await g.measure(`dev-lock`,()=>Eo({cwd:e,interactive:o,platform:u}));if(!x&&!se)return;let F=()=>{k||(k=!0,T?.kill(`SIGTERM`),ee?.kill(`SIGTERM`),D?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),O?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),re?.close().catch(()=>void 0),ne?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),w?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),te?.kill(`SIGTERM`))},ce=e=>{A??=e,F()},I=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>ce(e);return G.on(e,t),{handler:t,signal:e}}),le=async e=>{let t=Ht(e);T=t;try{await t.expectSuccess()}catch(e){if(!k)throw e}finally{T===t&&(T=void 0)}};try{let d=u===`ios`||u===`android`?u:void 0,f=d?await Ya({env:r,interactive:o,platform:d,target:n}):void 0,p=d&&f?await Xa({device:f,host:i,interactive:o,platform:d}):void 0,h=v?!0:i,y={},b=!1,S;x||([y,b]=await Promise.all([g.measure(`config`,()=>Ie({cwd:e})),g.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(c||o&&!l)&&await Mt(e))]),await g.measure(`i18n`,()=>Wn({cwd:e,projectConfig:y})),S=u!==`webext`&&zs(e)?await Va.getAvailablePort():void 0);let T=x?void 0:await g.measure(`https`,async()=>a&&!N?Pt({cwd:e}):void 0),A=Yo(r,u);j={...A,...g.environment,...b?{[Bt]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...u===`desktop`?{COREFRAME_TAURI_DEV:`1`,TAURI_ENV_PLATFORM:Js()}:void 0,...v?{COREFRAME_PLATFORM:v}:void 0,...T?{[At]:T.cert,[jt]:T.key}:void 0,...S?{COREFRAME_DASHBOARD_ORIGIN:`http://127.0.0.1:${S}`}:void 0};let ce=async()=>{if(!S)return;let t,n=async(e,n)=>{try{await e,k||t?.fail(Error(`The dashboard development server stopped unexpectedly.`))}catch(e){k||t?.fail(e)}finally{await n.outputTasks,n.stdout.end(),n.stderr.end(),await Promise.allSettled([zt(n.stdout),zt(n.stderr)]),ne===e&&(ne=void 0)}};t=So({port:S,start:async()=>{if(k)throw Error(`The dashboard development server was stopped before it started.`);let t=await Va.getAvailablePort();if(k)throw Error(`The dashboard development server was stopped before it started.`);let r=Y({label:`dashboard`}),i=Y({color:`red`,label:`dashboard`});r.pipe(G.stdout,{end:!1}),i.pipe(G.stderr,{end:!1});let a=R(Is,[`dev`,`--host`,`127.0.0.1`,`--port`,String(t)],{cwd:P.resolve(e,`dashboard`),env:{...j,PATH:P.resolve(e,`node_modules/.bin`)+P.delimiter+_},stdin:`inherit`});ne=a;let o=Promise.allSettled([Bs(a.stdout,r),Bs(a.stderr,i)]);return n(a,{outputTasks:o,stderr:i,stdout:r}),{host:`127.0.0.1`,port:t}}}),re=t;try{await t.listen(),await t.wait()}finally{await t.close(),re===t&&(re=void 0)}},I=async()=>{let t=Y({label:`web`}),n=Y({color:`red`,label:`web`});t.pipe(G.stdout,{end:!1}),n.pipe(G.stderr,{end:!1}),D=R(N?Fs:Is,N?$o({host:h,lan:s,port:C}):Ys({host:h,port:C,strictPort:v!==void 0}),{cwd:e,env:{...j,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[j.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:Ns+P.delimiter+_},stdin:`inherit`});let r=Promise.allSettled([Bs(D.stdout,t),Bs(D.stderr,n)]);try{await D;let e=(await r).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!k)throw e}finally{await r,t.end(),n.end(),await Promise.allSettled([zt(t),zt(n)]),D=void 0}},L=async()=>{let t=Y({label:`webext`}),n=Y({color:`red`,label:`webext`});t.pipe(G.stdout,{end:!1}),n.pipe(G.stderr,{end:!1}),O=R(Ps,As({host:i,port:C}),{cwd:e,env:j,stdin:`inherit`});let r=Promise.allSettled([Bs(O.stdout,t),Bs(O.stderr,n)]);try{await O;let e=(await r).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!k)throw e}finally{await r,t.end(),n.end(),await Promise.allSettled([zt(t),zt(n)]),O=void 0}},ue=async t=>{for(;!k;){let n=u===`android`&&!m?await oe():void 0,r=u===`desktop`?R(Ps,Gs(),{cwd:e,env:A,stdio:`inherit`}):R(`flutter`,Ks({device:f??{id:`macos`},serverUrl:qs(u,p,C),verbose:m}),{cwd:P.join(e,`src-flutter`),env:A,stdio:n?[`inherit`,`pipe`,`pipe`]:`inherit`});w=r;try{await Promise.all([r,n?.capture(r)]);return}catch(e){if(u===`desktop`||k||!o)throw e;let n=await z.confirm({initialValue:!0,message:`Flutter failed. Retry?`});if(z.isCancel(n)||!n){z.log.warn(t?`Flutter stopped. Web development is still running.`:`Flutter stopped.`),t&&await t;return}}finally{w===r&&(w=void 0)}}},de=async()=>{if(x){if(u===`web`)return;await ie({cwd:e}),await ue();return}if(u===`web`){await I();return}let t=I().then(()=>{if(!k)throw Error(`The Vite development server stopped while ${u===`desktop`?`Tauri`:`Flutter`} was still running.`)});u!==`desktop`&&await ie({cwd:e});try{await Promise.race([t,ue(t)])}finally{F(),await Promise.allSettled([t,w]),w=void 0}},fe=async()=>{let t=Ht({name:`panda`,command:Ps,args:[`exec`,`panda`,`dev`,`--no-color`],cwd:e,env:j});ee=t;try{if(await t.expectSuccess(),!k)throw Error(`The Panda CSS watcher stopped while development was still running.`)}catch(e){if(!k)throw e}finally{ee===t&&(ee=void 0)}},pe=async()=>{if(u===`webext`){await L();return}if(x){await de();return}let e=fe(),t=de(),n=S?ce():void 0;try{await Promise.race([e,t,n].filter(e=>e!==void 0)),k&&await t}finally{F(),await Promise.allSettled([e,t,n].filter(e=>e!==void 0))}},me=async()=>{x||!se?.owner||C===void 0||(await ns({cwd:e,owner:se.owner,platform:u,postgres:M,vitePort:C}),ae=se.owner)};if(b&&(j={...j,[Vt]:`1`}),k)return;if(u===`webext`){g.report(),await pe();return}if(x){g.report(),await pe();return}if(y.database?.dialect===`sqlite`&&(await g.measure(`database`,async()=>{let t=await Va.getAvailablePort(),n=P.resolve(e,`.coreframe`),i=P.join(n,`turso.db`);await $.mkdir(n,{recursive:!0}),j={...j,TURSO_DATABASE_URL:`http://127.0.0.1:${t}`,TURSO_AUTH_TOKEN:`dev`},te=Ht({name:`turso`,command:Ls,args:[`dev`,`--port`,String(t),`--db-file`,i],cwd:e,env:r}),await te.waitFor(`listening`)}),await g.measure(`schema`,()=>le({name:`db`,command:Ps,args:[`db`,`ensure`],cwd:e,env:j,prefix:!1})),k))return;if(Ws(y)){let t=Y({label:`postgres`});t.pipe(G.stdout,{end:!1});try{let n=await g.measure(`database`,()=>Us({config:y,cwd:e,env:j,failIfRunning:!0,interactive:o,isStopping:()=>k,postgresOutput:t,takeoverApproved:se?.takeoverApproved??!1}));if(!n)return;E=n,j=n.env,M=await Hs(n.env);try{k||await g.measure(`schema`,()=>le({name:`db`,command:Ps,args:[`db`,`ensure`],cwd:e,env:j,prefix:!1})),k||(await me(),g.report(),await pe())}finally{await n[Symbol.asyncDispose](),E===n&&(E=void 0)}}finally{t.end()}return}await me(),g.report(),await pe()}finally{F(),ae&&=(await rs({cwd:e,owner:ae}),void 0);let t;try{await E?.[Symbol.asyncDispose]()}catch(e){t=e}finally{for(let{handler:e,signal:t}of I)G.off(t,e);A&&(G.exitCode??=A===`SIGINT`?130:143)}Vs(t),await se?.release()}}function zs(e){return q(P.resolve(e,`dashboard/dashboard.config.ts`))}async function Bs(e,t){for await(let n of e)t.write(`${n}\n`)||await Rt(t,`drain`)}function Vs(e){if(e)throw e}async function Hs(e){let t=e.PGDATA;if(!t)return;let n=Number((await $.readFile(P.join(t,`postmaster.pid`),`utf8`).catch(()=>``)).split(/\r?\n/,1)[0]);return{dataDir:P.resolve(t),...Number.isSafeInteger(n)&&n>0?{pid:n}:void 0}}async function Us({interactive:e,isStopping:t,takeoverApproved:n,...r}){try{return await re(r)}catch(i){if(!(i instanceof m)||!e)throw i;if(!n){let e=await z.confirm({initialValue:!1,message:`PostgreSQL is already running for this project (PID ${i.pid}). Stop it and start here?`});if(z.isCancel(e)||!e){z.cancel(`Keeping the existing PostgreSQL process.`);return}}return await k(i),t()?void 0:re(r)}}function Ws(e){return(e.database?.dialect??`postgres`)===`postgres`}function Gs(){return[`exec`,`tauri`,`dev`,`--config`,JSON.stringify({build:{beforeDevCommand:``}})]}function Ks({device:e,serverUrl:t,verbose:n}){return[`run`,`-d`,e.id,`--dart-define=COREFRAME_DEV_SERVER_URL=${t}`,...n?[`--verbose`]:[]]}function qs(e,t,n){let r=t??(e===`android`?`10.0.2.2`:`127.0.0.1`);return`http://${r.includes(`:`)&&!r.startsWith(`[`)?`[${r}]`:r}:${n}`}function Js(){return G.platform===`win32`?`windows`:G.platform}function Ys({host:e,port:t,strictPort:n=!1}){return[`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)],...n?[`--strictPort`]:[]]}function Xs(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}async function Zs(e={}){let t=e.cwd??G.cwd(),n=await Pe(`scripts/preview.ts`,t);if(typeof n.default!=`function`)throw Error(`scripts/preview.ts must export a default preview function.`);return qt({...e,cwd:t},n.default)}const Qs=`worker-configuration.d.ts`;async function $s({check:e=!1,cwd:t=process.cwd()}={}){let n=await Ie({cwd:t}),r=await nt({coreframeConfig:n,cwd:t}),i=L(t,Qs),a=L(t,`.coreframe-worker-types-${W()}.d.ts`);try{try{await R(`pnpm`,[`exec`,`wrangler`,`types`,a,`--config`,r.path,`--strict-vars=false`,`--include-runtime=false`],{cwd:t,stdio:[`ignore`,`pipe`,`pipe`]})}catch(e){throw ec(e),e}let o=tc(await V(a,`utf8`)),s=Le(r.config),c=Fe(n.worker?.environment).filter(e=>!s.has(e.name)),l=`${o.trimEnd()}\n\n${nc(c)}\n`;if(e){if(await V(i,`utf8`).catch(()=>``)!==l)throw Error(`${Qs} is stale. Run "coreframe worker typegen" and commit the result.`);return{changed:!1,path:i}}let u=await V(i,`utf8`).catch(()=>``);return u!==l&&await U(i,l),{changed:u!==l,path:i}}finally{await r.dispose(),await H(a,{force:!0})}}function ec(e){if(typeof e!=`object`||!e||!(`output`in e))return;let{output:t}=e;typeof t!=`string`||t===``||process.stderr.write(t.endsWith(`
10
+ `:``;qe(e,`${JSON.stringify(n,null,r)}${i}`)}function ga(e,t){if(t.length!==0){console.log(`${e}:`);for(let e of t)console.log(` ${e}`);console.log(``)}}function _a(e){let t=R(oa([`rev-parse`,`--show-toplevel`]).trim(),`package.json`),n=Y(t,`utf8`),r=sa(n,t),i=Lr(e.target),a=pa(i),o=new Set(a.map(({name:e})=>e)),s=[],c=[],l=[],u=0;for(let e of a){let t=ma(r,e.name);if(!t){c.push(`missing: ${e.name} ${e.spec} (${e.group})`);continue}if(ua(t.spec)){l.push(`linked: ${e.name} ${t.spec}`);continue}if(t.spec===e.spec){u+=1;continue}s.push({...e,currentGroup:t.group,currentSpec:t.spec})}let d=aa.flatMap(e=>Object.entries(r[e]??{}).filter(([e])=>la(e)&&!o.has(e)).map(([t,n])=>`review: ${t} ${n} (${e})`));if(e.apply&&s.length>0){for(let e of s)r[e.currentGroup][e.name]=e.spec;ha(t,n,r)}console.log(`Coreframe package sync: ${i}`),console.log(``),ga(e.apply?`Updated Coreframe packages`:`Would update Coreframe packages`,s.map(({currentSpec:e,name:t,spec:n})=>`update: ${t} ${e} -> ${n}`)),ga(`Missing target Coreframe packages`,c),ga(`Locally linked Coreframe packages`,l),ga(`Downstream-only Coreframe packages`,d),u>0&&console.log(`${u} Coreframe package(s) already match the target versions.`),s.length===0?console.log(`No Coreframe package version updates found.`):e.apply||(console.log(``),console.log(`Run with --apply to write the ${s.length} package update(s).`))}const va={...f,displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return Tr(e)}},ya=p({name:`upgrade`,cmds:{"ensure-template-remote":n({name:`ensure-template-remote`,args:{remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:i({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>Fr({fetch:!e,remote:t})}),"check-skill-current":n({name:`check-skill-current`,args:{target:c({long:`target`,type:f,description:`Target Coreframe template git ref.`}),apply:i({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=Ii({apply:e,target:t})}}),"fast-forward-template-files":n({name:`fast-forward-template-files`,args:{target:c({long:`target`,type:f,description:`Target Coreframe template git ref.`}),base:c({long:`base`,type:l(f),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:i({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>ia({apply:e,base:t,target:n})}),"sync-coreframe-packages":n({name:`sync-coreframe-packages`,args:{target:c({long:`target`,type:f,description:`Target Coreframe template git ref.`}),apply:i({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>_a({apply:e,target:t})})}}),ba=p({name:`recipes`,cmds:{apply:n({name:`apply`,args:{recipe:u({type:va,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:c({long:`target`,type:l(f),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:i({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>ui(li({fetch:!e,name:t,remote:n,target:r}))}),list:n({name:`list`,args:{target:c({long:`target`,type:l(f),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:i({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>ki(Oi({fetch:!e,remote:t,target:n}))}),verify:n({name:`verify`,args:{recipe:u({type:va,displayName:`recipe`,description:`Recipe adoption to verify.`}),target:c({long:`target`,type:l(f),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:c({long:`remote`,type:f,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:i({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>oi(ai({fetch:!e,name:t,remote:n,target:r}))})}}),xa=p({name:`db`,cmds:{ensure:n({name:`ensure`,args:{},handler:b}),generate:n({name:`generate`,args:{args:d({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>O(`generate`,e)}),migrate:n({name:`migrate`,args:{args:d({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>O(`migrate`,e)}),"migrate-held":n({name:`migrate-held`,args:{local:i({long:`local`,description:`Run held migrations against the Coreframe-managed local PostgreSQL database.`,defaultValue:()=>!1})},handler:({local:e})=>T({target:e?`local`:`deployment`})}),"migrate-local":n({name:`migrate-local`,args:{},handler:E}),"migrations-check":n({name:`migrations-check`,args:{},handler:h}),reset:n({name:`reset`,args:{},handler:D}),seed:n({name:`seed`,args:{},handler:()=>A()}),"schema-check":n({name:`schema-check`,args:{seed:i({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>g({seed:e})}),setup:n({name:`setup`,args:{},handler:()=>te()}),studio:n({name:`studio`,args:{args:d({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>O(`studio`,e)})}}),Sa=`package.json`;async function Ca(e=process.argv.slice(2),t=process.env){let n=wa(e);Ma(n);let{packageJson:r,source:i}=await dt(Sa),a=await Le(),o=ht(a.deploy??{},n.environment,t);La(t,[`POSTHOG_API_KEY`,`POSTHOG_PROJECT_ID`]);let s=await Na(o,n.environment,()=>et({env:t})),c=_t({args:n,config:n.environment===`production`?o.tauriRelease:{},env:t});Ia(n.environment,c.enabled),await wt(c);let l=await ft({environment:n.environment}),u=l.values.DASHBOARD_PASSWORD??await Ra(t,n.environment);Tt(await tt({environment:n.environment}),n.environment,{availableNames:[...Object.keys(l.values),...u?[`DASHBOARD_PASSWORD`]:[]]});let d=await ot({environment:n.environment}),f=await ja();await Jn({env:t,revision:f});let p=f.slice(0,12),m=gt(n.environment,r.version,p),h=mt(r.name,m),g={...Va(t,n.environment,h,r.name,m),COREFRAME_I18N_RELEASE_REVISION:f},_=n.environment===`production`,b=!1,x={files:[]};B.intro(`Deploy ${h} to ${n.environment}`);let S=Object.keys(l.values).sort();S.length>0&&B.note(S.join(`
11
+ `),`Pending Worker secret updates`),d.provisioned&&B.log.info(`Provisioning Coreframe-managed access-token signing material.`),await Fa(n);let C=a.database?.dialect??`postgres`,T;switch(C){case`postgres`:T=await v({env:t});break;case`sqlite`:T=await y({env:t});break;default:throw Error(`Unsupported database dialect "${C}".`)}let E=await Oa(T),ee=await k(E);if(ee.length>0)throw Error(`Pending deploy migrations contain unsafe SQL. Move unsafe statements to held migrations.\n${w(ee)}`);let D=await Aa(n,E);try{_&&(await Dt(Sa,r,m),x=await Ot(c,m)),B.log.step(`Running pre-deploy build`),await z(`pnpm`,[`build`],{env:Ha(g),stdio:`inherit`});let e=c.enabled?await st({env:Ha(g),plan:c,releaseName:h,version:m}):void 0;B.log.step(`Running release build and uploading PostHog source maps`),b=!0,await z(`pnpm`,[`build`],{env:g,stdio:`inherit`}),D&&(B.log.step(`Running deploy-safe database migrations`),await z(`pnpm`,[`db`,`migrate`],{env:g,stdio:`inherit`})),B.log.step(`Deploying Worker and static assets to Cloudflare`);let t={...u?{DASHBOARD_PASSWORD:u}:{},...d.value?{[Xe]:d.value}:{},...l.values},i=Object.keys(t).length>0?await za(t):void 0,f=await nt({coreframeConfig:a,environment:n.environment,contributions:{generatedValues:{DEPLOY_ENV:n.environment,POSTHOG_RELEASE:h}}});try{await z(`pnpm`,[`exec`,`wrangler`,`deploy`,`--config`,f.path,`--env`,n.environment,`--strict`,`--keep-vars`,`--tag`,h,`--message`,`Deploy ${h}`,...i?[`--secrets-file`,i.path]:[]],{env:g,stdio:`inherit`}),await Ze(l),await Et({environment:n.environment})}finally{await f.dispose(),await i?.dispose()}let p={environment:n.environment,releaseName:h,url:s,version:m};o.afterWorkerDeploy&&(B.log.step(`Running required after-Worker deploy hook`),await bt(o,p)),n.skipPostDeployChecks||(B.log.step(`Running post-deploy checks`),await xt(o,p)),e&&(B.log.step(`Uploading Tauri release artifacts to Backblaze B2`),await Ct(c,e)),B.outro(`Deployed ${h} to ${n.environment}`)}catch(e){throw!b&&_&&(await W(Sa,i),await vt(x)),e}}function wa(e){return{environment:Ta(e[0]),runMigrations:e.includes(`--run-migrations`),skipMigrations:e.includes(`--skip-migrations`),skipPostDeployChecks:e.includes(`--skip-post-deploy-checks`),tauriLocalPlatforms:Ea(e,`--tauri-local-platform`).map(e=>at(e)),tauriWorkflowName:Da(e,`--tauri-workflow-name`),tauriWorkflowPlatforms:Ea(e,`--tauri-workflow-platform`).map(e=>at(e)),tauriWorkflowRef:Da(e,`--tauri-workflow-ref`),yes:e.includes(`--yes`)}}function Ta(e){if(e&&Qe.includes(e))return e;throw Error(`Deploy environment must be one of: ${Qe.join(`, `)}.`)}function Ea(e,t){let n=[];for(let r=0;r<e.length;r+=1){let i=e[r];if(i===t){let i=e[r+1];if(!i||i.startsWith(`--`))throw Error(`${t} requires a value.`);n.push(...i.split(`,`).filter(Boolean)),r+=1;continue}i.startsWith(`${t}=`)&&n.push(...i.slice(t.length+1).split(`,`).filter(Boolean))}return n}function Da(e,t){let n=Ea(e,t);if(n.length>1)throw Error(`${t} can only be provided once.`);return n[0]}async function Oa(e){try{return await ka(e)}finally{await e.close?.()}}async function ka(e){return x(await _(),await ee(e))}async function Aa(e,t){if(t.length===0)return B.log.info(`No pending deploy migrations.`),!1;if(B.note(C(t),`Pending deploy migrations`),e.runMigrations)return!0;if(e.skipMigrations)return!1;if(!process.stdout.isTTY)throw Error(`Pending migrations require --run-migrations or --skip-migrations in noninteractive deploys.`);let n=await B.confirm({initialValue:!0,message:`Run these deploy-safe database migrations before Cloudflare deploy?`});if(B.isCancel(n))throw B.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`);return n}async function ja(){let{stdout:e}=await z(`git`,[`status`,`--porcelain`],{stdin:`ignore`});if(e.trim().length>0)throw Error(`Deploy requires a clean git tree.`);let{stdout:t}=await z(`git`,[`rev-parse`,`HEAD`],{stdin:`ignore`});return t.trim()}function Ma(e){if(e.runMigrations&&e.skipMigrations)throw Error(`Use only one of --run-migrations or --skip-migrations.`)}async function Na(e,t,n=et){return e.url?Pa(e.url,t):t===`staging`&&e.stagingHostname?Pa(await n(),t):Pa(void 0,t)}function Pa(e,t){if(!e)throw Error(`Missing ${t} deploy URL. Set DEPLOY_URL or deploy.environments.${t}.url in coreframe.config.ts.`);let n;try{n=new URL(e)}catch{throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`);return n.toString()}async function Fa(e){if(e.environment!==`production`||e.yes)return;if(!process.stdout.isTTY)throw Error(`Production deploys require --yes in noninteractive environments.`);let t=await B.confirm({initialValue:!1,message:`Deploy to production?`});if(B.isCancel(t)||!t)throw B.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`)}function Ia(e,t){if(e===`staging`&&t)throw Error(`Tauri releases can only be published from production deploys.`)}function La(e,t){let n=t.filter(t=>!e[t]);if(n.length>0)throw Error(`Missing required deploy environment variables: ${n.join(`, `)}`);return Object.fromEntries(t.map(t=>[t,e[t]]))}async function Ra(e,t){let n=e.DASHBOARD_PASSWORD?.trim();if(n)return n;let r;try{r=Rt(await H(`.env`,`utf8`))}catch(e){throw Ba(e)&&e.code===`ENOENT`?Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`):e}let i=r.DASHBOARD_PASSWORD?.trim();if(!i)throw Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`);return i}async function za(e){let t=await Te(L(Ne(),`coreframe-deploy-secrets-`)),n=L(t,`secrets.json`);return await W(n,JSON.stringify(e),{mode:384}),{path:n,dispose:()=>U(t,{force:!0,recursive:!0})}}function Ba(e){return e instanceof Error&&`code`in e}function Va(e,t,n,r,i){return{...e,CLOUDFLARE_ENV:t,DEPLOY_ENV:t,POSTHOG_RELEASE:n,POSTHOG_RELEASE_NAME:e.POSTHOG_RELEASE_NAME??r,POSTHOG_RELEASE_VERSION:e.POSTHOG_RELEASE_VERSION??i}}function Ha(e){let{POSTHOG_API_KEY:t,POSTHOG_PROJECT_ID:n,...r}=e;return r}const $={access:be,chmod:xe,mkdir:V,mkdtemp:Te,readFile:H,readFileSync:Y,rm:U,writeFile:W},Ua={getAvailablePort:Ga},Wa={homedir:je,kill:K.kill,networkInterfaces:Me,tmpdir:Ne};async function Ga(){let e=Kt();try{await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)});let t=e.address();if(!t||typeof t==`string`)throw Error(`Could not allocate an available TCP port.`);return t.port}finally{e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}}async function Ka(){let e=await Ja();return typeof e.mobileDevHost==`string`?{mobileDevHost:e.mobileDevHost}:{}}async function qa(e){let t=await Ja(),n=Ya();await $.mkdir(F.dirname(n),{recursive:!0}),await $.writeFile(n,`${JSON.stringify({...t,...e},void 0,2)}\n`)}async function Ja(){try{let e=await $.readFile(Ya(),`utf8`),t=JSON.parse(e);return Xa(t)?t:{}}catch{return{}}}function Ya(){return F.join(Wa.homedir(),`.coreframe`,`preferences.json`)}function Xa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Za({env:e=K.env,interactive:t=K.stdin.isTTY===!0,platform:n,target:r}){let i=await no(n,e).catch(()=>[]),a=r?bo(i,r):void 0;if(a)return a;if(!r&&i.length>0)return to(i,n,t);let o=r?bo(await io(e).catch(()=>[]),r):void 0;if(o&&o.platform===n)return ao(o,n,e,t);let s=await ro(n,e),c=r?bo(s,r):void 0;if(c)return c;if(!r&&s.length>0)return to(s,n,t);let l=n===`ios`?`iOS`:`Android`;throw Error(r?`Could not find a ${l} device matching "${r}".`:`No connected ${l} devices or available ${l} ${n===`ios`?`simulators`:`emulators`} were detected.`)}async function Qa(e){let{device:t,host:n,interactive:r=K.stdin.isTTY===!0}=e;if(!t.physical&&n===void 0)return;if(typeof n==`string`&&n!==`0.0.0.0`&&n!==`::`)return n;let i=So();if(i.length===0)throw Error(`No external IP address was detected. Pass one explicitly with --host.`);let a=await $a();if(a&&i.includes(a))return a;if(i.length===1)return await eo(i[0]),i[0];if(!r)throw Error(`Multiple external IP addresses were detected (${i.join(`, `)}). Pass one explicitly with --host.`);let o=await B.select({message:`Which IP address should the mobile device use to reach the development server?`,options:i.map(e=>({label:e,value:e}))});if(B.isCancel(o))throw Error(`Mobile development IP selection was cancelled.`);return await eo(o),o}async function $a(){return(await Ka()).mobileDevHost}async function eo(e){try{await qa({mobileDevHost:e})}catch(e){B.log.warn(`Could not remember the mobile development IP address: ${e instanceof Error?e.message:String(e)}`)}}async function to(e,t,n){if(e.length===1)return e[0];if(!n)throw Error(`Multiple ${t===`ios`?`iOS`:`Android`} devices were detected. Pass a device name explicitly.`);let r=await B.select({message:`Which ${t===`ios`?`iOS`:`Android`} device should Coreframe use?`,options:e.map(e=>({label:e.label,value:e,hint:e.id}))});if(B.isCancel(r))throw Error(`Mobile development device selection was cancelled.`);return r}async function no(e,t){return e===`android`?so(t):lo(t)}async function ro(e,t){return e===`android`?co(t):uo(t)}async function io(e){let{stdout:t}=await z(`flutter`,[`emulators`],{env:e});return t.split(/\r?\n/).flatMap(e=>{let[t,n,,r]=e.split(/\s*•\s*/).map(e=>e.trim());return t&&n&&(r===`android`||r===`ios`)?[{id:t,label:n,name:n,physical:!1,platform:r}]:[]})}async function ao(e,t,n,r){let i=await oo(t,n).catch(()=>[]),{stdout:a}=await z(`flutter`,[`emulators`,`--launch`,e.id],{env:n});if(/No emulator found|More than one emulator matches/i.test(a))throw Error(a.trim());let o=Date.now()+3e4;do{let a=await oo(t,n).catch(()=>[]),o=bo(a,e.id);if(o)return o;let s=a.filter(e=>!i.some(t=>t.id===e.id));if(s.length>0)return to(s,t,r);if(a.length===1)return a[0];await qt(250)}while(Date.now()<o);let s=t===`ios`?`iOS simulator`:`Android emulator`;throw Error(`Flutter launched "${e.id}", but no ${s} became available.`)}async function oo(e,t){return e===`ios`?uo(t,`booted`):(await so(t)).filter(e=>!e.physical)}async function so(e){let t=await po(e,`platform-tools`,K.platform===`win32`?`adb.exe`:`adb`),{stdout:n}=await z(t,[`devices`],{env:e}),r=n.split(/\r?\n/).map(e=>e.match(/^(\S+)\s+device(?:\s|$)/)?.[1]).filter(e=>e!==void 0);return(await Promise.all(r.map(async n=>{let r=await ho(t,e,n,`ro.product.model`),i=n.startsWith(`emulator-`),a=i?await _o(t,e,n,r):await vo(t,e,n,r);return{id:n,label:a===r?a:`${a} (${r})`,name:a,physical:!i}}))).sort(Co)}async function co(e){let{stdout:t}=await z(await po(e,`emulator`,K.platform===`win32`?`emulator.exe`:`emulator`),[`-list-avds`],{env:e});return t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0&&!/^(INFO|WARNING|ERROR)\s+\|/.test(e)).map(e=>({id:e,label:e,name:e,physical:!1}))}async function lo(e){let t=await $.mkdtemp(F.join(Wa.tmpdir(),`coreframe-ios-devices-`)),n=F.join(t,`devices.json`);try{return await $.writeFile(n,``),await z(`xcrun`,[`devicectl`,`list`,`devices`,`--json-output`,n],{env:e}),(JSON.parse(await $.readFile(n,`utf8`)).result?.devices??[]).filter(fo).map(e=>({id:e.hardwareProperties.udid,label:`${e.deviceProperties.name} (${e.hardwareProperties.productType})`,name:e.deviceProperties.name,physical:!0})).sort(Co)}finally{await $.rm(t,{force:!0,recursive:!0})}}async function uo(e,t=`available`){let{stdout:n}=await z(`xcrun`,[`simctl`,`list`,`--json`,`devices`,t],{env:e}),r=JSON.parse(n);return Object.entries(r.devices??{}).filter(([e])=>e.includes(`iOS-`)).flatMap(([,e])=>e).flatMap(e=>e.name&&e.udid?[{id:e.udid,label:e.name,name:e.name,physical:!1}]:[]).sort(Co)}function fo(e){return e.connectionProperties?.tunnelState!==`unavailable`&&typeof e.hardwareProperties?.platform==`string`&&(e.hardwareProperties.platform.includes(`iOS`)||e.hardwareProperties.platform.includes(`xrOS`))&&typeof e.deviceProperties?.name==`string`&&typeof e.hardwareProperties.productType==`string`&&typeof e.hardwareProperties.udid==`string`}async function po(e,t,n){let r=e.ANDROID_HOME??e.ANDROID_SDK_ROOT,i=r?[r]:mo(e);for(let e of i){let r=F.join(e,t,n);try{return await $.access(r),r}catch{}}return n}function mo(e){return K.platform===`darwin`?[F.join(Wa.homedir(),`Library`,`Android`,`sdk`)]:K.platform===`win32`&&e.LOCALAPPDATA?[F.join(e.LOCALAPPDATA,`Android`,`Sdk`)]:[F.join(Wa.homedir(),`Android`,`Sdk`)]}async function ho(e,t,n,r){return(await go(e,t,[`-s`,n,`shell`,`getprop`,r])).trim()}async function go(e,t,n){return(await z(e,n,{env:t,timeout:3e3})).stdout}async function _o(e,t,n,r){return go(e,t,[`-s`,n,`emu`,`avd`,`name`]).then(e=>e.split(/\r?\n/)[0]?.trim()||r).catch(()=>r)}async function vo(e,t,n,r){return go(e,t,[`-s`,n,`shell`,`dumpsys`,`bluetooth_manager`]).then(e=>yo(e)||r).catch(()=>r)}function yo(e){return e.match(/\bname: (.+)/)?.[1]?.trim()}function bo(e,t){let n=e.map(e=>({device:e,score:Math.max(xo(t,e.name),xo(t,e.id))})).sort((e,t)=>t.score-e.score)[0];return n&&n.score>0?n.device:void 0}function xo(e,t){let n=e.toLowerCase(),r=t.toLowerCase();if(r===n)return 1e4;let i=r.indexOf(n);if(i>=0)return 5e3-i;let a=0,o=0;for(let e of n){let t=r.indexOf(e,o);if(t<0)return 0;a+=t===o?2:1,o=t+1}return a}function So(){return[...new Set(Object.values(Wa.networkInterfaces()).flatMap(e=>e??[]).filter(e=>!e.internal&&e.family===`IPv4`).map(e=>e.address))].sort()}function Co(e,t){return e.label.localeCompare(t.label)}function wo({host:e=`127.0.0.1`,port:t,start:n}){let r,i=!1,a=!1,o=!1,s,c,l,u,d,f=new Set,p=new Promise((e,t)=>{u=e,d=t}),m=e=>{a||o||(o=!0,d(e))},h=()=>(s||=Promise.resolve().then(n).catch(e=>{throw m(e),e}),s),g=e=>{f.add(e),e.once(`close`,()=>f.delete(e)),e.pause(),_(e).catch(t=>{m(t),e.destroy()})},_=async e=>{let t=await h();if(a||e.destroyed)return;let n=await To(t,()=>a);if(a||e.destroyed){n.destroy();return}f.add(n),n.once(`close`,()=>f.delete(n)),n.on(`error`,()=>e.destroy()),n.once(`close`,()=>e.destroy()),e.on(`error`,()=>n.destroy()),e.once(`close`,()=>n.destroy()),e.pipe(n),n.pipe(e)};return{close:async()=>l||(l=(async()=>{a=!0,o||(o=!0,u());for(let e of f)e.destroy();f.clear(),c&&!i&&await Promise.allSettled([c]),!(!r||!i)&&(await new Promise(e=>{r.close(()=>e())}),i=!1)})(),l),fail:m,listen:async()=>c||(r=Kt(g),c=new Promise((n,a)=>{let o=e=>{if(i){m(e);return}a(e)};r.once(`error`,o),r.once(`listening`,()=>{i=!0,r.off(`error`,o),r.on(`error`,m),n()}),r.listen(t,e)}),c),wait:()=>p}}async function To(e,t){let n=Date.now()+1e4,r;for(;!t();)try{return await Eo(e)}catch(e){if(r=e,Date.now()>=n)break;await new Promise(e=>setTimeout(e,50))}throw r instanceof Error?r:Error(`Could not connect to the dashboard.`)}function Eo({host:e=`127.0.0.1`,port:t}){return new Promise((n,r)=>{let i=Gt({host:e,port:t}),a=e=>{i.off(`connect`,o),i.destroy(),r(e)},o=()=>{i.off(`error`,a),n(i)};i.once(`error`,a),i.once(`connect`,o)})}const Do={command:Uo,isRunning:Po,stop(e){try{K.kill(e,`SIGTERM`)}catch(e){if(!Lo(e))throw e}},waitForExit:Fo};async function Oo({confirmStop:e=jo,cwd:t=K.cwd(),interactive:n=K.stdin.isTTY===!0,pid:r=K.pid,platform:i=`web`,processes:a=Do}={}){let o=await Ko(t,i),s=o.file,c={pid:r,platform:i,repository:o.repository,token:G()},l=`${JSON.stringify(c)}\n`,u=`${s}.${c.token}.tmp`,d=await zo({confirmStop:e,file:F.resolve(t,`.coreframe/dev.lock`),interactive:n,owner:c,processes:a});if(d===void 0)return;let f=d;await V(F.dirname(s),{recursive:!0}),await W(u,l,{flag:`wx`,mode:384});try{for(;;){try{return await we(u,s),{owner:c,async release(){await No(s,l)},takeoverApproved:f}}catch(e){if(!Io(e))throw e}let t=await Ao({confirmStop:e,file:s,interactive:n,owner:c,processes:a});if(t===void 0)return;f||=t}}finally{await Ae(u).catch(()=>void 0)}}async function ko({cwd:e=K.cwd(),platform:t=`web`}={}){let{file:n}=await Ko(e,t);return(await Mo(n))?.owner}async function Ao({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await Mo(t);if(!a||!Xo(a.owner,r)||!i.isRunning(a.owner.pid))return await No(t,a?.source),!1;if(!n)throw Error(`Coreframe dev is already running for this project (PID ${a.owner.pid}). Stop it before starting another.`);if(await e(a.owner.pid))return i.stop(a.owner.pid),await i.waitForExit(a.owner.pid),await No(t,a.source),!0}async function jo(e){let t=await B.confirm({initialValue:!1,message:`Coreframe dev is already running for this project (PID ${e}). Stop it and start here?`});return B.isCancel(t)||!t?(B.cancel(`Keeping the existing Coreframe dev process.`),!1):!0}async function Mo(e){try{let t=await H(e,`utf8`),n=JSON.parse(t);return!Number.isSafeInteger(n.pid)||Number(n.pid)<=0||typeof n.platform!=`string`||n.platform.length===0||typeof n.repository!=`string`||n.repository.length===0||typeof n.token!=`string`||n.token.length===0?void 0:{owner:n,source:t}}catch{return}}async function No(e,t){let n=await H(e,`utf8`).catch(()=>void 0);(t===void 0||n===t)&&await Ae(e).catch(()=>void 0)}function Po(e){try{return K.kill(e,0),!0}catch(e){return!Lo(e)}}async function Fo(e){let t=Date.now()+1e4;for(;Po(e);){if(Date.now()>=t)throw Error(`Coreframe dev process ${e} did not stop within 10 seconds.`);await new Promise(e=>setTimeout(e,50))}}function Io(e){return Ro(e)&&e.code===`EEXIST`}function Lo(e){return Ro(e)&&e.code===`ESRCH`}function Ro(e){return e instanceof Error}async function zo({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await Bo(t);if(!a||!i.isRunning(a.owner.pid))return await No(t,a?.source),!1;let o=i.command?.(a.owner.pid);if(!o||!Vo(o,r.platform))return!1;if(!n)throw Error(`Coreframe dev is already running for this project (PID ${a.owner.pid}). Stop it before starting another.`);if(await e(a.owner.pid))return i.stop(a.owner.pid),await i.waitForExit(a.owner.pid),await No(t,a.source),!0}async function Bo(e){try{let t=await H(e,`utf8`),n=JSON.parse(t);return!Number.isSafeInteger(n.pid)||Number(n.pid)<=0||typeof n.token!=`string`||n.token.length===0?void 0:{owner:n,source:t}}catch{return}}function Vo(e,t){let n=e.trim().split(/\s+/u),r=n.findIndex(e=>{let t=e.split(/[\\/]/u).at(-1);return t===`coreframe`||t===`coreframe.js`||t===`coreframe.ts`});if(r<0)return!1;let i=n.indexOf(`dev`,r+1);return i<0?!1:Ho(n.slice(i+1))===t}function Ho(e){let t=new Set([`android`,`desktop`,`ios`,`macos`,`web`]),n=new Set([`--debug`,`--host`,`--port`]),r=!1;for(let i of e){if(r){r=!1;continue}if(n.has(i)){r=!0;continue}if(!i.startsWith(`-`))return t.has(i)?i:`web`}return`web`}function Uo(e){let t=K.platform===`win32`?Go(e):Wo(e);if(t.status===0)return t.stdout.trim()||void 0}function Wo(e){return q(`ps`,[`-p`,String(e),`-o`,`command=`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}function Go(e){return q(`powershell.exe`,[`-NoProfile`,`-NonInteractive`,`-Command`,`(Get-CimInstance Win32_Process -Filter 'ProcessId = ${e}').CommandLine`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}async function Ko(e,t){let n=await qo(F.resolve(e)),r=n.gitCommonDir?F.join(n.path,`coreframe-dev`):F.join(n.path,`.coreframe`);return{file:F.join(r,`dev.${t}.lock`),repository:n.path}}async function qo(e){let t=Jo(e);return t?{gitCommonDir:!0,path:await Yo(F.resolve(e,t))}:{gitCommonDir:!1,path:await Yo(e)}}function Jo(e){let t=q(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]});if(t.status===0)return t.stdout.trim()||void 0}async function Yo(e){return De(e).catch(()=>F.resolve(e))}function Xo(e,t){return e.platform===t.platform&&e.repository===t.repository}function Zo(e,t){let n={...e};return t===`desktop`?delete n.COREFRAME_PLATFORM:t===`web`||t===`webext`?n.COREFRAME_PLATFORM=`web`:n.COREFRAME_PLATFORM=t,n}const Qo=K.platform===`win32`?`portless.cmd`:`portless`;async function $o({cwd:e,env:t,platform:n}){return n!==`web`||t.PORTLESS===`0`||t.TAURI_ENV_PLATFORM!==void 0||(await Jt()).isAgent?!1:Pt(e)}async function es({cwd:e,env:t,lan:n=!1}){let r=F.join(`node_modules`,`.bin`,Qo),i=[`proxy`,`start`,...n?[`--lan`]:[]];await z(F.resolve(e,r),i,{cwd:e,env:t,stdio:`inherit`})}function ts({host:e,lan:t=!1,port:n}){return[...t?[`--lan`]:[],`run`,...n===void 0?[]:[`--app-port`,String(n)],`react-router`,`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e]]}async function ns({cwd:e=K.cwd(),platform:t}){let n=await rs({cwd:e});if(!n||!fs(n.platform)||!ps(n.platform,t)||!hs(n.owner.pid))return;let r=await ko({cwd:e,platform:n.platform});if(!(!r||!gs(n.owner,r))&&!(n.postgres?.pid!==void 0&&!hs(n.postgres.pid)))return n}async function rs({cwd:e=K.cwd()}={}){let t;try{t=JSON.parse(await H(os(e),`utf8`))}catch{return}return ss(t)&&t.cwd===F.resolve(e)?t:void 0}async function is({cwd:e=K.cwd(),owner:t,platform:n,postgres:r,vitePort:i}){let a=os(e),o=F.dirname(a),s=`${a}.${G()}.tmp`,c={cwd:F.resolve(e),owner:t,platform:n,...r?{postgres:r}:void 0,version:1,vite:{port:i}};await V(o,{recursive:!0});try{await W(s,`${JSON.stringify(c)}\n`,{flag:`wx`,mode:384}),await Oe(s,a)}finally{await Ae(s).catch(()=>void 0)}}async function as({cwd:e=K.cwd(),owner:t}){let n=os(e),r=await rs({cwd:e});!r||!gs(r.owner,t)||await Ae(n).catch(()=>void 0)}function os(e){return F.resolve(e,`.coreframe/dev.session.json`)}function ss(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.version===1&&typeof t.cwd==`string`&&cs(t.owner)&&us(t.platform)&&ms(t.vite?.port)&&(t.postgres===void 0||ls(t.postgres))}function cs(e){if(!e||typeof e!=`object`)return!1;let t=e,n=t.pid;return typeof n==`number`&&Number.isSafeInteger(n)&&n>0&&typeof t.token==`string`}function ls(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.dataDir==`string`&&(t.pid===void 0||Number.isSafeInteger(t.pid)&&t.pid>0)}function us(e){return e===`android`||e===`desktop`||e===`ios`||e===`macos`||e===`web`}function ds(e){return e===`android`||e===`ios`||e===`macos`}function fs(e){return e===`web`||ds(e)}function ps(e,t){return t===void 0?ds(e):e===t}function ms(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0&&e<=65535}function hs(e){try{return K.kill(e,0),!0}catch(e){return e instanceof Error&&e.code===`EPERM`}}function gs(e,t){return e.pid===t.pid&&e.token===t.token}const _s=K.platform===`win32`?`pnpm.cmd`:`pnpm`,vs=K.platform===`win32`?`portless.cmd`:`portless`,ys=K.platform===`win32`?`react-router.cmd`:`react-router`;async function bs({cwd:e=K.cwd(),debug:t,device:n,env:r=K.env,host:i,https:a=!1,interactive:o=K.stdin.isTTY===!0,lan:s=!1,managed:c=!1,noManaged:l=!1,platform:u=`web`,portless:d,fresh:f=!1,reuseVite:p=!1,verbose:m=!1,webPort:h,supervisor:g}){let _=At({env:r}),v=Es(u)?u:void 0,y=Ds(u),b=u===`ios`||u===`android`?u:void 0,x=b?await Za({env:r,interactive:o,platform:b,target:n}):void 0,S=b&&x?await Qa({device:x,host:i,interactive:o,platform:b}):void 0,C=v?!0:i,w=await _.measure(`config`,()=>Le({cwd:e})),T=await _.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(c||o&&!l)&&await Nt(e));await _.measure(`i18n`,()=>Kn({cwd:e,projectConfig:w}));let E=await _.measure(`routing`,async()=>d??await $o({cwd:e,env:r,platform:u})),ee=await _.measure(`https`,async()=>a&&!E?Ft({cwd:e}):void 0),D=Zo(r,u),O={...D,..._.environment,...T?{[Vt]:`1`,[Ht]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...v?{COREFRAME_PLATFORM:v}:void 0,...ee?{[jt]:ee.cert,[Mt]:ee.key}:void 0},k=!1,A,te,j,ne,M,re,N,ae=new Map,oe=[`postgres`,`sqlite`,y];for(let e of oe){let t=e===`postgres`||e===`sqlite`?e:e.startsWith(`vite:flutter`)?`flutter`:`web`,n=Ut({label:t}),r=Ut({color:`red`,label:t});n.pipe(K.stdout,{end:!1}),r.pipe(K.stderr,{end:!1}),ae.set(e,{stderr:r,stdout:n})}let se=g.onEvent(e=>{e.event===`log`?(ae.get(e.resource)?.[e.stream])?.write(e.data):e.event===`service`&&e.resource===y&&(e.state===`failed`||e.state===`stopped`)&&(e.state===`failed`&&(N=Error(e.error??`${y} development failed.`)),P())}),P=()=>{k||(k=!0,j?.kill(`SIGTERM`),te?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0))},ce=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>{A??=e,P()};return K.on(e,t),{handler:t,signal:e}}),I=async e=>{let t=Wt(e);j=t;try{await t.expectSuccess()}catch(e){if(!k)throw e}finally{j===t&&(j=void 0)}};try{if(await g.subscribe(oe),Ts(w)){let e=await g.acquirePostgres({config:w,env:O});ne=e.leaseId,O={...O,...e.env}}if(w.database?.dialect===`sqlite`){let e=await g.acquireSqlite({config:w,env:O});M=e.leaseId,O={...O,...e.env}}(Ts(w)||w.database?.dialect===`sqlite`)&&await _.measure(`schema`,()=>I({name:`db`,command:_s,args:[`db`,`ensure`],cwd:e,env:O,prefix:!1}));let t=ws(h??r.COREFRAME_WEB_PORT),n=await g.status(),i=n.resources?.find(e=>e.resource===y),c=i!==void 0&&!f&&t===void 0?void 0:t??5173,l=c??i?.endpoint?.port??5173;if(c!==void 0&&n.resources?.some(e=>e.resource!==y&&e.endpoint?.port===l)){if(t!==void 0)throw Error(`Port ${l} is already used by another Coreframe development shell.`);l=await Ua.getAvailablePort()}if(!p){let t={...O,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[O.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:F.join(e,`node_modules`,`.bin`)+F.delimiter+(O.PATH??``)},n=[{args:E?ts({host:C,lan:s,port:l}):[`dev`,...C===void 0?[]:[`--host`,C===!0?`0.0.0.0`:C],`--port`,String(l),...v?[`--strictPort`]:[]],command:E?vs:ys,cwd:e,env:t},{args:[`exec`,`panda`,`dev`,`--no-color`],command:_s,cwd:e,env:O}],r=await g.acquireVite({configFingerprint:Cs({cwd:e,host:C,lan:s,https:a,portless:E,resource:y}),endpoint:{host:C===!0?`0.0.0.0`:C??`127.0.0.1`,port:l},processes:n,resource:y},f);re=r.leaseId,l=r.endpoint.port}if(_.report(),k)return;if(u===`web`?await Ss(g,y,()=>N):(await ie({cwd:e}),await xs({cwd:e,env:D,interactive:o,mobileHost:S,platform:u,port:l,requestStop:P,selectedDevice:x,isStopping:()=>k,setActiveNative:e=>{te=e},verbose:m})),N)throw N}finally{P(),re&&await g.release(re).catch(()=>void 0),ne&&await g.release(ne).catch(()=>void 0),M&&await g.release(M).catch(()=>void 0),se();for(let{handler:e,signal:t}of ce)K.off(t,e);for(let e of ae.values())e.stdout.end(),e.stderr.end();A&&(K.exitCode??=A===`SIGINT`?130:143),g.close()}}async function xs({cwd:e,env:t,interactive:n,mobileHost:r,platform:i,port:a,requestStop:o,selectedDevice:s,isStopping:c,setActiveNative:l,verbose:u}){for(;;){let d=i===`android`&&!u?await se():void 0,f=z(`flutter`,[`run`,`-d`,s?.id??`macos`,`--dart-define=COREFRAME_DEV_SERVER_URL=${Os(i,r,a)}`,...u?[`--verbose`]:[]],{cwd:F.join(e,`src-flutter`),env:t,stdio:d?[`inherit`,`pipe`,`pipe`]:`inherit`});l(f);try{await Promise.all([f,d?.capture(f)]);return}catch(e){if(c()||i===`desktop`||!n)throw e;let t=await B.confirm({initialValue:!0,message:`Flutter failed. Retry?`});if(B.isCancel(t)||!t){o();return}}finally{l(void 0)}}}async function Ss(e,t,n){await e.waitForServiceExit(t);let r=n();if(r)throw r}function Cs({cwd:e,host:t,lan:n,https:r,portless:i,resource:a}){return ze(`sha256`).update(JSON.stringify({cwd:F.resolve(e),host:t??null,lan:n,https:r,portless:i,resource:a})).digest(`hex`)}function ws(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}function Ts(e){return(e.database?.dialect??`postgres`)===`postgres`}function Es(e){return e===`android`||e===`ios`||e===`macos`}function Ds(e){if(e===`web`)return`vite:web`;if(Es(e))return`vite:flutter:${e}`;throw Error(`Unsupported supervised development platform: ${e}.`)}function Os(e,t,n){let r=t??(e===`android`?`10.0.2.2`:`127.0.0.1`);return`http://${r.includes(`:`)&&!r.startsWith(`[`)?`[${r}]`:r}:${n}`}const ks=`extension:dev`;function As(e){if(!J(L(e,`src-webext/wxt.config.ts`)))throw Error("No WXT configuration found at src-webext/wxt.config.ts. Apply the wxt recipe or add that convention before running `coreframe dev webext`.");let t=L(e,`package.json`),n;try{n=JSON.parse(Y(t,`utf8`))}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}if(!n||typeof n!=`object`||!(`scripts`in n)||!n.scripts||typeof n.scripts!=`object`||!(`extension:dev`in n.scripts)||typeof n.scripts[`extension:dev`]!=`string`)throw Error(`package.json must define scripts.${ks} for \`coreframe dev webext\`. Apply the wxt recipe and add its named extension lifecycle scripts.`)}function js({host:e,port:t}){let n=[...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)]];return[`run`,ks,...n.length>0?[`--`,...n]:[]]}const Ms=[`web`,`webext`,`desktop`,`ios`,`android`,`macos`],Ns=[`managed-dev-overlay`],Ps=F.resolve(`node_modules`,`.bin`),Fs=K.platform===`win32`?`pnpm.cmd`:`pnpm`,Is=K.platform===`win32`?`portless.cmd`:`portless`,Ls=K.platform===`win32`?`react-router.cmd`:`react-router`;async function Rs({cwd:e=K.cwd(),debug:t,device:n,env:r=K.env,host:i,https:a=!1,interactive:o=K.stdin.isTTY===!0,lan:s=!1,managed:c=!1,noManaged:l=!1,platform:u=`web`,fresh:d=!1,reuseVite:f=!1,supervisor:p,verbose:m=!1,webPort:h}={}){let g=At({env:r}),_=r.PATH??r.Path??``,v=u===`ios`||u===`android`||u===`macos`?u:void 0,y=u===`web`||v!==void 0;if(d&&f)throw Error(`Cannot use --fresh and --reuse-vite together.`);let b=!d&&(v||u===`web`)?await g.measure(`dev-session`,()=>ns({cwd:e,platform:u})):void 0,x=f||b!==void 0,S=u===`desktop`?void 0:Xs(h??r.COREFRAME_WEB_PORT);if(b&&S!==void 0&&S!==b.vite.port)throw Error(`The active development session uses port ${b.vite.port}. Omit --port or use that port when reusing it.`);let C=u===`ios`||u===`android`||u===`macos`?b?.vite.port??S??5173:u===`web`||u===`webext`?b?.vite.port??S:void 0,w,T,E,ee,D,O,k,A,te,j,M=!1,re,N=r,ae,oe;if(c&&l)throw Error(`Cannot use --managed and --no-managed together.`);if(t===`managed-dev-overlay`&&c)throw Error(`Cannot use --managed with --debug managed-dev-overlay.`);if(f&&v===void 0)throw Error(`The --reuse-vite option is only supported for Flutter development platforms (iOS, Android, and macOS).`);if(u===`webext`){if(c||l||t!==void 0||m)throw Error(`Managed development, debug features, and verbose native output are only supported for the main web or native development platforms.`);As(e)}if(a&&u!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(n!==void 0&&u!==`ios`&&u!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);if(u===`web`&&r.TAURI_ENV_PLATFORM!==void 0&&r.COREFRAME_TAURI_DEV!==`1`)throw Error("Direct Tauri development is not supported. Run `pnpm dev desktop` instead.");let P=await g.measure(`routing`,()=>$o({cwd:e,env:r,platform:u}));if(P&&await g.measure(`portless`,()=>es({cwd:e,env:r,lan:s})),y&&r.COREFRAME_DEV_SUPERVISOR!==`0`){let g=p??await kt({cwd:e,env:r});if(g)return bs({cwd:e,debug:t,device:n,env:r,fresh:d,host:i,https:a,interactive:o,lan:s,managed:c,noManaged:l,platform:u,portless:P,reuseVite:f,supervisor:g,verbose:m,webPort:h})}let ce=x?void 0:await g.measure(`dev-lock`,()=>Oo({cwd:e,interactive:o,platform:u}));if(!x&&!ce)return;let I=()=>{M||(M=!0,T?.kill(`SIGTERM`),O?.kill(`SIGTERM`),k?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),A?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),j?.close().catch(()=>void 0),te?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),w?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),le().catch(()=>void 0))},le=()=>ee?(D??=ee[Symbol.asyncDispose](),D):Promise.resolve(),L=e=>{re??=e,I()},ue=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>L(e);return K.on(e,t),{handler:t,signal:e}}),R=async e=>{let t=Wt(e);T=t;try{await t.expectSuccess()}catch(e){if(!M)throw e}finally{T===t&&(T=void 0)}};try{let d=u===`ios`||u===`android`?u:void 0,f=d?await Za({env:r,interactive:o,platform:d,target:n}):void 0,p=d&&f?await Qa({device:f,host:i,interactive:o,platform:d}):void 0,h=v?!0:i,y={},b=!1,S;x||([y,b]=await Promise.all([g.measure(`config`,()=>Le({cwd:e})),g.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(c||o&&!l)&&await Nt(e))]),await g.measure(`i18n`,()=>Kn({cwd:e,projectConfig:y})),S=u!==`webext`&&zs(e)?await Ua.getAvailablePort():void 0);let T=x?void 0:await g.measure(`https`,async()=>a&&!P?Ft({cwd:e}):void 0),D=Zo(r,u);N={...D,...g.environment,...b?{[Vt]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...u===`desktop`?{COREFRAME_TAURI_DEV:`1`,TAURI_ENV_PLATFORM:Js()}:void 0,...v?{COREFRAME_PLATFORM:v}:void 0,...T?{[jt]:T.cert,[Mt]:T.key}:void 0,...S?{COREFRAME_DASHBOARD_ORIGIN:`http://127.0.0.1:${S}`}:void 0};let re=async()=>{if(!S)return;let t,n=async(e,n)=>{try{await e,M||t?.fail(Error(`The dashboard development server stopped unexpectedly.`))}catch(e){M||t?.fail(e)}finally{await n.outputTasks,n.stdout.end(),n.stderr.end(),await Promise.allSettled([Bt(n.stdout),Bt(n.stderr)]),te===e&&(te=void 0)}};t=wo({port:S,start:async()=>{if(M)throw Error(`The dashboard development server was stopped before it started.`);let t=await Ua.getAvailablePort();if(M)throw Error(`The dashboard development server was stopped before it started.`);let r=Ut({label:`dashboard`}),i=Ut({color:`red`,label:`dashboard`});r.pipe(K.stdout,{end:!1}),i.pipe(K.stderr,{end:!1});let a=z(Ls,[`dev`,`--host`,`127.0.0.1`,`--port`,String(t)],{cwd:F.resolve(e,`dashboard`),env:{...N,PATH:F.resolve(e,`node_modules/.bin`)+F.delimiter+_},stdin:`inherit`});te=a;let o=Promise.allSettled([Bs(a.stdout,r),Bs(a.stderr,i)]);return n(a,{outputTasks:o,stderr:i,stdout:r}),{host:`127.0.0.1`,port:t}}}),j=t;try{await t.listen(),await t.wait()}finally{await t.close(),j===t&&(j=void 0)}},le=async()=>{let t=Ut({label:`web`}),n=Ut({color:`red`,label:`web`});t.pipe(K.stdout,{end:!1}),n.pipe(K.stderr,{end:!1}),k=z(P?Is:Ls,P?ts({host:h,lan:s,port:C}):Ys({host:h,port:C,strictPort:v!==void 0}),{cwd:e,env:{...N,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[N.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:Ps+F.delimiter+_},stdin:`inherit`});let r=Promise.allSettled([Bs(k.stdout,t),Bs(k.stderr,n)]);try{await k;let e=(await r).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!M)throw e}finally{await r,t.end(),n.end(),await Promise.allSettled([Bt(t),Bt(n)]),k=void 0}},L=async()=>{let t=Ut({label:`webext`}),n=Ut({color:`red`,label:`webext`});t.pipe(K.stdout,{end:!1}),n.pipe(K.stderr,{end:!1}),A=z(Fs,js({host:i,port:C}),{cwd:e,env:N,stdin:`inherit`});let r=Promise.allSettled([Bs(A.stdout,t),Bs(A.stderr,n)]);try{await A;let e=(await r).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!M)throw e}finally{await r,t.end(),n.end(),await Promise.allSettled([Bt(t),Bt(n)]),A=void 0}},ue=async t=>{for(;!M;){let n=u===`android`&&!m?await se():void 0,r=u===`desktop`?z(Fs,Gs(),{cwd:e,env:D,stdio:`inherit`}):z(`flutter`,Ks({device:f??{id:`macos`},serverUrl:qs(u,p,C),verbose:m}),{cwd:F.join(e,`src-flutter`),env:D,stdio:n?[`inherit`,`pipe`,`pipe`]:`inherit`});w=r;try{await Promise.all([r,n?.capture(r)]);return}catch(e){if(u===`desktop`||M||!o)throw e;let n=await B.confirm({initialValue:!0,message:`Flutter failed. Retry?`});if(B.isCancel(n)||!n){B.log.warn(t?`Flutter stopped. Web development is still running.`:`Flutter stopped.`),t&&await t;return}}finally{w===r&&(w=void 0)}}},de=async()=>{if(x){if(u===`web`)return;await ie({cwd:e}),await ue();return}if(u===`web`){await le();return}let t=le().then(()=>{if(!M)throw Error(`The Vite development server stopped while ${u===`desktop`?`Tauri`:`Flutter`} was still running.`)});u!==`desktop`&&await ie({cwd:e});try{await Promise.race([t,ue(t)])}finally{I(),await Promise.allSettled([t,w]),w=void 0}},fe=async()=>{let t=Wt({name:`panda`,command:Fs,args:[`exec`,`panda`,`dev`,`--no-color`],cwd:e,env:N});O=t;try{if(await t.expectSuccess(),!M)throw Error(`The Panda CSS watcher stopped while development was still running.`)}catch(e){if(!M)throw e}finally{O===t&&(O=void 0)}},pe=async()=>{if(u===`webext`){await L();return}if(x){await de();return}let e=fe(),t=de(),n=S?re():void 0;try{await Promise.race([e,t,n].filter(e=>e!==void 0)),M&&await t}finally{I(),await Promise.allSettled([e,t,n].filter(e=>e!==void 0))}},me=async()=>{x||!ce?.owner||C===void 0||(await is({cwd:e,owner:ce.owner,platform:u,postgres:oe,vitePort:C}),ae=ce.owner)};if(b&&(N={...N,[Ht]:`1`}),M)return;if(u===`webext`){g.report(),await pe();return}if(x){g.report(),await pe();return}if(y.database?.dialect===`sqlite`&&(await g.measure(`database`,async()=>{let t=await ne({config:y,cwd:e,env:r,tursoOutput:K.stdout,useSupervisorLease:!0});ee=t,N={...N,...t.env}}),await g.measure(`schema`,()=>R({name:`db`,command:Fs,args:[`db`,`ensure`],cwd:e,env:N,prefix:!1})),M))return;if(Ws(y)){let t=Ut({label:`postgres`});t.pipe(K.stdout,{end:!1});try{let n=await g.measure(`database`,()=>Us({config:y,cwd:e,env:N,failIfRunning:!0,interactive:o,isStopping:()=>M,postgresOutput:t,takeoverApproved:ce?.takeoverApproved??!1}));if(!n)return;E=n,N=n.env,oe=await Hs(n.env);try{M||await g.measure(`schema`,()=>R({name:`db`,command:Fs,args:[`db`,`ensure`],cwd:e,env:N,prefix:!1})),M||(await me(),g.report(),await pe())}finally{await n[Symbol.asyncDispose](),E===n&&(E=void 0)}}finally{t.end()}return}await me(),g.report(),await pe()}finally{I(),ae&&=(await as({cwd:e,owner:ae}),void 0);let t;try{await E?.[Symbol.asyncDispose]()}catch(e){t=e}finally{await le();for(let{handler:e,signal:t}of ue)K.off(t,e);re&&(K.exitCode??=re===`SIGINT`?130:143)}Vs(t),await ce?.release()}}function zs(e){return J(F.resolve(e,`dashboard/dashboard.config.ts`))}async function Bs(e,t){for await(let n of e)t.write(`${n}\n`)||await zt(t,`drain`)}function Vs(e){if(e)throw e}async function Hs(e){let t=e.PGDATA;if(!t)return;let n=Number((await $.readFile(F.join(t,`postmaster.pid`),`utf8`).catch(()=>``)).split(/\r?\n/,1)[0]);return{dataDir:F.resolve(t),...Number.isSafeInteger(n)&&n>0?{pid:n}:void 0}}async function Us({interactive:e,isStopping:t,takeoverApproved:n,...r}){try{return await j(r)}catch(i){if(!(i instanceof m)||!e)throw i;if(!n){let e=await B.confirm({initialValue:!1,message:`PostgreSQL is already running for this project (PID ${i.pid}). Stop it and start here?`});if(B.isCancel(e)||!e){B.cancel(`Keeping the existing PostgreSQL process.`);return}}return await M(i),t()?void 0:j(r)}}function Ws(e){return(e.database?.dialect??`postgres`)===`postgres`}function Gs(){return[`exec`,`tauri`,`dev`,`--config`,JSON.stringify({build:{beforeDevCommand:``}})]}function Ks({device:e,serverUrl:t,verbose:n}){return[`run`,`-d`,e.id,`--dart-define=COREFRAME_DEV_SERVER_URL=${t}`,...n?[`--verbose`]:[]]}function qs(e,t,n){let r=t??(e===`android`?`10.0.2.2`:`127.0.0.1`);return`http://${r.includes(`:`)&&!r.startsWith(`[`)?`[${r}]`:r}:${n}`}function Js(){return K.platform===`win32`?`windows`:K.platform}function Ys({host:e,port:t,strictPort:n=!1}){return[`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)],...n?[`--strictPort`]:[]]}function Xs(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}async function Zs(e={}){let t=e.cwd??K.cwd(),n=await Fe(`scripts/preview.ts`,t);if(typeof n.default!=`function`)throw Error(`scripts/preview.ts must export a default preview function.`);return Yt({...e,cwd:t},n.default)}const Qs=`worker-configuration.d.ts`;async function $s({check:e=!1,cwd:t=process.cwd()}={}){let n=await Le({cwd:t}),r=await rt({coreframeConfig:n,cwd:t}),i=R(t,Qs),a=R(t,`.coreframe-worker-types-${G()}.d.ts`);try{try{await z(`pnpm`,[`exec`,`wrangler`,`types`,a,`--config`,r.path,`--strict-vars=false`,`--include-runtime=false`],{cwd:t,stdio:[`ignore`,`pipe`,`pipe`]})}catch(e){throw ec(e),e}let o=tc(await H(a,`utf8`)),s=Re(r.config),c=Ie(n.worker?.environment).filter(e=>!s.has(e.name)),l=`${o.trimEnd()}\n\n${nc(c)}\n`;if(e){if(await H(i,`utf8`).catch(()=>``)!==l)throw Error(`${Qs} is stale. Run "coreframe worker typegen" and commit the result.`);return{changed:!1,path:i}}let u=await H(i,`utf8`).catch(()=>``);return u!==l&&await W(i,l),{changed:u!==l,path:i}}finally{await r.dispose(),await U(a,{force:!0})}}function ec(e){if(typeof e!=`object`||!e||!(`output`in e))return;let{output:t}=e;typeof t!=`string`||t===``||process.stderr.write(t.endsWith(`
12
12
  `)?t:`${t}\n`)}function tc(e){return e.split(/\r?\n/).filter(e=>!e.startsWith(`// Generated by Wrangler by running `)).join(`
13
13
  `)}function nc(e){return[`// Coreframe application string inventory declaration-merges with Wrangler's generated Env.`,`interface Env {`,...e.map(e=>` /** ${e.description.replaceAll(`*/`,`*\\/`)} */\n ${JSON.stringify(e.name)}?: string`),`}`].join(`
14
- `)}const rc=new Set([`.coreframe`,`.git`,`.react-router`,`.wrangler`,`.wxt`,`build`,`dist`,`node_modules`,`styled-system`,`target`]),ic=[`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`,`react-router.config.ts`,`src/web`],ac=[`dashboard`,`node_modules/@coreframe/dashboard/dist/package/app`,`node_modules/@coreframe/dashboard/package.json`,`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`],oc=[`coreframe.config.ts`,`node_modules/@coreframe/config/dist`,`node_modules/@coreframe/config/package.json`,`node_modules/@coreframe/deploy/dist`,`node_modules/@coreframe/deploy/package.json`,`node_modules/wrangler/package.json`,`package.json`,`pnpm-lock.yaml`,`src/api`,`wrangler.jsonc`],sc=`.coreframe/typegen.json`,cc=[`web`,`dashboard`,`worker`];async function lc({checkWorker:e=!1,cwd:t=G.cwd(),runners:n={}}={}){let r=await pc(t)??{generators:{},schemaVersion:1},i=[];return i.push(await dc({cwd:t,inputPaths:ic,name:`web`,outputPath:`.react-router`,run:()=>(n.web??fc)(t),state:r})),i.push(await dc({cwd:t,inputPaths:ac,name:`dashboard`,outputPath:`dashboard/.react-router`,run:()=>(n.dashboard??hr)(t),state:r})),i.push(await dc({cwd:t,inputPaths:oc,name:`worker`,outputPath:`worker-configuration.d.ts`,run:()=>(n.worker??$s)({check:e,cwd:t}),state:r})),i}function uc(e){return`${{dashboard:`Dashboard route types`,web:`Web route types`,worker:`Worker types`}[e.name]} ${e.changed?`generated`:`unchanged`}.`}async function dc({cwd:e,inputPaths:t,name:n,outputPath:r,run:i,state:a}){let o=await hc(e,t),s=await gc(e,r),c=a.generators[n];if(s&&c?.inputFingerprint===o&&c.outputFingerprint===s)return{changed:!1,name:n,ran:!1};await i();let l=await gc(e,r);if(!l)throw Error(`Coreframe ${n} typegen did not produce ${r}.`);return a.generators[n]={inputFingerprint:o,outputFingerprint:l},await mc(e,a),{changed:s!==l,name:n,ran:!0}}async function fc(e){let t=G.platform===`win32`?`react-router.cmd`:`react-router`,n=G.env;await R(t,[`typegen`],{cwd:e,env:{...n,PATH:P.resolve(e,`node_modules/.bin`)+P.delimiter+(n.PATH??n.Path??``)},stdio:`inherit`})}async function pc(e){try{let t=JSON.parse(await V(P.resolve(e,sc),`utf8`));if(!bc(t)||t.schemaVersion!==1)return;let n={};if(!bc(t.generators))return;for(let e of cc){let r=t.generators[e];bc(r)&&typeof r.inputFingerprint==`string`&&typeof r.outputFingerprint==`string`&&(n[e]={inputFingerprint:r.inputFingerprint,outputFingerprint:r.outputFingerprint})}return{generators:n,schemaVersion:1}}catch{return}}async function mc(e,t){let n=P.resolve(e,sc);await B(P.dirname(n),{recursive:!0}),await U(n,`${JSON.stringify(t)}\n`,{mode:384})}async function hc(e,t){let n=Re(`sha256`);for(let r of[...t].sort()){let t=P.resolve(e,r),i=await vc(t);if(!i){n.update(`missing:${r}\0`);continue}if(i.isDirectory()){n.update(`directory:${r}\0`);for(let r of await _c(t)){let i=P.join(t,r),a=P.relative(e,i).split(P.sep).join(`/`);n.update(`${a}\0`),n.update(await V(i))}continue}i.isFile()&&(n.update(`file:${r}\0`),n.update(await V(t)))}return n.digest(`hex`)}async function gc(e,t){if(await vc(P.resolve(e,t)))return hc(e,[t])}async function _c(e){let t=[];async function n(e,r){let i=await Te(e,{withFileTypes:!0});i.sort((e,t)=>e.name.localeCompare(t.name));for(let a of i)if(a.isDirectory()){if(rc.has(a.name))continue;await n(P.join(e,a.name),P.join(r,a.name))}else a.isFile()&&t.push(P.join(r,a.name))}return await n(e,``),t.sort()}async function vc(e){try{return await Oe(e)}catch(e){if(yc(e))return;throw e}}function yc(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`}function bc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const xc=P.resolve(`node_modules`,`.bin`);G.env.PATH=xc+P.delimiter+G.env.PATH;const Sc=G.platform===`win32`?`tsc.cmd`:`tsc`,Cc=[{name:`scripts`,path:`scripts/tsconfig.json`},{name:`shared`,path:`src/shared/tsconfig.json`},{name:`api`,path:`src/api/tsconfig.json`},{name:`worker`,path:`src/api/worker/tsconfig.json`},{name:`web`,path:`src/web/tsconfig.json`},{name:`dashboard`,path:`dashboard/tsconfig.json`}];async function wc(){await lc({checkWorker:!0});let e=[];for(let t of Cc)try{await ye(t.path),e.push(t)}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let t=e.map(e=>Ht({name:e.name,command:Sc,args:[`-p`,e.path]})),n=(await Promise.all(t.map(e=>e.wait()))).filter(e=>e.exitCode!==0);n.length>0&&(G.exitCode=n[0].exitCode)}const Tc=r(s(Ms),{displayName:`feature`,from:async e=>e}),Ec=[`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.`],Dc=n({name:`deploy`,args:{environment:u({type:s(Ze),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:i({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:i({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:i({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:a({long:`tauri-local-platform`,type:t(s(xt)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:c({long:`tauri-workflow-name`,type:l(f),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:a({long:`tauri-workflow-platform`,type:t(s(xt)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:c({long:`tauri-workflow-ref`,type:l(f),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:i({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})=>xa([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`]:[]])}),Oc=p({name:`staging`,cmds:{reassign:n({name:`reassign`,args:{json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ft();if(e){console.log(JSON.stringify({...t,notices:Ec}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Ec.join(` `)}`)}}),url:n({name:`url`,args:{json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await $e();console.log(e?JSON.stringify({url:t}):t)}})}}),kc=p({name:`secrets`,cmds:{"rotate-access-token":n({name:`rotate-access-token`,args:{environment:u({type:s(Ze),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:i({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 vt({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:n({name:`status`,args:{environment:u({type:l(s(Ze)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await et({environment:e});console.log(t?JSON.stringify(n):Pc(n))}}),set:n({name:`set`,args:{environment:u({type:s(Ze),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:u({type:l(f),displayName:`name`,description:`Declared Worker secret name; omit to configure known secrets.`}),bulk:i({long:`bulk`,description:`Queue known secrets from pasted or piped dotenv-formatted contents.`,defaultValue:()=>!1})},handler:async({environment:e,name:t,bulk:n})=>{if(n&&t)throw Error(`Use either a secret name or --bulk, not both.`);if(t){await st({environment:e,name:t,value:await Fc(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await lt(),i=n?await Lc(r):await Ic(r,e);await ct({environment:e,values:i});let a=Object.keys(i).sort();console.log(a.length>0?`Queued ${a.join(`, `)} for ${e}. Run coreframe deploy ${e} to apply.`:`No ${e} Worker secret updates were queued.`)}}),discard:n({name:`discard`,args:{environment:u({type:s(Ze),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:u({type:f,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await Qe({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),Ac=n({name:`typecheck`,args:{},handler:wc}),jc=p({name:`worker`,cmds:{typegen:n({name:`typegen`,args:{check:i({long:`check`,description:`Fail when the committed primary Worker declarations are stale.`,defaultValue:()=>!1})},handler:async({check:e})=>{let t=await $s({check:e});console.log(e?`${zc(t.path)} is current.`:`${zc(t.path)} ${t.changed?`generated`:`is unchanged`}.`)}})}}),Mc=n({name:`dev`,args:{debug:c({long:`debug`,type:l(Tc),description:`Launch a development feature in isolated debug mode.`}),https:i({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),fresh:i({long:`fresh`,description:`Start a new directory-scoped development session instead of attaching to one.`,defaultValue:()=>!1}),host:c({long:`host`,type:l(f),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),lan:i({long:`lan`,description:`Expose the Portless development proxy to devices on the local network.`,defaultValue:()=>!1}),managed:i({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:i({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),reuseVite:i({long:`reuse-vite`,description:`Use an existing Vite development server instead of starting another one for Flutter.`,defaultValue:()=>!1}),stop:i({long:`stop`,description:`Stop the directory development supervisor and its managed services.`,defaultValue:()=>!1}),platform:u({type:l(s(js)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:u({type:l(f),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:c({long:`port`,type:l(o),description:`Port for the web development server.`}),verbose:i({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,fresh:n,host:r,https:i,lan:a,managed:o,noManaged:s,platform:c,port:l,reuseVite:u,stop:d,verbose:f})=>d?Ft({cwd:G.cwd()}):Rs({debug:e,device:t,fresh:n,host:r,https:i,lan:a,managed:o,noManaged:s,platform:c??`web`,reuseVite:u,verbose:f,webPort:l})}),Nc=n({name:`preview`,args:{host:c({long:`host`,type:l(f),description:`Host address for the preview server.`}),port:c({long:`port`,type:l(o),description:`Port for the preview server.`})},handler:({host:e,port:t})=>Zs({host:e,port:t})});function Pc(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(`
15
- `)}async function Fc(e){if(!G.stdin.isTTY){let e=``;for await(let t of G.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await z.password({message:`Enter the new value for ${e}`});if(z.isCancel(t))throw z.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}async function Ic(e,t){if(!G.stdin.isTTY)throw Error(`Interactive secret setup requires a terminal. Provide a secret name or use --bulk with piped dotenv contents.`);if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let n={};for(let r of e){let e=r.requiredIn.includes(t),i=await z.password({message:`${r.name}: ${r.description}${e?` (required)`:` (optional; leave blank to skip)`}`,validate:n=>e&&!n?.trim()?`${r.name} is required in ${t}.`:void 0});if(z.isCancel(i))throw z.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);i.trim()&&(n[r.name]=i)}return n}async function Lc(e){if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let t=G.stdin.isTTY?await z.multiline({message:`Paste dotenv-formatted Worker secrets. Press Enter twice to submit.`,validate:e=>e?.trim()?void 0:`Paste at least one dotenv entry.`}):await Rc();if(z.isCancel(t))throw z.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);let{ignoredNames:n,values:r}=rt(t,e);return n.length>0&&z.log.info(`Ignored non-secret or undeclared names: ${n.join(`, `)}.`),r}async function Rc(){let e=``;for await(let t of G.stdin)e+=t.toString();return e}function zc(e){return e.split(/[\\/]/).at(-1)??e}const Bc=n({name:`typegen`,description:`Generate Coreframe route and Worker type declarations.`,args:{},handler:async()=>{let e=await lc();for(let t of e)console.log(uc(t))}});function Vc(e,{formatMessage:t,temporaryDirectory:n=Me(),write:r=e=>console.error(e)}={}){let i=qc(e),a=Xc(Uc(e,t),i);try{let t=I(He(I(n,`coreframe-error-`)),`error.log`);return Ke(t,`${Xc(Wc(e),i)}\n`,{mode:384}),r(`Error: ${a}\nFull diagnostic: ${t}`),t}catch{r(`Error: ${a}\nThe full diagnostic could not be written to the temporary directory.`);return}}function Hc(t,n={}){let r=typeof t==`function`?t:()=>e.run(e.binary(t),process.argv),i=!1,a=e=>{i||(i=!0,Vc(e,n),process.exit(1))};process.once(`uncaughtException`,a),process.once(`unhandledRejection`,a),Promise.resolve().then(r).catch(a)}function Uc(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 Wc(e){try{let t=Gc(e);if(!(e instanceof Error)||!Kc(t))return It(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${It(t,{customInspect:!1,depth:10})}`:``}`}catch{return`The thrown value could not be inspected.`}}function Gc(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:Gc(a.value,t),writable:!0})}return i}function Kc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function qc(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`?Jc(t.value,n):r(t.value))}}}try{r(e)}catch{}return n}function Jc(e,t){if(!(typeof e!=`object`||!e))for(let n of Reflect.ownKeys(e)){let r=Object.getOwnPropertyDescriptor(e,n);typeof n==`string`&&Yc(n)&&r&&`value`in r&&typeof r.value==`string`&&r.value&&t.add(r.value)}}function Yc(e){return/(?:^|_)(?:AUTH|CERT|COOKIE|CREDENTIALS?|DATABASE_URL|DSN|KEY|PASS(?:WORD)?|PRIVATE|SECRET|SESSION|TOKEN)(?:_|$)/i.test(e)}function Xc(e,t){return[...t].sort((e,t)=>t.length-e.length).reduce((e,t)=>e.replaceAll(t,`[redacted environment value]`),e)}const Zc=p({name:`coreframe`,cmds:{build:an,dashboard:br,assets:ur,flutter:dr,i18n:fr,deploy:Dc,staging:Oc,secrets:kc,typegen:Bc,typecheck:Ac,worker:jc,dev:Mc,preview:Nc,upgrade:_a,recipes:va,db:ya}});import.meta.main&&Hc(Zc,{formatMessage:process.argv[2]===`db`?x:void 0});export{Zc as coreframeCli};
14
+ `)}const rc=new Set([`.coreframe`,`.git`,`.react-router`,`.wrangler`,`.wxt`,`build`,`dist`,`node_modules`,`styled-system`,`target`]),ic=[`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`,`react-router.config.ts`,`src/web`],ac=[`dashboard`,`node_modules/@coreframe/dashboard/dist/package/app`,`node_modules/@coreframe/dashboard/package.json`,`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`],oc=[`coreframe.config.ts`,`node_modules/@coreframe/config/dist`,`node_modules/@coreframe/config/package.json`,`node_modules/@coreframe/deploy/dist`,`node_modules/@coreframe/deploy/package.json`,`node_modules/wrangler/package.json`,`package.json`,`pnpm-lock.yaml`,`src/api`,`wrangler.jsonc`],sc=`.coreframe/typegen.json`,cc=[`web`,`dashboard`,`worker`];async function lc({checkWorker:e=!1,cwd:t=K.cwd(),runners:n={}}={}){let r=await pc(t)??{generators:{},schemaVersion:1},i=[];return i.push(await dc({cwd:t,inputPaths:ic,name:`web`,outputPath:`.react-router`,run:()=>(n.web??fc)(t),state:r})),i.push(await dc({cwd:t,inputPaths:ac,name:`dashboard`,outputPath:`dashboard/.react-router`,run:()=>(n.dashboard??_r)(t),state:r})),i.push(await dc({cwd:t,inputPaths:oc,name:`worker`,outputPath:`worker-configuration.d.ts`,run:()=>(n.worker??$s)({check:e,cwd:t}),state:r})),i}function uc(e){return`${{dashboard:`Dashboard route types`,web:`Web route types`,worker:`Worker types`}[e.name]} ${e.changed?`generated`:`unchanged`}.`}async function dc({cwd:e,inputPaths:t,name:n,outputPath:r,run:i,state:a}){let o=await hc(e,t),s=await gc(e,r),c=a.generators[n];if(s&&c?.inputFingerprint===o&&c.outputFingerprint===s)return{changed:!1,name:n,ran:!1};await i();let l=await gc(e,r);if(!l)throw Error(`Coreframe ${n} typegen did not produce ${r}.`);return a.generators[n]={inputFingerprint:o,outputFingerprint:l},await mc(e,a),{changed:s!==l,name:n,ran:!0}}async function fc(e){let t=K.platform===`win32`?`react-router.cmd`:`react-router`,n=K.env;await z(t,[`typegen`],{cwd:e,env:{...n,PATH:F.resolve(e,`node_modules/.bin`)+F.delimiter+(n.PATH??n.Path??``)},stdio:`inherit`})}async function pc(e){try{let t=JSON.parse(await H(F.resolve(e,sc),`utf8`));if(!bc(t)||t.schemaVersion!==1)return;let n={};if(!bc(t.generators))return;for(let e of cc){let r=t.generators[e];bc(r)&&typeof r.inputFingerprint==`string`&&typeof r.outputFingerprint==`string`&&(n[e]={inputFingerprint:r.inputFingerprint,outputFingerprint:r.outputFingerprint})}return{generators:n,schemaVersion:1}}catch{return}}async function mc(e,t){let n=F.resolve(e,sc);await V(F.dirname(n),{recursive:!0}),await W(n,`${JSON.stringify(t)}\n`,{mode:384})}async function hc(e,t){let n=ze(`sha256`);for(let r of[...t].sort()){let t=F.resolve(e,r),i=await vc(t);if(!i){n.update(`missing:${r}\0`);continue}if(i.isDirectory()){n.update(`directory:${r}\0`);for(let r of await _c(t)){let i=F.join(t,r),a=F.relative(e,i).split(F.sep).join(`/`);n.update(`${a}\0`),n.update(await H(i))}continue}i.isFile()&&(n.update(`file:${r}\0`),n.update(await H(t)))}return n.digest(`hex`)}async function gc(e,t){if(await vc(F.resolve(e,t)))return hc(e,[t])}async function _c(e){let t=[];async function n(e,r){let i=await Ee(e,{withFileTypes:!0});i.sort((e,t)=>e.name.localeCompare(t.name));for(let a of i)if(a.isDirectory()){if(rc.has(a.name))continue;await n(F.join(e,a.name),F.join(r,a.name))}else a.isFile()&&t.push(F.join(r,a.name))}return await n(e,``),t.sort()}async function vc(e){try{return await ke(e)}catch(e){if(yc(e))return;throw e}}function yc(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`}function bc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const xc=F.resolve(`node_modules`,`.bin`);K.env.PATH=xc+F.delimiter+K.env.PATH;const Sc=K.platform===`win32`?`tsc.cmd`:`tsc`,Cc=[{name:`scripts`,path:`scripts/tsconfig.json`},{name:`shared`,path:`src/shared/tsconfig.json`},{name:`api`,path:`src/api/tsconfig.json`},{name:`worker`,path:`src/api/worker/tsconfig.json`},{name:`web`,path:`src/web/tsconfig.json`},{name:`dashboard`,path:`dashboard/tsconfig.json`}];async function wc(){await lc({checkWorker:!0});let e=[];for(let t of Cc)try{await be(t.path),e.push(t)}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let t=e.map(e=>Wt({name:e.name,command:Sc,args:[`-p`,e.path]})),n=(await Promise.all(t.map(e=>e.wait()))).filter(e=>e.exitCode!==0);n.length>0&&(K.exitCode=n[0].exitCode)}const Tc=r(s(Ns),{displayName:`feature`,from:async e=>e}),Ec=[`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.`],Dc=n({name:`deploy`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:i({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:i({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:i({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:a({long:`tauri-local-platform`,type:t(s(St)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:c({long:`tauri-workflow-name`,type:l(f),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:a({long:`tauri-workflow-platform`,type:t(s(St)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:c({long:`tauri-workflow-ref`,type:l(f),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:i({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})=>Ca([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`]:[]])}),Oc=p({name:`staging`,cmds:{reassign:n({name:`reassign`,args:{json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await pt();if(e){console.log(JSON.stringify({...t,notices:Ec}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Ec.join(` `)}`)}}),url:n({name:`url`,args:{json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await et();console.log(e?JSON.stringify({url:t}):t)}})}}),kc=p({name:`secrets`,cmds:{"rotate-access-token":n({name:`rotate-access-token`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:i({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 yt({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:n({name:`status`,args:{environment:u({type:l(s(Qe)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await tt({environment:e});console.log(t?JSON.stringify(n):Fc(n))}}),set:n({name:`set`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:u({type:l(f),displayName:`name`,description:`Declared Worker secret name; omit to configure known secrets.`}),bulk:i({long:`bulk`,description:`Queue known secrets from pasted or piped dotenv-formatted contents.`,defaultValue:()=>!1})},handler:async({environment:e,name:t,bulk:n})=>{if(n&&t)throw Error(`Use either a secret name or --bulk, not both.`);if(t){await ct({environment:e,name:t,value:await Ic(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await ut(),i=n?await Rc(r):await Lc(r,e);await lt({environment:e,values:i});let a=Object.keys(i).sort();console.log(a.length>0?`Queued ${a.join(`, `)} for ${e}. Run coreframe deploy ${e} to apply.`:`No ${e} Worker secret updates were queued.`)}}),discard:n({name:`discard`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:u({type:f,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await $e({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),Ac=n({name:`typecheck`,args:{},handler:wc}),jc=p({name:`worker`,cmds:{typegen:n({name:`typegen`,args:{check:i({long:`check`,description:`Fail when the committed primary Worker declarations are stale.`,defaultValue:()=>!1})},handler:async({check:e})=>{let t=await $s({check:e});console.log(e?`${Bc(t.path)} is current.`:`${Bc(t.path)} ${t.changed?`generated`:`is unchanged`}.`)}})}}),Mc=n({name:`dev`,args:{debug:c({long:`debug`,type:l(Tc),description:`Launch a development feature in isolated debug mode.`}),https:i({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),fresh:i({long:`fresh`,description:`Start a new directory-scoped development session instead of attaching to one.`,defaultValue:()=>!1}),host:c({long:`host`,type:l(f),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),lan:i({long:`lan`,description:`Expose the Portless development proxy to devices on the local network.`,defaultValue:()=>!1}),managed:i({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:i({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),reuseVite:i({long:`reuse-vite`,description:`Use an existing Vite development server instead of starting another one for Flutter.`,defaultValue:()=>!1}),stop:i({long:`stop`,description:`Stop the Vite development server for the selected platform.`,defaultValue:()=>!1}),platform:u({type:l(s(Ms)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:u({type:l(f),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:c({long:`port`,type:l(o),description:`Port for the web development server.`}),verbose:i({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,fresh:n,host:r,https:i,lan:a,managed:o,noManaged:s,platform:c,port:l,reuseVite:u,stop:d,verbose:f})=>d?It({cwd:K.cwd(),resource:Nc(c??`web`)}):Rs({debug:e,device:t,fresh:n,host:r,https:i,lan:a,managed:o,noManaged:s,platform:c??`web`,reuseVite:u,verbose:f,webPort:l})});function Nc(e){if(e===`web`)return`vite:web`;if(e===`ios`||e===`android`||e===`macos`)return`vite:flutter:${e}`;throw Error(`The --stop option is only supported for web, iOS, Android, and macOS development targets.`)}const Pc=n({name:`preview`,args:{host:c({long:`host`,type:l(f),description:`Host address for the preview server.`}),port:c({long:`port`,type:l(o),description:`Port for the preview server.`})},handler:({host:e,port:t})=>Zs({host:e,port:t})});function Fc(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(`
15
+ `)}async function Ic(e){if(!K.stdin.isTTY){let e=``;for await(let t of K.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await B.password({message:`Enter the new value for ${e}`});if(B.isCancel(t))throw B.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}async function Lc(e,t){if(!K.stdin.isTTY)throw Error(`Interactive secret setup requires a terminal. Provide a secret name or use --bulk with piped dotenv contents.`);if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let n={};for(let r of e){let e=r.requiredIn.includes(t),i=await B.password({message:`${r.name}: ${r.description}${e?` (required)`:` (optional; leave blank to skip)`}`,validate:n=>e&&!n?.trim()?`${r.name} is required in ${t}.`:void 0});if(B.isCancel(i))throw B.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);i.trim()&&(n[r.name]=i)}return n}async function Rc(e){if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let t=K.stdin.isTTY?await B.multiline({message:`Paste dotenv-formatted Worker secrets. Press Enter twice to submit.`,validate:e=>e?.trim()?void 0:`Paste at least one dotenv entry.`}):await zc();if(B.isCancel(t))throw B.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);let{ignoredNames:n,values:r}=it(t,e);return n.length>0&&B.log.info(`Ignored non-secret or undeclared names: ${n.join(`, `)}.`),r}async function zc(){let e=``;for await(let t of K.stdin)e+=t.toString();return e}function Bc(e){return e.split(/[\\/]/).at(-1)??e}const Vc=n({name:`typegen`,description:`Generate Coreframe route and Worker type declarations.`,args:{},handler:async()=>{let e=await lc();for(let t of e)console.log(uc(t))}});function Hc(e,{formatMessage:t,temporaryDirectory:n=Ne(),write:r=e=>console.error(e)}={}){let i=Jc(e),a=Zc(Wc(e,t),i);try{let t=L(Ue(L(n,`coreframe-error-`)),`error.log`);return qe(t,`${Zc(Gc(e),i)}\n`,{mode:384}),r(`Error: ${a}\nFull diagnostic: ${t}`),t}catch{r(`Error: ${a}\nThe full diagnostic could not be written to the temporary directory.`);return}}function Uc(t,n={}){let r=typeof t==`function`?t:()=>e.run(e.binary(t),process.argv),i=!1,a=e=>{i||(i=!0,Hc(e,n),process.exit(1))};process.once(`uncaughtException`,a),process.once(`unhandledRejection`,a),Promise.resolve().then(r).catch(a)}function Wc(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 Gc(e){try{let t=Kc(e);if(!(e instanceof Error)||!qc(t))return Lt(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${Lt(t,{customInspect:!1,depth:10})}`:``}`}catch{return`The thrown value could not be inspected.`}}function Kc(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:Kc(a.value,t),writable:!0})}return i}function qc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Jc(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`?Yc(t.value,n):r(t.value))}}}try{r(e)}catch{}return n}function Yc(e,t){if(!(typeof e!=`object`||!e))for(let n of Reflect.ownKeys(e)){let r=Object.getOwnPropertyDescriptor(e,n);typeof n==`string`&&Xc(n)&&r&&`value`in r&&typeof r.value==`string`&&r.value&&t.add(r.value)}}function Xc(e){return/(?:^|_)(?:AUTH|CERT|COOKIE|CREDENTIALS?|DATABASE_URL|DSN|KEY|PASS(?:WORD)?|PRIVATE|SECRET|SESSION|TOKEN)(?:_|$)/i.test(e)}function Zc(e,t){return[...t].sort((e,t)=>t.length-e.length).reduce((e,t)=>e.replaceAll(t,`[redacted environment value]`),e)}const Qc=p({name:`coreframe`,cmds:{build:sn,dashboard:Sr,assets:fr,flutter:pr,i18n:mr,deploy:Dc,staging:Oc,secrets:kc,typegen:Vc,typecheck:Ac,worker:jc,dev:Mc,preview:Pc,upgrade:ya,recipes:ba,db:xa}});import.meta.main&&Uc(Qc,{formatMessage:process.argv[2]===`db`?S:void 0});export{Qc as coreframeCli};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreframe/scripts",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Coreframe project workflow CLI and automation scripts",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,15 +28,15 @@
28
28
  "nano-spawn": "^2.1.0",
29
29
  "procband": "^0.3.8",
30
30
  "yaml": "^2.9.0",
31
- "@coreframe/deploy": "^0.1.3",
32
- "@coreframe/assets": "^0.1.6",
33
- "@coreframe/dev": "^0.1.5",
34
- "@coreframe/config": "^0.1.3",
31
+ "@coreframe/assets": "^0.1.7",
32
+ "@coreframe/config": "^0.1.4",
33
+ "@coreframe/db": "^0.1.4",
34
+ "@coreframe/dev": "^0.1.6",
35
35
  "@coreframe/dev-contracts": "^0.1.2",
36
- "@coreframe/flutter-tools": "^0.1.7",
36
+ "@coreframe/flutter-tools": "^0.1.9",
37
+ "@coreframe/deploy": "^0.1.4",
37
38
  "@coreframe/object-storage": "^0.1.1",
38
- "@coreframe/preview": "^0.1.1",
39
- "@coreframe/db": "^0.1.3"
39
+ "@coreframe/preview": "^0.1.2"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^26.1.0",