workspai 0.43.0 → 0.44.0
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 +26 -13
- package/contracts/agent-customization-pack.v1.json +1 -1
- package/contracts/autopilot-release.v1.json +204 -0
- package/contracts/cli-operation-result.v1.json +119 -0
- package/contracts/command-capabilities.v1.json +138 -0
- package/contracts/compatibility-matrix.v1.json +37 -0
- package/contracts/create-planner-capabilities.v1.json +156 -65
- package/contracts/doctor-project-scan.v2.json +60 -0
- package/contracts/doctor-remediation-plan.v1.json +19 -4
- package/contracts/doctor-remediation-plan.v2.json +7 -0
- package/contracts/doctor-workspace-cache.v2.json +82 -0
- package/contracts/extension-cli-compatibility.v1.json +47 -3
- package/contracts/infra-plan.v1.json +189 -0
- package/contracts/private-product-manifest.v1.json +155 -0
- package/contracts/product-factory-plan.v1.json +200 -0
- package/contracts/project-archive.v1.json +40 -0
- package/contracts/project-entry-capability.v1.json +127 -0
- package/contracts/published-contract-catalog.v1.json +334 -0
- package/contracts/runtime-command-surface.v1.json +239 -10
- package/contracts/version.v1.json +48 -0
- package/contracts/workspace-archive-capabilities.v1.json +90 -0
- package/contracts/workspace-archive-manifest.v1.json +107 -0
- package/contracts/workspace-archive-operation-result.v1.json +565 -0
- package/contracts/workspace-intelligence/agent-customization-pack-report.v1.json +98 -0
- package/contracts/workspace-intelligence/agent-hooks.v1.json +38 -0
- package/contracts/workspace-intelligence/agent-reports-index.v1.json +56 -0
- package/contracts/workspace-intelligence/mcp-design.v1.json +42 -0
- package/contracts/workspace-intelligence/workspace-context.v1.json +12 -0
- package/contracts/workspace-intelligence/workspace-explain.v1.json +1 -0
- package/contracts/workspace-intelligence-architecture.v1.json +723 -0
- package/contracts/workspace-intelligence-chain.v1.json +1194 -0
- package/contracts/workspace-list.v1.json +56 -0
- package/contracts/workspace-model-cache.v1.json +55 -0
- package/contracts/workspace-snapshot.v1.json +58 -0
- package/contracts/workspace-snapshot.v2.json +97 -0
- package/contracts/workspace-sync.v1.json +30 -0
- package/contracts/workspace-watch-event.v1.json +112 -0
- package/dist/analyze-6OCBM4ID.js +1 -0
- package/dist/{artifact-remediation-plan-5GJWPPRS.js → artifact-remediation-plan-Z7OCSME3.js} +3 -3
- package/dist/autopilot-release-LI2WJCEW.js +1 -0
- package/dist/{chunk-LZQNVH7D.js → chunk-2K3GYCPS.js} +1 -1
- package/dist/chunk-2QN6BMM7.js +2 -0
- package/dist/chunk-2QOWRBQD.js +1 -0
- package/dist/chunk-5AKYMAIL.js +1 -0
- package/dist/{chunk-RE773WOX.js → chunk-5PVEQ6CZ.js} +5 -5
- package/dist/{chunk-AFSZHLQT.js → chunk-7EIMPQR3.js} +1 -1
- package/dist/{chunk-3KXW53QI.js → chunk-7IHLTPZ6.js} +1 -1
- package/dist/chunk-7RIWU5TZ.js +1 -0
- package/dist/{chunk-T6OR6YOI.js → chunk-7UZVOYF5.js} +1 -1
- package/dist/chunk-B66A4TVP.js +1 -0
- package/dist/chunk-CL6TGI4Q.js +8 -0
- package/dist/chunk-FWJV7CCI.js +2 -0
- package/dist/chunk-J4AICQFB.js +1 -0
- package/dist/chunk-JICOD2GI.js +1 -0
- package/dist/{chunk-OJEWQO3Z.js → chunk-JP25YL3J.js} +17 -17
- package/dist/chunk-L2Q7B2OJ.js +1 -0
- package/dist/chunk-L3E6IRUQ.js +8 -0
- package/dist/chunk-LG6RFLPZ.js +1 -0
- package/dist/chunk-LGP6WXS2.js +4 -0
- package/dist/{chunk-VRDF2J46.js → chunk-M4VITK6X.js} +52 -50
- package/dist/chunk-NTXO7BMH.js +4 -0
- package/dist/{chunk-LPZFK3Y6.js → chunk-OW4UNG27.js} +65 -66
- package/dist/{chunk-LUP4U6EE.js → chunk-P424XYHP.js} +1 -1
- package/dist/chunk-P4SWTY5X.js +33 -0
- package/dist/chunk-TQEMLBAG.js +1 -0
- package/dist/chunk-TRMDODFM.js +13 -0
- package/dist/chunk-UNF72FTB.js +1 -0
- package/dist/chunk-V5JN4TDX.js +2 -0
- package/dist/chunk-VA5MRHKM.js +2 -0
- package/dist/chunk-XIVFLY6G.js +1 -0
- package/dist/chunk-YUX4YFGL.js +78 -0
- package/dist/{create-WRZO4HK2.js → create-DFAWAS5C.js} +1 -1
- package/dist/demo-kit-DZ7TPG7K.js +149 -0
- package/dist/doctor-PVSWDBJL.js +1 -0
- package/dist/{dotnet-webapi-clean-IPY3MCGQ.js → dotnet-webapi-clean-BYUUHX5Y.js} +20 -20
- package/dist/{gofiber-standard-N5N3QGH3.js → gofiber-standard-B6UK5GR7.js} +31 -31
- package/dist/{gogin-standard-LAWQTBWL.js → gogin-standard-BXU44VEM.js} +31 -31
- package/dist/index.d.ts +250 -24
- package/dist/index.js +218 -182
- package/dist/pipeline-ND734AJM.js +5 -0
- package/dist/{platform-capabilities-XAVU4HSM.js → platform-capabilities-YICBF4FA.js} +1 -1
- package/dist/{pythonRapidkitExec-3L3XJBSY.js → pythonRapidkitExec-UJYIB6FL.js} +1 -1
- package/dist/{springboot-standard-OZYF7ZM7.js → springboot-standard-PEHDKH2L.js} +27 -27
- package/dist/{workspace-PR6VZRBG.js → workspace-FQT3QIRS.js} +1 -1
- package/dist/workspace-agent-sync-ZYCPXTU3.js +1 -0
- package/dist/workspace-archive-EEGLHZDW.js +10 -0
- package/dist/workspace-context-WAGGJCDL.js +1 -0
- package/dist/{workspace-contract-XUGMCUSQ.js → workspace-contract-SEI4SNSG.js} +1 -1
- package/dist/workspace-explain-MVGGRCDN.js +1 -0
- package/dist/workspace-explain-contract-KT757JGQ.js +1 -0
- package/dist/{workspace-feedback-R6H4UFZB.js → workspace-feedback-RCB25NFO.js} +1 -1
- package/dist/{workspace-foundation-KGSV4E6D.js → workspace-foundation-KXDL6P6X.js} +1 -1
- package/dist/{workspace-history-CGCK2DJI.js → workspace-history-M4QQBIPB.js} +1 -1
- package/dist/workspace-intelligence-QOGD2TZS.js +1 -0
- package/dist/workspace-mcp-serve-CEFKEMYG.js +3 -0
- package/dist/{workspace-model-PNXXOGPO.js → workspace-model-GMSRBICO.js} +1 -1
- package/dist/workspace-registry-summary-S52SEJAG.js +1 -0
- package/dist/workspace-run-VC4OUPRF.js +1 -0
- package/dist/{workspace-verify-WSDUUTR5.js → workspace-verify-NP4GMFSV.js} +1 -1
- package/dist/workspace-watch-IIBH3Y25.js +1 -0
- package/docs/AI_FEATURES.md +67 -34
- package/docs/README.md +2 -1
- package/docs/commands-reference.md +26 -14
- package/docs/contracts/ARTIFACT_CATALOG.md +60 -36
- package/docs/contracts/README.md +3 -2
- package/docs/create-planner-capabilities.md +36 -18
- package/docs/workspace-operations.md +25 -0
- package/package.json +35 -13
- package/scripts/enterprise-package-smoke.mjs +40 -8
- package/scripts/prepack-enterprise.mjs +8 -0
- package/templates/kits/fastapi-ddd/.gitignore.j2 +11 -0
- package/templates/kits/fastapi-ddd/README.md.j2 +23 -18
- package/templates/kits/fastapi-ddd/common/env.example.j2 +2 -2
- package/templates/kits/fastapi-ddd/pyproject.toml.j2 +7 -7
- package/templates/kits/fastapi-ddd/src/app/config/__init__.py.j2 +1 -1
- package/templates/kits/fastapi-ddd/src/cli.py.j2 +6 -9
- package/templates/kits/fastapi-ddd/src/main.py.j2 +1 -1
- package/templates/kits/fastapi-standard/.gitignore.j2 +11 -0
- package/templates/kits/fastapi-standard/README.md.j2 +35 -30
- package/templates/kits/fastapi-standard/common/env.example.j2 +2 -2
- package/templates/kits/fastapi-standard/pyproject.toml.j2 +7 -7
- package/templates/kits/fastapi-standard/src/cli.py.j2 +7 -10
- package/templates/kits/fastapi-standard/src/main.py.j2 +1 -1
- package/templates/kits/fastapi-standard/src/routing/examples.py.j2 +1 -1
- package/templates/kits/fastapi-standard/tests/test_examples.py.j2 +1 -1
- package/templates/kits/nestjs-standard/.dockerignore.j2 +11 -0
- package/templates/kits/nestjs-standard/.eslintrc.js.j2 +25 -0
- package/templates/kits/nestjs-standard/.gitignore.j2 +22 -0
- package/templates/kits/nestjs-standard/.node-version.j2 +1 -0
- package/templates/kits/nestjs-standard/.nvmrc.j2 +1 -0
- package/templates/kits/nestjs-standard/.prettierrc.j2 +7 -0
- package/templates/kits/nestjs-standard/README.md.j2 +23 -18
- package/templates/kits/nestjs-standard/docs/README.md.j2 +2 -2
- package/templates/kits/nestjs-standard/jest.config.ts.j2 +1 -7
- package/templates/kits/nestjs-standard/package.json.j2 +1 -1
- package/templates/kits/nestjs-standard/src/config/configuration.ts.j2 +4 -4
- package/templates/kits/nestjs-standard/src/main.ts.j2 +1 -1
- package/templates/kits/nestjs-standard/src/modules/index.ts.j2 +1 -1
- package/templates/kits/nestjs-standard/tsconfig.build.json.j2 +1 -1
- package/templates/kits/nestjs-standard/tsconfig.json.j2 +1 -1
- package/dist/analyze-5BU4QIPK.js +0 -1
- package/dist/autopilot-release-QYUOVB26.js +0 -1
- package/dist/chunk-54XJNLYC.js +0 -13
- package/dist/chunk-5SWNSJGW.js +0 -1
- package/dist/chunk-753LOKFZ.js +0 -2
- package/dist/chunk-AAKUNWPR.js +0 -78
- package/dist/chunk-AQ4XZZC6.js +0 -1
- package/dist/chunk-CVTCPPEF.js +0 -1
- package/dist/chunk-DNAY5ALC.js +0 -1
- package/dist/chunk-EWYYLJQY.js +0 -2
- package/dist/chunk-LO4C4VXR.js +0 -4
- package/dist/chunk-LYC6AIF2.js +0 -2
- package/dist/chunk-NAAQMSO3.js +0 -1
- package/dist/chunk-NFUXULIF.js +0 -1
- package/dist/chunk-OL64GWQC.js +0 -9
- package/dist/chunk-PI5KUXDA.js +0 -7
- package/dist/chunk-SI3AQKIP.js +0 -1
- package/dist/chunk-VZKSNUEE.js +0 -2
- package/dist/chunk-WU4ZRRA5.js +0 -4
- package/dist/chunk-XEJD4KCV.js +0 -33
- package/dist/demo-kit-AJ5LIM5G.js +0 -149
- package/dist/doctor-MF3M3FS3.js +0 -1
- package/dist/pipeline-QCUHFWDY.js +0 -5
- package/dist/workspace-agent-sync-KTYF3HQR.js +0 -1
- package/dist/workspace-archive-GCZNI44O.js +0 -3
- package/dist/workspace-context-QUTOP2XV.js +0 -1
- package/dist/workspace-explain-JEONEGZZ.js +0 -1
- package/dist/workspace-explain-contract-DNS2YEL7.js +0 -1
- package/dist/workspace-intelligence-QJGVL37U.js +0 -1
- package/dist/workspace-mcp-serve-AK4MYEHQ.js +0 -3
- package/dist/workspace-registry-summary-RUJE6RPH.js +0 -1
- package/dist/workspace-run-Y7YMUIHX.js +0 -1
- package/dist/workspace-watch-AGPOJ74Q.js +0 -1
package/dist/chunk-5SWNSJGW.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {d,q,a as a$4}from'./chunk-T6OR6YOI.js';import {i,h}from'./chunk-4KUIFXHM.js';import {a as a$6}from'./chunk-HTYMXMQM.js';import {a as a$3,j as j$2,b as b$2}from'./chunk-VZKSNUEE.js';import {c as c$1,a as a$5,d as d$1}from'./chunk-NAAQMSO3.js';import {j as j$1}from'./chunk-RE773WOX.js';import {c,b as b$1}from'./chunk-LUP4U6EE.js';import {a}from'./chunk-GSWPGELT.js';import {a as a$2}from'./chunk-GZTYAEWX.js';import {a as a$1}from'./chunk-XZGVNGRB.js';import {p,o}from'./chunk-5XATWNME.js';import f from'path';import P from'fs-extra';import ht from'crypto';import {createRequire}from'module';var lt=new Set(["service","frontend","worker","library","infra","docs","test-suite","unknown"]);async function Ne(e){try{if(!await P.pathExists(e))return null;let t=await P.readJSON(e);return t&&typeof t=="object"?t:null}catch{return null}}async function ut(e){for(let t of e){let r=await Ne(t);if(r)return r}return null}function _e(e){if(typeof e!="string")return null;let t=e.trim().toLowerCase();return lt.has(t)?t:null}async function Te(e,t){let r=t??await ut(p(e,"project.json")),o=_e(r?.kind)??_e(r?.type);if(o)return o;let s=typeof r?.kit_name=="string"?r.kit_name:r?.kit,n=typeof r?.framework=="string"?r.framework:null,a=typeof r?.runtime=="string"?r.runtime:null,i=`${typeof s=="string"?s:""} ${n??""} ${a??""}`.trim().toLowerCase();if(/\b(frontend|nextjs|next\.js|react|vue|svelte|vite|angular|astro|remix|nuxt)\b/.test(i))return "frontend";if(/\b(fastapi|nestjs|springboot|spring boot|gofiber|gogin|dotnet|webapi|django|flask|express|fastify|python|node|java|go|rust|php|ruby|elixir)\b/.test(i))return "service";let c=await Ne(f.join(e,"package.json"));if(c){let d={...c.dependencies??{},...c.devDependencies??{}},l=c.scripts??{},p=Object.values(l).filter(u=>typeof u=="string").join(" ").toLowerCase();if(d.next||d.react||d.vue||d.svelte||d.vite||d["@angular/core"]||p.includes("next ")||p.includes("vite "))return "frontend";if(c.private===true&&!d.express&&!d["@nestjs/core"])return "library"}return await P.pathExists(f.join(e,"Dockerfile"))||await P.pathExists(f.join(e,"docker-compose.yml"))||await P.pathExists(f.join(e,"terraform.tf"))?"infra":"service"}var ft=new Set([...c().map(e=>e.id),...j$1().map(e=>e.kitId)]),mt=[{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}],H=new Map;for(let e of mt){H.set(e.id,e);for(let t of e.aliases)H.set(t,e);}var gt=new Set(["php","ruby","rust","elixir","clojure","scala","kotlin","unknown"]);function M(e){return e?.trim().toLowerCase()||void 0}function $e(e){let t=M(e.kitId)??M(e.framework)??M(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 r=e.kitId?b$1(e.kitId):void 0;if(r&&ft.has(r))return {lane:"native-create",status:"available",canExecuteCreate:true,requested:t,resolved:r,reason:"Workspai owns the create contract, project marker, registry, doctor, and workspace model path."};let o=H.get(t)??H.get(M(e.framework)??"")??H.get(M(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 Workspai owns the post-create contract."};let s=M(e.runtime);return s&>.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 wr(e){return !e.canExecuteCreate&&(e.lane==="external-create-adopt"||e.lane==="adopt-only"&&e.resolved!==void 0)}var He="workspace-dependency-graph.v1",Ve=["code-import","package-dep","event-pub-sub","service-dependsOn","shared-resource"];var Pr="rapidkit-freshness-metadata-v1";function de(e){if(Array.isArray(e))return e.map(t=>de(t));if(e&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=de(e[r]);return t}return e}function kt(e){return JSON.stringify(de(e))}function F(e){return ht.createHash("sha256").update(kt(e)).digest("hex")}var Ke=".workspai/workspace-graph.overrides.json",yt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),wt=new Set([".git",".hg",".svn",".workspai",".rapidkit",".venv","node_modules","dist","build","out","target","coverage","htmlcov",".next",".turbo",".cache"]),Le=600,ze=5,vt=256*1024,Be={inferred:1,contract:2,manual:3};function bt(e){return e.split(f.sep).join("/")}function Y(e,t){return bt(f.relative(e,t)||".")}function Ue(e){let t=new Map;for(let r of e.projects)t.has(r.name)||t.set(r.name,{id:r.name,path:r.path,...r.runtime?{runtime:r.runtime}:{},...r.framework?{framework:r.framework}:{},...r.kind?{kind:r.kind}:{}});return [...t.values()].sort((r,o)=>r.id.localeCompare(o.id))}function Je(e,t){let r=new Map,o=new Map;for(let n of t.projects){if(r.has(n.name))continue;let a=n.absolutePath?f.resolve(n.absolutePath):f.resolve(e,n.path);r.set(n.name,a),o.has(a)||o.set(a,n.name);}let s=[...o.entries()].map(([n,a])=>({dir:n,id:a})).sort((n,a)=>a.dir.length-n.dir.length||n.dir.localeCompare(a.dir));return {idToDir:r,dirToId:o,sortedDirs:s}}function Q(e,t){let r=f.resolve(t);for(let{dir:o,id:s}of e.sortedDirs)if(r===o||r.startsWith(`${o}${f.sep}`))return s;return null}async function ue(e){try{if(!await P.pathExists(e))return null;let t=await P.readJSON(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function me(e){try{return await P.pathExists(e)?await P.readFile(e,"utf8"):null}catch{return null}}async function qe(e,t){let r=[],o=new Map;for(let[s,n]of t.idToDir.entries()){let a=await ue(f.join(n,"package.json")),i=typeof a?.name=="string"?a.name.trim():"";i&&!o.has(i)&&o.set(i,s);}for(let[s,n]of t.idToDir.entries()){let a=await ue(f.join(n,"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),r.push({from:s,to:u,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:Y(e,f.join(n,"package.json")),detail:`declares dependency ${p}`}]}));}}}r.push(...await jt(e,t,s,n)),r.push(...await Et(e,t,s,n));}return r}async function jt(e,t,r,o){let s=await me(f.join(o,"pyproject.toml"));if(!s)return [];let n=[],a=new Set,i=/path\s*=\s*["']([^"']+)["']/g,c;for(;(c=i.exec(s))!==null;){let d=Q(t,f.resolve(o,c[1]));!d||d===r||a.has(d)||(a.add(d),n.push({from:r,to:d,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:Y(e,f.join(o,"pyproject.toml")),detail:`path dependency ${c[1]}`}]}));}return n}async function Et(e,t,r,o){let s=await me(f.join(o,"go.mod"));if(!s)return [];let n=[],a=new Set,i=/replace\s+\S+\s+=>\s+(\.[^\s]+)/g,c;for(;(c=i.exec(s))!==null;){let d=Q(t,f.resolve(o,c[1]));!d||d===r||a.has(d)||(a.add(d),n.push({from:r,to:d,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:Y(e,f.join(o,"go.mod")),detail:`go.mod replace ${c[1]}`}]}));}return n}async function Ct(e,t){let r=[],o=[e];for(;o.length>0&&r.length<t;){let s=o.shift();if(!s)continue;let n=[];try{n=await P.readdir(s,{withFileTypes:true});}catch{continue}let a=[],i=[];for(let c of n)if(c.isDirectory()){if(wt.has(c.name)||c.name.startsWith("."))continue;a.push(f.join(s,c.name));}else c.isFile()&&yt.has(f.extname(c.name))&&i.push(f.join(s,c.name));i.sort((c,d)=>c.localeCompare(d)),a.sort((c,d)=>c.localeCompare(d));for(let c of i){if(r.length>=t)break;r.push(c);}o.push(...a);}return r}var Pt=[/\bfrom\s+["']([^"']+)["']/g,/\bimport\s+["']([^"']+)["']/g,/\bimport\s*\(\s*["']([^"']+)["']\s*\)/g,/\brequire\s*\(\s*["']([^"']+)["']\s*\)/g];function St(e){let t=new Set;for(let r of Pt){r.lastIndex=0;let o;for(;(o=r.exec(e))!==null;){let s=o[1];s.startsWith(".")&&t.add(s);}}return [...t]}async function fe(e,t,r,o){let s=new Map;for(let[n,a]of t.idToDir.entries()){if(o&&!o.has(n))continue;let i=await Ct(a,r);for(let c of i){let d=await P.stat(c).catch(()=>null);if(!d||d.size>vt)continue;let l=await me(c);if(l)for(let p of St(l)){let u=f.resolve(f.dirname(c),p),m=Q(t,u);if(!m||m===n)continue;let S=`${n}\0${m}`,w=s.get(S);w||(w={from:n,to:m,evidence:[]},s.set(S,w)),w.evidence.length<ze&&w.evidence.push({file:Y(e,c),detail:`imports ${p}`});}}}return [...s.values()].map(n=>({from:n.from,to:n.to,kind:"code-import",source:"inferred",confidence:"medium",evidence:n.evidence}))}function Wt(e,t,r){let o=new Map;for(let s of r.projects){let n=xt(e,t,s);n&&o.set(s.slug,n);}return o}function xt(e,t,r){let o=[r.relativePath,r.externalPath].filter(s=>typeof s=="string"&&s.length>0);for(let s of o){let n=f.resolve(e,s),a=t.dirToId.get(n)??Q(t,n);if(a)return a}return t.idToDir.has(r.slug)?r.slug:null}function Xe(e,t,r){let o=[],s=Wt(e,t,r),n=b$2,a=new Map,i=new Map;for(let c of r.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:n,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:n,detail:`consumes event ${c}`}]});}return o.push(...Rt(r,s)),o}function pe(e){return e.toLowerCase().replace(/[^a-z0-9]/g,"")}function Rt(e,t){let r=[],o=e.projects.map(s=>({project:s,id:t.get(s.slug)})).filter(s=>!!s.id).filter(s=>pe(s.project.slug).length>=3);for(let s of e.projects){let n=t.get(s.slug);if(!n)continue;let a=s.contracts?.env??[];if(a.length===0)continue;let i=new Set;for(let c of a){let d=pe(c);for(let l of o)l.id===n||i.has(l.id)||!(d.includes(pe(l.project.slug))&&(l.project.ports?.length??0)>0)||(i.add(l.id),r.push({from:n,to:l.id,kind:"shared-resource",source:"inferred",confidence:"low",evidence:[{file:b$2,detail:`env ${c} references ${l.project.slug}`}]}));}}return r}async function Ye(e,t){let r=await ue(f.join(e,Ke)),o=Array.isArray(r?.edges)?r?.edges:[],s=[],n=new Set(Ve);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||!n.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:Ke,detail:"manual edge"}]});}return s}function At(e){return `${e.from}\0${e.to}\0${e.kind}`}function It(e){let t=new Set,r=[];for(let o of e){let s=`${o.file}\0${o.detail??""}`;t.has(s)||(t.add(s),r.push(o));}return r.sort((o,s)=>o.file.localeCompare(s.file)||(o.detail??"").localeCompare(s.detail??"")).slice(0,ze)}function Mt(e){let t=new Map;for(let r of e){let o=At(r),s=t.get(o);if(!s){t.set(o,{...r,evidence:[...r.evidence]});continue}let n=Be[s.source],a=Be[r.source];a>n?t.set(o,{...r,evidence:[...r.evidence,...s.evidence]}):a===n&&s.evidence.push(...r.evidence);}return [...t.values()].map(r=>({from:r.from,to:r.to,kind:r.kind,source:r.source,confidence:r.confidence,evidence:It(r.evidence)})).sort((r,o)=>r.from.localeCompare(o.from)||r.to.localeCompare(o.to)||r.kind.localeCompare(o.kind)||r.source.localeCompare(o.source))}function le(e){return Math.round(e*1e3)/1e3}function Ft(e){return Math.max(0,Math.min(100,Math.round(e)))}function Dt(e){return e>=75?"critical":e>=50?"high":e>=20?"medium":"low"}function Ot(e){return e==="critical"||e==="high"?"strict":e==="medium"?"elevated":"normal"}function Gt(e,t){let r=a$6({nodes:e,edges:t}),o=new Map;for(let s of e){let n=r.byId.get(s.id)??{fanIn:0,fanOut:0,reach:0,betweenness:0,isHotspot:false},a=t.filter(m=>m.from===s.id||m.to===s.id),i=a.filter(m=>m.source==="contract"||m.source==="manual").length,c=a.filter(m=>m.confidence==="low").length,d=[],l=n.reach*20+n.fanIn*14+n.fanOut*8+Math.min(20,n.betweenness*4)+i*8;n.isHotspot&&(l+=24,d.push("Critical-path hotspot in dependency graph")),n.reach>0&&d.push(`Change reaches ${n.reach} dependent project(s)`),n.fanIn>0&&d.push(`${n.fanIn} direct dependent project(s)`),n.fanOut>0&&d.push(`${n.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=Ft(l),u=Dt(p);o.set(s.id,{weight:u,score:p,verificationPriority:Ot(u),reasons:d.slice(0,5),centrality:{fanIn:n.fanIn,fanOut:n.fanOut,reach:n.reach,betweenness:n.betweenness,isHotspot:n.isHotspot}});}return o}function _t(e,t){let r=Gt(e,t);return e.map(o=>({...o,operationalProfile:r.get(o.id)}))}function Nt(e,t){let r=new Set;for(let c of t)r.add(c.from),r.add(c.to);let o=e.length,s=t.length,n=e.filter(c=>r.has(c.id)).length,a=Math.max(0,o-n),i=a$6({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:n,density:le(o>1?s/(o*(o-1)):0),edgeCoverageRatio:le(o>0?n/o:1),evidenceCoverageRatio:le(s>0?t.filter(c=>c.evidence.length>0).length/s:1),hotspotCount:i.hotspots.length,hasCycle:$t(e,t)}}function Tt(e,t,r){let o=[],s=e.filter(n=>!t.some(a=>a.from===n.id||a.to===n.id)).map(n=>n.id).sort((n,a)=>n.localeCompare(a));return r.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."}),r.nodeCount>1&&r.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}):r.orphanCount>0&&o.push({code:"graph.orphans.detected",severity:"warning",message:`${r.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)}),r.lowConfidenceEdges>0&&o.push({code:"graph.low_confidence_edges",severity:"info",message:`${r.lowConfidenceEdges} inferred edge(s) are low confidence.`,recommendation:"Promote important low-confidence relationships to workspace contract or manual overrides."}),r.edgeCount>0&&r.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."}),r.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((n,a)=>{let i={error:0,warning:1,info:2};return i[n.severity]-i[a.severity]||n.code.localeCompare(a.code)})}function $t(e,t){let r=new Map;for(let c of e)r.set(c.id,[]);for(let c of t)r.has(c.from)||r.set(c.from,[]),r.get(c.from)?.push(c.to);let o=0,s=1,n=2,a=new Map;for(let c of r.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=r.get(l.id)??[];if(l.index>=p.length){a.set(l.id,n),d.pop();continue}let u=p[l.index];l.index+=1;let m=a.get(u)??o;if(m===s)return true;m===o&&(a.set(u,s),d.push({id:u,index:0}));}return false};for(let c of [...r.keys()].sort())if(a.get(c)===o&&i(c))return true;return false}function Qe(e,t,r,o){let s=Mt(r.filter(c=>t.has(c.from)&&t.has(c.to))),n=_t(e,s),a=Nt(e,s),i=Tt(e,s,a);return {schemaVersion:He,generatedAt:(o??new Date).toISOString(),nodes:n,edges:s,stats:a,...i.length>0?{diagnostics:i}:{}}}async function Ze(e){let t=f.resolve(e.workspacePath),r=e.maxImportFilesPerProject??Le,o=Ue(e.model),s=new Set(o.map(i=>i.id)),n=Je(t,e.model),a=[];return a.push(...await qe(t,n)),a.push(...await fe(t,n,r)),e.contract&&a.push(...Xe(t,n,e.contract)),a.push(...await Ye(t,s)),Qe(o,s,a,e.now)}async function et(e){let t=f.resolve(e.workspacePath),r=e.maxImportFilesPerProject??Le,o=Ue(e.model),s=new Set(o.map(i=>i.id)),n=Je(t,e.model),a=[];if(a.push(...await qe(t,n)),e.structuralChange)a.push(...await fe(t,n,r));else {a.push(...await fe(t,n,r,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(...Xe(t,n,e.contract)),a.push(...await Ye(t,s)),Qe(o,s,a,e.now)}var he="workspace-model-cache.v1",ge=".workspai/cache/workspace-model.v1.json",tt=["package.json","pyproject.toml","requirements.txt","go.mod","go.sum","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","composer.json","Gemfile","workspai.project.json",".workspai/project.json",".workspai/context.json","rapidkit.project.json",".rapidkit/project.json",".rapidkit/context.json"],rt=[".workspai/workspace.contract.json",".workspai/workspace.json","workspai.workspace.json",".workspai/policies.yml",".workspai/policies.yaml",".rapidkit/workspace.contract.json",".rapidkit/workspace.json","rapidkit.workspace.json",".rapidkit/policies.yml",".rapidkit/policies.yaml"],Kt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),Bt=new Set([".git",".workspai",".rapidkit","node_modules","dist","build","out","target","coverage",".next",".turbo",".cache",".venv"]),Lt=1500,V=null;function ke(){if(V)return V;try{V=createRequire(import.meta.url)("../package.json")?.version??"0.0.0";}catch{V="0.0.0";}return V}async function Z(e){try{let t=await P.readFile(e);return ht.createHash("sha256").update(t).digest("hex")}catch{return null}}async function zt(e){let t={};for(let s of tt){let n=await Z(f.join(e,s));n&&(t[s]=n);}let r=[],o=[e];for(;o.length>0&&r.length<Lt;){let s=o.shift();if(!s)continue;let n=[];try{n=await P.readdir(s,{withFileTypes:true});}catch{continue}let a=[];for(let i of n)if(i.isDirectory()){if(Bt.has(i.name)||i.name.startsWith("."))continue;a.push(f.join(s,i.name));}else if(i.isFile()&&Kt.has(f.extname(i.name))){let c=f.join(s,i.name),d=await P.stat(c).catch(()=>null);if(d){let l=f.relative(e,c).split(f.sep).join("/");r.push(`${l}:${d.size}:${Math.round(d.mtimeMs)}`);}}a.sort((i,c)=>i.localeCompare(c)),o.push(...a);}return r.sort((s,n)=>s.localeCompare(n)),F({manifests:t,source:r})}async function ee(e,t){let r=f.resolve(e),o={},s=[...new Set(t.map(n=>f.relative(r,f.resolve(n)).split(f.sep).join("/")))].sort((n,a)=>n.localeCompare(a));for(let n of s)o[n]=await zt(f.join(r,n));return o}async function te(e){let t=f.resolve(e),r={};for(let o of rt){let s=await Z(f.join(t,o));s&&(r[o]=s);}return r}async function re(e){let t=f.resolve(e.workspacePath),r=[...new Set(e.projectPaths.map(n=>f.relative(t,f.resolve(n)).split(f.sep).join("/")))].sort((n,a)=>n.localeCompare(a)),o=[];for(let n of r){let a={};for(let i of tt){let c=await Z(f.join(t,n,i));c&&(a[i]=c);}o.push({project:n,manifests:a});}let s={};for(let n of rt){let a=await Z(f.join(t,n));a&&(s[n]=a);}return F({cacheSchema:he,cliVersion:e.cliVersion,flags:e.flags,workspaceJson:e.workspaceJson??null,marker:e.marker??null,projects:o,workspaceFiles:s})}async function ye(e){let t=await c$1(e,ge)??a$5(e,ge);try{if(!await P.pathExists(t))return null;let r=await P.readJson(t);return !r||r.schemaVersion!==he||typeof r.inputsHash!="string"||typeof r.cliVersion!="string"||!r.model?null:r}catch{return null}}async function ne(e,t){let r={schemaVersion:he,...t};return d$1(e,ge,r)}var nt="rapidkit-fact-freshness-v1",B={durable:720*60*60,derived:10080*60,evidenceBacked:1440*60,live:300,verifyBeforeUse:1440*60};function Ut(e){switch(e){case "durable":return B.durable;case "derived":return B.derived;case "evidence-backed":return B.evidenceBacked;case "live":return B.live;case "verify-before-use":return B.verifyBeforeUse}}function Jt(e){if(e.status)return e.status;if(e.ttlSeconds===null)return "unknown";let t=Date.parse(e.generatedAt);if(!Number.isFinite(t))return "unknown";let r=t+e.ttlSeconds*1e3;return e.now.getTime()>r?"stale":"fresh"}function qt(e){let t=e.now??new Date,r=e.generatedAt??t.toISOString(),o=e.ttlSeconds===void 0?Ut(e.kind):e.ttlSeconds,s=Jt({generatedAt:r,ttlSeconds:o,status:e.status,now:t}),n=o===null?void 0:new Date(Date.parse(r)+o*1e3),a=e.verifyBeforeUse??(e.kind==="live"||e.kind==="verify-before-use"||e.category!=="structure"||s!=="fresh");return {schemaVersion:nt,kind:e.kind,category:e.category,generatedAt:r,ttlSeconds:o,...n?{expiresAt:n.toISOString()}:{},status:s,verifyBeforeUse:a,...e.sourceArtifact?{sourceArtifact:e.sourceArtifact}:{},...e.sourcePath?{sourcePath:e.sourcePath}:{},inputsHash:e.inputsHash??F(e.value??null),reason:e.reason}}function v(e){return {id:e.id,label:e.label,scope:e.scope,value:e.value,...e.project?{project:e.project}:{},freshness:qt({...e.freshness,value:e.value})}}function ot(e){let t=e.generatedAt??(e.now??new Date).toISOString(),r={durable:0,derived:0,"evidence-backed":0,live:0,"verify-before-use":0},o={structure:0,verification:0,state:0},s=0,n=0,a=0,i=0;for(let c of e.facts)r[c.freshness.kind]+=1,o[c.freshness.category]+=1,c.freshness.status==="stale"&&(s+=1),c.freshness.status==="unknown"&&(n+=1),c.freshness.kind==="live"&&(a+=1),c.freshness.verifyBeforeUse&&(i+=1);return {schemaVersion:nt,generatedAt:t,status:s>0?"stale":n>0?"unknown":"fresh",totalFacts:e.facts.length,staleFacts:s,unknownFacts:n,liveFacts:a,verifyBeforeUseFacts:i,byKind:r,byCategory:o}}var Xt="workspace-model.v1",at=".workspai/reports/workspace-model.json",Yt=["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"],Qt=new Set([".git",".hg",".svn",".workspai",".rapidkit",".venv","node_modules","dist","build","target","coverage","htmlcov",".next",".turbo"]);function it(e,t){return (f.relative(e,t)||".").split(f.sep).join("/")}async function ct(e){try{if(!await P.pathExists(e))return null;let t=await P.readJSON(e);return t&&typeof t=="object"?t:null}catch{return null}}async function Zt(e,t){for(let r of t)if(await P.pathExists(f.join(e,r)))return true;return false}function we(e){let t=Number.parseInt(process.env.RAPIDKIT_WORKSPACE_MODEL_SCAN_DEPTH??"",10),r=typeof e=="number"&&Number.isFinite(e)?e:Number.isFinite(t)?t:4;return Math.min(12,Math.max(1,Math.trunc(r)))}async function ve(e,t){let r=f.resolve(e),o=[{dirPath:r,depth:0}],s=new Set,n=new Set;for(;o.length>0;){let a=o.shift();if(!a)continue;let i=f.resolve(a.dirPath);if(n.has(i))continue;if(n.add(i),i!==r&&await Zt(i,Yt)){s.add(i);continue}if(a.depth>=t)continue;let c=[];try{c=await P.readdir(i,{withFileTypes:true});}catch{continue}for(let d of c)!d.isDirectory()||Qt.has(d.name)||d.name.startsWith(".")&&d.name!==".config"||o.push({dirPath:f.join(i,d.name),depth:a.depth+1});}return Array.from(s).sort((a,i)=>a.localeCompare(i))}function be(e){let t=new Set,r=[];for(let o of e){let s=f.resolve(o);t.has(s)||(t.add(s),r.push(s));}return r.sort((o,s)=>o.localeCompare(s))}function st(e,t){let r=e?.[t];return typeof r=="string"&&r.trim()?r.trim():void 0}function er(e,t){return e?.[t]===true}function tr(e,t,r){let o=e?.frontend&&typeof e.frontend=="object"&&!Array.isArray(e.frontend)?e.frontend:void 0,s=st(o,"generator"),n=st(o,"command_display"),a=typeof t=="string"&&t.startsWith("frontend.");if(!(!s&&!a))return {...s?{id:s}:{},...t?{kit:t}:{},displayName:r,source:er(o,"official_generator")?"official-generator":"metadata",...n?{commandDisplay:n}:{}}}async function rr(e){let t=[".workspai/project.json",".workspai/context.json",".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"],r=[];for(let o of t)await P.pathExists(f.join(e,o))&&r.push(o);return r}async function j(e,t,r){let o=await c$1(e,t),s=o!==null,n={path:t.split(f.sep).join("/"),exists:s};if(o&&r){let a=await ct(o);typeof a?.generatedAt=="string"&&(n.generatedAt=a.generatedAt);let i=a?.status??a?.result??a?.verdict;typeof i=="string"&&(n.status=i);}return n}async function nr(e,t,r){let s=`${it(e,t)}/.workspai/reports`,n=await j(e,`${s}/doctor-project-last-run.json`,r);return {doctor:n?.exists===true?n:await j(e,`${s}/doctor-last-run.json`,r),remediationPlan:await j(e,`${s}/doctor-remediation-plan-last-run.json`,r),fixResult:await j(e,`${s}/doctor-fix-result-last-run.json`,r),analyze:await j(e,`${s}/analyze-last-run.json`,r),readiness:await j(e,`${s}/release-readiness-last-run.json`,r)}}async function or(e,t,r){let o=d(t),s=i(t,o),n=q(t),a=a$4(s.runtime),i$1=await Te(t,o),c=typeof o?.name=="string"&&o.name.trim()?o.name.trim():f.basename(t),d$1=typeof o?.kit_name=="string"?o.kit_name:typeof o?.kit=="string"?o.kit:void 0,l=typeof o?.engine=="string"?o.engine:n.engine!=="unknown"?n.engine:void 0,p=tr(o,d$1,s.displayName),u=$e({kitId:d$1,framework:s.key,runtime:s.runtime});return {name:c,path:it(e,t),...r.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:n.moduleSupport,...d$1?{kit:d$1}:{},...l?{engine:l}:{},...p?{generator:p}:{},createCapability:u,commands:{supported:n.supportedCommands,unsupported:n.unsupportedCommands,global:n.globalCommands,fleetStages:n.fleetStages,localOnly:n.localOnlyCommands,map:n.commandMap},importantFiles:await rr(t),evidence:await nr(e,t,r.includeEvidence),provenance:{path:"filesystem discovery",runtime:s.source,framework:s.source,commands:"project command capability matrix",createCapability:"create planner capability contract",evidence:"project .workspai/reports"}}}async function je(e){for(let t of o(e,"workspace.json")){let r=await ct(t);if(r)return r}return null}function sr(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 ar(e){let t=new Set;for(let r of e){let o=`${r.name} ${r.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 C(e,t,r,o){return {severity:e,code:t,message:r,target:o}}function dt(e){let t=[];e.workspace.name.trim()||t.push(C("error","workspace.name.missing","Workspace name could not be resolved.","workspace")),e.workspace.type==="observed-workspace"&&t.push(C("warning","workspace.marker.missing","Workspace marker is missing; model is based on filesystem observation.","workspace.marker")),e.summary.projectCount===0&&t.push(C("warning","workspace.projects.empty","No project roots were detected in this workspace.","projects")),e.contracts.exists||t.push(C("warning","workspace.contract.missing","Workspace contract is missing; dependency and API edges may be incomplete.",e.contracts.workspaceContractPath));let r=new Map;for(let n of e.projects){let a=n.name.toLowerCase(),i=r.get(a)??[];i.push(n),r.set(a,i),n.importantFiles.length||t.push(C("warning","project.markers.missing",`Project ${n.name} has no important manifest files recorded.`,n.path)),n.runtime==="unknown"&&t.push(C("warning","project.runtime.unknown",`Project ${n.name} runtime could not be confidently detected.`,n.path));let c=["test","build"];for(let p of c)n.commands.supported.includes(p)&&n.commands.unsupported.includes(p)&&t.push(C("error","project.commands.conflict",`Project ${n.name} marks ${p} as both supported and unsupported.`,n.path));let d=new Set(n.commands.fleetStages),l=new Set(n.commands.localOnly);for(let p of n.commands.fleetStages){l.has(p)&&t.push(C("error","project.commands.scope-conflict",`Project ${n.name} marks ${p} as both fleet and local-only.`,n.path));let u=n.commands.map[p];(!u||u.status!=="supported"||u.fleetEligible!==true||u.executionScope!=="fleet")&&t.push(C("error","project.commands.fleet-stage-invalid",`Project ${n.name} advertises ${p} as a fleet stage without a supported fleet capability.`,n.path));}for(let p of n.commands.localOnly){let u=n.commands.map[p];(!u||u.status!=="supported"||u.executionScope!=="local-only"||u.fleetEligible===true)&&t.push(C("error","project.commands.local-only-invalid",`Project ${n.name} advertises ${p} as local-only without a matching local-only capability.`,n.path));}for(let p of Object.values(n.commands.map))p.status==="supported"&&(p.fleetEligible===true&&!d.has(p.command)&&t.push(C("error","project.commands.fleet-stage-missing",`Project ${n.name} capability ${p.command} is fleet-eligible but missing from fleetStages.`,n.path)),p.executionScope==="local-only"&&p.fleetEligible!==true&&!l.has(p.command)&&t.push(C("error","project.commands.local-only-missing",`Project ${n.name} capability ${p.command} is local-only but missing from localOnly commands.`,n.path)));}for(let[n,a]of r.entries())a.length>1&&t.push(C("error","project.name.duplicate",`Project name "${n}" is ambiguous across ${a.length} project roots.`,a.map(i=>i.path).join(", ")));let o=t.filter(n=>n.severity==="error").length,s=t.filter(n=>n.severity==="warning").length;return {status:o>0?"failed":s>0?"warning":"passed",errors:o,warnings:s,issues:t}}function un(e){return dt(e)}function b(e){return e.join(".")}function ir(e,t){let r=at,o=e.generatedAt,s=[v({id:"workspace.name",label:"Workspace name",scope:"workspace",value:e.workspace.name,freshness:{kind:"durable",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["workspace","name"]),reason:"Workspace identity is structural metadata and changes through workspace setup."}}),v({id:"workspace.type",label:"Workspace type",scope:"workspace",value:e.identity.workspaceType,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["identity","workspaceType"]),reason:"Workspace type is derived from the current project inventory."}}),v({id:"workspace.projectCount",label:"Project count",scope:"workspace",value:e.summary.projectCount,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["summary","projectCount"]),reason:"Project count is derived from workspace discovery and should be refreshed after structural changes."}}),v({id:"workspace.runtimeFamilies",label:"Runtime families",scope:"workspace",value:e.identity.runtimeFamilies,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["identity","runtimeFamilies"]),reason:"Runtime coverage is inferred from project surfaces."}}),v({id:"workspace.policyMode",label:"Workspace policy mode",scope:"policy",value:e.policies.mode,freshness:{kind:"durable",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["policies","mode"]),reason:"Policy mode is configuration, not runtime state."}}),v({id:"workspace.contract.exists",label:"Workspace contract presence",scope:"contract",value:e.contracts.exists,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["contracts","exists"]),reason:"Contract presence is derived from workspace files and should be refreshed before release gating."}})];e.graph&&s.push(v({id:"graph.edgeCount",label:"Dependency graph edge count",scope:"graph",value:e.graph.stats.edgeCount,freshness:{kind:"derived",category:"structure",generatedAt:e.graph.generatedAt??o,now:t,sourceArtifact:r,sourcePath:b(["graph","stats","edgeCount"]),reason:"Graph topology is derived from manifests, imports, and workspace contracts."}}),v({id:"graph.evidenceCoverageRatio",label:"Dependency graph evidence coverage",scope:"graph",value:e.graph.stats.evidenceCoverageRatio,freshness:{kind:"derived",category:"structure",generatedAt:e.graph.generatedAt??o,now:t,sourceArtifact:r,sourcePath:b(["graph","stats","evidenceCoverageRatio"]),reason:"Graph evidence coverage changes when dependency evidence or contract edges change."}}));for(let[n,a]of e.projects.entries()){let i=`projects[${n}]`,c={kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,reason:"Project facts are derived from workspace discovery, project metadata, and framework probes."};s.push(v({id:`project.${a.name}.kind`,label:`${a.name} kind`,scope:"project",project:a.name,value:a.kind,freshness:{...c,sourcePath:b([i,"kind"])}}),v({id:`project.${a.name}.runtime`,label:`${a.name} runtime`,scope:"project",project:a.name,value:a.runtime,freshness:{...c,sourcePath:b([i,"runtime"])}}),v({id:`project.${a.name}.framework`,label:`${a.name} framework`,scope:"project",project:a.name,value:a.frameworkDisplayName,freshness:{...c,sourcePath:b([i,"frameworkDisplayName"])}}),v({id:`project.${a.name}.supportTier`,label:`${a.name} support tier`,scope:"project",project:a.name,value:a.supportTier,freshness:{...c,sourcePath:b([i,"supportTier"])}}),v({id:`project.${a.name}.safeFleetStages`,label:`${a.name} safe fleet stages`,scope:"command",project:a.name,value:a.commands.fleetStages,freshness:{...c,sourcePath:b([i,"commands","fleetStages"]),reason:"Safe command availability is derived from package and project command surfaces."}}));for(let[d,l]of Object.entries(a.evidence))s.push(v({id:`project.${a.name}.evidence.${d}`,label:`${a.name} ${d} evidence`,scope:"evidence",project:a.name,value:l?{path:l.path,exists:l.exists,status:l.status??null}:{exists:false},freshness:{kind:l?.exists?"evidence-backed":"verify-before-use",category:"verification",generatedAt:l?.generatedAt??o,now:t,sourceArtifact:l?.path??r,sourcePath:b([i,"evidence",d]),verifyBeforeUse:true,reason:l?.exists?"Evidence reports can expire or become stale after source changes.":"Missing evidence must be generated before this fact is used for verification."}}));}for(let[n,a]of Object.entries(e.evidence))s.push(v({id:`workspace.evidence.${n}`,label:`Workspace ${n} evidence`,scope:"evidence",value:a?{path:a.path,exists:a.exists,status:a.status??null}:null,freshness:{kind:a?.exists?"evidence-backed":"verify-before-use",category:"verification",generatedAt:a?.generatedAt??o,now:t,sourceArtifact:a?.path??r,sourcePath:b(["evidence",n]),verifyBeforeUse:true,reason:a?.exists?"Workspace evidence can expire or become stale after project, dependency, or policy changes.":"Missing workspace evidence must be generated before release or repair decisions."}}));return s}async function oe(e){let t=f.resolve(e.workspacePath),r=e.includeAbsolutePaths===true,o$1=e.includeEvidence===true,s=we(e.observableScanDepth),n=e.now??new Date,[a$3,i,c,d,l]=await Promise.all([a(t),je(t),a$1(t),a$2(t,{descendIntoMatchedProjects:false}),ve(t,s)]),p=be([...d,...l,...c.map(g=>f.isAbsolute(g.path)?g.path:f.join(t,g.path))]),u=e.reuseProjectModels,m=await Promise.all(p.map(g=>{if(u){let pt=f.relative(t,f.resolve(g)).split(f.sep).join("/"),Ee=u.get(pt);if(Ee)return Promise.resolve(Ee)}return or(t,g,{includeAbsolutePaths:r,includeEvidence:o$1})})),S=typeof i?.workspace_name=="string"?i.workspace_name:typeof i?.name=="string"?i.name:a$3?.name||f.basename(t),w=typeof i?.profile=="string"?i.profile:typeof i?.mode=="string"?i.mode:void 0,O=Array.from(new Set(m.map(g=>g.kind))).sort(),A=Array.from(new Set(m.map(g=>g.runtime))).sort(),se=Array.from(new Set(m.map(g=>g.framework))).sort(),G=[".workspai/policies.yml",".workspai/policies.yaml",".rapidkit/policies.yml",".rapidkit/policies.yaml"].find(g=>P.existsSync(f.join(t,g))),_=o(t,"workspace.contract.json").map(g=>f.relative(t,g).split(f.sep).join("/")).find(g=>P.existsSync(f.join(t,g)))??".workspai/workspace.contract.json",W=await P.pathExists(f.join(t,_)),L={schemaVersion:Xt,generatedAt:n.toISOString(),workspace:{name:S,root:t,...w?{profile:w}:{},type:a$3?"rapidkit-workspace":"observed-workspace",...a$3?{marker:{createdBy:a$3.createdBy,version:a$3.version,createdAt:a$3.createdAt}}:{}},identity:{workspaceType:sr(m),surfaces:O,runtimeFamilies:A,businessCapabilities:ar(m)},discovery:{observableScanDepth:s},projects:m,policies:{mode:typeof i?.policy_mode=="string"?i.policy_mode:typeof i?.policyMode=="string"?i.policyMode:"warn",source:G??null,exists:!!G},contracts:{workspaceContractPath:_,exists:W,status:W?"known":"missing"},evidence:{doctor:await j(t,".workspai/reports/doctor-last-run.json",o$1),projectDoctor:await j(t,".workspai/reports/doctor-project-last-run.json",o$1),doctorRemediationPlan:await j(t,".workspai/reports/doctor-remediation-plan-last-run.json",o$1),artifactRemediationPlan:await j(t,".workspai/reports/artifact-remediation-plan-last-run.json",o$1),doctorFixResult:await j(t,".workspai/reports/doctor-fix-result-last-run.json",o$1),analyze:await j(t,".workspai/reports/analyze-last-run.json",o$1),readiness:await j(t,".workspai/reports/release-readiness-last-run.json",o$1),pipeline:await j(t,".workspai/reports/pipeline-last-run.json",o$1)},summary:{projectCount:m.length,runtimes:A,frameworks:se,firstClassProjects:m.filter(g=>g.supportTier==="first-class").length,observedProjects:m.filter(g=>g.supportTier==="observed").length}},N=await lr(t,L,{contractExists:W,now:n,incrementalGraph:e.incrementalGraph}),T={...L,graph:N},y=dt(T),E=ir({...T},n),I=ot({facts:E,generatedAt:n.toISOString(),now:n});return {...T,facts:E,factFreshness:I,validation:y}}async function fn(e){if(e.cache!==true)return {model:await oe(e),cache:"disabled"};let t=f.resolve(e.workspacePath),r=we(e.observableScanDepth),o=ke(),[s,n,a$3,i,c]=await Promise.all([a(t),je(t),a$1(t),a$2(t,{descendIntoMatchedProjects:false}),ve(t,r)]),d=be([...i,...c,...a$3.map(w=>f.isAbsolute(w.path)?w.path:f.join(t,w.path))]),l=await re({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:r},projectPaths:d,workspaceJson:n,marker:s}),p=await ye(t);if(p&&p.cliVersion===o&&p.inputsHash===l)return {model:p.model,cache:"hit"};let u=await oe({...e}),[m,S]=await Promise.all([ee(t,d),te(t)]);return await ne(t,{cliVersion:o,inputsHash:l,generatedAt:(e.now??new Date).toISOString(),model:u,projectSignatures:m,workspaceFileSignatures:S}),{model:u,cache:"miss"}}function cr(e,t){let r=new Set,o=new Set,s=new Set;for(let[n,a]of Object.entries(t))n in e?e[n]!==a&&r.add(n):o.add(n);for(let n of Object.keys(e))n in t||s.add(n);return {changed:r,added:o,removed:s}}function dr(e={},t={}){let r=new Set([...Object.keys(e),...Object.keys(t)]);for(let o of r)if(e[o]!==t[o])return false;return true}async function mn(e){let t=f.resolve(e.workspacePath),r=we(e.observableScanDepth),o=ke(),s=e.now??new Date,[n,a$3,i,c,d]=await Promise.all([a(t),je(t),a$1(t),a$2(t,{descendIntoMatchedProjects:false}),ve(t,r)]),l=be([...c,...d,...i.map(y=>f.isAbsolute(y.path)?y.path:f.join(t,y.path))]),p=await ye(t),u=async()=>{let y=await oe({...e}),E=await re({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:r},projectPaths:l,workspaceJson:a$3,marker:n}),[I,g]=await Promise.all([ee(t,l),te(t)]);return await ne(t,{cliVersion:o,inputsHash:E,generatedAt:s.toISOString(),model:y,projectSignatures:I,workspaceFileSignatures:g}),{model:y,mode:"full"}};if(!p||p.cliVersion!==o||!p.projectSignatures||!p.model?.graph)return u();let m=await te(t);if(!dr(p.workspaceFileSignatures,m))return u();let S=await ee(t,l),{changed:w,added:O,removed:A}=cr(p.projectSignatures,S);if(w.size===0&&O.size===0&&A.size===0)return {model:p.model,mode:"unchanged"};let se=new Set([...w,...O]),G=new Map;for(let y of p.model.projects){let E=y.path.split(f.sep).join("/");!se.has(E)&&!A.has(E)&&G.set(E,y);}let _=new Set,W=false;for(let y of p.model.projects){let E=y.path.split(f.sep).join("/");w.has(E)&&_.add(y.name);}let L=O.size>0||A.size>0,N=await oe({...e,reuseProjectModels:G,incrementalGraph:{previousGraph:p.model.graph,changedProjectIds:_,structuralChange:L||W}});for(let y of p.model.projects){let E=y.path.split(f.sep).join("/");if(!w.has(E))continue;let I=N.projects.find(g=>g.path.split(f.sep).join("/")===E);if(I&&I.name!==y.name){W=true;break}}if(W)return u();let T=await re({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:r},projectPaths:l,workspaceJson:a$3,marker:n});return await ne(t,{cliVersion:o,inputsHash:T,generatedAt:s.toISOString(),model:N,projectSignatures:S,workspaceFileSignatures:m}),{model:N,mode:"incremental"}}async function pr(e){try{let{contract:t}=await j$2({workspacePath:e});return t&&typeof t=="object"?t:null}catch{return null}}async function lr(e,t,r){let o=r.contractExists?await pr(e):null;try{return r.incrementalGraph?await et({workspacePath:e,model:t,contract:o,now:r.now,previousGraph:r.incrementalGraph.previousGraph,changedProjectIds:r.incrementalGraph.changedProjectIds,structuralChange:r.incrementalGraph.structuralChange}):await Ze({workspacePath:e,model:t,contract:o,now:r.now})}catch{let s=t.projects.map(n=>({id:n.name,path:n.path}));return {schemaVersion:"workspace-dependency-graph.v1",generatedAt:r.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(n=>n.id).sort((n,a)=>n.localeCompare(a))}]:void 0}}}async function gn(e,t){let r=f.join(t,at);return await P.ensureDir(f.dirname(r)),await P.writeJSON(r,a$3(e),{spaces:2}),r}export{Pr as a,F as b,nt as c,v as d,ot as e,$e as f,wr as g,Te as h,He as i,Xt as j,at as k,un as l,ir as m,oe as n,fn as o,mn as p,gn as q};
|
package/dist/chunk-753LOKFZ.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import {o,l}from'./chunk-5XATWNME.js';import s from'fs';import p from'path';var i="workspace-run-v1",a="workspace-run-last.json",E=`.workspai/reports/${a}`;var W=new Set(["init","test","build","start"]);function P(e){return W.has(e)}async function d(e){try{return await s.promises.access(e,s.constants.F_OK),true}catch{return false}}async function w(e){try{let t=await s.promises.readFile(e,"utf-8");return JSON.parse(t)}catch{return null}}async function A(e,t){await s.promises.mkdir(p.dirname(e),{recursive:true}),await s.promises.writeFile(e,`${JSON.stringify(t,null,2)}
|
|
2
|
-
`,"utf-8");}function S(e){return !e||typeof e!="object"||Array.isArray(e)?null:e}function _(e){let t=e.stage;return typeof t!="string"||t.trim().length===0||!Array.isArray(e.projects)?false:P(t)||/^[a-z][a-z0-9_-]*$/i.test(t)}function h(e){let t=S(e);return !t||t.schemaVersion===i?false:_(t)}function N(e){let t=S(e);return t?t.schemaVersion===i&&t.stages!=null:false}function R(e){if(N(e))return e;if(h(e)){let t=e.stage;return {schemaVersion:i,generatedAt:e.generatedAt,workspacePath:e.workspacePath,latestStage:t,stages:{[t]:e},enterpriseControls:e.enterpriseControls??{jsonReady:true,evidencePath:E}}}return null}function x(e,t){let r=R(e);if(!r)return null;let n=t??r.latestStage;return r.stages[n]??null}async function L(e){let t=(await Promise.all(o(p.resolve(e),"reports",a).map(async n=>await d(n)?n:null))).find(n=>typeof n=="string");if(!t)return null;let r=await w(t);return R(r)}async function I(e,t){let r=p.resolve(e),n=l(r,"reports",a),c=(await Promise.all(o(r,"reports",a).map(async o=>await d(o)?o:null))).find(o=>typeof o=="string"),m=c?await w(c):null,l$1=R(m),g=l$1?{...l$1.stages}:{};g[t.stage]=t;let k={schemaVersion:i,generatedAt:t.generatedAt,workspacePath:t.workspacePath,latestStage:t.stage,stages:g,enterpriseControls:{jsonReady:true,evidencePath:E}};return await A(n,k),k}export{a,E as b,x as c,L as d,I as e};
|
package/dist/chunk-AAKUNWPR.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import {c,b}from'./chunk-3ZK2GU7C.js';import {f as f$1,e}from'./chunk-T3GJ7YVG.js';import {b as b$2}from'./chunk-22DT744Z.js';import {j,g}from'./chunk-SI3AQKIP.js';import {b as b$1}from'./chunk-JHC6SCJC.js';import {c as c$3,a as a$2,b as b$3}from'./chunk-NFUXULIF.js';import {q}from'./chunk-T6OR6YOI.js';import {i,d as d$1,b as b$5,a as a$4}from'./chunk-4KUIFXHM.js';import {c as c$1,d}from'./chunk-NAAQMSO3.js';import {a as a$1}from'./chunk-GZTYAEWX.js';import {f}from'./chunk-7YHK5NM3.js';import {c as c$2,l as l$1,i as i$1,b as b$4,s as s$1,m,o}from'./chunk-LZQNVH7D.js';import {a as a$3}from'./chunk-2FIX2MDC.js';import {a}from'./chunk-XZGVNGRB.js';import {p as p$1}from'./chunk-5XATWNME.js';import p from'chalk';import {createHash}from'crypto';import {execa}from'execa';import l from'fs-extra';import s from'path';function Ze(e){return `"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function At(e){let t=`scripts.${e.scriptName}=${e.scriptValue}`;return `cd ${Ze(e.projectPath)} && npm pkg set ${Ze(t)}`}function Oe(e){return `rapidkit:doctor:repair ${Buffer.from(JSON.stringify(e),"utf8").toString("base64url")}`}function nt(e){let t=s.join(e.projectPath,e.relativePath),r={type:"file-create",path:t,content:e.content,overwrite:false};return {id:`${e.issueId}.file-create`,issueId:e.issueId,title:e.title,status:"available",fixKind:"file-create",risk:e.risk??"safe",canAutoFix:true,canEditFiles:true,requiresApproval:true,requiresReview:e.requiresReview??false,files:[t],command:Oe(r),operation:r,verifyCommand:"npx workspai doctor project --json",refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function Ot(e){let t=s.join(e.projectPath,e.relativePath),r={type:"file-append",path:t,lines:e.lines,ensureNewline:true};return {id:`${e.issueId}.file-append`,issueId:e.issueId,title:e.title,status:"available",fixKind:"file-append",risk:e.risk??"safe",canAutoFix:true,canEditFiles:true,requiresApproval:true,requiresReview:e.requiresReview??false,files:[t],command:Oe(r),operation:r,verifyCommand:"npx workspai doctor project --json",refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function Mt(e){let t=s.join(e.projectPath,e.sourceRelativePath),r=s.join(e.projectPath,e.targetRelativePath),n={type:"file-copy",sourcePath:t,path:r,overwrite:false};return {id:`${e.issueId}.file-copy`,issueId:e.issueId,title:e.title,status:"available",fixKind:"file-copy",risk:e.risk??"safe",canAutoFix:true,canEditFiles:true,requiresApproval:true,requiresReview:e.requiresReview??false,files:[t,r],command:Oe(n),operation:n,verifyCommand:"npx workspai doctor project --json",refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function Tt(e){return e.lint&&e.lint.trim().length>0?"npm run lint":e.build&&e.build.trim().length>0?"npm run build":null}function Ht(e){let t=`frontend-script-${e.scriptName}`,r=s.join(e.projectPath,"package.json"),n=["npx workspai doctor project --json","npx workspai workspace verify --json"];return e.scriptValue?{id:`${t}.package-json-script`,issueId:t,title:`Add package.json ${e.scriptName} script`,status:"available",fixKind:"package-json-script",risk:"guarded",canAutoFix:true,canEditFiles:true,requiresApproval:true,requiresReview:false,files:[r],command:At({projectPath:e.projectPath,scriptName:e.scriptName,scriptValue:e.scriptValue}),operation:{type:"package-json-script",path:r,scriptName:e.scriptName,scriptValue:e.scriptValue},verifyCommand:"npx workspai doctor project --json",refreshCommands:n,reason:`Reuse the existing ${e.scriptValue} validation path as the ${e.scriptName} gate for ${e.frameworkDisplayName}.`}:{id:`${t}.manual`,issueId:t,title:`Define ${e.scriptName} script`,status:"manual",fixKind:"manual",risk:"guarded",canAutoFix:false,canEditFiles:false,requiresApproval:true,requiresReview:true,files:[r],refreshCommands:n,reason:`No safe ${e.frameworkDisplayName} fallback script could be inferred from existing package.json scripts.`,limitations:["Add a real test/lint/build command that matches the project quality gate before release."]}}function _t(e){let t=s.join(e.projectPath,"package.json");return {id:`${e.issueId}.package-json-script`,issueId:e.issueId,title:e.title,status:"available",fixKind:"package-json-script",risk:e.risk??"guarded",canAutoFix:true,canEditFiles:true,requiresApproval:true,requiresReview:e.requiresReview??false,files:[t],command:At({projectPath:e.projectPath,scriptName:e.scriptName,scriptValue:e.scriptValue}),operation:{type:"package-json-script",path:t,scriptName:e.scriptName,scriptValue:e.scriptValue},verifyCommand:"npx workspai doctor project --json",refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function Bt(e){let t=s.join(e.projectPath,"Makefile"),r={type:"makefile-target",path:t,target:e.targetName,command:e.command,phony:true};return {id:`${e.issueId}.makefile-target`,issueId:e.issueId,title:e.title,status:"available",fixKind:"file-append",risk:e.risk??"guarded",canAutoFix:true,canEditFiles:true,requiresApproval:true,requiresReview:e.requiresReview??true,files:[t],command:Oe(r),operation:r,verifyCommand:"npx workspai doctor project --json",refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function qt(e){return {id:`${e.issueId}.command`,issueId:e.issueId,title:e.title,status:"available",fixKind:e.fixKind??"command",risk:e.risk??"guarded",canAutoFix:true,canEditFiles:false,requiresApproval:true,requiresReview:e.requiresReview??true,files:e.files.map(t=>s.join(e.projectPath,t)),command:`cd ${Ze(e.projectPath)} && ${e.command}`,verifyCommand:"npx workspai doctor project --json",refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}var wn=[".eslintrc.js",".eslintrc.cjs",".eslintrc.json",".eslintrc.yaml",".eslintrc.yml","eslint.config.js","eslint.config.mjs","eslint.config.cjs"],vn=["tests","test","src/test","__tests__","e2e","playwright","cypress"],bn=["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"],jn=["src","app","pages"],xn=["dev","build","test","lint"];function Gt(e){let t=e?.scripts;if(!t||typeof t!="object"||Array.isArray(t))return {};let r={};for(let[n,o]of Object.entries(t))typeof o=="string"&&o.trim().length>0&&(r[n]=o);return r}async function Wt(e,t){for(let o of wn)if(await l.pathExists(s.join(e,o)))return true;let r=t??(await l.pathExists(s.join(e,"package.json"))?await l.readJson(s.join(e,"package.json")):null);if(!r)return false;if(r.eslintConfig)return true;let n={...r.dependencies??{},...r.devDependencies??{}};return !!(n.eslint||n["@eslint/js"]||n["@eslint/eslintrc"])}async function Kt(e,t){for(let o of vn)if(await l.pathExists(s.join(e,o)))return true;for(let o of bn)if(await l.pathExists(s.join(e,o)))return true;let r=Gt(t);if(r.test||r["test:unit"]||r["test:e2e"]||r["test:ci"]||r["test:watch"])return true;let n={...t?.dependencies??{},...t?.devDependencies??{}};return n.vitest||n.jest||n["@playwright/test"]||n.cypress?true:await Pn(e)}async function Pn(e){let t=["src","app","pages","components"],r=/\.(test|spec)\.(tsx?|jsx?|vue|svelte)$/i,o=new Set(["node_modules",".git","dist","build",".next","coverage",".turbo"]);for(let a of t){let i=s.join(e,a);if(!await l.pathExists(i))continue;let c=[{dir:i,depth:0}];for(;c.length>0;){let d=c.shift();if(!d)break;let u=[];try{u=await l.readdir(d.dir);}catch{continue}for(let h of u){let y=s.join(d.dir,h);if(r.test(h))return true;if(!(d.depth>=3||o.has(h)||h.startsWith(".")))try{(await l.stat(y)).isDirectory()&&c.push({dir:y,depth:d.depth+1});}catch{continue}}}}return false}async function rt(e){for(let t of jn){let r=s.join(e,t);if(await l.pathExists(r))try{if((await l.readdir(r)).some(o=>!o.startsWith(".")))return true}catch{continue}}return false}function Cn(e){let t=e.key;return b$5(t).key}function Rn(e,t,r){return a$4(t,r).some(o=>!!e[o])}async function Vt(e){let{projectPath:t,detection:r,packageJsonData:n}=e,o=Cn(r),a=b$5(o),i=Gt(n),c=[],d=await l.pathExists(s.join(t,"package-lock.json"))||await l.pathExists(s.join(t,"pnpm-lock.yaml"))||await l.pathExists(s.join(t,"yarn.lock"))||await l.pathExists(s.join(t,"bun.lockb"));c.push({id:"frontend-lockfile-integrity",label:"Frontend lockfile integrity",status:d?"pass":"warn",severity:"warn",scope:"project-scoped",reason:d?"Node lockfile detected for deterministic dependency restore.":"No Node lockfile detected (package-lock/yarn.lock/pnpm-lock.yaml/bun.lockb).",recommendation:d?void 0:"Commit a lockfile for deterministic installs and CI parity."});let u=await l.pathExists(s.join(t,"tsconfig.json")),h=await l.pathExists(s.join(t,"jsconfig.json")),y=u||h;c.push({id:"frontend-typescript-surface",label:"TypeScript project surface",status:y?"pass":"warn",severity:"warn",scope:"project-scoped",reason:y?u?"tsconfig.json detected.":"jsconfig.json detected.":"No tsconfig.json or jsconfig.json detected.",recommendation:y?void 0:"Add tsconfig.json (or jsconfig.json) for typed frontend builds and IDE parity."});let w=a.fileHints.length>0&&a.fileHints.some(f=>l.pathExistsSync(s.join(t,f)));c.push({id:"frontend-framework-config",label:`${a.displayName} config surface`,status:w?"pass":"warn",severity:"warn",scope:"project-scoped",reason:w?`${a.displayName} configuration artifacts detected.`:`No ${a.displayName} config markers detected (${a.fileHints.join(", ")||"n/a"}).`,recommendation:w?void 0:"Keep framework config files in-repo for reproducible dev/build behavior."});for(let f of xn){let v=Rn(i,o,f),x=f==="dev"||f==="build",k=!v&&f==="test"?Ht({projectPath:t,frameworkDisplayName:a.displayName,scriptName:f,scriptValue:Tt(i)}):void 0;c.push({id:`frontend-script-${f}`,label:`${f} script surface`,status:v?"pass":x?"fail":"warn",severity:x?"error":"warn",scope:"project-scoped",reason:v?`package.json exposes a ${f} script for ${a.displayName}.`:`No ${f} script detected for ${a.displayName}.`,recommendation:v?void 0:`Add a "${a$4(o,f)[0]??f}" script to package.json.`,repairCapability:k});}let g=await rt(t);return c.push({id:"frontend-source-tree",label:"Frontend source tree",status:g?"pass":"warn",severity:"warn",scope:"project-scoped",reason:g?"Application source directories detected (src/app/pages).":"No frontend source directories detected under src/, app/, or pages/.",recommendation:g?void 0:"Ensure the scaffolded application tree exists before running lifecycle commands."}),c}var Dn={node:["package-lock.json","pnpm-lock.yaml","yarn.lock","bun.lock","bun.lockb"],deno:["deno.lock"],bun:["bun.lock","bun.lockb"],python:["uv.lock","poetry.lock","requirements.txt","requirements.lock"],go:["go.sum"],java:["pom.xml","gradle.lockfile","gradle/libs.versions.toml"],rust:["Cargo.lock"],elixir:["mix.lock"],clojure:["deps.edn","project.clj"],php:["composer.lock"],ruby:["Gemfile.lock"],dotnet:["packages.lock.json","Directory.Packages.props"],unknown:[]},En={node:["package.json"],deno:["deno.json","deno.jsonc"],bun:["package.json","bunfig.toml"],python:["pyproject.toml","requirements.txt","setup.py"],go:["go.mod"],java:["pom.xml","build.gradle","build.gradle.kts"],rust:["Cargo.toml"],elixir:["mix.exs"],clojure:["deps.edn","project.clj"],php:["composer.json"],ruby:["Gemfile"],dotnet:["*.csproj","*.sln"],unknown:[]},Sn=["node_modules",".git",".workspai/reports",".venv","dist","build","coverage",".env",".env.*","!.env.example"].join(`
|
|
2
|
-
`),it=[".env",".env.*","!.env.example"];function De(e){return e?e==="bun"?"node":e==="python"||e==="node"||e==="go"||e==="java"||e==="rust"||e==="elixir"||e==="clojure"||e==="deno"||e==="php"||e==="ruby"||e==="dotnet"?e:"unknown":"unknown"}async function Me(e,t){for(let r of t){if(r.includes("*")){let n=r.replace("*","");if(await $n(e,n,2))return true;continue}if(await l.pathExists(s.join(e,r)))return true}return false}async function $n(e,t,r){let n=[{dir:e,depth:0}],o=new Set(["node_modules",".git",".workspai",".rapidkit","dist","build","coverage"]);for(;n.length>0;){let a=n.shift();if(!a)break;let i=[];try{i=await l.readdir(a.dir,{withFileTypes:true});}catch{continue}for(let c of i){if(o.has(c.name))continue;let d=s.join(a.dir,c.name);if(c.isFile()&&c.name.endsWith(t))return true;c.isDirectory()&&a.depth<r&&!c.name.startsWith(".")&&n.push({dir:d,depth:a.depth+1});}}return false}async function Te(e){try{return await l.pathExists(e)?await l.readFile(e,"utf8"):""}catch{return ""}}async function ot(e,t){let r=[];for(let n of t){let o=await Te(s.join(e,n));o&&r.push(o);}return r.join(`
|
|
3
|
-
`)}async function Fn(e){if(e.runtime==="node"){let t=typeof e.packageJsonData?.packageManager=="string"?e.packageJsonData.packageManager.split("@")[0]:null;return {command:t==="pnpm"?"pnpm install":t==="yarn"?"yarn install":t==="bun"?"bun install":"npm install",title:"Generate Node dependency lockfile",files:["package.json","package-lock.json","pnpm-lock.yaml","yarn.lock","bun.lock"],limitations:["Review dependency and lockfile changes before committing."]}}if(e.runtime==="go"&&await l.pathExists(s.join(e.projectPath,"go.mod")))return {command:"go mod tidy",title:"Reconcile Go module graph",files:["go.mod","go.sum"],limitations:["Review go.mod/go.sum changes before committing."]};if(e.runtime==="rust")return {command:"cargo fetch",title:"Generate Rust dependency baseline",files:["Cargo.toml","Cargo.lock"],limitations:["Review Cargo.lock changes before committing."]};if(e.runtime==="php")return {command:"composer install",title:"Generate Composer lockfile",files:["composer.json","composer.lock"],limitations:["Review composer.lock changes before committing."]};if(e.runtime==="ruby")return {command:"bundle install",title:"Generate Bundler lockfile",files:["Gemfile","Gemfile.lock"],limitations:["Review Gemfile.lock changes before committing."]};if(e.runtime==="dotnet")return {command:"dotnet restore",title:".NET dependency restore",files:["*.sln","*.csproj","packages.lock.json","Directory.Packages.props"],limitations:["Enable NuGet lock files in the project when release policy requires deterministic restore."]};if(e.runtime==="elixir")return {command:"mix deps.get",title:"Generate Elixir dependency lockfile",files:["mix.exs","mix.lock"],limitations:["Review mix.lock changes before committing."]};if(e.runtime==="clojure")return {command:"clojure -P",title:"Prepare Clojure dependency baseline",files:["deps.edn","project.clj"],limitations:["Review dependency cache and CI restore policy before release."]};if(e.runtime==="python"){let t=await Te(s.join(e.projectPath,"pyproject.toml"));if(/\[tool\.poetry\]/.test(t))return {command:"poetry install --no-root",title:"Install Poetry dependency baseline",files:["pyproject.toml","poetry.lock"],limitations:["Review poetry.lock changes before committing when Poetry resolves or updates the lockfile."]};if(/\[tool\.uv\]|\[project\]/.test(t))return {command:"uv lock",title:"Generate uv lockfile",files:["pyproject.toml","uv.lock"],limitations:["Review uv.lock changes before committing."]}}return null}function at(e){let t=e?.scripts;if(!t||typeof t!="object"||Array.isArray(t))return {};let r={};for(let[n,o]of Object.entries(t))typeof o=="string"&&o.trim().length>0&&(r[n]=o);return r}function Nn(e){if(e.runtime==="node"){let r=at(e.packageJsonData);if(!e.packageJsonData)return null;if(e.kind==="test"){let n=r.lint?"npm run lint":r.build?"npm run build":null;return n?{command:n,title:"Define Node test script",targetName:"test",files:["package.json"],limitations:["Replace this fallback with real tests when product coverage is required."]}:null}return e.kind==="security"?{command:"npm audit --audit-level=moderate",title:"Define Node security audit script",targetName:"audit",files:["package.json"]}:null}return {python:{test:{command:"python -m pytest",title:"Define Python test command",targetName:"test",files:["Makefile","pyproject.toml"]},quality:{command:"python -m ruff check .",title:"Define Python quality command",targetName:"quality",files:["Makefile","pyproject.toml"],limitations:["Ensure ruff is declared in project dev dependencies before enforcing in CI."]},security:{command:"python -m pip_audit",title:"Define Python security audit command",targetName:"security",files:["Makefile","pyproject.toml"],limitations:["Ensure pip-audit is available in the project toolchain before enforcing in CI."]}},go:{test:{command:"go test ./...",title:"Define Go test command",targetName:"test",files:["Makefile","go.mod"]},quality:{command:"gofmt -w .",title:"Define Go formatting command",targetName:"quality",files:["Makefile","go.mod"],limitations:["Use CI-specific check mode if formatting should not mutate files in pipelines."]},security:{command:"govulncheck ./...",title:"Define Go vulnerability scan command",targetName:"security",files:["Makefile","go.mod"],limitations:["Ensure govulncheck is installed or provisioned by CI before enforcing."]}},rust:{test:{command:"cargo test",title:"Define Rust test command",targetName:"test",files:["Makefile","Cargo.toml"]},quality:{command:"cargo fmt -- --check && cargo clippy --all-targets -- -D warnings",title:"Define Rust quality command",targetName:"quality",files:["Makefile","Cargo.toml"]},security:{command:"cargo audit",title:"Define Rust security audit command",targetName:"security",files:["Makefile","Cargo.toml"],limitations:["Ensure cargo-audit is installed or provisioned by CI before enforcing."]}},php:{test:{command:"vendor/bin/phpunit",title:"Define PHP test command",targetName:"test",files:["Makefile","composer.json"]},quality:{command:"vendor/bin/phpstan analyse",title:"Define PHP static analysis command",targetName:"quality",files:["Makefile","composer.json"],limitations:["Ensure phpstan is declared in require-dev before enforcing in CI."]},security:{command:"composer audit",title:"Define Composer security audit command",targetName:"security",files:["Makefile","composer.json"]}},ruby:{test:{command:"bundle exec rspec",title:"Define Ruby test command",targetName:"test",files:["Makefile","Gemfile"],limitations:["Use bundle exec ruby -Itest when the project uses minitest instead of RSpec."]},quality:{command:"bundle exec rubocop",title:"Define Ruby quality command",targetName:"quality",files:["Makefile","Gemfile"]},security:{command:"bundle exec bundler-audit check",title:"Define Ruby security audit command",targetName:"security",files:["Makefile","Gemfile"],limitations:["Ensure bundler-audit is installed or provisioned by CI before enforcing."]}},dotnet:{test:{command:"dotnet test",title:"Define .NET test command",targetName:"test",files:["Makefile","*.sln","*.csproj"]},quality:{command:"dotnet format --verify-no-changes",title:"Define .NET formatting gate",targetName:"quality",files:["Makefile","*.sln","*.csproj"]},security:{command:"dotnet list package --vulnerable",title:"Define .NET package vulnerability check",targetName:"security",files:["Makefile","*.sln","*.csproj"]}},java:{test:{command:"mvn test",title:"Define Java test command",targetName:"test",files:["Makefile","pom.xml","build.gradle","build.gradle.kts"],limitations:["Use ./gradlew test when the project is Gradle-first."]},quality:{command:"mvn verify",title:"Define Java verification command",targetName:"quality",files:["Makefile","pom.xml","build.gradle","build.gradle.kts"],limitations:["Use ./gradlew check when the project is Gradle-first."]},security:{command:"mvn org.owasp:dependency-check-maven:check",title:"Define Java dependency vulnerability check",targetName:"security",files:["Makefile","pom.xml"],limitations:["Review OWASP dependency-check policy and cache behavior before enforcing in CI."]}}}[e.runtime]?.[e.kind]??null}async function In(e){return Bt({issueId:e.issueId,title:e.contract.title,projectPath:e.projectPath,targetName:e.contract.targetName,command:e.contract.command,reason:e.reason,risk:"guarded",requiresReview:true,limitations:e.contract.limitations})}async function st(e){let t=Nn({runtime:e.runtime,kind:e.kind,packageJsonData:e.packageJsonData});if(t)return e.runtime==="node"&&e.packageJsonData?_t({issueId:e.issueId,title:t.title,projectPath:e.projectPath,scriptName:t.targetName,scriptValue:t.command,reason:e.reason,risk:"guarded",limitations:t.limitations}):In({issueId:e.issueId,projectPath:e.projectPath,contract:t,reason:e.reason})}function Ee(e){return {id:`${e.issueId}.manual`,issueId:e.issueId,title:e.title,status:"manual",fixKind:"manual",risk:"guarded",canAutoFix:false,canEditFiles:false,requiresApproval:true,requiresReview:true,files:e.files.map(t=>s.join(e.projectPath,t)),refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function An(e){return nt({issueId:"surface-dockerignore",title:"Create .dockerignore",projectPath:e,relativePath:".dockerignore",content:`${Sn}
|
|
4
|
-
`,reason:"Create a Docker build ignore baseline to keep secrets, dependencies, and reports out of container contexts."})}async function On(e){if(!await l.pathExists(s.join(e,".gitignore")))return nt({issueId:"surface-security-hygiene",title:"Create .gitignore secret baseline",projectPath:e,relativePath:".gitignore",content:`${it.join(`
|
|
5
|
-
`)}
|
|
6
|
-
`,reason:"Create a minimal ignore baseline so local env files are not committed accidentally."});let t=await Te(s.join(e,".gitignore")),r=it.filter(n=>!t.split(/\r?\n/).includes(n));return Ot({issueId:"surface-security-hygiene",title:"Append .gitignore secret baseline",projectPath:e,relativePath:".gitignore",lines:r,reason:"Append missing env-file ignore rules so local secrets stay out of source control."})}async function Mn(e){let t=En[e.runtime]??[],r=Dn[e.runtime]??[];if(t.length===0&&r.length===0)return null;let n=await Me(e.projectPath,t),o=await Me(e.projectPath,r),a=n&&!o?await Fn({projectPath:e.projectPath,runtime:e.runtime,packageJsonData:e.packageJsonData}):null;return {id:"surface-dependency-contract",label:"Dependency contract",status:!n||o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?o?"Dependency manifest and deterministic lock/baseline markers detected.":`Dependency manifest detected, but no deterministic baseline found (${r.join(", ")}).`:"No dependency manifest markers detected for this runtime.",recommendation:n&&!o?"Generate and commit the runtime-native lockfile or package baseline before release.":void 0,repairCapability:n&&!o&&a?qt({issueId:"surface-dependency-contract",title:a.title,projectPath:e.projectPath,command:a.command,files:a.files,fixKind:"dependency-sync",reason:"Generate the runtime-native dependency baseline so CI, Doctor, and Studio share deterministic dependency evidence.",limitations:a.limitations}):void 0}}async function Tn(e){let t=await l.pathExists(s.join(e.projectPath,".env.example")),r=await l.pathExists(s.join(e.projectPath,".env")),n=await l.pathExists(s.join(e.projectPath,"docs","env.md"))||await l.pathExists(s.join(e.projectPath,"ENVIRONMENT.md")),o=await l.pathExists(s.join(e.projectPath,"config")),a=t||n||o,i=e.projectKind==="frontend";return {id:"surface-env-contract",label:"Environment/config contract",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Environment/config contract marker detected.":i?"No frontend environment contract marker detected.":"No environment/config contract marker detected.",recommendation:a?void 0:"Add .env.example, config schema, or environment documentation for deterministic setup.",repairCapability:a?t&&!r?Mt({issueId:"surface-env-contract",title:"Create local .env from .env.example",projectPath:e.projectPath,sourceRelativePath:".env.example",targetRelativePath:".env",reason:"Seed the local environment file from the reviewed example without overwriting an existing .env."}):void 0:Ee({issueId:"surface-env-contract",title:"Define environment contract",projectPath:e.projectPath,files:[".env.example"],reason:"Environment contracts are product-specific; Doctor can identify the missing baseline, but values must be reviewed by the project owner."})}}async function Hn(e){let t=await l.pathExists(s.join(e.projectPath,"Dockerfile")),r=await l.pathExists(s.join(e.projectPath,".dockerignore")),n=await l.pathExists(s.join(e.projectPath,"docker-compose.yml"))||await l.pathExists(s.join(e.projectPath,"compose.yml"));return t?{id:"surface-dockerignore",label:"Container build context hygiene",status:r?"pass":"warn",severity:"warn",scope:"project-scoped",reason:r?"Dockerfile and .dockerignore detected.":"Dockerfile detected without .dockerignore.",recommendation:r?void 0:"Add .dockerignore to exclude dependencies, reports, git metadata, and local env files from image builds.",repairCapability:r?void 0:An(e.projectPath)}:{id:"surface-container-contract",label:"Container contract",status:n?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?"Compose surface detected; project has a local container orchestration baseline.":"No Dockerfile or compose surface detected.",recommendation:e.projectKind==="backend"||e.projectKind==="fullstack"?"Add Dockerfile or compose baseline when this service is expected to run in containerized environments.":"Add container baseline only if this app is shipped through containerized environments."}}async function _n(e){let t=["k8s","kubernetes","deploy","deployments","charts","helm","kustomization.yaml","kustomization.yml"];if(!await Me(e.projectPath,t))return {id:"surface-deploy-contract",label:"Deployment contract",status:"warn",severity:"warn",scope:"project-scoped",reason:"No Kubernetes/Helm/Kustomize deployment surface detected.",recommendation:e.projectKind==="backend"||e.projectKind==="fullstack"?"Add deployment manifests or document the non-Kubernetes deployment path.":"Document the deployment path when this frontend is production-hosted."};let n=await ot(e.projectPath,["k8s/deployment.yaml","k8s/deployment.yml","kubernetes/deployment.yaml","deploy/deployment.yaml","deployment.yaml","deployment.yml","values.yaml","charts/values.yaml"]),o=/readinessProbe|livenessProbe|startupProbe/.test(n),a=/resources:\s*[\s\S]*(limits:|requests:)/.test(n),i=o&&a;return {id:"surface-kubernetes-readiness",label:"Deployment readiness controls",status:i?"pass":"warn",severity:"warn",scope:"project-scoped",reason:i?"Deployment surface includes probe and resource-control markers.":"Deployment surface detected, but readiness/liveness probes or resource controls are incomplete.",recommendation:i?void 0:"Add readiness/liveness/startup probes and resource requests/limits to production deployment manifests.",repairCapability:i?void 0:Ee({issueId:"surface-kubernetes-readiness",title:"Harden deployment readiness controls",projectPath:e.projectPath,files:["k8s/","helm/","deploy/"],reason:"Deployment manifests are environment-specific and should be reviewed before mutation."})}}async function Bn(e){let t=await l.pathExists(s.join(e.projectPath,".gitignore")),n=(await Te(s.join(e.projectPath,".gitignore"))).split(/\r?\n/),o=t&&it.every(h=>n.includes(h)),a=at(e.packageJsonData),i=!!(a.audit||a["security:audit"]||a["audit:security"]||a["npm:audit"]),c=Number(e.vulnerabilities??0),d=c>0;return {id:"surface-security-hygiene",label:"Security hygiene surface",status:o&&!d?"pass":d?"fail":"warn",severity:d?"error":"warn",scope:"project-scoped",reason:d?`${c} moderate/high/critical dependency vulnerability(ies) reported.`:o?"Repository ignore baseline covers env-file secrets and no dependency vulnerabilities were reported by Doctor.":t?"Repository ignore baseline exists, but env-file secret rules are incomplete.":"No .gitignore baseline detected for local secrets/build artifacts.",recommendation:d?"Run the runtime-native audit fix path without force, review lockfile changes, then rerun Doctor.":o?i?void 0:"Consider adding a security audit script for CI parity.":"Add .gitignore entries for env files, build output, dependency directories, and local reports.",repairCapability:d?Ee({issueId:"surface-security-hygiene",title:"Review dependency vulnerability fix",projectPath:e.projectPath,files:["package.json","package-lock.json","pnpm-lock.yaml","yarn.lock"],reason:"Dependency vulnerability remediation can change transitive dependency graphs and must be reviewed.",limitations:["Avoid npm audit fix --force unless a maintainer explicitly accepts breaking changes."]}):o?void 0:await On(e.projectPath)}}async function qn(e){let t=De(e.runtimeFamily),r=e.hasTests===true,n=r?void 0:await st({issueId:"surface-test-contract",projectPath:e.projectPath,runtime:t,kind:"test",packageJsonData:e.packageJsonData,reason:"Create a deterministic runtime-native test command contract so Doctor, CI, and Studio can verify changes consistently."});return {id:"surface-test-contract",label:"Test contract",status:r?"pass":"warn",severity:"warn",scope:"project-scoped",reason:r?"Test surface detected through scripts, config, directories, or test files.":"No test surface detected by Doctor.",recommendation:r?void 0:"Add at least one deterministic test command or test baseline before release.",repairCapability:n??(r?void 0:Ee({issueId:"surface-test-contract",title:"Define test contract",projectPath:e.projectPath,files:["package.json","pyproject.toml","go.mod","pom.xml"],reason:"Doctor can identify missing test surfaces, but the correct test runner depends on product intent."}))}}function Gn(e){let t=at(e.packageJsonData),r=!!(t.format||t["format:check"]||t.prettier);return {id:"surface-format-contract",label:"Format contract",status:r?"pass":"warn",severity:"warn",scope:"project-scoped",reason:r?"Format script detected in package.json.":"No explicit format script detected by Doctor.",recommendation:r?void 0:"Add a formatter command or document the formatting tool used by CI."}}async function Wn(e){let t=De(e.runtimeFamily),n={node:["vitest.config.ts","jest.config.js","playwright.config.ts","cypress.config.ts"],deno:["deno.json","deno.jsonc"],bun:["bunfig.toml"],python:["pytest.ini","tox.ini","noxfile.py","tests","pyproject.toml"],go:["*_test.go"],java:["src/test","pom.xml","build.gradle","build.gradle.kts"],rust:["tests","Cargo.toml"],elixir:["test","mix.exs"],clojure:["test","deps.edn","project.clj"],php:["phpunit.xml","phpunit.xml.dist","tests"],ruby:["spec","test",".rspec"],dotnet:["*.Tests.csproj","*.Test.csproj","*.sln"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await Me(e.projectPath,n),a=e.hasTests===true&&o;return {id:"runtime-test-depth",label:"Runtime-native test depth",status:a?"pass":("warn"),severity:"warn",scope:"project-scoped",reason:a?"Runtime-native test markers detected.":e.hasTests?"Generic test surface detected, but runtime-native test markers are incomplete.":"No runtime-native test markers detected.",recommendation:a?void 0:"Add runtime-native tests/config so Doctor, CI, and Studio can verify changes deterministically."}}async function Kn(e){let t=De(e.runtimeFamily),n={node:["eslint.config.js","eslint.config.mjs",".eslintrc.json","prettier.config.js"],deno:["deno.json","deno.jsonc"],bun:["eslint.config.js","biome.json","bunfig.toml"],python:["ruff.toml","pyproject.toml",".flake8","mypy.ini","Makefile"],go:[".golangci.yml",".golangci.yaml","Makefile"],java:["checkstyle.xml","pom.xml","build.gradle","build.gradle.kts"],rust:["rustfmt.toml","clippy.toml","Cargo.toml"],elixir:[".formatter.exs","credo.exs","mix.exs"],clojure:["cljfmt.edn",".clj-kondo","deps.edn"],php:["phpcs.xml","phpstan.neon","pint.json","composer.json"],ruby:[".rubocop.yml","Gemfile"],dotnet:[".editorconfig","Directory.Build.props","global.json"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await ot(e.projectPath,n),a=/eslint|prettier|biome|ruff|black|mypy|golangci|checkstyle|spotless|pmd|clippy|rustfmt|credo|clj-kondo|phpstan|phpcs|pint|rubocop|editorconfig|dotnet format/i.test(o),i=a?void 0:await st({issueId:"runtime-quality-tooling",projectPath:e.projectPath,runtime:t,kind:"quality",packageJsonData:e.packageJsonData,reason:"Create a deterministic runtime-native quality command contract so CI and Studio can verify formatting/static-analysis consistently."});return {id:"runtime-quality-tooling",label:"Runtime-native quality tooling",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Runtime-native lint/format/static-analysis markers detected.":"No runtime-native lint/format/static-analysis markers detected.",recommendation:a?void 0:"Add runtime-native lint/format/static-analysis tooling and expose it to CI.",repairCapability:i}}async function Vn(e){let t=De(e.runtimeFamily),n={node:["package.json"],deno:["deno.json","deno.jsonc"],bun:["package.json","bunfig.toml"],python:["pyproject.toml","requirements.txt","Makefile"],go:["Makefile","go.mod"],java:["pom.xml","build.gradle","build.gradle.kts"],rust:["Cargo.toml"],elixir:["mix.exs"],clojure:["deps.edn","project.clj"],php:["composer.json"],ruby:["Gemfile",".bundler-audit.yml"],dotnet:["Directory.Build.props","*.csproj"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await ot(e.projectPath,n),a=/npm audit|pnpm audit|yarn audit|bun audit|pip[-_]audit|safety|bandit|govulncheck|gosec|dependency-check|owasp|cargo audit|mix hex.audit|composer audit|bundler-audit|brakeman|NuGetAudit|dotnet list package --vulnerable/i.test(o),i=a?void 0:await st({issueId:"runtime-security-tooling",projectPath:e.projectPath,runtime:t,kind:"security",packageJsonData:e.packageJsonData,reason:"Create a deterministic runtime-native security audit command contract so CI and Studio can verify dependency risk consistently."});return {id:"runtime-security-tooling",label:"Runtime-native security tooling",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Runtime-native security audit tooling marker detected.":"No runtime-native security audit tooling marker detected.",recommendation:a?void 0:"Expose a runtime-native dependency/security audit command for CI and Studio verification.",repairCapability:a?void 0:i||Ee({issueId:"runtime-security-tooling",title:"Define runtime security audit command",projectPath:e.projectPath,files:["package.json","pyproject.toml","Makefile","pom.xml","Cargo.toml"],reason:"Security tooling differs by runtime and organization policy; Doctor records the missing contract for review."})}}async function Jt(e){let t=De(e.runtimeFamily),r=[],n=await Mn({projectPath:e.projectPath,runtime:t,packageJsonData:e.packageJsonData});n&&r.push(n),r.push(await Tn(e)),r.push(await Hn(e)),r.push(await _n(e)),r.push(await Bn(e)),r.push(await qn(e)),t==="node"&&r.push(Gn(e));let o=await Promise.all([Wn(e),Kn(e),Vn(e)]);for(let a of o)a&&r.push(a);return r}function Ln(e){return [...new Set(e.filter(t=>t&&t.trim().length>0))]}function Lt(e){return [...new Set(e.filter(t=>t&&t.trim().length>0))]}function Un(){let e=s$1().map(n=>s.join(n,b$4()?"poetry.exe":"poetry")),t=b$4()?[s.join(process.env.APPDATA||"","Python","Scripts","poetry.exe"),s.join(process.env.USERPROFILE||"","AppData","Roaming","Python","Scripts","poetry.exe")]:[],r=b$4()?[]:["/usr/local/bin/poetry","/usr/bin/poetry"];return Ln([...e,...t,...r])}function zn(e){let t=s$1().map(d=>({location:"Global (user-local)",path:s.join(d,b$4()?"rapidkit.exe":"rapidkit")})),r=[{location:"Global (pipx)",path:s.join(e,".local","bin","rapidkit")},{location:"Global (pipx)",path:s.join(e,"AppData","Roaming","Python","Scripts","rapidkit.exe")},{location:"Global (pyenv)",path:s.join(e,".pyenv","shims","rapidkit")},{location:"Global (system)",path:"/usr/local/bin/rapidkit"},{location:"Global (system)",path:"/usr/bin/rapidkit"}],n=m(s.join(process.cwd(),".venv")),o$1=o(process.cwd()),a=[{location:"Workspace (.venv)",path:n},...o$1.map(d=>({location:"Workspace (launcher)",path:d}))],i=[...t,...r,...a],c=new Set;return i.filter(d=>c.has(d.path)?false:(c.add(d.path),true))}function Yn(e){let t=new Map([["Workspace (.venv)",0],["Global (user-local)",1],["Global (pipx)",2],["Global (pyenv)",3],["Global (system)",4]]);return [...e].sort((r,n)=>{let o=t.get(r.location)??Number.MAX_SAFE_INTEGER,a=t.get(n.location)??Number.MAX_SAFE_INTEGER;return o!==a?o-a:r.path.localeCompare(n.path)})}function ge(e){let t=0,r=e.issues.some(n=>n.toLowerCase().includes("environment file missing"));return e.hasEnvFile===false&&!r&&(t+=1),typeof e.vulnerabilities=="number"&&e.vulnerabilities>0&&(t+=1),t}function dt(e){return e.filter(t=>ge(t)>0).length}function ft(e){return e.reduce((t,r)=>t+ge(r),0)}function Qn(e){let t=e.coreVersion?.split(".")[0],r=e.npmVersion?.split(".")[0];return !t||!r?false:t!==r}var Xn="doctor-project-scan-v2",an="doctor-workspace-cache-v2",Zn=Object.freeze({version:"doctor-evidence-v1",scoringPolicyVersion:"doctor-score-policy-v1",generatedBy:"workspai",deterministicScoreBreakdown:true,scopeModel:"workspace-aggregate-or-project-scoped"}),Se=Object.freeze({local:{name:"local",exitOnErrors:true,exitOnWarnings:false,warningExitCode:0,advisoryWarningsBlockRelease:false,description:"Local diagnostics: report warnings without blocking the developer loop."},ci:{name:"ci",exitOnErrors:true,exitOnWarnings:true,warningExitCode:2,advisoryWarningsBlockRelease:false,description:"CI diagnostics: errors fail, warnings return a distinct warning exit code."},release:{name:"release",exitOnErrors:true,exitOnWarnings:true,warningExitCode:1,advisoryWarningsBlockRelease:true,description:"Release gate: any warning/error blocks release readiness."},"enterprise-strict":{name:"enterprise-strict",exitOnErrors:true,exitOnWarnings:true,warningExitCode:1,advisoryWarningsBlockRelease:true,description:"Enterprise strict gate: all warnings/errors block release and must carry evidence or repair guidance."}});function ve(){return {...Zn}}function Be(e){let t=e.profile?.trim();return t&&t in Se?{...Se[t]}:e.strict?{...Se.release}:e.ci?{...Se.ci}:{...Se.local}}function _e(e){return !e||e.total<=0?null:Math.round(e.passed/e.total*100)}function er(e){return e.id==="surface-security-hygiene"&&/vulnerabilit/i.test(`${e.reason} ${e.recommendation??""}`)?{category:"state",ttlSeconds:300,reason:"Dependency vulnerability evidence is live state and must be refreshed before release use."}:e.id.includes("script")||e.id.includes("test")||e.id.includes("quality")||e.id.includes("format")||e.id.includes("runtime")||e.id.includes("lockfile")?{category:"verification",ttlSeconds:1440*60,reason:"Verification/tooling evidence can drift with dependency and config changes; refresh daily or before release."}:e.id.includes("dependency")||e.id.includes("env")||e.id.includes("container")||e.id.includes("docker")||e.id.includes("deploy")||e.id.includes("kubernetes")||e.id.includes("source-tree")||e.id.includes("framework")||e.id.includes("typescript")?{category:"structure",ttlSeconds:10080*60,reason:"Structural workspace/project evidence is durable but should be refreshed when files or manifests change."}:{category:"verification",ttlSeconds:1440*60,reason:"Default Doctor evidence freshness contract for project-scoped verification."}}function tr(e,t){let r=er(e),n=Date.parse(t),o=typeof r.ttlSeconds=="number"?r.ttlSeconds*1e3:null,a=o!==null&&Number.isFinite(n)?new Date(n+o).toISOString():void 0,i=!Number.isFinite(n)||o!==null&&!a?"unknown":o!==null&&Date.now()>n+o?"stale":"fresh";return {category:r.category,generatedAt:t,ttlSeconds:r.ttlSeconds,...a?{expiresAt:a}:{},status:i,verifyBeforeUse:r.category!=="structure"||i!=="fresh",reason:r.reason}}function nr(e){let t=e.id.toLowerCase(),r=`${e.label} ${e.reason} ${e.recommendation??""}`.toLowerCase();return t.includes("dependency")||t.includes("lockfile")||r.includes("lockfile")?"dependency":t.includes("security")||r.includes("vulnerabilit")||r.includes("audit")?"security":t.includes("env")||r.includes(".env")||r.includes("environment")?"environment":t.includes("test")?"test":t.includes("quality")||t.includes("format")||t.includes("lint")?"quality":t.includes("docker")||t.includes("container")?"container":t.includes("deploy")||t.includes("kubernetes")?"deployment":t.includes("runtime")?"runtime":t.includes("contract")?"workspace-contract":t.includes("source-tree")?"source-tree":t.includes("framework")||t.includes("typescript")?"framework":t.includes("custom")?"custom":t.includes("script")||t.includes("config")?"configuration":"unknown"}function rr(e,t){return e.status==="pass"?"none":t==="security"?"security-risk":t==="deployment"||t==="runtime"?"runtime-risk":t==="dependency"||t==="test"||t==="quality"||t==="workspace-contract"?e.severity==="error"||e.status==="fail"?"release-risk":"ci-risk":t==="container"||t==="environment"?"release-risk":"developer-friction"}function ir(e){let{probe:t,freshness:r}=e,n=t.repairCapability;if(t.status==="pass")return {mode:"none",confidence:"high",primaryActionLabel:"No action required",requiresApproval:false,requiresFreshEvidence:false,reason:"Probe is passing.",relatedCommands:[]};if(r.status!=="fresh")return {mode:"refresh-evidence",confidence:"high",primaryActionLabel:"Refresh evidence",requiresApproval:false,requiresFreshEvidence:true,reason:`Evidence is ${r.status}; refresh Doctor before applying repairs.`,relatedCommands:["npx workspai doctor project --json"]};if(r.verifyBeforeUse&&r.category==="state")return {mode:"verify-before-fix",confidence:"high",primaryActionLabel:"Verify live state",requiresApproval:false,requiresFreshEvidence:true,reason:"Live state evidence must be re-read before Studio claims a fix path.",relatedCommands:["npx workspai doctor project --json"]};if(n?.status==="available"&&n.canAutoFix){let o=n.canEditFiles;return {mode:o?"edit-file":"run-command",confidence:"high",primaryActionLabel:o?"Apply file fix":"Run fix command",requiresApproval:n.requiresApproval,requiresFreshEvidence:r.verifyBeforeUse,reason:n.reason,relatedCommands:Lt([...n.command?[n.command]:[],...n.verifyCommand?[n.verifyCommand]:[],...n.refreshCommands])}}return n?.status==="manual"||n?.requiresReview?{mode:"review-required",confidence:"medium",primaryActionLabel:"Review fix path",requiresApproval:true,requiresFreshEvidence:r.verifyBeforeUse,reason:n?.reason??t.recommendation??t.reason,relatedCommands:Lt(n?.refreshCommands??["npx workspai doctor project --json"])}:t.recommendation?{mode:"manual-guidance",confidence:"medium",primaryActionLabel:"Inspect guidance",requiresApproval:false,requiresFreshEvidence:r.verifyBeforeUse,reason:t.recommendation,relatedCommands:["npx workspai doctor project --json"]}:{mode:"manual-guidance",confidence:"low",primaryActionLabel:"Inspect issue",requiresApproval:false,requiresFreshEvidence:r.verifyBeforeUse,reason:"Doctor classified the issue but does not have a deterministic repair path yet.",relatedCommands:["npx workspai doctor project --json"]}}function sn(e,t){let r=tr(e,e.freshness?.generatedAt??t),n=e.issueClass??nr(e),o=e.operationalImpact??rr(e,n),a=e.repairIntent??ir({probe:e,freshness:r});return {...e,freshness:r,issueClass:n,operationalImpact:o,repairIntent:a}}function Ut(e,t){Array.isArray(e.probes)&&(e.probes=e.probes.map(r=>sn(r,t)));}function cn(e,t){let r=e.flatMap(d=>Array.isArray(d.probes)?d.probes.map(u=>u.freshness).filter(u=>!!u):[]),n=r.filter(d=>d.status==="stale").length,o=r.filter(d=>d.status==="unknown").length,a=r.filter(d=>d.category==="state").length,i=r.filter(d=>d.verifyBeforeUse).length,c=r.map(d=>d.generatedAt).filter(Boolean).sort()[0];return {generatedAt:t,status:n>0?"stale":o>0?"unknown":"fresh",staleProbeCount:n,unknownProbeCount:o,liveStateProbeCount:a,verifyBeforeUseProbeCount:i,...c?{oldestProbeGeneratedAt:c}:{}}}function ln(e){return typeof e=="number"?e:Array.isArray(e)?e.length:0}async function dn(e,t){try{if(!await l.pathExists(e))return null;let r=await l.readJSON(e);return c$3(r,t)?r:null}catch{return null}}function pn(e,t){if(!e?.system)return [];let r=[{id:"python",current:t.python},{id:"poetry",current:t.poetry},{id:"pipx",current:t.pipx},{id:"go",current:t.go},{id:"rapidkitCore",current:t.rapidkitCore}],n=[];for(let o of r){let a=e.system?.[o.id]?.status;!a||a===o.current.status||n.push({id:o.id,from:a,to:o.current.status});}return n}function or(e,t){let r=new Map;for(let w of t.projects)r.set(w.path||w.name,w.issues.length);if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let n=Array.isArray(e.projects)?e.projects:[],o=new Map;for(let w of n){let g=w.path||w.name;g&&o.set(g,ln(w.issues));}let a=0,i=0,c=new Set,d=new Set,u=new Set([...Array.from(o.keys()),...Array.from(r.keys())]);for(let w of u){let g=o.get(w)??0,f=r.get(w)??0;f>g?(a+=f-g,c.add(w)):f<g&&(i+=g-f,d.add(w));}let h=_e(e.healthScore),y=_e(t.healthScore);return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:a,resolvedIssueCount:i,netIssueDelta:a-i,scoreDeltaPercent:h===null||y===null?null:y-h,systemStatusChanges:pn(e,{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore}),regressedProjects:Array.from(c).sort(),improvedProjects:Array.from(d).sort()}}function ar(e,t){if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let r=ln(e.project?.issues),n=t.project.issues.length,o=Math.max(n-r,0),a=Math.max(r-n,0),i=_e(e.healthScore),c=_e(t.healthScore),d=t.project.path||t.project.name;return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:o,resolvedIssueCount:a,netIssueDelta:o-a,scoreDeltaPercent:i===null||c===null?null:c-i,systemStatusChanges:pn(e,{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore}),regressedProjects:o>0?[d]:[],improvedProjects:a>0?[d]:[]}}function un(e){let t=e??[],r=0,n=0;for(let i of t){if(i.scope==="project-scoped"){r+=1;continue}(i.scope==="workspace-aggregate"||i.scope==="host-system")&&(n+=1);}let o=r>0&&n>0?1:0,a=o>0?"mixed":r>0?"scoped":n>0?"aggregated":"unknown";return {scopedCount:r,aggregatedCount:n,mixedCount:o,dominantScope:a}}function V(e,t){return b$4()?`cd "${e}"; ${t}`:`cd ${e} && ${t}`}function ae(e){return b$4()?V(e,"Copy-Item .env.example .env"):V(e,"cp .env.example .env")}function zt(e){return V(e,"poetry install --no-root")}function sr(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 cr(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 lr(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 pt(e,t){let r=q(t);e.commandCapabilities=r,e.supportTier=r.frameworkSupportTier;}function He(e,t,r,n){e.framework=t,e.frameworkConfidence=r,e.supportTier=sr(t),e.projectKind=cr(t),e.runtimeFamily=lr(t);}function mn(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 gt(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 dr(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 pr(e,t){e.framework=gt(t),e.frameworkKey=t.key,e.importStack=t.importStack,e.frameworkConfidence=t.confidence,e.supportTier=t.supportTier,e.projectKind="frontend",e.runtimeFamily=mn(t.runtime);}function Z(e,t){e.framework=gt(t),e.frameworkKey=t.key,e.importStack=t.importStack,e.frameworkConfidence=t.confidence,e.supportTier=t.supportTier,e.projectKind=dr(t)?"generic":"backend",e.runtimeFamily=mn(t.runtime);}function ur(e){let t=e.dependencies,r=e.scripts??{},n=(e.kitName??"").toLowerCase(),o=i=>!!t[i],a=Object.values(r).filter(i=>typeof i=="string").join(" ").toLowerCase();return o("next")||a.includes("next ")?{framework:"Next.js",confidence:"high"}:o("nuxt")||a.includes("nuxt ")?{framework:"Nuxt",confidence:"high"}:o("@nestjs/core")||n.startsWith("nestjs.")?{framework:"NestJS",confidence:"high"}:o("express")?{framework:"Express",confidence:"high"}:o("fastify")?{framework:"Fastify",confidence:"high"}:o("koa")?{framework:"Koa",confidence:"high"}:o("@angular/core")?{framework:"Angular",confidence:"high"}:o("@sveltejs/kit")||a.includes("svelte-kit")?{framework:"SvelteKit",confidence:"high"}:o("vue")?{framework:"Vue",confidence:"medium"}:o("react")&&o("react-dom")?{framework:"React",confidence:"medium"}:{framework:"Node.js",confidence:"low"}}async function mr(e,t){let r=i(e,t??null);return r.runtime!=="python"?{framework:"Python",confidence:"low"}:{framework:gt(r),confidence:r.confidence}}async function Yt(e){try{let t=await l.stat(e);return `${s.basename(e)}:${t.isDirectory()?"d":"f"}:${t.size}:${t.mtimeMs}`}catch{return `${s.basename(e)}:missing`}}async function fr(e){try{let t=new Set([".git",".venv","node_modules",".workspai",".rapidkit","dist","build","coverage","__pycache__"]),r=new Set,n=async i=>{if(await $e(i))return true;let c=["package.json","pyproject.toml","requirements.txt","go.mod","pom.xml","build.gradle","build.gradle.kts","*.csproj","Cargo.toml","composer.json","Gemfile","mix.exs","deps.edn","deno.json","deno.jsonc"];for(let d of c){if(d==="*.csproj"){if((await l.readdir(i).catch(()=>[])).some(h=>h.endsWith(".csproj")))return true;continue}if(await l.pathExists(s.join(i,d)))return true}return false};await $e(e)&&r.add(e);let o=await a(e);for(let i of o){let c=s.isAbsolute(i.path)?i.path:s.join(e,i.path);await n(c)&&r.add(c);}return (await a$1(e,{skipDirs:t,descendIntoMatchedProjects:false,isProjectDir:async(i,c)=>s.resolve(i)===s.resolve(c)?$e(i):n(i)})).forEach(i=>r.add(i)),r.size===0&&(await Sr(e,3,t)).forEach(c=>r.add(c)),r.size===0&&!await b$2(e)&&await n(e)&&r.add(e),Array.from(r).sort((i,c)=>i.localeCompare(c))}catch{return []}}async function gr(e,t){let r=[s.join(e,".workspai-workspace"),s.join(e,".workspai","workspace.json"),s.join(e,".workspai","imported-projects.json"),s.join(e,".workspai","policies.yml"),s.join(e,".workspai","toolchain.lock"),s.join(e,".workspai","cache-config.yml"),s.join(e,".rapidkit-workspace"),s.join(e,".rapidkit","workspace.json"),s.join(e,".rapidkit","imported-projects.json"),s.join(e,".rapidkit","policies.yml"),s.join(e,".rapidkit","toolchain.lock"),s.join(e,".rapidkit","cache-config.yml")],n=[".workspai/project.json",".workspai/context.json",".workspai/file-hashes.json",".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"],o=await Promise.all(r.map(Yt)),a=await Promise.all(t.map(async i=>{let c=await Promise.all(n.map(d=>Yt(s.join(i,d))));return `${i}::${c.join("|")}`}));return [Xn,...o,...a].join("||")}async function yr(e,t){try{if(!await l.pathExists(e))return null;let r=await l.readJSON(e);return !r||r.signature!==t||!Array.isArray(r.projects)||typeof r.schemaVersion=="string"&&r.schemaVersion!==an?null:r}catch{return null}}async function hr(e,t){try{await l.ensureDir(s.dirname(e)),await l.writeJSON(e,t,{spaces:2});}catch{}}async function kr(e$1,t,r){let n=s.join(e$1,".workspai","reports","doctor-last-run.json");try{let o=[];for(let a of t.projects)for(let i of a.issues??[])typeof i=="string"&&i.trim()&&o.push(`${a.name}: ${i.trim()}`);for(let[a,i]of [["python",t.python],["rapidkitCore",t.rapidkitCore]])if(i?.status==="error"){let c=typeof i.message=="string"?i.message:`${a} check failed`;o.push(`${a}: ${c}`);}return await d(e$1,".workspai/reports/doctor-last-run.json",f$1({schemaVersion:a$2,evidenceType:"workspace",contract:ve(),policyProfile:t.policyProfile,workspacePath:e$1,workspaceName:t.workspaceName,projectScanCached:t.projectScanCached??false,projectScanSignature:t.projectScanSignature,cachePath:r,healthScore:t.healthScore,evidenceFreshness:t.evidenceFreshness,system:{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore,versions:{core:t.coreVersion,npm:t.npmVersion}},projects:t.projects,summary:{totalProjects:t.projects.length,totalIssues:t.projects.reduce((a,i)=>a+i.issues.length,0),projectAdvisoryWarningProjects:dt(t.projects),projectAdvisoryWarnings:ft(t.projects),hasSystemErrors:[t.python,t.rapidkitCore].some(a=>a.status==="error"),scopeProvenance:t.scopeProvenance},driftDelta:t.driftDelta,scoreBreakdown:t.scoreBreakdown??[]},{commandId:"checkWorkspaceHealth",exitCode:xe(t.healthScore,{profile:t.policyProfile?.name}),generatedAt:new Date().toISOString(),blockers:o.slice(0,12),runId:e()})),n}catch{return}}async function yt(){let[e,t,r,n,o]=await Promise.all([wr(),vr(),br(),jr(),xr()]);return {python:e,poetry:t,pipx:r,go:n,rapidkitCore:o}}async function wr(){let e=i$1();for(let t of e)try{let{stdout:r}=await execa(t,["--version"],{timeout:3e3}),n=r.match(/Python (\d+\.\d+\.\d+)/);if(n){let o=n[1],[a,i]=o.split(".").map(Number);return a<3||a===3&&i<10?{status:"warn",message:`Python ${o} (requires 3.10+)`,details:`${t} found but version is below minimum requirement`}:{status:"ok",message:`Python ${o}`,details:`Using ${t}`}}}catch{continue}return {status:"error",message:"Python not found",details:"Install Python 3.10+ and ensure it's in PATH"}}async function vr(){try{let{stdout:e}=await execa("poetry",["--version"],{timeout:3e3}),t=e.match(/Poetry .*version ([\d.]+)/);return t?{status:"ok",message:`Poetry ${t[1]}`,details:"Available for dependency management"}:{status:"warn",message:"Poetry version unknown"}}catch{let e=i$1().map(t=>({cmd:t,args:t==="py"?["-3","-m","poetry","--version"]:["-m","poetry","--version"]}));for(let t of e)try{let{stdout:r}=await execa(t.cmd,t.args,{timeout:3e3,shell:c$2()}),n=r.match(/Poetry .*version ([\d.]+)/)||r.match(/([\d.]+)/);return {status:"ok",message:n?.[1]?`Poetry ${n[1]}`:"Poetry detected",details:`Available via ${t.cmd} ${t.args.join(" ")}`}}catch{continue}for(let t of Un())try{if(!await l.pathExists(t))continue;let{stdout:r}=await execa(t,["--version"],{timeout:3e3,shell:c$2()}),n=r.match(/Poetry .*version ([\d.]+)/)||r.match(/([\d.]+)/);return {status:"ok",message:n?.[1]?`Poetry ${n[1]}`:"Poetry detected",details:`Available at ${t}`}}catch{continue}return {status:"warn",message:"Poetry not installed",details:"Optional: Install for better dependency management"}}}async function br(){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 t of e)try{let r=t==="py"?["-3","-m","pipx","--version"]:["-m","pipx","--version"],{stdout:n}=await execa(t,r,{timeout:3e3,shell:c$2()});return {status:"ok",message:`pipx ${n.trim()}`,details:`Available via ${t} ${r.join(" ")}`}}catch{continue}return {status:"warn",message:"pipx not installed",details:"Optional: Install for isolated Python tools"}}}async function jr(){try{let{stdout:e}=await execa("go",["version"],{timeout:3e3}),t=e.match(/go version go(\d+\.\d+(?:\.\d+)?)/);return t?{status:"ok",message:`Go ${t[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 xr(){let e=process.env.HOME||process.env.USERPROFILE||"",t=[],r=zn(e);for(let{location:o,path:a}of r)try{if(await l.pathExists(a)){let{stdout:i,exitCode:c}=await execa(a,["--version"],{timeout:3e3,reject:false});if(c===0&&(i.includes("RapidKit Version")||i.includes("RapidKit"))){let d=i.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);d&&t.push({location:o,path:a,version:d[1]});}}}catch{continue}if(t.length>0){let o=t.filter(i=>i.location!=="Workspace (launcher)");if(o.length>0){let i=Yn(o),c=i[0].version,d=i.some(y=>y.location==="Workspace (.venv)"),u=i.some(y=>y.location.startsWith("Global (")),h=!d&&u?"Workspace (.venv): not installed (optional). For RapidKit Core module-enabled projects, run npx workspai workspace run init inside this workspace to install the local Python engine.":void 0;return {status:"ok",message:`RapidKit Core ${c}`,details:h,paths:i.map(y=>({location:y.location,path:y.path,version:y.version}))}}return {status:"ok",message:`RapidKit Core ${t[0].version}`,details:"Detected via workspace launcher"}}try{let{stdout:o,exitCode:a}=await execa("rapidkit",["--version"],{timeout:3e3,reject:false});if(a===0&&(o.includes("RapidKit Version")||o.includes("RapidKit"))){let i=o.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(i)return {status:"ok",message:`RapidKit Core ${i[1]}`,details:"Available via PATH"}}}catch{}try{let{stdout:o,exitCode:a}=await execa("poetry",["run","rapidkit","--version"],{timeout:3e3,reject:false});if(a===0&&(o.includes("RapidKit Version")||o.includes("RapidKit"))){let i=o.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(i)return {status:"ok",message:`RapidKit Core ${i[1]}`,details:"Available via Poetry"}}}catch{}let n=i$1();for(let o of n)try{let{stdout:a,exitCode:i}=await execa(o,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:3e3,reject:false});if(i===0&&a&&!a.includes("Traceback")&&!a.includes("ModuleNotFoundError")){let c=a.trim();if(c)return {status:"ok",message:`RapidKit Core ${c}`,details:`Available in ${o} environment`}}}catch{continue}return {status:"error",message:"RapidKit Core not installed",details:"Install with: pipx install rapidkit-core"}}async function U(e,t,r){let n=s.join(e,"Dockerfile");t.hasDocker=await l.pathExists(n);let o=s.join(e,"tests"),a=s.join(e,"test"),i=s.join(e,"src","test"),c=await l.pathExists(o)||await l.pathExists(a)||await l.pathExists(i),d=false;if(t.framework==="Go/Fiber"||t.framework==="Go/Gin")try{let u=[{dir:e,depth:0}],h=4,y=new Set([".git",".venv","node_modules","dist","build","vendor"]);for(;u.length>0&&!d;){let w=u.shift();if(!w)break;let g=[];try{g=await l.readdir(w.dir);}catch{continue}for(let f of g){let v=s.join(w.dir,f),x;try{x=await l.stat(v);}catch{continue}if(x.isFile()&&f.endsWith("_test.go")){d=true;break}x.isDirectory()&&w.depth<h&&!y.has(f)&&!f.startsWith(".")&&u.push({dir:v,depth:w.depth+1});}}}catch{}if(t.hasTests=c||d,t.runtimeFamily==="node"&&!t.hasTests&&(t.hasTests=await Kt(e,r)),t.runtimeFamily==="node")t.hasCodeQuality=await Wt(e,r);else if(t.framework==="Go/Fiber"||t.framework==="Go/Gin"){let u=s.join(e,".golangci.yml"),h=s.join(e,".golangci.yaml"),y=s.join(e,"Makefile"),w=await l.pathExists(y)&&(await l.readFile(y,"utf8")).includes("golangci-lint");t.hasCodeQuality=await l.pathExists(u)||await l.pathExists(h)||w;}else if(t.runtimeFamily==="python"){let u=s.join(e,"ruff.toml"),h=s.join(e,"pyproject.toml");if(await l.pathExists(h))try{let y=await l.readFile(h,"utf8");t.hasCodeQuality=y.includes("[tool.ruff]")||await l.pathExists(u);}catch{t.hasCodeQuality=await l.pathExists(u);}}else if(t.framework==="Spring Boot"){let u=s.join(e,"pom.xml");if(await l.pathExists(u))try{let h=await l.readFile(u,"utf8");t.hasCodeQuality=h.includes("spotless")||h.includes("checkstyle")||h.includes("pmd")||h.includes("maven-enforcer-plugin");}catch{t.hasCodeQuality=false;}}try{if(t.runtimeFamily==="node"){let{stdout:u}=await execa("npm",["audit","--json"],{cwd:e,reject:false});if(u)try{let y=JSON.parse(u).metadata?.vulnerabilities;y&&(t.vulnerabilities=(y.high||0)+(y.critical||0)+(y.moderate||0));}catch{}}else if(t.runtimeFamily==="python"){let u=s.join(e,".venv"),h=l$1(u);if(await l.pathExists(h))try{let{stdout:y}=await execa(h,["-m","pip","list","--format=json"],{timeout:5e3,reject:false});if(y){JSON.parse(y);t.vulnerabilities=0;}}catch{}}}catch{}}function W(e,t){e.probes||(e.probes=[]);let r=sn(t,new Date().toISOString());e.probes.push(r),r.repairCapability&&(e.repairCapabilities||(e.repairCapabilities=[]),e.repairCapabilities.push(r.repairCapability),r.repairCapability.status==="available"&&r.repairCapability.canAutoFix&&r.repairCapability.command&&(e.fixCommands=e.fixCommands??[],e.fixCommands.includes(r.repairCapability.command)||e.fixCommands.push(r.repairCapability.command)));}async function Pr(e,t){let r=t.runtimeFamily||"unknown";if(t.projectKind==="backend"||t.projectKind==="generic"){if(r==="node"){let o=await l.pathExists(s.join(e,"package-lock.json"))||await l.pathExists(s.join(e,"pnpm-lock.yaml"))||await l.pathExists(s.join(e,"yarn.lock"));W(t,{id:"adapter-node-lockfile-integrity",label:"Node adapter lockfile integrity",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?"Node lockfile detected for deterministic dependency restore.":"No Node lockfile detected (package-lock/yarn.lock/pnpm-lock.yaml).",recommendation:o?void 0:"Commit a lockfile for deterministic installs and CI parity."});let a=await l.pathExists(s.join(e,"src/main.ts"))||await l.pathExists(s.join(e,"src/main.js"))||await l.pathExists(s.join(e,"src/server.ts"))||await l.pathExists(s.join(e,"src/server.js"));W(t,{id:"adapter-node-boot-entrypoint",label:"Node adapter boot entrypoint",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Boot entrypoint markers detected for service startup path.":"No canonical Node boot entrypoint markers detected.",recommendation:a?void 0:"Define and document service bootstrap entrypoint (main/server)."});return}if(r==="python"){let o=await l.pathExists(s.join(e,"poetry.lock"))||await l.pathExists(s.join(e,"requirements.txt"))||await l.pathExists(s.join(e,"uv.lock"));W(t,{id:"adapter-python-lockfile-integrity",label:"Python adapter dependency integrity",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?"Python dependency contract file detected.":"No Python dependency contract file detected (poetry.lock/requirements/uv.lock).",recommendation:o?void 0:"Pin dependency contract for deterministic setup and reproducible CI."});let a=await l.pathExists(s.join(e,"app/main.py"))||await l.pathExists(s.join(e,"main.py"))||await l.pathExists(s.join(e,"manage.py"));W(t,{id:"adapter-python-boot-entrypoint",label:"Python adapter boot entrypoint",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Python application entrypoint markers detected.":"No Python application entrypoint markers detected.",recommendation:a?void 0:"Expose explicit app/main entrypoint for deterministic boot probes."});return}if(r==="java"){let o=await l.pathExists(s.join(e,"mvnw"))||await l.pathExists(s.join(e,"gradlew"));W(t,{id:"adapter-java-build-wrapper",label:"Java adapter build wrapper",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?"Build wrapper detected (mvnw/gradlew).":"No Java build wrapper detected.",recommendation:o?void 0:"Commit mvnw or gradlew for reproducible enterprise pipelines."});return}if(r==="go"){let o=await l.pathExists(s.join(e,"go.sum"));W(t,{id:"adapter-go-module-integrity",label:"Go adapter module integrity",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?"go.sum detected for deterministic module verification.":"go.sum missing; module integrity baseline is incomplete.",recommendation:o?void 0:"Generate and commit go.sum in the repository baseline."});}}}async function Cr(e,t){let r=[s.join(e,".workspai","doctor.adapters.json"),s.join(e,".rapidkit","doctor.adapters.json"),s.join(e,"doctor.adapters.json")];for(let n of r)if(await l.pathExists(n))try{let o=await l.readJSON(n),a=Array.isArray(o?.checks)?o.checks:[];for(let i=0;i<a.length;i+=1){let c=a[i]||{},d=Array.isArray(c.runtimes)?c.runtimes:[];if(d.length>0&&!d.includes(t.runtimeFamily||"unknown"))continue;let u=typeof c.id=="string"&&c.id.trim().length>0?c.id.trim():`adapter-check-${i+1}`,h=typeof c.label=="string"&&c.label.trim().length>0?c.label.trim():u,y=c.severity||"warn",w=Array.isArray(c.anyOfPaths)?c.anyOfPaths.filter(Boolean):[],g=Array.isArray(c.allOfPaths)?c.allOfPaths.filter(Boolean):[],f=w.length===0;for(let k of w)if(await l.pathExists(s.join(e,k))){f=true;break}let v=true;for(let k of g)if(!await l.pathExists(s.join(e,k))){v=false;break}let x=f&&v;W(t,{id:u,label:h,status:x?"pass":y==="error"?"fail":"warn",severity:y,scope:"project-scoped",reason:x?c.passReason||"Custom adapter contract satisfied.":c.failReason||`Custom adapter check failed from ${s.basename(n)}.`,recommendation:c.recommendation});}}catch{W(t,{id:"custom-adapter-config",label:"Custom doctor adapter configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${s.basename(n)}.`,recommendation:"Fix JSON syntax in doctor.adapters.json to re-enable adapter checks."});}}async function z(e,t){if(!(t.projectKind==="backend"||t.projectKind==="generic"))return;let n=s.join(e,".env"),o=s.join(e,".env.example"),a=await l.pathExists(n)||await l.pathExists(o)||await l.pathExists(s.join(e,"config"));W(t,{id:"config-surface",label:"Configuration contract surface",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Configuration artifacts detected (.env/.env.example/config).":"No explicit configuration contract artifacts detected.",recommendation:a?void 0:"Add .env.example or explicit config contract documentation for deterministic setup."});let i={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"]},c=t.runtimeFamily||"unknown",d=i[c]||i.unknown,u=false;for(let w of d)if(await l.pathExists(s.join(e,w))){u=true;break}W(t,{id:"migration-surface",label:"Migration/readiness surface",status:u?"pass":"warn",severity:"warn",scope:"project-scoped",reason:u?"Migration or schema evolution markers detected.":"No migration markers detected for this backend runtime.",recommendation:u?void 0:"Add migration tooling baseline (migrations dir or runtime-native migration config)."});let h=["src/health","src/healthcheck","src/main/resources/application.yml","src/main/resources/application.properties","app/health.py","routes/health.ts","routes/health.js"],y=false;for(let w of h)if(await l.pathExists(s.join(e,w))){y=true;break}W(t,{id:"runtime-health-surface",label:"Runtime health probe surface",status:y?"pass":"warn",severity:"warn",scope:"project-scoped",reason:y?"Health endpoint/config markers detected.":"No explicit runtime health endpoint markers detected.",recommendation:y?void 0:"Expose a deterministic health endpoint and keep it covered in verify pack."}),await Pr(e,t);}async function Rr(e,t,r,n){let o=await Vt({projectPath:e,detection:n,packageJsonData:r});for(let a of o)W(t,a);}async function Y(e,t,r){let n=await Jt({projectPath:e,runtimeFamily:t.runtimeFamily,projectKind:t.projectKind,packageJsonData:r,hasTests:t.hasTests,vulnerabilities:t.vulnerabilities});for(let o of n)W(t,o);}async function Q(e,t){let r=[s.join(e,".workspai","doctor.probes.json"),s.join(e,".rapidkit","doctor.probes.json"),s.join(e,"doctor.probes.json")];for(let n of r)if(await l.pathExists(n))try{let o=await l.readJSON(n),a=Array.isArray(o?.probes)?o.probes:[];for(let i=0;i<a.length;i+=1){let c=a[i]||{},d=typeof c.id=="string"&&c.id.trim().length>0?c.id.trim():`custom-probe-${i+1}`,u=typeof c.label=="string"&&c.label.trim().length>0?c.label.trim():d,h=c.severity||"warn",y=Array.isArray(c.anyOfPaths)?c.anyOfPaths.filter(Boolean):[],w=Array.isArray(c.allOfPaths)?c.allOfPaths.filter(Boolean):[],g=y.length===0;for(let x of y)if(await l.pathExists(s.join(e,x))){g=true;break}let f=true;for(let x of w)if(!await l.pathExists(s.join(e,x))){f=false;break}let v=g&&f;W(t,{id:d,label:u,status:v?"pass":h==="error"?"fail":"warn",severity:h,scope:"project-scoped",reason:v?"Custom probe contract satisfied.":`Custom probe failed from ${s.basename(n)}.`,recommendation:c.recommendation});}}catch{W(t,{id:"custom-probe-config",label:"Custom doctor probe configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${s.basename(n)}.`,recommendation:"Fix JSON syntax in doctor.probes.json to re-enable custom probes."});}await Cr(e,t);}async function qe(e,t={}){let n={name:s.basename(e),path:e,venvActive:false,depsInstalled:false,coreInstalled:false,issues:[],fixCommands:[]},o=t.allowNonRapidkit===true;if(!(await l.pathExists(s.join(e,".workspai"))||await l.pathExists(s.join(e,".rapidkit")))){if(!o)return n.issues.push("Not a valid Workspai project (missing .workspai metadata)"),n;n.issues.push("Not a Workspai-managed project (running generic backend diagnostics)");}try{let b=s.join(e,"registry.json");if(await l.pathExists(b)){let P=await l.readJson(b);P.installed_modules&&(n.stats={modules:P.installed_modules.length});}}catch{}try{let{auditProjectModulePaths:b}=await import('./module-layout-NZ43RSC5.js'),P=await b(e);if(P.issues.length>0){for(let S of P.issues)n.issues.push(`${S.message} (${S.slug})`);n.fixCommands=n.fixCommands??[],n.fixCommands.push("npx workspai workspace contract verify --strict --json"),n.fixCommands.push("npx workspai add module <slug> # reinstall via Core-backed module install");}}catch{}let i$1=null;try{for(let b of p$1(e,"project.json")){if(!await l.pathExists(b))continue;i$1=await l.readJson(b);let P=i$1?.kit_name||i$1?.kit;P&&(n.kit=P);break}}catch{}try{let b=s.join(e,".git");if(await l.pathExists(b)){let{stdout:P}=await execa("git",["log","-1","--format=%cr"],{cwd:e,reject:false});P&&(n.lastModified=P.trim());}else {let P=await l.stat(e),H=Date.now()-P.mtime.getTime(),F=Math.floor(H/(1e3*60*60*24));n.lastModified=F===0?"today":`${F} day${F>1?"s":""} ago`;}}catch{}let c=s.join(e,"package.json"),d=s.join(e,"pyproject.toml"),u=s.join(e,"requirements.txt"),h=s.join(e,"go.mod"),y=s.join(e,"pom.xml"),w=s.join(e,"build.sbt"),g=s.join(e,"Cargo.toml"),f=s.join(e,"mix.exs"),v=s.join(e,"deps.edn"),x=s.join(e,"project.clj"),k=s.join(e,"deno.json"),R=s.join(e,"deno.jsonc"),I=s.join(e,"bun.lockb"),T=s.join(e,"bun.lock"),m=s.join(e,"composer.json"),D=s.join(e,"Gemfile"),C=await l.pathExists(c),ee=await l.pathExists(d)||await l.pathExists(u),j=await l.pathExists(m),te=await l.pathExists(D),O=await l.pathExists(g),ie=await l.pathExists(f),Ne=await l.pathExists(v)||await l.pathExists(x),Ie=await l.pathExists(w),Ae=await l.pathExists(k)||await l.pathExists(R),K=i$1?.runtime==="dotnet";try{K=K||await Qt(e,".csproj",3)||await Qt(e,".sln",2);}catch{K=i$1?.runtime==="dotnet";}let Ce=await l.pathExists(h)||i$1?.runtime==="go"||typeof i$1?.kit_name=="string"&&(i$1.kit_name.startsWith("gofiber")||i$1.kit_name.startsWith("gogin")),de=C&&(await l.pathExists(I)||await l.pathExists(T)||typeof i$1?.packageManager=="string"&&(i$1?.packageManager).toLowerCase().startsWith("bun@"));if(Ce){Z(n,i(e,i$1??null)),n.isGoProject=true,n.venvActive=true,n.coreInstalled=false;try{await execa("go",["version"],{timeout:3e3});}catch{n.issues.push("Go toolchain not found \u2014 install from https://go.dev/dl/"),n.fixCommands?.push("https://go.dev/dl/");}let b=s.join(e,"go.sum");return await l.pathExists(b)?n.depsInstalled=true:(n.depsInstalled=false,n.issues.push("Go dependencies not downloaded (go.sum missing)"),n.fixCommands?.push(V(e,"go mod tidy"))),await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(await l.pathExists(y)||i$1?.runtime==="java"||typeof i$1?.kit_name=="string"&&i$1.kit_name.startsWith("springboot")){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=await l.pathExists(y),P=await l.pathExists(s.join(e,"build.gradle"))||await l.pathExists(s.join(e,"build.gradle.kts")),S=await l.pathExists(s.join(e,"mvnw"))||await l.pathExists(s.join(e,"mvnw.cmd")),H=await l.pathExists(s.join(e,"gradlew"))||await l.pathExists(s.join(e,"gradlew.bat"));try{await execa("java",["-version"],{timeout:3e3,reject:false});}catch{n.issues.push("Java runtime not found \u2014 install JDK 21+ and ensure java is on PATH"),n.fixCommands?.push("https://adoptium.net/");}if(b){if(!S)try{await execa("mvn",["-version"],{timeout:3e3,reject:false});}catch{n.issues.push("Maven not found \u2014 install Maven 3.9+ or add Maven Wrapper"),n.fixCommands?.push("https://maven.apache.org/install.html");}}else if(P&&!H)try{await execa("gradle",["--version"],{timeout:3e3,reject:false});}catch{n.issues.push("Gradle not found \u2014 install Gradle 8+ or add Gradle Wrapper"),n.fixCommands?.push("https://gradle.org/install/");}let F=s.join(e,"target"),A=s.join(e,"build","libs"),J=s.join(e,".workspai","cache","java","m2"),$=s.join(e,".workspai","cache","java","gradle");n.depsInstalled=await l.pathExists(F)||await l.pathExists(A)||await l.pathExists(J)||await l.pathExists($),n.depsInstalled||(n.issues.push("Java dependencies are not warmed or built yet"),n.fixCommands?.push(V(e,"npx workspai init")));let B=s.join(e,".env");if(n.hasEnvFile=await l.pathExists(B),!n.hasEnvFile){let pe=s.join(e,".env.example");await l.pathExists(pe)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}let re=s.join(e,"src","main","resources","application.yml");if(await l.pathExists(re))try{let pe=await l.readFile(re,"utf-8");/include:\s*[^\n]*health/i.test(pe)||/management:\s*[\s\S]*endpoint:\s*[\s\S]*health:/i.test(pe)||(n.issues.push("Actuator health endpoint exposure is not clearly configured in application.yml"),n.fixCommands?.push(V(e,"Ensure management.endpoints.web.exposure.include contains health in src/main/resources/application.yml")));}catch{n.issues.push("Unable to read application.yml for Spring Actuator health checks");}return await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(O){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=s.join(e,"Cargo.lock"),P=s.join(e,"target");n.depsInstalled=await l.pathExists(b)||await l.pathExists(P),n.depsInstalled||(n.issues.push("Rust dependencies are not resolved yet (Cargo.lock/target missing)"),n.fixCommands?.push(V(e,"cargo fetch")));let S=s.join(e,".env");if(n.hasEnvFile=await l.pathExists(S),!n.hasEnvFile){let H=s.join(e,".env.example");await l.pathExists(H)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}return await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(ie){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=s.join(e,"mix.lock"),P=s.join(e,"deps");n.depsInstalled=await l.pathExists(b)||await l.pathExists(P),n.depsInstalled||(n.issues.push("Elixir dependencies not installed (mix.lock/deps missing)"),n.fixCommands?.push(V(e,"mix deps.get")));let S=s.join(e,".env");if(n.hasEnvFile=await l.pathExists(S),!n.hasEnvFile){let H=s.join(e,".env.example");await l.pathExists(H)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}return await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(Ne){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=s.join(e,".cpcache"),P=s.join(e,"target"),S=await l.pathExists(v)||await l.pathExists(x);return n.depsInstalled=await l.pathExists(b)||await l.pathExists(P)||S,n.depsInstalled||(n.issues.push("Clojure dependency cache not initialized"),n.fixCommands?.push(V(e,"clojure -P"))),await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(Ie){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=s.join(e,"target");n.depsInstalled=await l.pathExists(b),n.depsInstalled||(n.issues.push("Scala build artifacts missing (run dependency/build warmup)"),n.fixCommands?.push(V(e,"sbt compile")));let P=s.join(e,".env");if(n.hasEnvFile=await l.pathExists(P),!n.hasEnvFile){let S=s.join(e,".env.example");await l.pathExists(S)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}return await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(Ae){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false,n.depsInstalled=true;let b=s.join(e,".env");if(n.hasEnvFile=await l.pathExists(b),!n.hasEnvFile){let P=s.join(e,".env.example");await l.pathExists(P)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}return await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(C){let b=null;try{b=await l.readJson(c);}catch{b=null;}let P={...b?.dependencies??{},...b?.devDependencies??{}},S=b?.scripts??{},H=typeof i$1?.kit_name=="string"?i$1.kit_name.toLowerCase():typeof i$1?.kit=="string"?i$1.kit.toLowerCase():"",F=d$1(e,i$1),A=ur({dependencies:P,scripts:S,kitName:H});if(de)He(n,"Bun","high");else {let $=i(e,i$1??null);$.key==="nestjs"||$.key==="express"||$.key==="fastify"||$.key==="koa"?Z(n,$):F.key!=="unknown"?pr(n,F):$.key!=="unknown"&&$.key!=="node"?Z(n,$):He(n,A.framework,A.confidence);}n.venvActive=true;let J=s.join(e,"node_modules");if(await l.pathExists(J))try{let B=(await l.readdir(J)).filter(re=>!re.startsWith(".")&&!re.startsWith("_"));n.depsInstalled=B.length>0;}catch{n.depsInstalled=false;}if(n.depsInstalled||(n.issues.push("Dependencies not installed (node_modules empty or missing)"),n.fixCommands?.push(V(e,de?"bun install":"npx workspai init"))),n.coreInstalled=false,n.projectKind==="frontend"){let $=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local"];if((await Promise.all($.map(re=>l.pathExists(s.join(e,re))))).some(Boolean))n.hasEnvFile=true;else {let re=s.join(e,".env.example");await l.pathExists(re)&&(n.hasEnvFile=false,n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}}else {let $=s.join(e,".env");if(n.hasEnvFile=await l.pathExists($),!n.hasEnvFile){let B=s.join(e,".env.example");await l.pathExists(B)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}}if(n.projectKind==="frontend")n.modulesHealthy=await rt(e),n.missingModules=[];else {let $=s.join(e,"src");if(n.modulesHealthy=true,n.missingModules=[],await l.pathExists($))try{let B=await l.readdir($);n.modulesHealthy=B.length>0;}catch{n.modulesHealthy=false;}}return await U(e,n,b),await Y(e,n,b),n.projectKind==="frontend"?await Rr(e,n,b,F.key!=="unknown"?F:d$1(e,i$1)):await z(e,n),await Q(e,n),n}if(ee){let b=await mr(e,i$1);He(n,b.framework,b.confidence);let P=s.join(e,".venv");if(await l.pathExists(P)){n.venvActive=true;let A=l$1(P);if(await l.pathExists(A)){try{let{stdout:B}=await execa(A,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:2e3});n.coreInstalled=true,n.coreVersion=B.trim();}catch{n.coreInstalled=false;}let J="fastapi";n.framework==="Django"?J="django":n.framework==="Flask"?J="flask":n.framework==="Python"&&(J="");let $=true;if(J)try{await execa(A,["-c",`import ${J}`],{timeout:2e3}),n.depsInstalled=true,$=false;}catch{$=true;}if($)try{let B=s.join(P,"lib");if(await l.pathExists(B)){let pe=(await l.readdir(B)).find(Re=>Re.startsWith("python"));if(pe){let Re=s.join(B,pe,"site-packages");if(await l.pathExists(Re)){let kn=(await l.readdir(Re)).filter(Ke=>!Ke.startsWith("_")&&!Ke.includes("dist-info")&&!["pip","setuptools","wheel","pkg_resources"].includes(Ke));n.depsInstalled=kn.length>0;}}}n.depsInstalled||(n.issues.push("Dependencies not installed"),n.fixCommands?.push(zt(e)));}catch{n.issues.push("Could not verify dependency installation");}}else n.issues.push("Virtual environment exists but Python executable not found");}else n.issues.push("Virtual environment not created"),n.fixCommands?.push(zt(e));let S=s.join(e,".env");if(n.hasEnvFile=await l.pathExists(S),!n.hasEnvFile){let A=s.join(e,".env.example");await l.pathExists(A)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}let H=s.join(e,"src"),F=s.join(e,"modules");if(n.modulesHealthy=true,n.missingModules=[],await l.pathExists(H)){let A=s.join(H,"__init__.py");await l.pathExists(A)||(n.modulesHealthy=false,n.missingModules.push("src/__init__.py"));}if(await l.pathExists(F))try{let A=await Dr(F);for(let J of A){let $=s.join(F,J,"__init__.py");await l.pathExists($)||(n.modulesHealthy=false,n.missingModules.push(`modules/${J}/__init__.py`));}}catch{}return !n.modulesHealthy&&n.missingModules.length>0&&n.issues.push(`Missing module init files: ${n.missingModules.join(", ")}`),await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(j){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=s.join(e,"vendor");n.depsInstalled=await l.pathExists(b),n.depsInstalled||(n.issues.push("PHP dependencies not installed (vendor missing)"),n.fixCommands?.push(V(e,"composer install")));let P=s.join(e,".env");if(n.hasEnvFile=await l.pathExists(P),!n.hasEnvFile){let S=s.join(e,".env.example");await l.pathExists(S)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(ae(e)));}return await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(te){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=await l.pathExists(s.join(e,"Gemfile.lock")),P=await l.pathExists(s.join(e,"vendor","bundle"));n.depsInstalled=b||P,n.depsInstalled||(n.issues.push("Ruby dependencies not installed (Gemfile.lock/vendor missing)"),n.fixCommands?.push(V(e,"bundle install")));let S=s.join(e,".env");return n.hasEnvFile=await l.pathExists(S),await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}if(K){Z(n,i(e,i$1??null)),n.venvActive=true,n.coreInstalled=false;let b=s.join(e,"obj"),P=s.join(e,"src","obj"),S=s.join(e,"packages.lock.json");n.depsInstalled=await l.pathExists(b)||await l.pathExists(P)||await l.pathExists(S),n.depsInstalled||(n.issues.push(".NET restore/build artifacts not found"),n.fixCommands?.push(V(e,"dotnet restore")));let H=s.join(e,".env");return n.hasEnvFile=await l.pathExists(H),await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}return He(n,"Unknown","low"),n.issues.push("Unknown project type (no recognized runtime marker files)"),await U(e,n),await Y(e,n),await z(e,n),await Q(e,n),n}async function Dr(e){try{return (await l.readdir(e,{withFileTypes:true})).filter(r=>r.isDirectory()).map(r=>r.name)}catch{try{let t=await l.readdir(e),r=[];for(let n of t)try{(await l.stat(s.join(e,n))).isDirectory()&&r.push(n);}catch{continue}return r}catch{return []}}}async function Qt(e,t,r){let n=[{dir:e,depth:0}],o=new Set([".git",".workspai",".rapidkit","node_modules","bin","obj","target"]);for(;n.length>0;){let a=n.shift();if(!a||a.depth>r)continue;let i;try{i=await l.readdir(a.dir,{withFileTypes:true});}catch{continue}for(let c of i){if(c.isFile()&&c.name.toLowerCase().endsWith(t.toLowerCase()))return true;c.isDirectory()&&!o.has(c.name)&&n.push({dir:s.join(a.dir,c.name),depth:a.depth+1});}}return false}async function $e(e){let t=["project.json","context.json","file-hashes.json"];for(let r of [".workspai",".rapidkit"])for(let n of t)if(await l.pathExists(s.join(e,r,n)))return true;return false}function Er(e,t){if(t.has(e))return true;let r=e.toLowerCase();return !!(r==="dist"||r.startsWith("dist-")||r.startsWith("dist_")||r==="build"||r.startsWith("build-")||r.startsWith("build_"))}async function Sr(e,t,r){let n=new Set,o=[{dir:e,depth:0}];for(;o.length>0;){let a=o.shift();if(!a)break;try{let i=await l.readdir(a.dir);for(let c of i){if(Er(c,r))continue;let d=s.join(a.dir,c),u;try{u=await l.stat(d);}catch{continue}if(u.isDirectory()){if(await $e(d)){n.add(d);continue}a.depth<t&&o.push({dir:d,depth:a.depth+1});}}}catch{continue}}return Array.from(n)}async function Fe(e){let t=s.resolve(e),r=s.parse(t).root;for(;;){if(await Nr(t))return t;if(t===r)break;t=s.dirname(t);}return null}async function $r(e){let t=s.resolve(e),r=await Fe(t),n=r??s.parse(t).root;for(;;){if(await $e(t)||await Fr(t)&&(!r||t!==r))return t;if(t===n)break;t=s.dirname(t);}return null}function Xt(e){let t=s.resolve(e);return process.platform==="darwin"?t.replace(/^\/private(?=\/var\/)/,""):t}async function Fr(e){let t=["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 r of t)if(await l.pathExists(s.join(e,r)))return true;return false}async function Nr(e){let t=[s.join(e,".rapidkit-workspace"),s.join(e,".rapidkit","workspace-marker.json"),s.join(e,".rapidkit","config.json")];return Promise.all(t.map(r=>l.pathExists(r))).then(r=>r.some(Boolean))}function ht(e,t){let r=0,n=0,o=0;return e.forEach(i=>{i.status==="ok"?r++:i.status==="warn"?n++:i.status==="error"&&o++;}),t.forEach(i=>{let c=ge(i),d=i.isGoProject?i.issues.length===0&&i.depsInstalled:i.issues.length===0&&i.venvActive&&i.depsInstalled;if(i.issues.length>0||c>0||!d){n++;return}r++;}),{total:r+n+o,passed:r,warnings:n,errors:o}}function fn(e,t,r={}){let n=[];for(let a of e)n.push({id:a.id,label:a.label,status:a.result.status,scope:"host-system",policyRuleId:"system-status-derived",reason:a.result.details||a.result.message});let o=[...t].sort((a,i)=>{let c=`${a.path||""}|${a.name||""}`.toLowerCase(),d=`${i.path||""}|${i.name||""}`.toLowerCase();return c.localeCompare(d)});for(let a of o){let i=a.issues.length>0,c=ge(a),d=i||c>0?"warn":"ok",u=i?`${a.issues.length} blocking issue(s)`:c>0?`${c} advisory warning(s)`:"Project checks passed";n.push({id:`project:${a.name}`,label:`Project ${a.name}`,status:d,scope:"project-scoped",policyRuleId:i?"project-blocking-issues":c>0?"project-advisory-warnings":"project-checks-passed",reason:u});}if(r.includeWorkspaceAggregateRules){let a=t.reduce((d,u)=>d+u.issues.length,0),i=ft(t),c=e.filter(d=>d.result.status==="error").length;n.push({id:"workspace:projects-discovered",label:"Workspace projects discovered",status:t.length>0?"ok":"warn",scope:"workspace-aggregate",policyRuleId:"workspace-project-discovery",reason:t.length>0?`${t.length} project(s) discovered for workspace analysis.`:"No projects discovered for workspace analysis."}),n.push({id:"workspace:system-error-gate",label:"Workspace system error gate",status:c>0?"error":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-system-error-gate",reason:c>0?`${c} system requirement gate(s) failed.`:"All system requirement gates passed."}),n.push({id:"workspace:blocking-issues-gate",label:"Workspace blocking issues gate",status:a>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-blocking-issues-gate",reason:a>0?`${a} blocking project issue(s) detected.`:"No blocking project issues detected."}),n.push({id:"workspace:advisory-warnings-gate",label:"Workspace advisory warnings gate",status:i>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-advisory-warning-gate",reason:i>0?`${i} advisory warning(s) detected.`:"No advisory warnings detected."});}return n}async function ct(e,t=true,r=Be({})){let n=s.basename(e);try{let g=s.join(e,".rapidkit-workspace");await l.pathExists(g)&&(n=(await l.readJSON(g)).name||n);}catch{try{let g=s.join(e,".rapidkit","config.json");n=(await l.readJSON(g)).workspace_name||n;}catch{}}let[o,a]=await Promise.all([yt(),fr(e)]),i={workspacePath:e,workspaceName:n,python:o.python,poetry:o.poetry,pipx:o.pipx,go:o.go,rapidkitCore:o.rapidkitCore,projects:[],policyProfile:r};f.debug(`Workspace scan found ${a.length} project(s)`);let c=await gr(e,a),d=s.join(e,".workspai","reports","doctor-workspace-cache.json"),u=t?await yr(d,c):null;if(u){i.projects=u.projects;for(let g of i.projects)Ut(g,u.generatedAt),pt(g,g.path);i.projectScanCached=true,f.debug(`Workspace project health cache hit: ${d}`);}else try{let g=new Date().toISOString(),f$1=await Promise.all(a.map(v=>qe(v,{allowNonRapidkit:true})));for(let v of f$1)Ut(v,g),pt(v,v.path);i.projects=f$1,i.projectScanCached=false,await hr(d,{schemaVersion:an,signature:c,generatedAt:g,projects:f$1}),f.debug(`Workspace project health cache refreshed: ${d}`);}catch(g){f.debug(`Failed to scan workspace projects: ${g}`);}i.projectScanSignature=c,i.projectScanCachePath=d;let h=[i.python,i.poetry,i.pipx,i.go,i.rapidkitCore];if(i.healthScore=ht(h,i.projects),i.scoreBreakdown=fn([{id:"system-python",label:"Python",result:i.python},{id:"system-poetry",label:"Poetry",result:i.poetry},{id:"system-pipx",label:"pipx",result:i.pipx},{id:"system-go",label:"Go",result:i.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:i.rapidkitCore}],i.projects,{includeWorkspaceAggregateRules:true}),i.scopeProvenance=un(i.scoreBreakdown),i.evidenceFreshness=cn(i.projects,new Date().toISOString()),i.rapidkitCore.status==="ok"){let g=i.rapidkitCore.message.match(/([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);g&&(i.coreVersion=g[1]);}let y=await c$1(e,".workspai/reports/doctor-last-run.json"),w=y?await dn(y,"workspace"):null;return i.driftDelta=or(w,i),i.evidencePath=await kr(e,i,u?d:null),i}function Zt(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,repairCapabilities:e.repairCapabilities,commandCapabilities:e.commandCapabilities}}async function Ir(e$1,t){let r=e$1||t.projectPath,n=s.join(r,".workspai","reports","doctor-project-last-run.json");try{let o=t.project.issues.filter(a=>typeof a=="string"&&a.trim().length>0).slice(0,12);return await d(r,".workspai/reports/doctor-project-last-run.json",f$1({schemaVersion:b$3,evidenceType:"project",contract:ve(),policyProfile:t.policyProfile,workspacePath:e$1||null,projectPath:t.projectPath,projectName:t.projectName,healthScore:t.healthScore,evidenceFreshness:t.evidenceFreshness,system:{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore},project:t.project,driftDelta:t.driftDelta,summary:{scopeProvenance:t.scopeProvenance},scoreBreakdown:t.scoreBreakdown??[]},{commandId:"projectDoctor",exitCode:xe(t.healthScore,{profile:t.policyProfile?.name}),generatedAt:new Date().toISOString(),blockers:o,runId:e()})),e$1&&s.resolve(e$1)!==s.resolve(t.projectPath)&&await d(t.projectPath,".workspai/reports/doctor-project-last-run.json",await l.readJson(n)),n}catch{return}}async function ut(e,t,r=[]){let n=s.join(e,".workspai","reports","doctor-remediation-plan-last-run.json");try{await d(e,".workspai/reports/doctor-remediation-plan-last-run.json",t);for(let o of r)s.resolve(o)!==s.resolve(e)&&await d(o,".workspai/reports/doctor-remediation-plan-last-run.json",t);return n}catch{return}}async function be(e,t,r=[]){let n=s.join(e,".workspai","reports","doctor-fix-result-last-run.json");try{await d(e,".workspai/reports/doctor-fix-result-last-run.json",t);for(let o of r)s.resolve(o)!==s.resolve(e)&&await d(o,".workspai/reports/doctor-fix-result-last-run.json",t);return n}catch{return}}async function je(e,t,r){try{await j(e,g(t,r));}catch{}}async function en(e,t=Be({})){let r=await Fe(e),n=await yt(),o=await qe(e,{allowNonRapidkit:true});pt(o,e);let a=ht([n.python,n.poetry,n.pipx,n.go,n.rapidkitCore],[o]),i={workspacePath:r||void 0,projectPath:e,projectName:s.basename(e),python:n.python,poetry:n.poetry,pipx:n.pipx,go:n.go,rapidkitCore:n.rapidkitCore,project:o,healthScore:a,policyProfile:t};i.scoreBreakdown=fn([{id:"system-python",label:"Python",result:i.python},{id:"system-poetry",label:"Poetry",result:i.poetry},{id:"system-pipx",label:"pipx",result:i.pipx},{id:"system-go",label:"Go",result:i.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:i.rapidkitCore}],[i.project]),i.scopeProvenance=un(i.scoreBreakdown),i.evidenceFreshness=cn([i.project],new Date().toISOString());let d=await c$1(r||e,".workspai/reports/doctor-project-last-run.json"),u=d?await dn(d,"project"):null;return i.driftDelta=ar(u,i),i.evidencePath=await Ir(r||void 0,i),i}function G(e,t){let r=e.status==="ok"?"\u2705":e.status==="warn"?"\u26A0\uFE0F":"\u274C",n=e.status==="ok"?p.green:e.status==="warn"?p.yellow:p.red;console.log(`${r} ${p.bold(t)}: ${n(e.message)}`),e.paths&&e.paths.length>0&&e.paths.forEach(o=>{let a=o.version?p.cyan(` -> ${o.version}`):"";console.log(` ${p.cyan("\u2022")} ${p.gray(o.location)}: ${p.dim(o.path)}${a}`);}),e.details&&console.log(` ${p.gray(e.details)}`);}function tn(e){let t=e.issues.length>0,r=t?"\u26A0\uFE0F":"\u2705",n=t?p.yellow:p.green;if(console.log(`
|
|
7
|
-
${r} ${p.bold("Project")}: ${n(e.name)}`),e.framework){let i=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(` ${i} Framework: ${p.cyan(e.framework)}${e.kit?p.gray(` (${e.kit})`):""}`);let c=[];e.runtimeFamily&&c.push(`runtime: ${e.runtimeFamily}`),e.projectKind&&c.push(`kind: ${e.projectKind}`),e.supportTier&&c.push(`support: ${e.supportTier}`),e.frameworkConfidence&&c.push(`confidence: ${e.frameworkConfidence}`),c.length>0&&console.log(` ${p.dim("\u21B3")} ${p.gray(c.join(" \u2022 "))}`);}if(console.log(` ${p.gray(`Path: ${e.path}`)}`),e.runtimeFamily==="python"&&(e.venvActive?console.log(` \u2705 Virtual environment: ${p.green("Active")}`):console.log(` \u274C Virtual environment: ${p.red("Not found")}`),e.coreInstalled?console.log(` ${p.dim("\u2139")} RapidKit Core: ${p.gray(e.coreVersion||"In venv")} ${p.dim("(optional)")}`):console.log(` ${p.dim("\u2139")} RapidKit Core: ${p.gray("Using global installation")} ${p.dim("(recommended)")}`)),e.depsInstalled?console.log(` \u2705 Dependencies: ${p.green("Installed")}`):console.log(` \u26A0\uFE0F Dependencies: ${p.yellow("Not installed")}`),e.hasEnvFile!==void 0&&(e.hasEnvFile?console.log(` \u2705 Environment: ${p.green(".env configured")}`):console.log(` \u26A0\uFE0F Environment: ${p.yellow(".env missing")}`)),e.modulesHealthy!==void 0){let i=e.projectKind==="frontend"?"Source tree":"Modules";e.modulesHealthy?console.log(` \u2705 ${i}: ${p.green("Healthy")}`):e.missingModules&&e.missingModules.length>0?console.log(` \u26A0\uFE0F ${i}: ${p.yellow(`Missing ${e.missingModules.length} init file(s)`)}`):e.projectKind==="frontend"&&console.log(` \u26A0\uFE0F ${i}: ${p.yellow("No application directories detected")}`);}if(e.stats){let i=[];e.stats.modules!==void 0&&i.push(`${e.stats.modules} module${e.stats.modules!==1?"s":""}`),i.length>0&&console.log(` \u{1F4CA} Stats: ${p.cyan(i.join(" \u2022 "))}`);}e.lastModified&&console.log(` \u{1F552} Last Modified: ${p.gray(e.lastModified)}`);let a=[];if(e.hasTests!==void 0&&a.push(e.hasTests?"\u2705 Tests":p.dim("\u2298 No tests")),e.hasDocker!==void 0&&a.push(e.hasDocker?"\u2705 Docker":p.dim("\u2298 No Docker")),e.hasCodeQuality!==void 0){let i=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";a.push(e.hasCodeQuality?`\u2705 ${i}`:p.dim(`\u2298 No ${i}`));}if(a.length>0&&console.log(` ${a.join(" \u2022 ")}`),e.vulnerabilities!==void 0&&e.vulnerabilities>0&&console.log(` \u26A0\uFE0F Security: ${p.yellow(`${e.vulnerabilities} vulnerability(ies) found`)}`),e.issues.length>0&&(console.log(` ${p.bold("Issues:")}`),e.issues.forEach(i=>{console.log(` \u2022 ${p.yellow(i)}`);}),e.fixCommands&&e.fixCommands.length>0&&(console.log(`
|
|
8
|
-
${p.bold.cyan("\u{1F527} Quick Fix:")}`),e.fixCommands.forEach(i=>{console.log(` ${p.cyan("$")} ${p.white(i)}`);}))),e.probes&&e.probes.length>0){console.log(` ${p.bold("Probe checks:")}`);for(let i of e.probes){let c=i.status==="pass"?"\u2705":i.status==="warn"?"\u26A0\uFE0F":"\u274C";console.log(` ${c} ${i.label}: ${p.gray(i.reason)}`),i.recommendation&&console.log(` ${p.dim("\u21B3")} ${p.gray(i.recommendation)}`);}}if(e.commandCapabilities){let i=e.commandCapabilities;if(console.log(` ${p.bold("Command support:")}`),console.log(` ${p.green("supported")} ${i.supportedCommands.length} \u2022 ${p.yellow("unsupported")} ${i.unsupportedCommands.length} \u2022 ${p.gray("global")} ${i.globalCommands.length}`),i.unsupportedCommands.length>0){let c=i.unsupportedCommands.slice(0,8).join(", "),d=i.unsupportedCommands.length>8?", ...":"";console.log(` ${p.dim("\u21B3")} ${p.gray(`Unsupported here: ${c}${d}`)}`);}}}async function gn(){try{return (await execa("go",["version"],{timeout:a$3(),reject:false})).exitCode===0}catch{return false}}function ye(e,t){let r=[new RegExp(`^cd\\s+"([^"]+)"\\s*(?:&&|;)\\s*${t}\\s*$`,"i"),new RegExp(`^cd\\s+'([^']+)'\\s*(?:&&|;)\\s*${t}\\s*$`,"i"),new RegExp(`^cd\\s+(.+?)\\s*(?:&&|;)\\s*${t}\\s*$`,"i")];for(let n of r){let o=e.match(n);if(o?.[1])return {projectPath:o[1].trim()}}return null}function Ge(e){return ye(e,"cp\\s+\\.env\\.example\\s+\\.env")||ye(e,"copy-item\\s+\\.env\\.example\\s+\\.env")}function yn(e){let t=[{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:"bun\\s+install",command:"bun",args:["install"]},{pattern:"poetry\\s+install",command:"poetry",args:["install"]},{pattern:"poetry\\s+install\\s+--no-root",command:"poetry",args:["install","--no-root"]},{pattern:"poetry\\s+lock",command:"poetry",args:["lock"]},{pattern:"uv\\s+lock",command:"uv",args:["lock"]},{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 r of t){let n=ye(e,r.pattern);if(n)return {projectPath:n.projectPath,command:r.command,args:r.args}}return null}function Ar(){let e=process.env.RAPIDKIT_DOCTOR_FIX_COMMAND_TIMEOUT_MS;if(e){let t=Number.parseInt(e,10);if(Number.isFinite(t)&&t>0)return t}return 6e4}function We(e){let t=[/^cd\s+"([^"]+)"\s*(?:&&|;)\s*npm\s+pkg\s+set\s+"scripts\.([^=]+)=([^"]+)"\s*$/i,/^cd\s+'([^']+)'\s*(?:&&|;)\s*npm\s+pkg\s+set\s+'scripts\.([^=]+)=([^']+)'\s*$/i,/^cd\s+(.+?)\s*(?:&&|;)\s*npm\s+pkg\s+set\s+scripts\.([^=\s]+)=(.+)\s*$/i];for(let r of t){let n=e.match(r);if(!(!n?.[1]||!n?.[2]||!n?.[3]))return {projectPath:n[1].trim(),scriptName:n[2].trim(),scriptValue:n[3].trim().replace(/\\"/g,'"').replace(/\\\\/g,"\\")}}return null}function Pe(e){let t=e.trim().match(/^rapidkit:doctor:repair\s+([A-Za-z0-9_-]+)$/);if(!t?.[1])return null;try{let r=Buffer.from(t[1],"base64url").toString("utf8"),n=JSON.parse(r);if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n;return o.type==="file-create"&&typeof o.path=="string"&&typeof o.content=="string"&&o.overwrite===false||o.type==="file-append"&&typeof o.path=="string"&&Array.isArray(o.lines)&&o.lines.every(a=>typeof a=="string")&&typeof o.ensureNewline=="boolean"||o.type==="file-copy"&&typeof o.sourcePath=="string"&&typeof o.path=="string"&&o.overwrite===false||o.type==="package-json-script"&&typeof o.path=="string"&&typeof o.scriptName=="string"&&typeof o.scriptValue=="string"||o.type==="json-edit"&&typeof o.path=="string"&&Array.isArray(o.edits)&&o.edits.every(a=>{if(!a||typeof a!="object"||Array.isArray(a))return false;let i=a;return typeof i.pointer=="string"&&i.pointer.startsWith("/")&&(typeof i.value=="string"||typeof i.value=="number"||typeof i.value=="boolean"||i.value===null)})||o.type==="env-key-add"&&typeof o.path=="string"&&Array.isArray(o.keys)&&o.keys.every(a=>{if(!a||typeof a!="object"||Array.isArray(a))return false;let i=a;return typeof i.name=="string"&&/^[A-Z_][A-Z0-9_]*$/i.test(i.name)&&typeof i.value=="string"&&(i.comment===void 0||typeof i.comment=="string")})||o.type==="makefile-target"&&typeof o.path=="string"&&typeof o.target=="string"&&/^[A-Za-z0-9_.:-]+$/.test(o.target)&&typeof o.command=="string"&&o.command.trim().length>0&&typeof o.phony=="boolean"?o:null}catch{return null}}function Or(e){let t=e.operation?Mr(e.operation):`command:${e.command}`,r=createHash("sha256").update(t).digest("base64url").slice(0,16);return `${e.projectName}:${e.kind}:${r}`}function Mr(e){switch(e.type){case "file-create":return `file-create:${e.path}:${e.overwrite}:${e.content}`;case "file-append":return `file-append:${e.path}:${e.ensureNewline}:${e.lines.join(`
|
|
9
|
-
`)}`;case "file-copy":return `file-copy:${e.sourcePath}:${e.path}:${e.overwrite}`;case "package-json-script":return `package-json-script:${e.path}:${e.scriptName}:${e.scriptValue}`;case "json-edit":return `json-edit:${e.path}:${e.edits.map(t=>`${t.pointer}=${JSON.stringify(t.value)}`).join("|")}`;case "env-key-add":return `env-key-add:${e.path}:${e.keys.map(t=>`${t.name}=${t.value??""}`).join("|")}`;case "makefile-target":return `makefile-target:${e.path}:${e.target}:${e.command}:${e.phony}`;default:return `operation:${JSON.stringify(e)}`}}function he(e,t){let r=s.resolve(e),n=s.resolve(t),o=s.relative(r,n);if(o.startsWith("..")||s.isAbsolute(o))throw new Error(`Repair target escapes project boundary: ${t}`);return n}async function Tr(e){if(!/^[A-Za-z0-9:_-]+$/.test(e.scriptName))throw new Error(`Unsafe package script name: ${e.scriptName}`);let t=s.join(e.projectPath,"package.json");if(!await l.pathExists(t))throw new Error(`package.json not found at ${t}`);let r=await l.readJSON(t),n=r.scripts&&typeof r.scripts=="object"&&!Array.isArray(r.scripts)?r.scripts:{},o=n[e.scriptName];typeof o=="string"&&o.trim().length>0||(r.scripts={...n,[e.scriptName]:e.scriptValue},await l.writeJSON(t,r,{spaces:2}));}async function Hr(e){let t=he(e.projectPath,e.operation.path);await l.pathExists(t)||(await l.ensureDir(s.dirname(t)),await l.writeFile(t,e.operation.content,"utf8"));}async function _r(e){let t=he(e.projectPath,e.operation.path);await l.ensureDir(s.dirname(t));let r=await kt(t),n=r.split(/\r?\n/),o=e.operation.lines.filter(i=>!n.includes(i));if(o.length===0)return;let a=r.length===0||r.endsWith(`
|
|
10
|
-
`)||!e.operation.ensureNewline?"":`
|
|
11
|
-
`;await l.appendFile(t,`${a}${o.join(`
|
|
12
|
-
`)}
|
|
13
|
-
`,"utf8");}async function Br(e){let t=he(e.projectPath,e.operation.sourcePath),r=he(e.projectPath,e.operation.path);if(!await l.pathExists(t))throw new Error(`Repair source file not found at ${t}`);await l.pathExists(r)||(await l.ensureDir(s.dirname(r)),await l.copy(t,r,{overwrite:e.operation.overwrite,errorOnExist:false}));}function qr(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")}async function Gr(e){let t=he(e.projectPath,e.operation.path);if(!await l.pathExists(t))throw new Error(`JSON repair target not found at ${t}`);let r=await l.readJSON(t);for(let n of e.operation.edits){let o=n.pointer.split("/").slice(1).map(qr);if(o.length===0||o.some(i=>i.length===0))throw new Error(`Unsupported JSON pointer: ${n.pointer}`);let a=r;for(let i of o.slice(0,-1)){let c=a[i];(!c||typeof c!="object"||Array.isArray(c))&&(a[i]={}),a=a[i];}a[o[o.length-1]]=n.value;}await l.writeJSON(t,r,{spaces:2});}async function Wr(e){let t=he(e.projectPath,e.operation.path);await l.ensureDir(s.dirname(t));let r=await kt(t),n=new Set(r.split(/\r?\n/).map(i=>i.trim().match(/^([A-Za-z_][A-Za-z0-9_]*)=/)?.[1]).filter(i=>!!i)),o=[];for(let i of e.operation.keys)n.has(i.name)||(i.comment&&o.push(`# ${i.comment}`),o.push(`${i.name}=${i.value}`));if(o.length===0)return;let a=r.length===0||r.endsWith(`
|
|
14
|
-
`)?"":`
|
|
15
|
-
`;await l.appendFile(t,`${a}${o.join(`
|
|
16
|
-
`)}
|
|
17
|
-
`,"utf8");}async function Kr(e){let t=he(e.projectPath,e.operation.path);await l.ensureDir(s.dirname(t));let r=await kt(t);if(new RegExp(`(^|\\n)${e.operation.target.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}:`,"m").test(r))return;let o=[...e.operation.phony?[`.PHONY: ${e.operation.target}`]:[],`${e.operation.target}:`,` ${e.operation.command}`],a=r.length===0||r.endsWith(`
|
|
18
|
-
`)?"":`
|
|
19
|
-
`;await l.appendFile(t,`${a}${o.join(`
|
|
20
|
-
`)}
|
|
21
|
-
`,"utf8");}async function kt(e){try{return await l.pathExists(e)?await l.readFile(e,"utf8"):""}catch{return ""}}async function Vr(e,t){let r=s.join(e,".workspai","cache","pypoetry");await l.ensureDir(r);let n={...process.env,POETRY_CACHE_DIR:r,POETRY_VIRTUALENVS_IN_PROJECT:"true"};await execa("poetry",["config","virtualenvs.in-project","true","--local"],{cwd:e,env:n,shell:c$2(),stdio:t?"pipe":"inherit"});let o=i$1(),a;for(let i of o)try{await execa("poetry",["env","use",i],{cwd:e,env:n,shell:c$2(),stdio:t?"pipe":"inherit"});return}catch(c){a=c;}if(a)throw a}function Jr(e,t){if(/^https?:\/\//i.test(t.trim()))return {projectName:e.name,projectPath:e.path,originalCommand:t,kind:"manual-url",risk:"safe",executable:false,reason:"Manual guidance URL"};if(Ge(t))return {projectName:e.name,projectPath:e.path,originalCommand:t,kind:"env-copy",risk:"safe",executable:true,reason:"Environment seed copy"};if(We(t))return {projectName:e.name,projectPath:e.path,originalCommand:t,kind:"package-json-script",risk:"guarded",executable:true,reason:"package.json lifecycle script repair"};let r=Pe(t);return r?.type==="file-create"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"file-create",risk:"safe",executable:true,reason:"Project-scoped file create repair"}:r?.type==="file-append"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"file-append",risk:"safe",executable:true,reason:"Project-scoped file append repair"}:r?.type==="file-copy"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"env-copy",risk:"safe",executable:true,reason:"Project-scoped file copy repair"}:r?.type==="json-edit"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"json-edit",risk:"guarded",executable:true,reason:"Project-scoped JSON document repair"}:r?.type==="env-key-add"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"env-key-add",risk:"guarded",executable:true,reason:"Project-scoped environment key repair"}:r?.type==="makefile-target"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"makefile-target",risk:"guarded",executable:true,reason:"Project-scoped Makefile target repair"}:ye(t,"rapidkit\\s+init")?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"rapidkit-init",risk:"guarded",executable:true,reason:"RapidKit initializer may mutate dependencies and configs"}:ye(t,"go\\s+mod\\s+tidy")?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"go-mod-tidy",risk:"guarded",executable:true,reason:"Go module graph reconciliation"}:yn(t)?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"dependency-sync",risk:"guarded",executable:true,reason:"Dependency synchronization command"}:{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"shell",risk:"invasive",executable:true,reason:"Generic shell command"}}function hn(e,t){return e.repairCapabilities?.find(r=>r.command===t)}function Lr(e,t){if(t)return e.probes?.find(r=>r.repairCapability?.id===t.id)}function Ur(e){let{step:t,capability:r,operation:n}=e;return n?.type==="file-create"?{title:r?.title??"Create file",summary:`Create ${s.basename(n.path)} if it does not already exist.`,changes:[`create ${n.path}`,"do not overwrite an existing file"]}:n?.type==="file-append"?{title:r?.title??"Append file rules",summary:`Append ${n.lines.length} missing line(s) to ${s.basename(n.path)}.`,changes:[`append to ${n.path}`,...n.lines.map(o=>`ensure line: ${o}`)]}:n?.type==="file-copy"?{title:r?.title??"Copy file",summary:`Copy ${s.basename(n.sourcePath)} to ${s.basename(n.path)} if the target is missing.`,changes:[`copy ${n.sourcePath} -> ${n.path}`,"do not overwrite an existing target file"]}:n?.type==="package-json-script"?{title:r?.title??"Update package.json script",summary:`Ensure package.json script "${n.scriptName}" exists.`,changes:[`set scripts.${n.scriptName}=${n.scriptValue}`]}:n?.type==="json-edit"?{title:r?.title??"Update JSON document",summary:`Apply ${n.edits.length} JSON pointer edit(s) to ${s.basename(n.path)}.`,changes:n.edits.map(o=>`set ${o.pointer}=${JSON.stringify(o.value)}`)}:n?.type==="env-key-add"?{title:r?.title??"Add environment keys",summary:`Ensure ${n.keys.length} environment key(s) exist in ${s.basename(n.path)}.`,changes:n.keys.map(o=>`ensure ${o.name}`)}:n?.type==="makefile-target"?{title:r?.title??"Add Makefile target",summary:`Ensure Makefile target "${n.target}" exists.`,changes:[`target ${n.target}`,`command ${n.command}`,...n.phony?["mark target as .PHONY"]:[]]}:t.kind==="env-copy"?{title:"Create .env from example",summary:"Copy .env.example to .env when the local env file is missing.",changes:["copy .env.example -> .env","do not overwrite existing .env"]}:t.kind==="manual-url"?{title:"Open manual guidance",summary:"Manual remediation is required outside Doctor.",changes:[t.originalCommand]}:{title:r?.title??"Run remediation command",summary:t.reason??"Run the planned remediation command.",changes:[t.originalCommand]}}function zr(e,t){let r=t.endsWith(`
|
|
22
|
-
`)?t.slice(0,-1).split(`
|
|
23
|
-
`):t.split(`
|
|
24
|
-
`);return ["--- /dev/null",`+++ ${e}`,"@@",...r.map(n=>`+${n}`)]}function Yr(e){let{step:t,operation:r}=e;if(!r)return {available:false,format:"none",summary:t.executable?"Command execution has no deterministic file diff preview.":"Guidance-only remediation has no file diff preview.",hunks:[]};if(r.type==="file-create")return {available:true,format:"unified",summary:`Create ${r.path} without overwriting an existing file.`,hunks:zr(r.path,r.content)};if(r.type==="file-append")return {available:true,format:"unified",summary:`Append ${r.lines.length} line(s) to ${r.path} when missing.`,hunks:[`--- ${r.path}`,`+++ ${r.path}`,"@@",...r.lines.map(n=>`+${n}`)]};if(r.type==="file-copy")return {available:true,format:"summary",summary:`Copy ${r.sourcePath} to ${r.path} when target is missing.`,hunks:[`copy ${r.sourcePath} -> ${r.path}`],limitations:["Source content is read during apply to avoid stale preview data."]};if(r.type==="package-json-script")return {available:true,format:"unified",summary:`Add scripts.${r.scriptName} to package.json when missing.`,hunks:[`--- ${r.path}`,`+++ ${r.path}`,"@@ scripts",`+ "${r.scriptName}": "${r.scriptValue}"`]};if(r.type==="json-edit")return {available:true,format:"summary",summary:`Apply ${r.edits.length} JSON pointer edit(s) to ${r.path}.`,hunks:r.edits.map(n=>`set ${n.pointer}=${JSON.stringify(n.value)}`)};if(r.type==="env-key-add")return {available:true,format:"unified",summary:`Add ${r.keys.length} env key(s) to ${r.path} when missing.`,hunks:[`--- ${r.path}`,`+++ ${r.path}`,"@@",...r.keys.flatMap(n=>[...n.comment?[`+# ${n.comment}`]:[],`+${n.name}=${n.value}`])]};if(r.type==="makefile-target"){let n=[...r.phony?[`.PHONY: ${r.target}`]:[],`${r.target}:`,` ${r.command}`];return {available:true,format:"unified",summary:`Add Makefile target "${r.target}" when missing.`,hunks:[`--- ${r.path}`,`+++ ${r.path}`,"@@",...n.map(o=>`+${o}`)]}}return {available:false,format:"none",summary:"No deterministic file diff preview is available for this remediation.",hunks:[]}}function Qr(e){return e.kind==="manual-url"?{available:false,strategy:"none"}:e.kind==="env-copy"||e.kind==="file-create"||e.kind==="file-append"?{available:true,strategy:"snapshot"}:e.risk==="guarded"||e.risk==="invasive"?{available:true,strategy:"snapshot"}:{available:true,strategy:"idempotent"}}function Xr(e){return e.executableInCurrentEnvironment?e.step.executable?e.policyProfile==="enterprise-strict"&&e.step.risk!=="safe"?{state:"review-required",reason:"Enterprise-strict policy requires review before guarded or invasive remediation."}:e.capability?.requiresReview?{state:"review-required",reason:"Repair capability requires human review before applying."}:{state:"ready",reason:"Remediation step is ready for approved execution."}:{state:"guidance-only",reason:e.step.reason??"This remediation is guidance-only."}:{state:"blocked",reason:e.blockedReason??"Required tool or environment is not available."}}function Zr(e){let{step:t,issueClass:r,repairIntent:n,operation:o}=e;return t.kind==="manual-url"||n?.mode==="manual-guidance"?"manual-review":t.kind==="dependency-sync"||t.kind==="go-mod-tidy"||r==="dependency"?"dependency-baseline":t.kind==="env-copy"||r==="environment"?"local-environment":t.kind==="package-json-script"||t.kind==="json-edit"||t.kind==="makefile-target"||o?.type==="file-append"&&(r==="test"||r==="quality"||r==="security")?"command-contract":t.kind==="env-key-add"?"local-environment":t.kind==="rapidkit-init"||r==="workspace-contract"?"runtime-governance":o?.type==="file-create"||o?.type==="file-append"?"source-hygiene":"generic-execution"}function nn(e){return {"dependency-baseline":10,"local-environment":20,"source-hygiene":30,"command-contract":40,"runtime-governance":50,"manual-review":80,"generic-execution":90}[e]}function ei(e){return [...e].sort((r,n)=>{let o=nn(r.phase)-nn(n.phase);if(o!==0)return o;let a=r.projectName.localeCompare(n.projectName);return a!==0?a:r.id.localeCompare(n.id)}).map((r,n)=>({...r,order:n+1}))}function ti(e){let t=new Map;for(let r of e){if(r.phase!=="dependency-baseline")continue;let n=t.get(r.projectPath)??[];n.push(r.id),t.set(r.projectPath,n);}return e.map(r=>{if(r.phase==="dependency-baseline")return r;let n=t.get(r.projectPath)??[];return n.length===0?r:{...r,dependsOn:[...new Set([...r.dependsOn,...n])]}})}function ni(e,t,r){if(r.kind==="dependency-sync"||r.kind==="go-mod-tidy")return `${e.path}:dependency-baseline`;let n=Pe(t);if(n?.type==="file-copy")return `${e.path}:file-copy:${n.path}`;if(n?.type==="file-create")return `${e.path}:file-create:${n.path}`;if(n?.type==="file-append")return `${e.path}:file-append:${n.path}`;if(n?.type==="package-json-script")return `${e.path}:package-json-script:${n.path}:${n.scriptName}`;if(n?.type==="json-edit")return `${e.path}:json-edit:${n.path}:${n.edits.map(i=>i.pointer).join(",")}`;if(n?.type==="env-key-add")return `${e.path}:env-key-add:${n.path}:${n.keys.map(i=>i.name).join(",")}`;if(n?.type==="makefile-target")return `${e.path}:makefile-target:${n.path}:${n.target}`;let o=Ge(t);if(o)return `${e.path}:file-copy:${s.join(o.projectPath,".env")}`;let a=We(t);return a?`${e.path}:package-json-script:${s.join(a.projectPath,"package.json")}:${a.scriptName}`:null}function ri(e,t){return hn(e,t)?4:Pe(t)?3:We(t)?2:Ge(t)?1:0}async function mt(e,t="local"){let r=e.filter(f=>f.fixCommands&&f.fixCommands.length>0),n=r.flatMap(f=>(f.fixCommands??[]).map(v=>({project:f,step:Jr(f,v),command:v}))),o=[],a=new Map;for(let f of n){let v=ni(f.project,f.command,f.step);if(!v){o.push(f);continue}let x=ri(f.project,f.command),k=a.get(v);if(!k){a.set(v,{index:o.length,priority:x}),o.push(f);continue}x>k.priority&&(o[k.index]=f,a.set(v,{index:k.index,priority:x}));}let i=o,c=null,d=[],u=0,h=0,y=0,w=0;for(let f of i){let{project:v,step:x,command:k}=f,R=x.executable,I;x.kind==="go-mod-tidy"&&(c===null&&(c=await gn()),c||(R=false,I="Go toolchain not available")),R&&(u+=1,x.risk==="safe"&&(h+=1),x.risk==="guarded"&&(y+=1),x.risk==="invasive"&&(w+=1));let T=hn(v,k),m=Lr(v,T),D=T?.operation??Pe(k)??void 0,C=T?.files??(D&&"path"in D?[D.path]:[]),ee=m?.repairIntent,j=Xr({step:x,capability:T,executableInCurrentEnvironment:R,blockedReason:I,policyProfile:t}),te=Zr({step:x,issueClass:m?.issueClass,repairIntent:ee,operation:D});d.push({...x,id:Or({projectName:v.name,kind:x.kind,command:k,operation:D}),phase:te,order:0,dependsOn:[],issueId:T?.issueId,issueClass:m?.issueClass,operationalImpact:m?.operationalImpact,repairIntent:ee,files:C,...D?{operation:D}:{},preview:Ur({step:x,capability:T,operation:D}),diffPreview:Yr({step:x,operation:D}),verifyCommand:T?.verifyCommand,refreshCommands:T?.refreshCommands??["npx workspai doctor project --json"],rollback:Qr(x),studioStatus:j,executableInCurrentEnvironment:R,blockedReason:I});}let g=ti(ei(d));return {schemaVersion:"doctor-remediation-plan-v2",generatedAt:new Date().toISOString(),policyProfile:t,fixableProjects:r.length,totalSteps:g.length,executableSteps:u,risk:{safe:h,guarded:y,invasive:w},steps:g}}function rn(e){let t=e instanceof Error?e.message:String(e),r=["ETIMEDOUT","ECONNRESET","ECONNREFUSED","EAI_AGAIN","ENOTFOUND","network","503","504"],n=t.toLowerCase();return r.some(o=>n.includes(o.toLowerCase()))}async function ii(e,t){let r=e.get(t);if(r)return r;let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,o=s.basename(t).replace(/[^a-zA-Z0-9._-]/g,"_"),a=s.join(t,".rapidkit","reports","fix-snapshots",`${o}-${n}`);await l.ensureDir(a);let i=[".env","package.json","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"],c=new Map;for(let u of i){let h=s.join(t,u);if(!await l.pathExists(h))continue;let y=s.join(a,u);await l.ensureDir(s.dirname(y)),await l.copy(h,y,{overwrite:true}),c.set(h,y);}let d={snapshotRoot:a,files:c,missingFiles:new Set};return e.set(t,d),d}async function we(e,t){if(e.files.has(t)||e.missingFiles.has(t))return;if(!await l.pathExists(t)){e.missingFiles.add(t);return}let r=s.basename(t),n=s.join(e.snapshotRoot,"ad-hoc",`${Date.now()}-${Math.random().toString(36).slice(2,8)}-${r}`);await l.ensureDir(s.dirname(n)),await l.copy(t,n,{overwrite:true}),e.files.set(t,n);}async function oi(e){for(let[t,r]of e.files.entries())await l.pathExists(r)&&(await l.ensureDir(s.dirname(t)),await l.copy(r,t,{overwrite:true}));for(let t of e.missingFiles)await l.pathExists(t)&&await l.remove(t);}async function ai(e){let t=await qe(e,{allowNonRapidkit:true});return {issues:t.issues.length,healthy:t.issues.length===0}}async function lt(e){let t=[];for(let r of e){let n=await qe(r.path,{allowNonRapidkit:true});for(let o of n.issues)typeof o=="string"&&o.trim()&&t.push(`${r.name}: ${o.trim()}`);}return t.slice(0,24)}function on(e){let t=[];for(let r of e)for(let n of r.issues)typeof n=="string"&&n.trim()&&t.push(`${r.name}: ${n.trim()}`);return t.slice(0,24)}async function le(e,t=false,r={}){let n=await mt(e,r.policyProfile);r.artifactRoot&&(r.planOnly||t)&&await ut(r.artifactRoot,n,r.artifactMirrorRoots);let o=e.filter(m=>m.fixCommands&&m.fixCommands.length>0),a=[],i=r.json===true,c$1=(...m)=>{i||console.log(...m);},d=null,u=n.steps.some(m=>m.kind==="go-mod-tidy"&&!m.executableInCurrentEnvironment),h=new Map;if(o.length===0){if(i||console.log(p.green(`
|
|
25
|
-
\u2705 No fixes needed - all projects are healthy!`)),t){let m=c({appliedFixes:[],remainingBlockers:[],verifyRecommended:b});return r.artifactRoot&&(await be(r.artifactRoot,m,r.artifactMirrorRoots),await je(r.artifactRoot,m,r.historyScope??"project")),m}return}if(!i){console.log(p.bold.cyan(`
|
|
26
|
-
\u{1F527} Available Fixes:
|
|
27
|
-
`));for(let m of o){let D=m.fixCommands??[];console.log(p.bold(`Project: ${p.yellow(m.name)}`)),D.forEach((C,ee)=>{console.log(` ${ee+1}. ${p.cyan(C)}`);}),console.log();}}if(r.planOnly){if(r.json){console.log(JSON.stringify(n,null,2));return}console.log(p.bold(`
|
|
28
|
-
\u{1F9ED} Remediation Plan
|
|
29
|
-
`)),console.log(p.gray(`Executable steps: ${n.executableSteps}/${n.totalSteps} | risk: safe=${n.risk.safe}, guarded=${n.risk.guarded}, invasive=${n.risk.invasive}`));for(let m of n.steps){let D=m.executableInCurrentEnvironment?p.green("ready"):p.yellow(`blocked${m.blockedReason?` (${m.blockedReason})`:""}`);console.log(` - ${p.cyan(m.projectName)} [${m.risk}] ${m.originalCommand} ${p.gray(`=> ${D}`)}`);}console.log(p.gray(`
|
|
30
|
-
Use --apply to execute this plan non-interactively, or --fix for interactive confirmation.`));return}let y=n.executableSteps,w=n.risk.safe,g=n.risk.guarded,f=n.risk.invasive;if(y===0){if(i||(console.log(p.gray("\u{1F4A1} No automatic fixes can be applied right now.")),u&&console.log(p.gray(" Install Go to enable go mod tidy fixes, then rerun `workspai doctor workspace --fix`."))),t){let m=c({appliedFixes:[],remainingBlockers:await lt(e),verifyRecommended:b});return r.artifactRoot&&(await be(r.artifactRoot,m,r.artifactMirrorRoots),await je(r.artifactRoot,m,r.historyScope??"project")),m}return}if(!t){i||console.log(p.gray('\u{1F4A1} Run "npx workspai doctor workspace --fix" to apply fixes automatically'));return}if(i||console.log(p.gray(`Risk policy: safe=${w}, guarded=${g}, invasive=${f}. Guarded/invasive fixes use snapshot + rollback.`)),!r.skipConfirmation){let{confirm:m}=await b$1([{type:"confirm",name:"confirm",message:`Apply ${o.reduce((D,C)=>D+(C.fixCommands?.length??0),0)} fix(es)?`,default:false}]);if(!m){i||console.log(p.yellow(`
|
|
31
|
-
\u26A0\uFE0F Fixes cancelled by user`));let D=c({appliedFixes:[],remainingBlockers:await lt(e),verifyRecommended:b});return r.artifactRoot&&(await be(r.artifactRoot,D,r.artifactMirrorRoots),await je(r.artifactRoot,D,r.historyScope??"project")),D}}i||console.log(p.bold.cyan(`
|
|
32
|
-
\u{1F680} Applying fixes...
|
|
33
|
-
`));let v=new Set,x=new Map(o.map(m=>[m.path,m])),k=new Set,R=Ar(),I=process.env.RAPIDKIT_DOCTOR_FIX_ALLOW_GUARDED_COMMANDS==="1"||process.env.RAPIDKIT_DOCTOR_FIX_ALLOW_DEPENDENCY_SYNC==="1",T="";for(let m of n.steps){if(!x.get(m.projectPath))continue;let C=m.originalCommand;i||T!==m.projectName&&(T=m.projectName,console.log(p.bold(`Fixing ${p.cyan(m.projectName)}...`)));let ee=`${m.projectPath}::${C}`;if(!v.has(ee)){v.add(ee);try{if(c$1(p.gray(` $ ${C}`)),m.kind==="manual-url"){c$1(p.yellow(` \u2139 Manual action required: open ${C}`)),c$1(p.green(` \u2705 Recorded as guidance
|
|
34
|
-
`));continue}if(!m.executable||!m.executableInCurrentEnvironment){let X=m.blockedReason?`: ${m.blockedReason}`:"";c$1(p.yellow(` \u26A0 Step is non-executable by policy${X}`)),c$1(p.green(` \u2705 Recorded as guidance
|
|
35
|
-
`));continue}let j=Pe(C),O=m.risk!=="safe"||j?.type==="file-create"||j?.type==="file-append"||j?.type==="file-copy"||j?.type==="json-edit"||j?.type==="env-key-add"||j?.type==="makefile-target"?await ii(h,m.projectPath):null;O&&j?.type==="file-create"&&await we(O,j.path),O&&j?.type==="file-append"&&await we(O,j.path),O&&j?.type==="file-copy"&&await we(O,j.path),O&&j?.type==="json-edit"&&await we(O,j.path),O&&j?.type==="env-key-add"&&await we(O,j.path),O&&j?.type==="makefile-target"&&await we(O,j.path);let ie=Ge(C);if(ie){let X=s.join(ie.projectPath,".env.example"),b=s.join(ie.projectPath,".env");if(!await l.pathExists(X))throw new Error(`.env.example not found at ${X}`);if(await l.pathExists(b)){c$1(p.green(` \u2705 .env already exists
|
|
36
|
-
`));continue}await l.copy(X,b,{overwrite:false,errorOnExist:false}),k.add(m.projectPath),a.push({path:b,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
37
|
-
`));continue}if(j?.type==="file-copy"){await Br({projectPath:m.projectPath,operation:j}),k.add(m.projectPath),a.push({path:j.path,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
38
|
-
`));continue}let Ne=We(C);if(Ne){await Tr(Ne),k.add(m.projectPath),a.push({path:m.projectPath,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
39
|
-
`));continue}if(j?.type==="file-create"){await Hr({projectPath:m.projectPath,operation:j}),k.add(m.projectPath),a.push({path:j.path,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
40
|
-
`));continue}if(j?.type==="file-append"){await _r({projectPath:m.projectPath,operation:j}),k.add(m.projectPath),a.push({path:j.path,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
41
|
-
`));continue}if(j?.type==="json-edit"){await Gr({projectPath:m.projectPath,operation:j}),k.add(m.projectPath),a.push({path:j.path,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
42
|
-
`));continue}if(j?.type==="env-key-add"){await Wr({projectPath:m.projectPath,operation:j}),k.add(m.projectPath),a.push({path:j.path,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
43
|
-
`));continue}if(j?.type==="makefile-target"){await Kr({projectPath:m.projectPath,operation:j}),k.add(m.projectPath),a.push({path:j.path,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
44
|
-
`));continue}let Ie=ye(C,"(?:npx\\s+workspai|rapidkit)\\s+init");if(Ie){if(!I){c$1(p.yellow(" \u26A0 workspai init is a guarded dependency/setup action; recording guidance instead of executing. Set RAPIDKIT_DOCTOR_FIX_ALLOW_GUARDED_COMMANDS=1 to opt in.")),a.push({path:m.projectPath,action:m.kind,outcome:"guidance",projectName:m.projectName,command:C,detail:"Guarded setup command was not auto-executed by doctor --fix. Run it explicitly after review."});continue}await execa("rapidkit",["init"],{cwd:Ie.projectPath,shell:c$2(),stdio:i?"pipe":"inherit",timeout:R,forceKillAfterDelay:1e3}),k.add(m.projectPath),a.push({path:m.projectPath,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
45
|
-
`));continue}let Ae=ye(C,"go\\s+mod\\s+tidy");if(Ae){if(d===null&&(d=await gn()),!d){c$1(p.yellow(" \u26A0 Go toolchain is not installed \u2014 skipping go mod tidy; install Go to apply this fix.")),c$1(p.green(` \u2705 Recorded as guidance
|
|
46
|
-
`));continue}await execa("go",["mod","tidy"],{cwd:Ae.projectPath,shell:c$2(),stdio:i?"pipe":"inherit",timeout:R,forceKillAfterDelay:1e3}),k.add(m.projectPath),a.push({path:m.projectPath,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
47
|
-
`));continue}let K=yn(C);if(K){if(!I&&new Set(["npm","pnpm","yarn","bun"]).has(K.command)){c$1(p.yellow(" \u26A0 dependency sync is a guarded install action; recording guidance instead of executing. Set RAPIDKIT_DOCTOR_FIX_ALLOW_GUARDED_COMMANDS=1 to opt in.")),a.push({path:m.projectPath,action:m.kind,outcome:"guidance",projectName:m.projectName,command:C,detail:"Guarded dependency command was not auto-executed by doctor --fix. Run it explicitly after review."});continue}let b=2,P,S=K.command==="poetry"&&K.args[0]==="install",H=S?{...process.env,POETRY_CACHE_DIR:s.join(K.projectPath,".rapidkit","cache","pypoetry"),POETRY_VIRTUALENVS_IN_PROJECT:"true"}:process.env;S&&await Vr(K.projectPath,i);for(let F=1;F<=b;F+=1)try{await execa(K.command,K.args,{cwd:K.projectPath,env:H,shell:c$2(),stdio:i?"pipe":"inherit",timeout:R,forceKillAfterDelay:1e3}),P=null;break}catch(A){if(P=A,F<b&&rn(A)){c$1(p.yellow(` \u26A0 Retrying dependency sync (${F}/${b-1})...`));continue}throw A}if(P)throw P;k.add(m.projectPath),a.push({path:m.projectPath,action:m.kind,outcome:"applied",projectName:m.projectName,command:C}),c$1(p.green(` \u2705 Success
|
|
48
|
-
`));continue}let Ce=m.kind==="shell"?2:1,de;for(let X=1;X<=Ce;X+=1)try{await execa(C,{shell:true,stdio:i?"pipe":"inherit",timeout:R,forceKillAfterDelay:1e3}),de=null;break}catch(b){if(de=b,X<Ce&&rn(b)){c$1(p.yellow(` \u26A0 Retrying command (${X}/${Ce-1})...`));continue}throw b}if(de)throw de;i||console.log(p.green(` \u2705 Success
|
|
49
|
-
`)),k.add(m.projectPath),a.push({path:m.projectPath,action:m.kind,outcome:"applied",projectName:m.projectName,command:C});}catch(j){let te=Pe(C);if(m.risk!=="safe"||te?.type==="file-create"||te?.type==="file-append"||te?.type==="file-copy"||te?.type==="json-edit"||te?.type==="env-key-add"||te?.type==="makefile-target"){let O=h.get(m.projectPath);if(O)try{await oi(O),i||console.log(p.yellow(" \u21A9 Rolled back snapshot after failed fix"));}catch(ie){i||console.log(p.red(` \u274C Rollback failed: ${ie instanceof Error?ie.message:String(ie)}`));}}i||console.log(p.red(` \u274C Failed: ${j instanceof Error?j.message:String(j)}
|
|
50
|
-
`)),a.push({path:m.projectPath,action:m.kind,outcome:"failed",projectName:m.projectName,command:C,detail:j instanceof Error?j.message:String(j)});}}}for(let m of o)if(k.has(m.path))try{let D=await ai(m.path);i||console.log(D.healthy?p.green(` \u2705 Post-fix verification passed for ${m.name}`):p.yellow(` \u26A0 Post-fix verification: ${D.issues} issue(s) remain for ${m.name}`));}catch(D){i||console.log(p.yellow(` \u26A0 Post-fix verification skipped: ${D instanceof Error?D.message:String(D)}`));}if(i||console.log(p.bold.green(`
|
|
51
|
-
\u2705 Fix process completed!`)),t){let m=c({appliedFixes:a,remainingBlockers:await lt(e),verifyRecommended:b});return r.artifactRoot&&(await be(r.artifactRoot,m,r.artifactMirrorRoots),await je(r.artifactRoot,m,r.historyScope??"project")),m}}function xe(e,t){let r=Be(t);if(r.name==="local")return 0;let n=Number(e?.errors??0),o=Number(e?.warnings??0);return r.exitOnErrors&&n>0?1:r.exitOnWarnings&&o>0?r.warningExitCode:0}async function Ji(e={}){let t=Be({profile:e.profile,strict:e.strict,ci:e.ci}),r=!!(e.fix||e.plan||e.apply),n=typeof e.workspace=="string"&&e.workspace.trim().length>0?s.resolve(e.workspace):null,o=!n&&!e.workspace&&!e.project&&r?await Fe(process.cwd()):null,a=!!e.workspace||!!o,i=!!e.project&&!a;if(e.json||console.log(p.bold.cyan(`
|
|
52
|
-
\u{1FA7A} Workspai Health Check
|
|
53
|
-
`)),a){let c$1=n??o??await Fe(process.cwd());c$1||(f.error("No Workspai workspace found in current directory or parents"),f.info('Run this command from within a workspace, or use "workspai doctor" for system check'),process.exit(1)),e.json||(o&&console.log(p.gray("\u2139\uFE0F Detected workspace context; enabling workspace checks for --fix")),console.log(p.bold(`Workspace: ${p.cyan(s.basename(c$1))}`)),console.log(p.gray(`Path: ${c$1}`)));let d=!(e.plan||e.fix||e.apply),u=await ct(c$1,d,t);if(e.json||(u.projectScanCached&&console.log(p.gray(`\u2139\uFE0F Reused cached project scan${u.projectScanCachePath?` (${s.basename(u.projectScanCachePath)})`:""}`)),u.evidencePath&&console.log(p.gray(`\u2139\uFE0F Evidence saved: ${u.evidencePath}`))),e.json){let g,f=e.plan||e.fix||e.apply?await mt(u.projects,t.name):void 0,v=f?await ut(c$1,f):void 0,x;(e.fix||e.apply)&&!e.plan&&(g=await le(u.projects,true,{skipConfirmation:e.apply===true||e.fix===true,json:true,policyProfile:t.name})??c({appliedFixes:[],remainingBlockers:[],verifyRecommended:b}),u=await ct(c$1,false,t),g={...g,remainingBlockers:on(u.projects)},x=await be(c$1,g),await je(c$1,g,"workspace"));let k={contract:ve(),policyProfile:t,workspace:{name:s.basename(c$1),path:c$1},cache:{projectScan:u.projectScanCached??false,projectScanPath:u.projectScanCachePath,evidencePath:u.evidencePath},healthScore:u.healthScore,evidenceFreshness:u.evidenceFreshness,system:{python:u.python,poetry:u.poetry,pipx:u.pipx,rapidkitCore:u.rapidkitCore,versions:{core:u.coreVersion,npm:u.npmVersion}},projects:u.projects.map(R=>Zt(R)),summary:{totalProjects:u.projects.length,totalIssues:u.projects.reduce((R,I)=>R+I.issues.length,0),projectAdvisoryWarningProjects:dt(u.projects),projectAdvisoryWarnings:ft(u.projects),hasSystemErrors:[u.python,u.rapidkitCore].some(R=>R.status==="error"),scopeProvenance:u.scopeProvenance},driftDelta:u.driftDelta,scoreBreakdown:u.scoreBreakdown??[],...f?{remediationPlan:f,remediationPlanPath:v}:{},...g?{appliedFixes:g.appliedFixes,remainingBlockers:g.remainingBlockers,verifyRecommended:g.verifyRecommended,fixResult:g,fixResultPath:x}:{}};return e.quiet||console.log(JSON.stringify(k,null,2)),xe(u.healthScore,{profile:t.name})}if(u.healthScore){let g=u.healthScore,f=Math.round(g.passed/g.total*100),v=f>=80?p.green:f>=50?p.yellow:p.red,x="\u2588".repeat(Math.floor(f/5))+"\u2591".repeat(20-Math.floor(f/5));console.log(p.bold(`
|
|
54
|
-
\u{1F4CA} Health Score:`)),console.log(` ${v(`${f}%`)} ${p.gray(x)}`),console.log(` ${p.green(`\u2705 ${g.passed} passed`)} ${p.gray("|")} ${p.yellow(`\u26A0\uFE0F ${g.warnings} warnings`)} ${p.gray("|")} ${p.red(`\u274C ${g.errors} errors`)}`);}console.log(p.bold(`
|
|
55
|
-
|
|
56
|
-
System Tools:
|
|
57
|
-
`)),G(u.python,"Python"),G(u.poetry,"Poetry"),G(u.pipx,"pipx"),G(u.go,"Go"),G(u.rapidkitCore,"RapidKit Core"),Qn({coreVersion:u.coreVersion,npmVersion:u.npmVersion})&&(console.log(p.yellow(`
|
|
58
|
-
\u26A0\uFE0F Version mismatch: Core ${u.coreVersion} / CLI ${u.npmVersion}`)),console.log(p.gray(" Consider updating to compatible major versions."))),u.projects.length>0?(console.log(p.bold(`
|
|
59
|
-
\u{1F4E6} Projects (${u.projects.length}):`)),u.projects.forEach(g=>tn(g))):(console.log(p.bold(`
|
|
60
|
-
\u{1F4E6} Projects:`)),console.log(p.gray(" No Workspai projects found in workspace")));let h=u.projects.reduce((g,f)=>g+f.issues.length,0),y=dt(u.projects),w=[u.python,u.rapidkitCore].some(g=>g.status==="error");if(w||h>0||y>0){let g=y>0?` and ${y} advisory warning project(s)`:"";if(console.log(p.bold.yellow(`
|
|
61
|
-
\u26A0\uFE0F Found ${h} project issue(s)${g}`)),w&&console.log(p.bold.red("\u274C System requirements not met")),e.plan)await le(u.projects,false,{planOnly:true,json:e.json,policyProfile:t.name,artifactRoot:c$1,historyScope:"workspace"});else if(e.fix||e.apply){if(await le(u.projects,true,{skipConfirmation:e.apply===true,policyProfile:t.name,artifactRoot:c$1,historyScope:"workspace"}),!e.json){let f=await ct(c$1,false,t),v=f.projects.reduce((k,R)=>k+R.issues.length,0),x=[f.python,f.rapidkitCore].some(k=>k.status==="error");x||v>0?(console.log(p.bold.yellow(`
|
|
62
|
-
\u26A0\uFE0F Post-fix verification found ${v} remaining issue(s)`)),x&&console.log(p.bold.red("\u274C System requirements still not met"))):console.log(p.bold.green(`
|
|
63
|
-
\u2705 Post-fix verification passed. Workspace is healthy.`)),f.projectScanCached&&console.log(p.gray(`\u2139\uFE0F Reused cached project scan${f.projectScanCachePath?` (${s.basename(f.projectScanCachePath)})`:""}`)),f.evidencePath&&console.log(p.gray(`\u2139\uFE0F Evidence refreshed: ${f.evidencePath}`));}}else h>0&&await le(u.projects,false);}else console.log(p.bold.green(`
|
|
64
|
-
\u2705 All checks passed! Workspace is healthy.`));return xe(u.healthScore,{profile:t.name})}else if(i){let c$1=await $r(process.cwd());if(!c$1){let k=await Fe(process.cwd());if(e.json){let R={contract:ve(),policyProfile:t,scope:"project",status:"error",generatedAt:new Date().toISOString(),workspace:k?{name:s.basename(k),path:k}:null,project:null,healthScore:{total:1,passed:0,warnings:0,errors:1},summary:{totalProjects:0,totalIssues:1,projectAdvisoryWarningProjects:0,projectAdvisoryWarnings:0,hasSystemErrors:false},error:{code:k?"doctor.project.scope.not_found_in_workspace":"doctor.project.scope.not_found",message:k?"No project found in the current directory within this workspace.":"No Workspai project found in the current directory or parents.",recommendation:k?"Run this command from inside a registered project directory, or use doctor workspace for workspace-wide checks.":"Run this command from within a project, or use doctor workspace from a Workspai workspace.",relatedCommands:k?["npx workspai doctor workspace --json","npx workspai workspace list --json"]:["npx workspai doctor workspace --json","npx workspai adopt --json"]}};return e.quiet||console.log(JSON.stringify(R,null,2)),1}k?(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 Workspai project found in current directory or parents"),f.info('Run this command from within a project, or use "workspai doctor workspace" for workspace checks'),process.exit(1);}let d=await en(c$1,t),u=d.workspacePath?Xt(d.workspacePath):null;if(e.json){let k,R=e.plan||e.fix||e.apply?await mt([d.project],t.name):void 0,I=u??c$1,T=u&&s.resolve(u)!==s.resolve(c$1)?[c$1]:[],m=R?await ut(I,R,T):void 0,D;(e.fix||e.apply)&&!e.plan&&(k=await le([d.project],true,{skipConfirmation:e.apply===true||e.fix===true,json:true,policyProfile:t.name})??c({appliedFixes:[],remainingBlockers:[],verifyRecommended:b}),d=await en(c$1,t),k={...k,remainingBlockers:on([d.project])},D=await be(I,k,T),await je(I,k,"project"));let C=Xt(d.project.path),ee={contract:ve(),policyProfile:t,scope:"project",workspace:u?{name:s.basename(u),path:u}:null,project:{...Zt(d.project),path:C},evidencePath:d.evidencePath,healthScore:d.healthScore,evidenceFreshness:d.evidenceFreshness,system:{python:d.python,poetry:d.poetry,pipx:d.pipx,go:d.go,rapidkitCore:d.rapidkitCore},summary:{totalProjects:1,totalIssues:d.project.issues.length,projectAdvisoryWarningProjects:ge(d.project)>0?1:0,projectAdvisoryWarnings:ge(d.project),hasSystemErrors:[d.python,d.rapidkitCore].some(j=>j.status==="error"),scopeProvenance:d.scopeProvenance},driftDelta:d.driftDelta,scoreBreakdown:d.scoreBreakdown??[],...R?{remediationPlan:R,remediationPlanPath:m}:{},...k?{appliedFixes:k.appliedFixes,remainingBlockers:k.remainingBlockers,verifyRecommended:k.verifyRecommended,fixResult:k,fixResultPath:D}:{}};return e.quiet||console.log(JSON.stringify(ee,null,2)),xe(d.healthScore,{profile:t.name})}console.log(p.bold(`Project: ${p.cyan(s.basename(c$1))}`)),console.log(p.gray(`Path: ${c$1}`)),d.workspacePath&&console.log(p.gray(`Workspace: ${s.basename(d.workspacePath)}`)),d.evidencePath&&console.log(p.gray(`\u2139\uFE0F Evidence saved: ${d.evidencePath}`));let h=d.healthScore,y=h.total>0?Math.round(h.passed/h.total*100):0,w=y>=80?p.green:y>=50?p.yellow:p.red,g="\u2588".repeat(Math.floor(y/5))+"\u2591".repeat(20-Math.floor(y/5));console.log(p.bold(`
|
|
65
|
-
\u{1F4CA} Health Score:`)),console.log(` ${w(`${y}%`)} ${p.gray(g)}`),console.log(` ${p.green(`\u2705 ${h.passed} passed`)} ${p.gray("|")} ${p.yellow(`\u26A0\uFE0F ${h.warnings} warnings`)} ${p.gray("|")} ${p.red(`\u274C ${h.errors} errors`)}`),console.log(p.bold(`
|
|
66
|
-
|
|
67
|
-
System Tools:
|
|
68
|
-
`)),G(d.python,"Python"),G(d.poetry,"Poetry"),G(d.pipx,"pipx"),G(d.go,"Go"),G(d.rapidkitCore,"RapidKit Core"),console.log(p.bold(`
|
|
69
|
-
\u{1F4E6} Project (1):`)),tn(d.project);let f$1=[d.python,d.rapidkitCore].some(k=>k.status==="error"),v=d.project.issues.length,x=ge(d.project);if(f$1||v>0||x>0){let k=x>0?` and ${x} advisory warning(s)`:"";if(console.log(p.bold.yellow(`
|
|
70
|
-
\u26A0\uFE0F Found ${v} project issue(s)${k}`)),f$1&&console.log(p.bold.red("\u274C System requirements not met")),e.plan){let R=d.workspacePath??c$1,I=d.workspacePath&&s.resolve(d.workspacePath)!==s.resolve(c$1)?[c$1]:[];await le([d.project],false,{planOnly:true,json:e.json,policyProfile:t.name,artifactRoot:R,artifactMirrorRoots:I,historyScope:"project"});}else if(e.fix||e.apply){let R=d.workspacePath??c$1,I=d.workspacePath&&s.resolve(d.workspacePath)!==s.resolve(c$1)?[c$1]:[];await le([d.project],true,{skipConfirmation:e.apply===true,policyProfile:t.name,artifactRoot:R,artifactMirrorRoots:I,historyScope:"project"});}else v>0&&await le([d.project],false);}else console.log(p.bold.green(`
|
|
71
|
-
\u2705 All checks passed! Project is healthy.`));return xe(d.healthScore,{profile:t.name})}else {let c=await yt(),d=c.python,u=c.poetry,h=c.pipx,y=c.go,w=c.rapidkitCore,g=[d,u,h,y,w],f=ht(g,[]),v=[d,w].filter(k=>k.status==="error").length;if(e.json){let k={contract:ve(),policyProfile:t,scope:"system",status:v>0?"error":"ok",generatedAt:new Date().toISOString(),healthScore:f,system:{python:d,poetry:u,pipx:h,go:y,rapidkitCore:w},summary:{totalChecks:g.length,errors:v,warnings:g.filter(R=>R.status==="warn").length,recommendedScopes:["workspace","project"]},nextActions:["npx workspai doctor workspace --json","npx workspai doctor project --json"]};return e.quiet||console.log(JSON.stringify(k,null,2)),(e.strict||e.ci)&&v>0?1:0}return console.log(p.bold(`System Tools:
|
|
72
|
-
`)),G(d,"Python"),G(u,"Poetry"),G(h,"pipx"),G(y,"Go"),G(w,"RapidKit Core"),[d,w].some(k=>k.status==="error")?(console.log(p.bold.red(`
|
|
73
|
-
\u274C Some required tools are missing`)),(e.fix||e.apply)&&console.log(p.gray(`
|
|
74
|
-
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "workspai doctor workspace --fix"`)),console.log(p.gray(`
|
|
75
|
-
Tip: Run "workspai doctor workspace" for workspace-wide checks, or "workspai doctor project" for the current project`))):(console.log(p.bold.green(`
|
|
76
|
-
\u2705 All required tools are installed!`)),(e.fix||e.apply)&&console.log(p.gray(`
|
|
77
|
-
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "workspai doctor workspace --fix"`)),console.log(p.gray(`
|
|
78
|
-
Tip: Run "workspai doctor workspace" for workspace-wide checks, or "workspai doctor project" for the current project`))),console.log(""),(e.strict||e.ci)&&v>0?1:0}}export{Be as a,xe as b,Ji as c};
|