@proofkit/cli 2.0.0-beta.23 → 2.0.0-beta.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e,i as t,n,o as r,s as i,t as a}from"./consts-BZnOMxpW.js";import{readFileSync as o}from"node:fs";import
|
|
3
|
-
`);
|
|
4
|
-
`}});await e.writeFile(r,
|
|
5
|
-
`)}const
|
|
6
|
-
`)}function Ze(e){return e.filter(e=>Ke.has(e)?!1:e===`.gitignore`?!0:!e.startsWith(`.`))}const Qe=e=>S.gen(function*(){let t=yield*j,n=yield*A,r=yield*O,i=yield*k;if(!(yield*S.promise(()=>t.exists(e.targetDir)))||Ze(yield*S.promise(()=>t.readdir(e.targetDir))).length===0)return;if(e.request.force){yield*S.promise(()=>t.emptyDir(e.targetDir));return}if(r.nonInteractive)throw Error(`${e.request.appDir} already exists and isn't empty. Remove the existing files or choose a different directory.`);let a=yield*S.promise(()=>i.select({message:`${e.request.appDir} already exists and isn't empty. How would you like to proceed?`,options:[{value:`abort`,label:`Abort installation`},{value:`clear`,label:`Clear the directory and continue`},{value:`overwrite`,label:`Continue and overwrite conflicting files`}]}));if(a===`abort`)throw new P;if(a===`clear`){if(!(yield*S.promise(()=>i.confirm({message:`Are you sure you want to clear the directory?`,initialValue:!1}))))throw new P;yield*S.promise(()=>t.emptyDir(e.targetDir));return}n.warn(`Continuing in ${e.request.appDir} and overwriting conflicting files when needed.`)}),$e=e=>S.gen(function*(){let t=yield*O,n=yield*j,r=yield*A,i=yield*Oe,o=yield*N,c=yield*Ee,l=yield*De,u=yield*ke,d=yield*M,f=[];yield*Qe(e),r.info(`Scaffolding in ${e.targetDir}`),yield*S.promise(()=>n.copyDir(e.templateDir,e.targetDir,{overwrite:!0}));let p=s.join(e.targetDir,`_gitignore`),m=s.join(e.targetDir,`.gitignore`);(yield*S.promise(()=>n.exists(p)))&&((yield*S.promise(()=>n.exists(m)))?yield*S.promise(()=>n.remove(p)):yield*S.promise(()=>n.rename(p,m)));let h=s.join(e.targetDir,`package.json`),g=oe(Ge(yield*S.promise(()=>n.readJson(h)),e.packageJson));yield*S.promise(()=>n.writeJson(h,g)),yield*S.promise(()=>i.writeSettings(e.targetDir,e.settings)),yield*S.promise(()=>n.writeFile(e.envFile.path,e.envFile.content));for(let t of e.writes)yield*S.promise(()=>n.writeFile(t.path,t.content));yield*S.promise(()=>L(n,e.targetDir,`__PNPM_COMMAND__`,e.packageManagerCommand)),yield*S.promise(()=>L(n,e.targetDir,`__PACKAGE_MANAGER__`,e.request.packageManager)),yield*S.promise(()=>L(n,e.targetDir,`__AGENT_INSTRUCTIONS__`,a)),e.request.importAlias!==`~/`&&(yield*S.promise(()=>L(n,e.targetDir,`~/`,Fe(e.request.importAlias))),yield*S.promise(()=>L(n,e.targetDir,`@/`,e.request.importAlias.replace(qe,``).replace(Je,`/`))));let _=e.settings;if(e.tasks.bootstrapFileMaker&&e.request.fileMaker){let t=e.request.fileMaker;_=yield*S.promise(()=>o.bootstrap(e.targetDir,_,t,e.request.appType)),yield*S.promise(()=>i.writeSettings(e.targetDir,_))}if(e.tasks.checkWebViewerAddon&&(yield*S.promise(async()=>{try{let{checkForWebViewerLayouts:n,getWebViewerAddonMessages:i}=await import(`./proofkit-webviewer-73IB1OBU.js`),a=i(await n(e.targetDir));for(let e of a.warn)r.warn(e);for(let e of a.info)r.info(e);t.nonInteractive&&f.push(...a.nextSteps)}catch(e){let t=e instanceof Error?e.message:String(e);r.warn(`Could not inspect the ProofKit WebViewer add-on (${t}).`)}})),e.tasks.runInstall){let t=[`install`];e.request.packageManager===`yarn`&&(t=[]),yield*S.promise(()=>c.run(e.request.packageManager,t,{cwd:e.targetDir,stdout:`pipe`,stderr:`pipe`}))}e.tasks.runInitialCodegen&&(yield*S.promise(()=>u.runInitial(e.targetDir,e.request.packageManager))),e.tasks.initializeGit&&(yield*S.promise(()=>l.initialize(e.targetDir)));let v=yield*S.promise(()=>d.getVersion(e.request.packageManager,e.targetDir));return r.success(`Created ${e.request.scopedAppName} in ${e.targetDir}${v?` using ${e.request.packageManager}@${v}`:``}`),r.info(R.bold(`Next steps:`)),r.info(Xe(e,Array.from(new Set(f)))),e}),et=/\/+$/,tt=/\\/g,nt=/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function rt(e){return e.replace(tt,`/`)}function it(e){return rt(e).replace(et,``)}function at(e){let t=it(e).split(`/`),n=t.at(-1)??``;n===`.`&&(n=s.basename(s.resolve(process.cwd())));let r=t.findIndex(e=>e.startsWith(`@`));r!==-1&&(n=t.slice(r).join(`/`));let i=t.filter(e=>!e.startsWith(`@`)).join(`/`);return[n,i]}function ot(e){let t=it(e);if(t===`.`){let e=s.basename(s.resolve(process.cwd()));return nt.test(e)?void 0:`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}let n=t.split(`/`),r=n.findIndex(e=>e.startsWith(`@`)),i=n.at(-1);if(r!==-1&&(i=n.slice(r).join(`/`)),!nt.test(i??``))return`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}const st={noGit:!1,noInstall:!1,force:!1,default:!1,CI:!1,importAlias:`~/`};function ct(e,t){let n=e.split(`.`).map(e=>Number.parseInt(e,10)||0),r=t.split(`.`).map(e=>Number.parseInt(e,10)||0);for(let e=0;e<Math.max(n.length,r.length);e+=1){let t=n[e]??0,i=r[e]??0;if(t>i)return 1;if(t<i)return-1}return 0}function lt(e){if(!!e.layoutName!=!!e.schemaName)throw Error(`Both --layout-name and --schema-name must be provided together.`)}async function ut({prompt:e,fileMakerService:t,flags:n,nonInteractive:r}){if(lt(n),!n.server&&r)throw Error(`Missing required hosted FileMaker inputs in non-interactive mode: --server, --file-name, and --data-api-key.`);let i=n.server??await e.text({message:`What is the URL of your FileMaker Server?`,validate:e=>{try{let t=e.startsWith(`http`)?e:`https://${e}`;new URL(t);return}catch{return`Please enter a valid URL`}}}),{normalizedUrl:a,versions:o}=await t.validateHostedServerUrl(i),s=new URL(a),c=n.fileName,l=n.dataApiKey,u=n.layoutName,d=n.schemaName,f,p=[],m=()=>{if(!f)throw Error(`OttoFMS authentication is required for hosted setup.`);return f};if(!(c&&l)){if(!(n.adminApiKey||o.ottoVersion&&ct(o.ottoVersion,`4.7.0`)>=0))throw Error(`OttoFMS 4.7.0 or later is required to auto-login. Upgrade OttoFMS or pass --admin-api-key for hosted setup.`);f=n.adminApiKey??(await t.getOttoFMSToken({url:s})).token}if(!c){if(r)throw Error(`Missing required FileMaker inputs in non-interactive mode: --file-name, --data-api-key.`);p=await t.listFiles({url:s,token:m()}),c=await e.searchSelect({message:`Which file would you like to connect to?`,options:[{value:`$deploy-demo`,label:`Deploy NEW ProofKit Demo File`,hint:`Use OttoFMS to deploy a new file for testing`,keywords:[`demo`,`proofkit`]},...p.slice().sort((e,t)=>e.filename.localeCompare(t.filename)).map(e=>({value:e.filename,label:e.filename,hint:e.status,keywords:[e.filename]}))]})}if(!c)throw Error(`No FileMaker file was selected.`);if(c===`$deploy-demo`){p.length===0&&(p=await t.listFiles({url:s,token:m()}));let n=p.some(e=>e.filename===`ProofKitDemo.fmp12`),i=n&&!r?await e.confirm({message:`The demo file already exists. Do you want to replace it with a fresh copy?`,initialValue:!1}):n,a=await t.deployDemoFile({url:s,token:m(),operation:i?`replace`:`install`});c=a.filename,l=a.apiKey,u??=`API_Contacts`,d??=`Contacts`}if(!l&&r)throw Error(`Missing required FileMaker inputs in non-interactive mode: --data-api-key.`);if(!l){let n=(await t.listAPIKeys({url:s,token:m()})).filter(e=>e.database===c),r=n.length===0?`create`:await e.searchSelect({message:`Which OttoFMS Data API key would you like to use?`,options:[...n.map(e=>({value:e.key,label:`${e.label} - ${e.user}`,hint:`${e.key.slice(0,5)}...${e.key.slice(-4)}`,keywords:[e.label,e.user,e.database]})),{value:`create`,label:`Create a new API key`,hint:`Requires FileMaker credentials for this file`,keywords:[`create`,`new`]}]});if(r===`create`){let n=await e.text({message:`Enter the account name for ${c}`,validate:e=>e?void 0:`An account name is required`}),r=await e.password({message:`Enter the password for ${n}`,validate:e=>e?void 0:`A password is required`});l=(await t.createDataAPIKeyWithCredentials({url:s,filename:c,username:n,password:r})).apiKey}else l=r}if(!l)throw Error(`No FileMaker Data API key was selected.`);let h=await t.listLayouts({dataApiKey:l,fmFile:c,server:s.origin});if(u&&!h.includes(u))throw Error(`Layout "${u}" was not found in ${c}.`);return r||u||d||await e.confirm({message:`Do you want to configure an initial layout for type generation now?`,initialValue:!1})&&(u=await e.searchSelect({message:`Select a layout to read data from`,options:h.map(e=>({value:e,label:e,keywords:[e]}))}),d=await e.text({message:`What should the generated schema be called?`,defaultValue:Ne(u),validate:e=>e?void 0:`A schema name is required`})),{mode:`hosted-otto`,dataSourceName:`filemaker`,envNames:F(`filemaker`),server:s.origin,fileName:c,dataApiKey:l,layoutName:u,schemaName:d,adminApiKey:n.adminApiKey,fmsVersion:o.fmsVersion,ottoVersion:o.ottoVersion}}async function dt({prompt:e,fileMakerService:t,flags:n,appType:r,nonInteractive:i}){if(n.dataSource!==`filemaker`)return{fileMaker:void 0,skipFileMakerSetup:!1};if(lt(n),r===`webviewer`&&!n.server)for(;;){let r=await t.detectLocalFmMcp();if(r.healthy&&r.connectedFiles[0])return{fileMaker:{mode:`local-fm-mcp`,dataSourceName:`filemaker`,envNames:F(`filemaker`),fmMcpBaseUrl:r.baseUrl,fileName:r.connectedFiles[0],layoutName:n.layoutName,schemaName:n.schemaName},skipFileMakerSetup:!1};if(i)throw r.healthy?Error(`ProofKit MCP Server was detected, but no FileMaker files are open. Open a file in FileMaker and rerun, or pass --server.`):Error(`ProofKit MCP Server was not detected and no FileMaker server was provided. Start the ProofKit MCP Server locally or rerun with --server.`);let a=await e.select({message:r.healthy?`I noticed you have the ProofKit MCP Server installed, but no files are open. How would you like to continue?`:`ProofKit MCP Server was not detected. How would you like to continue?`,options:[{value:`retry`,label:`Try again`,hint:r.healthy?`Open a FileMaker file, then retry detection`:`Retry ProofKit MCP Server detection`},{value:`hosted`,label:`Continue with hosted setup`,hint:`Use OttoFMS and a hosted FileMaker server`},{value:`skip`,label:`Skip for now`,hint:`Create the project and configure FileMaker later`}]});if(a!==`retry`){if(a===`skip`)return{fileMaker:void 0,skipFileMakerSetup:!0};break}}return{fileMaker:await ut({prompt:e,fileMakerService:t,flags:n,nonInteractive:i}),skipFileMakerSetup:!1}}const ft=(e,t)=>S.gen(function*(){let r={...st,...t},i=yield*k,a=yield*N,o=yield*O,s=o.nonInteractive||r.CI||r.nonInteractive===!0,c=e;if(!c){if(s)return yield*S.fail(Error(`Project name is required in non-interactive mode.`));c=yield*S.promise(()=>i.text({message:`What will your project be called?`,defaultValue:n,validate:ot}))}if(!c)return yield*S.fail(Error(`Project name is required.`));let l=ot(c);if(l)return yield*S.fail(Error(l));let u=r.appType??`browser`;r.appType||s||(u=yield*S.promise(()=>i.select({message:`What kind of app do you want to build?`,options:[{value:`browser`,label:`Web App for Browsers`,hint:`Uses Next.js and hosted deployment`},{value:`webviewer`,label:`FileMaker Web Viewer`,hint:`Uses Vite for FileMaker web viewers`}]})).pipe(S.map(e=>e)));let d=!!(r.server||r.adminApiKey||r.dataApiKey||r.fileName||r.layoutName||r.schemaName),f=`none`;if(r.dataSource?f=r.dataSource:u===`webviewer`&&(f=d||!(s&&!r.server)?`filemaker`:`none`),!(s||r.dataSource)&&u!==`webviewer`&&(f=yield*S.promise(()=>i.select({message:`Do you want to connect to a FileMaker Database now?`,options:[{value:`filemaker`,label:`Yes`,hint:`Set up env, datasource config, and typegen now`},{value:`none`,label:`No`,hint:`You can add a data source later`}]})).pipe(S.map(e=>e))),s&&!r.dataSource&&d||s&&f!==`filemaker`&&d)return yield*S.fail(Error(`FileMaker flags require --data-source filemaker in non-interactive mode.`));let{fileMaker:p,skipFileMakerSetup:m}=yield*S.promise(()=>dt({prompt:i,fileMakerService:a,flags:{...r,dataSource:f},appType:u,nonInteractive:s})),[h,g]=at(c);return{projectName:c,scopedAppName:h,appDir:g,appType:u,ui:r.ui??`shadcn`,dataSource:f,packageManager:o.packageManager,noInstall:r.noInstall,noGit:r.noGit,force:r.force,cwd:o.cwd,importAlias:r.importAlias,nonInteractive:s,debug:o.debug,fileMaker:p,skipFileMakerSetup:m,hasExplicitFileMakerInputs:d}});async function pt(e){try{await de(e)}catch{}}function mt(){return new fe.Agent({rejectUnauthorized:process.env.PROOFKIT_ALLOW_INSECURE_TLS!==`1`})}async function V(e,t){return await D.get(e,{headers:t?.headers,httpsAgent:mt(),timeout:t?.timeout??1e4,validateStatus:null})}async function ht(e,t,n){return await D.post(e,t,{headers:n?.headers,httpsAgent:mt(),timeout:n?.timeout??1e4,validateStatus:null})}async function gt(e,t){return await D.delete(e,{headers:t?.headers,httpsAgent:mt(),timeout:t?.timeout??1e4,validateStatus:null})}function _t(){let e=process.env.npm_config_user_agent;return e?e.startsWith(`yarn`)?`yarn`:e.startsWith(`pnpm`)?`pnpm`:e.startsWith(`bun`)?`bun`:`npm`:`npm`}const vt=Symbol.for(`@proofkit/new/prompt-cancelled`),yt=pe,H=he,bt=ge,xt=_e;function St(e){return e instanceof Error&&e.name===`ExitPromptError`}function U(e){return e().catch(e=>{if(St(e))return vt;throw e})}function Ct(e){return e===vt||me(e)}function wt(e){if(e)return t=>e(t)??!0}function Tt(e,t){return[e.label,e.hint??``,...e.keywords??[]].join(` `).toLowerCase().includes(t.trim().toLowerCase())}function W(e){return typeof e==`string`?e:e?!0:void 0}function Et(e,t){let n=t?.trim();return n?e.filter(e=>Tt(e,n)):e}function Dt(e){return U(()=>be({message:e.message,default:e.defaultValue,validate:wt(e.validate)}))}function Ot(e){return U(()=>xe({message:e.message,validate:wt(e.validate)}))}function kt(e){return U(()=>ye({message:e.message,default:e.initialValue}))}function At(e){return U(()=>Ce({message:e.message,pageSize:10,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}))}function jt(e){return U(()=>Se({message:e.message,pageSize:10,source:t=>{let n=Et(e.options,t);return n.length===0?[{value:`__no_matches__`,name:e.emptyMessage??`No matches found. Keep typing to refine your search.`,disabled:e.emptyMessage??`No matches found`}]:n.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}}))}function Mt(e){return U(()=>ve({message:e.message,pageSize:10,required:e.required,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}))}function G(e){if(Ct(e))throw new P;return e}function Nt(e){return e.startsWith(`https://`)?e:e.startsWith(`http://`)?e.replace(`http://`,`https://`):`https://${e}`}function Pt(e){let t=e=>e.isFolder===!0?(Array.isArray(e.folderLayoutNames)?e.folderLayoutNames:[]).flatMap(e=>t(e)):typeof e.name==`string`?[e.name]:[];return e.flatMap(t).sort((e,t)=>e.localeCompare(t))}const Ft={text:async e=>G(await Dt({message:e.message,defaultValue:e.defaultValue,validate:e.validate})).toString(),password:async e=>G(await Ot({message:e.message,validate:e.validate})).toString(),select:async e=>G(await At({message:e.message,options:e.options})),searchSelect:async e=>G(await jt(e)),multiSearchSelect:async e=>G(await Mt(e)),confirm:async e=>G(await kt({message:e.message,initialValue:e.initialValue}))},It={info:e=>H.info(e),warn:e=>H.warn(e),error:e=>H.error(e),success:e=>H.success(e),note:(e,t)=>bt(e,t)},K={exists:async e=>E.pathExists(e),readdir:async e=>E.readdir(e),emptyDir:async e=>E.emptyDir(e),copyDir:async(e,t,n)=>E.copy(e,t,{overwrite:n?.overwrite??!0}),rename:async(e,t)=>E.rename(e,t),remove:async e=>E.remove(e),readJson:async e=>E.readJson(e),writeJson:async(e,t)=>E.writeJson(e,t,{spaces:2}),writeFile:async(e,t)=>E.writeFile(e,t,`utf8`),readFile:async e=>E.readFile(e,`utf8`)},Lt={getTemplateDir:(t,n)=>t===`webviewer`?s.join(e,`vite-wv`):n===`mantine`?s.join(e,`nextjs-mantine`):s.join(e,`nextjs-shadcn`)},Rt={getVersion:async(e,t)=>{if(e===`bun`)return;let{stdout:n}=await T(e,[`-v`],{cwd:t});return n.trim()}},zt={run:async(e,t,n)=>{let r=await T(e,t,{cwd:n.cwd,stdout:n.stdout??`pipe`,stderr:n.stderr??`pipe`});return{stdout:r.stdout??``,stderr:r.stderr??``}}},Bt={initialize:async e=>{await T(`git`,[`init`],{cwd:e}),await T(`git`,[`add`,`.`],{cwd:e}),await T(`git`,[`commit`,`-m`,`Initial commit`],{cwd:e})}},Vt={writeSettings:async(e,t)=>E.writeJson(s.join(e,`proofkit.json`),t,{spaces:2}),appendEnvVars:async(e,t)=>{let n=s.join(e,`.env`),r=await E.pathExists(n)?await E.readFile(n,`utf8`):``,i=Object.entries(t).map(([e,t])=>`${e}=${t}`).join(`
|
|
2
|
+
import{a as e,i as t,n,o as r,s as i,t as a}from"./consts-BZnOMxpW.js";import{readFileSync as o,realpathSync as s}from"node:fs";import c from"node:path";import{fileURLToPath as l}from"node:url";import{optional as u,text as d,withDescription as f}from"@effect/cli/Args";import{make as p,run as m,withDescription as h,withSubcommands as g}from"@effect/cli/Command";import{boolean as _,choice as v,optional as ee,text as te,withAlias as ne,withDescription as y}from"@effect/cli/Options";import{isValidationError as re}from"@effect/cli/ValidationError";import{layer as ie}from"@effect/platform-node/NodeContext";import{Cause as b,Context as x,Effect as S,Exit as ae,Layer as C}from"effect";import{getOrUndefined as w}from"effect/Option";import{Chalk as oe}from"chalk";import se from"sort-package-json";import{applyEdits as ce,modify as le,parse as ue}from"jsonc-parser";import{randomUUID as de}from"node:crypto";import{execa as T}from"execa";import E from"fs-extra";import fe from"open";import pe from"node:https";import D from"axios";import{intro as me,isCancel as he,log as ge,note as _e,spinner as ve}from"@clack/prompts";import{checkbox as ye,confirm as be,input as xe,password as Se,search as Ce,select as we}from"@inquirer/prompts";import Te from"gradient-string";const O=x.GenericTag(`@proofkit/cli/CliContext`),k=x.GenericTag(`@proofkit/cli/PromptService`),A=x.GenericTag(`@proofkit/cli/ConsoleService`),j=x.GenericTag(`@proofkit/cli/FileSystemService`),Ee=x.GenericTag(`@proofkit/cli/TemplateService`),M=x.GenericTag(`@proofkit/cli/PackageManagerService`),De=x.GenericTag(`@proofkit/cli/ProcessService`),Oe=x.GenericTag(`@proofkit/cli/GitService`),ke=x.GenericTag(`@proofkit/cli/SettingsService`),N=x.GenericTag(`@proofkit/cli/FileMakerService`),Ae=x.GenericTag(`@proofkit/cli/CodegenService`);var P=class extends Error{constructor(e=`User aborted the operation`){super(e),this.name=`UserAbortedError`}};const je=[`API_`,`API `,`dapi_`,`dapi`],Me=/[^/]$/,Ne=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.json`,`.jsonc`,`.md`,`.css`,`.scss`,`.html`,`.mjs`,`.cjs`]);function Pe(e){let t=e.replace(/[-\s]/g,`_`);for(let e of je)t.startsWith(e)&&(t=t.replace(e,``));return t}function Fe(e){if(e===`filemaker`)return{database:`FM_DATABASE`,server:`FM_SERVER`,apiKey:`OTTO_API_KEY`};let t=e.toUpperCase();return{database:`${t}_FM_DATABASE`,server:`${t}_FM_SERVER`,apiKey:`${t}_OTTO_API_KEY`}}function F(e,t){return[`npm`,`bun`].includes(e)?`${e} run ${t}`:`${e} ${t}`}function Ie(e){return e===`npm`?`npm run`:e}function Le(e){return e.replace(/\*/g,``).replace(Me,`$&/`)}async function I(e,t,n,r){let i=await e.readdir(t);for(let a of i){let i=c.join(t,a);if(await e.readdir(i).catch(e=>{if((typeof e==`object`&&e&&`code`in e&&typeof e.code==`string`?e.code:void 0)!==`ENOTDIR`)throw e})){await I(e,i,n,r);continue}let o=c.extname(a);if(!Ne.has(o))continue;let s=await e.readFile(i).catch(()=>void 0);s?.includes(n)&&await e.writeFile(i,s.replaceAll(n,r))}}async function Re(e,t,n){let r=c.join(t,`src/lib/env.ts`);if(!await e.exists(r))return;let i=await e.readFile(r),a=i.indexOf(` server: {`);if(a===-1)return;let o=i.indexOf(` },`,a);if(o===-1)return;let s=n.filter(e=>!i.includes(`${e.name}:`)).map(e=>` ${e.name}: ${e.zodSchema},`).join(`
|
|
3
|
+
`);s&&(i=`${i.slice(0,o)}${s}\n${i.slice(o)}`,await e.writeFile(r,i))}async function ze(e,t,n){let r=c.join(t,`proofkit-typegen.config.jsonc`),i=`./src/config/schemas/${n.dataSourceName}`,a={type:`fmdapi`,layouts:[],path:i,clearOldFiles:!0,clientSuffix:`Layout`};n.envNames&&(a.envNames={server:n.envNames.server,db:n.envNames.database,auth:{apiKey:n.envNames.apiKey}}),n.appType===`webviewer`&&(a.webviewerScriptName=`ExecuteDataApi`),n.fmMcpBaseUrl&&(a.fmMcp={enabled:!0,baseUrl:n.fmMcpBaseUrl,...n.connectedFileName?{connectedFileName:n.connectedFileName}:{}});let o=n.layoutName&&n.schemaName?{layoutName:n.layoutName,schemaName:n.schemaName,valueLists:`allowEmpty`}:void 0;if(o&&(a.layouts=[o]),!await e.exists(r)){let t={$schema:`https://proofkit.dev/typegen-config-schema.json`,config:[a]};await e.writeFile(r,`${JSON.stringify(t,null,2)}\n`);return}let s=await e.readFile(r),l=ue(s),u=Array.isArray(l.config)?l.config:[l.config],d=u.findIndex(e=>e.path===i);if(d===-1)u.push(a);else{let e=u[d]??{},t=Array.isArray(e.layouts)?e.layouts:[],n=t;o&&!t.some(e=>e?.layoutName===o.layoutName)&&(n=[...t,o]),u[d]={...e,...a,layouts:n}}let f=le(s,[`config`],Array.isArray(l.config)?u:u[0]??a,{formattingOptions:{insertSpaces:!0,tabSize:2,eol:`
|
|
4
|
+
`}});await e.writeFile(r,ce(s,f))}function Be(){let e=[c.resolve(t,`package.json`),c.resolve(t,`../cli/package.json`)];for(let t of e)try{let e=JSON.parse(o(t,`utf8`));if(e.version&&e.version!==`0.0.0-private`)return e.version}catch{}return`0.0.0-private`}function Ve(){return`beta`}function He(){return process.versions.node.split(`.`)[0]??`22`}function Ue(e){return{ui:e.ui,appType:e.appType,envFile:`.env`,dataSources:[],replacedMainPage:!1,registryTemplates:[]}}function We(){return[`# When adding additional environment variables, update the schema alongside this file.`,``].join(`
|
|
5
|
+
`)}const Ge={"@radix-ui/react-slot":`^1.2.3`,"class-variance-authority":`^0.7.1`,clsx:`^2.1.1`,"lucide-react":`^0.577.0`,"tailwind-merge":`^3.5.0`,tailwindcss:`^4.1.10`,"tw-animate-css":`^1.4.0`};function Ke(e,t){let n=c.resolve(e.cwd,e.appDir),r=Ve(),i=Ue(e),a=Ie(e.packageManager),o={name:e.scopedAppName,packageManager:t.packageManagerVersion?`${e.packageManager}@${t.packageManagerVersion}`:void 0,proofkitMetadata:{initVersion:Be(),scaffoldPackage:`@proofkit/cli`},dependencies:{},devDependencies:{"@proofkit/cli":r,"@types/node":`^${He()}`}};return e.appType===`browser`&&(Object.assign(o.dependencies,Ge),o.dependencies[`@tailwindcss/postcss`]=`^4.1.10`,o.dependencies[`next-themes`]=`^0.4.6`),e.appType===`webviewer`&&(Object.assign(o.dependencies,Ge),o.dependencies[`@proofkit/fmdapi`]=r,o.dependencies[`@proofkit/webviewer`]=r,o.dependencies[`@tanstack/react-query`]=`^5.90.21`,o.dependencies[`@tanstack/react-router`]=`^1.167.4`,o.dependencies.zod=`^4`,o.devDependencies[`@proofkit/typegen`]=r,o.devDependencies[`@tailwindcss/vite`]=`^4.2.1`,o.devDependencies.ultracite=`7.0.8`),{request:e,targetDir:n,templateDir:t.templateDir,packageManagerCommand:a,packageJson:o,settings:i,envFile:{path:c.join(n,`.env`),content:We()},writes:[],commands:[...e.noInstall?[]:[{type:`install`}],...e.dataSource===`filemaker`&&!e.skipFileMakerSetup&&!(e.appType===`webviewer`&&e.nonInteractive&&!e.hasExplicitFileMakerInputs)?[{type:`codegen`}]:[],...e.noGit?[]:[{type:`git-init`}]],tasks:{bootstrapFileMaker:e.dataSource===`filemaker`&&!e.skipFileMakerSetup,checkWebViewerAddon:e.appType===`webviewer`,runInstall:!e.noInstall,runInitialCodegen:e.dataSource===`filemaker`&&!e.skipFileMakerSetup&&!(e.appType===`webviewer`&&e.nonInteractive&&!e.hasExplicitFileMakerInputs),initializeGit:!e.noGit},nextSteps:[`cd ${e.appDir}`,...e.noInstall?[e.packageManager===`yarn`?`yarn`:`${e.packageManager} install`]:[],`npx @tanstack/intent@latest install`,F(e.packageManager,`dev`),...e.appType===`webviewer`?[F(e.packageManager,`typegen`),F(e.packageManager,`launch-fm`)]:[],F(e.packageManager,`proofkit`)]}}function qe(e,t,n=!0){e.name=t.name,e.proofkitMetadata=t.proofkitMetadata,t.packageManager&&(e.packageManager=t.packageManager),e.dependencies||={},e.devDependencies||={};let r=(e,t)=>{for(let[r,i]of Object.entries(t))(n||!(r in e))&&(e[r]=i)};return r(e.dependencies,t.dependencies),r(e.devDependencies,t.devDependencies),e}const Je=new Set([`.agents`,`.claude`,`.clawed`,`.clinerules`,`.cursor`,`.windsurf`]),Ye=/\*/g,Xe=/\/?$/,L=new oe({level:1}),R=e=>L.cyan(e),z=e=>L.bold(e),Ze=e=>L.yellow(e);function Qe(e,t=[]){let n=[`${z(`Project root:`)} ${R(`cd ${Ze(e.request.appDir)}`)}`,``,z(`Agent setup:`),`Have your agent run this in the new project and complete the interactive prompt so it can load the right skills:`,` ${R(`npx @tanstack/intent@latest install`)}`];return e.request.noInstall&&n.push(``,z(`Install dependencies:`),` ${R(e.request.packageManager===`yarn`?`yarn`:`${e.request.packageManager} install`)}`),n.push(``,z(`Start the app:`),` ${R(`${e.packageManagerCommand} dev`)}`),e.request.appType===`webviewer`&&(n.push(``,z(`When your FileMaker file is ready:`),` ${R(`${e.packageManagerCommand} typegen`)}`,` ${R(`${e.packageManagerCommand} launch-fm`)}`),t.length>0&&n.push(...t.map(e=>` ${R(e)}`))),n.push(``,z(`More ProofKit commands:`),` ${R(`${e.packageManagerCommand} proofkit`)}`),n.join(`
|
|
6
|
+
`)}function $e(e){return e.filter(e=>Je.has(e)?!1:e===`.gitignore`?!0:!e.startsWith(`.`))}const et=e=>S.gen(function*(){let t=yield*j,n=yield*A,r=yield*O,i=yield*k;if(!(yield*S.promise(()=>t.exists(e.targetDir)))||$e(yield*S.promise(()=>t.readdir(e.targetDir))).length===0)return;if(e.request.force){yield*S.promise(()=>t.emptyDir(e.targetDir));return}if(r.nonInteractive)throw Error(`${e.request.appDir} already exists and isn't empty. Remove the existing files or choose a different directory.`);let a=yield*S.promise(()=>i.select({message:`${e.request.appDir} already exists and isn't empty. How would you like to proceed?`,options:[{value:`abort`,label:`Abort installation`},{value:`clear`,label:`Clear the directory and continue`},{value:`overwrite`,label:`Continue and overwrite conflicting files`}]}));if(a===`abort`)throw new P;if(a===`clear`){if(!(yield*S.promise(()=>i.confirm({message:`Are you sure you want to clear the directory?`,initialValue:!1}))))throw new P;yield*S.promise(()=>t.emptyDir(e.targetDir));return}n.warn(`Continuing in ${e.request.appDir} and overwriting conflicting files when needed.`)}),tt=e=>S.gen(function*(){let t=yield*O,n=yield*j,r=yield*A,i=yield*ke,o=yield*N,s=yield*De,l=yield*Oe,u=yield*Ae,d=yield*M,f=[];yield*et(e),r.info(`Scaffolding in ${e.targetDir}`),yield*S.promise(()=>n.copyDir(e.templateDir,e.targetDir,{overwrite:!0}));let p=c.join(e.targetDir,`_gitignore`),m=c.join(e.targetDir,`.gitignore`);(yield*S.promise(()=>n.exists(p)))&&((yield*S.promise(()=>n.exists(m)))?yield*S.promise(()=>n.remove(p)):yield*S.promise(()=>n.rename(p,m)));let h=c.join(e.targetDir,`package.json`),g=se(qe(yield*S.promise(()=>n.readJson(h)),e.packageJson));yield*S.promise(()=>n.writeJson(h,g)),yield*S.promise(()=>i.writeSettings(e.targetDir,e.settings)),yield*S.promise(()=>n.writeFile(e.envFile.path,e.envFile.content));for(let t of e.writes)yield*S.promise(()=>n.writeFile(t.path,t.content));yield*S.promise(()=>I(n,e.targetDir,`__PNPM_COMMAND__`,e.packageManagerCommand)),yield*S.promise(()=>I(n,e.targetDir,`__PACKAGE_MANAGER__`,e.request.packageManager)),yield*S.promise(()=>I(n,e.targetDir,`__AGENT_INSTRUCTIONS__`,a)),e.request.importAlias!==`~/`&&(yield*S.promise(()=>I(n,e.targetDir,`~/`,Le(e.request.importAlias))),yield*S.promise(()=>I(n,e.targetDir,`@/`,e.request.importAlias.replace(Ye,``).replace(Xe,`/`))));let _=e.settings;if(e.tasks.bootstrapFileMaker&&e.request.fileMaker){let t=e.request.fileMaker;_=yield*S.promise(()=>o.bootstrap(e.targetDir,_,t,e.request.appType)),yield*S.promise(()=>i.writeSettings(e.targetDir,_))}if(e.tasks.checkWebViewerAddon&&(yield*S.promise(async()=>{try{let{checkForWebViewerLayouts:n,getWebViewerAddonMessages:i}=await import(`./proofkit-webviewer-73IB1OBU.js`),a=i(await n(e.targetDir));for(let e of a.warn)r.warn(e);for(let e of a.info)r.info(e);t.nonInteractive&&f.push(...a.nextSteps)}catch(e){let t=e instanceof Error?e.message:String(e);r.warn(`Could not inspect the ProofKit WebViewer add-on (${t}).`)}})),e.tasks.runInstall){let t=[`install`];e.request.packageManager===`yarn`&&(t=[]),yield*S.promise(()=>s.run(e.request.packageManager,t,{cwd:e.targetDir,stdout:`pipe`,stderr:`pipe`}))}e.tasks.runInitialCodegen&&(yield*S.promise(()=>u.runInitial(e.targetDir,e.request.packageManager))),e.tasks.initializeGit&&(yield*S.promise(()=>l.initialize(e.targetDir)));let v=yield*S.promise(()=>d.getVersion(e.request.packageManager,e.targetDir));return r.success(`Created ${e.request.scopedAppName} in ${e.targetDir}${v?` using ${e.request.packageManager}@${v}`:``}`),r.info(L.bold(`Next steps:`)),r.info(Qe(e,Array.from(new Set(f)))),e}),nt=/\/+$/,rt=/\\/g,it=/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function at(e){return e.replace(rt,`/`)}function ot(e){return at(e).replace(nt,``)}function st(e){let t=ot(e).split(`/`),n=t.at(-1)??``;n===`.`&&(n=c.basename(c.resolve(process.cwd())));let r=t.findIndex(e=>e.startsWith(`@`));r!==-1&&(n=t.slice(r).join(`/`));let i=t.filter(e=>!e.startsWith(`@`)).join(`/`);return[n,i]}function ct(e){let t=ot(e);if(t===`.`){let e=c.basename(c.resolve(process.cwd()));return it.test(e)?void 0:`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}let n=t.split(`/`),r=n.findIndex(e=>e.startsWith(`@`)),i=n.at(-1);if(r!==-1&&(i=n.slice(r).join(`/`)),!it.test(i??``))return`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}const lt={noGit:!1,noInstall:!1,force:!1,default:!1,CI:!1,importAlias:`~/`};function ut(e,t){let n=e.split(`.`).map(e=>Number.parseInt(e,10)||0),r=t.split(`.`).map(e=>Number.parseInt(e,10)||0);for(let e=0;e<Math.max(n.length,r.length);e+=1){let t=n[e]??0,i=r[e]??0;if(t>i)return 1;if(t<i)return-1}return 0}function dt(e){if(!!e.layoutName!=!!e.schemaName)throw Error(`Both --layout-name and --schema-name must be provided together.`)}async function ft({prompt:e,fileMakerService:t,flags:n,nonInteractive:r}){if(dt(n),!n.server&&r)throw Error(`Missing required hosted FileMaker inputs in non-interactive mode: --server, --file-name, and --data-api-key.`);let i=n.server??await e.text({message:`What is the URL of your FileMaker Server?`,validate:e=>{try{let t=e.startsWith(`http`)?e:`https://${e}`;new URL(t);return}catch{return`Please enter a valid URL`}}}),{normalizedUrl:a,versions:o}=await t.validateHostedServerUrl(i),s=new URL(a),c=n.fileName,l=n.dataApiKey,u=n.layoutName,d=n.schemaName,f,p=[],m=()=>{if(!f)throw Error(`OttoFMS authentication is required for hosted setup.`);return f};if(!(c&&l)){if(!(n.adminApiKey||o.ottoVersion&&ut(o.ottoVersion,`4.7.0`)>=0))throw Error(`OttoFMS 4.7.0 or later is required to auto-login. Upgrade OttoFMS or pass --admin-api-key for hosted setup.`);f=n.adminApiKey??(await t.getOttoFMSToken({url:s})).token}if(!c){if(r)throw Error(`Missing required FileMaker inputs in non-interactive mode: --file-name, --data-api-key.`);p=await t.listFiles({url:s,token:m()}),c=await e.searchSelect({message:`Which file would you like to connect to?`,options:[{value:`$deploy-demo`,label:`Deploy NEW ProofKit Demo File`,hint:`Use OttoFMS to deploy a new file for testing`,keywords:[`demo`,`proofkit`]},...p.slice().sort((e,t)=>e.filename.localeCompare(t.filename)).map(e=>({value:e.filename,label:e.filename,hint:e.status,keywords:[e.filename]}))]})}if(!c)throw Error(`No FileMaker file was selected.`);if(c===`$deploy-demo`){p.length===0&&(p=await t.listFiles({url:s,token:m()}));let n=p.some(e=>e.filename===`ProofKitDemo.fmp12`),i=n&&!r?await e.confirm({message:`The demo file already exists. Do you want to replace it with a fresh copy?`,initialValue:!1}):n,a=await t.deployDemoFile({url:s,token:m(),operation:i?`replace`:`install`});c=a.filename,l=a.apiKey,u??=`API_Contacts`,d??=`Contacts`}if(!l&&r)throw Error(`Missing required FileMaker inputs in non-interactive mode: --data-api-key.`);if(!l){let n=(await t.listAPIKeys({url:s,token:m()})).filter(e=>e.database===c),r=n.length===0?`create`:await e.searchSelect({message:`Which OttoFMS Data API key would you like to use?`,options:[...n.map(e=>({value:e.key,label:`${e.label} - ${e.user}`,hint:`${e.key.slice(0,5)}...${e.key.slice(-4)}`,keywords:[e.label,e.user,e.database]})),{value:`create`,label:`Create a new API key`,hint:`Requires FileMaker credentials for this file`,keywords:[`create`,`new`]}]});if(r===`create`){let n=await e.text({message:`Enter the account name for ${c}`,validate:e=>e?void 0:`An account name is required`}),r=await e.password({message:`Enter the password for ${n}`,validate:e=>e?void 0:`A password is required`});l=(await t.createDataAPIKeyWithCredentials({url:s,filename:c,username:n,password:r})).apiKey}else l=r}if(!l)throw Error(`No FileMaker Data API key was selected.`);let h=await t.listLayouts({dataApiKey:l,fmFile:c,server:s.origin});if(u&&!h.includes(u))throw Error(`Layout "${u}" was not found in ${c}.`);return r||u||d||await e.confirm({message:`Do you want to configure an initial layout for type generation now?`,initialValue:!1})&&(u=await e.searchSelect({message:`Select a layout to read data from`,options:h.map(e=>({value:e,label:e,keywords:[e]}))}),d=await e.text({message:`What should the generated schema be called?`,defaultValue:Pe(u),validate:e=>e?void 0:`A schema name is required`})),{mode:`hosted-otto`,dataSourceName:`filemaker`,envNames:Fe(`filemaker`),server:s.origin,fileName:c,dataApiKey:l,layoutName:u,schemaName:d,adminApiKey:n.adminApiKey,fmsVersion:o.fmsVersion,ottoVersion:o.ottoVersion}}async function pt({prompt:e,fileMakerService:t,flags:n,appType:r,nonInteractive:i}){if(n.dataSource!==`filemaker`)return{fileMaker:void 0,skipFileMakerSetup:!1};if(dt(n),r===`webviewer`&&!n.server)for(;;){let r=await t.detectLocalFmMcp();if(r.healthy&&r.connectedFiles[0])return{fileMaker:{mode:`local-fm-mcp`,dataSourceName:`filemaker`,envNames:Fe(`filemaker`),fmMcpBaseUrl:r.baseUrl,fileName:r.connectedFiles[0],layoutName:n.layoutName,schemaName:n.schemaName},skipFileMakerSetup:!1};if(i)throw r.healthy?Error(`ProofKit MCP Server was detected, but no FileMaker files are open. Open a file in FileMaker and rerun, or pass --server.`):Error(`ProofKit MCP Server was not detected and no FileMaker server was provided. Start the ProofKit MCP Server locally or rerun with --server.`);let a=await e.select({message:r.healthy?`I noticed you have the ProofKit MCP Server installed, but no files are open. How would you like to continue?`:`ProofKit MCP Server was not detected. How would you like to continue?`,options:[{value:`retry`,label:`Try again`,hint:r.healthy?`Open a FileMaker file, then retry detection`:`Retry ProofKit MCP Server detection`},{value:`hosted`,label:`Continue with hosted setup`,hint:`Use OttoFMS and a hosted FileMaker server`},{value:`skip`,label:`Skip for now`,hint:`Create the project and configure FileMaker later`}]});if(a!==`retry`){if(a===`skip`)return{fileMaker:void 0,skipFileMakerSetup:!0};break}}return{fileMaker:await ft({prompt:e,fileMakerService:t,flags:n,nonInteractive:i}),skipFileMakerSetup:!1}}const mt=(e,t)=>S.gen(function*(){let r={...lt,...t},i=yield*k,a=yield*N,o=yield*O,s=o.nonInteractive||r.CI||r.nonInteractive===!0,c=e;if(!c){if(s)return yield*S.fail(Error(`Project name is required in non-interactive mode.`));c=yield*S.promise(()=>i.text({message:`What will your project be called?`,defaultValue:n,validate:ct}))}if(!c)return yield*S.fail(Error(`Project name is required.`));let l=ct(c);if(l)return yield*S.fail(Error(l));let u=r.appType??`browser`;r.appType||s||(u=yield*S.promise(()=>i.select({message:`What kind of app do you want to build?`,options:[{value:`browser`,label:`Web App for Browsers`,hint:`Uses Next.js and hosted deployment`},{value:`webviewer`,label:`FileMaker Web Viewer`,hint:`Uses Vite for FileMaker web viewers`}]})).pipe(S.map(e=>e)));let d=!!(r.server||r.adminApiKey||r.dataApiKey||r.fileName||r.layoutName||r.schemaName),f=`none`;if(r.dataSource?f=r.dataSource:u===`webviewer`&&(f=d||!(s&&!r.server)?`filemaker`:`none`),!(s||r.dataSource)&&u!==`webviewer`&&(f=yield*S.promise(()=>i.select({message:`Do you want to connect to a FileMaker Database now?`,options:[{value:`filemaker`,label:`Yes`,hint:`Set up env, datasource config, and typegen now`},{value:`none`,label:`No`,hint:`You can add a data source later`}]})).pipe(S.map(e=>e))),s&&!r.dataSource&&d||s&&f!==`filemaker`&&d)return yield*S.fail(Error(`FileMaker flags require --data-source filemaker in non-interactive mode.`));let{fileMaker:p,skipFileMakerSetup:m}=yield*S.promise(()=>pt({prompt:i,fileMakerService:a,flags:{...r,dataSource:f},appType:u,nonInteractive:s})),[h,g]=st(c);return{projectName:c,scopedAppName:h,appDir:g,appType:u,ui:r.ui??`shadcn`,dataSource:f,packageManager:o.packageManager,noInstall:r.noInstall,noGit:r.noGit,force:r.force,cwd:o.cwd,importAlias:r.importAlias,nonInteractive:s,debug:o.debug,fileMaker:p,skipFileMakerSetup:m,hasExplicitFileMakerInputs:d}});async function ht(e){try{await fe(e)}catch{}}function B(){return new pe.Agent({rejectUnauthorized:process.env.PROOFKIT_ALLOW_INSECURE_TLS!==`1`})}async function V(e,t){return await D.get(e,{headers:t?.headers,httpsAgent:B(),timeout:t?.timeout??1e4,validateStatus:null})}async function gt(e,t,n){return await D.post(e,t,{headers:n?.headers,httpsAgent:B(),timeout:n?.timeout??1e4,validateStatus:null})}async function _t(e,t){return await D.delete(e,{headers:t?.headers,httpsAgent:B(),timeout:t?.timeout??1e4,validateStatus:null})}function vt(){let e=process.env.npm_config_user_agent;return e?e.startsWith(`yarn`)?`yarn`:e.startsWith(`pnpm`)?`pnpm`:e.startsWith(`bun`)?`bun`:`npm`:`npm`}const yt=Symbol.for(`@proofkit/new/prompt-cancelled`),bt=me,H=ge,xt=_e,St=ve;function Ct(e){return e instanceof Error&&e.name===`ExitPromptError`}function U(e){return e().catch(e=>{if(Ct(e))return yt;throw e})}function wt(e){return e===yt||he(e)}function Tt(e){if(e)return t=>e(t)??!0}function Et(e,t){return[e.label,e.hint??``,...e.keywords??[]].join(` `).toLowerCase().includes(t.trim().toLowerCase())}function W(e){return typeof e==`string`?e:e?!0:void 0}function Dt(e,t){let n=t?.trim();return n?e.filter(e=>Et(e,n)):e}function Ot(e){return U(()=>xe({message:e.message,default:e.defaultValue,validate:Tt(e.validate)}))}function kt(e){return U(()=>Se({message:e.message,validate:Tt(e.validate)}))}function At(e){return U(()=>be({message:e.message,default:e.initialValue}))}function jt(e){return U(()=>we({message:e.message,pageSize:10,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}))}function Mt(e){return U(()=>Ce({message:e.message,pageSize:10,source:t=>{let n=Dt(e.options,t);return n.length===0?[{value:`__no_matches__`,name:e.emptyMessage??`No matches found. Keep typing to refine your search.`,disabled:e.emptyMessage??`No matches found`}]:n.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}}))}function Nt(e){return U(()=>ye({message:e.message,pageSize:10,required:e.required,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}))}function G(e){if(wt(e))throw new P;return e}function Pt(e){return e.startsWith(`https://`)?e:e.startsWith(`http://`)?e.replace(`http://`,`https://`):`https://${e}`}function Ft(e){let t=e=>e.isFolder===!0?(Array.isArray(e.folderLayoutNames)?e.folderLayoutNames:[]).flatMap(e=>t(e)):typeof e.name==`string`?[e.name]:[];return e.flatMap(t).sort((e,t)=>e.localeCompare(t))}const It={text:async e=>G(await Ot({message:e.message,defaultValue:e.defaultValue,validate:e.validate})).toString(),password:async e=>G(await kt({message:e.message,validate:e.validate})).toString(),select:async e=>G(await jt({message:e.message,options:e.options})),searchSelect:async e=>G(await Mt(e)),multiSearchSelect:async e=>G(await Nt(e)),confirm:async e=>G(await At({message:e.message,initialValue:e.initialValue}))},Lt={info:e=>H.info(e),warn:e=>H.warn(e),error:e=>H.error(e),success:e=>H.success(e),note:(e,t)=>xt(e,t)},K={exists:async e=>E.pathExists(e),readdir:async e=>E.readdir(e),emptyDir:async e=>E.emptyDir(e),copyDir:async(e,t,n)=>E.copy(e,t,{overwrite:n?.overwrite??!0}),rename:async(e,t)=>E.rename(e,t),remove:async e=>E.remove(e),readJson:async e=>E.readJson(e),writeJson:async(e,t)=>E.writeJson(e,t,{spaces:2}),writeFile:async(e,t)=>E.writeFile(e,t,`utf8`),readFile:async e=>E.readFile(e,`utf8`)},Rt={getTemplateDir:(t,n)=>t===`webviewer`?c.join(e,`vite-wv`):n===`mantine`?c.join(e,`nextjs-mantine`):c.join(e,`nextjs-shadcn`)},zt={getVersion:async(e,t)=>{if(e===`bun`)return;let{stdout:n}=await T(e,[`-v`],{cwd:t});return n.trim()}},Bt={run:async(e,t,n)=>{let r=await T(e,t,{cwd:n.cwd,stdout:n.stdout??`pipe`,stderr:n.stderr??`pipe`});return{stdout:r.stdout??``,stderr:r.stderr??``}}},Vt={initialize:async e=>{await T(`git`,[`init`],{cwd:e}),await T(`git`,[`add`,`.`],{cwd:e}),await T(`git`,[`commit`,`-m`,`Initial commit`],{cwd:e})}},Ht={writeSettings:async(e,t)=>E.writeJson(c.join(e,`proofkit.json`),t,{spaces:2}),appendEnvVars:async(e,t)=>{let n=c.join(e,`.env`),r=await E.pathExists(n)?await E.readFile(n,`utf8`):``,i=Object.entries(t).map(([e,t])=>`${e}=${t}`).join(`
|
|
7
7
|
`),a=[r.trimEnd(),i].filter(Boolean).join(`
|
|
8
8
|
`).concat(`
|
|
9
|
-
`);await E.writeFile(n,a,`utf8`)},ensureTypegenConfig:async(e,t)=>void 0};function
|
|
10
|
-
`),`Project commands`);return}
|
|
9
|
+
`);await E.writeFile(n,a,`utf8`)},ensureTypegenConfig:async(e,t)=>void 0};function Ut(e){return{type:`fm`,name:e,envNames:Fe(e)}}function Wt(e,t,n){let r=Ut(t.dataSourceName),i={...e,dataSources:e.dataSources.some(e=>e.name===r.name)?e.dataSources:[...e.dataSources,r]};return t.mode===`local-fm-mcp`?Promise.resolve({settings:i,envVars:{},envSchemaEntries:[],typegenConfig:{mode:t.mode,dataSourceName:t.dataSourceName,fmMcpBaseUrl:t.fmMcpBaseUrl,connectedFileName:t.fileName,layoutName:t.layoutName,schemaName:t.schemaName,appType:n}}):Promise.resolve({settings:i,envVars:{[t.envNames.database]:t.fileName,[t.envNames.server]:t.server,[t.envNames.apiKey]:t.dataApiKey},envSchemaEntries:[{name:t.envNames.database,zodSchema:`z.string().endsWith(".fmp12")`,defaultValue:t.fileName},{name:t.envNames.server,zodSchema:`z.string().url()`,defaultValue:t.server},{name:t.envNames.apiKey,zodSchema:`z.string().startsWith("dk_")`,defaultValue:t.dataApiKey}],typegenConfig:{mode:t.mode,dataSourceName:t.dataSourceName,envNames:t.envNames,layoutName:t.layoutName,schemaName:t.schemaName,appType:n}})}const q={detectLocalFmMcp:async(e=process.env.FM_MCP_BASE_URL??`http://127.0.0.1:1365`)=>{try{if(!(await fetch(`${e}/health`,{signal:AbortSignal.timeout(3e3)})).ok)return{baseUrl:e,healthy:!1,connectedFiles:[]};let t=await fetch(`${e}/connectedFiles`,{signal:AbortSignal.timeout(3e3)}).then(async e=>e.ok?await e.json():[]).catch(()=>[]);return{baseUrl:e,healthy:!0,connectedFiles:Array.isArray(t)?t.filter(e=>typeof e==`string`):[]}}catch{return{baseUrl:e,healthy:!1,connectedFiles:[]}}},validateHostedServerUrl:async(e,t)=>{let n=Pt(e),r=(await V(new URL(`/fmws/serverinfo`,n).toString())).data?.data?.ServerVersion?.split(` `)[0];if(!r)throw Error(`Invalid FileMaker Server URL: ${n}`);let i=null;if(i=(await V(new URL(`/otto/api/info`,n).toString()).catch(()=>void 0))?.data?.response?.Otto?.version??null,!i){let e=new URL(n);e.port=t?String(t):`3030`,e.pathname=`/api/otto/info`,i=(await V(e.toString()).catch(()=>void 0))?.data?.Otto?.version??null}return{normalizedUrl:new URL(n).origin,versions:{fmsVersion:r,ottoVersion:i}}},getOttoFMSToken:async({url:e})=>{let t=de().replaceAll(`-`,``).slice(0,18),n=new URL(`/otto/wizard/${t}`,e.origin);H.info(`If the browser window didn't open automatically, use this Otto login URL:\n${n.toString()}`),await ht(n.toString());let r=St();r.start(`Waiting for OttoFMS login`);let i=Date.now()+18e4;for(;Date.now()<i;){let n=(await V(`${e.origin}/otto/api/cli/checkHash/${t}`,{headers:{"Accept-Encoding":`deflate`},timeout:5e3}).catch(()=>void 0))?.data?.response?.token;if(n)return r.stop(`Login complete`),await _t(`${e.origin}/otto/api/cli/checkHash/${t}`,{headers:{"Accept-Encoding":`deflate`}}).catch(()=>void 0),{token:n};await new Promise(e=>setTimeout(e,500))}throw r.stop(`Login timed out`),Error(`OttoFMS login timed out after 3 minutes.`)},listFiles:async({url:e,token:t})=>((await V(`${e.origin}/otto/fmi/admin/api/v2/databases`,{headers:{Authorization:`Bearer ${t}`}})).data?.response?.databases??[]).filter(e=>typeof e.filename==`string`).map(e=>({filename:e.filename,status:e.status??`unknown`})),listAPIKeys:async({url:e,token:t})=>((await V(`${e.origin}/otto/api/api-key`,{headers:{Authorization:`Bearer ${t}`}})).data?.response?.[`api-keys`]??[]).filter(e=>typeof e.key==`string`&&typeof e.user==`string`&&typeof e.database==`string`&&typeof e.label==`string`).map(e=>({key:e.key,user:e.user,database:e.database,label:e.label})),createDataAPIKeyWithCredentials:async({url:e,filename:t,username:n,password:r})=>{let i=(await gt(`${e.origin}/otto/api/api-key/create-only`,{database:t,label:`For FM Web App`,user:n,pass:r})).data?.response?.key;if(!i)throw Error(`Failed to create a Data API key for ${t}.`);return{apiKey:i}},startDeployment:async({payload:e,url:t,token:n})=>gt(`${t.origin}/otto/api/deployment`,e,{headers:{Authorization:`Bearer ${n}`}}),getDeploymentStatus:async({url:e,token:t,deploymentId:n})=>V(`${e.origin}/otto/api/deployment/${n}`,{headers:{Authorization:`Bearer ${t}`}}),deployDemoFile:async({url:e,token:t,operation:n})=>{let r=`ProofKitDemo.fmp12`,i=St();i.start(`Deploying ProofKit Demo file`);let a={scheduled:!1,label:`Install ProofKit Demo`,deployments:[{name:`Install ProofKit Demo`,source:{type:`url`,url:`https://proofkit.dev/proofkit-demo/manifest.json`},fileOperations:[{target:{fileName:r},operation:n,source:{fileName:r},location:{folder:`default`,subFolder:``}}],concurrency:1,options:{closeFilesAfterBuild:!1,keepFilesClosedAfterComplete:!1,transferContainerData:!1}}],abortRemaining:!1},o=(await q.startDeployment({payload:a,url:e,token:t})).data?.response?.subDeploymentIds?.[0];if(!o)throw i.stop(`Demo deployment failed`),Error(`No deployment ID was returned when deploying the demo file.`);let s=Date.now()+3e5,c=!1;for(;Date.now()<s;){await new Promise(e=>setTimeout(e,2500));let n=await q.getDeploymentStatus({url:e,token:t,deploymentId:o});if(!n.data?.response?.running){if(n.data?.response?.status!==`complete`)throw i.stop(`Demo deployment failed`),Error(`ProofKit Demo deployment did not complete successfully.`);c=!0;break}}if(!c)throw i.stop(`Demo deployment timed out`),Error(`ProofKit Demo deployment timed out after 5 minutes.`);let l=await q.createDataAPIKeyWithCredentials({url:e,filename:r,username:`admin`,password:`admin`});return i.stop(`Demo file deployed`),{apiKey:l.apiKey,filename:r}},listLayouts:async({dataApiKey:e,fmFile:t,server:n})=>Ft((await V(`${n}/otto/fmi/data/vLatest/databases/${encodeURIComponent(t)}/layouts`,{headers:{Authorization:`Bearer ${e}`}})).data?.response?.layouts??[]),createFileMakerBootstrapArtifacts:Wt,bootstrap:async(e,t,n,r)=>{let i=await Wt(t,n,r);return Object.keys(i.envVars).length>0&&(await Ht.appendEnvVars(e,i.envVars),await Re(K,e,i.envSchemaEntries)),await ze(K,e,{appType:i.typegenConfig.appType,dataSourceName:i.typegenConfig.dataSourceName,envNames:i.typegenConfig.envNames,fmMcpBaseUrl:i.typegenConfig.fmMcpBaseUrl,connectedFileName:i.typegenConfig.connectedFileName,layoutName:i.typegenConfig.layoutName,schemaName:i.typegenConfig.schemaName}),i.settings}},Gt={runInitial:async(e,t)=>{let n;n=t===`npm`?[`npm`,`run`,`typegen`]:t===`bun`?[`bun`,`run`,`typegen`]:[t,`typegen`];let r=n[0];if(!r)throw Error(`Unable to resolve the codegen command`);await T(r,n.slice(1),{cwd:e})}};function J(e){let t={cwd:e.cwd,debug:e.debug,nonInteractive:e.nonInteractive,packageManager:vt()},n=C.mergeAll(C.succeed(O,t),C.succeed(k,It),C.succeed(A,Lt),C.succeed(j,K),C.succeed(Ee,Rt),C.succeed(M,zt),C.succeed(De,Bt),C.succeed(Oe,Vt),C.succeed(ke,Ht),C.succeed(N,q),C.succeed(Ae,Gt));return e=>S.provide(e,n)}const Y=Te(Object.values({purple:`#89216B`,lightPurple:`#D15ABB`,orange:`#FF595E`}));function Kt(e=`0.0.0-private`){let t=vt();(t===`yarn`||t===`pnpm`)&&console.log(``),console.log(Y.multiline(i(e)))}const X={noGit:!1,noInstall:!1,force:!1,default:!1,CI:!1,importAlias:`~/`};function qt(){try{let e=new URL(`../package.json`,import.meta.url);return JSON.parse(o(l(e),`utf8`)).version??`0.0.0-private`}catch{return`0.0.0-private`}}const Z=(e,t)=>S.gen(function*(){let n=yield*Ee,r=yield*M,i=yield*mt(e,{...X,...t}),a=Ke(i,{templateDir:n.getTemplateDir(i.appType,i.ui),packageManagerVersion:yield*S.promise(()=>r.getVersion(i.packageManager,i.cwd))});return yield*tt(a),{request:i,plan:a}}),Jt=e=>S.gen(function*(){let t=yield*O,n=yield*j,r=yield*A,i={...X,...e};if(t.nonInteractive||i.CI||i.nonInteractive)throw Error("The default command is interactive-only in non-interactive mode. Run an explicit command such as `proofkit init <name> --non-interactive`.");let a=c.join(t.cwd,`proofkit.json`);if(yield*S.promise(()=>n.exists(a))){bt(`Found ${Y(`ProofKit`)} project`),r.note([`Project command routing is being migrated into the Effect CLI surface.`,"Use an explicit command such as `proofkit add`, `proofkit remove`, `proofkit typegen`, `proofkit deploy`, or `proofkit upgrade`."].join(`
|
|
10
|
+
`),`Project commands`);return}bt(`No ${Y(`ProofKit`)} project found, running \`init\``),yield*Z(void 0,{...i,default:!0})}),Yt=u(d({name:`dir`})).pipe(f(`The project name or target directory`));function Q(e,t){return ee(te(e).pipe(y(t)))}function Xt(e,t,n){return ee(v(e,t).pipe(y(n)))}function $(e,t){return J({cwd:process.cwd(),debug:t?.debug===!0,nonInteractive:t?.nonInteractive===!0})(S.promise(e))}function Zt(){return p(`init`,{dir:Yt,appType:Xt(`app-type`,[`browser`,`webviewer`],`The type of app to create`),ui:Xt(`ui`,[`shadcn`,`mantine`],`The UI scaffold to create`),server:Q(`server`,`The URL of your FileMaker Server`),adminApiKey:Q(`admin-api-key`,`Admin API key for OttoFMS`),fileName:Q(`file-name`,`The name of the FileMaker file`),layoutName:Q(`layout-name`,`The FileMaker layout name to scaffold`),schemaName:Q(`schema-name`,`The generated schema name`),dataApiKey:Q(`data-api-key`,`The Otto Data API key to use`),dataSource:Xt(`data-source`,[`filemaker`,`none`],`The data source to use`),noGit:_(`no-git`).pipe(y(`Skip git initialization`)),noInstall:_(`no-install`).pipe(y(`Skip package installation`)),force:_(`force`).pipe(ne(`f`),y(`Force overwrite target directory when it already contains files`)),CI:_(`ci`).pipe(y(`Deprecated alias for --non-interactive`)),nonInteractive:_(`non-interactive`).pipe(y(`Never prompt for input; fail when required values are missing`)),debug:_(`debug`).pipe(y(`Run in debug mode`))},({dir:e,...t})=>{let n={...X,appType:w(t.appType),ui:w(t.ui),server:w(t.server),adminApiKey:w(t.adminApiKey),fileName:w(t.fileName),layoutName:w(t.layoutName),schemaName:w(t.schemaName),dataApiKey:w(t.dataApiKey),dataSource:w(t.dataSource),noGit:t.noGit,noInstall:t.noInstall,force:t.force,CI:t.CI,nonInteractive:t.nonInteractive,debug:t.debug};return J({cwd:process.cwd(),debug:n.debug===!0,nonInteractive:!!(n.CI||n.nonInteractive)})(Z(w(e),n))}).pipe(h(`Create a new project with ProofKit`))}function Qt(){return p(`add`,{name:u(d({name:`name`})).pipe(f(`Component or registry item to add`)),target:u(d({name:`target`})).pipe(f(`Optional add target`)),noInstall:_(`no-install`).pipe(y(`Skip package installation`)),CI:_(`ci`).pipe(y(`Deprecated alias for --non-interactive`)),nonInteractive:_(`non-interactive`).pipe(y(`Never prompt for input; fail when required values are missing`)),debug:_(`debug`).pipe(y(`Run in debug mode`))},({name:e,target:t,noInstall:n,CI:r,nonInteractive:i,debug:a})=>$(async()=>{let[{runAdd:o},{initProgramState:s,state:c}]=await Promise.all([import(`./add-DrcID6d6.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);s({noInstall:n,ci:r,nonInteractive:i,debug:a}),c.baseCommand=`add`,c.projectDir=process.cwd(),await o(w(e),{noInstall:n,target:w(t)})},{nonInteractive:r||i,debug:a})).pipe(h(`Add a new component to your project`))}function $t(){return p(`remove`,{name:u(d({name:`name`})).pipe(f(`Component type to remove`)),CI:_(`ci`).pipe(y(`Deprecated alias for --non-interactive`)),nonInteractive:_(`non-interactive`).pipe(y(`Never prompt for input; fail when required values are missing`)),debug:_(`debug`).pipe(y(`Run in debug mode`))},({name:e,CI:t,nonInteractive:n,debug:r})=>$(async()=>{let[{runRemove:i},{initProgramState:a,state:o}]=await Promise.all([import(`./remove-BOCU6In3.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);a({ci:t,nonInteractive:n,debug:r}),o.baseCommand=`remove`,o.projectDir=process.cwd(),await i(w(e))},{nonInteractive:t||n,debug:r})).pipe(h(`Remove a component from your project`))}function en(){return p(`typegen`,{debug:_(`debug`).pipe(y(`Run in debug mode`))},({debug:e})=>$(async()=>{let[{runTypegen:e},{state:t}]=await Promise.all([import(`./typegen-DyXaif5O.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);t.projectDir=process.cwd(),await e({settings:(await import(`./parseSettings-DJ2m9sgJ.js`).then(e=>e.i)).getSettings()})},{debug:e})).pipe(h(`Generate types for your project`))}function tn(){return p(`deploy`,{debug:_(`debug`).pipe(y(`Run in debug mode`))},({debug:e})=>$(async()=>{let[{runDeploy:t},{initProgramState:n,state:r}]=await Promise.all([import(`./deploy-D25sPO7K.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);n({debug:e}),r.baseCommand=`deploy`,r.projectDir=process.cwd(),await t()},{debug:e})).pipe(h(`Deploy your app`))}function nn(){return p(`upgrade`,{CI:_(`ci`).pipe(y(`Deprecated alias for --non-interactive`)),nonInteractive:_(`non-interactive`).pipe(y(`Never prompt for input; fail when required values are missing`)),debug:_(`debug`).pipe(y(`Run in debug mode`))},({CI:e,nonInteractive:t,debug:n})=>$(async()=>{let[{runUpgrade:r},{initProgramState:i,state:a}]=await Promise.all([import(`./update-FX71y5b3.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);i({ci:e,nonInteractive:t,debug:n}),a.baseCommand=`upgrade`,a.projectDir=process.cwd(),await r()},{nonInteractive:e||t,debug:n})).pipe(h(`Upgrade ProofKit components in your project`))}const rn=m(p(r,{CI:_(`ci`).pipe(y(`Deprecated alias for --non-interactive`)),nonInteractive:_(`non-interactive`).pipe(y(`Never prompt for input; fail when required values are missing`)),debug:_(`debug`).pipe(y(`Run in debug mode`))},e=>J({cwd:process.cwd(),debug:e.debug===!0,nonInteractive:!!(e.CI||e.nonInteractive)})(Jt({...X,CI:e.CI,nonInteractive:e.nonInteractive,debug:e.debug}))).pipe(h(`Interactive CLI to scaffold and manage ProofKit projects`),g([Zt(),Qt(),$t(),en(),tn(),nn()])),{name:`ProofKit`,version:qt()});function an(e,t){if(!e)return!1;let n=l(t);try{return s(e)===s(n)}catch{return c.resolve(e)===c.resolve(n)}}const on=an(process.argv[1],import.meta.url),sn=new Set([`--debug`]);function cn(e){return e.some(e=>sn.has(e))}function ln(e,t){let n=w(b.failureOption(e));if(!(n&&re(n))){let t=b.squash(e);console.error(t instanceof Error?t.message:String(t))}t&&console.error(`\n[debug] ${b.pretty(e)}`)}async function un(e){let t=cn(e),n=await S.runPromiseExit(rn(e).pipe(S.provide(ie)));ae.isFailure(n)&&(ln(n.cause,t),process.exitCode=1)}on&&(Kt(qt()),un(process.argv).catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1}));export{rn as cli,Jt as runDefaultCommand,Z as runInit};
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["parseJsonc","chalk","intro","clackIntro","log","clackLog","note","clackNote","spinner","clackSpinner","isCancel","clackIsCancel","inquirerInput","inquirerPassword","inquirerConfirm","inquirerSelect","inquirerSearch","inquirerCheckbox","isCancel","log","note","fs","createSpinner","optionalArg","textArg","withArgDescription","optionalOption","textOption","withOptionDescription","choiceOption","makeCommand","booleanOption","withCommandDescription","nodeContextLayer"],"sources":["../src/core/context.ts","../src/core/errors.ts","../src/utils/projectFiles.ts","../src/utils/versioning.ts","../src/core/planInit.ts","../src/core/executeInitPlan.ts","../src/utils/projectName.ts","../src/core/resolveInitRequest.ts","../src/utils/browserOpen.ts","../src/utils/http.ts","../src/utils/packageManager.ts","../src/utils/prompts.ts","../src/services/live.ts","../src/utils/renderTitle.ts","../src/index.ts"],"sourcesContent":["import { Context } from \"effect\";\nimport type { AppType, FileMakerEnvNames, FileMakerInputs, ProofKitSettings, UIType } from \"~/core/types.js\";\nimport type { PackageManager } from \"~/utils/packageManager.js\";\n\nexport interface CliContextValue {\n cwd: string;\n debug: boolean;\n nonInteractive: boolean;\n packageManager: PackageManager;\n resolvedProjectConfig?: {\n appType?: AppType;\n ui?: UIType;\n projectDir?: string;\n };\n}\n\nexport const CliContext = Context.GenericTag<CliContextValue>(\"@proofkit/cli/CliContext\");\n\nexport interface PromptService {\n readonly text: (options: {\n message: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n }) => Promise<string>;\n readonly password: (options: {\n message: string;\n validate?: (value: string) => string | undefined;\n }) => Promise<string>;\n readonly select: <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string; disabled?: boolean | string }>;\n }) => Promise<T>;\n readonly searchSelect: <T extends string>(options: {\n message: string;\n emptyMessage?: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n }) => Promise<T>;\n readonly multiSearchSelect: <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n required?: boolean;\n }) => Promise<T[]>;\n readonly confirm: (options: { message: string; initialValue?: boolean }) => Promise<boolean>;\n}\n\nexport const PromptService = Context.GenericTag<PromptService>(\"@proofkit/cli/PromptService\");\n\nexport interface ConsoleService {\n readonly info: (message: string) => void;\n readonly warn: (message: string) => void;\n readonly error: (message: string) => void;\n readonly success: (message: string) => void;\n readonly note: (message: string, title?: string) => void;\n}\n\nexport const ConsoleService = Context.GenericTag<ConsoleService>(\"@proofkit/cli/ConsoleService\");\n\nexport interface FileSystemService {\n readonly exists: (path: string) => Promise<boolean>;\n readonly readdir: (path: string) => Promise<string[]>;\n readonly emptyDir: (path: string) => Promise<void>;\n readonly copyDir: (from: string, to: string, options?: { overwrite?: boolean }) => Promise<void>;\n readonly rename: (from: string, to: string) => Promise<void>;\n readonly remove: (path: string) => Promise<void>;\n readonly readJson: <T>(path: string) => Promise<T>;\n readonly writeJson: (path: string, value: unknown) => Promise<void>;\n readonly writeFile: (path: string, content: string) => Promise<void>;\n readonly readFile: (path: string) => Promise<string>;\n}\n\nexport const FileSystemService = Context.GenericTag<FileSystemService>(\"@proofkit/cli/FileSystemService\");\n\nexport interface TemplateService {\n readonly getTemplateDir: (appType: AppType, ui: UIType) => string;\n}\n\nexport const TemplateService = Context.GenericTag<TemplateService>(\"@proofkit/cli/TemplateService\");\n\nexport interface PackageManagerService {\n readonly getVersion: (packageManager: PackageManager, cwd: string) => Promise<string | undefined>;\n}\n\nexport const PackageManagerService = Context.GenericTag<PackageManagerService>(\"@proofkit/cli/PackageManagerService\");\n\nexport interface ProcessService {\n readonly run: (\n command: string,\n args: string[],\n options: {\n cwd: string;\n stdout?: \"pipe\" | \"inherit\" | \"ignore\";\n stderr?: \"pipe\" | \"inherit\" | \"ignore\";\n },\n ) => Promise<{ stdout: string; stderr: string }>;\n}\n\nexport const ProcessService = Context.GenericTag<ProcessService>(\"@proofkit/cli/ProcessService\");\n\nexport interface GitService {\n readonly initialize: (projectDir: string) => Promise<void>;\n}\n\nexport const GitService = Context.GenericTag<GitService>(\"@proofkit/cli/GitService\");\n\nexport interface SettingsService {\n readonly writeSettings: (projectDir: string, settings: ProofKitSettings) => Promise<void>;\n readonly appendEnvVars: (projectDir: string, vars: Record<string, string>) => Promise<void>;\n readonly ensureTypegenConfig: (\n projectDir: string,\n options: { appType: AppType; fileMaker?: FileMakerInputs },\n ) => Promise<void>;\n}\n\nexport const SettingsService = Context.GenericTag<SettingsService>(\"@proofkit/cli/SettingsService\");\n\nexport interface FmMcpStatus {\n baseUrl: string;\n healthy: boolean;\n connectedFiles: string[];\n}\n\nexport interface FileMakerServerVersions {\n fmsVersion: string;\n ottoVersion: string | null;\n}\n\nexport interface OttoFileInfo {\n filename: string;\n status: string;\n}\n\nexport interface OttoApiKeyInfo {\n key: string;\n user: string;\n database: string;\n label: string;\n}\n\nexport interface FileMakerDataSourceEntry {\n type: \"fm\";\n name: string;\n envNames: FileMakerEnvNames;\n}\n\nexport interface FileMakerBootstrapArtifacts {\n settings: ProofKitSettings;\n envVars: Record<string, string>;\n envSchemaEntries: Array<{\n name: string;\n zodSchema: string;\n defaultValue: string;\n }>;\n typegenConfig: {\n mode: FileMakerInputs[\"mode\"];\n dataSourceName: string;\n envNames?: FileMakerEnvNames;\n fmMcpBaseUrl?: string;\n connectedFileName?: string;\n layoutName?: string;\n schemaName?: string;\n appType: AppType;\n };\n}\n\nexport interface FileMakerService {\n readonly detectLocalFmMcp: (baseUrl?: string) => Promise<FmMcpStatus>;\n readonly validateHostedServerUrl: (\n serverUrl: string,\n ottoPort?: number | null,\n ) => Promise<{\n normalizedUrl: string;\n versions: FileMakerServerVersions;\n }>;\n readonly getOttoFMSToken: (options: { url: URL }) => Promise<{ token: string }>;\n readonly listFiles: (options: { url: URL; token: string }) => Promise<OttoFileInfo[]>;\n readonly listAPIKeys: (options: { url: URL; token: string }) => Promise<OttoApiKeyInfo[]>;\n readonly createDataAPIKeyWithCredentials: (options: {\n url: URL;\n filename: string;\n username: string;\n password: string;\n }) => Promise<{ apiKey: string }>;\n readonly deployDemoFile: (options: {\n url: URL;\n token: string;\n operation: \"install\" | \"replace\";\n }) => Promise<{ apiKey: string; filename: string }>;\n readonly listLayouts: (options: { dataApiKey: string; fmFile: string; server: string }) => Promise<string[]>;\n readonly createFileMakerBootstrapArtifacts: (\n settings: ProofKitSettings,\n inputs: FileMakerInputs,\n appType: AppType,\n ) => Promise<FileMakerBootstrapArtifacts>;\n readonly bootstrap: (\n projectDir: string,\n settings: ProofKitSettings,\n inputs: FileMakerInputs,\n appType: AppType,\n ) => Promise<ProofKitSettings>;\n}\n\nexport const FileMakerService = Context.GenericTag<FileMakerService>(\"@proofkit/cli/FileMakerService\");\n\nexport interface CodegenService {\n readonly runInitial: (projectDir: string, packageManager: PackageManager) => Promise<void>;\n}\n\nexport const CodegenService = Context.GenericTag<CodegenService>(\"@proofkit/cli/CodegenService\");\n","export class UserAbortedError extends Error {\n constructor(message = \"User aborted the operation\") {\n super(message);\n this.name = \"UserAbortedError\";\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { applyEdits, modify, parse as parseJsonc } from \"jsonc-parser\";\nimport { PKG_ROOT } from \"~/consts.js\";\nimport type { FileMakerEnvNames } from \"~/core/types.js\";\nimport type { PackageManager } from \"~/utils/packageManager.js\";\n\nconst commonFileMakerLayoutPrefixes = [\"API_\", \"API \", \"dapi_\", \"dapi\"];\nconst TRAILING_SLASH_REGEX = /[^/]$/;\nconst textFileExtensions = new Set([\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".jsonc\",\n \".md\",\n \".css\",\n \".scss\",\n \".html\",\n \".mjs\",\n \".cjs\",\n]);\n\nexport function getDefaultSchemaName(layoutName: string) {\n let schemaName = layoutName.replace(/[-\\s]/g, \"_\");\n for (const prefix of commonFileMakerLayoutPrefixes) {\n if (schemaName.startsWith(prefix)) {\n schemaName = schemaName.replace(prefix, \"\");\n }\n }\n return schemaName;\n}\n\nexport function createDataSourceEnvNames(dataSourceName: string): FileMakerEnvNames {\n if (dataSourceName === \"filemaker\") {\n return {\n database: \"FM_DATABASE\",\n server: \"FM_SERVER\",\n apiKey: \"OTTO_API_KEY\",\n };\n }\n\n const upperName = dataSourceName.toUpperCase();\n return {\n database: `${upperName}_FM_DATABASE`,\n server: `${upperName}_FM_SERVER`,\n apiKey: `${upperName}_OTTO_API_KEY`,\n };\n}\n\nexport function formatPackageManagerCommand(packageManager: PackageManager, command: string) {\n return [\"npm\", \"bun\"].includes(packageManager) ? `${packageManager} run ${command}` : `${packageManager} ${command}`;\n}\n\nexport function getTemplatePackageCommand(packageManager: PackageManager) {\n if (packageManager === \"npm\") {\n return \"npm run\";\n }\n return packageManager;\n}\n\nexport function normalizeImportAlias(importAlias: string) {\n return importAlias.replace(/\\*/g, \"\").replace(TRAILING_SLASH_REGEX, \"$&/\");\n}\n\nexport async function replaceTextInFiles(\n fs: {\n readdir: (path: string) => Promise<string[]>;\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, content: string) => Promise<void>;\n },\n rootDir: string,\n searchValue: string,\n replaceValue: string,\n) {\n const entries = await fs.readdir(rootDir);\n for (const entry of entries) {\n const fullPath = path.join(rootDir, entry);\n const childEntries = await fs.readdir(fullPath).catch((error: unknown) => {\n const code =\n typeof error === \"object\" && error !== null && \"code\" in error && typeof error.code === \"string\"\n ? error.code\n : undefined;\n\n if (code === \"ENOTDIR\") {\n return undefined;\n }\n\n throw error;\n });\n if (childEntries) {\n await replaceTextInFiles(fs, fullPath, searchValue, replaceValue);\n continue;\n }\n\n const extension = path.extname(entry);\n if (!textFileExtensions.has(extension)) {\n continue;\n }\n\n const content = await fs.readFile(fullPath).catch(() => undefined);\n if (!content?.includes(searchValue)) {\n continue;\n }\n\n await fs.writeFile(fullPath, content.replaceAll(searchValue, replaceValue));\n }\n}\n\nexport async function updateEnvSchemaFile(\n fs: {\n exists: (path: string) => Promise<boolean>;\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, content: string) => Promise<void>;\n },\n projectDir: string,\n envEntries: Array<{ name: string; zodSchema: string }>,\n) {\n const envFilePath = path.join(projectDir, \"src/lib/env.ts\");\n if (!(await fs.exists(envFilePath))) {\n return;\n }\n\n let content = await fs.readFile(envFilePath);\n const marker = \" server: {\";\n const markerIndex = content.indexOf(marker);\n if (markerIndex === -1) {\n return;\n }\n\n const insertIndex = content.indexOf(\" },\", markerIndex);\n if (insertIndex === -1) {\n return;\n }\n\n const additions = envEntries\n .filter((entry) => !content.includes(`${entry.name}:`))\n .map((entry) => ` ${entry.name}: ${entry.zodSchema},`)\n .join(\"\\n\");\n\n if (!additions) {\n return;\n }\n\n content = `${content.slice(0, insertIndex)}${additions}\\n${content.slice(insertIndex)}`;\n await fs.writeFile(envFilePath, content);\n}\n\ninterface TypegenFileContent {\n $schema?: string;\n config: Record<string, unknown>[] | Record<string, unknown>;\n}\n\nexport async function updateTypegenConfig(\n fs: {\n exists: (path: string) => Promise<boolean>;\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, content: string) => Promise<void>;\n },\n projectDir: string,\n options: {\n appType: \"browser\" | \"webviewer\";\n dataSourceName: string;\n envNames?: FileMakerEnvNames;\n fmMcpBaseUrl?: string;\n connectedFileName?: string;\n layoutName?: string;\n schemaName?: string;\n },\n) {\n const configPath = path.join(projectDir, \"proofkit-typegen.config.jsonc\");\n const dsPath = `./src/config/schemas/${options.dataSourceName}`;\n const nextDataSource: Record<string, unknown> = {\n type: \"fmdapi\",\n layouts: [],\n path: dsPath,\n clearOldFiles: true,\n clientSuffix: \"Layout\",\n };\n\n if (options.envNames) {\n nextDataSource.envNames = {\n server: options.envNames.server,\n db: options.envNames.database,\n auth: { apiKey: options.envNames.apiKey },\n };\n }\n\n if (options.appType === \"webviewer\") {\n nextDataSource.webviewerScriptName = \"ExecuteDataApi\";\n }\n\n if (options.fmMcpBaseUrl) {\n nextDataSource.fmMcp = {\n enabled: true,\n baseUrl: options.fmMcpBaseUrl,\n ...(options.connectedFileName ? { connectedFileName: options.connectedFileName } : {}),\n };\n }\n\n const layout =\n options.layoutName && options.schemaName\n ? {\n layoutName: options.layoutName,\n schemaName: options.schemaName,\n valueLists: \"allowEmpty\",\n }\n : undefined;\n\n if (layout) {\n nextDataSource.layouts = [layout];\n }\n\n if (!(await fs.exists(configPath))) {\n const nextContent: TypegenFileContent = {\n $schema: \"https://proofkit.dev/typegen-config-schema.json\",\n config: [nextDataSource],\n };\n await fs.writeFile(configPath, `${JSON.stringify(nextContent, null, 2)}\\n`);\n return;\n }\n\n const original = await fs.readFile(configPath);\n const parsed = parseJsonc(original) as TypegenFileContent;\n const configArray = Array.isArray(parsed.config) ? parsed.config : [parsed.config];\n const existingIndex = configArray.findIndex((entry) => entry.path === dsPath);\n\n if (existingIndex === -1) {\n configArray.push(nextDataSource);\n } else {\n const existing = (configArray[existingIndex] ?? {}) as Record<string, unknown>;\n const existingLayouts = Array.isArray(existing.layouts) ? existing.layouts : [];\n let nextLayouts = existingLayouts;\n if (layout && !existingLayouts.some((item) => item?.layoutName === layout.layoutName)) {\n nextLayouts = [...existingLayouts, layout];\n }\n configArray[existingIndex] = {\n ...existing,\n ...nextDataSource,\n layouts: nextLayouts,\n };\n }\n\n const nextConfig = Array.isArray(parsed.config) ? configArray : (configArray[0] ?? nextDataSource);\n const edits = modify(original, [\"config\"], nextConfig, {\n formattingOptions: {\n insertSpaces: true,\n tabSize: 2,\n eol: \"\\n\",\n },\n });\n await fs.writeFile(configPath, applyEdits(original, edits));\n}\n\nexport function getScaffoldVersion() {\n const candidates = [path.resolve(PKG_ROOT, \"package.json\"), path.resolve(PKG_ROOT, \"../cli/package.json\")];\n\n for (const candidate of candidates) {\n try {\n const packageJson = JSON.parse(readFileSync(candidate, \"utf8\")) as { version?: string };\n if (packageJson.version && packageJson.version !== \"0.0.0-private\") {\n return packageJson.version;\n }\n } catch {\n // ignore and continue searching\n }\n }\n\n return \"0.0.0-private\";\n}\n","export function getProofkitReleaseTag() {\n return \"beta\";\n}\n\nexport function getNodeMajorVersion() {\n return process.versions.node.split(\".\")[0] ?? \"22\";\n}\n","import path from \"node:path\";\nimport type { PackageJson } from \"type-fest\";\n\nimport type { InitPlan, InitRequest, ProofKitSettings } from \"~/core/types.js\";\nimport { formatPackageManagerCommand, getScaffoldVersion, getTemplatePackageCommand } from \"~/utils/projectFiles.js\";\nimport { getNodeMajorVersion, getProofkitReleaseTag } from \"~/utils/versioning.js\";\n\nfunction createDefaultSettings(request: InitRequest): ProofKitSettings {\n return {\n ui: request.ui,\n appType: request.appType,\n envFile: \".env\",\n dataSources: [],\n replacedMainPage: false,\n registryTemplates: [],\n };\n}\n\nfunction createEnvFileContent() {\n return [\"# When adding additional environment variables, update the schema alongside this file.\", \"\"].join(\"\\n\");\n}\n\nconst sharedUiDependencies = {\n \"@radix-ui/react-slot\": \"^1.2.3\",\n \"class-variance-authority\": \"^0.7.1\",\n clsx: \"^2.1.1\",\n \"lucide-react\": \"^0.577.0\",\n \"tailwind-merge\": \"^3.5.0\",\n tailwindcss: \"^4.1.10\",\n \"tw-animate-css\": \"^1.4.0\",\n} satisfies Record<string, string>;\n\nexport function planInit(\n request: InitRequest,\n options: { templateDir: string; packageManagerVersion?: string },\n): InitPlan {\n const targetDir = path.resolve(request.cwd, request.appDir);\n const releaseTag = getProofkitReleaseTag();\n const settings = createDefaultSettings(request);\n const packageManagerCommand = getTemplatePackageCommand(request.packageManager);\n\n const packageJson: InitPlan[\"packageJson\"] = {\n name: request.scopedAppName,\n packageManager: options.packageManagerVersion\n ? `${request.packageManager}@${options.packageManagerVersion}`\n : undefined,\n proofkitMetadata: {\n initVersion: getScaffoldVersion(),\n scaffoldPackage: \"@proofkit/cli\",\n },\n dependencies: {},\n devDependencies: {\n \"@proofkit/cli\": releaseTag,\n \"@types/node\": `^${getNodeMajorVersion()}`,\n },\n };\n\n if (request.appType === \"browser\") {\n Object.assign(packageJson.dependencies, sharedUiDependencies);\n packageJson.dependencies[\"@tailwindcss/postcss\"] = \"^4.1.10\";\n packageJson.dependencies[\"next-themes\"] = \"^0.4.6\";\n }\n\n if (request.appType === \"webviewer\") {\n Object.assign(packageJson.dependencies, sharedUiDependencies);\n packageJson.dependencies[\"@proofkit/fmdapi\"] = releaseTag;\n packageJson.dependencies[\"@proofkit/webviewer\"] = releaseTag;\n packageJson.dependencies[\"@tanstack/react-query\"] = \"^5.90.21\";\n packageJson.dependencies[\"@tanstack/react-router\"] = \"^1.167.4\";\n packageJson.dependencies.zod = \"^4\";\n packageJson.devDependencies[\"@proofkit/typegen\"] = releaseTag;\n packageJson.devDependencies[\"@tailwindcss/vite\"] = \"^4.2.1\";\n packageJson.devDependencies.ultracite = \"7.0.8\";\n }\n\n return {\n request,\n targetDir,\n templateDir: options.templateDir,\n packageManagerCommand,\n packageJson,\n settings,\n envFile: {\n path: path.join(targetDir, \".env\"),\n content: createEnvFileContent(),\n },\n writes: [],\n commands: [\n ...(request.noInstall ? [] : [{ type: \"install\" as const }]),\n ...(request.dataSource === \"filemaker\" &&\n !request.skipFileMakerSetup &&\n !(request.appType === \"webviewer\" && request.nonInteractive && !request.hasExplicitFileMakerInputs)\n ? [{ type: \"codegen\" as const }]\n : []),\n ...(request.noGit ? [] : [{ type: \"git-init\" as const }]),\n ],\n tasks: {\n bootstrapFileMaker: request.dataSource === \"filemaker\" && !request.skipFileMakerSetup,\n checkWebViewerAddon: request.appType === \"webviewer\",\n runInstall: !request.noInstall,\n runInitialCodegen:\n request.dataSource === \"filemaker\" &&\n !request.skipFileMakerSetup &&\n !(request.appType === \"webviewer\" && request.nonInteractive && !request.hasExplicitFileMakerInputs),\n initializeGit: !request.noGit,\n },\n nextSteps: [\n `cd ${request.appDir}`,\n ...(request.noInstall ? [request.packageManager === \"yarn\" ? \"yarn\" : `${request.packageManager} install`] : []),\n \"npx @tanstack/intent@latest install\",\n formatPackageManagerCommand(request.packageManager, \"dev\"),\n ...(request.appType === \"webviewer\"\n ? [\n formatPackageManagerCommand(request.packageManager, \"typegen\"),\n formatPackageManagerCommand(request.packageManager, \"launch-fm\"),\n ]\n : []),\n formatPackageManagerCommand(request.packageManager, \"proofkit\"),\n ],\n };\n}\n\nexport function applyPackageJsonMutations(\n packageJson: PackageJson,\n mutations: InitPlan[\"packageJson\"],\n overwriteDependencies = true,\n) {\n packageJson.name = mutations.name;\n packageJson.proofkitMetadata = mutations.proofkitMetadata as PackageJson[\"proofkitMetadata\"];\n if (mutations.packageManager) {\n packageJson.packageManager = mutations.packageManager;\n }\n\n if (!packageJson.dependencies) {\n packageJson.dependencies = {};\n }\n if (!packageJson.devDependencies) {\n packageJson.devDependencies = {};\n }\n\n const merge = (target: Record<string, string>, source: Record<string, string>) => {\n for (const [name, version] of Object.entries(source)) {\n if (overwriteDependencies || !(name in target)) {\n target[name] = version;\n }\n }\n };\n\n merge(packageJson.dependencies as Record<string, string>, mutations.dependencies);\n merge(packageJson.devDependencies as Record<string, string>, mutations.devDependencies);\n\n return packageJson;\n}\n","import path from \"node:path\";\nimport { Chalk } from \"chalk\";\nimport { Effect } from \"effect\";\nimport sortPackageJson from \"sort-package-json\";\n\nimport { AGENT_INSTRUCTIONS } from \"~/consts.js\";\nimport {\n CliContext,\n CodegenService,\n ConsoleService,\n FileMakerService,\n FileSystemService,\n GitService,\n PackageManagerService,\n ProcessService,\n PromptService,\n SettingsService,\n} from \"~/core/context.js\";\nimport { UserAbortedError } from \"~/core/errors.js\";\nimport { applyPackageJsonMutations } from \"~/core/planInit.js\";\nimport type { InitPlan } from \"~/core/types.js\";\nimport { normalizeImportAlias, replaceTextInFiles } from \"~/utils/projectFiles.js\";\n\nconst AGENT_METADATA_DIRS = new Set([\".agents\", \".claude\", \".clawed\", \".clinerules\", \".cursor\", \".windsurf\"]);\nconst IMPORT_ALIAS_WILDCARD_REGEX = /\\*/g;\nconst IMPORT_ALIAS_TRAILING_SLASH_REGEX = /\\/?$/;\nconst chalk = new Chalk({ level: 1 });\n\nconst formatCommand = (command: string) => chalk.cyan(command);\nconst formatHeading = (heading: string) => chalk.bold(heading);\nconst formatPath = (value: string) => chalk.yellow(value);\n\nfunction renderNextSteps(plan: InitPlan, additionalSteps: string[] = []) {\n const lines = [\n `${formatHeading(\"Project root:\")} ${formatCommand(`cd ${formatPath(plan.request.appDir)}`)}`,\n \"\",\n formatHeading(\"Agent setup:\"),\n \"Have your agent run this in the new project and complete the interactive prompt so it can load the right skills:\",\n ` ${formatCommand(\"npx @tanstack/intent@latest install\")}`,\n ];\n\n if (plan.request.noInstall) {\n lines.push(\n \"\",\n formatHeading(\"Install dependencies:\"),\n ` ${formatCommand(plan.request.packageManager === \"yarn\" ? \"yarn\" : `${plan.request.packageManager} install`)}`,\n );\n }\n\n lines.push(\"\", formatHeading(\"Start the app:\"), ` ${formatCommand(`${plan.packageManagerCommand} dev`)}`);\n\n if (plan.request.appType === \"webviewer\") {\n lines.push(\n \"\",\n formatHeading(\"When your FileMaker file is ready:\"),\n ` ${formatCommand(`${plan.packageManagerCommand} typegen`)}`,\n ` ${formatCommand(`${plan.packageManagerCommand} launch-fm`)}`,\n );\n\n if (additionalSteps.length > 0) {\n lines.push(...additionalSteps.map((step) => ` ${formatCommand(step)}`));\n }\n }\n\n lines.push(\n \"\",\n formatHeading(\"More ProofKit commands:\"),\n ` ${formatCommand(`${plan.packageManagerCommand} proofkit`)}`,\n );\n\n return lines.join(\"\\n\");\n}\n\nfunction getMeaningfulDirectoryEntries(entries: string[]) {\n return entries.filter((entry) => {\n if (AGENT_METADATA_DIRS.has(entry)) {\n return false;\n }\n if (entry === \".gitignore\") {\n return true;\n }\n if (entry.startsWith(\".\")) {\n return false;\n }\n return true;\n });\n}\n\nexport const prepareDirectory = (plan: InitPlan) =>\n Effect.gen(function* () {\n const fs = yield* FileSystemService;\n const consoleService = yield* ConsoleService;\n const cliContext = yield* CliContext;\n const prompts = yield* PromptService;\n\n const exists = yield* Effect.promise(() => fs.exists(plan.targetDir));\n if (!exists) {\n return;\n }\n\n const entries = yield* Effect.promise(() => fs.readdir(plan.targetDir));\n const meaningfulEntries = getMeaningfulDirectoryEntries(entries);\n if (meaningfulEntries.length === 0) {\n return;\n }\n\n if (plan.request.force) {\n yield* Effect.promise(() => fs.emptyDir(plan.targetDir));\n return;\n }\n\n if (cliContext.nonInteractive) {\n throw new Error(\n `${plan.request.appDir} already exists and isn't empty. Remove the existing files or choose a different directory.`,\n );\n }\n\n const overwriteMode = yield* Effect.promise(() =>\n prompts.select({\n message: `${plan.request.appDir} already exists and isn't empty. How would you like to proceed?`,\n options: [\n { value: \"abort\", label: \"Abort installation\" },\n { value: \"clear\", label: \"Clear the directory and continue\" },\n { value: \"overwrite\", label: \"Continue and overwrite conflicting files\" },\n ],\n }),\n );\n\n if (overwriteMode === \"abort\") {\n throw new UserAbortedError();\n }\n\n if (overwriteMode === \"clear\") {\n const confirmed = yield* Effect.promise(() =>\n prompts.confirm({\n message: \"Are you sure you want to clear the directory?\",\n initialValue: false,\n }),\n );\n if (!confirmed) {\n throw new UserAbortedError();\n }\n yield* Effect.promise(() => fs.emptyDir(plan.targetDir));\n return;\n }\n\n consoleService.warn(`Continuing in ${plan.request.appDir} and overwriting conflicting files when needed.`);\n });\n\nexport const executeInitPlan = (plan: InitPlan) =>\n Effect.gen(function* () {\n const cliContext = yield* CliContext;\n const fs = yield* FileSystemService;\n const consoleService = yield* ConsoleService;\n const settingsService = yield* SettingsService;\n const fileMakerService = yield* FileMakerService;\n const processService = yield* ProcessService;\n const gitService = yield* GitService;\n const codegenService = yield* CodegenService;\n const packageManagerService = yield* PackageManagerService;\n const additionalNextSteps: string[] = [];\n\n yield* prepareDirectory(plan);\n\n consoleService.info(`Scaffolding in ${plan.targetDir}`);\n yield* Effect.promise(() => fs.copyDir(plan.templateDir, plan.targetDir, { overwrite: true }));\n\n const stagedGitignore = path.join(plan.targetDir, \"_gitignore\");\n const finalGitignore = path.join(plan.targetDir, \".gitignore\");\n if (yield* Effect.promise(() => fs.exists(stagedGitignore))) {\n if (yield* Effect.promise(() => fs.exists(finalGitignore))) {\n yield* Effect.promise(() => fs.remove(stagedGitignore));\n } else {\n yield* Effect.promise(() => fs.rename(stagedGitignore, finalGitignore));\n }\n }\n\n const packageJsonPath = path.join(plan.targetDir, \"package.json\");\n const packageJson = yield* Effect.promise(() => fs.readJson<Record<string, unknown>>(packageJsonPath));\n const updatedPackageJson = sortPackageJson(\n applyPackageJsonMutations(packageJson as never, plan.packageJson) as never,\n );\n yield* Effect.promise(() => fs.writeJson(packageJsonPath, updatedPackageJson));\n\n yield* Effect.promise(() => settingsService.writeSettings(plan.targetDir, plan.settings));\n yield* Effect.promise(() => fs.writeFile(plan.envFile.path, plan.envFile.content));\n for (const write of plan.writes) {\n yield* Effect.promise(() => fs.writeFile(write.path, write.content));\n }\n\n yield* Effect.promise(() => replaceTextInFiles(fs, plan.targetDir, \"__PNPM_COMMAND__\", plan.packageManagerCommand));\n yield* Effect.promise(() =>\n replaceTextInFiles(fs, plan.targetDir, \"__PACKAGE_MANAGER__\", plan.request.packageManager),\n );\n yield* Effect.promise(() => replaceTextInFiles(fs, plan.targetDir, \"__AGENT_INSTRUCTIONS__\", AGENT_INSTRUCTIONS));\n if (plan.request.importAlias !== \"~/\") {\n yield* Effect.promise(() =>\n replaceTextInFiles(fs, plan.targetDir, \"~/\", normalizeImportAlias(plan.request.importAlias)),\n );\n yield* Effect.promise(() =>\n replaceTextInFiles(\n fs,\n plan.targetDir,\n \"@/\",\n plan.request.importAlias\n .replace(IMPORT_ALIAS_WILDCARD_REGEX, \"\")\n .replace(IMPORT_ALIAS_TRAILING_SLASH_REGEX, \"/\"),\n ),\n );\n }\n\n let nextSettings = plan.settings;\n if (plan.tasks.bootstrapFileMaker && plan.request.fileMaker) {\n const fileMakerInputs = plan.request.fileMaker;\n nextSettings = yield* Effect.promise(() =>\n fileMakerService.bootstrap(plan.targetDir, nextSettings, fileMakerInputs, plan.request.appType),\n );\n yield* Effect.promise(() => settingsService.writeSettings(plan.targetDir, nextSettings));\n }\n\n if (plan.tasks.checkWebViewerAddon) {\n yield* Effect.promise(async () => {\n try {\n const { checkForWebViewerLayouts, getWebViewerAddonMessages } = await import(\n \"~/installers/proofkit-webviewer.js\"\n );\n const status = await checkForWebViewerLayouts(plan.targetDir);\n const messages = getWebViewerAddonMessages(status);\n\n for (const message of messages.warn) {\n consoleService.warn(message);\n }\n for (const message of messages.info) {\n consoleService.info(message);\n }\n if (cliContext.nonInteractive) {\n additionalNextSteps.push(...messages.nextSteps);\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n consoleService.warn(`Could not inspect the ProofKit WebViewer add-on (${message}).`);\n }\n });\n }\n\n if (plan.tasks.runInstall) {\n let installArgs: string[] = [\"install\"];\n if (plan.request.packageManager === \"yarn\") {\n installArgs = [];\n }\n yield* Effect.promise(() =>\n processService.run(plan.request.packageManager, installArgs, {\n cwd: plan.targetDir,\n stdout: \"pipe\",\n stderr: \"pipe\",\n }),\n );\n }\n\n if (plan.tasks.runInitialCodegen) {\n yield* Effect.promise(() => codegenService.runInitial(plan.targetDir, plan.request.packageManager));\n }\n\n if (plan.tasks.initializeGit) {\n yield* Effect.promise(() => gitService.initialize(plan.targetDir));\n }\n\n const packageManagerVersion = yield* Effect.promise(() =>\n packageManagerService.getVersion(plan.request.packageManager, plan.targetDir),\n );\n\n consoleService.success(\n `Created ${plan.request.scopedAppName} in ${plan.targetDir}${\n packageManagerVersion ? ` using ${plan.request.packageManager}@${packageManagerVersion}` : \"\"\n }`,\n );\n consoleService.info(chalk.bold(\"Next steps:\"));\n consoleService.info(renderNextSteps(plan, Array.from(new Set(additionalNextSteps))));\n return plan;\n });\n","import path from \"node:path\";\n\nconst TRAILING_SLASHES_REGEX = /\\/+$/;\nconst PATH_SEPARATOR_REGEX = /\\\\/g;\nconst VALID_APP_NAME_REGEX = /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n\nfunction normalizeProjectName(value: string) {\n return value.replace(PATH_SEPARATOR_REGEX, \"/\");\n}\n\nfunction trimTrailingSlashes(value: string) {\n return normalizeProjectName(value).replace(TRAILING_SLASHES_REGEX, \"\");\n}\n\nexport function parseNameAndPath(projectName: string): [scopedAppName: string, appDir: string] {\n const normalized = trimTrailingSlashes(projectName);\n const segments = normalized.split(\"/\");\n let scopedAppName = segments.at(-1) ?? \"\";\n\n if (scopedAppName === \".\") {\n scopedAppName = path.basename(path.resolve(process.cwd()));\n }\n\n const scopeIndex = segments.findIndex((segment) => segment.startsWith(\"@\"));\n if (scopeIndex !== -1) {\n scopedAppName = segments.slice(scopeIndex).join(\"/\");\n }\n\n const appDir = segments.filter((segment) => !segment.startsWith(\"@\")).join(\"/\");\n\n return [scopedAppName, appDir];\n}\n\nexport function validateAppName(projectName: string) {\n const normalized = trimTrailingSlashes(projectName);\n if (normalized === \".\") {\n const currentDirName = path.basename(path.resolve(process.cwd()));\n return VALID_APP_NAME_REGEX.test(currentDirName)\n ? undefined\n : \"Name must consist of only lowercase alphanumeric characters, '-', and '_'\";\n }\n\n const segments = normalized.split(\"/\");\n const scopeIndex = segments.findIndex((segment) => segment.startsWith(\"@\"));\n let scopedAppName = segments.at(-1);\n\n if (scopeIndex !== -1) {\n scopedAppName = segments.slice(scopeIndex).join(\"/\");\n }\n\n if (VALID_APP_NAME_REGEX.test(scopedAppName ?? \"\")) {\n return;\n }\n\n return \"Name must consist of only lowercase alphanumeric characters, '-', and '_'\";\n}\n","import { Effect } from \"effect\";\n\nimport { DEFAULT_APP_NAME } from \"~/consts.js\";\nimport { CliContext, FileMakerService, PromptService } from \"~/core/context.js\";\nimport type { AppType, CliFlags, DataSourceType, FileMakerInputs, InitRequest } from \"~/core/types.js\";\nimport { createDataSourceEnvNames, getDefaultSchemaName } from \"~/utils/projectFiles.js\";\nimport { parseNameAndPath, validateAppName } from \"~/utils/projectName.js\";\n\nconst defaultFlags: CliFlags = {\n noGit: false,\n noInstall: false,\n force: false,\n default: false,\n CI: false,\n importAlias: \"~/\",\n};\n\nfunction compareSemver(left: string, right: string) {\n const leftParts = left.split(\".\").map((part) => Number.parseInt(part, 10) || 0);\n const rightParts = right.split(\".\").map((part) => Number.parseInt(part, 10) || 0);\n\n for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index += 1) {\n const leftValue = leftParts[index] ?? 0;\n const rightValue = rightParts[index] ?? 0;\n if (leftValue > rightValue) {\n return 1;\n }\n if (leftValue < rightValue) {\n return -1;\n }\n }\n\n return 0;\n}\n\nfunction validateLayoutInputs(flags: CliFlags) {\n const hasLayoutName = Boolean(flags.layoutName);\n const hasSchemaName = Boolean(flags.schemaName);\n\n if (hasLayoutName !== hasSchemaName) {\n throw new Error(\"Both --layout-name and --schema-name must be provided together.\");\n }\n}\n\nasync function resolveHostedFileMakerInputs({\n prompt,\n fileMakerService,\n flags,\n nonInteractive,\n}: {\n prompt: PromptService;\n fileMakerService: FileMakerService;\n flags: CliFlags;\n nonInteractive: boolean;\n}): Promise<FileMakerInputs> {\n validateLayoutInputs(flags);\n\n if (!flags.server && nonInteractive) {\n throw new Error(\n \"Missing required hosted FileMaker inputs in non-interactive mode: --server, --file-name, and --data-api-key.\",\n );\n }\n\n const rawServer =\n flags.server ??\n (await prompt.text({\n message: \"What is the URL of your FileMaker Server?\",\n validate: (value) => {\n try {\n const normalized = value.startsWith(\"http\") ? value : `https://${value}`;\n new URL(normalized);\n return;\n } catch {\n return \"Please enter a valid URL\";\n }\n },\n }));\n\n const { normalizedUrl, versions } = await fileMakerService.validateHostedServerUrl(rawServer);\n const hostedUrl = new URL(normalizedUrl);\n const demoFileName = \"ProofKitDemo.fmp12\";\n\n let selectedFile = flags.fileName;\n let dataApiKey = flags.dataApiKey;\n let layoutName = flags.layoutName;\n let schemaName = flags.schemaName;\n let token: string | undefined;\n let files: Awaited<ReturnType<FileMakerService[\"listFiles\"]>> = [];\n const requireHostedToken = () => {\n if (!token) {\n throw new Error(\"OttoFMS authentication is required for hosted setup.\");\n }\n return token;\n };\n\n if (!(selectedFile && dataApiKey)) {\n if (!(flags.adminApiKey || (versions.ottoVersion && compareSemver(versions.ottoVersion, \"4.7.0\") >= 0))) {\n throw new Error(\n \"OttoFMS 4.7.0 or later is required to auto-login. Upgrade OttoFMS or pass --admin-api-key for hosted setup.\",\n );\n }\n token = flags.adminApiKey ?? (await fileMakerService.getOttoFMSToken({ url: hostedUrl })).token;\n }\n\n if (!selectedFile) {\n if (nonInteractive) {\n throw new Error(\"Missing required FileMaker inputs in non-interactive mode: --file-name, --data-api-key.\");\n }\n\n files = await fileMakerService.listFiles({ url: hostedUrl, token: requireHostedToken() });\n selectedFile = await prompt.searchSelect({\n message: \"Which file would you like to connect to?\",\n options: [\n {\n value: \"$deploy-demo\",\n label: \"Deploy NEW ProofKit Demo File\",\n hint: \"Use OttoFMS to deploy a new file for testing\",\n keywords: [\"demo\", \"proofkit\"],\n },\n ...files\n .slice()\n .sort((left, right) => left.filename.localeCompare(right.filename))\n .map((file) => ({\n value: file.filename,\n label: file.filename,\n hint: file.status,\n keywords: [file.filename],\n })),\n ],\n });\n }\n\n if (!selectedFile) {\n throw new Error(\"No FileMaker file was selected.\");\n }\n\n if (selectedFile === \"$deploy-demo\") {\n if (files.length === 0) {\n files = await fileMakerService.listFiles({ url: hostedUrl, token: requireHostedToken() });\n }\n const demoExists = files.some((file) => file.filename === demoFileName);\n const replaceDemo =\n demoExists && !nonInteractive\n ? await prompt.confirm({\n message: \"The demo file already exists. Do you want to replace it with a fresh copy?\",\n initialValue: false,\n })\n : demoExists;\n const deployed = await fileMakerService.deployDemoFile({\n url: hostedUrl,\n token: requireHostedToken(),\n operation: replaceDemo ? \"replace\" : \"install\",\n });\n selectedFile = deployed.filename;\n dataApiKey = deployed.apiKey;\n layoutName ??= \"API_Contacts\";\n schemaName ??= \"Contacts\";\n }\n\n if (!dataApiKey && nonInteractive) {\n throw new Error(\"Missing required FileMaker inputs in non-interactive mode: --data-api-key.\");\n }\n\n if (!dataApiKey) {\n const apiKeys = (await fileMakerService.listAPIKeys({ url: hostedUrl, token: requireHostedToken() })).filter(\n (apiKey) => apiKey.database === selectedFile,\n );\n\n const selection =\n apiKeys.length === 0\n ? \"create\"\n : await prompt.searchSelect({\n message: \"Which OttoFMS Data API key would you like to use?\",\n options: [\n ...apiKeys.map((apiKey) => ({\n value: apiKey.key,\n label: `${apiKey.label} - ${apiKey.user}`,\n hint: `${apiKey.key.slice(0, 5)}...${apiKey.key.slice(-4)}`,\n keywords: [apiKey.label, apiKey.user, apiKey.database],\n })),\n {\n value: \"create\",\n label: \"Create a new API key\",\n hint: \"Requires FileMaker credentials for this file\",\n keywords: [\"create\", \"new\"],\n },\n ],\n });\n\n if (selection === \"create\") {\n const username = await prompt.text({\n message: `Enter the account name for ${selectedFile}`,\n validate: (value) => (value ? undefined : \"An account name is required\"),\n });\n const password = await prompt.password({\n message: `Enter the password for ${username}`,\n validate: (value) => (value ? undefined : \"A password is required\"),\n });\n dataApiKey = (\n await fileMakerService.createDataAPIKeyWithCredentials({\n url: hostedUrl,\n filename: selectedFile,\n username,\n password,\n })\n ).apiKey;\n } else {\n dataApiKey = selection;\n }\n }\n\n if (!dataApiKey) {\n throw new Error(\"No FileMaker Data API key was selected.\");\n }\n\n const layouts = await fileMakerService.listLayouts({\n dataApiKey,\n fmFile: selectedFile,\n server: hostedUrl.origin,\n });\n\n if (layoutName && !layouts.includes(layoutName)) {\n throw new Error(`Layout \"${layoutName}\" was not found in ${selectedFile}.`);\n }\n\n if (!(nonInteractive || layoutName || schemaName)) {\n const shouldConfigureLayout = await prompt.confirm({\n message: \"Do you want to configure an initial layout for type generation now?\",\n initialValue: false,\n });\n\n if (shouldConfigureLayout) {\n layoutName = await prompt.searchSelect({\n message: \"Select a layout to read data from\",\n options: layouts.map((layout) => ({\n value: layout,\n label: layout,\n keywords: [layout],\n })),\n });\n\n schemaName = await prompt.text({\n message: \"What should the generated schema be called?\",\n defaultValue: getDefaultSchemaName(layoutName),\n validate: (value) => (value ? undefined : \"A schema name is required\"),\n });\n }\n }\n\n return {\n mode: \"hosted-otto\",\n dataSourceName: \"filemaker\",\n envNames: createDataSourceEnvNames(\"filemaker\"),\n server: hostedUrl.origin,\n fileName: selectedFile,\n dataApiKey,\n layoutName,\n schemaName,\n adminApiKey: flags.adminApiKey,\n fmsVersion: versions.fmsVersion,\n ottoVersion: versions.ottoVersion,\n };\n}\n\nasync function resolveFileMakerInputs({\n prompt,\n fileMakerService,\n flags,\n appType,\n nonInteractive,\n}: {\n prompt: PromptService;\n fileMakerService: FileMakerService;\n flags: CliFlags;\n appType: AppType;\n nonInteractive: boolean;\n}) {\n if (flags.dataSource !== \"filemaker\") {\n return { fileMaker: undefined, skipFileMakerSetup: false };\n }\n\n validateLayoutInputs(flags);\n\n if (appType === \"webviewer\" && !flags.server) {\n while (true) {\n const localFmMcp = await fileMakerService.detectLocalFmMcp();\n if (localFmMcp.healthy && localFmMcp.connectedFiles[0]) {\n return {\n fileMaker: {\n mode: \"local-fm-mcp\",\n dataSourceName: \"filemaker\",\n envNames: createDataSourceEnvNames(\"filemaker\"),\n fmMcpBaseUrl: localFmMcp.baseUrl,\n fileName: localFmMcp.connectedFiles[0],\n layoutName: flags.layoutName,\n schemaName: flags.schemaName,\n } satisfies FileMakerInputs,\n skipFileMakerSetup: false,\n };\n }\n\n if (nonInteractive) {\n if (localFmMcp.healthy) {\n throw new Error(\n \"ProofKit MCP Server was detected, but no FileMaker files are open. Open a file in FileMaker and rerun, or pass --server.\",\n );\n }\n\n throw new Error(\n \"ProofKit MCP Server was not detected and no FileMaker server was provided. Start the ProofKit MCP Server locally or rerun with --server.\",\n );\n }\n\n const fallbackAction = await prompt.select({\n message: localFmMcp.healthy\n ? \"I noticed you have the ProofKit MCP Server installed, but no files are open. How would you like to continue?\"\n : \"ProofKit MCP Server was not detected. How would you like to continue?\",\n options: [\n {\n value: \"retry\",\n label: \"Try again\",\n hint: localFmMcp.healthy\n ? \"Open a FileMaker file, then retry detection\"\n : \"Retry ProofKit MCP Server detection\",\n },\n {\n value: \"hosted\",\n label: \"Continue with hosted setup\",\n hint: \"Use OttoFMS and a hosted FileMaker server\",\n },\n {\n value: \"skip\",\n label: \"Skip for now\",\n hint: \"Create the project and configure FileMaker later\",\n },\n ],\n });\n\n if (fallbackAction === \"retry\") {\n continue;\n }\n\n if (fallbackAction === \"skip\") {\n return {\n fileMaker: undefined,\n skipFileMakerSetup: true,\n };\n }\n\n break;\n }\n }\n\n return {\n fileMaker: await resolveHostedFileMakerInputs({\n prompt,\n fileMakerService,\n flags,\n nonInteractive,\n }),\n skipFileMakerSetup: false,\n };\n}\n\nexport const resolveInitRequest = (name?: string, rawFlags?: CliFlags) =>\n Effect.gen(function* () {\n const flags = { ...defaultFlags, ...rawFlags };\n const prompt = yield* PromptService;\n const fileMakerService = yield* FileMakerService;\n const cliContext = yield* CliContext;\n const nonInteractive = cliContext.nonInteractive || flags.CI || flags.nonInteractive === true;\n\n let projectName = name;\n if (!projectName) {\n if (nonInteractive) {\n return yield* Effect.fail(new Error(\"Project name is required in non-interactive mode.\"));\n }\n\n projectName = yield* Effect.promise(() =>\n prompt.text({\n message: \"What will your project be called?\",\n defaultValue: DEFAULT_APP_NAME,\n validate: validateAppName,\n }),\n );\n }\n\n if (!projectName) {\n return yield* Effect.fail(new Error(\"Project name is required.\"));\n }\n\n const validationError = validateAppName(projectName);\n if (validationError) {\n return yield* Effect.fail(new Error(validationError));\n }\n\n let appType: AppType = flags.appType ?? \"browser\";\n if (!(flags.appType || nonInteractive)) {\n appType = yield* Effect.promise(() =>\n prompt.select({\n message: \"What kind of app do you want to build?\",\n options: [\n {\n value: \"browser\",\n label: \"Web App for Browsers\",\n hint: \"Uses Next.js and hosted deployment\",\n },\n {\n value: \"webviewer\",\n label: \"FileMaker Web Viewer\",\n hint: \"Uses Vite for FileMaker web viewers\",\n },\n ],\n }),\n ).pipe(Effect.map((value) => value as AppType));\n }\n\n const hasExplicitFileMakerInputs = Boolean(\n flags.server || flags.adminApiKey || flags.dataApiKey || flags.fileName || flags.layoutName || flags.schemaName,\n );\n\n let dataSource: DataSourceType = \"none\";\n if (flags.dataSource) {\n dataSource = flags.dataSource;\n } else if (appType === \"webviewer\") {\n dataSource = hasExplicitFileMakerInputs || !(nonInteractive && !flags.server) ? \"filemaker\" : \"none\";\n }\n\n if (!(nonInteractive || flags.dataSource) && appType !== \"webviewer\") {\n dataSource = yield* Effect.promise(() =>\n prompt.select({\n message: \"Do you want to connect to a FileMaker Database now?\",\n options: [\n {\n value: \"filemaker\",\n label: \"Yes\",\n hint: \"Set up env, datasource config, and typegen now\",\n },\n {\n value: \"none\",\n label: \"No\",\n hint: \"You can add a data source later\",\n },\n ],\n }),\n ).pipe(Effect.map((value) => value as DataSourceType));\n }\n\n if (nonInteractive && !flags.dataSource && hasExplicitFileMakerInputs) {\n return yield* Effect.fail(new Error(\"FileMaker flags require --data-source filemaker in non-interactive mode.\"));\n }\n\n if (nonInteractive && dataSource !== \"filemaker\" && hasExplicitFileMakerInputs) {\n return yield* Effect.fail(new Error(\"FileMaker flags require --data-source filemaker in non-interactive mode.\"));\n }\n\n const { fileMaker, skipFileMakerSetup } = yield* Effect.promise(() =>\n resolveFileMakerInputs({\n prompt,\n fileMakerService,\n flags: { ...flags, dataSource },\n appType,\n nonInteractive,\n }),\n );\n\n const [scopedAppName, appDir] = parseNameAndPath(projectName);\n\n return {\n projectName,\n scopedAppName,\n appDir,\n appType,\n ui: flags.ui ?? \"shadcn\",\n dataSource,\n packageManager: cliContext.packageManager,\n noInstall: flags.noInstall,\n noGit: flags.noGit,\n force: flags.force,\n cwd: cliContext.cwd,\n importAlias: flags.importAlias,\n nonInteractive,\n debug: cliContext.debug,\n fileMaker,\n skipFileMakerSetup,\n hasExplicitFileMakerInputs,\n } satisfies InitRequest;\n });\n","import open from \"open\";\n\nexport async function openBrowser(url: string): Promise<void> {\n try {\n await open(url);\n } catch {\n // Ignore open failures and let the user copy the URL manually.\n }\n}\n\nexport const openExternal: (url: string) => Promise<void> = openBrowser;\n","import https from \"node:https\";\nimport axios from \"axios\";\n\nfunction createHttpsAgent() {\n return new https.Agent({\n rejectUnauthorized: process.env.PROOFKIT_ALLOW_INSECURE_TLS !== \"1\",\n });\n}\n\nexport async function getJson<T>(url: string, options?: { headers?: Record<string, string>; timeout?: number }) {\n const response = await axios.get<T>(url, {\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeout ?? 10_000,\n validateStatus: null,\n });\n return response;\n}\n\nexport async function postJson<T>(\n url: string,\n data: unknown,\n options?: { headers?: Record<string, string>; timeout?: number },\n) {\n const response = await axios.post<T>(url, data, {\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeout ?? 10_000,\n validateStatus: null,\n });\n return response;\n}\n\nexport async function deleteJson(url: string, options?: { headers?: Record<string, string>; timeout?: number }) {\n const response = await axios.delete(url, {\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeout ?? 10_000,\n validateStatus: null,\n });\n return response;\n}\n\nexport async function requestJson<T>(\n url: string | URL,\n options?: {\n method?: \"GET\" | \"POST\" | \"DELETE\";\n headers?: Record<string, string>;\n body?: Record<string, unknown>;\n timeoutMs?: number;\n },\n) {\n const response = await axios.request<T>({\n url: url.toString(),\n method: options?.method ?? \"GET\",\n data: options?.body,\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeoutMs ?? 10_000,\n });\n return response;\n}\n\nexport async function requestText(\n url: string | URL,\n options?: {\n method?: \"GET\" | \"POST\" | \"DELETE\";\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n) {\n const response = await axios.request<string>({\n url: url.toString(),\n method: options?.method ?? \"GET\",\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeoutMs ?? 10_000,\n responseType: \"text\",\n validateStatus: null,\n });\n return {\n status: response.status,\n data: response.data,\n };\n}\n","export type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport function detectUserPackageManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent;\n\n if (userAgent) {\n if (userAgent.startsWith(\"yarn\")) {\n return \"yarn\";\n }\n if (userAgent.startsWith(\"pnpm\")) {\n return \"pnpm\";\n }\n if (userAgent.startsWith(\"bun\")) {\n return \"bun\";\n }\n return \"npm\";\n }\n\n return \"npm\";\n}\n","import {\n intro as clackIntro,\n isCancel as clackIsCancel,\n log as clackLog,\n note as clackNote,\n outro as clackOutro,\n spinner as clackSpinner,\n} from \"@clack/prompts\";\nimport {\n checkbox as inquirerCheckbox,\n confirm as inquirerConfirm,\n input as inquirerInput,\n password as inquirerPassword,\n search as inquirerSearch,\n select as inquirerSelect,\n} from \"@inquirer/prompts\";\n\nconst CANCEL_SYMBOL = Symbol.for(\"@proofkit/new/prompt-cancelled\");\n\nexport const intro = clackIntro;\nexport const log = clackLog;\nexport const note = clackNote;\nexport const outro = clackOutro;\nexport const spinner = clackSpinner;\n\nfunction isPromptCancel(error: unknown) {\n return error instanceof Error && error.name === \"ExitPromptError\";\n}\n\nfunction withCancelSentinel<T>(fn: () => Promise<T>): Promise<T | symbol> {\n return fn().catch((error: unknown) => {\n if (isPromptCancel(error)) {\n return CANCEL_SYMBOL;\n }\n throw error;\n });\n}\n\nexport function isCancel(value: unknown): value is symbol {\n return value === CANCEL_SYMBOL || clackIsCancel(value);\n}\n\nexport interface PromptOption<T extends string> {\n value: T;\n label: string;\n hint?: string;\n disabled?: boolean | string;\n}\n\nexport interface SearchPromptOption<T extends string> extends PromptOption<T> {\n keywords?: readonly string[];\n}\n\nfunction normalizeValidate(\n validate: ((value: string) => string | undefined) | undefined,\n): ((value: string) => string | boolean) | undefined {\n if (!validate) {\n return undefined;\n }\n\n return (value: string) => validate(value) ?? true;\n}\n\nfunction matchesSearch(option: SearchPromptOption<string>, query: string) {\n const haystack = [option.label, option.hint ?? \"\", ...(option.keywords ?? [])].join(\" \").toLowerCase();\n return haystack.includes(query.trim().toLowerCase());\n}\n\nfunction normalizeDisabledMessage(value: boolean | string | undefined) {\n if (typeof value === \"string\") {\n return value;\n }\n return value ? true : undefined;\n}\n\nexport function filterSearchOptions<T extends string>(\n options: readonly SearchPromptOption<T>[],\n query: string | undefined,\n) {\n const term = query?.trim();\n if (!term) {\n return options;\n }\n\n return options.filter((option) => matchesSearch(option, term));\n}\n\nexport function textPrompt(options: {\n message: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n}) {\n return withCancelSentinel(() =>\n inquirerInput({\n message: options.message,\n default: options.defaultValue,\n validate: normalizeValidate(options.validate),\n }),\n );\n}\n\nexport function passwordPrompt(options: { message: string; validate?: (value: string) => string | undefined }) {\n return withCancelSentinel(() =>\n inquirerPassword({\n message: options.message,\n validate: normalizeValidate(options.validate),\n }),\n );\n}\n\nexport function confirmPrompt(options: { message: string; initialValue?: boolean }) {\n return withCancelSentinel(() =>\n inquirerConfirm({\n message: options.message,\n default: options.initialValue,\n }),\n );\n}\n\nexport function selectPrompt<T extends string>(options: { message: string; options: PromptOption<T>[] }) {\n return withCancelSentinel(() =>\n inquirerSelect<T>({\n message: options.message,\n pageSize: 10,\n choices: options.options.map((option) => ({\n value: option.value,\n name: option.label,\n description: option.hint,\n disabled: normalizeDisabledMessage(option.disabled),\n })),\n }),\n );\n}\n\nexport function searchSelectPrompt<T extends string>(options: {\n message: string;\n emptyMessage?: string;\n options: SearchPromptOption<T>[];\n}) {\n return withCancelSentinel(() =>\n inquirerSearch<T>({\n message: options.message,\n pageSize: 10,\n source: (input) => {\n const filtered = filterSearchOptions(options.options, input);\n if (filtered.length === 0) {\n return [\n {\n value: \"__no_matches__\" as T,\n name: options.emptyMessage ?? \"No matches found. Keep typing to refine your search.\",\n disabled: options.emptyMessage ?? \"No matches found\",\n },\n ];\n }\n\n return filtered.map((option) => ({\n value: option.value,\n name: option.label,\n description: option.hint,\n disabled: normalizeDisabledMessage(option.disabled),\n }));\n },\n }),\n );\n}\n\nexport function multiSearchSelectPrompt<T extends string>(options: {\n message: string;\n options: SearchPromptOption<T>[];\n required?: boolean;\n}) {\n return withCancelSentinel(() =>\n inquirerCheckbox<T>({\n message: options.message,\n pageSize: 10,\n required: options.required,\n choices: options.options.map((option) => ({\n value: option.value,\n name: option.label,\n description: option.hint,\n disabled: normalizeDisabledMessage(option.disabled),\n })),\n }),\n );\n}\n","import { randomUUID } from \"node:crypto\";\nimport path from \"node:path\";\nimport { Effect, Layer } from \"effect\";\nimport { execa } from \"execa\";\nimport fs from \"fs-extra\";\nimport { TEMPLATE_ROOT } from \"~/consts.js\";\nimport {\n CliContext,\n type CliContextValue,\n CodegenService,\n ConsoleService,\n type FileMakerBootstrapArtifacts,\n FileMakerService,\n FileSystemService,\n GitService,\n type OttoApiKeyInfo,\n type OttoFileInfo,\n PackageManagerService,\n ProcessService,\n PromptService,\n SettingsService,\n TemplateService,\n} from \"~/core/context.js\";\nimport { UserAbortedError } from \"~/core/errors.js\";\nimport type { AppType, FileMakerInputs, ProofKitSettings, UIType } from \"~/core/types.js\";\nimport { openBrowser } from \"~/utils/browserOpen.js\";\nimport { deleteJson, getJson, postJson } from \"~/utils/http.js\";\nimport { detectUserPackageManager } from \"~/utils/packageManager.js\";\nimport { createDataSourceEnvNames, updateEnvSchemaFile, updateTypegenConfig } from \"~/utils/projectFiles.js\";\nimport {\n confirmPrompt,\n spinner as createSpinner,\n isCancel,\n log,\n multiSearchSelectPrompt,\n note,\n passwordPrompt,\n searchSelectPrompt,\n selectPrompt,\n textPrompt,\n} from \"~/utils/prompts.js\";\n\nfunction unwrap<T>(value: T | symbol): T {\n if (isCancel(value)) {\n throw new UserAbortedError();\n }\n return value as T;\n}\n\nfunction normalizeUrl(serverUrl: string) {\n if (serverUrl.startsWith(\"https://\")) {\n return serverUrl;\n }\n if (serverUrl.startsWith(\"http://\")) {\n return serverUrl.replace(\"http://\", \"https://\");\n }\n return `https://${serverUrl}`;\n}\n\ninterface LayoutFolder {\n isFolder?: boolean;\n name?: string;\n folderLayoutNames?: LayoutFolder[];\n}\n\nfunction transformLayoutList(layouts: LayoutFolder[]): string[] {\n const flatten = (layout: LayoutFolder): string[] => {\n if (layout.isFolder === true) {\n const folderLayouts = Array.isArray(layout.folderLayoutNames) ? layout.folderLayoutNames : [];\n return folderLayouts.flatMap((item) => flatten(item));\n }\n return typeof layout.name === \"string\" ? [layout.name] : [];\n };\n\n return layouts.flatMap(flatten).sort((left, right) => left.localeCompare(right));\n}\n\nconst promptService = {\n text: async (options: { message: string; defaultValue?: string; validate?: (value: string) => string | undefined }) =>\n unwrap(\n await textPrompt({\n message: options.message,\n defaultValue: options.defaultValue,\n validate: options.validate,\n }),\n ).toString(),\n password: async (options: { message: string; validate?: (value: string) => string | undefined }) =>\n unwrap(\n await passwordPrompt({\n message: options.message,\n validate: options.validate,\n }),\n ).toString(),\n select: async <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n }) =>\n unwrap(\n await selectPrompt({\n message: options.message,\n options: options.options,\n }),\n ) as T,\n searchSelect: async <T extends string>(options: {\n message: string;\n emptyMessage?: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n }) => unwrap(await searchSelectPrompt(options)) as T,\n multiSearchSelect: async <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n required?: boolean;\n }) => unwrap(await multiSearchSelectPrompt(options)),\n confirm: async (options: { message: string; initialValue?: boolean }) =>\n unwrap(\n await confirmPrompt({\n message: options.message,\n initialValue: options.initialValue,\n }),\n ) as boolean,\n};\n\nconst consoleService = {\n info: (message: string) => log.info(message),\n warn: (message: string) => log.warn(message),\n error: (message: string) => log.error(message),\n success: (message: string) => log.success(message),\n note: (message: string, title?: string) => note(message, title),\n};\n\nconst fileSystemService = {\n exists: async (targetPath: string) => fs.pathExists(targetPath),\n readdir: async (targetPath: string) => fs.readdir(targetPath),\n emptyDir: async (targetPath: string) => fs.emptyDir(targetPath),\n copyDir: async (from: string, to: string, options?: { overwrite?: boolean }) =>\n fs.copy(from, to, { overwrite: options?.overwrite ?? true }),\n rename: async (from: string, to: string) => fs.rename(from, to),\n remove: async (targetPath: string) => fs.remove(targetPath),\n readJson: async <T>(targetPath: string) => fs.readJson(targetPath) as Promise<T>,\n writeJson: async (targetPath: string, value: unknown) => fs.writeJson(targetPath, value, { spaces: 2 }),\n writeFile: async (targetPath: string, content: string) => fs.writeFile(targetPath, content, \"utf8\"),\n readFile: async (targetPath: string) => fs.readFile(targetPath, \"utf8\"),\n};\n\nconst templateService = {\n getTemplateDir: (appType: AppType, ui: UIType) => {\n if (appType === \"webviewer\") {\n return path.join(TEMPLATE_ROOT, \"vite-wv\");\n }\n if (ui === \"mantine\") {\n return path.join(TEMPLATE_ROOT, \"nextjs-mantine\");\n }\n return path.join(TEMPLATE_ROOT, \"nextjs-shadcn\");\n },\n};\n\nconst packageManagerService = {\n getVersion: async (packageManager: string, cwd: string) => {\n if (packageManager === \"bun\") {\n return undefined;\n }\n const { stdout } = await execa(packageManager, [\"-v\"], { cwd });\n return stdout.trim();\n },\n};\n\nconst processService = {\n run: async (\n command: string,\n args: string[],\n options: {\n cwd: string;\n stdout?: \"pipe\" | \"inherit\" | \"ignore\";\n stderr?: \"pipe\" | \"inherit\" | \"ignore\";\n },\n ) => {\n const result = await execa(command, args, {\n cwd: options.cwd,\n stdout: options.stdout ?? \"pipe\",\n stderr: options.stderr ?? \"pipe\",\n });\n return {\n stdout: result.stdout ?? \"\",\n stderr: result.stderr ?? \"\",\n };\n },\n};\n\nconst gitService = {\n initialize: async (projectDir: string) => {\n await execa(\"git\", [\"init\"], { cwd: projectDir });\n await execa(\"git\", [\"add\", \".\"], { cwd: projectDir });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], { cwd: projectDir });\n },\n};\n\nconst settingsService = {\n writeSettings: async (projectDir: string, settings: ProofKitSettings) =>\n fs.writeJson(path.join(projectDir, \"proofkit.json\"), settings, { spaces: 2 }),\n appendEnvVars: async (projectDir: string, vars: Record<string, string>) => {\n const envPath = path.join(projectDir, \".env\");\n const existing = (await fs.pathExists(envPath)) ? await fs.readFile(envPath, \"utf8\") : \"\";\n const additions = Object.entries(vars)\n .map(([name, value]) => `${name}=${value}`)\n .join(\"\\n\");\n const nextContent = [existing.trimEnd(), additions].filter(Boolean).join(\"\\n\").concat(\"\\n\");\n await fs.writeFile(envPath, nextContent, \"utf8\");\n },\n ensureTypegenConfig: async (_projectDir: string, _options: { appType: AppType; fileMaker?: FileMakerInputs }) =>\n undefined,\n};\n\nfunction createDataSourceEntry(dataSourceName: string) {\n return {\n type: \"fm\" as const,\n name: dataSourceName,\n envNames: createDataSourceEnvNames(dataSourceName),\n };\n}\n\nfunction createFileMakerBootstrapArtifacts(\n settings: ProofKitSettings,\n inputs: FileMakerInputs,\n appType: AppType,\n): Promise<FileMakerBootstrapArtifacts> {\n const dataSourceEntry = createDataSourceEntry(inputs.dataSourceName);\n const nextSettings: ProofKitSettings = {\n ...settings,\n dataSources: settings.dataSources.some((entry) => entry.name === dataSourceEntry.name)\n ? settings.dataSources\n : [...settings.dataSources, dataSourceEntry],\n };\n\n if (inputs.mode === \"local-fm-mcp\") {\n return Promise.resolve({\n settings: nextSettings,\n envVars: {},\n envSchemaEntries: [],\n typegenConfig: {\n mode: inputs.mode,\n dataSourceName: inputs.dataSourceName,\n fmMcpBaseUrl: inputs.fmMcpBaseUrl,\n connectedFileName: inputs.fileName,\n layoutName: inputs.layoutName,\n schemaName: inputs.schemaName,\n appType,\n },\n });\n }\n\n return Promise.resolve({\n settings: nextSettings,\n envVars: {\n [inputs.envNames.database]: inputs.fileName,\n [inputs.envNames.server]: inputs.server,\n [inputs.envNames.apiKey]: inputs.dataApiKey,\n },\n envSchemaEntries: [\n {\n name: inputs.envNames.database,\n zodSchema: 'z.string().endsWith(\".fmp12\")',\n defaultValue: inputs.fileName,\n },\n {\n name: inputs.envNames.server,\n zodSchema: \"z.string().url()\",\n defaultValue: inputs.server,\n },\n {\n name: inputs.envNames.apiKey,\n zodSchema: 'z.string().startsWith(\"dk_\")',\n defaultValue: inputs.dataApiKey,\n },\n ],\n typegenConfig: {\n mode: inputs.mode,\n dataSourceName: inputs.dataSourceName,\n envNames: inputs.envNames,\n layoutName: inputs.layoutName,\n schemaName: inputs.schemaName,\n appType,\n },\n });\n}\n\nconst fileMakerService = {\n detectLocalFmMcp: async (baseUrl = process.env.FM_MCP_BASE_URL ?? \"http://127.0.0.1:1365\") => {\n try {\n const health = await fetch(`${baseUrl}/health`, { signal: AbortSignal.timeout(3000) });\n if (!health.ok) {\n return { baseUrl, healthy: false, connectedFiles: [] };\n }\n const connectedFiles = await fetch(`${baseUrl}/connectedFiles`, { signal: AbortSignal.timeout(3000) })\n .then(async (response) => (response.ok ? ((await response.json()) as unknown) : []))\n .catch(() => []);\n return {\n baseUrl,\n healthy: true,\n connectedFiles: Array.isArray(connectedFiles)\n ? connectedFiles.filter((item): item is string => typeof item === \"string\")\n : [],\n };\n } catch {\n return { baseUrl, healthy: false, connectedFiles: [] };\n }\n },\n validateHostedServerUrl: async (serverUrl: string, ottoPort?: number | null) => {\n const normalizedUrl = normalizeUrl(serverUrl);\n const fmsUrl = new URL(\"/fmws/serverinfo\", normalizedUrl).toString();\n const fmsResponse = await getJson<{ data?: { ServerVersion?: string } }>(fmsUrl);\n const serverVersion = fmsResponse.data?.data?.ServerVersion?.split(\" \")[0];\n if (!serverVersion) {\n throw new Error(`Invalid FileMaker Server URL: ${normalizedUrl}`);\n }\n\n let ottoVersion: string | null = null;\n const otto4Response = await getJson<{ response?: { Otto?: { version?: string } } }>(\n new URL(\"/otto/api/info\", normalizedUrl).toString(),\n ).catch(() => undefined);\n ottoVersion = otto4Response?.data?.response?.Otto?.version ?? null;\n\n if (!ottoVersion) {\n const otto3Url = new URL(normalizedUrl);\n otto3Url.port = ottoPort ? String(ottoPort) : \"3030\";\n otto3Url.pathname = \"/api/otto/info\";\n const otto3Response = await getJson<{ Otto?: { version?: string } }>(otto3Url.toString()).catch(() => undefined);\n ottoVersion = otto3Response?.data?.Otto?.version ?? null;\n }\n\n return {\n normalizedUrl: new URL(normalizedUrl).origin,\n versions: {\n fmsVersion: serverVersion,\n ottoVersion,\n },\n };\n },\n getOttoFMSToken: async ({ url }: { url: URL }) => {\n const hash = randomUUID().replaceAll(\"-\", \"\").slice(0, 18);\n const loginUrl = new URL(`/otto/wizard/${hash}`, url.origin);\n log.info(`If the browser window didn't open automatically, use this Otto login URL:\\n${loginUrl.toString()}`);\n await openBrowser(loginUrl.toString());\n\n const spin = createSpinner();\n spin.start(\"Waiting for OttoFMS login\");\n\n const deadline = Date.now() + 180_000;\n while (Date.now() < deadline) {\n const response = await getJson<{ response?: { token?: string } }>(\n `${url.origin}/otto/api/cli/checkHash/${hash}`,\n { headers: { \"Accept-Encoding\": \"deflate\" }, timeout: 5000 },\n ).catch(() => undefined);\n const token = response?.data?.response?.token;\n if (token) {\n spin.stop(\"Login complete\");\n await deleteJson(`${url.origin}/otto/api/cli/checkHash/${hash}`, {\n headers: { \"Accept-Encoding\": \"deflate\" },\n }).catch(() => undefined);\n return { token };\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n\n spin.stop(\"Login timed out\");\n throw new Error(\"OttoFMS login timed out after 3 minutes.\");\n },\n listFiles: async ({ url, token }: { url: URL; token: string }) => {\n const response = await getJson<{ response?: { databases?: Array<{ filename?: string; status?: string }> } }>(\n `${url.origin}/otto/fmi/admin/api/v2/databases`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n );\n const databases = (response.data?.response?.databases ?? []) as Record<string, unknown>[];\n return databases\n .filter((database): database is { filename: string; status?: string } => typeof database.filename === \"string\")\n .map(\n (database) =>\n ({\n filename: database.filename,\n status: database.status ?? \"unknown\",\n }) satisfies OttoFileInfo,\n );\n },\n listAPIKeys: async ({ url, token }: { url: URL; token: string }) => {\n const response = await getJson<{ response?: { \"api-keys\"?: Record<string, unknown>[] } }>(\n `${url.origin}/otto/api/api-key`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n );\n const apiKeys = (response.data?.response?.[\"api-keys\"] ?? []) as Record<string, unknown>[];\n return apiKeys\n .filter(\n (apiKey): apiKey is { key: string; user: string; database: string; label: string } =>\n typeof apiKey.key === \"string\" &&\n typeof apiKey.user === \"string\" &&\n typeof apiKey.database === \"string\" &&\n typeof apiKey.label === \"string\",\n )\n .map(\n (apiKey) =>\n ({\n key: apiKey.key,\n user: apiKey.user,\n database: apiKey.database,\n label: apiKey.label,\n }) satisfies OttoApiKeyInfo,\n );\n },\n createDataAPIKeyWithCredentials: async ({\n url,\n filename,\n username,\n password: userPassword,\n }: {\n url: URL;\n filename: string;\n username: string;\n password: string;\n }) => {\n const response = await postJson<{ response?: { key?: string } }>(`${url.origin}/otto/api/api-key/create-only`, {\n database: filename,\n label: \"For FM Web App\",\n user: username,\n pass: userPassword,\n });\n const apiKey = response.data?.response?.key;\n if (!apiKey) {\n throw new Error(`Failed to create a Data API key for ${filename}.`);\n }\n return { apiKey };\n },\n startDeployment: async ({ payload, url, token }: { payload: unknown; url: URL; token: string }) =>\n postJson<{ response?: { subDeploymentIds?: number[] } }>(`${url.origin}/otto/api/deployment`, payload, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }),\n getDeploymentStatus: async ({ url, token, deploymentId }: { url: URL; token: string; deploymentId: number }) =>\n getJson<{ response?: { status?: string; running?: boolean } }>(\n `${url.origin}/otto/api/deployment/${deploymentId}`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n ),\n deployDemoFile: async ({ url, token, operation }: { url: URL; token: string; operation: \"install\" | \"replace\" }) => {\n const demoFileName = \"ProofKitDemo.fmp12\";\n const spin = createSpinner();\n spin.start(\"Deploying ProofKit Demo file\");\n\n const deploymentPayload = {\n scheduled: false,\n label: \"Install ProofKit Demo\",\n deployments: [\n {\n name: \"Install ProofKit Demo\",\n source: {\n type: \"url\",\n url: \"https://proofkit.dev/proofkit-demo/manifest.json\",\n },\n fileOperations: [\n {\n target: {\n fileName: demoFileName,\n },\n operation,\n source: {\n fileName: demoFileName,\n },\n location: {\n folder: \"default\",\n subFolder: \"\",\n },\n },\n ],\n concurrency: 1,\n options: {\n closeFilesAfterBuild: false,\n keepFilesClosedAfterComplete: false,\n transferContainerData: false,\n },\n },\n ],\n abortRemaining: false,\n };\n\n const deployment = await fileMakerService.startDeployment({\n payload: deploymentPayload,\n url,\n token,\n });\n\n const deploymentId = deployment.data?.response?.subDeploymentIds?.[0];\n if (!deploymentId) {\n spin.stop(\"Demo deployment failed\");\n throw new Error(\"No deployment ID was returned when deploying the demo file.\");\n }\n\n const deploymentDeadline = Date.now() + 300_000;\n let deploymentCompleted = false;\n while (Date.now() < deploymentDeadline) {\n await new Promise((resolve) => setTimeout(resolve, 2500));\n const status = await fileMakerService.getDeploymentStatus({\n url,\n token,\n deploymentId,\n });\n\n if (!status.data?.response?.running) {\n if (status.data?.response?.status !== \"complete\") {\n spin.stop(\"Demo deployment failed\");\n throw new Error(\"ProofKit Demo deployment did not complete successfully.\");\n }\n deploymentCompleted = true;\n break;\n }\n }\n\n if (!deploymentCompleted) {\n spin.stop(\"Demo deployment timed out\");\n throw new Error(\"ProofKit Demo deployment timed out after 5 minutes.\");\n }\n\n const apiKey = await fileMakerService.createDataAPIKeyWithCredentials({\n url,\n filename: demoFileName,\n username: \"admin\",\n password: \"admin\",\n });\n spin.stop(\"Demo file deployed\");\n return { apiKey: apiKey.apiKey, filename: demoFileName };\n },\n listLayouts: async ({ dataApiKey, fmFile, server }: { dataApiKey: string; fmFile: string; server: string }) => {\n const response = await getJson<{ response?: { layouts?: LayoutFolder[] } }>(\n `${server}/otto/fmi/data/vLatest/databases/${encodeURIComponent(fmFile)}/layouts`,\n {\n headers: {\n Authorization: `Bearer ${dataApiKey}`,\n },\n },\n );\n return transformLayoutList(response.data?.response?.layouts ?? []);\n },\n createFileMakerBootstrapArtifacts,\n bootstrap: async (projectDir: string, settings: ProofKitSettings, inputs: FileMakerInputs, appType: AppType) => {\n const artifacts = await createFileMakerBootstrapArtifacts(settings, inputs, appType);\n if (Object.keys(artifacts.envVars).length > 0) {\n await settingsService.appendEnvVars(projectDir, artifacts.envVars);\n await updateEnvSchemaFile(fileSystemService, projectDir, artifacts.envSchemaEntries);\n }\n\n await updateTypegenConfig(fileSystemService, projectDir, {\n appType: artifacts.typegenConfig.appType,\n dataSourceName: artifacts.typegenConfig.dataSourceName,\n envNames: artifacts.typegenConfig.envNames,\n fmMcpBaseUrl: artifacts.typegenConfig.fmMcpBaseUrl,\n connectedFileName: artifacts.typegenConfig.connectedFileName,\n layoutName: artifacts.typegenConfig.layoutName,\n schemaName: artifacts.typegenConfig.schemaName,\n });\n\n return artifacts.settings;\n },\n};\n\nconst codegenService = {\n runInitial: async (projectDir: string, packageManager: CliContextValue[\"packageManager\"]) => {\n let commandParts: string[];\n if (packageManager === \"npm\") {\n commandParts = [\"npm\", \"run\", \"typegen\"];\n } else if (packageManager === \"bun\") {\n commandParts = [\"bun\", \"run\", \"typegen\"];\n } else {\n commandParts = [packageManager, \"typegen\"];\n }\n const command = commandParts[0];\n if (!command) {\n throw new Error(\"Unable to resolve the codegen command\");\n }\n const args = commandParts.slice(1);\n await execa(command, args, { cwd: projectDir });\n },\n};\n\nexport function makeLiveLayer(options: { cwd: string; debug: boolean; nonInteractive: boolean }) {\n const cliContext: CliContextValue = {\n cwd: options.cwd,\n debug: options.debug,\n nonInteractive: options.nonInteractive,\n packageManager: detectUserPackageManager(),\n };\n\n const layer = Layer.mergeAll(\n Layer.succeed(CliContext, cliContext),\n Layer.succeed(PromptService, promptService),\n Layer.succeed(ConsoleService, consoleService),\n Layer.succeed(FileSystemService, fileSystemService),\n Layer.succeed(TemplateService, templateService),\n Layer.succeed(PackageManagerService, packageManagerService),\n Layer.succeed(ProcessService, processService),\n Layer.succeed(GitService, gitService),\n Layer.succeed(SettingsService, settingsService),\n Layer.succeed(FileMakerService, fileMakerService),\n Layer.succeed(CodegenService, codegenService),\n );\n\n return <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.provide(effect, layer);\n}\n","import gradient from \"gradient-string\";\nimport { getTitleText } from \"~/consts.js\";\nimport { detectUserPackageManager } from \"~/utils/packageManager.js\";\n\nconst proofTheme = {\n purple: \"#89216B\",\n lightPurple: \"#D15ABB\",\n orange: \"#FF595E\",\n};\n\nexport const proofGradient = gradient(Object.values(proofTheme));\nexport function renderTitle(version = \"0.0.0-private\") {\n const pkgManager = detectUserPackageManager();\n if (pkgManager === \"yarn\" || pkgManager === \"pnpm\") {\n console.log(\"\");\n }\n console.log(proofGradient.multiline(getTitleText(version)));\n}\n","#!/usr/bin/env node\nimport { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { optional as optionalArg, text as textArg, withDescription as withArgDescription } from \"@effect/cli/Args\";\nimport {\n make as makeCommand,\n run,\n withDescription as withCommandDescription,\n withSubcommands,\n} from \"@effect/cli/Command\";\nimport {\n boolean as booleanOption,\n choice as choiceOption,\n optional as optionalOption,\n text as textOption,\n withAlias,\n withDescription as withOptionDescription,\n} from \"@effect/cli/Options\";\nimport { isValidationError } from \"@effect/cli/ValidationError\";\nimport { layer as nodeContextLayer } from \"@effect/platform-node/NodeContext\";\nimport { Cause, Effect, Exit } from \"effect\";\nimport { getOrUndefined } from \"effect/Option\";\nimport { cliName } from \"~/consts.js\";\nimport {\n CliContext,\n ConsoleService,\n FileSystemService,\n PackageManagerService,\n TemplateService,\n} from \"~/core/context.js\";\nimport { executeInitPlan } from \"~/core/executeInitPlan.js\";\nimport { planInit } from \"~/core/planInit.js\";\nimport { resolveInitRequest } from \"~/core/resolveInitRequest.js\";\nimport type { CliFlags } from \"~/core/types.js\";\nimport { makeLiveLayer } from \"~/services/live.js\";\nimport { intro } from \"~/utils/prompts.js\";\nimport { proofGradient, renderTitle } from \"~/utils/renderTitle.js\";\n\nconst defaultCliFlags: CliFlags = {\n noGit: false,\n noInstall: false,\n force: false,\n default: false,\n CI: false,\n importAlias: \"~/\",\n};\n\nfunction getCliVersion() {\n try {\n const packageJsonUrl = new URL(\"../package.json\", import.meta.url);\n const packageJson = JSON.parse(readFileSync(fileURLToPath(packageJsonUrl), \"utf8\")) as { version?: string };\n return packageJson.version ?? \"0.0.0-private\";\n } catch {\n return \"0.0.0-private\";\n }\n}\n\nexport const runInit = (name?: string, rawFlags?: Partial<CliFlags>) =>\n Effect.gen(function* () {\n const templateService = yield* TemplateService;\n const packageManagerService = yield* PackageManagerService;\n const request = yield* resolveInitRequest(name, { ...defaultCliFlags, ...rawFlags });\n const templateDir = templateService.getTemplateDir(request.appType, request.ui);\n const packageManagerVersion = yield* Effect.promise(() =>\n packageManagerService.getVersion(request.packageManager, request.cwd),\n );\n const plan = planInit(request, { templateDir, packageManagerVersion });\n yield* executeInitPlan(plan);\n return { request, plan };\n });\n\nexport const runDefaultCommand = (rawFlags?: Partial<CliFlags>) =>\n Effect.gen(function* () {\n const cliContext = yield* CliContext;\n const fsService = yield* FileSystemService;\n const consoleService = yield* ConsoleService;\n const flags = { ...defaultCliFlags, ...rawFlags };\n\n if (cliContext.nonInteractive || flags.CI || flags.nonInteractive) {\n throw new Error(\n \"The default command is interactive-only in non-interactive mode. Run an explicit command such as `proofkit init <name> --non-interactive`.\",\n );\n }\n\n const settingsPath = path.join(cliContext.cwd, \"proofkit.json\");\n const hasProofKitProject = yield* Effect.promise(() => fsService.exists(settingsPath));\n\n if (hasProofKitProject) {\n intro(`Found ${proofGradient(\"ProofKit\")} project`);\n consoleService.note(\n [\n \"Project command routing is being migrated into the Effect CLI surface.\",\n \"Use an explicit command such as `proofkit add`, `proofkit remove`, `proofkit typegen`, `proofkit deploy`, or `proofkit upgrade`.\",\n ].join(\"\\n\"),\n \"Project commands\",\n );\n return;\n }\n\n intro(`No ${proofGradient(\"ProofKit\")} project found, running \\`init\\``);\n yield* runInit(undefined, {\n ...flags,\n default: true,\n });\n });\n\nconst initDirectoryArg = optionalArg(textArg({ name: \"dir\" })).pipe(\n withArgDescription(\"The project name or target directory\"),\n);\n\nfunction optionalTextOption(name: string, description: string) {\n return optionalOption(textOption(name).pipe(withOptionDescription(description)));\n}\n\nfunction optionalChoiceOption<Choices extends readonly string[]>(name: string, choices: Choices, description: string) {\n return optionalOption(choiceOption(name, choices).pipe(withOptionDescription(description)));\n}\n\nfunction legacyEffect<T>(runLegacy: () => Promise<T>, options?: { nonInteractive?: boolean; debug?: boolean }) {\n return makeLiveLayer({\n cwd: process.cwd(),\n debug: options?.debug === true,\n nonInteractive: options?.nonInteractive === true,\n })(Effect.promise(runLegacy));\n}\n\nfunction makeInitCommand() {\n return makeCommand(\n \"init\",\n {\n dir: initDirectoryArg,\n appType: optionalChoiceOption(\"app-type\", [\"browser\", \"webviewer\"] as const, \"The type of app to create\"),\n ui: optionalChoiceOption(\"ui\", [\"shadcn\", \"mantine\"] as const, \"The UI scaffold to create\"),\n server: optionalTextOption(\"server\", \"The URL of your FileMaker Server\"),\n adminApiKey: optionalTextOption(\"admin-api-key\", \"Admin API key for OttoFMS\"),\n fileName: optionalTextOption(\"file-name\", \"The name of the FileMaker file\"),\n layoutName: optionalTextOption(\"layout-name\", \"The FileMaker layout name to scaffold\"),\n schemaName: optionalTextOption(\"schema-name\", \"The generated schema name\"),\n dataApiKey: optionalTextOption(\"data-api-key\", \"The Otto Data API key to use\"),\n dataSource: optionalChoiceOption(\"data-source\", [\"filemaker\", \"none\"] as const, \"The data source to use\"),\n noGit: booleanOption(\"no-git\").pipe(withOptionDescription(\"Skip git initialization\")),\n noInstall: booleanOption(\"no-install\").pipe(withOptionDescription(\"Skip package installation\")),\n force: booleanOption(\"force\").pipe(\n withAlias(\"f\"),\n withOptionDescription(\"Force overwrite target directory when it already contains files\"),\n ),\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ dir, ...options }) => {\n const flags: CliFlags = {\n ...defaultCliFlags,\n appType: getOrUndefined(options.appType),\n ui: getOrUndefined(options.ui),\n server: getOrUndefined(options.server),\n adminApiKey: getOrUndefined(options.adminApiKey),\n fileName: getOrUndefined(options.fileName),\n layoutName: getOrUndefined(options.layoutName),\n schemaName: getOrUndefined(options.schemaName),\n dataApiKey: getOrUndefined(options.dataApiKey),\n dataSource: getOrUndefined(options.dataSource),\n noGit: options.noGit,\n noInstall: options.noInstall,\n force: options.force,\n CI: options.CI,\n nonInteractive: options.nonInteractive,\n debug: options.debug,\n };\n\n return makeLiveLayer({\n cwd: process.cwd(),\n debug: flags.debug === true,\n nonInteractive: Boolean(flags.CI || flags.nonInteractive),\n })(runInit(getOrUndefined(dir), flags));\n },\n ).pipe(withCommandDescription(\"Create a new project with ProofKit\"));\n}\n\nfunction makeAddCommand() {\n return makeCommand(\n \"add\",\n {\n name: optionalArg(textArg({ name: \"name\" })).pipe(withArgDescription(\"Component or registry item to add\")),\n target: optionalArg(textArg({ name: \"target\" })).pipe(withArgDescription(\"Optional add target\")),\n noInstall: booleanOption(\"no-install\").pipe(withOptionDescription(\"Skip package installation\")),\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ name, target, noInstall, CI, nonInteractive, debug }) =>\n legacyEffect(\n async () => {\n const [{ runAdd }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/add/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({\n noInstall,\n ci: CI,\n nonInteractive,\n debug,\n });\n state.baseCommand = \"add\";\n state.projectDir = process.cwd();\n await runAdd(getOrUndefined(name), { noInstall, target: getOrUndefined(target) });\n },\n { nonInteractive: CI || nonInteractive, debug },\n ),\n ).pipe(withCommandDescription(\"Add a new component to your project\"));\n}\n\nfunction makeRemoveCommand() {\n return makeCommand(\n \"remove\",\n {\n name: optionalArg(textArg({ name: \"name\" })).pipe(withArgDescription(\"Component type to remove\")),\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ name, CI, nonInteractive, debug }) =>\n legacyEffect(\n async () => {\n const [{ runRemove }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/remove/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({\n ci: CI,\n nonInteractive,\n debug,\n });\n state.baseCommand = \"remove\";\n state.projectDir = process.cwd();\n await runRemove(getOrUndefined(name));\n },\n { nonInteractive: CI || nonInteractive, debug },\n ),\n ).pipe(withCommandDescription(\"Remove a component from your project\"));\n}\n\nfunction makeTypegenCommand() {\n return makeCommand(\n \"typegen\",\n {\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ debug }) =>\n legacyEffect(\n async () => {\n const [{ runTypegen }, { state }] = await Promise.all([\n import(\"~/cli/typegen/index.js\"),\n import(\"~/state.js\"),\n ]);\n state.projectDir = process.cwd();\n await runTypegen({\n settings: (await import(\"~/utils/parseSettings.js\")).getSettings(),\n });\n },\n { debug },\n ),\n ).pipe(withCommandDescription(\"Generate types for your project\"));\n}\n\nfunction makeDeployCommand() {\n return makeCommand(\n \"deploy\",\n {\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ debug }) =>\n legacyEffect(\n async () => {\n const [{ runDeploy }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/deploy/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({ debug });\n state.baseCommand = \"deploy\";\n state.projectDir = process.cwd();\n await runDeploy();\n },\n { debug },\n ),\n ).pipe(withCommandDescription(\"Deploy your app\"));\n}\n\nfunction makeUpgradeCommand() {\n return makeCommand(\n \"upgrade\",\n {\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ CI, nonInteractive, debug }) =>\n legacyEffect(\n async () => {\n const [{ runUpgrade }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/update/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({ ci: CI, nonInteractive, debug });\n state.baseCommand = \"upgrade\";\n state.projectDir = process.cwd();\n await runUpgrade();\n },\n { nonInteractive: CI || nonInteractive, debug },\n ),\n ).pipe(withCommandDescription(\"Upgrade ProofKit components in your project\"));\n}\n\nconst rootCommand = makeCommand(\n cliName,\n {\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n (options) =>\n makeLiveLayer({\n cwd: process.cwd(),\n debug: options.debug === true,\n nonInteractive: Boolean(options.CI || options.nonInteractive),\n })(\n runDefaultCommand({\n ...defaultCliFlags,\n CI: options.CI,\n nonInteractive: options.nonInteractive,\n debug: options.debug,\n }),\n ),\n).pipe(\n withCommandDescription(\"Interactive CLI to scaffold and manage ProofKit projects\"),\n withSubcommands([\n makeInitCommand(),\n makeAddCommand(),\n makeRemoveCommand(),\n makeTypegenCommand(),\n makeDeployCommand(),\n makeUpgradeCommand(),\n ]),\n);\n\nexport const cli = run(rootCommand, {\n name: \"ProofKit\",\n version: getCliVersion(),\n});\n\nconst isMainModule = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);\n\nconst debugFlagNames = new Set([\"--debug\"]);\n\nfunction shouldShowDebugDetails(argv: readonly string[]) {\n return argv.some((arg) => debugFlagNames.has(arg));\n}\n\nfunction renderFailure(cause: Cause.Cause<unknown>, showDebugDetails: boolean) {\n const failure = getOrUndefined(Cause.failureOption(cause));\n\n if (!(failure && isValidationError(failure))) {\n const error = Cause.squash(cause);\n console.error(error instanceof Error ? error.message : String(error));\n }\n\n if (showDebugDetails) {\n console.error(`\\n[debug] ${Cause.pretty(cause)}`);\n }\n}\n\nasync function main(argv: readonly string[]) {\n const showDebugDetails = shouldShowDebugDetails(argv);\n const exit = await Effect.runPromiseExit(cli(argv).pipe(Effect.provide(nodeContextLayer)));\n\n if (Exit.isFailure(exit)) {\n renderFailure(exit.cause, showDebugDetails);\n process.exitCode = 1;\n }\n}\n\nif (isMainModule) {\n renderTitle(getCliVersion());\n main(process.argv).catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["parseJsonc","chalk","intro","clackIntro","log","clackLog","note","clackNote","spinner","clackSpinner","isCancel","clackIsCancel","inquirerInput","inquirerPassword","inquirerConfirm","inquirerSelect","inquirerSearch","inquirerCheckbox","isCancel","log","note","fs","createSpinner","optionalArg","textArg","withArgDescription","optionalOption","textOption","withOptionDescription","choiceOption","makeCommand","booleanOption","withCommandDescription","nodeContextLayer"],"sources":["../src/core/context.ts","../src/core/errors.ts","../src/utils/projectFiles.ts","../src/utils/versioning.ts","../src/core/planInit.ts","../src/core/executeInitPlan.ts","../src/utils/projectName.ts","../src/core/resolveInitRequest.ts","../src/utils/browserOpen.ts","../src/utils/http.ts","../src/utils/packageManager.ts","../src/utils/prompts.ts","../src/services/live.ts","../src/utils/renderTitle.ts","../src/index.ts"],"sourcesContent":["import { Context } from \"effect\";\nimport type { AppType, FileMakerEnvNames, FileMakerInputs, ProofKitSettings, UIType } from \"~/core/types.js\";\nimport type { PackageManager } from \"~/utils/packageManager.js\";\n\nexport interface CliContextValue {\n cwd: string;\n debug: boolean;\n nonInteractive: boolean;\n packageManager: PackageManager;\n resolvedProjectConfig?: {\n appType?: AppType;\n ui?: UIType;\n projectDir?: string;\n };\n}\n\nexport const CliContext = Context.GenericTag<CliContextValue>(\"@proofkit/cli/CliContext\");\n\nexport interface PromptService {\n readonly text: (options: {\n message: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n }) => Promise<string>;\n readonly password: (options: {\n message: string;\n validate?: (value: string) => string | undefined;\n }) => Promise<string>;\n readonly select: <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string; disabled?: boolean | string }>;\n }) => Promise<T>;\n readonly searchSelect: <T extends string>(options: {\n message: string;\n emptyMessage?: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n }) => Promise<T>;\n readonly multiSearchSelect: <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n required?: boolean;\n }) => Promise<T[]>;\n readonly confirm: (options: { message: string; initialValue?: boolean }) => Promise<boolean>;\n}\n\nexport const PromptService = Context.GenericTag<PromptService>(\"@proofkit/cli/PromptService\");\n\nexport interface ConsoleService {\n readonly info: (message: string) => void;\n readonly warn: (message: string) => void;\n readonly error: (message: string) => void;\n readonly success: (message: string) => void;\n readonly note: (message: string, title?: string) => void;\n}\n\nexport const ConsoleService = Context.GenericTag<ConsoleService>(\"@proofkit/cli/ConsoleService\");\n\nexport interface FileSystemService {\n readonly exists: (path: string) => Promise<boolean>;\n readonly readdir: (path: string) => Promise<string[]>;\n readonly emptyDir: (path: string) => Promise<void>;\n readonly copyDir: (from: string, to: string, options?: { overwrite?: boolean }) => Promise<void>;\n readonly rename: (from: string, to: string) => Promise<void>;\n readonly remove: (path: string) => Promise<void>;\n readonly readJson: <T>(path: string) => Promise<T>;\n readonly writeJson: (path: string, value: unknown) => Promise<void>;\n readonly writeFile: (path: string, content: string) => Promise<void>;\n readonly readFile: (path: string) => Promise<string>;\n}\n\nexport const FileSystemService = Context.GenericTag<FileSystemService>(\"@proofkit/cli/FileSystemService\");\n\nexport interface TemplateService {\n readonly getTemplateDir: (appType: AppType, ui: UIType) => string;\n}\n\nexport const TemplateService = Context.GenericTag<TemplateService>(\"@proofkit/cli/TemplateService\");\n\nexport interface PackageManagerService {\n readonly getVersion: (packageManager: PackageManager, cwd: string) => Promise<string | undefined>;\n}\n\nexport const PackageManagerService = Context.GenericTag<PackageManagerService>(\"@proofkit/cli/PackageManagerService\");\n\nexport interface ProcessService {\n readonly run: (\n command: string,\n args: string[],\n options: {\n cwd: string;\n stdout?: \"pipe\" | \"inherit\" | \"ignore\";\n stderr?: \"pipe\" | \"inherit\" | \"ignore\";\n },\n ) => Promise<{ stdout: string; stderr: string }>;\n}\n\nexport const ProcessService = Context.GenericTag<ProcessService>(\"@proofkit/cli/ProcessService\");\n\nexport interface GitService {\n readonly initialize: (projectDir: string) => Promise<void>;\n}\n\nexport const GitService = Context.GenericTag<GitService>(\"@proofkit/cli/GitService\");\n\nexport interface SettingsService {\n readonly writeSettings: (projectDir: string, settings: ProofKitSettings) => Promise<void>;\n readonly appendEnvVars: (projectDir: string, vars: Record<string, string>) => Promise<void>;\n readonly ensureTypegenConfig: (\n projectDir: string,\n options: { appType: AppType; fileMaker?: FileMakerInputs },\n ) => Promise<void>;\n}\n\nexport const SettingsService = Context.GenericTag<SettingsService>(\"@proofkit/cli/SettingsService\");\n\nexport interface FmMcpStatus {\n baseUrl: string;\n healthy: boolean;\n connectedFiles: string[];\n}\n\nexport interface FileMakerServerVersions {\n fmsVersion: string;\n ottoVersion: string | null;\n}\n\nexport interface OttoFileInfo {\n filename: string;\n status: string;\n}\n\nexport interface OttoApiKeyInfo {\n key: string;\n user: string;\n database: string;\n label: string;\n}\n\nexport interface FileMakerDataSourceEntry {\n type: \"fm\";\n name: string;\n envNames: FileMakerEnvNames;\n}\n\nexport interface FileMakerBootstrapArtifacts {\n settings: ProofKitSettings;\n envVars: Record<string, string>;\n envSchemaEntries: Array<{\n name: string;\n zodSchema: string;\n defaultValue: string;\n }>;\n typegenConfig: {\n mode: FileMakerInputs[\"mode\"];\n dataSourceName: string;\n envNames?: FileMakerEnvNames;\n fmMcpBaseUrl?: string;\n connectedFileName?: string;\n layoutName?: string;\n schemaName?: string;\n appType: AppType;\n };\n}\n\nexport interface FileMakerService {\n readonly detectLocalFmMcp: (baseUrl?: string) => Promise<FmMcpStatus>;\n readonly validateHostedServerUrl: (\n serverUrl: string,\n ottoPort?: number | null,\n ) => Promise<{\n normalizedUrl: string;\n versions: FileMakerServerVersions;\n }>;\n readonly getOttoFMSToken: (options: { url: URL }) => Promise<{ token: string }>;\n readonly listFiles: (options: { url: URL; token: string }) => Promise<OttoFileInfo[]>;\n readonly listAPIKeys: (options: { url: URL; token: string }) => Promise<OttoApiKeyInfo[]>;\n readonly createDataAPIKeyWithCredentials: (options: {\n url: URL;\n filename: string;\n username: string;\n password: string;\n }) => Promise<{ apiKey: string }>;\n readonly deployDemoFile: (options: {\n url: URL;\n token: string;\n operation: \"install\" | \"replace\";\n }) => Promise<{ apiKey: string; filename: string }>;\n readonly listLayouts: (options: { dataApiKey: string; fmFile: string; server: string }) => Promise<string[]>;\n readonly createFileMakerBootstrapArtifacts: (\n settings: ProofKitSettings,\n inputs: FileMakerInputs,\n appType: AppType,\n ) => Promise<FileMakerBootstrapArtifacts>;\n readonly bootstrap: (\n projectDir: string,\n settings: ProofKitSettings,\n inputs: FileMakerInputs,\n appType: AppType,\n ) => Promise<ProofKitSettings>;\n}\n\nexport const FileMakerService = Context.GenericTag<FileMakerService>(\"@proofkit/cli/FileMakerService\");\n\nexport interface CodegenService {\n readonly runInitial: (projectDir: string, packageManager: PackageManager) => Promise<void>;\n}\n\nexport const CodegenService = Context.GenericTag<CodegenService>(\"@proofkit/cli/CodegenService\");\n","export class UserAbortedError extends Error {\n constructor(message = \"User aborted the operation\") {\n super(message);\n this.name = \"UserAbortedError\";\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { applyEdits, modify, parse as parseJsonc } from \"jsonc-parser\";\nimport { PKG_ROOT } from \"~/consts.js\";\nimport type { FileMakerEnvNames } from \"~/core/types.js\";\nimport type { PackageManager } from \"~/utils/packageManager.js\";\n\nconst commonFileMakerLayoutPrefixes = [\"API_\", \"API \", \"dapi_\", \"dapi\"];\nconst TRAILING_SLASH_REGEX = /[^/]$/;\nconst textFileExtensions = new Set([\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".jsonc\",\n \".md\",\n \".css\",\n \".scss\",\n \".html\",\n \".mjs\",\n \".cjs\",\n]);\n\nexport function getDefaultSchemaName(layoutName: string) {\n let schemaName = layoutName.replace(/[-\\s]/g, \"_\");\n for (const prefix of commonFileMakerLayoutPrefixes) {\n if (schemaName.startsWith(prefix)) {\n schemaName = schemaName.replace(prefix, \"\");\n }\n }\n return schemaName;\n}\n\nexport function createDataSourceEnvNames(dataSourceName: string): FileMakerEnvNames {\n if (dataSourceName === \"filemaker\") {\n return {\n database: \"FM_DATABASE\",\n server: \"FM_SERVER\",\n apiKey: \"OTTO_API_KEY\",\n };\n }\n\n const upperName = dataSourceName.toUpperCase();\n return {\n database: `${upperName}_FM_DATABASE`,\n server: `${upperName}_FM_SERVER`,\n apiKey: `${upperName}_OTTO_API_KEY`,\n };\n}\n\nexport function formatPackageManagerCommand(packageManager: PackageManager, command: string) {\n return [\"npm\", \"bun\"].includes(packageManager) ? `${packageManager} run ${command}` : `${packageManager} ${command}`;\n}\n\nexport function getTemplatePackageCommand(packageManager: PackageManager) {\n if (packageManager === \"npm\") {\n return \"npm run\";\n }\n return packageManager;\n}\n\nexport function normalizeImportAlias(importAlias: string) {\n return importAlias.replace(/\\*/g, \"\").replace(TRAILING_SLASH_REGEX, \"$&/\");\n}\n\nexport async function replaceTextInFiles(\n fs: {\n readdir: (path: string) => Promise<string[]>;\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, content: string) => Promise<void>;\n },\n rootDir: string,\n searchValue: string,\n replaceValue: string,\n) {\n const entries = await fs.readdir(rootDir);\n for (const entry of entries) {\n const fullPath = path.join(rootDir, entry);\n const childEntries = await fs.readdir(fullPath).catch((error: unknown) => {\n const code =\n typeof error === \"object\" && error !== null && \"code\" in error && typeof error.code === \"string\"\n ? error.code\n : undefined;\n\n if (code === \"ENOTDIR\") {\n return undefined;\n }\n\n throw error;\n });\n if (childEntries) {\n await replaceTextInFiles(fs, fullPath, searchValue, replaceValue);\n continue;\n }\n\n const extension = path.extname(entry);\n if (!textFileExtensions.has(extension)) {\n continue;\n }\n\n const content = await fs.readFile(fullPath).catch(() => undefined);\n if (!content?.includes(searchValue)) {\n continue;\n }\n\n await fs.writeFile(fullPath, content.replaceAll(searchValue, replaceValue));\n }\n}\n\nexport async function updateEnvSchemaFile(\n fs: {\n exists: (path: string) => Promise<boolean>;\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, content: string) => Promise<void>;\n },\n projectDir: string,\n envEntries: Array<{ name: string; zodSchema: string }>,\n) {\n const envFilePath = path.join(projectDir, \"src/lib/env.ts\");\n if (!(await fs.exists(envFilePath))) {\n return;\n }\n\n let content = await fs.readFile(envFilePath);\n const marker = \" server: {\";\n const markerIndex = content.indexOf(marker);\n if (markerIndex === -1) {\n return;\n }\n\n const insertIndex = content.indexOf(\" },\", markerIndex);\n if (insertIndex === -1) {\n return;\n }\n\n const additions = envEntries\n .filter((entry) => !content.includes(`${entry.name}:`))\n .map((entry) => ` ${entry.name}: ${entry.zodSchema},`)\n .join(\"\\n\");\n\n if (!additions) {\n return;\n }\n\n content = `${content.slice(0, insertIndex)}${additions}\\n${content.slice(insertIndex)}`;\n await fs.writeFile(envFilePath, content);\n}\n\ninterface TypegenFileContent {\n $schema?: string;\n config: Record<string, unknown>[] | Record<string, unknown>;\n}\n\nexport async function updateTypegenConfig(\n fs: {\n exists: (path: string) => Promise<boolean>;\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, content: string) => Promise<void>;\n },\n projectDir: string,\n options: {\n appType: \"browser\" | \"webviewer\";\n dataSourceName: string;\n envNames?: FileMakerEnvNames;\n fmMcpBaseUrl?: string;\n connectedFileName?: string;\n layoutName?: string;\n schemaName?: string;\n },\n) {\n const configPath = path.join(projectDir, \"proofkit-typegen.config.jsonc\");\n const dsPath = `./src/config/schemas/${options.dataSourceName}`;\n const nextDataSource: Record<string, unknown> = {\n type: \"fmdapi\",\n layouts: [],\n path: dsPath,\n clearOldFiles: true,\n clientSuffix: \"Layout\",\n };\n\n if (options.envNames) {\n nextDataSource.envNames = {\n server: options.envNames.server,\n db: options.envNames.database,\n auth: { apiKey: options.envNames.apiKey },\n };\n }\n\n if (options.appType === \"webviewer\") {\n nextDataSource.webviewerScriptName = \"ExecuteDataApi\";\n }\n\n if (options.fmMcpBaseUrl) {\n nextDataSource.fmMcp = {\n enabled: true,\n baseUrl: options.fmMcpBaseUrl,\n ...(options.connectedFileName ? { connectedFileName: options.connectedFileName } : {}),\n };\n }\n\n const layout =\n options.layoutName && options.schemaName\n ? {\n layoutName: options.layoutName,\n schemaName: options.schemaName,\n valueLists: \"allowEmpty\",\n }\n : undefined;\n\n if (layout) {\n nextDataSource.layouts = [layout];\n }\n\n if (!(await fs.exists(configPath))) {\n const nextContent: TypegenFileContent = {\n $schema: \"https://proofkit.dev/typegen-config-schema.json\",\n config: [nextDataSource],\n };\n await fs.writeFile(configPath, `${JSON.stringify(nextContent, null, 2)}\\n`);\n return;\n }\n\n const original = await fs.readFile(configPath);\n const parsed = parseJsonc(original) as TypegenFileContent;\n const configArray = Array.isArray(parsed.config) ? parsed.config : [parsed.config];\n const existingIndex = configArray.findIndex((entry) => entry.path === dsPath);\n\n if (existingIndex === -1) {\n configArray.push(nextDataSource);\n } else {\n const existing = (configArray[existingIndex] ?? {}) as Record<string, unknown>;\n const existingLayouts = Array.isArray(existing.layouts) ? existing.layouts : [];\n let nextLayouts = existingLayouts;\n if (layout && !existingLayouts.some((item) => item?.layoutName === layout.layoutName)) {\n nextLayouts = [...existingLayouts, layout];\n }\n configArray[existingIndex] = {\n ...existing,\n ...nextDataSource,\n layouts: nextLayouts,\n };\n }\n\n const nextConfig = Array.isArray(parsed.config) ? configArray : (configArray[0] ?? nextDataSource);\n const edits = modify(original, [\"config\"], nextConfig, {\n formattingOptions: {\n insertSpaces: true,\n tabSize: 2,\n eol: \"\\n\",\n },\n });\n await fs.writeFile(configPath, applyEdits(original, edits));\n}\n\nexport function getScaffoldVersion() {\n const candidates = [path.resolve(PKG_ROOT, \"package.json\"), path.resolve(PKG_ROOT, \"../cli/package.json\")];\n\n for (const candidate of candidates) {\n try {\n const packageJson = JSON.parse(readFileSync(candidate, \"utf8\")) as { version?: string };\n if (packageJson.version && packageJson.version !== \"0.0.0-private\") {\n return packageJson.version;\n }\n } catch {\n // ignore and continue searching\n }\n }\n\n return \"0.0.0-private\";\n}\n","export function getProofkitReleaseTag() {\n return \"beta\";\n}\n\nexport function getNodeMajorVersion() {\n return process.versions.node.split(\".\")[0] ?? \"22\";\n}\n","import path from \"node:path\";\nimport type { PackageJson } from \"type-fest\";\n\nimport type { InitPlan, InitRequest, ProofKitSettings } from \"~/core/types.js\";\nimport { formatPackageManagerCommand, getScaffoldVersion, getTemplatePackageCommand } from \"~/utils/projectFiles.js\";\nimport { getNodeMajorVersion, getProofkitReleaseTag } from \"~/utils/versioning.js\";\n\nfunction createDefaultSettings(request: InitRequest): ProofKitSettings {\n return {\n ui: request.ui,\n appType: request.appType,\n envFile: \".env\",\n dataSources: [],\n replacedMainPage: false,\n registryTemplates: [],\n };\n}\n\nfunction createEnvFileContent() {\n return [\"# When adding additional environment variables, update the schema alongside this file.\", \"\"].join(\"\\n\");\n}\n\nconst sharedUiDependencies = {\n \"@radix-ui/react-slot\": \"^1.2.3\",\n \"class-variance-authority\": \"^0.7.1\",\n clsx: \"^2.1.1\",\n \"lucide-react\": \"^0.577.0\",\n \"tailwind-merge\": \"^3.5.0\",\n tailwindcss: \"^4.1.10\",\n \"tw-animate-css\": \"^1.4.0\",\n} satisfies Record<string, string>;\n\nexport function planInit(\n request: InitRequest,\n options: { templateDir: string; packageManagerVersion?: string },\n): InitPlan {\n const targetDir = path.resolve(request.cwd, request.appDir);\n const releaseTag = getProofkitReleaseTag();\n const settings = createDefaultSettings(request);\n const packageManagerCommand = getTemplatePackageCommand(request.packageManager);\n\n const packageJson: InitPlan[\"packageJson\"] = {\n name: request.scopedAppName,\n packageManager: options.packageManagerVersion\n ? `${request.packageManager}@${options.packageManagerVersion}`\n : undefined,\n proofkitMetadata: {\n initVersion: getScaffoldVersion(),\n scaffoldPackage: \"@proofkit/cli\",\n },\n dependencies: {},\n devDependencies: {\n \"@proofkit/cli\": releaseTag,\n \"@types/node\": `^${getNodeMajorVersion()}`,\n },\n };\n\n if (request.appType === \"browser\") {\n Object.assign(packageJson.dependencies, sharedUiDependencies);\n packageJson.dependencies[\"@tailwindcss/postcss\"] = \"^4.1.10\";\n packageJson.dependencies[\"next-themes\"] = \"^0.4.6\";\n }\n\n if (request.appType === \"webviewer\") {\n Object.assign(packageJson.dependencies, sharedUiDependencies);\n packageJson.dependencies[\"@proofkit/fmdapi\"] = releaseTag;\n packageJson.dependencies[\"@proofkit/webviewer\"] = releaseTag;\n packageJson.dependencies[\"@tanstack/react-query\"] = \"^5.90.21\";\n packageJson.dependencies[\"@tanstack/react-router\"] = \"^1.167.4\";\n packageJson.dependencies.zod = \"^4\";\n packageJson.devDependencies[\"@proofkit/typegen\"] = releaseTag;\n packageJson.devDependencies[\"@tailwindcss/vite\"] = \"^4.2.1\";\n packageJson.devDependencies.ultracite = \"7.0.8\";\n }\n\n return {\n request,\n targetDir,\n templateDir: options.templateDir,\n packageManagerCommand,\n packageJson,\n settings,\n envFile: {\n path: path.join(targetDir, \".env\"),\n content: createEnvFileContent(),\n },\n writes: [],\n commands: [\n ...(request.noInstall ? [] : [{ type: \"install\" as const }]),\n ...(request.dataSource === \"filemaker\" &&\n !request.skipFileMakerSetup &&\n !(request.appType === \"webviewer\" && request.nonInteractive && !request.hasExplicitFileMakerInputs)\n ? [{ type: \"codegen\" as const }]\n : []),\n ...(request.noGit ? [] : [{ type: \"git-init\" as const }]),\n ],\n tasks: {\n bootstrapFileMaker: request.dataSource === \"filemaker\" && !request.skipFileMakerSetup,\n checkWebViewerAddon: request.appType === \"webviewer\",\n runInstall: !request.noInstall,\n runInitialCodegen:\n request.dataSource === \"filemaker\" &&\n !request.skipFileMakerSetup &&\n !(request.appType === \"webviewer\" && request.nonInteractive && !request.hasExplicitFileMakerInputs),\n initializeGit: !request.noGit,\n },\n nextSteps: [\n `cd ${request.appDir}`,\n ...(request.noInstall ? [request.packageManager === \"yarn\" ? \"yarn\" : `${request.packageManager} install`] : []),\n \"npx @tanstack/intent@latest install\",\n formatPackageManagerCommand(request.packageManager, \"dev\"),\n ...(request.appType === \"webviewer\"\n ? [\n formatPackageManagerCommand(request.packageManager, \"typegen\"),\n formatPackageManagerCommand(request.packageManager, \"launch-fm\"),\n ]\n : []),\n formatPackageManagerCommand(request.packageManager, \"proofkit\"),\n ],\n };\n}\n\nexport function applyPackageJsonMutations(\n packageJson: PackageJson,\n mutations: InitPlan[\"packageJson\"],\n overwriteDependencies = true,\n) {\n packageJson.name = mutations.name;\n packageJson.proofkitMetadata = mutations.proofkitMetadata as PackageJson[\"proofkitMetadata\"];\n if (mutations.packageManager) {\n packageJson.packageManager = mutations.packageManager;\n }\n\n if (!packageJson.dependencies) {\n packageJson.dependencies = {};\n }\n if (!packageJson.devDependencies) {\n packageJson.devDependencies = {};\n }\n\n const merge = (target: Record<string, string>, source: Record<string, string>) => {\n for (const [name, version] of Object.entries(source)) {\n if (overwriteDependencies || !(name in target)) {\n target[name] = version;\n }\n }\n };\n\n merge(packageJson.dependencies as Record<string, string>, mutations.dependencies);\n merge(packageJson.devDependencies as Record<string, string>, mutations.devDependencies);\n\n return packageJson;\n}\n","import path from \"node:path\";\nimport { Chalk } from \"chalk\";\nimport { Effect } from \"effect\";\nimport sortPackageJson from \"sort-package-json\";\n\nimport { AGENT_INSTRUCTIONS } from \"~/consts.js\";\nimport {\n CliContext,\n CodegenService,\n ConsoleService,\n FileMakerService,\n FileSystemService,\n GitService,\n PackageManagerService,\n ProcessService,\n PromptService,\n SettingsService,\n} from \"~/core/context.js\";\nimport { UserAbortedError } from \"~/core/errors.js\";\nimport { applyPackageJsonMutations } from \"~/core/planInit.js\";\nimport type { InitPlan } from \"~/core/types.js\";\nimport { normalizeImportAlias, replaceTextInFiles } from \"~/utils/projectFiles.js\";\n\nconst AGENT_METADATA_DIRS = new Set([\".agents\", \".claude\", \".clawed\", \".clinerules\", \".cursor\", \".windsurf\"]);\nconst IMPORT_ALIAS_WILDCARD_REGEX = /\\*/g;\nconst IMPORT_ALIAS_TRAILING_SLASH_REGEX = /\\/?$/;\nconst chalk = new Chalk({ level: 1 });\n\nconst formatCommand = (command: string) => chalk.cyan(command);\nconst formatHeading = (heading: string) => chalk.bold(heading);\nconst formatPath = (value: string) => chalk.yellow(value);\n\nfunction renderNextSteps(plan: InitPlan, additionalSteps: string[] = []) {\n const lines = [\n `${formatHeading(\"Project root:\")} ${formatCommand(`cd ${formatPath(plan.request.appDir)}`)}`,\n \"\",\n formatHeading(\"Agent setup:\"),\n \"Have your agent run this in the new project and complete the interactive prompt so it can load the right skills:\",\n ` ${formatCommand(\"npx @tanstack/intent@latest install\")}`,\n ];\n\n if (plan.request.noInstall) {\n lines.push(\n \"\",\n formatHeading(\"Install dependencies:\"),\n ` ${formatCommand(plan.request.packageManager === \"yarn\" ? \"yarn\" : `${plan.request.packageManager} install`)}`,\n );\n }\n\n lines.push(\"\", formatHeading(\"Start the app:\"), ` ${formatCommand(`${plan.packageManagerCommand} dev`)}`);\n\n if (plan.request.appType === \"webviewer\") {\n lines.push(\n \"\",\n formatHeading(\"When your FileMaker file is ready:\"),\n ` ${formatCommand(`${plan.packageManagerCommand} typegen`)}`,\n ` ${formatCommand(`${plan.packageManagerCommand} launch-fm`)}`,\n );\n\n if (additionalSteps.length > 0) {\n lines.push(...additionalSteps.map((step) => ` ${formatCommand(step)}`));\n }\n }\n\n lines.push(\n \"\",\n formatHeading(\"More ProofKit commands:\"),\n ` ${formatCommand(`${plan.packageManagerCommand} proofkit`)}`,\n );\n\n return lines.join(\"\\n\");\n}\n\nfunction getMeaningfulDirectoryEntries(entries: string[]) {\n return entries.filter((entry) => {\n if (AGENT_METADATA_DIRS.has(entry)) {\n return false;\n }\n if (entry === \".gitignore\") {\n return true;\n }\n if (entry.startsWith(\".\")) {\n return false;\n }\n return true;\n });\n}\n\nexport const prepareDirectory = (plan: InitPlan) =>\n Effect.gen(function* () {\n const fs = yield* FileSystemService;\n const consoleService = yield* ConsoleService;\n const cliContext = yield* CliContext;\n const prompts = yield* PromptService;\n\n const exists = yield* Effect.promise(() => fs.exists(plan.targetDir));\n if (!exists) {\n return;\n }\n\n const entries = yield* Effect.promise(() => fs.readdir(plan.targetDir));\n const meaningfulEntries = getMeaningfulDirectoryEntries(entries);\n if (meaningfulEntries.length === 0) {\n return;\n }\n\n if (plan.request.force) {\n yield* Effect.promise(() => fs.emptyDir(plan.targetDir));\n return;\n }\n\n if (cliContext.nonInteractive) {\n throw new Error(\n `${plan.request.appDir} already exists and isn't empty. Remove the existing files or choose a different directory.`,\n );\n }\n\n const overwriteMode = yield* Effect.promise(() =>\n prompts.select({\n message: `${plan.request.appDir} already exists and isn't empty. How would you like to proceed?`,\n options: [\n { value: \"abort\", label: \"Abort installation\" },\n { value: \"clear\", label: \"Clear the directory and continue\" },\n { value: \"overwrite\", label: \"Continue and overwrite conflicting files\" },\n ],\n }),\n );\n\n if (overwriteMode === \"abort\") {\n throw new UserAbortedError();\n }\n\n if (overwriteMode === \"clear\") {\n const confirmed = yield* Effect.promise(() =>\n prompts.confirm({\n message: \"Are you sure you want to clear the directory?\",\n initialValue: false,\n }),\n );\n if (!confirmed) {\n throw new UserAbortedError();\n }\n yield* Effect.promise(() => fs.emptyDir(plan.targetDir));\n return;\n }\n\n consoleService.warn(`Continuing in ${plan.request.appDir} and overwriting conflicting files when needed.`);\n });\n\nexport const executeInitPlan = (plan: InitPlan) =>\n Effect.gen(function* () {\n const cliContext = yield* CliContext;\n const fs = yield* FileSystemService;\n const consoleService = yield* ConsoleService;\n const settingsService = yield* SettingsService;\n const fileMakerService = yield* FileMakerService;\n const processService = yield* ProcessService;\n const gitService = yield* GitService;\n const codegenService = yield* CodegenService;\n const packageManagerService = yield* PackageManagerService;\n const additionalNextSteps: string[] = [];\n\n yield* prepareDirectory(plan);\n\n consoleService.info(`Scaffolding in ${plan.targetDir}`);\n yield* Effect.promise(() => fs.copyDir(plan.templateDir, plan.targetDir, { overwrite: true }));\n\n const stagedGitignore = path.join(plan.targetDir, \"_gitignore\");\n const finalGitignore = path.join(plan.targetDir, \".gitignore\");\n if (yield* Effect.promise(() => fs.exists(stagedGitignore))) {\n if (yield* Effect.promise(() => fs.exists(finalGitignore))) {\n yield* Effect.promise(() => fs.remove(stagedGitignore));\n } else {\n yield* Effect.promise(() => fs.rename(stagedGitignore, finalGitignore));\n }\n }\n\n const packageJsonPath = path.join(plan.targetDir, \"package.json\");\n const packageJson = yield* Effect.promise(() => fs.readJson<Record<string, unknown>>(packageJsonPath));\n const updatedPackageJson = sortPackageJson(\n applyPackageJsonMutations(packageJson as never, plan.packageJson) as never,\n );\n yield* Effect.promise(() => fs.writeJson(packageJsonPath, updatedPackageJson));\n\n yield* Effect.promise(() => settingsService.writeSettings(plan.targetDir, plan.settings));\n yield* Effect.promise(() => fs.writeFile(plan.envFile.path, plan.envFile.content));\n for (const write of plan.writes) {\n yield* Effect.promise(() => fs.writeFile(write.path, write.content));\n }\n\n yield* Effect.promise(() => replaceTextInFiles(fs, plan.targetDir, \"__PNPM_COMMAND__\", plan.packageManagerCommand));\n yield* Effect.promise(() =>\n replaceTextInFiles(fs, plan.targetDir, \"__PACKAGE_MANAGER__\", plan.request.packageManager),\n );\n yield* Effect.promise(() => replaceTextInFiles(fs, plan.targetDir, \"__AGENT_INSTRUCTIONS__\", AGENT_INSTRUCTIONS));\n if (plan.request.importAlias !== \"~/\") {\n yield* Effect.promise(() =>\n replaceTextInFiles(fs, plan.targetDir, \"~/\", normalizeImportAlias(plan.request.importAlias)),\n );\n yield* Effect.promise(() =>\n replaceTextInFiles(\n fs,\n plan.targetDir,\n \"@/\",\n plan.request.importAlias\n .replace(IMPORT_ALIAS_WILDCARD_REGEX, \"\")\n .replace(IMPORT_ALIAS_TRAILING_SLASH_REGEX, \"/\"),\n ),\n );\n }\n\n let nextSettings = plan.settings;\n if (plan.tasks.bootstrapFileMaker && plan.request.fileMaker) {\n const fileMakerInputs = plan.request.fileMaker;\n nextSettings = yield* Effect.promise(() =>\n fileMakerService.bootstrap(plan.targetDir, nextSettings, fileMakerInputs, plan.request.appType),\n );\n yield* Effect.promise(() => settingsService.writeSettings(plan.targetDir, nextSettings));\n }\n\n if (plan.tasks.checkWebViewerAddon) {\n yield* Effect.promise(async () => {\n try {\n const { checkForWebViewerLayouts, getWebViewerAddonMessages } = await import(\n \"~/installers/proofkit-webviewer.js\"\n );\n const status = await checkForWebViewerLayouts(plan.targetDir);\n const messages = getWebViewerAddonMessages(status);\n\n for (const message of messages.warn) {\n consoleService.warn(message);\n }\n for (const message of messages.info) {\n consoleService.info(message);\n }\n if (cliContext.nonInteractive) {\n additionalNextSteps.push(...messages.nextSteps);\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n consoleService.warn(`Could not inspect the ProofKit WebViewer add-on (${message}).`);\n }\n });\n }\n\n if (plan.tasks.runInstall) {\n let installArgs: string[] = [\"install\"];\n if (plan.request.packageManager === \"yarn\") {\n installArgs = [];\n }\n yield* Effect.promise(() =>\n processService.run(plan.request.packageManager, installArgs, {\n cwd: plan.targetDir,\n stdout: \"pipe\",\n stderr: \"pipe\",\n }),\n );\n }\n\n if (plan.tasks.runInitialCodegen) {\n yield* Effect.promise(() => codegenService.runInitial(plan.targetDir, plan.request.packageManager));\n }\n\n if (plan.tasks.initializeGit) {\n yield* Effect.promise(() => gitService.initialize(plan.targetDir));\n }\n\n const packageManagerVersion = yield* Effect.promise(() =>\n packageManagerService.getVersion(plan.request.packageManager, plan.targetDir),\n );\n\n consoleService.success(\n `Created ${plan.request.scopedAppName} in ${plan.targetDir}${\n packageManagerVersion ? ` using ${plan.request.packageManager}@${packageManagerVersion}` : \"\"\n }`,\n );\n consoleService.info(chalk.bold(\"Next steps:\"));\n consoleService.info(renderNextSteps(plan, Array.from(new Set(additionalNextSteps))));\n return plan;\n });\n","import path from \"node:path\";\n\nconst TRAILING_SLASHES_REGEX = /\\/+$/;\nconst PATH_SEPARATOR_REGEX = /\\\\/g;\nconst VALID_APP_NAME_REGEX = /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n\nfunction normalizeProjectName(value: string) {\n return value.replace(PATH_SEPARATOR_REGEX, \"/\");\n}\n\nfunction trimTrailingSlashes(value: string) {\n return normalizeProjectName(value).replace(TRAILING_SLASHES_REGEX, \"\");\n}\n\nexport function parseNameAndPath(projectName: string): [scopedAppName: string, appDir: string] {\n const normalized = trimTrailingSlashes(projectName);\n const segments = normalized.split(\"/\");\n let scopedAppName = segments.at(-1) ?? \"\";\n\n if (scopedAppName === \".\") {\n scopedAppName = path.basename(path.resolve(process.cwd()));\n }\n\n const scopeIndex = segments.findIndex((segment) => segment.startsWith(\"@\"));\n if (scopeIndex !== -1) {\n scopedAppName = segments.slice(scopeIndex).join(\"/\");\n }\n\n const appDir = segments.filter((segment) => !segment.startsWith(\"@\")).join(\"/\");\n\n return [scopedAppName, appDir];\n}\n\nexport function validateAppName(projectName: string) {\n const normalized = trimTrailingSlashes(projectName);\n if (normalized === \".\") {\n const currentDirName = path.basename(path.resolve(process.cwd()));\n return VALID_APP_NAME_REGEX.test(currentDirName)\n ? undefined\n : \"Name must consist of only lowercase alphanumeric characters, '-', and '_'\";\n }\n\n const segments = normalized.split(\"/\");\n const scopeIndex = segments.findIndex((segment) => segment.startsWith(\"@\"));\n let scopedAppName = segments.at(-1);\n\n if (scopeIndex !== -1) {\n scopedAppName = segments.slice(scopeIndex).join(\"/\");\n }\n\n if (VALID_APP_NAME_REGEX.test(scopedAppName ?? \"\")) {\n return;\n }\n\n return \"Name must consist of only lowercase alphanumeric characters, '-', and '_'\";\n}\n","import { Effect } from \"effect\";\n\nimport { DEFAULT_APP_NAME } from \"~/consts.js\";\nimport { CliContext, FileMakerService, PromptService } from \"~/core/context.js\";\nimport type { AppType, CliFlags, DataSourceType, FileMakerInputs, InitRequest } from \"~/core/types.js\";\nimport { createDataSourceEnvNames, getDefaultSchemaName } from \"~/utils/projectFiles.js\";\nimport { parseNameAndPath, validateAppName } from \"~/utils/projectName.js\";\n\nconst defaultFlags: CliFlags = {\n noGit: false,\n noInstall: false,\n force: false,\n default: false,\n CI: false,\n importAlias: \"~/\",\n};\n\nfunction compareSemver(left: string, right: string) {\n const leftParts = left.split(\".\").map((part) => Number.parseInt(part, 10) || 0);\n const rightParts = right.split(\".\").map((part) => Number.parseInt(part, 10) || 0);\n\n for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index += 1) {\n const leftValue = leftParts[index] ?? 0;\n const rightValue = rightParts[index] ?? 0;\n if (leftValue > rightValue) {\n return 1;\n }\n if (leftValue < rightValue) {\n return -1;\n }\n }\n\n return 0;\n}\n\nfunction validateLayoutInputs(flags: CliFlags) {\n const hasLayoutName = Boolean(flags.layoutName);\n const hasSchemaName = Boolean(flags.schemaName);\n\n if (hasLayoutName !== hasSchemaName) {\n throw new Error(\"Both --layout-name and --schema-name must be provided together.\");\n }\n}\n\nasync function resolveHostedFileMakerInputs({\n prompt,\n fileMakerService,\n flags,\n nonInteractive,\n}: {\n prompt: PromptService;\n fileMakerService: FileMakerService;\n flags: CliFlags;\n nonInteractive: boolean;\n}): Promise<FileMakerInputs> {\n validateLayoutInputs(flags);\n\n if (!flags.server && nonInteractive) {\n throw new Error(\n \"Missing required hosted FileMaker inputs in non-interactive mode: --server, --file-name, and --data-api-key.\",\n );\n }\n\n const rawServer =\n flags.server ??\n (await prompt.text({\n message: \"What is the URL of your FileMaker Server?\",\n validate: (value) => {\n try {\n const normalized = value.startsWith(\"http\") ? value : `https://${value}`;\n new URL(normalized);\n return;\n } catch {\n return \"Please enter a valid URL\";\n }\n },\n }));\n\n const { normalizedUrl, versions } = await fileMakerService.validateHostedServerUrl(rawServer);\n const hostedUrl = new URL(normalizedUrl);\n const demoFileName = \"ProofKitDemo.fmp12\";\n\n let selectedFile = flags.fileName;\n let dataApiKey = flags.dataApiKey;\n let layoutName = flags.layoutName;\n let schemaName = flags.schemaName;\n let token: string | undefined;\n let files: Awaited<ReturnType<FileMakerService[\"listFiles\"]>> = [];\n const requireHostedToken = () => {\n if (!token) {\n throw new Error(\"OttoFMS authentication is required for hosted setup.\");\n }\n return token;\n };\n\n if (!(selectedFile && dataApiKey)) {\n if (!(flags.adminApiKey || (versions.ottoVersion && compareSemver(versions.ottoVersion, \"4.7.0\") >= 0))) {\n throw new Error(\n \"OttoFMS 4.7.0 or later is required to auto-login. Upgrade OttoFMS or pass --admin-api-key for hosted setup.\",\n );\n }\n token = flags.adminApiKey ?? (await fileMakerService.getOttoFMSToken({ url: hostedUrl })).token;\n }\n\n if (!selectedFile) {\n if (nonInteractive) {\n throw new Error(\"Missing required FileMaker inputs in non-interactive mode: --file-name, --data-api-key.\");\n }\n\n files = await fileMakerService.listFiles({ url: hostedUrl, token: requireHostedToken() });\n selectedFile = await prompt.searchSelect({\n message: \"Which file would you like to connect to?\",\n options: [\n {\n value: \"$deploy-demo\",\n label: \"Deploy NEW ProofKit Demo File\",\n hint: \"Use OttoFMS to deploy a new file for testing\",\n keywords: [\"demo\", \"proofkit\"],\n },\n ...files\n .slice()\n .sort((left, right) => left.filename.localeCompare(right.filename))\n .map((file) => ({\n value: file.filename,\n label: file.filename,\n hint: file.status,\n keywords: [file.filename],\n })),\n ],\n });\n }\n\n if (!selectedFile) {\n throw new Error(\"No FileMaker file was selected.\");\n }\n\n if (selectedFile === \"$deploy-demo\") {\n if (files.length === 0) {\n files = await fileMakerService.listFiles({ url: hostedUrl, token: requireHostedToken() });\n }\n const demoExists = files.some((file) => file.filename === demoFileName);\n const replaceDemo =\n demoExists && !nonInteractive\n ? await prompt.confirm({\n message: \"The demo file already exists. Do you want to replace it with a fresh copy?\",\n initialValue: false,\n })\n : demoExists;\n const deployed = await fileMakerService.deployDemoFile({\n url: hostedUrl,\n token: requireHostedToken(),\n operation: replaceDemo ? \"replace\" : \"install\",\n });\n selectedFile = deployed.filename;\n dataApiKey = deployed.apiKey;\n layoutName ??= \"API_Contacts\";\n schemaName ??= \"Contacts\";\n }\n\n if (!dataApiKey && nonInteractive) {\n throw new Error(\"Missing required FileMaker inputs in non-interactive mode: --data-api-key.\");\n }\n\n if (!dataApiKey) {\n const apiKeys = (await fileMakerService.listAPIKeys({ url: hostedUrl, token: requireHostedToken() })).filter(\n (apiKey) => apiKey.database === selectedFile,\n );\n\n const selection =\n apiKeys.length === 0\n ? \"create\"\n : await prompt.searchSelect({\n message: \"Which OttoFMS Data API key would you like to use?\",\n options: [\n ...apiKeys.map((apiKey) => ({\n value: apiKey.key,\n label: `${apiKey.label} - ${apiKey.user}`,\n hint: `${apiKey.key.slice(0, 5)}...${apiKey.key.slice(-4)}`,\n keywords: [apiKey.label, apiKey.user, apiKey.database],\n })),\n {\n value: \"create\",\n label: \"Create a new API key\",\n hint: \"Requires FileMaker credentials for this file\",\n keywords: [\"create\", \"new\"],\n },\n ],\n });\n\n if (selection === \"create\") {\n const username = await prompt.text({\n message: `Enter the account name for ${selectedFile}`,\n validate: (value) => (value ? undefined : \"An account name is required\"),\n });\n const password = await prompt.password({\n message: `Enter the password for ${username}`,\n validate: (value) => (value ? undefined : \"A password is required\"),\n });\n dataApiKey = (\n await fileMakerService.createDataAPIKeyWithCredentials({\n url: hostedUrl,\n filename: selectedFile,\n username,\n password,\n })\n ).apiKey;\n } else {\n dataApiKey = selection;\n }\n }\n\n if (!dataApiKey) {\n throw new Error(\"No FileMaker Data API key was selected.\");\n }\n\n const layouts = await fileMakerService.listLayouts({\n dataApiKey,\n fmFile: selectedFile,\n server: hostedUrl.origin,\n });\n\n if (layoutName && !layouts.includes(layoutName)) {\n throw new Error(`Layout \"${layoutName}\" was not found in ${selectedFile}.`);\n }\n\n if (!(nonInteractive || layoutName || schemaName)) {\n const shouldConfigureLayout = await prompt.confirm({\n message: \"Do you want to configure an initial layout for type generation now?\",\n initialValue: false,\n });\n\n if (shouldConfigureLayout) {\n layoutName = await prompt.searchSelect({\n message: \"Select a layout to read data from\",\n options: layouts.map((layout) => ({\n value: layout,\n label: layout,\n keywords: [layout],\n })),\n });\n\n schemaName = await prompt.text({\n message: \"What should the generated schema be called?\",\n defaultValue: getDefaultSchemaName(layoutName),\n validate: (value) => (value ? undefined : \"A schema name is required\"),\n });\n }\n }\n\n return {\n mode: \"hosted-otto\",\n dataSourceName: \"filemaker\",\n envNames: createDataSourceEnvNames(\"filemaker\"),\n server: hostedUrl.origin,\n fileName: selectedFile,\n dataApiKey,\n layoutName,\n schemaName,\n adminApiKey: flags.adminApiKey,\n fmsVersion: versions.fmsVersion,\n ottoVersion: versions.ottoVersion,\n };\n}\n\nasync function resolveFileMakerInputs({\n prompt,\n fileMakerService,\n flags,\n appType,\n nonInteractive,\n}: {\n prompt: PromptService;\n fileMakerService: FileMakerService;\n flags: CliFlags;\n appType: AppType;\n nonInteractive: boolean;\n}) {\n if (flags.dataSource !== \"filemaker\") {\n return { fileMaker: undefined, skipFileMakerSetup: false };\n }\n\n validateLayoutInputs(flags);\n\n if (appType === \"webviewer\" && !flags.server) {\n while (true) {\n const localFmMcp = await fileMakerService.detectLocalFmMcp();\n if (localFmMcp.healthy && localFmMcp.connectedFiles[0]) {\n return {\n fileMaker: {\n mode: \"local-fm-mcp\",\n dataSourceName: \"filemaker\",\n envNames: createDataSourceEnvNames(\"filemaker\"),\n fmMcpBaseUrl: localFmMcp.baseUrl,\n fileName: localFmMcp.connectedFiles[0],\n layoutName: flags.layoutName,\n schemaName: flags.schemaName,\n } satisfies FileMakerInputs,\n skipFileMakerSetup: false,\n };\n }\n\n if (nonInteractive) {\n if (localFmMcp.healthy) {\n throw new Error(\n \"ProofKit MCP Server was detected, but no FileMaker files are open. Open a file in FileMaker and rerun, or pass --server.\",\n );\n }\n\n throw new Error(\n \"ProofKit MCP Server was not detected and no FileMaker server was provided. Start the ProofKit MCP Server locally or rerun with --server.\",\n );\n }\n\n const fallbackAction = await prompt.select({\n message: localFmMcp.healthy\n ? \"I noticed you have the ProofKit MCP Server installed, but no files are open. How would you like to continue?\"\n : \"ProofKit MCP Server was not detected. How would you like to continue?\",\n options: [\n {\n value: \"retry\",\n label: \"Try again\",\n hint: localFmMcp.healthy\n ? \"Open a FileMaker file, then retry detection\"\n : \"Retry ProofKit MCP Server detection\",\n },\n {\n value: \"hosted\",\n label: \"Continue with hosted setup\",\n hint: \"Use OttoFMS and a hosted FileMaker server\",\n },\n {\n value: \"skip\",\n label: \"Skip for now\",\n hint: \"Create the project and configure FileMaker later\",\n },\n ],\n });\n\n if (fallbackAction === \"retry\") {\n continue;\n }\n\n if (fallbackAction === \"skip\") {\n return {\n fileMaker: undefined,\n skipFileMakerSetup: true,\n };\n }\n\n break;\n }\n }\n\n return {\n fileMaker: await resolveHostedFileMakerInputs({\n prompt,\n fileMakerService,\n flags,\n nonInteractive,\n }),\n skipFileMakerSetup: false,\n };\n}\n\nexport const resolveInitRequest = (name?: string, rawFlags?: CliFlags) =>\n Effect.gen(function* () {\n const flags = { ...defaultFlags, ...rawFlags };\n const prompt = yield* PromptService;\n const fileMakerService = yield* FileMakerService;\n const cliContext = yield* CliContext;\n const nonInteractive = cliContext.nonInteractive || flags.CI || flags.nonInteractive === true;\n\n let projectName = name;\n if (!projectName) {\n if (nonInteractive) {\n return yield* Effect.fail(new Error(\"Project name is required in non-interactive mode.\"));\n }\n\n projectName = yield* Effect.promise(() =>\n prompt.text({\n message: \"What will your project be called?\",\n defaultValue: DEFAULT_APP_NAME,\n validate: validateAppName,\n }),\n );\n }\n\n if (!projectName) {\n return yield* Effect.fail(new Error(\"Project name is required.\"));\n }\n\n const validationError = validateAppName(projectName);\n if (validationError) {\n return yield* Effect.fail(new Error(validationError));\n }\n\n let appType: AppType = flags.appType ?? \"browser\";\n if (!(flags.appType || nonInteractive)) {\n appType = yield* Effect.promise(() =>\n prompt.select({\n message: \"What kind of app do you want to build?\",\n options: [\n {\n value: \"browser\",\n label: \"Web App for Browsers\",\n hint: \"Uses Next.js and hosted deployment\",\n },\n {\n value: \"webviewer\",\n label: \"FileMaker Web Viewer\",\n hint: \"Uses Vite for FileMaker web viewers\",\n },\n ],\n }),\n ).pipe(Effect.map((value) => value as AppType));\n }\n\n const hasExplicitFileMakerInputs = Boolean(\n flags.server || flags.adminApiKey || flags.dataApiKey || flags.fileName || flags.layoutName || flags.schemaName,\n );\n\n let dataSource: DataSourceType = \"none\";\n if (flags.dataSource) {\n dataSource = flags.dataSource;\n } else if (appType === \"webviewer\") {\n dataSource = hasExplicitFileMakerInputs || !(nonInteractive && !flags.server) ? \"filemaker\" : \"none\";\n }\n\n if (!(nonInteractive || flags.dataSource) && appType !== \"webviewer\") {\n dataSource = yield* Effect.promise(() =>\n prompt.select({\n message: \"Do you want to connect to a FileMaker Database now?\",\n options: [\n {\n value: \"filemaker\",\n label: \"Yes\",\n hint: \"Set up env, datasource config, and typegen now\",\n },\n {\n value: \"none\",\n label: \"No\",\n hint: \"You can add a data source later\",\n },\n ],\n }),\n ).pipe(Effect.map((value) => value as DataSourceType));\n }\n\n if (nonInteractive && !flags.dataSource && hasExplicitFileMakerInputs) {\n return yield* Effect.fail(new Error(\"FileMaker flags require --data-source filemaker in non-interactive mode.\"));\n }\n\n if (nonInteractive && dataSource !== \"filemaker\" && hasExplicitFileMakerInputs) {\n return yield* Effect.fail(new Error(\"FileMaker flags require --data-source filemaker in non-interactive mode.\"));\n }\n\n const { fileMaker, skipFileMakerSetup } = yield* Effect.promise(() =>\n resolveFileMakerInputs({\n prompt,\n fileMakerService,\n flags: { ...flags, dataSource },\n appType,\n nonInteractive,\n }),\n );\n\n const [scopedAppName, appDir] = parseNameAndPath(projectName);\n\n return {\n projectName,\n scopedAppName,\n appDir,\n appType,\n ui: flags.ui ?? \"shadcn\",\n dataSource,\n packageManager: cliContext.packageManager,\n noInstall: flags.noInstall,\n noGit: flags.noGit,\n force: flags.force,\n cwd: cliContext.cwd,\n importAlias: flags.importAlias,\n nonInteractive,\n debug: cliContext.debug,\n fileMaker,\n skipFileMakerSetup,\n hasExplicitFileMakerInputs,\n } satisfies InitRequest;\n });\n","import open from \"open\";\n\nexport async function openBrowser(url: string): Promise<void> {\n try {\n await open(url);\n } catch {\n // Ignore open failures and let the user copy the URL manually.\n }\n}\n\nexport const openExternal: (url: string) => Promise<void> = openBrowser;\n","import https from \"node:https\";\nimport axios from \"axios\";\n\nfunction createHttpsAgent() {\n return new https.Agent({\n rejectUnauthorized: process.env.PROOFKIT_ALLOW_INSECURE_TLS !== \"1\",\n });\n}\n\nexport async function getJson<T>(url: string, options?: { headers?: Record<string, string>; timeout?: number }) {\n const response = await axios.get<T>(url, {\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeout ?? 10_000,\n validateStatus: null,\n });\n return response;\n}\n\nexport async function postJson<T>(\n url: string,\n data: unknown,\n options?: { headers?: Record<string, string>; timeout?: number },\n) {\n const response = await axios.post<T>(url, data, {\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeout ?? 10_000,\n validateStatus: null,\n });\n return response;\n}\n\nexport async function deleteJson(url: string, options?: { headers?: Record<string, string>; timeout?: number }) {\n const response = await axios.delete(url, {\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeout ?? 10_000,\n validateStatus: null,\n });\n return response;\n}\n\nexport async function requestJson<T>(\n url: string | URL,\n options?: {\n method?: \"GET\" | \"POST\" | \"DELETE\";\n headers?: Record<string, string>;\n body?: Record<string, unknown>;\n timeoutMs?: number;\n },\n) {\n const response = await axios.request<T>({\n url: url.toString(),\n method: options?.method ?? \"GET\",\n data: options?.body,\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeoutMs ?? 10_000,\n });\n return response;\n}\n\nexport async function requestText(\n url: string | URL,\n options?: {\n method?: \"GET\" | \"POST\" | \"DELETE\";\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n) {\n const response = await axios.request<string>({\n url: url.toString(),\n method: options?.method ?? \"GET\",\n headers: options?.headers,\n httpsAgent: createHttpsAgent(),\n timeout: options?.timeoutMs ?? 10_000,\n responseType: \"text\",\n validateStatus: null,\n });\n return {\n status: response.status,\n data: response.data,\n };\n}\n","export type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport function detectUserPackageManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent;\n\n if (userAgent) {\n if (userAgent.startsWith(\"yarn\")) {\n return \"yarn\";\n }\n if (userAgent.startsWith(\"pnpm\")) {\n return \"pnpm\";\n }\n if (userAgent.startsWith(\"bun\")) {\n return \"bun\";\n }\n return \"npm\";\n }\n\n return \"npm\";\n}\n","import {\n intro as clackIntro,\n isCancel as clackIsCancel,\n log as clackLog,\n note as clackNote,\n outro as clackOutro,\n spinner as clackSpinner,\n} from \"@clack/prompts\";\nimport {\n checkbox as inquirerCheckbox,\n confirm as inquirerConfirm,\n input as inquirerInput,\n password as inquirerPassword,\n search as inquirerSearch,\n select as inquirerSelect,\n} from \"@inquirer/prompts\";\n\nconst CANCEL_SYMBOL = Symbol.for(\"@proofkit/new/prompt-cancelled\");\n\nexport const intro = clackIntro;\nexport const log = clackLog;\nexport const note = clackNote;\nexport const outro = clackOutro;\nexport const spinner = clackSpinner;\n\nfunction isPromptCancel(error: unknown) {\n return error instanceof Error && error.name === \"ExitPromptError\";\n}\n\nfunction withCancelSentinel<T>(fn: () => Promise<T>): Promise<T | symbol> {\n return fn().catch((error: unknown) => {\n if (isPromptCancel(error)) {\n return CANCEL_SYMBOL;\n }\n throw error;\n });\n}\n\nexport function isCancel(value: unknown): value is symbol {\n return value === CANCEL_SYMBOL || clackIsCancel(value);\n}\n\nexport interface PromptOption<T extends string> {\n value: T;\n label: string;\n hint?: string;\n disabled?: boolean | string;\n}\n\nexport interface SearchPromptOption<T extends string> extends PromptOption<T> {\n keywords?: readonly string[];\n}\n\nfunction normalizeValidate(\n validate: ((value: string) => string | undefined) | undefined,\n): ((value: string) => string | boolean) | undefined {\n if (!validate) {\n return undefined;\n }\n\n return (value: string) => validate(value) ?? true;\n}\n\nfunction matchesSearch(option: SearchPromptOption<string>, query: string) {\n const haystack = [option.label, option.hint ?? \"\", ...(option.keywords ?? [])].join(\" \").toLowerCase();\n return haystack.includes(query.trim().toLowerCase());\n}\n\nfunction normalizeDisabledMessage(value: boolean | string | undefined) {\n if (typeof value === \"string\") {\n return value;\n }\n return value ? true : undefined;\n}\n\nexport function filterSearchOptions<T extends string>(\n options: readonly SearchPromptOption<T>[],\n query: string | undefined,\n) {\n const term = query?.trim();\n if (!term) {\n return options;\n }\n\n return options.filter((option) => matchesSearch(option, term));\n}\n\nexport function textPrompt(options: {\n message: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n}) {\n return withCancelSentinel(() =>\n inquirerInput({\n message: options.message,\n default: options.defaultValue,\n validate: normalizeValidate(options.validate),\n }),\n );\n}\n\nexport function passwordPrompt(options: { message: string; validate?: (value: string) => string | undefined }) {\n return withCancelSentinel(() =>\n inquirerPassword({\n message: options.message,\n validate: normalizeValidate(options.validate),\n }),\n );\n}\n\nexport function confirmPrompt(options: { message: string; initialValue?: boolean }) {\n return withCancelSentinel(() =>\n inquirerConfirm({\n message: options.message,\n default: options.initialValue,\n }),\n );\n}\n\nexport function selectPrompt<T extends string>(options: { message: string; options: PromptOption<T>[] }) {\n return withCancelSentinel(() =>\n inquirerSelect<T>({\n message: options.message,\n pageSize: 10,\n choices: options.options.map((option) => ({\n value: option.value,\n name: option.label,\n description: option.hint,\n disabled: normalizeDisabledMessage(option.disabled),\n })),\n }),\n );\n}\n\nexport function searchSelectPrompt<T extends string>(options: {\n message: string;\n emptyMessage?: string;\n options: SearchPromptOption<T>[];\n}) {\n return withCancelSentinel(() =>\n inquirerSearch<T>({\n message: options.message,\n pageSize: 10,\n source: (input) => {\n const filtered = filterSearchOptions(options.options, input);\n if (filtered.length === 0) {\n return [\n {\n value: \"__no_matches__\" as T,\n name: options.emptyMessage ?? \"No matches found. Keep typing to refine your search.\",\n disabled: options.emptyMessage ?? \"No matches found\",\n },\n ];\n }\n\n return filtered.map((option) => ({\n value: option.value,\n name: option.label,\n description: option.hint,\n disabled: normalizeDisabledMessage(option.disabled),\n }));\n },\n }),\n );\n}\n\nexport function multiSearchSelectPrompt<T extends string>(options: {\n message: string;\n options: SearchPromptOption<T>[];\n required?: boolean;\n}) {\n return withCancelSentinel(() =>\n inquirerCheckbox<T>({\n message: options.message,\n pageSize: 10,\n required: options.required,\n choices: options.options.map((option) => ({\n value: option.value,\n name: option.label,\n description: option.hint,\n disabled: normalizeDisabledMessage(option.disabled),\n })),\n }),\n );\n}\n","import { randomUUID } from \"node:crypto\";\nimport path from \"node:path\";\nimport { Effect, Layer } from \"effect\";\nimport { execa } from \"execa\";\nimport fs from \"fs-extra\";\nimport { TEMPLATE_ROOT } from \"~/consts.js\";\nimport {\n CliContext,\n type CliContextValue,\n CodegenService,\n ConsoleService,\n type FileMakerBootstrapArtifacts,\n FileMakerService,\n FileSystemService,\n GitService,\n type OttoApiKeyInfo,\n type OttoFileInfo,\n PackageManagerService,\n ProcessService,\n PromptService,\n SettingsService,\n TemplateService,\n} from \"~/core/context.js\";\nimport { UserAbortedError } from \"~/core/errors.js\";\nimport type { AppType, FileMakerInputs, ProofKitSettings, UIType } from \"~/core/types.js\";\nimport { openBrowser } from \"~/utils/browserOpen.js\";\nimport { deleteJson, getJson, postJson } from \"~/utils/http.js\";\nimport { detectUserPackageManager } from \"~/utils/packageManager.js\";\nimport { createDataSourceEnvNames, updateEnvSchemaFile, updateTypegenConfig } from \"~/utils/projectFiles.js\";\nimport {\n confirmPrompt,\n spinner as createSpinner,\n isCancel,\n log,\n multiSearchSelectPrompt,\n note,\n passwordPrompt,\n searchSelectPrompt,\n selectPrompt,\n textPrompt,\n} from \"~/utils/prompts.js\";\n\nfunction unwrap<T>(value: T | symbol): T {\n if (isCancel(value)) {\n throw new UserAbortedError();\n }\n return value as T;\n}\n\nfunction normalizeUrl(serverUrl: string) {\n if (serverUrl.startsWith(\"https://\")) {\n return serverUrl;\n }\n if (serverUrl.startsWith(\"http://\")) {\n return serverUrl.replace(\"http://\", \"https://\");\n }\n return `https://${serverUrl}`;\n}\n\ninterface LayoutFolder {\n isFolder?: boolean;\n name?: string;\n folderLayoutNames?: LayoutFolder[];\n}\n\nfunction transformLayoutList(layouts: LayoutFolder[]): string[] {\n const flatten = (layout: LayoutFolder): string[] => {\n if (layout.isFolder === true) {\n const folderLayouts = Array.isArray(layout.folderLayoutNames) ? layout.folderLayoutNames : [];\n return folderLayouts.flatMap((item) => flatten(item));\n }\n return typeof layout.name === \"string\" ? [layout.name] : [];\n };\n\n return layouts.flatMap(flatten).sort((left, right) => left.localeCompare(right));\n}\n\nconst promptService = {\n text: async (options: { message: string; defaultValue?: string; validate?: (value: string) => string | undefined }) =>\n unwrap(\n await textPrompt({\n message: options.message,\n defaultValue: options.defaultValue,\n validate: options.validate,\n }),\n ).toString(),\n password: async (options: { message: string; validate?: (value: string) => string | undefined }) =>\n unwrap(\n await passwordPrompt({\n message: options.message,\n validate: options.validate,\n }),\n ).toString(),\n select: async <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n }) =>\n unwrap(\n await selectPrompt({\n message: options.message,\n options: options.options,\n }),\n ) as T,\n searchSelect: async <T extends string>(options: {\n message: string;\n emptyMessage?: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n }) => unwrap(await searchSelectPrompt(options)) as T,\n multiSearchSelect: async <T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string; keywords?: string[]; disabled?: boolean | string }>;\n required?: boolean;\n }) => unwrap(await multiSearchSelectPrompt(options)),\n confirm: async (options: { message: string; initialValue?: boolean }) =>\n unwrap(\n await confirmPrompt({\n message: options.message,\n initialValue: options.initialValue,\n }),\n ) as boolean,\n};\n\nconst consoleService = {\n info: (message: string) => log.info(message),\n warn: (message: string) => log.warn(message),\n error: (message: string) => log.error(message),\n success: (message: string) => log.success(message),\n note: (message: string, title?: string) => note(message, title),\n};\n\nconst fileSystemService = {\n exists: async (targetPath: string) => fs.pathExists(targetPath),\n readdir: async (targetPath: string) => fs.readdir(targetPath),\n emptyDir: async (targetPath: string) => fs.emptyDir(targetPath),\n copyDir: async (from: string, to: string, options?: { overwrite?: boolean }) =>\n fs.copy(from, to, { overwrite: options?.overwrite ?? true }),\n rename: async (from: string, to: string) => fs.rename(from, to),\n remove: async (targetPath: string) => fs.remove(targetPath),\n readJson: async <T>(targetPath: string) => fs.readJson(targetPath) as Promise<T>,\n writeJson: async (targetPath: string, value: unknown) => fs.writeJson(targetPath, value, { spaces: 2 }),\n writeFile: async (targetPath: string, content: string) => fs.writeFile(targetPath, content, \"utf8\"),\n readFile: async (targetPath: string) => fs.readFile(targetPath, \"utf8\"),\n};\n\nconst templateService = {\n getTemplateDir: (appType: AppType, ui: UIType) => {\n if (appType === \"webviewer\") {\n return path.join(TEMPLATE_ROOT, \"vite-wv\");\n }\n if (ui === \"mantine\") {\n return path.join(TEMPLATE_ROOT, \"nextjs-mantine\");\n }\n return path.join(TEMPLATE_ROOT, \"nextjs-shadcn\");\n },\n};\n\nconst packageManagerService = {\n getVersion: async (packageManager: string, cwd: string) => {\n if (packageManager === \"bun\") {\n return undefined;\n }\n const { stdout } = await execa(packageManager, [\"-v\"], { cwd });\n return stdout.trim();\n },\n};\n\nconst processService = {\n run: async (\n command: string,\n args: string[],\n options: {\n cwd: string;\n stdout?: \"pipe\" | \"inherit\" | \"ignore\";\n stderr?: \"pipe\" | \"inherit\" | \"ignore\";\n },\n ) => {\n const result = await execa(command, args, {\n cwd: options.cwd,\n stdout: options.stdout ?? \"pipe\",\n stderr: options.stderr ?? \"pipe\",\n });\n return {\n stdout: result.stdout ?? \"\",\n stderr: result.stderr ?? \"\",\n };\n },\n};\n\nconst gitService = {\n initialize: async (projectDir: string) => {\n await execa(\"git\", [\"init\"], { cwd: projectDir });\n await execa(\"git\", [\"add\", \".\"], { cwd: projectDir });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], { cwd: projectDir });\n },\n};\n\nconst settingsService = {\n writeSettings: async (projectDir: string, settings: ProofKitSettings) =>\n fs.writeJson(path.join(projectDir, \"proofkit.json\"), settings, { spaces: 2 }),\n appendEnvVars: async (projectDir: string, vars: Record<string, string>) => {\n const envPath = path.join(projectDir, \".env\");\n const existing = (await fs.pathExists(envPath)) ? await fs.readFile(envPath, \"utf8\") : \"\";\n const additions = Object.entries(vars)\n .map(([name, value]) => `${name}=${value}`)\n .join(\"\\n\");\n const nextContent = [existing.trimEnd(), additions].filter(Boolean).join(\"\\n\").concat(\"\\n\");\n await fs.writeFile(envPath, nextContent, \"utf8\");\n },\n ensureTypegenConfig: async (_projectDir: string, _options: { appType: AppType; fileMaker?: FileMakerInputs }) =>\n undefined,\n};\n\nfunction createDataSourceEntry(dataSourceName: string) {\n return {\n type: \"fm\" as const,\n name: dataSourceName,\n envNames: createDataSourceEnvNames(dataSourceName),\n };\n}\n\nfunction createFileMakerBootstrapArtifacts(\n settings: ProofKitSettings,\n inputs: FileMakerInputs,\n appType: AppType,\n): Promise<FileMakerBootstrapArtifacts> {\n const dataSourceEntry = createDataSourceEntry(inputs.dataSourceName);\n const nextSettings: ProofKitSettings = {\n ...settings,\n dataSources: settings.dataSources.some((entry) => entry.name === dataSourceEntry.name)\n ? settings.dataSources\n : [...settings.dataSources, dataSourceEntry],\n };\n\n if (inputs.mode === \"local-fm-mcp\") {\n return Promise.resolve({\n settings: nextSettings,\n envVars: {},\n envSchemaEntries: [],\n typegenConfig: {\n mode: inputs.mode,\n dataSourceName: inputs.dataSourceName,\n fmMcpBaseUrl: inputs.fmMcpBaseUrl,\n connectedFileName: inputs.fileName,\n layoutName: inputs.layoutName,\n schemaName: inputs.schemaName,\n appType,\n },\n });\n }\n\n return Promise.resolve({\n settings: nextSettings,\n envVars: {\n [inputs.envNames.database]: inputs.fileName,\n [inputs.envNames.server]: inputs.server,\n [inputs.envNames.apiKey]: inputs.dataApiKey,\n },\n envSchemaEntries: [\n {\n name: inputs.envNames.database,\n zodSchema: 'z.string().endsWith(\".fmp12\")',\n defaultValue: inputs.fileName,\n },\n {\n name: inputs.envNames.server,\n zodSchema: \"z.string().url()\",\n defaultValue: inputs.server,\n },\n {\n name: inputs.envNames.apiKey,\n zodSchema: 'z.string().startsWith(\"dk_\")',\n defaultValue: inputs.dataApiKey,\n },\n ],\n typegenConfig: {\n mode: inputs.mode,\n dataSourceName: inputs.dataSourceName,\n envNames: inputs.envNames,\n layoutName: inputs.layoutName,\n schemaName: inputs.schemaName,\n appType,\n },\n });\n}\n\nconst fileMakerService = {\n detectLocalFmMcp: async (baseUrl = process.env.FM_MCP_BASE_URL ?? \"http://127.0.0.1:1365\") => {\n try {\n const health = await fetch(`${baseUrl}/health`, { signal: AbortSignal.timeout(3000) });\n if (!health.ok) {\n return { baseUrl, healthy: false, connectedFiles: [] };\n }\n const connectedFiles = await fetch(`${baseUrl}/connectedFiles`, { signal: AbortSignal.timeout(3000) })\n .then(async (response) => (response.ok ? ((await response.json()) as unknown) : []))\n .catch(() => []);\n return {\n baseUrl,\n healthy: true,\n connectedFiles: Array.isArray(connectedFiles)\n ? connectedFiles.filter((item): item is string => typeof item === \"string\")\n : [],\n };\n } catch {\n return { baseUrl, healthy: false, connectedFiles: [] };\n }\n },\n validateHostedServerUrl: async (serverUrl: string, ottoPort?: number | null) => {\n const normalizedUrl = normalizeUrl(serverUrl);\n const fmsUrl = new URL(\"/fmws/serverinfo\", normalizedUrl).toString();\n const fmsResponse = await getJson<{ data?: { ServerVersion?: string } }>(fmsUrl);\n const serverVersion = fmsResponse.data?.data?.ServerVersion?.split(\" \")[0];\n if (!serverVersion) {\n throw new Error(`Invalid FileMaker Server URL: ${normalizedUrl}`);\n }\n\n let ottoVersion: string | null = null;\n const otto4Response = await getJson<{ response?: { Otto?: { version?: string } } }>(\n new URL(\"/otto/api/info\", normalizedUrl).toString(),\n ).catch(() => undefined);\n ottoVersion = otto4Response?.data?.response?.Otto?.version ?? null;\n\n if (!ottoVersion) {\n const otto3Url = new URL(normalizedUrl);\n otto3Url.port = ottoPort ? String(ottoPort) : \"3030\";\n otto3Url.pathname = \"/api/otto/info\";\n const otto3Response = await getJson<{ Otto?: { version?: string } }>(otto3Url.toString()).catch(() => undefined);\n ottoVersion = otto3Response?.data?.Otto?.version ?? null;\n }\n\n return {\n normalizedUrl: new URL(normalizedUrl).origin,\n versions: {\n fmsVersion: serverVersion,\n ottoVersion,\n },\n };\n },\n getOttoFMSToken: async ({ url }: { url: URL }) => {\n const hash = randomUUID().replaceAll(\"-\", \"\").slice(0, 18);\n const loginUrl = new URL(`/otto/wizard/${hash}`, url.origin);\n log.info(`If the browser window didn't open automatically, use this Otto login URL:\\n${loginUrl.toString()}`);\n await openBrowser(loginUrl.toString());\n\n const spin = createSpinner();\n spin.start(\"Waiting for OttoFMS login\");\n\n const deadline = Date.now() + 180_000;\n while (Date.now() < deadline) {\n const response = await getJson<{ response?: { token?: string } }>(\n `${url.origin}/otto/api/cli/checkHash/${hash}`,\n { headers: { \"Accept-Encoding\": \"deflate\" }, timeout: 5000 },\n ).catch(() => undefined);\n const token = response?.data?.response?.token;\n if (token) {\n spin.stop(\"Login complete\");\n await deleteJson(`${url.origin}/otto/api/cli/checkHash/${hash}`, {\n headers: { \"Accept-Encoding\": \"deflate\" },\n }).catch(() => undefined);\n return { token };\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n\n spin.stop(\"Login timed out\");\n throw new Error(\"OttoFMS login timed out after 3 minutes.\");\n },\n listFiles: async ({ url, token }: { url: URL; token: string }) => {\n const response = await getJson<{ response?: { databases?: Array<{ filename?: string; status?: string }> } }>(\n `${url.origin}/otto/fmi/admin/api/v2/databases`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n );\n const databases = (response.data?.response?.databases ?? []) as Record<string, unknown>[];\n return databases\n .filter((database): database is { filename: string; status?: string } => typeof database.filename === \"string\")\n .map(\n (database) =>\n ({\n filename: database.filename,\n status: database.status ?? \"unknown\",\n }) satisfies OttoFileInfo,\n );\n },\n listAPIKeys: async ({ url, token }: { url: URL; token: string }) => {\n const response = await getJson<{ response?: { \"api-keys\"?: Record<string, unknown>[] } }>(\n `${url.origin}/otto/api/api-key`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n );\n const apiKeys = (response.data?.response?.[\"api-keys\"] ?? []) as Record<string, unknown>[];\n return apiKeys\n .filter(\n (apiKey): apiKey is { key: string; user: string; database: string; label: string } =>\n typeof apiKey.key === \"string\" &&\n typeof apiKey.user === \"string\" &&\n typeof apiKey.database === \"string\" &&\n typeof apiKey.label === \"string\",\n )\n .map(\n (apiKey) =>\n ({\n key: apiKey.key,\n user: apiKey.user,\n database: apiKey.database,\n label: apiKey.label,\n }) satisfies OttoApiKeyInfo,\n );\n },\n createDataAPIKeyWithCredentials: async ({\n url,\n filename,\n username,\n password: userPassword,\n }: {\n url: URL;\n filename: string;\n username: string;\n password: string;\n }) => {\n const response = await postJson<{ response?: { key?: string } }>(`${url.origin}/otto/api/api-key/create-only`, {\n database: filename,\n label: \"For FM Web App\",\n user: username,\n pass: userPassword,\n });\n const apiKey = response.data?.response?.key;\n if (!apiKey) {\n throw new Error(`Failed to create a Data API key for ${filename}.`);\n }\n return { apiKey };\n },\n startDeployment: async ({ payload, url, token }: { payload: unknown; url: URL; token: string }) =>\n postJson<{ response?: { subDeploymentIds?: number[] } }>(`${url.origin}/otto/api/deployment`, payload, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }),\n getDeploymentStatus: async ({ url, token, deploymentId }: { url: URL; token: string; deploymentId: number }) =>\n getJson<{ response?: { status?: string; running?: boolean } }>(\n `${url.origin}/otto/api/deployment/${deploymentId}`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n ),\n deployDemoFile: async ({ url, token, operation }: { url: URL; token: string; operation: \"install\" | \"replace\" }) => {\n const demoFileName = \"ProofKitDemo.fmp12\";\n const spin = createSpinner();\n spin.start(\"Deploying ProofKit Demo file\");\n\n const deploymentPayload = {\n scheduled: false,\n label: \"Install ProofKit Demo\",\n deployments: [\n {\n name: \"Install ProofKit Demo\",\n source: {\n type: \"url\",\n url: \"https://proofkit.dev/proofkit-demo/manifest.json\",\n },\n fileOperations: [\n {\n target: {\n fileName: demoFileName,\n },\n operation,\n source: {\n fileName: demoFileName,\n },\n location: {\n folder: \"default\",\n subFolder: \"\",\n },\n },\n ],\n concurrency: 1,\n options: {\n closeFilesAfterBuild: false,\n keepFilesClosedAfterComplete: false,\n transferContainerData: false,\n },\n },\n ],\n abortRemaining: false,\n };\n\n const deployment = await fileMakerService.startDeployment({\n payload: deploymentPayload,\n url,\n token,\n });\n\n const deploymentId = deployment.data?.response?.subDeploymentIds?.[0];\n if (!deploymentId) {\n spin.stop(\"Demo deployment failed\");\n throw new Error(\"No deployment ID was returned when deploying the demo file.\");\n }\n\n const deploymentDeadline = Date.now() + 300_000;\n let deploymentCompleted = false;\n while (Date.now() < deploymentDeadline) {\n await new Promise((resolve) => setTimeout(resolve, 2500));\n const status = await fileMakerService.getDeploymentStatus({\n url,\n token,\n deploymentId,\n });\n\n if (!status.data?.response?.running) {\n if (status.data?.response?.status !== \"complete\") {\n spin.stop(\"Demo deployment failed\");\n throw new Error(\"ProofKit Demo deployment did not complete successfully.\");\n }\n deploymentCompleted = true;\n break;\n }\n }\n\n if (!deploymentCompleted) {\n spin.stop(\"Demo deployment timed out\");\n throw new Error(\"ProofKit Demo deployment timed out after 5 minutes.\");\n }\n\n const apiKey = await fileMakerService.createDataAPIKeyWithCredentials({\n url,\n filename: demoFileName,\n username: \"admin\",\n password: \"admin\",\n });\n spin.stop(\"Demo file deployed\");\n return { apiKey: apiKey.apiKey, filename: demoFileName };\n },\n listLayouts: async ({ dataApiKey, fmFile, server }: { dataApiKey: string; fmFile: string; server: string }) => {\n const response = await getJson<{ response?: { layouts?: LayoutFolder[] } }>(\n `${server}/otto/fmi/data/vLatest/databases/${encodeURIComponent(fmFile)}/layouts`,\n {\n headers: {\n Authorization: `Bearer ${dataApiKey}`,\n },\n },\n );\n return transformLayoutList(response.data?.response?.layouts ?? []);\n },\n createFileMakerBootstrapArtifacts,\n bootstrap: async (projectDir: string, settings: ProofKitSettings, inputs: FileMakerInputs, appType: AppType) => {\n const artifacts = await createFileMakerBootstrapArtifacts(settings, inputs, appType);\n if (Object.keys(artifacts.envVars).length > 0) {\n await settingsService.appendEnvVars(projectDir, artifacts.envVars);\n await updateEnvSchemaFile(fileSystemService, projectDir, artifacts.envSchemaEntries);\n }\n\n await updateTypegenConfig(fileSystemService, projectDir, {\n appType: artifacts.typegenConfig.appType,\n dataSourceName: artifacts.typegenConfig.dataSourceName,\n envNames: artifacts.typegenConfig.envNames,\n fmMcpBaseUrl: artifacts.typegenConfig.fmMcpBaseUrl,\n connectedFileName: artifacts.typegenConfig.connectedFileName,\n layoutName: artifacts.typegenConfig.layoutName,\n schemaName: artifacts.typegenConfig.schemaName,\n });\n\n return artifacts.settings;\n },\n};\n\nconst codegenService = {\n runInitial: async (projectDir: string, packageManager: CliContextValue[\"packageManager\"]) => {\n let commandParts: string[];\n if (packageManager === \"npm\") {\n commandParts = [\"npm\", \"run\", \"typegen\"];\n } else if (packageManager === \"bun\") {\n commandParts = [\"bun\", \"run\", \"typegen\"];\n } else {\n commandParts = [packageManager, \"typegen\"];\n }\n const command = commandParts[0];\n if (!command) {\n throw new Error(\"Unable to resolve the codegen command\");\n }\n const args = commandParts.slice(1);\n await execa(command, args, { cwd: projectDir });\n },\n};\n\nexport function makeLiveLayer(options: { cwd: string; debug: boolean; nonInteractive: boolean }) {\n const cliContext: CliContextValue = {\n cwd: options.cwd,\n debug: options.debug,\n nonInteractive: options.nonInteractive,\n packageManager: detectUserPackageManager(),\n };\n\n const layer = Layer.mergeAll(\n Layer.succeed(CliContext, cliContext),\n Layer.succeed(PromptService, promptService),\n Layer.succeed(ConsoleService, consoleService),\n Layer.succeed(FileSystemService, fileSystemService),\n Layer.succeed(TemplateService, templateService),\n Layer.succeed(PackageManagerService, packageManagerService),\n Layer.succeed(ProcessService, processService),\n Layer.succeed(GitService, gitService),\n Layer.succeed(SettingsService, settingsService),\n Layer.succeed(FileMakerService, fileMakerService),\n Layer.succeed(CodegenService, codegenService),\n );\n\n return <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.provide(effect, layer);\n}\n","import gradient from \"gradient-string\";\nimport { getTitleText } from \"~/consts.js\";\nimport { detectUserPackageManager } from \"~/utils/packageManager.js\";\n\nconst proofTheme = {\n purple: \"#89216B\",\n lightPurple: \"#D15ABB\",\n orange: \"#FF595E\",\n};\n\nexport const proofGradient = gradient(Object.values(proofTheme));\nexport function renderTitle(version = \"0.0.0-private\") {\n const pkgManager = detectUserPackageManager();\n if (pkgManager === \"yarn\" || pkgManager === \"pnpm\") {\n console.log(\"\");\n }\n console.log(proofGradient.multiline(getTitleText(version)));\n}\n","#!/usr/bin/env node\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { optional as optionalArg, text as textArg, withDescription as withArgDescription } from \"@effect/cli/Args\";\nimport {\n make as makeCommand,\n run,\n withDescription as withCommandDescription,\n withSubcommands,\n} from \"@effect/cli/Command\";\nimport {\n boolean as booleanOption,\n choice as choiceOption,\n optional as optionalOption,\n text as textOption,\n withAlias,\n withDescription as withOptionDescription,\n} from \"@effect/cli/Options\";\nimport { isValidationError } from \"@effect/cli/ValidationError\";\nimport { layer as nodeContextLayer } from \"@effect/platform-node/NodeContext\";\nimport { Cause, Effect, Exit } from \"effect\";\nimport { getOrUndefined } from \"effect/Option\";\nimport { cliName } from \"~/consts.js\";\nimport {\n CliContext,\n ConsoleService,\n FileSystemService,\n PackageManagerService,\n TemplateService,\n} from \"~/core/context.js\";\nimport { executeInitPlan } from \"~/core/executeInitPlan.js\";\nimport { planInit } from \"~/core/planInit.js\";\nimport { resolveInitRequest } from \"~/core/resolveInitRequest.js\";\nimport type { CliFlags } from \"~/core/types.js\";\nimport { makeLiveLayer } from \"~/services/live.js\";\nimport { intro } from \"~/utils/prompts.js\";\nimport { proofGradient, renderTitle } from \"~/utils/renderTitle.js\";\n\nconst defaultCliFlags: CliFlags = {\n noGit: false,\n noInstall: false,\n force: false,\n default: false,\n CI: false,\n importAlias: \"~/\",\n};\n\nfunction getCliVersion() {\n try {\n const packageJsonUrl = new URL(\"../package.json\", import.meta.url);\n const packageJson = JSON.parse(readFileSync(fileURLToPath(packageJsonUrl), \"utf8\")) as { version?: string };\n return packageJson.version ?? \"0.0.0-private\";\n } catch {\n return \"0.0.0-private\";\n }\n}\n\nexport const runInit = (name?: string, rawFlags?: Partial<CliFlags>) =>\n Effect.gen(function* () {\n const templateService = yield* TemplateService;\n const packageManagerService = yield* PackageManagerService;\n const request = yield* resolveInitRequest(name, { ...defaultCliFlags, ...rawFlags });\n const templateDir = templateService.getTemplateDir(request.appType, request.ui);\n const packageManagerVersion = yield* Effect.promise(() =>\n packageManagerService.getVersion(request.packageManager, request.cwd),\n );\n const plan = planInit(request, { templateDir, packageManagerVersion });\n yield* executeInitPlan(plan);\n return { request, plan };\n });\n\nexport const runDefaultCommand = (rawFlags?: Partial<CliFlags>) =>\n Effect.gen(function* () {\n const cliContext = yield* CliContext;\n const fsService = yield* FileSystemService;\n const consoleService = yield* ConsoleService;\n const flags = { ...defaultCliFlags, ...rawFlags };\n\n if (cliContext.nonInteractive || flags.CI || flags.nonInteractive) {\n throw new Error(\n \"The default command is interactive-only in non-interactive mode. Run an explicit command such as `proofkit init <name> --non-interactive`.\",\n );\n }\n\n const settingsPath = path.join(cliContext.cwd, \"proofkit.json\");\n const hasProofKitProject = yield* Effect.promise(() => fsService.exists(settingsPath));\n\n if (hasProofKitProject) {\n intro(`Found ${proofGradient(\"ProofKit\")} project`);\n consoleService.note(\n [\n \"Project command routing is being migrated into the Effect CLI surface.\",\n \"Use an explicit command such as `proofkit add`, `proofkit remove`, `proofkit typegen`, `proofkit deploy`, or `proofkit upgrade`.\",\n ].join(\"\\n\"),\n \"Project commands\",\n );\n return;\n }\n\n intro(`No ${proofGradient(\"ProofKit\")} project found, running \\`init\\``);\n yield* runInit(undefined, {\n ...flags,\n default: true,\n });\n });\n\nconst initDirectoryArg = optionalArg(textArg({ name: \"dir\" })).pipe(\n withArgDescription(\"The project name or target directory\"),\n);\n\nfunction optionalTextOption(name: string, description: string) {\n return optionalOption(textOption(name).pipe(withOptionDescription(description)));\n}\n\nfunction optionalChoiceOption<Choices extends readonly string[]>(name: string, choices: Choices, description: string) {\n return optionalOption(choiceOption(name, choices).pipe(withOptionDescription(description)));\n}\n\nfunction legacyEffect<T>(runLegacy: () => Promise<T>, options?: { nonInteractive?: boolean; debug?: boolean }) {\n return makeLiveLayer({\n cwd: process.cwd(),\n debug: options?.debug === true,\n nonInteractive: options?.nonInteractive === true,\n })(Effect.promise(runLegacy));\n}\n\nfunction makeInitCommand() {\n return makeCommand(\n \"init\",\n {\n dir: initDirectoryArg,\n appType: optionalChoiceOption(\"app-type\", [\"browser\", \"webviewer\"] as const, \"The type of app to create\"),\n ui: optionalChoiceOption(\"ui\", [\"shadcn\", \"mantine\"] as const, \"The UI scaffold to create\"),\n server: optionalTextOption(\"server\", \"The URL of your FileMaker Server\"),\n adminApiKey: optionalTextOption(\"admin-api-key\", \"Admin API key for OttoFMS\"),\n fileName: optionalTextOption(\"file-name\", \"The name of the FileMaker file\"),\n layoutName: optionalTextOption(\"layout-name\", \"The FileMaker layout name to scaffold\"),\n schemaName: optionalTextOption(\"schema-name\", \"The generated schema name\"),\n dataApiKey: optionalTextOption(\"data-api-key\", \"The Otto Data API key to use\"),\n dataSource: optionalChoiceOption(\"data-source\", [\"filemaker\", \"none\"] as const, \"The data source to use\"),\n noGit: booleanOption(\"no-git\").pipe(withOptionDescription(\"Skip git initialization\")),\n noInstall: booleanOption(\"no-install\").pipe(withOptionDescription(\"Skip package installation\")),\n force: booleanOption(\"force\").pipe(\n withAlias(\"f\"),\n withOptionDescription(\"Force overwrite target directory when it already contains files\"),\n ),\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ dir, ...options }) => {\n const flags: CliFlags = {\n ...defaultCliFlags,\n appType: getOrUndefined(options.appType),\n ui: getOrUndefined(options.ui),\n server: getOrUndefined(options.server),\n adminApiKey: getOrUndefined(options.adminApiKey),\n fileName: getOrUndefined(options.fileName),\n layoutName: getOrUndefined(options.layoutName),\n schemaName: getOrUndefined(options.schemaName),\n dataApiKey: getOrUndefined(options.dataApiKey),\n dataSource: getOrUndefined(options.dataSource),\n noGit: options.noGit,\n noInstall: options.noInstall,\n force: options.force,\n CI: options.CI,\n nonInteractive: options.nonInteractive,\n debug: options.debug,\n };\n\n return makeLiveLayer({\n cwd: process.cwd(),\n debug: flags.debug === true,\n nonInteractive: Boolean(flags.CI || flags.nonInteractive),\n })(runInit(getOrUndefined(dir), flags));\n },\n ).pipe(withCommandDescription(\"Create a new project with ProofKit\"));\n}\n\nfunction makeAddCommand() {\n return makeCommand(\n \"add\",\n {\n name: optionalArg(textArg({ name: \"name\" })).pipe(withArgDescription(\"Component or registry item to add\")),\n target: optionalArg(textArg({ name: \"target\" })).pipe(withArgDescription(\"Optional add target\")),\n noInstall: booleanOption(\"no-install\").pipe(withOptionDescription(\"Skip package installation\")),\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ name, target, noInstall, CI, nonInteractive, debug }) =>\n legacyEffect(\n async () => {\n const [{ runAdd }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/add/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({\n noInstall,\n ci: CI,\n nonInteractive,\n debug,\n });\n state.baseCommand = \"add\";\n state.projectDir = process.cwd();\n await runAdd(getOrUndefined(name), { noInstall, target: getOrUndefined(target) });\n },\n { nonInteractive: CI || nonInteractive, debug },\n ),\n ).pipe(withCommandDescription(\"Add a new component to your project\"));\n}\n\nfunction makeRemoveCommand() {\n return makeCommand(\n \"remove\",\n {\n name: optionalArg(textArg({ name: \"name\" })).pipe(withArgDescription(\"Component type to remove\")),\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ name, CI, nonInteractive, debug }) =>\n legacyEffect(\n async () => {\n const [{ runRemove }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/remove/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({\n ci: CI,\n nonInteractive,\n debug,\n });\n state.baseCommand = \"remove\";\n state.projectDir = process.cwd();\n await runRemove(getOrUndefined(name));\n },\n { nonInteractive: CI || nonInteractive, debug },\n ),\n ).pipe(withCommandDescription(\"Remove a component from your project\"));\n}\n\nfunction makeTypegenCommand() {\n return makeCommand(\n \"typegen\",\n {\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ debug }) =>\n legacyEffect(\n async () => {\n const [{ runTypegen }, { state }] = await Promise.all([\n import(\"~/cli/typegen/index.js\"),\n import(\"~/state.js\"),\n ]);\n state.projectDir = process.cwd();\n await runTypegen({\n settings: (await import(\"~/utils/parseSettings.js\")).getSettings(),\n });\n },\n { debug },\n ),\n ).pipe(withCommandDescription(\"Generate types for your project\"));\n}\n\nfunction makeDeployCommand() {\n return makeCommand(\n \"deploy\",\n {\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ debug }) =>\n legacyEffect(\n async () => {\n const [{ runDeploy }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/deploy/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({ debug });\n state.baseCommand = \"deploy\";\n state.projectDir = process.cwd();\n await runDeploy();\n },\n { debug },\n ),\n ).pipe(withCommandDescription(\"Deploy your app\"));\n}\n\nfunction makeUpgradeCommand() {\n return makeCommand(\n \"upgrade\",\n {\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n ({ CI, nonInteractive, debug }) =>\n legacyEffect(\n async () => {\n const [{ runUpgrade }, { initProgramState, state }] = await Promise.all([\n import(\"~/cli/update/index.js\"),\n import(\"~/state.js\"),\n ]);\n initProgramState({ ci: CI, nonInteractive, debug });\n state.baseCommand = \"upgrade\";\n state.projectDir = process.cwd();\n await runUpgrade();\n },\n { nonInteractive: CI || nonInteractive, debug },\n ),\n ).pipe(withCommandDescription(\"Upgrade ProofKit components in your project\"));\n}\n\nconst rootCommand = makeCommand(\n cliName,\n {\n CI: booleanOption(\"ci\").pipe(withOptionDescription(\"Deprecated alias for --non-interactive\")),\n nonInteractive: booleanOption(\"non-interactive\").pipe(\n withOptionDescription(\"Never prompt for input; fail when required values are missing\"),\n ),\n debug: booleanOption(\"debug\").pipe(withOptionDescription(\"Run in debug mode\")),\n },\n (options) =>\n makeLiveLayer({\n cwd: process.cwd(),\n debug: options.debug === true,\n nonInteractive: Boolean(options.CI || options.nonInteractive),\n })(\n runDefaultCommand({\n ...defaultCliFlags,\n CI: options.CI,\n nonInteractive: options.nonInteractive,\n debug: options.debug,\n }),\n ),\n).pipe(\n withCommandDescription(\"Interactive CLI to scaffold and manage ProofKit projects\"),\n withSubcommands([\n makeInitCommand(),\n makeAddCommand(),\n makeRemoveCommand(),\n makeTypegenCommand(),\n makeDeployCommand(),\n makeUpgradeCommand(),\n ]),\n);\n\nexport const cli = run(rootCommand, {\n name: \"ProofKit\",\n version: getCliVersion(),\n});\n\nfunction isMainEntrypoint(argvPath: string | undefined, moduleUrl: string) {\n if (!argvPath) {\n return false;\n }\n\n const resolvedModulePath = fileURLToPath(moduleUrl);\n\n try {\n return realpathSync(argvPath) === realpathSync(resolvedModulePath);\n } catch {\n return path.resolve(argvPath) === path.resolve(resolvedModulePath);\n }\n}\n\nconst isMainModule = isMainEntrypoint(process.argv[1], import.meta.url);\n\nconst debugFlagNames = new Set([\"--debug\"]);\n\nfunction shouldShowDebugDetails(argv: readonly string[]) {\n return argv.some((arg) => debugFlagNames.has(arg));\n}\n\nfunction renderFailure(cause: Cause.Cause<unknown>, showDebugDetails: boolean) {\n const failure = getOrUndefined(Cause.failureOption(cause));\n\n if (!(failure && isValidationError(failure))) {\n const error = Cause.squash(cause);\n console.error(error instanceof Error ? error.message : String(error));\n }\n\n if (showDebugDetails) {\n console.error(`\\n[debug] ${Cause.pretty(cause)}`);\n }\n}\n\nasync function main(argv: readonly string[]) {\n const showDebugDetails = shouldShowDebugDetails(argv);\n const exit = await Effect.runPromiseExit(cli(argv).pipe(Effect.provide(nodeContextLayer)));\n\n if (Exit.isFailure(exit)) {\n renderFailure(exit.cause, showDebugDetails);\n process.exitCode = 1;\n }\n}\n\nif (isMainModule) {\n renderTitle(getCliVersion());\n main(process.argv).catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n });\n}\n"],"mappings":";kvCAgBA,MAAa,EAAa,EAAQ,WAA4B,2BAA2B,CA6B5E,EAAgB,EAAQ,WAA0B,8BAA8B,CAUhF,EAAiB,EAAQ,WAA2B,+BAA+B,CAenF,EAAoB,EAAQ,WAA8B,kCAAkC,CAM5F,GAAkB,EAAQ,WAA4B,gCAAgC,CAMtF,EAAwB,EAAQ,WAAkC,sCAAsC,CAcxG,GAAiB,EAAQ,WAA2B,+BAA+B,CAMnF,GAAa,EAAQ,WAAuB,2BAA2B,CAWvE,GAAkB,EAAQ,WAA4B,gCAAgC,CAwFtF,EAAmB,EAAQ,WAA6B,iCAAiC,CAMzF,GAAiB,EAAQ,WAA2B,+BAA+B,CC/MhG,IAAa,EAAb,cAAsC,KAAM,CAC1C,YAAY,EAAU,6BAA8B,CAClD,MAAM,EAAQ,CACd,KAAK,KAAO,qBCIhB,MAAM,GAAgC,CAAC,OAAQ,OAAQ,QAAS,OAAO,CACjE,GAAuB,QACvB,GAAqB,IAAI,IAAI,CACjC,MACA,OACA,MACA,OACA,QACA,SACA,MACA,OACA,QACA,QACA,OACA,OACD,CAAC,CAEF,SAAgB,GAAqB,EAAoB,CACvD,IAAI,EAAa,EAAW,QAAQ,SAAU,IAAI,CAClD,IAAK,IAAM,KAAU,GACf,EAAW,WAAW,EAAO,GAC/B,EAAa,EAAW,QAAQ,EAAQ,GAAG,EAG/C,OAAO,EAGT,SAAgB,GAAyB,EAA2C,CAClF,GAAI,IAAmB,YACrB,MAAO,CACL,SAAU,cACV,OAAQ,YACR,OAAQ,eACT,CAGH,IAAM,EAAY,EAAe,aAAa,CAC9C,MAAO,CACL,SAAU,GAAG,EAAU,cACvB,OAAQ,GAAG,EAAU,YACrB,OAAQ,GAAG,EAAU,eACtB,CAGH,SAAgB,EAA4B,EAAgC,EAAiB,CAC3F,MAAO,CAAC,MAAO,MAAM,CAAC,SAAS,EAAe,CAAG,GAAG,EAAe,OAAO,IAAY,GAAG,EAAe,GAAG,IAG7G,SAAgB,GAA0B,EAAgC,CAIxE,OAHI,IAAmB,MACd,UAEF,EAGT,SAAgB,GAAqB,EAAqB,CACxD,OAAO,EAAY,QAAQ,MAAO,GAAG,CAAC,QAAQ,GAAsB,MAAM,CAG5E,eAAsB,EACpB,EAKA,EACA,EACA,EACA,CACA,IAAM,EAAU,MAAM,EAAG,QAAQ,EAAQ,CACzC,IAAK,IAAM,KAAS,EAAS,CAC3B,IAAM,EAAW,EAAK,KAAK,EAAS,EAAM,CAa1C,GAZqB,MAAM,EAAG,QAAQ,EAAS,CAAC,MAAO,GAAmB,CAMxE,IAJE,OAAO,GAAU,UAAY,GAAkB,SAAU,GAAS,OAAO,EAAM,MAAS,SACpF,EAAM,KACN,IAAA,MAEO,UAIb,MAAM,GACN,CACgB,CAChB,MAAM,EAAmB,EAAI,EAAU,EAAa,EAAa,CACjE,SAGF,IAAM,EAAY,EAAK,QAAQ,EAAM,CACrC,GAAI,CAAC,GAAmB,IAAI,EAAU,CACpC,SAGF,IAAM,EAAU,MAAM,EAAG,SAAS,EAAS,CAAC,UAAY,IAAA,GAAU,CAC7D,GAAS,SAAS,EAAY,EAInC,MAAM,EAAG,UAAU,EAAU,EAAQ,WAAW,EAAa,EAAa,CAAC,EAI/E,eAAsB,GACpB,EAKA,EACA,EACA,CACA,IAAM,EAAc,EAAK,KAAK,EAAY,iBAAiB,CAC3D,GAAI,CAAE,MAAM,EAAG,OAAO,EAAY,CAChC,OAGF,IAAI,EAAU,MAAM,EAAG,SAAS,EAAY,CAEtC,EAAc,EAAQ,QADb,cAC4B,CAC3C,GAAI,IAAgB,GAClB,OAGF,IAAM,EAAc,EAAQ,QAAQ,OAAQ,EAAY,CACxD,GAAI,IAAgB,GAClB,OAGF,IAAM,EAAY,EACf,OAAQ,GAAU,CAAC,EAAQ,SAAS,GAAG,EAAM,KAAK,GAAG,CAAC,CACtD,IAAK,GAAU,OAAO,EAAM,KAAK,IAAI,EAAM,UAAU,GAAG,CACxD,KAAK;EAAK,CAER,IAIL,EAAU,GAAG,EAAQ,MAAM,EAAG,EAAY,GAAG,EAAU,IAAI,EAAQ,MAAM,EAAY,GACrF,MAAM,EAAG,UAAU,EAAa,EAAQ,EAQ1C,eAAsB,GACpB,EAKA,EACA,EASA,CACA,IAAM,EAAa,EAAK,KAAK,EAAY,gCAAgC,CACnE,EAAS,wBAAwB,EAAQ,iBACzC,EAA0C,CAC9C,KAAM,SACN,QAAS,EAAE,CACX,KAAM,EACN,cAAe,GACf,aAAc,SACf,CAEG,EAAQ,WACV,EAAe,SAAW,CACxB,OAAQ,EAAQ,SAAS,OACzB,GAAI,EAAQ,SAAS,SACrB,KAAM,CAAE,OAAQ,EAAQ,SAAS,OAAQ,CAC1C,EAGC,EAAQ,UAAY,cACtB,EAAe,oBAAsB,kBAGnC,EAAQ,eACV,EAAe,MAAQ,CACrB,QAAS,GACT,QAAS,EAAQ,aACjB,GAAI,EAAQ,kBAAoB,CAAE,kBAAmB,EAAQ,kBAAmB,CAAG,EAAE,CACtF,EAGH,IAAM,EACJ,EAAQ,YAAc,EAAQ,WAC1B,CACE,WAAY,EAAQ,WACpB,WAAY,EAAQ,WACpB,WAAY,aACb,CACD,IAAA,GAMN,GAJI,IACF,EAAe,QAAU,CAAC,EAAO,EAG/B,CAAE,MAAM,EAAG,OAAO,EAAW,CAAG,CAClC,IAAM,EAAkC,CACtC,QAAS,kDACT,OAAQ,CAAC,EAAe,CACzB,CACD,MAAM,EAAG,UAAU,EAAY,GAAG,KAAK,UAAU,EAAa,KAAM,EAAE,CAAC,IAAI,CAC3E,OAGF,IAAM,EAAW,MAAM,EAAG,SAAS,EAAW,CACxC,EAASA,GAAW,EAAS,CAC7B,EAAc,MAAM,QAAQ,EAAO,OAAO,CAAG,EAAO,OAAS,CAAC,EAAO,OAAO,CAC5E,EAAgB,EAAY,UAAW,GAAU,EAAM,OAAS,EAAO,CAE7E,GAAI,IAAkB,GACpB,EAAY,KAAK,EAAe,KAC3B,CACL,IAAM,EAAY,EAAY,IAAkB,EAAE,CAC5C,EAAkB,MAAM,QAAQ,EAAS,QAAQ,CAAG,EAAS,QAAU,EAAE,CAC3E,EAAc,EACd,GAAU,CAAC,EAAgB,KAAM,GAAS,GAAM,aAAe,EAAO,WAAW,GACnF,EAAc,CAAC,GAAG,EAAiB,EAAO,EAE5C,EAAY,GAAiB,CAC3B,GAAG,EACH,GAAG,EACH,QAAS,EACV,CAIH,IAAM,EAAQ,GAAO,EAAU,CAAC,SAAS,CADtB,MAAM,QAAQ,EAAO,OAAO,CAAG,EAAe,EAAY,IAAM,EAC5B,CACrD,kBAAmB,CACjB,aAAc,GACd,QAAS,EACT,IAAK;EACN,CACF,CAAC,CACF,MAAM,EAAG,UAAU,EAAY,GAAW,EAAU,EAAM,CAAC,CAG7D,SAAgB,IAAqB,CACnC,IAAM,EAAa,CAAC,EAAK,QAAQ,EAAU,eAAe,CAAE,EAAK,QAAQ,EAAU,sBAAsB,CAAC,CAE1G,IAAK,IAAM,KAAa,EACtB,GAAI,CACF,IAAM,EAAc,KAAK,MAAM,EAAa,EAAW,OAAO,CAAC,CAC/D,GAAI,EAAY,SAAW,EAAY,UAAY,gBACjD,OAAO,EAAY,aAEf,EAKV,MAAO,gBC7QT,SAAgB,IAAwB,CACtC,MAAO,OAGT,SAAgB,IAAsB,CACpC,OAAO,QAAQ,SAAS,KAAK,MAAM,IAAI,CAAC,IAAM,KCEhD,SAAS,GAAsB,EAAwC,CACrE,MAAO,CACL,GAAI,EAAQ,GACZ,QAAS,EAAQ,QACjB,QAAS,OACT,YAAa,EAAE,CACf,iBAAkB,GAClB,kBAAmB,EAAE,CACtB,CAGH,SAAS,IAAuB,CAC9B,MAAO,CAAC,yFAA0F,GAAG,CAAC,KAAK;EAAK,CAGlH,MAAM,GAAuB,CAC3B,uBAAwB,SACxB,2BAA4B,SAC5B,KAAM,SACN,eAAgB,WAChB,iBAAkB,SAClB,YAAa,UACb,iBAAkB,SACnB,CAED,SAAgB,GACd,EACA,EACU,CACV,IAAM,EAAY,EAAK,QAAQ,EAAQ,IAAK,EAAQ,OAAO,CACrD,EAAa,IAAuB,CACpC,EAAW,GAAsB,EAAQ,CACzC,EAAwB,GAA0B,EAAQ,eAAe,CAEzE,EAAuC,CAC3C,KAAM,EAAQ,cACd,eAAgB,EAAQ,sBACpB,GAAG,EAAQ,eAAe,GAAG,EAAQ,wBACrC,IAAA,GACJ,iBAAkB,CAChB,YAAa,IAAoB,CACjC,gBAAiB,gBAClB,CACD,aAAc,EAAE,CAChB,gBAAiB,CACf,gBAAiB,EACjB,cAAe,IAAI,IAAqB,GACzC,CACF,CAoBD,OAlBI,EAAQ,UAAY,YACtB,OAAO,OAAO,EAAY,aAAc,GAAqB,CAC7D,EAAY,aAAa,wBAA0B,UACnD,EAAY,aAAa,eAAiB,UAGxC,EAAQ,UAAY,cACtB,OAAO,OAAO,EAAY,aAAc,GAAqB,CAC7D,EAAY,aAAa,oBAAsB,EAC/C,EAAY,aAAa,uBAAyB,EAClD,EAAY,aAAa,yBAA2B,WACpD,EAAY,aAAa,0BAA4B,WACrD,EAAY,aAAa,IAAM,KAC/B,EAAY,gBAAgB,qBAAuB,EACnD,EAAY,gBAAgB,qBAAuB,SACnD,EAAY,gBAAgB,UAAY,SAGnC,CACL,UACA,YACA,YAAa,EAAQ,YACrB,wBACA,cACA,WACA,QAAS,CACP,KAAM,EAAK,KAAK,EAAW,OAAO,CAClC,QAAS,IAAsB,CAChC,CACD,OAAQ,EAAE,CACV,SAAU,CACR,GAAI,EAAQ,UAAY,EAAE,CAAG,CAAC,CAAE,KAAM,UAAoB,CAAC,CAC3D,GAAI,EAAQ,aAAe,aAC3B,CAAC,EAAQ,oBACT,EAAE,EAAQ,UAAY,aAAe,EAAQ,gBAAkB,CAAC,EAAQ,4BACpE,CAAC,CAAE,KAAM,UAAoB,CAAC,CAC9B,EAAE,CACN,GAAI,EAAQ,MAAQ,EAAE,CAAG,CAAC,CAAE,KAAM,WAAqB,CAAC,CACzD,CACD,MAAO,CACL,mBAAoB,EAAQ,aAAe,aAAe,CAAC,EAAQ,mBACnE,oBAAqB,EAAQ,UAAY,YACzC,WAAY,CAAC,EAAQ,UACrB,kBACE,EAAQ,aAAe,aACvB,CAAC,EAAQ,oBACT,EAAE,EAAQ,UAAY,aAAe,EAAQ,gBAAkB,CAAC,EAAQ,4BAC1E,cAAe,CAAC,EAAQ,MACzB,CACD,UAAW,CACT,MAAM,EAAQ,SACd,GAAI,EAAQ,UAAY,CAAC,EAAQ,iBAAmB,OAAS,OAAS,GAAG,EAAQ,eAAe,UAAU,CAAG,EAAE,CAC/G,sCACA,EAA4B,EAAQ,eAAgB,MAAM,CAC1D,GAAI,EAAQ,UAAY,YACpB,CACE,EAA4B,EAAQ,eAAgB,UAAU,CAC9D,EAA4B,EAAQ,eAAgB,YAAY,CACjE,CACD,EAAE,CACN,EAA4B,EAAQ,eAAgB,WAAW,CAChE,CACF,CAGH,SAAgB,GACd,EACA,EACA,EAAwB,GACxB,CACA,EAAY,KAAO,EAAU,KAC7B,EAAY,iBAAmB,EAAU,iBACrC,EAAU,iBACZ,EAAY,eAAiB,EAAU,gBAGzC,AACE,EAAY,eAAe,EAAE,CAE/B,AACE,EAAY,kBAAkB,EAAE,CAGlC,IAAM,GAAS,EAAgC,IAAmC,CAChF,IAAK,GAAM,CAAC,EAAM,KAAY,OAAO,QAAQ,EAAO,EAC9C,GAAyB,EAAE,KAAQ,MACrC,EAAO,GAAQ,IAQrB,OAHA,EAAM,EAAY,aAAwC,EAAU,aAAa,CACjF,EAAM,EAAY,gBAA2C,EAAU,gBAAgB,CAEhF,EChIT,MAAM,GAAsB,IAAI,IAAI,CAAC,UAAW,UAAW,UAAW,cAAe,UAAW,YAAY,CAAC,CACvG,GAA8B,MAC9B,GAAoC,OACpCC,EAAQ,IAAI,GAAM,CAAE,MAAO,EAAG,CAAC,CAE/B,EAAiB,GAAoBA,EAAM,KAAK,EAAQ,CACxD,EAAiB,GAAoBA,EAAM,KAAK,EAAQ,CACxD,GAAc,GAAkBA,EAAM,OAAO,EAAM,CAEzD,SAAS,GAAgB,EAAgB,EAA4B,EAAE,CAAE,CACvE,IAAM,EAAQ,CACZ,GAAG,EAAc,gBAAgB,CAAC,GAAG,EAAc,MAAM,GAAW,EAAK,QAAQ,OAAO,GAAG,GAC3F,GACA,EAAc,eAAe,CAC7B,mHACA,KAAK,EAAc,sCAAsC,GAC1D,CA+BD,OA7BI,EAAK,QAAQ,WACf,EAAM,KACJ,GACA,EAAc,wBAAwB,CACtC,KAAK,EAAc,EAAK,QAAQ,iBAAmB,OAAS,OAAS,GAAG,EAAK,QAAQ,eAAe,UAAU,GAC/G,CAGH,EAAM,KAAK,GAAI,EAAc,iBAAiB,CAAE,KAAK,EAAc,GAAG,EAAK,sBAAsB,MAAM,GAAG,CAEtG,EAAK,QAAQ,UAAY,cAC3B,EAAM,KACJ,GACA,EAAc,qCAAqC,CACnD,KAAK,EAAc,GAAG,EAAK,sBAAsB,UAAU,GAC3D,KAAK,EAAc,GAAG,EAAK,sBAAsB,YAAY,GAC9D,CAEG,EAAgB,OAAS,GAC3B,EAAM,KAAK,GAAG,EAAgB,IAAK,GAAS,KAAK,EAAc,EAAK,GAAG,CAAC,EAI5E,EAAM,KACJ,GACA,EAAc,0BAA0B,CACxC,KAAK,EAAc,GAAG,EAAK,sBAAsB,WAAW,GAC7D,CAEM,EAAM,KAAK;EAAK,CAGzB,SAAS,GAA8B,EAAmB,CACxD,OAAO,EAAQ,OAAQ,GACjB,GAAoB,IAAI,EAAM,CACzB,GAEL,IAAU,aACL,GAET,CAAI,EAAM,WAAW,IAAI,CAIzB,CAGJ,MAAa,GAAoB,GAC/B,EAAO,IAAI,WAAa,CACtB,IAAM,EAAK,MAAO,EACZ,EAAiB,MAAO,EACxB,EAAa,MAAO,EACpB,EAAU,MAAO,EASvB,GANI,EADW,MAAO,EAAO,YAAc,EAAG,OAAO,EAAK,UAAU,CAAC,GAM3C,GADV,MAAO,EAAO,YAAc,EAAG,QAAQ,EAAK,UAAU,CAAC,CACP,CAC1C,SAAW,EAC/B,OAGF,GAAI,EAAK,QAAQ,MAAO,CACtB,MAAO,EAAO,YAAc,EAAG,SAAS,EAAK,UAAU,CAAC,CACxD,OAGF,GAAI,EAAW,eACb,MAAU,MACR,GAAG,EAAK,QAAQ,OAAO,6FACxB,CAGH,IAAM,EAAgB,MAAO,EAAO,YAClC,EAAQ,OAAO,CACb,QAAS,GAAG,EAAK,QAAQ,OAAO,iEAChC,QAAS,CACP,CAAE,MAAO,QAAS,MAAO,qBAAsB,CAC/C,CAAE,MAAO,QAAS,MAAO,mCAAoC,CAC7D,CAAE,MAAO,YAAa,MAAO,2CAA4C,CAC1E,CACF,CAAC,CACH,CAED,GAAI,IAAkB,QACpB,MAAM,IAAI,EAGZ,GAAI,IAAkB,QAAS,CAO7B,GAAI,EANc,MAAO,EAAO,YAC9B,EAAQ,QAAQ,CACd,QAAS,gDACT,aAAc,GACf,CAAC,CACH,EAEC,MAAM,IAAI,EAEZ,MAAO,EAAO,YAAc,EAAG,SAAS,EAAK,UAAU,CAAC,CACxD,OAGF,EAAe,KAAK,iBAAiB,EAAK,QAAQ,OAAO,iDAAiD,EAC1G,CAES,GAAmB,GAC9B,EAAO,IAAI,WAAa,CACtB,IAAM,EAAa,MAAO,EACpB,EAAK,MAAO,EACZ,EAAiB,MAAO,EACxB,EAAkB,MAAO,GACzB,EAAmB,MAAO,EAC1B,EAAiB,MAAO,GACxB,EAAa,MAAO,GACpB,EAAiB,MAAO,GACxB,EAAwB,MAAO,EAC/B,EAAgC,EAAE,CAExC,MAAO,GAAiB,EAAK,CAE7B,EAAe,KAAK,kBAAkB,EAAK,YAAY,CACvD,MAAO,EAAO,YAAc,EAAG,QAAQ,EAAK,YAAa,EAAK,UAAW,CAAE,UAAW,GAAM,CAAC,CAAC,CAE9F,IAAM,EAAkB,EAAK,KAAK,EAAK,UAAW,aAAa,CACzD,EAAiB,EAAK,KAAK,EAAK,UAAW,aAAa,EAC1D,MAAO,EAAO,YAAc,EAAG,OAAO,EAAgB,CAAC,KACrD,MAAO,EAAO,YAAc,EAAG,OAAO,EAAe,CAAC,EACxD,MAAO,EAAO,YAAc,EAAG,OAAO,EAAgB,CAAC,CAEvD,MAAO,EAAO,YAAc,EAAG,OAAO,EAAiB,EAAe,CAAC,EAI3E,IAAM,EAAkB,EAAK,KAAK,EAAK,UAAW,eAAe,CAE3D,EAAqB,GACzB,GAFkB,MAAO,EAAO,YAAc,EAAG,SAAkC,EAAgB,CAAC,CAEpD,EAAK,YAAY,CAClE,CACD,MAAO,EAAO,YAAc,EAAG,UAAU,EAAiB,EAAmB,CAAC,CAE9E,MAAO,EAAO,YAAc,EAAgB,cAAc,EAAK,UAAW,EAAK,SAAS,CAAC,CACzF,MAAO,EAAO,YAAc,EAAG,UAAU,EAAK,QAAQ,KAAM,EAAK,QAAQ,QAAQ,CAAC,CAClF,IAAK,IAAM,KAAS,EAAK,OACvB,MAAO,EAAO,YAAc,EAAG,UAAU,EAAM,KAAM,EAAM,QAAQ,CAAC,CAGtE,MAAO,EAAO,YAAc,EAAmB,EAAI,EAAK,UAAW,mBAAoB,EAAK,sBAAsB,CAAC,CACnH,MAAO,EAAO,YACZ,EAAmB,EAAI,EAAK,UAAW,sBAAuB,EAAK,QAAQ,eAAe,CAC3F,CACD,MAAO,EAAO,YAAc,EAAmB,EAAI,EAAK,UAAW,yBAA0B,EAAmB,CAAC,CAC7G,EAAK,QAAQ,cAAgB,OAC/B,MAAO,EAAO,YACZ,EAAmB,EAAI,EAAK,UAAW,KAAM,GAAqB,EAAK,QAAQ,YAAY,CAAC,CAC7F,CACD,MAAO,EAAO,YACZ,EACE,EACA,EAAK,UACL,KACA,EAAK,QAAQ,YACV,QAAQ,GAA6B,GAAG,CACxC,QAAQ,GAAmC,IAAI,CACnD,CACF,EAGH,IAAI,EAAe,EAAK,SACxB,GAAI,EAAK,MAAM,oBAAsB,EAAK,QAAQ,UAAW,CAC3D,IAAM,EAAkB,EAAK,QAAQ,UACrC,EAAe,MAAO,EAAO,YAC3B,EAAiB,UAAU,EAAK,UAAW,EAAc,EAAiB,EAAK,QAAQ,QAAQ,CAChG,CACD,MAAO,EAAO,YAAc,EAAgB,cAAc,EAAK,UAAW,EAAa,CAAC,CA4B1F,GAzBI,EAAK,MAAM,sBACb,MAAO,EAAO,QAAQ,SAAY,CAChC,GAAI,CACF,GAAM,CAAE,2BAA0B,6BAA8B,MAAM,OACpE,oCAGI,EAAW,EADF,MAAM,EAAyB,EAAK,UAAU,CACX,CAElD,IAAK,IAAM,KAAW,EAAS,KAC7B,EAAe,KAAK,EAAQ,CAE9B,IAAK,IAAM,KAAW,EAAS,KAC7B,EAAe,KAAK,EAAQ,CAE1B,EAAW,gBACb,EAAoB,KAAK,GAAG,EAAS,UAAU,OAE1C,EAAgB,CACvB,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CACtE,EAAe,KAAK,oDAAoD,EAAQ,IAAI,GAEtF,EAGA,EAAK,MAAM,WAAY,CACzB,IAAI,EAAwB,CAAC,UAAU,CACnC,EAAK,QAAQ,iBAAmB,SAClC,EAAc,EAAE,EAElB,MAAO,EAAO,YACZ,EAAe,IAAI,EAAK,QAAQ,eAAgB,EAAa,CAC3D,IAAK,EAAK,UACV,OAAQ,OACR,OAAQ,OACT,CAAC,CACH,CAGC,EAAK,MAAM,oBACb,MAAO,EAAO,YAAc,EAAe,WAAW,EAAK,UAAW,EAAK,QAAQ,eAAe,CAAC,EAGjG,EAAK,MAAM,gBACb,MAAO,EAAO,YAAc,EAAW,WAAW,EAAK,UAAU,CAAC,EAGpE,IAAM,EAAwB,MAAO,EAAO,YAC1C,EAAsB,WAAW,EAAK,QAAQ,eAAgB,EAAK,UAAU,CAC9E,CASD,OAPA,EAAe,QACb,WAAW,EAAK,QAAQ,cAAc,MAAM,EAAK,YAC/C,EAAwB,UAAU,EAAK,QAAQ,eAAe,GAAG,IAA0B,KAE9F,CACD,EAAe,KAAKA,EAAM,KAAK,cAAc,CAAC,CAC9C,EAAe,KAAK,GAAgB,EAAM,MAAM,KAAK,IAAI,IAAI,EAAoB,CAAC,CAAC,CAAC,CAC7E,GACP,CCrRE,GAAyB,OACzB,GAAuB,MACvB,GAAuB,6DAE7B,SAAS,GAAqB,EAAe,CAC3C,OAAO,EAAM,QAAQ,GAAsB,IAAI,CAGjD,SAAS,GAAoB,EAAe,CAC1C,OAAO,GAAqB,EAAM,CAAC,QAAQ,GAAwB,GAAG,CAGxE,SAAgB,GAAiB,EAA8D,CAE7F,IAAM,EADa,GAAoB,EAAY,CACvB,MAAM,IAAI,CAClC,EAAgB,EAAS,GAAG,GAAG,EAAI,GAEnC,IAAkB,MACpB,EAAgB,EAAK,SAAS,EAAK,QAAQ,QAAQ,KAAK,CAAC,CAAC,EAG5D,IAAM,EAAa,EAAS,UAAW,GAAY,EAAQ,WAAW,IAAI,CAAC,CACvE,IAAe,KACjB,EAAgB,EAAS,MAAM,EAAW,CAAC,KAAK,IAAI,EAGtD,IAAM,EAAS,EAAS,OAAQ,GAAY,CAAC,EAAQ,WAAW,IAAI,CAAC,CAAC,KAAK,IAAI,CAE/E,MAAO,CAAC,EAAe,EAAO,CAGhC,SAAgB,GAAgB,EAAqB,CACnD,IAAM,EAAa,GAAoB,EAAY,CACnD,GAAI,IAAe,IAAK,CACtB,IAAM,EAAiB,EAAK,SAAS,EAAK,QAAQ,QAAQ,KAAK,CAAC,CAAC,CACjE,OAAO,GAAqB,KAAK,EAAe,CAC5C,IAAA,GACA,4EAGN,IAAM,EAAW,EAAW,MAAM,IAAI,CAChC,EAAa,EAAS,UAAW,GAAY,EAAQ,WAAW,IAAI,CAAC,CACvE,EAAgB,EAAS,GAAG,GAAG,CAEnC,GAAI,IAAe,KACjB,EAAgB,EAAS,MAAM,EAAW,CAAC,KAAK,IAAI,EAGlD,IAAqB,KAAK,GAAiB,GAAG,CAIlD,MAAO,4EC9CT,MAAM,GAAyB,CAC7B,MAAO,GACP,UAAW,GACX,MAAO,GACP,QAAS,GACT,GAAI,GACJ,YAAa,KACd,CAED,SAAS,GAAc,EAAc,EAAe,CAClD,IAAM,EAAY,EAAK,MAAM,IAAI,CAAC,IAAK,GAAS,OAAO,SAAS,EAAM,GAAG,EAAI,EAAE,CACzE,EAAa,EAAM,MAAM,IAAI,CAAC,IAAK,GAAS,OAAO,SAAS,EAAM,GAAG,EAAI,EAAE,CAEjF,IAAK,IAAI,EAAQ,EAAG,EAAQ,KAAK,IAAI,EAAU,OAAQ,EAAW,OAAO,CAAE,GAAS,EAAG,CACrF,IAAM,EAAY,EAAU,IAAU,EAChC,EAAa,EAAW,IAAU,EACxC,GAAI,EAAY,EACd,MAAO,GAET,GAAI,EAAY,EACd,MAAO,GAIX,MAAO,GAGT,SAAS,GAAqB,EAAiB,CAI7C,GAHsB,EAAQ,EAAM,YACd,EAAQ,EAAM,WAGlC,MAAU,MAAM,kEAAkE,CAItF,eAAe,GAA6B,CAC1C,SACA,mBACA,QACA,kBAM2B,CAG3B,GAFA,GAAqB,EAAM,CAEvB,CAAC,EAAM,QAAU,EACnB,MAAU,MACR,+GACD,CAGH,IAAM,EACJ,EAAM,QACL,MAAM,EAAO,KAAK,CACjB,QAAS,4CACT,SAAW,GAAU,CACnB,GAAI,CACF,IAAM,EAAa,EAAM,WAAW,OAAO,CAAG,EAAQ,WAAW,IACjE,IAAI,IAAI,EAAW,CACnB,YACM,CACN,MAAO,6BAGZ,CAAC,CAEE,CAAE,gBAAe,YAAa,MAAM,EAAiB,wBAAwB,EAAU,CACvF,EAAY,IAAI,IAAI,EAAc,CAGpC,EAAe,EAAM,SACrB,EAAa,EAAM,WACnB,EAAa,EAAM,WACnB,EAAa,EAAM,WACnB,EACA,EAA4D,EAAE,CAC5D,MAA2B,CAC/B,GAAI,CAAC,EACH,MAAU,MAAM,uDAAuD,CAEzE,OAAO,GAGT,GAAI,EAAE,GAAgB,GAAa,CACjC,GAAI,EAAE,EAAM,aAAgB,EAAS,aAAe,GAAc,EAAS,YAAa,QAAQ,EAAI,GAClG,MAAU,MACR,8GACD,CAEH,EAAQ,EAAM,cAAgB,MAAM,EAAiB,gBAAgB,CAAE,IAAK,EAAW,CAAC,EAAE,MAG5F,GAAI,CAAC,EAAc,CACjB,GAAI,EACF,MAAU,MAAM,0FAA0F,CAG5G,EAAQ,MAAM,EAAiB,UAAU,CAAE,IAAK,EAAW,MAAO,GAAoB,CAAE,CAAC,CACzF,EAAe,MAAM,EAAO,aAAa,CACvC,QAAS,2CACT,QAAS,CACP,CACE,MAAO,eACP,MAAO,gCACP,KAAM,+CACN,SAAU,CAAC,OAAQ,WAAW,CAC/B,CACD,GAAG,EACA,OAAO,CACP,MAAM,EAAM,IAAU,EAAK,SAAS,cAAc,EAAM,SAAS,CAAC,CAClE,IAAK,IAAU,CACd,MAAO,EAAK,SACZ,MAAO,EAAK,SACZ,KAAM,EAAK,OACX,SAAU,CAAC,EAAK,SAAS,CAC1B,EAAE,CACN,CACF,CAAC,CAGJ,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,CAGpD,GAAI,IAAiB,eAAgB,CAC/B,EAAM,SAAW,IACnB,EAAQ,MAAM,EAAiB,UAAU,CAAE,IAAK,EAAW,MAAO,GAAoB,CAAE,CAAC,EAE3F,IAAM,EAAa,EAAM,KAAM,GAAS,EAAK,WAAa,qBAAa,CACjE,EACJ,GAAc,CAAC,EACX,MAAM,EAAO,QAAQ,CACnB,QAAS,6EACT,aAAc,GACf,CAAC,CACF,EACA,EAAW,MAAM,EAAiB,eAAe,CACrD,IAAK,EACL,MAAO,GAAoB,CAC3B,UAAW,EAAc,UAAY,UACtC,CAAC,CACF,EAAe,EAAS,SACxB,EAAa,EAAS,OACtB,IAAe,eACf,IAAe,WAGjB,GAAI,CAAC,GAAc,EACjB,MAAU,MAAM,6EAA6E,CAG/F,GAAI,CAAC,EAAY,CACf,IAAM,GAAW,MAAM,EAAiB,YAAY,CAAE,IAAK,EAAW,MAAO,GAAoB,CAAE,CAAC,EAAE,OACnG,GAAW,EAAO,WAAa,EACjC,CAEK,EACJ,EAAQ,SAAW,EACf,SACA,MAAM,EAAO,aAAa,CACxB,QAAS,oDACT,QAAS,CACP,GAAG,EAAQ,IAAK,IAAY,CAC1B,MAAO,EAAO,IACd,MAAO,GAAG,EAAO,MAAM,KAAK,EAAO,OACnC,KAAM,GAAG,EAAO,IAAI,MAAM,EAAG,EAAE,CAAC,KAAK,EAAO,IAAI,MAAM,GAAG,GACzD,SAAU,CAAC,EAAO,MAAO,EAAO,KAAM,EAAO,SAAS,CACvD,EAAE,CACH,CACE,MAAO,SACP,MAAO,uBACP,KAAM,+CACN,SAAU,CAAC,SAAU,MAAM,CAC5B,CACF,CACF,CAAC,CAER,GAAI,IAAc,SAAU,CAC1B,IAAM,EAAW,MAAM,EAAO,KAAK,CACjC,QAAS,8BAA8B,IACvC,SAAW,GAAW,EAAQ,IAAA,GAAY,8BAC3C,CAAC,CACI,EAAW,MAAM,EAAO,SAAS,CACrC,QAAS,0BAA0B,IACnC,SAAW,GAAW,EAAQ,IAAA,GAAY,yBAC3C,CAAC,CACF,GACE,MAAM,EAAiB,gCAAgC,CACrD,IAAK,EACL,SAAU,EACV,WACA,WACD,CAAC,EACF,YAEF,EAAa,EAIjB,GAAI,CAAC,EACH,MAAU,MAAM,0CAA0C,CAG5D,IAAM,EAAU,MAAM,EAAiB,YAAY,CACjD,aACA,OAAQ,EACR,OAAQ,EAAU,OACnB,CAAC,CAEF,GAAI,GAAc,CAAC,EAAQ,SAAS,EAAW,CAC7C,MAAU,MAAM,WAAW,EAAW,qBAAqB,EAAa,GAAG,CA2B7E,OAxBM,GAAkB,GAAc,GACN,MAAM,EAAO,QAAQ,CACjD,QAAS,sEACT,aAAc,GACf,CAAC,GAGA,EAAa,MAAM,EAAO,aAAa,CACrC,QAAS,oCACT,QAAS,EAAQ,IAAK,IAAY,CAChC,MAAO,EACP,MAAO,EACP,SAAU,CAAC,EAAO,CACnB,EAAE,CACJ,CAAC,CAEF,EAAa,MAAM,EAAO,KAAK,CAC7B,QAAS,8CACT,aAAc,GAAqB,EAAW,CAC9C,SAAW,GAAW,EAAQ,IAAA,GAAY,4BAC3C,CAAC,EAIC,CACL,KAAM,cACN,eAAgB,YAChB,SAAU,GAAyB,YAAY,CAC/C,OAAQ,EAAU,OAClB,SAAU,EACV,aACA,aACA,aACA,YAAa,EAAM,YACnB,WAAY,EAAS,WACrB,YAAa,EAAS,YACvB,CAGH,eAAe,GAAuB,CACpC,SACA,mBACA,QACA,UACA,kBAOC,CACD,GAAI,EAAM,aAAe,YACvB,MAAO,CAAE,UAAW,IAAA,GAAW,mBAAoB,GAAO,CAK5D,GAFA,GAAqB,EAAM,CAEvB,IAAY,aAAe,CAAC,EAAM,OACpC,OAAa,CACX,IAAM,EAAa,MAAM,EAAiB,kBAAkB,CAC5D,GAAI,EAAW,SAAW,EAAW,eAAe,GAClD,MAAO,CACL,UAAW,CACT,KAAM,eACN,eAAgB,YAChB,SAAU,GAAyB,YAAY,CAC/C,aAAc,EAAW,QACzB,SAAU,EAAW,eAAe,GACpC,WAAY,EAAM,WAClB,WAAY,EAAM,WACnB,CACD,mBAAoB,GACrB,CAGH,GAAI,EAOF,MANI,EAAW,QACH,MACR,2HACD,CAGO,MACR,2IACD,CAGH,IAAM,EAAiB,MAAM,EAAO,OAAO,CACzC,QAAS,EAAW,QAChB,+GACA,wEACJ,QAAS,CACP,CACE,MAAO,QACP,MAAO,YACP,KAAM,EAAW,QACb,8CACA,sCACL,CACD,CACE,MAAO,SACP,MAAO,6BACP,KAAM,4CACP,CACD,CACE,MAAO,OACP,MAAO,eACP,KAAM,mDACP,CACF,CACF,CAAC,CAEE,OAAmB,QAIvB,IAAI,IAAmB,OACrB,MAAO,CACL,UAAW,IAAA,GACX,mBAAoB,GACrB,CAGH,OAIJ,MAAO,CACL,UAAW,MAAM,GAA6B,CAC5C,SACA,mBACA,QACA,iBACD,CAAC,CACF,mBAAoB,GACrB,CAGH,MAAa,IAAsB,EAAe,IAChD,EAAO,IAAI,WAAa,CACtB,IAAM,EAAQ,CAAE,GAAG,GAAc,GAAG,EAAU,CACxC,EAAS,MAAO,EAChB,EAAmB,MAAO,EAC1B,EAAa,MAAO,EACpB,EAAiB,EAAW,gBAAkB,EAAM,IAAM,EAAM,iBAAmB,GAErF,EAAc,EAClB,GAAI,CAAC,EAAa,CAChB,GAAI,EACF,OAAO,MAAO,EAAO,KAAS,MAAM,oDAAoD,CAAC,CAG3F,EAAc,MAAO,EAAO,YAC1B,EAAO,KAAK,CACV,QAAS,oCACT,aAAc,EACd,SAAU,GACX,CAAC,CACH,CAGH,GAAI,CAAC,EACH,OAAO,MAAO,EAAO,KAAS,MAAM,4BAA4B,CAAC,CAGnE,IAAM,EAAkB,GAAgB,EAAY,CACpD,GAAI,EACF,OAAO,MAAO,EAAO,KAAS,MAAM,EAAgB,CAAC,CAGvD,IAAI,EAAmB,EAAM,SAAW,UAClC,EAAM,SAAW,IACrB,EAAU,MAAO,EAAO,YACtB,EAAO,OAAO,CACZ,QAAS,yCACT,QAAS,CACP,CACE,MAAO,UACP,MAAO,uBACP,KAAM,qCACP,CACD,CACE,MAAO,YACP,MAAO,uBACP,KAAM,sCACP,CACF,CACF,CAAC,CACH,CAAC,KAAK,EAAO,IAAK,GAAU,EAAiB,CAAC,EAGjD,IAAM,EAA6B,GACjC,EAAM,QAAU,EAAM,aAAe,EAAM,YAAc,EAAM,UAAY,EAAM,YAAc,EAAM,YAGnG,EAA6B,OA+BjC,GA9BI,EAAM,WACR,EAAa,EAAM,WACV,IAAY,cACrB,EAAa,GAA8B,EAAE,GAAkB,CAAC,EAAM,QAAU,YAAc,QAG5F,EAAE,GAAkB,EAAM,aAAe,IAAY,cACvD,EAAa,MAAO,EAAO,YACzB,EAAO,OAAO,CACZ,QAAS,sDACT,QAAS,CACP,CACE,MAAO,YACP,MAAO,MACP,KAAM,iDACP,CACD,CACE,MAAO,OACP,MAAO,KACP,KAAM,kCACP,CACF,CACF,CAAC,CACH,CAAC,KAAK,EAAO,IAAK,GAAU,EAAwB,CAAC,EAGpD,GAAkB,CAAC,EAAM,YAAc,GAIvC,GAAkB,IAAe,aAAe,EAClD,OAAO,MAAO,EAAO,KAAS,MAAM,2EAA2E,CAAC,CAGlH,GAAM,CAAE,YAAW,sBAAuB,MAAO,EAAO,YACtD,GAAuB,CACrB,SACA,mBACA,MAAO,CAAE,GAAG,EAAO,aAAY,CAC/B,UACA,iBACD,CAAC,CACH,CAEK,CAAC,EAAe,GAAU,GAAiB,EAAY,CAE7D,MAAO,CACL,cACA,gBACA,SACA,UACA,GAAI,EAAM,IAAM,SAChB,aACA,eAAgB,EAAW,eAC3B,UAAW,EAAM,UACjB,MAAO,EAAM,MACb,MAAO,EAAM,MACb,IAAK,EAAW,IAChB,YAAa,EAAM,YACnB,iBACA,MAAO,EAAW,MAClB,YACA,qBACA,6BACD,EACD,CCreJ,eAAsB,GAAY,EAA4B,CAC5D,GAAI,CACF,MAAM,GAAK,EAAI,MACT,GCFV,SAAS,GAAmB,CAC1B,OAAO,IAAI,GAAM,MAAM,CACrB,mBAAoB,QAAQ,IAAI,8BAAgC,IACjE,CAAC,CAGJ,eAAsB,EAAW,EAAa,EAAkE,CAO9G,OANiB,MAAM,EAAM,IAAO,EAAK,CACvC,QAAS,GAAS,QAClB,WAAY,GAAkB,CAC9B,QAAS,GAAS,SAAW,IAC7B,eAAgB,KACjB,CAAC,CAIJ,eAAsB,GACpB,EACA,EACA,EACA,CAOA,OANiB,MAAM,EAAM,KAAQ,EAAK,EAAM,CAC9C,QAAS,GAAS,QAClB,WAAY,GAAkB,CAC9B,QAAS,GAAS,SAAW,IAC7B,eAAgB,KACjB,CAAC,CAIJ,eAAsB,GAAW,EAAa,EAAkE,CAO9G,OANiB,MAAM,EAAM,OAAO,EAAK,CACvC,QAAS,GAAS,QAClB,WAAY,GAAkB,CAC9B,QAAS,GAAS,SAAW,IAC7B,eAAgB,KACjB,CAAC,CCrCJ,SAAgB,IAA2C,CACzD,IAAM,EAAY,QAAQ,IAAI,sBAe9B,OAbI,EACE,EAAU,WAAW,OAAO,CACvB,OAEL,EAAU,WAAW,OAAO,CACvB,OAEL,EAAU,WAAW,MAAM,CACtB,MAEF,MAGF,MCDT,MAAM,GAAgB,OAAO,IAAI,iCAAiC,CAErDC,GAAQC,GACRC,EAAMC,GACNC,GAAOC,GAEPC,GAAUC,GAEvB,SAAS,GAAe,EAAgB,CACtC,OAAO,aAAiB,OAAS,EAAM,OAAS,kBAGlD,SAAS,EAAsB,EAA2C,CACxE,OAAO,GAAI,CAAC,MAAO,GAAmB,CACpC,GAAI,GAAe,EAAM,CACvB,OAAO,GAET,MAAM,GACN,CAGJ,SAAgBC,GAAS,EAAiC,CACxD,OAAO,IAAU,IAAiBC,GAAc,EAAM,CAcxD,SAAS,GACP,EACmD,CAC9C,KAIL,MAAQ,IAAkB,EAAS,EAAM,EAAI,GAG/C,SAAS,GAAc,EAAoC,EAAe,CAExE,MADiB,CAAC,EAAO,MAAO,EAAO,MAAQ,GAAI,GAAI,EAAO,UAAY,EAAE,CAAE,CAAC,KAAK,IAAI,CAAC,aAAa,CACtF,SAAS,EAAM,MAAM,CAAC,aAAa,CAAC,CAGtD,SAAS,EAAyB,EAAqC,CAIrE,OAHI,OAAO,GAAU,SACZ,EAEF,EAAQ,GAAO,IAAA,GAGxB,SAAgB,GACd,EACA,EACA,CACA,IAAM,EAAO,GAAO,MAAM,CAK1B,OAJK,EAIE,EAAQ,OAAQ,GAAW,GAAc,EAAQ,EAAK,CAAC,CAHrD,EAMX,SAAgB,GAAW,EAIxB,CACD,OAAO,MACLC,GAAc,CACZ,QAAS,EAAQ,QACjB,QAAS,EAAQ,aACjB,SAAU,GAAkB,EAAQ,SAAS,CAC9C,CAAC,CACH,CAGH,SAAgB,GAAe,EAAgF,CAC7G,OAAO,MACLC,GAAiB,CACf,QAAS,EAAQ,QACjB,SAAU,GAAkB,EAAQ,SAAS,CAC9C,CAAC,CACH,CAGH,SAAgB,GAAc,EAAsD,CAClF,OAAO,MACLC,GAAgB,CACd,QAAS,EAAQ,QACjB,QAAS,EAAQ,aAClB,CAAC,CACH,CAGH,SAAgB,GAA+B,EAA0D,CACvG,OAAO,MACLC,GAAkB,CAChB,QAAS,EAAQ,QACjB,SAAU,GACV,QAAS,EAAQ,QAAQ,IAAK,IAAY,CACxC,MAAO,EAAO,MACd,KAAM,EAAO,MACb,YAAa,EAAO,KACpB,SAAU,EAAyB,EAAO,SAAS,CACpD,EAAE,CACJ,CAAC,CACH,CAGH,SAAgB,GAAqC,EAIlD,CACD,OAAO,MACLC,GAAkB,CAChB,QAAS,EAAQ,QACjB,SAAU,GACV,OAAS,GAAU,CACjB,IAAM,EAAW,GAAoB,EAAQ,QAAS,EAAM,CAW5D,OAVI,EAAS,SAAW,EACf,CACL,CACE,MAAO,iBACP,KAAM,EAAQ,cAAgB,uDAC9B,SAAU,EAAQ,cAAgB,mBACnC,CACF,CAGI,EAAS,IAAK,IAAY,CAC/B,MAAO,EAAO,MACd,KAAM,EAAO,MACb,YAAa,EAAO,KACpB,SAAU,EAAyB,EAAO,SAAS,CACpD,EAAE,EAEN,CAAC,CACH,CAGH,SAAgB,GAA0C,EAIvD,CACD,OAAO,MACLC,GAAoB,CAClB,QAAS,EAAQ,QACjB,SAAU,GACV,SAAU,EAAQ,SAClB,QAAS,EAAQ,QAAQ,IAAK,IAAY,CACxC,MAAO,EAAO,MACd,KAAM,EAAO,MACb,YAAa,EAAO,KACpB,SAAU,EAAyB,EAAO,SAAS,CACpD,EAAE,CACJ,CAAC,CACH,CC7IH,SAAS,EAAU,EAAsB,CACvC,GAAIC,GAAS,EAAM,CACjB,MAAM,IAAI,EAEZ,OAAO,EAGT,SAAS,GAAa,EAAmB,CAOvC,OANI,EAAU,WAAW,WAAW,CAC3B,EAEL,EAAU,WAAW,UAAU,CAC1B,EAAU,QAAQ,UAAW,WAAW,CAE1C,WAAW,IASpB,SAAS,GAAoB,EAAmC,CAC9D,IAAM,EAAW,GACX,EAAO,WAAa,IACA,MAAM,QAAQ,EAAO,kBAAkB,CAAG,EAAO,kBAAoB,EAAE,EACxE,QAAS,GAAS,EAAQ,EAAK,CAAC,CAEhD,OAAO,EAAO,MAAS,SAAW,CAAC,EAAO,KAAK,CAAG,EAAE,CAG7D,OAAO,EAAQ,QAAQ,EAAQ,CAAC,MAAM,EAAM,IAAU,EAAK,cAAc,EAAM,CAAC,CAGlF,MAAM,GAAgB,CACpB,KAAM,KAAO,IACX,EACE,MAAM,GAAW,CACf,QAAS,EAAQ,QACjB,aAAc,EAAQ,aACtB,SAAU,EAAQ,SACnB,CAAC,CACH,CAAC,UAAU,CACd,SAAU,KAAO,IACf,EACE,MAAM,GAAe,CACnB,QAAS,EAAQ,QACjB,SAAU,EAAQ,SACnB,CAAC,CACH,CAAC,UAAU,CACd,OAAQ,KAAyB,IAI/B,EACE,MAAM,GAAa,CACjB,QAAS,EAAQ,QACjB,QAAS,EAAQ,QAClB,CAAC,CACH,CACH,aAAc,KAAyB,IAIjC,EAAO,MAAM,GAAmB,EAAQ,CAAC,CAC/C,kBAAmB,KAAyB,IAItC,EAAO,MAAM,GAAwB,EAAQ,CAAC,CACpD,QAAS,KAAO,IACd,EACE,MAAM,GAAc,CAClB,QAAS,EAAQ,QACjB,aAAc,EAAQ,aACvB,CAAC,CACH,CACJ,CAEK,GAAiB,CACrB,KAAO,GAAoBC,EAAI,KAAK,EAAQ,CAC5C,KAAO,GAAoBA,EAAI,KAAK,EAAQ,CAC5C,MAAQ,GAAoBA,EAAI,MAAM,EAAQ,CAC9C,QAAU,GAAoBA,EAAI,QAAQ,EAAQ,CAClD,MAAO,EAAiB,IAAmBC,GAAK,EAAS,EAAM,CAChE,CAEK,EAAoB,CACxB,OAAQ,KAAO,IAAuBC,EAAG,WAAW,EAAW,CAC/D,QAAS,KAAO,IAAuBA,EAAG,QAAQ,EAAW,CAC7D,SAAU,KAAO,IAAuBA,EAAG,SAAS,EAAW,CAC/D,QAAS,MAAO,EAAc,EAAY,IACxCA,EAAG,KAAK,EAAM,EAAI,CAAE,UAAW,GAAS,WAAa,GAAM,CAAC,CAC9D,OAAQ,MAAO,EAAc,IAAeA,EAAG,OAAO,EAAM,EAAG,CAC/D,OAAQ,KAAO,IAAuBA,EAAG,OAAO,EAAW,CAC3D,SAAU,KAAU,IAAuBA,EAAG,SAAS,EAAW,CAClE,UAAW,MAAO,EAAoB,IAAmBA,EAAG,UAAU,EAAY,EAAO,CAAE,OAAQ,EAAG,CAAC,CACvG,UAAW,MAAO,EAAoB,IAAoBA,EAAG,UAAU,EAAY,EAAS,OAAO,CACnG,SAAU,KAAO,IAAuBA,EAAG,SAAS,EAAY,OAAO,CACxE,CAEK,GAAkB,CACtB,gBAAiB,EAAkB,IAC7B,IAAY,YACP,EAAK,KAAK,EAAe,UAAU,CAExC,IAAO,UACF,EAAK,KAAK,EAAe,iBAAiB,CAE5C,EAAK,KAAK,EAAe,gBAAgB,CAEnD,CAEK,GAAwB,CAC5B,WAAY,MAAO,EAAwB,IAAgB,CACzD,GAAI,IAAmB,MACrB,OAEF,GAAM,CAAE,UAAW,MAAM,EAAM,EAAgB,CAAC,KAAK,CAAE,CAAE,MAAK,CAAC,CAC/D,OAAO,EAAO,MAAM,EAEvB,CAEK,GAAiB,CACrB,IAAK,MACH,EACA,EACA,IAKG,CACH,IAAM,EAAS,MAAM,EAAM,EAAS,EAAM,CACxC,IAAK,EAAQ,IACb,OAAQ,EAAQ,QAAU,OAC1B,OAAQ,EAAQ,QAAU,OAC3B,CAAC,CACF,MAAO,CACL,OAAQ,EAAO,QAAU,GACzB,OAAQ,EAAO,QAAU,GAC1B,EAEJ,CAEK,GAAa,CACjB,WAAY,KAAO,IAAuB,CACxC,MAAM,EAAM,MAAO,CAAC,OAAO,CAAE,CAAE,IAAK,EAAY,CAAC,CACjD,MAAM,EAAM,MAAO,CAAC,MAAO,IAAI,CAAE,CAAE,IAAK,EAAY,CAAC,CACrD,MAAM,EAAM,MAAO,CAAC,SAAU,KAAM,iBAAiB,CAAE,CAAE,IAAK,EAAY,CAAC,EAE9E,CAEK,GAAkB,CACtB,cAAe,MAAO,EAAoB,IACxCA,EAAG,UAAU,EAAK,KAAK,EAAY,gBAAgB,CAAE,EAAU,CAAE,OAAQ,EAAG,CAAC,CAC/E,cAAe,MAAO,EAAoB,IAAiC,CACzE,IAAM,EAAU,EAAK,KAAK,EAAY,OAAO,CACvC,EAAY,MAAMA,EAAG,WAAW,EAAQ,CAAI,MAAMA,EAAG,SAAS,EAAS,OAAO,CAAG,GACjF,EAAY,OAAO,QAAQ,EAAK,CACnC,KAAK,CAAC,EAAM,KAAW,GAAG,EAAK,GAAG,IAAQ,CAC1C,KAAK;EAAK,CACP,EAAc,CAAC,EAAS,SAAS,CAAE,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK;EAAK,CAAC,OAAO;EAAK,CAC3F,MAAMA,EAAG,UAAU,EAAS,EAAa,OAAO,EAElD,oBAAqB,MAAO,EAAqB,IAC/C,IAAA,GACH,CAED,SAAS,GAAsB,EAAwB,CACrD,MAAO,CACL,KAAM,KACN,KAAM,EACN,SAAU,GAAyB,EAAe,CACnD,CAGH,SAAS,GACP,EACA,EACA,EACsC,CACtC,IAAM,EAAkB,GAAsB,EAAO,eAAe,CAC9D,EAAiC,CACrC,GAAG,EACH,YAAa,EAAS,YAAY,KAAM,GAAU,EAAM,OAAS,EAAgB,KAAK,CAClF,EAAS,YACT,CAAC,GAAG,EAAS,YAAa,EAAgB,CAC/C,CAmBD,OAjBI,EAAO,OAAS,eACX,QAAQ,QAAQ,CACrB,SAAU,EACV,QAAS,EAAE,CACX,iBAAkB,EAAE,CACpB,cAAe,CACb,KAAM,EAAO,KACb,eAAgB,EAAO,eACvB,aAAc,EAAO,aACrB,kBAAmB,EAAO,SAC1B,WAAY,EAAO,WACnB,WAAY,EAAO,WACnB,UACD,CACF,CAAC,CAGG,QAAQ,QAAQ,CACrB,SAAU,EACV,QAAS,EACN,EAAO,SAAS,UAAW,EAAO,UAClC,EAAO,SAAS,QAAS,EAAO,QAChC,EAAO,SAAS,QAAS,EAAO,WAClC,CACD,iBAAkB,CAChB,CACE,KAAM,EAAO,SAAS,SACtB,UAAW,gCACX,aAAc,EAAO,SACtB,CACD,CACE,KAAM,EAAO,SAAS,OACtB,UAAW,mBACX,aAAc,EAAO,OACtB,CACD,CACE,KAAM,EAAO,SAAS,OACtB,UAAW,+BACX,aAAc,EAAO,WACtB,CACF,CACD,cAAe,CACb,KAAM,EAAO,KACb,eAAgB,EAAO,eACvB,SAAU,EAAO,SACjB,WAAY,EAAO,WACnB,WAAY,EAAO,WACnB,UACD,CACF,CAAC,CAGJ,MAAM,EAAmB,CACvB,iBAAkB,MAAO,EAAU,QAAQ,IAAI,iBAAmB,0BAA4B,CAC5F,GAAI,CAEF,GAAI,EADW,MAAM,MAAM,GAAG,EAAQ,SAAU,CAAE,OAAQ,YAAY,QAAQ,IAAK,CAAE,CAAC,EAC1E,GACV,MAAO,CAAE,UAAS,QAAS,GAAO,eAAgB,EAAE,CAAE,CAExD,IAAM,EAAiB,MAAM,MAAM,GAAG,EAAQ,iBAAkB,CAAE,OAAQ,YAAY,QAAQ,IAAK,CAAE,CAAC,CACnG,KAAK,KAAO,IAAc,EAAS,GAAO,MAAM,EAAS,MAAM,CAAgB,EAAE,CAAE,CACnF,UAAY,EAAE,CAAC,CAClB,MAAO,CACL,UACA,QAAS,GACT,eAAgB,MAAM,QAAQ,EAAe,CACzC,EAAe,OAAQ,GAAyB,OAAO,GAAS,SAAS,CACzE,EAAE,CACP,MACK,CACN,MAAO,CAAE,UAAS,QAAS,GAAO,eAAgB,EAAE,CAAE,GAG1D,wBAAyB,MAAO,EAAmB,IAA6B,CAC9E,IAAM,EAAgB,GAAa,EAAU,CAGvC,GADc,MAAM,EADX,IAAI,IAAI,mBAAoB,EAAc,CAAC,UAAU,CACY,EAC9C,MAAM,MAAM,eAAe,MAAM,IAAI,CAAC,GACxE,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,IAAgB,CAGnE,IAAI,EAA6B,KAMjC,GAFA,GAHsB,MAAM,EAC1B,IAAI,IAAI,iBAAkB,EAAc,CAAC,UAAU,CACpD,CAAC,UAAY,IAAA,GAAU,GACK,MAAM,UAAU,MAAM,SAAW,KAE1D,CAAC,EAAa,CAChB,IAAM,EAAW,IAAI,IAAI,EAAc,CACvC,EAAS,KAAO,EAAW,OAAO,EAAS,CAAG,OAC9C,EAAS,SAAW,iBAEpB,GADsB,MAAM,EAAyC,EAAS,UAAU,CAAC,CAAC,UAAY,IAAA,GAAU,GACnF,MAAM,MAAM,SAAW,KAGtD,MAAO,CACL,cAAe,IAAI,IAAI,EAAc,CAAC,OACtC,SAAU,CACR,WAAY,EACZ,cACD,CACF,EAEH,gBAAiB,MAAO,CAAE,SAAwB,CAChD,IAAM,EAAO,IAAY,CAAC,WAAW,IAAK,GAAG,CAAC,MAAM,EAAG,GAAG,CACpD,EAAW,IAAI,IAAI,gBAAgB,IAAQ,EAAI,OAAO,CAC5D,EAAI,KAAK,8EAA8E,EAAS,UAAU,GAAG,CAC7G,MAAM,GAAY,EAAS,UAAU,CAAC,CAEtC,IAAM,EAAOC,IAAe,CAC5B,EAAK,MAAM,4BAA4B,CAEvC,IAAM,EAAW,KAAK,KAAK,CAAG,KAC9B,KAAO,KAAK,KAAK,CAAG,GAAU,CAK5B,IAAM,GAJW,MAAM,EACrB,GAAG,EAAI,OAAO,0BAA0B,IACxC,CAAE,QAAS,CAAE,kBAAmB,UAAW,CAAE,QAAS,IAAM,CAC7D,CAAC,UAAY,IAAA,GAAU,GACA,MAAM,UAAU,MACxC,GAAI,EAKF,OAJA,EAAK,KAAK,iBAAiB,CAC3B,MAAM,GAAW,GAAG,EAAI,OAAO,0BAA0B,IAAQ,CAC/D,QAAS,CAAE,kBAAmB,UAAW,CAC1C,CAAC,CAAC,UAAY,IAAA,GAAU,CAClB,CAAE,QAAO,CAElB,MAAM,IAAI,QAAS,GAAY,WAAW,EAAS,IAAI,CAAC,CAI1D,MADA,EAAK,KAAK,kBAAkB,CAClB,MAAM,2CAA2C,EAE7D,UAAW,MAAO,CAAE,MAAK,aACN,MAAM,EACrB,GAAG,EAAI,OAAO,kCACd,CACE,QAAS,CACP,cAAe,UAAU,IAC1B,CACF,CACF,EAC2B,MAAM,UAAU,WAAa,EAAE,EAExD,OAAQ,GAAgE,OAAO,EAAS,UAAa,SAAS,CAC9G,IACE,IACE,CACC,SAAU,EAAS,SACnB,OAAQ,EAAS,QAAU,UAC5B,EACJ,CAEL,YAAa,MAAO,CAAE,MAAK,aACR,MAAM,EACrB,GAAG,EAAI,OAAO,mBACd,CACE,QAAS,CACP,cAAe,UAAU,IAC1B,CACF,CACF,EACyB,MAAM,WAAW,aAAe,EAAE,EAEzD,OACE,GACC,OAAO,EAAO,KAAQ,UACtB,OAAO,EAAO,MAAS,UACvB,OAAO,EAAO,UAAa,UAC3B,OAAO,EAAO,OAAU,SAC3B,CACA,IACE,IACE,CACC,IAAK,EAAO,IACZ,KAAM,EAAO,KACb,SAAU,EAAO,SACjB,MAAO,EAAO,MACf,EACJ,CAEL,gCAAiC,MAAO,CACtC,MACA,WACA,WACA,SAAU,KAMN,CAOJ,IAAM,GANW,MAAM,GAA0C,GAAG,EAAI,OAAO,+BAAgC,CAC7G,SAAU,EACV,MAAO,iBACP,KAAM,EACN,KAAM,EACP,CAAC,EACsB,MAAM,UAAU,IACxC,GAAI,CAAC,EACH,MAAU,MAAM,uCAAuC,EAAS,GAAG,CAErE,MAAO,CAAE,SAAQ,EAEnB,gBAAiB,MAAO,CAAE,UAAS,MAAK,WACtC,GAAyD,GAAG,EAAI,OAAO,sBAAuB,EAAS,CACrG,QAAS,CACP,cAAe,UAAU,IAC1B,CACF,CAAC,CACJ,oBAAqB,MAAO,CAAE,MAAK,QAAO,kBACxC,EACE,GAAG,EAAI,OAAO,uBAAuB,IACrC,CACE,QAAS,CACP,cAAe,UAAU,IAC1B,CACF,CACF,CACH,eAAgB,MAAO,CAAE,MAAK,QAAO,eAA+E,CAClH,IAAM,EAAe,qBACf,EAAOA,IAAe,CAC5B,EAAK,MAAM,+BAA+B,CAE1C,IAAM,EAAoB,CACxB,UAAW,GACX,MAAO,wBACP,YAAa,CACX,CACE,KAAM,wBACN,OAAQ,CACN,KAAM,MACN,IAAK,mDACN,CACD,eAAgB,CACd,CACE,OAAQ,CACN,SAAU,EACX,CACD,YACA,OAAQ,CACN,SAAU,EACX,CACD,SAAU,CACR,OAAQ,UACR,UAAW,GACZ,CACF,CACF,CACD,YAAa,EACb,QAAS,CACP,qBAAsB,GACtB,6BAA8B,GAC9B,sBAAuB,GACxB,CACF,CACF,CACD,eAAgB,GACjB,CAQK,GANa,MAAM,EAAiB,gBAAgB,CACxD,QAAS,EACT,MACA,QACD,CAAC,EAE8B,MAAM,UAAU,mBAAmB,GACnE,GAAI,CAAC,EAEH,MADA,EAAK,KAAK,yBAAyB,CACzB,MAAM,8DAA8D,CAGhF,IAAM,EAAqB,KAAK,KAAK,CAAG,IACpC,EAAsB,GAC1B,KAAO,KAAK,KAAK,CAAG,GAAoB,CACtC,MAAM,IAAI,QAAS,GAAY,WAAW,EAAS,KAAK,CAAC,CACzD,IAAM,EAAS,MAAM,EAAiB,oBAAoB,CACxD,MACA,QACA,eACD,CAAC,CAEF,GAAI,CAAC,EAAO,MAAM,UAAU,QAAS,CACnC,GAAI,EAAO,MAAM,UAAU,SAAW,WAEpC,MADA,EAAK,KAAK,yBAAyB,CACzB,MAAM,0DAA0D,CAE5E,EAAsB,GACtB,OAIJ,GAAI,CAAC,EAEH,MADA,EAAK,KAAK,4BAA4B,CAC5B,MAAM,sDAAsD,CAGxE,IAAM,EAAS,MAAM,EAAiB,gCAAgC,CACpE,MACA,SAAU,EACV,SAAU,QACV,SAAU,QACX,CAAC,CAEF,OADA,EAAK,KAAK,qBAAqB,CACxB,CAAE,OAAQ,EAAO,OAAQ,SAAU,EAAc,EAE1D,YAAa,MAAO,CAAE,aAAY,SAAQ,YASjC,IARU,MAAM,EACrB,GAAG,EAAO,mCAAmC,mBAAmB,EAAO,CAAC,UACxE,CACE,QAAS,CACP,cAAe,UAAU,IAC1B,CACF,CACF,EACmC,MAAM,UAAU,SAAW,EAAE,CAAC,CAEpE,qCACA,UAAW,MAAO,EAAoB,EAA4B,EAAyB,IAAqB,CAC9G,IAAM,EAAY,MAAM,GAAkC,EAAU,EAAQ,EAAQ,CAgBpF,OAfI,OAAO,KAAK,EAAU,QAAQ,CAAC,OAAS,IAC1C,MAAM,GAAgB,cAAc,EAAY,EAAU,QAAQ,CAClE,MAAM,GAAoB,EAAmB,EAAY,EAAU,iBAAiB,EAGtF,MAAM,GAAoB,EAAmB,EAAY,CACvD,QAAS,EAAU,cAAc,QACjC,eAAgB,EAAU,cAAc,eACxC,SAAU,EAAU,cAAc,SAClC,aAAc,EAAU,cAAc,aACtC,kBAAmB,EAAU,cAAc,kBAC3C,WAAY,EAAU,cAAc,WACpC,WAAY,EAAU,cAAc,WACrC,CAAC,CAEK,EAAU,UAEpB,CAEK,GAAiB,CACrB,WAAY,MAAO,EAAoB,IAAsD,CAC3F,IAAI,EACJ,AAKE,EALE,IAAmB,MACN,CAAC,MAAO,MAAO,UAAU,CAC/B,IAAmB,MACb,CAAC,MAAO,MAAO,UAAU,CAEzB,CAAC,EAAgB,UAAU,CAE5C,IAAM,EAAU,EAAa,GAC7B,GAAI,CAAC,EACH,MAAU,MAAM,wCAAwC,CAG1D,MAAM,EAAM,EADC,EAAa,MAAM,EAAE,CACP,CAAE,IAAK,EAAY,CAAC,EAElD,CAED,SAAgB,EAAc,EAAmE,CAC/F,IAAM,EAA8B,CAClC,IAAK,EAAQ,IACb,MAAO,EAAQ,MACf,eAAgB,EAAQ,eACxB,eAAgB,IAA0B,CAC3C,CAEK,EAAQ,EAAM,SAClB,EAAM,QAAQ,EAAY,EAAW,CACrC,EAAM,QAAQ,EAAe,GAAc,CAC3C,EAAM,QAAQ,EAAgB,GAAe,CAC7C,EAAM,QAAQ,EAAmB,EAAkB,CACnD,EAAM,QAAQ,GAAiB,GAAgB,CAC/C,EAAM,QAAQ,EAAuB,GAAsB,CAC3D,EAAM,QAAQ,GAAgB,GAAe,CAC7C,EAAM,QAAQ,GAAY,GAAW,CACrC,EAAM,QAAQ,GAAiB,GAAgB,CAC/C,EAAM,QAAQ,EAAkB,EAAiB,CACjD,EAAM,QAAQ,GAAgB,GAAe,CAC9C,CAED,MAAiB,IAAmC,EAAO,QAAQ,EAAQ,EAAM,CC3lBnF,MAAa,EAAgB,GAAS,OAAO,OAN1B,CACjB,OAAQ,UACR,YAAa,UACb,OAAQ,UACT,CAE8D,CAAC,CAChE,SAAgB,GAAY,EAAU,gBAAiB,CACrD,IAAM,EAAa,IAA0B,EACzC,IAAe,QAAU,IAAe,SAC1C,QAAQ,IAAI,GAAG,CAEjB,QAAQ,IAAI,EAAc,UAAU,EAAa,EAAQ,CAAC,CAAC,CCuB7D,MAAM,EAA4B,CAChC,MAAO,GACP,UAAW,GACX,MAAO,GACP,QAAS,GACT,GAAI,GACJ,YAAa,KACd,CAED,SAAS,IAAgB,CACvB,GAAI,CACF,IAAM,EAAiB,IAAI,IAAI,kBAAmB,OAAO,KAAK,IAAI,CAElE,OADoB,KAAK,MAAM,EAAa,EAAc,EAAe,CAAE,OAAO,CAAC,CAChE,SAAW,qBACxB,CACN,MAAO,iBAIX,MAAa,GAAW,EAAe,IACrC,EAAO,IAAI,WAAa,CACtB,IAAM,EAAkB,MAAO,GACzB,EAAwB,MAAO,EAC/B,EAAU,MAAO,GAAmB,EAAM,CAAE,GAAG,EAAiB,GAAG,EAAU,CAAC,CAK9E,EAAO,GAAS,EAAS,CAAE,YAJb,EAAgB,eAAe,EAAQ,QAAS,EAAQ,GAAG,CAIjC,sBAHhB,MAAO,EAAO,YAC1C,EAAsB,WAAW,EAAQ,eAAgB,EAAQ,IAAI,CACtE,CACoE,CAAC,CAEtE,OADA,MAAO,GAAgB,EAAK,CACrB,CAAE,UAAS,OAAM,EACxB,CAES,GAAqB,GAChC,EAAO,IAAI,WAAa,CACtB,IAAM,EAAa,MAAO,EACpB,EAAY,MAAO,EACnB,EAAiB,MAAO,EACxB,EAAQ,CAAE,GAAG,EAAiB,GAAG,EAAU,CAEjD,GAAI,EAAW,gBAAkB,EAAM,IAAM,EAAM,eACjD,MAAU,MACR,6IACD,CAGH,IAAM,EAAe,EAAK,KAAK,EAAW,IAAK,gBAAgB,CAG/D,GAF2B,MAAO,EAAO,YAAc,EAAU,OAAO,EAAa,CAAC,CAE9D,CACtB,GAAM,SAAS,EAAc,WAAW,CAAC,UAAU,CACnD,EAAe,KACb,CACE,yEACA,mIACD,CAAC,KAAK;EAAK,CACZ,mBACD,CACD,OAGF,GAAM,MAAM,EAAc,WAAW,CAAC,kCAAkC,CACxE,MAAO,EAAQ,IAAA,GAAW,CACxB,GAAG,EACH,QAAS,GACV,CAAC,EACF,CAEE,GAAmBC,EAAYC,EAAQ,CAAE,KAAM,MAAO,CAAC,CAAC,CAAC,KAC7DC,EAAmB,uCAAuC,CAC3D,CAED,SAAS,EAAmB,EAAc,EAAqB,CAC7D,OAAOC,GAAeC,GAAW,EAAK,CAAC,KAAKC,EAAsB,EAAY,CAAC,CAAC,CAGlF,SAAS,GAAwD,EAAc,EAAkB,EAAqB,CACpH,OAAOF,GAAeG,EAAa,EAAM,EAAQ,CAAC,KAAKD,EAAsB,EAAY,CAAC,CAAC,CAG7F,SAAS,EAAgB,EAA6B,EAAyD,CAC7G,OAAO,EAAc,CACnB,IAAK,QAAQ,KAAK,CAClB,MAAO,GAAS,QAAU,GAC1B,eAAgB,GAAS,iBAAmB,GAC7C,CAAC,CAAC,EAAO,QAAQ,EAAU,CAAC,CAG/B,SAAS,IAAkB,CACzB,OAAOE,EACL,OACA,CACE,IAAK,GACL,QAAS,GAAqB,WAAY,CAAC,UAAW,YAAY,CAAW,4BAA4B,CACzG,GAAI,GAAqB,KAAM,CAAC,SAAU,UAAU,CAAW,4BAA4B,CAC3F,OAAQ,EAAmB,SAAU,mCAAmC,CACxE,YAAa,EAAmB,gBAAiB,4BAA4B,CAC7E,SAAU,EAAmB,YAAa,iCAAiC,CAC3E,WAAY,EAAmB,cAAe,wCAAwC,CACtF,WAAY,EAAmB,cAAe,4BAA4B,CAC1E,WAAY,EAAmB,eAAgB,+BAA+B,CAC9E,WAAY,GAAqB,cAAe,CAAC,YAAa,OAAO,CAAW,yBAAyB,CACzG,MAAOC,EAAc,SAAS,CAAC,KAAKH,EAAsB,0BAA0B,CAAC,CACrF,UAAWG,EAAc,aAAa,CAAC,KAAKH,EAAsB,4BAA4B,CAAC,CAC/F,MAAOG,EAAc,QAAQ,CAAC,KAC5B,GAAU,IAAI,CACdH,EAAsB,kEAAkE,CACzF,CACD,GAAIG,EAAc,KAAK,CAAC,KAAKH,EAAsB,yCAAyC,CAAC,CAC7F,eAAgBG,EAAc,kBAAkB,CAAC,KAC/CH,EAAsB,gEAAgE,CACvF,CACD,MAAOG,EAAc,QAAQ,CAAC,KAAKH,EAAsB,oBAAoB,CAAC,CAC/E,EACA,CAAE,MAAK,GAAG,KAAc,CACvB,IAAM,EAAkB,CACtB,GAAG,EACH,QAAS,EAAe,EAAQ,QAAQ,CACxC,GAAI,EAAe,EAAQ,GAAG,CAC9B,OAAQ,EAAe,EAAQ,OAAO,CACtC,YAAa,EAAe,EAAQ,YAAY,CAChD,SAAU,EAAe,EAAQ,SAAS,CAC1C,WAAY,EAAe,EAAQ,WAAW,CAC9C,WAAY,EAAe,EAAQ,WAAW,CAC9C,WAAY,EAAe,EAAQ,WAAW,CAC9C,WAAY,EAAe,EAAQ,WAAW,CAC9C,MAAO,EAAQ,MACf,UAAW,EAAQ,UACnB,MAAO,EAAQ,MACf,GAAI,EAAQ,GACZ,eAAgB,EAAQ,eACxB,MAAO,EAAQ,MAChB,CAED,OAAO,EAAc,CACnB,IAAK,QAAQ,KAAK,CAClB,MAAO,EAAM,QAAU,GACvB,eAAgB,GAAQ,EAAM,IAAM,EAAM,gBAC3C,CAAC,CAAC,EAAQ,EAAe,EAAI,CAAE,EAAM,CAAC,EAE1C,CAAC,KAAKI,EAAuB,qCAAqC,CAAC,CAGtE,SAAS,IAAiB,CACxB,OAAOF,EACL,MACA,CACE,KAAMP,EAAYC,EAAQ,CAAE,KAAM,OAAQ,CAAC,CAAC,CAAC,KAAKC,EAAmB,oCAAoC,CAAC,CAC1G,OAAQF,EAAYC,EAAQ,CAAE,KAAM,SAAU,CAAC,CAAC,CAAC,KAAKC,EAAmB,sBAAsB,CAAC,CAChG,UAAWM,EAAc,aAAa,CAAC,KAAKH,EAAsB,4BAA4B,CAAC,CAC/F,GAAIG,EAAc,KAAK,CAAC,KAAKH,EAAsB,yCAAyC,CAAC,CAC7F,eAAgBG,EAAc,kBAAkB,CAAC,KAC/CH,EAAsB,gEAAgE,CACvF,CACD,MAAOG,EAAc,QAAQ,CAAC,KAAKH,EAAsB,oBAAoB,CAAC,CAC/E,EACA,CAAE,OAAM,SAAQ,YAAW,KAAI,iBAAgB,WAC9C,EACE,SAAY,CACV,GAAM,CAAC,CAAE,UAAU,CAAE,mBAAkB,UAAW,MAAM,QAAQ,IAAI,CAClE,OAAO,qBACP,OAAO,uBAAA,KAAA,GAAA,EAAA,EAAA,CACR,CAAC,CACF,EAAiB,CACf,YACA,GAAI,EACJ,iBACA,QACD,CAAC,CACF,EAAM,YAAc,MACpB,EAAM,WAAa,QAAQ,KAAK,CAChC,MAAM,EAAO,EAAe,EAAK,CAAE,CAAE,YAAW,OAAQ,EAAe,EAAO,CAAE,CAAC,EAEnF,CAAE,eAAgB,GAAM,EAAgB,QAAO,CAChD,CACJ,CAAC,KAAKI,EAAuB,sCAAsC,CAAC,CAGvE,SAAS,IAAoB,CAC3B,OAAOF,EACL,SACA,CACE,KAAMP,EAAYC,EAAQ,CAAE,KAAM,OAAQ,CAAC,CAAC,CAAC,KAAKC,EAAmB,2BAA2B,CAAC,CACjG,GAAIM,EAAc,KAAK,CAAC,KAAKH,EAAsB,yCAAyC,CAAC,CAC7F,eAAgBG,EAAc,kBAAkB,CAAC,KAC/CH,EAAsB,gEAAgE,CACvF,CACD,MAAOG,EAAc,QAAQ,CAAC,KAAKH,EAAsB,oBAAoB,CAAC,CAC/E,EACA,CAAE,OAAM,KAAI,iBAAgB,WAC3B,EACE,SAAY,CACV,GAAM,CAAC,CAAE,aAAa,CAAE,mBAAkB,UAAW,MAAM,QAAQ,IAAI,CACrE,OAAO,wBACP,OAAO,uBAAA,KAAA,GAAA,EAAA,EAAA,CACR,CAAC,CACF,EAAiB,CACf,GAAI,EACJ,iBACA,QACD,CAAC,CACF,EAAM,YAAc,SACpB,EAAM,WAAa,QAAQ,KAAK,CAChC,MAAM,EAAU,EAAe,EAAK,CAAC,EAEvC,CAAE,eAAgB,GAAM,EAAgB,QAAO,CAChD,CACJ,CAAC,KAAKI,EAAuB,uCAAuC,CAAC,CAGxE,SAAS,IAAqB,CAC5B,OAAOF,EACL,UACA,CACE,MAAOC,EAAc,QAAQ,CAAC,KAAKH,EAAsB,oBAAoB,CAAC,CAC/E,EACA,CAAE,WACD,EACE,SAAY,CACV,GAAM,CAAC,CAAE,cAAc,CAAE,UAAW,MAAM,QAAQ,IAAI,CACpD,OAAO,yBACP,OAAO,uBAAA,KAAA,GAAA,EAAA,EAAA,CACR,CAAC,CACF,EAAM,WAAa,QAAQ,KAAK,CAChC,MAAM,EAAW,CACf,UAAW,MAAM,OAAO,+BAAA,KAAA,GAAA,EAAA,EAAA,EAA6B,aAAa,CACnE,CAAC,EAEJ,CAAE,QAAO,CACV,CACJ,CAAC,KAAKI,EAAuB,kCAAkC,CAAC,CAGnE,SAAS,IAAoB,CAC3B,OAAOF,EACL,SACA,CACE,MAAOC,EAAc,QAAQ,CAAC,KAAKH,EAAsB,oBAAoB,CAAC,CAC/E,EACA,CAAE,WACD,EACE,SAAY,CACV,GAAM,CAAC,CAAE,aAAa,CAAE,mBAAkB,UAAW,MAAM,QAAQ,IAAI,CACrE,OAAO,wBACP,OAAO,uBAAA,KAAA,GAAA,EAAA,EAAA,CACR,CAAC,CACF,EAAiB,CAAE,QAAO,CAAC,CAC3B,EAAM,YAAc,SACpB,EAAM,WAAa,QAAQ,KAAK,CAChC,MAAM,GAAW,EAEnB,CAAE,QAAO,CACV,CACJ,CAAC,KAAKI,EAAuB,kBAAkB,CAAC,CAGnD,SAAS,IAAqB,CAC5B,OAAOF,EACL,UACA,CACE,GAAIC,EAAc,KAAK,CAAC,KAAKH,EAAsB,yCAAyC,CAAC,CAC7F,eAAgBG,EAAc,kBAAkB,CAAC,KAC/CH,EAAsB,gEAAgE,CACvF,CACD,MAAOG,EAAc,QAAQ,CAAC,KAAKH,EAAsB,oBAAoB,CAAC,CAC/E,EACA,CAAE,KAAI,iBAAgB,WACrB,EACE,SAAY,CACV,GAAM,CAAC,CAAE,cAAc,CAAE,mBAAkB,UAAW,MAAM,QAAQ,IAAI,CACtE,OAAO,wBACP,OAAO,uBAAA,KAAA,GAAA,EAAA,EAAA,CACR,CAAC,CACF,EAAiB,CAAE,GAAI,EAAI,iBAAgB,QAAO,CAAC,CACnD,EAAM,YAAc,UACpB,EAAM,WAAa,QAAQ,KAAK,CAChC,MAAM,GAAY,EAEpB,CAAE,eAAgB,GAAM,EAAgB,QAAO,CAChD,CACJ,CAAC,KAAKI,EAAuB,8CAA8C,CAAC,CAqC/E,MAAa,GAAM,EAlCCF,EAClB,EACA,CACE,GAAIC,EAAc,KAAK,CAAC,KAAKH,EAAsB,yCAAyC,CAAC,CAC7F,eAAgBG,EAAc,kBAAkB,CAAC,KAC/CH,EAAsB,gEAAgE,CACvF,CACD,MAAOG,EAAc,QAAQ,CAAC,KAAKH,EAAsB,oBAAoB,CAAC,CAC/E,CACA,GACC,EAAc,CACZ,IAAK,QAAQ,KAAK,CAClB,MAAO,EAAQ,QAAU,GACzB,eAAgB,GAAQ,EAAQ,IAAM,EAAQ,gBAC/C,CAAC,CACA,GAAkB,CAChB,GAAG,EACH,GAAI,EAAQ,GACZ,eAAgB,EAAQ,eACxB,MAAO,EAAQ,MAChB,CAAC,CACH,CACJ,CAAC,KACAI,EAAuB,2DAA2D,CAClF,EAAgB,CACd,IAAiB,CACjB,IAAgB,CAChB,IAAmB,CACnB,IAAoB,CACpB,IAAmB,CACnB,IAAoB,CACrB,CAAC,CACH,CAEmC,CAClC,KAAM,WACN,QAAS,IAAe,CACzB,CAAC,CAEF,SAAS,GAAiB,EAA8B,EAAmB,CACzE,GAAI,CAAC,EACH,MAAO,GAGT,IAAM,EAAqB,EAAc,EAAU,CAEnD,GAAI,CACF,OAAO,EAAa,EAAS,GAAK,EAAa,EAAmB,MAC5D,CACN,OAAO,EAAK,QAAQ,EAAS,GAAK,EAAK,QAAQ,EAAmB,EAItE,MAAM,GAAe,GAAiB,QAAQ,KAAK,GAAI,OAAO,KAAK,IAAI,CAEjE,GAAiB,IAAI,IAAI,CAAC,UAAU,CAAC,CAE3C,SAAS,GAAuB,EAAyB,CACvD,OAAO,EAAK,KAAM,GAAQ,GAAe,IAAI,EAAI,CAAC,CAGpD,SAAS,GAAc,EAA6B,EAA2B,CAC7E,IAAM,EAAU,EAAe,EAAM,cAAc,EAAM,CAAC,CAE1D,GAAI,EAAE,GAAW,GAAkB,EAAQ,EAAG,CAC5C,IAAM,EAAQ,EAAM,OAAO,EAAM,CACjC,QAAQ,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,CAGnE,GACF,QAAQ,MAAM,aAAa,EAAM,OAAO,EAAM,GAAG,CAIrD,eAAe,GAAK,EAAyB,CAC3C,IAAM,EAAmB,GAAuB,EAAK,CAC/C,EAAO,MAAM,EAAO,eAAe,GAAI,EAAK,CAAC,KAAK,EAAO,QAAQC,GAAiB,CAAC,CAAC,CAEtF,GAAK,UAAU,EAAK,GACtB,GAAc,EAAK,MAAO,EAAiB,CAC3C,QAAQ,SAAW,GAInB,KACF,GAAY,IAAe,CAAC,CAC5B,GAAK,QAAQ,KAAK,CAAC,MAAO,GAAU,CAClC,QAAQ,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,CACrE,QAAQ,SAAW,GACnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proofkit/cli",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.24",
|
|
4
4
|
"description": "Interactive CLI to scaffold and manage ProofKit projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"sort-package-json": "^2.15.1",
|
|
71
71
|
"ts-morph": "^26.0.0",
|
|
72
72
|
"type-fest": "^3.13.1",
|
|
73
|
-
"@proofkit/
|
|
74
|
-
"@proofkit/
|
|
73
|
+
"@proofkit/typegen": "1.1.0-beta.19",
|
|
74
|
+
"@proofkit/fmdapi": "5.1.0-beta.3"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@auth/drizzle-adapter": "^1.11.1",
|