@coreframe/scripts 0.1.49 → 0.1.50

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.
Files changed (130) hide show
  1. package/dist/coreframe.d.ts +233 -41
  2. package/dist/coreframe.js +13 -2
  3. package/package.json +16 -30
  4. package/dist/_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js +0 -1
  5. package/dist/assets/contracts.d.ts +0 -187
  6. package/dist/assets/contracts.js +0 -1
  7. package/dist/assets/credentials.d.ts +0 -35
  8. package/dist/assets/credentials.js +0 -1
  9. package/dist/assets/images.d.ts +0 -32
  10. package/dist/assets/images.js +0 -1
  11. package/dist/assets/media.d.ts +0 -42
  12. package/dist/assets/media.js +0 -1
  13. package/dist/assets/project.d.ts +0 -54
  14. package/dist/assets/project.js +0 -3
  15. package/dist/assets/storage.d.ts +0 -60
  16. package/dist/assets/storage.js +0 -1
  17. package/dist/assets/workflows.d.ts +0 -69
  18. package/dist/assets/workflows.js +0 -1
  19. package/dist/assets.d.ts +0 -4
  20. package/dist/assets.js +0 -1
  21. package/dist/config.d.ts +0 -49
  22. package/dist/config.js +0 -1
  23. package/dist/db/apply-seed.d.ts +0 -8
  24. package/dist/db/apply-seed.js +0 -1
  25. package/dist/db/client.d.ts +0 -30
  26. package/dist/db/client.js +0 -1
  27. package/dist/db/config.d.ts +0 -24
  28. package/dist/db/config.js +0 -1
  29. package/dist/db/drizzle-kit.d.ts +0 -10
  30. package/dist/db/drizzle-kit.js +0 -2
  31. package/dist/db/ensure.d.ts +0 -9
  32. package/dist/db/ensure.js +0 -2
  33. package/dist/db/error.d.ts +0 -4
  34. package/dist/db/error.js +0 -1
  35. package/dist/db/local-postgres.d.ts +0 -65
  36. package/dist/db/local-postgres.js +0 -1
  37. package/dist/db/migrate-held.d.ts +0 -16
  38. package/dist/db/migrate-held.js +0 -10
  39. package/dist/db/migrate.d.ts +0 -9
  40. package/dist/db/migrate.js +0 -2
  41. package/dist/db/project.d.ts +0 -23
  42. package/dist/db/project.js +0 -1
  43. package/dist/db/reset.d.ts +0 -9
  44. package/dist/db/reset.js +0 -2
  45. package/dist/db/schema-check.d.ts +0 -11
  46. package/dist/db/schema-check.js +0 -2
  47. package/dist/db/schema-push.d.ts +0 -22
  48. package/dist/db/schema-push.js +0 -1
  49. package/dist/db/seed.d.ts +0 -19
  50. package/dist/db/seed.js +0 -2
  51. package/dist/db/setup.d.ts +0 -11
  52. package/dist/db/setup.js +0 -2
  53. package/dist/deploy/access-token-secret.d.ts +0 -39
  54. package/dist/deploy/access-token-secret.js +0 -1
  55. package/dist/deploy/check-migrations.d.ts +0 -4
  56. package/dist/deploy/check-migrations.js +0 -2
  57. package/dist/deploy/checks.d.ts +0 -8
  58. package/dist/deploy/checks.js +0 -1
  59. package/dist/deploy/config.d.ts +0 -68
  60. package/dist/deploy/config.js +0 -1
  61. package/dist/deploy/migrations.d.ts +0 -24
  62. package/dist/deploy/migrations.js +0 -4
  63. package/dist/deploy/pending-migrations.d.ts +0 -9
  64. package/dist/deploy/pending-migrations.js +0 -1
  65. package/dist/deploy/tauri-release.d.ts +0 -106
  66. package/dist/deploy/tauri-release.js +0 -1
  67. package/dist/deploy/version.d.ts +0 -24
  68. package/dist/deploy/version.js +0 -1
  69. package/dist/deploy.d.ts +0 -21
  70. package/dist/deploy.js +0 -3
  71. package/dist/dev-device.d.ts +0 -34
  72. package/dist/dev-device.js +0 -1
  73. package/dist/dev-https.d.ts +0 -17
  74. package/dist/dev-https.js +0 -1
  75. package/dist/dev-lock.d.ts +0 -28
  76. package/dist/dev-lock.js +0 -1
  77. package/dist/dev-timing.d.ts +0 -25
  78. package/dist/dev-timing.js +0 -1
  79. package/dist/dev.d.ts +0 -39
  80. package/dist/dev.js +0 -3
  81. package/dist/environment.d.ts +0 -27
  82. package/dist/environment.js +0 -1
  83. package/dist/i18n/catalogs.d.ts +0 -60
  84. package/dist/i18n/catalogs.js +0 -1
  85. package/dist/i18n/contracts.d.ts +0 -60
  86. package/dist/i18n/contracts.js +0 -1
  87. package/dist/i18n/paths.d.ts +0 -12
  88. package/dist/i18n/paths.js +0 -1
  89. package/dist/i18n/storage.d.ts +0 -117
  90. package/dist/i18n/storage.js +0 -1
  91. package/dist/i18n/workflows.d.ts +0 -46
  92. package/dist/i18n/workflows.js +0 -1
  93. package/dist/managed-dev-protocol.d.ts +0 -135
  94. package/dist/managed-dev-protocol.js +0 -1
  95. package/dist/managed-dev.d.ts +0 -48
  96. package/dist/managed-dev.js +0 -5
  97. package/dist/private-object-store.d.ts +0 -28
  98. package/dist/private-object-store.js +0 -1
  99. package/dist/project.d.ts +0 -5
  100. package/dist/project.js +0 -1
  101. package/dist/recipes/apply.d.ts +0 -26
  102. package/dist/recipes/apply.js +0 -2
  103. package/dist/recipes/list.d.ts +0 -14
  104. package/dist/recipes/list.js +0 -1
  105. package/dist/recipes/manifest.d.ts +0 -14
  106. package/dist/recipes/manifest.js +0 -1
  107. package/dist/recipes/source.d.ts +0 -22
  108. package/dist/recipes/source.js +0 -1
  109. package/dist/runner.d.ts +0 -20
  110. package/dist/runner.js +0 -1
  111. package/dist/staging.d.ts +0 -33
  112. package/dist/staging.js +0 -3
  113. package/dist/tauri-dev-output.d.ts +0 -21
  114. package/dist/tauri-dev-output.js +0 -2
  115. package/dist/typecheck.d.ts +0 -4
  116. package/dist/typecheck.js +0 -2
  117. package/dist/upgrade/check-skill-current.d.ts +0 -11
  118. package/dist/upgrade/check-skill-current.js +0 -2
  119. package/dist/upgrade/ensure-template-remote.d.ts +0 -13
  120. package/dist/upgrade/ensure-template-remote.js +0 -2
  121. package/dist/upgrade/fast-forward-template-files.d.ts +0 -9
  122. package/dist/upgrade/fast-forward-template-files.js +0 -2
  123. package/dist/upgrade/sync-coreframe-packages.d.ts +0 -8
  124. package/dist/upgrade/sync-coreframe-packages.js +0 -4
  125. package/dist/upgrade/template-ref.d.ts +0 -6
  126. package/dist/upgrade/template-ref.js +0 -1
  127. package/dist/user-preferences.d.ts +0 -8
  128. package/dist/user-preferences.js +0 -1
  129. package/dist/worker-environment.d.ts +0 -95
  130. package/dist/worker-environment.js +0 -1
