@flisk-sh/flisk 1.3.201 → 1.3.205

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/cli/dist/cli.js +41 -9
  3. package/cli/dist/commands/doctor.js +22 -0
  4. package/cli/dist/commands/open.js +9 -1
  5. package/cli/dist/commands/project.js +4 -2
  6. package/cli/dist/commands/resource.js +3 -1
  7. package/cli/dist/utils/cold-preflight.js +14 -0
  8. package/cli/dist/utils/colima.js +163 -0
  9. package/cli/dist/utils/doctor-fix.js +105 -2
  10. package/cli/dist/utils/machine-output.js +27 -0
  11. package/cli/dist/utils/project-templates.js +1 -0
  12. package/cli/dist/utils/stack-progress.js +5 -4
  13. package/cli/dist-bundle/{chunk-M6S25PIS.js → chunk-4TMLNLYG.js} +1 -1
  14. package/cli/dist-bundle/{chunk-R67UHACQ.js → chunk-5G7E6CO2.js} +1 -1
  15. package/cli/dist-bundle/chunk-67M3DX6J.js +34 -0
  16. package/cli/dist-bundle/{chunk-KXKBWLTE.js → chunk-BHQDQQYQ.js} +1 -1
  17. package/cli/dist-bundle/{chunk-LYOSHFYU.js → chunk-CLQSJP6M.js} +1 -1
  18. package/cli/dist-bundle/chunk-GIMHTZNR.js +2 -0
  19. package/cli/dist-bundle/chunk-IQNUVQH5.js +52 -0
  20. package/cli/dist-bundle/{chunk-NC6KOYDN.js → chunk-P2MFLNY2.js} +1 -1
  21. package/cli/dist-bundle/chunk-WVSI4XL5.js +4 -0
  22. package/cli/dist-bundle/{chunk-5ZSZ4WCI.js → chunk-YNJTA77W.js} +1 -1
  23. package/cli/dist-bundle/chunk-YZRPX76N.js +2 -0
  24. package/cli/dist-bundle/cli.js +226 -226
  25. package/cli/dist-bundle/cold-preflight-R53YXYOC.js +2 -0
  26. package/cli/dist-bundle/colima-SVZX2UML.js +2 -0
  27. package/cli/dist-bundle/{open-SMKISRHH.js → open-PKNOQQXA.js} +1 -1
  28. package/cli/dist-bundle/project-I5QVEGNB.js +2 -0
  29. package/cli/dist-bundle/project-templates-JDRE7AVL.js +2 -0
  30. package/cli/dist-bundle/stack-progress-6GO2TCRH.js +2 -0
  31. package/cli/dist-bundle/{tilt-port-owner-67UVQJTX.js → tilt-port-owner-Y5LHXWPS.js} +1 -1
  32. package/cli/package.json +4 -4
  33. package/engine/assets/docker/wake-gateway/Dockerfile +1 -1
  34. package/engine/topologies/platform/docker/compose/compose.star +20 -18
  35. package/engine/topologies/platform/docker/compose/unsafe_value.star +23 -0
  36. package/engine/topologies/platform/docker/networking/traefik.star +19 -0
  37. package/package.json +2 -2
  38. package/cli/dist-bundle/chunk-GCFNSFW7.js +0 -52
  39. package/cli/dist-bundle/chunk-GNNN2WCF.js +0 -4
  40. package/cli/dist-bundle/chunk-S5EXKK7H.js +0 -34
  41. package/cli/dist-bundle/cold-preflight-6Z4RBFKV.js +0 -2
  42. package/cli/dist-bundle/project-WEC2GSR7.js +0 -2
  43. package/cli/dist-bundle/stack-progress-UVREHNNB.js +0 -2
  44. /package/cli/dist-bundle/{devtools-ZUHXW33W.js → devtools-MGITLOWZ.js} +0 -0
