rapidkit 0.27.3 → 0.27.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -1
- package/dist/chunk-NFUXULIF.js +1 -0
- package/dist/chunk-RWV2GNJJ.js +33 -0
- package/dist/chunk-TYC54P7X.js +4 -0
- package/dist/create-4NQKTQ3C.js +842 -0
- package/dist/doctor-BGVPFJ5U.js +47 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +130 -130
- package/dist/package.json +4 -1
- package/dist/pythonRapidkitExec-GPPHN3L4.js +1 -0
- package/dist/{workspace-7JHX7L3E.js → workspace-776YW7I6.js} +10 -10
- package/dist/workspace-run-7EGSG2UO.js +3 -0
- package/package.json +4 -1
- package/dist/chunk-UOGFCKQ5.js +0 -33
- package/dist/create-3V7O72CO.js +0 -781
- package/dist/doctor-VR432RMW.js +0 -48
- package/dist/pythonRapidkitExec-K2SFGAYJ.js +0 -1
- package/dist/workspace-run-3HRMQT7D.js +0 -3
package/dist/doctor-VR432RMW.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import {b,f,d,a as a$1,k,g,i as i$1}from'./chunk-Z5LKRG57.js';import {a}from'./chunk-VM2TOHNX.js';import l from'chalk';import {execa}from'execa';import i from'fs-extra';import o from'path';import Oe from'inquirer';function Le(e){return [...new Set(e.filter(s=>s&&s.trim().length>0))]}function Ve(){let e=k().map(t=>o.join(t,a$1()?"poetry.exe":"poetry")),s=a$1()?[o.join(process.env.APPDATA||"","Python","Scripts","poetry.exe"),o.join(process.env.USERPROFILE||"","AppData","Roaming","Python","Scripts","poetry.exe")]:[],a=a$1()?[]:["/usr/local/bin/poetry","/usr/bin/poetry"];return Le([...e,...s,...a])}function Je(e){let s=k().map(u=>({location:"Global (user-local)",path:o.join(u,a$1()?"rapidkit.exe":"rapidkit")})),a=[{location:"Global (pipx)",path:o.join(e,".local","bin","rapidkit")},{location:"Global (pipx)",path:o.join(e,"AppData","Roaming","Python","Scripts","rapidkit.exe")},{location:"Global (pyenv)",path:o.join(e,".pyenv","shims","rapidkit")},{location:"Global (system)",path:"/usr/local/bin/rapidkit"},{location:"Global (system)",path:"/usr/bin/rapidkit"}],t=g(o.join(process.cwd(),".venv")),r=i$1(process.cwd()),n=[{location:"Workspace (.venv)",path:t},...r.map(u=>({location:"Workspace (launcher)",path:u}))],c=[...s,...a,...n],d=new Set;return c.filter(u=>d.has(u.path)?false:(d.add(u.path),true))}function qe(e){let s=new Map([["Workspace (.venv)",0],["Global (user-local)",1],["Global (pipx)",2],["Global (pyenv)",3],["Global (system)",4]]);return [...e].sort((a,t)=>{let r=s.get(a.location)??Number.MAX_SAFE_INTEGER,n=s.get(t.location)??Number.MAX_SAFE_INTEGER;return r!==n?r-n:a.path.localeCompare(t.path)})}function Q(e){let s=0,a=e.issues.some(t=>t.toLowerCase().includes("environment file missing"));return e.hasEnvFile===false&&!a&&(s+=1),typeof e.vulnerabilities=="number"&&e.vulnerabilities>0&&(s+=1),s}function pe(e){return e.filter(s=>Q(s)>0).length}function fe(e){return e.reduce((s,a)=>s+Q(a),0)}var Ue="doctor-project-scan-v2",ze=Object.freeze({version:"doctor-evidence-v1",scoringPolicyVersion:"doctor-score-policy-v1",generatedBy:"rapidkit-npm",deterministicScoreBreakdown:true,scopeModel:"workspace-aggregate-or-project-scoped"});function oe(){return {...ze}}function ie(e){return !e||e.total<=0?null:Math.round(e.passed/e.total*100)}function Pe(e){return typeof e=="number"?e:Array.isArray(e)?e.length:0}async function Se(e){try{if(!await i.pathExists(e))return null;let s=await i.readJSON(e);return !s||typeof s!="object"?null:s}catch{return null}}function $e(e,s){if(!e?.system)return [];let a=[{id:"python",current:s.python},{id:"poetry",current:s.poetry},{id:"pipx",current:s.pipx},{id:"go",current:s.go},{id:"rapidkitCore",current:s.rapidkitCore}],t=[];for(let r of a){let n=e.system?.[r.id]?.status;!n||n===r.current.status||t.push({id:r.id,from:n,to:r.current.status});}return t}function Qe(e,s){let a=new Map;for(let f of s.projects)a.set(f.path||f.name,f.issues.length);if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let t=Array.isArray(e.projects)?e.projects:[],r=new Map;for(let f of t){let k=f.path||f.name;k&&r.set(k,Pe(f.issues));}let n=0,c=0,d=new Set,u=new Set,m=new Set([...Array.from(r.keys()),...Array.from(a.keys())]);for(let f of m){let k=r.get(f)??0,w=a.get(f)??0;w>k?(n+=w-k,d.add(f)):w<k&&(c+=k-w,u.add(f));}let p=ie(e.healthScore),h=ie(s.healthScore);return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:n,resolvedIssueCount:c,netIssueDelta:n-c,scoreDeltaPercent:p===null||h===null?null:h-p,systemStatusChanges:$e(e,{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore}),regressedProjects:Array.from(d).sort(),improvedProjects:Array.from(u).sort()}}function Xe(e,s){if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let a=Pe(e.project?.issues),t=s.project.issues.length,r=Math.max(t-a,0),n=Math.max(a-t,0),c=ie(e.healthScore),d=ie(s.healthScore),u=s.project.path||s.project.name;return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:r,resolvedIssueCount:n,netIssueDelta:r-n,scoreDeltaPercent:c===null||d===null?null:d-c,systemStatusChanges:$e(e,{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore}),regressedProjects:r>0?[u]:[],improvedProjects:n>0?[u]:[]}}function Re(e){let s=e??[],a=0,t=0;for(let c of s){if(c.scope==="project-scoped"){a+=1;continue}(c.scope==="workspace-aggregate"||c.scope==="host-system")&&(t+=1);}let r=a>0&&t>0?1:0,n=r>0?"mixed":a>0?"scoped":t>0?"aggregated":"unknown";return {scopedCount:a,aggregatedCount:t,mixedCount:r,dominantScope:n}}function S(e,s){return a$1()?`cd "${e}"; ${s}`:`cd ${e} && ${s}`}function O(e){return a$1()?S(e,"Copy-Item .env.example .env"):S(e,"cp .env.example .env")}function Ye(e){return e==="FastAPI"||e==="NestJS"||e==="Go/Fiber"||e==="Go/Gin"||e==="Spring Boot"||e==="Rust"||e==="Phoenix"?"first-class":e==="Django"||e==="Flask"||e==="Express"||e==="Fastify"||e==="Koa"||e==="Elixir"||e==="Clojure"||e==="Scala"||e==="Kotlin"||e==="Deno"||e==="Bun"||e==="PHP"||e==="Laravel"||e==="Ruby"||e==="Ruby on Rails"||e==="ASP.NET"?"extended":"observed"}function Ze(e){return e==="Next.js"||e==="Nuxt"||e==="React"||e==="Vue"||e==="Angular"||e==="SvelteKit"?"frontend":e==="Unknown"||e==="Node.js"||e==="Python"?"generic":"backend"}function et(e){return e==="NestJS"||e==="Next.js"||e==="Nuxt"||e==="React"||e==="Vue"||e==="Angular"||e==="SvelteKit"||e==="Bun"||e==="Express"||e==="Fastify"||e==="Koa"||e==="Node.js"?"node":e==="FastAPI"||e==="Django"||e==="Flask"||e==="Python"?"python":e==="Go/Fiber"||e==="Go/Gin"?"go":e==="Spring Boot"?"java":e==="Rust"?"rust":e==="Elixir"||e==="Phoenix"?"elixir":e==="Clojure"?"clojure":e==="Deno"?"deno":e==="Laravel"||e==="PHP"?"php":e==="Ruby on Rails"||e==="Ruby"?"ruby":e==="ASP.NET"?"dotnet":"unknown"}function F(e,s,a){e.framework=s,e.frameworkConfidence=a,e.supportTier=Ye(s),e.projectKind=Ze(s),e.runtimeFamily=et(s);}function tt(e){let s=e.dependencies,a=e.scripts??{},t=(e.kitName??"").toLowerCase(),r=c=>!!s[c],n=Object.values(a).filter(c=>typeof c=="string").join(" ").toLowerCase();return r("next")||n.includes("next ")?{framework:"Next.js",confidence:"high"}:r("nuxt")||n.includes("nuxt ")?{framework:"Nuxt",confidence:"high"}:r("@nestjs/core")||t.startsWith("nestjs.")?{framework:"NestJS",confidence:"high"}:r("express")?{framework:"Express",confidence:"high"}:r("fastify")?{framework:"Fastify",confidence:"high"}:r("koa")?{framework:"Koa",confidence:"high"}:r("@angular/core")?{framework:"Angular",confidence:"high"}:r("@sveltejs/kit")||n.includes("svelte-kit")?{framework:"SvelteKit",confidence:"high"}:r("vue")?{framework:"Vue",confidence:"medium"}:r("react")&&r("react-dom")?{framework:"React",confidence:"medium"}:{framework:"Node.js",confidence:"low"}}async function st(e){let s=[o.join(e,"pyproject.toml"),o.join(e,"requirements.txt")],a=[];for(let r of s)if(await i.pathExists(r))try{a.push((await i.readFile(r,"utf8")).toLowerCase());}catch{continue}let t=a.join(`
|
|
2
|
-
`);return t.includes("fastapi")?{framework:"FastAPI",confidence:"high"}:t.includes("django")?{framework:"Django",confidence:"high"}:t.includes("flask")?{framework:"Flask",confidence:"high"}:{framework:"Python",confidence:a.length>0?"medium":"low"}}async function ve(e){try{let s=await i.stat(e);return `${o.basename(e)}:${s.isDirectory()?"d":"f"}:${s.size}:${s.mtimeMs}`}catch{return `${o.basename(e)}:missing`}}async function nt(e){try{let s=new Set([".git",".venv","node_modules",".rapidkit","dist","build","coverage","__pycache__"]),a=new Set;await ae(e)&&a.add(e);let t=async(r,n)=>{if(n<0)return;let c=await Fe(r);for(let d of c){if(De(d,s))continue;let u=o.join(r,d);if(await ae(u)){a.add(u);continue}n>0&&await t(u,n-1);}};return await t(e,1),a.size===0&&(await gt(e,3,s)).forEach(n=>a.add(n)),Array.from(a).sort((r,n)=>r.localeCompare(n))}catch{return []}}async function ot(e,s){let a=[o.join(e,".rapidkit-workspace"),o.join(e,".rapidkit","workspace.json"),o.join(e,".rapidkit","policies.yml"),o.join(e,".rapidkit","toolchain.lock"),o.join(e,".rapidkit","cache-config.yml")],t=[".rapidkit/project.json",".rapidkit/context.json",".rapidkit/file-hashes.json","package.json","pyproject.toml","composer.json","Gemfile","Gemfile.lock","go.mod","go.sum","pom.xml","requirements.txt","Dockerfile","Makefile",".env",".env.example","src","modules","tests","test",".venv","node_modules"],r=await Promise.all(a.map(ve)),n=await Promise.all(s.map(async c=>{let d=await Promise.all(t.map(u=>ve(o.join(c,u))));return `${c}::${d.join("|")}`}));return [Ue,...r,...n].join("||")}async function it(e,s){try{if(!await i.pathExists(e))return null;let a=await i.readJSON(e);return !a||a.signature!==s||!Array.isArray(a.projects)?null:a}catch{return null}}async function at(e,s){try{await i.ensureDir(o.dirname(e)),await i.writeJSON(e,s,{spaces:2});}catch{}}async function rt(e,s,a){let t=o.join(e,".rapidkit","reports","doctor-last-run.json");try{return await i.ensureDir(o.dirname(t)),await i.writeJSON(t,{generatedAt:new Date().toISOString(),contract:oe(),workspacePath:e,workspaceName:s.workspaceName,projectScanCached:s.projectScanCached??false,projectScanSignature:s.projectScanSignature,cachePath:a,healthScore:s.healthScore,system:{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore,versions:{core:s.coreVersion,npm:s.npmVersion}},projects:s.projects,summary:{totalProjects:s.projects.length,totalIssues:s.projects.reduce((r,n)=>r+n.issues.length,0),projectAdvisoryWarningProjects:pe(s.projects),projectAdvisoryWarnings:fe(s.projects),hasSystemErrors:[s.python,s.rapidkitCore].some(r=>r.status==="error"),scopeProvenance:s.scopeProvenance},driftDelta:s.driftDelta,scoreBreakdown:s.scoreBreakdown??[]},{spaces:2}),t}catch{return}}async function ge(){let[e,s,a,t,r]=await Promise.all([ct(),lt(),dt(),ut(),pt()]);return {python:e,poetry:s,pipx:a,go:t,rapidkitCore:r}}async function ct(){let e=d();for(let s of e)try{let{stdout:a}=await execa(s,["--version"],{timeout:3e3}),t=a.match(/Python (\d+\.\d+\.\d+)/);if(t){let r=t[1],[n,c]=r.split(".").map(Number);return n<3||n===3&&c<10?{status:"warn",message:`Python ${r} (requires 3.10+)`,details:`${s} found but version is below minimum requirement`}:{status:"ok",message:`Python ${r}`,details:`Using ${s}`}}}catch{continue}return {status:"error",message:"Python not found",details:"Install Python 3.10+ and ensure it's in PATH"}}async function lt(){try{let{stdout:e}=await execa("poetry",["--version"],{timeout:3e3}),s=e.match(/Poetry .*version ([\d.]+)/);return s?{status:"ok",message:`Poetry ${s[1]}`,details:"Available for dependency management"}:{status:"warn",message:"Poetry version unknown"}}catch{let e=d().map(s=>({cmd:s,args:s==="py"?["-3","-m","poetry","--version"]:["-m","poetry","--version"]}));for(let s of e)try{let{stdout:a}=await execa(s.cmd,s.args,{timeout:3e3,shell:b()}),t=a.match(/Poetry .*version ([\d.]+)/)||a.match(/([\d.]+)/);return {status:"ok",message:t?.[1]?`Poetry ${t[1]}`:"Poetry detected",details:`Available via ${s.cmd} ${s.args.join(" ")}`}}catch{continue}for(let s of Ve())try{if(!await i.pathExists(s))continue;let{stdout:a}=await execa(s,["--version"],{timeout:3e3,shell:b()}),t=a.match(/Poetry .*version ([\d.]+)/)||a.match(/([\d.]+)/);return {status:"ok",message:t?.[1]?`Poetry ${t[1]}`:"Poetry detected",details:`Available at ${s}`}}catch{continue}return {status:"warn",message:"Poetry not installed",details:"Optional: Install for better dependency management"}}}async function dt(){try{let{stdout:e}=await execa("pipx",["--version"],{timeout:3e3});return {status:"ok",message:`pipx ${e.trim()}`,details:"Available for global tool installation"}}catch{let e=d();for(let s of e)try{let a=s==="py"?["-3","-m","pipx","--version"]:["-m","pipx","--version"],{stdout:t}=await execa(s,a,{timeout:3e3,shell:b()});return {status:"ok",message:`pipx ${t.trim()}`,details:`Available via ${s} ${a.join(" ")}`}}catch{continue}return {status:"warn",message:"pipx not installed",details:"Optional: Install for isolated Python tools"}}}async function ut(){try{let{stdout:e}=await execa("go",["version"],{timeout:3e3}),s=e.match(/go version go(\d+\.\d+(?:\.\d+)?)/);return s?{status:"ok",message:`Go ${s[1]}`,details:"Available for Go/Fiber and Go/Gin projects"}:{status:"ok",message:"Go (version unknown)",details:"go found in PATH"}}catch{return {status:"warn",message:"Go not installed",details:"Optional: Required only for gofiber.standard / gogin.standard projects \u2014 https://go.dev/dl/"}}}async function pt(){let e=process.env.HOME||process.env.USERPROFILE||"",s=[],a=Je(e);for(let{location:r,path:n}of a)try{if(await i.pathExists(n)){let{stdout:c,exitCode:d}=await execa(n,["--version"],{timeout:3e3,reject:false});if(d===0&&(c.includes("RapidKit Version")||c.includes("RapidKit"))){let u=c.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);u&&s.push({location:r,path:n,version:u[1]});}}}catch{continue}if(s.length>0){let r=s.filter(c=>c.location!=="Workspace (launcher)");if(r.length>0){let c=qe(r);return {status:"ok",message:`RapidKit Core ${c[0].version}`,paths:c.map(u=>({location:u.location,path:u.path,version:u.version}))}}return {status:"ok",message:`RapidKit Core ${s[0].version}`,details:"Detected via workspace launcher"}}try{let{stdout:r,exitCode:n}=await execa("rapidkit",["--version"],{timeout:3e3,reject:false});if(n===0&&(r.includes("RapidKit Version")||r.includes("RapidKit"))){let c=r.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(c)return {status:"ok",message:`RapidKit Core ${c[1]}`,details:"Available via PATH"}}}catch{}try{let{stdout:r,exitCode:n}=await execa("poetry",["run","rapidkit","--version"],{timeout:3e3,reject:false});if(n===0&&(r.includes("RapidKit Version")||r.includes("RapidKit"))){let c=r.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(c)return {status:"ok",message:`RapidKit Core ${c[1]}`,details:"Available via Poetry"}}}catch{}let t=d();for(let r of t)try{let{stdout:n,exitCode:c}=await execa(r,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:3e3,reject:false});if(c===0&&n&&!n.includes("Traceback")&&!n.includes("ModuleNotFoundError")){let d=n.trim();if(d)return {status:"ok",message:`RapidKit Core ${d}`,details:`Available in ${r} environment`}}}catch{continue}return {status:"error",message:"RapidKit Core not installed",details:"Install with: pipx install rapidkit-core"}}async function H(e,s){let a=o.join(e,"Dockerfile");s.hasDocker=await i.pathExists(a);let t=o.join(e,"tests"),r=o.join(e,"test"),n=o.join(e,"src","test"),c=await i.pathExists(t)||await i.pathExists(r)||await i.pathExists(n),d=false;if(s.framework==="Go/Fiber"||s.framework==="Go/Gin")try{let u=[{dir:e,depth:0}],m=4,p=new Set([".git",".venv","node_modules","dist","build","vendor"]);for(;u.length>0&&!d;){let h=u.shift();if(!h)break;let f=[];try{f=await i.readdir(h.dir);}catch{continue}for(let k of f){let w=o.join(h.dir,k),v;try{v=await i.stat(w);}catch{continue}if(v.isFile()&&k.endsWith("_test.go")){d=true;break}v.isDirectory()&&h.depth<m&&!p.has(k)&&!k.startsWith(".")&&u.push({dir:w,depth:h.depth+1});}}}catch{}if(s.hasTests=c||d,s.runtimeFamily==="node"){let u=o.join(e,".eslintrc.js"),m=o.join(e,".eslintrc.json");s.hasCodeQuality=await i.pathExists(u)||await i.pathExists(m);}else if(s.framework==="Go/Fiber"||s.framework==="Go/Gin"){let u=o.join(e,".golangci.yml"),m=o.join(e,".golangci.yaml"),p=o.join(e,"Makefile"),h=await i.pathExists(p)&&(await i.readFile(p,"utf8")).includes("golangci-lint");s.hasCodeQuality=await i.pathExists(u)||await i.pathExists(m)||h;}else if(s.runtimeFamily==="python"){let u=o.join(e,"ruff.toml"),m=o.join(e,"pyproject.toml");if(await i.pathExists(m))try{let p=await i.readFile(m,"utf8");s.hasCodeQuality=p.includes("[tool.ruff]")||await i.pathExists(u);}catch{s.hasCodeQuality=await i.pathExists(u);}}else if(s.framework==="Spring Boot"){let u=o.join(e,"pom.xml");if(await i.pathExists(u))try{let m=await i.readFile(u,"utf8");s.hasCodeQuality=m.includes("spotless")||m.includes("checkstyle")||m.includes("pmd")||m.includes("maven-enforcer-plugin");}catch{s.hasCodeQuality=false;}}try{if(s.runtimeFamily==="node"){let{stdout:u}=await execa("npm",["audit","--json"],{cwd:e,reject:false});if(u)try{let p=JSON.parse(u).metadata?.vulnerabilities;p&&(s.vulnerabilities=(p.high||0)+(p.critical||0)+(p.moderate||0));}catch{}}else if(s.runtimeFamily==="python"){let u=o.join(e,".venv"),m=f(u);if(await i.pathExists(m))try{let{stdout:p}=await execa(m,["-m","pip","list","--format=json"],{timeout:5e3,reject:false});if(p){JSON.parse(p);s.vulnerabilities=0;}}catch{}}}catch{}}function N(e,s){e.probes||(e.probes=[]),e.probes.push(s);}async function mt(e,s){let a=s.runtimeFamily||"unknown";if(s.projectKind==="backend"||s.projectKind==="generic"){if(a==="node"){let r=await i.pathExists(o.join(e,"package-lock.json"))||await i.pathExists(o.join(e,"pnpm-lock.yaml"))||await i.pathExists(o.join(e,"yarn.lock"));N(s,{id:"adapter-node-lockfile-integrity",label:"Node adapter lockfile integrity",status:r?"pass":"warn",severity:"warn",scope:"project-scoped",reason:r?"Node lockfile detected for deterministic dependency restore.":"No Node lockfile detected (package-lock/yarn.lock/pnpm-lock.yaml).",recommendation:r?void 0:"Commit a lockfile for deterministic installs and CI parity."});let n=await i.pathExists(o.join(e,"src/main.ts"))||await i.pathExists(o.join(e,"src/main.js"))||await i.pathExists(o.join(e,"src/server.ts"))||await i.pathExists(o.join(e,"src/server.js"));N(s,{id:"adapter-node-boot-entrypoint",label:"Node adapter boot entrypoint",status:n?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?"Boot entrypoint markers detected for service startup path.":"No canonical Node boot entrypoint markers detected.",recommendation:n?void 0:"Define and document service bootstrap entrypoint (main/server)."});return}if(a==="python"){let r=await i.pathExists(o.join(e,"poetry.lock"))||await i.pathExists(o.join(e,"requirements.txt"))||await i.pathExists(o.join(e,"uv.lock"));N(s,{id:"adapter-python-lockfile-integrity",label:"Python adapter dependency integrity",status:r?"pass":"warn",severity:"warn",scope:"project-scoped",reason:r?"Python dependency contract file detected.":"No Python dependency contract file detected (poetry.lock/requirements/uv.lock).",recommendation:r?void 0:"Pin dependency contract for deterministic setup and reproducible CI."});let n=await i.pathExists(o.join(e,"app/main.py"))||await i.pathExists(o.join(e,"main.py"))||await i.pathExists(o.join(e,"manage.py"));N(s,{id:"adapter-python-boot-entrypoint",label:"Python adapter boot entrypoint",status:n?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?"Python application entrypoint markers detected.":"No Python application entrypoint markers detected.",recommendation:n?void 0:"Expose explicit app/main entrypoint for deterministic boot probes."});return}if(a==="java"){let r=await i.pathExists(o.join(e,"mvnw"))||await i.pathExists(o.join(e,"gradlew"));N(s,{id:"adapter-java-build-wrapper",label:"Java adapter build wrapper",status:r?"pass":"warn",severity:"warn",scope:"project-scoped",reason:r?"Build wrapper detected (mvnw/gradlew).":"No Java build wrapper detected.",recommendation:r?void 0:"Commit mvnw or gradlew for reproducible enterprise pipelines."});return}if(a==="go"){let r=await i.pathExists(o.join(e,"go.sum"));N(s,{id:"adapter-go-module-integrity",label:"Go adapter module integrity",status:r?"pass":"warn",severity:"warn",scope:"project-scoped",reason:r?"go.sum detected for deterministic module verification.":"go.sum missing; module integrity baseline is incomplete.",recommendation:r?void 0:"Generate and commit go.sum in the repository baseline."});}}}async function ft(e,s){let a=[o.join(e,".rapidkit","doctor.adapters.json"),o.join(e,"doctor.adapters.json")];for(let t of a)if(await i.pathExists(t))try{let r=await i.readJSON(t),n=Array.isArray(r?.checks)?r.checks:[];for(let c=0;c<n.length;c+=1){let d=n[c]||{},u=Array.isArray(d.runtimes)?d.runtimes:[];if(u.length>0&&!u.includes(s.runtimeFamily||"unknown"))continue;let m=typeof d.id=="string"&&d.id.trim().length>0?d.id.trim():`adapter-check-${c+1}`,p=typeof d.label=="string"&&d.label.trim().length>0?d.label.trim():m,h=d.severity||"warn",f=Array.isArray(d.anyOfPaths)?d.anyOfPaths.filter(Boolean):[],k=Array.isArray(d.allOfPaths)?d.allOfPaths.filter(Boolean):[],w=f.length===0;for(let D of f)if(await i.pathExists(o.join(e,D))){w=true;break}let v=true;for(let D of k)if(!await i.pathExists(o.join(e,D))){v=false;break}let $=w&&v;N(s,{id:m,label:p,status:$?"pass":h==="error"?"fail":"warn",severity:h,scope:"project-scoped",reason:$?d.passReason||"Custom adapter contract satisfied.":d.failReason||`Custom adapter check failed from ${o.basename(t)}.`,recommendation:d.recommendation});}}catch{N(s,{id:"custom-adapter-config",label:"Custom doctor adapter configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${o.basename(t)}.`,recommendation:"Fix JSON syntax in doctor.adapters.json to re-enable adapter checks."});}}async function W(e,s){if(!(s.projectKind==="backend"||s.projectKind==="generic"))return;let t=o.join(e,".env"),r=o.join(e,".env.example"),n=await i.pathExists(t)||await i.pathExists(r)||await i.pathExists(o.join(e,"config"));N(s,{id:"config-surface",label:"Configuration contract surface",status:n?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?"Configuration artifacts detected (.env/.env.example/config).":"No explicit configuration contract artifacts detected.",recommendation:n?void 0:"Add .env.example or explicit config contract documentation for deterministic setup."});let c={python:["alembic.ini","migrations","versions"],node:["prisma/schema.prisma","migrations","typeorm.config.ts","typeorm.config.js"],go:["migrations","db/migrations"],java:["src/main/resources/db/migration","src/main/resources/liquibase"],rust:["migrations","sqlx-data.json"],elixir:["priv/repo/migrations"],clojure:["resources/migrations","migrations"],deno:["migrations"],php:["database/migrations","migrations"],ruby:["db/migrate"],dotnet:["Migrations","Data/Migrations"],unknown:["migrations"]},d=s.runtimeFamily||"unknown",u=c[d]||c.unknown,m=false;for(let f of u)if(await i.pathExists(o.join(e,f))){m=true;break}N(s,{id:"migration-surface",label:"Migration/readiness surface",status:m?"pass":"warn",severity:"warn",scope:"project-scoped",reason:m?"Migration or schema evolution markers detected.":"No migration markers detected for this backend runtime.",recommendation:m?void 0:"Add migration tooling baseline (migrations dir or runtime-native migration config)."});let p=["src/health","src/healthcheck","src/main/resources/application.yml","src/main/resources/application.properties","app/health.py","routes/health.ts","routes/health.js"],h=false;for(let f of p)if(await i.pathExists(o.join(e,f))){h=true;break}N(s,{id:"runtime-health-surface",label:"Runtime health probe surface",status:h?"pass":"warn",severity:"warn",scope:"project-scoped",reason:h?"Health endpoint/config markers detected.":"No explicit runtime health endpoint markers detected.",recommendation:h?void 0:"Expose a deterministic health endpoint and keep it covered in verify pack."}),await mt(e,s);}async function _(e,s){let a=[o.join(e,".rapidkit","doctor.probes.json"),o.join(e,"doctor.probes.json")];for(let t of a)if(await i.pathExists(t))try{let r=await i.readJSON(t),n=Array.isArray(r?.probes)?r.probes:[];for(let c=0;c<n.length;c+=1){let d=n[c]||{},u=typeof d.id=="string"&&d.id.trim().length>0?d.id.trim():`custom-probe-${c+1}`,m=typeof d.label=="string"&&d.label.trim().length>0?d.label.trim():u,p=d.severity||"warn",h=Array.isArray(d.anyOfPaths)?d.anyOfPaths.filter(Boolean):[],f=Array.isArray(d.allOfPaths)?d.allOfPaths.filter(Boolean):[],k=h.length===0;for(let $ of h)if(await i.pathExists(o.join(e,$))){k=true;break}let w=true;for(let $ of f)if(!await i.pathExists(o.join(e,$))){w=false;break}let v=k&&w;N(s,{id:u,label:m,status:v?"pass":p==="error"?"fail":"warn",severity:p,scope:"project-scoped",reason:v?"Custom probe contract satisfied.":`Custom probe failed from ${o.basename(t)}.`,recommendation:d.recommendation});}}catch{N(s,{id:"custom-probe-config",label:"Custom doctor probe configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${o.basename(t)}.`,recommendation:"Fix JSON syntax in doctor.probes.json to re-enable custom probes."});}await ft(e,s);}async function he(e,s={}){let t={name:o.basename(e),path:e,venvActive:false,depsInstalled:false,coreInstalled:false,issues:[],fixCommands:[]},r=s.allowNonRapidkit===true,n=o.join(e,".rapidkit");if(!await i.pathExists(n)){if(!r)return t.issues.push("Not a valid RapidKit project (missing .rapidkit directory)"),t;t.issues.push("Not a RapidKit-managed project (running generic backend diagnostics)");}try{let y=o.join(e,"registry.json");if(await i.pathExists(y)){let g=await i.readJson(y);g.installed_modules&&(t.stats={modules:g.installed_modules.length});}}catch{}let c=null;try{let y=o.join(n,"project.json");if(await i.pathExists(y)){c=await i.readJson(y);let g=c?.kit_name||c?.kit;g&&(t.kit=g);}}catch{}try{let y=o.join(e,".git");if(await i.pathExists(y)){let{stdout:g}=await execa("git",["log","-1","--format=%cr"],{cwd:e,reject:false});g&&(t.lastModified=g.trim());}else {let g=await i.stat(e),E=Date.now()-g.mtime.getTime(),b=Math.floor(E/(1e3*60*60*24));t.lastModified=b===0?"today":`${b} day${b>1?"s":""} ago`;}}catch{}let d=o.join(e,"package.json"),u=o.join(e,"pyproject.toml"),m=o.join(e,"requirements.txt"),p=o.join(e,"go.mod"),h=o.join(e,"pom.xml"),f$1=o.join(e,"build.sbt"),k=o.join(e,"Cargo.toml"),w=o.join(e,"mix.exs"),v=o.join(e,"deps.edn"),$=o.join(e,"project.clj"),D=o.join(e,"deno.json"),L=o.join(e,"deno.jsonc"),V=o.join(e,"bun.lockb"),B=o.join(e,"bun.lock"),Y=o.join(e,"composer.json"),J=o.join(e,"Gemfile"),M=await i.pathExists(d),A=await i.pathExists(u)||await i.pathExists(m),Z=await i.pathExists(Y),ee=await i.pathExists(J),Me=await i.pathExists(k),Ge=await i.pathExists(w),We=await i.pathExists(v)||await i.pathExists($),_e=await i.pathExists(f$1),Be=await i.pathExists(D)||await i.pathExists(L),re=false;try{re=(await i.readdir(e)).some(g=>g.endsWith(".csproj")||g.endsWith(".sln"));}catch{re=false;}let Ke=await i.pathExists(p)||c?.runtime==="go"||typeof c?.kit_name=="string"&&(c.kit_name.startsWith("gofiber")||c.kit_name.startsWith("gogin")),ye=M&&(await i.pathExists(V)||await i.pathExists(B)||typeof c?.packageManager=="string"&&(c?.packageManager).toLowerCase().startsWith("bun@"));if(Ke){let y=c?.kit_name??"";F(t,y.startsWith("gogin")?"Go/Gin":"Go/Fiber","high"),t.isGoProject=true,t.venvActive=true,t.coreInstalled=false;try{await execa("go",["version"],{timeout:3e3});}catch{t.issues.push("Go toolchain not found \u2014 install from https://go.dev/dl/"),t.fixCommands?.push("https://go.dev/dl/");}let g=o.join(e,"go.sum");return await i.pathExists(g)?t.depsInstalled=true:(t.depsInstalled=false,t.issues.push("Go dependencies not downloaded (go.sum missing)"),t.fixCommands?.push(S(e,"go mod tidy"))),await H(e,t),await W(e,t),await _(e,t),t}if(await i.pathExists(h)||c?.runtime==="java"||typeof c?.kit_name=="string"&&c.kit_name.startsWith("springboot")){F(t,"Spring Boot","high"),t.venvActive=true,t.coreInstalled=false;let y=await i.pathExists(h),g=await i.pathExists(o.join(e,"build.gradle"))||await i.pathExists(o.join(e,"build.gradle.kts")),C=await i.pathExists(o.join(e,"mvnw"))||await i.pathExists(o.join(e,"mvnw.cmd")),E=await i.pathExists(o.join(e,"gradlew"))||await i.pathExists(o.join(e,"gradlew.bat"));try{await execa("java",["-version"],{timeout:3e3,reject:false});}catch{t.issues.push("Java runtime not found \u2014 install JDK 21+ and ensure java is on PATH"),t.fixCommands?.push("https://adoptium.net/");}if(y){if(!C)try{await execa("mvn",["-version"],{timeout:3e3,reject:false});}catch{t.issues.push("Maven not found \u2014 install Maven 3.9+ or add Maven Wrapper"),t.fixCommands?.push("https://maven.apache.org/install.html");}}else if(g&&!E)try{await execa("gradle",["--version"],{timeout:3e3,reject:false});}catch{t.issues.push("Gradle not found \u2014 install Gradle 8+ or add Gradle Wrapper"),t.fixCommands?.push("https://gradle.org/install/");}let b=o.join(e,"target"),j=o.join(e,"build","libs"),I=o.join(e,".rapidkit","cache","java","m2"),R=o.join(e,".rapidkit","cache","java","gradle");t.depsInstalled=await i.pathExists(b)||await i.pathExists(j)||await i.pathExists(I)||await i.pathExists(R),t.depsInstalled||(t.issues.push("Java dependencies are not warmed or built yet"),t.fixCommands?.push(S(e,"rapidkit init")));let G=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(G),!t.hasEnvFile){let q=o.join(e,".env.example");await i.pathExists(q)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}let K=o.join(e,"src","main","resources","application.yml");if(await i.pathExists(K))try{let q=await i.readFile(K,"utf-8");/include:\s*[^\n]*health/i.test(q)||/management:\s*[\s\S]*endpoint:\s*[\s\S]*health:/i.test(q)||(t.issues.push("Actuator health endpoint exposure is not clearly configured in application.yml"),t.fixCommands?.push(S(e,"Ensure management.endpoints.web.exposure.include contains health in src/main/resources/application.yml")));}catch{t.issues.push("Unable to read application.yml for Spring Actuator health checks");}return await H(e,t),await W(e,t),await _(e,t),t}if(Me){F(t,"Rust","high"),t.venvActive=true,t.coreInstalled=false;let y=o.join(e,"Cargo.lock"),g=o.join(e,"target");t.depsInstalled=await i.pathExists(y)||await i.pathExists(g),t.depsInstalled||(t.issues.push("Rust dependencies are not resolved yet (Cargo.lock/target missing)"),t.fixCommands?.push(S(e,"cargo fetch")));let C=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(C),!t.hasEnvFile){let E=o.join(e,".env.example");await i.pathExists(E)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}return await H(e,t),await W(e,t),await _(e,t),t}if(Ge){let y="Elixir",g="medium";try{(await i.readFile(w,"utf8")).toLowerCase().includes("phoenix")&&(y="Phoenix",g="high");}catch{g="low";}F(t,y,g),t.venvActive=true,t.coreInstalled=false;let C=o.join(e,"mix.lock"),E=o.join(e,"deps");t.depsInstalled=await i.pathExists(C)||await i.pathExists(E),t.depsInstalled||(t.issues.push("Elixir dependencies not installed (mix.lock/deps missing)"),t.fixCommands?.push(S(e,"mix deps.get")));let b=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(b),!t.hasEnvFile){let j=o.join(e,".env.example");await i.pathExists(j)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}return await H(e,t),await W(e,t),await _(e,t),t}if(We){F(t,"Clojure","medium"),t.venvActive=true,t.coreInstalled=false;let y=o.join(e,".cpcache"),g=o.join(e,"target"),C=await i.pathExists(v)||await i.pathExists($);return t.depsInstalled=await i.pathExists(y)||await i.pathExists(g)||C,t.depsInstalled||(t.issues.push("Clojure dependency cache not initialized"),t.fixCommands?.push(S(e,"clojure -P"))),await H(e,t),await W(e,t),await _(e,t),t}if(_e){F(t,"Scala","high"),t.venvActive=true,t.coreInstalled=false;let y=o.join(e,"target");t.depsInstalled=await i.pathExists(y),t.depsInstalled||(t.issues.push("Scala build artifacts missing (run dependency/build warmup)"),t.fixCommands?.push(S(e,"sbt compile")));let g=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(g),!t.hasEnvFile){let C=o.join(e,".env.example");await i.pathExists(C)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}return await H(e,t),await W(e,t),await _(e,t),t}if(Be){F(t,"Deno","high"),t.venvActive=true,t.coreInstalled=false,t.depsInstalled=true;let y=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(y),!t.hasEnvFile){let g=o.join(e,".env.example");await i.pathExists(g)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}return await H(e,t),await W(e,t),await _(e,t),t}if(M){let y=null;try{y=await i.readJson(d);}catch{y=null;}let g={...y?.dependencies??{},...y?.devDependencies??{}},C=y?.scripts??{},E=typeof c?.kit_name=="string"?c.kit_name.toLowerCase():typeof c?.kit=="string"?c.kit.toLowerCase():"",b=tt({dependencies:g,scripts:C,kitName:E});ye?F(t,"Bun","high"):F(t,b.framework,b.confidence),t.venvActive=true;let j=o.join(e,"node_modules");if(await i.pathExists(j))try{let G=(await i.readdir(j)).filter(K=>!K.startsWith(".")&&!K.startsWith("_"));t.depsInstalled=G.length>0;}catch{t.depsInstalled=false;}if(t.depsInstalled||(t.issues.push("Dependencies not installed (node_modules empty or missing)"),t.fixCommands?.push(S(e,ye?"bun install":"rapidkit init"))),t.coreInstalled=false,t.projectKind==="frontend"){let R=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local"];if((await Promise.all(R.map(K=>i.pathExists(o.join(e,K))))).some(Boolean))t.hasEnvFile=true;else {let K=o.join(e,".env.example");await i.pathExists(K)&&(t.hasEnvFile=false,t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}}else {let R=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(R),!t.hasEnvFile){let G=o.join(e,".env.example");await i.pathExists(G)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}}let I=o.join(e,"src");if(t.modulesHealthy=true,t.missingModules=[],await i.pathExists(I))try{let R=await i.readdir(I);t.modulesHealthy=R.length>0;}catch{t.modulesHealthy=false;}return await H(e,t),await W(e,t),await _(e,t),t}if(A){let y=await st(e);F(t,y.framework,y.confidence);let g=o.join(e,".venv");if(await i.pathExists(g)){t.venvActive=true;let j=f(g);if(await i.pathExists(j)){try{let{stdout:G}=await execa(j,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:2e3});t.coreInstalled=true,t.coreVersion=G.trim();}catch{t.coreInstalled=false;}let I="fastapi";t.framework==="Django"?I="django":t.framework==="Flask"?I="flask":t.framework==="Python"&&(I="");let R=true;if(I)try{await execa(j,["-c",`import ${I}`],{timeout:2e3}),t.depsInstalled=true,R=false;}catch{R=true;}if(R)try{let G=o.join(g,"lib");if(await i.pathExists(G)){let q=(await i.readdir(G)).find(te=>te.startsWith("python"));if(q){let te=o.join(G,q,"site-packages");if(await i.pathExists(te)){let Te=(await i.readdir(te)).filter(ce=>!ce.startsWith("_")&&!ce.includes("dist-info")&&!["pip","setuptools","wheel","pkg_resources"].includes(ce));t.depsInstalled=Te.length>0;}}}t.depsInstalled||(t.issues.push("Dependencies not installed"),t.fixCommands?.push(S(e,"rapidkit init")));}catch{t.issues.push("Could not verify dependency installation");}}else t.issues.push("Virtual environment exists but Python executable not found");}else t.issues.push("Virtual environment not created"),t.fixCommands?.push(S(e,"rapidkit init"));let C=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(C),!t.hasEnvFile){let j=o.join(e,".env.example");await i.pathExists(j)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}let E=o.join(e,"src"),b=o.join(e,"modules");if(t.modulesHealthy=true,t.missingModules=[],await i.pathExists(E)){let j=o.join(E,"__init__.py");await i.pathExists(j)||(t.modulesHealthy=false,t.missingModules.push("src/__init__.py"));}if(await i.pathExists(b))try{let j=await Fe(b);for(let I of j){let R=o.join(b,I,"__init__.py");await i.pathExists(R)||(t.modulesHealthy=false,t.missingModules.push(`modules/${I}/__init__.py`));}}catch{}return !t.modulesHealthy&&t.missingModules.length>0&&t.issues.push(`Missing module init files: ${t.missingModules.join(", ")}`),await H(e,t),await W(e,t),await _(e,t),t}if(Z){let y="PHP",g="medium";try{let b=await i.readJson(Y);({...b?.require??{},...b?.["require-dev"]??{}})["laravel/framework"]?(y="Laravel",g="high"):(y="PHP",g="medium");}catch{y="PHP",g="low";}F(t,y,g),t.venvActive=true,t.coreInstalled=false;let C=o.join(e,"vendor");t.depsInstalled=await i.pathExists(C),t.depsInstalled||(t.issues.push("PHP dependencies not installed (vendor missing)"),t.fixCommands?.push(S(e,"composer install")));let E=o.join(e,".env");if(t.hasEnvFile=await i.pathExists(E),!t.hasEnvFile){let b=o.join(e,".env.example");await i.pathExists(b)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(O(e)));}return await H(e,t),await W(e,t),await _(e,t),t}if(ee){let y="Ruby",g="low";try{let j=(await i.readFile(J,"utf8")).toLowerCase();j.includes("gem 'rails'")||j.includes('gem "rails"')?(y="Ruby on Rails",g="high"):(y="Ruby",g="medium");}catch{g="low";}F(t,y,g),t.venvActive=true,t.coreInstalled=false;let C=await i.pathExists(o.join(e,"Gemfile.lock")),E=await i.pathExists(o.join(e,"vendor","bundle"));t.depsInstalled=C||E,t.depsInstalled||(t.issues.push("Ruby dependencies not installed (Gemfile.lock/vendor missing)"),t.fixCommands?.push(S(e,"bundle install")));let b=o.join(e,".env");return t.hasEnvFile=await i.pathExists(b),await H(e,t),await W(e,t),await _(e,t),t}if(re){F(t,"ASP.NET","medium"),t.venvActive=true,t.coreInstalled=false;let y=o.join(e,"obj"),g=o.join(e,"packages.lock.json");t.depsInstalled=await i.pathExists(y)||await i.pathExists(g),t.depsInstalled||(t.issues.push(".NET restore/build artifacts not found"),t.fixCommands?.push(S(e,"dotnet restore")));let C=o.join(e,".env");return t.hasEnvFile=await i.pathExists(C),await H(e,t),t}return F(t,"Unknown","low"),t.issues.push("Unknown project type (no recognized runtime marker files)"),await H(e,t),await W(e,t),await _(e,t),t}async function Fe(e){try{return (await i.readdir(e,{withFileTypes:true})).filter(a=>a.isDirectory()).map(a=>a.name)}catch{try{let s=await i.readdir(e),a=[];for(let t of s)try{(await i.stat(o.join(e,t))).isDirectory()&&a.push(t);}catch{continue}return a}catch{return []}}}async function ae(e){let s=o.join(e,".rapidkit");if(!await i.pathExists(s))return false;let a=["project.json","context.json","file-hashes.json"];for(let t of a)if(await i.pathExists(o.join(s,t)))return true;return false}function De(e,s){if(s.has(e))return true;let a=e.toLowerCase();return !!(a==="dist"||a.startsWith("dist-")||a.startsWith("dist_")||a==="build"||a.startsWith("build-")||a.startsWith("build_"))}async function gt(e,s,a){let t=new Set,r=[{dir:e,depth:0}];for(;r.length>0;){let n=r.shift();if(!n)break;try{let c=await i.readdir(n.dir);for(let d of c){if(De(d,a))continue;let u=o.join(n.dir,d),m;try{m=await i.stat(u);}catch{continue}if(m.isDirectory()){if(await ae(u)){t.add(u);continue}n.depth<s&&r.push({dir:u,depth:n.depth+1});}}}catch{continue}}return Array.from(t)}async function me(e){let s=e,a=o.parse(s).root;for(;s!==a;){let t=[o.join(s,".rapidkit-workspace"),o.join(s,".rapidkit","workspace-marker.json"),o.join(s,".rapidkit","config.json")];for(let r of t)if(await i.pathExists(r))return s;s=o.dirname(s);}return null}async function ht(e){let s=e,a=o.parse(s).root;for(;;){if(await ae(s)||await yt(s))return s;if(s===a)break;s=o.dirname(s);}return null}function xe(e){let s=o.resolve(e);return process.platform==="darwin"?s.replace(/^\/private(?=\/var\/)/,""):s}async function yt(e){let s=["package.json","pyproject.toml","requirements.txt","go.mod","pom.xml","build.sbt","Cargo.toml","mix.exs","deps.edn","project.clj","deno.json","deno.jsonc","composer.json","Gemfile"];for(let a of s)if(await i.pathExists(o.join(e,a)))return true;return false}function Ae(e,s){let a=0,t=0,r=0;return e.forEach(c=>{c.status==="ok"?a++:c.status==="warn"?t++:c.status==="error"&&r++;}),s.forEach(c=>{let d=Q(c),u=c.isGoProject?c.issues.length===0&&c.depsInstalled:c.issues.length===0&&c.venvActive&&c.depsInstalled;if(c.issues.length>0||d>0||!u){t++;return}a++;}),{total:a+t+r,passed:a,warnings:t,errors:r}}function Ie(e,s,a={}){let t=[];for(let n of e)t.push({id:n.id,label:n.label,status:n.result.status,scope:"host-system",policyRuleId:"system-status-derived",reason:n.result.details||n.result.message});let r=[...s].sort((n,c)=>{let d=`${n.path||""}|${n.name||""}`.toLowerCase(),u=`${c.path||""}|${c.name||""}`.toLowerCase();return d.localeCompare(u)});for(let n of r){let c=n.issues.length>0,d=Q(n),u=c||d>0?"warn":"ok",m=c?`${n.issues.length} blocking issue(s)`:d>0?`${d} advisory warning(s)`:"Project checks passed";t.push({id:`project:${n.name}`,label:`Project ${n.name}`,status:u,scope:"project-scoped",policyRuleId:c?"project-blocking-issues":d>0?"project-advisory-warnings":"project-checks-passed",reason:m});}if(a.includeWorkspaceAggregateRules){let n=s.reduce((u,m)=>u+m.issues.length,0),c=fe(s),d=e.filter(u=>u.result.status==="error").length;t.push({id:"workspace:projects-discovered",label:"Workspace projects discovered",status:s.length>0?"ok":"warn",scope:"workspace-aggregate",policyRuleId:"workspace-project-discovery",reason:s.length>0?`${s.length} project(s) discovered for workspace analysis.`:"No projects discovered for workspace analysis."}),t.push({id:"workspace:system-error-gate",label:"Workspace system error gate",status:d>0?"error":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-system-error-gate",reason:d>0?`${d} system requirement gate(s) failed.`:"All system requirement gates passed."}),t.push({id:"workspace:blocking-issues-gate",label:"Workspace blocking issues gate",status:n>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-blocking-issues-gate",reason:n>0?`${n} blocking project issue(s) detected.`:"No blocking project issues detected."}),t.push({id:"workspace:advisory-warnings-gate",label:"Workspace advisory warnings gate",status:c>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-advisory-warning-gate",reason:c>0?`${c} advisory warning(s) detected.`:"No advisory warnings detected."});}return t}async function be(e,s=true){let a$1=o.basename(e);try{let f=o.join(e,".rapidkit-workspace");await i.pathExists(f)&&(a$1=(await i.readJSON(f)).name||a$1);}catch{try{let f=o.join(e,".rapidkit","config.json");a$1=(await i.readJSON(f)).workspace_name||a$1;}catch{}}let[t,r]=await Promise.all([ge(),nt(e)]),n={workspacePath:e,workspaceName:a$1,python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore,projects:[]};a.debug(`Workspace scan found ${r.length} project(s)`);let c=await ot(e,r),d=o.join(e,".rapidkit","reports","doctor-workspace-cache.json"),u=s?await it(d,c):null;if(u)n.projects=u.projects,n.projectScanCached=true,a.debug(`Workspace project health cache hit: ${d}`);else try{let f=await Promise.all(r.map(k=>he(k)));n.projects=f,n.projectScanCached=false,await at(d,{signature:c,generatedAt:new Date().toISOString(),projects:f}),a.debug(`Workspace project health cache refreshed: ${d}`);}catch(f){a.debug(`Failed to scan workspace projects: ${f}`);}n.projectScanSignature=c,n.projectScanCachePath=d;let m=[n.python,n.poetry,n.pipx,n.go,n.rapidkitCore];if(n.healthScore=Ae(m,n.projects),n.scoreBreakdown=Ie([{id:"system-python",label:"Python",result:n.python},{id:"system-poetry",label:"Poetry",result:n.poetry},{id:"system-pipx",label:"pipx",result:n.pipx},{id:"system-go",label:"Go",result:n.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:n.rapidkitCore}],n.projects,{includeWorkspaceAggregateRules:true}),n.scopeProvenance=Re(n.scoreBreakdown),n.rapidkitCore.status==="ok"){let f=n.rapidkitCore.message.match(/([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);f&&(n.coreVersion=f[1]);}let p=o.join(e,".rapidkit","reports","doctor-last-run.json"),h=await Se(p);return n.driftDelta=Qe(h,n),n.evidencePath=await rt(e,n,u?d:null),n}async function wt(e,s){let a=e||s.projectPath,t=o.join(a,".rapidkit","reports","doctor-project-last-run.json");try{return await i.ensureDir(o.dirname(t)),await i.writeJSON(t,{generatedAt:new Date().toISOString(),contract:oe(),workspacePath:e||null,projectPath:s.projectPath,projectName:s.projectName,healthScore:s.healthScore,system:{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore},project:s.project,driftDelta:s.driftDelta,summary:{scopeProvenance:s.scopeProvenance},scoreBreakdown:s.scoreBreakdown??[]},{spaces:2}),t}catch{return}}async function kt(e){let s=await me(e),a=await ge(),t=await he(e,{allowNonRapidkit:true}),r=Ae([a.python,a.poetry,a.pipx,a.go,a.rapidkitCore],[t]),n={workspacePath:s||void 0,projectPath:e,projectName:o.basename(e),python:a.python,poetry:a.poetry,pipx:a.pipx,go:a.go,rapidkitCore:a.rapidkitCore,project:t,healthScore:r};n.scoreBreakdown=Ie([{id:"system-python",label:"Python",result:n.python},{id:"system-poetry",label:"Poetry",result:n.poetry},{id:"system-pipx",label:"pipx",result:n.pipx},{id:"system-go",label:"Go",result:n.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:n.rapidkitCore}],[n.project]),n.scopeProvenance=Re(n.scoreBreakdown);let c=s||e,d=o.join(c,".rapidkit","reports","doctor-project-last-run.json"),u=await Se(d);return n.driftDelta=Xe(u,n),n.evidencePath=await wt(s||void 0,n),n}function P(e,s){let a=e.status==="ok"?"\u2705":e.status==="warn"?"\u26A0\uFE0F":"\u274C",t=e.status==="ok"?l.green:e.status==="warn"?l.yellow:l.red;console.log(`${a} ${l.bold(s)}: ${t(e.message)}`),e.paths&&e.paths.length>0?e.paths.forEach(r=>{let n=r.version?l.cyan(` -> ${r.version}`):"";console.log(` ${l.cyan("\u2022")} ${l.gray(r.location)}: ${l.dim(r.path)}${n}`);}):e.details&&console.log(` ${l.gray(e.details)}`);}function je(e){let s=e.issues.length>0,a=s?"\u26A0\uFE0F":"\u2705",t=s?l.yellow:l.green;if(console.log(`
|
|
3
|
-
${a} ${l.bold("Project")}: ${t(e.name)}`),e.framework){let c=e.framework==="FastAPI"||e.framework==="Django"||e.framework==="Flask"?"\u{1F40D}":e.framework==="NestJS"?"\u{1F985}":e.framework==="Next.js"||e.framework==="Nuxt"?"\u25B2":e.framework==="React"?"\u269B\uFE0F":e.framework==="Vue"?"\u{1F7E2}":e.framework==="Angular"?"\u{1F170}\uFE0F":e.framework==="SvelteKit"?"\u{1F9E1}":e.framework==="Spring Boot"?"\u2615":e.framework==="Rust"?"\u{1F980}":e.framework==="Elixir"||e.framework==="Phoenix"?"\u{1F9EA}":e.framework==="Clojure"?"\u2699\uFE0F":e.framework==="Scala"?"\u{1F53A}":e.framework==="Kotlin"?"\u{1F7E3}":e.framework==="Deno"?"\u{1F995}":e.framework==="Bun"?"\u{1F956}":e.framework==="Go/Fiber"||e.framework==="Go/Gin"?"\u{1F439}":e.framework==="Laravel"||e.framework==="PHP"?"\u{1F418}":e.framework==="Ruby on Rails"||e.framework==="Ruby"?"\u{1F48E}":e.framework==="ASP.NET"?"\u{1F537}":"\u{1F4E6}";console.log(` ${c} Framework: ${l.cyan(e.framework)}${e.kit?l.gray(` (${e.kit})`):""}`);let d=[];e.runtimeFamily&&d.push(`runtime: ${e.runtimeFamily}`),e.projectKind&&d.push(`kind: ${e.projectKind}`),e.supportTier&&d.push(`support: ${e.supportTier}`),e.frameworkConfidence&&d.push(`confidence: ${e.frameworkConfidence}`),d.length>0&&console.log(` ${l.dim("\u21B3")} ${l.gray(d.join(" \u2022 "))}`);}if(console.log(` ${l.gray(`Path: ${e.path}`)}`),e.runtimeFamily==="python"&&(e.venvActive?console.log(` \u2705 Virtual environment: ${l.green("Active")}`):console.log(` \u274C Virtual environment: ${l.red("Not found")}`),e.coreInstalled?console.log(` ${l.dim("\u2139")} RapidKit Core: ${l.gray(e.coreVersion||"In venv")} ${l.dim("(optional)")}`):console.log(` ${l.dim("\u2139")} RapidKit Core: ${l.gray("Using global installation")} ${l.dim("(recommended)")}`)),e.depsInstalled?console.log(` \u2705 Dependencies: ${l.green("Installed")}`):console.log(` \u26A0\uFE0F Dependencies: ${l.yellow("Not installed")}`),e.hasEnvFile!==void 0&&(e.hasEnvFile?console.log(` \u2705 Environment: ${l.green(".env configured")}`):console.log(` \u26A0\uFE0F Environment: ${l.yellow(".env missing")}`)),e.modulesHealthy!==void 0&&(e.modulesHealthy?console.log(` \u2705 Modules: ${l.green("Healthy")}`):e.missingModules&&e.missingModules.length>0&&console.log(` \u26A0\uFE0F Modules: ${l.yellow(`Missing ${e.missingModules.length} init file(s)`)}`)),e.stats){let c=[];e.stats.modules!==void 0&&c.push(`${e.stats.modules} module${e.stats.modules!==1?"s":""}`),c.length>0&&console.log(` \u{1F4CA} Stats: ${l.cyan(c.join(" \u2022 "))}`);}e.lastModified&&console.log(` \u{1F552} Last Modified: ${l.gray(e.lastModified)}`);let n=[];if(e.hasTests!==void 0&&n.push(e.hasTests?"\u2705 Tests":l.dim("\u2298 No tests")),e.hasDocker!==void 0&&n.push(e.hasDocker?"\u2705 Docker":l.dim("\u2298 No Docker")),e.hasCodeQuality!==void 0){let c=e.runtimeFamily==="node"?"ESLint":e.runtimeFamily==="rust"?"clippy":e.runtimeFamily==="elixir"?"Credo":e.runtimeFamily==="clojure"?"clj-kondo":e.runtimeFamily==="deno"?"deno lint":e.framework==="Spring Boot"?"Static analysis":e.framework==="Go/Fiber"||e.framework==="Go/Gin"?"golangci-lint":e.runtimeFamily==="python"?"Ruff":"Lint";n.push(e.hasCodeQuality?`\u2705 ${c}`:l.dim(`\u2298 No ${c}`));}if(n.length>0&&console.log(` ${n.join(" \u2022 ")}`),e.vulnerabilities!==void 0&&e.vulnerabilities>0&&console.log(` \u26A0\uFE0F Security: ${l.yellow(`${e.vulnerabilities} vulnerability(ies) found`)}`),e.issues.length>0&&(console.log(` ${l.bold("Issues:")}`),e.issues.forEach(c=>{console.log(` \u2022 ${l.yellow(c)}`);}),e.fixCommands&&e.fixCommands.length>0&&(console.log(`
|
|
4
|
-
${l.bold.cyan("\u{1F527} Quick Fix:")}`),e.fixCommands.forEach(c=>{console.log(` ${l.cyan("$")} ${l.white(c)}`);}))),e.probes&&e.probes.length>0){console.log(` ${l.bold("Probe checks:")}`);for(let c of e.probes){let d=c.status==="pass"?"\u2705":c.status==="warn"?"\u26A0\uFE0F":"\u274C";console.log(` ${d} ${c.label}: ${l.gray(c.reason)}`),c.recommendation&&console.log(` ${l.dim("\u21B3")} ${l.gray(c.recommendation)}`);}}}async function Ce(){try{return (await execa("go",["version"],{timeout:3e3,reject:false})).exitCode===0}catch{return false}}function X(e,s){let a=[new RegExp(`^cd\\s+"([^"]+)"\\s*(?:&&|;)\\s*${s}\\s*$`,"i"),new RegExp(`^cd\\s+'([^']+)'\\s*(?:&&|;)\\s*${s}\\s*$`,"i"),new RegExp(`^cd\\s+(.+?)\\s*(?:&&|;)\\s*${s}\\s*$`,"i")];for(let t of a){let r=e.match(t);if(r?.[1])return {projectPath:r[1].trim()}}return null}function He(e){return X(e,"cp\\s+\\.env\\.example\\s+\\.env")||X(e,"copy-item\\s+\\.env\\.example\\s+\\.env")}function Ne(e){let s=[{pattern:"npm\\s+install",command:"npm",args:["install"]},{pattern:"npm\\s+ci",command:"npm",args:["ci"]},{pattern:"pnpm\\s+install",command:"pnpm",args:["install"]},{pattern:"yarn\\s+install",command:"yarn",args:["install"]},{pattern:"poetry\\s+install",command:"poetry",args:["install"]},{pattern:"pip\\s+install\\s+-r\\s+requirements\\.txt",command:"pip",args:["install","-r","requirements.txt"]},{pattern:"composer\\s+install",command:"composer",args:["install"]},{pattern:"bundle\\s+install",command:"bundle",args:["install"]},{pattern:"dotnet\\s+restore",command:"dotnet",args:["restore"]},{pattern:"cargo\\s+fetch",command:"cargo",args:["fetch"]},{pattern:"mix\\s+deps\\.get",command:"mix",args:["deps.get"]},{pattern:"clojure\\s+-P",command:"clojure",args:["-P"]},{pattern:"sbt\\s+compile",command:"sbt",args:["compile"]}];for(let a of s){let t=X(e,a.pattern);if(t)return {projectPath:t.projectPath,command:a.command,args:a.args}}return null}function ue(e,s){return /^https?:\/\//i.test(s.trim())?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"manual-url",risk:"safe",executable:false,reason:"Manual guidance URL"}:He(s)?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"env-copy",risk:"safe",executable:true,reason:"Environment seed copy"}:X(s,"rapidkit\\s+init")?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"rapidkit-init",risk:"guarded",executable:true,reason:"RapidKit initializer may mutate dependencies and configs"}:X(s,"go\\s+mod\\s+tidy")?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"go-mod-tidy",risk:"guarded",executable:true,reason:"Go module graph reconciliation"}:Ne(s)?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"dependency-sync",risk:"guarded",executable:true,reason:"Dependency synchronization command"}:{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"shell",risk:"invasive",executable:true,reason:"Generic shell command"}}function Ee(e){let s=e instanceof Error?e.message:String(e),a=["ETIMEDOUT","ECONNRESET","ECONNREFUSED","EAI_AGAIN","ENOTFOUND","network","503","504"],t=s.toLowerCase();return a.some(r=>t.includes(r.toLowerCase()))}async function vt(e,s){let a=e.get(s);if(a)return a;let t=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,r=o.basename(s).replace(/[^a-zA-Z0-9._-]/g,"_"),n=o.join(s,".rapidkit","reports","fix-snapshots",`${r}-${t}`);await i.ensureDir(n);let c=[".env","package-lock.json","pnpm-lock.yaml","yarn.lock","poetry.lock","requirements.txt","go.mod","go.sum","Cargo.lock","composer.lock","Gemfile.lock","pom.xml","build.gradle","build.gradle.kts","gradle.lockfile"],d=new Map;for(let m of c){let p=o.join(s,m);if(!await i.pathExists(p))continue;let h=o.join(n,m);await i.ensureDir(o.dirname(h)),await i.copy(p,h,{overwrite:true}),d.set(p,h);}let u={snapshotRoot:n,files:d};return e.set(s,u),u}async function xt(e){for(let[s,a]of e.files.entries())await i.pathExists(a)&&(await i.ensureDir(o.dirname(s)),await i.copy(a,s,{overwrite:true}));}async function bt(e){let s=await he(e,{allowNonRapidkit:true});return {issues:s.issues.length,healthy:s.issues.length===0}}async function ne(e,s=false){let a=e.filter(f=>f.fixCommands&&f.fixCommands.length>0),t=null,r=new Map;if(a.length===0){console.log(l.green(`
|
|
5
|
-
\u2705 No fixes needed - all projects are healthy!`));return}let n=a.flatMap(f=>(f.fixCommands??[]).map(k=>ue(f,k)));console.log(l.bold.cyan(`
|
|
6
|
-
\u{1F527} Available Fixes:
|
|
7
|
-
`));for(let f of a){let k=f.fixCommands??[];console.log(l.bold(`Project: ${l.yellow(f.name)}`)),k.forEach((w,v)=>{console.log(` ${v+1}. ${l.cyan(w)}`);}),console.log();}let c=0,d=0,u=0,m=0;for(let f of n)f.executable&&(f.kind==="go-mod-tidy"&&(t===null&&(t=await Ce()),!t)||(c+=1,f.risk==="safe"&&(d+=1),f.risk==="guarded"&&(u+=1),f.risk==="invasive"&&(m+=1)));if(c===0){console.log(l.gray("\u{1F4A1} No automatic fixes can be applied right now.")),t===false&&console.log(l.gray(" Install Go to enable go mod tidy fixes, then rerun `rapidkit doctor workspace --fix`."));return}if(!s){console.log(l.gray('\u{1F4A1} Run "npx rapidkit doctor workspace --fix" to apply fixes automatically'));return}console.log(l.gray(`Risk policy: safe=${d}, guarded=${u}, invasive=${m}. Guarded/invasive fixes use snapshot + rollback.`));let{confirm:p}=await Oe.prompt([{type:"confirm",name:"confirm",message:`Apply ${a.reduce((f,k)=>f+(k.fixCommands?.length??0),0)} fix(es)?`,default:false}]);if(!p){console.log(l.yellow(`
|
|
8
|
-
\u26A0\uFE0F Fixes cancelled by user`));return}console.log(l.bold.cyan(`
|
|
9
|
-
\u{1F680} Applying fixes...
|
|
10
|
-
`));let h=new Set;for(let f of a){let k=f.fixCommands??[];console.log(l.bold(`Fixing ${l.cyan(f.name)}...`));for(let w of k){let v=ue(f,w),$=`${f.path}::${w}`;if(!h.has($)){h.add($);try{if(console.log(l.gray(` $ ${w}`)),v.kind==="manual-url"){console.log(l.yellow(` \u2139 Manual action required: open ${w}`)),console.log(l.green(` \u2705 Recorded as guidance
|
|
11
|
-
`));continue}if(!v.executable){console.log(l.yellow(" \u26A0 Step is non-executable by policy")),console.log(l.green(` \u2705 Recorded as guidance
|
|
12
|
-
`));continue}v.risk!=="safe"&&await vt(r,v.projectPath);let D=He(w);if(D){let M=o.join(D.projectPath,".env.example"),A=o.join(D.projectPath,".env");if(!await i.pathExists(M))throw new Error(`.env.example not found at ${M}`);if(await i.pathExists(A)){console.log(l.green(` \u2705 .env already exists
|
|
13
|
-
`));continue}await i.copy(M,A,{overwrite:false,errorOnExist:false}),console.log(l.green(` \u2705 Success
|
|
14
|
-
`));continue}let L=X(w,"rapidkit\\s+init");if(L){await execa("rapidkit",["init"],{cwd:L.projectPath,shell:b(),stdio:"inherit"}),console.log(l.green(` \u2705 Success
|
|
15
|
-
`));continue}let V=X(w,"go\\s+mod\\s+tidy");if(V){if(t===null&&(t=await Ce()),!t){console.log(l.yellow(" \u26A0 Go toolchain is not installed \u2014 skipping go mod tidy; install Go to apply this fix.")),console.log(l.green(` \u2705 Recorded as guidance
|
|
16
|
-
`));continue}await execa("go",["mod","tidy"],{cwd:V.projectPath,shell:b(),stdio:"inherit"}),console.log(l.green(` \u2705 Success
|
|
17
|
-
`));continue}let B=Ne(w);if(B){let A;for(let Z=1;Z<=2;Z+=1)try{await execa(B.command,B.args,{cwd:B.projectPath,shell:b(),stdio:"inherit"}),A=null;break}catch(ee){if(A=ee,Z<2&&Ee(ee)){console.log(l.yellow(` \u26A0 Retrying dependency sync (${Z}/1)...`));continue}throw ee}if(A)throw A;console.log(l.green(` \u2705 Success
|
|
18
|
-
`));continue}let Y=v.kind==="shell"?2:1,J;for(let M=1;M<=Y;M+=1)try{await execa(w,{shell:true,stdio:"inherit"}),J=null;break}catch(A){if(J=A,M<Y&&Ee(A)){console.log(l.yellow(` \u26A0 Retrying command (${M}/${Y-1})...`));continue}throw A}if(J)throw J;console.log(l.green(` \u2705 Success
|
|
19
|
-
`));}catch(D){let L=ue(f,w);if(L.risk!=="safe"){let V=r.get(L.projectPath);if(V)try{await xt(V),console.log(l.yellow(" \u21A9 Rolled back snapshot after failed fix"));}catch(B){console.log(l.red(` \u274C Rollback failed: ${B instanceof Error?B.message:String(B)}`));}}console.log(l.red(` \u274C Failed: ${D instanceof Error?D.message:String(D)}
|
|
20
|
-
`));}}}try{let w=await bt(f.path);console.log(w.healthy?l.green(` \u2705 Post-fix verification passed for ${f.name}`):l.yellow(` \u26A0 Post-fix verification: ${w.issues} issue(s) remain for ${f.name}`));}catch(w){console.log(l.yellow(` \u26A0 Post-fix verification skipped: ${w instanceof Error?w.message:String(w)}`));}}console.log(l.bold.green(`
|
|
21
|
-
\u2705 Fix process completed!`));}async function Ht(e={}){let s=!e.workspace&&!e.project&&e.fix?await me(process.cwd()):null,a$1=e.workspace||!!s,t=!!e.project&&!a$1;if(e.json||console.log(l.bold.cyan(`
|
|
22
|
-
\u{1FA7A} RapidKit Health Check
|
|
23
|
-
`)),a$1){let r=s??await me(process.cwd());r||(a.error("No RapidKit workspace found in current directory or parents"),a.info('Run this command from within a workspace, or use "rapidkit doctor" for system check'),process.exit(1)),e.json||(s&&console.log(l.gray("\u2139\uFE0F Detected workspace context; enabling workspace checks for --fix")),console.log(l.bold(`Workspace: ${l.cyan(o.basename(r))}`)),console.log(l.gray(`Path: ${r}`)));let n=await be(r);if(e.json||(n.projectScanCached&&console.log(l.gray(`\u2139\uFE0F Reused cached project scan${n.projectScanCachePath?` (${o.basename(n.projectScanCachePath)})`:""}`)),n.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence saved: ${n.evidencePath}`))),e.json){let m={contract:oe(),workspace:{name:o.basename(r),path:r},cache:{projectScan:n.projectScanCached??false,projectScanPath:n.projectScanCachePath,evidencePath:n.evidencePath},healthScore:n.healthScore,system:{python:n.python,poetry:n.poetry,pipx:n.pipx,rapidkitCore:n.rapidkitCore,versions:{core:n.coreVersion,npm:n.npmVersion}},projects:n.projects.map(p=>({name:p.name,path:p.path,framework:p.framework,runtimeFamily:p.runtimeFamily,projectKind:p.projectKind,supportTier:p.supportTier,frameworkConfidence:p.frameworkConfidence,venvActive:p.venvActive,depsInstalled:p.depsInstalled,hasEnvFile:p.hasEnvFile,vulnerabilities:p.vulnerabilities,coreInstalled:p.coreInstalled,coreVersion:p.coreVersion,issues:p.issues,fixCommands:p.fixCommands,probes:p.probes})),summary:{totalProjects:n.projects.length,totalIssues:n.projects.reduce((p,h)=>p+h.issues.length,0),projectAdvisoryWarningProjects:pe(n.projects),projectAdvisoryWarnings:fe(n.projects),hasSystemErrors:[n.python,n.rapidkitCore].some(p=>p.status==="error"),scopeProvenance:n.scopeProvenance},driftDelta:n.driftDelta,scoreBreakdown:n.scoreBreakdown??[]};console.log(JSON.stringify(m,null,2));return}if(n.healthScore){let m=n.healthScore,p=Math.round(m.passed/m.total*100),h=p>=80?l.green:p>=50?l.yellow:l.red,f="\u2588".repeat(Math.floor(p/5))+"\u2591".repeat(20-Math.floor(p/5));console.log(l.bold(`
|
|
24
|
-
\u{1F4CA} Health Score:`)),console.log(` ${h(`${p}%`)} ${l.gray(f)}`),console.log(` ${l.green(`\u2705 ${m.passed} passed`)} ${l.gray("|")} ${l.yellow(`\u26A0\uFE0F ${m.warnings} warnings`)} ${l.gray("|")} ${l.red(`\u274C ${m.errors} errors`)}`);}if(console.log(l.bold(`
|
|
25
|
-
|
|
26
|
-
System Tools:
|
|
27
|
-
`)),P(n.python,"Python"),P(n.poetry,"Poetry"),P(n.pipx,"pipx"),P(n.go,"Go"),P(n.rapidkitCore,"RapidKit Core"),n.coreVersion&&n.npmVersion){let m=n.coreVersion.split(".")[1],p=n.npmVersion.split(".")[1];m!==p&&(console.log(l.yellow(`
|
|
28
|
-
\u26A0\uFE0F Version mismatch: Core ${n.coreVersion} / CLI ${n.npmVersion}`)),console.log(l.gray(" Consider updating to matching versions for best compatibility")));}n.projects.length>0?(console.log(l.bold(`
|
|
29
|
-
\u{1F4E6} Projects (${n.projects.length}):`)),n.projects.forEach(m=>je(m))):(console.log(l.bold(`
|
|
30
|
-
\u{1F4E6} Projects:`)),console.log(l.gray(" No RapidKit projects found in workspace")));let c=n.projects.reduce((m,p)=>m+p.issues.length,0),d=pe(n.projects),u=[n.python,n.rapidkitCore].some(m=>m.status==="error");if(u||c>0||d>0){let m=d>0?` and ${d} advisory warning project(s)`:"";if(console.log(l.bold.yellow(`
|
|
31
|
-
\u26A0\uFE0F Found ${c} project issue(s)${m}`)),u&&console.log(l.bold.red("\u274C System requirements not met")),e.fix){if(await ne(n.projects,true),!e.json){let p=await be(r,false),h=p.projects.reduce((k,w)=>k+w.issues.length,0),f=[p.python,p.rapidkitCore].some(k=>k.status==="error");f||h>0?(console.log(l.bold.yellow(`
|
|
32
|
-
\u26A0\uFE0F Post-fix verification found ${h} remaining issue(s)`)),f&&console.log(l.bold.red("\u274C System requirements still not met"))):console.log(l.bold.green(`
|
|
33
|
-
\u2705 Post-fix verification passed. Workspace is healthy.`)),p.projectScanCached&&console.log(l.gray(`\u2139\uFE0F Reused cached project scan${p.projectScanCachePath?` (${o.basename(p.projectScanCachePath)})`:""}`)),p.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence refreshed: ${p.evidencePath}`));}}else c>0&&await ne(n.projects,false);}else console.log(l.bold.green(`
|
|
34
|
-
\u2705 All checks passed! Workspace is healthy.`));}else if(t){let r=await ht(process.cwd());r||(a.error("No RapidKit project found in current directory or parents"),a.info('Run this command from within a project, or use "rapidkit doctor workspace" for workspace checks'),process.exit(1));let n=await kt(r),c=n.workspacePath?xe(n.workspacePath):null,d=xe(n.project.path);if(e.json){let v={contract:oe(),scope:"project",workspace:c?{name:o.basename(c),path:c}:null,project:{name:n.project.name,path:d,framework:n.project.framework,runtimeFamily:n.project.runtimeFamily,projectKind:n.project.projectKind,supportTier:n.project.supportTier,frameworkConfidence:n.project.frameworkConfidence,venvActive:n.project.venvActive,depsInstalled:n.project.depsInstalled,hasEnvFile:n.project.hasEnvFile,vulnerabilities:n.project.vulnerabilities,coreInstalled:n.project.coreInstalled,coreVersion:n.project.coreVersion,issues:n.project.issues,fixCommands:n.project.fixCommands,probes:n.project.probes},evidencePath:n.evidencePath,healthScore:n.healthScore,system:{python:n.python,poetry:n.poetry,pipx:n.pipx,go:n.go,rapidkitCore:n.rapidkitCore},summary:{totalProjects:1,totalIssues:n.project.issues.length,projectAdvisoryWarningProjects:Q(n.project)>0?1:0,projectAdvisoryWarnings:Q(n.project),hasSystemErrors:[n.python,n.rapidkitCore].some($=>$.status==="error"),scopeProvenance:n.scopeProvenance},driftDelta:n.driftDelta,scoreBreakdown:n.scoreBreakdown??[]};console.log(JSON.stringify(v,null,2));return}console.log(l.bold(`Project: ${l.cyan(o.basename(r))}`)),console.log(l.gray(`Path: ${r}`)),n.workspacePath&&console.log(l.gray(`Workspace: ${o.basename(n.workspacePath)}`)),n.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence saved: ${n.evidencePath}`));let u=n.healthScore,m=u.total>0?Math.round(u.passed/u.total*100):0,p=m>=80?l.green:m>=50?l.yellow:l.red,h="\u2588".repeat(Math.floor(m/5))+"\u2591".repeat(20-Math.floor(m/5));console.log(l.bold(`
|
|
35
|
-
\u{1F4CA} Health Score:`)),console.log(` ${p(`${m}%`)} ${l.gray(h)}`),console.log(` ${l.green(`\u2705 ${u.passed} passed`)} ${l.gray("|")} ${l.yellow(`\u26A0\uFE0F ${u.warnings} warnings`)} ${l.gray("|")} ${l.red(`\u274C ${u.errors} errors`)}`),console.log(l.bold(`
|
|
36
|
-
|
|
37
|
-
System Tools:
|
|
38
|
-
`)),P(n.python,"Python"),P(n.poetry,"Poetry"),P(n.pipx,"pipx"),P(n.go,"Go"),P(n.rapidkitCore,"RapidKit Core"),console.log(l.bold(`
|
|
39
|
-
\u{1F4E6} Project (1):`)),je(n.project);let f=[n.python,n.rapidkitCore].some(v=>v.status==="error"),k=n.project.issues.length,w=Q(n.project);if(f||k>0||w>0){let v=w>0?` and ${w} advisory warning(s)`:"";console.log(l.bold.yellow(`
|
|
40
|
-
\u26A0\uFE0F Found ${k} project issue(s)${v}`)),f&&console.log(l.bold.red("\u274C System requirements not met")),e.fix?await ne([n.project],true):k>0&&await ne([n.project],false);}else console.log(l.bold.green(`
|
|
41
|
-
\u2705 All checks passed! Project is healthy.`));}else {console.log(l.bold(`System Tools:
|
|
42
|
-
`));let r=await ge(),n=r.python,c=r.poetry,d=r.pipx,u=r.go,m=r.rapidkitCore;P(n,"Python"),P(c,"Poetry"),P(d,"pipx"),P(u,"Go"),P(m,"RapidKit Core"),[n,m].some(h=>h.status==="error")?(console.log(l.bold.red(`
|
|
43
|
-
\u274C Some required tools are missing`)),e.fix&&console.log(l.gray(`
|
|
44
|
-
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(l.gray(`
|
|
45
|
-
Tip: Run "rapidkit doctor workspace" for detailed project checks`))):(console.log(l.bold.green(`
|
|
46
|
-
\u2705 All required tools are installed!`)),e.fix&&console.log(l.gray(`
|
|
47
|
-
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(l.gray(`
|
|
48
|
-
Tip: Run "rapidkit doctor workspace" for detailed project checks`)));}console.log("");}export{Ht as runDoctor};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export{j as __test__,b as checkRapidkitCoreAvailable,h as getCachedCoreTopLevelCommands,g as getCoreTopLevelCommands,i as getModulesCatalog,c as resolveRapidkitPython,d as runCoreRapidkit,f as runCoreRapidkitCapture,e as runCoreRapidkitStreamed}from'./chunk-UOGFCKQ5.js';
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import x from'fs';import f from'path';import A from'chalk';import {execa}from'execa';var te={"python-fastapi":{runtime:"python",framework:"FastAPI",markers:["pyproject.toml","fastapi"],commands:{init:"python -m pip install -e .",test:"pytest",build:"python -m build",start:"uvicorn main:app --reload"},errorPatterns:{setup:["ModuleNotFoundError","No module named","pip: command not found"],"test-failure":["FAILED","ERROR","test session started"],dependency:["ImportError","missing.*dependency"],runtime:["TypeError","AttributeError","ValueError"],timeout:["timeout","Timeout","timed out"],unknown:[]},healthCheck:{stage:"start",type:"http",value:"http://localhost:8000/docs"},validation:{command:"python -m pip list | grep fastapi",error:"FastAPI not installed"}},"python-django":{runtime:"python",framework:"Django",markers:["manage.py","django"],commands:{init:"python manage.py migrate",test:"python manage.py test",build:"python manage.py collectstatic --noinput",start:"python manage.py runserver 0.0.0.0:8000"},errorPatterns:{setup:["ModuleNotFoundError","ProgrammingError.*migrate"],"test-failure":["FAILED","ERROR","Ran.*test"],dependency:["ImportError","missing.*dependency"],runtime:["DatabaseError","ImproperlyConfigured"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8e3},dependencies:["init"]},"node-nestjs":{runtime:"node",framework:"NestJS",markers:["package.json","@nestjs/core"],commands:{init:"npm install",test:"npm run test",build:"npm run build",start:"npm run start"},errorPatterns:{setup:["npm ERR!","ENOENT","not found"],"test-failure":["Tests.*failed","FAIL","fail.*test"],dependency:["Cannot find module","ERR_MODULE_NOT_FOUND"],runtime:["TypeError","Error: ","ReferenceError"],timeout:["timeout","TIMEOUT"],unknown:[]},healthCheck:{stage:"start",type:"port",value:3e3}},"node-express":{runtime:"node",framework:"Express",markers:["package.json","express"],commands:{init:"npm install",test:"npm run test",build:"npm run build",start:"npm start"},errorPatterns:{setup:["npm ERR!","ENOENT"],"test-failure":["failed","FAIL"],dependency:["Cannot find module"],runtime:["Error","TypeError"],timeout:["timeout"],unknown:[]}},"go-fiber":{runtime:"go",framework:"Fiber",markers:["go.mod","fiber"],commands:{init:"go mod download && go mod tidy",test:"go test ./...",build:"go build -o app .",start:"./app"},errorPatterns:{setup:["go: .*not found","cannot find","go mod tidy"],"test-failure":["FAIL","--- FAIL"],dependency:["missing.*module"],runtime:["panic","fatal","Error"],timeout:["timeout","context deadline"],unknown:[]},dependencies:["init"]},"go-gin":{runtime:"go",framework:"Gin",markers:["go.mod","gin-gonic"],commands:{init:"go mod download && go mod tidy",test:"go test ./...",build:"go build -o app .",start:"./app"},errorPatterns:{setup:["go: .*not found"],"test-failure":["FAIL"],dependency:["missing.*module"],runtime:["panic"],timeout:["timeout"],unknown:[]}},"java-springboot":{runtime:"java",framework:"Spring Boot",markers:["pom.xml","build.gradle","spring-boot"],commands:{init:"mvn dependency:go-offline",test:"mvn test",build:"mvn package -DskipTests",start:"mvn spring-boot:run"},errorPatterns:{setup:["\\[ERROR\\]","BUILD FAILURE","missing dependencies"],"test-failure":["\\[ERROR\\] Tests run:","BUILD FAILURE"],dependency:["missing.*dependency"],runtime:["Exception","Error","NullPointerException"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8080}},"php-laravel":{runtime:"php",framework:"Laravel",markers:["composer.json","artisan","app/Models"],commands:{init:"composer install && php artisan migrate:fresh --seed",test:"php artisan test",build:"php artisan config:cache && php artisan route:cache && php artisan view:cache",start:"php artisan serve --host=0.0.0.0 --port=8000"},errorPatterns:{setup:["Composer.*lock","Fatal error","Class.*not found"],"test-failure":["FAILED","Tests.*failed"],dependency:["Class.*not found","require.*failed"],runtime:["Fatal error","Exception","Error"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8e3},dependencies:["init"]},"php-symfony":{runtime:"php",framework:"Symfony",markers:["composer.json","symfony.lock","bin/console"],commands:{init:"composer install && php bin/console doctrine:database:create",test:"php bin/phpunit",build:"php bin/console cache:clear --env=prod",start:"symfony serve --no-tls"},errorPatterns:{setup:["Composer.*error","Fatal error"],"test-failure":["FAILED","failure"],dependency:["Class.*not found"],runtime:["Fatal error","Exception"],timeout:["timeout"],unknown:[]},dependencies:["init"]},"rust-actix":{runtime:"rust",framework:"Actix-web",markers:["Cargo.toml","actix"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find","failed.*download"],"test-failure":["test result:","FAILED"],dependency:["can.t find.*crate"],runtime:["error\\[E","thread.*panicked"],timeout:["timeout"],unknown:[]},validation:{command:"cargo --version",error:"Rust/Cargo not installed"}},"rust-axum":{runtime:"rust",framework:"Axum",markers:["Cargo.toml","axum"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find"],"test-failure":["test result:","FAILED"],dependency:["can.t find.*crate"],runtime:["error\\[E"],timeout:["timeout"],unknown:[]}},"rust-rocket":{runtime:"rust",framework:"Rocket",markers:["Cargo.toml","rocket"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find"],"test-failure":["FAILED"],dependency:["can.t find"],runtime:["error\\[E"],timeout:["timeout"],unknown:[]}},"dotnet-aspnetcore":{runtime:"dotnet",framework:"ASP.NET Core",markers:[".csproj",".sln","Program.cs"],commands:{init:"dotnet restore",test:"dotnet test",build:"dotnet build -c Release",start:"dotnet run"},errorPatterns:{setup:["error CS","CSPROJ.*not found","NuGet.*restore"],"test-failure":["Failed:.*test","FAILED"],dependency:["error NU1101"],runtime:["error CS","Exception"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:5e3}},"elixir-phoenix":{runtime:"elixir",framework:"Phoenix",markers:["mix.exs","phoenix"],commands:{init:"mix setup",test:"mix test",build:"mix compile --all-warnings",start:"mix phx.server"},errorPatterns:{setup:["\\*\\* \\(.*Error\\)","Mix.InstallError"],"test-failure":["\\d+\\sfailed","FAILED"],dependency:["dependencies are not available"],runtime:["\\*\\* \\(","RuntimeError"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:4e3},dependencies:["init"]},"ruby-rails":{runtime:"ruby",framework:"Rails",markers:["Gemfile","config/application.rb","bin/rails"],commands:{init:"bundle install && rails db:prepare",test:"rails test",build:"rails assets:precompile",start:"rails server --binding=0.0.0.0 --port=3000"},errorPatterns:{setup:["Bundler::.*Error","Gem::.*Error"],"test-failure":["failures,","error,","FAILED"],dependency:["Could not find.*gem"],runtime:["Error","Exception","NoMethodError"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:3e3},dependencies:["init"]},"ruby-sinatra":{runtime:"ruby",framework:"Sinatra",markers:["Gemfile","app.rb","sinatra"],commands:{init:"bundle install",test:"rspec",build:`echo "Sinatra apps don't require build"`,start:"ruby app.rb"},errorPatterns:{setup:["Bundler.*Error","Gem.*Error"],"test-failure":["failure","FAILED"],dependency:["Could not find.*gem"],runtime:["Error","NoMethodError"],timeout:["timeout"],unknown:[]}}},re={init:{python:["pip install -e .","poetry install","pip install -r requirements.txt"],node:["npm install","pnpm install","yarn install"],go:["go mod download && go mod tidy","go get ./..."],java:["mvn dependency:go-offline","gradle dependencies"],php:["composer install"],rust:["cargo fetch"],dotnet:["dotnet restore"],elixir:["mix deps.get"],ruby:["bundle install"],"jvm-generic":["mvn dependency:go-offline","gradle dependencies"],unknown:[]},test:{python:["pytest","python -m unittest","python -m pytest"],node:["npm test","npm run test"],go:["go test ./...","make test"],java:["mvn test","gradle test"],php:["php artisan test","phpunit","pest"],rust:["cargo test"],dotnet:["dotnet test"],elixir:["mix test"],ruby:["rspec","ruby -m minitest"],"jvm-generic":["mvn test","gradle test"],unknown:[]},build:{python:["python -m build","python setup.py build"],node:["npm run build"],go:["go build -o app .","go build ./..."],java:["mvn package -DskipTests","gradle build -x test"],php:['echo "PHP build: typically no build step"'],rust:["cargo build --release"],dotnet:["dotnet build -c Release"],elixir:["mix compile"],ruby:["gem build *.gemspec"],"jvm-generic":["mvn package -DskipTests","gradle build"],unknown:[]},start:{python:["python app.py","python main.py","uvicorn main:app --reload"],node:["npm start","node index.js","node src/index.js"],go:["./app","go run main.go","go run ./..."],java:["mvn spring-boot:run","gradle bootRun","java -jar target/*.jar"],php:["php -S 0.0.0.0:8000","php artisan serve"],rust:["cargo run --release","./target/release/app"],dotnet:["dotnet run"],elixir:["mix phx.server","iex -S mix"],ruby:["rails server","ruby app.rb","bundle exec puma"],"jvm-generic":["java -jar *.jar","gradle run"],unknown:[]}};function H(e,t,n){if(t){let o=`${e}-${t.toLowerCase().replace(/\s+/g,"-")}`,i=te[o];if(i&&i.commands[n])return i.commands[n]}let r=re[n]?.[e]??[];return r.length>0?r[0]:void 0}function ne(e){let t=[{file:"go.mod",runtime:"go"},{file:"Cargo.toml",runtime:"rust"},{file:"pom.xml",runtime:"java"},{file:"build.gradle",runtime:"java"},{file:"mix.exs",runtime:"elixir"},{file:"composer.json",runtime:"php"},{file:".csproj",runtime:"dotnet"},{file:".sln",runtime:"dotnet"},{file:"package.json",runtime:"node"},{file:"Gemfile",runtime:"ruby"},{file:"pyproject.toml",runtime:"python"},{file:"setup.py",runtime:"python"},{file:"requirements.txt",runtime:"python"}],n=[];for(let{file:r,runtime:o}of t)x.existsSync(f.join(e,r))&&(n.includes(o)||n.push(o));return {primary:n.length>0?n[0]:"unknown",secondary:n.slice(1)}}function V(e){return ne(e).primary}function B(e,t){if(!e)return "unknown";t||(t={setup:["ModuleNotFoundError","npm ERR!","error:","not found"],"test-failure":["FAILED","FAIL","failed"],dependency:["cannot find module","import.*error"],runtime:["Exception","Error:","panic","TypeError"],timeout:["timeout","Timeout","deadline exceeded"],unknown:[]});for(let[n,r]of Object.entries(t))for(let o of r)if(new RegExp(o,"i").test(e))return n;return "unknown"}async function J(e){let t=e.split(/[&|;]\s*/)[0].trim().split(/\s+/)[0];if(["echo","cd","pwd","test","true","false","exit"].includes(t))return {valid:true};try{let r=process.platform==="win32"?"where":"which";if((await execa(r,[t],{reject:false})).exitCode===0)return {valid:true}}catch{}return {valid:false,reason:`Command '${t}' not found or not executable`}}function U(e,t,n){return t?n&&typeof t[n]=="string"?t[n]:typeof t.default=="string"?t.default:e:e}var oe=new Set(["init","test","build","start"]),se=new Set([".git","node_modules",".rapidkit",".venv","dist","build","coverage","htmlcov"]);async function T(e){try{return await x.promises.access(e,x.constants.F_OK),true}catch{return false}}async function ae(e){let t=await x.promises.readFile(e,"utf-8");return JSON.parse(t)}async function ie(e,t){await x.promises.mkdir(f.dirname(e),{recursive:true}),await x.promises.writeFile(e,`${JSON.stringify(t,null,2)}
|
|
2
|
-
`,"utf-8");}function I(e){return e.replace(/\\/g,"/")}async function ue(e){let t=new Set;async function n(r){let o;try{o=await x.promises.readdir(r,{withFileTypes:true});}catch{return}if(await T(f.join(r,".rapidkit","context.json"))||await T(f.join(r,".rapidkit","project.json"))){t.add(f.resolve(r));return}for(let i of o){if(!i.isDirectory()||se.has(i.name))continue;let s=f.join(r,i.name);await n(s);}}return await n(f.resolve(e)),[...t].sort((r,o)=>r.localeCompare(o))}async function ce(e,t,n){let r=await execa("git",["diff","--name-only",`${n}...HEAD`],{cwd:e,reject:false});if(r.exitCode!==0)return new Set(t);let o=r.stdout.split(/\r?\n/).map(s=>s.trim()).filter(s=>s.length>0).map(s=>I(s));if(o.length===0)return new Set;let i=new Set;for(let s of t){let m=I(f.relative(e,s));if(!m||m===".")continue;let u=`${m}/`;o.some(g=>g===m||g.startsWith(u))&&i.add(s);}return i}async function de(e,t,n){let r=f.join(e,".rapidkit","workspace-dependency-graph.json");if(!await T(r))return {expanded:n,graphStatus:"missing",expansionDepth:0};let o;try{o=await ae(r);}catch{return {expanded:n,graphStatus:"invalid",expansionDepth:0}}let i=new Set(t.map(p=>f.resolve(p))),s=new Map;if(!o||typeof o!="object"||Array.isArray(o))return {expanded:n,graphStatus:"invalid",expansionDepth:0};let m=Array.isArray(o.projects)?o.projects:[];for(let p of m){if(!p||typeof p!="object"||Array.isArray(p))continue;let h=p,w=typeof h.path=="string"?h.path:"",d=f.resolve(e,w);if(!i.has(d))continue;let y=Array.isArray(h.dependsOn)?h.dependsOn.filter(v=>typeof v=="string"):[];for(let v of y){let C=f.resolve(e,v);i.has(C)&&(s.has(C)||s.set(C,new Set),s.get(C)?.add(d));}}let u=new Set(n),g=[...u],R=0;for(;g.length>0;){let p=g.shift();if(!p)continue;let h=s.get(p);if(h)for(let w of h)u.has(w)||(u.add(w),g.push(w),R+=1);}return {expanded:u,graphStatus:"loaded",expansionDepth:R}}async function le(e,t){if(typeof t=="boolean")return t;let n=f.join(e,".rapidkit","policies.yml");if(!await T(n))return true;let r="";try{r=await x.promises.readFile(n,"utf-8");}catch{return true}let o=r.match(/^[\t ]*rules\.enforce_workspace_run_gates:\s*(true|false)\s*(?:#.*)?$/m);return o?o[1]==="true":true}async function O(e,t){let n=process.argv[1];if(!n)return {exitCode:1,stdout:"",stderr:"RapidKit entrypoint is unavailable for nested workspace-run execution."};let r=await execa(process.execPath,[n,...e],{cwd:t,reject:false,env:{...process.env,RAPIDKIT_WORKSPACE_RUN_CHILD:"1"}});return {exitCode:Number(r.exitCode??1),stdout:r.stdout,stderr:r.stderr}}function me(e){return e==="node"||e==="go"||e==="java"||e==="python"}function pe(){return process.env.VITEST==="true"||process.env.VITEST==="1"||process.env.NODE_ENV==="test"}async function fe(e){let t=process.cwd();try{process.chdir(e);let{handleInitCommand:n}=await import('./index.js');return {exitCode:await n(["init"]),stdout:"",stderr:""}}finally{process.chdir(t);}}async function ge(e){let t=f.join(e,".rapidkit","context.json");if(x.existsSync(t))try{let r=JSON.parse(x.readFileSync(t,"utf-8"));if(typeof r.runtime=="string"){let o={};if(r.commands&&typeof r.commands=="object")for(let[i,s]of Object.entries(r.commands))typeof s=="string"&&(o[i]=s);return {runtime:r.runtime,framework:typeof r.framework=="string"?r.framework:void 0,commandOverrides:Object.keys(o).length>0?o:void 0,environment:typeof r.environment=="string"?r.environment:void 0}}}catch{}return {runtime:V(e),framework:void 0}}async function he(e,t,n,r,o,i){let s=!o?.[t]&&me(n),m;if(o&&o[t]?m=o[t]:s?m=`rapidkit ${t}`:m=H(n,r,t),!m)return {exitCode:127,command:`<stage not supported for ${n}>`,message:`No stage command found for runtime '${n}' and framework '${r||"unknown"}'`,errorCategory:"runtime"};let u=U(m,o,i);if(!u)return {exitCode:127,command:m,message:"Failed to resolve stage command",errorCategory:"runtime"};if(!s){let d=await J(u);if(!d.valid)return {exitCode:127,command:u,message:d.reason||"Command not available",errorCategory:"setup"}}let g=0,R="",p="",h;try{let d=s?t==="init"&&pe()?await fe(e):await O([t],e):await execa(u,[],{cwd:e,reject:false,shell:true});if(g=Number(d.exitCode??0),R=d.stdout,p=d.stderr,g!==0){let y=`${R}
|
|
3
|
-
${p}`;h=B(y);}}catch(d){return {exitCode:1,command:u,message:d instanceof Error?d.message:"Command execution failed",errorCategory:"runtime"}}return {exitCode:g,command:u,errorCategory:h,healthStatus:void 0,message:g!==0?`Stage failed with exit code ${g}`:void 0}}function K(e){try{return JSON.parse(e)}catch{return null}}async function ye(e){let t=[],n=await O(["doctor","workspace","--json"],e);if(n.exitCode!==0)t.push({gate:"doctor-workspace",status:"fail",summary:"doctor workspace command failed"});else {let i=K(n.stdout)?.healthScore,s=Number(i?.errors??0);Number.isFinite(s)&&s>0?t.push({gate:"doctor-workspace",status:"fail",summary:`doctor workspace reports ${s} error(s)`}):t.push({gate:"doctor-workspace",status:"pass",summary:"doctor workspace passed"});}let r=await O(["readiness","--json"],e);if(r.exitCode!==0)t.push({gate:"readiness",status:"fail",summary:"readiness command failed"});else {let o=K(r.stdout),i=String(o?.overallStatus??"").toLowerCase();i==="fail"?t.push({gate:"readiness",status:"fail",summary:"readiness overall status is fail"}):i==="warn"?t.push({gate:"readiness",status:"warn",summary:"readiness overall status is warn"}):t.push({gate:"readiness",status:"pass",summary:"readiness overall status is pass"});}return t}function ke(e){return oe.has(e)}function we(e,t){let n=Math.max(1,Math.min(4,t)),r=Number(e??n);return Number.isFinite(r)?Math.max(1,Math.min(16,Math.trunc(r))):n}async function Ae(e){if(!ke(e.stage))throw new Error(`Unsupported workspace run stage: ${e.stage}`);let t=Date.now(),n=f.resolve(e.workspacePath),r=await ue(n),o=e.affected===true,i=e.blastRadius===true,s=e.since?.trim()||"HEAD~1",m=o?await ce(n,r,s):new Set(r),u,g="not-applicable",R=0,p="all";if(o&&i){let a=await de(n,r,m);u=a.expanded,g=a.graphStatus,R=a.expansionDepth,p="affected+blast-radius";}else o?(u=m,p="affected"):(u=m,p="all");let h=e.stage==="init"?false:await le(n,e.enforceGates),w=h?await ye(n):[{gate:"doctor-workspace",status:"skipped",summary:"workspace run gates disabled"},{gate:"readiness",status:"skipped",summary:"workspace run gates disabled"}],d=w.find(a=>a.status==="fail"),y=r.filter(a=>u.has(a)),v=e.continueOnError===true,C=e.parallel===true,N=we(e.maxWorkers,y.length),E=new Map;for(let a of r)E.set(a,{path:a,relativePath:I(f.relative(n,a)),selected:u.has(a),affected:u.has(a),status:(u.has(a),"skipped"),exitCode:null,durationMs:0,reason:u.has(a)?void 0:"not affected",framework:void 0,runtimeDetected:void 0,executionCommand:void 0});if(d)for(let a of y){let l=E.get(a);l&&(l.status="skipped",l.reason=`blocked by ${d.gate}`);}else {let a=async l=>{let c=E.get(l);if(!c)return;c.selected=true,c.affected=true;let P=Date.now(),{runtime:b,framework:k,commandOverrides:S,environment:z}=await ge(l);c.runtimeDetected=b,c.framework=k;let j=await he(l,e.stage,b,k,S,z);c.executionCommand=j.command,c.errorCategory=j.errorCategory,c.healthStatus=j.healthStatus,c.durationMs=Date.now()-P,c.exitCode=j.exitCode,j.exitCode===0?(c.status="passed",c.reason=void 0):(c.status="failed",c.reason=j.message||"stage command failed",c.errorMessage=j.message);};if(C&&y.length>1){let l=0,c=false,P=new Array(N).fill(null).map(async()=>{for(;l<y.length;){if(c&&!v)return;let b=l;l+=1;let k=y[b];await a(k),E.get(k)?.status==="failed"&&(c=true);}});if(await Promise.all(P),!v&&c){let b=false;for(let k of y){let S=E.get(k);if(S){if(S.status==="failed"){b=true;continue}b&&S.status==="skipped"&&(S.reason=S.reason||"stopped after failure");}}}}else for(let l of y){await a(l);let c=E.get(l);if(!v&&c?.status==="failed"){let P=y.slice(y.indexOf(l)+1);for(let b of P){let k=E.get(b);k&&(k.status="skipped",k.reason="stopped after failure");}break}}}let F=[];for(let a of r){let l=E.get(a);l&&F.push(l);}let $=F.filter(a=>a.status==="passed").length,D=F.filter(a=>a.status==="failed").length,W=F.filter(a=>a.status==="skipped").length,L=e.strict===true,q=D>0||L&&w.some(a=>a.status!=="pass")?1:0,G={schemaVersion:"1.0",workspacePath:n,stage:e.stage,generatedAt:new Date().toISOString(),durationMs:Date.now()-t,options:{affected:o,blastRadius:i,since:o?s:null,parallel:C,maxWorkers:N,continueOnError:v,strict:L,enforceGates:h},selection:{mode:p,since:o?s:null,graphStatus:g,expansionDepth:R},gates:{enforced:h,results:w,blocked:!!d,blockingGate:d?.gate},summary:{projectCount:r.length,selectedCount:y.length,passed:$,failed:D,skipped:W,exitCode:q},projects:F},_=f.join(n,".rapidkit","reports","workspace-run-last.json");return await ie(_,G),e.json||(d&&(console.log(A.red(`\u274C Workspace run blocked by ${d.gate}`)),console.log(A.gray(` ${d.summary}`))),console.log(A.cyan(`Workspace run (${e.stage}) => passed: ${$}, failed: ${D}, skipped: ${W}`)),console.log(A.gray(`Report: ${_}`))),G}export{Ae as runWorkspaceStage};
|