package/dist/coreframe.js CHANGED
@@ -1,3 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import{assertAssetCredentialProfile as e,configureAssetCredentials as t}from"./assets/credentials.js";import{addAsset as n,buildAssets as r,checkAssets as i,printAssetResult as a,publishAssets as o}from"./assets/workflows.js";import"./assets.js";import{runDrizzleKitCommand as s}from"./db/drizzle-kit.js";import{seedLocalDb as c}from"./db/seed.js";import{migrateLocalDb as l}from"./db/migrate.js";import{resetLocalDb as u}from"./db/reset.js";import{setupLocalDb as d}from"./db/setup.js";import{ensureLocalDb as f}from"./db/ensure.js";import{formatDbErrorMessage as p}from"./db/error.js";import{migrateHeldMigrations as ee}from"./db/migrate-held.js";import{checkSchemaPush as m}from"./db/schema-check.js";import{rotateAccessTokenSigningSecret as h}from"./deploy/access-token-secret.js";import{deployEnvironments as g,tauriReleasePlatforms as _}from"./deploy/config.js";import{buildI18n as te,materializeI18nSnapshot as ne,prepareI18nRelease as re}from"./i18n/workflows.js";import{discoverStagingUrl as ie,reassignStagingHostname as ae}from"./staging.js";import{discardPendingWorkerSecret as oe,inspectWorkerEnvironment as se,parseDeclaredWorkerSecretEnv as ce,queueWorkerSecret as le,queueWorkerSecrets as ue,readDeclaredWorkerSecrets as v}from"./worker-environment.js";import{deployProject as y}from"./deploy.js";import{checkDeployMigrations as b}from"./deploy/check-migrations.js";import{devDebugFeatures as x,devPlatforms as S,runDevServer as C}from"./dev.js";import{validateRecipeName as w}from"./recipes/manifest.js";import{ensureTemplateRemote as T}from"./upgrade/ensure-template-remote.js";import{applyRecipe as E,printAppliedRecipe as D}from"./recipes/apply.js";import{listRecipes as O,printRecipeCatalog as k}from"./recipes/list.js";import{run as A}from"./runner.js";import{typecheckProject as j}from"./typecheck.js";import{checkUpgradeSkillCurrent as M}from"./upgrade/check-skill-current.js";import{fastForwardTemplateFiles as N}from"./upgrade/fast-forward-template-files.js";import{syncCoreframePackages as P}from"./upgrade/sync-coreframe-packages.js";import{array as F,command as I,extendType as L,flag as R,multioption as z,number as B,oneOf as V,option as H,optional as U,positional as W,rest as G,string as K,subcommands as q}from"@alloc/cmd-ts";import*as J from"@clack/prompts";const de=L(V(x),{displayName:`feature`,from:async e=>e}),Y=[`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.`],X=[`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(` `),fe=L(K,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),pe=L(K,{displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return w(e)}}),me=L(K,{displayName:`profile`,async from(t){return e(t)}}),Z=L(K,{displayName:`pack`,description:`Asset pack name, such as training-videos.`,async from(e){if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e))throw Error(`Asset pack names must use lowercase hyphen-separated segments.`);return e}}),Q=q({name:`coreframe`,cmds:{assets:q({name:`assets`,cmds:{configure:I({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${X}`,args:{profile:W({type:me,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{J.note(X,`Required B2 key access`);let n=await J.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(J.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);let r=await J.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(J.isCancel(r))throw Error(`Asset credential configuration was cancelled.`);await t({applicationKey:r,applicationKeyId:n.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:I({name:`add`,args:{file:W({type:K,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:H({long:`id`,type:K,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:H({long:`alt`,type:U(K),description:`Required alt text for raster image and SVG assets.`}),pack:H({long:`pack`,type:U(Z),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:H({long:`widths`,type:U(fe),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:r,json:i,pack:o,variantWidths:s})=>a(await n({alt:e,file:t,id:r,pack:o,variantWidths:s}),i)}),build:I({name:`build`,args:{id:H({long:`id`,type:U(K),description:`Build only one logical asset ID.`}),pack:H({long:`pack`,type:U(Z),description:`Build only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>a(await r({id:e,pack:n}),t)}),check:I({name:`check`,args:{fix:R({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:H({long:`pack`,type:U(Z),description:`Check only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await i({fix:e,pack:n});a(r,t),r.ok||(process.exitCode=1)}}),publish:I({name:`publish`,args:{pack:H({long:`pack`,type:U(Z),description:`Publish only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await o({pack:t});a(n,e),n.ok||(process.exitCode=1)}}),status:I({name:`status`,args:{pack:H({long:`pack`,type:U(Z),description:`Report status for only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await i({pack:t});a(n,e),n.ok||(process.exitCode=1)}})}}),i18n:q({name:`i18n`,cmds:{build:I({name:`build`,description:`Extract source messages or materialize an exact release catalog snapshot.`,args:{},handler:async()=>{await te()}}),materialize:I({name:`materialize`,description:`Materialize the immutable i18n snapshot for an exact commit.`,args:{revision:H({long:`revision`,type:U(K),description:`Full commit SHA. Defaults to the checked-out commit.`})},handler:async({revision:e})=>{let t=await ne({revision:e});t&&console.log(`Materialized i18n snapshot ${t.snapshot}.`)}}),prepare:I({name:`prepare`,description:`Fill missing translations, strictly compile, and publish an immutable tagged snapshot.`,args:{tag:H({long:`tag`,type:K,description:`Pushed v* release tag that points to the checked-out commit.`})},handler:async({tag:e})=>{let t=await re({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),deploy:I({name:`deploy`,args:{environment:W({type:V(g),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:R({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:R({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:R({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:z({long:`tauri-local-platform`,type:F(V(_)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:H({long:`tauri-workflow-name`,type:U(K),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:z({long:`tauri-workflow-platform`,type:F(V(_)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:H({long:`tauri-workflow-ref`,type:U(K),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:R({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})=>y([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),staging:q({name:`staging`,cmds:{reassign:I({name:`reassign`,args:{json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ae();if(e){console.log(JSON.stringify({...t,notices:Y}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Y.join(` `)}`)}}),url:I({name:`url`,args:{json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ie();console.log(e?JSON.stringify({url:t}):t)}})}}),secrets:q({name:`secrets`,cmds:{"rotate-access-token":I({name:`rotate-access-token`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:R({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 h({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:I({name:`status`,args:{environment:W({type:U(V(g)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await se({environment:e});console.log(t?JSON.stringify(n):he(n))}}),set:I({name:`set`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:W({type:U(K),displayName:`name`,description:`Declared Worker secret name; omit to configure known secrets.`}),bulk:R({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 le({environment:e,name:t,value:await ge(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await v(),i=n?await _e(r):await $(r,e);await ue({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:I({name:`discard`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:W({type:K,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await oe({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),typecheck:I({name:`typecheck`,args:{},handler:j}),dev:I({name:`dev`,args:{debug:H({long:`debug`,type:U(de),description:`Launch a development feature in isolated debug mode.`}),https:R({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),host:H({long:`host`,type:U(K),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),managed:R({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:R({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),platform:W({type:U(V(S)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:W({type:U(K),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:H({long:`port`,type:U(B),description:`Port for the web development server.`}),verbose:R({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o,port:s,verbose:c})=>C({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o??`web`,verbose:c,webPort:s})}),upgrade:q({name:`upgrade`,cmds:{"ensure-template-remote":I({name:`ensure-template-remote`,args:{remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:R({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>T({fetch:!e,remote:t})}),"check-skill-current":I({name:`check-skill-current`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:R({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=M({apply:e,target:t})}}),"fast-forward-template-files":I({name:`fast-forward-template-files`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),base:H({long:`base`,type:U(K),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:R({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>N({apply:e,base:t,target:n})}),"sync-coreframe-packages":I({name:`sync-coreframe-packages`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:R({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>P({apply:e,target:t})})}}),recipes:q({name:`recipes`,cmds:{apply:I({name:`apply`,args:{recipe:W({type:pe,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:R({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>D(E({fetch:!e,name:t,remote:n,target:r}))}),list:I({name:`list`,args:{target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:R({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>k(O({fetch:!e,remote:t,target:n}))})}}),db:q({name:`db`,cmds:{ensure:I({name:`ensure`,args:{},handler:f}),generate:I({name:`generate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>s(`generate`,e)}),migrate:I({name:`migrate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>s(`migrate`,e)}),"migrate-held":I({name:`migrate-held`,args:{confirm:H({long:`confirm`,type:U(V([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>ee({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":I({name:`migrate-local`,args:{},handler:l}),"migrations-check":I({name:`migrations-check`,args:{},handler:b}),reset:I({name:`reset`,args:{},handler:u}),seed:I({name:`seed`,args:{},handler:()=>c()}),"schema-check":I({name:`schema-check`,args:{seed:R({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>m({seed:e})}),setup:I({name:`setup`,args:{},handler:()=>d()}),studio:I({name:`studio`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>s(`studio`,e)})}})}});import.meta.main&&A(Q,{formatMessage:process.argv[2]===`db`?p:void 0});function he(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
3
- `)}async function ge(e){if(!process.stdin.isTTY){let e=``;for await(let t of process.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await J.password({message:`Enter the new value for ${e}`});if(J.isCancel(t))throw J.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}async function $(e,t){if(!process.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 J.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(J.isCancel(i))throw J.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);i.trim()&&(n[r.name]=i)}return n}async function _e(e){if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let t=process.stdin.isTTY?await J.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 ve();if(J.isCancel(t))throw J.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);let{ignoredNames:n,values:r}=ce(t,e);return n.length>0&&J.log.info(`Ignored non-secret or undeclared names: ${n.join(`, `)}.`),r}async function ve(){let e=``;for await(let t of process.stdin)e+=t.toString();return e}export{Q as coreframeCli};
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 ee,resetLocalDb as E,runDrizzleKitCommand as D,scanDeployMigrationFiles as O,seedLocalDb as te,setupLocalDb as ne,startProjectPostgres as k,stopProjectPostgres as A}from"@coreframe/db";import{checkFlutterClient as j,ensureFlutterDevAssetDirectories as re,flutterPlatforms as M,generateFlutterNativeBridge as ie,prepareFlutterClient as N,prepareFlutterDevOutput as ae,productionApiOrigin as P,runFlutterAcceptance as oe}from"@coreframe/flutter-tools";import F,{dirname as I,isAbsolute as se,join as L,posix as ce,resolve as R,sep as le}from"node:path";import z from"nano-spawn";import*as B from"@clack/prompts";import{addAsset as ue,buildAssets as de,checkAssets as fe,printAssetResult as pe,publishAssets as me}from"@coreframe/assets";import{assertAssetCredentialProfile as he,configureAssetCredentials as ge,createB2PrivateObjectStore as _e}from"@coreframe/object-storage";import{access as ve,chmod as ye,copyFile as be,cp as xe,link as Se,mkdir as V,mkdtemp as Ce,readFile as H,realpath as we,rename as Te,rm as U,stat as Ee,unlink as De,writeFile as Oe}from"node:fs/promises";import{homedir as ke,networkInterfaces as Ae,tmpdir as je}from"node:os";import{importProjectDependency as Me,normalizeWorkerEnvironment as Ne,readProjectConfig as Pe,wranglerEnvironmentNames as Fe}from"@coreframe/config";import{createHash as Ie,randomUUID as W}from"node:crypto";import G from"node:process";import{spawnSync as K}from"node:child_process";import{chmodSync as Le,existsSync as q,lstatSync as Re,mkdirSync as ze,mkdtempSync as Be,readFileSync as J,readlinkSync as Ve,rmSync as He,symlinkSync as Ue,writeFileSync as We}from"node:fs";import{parse as Ge,stringify as Ke}from"yaml";import{accessTokenSigningSecretName as qe,clearAppliedPendingWorkerSecrets as Je,deployEnvironments as Ye,discardPendingWorkerSecret as Xe,discoverStagingUrl as Ze,inspectWorkerEnvironment as Qe,materializePrimaryWorkerConfig as $e,materializePrimaryWorkerTypeConfig as et,parseDeclaredWorkerSecretEnv as tt,parseTauriReleasePlatform as nt,prepareAccessTokenSigningSecret as rt,prepareTauriRelease as it,queueWorkerSecret as at,queueWorkerSecrets as ot,readDeclaredWorkerSecrets as st,readPackageJson as ct,readPendingWorkerSecretSnapshot as lt,reassignStagingHostname as ut,releaseName as dt,resolveDeployConfig as ft,resolveReleaseVersion as pt,resolveTauriReleasePlan as mt,restoreTauriReleaseMetadata as ht,rotateAccessTokenSigningSecret as gt,runAfterWorkerDeploy as _t,runPostDeployChecks as vt,tauriReleasePlatforms as yt,uploadTauriReleaseToB2 as bt,validateTauriReleasePlan as xt,validateWorkerEnvironmentForDeploy as St,verifyAccessTokenSigningSecret as Ct,writePackageVersion as wt,writeTauriReleaseMetadata as Tt}from"@coreframe/deploy";import{connectDevSupervisor as Et,createDevStartupTiming as Dt,devHttpsCertEnv as Ot,devHttpsKeyEnv as kt,isManagedDevCheckout as At,isPrimaryCheckout as jt,prepareDevHttps as Mt,stopDevSupervisor as Nt}from"@coreframe/dev";import{inspect as Pt,parseEnv as Ft}from"node:util";import{once as It}from"node:events";import{finished as Lt}from"node:stream/promises";import{codexTaskEnv as Rt}from"@coreframe/dev-contracts/codex-task";import{managedDevEnv as zt}from"@coreframe/dev-contracts/managed-dev";import{determineAgent as Bt}from"@vercel/detect-agent";import{createPrefixStream as Y,supervise as Vt}from"procband";import{createConnection as Ht,createServer as Ut}from"node:net";import{setTimeout as Wt}from"node:timers/promises";const Gt=[`web`,...M];function Kt(e=`web`,{apiOrigin:t,cwd:n=process.cwd(),simulator:r=!1}={}){if(Zt(e,r),e===`web`)return[$t(`pnpm`,[`build`],n,{COREFRAME_PLATFORM:`web`})];let i=P(t);return[{kind:`prepare`,platform:e},$t(`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}={}){Zt(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 Jt(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 Yt(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
+ `):[`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 Xt({apiOrigin:e,cwd:t=process.cwd(),environment:n=process.env,platform:r=`web`,simulator:i=!1,prepareClient:a=N,runCommand:o=Qt}={}){Zt(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 Kt(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(Jt(t)):r===`ios`&&console.log(Yt(t,{simulator:i}))}function Zt(e,t){if(t&&e!==`ios`)throw Error(`The --simulator flag is only supported for the iOS build target.`)}async function Qt(e,t,{cwd:n,env:r}){await z(e,t,{cwd:n,env:r,stdio:`inherit`})}function $t(e,t,n,r){return{kind:`command`,command:e,args:t,cwd:n,...r===void 0?{}:{environment:r}}}const en=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in a packaged Flutter client.`,async from(e){return P(e)}}),tn=n({name:`build`,description:`Build the web client or a release Flutter app. Tauri is not built.`,args:{platform:u({type:l(s(Gt)),displayName:`platform`,description:`Build target: web, iOS, Android, or macOS. Defaults to web.`}),apiOrigin:c({long:`api-origin`,type:l(en),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})=>Xt({apiOrigin:e,platform:t,simulator:n})}),nn=/^[a-f0-9]{64}$/,rn=/^[a-f0-9]{40}$/,an=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function on(e){if(!nn.test(e))throw Error(`Invalid SHA-256 digest "${e}".`);return e}function sn(e){if(!rn.test(e))throw Error(`Invalid full Git revision "${e}".`);return e}function cn(e,t){if(!an.test(e))throw Error(`${t} must contain only letters, numbers, dots, underscores, or hyphens.`);return e}function ln(e){return`projects/${cn(e,`Project ID`)}/i18n/v1`}function un(e,t){return on(t),`${ln(e)}/objects/sha256/${t.slice(0,2)}/${t}`}function dn(e,t){return sn(t),`${ln(e)}/commits/${t}.json`}function fn(e,t){return pn(t),`${ln(e)}/releases/${encodeURIComponent(t)}.json`}function pn(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}${le}`))throw Error(`Unsafe i18n artifact path "${t}".`);return r}function Z(e,t,n){return`${e.directory}/${t}/${n}.json`}function mn(e,t,n){return`${e.directory}/${t}/${n}.mjs`}async function hn(e){await z(`pnpm`,[`exec`,`lingui`,`extract`],{cwd:e,stdio:`inherit`})}async function gn({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 xn(o),c=Object.fromEntries(Object.entries(s).filter(([,e])=>!e.obsolete)),l=L(r,`${n}-${a}.json`);await V(I(l),{recursive:!0}),await be(o,l),i.push({path:o,backup:l}),await Sn(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 be(t,e)}finally{for(let n of e.locales)for(let r of e.catalogs)await U(X(t,mn(e,n,r)),{force:!0})}}}async function _n({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 xn(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)=>Dn(e).localeCompare(Dn(t)))}async function vn({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 Cn(await wn({args:e.generator.args??[],command:e.generator.command,cwd:t,env:r,input:JSON.stringify(i)}))}async function yn({config:e,cwd:t,missing:n,response:r}){let i=new Map(n.map(e=>[Dn(e),e])),a=new Map;for(let e of r.translations){let t=Dn(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 Me(`@lingui/message-utils/compileMessage`,t);for(let e of n){let t=a.get(Dn(e));Tn({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 xn(i),s=!1;for(let[e,t]of Object.entries(o)){let i=a.get(Dn({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 Sn(i,o)}}async function bn({config:e,cwd:t}){let n=await _n({config:e,cwd:t});if(n.length>0)throw Error(`I18n catalogs remain incomplete: ${n.length} translations are missing.`);let r=await Me(`@lingui/message-utils/compileMessage`,t);for(let n of e.locales)if(n!==e.sourceLocale)for(let i of e.catalogs){let a=await xn(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}.`);Tn({compileMessage:r,id:e,locale:n,source:t.message,translation:t.translation})}}}async function xn(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 Sn(e,t){await V(I(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;await Oe(n,`${JSON.stringify(t,null,2)}\n`),await Te(n,e)}function Cn(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 wn({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 Tn({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=En(a),c=En(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 En(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 Dn(e){return`${e.locale}\0${e.catalog}\0${e.id}`}function On(e){return Ie(`sha256`).update(e).digest(`hex`)}async function kn(e){return On(await H(e))}function An(e){return Buffer.from(`${JSON.stringify(e,null,2)}\n`)}async function jn({bucket:e,digest:t,projectId:n,source:r,store:i}){if(on(t),await kn(r)!==t)throw Error(`I18n object source does not match declared SHA-256 digest ${t}.`);let a=un(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 kn(o)!==t)throw Error(`Existing immutable i18n object ${a} failed integrity verification.`)}finally{await U(o,{force:!0})}}async function Mn({bucket:e,key:t,reference:n,store:r,temporaryDirectory:i}){let a=An(n),o=L(i,`reference-${W()}.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 Oe(o,a,{flag:`wx`});try{await r.upload(e,t,o,`application/json`)}finally{await U(o,{force:!0})}let s=L(i,`reference-${W()}.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 Nn({bucket:e,manifest:t,projectId:n,store:r,temporaryDirectory:i}){let a=An(t),o=On(a),s=L(i,`manifest-${o}.json`);await Oe(s,a,{flag:`wx`});try{await jn({bucket:e,digest:o,projectId:n,source:s,store:r})}finally{await U(s,{force:!0})}return o}async function Pn({bucket:e,key:t,store:n,temporaryDirectory:r}){if(!await n.has(e,t))return;let i=L(r,`reference-${W()}.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 sn(r.revision),on(r.snapshot),r}finally{await U(i,{force:!0})}}async function Fn({bucket:e,projectId:t,revision:n,store:r,temporaryDirectory:i}){let a=await Pn({bucket:e,key:dn(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 In({bucket:e,projectId:t,reference:n,store:r,tag:i,temporaryDirectory:a}){await Mn({bucket:e,key:dn(t,n.revision),reference:n,store:r,temporaryDirectory:a}),i&&await Mn({bucket:e,key:fn(t,i),reference:n,store:r,temporaryDirectory:a})}async function Ln({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:a}){on(n);let o=L(R(t),`v1`,`sha256`,n.slice(0,2),n);if(await zn(o,n)===!1){await V(I(o),{recursive:!0});let t=`${o}.${process.pid}.${W()}.tmp`;try{if(await i.download(e,un(r,n),t),await kn(t)!==n)throw Error(`Downloaded i18n object failed SHA-256 verification: ${n}.`);await U(o,{force:!0}),await Te(t,o)}finally{await U(t,{force:!0})}}await V(I(a),{recursive:!0});let s=`${a}.${process.pid}.${W()}.tmp`;try{if(await be(o,s),await kn(s)!==n)throw Error(`Cached i18n object failed SHA-256 verification: ${n}.`);await U(a,{force:!0}),await Te(s,a)}finally{await U(s,{force:!0})}}async function Rn({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,temporaryDirectory:a}){let o=L(a,`manifest-${n}.json`);await Ln({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}.`);sn(s.revision),s.baseline!==void 0&&on(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}.`);on(e.digest)}return s}async function zn(e,t){try{return(await Ee(e)).isFile()&&await kn(e)===t}catch{return!1}}async function Bn({cwd:e=process.cwd(),env:t=process.env}={}){if((await Pe({cwd:e})).i18n){if(t.COREFRAME_I18N_RELEASE_REVISION){await Un({cwd:e,env:t,revision:t.COREFRAME_I18N_RELEASE_REVISION});return}await hn(e)}}async function Vn({cwd:e=process.cwd(),projectConfig:t}={}){let n=t??await Pe({cwd:e});if(!n.i18n)return;let r=Wn(n.i18n),i=X(e,r.directory);try{if(!(await Ee(i)).isDirectory())throw Error(`I18n catalog path is not a directory: ${i}.`)}catch(t){if(t.code!==`ENOENT`)throw t;await hn(e);return}for(let t of r.locales)for(let n of r.catalogs)try{if(!(await Ee(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 hn(e);return}}async function Hn({cwd:e=process.cwd(),env:t=process.env,store:n,tag:r}){pn(r);let i=await Gn({cwd:e,env:t,store:n});await $n(e);let a=await Qn(e);await er(e,r,a);let o=await Ce(L(je(),`coreframe-i18n-prepare-`));try{let n=await Fn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,revision:a,store:i.store,temporaryDirectory:o});if(n){let e=await Rn({bucket:i.assets.sourceBucket,cacheRoot:i.cacheRoot,digest:n.snapshot,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return Zn(i,e,a),await qn(i,e),await In({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:n,store:i.store,tag:r,temporaryDirectory:o}),{reused:!0,snapshot:n.snapshot}}return await Xn(i,o,async()=>{let n=await Kn(i,a,o);n||await Yn(i),await hn(e);let s=await _n({config:i.config,cwd:e}),c=await vn({config:i.config,cwd:e,env:t,messages:s});await yn({config:i.config,cwd:e,missing:s,response:c}),await bn({config:i.config,cwd:e}),await gn({config:i.config,cwd:e,strict:!0,temporaryDirectory:o});let l=await Jn(i),u={...n?{baseline:n}:{},catalogs:i.config.catalogs,files:l,generator:s.length>0?i.config.generator?.id??`unconfigured`:`none`,linguiVersion:await tr(e),locales:i.config.locales,projectId:i.assets.projectId,revision:a,sourceLocale:i.config.sourceLocale,version:1},d=await Nn({bucket:i.assets.sourceBucket,manifest:u,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return await In({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 Un({cwd:e=process.cwd(),env:t=process.env,revision:n,store:r}={}){let i=await Pe({cwd:e});if(!i.i18n)return;let a=await Gn({cwd:e,env:t,store:r,projectConfig:i}),o=sn(n??await Qn(e)),s=await Ce(L(je(),`coreframe-i18n-materialize-`));try{let e=await Fn({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 Rn({bucket:a.assets.sourceBucket,cacheRoot:a.cacheRoot,digest:e.snapshot,projectId:a.assets.projectId,store:a.store,temporaryDirectory:s});return Zn(a,t,o),await qn(a,t),{revision:o,snapshot:e.snapshot}}finally{await U(s,{force:!0,recursive:!0})}}function Wn(e){let t=cn(e.sourceLocale,`Source locale`),n=[...new Set(e.locales.map(e=>cn(e,`Locale`)))],r=[...new Set(e.catalogs.map(e=>cn(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 Gn({cwd:e=process.cwd(),env:t=process.env,projectConfig:n,store:r}){let i=n??await Pe({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:Wn(i.i18n),cwd:R(e),env:t,store:r??_e({config:a,env:t})}}async function Kn(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 Fn({bucket:e.assets.sourceBucket,projectId:e.assets.projectId,revision:sn(t),store:e.store,temporaryDirectory:n});if(!r)continue;let i=await Rn({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:r.snapshot,projectId:e.assets.projectId,store:e.store,temporaryDirectory:n});return Zn(e,i,t),await qn(e,i),r.snapshot}}async function qn(e,t){for(let n of t.files)if(await Ln({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:n.digest,projectId:e.assets.projectId,store:e.store,target:X(e.cwd,n.path)}),(await Ee(X(e.cwd,n.path))).size!==n.size)throw Error(`Materialized i18n artifact size does not match manifest: ${n.path}.`)}async function Jn(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 kn(a);await jn({bucket:e.assets.sourceBucket,digest:o,projectId:e.assets.projectId,source:a,store:e.store}),t.push({digest:o,path:i,size:(await Ee(a)).size})}return t.sort((e,t)=>e.path.localeCompare(t.path))}async function Yn(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 Me(`@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 Sn(X(e.cwd,Z(e.config,t,r)),a.parse(n)),o=!0}catch{}}return o}async function Xn(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 ve(o)}catch{continue}let s=L(t,`previous-catalogs`,a);await V(I(s),{recursive:!0}),await Te(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 Te(e,t);throw t}}function Zn(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 Qn(e){let{stdout:t}=await z(`git`,[`rev-parse`,`HEAD`],{cwd:e,stdin:`ignore`});return sn(t.trim())}async function $n(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 er(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 tr(e){let{stdout:t}=await z(`pnpm`,[`exec`,`lingui`,`--version`],{cwd:e,stdin:`ignore`});return t.trim()}const nr=[`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(` `),rr=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}}),ir=r(f,{displayName:`profile`,async from(e){return he(e)}}),ar=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}}),or=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in the packaged Flutter client.`,async from(e){return P(e)}}),sr=p({name:`assets`,cmds:{configure:n({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${nr}`,args:{profile:u({type:ir,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{B.note(nr,`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 ge({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(ar),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:c({long:`widths`,type:l(rr),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})=>pe(await ue({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(ar),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})=>pe(await de({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(ar),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 fe({fix:e,pack:n});pe(r,t),r.ok||(process.exitCode=1)}}),publish:n({name:`publish`,args:{pack:c({long:`pack`,type:l(ar),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 me({pack:t});pe(n,e),n.ok||(process.exitCode=1)}}),status:n({name:`status`,args:{pack:c({long:`pack`,type:l(ar),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 fe({pack:t});pe(n,e),n.ok||(process.exitCode=1)}})}}),cr=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:or,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e})=>oe({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})=>ie({check:e})}),prepare:n({name:`prepare`,description:`Build and package the React client for one Flutter platform.`,args:{platform:u({type:s(M),displayName:`platform`,description:`Flutter platform whose packaged client should be prepared.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:or,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>N({apiOrigin:e,platform:t})}),check:n({name:`check`,description:`Reject missing, stale, modified, or incorrectly targeted Flutter assets.`,args:{platform:u({type:s(M),displayName:`platform`,description:`Flutter platform whose packaged client should be checked.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:or,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>j({apiOrigin:e,platform:t})})}}),lr=p({name:`i18n`,cmds:{build:n({name:`build`,description:`Extract source messages or materialize an exact release catalog snapshot.`,args:{},handler:async()=>{await Bn()}}),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 Un({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 Hn({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),ur=G.platform===`win32`?`react-router.cmd`:`react-router`,dr=G.platform===`win32`?`panda.cmd`:`panda`;async function fr(e=G.cwd()){await hr(e),await mr(e,[`typegen`])}async function pr(e=G.cwd(),t=G.env){if((t.COREFRAME_PLATFORM??t.TAURI_ENV_PLATFORM??`web`)!==`web`)return;let n=F.resolve(e,`.coreframe/dashboard-build`),r=F.join(n,`client`),i=F.resolve(e,`dist/client/__dashboard`);await U(n,{force:!0,recursive:!0}),await gr(e,dr,[`build`],t),await mr(e,[`build`],t),await U(i,{force:!0,recursive:!0}),await V(F.dirname(i),{recursive:!0}),await xe(r,i,{recursive:!0})}async function mr(e,t,n=G.env){await gr(e,ur,t,n)}async function hr(e){await U(F.resolve(e,`dashboard/.react-router`),{force:!0,recursive:!0})}async function gr(e,t,n,r=G.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 _r=p({name:`dashboard`,cmds:{build:n({name:`build`,args:{},handler:()=>pr()}),typegen:n({name:`typegen`,args:{},handler:()=>fr()})}}),vr=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function yr(e,t){let n=xr(e,t);if(!Sr(n)||!Cr(n,[`description`,`requires`,`routes`,`verifier`])||!Tr(n.description)||n.requires!==void 0&&(!Array.isArray(n.requires)||!n.requires.every(Tr))||n.verifier!==void 0&&!Tr(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=>br(e));if(new Set(r).size!==r.length)throw Error(`${t} contains duplicate recipe requirements.`);let i=n.routes.map((e,n)=>{if(!Sr(e)||!wr(e,[`path`,`router`,`when`])||!Tr(e.path)||!Tr(e.router)||!Tr(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 br(e){if(!vr.test(e))throw Error(`Recipe names use lowercase letters, numbers, and single hyphens.`);return e}function xr(e,t){try{return Ge(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Sr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Cr(e,t){return Object.keys(e).every(e=>t.includes(e))}function wr(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function Tr(e){return typeof e==`string`&&e.length>0}const Er=`https://github.com/airlock-labs/coreframe.git`;function Dr(e,t){return K(`git`,e,{cwd:t,encoding:`utf8`})}function Or(e,t){let n=Dr(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 kr(e,t){let n=Dr([`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 Ar({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`}={}){if(n.length===0)throw Error(`Remote name must not be empty.`);Or([`rev-parse`,`--show-toplevel`],e);let r=kr(n,e);if(r===null)Or([`remote`,`add`,n,Er],e),console.log(`Added ${n} remote: ${Er}`);else if(r===Er)console.log(`${n} remote already points at ${Er}`);else throw Error(`${n} remote points at ${r}, not ${Er}.\nChoose the intended template source before continuing, then update or rename the remote manually.`);t&&(Or([`fetch`,n,`--tags`,`--prune`],e),console.log(`Fetched ${n}.`))}const jr=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;function Mr(e){return jr.test(e)?`v${e}`:e}function Nr(e){return`${Mr(e)}:template`}function Pr(e,t){return`${Nr(e)}/${t}`}function Fr({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`,target:r}={}){let i=zr(e),a=Ur(i,[`rev-parse`,`--show-toplevel`]),o=Mr(r??Br(i));return Ar({cwd:a,fetch:t,remote:n}),{projectRoot:i,ref:o,repositoryRoot:a}}function Ir(e,t,n){return Lr(e,t,n).toString(`utf8`)}function Lr(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}. ${Wr([`show`,r],i)}`);return i.stdout}function Rr(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(Wr([`ls-tree`,t,n],r));return r.stdout.toString(`utf8`).split(`\0`).filter(Boolean)}function zr(e){let t=R(e);for(;;){let e=L(t,`package.json`),n=Hr(e);if(n!==void 0&&Vr(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 Br(e){let t=L(e,`package.json`),n=Hr(t);if(n===void 0)throw Error(`Required file package.json does not exist.`);let r=Vr(n,t).engines?.coreframe;if(!r)throw Error(`package.json must declare an exact engines.coreframe recipe baseline.`);return r}function Vr(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Hr(e){try{return J(e,`utf8`)}catch(e){if(Gr(e)&&e.code===`ENOENT`)return;throw e}}function Ur(e,t){let n=K(`git`,t,{cwd:e,encoding:`utf8`});if(n.status!==0)throw Error(Wr(t,n));return n.stdout.trim()}function Wr(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 Gr(e){return e instanceof Error&&`code`in e}const Kr=[{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 desktop, iOS, and Android development platforms`,test:e=>Q(e,[`"desktop"`,`"ios"`,`"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:`src/web/tauri/mobile-platform.ts`,requirement:`centralize supported Tauri mobile-platform detection`,test:e=>Q(e,[`getTauriMobilePlatform`,`import.meta.env.PLATFORM`])},{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:`src-tauri/.agents/references/ios-device-testing.md`,requirement:`install physical iOS device-testing guidance beside the native owner`,test:e=>Q(e,[`pnpm dev ios`,`Connect via network`])},{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 the Tauri release-artifact workflow`,test:e=>Q(e,[`Build Tauri Release Artifacts`,`pnpm exec tauri`])}],qr=[`CoreframeTemplateProject7A91C`,`coreframe-template-project-7a91c`,`coreframe_template_project_7a91c`,`com.example.coreframetemplateproject7a91c`];function Jr(e){let t=[];for(let n of Kr){let r=L(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=L(e,`src-tauri/tauri.conf.json`);q(n)?Yr(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);q(r)&&qr.some(e=>J(r,`utf8`).includes(e))&&t.push(`${n} must replace the Coreframe template identity sentinel.`)}return t}function Yr(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 Xr({name:e,...t}){let n=Fr(t),r=`recipes/${e}/recipe.yaml`,i=$r(yr(Ir(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 Zr(e){console.log(`Verified Coreframe recipe ${e.name} from ${e.ref}.`)}function Qr(e,t){for(let n of e){let e=`recipes/${n}/recipe.yaml`,r=$r(yr(Ir(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 $r(e,t){if(!e)throw Error(`Required recipe does not declare a verifier.`);if(e===`tauri`)return Jr(t);throw Error(`Unknown recipe verifier ${JSON.stringify(e)}.`)}function ei({cwd:e=process.cwd(),fetch:t=!0,name:n,remote:r=`template`,target:i}){br(n);let a=Fr({cwd:e,fetch:t,remote:r,target:i}),{projectRoot:o,ref:s,repositoryRoot:c}=a,l=`recipes/${n}`,u=`${l}/recipe.yaml`,d=yr(Ir(c,s,u),u);Qr(d.requires,a);let f=Ir(c,s,`${l}/RECIPE.md`),p=Rr(c,s,`${l}/files`),m=Rr(c,s,`${l}/patches`),h=Rr(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(si(t,`Recipe file ${e}`),t.startsWith(`.agents/`))throw Error(`Recipe file ${e} must be stored in the recipe's .agents directory.`);g.set(t,Lr(c,s,e)),_.set(t,e)}for(let e of h){let t=e.slice(`${l}/`.length);if(ii(t,`Recipe asset ${e}`),g.has(t))throw Error(`Recipe declares ${t} as both a file and an agent asset.`);g.set(t,Lr(c,s,e)),_.set(t,e)}for(let e of m){let t=ci(e,l);if(g.has(t))throw Error(`Recipe declares ${t} as both a file and a patch.`);let n=Lr(c,s,e);li(n.toString(`utf8`),t,e),oi(o,t),ui(o,n,!1)?(v.push({contents:n,destinationPath:t}),x.push(t)):ui(o,n,!0)?S.push(t):b.push({destination:t,source:e})}let w=new Map;for(let[e,t]of g){let r=pi(oi(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(ii(e.router,`Recipe route router`),ai(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(oi(o,e.path)))throw Error(`Recipe route target ${e.path} does not exist.`);let t=T.get(e.router)??ni(mi(oi(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=mi(oi(o,e),e),r=Ke(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=oi(o,e);ze(I(n),{recursive:!0}),We(n,t)}return v.length>0&&di(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 ti(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 ni(e,t){let n=ri(e,t);if(!hi(n)||!gi(n,[`routes`,`rules`])||!Array.isArray(n.rules)||!n.rules.every(_i)||!Array.isArray(n.routes))throw Error(`${t} must contain only string rules and a routes array.`);let r=n.routes.map((e,n)=>{if(!hi(e)||!gi(e,[`path`,`when`])||!_i(e.path)||!_i(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 ri(e,t){try{return Ge(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function ii(e,t){if(!e.startsWith(`.agents/`))throw Error(`${t} must be a normalized project-relative path beneath .agents/.`);si(e,t)}function ai(e,t){if(si(e,t),!/(?:^|\/)\.agents\/rules\/.+\.md$/u.test(e))throw Error(`${t} must point to a Markdown rule beneath an .agents/rules directory.`)}function oi(e,t){si(t,`Recipe destination`);let n=L(e,t),r=e;for(let e of t.split(`/`))if(r=L(r,e),q(r)&&Re(r).isSymbolicLink())throw Error(`Recipe destination ${t} crosses symbolic link ${r}.`);return n}function si(e,t){if(e.length===0||se(e)||e===`..`||e.startsWith(`../`)||e.includes(`\\`)||ce.normalize(e)!==e)throw Error(`${t} must be a normalized project-relative path.`)}function ci(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 si(r,`Recipe patch ${e}`),r}function li(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 ui(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 di(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 fi(e){return pi(e)?.toString(`utf8`)}function pi(e){try{return J(e)}catch(e){if(vi(e)&&e.code===`ENOENT`)return;throw e}}function mi(e,t){let n=fi(e);if(n===void 0)throw Error(`Required file ${t} does not exist.`);return n}function hi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function gi(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function _i(e){return typeof e==`string`&&e.length>0}function vi(e){return e instanceof Error&&`code`in e}function yi(e={}){let{ref:t,repositoryRoot:n}=Fr(e),r=Rr(n,t,`recipes`).filter(e=>/^recipes\/[^/]+\/recipe\.yaml$/u.test(e)).map(e=>{let r=e.split(`/`)[1];return br(r),{description:yr(Ir(n,t,e),e).description,name:r}});return r.sort((e,t)=>e.name.localeCompare(t.name)),{recipes:r,ref:t}}function bi(e){console.log(`Coreframe recipes at ${e.ref}:`);for(let t of e.recipes)console.log(`${t.name} — ${t.description}`)}const xi=`.agents/skills/coreframe-upgrade/SKILL.md`;function Si(e,t={}){return K(`git`,e,t)}function Ci(e){return e.stderr.toString(`utf8`).trim()||e.stdout.toString(`utf8`).trim()}function wi(e,t){let n=Pr(e,t),r=Si([`show`,n],{encoding:`utf8`});if(r.status!==0){let e=Ci(r);throw Error(`Could not read ${n}.${e?` ${e}`:``}`)}return r.stdout.toString()}function Ti(){let e=Si([`rev-parse`,`--show-toplevel`],{encoding:`utf8`});if(e.status!==0){let t=Ci(e);throw Error(`Could not find git repository root.${t?` ${t}`:``}`)}return e.stdout.toString().trim()}function Ei(e,t){let n=Be(L(je(),`coreframe-upgrade-skill-`)),r=L(n,`SKILL.md`);try{We(r,t);let n=Ci(Si([`--no-pager`,`diff`,`--no-index`,`--color=never`,`--`,e,r]));n&&console.log(n)}finally{He(n,{force:!0,recursive:!0})}}function Di({apply:e,target:t}){let n=L(Ti(),xi),r=Mr(t);if(!q(n))throw Error(`Local ${xi} does not exist.`);let i=J(n,`utf8`),a=wi(t,xi);return i===a?(console.log(`Coreframe upgrade skill matches ${r}:template/${xi}.`),0):e?(We(n,a),console.error(`Updated ${xi} from ${r}:template. Reread it before continuing the upgrade.`),20):(console.error(`Coreframe upgrade skill differs from ${r}:template/${xi}.`),console.error(`Run again with --apply to update it, then reread ${xi} before continuing.`),Ei(n,a),20)}const Oi=[{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`}],ki=new Set([`100644`,`100755`,`120000`]);function Ai(e,t={}){return K(`git`,e,t)}function ji(e){let t=Ai(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 Mi(e){let t=Ai(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 Ni(){return ji([`rev-parse`,`--show-toplevel`]).trim()}function Pi(e){let t=L(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 Fi(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 Ii(e,t){let n=Fi(Mi([`diff`,`--name-status`,`-z`,`--no-renames`,Nr(e),Nr(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 Li(e,t){let n=Mi([`ls-tree`,`-z`,Nr(e),`--`,t]);if(n.length===0)return null;let r=Fi(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 Ri(e){return Mi([`cat-file`,`blob`,e.object])}function zi(e,t){let n=R(e,t),r=e.endsWith(le)?e:`${e}${le}`;if(n!==e&&!n.startsWith(r))throw Error(`Refusing to access path outside repository: ${t}`);return n}function Bi(e){try{return Re(e),!0}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return!1;throw e}}function Vi(e){return(e.mode&73)!=0}function Hi(e){return e===null||e.type===`blob`&&ki.has(e.mode)}function Ui(e){return Oi.find(t=>t.matches(e))?.reason}function Wi(e,t,n){let r=zi(e,t);if(n===null)return{matches:!Bi(r)};if(!Hi(n))return{matches:!1,reason:`unsupported template entry mode ${n.mode} ${n.type}`};let i;try{i=Re(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=Ri(n);return n.mode===`120000`?i.isSymbolicLink()?{matches:Buffer.from(Ve(r),`utf8`).equals(a)}:{matches:!1,reason:`worktree path is not a symlink`}:i.isFile()?(n.mode===`100755`?Vi(i):!Vi(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 Gi(e){Bi(e)&&He(e,{force:!0,recursive:!1})}function Ki(e,t,n){let r=zi(e,t);if(n===null){Gi(r);return}if(ze(I(r),{recursive:!0}),n.mode===`120000`){Gi(r),Ue(Ri(n).toString(`utf8`),r);return}let i=Bi(r)?Re(r):null;i&&!i.isFile()&&Gi(r),We(r,Ri(n)),Le(r,n.mode===`100755`?493:420)}function qi(e,t){return e===null&&t!==null?`add`:e!==null&&t===null?`delete`:`update`}function Ji(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 Yi(e){let t=Ni(),n=Mr(e.base??Pi(t)),r=Mr(e.target),i=Ii(n,r),a=[],o=[],s=[],c=[];for(let e of i){let i=Ui(e.path);if(i){o.push({action:`ignored`,path:e.path,reason:i});continue}let l=Li(n,e.path),u=Li(r,e.path),d=qi(l,u);if(!Hi(l)||!Hi(u)){s.push({action:d,path:e.path,reason:`unsupported template entry type`});continue}if(Wi(t,e.path,u).matches){c.push({action:`unchanged`,path:e.path});continue}let f=Wi(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)Ki(t,e.path,e.targetEntry??null);console.log(`Coreframe template fast-forward: ${n} -> ${r}`),console.log(``),Ji(e.apply?`Applied clean template updates`:`Would apply clean template updates`,a),Ji(`Ignored downstream-owned paths`,o),Ji(`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 Xi=[`dependencies`,`devDependencies`];function Zi(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 Qi(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}: ${e instanceof Error?e.message:e}`)}}function $i(e,t){let n=`${Mr(e)}:${t}`;return Qi(Zi([`show`,n]),n)}function ea(e){return e.startsWith(`@coreframe/`)}function ta(e){return e.startsWith(`file:`)||e.startsWith(`link:`)||e.startsWith(`workspace:`)}function na(e){return e.startsWith(`file:`)||e.startsWith(`link:`)}function ra(e,t){let n=e.indexOf(`:`),r=e.slice(n+1),i=ce.normalize(ce.join(`template`,r,`package.json`));if(r.length===0||ce.isAbsolute(r)||i===`..`||i.startsWith(`../`))throw Error(`Invalid local template dependency for ${t}: ${e}`);return i}function ia(e){let t=$i(e,`template/package.json`),n=[],r=new Set;for(let i of Xi)for(let[a,o]of Object.entries(t[i]??{})){if(!ea(a)||!na(o))continue;if(r.has(a))throw Error(`Target template declares ${a} more than once.`);let t=ra(o,a),s=$i(e,t);if(s.name!==a||typeof s.version!=`string`)throw Error(`${Mr(e)}:${t} must declare ${a} with a version.`);n.push({group:i,name:a,spec:`^${s.version}`}),r.add(a)}return n}function aa(e,t){for(let n of Xi){let r=e[n]?.[t];if(r)return{group:n,spec:r}}}function oa(e,t,n){let r=t.match(/\n([\t ]+)"/u)?.[1]??` `,i=t.endsWith(`
9
+ `)?`
10
+ `:``;We(e,`${JSON.stringify(n,null,r)}${i}`)}function sa(e,t){if(t.length!==0){console.log(`${e}:`);for(let e of t)console.log(` ${e}`);console.log(``)}}function ca(e){let t=R(Zi([`rev-parse`,`--show-toplevel`]).trim(),`package.json`),n=J(t,`utf8`),r=Qi(n,t),i=Mr(e.target),a=ia(i),o=new Set(a.map(({name:e})=>e)),s=[],c=[],l=[],u=0;for(let e of a){let t=aa(r,e.name);if(!t){c.push(`missing: ${e.name} ${e.spec} (${e.group})`);continue}if(ta(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=Xi.flatMap(e=>Object.entries(r[e]??{}).filter(([e])=>ea(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;oa(t,n,r)}console.log(`Coreframe package sync: ${i}`),console.log(``),sa(e.apply?`Updated Coreframe packages`:`Would update Coreframe packages`,s.map(({currentSpec:e,name:t,spec:n})=>`update: ${t} ${e} -> ${n}`)),sa(`Missing target Coreframe packages`,c),sa(`Locally linked Coreframe packages`,l),sa(`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 la={...f,displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return br(e)}},ua=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})=>Ar({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=Di({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})=>Yi({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})=>ca({apply:e,target:t})})}}),da=p({name:`recipes`,cmds:{apply:n({name:`apply`,args:{recipe:u({type:la,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})=>ti(ei({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})=>bi(yi({fetch:!e,remote:t,target:n}))}),verify:n({name:`verify`,args:{recipe:u({type:la,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})=>Zr(Xr({fetch:!e,name:t,remote:n,target:r}))})}}),fa=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})=>D(`generate`,e)}),migrate:n({name:`migrate`,args:{args:d({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>D(`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:E}),seed:n({name:`seed`,args:{},handler:()=>te()}),"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})=>D(`studio`,e)})}}),pa=`package.json`;async function ma(e=process.argv.slice(2),t=process.env){let n=ha(e);Ca(n);let{packageJson:r,source:i}=await ct(pa),a=await Pe(),o=ft(a.deploy??{},n.environment,t);Oa(t,[`POSTHOG_API_KEY`,`POSTHOG_PROJECT_ID`]);let s=await wa(o,n.environment,()=>Ze({env:t})),c=mt({args:n,config:n.environment===`production`?o.tauriRelease:{},env:t});Da(n.environment,c.enabled),await xt(c);let l=await lt({environment:n.environment}),u=l.values.DASHBOARD_PASSWORD??await ka(t,n.environment);St(await Qe({environment:n.environment}),n.environment,{availableNames:[...Object.keys(l.values),...u?[`DASHBOARD_PASSWORD`]:[]]});let d=await rt({environment:n.environment}),f=await Sa();await Un({env:t,revision:f});let p=f.slice(0,12),m=pt(n.environment,r.version,p),h=dt(r.name,m),g={...Ma(t,n.environment,h,r.name,m),COREFRAME_I18N_RELEASE_REVISION:f},_=n.environment===`production`,y=!1,b={files:[]};B.intro(`Deploy ${h} to ${n.environment}`);let x=Object.keys(l.values).sort();x.length>0&&B.note(x.join(`
11
+ `),`Pending Worker secret updates`),d.provisioned&&B.log.info(`Provisioning Coreframe-managed access-token signing material.`),await Ea(n);let S=await ya(await v({config:a.database,env:t})),w=await O(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 xa(n,S);try{_&&(await wt(pa,r,m),b=await Tt(c,m)),B.log.step(`Running pre-deploy build`),await z(`pnpm`,[`build`],{env:Na(g),stdio:`inherit`});let e=c.enabled?await it({env:Na(g),plan:c,releaseName:h,version:m}):void 0;B.log.step(`Running release build and uploading PostHog source maps`),y=!0,await z(`pnpm`,[`build`],{env:g,stdio:`inherit`}),T&&(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?{[qe]:d.value}:{},...l.values},i=Object.keys(t).length>0?await Aa(t):void 0,f=await $e({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 Je(l),await Ct({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 _t(o,p)),n.skipPostDeployChecks||(B.log.step(`Running post-deploy checks`),await vt(o,p)),e&&(B.log.step(`Uploading Tauri release artifacts to Backblaze B2`),await bt(c,e)),B.outro(`Deployed ${h} to ${n.environment}`)}catch(e){throw!y&&_&&(await Oe(pa,i),await ht(b)),e}}function ha(e){return{environment:ga(e[0]),runMigrations:e.includes(`--run-migrations`),skipMigrations:e.includes(`--skip-migrations`),skipPostDeployChecks:e.includes(`--skip-post-deploy-checks`),tauriLocalPlatforms:_a(e,`--tauri-local-platform`).map(e=>nt(e)),tauriWorkflowName:va(e,`--tauri-workflow-name`),tauriWorkflowPlatforms:_a(e,`--tauri-workflow-platform`).map(e=>nt(e)),tauriWorkflowRef:va(e,`--tauri-workflow-ref`),yes:e.includes(`--yes`)}}function ga(e){if(e&&Ye.includes(e))return e;throw Error(`Deploy environment must be one of: ${Ye.join(`, `)}.`)}function _a(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 va(e,t){let n=_a(e,t);if(n.length>1)throw Error(`${t} can only be provided once.`);return n[0]}async function ya(e){try{return await ba(e)}finally{await e.close?.()}}async function ba(e){return b(await _(),await ee(e))}async function xa(e,t){if(t.length===0)return B.log.info(`No pending deploy migrations.`),!1;if(B.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 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 Sa(){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 Ca(e){if(e.runMigrations&&e.skipMigrations)throw Error(`Use only one of --run-migrations or --skip-migrations.`)}async function wa(e,t,n=Ze){return e.url?Ta(e.url,t):t===`staging`&&e.stagingHostname?Ta(await n(),t):Ta(void 0,t)}function Ta(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 Ea(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 Da(e,t){if(e===`staging`&&t)throw Error(`Tauri releases can only be published from production deploys.`)}function Oa(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 ka(e,t){let n=e.DASHBOARD_PASSWORD?.trim();if(n)return n;let r;try{r=Ft(await H(`.env`,`utf8`))}catch(e){throw ja(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 Aa(e){let t=await Ce(L(je(),`coreframe-deploy-secrets-`)),n=L(t,`secrets.json`);return await Oe(n,JSON.stringify(e),{mode:384}),{path:n,dispose:()=>U(t,{force:!0,recursive:!0})}}function ja(e){return e instanceof Error&&`code`in e}function Ma(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 Na(e){let{POSTHOG_API_KEY:t,POSTHOG_PROJECT_ID:n,...r}=e;return r}const $={access:ve,chmod:ye,mkdir:V,mkdtemp:Ce,readFile:H,readFileSync:J,rm:U,writeFile:Oe},Pa={getAvailablePort:Ia},Fa={homedir:ke,kill:G.kill,networkInterfaces:Ae,tmpdir:je};async function Ia(){let e=Ut();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 La(){let e=await za();return typeof e.mobileDevHost==`string`?{mobileDevHost:e.mobileDevHost}:{}}async function Ra(e){let t=await za(),n=Ba();await $.mkdir(F.dirname(n),{recursive:!0}),await $.writeFile(n,`${JSON.stringify({...t,...e},void 0,2)}\n`)}async function za(){try{let e=await $.readFile(Ba(),`utf8`),t=JSON.parse(e);return Va(t)?t:{}}catch{return{}}}function Ba(){return F.join(Fa.homedir(),`.coreframe`,`preferences.json`)}function Va(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Ha({env:e=G.env,interactive:t=G.stdin.isTTY===!0,platform:n,target:r}){let i=await qa(n,e).catch(()=>[]),a=r?uo(i,r):void 0;if(a)return a;if(!r&&i.length>0)return Ka(i,n,t);let o=r?uo(await Ya(e).catch(()=>[]),r):void 0;if(o&&o.platform===n)return Xa(o,n,e,t);let s=await Ja(n,e),c=r?uo(s,r):void 0;if(c)return c;if(!r&&s.length>0)return Ka(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 Ua(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=po();if(i.length===0)throw Error(`No external IP address was detected. Pass one explicitly with --host.`);let a=await Wa();if(a&&i.includes(a))return a;if(i.length===1)return await Ga(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 Ga(o),o}async function Wa(){return(await La()).mobileDevHost}async function Ga(e){try{await Ra({mobileDevHost:e})}catch(e){B.log.warn(`Could not remember the mobile development IP address: ${e instanceof Error?e.message:String(e)}`)}}async function Ka(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 qa(e,t){return e===`android`?Qa(t):eo(t)}async function Ja(e,t){return e===`android`?$a(t):to(t)}async function Ya(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 Xa(e,t,n,r){let i=await Za(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 Za(t,n).catch(()=>[]),o=uo(a,e.id);if(o)return o;let s=a.filter(e=>!i.some(t=>t.id===e.id));if(s.length>0)return Ka(s,t,r);if(a.length===1)return a[0];await Wt(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 Za(e,t){return e===`ios`?to(t,`booted`):(await Qa(t)).filter(e=>!e.physical)}async function Qa(e){let t=await ro(e,`platform-tools`,G.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 ao(t,e,n,`ro.product.model`),i=n.startsWith(`emulator-`),a=i?await so(t,e,n,r):await co(t,e,n,r);return{id:n,label:a===r?a:`${a} (${r})`,name:a,physical:!i}}))).sort(mo)}async function $a(e){let{stdout:t}=await z(await ro(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 eo(e){let t=await $.mkdtemp(F.join(Fa.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(no).map(e=>({id:e.hardwareProperties.udid,label:`${e.deviceProperties.name} (${e.hardwareProperties.productType})`,name:e.deviceProperties.name,physical:!0})).sort(mo)}finally{await $.rm(t,{force:!0,recursive:!0})}}async function to(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(mo)}function no(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 ro(e,t,n){let r=e.ANDROID_HOME??e.ANDROID_SDK_ROOT,i=r?[r]:io(e);for(let e of i){let r=F.join(e,t,n);try{return await $.access(r),r}catch{}}return n}function io(e){return G.platform===`darwin`?[F.join(Fa.homedir(),`Library`,`Android`,`sdk`)]:G.platform===`win32`&&e.LOCALAPPDATA?[F.join(e.LOCALAPPDATA,`Android`,`Sdk`)]:[F.join(Fa.homedir(),`Android`,`Sdk`)]}async function ao(e,t,n,r){return(await oo(e,t,[`-s`,n,`shell`,`getprop`,r])).trim()}async function oo(e,t,n){return(await z(e,n,{env:t,timeout:3e3})).stdout}async function so(e,t,n,r){return oo(e,t,[`-s`,n,`emu`,`avd`,`name`]).then(e=>e.split(/\r?\n/)[0]?.trim()||r).catch(()=>r)}async function co(e,t,n,r){return oo(e,t,[`-s`,n,`shell`,`dumpsys`,`bluetooth_manager`]).then(e=>lo(e)||r).catch(()=>r)}function lo(e){return e.match(/\bname: (.+)/)?.[1]?.trim()}function uo(e,t){let n=e.map(e=>({device:e,score:Math.max(fo(t,e.name),fo(t,e.id))})).sort((e,t)=>t.score-e.score)[0];return n&&n.score>0?n.device:void 0}function fo(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 po(){return[...new Set(Object.values(Fa.networkInterfaces()).flatMap(e=>e??[]).filter(e=>!e.internal&&e.family===`IPv4`).map(e=>e.address))].sort()}function mo(e,t){return e.label.localeCompare(t.label)}function ho({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 go(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=Ut(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 go(e,t){let n=Date.now()+1e4,r;for(;!t();)try{return await _o(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 _o({host:e=`127.0.0.1`,port:t}){return new Promise((n,r)=>{let i=Ht({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 vo={command:Po,isRunning:To,stop(e){try{G.kill(e,`SIGTERM`)}catch(e){if(!Oo(e))throw e}},waitForExit:Eo};async function yo({confirmStop:e=So,cwd:t=G.cwd(),interactive:n=G.stdin.isTTY===!0,pid:r=G.pid,platform:i=`web`,processes:a=vo}={}){let o=await Lo(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 Ao({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 Oe(u,l,{flag:`wx`,mode:384});try{for(;;){try{return await Se(u,s),{owner:c,async release(){await wo(s,l)},takeoverApproved:f}}catch(e){if(!Do(e))throw e}let t=await xo({confirmStop:e,file:s,interactive:n,owner:c,processes:a});if(t===void 0)return;f||=t}}finally{await De(u).catch(()=>void 0)}}async function bo({cwd:e=G.cwd(),platform:t=`web`}={}){let{file:n}=await Lo(e,t);return(await Co(n))?.owner}async function xo({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await Co(t);if(!a||!Vo(a.owner,r)||!i.isRunning(a.owner.pid))return await wo(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 wo(t,a.source),!0}async function So(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 Co(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 wo(e,t){let n=await H(e,`utf8`).catch(()=>void 0);(t===void 0||n===t)&&await De(e).catch(()=>void 0)}function To(e){try{return G.kill(e,0),!0}catch(e){return!Oo(e)}}async function Eo(e){let t=Date.now()+1e4;for(;To(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 Do(e){return ko(e)&&e.code===`EEXIST`}function Oo(e){return ko(e)&&e.code===`ESRCH`}function ko(e){return e instanceof Error}async function Ao({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await jo(t);if(!a||!i.isRunning(a.owner.pid))return await wo(t,a?.source),!1;let o=i.command?.(a.owner.pid);if(!o||!Mo(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 wo(t,a.source),!0}async function jo(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 Mo(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:No(n.slice(i+1))===t}function No(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 Po(e){let t=G.platform===`win32`?Io(e):Fo(e);if(t.status===0)return t.stdout.trim()||void 0}function Fo(e){return K(`ps`,[`-p`,String(e),`-o`,`command=`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}function Io(e){return K(`powershell.exe`,[`-NoProfile`,`-NonInteractive`,`-Command`,`(Get-CimInstance Win32_Process -Filter 'ProcessId = ${e}').CommandLine`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}async function Lo(e,t){let n=await Ro(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 Ro(e){let t=zo(e);return t?{gitCommonDir:!0,path:await Bo(F.resolve(e,t))}:{gitCommonDir:!1,path:await Bo(e)}}function zo(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 Bo(e){return we(e).catch(()=>F.resolve(e))}function Vo(e,t){return e.platform===t.platform&&e.repository===t.repository}function Ho(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}async function Uo({cwd:e=G.cwd(),platform:t}){let n=await Wo({cwd:e});if(!n||!$o(n.platform)||!es(n.platform,t)||!ns(n.owner.pid))return;let r=await bo({cwd:e,platform:n.platform});if(!(!r||!rs(n.owner,r))&&!(n.postgres?.pid!==void 0&&!ns(n.postgres.pid)))return n}async function Wo({cwd:e=G.cwd()}={}){let t;try{t=JSON.parse(await H(qo(e),`utf8`))}catch{return}return Jo(t)&&t.cwd===F.resolve(e)?t:void 0}async function Go({cwd:e=G.cwd(),owner:t,platform:n,postgres:r,vitePort:i}){let a=qo(e),o=F.dirname(a),s=`${a}.${W()}.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 Oe(s,`${JSON.stringify(c)}\n`,{flag:`wx`,mode:384}),await Te(s,a)}finally{await De(s).catch(()=>void 0)}}async function Ko({cwd:e=G.cwd(),owner:t}){let n=qo(e),r=await Wo({cwd:e});!r||!rs(r.owner,t)||await De(n).catch(()=>void 0)}function qo(e){return F.resolve(e,`.coreframe/dev.session.json`)}function Jo(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.version===1&&typeof t.cwd==`string`&&Yo(t.owner)&&Zo(t.platform)&&ts(t.vite?.port)&&(t.postgres===void 0||Xo(t.postgres))}function Yo(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 Xo(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 Zo(e){return e===`android`||e===`desktop`||e===`ios`||e===`macos`||e===`web`}function Qo(e){return e===`android`||e===`ios`||e===`macos`}function $o(e){return e===`web`||Qo(e)}function es(e,t){return t===void 0?Qo(e):e===t}function ts(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0&&e<=65535}function ns(e){try{return G.kill(e,0),!0}catch(e){return e instanceof Error&&e.code===`EPERM`}}function rs(e,t){return e.pid===t.pid&&e.token===t.token}const is=G.platform===`win32`?`pnpm.cmd`:`pnpm`,as=G.platform===`win32`?`portless.cmd`:`portless`,os=G.platform===`win32`?`react-router.cmd`:`react-router`,ss=G.platform===`win32`?`turso.cmd`:`turso`;async function cs({cwd:e=G.cwd(),debug:t,device:n,env:r=G.env,host:i,https:a=!1,interactive:o=G.stdin.isTTY===!0,managed:s=!1,noManaged:c=!1,platform:l=`web`,fresh:u=!1,reuseVite:d=!1,verbose:f=!1,webPort:p,supervisor:m}){let h=Dt({env:r}),g=ms(l)?l:void 0,_=hs(l),v=l===`ios`||l===`android`?l:void 0,y=v?await Ha({env:r,interactive:o,platform:v,target:n}):void 0,b=v&&y?await Ua({device:y,host:i,interactive:o,platform:v}):void 0,x=g?!0:i,S=await h.measure(`config`,()=>Pe({cwd:e})),C=await h.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(s||o&&!c)&&await At(e));await h.measure(`i18n`,()=>Vn({cwd:e,projectConfig:S}));let w=await h.measure(`routing`,async()=>l===`web`&&r.PORTLESS!==`0`&&r.TAURI_ENV_PLATFORM===void 0&&!(await Bt()).isAgent&&await jt(e)),T=await h.measure(`https`,async()=>a&&!w?Mt({cwd:e}):void 0),ee=Ho(r,l),E={...ee,...h.environment,...C?{[Rt]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...g?{COREFRAME_PLATFORM:g}:void 0,...T?{[Ot]:T.cert,[kt]:T.key}:void 0},D=!1,O,te,ne,k,A,j,M,ie=new Map,N=[`postgres`,_];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}),ie.set(e,{stderr:r,stdout:n})}let ae=m.onEvent(e=>{e.event===`log`?(ie.get(e.resource)?.[e.stream])?.write(e.data):e.event===`service`&&e.resource===_&&e.state===`failed`&&(M=Error(e.error??`${_} development failed.`),P())}),P=()=>{D||(D=!0,ne?.kill(`SIGTERM`),k?.kill(`SIGTERM`),te?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0))},oe=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>{O??=e,P()};return G.on(e,t),{handler:t,signal:e}}),I=async e=>{let t=Vt(e);ne=t;try{await t.expectSuccess()}catch(e){if(!D)throw e}finally{ne===t&&(ne=void 0)}};try{if(await m.subscribe(N),ps(S)){let e=await m.acquirePostgres({config:S,env:E});A=e.leaseId,E={...E,...e.env}}if(S.database?.dialect===`sqlite`){let t=await Pa.getAvailablePort(),n=F.resolve(e,`.coreframe`),r=F.join(n,`turso.db`);await $.mkdir(n,{recursive:!0}),E={...E,TURSO_DATABASE_URL:`http://127.0.0.1:${t}`,TURSO_AUTH_TOKEN:`dev`},k=Vt({name:`turso`,command:ss,args:[`dev`,`--port`,String(t),`--db-file`,r],cwd:e,env:E}),await k.waitFor(`listening`)}(ps(S)||S.database?.dialect===`sqlite`)&&await h.measure(`schema`,()=>I({name:`db`,command:is,args:[`db`,`ensure`],cwd:e,env:E,prefix:!1}));let t=fs(p??r.COREFRAME_WEB_PORT),n=await m.status(),i=n.resources?.find(e=>e.resource===_),s=i!==void 0&&!u&&t===void 0?void 0:t??5173,c=s??i?.endpoint?.port??5173;if(s!==void 0&&n.resources?.some(e=>e.resource!==_&&e.endpoint?.port===c)){if(t!==void 0)throw Error(`Port ${c} is already used by another Coreframe development shell.`);c=await Pa.getAvailablePort()}if(!d){let t={...E,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[E.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:F.join(e,`node_modules`,`.bin`)+F.delimiter+(E.PATH??``)},n=[{args:w?[`run`,`--app-port`,String(c),`react-router`,`dev`,...x===void 0?[]:[`--host`,x===!0?`0.0.0.0`:x]]:[`dev`,...x===void 0?[]:[`--host`,x===!0?`0.0.0.0`:x],`--port`,String(c),...g?[`--strictPort`]:[]],command:w?as:os,cwd:e,env:t},{args:[`exec`,`panda`,`dev`,`--no-color`],command:is,cwd:e,env:E}],r=await m.acquireVite({configFingerprint:ds({cwd:e,host:x,https:a,portless:w,resource:_}),endpoint:{host:x===!0?`0.0.0.0`:x??`127.0.0.1`,port:c},processes:n,resource:_},u);j=r.leaseId,c=r.endpoint.port}if(h.report(),D)return;if(l===`web`?await us(m,_,()=>M):(await re({cwd:e}),await ls({cwd:e,env:ee,interactive:o,mobileHost:b,platform:l,port:c,requestStop:P,selectedDevice:y,isStopping:()=>D,setActiveNative:e=>{te=e},verbose:f})),M)throw M}finally{P(),j&&await m.release(j).catch(()=>void 0),A&&await m.release(A).catch(()=>void 0),ae();for(let{handler:e,signal:t}of oe)G.off(t,e);for(let e of ie.values())e.stdout.end(),e.stderr.end();O&&(G.exitCode??=O===`SIGINT`?130:143),m.close()}}async function ls({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 ae():void 0,f=z(`flutter`,[`run`,`-d`,s?.id??`macos`,`--dart-define=COREFRAME_DEV_SERVER_URL=${gs(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 us(e,t,n){await e.waitForServiceExit(t);let r=n();if(r)throw r}function ds({cwd:e,host:t,https:n,portless:r,resource:i}){return Ie(`sha256`).update(JSON.stringify({cwd:F.resolve(e),host:t??null,https:n,portless:r,resource:i})).digest(`hex`)}function fs(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 ps(e){return(e.database?.dialect??`postgres`)===`postgres`}function ms(e){return e===`android`||e===`ios`||e===`macos`}function hs(e){if(e===`web`)return`vite:web`;if(ms(e))return`vite:flutter:${e}`;throw Error(`Unsupported supervised development platform: ${e}.`)}function gs(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 _s=`extension:dev`;function vs(e){if(!q(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(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.${_s} for \`coreframe dev webext\`. Apply the wxt recipe and add its named extension lifecycle scripts.`)}function ys({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`,_s,...n.length>0?[`--`,...n]:[]]}const bs=[`web`,`webext`,`desktop`,`ios`,`android`,`macos`],xs=[`managed-dev-overlay`],Ss=F.resolve(`node_modules`,`.bin`),Cs=G.platform===`win32`?`pnpm.cmd`:`pnpm`,ws=G.platform===`win32`?`portless.cmd`:`portless`,Ts=G.platform===`win32`?`react-router.cmd`:`react-router`,Es=G.platform===`win32`?`turso.cmd`:`turso`;async function Ds({cwd:e=G.cwd(),debug:t,device:n,env:r=G.env,host:i,https:a=!1,interactive:o=G.stdin.isTTY===!0,managed:s=!1,noManaged:c=!1,platform:l=`web`,fresh:u=!1,reuseVite:d=!1,supervisor:f,verbose:p=!1,webPort:m}={}){let h=Dt({env:r}),g=r.PATH??r.Path??``,_=l===`ios`||l===`android`||l===`macos`?l:void 0,v=l===`web`||_!==void 0;if(u&&d)throw Error(`Cannot use --fresh and --reuse-vite together.`);let y=!u&&(_||l===`web`)?await h.measure(`dev-session`,()=>Uo({cwd:e,platform:l})):void 0,b=d||y!==void 0,x=l===`desktop`?void 0:Bs(m??r.COREFRAME_WEB_PORT);if(y&&x!==void 0&&x!==y.vite.port)throw Error(`The active development session uses port ${y.vite.port}. Omit --port or use that port when reusing it.`);let S=l===`ios`||l===`android`||l===`macos`?y?.vite.port??x??5173:l===`web`||l===`webext`?y?.vite.port??x:void 0,C,w,T,ee,E,D,O,te,ne,k=!1,A,j=r,M,ie;if(s&&c)throw Error(`Cannot use --managed and --no-managed together.`);if(t===`managed-dev-overlay`&&s)throw Error(`Cannot use --managed with --debug managed-dev-overlay.`);if(d&&_===void 0)throw Error(`The --reuse-vite option is only supported for Flutter development platforms (iOS, Android, and macOS).`);if(l===`webext`){if(s||c||t!==void 0||p)throw Error(`Managed development, debug features, and verbose native output are only supported for the main web or native development platforms.`);vs(e)}if(a&&l!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(n!==void 0&&l!==`ios`&&l!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);if(l===`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.");if(v&&r.COREFRAME_DEV_SUPERVISOR!==`0`){let h=f??await Et({cwd:e,env:r});if(h)return cs({cwd:e,debug:t,device:n,env:r,fresh:u,host:i,https:a,interactive:o,managed:s,noManaged:c,platform:l,reuseVite:d,supervisor:h,verbose:p,webPort:m})}let N=b?void 0:await h.measure(`dev-lock`,()=>yo({cwd:e,interactive:o,platform:l}));if(!b&&!N)return;let P=()=>{k||(k=!0,w?.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),ne?.close().catch(()=>void 0),te?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),C?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),E?.kill(`SIGTERM`))},oe=e=>{A??=e,P()},I=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>oe(e);return G.on(e,t),{handler:t,signal:e}}),se=async e=>{let t=Vt(e);w=t;try{await t.expectSuccess()}catch(e){if(!k)throw e}finally{w===t&&(w=void 0)}};try{let u=l===`ios`||l===`android`?l:void 0,d=u?await Ha({env:r,interactive:o,platform:u,target:n}):void 0,f=u&&d?await Ua({device:d,host:i,interactive:o,platform:u}):void 0,m=_?!0:i,v={},y=!1,x=!1,w;b||([v,y,x]=await Promise.all([h.measure(`config`,()=>Pe({cwd:e})),h.measure(`routing`,async()=>l===`web`&&r.PORTLESS!==`0`&&r.TAURI_ENV_PLATFORM===void 0&&!(await Bt()).isAgent&&await jt(e)),h.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(s||o&&!c)&&await At(e))]),await h.measure(`i18n`,()=>Vn({cwd:e,projectConfig:v})),w=l!==`webext`&&Os(e)?await Pa.getAvailablePort():void 0);let A=b?void 0:await h.measure(`https`,async()=>a&&!y?Mt({cwd:e}):void 0),oe=Ho(r,l);j={...oe,...h.environment,...x?{[Rt]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...l===`desktop`?{COREFRAME_TAURI_DEV:`1`,TAURI_ENV_PLATFORM:Ls()}:void 0,..._?{COREFRAME_PLATFORM:_}:void 0,...A?{[Ot]:A.cert,[kt]:A.key}:void 0,...w?{COREFRAME_DASHBOARD_ORIGIN:`http://127.0.0.1:${w}`}:void 0};let I=async()=>{if(!w)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([Lt(n.stdout),Lt(n.stderr)]),te===e&&(te=void 0)}};t=ho({port:w,start:async()=>{if(k)throw Error(`The dashboard development server was stopped before it started.`);let t=await Pa.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=z(Ts,[`dev`,`--host`,`127.0.0.1`,`--port`,String(t)],{cwd:F.resolve(e,`dashboard`),env:{...j,PATH:F.resolve(e,`node_modules/.bin`)+F.delimiter+g},stdin:`inherit`});te=a;let o=Promise.allSettled([ks(a.stdout,r),ks(a.stderr,i)]);return n(a,{outputTasks:o,stderr:i,stdout:r}),{host:`127.0.0.1`,port:t}}}),ne=t;try{await t.listen(),await t.wait()}finally{await t.close(),ne===t&&(ne=void 0)}},L=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=z(y?ws:Ts,y?zs({host:m,port:S}):Rs({host:m,port:S,strictPort:_!==void 0}),{cwd:e,env:{...j,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[j.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:Ss+F.delimiter+g},stdin:`inherit`});let r=Promise.allSettled([ks(D.stdout,t),ks(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([Lt(t),Lt(n)]),D=void 0}},ce=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=z(Cs,ys({host:i,port:S}),{cwd:e,env:j,stdin:`inherit`});let r=Promise.allSettled([ks(O.stdout,t),ks(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([Lt(t),Lt(n)]),O=void 0}},R=async t=>{for(;!k;){let n=l===`android`&&!p?await ae():void 0,r=l===`desktop`?z(Cs,Ps(),{cwd:e,env:oe,stdio:`inherit`}):z(`flutter`,Fs({device:d??{id:`macos`},serverUrl:Is(l,f,S),verbose:p}),{cwd:F.join(e,`src-flutter`),env:oe,stdio:n?[`inherit`,`pipe`,`pipe`]:`inherit`});C=r;try{await Promise.all([r,n?.capture(r)]);return}catch(e){if(l===`desktop`||k||!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{C===r&&(C=void 0)}}},le=async()=>{if(b){if(l===`web`)return;await re({cwd:e}),await R();return}if(l===`web`){await L();return}let t=L().then(()=>{if(!k)throw Error(`The Vite development server stopped while ${l===`desktop`?`Tauri`:`Flutter`} was still running.`)});l!==`desktop`&&await re({cwd:e});try{await Promise.race([t,R(t)])}finally{P(),await Promise.allSettled([t,C]),C=void 0}},ue=async()=>{let t=Vt({name:`panda`,command:Cs,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)}},de=async()=>{if(l===`webext`){await ce();return}if(b){await le();return}let e=ue(),t=le(),n=w?I():void 0;try{await Promise.race([e,t,n].filter(e=>e!==void 0)),k&&await t}finally{P(),await Promise.allSettled([e,t,n].filter(e=>e!==void 0))}},fe=async()=>{b||!N?.owner||S===void 0||(await Go({cwd:e,owner:N.owner,platform:l,postgres:ie,vitePort:S}),M=N.owner)};if(x&&(j={...j,[zt]:`1`}),k)return;if(l===`webext`){h.report(),await de();return}if(b){h.report(),await de();return}if(v.database?.dialect===`sqlite`&&(await h.measure(`database`,async()=>{let t=await Pa.getAvailablePort(),n=F.resolve(e,`.coreframe`),i=F.join(n,`turso.db`);await $.mkdir(n,{recursive:!0}),j={...j,TURSO_DATABASE_URL:`http://127.0.0.1:${t}`,TURSO_AUTH_TOKEN:`dev`},E=Vt({name:`turso`,command:Es,args:[`dev`,`--port`,String(t),`--db-file`,i],cwd:e,env:r}),await E.waitFor(`listening`)}),await h.measure(`schema`,()=>se({name:`db`,command:Cs,args:[`db`,`ensure`],cwd:e,env:j,prefix:!1})),k))return;if(Ns(v)){let t=Y({label:`postgres`});t.pipe(G.stdout,{end:!1});try{let n=await h.measure(`database`,()=>Ms({config:v,cwd:e,env:j,failIfRunning:!0,interactive:o,isStopping:()=>k,postgresOutput:t,takeoverApproved:N?.takeoverApproved??!1}));if(!n)return;T=n,j=n.env,ie=await js(n.env);try{k||await h.measure(`schema`,()=>se({name:`db`,command:Cs,args:[`db`,`ensure`],cwd:e,env:j,prefix:!1})),k||(await fe(),h.report(),await de())}finally{await n[Symbol.asyncDispose](),T===n&&(T=void 0)}}finally{t.end()}return}await fe(),h.report(),await de()}finally{P(),M&&=(await Ko({cwd:e,owner:M}),void 0);let t;try{await T?.[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)}As(t),await N?.release()}}function Os(e){return q(F.resolve(e,`dashboard/dashboard.config.ts`))}async function ks(e,t){for await(let n of e)t.write(`${n}\n`)||await It(t,`drain`)}function As(e){if(e)throw e}async function js(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 Ms({interactive:e,isStopping:t,takeoverApproved:n,...r}){try{return await k(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 A(i),t()?void 0:k(r)}}function Ns(e){return(e.database?.dialect??`postgres`)===`postgres`}function Ps(){return[`exec`,`tauri`,`dev`,`--config`,JSON.stringify({build:{beforeDevCommand:``}})]}function Fs({device:e,serverUrl:t,verbose:n}){return[`run`,`-d`,e.id,`--dart-define=COREFRAME_DEV_SERVER_URL=${t}`,...n?[`--verbose`]:[]]}function Is(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 Ls(){return G.platform===`win32`?`windows`:G.platform}function Rs({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 zs({host:e,port:t}){return[`run`,...t===void 0?[]:[`--app-port`,String(t)],`react-router`,...Rs({host:e,port:void 0})]}function Bs(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}const Vs=F.resolve(`node_modules`,`.bin`);G.env.PATH=Vs+F.delimiter+G.env.PATH;const Hs=G.platform===`win32`?`tsc.cmd`:`tsc`,Us=[{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 Ws(){let e=[];for(let t of Us)try{await ve(t.path),e.push(t)}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let t=e.map(e=>Vt({name:e.name,command:Hs,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 Gs=`worker-configuration.d.ts`;async function Ks({check:e=!1,cwd:t=process.cwd()}={}){let n=await Pe({cwd:t}),r=await et({coreframeConfig:n,cwd:t}),i=R(t,Gs),a=R(t,`.coreframe-worker-types-${W()}.d.ts`);try{await z(`pnpm`,[`exec`,`wrangler`,`types`,a,`--config`,r.path,`--strict-vars=false`,`--include-runtime=false`],{cwd:t,stdio:`inherit`});let o=qs(await H(a,`utf8`)),s=Fe(r.config),c=Ne(n.worker?.environment).filter(e=>!s.has(e.name)),l=`${o.trimEnd()}\n\n${Js(c)}\n`;if(e){if(await H(i,`utf8`).catch(()=>``)!==l)throw Error(`${Gs} 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 Oe(i,l),{changed:u!==l,path:i}}finally{await r.dispose(),await U(a,{force:!0})}}function qs(e){return e.split(/\r?\n/).filter(e=>!e.startsWith(`// Generated by Wrangler by running `)).join(`
12
+ `)}function Js(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(`
13
+ `)}const Ys=r(s(xs),{displayName:`feature`,from:async e=>e}),Xs=[`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.`],Zs=n({name:`deploy`,args:{environment:u({type:s(Ye),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(yt)),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(yt)),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})=>ma([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`]:[]])}),Qs=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 ut();if(e){console.log(JSON.stringify({...t,notices:Xs}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Xs.join(` `)}`)}}),url:n({name:`url`,args:{json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await Ze();console.log(e?JSON.stringify({url:t}):t)}})}}),$s=p({name:`secrets`,cmds:{"rotate-access-token":n({name:`rotate-access-token`,args:{environment:u({type:s(Ye),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 gt({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(Ye)),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 Qe({environment:e});console.log(t?JSON.stringify(n):rc(n))}}),set:n({name:`set`,args:{environment:u({type:s(Ye),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 at({environment:e,name:t,value:await ic(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await st(),i=n?await oc(r):await ac(r,e);await ot({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(Ye),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 Xe({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),ec=n({name:`typecheck`,args:{},handler:Ws}),tc=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 Ks({check:e});console.log(e?`${cc(t.path)} is current.`:`${cc(t.path)} ${t.changed?`generated`:`is unchanged`}.`)}})}}),nc=n({name:`dev`,args:{debug:c({long:`debug`,type:l(Ys),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.`}),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(bs)),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,managed:a,noManaged:o,platform:s,port:c,reuseVite:l,stop:u,verbose:d})=>u?Nt({cwd:G.cwd()}):Ds({debug:e,device:t,fresh:n,host:r,https:i,managed:a,noManaged:o,platform:s??`web`,reuseVite:l,verbose:d,webPort:c})});function rc(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(`
14
+ `)}async function ic(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 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 ac(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 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 oc(e){if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let t=G.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 sc();if(B.isCancel(t))throw B.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);let{ignoredNames:n,values:r}=tt(t,e);return n.length>0&&B.log.info(`Ignored non-secret or undeclared names: ${n.join(`, `)}.`),r}async function sc(){let e=``;for await(let t of G.stdin)e+=t.toString();return e}function cc(e){return e.split(/[\\/]/).at(-1)??e}function lc(e,{formatMessage:t,temporaryDirectory:n=je(),write:r=e=>console.error(e)}={}){let i=hc(e),a=_c(dc(e,t),i);try{let t=L(Be(L(n,`coreframe-error-`)),`error.log`);return We(t,`${_c(fc(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,lc(e,n),process.exit(1))};process.once(`uncaughtException`,a),process.once(`unhandledRejection`,a),Promise.resolve().then(r).catch(a)}function dc(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 fc(e){try{let t=pc(e);if(!(e instanceof Error)||!mc(t))return Pt(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${Pt(t,{customInspect:!1,depth:10})}`:``}`}catch{return`The thrown value could not be inspected.`}}function pc(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:pc(a.value,t),writable:!0})}return i}function mc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hc(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`?gc(t.value,n):r(t.value))}}}try{r(e)}catch{}return n}function gc(e,t){if(!(typeof e!=`object`||!e))for(let n of Reflect.ownKeys(e)){let r=Object.getOwnPropertyDescriptor(e,n);r&&`value`in r&&typeof r.value==`string`&&r.value&&t.add(r.value)}}function _c(e,t){return[...t].sort((e,t)=>t.length-e.length).reduce((e,t)=>e.replaceAll(t,`[redacted environment value]`),e)}const vc=p({name:`coreframe`,cmds:{build:tn,dashboard:_r,assets:sr,flutter:cr,i18n:lr,deploy:Zs,staging:Qs,secrets:$s,typecheck:ec,worker:tc,dev:nc,upgrade:ua,recipes:da,db:fa}});import.meta.main&&uc(vc,{formatMessage:process.argv[2]===`db`?x:void 0});export{vc as coreframeCli};
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@coreframe/scripts",
3
- "version": "0.1.49",
3
+ "version": "0.1.50",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/airlock-labs/coreframe.git",
7
- "directory": "scripts"
7
+ "directory": "node/scripts"
8
8
  },
9
9
  "bin": {
10
10
  "coreframe": "./bin/coreframe.js"
@@ -15,53 +15,39 @@
15
15
  ],
16
16
  "type": "module",
17
17
  "exports": {
18
- "./*": {
19
- "types": "./dist/*.d.ts",
20
- "default": "./dist/*.js"
18
+ ".": {
19
+ "types": "./dist/coreframe.d.ts",
20
+ "default": "./dist/coreframe.js"
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
24
  "@alloc/cmd-ts": "0.17.1",
25
- "@aws-sdk/client-s3": "^3.1090.0",
26
25
  "@clack/prompts": "^1.6.0",
27
26
  "@vercel/detect-agent": "^1.2.3",
28
- "cross-keychain": "1.1.0",
29
- "drizzle-orm": "1.0.0-rc.4",
30
- "import-meta-resolve": "^4.2.0",
31
- "local-postgres": "0.3.1",
32
- "mp4box": "^2.4.1",
33
- "music-metadata": "^11.14.0",
34
27
  "nano-spawn": "^2.1.0",
35
28
  "procband": "^0.3.8",
36
- "saxes": "^6.0.0",
37
- "tinyglobby": "^0.2.17",
38
- "yaml": "^2.9.0"
29
+ "yaml": "^2.9.0",
30
+ "@coreframe/config": "^0.1.0",
31
+ "@coreframe/db": "^0.1.0",
32
+ "@coreframe/deploy": "^0.1.0",
33
+ "@coreframe/dev": "^0.1.0",
34
+ "@coreframe/dev-contracts": "^0.1.0",
35
+ "@coreframe/assets": "^0.1.0",
36
+ "@coreframe/object-storage": "^0.1.0",
37
+ "@coreframe/flutter-tools": "^0.1.0"
39
38
  },
40
39
  "devDependencies": {
41
40
  "@types/node": "^26.1.0",
42
- "sharp": "^0.34.5",
41
+ "drizzle-orm": "1.0.0-rc.4",
43
42
  "tsdown": "0.22.3",
44
43
  "typescript": "6.0.3",
45
- "vite": "^8.1.0",
46
44
  "vitest": "^4.1.9"
47
45
  },
48
- "peerDependencies": {
49
- "sharp": "^0.34.5",
50
- "vite": "^8.0.0"
51
- },
52
- "peerDependenciesMeta": {
53
- "sharp": {
54
- "optional": true
55
- },
56
- "vite": {
57
- "optional": true
58
- }
59
- },
60
46
  "scripts": {
61
47
  "build": "tsdown",
62
48
  "test": "vitest run --reporter=minimal",
63
49
  "typecheck": "tsc --noEmit -p tsconfig.json",
64
- "format": "oxfmt",
50
+ "format": "oxlint --fix && oxfmt",
65
51
  "lint": "oxlint"
66
52
  }
67
53
  }
@@ -1 +0,0 @@
1
- function e(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function r(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:r.bind(null,!1),a:r.bind(null,!0),d:function(){var r,i=this.e,a=0;function o(){for(;r=n.pop();)try{if(!r.a&&a===1)return a=0,n.push(r),Promise.resolve().then(o);if(r.d){var e=r.d.call(r.v);if(r.a)return a|=2,Promise.resolve(e).then(o,s)}else a|=1}catch(e){return s(e)}if(a===1)return i===t?Promise.resolve():Promise.reject(i);if(i!==t)throw i}function s(n){return i=i===t?n:new e(n,i),o()}return o()}}}export{e as default};
@@ -1,187 +0,0 @@
1
- //#region assets/contracts.d.ts
2
- declare const catalogSchemaVersion: 2;
3
- declare const manifestSchemaVersion: 2;
4
- type AssetKind = "image" | "svg" | "audio" | "video" | "lottie";
5
- type AssetCatalog = {
6
- schemaVersion: typeof catalogSchemaVersion;
7
- assets: Record<string, AssetCatalogEntry>;
8
- packs?: Record<string, AssetCatalogPack>;
9
- };
10
- type AssetCatalogPack = {
11
- assets: Record<string, AssetCatalogEntry>;
12
- };
13
- type AssetCatalogEntry = ImageCatalogEntry | SvgCatalogEntry | AudioCatalogEntry | VideoCatalogEntry | LottieCatalogEntry;
14
- type ImageCatalogEntry = {
15
- kind: "image";
16
- source: AssetSource;
17
- alt: string;
18
- variantWidths?: number[];
19
- };
20
- type SvgCatalogEntry = {
21
- kind: "svg";
22
- source: AssetSource;
23
- alt: string;
24
- };
25
- type AudioCatalogEntry = {
26
- kind: "audio";
27
- source: AssetSource;
28
- };
29
- type VideoCatalogEntry = {
30
- kind: "video";
31
- source: AssetSource;
32
- };
33
- type LottieCatalogEntry = {
34
- kind: "lottie";
35
- source: AssetSource;
36
- };
37
- type AssetSource = {
38
- digest: string;
39
- filename: string;
40
- mediaType: string;
41
- size: number;
42
- };
43
- type AssetManifest = {
44
- schemaVersion: typeof manifestSchemaVersion;
45
- pack?: string;
46
- assets: Record<string, AssetManifestEntry>;
47
- };
48
- type AssetManifestEntry = ImageManifestEntry | SvgManifestEntry | AudioManifestEntry | VideoManifestEntry | LottieManifestEntry;
49
- type ImageManifestEntry = {
50
- kind: "image";
51
- sourceDigest: string;
52
- alt: string;
53
- width: number;
54
- height: number;
55
- variants: AssetVariant[];
56
- };
57
- type SvgManifestEntry = {
58
- kind: "svg";
59
- sourceDigest: string;
60
- alt: string;
61
- viewBox: SvgViewBox;
62
- file: SvgAssetFile;
63
- };
64
- type AudioManifestEntry = {
65
- kind: "audio";
66
- sourceDigest: string;
67
- durationSeconds: number;
68
- file: AudioAssetFile;
69
- };
70
- type VideoManifestEntry = {
71
- kind: "video";
72
- sourceDigest: string;
73
- width: number;
74
- height: number;
75
- durationSeconds: number;
76
- hasAudio: boolean;
77
- file: VideoAssetFile;
78
- };
79
- type LottieManifestEntry = {
80
- kind: "lottie";
81
- sourceDigest: string;
82
- width: number;
83
- height: number;
84
- frameRate: number;
85
- durationSeconds: number;
86
- file: LottieAssetFile;
87
- };
88
- type SvgViewBox = {
89
- minX: number;
90
- minY: number;
91
- width: number;
92
- height: number;
93
- };
94
- type AssetVariant = {
95
- format: "webp";
96
- mediaType: "image/webp";
97
- width: number;
98
- height: number;
99
- path: string;
100
- size: number;
101
- hash: string;
102
- };
103
- type AssetFile = SvgAssetFile | AudioAssetFile | VideoAssetFile | LottieAssetFile;
104
- type SvgAssetFile = {
105
- format: "svg";
106
- mediaType: "image/svg+xml";
107
- path: string;
108
- size: number;
109
- hash: string;
110
- };
111
- type AudioAssetFile = {
112
- format: "mp3";
113
- mediaType: "audio/mpeg";
114
- path: string;
115
- size: number;
116
- hash: string;
117
- };
118
- type VideoAssetFile = {
119
- format: "mp4";
120
- mediaType: "video/mp4";
121
- path: string;
122
- size: number;
123
- hash: string;
124
- };
125
- type LottieAssetFile = {
126
- format: "json";
127
- mediaType: "application/json";
128
- path: string;
129
- size: number;
130
- hash: string;
131
- };
132
- type AssetOutput = AssetVariant | AssetFile;
133
- type AssetProblem = {
134
- code: "CATALOG_MISSING" | "GENERATED_ASSET_MISSING" | "INVALID_ALT" | "INVALID_ASSET_ID" | "INVALID_CATALOG" | "INVALID_MANIFEST" | "INVALID_MEDIA" | "INVALID_REFERENCE" | "INVALID_SOURCE" | "INVALID_VARIANT_PATH" | "INVALID_VARIANT_WIDTHS" | "MANIFEST_MISSING" | "MANIFEST_STALE" | "REFERENCE_MISSING" | "SCHEMA_MIGRATION_REQUIRED" | "SOURCE_UNAVAILABLE";
135
- message: string;
136
- assetId?: string;
137
- file?: string;
138
- fix?: string;
139
- };
140
- type AssetStatus = {
141
- ok: boolean;
142
- assets: AssetStatusEntry[];
143
- problems: AssetProblem[];
144
- };
145
- type AssetStatusEntry = {
146
- assetId: string;
147
- source: AssetSource;
148
- outputs: AssetOutputStatus[];
149
- };
150
- type AssetOutputStatus = AssetOutput & {
151
- exists: boolean;
152
- };
153
- type AssetBuildResult = {
154
- ok: boolean;
155
- assets: AssetBuildEntry[];
156
- fetched: string[];
157
- problems: AssetProblem[];
158
- };
159
- type AssetBuildEntry = {
160
- assetId: string;
161
- outputs: AssetOutput[];
162
- };
163
- type AssetPublishResult = {
164
- ok: boolean;
165
- uploaded: PublishedAsset[];
166
- skipped: PublishedAsset[];
167
- reportPath: string;
168
- problems: AssetProblem[];
169
- };
170
- type PublishedAsset = {
171
- assetId: string;
172
- source: string;
173
- target: string;
174
- size: number;
175
- };
176
- type LoadedAssetCatalog = {
177
- catalog: AssetCatalog;
178
- problems: AssetProblem[];
179
- migrated?: boolean;
180
- migrationRequired?: boolean;
181
- };
182
- type LoadedAssetManifest = {
183
- manifest: AssetManifest;
184
- problems: AssetProblem[];
185
- };
186
- //#endregion
187
- export { AssetBuildEntry, AssetBuildResult, AssetCatalog, AssetCatalogEntry, AssetCatalogPack, AssetFile, AssetKind, AssetManifest, AssetManifestEntry, AssetOutput, AssetOutputStatus, AssetProblem, AssetPublishResult, AssetSource, AssetStatus, AssetStatusEntry, AssetVariant, AudioAssetFile, AudioCatalogEntry, AudioManifestEntry, ImageCatalogEntry, ImageManifestEntry, LoadedAssetCatalog, LoadedAssetManifest, LottieAssetFile, LottieCatalogEntry, LottieManifestEntry, PublishedAsset, SvgAssetFile, SvgCatalogEntry, SvgManifestEntry, SvgViewBox, VideoAssetFile, VideoCatalogEntry, VideoManifestEntry, catalogSchemaVersion, manifestSchemaVersion };
@@ -1 +0,0 @@
1
- const e=2,t=2;export{e as catalogSchemaVersion,t as manifestSchemaVersion};