@@ -0,0 +1,34 @@
1
+ import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
+ import{a as O}from"./chunk-GIMHTZNR.js";import{b as N,c as pe,d as q,i as D,j as Y,n as J,o as I,q as C}from"./chunk-BHQDQQYQ.js";import{H as z,J as G,L as E,Na as re,Ra as ae,Sa as se,Ua as ie,V as T,W as B,Wa as ce,Xa as le,Ya as de,aa as f,ba as y,ca as t,d as x,ja as ne,k as U,ka as W,la as V,m as P,s as F}from"./chunk-CLQSJP6M.js";import{b as p}from"./chunk-CF46CD6R.js";import{execFileSync as ye}from"node:child_process";import{cpSync as be,existsSync as b,readdirSync as Se,readFileSync as K,writeFileSync as je}from"node:fs";import{basename as _e,dirname as we,isAbsolute as xe,join as j,resolve as M}from"node:path";import{cwd as ue}from"node:process";import{fileURLToPath as Pe}from"node:url";import{Command as Ee}from"commander";var he="-y, --yes",ke="Skip prompts and confirmations; use defaults";function fe(e,o=ke){return e.option(he,o,!1)}async function ve(e,o=!0){let c=await I({message:e,initial:o});return c||T(),c}function De(e,o=1){e.valid||E(e.error??"Validation failed",o)}function Je(e,o,c,a){return e.dryRun?(a?a():(console.log(`Dry run - ${o}`),console.log(`Would run: ${c}`)),!0):!1}async function Ie(e,o){return await ve(e,!0)?!0:(o&&o(),!1)}var L=new Map;function me(e){e!==void 0?L.delete(e):L.clear()}function ze(e=!1){let o=F(),c=o??"";if(!e){let r=L.get(c);if(r)return r}let{resources:a,problems:l}=o?ae(o):{resources:ie(),problems:[]},d=de(a),n=le(a);se(l);let g=a.filter(r=>!r.stack),m=new Map;for(let r of a)if(r.stack){let _=m.get(r.stack)||[];_.push(r),m.set(r.stack,_)}let k={resources:a,problems:l,stacks:d,stackNames:n,unassignedResources:g,resourcesByStack:m};return L.set(c,k),k}var A={proxy:{name:"proxy",description:"Traefik reverse proxy and API gateway for routing all services",category:"core",phase:"pre_alpha",enabled_by_default:!0,dependsOn:[]},verdaccio:{name:"verdaccio",description:"Verdaccio npm registry for package management and local publishing (Premium - requires TDK_LICENSE_KEY)",category:"premium",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[]},[x]:{name:x,description:"PostgreSQL database for data persistence and SQL operations",category:"core",phase:"pre_alpha",enabled_by_default:!0,dependsOn:[]},monitoring:{name:"monitoring",description:"SigNoz or SkyWalking observability platform for monitoring and tracing",category:"optional",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[x]},elk:{name:"elk",description:"Elasticsearch, Logstash, Kibana stack for log aggregation and analysis",category:"optional",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[]},debezium:{name:"debezium",description:"Change Data Capture for real-time data streaming from databases",category:"optional",phase:"pre_alpha",enabled_by_default:!1,dependsOn:[x]},"golden-image":{name:"golden-image",description:"Pre-built Docker image layer for faster builds and smaller deployments",category:"optional",phase:"pre_alpha",enabled_by_default:!0,dependsOn:[]}};function H(e,o){try{return ce(e,o)}catch{return[]}}function Ce(e){return new Set([...e.phases.pre_alpha.enabledStacks,...e.phases.alpha.enabledStacks,...e.phases.beta.enabledStacks,...e.phases.out_of_scope.enabledStacks])}function Q(e,o){let c=Ce(e),a=o.filter(l=>!c.has(l));return a.length===0?(e.phases.pre_alpha.enabledStacks=Array.from(new Set(e.phases.pre_alpha.enabledStacks)),[]):(e.phases.pre_alpha.enabledStacks=Array.from(new Set([...e.phases.pre_alpha.enabledStacks,...a])),a)}function mt(e,o){let c=j(e,".tdk",U);if(!b(c))return[];let a=D(e),l=Q(a,H(e,o));return l.length>0&&N(c,a),l}function Oe(){return Object.values(A).filter(e=>e.enabled_by_default&&e.category==="core").map(e=>e.name)}function Ae(e,o){return o||(O[e]?.repo.split("/").pop()??e).replace(/\.git$/,"")}async function Re(e,o,c){let a=O[e];if(!a){console.log(p.red(`
3
+ \u274C Unknown template: "${e}"`)),console.log(p.yellow(`
4
+ Available templates:`));for(let[n,g]of Object.entries(O))console.log(` ${p.cyan(n)} ${p.gray(`- ${g.description}`)}`);console.log(p.gray("\nOr run `flisk project` with no template for a blank project.")),process.exit(1)}let l=Ae(e,o);re(l)||z.invalidPath(l).exit();let d=xe(l)?l:M(ue(),l);b(d)&&Se(d).length>0&&z.directoryExists(d).exit(),B(`Cloning template: ${e}`),t(`${a.description}
5
+ `,0),t(`Source: ${a.bundledPath?"bundled Flisk example":a.repo}`,0),t(`Destination: ${d}
6
+ `,0);try{if(a.bundledPath){let n=M(we(Pe(new URL("../dist/commands/project.js",import.meta.url).href)),"../../../");be(M(n,a.bundledPath),d,{recursive:!0});let g=_e(d).replace(/-/g,"_");for(let m of["services/platform/messaging/docker-compose.yml","services/shop/orders-api/service.json","services/shop/orders-api/src/index.ts","services/shop/orders-worker/service.json","services/shop/orders-worker/src/index.ts"]){let k=j(d,m),r=K(k,"utf-8");je(k,r.replaceAll("tdk_example",g))}}else ye("git",["clone",a.repo,d],{stdio:"inherit"})}catch{E(a.bundledPath?"Bundled example copy failed. Reinstall the Flisk CLI package and try again.":"git clone failed. Check you have git installed and network access.")}me(),console.log(p.green(`
7
+ \u2705 Cloned "${e}" into ${l}/`)),t(`
8
+ Next steps:`,0),t(`1. cd ${l}`),t("2. flisk doctor # check Docker/Tilt are ready"),t("3. flisk up # start the stack"),t(`
9
+ Runtime readiness:`,0);for(let n of c)t(n,0)}var R={version:"1.0",project:{name:"",version:"1.0.0"},phases:{pre_alpha:{name:"Pre-Alpha",description:"Core infrastructure and MVP services",enabledStacks:Oe()},alpha:{name:"Alpha",description:"Essential business services",enabledStacks:[]},beta:{name:"Beta",description:"Extended features",enabledStacks:[]},out_of_scope:{name:"Out of Scope",description:"Future releases",enabledStacks:[]}},optional_infra:{monitoring:!1,elk:!1,debezium:!1,golden_image:!0,verdaccio:!1},discovery:{paths:["services/*/*"]},overrides:{}},ut=fe(new Ee("project")).description("Initialize or validate project-level master configuration").argument("[template]",`Clone a starter example instead of a blank project (${Object.keys(O).join(", ")})`).option("--path <dir>","Directory to clone the template into (default: the template's repo name)").option("--check","Check if master configs exist and are in sync").option("--force","Overwrite existing configuration (dangerous)").option("--config-file <path>","Load project config from existing JSON file").action(async(e,o)=>{let{assertMachineReadyOrExit:c,detectRuntimePrerequisites:a,formatRuntimeNextSteps:l}=await import("./cold-preflight-R53YXYOC.js");await c({scope:"scaffold"});let d=l(a());if(e){await G(async()=>Re(e,o.path,d));return}await G(async()=>{let n=F();n||(n=ue(),y(`\u{1F680} Initializing new Flisk project...
10
+ `),t(`Location: ${n}
11
+ `,0));let g=j(n,".tdk"),m=j(g,U);if(o.check){let i=P.every(u=>b(j(n,".tdk",".tdk-out",u))),h=b(m);if(i&&h){let u=D(n);f("Project configuration is valid"),t(`Project: ${u.project.name}`,3),t(`Phases: ${Object.keys(u.phases).join(", ")}`,3),process.exit(0)}else{if(console.log(p.yellow("\u26A0\uFE0F Project configuration incomplete:")),h||t(".tdk/project.json (not found)",3),!i)for(let u of P.filter(S=>!b(j(n,".tdk/.tdk-out",S))))t(`.tdk/.tdk-out/${u} (not found)`,3);t("Run `flisk project` to create them."),process.exit(1)}}B("Project Configuration"),t(`Project root: ${n}
12
+ `,0),b(g)||(pe(g),f("Created: .tdk/ directory"));let k=b(m);if(k&&!o.force){f(".tdk/project.json exists");let i=JSON.parse(K(m,"utf-8")),h=D(n),u=H(n),S=Q(h,u);if((S.length>0||!i.phases)&&N(m,h),S.length>0&&t(`Auto-enabled discovered service stacks: ${S.join(", ")}`,0),y(`
13
+ \u{1F4CB} Regenerating master configuration files...
14
+ `),await Y(n),V(n))f("Created: .env (the defaults work as-is)");else{let v=W(n);v.length>0&&f(`Updated: .env (added ${v.join(", ")}; existing values unchanged)`)}let $=q(n);$.length>0&&f(`Added to .gitignore: ${$.join(", ")}`),console.log(p.green(`
15
+ \u2705 Project configuration regenerated!`)),t(`
16
+ Generated in .tdk/.tdk-out/:`,0);for(let v of P)t(`- ${v}`);t(`
17
+ Runtime readiness:`,0);for(let v of d)t(v,0);return}if(k&&o.force&&!o.yes&&(console.log(p.red(`
18
+ \u26A0\uFE0F WARNING: --force will overwrite .tdk/project.json!`)),!await I({message:"This will reset your project configuration. Continue?",initial:!1}))){T();return}let r,_=H(n);if(o.configFile){let i=M(o.configFile);b(i)||E(`Config file not found: ${i}`);let h=K(i,"utf-8");r=JSON.parse(h),f(`Loaded config from: ${i}`)}else if(o.yes)r=JSON.parse(JSON.stringify(R)),r.project.name=n.split("/").pop()||"my-project",console.log(p.gray("Using default configuration (non-interactive mode)"));else{y(`\u{1F4DD} Project Setup Wizard
19
+ `);let i=await J({message:"Project name:",initial:n.split("/").pop()||"my-project",validate:s=>s.trim()!==""||"Project name is required"}),h=await J({message:"Project version:",initial:"1.0.0-alpha"}),u=Object.values(A).filter(s=>s.category==="core"&&s.phase==="pre_alpha"),S=new Set(u.map(s=>s.name)),te=await C({message:"Select Pre-Alpha enabled stacks (core infrastructure):",choices:[...u.map(s=>({title:s.description,value:s.name,selected:s.enabled_by_default})),..._.filter(s=>!S.has(s)).map(s=>({title:`${s} (discovered service stack)`,value:s,selected:!0}))]}),$=await C({message:"Select Alpha enabled stacks (core business):",choices:[{title:"api (Backend API)",value:"api"},{title:"app (Frontend app)",value:"app"}]}),v=await C({message:"Select Beta enabled stacks (extended features):",choices:[{title:"worker (Background jobs)",value:"worker"},{title:"migrator (Database migrations)",value:"migrator"}]}),w=await C({message:"Enable optional infrastructure (high resource):",choices:Object.values(A).filter(s=>s.category==="optional").concat(Object.values(A).filter(s=>s.category==="premium")).map(s=>({title:s.description,value:s.name,selected:s.enabled_by_default}))});y(`
20
+ \u{1F4C2} Service discovery`),t("What: folder patterns Flisk scans for a service.json in each match."),t("Where: type one or more globs, comma-separated."),t("How: saved as discovery.paths in .tdk/project.json - editable later."),t(`Example: ${R.discovery.paths.join(", ")}
21
+ `);let ge=await J({message:"Folders to scan:",initial:R.discovery.paths.join(", ")});r=JSON.parse(JSON.stringify(R)),r.project.name=i,r.project.version=h,r.phases.pre_alpha.enabledStacks=Array.from(new Set(te)),r.phases.alpha.enabledStacks=Array.from(new Set($)),r.phases.beta.enabledStacks=Array.from(new Set(v)),r.optional_infra.monitoring=w.includes("monitoring"),r.optional_infra.elk=w.includes("elk"),r.optional_infra.debezium=w.includes("debezium"),r.optional_infra.golden_image=w.includes("golden_image"),r.optional_infra.verdaccio=w.includes("verdaccio");let oe=ge.split(",").map(s=>s.trim()).filter(s=>s.length>0);r.discovery.paths=oe.length>0?oe:R.discovery.paths}let X=Q(r,_);if(X.length>0&&t(`Auto-enabled discovered service stacks: ${X.join(", ")}`,0),y(`
22
+ \u{1F4CB} Creating project configuration...
23
+ `),N(m,r),f("Created: .tdk/project.json"),t(`\u2192 Project: ${r.project.name}`),y(`
24
+ \u{1F4CB} Generating master configuration files...
25
+ `),await Y(n),y(`
26
+ \u{1F527} Setting up environment variables...
27
+ `),V(n))f("Created: .env (the defaults work as-is)");else{let i=W(n);i.length>0?f(`Updated: .env (added ${i.join(", ")}; existing values unchanged)`):f("Found: .env (environment already configured)")}let Z=ne(n);if(Z.missing.length>0){console.log(p.yellow(`
28
+ \u26A0\uFE0F Missing required environment variables:`));for(let i of Z.missing)t(`- ${i}`,1);t("\u2192 Edit .env and fill in these values before running `flisk up`",1)}let ee=q(n);ee.length>0&&f(`Added to .gitignore: ${ee.join(", ")}`),console.log(p.green(`
29
+ \u2705 Project configuration complete!`)),t(`
30
+ Generated files in .tdk/.tdk-out/:`,0);for(let i of P)t(`- ${i}`);t(`
31
+ Environment configuration:`,0),t("- .env (contains all required variables)"),t(`
32
+ Source file:`,0),t("- .tdk/project.json (edit this to change project structure)"),t(`
33
+ Next steps:`,0),t("1. flisk resource api --type backend --stack app # scaffold a service"),t("2. flisk up app # start it"),t(`
34
+ Runtime readiness:`,0);for(let i of d)t(i,0);t("\nAfter editing .tdk/project.json, run `flisk config regenerate`.",0)})});export{me as a,ze as b,fe as c,De as d,Je as e,Ie as f,mt as g,Ae as h,Re as i,ut as j};
@@ -1,5 +1,5 @@
1
1
  import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{c as z,e as Q}from"./chunk-42IVF3YT.js";import{Fa as J,Ga as B,Qa as O,Ta as Y,cb as X,d as v,e as k,g as q,ga as L,h as x,i as P,j as F,k as W,l as A,p as d,q as N}from"./chunk-LYOSHFYU.js";import{b as V}from"./chunk-CF46CD6R.js";import{a as $}from"./chunk-6EA4DGCY.js";import{appendFileSync as le,existsSync as C,mkdirSync as fe,readFileSync as de,writeFileSync as Z}from"node:fs";import{dirname as pe,resolve as w}from"node:path";function ft(t,e,n){for(let[r,s]of e.entries())console.log(V.blue(`${s.emoji} ${s.description}...`)),s.type==="json"?me(t,s.filename,s.content):he(t,s.filename,String(s.content)),n&&n(s,r,e.length)}function ue(t,e,n=2){let r=`${JSON.stringify(e,null,n)}
2
+ import{c as z,e as Q}from"./chunk-42IVF3YT.js";import{Fa as J,Ga as B,Qa as O,Ta as Y,cb as X,d as v,e as k,g as q,ga as L,h as x,i as P,j as F,k as W,l as A,p as d,q as N}from"./chunk-CLQSJP6M.js";import{b as V}from"./chunk-CF46CD6R.js";import{a as $}from"./chunk-6EA4DGCY.js";import{appendFileSync as le,existsSync as C,mkdirSync as fe,readFileSync as de,writeFileSync as Z}from"node:fs";import{dirname as pe,resolve as w}from"node:path";function ft(t,e,n){for(let[r,s]of e.entries())console.log(V.blue(`${s.emoji} ${s.description}...`)),s.type==="json"?me(t,s.filename,s.content):he(t,s.filename,String(s.content)),n&&n(s,r,e.length)}function ue(t,e,n=2){let r=`${JSON.stringify(e,null,n)}
3
3
  `;Z(t,r,"utf-8")}function me(t,e,n,r=2){let s=w(t,e);ue(s,n,r)}function U(t,e){Z(t,e,"utf-8")}function he(t,e,n){let r=w(t,e);U(r,n)}function dt(t){C(t)||fe(t,{recursive:!0})}var ge=[".env",".tdk/.tdk-out/",".tdk/.project-id",".tdk/smoke/","node_modules/"];function Se(t){let e=w(t,".gitignore"),n=C(e)?de(e,"utf-8"):"",r=new Set(n.split(`
4
4
  `).map(f=>f.trim().replace(/\/$/,""))),s=ge.filter(f=>!r.has(f.replace(/\/$/,"")));if(s.length===0)return[];let c=n&&!n.endsWith(`
5
5
  `)?`
@@ -1,5 +1,5 @@
1
1
  import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{b as f}from"./chunk-CF46CD6R.js";var ar="Container Runtime",_="bring-your-own";var De="database-management",cr=".tiltignore",Ie="service.json",Q="docker-compose.yml",ur=".autogenerated",Ct="TILT_TECH_STACK.star",Dt="TILT_RESOURCE_DEFAULTS.star",B="project.json",je="package.json",fr=[Ct,Dt,"spec.master"],pr=["backend","frontend","library","sdk","worker","migrator","mcp","agent",_],lr={backend:["dev","build","start"],worker:["dev","build","start"],migrator:["dev","build","start"],mcp:["dev","build","start"],agent:["dev","build","start"],frontend:["dev","build"],library:["dev","build"],sdk:["dev","build"],[_]:[]};var Z=["monitoring","elk","debezium","golden_image","verdaccio"],dr={frontend:{base:3e3,min:3e3,max:3999,range:"3000-3999"},backend:{base:4e3,min:4e3,max:4999,range:"4000-4999"},mcp:{base:4e3,min:4e3,max:5999,range:"4000-5999"},agent:{base:4e3,min:4e3,max:5999,range:"4000-5999"},[_]:{base:4e3,min:4e3,max:5999,range:"4000-5999"},worker:{base:6e3,min:6e3,max:6999,range:"6000-6999"},health:{base:5e3,min:5e3,max:5999,range:"5000-5999"},migrator:{base:7e3,min:7e3,max:7999,range:"7000-7999"}},mr={tiltUi:10350,traefik:8080},ee="https://flisk.sh/docs/quickstart/";var Ne=["node_modules",".git",".tilt",".tilt-engine","dist","build",".prisma",".turbo","coverage","tmp","temp","__tests__","test","tests",".github",".vscode","docs"],Pe=["Dockerfile",Q,"docker-compose.yaml","Tiltfile","vite.config.ts","tsconfig.json","tsconfig.build.json"],It={infra:"\u{1F3D7}\uFE0F",core:"\u{1F527}",api:"\u26A1",app:"\u{1F3A8}",orchestrator:"\u2699\uFE0F"};function hr(e){let t=e.toLowerCase();for(let[n,r]of Object.entries(It))if(t.includes(n))return r;return"\u{1F4E6}"}import{existsSync as Nt}from"node:fs";import{dirname as Pt,join as Ft,resolve as Ue}from"node:path";import{cwd as Ut}from"node:process";var Fe={name:"tdk-cli-internal",private:!0,version:"1.3.201",description:"Flisk CLI \u2014 start services on your machine.",keywords:["flisk","tilt","cli","local-dev","microservices"],homepage:"https://github.com/flisk-sh/flisk#readme",bugs:{url:"https://github.com/flisk-sh/flisk/issues"},repository:{type:"git",url:"git+https://github.com/flisk-sh/flisk.git",directory:"cli"},license:"MIT",author:"Flisk Team",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",bin:{flisk:"bin/tdk.js"},files:["dist","dist-bundle","bin","templates","README.md","Tiltfile","engine","discovery","specs","ext","!ext/ide-components/code_executor","shared-platform-engineering/docker-templates"],scripts:{build:"tsc && node scripts/bundle.mjs","build:watch":"tsc --watch","check:dist":"npm run build && ../scripts/check-cli-dist.sh",lint:"biome check .","lint:fix":"biome check . --write",typecheck:"tsc --project tsconfig.typecheck.json",clean:"rm -rf dist",dev:"bun run build:watch",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage --coverage.reportOnFailure --coverage.reporter=text --coverage.reporter=html --coverage.reporter=json-summary --coverage.reporter=json --coverage.reportsDirectory=coverage --reporter=default --reporter=json --outputFile.json=test-results/vitest.json",prepack:"../scripts/stage-npm-engine.sh && npm run build"},dependencies:{commander:"^15.0.0",handlebars:"^4.7.8"},devDependencies:{"@biomejs/biome":"^2.5.13","@types/node":"^22.0.0","@types/react":"^19.3.0","@vitest/coverage-v8":"^5.0.2",ajv:"^8.17.1",chalk:"^6.0.1",esbuild:"^0.28.2",ink:"^8.0.0",knip:"^6.38.0",react:"^19.3.0","react-devtools-core":"^8.0.0",typescript:"^7.0.2",vite:"^8.3.3",vitest:"^5.0.0"},engines:{node:">=22.12.0"}};function E(e=Ut()){let t=Ue(e),n=Ue("/");for(;t!==n;){if(Nt(Ft(t,".tdk",B)))return t;let r=Pt(t);if(r===t)break;t=r}return null}var V=null;function Mt(){if(V)return V;let e=Fe;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return V={name:String(t.name??"@flisk-sh/flisk"),version:String(t.version??"0.0.0"),fullPackage:t},V}function wr(){return Mt().version}import{existsSync as Me}from"node:fs";import{delimiter as Le,extname as Be,join as Ve}from"node:path";import{delimiter as br,extname as Lt}from"node:path";function U(){return process.platform==="win32"}function Bt(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function Vt(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function Gt(e,t){let n=Bt(e),r=Vt(t);if(!n||!r||n==="windows"&&r!=="amd64")return null;let o=`tdk-${n}-${r}`;return n==="windows"?`${o}.exe`:o}function Ar(){return Gt(process.platform,process.arch)}function Rr(){return U()?"tdk.exe":"flisk"}function te(e,t=U()){return t?Lt(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function G(e){let t=process.env.PATH??process.env.Path??"",n=U(),r=te(e,n);if(n&&!Be(e))for(let o of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let s=o.toLowerCase();s&&!r.includes(`${e}${s}`)&&r.push(`${e}${s}`)}for(let o of t.split(Le))if(o)for(let s of r){let i=Ve(o,s);if(Me(i))return i}return null}function Ir(e){let t=process.env.PATH??process.env.Path??"",n=U(),r=te(e,n);if(n&&!Be(e))for(let i of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let a=i.toLowerCase();a&&!r.includes(`${e}${a}`)&&r.push(`${e}${a}`)}let o=[],s=new Set;for(let i of t.split(Le))if(i)for(let a of r){let c=Ve(i,a);if(!Me(c))continue;let p=n?c.toLowerCase():c;s.has(p)||(s.add(p),o.push(c))}return o}import{execFileSync as Wt,execSync as Kt}from"node:child_process";var Ge=1e4;function We(){let e=!1;if(process.platform==="win32")try{return Wt(G("docker")??"docker",["ps"],{stdio:"ignore",timeout:Ge,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return Kt(t,{stdio:"ignore",timeout:Ge}),"running"}catch(n){n.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function W(e,t){return e[t]??0}function Ht(e,t){let n=Array.from({length:t.length+1},(r,o)=>o);for(let r=1;r<=e.length;r++){let o=[r];for(let s=1;s<=t.length;s++){let i=e[r-1]===t[s-1]?0:1;o[s]=Math.min(W(o,s-1)+1,W(n,s)+1,W(n,s-1)+i)}n=o}return W(n,t.length)}function zt(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length-1;n++)if(e[n]!==t[n]&&e[n]===t[n+1]&&e[n+1]===t[n]&&e.slice(0,n)===t.slice(0,n)&&e.slice(n+2)===t.slice(n+2))return!0;return!1}function Ke(e,t){if(e.length<2||t.length===0||t.includes(e))return;let n=e.toLowerCase(),r,o=Number.POSITIVE_INFINITY;for(let s of t){if(s.length===0)continue;let i=s.toLowerCase(),a=zt(n,i)?1:Ht(n,i),c=Math.max(1,Math.min(2,Math.floor(Math.max(n.length,i.length)/3)));a>c||(a<o||a===o&&(r===void 0||s<r))&&(r=s,o=a)}return r}import{spawn as Jt}from"node:child_process";import{join as qt}from"node:path";function Yt(e,t=[],n={}){return new Promise((r,o)=>{let s=[e,...t];n.verbose&&console.log(`Executing: tilt ${s.join(" ")}`);let i=Jt(G("tilt")??"tilt",s,{stdio:n.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:n.timeoutMs}),a="",c="";n.inheritStdio||(i.stdout?.on("data",p=>{a+=p.toString()}),i.stderr?.on("data",p=>{c+=p.toString()})),i.on("close",p=>{r({exitCode:p??1,stdout:a,stderr:c})}),i.on("error",p=>{o(new Error(`Failed to spawn tilt: ${p.message}`))})})}async function He(){try{return(await Yt("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function Xt(){let e=E();if(!e)throw $.notInProject();return qt(e,".tdk",".tdk-out","Tiltfile")}function ze(e){let t=Xt();e.push("-f",t)}function Wr(e,t={}){let n=[];return ze(n),t.focusTargets&&t.focusTargets.length>0&&n.push("--",`--focus=${t.focusTargets.join(",")}`),n.push(...e),t.verbose&&!t.quiet&&n.push("--verbose"),t.watch&&n.push("--watch"),n}function Kr(e={}){let t=[];return ze(t),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function Je(e){return e instanceof Error?e.message:String(e)}function Zr(e,t){if(process.env.TDK_VERBOSE){let n=t!==void 0?`: ${Je(t)}`:"";console.warn(f.gray(`${e}${n}`))}}var S=class extends Error{suggestions;exitCode;constructor(t,n=[],r=1){super(t),this.name="TdkError",this.suggestions=n,this.exitCode=r}display(){oe(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}},re=class extends Error{code;constructor(t=1){super(`process.exit(${t})`),this.name="ProcessExitError",this.code=t}};function ne(e,t,n=!1){let r=new Set;for(let o of e){let s=Ke(o,t);s&&r.add(n?`Did you mean "${s}" for "${o}"?`:`Did you mean "${s}"?`)}return[...r]}var $={tiltNotInstalled:()=>new S("Tilt CLI is not installed",["Install Tilt: `brew install tilt` (macOS)","Or download from: https://docs.tilt.dev/install.html","Verify with: `tilt version`",`Setup guide: ${ee}`]),dockerNotAvailable:()=>new S("Docker (or a compatible container runtime) is not running",["Start Docker Desktop, then verify with: `docker ps`","Or start Colima: `colima start`","Or start the Docker service on Linux: `sudo systemctl start docker`",`Setup guide: ${ee}`]),dockerNotResponding:()=>new S("Docker is running but not responding (`docker ps` hung for 10s)",["Quit and reopen Docker Desktop, or run `colima restart`","Then verify with: `docker ps`"]),stackNotFound:(e,t=[])=>new S(`Stack "${e}" not found`,[...ne([e],t),"Run `flisk stacks` to see available stacks","Run `flisk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new S(`Resource "${e}" not found`,[...ne([e],t),"Run `flisk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let n=ne(e,t,e.length>1);return new S(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,n,2)},directoryExists:e=>new S(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new S(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new S("Could not find project root (no .tdk/project.json found)",["Run this from within a Flisk project","Run `flisk project --yes` to initialize a new project"])};function eo(){let e=E();return e||$.notInProject().exit()}function Qt(e){e instanceof S&&e.exit(),oe(Je(e)),process.exit(1)}async function Zt(e,t){try{return await e()}catch(n){if(n instanceof re)throw n;return t?.verbose&&n instanceof Error&&n.stack&&console.error(f.gray(n.stack)),Qt(n)}}async function to(e,t){let n=[],r=We();return r==="unresponsive"?n.push($.dockerNotResponding()):r==="missing"&&n.push($.dockerNotAvailable()),await He()||n.push($.tiltNotInstalled()),n.length>0&&(console.error(f.red(`
2
+ import{b as f}from"./chunk-CF46CD6R.js";var ar="Container Runtime",_="bring-your-own";var De="database-management",cr=".tiltignore",Ie="service.json",Q="docker-compose.yml",ur=".autogenerated",Ct="TILT_TECH_STACK.star",Dt="TILT_RESOURCE_DEFAULTS.star",B="project.json",je="package.json",fr=[Ct,Dt,"spec.master"],pr=["backend","frontend","library","sdk","worker","migrator","mcp","agent",_],lr={backend:["dev","build","start"],worker:["dev","build","start"],migrator:["dev","build","start"],mcp:["dev","build","start"],agent:["dev","build","start"],frontend:["dev","build"],library:["dev","build"],sdk:["dev","build"],[_]:[]};var Z=["monitoring","elk","debezium","golden_image","verdaccio"],dr={frontend:{base:3e3,min:3e3,max:3999,range:"3000-3999"},backend:{base:4e3,min:4e3,max:4999,range:"4000-4999"},mcp:{base:4e3,min:4e3,max:5999,range:"4000-5999"},agent:{base:4e3,min:4e3,max:5999,range:"4000-5999"},[_]:{base:4e3,min:4e3,max:5999,range:"4000-5999"},worker:{base:6e3,min:6e3,max:6999,range:"6000-6999"},health:{base:5e3,min:5e3,max:5999,range:"5000-5999"},migrator:{base:7e3,min:7e3,max:7999,range:"7000-7999"}},mr={tiltUi:10350,traefik:8080},ee="https://flisk.sh/docs/quickstart/";var Ne=["node_modules",".git",".tilt",".tilt-engine","dist","build",".prisma",".turbo","coverage","tmp","temp","__tests__","test","tests",".github",".vscode","docs"],Pe=["Dockerfile",Q,"docker-compose.yaml","Tiltfile","vite.config.ts","tsconfig.json","tsconfig.build.json"],It={infra:"\u{1F3D7}\uFE0F",core:"\u{1F527}",api:"\u26A1",app:"\u{1F3A8}",orchestrator:"\u2699\uFE0F"};function hr(e){let t=e.toLowerCase();for(let[n,r]of Object.entries(It))if(t.includes(n))return r;return"\u{1F4E6}"}import{existsSync as Nt}from"node:fs";import{dirname as Pt,join as Ft,resolve as Ue}from"node:path";import{cwd as Ut}from"node:process";var Fe={name:"tdk-cli-internal",private:!0,version:"1.3.205",description:"Flisk CLI \u2014 start services on your machine.",keywords:["flisk","tilt","cli","local-dev","microservices"],homepage:"https://github.com/flisk-sh/flisk#readme",bugs:{url:"https://github.com/flisk-sh/flisk/issues"},repository:{type:"git",url:"git+https://github.com/flisk-sh/flisk.git",directory:"cli"},license:"MIT",author:"Flisk Team",type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",bin:{flisk:"bin/tdk.js"},files:["dist","dist-bundle","bin","templates","README.md","Tiltfile","engine","discovery","specs","ext","!ext/ide-components/code_executor","shared-platform-engineering/docker-templates"],scripts:{build:"tsc && node scripts/bundle.mjs","build:watch":"tsc --watch","check:dist":"npm run build && ../scripts/check-cli-dist.sh",lint:"biome check .","lint:fix":"biome check . --write",typecheck:"tsc --project tsconfig.typecheck.json",clean:"rm -rf dist",dev:"bun run build:watch",test:"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage --coverage.reportOnFailure --coverage.reporter=text --coverage.reporter=html --coverage.reporter=json-summary --coverage.reporter=json --coverage.reportsDirectory=coverage --reporter=default --reporter=json --outputFile.json=test-results/vitest.json",prepack:"../scripts/stage-npm-engine.sh && npm run build"},dependencies:{commander:"^15.0.0",handlebars:"^4.7.8"},devDependencies:{"@biomejs/biome":"^2.5.13","@types/node":"^26.6.5","@types/react":"^19.3.0","@vitest/coverage-v8":"5.0.5",ajv:"^8.17.1",chalk:"^6.0.1",esbuild:"^0.28.2",ink:"^8.0.0",knip:"^6.38.0",react:"^19.3.0","react-devtools-core":"^8.0.0",typescript:"^7.0.2",vite:"^8.3.3",vitest:"5.0.5"},engines:{node:">=22.12.0"}};function E(e=Ut()){let t=Ue(e),n=Ue("/");for(;t!==n;){if(Nt(Ft(t,".tdk",B)))return t;let r=Pt(t);if(r===t)break;t=r}return null}var V=null;function Mt(){if(V)return V;let e=Fe;if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Invalid package.json: expected object");let t=e;return V={name:String(t.name??"@flisk-sh/flisk"),version:String(t.version??"0.0.0"),fullPackage:t},V}function wr(){return Mt().version}import{existsSync as Me}from"node:fs";import{delimiter as Le,extname as Be,join as Ve}from"node:path";import{delimiter as br,extname as Lt}from"node:path";function U(){return process.platform==="win32"}function Bt(e){return e==="linux"?"linux":e==="darwin"?"darwin":e==="win32"?"windows":null}function Vt(e){return e==="x64"?"amd64":e==="arm64"?"arm64":null}function Gt(e,t){let n=Bt(e),r=Vt(t);if(!n||!r||n==="windows"&&r!=="amd64")return null;let o=`tdk-${n}-${r}`;return n==="windows"?`${o}.exe`:o}function Ar(){return Gt(process.platform,process.arch)}function Rr(){return U()?"tdk.exe":"flisk"}function te(e,t=U()){return t?Lt(e)?[e]:[e,`${e}.exe`,`${e}.cmd`,`${e}.bat`]:[e]}function G(e){let t=process.env.PATH??process.env.Path??"",n=U(),r=te(e,n);if(n&&!Be(e))for(let o of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let s=o.toLowerCase();s&&!r.includes(`${e}${s}`)&&r.push(`${e}${s}`)}for(let o of t.split(Le))if(o)for(let s of r){let i=Ve(o,s);if(Me(i))return i}return null}function Ir(e){let t=process.env.PATH??process.env.Path??"",n=U(),r=te(e,n);if(n&&!Be(e))for(let i of(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";")){let a=i.toLowerCase();a&&!r.includes(`${e}${a}`)&&r.push(`${e}${a}`)}let o=[],s=new Set;for(let i of t.split(Le))if(i)for(let a of r){let c=Ve(i,a);if(!Me(c))continue;let p=n?c.toLowerCase():c;s.has(p)||(s.add(p),o.push(c))}return o}import{execFileSync as Wt,execSync as Kt}from"node:child_process";var Ge=1e4;function We(){let e=!1;if(process.platform==="win32")try{return Wt(G("docker")??"docker",["ps"],{stdio:"ignore",timeout:Ge,windowsHide:!0}),"running"}catch(t){return t.code==="ETIMEDOUT"?"unresponsive":"missing"}for(let t of["docker ps","colima status","podman ps"])try{return Kt(t,{stdio:"ignore",timeout:Ge}),"running"}catch(n){n.code==="ETIMEDOUT"&&(e=!0)}return e?"unresponsive":"missing"}function W(e,t){return e[t]??0}function Ht(e,t){let n=Array.from({length:t.length+1},(r,o)=>o);for(let r=1;r<=e.length;r++){let o=[r];for(let s=1;s<=t.length;s++){let i=e[r-1]===t[s-1]?0:1;o[s]=Math.min(W(o,s-1)+1,W(n,s)+1,W(n,s-1)+i)}n=o}return W(n,t.length)}function zt(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length-1;n++)if(e[n]!==t[n]&&e[n]===t[n+1]&&e[n+1]===t[n]&&e.slice(0,n)===t.slice(0,n)&&e.slice(n+2)===t.slice(n+2))return!0;return!1}function Ke(e,t){if(e.length<2||t.length===0||t.includes(e))return;let n=e.toLowerCase(),r,o=Number.POSITIVE_INFINITY;for(let s of t){if(s.length===0)continue;let i=s.toLowerCase(),a=zt(n,i)?1:Ht(n,i),c=Math.max(1,Math.min(2,Math.floor(Math.max(n.length,i.length)/3)));a>c||(a<o||a===o&&(r===void 0||s<r))&&(r=s,o=a)}return r}import{spawn as Jt}from"node:child_process";import{join as qt}from"node:path";function Yt(e,t=[],n={}){return new Promise((r,o)=>{let s=[e,...t];n.verbose&&console.log(`Executing: tilt ${s.join(" ")}`);let i=Jt(G("tilt")??"tilt",s,{stdio:n.inheritStdio?"inherit":"pipe",shell:!1,windowsHide:process.platform==="win32",timeout:n.timeoutMs}),a="",c="";n.inheritStdio||(i.stdout?.on("data",p=>{a+=p.toString()}),i.stderr?.on("data",p=>{c+=p.toString()})),i.on("close",p=>{r({exitCode:p??1,stdout:a,stderr:c})}),i.on("error",p=>{o(new Error(`Failed to spawn tilt: ${p.message}`))})})}async function He(){try{return(await Yt("version",[],{inheritStdio:!1,timeoutMs:1e4})).exitCode===0}catch{return!1}}function Xt(){let e=E();if(!e)throw $.notInProject();return qt(e,".tdk",".tdk-out","Tiltfile")}function ze(e){let t=Xt();e.push("-f",t)}function Wr(e,t={}){let n=[];return ze(n),t.focusTargets&&t.focusTargets.length>0&&n.push("--",`--focus=${t.focusTargets.join(",")}`),n.push(...e),t.verbose&&!t.quiet&&n.push("--verbose"),t.watch&&n.push("--watch"),n}function Kr(e={}){let t=[];return ze(t),e.focusTargets&&e.focusTargets.length>0&&t.push("--",`--focus=${e.focusTargets.join(",")}`),t}function Je(e){return e instanceof Error?e.message:String(e)}function Zr(e,t){if(process.env.TDK_VERBOSE){let n=t!==void 0?`: ${Je(t)}`:"";console.warn(f.gray(`${e}${n}`))}}var S=class extends Error{suggestions;exitCode;constructor(t,n=[],r=1){super(t),this.name="TdkError",this.suggestions=n,this.exitCode=r}display(){oe(this.message,void 0,this.suggestions)}exit(){this.display(),process.exit(this.exitCode)}},re=class extends Error{code;constructor(t=1){super(`process.exit(${t})`),this.name="ProcessExitError",this.code=t}};function ne(e,t,n=!1){let r=new Set;for(let o of e){let s=Ke(o,t);s&&r.add(n?`Did you mean "${s}" for "${o}"?`:`Did you mean "${s}"?`)}return[...r]}var $={tiltNotInstalled:()=>new S("Tilt CLI is not installed",["Install Tilt: `brew install tilt` (macOS)","Or download from: https://docs.tilt.dev/install.html","Verify with: `tilt version`",`Setup guide: ${ee}`]),dockerNotAvailable:()=>new S("Docker (or a compatible container runtime) is not running",["Start Docker Desktop, then verify with: `docker ps`","Or start Colima: `colima start`","Or start the Docker service on Linux: `sudo systemctl start docker`",`Setup guide: ${ee}`]),dockerNotResponding:()=>new S("Docker is running but not responding (`docker ps` hung for 10s)",["Quit and reopen Docker Desktop, or run `colima restart`","Then verify with: `docker ps`"]),stackNotFound:(e,t=[])=>new S(`Stack "${e}" not found`,[...ne([e],t),"Run `flisk stacks` to see available stacks","Run `flisk stack` to assign resources to a stack"]),resourceNotFound:(e,t=[])=>new S(`Resource "${e}" not found`,[...ne([e],t),"Run `flisk resources` to list all resources","Check the resource name spelling"]),unknownServices:(e,t)=>{let n=ne(e,t,e.length>1);return new S(`Unknown service ${e.join(", ")}. Valid names: ${t.join(", ")}`,n,2)},directoryExists:e=>new S(`Directory already exists: ${e}`,["Use `--path` to specify a different location","Remove the existing directory if no longer needed"]),invalidPath:e=>new S(`Invalid path: ${e}`,["Path must be within the project directory",'Path cannot contain special characters like <>:"|?*']),notInProject:()=>new S("Could not find project root (no .tdk/project.json found)",["Run this from within a Flisk project","Run `flisk project --yes` to initialize a new project"])};function eo(){let e=E();return e||$.notInProject().exit()}function Qt(e){e instanceof S&&e.exit(),oe(Je(e)),process.exit(1)}async function Zt(e,t){try{return await e()}catch(n){if(n instanceof re)throw n;return t?.verbose&&n instanceof Error&&n.stack&&console.error(f.gray(n.stack)),Qt(n)}}async function to(e,t){let n=[],r=We();return r==="unresponsive"?n.push($.dockerNotResponding()):r==="missing"&&n.push($.dockerNotAvailable()),await He()||n.push($.tiltNotInstalled()),n.length>0&&(console.error(f.red(`
3
3
  Flisk can't start - missing prerequisites:
4
4
  `)),n.forEach((o,s)=>{s>0&&console.error(""),o.display()}),console.error(f.gray("\nRun `flisk doctor` for a full environment check.")),process.exit(1)),Zt(e,t)}function no(e,t=1,n){oe(e,void 0,n),process.exit(t)}function oe(e,t,n){if(console.error(f.red(`\u274C ${e}`)),t&&console.error(f.gray(` ${t}`)),n&&n.length>0){console.error(f.yellow(`
5
5
  \u{1F4A1} Suggestions:`));for(let r of n)console.error(f.cyan(` \u2192 ${r}`))}}function ro(e,t){console.error(f.red(`
@@ -0,0 +1,2 @@
1
+ import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
+ var s={demo:{repo:"https://github.com/flisk-sh/tdk-restaurant-example.git",description:"The demo stack: restaurant ops with reservations, kitchen and floor control",fixedDir:"flisk-demo"},restaurant:{repo:"https://github.com/flisk-sh/tdk-restaurant-example.git",description:"Restaurant ops: reservations, kitchen, floor control (Hono + Vite + Bun)"},saas:{repo:"https://github.com/flisk-sh/tdk-saas-starter.git",description:"SaaS starter: account dashboard and a working checkout button (Hono + Vite + Bun)"},erp:{repo:"https://github.com/flisk-sh/tdk-erp-system.git",description:"Enterprise ERP: 100 microservices across 7 business domains"},"user-management":{repo:"https://github.com/flisk-sh/tdk-user-management.git",description:"User/auth management services"},ecommerce:{repo:"https://github.com/flisk-sh/tdk-ecommerce-example.git",description:"Vue 3 storefront and Hono catalog API (needs Flisk 1.3.75+ for --framework vue)"},example:{repo:"https://github.com/flisk-sh/tdk-example.git",bundledPath:"examples/tdk-example",description:"Hono + Postgres + NATS worker + Vite example with a routed write path"},"agent-stack":{repo:"https://github.com/flisk-sh/tdk-agent-stack.git",description:"AI agent stack: Bun agent + MCP tool server + Postgres + NATS"}};function r(e){let t=e[2];if(!(!t||t.startsWith("-")))return t in s?t:void 0}export{s as a,r as b};
@@ -0,0 +1,52 @@
1
+ import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
+ import{f as O,g as ht,h as gt,i as kt,j as Z,k as St,l as yt,m as xt,n as wt,o as Pt,p as ee,q as bt,s as vt,t as Dt}from"./chunk-4TMLNLYG.js";import{b as L,c as Tt,d as G}from"./chunk-YZRPX76N.js";import{a as ut,f as dt,g as Q,j as Ct,k as $t,l as Nt,n as Et,o as Se,p as ye,r as xe,s as we,t as Rt,u as Pe,v as Ot}from"./chunk-5G7E6CO2.js";import{i as ft,o as mt}from"./chunk-BHQDQQYQ.js";import{c as pt}from"./chunk-42IVF3YT.js";import{Aa as ct,Ba as lt,Ca as ke,G as Ze,O as C,Ta as x,b,fa as et,h as M,ja as tt,k as H,l as U,m as fe,ma as st,na as he,o as me,oa as X,pa as nt,qa as rt,s as g,t as Ye,ua as ge,va as ot,wa as Y,x as $,xa as it,y as Qe,ya as at}from"./chunk-CLQSJP6M.js";import{b as h}from"./chunk-CF46CD6R.js";import{execFileSync as Ds}from"node:child_process";import{readFileSync as Ar}from"node:fs";import{join as jr}from"node:path";import{execFileSync as Wn,execSync as ls}from"node:child_process";import{existsSync as D,readdirSync as Un,readFileSync as B}from"node:fs";import{join as w,normalize as Le,relative as Be}from"node:path";import{Command as Gn}from"commander";import{existsSync as Rs}from"node:fs";var te="docs/agent-hosts.md",be=`WebContainers cannot run Flisk: there is no Docker daemon or Tilt. Run \`flisk up\` on a machine with Docker. See ${te}.`,_t=`Docker is not reachable from this Dev Container. Mount the host Docker socket (-v /var/run/docker.sock:/var/run/docker.sock) or add the docker-outside-of-docker feature to devcontainer.json, then retry. Docker-in-docker is not supported. See ${te}.`;function Os(){return{env:process.env,versions:process.versions,platform:process.platform,fileExists:Rs}}function At(e=Os()){let{env:t,versions:s,platform:n,fileExists:r}=e;return s.webcontainer?{kind:"webcontainer",canUp:!1}:t.CODESPACES==="true"?{kind:"codespaces",canUp:!0}:t.REMOTE_CONTAINERS||r("/.dockerenv")&&t.DEVCONTAINER?{kind:"devcontainer",canUp:!0}:n==="win32"?{kind:"native-windows",canUp:t.TDK_ALLOW_NATIVE_WINDOWS==="1"}:n==="linux"&&t.WSL_DISTRO_NAME?{kind:"wsl2",canUp:!0}:{kind:"local",canUp:!0}}function jt(e){return e==="devcontainer"||e==="codespaces"}function se(e){return e.some(t=>et(t.config?.appType)||t.config?.appType==="frontend"||t.config?.appType==="worker")}import{existsSync as _s,readFileSync as As}from"node:fs";import{join as js,relative as It,resolve as Ft,sep as Is}from"node:path";var Fs=2,Mt=["services/*/*"];function Ht(e){return e.split(Is).filter(Boolean)}function Ms(e,t){let s=0,n=0,r=-1,o=0;for(;n<t.length;)if(s<e.length&&e[s]!=="*"&&(e[s]==="?"||e[s]===t[n]))s++,n++;else if(s<e.length&&e[s]==="*")r=s++,o=n;else if(r!==-1)s=r+1,n=++o;else return!1;for(;s<e.length&&e[s]==="*";)s++;return s===e.length}function Hs(e,t){return e.length===t.length&&e.every((s,n)=>Ms(s,t[n]))}function ve(e){let t=js(e,".tdk",H);if(!_s(t))return Mt;try{let s=JSON.parse(As(t,"utf-8"))?.discovery?.paths;if(Array.isArray(s)&&s.every(n=>typeof n=="string"))return s}catch{}return Mt}function ne(e,t,s){let n=Ht(It(e,Ft(e,t)));return s.some(r=>{let o=Ht(It(e,Ft(e,r)));for(let i=0;i<=Fs;i++){let a=n.length-i;if(a>0&&Hs(o,n.slice(0,a)))return!0}return!1})}function zr(e,t,s,n){let r=ve(e);if(ne(e,t,r))return{path:t};let o=`services/${s}/${n}`;return ne(e,o,r)?{path:o,adjustedFrom:t}:{path:t}}import{execFile as Ls}from"node:child_process";import{promisify as Bs}from"node:util";var Vs=Bs(Ls),Ws=1e4,Us=5,Lt=10*6e4,Gs=3,Ks=200,Js=async e=>{let{stdout:t,stderr:s}=await Vs("docker",e,{encoding:"utf-8",timeout:Ws,windowsHide:!0});return`${t}${s}`};function qs(e,t){let s=Ct(t).toLowerCase(),n=e.replace(/-/g,"_").toLowerCase();return n===s||n.startsWith(`${s}_`)}function zs(e,t=Date.now()){if(e.status==="restarting")return!0;if(e.restartCount<Us)return!1;if(e.status==="running"){let n=Date.parse(e.startedAt);return Number.isNaN(n)||t-n<Lt}let s=Date.parse(e.finishedAt??"");return e.exitCode!==0&&!Number.isNaN(s)&&t-s<Lt}function Xs(e,t){let s=/database "([^"]+)" does not exist/i.exec(e);return s?`database "${s[1]}" does not exist: re-run the project's database provisioning (flisk up) or create it`:/Cannot find module|MODULE_NOT_FOUND|module not found/i.test(e)?"a module is missing from the image: rebuild it (flisk up --force) after checking the resource's dependencies":/EADDRINUSE|address already in use/i.test(e)?"the port inside the container is already in use: check for two processes started by the same command":/ECONNREFUSED|connection refused|could not connect/i.test(e)?"a dependency is not reachable: check that the service it connects to is running and healthy":/\b(?:environment variable|env var)\b.*\b(?:missing|not set|required|undefined)\b/i.test(e)||/\b[A-Z][A-Z0-9_]{2,}\b (?:is )?(?:not set|required|missing)\b/.test(e)?"a required environment variable is missing: check the project's .env":t.exitCode===137?"killed (exit 137), usually out of memory: raise the container's memory limit":null}function Ys(e){let t=[];for(let s of e.split(/\r?\n/)){let[n,r,o,i,a,c]=s.split(" ");!n||r===void 0||t.push({name:n.replace(/^\//,""),restartCount:Number(r)||0,status:o??"",startedAt:i??"",exitCode:Number(a)||0,finishedAt:c??""})}return t}async function Bt(e,t=[],s=Js,n=Date.now()){let r="Crash-looping containers",o;try{o=(await s(["ps","-a","--format",'{{.ID}} {{.Label "com.docker.compose.project"}}'])).split(/\r?\n/).map(m=>m.split(" ")).filter(([m,d])=>m&&d&&qs(d,e)).map(([m])=>m)}catch{return{name:r,didPass:!0,isSkipped:!0,message:"Docker not available - skipped crash-loop check"}}if(o.length===0)return{name:r,didPass:!0,isSkipped:!0,message:"No project containers to check"};let i;try{i=Ys(await s(["inspect","--format","{{.Name}} {{.RestartCount}} {{.State.Status}} {{.State.StartedAt}} {{.State.ExitCode}} {{.State.FinishedAt}}",...o]))}catch{return{name:r,didPass:!0,isSkipped:!0,message:"Containers changed while checking - skipped crash-loop check"}}let a=i.filter(f=>zs(f,n));if(a.length===0)return{name:r,didPass:!0,message:"No project container is crash-looping"};let c=[],l=new Set;for(let f of a){let m="";try{m=await s(["logs","--tail",String(Gs),f.name])}catch{}let d=X(m,t).split(/\r?\n/).map(k=>k.trim().slice(0,Ks)).filter(Boolean),S=Xs(m,f);S&&l.add(S),c.push([`${f.name}: ${f.status}, restarted ${f.restartCount} times`,...d.map(k=>` | ${k}`)].join(`
3
+ `))}return{name:r,didPass:!1,message:`${a.length} container${a.length===1?" is":"s are"} crash-looping:
4
+ ${c.join(`
5
+ `)}`,fix:[...l,"Read the full log: docker logs <container>"].join("; ")}}import{execFile as dn,execFileSync as pn}from"node:child_process";import{existsSync as fn,realpathSync as Jt,statfsSync as mn}from"node:fs";import{homedir as hn}from"node:os";import{join as gn}from"node:path";import{promisify as kn}from"node:util";import{statfsSync as Qs}from"node:fs";import{homedir as Zs}from"node:os";var re="Disk Space",en=1024**3,tn=2,De=10,Vt=["Free disk space, then retry: flisk doctor"," docker system prune -af # unused images and build cache (needs Docker running)"," npm cache clean --force"," bun pm cache rm"," brew cleanup -s"].join(`
6
+ `);function Wt(e=Qs,t=Zs()){let s;try{let r=e(t);s=Number(r.bavail)*Number(r.bsize)/en}catch{return{name:re,didPass:!0,isSkipped:!0,message:"Could not read free disk space"}}let n=`${s.toFixed(1)} GB free`;return s<tn?{name:re,didPass:!1,message:`${n}: Docker cannot build or start containers`,fix:Vt}:s<De?{name:re,didPass:!1,isWarning:!0,message:`${n}: image builds may fail`,fix:Vt}:{name:re,didPass:!0,message:n}}var sn="Quit Docker Desktop completely (whale icon > Quit Docker Desktop), reopen it, and wait until it shows Running. If it keeps getting stuck, check free disk space. Then retry: flisk doctor";function Ut(e,t=process.platform){return t!=="darwin"||!e?null:{name:"Container Runtime",didPass:!1,message:"Docker Desktop is open, but its engine is not responding",fix:sn}}import{execFileSync as nn}from"node:child_process";var Te=(e,t)=>nn(e,t,{encoding:"utf-8",stdio:"pipe",windowsHide:!0}),Gt=["traefik-public","traefik-private","backend","database","infisical-network","verdaccio-network","proxy"];function Ce(e){let t=e.replace(/-/g,"_");return Gt.map(s=>`${t}_${s}`)}function Kt(e){let t=new Set;for(let s of e)for(let n of["traefik-public","traefik-private"])s.endsWith(`_${n}`)&&t.add(s.slice(0,-(n.length+1)));return t}function $e(e,t){for(let s of Gt)if(e.endsWith(`_${s}`)){let n=e.slice(0,-(s.length+1));if(t.has(n))return n}return null}function io(e,t=Te){let s=new Set(t("docker",["network","ls","--format","{{.Name}}"]).split(/\r?\n/).map(r=>r.trim()).filter(Boolean)),n={removed:[],kept:[]};for(let r of Ce(e))if(s.has(r))try{t("docker",["network","rm",r]),n.removed.push(r)}catch(o){let i=String(o.stderr??o).trim();n.kept.push({name:r,reason:i.split(/\r?\n/)[0]??""})}return n}function oe(e,t=process.platform,s=Te){if(t==="win32")return[];let n;try{n=s("ps",["-axo","pid=,command="])}catch{return[]}let r=[];for(let o of n.split(/\r?\n/)){let i=/^\s*(\d+)\s+(.*)$/.exec(o);if(!i)continue;let a=i[2]??"",c=(a.split(/\s+/)[0]??"").split("/").at(-1),l=` -f ${e}`,f=a.indexOf(l),m=a[f+l.length];c==="tilt"&&/^\S+\s+up\s/.test(a)&&f>0&&(m===void 0||m===" ")&&r.push(Number(i[1]))}return r}function ao(e,t=process.platform,s=Te){let n=oe(e,t,s);for(let r of n)try{s("kill",["-TERM",String(r)])}catch{}return n}async function co(e,t=8e3,s=oe){let n=Date.now()+t;for(;s(e).length>0;){if(Date.now()>=n)return!1;await new Promise(r=>setTimeout(r,250))}return!0}import{execFile as rn}from"node:child_process";function Ne(e){return new Promise(t=>{rn($("tilt")??"tilt",["get","uiresources","-o","json","--port",String(e)],{timeout:15e3,maxBuffer:16*1024*1024},(s,n)=>t(s?null:n))})}function on(e){let s=(JSON.parse(e).items??[]).filter(n=>n.status?.disableStatus?.state!=="Disabled").map(n=>n.status?.updateStatus==="not_applicable"?{...n,status:{...n.status,updateStatus:"ok"}}:n);return JSON.stringify({items:s})}function an(e){return(JSON.parse(e).items??[]).filter(t=>t.status?.disableStatus?.state!=="Disabled").flatMap(t=>t.metadata?.name?[t.metadata.name]:[])}function cn(e,t){let s=JSON.parse(e).items??[],n=new Map(s.map(r=>[r.metadata?.name,r]));return{missing:t.filter(r=>!n.has(r)),disabled:t.filter(r=>n.get(r)?.status?.disableStatus?.state==="Disabled")}}function ln(e){return e.endsWith("-typecheck")}function un(e,t,s){let n=Nt(on(e),t),r=n.failures.filter(i=>!ln(i.name)),o={ready:r.length===0&&n.pendingCount===0&&n.okCount>0,failures:r.map(i=>({name:i.name,message:i.error||`${i.updateStatus}/${i.runtimeStatus}`})),pending:n.pendingCount,timedOut:!1,enabled:an(e)};if(s&&s.length>0){let{missing:i,disabled:a}=cn(e,s);if(i.length>0&&(o={...o,ready:!1,pending:o.pending+i.length}),a.length>0)return{settled:!0,result:{...o,ready:!1,failures:[...o.failures,...a.map(c=>({name:c,message:"disabled in Tilt"}))]}}}return{result:o,settled:o.ready||o.failures.length>0&&o.pending===0}}async function mo(e,t={}){let s=t.timeoutMs??Number(process.env.TDK_UP_READY_TIMEOUT_MS??9e5),n=t.intervalMs??2e3,r=t.fetchJson??Ne,o=t.deferred??$t(),i=Date.now()+s,a={ready:!1,failures:[],pending:0,timedOut:!1,enabled:[]};for(;;){let c=await r(e);if(c)try{let l=un(c,o,t.expected);if(a=l.result,l.settled||a.failures.length>0&&t.isStalled?.(c))return a}catch{}if(Date.now()>=i)return{...a,ready:!1,timedOut:!0};await new Promise(l=>setTimeout(l,n))}}var I=kn(dn),Sn=15e3,yn=/^tdk_doctor_probe_(\d+)$/,xn=async e=>{let{stdout:t}=await I("docker",e,{encoding:"utf-8",timeout:Sn,windowsHide:!0});return t};function wn(){try{return pn("docker",["info","--format","{{.ServerVersion}}"],{encoding:"utf-8",timeout:15e3,stdio:["ignore","pipe","ignore"]}),!0}catch{return!1}}function ie(e){return String(e.stderr??e).trim().split(/\r?\n/)[0]??""}var Pn=120;function bn(e){let t=/^\s*(?:(?:(\d+)-)?(\d+):)?(\d+):(\d+)\s*$/.exec(e);if(!t)return null;let[,s="0",n="0",r="0",o="0"]=t;return((Number(s)*24+Number(n))*60+Number(r))*60+Number(o)}async function vn(e,t=Ne,s=2,n=r=>new Promise(o=>setTimeout(o,r))){for(let r=0;r<s;r++){r>0&&await n(1e3);for(let o of e)if(await t(o)!==null)return!0}return!1}async function Dn(e){if(process.platform==="win32")return"unknown";try{let{stdout:t}=await I("ps",["-p",String(e),"-o","etime="],{encoding:"utf-8",timeout:5e3}),s=bn(t);if(s===null||s<Pn)return"unknown";let{stdout:n}=await I("lsof",["-nP","-a","-p",String(e),"-iTCP","-sTCP:LISTEN","-Fn"],{encoding:"utf-8",timeout:5e3}),r=[...n.matchAll(/^n.*:(\d+)$/gm)].map(o=>Number(o[1]));return await vn(r)?"healthy":"stale"}catch{return"unknown"}}function Tn(e=xn){return{colima:Cn,colimaStatus:()=>L(),dockerAnswers:wn,async listNetworks(){let t=(await e(["network","ls","--format","{{.Name}}"])).split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return(await Promise.all(t.map(async n=>{try{let r=await e(["network","inspect","--format","{{len .Containers}}",n]);return{name:n,containers:Number(r.trim())||0}}catch(r){if(/no such network|not found/i.test(String(r)))return null;throw r}}))).filter(n=>n!==null)},async removeNetwork(t){try{await e(["network","rm",t])}catch(s){throw new Error(ie(s))}},freeDiskGib(){try{let t=mn(hn());return Number(t.bavail)*Number(t.bsize)/1024**3}catch{return null}},async reclaimable(){let t=null;try{let n=await e(["system","df","--format","{{.Type}} {{.Reclaimable}}"]);for(let r of n.split(/\r?\n/)){let[o,i]=r.split(" ");o==="Build Cache"&&i&&(t=i.replace(/\s*\(.*\)/,"").trim())}}catch{}let s=0;try{s=(await e(["images","-q","-f","dangling=true"])).split(/\r?\n/).filter(Boolean).length}catch{}return{buildCache:t,danglingImages:s}},async prune(t){try{await e(t==="builder"?["builder","prune","-f"]:["image","prune","-f"])}catch(s){throw new Error(ie(s))}},async tiltStatus(t){return Dn(t)},stopProcess(t){process.kill(t,"SIGTERM")},isProcessAlive(t){try{return process.kill(t,0),!0}catch(s){return s.code==="EPERM"}}}}var qt=Tn();async function Cn(e){if(e==="native-lima"){let n=G();if(!n){let o=fn("/opt/homebrew/bin/brew")?"/opt/homebrew/bin/brew":"brew";if(await I(o,["reinstall","lima"],{encoding:"utf-8",timeout:3e5}),n=G(),!n)throw new Error("brew reinstall lima did not provide a native limactl")}let r=n?{...process.env,PATH:`${n}:${process.env.PATH??""}`}:process.env;await I("colima",["start"],{encoding:"utf-8",timeout:3e5,env:r});return}let t=G(),s=t?{...process.env,PATH:`${t}:${process.env.PATH??""}`}:process.env;await I("colima",[e],{encoding:"utf-8",timeout:3e5,env:s})}async function zt(e,t=qt,s={}){let n=[],r=[];for(let d of s.tiltPids??[])await t.tiltStatus(d)==="stale"?n.push({id:`stop-tilt:${d}`,check:"Tilt processes",scope:"project",command:`kill -TERM ${d}`,status:"planned",reason:"this project's Tilt is running but its UI does not answer"}):r.push(d);let o=r.length>0?`Tilt is running for this project (pid ${r.join(", ")}); run flisk down first`:void 0,i=t.colimaStatus(),a=Tt(i,t.dockerAnswers());if(a==="start")n.push({id:"colima:start",check:"Colima",scope:"host",command:"colima start",status:"planned",reason:i.problem??"the Colima VM is not running"});else if(a==="restart")n.push({id:"colima:restart",check:"Colima",scope:"host",command:"colima restart",status:"planned",reason:"the Colima VM is running but its Docker daemon does not answer"});else if(a==="native-lima"){let d=G();n.push({id:"colima:native-lima",check:"Colima",scope:"host",command:d?`PATH="${d}:$PATH" colima start`:"brew reinstall lima",status:"planned",reason:d?`the colima CLI on this PATH cannot see the VM; a native limactl is installed in ${d}`:"the colima CLI on this PATH cannot see the VM; lima is installed as an x86_64 build (brew reinstall lima)"})}let c=await t.listNetworks(),l=t.freeDiskGib();if(l!==null&&l<De){let{buildCache:d,danglingImages:S}=await t.reclaimable(),k=`${l.toFixed(1)} GB free`;d&&!/^0(\.0+)?\s*B$/i.test(d)&&n.push({id:"prune:builder",check:"Disk Space",scope:"host",command:"docker builder prune -f",status:"planned",reason:`${k}; ${d} of build cache reclaimable`}),S>0&&n.push({id:"prune:images",check:"Disk Space",scope:"host",command:"docker image prune -f",status:"planned",reason:`${k}; ${S} untagged image${S===1?"":"s"}`})}let f=new Set(e?Ce(e):[]),m=Kt(c.map(d=>d.name));for(let d of c){let S=yn.exec(d.name),k,y,p="unused network";if(S)k="probe",y="Orphaned probe networks";else if(f.has(d.name))k="project",y="Docker networks";else if(s.machine&&$e(d.name,m))k="machine",y="Docker networks",p=`unused network of project "${$e(d.name,m)}"`;else continue;let v={id:`remove-network:${d.name}`,check:y,scope:k,command:`docker network rm ${d.name}`,status:"planned",reason:p};d.containers>0?(v.status="skipped",v.reason=`${d.containers} container(s) still attached`):k==="project"&&o?(v.status="skipped",v.reason=o):S&&t.isProcessAlive(Number(S[1]))&&(v.status="skipped",v.reason=`probe of a running process (pid ${S[1]})`),n.push(v)}return n}async function Xt(e,t,s=qt){let n=[];for(let r of e){if(r.status!=="planned"||t.dryRun){n.push(r);continue}if(!t.confirm){n.push({...r,status:"skipped",reason:"confirmation required; run in a terminal or pass --yes"});continue}let o=!1;try{o=await t.confirm(r)}catch{}if(!o){n.push({...r,status:"skipped",reason:"not confirmed"});continue}try{if(r.id.startsWith("prune:")){await s.prune(r.id==="prune:builder"?"builder":"images"),n.push({...r,status:"applied",reason:"pruned"});continue}if(r.id.startsWith("colima:")){let i=r.id.slice(7);if(i==="start"||i==="restart"){await s.colima(i),n.push({...r,status:"applied",reason:`colima ${i} ran`});continue}try{await s.colima("native-lima"),n.push({...r,status:"applied",reason:"native lima repaired and colima started"})}catch(a){n.push({...r,status:"failed",reason:ie(a)})}continue}if(r.id.startsWith("stop-tilt:")){s.stopProcess(Number(r.id.slice(10))),n.push({...r,status:"applied",reason:"stopped"});continue}await s.removeNetwork(r.id.slice(15)),n.push({...r,status:"applied",reason:"removed"})}catch(i){n.push({...r,status:"failed",reason:ie(i)})}}return n}function Yt(e){return e.some(t=>t.status==="failed")}async function $n(e){try{let{stdout:t}=await I(e,["--version"],{encoding:"utf-8",timeout:5e3,windowsHide:!0});return t.trim().split(/\r?\n/)[0]||null}catch{return null}}async function Nn(e=Qe("flisk"),t=$n){let s=new Set,n=[];for(let r of e){let o=r;try{o=Jt(r)}catch{}s.has(o)||(s.add(o),n.push({path:r,version:await t(r)}))}return n}async function Qt(e){let t=e??await Nn();if(t.length<=1)return{name:"Flisk installs",didPass:!0,message:"One flisk install on PATH"};let s=t.map(r=>`${r.path} (${r.version??"version unknown"})`).join(", "),n=new Set(t.map(r=>r.version));return{name:"Flisk installs",didPass:!1,isWarning:!0,message:`${t.length} flisk installs on PATH${n.size>1?" with different versions":""}: ${s}`,fix:"Keep one: remove the others, or run flisk upgrade. The first on PATH is the one your shell runs; tools that launch /usr/local/bin/flisk directly may use another"}}function Zt(e,t=oe){let s=new Set([e]);try{s.add(Jt(e))}catch{}let n=new Set;for(let r of s)for(let o of t(gn(r,".tdk",".tdk-out","Tiltfile")))n.add(o);return[...n]}var Ee=1;function En(e,t=[]){return{schemaVersion:Ee,data:e,errors:t}}function Rn(e){return e instanceof Ze?{error:{code:"COMMAND_FAILED",message:e.message,...e.suggestions.length>0?{suggestions:e.suggestions}:{}},exitCode:e.exitCode}:{error:{code:"INTERNAL",message:e instanceof Error?e.message:String(e)},exitCode:2}}function $o(e){let t=Rn(e);console.log(JSON.stringify(En(null,[t.error]))),console.error(t.error.message),process.exit(t.exitCode)}async function ts(e,t){let s=[],n=[],r=o=>{o.status==="fulfilled"?s.push(o.value):n.push({code:"INTERNAL",message:o.reason instanceof Error?o.reason.message:String(o.reason)})};for(let o of await Promise.allSettled(e.map(i=>Promise.resolve().then(i))))r(o);for(let o of t)for(let i of await Promise.allSettled([Promise.resolve().then(o)]))r(i);return{checks:s,errors:n}}function es(e){let t=e.find(s=>s.name===b);return t?t.didPass:null}function j(e,t,s=[],n,r){return{schemaVersion:Ee,data:{ready:s.length===0&&e.every(o=>o.didPass||o.isSkipped||o.isWarning),inProject:t,checks:e,...r?{host:{...r,containerRuntimeReachable:es(e),canUp:r.canUp&&es(e)!==!1}}:{},...n!==void 0?{ports:{http:{requested:n?.requested.ingressHttp??80,chosen:n?.ingressHttp??null,explicit:n?.explicit.ingressHttp??!!process.env.TDK_HTTP_PORT,reason:n?.reason.ingressHttp??"port planning failed"},https:{requested:n?.requested.ingressHttps??443,chosen:n?.ingressHttps??null,explicit:n?.explicit.ingressHttps??!!process.env.TDK_HTTPS_PORT,reason:n?.reason.ingressHttps??"port planning failed"},postgres:{requested:n?.requested.postgres??5432,chosen:n?.postgres??null,explicit:n?.explicit.postgres??!!process.env.TDK_POSTGRES_PORT,reason:n?.reason.postgres??"port planning failed"}}}:{}},errors:s}}function ss(e){return e.errors.length>0?2:e.data.ready?0:1}import{existsSync as Oe,readFileSync as ns}from"node:fs";import{dirname as On,join as Re,normalize as _n}from"node:path";function An(e){let t=new Set,s=/^load\s*\(([\s\S]*?)\)/gm;for(let n of e.matchAll(s)){let r=n[1]??"",o=/["']([^"']+)["']/g,i=Array.from(r.matchAll(o),a=>a[1]);for(let a of i.slice(1))a.startsWith("_")&&t.add(a)}return Array.from(t).sort()}function rs(e,t,s){return t==="ext://tdk-cli"?Re(s,".tdk",".tdk-out","tdk-cli-ext","Tiltfile"):t.startsWith(".")||!t.includes("://")&&!t.startsWith("@")?_n(Re(On(e),t)):null}function jn(e,t,s){let n=[],r=/^load\s*\(([\s\S]*?)\)/gm;for(let o of t.matchAll(r)){let c=(o[1]??"").match(/["']([^"']+)["']/)?.[1];if(!c)continue;let l=rs(e,c,s);l&&(Oe(l)||n.push(`${e}: ${c} -> ${l}`))}return n}function In(e,t,s){let n=[],r=/^load\s*\(([\s\S]*?)\)/gm;for(let o of t.matchAll(r)){let c=(o[1]??"").match(/["']([^"']+)["']/)?.[1];if(c){let l=rs(e,c,s);l&&n.push(l)}}return n}function Fn(e,t){let s=new Set,n=[e];for(;n.length>0;){let r=n.pop();if(!r||s.has(r)||!Oe(r))continue;s.add(r);let o=ns(r,"utf-8");for(let i of In(r,o,t))s.has(i)||n.push(i)}return Array.from(s).sort()}function os(){let e=g()??process.cwd(),t=Re(e,".tdk",".tdk-out","Tiltfile");if(!Oe(t))return{name:"Starlark Load Exports",didPass:!0,isSkipped:!0,message:"No generated Tiltfile to check"};let s=[],n=[],r=Fn(t,e);for(let i of r){let a=ns(i,"utf-8"),c=An(a);c.length>0&&s.push(`${i}: ${c.join(", ")}`);for(let l of jn(i,a,e))n.push(l)}if(s.length===0&&n.length===0)return{name:"Starlark Load Exports",didPass:!0,message:`${C(r.length,"reachable Starlark file")} ${r.length===1?"has":"have"} valid load exports and paths`};let o=[];return s.length>0&&o.push(`Private exported symbols:
7
+ ${s.join(`
8
+ `)}`),n.length>0&&o.push(`Missing relative load targets:
9
+ ${n.join(`
10
+ `)}`),{name:"Starlark Load Exports",didPass:!1,message:`Starlark load() issues will stop Tilt before services start:
11
+ ${o.join(`
12
+
13
+ `)}`,fix:"Regenerate with a current Flisk (`flisk config regenerate`). If the issue remains, rename loaded symbols without leading underscores and update stale load paths."}}import{relative as Mn}from"node:path";function ae(e,t){return Mn(e,t.configPath)||t.configPath}function is(e){let t=e.config?.dependsOn;return t===void 0?[]:Array.isArray(t)&&t.every(s=>typeof s=="string")?t:null}function Hn(e){let t=new Set(e.map(a=>a.name)),s=new Map(e.map(a=>[a.name,(is(a)??[]).filter(c=>t.has(c))])),n=new Map,r=new Map,o=[],i=a=>{r.set(a,"visiting"),o.push(a);for(let c of s.get(a)??[])if(r.get(c)==="visiting"){let l=o.slice(o.indexOf(c)),f=l.indexOf([...l].sort()[0]??c),m=[...l.slice(f),...l.slice(0,f)];n.set(m.join(">"),[...m,m[0]??c])}else r.has(c)||i(c);o.pop(),r.set(a,"done")};for(let a of[...s.keys()].sort())r.has(a)||i(a);return[...n.values()]}function _e(e=g()??process.cwd(),t=x(e)){let s=t.flatMap(n=>is(n)===null?[`${ae(e,n)} dependsOn ${JSON.stringify(n.config?.dependsOn)}: expected an array of service names`]:[]);return s.length===0?{name:"dependsOn",didPass:!0,message:"Every dependsOn is a list of service names"}:{name:"dependsOn",didPass:!1,message:`${C(s.length,"invalid dependsOn","invalid dependsOn")}:
14
+ ${s.join(`
15
+ `)}`,fix:'Write "dependsOn" as an array of service names, for example ["postgres", "api"]'}}function Ae(e=g()??process.cwd(),t=x(e)){let s=new Map(t.map(o=>[o.name,o])),n=Hn(t);if(n.length===0)return{name:"Circular dependencies",didPass:!0,message:"No service depends on itself through dependsOn"};let r=n.map(o=>{let i=s.get(o[0]??""),a=o[1]??"";return`${i?ae(e,i):o[0]} dependsOn "${a}": circular dependency ${o.join(" -> ")}`});return{name:"Circular dependencies",didPass:!1,message:`${n.length} ${n.length===1?"circular dependency":"circular dependencies"}:
16
+ ${r.join(`
17
+ `)}`,fix:'Remove one "dependsOn" entry in each cycle so the services no longer wait on each other, or move what they share into a third service'}}function je(e=g()??process.cwd(),t=x(e)){let s=t.flatMap(n=>{let r=n.config?.port;return r===void 0?[]:typeof r=="number"&&Number.isInteger(r)&&r>=1&&r<=65535?[]:[`${ae(e,n)} port ${JSON.stringify(r)}: not an integer from 1 to 65535`]});return s.length===0?{name:"Service ports",didPass:!0,message:"Every declared port is valid"}:{name:"Service ports",didPass:!1,message:`${C(s.length,"invalid port")}:
18
+ ${s.join(`
19
+ `)}`,fix:'Set "port" to the port the service listens on, an integer from 1 to 65535'}}function Ie(e=g()??process.cwd(),t=!1,s=x(e)){let n=[],r=[];for(let i of s){let a=i.config?.schemaVersion;if(a===ke)continue;let c=ae(e,i);a===void 0?n.push(`${c} schemaVersion: missing`):r.push(`${c} schemaVersion ${JSON.stringify(a)}: this flisk supports ${ke}`)}if(n.length===0&&r.length===0)return{name:"schemaVersion",didPass:!0,message:"Every service.json has a supported schemaVersion"};let o=[...n.length>0?["Run `flisk config migrate` to add the missing schemaVersion"]:[],...r.length>0?["A version this flisk does not support cannot be migrated: upgrade flisk"]:[]];return{name:"schemaVersion",didPass:!1,isWarning:!t,message:`${C(n.length+r.length,"service.json file")} without a supported schemaVersion:
20
+ ${[...n,...r].join(`
21
+ `)}`,fix:o.join(". ")}}function Go(e,t){let s=Ie(e,!1,t);s.didPass||(console.warn(h.yellow(`\u26A0 ${s.message}`)),s.fix&&console.warn(h.gray(` ${s.fix}`)))}function Ko(e,t={},s=process.exit){let n=t.resources??x(e),r=[Z(e,n),_e(e,n),Ae(e,n),je(e,n)].filter(i=>!i.didPass);if(r.length===0)return;let o=r.map(i=>`${i.message}${i.fix?`
22
+ Fix: ${i.fix}`:""}`).join(`
23
+ `);t.onInvalid?.(o);for(let i of r)console.error(h.red(`\u2717 ${i.message}`)),i.fix&&console.error(h.gray(` Fix: ${i.fix}`));s(1)}import{readFileSync as Ln}from"node:fs";import{join as Bn}from"node:path";function as(e){let t=e.trim().match(/(\d+)\.(\d+)(?:\.(\d+))?/);return t?[Number(t[1]),Number(t[2]),Number(t[3]??0)]:null}function Vn(e){try{return JSON.parse(Ln(Bn(e,".tdk",H),"utf-8"))?.minTdkVersion}catch{return}}function cs(e,t){let s=Vn(e);if(s===void 0)return{status:"none"};let n=typeof s=="string"?as(s):null;if(!n||!/^\d+\.\d+\.\d+$/.test(String(s).trim()))return{status:"malformed",message:`.tdk/project.json minTdkVersion ${JSON.stringify(s)} is not a version like "1.3.80"`,fix:'Set minTdkVersion to a MAJOR.MINOR.PATCH string, for example "1.3.80".'};let r=as(t),o=r!==null&&(()=>{for(let[a,c]of n.entries()){let l=r[a]??0;if(l!==c)return l>c}return!0})(),i=n.join(".");return o?{status:"ok",required:i}:{status:"too-old",required:i,message:`flisk ${t} is older than the ${i} this project requires (minTdkVersion)`,fix:"Run: flisk upgrade"}}var R=1e4,E={dockerMissing:"See https://docs.docker.com/get-docker/",dockerDaemonDown:"Start Docker Desktop, OrbStack, or Colima, then retry: flisk doctor",tiltMissing:"curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash",bunMissing:"curl -fsSL https://bun.sh/install | bash",port80:"Stop the process bound to port 80, or stop local nginx/caddy. Then: flisk doctor",port5432:"Stop local Postgres or change the host port. Then: flisk doctor",notProject:"flisk project --yes"},us="WSL2 detected. Use Docker Desktop WSL integration. Guide: docs/wsl2.md",ds="Native Windows landscape boot is unsupported. Use WSL2 Ubuntu with Docker Desktop integration. Guide: docs/wsl2.md",Fe=[0,25,0],F=[1,2,0];function ce(e,t){let s=We(e);return s?Ue(s,t):!1}function Kn(e,t,s=process.platform==="linux"&&!!process.env.WSL_DISTRO_NAME){if(!s)return{name:"WSL project location",didPass:!0,isSkipped:!0,message:"Not running in WSL2 - skipped project filesystem check"};let n=e.replace(/\\/g,"/").replace(/\/+$/,"").toLowerCase();if(n!=="/mnt/c"&&!n.startsWith("/mnt/c/"))return{name:"WSL project location",didPass:!0,message:`${us} Project is on the WSL filesystem.`};let r=`${us} Project is under /mnt/c (${e}); hot reload may be broken. Move it into the WSL filesystem, such as ~/projects.`;return{name:"WSL project location",didPass:!t,isWarning:!t,message:r,fix:"Move the repository under your WSL home directory (for example, ~/projects) and retry flisk doctor."}}function Jn(e){let t=e.replace(/^\[(.*)\]$/,"$1");return t==="0.0.0.0"||/^[0:]*:0\.0\.0\.0$/.test(t)?!0:t.includes(":")&&/^[0:]+$/.test(t)}function qn(e=process.env,t=!1){let s=(e.TDK_BIND_ADDRESS??"").trim();return Jn(s)?{name:"Dev Port Bind Address",didPass:!t,isWarning:!t,message:`TDK_BIND_ADDRESS is ${s}: Traefik and Postgres are reachable from other machines on the network.`,fix:"Unset TDK_BIND_ADDRESS to keep dev ports on 127.0.0.1. Keep it only when you test from another device on purpose."}:{name:"Dev Port Bind Address",didPass:!0,message:s?`Dev ports bind to ${s}`:"Dev ports bind to 127.0.0.1 (this machine only)"}}function ms(e){let t=e.filter(n=>!n.didPass&&!n.isSkipped&&!n.isWarning),s=e.filter(n=>n.didPass||n.isSkipped||n.isWarning);return t.sort((n,r)=>{let o=i=>i.name==="Host Ports"&&/\b5432\b/.test(i.message)?0:i.name==="Host Ports"?1:i.name==="Ingress Ports"?2:3;return o(n)-o(r)}),[...t,...s]}function zn(e,t){return t?e?"Doctor passed. Next: flisk up":"Doctor passed. Next: flisk project example":"Doctor failed. Fix the items above, then run: flisk doctor"}var Ve={checkDockerOperatingSystem:"Docker OS",checkDockerCompose:"Docker Compose",checkDockerVersions:"Docker Versions",checkDockerNetworkCapacity:"Docker Network Pool",checkContainerResourceHealth:"Container Resource Health",checkCrashLoopingContainers:"Crash-looping containers",checkTiltResourceHealth:"Tilt Resources",checkServiceHealth:"Service Health",checkServiceSmoke:"Service Smoke",checkAdvertisedEndpoints:"Advertised Endpoints"},ps=new Set(["Docker OS","Docker Compose","Docker Versions","Docker Network Pool","Container Resource Health","Crash-looping containers","Tilt Resources","Service Health","Service Smoke","Advertised Endpoints",...Object.keys(Ve)]);function Xn(e){return!!(e.requiresContainerRuntime||e.checkName&&ps.has(e.checkName)||e.name&&ps.has(e.name))}function N(e,t){let s=()=>t();return s.requiresContainerRuntime=!0,s.checkName=e,s}async function Yn(e,t={}){let s=[],n=!!t.containerRuntimeFailed;for(let r of e){if(n&&Xn(r)){let i=r.checkName??(r.name&&Ve[r.name]?Ve[r.name]:r.name&&r.name!=="check"&&r.name!=="fn"?r.name:"Container check");s.push({name:i,didPass:!0,isSkipped:!0,message:`Docker not running - skipped ${i} check`});continue}let o=await r();if(s.push(o),o.name===b&&!o.didPass&&(n=!0),!t.all&&!o.didPass&&!o.isSkipped&&!o.isWarning)break}return s}function Qn(e){let t=0,s=0,n=0,r=0;for(let o of e)o.isSkipped?n++:o.isWarning?r++:o.didPass?t++:s++;return r>0?`${t} passed, ${r} warned, ${s} failed, ${n} skipped`:`${t} passed, ${s} failed, ${n} skipped`}function Ke(e){return ht(e)}function Zn(e,t,s,n,r){return async(o=O)=>{try{return await o(t,R),{name:e,didPass:!0,message:s}}catch(i){return Ke(i)?{name:e,didPass:!1,message:`${e} did not respond within ${R/1e3}s`,fix:r}:{name:e,didPass:!1,message:n,fix:r}}}}async function Me(e){try{return await O(e,R),!0}catch{return!1}}async function er(){let e=L();return e.isColima?e.running&&!e.problem?{name:"Colima",didPass:!0,message:`Colima VM is running${e.arch?` (${e.arch})`:""}`}:{name:"Colima",didPass:!1,message:e.problem??"The Colima VM is not running",fix:e.fix}:{name:"Colima",didPass:!0,message:"Docker does not run on Colima"}}async function Je(){if(process.platform==="win32")try{return await O("docker ps",R),{name:b,didPass:!0,message:"Docker Desktop Linux container engine is running"}}catch{return{name:b,didPass:!1,message:"Docker is not running",fix:E.dockerDaemonDown}}let e=!!$("docker");try{return await O("docker ps",R),{name:b,didPass:!0,message:"Docker daemon is running"}}catch(s){if(Ke(s))return{name:b,didPass:!1,message:"Docker daemon is not responding",fix:E.dockerDaemonDown}}let t=Ut(await Me("pgrep -f com.docker.backend"));return t||(await Me("colima status")?{name:b,didPass:!0,message:"Colima (Docker runtime) is running"}:$("colima")?{name:b,didPass:!1,message:"Colima is installed but not running",fix:E.dockerDaemonDown}:await Me("podman ps")?{name:b,didPass:!0,message:"Podman is running"}:e?{name:b,didPass:!1,message:"Docker daemon is not running",fix:E.dockerDaemonDown}:{name:b,didPass:!1,message:"Docker is not running",fix:E.dockerMissing})}var K=Zn("Docker Compose","docker compose version","Docker Compose plugin available","Docker Compose plugin not found","Install Docker Compose: https://docs.docker.com/compose/install/");K.requiresContainerRuntime=!0;K.checkName="Docker Compose";var tr=[25,0,0],sr=[2,20,2];function We(e){let t=e.trim().match(/(\d+)\.(\d+)(?:\.(\d+))?/);return t?[Number(t[1]),Number(t[2]),Number(t[3]??0)]:null}function Ue(e,t){for(let[s,n]of t.entries()){let r=e[s]??0;if(r!==n)return r>n}return!0}async function J(e=O){let t=async a=>String(await e(a,R)).trim(),s,n;try{[s,n]=await Promise.all([t("docker version --format '{{.Server.Version}}'"),t("docker compose version --short")])}catch{return{name:"Docker Versions",didPass:!0,isSkipped:!0,message:"Could not read Docker Engine/Compose versions - skipped version check"}}let r=We(s),o=We(n);if(!r||!o)return{name:"Docker Versions",didPass:!0,isSkipped:!0,message:`Unrecognized Docker version output (engine "${s}", compose "${n}") - skipped version check`};let i=[];return Ue(r,tr)||i.push(`Docker Engine ${s} (need 25.0+)`),Ue(o,sr)||i.push(`Docker Compose ${n} (need 2.20.2+)`),i.length===0?{name:"Docker Versions",didPass:!0,message:`Docker Engine ${s} and Compose ${n} support generated healthchecks`}:{name:"Docker Versions",didPass:!1,message:`Docker is too old for generated healthchecks (they use start_interval):
24
+ ${i.join(`
25
+ `)}`,fix:"Update Docker Desktop, or on Linux update docker-ce and the docker-compose-plugin package"}}J.requiresContainerRuntime=!0;J.checkName="Docker Versions";async function qe(e=O){let t;try{t=String(await e("tilt version",R)).trim()}catch{return{name:"Tilt CLI",didPass:!1,message:"Tilt CLI not found",fix:E.tiltMissing}}return ce(t,Fe)?{name:"Tilt CLI",didPass:!0,message:`Tilt ${t} is available`}:{name:"Tilt CLI",didPass:!1,message:`Tilt ${t||"version unknown"} is below the required v${Fe.join(".")} floor`,fix:`Install Tilt v${Fe.join(".")} or newer: https://docs.tilt.dev/install.html`}}async function ze(e=O){let t;try{t=String(await e("docker info --format '{{.OSType}}'",R)).trim().toLowerCase()}catch{return{name:"Docker OS",didPass:!0,isSkipped:!0,message:"Docker OS unavailable - daemon failure reported separately"}}return t!=="linux"?{name:"Docker OS",didPass:!1,message:`Docker is using the ${t||"unknown"} engine; Flisk requires Linux containers`,fix:"Switch Docker Desktop to Linux containers, enable WSL2 integration, then retry flisk doctor."}:{name:"Docker OS",didPass:!0,message:"Docker is using Linux containers"}}ze.requiresContainerRuntime=!0;ze.checkName="Docker OS";async function nr(e=O){let t=g();if(!t)return{name:"Bun",didPass:!0,isSkipped:!0,message:"Not in a project - skipping Bun check"};if(!se(x(t)))return{name:"Bun",didPass:!0,isSkipped:!0,message:"No generated JS services - skipping Bun check"};try{let s=String(await e("bun --version",R)).trim();return ce(s,F)?{name:"Bun",didPass:!0,message:`Bun ${s} is available`}:{name:"Bun",didPass:!1,message:`Bun ${s||"version unknown"} is below the required ${F.join(".")} floor`,fix:`Install Bun ${F.join(".")} or newer: https://bun.sh/install`}}catch{return{name:"Bun",didPass:!1,message:"Bun is not available",fix:E.bunMissing}}}function rr(){let e=g()??process.cwd(),t=tt(e);if(t.missing.length>0)return{name:"Environment Variables",didPass:!1,message:`Missing required env variables: ${t.missing.join(", ")}`,fix:D(w(e,".env"))?`Edit .env and set these values:
26
+ ${t.missing.map(n=>`${n}=<value>`).join(`
27
+ `)}`:"No .env file yet. Run `flisk project` to create one with working defaults."};if(t.invalid.length>0)return{name:"Environment Variables",didPass:!1,message:`Invalid env variables: ${t.invalid.join(", ")}`,fix:"Edit .env and provide values for empty variables"};let s=t.warnings.filter(n=>!n.startsWith(".env file not found"));return{name:"Environment Variables",didPass:!0,message:s.length>0?`All required environment variables are set (warning: ${s.join("; ")})`:"All required environment variables are set"}}function or(){let e=g()??process.cwd(),t=w(e,".tdk",".tdk-out"),s=fe.filter(n=>!D(w(t,n)));return s.length===0?{name:"Master Configs",didPass:!0,message:`${fe.join(", ")} found`}:{name:"Master Configs",didPass:!1,message:`Master configs missing: ${s.join(", ")}`,fix:"Run: flisk project"}}function ir(e=Ye()){let t=g();if(!t)return{name:"Flisk version",didPass:!0,isSkipped:!0,message:"Not in a project - skipping Flisk version check"};let s=cs(t,e);return s.status==="none"?{name:"Flisk version",didPass:!0,isSkipped:!0,message:`flisk ${e} (no minTdkVersion in .tdk/project.json)`}:s.status==="malformed"||s.status==="too-old"?{name:"Flisk version",didPass:!1,message:s.message,fix:s.fix}:{name:"Flisk version",didPass:!0,message:`flisk ${e} meets minTdkVersion ${s.required}`}}function ar(){let e=g()??process.cwd(),t=ve(e),s=x(e).filter(r=>!ne(e,r.path,t));if(s.length===0)return{name:"Resource Discovery",didPass:!0,message:`All resources are covered by discovery.paths ${JSON.stringify(t)}`};let n=s.map(r=>Le(Be(e,r.path))).join(", ");return{name:"Resource Discovery",didPass:!1,message:`${C(s.length,"resource")} outside discovery.paths ${JSON.stringify(t)}: ${n}. \`flisk up\` will not start them`,fix:"Move each under services/<stack>/<name>, or add a matching pattern to discovery.paths in .tdk/project.json and run: flisk config regenerate"}}var cr=["install-deps.sh","bun-hoisted-symlink-fix.sh","prisma-bun-client-link-fix.sh","prisma-normalize-client.sh","infisical-entrypoint.sh"],lr=/shared-platform-engineering\/docker-templates\/([\w.-]+)/g;function ur(e){let t=new Set;for(let s of x(e)){let n=w(s.path,M);if(D(n)){for(let r of Un(n))if(!(!r.startsWith("Dockerfile")||r.endsWith(".dockerignore")))for(let o of B(w(n,r),"utf-8").matchAll(lr))t.add(o[1])}}return[...t]}function dr(){let e=g()??process.cwd(),t=[];D(w(e,U))||t.push(`${U} (workspace root manifest)`);let s=w(e,"shared-platform-engineering","docker-templates"),n=[];try{n=ur(e)}catch{}for(let r of new Set([...cr,...n]))D(w(s,r))||t.push(`shared-platform-engineering/docker-templates/${r}`);return t.length===0?{name:"Generated Runtime Assets",didPass:!0,message:"Generated Docker runtime assets are present"}:{name:"Generated Runtime Assets",didPass:!1,message:`Generated Dockerfiles reference missing project runtime assets:
28
+ ${t.join(`
29
+ `)}`,fix:"Run `flisk project --yes` (or `flisk config regenerate`) with an updated Flisk. `flisk up` also refreshes these assets before starting Tilt."}}function pr(){let e=g()??process.cwd(),t=x(e),s=[];for(let n of t){let r=w(n.path,U);if(!D(r))continue;let o=n.config?.appType??"backend",i=me[o]??me.backend,a;try{a=JSON.parse(B(r,"utf-8")).scripts??{}}catch{s.push(`${n.name} (package.json is invalid JSON)`);continue}let c=i.filter(l=>!a[l]);c.length>0&&s.push(`${n.name}: missing "${c.join('", "')}"`)}return s.length===0?{name:"Startup Scripts",didPass:!0,message:"All services have required package.json scripts"}:{name:"Startup Scripts",didPass:!1,message:`Services missing required package.json scripts:
30
+ ${s.join(`
31
+ `)}`,fix:`Add the missing scripts to each service's package.json, e.g.:
32
+ "dev": "bun run src/index.ts",
33
+ "build": "tsc",
34
+ "start": "bun run dist/index.js"`}}function hs(e){if(e.startsWith("@"))return[e.split("/").slice(0,2).join("/")];let t=e.split("/")[0]??e;return[`@types/${t}`,t]}function gs(e,t,s=0){let n=e[t];if(typeof n!="string"||s>3)return!1;if(/(^|[\s;&|(])tsc(\s|$)/.test(n))return!0;for(let r of n.matchAll(/\b(?:bun|npm|pnpm|yarn)\s+run\s+([\w:.-]+)/g))if(gs(e,r[1],s+1))return!0;return!1}function fs(e){let t=hs(e);return e.includes("/")||e.startsWith("@")?t[t.length-1]:t[0]}var fr={"@types/bun":"^1.4.2","@types/node":"^20.0.0"};function mr(e,t){return(t.includes("bun")||e.has("@types/bun"))&&!e.has("@types/node")}function hr(){let e=g()??process.cwd(),t=x(e),s=[],n=new Set;for(let o of t){let i=w(o.path,U),a=w(o.path,M,"tsconfig.docker.autogenerated.json");if(!D(i)||!D(a))continue;let f=Ge(a)?.compilerOptions?.types;if(!Array.isArray(f))continue;let m=Ge(i),d=m?.scripts??{};if(!gs(d,"build"))continue;let S=new Set([...Object.keys(m?.devDependencies??{}),...Object.keys(m?.dependencies??{})]),k=f.filter(y=>typeof y=="string").filter(y=>!hs(y).some(p=>S.has(p)));for(let y of k)n.add(fs(y));if(k.length>0){let y=k.map(p=>`"${p}" (needs ${fs(p)})`).join(", ");s.push(`${o.name}: "types" lists ${y}`)}mr(S,f)&&(n.add("@types/node"),s.push(`${o.name}: uses @types/bun, which references node types internally, but @types/node is not a direct dependency`))}if(s.length===0)return{name:"TypeScript Type Dependencies",didPass:!0,message:`Every service's Docker tsconfig "types" entry has its @types package installed`};let r=[...n].map(o=>{let i=fr[o];return i?`"${o}": "${i}"`:`${o} (bun add -d ${o})`});return{name:"TypeScript Type Dependencies",didPass:!1,message:`\`bun run build\` will fail with TS2688 (Cannot find type definition file) because a @types package it needs is not a direct dependency:
35
+ ${s.join(`
36
+ `)}`,fix:`Add to each service's package.json devDependencies: ${r.join(", ")}`}}function Ge(e){try{return JSON.parse(B(e,"utf-8"))}catch{return null}}function gr(e){let s=Ge(e)?.compilerOptions;return s?.allowSyntheticDefaultImports===!0||s?.esModuleInterop===!0}function kr(){let e=g()??process.cwd(),t=x(e).filter(n=>n.config?.appType==="frontend");if(t.length===0)return{name:"Frontend Docker Preflight",didPass:!0,isSkipped:!0,message:"No frontend services to check"};let s=[];for(let n of t){D(w(n.path,"public"))||s.push(`${n.name}: no public/ folder, but the Docker build copies it. Create it: mkdir -p ${Le(Be(e,w(n.path,"public")))} && touch ${Le(Be(e,w(n.path,"public",".gitkeep")))}`);let r=w(n.path,M,"Dockerfile.app.autogenerated"),o=w(n.path,M,"tsconfig.docker.autogenerated.json");if(D(r)){let i=B(r,"utf-8"),a=/\bEXPOSE\s+80\b/.test(i),c=n.config?.stack,l=c?w(e,"services",c,M,"docker-compose.app.autogenerated.yml"):"";if(a&&l&&D(l)){let f=B(l,"utf-8"),m=n.name.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=new RegExp(`traefik\\.http\\.services\\.${m}\\.loadbalancer\\.server\\.port=(\\d+)`),k=f.match(d)?.[1];k&&k!=="80"&&s.push(`${n.name}: nginx runtime exposes 80, but generated Traefik routes to ${k}`)}}if(D(o)&&!gr(o)){let i=w(n.path,"src","main.tsx");if(D(i)){let a=B(i,"utf-8"),c=[/import\s+\w+\s+from\s+["']react["']/,/import\s+\w+\s+from\s+["']react-dom\/client["']/].filter(l=>l.test(a)).map(l=>l.source.includes("react-dom")?"react-dom/client":"react");c.length>0&&s.push(`${n.name}: Docker tsconfig does not allow synthetic default imports, but src/main.tsx default-imports ${c.join(" and ")}`)}}}return s.length===0?{name:"Frontend Docker Preflight",didPass:!0,message:`${C(t.length,"frontend")} ${t.length===1?"has":"have"} compatible Docker build/routing metadata`}:{name:"Frontend Docker Preflight",didPass:!1,message:`Frontend Docker metadata has issues that will make \`flisk up\` fail or route 404:
37
+ ${s.join(`
38
+ `)}`,fix:'Regenerate with a current Flisk (`flisk config regenerate`) and ensure frontend nginx runtimes route to port 80. For React entrypoints, prefer named imports: `import { StrictMode } from "react"` and `import { createRoot } from "react-dom/client"`.'}}var Sr=90,yr=80;function xr(e){return e.split(`
39
+ `).map(t=>t.trim()).filter(Boolean).map(t=>{let[s,n,r]=t.split(",");return{name:s??"unknown",memPct:Number.parseFloat((n??"").replace(/%/g,"")),cpuPct:Number.parseFloat((r??"").replace(/%/g,""))}}).filter(t=>Number.isFinite(t.memPct)&&Number.isFinite(t.cpuPct))}var wr=Object.assign(function(){let t;try{t=Wn($("docker")??"docker",["stats","--no-stream","--format","{{.Name}},{{.MemPerc}},{{.CPUPerc}}"],{stdio:"pipe",encoding:"utf-8",timeout:R,windowsHide:process.platform==="win32"})}catch(o){return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:Ke(o)?"Docker not responding - skipped container resource check":"Docker not running - skipped container resource check"}}let s=xr(t);if(s.length===0)return{name:"Container Resource Health",didPass:!0,isSkipped:!0,message:"No running containers to check"};let n=s.filter(o=>o.memPct>=Sr&&o.cpuPct>=yr);if(n.length===0)return{name:"Container Resource Health",didPass:!0,message:`${C(s.length,"container")} within normal resource usage`};let r=n.map(o=>`${o.name} (mem ${o.memPct.toFixed(0)}%, cpu ${o.cpuPct.toFixed(0)}%)`).join(`
40
+ `);return{name:"Container Resource Health",didPass:!1,message:`${C(n.length,"container")} pinned near its memory limit while burning CPU -- likely stuck in a boot-time retry/fetch loop, not a normal crash:
41
+ ${r}`,fix:"Check the container's boot logs for a network fetch loop (e.g. `bunx <pkg>` re-downloading a CLI on every start instead of using one already installed): docker logs <container>. If a Prisma auto-migration is the cause, set AUTO_MIGRATE=false in the project's .env as a temporary unblock."}},{requiresContainerRuntime:!0,checkName:"Container Resource Health"}),Pr=5e3;async function br(e,t){let s=g()??process.cwd(),n=ge(x(s),t);return n.length===0?{name:"Service Health",didPass:!0,isSkipped:!0,message:"No routable services to ping"}:xe(await Y(n,e))}async function vr(e,t){let s=g()??process.cwd(),n=x(s),r=at(it(n,t),{timeoutSeconds:Math.ceil(e/1e3)});return r.length===0?we([]):(await Y(ge(n,t),e)).some(i=>i.status!==void 0)?we(await lt(r,ct(s))):{name:"Service Smoke",didPass:!0,isSkipped:!0,message:"No services responded - skipped smoke checks"}}async function Dr(e,t){let s=g()??process.cwd(),n=x(s),r=ot(n,t);return r.length===0?{name:"Advertised Endpoints",didPass:!0,isSkipped:!0,message:"No routable services to check"}:Rt(await Y(r,e))}function Tr(e,t){if(e.length===0){console.log(`${h.green("\u2713")} Nothing to repair
42
+ `);return}for(let s of e){let n=s.status==="planned"?`${h.cyan("would run")}`:s.status==="applied"?h.green("ran"):s.status==="failed"?h.red("failed"):h.gray("skipped"),r=s.status==="planned"?"":` (${s.reason})`;console.log(`${n}: ${s.command}${r}`)}t&&console.log(h.gray(`
43
+ Dry run: nothing was changed.`)),console.log("")}function He(e){for(let t of ms(e))!t.didPass&&!t.isSkipped&&!t.isWarning?(console.log(`${h.red("\u2717")} ${t.message}`),t.fix&&console.log(`${h.blue("\u2139")} Fix: ${t.fix}`)):t.isWarning?(console.log(`${h.yellow("\u26A0")} ${h.yellow(t.message)}`),t.fix&&console.log(`${h.blue("\u2139")} Fix: ${t.fix}`)):t.isSkipped?(console.log(`${h.gray("\u25CB")} ${h.gray(t.message)}`),t.fix&&console.log(`${h.blue("\u2139")} ${t.fix}`)):console.log(`${h.green("\u2713")} ${t.message}`)}function Cr(e,t,s,n={},r){let o=r??[...e,...t];n.all?(console.log(h.bold("Machine")),He(e),console.log(`
44
+ ${h.bold("Project")}`),s?t.length>0&&He(t):console.log(`${h.gray("\u25CB")} ${h.gray("Not in a Flisk project, so project checks were skipped")}`),console.log(""),console.log(Qn(o))):(He(o),console.log(""),o.every(a=>a.didPass||a.isSkipped||a.isWarning)&&!s&&(console.log(`${h.gray("\u25CB")} ${h.gray("Not in a Flisk project, so project checks were skipped")}`),console.log("")))}var $r=new Gn("doctor").description("Check environment readiness for Flisk").option("--all","Run every check and show Machine and Project sections with a summary",!1).option("--json","Output a versioned JSON readiness report",!1).exitOverride(e=>{e.exitCode===0&&process.exit(0),$r.opts().json&&console.log(JSON.stringify(j([],!1,[{code:"USAGE",message:e.message}]))),process.exit(2)}).option("--no-ping","Skip pinging running services' /health endpoints").option("--strict","Fail warnings such as a WSL project under /mnt/c").option("--fix","Repair this project's unused Docker networks and leftover doctor probes",!1).option("--dry-run","With --fix: list the repairs without changing anything",!1).option("--scope <scope>","With --fix: project (default) or machine, which also removes unused networks of other Flisk projects","project").option("-y, --yes","With --fix: apply every repair without asking",!1).option("--ping-timeout <ms>","Per-service ping timeout in milliseconds",String(Pr)).action(async e=>{let t=Number(e.pingTimeout);if(!/^\d+$/.test(e.pingTimeout)||!Number.isSafeInteger(t)||t<=0){let u="--ping-timeout must be a positive integer number of milliseconds";e.json&&console.log(JSON.stringify(j([],!1,[{code:"USAGE",message:u}]))),console.error(u),process.exit(2);return}let s=!["project","machine"].includes(e.scope),n=e.scope!=="project"&&!e.fix;if(s||n||(e.dryRun||e.yes)&&!e.fix){let u=s?`--scope must be project or machine, got "${e.scope}"`:n?"--scope only applies with --fix":`${e.dryRun?"--dry-run":"--yes"} only applies with --fix`;e.json&&console.log(JSON.stringify(j([],!1,[{code:"USAGE",message:u}]))),console.error(u),process.exit(2);return}e.json||console.log("Flisk doctor checks your local Docker + Tilt development environment; it does not check cluster deployments.");let r=At();if(process.platform==="win32"){if(e.json){let u=null;try{u=await ut()}catch{}console.log(JSON.stringify(j([{name:"Native Windows support",didPass:!1,message:ds,fix:"Use WSL2 Ubuntu with Docker Desktop integration. Guide: docs/wsl2.md"}],!!g(),[],u,{...r,canUp:!1})))}console.error(ds),process.exit(1);return}if(r.kind==="webcontainer"){let u=j([{name:"Host",didPass:!1,message:be,fix:`Use a machine with Docker. Guide: ${te}`}],!!g(),[],void 0,r);e.json&&console.log(JSON.stringify(u)),console.error(be),process.exit(1);return}e.json||(console.log(`
45
+ ${h.bold("\u{1F50D} Flisk Doctor")}
46
+ `),console.log(`Checking environment...
47
+ `));let o=g(),i;if(e.fix){try{let u;if(o)try{u=ft(o).project.name}catch{}let P=o?Zt(o):[],ue=await zt(u,void 0,{tiltPids:P,machine:e.scope==="machine"});i=await Xt(ue,{dryRun:e.dryRun,confirm:e.yes||!e.json&&process.stdin.isTTY?async T=>e.yes||await mt({message:`Run \`${T.command}\` (${T.check}, ${T.reason})?`}):void 0})}catch(u){i=[{id:"plan-fixes",check:"Docker networks",scope:"project",command:"docker network ls",status:"failed",reason:`could not list Docker networks: ${(u instanceof Error?u.message:String(u)).split(/\r?\n/)[0]}`}]}e.json||Tr(i,e.dryRun)}let a,c;try{a=await Q(o??process.cwd())}catch(u){a=null,c=u instanceof Error?u.message:String(u)}let l=[()=>a?{name:"Host Ports",didPass:!0,message:`HTTP ${a.ingressHttp}, HTTPS ${a.ingressHttps}, Postgres ${a.postgres}`}:{name:"Host Ports",didPass:!1,message:c??"Could not select host ports",fix:"Set TDK_HTTP_PORT, TDK_HTTPS_PORT, or TDK_POSTGRES_PORT to available host ports."},()=>a?ye(ls,void 0,[a.ingressHttp,a.ingressHttps]):{name:"Ingress Ports",didPass:!1,message:"Ingress port plan is unavailable"},er,Je,()=>Wt(),N("Docker OS",ze),qe,N("Docker Compose",K),N("Docker Versions",J),nr,()=>Kn(g()??process.cwd(),e.strict),()=>qn(process.env,e.strict),N("Docker Network Pool",()=>Dt()),()=>Qt()],f=[()=>ir(),or,dr,os,pr,()=>Ot(),hr,kr,ar,()=>kt(),()=>Z(),()=>_e(),()=>Ae(),()=>je(),()=>Ie(void 0,e.strict),()=>St(),()=>yt(),()=>wt(),()=>xt(),()=>ee(),()=>gt(),()=>bt(),()=>Pt(),()=>vt(),rr,async()=>{let u=g()??process.cwd(),P=Et(u)?await pt(u):!0;return Se(ls,u,void 0,P)},N("Container Resource Health",wr),N("Crash-looping containers",()=>{let u=g()??process.cwd(),P=[];try{P=he(u)}catch{return{name:"Crash-looping containers",didPass:!0,isSkipped:!0,message:"Could not read .env - skipped crash-loop check"}}return Bt(rt(),P)}),N("Tilt Resources",Pe)];if(e.ping){let u=o?dt(o,a?.ingressHttp):a?.ingressHttp;f.push(N("Service Health",()=>br(t,u))),f.push(N("Service Smoke",()=>vr(t,u))),f.push(N("Advertised Endpoints",()=>Dr(t,u)))}let m=!!o,d=[],S=[],k,y=[];if(e.json||!e.all){let u=await ts(l,m?f:[]);k=u.checks,y=u.errors}else{let u=async(T,Ns=!1)=>{let Es=T.map(z=>{let de=async()=>{try{return await z()}catch(pe){return y.push({code:"INTERNAL",message:pe instanceof Error?pe.message:String(pe)}),{name:z.checkName??"Doctor check",didPass:!1,isSkipped:!1,message:"Check failed with an internal error"}}};return de.requiresContainerRuntime=z.requiresContainerRuntime,de.checkName=z.checkName,de});return Yn(Es,{all:!!e.all,containerRuntimeFailed:Ns})};d=await u(l);let P=d.some(T=>!T.didPass&&!T.isSkipped&&!T.isWarning),ue=d.some(T=>T.name===b&&!T.didPass);m&&(e.all||!P)&&(S=await u(f,ue)),k=[...d,...S]}if(jt(r.kind))for(let u of k)u.name===b&&!u.didPass&&(u.fix=_t);let p=j(ms(k),m,y,a,r);i&&(p.data.actions=i),i&&Yt(i)&&(p.data.ready=!1);let A=ss(p),W=p.data.ready;if(e.json){let u;try{u=he(g()??process.cwd())}catch(P){if(!(P instanceof st))throw P;console.log(JSON.stringify(j([],m,[...y,{code:"ENV_UNREADABLE",message:P.message}]))),console.error(P.message),process.exit(1)}console.log(JSON.stringify(nt(p,u)));for(let P of y)console.error(X(P.message,u));A!==0&&process.exit(A);return}for(let u of y)console.error(`${h.red("\u2717")} Doctor check failed: ${u.message}`);Cr(d,S,m,e,k);let Xe=zn(m,W);console.log(`${W?h.green(h.bold("\u2713")):h.red(h.bold("\u2717"))} ${Xe}`),A!==0&&process.exit(A)});function ks(e){return ce(e,F)}var q=`${F[0]}.${F[1]}+`;import{execFileSync as Ss}from"node:child_process";import{accessSync as ys,constants as xs,readdirSync as Nr}from"node:fs";import{delimiter as Er,join as V}from"node:path";var _="flisk",ws="@flisk-sh/flisk",Rr="https://github.com/flisk-sh/flisk",Ps="@tdk-landscape/tdk-cli-core";function bs(e=_,t=process.env){let s=t.PATH??t.Path??"";for(let n of s.split(Er)){if(!n)continue;let r=[V(n,e),V(n,`${e}.cmd`),V(n,`${e}.exe`)];for(let o of r)try{return ys(o,xs.X_OK),!0}catch{}}return!1}function Or(e=process.env){let t=e.HOME??e.USERPROFILE??"";if(!t)return"flisk-workspace";let s=V(t,"Documents");try{return ys(s,xs.F_OK),V(s,"flisk")}catch{return V(t,"flisk")}}function _r(e){try{return Nr(e).every(t=>t.startsWith("."))}catch{return!0}}function vs(e=process.env,t=process.cwd()){if(!bs(_,e))return`The \`${_}\` command is not on PATH (this run is not a global install). Install it with \`npm install -g ${ws}\`, then run \`${_} project --yes\`. If npm reports EEXIST for \`flisk\`, the old package still owns that command: run \`npm uninstall -g ${Ps}\` first. The current release is published from ${Rr}.`;if(_r(t))return`Next: ${_} project --yes`;let s=Or(e);return`Next: mkdir -p ${s} && cd ${s} && ${_} project --yes
48
+ (${_} project writes .tdk/ and the master configs into the current folder, so it starts clean in a folder of its own. Or clone a starter: ${_} project example)`}function Hi(e=process.env){if(bs(_,e))return"present";let t=e.npm_execpath?.includes("bun")?"bun":"npm",s=t==="bun"?"bun remove -g":"npm uninstall -g";try{Ss(s,[Ps],{stdio:"ignore",timeout:12e4})}catch{}try{return Ss(t,["install","-g",ws],{stdio:"inherit",timeout:3e5}),"installed"}catch{return"failed"}}var Ir=["docker","compose","tilt"],Cs=["node","bun","ports"],$s=["node",...Ir,"bun","ports"];function Fr(e,t){return{id:e,ok:t.didPass||!!t.isSkipped,message:t.message,fix:t.fix}}function Ts(e){let[t=0,s=0]=String(e).split(".").map(n=>Number.parseInt(n,10));return!Number.isFinite(t)||!Number.isFinite(s)||t<22||t===22&&s<12}async function le(e,t,s){try{return Fr(e,await t())}catch{return{id:e,ok:!1,message:s}}}function Mr(e){return e.isSkipped?{...e,didPass:!1,isSkipped:!1,message:`Could not verify Docker Engine/Compose minimum versions: ${e.message}`,fix:e.fix??"Start Docker and ensure Docker Engine 25+ and Compose 2.20.2+ are installed."}:e}function Hr(e){try{return x(e).some(t=>t.config?.featuresEnabled?.includes("prisma")??!1)}catch{return!1}}async function Lr(e={}){let t=e.cwd??process.cwd(),s=e.scope??"runtime",n=g(t),r=!!n,o=[],i=process.versions.node;if(o.push({id:"node",ok:!Ts(i),message:i,fix:Ts(i)?`Install Node.js 22.12+ (current: ${i}). https://nodejs.org`:void 0}),s==="runtime"){let p=L();p.isColima&&o.push({id:"colima",ok:p.running,message:p.running?`Colima VM is running${p.arch?` (${p.arch})`:""}`:p.problem??"The Colima VM is not running",fix:p.running?void 0:p.fix}),o.push(await le("docker",Je,"Docker daemon is not running")),o.push(await le("compose",async()=>{let[v,A]=await Promise.all([K(),J()]);return v.didPass?Mr(A):v},"Docker Engine or Compose version check failed")),o.push(await le("tilt",qe,"Tilt CLI not found"))}let a=n?se(x(n)):!0,c=!1,l=a?$("bun"):void 0;if(l)try{let p=Ds(l,["--version"],{encoding:"utf-8",timeout:3e3}).trim();c=ks(p)}catch{}o.push(a?{id:"bun",ok:c,message:c?`Bun ${q} is available on PATH`:`Bun ${q} not found on PATH`,fix:c?void 0:"curl -fsSL https://bun.sh/install | bash"}:{id:"bun",ok:!0,message:"Bun not needed: no generated JS services"});try{let p=await Q(n??t,s==="scaffold"?{inspectDocker:!1}:{});o.push({id:"ports",ok:!0,message:`HTTP ${p.ingressHttp}, HTTPS ${p.ingressHttps}, Postgres ${p.postgres}`})}catch(p){o.push({id:"ports",ok:!1,message:p instanceof Error?p.message:String(p),fix:"Set TDK_HTTP_PORT, TDK_HTTPS_PORT, or TDK_POSTGRES_PORT to available host ports."})}if(n&&s==="runtime"){let p=await le("nats",()=>ee(n),"NATS broker check failed");if(p.ok||o.push(p),Hr(n)){let v=!1;try{let A=JSON.parse(Ar(jr(n,".tdk",H),"utf-8")),W=String(A?.project?.name??"").replace(/-/g,"_");W&&(v=Ds($("docker")??"docker",["ps","--filter",`label=com.docker.compose.project=${W}`,"--filter","label=com.docker.compose.service=postgres","--filter","health=healthy","--format","{{.Names}}"],{encoding:"utf-8",timeout:3e3}).trim().length>0)}catch{}v||o.push({id:"prisma",ok:!1,message:"A Prisma resource is configured, but the project Postgres service is not healthy",fix:"Run `flisk up` to start the bundled Postgres, then check `flisk doctor`."})}}let f=o.filter(p=>!p.ok).slice(0,8),m=s==="scaffold"?Cs:$s,d=f.some(p=>m.includes(p.id)),S=f.some(p=>p.id==="bun"),k=f.length?d?s==="scaffold"?S?`Project setup blocked. Bun ${q} must be installed on PATH.
49
+ Fix the machine checks below.`:"Project setup blocked. Fix the machine checks below.":S?`Cold start blocked. Bun ${q} must be installed on PATH.
50
+ Prisma/NATS configuration is project-specific and generated after \`flisk project\`. Fix the machine checks below.`:"Cold start blocked. Bun/Prisma/NATS are not the first failure.\nThey are generated after `flisk project`. Fix the machine checks below.":"Machine is ready. Project wiring is not.":"",y=f.length?"":r?"Environment ready for Flisk":`This machine is ready for Flisk.
51
+ ${vs()}`;return{ok:f.length===0,inProject:r,items:f,header:k,footer:y}}function Br(e,t={}){let s=[e.header];for(let n of e.items)s.push(`FAIL ${n.id.padEnd(7)} ${n.message}`),n.fix&&s.push(` ${n.fix}`);return e.footer&&(t.includeSuccessFooter??!0)&&s.push(e.footer),s.filter(Boolean).join(`
52
+ `)}async function ta(e={}){let t=e.scope??"runtime",s=await Lr({scope:t}),n=t==="scaffold"?Cs:$s;s.items.some(o=>n.includes(o.id))&&(console.error(Br(s)),process.exit(1))}function sa(e=$){return{hasDockerCli:!!e("docker"),hasTiltCli:!!e("tilt")}}function na(e){let t=[];return e.hasDockerCli||t.push(`Docker is not installed. ${E.dockerMissing}`),e.hasTiltCli||t.push(`Tilt is not installed. ${E.tiltMissing}`),t.push("Docker and Tilt are only needed to start the stack: start them, then run `flisk doctor` (readiness) and `flisk up`."),t}export{En as a,Rn as b,$o as c,be as d,_t as e,At as f,jt as g,ve as h,ne as i,zr as j,io as k,ao as l,co as m,Ne as n,on as o,un as p,mo as q,Go as r,Ko as s,cs as t,$r as u,Ps as v,Hi as w,Ir as x,Cs as y,$s as z,Ts as A,Mr as B,Lr as C,Br as D,ta as E,sa as F,na as G};
@@ -1,2 +1,2 @@
1
1
  import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{r as c}from"./chunk-M6S25PIS.js";import{execFileSync as u}from"node:child_process";import{realpathSync as l}from"node:fs";import{resolve as p}from"node:path";var m=(o,t)=>u(o,t,{encoding:"utf-8",stdio:"pipe",timeout:5e3,windowsHide:!0});function a(o,t=process.platform,e=m){if(t==="win32")return null;try{let s=e("lsof",["-nP",`-iTCP:${o}`,"-sTCP:LISTEN","-t"]).split(/\r?\n/).map(r=>r.trim()).filter(Boolean);for(let r of s){let n=e("ps",["-p",r,"-o","command="]).trim(),[i]=c(`${r} ${n}`);if(i)return i}}catch{}return null}function f(o){try{return l(o)}catch{return p(o)}}function d(o,t){return o!==null&&f(o.root)!==f(t)}async function P(o,t,e,s=a){let r={running:[],foreign:[]};for(let n of o){if(!await e(n))continue;let i=s(n);i&&d(i,t)?r.foreign.push({port:n,root:i.root}):r.running.push(n)}return r}export{a,d as b,P as c};
2
+ import{r as c}from"./chunk-4TMLNLYG.js";import{execFileSync as u}from"node:child_process";import{realpathSync as l}from"node:fs";import{resolve as p}from"node:path";var m=(o,t)=>u(o,t,{encoding:"utf-8",stdio:"pipe",timeout:5e3,windowsHide:!0});function a(o,t=process.platform,e=m){if(t==="win32")return null;try{let s=e("lsof",["-nP",`-iTCP:${o}`,"-sTCP:LISTEN","-t"]).split(/\r?\n/).map(r=>r.trim()).filter(Boolean);for(let r of s){let n=e("ps",["-p",r,"-o","command="]).trim(),[i]=c(`${r} ${n}`);if(i)return i}}catch{}return null}function f(o){try{return l(o)}catch{return p(o)}}function d(o,t){return o!==null&&f(o.root)!==f(t)}async function P(o,t,e,s=a){let r={running:[],foreign:[]};for(let n of o){if(!await e(n))continue;let i=s(n);i&&d(i,t)?r.foreign.push({port:n,root:i.root}):r.running.push(n)}return r}export{a,d as b,P as c};
@@ -0,0 +1,4 @@
1
+ import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
+ import{a as S}from"./chunk-DTIHDMED.js";import{g as u,q as b}from"./chunk-5G7E6CO2.js";import{a as P}from"./chunk-YNJTA77W.js";import{Ra as x,ba as h,ca as w,d,k as m,ra as y,s as g,ta as k}from"./chunk-CLQSJP6M.js";import{b as a}from"./chunk-CF46CD6R.js";import{Command as R}from"commander";import{readFileSync as N}from"node:fs";import{join as O}from"node:path";function C(o){let e=o.config;return e?Array.isArray(e.featuresEnabled)&&e.featuresEnabled.includes(d)?!0:(Array.isArray(e.dependsOn)?e.dependsOn:[]).some(n=>P.includes(n)):!1}function J(o,e){let i=o.replace(/-/g,"_"),n=[];for(let t of[...e].sort((r,s)=>r.name.localeCompare(s.name))){let r=t.resources.filter(C).map(s=>s.name);r.length!==0&&n.push({name:`${i}_${t.name.replace(/-/g,"_")}`,stack:t.name,services:r.sort()})}return n.length===0?null:{name:"postgres",databases:n}}function $(o){try{let e=JSON.parse(N(O(o,".tdk",m),"utf-8"));return typeof e?.project?.name=="string"?e.project.name:null}catch{return null}}import{spawn as T}from"node:child_process";function F(o){try{let e=new URL(o);return e.protocol==="http:"||e.protocol==="https:"}catch{return!1}}function E(o,e=process.platform,i=T){if(!F(o))return Promise.resolve(!1);let n,t;return e==="darwin"?(n="open",t=[o]):e==="win32"?(n="rundll32.exe",t=["url.dll,FileProtocolHandler",o]):(n="xdg-open",t=[o]),new Promise(r=>{try{let s=i(n,t,{stdio:"ignore",detached:!0,windowsHide:!0});s.once("error",()=>r(!1)),s.once("spawn",()=>{typeof s.unref=="function"&&s.unref(),r(!0)})}catch{r(!1)}})}function V(o,e=process.platform,i=T){return new Promise(n=>{let t,r;e==="darwin"?(t="pbcopy",r=[]):e==="win32"?(t="clip",r=[]):(t="xclip",r=["-selection","clipboard"]);try{let s=i(t,r,{stdio:["pipe","ignore","ignore"],windowsHide:!0});s.on("error",()=>{n(!1)}),s.on("close",c=>{n(c===0)}),s.stdin?(s.stdin.on("error",()=>{n(!1)}),s.stdin.write(o,"utf-8"),s.stdin.end()):n(!1)}catch{n(!1)}})}async function j(o){let{resources:e}=x(o),i=await u(o,{inspectDocker:!1}),{appBase:n}=y(i?.ingressHttp,o);return e.filter(t=>t.config?.appType==="frontend").map(t=>({name:t.name,url:`${n}${k(t)}`}))}async function H(o,e=2e3){try{return(await fetch(o,{signal:AbortSignal.timeout(e)})).status<500}catch{return!1}}async function A(o,e=3e4,i){if(o.length===0)return;let n=Date.now(),t=n+e;for(;;){for(let s of o)if(await H(s.url))return s;let r=Date.now()-n;if(r>=e)return;i?.(r),await new Promise(s=>setTimeout(s,2e3))}}async function te(o,e=0,i){let n=await j(o);return A(n,e,i)}async function _(o){let e=o??g();if(!e)return console.log(a.yellow("Not in a Flisk project, so there is no frontend to open.")),console.log(a.gray("Run `flisk project --yes` first, or `flisk open` inside a project.")),null;let i=await j(e);if(i.length===0)return console.log(a.yellow("This project has no frontend service to open.")),console.log(a.gray("Start the stack with `flisk up` and add a frontend with `flisk resource`.")),null;let n=$(e);h(`Opening the first frontend of ${n??"this project"}`);for(let c of i)console.log(a.gray(` - ${c.name}: ${c.url}`));let t=S("Waiting for the frontend to answer..."),r=await A(i,12e4,c=>{t.text=`Waiting for the frontend to answer... ${Math.round(c/1e3)}s`});if(!r){t.fail("No frontend answered yet.");let l=(await u(e,{inspectDocker:!1}))?.ingressHttp,D=l?await b(l)==="in-use":!1;if(l&&!D){console.log(a.yellow(`The stack is running, but this machine cannot reach port ${l}.`)),console.log(a.gray(" Docker is not publishing the port to the host."));let{checkColima:p}=await import("./colima-SVZX2UML.js"),f=p();f.isColima&&!f.running?(console.log(a.gray(` ${f.problem??"The Colima VM is not running"}`)),console.log(a.gray(` Fix: ${f.fix??"colima start"}`))):console.log(a.gray(" Restart the Docker runtime (Docker Desktop or Colima), then run `flisk open` again."))}else console.log(a.yellow("The stack is not serving the frontend yet.")),console.log(a.gray(" - Start the stack in another terminal: flisk up")),console.log(a.gray(" - Then run this again: flisk open"));for(let p of i)console.log(a.gray(` - ${p.name}: ${p.url}`));return null}t.succeed(`The frontend is up: ${r.name}`);let s=await E(r.url);return console.log(s?a.green(`
3
+ Opened ${r.url}`):a.yellow(`
4
+ Could not open a browser. Open ${r.url} yourself.`)),w("Run `flisk open` again to open the next frontend."),r.url}var re=new R("open").description("Open the first frontend of the project in your browser").action(async()=>{await _()});export{J as a,$ as b,E as c,V as d,j as e,H as f,A as g,te as h,_ as i,re as j};
@@ -1,2 +1,2 @@
1
1
  import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
- import{Ta as _,cb as A,d as u,k as S}from"./chunk-LYOSHFYU.js";import{existsSync as w,readFileSync as h}from"node:fs";import{join as i}from"node:path";var O=["postgres",u],y=["pre_alpha","alpha","beta","out_of_scope"];function D(e){return O.includes(e)}function b(e){try{return JSON.parse(h(i(e,".tdk",S),"utf-8"))}catch{return}}function d(e){try{return w(e)?h(e,"utf-8"):void 0}catch{return}}function k(e,s){let n=r=>{let t=r;for(;t<e.length&&/\s/.test(e[t]);)t+=1;return t},a=0;for(;;){let r=e.indexOf(s,a);if(r===-1)return;let t=n(r+s.length);if(e[t]==="="&&(t=n(t+1),e[t]==="[")){let o=e.indexOf("]",t+1);return o===-1?void 0:[...e.slice(t+1,o).matchAll(/"([^"]+)"|'([^']+)'/g)].map(f=>f[1]??f[2]??"")}a=r+s.length}}function N(e){let s=i(e,".tdk",".tdk-out","Tiltfile"),n=d(s);if(n)return k(n,"ALWAYS_ENABLED_INFRA")}function M(e){let s=i(e,".tdk",".tdk-out","spec.master"),n=d(s);if(n!==void 0)return/"database-management"\s*:\s*True/.test(n)}function x(e){let s=i(e,".tdk",".tdk-out"),n=d(i(s,"Tiltfile")),a=d(i(s,"spec.master")),r=d(i(s,"tdk-cli-ext","discovery","config.star")),t=d(i(s,"tdk-cli-ext","engine","topologies","tilt","config","profiles.star"));if(!n||!a||!r||!t)return!1;let o=a.match(/PRE_ALPHA_RESOURCES\s*=\s*\{([^}]*)\}/)?.[1],f=k(r,"CORE_INFRA");return/FOCUS_MODE\s*,\s*FOCUS_ENABLED_ALL\s*,\s*FOCUS_ENABLED_RESOURCES\s*=\s*Config\.apply_focus\(cfg\)/.test(n)&&/if FOCUS_MODE and FOCUS_ENABLED_ALL\s*:/.test(n)&&/"[^"]+"\s*:\s*True|'[^']+'\s*:\s*True/.test(o??"")&&(f?.includes("postgres")??!1)&&/["']postgres["']\s*:\s*["']database-management["']/.test(r)&&/for infra in CORE_INFRA_EXPORT\s*:/.test(t)&&/needed\[INFRA_STACK_MAP_EXPORT\[infra\]\]\s*=\s*True/.test(t)}function C(e){let s=b(e);if(!s)return!1;let n=s.phases??{};for(let r of y){let t=n[r]?.enabledStacks;if(Array.isArray(t)&&t.includes(u))return!0}let a=s.always_enabled_infra??A;return Array.isArray(a)&&a.includes(u)}function L(e,s){let n=new Set;for(let t of O)n.add(t);for(let t of s)n.add(t.name),t.stack&&n.add(t.stack);let a=b(e);if(a){let t=a.phases??{};for(let f of y){let l=t[f]?.enabledStacks;if(Array.isArray(l))for(let c of l)n.add(c)}let o=a.always_enabled_infra??A;if(Array.isArray(o))for(let f of o)n.add(f)}let r=N(e);if(Array.isArray(r))for(let t of r)n.add(t);return n}function $(e,s=_(e)){let n=C(e),a=N(e),r=Array.isArray(a)&&a.includes(u),t=M(e)===!0,o=n||r||t,f=!n&&x(e),l=L(e,s),c=[],E=[];for(let p of s){let P=p.config?.dependsOn??[],g=!1;for(let m of P){if(D(m)){g=!0;continue}l.has(m)||E.push({resource:p.name,name:m})}g&&c.push(p.name)}let T=o||c.length>0,F=o?"feature":c.length>0?"dependsOn":"none";return{featureOn:o,featureOnFromProjectJson:n,featureOnFromTiltfile:r,featureOnFromSpecMaster:t,focusWouldEnableDatabaseManagement:f,dependsOnUsers:c,willStart:T,reason:F,unknownDependsOnNames:E}}export{O as a,$ as b};
2
+ import{Ta as _,cb as A,d as u,k as S}from"./chunk-CLQSJP6M.js";import{existsSync as w,readFileSync as h}from"node:fs";import{join as i}from"node:path";var O=["postgres",u],y=["pre_alpha","alpha","beta","out_of_scope"];function D(e){return O.includes(e)}function b(e){try{return JSON.parse(h(i(e,".tdk",S),"utf-8"))}catch{return}}function d(e){try{return w(e)?h(e,"utf-8"):void 0}catch{return}}function k(e,s){let n=r=>{let t=r;for(;t<e.length&&/\s/.test(e[t]);)t+=1;return t},a=0;for(;;){let r=e.indexOf(s,a);if(r===-1)return;let t=n(r+s.length);if(e[t]==="="&&(t=n(t+1),e[t]==="[")){let o=e.indexOf("]",t+1);return o===-1?void 0:[...e.slice(t+1,o).matchAll(/"([^"]+)"|'([^']+)'/g)].map(f=>f[1]??f[2]??"")}a=r+s.length}}function N(e){let s=i(e,".tdk",".tdk-out","Tiltfile"),n=d(s);if(n)return k(n,"ALWAYS_ENABLED_INFRA")}function M(e){let s=i(e,".tdk",".tdk-out","spec.master"),n=d(s);if(n!==void 0)return/"database-management"\s*:\s*True/.test(n)}function x(e){let s=i(e,".tdk",".tdk-out"),n=d(i(s,"Tiltfile")),a=d(i(s,"spec.master")),r=d(i(s,"tdk-cli-ext","discovery","config.star")),t=d(i(s,"tdk-cli-ext","engine","topologies","tilt","config","profiles.star"));if(!n||!a||!r||!t)return!1;let o=a.match(/PRE_ALPHA_RESOURCES\s*=\s*\{([^}]*)\}/)?.[1],f=k(r,"CORE_INFRA");return/FOCUS_MODE\s*,\s*FOCUS_ENABLED_ALL\s*,\s*FOCUS_ENABLED_RESOURCES\s*=\s*Config\.apply_focus\(cfg\)/.test(n)&&/if FOCUS_MODE and FOCUS_ENABLED_ALL\s*:/.test(n)&&/"[^"]+"\s*:\s*True|'[^']+'\s*:\s*True/.test(o??"")&&(f?.includes("postgres")??!1)&&/["']postgres["']\s*:\s*["']database-management["']/.test(r)&&/for infra in CORE_INFRA_EXPORT\s*:/.test(t)&&/needed\[INFRA_STACK_MAP_EXPORT\[infra\]\]\s*=\s*True/.test(t)}function C(e){let s=b(e);if(!s)return!1;let n=s.phases??{};for(let r of y){let t=n[r]?.enabledStacks;if(Array.isArray(t)&&t.includes(u))return!0}let a=s.always_enabled_infra??A;return Array.isArray(a)&&a.includes(u)}function L(e,s){let n=new Set;for(let t of O)n.add(t);for(let t of s)n.add(t.name),t.stack&&n.add(t.stack);let a=b(e);if(a){let t=a.phases??{};for(let f of y){let l=t[f]?.enabledStacks;if(Array.isArray(l))for(let c of l)n.add(c)}let o=a.always_enabled_infra??A;if(Array.isArray(o))for(let f of o)n.add(f)}let r=N(e);if(Array.isArray(r))for(let t of r)n.add(t);return n}function $(e,s=_(e)){let n=C(e),a=N(e),r=Array.isArray(a)&&a.includes(u),t=M(e)===!0,o=n||r||t,f=!n&&x(e),l=L(e,s),c=[],E=[];for(let p of s){let P=p.config?.dependsOn??[],g=!1;for(let m of P){if(D(m)){g=!0;continue}l.has(m)||E.push({resource:p.name,name:m})}g&&c.push(p.name)}let T=o||c.length>0,F=o?"feature":c.length>0?"dependsOn":"none";return{featureOn:o,featureOnFromProjectJson:n,featureOnFromTiltfile:r,featureOnFromSpecMaster:t,focusWouldEnableDatabaseManagement:f,dependsOnUsers:c,willStart:T,reason:F,unknownDependsOnNames:E}}export{O as a,$ as b};
@@ -0,0 +1,2 @@
1
+ import{createRequire as __tdkRequire}from'node:module';const require=__tdkRequire(import.meta.url);
2
+ import{execFileSync as a,spawnSync as c}from"node:child_process";import{existsSync as s}from"node:fs";import{join as l}from"node:path";var u=()=>({env:process.env,dockerAnswers:()=>{try{return a("docker",["info","--format","{{.ServerVersion}}"],{encoding:"utf-8",timeout:1e4,stdio:["ignore","pipe","ignore"]}),!0}catch{return!1}},run:(t,e)=>{let n=c(t,e,{encoding:"utf-8",timeout:2e4,stdio:["ignore","pipe","pipe"]});return`${n.stdout??""}${n.stderr??""}`},exists:s,home:process.env.HOME??""});function m(t=u()){let e=t.env.DOCKER_HOST??"";if(e.includes(".colima"))return!0;let n=l(t.home,".colima","default","docker.sock");return t.exists(n)&&e.includes("docker.sock")===!1&&e!==""}function p(t=u()){if(!m(t))return{isColima:!1,running:!0};let e="";try{e=t.run("colima",["status"])}catch(n){let i=String(n?.stderr??n);return/rosetta|native arch/i.test(i)?{isColima:!0,running:!1,problem:"Lima is installed as an x86_64 build, so it cannot start the Colima VM on this Mac",fix:"Install a native Lima (brew reinstall lima, or use a native limactl on PATH) and run `colima start`"}:t.dockerAnswers()?{isColima:!0,running:!0,problem:"The Colima VM is running, but the colima CLI on this PATH cannot see it",fix:"Use a native limactl (a Rosetta x86_64 limactl cannot talk to the VM): brew reinstall lima, or put a native limactl first on PATH"}:/not running/i.test(i)?{isColima:!0,running:!1,problem:"The Colima VM is not running",fix:"Run `colima start`"}:{isColima:!0,running:!1,problem:"The state of the Colima VM could not be read",fix:"Run `colima status` to see what it says"}}return/is running/i.test(e)?{isColima:!0,running:!0,arch:/arch:\s*(\S+)/.exec(e)?.[1]}:t.dockerAnswers()?{isColima:!0,running:!0,problem:"The Colima VM is running, but the colima CLI on this PATH cannot see it",fix:"Use a native limactl (a Rosetta x86_64 limactl cannot talk to the VM): brew reinstall lima, or put a native limactl first on PATH"}:{isColima:!0,running:!1,problem:"The Colima VM is not running",fix:"Run `colima start`"}}function g(t,e){if(t.isColima){if(t.problem&&/x86_64|rosetta|native arch|cannot see it/i.test(t.problem))return"native-lima";if(!t.running)return"start";if(!e)return"restart"}}function C(t=process.env){let e=t.HOME??"",n=["/opt/homebrew/bin",e?`${e}/.local/bin`:"",e?`${e}/bin`:""].filter(Boolean);for(let i of n){let r=l(i,"limactl");try{if(!s(r))continue;let o="";try{o=a("file",["-bL",r],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]})}catch{return i}if(/arm64|aarch64/i.test(o))return i}catch{}}}export{m as a,p as b,g as c,C as d};