rapidkit 0.41.0 → 0.41.2
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 +88 -11
- package/contracts/extension-cli-compatibility.v1.json +1 -1
- package/contracts/runtime-command-surface.v1.json +3 -1
- package/contracts/workspace-intelligence/agent-action-outcome.v1.json +17 -1
- package/contracts/workspace-intelligence/studio-blocker-handoff.v1.json +24 -0
- package/contracts/workspace-intelligence/workspace-dependency-graph.v1.json +61 -1
- package/dist/analyze-QYHMGLSG.js +1 -0
- package/dist/autopilot-release-YDEUKRW6.js +1 -0
- package/dist/{chunk-WA6JYVJM.js → chunk-33LR2QEM.js} +1 -1
- package/dist/{chunk-DMUEGR36.js → chunk-3PTJID76.js} +1 -1
- package/dist/chunk-46AGNYI7.js +50 -0
- package/dist/chunk-AQ4XZZC6.js +1 -0
- package/dist/{chunk-MGUJWRZA.js → chunk-BFEBZABL.js} +3 -3
- package/dist/chunk-DWXRVGOY.js +2 -0
- package/dist/chunk-E5ZVQL3C.js +13 -0
- package/dist/chunk-ELU3G6DQ.js +9 -0
- package/dist/chunk-EN6YCX36.js +1 -0
- package/dist/chunk-FMBSON6H.js +33 -0
- package/dist/chunk-GBJBQ43T.js +1 -0
- package/dist/chunk-HYAT2EG7.js +1 -0
- package/dist/{chunk-FPUNOIAR.js → chunk-ITJ6RKUW.js} +3 -3
- package/dist/{chunk-Y2SCTWL4.js → chunk-JNXT6KJV.js} +2 -2
- package/dist/{chunk-XOVB2ZP5.js → chunk-JU3VNLTY.js} +1 -1
- package/dist/{chunk-44GSDNPQ.js → chunk-KIUSCFHF.js} +1 -1
- package/dist/{chunk-KTQZUWAM.js → chunk-RSYUNEH7.js} +13 -13
- package/dist/chunk-VDTAPIHB.js +2 -0
- package/dist/chunk-WCICO7ZB.js +13 -0
- package/dist/chunk-WRMCPKGA.js +1 -0
- package/dist/{chunk-73IS6RIM.js → chunk-ZPXMZCYG.js} +1 -1
- package/dist/{create-UGXMC4CT.js → create-RNP5ACQL.js} +1 -1
- package/dist/demo-kit-N5U3NGAE.js +149 -0
- package/dist/{doctor-LCKG5S76.js → doctor-XM6QDTDC.js} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +118 -117
- package/dist/{pipeline-MKNYPNGD.js → pipeline-YD2DO7XY.js} +1 -1
- package/dist/platform-capabilities-TSLK667K.js +1 -0
- package/dist/{pythonRapidkitExec-MNWRC4F2.js → pythonRapidkitExec-SGKW76XM.js} +1 -1
- package/dist/{workspace-FDMJD5XI.js → workspace-E554C5SM.js} +1 -1
- package/dist/{workspace-agent-sync-WJIZCZX5.js → workspace-agent-sync-BHE2V4KS.js} +1 -1
- package/dist/{workspace-context-RYOQYGOP.js → workspace-context-VJTXW3K4.js} +1 -1
- package/dist/{workspace-contract-ITFCJCHI.js → workspace-contract-OO4GMENV.js} +1 -1
- package/dist/workspace-explain-XJ22ZXJY.js +1 -0
- package/dist/workspace-explain-contract-24RQ7KIW.js +1 -0
- package/dist/{workspace-foundation-SILFUKL5.js → workspace-foundation-LISDH53T.js} +1 -1
- package/dist/{workspace-intelligence-YOZQBAK5.js → workspace-intelligence-EC63CRVF.js} +1 -1
- package/dist/workspace-mcp-serve-KOM2V35Q.js +3 -0
- package/dist/{workspace-model-VMMLHJWI.js → workspace-model-YL7W3573.js} +1 -1
- package/dist/workspace-registry-summary-X5WRUU3T.js +1 -0
- package/dist/workspace-run-F5FADRY5.js +1 -0
- package/dist/workspace-verify-IAUHP6Y6.js +1 -0
- package/dist/{workspace-watch-3MEZRSEE.js → workspace-watch-H2AETGFI.js} +1 -1
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/OPEN_SOURCE_USER_SCENARIOS.md +1 -1
- package/docs/README.md +1 -1
- package/docs/commands-reference.md +10 -2
- package/docs/contracts/ARTIFACT_CATALOG.md +1 -1
- package/docs/contracts/README.md +11 -0
- package/package.json +7 -3
- package/scripts/enterprise-package-smoke.mjs +433 -0
- package/scripts/prepack-enterprise.mjs +40 -0
- package/templates/generator.js +175 -0
- package/templates/kits/fastapi-ddd/README.md.j2 +122 -0
- package/templates/kits/fastapi-ddd/common/env.example.j2 +10 -0
- package/templates/kits/fastapi-ddd/env.example.j2 +1 -0
- package/templates/kits/fastapi-ddd/pyproject.toml.j2 +64 -0
- package/templates/kits/fastapi-ddd/src/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/app/__init__.py.j2 +11 -0
- package/templates/kits/fastapi-ddd/src/app/application/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/application/interfaces.py.j2 +43 -0
- package/templates/kits/fastapi-ddd/src/app/application/use_cases/__init__.py.j2 +6 -0
- package/templates/kits/fastapi-ddd/src/app/application/use_cases/health.py.j2 +14 -0
- package/templates/kits/fastapi-ddd/src/app/application/use_cases/notes.py.j2 +24 -0
- package/templates/kits/fastapi-ddd/src/app/config/__init__.py.j2 +16 -0
- package/templates/kits/fastapi-ddd/src/app/domain/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/app/domain/models/__init__.py.j2 +6 -0
- package/templates/kits/fastapi-ddd/src/app/domain/models/health.py.j2 +16 -0
- package/templates/kits/fastapi-ddd/src/app/domain/models/note.py.j2 +27 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/repositories/__init__.py.j2 +6 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/repositories/health.py.j2 +17 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/repositories/notes.py.j2 +28 -0
- package/templates/kits/fastapi-ddd/src/app/main.py.j2 +61 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/dependencies/__init__.py.j2 +19 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/router.py.j2 +10 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/routes/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/routes/health.py.j2 +27 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/routes/notes.py.j2 +50 -0
- package/templates/kits/fastapi-ddd/src/app/shared/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/shared/result.py.j2 +28 -0
- package/templates/kits/fastapi-ddd/src/cli.py.j2 +167 -0
- package/templates/kits/fastapi-ddd/src/main.py.j2 +35 -0
- package/templates/kits/fastapi-ddd/src/modules/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/routing/__init__.py.j2 +13 -0
- package/templates/kits/fastapi-ddd/src/routing/health.py.j2 +7 -0
- package/templates/kits/fastapi-ddd/src/routing/notes.py.j2 +7 -0
- package/templates/kits/fastapi-ddd/tests/__init__.py.j2 +1 -0
- package/templates/kits/fastapi-ddd/tests/test_app_factory.py.j2 +22 -0
- package/templates/kits/fastapi-ddd/tests/test_health.py.j2 +17 -0
- package/templates/kits/fastapi-ddd/tests/test_notes.py.j2 +27 -0
- package/templates/kits/fastapi-standard/README.md.j2 +145 -0
- package/templates/kits/fastapi-standard/common/env.example.j2 +10 -0
- package/templates/kits/fastapi-standard/env.example.j2 +1 -0
- package/templates/kits/fastapi-standard/pyproject.toml.j2 +64 -0
- package/templates/kits/fastapi-standard/src/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-standard/src/cli.py.j2 +168 -0
- package/templates/kits/fastapi-standard/src/main.py.j2 +66 -0
- package/templates/kits/fastapi-standard/src/modules/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-standard/src/routing/__init__.py.j2 +16 -0
- package/templates/kits/fastapi-standard/src/routing/examples.py.j2 +71 -0
- package/templates/kits/fastapi-standard/src/routing/health.py.j2 +22 -0
- package/templates/kits/fastapi-standard/tests/__init__.py.j2 +1 -0
- package/templates/kits/fastapi-standard/tests/test_examples.py.j2 +29 -0
- package/templates/kits/fastapi-standard/tests/test_health.py.j2 +17 -0
- package/templates/kits/nestjs-standard/Dockerfile.j2 +41 -0
- package/templates/kits/nestjs-standard/README.md.j2 +139 -0
- package/templates/kits/nestjs-standard/docker-compose.yml.j2 +94 -0
- package/templates/kits/nestjs-standard/docs/README.md.j2 +15 -0
- package/templates/kits/nestjs-standard/env.example.j2 +18 -0
- package/templates/kits/nestjs-standard/eslint.config.cjs.j2 +9 -0
- package/templates/kits/nestjs-standard/jest.config.ts.j2 +22 -0
- package/templates/kits/nestjs-standard/nest-cli.json.j2 +10 -0
- package/templates/kits/nestjs-standard/package.json.j2 +101 -0
- package/templates/kits/nestjs-standard/src/app.controller.ts.j2 +14 -0
- package/templates/kits/nestjs-standard/src/app.module.ts.j2 +26 -0
- package/templates/kits/nestjs-standard/src/app.service.ts.j2 +16 -0
- package/templates/kits/nestjs-standard/src/auth/auth.controller.ts.j2 +20 -0
- package/templates/kits/nestjs-standard/src/auth/auth.module.ts.j2 +13 -0
- package/templates/kits/nestjs-standard/src/auth/auth.service.ts.j2 +6 -0
- package/templates/kits/nestjs-standard/src/auth/entities/token.entity.ts.j2 +3 -0
- package/templates/kits/nestjs-standard/src/auth/entities/user.entity.ts.j2 +3 -0
- package/templates/kits/nestjs-standard/src/auth/entities/webauthn.entity.ts.j2 +3 -0
- package/templates/kits/nestjs-standard/src/config/configuration.ts.j2 +85 -0
- package/templates/kits/nestjs-standard/src/config/index.ts.j2 +2 -0
- package/templates/kits/nestjs-standard/src/config/validation.ts.j2 +21 -0
- package/templates/kits/nestjs-standard/src/examples/dto/create-note.dto.ts.j2 +11 -0
- package/templates/kits/nestjs-standard/src/examples/examples.controller.ts.j2 +24 -0
- package/templates/kits/nestjs-standard/src/examples/examples.module.ts.j2 +10 -0
- package/templates/kits/nestjs-standard/src/examples/examples.service.ts.j2 +33 -0
- package/templates/kits/nestjs-standard/src/main.ts.j2 +53 -0
- package/templates/kits/nestjs-standard/src/modules/index.ts.j2 +25 -0
- package/templates/kits/nestjs-standard/test/app.controller.spec.ts.j2 +24 -0
- package/templates/kits/nestjs-standard/test/app.e2e-spec.ts.j2 +60 -0
- package/templates/kits/nestjs-standard/test/examples.controller.spec.ts.j2 +28 -0
- package/templates/kits/nestjs-standard/test/jest-e2e.json.j2 +15 -0
- package/templates/kits/nestjs-standard/tsconfig.build.json.j2 +12 -0
- package/templates/kits/nestjs-standard/tsconfig.json.j2 +26 -0
- package/dist/analyze-JVMUCQ22.js +0 -1
- package/dist/autopilot-release-GM5ALPWO.js +0 -1
- package/dist/chunk-424B73UF.js +0 -1
- package/dist/chunk-56RL5OB6.js +0 -2
- package/dist/chunk-AO6PG3K2.js +0 -9
- package/dist/chunk-AT3EQ2S7.js +0 -2
- package/dist/chunk-FVCZGUVX.js +0 -1
- package/dist/chunk-GX7UU7LL.js +0 -33
- package/dist/chunk-P5ODFWB2.js +0 -13
- package/dist/chunk-QN2LPLHO.js +0 -1
- package/dist/chunk-RIZCWYRR.js +0 -1
- package/dist/chunk-YOQ2546V.js +0 -50
- package/dist/chunk-Z5LKRG57.js +0 -1
- package/dist/chunk-ZQRFVFKK.js +0 -13
- package/dist/demo-kit-2VI4H6OJ.js +0 -141
- package/dist/workspace-explain-VKSUKP3O.js +0 -1
- package/dist/workspace-explain-contract-CLHQ3XEH.js +0 -1
- package/dist/workspace-mcp-serve-OOLITFCK.js +0 -3
- package/dist/workspace-registry-summary-ZXGKL2NT.js +0 -1
- package/dist/workspace-run-IHB2TPMD.js +0 -1
- package/dist/workspace-verify-3CAKAZIL.js +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {f as f$1,e}from'./chunk-PCXSTKZ5.js';import {b}from'./chunk-CDCYRBAY.js';import {c as c$1,a as a$2,b as b$1}from'./chunk-NFUXULIF.js';import {q}from'./chunk-YBS2HGO3.js';import {i,d,b as b$3,a as a$4}from'./chunk-UZW5QFRW.js';import {f}from'./chunk-OLDPVVSV.js';import {c,l as l$1,i as i$1,b as b$2,q as q$1,m,o}from'./chunk-WRMCPKGA.js';import {a as a$3}from'./chunk-2FIX2MDC.js';import {a as a$1}from'./chunk-HHJAANUC.js';import l from'chalk';import {execa}from'execa';import a from'fs-extra';import r from'path';var Ct=[".eslintrc.js",".eslintrc.cjs",".eslintrc.json",".eslintrc.yaml",".eslintrc.yml","eslint.config.js","eslint.config.mjs","eslint.config.cjs"],Et=["tests","test","src/test","__tests__","e2e","playwright","cypress"],Pt=["vitest.config.ts","vitest.config.js","vitest.config.mjs","jest.config.js","jest.config.ts","jest.config.mjs","playwright.config.ts","playwright.config.js","cypress.config.js","cypress.config.ts"],St=["src","app","pages"],Rt=["dev","build","test","lint"];function Xe(e){let n=e?.scripts;if(!n||typeof n!="object"||Array.isArray(n))return {};let i={};for(let[t,c]of Object.entries(n))typeof c=="string"&&c.trim().length>0&&(i[t]=c);return i}async function Ye(e,n){for(let c of Ct)if(await a.pathExists(r.join(e,c)))return true;let i=n??(await a.pathExists(r.join(e,"package.json"))?await a.readJson(r.join(e,"package.json")):null);if(!i)return false;if(i.eslintConfig)return true;let t={...i.dependencies??{},...i.devDependencies??{}};return !!(t.eslint||t["@eslint/js"]||t["@eslint/eslintrc"])}async function Ze(e,n){for(let c of Et)if(await a.pathExists(r.join(e,c)))return true;for(let c of Pt)if(await a.pathExists(r.join(e,c)))return true;let i=Xe(n);if(i.test||i["test:unit"]||i["test:e2e"]||i["test:ci"]||i["test:watch"])return true;let t={...n?.dependencies??{},...n?.devDependencies??{}};return t.vitest||t.jest||t["@playwright/test"]||t.cypress?true:await Ft(e)}async function Ft(e){let n=["src","app","pages","components"],i=/\.(test|spec)\.(tsx?|jsx?|vue|svelte)$/i,c=new Set(["node_modules",".git","dist","build",".next","coverage",".turbo"]);for(let o of n){let s=r.join(e,o);if(!await a.pathExists(s))continue;let d=[{dir:s,depth:0}];for(;d.length>0;){let u=d.shift();if(!u)break;let m=[];try{m=await a.readdir(u.dir);}catch{continue}for(let p of m){let f=r.join(u.dir,p);if(i.test(p))return true;if(!(u.depth>=3||c.has(p)||p.startsWith(".")))try{(await a.stat(f)).isDirectory()&&d.push({dir:f,depth:u.depth+1});}catch{continue}}}}return false}async function Re(e){for(let n of St){let i=r.join(e,n);if(await a.pathExists(i))try{if((await a.readdir(i)).some(c=>!c.startsWith(".")))return true}catch{continue}}return false}function $t(e){let n=e.key;return b$3(n).key}function Dt(e,n,i){return a$4(n,i).some(c=>!!e[c])}async function et(e){let{projectPath:n,detection:i,packageJsonData:t}=e,c=$t(i),o=b$3(c),s=Xe(t),d=[],u=await a.pathExists(r.join(n,"package-lock.json"))||await a.pathExists(r.join(n,"pnpm-lock.yaml"))||await a.pathExists(r.join(n,"yarn.lock"))||await a.pathExists(r.join(n,"bun.lockb"));d.push({id:"frontend-lockfile-integrity",label:"Frontend lockfile integrity",status:u?"pass":"warn",severity:"warn",scope:"project-scoped",reason:u?"Node lockfile detected for deterministic dependency restore.":"No Node lockfile detected (package-lock/yarn.lock/pnpm-lock.yaml/bun.lockb).",recommendation:u?void 0:"Commit a lockfile for deterministic installs and CI parity."});let m=await a.pathExists(r.join(n,"tsconfig.json")),p=await a.pathExists(r.join(n,"jsconfig.json")),f=m||p;d.push({id:"frontend-typescript-surface",label:"TypeScript project surface",status:f?"pass":"warn",severity:"warn",scope:"project-scoped",reason:f?m?"tsconfig.json detected.":"jsconfig.json detected.":"No tsconfig.json or jsconfig.json detected.",recommendation:f?void 0:"Add tsconfig.json (or jsconfig.json) for typed frontend builds and IDE parity."});let g=o.fileHints.length>0&&o.fileHints.some(k=>a.pathExistsSync(r.join(n,k)));d.push({id:"frontend-framework-config",label:`${o.displayName} config surface`,status:g?"pass":"warn",severity:"warn",scope:"project-scoped",reason:g?`${o.displayName} configuration artifacts detected.`:`No ${o.displayName} config markers detected (${o.fileHints.join(", ")||"n/a"}).`,recommendation:g?void 0:"Keep framework config files in-repo for reproducible dev/build behavior."});for(let k of Rt){let h=Dt(s,c,k),x=k==="dev"||k==="build";d.push({id:`frontend-script-${k}`,label:`${k} script surface`,status:h?"pass":x?"fail":"warn",severity:x?"error":"warn",scope:"project-scoped",reason:h?`package.json exposes a ${k} script for ${o.displayName}.`:`No ${k} script detected for ${o.displayName}.`,recommendation:h?void 0:`Add a "${a$4(c,k)[0]??k}" script to package.json.`});}let y=await Re(n);return d.push({id:"frontend-source-tree",label:"Frontend source tree",status:y?"pass":"warn",severity:"warn",scope:"project-scoped",reason:y?"Application source directories detected (src/app/pages).":"No frontend source directories detected under src/, app/, or pages/.",recommendation:y?void 0:"Ensure the scaffolded application tree exists before running lifecycle commands."}),d}var At="rapidkit-doctor-fix-result-v1",ee="npx rapidkit workspace verify --from-impact .rapidkit/reports/workspace-impact-last-run.json --json";function re(e){return {schemaVersion:At,appliedFixes:e.appliedFixes,remainingBlockers:e.remainingBlockers,verifyRecommended:e.verifyRecommended??ee}}function It(e){return [...new Set(e.filter(n=>n&&n.trim().length>0))]}function Nt(){let e=q$1().map(t=>r.join(t,b$2()?"poetry.exe":"poetry")),n=b$2()?[r.join(process.env.APPDATA||"","Python","Scripts","poetry.exe"),r.join(process.env.USERPROFILE||"","AppData","Roaming","Python","Scripts","poetry.exe")]:[],i=b$2()?[]:["/usr/local/bin/poetry","/usr/bin/poetry"];return It([...e,...n,...i])}function Ht(e){let n=q$1().map(u=>({location:"Global (user-local)",path:r.join(u,b$2()?"rapidkit.exe":"rapidkit")})),i=[{location:"Global (pipx)",path:r.join(e,".local","bin","rapidkit")},{location:"Global (pipx)",path:r.join(e,"AppData","Roaming","Python","Scripts","rapidkit.exe")},{location:"Global (pyenv)",path:r.join(e,".pyenv","shims","rapidkit")},{location:"Global (system)",path:"/usr/local/bin/rapidkit"},{location:"Global (system)",path:"/usr/bin/rapidkit"}],t=m(r.join(process.cwd(),".venv")),c=o(process.cwd()),o$1=[{location:"Workspace (.venv)",path:t},...c.map(u=>({location:"Workspace (launcher)",path:u}))],s=[...n,...i,...o$1],d=new Set;return s.filter(u=>d.has(u.path)?false:(d.add(u.path),true))}function Mt(e){let n=new Map([["Workspace (.venv)",0],["Global (user-local)",1],["Global (pipx)",2],["Global (pyenv)",3],["Global (system)",4]]);return [...e].sort((i,t)=>{let c=n.get(i.location)??Number.MAX_SAFE_INTEGER,o=n.get(t.location)??Number.MAX_SAFE_INTEGER;return c!==o?c-o:i.path.localeCompare(t.path)})}function ne(e){let n=0,i=e.issues.some(t=>t.toLowerCase().includes("environment file missing"));return e.hasEnvFile===false&&!i&&(n+=1),typeof e.vulnerabilities=="number"&&e.vulnerabilities>0&&(n+=1),n}function De(e){return e.filter(n=>ne(n)>0).length}function He(e){return e.reduce((n,i)=>n+ne(i),0)}var _t="doctor-project-scan-v2",at="doctor-workspace-cache-v2",Bt=Object.freeze({version:"doctor-evidence-v1",scoringPolicyVersion:"doctor-score-policy-v1",generatedBy:"rapidkit-npm",deterministicScoreBreakdown:true,scopeModel:"workspace-aggregate-or-project-scoped"});function ye(){return {...Bt}}function ke(e){return !e||e.total<=0?null:Math.round(e.passed/e.total*100)}function ct(e){return typeof e=="number"?e:Array.isArray(e)?e.length:0}async function lt(e,n){try{if(!await a.pathExists(e))return null;let i=await a.readJSON(e);return c$1(i,n)?i:null}catch{return null}}function dt(e,n){if(!e?.system)return [];let i=[{id:"python",current:n.python},{id:"poetry",current:n.poetry},{id:"pipx",current:n.pipx},{id:"go",current:n.go},{id:"rapidkitCore",current:n.rapidkitCore}],t=[];for(let c of i){let o=e.system?.[c.id]?.status;!o||o===c.current.status||t.push({id:c.id,from:o,to:c.current.status});}return t}function Tt(e,n){let i=new Map;for(let g of n.projects)i.set(g.path||g.name,g.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:[],c=new Map;for(let g of t){let y=g.path||g.name;y&&c.set(y,ct(g.issues));}let o=0,s=0,d=new Set,u=new Set,m=new Set([...Array.from(c.keys()),...Array.from(i.keys())]);for(let g of m){let y=c.get(g)??0,k=i.get(g)??0;k>y?(o+=k-y,d.add(g)):k<y&&(s+=y-k,u.add(g));}let p=ke(e.healthScore),f=ke(n.healthScore);return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:o,resolvedIssueCount:s,netIssueDelta:o-s,scoreDeltaPercent:p===null||f===null?null:f-p,systemStatusChanges:dt(e,{python:n.python,poetry:n.poetry,pipx:n.pipx,go:n.go,rapidkitCore:n.rapidkitCore}),regressedProjects:Array.from(d).sort(),improvedProjects:Array.from(u).sort()}}function Ot(e,n){if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let i=ct(e.project?.issues),t=n.project.issues.length,c=Math.max(t-i,0),o=Math.max(i-t,0),s=ke(e.healthScore),d=ke(n.healthScore),u=n.project.path||n.project.name;return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:c,resolvedIssueCount:o,netIssueDelta:c-o,scoreDeltaPercent:s===null||d===null?null:d-s,systemStatusChanges:dt(e,{python:n.python,poetry:n.poetry,pipx:n.pipx,go:n.go,rapidkitCore:n.rapidkitCore}),regressedProjects:c>0?[u]:[],improvedProjects:o>0?[u]:[]}}function ut(e){let n=e??[],i=0,t=0;for(let s of n){if(s.scope==="project-scoped"){i+=1;continue}(s.scope==="workspace-aggregate"||s.scope==="host-system")&&(t+=1);}let c=i>0&&t>0?1:0,o=c>0?"mixed":i>0?"scoped":t>0?"aggregated":"unknown";return {scopedCount:i,aggregatedCount:t,mixedCount:c,dominantScope:o}}function $(e,n){return b$2()?`cd "${e}"; ${n}`:`cd ${e} && ${n}`}function z(e){return b$2()?$(e,"Copy-Item .env.example .env"):$(e,"cp .env.example .env")}function Gt(e){return e==="FastAPI"||e==="NestJS"?"first-class":e==="Django"||e==="Flask"||e==="Express"||e==="Fastify"||e==="Koa"||e==="Go/Fiber"||e==="Go/Gin"||e==="Spring Boot"||e==="Rust"||e==="Phoenix"||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 Kt(e){return e==="Next.js"||e==="Remix"||e==="Nuxt"||e==="React"||e==="Vue"||e==="Angular"||e==="SvelteKit"||e==="Svelte"||e==="Vite"||e==="Astro"||e==="Solid"?"frontend":e==="Unknown"||e==="Node.js"||e==="Python"?"generic":"backend"}function Wt(e){return e==="NestJS"||e==="Next.js"||e==="Remix"||e==="Nuxt"||e==="React"||e==="Vue"||e==="Angular"||e==="SvelteKit"||e==="Svelte"||e==="Vite"||e==="Astro"||e==="Solid"||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 Ae(e,n){let i=q(n);e.commandCapabilities=i,e.supportTier=i.frameworkSupportTier;}function he(e,n,i,t){e.framework=n,e.frameworkConfidence=i,e.supportTier=Gt(n),e.projectKind=Kt(n),e.runtimeFamily=Wt(n);}function pt(e){return e==="python"?"python":e==="node"||e==="bun"?"node":e==="go"?"go":e==="java"?"java":e==="rust"?"rust":e==="elixir"?"elixir":e==="clojure"?"clojure":e==="deno"?"deno":e==="php"?"php":e==="ruby"?"ruby":e==="dotnet"?"dotnet":"unknown"}function Me(e){switch(e.key){case "fastapi":return "FastAPI";case "django":return "Django";case "flask":return "Flask";case "python":return "Python";case "nestjs":return "NestJS";case "nextjs":return "Next.js";case "remix":return "Remix";case "nuxt":return "Nuxt";case "react":return "React";case "vite":return "Vite";case "vue":return "Vue";case "sveltekit":return "SvelteKit";case "svelte":return "Svelte";case "angular":return "Angular";case "astro":return "Astro";case "solid":return "Solid";case "express":return "Express";case "fastify":return "Fastify";case "koa":return "Koa";case "node":return "Node.js";case "gofiber":return "Go/Fiber";case "gogin":return "Go/Gin";case "echo":return "Echo";case "go":return "Go";case "springboot":return "Spring Boot";case "java":return "Java";case "laravel":return "Laravel";case "php":return "PHP";case "rails":return "Ruby on Rails";case "ruby":return "Ruby";case "dotnet":return "ASP.NET";case "phoenix":return "Phoenix";case "elixir":return "Elixir";case "clojure":return "Clojure";case "scala":return "Scala";case "kotlin":return "Kotlin";case "deno":return "Deno";case "bun":return "Bun";case "actix":case "axum":case "rocket":case "rust":return "Rust";case "sinatra":case "symfony":case "unknown":return "Unknown";default:return "Unknown"}}function Vt(e){return e.key==="python"||e.key==="node"||e.key==="go"||e.key==="java"||e.key==="php"||e.key==="ruby"||e.key==="dotnet"||e.key==="rust"||e.key==="elixir"||e.key==="clojure"||e.key==="scala"||e.key==="kotlin"||e.key==="deno"||e.key==="bun"||e.key==="unknown"}function Lt(e,n){e.framework=Me(n),e.frameworkKey=n.key,e.importStack=n.importStack,e.frameworkConfidence=n.confidence,e.supportTier=n.supportTier,e.projectKind="frontend",e.runtimeFamily=pt(n.runtime);}function W(e,n){e.framework=Me(n),e.frameworkKey=n.key,e.importStack=n.importStack,e.frameworkConfidence=n.confidence,e.supportTier=n.supportTier,e.projectKind=Vt(n)?"generic":"backend",e.runtimeFamily=pt(n.runtime);}function Jt(e){let n=e.dependencies,i=e.scripts??{},t=(e.kitName??"").toLowerCase(),c=s=>!!n[s],o=Object.values(i).filter(s=>typeof s=="string").join(" ").toLowerCase();return c("next")||o.includes("next ")?{framework:"Next.js",confidence:"high"}:c("nuxt")||o.includes("nuxt ")?{framework:"Nuxt",confidence:"high"}:c("@nestjs/core")||t.startsWith("nestjs.")?{framework:"NestJS",confidence:"high"}:c("express")?{framework:"Express",confidence:"high"}:c("fastify")?{framework:"Fastify",confidence:"high"}:c("koa")?{framework:"Koa",confidence:"high"}:c("@angular/core")?{framework:"Angular",confidence:"high"}:c("@sveltejs/kit")||o.includes("svelte-kit")?{framework:"SvelteKit",confidence:"high"}:c("vue")?{framework:"Vue",confidence:"medium"}:c("react")&&c("react-dom")?{framework:"React",confidence:"medium"}:{framework:"Node.js",confidence:"low"}}async function qt(e){let n=i(e);return n.runtime!=="python"?{framework:"Python",confidence:"low"}:{framework:Me(n),confidence:n.confidence}}async function tt(e){try{let n=await a.stat(e);return `${r.basename(e)}:${n.isDirectory()?"d":"f"}:${n.size}:${n.mtimeMs}`}catch{return `${r.basename(e)}:missing`}}async function Ut(e){try{let n=new Set([".git",".venv","node_modules",".rapidkit","dist","build","coverage","__pycache__"]),i=new Set;await pe(e)&&i.add(e);let t=await a$1(e);for(let o of t){let s=r.isAbsolute(o.path)?o.path:r.join(e,o.path);await pe(s)&&i.add(s);}let c=async(o,s)=>{if(s<0)return;let d=await mt(o);for(let u of d){if(ft(u,n))continue;let m=r.join(o,u);if(await pe(m)){i.add(m);continue}s>0&&await c(m,s-1);}};return await c(e,1),i.size===0&&(await cn(e,3,n)).forEach(s=>i.add(s)),Array.from(i).sort((o,s)=>o.localeCompare(s))}catch{return []}}async function zt(e,n){let i=[r.join(e,".rapidkit-workspace"),r.join(e,".rapidkit","workspace.json"),r.join(e,".rapidkit","imported-projects.json"),r.join(e,".rapidkit","policies.yml"),r.join(e,".rapidkit","toolchain.lock"),r.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"],c=await Promise.all(i.map(tt)),o=await Promise.all(n.map(async s=>{let d=await Promise.all(t.map(u=>tt(r.join(s,u))));return `${s}::${d.join("|")}`}));return [_t,...c,...o].join("||")}async function Qt(e,n){try{if(!await a.pathExists(e))return null;let i=await a.readJSON(e);return !i||i.signature!==n||!Array.isArray(i.projects)||typeof i.schemaVersion=="string"&&i.schemaVersion!==at?null:i}catch{return null}}async function Xt(e,n){try{await a.ensureDir(r.dirname(e)),await a.writeJSON(e,n,{spaces:2});}catch{}}async function Yt(e$1,n,i){let t=r.join(e$1,".rapidkit","reports","doctor-last-run.json");try{await a.ensureDir(r.dirname(t));let c=[];for(let o of n.projects)for(let s of o.issues??[])typeof s=="string"&&s.trim()&&c.push(`${o.name}: ${s.trim()}`);for(let[o,s]of [["python",n.python],["rapidkitCore",n.rapidkitCore]])if(s?.status==="error"){let d=typeof s.message=="string"?s.message:`${o} check failed`;c.push(`${o}: ${d}`);}return await a.writeJSON(t,f$1({schemaVersion:a$2,evidenceType:"workspace",contract:ye(),workspacePath:e$1,workspaceName:n.workspaceName,projectScanCached:n.projectScanCached??false,projectScanSignature:n.projectScanSignature,cachePath:i,healthScore:n.healthScore,system:{python:n.python,poetry:n.poetry,pipx:n.pipx,go:n.go,rapidkitCore:n.rapidkitCore,versions:{core:n.coreVersion,npm:n.npmVersion}},projects:n.projects,summary:{totalProjects:n.projects.length,totalIssues:n.projects.reduce((o,s)=>o+s.issues.length,0),projectAdvisoryWarningProjects:De(n.projects),projectAdvisoryWarnings:He(n.projects),hasSystemErrors:[n.python,n.rapidkitCore].some(o=>o.status==="error"),scopeProvenance:n.scopeProvenance},driftDelta:n.driftDelta,scoreBreakdown:n.scoreBreakdown??[]},{commandId:"checkWorkspaceHealth",exitCode:ae(n.healthScore,{}),generatedAt:new Date().toISOString(),blockers:c.slice(0,12),runId:e()}),{spaces:2}),t}catch{return}}async function _e(){let[e,n,i,t,c]=await Promise.all([Zt(),en(),tn(),nn(),sn()]);return {python:e,poetry:n,pipx:i,go:t,rapidkitCore:c}}async function Zt(){let e=i$1();for(let n of e)try{let{stdout:i}=await execa(n,["--version"],{timeout:3e3}),t=i.match(/Python (\d+\.\d+\.\d+)/);if(t){let c=t[1],[o,s]=c.split(".").map(Number);return o<3||o===3&&s<10?{status:"warn",message:`Python ${c} (requires 3.10+)`,details:`${n} found but version is below minimum requirement`}:{status:"ok",message:`Python ${c}`,details:`Using ${n}`}}}catch{continue}return {status:"error",message:"Python not found",details:"Install Python 3.10+ and ensure it's in PATH"}}async function en(){try{let{stdout:e}=await execa("poetry",["--version"],{timeout:3e3}),n=e.match(/Poetry .*version ([\d.]+)/);return n?{status:"ok",message:`Poetry ${n[1]}`,details:"Available for dependency management"}:{status:"warn",message:"Poetry version unknown"}}catch{let e=i$1().map(n=>({cmd:n,args:n==="py"?["-3","-m","poetry","--version"]:["-m","poetry","--version"]}));for(let n of e)try{let{stdout:i}=await execa(n.cmd,n.args,{timeout:3e3,shell:c()}),t=i.match(/Poetry .*version ([\d.]+)/)||i.match(/([\d.]+)/);return {status:"ok",message:t?.[1]?`Poetry ${t[1]}`:"Poetry detected",details:`Available via ${n.cmd} ${n.args.join(" ")}`}}catch{continue}for(let n of Nt())try{if(!await a.pathExists(n))continue;let{stdout:i}=await execa(n,["--version"],{timeout:3e3,shell:c()}),t=i.match(/Poetry .*version ([\d.]+)/)||i.match(/([\d.]+)/);return {status:"ok",message:t?.[1]?`Poetry ${t[1]}`:"Poetry detected",details:`Available at ${n}`}}catch{continue}return {status:"warn",message:"Poetry not installed",details:"Optional: Install for better dependency management"}}}async function tn(){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=i$1();for(let n of e)try{let i=n==="py"?["-3","-m","pipx","--version"]:["-m","pipx","--version"],{stdout:t}=await execa(n,i,{timeout:3e3,shell:c()});return {status:"ok",message:`pipx ${t.trim()}`,details:`Available via ${n} ${i.join(" ")}`}}catch{continue}return {status:"warn",message:"pipx not installed",details:"Optional: Install for isolated Python tools"}}}async function nn(){try{let{stdout:e}=await execa("go",["version"],{timeout:3e3}),n=e.match(/go version go(\d+\.\d+(?:\.\d+)?)/);return n?{status:"ok",message:`Go ${n[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 sn(){let e=process.env.HOME||process.env.USERPROFILE||"",n=[],i=Ht(e);for(let{location:c,path:o}of i)try{if(await a.pathExists(o)){let{stdout:s,exitCode:d}=await execa(o,["--version"],{timeout:3e3,reject:false});if(d===0&&(s.includes("RapidKit Version")||s.includes("RapidKit"))){let u=s.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);u&&n.push({location:c,path:o,version:u[1]});}}}catch{continue}if(n.length>0){let c=n.filter(s=>s.location!=="Workspace (launcher)");if(c.length>0){let s=Mt(c),d=s[0].version,u=s.some(f=>f.location==="Workspace (.venv)"),m=s.some(f=>f.location.startsWith("Global (")),p=!u&&m?"Workspace (.venv): not installed (optional). For best project-level performance and isolation, run npx rapidkit workspace run init inside this workspace.":void 0;return {status:"ok",message:`RapidKit Core ${d}`,details:p,paths:s.map(f=>({location:f.location,path:f.path,version:f.version}))}}return {status:"ok",message:`RapidKit Core ${n[0].version}`,details:"Detected via workspace launcher"}}try{let{stdout:c,exitCode:o}=await execa("rapidkit",["--version"],{timeout:3e3,reject:false});if(o===0&&(c.includes("RapidKit Version")||c.includes("RapidKit"))){let s=c.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(s)return {status:"ok",message:`RapidKit Core ${s[1]}`,details:"Available via PATH"}}}catch{}try{let{stdout:c,exitCode:o}=await execa("poetry",["run","rapidkit","--version"],{timeout:3e3,reject:false});if(o===0&&(c.includes("RapidKit Version")||c.includes("RapidKit"))){let s=c.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(s)return {status:"ok",message:`RapidKit Core ${s[1]}`,details:"Available via Poetry"}}}catch{}let t=i$1();for(let c of t)try{let{stdout:o,exitCode:s}=await execa(c,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:3e3,reject:false});if(s===0&&o&&!o.includes("Traceback")&&!o.includes("ModuleNotFoundError")){let d=o.trim();if(d)return {status:"ok",message:`RapidKit Core ${d}`,details:`Available in ${c} environment`}}}catch{continue}return {status:"error",message:"RapidKit Core not installed",details:"Install with: pipx install rapidkit-core"}}async function T(e,n,i){let t=r.join(e,"Dockerfile");n.hasDocker=await a.pathExists(t);let c=r.join(e,"tests"),o=r.join(e,"test"),s=r.join(e,"src","test"),d=await a.pathExists(c)||await a.pathExists(o)||await a.pathExists(s),u=false;if(n.framework==="Go/Fiber"||n.framework==="Go/Gin")try{let m=[{dir:e,depth:0}],p=4,f=new Set([".git",".venv","node_modules","dist","build","vendor"]);for(;m.length>0&&!u;){let g=m.shift();if(!g)break;let y=[];try{y=await a.readdir(g.dir);}catch{continue}for(let k of y){let h=r.join(g.dir,k),x;try{x=await a.stat(h);}catch{continue}if(x.isFile()&&k.endsWith("_test.go")){u=true;break}x.isDirectory()&&g.depth<p&&!f.has(k)&&!k.startsWith(".")&&m.push({dir:h,depth:g.depth+1});}}}catch{}if(n.hasTests=d||u,n.runtimeFamily==="node"&&!n.hasTests&&(n.hasTests=await Ze(e,i)),n.runtimeFamily==="node")n.hasCodeQuality=await Ye(e,i);else if(n.framework==="Go/Fiber"||n.framework==="Go/Gin"){let m=r.join(e,".golangci.yml"),p=r.join(e,".golangci.yaml"),f=r.join(e,"Makefile"),g=await a.pathExists(f)&&(await a.readFile(f,"utf8")).includes("golangci-lint");n.hasCodeQuality=await a.pathExists(m)||await a.pathExists(p)||g;}else if(n.runtimeFamily==="python"){let m=r.join(e,"ruff.toml"),p=r.join(e,"pyproject.toml");if(await a.pathExists(p))try{let f=await a.readFile(p,"utf8");n.hasCodeQuality=f.includes("[tool.ruff]")||await a.pathExists(m);}catch{n.hasCodeQuality=await a.pathExists(m);}}else if(n.framework==="Spring Boot"){let m=r.join(e,"pom.xml");if(await a.pathExists(m))try{let p=await a.readFile(m,"utf8");n.hasCodeQuality=p.includes("spotless")||p.includes("checkstyle")||p.includes("pmd")||p.includes("maven-enforcer-plugin");}catch{n.hasCodeQuality=false;}}try{if(n.runtimeFamily==="node"){let{stdout:m}=await execa("npm",["audit","--json"],{cwd:e,reject:false});if(m)try{let f=JSON.parse(m).metadata?.vulnerabilities;f&&(n.vulnerabilities=(f.high||0)+(f.critical||0)+(f.moderate||0));}catch{}}else if(n.runtimeFamily==="python"){let m=r.join(e,".venv"),p=l$1(m);if(await a.pathExists(p))try{let{stdout:f}=await execa(p,["-m","pip","list","--format=json"],{timeout:5e3,reject:false});if(f){JSON.parse(f);n.vulnerabilities=0;}}catch{}}}catch{}}function N(e,n){e.probes||(e.probes=[]),e.probes.push(n);}async function on(e,n){let i=n.runtimeFamily||"unknown";if(n.projectKind==="backend"||n.projectKind==="generic"){if(i==="node"){let c=await a.pathExists(r.join(e,"package-lock.json"))||await a.pathExists(r.join(e,"pnpm-lock.yaml"))||await a.pathExists(r.join(e,"yarn.lock"));N(n,{id:"adapter-node-lockfile-integrity",label:"Node adapter lockfile integrity",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Node lockfile detected for deterministic dependency restore.":"No Node lockfile detected (package-lock/yarn.lock/pnpm-lock.yaml).",recommendation:c?void 0:"Commit a lockfile for deterministic installs and CI parity."});let o=await a.pathExists(r.join(e,"src/main.ts"))||await a.pathExists(r.join(e,"src/main.js"))||await a.pathExists(r.join(e,"src/server.ts"))||await a.pathExists(r.join(e,"src/server.js"));N(n,{id:"adapter-node-boot-entrypoint",label:"Node adapter boot entrypoint",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?"Boot entrypoint markers detected for service startup path.":"No canonical Node boot entrypoint markers detected.",recommendation:o?void 0:"Define and document service bootstrap entrypoint (main/server)."});return}if(i==="python"){let c=await a.pathExists(r.join(e,"poetry.lock"))||await a.pathExists(r.join(e,"requirements.txt"))||await a.pathExists(r.join(e,"uv.lock"));N(n,{id:"adapter-python-lockfile-integrity",label:"Python adapter dependency integrity",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Python dependency contract file detected.":"No Python dependency contract file detected (poetry.lock/requirements/uv.lock).",recommendation:c?void 0:"Pin dependency contract for deterministic setup and reproducible CI."});let o=await a.pathExists(r.join(e,"app/main.py"))||await a.pathExists(r.join(e,"main.py"))||await a.pathExists(r.join(e,"manage.py"));N(n,{id:"adapter-python-boot-entrypoint",label:"Python adapter boot entrypoint",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?"Python application entrypoint markers detected.":"No Python application entrypoint markers detected.",recommendation:o?void 0:"Expose explicit app/main entrypoint for deterministic boot probes."});return}if(i==="java"){let c=await a.pathExists(r.join(e,"mvnw"))||await a.pathExists(r.join(e,"gradlew"));N(n,{id:"adapter-java-build-wrapper",label:"Java adapter build wrapper",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Build wrapper detected (mvnw/gradlew).":"No Java build wrapper detected.",recommendation:c?void 0:"Commit mvnw or gradlew for reproducible enterprise pipelines."});return}if(i==="go"){let c=await a.pathExists(r.join(e,"go.sum"));N(n,{id:"adapter-go-module-integrity",label:"Go adapter module integrity",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"go.sum detected for deterministic module verification.":"go.sum missing; module integrity baseline is incomplete.",recommendation:c?void 0:"Generate and commit go.sum in the repository baseline."});}}}async function rn(e,n){let i=[r.join(e,".rapidkit","doctor.adapters.json"),r.join(e,"doctor.adapters.json")];for(let t of i)if(await a.pathExists(t))try{let c=await a.readJSON(t),o=Array.isArray(c?.checks)?c.checks:[];for(let s=0;s<o.length;s+=1){let d=o[s]||{},u=Array.isArray(d.runtimes)?d.runtimes:[];if(u.length>0&&!u.includes(n.runtimeFamily||"unknown"))continue;let m=typeof d.id=="string"&&d.id.trim().length>0?d.id.trim():`adapter-check-${s+1}`,p=typeof d.label=="string"&&d.label.trim().length>0?d.label.trim():m,f=d.severity||"warn",g=Array.isArray(d.anyOfPaths)?d.anyOfPaths.filter(Boolean):[],y=Array.isArray(d.allOfPaths)?d.allOfPaths.filter(Boolean):[],k=g.length===0;for(let b of g)if(await a.pathExists(r.join(e,b))){k=true;break}let h=true;for(let b of y)if(!await a.pathExists(r.join(e,b))){h=false;break}let x=k&&h;N(n,{id:m,label:p,status:x?"pass":f==="error"?"fail":"warn",severity:f,scope:"project-scoped",reason:x?d.passReason||"Custom adapter contract satisfied.":d.failReason||`Custom adapter check failed from ${r.basename(t)}.`,recommendation:d.recommendation});}}catch{N(n,{id:"custom-adapter-config",label:"Custom doctor adapter configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${r.basename(t)}.`,recommendation:"Fix JSON syntax in doctor.adapters.json to re-enable adapter checks."});}}async function O(e,n){if(!(n.projectKind==="backend"||n.projectKind==="generic"))return;let t=r.join(e,".env"),c=r.join(e,".env.example"),o=await a.pathExists(t)||await a.pathExists(c)||await a.pathExists(r.join(e,"config"));N(n,{id:"config-surface",label:"Configuration contract surface",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?"Configuration artifacts detected (.env/.env.example/config).":"No explicit configuration contract artifacts detected.",recommendation:o?void 0:"Add .env.example or explicit config contract documentation for deterministic setup."});let s={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=n.runtimeFamily||"unknown",u=s[d]||s.unknown,m=false;for(let g of u)if(await a.pathExists(r.join(e,g))){m=true;break}N(n,{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"],f=false;for(let g of p)if(await a.pathExists(r.join(e,g))){f=true;break}N(n,{id:"runtime-health-surface",label:"Runtime health probe surface",status:f?"pass":"warn",severity:"warn",scope:"project-scoped",reason:f?"Health endpoint/config markers detected.":"No explicit runtime health endpoint markers detected.",recommendation:f?void 0:"Expose a deterministic health endpoint and keep it covered in verify pack."}),await on(e,n);}async function an(e,n,i,t){let c=await et({projectPath:e,detection:t,packageJsonData:i});for(let o of c)N(n,o);}async function G(e,n){let i=[r.join(e,".rapidkit","doctor.probes.json"),r.join(e,"doctor.probes.json")];for(let t of i)if(await a.pathExists(t))try{let c=await a.readJSON(t),o=Array.isArray(c?.probes)?c.probes:[];for(let s=0;s<o.length;s+=1){let d=o[s]||{},u=typeof d.id=="string"&&d.id.trim().length>0?d.id.trim():`custom-probe-${s+1}`,m=typeof d.label=="string"&&d.label.trim().length>0?d.label.trim():u,p=d.severity||"warn",f=Array.isArray(d.anyOfPaths)?d.anyOfPaths.filter(Boolean):[],g=Array.isArray(d.allOfPaths)?d.allOfPaths.filter(Boolean):[],y=f.length===0;for(let x of f)if(await a.pathExists(r.join(e,x))){y=true;break}let k=true;for(let x of g)if(!await a.pathExists(r.join(e,x))){k=false;break}let h=y&&k;N(n,{id:u,label:m,status:h?"pass":p==="error"?"fail":"warn",severity:p,scope:"project-scoped",reason:h?"Custom probe contract satisfied.":`Custom probe failed from ${r.basename(t)}.`,recommendation:d.recommendation});}}catch{N(n,{id:"custom-probe-config",label:"Custom doctor probe configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${r.basename(t)}.`,recommendation:"Fix JSON syntax in doctor.probes.json to re-enable custom probes."});}await rn(e,n);}async function we(e,n={}){let t={name:r.basename(e),path:e,venvActive:false,depsInstalled:false,coreInstalled:false,issues:[],fixCommands:[]},c=n.allowNonRapidkit===true,o=r.join(e,".rapidkit");if(!await a.pathExists(o)){if(!c)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 w=r.join(e,"registry.json");if(await a.pathExists(w)){let v=await a.readJson(w);v.installed_modules&&(t.stats={modules:v.installed_modules.length});}}catch{}try{let{auditProjectModulePaths:w}=await import('./module-layout-NZ43RSC5.js'),v=await w(e);if(v.issues.length>0){for(let E of v.issues)t.issues.push(`${E.message} (${E.slug})`);t.fixCommands=t.fixCommands??[],t.fixCommands.push("npx rapidkit workspace contract verify --strict --json"),t.fixCommands.push("npx rapidkit add module <slug> # reinstall via Core-backed module install");}}catch{}let s=null;try{let w=r.join(o,"project.json");if(await a.pathExists(w)){s=await a.readJson(w);let v=s?.kit_name||s?.kit;v&&(t.kit=v);}}catch{}try{let w=r.join(e,".git");if(await a.pathExists(w)){let{stdout:v}=await execa("git",["log","-1","--format=%cr"],{cwd:e,reject:false});v&&(t.lastModified=v.trim());}else {let v=await a.stat(e),D=Date.now()-v.mtime.getTime(),A=Math.floor(D/(1e3*60*60*24));t.lastModified=A===0?"today":`${A} day${A>1?"s":""} ago`;}}catch{}let d$1=r.join(e,"package.json"),u=r.join(e,"pyproject.toml"),m=r.join(e,"requirements.txt"),p=r.join(e,"go.mod"),f=r.join(e,"pom.xml"),g=r.join(e,"build.sbt"),y=r.join(e,"Cargo.toml"),k=r.join(e,"mix.exs"),h=r.join(e,"deps.edn"),x=r.join(e,"project.clj"),b=r.join(e,"deno.json"),H=r.join(e,"deno.jsonc"),fe=r.join(e,"bun.lockb"),K=r.join(e,"bun.lock"),U=r.join(e,"composer.json"),Q=r.join(e,"Gemfile"),V=await a.pathExists(d$1),ce=await a.pathExists(u)||await a.pathExists(m),oe=await a.pathExists(U),L=await a.pathExists(Q),M=await a.pathExists(y),ie=await a.pathExists(k),le=await a.pathExists(h)||await a.pathExists(x),vt=await a.pathExists(g),xt=await a.pathExists(b)||await a.pathExists(H),ge=s?.runtime==="dotnet";try{ge=ge||await nt(e,".csproj",3)||await nt(e,".sln",2);}catch{ge=s?.runtime==="dotnet";}let bt=await a.pathExists(p)||s?.runtime==="go"||typeof s?.kit_name=="string"&&(s.kit_name.startsWith("gofiber")||s.kit_name.startsWith("gogin")),Be=V&&(await a.pathExists(fe)||await a.pathExists(K)||typeof s?.packageManager=="string"&&(s?.packageManager).toLowerCase().startsWith("bun@"));if(bt){W(t,i(e,s??null)),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 w=r.join(e,"go.sum");return await a.pathExists(w)?t.depsInstalled=true:(t.depsInstalled=false,t.issues.push("Go dependencies not downloaded (go.sum missing)"),t.fixCommands?.push($(e,"go mod tidy"))),await T(e,t),await O(e,t),await G(e,t),t}if(await a.pathExists(f)||s?.runtime==="java"||typeof s?.kit_name=="string"&&s.kit_name.startsWith("springboot")){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=await a.pathExists(f),v=await a.pathExists(r.join(e,"build.gradle"))||await a.pathExists(r.join(e,"build.gradle.kts")),E=await a.pathExists(r.join(e,"mvnw"))||await a.pathExists(r.join(e,"mvnw.cmd")),D=await a.pathExists(r.join(e,"gradlew"))||await a.pathExists(r.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(w){if(!E)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(v&&!D)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 A=r.join(e,"target"),I=r.join(e,"build","libs"),_=r.join(e,".rapidkit","cache","java","m2"),C=r.join(e,".rapidkit","cache","java","gradle");t.depsInstalled=await a.pathExists(A)||await a.pathExists(I)||await a.pathExists(_)||await a.pathExists(C),t.depsInstalled||(t.issues.push("Java dependencies are not warmed or built yet"),t.fixCommands?.push($(e,"rapidkit init")));let S=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(S),!t.hasEnvFile){let X=r.join(e,".env.example");await a.pathExists(X)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}let q=r.join(e,"src","main","resources","application.yml");if(await a.pathExists(q))try{let X=await a.readFile(q,"utf-8");/include:\s*[^\n]*health/i.test(X)||/management:\s*[\s\S]*endpoint:\s*[\s\S]*health:/i.test(X)||(t.issues.push("Actuator health endpoint exposure is not clearly configured in application.yml"),t.fixCommands?.push($(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 T(e,t),await O(e,t),await G(e,t),t}if(M){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=r.join(e,"Cargo.lock"),v=r.join(e,"target");t.depsInstalled=await a.pathExists(w)||await a.pathExists(v),t.depsInstalled||(t.issues.push("Rust dependencies are not resolved yet (Cargo.lock/target missing)"),t.fixCommands?.push($(e,"cargo fetch")));let E=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(E),!t.hasEnvFile){let D=r.join(e,".env.example");await a.pathExists(D)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}return await T(e,t),await O(e,t),await G(e,t),t}if(ie){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=r.join(e,"mix.lock"),v=r.join(e,"deps");t.depsInstalled=await a.pathExists(w)||await a.pathExists(v),t.depsInstalled||(t.issues.push("Elixir dependencies not installed (mix.lock/deps missing)"),t.fixCommands?.push($(e,"mix deps.get")));let E=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(E),!t.hasEnvFile){let D=r.join(e,".env.example");await a.pathExists(D)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}return await T(e,t),await O(e,t),await G(e,t),t}if(le){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=r.join(e,".cpcache"),v=r.join(e,"target"),E=await a.pathExists(h)||await a.pathExists(x);return t.depsInstalled=await a.pathExists(w)||await a.pathExists(v)||E,t.depsInstalled||(t.issues.push("Clojure dependency cache not initialized"),t.fixCommands?.push($(e,"clojure -P"))),await T(e,t),await O(e,t),await G(e,t),t}if(vt){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=r.join(e,"target");t.depsInstalled=await a.pathExists(w),t.depsInstalled||(t.issues.push("Scala build artifacts missing (run dependency/build warmup)"),t.fixCommands?.push($(e,"sbt compile")));let v=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(v),!t.hasEnvFile){let E=r.join(e,".env.example");await a.pathExists(E)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}return await T(e,t),await O(e,t),await G(e,t),t}if(xt){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false,t.depsInstalled=true;let w=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(w),!t.hasEnvFile){let v=r.join(e,".env.example");await a.pathExists(v)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}return await T(e,t),await O(e,t),await G(e,t),t}if(V){let w=null;try{w=await a.readJson(d$1);}catch{w=null;}let v={...w?.dependencies??{},...w?.devDependencies??{}},E=w?.scripts??{},D=typeof s?.kit_name=="string"?s.kit_name.toLowerCase():typeof s?.kit=="string"?s.kit.toLowerCase():"",A=d(e,s),I=Jt({dependencies:v,scripts:E,kitName:D});if(Be)he(t,"Bun","high");else {let C=i(e,s??null);C.key==="nestjs"||C.key==="express"||C.key==="fastify"||C.key==="koa"?W(t,C):A.key!=="unknown"?Lt(t,A):C.key!=="unknown"&&C.key!=="node"?W(t,C):he(t,I.framework,I.confidence);}t.venvActive=true;let _=r.join(e,"node_modules");if(await a.pathExists(_))try{let S=(await a.readdir(_)).filter(q=>!q.startsWith(".")&&!q.startsWith("_"));t.depsInstalled=S.length>0;}catch{t.depsInstalled=false;}if(t.depsInstalled||(t.issues.push("Dependencies not installed (node_modules empty or missing)"),t.fixCommands?.push($(e,Be?"bun install":"rapidkit init"))),t.coreInstalled=false,t.projectKind==="frontend"){let C=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local"];if((await Promise.all(C.map(q=>a.pathExists(r.join(e,q))))).some(Boolean))t.hasEnvFile=true;else {let q=r.join(e,".env.example");await a.pathExists(q)&&(t.hasEnvFile=false,t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}}else {let C=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(C),!t.hasEnvFile){let S=r.join(e,".env.example");await a.pathExists(S)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}}if(t.projectKind==="frontend")t.modulesHealthy=await Re(e),t.missingModules=[];else {let C=r.join(e,"src");if(t.modulesHealthy=true,t.missingModules=[],await a.pathExists(C))try{let S=await a.readdir(C);t.modulesHealthy=S.length>0;}catch{t.modulesHealthy=false;}}return await T(e,t,w),t.projectKind==="frontend"?await an(e,t,w,A.key!=="unknown"?A:d(e,s)):await O(e,t),await G(e,t),t}if(ce){let w=await qt(e);he(t,w.framework,w.confidence);let v=r.join(e,".venv");if(await a.pathExists(v)){t.venvActive=true;let I=l$1(v);if(await a.pathExists(I)){try{let{stdout:S}=await execa(I,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:2e3});t.coreInstalled=true,t.coreVersion=S.trim();}catch{t.coreInstalled=false;}let _="fastapi";t.framework==="Django"?_="django":t.framework==="Flask"?_="flask":t.framework==="Python"&&(_="");let C=true;if(_)try{await execa(I,["-c",`import ${_}`],{timeout:2e3}),t.depsInstalled=true,C=false;}catch{C=true;}if(C)try{let S=r.join(v,"lib");if(await a.pathExists(S)){let X=(await a.readdir(S)).find(de=>de.startsWith("python"));if(X){let de=r.join(S,X,"site-packages");if(await a.pathExists(de)){let jt=(await a.readdir(de)).filter(ve=>!ve.startsWith("_")&&!ve.includes("dist-info")&&!["pip","setuptools","wheel","pkg_resources"].includes(ve));t.depsInstalled=jt.length>0;}}}t.depsInstalled||(t.issues.push("Dependencies not installed"),t.fixCommands?.push($(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($(e,"rapidkit init"));let E=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(E),!t.hasEnvFile){let I=r.join(e,".env.example");await a.pathExists(I)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}let D=r.join(e,"src"),A=r.join(e,"modules");if(t.modulesHealthy=true,t.missingModules=[],await a.pathExists(D)){let I=r.join(D,"__init__.py");await a.pathExists(I)||(t.modulesHealthy=false,t.missingModules.push("src/__init__.py"));}if(await a.pathExists(A))try{let I=await mt(A);for(let _ of I){let C=r.join(A,_,"__init__.py");await a.pathExists(C)||(t.modulesHealthy=false,t.missingModules.push(`modules/${_}/__init__.py`));}}catch{}return !t.modulesHealthy&&t.missingModules.length>0&&t.issues.push(`Missing module init files: ${t.missingModules.join(", ")}`),await T(e,t),await O(e,t),await G(e,t),t}if(oe){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=r.join(e,"vendor");t.depsInstalled=await a.pathExists(w),t.depsInstalled||(t.issues.push("PHP dependencies not installed (vendor missing)"),t.fixCommands?.push($(e,"composer install")));let v=r.join(e,".env");if(t.hasEnvFile=await a.pathExists(v),!t.hasEnvFile){let E=r.join(e,".env.example");await a.pathExists(E)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(z(e)));}return await T(e,t),await O(e,t),await G(e,t),t}if(L){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=await a.pathExists(r.join(e,"Gemfile.lock")),v=await a.pathExists(r.join(e,"vendor","bundle"));t.depsInstalled=w||v,t.depsInstalled||(t.issues.push("Ruby dependencies not installed (Gemfile.lock/vendor missing)"),t.fixCommands?.push($(e,"bundle install")));let E=r.join(e,".env");return t.hasEnvFile=await a.pathExists(E),await T(e,t),await O(e,t),await G(e,t),t}if(ge){W(t,i(e,s??null)),t.venvActive=true,t.coreInstalled=false;let w=r.join(e,"obj"),v=r.join(e,"src","obj"),E=r.join(e,"packages.lock.json");t.depsInstalled=await a.pathExists(w)||await a.pathExists(v)||await a.pathExists(E),t.depsInstalled||(t.issues.push(".NET restore/build artifacts not found"),t.fixCommands?.push($(e,"dotnet restore")));let D=r.join(e,".env");return t.hasEnvFile=await a.pathExists(D),await T(e,t),await O(e,t),await G(e,t),t}return he(t,"Unknown","low"),t.issues.push("Unknown project type (no recognized runtime marker files)"),await T(e,t),await O(e,t),await G(e,t),t}async function mt(e){try{return (await a.readdir(e,{withFileTypes:true})).filter(i=>i.isDirectory()).map(i=>i.name)}catch{try{let n=await a.readdir(e),i=[];for(let t of n)try{(await a.stat(r.join(e,t))).isDirectory()&&i.push(t);}catch{continue}return i}catch{return []}}}async function nt(e,n,i){let t=[{dir:e,depth:0}],c=new Set([".git",".rapidkit","node_modules","bin","obj","target"]);for(;t.length>0;){let o=t.shift();if(!o||o.depth>i)continue;let s;try{s=await a.readdir(o.dir,{withFileTypes:true});}catch{continue}for(let d of s){if(d.isFile()&&d.name.toLowerCase().endsWith(n.toLowerCase()))return true;d.isDirectory()&&!c.has(d.name)&&t.push({dir:r.join(o.dir,d.name),depth:o.depth+1});}}return false}async function pe(e){let n=r.join(e,".rapidkit");if(!await a.pathExists(n))return false;let i=["project.json","context.json","file-hashes.json"];for(let t of i)if(await a.pathExists(r.join(n,t)))return true;return false}function ft(e,n){if(n.has(e))return true;let i=e.toLowerCase();return !!(i==="dist"||i.startsWith("dist-")||i.startsWith("dist_")||i==="build"||i.startsWith("build-")||i.startsWith("build_"))}async function cn(e,n,i){let t=new Set,c=[{dir:e,depth:0}];for(;c.length>0;){let o=c.shift();if(!o)break;try{let s=await a.readdir(o.dir);for(let d of s){if(ft(d,i))continue;let u=r.join(o.dir,d),m;try{m=await a.stat(u);}catch{continue}if(m.isDirectory()){if(await pe(u)){t.add(u);continue}o.depth<n&&c.push({dir:u,depth:o.depth+1});}}}catch{continue}}return Array.from(t)}async function me(e){let n=r.resolve(e),i=r.parse(n).root;for(;;){if(await un(n))return n;if(n===i)break;n=r.dirname(n);}return null}async function ln(e){let n=r.resolve(e),i=await me(n),t=i??r.parse(n).root;for(;;){if(await pe(n)||await dn(n)&&(!i||n!==i))return n;if(n===t)break;n=r.dirname(n);}return null}function st(e){let n=r.resolve(e);return process.platform==="darwin"?n.replace(/^\/private(?=\/var\/)/,""):n}async function dn(e){let n=["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 i of n)if(await a.pathExists(r.join(e,i)))return true;return false}async function un(e){let n=[r.join(e,".rapidkit-workspace"),r.join(e,".rapidkit","workspace-marker.json"),r.join(e,".rapidkit","config.json")];return Promise.all(n.map(i=>a.pathExists(i))).then(i=>i.some(Boolean))}function gt(e,n){let i=0,t=0,c=0;return e.forEach(s=>{s.status==="ok"?i++:s.status==="warn"?t++:s.status==="error"&&c++;}),n.forEach(s=>{let d=ne(s),u=s.isGoProject?s.issues.length===0&&s.depsInstalled:s.issues.length===0&&s.venvActive&&s.depsInstalled;if(s.issues.length>0||d>0||!u){t++;return}i++;}),{total:i+t+c,passed:i,warnings:t,errors:c}}function ht(e,n,i={}){let t=[];for(let o of e)t.push({id:o.id,label:o.label,status:o.result.status,scope:"host-system",policyRuleId:"system-status-derived",reason:o.result.details||o.result.message});let c=[...n].sort((o,s)=>{let d=`${o.path||""}|${o.name||""}`.toLowerCase(),u=`${s.path||""}|${s.name||""}`.toLowerCase();return d.localeCompare(u)});for(let o of c){let s=o.issues.length>0,d=ne(o),u=s||d>0?"warn":"ok",m=s?`${o.issues.length} blocking issue(s)`:d>0?`${d} advisory warning(s)`:"Project checks passed";t.push({id:`project:${o.name}`,label:`Project ${o.name}`,status:u,scope:"project-scoped",policyRuleId:s?"project-blocking-issues":d>0?"project-advisory-warnings":"project-checks-passed",reason:m});}if(i.includeWorkspaceAggregateRules){let o=n.reduce((u,m)=>u+m.issues.length,0),s=He(n),d=e.filter(u=>u.result.status==="error").length;t.push({id:"workspace:projects-discovered",label:"Workspace projects discovered",status:n.length>0?"ok":"warn",scope:"workspace-aggregate",policyRuleId:"workspace-project-discovery",reason:n.length>0?`${n.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:o>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-blocking-issues-gate",reason:o>0?`${o} blocking project issue(s) detected.`:"No blocking project issues detected."}),t.push({id:"workspace:advisory-warnings-gate",label:"Workspace advisory warnings gate",status:s>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-advisory-warning-gate",reason:s>0?`${s} advisory warning(s) detected.`:"No advisory warnings detected."});}return t}async function Fe(e,n=true){let i=r.basename(e);try{let g=r.join(e,".rapidkit-workspace");await a.pathExists(g)&&(i=(await a.readJSON(g)).name||i);}catch{try{let g=r.join(e,".rapidkit","config.json");i=(await a.readJSON(g)).workspace_name||i;}catch{}}let[t,c]=await Promise.all([_e(),Ut(e)]),o={workspacePath:e,workspaceName:i,python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore,projects:[]};f.debug(`Workspace scan found ${c.length} project(s)`);let s=await zt(e,c),d=r.join(e,".rapidkit","reports","doctor-workspace-cache.json"),u=n?await Qt(d,s):null;if(u){o.projects=u.projects;for(let g of o.projects)Ae(g,g.path);o.projectScanCached=true,f.debug(`Workspace project health cache hit: ${d}`);}else try{let g=await Promise.all(c.map(y=>we(y)));for(let y of g)Ae(y,y.path);o.projects=g,o.projectScanCached=false,await Xt(d,{schemaVersion:at,signature:s,generatedAt:new Date().toISOString(),projects:g}),f.debug(`Workspace project health cache refreshed: ${d}`);}catch(g){f.debug(`Failed to scan workspace projects: ${g}`);}o.projectScanSignature=s,o.projectScanCachePath=d;let m=[o.python,o.poetry,o.pipx,o.go,o.rapidkitCore];if(o.healthScore=gt(m,o.projects),o.scoreBreakdown=ht([{id:"system-python",label:"Python",result:o.python},{id:"system-poetry",label:"Poetry",result:o.poetry},{id:"system-pipx",label:"pipx",result:o.pipx},{id:"system-go",label:"Go",result:o.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:o.rapidkitCore}],o.projects,{includeWorkspaceAggregateRules:true}),o.scopeProvenance=ut(o.scoreBreakdown),o.rapidkitCore.status==="ok"){let g=o.rapidkitCore.message.match(/([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);g&&(o.coreVersion=g[1]);}let p=r.join(e,".rapidkit","reports","doctor-last-run.json"),f$1=await lt(p,"workspace");return o.driftDelta=Tt(f$1,o),o.evidencePath=await Yt(e,o,u?d:null),o}function ot(e){return {name:e.name,path:e.path,framework:e.framework,frameworkKey:e.frameworkKey,importStack:e.importStack,runtimeFamily:e.runtimeFamily,projectKind:e.projectKind,supportTier:e.supportTier,frameworkConfidence:e.frameworkConfidence,kit:e.kit,venvActive:e.venvActive,depsInstalled:e.depsInstalled,hasEnvFile:e.hasEnvFile,modulesHealthy:e.modulesHealthy,missingModules:e.missingModules,hasTests:e.hasTests,hasDocker:e.hasDocker,hasCodeQuality:e.hasCodeQuality,vulnerabilities:e.vulnerabilities,coreInstalled:e.coreInstalled,coreVersion:e.coreVersion,lastModified:e.lastModified,stats:e.stats,issues:e.issues,fixCommands:e.fixCommands,probes:e.probes,commandCapabilities:e.commandCapabilities}}async function pn(e$1,n){let i=e$1||n.projectPath,t=r.join(i,".rapidkit","reports","doctor-project-last-run.json");try{await a.ensureDir(r.dirname(t));let c=n.project.issues.filter(o=>typeof o=="string"&&o.trim().length>0).slice(0,12);return await a.writeJSON(t,f$1({schemaVersion:b$1,evidenceType:"project",contract:ye(),workspacePath:e$1||null,projectPath:n.projectPath,projectName:n.projectName,healthScore:n.healthScore,system:{python:n.python,poetry:n.poetry,pipx:n.pipx,go:n.go,rapidkitCore:n.rapidkitCore},project:n.project,driftDelta:n.driftDelta,summary:{scopeProvenance:n.scopeProvenance},scoreBreakdown:n.scoreBreakdown??[]},{commandId:"projectDoctor",exitCode:ae(n.healthScore,{}),generatedAt:new Date().toISOString(),blockers:c,runId:e()}),{spaces:2}),t}catch{return}}async function mn(e){let n=await me(e),i=await _e(),t=await we(e,{allowNonRapidkit:true});Ae(t,e);let c=gt([i.python,i.poetry,i.pipx,i.go,i.rapidkitCore],[t]),o={workspacePath:n||void 0,projectPath:e,projectName:r.basename(e),python:i.python,poetry:i.poetry,pipx:i.pipx,go:i.go,rapidkitCore:i.rapidkitCore,project:t,healthScore:c};o.scoreBreakdown=ht([{id:"system-python",label:"Python",result:o.python},{id:"system-poetry",label:"Poetry",result:o.poetry},{id:"system-pipx",label:"pipx",result:o.pipx},{id:"system-go",label:"Go",result:o.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:o.rapidkitCore}],[o.project]),o.scopeProvenance=ut(o.scoreBreakdown);let s=n||e,d=r.join(s,".rapidkit","reports","doctor-project-last-run.json"),u=await lt(d,"project");return o.driftDelta=Ot(u,o),o.evidencePath=await pn(n||void 0,o),o}function F(e,n){let i=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(`${i} ${l.bold(n)}: ${t(e.message)}`),e.paths&&e.paths.length>0&&e.paths.forEach(c=>{let o=c.version?l.cyan(` -> ${c.version}`):"";console.log(` ${l.cyan("\u2022")} ${l.gray(c.location)}: ${l.dim(c.path)}${o}`);}),e.details&&console.log(` ${l.gray(e.details)}`);}function it(e){let n=e.issues.length>0,i=n?"\u26A0\uFE0F":"\u2705",t=n?l.yellow:l.green;if(console.log(`
|
|
2
|
+
${i} ${l.bold("Project")}: ${t(e.name)}`),e.framework){let s=e.framework==="FastAPI"||e.framework==="Django"||e.framework==="Flask"?"\u{1F40D}":e.framework==="NestJS"?"\u{1F985}":e.framework==="Next.js"||e.framework==="Nuxt"||e.framework==="Remix"?"\u25B2":e.framework==="React"||e.framework==="Vite"?"\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(` ${s} 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){let s=e.projectKind==="frontend"?"Source tree":"Modules";e.modulesHealthy?console.log(` \u2705 ${s}: ${l.green("Healthy")}`):e.missingModules&&e.missingModules.length>0?console.log(` \u26A0\uFE0F ${s}: ${l.yellow(`Missing ${e.missingModules.length} init file(s)`)}`):e.projectKind==="frontend"&&console.log(` \u26A0\uFE0F ${s}: ${l.yellow("No application directories detected")}`);}if(e.stats){let s=[];e.stats.modules!==void 0&&s.push(`${e.stats.modules} module${e.stats.modules!==1?"s":""}`),s.length>0&&console.log(` \u{1F4CA} Stats: ${l.cyan(s.join(" \u2022 "))}`);}e.lastModified&&console.log(` \u{1F552} Last Modified: ${l.gray(e.lastModified)}`);let o=[];if(e.hasTests!==void 0&&o.push(e.hasTests?"\u2705 Tests":l.dim("\u2298 No tests")),e.hasDocker!==void 0&&o.push(e.hasDocker?"\u2705 Docker":l.dim("\u2298 No Docker")),e.hasCodeQuality!==void 0){let s=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";o.push(e.hasCodeQuality?`\u2705 ${s}`:l.dim(`\u2298 No ${s}`));}if(o.length>0&&console.log(` ${o.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(s=>{console.log(` \u2022 ${l.yellow(s)}`);}),e.fixCommands&&e.fixCommands.length>0&&(console.log(`
|
|
3
|
+
${l.bold.cyan("\u{1F527} Quick Fix:")}`),e.fixCommands.forEach(s=>{console.log(` ${l.cyan("$")} ${l.white(s)}`);}))),e.probes&&e.probes.length>0){console.log(` ${l.bold("Probe checks:")}`);for(let s of e.probes){let d=s.status==="pass"?"\u2705":s.status==="warn"?"\u26A0\uFE0F":"\u274C";console.log(` ${d} ${s.label}: ${l.gray(s.reason)}`),s.recommendation&&console.log(` ${l.dim("\u21B3")} ${l.gray(s.recommendation)}`);}}if(e.commandCapabilities){let s=e.commandCapabilities;if(console.log(` ${l.bold("Command support:")}`),console.log(` ${l.green("supported")} ${s.supportedCommands.length} \u2022 ${l.yellow("unsupported")} ${s.unsupportedCommands.length} \u2022 ${l.gray("global")} ${s.globalCommands.length}`),s.unsupportedCommands.length>0){let d=s.unsupportedCommands.slice(0,8).join(", "),u=s.unsupportedCommands.length>8?", ...":"";console.log(` ${l.dim("\u21B3")} ${l.gray(`Unsupported here: ${d}${u}`)}`);}}}async function yt(){try{return (await execa("go",["version"],{timeout:a$3(),reject:false})).exitCode===0}catch{return false}}function se(e,n){let i=[new RegExp(`^cd\\s+"([^"]+)"\\s*(?:&&|;)\\s*${n}\\s*$`,"i"),new RegExp(`^cd\\s+'([^']+)'\\s*(?:&&|;)\\s*${n}\\s*$`,"i"),new RegExp(`^cd\\s+(.+?)\\s*(?:&&|;)\\s*${n}\\s*$`,"i")];for(let t of i){let c=e.match(t);if(c?.[1])return {projectPath:c[1].trim()}}return null}function kt(e){return se(e,"cp\\s+\\.env\\.example\\s+\\.env")||se(e,"copy-item\\s+\\.env\\.example\\s+\\.env")}function wt(e){let n=[{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 i of n){let t=se(e,i.pattern);if(t)return {projectPath:t.projectPath,command:i.command,args:i.args}}return null}function Ie(e,n){return /^https?:\/\//i.test(n.trim())?{projectName:e.name,projectPath:e.path,originalCommand:n,kind:"manual-url",risk:"safe",executable:false,reason:"Manual guidance URL"}:kt(n)?{projectName:e.name,projectPath:e.path,originalCommand:n,kind:"env-copy",risk:"safe",executable:true,reason:"Environment seed copy"}:se(n,"rapidkit\\s+init")?{projectName:e.name,projectPath:e.path,originalCommand:n,kind:"rapidkit-init",risk:"guarded",executable:true,reason:"RapidKit initializer may mutate dependencies and configs"}:se(n,"go\\s+mod\\s+tidy")?{projectName:e.name,projectPath:e.path,originalCommand:n,kind:"go-mod-tidy",risk:"guarded",executable:true,reason:"Go module graph reconciliation"}:wt(n)?{projectName:e.name,projectPath:e.path,originalCommand:n,kind:"dependency-sync",risk:"guarded",executable:true,reason:"Dependency synchronization command"}:{projectName:e.name,projectPath:e.path,originalCommand:n,kind:"shell",risk:"invasive",executable:true,reason:"Generic shell command"}}async function Ne(e){let n=e.filter(m=>m.fixCommands&&m.fixCommands.length>0),i=n.flatMap(m=>(m.fixCommands??[]).map(p=>Ie(m,p))),t=null,c=[],o=0,s=0,d=0,u=0;for(let m of i){let p=m.executable,f;m.kind==="go-mod-tidy"&&(t===null&&(t=await yt()),t||(p=false,f="Go toolchain not available")),p&&(o+=1,m.risk==="safe"&&(s+=1),m.risk==="guarded"&&(d+=1),m.risk==="invasive"&&(u+=1)),c.push({...m,executableInCurrentEnvironment:p,blockedReason:f});}return {generatedAt:new Date().toISOString(),fixableProjects:n.length,totalSteps:c.length,executableSteps:o,risk:{safe:s,guarded:d,invasive:u},steps:c}}function rt(e){let n=e instanceof Error?e.message:String(e),i=["ETIMEDOUT","ECONNRESET","ECONNREFUSED","EAI_AGAIN","ENOTFOUND","network","503","504"],t=n.toLowerCase();return i.some(c=>t.includes(c.toLowerCase()))}async function fn(e,n){let i=e.get(n);if(i)return i;let t=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,c=r.basename(n).replace(/[^a-zA-Z0-9._-]/g,"_"),o=r.join(n,".rapidkit","reports","fix-snapshots",`${c}-${t}`);await a.ensureDir(o);let s=[".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 s){let p=r.join(n,m);if(!await a.pathExists(p))continue;let f=r.join(o,m);await a.ensureDir(r.dirname(f)),await a.copy(p,f,{overwrite:true}),d.set(p,f);}let u={snapshotRoot:o,files:d};return e.set(n,u),u}async function gn(e){for(let[n,i]of e.files.entries())await a.pathExists(i)&&(await a.ensureDir(r.dirname(n)),await a.copy(i,n,{overwrite:true}));}async function hn(e){let n=await we(e,{allowNonRapidkit:true});return {issues:n.issues.length,healthy:n.issues.length===0}}async function $e(e){let n=[];for(let i of e){let t=await we(i.path,{allowNonRapidkit:true});for(let c of t.issues)typeof c=="string"&&c.trim()&&n.push(`${i.name}: ${c.trim()}`);}return n.slice(0,24)}async function te(e,n=false,i={}){let t=await Ne(e),c$1=e.filter(h=>h.fixCommands&&h.fixCommands.length>0),o=[],s=i.json===true,d=null,u=t.steps.some(h=>h.kind==="go-mod-tidy"&&!h.executableInCurrentEnvironment),m=new Map;if(c$1.length===0)return s||console.log(l.green(`
|
|
4
|
+
\u2705 No fixes needed - all projects are healthy!`)),n?re({appliedFixes:[],remainingBlockers:[],verifyRecommended:ee}):void 0;if(!s){console.log(l.bold.cyan(`
|
|
5
|
+
\u{1F527} Available Fixes:
|
|
6
|
+
`));for(let h of c$1){let x=h.fixCommands??[];console.log(l.bold(`Project: ${l.yellow(h.name)}`)),x.forEach((b,H)=>{console.log(` ${H+1}. ${l.cyan(b)}`);}),console.log();}}if(i.planOnly){if(i.json){console.log(JSON.stringify(t,null,2));return}console.log(l.bold(`
|
|
7
|
+
\u{1F9ED} Remediation Plan
|
|
8
|
+
`)),console.log(l.gray(`Executable steps: ${t.executableSteps}/${t.totalSteps} | risk: safe=${t.risk.safe}, guarded=${t.risk.guarded}, invasive=${t.risk.invasive}`));for(let h of t.steps){let x=h.executableInCurrentEnvironment?l.green("ready"):l.yellow(`blocked${h.blockedReason?` (${h.blockedReason})`:""}`);console.log(` - ${l.cyan(h.projectName)} [${h.risk}] ${h.originalCommand} ${l.gray(`=> ${x}`)}`);}console.log(l.gray(`
|
|
9
|
+
Use --apply to execute this plan non-interactively, or --fix for interactive confirmation.`));return}let p=t.executableSteps,f=t.risk.safe,g=t.risk.guarded,y=t.risk.invasive;if(p===0)return s||(console.log(l.gray("\u{1F4A1} No automatic fixes can be applied right now.")),u&&console.log(l.gray(" Install Go to enable go mod tidy fixes, then rerun `rapidkit doctor workspace --fix`."))),n?re({appliedFixes:[],remainingBlockers:await $e(c$1),verifyRecommended:ee}):void 0;if(!n){s||console.log(l.gray('\u{1F4A1} Run "npx rapidkit doctor workspace --fix" to apply fixes automatically'));return}if(s||console.log(l.gray(`Risk policy: safe=${f}, guarded=${g}, invasive=${y}. Guarded/invasive fixes use snapshot + rollback.`)),!i.skipConfirmation){let{confirm:h}=await b([{type:"confirm",name:"confirm",message:`Apply ${c$1.reduce((x,b)=>x+(b.fixCommands?.length??0),0)} fix(es)?`,default:false}]);if(!h)return s||console.log(l.yellow(`
|
|
10
|
+
\u26A0\uFE0F Fixes cancelled by user`)),re({appliedFixes:[],remainingBlockers:await $e(c$1),verifyRecommended:ee})}s||console.log(l.bold.cyan(`
|
|
11
|
+
\u{1F680} Applying fixes...
|
|
12
|
+
`));let k=new Set;for(let h of c$1){let x=h.fixCommands??[];s||console.log(l.bold(`Fixing ${l.cyan(h.name)}...`));for(let b of x){let H=Ie(h,b),fe=`${h.path}::${b}`;if(!k.has(fe)){k.add(fe);try{if(console.log(l.gray(` $ ${b}`)),H.kind==="manual-url"){console.log(l.yellow(` \u2139 Manual action required: open ${b}`)),console.log(l.green(` \u2705 Recorded as guidance
|
|
13
|
+
`));continue}if(!H.executable){console.log(l.yellow(" \u26A0 Step is non-executable by policy")),console.log(l.green(` \u2705 Recorded as guidance
|
|
14
|
+
`));continue}H.risk!=="safe"&&await fn(m,H.projectPath);let K=kt(b);if(K){let L=r.join(K.projectPath,".env.example"),M=r.join(K.projectPath,".env");if(!await a.pathExists(L))throw new Error(`.env.example not found at ${L}`);if(await a.pathExists(M)){console.log(l.green(` \u2705 .env already exists
|
|
15
|
+
`));continue}await a.copy(L,M,{overwrite:false,errorOnExist:false}),console.log(l.green(` \u2705 Success
|
|
16
|
+
`));continue}let U=se(b,"rapidkit\\s+init");if(U){await execa("rapidkit",["init"],{cwd:U.projectPath,shell:c(),stdio:"inherit"}),console.log(l.green(` \u2705 Success
|
|
17
|
+
`));continue}let Q=se(b,"go\\s+mod\\s+tidy");if(Q){if(d===null&&(d=await yt()),!d){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
|
|
18
|
+
`));continue}await execa("go",["mod","tidy"],{cwd:Q.projectPath,shell:c(),stdio:"inherit"}),console.log(l.green(` \u2705 Success
|
|
19
|
+
`));continue}let V=wt(b);if(V){let M;for(let ie=1;ie<=2;ie+=1)try{await execa(V.command,V.args,{cwd:V.projectPath,shell:c(),stdio:"inherit"}),M=null;break}catch(le){if(M=le,ie<2&&rt(le)){console.log(l.yellow(` \u26A0 Retrying dependency sync (${ie}/1)...`));continue}throw le}if(M)throw M;console.log(l.green(` \u2705 Success
|
|
20
|
+
`));continue}let ce=H.kind==="shell"?2:1,oe;for(let L=1;L<=ce;L+=1)try{await execa(b,{shell:true,stdio:"inherit"}),oe=null;break}catch(M){if(oe=M,L<ce&&rt(M)){console.log(l.yellow(` \u26A0 Retrying command (${L}/${ce-1})...`));continue}throw M}if(oe)throw oe;s||console.log(l.green(` \u2705 Success
|
|
21
|
+
`)),o.push({path:H.projectPath,action:H.kind,outcome:"applied",projectName:h.name,command:b});}catch(K){let U=Ie(h,b);if(U.risk!=="safe"){let Q=m.get(U.projectPath);if(Q)try{await gn(Q),s||console.log(l.yellow(" \u21A9 Rolled back snapshot after failed fix"));}catch(V){s||console.log(l.red(` \u274C Rollback failed: ${V instanceof Error?V.message:String(V)}`));}}s||console.log(l.red(` \u274C Failed: ${K instanceof Error?K.message:String(K)}
|
|
22
|
+
`)),o.push({path:U.projectPath,action:U.kind,outcome:"failed",projectName:h.name,command:b,detail:K instanceof Error?K.message:String(K)});}}}try{let b=await hn(h.path);console.log(b.healthy?l.green(` \u2705 Post-fix verification passed for ${h.name}`):l.yellow(` \u26A0 Post-fix verification: ${b.issues} issue(s) remain for ${h.name}`));}catch(b){console.log(l.yellow(` \u26A0 Post-fix verification skipped: ${b instanceof Error?b.message:String(b)}`));}}if(s||console.log(l.bold.green(`
|
|
23
|
+
\u2705 Fix process completed!`)),n)return re({appliedFixes:o,remainingBlockers:await $e(c$1),verifyRecommended:ee})}function ae(e,n){if(!n.strict&&!n.ci)return 0;let i=Number(e?.errors??0),t=Number(e?.warnings??0);return i>0?1:n.ci&&t>0?2:n.strict&&t>0?1:0}async function Wn(e={}){let n=!!(e.fix||e.plan||e.apply),i=!e.workspace&&!e.project&&n?await me(process.cwd()):null,t=e.workspace||!!i,c=!!e.project&&!t;if(e.json||console.log(l.bold.cyan(`
|
|
24
|
+
\u{1FA7A} RapidKit Health Check
|
|
25
|
+
`)),t){let o=i??await me(process.cwd());o||(f.error("No RapidKit workspace found in current directory or parents"),f.info('Run this command from within a workspace, or use "rapidkit doctor" for system check'),process.exit(1)),e.json||(i&&console.log(l.gray("\u2139\uFE0F Detected workspace context; enabling workspace checks for --fix")),console.log(l.bold(`Workspace: ${l.cyan(r.basename(o))}`)),console.log(l.gray(`Path: ${o}`)));let s=await Fe(o);if(e.json||(s.projectScanCached&&console.log(l.gray(`\u2139\uFE0F Reused cached project scan${s.projectScanCachePath?` (${r.basename(s.projectScanCachePath)})`:""}`)),s.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence saved: ${s.evidencePath}`))),e.json){let p,f=e.plan?await Ne(s.projects):void 0;(e.fix||e.apply)&&!e.plan&&(p=await te(s.projects,true,{skipConfirmation:e.apply===true||e.fix===true,json:true})??re({appliedFixes:[],remainingBlockers:[],verifyRecommended:ee}),s=await Fe(o,false));let g={contract:ye(),workspace:{name:r.basename(o),path:o},cache:{projectScan:s.projectScanCached??false,projectScanPath:s.projectScanCachePath,evidencePath:s.evidencePath},healthScore:s.healthScore,system:{python:s.python,poetry:s.poetry,pipx:s.pipx,rapidkitCore:s.rapidkitCore,versions:{core:s.coreVersion,npm:s.npmVersion}},projects:s.projects.map(y=>ot(y)),summary:{totalProjects:s.projects.length,totalIssues:s.projects.reduce((y,k)=>y+k.issues.length,0),projectAdvisoryWarningProjects:De(s.projects),projectAdvisoryWarnings:He(s.projects),hasSystemErrors:[s.python,s.rapidkitCore].some(y=>y.status==="error"),scopeProvenance:s.scopeProvenance},driftDelta:s.driftDelta,scoreBreakdown:s.scoreBreakdown??[],...f?{remediationPlan:f}:{},...p?{appliedFixes:p.appliedFixes,remainingBlockers:p.remainingBlockers,verifyRecommended:p.verifyRecommended,fixResult:p}:{}};return e.quiet||console.log(JSON.stringify(g,null,2)),ae(s.healthScore,e)}if(s.healthScore){let p=s.healthScore,f=Math.round(p.passed/p.total*100),g=f>=80?l.green:f>=50?l.yellow:l.red,y="\u2588".repeat(Math.floor(f/5))+"\u2591".repeat(20-Math.floor(f/5));console.log(l.bold(`
|
|
26
|
+
\u{1F4CA} Health Score:`)),console.log(` ${g(`${f}%`)} ${l.gray(y)}`),console.log(` ${l.green(`\u2705 ${p.passed} passed`)} ${l.gray("|")} ${l.yellow(`\u26A0\uFE0F ${p.warnings} warnings`)} ${l.gray("|")} ${l.red(`\u274C ${p.errors} errors`)}`);}if(console.log(l.bold(`
|
|
27
|
+
|
|
28
|
+
System Tools:
|
|
29
|
+
`)),F(s.python,"Python"),F(s.poetry,"Poetry"),F(s.pipx,"pipx"),F(s.go,"Go"),F(s.rapidkitCore,"RapidKit Core"),s.coreVersion&&s.npmVersion){let p=s.coreVersion.split(".")[1],f=s.npmVersion.split(".")[1];p!==f&&(console.log(l.yellow(`
|
|
30
|
+
\u26A0\uFE0F Version mismatch: Core ${s.coreVersion} / CLI ${s.npmVersion}`)),console.log(l.gray(" Consider updating to matching versions for best compatibility")));}s.projects.length>0?(console.log(l.bold(`
|
|
31
|
+
\u{1F4E6} Projects (${s.projects.length}):`)),s.projects.forEach(p=>it(p))):(console.log(l.bold(`
|
|
32
|
+
\u{1F4E6} Projects:`)),console.log(l.gray(" No RapidKit projects found in workspace")));let d=s.projects.reduce((p,f)=>p+f.issues.length,0),u=De(s.projects),m=[s.python,s.rapidkitCore].some(p=>p.status==="error");if(m||d>0||u>0){let p=u>0?` and ${u} advisory warning project(s)`:"";if(console.log(l.bold.yellow(`
|
|
33
|
+
\u26A0\uFE0F Found ${d} project issue(s)${p}`)),m&&console.log(l.bold.red("\u274C System requirements not met")),e.plan)await te(s.projects,false,{planOnly:true,json:e.json});else if(e.fix||e.apply){if(await te(s.projects,true,{skipConfirmation:e.apply===true}),!e.json){let f=await Fe(o,false),g=f.projects.reduce((k,h)=>k+h.issues.length,0),y=[f.python,f.rapidkitCore].some(k=>k.status==="error");y||g>0?(console.log(l.bold.yellow(`
|
|
34
|
+
\u26A0\uFE0F Post-fix verification found ${g} remaining issue(s)`)),y&&console.log(l.bold.red("\u274C System requirements still not met"))):console.log(l.bold.green(`
|
|
35
|
+
\u2705 Post-fix verification passed. Workspace is healthy.`)),f.projectScanCached&&console.log(l.gray(`\u2139\uFE0F Reused cached project scan${f.projectScanCachePath?` (${r.basename(f.projectScanCachePath)})`:""}`)),f.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence refreshed: ${f.evidencePath}`));}}else d>0&&await te(s.projects,false);}else console.log(l.bold.green(`
|
|
36
|
+
\u2705 All checks passed! Workspace is healthy.`));return ae(s.healthScore,e)}else if(c){let o=await ln(process.cwd());o||(await me(process.cwd())?(f.error("No backend project found in current directory within this workspace"),f.info("Run this command from inside a project directory in the workspace")):f.error("No RapidKit project found in current directory or parents"),f.info('Run this command from within a project, or use "rapidkit doctor workspace" for workspace checks'),process.exit(1));let s=await mn(o),d=s.workspacePath?st(s.workspacePath):null,u=st(s.project.path);if(e.json){let x=e.plan?await Ne([s.project]):void 0,b={contract:ye(),scope:"project",workspace:d?{name:r.basename(d),path:d}:null,project:{...ot(s.project),path:u},evidencePath:s.evidencePath,healthScore:s.healthScore,system:{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore},summary:{totalProjects:1,totalIssues:s.project.issues.length,projectAdvisoryWarningProjects:ne(s.project)>0?1:0,projectAdvisoryWarnings:ne(s.project),hasSystemErrors:[s.python,s.rapidkitCore].some(H=>H.status==="error"),scopeProvenance:s.scopeProvenance},driftDelta:s.driftDelta,scoreBreakdown:s.scoreBreakdown??[],...x?{remediationPlan:x}:{}};return e.quiet||console.log(JSON.stringify(b,null,2)),ae(s.healthScore,e)}console.log(l.bold(`Project: ${l.cyan(r.basename(o))}`)),console.log(l.gray(`Path: ${o}`)),s.workspacePath&&console.log(l.gray(`Workspace: ${r.basename(s.workspacePath)}`)),s.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence saved: ${s.evidencePath}`));let m=s.healthScore,p=m.total>0?Math.round(m.passed/m.total*100):0,f$1=p>=80?l.green:p>=50?l.yellow:l.red,g="\u2588".repeat(Math.floor(p/5))+"\u2591".repeat(20-Math.floor(p/5));console.log(l.bold(`
|
|
37
|
+
\u{1F4CA} Health Score:`)),console.log(` ${f$1(`${p}%`)} ${l.gray(g)}`),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`)}`),console.log(l.bold(`
|
|
38
|
+
|
|
39
|
+
System Tools:
|
|
40
|
+
`)),F(s.python,"Python"),F(s.poetry,"Poetry"),F(s.pipx,"pipx"),F(s.go,"Go"),F(s.rapidkitCore,"RapidKit Core"),console.log(l.bold(`
|
|
41
|
+
\u{1F4E6} Project (1):`)),it(s.project);let y=[s.python,s.rapidkitCore].some(x=>x.status==="error"),k=s.project.issues.length,h=ne(s.project);if(y||k>0||h>0){let x=h>0?` and ${h} advisory warning(s)`:"";console.log(l.bold.yellow(`
|
|
42
|
+
\u26A0\uFE0F Found ${k} project issue(s)${x}`)),y&&console.log(l.bold.red("\u274C System requirements not met")),e.plan?await te([s.project],false,{planOnly:true,json:e.json}):e.fix||e.apply?await te([s.project],true,{skipConfirmation:e.apply===true}):k>0&&await te([s.project],false);}else console.log(l.bold.green(`
|
|
43
|
+
\u2705 All checks passed! Project is healthy.`));return ae(s.healthScore,e)}else {console.log(l.bold(`System Tools:
|
|
44
|
+
`));let o=await _e(),s=o.python,d=o.poetry,u=o.pipx,m=o.go,p=o.rapidkitCore;F(s,"Python"),F(d,"Poetry"),F(u,"pipx"),F(m,"Go"),F(p,"RapidKit Core"),[s,p].some(y=>y.status==="error")?(console.log(l.bold.red(`
|
|
45
|
+
\u274C Some required tools are missing`)),(e.fix||e.apply)&&console.log(l.gray(`
|
|
46
|
+
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(l.gray(`
|
|
47
|
+
Tip: Run "rapidkit doctor workspace" for workspace-wide checks, or "rapidkit doctor project" for the current project`))):(console.log(l.bold.green(`
|
|
48
|
+
\u2705 All required tools are installed!`)),(e.fix||e.apply)&&console.log(l.gray(`
|
|
49
|
+
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(l.gray(`
|
|
50
|
+
Tip: Run "rapidkit doctor workspace" for workspace-wide checks, or "rapidkit doctor project" for the current project`))),console.log("");let g=[s,p].filter(y=>y.status==="error").length;return (e.strict||e.ci)&&g>0?1:0}}export{ae as a,Wn as b};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var o="workspace-explain.v1",f=["project","release-blocked","blocker","trace"];function i(t){let r=t.trim();if(!r)return null;if(r==="release-blocked")return {kind:"release-blocked"};if(r.startsWith("project:")){let e=r.slice(8).trim();return e?{kind:"project",project:e}:null}if(r.startsWith("blocker:")){let e=r.slice(8).trim();return e?{kind:"blocker",blockerId:e}:null}if(r.startsWith("trace:")){let e=r.slice(6).trim();return e?{kind:"trace",diffRef:e}:null}return {kind:"project",project:r}}function g(t){let r=t.trim();if(!r)return null;if(r.startsWith("trace:")){let n=i(r);return n?.kind==="trace"?n:null}let e=r.replace(/\\/g,"/").trim().toLowerCase();return e.endsWith(".json")||e.includes("workspace-model-diff")||e.startsWith(".rapidkit/")||e.includes("/.rapidkit/")?{kind:"trace",diffRef:r}:null}function u(t){if(!t||typeof t!="object"||Array.isArray(t))return false;let r=t;return r.schemaVersion===o&&typeof r.generatedAt=="string"&&typeof r.summary=="string"&&Array.isArray(r.sections)&&r.target!=null&&typeof r.target=="object"&&!Array.isArray(r.target)&&typeof r.target.kind=="string"}export{o as a,f as b,i as c,g as d,u as e};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {c}from'./chunk-NFUXULIF.js';import {a}from'./chunk-A5FBGRJA.js';import {a as a$1}from'./chunk-VKLL63TL.js';import {b}from'./chunk-Q2KZIBV4.js';import {
|
|
1
|
+
import {c}from'./chunk-NFUXULIF.js';import {a}from'./chunk-A5FBGRJA.js';import {a as a$1}from'./chunk-VKLL63TL.js';import {b}from'./chunk-Q2KZIBV4.js';import {p}from'./chunk-WRMCPKGA.js';import {promises}from'fs';import o from'path';import i from'chalk';import N from'ora';import {execa}from'execa';function B(e){let t=a(e.path),r=Array.isArray(e.projects)?e.projects:[],a$1=[],s=new Set;for(let p of r){if(!p||typeof p.name!="string"||typeof p.path!="string")continue;let n=a(p.path);s.has(n)||(s.add(n),a$1.push({name:p.name,path:n}));}return {name:e.name,path:t,mode:e.mode,projects:a$1}}function P(e){let t=[],r=new Set;for(let a of e.workspaces||[]){if(!a||typeof a.name!="string"||typeof a.path!="string")continue;let s=B(a);r.has(s.path)||(r.add(s.path),t.push(s));}return {workspaces:t}}async function F(e){try{let t=await promises.readFile(e,"utf8"),r=JSON.parse(t);if(r&&Array.isArray(r.workspaces))return P(r)}catch{}return {workspaces:[]}}async function T(e,t){try{let r=a(e),a$1=p(),s=o.join(a$1,"workspaces.json");await promises.mkdir(a$1,{recursive:true});let p$1={name:t,path:r,mode:"full",projects:[]};for(let n=0;n<3;n+=1){let c=await F(s);if(c.workspaces.some(k=>k.path===r)||(c.workspaces.push(p$1),await promises.writeFile(s,JSON.stringify(c,null,2)),(await F(s)).workspaces.some(k=>k.path===r)))return}console.warn(i.gray("Note: Could not register workspace in shared registry"));}catch{console.warn(i.gray("Note: Could not register workspace in shared registry"));}}async function ne(e,t=false){let r=a(e),a$1={workspacePath:r,workspaceFound:false,added:[],skipped:0};try{let s=p(),p$1=o.join(s,"workspaces.json"),n={workspaces:[]};try{let f=await promises.readFile(p$1,"utf8"),h=JSON.parse(f);h&&Array.isArray(h.workspaces)&&(n=P(h));}catch{return t||console.log("\u26A0\uFE0F Workspace registry not found"),a$1}let c=n.workspaces.find(f=>f.path===r);if(!c)return t||console.log("\u26A0\uFE0F Workspace not registered in registry"),a$1;Array.isArray(c.projects)||(c.projects=[]);let l=0,k=0,g=[],m=[e],y=new Set;for(;m.length>0;){let f=m.shift();if(!f||y.has(f))continue;y.add(f);let h=await promises.readdir(f,{withFileTypes:true});for(let w of h){if(!w.isDirectory()||w.name.startsWith(".")||["node_modules","dist","build","target","coverage","htmlcov"].includes(w.name))continue;let b=o.join(f,w.name),u=a(b),$=o.join(u,".rapidkit","context.json"),W=o.join(u,".rapidkit","project.json");try{let S=false;try{await promises.access($),S=true;}catch{await promises.access(W),S=true;}if(S){let v=o.basename(u);c.projects.some(_=>_.path===u||_.name===v)?k++:(c.projects.push({name:v,path:u}),l++,g.push(u),t||console.log(`\u2714 Added: ${o.relative(e,u)}`));continue}}catch{}m.push(b);}}return l>0?(await promises.writeFile(p$1,JSON.stringify(n,null,2)),t||console.log(`
|
|
2
2
|
\u2705 Synced ${l} project(s) to registry`)):t||console.log(`
|
|
3
|
-
\u2705 All projects already registered (${k} found)`),{workspacePath:r,workspaceFound:true,added:g,skipped:k}}catch(s){return t||console.error("\u274C Failed to sync projects:",s.message),a$1}}async function se(e,t,r){try{let a$1=a(e),s=a(r),p=
|
|
3
|
+
\u2705 All projects already registered (${k} found)`),{workspacePath:r,workspaceFound:true,added:g,skipped:k}}catch(s){return t||console.error("\u274C Failed to sync projects:",s.message),a$1}}async function se(e,t,r){try{let a$1=a(e),s=a(r),p$1=p(),n=o.join(p$1,"workspaces.json"),c={workspaces:[]};try{let m=await promises.readFile(n,"utf8"),y=JSON.parse(m);y&&Array.isArray(y.workspaces)&&(c=P(y));}catch{return}let l=c.workspaces.find(m=>m.path===a$1);if(!l)return;Array.isArray(l.projects)||(l.projects=[]);let k=l.projects.findIndex(m=>m.path===s||m.name===t),g={name:t,path:s};if(k>=0){let m=l.projects[k];(m.name!==g.name||m.path!==g.path)&&(l.projects[k]=g,await promises.writeFile(n,JSON.stringify(c,null,2)));}else l.projects.push({name:t,path:s}),await promises.writeFile(n,JSON.stringify(c,null,2));}catch{}}async function ce(e,t){let r=N("Creating RapidKit workspace...").start();try{await promises.mkdir(e,{recursive:true}),await promises.mkdir(o.join(e,".rapidkit"),{recursive:true});let a={workspace_name:t.name,author:t.author,rapidkit_version:b(),created_at:new Date().toISOString(),type:"workspace"};await promises.writeFile(o.join(e,".rapidkit","config.json"),JSON.stringify(a,null,2));let{syncWorkspaceFoundationFiles:s}=await import('./create-RNP5ACQL.js');await s(e,{workspaceName:t.name,installMethod:"venv",writeMarker:true,writeGitignore:false,onlyIfMissing:true});let{publishWorkspaceRegistrySummary:p}=await import('./workspace-registry-summary-X5WRUU3T.js');await p(e);let n=z();await promises.writeFile(o.join(e,"rapidkit"),n),await promises.chmod(o.join(e,"rapidkit"),493);let c=U();await promises.writeFile(o.join(e,"rapidkit.cmd"),c);let l=J(t.name);if(await promises.writeFile(o.join(e,"README.md"),l),await promises.writeFile(o.join(e,".gitignore"),`# RapidKit workspace
|
|
4
4
|
.env
|
|
5
5
|
.env.*
|
|
6
6
|
!.env.example
|
|
@@ -614,7 +614,7 @@ ${i.bold("\u{1F310} API endpoints:")}
|
|
|
614
614
|
http://localhost:8000/examples/notes # Example API
|
|
615
615
|
|
|
616
616
|
${i.gray("\u{1F4A1} Tip: Install globally (npm i -g rapidkit) to use without npx")}
|
|
617
|
-
`);}catch(p){throw s.fail(`Failed to create ${a} project`),p}}async function O(e,t,r){let a=await promises.readdir(e,{withFileTypes:true});for(let s of a){let p=o.join(e,s.name),n=s.name.replace(/\.j2$/,""),c=o.join(t,n);if(s.isDirectory())await promises.mkdir(c,{recursive:true}),await O(p,c,r);else {let l=await promises.readFile(p,"utf-8");s.name.endsWith(".j2")&&(l=K(l,r)),await promises.writeFile(c,l),(n==="rapidkit"||n==="activate"||n.endsWith(".py")&&c.includes(".rapidkit"))&&await promises.chmod(c,493);}}}function K(e,t){let r=e;for(let[a,s]of Object.entries(t)){let p=new RegExp(`\\{\\{\\s*${a}\\s*\\}\\}`,"g");r=r.replace(p,String(s));let n=new RegExp(`\\{\\{\\s*${a}\\s*\\|\\s*replace\\s*\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]*)['"]\\s*\\)\\s*\\}\\}`,"g");r=r.replace(n,(k,g,m)=>String(s).replace(new RegExp(g,"g"),m));let c=new RegExp(`\\{\\{\\s*${a}\\s*\\|\\s*lower\\s*\\}\\}`,"g");r=r.replace(c,String(s).toLowerCase());let l=new RegExp(`\\{\\{\\s*${a}\\s*\\|\\s*replace\\s*\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]*)['"]\\s*\\)\\s*\\|\\s*lower\\s*\\}\\}`,"g");r=r.replace(l,(k,g,m)=>String(s).replace(new RegExp(g,"g"),m).toLowerCase());}return r}async function de(){let e=
|
|
617
|
+
`);}catch(p){throw s.fail(`Failed to create ${a} project`),p}}async function O(e,t,r){let a=await promises.readdir(e,{withFileTypes:true});for(let s of a){let p=o.join(e,s.name),n=s.name.replace(/\.j2$/,""),c=o.join(t,n);if(s.isDirectory())await promises.mkdir(c,{recursive:true}),await O(p,c,r);else {let l=await promises.readFile(p,"utf-8");s.name.endsWith(".j2")&&(l=K(l,r)),await promises.writeFile(c,l),(n==="rapidkit"||n==="activate"||n.endsWith(".py")&&c.includes(".rapidkit"))&&await promises.chmod(c,493);}}}function K(e,t){let r=e;for(let[a,s]of Object.entries(t)){let p=new RegExp(`\\{\\{\\s*${a}\\s*\\}\\}`,"g");r=r.replace(p,String(s));let n=new RegExp(`\\{\\{\\s*${a}\\s*\\|\\s*replace\\s*\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]*)['"]\\s*\\)\\s*\\}\\}`,"g");r=r.replace(n,(k,g,m)=>String(s).replace(new RegExp(g,"g"),m));let c=new RegExp(`\\{\\{\\s*${a}\\s*\\|\\s*lower\\s*\\}\\}`,"g");r=r.replace(c,String(s).toLowerCase());let l=new RegExp(`\\{\\{\\s*${a}\\s*\\|\\s*replace\\s*\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]*)['"]\\s*\\)\\s*\\|\\s*lower\\s*\\}\\}`,"g");r=r.replace(l,(k,g,m)=>String(s).replace(new RegExp(g,"g"),m).toLowerCase());}return r}async function de(){let e=p(),t=o.join(e,"workspaces.json");if(!await promises.stat(t).catch(()=>null)){console.log(i.yellow(`
|
|
618
618
|
\u26A0\uFE0F No workspaces registered yet.
|
|
619
619
|
`)),console.log(i.gray(`Create a workspace with: npx rapidkit <workspace-name>
|
|
620
620
|
`));return}try{let r=await promises.readFile(t,"utf8"),a=JSON.parse(r);if(!a||typeof a!="object"||!Array.isArray(a.workspaces)){console.log(i.yellow(`
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {j,h as h$1,g}from'./chunk-EN6YCX36.js';import {a as a$1}from'./chunk-HTYMXMQM.js';import {c}from'./chunk-S5KTATOU.js';import {a}from'./chunk-3PTJID76.js';import de from'crypto';import f from'path';import y from'fs-extra';import {spawnSync}from'child_process';function A(e,t){let r=spawnSync("git",t,{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"]});return r.status!==0?{ok:false,stdout:""}:{ok:true,stdout:(r.stdout??"").trim()}}function pe(e){let t=[],r=[],n=[];for(let c of e.split(`
|
|
2
|
+
`)){if(!c.trim())continue;let a=c.slice(0,2),i=c.slice(3).trim();if(i){if(a==="??"){r.push(i);continue}a.includes("D")&&n.push(i),t.push(i);}}return {changedFiles:[...new Set(t)].sort(),untrackedFiles:[...new Set(r)].sort(),deletedFiles:[...new Set(n)].sort()}}function z(e,t){let r={available:false,dirty:false,changedFiles:[],untrackedFiles:[],deletedFiles:[]},n=A(e,["rev-parse","--is-inside-work-tree"]);if(!n.ok||n.stdout!=="true")return r;let c=A(e,["rev-parse","--abbrev-ref","HEAD"]),a=A(e,["rev-parse","HEAD"]),i=A(e,["status","--porcelain=v1","--untracked-files=all"]),p=pe(i.stdout),m=p.changedFiles.length>0||p.untrackedFiles.length>0||p.deletedFiles.length>0;return {available:true,branch:c.ok?c.stdout:void 0,commit:a.ok?a.stdout:void 0,ref:t?.ref,dirty:m,changedFiles:p.changedFiles,untrackedFiles:p.untrackedFiles,deletedFiles:p.deletedFiles}}var X="workspace-model-snapshot.v1",V="workspace-model-diff.v1",E=".rapidkit/reports/workspace-model-snapshot.json",Z=".rapidkit/reports/workspace-model-diff-last-run.json",le="workspace-impact.v1",me=".rapidkit/reports/workspace-impact-last-run.json";function ee(e){let t=e.trim().toLowerCase();return t==="git"||t.startsWith("git:")}function fe(e){let t=e.trim();return t.toLowerCase()==="git"?"HEAD":t.toLowerCase().startsWith("git:")&&t.slice(4).trim()||"HEAD"}function H(e){if(Array.isArray(e))return e.map(t=>H(t));if(e&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=H(e[r]);return t}return e}function k(e){return JSON.stringify(H(e))}function x(e){let{runId:t,...r}=e,n={...r,generatedAt:"<ignored>",graph:e.graph?{...e.graph,generatedAt:"<ignored>"}:void 0,validation:e.validation?{...e.validation,issues:e.validation.issues.map(c=>({...c})).sort((c,a)=>{let i=`${c.severity}:${c.code}:${c.target}:${c.message}`,p=`${a.severity}:${a.code}:${a.target}:${a.message}`;return i.localeCompare(p)})}:void 0};return de.createHash("sha256").update(k(n)).digest("hex")}function te(e,t){return f.isAbsolute(t)?t:f.join(e,t)}async function ue(e){let t=await y.readJson(e);if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`Workspace model input is not a JSON object: ${e}`);let r=t;if(r.schemaVersion===X){let n=r;if(!n.model||n.model.schemaVersion!==g)throw new Error(`Invalid workspace model snapshot: ${e}`);return {model:n.model,hash:n.modelHash||x(n.model)}}if(r.schemaVersion===g){let n=r;return {model:n,hash:x(n)}}throw r.schemaVersion===V?new Error(`workspace diff --from received a diff report (${f.basename(e)}). Use a workspace model snapshot or model report as baseline, e.g. ${E}. To analyze an existing diff report, run: npx rapidkit workspace impact --from ${f.basename(e)} --json`):new Error(`Unsupported workspace model input schema: ${String(r.schemaVersion)}`)}async function ge(e){let t=await y.readJson(e);if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`Workspace diff input is not a JSON object: ${e}`);let r=t;if(r.schemaVersion!==V)return null;let n=r;if(!n.currentModel||n.currentModel.schemaVersion!==g||!n.summary||!Array.isArray(n.changes))throw new Error(`Invalid workspace model diff report: ${e}`);return n}async function Ge(e){let t=e.model??await j({workspacePath:e.workspacePath,includeAbsolutePaths:e.includeAbsolutePaths,includeEvidence:e.includeEvidence,observableScanDepth:e.observableScanDepth,now:e.now});return {schemaVersion:X,generatedAt:(e.now??new Date).toISOString(),modelHash:x(t),modelRef:h$1,model:t}}async function Ne(e,t){let r=f.join(t,E);return await y.ensureDir(f.dirname(r)),await y.writeJson(r,a(e),{spaces:2}),r}function D(e){return {name:e.name,path:e.path,kind:e.kind,runtime:e.runtime,framework:e.framework,generator:e.generator,supportTier:e.supportTier,commands:e.commands,importantFiles:e.importantFiles}}function h(e,t){e.push(t);}function ke(e,t){let r=[],n=["name","profile","type"],c=["workspaceType","surfaces","runtimeFamilies","businessCapabilities"];for(let a of n){let i=e.workspace[a],p=t.workspace[a];k(i)!==k(p)&&h(r,{type:"workspace.changed",severity:"info",target:`workspace.${a}`,message:`Workspace metadata field changed: ${String(a)}`,before:i,after:p});}for(let a of c){let i=e.identity[a],p=t.identity[a];k(i)!==k(p)&&h(r,{type:"workspace.changed",severity:"info",target:`identity.${a}`,message:`Workspace identity field changed: ${String(a)}`,before:i,after:p});}return k(e.policies)!==k(t.policies)&&h(r,{type:"workspace.changed",severity:"warning",target:"policies",message:"Workspace policy summary changed.",before:e.policies,after:t.policies}),k(e.evidence)!==k(t.evidence)&&h(r,{type:"workspace.changed",severity:"info",target:"evidence",message:"Workspace evidence summary changed.",before:e.evidence,after:t.evidence}),k(e.discovery)!==k(t.discovery)&&h(r,{type:"workspace.changed",severity:"info",target:"discovery",message:"Workspace discovery settings changed.",before:e.discovery,after:t.discovery}),e.contracts.exists!==t.contracts.exists&&h(r,{type:"workspace.changed",severity:t.contracts.exists?"info":"warning",target:t.contracts.workspaceContractPath,message:"Workspace contract presence changed.",before:e.contracts.exists,after:t.contracts.exists}),r}function he(e,t){let r=e.validation??null,n=t.validation??null;return k(r)===k(n)?[]:[{type:"validation.changed",severity:n?.status==="failed"?"critical":"warning",target:"validation",message:"Workspace model validation changed.",before:r,after:n}]}function we(e,t){let r=[],n=new Map(e.projects.map(a=>[a.path,a])),c=new Map(t.projects.map(a=>[a.path,a]));for(let[a,i]of c.entries()){let p=n.get(a);if(!p){h(r,{type:"project.added",severity:"info",target:a,message:`Project added: ${i.name}`,after:D(i)});continue}let m=D(p),l=D(i);if(k(m)!==k(l)){let g=p.runtime!==i.runtime||p.framework!==i.framework;h(r,{type:"project.changed",severity:g?"warning":"info",target:a,message:`Project changed: ${i.name}`,before:m,after:l});}}for(let[a,i]of n.entries())c.has(a)||h(r,{type:"project.removed",severity:"warning",target:a,message:`Project removed: ${i.name}`,before:D(i)});return r.sort((a,i)=>`${a.type}:${a.target}`.localeCompare(`${i.type}:${i.target}`))}async function ye(e){let t=f.resolve(e.workspacePath),r=ee(e.fromPath),n=r?fe(e.fromPath):void 0,c=e.fromPath;if(r){let u=f.join(t,E);if(!await y.pathExists(u))throw new Error("Git-aware workspace diff requires an existing snapshot at .rapidkit/reports/workspace-model-snapshot.json. Run: npx rapidkit workspace snapshot --json");c=E;}let a=te(t,c),i=await ue(a),p=e.model??await j({workspacePath:t,includeAbsolutePaths:e.includeAbsolutePaths,includeEvidence:e.includeEvidence,observableScanDepth:e.observableScanDepth,now:e.now}),m=x(p),l=[...ke(i.model,p),...we(i.model,p),...he(i.model,p)],g;e.includeGitObservation!==false&&(g=e.gitObservation??z(t,{ref:n}),g.available&&je(l,g,p));let v=l.filter(u=>u.type.startsWith("git.")).length,R=i.hash!==m,W=r?`git:${n??"HEAD"}`:f.relative(t,a).split(f.sep).join("/");return {schemaVersion:V,generatedAt:(e.now??new Date).toISOString(),fromRef:W,toRef:h$1,fromHash:i.hash,toHash:m,summary:{changed:R||v>0,addedProjects:l.filter(u=>u.type==="project.added").length,removedProjects:l.filter(u=>u.type==="project.removed").length,changedProjects:l.filter(u=>u.type==="project.changed").length,workspaceChanges:l.filter(u=>u.type==="workspace.changed").length,validationChanges:l.filter(u=>u.type==="validation.changed").length,gitChangedFiles:v},git:g?.available?Me(g,n):{available:false,dirty:false,changedFiles:0,untrackedFiles:0,deletedFiles:0},changes:l,currentModel:p}}async function Be(e,t){let r=f.join(t,Z);return await y.ensureDir(f.dirname(r)),await y.writeJson(r,a(e),{spaces:2}),r}function P(e){return {none:0,low:1,medium:2,high:3,critical:4}[e]}function J(e){return e.reduce((t,r)=>P(r)>P(t)?r:t,"none")}var T=["none","low","medium","high","critical"];function We(e){let t=Math.max(1,P(e)-1);return T[t]}function be(e){let t=Math.min(T.length-1,P(e)+1);return T[t]}function U(e){return e.join(" ")}function w(e,t,r,n){return {id:e,label:t,scope:n.scope,project:n.project,display:U(["npx","rapidkit",...r]),execute:U(["npx","--yes","--package","rapidkit","rapidkit",...r]),required:n.required!==false}}function Y(e){let t=`project:${e.name}`,r=e.commands.fleetStages;return [w(`project.${e.name}.init`,`Run init for ${e.name}`,["workspace","run","init","--scope",t,"--json"],{scope:"project",project:e.name,required:r.includes("init")}),w(`project.${e.name}.test`,`Run tests for ${e.name}`,["workspace","run","test","--scope",t,"--json"],{scope:"project",project:e.name,required:r.includes("test")}),w(`project.${e.name}.build`,`Run build for ${e.name}`,["workspace","run","build","--scope",t,"--json"],{scope:"project",project:e.name,required:r.includes("build")}),w(`project.${e.name}.start`,`Run start for ${e.name}`,["workspace","run","start","--scope",t,"--json"],{scope:"project",project:e.name,required:r.includes("start")})]}function $(){return [w("workspace.doctor","Run workspace doctor",["doctor","workspace","--json"],{scope:"workspace"}),w("workspace.contract.verify","Verify workspace contract",["workspace","contract","verify","--json"],{scope:"workspace"}),w("workspace.readiness","Run release readiness",["readiness","--json"],{scope:"workspace"}),w("workspace.analyze","Run workspace analyze",["analyze","--json"],{scope:"workspace",required:false}),w("workspace.pipeline","Run governance pipeline",["pipeline","--json"],{scope:"workspace",required:false}),w("workspace.doctor-fix","Verify doctor fix result",["doctor","workspace","--fix","--json"],{scope:"workspace",required:false})]}function ve(e,t){let r=t.split(f.sep).join("/");return e.projects.filter(c=>{let a=c.path.split(f.sep).join("/");return r===a||r.startsWith(`${a}/`)}).sort((c,a)=>a.path.length-c.path.length)[0]}function je(e,t,r){let n=new Set(e.map(a=>a.target)),c=(a,i)=>{let p=i.split(f.sep).join("/"),m=`git:${p}`;if(n.has(m))return;let l=ve(r,p),g=l?`${l.name} (${l.path})`:"workspace";h(e,{type:a,severity:a==="git.deleted"?"warning":"info",target:m,message:`Git ${a==="git.untracked"?"untracked":a==="git.deleted"?"deleted":"changed"} file affects ${g}: ${p}`,after:{path:p,project:l?.name,projectPath:l?.path}}),n.add(m);};for(let a of t.changedFiles)c("git.file.changed",a);for(let a of t.untrackedFiles)c("git.untracked",a);for(let a of t.deletedFiles)c("git.deleted",a);}function Me(e,t){return {available:true,ref:t??e.ref,branch:e.branch,commit:e.commit,dirty:e.dirty,changedFiles:e.changedFiles.length,untrackedFiles:e.untrackedFiles.length,deletedFiles:e.deletedFiles.length}}function Pe(e){let t=new Set,r=[];for(let n of e){let c=`${n.scope}:${n.project??""}:${n.display}`;t.has(c)||(t.add(c),r.push(n));}return r}function Ie(e){return e.type==="project.removed"?"high":e.severity==="critical"?"critical":e.severity==="warning"?"high":("medium")}function Re(e,t){return e.severity==="critical"?"critical":e.target==="policies"||e.target.includes("contract")?"high":e.type==="validation.changed"?(t?.projectCount??0)===0?"low":"high":e.target==="evidence"?"low":e.severity==="warning"?"medium":"low"}function Ce(e){return e.affectedProjects>0||e.projectCount>0||!e.changes.every(r=>r.severity==="critical"?false:r.type.startsWith("git.")||r.type==="validation.changed")?e.risk:P(e.risk)>=P("high")||e.risk==="medium"?"low":e.risk}function Q(e,t){if(!e||e==="workspace")return true;let r=(e.startsWith("project:")?e.slice(8):e).trim().toLowerCase();return [t.name,t.path,f.basename(t.path),t.absolutePath].filter(n=>typeof n=="string"&&n.trim().length>0).map(n=>n.trim().toLowerCase()).includes(r)}function Oe(e){if(!e.changed)return {headline:"No workspace model impact detected.",bullets:["The current workspace model matches the provided snapshot/report."],unsafeAssumptions:["Do not claim runtime verification passed unless a report exists."]};let t=e.affectedProjects.map(r=>r.project?.name??r.target);return {headline:`Workspace impact risk: ${e.risk}.`,bullets:[`Affected projects: ${t.length?t.join(", "):"none"}.`,`Workspace-level items: ${e.workspaceImpact.length}.`,"Use the verification plan before recommending apply, rollback, or release actions."],unsafeAssumptions:["Do not infer test/build success from impact alone.","Do not apply fixes without project scope and verification evidence.","Use display commands for users and execute commands for automation."]}}async function qe(e){let t=f.resolve(e.workspacePath),r=ee(e.fromPath),n=e.diff;if(!n&&!r){let o=te(t,e.fromPath);n=await ge(o)??void 0;}n||(n=await ye({workspacePath:t,fromPath:e.fromPath,includeAbsolutePaths:e.includeAbsolutePaths,includeEvidence:e.includeEvidence,includeGitObservation:e.includeGitObservation,gitObservation:e.gitObservation,now:e.now,model:e.model}));let c$1=new Map(n.currentModel.projects.map(o=>[o.path,o])),a=new Map(n.currentModel.projects.map(o=>[o.name,o])),i=n.changes.filter(o=>o.type.startsWith("project.")),p=new Map;for(let o of i){let d=(c$1.get(o.target)??(typeof o.before?.name=="string"?a.get(o.before.name):void 0))?.path??o.target,b=p.get(d)??[];b.push(o),p.set(d,b);}let m=[];for(let[o,s]of p.entries()){let d=c$1.get(o);if(d&&!Q(e.scope,d))continue;let b=J(s.map(Ie)),C=d?.name??(typeof s[0]?.before?.name=="string"?String(s[0].before.name):o);m.push({id:`project:${C}`,scope:"project",target:o,title:`Project impact: ${C}`,summary:s.map(j=>j.message).join(" "),risk:b,reasons:s.map(j=>`${j.type}: ${j.message}`),project:d?{name:d.name,path:d.path,kind:d.kind,runtime:d.runtime,framework:d.framework,supportTier:d.supportTier,...d.generator?{generator:d.generator}:{}}:void 0,verification:d?Y(d):$()});}let l=n.currentModel.graph,g=l?a$1(l):void 0,v=new Set(m.map(o=>o.project?.name).filter(o=>typeof o=="string")),R=new Map;for(let o of m)if(o.project?.name){let s=g?.byId.get(o.project.name);s&&(o.centrality={fanIn:s.fanIn,fanOut:s.fanOut,reach:s.reach,betweenness:s.betweenness,isHotspot:s.isHotspot},s.isHotspot&&(o.risk=be(o.risk),o.reasons=[...o.reasons,`graph.hotspot: critical-path project with ${s.reach} transitive dependent(s); risk escalated.`])),o.origin="direct",o.distance=0,R.set(o.project.name,o.risk);}let W=[],u=0;if(l&&v.size>0){let o=c(l,v);for(let s of o.values()){if(s.distance===0||v.has(s.id))continue;let d=a.get(s.id);if(d&&!Q(e.scope,d))continue;let b=s.path[0],C=s.path[s.path.length-2]??b,j=R.get(b)??"medium",ae=We(j),M=g?.byId.get(s.id);u=Math.max(u,s.distance),W.push({id:`transitive:${s.id}`,scope:"project",target:d?.path??s.id,title:`Transitive impact: ${s.id}`,summary:`Depends on changed project ${b}${s.via?` via ${s.via}`:""} (distance ${s.distance}).`,risk:ae,reasons:[`graph.dependent: depends on ${C}${s.via?` via ${s.via}`:""} (path ${s.path.join(" -> ")})`],project:d?{name:d.name,path:d.path,kind:d.kind,runtime:d.runtime,framework:d.framework,supportTier:d.supportTier,...d.generator?{generator:d.generator}:{}}:void 0,verification:d?Y(d):$(),origin:"transitive",distance:s.distance,path:s.path,via:s.via,...M?{centrality:{fanIn:M.fanIn,fanOut:M.fanOut,reach:M.reach,betweenness:M.betweenness,isHotspot:M.isHotspot}}:{}});}}W.sort((o,s)=>o.target.localeCompare(s.target));let re=g?g.hotspots.flatMap(o=>{let s=g.byId.get(o);return s?[{project:o,fanIn:s.fanIn,fanOut:s.fanOut,reach:s.reach,betweenness:s.betweenness}]:[]}):[],ne=n.changes.filter(o=>!o.type.startsWith("project.")),G=n.currentModel.summary?.projectCount??n.currentModel.projects.length,I=ne.map(o=>({id:`workspace:${o.target}`,scope:"workspace",target:o.target,title:`Workspace impact: ${o.target}`,summary:o.message,risk:Re(o,{projectCount:G}),reasons:[`${o.type}: ${o.message}`],verification:$()})),N=Pe([...m.flatMap(o=>o.verification),...W.flatMap(o=>o.verification),...I.flatMap(o=>o.verification),...n.summary.changed?$():[]]).filter(o=>o.required),oe=J([...m.map(o=>o.risk),...W.map(o=>o.risk),...I.map(o=>o.risk)]),B=Ce({risk:oe,affectedProjects:m.length,projectCount:G,changes:n.changes}),q={changed:n.summary.changed,risk:B,affectedProjects:m.length,workspaceItems:I.length,recommendedCommands:N.length,blastRadius:{directlyAffected:m.length,transitivelyAffected:W.length,maxDistance:u,graphEdges:l?.edges.length??0}};return {schemaVersion:le,generatedAt:(e.now??new Date).toISOString(),fromRef:n.fromRef,diffRef:Z,workspace:{name:n.currentModel.workspace.name,profile:n.currentModel.workspace.profile,type:n.currentModel.workspace.type},summary:q,affectedProjects:m.sort((o,s)=>o.target.localeCompare(s.target)),transitiveImpact:W,criticalPathHotspots:re,workspaceImpact:I.sort((o,s)=>o.target.localeCompare(s.target)),verificationPlan:N,agentBrief:Oe({changed:q.changed,risk:B,affectedProjects:m,workspaceImpact:I}),diff:n}}async function Ke(e,t){let r=f.join(t,me);return await y.ensureDir(f.dirname(r)),await y.writeJson(r,a(e),{spaces:2}),r}export{X as a,V as b,E as c,Z as d,le as e,me as f,ee as g,fe as h,Ge as i,Ne as j,ye as k,Be as l,$ as m,qe as n,Ke as o};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {b as b$1}from'./chunk-Q2KZIBV4.js';import {e,g,c}from'./chunk-WRMCPKGA.js';import L from'validate-npm-package-name';import o from'path';import {spawn}from'child_process';import s from'chalk';import l from'fs-extra';var m=class extends Error{constructor(r,n,a){super(r);this.code=n;this.details=a;this.name="RapidKitError",Error.captureStackTrace(this,this.constructor);}code;details},D=class extends m{constructor(t,r){let n=r?`Python ${t}+ required, found ${r}`:`Python ${t}+ not found`;super(n,"PYTHON_NOT_FOUND","Please install Python from https://www.python.org/downloads/");}},$=class extends m{constructor(){super("Poetry is not installed","POETRY_NOT_FOUND","Install Poetry from https://python-poetry.org/docs/#installation");}},E=class extends m{constructor(){super("pipx is not installed","PIPX_NOT_FOUND","Install pipx from https://pypa.github.io/pipx/installation/");}},G=class extends m{constructor(t){super(`Directory "${t}" already exists`,"DIRECTORY_EXISTS","Please choose a different name or remove the existing directory");}},p=class extends m{constructor(t,r){super(`Invalid project name: "${t}"`,"INVALID_PROJECT_NAME",r);}},S=class extends m{constructor(t,r){let n=`Installation failed at: ${t}`,a=`${r.message}
|
|
2
|
+
|
|
3
|
+
Troubleshooting:
|
|
4
|
+
- Check your internet connection
|
|
5
|
+
- Verify Python/Poetry installation
|
|
6
|
+
- Try running with --debug flag for more details`;super(n,"INSTALLATION_ERROR",a);}},F=class extends m{constructor(){super("RapidKit Python package is not yet available on PyPI","RAPIDKIT_NOT_AVAILABLE",`Available options:
|
|
7
|
+
1. Install Python 3.10+ and retry the same command
|
|
8
|
+
2. Use the core workflow: npx rapidkit create workspace <name>
|
|
9
|
+
3. Offline fallback (limited): npx rapidkit create project fastapi.standard <name> --output .
|
|
10
|
+
|
|
11
|
+
Legacy: set RAPIDKIT_SHOW_LEGACY=1 to reveal template-mode flags in help.`);}};function R(e){let t=L(e);if(!t.validForNewPackages){let n=t.errors||[],a=t.warnings||[],i=[...n,...a];throw new p(e,`NPM validation failed: ${i.join(", ")}`)}if(!/^[a-z][a-z0-9_-]*$/.test(e))throw new p(e,"Must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores");if(["test","tests","src","dist","build","lib","python","pip","poetry","node","npm","rapidkit","rapidkit"].includes(e.toLowerCase()))throw new p(e,`"${e}" is a reserved name. Please choose a different name.`);if(e.length<2)throw new p(e,"Name must be at least 2 characters long");if(e.length>214)throw new p(e,"Name must be less than 214 characters");return true}function pe(e){let t=U(e.workspacePath,e.result.projectPath)?"imported":"adopted";return {name:e.result.projectName,path:e.result.projectPath,relativePath:V(e.workspacePath,e.result.projectPath),relationship:t,stack:e.result.definition.framework,runtime:"node",framework:e.result.definition.framework,frameworkDisplayName:e.result.definition.displayName,supportTier:"extended",moduleSupport:false,confidence:"high",source:t==="adopted"?"adopted-local":"local-folder",importedAt:e.importedAt??new Date().toISOString()}}function U(e,t){let r=o.relative(o.resolve(e),o.resolve(t));return r===""||r.length>0&&!r.startsWith("..")&&!o.isAbsolute(r)}function V(e,t){return (o.relative(e,t)||".").split(o.sep).join("/")}var K=[{id:"nextjs",kitId:"frontend.nextjs",aliases:["frontend.nextjs","next","nextjs","next.js"],displayName:"Next.js",framework:"nextjs",defaultPort:3e3,commandDisplay:e=>`npx create-next-app@latest ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","create-next-app@latest",e,"--yes",...t.skipGit?["--disable-git"]:[],...t.skipInstall?["--skip-install"]:[]]})},{id:"remix",kitId:"frontend.remix",aliases:["frontend.remix","remix","remix-run","react-router"],displayName:"React Router",framework:"remix",defaultPort:5173,commandDisplay:e=>`npx create-react-router@latest ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","create-react-router@latest",e,"--yes",...t.skipInstall?["--no-install"]:["--install"],"--no-git-init"]})},{id:"vite-react",kitId:"frontend.vite-react",aliases:["frontend.vite-react","vite-react","react","vite.react"],displayName:"React + Vite",framework:"react",defaultPort:5173,commandDisplay:e=>`npm create vite@latest ${e} -- --template react-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","react-ts","--no-interactive"]})},{id:"vite-vue",kitId:"frontend.vite-vue",aliases:["frontend.vite-vue","vite-vue","vue","vite.vue"],displayName:"Vue + Vite",framework:"vue",defaultPort:5173,commandDisplay:e=>`npm create vite@latest ${e} -- --template vue-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","vue-ts","--no-interactive"]})},{id:"vite-svelte",kitId:"frontend.vite-svelte",aliases:["frontend.vite-svelte","vite-svelte","svelte","vite.svelte"],displayName:"Svelte + Vite",framework:"svelte",defaultPort:5173,commandDisplay:e=>`npm create vite@latest ${e} -- --template svelte-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","svelte-ts","--no-interactive"]})},{id:"vite-solid",kitId:"frontend.vite-solid",aliases:["frontend.vite-solid","vite-solid","solid","solidjs","vite.solid"],displayName:"Solid + Vite",framework:"solid",defaultPort:5173,commandDisplay:e=>`npm create vite@latest ${e} -- --template solid-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","solid-ts","--no-interactive"]})},{id:"vite-vanilla",kitId:"frontend.vite-vanilla",aliases:["frontend.vite-vanilla","vite","vanilla","vite-vanilla"],displayName:"Vite",framework:"vite",defaultPort:5173,commandDisplay:e=>`npm create vite@latest ${e} -- --template vanilla-ts`,commandExec:e=>({command:"npm",args:["create","vite@latest",e,"--","--template","vanilla-ts","--no-interactive"]})},{id:"nuxt",kitId:"frontend.nuxt",aliases:["frontend.nuxt","nuxt","nuxtjs","nuxt.js"],displayName:"Nuxt",framework:"nuxt",defaultPort:3e3,commandDisplay:(e,t)=>`npx create-nuxt@latest ${e} --template minimal --packageManager npm --gitInit ${t?.skipGit?"false":"true"}${t?.skipInstall?" --no-install":""}`,commandExec:(e,t)=>({command:"npx",args:["--yes","create-nuxt@latest",e,"--template","minimal","--packageManager","npm","--gitInit",t.skipGit?"false":"true",...t.skipInstall?["--no-install"]:[]]})},{id:"angular",kitId:"frontend.angular",aliases:["frontend.angular","angular","ng"],displayName:"Angular",framework:"angular",defaultPort:4200,minNodeMajor:18,minNodeMessage:"Angular scaffolding requires Node.js 18.19+ or 20.11+. Upgrade Node, or choose another frontend kit.",commandDisplay:e=>`npx @angular/cli@19 new ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","@angular/cli@19","new",e,"--defaults","--skip-git",...t.skipInstall?["--skip-install"]:[]]})},{id:"astro",kitId:"frontend.astro",aliases:["frontend.astro","astro"],displayName:"Astro",framework:"astro",defaultPort:4321,commandDisplay:e=>`npm create astro@4 ${e}`,commandExec:(e,t)=>({command:"npm",args:["create","astro@4",e,"--","--yes",...t.skipInstall?["--no-install"]:[],...t.skipGit?["--no-git"]:[]]})},{id:"sveltekit",kitId:"frontend.sveltekit",aliases:["frontend.sveltekit","sveltekit","svelte-kit"],displayName:"SvelteKit",framework:"sveltekit",defaultPort:5173,commandDisplay:e=>`npx sv@latest create ${e}`,commandExec:(e,t)=>({command:"npx",args:["--yes","sv@latest","create",e,"--template","minimal","--types","ts","--no-add-ons",...t.skipInstall?["--no-install"]:["--install","npm"]]})}],v=new Map;for(let e of K){v.set(e.id,e),v.set(e.kitId,e);for(let t of e.aliases)v.set(t.toLowerCase(),e);}function ge(){return [...K]}function f(e){return e?v.get(e.trim().toLowerCase())??null:null}function fe(e){return !!f(e)}function ue(e){if(e[0]!=="create"||e[1]!=="frontend")return null;let t=e[2],r=e[3],n=e.slice(4),a=f(t);return a?["create","project",a.kitId,r??"",...n].filter(Boolean):["create","project",`frontend.${t??""}`,r??"",...n].filter(Boolean)}function A(e,t){return `rapidkit create project ${f(e)?.id??e.replace(/^frontend\./,"")} ${t}`}function C(e,t){return `npx ${A(e,t)}`}function J(e){let t=f(e);return t?`${A(t.id,"<name>")} [--output <dir>] [--skip-install] [--dry-run]`:"rapidkit create project <nextjs|remix|vite-react|vite-vue|vite-svelte|vite-solid|vite-vanilla|nuxt|angular|astro|sveltekit> <name> [--output <dir>] [--skip-install] [--dry-run]"}async function ke(e){let t=e.args;if(t[0]!=="create"||t[1]!=="project")throw new Error("Frontend create expects normalized args: create project <frontend.kit> <name>");let r=f(t[2]);if(!r)throw new Error(`Unknown frontend generator: ${t[2]??"(missing)"}`);let n=t[3];if(!n)throw new Error(`Usage: ${J(r.id)}`);R(n),q(r);let a=Q(t,"--output")||process.cwd(),i=o.resolve(a,n),g=e.dryRun===true||t.includes("--dry-run"),y=t.includes("--skip-install"),u=t.includes("--skip-git")||t.includes("--no-git"),c=r.commandExec(n,{skipGit:u,skipInstall:y}),k=r.commandDisplay(n,{skipGit:u,skipInstall:y});if(await l.pathExists(i))throw new Error(`Directory "${i}" already exists`);if(g)return Y({definition:r,projectName:n,projectPath:i,commandPlan:c}),{definition:r,projectName:n,projectPath:i,dryRun:g,commandDisplay:k,commandExec:[c.command,...c.args]};await l.ensureDir(o.dirname(i));let w=await O(c.command,c.args,o.dirname(i)),h=await H(i);if(w!==0&&!h)throw new Error(`Official ${r.displayName} generator failed with exit code ${w}`);return w!==0&&h&&console.log(s.yellow(`\u26A0\uFE0F Official ${r.displayName} generator exited with code ${w}, but the scaffold looks complete. Continuing RapidKit project setup...`)),u||await X(i),await W({definition:r,projectName:n,projectPath:i,commandDisplay:k,commandExec:[c.command,...c.args],skipGit:u,skipInstall:y}),console.log(s.green(`\u2705 ${r.displayName} project created at ${i}`)),console.log(s.gray(` Display command: ${C(r.id,n)}`)),console.log(s.gray(" Next: cd "+n+" && npx rapidkit dev")),{definition:r,projectName:n,projectPath:i,dryRun:g,commandDisplay:k,commandExec:[c.command,...c.args]}}async function W(e){let t=new Date().toISOString(),r=await b$1(),n={schema_version:"1.0",name:e.projectName,slug:e.projectName,kind:"frontend",project_type:"frontend",runtime:"node",framework:e.definition.framework,framework_display_name:e.definition.displayName,kit_name:e.definition.kitId,kit:e.definition.kitId,engine:"npm",support_tier:"extended",module_support:false,modules:[],rapidkit_version:r,generated_by:"rapidkit-npm",generated_at:t,frontend:{generator:e.definition.id,official_generator:true,default_port:e.definition.defaultPort,command_display:e.commandDisplay,command_exec:e.commandExec,skip_install:e.skipInstall,skip_git:e.skipGit},contracts:{owns:[],apis:[],publishes:[],consumes:[],dependsOn:[],env:[]}},a={project:e.projectName,runtime:"node",framework:e.definition.framework,kind:"frontend",source:"official-generator"},i={kind:"rapidkit.frontend_create",schema_version:"1.0",generated_at:t,project:{name:e.projectName,path:e.projectPath,kind:"frontend",runtime:"node",framework:e.definition.framework,framework_display_name:e.definition.displayName,kit_name:e.definition.kitId},generator:{id:e.definition.id,command_display:e.commandDisplay,command_exec:e.commandExec}};await l.ensureDir(o.join(e.projectPath,".rapidkit")),await l.writeJson(o.join(e.projectPath,".rapidkit","project.json"),n,{spaces:2}),await l.writeJson(o.join(e.projectPath,".rapidkit","context.json"),a,{spaces:2}),await l.writeJson(o.join(e.projectPath,".rapidkit","frontend-create.json"),i,{spaces:2});}function Y(e){console.log(s.bold(`
|
|
12
|
+
RapidKit frontend create plan: ${e.definition.displayName}`)),console.log(s.gray(`Project: ${e.projectName}`)),console.log(s.gray(`Target: ${e.projectPath}`)),console.log(s.gray(`Show: ${C(e.definition.id,e.projectName)}`)),console.log(s.gray(`Run: ${[e.commandPlan.command,...e.commandPlan.args].join(" ")}`)),console.log(s.gray(`Default: http://localhost:${e.definition.defaultPort}`));}function z(){let e=Number.parseInt(process.versions.node.split(".")[0]??"",10);return Number.isFinite(e)?e:0}function q(e){if(!(!e.minNodeMajor||z()>=e.minNodeMajor))throw new Error(e.minNodeMessage??`${e.displayName} requires Node.js ${e.minNodeMajor}+ (current: ${process.versions.node}).`)}async function H(e){if(!await l.pathExists(e))return false;let t=o.join(e,"package.json");return await l.pathExists(t)?true:(await l.readdir(e)).length>0}async function X(e){let t=o.join(e,".git");if(await l.pathExists(t))return;if(await O("git",["init"],e)===0){console.log(s.gray(" Git repository initialized."));return}console.log(s.yellow("\u26A0\uFE0F Git initialization was skipped or failed. You can run `git init` manually inside the project."));}async function O(e$1,t,r){let n=e(e$1);return await new Promise(a=>{let i=spawn(n.command,[...n.prefixArgs,...t],{cwd:r,stdio:"inherit",shell:c(),env:g()});i.on("close",g=>a(g??1)),i.on("error",()=>a(1));})}function Q(e,t){let r=e.indexOf(t);if(r>=0&&r+1<e.length)return e[r+1];let n=e.find(a=>a.startsWith(`${t}=`));return n?n.slice(t.length+1):void 0}var T=[{id:"fastapi.standard",aliases:["fastapi","fastapi.standard"],label:"fastapi \u2014 FastAPI Standard Kit",description:"Core-backed FastAPI service scaffold.",owner:"core",runtime:"python",framework:"fastapi",moduleSupport:true,stability:"stable"},{id:"fastapi.ddd",aliases:["fastapi.ddd","fastapi-ddd"],label:"fastapi \u2014 FastAPI DDD Kit",description:"Core-backed FastAPI DDD service scaffold.",owner:"core",runtime:"python",framework:"fastapi",moduleSupport:true,stability:"stable"},{id:"nestjs.standard",aliases:["nestjs","nest","nestjs.standard"],label:"nestjs \u2014 NestJS Standard Kit",description:"Core-backed NestJS service scaffold.",owner:"core",runtime:"node",framework:"nestjs",moduleSupport:true,stability:"stable"},{id:"springboot.standard",aliases:["spring","springboot","springboot.standard","java"],label:"spring \u2014 Spring Boot Standard Kit",description:"npm-backed Spring Boot service scaffold.",owner:"npm",runtime:"java",framework:"springboot",moduleSupport:false,stability:"stable",generator:"springboot",createUsage:"rapidkit create project springboot.standard <name> [--java-version <major>] [--spring-boot-version <semver>] [--group-id <com.example>] [--package-name <com.example.app>] [--port <number>]"},{id:"gofiber.standard",aliases:["go","go.standard","fiber","gofiber","gofiber.standard","go/fiber"],label:"go/fiber \u2014 Go Fiber Standard Kit",description:"npm-backed Go Fiber service scaffold.",owner:"npm",runtime:"go",framework:"gofiber",moduleSupport:false,stability:"stable",generator:"gofiber",createUsage:"rapidkit create project gofiber.standard <name> [--output <dir>]"},{id:"gogin.standard",aliases:["gin","gogin","gogin.standard","go/gin"],label:"go/gin \u2014 Go Gin Standard Kit",description:"npm-backed Go Gin service scaffold.",owner:"npm",runtime:"go",framework:"gogin",moduleSupport:false,stability:"stable",generator:"gogin",createUsage:"rapidkit create project gogin.standard <name> [--output <dir>]"},{id:"dotnet.webapi.clean",aliases:["dotnet","dotnet.webapi","dotnet.webapi.clean","aspnet","aspnetcore","asp.net","asp.net-core","csharp","c#"],label:"dotnet \u2014 ASP.NET Core Clean Web API",description:"npm-backed ASP.NET Core Web API with clean architecture boundaries.",owner:"npm",runtime:"dotnet",framework:"dotnet",moduleSupport:false,stability:"preview",generator:"dotnet-webapi-clean",createUsage:"rapidkit create project dotnet.webapi.clean <name> [--target-framework net8.0] [--root-namespace <Company.Product>] [--port <number>]"}],b=new Map;for(let e of T){b.set(e.id.toLowerCase(),e);for(let t of e.aliases)b.set(t.toLowerCase(),e);}function M(e){return e?b.get(e.trim().toLowerCase())??null:null}function ye(e){return M(e)?.id??e}function xe(){return T.filter(e=>e.owner==="core"||e.generator)}function je(e){return M(e)?.owner==="npm"}async function be(e,t){if(!e.generator)throw new Error(`Kit is not backed by an npm generator: ${e.id}`);if(e.generator==="gofiber"){let{generateGoFiberKit:r}=await import('./gofiber-standard-BQ4HCXL2.js');await r(t.projectPath,{project_name:t.projectName,module_path:t.projectName,skipGit:t.skipGit,skipInstall:t.skipInstall});return}if(e.generator==="gogin"){let{generateGoGinKit:r}=await import('./gogin-standard-PUBCYW3A.js');await r(t.projectPath,{project_name:t.projectName,module_path:t.projectName,skipGit:t.skipGit,skipInstall:t.skipInstall});return}if(e.generator==="springboot"){let{generateSpringBootKit:r}=await import('./springboot-standard-XFVQI37R.js');await r(t.projectPath,{project_name:t.projectName,artifact_id:t.projectName,java_version:d(t.args,"--java-version")?.trim(),spring_boot_version:d(t.args,"--spring-boot-version")?.trim(),springdoc_version:d(t.args,"--springdoc-version")?.trim(),group_id:d(t.args,"--group-id")?.trim(),package_name:d(t.args,"--package-name")?.trim(),description:d(t.args,"--description")?.trim(),port:d(t.args,"--port")?.trim(),skipGit:t.skipGit,skipInstall:t.skipInstall});return}if(e.generator==="dotnet-webapi-clean"){let{generateDotnetWebApiCleanKit:r}=await import('./dotnet-webapi-clean-K33C77EI.js');await r(t.projectPath,{project_name:t.projectName,target_framework:d(t.args,"--target-framework")?.trim(),root_namespace:d(t.args,"--root-namespace")?.trim(),description:d(t.args,"--description")?.trim(),port:d(t.args,"--port")?.trim(),skipGit:t.skipGit,skipInstall:t.skipInstall});return}throw new Error(`Unhandled npm kit generator: ${e.generator}`)}function d(e,t){let r=e.indexOf(t);if(r>=0&&r+1<e.length)return e[r+1];let n=e.find(a=>a.startsWith(`${t}=`));return n?n.slice(t.length+1):void 0}
|
|
13
|
+
export{m as a,D as b,$ as c,E as d,G as e,S as f,F as g,R as h,pe as i,ge as j,f as k,fe as l,ue as m,J as n,ke as o,M as p,ye as q,xe as r,je as s,be as t};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {a,b}from'./chunk-KMUWWZRT.js';import {f as f$1,e}from'./chunk-PCXSTKZ5.js';import {h,i}from'./chunk-UZW5QFRW.js';import {a as a$1}from'./chunk-VKLL63TL.js';import y from'fs';import o from'path';import s from'chalk';var T=new Set([".git",".rapidkit",".venv","node_modules","dist","build","target","coverage","htmlcov",".next"]);async function k(e){try{return await y.promises.access(e,y.constants.F_OK),true}catch{return false}}async function z(e){try{let n=JSON.parse(await y.promises.readFile(e,"utf-8"));return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}async function N(e){try{return await y.promises.readFile(e,"utf-8")}catch{return ""}}function O(e){return a(e)}async function K(e,n){return await k(o.join(e,".rapidkit","project.json"))||await k(o.join(e,".rapidkit","context.json"))?true:b(e)?false:o.resolve(e)===o.resolve(n)?h(e).length>0:h(e).length>0}async function M(e){let n=await a$1(e,{skipDirs:T,includeHiddenDirs:false,descendIntoMatchedProjects:false,isProjectDir:K});return n.length>0?n:b(e)?[]:h(e).length>0?[e]:[]}function _(e,n){return o.relative(e,n).replace(/\\/g,"/")||"."}async function A(e,n){for(let t of n)if(await k(o.join(e,t)))return true;return false}async function J(e){return A(e,["health","health.ts","health.js","health.py","health.go","health.kt","health.rb","health.php","healthcheck","health-check","src/health.ts","src/health.js","src/health.py","src/health.go","src/health.kt","src/health.rb","src/health.php","src/healthcheck.ts","src/healthcheck.js","src/liveness.ts","src/readiness.ts","src/ping.ts"])}async function W(e){if(await A(e,["tests","test","__tests__","src/__tests__","pytest.ini","vitest.config.ts","jest.config.ts"]))return true;let t=await z(o.join(e,"package.json")),i=t?.scripts&&typeof t.scripts=="object"?t.scripts:{};return typeof i.test=="string"&&i.test.trim().length>0}async function H(e){let n=await z(o.join(e,"package.json")),t=n?.scripts&&typeof n.scripts=="object"?n.scripts:{};return Object.keys(t).sort()}function f(e,n,t,i,r,d){return {id:e,severity:n,target:t,title:i,detail:r,remediation:d}}function B(e){let n=e.reduce((t,i)=>i.severity==="fail"?t+28:i.severity==="warn"?t+12:t+3,0);return Math.max(0,100-n)}async function U(e,n){let t=await z(o.join(n,".rapidkit","project.json")),i$1=i(n,t),r=h(n),d=i$1.runtime==="unknown"?r[0]||"unknown":i$1.runtime,a=_(e,n),p=a,g=await H(n),u=await k(o.join(n,".rapidkit","project.json"))||await k(o.join(n,".rapidkit","context.json")),l=await W(n),h$1=await A(n,["Dockerfile","dockerfile"]),w=await A(n,[".env.example","env.example","config/env.example"]),P=await A(n,[".github/workflows/ci.yml",".github/workflows/ci.yaml",".github/workflows/main.yml",".github/workflows/build.yml",".github/workflows/test.yml",".github/workflows/deploy.yml",".gitlab-ci.yml",".circleci/config.yml","azure-pipelines.yml","bitbucket-pipelines.yml","cloudbuild.yaml"]),R=await J(n),m=[];return i$1.key==="unknown"&&m.push(f("project.stack.unknown","fail",p,"Project stack is unknown","RapidKit cannot confidently classify this backend project.","Add .rapidkit/project.json metadata or import the project with `rapidkit import`.")),u||m.push(f("project.marker.missing","warn",p,"RapidKit marker is missing","The project can be detected by files, but it is not registered with RapidKit metadata.","Run `rapidkit import <path>` from a workspace or create the project through RapidKit.")),l||m.push(f("project.tests.missing","warn",p,"Test entrypoint is missing","No common test folder, config, or package test script was found.","Add a test command so `rapidkit workspace run test --affected` can gate changes.")),w||m.push(f("project.env.example.missing","info",p,"Environment example is missing","No .env.example or env.example file was found.","Add an env example for onboarding and CI secret documentation.")),P||m.push(f("project.ci.missing","warn",p,"Continuous integration is missing","No recognized CI/CD configuration file was detected for this project.","Add CI configuration so tests and checks run automatically for every change.")),R||m.push(f("project.health.missing","info",p,"Health or readiness probe is missing","The project has no obvious health or readiness endpoint to support automated deployment and runtime checks.","Add a simple health endpoint and document it for readiness gates and observability.")),h$1||m.push(f("project.container.missing","info",p,"Container recipe is missing","No Dockerfile was found for this project.","Add a Dockerfile when the service is intended for containerized deployment.")),{name:o.basename(n),path:n,relativePath:a,runtime:d,framework:i$1.key,confidence:i$1.confidence,supportTier:i$1.supportTier,hasRapidKitMarker:u,hasTests:l,hasDockerfile:h$1,hasEnvExample:w,hasCiConfig:P,hasHealthEndpoint:R,scripts:g,findings:m,score:B(m)}}function V(e){return e.name.toLowerCase()}async function L(e){let n=new Map(e.map(r=>[V(r),r])),t=[];for(let r of e){let d=await z(o.join(r.path,"package.json")),a={...d?.dependencies??{},...d?.devDependencies??{},...d?.peerDependencies??{}};for(let g of Object.keys(a)){let u=g.replace(/^@[^/]+\//,"").toLowerCase(),l=n.get(u);l&&l.relativePath!==r.relativePath&&t.push({from:r.relativePath,to:l.relativePath,kind:"package"});}let p=await N(o.join(r.path,"pyproject.toml"));for(let g of e)g.relativePath!==r.relativePath&&p.includes(g.name)&&t.push({from:r.relativePath,to:g.relativePath,kind:"workspace-reference"});}let i=new Set;return t.filter(r=>{let d=`${r.from}\0${r.to}\0${r.kind}`;return i.has(d)?false:(i.add(d),true)})}function q(e,n){let t=new Map;for(let i of e)t.set(i.relativePath,{project:i.relativePath,directDependents:0,directDependencies:0});for(let i of n){let r=t.get(i.from),d=t.get(i.to);r&&(r.directDependencies+=1),d&&(d.directDependents+=1);}return Array.from(t.values()).sort((i,r)=>r.directDependents-i.directDependents||r.directDependencies-i.directDependencies)}async function Q(e){let n=await z(o.join(e,".rapidkit","workspace.json"));return typeof n?.profile=="string"?n.profile:null}function X(e){return {fail:e.filter(n=>n.severity==="fail").length,warn:e.filter(n=>n.severity==="warn").length,info:e.filter(n=>n.severity==="info").length}}function Y(e){if(e.projectCount===0)return e.workspaceDetected?["Add your first project: npx rapidkit create project <name> --kit <kit>","Import an existing service: npx rapidkit import <path>"]:["Create a RapidKit workspace: npx rapidkit create workspace my-workspace --profile polyglot","Import an existing service: npx rapidkit import ../service"];let n=[];return e.findings.some(t=>t.id==="workspace.marker.missing")&&n.push("Initialize workspace metadata with `rapidkit bootstrap --profile polyglot`."),e.findings.some(t=>t.id==="project.marker.missing")&&n.push("Register detected projects with `rapidkit import <path>` or recreate them via `rapidkit create project`."),e.findings.some(t=>t.id==="project.tests.missing")&&n.push("Add test entrypoints, then gate changes with `rapidkit workspace run test --affected --strict`."),e.findings.some(t=>t.id==="project.ci.missing")&&n.push("Add CI/CD configuration to catch regressions early and make workspace health checks actionable."),e.findings.some(t=>t.id==="project.health.missing")&&n.push("Add a health/readiness endpoint so runtime probes and deployment checks can verify service health."),e.hasGraph||n.push("Create `.rapidkit/workspace-dependency-graph.json` or use analyze output as the first graph seed."),n.push("Run `rapidkit autopilot release --mode audit --json` before release."),Array.from(new Set(n))}async function ce(e$1={}){let n=o.resolve(e$1.workspacePath||process.cwd());if(!await k(n))throw new Error(`Workspace path does not exist: ${n}`);let t=O(n)??n,i=await k(o.join(t,".rapidkit-workspace"))||await k(o.join(t,".rapidkit","workspace.json")),r=await Q(t),d=await M(t),a=await Promise.all(d.map(c=>U(t,c))),p=await L(a),g=q(a,p),u=[];i||u.push(f("workspace.marker.missing","warn",".","Workspace metadata is missing","The directory can be analyzed, but it is not a registered RapidKit workspace.","Run `rapidkit create workspace` or `rapidkit bootstrap --profile polyglot` in a workspace root.")),a.length===0&&u.push(f("workspace.projects.missing","warn",".","No backend projects detected","RapidKit did not find runtime markers or project metadata under this root.","Create a project with `rapidkit create project` or import one with `rapidkit import <path>`."));let l=[...u,...a.flatMap(c=>c.findings)],h=X(l),w={};for(let c of a)w[c.runtime]=(w[c.runtime]||0)+1;let P=a.length>0?Math.round(a.reduce((c,v)=>c+v.score,0)/a.length):0,R=u.reduce((c,v)=>c+(v.severity==="fail"?20:v.severity==="warn"?8:2),0),m=Math.max(0,P-R),E=a.length===0&&h.fail===0&&l.length>0&&l.every(c=>c.id==="workspace.projects.missing"&&c.severity==="warn"),S=h.fail>0||e$1.strict&&h.warn>0&&!E?"blocked":h.warn>0?"needs-attention":"ready",j={schemaVersion:"rapidkit-analyze-v1",generatedAt:new Date().toISOString(),workspacePath:t,workspaceDetected:i,profile:r,summary:{score:m,verdict:S,projectCount:a.length,runtimeCount:Object.keys(w).length,findings:h},runtimes:w,projects:a,dependencyGraph:{status:p.length>0?"generated":"empty",edges:p,topImpactedProjects:g.slice(0,5)},findings:l,nextActions:Y({findings:l,projectCount:a.length,hasGraph:p.length>0,workspaceDetected:i}),enterpriseControls:{jsonReady:true,ciGateCommand:"rapidkit analyze --json --strict",releaseGateCommand:"rapidkit autopilot release --mode enforce --json",evidencePath:".rapidkit/reports/analyze-last-run.json"}};if(e$1.output&&(await y.promises.mkdir(o.dirname(o.resolve(e$1.output)),{recursive:true}),await y.promises.writeFile(o.resolve(e$1.output),`${JSON.stringify(j,null,2)}
|
|
2
|
+
`)),!e$1.output&&i){let c=o.join(t,".rapidkit","reports","analyze-last-run.json");await y.promises.mkdir(o.dirname(c),{recursive:true});let v=f$1(j,{commandId:"workspaceAnalyze",exitCode:j.summary.verdict==="blocked"?2:j.summary.verdict==="needs-attention"?1:0,generatedAt:j.generatedAt,blockers:j.findings.filter(x=>x.severity==="fail").map(x=>x.title).slice(0,12),runId:e()});await y.promises.writeFile(c,`${JSON.stringify(v,null,2)}
|
|
3
|
+
`);}return j}function de(e){let n=e.summary.verdict==="ready"?s.green:e.summary.verdict==="needs-attention"?s.yellow:s.red;if(console.log(s.bold(`
|
|
4
|
+
RapidKit Workspace Analysis
|
|
5
|
+
`)),console.log(s.cyan("Workspace:"),e.workspacePath),console.log(s.cyan("Profile:"),e.profile||"not configured"),console.log(s.cyan("Score:"),`${e.summary.score}/100`),console.log(s.cyan("Verdict:"),n(e.summary.verdict)),console.log(s.gray(`Projects: ${e.summary.projectCount}, runtimes: ${e.summary.runtimeCount}, findings: ${e.summary.findings.fail} fail / ${e.summary.findings.warn} warn / ${e.summary.findings.info} info`)),e.projects.length>0){console.log(s.bold(`
|
|
6
|
+
Projects`));for(let t of e.projects){let i=t.score>=85?s.green("pass"):t.score>=65?s.yellow("watch"):s.red("risk");console.log(` ${t.relativePath} ${s.gray(`${t.runtime}/${t.framework}`)} ${i} ${t.score}/100`);}}if(e.dependencyGraph.status==="generated"&&(console.log(s.bold(`
|
|
7
|
+
Dependency Graph`)),console.log(s.gray(` edges: ${e.dependencyGraph.edges.length}`)),e.dependencyGraph.topImpactedProjects.length>0)){console.log(s.gray(" Top impacted projects:"));for(let t of e.dependencyGraph.topImpactedProjects.slice(0,3))console.log(` ${t.project} (${t.directDependents} dependents, ${t.directDependencies} dependencies)`);}if(e.findings.length>0){console.log(s.bold(`
|
|
8
|
+
Top Findings`));for(let t of e.findings.slice(0,8)){let i=t.severity==="fail"?s.red:t.severity==="warn"?s.yellow:s.gray;console.log(` ${i(t.severity.toUpperCase())} ${t.target}: ${t.title}`),console.log(s.gray(` ${t.remediation}`));}}console.log(s.bold(`
|
|
9
|
+
Next Actions`));for(let t of e.nextActions.slice(0,5))console.log(s.gray(` - ${t}`));console.log();}export{ce as a,de as b};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {a as a$5}from'./chunk-HTYMXMQM.js';import {a as a$4,q as q$2,k}from'./chunk-YBS2HGO3.js';import {i,h}from'./chunk-UZW5QFRW.js';import {a as a$3,j as j$1,b}from'./chunk-3PTJID76.js';import {r,j,q as q$1}from'./chunk-E5ZVQL3C.js';import {a}from'./chunk-RV6HBTFC.js';import {a as a$2}from'./chunk-VKLL63TL.js';import {a as a$1}from'./chunk-HHJAANUC.js';import m from'path';import E from'fs-extra';import tt from'crypto';import {createRequire}from'module';var Ye=new Set(["service","frontend","worker","library","infra","docs","test-suite","unknown"]);async function We(e){try{if(!await E.pathExists(e))return null;let t=await E.readJSON(e);return t&&typeof t=="object"?t:null}catch{return null}}function xe(e){if(typeof e!="string")return null;let t=e.trim().toLowerCase();return Ye.has(t)?t:null}async function Re(e,t){let n=t??await We(m.join(e,".rapidkit","project.json")),o=xe(n?.kind)??xe(n?.type);if(o)return o;let s=await We(m.join(e,"package.json"));if(s){let r={...s.dependencies??{},...s.devDependencies??{}},a=s.scripts??{},i=Object.values(a).filter(c=>typeof c=="string").join(" ").toLowerCase();if(r.next||r.react||r.vue||r.svelte||r.vite||r["@angular/core"]||i.includes("next ")||i.includes("vite "))return "frontend";if(s.private===true&&!r.express&&!r["@nestjs/core"])return "library"}return await E.pathExists(m.join(e,"Dockerfile"))||await E.pathExists(m.join(e,"docker-compose.yml"))||await E.pathExists(m.join(e,"terraform.tf"))?"infra":"service"}var Qe=new Set([...r().map(e=>e.id),...j().map(e=>e.kitId)]),Ze=[{id:"wordpress-site",aliases:["wordpress","wordpress-site","wp","wp-site"],ecosystem:"wordpress",status:"planned",officialCommands:["wp core download","wp config create","wp db create","wp core install"],adoptAfterCreate:true},{id:"wordpress-block",aliases:["wordpress-block","wp-block","gutenberg-block"],ecosystem:"wordpress",status:"planned",officialCommands:["npx @wordpress/create-block@latest <slug>"],adoptAfterCreate:true},{id:"laravel",aliases:["laravel","php-laravel"],ecosystem:"php",status:"planned",officialCommands:["composer create-project laravel/laravel <name>"],adoptAfterCreate:true},{id:"symfony",aliases:["symfony","php-symfony"],ecosystem:"php",status:"planned",officialCommands:["composer create-project symfony/skeleton <name>"],adoptAfterCreate:true},{id:"rails",aliases:["rails","ruby-on-rails","ruby-rails"],ecosystem:"ruby",status:"planned",officialCommands:["rails new <name>"],adoptAfterCreate:true}],F=new Map;for(let e of Ze){F.set(e.id,e);for(let t of e.aliases)F.set(t,e);}var et=new Set(["php","ruby","rust","elixir","clojure","scala","kotlin","unknown"]);function A(e){return e?.trim().toLowerCase()||void 0}function Ie(e){let t=A(e.kitId)??A(e.framework)??A(e.runtime)??"unknown";if(e.projectExists)return {lane:"adopt-only",status:"available",canExecuteCreate:false,requested:t,reason:"Existing projects enter Workspace Intelligence through adopt/import."};let n=e.kitId?q$1(e.kitId):void 0;if(n&&Qe.has(n))return {lane:"native-create",status:"available",canExecuteCreate:true,requested:t,resolved:n,reason:"RapidKit owns the create contract, project marker, registry, doctor, and workspace model path."};let o=F.get(t)??F.get(A(e.framework)??"")??F.get(A(e.runtime)??"");if(o)return {lane:"external-create-adopt",status:o.status,canExecuteCreate:false,requested:t,resolved:o.id,officialCommands:o.officialCommands,fallbackLane:"adopt-only",reason:"External generator support is planned but not enabled; use adopt/import until RapidKit owns the post-create contract."};let s=A(e.runtime);return s&&et.has(s)?{lane:"adopt-only",status:"available",canExecuteCreate:false,requested:t,resolved:s,reason:"Runtime can be governed through Workspace Intelligence, but native create is not supported."}:{lane:"adopt-only",status:"available",canExecuteCreate:false,requested:t,reason:"No native create contract is available; use adopt/import to enter Workspace Intelligence."}}function tn(e){return !e.canExecuteCreate&&(e.lane==="external-create-adopt"||e.lane==="adopt-only"&&e.resolved!==void 0)}var Ae="workspace-dependency-graph.v1",Me=["code-import","package-dep","event-pub-sub","service-dependsOn","shared-resource"];var cn="rapidkit-freshness-metadata-v1";function oe(e){if(Array.isArray(e))return e.map(t=>oe(t));if(e&&typeof e=="object"){let t={};for(let n of Object.keys(e).sort())t[n]=oe(e[n]);return t}return e}function nt(e){return JSON.stringify(oe(e))}function z(e){return tt.createHash("sha256").update(nt(e)).digest("hex")}var De=".rapidkit/workspace-graph.overrides.json",rt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),ot=new Set([".git",".hg",".svn",".rapidkit",".venv","node_modules","dist","build","out","target","coverage","htmlcov",".next",".turbo",".cache"]),Oe=600,_e=5,st=256*1024,Ge={inferred:1,contract:2,manual:3};function at(e){return e.split(m.sep).join("/")}function J(e,t){return at(m.relative(e,t)||".")}function Ne(e){let t=new Map;for(let n of e.projects)t.has(n.name)||t.set(n.name,{id:n.name,path:n.path,...n.runtime?{runtime:n.runtime}:{},...n.framework?{framework:n.framework}:{},...n.kind?{kind:n.kind}:{}});return [...t.values()].sort((n,o)=>n.id.localeCompare(o.id))}function Te(e,t){let n=new Map,o=new Map;for(let r of t.projects){if(n.has(r.name))continue;let a=r.absolutePath?m.resolve(r.absolutePath):m.resolve(e,r.path);n.set(r.name,a),o.has(a)||o.set(a,r.name);}let s=[...o.entries()].map(([r,a])=>({dir:r,id:a})).sort((r,a)=>a.dir.length-r.dir.length||r.dir.localeCompare(a.dir));return {idToDir:n,dirToId:o,sortedDirs:s}}function q(e,t){let n=m.resolve(t);for(let{dir:o,id:s}of e.sortedDirs)if(n===o||n.startsWith(`${o}${m.sep}`))return s;return null}async function ie(e){try{if(!await E.pathExists(e))return null;let t=await E.readJSON(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function de(e){try{return await E.pathExists(e)?await E.readFile(e,"utf8"):null}catch{return null}}async function Fe(e,t){let n=[],o=new Map;for(let[s,r]of t.idToDir.entries()){let a=await ie(m.join(r,"package.json")),i=typeof a?.name=="string"?a.name.trim():"";i&&!o.has(i)&&o.set(i,s);}for(let[s,r]of t.idToDir.entries()){let a=await ie(m.join(r,"package.json"));if(a){let i=["dependencies","devDependencies","peerDependencies","optionalDependencies"],c=new Set;for(let d of i){let l=a[d];if(!(!l||typeof l!="object"||Array.isArray(l)))for(let p of Object.keys(l)){let u=o.get(p);!u||u===s||c.has(u)||(c.add(u),n.push({from:s,to:u,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:J(e,m.join(r,"package.json")),detail:`declares dependency ${p}`}]}));}}}n.push(...await it(e,t,s,r)),n.push(...await ct(e,t,s,r));}return n}async function it(e,t,n,o){let s=await de(m.join(o,"pyproject.toml"));if(!s)return [];let r=[],a=new Set,i=/path\s*=\s*["']([^"']+)["']/g,c;for(;(c=i.exec(s))!==null;){let d=q(t,m.resolve(o,c[1]));!d||d===n||a.has(d)||(a.add(d),r.push({from:n,to:d,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:J(e,m.join(o,"pyproject.toml")),detail:`path dependency ${c[1]}`}]}));}return r}async function ct(e,t,n,o){let s=await de(m.join(o,"go.mod"));if(!s)return [];let r=[],a=new Set,i=/replace\s+\S+\s+=>\s+(\.[^\s]+)/g,c;for(;(c=i.exec(s))!==null;){let d=q(t,m.resolve(o,c[1]));!d||d===n||a.has(d)||(a.add(d),r.push({from:n,to:d,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:J(e,m.join(o,"go.mod")),detail:`go.mod replace ${c[1]}`}]}));}return r}async function dt(e,t){let n=[],o=[e];for(;o.length>0&&n.length<t;){let s=o.shift();if(!s)continue;let r=[];try{r=await E.readdir(s,{withFileTypes:true});}catch{continue}let a=[],i=[];for(let c of r)if(c.isDirectory()){if(ot.has(c.name)||c.name.startsWith("."))continue;a.push(m.join(s,c.name));}else c.isFile()&&rt.has(m.extname(c.name))&&i.push(m.join(s,c.name));i.sort((c,d)=>c.localeCompare(d)),a.sort((c,d)=>c.localeCompare(d));for(let c of i){if(n.length>=t)break;n.push(c);}o.push(...a);}return n}var pt=[/\bfrom\s+["']([^"']+)["']/g,/\bimport\s+["']([^"']+)["']/g,/\bimport\s*\(\s*["']([^"']+)["']\s*\)/g,/\brequire\s*\(\s*["']([^"']+)["']\s*\)/g];function lt(e){let t=new Set;for(let n of pt){n.lastIndex=0;let o;for(;(o=n.exec(e))!==null;){let s=o[1];s.startsWith(".")&&t.add(s);}}return [...t]}async function ce(e,t,n,o){let s=new Map;for(let[r,a]of t.idToDir.entries()){if(o&&!o.has(r))continue;let i=await dt(a,n);for(let c of i){let d=await E.stat(c).catch(()=>null);if(!d||d.size>st)continue;let l=await de(c);if(l)for(let p of lt(l)){let u=m.resolve(m.dirname(c),p),f=q(t,u);if(!f||f===r)continue;let b=`${r}\0${f}`,y=s.get(b);y||(y={from:r,to:f,evidence:[]},s.set(b,y)),y.evidence.length<_e&&y.evidence.push({file:J(e,c),detail:`imports ${p}`});}}}return [...s.values()].map(r=>({from:r.from,to:r.to,kind:"code-import",source:"inferred",confidence:"medium",evidence:r.evidence}))}function ut(e,t,n){let o=new Map;for(let s of n.projects){let r=mt(e,t,s);r&&o.set(s.slug,r);}return o}function mt(e,t,n){let o=[n.relativePath,n.externalPath].filter(s=>typeof s=="string"&&s.length>0);for(let s of o){let r=m.resolve(e,s),a=t.dirToId.get(r)??q(t,r);if(a)return a}return t.idToDir.has(n.slug)?n.slug:null}function He(e,t,n){let o=[],s=ut(e,t,n),r=b,a=new Map,i=new Map;for(let c of n.projects){let d=s.get(c.slug);if(!d)continue;let l=c.contracts??{publishes:[],consumes:[],dependsOn:[]};for(let p of l.dependsOn??[]){let u=s.get(p);!u||u===d||o.push({from:d,to:u,kind:"service-dependsOn",source:"contract",confidence:"high",evidence:[{file:r,detail:`dependsOn ${p}`}]});}for(let p of l.publishes??[])a.has(p)||a.set(p,new Set),a.get(p)?.add(d);for(let p of l.consumes??[])i.has(p)||i.set(p,new Set),i.get(p)?.add(d);}for(let[c,d]of a.entries()){let l=i.get(c);if(l)for(let p of l)for(let u of d)p!==u&&o.push({from:p,to:u,kind:"event-pub-sub",source:"contract",confidence:"high",evidence:[{file:r,detail:`consumes event ${c}`}]});}return o.push(...ft(n,s)),o}function se(e){return e.toLowerCase().replace(/[^a-z0-9]/g,"")}function ft(e,t){let n=[],o=e.projects.map(s=>({project:s,id:t.get(s.slug)})).filter(s=>!!s.id).filter(s=>se(s.project.slug).length>=3);for(let s of e.projects){let r=t.get(s.slug);if(!r)continue;let a=s.contracts?.env??[];if(a.length===0)continue;let i=new Set;for(let c of a){let d=se(c);for(let l of o)l.id===r||i.has(l.id)||!(d.includes(se(l.project.slug))&&(l.project.ports?.length??0)>0)||(i.add(l.id),n.push({from:r,to:l.id,kind:"shared-resource",source:"inferred",confidence:"low",evidence:[{file:b,detail:`env ${c} references ${l.project.slug}`}]}));}}return n}async function Ke(e,t){let n=await ie(m.join(e,De)),o=Array.isArray(n?.edges)?n?.edges:[],s=[],r=new Set(Me);for(let a of o){if(!a||typeof a!="object"||Array.isArray(a))continue;let i=a,c=typeof i.from=="string"?i.from:"",d=typeof i.to=="string"?i.to:"",l=typeof i.kind=="string"?i.kind:"";if(!t.has(c)||!t.has(d)||c===d||!r.has(l))continue;let p=Array.isArray(i.evidence)?i.evidence.map(u=>u&&typeof u=="object"&&typeof u.file=="string"?{file:u.file,...typeof u.detail=="string"?{detail:u.detail}:{}}:null).filter(u=>!!u):[];s.push({from:c,to:d,kind:l,source:"manual",confidence:"high",evidence:p.length>0?p:[{file:De,detail:"manual edge"}]});}return s}function gt(e){return `${e.from}\0${e.to}\0${e.kind}`}function ht(e){let t=new Set,n=[];for(let o of e){let s=`${o.file}\0${o.detail??""}`;t.has(s)||(t.add(s),n.push(o));}return n.sort((o,s)=>o.file.localeCompare(s.file)||(o.detail??"").localeCompare(s.detail??"")).slice(0,_e)}function kt(e){let t=new Map;for(let n of e){let o=gt(n),s=t.get(o);if(!s){t.set(o,{...n,evidence:[...n.evidence]});continue}let r=Ge[s.source],a=Ge[n.source];a>r?t.set(o,{...n,evidence:[...n.evidence,...s.evidence]}):a===r&&s.evidence.push(...n.evidence);}return [...t.values()].map(n=>({from:n.from,to:n.to,kind:n.kind,source:n.source,confidence:n.confidence,evidence:ht(n.evidence)})).sort((n,o)=>n.from.localeCompare(o.from)||n.to.localeCompare(o.to)||n.kind.localeCompare(o.kind)||n.source.localeCompare(o.source))}function ae(e){return Math.round(e*1e3)/1e3}function yt(e){return Math.max(0,Math.min(100,Math.round(e)))}function wt(e){return e>=75?"critical":e>=50?"high":e>=20?"medium":"low"}function vt(e){return e==="critical"||e==="high"?"strict":e==="medium"?"elevated":"normal"}function Et(e,t){let n=a$5({nodes:e,edges:t}),o=new Map;for(let s of e){let r=n.byId.get(s.id)??{fanIn:0,fanOut:0,reach:0,betweenness:0,isHotspot:false},a=t.filter(f=>f.from===s.id||f.to===s.id),i=a.filter(f=>f.source==="contract"||f.source==="manual").length,c=a.filter(f=>f.confidence==="low").length,d=[],l=r.reach*20+r.fanIn*14+r.fanOut*8+Math.min(20,r.betweenness*4)+i*8;r.isHotspot&&(l+=24,d.push("Critical-path hotspot in dependency graph")),r.reach>0&&d.push(`Change reaches ${r.reach} dependent project(s)`),r.fanIn>0&&d.push(`${r.fanIn} direct dependent project(s)`),r.fanOut>0&&d.push(`${r.fanOut} direct dependency project(s)`),i>0&&d.push(`${i} contract/manual edge(s)`),c>0&&d.push(`${c} low-confidence inferred edge(s) need review`),a.length===0&&d.push("No dependency evidence connected to this project yet");let p=yt(l),u=wt(p);o.set(s.id,{weight:u,score:p,verificationPriority:vt(u),reasons:d.slice(0,5),centrality:{fanIn:r.fanIn,fanOut:r.fanOut,reach:r.reach,betweenness:r.betweenness,isHotspot:r.isHotspot}});}return o}function bt(e,t){let n=Et(e,t);return e.map(o=>({...o,operationalProfile:n.get(o.id)}))}function Ct(e,t){let n=new Set;for(let c of t)n.add(c.from),n.add(c.to);let o=e.length,s=t.length,r=e.filter(c=>n.has(c.id)).length,a=Math.max(0,o-r),i=a$5({nodes:e,edges:t});return {nodeCount:o,edgeCount:s,inferredEdges:t.filter(c=>c.source==="inferred").length,contractEdges:t.filter(c=>c.source==="contract").length,manualEdges:t.filter(c=>c.source==="manual").length,authoritativeEdges:t.filter(c=>c.source==="contract"||c.source==="manual").length,lowConfidenceEdges:t.filter(c=>c.confidence==="low").length,orphanCount:a,connectedNodeCount:r,density:ae(o>1?s/(o*(o-1)):0),edgeCoverageRatio:ae(o>0?r/o:1),evidenceCoverageRatio:ae(s>0?t.filter(c=>c.evidence.length>0).length/s:1),hotspotCount:i.hotspots.length,hasCycle:jt(e,t)}}function Pt(e,t,n){let o=[],s=e.filter(r=>!t.some(a=>a.from===r.id||a.to===r.id)).map(r=>r.id).sort((r,a)=>r.localeCompare(a));return n.nodeCount===0&&o.push({code:"graph.empty",severity:"info",message:"Workspace model has no projects, so dependency reasoning is unavailable.",recommendation:"Import, scaffold, or register projects before relying on graph-aware impact."}),n.nodeCount>1&&n.edgeCount===0?o.push({code:"graph.edges.missing",severity:"warning",message:"Projects were detected, but no inter-project dependency edges were found.",recommendation:"Run graph explain, add workspace contract relationships, or define manual graph overrides for operational dependencies that code imports cannot reveal.",nodeIds:s}):n.orphanCount>0&&o.push({code:"graph.orphans.detected",severity:"warning",message:`${n.orphanCount} project(s) have no dependency evidence connected to the graph.`,recommendation:"Review isolated projects and add package, contract, or manual edges when they participate in release-critical flows.",nodeIds:s.slice(0,12)}),n.lowConfidenceEdges>0&&o.push({code:"graph.low_confidence_edges",severity:"info",message:`${n.lowConfidenceEdges} inferred edge(s) are low confidence.`,recommendation:"Promote important low-confidence relationships to workspace contract or manual overrides."}),n.edgeCount>0&&n.evidenceCoverageRatio<1&&o.push({code:"graph.evidence.partial",severity:"warning",message:"Some dependency edges do not include file-level evidence.",recommendation:"Attach evidence to manual overrides so agents can audit why a relationship exists."}),n.hasCycle&&o.push({code:"graph.cycle.detected",severity:"error",message:"The dependency graph contains at least one directed cycle.",recommendation:"Break the cycle or document the relationship explicitly before using graph-aware release gates."}),o.sort((r,a)=>{let i={error:0,warning:1,info:2};return i[r.severity]-i[a.severity]||r.code.localeCompare(a.code)})}function jt(e,t){let n=new Map;for(let c of e)n.set(c.id,[]);for(let c of t)n.has(c.from)||n.set(c.from,[]),n.get(c.from)?.push(c.to);let o=0,s=1,r=2,a=new Map;for(let c of n.keys())a.set(c,o);let i=c=>{let d=[{id:c,index:0}];for(a.set(c,s);d.length>0;){let l=d[d.length-1],p=n.get(l.id)??[];if(l.index>=p.length){a.set(l.id,r),d.pop();continue}let u=p[l.index];l.index+=1;let f=a.get(u)??o;if(f===s)return true;f===o&&(a.set(u,s),d.push({id:u,index:0}));}return false};for(let c of [...n.keys()].sort())if(a.get(c)===o&&i(c))return true;return false}function Ve(e,t,n,o){let s=kt(n.filter(c=>t.has(c.from)&&t.has(c.to))),r=bt(e,s),a=Ct(e,s),i=Pt(e,s,a);return {schemaVersion:Ae,generatedAt:(o??new Date).toISOString(),nodes:r,edges:s,stats:a,...i.length>0?{diagnostics:i}:{}}}async function $e(e){let t=m.resolve(e.workspacePath),n=e.maxImportFilesPerProject??Oe,o=Ne(e.model),s=new Set(o.map(i=>i.id)),r=Te(t,e.model),a=[];return a.push(...await Fe(t,r)),a.push(...await ce(t,r,n)),e.contract&&a.push(...He(t,r,e.contract)),a.push(...await Ke(t,s)),Ve(o,s,a,e.now)}async function Le(e){let t=m.resolve(e.workspacePath),n=e.maxImportFilesPerProject??Oe,o=Ne(e.model),s=new Set(o.map(i=>i.id)),r=Te(t,e.model),a=[];if(a.push(...await Fe(t,r)),e.structuralChange)a.push(...await ce(t,r,n));else {a.push(...await ce(t,r,n,e.changedProjectIds));for(let i of e.previousGraph.edges)i.kind==="code-import"&&i.source==="inferred"&&!e.changedProjectIds.has(i.from)&&s.has(i.from)&&s.has(i.to)&&a.push({from:i.from,to:i.to,kind:"code-import",source:"inferred",confidence:i.confidence,evidence:i.evidence});}return e.contract&&a.push(...He(t,r,e.contract)),a.push(...await Ke(t,s)),Ve(o,s,a,e.now)}var pe="workspace-model-cache.v1",Be=".rapidkit/cache/workspace-model.v1.json",ze=["package.json","pyproject.toml","requirements.txt","go.mod","go.sum","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","composer.json","Gemfile","rapidkit.project.json",".rapidkit/project.json"],xt=[".rapidkit/workspace.contract.json",".rapidkit/workspace.json","rapidkit.workspace.json",".rapidkit/policies.yml",".rapidkit/policies.yaml"],Rt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),It=new Set([".git",".rapidkit","node_modules","dist","build","out","target","coverage",".next",".turbo",".cache",".venv"]),At=1500,H=null;function le(){if(H)return H;try{H=createRequire(import.meta.url)("../package.json")?.version??"0.0.0";}catch{H="0.0.0";}return H}async function U(e){try{let t=await E.readFile(e);return tt.createHash("sha256").update(t).digest("hex")}catch{return null}}async function Mt(e){let t={};for(let s of ze){let r=await U(m.join(e,s));r&&(t[s]=r);}let n=[],o=[e];for(;o.length>0&&n.length<At;){let s=o.shift();if(!s)continue;let r=[];try{r=await E.readdir(s,{withFileTypes:true});}catch{continue}let a=[];for(let i of r)if(i.isDirectory()){if(It.has(i.name)||i.name.startsWith("."))continue;a.push(m.join(s,i.name));}else if(i.isFile()&&Rt.has(m.extname(i.name))){let c=m.join(s,i.name),d=await E.stat(c).catch(()=>null);if(d){let l=m.relative(e,c).split(m.sep).join("/");n.push(`${l}:${d.size}:${Math.round(d.mtimeMs)}`);}}a.sort((i,c)=>i.localeCompare(c)),o.push(...a);}return n.sort((s,r)=>s.localeCompare(r)),z({manifests:t,source:n})}async function X(e,t){let n=m.resolve(e),o={},s=[...new Set(t.map(r=>m.relative(n,m.resolve(r)).split(m.sep).join("/")))].sort((r,a)=>r.localeCompare(a));for(let r of s)o[r]=await Mt(m.join(n,r));return o}async function Y(e){let t=m.resolve(e),n={};for(let o of xt){let s=await U(m.join(t,o));s&&(n[o]=s);}return n}async function Q(e){let t=m.resolve(e.workspacePath),n=[...new Set(e.projectPaths.map(r=>m.relative(t,m.resolve(r)).split(m.sep).join("/")))].sort((r,a)=>r.localeCompare(a)),o=[];for(let r of n){let a={};for(let i of ze){let c=await U(m.join(t,r,i));c&&(a[i]=c);}o.push({project:r,manifests:a});}let s={};for(let r of [".rapidkit/workspace.contract.json",".rapidkit/workspace.json","rapidkit.workspace.json",".rapidkit/policies.yml",".rapidkit/policies.yaml"]){let a=await U(m.join(t,r));a&&(s[r]=a);}return z({cacheSchema:pe,cliVersion:e.cliVersion,flags:e.flags,workspaceJson:e.workspaceJson??null,marker:e.marker??null,projects:o,workspaceFiles:s})}async function ue(e){let t=m.join(m.resolve(e),Be);try{if(!await E.pathExists(t))return null;let n=await E.readJson(t);return !n||n.schemaVersion!==pe||typeof n.inputsHash!="string"||typeof n.cliVersion!="string"||!n.model?null:n}catch{return null}}async function Z(e,t){let n=m.join(m.resolve(e),Be);await E.ensureDir(m.dirname(n));let o={schemaVersion:pe,...t};return await E.writeJson(n,o,{spaces:2}),n}var Dt="workspace-model.v1",Gt=".rapidkit/reports/workspace-model.json",Ot=["package.json","pyproject.toml","requirements.txt","go.mod","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","composer.json","Gemfile","mix.exs","deno.json","deno.jsonc","bun.lock","bun.lockb","deps.edn","project.clj","build.sbt","docker-compose.yml","docker-compose.yaml","terraform.tf"],_t=new Set([".git",".hg",".svn",".rapidkit",".venv","node_modules","dist","build","target","coverage","htmlcov",".next",".turbo"]);function qe(e,t){return (m.relative(e,t)||".").split(m.sep).join("/")}async function Ue(e){try{if(!await E.pathExists(e))return null;let t=await E.readJSON(e);return t&&typeof t=="object"?t:null}catch{return null}}async function Nt(e,t){for(let n of t)if(await E.pathExists(m.join(e,n)))return true;return false}function me(e){let t=Number.parseInt(process.env.RAPIDKIT_WORKSPACE_MODEL_SCAN_DEPTH??"",10),n=typeof e=="number"&&Number.isFinite(e)?e:Number.isFinite(t)?t:4;return Math.min(12,Math.max(1,Math.trunc(n)))}async function fe(e,t){let n=m.resolve(e),o=[{dirPath:n,depth:0}],s=new Set,r=new Set;for(;o.length>0;){let a=o.shift();if(!a)continue;let i=m.resolve(a.dirPath);if(r.has(i))continue;if(r.add(i),i!==n&&await Nt(i,Ot)){s.add(i);continue}if(a.depth>=t)continue;let c=[];try{c=await E.readdir(i,{withFileTypes:true});}catch{continue}for(let d of c)!d.isDirectory()||_t.has(d.name)||d.name.startsWith(".")&&d.name!==".config"||o.push({dirPath:m.join(i,d.name),depth:a.depth+1});}return Array.from(s).sort((a,i)=>a.localeCompare(i))}function ge(e){let t=new Set,n=[];for(let o of e){let s=m.resolve(o);t.has(s)||(t.add(s),n.push(s));}return n.sort((o,s)=>o.localeCompare(s))}function Je(e,t){let n=e?.[t];return typeof n=="string"&&n.trim()?n.trim():void 0}function Tt(e,t){return e?.[t]===true}function Ft(e,t,n){let o=e?.frontend&&typeof e.frontend=="object"&&!Array.isArray(e.frontend)?e.frontend:void 0,s=Je(o,"generator"),r=Je(o,"command_display"),a=typeof t=="string"&&t.startsWith("frontend.");if(!(!s&&!a))return {...s?{id:s}:{},...t?{kit:t}:{},displayName:n,source:Tt(o,"official_generator")?"official-generator":"metadata",...r?{commandDisplay:r}:{}}}async function Ht(e){let t=[".rapidkit/project.json",".rapidkit/context.json","package.json","pyproject.toml","requirements.txt","go.mod","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","composer.json","Gemfile","mix.exs","deno.json","Dockerfile","docker-compose.yml","README.md"],n=[];for(let o of t)await E.pathExists(m.join(e,o))&&n.push(o);return n}async function C(e,t,n){let o=m.join(e,t),s=await E.pathExists(o),r={path:t.split(m.sep).join("/"),exists:s};if(s&&n){let a=await Ue(o);typeof a?.generatedAt=="string"&&(r.generatedAt=a.generatedAt);let i=a?.status??a?.result??a?.verdict;typeof i=="string"&&(r.status=i);}return r}async function Kt(e,t,n){let s=`${qe(e,t)}/.rapidkit/reports`,r=await C(e,`${s}/doctor-project-last-run.json`,n);return {doctor:r?.exists===true?r:await C(e,`${s}/doctor-last-run.json`,n),analyze:await C(e,`${s}/analyze-last-run.json`,n),readiness:await C(e,`${s}/release-readiness-last-run.json`,n)}}async function Vt(e,t,n){let o=a$4(t),s=i(t,o),r=q$2(t),a=k(s.runtime),i$1=await Re(t,o),c=typeof o?.name=="string"&&o.name.trim()?o.name.trim():m.basename(t),d=typeof o?.kit_name=="string"?o.kit_name:typeof o?.kit=="string"?o.kit:void 0,l=typeof o?.engine=="string"?o.engine:r.engine!=="unknown"?r.engine:void 0,p=Ft(o,d,s.displayName),u=Ie({kitId:d,framework:s.key,runtime:s.runtime});return {name:c,path:qe(e,t),...n.includeAbsolutePaths?{absolutePath:t}:{},kind:i$1,runtime:s.runtime,runtimeCandidates:h(t),framework:s.key,frameworkDisplayName:s.displayName,confidence:s.confidence,detectionSource:s.source,supportTier:s.supportTier,runtimeSupportTier:a.tier,runtimeDoctorSupport:a.doctorSupport,moduleSupport:r.moduleSupport,...d?{kit:d}:{},...l?{engine:l}:{},...p?{generator:p}:{},createCapability:u,commands:{supported:r.supportedCommands,unsupported:r.unsupportedCommands,global:r.globalCommands,fleetStages:r.fleetStages,localOnly:r.localOnlyCommands,map:r.commandMap},importantFiles:await Ht(t),evidence:await Kt(e,t,n.includeEvidence),provenance:{path:"filesystem discovery",runtime:s.source,framework:s.source,commands:"project command capability matrix",createCapability:"create planner capability contract",evidence:"project .rapidkit/reports"}}}async function he(e){return Ue(m.join(e,".rapidkit","workspace.json"))}function $t(e){return e.some(t=>t.kind==="frontend")&&e.length>1?"full-stack-workspace":e.some(t=>t.kind==="frontend")?"frontend-workspace":e.length>1?"backend-platform":"backend-workspace"}function Lt(e){let t=new Set;for(let n of e){let o=`${n.name} ${n.path}`.toLowerCase();for(let s of ["auth","billing","payment","notification","order","admin","report","search","analytics"])o.includes(s)&&t.add(s);}return Array.from(t).sort()}function v(e,t,n,o){return {severity:e,code:t,message:n,target:o}}function Xe(e){let t=[];e.workspace.name.trim()||t.push(v("error","workspace.name.missing","Workspace name could not be resolved.","workspace")),e.workspace.type==="observed-workspace"&&t.push(v("warning","workspace.marker.missing","Workspace marker is missing; model is based on filesystem observation.","workspace.marker")),e.summary.projectCount===0&&t.push(v("warning","workspace.projects.empty","No project roots were detected in this workspace.","projects")),e.contracts.exists||t.push(v("warning","workspace.contract.missing","Workspace contract is missing; dependency and API edges may be incomplete.",e.contracts.workspaceContractPath));let n=new Map;for(let r of e.projects){let a=r.name.toLowerCase(),i=n.get(a)??[];i.push(r),n.set(a,i),r.importantFiles.length||t.push(v("warning","project.markers.missing",`Project ${r.name} has no important manifest files recorded.`,r.path)),r.runtime==="unknown"&&t.push(v("warning","project.runtime.unknown",`Project ${r.name} runtime could not be confidently detected.`,r.path));let c=["test","build"];for(let p of c)r.commands.supported.includes(p)&&r.commands.unsupported.includes(p)&&t.push(v("error","project.commands.conflict",`Project ${r.name} marks ${p} as both supported and unsupported.`,r.path));let d=new Set(r.commands.fleetStages),l=new Set(r.commands.localOnly);for(let p of r.commands.fleetStages){l.has(p)&&t.push(v("error","project.commands.scope-conflict",`Project ${r.name} marks ${p} as both fleet and local-only.`,r.path));let u=r.commands.map[p];(!u||u.status!=="supported"||u.fleetEligible!==true||u.executionScope!=="fleet")&&t.push(v("error","project.commands.fleet-stage-invalid",`Project ${r.name} advertises ${p} as a fleet stage without a supported fleet capability.`,r.path));}for(let p of r.commands.localOnly){let u=r.commands.map[p];(!u||u.status!=="supported"||u.executionScope!=="local-only"||u.fleetEligible===true)&&t.push(v("error","project.commands.local-only-invalid",`Project ${r.name} advertises ${p} as local-only without a matching local-only capability.`,r.path));}for(let p of Object.values(r.commands.map))p.status==="supported"&&(p.fleetEligible===true&&!d.has(p.command)&&t.push(v("error","project.commands.fleet-stage-missing",`Project ${r.name} capability ${p.command} is fleet-eligible but missing from fleetStages.`,r.path)),p.executionScope==="local-only"&&p.fleetEligible!==true&&!l.has(p.command)&&t.push(v("error","project.commands.local-only-missing",`Project ${r.name} capability ${p.command} is local-only but missing from localOnly commands.`,r.path)));}for(let[r,a]of n.entries())a.length>1&&t.push(v("error","project.name.duplicate",`Project name "${r}" is ambiguous across ${a.length} project roots.`,a.map(i=>i.path).join(", ")));let o=t.filter(r=>r.severity==="error").length,s=t.filter(r=>r.severity==="warning").length;return {status:o>0?"failed":s>0?"warning":"passed",errors:o,warnings:s,issues:t}}function Kn(e){return Xe(e)}async function ee(e){let t=m.resolve(e.workspacePath),n=e.includeAbsolutePaths===true,o=e.includeEvidence===true,s=me(e.observableScanDepth),r=e.now??new Date,[a$3,i,c,d,l]=await Promise.all([a(t),he(t),a$1(t),a$2(t,{descendIntoMatchedProjects:false}),fe(t,s)]),p=ge([...d,...l,...c.map(g=>m.isAbsolute(g.path)?g.path:m.join(t,g.path))]),u=e.reuseProjectModels,f=await Promise.all(p.map(g=>{if(u){let W=m.relative(t,m.resolve(g)).split(m.sep).join("/"),x=u.get(W);if(x)return Promise.resolve(x)}return Vt(t,g,{includeAbsolutePaths:n,includeEvidence:o})})),b=typeof i?.workspace_name=="string"?i.workspace_name:typeof i?.name=="string"?i.name:a$3?.name||m.basename(t),y=typeof i?.profile=="string"?i.profile:typeof i?.mode=="string"?i.mode:void 0,D=Array.from(new Set(f.map(g=>g.kind))).sort(),S=Array.from(new Set(f.map(g=>g.runtime))).sort(),te=Array.from(new Set(f.map(g=>g.framework))).sort(),G=[".rapidkit/policies.yml",".rapidkit/policies.yaml"].find(g=>E.existsSync(m.join(t,g))),O=".rapidkit/workspace.contract.json",P=await E.pathExists(m.join(t,O)),K={schemaVersion:Dt,generatedAt:r.toISOString(),workspace:{name:b,root:t,...y?{profile:y}:{},type:a$3?"rapidkit-workspace":"observed-workspace",...a$3?{marker:{createdBy:a$3.createdBy,version:a$3.version,createdAt:a$3.createdAt}}:{}},identity:{workspaceType:$t(f),surfaces:D,runtimeFamilies:S,businessCapabilities:Lt(f)},discovery:{observableScanDepth:s},projects:f,policies:{mode:typeof i?.policy_mode=="string"?i.policy_mode:typeof i?.policyMode=="string"?i.policyMode:"warn",source:G??null,exists:!!G},contracts:{workspaceContractPath:O,exists:P,status:P?"known":"missing"},evidence:{doctor:await C(t,".rapidkit/reports/doctor-last-run.json",o),analyze:await C(t,".rapidkit/reports/analyze-last-run.json",o),readiness:await C(t,".rapidkit/reports/release-readiness-last-run.json",o),pipeline:await C(t,".rapidkit/reports/pipeline-last-run.json",o)},summary:{projectCount:f.length,runtimes:S,frameworks:te,firstClassProjects:f.filter(g=>g.supportTier==="first-class").length,observedProjects:f.filter(g=>g.supportTier==="observed").length}},_=await qt(t,K,{contractExists:P,now:r,incrementalGraph:e.incrementalGraph}),V={...K,graph:_},w=Xe(V);return {...V,validation:w}}async function Vn(e){if(e.cache!==true)return {model:await ee(e),cache:"disabled"};let t=m.resolve(e.workspacePath),n=me(e.observableScanDepth),o=le(),[s,r,a$3,i,c]=await Promise.all([a(t),he(t),a$1(t),a$2(t,{descendIntoMatchedProjects:false}),fe(t,n)]),d=ge([...i,...c,...a$3.map(y=>m.isAbsolute(y.path)?y.path:m.join(t,y.path))]),l=await Q({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:n},projectPaths:d,workspaceJson:r,marker:s}),p=await ue(t);if(p&&p.cliVersion===o&&p.inputsHash===l)return {model:p.model,cache:"hit"};let u=await ee({...e}),[f,b]=await Promise.all([X(t,d),Y(t)]);return await Z(t,{cliVersion:o,inputsHash:l,generatedAt:(e.now??new Date).toISOString(),model:u,projectSignatures:f,workspaceFileSignatures:b}),{model:u,cache:"miss"}}function Bt(e,t){let n=new Set,o=new Set,s=new Set;for(let[r,a]of Object.entries(t))r in e?e[r]!==a&&n.add(r):o.add(r);for(let r of Object.keys(e))r in t||s.add(r);return {changed:n,added:o,removed:s}}function zt(e={},t={}){let n=new Set([...Object.keys(e),...Object.keys(t)]);for(let o of n)if(e[o]!==t[o])return false;return true}async function $n(e){let t=m.resolve(e.workspacePath),n=me(e.observableScanDepth),o=le(),s=e.now??new Date,[r,a$3,i,c,d]=await Promise.all([a(t),he(t),a$1(t),a$2(t,{descendIntoMatchedProjects:false}),fe(t,n)]),l=ge([...c,...d,...i.map(w=>m.isAbsolute(w.path)?w.path:m.join(t,w.path))]),p=await ue(t),u=async()=>{let w=await ee({...e}),g=await Q({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:n},projectPaths:l,workspaceJson:a$3,marker:r}),[W,x]=await Promise.all([X(t,l),Y(t)]);return await Z(t,{cliVersion:o,inputsHash:g,generatedAt:s.toISOString(),model:w,projectSignatures:W,workspaceFileSignatures:x}),{model:w,mode:"full"}};if(!p||p.cliVersion!==o||!p.projectSignatures||!p.model?.graph)return u();let f=await Y(t);if(!zt(p.workspaceFileSignatures,f))return u();let b=await X(t,l),{changed:y,added:D,removed:S}=Bt(p.projectSignatures,b);if(y.size===0&&D.size===0&&S.size===0)return {model:p.model,mode:"unchanged"};let te=new Set([...y,...D]),G=new Map;for(let w of p.model.projects){let g=w.path.split(m.sep).join("/");!te.has(g)&&!S.has(g)&&G.set(g,w);}let O=new Set,P=false;for(let w of p.model.projects){let g=w.path.split(m.sep).join("/");y.has(g)&&O.add(w.name);}let K=D.size>0||S.size>0,_=await ee({...e,reuseProjectModels:G,incrementalGraph:{previousGraph:p.model.graph,changedProjectIds:O,structuralChange:K||P}});for(let w of p.model.projects){let g=w.path.split(m.sep).join("/");if(!y.has(g))continue;let W=_.projects.find(x=>x.path.split(m.sep).join("/")===g);if(W&&W.name!==w.name){P=true;break}}if(P)return u();let V=await Q({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:n},projectPaths:l,workspaceJson:a$3,marker:r});return await Z(t,{cliVersion:o,inputsHash:V,generatedAt:s.toISOString(),model:_,projectSignatures:b,workspaceFileSignatures:f}),{model:_,mode:"incremental"}}async function Jt(e){try{let{contract:t}=await j$1({workspacePath:e});return t&&typeof t=="object"?t:null}catch{return null}}async function qt(e,t,n){let o=n.contractExists?await Jt(e):null;try{return n.incrementalGraph?await Le({workspacePath:e,model:t,contract:o,now:n.now,previousGraph:n.incrementalGraph.previousGraph,changedProjectIds:n.incrementalGraph.changedProjectIds,structuralChange:n.incrementalGraph.structuralChange}):await $e({workspacePath:e,model:t,contract:o,now:n.now})}catch{let s=t.projects.map(r=>({id:r.name,path:r.path}));return {schemaVersion:"workspace-dependency-graph.v1",generatedAt:n.now.toISOString(),nodes:s,edges:[],stats:{nodeCount:s.length,edgeCount:0,inferredEdges:0,contractEdges:0,manualEdges:0,authoritativeEdges:0,lowConfidenceEdges:0,orphanCount:s.length,connectedNodeCount:0,density:0,edgeCoverageRatio:s.length>0?0:1,evidenceCoverageRatio:1,hotspotCount:0,hasCycle:false},diagnostics:s.length>1?[{code:"graph.inference.failed",severity:"warning",message:"Dependency graph inference failed; model contains projects but no dependency edges.",recommendation:"Run workspace model again after fixing graph inputs, or add workspace contract/manual graph overrides.",nodeIds:s.map(r=>r.id).sort((r,a)=>r.localeCompare(a))}]:void 0}}}async function Ln(e,t){let n=m.join(t,Gt);return await E.ensureDir(m.dirname(n)),await E.writeJSON(n,a$3(e),{spaces:2}),n}export{cn as a,z as b,Ie as c,tn as d,Re as e,Ae as f,Dt as g,Gt as h,Kn as i,ee as j,Vn as k,$n as l,Ln as m};
|