workspai 0.53.0 → 0.54.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/contracts/artifact-remediation-plan.v1.json +22 -3
- package/contracts/doctor-project-evidence.v1.json +21 -2
- package/contracts/doctor-remediation-plan.v1.json +22 -3
- package/contracts/doctor-workspace-evidence.v1.json +21 -2
- package/contracts/extension-cli-compatibility.v1.json +1 -1
- package/contracts/workspace-intelligence/doctor-dependency-repair-transaction.v1.json +52 -13
- package/contracts/workspace-intelligence/workspace-repair-transaction.v1.json +56 -6
- package/contracts/workspace-repair-capabilities.v1.json +48 -0
- package/dist/{artifact-remediation-plan-CJSPCMWA.js → artifact-remediation-plan-A2PRCUNA.js} +1 -1
- package/dist/autopilot-release-63XHNGR6.js +1 -0
- package/dist/{chunk-T6JI7GYZ.js → chunk-4HTSZGEU.js} +50 -50
- package/dist/{chunk-HOVJUP7K.js → chunk-BPACED27.js} +1 -1
- package/dist/{chunk-E5YYVFM2.js → chunk-I5CGTCP5.js} +1 -1
- package/dist/chunk-IQQWQ3II.js +3 -0
- package/dist/chunk-UFOCUHG3.js +1 -0
- package/dist/{chunk-27AXFTKW.js → chunk-ZLYEYHMH.js} +1 -1
- package/dist/{doctor-KNIYGDM7.js → doctor-HJ3O7SAO.js} +1 -1
- package/dist/index.js +7 -7
- package/dist/{pipeline-PVCLAQDI.js → pipeline-TDQK5QYQ.js} +1 -1
- package/dist/{verified-goal-MCSNMA3P.js → verified-goal-S2PEBJUV.js} +1 -1
- package/dist/{workspace-intelligence-runner-JNCQLUH7.js → workspace-intelligence-runner-EQFLRVRL.js} +1 -1
- package/dist/workspace-repair-engine-OZXOXVVV.js +3 -0
- package/dist/workspace-run-VPXRRHDK.js +1 -0
- package/docs/doctor-command.md +6 -0
- package/docs/workspace-repair-engine.md +17 -8
- package/package.json +1 -1
- package/dist/autopilot-release-LZWNQQLY.js +0 -1
- package/dist/chunk-SUV7Y2FH.js +0 -3
- package/dist/chunk-ZTKIBREF.js +0 -1
- package/dist/workspace-repair-engine-SRWECKZO.js +0 -3
- package/dist/workspace-run-3U77TMKX.js +0 -1
- /package/dist/{chunk-USMLRNZ7.js → chunk-3LVJBH7V.js} +0 -0
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
import {
|
|
2
|
-
`),St=[".env",".env.*","!.env.example"];function Ce(e){return e&&(e==="python"||e==="node"||e==="go"||e==="java"||e==="rust"||e==="elixir"||e==="clojure"||e==="deno"||e==="bun"||e==="php"||e==="ruby"||e==="dotnet"||e==="scala"||e==="kotlin"||e==="c"||e==="cpp")?e:"unknown"}async function xe(e,t){for(let i of t){if(i.includes("*")){let n=i.replace("*","");if(await
|
|
3
|
-
`)}var Ri=new Set([".c",".cc",".clj",".cljs",".cpp",".cs",".ex",".exs",".go",".h",".hpp",".java",".js",".jsx",".kt",".kts",".mjs",".cjs",".php",".py",".rb",".rs",".scala",".svelte",".ts",".tsx",".vue"]),Si=[/\bprocess\.env(?:\.([A-Z][A-Z0-9_]*)|\[['"]([A-Z][A-Z0-9_]*)['"]\])/g,/\bimport\.meta\.env\.([A-Z][A-Z0-9_]*)/g,/\b(?:Deno\.env\.get|os\.getenv|os\.Getenv|os\.LookupEnv|System\.getenv|std::env::var|env!|option_env!|getenv|Environment\.GetEnvironmentVariable)\(\s*['"]([A-Z][A-Z0-9_]*)['"]/g,/\bos\.environ(?:\.get\(\s*['"]([A-Z][A-Z0-9_]*)['"]|\[\s*['"]([A-Z][A-Z0-9_]*)['"]\s*\])/g,/\bENV(?:\.fetch\(\s*['"]([A-Z][A-Z0-9_]*)['"]|\[\s*['"]([A-Z][A-Z0-9_]*)['"]\s*\])/g,/\$_ENV\[\s*['"]([A-Z][A-Z0-9_]*)['"]\s*\]/g,/@Value\(\s*['"]\$\{([A-Z][A-Z0-9_]*)(?::[^}]*)?\}['"]\s*\)/g];async function Ei(e){let t=new Set,i=new Set([".git",".next",".nuxt",".output",".rapidkit",".svelte-kit",".venv",".workspai","build","coverage","dist","node_modules","target","vendor"]),n=[{dir:e,depth:0}],o=0;for(;n.length>0&&o<300;){let a=n.shift();if(!a)break;let r=[];try{r=await u.readdir(a.dir,{withFileTypes:true});}catch{continue}for(let c of r){if(i.has(c.name))continue;let l=d.join(a.dir,c.name);if(c.isDirectory()){a.depth<6&&!c.name.startsWith(".")&&n.push({dir:l,depth:a.depth+1});continue}if(!c.isFile()||!Ri.has(d.extname(c.name).toLowerCase()))continue;o+=1;let p="";try{if((await u.stat(l)).size>512*1024)continue;p=await u.readFile(l,"utf8");}catch{continue}for(let g of Si){g.lastIndex=0;for(let v of p.matchAll(g)){let j=v.slice(1).find(k=>typeof k=="string"&&k.length>0);j&&t.add(j);}}}}let s=await _e(d.join(e,".env"));for(let a of s.split(/\r?\n/)){let r=a.match(/^\s*(?:export\s+)?([A-Z][A-Z0-9_]*)\s*=/);r?.[1]&&t.add(r[1]);}return [...t].sort((a,r)=>a.localeCompare(r))}async function Ai(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 u.pathExists(d.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==="java"){let t=await u.pathExists(d.join(e.projectPath,"pom.xml")),i=await u.pathExists(d.join(e.projectPath,"mvnw"))||await u.pathExists(d.join(e.projectPath,"mvnw.cmd")),n=await u.pathExists(d.join(e.projectPath,"gradlew"))||await u.pathExists(d.join(e.projectPath,"gradlew.bat"));return {command:t?i?process.platform==="win32"?".\\mvnw.cmd -B -DskipTests dependency:go-offline":"./mvnw -B -DskipTests dependency:go-offline":"mvn -B -DskipTests dependency:go-offline":n?process.platform==="win32"?".\\gradlew.bat dependencies":"./gradlew dependencies":"gradle dependencies",title:"Prepare Java dependency baseline",files:["pom.xml","build.gradle","build.gradle.kts","gradle.lockfile"],limitations:["Review resolved dependency and lockfile changes before committing."]}}if(e.runtime==="scala")return {command:"sbt update",title:"Prepare Scala dependency baseline",files:["build.sbt","project/build.properties","project/plugins.sbt"],limitations:["Review resolved dependency and plugin changes before committing."]};if(e.runtime==="kotlin")return {command:process.platform==="win32"?".\\gradlew.bat dependencies":"./gradlew dependencies",title:"Prepare Kotlin dependency baseline",files:["build.gradle","build.gradle.kts","gradle.lockfile"],limitations:["Review resolved dependency and lockfile 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 _e(d.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 Ge(e){let t=e?.scripts;if(!t||typeof t!="object"||Array.isArray(t))return {};let i={};for(let[n,o]of Object.entries(t))typeof o=="string"&&o.trim().length>0&&(i[n]=o);return i}function $i(e){if(e.runtime==="node"){let i=Ge(e.packageJsonData);if(!e.packageJsonData)return null;if(e.kind==="test"){let n=i.lint?"npm run lint":i.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 {deno:{test:{command:"deno test --allow-none",title:"Define Deno test command",targetName:"test",files:["Makefile","deno.json","deno.jsonc"]},quality:{command:"deno fmt --check && deno lint",title:"Define Deno quality command",targetName:"quality",files:["Makefile","deno.json","deno.jsonc"]},security:{command:"deno info --json",title:"Define Deno dependency inspection command",targetName:"security",files:["Makefile","deno.json","deno.jsonc","deno.lock"],limitations:["Pair dependency inspection with the organization vulnerability service used by CI."]}},bun:{test:{command:"bun test",title:"Define Bun test script",targetName:"test",files:["package.json","bun.lock","bun.lockb"]},quality:{command:"bunx eslint .",title:"Define Bun quality script",targetName:"quality",files:["package.json"],limitations:["Ensure ESLint is declared before enforcing this command in CI."]},security:{command:"bun audit",title:"Define Bun security audit script",targetName:"audit",files:["package.json","bun.lock","bun.lockb"]}},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."]}},elixir:{test:{command:"mix test",title:"Define Elixir test command",targetName:"test",files:["Makefile","mix.exs"]},quality:{command:"mix format --check-formatted && mix credo --strict",title:"Define Elixir quality command",targetName:"quality",files:["Makefile","mix.exs",".formatter.exs","credo.exs"],limitations:["Ensure Credo is declared before enforcing the strict quality command."]},security:{command:"mix hex.audit",title:"Define Hex dependency audit command",targetName:"security",files:["Makefile","mix.exs","mix.lock"]}},clojure:{test:{command:"clojure -M:test",title:"Define Clojure test command",targetName:"test",files:["Makefile","deps.edn","project.clj"],limitations:["Align the alias with the test runner declared by the project."]},quality:{command:"clj-kondo --lint src test",title:"Define Clojure quality command",targetName:"quality",files:["Makefile","deps.edn","project.clj"],limitations:["Ensure clj-kondo is provisioned before enforcing this command in CI."]},security:{command:"clojure -Stree",title:"Define Clojure dependency inspection command",targetName:"security",files:["Makefile","deps.edn","project.clj"],limitations:["Pair dependency-tree inspection with the vulnerability scanner selected by the organization."]}},scala:{test:{command:"sbt test",title:"Define Scala test command",targetName:"test",files:["Makefile","build.sbt"]},quality:{command:"sbt scalafmtCheckAll scalafixAll",title:"Define Scala quality command",targetName:"quality",files:["Makefile","build.sbt",".scalafmt.conf"],limitations:["Declare Scalafmt and Scalafix plugins before enforcing this command."]},security:{command:"sbt dependencyTree",title:"Define Scala dependency inspection command",targetName:"security",files:["Makefile","build.sbt"],limitations:["Pair dependency inspection with the organization vulnerability scanner."]}},kotlin:{test:{command:"./gradlew test",title:"Define Kotlin test command",targetName:"test",files:["Makefile","build.gradle","build.gradle.kts"]},quality:{command:"./gradlew check",title:"Define Kotlin quality command",targetName:"quality",files:["Makefile","build.gradle","build.gradle.kts"]},security:{command:"./gradlew dependencies",title:"Define Kotlin dependency inspection command",targetName:"security",files:["Makefile","build.gradle","build.gradle.kts"],limitations:["Pair dependency inspection with the organization vulnerability scanner."]}},c:{test:{command:"ctest --test-dir build --output-on-failure",title:"Define C test command",targetName:"test",files:["Makefile","CMakeLists.txt"]},quality:{command:"clang-tidy src/**/*.c --",title:"Define C quality command",targetName:"quality",files:["Makefile","CMakeLists.txt",".clang-tidy"],limitations:["Align source globs and compile database with the project build."]},security:{command:"cmake --build build --target sbom",title:"Define C dependency evidence command",targetName:"security",files:["Makefile","CMakeLists.txt"],limitations:["Declare the SBOM target or replace it with the organization scanner."]}},cpp:{test:{command:"ctest --test-dir build --output-on-failure",title:"Define C++ test command",targetName:"test",files:["Makefile","CMakeLists.txt"]},quality:{command:"clang-tidy src/**/*.cpp --",title:"Define C++ quality command",targetName:"quality",files:["Makefile","CMakeLists.txt",".clang-tidy"],limitations:["Align source globs and compile database with the project build."]},security:{command:"cmake --build build --target sbom",title:"Define C++ dependency evidence command",targetName:"security",files:["Makefile","CMakeLists.txt"],limitations:["Declare the SBOM target or replace it with the organization scanner."]}}}[e.runtime]?.[e.kind]??null}async function Fi(e){return h({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 Et(e){let t=$i({runtime:e.runtime,kind:e.kind,packageJsonData:e.packageJsonData});if(t)return (e.runtime==="node"||e.runtime==="bun")&&e.packageJsonData?g$1({issueId:e.issueId,title:t.title,projectPath:e.projectPath,scriptName:t.targetName,scriptValue:t.command,reason:e.reason,risk:"guarded",limitations:t.limitations}):Fi({issueId:e.issueId,projectPath:e.projectPath,contract:t,reason:e.reason})}function Pe(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=>d.join(e.projectPath,t)),refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function Ni(e){return b$8({issueId:"surface-dockerignore",title:"Create .dockerignore",projectPath:e,relativePath:".dockerignore",content:`${Pi}
|
|
4
|
-
`,reason:"Create a Docker build ignore baseline to keep secrets, dependencies, and reports out of container contexts."})}async function
|
|
1
|
+
import {b as b$7,g as g$1,f as f$3,j as j$4,e as e$3,c as c$4,d as d$7,h,i}from'./chunk-UFOCUHG3.js';import {c,b,d as d$3}from'./chunk-KFKZOPZC.js';import {f as f$1,e as e$2}from'./chunk-T3GJ7YVG.js';import {b as b$2}from'./chunk-MRFN5ZQP.js';import {b as b$1}from'./chunk-KVSYBHUR.js';import {c as c$3,a as a$5,d as d$4,b as b$5}from'./chunk-QZ7PNMVP.js';import {j,g}from'./chunk-GDU7VP6G.js';import {d as d$6}from'./chunk-PS5F4DCT.js';import {b as b$4,c as c$2}from'./chunk-7KKP7RNB.js';import {b as b$3}from'./chunk-7AR5PDLD.js';import {a as a$3}from'./chunk-27UR373Z.js';import {a as a$1}from'./chunk-Y5YAP4F3.js';import {a as a$2}from'./chunk-MQ73VS4E.js';import {w}from'./chunk-6HJJHEL6.js';import {j as j$3,d as d$5,b as b$8,a as a$9}from'./chunk-2PY65U6X.js';import {a as a$8}from'./chunk-GR6442P7.js';import {d as d$1,e as e$1,f as f$2}from'./chunk-WIO6L24E.js';import {a as a$4}from'./chunk-AFIFZTOY.js';import {a,d as d$2,e}from'./chunk-44VJHNZB.js';import {f}from'./chunk-VRW6KXNK.js';import {a as a$7}from'./chunk-TQEMLBAG.js';import {s,j as j$1,t}from'./chunk-MOSXTVPU.js';import {c as c$1,j as j$2,b as b$6,t as t$1,n,p,m as m$1}from'./chunk-RJIYCDVC.js';import {a as a$6}from'./chunk-2FIX2MDC.js';import m from'chalk';import {createHash}from'crypto';import {execa}from'execa';import u from'fs-extra';import d from'path';import {existsSync}from'fs';var yi=[".eslintrc.js",".eslintrc.cjs",".eslintrc.json",".eslintrc.yaml",".eslintrc.yml","eslint.config.js","eslint.config.mjs","eslint.config.cjs"],hi=["tests","test","src/test","__tests__","e2e","playwright","cypress"],ki=["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"],vi=["src","app","pages"],bi=["dev","build","test","lint"];function Cn(e){let t=e?.scripts;if(!t||typeof t!="object"||Array.isArray(t))return {};let i={};for(let[n,o]of Object.entries(t))typeof o=="string"&&o.trim().length>0&&(i[n]=o);return i}async function Pn(e,t){for(let o of yi)if(await u.pathExists(d.join(e,o)))return true;let i=t??(await u.pathExists(d.join(e,"package.json"))?await u.readJson(d.join(e,"package.json")):null);if(!i)return false;if(i.eslintConfig)return true;let n={...i.dependencies??{},...i.devDependencies??{}};return !!(n.eslint||n["@eslint/js"]||n["@eslint/eslintrc"])}async function Dn(e,t){for(let o of hi)if(await u.pathExists(d.join(e,o)))return true;for(let o of ki)if(await u.pathExists(d.join(e,o)))return true;let i=Cn(t);if(i.test||i["test:unit"]||i["test:e2e"]||i["test:ci"]||i["test:watch"])return true;let n={...t?.dependencies??{},...t?.devDependencies??{}};return n.vitest||n.jest||n["@playwright/test"]||n.cypress?true:await wi(e)}async function wi(e){let t=["src","app","pages","components"],i=/\.(test|spec)\.(tsx?|jsx?|vue|svelte)$/i,o=new Set(["node_modules",".git","dist","build",".next","coverage",".turbo"]);for(let s of t){let a=d.join(e,s);if(!await u.pathExists(a))continue;let r=[{dir:a,depth:0}];for(;r.length>0;){let c=r.shift();if(!c)break;let l=[];try{l=await u.readdir(c.dir);}catch{continue}for(let p of l){let y=d.join(c.dir,p);if(i.test(p))return true;if(!(c.depth>=3||o.has(p)||p.startsWith(".")))try{(await u.stat(y)).isDirectory()&&r.push({dir:y,depth:c.depth+1});}catch{continue}}}}return false}async function Rt(e){for(let t of vi){let i=d.join(e,t);if(await u.pathExists(i))try{if((await u.readdir(i)).some(o=>!o.startsWith(".")))return true}catch{continue}}return false}function ji(e){let t=e.key;return b$8(t).key}function xi(e,t,i){return a$9(t,i).some(o=>!!e[o])}async function Rn(e){let{projectPath:t,detection:i,packageJsonData:n}=e,o=ji(i),s=b$8(o),a=Cn(n),r=[],c=await u.pathExists(d.join(t,"package-lock.json"))||await u.pathExists(d.join(t,"pnpm-lock.yaml"))||await u.pathExists(d.join(t,"yarn.lock"))||await u.pathExists(d.join(t,"bun.lockb"));r.push({id:"frontend-lockfile-integrity",label:"Frontend lockfile integrity",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Node lockfile detected for deterministic dependency restore.":"No Node lockfile detected (package-lock/yarn.lock/pnpm-lock.yaml/bun.lockb).",recommendation:c?void 0:"Commit a lockfile for deterministic installs and CI parity."});let l=await u.pathExists(d.join(t,"tsconfig.json")),p=await u.pathExists(d.join(t,"jsconfig.json")),y=l||p;r.push({id:"frontend-typescript-surface",label:"TypeScript project surface",status:y?"pass":"warn",severity:"warn",scope:"project-scoped",reason:y?l?"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 v=s.fileHints.length>0&&s.fileHints.some(k=>existsSync(d.join(t,k)));r.push({id:"frontend-framework-config",label:`${s.displayName} config surface`,status:v?"pass":"warn",severity:"warn",scope:"project-scoped",reason:v?`${s.displayName} configuration artifacts detected.`:`No ${s.displayName} config markers detected (${s.fileHints.join(", ")||"n/a"}).`,recommendation:v?void 0:"Keep framework config files in-repo for reproducible dev/build behavior."});for(let k of bi){let g=xi(a,o,k),h=k==="dev"||k==="build",w=!g&&k==="test"?g$1({projectPath:t,frameworkDisplayName:s.displayName,scriptName:k,scriptValue:f$3(a)}):void 0;r.push({id:`frontend-script-${k}`,label:`${k} script surface`,status:g?"pass":h?"fail":"warn",severity:h?"error":"warn",scope:"project-scoped",reason:g?`package.json exposes a ${k} script for ${s.displayName}.`:`No ${k} script detected for ${s.displayName}.`,recommendation:g?void 0:`Add a "${a$9(o,k)[0]??k}" script to package.json.`,repairCapability:w});}let j=await Rt(t);return r.push({id:"frontend-source-tree",label:"Frontend source tree",status:j?"pass":"warn",severity:"warn",scope:"project-scoped",reason:j?"Application source directories detected (src/app/pages).":"No frontend source directories detected under src/, app/, or pages/.",recommendation:j?void 0:"Ensure the scaffolded application tree exists before running lifecycle commands."}),r}var Ci={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:["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"],scala:["project/build.properties","project/plugins.sbt"],kotlin:["gradle.lockfile","gradle/libs.versions.toml"],c:["conan.lock","vcpkg-lock.json"],cpp:["conan.lock","vcpkg-lock.json"],unknown:[]},Pi={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"],scala:["build.sbt"],kotlin:["build.gradle","build.gradle.kts","pom.xml"],c:["CMakeLists.txt","meson.build","Makefile"],cpp:["CMakeLists.txt","meson.build","Makefile"],unknown:[]},Di=["node_modules",".git",".workspai/reports",".venv","dist","build","coverage",".env",".env.*","!.env.example"].join(`
|
|
2
|
+
`),St=[".env",".env.*","!.env.example"];function Ce(e){return e&&(e==="python"||e==="node"||e==="go"||e==="java"||e==="rust"||e==="elixir"||e==="clojure"||e==="deno"||e==="bun"||e==="php"||e==="ruby"||e==="dotnet"||e==="scala"||e==="kotlin"||e==="c"||e==="cpp")?e:"unknown"}async function xe(e,t){for(let i of t){if(i.includes("*")){let n=i.replace("*","");if(await Ri(e,n,2))return true;continue}if(await u.pathExists(d.join(e,i)))return true}return false}async function Ri(e,t,i){let n=[{dir:e,depth:0}],o=new Set(["node_modules",".git",".workspai",".rapidkit","dist","build","coverage"]);for(;n.length>0;){let s=n.shift();if(!s)break;let a=[];try{a=await u.readdir(s.dir,{withFileTypes:true});}catch{continue}for(let r of a){if(o.has(r.name))continue;let c=d.join(s.dir,r.name);if(r.isFile()&&r.name.endsWith(t))return true;r.isDirectory()&&s.depth<i&&!r.name.startsWith(".")&&n.push({dir:c,depth:s.depth+1});}}return false}async function _e(e){try{return await u.pathExists(e)?await u.readFile(e,"utf8"):""}catch{return ""}}async function at(e,t){let i=[];for(let n of t){let o=await _e(d.join(e,n));o&&i.push(o);}return i.join(`
|
|
3
|
+
`)}var Si=new Set([".c",".cc",".clj",".cljs",".cpp",".cs",".ex",".exs",".go",".h",".hpp",".java",".js",".jsx",".kt",".kts",".mjs",".cjs",".php",".py",".rb",".rs",".scala",".svelte",".ts",".tsx",".vue"]),Ei=[/\bprocess\.env(?:\.([A-Z][A-Z0-9_]*)|\[['"]([A-Z][A-Z0-9_]*)['"]\])/g,/\bimport\.meta\.env\.([A-Z][A-Z0-9_]*)/g,/\b(?:Deno\.env\.get|os\.getenv|os\.Getenv|os\.LookupEnv|System\.getenv|std::env::var|env!|option_env!|getenv|Environment\.GetEnvironmentVariable)\(\s*['"]([A-Z][A-Z0-9_]*)['"]/g,/\bos\.environ(?:\.get\(\s*['"]([A-Z][A-Z0-9_]*)['"]|\[\s*['"]([A-Z][A-Z0-9_]*)['"]\s*\])/g,/\bENV(?:\.fetch\(\s*['"]([A-Z][A-Z0-9_]*)['"]|\[\s*['"]([A-Z][A-Z0-9_]*)['"]\s*\])/g,/\$_ENV\[\s*['"]([A-Z][A-Z0-9_]*)['"]\s*\]/g,/@Value\(\s*['"]\$\{([A-Z][A-Z0-9_]*)(?::[^}]*)?\}['"]\s*\)/g];async function Ai(e){let t=new Set,i=new Set([".git",".next",".nuxt",".output",".rapidkit",".svelte-kit",".venv",".workspai","build","coverage","dist","node_modules","target","vendor"]),n=[{dir:e,depth:0}],o=0;for(;n.length>0&&o<300;){let a=n.shift();if(!a)break;let r=[];try{r=await u.readdir(a.dir,{withFileTypes:true});}catch{continue}for(let c of r){if(i.has(c.name))continue;let l=d.join(a.dir,c.name);if(c.isDirectory()){a.depth<6&&!c.name.startsWith(".")&&n.push({dir:l,depth:a.depth+1});continue}if(!c.isFile()||!Si.has(d.extname(c.name).toLowerCase()))continue;o+=1;let p="";try{if((await u.stat(l)).size>512*1024)continue;p=await u.readFile(l,"utf8");}catch{continue}for(let y of Ei){y.lastIndex=0;for(let v of p.matchAll(y)){let j=v.slice(1).find(k=>typeof k=="string"&&k.length>0);j&&t.add(j);}}}}let s=await _e(d.join(e,".env"));for(let a of s.split(/\r?\n/)){let r=a.match(/^\s*(?:export\s+)?([A-Z][A-Z0-9_]*)\s*=/);r?.[1]&&t.add(r[1]);}return [...t].sort((a,r)=>a.localeCompare(r))}async function $i(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 u.pathExists(d.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==="java"){let t=await u.pathExists(d.join(e.projectPath,"pom.xml")),i=await u.pathExists(d.join(e.projectPath,"mvnw"))||await u.pathExists(d.join(e.projectPath,"mvnw.cmd")),n=await u.pathExists(d.join(e.projectPath,"gradlew"))||await u.pathExists(d.join(e.projectPath,"gradlew.bat"));return {command:t?i?process.platform==="win32"?".\\mvnw.cmd -B -DskipTests dependency:go-offline":"./mvnw -B -DskipTests dependency:go-offline":"mvn -B -DskipTests dependency:go-offline":n?process.platform==="win32"?".\\gradlew.bat dependencies":"./gradlew dependencies":"gradle dependencies",title:"Prepare Java dependency baseline",files:["pom.xml","build.gradle","build.gradle.kts","gradle.lockfile"],limitations:["Review resolved dependency and lockfile changes before committing."]}}if(e.runtime==="scala")return {command:"sbt update",title:"Prepare Scala dependency baseline",files:["build.sbt","project/build.properties","project/plugins.sbt"],limitations:["Review resolved dependency and plugin changes before committing."]};if(e.runtime==="kotlin")return {command:process.platform==="win32"?".\\gradlew.bat dependencies":"./gradlew dependencies",title:"Prepare Kotlin dependency baseline",files:["build.gradle","build.gradle.kts","gradle.lockfile"],limitations:["Review resolved dependency and lockfile 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 _e(d.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 Ge(e){let t=e?.scripts;if(!t||typeof t!="object"||Array.isArray(t))return {};let i={};for(let[n,o]of Object.entries(t))typeof o=="string"&&o.trim().length>0&&(i[n]=o);return i}function Fi(e){if(e.runtime==="node"){let i=Ge(e.packageJsonData);if(!e.packageJsonData)return null;if(e.kind==="test"){let n=i.lint?"npm run lint":i.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 {deno:{test:{command:"deno test --allow-none",title:"Define Deno test command",targetName:"test",files:["Makefile","deno.json","deno.jsonc"]},quality:{command:"deno fmt --check && deno lint",title:"Define Deno quality command",targetName:"quality",files:["Makefile","deno.json","deno.jsonc"]},security:{command:"deno info --json",title:"Define Deno dependency inspection command",targetName:"security",files:["Makefile","deno.json","deno.jsonc","deno.lock"],limitations:["Pair dependency inspection with the organization vulnerability service used by CI."]}},bun:{test:{command:"bun test",title:"Define Bun test script",targetName:"test",files:["package.json","bun.lock","bun.lockb"]},quality:{command:"bunx eslint .",title:"Define Bun quality script",targetName:"quality",files:["package.json"],limitations:["Ensure ESLint is declared before enforcing this command in CI."]},security:{command:"bun audit",title:"Define Bun security audit script",targetName:"audit",files:["package.json","bun.lock","bun.lockb"]}},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."]}},elixir:{test:{command:"mix test",title:"Define Elixir test command",targetName:"test",files:["Makefile","mix.exs"]},quality:{command:"mix format --check-formatted && mix credo --strict",title:"Define Elixir quality command",targetName:"quality",files:["Makefile","mix.exs",".formatter.exs","credo.exs"],limitations:["Ensure Credo is declared before enforcing the strict quality command."]},security:{command:"mix hex.audit",title:"Define Hex dependency audit command",targetName:"security",files:["Makefile","mix.exs","mix.lock"]}},clojure:{test:{command:"clojure -M:test",title:"Define Clojure test command",targetName:"test",files:["Makefile","deps.edn","project.clj"],limitations:["Align the alias with the test runner declared by the project."]},quality:{command:"clj-kondo --lint src test",title:"Define Clojure quality command",targetName:"quality",files:["Makefile","deps.edn","project.clj"],limitations:["Ensure clj-kondo is provisioned before enforcing this command in CI."]},security:{command:"clojure -Stree",title:"Define Clojure dependency inspection command",targetName:"security",files:["Makefile","deps.edn","project.clj"],limitations:["Pair dependency-tree inspection with the vulnerability scanner selected by the organization."]}},scala:{test:{command:"sbt test",title:"Define Scala test command",targetName:"test",files:["Makefile","build.sbt"]},quality:{command:"sbt scalafmtCheckAll scalafixAll",title:"Define Scala quality command",targetName:"quality",files:["Makefile","build.sbt",".scalafmt.conf"],limitations:["Declare Scalafmt and Scalafix plugins before enforcing this command."]},security:{command:"sbt dependencyTree",title:"Define Scala dependency inspection command",targetName:"security",files:["Makefile","build.sbt"],limitations:["Pair dependency inspection with the organization vulnerability scanner."]}},kotlin:{test:{command:"./gradlew test",title:"Define Kotlin test command",targetName:"test",files:["Makefile","build.gradle","build.gradle.kts"]},quality:{command:"./gradlew check",title:"Define Kotlin quality command",targetName:"quality",files:["Makefile","build.gradle","build.gradle.kts"]},security:{command:"./gradlew dependencies",title:"Define Kotlin dependency inspection command",targetName:"security",files:["Makefile","build.gradle","build.gradle.kts"],limitations:["Pair dependency inspection with the organization vulnerability scanner."]}},c:{test:{command:"ctest --test-dir build --output-on-failure",title:"Define C test command",targetName:"test",files:["Makefile","CMakeLists.txt"]},quality:{command:"clang-tidy src/**/*.c --",title:"Define C quality command",targetName:"quality",files:["Makefile","CMakeLists.txt",".clang-tidy"],limitations:["Align source globs and compile database with the project build."]},security:{command:"cmake --build build --target sbom",title:"Define C dependency evidence command",targetName:"security",files:["Makefile","CMakeLists.txt"],limitations:["Declare the SBOM target or replace it with the organization scanner."]}},cpp:{test:{command:"ctest --test-dir build --output-on-failure",title:"Define C++ test command",targetName:"test",files:["Makefile","CMakeLists.txt"]},quality:{command:"clang-tidy src/**/*.cpp --",title:"Define C++ quality command",targetName:"quality",files:["Makefile","CMakeLists.txt",".clang-tidy"],limitations:["Align source globs and compile database with the project build."]},security:{command:"cmake --build build --target sbom",title:"Define C++ dependency evidence command",targetName:"security",files:["Makefile","CMakeLists.txt"],limitations:["Declare the SBOM target or replace it with the organization scanner."]}}}[e.runtime]?.[e.kind]??null}async function Ni(e){return i({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 Et(e){let t=Fi({runtime:e.runtime,kind:e.kind,packageJsonData:e.packageJsonData});if(t)return (e.runtime==="node"||e.runtime==="bun")&&e.packageJsonData?h({issueId:e.issueId,title:t.title,projectPath:e.projectPath,scriptName:t.targetName,scriptValue:t.command,reason:e.reason,risk:"guarded",limitations:t.limitations}):Ni({issueId:e.issueId,projectPath:e.projectPath,contract:t,reason:e.reason})}function Pe(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=>d.join(e.projectPath,t)),refreshCommands:["npx workspai doctor project --json","npx workspai workspace verify --json"],reason:e.reason,limitations:e.limitations}}function Ii(e){return c$4({issueId:"surface-dockerignore",title:"Create .dockerignore",projectPath:e,relativePath:".dockerignore",content:`${Di}
|
|
4
|
+
`,reason:"Create a Docker build ignore baseline to keep secrets, dependencies, and reports out of container contexts."})}async function Mi(e){if(!await u.pathExists(d.join(e,".gitignore")))return c$4({issueId:"surface-security-hygiene",title:"Create .gitignore secret baseline",projectPath:e,relativePath:".gitignore",content:`${St.join(`
|
|
5
5
|
`)}
|
|
6
|
-
`,reason:"Create a minimal ignore baseline so local env files are not committed accidentally."});let t=await _e(d.join(e,".gitignore")),i=St.filter(n=>!t.split(/\r?\n/).includes(n));return
|
|
7
|
-
`);return {id:"surface-env-contract",label:"Environment/config contract",status:s||l?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Environment/config contract marker detected.":l?"No runtime environment-variable usage was detected; an environment contract is not currently applicable.":a?"No frontend environment contract marker detected.":"No environment/config contract marker detected.",recommendation:s||l?void 0:"Add .env.example, config schema, or environment documentation for deterministic setup.",repairCapability:s?t&&!i?
|
|
8
|
-
`,reason:"Create a secret-free .env.example from environment keys observed in source. Values remain empty for project-owner review.",limitations:["Only variable names are copied; secrets and local values are never read into the generated contract.","Review required and optional variables before committing the example."]}):Pe({issueId:"surface-env-contract",title:"Define environment contract",projectPath:e.projectPath,files:[".env.example"],reason:"A local .env exists, but no safe variable names could be inferred. Review the required keys before publishing an example."})}}async function Oi(e){let t=await u.pathExists(d.join(e.projectPath,"Dockerfile")),i=await u.pathExists(d.join(e.projectPath,".dockerignore")),n=await u.pathExists(d.join(e.projectPath,"docker-compose.yml"))||await u.pathExists(d.join(e.projectPath,"compose.yml"));return t?{id:"surface-dockerignore",label:"Container build context hygiene",status:i?"pass":"warn",severity:"warn",scope:"project-scoped",reason:i?"Dockerfile and .dockerignore detected.":"Dockerfile detected without .dockerignore.",recommendation:i?void 0:"Add .dockerignore to exclude dependencies, reports, git metadata, and local env files from image builds.",repairCapability:i?void 0:Ni(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 a container baseline only when this project is shipped through containerized environments."}}async function _i(e){let t=["k8s","kubernetes","deploy","deployments","charts","helm","kustomization.yaml","kustomization.yml"];if(!await xe(e.projectPath,t)){let r=["DEPLOYMENT.md","docs/deployment.md","docs/deploy.md","Procfile","fly.toml","render.yaml","railway.json","vercel.json","netlify.toml","serverless.yml","serverless.yaml","sst.config.ts","cdk.json","terraform","infra"],c=await xe(e.projectPath,r);return {id:"surface-deploy-contract",label:"Deployment contract",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"A documented or provider-managed non-Kubernetes deployment surface was detected.":"No declared deployment surface or deployment-path documentation was detected.",recommendation:c?void 0:e.projectKind==="backend"||e.projectKind==="fullstack"?"Add deployment manifests or document the non-Kubernetes deployment path.":"Document the distribution or deployment path when this project is production-hosted."}}let n=await at(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),s=/resources:\s*[\s\S]*(limits:|requests:)/.test(n),a=o&&s;return {id:"surface-kubernetes-readiness",label:"Deployment readiness controls",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Deployment surface includes probe and resource-control markers.":"Deployment surface detected, but readiness/liveness probes or resource controls are incomplete.",recommendation:a?void 0:"Add readiness/liveness/startup probes and resource requests/limits to production deployment manifests.",repairCapability:a?void 0:Pe({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 Gi(e){let t=await u.pathExists(d.join(e.projectPath,".gitignore")),n=(await _e(d.join(e.projectPath,".gitignore"))).split(/\r?\n/),o=t&&St.every(B=>n.includes(B)),s=Ge(e.packageJsonData),a=!!(s.audit||s["security:audit"]||s["audit:security"]||s["npm:audit"]),r=e.dependencyAudit,c=Number(r?.blockingFindingCount??r?.findingCount??e.vulnerabilities??0),l=c>0,p=r?.status==="clean",g=r?.status==="tool-unavailable"||r?.status==="unsupported"||r?.status==="failed",v=Ce(e.runtimeFamily),k=["package.json","package-lock.json",...await u.pathExists(d.join(e.projectPath,"npm-shrinkwrap.json"))?["npm-shrinkwrap.json"]:[]],y=r?.invocation,h=r?.remediation?.disposition,w=r?.remediation?.resolutionCandidates?.length??0,b=h==="compatible"||h==="mixed"||!r&&v==="node",D=l&&b&&(r?.tool==="npm audit"||!r&&v==="node")?{cwd:e.projectPath,executable:"npm",args:["audit","fix","--audit-level=moderate"]}:l&&b&&r?.tool==="bun audit"?{cwd:e.projectPath,executable:"bun",args:["update"]}:l&&b&&r?.tool==="deno audit"?{cwd:e.projectPath,executable:"deno",args:["audit","--fix"]}:void 0,F=l?[{id:"audit-live-state",kind:"diagnose",description:"Read the current advisory graph and classify direct, transitive, fixable, and breaking findings.",risk:"safe",invocation:y,continueWhen:"always"},...D?[{id:"apply-compatible-fixes",kind:"safe-fix",description:"Apply runtime-authored compatible dependency and lockfile updates without forcing breaking upgrades.",risk:"guarded",invocation:D,continueWhen:"previous-passed"}]:[],{id:"upgrade-owning-dependencies",kind:"targeted-upgrade",description:"Upgrade the smallest set of direct dependencies that own unresolved advisory paths, then run tests and build.",risk:"guarded",continueWhen:D?"blocker-remains":"always"},{id:"recheck-advisory-graph",kind:"verify",description:"Re-run the runtime-native audit and retain only unresolved advisory paths.",risk:"safe",invocation:y,continueWhen:"blocker-remains"},{id:"review-unfixable-advisories",kind:"exception-review",description:"For advisories without a compatible fix, require a time-bounded policy exception or an explicit replacement plan.",risk:"invasive",continueWhen:"manual-decision"}]:void 0,f=l&&D?i({issueId:"surface-security-hygiene",title:`Apply compatible ${r?.ecosystem??v} vulnerability fixes`,projectPath:e.projectPath,command:[D.executable,...D.args].join(" "),invocation:{executable:D.executable,args:D.args},strategy:F,transaction:{schemaVersion:"workspai.doctor-dependency-repair-transaction.v1",kind:"dependency-security",state:"planned",projectPath:e.projectPath,ecosystem:r?.ecosystem??D.executable??v,requiredStages:["reconcile","audit","test","build"],completion:{manifestLockConsistent:true,auditClean:true,declaredTestsPass:true,declaredBuildPass:true,canonicalVerificationRequired:true}},files:k,reason:"Apply runtime-authored compatible vulnerability remediations, then regenerate Doctor and release-readiness evidence.",risk:"guarded",requiresReview:true,limitations:["Never add --force automatically; unresolved advisories require an evidence-backed dependency upgrade plan.","Review lockfile changes and rerun the complete Workspace Intelligence verification loop."]}):void 0,R=o&&p,x=r?.reason;return {id:"surface-security-hygiene",label:"Security hygiene surface",status:R?"pass":l?"fail":"warn",severity:l?"error":"warn",scope:"project-scoped",reason:l?`${c} moderate/high/critical dependency vulnerability(ies) reported.`:g?`${x} Doctor did not treat unavailable audit evidence as a clean result.`:o&&p?"Repository ignore baseline covers env-file secrets and the runtime-native dependency audit is clean.":o?"Repository ignore baseline covers env-file secrets, but no current dependency audit evidence is available.":t?"Repository ignore baseline exists, but env-file secret rules are incomplete.":"No .gitignore baseline detected for local secrets/build artifacts.",recommendation:l?w>0&&!b?`No direct automatic fix is currently authorized. Evaluate the ${w} structured dependency resolution candidate(s) through a guarded reconcile, audit, test, and build transaction before considering a breaking change.`:h==="breaking-only"||h==="none"?w>0?`No direct automatic fix is currently available. Evaluate the ${w} structured dependency resolution candidate(s) through a guarded install, audit, test, and build transaction before considering a breaking change.`:"No compatible automatic fix is currently available. Review an explicit replacement, a time-bounded exception, or wait for an upstream patch.":"Run the runtime-native audit fix path without force, review lockfile changes, then rerun Doctor.":g?"Install or declare the runtime-native audit tool, rerun Doctor, and keep the command available to CI and Studio.":o?a?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:l?f??{...Pe({issueId:"surface-security-hygiene",title:`Resolve ${r?.ecosystem??v} dependency vulnerabilities`,projectPath:e.projectPath,files:["package.json","package-lock.json","pnpm-lock.yaml","yarn.lock","pyproject.toml","requirements.txt","go.mod","Cargo.toml","composer.json","Gemfile","Directory.Packages.props"],reason:h==="breaking-only"?w>0?"The runtime-native direct fix is breaking or a downgrade. Doctor preserved bounded owner, constraint, or transitive resolution candidates for guarded compatibility verification before requesting an engineering decision.":"The runtime-native audit exposes only breaking or downgrade remediation. Doctor requires an explicit engineering decision instead of presenting it as an automatic fix.":h==="none"?w>0?"The runtime-native audit reports no direct fix. Evaluate its structured transitive or constraint resolution candidates through the dependency transaction before choosing replacement, exception, or upstream wait.":"The runtime-native audit reports no available fix. Use an explicit replacement plan, time-bounded exception, or upstream patch.":"Dependency remediation can change direct and transitive graphs; use the audit evidence to upgrade the owning dependencies.",limitations:["Never force a breaking dependency upgrade automatically.","Review lock or baseline changes, run project tests/build, then rerun the complete Workspace Intelligence verification loop."]}),strategy:F,transaction:{schemaVersion:"workspai.doctor-dependency-repair-transaction.v1",kind:"dependency-security",state:"planned",projectPath:e.projectPath,ecosystem:r?.ecosystem??D?.executable??v,requiredStages:["reconcile","audit","test","build"],completion:{manifestLockConsistent:true,auditClean:true,declaredTestsPass:true,declaredBuildPass:true,canonicalVerificationRequired:true}}}:o?void 0:await Ii(e.projectPath)}}async function Ki(e){let t=Ce(e.runtimeFamily),i=e.hasTests===true,n=i?void 0:await Et({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:i?"pass":"warn",severity:"warn",scope:"project-scoped",reason:i?"Test surface detected through scripts, config, directories, or test files.":"No test surface detected by Doctor.",recommendation:i?void 0:"Add at least one deterministic test command or test baseline before release.",repairCapability:n??(i?void 0:Pe({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."}))}}async function Wi(e$1){let t=d.join(e$1.projectPath,".workspai","reports","project-test-coverage-last-run.json"),i$1=await u.readJson(t).catch(()=>null);if(!(i$1?.schemaVersion===d$2.projectTestCoverage.schemaVersion))return {id:"test-coverage-evidence",label:"Test coverage evidence",status:"warn",severity:"warn",scope:"project-scoped",reason:"No normalized project coverage evidence has been generated yet.",recommendation:"Run project coverage once to establish a measurable baseline before selecting a coverage goal.",repairCapability:i({issueId:"test-coverage-evidence",title:"Generate project coverage baseline",projectPath:e$1.projectPath,command:"npx workspai project coverage --run --json",invocation:{executable:"npx",args:["workspai","project","coverage","--run","--json"]},files:[e.projectTestCoverage],reason:"Run the runtime-native test coverage adapter and publish normalized evidence for Doctor, CI, Studio, and IDE consumers.",risk:"safe",requiresReview:false})};let o=i$1.target?.metric??"lines",s=Bi(i$1.target?.percent),a=i$1.metrics?.[o]?.percent,r=typeof a=="number"?`${a}%`:"unavailable",c=i$1.status==="passed"?"pass":i$1.status==="below-target"||i$1.status==="failed"?"fail":"warn";return {id:"test-coverage-evidence",label:"Test coverage evidence",status:c,severity:c==="fail"?"error":"warn",scope:"project-scoped",reason:i$1.status==="passed"?`${o} coverage ${r} satisfies the ${s}% project target.`:i$1.status==="below-target"?`${o} coverage ${r} is below the ${s}% project target.`:i$1.status==="failed"?"The runtime-native coverage command failed; the target cannot be verified.":"Coverage evidence exists, but no supported metric could be normalized.",recommendation:i$1.status==="passed"?void 0:i$1.status==="below-target"?`Add targeted tests for the lowest-coverage source paths, then rerun project coverage with target ${s}%.`:"Repair the runtime-native coverage command or reporter and regenerate evidence.",repairCapability:i$1.status==="passed"?void 0:Pe({issueId:"test-coverage-evidence",title:"Reach the project coverage goal",projectPath:e$1.projectPath,files:[e.projectTestCoverage,...(i$1.lowCoverageFiles??[]).map(l=>l.path).filter(l=>typeof l=="string").slice(0,20)],reason:"Test creation requires source-aware assertions. Studio should use the normalized low-coverage paths, edit tests, and rerun the same target until verified.",limitations:["Do not lower thresholds, exclude difficult source files, remove assertions, or skip failing tests to satisfy the goal."]})}}function Bi(e){let t=Number(e);return Number.isFinite(t)&&t>=0?t:0}function Hi(e){let t=Ge(e.packageJsonData),i=!!(t.format||t["format:check"]||t.prettier);return {id:"surface-format-contract",label:"Format contract",status:i?"pass":"warn",severity:"warn",scope:"project-scoped",reason:i?"Format script detected in package.json.":"No explicit format script detected by Doctor.",recommendation:i?void 0:"Add a formatter command or document the formatting tool used by CI."}}async function qi(e){let t=Ce(e.runtimeFamily),n={node:["test","tests","__tests__","vitest.config.ts","vitest.config.js","vitest.config.mts","vitest.config.mjs","jest.config.ts","jest.config.js","jest.config.cjs","jest.config.mjs","playwright.config.ts","playwright.config.js","cypress.config.ts","cypress.config.js","*.spec.ts","*.spec.js","*.test.ts","*.test.js"],deno:["deno.json","deno.jsonc"],bun:["bunfig.toml","test","tests","*.test.ts","*.spec.ts"],python:["pytest.ini","tox.ini","noxfile.py","tests","test","conftest.py","*_test.py"],go:["*_test.go"],java:["src/test","*Test.java","*Tests.java","*IT.java"],rust:["tests","*_test.rs"],elixir:["test","*_test.exs"],clojure:["test","*_test.clj","*_test.cljc"],php:["phpunit.xml","phpunit.xml.dist","tests"],ruby:["spec","test",".rspec"],dotnet:["*.Tests.csproj","*.Test.csproj","*Tests.cs"],scala:["src/test","*Spec.scala","*Suite.scala"],kotlin:["src/test","*Test.kt","*Tests.kt"],c:["test","tests","*_test.c","test_*.c"],cpp:["test","tests","*_test.cpp","test_*.cpp","*Test.cpp"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await xe(e.projectPath,n),s=Ge(e.packageJsonData),a=Object.values(s).join(`
|
|
6
|
+
`,reason:"Create a minimal ignore baseline so local env files are not committed accidentally."});let t=await _e(d.join(e,".gitignore")),i=St.filter(n=>!t.split(/\r?\n/).includes(n));return d$7({issueId:"surface-security-hygiene",title:"Append .gitignore secret baseline",projectPath:e,relativePath:".gitignore",lines:i,reason:"Append missing env-file ignore rules so local secrets stay out of source control."})}async function Ti(e){let t=Pi[e.runtime]??[],i=Ci[e.runtime]??[];if(t.length===0&&i.length===0)return null;let n=await xe(e.projectPath,t),o=await xe(e.projectPath,i),s=n&&!o?await $i({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 (${i.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&&s?j$4({issueId:"surface-dependency-contract",title:s.title,projectPath:e.projectPath,command:s.command,files:s.files,fixKind:"dependency-sync",reason:"Generate the runtime-native dependency baseline so CI, Doctor, and Studio share deterministic dependency evidence.",limitations:s.limitations}):void 0}}async function Oi(e){let t=await u.pathExists(d.join(e.projectPath,".env.example")),i=await u.pathExists(d.join(e.projectPath,".env")),n=await u.pathExists(d.join(e.projectPath,"docs","env.md"))||await u.pathExists(d.join(e.projectPath,"ENVIRONMENT.md")),o=await u.pathExists(d.join(e.projectPath,"config")),s=t||n||o,a=e.projectKind==="frontend",r=s?[]:await Ai(e.projectPath),c=i||r.length>0,l=!s&&!c,p=r.map(y=>`${y}=`).join(`
|
|
7
|
+
`);return {id:"surface-env-contract",label:"Environment/config contract",status:s||l?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Environment/config contract marker detected.":l?"No runtime environment-variable usage was detected; an environment contract is not currently applicable.":a?"No frontend environment contract marker detected.":"No environment/config contract marker detected.",recommendation:s||l?void 0:"Add .env.example, config schema, or environment documentation for deterministic setup.",repairCapability:s?t&&!i?e$3({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:l?void 0:r.length>0?c$4({issueId:"surface-env-contract",title:"Create environment contract skeleton",projectPath:e.projectPath,relativePath:".env.example",content:`${p}
|
|
8
|
+
`,reason:"Create a secret-free .env.example from environment keys observed in source. Values remain empty for project-owner review.",limitations:["Only variable names are copied; secrets and local values are never read into the generated contract.","Review required and optional variables before committing the example."]}):Pe({issueId:"surface-env-contract",title:"Define environment contract",projectPath:e.projectPath,files:[".env.example"],reason:"A local .env exists, but no safe variable names could be inferred. Review the required keys before publishing an example."})}}async function _i(e){let t=await u.pathExists(d.join(e.projectPath,"Dockerfile")),i=await u.pathExists(d.join(e.projectPath,".dockerignore")),n=await u.pathExists(d.join(e.projectPath,"docker-compose.yml"))||await u.pathExists(d.join(e.projectPath,"compose.yml"));return t?{id:"surface-dockerignore",label:"Container build context hygiene",status:i?"pass":"warn",severity:"warn",scope:"project-scoped",reason:i?"Dockerfile and .dockerignore detected.":"Dockerfile detected without .dockerignore.",recommendation:i?void 0:"Add .dockerignore to exclude dependencies, reports, git metadata, and local env files from image builds.",repairCapability:i?void 0:Ii(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 a container baseline only when this project is shipped through containerized environments."}}async function Gi(e){let t=["k8s","kubernetes","deploy","deployments","charts","helm","kustomization.yaml","kustomization.yml"];if(!await xe(e.projectPath,t)){let r=["DEPLOYMENT.md","docs/deployment.md","docs/deploy.md","Procfile","fly.toml","render.yaml","railway.json","vercel.json","netlify.toml","serverless.yml","serverless.yaml","sst.config.ts","cdk.json","terraform","infra"],c=await xe(e.projectPath,r);return {id:"surface-deploy-contract",label:"Deployment contract",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"A documented or provider-managed non-Kubernetes deployment surface was detected.":"No declared deployment surface or deployment-path documentation was detected.",recommendation:c?void 0:e.projectKind==="backend"||e.projectKind==="fullstack"?"Add deployment manifests or document the non-Kubernetes deployment path.":"Document the distribution or deployment path when this project is production-hosted."}}let n=await at(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),s=/resources:\s*[\s\S]*(limits:|requests:)/.test(n),a=o&&s;return {id:"surface-kubernetes-readiness",label:"Deployment readiness controls",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?"Deployment surface includes probe and resource-control markers.":"Deployment surface detected, but readiness/liveness probes or resource controls are incomplete.",recommendation:a?void 0:"Add readiness/liveness/startup probes and resource requests/limits to production deployment manifests.",repairCapability:a?void 0:Pe({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 Ki(e){let t=await u.pathExists(d.join(e.projectPath,".gitignore")),n=(await _e(d.join(e.projectPath,".gitignore"))).split(/\r?\n/),o=t&&St.every(B=>n.includes(B)),s=Ge(e.packageJsonData),a=!!(s.audit||s["security:audit"]||s["audit:security"]||s["npm:audit"]),r=e.dependencyAudit,c=Number(r?.blockingFindingCount??r?.findingCount??e.vulnerabilities??0),l=c>0,p=r?.status==="clean",y=r?.status==="tool-unavailable"||r?.status==="unsupported"||r?.status==="failed",v=Ce(e.runtimeFamily),k=["package.json","package-lock.json",...await u.pathExists(d.join(e.projectPath,"npm-shrinkwrap.json"))?["npm-shrinkwrap.json"]:[]],g=r?.invocation,h=r?.remediation?.disposition,w=r?.remediation?.resolutionCandidates?.length??0,b=h==="compatible"||h==="mixed"||!r&&v==="node",D=l&&b&&(r?.tool==="npm audit"||!r&&v==="node")?{cwd:e.projectPath,executable:"npm",args:["audit","fix","--audit-level=moderate"]}:l&&b&&r?.tool==="bun audit"?{cwd:e.projectPath,executable:"bun",args:["update"]}:l&&b&&r?.tool==="deno audit"?{cwd:e.projectPath,executable:"deno",args:["audit","--fix"]}:void 0,F=l?[{id:"audit-live-state",kind:"diagnose",description:"Read the current advisory graph and classify direct, transitive, fixable, and breaking findings.",risk:"safe",invocation:g,continueWhen:"always"},...D?[{id:"apply-compatible-fixes",kind:"safe-fix",description:"Apply runtime-authored compatible dependency and lockfile updates without forcing breaking upgrades.",risk:"guarded",invocation:D,continueWhen:"previous-passed"}]:[],{id:"upgrade-owning-dependencies",kind:"targeted-upgrade",description:"Upgrade the smallest set of direct dependencies that own unresolved advisory paths, then run tests and build.",risk:"guarded",continueWhen:D?"blocker-remains":"always"},{id:"recheck-advisory-graph",kind:"verify",description:"Re-run the runtime-native audit and retain only unresolved advisory paths.",risk:"safe",invocation:g,continueWhen:"blocker-remains"},{id:"review-unfixable-advisories",kind:"exception-review",description:"For advisories without a compatible fix, require a time-bounded policy exception or an explicit replacement plan.",risk:"invasive",continueWhen:"manual-decision"}]:void 0,f=l&&D?j$4({issueId:"surface-security-hygiene",title:`Apply compatible ${r?.ecosystem??v} vulnerability fixes`,projectPath:e.projectPath,command:[D.executable,...D.args].join(" "),invocation:{executable:D.executable,args:D.args},strategy:F,transaction:{schemaVersion:"workspai.doctor-dependency-repair-transaction.v1",kind:"dependency-security",state:"planned",projectPath:e.projectPath,ecosystem:r?.ecosystem??D.executable??v,requiredStages:["reconcile","audit","test","build"],completion:{manifestLockConsistent:true,auditClean:true,declaredTestsPass:true,declaredBuildPass:true,canonicalVerificationRequired:true}},files:k,reason:"Apply runtime-authored compatible vulnerability remediations, then regenerate Doctor and release-readiness evidence.",risk:"guarded",requiresReview:true,limitations:["Never add --force automatically; unresolved advisories require an evidence-backed dependency upgrade plan.","Review lockfile changes and rerun the complete Workspace Intelligence verification loop."]}):void 0,R=o&&p,x=r?.reason;return {id:"surface-security-hygiene",label:"Security hygiene surface",status:R?"pass":l?"fail":"warn",severity:l?"error":"warn",scope:"project-scoped",reason:l?`${c} moderate/high/critical dependency vulnerability(ies) reported.`:y?`${x} Doctor did not treat unavailable audit evidence as a clean result.`:o&&p?"Repository ignore baseline covers env-file secrets and the runtime-native dependency audit is clean.":o?"Repository ignore baseline covers env-file secrets, but no current dependency audit evidence is available.":t?"Repository ignore baseline exists, but env-file secret rules are incomplete.":"No .gitignore baseline detected for local secrets/build artifacts.",recommendation:l?w>0&&!b?`No direct automatic fix is currently authorized. Evaluate the ${w} structured dependency resolution candidate(s) through a guarded reconcile, audit, test, and build transaction before considering a breaking change.`:h==="breaking-only"||h==="none"?w>0?`No direct automatic fix is currently available. Evaluate the ${w} structured dependency resolution candidate(s) through a guarded install, audit, test, and build transaction before considering a breaking change.`:"No compatible automatic fix is currently available. Review an explicit replacement, a time-bounded exception, or wait for an upstream patch.":"Run the runtime-native audit fix path without force, review lockfile changes, then rerun Doctor.":y?"Install or declare the runtime-native audit tool, rerun Doctor, and keep the command available to CI and Studio.":o?a?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:l?f??{...Pe({issueId:"surface-security-hygiene",title:`Resolve ${r?.ecosystem??v} dependency vulnerabilities`,projectPath:e.projectPath,files:["package.json","package-lock.json","pnpm-lock.yaml","yarn.lock","pyproject.toml","requirements.txt","go.mod","Cargo.toml","composer.json","Gemfile","Directory.Packages.props"],reason:h==="breaking-only"?w>0?"The runtime-native direct fix is breaking or a downgrade. Doctor preserved bounded owner, constraint, or transitive resolution candidates for guarded compatibility verification before requesting an engineering decision.":"The runtime-native audit exposes only breaking or downgrade remediation. Doctor requires an explicit engineering decision instead of presenting it as an automatic fix.":h==="none"?w>0?"The runtime-native audit reports no direct fix. Evaluate its structured transitive or constraint resolution candidates through the dependency transaction before choosing replacement, exception, or upstream wait.":"The runtime-native audit reports no available fix. Use an explicit replacement plan, time-bounded exception, or upstream patch.":"Dependency remediation can change direct and transitive graphs; use the audit evidence to upgrade the owning dependencies.",limitations:["Never force a breaking dependency upgrade automatically.","Review lock or baseline changes, run project tests/build, then rerun the complete Workspace Intelligence verification loop."]}),strategy:F,transaction:{schemaVersion:"workspai.doctor-dependency-repair-transaction.v1",kind:"dependency-security",state:"planned",projectPath:e.projectPath,ecosystem:r?.ecosystem??D?.executable??v,requiredStages:["reconcile","audit","test","build"],completion:{manifestLockConsistent:true,auditClean:true,declaredTestsPass:true,declaredBuildPass:true,canonicalVerificationRequired:true}}}:o?void 0:await Mi(e.projectPath)}}async function Wi(e){let t=Ce(e.runtimeFamily),i=e.hasTests===true,n=i?void 0:await Et({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:i?"pass":"warn",severity:"warn",scope:"project-scoped",reason:i?"Test surface detected through scripts, config, directories, or test files.":"No test surface detected by Doctor.",recommendation:i?void 0:"Add at least one deterministic test command or test baseline before release.",repairCapability:n??(i?void 0:Pe({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."}))}}async function Bi(e$1){let t=d.join(e$1.projectPath,".workspai","reports","project-test-coverage-last-run.json"),i=await u.readJson(t).catch(()=>null);if(!(i?.schemaVersion===d$2.projectTestCoverage.schemaVersion))return {id:"test-coverage-evidence",label:"Test coverage evidence",status:"warn",severity:"warn",scope:"project-scoped",reason:"No normalized project coverage evidence has been generated yet.",recommendation:"Run project coverage once to establish a measurable baseline before selecting a coverage goal.",repairCapability:j$4({issueId:"test-coverage-evidence",title:"Generate project coverage baseline",projectPath:e$1.projectPath,command:"npx workspai project coverage --run --json",invocation:{executable:"npx",args:["workspai","project","coverage","--run","--json"]},files:[e.projectTestCoverage],reason:"Run the runtime-native test coverage adapter and publish normalized evidence for Doctor, CI, Studio, and IDE consumers.",risk:"safe",requiresReview:false})};let o=i.target?.metric??"lines",s=Hi(i.target?.percent),a=i.metrics?.[o]?.percent,r=typeof a=="number"?`${a}%`:"unavailable",c=i.status==="passed"?"pass":i.status==="below-target"||i.status==="failed"?"fail":"warn";return {id:"test-coverage-evidence",label:"Test coverage evidence",status:c,severity:c==="fail"?"error":"warn",scope:"project-scoped",reason:i.status==="passed"?`${o} coverage ${r} satisfies the ${s}% project target.`:i.status==="below-target"?`${o} coverage ${r} is below the ${s}% project target.`:i.status==="failed"?"The runtime-native coverage command failed; the target cannot be verified.":"Coverage evidence exists, but no supported metric could be normalized.",recommendation:i.status==="passed"?void 0:i.status==="below-target"?`Add targeted tests for the lowest-coverage source paths, then rerun project coverage with target ${s}%.`:"Repair the runtime-native coverage command or reporter and regenerate evidence.",repairCapability:i.status==="passed"?void 0:Pe({issueId:"test-coverage-evidence",title:"Reach the project coverage goal",projectPath:e$1.projectPath,files:[e.projectTestCoverage,...(i.lowCoverageFiles??[]).map(l=>l.path).filter(l=>typeof l=="string").slice(0,20)],reason:"Test creation requires source-aware assertions. Studio should use the normalized low-coverage paths, edit tests, and rerun the same target until verified.",limitations:["Do not lower thresholds, exclude difficult source files, remove assertions, or skip failing tests to satisfy the goal."]})}}function Hi(e){let t=Number(e);return Number.isFinite(t)&&t>=0?t:0}function qi(e){let t=Ge(e.packageJsonData),i=!!(t.format||t["format:check"]||t.prettier);return {id:"surface-format-contract",label:"Format contract",status:i?"pass":"warn",severity:"warn",scope:"project-scoped",reason:i?"Format script detected in package.json.":"No explicit format script detected by Doctor.",recommendation:i?void 0:"Add a formatter command or document the formatting tool used by CI."}}async function Li(e){let t=Ce(e.runtimeFamily),n={node:["test","tests","__tests__","vitest.config.ts","vitest.config.js","vitest.config.mts","vitest.config.mjs","jest.config.ts","jest.config.js","jest.config.cjs","jest.config.mjs","playwright.config.ts","playwright.config.js","cypress.config.ts","cypress.config.js","*.spec.ts","*.spec.js","*.test.ts","*.test.js"],deno:["deno.json","deno.jsonc"],bun:["bunfig.toml","test","tests","*.test.ts","*.spec.ts"],python:["pytest.ini","tox.ini","noxfile.py","tests","test","conftest.py","*_test.py"],go:["*_test.go"],java:["src/test","*Test.java","*Tests.java","*IT.java"],rust:["tests","*_test.rs"],elixir:["test","*_test.exs"],clojure:["test","*_test.clj","*_test.cljc"],php:["phpunit.xml","phpunit.xml.dist","tests"],ruby:["spec","test",".rspec"],dotnet:["*.Tests.csproj","*.Test.csproj","*Tests.cs"],scala:["src/test","*Spec.scala","*Suite.scala"],kotlin:["src/test","*Test.kt","*Tests.kt"],c:["test","tests","*_test.c","test_*.c"],cpp:["test","tests","*_test.cpp","test_*.cpp","*Test.cpp"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await xe(e.projectPath,n),s=Ge(e.packageJsonData),a=Object.values(s).join(`
|
|
9
9
|
`),r=await at(e.projectPath,["pyproject.toml","Cargo.toml","mix.exs","deps.edn","project.clj","composer.json","Gemfile","pom.xml","build.gradle","build.gradle.kts","deno.json","deno.jsonc"]),l={node:/\b(jest|vitest|mocha|ava|tap|playwright|cypress|node\s+--test|bun\s+test)\b/i,bun:/\bbun\s+test\b/i,deno:/\bdeno\s+test\b/i,python:/\b(pytest|unittest|tox|nox)\b/i,java:/\b(junit|testng|surefire|failsafe|gradle[^]*\btest\b)\b/i,rust:/\b(cargo\s+test|dev-dependencies)\b/i,elixir:/\b(ex_unit|mix\s+test)\b/i,clojure:/\b(clojure\.test|kaocha|eftest)\b/i,php:/\b(phpunit|pestphp|pest)\b/i,ruby:/\b(rspec|minitest)\b/i,dotnet:/\b(Microsoft\.NET\.Test\.Sdk|xunit|nunit|mstest)\b/i,scala:/\b(scalatest|munit|specs2|sbt\s+test)\b/i,kotlin:/\b(kotest|junit|gradle[^]*\btest\b)\b/i,c:/\b(ctest|cmocka|criterion|unity)\b/i,cpp:/\b(ctest|catch2|gtest|googletest|doctest)\b/i}[t]?.test(`${a}
|
|
10
|
-
${r}`)??false,p=e.hasTests===true&&(o||l);return {id:"runtime-test-depth",label:"Runtime-native test depth",status:p?"pass":("warn"),severity:"warn",scope:"project-scoped",reason:p?"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:p?void 0:"Add runtime-native tests/config so Doctor, CI, and Studio can verify changes deterministically."}}async function
|
|
10
|
+
${r}`)??false,p=e.hasTests===true&&(o||l);return {id:"runtime-test-depth",label:"Runtime-native test depth",status:p?"pass":("warn"),severity:"warn",scope:"project-scoped",reason:p?"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:p?void 0:"Add runtime-native tests/config so Doctor, CI, and Studio can verify changes deterministically."}}async function Vi(e){let t=Ce(e.runtimeFamily),n={node:["eslint.config.js","eslint.config.cjs","eslint.config.mjs","eslint.config.ts","eslint.config.mts",".eslintrc",".eslintrc.js",".eslintrc.cjs",".eslintrc.json","prettier.config.js","prettier.config.cjs","prettier.config.mjs",".prettierrc",".prettierrc.json","biome.json","biome.jsonc"],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"],scala:[".scalafmt.conf",".scalafix.conf","build.sbt"],kotlin:[".editorconfig","detekt.yml","build.gradle","build.gradle.kts"],c:[".clang-format",".clang-tidy","CMakeLists.txt"],cpp:[".clang-format",".clang-tidy","CMakeLists.txt"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await at(e.projectPath,[...n,"package.json","pyproject.toml","Makefile","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","mix.exs","deps.edn","project.clj","composer.json","Gemfile","Directory.Build.props"]),s=Ge(e.packageJsonData),a=Object.entries(s).filter(([p])=>/lint|format|quality|check|typecheck|static/i.test(p)).map(([,p])=>p).join(`
|
|
11
11
|
`),r=await xe(e.projectPath,n),c=/eslint|prettier|biome|ruff|black|mypy|golangci|checkstyle|spotless|pmd|clippy|rustfmt|credo|clj-kondo|phpstan|phpcs|pint|rubocop|editorconfig|dotnet format|scalafmt|scalafix|detekt|ktlint|clang-tidy|clang-format/i.test(`${o}
|
|
12
|
-
${a}`)||r,l=c?void 0:await Et({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:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Runtime-native lint/format/static-analysis markers detected.":"No runtime-native lint/format/static-analysis markers detected.",recommendation:c?void 0:"Add runtime-native lint/format/static-analysis tooling and expose it to CI.",repairCapability:l}}async function Vi(e){let t=Ce(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"],scala:["build.sbt","project/plugins.sbt"],kotlin:["build.gradle","build.gradle.kts","pom.xml"],c:["CMakeLists.txt","conanfile.py","conanfile.txt","vcpkg.json"],cpp:["CMakeLists.txt","conanfile.py","conanfile.txt","vcpkg.json"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await at(e.projectPath,n),s=/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|dependencyCheck|dependency-check|snyk|trivy|osv-scanner|cyclonedx|sbom/i.test(o),a=s?void 0:await Et({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:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Runtime-native security audit tooling marker detected.":"No runtime-native security audit tooling marker detected.",recommendation:s?void 0:"Expose a runtime-native dependency/security audit command for CI and Studio verification.",repairCapability:s?void 0:a||Pe({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 Dn(e){let t=Ce(e.runtimeFamily),i=[],n=await Mi({projectPath:e.projectPath,runtime:t,packageJsonData:e.packageJsonData});n&&i.push(n),i.push(await Ti(e)),i.push(await Oi(e)),i.push(await _i(e)),i.push(await Gi(e)),i.push(await Ki(e)),i.push(await Wi(e)),(t==="node"||t==="bun")&&i.push(Hi(e));let o=await Promise.all([qi(e),Li(e),Vi(e)]);for(let s of o)s&&i.push(s);return i}var le={low:0,moderate:0,high:0,critical:0,unknown:0};function zi(e){let t=String(e??"unknown").toLowerCase();return t==="medium"?"moderate":t==="low"||t==="moderate"||t==="high"||t==="critical"?t:"unknown"}function ce(e){let t=typeof e.name=="string"?e.name.trim():"";return t?{name:t,...typeof e.version=="string"&&e.version.trim()?{version:e.version.trim()}:{},...typeof e.direct=="boolean"?{direct:e.direct}:{},advisoryIds:[...new Set((e.advisoryIds??[]).map(i=>typeof i=="string"||typeof i=="number"?String(i).trim():"").filter(Boolean))].sort(),severities:[...new Set((e.severities??[]).map(i=>zi(i)))].sort()}:null}function ae(e){let t=new Map;for(let i of e){if(!i)continue;let n=i.name.toLowerCase(),o=t.get(n);if(!o){t.set(n,i);continue}t.set(n,{name:o.name,...o.version||i.version?{version:o.version??i.version}:{},...o.direct!==void 0||i.direct!==void 0?{direct:o.direct??i.direct}:{},advisoryIds:[...new Set([...o.advisoryIds,...i.advisoryIds])].sort(),severities:[...new Set([...o.severities,...i.severities])].sort()});}return [...t.values()].sort((i,n)=>i.name.localeCompare(n.name))}function Rn(e){return e.map(t=>{let i=t.direct===true?"direct":t.direct===false?"transitive":"unknown";return {packageName:t.name,relationship:i,strategies:i==="direct"?["direct-upgrade","constraint-update","replacement","policy-exception","upstream-wait"]:["owner-upgrade","constraint-update","replacement","policy-exception","upstream-wait"],risk:"guarded",autoExecutable:false,requiresCompatibilityVerification:true,...t.version?{currentVersion:t.version}:{},ownerPackages:[],advisoryIds:[...t.advisoryIds],reason:"Resolve the advisory through the runtime-native dependency manifest and lock/baseline, then prove compatibility with audit, tests, build, and canonical verification."}})}var At=new Map,Ui=["package.json","package-lock.json","npm-shrinkwrap.json","pnpm-lock.yaml","yarn.lock",".yarnrc.yml","bun.lock","bun.lockb","deno.lock","pyproject.toml","requirements.txt","uv.lock","poetry.lock","go.mod","go.sum","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","Cargo.lock","composer.json","composer.lock","Gemfile","Gemfile.lock","mix.exs","mix.lock","deps.edn","project.clj","Directory.Packages.props","packages.lock.json"];function Zi(){let e=Number(process.env.RAPIDKIT_DOCTOR_AUDIT_TIMEOUT_MS);return Number.isFinite(e)&&e>0?Math.trunc(e):15e3}async function Yi(e,t){let i=[];for(let n of Ui){let o=d.join(e,n);try{let s=await u.stat(o);i.push(`${n}:${s.size}:${s.mtimeMs}`);}catch{}}return `${d.resolve(e)}\0${t}\0${i.join("|")}`}function me(e){let t=e.trim();if(!t)return null;try{let i=JSON.parse(t);return i&&typeof i=="object"&&!Array.isArray(i)?i:null}catch{return null}}function Ke(e){return typeof e=="number"&&Number.isFinite(e)?Math.max(0,e):0}function Sn(e){let t=e&&typeof e=="object"&&!Array.isArray(e)?e:{};return {low:Ke(t.low),moderate:Ke(t.moderate??t.medium),high:Ke(t.high),critical:Ke(t.critical),unknown:Ke(t.unknown)}}function Be(e){return e.low+e.moderate+e.high+e.critical+e.unknown}function Qi(e){if(typeof e!="string")return;let t=e.trim(),i=t.match(/^<\s*(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/);if(i)return `>=${i[1]}`;let n=t.match(/^<=\s*(\d+)\.(\d+)\.(\d+)$/);if(n)return `>=${n[1]}.${n[2]}.${Number(n[3])+1}`}async function Xi(e){let t=new Map;try{let i=await u.readJSON(d.join(e,"package.json"));for(let n of ["dependencies","devDependencies","optionalDependencies","peerDependencies"]){let o=i[n];if(!(!o||typeof o!="object"||Array.isArray(o)))for(let[s,a]of Object.entries(o))typeof a=="string"&&a.trim()&&t.set(s.toLowerCase(),a.trim());}}catch{}return t}async function eo(e,t){let i=me(t),n=i?.vulnerabilities&&typeof i.vulnerabilities=="object"&&!Array.isArray(i.vulnerabilities)?i.vulnerabilities:void 0;if(!n)return [];let[o,s]=await Promise.all([$n(e),Xi(e)]),a=new Map;for(let[r,c]of Object.entries(n)){let l=c&&typeof c=="object"?c:{},p=typeof l.name=="string"&&l.name.trim()?l.name.trim():r.trim();if(!p)continue;let g=l.isDirect===true?"direct":l.isDirect===false?"transitive":"unknown",v=Array.isArray(l.effects)?[...new Set(l.effects.filter(F=>typeof F=="string").map(F=>F.trim()).filter(Boolean))].sort():[],j=Array.isArray(l.via)?l.via:[],k=[...new Set(j.flatMap(F=>{let f=F&&typeof F=="object"?F:{};return [f.source,f.url].filter(R=>typeof R=="string"||typeof R=="number").map(String)}))].sort(),y=typeof l.range=="string"?l.range.trim():void 0,h=Qi(y),w=s.get(p.toLowerCase()),b=o.get(p.toLowerCase()),D=g==="direct"?["direct-upgrade","constraint-update","replacement","policy-exception","upstream-wait"]:[...v.length>0?["owner-upgrade"]:[],"transitive-override","replacement","policy-exception","upstream-wait"];a.set(p.toLowerCase(),{packageName:p,relationship:g,strategies:D,risk:"guarded",autoExecutable:false,requiresCompatibilityVerification:true,...b?{currentVersion:b}:{},...w?{currentRange:w}:{},...y?{vulnerableRange:y}:{},...h?{safeVersionConstraint:h}:{},ownerPackages:v,advisoryIds:k,reason:g==="direct"?"Resolve the direct dependency inside its declared compatibility boundary, then reconcile and verify the complete dependency transaction.":"Resolve the vulnerable transitive path through a compatible owner upgrade or a guarded package-manager constraint; never infer safety from an audit downgrade."});}return [...a.values()].sort((r,c)=>r.packageName.localeCompare(c.packageName))}function Re(e,t,i=1){let n=String(t??"unknown").toLowerCase();n==="low"?e.low+=i:n==="moderate"||n==="medium"?e.moderate+=i:n==="high"?e.high+=i:n==="critical"?e.critical+=i:e.unknown+=i;}function He(e,t){if(Array.isArray(e)){for(let n of e)He(n,t);return}if(!e||typeof e!="object")return;let i=e;t(i);for(let n of Object.values(i))He(n,t);}function to(e,t){if(t===0)return {disposition:"not-needed",compatibleFixAvailable:false,breakingFixAvailable:false,candidates:[]};let i=false,n=false,o=false,s=[];for(let[r,c]of e){let l=c&&typeof c=="object"?c:{};if(!Object.prototype.hasOwnProperty.call(l,"fixAvailable"))continue;i=true;let p=l.fixAvailable;if(p===true){n=true,s.push({packageName:r,breaking:false});continue}if(!p||typeof p!="object"||Array.isArray(p))continue;let g=p,v=typeof g.name=="string"&&g.name.trim()?g.name.trim():r,j=g.isSemVerMajor===true;n||=!j,o||=j,s.push({packageName:v,...typeof g.version=="string"&&g.version.trim()?{version:g.version.trim()}:{},breaking:j});}return {disposition:n?o?"mixed":"compatible":o?"breaking-only":i?"none":"unknown",compatibleFixAvailable:n,breakingFixAvailable:o,candidates:s.sort((r,c)=>`${r.packageName}@${r.version??""}`.localeCompare(`${c.packageName}@${c.version??""}`))}}function no(e,t){let i=s=>{let a=s.trim().match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?(?:\+.+)?$/);return a?[Number(a[1]),Number(a[2]),Number(a[3]),a[4]??""]:null},n=i(e),o=i(t);if(!n||!o)return null;for(let s=0;s<3;s+=1)if(n[s]!==o[s])return Number(n[s])>Number(o[s])?1:-1;return n[3]===o[3]?0:n[3]?o[3]?n[3].localeCompare(o[3]):-1:1}async function $n(e){let t=new Map;try{let i=await u.readJSON(d.join(e,"package-lock.json")),n=i.packages&&typeof i.packages=="object"&&!Array.isArray(i.packages)?i.packages:{};for(let[s,a]of Object.entries(n)){if(!s.startsWith("node_modules/"))continue;let r=s.replace(/^node_modules\//,"").split("/node_modules/").at(-1)?.trim()??"";if(!r)continue;let c=a&&typeof a=="object"?a:{};!t.has(r.toLowerCase())&&typeof c.version=="string"&&c.version.trim()&&t.set(r.toLowerCase(),c.version.trim());}let o=i.dependencies&&typeof i.dependencies=="object"&&!Array.isArray(i.dependencies)?i.dependencies:{};for(let[s,a]of Object.entries(o)){if(t.has(s.toLowerCase()))continue;let r=a&&typeof a=="object"?a:{};typeof r.version=="string"&&r.version.trim()&&t.set(s.toLowerCase(),r.version.trim());}}catch{}return t}async function io(e,t){if(t.disposition==="not-needed")return t;let i=await $n(e),n=new Map;for(let c of t.candidates){let l=i.get(c.packageName.toLowerCase());if(c.version&&l){let v=no(c.version,l);if(v!==null&&v<=0)continue}let p=`${c.packageName.toLowerCase()}\0${c.version??""}`,g=n.get(p);n.set(p,{packageName:g?.packageName??c.packageName,...c.version?{version:c.version}:{},breaking:!!(g?.breaking||c.breaking)});}let o=[...n.values()].sort((c,l)=>`${c.packageName}@${c.version??""}`.localeCompare(`${l.packageName}@${l.version??""}`)),s=o.some(c=>!c.breaking),a=o.some(c=>c.breaking);return {disposition:s?a?"mixed":"compatible":a?"breaking-only":"none",compatibleFixAvailable:s,breakingFixAvailable:a,candidates:o}}function oo(e){let t=me(e);if(!t){let c={...le},l=[],p=0,g=false;for(let v of e.split(/\r?\n/)){let j=me(v);if(!j)continue;let k=j.data&&typeof j.data=="object"?j.data:{};if(j.type==="auditAdvisory"){let y=k.advisory&&typeof k.advisory=="object"?k.advisory:{};p+=1,Re(c,y.severity);let h=ce({name:y.module_name??y.name,advisoryIds:[y.id,y.github_advisory_id,y.url],severities:[y.severity]});h&&l.push(h);}if(j.type==="auditSummary"){g=true;let y=Sn(k.vulnerabilities);if(Be(y)>=p)return {findingCount:Be(y),severityCounts:y,subjects:ae(l)}}}return p>0||g?{findingCount:p,severityCounts:c,subjects:ae(l)}:null}let i=t.metadata&&typeof t.metadata=="object"?t.metadata:null,n=Sn(i?.vulnerabilities),o=t.vulnerabilities&&typeof t.vulnerabilities=="object"?Object.entries(t.vulnerabilities):[],s=ae(o.map(([c,l])=>{let p=l&&typeof l=="object"?l:{},g=Array.isArray(p.via)?p.via:[];return ce({name:p.name??c,direct:p.isDirect,advisoryIds:g.flatMap(v=>{let j=v&&typeof v=="object"?v:{};return [j.source,j.url]}),severities:[p.severity]})}));if(Be(n)>0||i?.vulnerabilities){let c=Be(n);return {findingCount:c,severityCounts:n,subjects:s,remediation:to(o,c)}}let a=t.advisories&&typeof t.advisories=="object"?Object.entries(t.advisories):[],r=[];for(let[c,l]of a){let p=l&&typeof l=="object"?l:{};Re(n,p.severity);let g=ce({name:p.module_name??p.name,advisoryIds:[p.id,p.github_advisory_id,p.url,c],severities:[p.severity]});g&&r.push(g);}return {findingCount:a.length,severityCounts:n,subjects:ae([...s,...r])}}function ro(e){let t=(()=>{try{return JSON.parse(e.trim())}catch{return null}})(),i=Array.isArray(t)?t:t&&typeof t=="object"?t.dependencies:null;if(!Array.isArray(i))return null;let n={...le},o=[],s=0;for(let a of i){let r=a&&typeof a=="object"?a:{},c=Array.isArray(r.vulns)?r.vulns:[];if(s+=c.length,n.unknown+=c.length,c.length>0){let l=ce({name:r.name,version:r.version,advisoryIds:c.flatMap(p=>{let g=p&&typeof p=="object"?p:{};return [g.id,g.aliases].flatMap(v=>Array.isArray(v)?v:[v])}),severities:c.map(()=>"unknown")});l&&o.push(l);}}return {findingCount:s,severityCounts:n,subjects:ae(o)}}function so(e){if(!e.trim())return null;let t=new Set,i=new Map;for(let n of e.split(/\r?\n/)){let o=me(n),s=o?.osv&&typeof o.osv=="object"?o.osv:null;typeof s?.id=="string"&&t.add(s.id);let a=o?.finding&&typeof o.finding=="object"?o.finding:null;typeof a?.osv=="string"&&t.add(a.osv);let r=Array.isArray(a?.trace)?a.trace:[];for(let c of r){let l=c&&typeof c=="object"?c:{},p=typeof l.module=="string"?l.module:typeof l.package=="string"?l.package:"";if(!p)continue;let g=i.get(p)??{advisoryIds:new Set};typeof l.version=="string"&&(g.version=l.version),typeof a?.osv=="string"&&g.advisoryIds.add(a.osv),i.set(p,g);}}return {findingCount:t.size,severityCounts:{...le,unknown:t.size},subjects:[...i.entries()].map(([n,o])=>ce({name:n,version:o.version,advisoryIds:[...o.advisoryIds],severities:["unknown"]})).filter(n=>!!n)}}function ao(e){let t=me(e);if(!t)return null;let i=t.vulnerabilities&&typeof t.vulnerabilities=="object"?t.vulnerabilities:{},n=Array.isArray(i.list)?i.list:[],o={...le},s=[];for(let a of n){let r=a&&typeof a=="object"?a:{},c=r.advisory&&typeof r.advisory=="object"?r.advisory:{};Re(o,c.severity);let l=r.package&&typeof r.package=="object"?r.package:{},p=ce({name:l.name,version:l.version,advisoryIds:[c.id,c.url],severities:[c.severity]});p&&s.push(p);}return {findingCount:n.length,severityCounts:o,subjects:ae(s)}}function co(e){let t=me(e);if(!t)return null;let i=t.advisories&&typeof t.advisories=="object"?t.advisories:{},n={...le},o=0,s=[];for(let[a,r]of Object.entries(i)){let c=Array.isArray(r)?r:[r],l=ce({name:a,advisoryIds:c.flatMap(p=>{let g=p&&typeof p=="object"?p:{};return [g.advisoryId,g.cve,g.link]}),severities:c.map(p=>(p&&typeof p=="object"?p:{}).severity)});l&&s.push(l);}return He(i,a=>{(typeof a.advisoryId=="string"||typeof a.cve=="string")&&(o+=1,Re(n,a.severity));}),{findingCount:o,severityCounts:n,subjects:ae(s)}}function lo(e){let t=me(e);if(!t)return null;let i={...le},n=0,o=[];return He(t,s=>{if(!Array.isArray(s.vulnerabilities))return;for(let r of s.vulnerabilities){let c=r&&typeof r=="object"?r:{};n+=1,Re(i,c.severity);}let a=ce({name:s.id??s.name??s.packageId,version:s.resolvedVersion??s.version,direct:s.isTransitive===false,advisoryIds:s.vulnerabilities.flatMap(r=>{let c=r&&typeof r=="object"?r:{};return [c.advisoryurl,c.advisoryUrl,c.url]}),severities:s.vulnerabilities.map(r=>(r&&typeof r=="object"?r:{}).severity)});a&&o.push(a);}),{findingCount:n,severityCounts:i,subjects:ae(o)}}function uo(e){let t=me(e);if(!t)return null;let i={...le},n=new Set,o=[];return He(t,s=>{let a=s.id??s.cve??s.advisory??s.url;if(typeof a!="string")return;n.add(a),Re(i,s.severity??s.criticality);let r=s.gem&&typeof s.gem=="object"?s.gem:{},c=ce({name:r.name??s.gemName??s.name,version:r.version??s.version,advisoryIds:[a],severities:[s.severity??s.criticality]});c&&o.push(c);}),{findingCount:n.size,severityCounts:n.size>0&&Be(i)===0?{...i,unknown:n.size}:i,subjects:ae(o)}}function En(e,t){let i=`${e}
|
|
13
|
-
${t}`.trim();if(!i)return null;let n=i.match(/(?:found|total:?)\s+(\d+)\s+vulnerabilit/i),o=/no (?:known )?vulnerabilit|no retired packages found|no insecure dependencies found/i.test(i);if(!n&&!o)return null;let s=n?Number(n[1]):0;return {findingCount:s,severityCounts:{...le,unknown:s},subjects:[]}}function
|
|
14
|
-
${o.stderr}`);return {...n,invocation:i.invocation,exitCode:o.exitCode,status:c?"tool-unavailable":"failed",reason:c?`${i.tool} is not installed or not supported by the detected runtime version.`:`${i.tool} did not produce parseable vulnerability evidence.`}}if((e.runtime==="node"||e.runtime==="bun")&&s.remediation&&(s.remediation=await io(e.projectPath,s.remediation),s.findingCount>0&&!s.remediation.compatibleFixAvailable)){let c=await eo(e.projectPath,o.stdout);s.remediation.resolutionCandidates=c.length>0?c:Rn(s.subjects);}let a=s.severityCounts.moderate+s.severityCounts.high+s.severityCounts.critical+s.severityCounts.unknown,r=s.remediation??(s.findingCount===0?{disposition:"not-needed",compatibleFixAvailable:false,breakingFixAvailable:false,candidates:[]}:{disposition:"unknown",compatibleFixAvailable:false,breakingFixAvailable:false,candidates:[],resolutionCandidates:Rn(s.subjects)});return {...n,invocation:i.invocation,exitCode:o.exitCode,findingCount:s.findingCount,blockingFindingCount:a,severityCounts:s.severityCounts,subjects:s.subjects,remediation:r,status:s.findingCount>0?"vulnerable":"clean",reason:s.findingCount>0?`${i.tool} reported ${s.findingCount} known dependency vulnerability finding(s).`:`${i.tool} completed without known dependency vulnerability findings.`}}catch(o){return {...n,invocation:i.invocation,status:An(o)?"tool-unavailable":"failed",reason:An(o)?`${i.tool} is not installed or cannot be resolved from this project environment.`:`${i.tool} could not complete: ${o instanceof Error?o.message:String(o)}`}}}async function Fn(e){let t=await Yi(e.projectPath,e.runtime),i=At.get(t);if(i)return i;let n=fo(e);At.set(t,n);try{return await n}catch(o){throw At.delete(t),o}}var Mn="Graph paths identify evidence-backed structural reachability and verification candidates; they do not prove runtime causality or that every affected surface has been discovered.",Nn={dependency:["package","module"],security:["package","module"],test:["test-suite"],quality:["file","symbol","module"],container:["container"],deployment:["deployment","container","environment"],environment:["environment"],configuration:["environment","file"],runtime:["service","container","deployment"],"workspace-contract":["project","service","api","endpoint"],"source-tree":["file","module","symbol"],framework:["service","project","package"],custom:["project"],unknown:["project"]},go=new Set(["project","service","api","endpoint","schema","database","queue","container","deployment","pipeline","environment","document","decision","test-suite","owner"]),yo=new Set(["test-suite","pipeline"]);function Ft(e,t){if(!e)return ".";let i=d.relative(e,t).split(d.sep).join("/");return i&&!i.startsWith("../")?i:"."}function $t(e){return {id:e.id,kind:e.kind,label:e.label,...e.projectId?{projectId:e.projectId}:{}}}function Se(e,t,i,n={artifact:b$4}){return {schemaVersion:d$3,generatedAt:(e.now??new Date).toISOString(),status:t,claimBoundary:Mn,graph:n,project:{name:e.projectName,path:Ft(e.workspacePath,e.projectPath)},summary:{findingCount:0,rootEntityCount:0,affectedEntityCount:0,verificationTargetCount:0,proofPathCount:0,subjectCount:0,unresolvedSubjectCount:0,unknownCount:1},findings:[],diagnostics:[i]}}function ho(e,t){let i=Ft(t.workspacePath,t.projectPath).toLowerCase(),n=new Set([t.projectName,d.basename(t.projectPath),i].map(o=>o.trim().toLowerCase()).filter(Boolean));return e.entities.filter(o=>o.kind==="project").find(o=>[o.projectId,o.label,o.identity.key,...o.identity.aliases,typeof o.attributes.path=="string"?o.attributes.path:void 0].filter(a=>typeof a=="string").map(a=>a.toLowerCase()).some(a=>n.has(a)||n.has(d.basename(a))))}function ko(e,t){let i=t.projectId??t.label,n=e.entities.filter(a=>a.id===t.id||a.projectId===i||a.projectId===t.projectId),o=new Set(n.map(a=>a.id)),s=new Set;for(let a of e.relations)o.has(a.from)&&s.add(a.to),o.has(a.to)&&s.add(a.from);return e.entities.filter(a=>o.has(a.id)||s.has(a.id))}function vo(e){let t=new Map,i=(n,o)=>{let s=t.get(n)??[];s.push(o),t.set(n,s);};for(let n of e.relations)i(n.from,n.to),i(n.to,n.from);for(let n of t.values())n.sort();return t}function bo(e,t,i){let n=vo(e),o=new Set(t),s=t.map(a=>({id:a,depth:0}));for(let a=0;a<s.length;a+=1){let r=s[a];if(!(!r||r.depth>=i))for(let c of n.get(r.id)??[])o.has(c)||(o.add(c),s.push({id:c,depth:r.depth+1}));}return [...o]}function In(e){let t=["name","specifier","package","module"].flatMap(i=>{let n=e.attributes[i];return Array.isArray(n)?n:[n]});return new Set([e.label,...e.identity.aliases,...t].filter(i=>typeof i=="string").map(i=>i.trim().toLowerCase()).filter(Boolean))}function wo(e,t,i,n){let o=ko(e,t),s=Nn[i]??Nn.unknown,a=[...new Set(n.map(c=>c.trim().toLowerCase()).filter(Boolean))];if(a.length>0){let c=o.filter(p=>s?.includes(p.kind)&&a.some(g=>In(p).has(g))),l=new Set(a.filter(p=>c.some(g=>In(g).has(p))));return {roots:c.length>0?c.slice(0,12):[t],unresolvedSubjects:n.filter(p=>!l.has(p.trim().toLowerCase()))}}let r=o.filter(c=>s?.includes(c.kind)).slice(0,6);return {roots:r.length>0?r:[t],unresolvedSubjects:[]}}function jo(e,t,i){let n=i.issueClass??"unknown",o=[...new Set((i.subjects??[]).map(h=>h.trim()).filter(Boolean))],{roots:s,unresolvedSubjects:a}=wo(e,t,n,o),r=new Map(e.entities.map(h=>[h.id,h])),c=bo(e,s.map(h=>h.id),3).map(h=>r.get(h)).filter(h=>!!h),l=c.filter(h=>!s.some(w=>w.id===h.id)&&go.has(h.kind)).slice(0,20),p=c.filter(h=>yo.has(h.kind)).slice(0,8),v=[...l,...p].filter((h,w,b)=>b.findIndex(D=>D.id===h.id)===w).slice(0,12).flatMap(h=>{let b=s.map(D=>d$6(e,D.id,h.id)).filter(D=>D.found).sort((D,F)=>D.hops.length-F.hops.length)[0];return b?[{from:b.resolvedFrom??b.from,to:b.resolvedTo??b.to,entityPath:b.entityPath,hops:b.hops,proofIds:b.proofs.map(D=>D.id)}]:[]}),j=new Set([...s.flatMap(h=>h.proofIds),...v.flatMap(h=>h.proofIds)]),k=e.proofs.filter(h=>j.has(h.id)).map(h=>h.artifact).filter((h,w,b)=>b.indexOf(h)===w).sort().slice(0,20),y=[];return l.length===0&&y.push("No affected surface is structurally reachable from the selected root evidence."),p.length===0&&y.push("No graph-connected test suite or pipeline is available as a verification target."),k.length===0&&y.push("The selected graph entities do not carry portable source evidence."),a.length>0&&y.push(`No canonical graph entity resolved for ${a.length} reported subject(s): ${a.join(", ")}.`),{issueId:i.id,issueClass:n,status:i.status==="fail"?"fail":"warn",reason:i.reason,scope:"structural-impact-candidates",subjects:o,unresolvedSubjects:a,rootEntities:s.map($t),affectedEntities:l.map($t),verificationTargets:p.map($t),proofPaths:v,sourceArtifacts:k,unknowns:y}}async function Nt(e){if(!e.workspacePath)return Se(e,"graph-missing","Project is not attached to a Workspai workspace; no workspace graph can be consulted.");let t=d.join(e.workspacePath,b$4),i=d.join(e.workspacePath,a.model);if(!await u.pathExists(t))return Se(e,"graph-missing","Workspace knowledge graph is missing. Run workspace model before relying on graph-aware diagnosis.");if(!await u.pathExists(i))return Se(e,"model-missing","Canonical workspace model is missing, so graph source binding cannot be verified.");let n,o;try{let c=await u.readJSON(t),l=await u.readJSON(i);a$4(c,"contracts/workspace-intelligence/workspace-knowledge-graph.v1.json","Doctor graph diagnosis source"),a$4(l,"contracts/workspace-intelligence/workspace-model.v1.json","Doctor graph diagnosis model"),n=c,o=l;}catch(c){return Se(e,"invalid",`Graph-aware diagnosis rejected invalid evidence: ${c instanceof Error?c.message:String(c)}`)}let s={artifact:b$4,schemaVersion:n.schemaVersion,sourceArtifact:n.source.artifact,sourceHash:n.source.hash,entityCount:n.entities.length,relationCount:n.relations.length,proofCount:n.proofs.length};try{c$2(n,o);}catch(c){return Se(e,"stale",c instanceof Error?c.message:String(c),s)}let a$1=ho(n,e);if(!a$1)return Se(e,"project-unresolved","The current project could not be resolved to one canonical project entity.",s);let r=[...(e.probes??[]).filter(c=>c.status!=="pass"),...(e.issues??[]).map((c,l)=>({id:`legacy-project-issue-${l+1}`,status:"fail",reason:c,issueClass:"runtime"}))].map(c=>jo(n,a$1,c));return {schemaVersion:d$3,generatedAt:(e.now??new Date).toISOString(),status:"available",claimBoundary:Mn,graph:s,project:{name:e.projectName,path:Ft(e.workspacePath,e.projectPath),entityId:a$1.id},summary:{findingCount:r.length,rootEntityCount:new Set(r.flatMap(c=>c.rootEntities.map(l=>l.id))).size,affectedEntityCount:new Set(r.flatMap(c=>c.affectedEntities.map(l=>l.id))).size,verificationTargetCount:new Set(r.flatMap(c=>c.verificationTargets.map(l=>l.id))).size,proofPathCount:r.reduce((c,l)=>c+l.proofPaths.length,0),subjectCount:new Set(r.flatMap(c=>c.subjects)).size,unresolvedSubjectCount:new Set(r.flatMap(c=>c.unresolvedSubjects)).size,unknownCount:r.reduce((c,l)=>c+l.unknowns.length,0)},findings:r,diagnostics:[]}}var _t=a.doctor;function Qn(e){return [...new Set(e.filter(t=>t&&t.trim().length>0))]}function Tn(e){return [...new Set(e.filter(t=>t&&t.trim().length>0))]}function xo(){let e=t$1().map(n=>d.join(n,b$6()?"poetry.exe":"poetry")),t=b$6()?[d.join(process.env.APPDATA||"","Python","Scripts","poetry.exe"),d.join(process.env.USERPROFILE||"","AppData","Roaming","Python","Scripts","poetry.exe")]:[],i=b$6()?[]:["/usr/local/bin/poetry","/usr/bin/poetry"];return Qn([...e,...t,...i])}function Co(e,t=process.cwd()){let i=t$1().map(l=>({location:"Global (user-local)",path:d.join(l,b$6()?"rapidkit.exe":"rapidkit")})),n$1=[{location:"Global (pipx)",path:d.join(e,".local","bin","rapidkit")},{location:"Global (pipx)",path:d.join(e,"AppData","Roaming","Python","Scripts","rapidkit.exe")},{location:"Global (pyenv)",path:d.join(e,".pyenv","shims","rapidkit")},{location:"Global (system)",path:"/usr/local/bin/rapidkit"},{location:"Global (system)",path:"/usr/bin/rapidkit"}],o=n(d.join(t,".venv")),s=p(t),a=[{location:"Workspace (.venv)",path:o},...s.map(l=>({location:"Workspace (launcher)",path:l}))],r=[...i,...n$1,...a],c=new Set;return r.filter(l=>c.has(l.path)?false:(c.add(l.path),true))}function Po(e){let t=new Map([["Workspace (.venv)",0],["Global (user-local)",1],["Global (pipx)",2],["Global (pyenv)",3],["Global (system)",4]]);return [...e].sort((i,n)=>{let o=t.get(i.location)??Number.MAX_SAFE_INTEGER,s=t.get(n.location)??Number.MAX_SAFE_INTEGER;return o!==s?o-s:i.path.localeCompare(n.path)})}function On(e,t){if(e.status!=="error")return e;let i=[e.details,t].filter(n=>typeof n=="string"&&n.trim().length>0).join(" ");return {...e,status:"warn",...i?{details:i}:{}}}function Xn(e,t){let i=t.some(n=>n.runtimeFamily==="python");return {...e,python:i?e.python:On(e.python,"Python is optional because this scope has no detected Python project."),rapidkitCore:/not installed/i.test(e.rapidkitCore.message)?On(e.rapidkitCore,"RapidKit Core is an optional engine for Python-backed kits and modules; Workspai CLI diagnostics remain available without it."):e.rapidkitCore}}function Do(e){let i=(e.probes??[]).filter(a=>a.status==="warn").length,n=e.issues.some(a=>a.toLowerCase().includes("environment file missing")),o=(e.probes??[]).some(a=>a.id==="surface-env-contract"),s=(e.probes??[]).some(a=>a.id==="surface-security-hygiene");return e.hasEnvFile===false&&!n&&!o&&(i+=1),typeof e.vulnerabilities=="number"&&e.vulnerabilities>0&&!s&&(i+=1),i}function Ro(e){let t=e.coreVersion?.split(".")[0],i=e.npmVersion?.split(".")[0];return !t||!i?false:t!==i}var So="doctor-project-scan-v2",Eo="doctor-project-scan-policy-v1",ei=d$2.doctorWorkspaceCache.schemaVersion,Ao=Object.freeze({version:"doctor-evidence-v1",scoringPolicyVersion:"doctor-score-policy-v2",generatedBy:"workspai",deterministicScoreBreakdown:true,scopeModel:"workspace-aggregate-or-project-scoped"}),Le=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 $e(){return {...Ao}}function mt(e){let t=e.profile?.trim();return t&&t in Le?{...Le[t]}:e.strict?{...Le.release}:e.ci?{...Le.ci}:{...Le.local}}function ut(e){return !e||e.total<=0?null:Math.round(e.passed/e.total*100)}function $o(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 Fo(e,t){let i=$o(e),n=Date.parse(t),o=typeof i.ttlSeconds=="number"?i.ttlSeconds*1e3:null,s=o!==null&&Number.isFinite(n)?new Date(n+o).toISOString():void 0,a=!Number.isFinite(n)||o!==null&&!s?"unknown":o!==null&&Date.now()>n+o?"stale":"fresh";return {category:i.category,generatedAt:t,ttlSeconds:i.ttlSeconds,...s?{expiresAt:s}:{},status:a,verifyBeforeUse:i.category!=="structure"||a!=="fresh",reason:i.reason}}function No(e){let t=e.id.toLowerCase(),i=`${e.label} ${e.reason} ${e.recommendation??""}`.toLowerCase();return t.includes("dependency")||t.includes("lockfile")||i.includes("lockfile")?"dependency":t.includes("security")||i.includes("vulnerabilit")||i.includes("audit")?"security":t.includes("env")||i.includes(".env")||i.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 ti(e){let t=e.dependencyAudit?.subjects.map(i=>i.name)??[];return (e.probes??[]).map(i=>({...i,...i.id==="surface-security-hygiene"&&t.length>0?{subjects:t}:{}}))}function Io(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 Mo(e){let{probe:t,freshness:i}=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(i.status!=="fresh")return {mode:"refresh-evidence",confidence:"high",primaryActionLabel:"Refresh evidence",requiresApproval:false,requiresFreshEvidence:true,reason:`Evidence is ${i.status}; refresh Doctor before applying repairs.`,relatedCommands:["npx workspai doctor project --json"]};if(n?.status==="manual"||n?.requiresReview)return {mode:"review-required",confidence:"medium",primaryActionLabel:"Review fix path",requiresApproval:true,requiresFreshEvidence:i.verifyBeforeUse,reason:n?.reason??t.recommendation??t.reason,relatedCommands:Tn(n?.refreshCommands??["npx workspai doctor project --json"])};if(i.verifyBeforeUse&&i.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:i.verifyBeforeUse,reason:n.reason,relatedCommands:Tn([...n.command?[n.command]:[],...n.verifyCommand?[n.verifyCommand]:[],...n.refreshCommands])}}return t.recommendation?{mode:"manual-guidance",confidence:"medium",primaryActionLabel:"Inspect guidance",requiresApproval:false,requiresFreshEvidence:i.verifyBeforeUse,reason:t.recommendation,relatedCommands:["npx workspai doctor project --json"]}:{mode:"manual-guidance",confidence:"low",primaryActionLabel:"Inspect issue",requiresApproval:false,requiresFreshEvidence:i.verifyBeforeUse,reason:"Doctor classified the issue but does not have a deterministic repair path yet.",relatedCommands:["npx workspai doctor project --json"]}}function ni(e,t){let i=Fo(e,e.freshness?.generatedAt??t),n=e.issueClass??No(e),o=e.operationalImpact??Io(e,n),s=Mo({probe:e,freshness:i});return {...e,freshness:i,issueClass:n,operationalImpact:o,repairIntent:s}}function _n(e,t){Array.isArray(e.probes)&&(e.probes=e.probes.map(i=>ni(i,t)));}function ii(e,t){let i=e.flatMap(c=>Array.isArray(c.probes)?c.probes.map(l=>l.freshness).filter(l=>!!l):[]),n=i.filter(c=>c.status==="stale").length,o=i.filter(c=>c.status==="unknown").length,s=i.filter(c=>c.category==="state").length,a=i.filter(c=>c.verifyBeforeUse).length,r=i.map(c=>c.generatedAt).filter(Boolean).sort()[0];return {generatedAt:t,status:n>0?"stale":o>0?"unknown":"fresh",staleProbeCount:n,unknownProbeCount:o,liveStateProbeCount:s,verifyBeforeUseProbeCount:a,...r?{oldestProbeGeneratedAt:r}:{}}}function oi(e){return typeof e=="number"?e:Array.isArray(e)?e.length:0}async function ri(e,t){try{if(!await u.pathExists(e))return null;let i=await u.readJSON(e);return c$3(i,t)?i:null}catch{return null}}function si(e,t){if(!e?.system)return [];let i=[{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 i){let s=e.system?.[o.id]?.status;!s||s===o.current.status||n.push({id:o.id,from:s,to:o.current.status});}return n}function To(e,t){let i=new Map;for(let v of t.projects)i.set(v.path||v.name,v.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 v of n){let j=v.path||v.name;j&&o.set(j,oi(v.issues));}let s=0,a=0,r=new Set,c=new Set,l=new Set([...Array.from(o.keys()),...Array.from(i.keys())]);for(let v of l){let j=o.get(v)??0,k=i.get(v)??0;k>j?(s+=k-j,r.add(v)):k<j&&(a+=j-k,c.add(v));}let p=ut(e.healthScore),g=ut(t.healthScore);return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:s,resolvedIssueCount:a,netIssueDelta:s-a,scoreDeltaPercent:p===null||g===null?null:g-p,systemStatusChanges:si(e,{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore}),regressedProjects:Array.from(r).sort(),improvedProjects:Array.from(c).sort()}}function Oo(e,t){if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let i=oi(e.project?.issues),n=t.project.issues.length,o=Math.max(n-i,0),s=Math.max(i-n,0),a=ut(e.healthScore),r=ut(t.healthScore),c=t.project.path||t.project.name;return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:o,resolvedIssueCount:s,netIssueDelta:o-s,scoreDeltaPercent:a===null||r===null?null:r-a,systemStatusChanges:si(e,{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore}),regressedProjects:o>0?[c]:[],improvedProjects:s>0?[c]:[]}}function ai(e){let t=e??[],i=0,n=0;for(let a of t){if(a.scope==="project-scoped"){i+=1;continue}(a.scope==="workspace-aggregate"||a.scope==="host-system")&&(n+=1);}let o=i>0&&n>0?1:0,s=o>0?"mixed":i>0?"scoped":n>0?"aggregated":"unknown";return {scopedCount:i,aggregatedCount:n,mixedCount:o,dominantScope:s}}function q(e,t){return b$6()?`Set-Location -LiteralPath "${e.replace(/"/g,'`"')}"; ${t}`:`cd '${e.replace(/'/g,`'"'"'`)}' && ${t}`}function de(e){return b$6()?q(e,"Copy-Item .env.example .env"):q(e,"cp .env.example .env")}function Gn(e){return q(e,"poetry install --no-root")}function _o(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==="C"||e==="C++"||e==="Deno"||e==="Bun"||e==="PHP"||e==="Laravel"||e==="Ruby"||e==="Ruby on Rails"||e==="ASP.NET"?"extended":"observed"}function Go(e){return e==="Tauri"||e==="Electron"?"desktop":e==="VS Code Extension"?"extension":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"||e==="Go"||e==="Java"||e==="Scala"||e==="Kotlin"||e==="C"||e==="C++"?"generic":"backend"}function Ko(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==="Express"||e==="Fastify"||e==="Koa"||e==="Tauri"||e==="Electron"||e==="VS Code Extension"||e==="Node.js"?"node":e==="Bun"?"bun":e==="FastAPI"||e==="Django"||e==="Flask"||e==="Python"?"python":e==="Go/Fiber"||e==="Go/Gin"||e==="Go"||e==="Echo"?"go":e==="Spring Boot"||e==="Java"?"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":e==="Scala"?"scala":e==="Kotlin"?"kotlin":e==="C"?"c":e==="C++"?"cpp":"unknown"}function Gt(e,t){let i=w(t);e.commandCapabilities=i,e.supportTier=i.frameworkSupportTier;}function lt(e,t,i,n){e.framework=t,e.frameworkConfidence=i,e.supportTier=_o(t),e.projectKind=Go(t),e.runtimeFamily=Ko(t);}function ci(e){return e==="python"?"python":e==="node"?"node":e==="bun"?"bun":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":e==="scala"?"scala":e==="kotlin"?"kotlin":e==="c"?"c":e==="cpp"?"cpp":"unknown"}function Bt(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 "tauri":return "Tauri";case "electron":return "Electron";case "vscode-extension":return "VS Code Extension";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":return e.key==="sinatra"?"Ruby":"PHP";case "c":return "C";case "cpp":return "C++";case "unknown":return "Unknown";default:return "Unknown"}}function Wo(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 Bo(e,t){e.framework=Bt(t),e.frameworkKey=t.key,e.importStack=t.importStack,e.frameworkConfidence=t.confidence,e.supportTier=t.supportTier,e.projectKind="frontend",e.runtimeFamily=ci(t.runtime);}function ee(e,t){e.framework=Bt(t),e.frameworkKey=t.key,e.importStack=t.importStack,e.frameworkConfidence=t.confidence,e.supportTier=t.supportTier,e.projectKind=t.key==="tauri"||t.key==="electron"?"desktop":t.key==="vscode-extension"?"extension":Wo(t)?"generic":"backend",e.runtimeFamily=ci(t.runtime);}function Ho(e){let t=e.dependencies,i=e.scripts??{},n=(e.kitName??"").toLowerCase(),o=a=>!!t[a],s=Object.values(i).filter(a=>typeof a=="string").join(" ").toLowerCase();return o("next")||s.includes("next ")?{framework:"Next.js",confidence:"high"}:o("nuxt")||s.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")||s.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 qo(e,t){let i=j$3(e,t??null);return i.runtime!=="python"?{framework:"Python",confidence:"low"}:{framework:Bt(i),confidence:i.confidence}}async function Kn(e){try{let t=await u.stat(e);return `${d.basename(e)}:${t.isDirectory()?"d":"f"}:${t.size}:${t.mtimeMs}`}catch{return `${d.basename(e)}:missing`}}async function Lo(e){try{let t=new Set([".git",".venv","node_modules",".workspai",".rapidkit","dist","build","coverage","__pycache__"]),i=new Set,n=async a=>{if(await ze(a))return true;let r=["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 c of r){if(c==="*.csproj"){if((await u.readdir(a).catch(()=>[])).some(p=>p.endsWith(".csproj")))return true;continue}if(await u.pathExists(d.join(a,c)))return true}return false};await ze(e)&&i.add(e);let o=await a$2(e);for(let a of o){let r=d.isAbsolute(a.path)?a.path:d.join(e,a.path);await n(r)&&i.add(r);}return (await a$3(e,{skipDirs:t,descendIntoMatchedProjects:false,isProjectDir:async(a,r)=>d.resolve(a)===d.resolve(r)?ze(a):n(a)})).forEach(a=>i.add(a)),i.size===0&&(await dr(e,3,t)).forEach(r=>i.add(r)),i.size===0&&!await b$2(e)&&await n(e)&&i.add(e),Array.from(i).sort((a,r)=>a.localeCompare(r))}catch{return []}}async function Vo(e,t){let i=[d.join(e,".workspai-workspace"),d.join(e,".workspai","workspace.json"),d.join(e,".workspai","imported-projects.json"),d.join(e,".workspai","policies.yml"),d.join(e,".workspai","toolchain.lock"),d.join(e,".workspai","cache-config.yml"),d.join(e,".rapidkit-workspace"),d.join(e,".rapidkit","workspace.json"),d.join(e,".rapidkit","imported-projects.json"),d.join(e,".rapidkit","policies.yml"),d.join(e,".rapidkit","toolchain.lock"),d.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(i.map(Kn)),s=await Promise.all(t.map(async a=>{let r=await Promise.all(n.map(c=>Kn(d.join(a,c))));return `${a}::${r.join("|")}`}));return [So,Eo,...o,...s].join("||")}async function Jo(e,t){try{if(!await u.pathExists(e))return null;let i=await u.readJSON(e);a$4(i,"contracts/doctor-workspace-cache.v2.json",`Doctor workspace cache ${e}`);let n=i;return !n||n.signature!==t||!Array.isArray(n.projects)||typeof n.schemaVersion=="string"&&n.schemaVersion!==ei?null:n}catch{return null}}async function zo(e,t){try{a$4(t,"contracts/doctor-workspace-cache.v2.json",`Doctor workspace cache ${e}`),await u.ensureDir(d.dirname(e)),await u.writeJSON(e,t,{spaces:2});}catch{}}async function Uo(e,t,i){let n=d.join(e,_t);try{let o=[];for(let l of t.projects){for(let p of l.issues??[])typeof p=="string"&&p.trim()&&o.push(`${l.name}: ${p.trim()}`);for(let p of l.probes??[])p.status==="fail"&&p.reason.trim()&&o.push(`${l.name}: ${p.reason.trim()}`);}for(let[l,p]of [["python",t.python],["rapidkitCore",t.rapidkitCore]])if(p?.status==="error"){let g=typeof p.message=="string"?p.message:`${l} check failed`;o.push(`${l}: ${g}`);}let s=t.projects.map(te),a=s.reduce((l,p)=>l+p.blockingFindings,0),r=s.reduce((l,p)=>l+p.advisoryFindings,0),c=f$1({schemaVersion:a$5,evidenceType:"workspace",contract:$e(),policyProfile:t.policyProfile,workspacePath:e,workspaceName:t.workspaceName,projectScanCached:t.projectScanCached??false,projectScanSignature:t.projectScanSignature,cachePath:i,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((l,p)=>l+p.issues.length,0),verdict:t.healthScore?.verdict??"passed",blockingFindings:a,advisoryFindings:r,projectAdvisoryWarningProjects:s.filter(l=>l.advisoryFindings>0).length,projectAdvisoryWarnings:r,hasSystemErrors:[t.python,t.rapidkitCore].some(l=>l.status==="error"),scopeProvenance:t.scopeProvenance},driftDelta:t.driftDelta,scoreBreakdown:t.scoreBreakdown??[]},{commandId:"checkWorkspaceHealth",exitCode:Ze(t.healthScore,{profile:t.policyProfile?.name}),generatedAt:new Date().toISOString(),blockers:o.slice(0,12),runId:e$2()});return d$4(c),await e$1(e,_t,c),n}catch(o){if(o instanceof Error&&o.message.includes("violates contracts/"))throw o;return}}async function Ht(e=process.cwd()){let[t,i,n,o,s]=await Promise.all([Zo(),Yo(),Qo(),Xo(),er(e)]);return {python:t,poetry:i,pipx:n,go:o,rapidkitCore:s}}async function Zo(){let e=j$2(),t;for(let i of e)try{let n=i==="py"?["-3","--version"]:["--version"],{stdout:o,stderr:s}=await execa(i,n,{timeout:3e3,reject:false}),r=`${o??""}
|
|
15
|
-
${s??""}`.match(/Python\s+(\d+\.\d+(?:\.\d+)?)/i);if(r){let c=r[1],[l,p]=c.split(".").map(Number);if(l<3||l===3&&p<10){t??={version:c,command:[i,...n.slice(0,-1)].join(" ")};continue}return {status:"ok",message:`Python ${c}`,details:`Using ${[i,...n.slice(0,-1)].join(" ")}`}}}catch{continue}return t?{status:"warn",message:`Python ${t.version} (requires 3.10+)`,details:`${t.command} found but version is below minimum requirement`}:{status:"error",message:"Python not found",details:"Install Python 3.10+ and ensure it's in PATH"}}async function
|
|
16
|
-
${n.stderr??""}`),s=new Set(["pip","setuptools","wheel"]),a=o?.some(r=>typeof r.name=="string"&&!s.has(r.name.toLowerCase()))??false;return {interpreter:t,coreVersion:i,dependenciesInstalled:a}}catch{return {interpreter:t,coreVersion:i,dependenciesInstalled:false}}}return {dependenciesInstalled:false}}async function ir(e,t,i){let n=d.join(e,".venv");if(await u.pathExists(n))return {environmentPath:n,...await Wn({environmentPath:n,frameworkImport:t})};if(i)try{let o=await execa("poetry",["env","info","--path"],{cwd:e,timeout:3e3,reject:false}),s=o.stdout.trim();if(o.exitCode===0&&s&&await u.pathExists(s))return {environmentPath:s,...await Wn({environmentPath:s,frameworkImport:t})}}catch{}return {dependenciesInstalled:false}}function O(e,t){e.probes||(e.probes=[]);let i=ni(t,new Date().toISOString());e.probes.push(i),i.repairCapability&&(e.repairCapabilities||(e.repairCapabilities=[]),e.repairCapabilities.push(i.repairCapability),i.repairCapability.status==="available"&&i.repairCapability.canAutoFix&&i.repairCapability.command&&(e.fixCommands=e.fixCommands??[],e.fixCommands.includes(i.repairCapability.command)||e.fixCommands.push(i.repairCapability.command)));}async function Je(e,t){return (await Promise.all(t.map(i=>u.pathExists(d.join(e,i))))).some(Boolean)}async function It(e,t){let i=new Set(t.ignoreDirs??["node_modules",".git","bin","obj","dist"]),o=(t.under&&t.under.length>0?t.under:["."]).map(s=>d.join(e,s));for(;o.length>0;){let s=o.shift(),a;try{a=await u.readdir(s,{withFileTypes:true});}catch{continue}for(let r of a){if(r.isFile()&&(t.name&&r.name===t.name||t.suffix&&r.name.endsWith(t.suffix)))return true;r.isDirectory()&&!i.has(r.name)&&o.push(d.join(s,r.name));}}return false}async function or(e,t){let i=t.runtimeFamily||"unknown";if(t.projectKind==="backend"||t.projectKind==="generic"||t.projectKind==="desktop"||t.projectKind==="extension"){if(i==="node"){let o=await u.pathExists(d.join(e,"package-lock.json"))||await u.pathExists(d.join(e,"pnpm-lock.yaml"))||await u.pathExists(d.join(e,"yarn.lock"));O(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 s=t.projectKind==="extension"?["src/extension.ts","src/extension.js","extension.ts","extension.js"]:t.projectKind==="desktop"?["src/main.ts","src/main.js","src/index.ts","src/index.js","src-tauri/src/main.rs"]:["src/main.ts","src/main.js","src/server.ts","src/server.js","server.ts","server.js","index.ts","index.js"],a=await Je(e,s);O(t,{id:"adapter-node-boot-entrypoint",label:t.projectKind==="extension"?"Extension activation entrypoint":t.projectKind==="desktop"?"Desktop application entrypoint":"Node adapter boot entrypoint",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?`${t.projectKind==="extension"?"Extension":t.projectKind==="desktop"?"Desktop application":"Service"} entrypoint markers detected.`:`No canonical ${t.projectKind==="extension"?"extension activation":t.projectKind==="desktop"?"desktop application":"Node boot"} entrypoint markers detected.`,recommendation:a?void 0:t.projectKind==="extension"?"Expose the extension activation module declared by package.json.":t.projectKind==="desktop"?"Expose and document the desktop main-process or Tauri entrypoint.":"Define and document service bootstrap entrypoint (main/server)."});return}if(i==="python"){let o=await u.pathExists(d.join(e,"poetry.lock"))||await u.pathExists(d.join(e,"requirements.txt"))||await u.pathExists(d.join(e,"uv.lock"));O(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 Je(e,["src/main.py","src/app/main.py","app/main.py","main.py","manage.py","asgi.py","wsgi.py"]);O(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(i==="java"){let o=await u.pathExists(d.join(e,"mvnw"))||await u.pathExists(d.join(e,"gradlew"));O(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."});let s=await Je(e,["src/main/java/Application.java","src/main/kotlin/Application.kt"])||await It(e,{suffix:"Application.java",under:["src/main/java"]})||await It(e,{suffix:"Application.kt",under:["src/main/kotlin"]});O(t,{id:"adapter-java-boot-entrypoint",label:"Java adapter boot entrypoint",status:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Java application entrypoint markers detected.":"No Java application entrypoint markers detected.",recommendation:s?void 0:"Expose a Spring Boot Application class under src/main/java or src/main/kotlin."});return}if(i==="go"){let o=await u.pathExists(d.join(e,"go.sum"));O(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."});let s=await Je(e,["cmd/server/main.go","cmd/api/main.go","main.go"]);O(t,{id:"adapter-go-boot-entrypoint",label:"Go adapter boot entrypoint",status:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Go application entrypoint markers detected.":"No Go application entrypoint markers detected.",recommendation:s?void 0:"Expose a Go main package entrypoint such as cmd/server/main.go."});return}if(i==="dotnet"){let o=await Je(e,["Program.cs","src/Program.cs"])||await It(e,{name:"Program.cs"});O(t,{id:"adapter-dotnet-boot-entrypoint",label:".NET adapter boot entrypoint",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?".NET application entrypoint markers detected.":"No .NET application entrypoint markers detected.",recommendation:o?void 0:"Expose Program.cs at the project root or under src for deterministic boot probes."});}}}async function rr(e,t){let i=[d.join(e,".workspai","doctor.adapters.json"),d.join(e,".rapidkit","doctor.adapters.json"),d.join(e,"doctor.adapters.json")];for(let n of i)if(await u.pathExists(n))try{let o=await u.readJSON(n),s=Array.isArray(o?.checks)?o.checks:[];for(let a=0;a<s.length;a+=1){let r=s[a]||{},c=Array.isArray(r.runtimes)?r.runtimes:[];if(c.length>0&&!c.includes(t.runtimeFamily||"unknown"))continue;let l=typeof r.id=="string"&&r.id.trim().length>0?r.id.trim():`adapter-check-${a+1}`,p=typeof r.label=="string"&&r.label.trim().length>0?r.label.trim():l,g=r.severity||"warn",v=Array.isArray(r.anyOfPaths)?r.anyOfPaths.filter(Boolean):[],j=Array.isArray(r.allOfPaths)?r.allOfPaths.filter(Boolean):[],k=v.length===0;for(let w of v)if(await u.pathExists(d.join(e,w))){k=true;break}let y=true;for(let w of j)if(!await u.pathExists(d.join(e,w))){y=false;break}let h=k&&y;O(t,{id:l,label:p,status:h?"pass":g==="error"?"fail":"warn",severity:g,scope:"project-scoped",reason:h?r.passReason||"Custom adapter contract satisfied.":r.failReason||`Custom adapter check failed from ${d.basename(n)}.`,recommendation:r.recommendation});}}catch{O(t,{id:"custom-adapter-config",label:"Custom doctor adapter configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${d.basename(n)}.`,recommendation:"Fix JSON syntax in doctor.adapters.json to re-enable adapter checks."});}}async function U(e,t){if(!(t.projectKind==="backend"||t.projectKind==="generic"))return;let n=d.join(e,".env"),o=d.join(e,".env.example"),s=await u.pathExists(n)||await u.pathExists(o)||await u.pathExists(d.join(e,"config"));O(t,{id:"config-surface",label:"Configuration contract surface",status:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Configuration artifacts detected (.env/.env.example/config).":"No explicit configuration contract artifacts detected.",recommendation:s?void 0:"Add .env.example or explicit config contract documentation for deterministic setup."});let a={python:["alembic.ini","migrations","versions"],node:["prisma/schema.prisma","migrations","typeorm.config.ts","typeorm.config.js"],bun:["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"],scala:["src/main/resources/db/migration","conf/evolutions"],kotlin:["src/main/resources/db/migration","src/main/resources/liquibase"],c:["migrations","db/migrations"],cpp:["migrations","db/migrations"],unknown:["migrations"]},r=t.runtimeFamily||"unknown",c=a[r]||a.unknown,l=false;for(let v of c)if(await u.pathExists(d.join(e,v))){l=true;break}O(t,{id:"migration-surface",label:"Migration/readiness surface",status:l?"pass":"warn",severity:"warn",scope:"project-scoped",reason:l?"Migration or schema evolution markers detected.":"No migration markers detected for this backend runtime.",recommendation:l?void 0:"Add migration tooling baseline (migrations dir or runtime-native migration config)."});let p=["src/health","src/healthcheck","src/main/resources/application.yml","src/main/resources/application.properties","app/health.py","routes/health.ts","routes/health.js"],g=false;for(let v of p)if(await u.pathExists(d.join(e,v))){g=true;break}O(t,{id:"runtime-health-surface",label:"Runtime health probe surface",status:g?"pass":"warn",severity:"warn",scope:"project-scoped",reason:g?"Health endpoint/config markers detected.":"No explicit runtime health endpoint markers detected.",recommendation:g?void 0:"Expose a deterministic health endpoint and keep it covered in verify pack."}),await or(e,t);}async function sr(e,t,i,n){let o=await Pn({projectPath:e,detection:n,packageJsonData:i});for(let s of o)O(t,s);}async function Z(e,t,i){let n=await Dn({projectPath:e,runtimeFamily:t.runtimeFamily,projectKind:t.projectKind,packageJsonData:i,hasTests:t.hasTests,vulnerabilities:t.vulnerabilities,dependencyAudit:t.dependencyAudit});for(let o of n)O(t,o);}async function Y(e,t){let i=[d.join(e,".workspai","doctor.probes.json"),d.join(e,".rapidkit","doctor.probes.json"),d.join(e,"doctor.probes.json")];for(let n of i)if(await u.pathExists(n))try{let o=await u.readJSON(n),s=Array.isArray(o?.probes)?o.probes:[];for(let a=0;a<s.length;a+=1){let r=s[a]||{},c=typeof r.id=="string"&&r.id.trim().length>0?r.id.trim():`custom-probe-${a+1}`,l=typeof r.label=="string"&&r.label.trim().length>0?r.label.trim():c,p=r.severity||"warn",g=Array.isArray(r.anyOfPaths)?r.anyOfPaths.filter(Boolean):[],v=Array.isArray(r.allOfPaths)?r.allOfPaths.filter(Boolean):[],j=g.length===0;for(let h of g)if(await u.pathExists(d.join(e,h))){j=true;break}let k=true;for(let h of v)if(!await u.pathExists(d.join(e,h))){k=false;break}let y=j&&k;O(t,{id:c,label:l,status:y?"pass":p==="error"?"fail":"warn",severity:p,scope:"project-scoped",reason:y?"Custom probe contract satisfied.":`Custom probe failed from ${d.basename(n)}.`,recommendation:r.recommendation});}}catch{O(t,{id:"custom-probe-config",label:"Custom doctor probe configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${d.basename(n)}.`,recommendation:"Fix JSON syntax in doctor.probes.json to re-enable custom probes."});}await rr(e,t);}async function ar(e,t$1={}){let n={name:d.basename(e),path:e,venvActive:false,depsInstalled:false,coreInstalled:false,issues:[],fixCommands:[]},o=t$1.allowNonRapidkit===true;if(!(await u.pathExists(d.join(e,".workspai"))||await u.pathExists(d.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 C=d.join(e,"registry.json");if(await u.pathExists(C)){let S=await u.readJson(C);S.installed_modules&&(n.stats={modules:S.installed_modules.length});}}catch{}try{let{auditProjectModulePaths:C}=await import('./module-layout-NZ43RSC5.js'),S=await C(e);if(S.issues.length>0){for(let I of S.issues)n.issues.push(`${I.message} (${I.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 a=null;try{for(let C of t(e,"project.json")){if(!await u.pathExists(C))continue;a=await u.readJson(C);let S=a?.kit_name||a?.kit;S&&(n.kit=S);break}}catch{}try{let C=d.join(e,".git");if(await u.pathExists(C)){let{stdout:S}=await execa("git",["log","-1","--format=%cr"],{cwd:e,reject:false,env:a$7()});S&&(n.lastModified=S.trim());}else {let S=await u.stat(e),T=Date.now()-S.mtime.getTime(),_=Math.floor(T/(1e3*60*60*24));n.lastModified=_===0?"today":`${_} day${_>1?"s":""} ago`;}}catch{}let r=d.join(e,"package.json"),c=d.join(e,"pyproject.toml"),l=d.join(e,"requirements.txt"),p=d.join(e,"go.mod"),g=d.join(e,"pom.xml"),v=d.join(e,"build.sbt"),j=d.join(e,"Cargo.toml"),k=d.join(e,"mix.exs"),y=d.join(e,"deps.edn"),h=d.join(e,"project.clj"),w=d.join(e,"deno.json"),b=d.join(e,"deno.jsonc"),D=d.join(e,"bun.lockb"),F=d.join(e,"bun.lock"),f=d.join(e,"composer.json"),R=d.join(e,"Gemfile"),x=await u.pathExists(r),B=await u.pathExists(c)||await u.pathExists(l),P=await u.pathExists(f),L=await u.pathExists(R),M=await u.pathExists(j),ne=await u.pathExists(k),Ye=await u.pathExists(y)||await u.pathExists(h),Qe=await u.pathExists(v),Xe=await u.pathExists(w)||await u.pathExists(b),V=a?.runtime==="dotnet";try{V=V||await Bn(e,".csproj",3)||await Bn(e,".sln",2);}catch{V=a?.runtime==="dotnet";}let Me=await u.pathExists(p)||a?.runtime==="go"||typeof a?.kit_name=="string"&&(a.kit_name.startsWith("gofiber")||a.kit_name.startsWith("gogin")),ge=x&&(await u.pathExists(D)||await u.pathExists(F)||typeof a?.packageManager=="string"&&(a?.packageManager).toLowerCase().startsWith("bun@"));if(Me){ee(n,j$3(e,a??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/");}let C=d.join(e,"go.sum");return await u.pathExists(C)?n.depsInstalled=true:(n.depsInstalled=false,n.issues.push("Go dependencies not downloaded (go.sum missing)"),n.fixCommands?.push(q(e,"go mod tidy"))),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(await u.pathExists(g)||a?.runtime==="java"||typeof a?.kit_name=="string"&&a.kit_name.startsWith("springboot")){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=await u.pathExists(g),S=await u.pathExists(d.join(e,"build.gradle"))||await u.pathExists(d.join(e,"build.gradle.kts")),I=await u.pathExists(d.join(e,"mvnw"))||await u.pathExists(d.join(e,"mvnw.cmd")),T=await u.pathExists(d.join(e,"gradlew"))||await u.pathExists(d.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");}if(C){if(!I)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");}}else if(S&&!T)try{await execa("gradle",["--version"],{timeout:3e3,reject:false});}catch{n.issues.push("Gradle not found \u2014 install Gradle 8+ or add Gradle Wrapper");}let _=d.join(e,"target"),ie=d.join(e,"build","libs"),ue=d.join(e,".workspai","cache","java","m2"),E=d.join(e,".workspai","cache","java","gradle");if(n.depsInstalled=await u.pathExists(_)||await u.pathExists(ie)||await u.pathExists(ue)||await u.pathExists(E),!n.depsInstalled){n.issues.push("Java dependencies are not warmed or built yet");let we=C?I?b$6()?".\\mvnw.cmd -B -DskipTests dependency:go-offline":"./mvnw -B -DskipTests dependency:go-offline":"mvn -B -DskipTests dependency:go-offline":T?b$6()?".\\gradlew.bat dependencies":"./gradlew dependencies":"gradle dependencies";n.fixCommands?.push(q(e,we));}let H=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(H),!n.hasEnvFile){let we=d.join(e,".env.example");await u.pathExists(we)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}let oe=d.join(e,"src","main","resources","application.yml");if(await u.pathExists(oe))try{let we=await u.readFile(oe,"utf-8");/include:\s*[^\n]*health/i.test(we)||/management:\s*[\s\S]*endpoint:\s*[\s\S]*health:/i.test(we)||(n.issues.push("Actuator health endpoint exposure is not clearly configured in application.yml"),n.fixCommands?.push(q(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 z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(M){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"Cargo.lock"),S=d.join(e,"target");n.depsInstalled=await u.pathExists(C)||await u.pathExists(S),n.depsInstalled||(n.issues.push("Rust dependencies are not resolved yet (Cargo.lock/target missing)"),n.fixCommands?.push(q(e,"cargo fetch")));let I=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(I),!n.hasEnvFile){let T=d.join(e,".env.example");await u.pathExists(T)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(ne){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"mix.lock"),S=d.join(e,"deps");n.depsInstalled=await u.pathExists(C)||await u.pathExists(S),n.depsInstalled||(n.issues.push("Elixir dependencies not installed (mix.lock/deps missing)"),n.fixCommands?.push(q(e,"mix deps.get")));let I=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(I),!n.hasEnvFile){let T=d.join(e,".env.example");await u.pathExists(T)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(Ye){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,".cpcache"),S=d.join(e,"target"),I=await u.pathExists(y)||await u.pathExists(h);return n.depsInstalled=await u.pathExists(C)||await u.pathExists(S)||I,n.depsInstalled||(n.issues.push("Clojure dependency cache not initialized"),n.fixCommands?.push(q(e,"clojure -P"))),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(Qe){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"target");n.depsInstalled=await u.pathExists(C),n.depsInstalled||(n.issues.push("Scala build artifacts missing (run dependency/build warmup)"),n.fixCommands?.push(q(e,"sbt compile")));let S=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(S),!n.hasEnvFile){let I=d.join(e,".env.example");await u.pathExists(I)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(Xe){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false,n.depsInstalled=true;let C=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(C),!n.hasEnvFile){let S=d.join(e,".env.example");await u.pathExists(S)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(x){let C=null;try{C=await u.readJson(r);}catch{C=null;}let S={...C?.dependencies??{},...C?.devDependencies??{}},I=C?.scripts??{},T=typeof a?.kit_name=="string"?a.kit_name.toLowerCase():typeof a?.kit=="string"?a.kit.toLowerCase():"",_=d$5(e,a),ie=Ho({dependencies:S,scripts:I,kitName:T});if(ge)lt(n,"Bun","high");else {let E=j$3(e,a??null);E.key==="nestjs"||E.key==="express"||E.key==="fastify"||E.key==="koa"||E.key==="tauri"||E.key==="electron"||E.key==="vscode-extension"?ee(n,E):_.key!=="unknown"?Bo(n,_):E.key!=="unknown"&&E.key!=="node"?ee(n,E):lt(n,ie.framework,ie.confidence);}n.venvActive=true;let ue=d.join(e,"node_modules");if(await u.pathExists(ue))try{let H=(await u.readdir(ue)).filter(oe=>!oe.startsWith(".")&&!oe.startsWith("_"));n.depsInstalled=H.length>0;}catch{n.depsInstalled=false;}if(!n.depsInstalled){n.issues.push("Dependencies not installed (node_modules empty or missing)");let E=typeof C?.packageManager=="string"?C.packageManager.split("@")[0]:void 0,H=ge?"bun install":E==="pnpm"||await u.pathExists(d.join(e,"pnpm-lock.yaml"))?"pnpm install":E==="yarn"||await u.pathExists(d.join(e,"yarn.lock"))?"yarn install":"npm install";n.fixCommands?.push(q(e,H));}if(n.coreInstalled=false,n.projectKind==="frontend"){let E=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local"];if((await Promise.all(E.map(oe=>u.pathExists(d.join(e,oe))))).some(Boolean))n.hasEnvFile=true;else {let oe=d.join(e,".env.example");await u.pathExists(oe)&&(n.hasEnvFile=false,n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}}else {let E=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(E),!n.hasEnvFile){let H=d.join(e,".env.example");await u.pathExists(H)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}}if(n.projectKind==="frontend")n.modulesHealthy=await Rt(e),n.missingModules=[];else {let E=d.join(e,"src");if(n.modulesHealthy=true,n.missingModules=[],await u.pathExists(E))try{let H=await u.readdir(E);n.modulesHealthy=H.length>0;}catch{n.modulesHealthy=false;}}return await z(e,n,C),await Z(e,n,C),n.projectKind==="frontend"?await sr(e,n,C,_.key!=="unknown"?_:d$5(e,a)):await U(e,n),await Y(e,n),n}if(B){let C=await qo(e,a);lt(n,C.framework,C.confidence);let S="fastapi";n.framework==="Django"?S="django":n.framework==="Flask"?S="flask":n.framework==="Python"&&(S="");let I=await ht(c),T=await ir(e,S,/\[tool\.poetry\]/.test(I));n.venvActive=!!T.environmentPath,n.depsInstalled=T.dependenciesInstalled,n.coreInstalled=!!T.coreVersion,n.coreVersion=T.coreVersion,T.environmentPath?T.interpreter?n.depsInstalled||(n.issues.push("Dependencies not installed"),n.fixCommands?.push(Gn(e))):n.issues.push("Virtual environment exists but Python executable not found"):(n.issues.push("Virtual environment not created"),n.fixCommands?.push(Gn(e)));let _=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(_),!n.hasEnvFile){let E=d.join(e,".env.example");await u.pathExists(E)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}let ie=d.join(e,"src"),ue=d.join(e,"modules");if(n.modulesHealthy=true,n.missingModules=[],await u.pathExists(ie)){let E=d.join(ie,"__init__.py");await u.pathExists(E)||(n.modulesHealthy=false,n.missingModules.push("src/__init__.py"));}if(await u.pathExists(ue))try{let E=await cr(ue);for(let H of E){let oe=d.join(ue,H,"__init__.py");await u.pathExists(oe)||(n.modulesHealthy=false,n.missingModules.push(`modules/${H}/__init__.py`));}}catch{}return !n.modulesHealthy&&n.missingModules.length>0&&n.issues.push(`Missing module init files: ${n.missingModules.join(", ")}`),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(P){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"vendor");n.depsInstalled=await u.pathExists(C),n.depsInstalled||(n.issues.push("PHP dependencies not installed (vendor missing)"),n.fixCommands?.push(q(e,"composer install")));let S=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(S),!n.hasEnvFile){let I=d.join(e,".env.example");await u.pathExists(I)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(L){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=await u.pathExists(d.join(e,"Gemfile.lock")),S=await u.pathExists(d.join(e,"vendor","bundle"));n.depsInstalled=C||S,n.depsInstalled||(n.issues.push("Ruby dependencies not installed (Gemfile.lock/vendor missing)"),n.fixCommands?.push(q(e,"bundle install")));let I=d.join(e,".env");return n.hasEnvFile=await u.pathExists(I),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(V){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"obj"),S=d.join(e,"src","obj"),I=d.join(e,"packages.lock.json");n.depsInstalled=await u.pathExists(C)||await u.pathExists(S)||await u.pathExists(I),n.depsInstalled||(n.issues.push(".NET restore/build artifacts not found"),n.fixCommands?.push(q(e,"dotnet restore")));let T=d.join(e,".env");return n.hasEnvFile=await u.pathExists(T),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}return lt(n,"Unknown","low"),n.issues.push("Unknown project type (no recognized runtime marker files)"),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}function li(e){if(!e.fixCommands)return e;let t=new Set;return e.fixCommands=e.fixCommands.filter(i=>{let n=i.trim();return /^https?:\/\/\S+$/i.test(n)||!n||t.has(n)?false:(t.add(n),true)}),e}async function ft(e,t={}){let i=li(await ar(e,t)),n=await b$3(e);return n==="backend"||n==="service"||n==="worker"?i.projectKind="backend":n==="frontend"||n==="desktop"||n==="extension"?i.projectKind=n:i.projectKind||(i.projectKind="generic"),i}async function cr(e){try{return (await u.readdir(e,{withFileTypes:true})).filter(i=>i.isDirectory()).map(i=>i.name)}catch{try{let t=await u.readdir(e),i=[];for(let n of t)try{(await u.stat(d.join(e,n))).isDirectory()&&i.push(n);}catch{continue}return i}catch{return []}}}async function Bn(e,t,i){let n=[{dir:e,depth:0}],o=new Set([".git",".workspai",".rapidkit","node_modules","bin","obj","target"]);for(;n.length>0;){let s=n.shift();if(!s||s.depth>i)continue;let a;try{a=await u.readdir(s.dir,{withFileTypes:true});}catch{continue}for(let r of a){if(r.isFile()&&r.name.toLowerCase().endsWith(t.toLowerCase()))return true;r.isDirectory()&&!o.has(r.name)&&!a$8(r.name)&&n.push({dir:d.join(s.dir,r.name),depth:s.depth+1});}}return false}async function ze(e){let t=["project.json","context.json","file-hashes.json"];for(let i of [".workspai",".rapidkit"])for(let n of t)if(await u.pathExists(d.join(e,i,n)))return true;return false}function lr(e,t){if(t.has(e)||a$8(e))return true;let i=e.toLowerCase();return !!(i==="dist"||i.startsWith("dist-")||i.startsWith("dist_")||i==="build"||i.startsWith("build-")||i.startsWith("build_"))}async function dr(e,t,i){let n=new Set,o=[{dir:e,depth:0}];for(;o.length>0;){let s=o.shift();if(!s)break;try{let a=await u.readdir(s.dir);for(let r of a){if(lr(r,i))continue;let c=d.join(s.dir,r),l;try{l=await u.stat(c);}catch{continue}if(l.isDirectory()){if(await ze(c)){n.add(c);continue}s.depth<t&&o.push({dir:c,depth:s.depth+1});}}}catch{continue}}return Array.from(n)}async function Ue(e){let t=d.resolve(e),i=d.parse(t).root;for(;;){if(await mr(t))return t;if(t===i)break;t=d.dirname(t);}return null}async function ur(e){let t=d.resolve(e),i=await Ue(t),n=i??d.parse(t).root;for(;;){if(await ze(t)||await pr(t)&&(!i||t!==i))return t;if(t===n)break;t=d.dirname(t);}return null}function Hn(e){let t=d.resolve(e);return process.platform==="darwin"?t.replace(/^\/private(?=\/var\/)/,""):t}async function pr(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 i of t)if(await u.pathExists(d.join(e,i)))return true;return false}async function mr(e){if(j$1(e))return true;let t=[d.join(e,".rapidkit","workspace-marker.json"),d.join(e,".rapidkit","config.json")];return Promise.all(t.map(i=>u.pathExists(i))).then(i=>i.some(Boolean))}function qt(e,t){let i={total:0,passed:0,warnings:0,errors:0},n={total:0,passed:0,warnings:0,errors:0};e.forEach(r=>{i.total+=1,r.status==="ok"?i.passed+=1:r.status==="warn"?i.warnings+=1:r.status==="error"&&(i.errors+=1);}),t.forEach(r=>{let c=r.probes??[];if(c.length>0){for(let g of c)n.total+=1,g.status==="pass"?n.passed+=1:g.status==="warn"?n.warnings+=1:n.errors+=1;r.issues.length>0&&(n.total+=r.issues.length,n.errors+=r.issues.length);return}n.total+=1;let l=Do(r),p=r.isGoProject?r.issues.length===0&&r.depsInstalled:r.issues.length===0&&r.venvActive&&r.depsInstalled;r.issues.length>0||!p?n.errors+=1:l>0?n.warnings+=1:n.passed+=1;});let o=i.passed+n.passed,s=i.warnings+n.warnings,a=i.errors+n.errors;return {total:i.total+n.total,passed:o,warnings:s,errors:a,verdict:a>0?"blocked":s>0?"attention":"passed",components:{host:i,projects:n}}}function te(e){let t=e.probes??[],i=t.filter(r=>r.status==="pass").length,n=t.filter(r=>r.status==="warn").length,o=t.filter(r=>r.status==="fail").length,s=o+e.issues.length,a=n;return {total:t.length,passed:i,warnings:n,failed:o,blockingFindings:s,advisoryFindings:a,verdict:s>0?"blocked":a>0?"attention":"passed"}}function fr(e){let t=te(e);e.probeSummary=t,e.verdict=t.verdict;}function di(e,t,i={}){let n=[];for(let s of e)n.push({id:s.id,label:s.label,status:s.result.status,scope:"host-system",policyRuleId:"system-status-derived",reason:s.result.details||s.result.message});let o=[...t].sort((s,a)=>{let r=`${s.path||""}|${s.name||""}`.toLowerCase(),c=`${a.path||""}|${a.name||""}`.toLowerCase();return r.localeCompare(c)});for(let s of o){fr(s);for(let a of s.probes??[])n.push({id:`project:${s.name}:probe:${a.id}`,label:`${s.name} \xB7 ${a.label}`,status:a.status==="pass"?"ok":a.status==="warn"?"warn":"error",scope:"project-scoped",policyRuleId:`project-probe-${a.id}`,reason:a.reason});for(let[a,r]of s.issues.entries())n.push({id:`project:${s.name}:legacy:${a+1}`,label:`${s.name} \xB7 Runtime issue`,status:"error",scope:"project-scoped",policyRuleId:"project-runtime-issue",reason:r});(s.probes?.length??0)===0&&s.issues.length===0&&n.push({id:`project:${s.name}`,label:`Project ${s.name}`,status:"ok",scope:"project-scoped",policyRuleId:"project-checks-passed",reason:"Project checks passed"});}if(i.includeWorkspaceAggregateRules){let s=t.reduce((c,l)=>c+te(l).blockingFindings,0),a=t.reduce((c,l)=>c+te(l).advisoryFindings,0),r=e.filter(c=>c.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:r>0?"error":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-system-error-gate",reason:r>0?`${r} system requirement gate(s) failed.`:"All system requirement gates passed."}),n.push({id:"workspace:blocking-issues-gate",label:"Workspace blocking issues gate",status:s>0?"error":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-blocking-issues-gate",reason:s>0?`${s} blocking project issue(s) detected.`:"No blocking project issues detected."}),n.push({id:"workspace:advisory-warnings-gate",label:"Workspace advisory warnings gate",status:a>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-advisory-warning-gate",reason:a>0?`${a} advisory warning(s) detected.`:"No advisory warnings detected."});}return n}async function Mt(e,t=true,i=mt({})){let n=d.basename(e),o=await a$1(e);if(typeof o?.name=="string"&&o.name.trim().length>0)n=o.name;else try{for(let y of s(e,"workspace.json")){if(!await u.pathExists(y))continue;let h=await u.readJSON(y);n=h.workspace_name||h.name||n;break}}catch{}let[s$1,a]=await Promise.all([Ht(e),Lo(e)]),r={workspacePath:e,workspaceName:n,python:s$1.python,poetry:s$1.poetry,pipx:s$1.pipx,go:s$1.go,rapidkitCore:s$1.rapidkitCore,projects:[],policyProfile:i};f.debug(`Workspace scan found ${a.length} project(s)`);let c=await Vo(e,a),l=d.join(e,".workspai","reports","doctor-workspace-cache.json"),p=t?await Jo(l,c):null;if(p){r.projects=p.projects;for(let y of r.projects)li(y),_n(y,p.generatedAt),Gt(y,y.path);r.projectScanCached=true,f.debug(`Workspace project health cache hit: ${l}`);}else try{let y=new Date().toISOString(),h=await Promise.all(a.map(w=>ft(w,{allowNonRapidkit:true})));for(let w of h)_n(w,y),Gt(w,w.path);r.projects=h,r.projectScanCached=false,await zo(l,{schemaVersion:ei,signature:c,generatedAt:y,projects:h}),f.debug(`Workspace project health cache refreshed: ${l}`);}catch(y){f.debug(`Failed to scan workspace projects: ${y}`);}r.projectScanSignature=c,r.projectScanCachePath=l;let g=Xn({python:r.python,poetry:r.poetry,pipx:r.pipx,go:r.go,rapidkitCore:r.rapidkitCore},r.projects);r.python=g.python,r.poetry=g.poetry,r.pipx=g.pipx,r.go=g.go,r.rapidkitCore=g.rapidkitCore,await Promise.all(r.projects.map(async y=>{y.graphDiagnosis=await Nt({workspacePath:e,projectPath:y.path,projectName:y.name,probes:ti(y),issues:y.issues});}));let v=[r.python,r.poetry,r.pipx,r.go,r.rapidkitCore];if(r.healthScore=qt(v,r.projects),r.scoreBreakdown=di([{id:"system-python",label:"Python",result:r.python},{id:"system-poetry",label:"Poetry",result:r.poetry},{id:"system-pipx",label:"pipx",result:r.pipx},{id:"system-go",label:"Go",result:r.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:r.rapidkitCore}],r.projects,{includeWorkspaceAggregateRules:true}),r.scopeProvenance=ai(r.scoreBreakdown),r.evidenceFreshness=ii(r.projects,new Date().toISOString()),r.rapidkitCore.status==="ok"){let y=r.rapidkitCore.message.match(/([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);y&&(r.coreVersion=y[1]);}let j=await d$1(e,_t),k=j?await ri(j,"workspace"):null;return r.driftDelta=To(k,r),r.evidencePath=await Uo(e,r,p?l:null),r}function qn(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,dependencyAudit:e.dependencyAudit,coreInstalled:e.coreInstalled,coreVersion:e.coreVersion,lastModified:e.lastModified,stats:e.stats,issues:e.issues,fixCommands:e.fixCommands,probes:e.probes,verdict:e.verdict??te(e).verdict,probeSummary:e.probeSummary??te(e),repairCapabilities:e.repairCapabilities,commandCapabilities:e.commandCapabilities,graphDiagnosis:e.graphDiagnosis}}function ui(e,t){let i=e?d.relative(e,t).split(d.sep).join("/"):d.resolve(t),n=d.basename(t).toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"project",o=createHash("sha256").update(i).digest("hex").slice(0,12);return `.workspai/reports/projects/${n}--${o}/doctor-project-last-run.json`}async function gr(e$3,t){let i=e$3||t.projectPath,n=e.doctorProject,o=ui(e$3,t.projectPath),s=d.join(i,n);try{let a=[...t.project.issues,...(t.project.probes??[]).filter(l=>l.status==="fail").map(l=>l.reason)].filter(l=>typeof l=="string"&&l.trim().length>0).slice(0,12),r=te(t.project),c=f$1({schemaVersion:b$5,evidenceType:"project",contract:$e(),policyProfile:t.policyProfile,workspacePath:e$3||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,verdict:r.verdict,probeSummary:r,blockingFindings:r.blockingFindings,advisoryFindings:r.advisoryFindings},scoreBreakdown:t.scoreBreakdown??[]},{commandId:"projectDoctor",exitCode:Ze(t.healthScore,{profile:t.policyProfile?.name}),generatedAt:new Date().toISOString(),blockers:a,runId:e$2()});return d$4(c),e$3?await f$2(e$3,n,[{relativePath:n,payload:c},{relativePath:o,payload:c}]):await e$1(i,n,c),e$3&&d.resolve(e$3)!==d.resolve(t.projectPath)&&await e$1(t.projectPath,n,c),s}catch(a){if(a instanceof Error&&a.message.includes("violates contracts/"))throw a;return}}async function Kt(e$2,t,i=[]){let n=d.join(e$2,e.doctorRemediationPlan);try{await e$1(e$2,e.doctorRemediationPlan,t);for(let o of i)d.resolve(o)!==d.resolve(e$2)&&await e$1(o,e.doctorRemediationPlan,t);return n}catch(o){if(o instanceof Error&&o.message.includes("violates contracts/"))throw o;return}}async function Fe(e$2,t,i=[]){let n=d.join(e$2,e.doctorFixResult);try{await e$1(e$2,e.doctorFixResult,t);for(let o of i)d.resolve(o)!==d.resolve(e$2)&&await e$1(o,e.doctorFixResult,t);return n}catch{return}}async function Ne(e,t,i){try{await j(e,g(t,i));}catch{}}async function Ln(e$1,t=mt({})){let i=await Ue(e$1),n=await Ht(i||e$1),o=await ft(e$1,{allowNonRapidkit:true}),s=Xn(n,[o]);Gt(o,e$1),o.graphDiagnosis=await Nt({workspacePath:i||void 0,projectPath:e$1,projectName:o.name,probes:ti(o),issues:o.issues});let a=qt([s.python,s.poetry,s.pipx,s.go,s.rapidkitCore],[o]),r={workspacePath:i||void 0,projectPath:e$1,projectName:d.basename(e$1),python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore,project:o,healthScore:a,policyProfile:t};r.scoreBreakdown=di([{id:"system-python",label:"Python",result:r.python},{id:"system-poetry",label:"Poetry",result:r.poetry},{id:"system-pipx",label:"pipx",result:r.pipx},{id:"system-go",label:"Go",result:r.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:r.rapidkitCore}],[r.project]),r.scopeProvenance=ai(r.scoreBreakdown),r.evidenceFreshness=ii([r.project],new Date().toISOString());let c=await d$1(e$1,e.doctorProject),l=i?await d$1(i,ui(i,e$1)):null,p=c??l,g=p?await ri(p,"project"):null;return r.driftDelta=Oo(g,r),r.evidencePath=await gr(i||void 0,r),r}function W(e,t){let i=e.status==="ok"?"\u2705":e.status==="warn"?"\u26A0\uFE0F":"\u274C",n=e.status==="ok"?m.green:e.status==="warn"?m.yellow:m.red;console.log(`${i} ${m.bold(t)}: ${n(e.message)}`),e.paths&&e.paths.length>0&&e.paths.forEach(o=>{let s=o.version?m.cyan(` -> ${o.version}`):"";console.log(` ${m.cyan("\u2022")} ${m.gray(o.location)}: ${m.dim(o.path)}${s}`);}),e.details&&console.log(` ${m.gray(e.details)}`);}function dt(e,t){let i=pt(e,t);if(/^(?:workspai|rapidkit):doctor:repair\s/.test(t))return i?.title??"Apply Doctor-managed project repair";if(/^https?:\/\//i.test(t.trim()))return `Open: ${t.trim()}`;let n=t.match(/\s+(?:&&|;)\s+/);return `Run in project: ${n?t.slice((n.index??0)+n[0].length):t}`}function Vn(e,t){let i=e.issues.length>0,n=i?"\u26A0\uFE0F":"\u2705",o=i?m.yellow:m.green;if(console.log(`
|
|
12
|
+
${a}`)||r,l=c?void 0:await Et({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:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Runtime-native lint/format/static-analysis markers detected.":"No runtime-native lint/format/static-analysis markers detected.",recommendation:c?void 0:"Add runtime-native lint/format/static-analysis tooling and expose it to CI.",repairCapability:l}}async function Ji(e){let t=Ce(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"],scala:["build.sbt","project/plugins.sbt"],kotlin:["build.gradle","build.gradle.kts","pom.xml"],c:["CMakeLists.txt","conanfile.py","conanfile.txt","vcpkg.json"],cpp:["CMakeLists.txt","conanfile.py","conanfile.txt","vcpkg.json"],unknown:[]}[t]??[];if(n.length===0)return null;let o=await at(e.projectPath,n),s=/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|dependencyCheck|dependency-check|snyk|trivy|osv-scanner|cyclonedx|sbom/i.test(o),a=s?void 0:await Et({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:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Runtime-native security audit tooling marker detected.":"No runtime-native security audit tooling marker detected.",recommendation:s?void 0:"Expose a runtime-native dependency/security audit command for CI and Studio verification.",repairCapability:s?void 0:a||Pe({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 Sn(e){let t=Ce(e.runtimeFamily),i=[],n=await Ti({projectPath:e.projectPath,runtime:t,packageJsonData:e.packageJsonData});n&&i.push(n),i.push(await Oi(e)),i.push(await _i(e)),i.push(await Gi(e)),i.push(await Ki(e)),i.push(await Wi(e)),i.push(await Bi(e)),(t==="node"||t==="bun")&&i.push(qi(e));let o=await Promise.all([Li(e),Vi(e),Ji(e)]);for(let s of o)s&&i.push(s);return i}var le={low:0,moderate:0,high:0,critical:0,unknown:0};function Ui(e){let t=String(e??"unknown").toLowerCase();return t==="medium"?"moderate":t==="low"||t==="moderate"||t==="high"||t==="critical"?t:"unknown"}function ce(e){let t=typeof e.name=="string"?e.name.trim():"";return t?{name:t,...typeof e.version=="string"&&e.version.trim()?{version:e.version.trim()}:{},...typeof e.direct=="boolean"?{direct:e.direct}:{},advisoryIds:[...new Set((e.advisoryIds??[]).map(i=>typeof i=="string"||typeof i=="number"?String(i).trim():"").filter(Boolean))].sort(),severities:[...new Set((e.severities??[]).map(i=>Ui(i)))].sort()}:null}function ae(e){let t=new Map;for(let i of e){if(!i)continue;let n=i.name.toLowerCase(),o=t.get(n);if(!o){t.set(n,i);continue}t.set(n,{name:o.name,...o.version||i.version?{version:o.version??i.version}:{},...o.direct!==void 0||i.direct!==void 0?{direct:o.direct??i.direct}:{},advisoryIds:[...new Set([...o.advisoryIds,...i.advisoryIds])].sort(),severities:[...new Set([...o.severities,...i.severities])].sort()});}return [...t.values()].sort((i,n)=>i.name.localeCompare(n.name))}function En(e){return e.map(t=>{let i=t.direct===true?"direct":t.direct===false?"transitive":"unknown";return {packageName:t.name,relationship:i,strategies:i==="direct"?["direct-upgrade","constraint-update","replacement","policy-exception","upstream-wait"]:["owner-upgrade","constraint-update","replacement","policy-exception","upstream-wait"],risk:"guarded",autoExecutable:false,requiresCompatibilityVerification:true,...t.version?{currentVersion:t.version}:{},ownerPackages:[],advisoryIds:[...t.advisoryIds],reason:"Resolve the advisory through the runtime-native dependency manifest and lock/baseline, then prove compatibility with audit, tests, build, and canonical verification."}})}var At=new Map,Zi=["package.json","package-lock.json","npm-shrinkwrap.json","pnpm-lock.yaml","yarn.lock",".yarnrc.yml","bun.lock","bun.lockb","deno.lock","pyproject.toml","requirements.txt","uv.lock","poetry.lock","go.mod","go.sum","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","Cargo.lock","composer.json","composer.lock","Gemfile","Gemfile.lock","mix.exs","mix.lock","deps.edn","project.clj","Directory.Packages.props","packages.lock.json"];function Yi(){let e=Number(process.env.RAPIDKIT_DOCTOR_AUDIT_TIMEOUT_MS);return Number.isFinite(e)&&e>0?Math.trunc(e):15e3}async function Qi(e,t){let i=[];for(let n of Zi){let o=d.join(e,n);try{let s=await u.stat(o);i.push(`${n}:${s.size}:${s.mtimeMs}`);}catch{}}return `${d.resolve(e)}\0${t}\0${i.join("|")}`}function me(e){let t=e.trim();if(!t)return null;try{let i=JSON.parse(t);return i&&typeof i=="object"&&!Array.isArray(i)?i:null}catch{return null}}function Ke(e){return typeof e=="number"&&Number.isFinite(e)?Math.max(0,e):0}function An(e){let t=e&&typeof e=="object"&&!Array.isArray(e)?e:{};return {low:Ke(t.low),moderate:Ke(t.moderate??t.medium),high:Ke(t.high),critical:Ke(t.critical),unknown:Ke(t.unknown)}}function Be(e){return e.low+e.moderate+e.high+e.critical+e.unknown}function Xi(e){if(typeof e!="string")return;let t=e.trim(),i=t.match(/^<\s*(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/);if(i)return `>=${i[1]}`;let n=t.match(/^<=\s*(\d+)\.(\d+)\.(\d+)$/);if(n)return `>=${n[1]}.${n[2]}.${Number(n[3])+1}`}async function eo(e){let t=new Map;try{let i=await u.readJSON(d.join(e,"package.json"));for(let n of ["dependencies","devDependencies","optionalDependencies","peerDependencies"]){let o=i[n];if(!(!o||typeof o!="object"||Array.isArray(o)))for(let[s,a]of Object.entries(o))typeof a=="string"&&a.trim()&&t.set(s.toLowerCase(),a.trim());}}catch{}return t}async function to(e,t){let i=me(t),n=i?.vulnerabilities&&typeof i.vulnerabilities=="object"&&!Array.isArray(i.vulnerabilities)?i.vulnerabilities:void 0;if(!n)return [];let[o,s]=await Promise.all([Nn(e),eo(e)]),a=new Map;for(let[r,c]of Object.entries(n)){let l=c&&typeof c=="object"?c:{},p=typeof l.name=="string"&&l.name.trim()?l.name.trim():r.trim();if(!p)continue;let y=l.isDirect===true?"direct":l.isDirect===false?"transitive":"unknown",v=Array.isArray(l.effects)?[...new Set(l.effects.filter(F=>typeof F=="string").map(F=>F.trim()).filter(Boolean))].sort():[],j=Array.isArray(l.via)?l.via:[],k=[...new Set(j.flatMap(F=>{let f=F&&typeof F=="object"?F:{};return [f.source,f.url].filter(R=>typeof R=="string"||typeof R=="number").map(String)}))].sort(),g=typeof l.range=="string"?l.range.trim():void 0,h=Xi(g),w=s.get(p.toLowerCase()),b=o.get(p.toLowerCase()),D=y==="direct"?["direct-upgrade","constraint-update","replacement","policy-exception","upstream-wait"]:[...v.length>0?["owner-upgrade"]:[],"transitive-override","replacement","policy-exception","upstream-wait"];a.set(p.toLowerCase(),{packageName:p,relationship:y,strategies:D,risk:"guarded",autoExecutable:false,requiresCompatibilityVerification:true,...b?{currentVersion:b}:{},...w?{currentRange:w}:{},...g?{vulnerableRange:g}:{},...h?{safeVersionConstraint:h}:{},ownerPackages:v,advisoryIds:k,reason:y==="direct"?"Resolve the direct dependency inside its declared compatibility boundary, then reconcile and verify the complete dependency transaction.":"Resolve the vulnerable transitive path through a compatible owner upgrade or a guarded package-manager constraint; never infer safety from an audit downgrade."});}return [...a.values()].sort((r,c)=>r.packageName.localeCompare(c.packageName))}function Re(e,t,i=1){let n=String(t??"unknown").toLowerCase();n==="low"?e.low+=i:n==="moderate"||n==="medium"?e.moderate+=i:n==="high"?e.high+=i:n==="critical"?e.critical+=i:e.unknown+=i;}function He(e,t){if(Array.isArray(e)){for(let n of e)He(n,t);return}if(!e||typeof e!="object")return;let i=e;t(i);for(let n of Object.values(i))He(n,t);}function no(e,t){if(t===0)return {disposition:"not-needed",compatibleFixAvailable:false,breakingFixAvailable:false,candidates:[]};let i=false,n=false,o=false,s=[];for(let[r,c]of e){let l=c&&typeof c=="object"?c:{};if(!Object.prototype.hasOwnProperty.call(l,"fixAvailable"))continue;i=true;let p=l.fixAvailable;if(p===true){n=true,s.push({packageName:r,breaking:false});continue}if(!p||typeof p!="object"||Array.isArray(p))continue;let y=p,v=typeof y.name=="string"&&y.name.trim()?y.name.trim():r,j=y.isSemVerMajor===true;n||=!j,o||=j,s.push({packageName:v,...typeof y.version=="string"&&y.version.trim()?{version:y.version.trim()}:{},breaking:j});}return {disposition:n?o?"mixed":"compatible":o?"breaking-only":i?"none":"unknown",compatibleFixAvailable:n,breakingFixAvailable:o,candidates:s.sort((r,c)=>`${r.packageName}@${r.version??""}`.localeCompare(`${c.packageName}@${c.version??""}`))}}function io(e,t){let i=s=>{let a=s.trim().match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?(?:\+.+)?$/);return a?[Number(a[1]),Number(a[2]),Number(a[3]),a[4]??""]:null},n=i(e),o=i(t);if(!n||!o)return null;for(let s=0;s<3;s+=1)if(n[s]!==o[s])return Number(n[s])>Number(o[s])?1:-1;return n[3]===o[3]?0:n[3]?o[3]?n[3].localeCompare(o[3]):-1:1}async function Nn(e){let t=new Map;try{let i=await u.readJSON(d.join(e,"package-lock.json")),n=i.packages&&typeof i.packages=="object"&&!Array.isArray(i.packages)?i.packages:{};for(let[s,a]of Object.entries(n)){if(!s.startsWith("node_modules/"))continue;let r=s.replace(/^node_modules\//,"").split("/node_modules/").at(-1)?.trim()??"";if(!r)continue;let c=a&&typeof a=="object"?a:{};!t.has(r.toLowerCase())&&typeof c.version=="string"&&c.version.trim()&&t.set(r.toLowerCase(),c.version.trim());}let o=i.dependencies&&typeof i.dependencies=="object"&&!Array.isArray(i.dependencies)?i.dependencies:{};for(let[s,a]of Object.entries(o)){if(t.has(s.toLowerCase()))continue;let r=a&&typeof a=="object"?a:{};typeof r.version=="string"&&r.version.trim()&&t.set(s.toLowerCase(),r.version.trim());}}catch{}return t}async function oo(e,t){if(t.disposition==="not-needed")return t;let i=await Nn(e),n=new Map;for(let c of t.candidates){let l=i.get(c.packageName.toLowerCase());if(c.version&&l){let v=io(c.version,l);if(v!==null&&v<=0)continue}let p=`${c.packageName.toLowerCase()}\0${c.version??""}`,y=n.get(p);n.set(p,{packageName:y?.packageName??c.packageName,...c.version?{version:c.version}:{},breaking:!!(y?.breaking||c.breaking)});}let o=[...n.values()].sort((c,l)=>`${c.packageName}@${c.version??""}`.localeCompare(`${l.packageName}@${l.version??""}`)),s=o.some(c=>!c.breaking),a=o.some(c=>c.breaking);return {disposition:s?a?"mixed":"compatible":a?"breaking-only":"none",compatibleFixAvailable:s,breakingFixAvailable:a,candidates:o}}function ro(e){let t=me(e);if(!t){let c={...le},l=[],p=0,y=false;for(let v of e.split(/\r?\n/)){let j=me(v);if(!j)continue;let k=j.data&&typeof j.data=="object"?j.data:{};if(j.type==="auditAdvisory"){let g=k.advisory&&typeof k.advisory=="object"?k.advisory:{};p+=1,Re(c,g.severity);let h=ce({name:g.module_name??g.name,advisoryIds:[g.id,g.github_advisory_id,g.url],severities:[g.severity]});h&&l.push(h);}if(j.type==="auditSummary"){y=true;let g=An(k.vulnerabilities);if(Be(g)>=p)return {findingCount:Be(g),severityCounts:g,subjects:ae(l)}}}return p>0||y?{findingCount:p,severityCounts:c,subjects:ae(l)}:null}let i=t.metadata&&typeof t.metadata=="object"?t.metadata:null,n=An(i?.vulnerabilities),o=t.vulnerabilities&&typeof t.vulnerabilities=="object"?Object.entries(t.vulnerabilities):[],s=ae(o.map(([c,l])=>{let p=l&&typeof l=="object"?l:{},y=Array.isArray(p.via)?p.via:[];return ce({name:p.name??c,direct:p.isDirect,advisoryIds:y.flatMap(v=>{let j=v&&typeof v=="object"?v:{};return [j.source,j.url]}),severities:[p.severity]})}));if(Be(n)>0||i?.vulnerabilities){let c=Be(n);return {findingCount:c,severityCounts:n,subjects:s,remediation:no(o,c)}}let a=t.advisories&&typeof t.advisories=="object"?Object.entries(t.advisories):[],r=[];for(let[c,l]of a){let p=l&&typeof l=="object"?l:{};Re(n,p.severity);let y=ce({name:p.module_name??p.name,advisoryIds:[p.id,p.github_advisory_id,p.url,c],severities:[p.severity]});y&&r.push(y);}return {findingCount:a.length,severityCounts:n,subjects:ae([...s,...r])}}function so(e){let t=(()=>{try{return JSON.parse(e.trim())}catch{return null}})(),i=Array.isArray(t)?t:t&&typeof t=="object"?t.dependencies:null;if(!Array.isArray(i))return null;let n={...le},o=[],s=0;for(let a of i){let r=a&&typeof a=="object"?a:{},c=Array.isArray(r.vulns)?r.vulns:[];if(s+=c.length,n.unknown+=c.length,c.length>0){let l=ce({name:r.name,version:r.version,advisoryIds:c.flatMap(p=>{let y=p&&typeof p=="object"?p:{};return [y.id,y.aliases].flatMap(v=>Array.isArray(v)?v:[v])}),severities:c.map(()=>"unknown")});l&&o.push(l);}}return {findingCount:s,severityCounts:n,subjects:ae(o)}}function ao(e){if(!e.trim())return null;let t=new Set,i=new Map;for(let n of e.split(/\r?\n/)){let o=me(n),s=o?.osv&&typeof o.osv=="object"?o.osv:null;typeof s?.id=="string"&&t.add(s.id);let a=o?.finding&&typeof o.finding=="object"?o.finding:null;typeof a?.osv=="string"&&t.add(a.osv);let r=Array.isArray(a?.trace)?a.trace:[];for(let c of r){let l=c&&typeof c=="object"?c:{},p=typeof l.module=="string"?l.module:typeof l.package=="string"?l.package:"";if(!p)continue;let y=i.get(p)??{advisoryIds:new Set};typeof l.version=="string"&&(y.version=l.version),typeof a?.osv=="string"&&y.advisoryIds.add(a.osv),i.set(p,y);}}return {findingCount:t.size,severityCounts:{...le,unknown:t.size},subjects:[...i.entries()].map(([n,o])=>ce({name:n,version:o.version,advisoryIds:[...o.advisoryIds],severities:["unknown"]})).filter(n=>!!n)}}function co(e){let t=me(e);if(!t)return null;let i=t.vulnerabilities&&typeof t.vulnerabilities=="object"?t.vulnerabilities:{},n=Array.isArray(i.list)?i.list:[],o={...le},s=[];for(let a of n){let r=a&&typeof a=="object"?a:{},c=r.advisory&&typeof r.advisory=="object"?r.advisory:{};Re(o,c.severity);let l=r.package&&typeof r.package=="object"?r.package:{},p=ce({name:l.name,version:l.version,advisoryIds:[c.id,c.url],severities:[c.severity]});p&&s.push(p);}return {findingCount:n.length,severityCounts:o,subjects:ae(s)}}function lo(e){let t=me(e);if(!t)return null;let i=t.advisories&&typeof t.advisories=="object"?t.advisories:{},n={...le},o=0,s=[];for(let[a,r]of Object.entries(i)){let c=Array.isArray(r)?r:[r],l=ce({name:a,advisoryIds:c.flatMap(p=>{let y=p&&typeof p=="object"?p:{};return [y.advisoryId,y.cve,y.link]}),severities:c.map(p=>(p&&typeof p=="object"?p:{}).severity)});l&&s.push(l);}return He(i,a=>{(typeof a.advisoryId=="string"||typeof a.cve=="string")&&(o+=1,Re(n,a.severity));}),{findingCount:o,severityCounts:n,subjects:ae(s)}}function uo(e){let t=me(e);if(!t)return null;let i={...le},n=0,o=[];return He(t,s=>{if(!Array.isArray(s.vulnerabilities))return;for(let r of s.vulnerabilities){let c=r&&typeof r=="object"?r:{};n+=1,Re(i,c.severity);}let a=ce({name:s.id??s.name??s.packageId,version:s.resolvedVersion??s.version,direct:s.isTransitive===false,advisoryIds:s.vulnerabilities.flatMap(r=>{let c=r&&typeof r=="object"?r:{};return [c.advisoryurl,c.advisoryUrl,c.url]}),severities:s.vulnerabilities.map(r=>(r&&typeof r=="object"?r:{}).severity)});a&&o.push(a);}),{findingCount:n,severityCounts:i,subjects:ae(o)}}function po(e){let t=me(e);if(!t)return null;let i={...le},n=new Set,o=[];return He(t,s=>{let a=s.id??s.cve??s.advisory??s.url;if(typeof a!="string")return;n.add(a),Re(i,s.severity??s.criticality);let r=s.gem&&typeof s.gem=="object"?s.gem:{},c=ce({name:r.name??s.gemName??s.name,version:r.version??s.version,advisoryIds:[a],severities:[s.severity??s.criticality]});c&&o.push(c);}),{findingCount:n.size,severityCounts:n.size>0&&Be(i)===0?{...i,unknown:n.size}:i,subjects:ae(o)}}function $n(e,t){let i=`${e}
|
|
13
|
+
${t}`.trim();if(!i)return null;let n=i.match(/(?:found|total:?)\s+(\d+)\s+vulnerabilit/i),o=/no (?:known )?vulnerabilit|no retired packages found|no insecure dependencies found/i.test(i);if(!n&&!o)return null;let s=n?Number(n[1]):0;return {findingCount:s,severityCounts:{...le,unknown:s},subjects:[]}}function mo(e,t,i){return e==="node"||e==="bun"?ro(t):e==="python"?so(t):e==="go"?ao(t):e==="rust"?co(t):e==="php"?lo(t):e==="dotnet"?uo(t):e==="ruby"?po(t)??$n(t,i):e==="deno"||e==="elixir"?$n(t,i):null}async function We(e,t){return u.pathExists(d.join(e,t))}async function fo(e,t){if(t==="bun")return {ecosystem:"npm",tool:"bun audit",invocation:{cwd:e,executable:"bun",args:["audit","--json"]}};if(t==="node"){if(await We(e,"bun.lock")||await We(e,"bun.lockb"))return {ecosystem:"npm",tool:"bun audit",invocation:{cwd:e,executable:"bun",args:["audit","--json"]}};if(await We(e,"pnpm-lock.yaml"))return {ecosystem:"npm",tool:"pnpm audit",invocation:{cwd:e,executable:"pnpm",args:["audit","--json"]}};if(await We(e,"yarn.lock")){let i=await We(e,".yarnrc.yml");return {ecosystem:"npm",tool:"yarn audit",invocation:{cwd:e,executable:"yarn",args:i?["npm","audit","--json","--severity","moderate"]:["audit","--json","--level","moderate"]}}}return {ecosystem:"npm",tool:"npm audit",invocation:{cwd:e,executable:"npm",args:["audit","--json"]}}}if(t==="deno")return {ecosystem:"deno",tool:"deno audit",invocation:{cwd:e,executable:"deno",args:["audit"]}};if(t==="python"){let i=d.join(e,".venv",process.platform==="win32"?"Scripts/python.exe":"bin/python");return {ecosystem:"PyPI",tool:"pip-audit",invocation:{cwd:e,executable:await u.pathExists(i)?i:process.platform==="win32"?"python":"python3",args:["-m","pip_audit","--format","json"]}}}return t==="go"?{ecosystem:"Go modules",tool:"govulncheck",invocation:{cwd:e,executable:"govulncheck",args:["-json","./..."]}}:t==="rust"?{ecosystem:"crates.io",tool:"cargo-audit",invocation:{cwd:e,executable:"cargo",args:["audit","--json"]}}:t==="php"?{ecosystem:"Packagist",tool:"Composer audit",invocation:{cwd:e,executable:"composer",args:["audit","--format=json"]}}:t==="ruby"?{ecosystem:"RubyGems",tool:"bundler-audit",invocation:{cwd:e,executable:"bundle-audit",args:["check","--format","json"]}}:t==="dotnet"?{ecosystem:"NuGet",tool:".NET package audit",invocation:{cwd:e,executable:"dotnet",args:["package","list","--vulnerable","--include-transitive","--format","json"]}}:t==="elixir"?{ecosystem:"Hex",tool:"mix hex.audit",invocation:{cwd:e,executable:"mix",args:["hex.audit"]}}:t==="java"?{ecosystem:"Maven/Gradle",tool:"OWASP Dependency-Check",unsupportedReason:"No universal zero-configuration Java vulnerability scanner is safe to invoke. Declare OWASP Dependency-Check or an organization-approved equivalent in the build."}:t==="scala"||t==="kotlin"?{ecosystem:"Maven/JVM",tool:"organization-selected JVM dependency scanner",unsupportedReason:"No universal zero-configuration JVM vulnerability scanner is safe to invoke. Declare an organization-approved scanner in the project build."}:t==="c"||t==="cpp"?{ecosystem:t==="c"?"C/native":"C++/native",tool:"organization-selected native dependency scanner",unsupportedReason:"Native dependency provenance depends on the build and package manager. Declare an organization-approved SBOM or vulnerability scanner in the project command contract."}:t==="clojure"?{ecosystem:"Clojars/Maven",tool:"organization-selected Clojure audit",unsupportedReason:"No portable Clojure vulnerability command is declared. Configure an organization-approved scanner and expose it through the project command contract."}:{ecosystem:"unknown",tool:"none",unsupportedReason:"Doctor could not determine a supported dependency ecosystem."}}function Fn(e){let t=e&&typeof e=="object"?e:void 0,i=String(t?.code??""),n=String(t?.message??"");return i==="ENOENT"||/not found|is not recognized|no module named pip_audit/i.test(n)}async function go(e){let t=new Date().toISOString(),i=await fo(e.projectPath,e.runtime),n={schemaVersion:"doctor-dependency-audit-v1",runtime:e.runtime,ecosystem:i.ecosystem,tool:i.tool,generatedAt:t,findingCount:null,blockingFindingCount:null,severityCounts:{...le},subjects:[],limitations:["A clean result covers known advisories available to the selected runtime-native audit tool at execution time.","Doctor never treats a missing scanner, malformed output, registry failure, or timeout as a clean audit."]};if(!i.invocation)return {...n,status:"unsupported",reason:i.unsupportedReason??"No supported audit invocation is available."};try{let o=await execa(i.invocation.executable,i.invocation.args,{cwd:i.invocation.cwd,timeout:Yi(),reject:false}),s=mo(e.runtime,o.stdout,o.stderr);if(!s){let c=/not found|no module named pip_audit|unknown command|unrecognized (?:command|option)/i.test(`${o.stdout}
|
|
14
|
+
${o.stderr}`);return {...n,invocation:i.invocation,exitCode:o.exitCode,status:c?"tool-unavailable":"failed",reason:c?`${i.tool} is not installed or not supported by the detected runtime version.`:`${i.tool} did not produce parseable vulnerability evidence.`}}if((e.runtime==="node"||e.runtime==="bun")&&s.remediation&&(s.remediation=await oo(e.projectPath,s.remediation),s.findingCount>0&&!s.remediation.compatibleFixAvailable)){let c=await to(e.projectPath,o.stdout);s.remediation.resolutionCandidates=c.length>0?c:En(s.subjects);}let a=s.severityCounts.moderate+s.severityCounts.high+s.severityCounts.critical+s.severityCounts.unknown,r=s.remediation??(s.findingCount===0?{disposition:"not-needed",compatibleFixAvailable:false,breakingFixAvailable:false,candidates:[]}:{disposition:"unknown",compatibleFixAvailable:false,breakingFixAvailable:false,candidates:[],resolutionCandidates:En(s.subjects)});return {...n,invocation:i.invocation,exitCode:o.exitCode,findingCount:s.findingCount,blockingFindingCount:a,severityCounts:s.severityCounts,subjects:s.subjects,remediation:r,status:s.findingCount>0?"vulnerable":"clean",reason:s.findingCount>0?`${i.tool} reported ${s.findingCount} known dependency vulnerability finding(s).`:`${i.tool} completed without known dependency vulnerability findings.`}}catch(o){return {...n,invocation:i.invocation,status:Fn(o)?"tool-unavailable":"failed",reason:Fn(o)?`${i.tool} is not installed or cannot be resolved from this project environment.`:`${i.tool} could not complete: ${o instanceof Error?o.message:String(o)}`}}}async function In(e){let t=await Qi(e.projectPath,e.runtime),i=At.get(t);if(i)return i;let n=go(e);At.set(t,n);try{return await n}catch(o){throw At.delete(t),o}}var On="Graph paths identify evidence-backed structural reachability and verification candidates; they do not prove runtime causality or that every affected surface has been discovered.",Mn={dependency:["package","module"],security:["package","module"],test:["test-suite"],quality:["file","symbol","module"],container:["container"],deployment:["deployment","container","environment"],environment:["environment"],configuration:["environment","file"],runtime:["service","container","deployment"],"workspace-contract":["project","service","api","endpoint"],"source-tree":["file","module","symbol"],framework:["service","project","package"],custom:["project"],unknown:["project"]},yo=new Set(["project","service","api","endpoint","schema","database","queue","container","deployment","pipeline","environment","document","decision","test-suite","owner"]),ho=new Set(["test-suite","pipeline"]);function Ft(e,t){if(!e)return ".";let i=d.relative(e,t).split(d.sep).join("/");return i&&!i.startsWith("../")?i:"."}function $t(e){return {id:e.id,kind:e.kind,label:e.label,...e.projectId?{projectId:e.projectId}:{}}}function Se(e,t,i,n={artifact:b$4}){return {schemaVersion:d$3,generatedAt:(e.now??new Date).toISOString(),status:t,claimBoundary:On,graph:n,project:{name:e.projectName,path:Ft(e.workspacePath,e.projectPath)},summary:{findingCount:0,rootEntityCount:0,affectedEntityCount:0,verificationTargetCount:0,proofPathCount:0,subjectCount:0,unresolvedSubjectCount:0,unknownCount:1},findings:[],diagnostics:[i]}}function ko(e,t){let i=Ft(t.workspacePath,t.projectPath).toLowerCase(),n=new Set([t.projectName,d.basename(t.projectPath),i].map(o=>o.trim().toLowerCase()).filter(Boolean));return e.entities.filter(o=>o.kind==="project").find(o=>[o.projectId,o.label,o.identity.key,...o.identity.aliases,typeof o.attributes.path=="string"?o.attributes.path:void 0].filter(a=>typeof a=="string").map(a=>a.toLowerCase()).some(a=>n.has(a)||n.has(d.basename(a))))}function vo(e,t){let i=t.projectId??t.label,n=e.entities.filter(a=>a.id===t.id||a.projectId===i||a.projectId===t.projectId),o=new Set(n.map(a=>a.id)),s=new Set;for(let a of e.relations)o.has(a.from)&&s.add(a.to),o.has(a.to)&&s.add(a.from);return e.entities.filter(a=>o.has(a.id)||s.has(a.id))}function bo(e){let t=new Map,i=(n,o)=>{let s=t.get(n)??[];s.push(o),t.set(n,s);};for(let n of e.relations)i(n.from,n.to),i(n.to,n.from);for(let n of t.values())n.sort();return t}function wo(e,t,i){let n=bo(e),o=new Set(t),s=t.map(a=>({id:a,depth:0}));for(let a=0;a<s.length;a+=1){let r=s[a];if(!(!r||r.depth>=i))for(let c of n.get(r.id)??[])o.has(c)||(o.add(c),s.push({id:c,depth:r.depth+1}));}return [...o]}function Tn(e){let t=["name","specifier","package","module"].flatMap(i=>{let n=e.attributes[i];return Array.isArray(n)?n:[n]});return new Set([e.label,...e.identity.aliases,...t].filter(i=>typeof i=="string").map(i=>i.trim().toLowerCase()).filter(Boolean))}function jo(e,t,i,n){let o=vo(e,t),s=Mn[i]??Mn.unknown,a=[...new Set(n.map(c=>c.trim().toLowerCase()).filter(Boolean))];if(a.length>0){let c=o.filter(p=>s?.includes(p.kind)&&a.some(y=>Tn(p).has(y))),l=new Set(a.filter(p=>c.some(y=>Tn(y).has(p))));return {roots:c.length>0?c.slice(0,12):[t],unresolvedSubjects:n.filter(p=>!l.has(p.trim().toLowerCase()))}}let r=o.filter(c=>s?.includes(c.kind)).slice(0,6);return {roots:r.length>0?r:[t],unresolvedSubjects:[]}}function xo(e,t,i){let n=i.issueClass??"unknown",o=[...new Set((i.subjects??[]).map(h=>h.trim()).filter(Boolean))],{roots:s,unresolvedSubjects:a}=jo(e,t,n,o),r=new Map(e.entities.map(h=>[h.id,h])),c=wo(e,s.map(h=>h.id),3).map(h=>r.get(h)).filter(h=>!!h),l=c.filter(h=>!s.some(w=>w.id===h.id)&&yo.has(h.kind)).slice(0,20),p=c.filter(h=>ho.has(h.kind)).slice(0,8),v=[...l,...p].filter((h,w,b)=>b.findIndex(D=>D.id===h.id)===w).slice(0,12).flatMap(h=>{let b=s.map(D=>d$6(e,D.id,h.id)).filter(D=>D.found).sort((D,F)=>D.hops.length-F.hops.length)[0];return b?[{from:b.resolvedFrom??b.from,to:b.resolvedTo??b.to,entityPath:b.entityPath,hops:b.hops,proofIds:b.proofs.map(D=>D.id)}]:[]}),j=new Set([...s.flatMap(h=>h.proofIds),...v.flatMap(h=>h.proofIds)]),k=e.proofs.filter(h=>j.has(h.id)).map(h=>h.artifact).filter((h,w,b)=>b.indexOf(h)===w).sort().slice(0,20),g=[];return l.length===0&&g.push("No affected surface is structurally reachable from the selected root evidence."),p.length===0&&g.push("No graph-connected test suite or pipeline is available as a verification target."),k.length===0&&g.push("The selected graph entities do not carry portable source evidence."),a.length>0&&g.push(`No canonical graph entity resolved for ${a.length} reported subject(s): ${a.join(", ")}.`),{issueId:i.id,issueClass:n,status:i.status==="fail"?"fail":"warn",reason:i.reason,scope:"structural-impact-candidates",subjects:o,unresolvedSubjects:a,rootEntities:s.map($t),affectedEntities:l.map($t),verificationTargets:p.map($t),proofPaths:v,sourceArtifacts:k,unknowns:g}}async function Nt(e){if(!e.workspacePath)return Se(e,"graph-missing","Project is not attached to a Workspai workspace; no workspace graph can be consulted.");let t=d.join(e.workspacePath,b$4),i=d.join(e.workspacePath,a.model);if(!await u.pathExists(t))return Se(e,"graph-missing","Workspace knowledge graph is missing. Run workspace model before relying on graph-aware diagnosis.");if(!await u.pathExists(i))return Se(e,"model-missing","Canonical workspace model is missing, so graph source binding cannot be verified.");let n,o;try{let c=await u.readJSON(t),l=await u.readJSON(i);a$4(c,"contracts/workspace-intelligence/workspace-knowledge-graph.v1.json","Doctor graph diagnosis source"),a$4(l,"contracts/workspace-intelligence/workspace-model.v1.json","Doctor graph diagnosis model"),n=c,o=l;}catch(c){return Se(e,"invalid",`Graph-aware diagnosis rejected invalid evidence: ${c instanceof Error?c.message:String(c)}`)}let s={artifact:b$4,schemaVersion:n.schemaVersion,sourceArtifact:n.source.artifact,sourceHash:n.source.hash,entityCount:n.entities.length,relationCount:n.relations.length,proofCount:n.proofs.length};try{c$2(n,o);}catch(c){return Se(e,"stale",c instanceof Error?c.message:String(c),s)}let a$1=ko(n,e);if(!a$1)return Se(e,"project-unresolved","The current project could not be resolved to one canonical project entity.",s);let r=[...(e.probes??[]).filter(c=>c.status!=="pass"),...(e.issues??[]).map((c,l)=>({id:`legacy-project-issue-${l+1}`,status:"fail",reason:c,issueClass:"runtime"}))].map(c=>xo(n,a$1,c));return {schemaVersion:d$3,generatedAt:(e.now??new Date).toISOString(),status:"available",claimBoundary:On,graph:s,project:{name:e.projectName,path:Ft(e.workspacePath,e.projectPath),entityId:a$1.id},summary:{findingCount:r.length,rootEntityCount:new Set(r.flatMap(c=>c.rootEntities.map(l=>l.id))).size,affectedEntityCount:new Set(r.flatMap(c=>c.affectedEntities.map(l=>l.id))).size,verificationTargetCount:new Set(r.flatMap(c=>c.verificationTargets.map(l=>l.id))).size,proofPathCount:r.reduce((c,l)=>c+l.proofPaths.length,0),subjectCount:new Set(r.flatMap(c=>c.subjects)).size,unresolvedSubjectCount:new Set(r.flatMap(c=>c.unresolvedSubjects)).size,unknownCount:r.reduce((c,l)=>c+l.unknowns.length,0)},findings:r,diagnostics:[]}}var _t=a.doctor;function ei(e){return [...new Set(e.filter(t=>t&&t.trim().length>0))]}function _n(e){return [...new Set(e.filter(t=>t&&t.trim().length>0))]}function Co(){let e=t$1().map(n=>d.join(n,b$6()?"poetry.exe":"poetry")),t=b$6()?[d.join(process.env.APPDATA||"","Python","Scripts","poetry.exe"),d.join(process.env.USERPROFILE||"","AppData","Roaming","Python","Scripts","poetry.exe")]:[],i=b$6()?[]:["/usr/local/bin/poetry","/usr/bin/poetry"];return ei([...e,...t,...i])}function Po(e,t=process.cwd()){let i=t$1().map(l=>({location:"Global (user-local)",path:d.join(l,b$6()?"rapidkit.exe":"rapidkit")})),n$1=[{location:"Global (pipx)",path:d.join(e,".local","bin","rapidkit")},{location:"Global (pipx)",path:d.join(e,"AppData","Roaming","Python","Scripts","rapidkit.exe")},{location:"Global (pyenv)",path:d.join(e,".pyenv","shims","rapidkit")},{location:"Global (system)",path:"/usr/local/bin/rapidkit"},{location:"Global (system)",path:"/usr/bin/rapidkit"}],o=n(d.join(t,".venv")),s=p(t),a=[{location:"Workspace (.venv)",path:o},...s.map(l=>({location:"Workspace (launcher)",path:l}))],r=[...i,...n$1,...a],c=new Set;return r.filter(l=>c.has(l.path)?false:(c.add(l.path),true))}function Do(e){let t=new Map([["Workspace (.venv)",0],["Global (user-local)",1],["Global (pipx)",2],["Global (pyenv)",3],["Global (system)",4]]);return [...e].sort((i,n)=>{let o=t.get(i.location)??Number.MAX_SAFE_INTEGER,s=t.get(n.location)??Number.MAX_SAFE_INTEGER;return o!==s?o-s:i.path.localeCompare(n.path)})}function Gn(e,t){if(e.status!=="error")return e;let i=[e.details,t].filter(n=>typeof n=="string"&&n.trim().length>0).join(" ");return {...e,status:"warn",...i?{details:i}:{}}}function ti(e,t){let i=t.some(n=>n.runtimeFamily==="python");return {...e,python:i?e.python:Gn(e.python,"Python is optional because this scope has no detected Python project."),rapidkitCore:/not installed/i.test(e.rapidkitCore.message)?Gn(e.rapidkitCore,"RapidKit Core is an optional engine for Python-backed kits and modules; Workspai CLI diagnostics remain available without it."):e.rapidkitCore}}function Ro(e){let i=(e.probes??[]).filter(a=>a.status==="warn").length,n=e.issues.some(a=>a.toLowerCase().includes("environment file missing")),o=(e.probes??[]).some(a=>a.id==="surface-env-contract"),s=(e.probes??[]).some(a=>a.id==="surface-security-hygiene");return e.hasEnvFile===false&&!n&&!o&&(i+=1),typeof e.vulnerabilities=="number"&&e.vulnerabilities>0&&!s&&(i+=1),i}function So(e){let t=e.coreVersion?.split(".")[0],i=e.npmVersion?.split(".")[0];return !t||!i?false:t!==i}var Eo="doctor-project-scan-v2",Ao="doctor-project-scan-policy-v1",ni=d$2.doctorWorkspaceCache.schemaVersion,$o=Object.freeze({version:"doctor-evidence-v1",scoringPolicyVersion:"doctor-score-policy-v2",generatedBy:"workspai",deterministicScoreBreakdown:true,scopeModel:"workspace-aggregate-or-project-scoped"}),Le=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 $e(){return {...$o}}function mt(e){let t=e.profile?.trim();return t&&t in Le?{...Le[t]}:e.strict?{...Le.release}:e.ci?{...Le.ci}:{...Le.local}}function ut(e){return !e||e.total<=0?null:Math.round(e.passed/e.total*100)}function Fo(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 No(e,t){let i=Fo(e),n=Date.parse(t),o=typeof i.ttlSeconds=="number"?i.ttlSeconds*1e3:null,s=o!==null&&Number.isFinite(n)?new Date(n+o).toISOString():void 0,a=!Number.isFinite(n)||o!==null&&!s?"unknown":o!==null&&Date.now()>n+o?"stale":"fresh";return {category:i.category,generatedAt:t,ttlSeconds:i.ttlSeconds,...s?{expiresAt:s}:{},status:a,verifyBeforeUse:i.category!=="structure"||a!=="fresh",reason:i.reason}}function Io(e){let t=e.id.toLowerCase(),i=`${e.label} ${e.reason} ${e.recommendation??""}`.toLowerCase();return t.includes("dependency")||t.includes("lockfile")||i.includes("lockfile")?"dependency":t.includes("security")||i.includes("vulnerabilit")||i.includes("audit")?"security":t.includes("env")||i.includes(".env")||i.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 ii(e){let t=e.dependencyAudit?.subjects.map(i=>i.name)??[];return (e.probes??[]).map(i=>({...i,...i.id==="surface-security-hygiene"&&t.length>0?{subjects:t}:{}}))}function Mo(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 To(e){let{probe:t,freshness:i}=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(i.status!=="fresh")return {mode:"refresh-evidence",confidence:"high",primaryActionLabel:"Refresh evidence",requiresApproval:false,requiresFreshEvidence:true,reason:`Evidence is ${i.status}; refresh Doctor before applying repairs.`,relatedCommands:["npx workspai doctor project --json"]};if(n?.status==="manual"||n?.requiresReview)return {mode:"review-required",confidence:"medium",primaryActionLabel:"Review fix path",requiresApproval:true,requiresFreshEvidence:i.verifyBeforeUse,reason:n?.reason??t.recommendation??t.reason,relatedCommands:_n(n?.refreshCommands??["npx workspai doctor project --json"])};if(i.verifyBeforeUse&&i.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:i.verifyBeforeUse,reason:n.reason,relatedCommands:_n([...n.command?[n.command]:[],...n.verifyCommand?[n.verifyCommand]:[],...n.refreshCommands])}}return t.recommendation?{mode:"manual-guidance",confidence:"medium",primaryActionLabel:"Inspect guidance",requiresApproval:false,requiresFreshEvidence:i.verifyBeforeUse,reason:t.recommendation,relatedCommands:["npx workspai doctor project --json"]}:{mode:"manual-guidance",confidence:"low",primaryActionLabel:"Inspect issue",requiresApproval:false,requiresFreshEvidence:i.verifyBeforeUse,reason:"Doctor classified the issue but does not have a deterministic repair path yet.",relatedCommands:["npx workspai doctor project --json"]}}function oi(e,t){let i=No(e,e.freshness?.generatedAt??t),n=e.issueClass??Io(e),o=e.operationalImpact??Mo(e,n),s=To({probe:e,freshness:i});return {...e,freshness:i,issueClass:n,operationalImpact:o,repairIntent:s}}function Kn(e,t){Array.isArray(e.probes)&&(e.probes=e.probes.map(i=>oi(i,t)));}function ri(e,t){let i=e.flatMap(c=>Array.isArray(c.probes)?c.probes.map(l=>l.freshness).filter(l=>!!l):[]),n=i.filter(c=>c.status==="stale").length,o=i.filter(c=>c.status==="unknown").length,s=i.filter(c=>c.category==="state").length,a=i.filter(c=>c.verifyBeforeUse).length,r=i.map(c=>c.generatedAt).filter(Boolean).sort()[0];return {generatedAt:t,status:n>0?"stale":o>0?"unknown":"fresh",staleProbeCount:n,unknownProbeCount:o,liveStateProbeCount:s,verifyBeforeUseProbeCount:a,...r?{oldestProbeGeneratedAt:r}:{}}}function si(e){return typeof e=="number"?e:Array.isArray(e)?e.length:0}async function ai(e,t){try{if(!await u.pathExists(e))return null;let i=await u.readJSON(e);return c$3(i,t)?i:null}catch{return null}}function ci(e,t){if(!e?.system)return [];let i=[{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 i){let s=e.system?.[o.id]?.status;!s||s===o.current.status||n.push({id:o.id,from:s,to:o.current.status});}return n}function Oo(e,t){let i=new Map;for(let v of t.projects)i.set(v.path||v.name,v.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 v of n){let j=v.path||v.name;j&&o.set(j,si(v.issues));}let s=0,a=0,r=new Set,c=new Set,l=new Set([...Array.from(o.keys()),...Array.from(i.keys())]);for(let v of l){let j=o.get(v)??0,k=i.get(v)??0;k>j?(s+=k-j,r.add(v)):k<j&&(a+=j-k,c.add(v));}let p=ut(e.healthScore),y=ut(t.healthScore);return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:s,resolvedIssueCount:a,netIssueDelta:s-a,scoreDeltaPercent:p===null||y===null?null:y-p,systemStatusChanges:ci(e,{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore}),regressedProjects:Array.from(r).sort(),improvedProjects:Array.from(c).sort()}}function _o(e,t){if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let i=si(e.project?.issues),n=t.project.issues.length,o=Math.max(n-i,0),s=Math.max(i-n,0),a=ut(e.healthScore),r=ut(t.healthScore),c=t.project.path||t.project.name;return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:o,resolvedIssueCount:s,netIssueDelta:o-s,scoreDeltaPercent:a===null||r===null?null:r-a,systemStatusChanges:ci(e,{python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore}),regressedProjects:o>0?[c]:[],improvedProjects:s>0?[c]:[]}}function li(e){let t=e??[],i=0,n=0;for(let a of t){if(a.scope==="project-scoped"){i+=1;continue}(a.scope==="workspace-aggregate"||a.scope==="host-system")&&(n+=1);}let o=i>0&&n>0?1:0,s=o>0?"mixed":i>0?"scoped":n>0?"aggregated":"unknown";return {scopedCount:i,aggregatedCount:n,mixedCount:o,dominantScope:s}}function q(e,t){return b$6()?`Set-Location -LiteralPath "${e.replace(/"/g,'`"')}"; ${t}`:`cd '${e.replace(/'/g,`'"'"'`)}' && ${t}`}function de(e){return b$6()?q(e,"Copy-Item .env.example .env"):q(e,"cp .env.example .env")}function Wn(e){return q(e,"poetry install --no-root")}function Go(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==="C"||e==="C++"||e==="Deno"||e==="Bun"||e==="PHP"||e==="Laravel"||e==="Ruby"||e==="Ruby on Rails"||e==="ASP.NET"?"extended":"observed"}function Ko(e){return e==="Tauri"||e==="Electron"?"desktop":e==="VS Code Extension"?"extension":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"||e==="Go"||e==="Java"||e==="Scala"||e==="Kotlin"||e==="C"||e==="C++"?"generic":"backend"}function Wo(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==="Express"||e==="Fastify"||e==="Koa"||e==="Tauri"||e==="Electron"||e==="VS Code Extension"||e==="Node.js"?"node":e==="Bun"?"bun":e==="FastAPI"||e==="Django"||e==="Flask"||e==="Python"?"python":e==="Go/Fiber"||e==="Go/Gin"||e==="Go"||e==="Echo"?"go":e==="Spring Boot"||e==="Java"?"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":e==="Scala"?"scala":e==="Kotlin"?"kotlin":e==="C"?"c":e==="C++"?"cpp":"unknown"}function Gt(e,t){let i=w(t);e.commandCapabilities=i,e.supportTier=i.frameworkSupportTier;}function lt(e,t,i,n){e.framework=t,e.frameworkConfidence=i,e.supportTier=Go(t),e.projectKind=Ko(t),e.runtimeFamily=Wo(t);}function di(e){return e==="python"?"python":e==="node"?"node":e==="bun"?"bun":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":e==="scala"?"scala":e==="kotlin"?"kotlin":e==="c"?"c":e==="cpp"?"cpp":"unknown"}function Bt(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 "tauri":return "Tauri";case "electron":return "Electron";case "vscode-extension":return "VS Code Extension";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":return e.key==="sinatra"?"Ruby":"PHP";case "c":return "C";case "cpp":return "C++";case "unknown":return "Unknown";default:return "Unknown"}}function Bo(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 Ho(e,t){e.framework=Bt(t),e.frameworkKey=t.key,e.importStack=t.importStack,e.frameworkConfidence=t.confidence,e.supportTier=t.supportTier,e.projectKind="frontend",e.runtimeFamily=di(t.runtime);}function ee(e,t){e.framework=Bt(t),e.frameworkKey=t.key,e.importStack=t.importStack,e.frameworkConfidence=t.confidence,e.supportTier=t.supportTier,e.projectKind=t.key==="tauri"||t.key==="electron"?"desktop":t.key==="vscode-extension"?"extension":Bo(t)?"generic":"backend",e.runtimeFamily=di(t.runtime);}function qo(e){let t=e.dependencies,i=e.scripts??{},n=(e.kitName??"").toLowerCase(),o=a=>!!t[a],s=Object.values(i).filter(a=>typeof a=="string").join(" ").toLowerCase();return o("next")||s.includes("next ")?{framework:"Next.js",confidence:"high"}:o("nuxt")||s.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")||s.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 Lo(e,t){let i=j$3(e,t??null);return i.runtime!=="python"?{framework:"Python",confidence:"low"}:{framework:Bt(i),confidence:i.confidence}}async function Bn(e){try{let t=await u.stat(e);return `${d.basename(e)}:${t.isDirectory()?"d":"f"}:${t.size}:${t.mtimeMs}`}catch{return `${d.basename(e)}:missing`}}async function Vo(e){try{let t=new Set([".git",".venv","node_modules",".workspai",".rapidkit","dist","build","coverage","__pycache__"]),i=new Set,n=async a=>{if(await ze(a))return true;let r=["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 c of r){if(c==="*.csproj"){if((await u.readdir(a).catch(()=>[])).some(p=>p.endsWith(".csproj")))return true;continue}if(await u.pathExists(d.join(a,c)))return true}return false};await ze(e)&&i.add(e);let o=await a$2(e);for(let a of o){let r=d.isAbsolute(a.path)?a.path:d.join(e,a.path);await n(r)&&i.add(r);}return (await a$3(e,{skipDirs:t,descendIntoMatchedProjects:false,isProjectDir:async(a,r)=>d.resolve(a)===d.resolve(r)?ze(a):n(a)})).forEach(a=>i.add(a)),i.size===0&&(await ur(e,3,t)).forEach(r=>i.add(r)),i.size===0&&!await b$2(e)&&await n(e)&&i.add(e),Array.from(i).sort((a,r)=>a.localeCompare(r))}catch{return []}}async function Jo(e,t){let i=[d.join(e,".workspai-workspace"),d.join(e,".workspai","workspace.json"),d.join(e,".workspai","imported-projects.json"),d.join(e,".workspai","policies.yml"),d.join(e,".workspai","toolchain.lock"),d.join(e,".workspai","cache-config.yml"),d.join(e,".rapidkit-workspace"),d.join(e,".rapidkit","workspace.json"),d.join(e,".rapidkit","imported-projects.json"),d.join(e,".rapidkit","policies.yml"),d.join(e,".rapidkit","toolchain.lock"),d.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(i.map(Bn)),s=await Promise.all(t.map(async a=>{let r=await Promise.all(n.map(c=>Bn(d.join(a,c))));return `${a}::${r.join("|")}`}));return [Eo,Ao,...o,...s].join("||")}async function zo(e,t){try{if(!await u.pathExists(e))return null;let i=await u.readJSON(e);a$4(i,"contracts/doctor-workspace-cache.v2.json",`Doctor workspace cache ${e}`);let n=i;return !n||n.signature!==t||!Array.isArray(n.projects)||typeof n.schemaVersion=="string"&&n.schemaVersion!==ni?null:n}catch{return null}}async function Uo(e,t){try{a$4(t,"contracts/doctor-workspace-cache.v2.json",`Doctor workspace cache ${e}`),await u.ensureDir(d.dirname(e)),await u.writeJSON(e,t,{spaces:2});}catch{}}async function Zo(e,t,i){let n=d.join(e,_t);try{let o=[];for(let l of t.projects){for(let p of l.issues??[])typeof p=="string"&&p.trim()&&o.push(`${l.name}: ${p.trim()}`);for(let p of l.probes??[])p.status==="fail"&&p.reason.trim()&&o.push(`${l.name}: ${p.reason.trim()}`);}for(let[l,p]of [["python",t.python],["rapidkitCore",t.rapidkitCore]])if(p?.status==="error"){let y=typeof p.message=="string"?p.message:`${l} check failed`;o.push(`${l}: ${y}`);}let s=t.projects.map(te),a=s.reduce((l,p)=>l+p.blockingFindings,0),r=s.reduce((l,p)=>l+p.advisoryFindings,0),c=f$1({schemaVersion:a$5,evidenceType:"workspace",contract:$e(),policyProfile:t.policyProfile,workspacePath:e,workspaceName:t.workspaceName,projectScanCached:t.projectScanCached??false,projectScanSignature:t.projectScanSignature,cachePath:i,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((l,p)=>l+p.issues.length,0),verdict:t.healthScore?.verdict??"passed",blockingFindings:a,advisoryFindings:r,projectAdvisoryWarningProjects:s.filter(l=>l.advisoryFindings>0).length,projectAdvisoryWarnings:r,hasSystemErrors:[t.python,t.rapidkitCore].some(l=>l.status==="error"),scopeProvenance:t.scopeProvenance},driftDelta:t.driftDelta,scoreBreakdown:t.scoreBreakdown??[]},{commandId:"checkWorkspaceHealth",exitCode:Ze(t.healthScore,{profile:t.policyProfile?.name}),generatedAt:new Date().toISOString(),blockers:o.slice(0,12),runId:e$2()});return d$4(c),await e$1(e,_t,c),n}catch(o){if(o instanceof Error&&o.message.includes("violates contracts/"))throw o;return}}async function Ht(e=process.cwd()){let[t,i,n,o,s]=await Promise.all([Yo(),Qo(),Xo(),er(),tr(e)]);return {python:t,poetry:i,pipx:n,go:o,rapidkitCore:s}}async function Yo(){let e=j$2(),t;for(let i of e)try{let n=i==="py"?["-3","--version"]:["--version"],{stdout:o,stderr:s}=await execa(i,n,{timeout:3e3,reject:false}),r=`${o??""}
|
|
15
|
+
${s??""}`.match(/Python\s+(\d+\.\d+(?:\.\d+)?)/i);if(r){let c=r[1],[l,p]=c.split(".").map(Number);if(l<3||l===3&&p<10){t??={version:c,command:[i,...n.slice(0,-1)].join(" ")};continue}return {status:"ok",message:`Python ${c}`,details:`Using ${[i,...n.slice(0,-1)].join(" ")}`}}}catch{continue}return t?{status:"warn",message:`Python ${t.version} (requires 3.10+)`,details:`${t.command} found but version is below minimum requirement`}:{status:"error",message:"Python not found",details:"Install Python 3.10+ and ensure it's in PATH"}}async function Qo(){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=j$2().map(t=>({cmd:t,args:t==="py"?["-3","-m","poetry","--version"]:["-m","poetry","--version"]}));for(let t of e)try{let{stdout:i}=await execa(t.cmd,t.args,{timeout:3e3,shell:c$1()}),n=i.match(/Poetry .*version ([\d.]+)/)||i.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 Co())try{if(!await u.pathExists(t))continue;let{stdout:i}=await execa(t,["--version"],{timeout:3e3,shell:c$1()}),n=i.match(/Poetry .*version ([\d.]+)/)||i.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 Xo(){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=j$2();for(let t of e)try{let i=t==="py"?["-3","-m","pipx","--version"]:["-m","pipx","--version"],{stdout:n}=await execa(t,i,{timeout:3e3,shell:c$1()});return {status:"ok",message:`pipx ${n.trim()}`,details:`Available via ${t} ${i.join(" ")}`}}catch{continue}return {status:"warn",message:"pipx not installed",details:"Optional: Install for isolated Python tools"}}}async function er(){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 tr(e=process.cwd()){let t=process.env.HOME||process.env.USERPROFILE||"",i=[],n=[],o=Po(t,e);for(let{location:a,path:r}of o)try{if(await u.pathExists(r)){let{stdout:c,exitCode:l}=await execa(r,["--version"],{timeout:3e3,reject:false});if(l===0&&(c.includes("RapidKit Version")||c.includes("RapidKit"))){let p=c.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(p){let y=await execa(r,["list","--json"],{timeout:5e3,reject:false});y.exitCode===0?i.push({location:a,path:r,version:p[1]}):n.push({location:a,path:r,version:p[1],reason:Ve(y.stderr||y.stdout)});}}}}catch(c){await u.pathExists(r)&&n.push({location:a,path:r,reason:Ve(c instanceof Error?c.message:String(c))});continue}if(i.length>0){let a=i.filter(c=>c.location!=="Workspace (launcher)");if(a.length>0){let c=Do(a),l=c[0].version,p=c.some(j=>j.location==="Workspace (.venv)"),y=c.some(j=>j.location.startsWith("Global (")),v=!p&&y?"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 ${l}`,details:v,paths:c.map(j=>({location:j.location,path:j.path,version:j.version}))}}return {status:"ok",message:`RapidKit Core ${i[0].version}`,details:"Detected via workspace launcher"}}try{let{stdout:a,exitCode:r}=await execa("rapidkit",["--version"],{timeout:3e3,reject:false});if(r===0&&(a.includes("RapidKit Version")||a.includes("RapidKit"))){let c=a.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(c){let l=await execa("rapidkit",["list","--json"],{timeout:5e3,reject:false});if(l.exitCode===0)return {status:"ok",message:`RapidKit Core ${c[1]}`,details:"Available via PATH"};n.push({location:"PATH",path:"rapidkit",version:c[1],reason:Ve(l.stderr||l.stdout)});}}}catch{}try{let{stdout:a,exitCode:r}=await execa("poetry",["run","rapidkit","--version"],{timeout:3e3,reject:false});if(r===0&&(a.includes("RapidKit Version")||a.includes("RapidKit"))){let c=a.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(c){let l=await execa("poetry",["run","rapidkit","list","--json"],{timeout:5e3,reject:false});if(l.exitCode===0)return {status:"ok",message:`RapidKit Core ${c[1]}`,details:"Available via Poetry"};n.push({location:"Poetry",path:"poetry run rapidkit",version:c[1],reason:Ve(l.stderr||l.stdout)});}}}catch{}let s=j$2();for(let a of s)try{let r=a==="py"?["-3","-c","import rapidkit_core; print(rapidkit_core.__version__)"]:["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{stdout:c,exitCode:l}=await execa(a,r,{timeout:3e3,reject:false});if(l===0&&c&&!c.includes("Traceback")&&!c.includes("ModuleNotFoundError")){let p=c.trim();if(p){let v=await execa(a,a==="py"?["-3","-m","rapidkit","list","--json"]:["-m","rapidkit","list","--json"],{timeout:5e3,reject:false});if(v.exitCode===0)return {status:"ok",message:`RapidKit Core ${p}`,details:`Available in ${a} environment`};n.push({location:`${a} environment`,path:`${a} -m rapidkit`,version:p,reason:Ve(v.stderr||v.stdout)});}}}catch{continue}if(n.length>0){let a=n[0];return {status:"error",message:a.version?`RapidKit Core ${a.version} installed but unusable`:"RapidKit Core installed but unusable",details:`${a.reason} Reinstall or repair this Python environment before running Core-backed commands.`,paths:n.map(({location:r,path:c,version:l})=>({location:r,path:c,...l?{version:l}:{}}))}}return {status:"error",message:"RapidKit Core not installed",details:"Install with: pipx install rapidkit-core"}}function Ve(e){let t=e.replace(/\x1b\[[0-9;]*m/g,"").replace(/\s+/g," ").trim();return t?t.length>240?`${t.slice(0,237)}...`:t:"A real Core catalog command failed without diagnostics."}async function z(e,t,i){let n=d.join(e,"Dockerfile");t.hasDocker=await u.pathExists(n);let o=d.join(e,"tests"),s=d.join(e,"test"),a=d.join(e,"src","test"),r=await u.pathExists(o)||await u.pathExists(s)||await u.pathExists(a),c=false;if(t.framework==="Go/Fiber"||t.framework==="Go/Gin")try{let l=[{dir:e,depth:0}],p=4,y=new Set([".git",".venv","node_modules","dist","build","vendor"]);for(;l.length>0&&!c;){let v=l.shift();if(!v)break;let j=[];try{j=await u.readdir(v.dir);}catch{continue}for(let k of j){let g=d.join(v.dir,k),h;try{h=await u.stat(g);}catch{continue}if(h.isFile()&&k.endsWith("_test.go")){c=true;break}h.isDirectory()&&v.depth<p&&!y.has(k)&&!k.startsWith(".")&&l.push({dir:g,depth:v.depth+1});}}}catch{}if(t.hasTests=r||c,(t.runtimeFamily==="node"||t.runtimeFamily==="bun")&&!t.hasTests&&(t.hasTests=await Dn(e,i)),t.runtimeFamily==="node"||t.runtimeFamily==="bun")t.hasCodeQuality=await Pn(e,i);else if(t.framework==="Go/Fiber"||t.framework==="Go/Gin"){let l=d.join(e,".golangci.yml"),p=d.join(e,".golangci.yaml"),y=d.join(e,"Makefile"),v=await u.pathExists(y)&&(await u.readFile(y,"utf8")).includes("golangci-lint");t.hasCodeQuality=await u.pathExists(l)||await u.pathExists(p)||v;}else if(t.runtimeFamily==="python"){let l=d.join(e,"ruff.toml"),p=d.join(e,"pyproject.toml");if(await u.pathExists(p))try{let y=await u.readFile(p,"utf8");t.hasCodeQuality=y.includes("[tool.ruff]")||await u.pathExists(l);}catch{t.hasCodeQuality=await u.pathExists(l);}}else if(t.framework==="Spring Boot"){let l=d.join(e,"pom.xml");if(await u.pathExists(l))try{let p=await u.readFile(l,"utf8");t.hasCodeQuality=p.includes("spotless")||p.includes("checkstyle")||p.includes("pmd")||p.includes("maven-enforcer-plugin");}catch{t.hasCodeQuality=false;}}t.dependencyAudit=await In({projectPath:e,runtime:t.runtimeFamily??"unknown"}),t.vulnerabilities=t.dependencyAudit.status==="vulnerable"?t.dependencyAudit.blockingFindingCount??t.dependencyAudit.findingCount??0:void 0;}function nr(e){return ei([m$1(e),d.join(e,"Scripts","python.exe"),d.join(e,"Scripts","python"),d.join(e,"bin","python"),d.join(e,"bin","python3")])}function ir(e){let t=e.indexOf("["),i=e.lastIndexOf("]");if(t<0||i<t)return null;try{let n=JSON.parse(e.slice(t,i+1));return Array.isArray(n)?n:null}catch{return null}}async function Hn(e){for(let t of nr(e.environmentPath)){if(!await u.pathExists(t))continue;let i;try{let n=await execa(t,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:2e3,reject:false});n.exitCode===0&&n.stdout.trim()&&(i=n.stdout.trim());}catch{}if(e.frameworkImport)try{if((await execa(t,["-c",`import ${e.frameworkImport}`],{timeout:2e3,reject:false})).exitCode===0)return {interpreter:t,coreVersion:i,dependenciesInstalled:true}}catch{}try{let n=await execa(t,["-m","pip","list","--format=json"],{timeout:5e3,reject:false}),o=ir(`${n.stdout??""}
|
|
16
|
+
${n.stderr??""}`),s=new Set(["pip","setuptools","wheel"]),a=o?.some(r=>typeof r.name=="string"&&!s.has(r.name.toLowerCase()))??false;return {interpreter:t,coreVersion:i,dependenciesInstalled:a}}catch{return {interpreter:t,coreVersion:i,dependenciesInstalled:false}}}return {dependenciesInstalled:false}}async function or(e,t,i){let n=d.join(e,".venv");if(await u.pathExists(n))return {environmentPath:n,...await Hn({environmentPath:n,frameworkImport:t})};if(i)try{let o=await execa("poetry",["env","info","--path"],{cwd:e,timeout:3e3,reject:false}),s=o.stdout.trim();if(o.exitCode===0&&s&&await u.pathExists(s))return {environmentPath:s,...await Hn({environmentPath:s,frameworkImport:t})}}catch{}return {dependenciesInstalled:false}}function O(e,t){e.probes||(e.probes=[]);let i=oi(t,new Date().toISOString());e.probes.push(i),i.repairCapability&&(e.repairCapabilities||(e.repairCapabilities=[]),e.repairCapabilities.push(i.repairCapability),i.repairCapability.status==="available"&&i.repairCapability.canAutoFix&&i.repairCapability.command&&(e.fixCommands=e.fixCommands??[],e.fixCommands.includes(i.repairCapability.command)||e.fixCommands.push(i.repairCapability.command)));}async function Je(e,t){return (await Promise.all(t.map(i=>u.pathExists(d.join(e,i))))).some(Boolean)}async function It(e,t){let i=new Set(t.ignoreDirs??["node_modules",".git","bin","obj","dist"]),o=(t.under&&t.under.length>0?t.under:["."]).map(s=>d.join(e,s));for(;o.length>0;){let s=o.shift(),a;try{a=await u.readdir(s,{withFileTypes:true});}catch{continue}for(let r of a){if(r.isFile()&&(t.name&&r.name===t.name||t.suffix&&r.name.endsWith(t.suffix)))return true;r.isDirectory()&&!i.has(r.name)&&o.push(d.join(s,r.name));}}return false}async function rr(e,t){let i=t.runtimeFamily||"unknown";if(t.projectKind==="backend"||t.projectKind==="generic"||t.projectKind==="desktop"||t.projectKind==="extension"){if(i==="node"){let o=await u.pathExists(d.join(e,"package-lock.json"))||await u.pathExists(d.join(e,"pnpm-lock.yaml"))||await u.pathExists(d.join(e,"yarn.lock"));O(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 s=t.projectKind==="extension"?["src/extension.ts","src/extension.js","extension.ts","extension.js"]:t.projectKind==="desktop"?["src/main.ts","src/main.js","src/index.ts","src/index.js","src-tauri/src/main.rs"]:["src/main.ts","src/main.js","src/server.ts","src/server.js","server.ts","server.js","index.ts","index.js"],a=await Je(e,s);O(t,{id:"adapter-node-boot-entrypoint",label:t.projectKind==="extension"?"Extension activation entrypoint":t.projectKind==="desktop"?"Desktop application entrypoint":"Node adapter boot entrypoint",status:a?"pass":"warn",severity:"warn",scope:"project-scoped",reason:a?`${t.projectKind==="extension"?"Extension":t.projectKind==="desktop"?"Desktop application":"Service"} entrypoint markers detected.`:`No canonical ${t.projectKind==="extension"?"extension activation":t.projectKind==="desktop"?"desktop application":"Node boot"} entrypoint markers detected.`,recommendation:a?void 0:t.projectKind==="extension"?"Expose the extension activation module declared by package.json.":t.projectKind==="desktop"?"Expose and document the desktop main-process or Tauri entrypoint.":"Define and document service bootstrap entrypoint (main/server)."});return}if(i==="python"){let o=await u.pathExists(d.join(e,"poetry.lock"))||await u.pathExists(d.join(e,"requirements.txt"))||await u.pathExists(d.join(e,"uv.lock"));O(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 Je(e,["src/main.py","src/app/main.py","app/main.py","main.py","manage.py","asgi.py","wsgi.py"]);O(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(i==="java"){let o=await u.pathExists(d.join(e,"mvnw"))||await u.pathExists(d.join(e,"gradlew"));O(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."});let s=await Je(e,["src/main/java/Application.java","src/main/kotlin/Application.kt"])||await It(e,{suffix:"Application.java",under:["src/main/java"]})||await It(e,{suffix:"Application.kt",under:["src/main/kotlin"]});O(t,{id:"adapter-java-boot-entrypoint",label:"Java adapter boot entrypoint",status:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Java application entrypoint markers detected.":"No Java application entrypoint markers detected.",recommendation:s?void 0:"Expose a Spring Boot Application class under src/main/java or src/main/kotlin."});return}if(i==="go"){let o=await u.pathExists(d.join(e,"go.sum"));O(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."});let s=await Je(e,["cmd/server/main.go","cmd/api/main.go","main.go"]);O(t,{id:"adapter-go-boot-entrypoint",label:"Go adapter boot entrypoint",status:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Go application entrypoint markers detected.":"No Go application entrypoint markers detected.",recommendation:s?void 0:"Expose a Go main package entrypoint such as cmd/server/main.go."});return}if(i==="dotnet"){let o=await Je(e,["Program.cs","src/Program.cs"])||await It(e,{name:"Program.cs"});O(t,{id:"adapter-dotnet-boot-entrypoint",label:".NET adapter boot entrypoint",status:o?"pass":"warn",severity:"warn",scope:"project-scoped",reason:o?".NET application entrypoint markers detected.":"No .NET application entrypoint markers detected.",recommendation:o?void 0:"Expose Program.cs at the project root or under src for deterministic boot probes."});}}}async function sr(e,t){let i=[d.join(e,".workspai","doctor.adapters.json"),d.join(e,".rapidkit","doctor.adapters.json"),d.join(e,"doctor.adapters.json")];for(let n of i)if(await u.pathExists(n))try{let o=await u.readJSON(n),s=Array.isArray(o?.checks)?o.checks:[];for(let a=0;a<s.length;a+=1){let r=s[a]||{},c=Array.isArray(r.runtimes)?r.runtimes:[];if(c.length>0&&!c.includes(t.runtimeFamily||"unknown"))continue;let l=typeof r.id=="string"&&r.id.trim().length>0?r.id.trim():`adapter-check-${a+1}`,p=typeof r.label=="string"&&r.label.trim().length>0?r.label.trim():l,y=r.severity||"warn",v=Array.isArray(r.anyOfPaths)?r.anyOfPaths.filter(Boolean):[],j=Array.isArray(r.allOfPaths)?r.allOfPaths.filter(Boolean):[],k=v.length===0;for(let w of v)if(await u.pathExists(d.join(e,w))){k=true;break}let g=true;for(let w of j)if(!await u.pathExists(d.join(e,w))){g=false;break}let h=k&&g;O(t,{id:l,label:p,status:h?"pass":y==="error"?"fail":"warn",severity:y,scope:"project-scoped",reason:h?r.passReason||"Custom adapter contract satisfied.":r.failReason||`Custom adapter check failed from ${d.basename(n)}.`,recommendation:r.recommendation});}}catch{O(t,{id:"custom-adapter-config",label:"Custom doctor adapter configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${d.basename(n)}.`,recommendation:"Fix JSON syntax in doctor.adapters.json to re-enable adapter checks."});}}async function U(e,t){if(!(t.projectKind==="backend"||t.projectKind==="generic"))return;let n=d.join(e,".env"),o=d.join(e,".env.example"),s=await u.pathExists(n)||await u.pathExists(o)||await u.pathExists(d.join(e,"config"));O(t,{id:"config-surface",label:"Configuration contract surface",status:s?"pass":"warn",severity:"warn",scope:"project-scoped",reason:s?"Configuration artifacts detected (.env/.env.example/config).":"No explicit configuration contract artifacts detected.",recommendation:s?void 0:"Add .env.example or explicit config contract documentation for deterministic setup."});let a={python:["alembic.ini","migrations","versions"],node:["prisma/schema.prisma","migrations","typeorm.config.ts","typeorm.config.js"],bun:["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"],scala:["src/main/resources/db/migration","conf/evolutions"],kotlin:["src/main/resources/db/migration","src/main/resources/liquibase"],c:["migrations","db/migrations"],cpp:["migrations","db/migrations"],unknown:["migrations"]},r=t.runtimeFamily||"unknown",c=a[r]||a.unknown,l=false;for(let v of c)if(await u.pathExists(d.join(e,v))){l=true;break}O(t,{id:"migration-surface",label:"Migration/readiness surface",status:l?"pass":"warn",severity:"warn",scope:"project-scoped",reason:l?"Migration or schema evolution markers detected.":"No migration markers detected for this backend runtime.",recommendation:l?void 0:"Add migration tooling baseline (migrations dir or runtime-native migration config)."});let p=["src/health","src/healthcheck","src/main/resources/application.yml","src/main/resources/application.properties","app/health.py","routes/health.ts","routes/health.js"],y=false;for(let v of p)if(await u.pathExists(d.join(e,v))){y=true;break}O(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 rr(e,t);}async function ar(e,t,i,n){let o=await Rn({projectPath:e,detection:n,packageJsonData:i});for(let s of o)O(t,s);}async function Z(e,t,i){let n=await Sn({projectPath:e,runtimeFamily:t.runtimeFamily,projectKind:t.projectKind,packageJsonData:i,hasTests:t.hasTests,vulnerabilities:t.vulnerabilities,dependencyAudit:t.dependencyAudit});for(let o of n)O(t,o);}async function Y(e,t){let i=[d.join(e,".workspai","doctor.probes.json"),d.join(e,".rapidkit","doctor.probes.json"),d.join(e,"doctor.probes.json")];for(let n of i)if(await u.pathExists(n))try{let o=await u.readJSON(n),s=Array.isArray(o?.probes)?o.probes:[];for(let a=0;a<s.length;a+=1){let r=s[a]||{},c=typeof r.id=="string"&&r.id.trim().length>0?r.id.trim():`custom-probe-${a+1}`,l=typeof r.label=="string"&&r.label.trim().length>0?r.label.trim():c,p=r.severity||"warn",y=Array.isArray(r.anyOfPaths)?r.anyOfPaths.filter(Boolean):[],v=Array.isArray(r.allOfPaths)?r.allOfPaths.filter(Boolean):[],j=y.length===0;for(let h of y)if(await u.pathExists(d.join(e,h))){j=true;break}let k=true;for(let h of v)if(!await u.pathExists(d.join(e,h))){k=false;break}let g=j&&k;O(t,{id:c,label:l,status:g?"pass":p==="error"?"fail":"warn",severity:p,scope:"project-scoped",reason:g?"Custom probe contract satisfied.":`Custom probe failed from ${d.basename(n)}.`,recommendation:r.recommendation});}}catch{O(t,{id:"custom-probe-config",label:"Custom doctor probe configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${d.basename(n)}.`,recommendation:"Fix JSON syntax in doctor.probes.json to re-enable custom probes."});}await sr(e,t);}async function cr(e,t$1={}){let n={name:d.basename(e),path:e,venvActive:false,depsInstalled:false,coreInstalled:false,issues:[],fixCommands:[]},o=t$1.allowNonRapidkit===true;if(!(await u.pathExists(d.join(e,".workspai"))||await u.pathExists(d.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 C=d.join(e,"registry.json");if(await u.pathExists(C)){let S=await u.readJson(C);S.installed_modules&&(n.stats={modules:S.installed_modules.length});}}catch{}try{let{auditProjectModulePaths:C}=await import('./module-layout-NZ43RSC5.js'),S=await C(e);if(S.issues.length>0){for(let I of S.issues)n.issues.push(`${I.message} (${I.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 a=null;try{for(let C of t(e,"project.json")){if(!await u.pathExists(C))continue;a=await u.readJson(C);let S=a?.kit_name||a?.kit;S&&(n.kit=S);break}}catch{}try{let C=d.join(e,".git");if(await u.pathExists(C)){let{stdout:S}=await execa("git",["log","-1","--format=%cr"],{cwd:e,reject:false,env:a$7()});S&&(n.lastModified=S.trim());}else {let S=await u.stat(e),T=Date.now()-S.mtime.getTime(),_=Math.floor(T/(1e3*60*60*24));n.lastModified=_===0?"today":`${_} day${_>1?"s":""} ago`;}}catch{}let r=d.join(e,"package.json"),c=d.join(e,"pyproject.toml"),l=d.join(e,"requirements.txt"),p=d.join(e,"go.mod"),y=d.join(e,"pom.xml"),v=d.join(e,"build.sbt"),j=d.join(e,"Cargo.toml"),k=d.join(e,"mix.exs"),g=d.join(e,"deps.edn"),h=d.join(e,"project.clj"),w=d.join(e,"deno.json"),b=d.join(e,"deno.jsonc"),D=d.join(e,"bun.lockb"),F=d.join(e,"bun.lock"),f=d.join(e,"composer.json"),R=d.join(e,"Gemfile"),x=await u.pathExists(r),B=await u.pathExists(c)||await u.pathExists(l),P=await u.pathExists(f),L=await u.pathExists(R),M=await u.pathExists(j),ne=await u.pathExists(k),Ye=await u.pathExists(g)||await u.pathExists(h),Qe=await u.pathExists(v),Xe=await u.pathExists(w)||await u.pathExists(b),V=a?.runtime==="dotnet";try{V=V||await qn(e,".csproj",3)||await qn(e,".sln",2);}catch{V=a?.runtime==="dotnet";}let Me=await u.pathExists(p)||a?.runtime==="go"||typeof a?.kit_name=="string"&&(a.kit_name.startsWith("gofiber")||a.kit_name.startsWith("gogin")),ge=x&&(await u.pathExists(D)||await u.pathExists(F)||typeof a?.packageManager=="string"&&(a?.packageManager).toLowerCase().startsWith("bun@"));if(Me){ee(n,j$3(e,a??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/");}let C=d.join(e,"go.sum");return await u.pathExists(C)?n.depsInstalled=true:(n.depsInstalled=false,n.issues.push("Go dependencies not downloaded (go.sum missing)"),n.fixCommands?.push(q(e,"go mod tidy"))),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(await u.pathExists(y)||a?.runtime==="java"||typeof a?.kit_name=="string"&&a.kit_name.startsWith("springboot")){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=await u.pathExists(y),S=await u.pathExists(d.join(e,"build.gradle"))||await u.pathExists(d.join(e,"build.gradle.kts")),I=await u.pathExists(d.join(e,"mvnw"))||await u.pathExists(d.join(e,"mvnw.cmd")),T=await u.pathExists(d.join(e,"gradlew"))||await u.pathExists(d.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");}if(C){if(!I)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");}}else if(S&&!T)try{await execa("gradle",["--version"],{timeout:3e3,reject:false});}catch{n.issues.push("Gradle not found \u2014 install Gradle 8+ or add Gradle Wrapper");}let _=d.join(e,"target"),ie=d.join(e,"build","libs"),ue=d.join(e,".workspai","cache","java","m2"),E=d.join(e,".workspai","cache","java","gradle");if(n.depsInstalled=await u.pathExists(_)||await u.pathExists(ie)||await u.pathExists(ue)||await u.pathExists(E),!n.depsInstalled){n.issues.push("Java dependencies are not warmed or built yet");let we=C?I?b$6()?".\\mvnw.cmd -B -DskipTests dependency:go-offline":"./mvnw -B -DskipTests dependency:go-offline":"mvn -B -DskipTests dependency:go-offline":T?b$6()?".\\gradlew.bat dependencies":"./gradlew dependencies":"gradle dependencies";n.fixCommands?.push(q(e,we));}let H=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(H),!n.hasEnvFile){let we=d.join(e,".env.example");await u.pathExists(we)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}let oe=d.join(e,"src","main","resources","application.yml");if(await u.pathExists(oe))try{let we=await u.readFile(oe,"utf-8");/include:\s*[^\n]*health/i.test(we)||/management:\s*[\s\S]*endpoint:\s*[\s\S]*health:/i.test(we)||(n.issues.push("Actuator health endpoint exposure is not clearly configured in application.yml"),n.fixCommands?.push(q(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 z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(M){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"Cargo.lock"),S=d.join(e,"target");n.depsInstalled=await u.pathExists(C)||await u.pathExists(S),n.depsInstalled||(n.issues.push("Rust dependencies are not resolved yet (Cargo.lock/target missing)"),n.fixCommands?.push(q(e,"cargo fetch")));let I=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(I),!n.hasEnvFile){let T=d.join(e,".env.example");await u.pathExists(T)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(ne){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"mix.lock"),S=d.join(e,"deps");n.depsInstalled=await u.pathExists(C)||await u.pathExists(S),n.depsInstalled||(n.issues.push("Elixir dependencies not installed (mix.lock/deps missing)"),n.fixCommands?.push(q(e,"mix deps.get")));let I=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(I),!n.hasEnvFile){let T=d.join(e,".env.example");await u.pathExists(T)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(Ye){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,".cpcache"),S=d.join(e,"target"),I=await u.pathExists(g)||await u.pathExists(h);return n.depsInstalled=await u.pathExists(C)||await u.pathExists(S)||I,n.depsInstalled||(n.issues.push("Clojure dependency cache not initialized"),n.fixCommands?.push(q(e,await u.pathExists(g)?"clojure -P":"lein deps"))),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(Qe){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"target");n.depsInstalled=await u.pathExists(C),n.depsInstalled||(n.issues.push("Scala build artifacts missing (run dependency/build warmup)"),n.fixCommands?.push(q(e,"sbt compile")));let S=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(S),!n.hasEnvFile){let I=d.join(e,".env.example");await u.pathExists(I)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(Xe){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false,n.depsInstalled=true;let C=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(C),!n.hasEnvFile){let S=d.join(e,".env.example");await u.pathExists(S)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(x){let C=null;try{C=await u.readJson(r);}catch{C=null;}let S={...C?.dependencies??{},...C?.devDependencies??{}},I=C?.scripts??{},T=typeof a?.kit_name=="string"?a.kit_name.toLowerCase():typeof a?.kit=="string"?a.kit.toLowerCase():"",_=d$5(e,a),ie=qo({dependencies:S,scripts:I,kitName:T});if(ge)lt(n,"Bun","high");else {let E=j$3(e,a??null);E.key==="nestjs"||E.key==="express"||E.key==="fastify"||E.key==="koa"||E.key==="tauri"||E.key==="electron"||E.key==="vscode-extension"?ee(n,E):_.key!=="unknown"?Ho(n,_):E.key!=="unknown"&&E.key!=="node"?ee(n,E):lt(n,ie.framework,ie.confidence);}n.venvActive=true;let ue=d.join(e,"node_modules");if(await u.pathExists(ue))try{let H=(await u.readdir(ue)).filter(oe=>!oe.startsWith(".")&&!oe.startsWith("_"));n.depsInstalled=H.length>0;}catch{n.depsInstalled=false;}if(!n.depsInstalled){n.issues.push("Dependencies not installed (node_modules empty or missing)");let E=typeof C?.packageManager=="string"?C.packageManager.split("@")[0]:void 0,H=ge?"bun install":E==="pnpm"||await u.pathExists(d.join(e,"pnpm-lock.yaml"))?"pnpm install":E==="yarn"||await u.pathExists(d.join(e,"yarn.lock"))?"yarn install":"npm install";n.fixCommands?.push(q(e,H));}if(n.coreInstalled=false,n.projectKind==="frontend"){let E=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local"];if((await Promise.all(E.map(oe=>u.pathExists(d.join(e,oe))))).some(Boolean))n.hasEnvFile=true;else {let oe=d.join(e,".env.example");await u.pathExists(oe)&&(n.hasEnvFile=false,n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}}else {let E=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(E),!n.hasEnvFile){let H=d.join(e,".env.example");await u.pathExists(H)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}}if(n.projectKind==="frontend")n.modulesHealthy=await Rt(e),n.missingModules=[];else {let E=d.join(e,"src");if(n.modulesHealthy=true,n.missingModules=[],await u.pathExists(E))try{let H=await u.readdir(E);n.modulesHealthy=H.length>0;}catch{n.modulesHealthy=false;}}return await z(e,n,C),await Z(e,n,C),n.projectKind==="frontend"?await ar(e,n,C,_.key!=="unknown"?_:d$5(e,a)):await U(e,n),await Y(e,n),n}if(B){let C=await Lo(e,a);lt(n,C.framework,C.confidence);let S="fastapi";n.framework==="Django"?S="django":n.framework==="Flask"?S="flask":n.framework==="Python"&&(S="");let I=await ht(c),T=await or(e,S,/\[tool\.poetry\]/.test(I));n.venvActive=!!T.environmentPath,n.depsInstalled=T.dependenciesInstalled,n.coreInstalled=!!T.coreVersion,n.coreVersion=T.coreVersion,T.environmentPath?T.interpreter?n.depsInstalled||(n.issues.push("Dependencies not installed"),n.fixCommands?.push(Wn(e))):n.issues.push("Virtual environment exists but Python executable not found"):(n.issues.push("Virtual environment not created"),n.fixCommands?.push(Wn(e)));let _=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(_),!n.hasEnvFile){let E=d.join(e,".env.example");await u.pathExists(E)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}let ie=d.join(e,"src"),ue=d.join(e,"modules");if(n.modulesHealthy=true,n.missingModules=[],await u.pathExists(ie)){let E=d.join(ie,"__init__.py");await u.pathExists(E)||(n.modulesHealthy=false,n.missingModules.push("src/__init__.py"));}if(await u.pathExists(ue))try{let E=await lr(ue);for(let H of E){let oe=d.join(ue,H,"__init__.py");await u.pathExists(oe)||(n.modulesHealthy=false,n.missingModules.push(`modules/${H}/__init__.py`));}}catch{}return !n.modulesHealthy&&n.missingModules.length>0&&n.issues.push(`Missing module init files: ${n.missingModules.join(", ")}`),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(P){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"vendor");n.depsInstalled=await u.pathExists(C),n.depsInstalled||(n.issues.push("PHP dependencies not installed (vendor missing)"),n.fixCommands?.push(q(e,"composer install")));let S=d.join(e,".env");if(n.hasEnvFile=await u.pathExists(S),!n.hasEnvFile){let I=d.join(e,".env.example");await u.pathExists(I)&&(n.issues.push("Environment file missing (found .env.example)"),n.fixCommands?.push(de(e)));}return await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(L){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=await u.pathExists(d.join(e,"Gemfile.lock")),S=await u.pathExists(d.join(e,"vendor","bundle"));n.depsInstalled=C||S,n.depsInstalled||(n.issues.push("Ruby dependencies not installed (Gemfile.lock/vendor missing)"),n.fixCommands?.push(q(e,"bundle install")));let I=d.join(e,".env");return n.hasEnvFile=await u.pathExists(I),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}if(V){ee(n,j$3(e,a??null)),n.venvActive=true,n.coreInstalled=false;let C=d.join(e,"obj"),S=d.join(e,"src","obj"),I=d.join(e,"packages.lock.json");n.depsInstalled=await u.pathExists(C)||await u.pathExists(S)||await u.pathExists(I),n.depsInstalled||(n.issues.push(".NET restore/build artifacts not found"),n.fixCommands?.push(q(e,"dotnet restore")));let T=d.join(e,".env");return n.hasEnvFile=await u.pathExists(T),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}return lt(n,"Unknown","low"),n.issues.push("Unknown project type (no recognized runtime marker files)"),await z(e,n),await Z(e,n),await U(e,n),await Y(e,n),n}function ui(e){if(!e.fixCommands)return e;let t=new Set;return e.fixCommands=e.fixCommands.filter(i=>{let n=i.trim();return /^https?:\/\/\S+$/i.test(n)||!n||t.has(n)?false:(t.add(n),true)}),e}async function ft(e,t={}){let i=ui(await cr(e,t));kr(i);let n=await b$3(e);return n==="backend"||n==="service"||n==="worker"?i.projectKind="backend":n==="frontend"||n==="desktop"||n==="extension"?i.projectKind=n:i.projectKind||(i.projectKind="generic"),i}async function lr(e){try{return (await u.readdir(e,{withFileTypes:true})).filter(i=>i.isDirectory()).map(i=>i.name)}catch{try{let t=await u.readdir(e),i=[];for(let n of t)try{(await u.stat(d.join(e,n))).isDirectory()&&i.push(n);}catch{continue}return i}catch{return []}}}async function qn(e,t,i){let n=[{dir:e,depth:0}],o=new Set([".git",".workspai",".rapidkit","node_modules","bin","obj","target"]);for(;n.length>0;){let s=n.shift();if(!s||s.depth>i)continue;let a;try{a=await u.readdir(s.dir,{withFileTypes:true});}catch{continue}for(let r of a){if(r.isFile()&&r.name.toLowerCase().endsWith(t.toLowerCase()))return true;r.isDirectory()&&!o.has(r.name)&&!a$8(r.name)&&n.push({dir:d.join(s.dir,r.name),depth:s.depth+1});}}return false}async function ze(e){let t=["project.json","context.json","file-hashes.json"];for(let i of [".workspai",".rapidkit"])for(let n of t)if(await u.pathExists(d.join(e,i,n)))return true;return false}function dr(e,t){if(t.has(e)||a$8(e))return true;let i=e.toLowerCase();return !!(i==="dist"||i.startsWith("dist-")||i.startsWith("dist_")||i==="build"||i.startsWith("build-")||i.startsWith("build_"))}async function ur(e,t,i){let n=new Set,o=[{dir:e,depth:0}];for(;o.length>0;){let s=o.shift();if(!s)break;try{let a=await u.readdir(s.dir);for(let r of a){if(dr(r,i))continue;let c=d.join(s.dir,r),l;try{l=await u.stat(c);}catch{continue}if(l.isDirectory()){if(await ze(c)){n.add(c);continue}s.depth<t&&o.push({dir:c,depth:s.depth+1});}}}catch{continue}}return Array.from(n)}async function Ue(e){let t=d.resolve(e),i=d.parse(t).root;for(;;){if(await fr(t))return t;if(t===i)break;t=d.dirname(t);}return null}async function pr(e){let t=d.resolve(e),i=await Ue(t),n=i??d.parse(t).root;for(;;){if(await ze(t)||await mr(t)&&(!i||t!==i))return t;if(t===n)break;t=d.dirname(t);}return null}function Ln(e){let t=d.resolve(e);return process.platform==="darwin"?t.replace(/^\/private(?=\/var\/)/,""):t}async function mr(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 i of t)if(await u.pathExists(d.join(e,i)))return true;return false}async function fr(e){if(j$1(e))return true;let t=[d.join(e,".rapidkit","workspace-marker.json"),d.join(e,".rapidkit","config.json")];return Promise.all(t.map(i=>u.pathExists(i))).then(i=>i.some(Boolean))}function qt(e,t){let i={total:0,passed:0,warnings:0,errors:0},n={total:0,passed:0,warnings:0,errors:0};e.forEach(r=>{i.total+=1,r.status==="ok"?i.passed+=1:r.status==="warn"?i.warnings+=1:r.status==="error"&&(i.errors+=1);}),t.forEach(r=>{let c=r.probes??[];if(c.length>0){for(let y of c)n.total+=1,y.status==="pass"?n.passed+=1:y.status==="warn"?n.warnings+=1:n.errors+=1;r.issues.length>0&&(n.total+=r.issues.length,n.errors+=r.issues.length);return}n.total+=1;let l=Ro(r),p=r.isGoProject?r.issues.length===0&&r.depsInstalled:r.issues.length===0&&r.venvActive&&r.depsInstalled;r.issues.length>0||!p?n.errors+=1:l>0?n.warnings+=1:n.passed+=1;});let o=i.passed+n.passed,s=i.warnings+n.warnings,a=i.errors+n.errors;return {total:i.total+n.total,passed:o,warnings:s,errors:a,verdict:a>0?"blocked":s>0?"attention":"passed",components:{host:i,projects:n}}}function te(e){let t=e.probes??[],i=t.filter(r=>r.status==="pass").length,n=t.filter(r=>r.status==="warn").length,o=t.filter(r=>r.status==="fail").length,s=o+e.issues.length,a=n;return {total:t.length,passed:i,warnings:n,failed:o,blockingFindings:s,advisoryFindings:a,verdict:s>0?"blocked":a>0?"attention":"passed"}}function gr(e){let t=te(e);e.probeSummary=t,e.verdict=t.verdict;}function pi(e,t,i={}){let n=[];for(let s of e)n.push({id:s.id,label:s.label,status:s.result.status,scope:"host-system",policyRuleId:"system-status-derived",reason:s.result.details||s.result.message});let o=[...t].sort((s,a)=>{let r=`${s.path||""}|${s.name||""}`.toLowerCase(),c=`${a.path||""}|${a.name||""}`.toLowerCase();return r.localeCompare(c)});for(let s of o){gr(s);for(let a of s.probes??[])n.push({id:`project:${s.name}:probe:${a.id}`,label:`${s.name} \xB7 ${a.label}`,status:a.status==="pass"?"ok":a.status==="warn"?"warn":"error",scope:"project-scoped",policyRuleId:`project-probe-${a.id}`,reason:a.reason});for(let[a,r]of s.issues.entries())n.push({id:`project:${s.name}:legacy:${a+1}`,label:`${s.name} \xB7 Runtime issue`,status:"error",scope:"project-scoped",policyRuleId:"project-runtime-issue",reason:r});(s.probes?.length??0)===0&&s.issues.length===0&&n.push({id:`project:${s.name}`,label:`Project ${s.name}`,status:"ok",scope:"project-scoped",policyRuleId:"project-checks-passed",reason:"Project checks passed"});}if(i.includeWorkspaceAggregateRules){let s=t.reduce((c,l)=>c+te(l).blockingFindings,0),a=t.reduce((c,l)=>c+te(l).advisoryFindings,0),r=e.filter(c=>c.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:r>0?"error":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-system-error-gate",reason:r>0?`${r} system requirement gate(s) failed.`:"All system requirement gates passed."}),n.push({id:"workspace:blocking-issues-gate",label:"Workspace blocking issues gate",status:s>0?"error":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-blocking-issues-gate",reason:s>0?`${s} blocking project issue(s) detected.`:"No blocking project issues detected."}),n.push({id:"workspace:advisory-warnings-gate",label:"Workspace advisory warnings gate",status:a>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-advisory-warning-gate",reason:a>0?`${a} advisory warning(s) detected.`:"No advisory warnings detected."});}return n}async function Mt(e,t=true,i=mt({})){let n=d.basename(e),o=await a$1(e);if(typeof o?.name=="string"&&o.name.trim().length>0)n=o.name;else try{for(let g of s(e,"workspace.json")){if(!await u.pathExists(g))continue;let h=await u.readJSON(g);n=h.workspace_name||h.name||n;break}}catch{}let[s$1,a]=await Promise.all([Ht(e),Vo(e)]),r={workspacePath:e,workspaceName:n,python:s$1.python,poetry:s$1.poetry,pipx:s$1.pipx,go:s$1.go,rapidkitCore:s$1.rapidkitCore,projects:[],policyProfile:i};f.debug(`Workspace scan found ${a.length} project(s)`);let c=await Jo(e,a),l=d.join(e,".workspai","reports","doctor-workspace-cache.json"),p=t?await zo(l,c):null;if(p){r.projects=p.projects;for(let g of r.projects)ui(g),Kn(g,p.generatedAt),Gt(g,g.path);r.projectScanCached=true,f.debug(`Workspace project health cache hit: ${l}`);}else try{let g=new Date().toISOString(),h=await Promise.all(a.map(w=>ft(w,{allowNonRapidkit:true})));for(let w of h)Kn(w,g),Gt(w,w.path);r.projects=h,r.projectScanCached=false,await Uo(l,{schemaVersion:ni,signature:c,generatedAt:g,projects:h}),f.debug(`Workspace project health cache refreshed: ${l}`);}catch(g){f.debug(`Failed to scan workspace projects: ${g}`);}r.projectScanSignature=c,r.projectScanCachePath=l;let y=ti({python:r.python,poetry:r.poetry,pipx:r.pipx,go:r.go,rapidkitCore:r.rapidkitCore},r.projects);r.python=y.python,r.poetry=y.poetry,r.pipx=y.pipx,r.go=y.go,r.rapidkitCore=y.rapidkitCore,await Promise.all(r.projects.map(async g=>{g.graphDiagnosis=await Nt({workspacePath:e,projectPath:g.path,projectName:g.name,probes:ii(g),issues:g.issues});}));let v=[r.python,r.poetry,r.pipx,r.go,r.rapidkitCore];if(r.healthScore=qt(v,r.projects),r.scoreBreakdown=pi([{id:"system-python",label:"Python",result:r.python},{id:"system-poetry",label:"Poetry",result:r.poetry},{id:"system-pipx",label:"pipx",result:r.pipx},{id:"system-go",label:"Go",result:r.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:r.rapidkitCore}],r.projects,{includeWorkspaceAggregateRules:true}),r.scopeProvenance=li(r.scoreBreakdown),r.evidenceFreshness=ri(r.projects,new Date().toISOString()),r.rapidkitCore.status==="ok"){let g=r.rapidkitCore.message.match(/([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);g&&(r.coreVersion=g[1]);}let j=await d$1(e,_t),k=j?await ai(j,"workspace"):null;return r.driftDelta=Oo(k,r),r.evidencePath=await Zo(e,r,p?l:null),r}function Vn(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,dependencyAudit:e.dependencyAudit,coreInstalled:e.coreInstalled,coreVersion:e.coreVersion,lastModified:e.lastModified,stats:e.stats,issues:e.issues,fixCommands:e.fixCommands,probes:e.probes,verdict:e.verdict??te(e).verdict,probeSummary:e.probeSummary??te(e),repairCapabilities:e.repairCapabilities,commandCapabilities:e.commandCapabilities,graphDiagnosis:e.graphDiagnosis}}function mi(e,t){let i=e?d.relative(e,t).split(d.sep).join("/"):d.resolve(t),n=d.basename(t).toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"project",o=createHash("sha256").update(i).digest("hex").slice(0,12);return `.workspai/reports/projects/${n}--${o}/doctor-project-last-run.json`}async function yr(e$3,t){let i=e$3||t.projectPath,n=e.doctorProject,o=mi(e$3,t.projectPath),s=d.join(i,n);try{let a=[...t.project.issues,...(t.project.probes??[]).filter(l=>l.status==="fail").map(l=>l.reason)].filter(l=>typeof l=="string"&&l.trim().length>0).slice(0,12),r=te(t.project),c=f$1({schemaVersion:b$5,evidenceType:"project",contract:$e(),policyProfile:t.policyProfile,workspacePath:e$3||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,verdict:r.verdict,probeSummary:r,blockingFindings:r.blockingFindings,advisoryFindings:r.advisoryFindings},scoreBreakdown:t.scoreBreakdown??[]},{commandId:"projectDoctor",exitCode:Ze(t.healthScore,{profile:t.policyProfile?.name}),generatedAt:new Date().toISOString(),blockers:a,runId:e$2()});return d$4(c),e$3?await f$2(e$3,n,[{relativePath:n,payload:c},{relativePath:o,payload:c}]):await e$1(i,n,c),e$3&&d.resolve(e$3)!==d.resolve(t.projectPath)&&await e$1(t.projectPath,n,c),s}catch(a){if(a instanceof Error&&a.message.includes("violates contracts/"))throw a;return}}async function Kt(e$2,t,i=[]){let n=d.join(e$2,e.doctorRemediationPlan);try{await e$1(e$2,e.doctorRemediationPlan,t);for(let o of i)d.resolve(o)!==d.resolve(e$2)&&await e$1(o,e.doctorRemediationPlan,t);return n}catch(o){if(o instanceof Error&&o.message.includes("violates contracts/"))throw o;return}}async function Fe(e$2,t,i=[]){let n=d.join(e$2,e.doctorFixResult);try{await e$1(e$2,e.doctorFixResult,t);for(let o of i)d.resolve(o)!==d.resolve(e$2)&&await e$1(o,e.doctorFixResult,t);return n}catch{return}}async function Ne(e,t,i){try{await j(e,g(t,i));}catch{}}async function Jn(e$1,t=mt({})){let i=await Ue(e$1),n=await Ht(i||e$1),o=await ft(e$1,{allowNonRapidkit:true}),s=ti(n,[o]);Gt(o,e$1),o.graphDiagnosis=await Nt({workspacePath:i||void 0,projectPath:e$1,projectName:o.name,probes:ii(o),issues:o.issues});let a=qt([s.python,s.poetry,s.pipx,s.go,s.rapidkitCore],[o]),r={workspacePath:i||void 0,projectPath:e$1,projectName:d.basename(e$1),python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore,project:o,healthScore:a,policyProfile:t};r.scoreBreakdown=pi([{id:"system-python",label:"Python",result:r.python},{id:"system-poetry",label:"Poetry",result:r.poetry},{id:"system-pipx",label:"pipx",result:r.pipx},{id:"system-go",label:"Go",result:r.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:r.rapidkitCore}],[r.project]),r.scopeProvenance=li(r.scoreBreakdown),r.evidenceFreshness=ri([r.project],new Date().toISOString());let c=await d$1(e$1,e.doctorProject),l=i?await d$1(i,mi(i,e$1)):null,p=c??l,y=p?await ai(p,"project"):null;return r.driftDelta=_o(y,r),r.evidencePath=await yr(i||void 0,r),r}function W(e,t){let i=e.status==="ok"?"\u2705":e.status==="warn"?"\u26A0\uFE0F":"\u274C",n=e.status==="ok"?m.green:e.status==="warn"?m.yellow:m.red;console.log(`${i} ${m.bold(t)}: ${n(e.message)}`),e.paths&&e.paths.length>0&&e.paths.forEach(o=>{let s=o.version?m.cyan(` -> ${o.version}`):"";console.log(` ${m.cyan("\u2022")} ${m.gray(o.location)}: ${m.dim(o.path)}${s}`);}),e.details&&console.log(` ${m.gray(e.details)}`);}function dt(e,t){let i=pt(e,t);if(/^(?:workspai|rapidkit):doctor:repair\s/.test(t))return i?.title??"Apply Doctor-managed project repair";if(/^https?:\/\//i.test(t.trim()))return `Open: ${t.trim()}`;let n=t.match(/\s+(?:&&|;)\s+/);return `Run in project: ${n?t.slice((n.index??0)+n[0].length):t}`}function zn(e,t){let i=e.issues.length>0,n=i?"\u26A0\uFE0F":"\u2705",o=i?m.yellow:m.green;if(console.log(`
|
|
17
17
|
${n} ${m.bold("Project")}: ${o(e.name)}`),e.framework){let r=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(` ${r} Framework: ${m.cyan(e.framework)}${e.kit?m.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(` ${m.dim("\u21B3")} ${m.gray(c.join(" \u2022 "))}`);}if(console.log(` ${m.gray(`Path: ${e.path}`)}`),e.runtimeFamily==="python"&&(e.venvActive?console.log(` \u2705 Virtual environment: ${m.green("Active")}`):console.log(` \u274C Virtual environment: ${m.red("Not found")}`),e.coreInstalled?console.log(` ${m.dim("\u2139")} RapidKit Core: ${m.gray(e.coreVersion||"In venv")} ${m.dim("(optional)")}`):t?.status==="ok"?console.log(` ${m.dim("\u2139")} RapidKit Core: ${m.gray("Using global installation")} ${m.dim("(recommended)")}`):console.log(` \u274C RapidKit Core: ${m.red("Not detected locally or globally")}`)),e.depsInstalled?console.log(` \u2705 Dependencies: ${m.green("Installed")}`):console.log(` \u26A0\uFE0F Dependencies: ${m.yellow("Not installed")}`),e.hasEnvFile!==void 0&&(e.hasEnvFile?console.log(` \u2705 Environment: ${m.green(".env configured")}`):console.log(` \u26A0\uFE0F Environment: ${m.yellow(".env missing")}`)),e.modulesHealthy!==void 0){let r=e.projectKind==="frontend"?"Source tree":e.projectKind==="desktop"?"Application source":e.projectKind==="extension"?"Extension source":"Modules";e.modulesHealthy?console.log(` \u2705 ${r}: ${m.green("Healthy")}`):e.missingModules&&e.missingModules.length>0?console.log(` \u26A0\uFE0F ${r}: ${m.yellow(`Missing ${e.missingModules.length} init file(s)`)}`):(e.projectKind==="frontend"||e.projectKind==="desktop"||e.projectKind==="extension")&&console.log(` \u26A0\uFE0F ${r}: ${m.yellow("No application directories detected")}`);}if(e.stats){let r=[];e.stats.modules!==void 0&&r.push(`${e.stats.modules} module${e.stats.modules!==1?"s":""}`),r.length>0&&console.log(` \u{1F4CA} Stats: ${m.cyan(r.join(" \u2022 "))}`);}e.lastModified&&console.log(` \u{1F552} Last Modified: ${m.gray(e.lastModified)}`);let a=[];if(e.hasTests!==void 0&&a.push(e.hasTests?"\u2705 Tests":m.dim("\u2298 No tests")),e.hasDocker!==void 0&&a.push(e.hasDocker?"\u2705 Docker":m.dim("\u2298 No Docker")),e.hasCodeQuality!==void 0){let r=e.runtimeFamily==="node"||e.runtimeFamily==="bun"?"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 ${r}`:m.dim(`\u2298 No ${r}`));}if(a.length>0&&console.log(` ${a.join(" \u2022 ")}`),e.vulnerabilities!==void 0&&e.vulnerabilities>0&&console.log(` \u26A0\uFE0F Security: ${m.yellow(`${e.vulnerabilities} vulnerability(ies) found`)}`),e.issues.length>0&&(console.log(` ${m.bold("Issues:")}`),e.issues.forEach(r=>{console.log(` \u2022 ${m.yellow(r)}`);}),e.fixCommands&&e.fixCommands.length>0&&(console.log(`
|
|
18
|
-
${m.bold.cyan("\u{1F527} Quick Fix:")}`),e.fixCommands.forEach(r=>{console.log(` ${m.white(dt(e,r))}`);}))),e.probes&&e.probes.length>0){console.log(` ${m.bold("Probe checks:")}`);for(let r of e.probes){let c=r.status==="pass"?"\u2705":r.status==="warn"?"\u26A0\uFE0F":"\u274C";console.log(` ${c} ${r.label}: ${m.gray(r.reason)}`),r.recommendation&&console.log(` ${m.dim("\u21B3")} ${m.gray(r.recommendation)}`);}}if(e.graphDiagnosis?.status==="available"){let r=e.graphDiagnosis.summary;console.log(` ${m.bold("Graph-aware diagnosis:")}`),console.log(` ${r.findingCount} finding(s) \u2022 ${r.affectedEntityCount} affected candidate(s) \u2022 ${r.verificationTargetCount} verification target(s) \u2022 ${r.proofPathCount} proof path(s)`),r.unknownCount>0&&console.log(` ${m.dim("\u21B3")} ${m.gray(`${r.unknownCount} explicit unknown(s); inspect JSON evidence before expanding impact claims.`)}`);}else e.graphDiagnosis&&["stale","invalid","project-unresolved"].includes(e.graphDiagnosis.status)&&console.log(` \u26A0\uFE0F Graph-aware diagnosis: ${m.yellow(e.graphDiagnosis.status)} ${m.dim("(refresh workspace model evidence)")}`);if(e.commandCapabilities){let r=e.commandCapabilities;if(console.log(` ${m.bold("Command support:")}`),console.log(` ${m.green("supported")} ${r.supportedCommands.length} \u2022 ${m.yellow("unsupported")} ${r.unsupportedCommands.length} \u2022 ${m.gray("global")} ${r.globalCommands.length}`),r.unsupportedCommands.length>0){let c=r.unsupportedCommands.slice(0,8).join(", "),l=r.unsupportedCommands.length>8?", ...":"";console.log(` ${m.dim("\u21B3")} ${m.gray(`Unsupported here: ${c}${l}`)}`);}}}async function
|
|
19
|
-
`)}`;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 be(e,t){let i=d.resolve(e),n=d.isAbsolute(t)?d.resolve(t):d.resolve(i,t),o=d.relative(i,n);if(o.startsWith("..")||d.isAbsolute(o))throw new Error(`Repair target escapes project boundary: ${t}`);return n}async function
|
|
18
|
+
${m.bold.cyan("\u{1F527} Quick Fix:")}`),e.fixCommands.forEach(r=>{console.log(` ${m.white(dt(e,r))}`);}))),e.probes&&e.probes.length>0){console.log(` ${m.bold("Probe checks:")}`);for(let r of e.probes){let c=r.status==="pass"?"\u2705":r.status==="warn"?"\u26A0\uFE0F":"\u274C";console.log(` ${c} ${r.label}: ${m.gray(r.reason)}`),r.recommendation&&console.log(` ${m.dim("\u21B3")} ${m.gray(r.recommendation)}`);}}if(e.graphDiagnosis?.status==="available"){let r=e.graphDiagnosis.summary;console.log(` ${m.bold("Graph-aware diagnosis:")}`),console.log(` ${r.findingCount} finding(s) \u2022 ${r.affectedEntityCount} affected candidate(s) \u2022 ${r.verificationTargetCount} verification target(s) \u2022 ${r.proofPathCount} proof path(s)`),r.unknownCount>0&&console.log(` ${m.dim("\u21B3")} ${m.gray(`${r.unknownCount} explicit unknown(s); inspect JSON evidence before expanding impact claims.`)}`);}else e.graphDiagnosis&&["stale","invalid","project-unresolved"].includes(e.graphDiagnosis.status)&&console.log(` \u26A0\uFE0F Graph-aware diagnosis: ${m.yellow(e.graphDiagnosis.status)} ${m.dim("(refresh workspace model evidence)")}`);if(e.commandCapabilities){let r=e.commandCapabilities;if(console.log(` ${m.bold("Command support:")}`),console.log(` ${m.green("supported")} ${r.supportedCommands.length} \u2022 ${m.yellow("unsupported")} ${r.unsupportedCommands.length} \u2022 ${m.gray("global")} ${r.globalCommands.length}`),r.unsupportedCommands.length>0){let c=r.unsupportedCommands.slice(0,8).join(", "),l=r.unsupportedCommands.length>8?", ...":"";console.log(` ${m.dim("\u21B3")} ${m.gray(`Unsupported here: ${c}${l}`)}`);}}}async function fi(){try{return (await execa("go",["version"],{timeout:a$6(),reject:false})).exitCode===0}catch{return false}}function ve(e,t){let i=[new RegExp(`^Set-Location\\s+-LiteralPath\\s+"([^"]+)"\\s*;\\s*${t}\\s*$`,"i"),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 i){let o=e.match(n);if(o?.[1])return {projectPath:o[1].trim()}}return null}function gt(e){return ve(e,"cp\\s+\\.env\\.example\\s+\\.env")||ve(e,"copy-item\\s+\\.env\\.example\\s+\\.env")}function Lt(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:"lein\\s+deps",command:"lein",args:["deps"]},{pattern:"sbt\\s+compile",command:"sbt",args:["compile"]},{pattern:"go\\s+mod\\s+tidy",command:"go",args:["mod","tidy"]},{pattern:"mvn\\s+-B\\s+-DskipTests\\s+dependency:go-offline",command:"mvn",args:["-B","-DskipTests","dependency:go-offline"]},{pattern:"\\.\\/mvnw\\s+-B\\s+-DskipTests\\s+dependency:go-offline",command:"./mvnw",args:["-B","-DskipTests","dependency:go-offline"]},{pattern:"\\.\\\\mvnw\\.cmd\\s+-B\\s+-DskipTests\\s+dependency:go-offline",command:".\\mvnw.cmd",args:["-B","-DskipTests","dependency:go-offline"]},{pattern:"gradle\\s+dependencies",command:"gradle",args:["dependencies"]},{pattern:"\\.\\/gradlew\\s+dependencies",command:"./gradlew",args:["dependencies"]},{pattern:"\\.\\\\gradlew\\.bat\\s+dependencies",command:".\\gradlew.bat",args:["dependencies"]}];for(let i of t){let n=ve(e,i.pattern);if(n)return {projectPath:n.projectPath,command:i.command,args:i.args}}return null}function hr(e){let t=d.posix.basename(e.replaceAll("\\","/")).toLowerCase().replace(/\.(?:cmd|bat)$/i,"");return ["npm","pnpm","yarn","bun"].includes(t)?{ecosystem:t,files:["package.json","package-lock.json","npm-shrinkwrap.json","pnpm-lock.yaml","yarn.lock","bun.lock","bun.lockb"]}:["poetry","uv","pip","pip3","python","python3","py"].includes(t)?{ecosystem:t==="uv"?"uv":t==="poetry"?"poetry":"python",files:["pyproject.toml","poetry.lock","uv.lock","requirements.txt"]}:t==="go"?{ecosystem:"go",files:["go.mod","go.sum"]}:t==="cargo"?{ecosystem:"cargo",files:["Cargo.toml","Cargo.lock"]}:t==="composer"?{ecosystem:"composer",files:["composer.json","composer.lock"]}:t==="bundle"?{ecosystem:"bundler",files:["Gemfile","Gemfile.lock"]}:t==="mix"?{ecosystem:"mix",files:["mix.exs","mix.lock"]}:t==="dotnet"?{ecosystem:"dotnet",files:["Directory.Packages.props","packages.lock.json"]}:t==="clojure"||t==="lein"?{ecosystem:"clojure",files:["deps.edn","project.clj"]}:t==="sbt"?{ecosystem:"sbt",files:["build.sbt"]}:t==="mvn"||t==="mvnw"?{ecosystem:"maven",files:["pom.xml"]}:t==="gradle"||t==="gradlew"?{ecosystem:"gradle",files:["build.gradle","build.gradle.kts","gradle.lockfile"]}:{ecosystem:t,files:[]}}function kr(e){for(let t of e.fixCommands??[]){let i=Lt(t);if(!i)continue;let n=hr(i.command),o=b$7({issueId:"runtime-dependency-materialization",title:`Install ${n.ecosystem} dependencies`,projectPath:i.projectPath,ecosystem:n.ecosystem,executable:i.command,args:i.args,files:n.files,command:t,reason:"The dependency definition exists, but its local runtime dependency tree is missing or incomplete.",limitations:["This transaction may update a lockfile when the package manager determines it is stale.","Source mutation is not required when the existing manifest and lockfile are already consistent."]});e.repairCapabilities=e.repairCapabilities??[],e.repairCapabilities.some(s=>s.id===o.id)||e.repairCapabilities.push(o);}}function vr(){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 yt(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 i of t){let n=e.match(i);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 Ie(e){let t=e.trim().match(/^(?:workspai|rapidkit):doctor:repair\s+([A-Za-z0-9_-]+)$/);if(!t?.[1])return null;try{let i=Buffer.from(t[1],"base64url").toString("utf8"),n=JSON.parse(i);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(s=>typeof s=="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(s=>{if(!s||typeof s!="object"||Array.isArray(s))return false;let a=s;return typeof a.pointer=="string"&&a.pointer.startsWith("/")&&(typeof a.value=="string"||typeof a.value=="number"||typeof a.value=="boolean"||a.value===null)})||o.type==="env-key-add"&&typeof o.path=="string"&&Array.isArray(o.keys)&&o.keys.every(s=>{if(!s||typeof s!="object"||Array.isArray(s))return false;let a=s;return typeof a.name=="string"&&/^[A-Z_][A-Z0-9_]*$/i.test(a.name)&&typeof a.value=="string"&&(a.comment===void 0||typeof a.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 br(e){let t=e.operation?wr(e.operation):e.capabilityId?`capability:${e.capabilityId}`:`command:${e.command}`,i=createHash("sha256").update(t).digest("base64url").slice(0,16);return `${e.projectName}:${e.kind}:${i}`}function wr(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(`
|
|
19
|
+
`)}`;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 be(e,t){let i=d.resolve(e),n=d.isAbsolute(t)?d.resolve(t):d.resolve(i,t),o=d.relative(i,n);if(o.startsWith("..")||d.isAbsolute(o))throw new Error(`Repair target escapes project boundary: ${t}`);return n}async function jr(e){if(!/^[A-Za-z0-9:_-]+$/.test(e.scriptName))throw new Error(`Unsafe package script name: ${e.scriptName}`);let t=d.join(e.projectPath,"package.json");if(!await u.pathExists(t))throw new Error(`package.json not found at ${t}`);let i=await u.readJSON(t),n=i.scripts&&typeof i.scripts=="object"&&!Array.isArray(i.scripts)?i.scripts:{},o=n[e.scriptName];typeof o=="string"&&o.trim().length>0||(i.scripts={...n,[e.scriptName]:e.scriptValue},await u.writeJSON(t,i,{spaces:2}));}async function xr(e){let t=be(e.projectPath,e.operation.path);await u.pathExists(t)||(await u.ensureDir(d.dirname(t)),await u.writeFile(t,e.operation.content,"utf8"));}async function Cr(e){let t=be(e.projectPath,e.operation.path);await u.ensureDir(d.dirname(t));let i=await ht(t),n=i.split(/\r?\n/),o=e.operation.lines.filter(a=>!n.includes(a));if(o.length===0)return;let s=i.length===0||i.endsWith(`
|
|
20
20
|
`)||!e.operation.ensureNewline?"":`
|
|
21
21
|
`;await u.appendFile(t,`${s}${o.join(`
|
|
22
22
|
`)}
|
|
23
|
-
`,"utf8");}async function
|
|
23
|
+
`,"utf8");}async function Pr(e){let t=be(e.projectPath,e.operation.sourcePath),i=be(e.projectPath,e.operation.path);if(!await u.pathExists(t))throw new Error(`Repair source file not found at ${t}`);await u.pathExists(i)||(await u.ensureDir(d.dirname(i)),await u.copy(t,i,{overwrite:e.operation.overwrite,errorOnExist:false}));}function Dr(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")}async function Rr(e){let t=be(e.projectPath,e.operation.path);if(!await u.pathExists(t))throw new Error(`JSON repair target not found at ${t}`);let i=await u.readJSON(t);for(let n of e.operation.edits){let o=n.pointer.split("/").slice(1).map(Dr);if(o.length===0||o.some(a=>a.length===0))throw new Error(`Unsupported JSON pointer: ${n.pointer}`);let s=i;for(let a of o.slice(0,-1)){let r=s[a];(!r||typeof r!="object"||Array.isArray(r))&&(s[a]={}),s=s[a];}s[o[o.length-1]]=n.value;}await u.writeJSON(t,i,{spaces:2});}async function Sr(e){let t=be(e.projectPath,e.operation.path);await u.ensureDir(d.dirname(t));let i=await ht(t),n=new Set(i.split(/\r?\n/).map(a=>a.trim().match(/^([A-Za-z_][A-Za-z0-9_]*)=/)?.[1]).filter(a=>!!a)),o=[];for(let a of e.operation.keys)n.has(a.name)||(a.comment&&o.push(`# ${a.comment}`),o.push(`${a.name}=${a.value}`));if(o.length===0)return;let s=i.length===0||i.endsWith(`
|
|
24
24
|
`)?"":`
|
|
25
25
|
`;await u.appendFile(t,`${s}${o.join(`
|
|
26
26
|
`)}
|
|
27
|
-
`,"utf8");}async function
|
|
27
|
+
`,"utf8");}async function Er(e){let t=be(e.projectPath,e.operation.path);await u.ensureDir(d.dirname(t));let i=await ht(t);if(new RegExp(`(^|\\n)${e.operation.target.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}:`,"m").test(i))return;let o=[...e.operation.phony?[`.PHONY: ${e.operation.target}`]:[],`${e.operation.target}:`,` ${e.operation.command}`],s=i.length===0||i.endsWith(`
|
|
28
28
|
`)?"":`
|
|
29
29
|
`;await u.appendFile(t,`${s}${o.join(`
|
|
30
30
|
`)}
|
|
31
|
-
`,"utf8");}async function ht(e){try{return await u.pathExists(e)?await u.readFile(e,"utf8"):""}catch{return ""}}function
|
|
31
|
+
`,"utf8");}async function ht(e){try{return await u.pathExists(e)?await u.readFile(e,"utf8"):""}catch{return ""}}function Ar(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(gt(t))return {projectName:e.name,projectPath:e.path,originalCommand:t,kind:"env-copy",risk:"safe",executable:true,reason:"Environment seed copy"};if(yt(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 i=Ie(t);return i?.type==="file-create"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"file-create",risk:"safe",executable:true,reason:"Project-scoped file create repair"}:i?.type==="file-append"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"file-append",risk:"safe",executable:true,reason:"Project-scoped file append repair"}:i?.type==="file-copy"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"env-copy",risk:"safe",executable:true,reason:"Project-scoped file copy repair"}:i?.type==="json-edit"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"json-edit",risk:"guarded",executable:true,reason:"Project-scoped JSON document repair"}:i?.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"}:i?.type==="makefile-target"?{projectName:e.name,projectPath:e.path,originalCommand:t,kind:"makefile-target",risk:"guarded",executable:true,reason:"Project-scoped Makefile target repair"}:ve(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"}:ve(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"}:Lt(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 pt(e,t){return e.repairCapabilities?.find(i=>i.command===t)}function Tt(e,t){if(t)return e.probes?.find(i=>i.repairCapability?.id===t.id)}function $r(e){let{step:t,capability:i,operation:n}=e;if(n?.type==="file-create")return {title:i?.title??"Create file",summary:`Create ${d.basename(n.path)} if it does not already exist.`,changes:[`create ${n.path}`,"do not overwrite an existing file"]};if(n?.type==="file-append")return {title:i?.title??"Append file rules",summary:`Append ${n.lines.length} missing line(s) to ${d.basename(n.path)}.`,changes:[`append to ${n.path}`,...n.lines.map(o=>`ensure line: ${o}`)]};if(n?.type==="file-copy")return {title:i?.title??"Copy file",summary:`Copy ${d.basename(n.sourcePath)} to ${d.basename(n.path)} if the target is missing.`,changes:[`copy ${n.sourcePath} -> ${n.path}`,"do not overwrite an existing target file"]};if(n?.type==="package-json-script")return {title:i?.title??"Update package.json script",summary:`Ensure package.json script "${n.scriptName}" exists.`,changes:[`set scripts.${n.scriptName}=${n.scriptValue}`]};if(n?.type==="json-edit")return {title:i?.title??"Update JSON document",summary:`Apply ${n.edits.length} JSON pointer edit(s) to ${d.basename(n.path)}.`,changes:n.edits.map(o=>`set ${o.pointer}=${JSON.stringify(o.value)}`)};if(n?.type==="env-key-add")return {title:i?.title??"Add environment keys",summary:`Ensure ${n.keys.length} environment key(s) exist in ${d.basename(n.path)}.`,changes:n.keys.map(o=>`ensure ${o.name}`)};if(n?.type==="makefile-target")return {title:i?.title??"Add Makefile target",summary:`Ensure Makefile target "${n.target}" exists.`,changes:[`target ${n.target}`,`command ${n.command}`,...n.phony?["mark target as .PHONY"]:[]]};if(t.kind==="env-copy")return {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"]};if(t.kind==="manual-url")return {title:"Open manual guidance",summary:"Manual remediation is required outside Doctor.",changes:[t.originalCommand]};if(i?.status==="manual"||i?.requiresReview){let o=i.transaction?.kind==="dependency-security";return {title:i.title,summary:i.reason,changes:o?["review the dependency remediation candidates","approve a breaking change, replacement, exception, or upstream wait explicitly"]:["review the project-specific requirements and proposed guidance","approve the intended source or configuration change explicitly"]}}return {title:i?.title??"Run remediation command",summary:t.reason??"Run the planned remediation command.",changes:[t.originalCommand]}}function Fr(e,t){let i=t.endsWith(`
|
|
32
32
|
`)?t.slice(0,-1).split(`
|
|
33
33
|
`):t.split(`
|
|
34
|
-
`);return ["--- /dev/null",`+++ ${e}`,"@@",...i.map(n=>`+${n}`)]}function Ar(e){let{step:t,operation:i}=e;if(!i)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(i.type==="file-create")return {available:true,format:"unified",summary:`Create ${i.path} without overwriting an existing file.`,hunks:Er(i.path,i.content)};if(i.type==="file-append")return {available:true,format:"unified",summary:`Append ${i.lines.length} line(s) to ${i.path} when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@",...i.lines.map(n=>`+${n}`)]};if(i.type==="file-copy")return {available:true,format:"summary",summary:`Copy ${i.sourcePath} to ${i.path} when target is missing.`,hunks:[`copy ${i.sourcePath} -> ${i.path}`],limitations:["Source content is read during apply to avoid stale preview data."]};if(i.type==="package-json-script")return {available:true,format:"unified",summary:`Add scripts.${i.scriptName} to package.json when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@ scripts",`+ "${i.scriptName}": "${i.scriptValue}"`]};if(i.type==="json-edit")return {available:true,format:"summary",summary:`Apply ${i.edits.length} JSON pointer edit(s) to ${i.path}.`,hunks:i.edits.map(n=>`set ${n.pointer}=${JSON.stringify(n.value)}`)};if(i.type==="env-key-add")return {available:true,format:"unified",summary:`Add ${i.keys.length} env key(s) to ${i.path} when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@",...i.keys.flatMap(n=>[...n.comment?[`+# ${n.comment}`]:[],`+${n.name}=${n.value}`])]};if(i.type==="makefile-target"){let n=[...i.phony?[`.PHONY: ${i.target}`]:[],`${i.target}:`,` ${i.command}`];return {available:true,format:"unified",summary:`Add Makefile target "${i.target}" when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@",...n.map(o=>`+${o}`)]}}return {available:false,format:"none",summary:"No deterministic file diff preview is available for this remediation.",hunks:[]}}function $r(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 Fr(e){return e.step.executable?e.executableInCurrentEnvironment?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:"blocked",reason:e.blockedReason??"Required tool or environment is not available."}:e.capability?.status==="manual"||e.capability?.requiresReview?{state:"review-required",reason:e.capability.reason}:{state:"guidance-only",reason:e.step.reason??"This remediation is guidance-only."}}function Nr(e){let{step:t,issueClass:i,repairIntent:n,operation:o}=e;return t.kind==="dependency-sync"||t.kind==="go-mod-tidy"||i==="dependency"?"dependency-baseline":!t.executable||t.kind==="manual-url"||n?.mode==="manual-guidance"?"manual-review":t.kind==="env-copy"||i==="environment"?"local-environment":t.kind==="package-json-script"||t.kind==="json-edit"||t.kind==="makefile-target"||o?.type==="file-append"&&(i==="test"||i==="quality"||i==="security")?"command-contract":t.kind==="env-key-add"?"local-environment":t.kind==="rapidkit-init"||i==="workspace-contract"?"runtime-governance":o?.type==="file-create"||o?.type==="file-append"?"source-hygiene":"generic-execution"}function Jn(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 Ir(e){return [...e].sort((i,n)=>{let o=Jn(i.phase)-Jn(n.phase);if(o!==0)return o;let s=i.projectName.localeCompare(n.projectName);return s!==0?s:i.id.localeCompare(n.id)}).map((i,n)=>({...i,order:n+1}))}function Mr(e){let t=new Map;for(let i of e){if(i.phase!=="dependency-baseline")continue;let n=t.get(i.projectPath)??[];n.push(i.id),t.set(i.projectPath,n);}return e.map(i=>{if(i.phase==="dependency-baseline")return i;let n=t.get(i.projectPath)??[];return n.length===0?i:{...i,dependsOn:[...new Set([...i.dependsOn,...n])]}})}function Tr(e,t,i){if(i.kind==="dependency-sync"||i.kind==="go-mod-tidy")return `${e.path}:dependency-baseline`;let n=Ie(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(a=>a.pointer).join(",")}`;if(n?.type==="env-key-add")return `${e.path}:env-key-add:${n.path}:${n.keys.map(a=>a.name).join(",")}`;if(n?.type==="makefile-target")return `${e.path}:makefile-target:${n.path}:${n.target}`;let o=gt(t);if(o)return `${e.path}:file-copy:${d.join(o.projectPath,".env")}`;let s=yt(t);return s?`${e.path}:package-json-script:${d.join(s.projectPath,"package.json")}:${s.scriptName}`:null}function Or(e,t){return pt(e,t)?4:Ie(t)?3:yt(t)?2:gt(t)?1:0}async function Wt(e,t="local"){let n=e.filter(y=>(y.fixCommands?.length??0)>0||(y.repairCapabilities??[]).some(h=>h.status==="manual")).flatMap(y=>{let h=(y.fixCommands??[]).map(b=>{let D=pt(y,b);return {project:y,step:Rr(y,b),command:b,capability:D,probe:Tt(y,D)}}),w=(y.repairCapabilities??[]).filter(b=>b.status==="manual").map(b=>({project:y,step:{projectName:y.name,projectPath:y.path,originalCommand:b.command??"",kind:"shell",risk:b.risk,executable:false,reason:b.reason},command:b.command??"",capability:b,probe:Tt(y,b)}));return [...h,...w]}),o=[],s=new Map;for(let y of n){let h=Tr(y.project,y.command,y.step);if(!h){o.push(y);continue}let w=Or(y.project,y.command),b=s.get(h);if(!b){s.set(h,{index:o.length,priority:w}),o.push(y);continue}w>b.priority&&(o[b.index]=y,s.set(h,{index:b.index,priority:w}));}let a=o,r=null,c=[],l=0,p=0,g=0,v=0;for(let y of a){let{project:h,step:w,command:b}=y,D=w.executable,F;w.kind==="go-mod-tidy"&&(r===null&&(r=await pi()),r||(D=false,F="Go toolchain not available")),D&&(l+=1,w.risk==="safe"&&(p+=1),w.risk==="guarded"&&(g+=1),w.risk==="invasive"&&(v+=1));let f=y.capability??pt(h,b),R=y.probe??Tt(h,f),x=f?.operation??Ie(b)??void 0,B=f?.files??(x&&"path"in x?[x.path]:[]),P=R?.repairIntent,L=Fr({step:w,capability:f,executableInCurrentEnvironment:D,blockedReason:F,policyProfile:t}),M=Nr({step:w,issueClass:R?.issueClass,repairIntent:P,operation:x});c.push({...w,id:hr({projectName:h.name,kind:w.kind,command:b,operation:x,capabilityId:f?.id}),phase:M,order:0,dependsOn:[],issueId:f?.issueId,issueClass:R?.issueClass,operationalImpact:R?.operationalImpact,repairIntent:P,files:B,...x?{operation:x}:{},...f?.strategy?{strategy:f.strategy.map(ne=>structuredClone(ne))}:{},...f?.transaction?{transaction:structuredClone(f.transaction)}:{},preview:Sr({step:w,capability:f,operation:x}),diffPreview:Ar({step:w,operation:x}),verifyCommand:f?.verifyCommand,refreshCommands:f?.refreshCommands??["npx workspai doctor project --json"],rollback:$r(w),studioStatus:L,executableInCurrentEnvironment:D,blockedReason:F});}let j=Mr(Ir(c)),k=new Set(j.map(y=>y.projectPath)).size;return {schemaVersion:d$2.doctorRemediationPlan.schemaVersion,generatedAt:new Date().toISOString(),policyProfile:t,fixableProjects:k,totalSteps:j.length,executableSteps:l,risk:{safe:p,guarded:g,invasive:v},steps:j}}function zn(e){let t=e instanceof Error?e.message:String(e),i=["ETIMEDOUT","ECONNRESET","ECONNREFUSED","EAI_AGAIN","ENOTFOUND","network","503","504"],n=t.toLowerCase();return i.some(o=>n.includes(o.toLowerCase()))}async function _r(e,t){let i=e.get(t);if(i)return i;let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,o=d.basename(t).replace(/[^a-zA-Z0-9._-]/g,"_"),s=d.join(t,".workspai","reports","fix-snapshots",`${o}-${n}`);await u.ensureDir(s);let a=[".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"],r=new Map;for(let l of a){let p=d.join(t,l);if(!await u.pathExists(p))continue;let g=d.join(s,l);await u.ensureDir(d.dirname(g)),await u.copy(p,g,{overwrite:true}),r.set(p,g);}let c={snapshotRoot:s,files:r,missingFiles:new Set};return e.set(t,c),c}async function Ae(e,t){if(e.files.has(t)||e.missingFiles.has(t))return;if(!await u.pathExists(t)){e.missingFiles.add(t);return}let i=d.basename(t),n=d.join(e.snapshotRoot,"ad-hoc",`${Date.now()}-${Math.random().toString(36).slice(2,8)}-${i}`);await u.ensureDir(d.dirname(n)),await u.copy(t,n,{overwrite:true}),e.files.set(t,n);}async function Gr(e){for(let[t,i]of e.files.entries())await u.pathExists(i)&&(await u.ensureDir(d.dirname(t)),await u.copy(i,t,{overwrite:true}));for(let t of e.missingFiles)await u.pathExists(t)&&await u.remove(t);}async function Kr(e){let t=await ft(e,{allowNonRapidkit:true});return {issues:t.issues.length,healthy:t.issues.length===0}}async function Ot(e){let t=[];for(let i of e){let n=await ft(i.path,{allowNonRapidkit:true});for(let o of n.issues)typeof o=="string"&&o.trim()&&t.push(`${i.name}: ${o.trim()}`);}return t.slice(0,24)}function Un(e){let t=[];for(let i of e)for(let n of i.issues)typeof n=="string"&&n.trim()&&t.push(`${i.name}: ${n.trim()}`);return t.slice(0,24)}async function fe(e,t=false,i={}){let n=await Wt(e,i.policyProfile);i.artifactRoot&&(i.planOnly||t)&&await Kt(i.artifactRoot,n,i.artifactMirrorRoots);let o=e.filter(f=>f.fixCommands&&f.fixCommands.length>0),s=[],a=i.json===true,r=(...f)=>{a||console.log(...f);},c$2=null,l=n.steps.some(f=>f.kind==="go-mod-tidy"&&!f.executableInCurrentEnvironment),p=new Map;if(o.length===0){if(a||console.log(m.green(`
|
|
34
|
+
`);return ["--- /dev/null",`+++ ${e}`,"@@",...i.map(n=>`+${n}`)]}function Nr(e){let{step:t,operation:i}=e;if(!i)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(i.type==="file-create")return {available:true,format:"unified",summary:`Create ${i.path} without overwriting an existing file.`,hunks:Fr(i.path,i.content)};if(i.type==="file-append")return {available:true,format:"unified",summary:`Append ${i.lines.length} line(s) to ${i.path} when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@",...i.lines.map(n=>`+${n}`)]};if(i.type==="file-copy")return {available:true,format:"summary",summary:`Copy ${i.sourcePath} to ${i.path} when target is missing.`,hunks:[`copy ${i.sourcePath} -> ${i.path}`],limitations:["Source content is read during apply to avoid stale preview data."]};if(i.type==="package-json-script")return {available:true,format:"unified",summary:`Add scripts.${i.scriptName} to package.json when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@ scripts",`+ "${i.scriptName}": "${i.scriptValue}"`]};if(i.type==="json-edit")return {available:true,format:"summary",summary:`Apply ${i.edits.length} JSON pointer edit(s) to ${i.path}.`,hunks:i.edits.map(n=>`set ${n.pointer}=${JSON.stringify(n.value)}`)};if(i.type==="env-key-add")return {available:true,format:"unified",summary:`Add ${i.keys.length} env key(s) to ${i.path} when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@",...i.keys.flatMap(n=>[...n.comment?[`+# ${n.comment}`]:[],`+${n.name}=${n.value}`])]};if(i.type==="makefile-target"){let n=[...i.phony?[`.PHONY: ${i.target}`]:[],`${i.target}:`,` ${i.command}`];return {available:true,format:"unified",summary:`Add Makefile target "${i.target}" when missing.`,hunks:[`--- ${i.path}`,`+++ ${i.path}`,"@@",...n.map(o=>`+${o}`)]}}return {available:false,format:"none",summary:"No deterministic file diff preview is available for this remediation.",hunks:[]}}function Ir(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 Mr(e){return e.step.executable?e.executableInCurrentEnvironment?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:"blocked",reason:e.blockedReason??"Required tool or environment is not available."}:e.capability?.status==="manual"||e.capability?.requiresReview?{state:"review-required",reason:e.capability.reason}:{state:"guidance-only",reason:e.step.reason??"This remediation is guidance-only."}}function Tr(e){let{step:t,issueClass:i,repairIntent:n,operation:o}=e;return t.kind==="dependency-sync"||t.kind==="go-mod-tidy"||i==="dependency"?"dependency-baseline":!t.executable||t.kind==="manual-url"||n?.mode==="manual-guidance"?"manual-review":t.kind==="env-copy"||i==="environment"?"local-environment":t.kind==="package-json-script"||t.kind==="json-edit"||t.kind==="makefile-target"||o?.type==="file-append"&&(i==="test"||i==="quality"||i==="security")?"command-contract":t.kind==="env-key-add"?"local-environment":t.kind==="rapidkit-init"||i==="workspace-contract"?"runtime-governance":o?.type==="file-create"||o?.type==="file-append"?"source-hygiene":"generic-execution"}function Un(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 Or(e){return [...e].sort((i,n)=>{let o=Un(i.phase)-Un(n.phase);if(o!==0)return o;let s=i.projectName.localeCompare(n.projectName);return s!==0?s:i.id.localeCompare(n.id)}).map((i,n)=>({...i,order:n+1}))}function _r(e){let t=new Map;for(let i of e){if(i.phase!=="dependency-baseline")continue;let n=t.get(i.projectPath)??[];n.push(i.id),t.set(i.projectPath,n);}return e.map(i=>{if(i.phase==="dependency-baseline")return i;let n=t.get(i.projectPath)??[];return n.length===0?i:{...i,dependsOn:[...new Set([...i.dependsOn,...n])]}})}function Gr(e,t,i){if(i.kind==="dependency-sync"||i.kind==="go-mod-tidy")return `${e.path}:dependency-baseline`;let n=Ie(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(a=>a.pointer).join(",")}`;if(n?.type==="env-key-add")return `${e.path}:env-key-add:${n.path}:${n.keys.map(a=>a.name).join(",")}`;if(n?.type==="makefile-target")return `${e.path}:makefile-target:${n.path}:${n.target}`;let o=gt(t);if(o)return `${e.path}:file-copy:${d.join(o.projectPath,".env")}`;let s=yt(t);return s?`${e.path}:package-json-script:${d.join(s.projectPath,"package.json")}:${s.scriptName}`:null}function Kr(e,t){return pt(e,t)?4:Ie(t)?3:yt(t)?2:gt(t)?1:0}async function Wt(e,t="local"){let n=e.filter(g=>(g.fixCommands?.length??0)>0||(g.repairCapabilities??[]).some(h=>h.status==="manual")).flatMap(g=>{let h=(g.fixCommands??[]).map(b=>{let D=pt(g,b);return {project:g,step:Ar(g,b),command:b,capability:D,probe:Tt(g,D)}}),w=(g.repairCapabilities??[]).filter(b=>b.status==="manual").map(b=>({project:g,step:{projectName:g.name,projectPath:g.path,originalCommand:b.command??"",kind:"shell",risk:b.risk,executable:false,reason:b.reason},command:b.command??"",capability:b,probe:Tt(g,b)}));return [...h,...w]}),o=[],s=new Map;for(let g of n){let h=Gr(g.project,g.command,g.step);if(!h){o.push(g);continue}let w=Kr(g.project,g.command),b=s.get(h);if(!b){s.set(h,{index:o.length,priority:w}),o.push(g);continue}w>b.priority&&(o[b.index]=g,s.set(h,{index:b.index,priority:w}));}let a=o,r=null,c=[],l=0,p=0,y=0,v=0;for(let g of a){let{project:h,step:w,command:b}=g,D=w.executable,F;w.kind==="go-mod-tidy"&&(r===null&&(r=await fi()),r||(D=false,F="Go toolchain not available")),D&&(l+=1,w.risk==="safe"&&(p+=1),w.risk==="guarded"&&(y+=1),w.risk==="invasive"&&(v+=1));let f=g.capability??pt(h,b),R=g.probe??Tt(h,f),x=f?.operation??Ie(b)??void 0,B=f?.files??(x&&"path"in x?[x.path]:[]),P=R?.repairIntent,L=Mr({step:w,capability:f,executableInCurrentEnvironment:D,blockedReason:F,policyProfile:t}),M=Tr({step:w,issueClass:R?.issueClass,repairIntent:P,operation:x});c.push({...w,id:br({projectName:h.name,kind:w.kind,command:b,operation:x,capabilityId:f?.id}),phase:M,order:0,dependsOn:[],issueId:f?.issueId,issueClass:R?.issueClass,operationalImpact:R?.operationalImpact,repairIntent:P,files:B,...x?{operation:x}:{},...f?.strategy?{strategy:f.strategy.map(ne=>structuredClone(ne))}:{},...f?.transaction?{transaction:structuredClone(f.transaction)}:{},preview:$r({step:w,capability:f,operation:x}),diffPreview:Nr({step:w,operation:x}),verifyCommand:f?.verifyCommand,refreshCommands:f?.refreshCommands??["npx workspai doctor project --json"],rollback:Ir(w),studioStatus:L,executableInCurrentEnvironment:D,blockedReason:F});}let j=_r(Or(c)),k=new Set(j.map(g=>g.projectPath)).size;return {schemaVersion:d$2.doctorRemediationPlan.schemaVersion,generatedAt:new Date().toISOString(),policyProfile:t,fixableProjects:k,totalSteps:j.length,executableSteps:l,risk:{safe:p,guarded:y,invasive:v},steps:j}}function Zn(e){let t=e instanceof Error?e.message:String(e),i=["ETIMEDOUT","ECONNRESET","ECONNREFUSED","EAI_AGAIN","ENOTFOUND","network","503","504"],n=t.toLowerCase();return i.some(o=>n.includes(o.toLowerCase()))}async function Wr(e,t){let i=e.get(t);if(i)return i;let n=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,o=d.basename(t).replace(/[^a-zA-Z0-9._-]/g,"_"),s=d.join(t,".workspai","reports","fix-snapshots",`${o}-${n}`);await u.ensureDir(s);let a=[".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"],r=new Map;for(let l of a){let p=d.join(t,l);if(!await u.pathExists(p))continue;let y=d.join(s,l);await u.ensureDir(d.dirname(y)),await u.copy(p,y,{overwrite:true}),r.set(p,y);}let c={snapshotRoot:s,files:r,missingFiles:new Set};return e.set(t,c),c}async function Ae(e,t){if(e.files.has(t)||e.missingFiles.has(t))return;if(!await u.pathExists(t)){e.missingFiles.add(t);return}let i=d.basename(t),n=d.join(e.snapshotRoot,"ad-hoc",`${Date.now()}-${Math.random().toString(36).slice(2,8)}-${i}`);await u.ensureDir(d.dirname(n)),await u.copy(t,n,{overwrite:true}),e.files.set(t,n);}async function Br(e){for(let[t,i]of e.files.entries())await u.pathExists(i)&&(await u.ensureDir(d.dirname(t)),await u.copy(i,t,{overwrite:true}));for(let t of e.missingFiles)await u.pathExists(t)&&await u.remove(t);}async function Hr(e){let t=await ft(e,{allowNonRapidkit:true});return {issues:t.issues.length,healthy:t.issues.length===0}}async function Ot(e){let t=[];for(let i of e){let n=await ft(i.path,{allowNonRapidkit:true});for(let o of n.issues)typeof o=="string"&&o.trim()&&t.push(`${i.name}: ${o.trim()}`);}return t.slice(0,24)}function Yn(e){let t=[];for(let i of e)for(let n of i.issues)typeof n=="string"&&n.trim()&&t.push(`${i.name}: ${n.trim()}`);return t.slice(0,24)}async function fe(e,t=false,i={}){let n=await Wt(e,i.policyProfile);i.artifactRoot&&(i.planOnly||t)&&await Kt(i.artifactRoot,n,i.artifactMirrorRoots);let o=e.filter(f=>f.fixCommands&&f.fixCommands.length>0),s=[],a=i.json===true,r=(...f)=>{a||console.log(...f);},c$2=null,l=n.steps.some(f=>f.kind==="go-mod-tidy"&&!f.executableInCurrentEnvironment),p=new Map;if(o.length===0){if(a||console.log(m.green(`
|
|
35
35
|
\u2705 No fixes needed - all projects are healthy!`)),t){let f=c({appliedFixes:[],remainingBlockers:[],verifyRecommended:b});return i.artifactRoot&&(await Fe(i.artifactRoot,f,i.artifactMirrorRoots),await Ne(i.artifactRoot,f,i.historyScope??"project")),f}return}if(!a){console.log(m.bold.cyan(`
|
|
36
36
|
\u{1F527} Available Fixes:
|
|
37
37
|
`));for(let f of o){let R=f.fixCommands??[];console.log(m.bold(`Project: ${m.yellow(f.name)}`)),R.forEach((x,B)=>{console.log(` ${B+1}. ${m.cyan(dt(f,x))}`);}),console.log();}}if(i.planOnly){if(i.json){console.log(JSON.stringify(n,null,2));return}console.log(m.bold(`
|
|
38
38
|
\u{1F9ED} Remediation Plan
|
|
39
39
|
`)),console.log(m.gray(`Executable steps: ${n.executableSteps}/${n.totalSteps} | risk: safe=${n.risk.safe}, guarded=${n.risk.guarded}, invasive=${n.risk.invasive}`));for(let f of n.steps){let R=o.find(B=>B.path===f.projectPath),x=f.executableInCurrentEnvironment?m.green("ready"):m.yellow(`blocked${f.blockedReason?` (${f.blockedReason})`:""}`);console.log(` - ${m.cyan(f.projectName)} [${f.risk}] ${R?dt(R,f.originalCommand):f.preview.title} ${m.gray(`=> ${x}`)}`);}console.log(m.gray(`
|
|
40
|
-
Use --apply to execute this plan non-interactively, or --fix for interactive confirmation.`));return}let
|
|
40
|
+
Use --apply to execute this plan non-interactively, or --fix for interactive confirmation.`));return}let y=n.executableSteps,v=n.risk.safe,j=n.risk.guarded,k=n.risk.invasive;if(y===0){if(a||(console.log(m.gray("\u{1F4A1} No automatic fixes can be applied right now.")),l&&console.log(m.gray(" Install Go to enable go mod tidy fixes, then rerun `workspai doctor workspace --fix`."))),t){let f=c({appliedFixes:[],remainingBlockers:await Ot(e),verifyRecommended:b});return i.artifactRoot&&(await Fe(i.artifactRoot,f,i.artifactMirrorRoots),await Ne(i.artifactRoot,f,i.historyScope??"project")),f}return}if(!t){a||console.log(m.gray('\u{1F4A1} Run "npx workspai doctor workspace --fix" to apply fixes automatically'));return}if(a||console.log(m.gray(`Risk policy: safe=${v}, guarded=${j}, invasive=${k}. Guarded/invasive fixes use snapshot + rollback.`)),!i.skipConfirmation){let{confirm:f}=await b$1([{type:"confirm",name:"confirm",message:`Apply ${o.reduce((R,x)=>R+(x.fixCommands?.length??0),0)} fix(es)?`,default:false}]);if(!f){a||console.log(m.yellow(`
|
|
41
41
|
\u26A0\uFE0F Fixes cancelled by user`));let R=c({appliedFixes:[],remainingBlockers:await Ot(e),verifyRecommended:b});return i.artifactRoot&&(await Fe(i.artifactRoot,R,i.artifactMirrorRoots),await Ne(i.artifactRoot,R,i.historyScope??"project")),R}}a||console.log(m.bold.cyan(`
|
|
42
42
|
\u{1F680} Applying fixes...
|
|
43
|
-
`));let
|
|
43
|
+
`));let g=new Set,h=new Map(o.map(f=>[f.path,f])),w=new Set,b$2=vr(),D=process.env.RAPIDKIT_DOCTOR_FIX_ALLOW_GUARDED_COMMANDS==="1"||process.env.RAPIDKIT_DOCTOR_FIX_ALLOW_DEPENDENCY_SYNC==="1",F="";for(let f of n.steps){let R=h.get(f.projectPath);if(!R)continue;let x=f.originalCommand;a||F!==f.projectName&&(F=f.projectName,console.log(m.bold(`Fixing ${m.cyan(f.projectName)}...`)));let B=`${f.projectPath}::${x}`;if(!g.has(B)){g.add(B);try{if(r(m.gray(` ${dt(R,x)}`)),f.kind==="manual-url"){r(m.yellow(` \u2139 Manual action required: open ${x}`)),r(m.green(` \u2705 Recorded as guidance
|
|
44
44
|
`));continue}if(!f.executable||!f.executableInCurrentEnvironment){let Q=f.blockedReason?`: ${f.blockedReason}`:"";r(m.yellow(` \u26A0 Step is non-executable by policy${Q}`)),r(m.green(` \u2705 Recorded as guidance
|
|
45
|
-
`));continue}let P=Ie(x),M=f.risk!=="safe"||P?.type==="file-create"||P?.type==="file-append"||P?.type==="file-copy"||P?.type==="json-edit"||P?.type==="env-key-add"||P?.type==="makefile-target"?await
|
|
45
|
+
`));continue}let P=Ie(x),M=f.risk!=="safe"||P?.type==="file-create"||P?.type==="file-append"||P?.type==="file-copy"||P?.type==="json-edit"||P?.type==="env-key-add"||P?.type==="makefile-target"?await Wr(p,f.projectPath):null;M&&P?.type==="file-create"&&await Ae(M,P.path),M&&P?.type==="file-append"&&await Ae(M,P.path),M&&P?.type==="file-copy"&&await Ae(M,P.path),M&&P?.type==="json-edit"&&await Ae(M,P.path),M&&P?.type==="env-key-add"&&await Ae(M,P.path),M&&P?.type==="makefile-target"&&await Ae(M,P.path);let ne=gt(x);if(ne){let Q=d.join(ne.projectPath,".env.example"),C=d.join(ne.projectPath,".env");if(!await u.pathExists(Q))throw new Error(`.env.example not found at ${Q}`);if(await u.pathExists(C)){r(m.green(` \u2705 .env already exists
|
|
46
46
|
`));continue}await u.copy(Q,C,{overwrite:false,errorOnExist:false}),w.add(f.projectPath),s.push({path:C,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
47
|
-
`));continue}if(P?.type==="file-copy"){await
|
|
48
|
-
`));continue}let Ye=yt(x);if(Ye){await
|
|
49
|
-
`));continue}if(P?.type==="file-create"){await
|
|
50
|
-
`));continue}if(P?.type==="file-append"){await
|
|
51
|
-
`));continue}if(P?.type==="json-edit"){await
|
|
52
|
-
`));continue}if(P?.type==="env-key-add"){await
|
|
53
|
-
`));continue}if(P?.type==="makefile-target"){await
|
|
47
|
+
`));continue}if(P?.type==="file-copy"){await Pr({projectPath:f.projectPath,operation:P}),w.add(f.projectPath),s.push({path:P.path,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
48
|
+
`));continue}let Ye=yt(x);if(Ye){await jr(Ye),w.add(f.projectPath),s.push({path:f.projectPath,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
49
|
+
`));continue}if(P?.type==="file-create"){await xr({projectPath:f.projectPath,operation:P}),w.add(f.projectPath),s.push({path:P.path,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
50
|
+
`));continue}if(P?.type==="file-append"){await Cr({projectPath:f.projectPath,operation:P}),w.add(f.projectPath),s.push({path:P.path,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
51
|
+
`));continue}if(P?.type==="json-edit"){await Rr({projectPath:f.projectPath,operation:P}),w.add(f.projectPath),s.push({path:P.path,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
52
|
+
`));continue}if(P?.type==="env-key-add"){await Sr({projectPath:f.projectPath,operation:P}),w.add(f.projectPath),s.push({path:P.path,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
53
|
+
`));continue}if(P?.type==="makefile-target"){await Er({projectPath:f.projectPath,operation:P}),w.add(f.projectPath),s.push({path:P.path,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
54
54
|
`));continue}let Qe=ve(x,"(?:npx\\s+workspai|rapidkit)\\s+init");if(Qe){if(!D){r(m.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.")),s.push({path:f.projectPath,action:f.kind,outcome:"guidance",projectName:f.projectName,command:x,detail:"Guarded setup command was not auto-executed by doctor --fix. Run it explicitly after review."});continue}await execa("rapidkit",["init"],{cwd:Qe.projectPath,shell:c$1(),stdio:a?"pipe":"inherit",timeout:b$2,forceKillAfterDelay:1e3}),w.add(f.projectPath),s.push({path:f.projectPath,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
55
|
-
`));continue}let Xe=ve(x,"go\\s+mod\\s+tidy");if(Xe){if(c$2===null&&(c$2=await
|
|
55
|
+
`));continue}let Xe=ve(x,"go\\s+mod\\s+tidy");if(Xe){if(c$2===null&&(c$2=await fi()),!c$2){r(m.yellow(" \u26A0 Go toolchain is not installed \u2014 skipping go mod tidy; install Go to apply this fix.")),r(m.green(` \u2705 Recorded as guidance
|
|
56
56
|
`));continue}await execa("go",["mod","tidy"],{cwd:Xe.projectPath,shell:c$1(),stdio:a?"pipe":"inherit",timeout:b$2,forceKillAfterDelay:1e3}),w.add(f.projectPath),s.push({path:f.projectPath,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
57
|
-
`));continue}let V=
|
|
58
|
-
`));continue}let Me=f.kind==="shell"?2:1,ge;for(let Q=1;Q<=Me;Q+=1)try{await execa(x,{shell:true,stdio:a?"pipe":"inherit",timeout:b$2,forceKillAfterDelay:1e3}),ge=null;break}catch(C){if(ge=C,Q<Me&&
|
|
59
|
-
`)),w.add(f.projectPath),s.push({path:f.projectPath,action:f.kind,outcome:"applied",projectName:f.projectName,command:x});}catch(P){let L=Ie(x);if(f.risk!=="safe"||L?.type==="file-create"||L?.type==="file-append"||L?.type==="file-copy"||L?.type==="json-edit"||L?.type==="env-key-add"||L?.type==="makefile-target"){let M=p.get(f.projectPath);if(M)try{await
|
|
60
|
-
`)),s.push({path:f.projectPath,action:f.kind,outcome:"failed",projectName:f.projectName,command:x,detail:P instanceof Error?P.message:String(P)});}}}for(let f of o)if(w.has(f.path))try{let R=await
|
|
61
|
-
\u2705 Fix process completed!`)),t){let f=c({appliedFixes:s,remainingBlockers:await Ot(e),verifyRecommended:b});return i.artifactRoot&&(await Fe(i.artifactRoot,f,i.artifactMirrorRoots),await Ne(i.artifactRoot,f,i.historyScope??"project")),f}}function Ze(e,t){let i=mt(t),n=Number(e?.errors??0),o=Number(e?.warnings??0);return i.exitOnErrors&&n>0?1:i.exitOnWarnings&&o>0?i.warningExitCode:0}function
|
|
57
|
+
`));continue}let V=Lt(x);if(V){if(!D&&new Set(["npm","pnpm","yarn","bun","poetry","pip","pip3","pipenv"]).has(V.command)){r(m.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.")),s.push({path:f.projectPath,action:f.kind,outcome:"guidance",projectName:f.projectName,command:x,detail:"Guarded dependency command was not auto-executed by doctor --fix. Run it explicitly after review."});continue}let C=2,S,T=V.command==="poetry"&&V.args[0]==="install"?{...process.env,POETRY_CACHE_DIR:d.join(V.projectPath,".workspai","cache","python","poetry")}:process.env;for(let _=1;_<=C;_+=1)try{await execa(V.command,V.args,{cwd:V.projectPath,env:T,shell:c$1(),stdio:a?"pipe":"inherit",timeout:b$2,forceKillAfterDelay:1e3}),S=null;break}catch(ie){if(S=ie,_<C&&Zn(ie)){r(m.yellow(` \u26A0 Retrying dependency sync (${_}/${C-1})...`));continue}throw ie}if(S)throw S;w.add(f.projectPath),s.push({path:f.projectPath,action:f.kind,outcome:"applied",projectName:f.projectName,command:x}),r(m.green(` \u2705 Success
|
|
58
|
+
`));continue}let Me=f.kind==="shell"?2:1,ge;for(let Q=1;Q<=Me;Q+=1)try{await execa(x,{shell:true,stdio:a?"pipe":"inherit",timeout:b$2,forceKillAfterDelay:1e3}),ge=null;break}catch(C){if(ge=C,Q<Me&&Zn(C)){r(m.yellow(` \u26A0 Retrying command (${Q}/${Me-1})...`));continue}throw C}if(ge)throw ge;a||console.log(m.green(` \u2705 Success
|
|
59
|
+
`)),w.add(f.projectPath),s.push({path:f.projectPath,action:f.kind,outcome:"applied",projectName:f.projectName,command:x});}catch(P){let L=Ie(x);if(f.risk!=="safe"||L?.type==="file-create"||L?.type==="file-append"||L?.type==="file-copy"||L?.type==="json-edit"||L?.type==="env-key-add"||L?.type==="makefile-target"){let M=p.get(f.projectPath);if(M)try{await Br(M),a||console.log(m.yellow(" \u21A9 Rolled back snapshot after failed fix"));}catch(ne){a||console.log(m.red(` \u274C Rollback failed: ${ne instanceof Error?ne.message:String(ne)}`));}}a||console.log(m.red(` \u274C Failed: ${P instanceof Error?P.message:String(P)}
|
|
60
|
+
`)),s.push({path:f.projectPath,action:f.kind,outcome:"failed",projectName:f.projectName,command:x,detail:P instanceof Error?P.message:String(P)});}}}for(let f of o)if(w.has(f.path))try{let R=await Hr(f.path);a||console.log(R.healthy?m.green(` \u2705 Post-fix verification passed for ${f.name}`):m.yellow(` \u26A0 Post-fix verification: ${R.issues} issue(s) remain for ${f.name}`));}catch(R){a||console.log(m.yellow(` \u26A0 Post-fix verification skipped: ${R instanceof Error?R.message:String(R)}`));}if(a||console.log(m.bold.green(`
|
|
61
|
+
\u2705 Fix process completed!`)),t){let f=c({appliedFixes:s,remainingBlockers:await Ot(e),verifyRecommended:b});return i.artifactRoot&&(await Fe(i.artifactRoot,f,i.artifactMirrorRoots),await Ne(i.artifactRoot,f,i.historyScope??"project")),f}}function Ze(e,t){let i=mt(t),n=Number(e?.errors??0),o=Number(e?.warnings??0);return i.exitOnErrors&&n>0?1:i.exitOnWarnings&&o>0?i.warningExitCode:0}function Qn(e,t,i){let n=Ze(e,t);return i?.appliedFixes.some(s=>s.outcome==="failed")??false?Math.max(n,1):n}async function Ys(e={}){let t=mt({profile:e.profile,strict:e.strict,ci:e.ci}),i=!!(e.fix||e.plan||e.apply),n=typeof e.workspace=="string"&&e.workspace.trim().length>0?d.resolve(e.workspace):null,o=!n&&!e.workspace&&!e.project&&i?await Ue(process.cwd()):null,s=!!e.workspace||!!o,a=!!e.project&&!s;if(e.json||console.log(m.bold.cyan(`
|
|
62
62
|
\u{1FA7A} Workspai Health Check
|
|
63
|
-
`)),s){let r=n??o??await Ue(process.cwd());r||(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(m.gray("\u2139\uFE0F Detected workspace context; enabling workspace checks for --fix")),console.log(m.bold(`Workspace: ${m.cyan(d.basename(r))}`)),console.log(m.gray(`Path: ${r}`)));let c$1=!(e.plan||e.fix||e.apply),l=await Mt(r,c$1,t);if(e.json||(l.projectScanCached&&console.log(m.gray(`\u2139\uFE0F Reused cached project scan${l.projectScanCachePath?` (${d.basename(l.projectScanCachePath)})`:""}`)),l.evidencePath&&console.log(m.gray(`\u2139\uFE0F Evidence saved: ${l.evidencePath}`))),e.json){let k,
|
|
64
|
-
\u{1F4CA} Health Score:`)),console.log(` ${h(`${
|
|
63
|
+
`)),s){let r=n??o??await Ue(process.cwd());r||(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(m.gray("\u2139\uFE0F Detected workspace context; enabling workspace checks for --fix")),console.log(m.bold(`Workspace: ${m.cyan(d.basename(r))}`)),console.log(m.gray(`Path: ${r}`)));let c$1=!(e.plan||e.fix||e.apply),l=await Mt(r,c$1,t);if(e.json||(l.projectScanCached&&console.log(m.gray(`\u2139\uFE0F Reused cached project scan${l.projectScanCachePath?` (${d.basename(l.projectScanCachePath)})`:""}`)),l.evidencePath&&console.log(m.gray(`\u2139\uFE0F Evidence saved: ${l.evidencePath}`))),e.json){let k,g=e.plan||e.fix||e.apply?await Wt(l.projects,t.name):void 0,h=g?await Kt(r,g):void 0,w;(e.fix||e.apply)&&!e.plan&&(k=await fe(l.projects,true,{skipConfirmation:e.apply===true||e.fix===true,json:true,policyProfile:t.name})??c({appliedFixes:[],remainingBlockers:[],verifyRecommended:b}),l=await Mt(r,false,t),k={...k,remainingBlockers:Yn(l.projects)},w=await Fe(r,k),await Ne(r,k,"workspace"));let b$1=l.projects.map(te),D=b$1.reduce((R,x)=>R+x.blockingFindings,0),F=b$1.reduce((R,x)=>R+x.advisoryFindings,0),f={contract:$e(),policyProfile:t,workspace:{name:l.workspaceName,path:r},cache:{projectScan:l.projectScanCached??false,projectScanPath:l.projectScanCachePath,evidencePath:l.evidencePath},healthScore:l.healthScore,evidenceFreshness:l.evidenceFreshness,system:{python:l.python,poetry:l.poetry,pipx:l.pipx,rapidkitCore:l.rapidkitCore,versions:{core:l.coreVersion,npm:l.npmVersion}},projects:l.projects.map(R=>Vn(R)),summary:{totalProjects:l.projects.length,totalIssues:l.projects.reduce((R,x)=>R+x.issues.length,0),verdict:l.healthScore?.verdict??"passed",blockingFindings:D,advisoryFindings:F,projectAdvisoryWarningProjects:b$1.filter(R=>R.advisoryFindings>0).length,projectAdvisoryWarnings:F,hasSystemErrors:[l.python,l.rapidkitCore].some(R=>R.status==="error"),scopeProvenance:l.scopeProvenance},driftDelta:l.driftDelta,scoreBreakdown:l.scoreBreakdown??[],...g?{remediationPlan:g,remediationPlanPath:h}:{},...k?{appliedFixes:k.appliedFixes,remainingBlockers:k.remainingBlockers,verifyRecommended:k.verifyRecommended,fixResult:k,fixResultPath:w}:{}};return e.quiet||console.log(JSON.stringify(f,null,2)),Qn(l.healthScore,{profile:t.name},k)}if(l.healthScore){let k=l.healthScore,g=Math.round(k.passed/k.total*100),h=g>=80?m.green:g>=50?m.yellow:m.red,w="\u2588".repeat(Math.floor(g/5))+"\u2591".repeat(20-Math.floor(g/5));console.log(m.bold(`
|
|
64
|
+
\u{1F4CA} Health Score:`)),console.log(` ${h(`${g}%`)} ${m.gray(w)}`),console.log(` ${m.green(`\u2705 ${k.passed} passed`)} ${m.gray("|")} ${m.yellow(`\u26A0\uFE0F ${k.warnings} warnings`)} ${m.gray("|")} ${m.red(`\u274C ${k.errors} errors`)}`);}console.log(m.bold(`
|
|
65
65
|
|
|
66
66
|
System Tools:
|
|
67
|
-
`)),W(l.python,"Python"),W(l.poetry,"Poetry"),W(l.pipx,"pipx"),W(l.go,"Go"),W(l.rapidkitCore,"RapidKit Core"),
|
|
67
|
+
`)),W(l.python,"Python"),W(l.poetry,"Poetry"),W(l.pipx,"pipx"),W(l.go,"Go"),W(l.rapidkitCore,"RapidKit Core"),So({coreVersion:l.coreVersion,npmVersion:l.npmVersion})&&(console.log(m.yellow(`
|
|
68
68
|
\u26A0\uFE0F Version mismatch: Core ${l.coreVersion} / CLI ${l.npmVersion}`)),console.log(m.gray(" Consider updating to compatible major versions."))),l.projects.length>0?(console.log(m.bold(`
|
|
69
|
-
\u{1F4E6} Projects (${l.projects.length}):`)),l.projects.forEach(k=>
|
|
70
|
-
\u{1F4E6} Projects:`)),console.log(m.gray(" No Workspai projects found in workspace")));let p=l.projects.map(te),
|
|
71
|
-
\u26A0\uFE0F Doctor verdict: ${l.healthScore?.verdict??"attention"} \xB7 ${
|
|
72
|
-
\u26A0\uFE0F Post-fix verification found ${
|
|
73
|
-
\u2705 Post-fix verification passed. Workspace is healthy.`)),k.projectScanCached&&console.log(m.gray(`\u2139\uFE0F Reused cached project scan${k.projectScanCachePath?` (${d.basename(k.projectScanCachePath)})`:""}`)),k.evidencePath&&console.log(m.gray(`\u2139\uFE0F Evidence refreshed: ${k.evidencePath}`));}}else
|
|
74
|
-
\u2705 All checks passed! Workspace is healthy.`));return Ze(l.healthScore,{profile:t.name})}else if(a){let r=await
|
|
75
|
-
\u{1F4CA} Health Score:`)),console.log(` ${v(`${
|
|
69
|
+
\u{1F4E6} Projects (${l.projects.length}):`)),l.projects.forEach(k=>zn(k,l.rapidkitCore))):(console.log(m.bold(`
|
|
70
|
+
\u{1F4E6} Projects:`)),console.log(m.gray(" No Workspai projects found in workspace")));let p=l.projects.map(te),y=p.reduce((k,g)=>k+g.blockingFindings,0),v=p.reduce((k,g)=>k+g.advisoryFindings,0),j=[l.python,l.rapidkitCore].some(k=>k.status==="error");if(j||y>0||v>0)if(console.log(m.bold.yellow(`
|
|
71
|
+
\u26A0\uFE0F Doctor verdict: ${l.healthScore?.verdict??"attention"} \xB7 ${y} blocking finding(s) \xB7 ${v} advisory finding(s)`)),j&&console.log(m.bold.red("\u274C System requirements not met")),e.plan)await fe(l.projects,false,{planOnly:true,json:e.json,policyProfile:t.name,artifactRoot:r,historyScope:"workspace"});else if(e.fix||e.apply){if(await fe(l.projects,true,{skipConfirmation:e.apply===true,policyProfile:t.name,artifactRoot:r,historyScope:"workspace"}),!e.json){let k=await Mt(r,false,t),g=k.projects.map(te).reduce((w,b)=>w+b.blockingFindings,0),h=[k.python,k.rapidkitCore].some(w=>w.status==="error");h||g>0?(console.log(m.bold.yellow(`
|
|
72
|
+
\u26A0\uFE0F Post-fix verification found ${g} remaining issue(s)`)),h&&console.log(m.bold.red("\u274C System requirements still not met"))):console.log(m.bold.green(`
|
|
73
|
+
\u2705 Post-fix verification passed. Workspace is healthy.`)),k.projectScanCached&&console.log(m.gray(`\u2139\uFE0F Reused cached project scan${k.projectScanCachePath?` (${d.basename(k.projectScanCachePath)})`:""}`)),k.evidencePath&&console.log(m.gray(`\u2139\uFE0F Evidence refreshed: ${k.evidencePath}`));}}else y>0&&await fe(l.projects,false);else console.log(m.bold.green(`
|
|
74
|
+
\u2705 All checks passed! Workspace is healthy.`));return Ze(l.healthScore,{profile:t.name})}else if(a){let r=await pr(process.cwd());if(!r){let b=await Ue(process.cwd());if(e.json){let D={contract:$e(),policyProfile:t,scope:"project",status:"error",generatedAt:new Date().toISOString(),workspace:b?{name:d.basename(b),path:b}:null,project:null,healthScore:{total:1,passed:0,warnings:0,errors:1,verdict:"blocked",components:{host:{total:0,passed:0,warnings:0,errors:0},projects:{total:1,passed:0,warnings:0,errors:1}}},summary:{totalProjects:0,totalIssues:1,projectAdvisoryWarningProjects:0,projectAdvisoryWarnings:0,hasSystemErrors:false},error:{code:b?"doctor.project.scope.not_found_in_workspace":"doctor.project.scope.not_found",message:b?"No project found in the current directory within this workspace.":"No Workspai project found in the current directory or parents.",recommendation:b?"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:b?["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(D,null,2)),1}b?(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 c$1=await Jn(r,t),l=c$1.workspacePath?Ln(c$1.workspacePath):null;if(e.json){let b$1,D=e.plan||e.fix||e.apply?await Wt([c$1.project],t.name):void 0,F=r,f=[],R=D?await Kt(F,D,f):void 0,x;(e.fix||e.apply)&&!e.plan&&(b$1=await fe([c$1.project],true,{skipConfirmation:e.apply===true||e.fix===true,json:true,policyProfile:t.name})??c({appliedFixes:[],remainingBlockers:[],verifyRecommended:b}),c$1=await Jn(r,t),b$1={...b$1,remainingBlockers:Yn([c$1.project])},x=await Fe(F,b$1,f),await Ne(F,b$1,"project"));let B=Ln(c$1.project.path),P=te(c$1.project),L={contract:$e(),policyProfile:t,scope:"project",workspace:l?{name:d.basename(l),path:l}:null,project:{...Vn(c$1.project),path:B},evidencePath:c$1.evidencePath,healthScore:c$1.healthScore,evidenceFreshness:c$1.evidenceFreshness,system:{python:c$1.python,poetry:c$1.poetry,pipx:c$1.pipx,go:c$1.go,rapidkitCore:c$1.rapidkitCore},summary:{totalProjects:1,totalIssues:c$1.project.issues.length,verdict:P.verdict,probeSummary:P,blockingFindings:P.blockingFindings,advisoryFindings:P.advisoryFindings,projectAdvisoryWarningProjects:P.advisoryFindings>0?1:0,projectAdvisoryWarnings:P.advisoryFindings,hasSystemErrors:[c$1.python,c$1.rapidkitCore].some(M=>M.status==="error"),scopeProvenance:c$1.scopeProvenance},driftDelta:c$1.driftDelta,scoreBreakdown:c$1.scoreBreakdown??[],...D?{remediationPlan:D,remediationPlanPath:R}:{},...b$1?{appliedFixes:b$1.appliedFixes,remainingBlockers:b$1.remainingBlockers,verifyRecommended:b$1.verifyRecommended,fixResult:b$1,fixResultPath:x}:{}};return e.quiet||console.log(JSON.stringify(L,null,2)),Qn(c$1.healthScore,{profile:t.name},b$1)}console.log(m.bold(`Project: ${m.cyan(d.basename(r))}`)),console.log(m.gray(`Path: ${r}`)),c$1.workspacePath&&console.log(m.gray(`Workspace: ${d.basename(c$1.workspacePath)}`)),c$1.evidencePath&&console.log(m.gray(`\u2139\uFE0F Evidence saved: ${c$1.evidencePath}`));let p=c$1.healthScore,y=p.total>0?Math.round(p.passed/p.total*100):0,v=y>=80?m.green:y>=50?m.yellow:m.red,j="\u2588".repeat(Math.floor(y/5))+"\u2591".repeat(20-Math.floor(y/5));console.log(m.bold(`
|
|
75
|
+
\u{1F4CA} Health Score:`)),console.log(` ${v(`${y}%`)} ${m.gray(j)}`),console.log(` ${m.green(`\u2705 ${p.passed} passed`)} ${m.gray("|")} ${m.yellow(`\u26A0\uFE0F ${p.warnings} warnings`)} ${m.gray("|")} ${m.red(`\u274C ${p.errors} errors`)}`),console.log(m.bold(`
|
|
76
76
|
|
|
77
77
|
System Tools:
|
|
78
78
|
`)),W(c$1.python,"Python"),W(c$1.poetry,"Poetry"),W(c$1.pipx,"pipx"),W(c$1.go,"Go"),W(c$1.rapidkitCore,"RapidKit Core"),console.log(m.bold(`
|
|
79
|
-
\u{1F4E6} Project (1):`)),
|
|
80
|
-
\u26A0\uFE0F Doctor verdict: ${
|
|
81
|
-
\u2705 All checks passed! Project is healthy.`));return Ze(c$1.healthScore,{profile:t.name})}else {let r=await Ht(),c=r.python,l=r.poetry,p=r.pipx,
|
|
82
|
-
`)),W(c,"Python"),W(l,"Poetry"),W(p,"pipx"),W(
|
|
79
|
+
\u{1F4E6} Project (1):`)),zn(c$1.project,c$1.rapidkitCore);let k=[c$1.python,c$1.rapidkitCore].some(b=>b.status==="error"),g=te(c$1.project),h=g.blockingFindings,w=g.advisoryFindings;if(k||h>0||w>0)if(console.log(m.bold.yellow(`
|
|
80
|
+
\u26A0\uFE0F Doctor verdict: ${g.verdict} \xB7 ${h} blocking finding(s) \xB7 ${w} advisory finding(s)`)),k&&console.log(m.bold.red("\u274C System requirements not met")),e.plan){let b=c$1.workspacePath??r,D=c$1.workspacePath&&d.resolve(c$1.workspacePath)!==d.resolve(r)?[r]:[];await fe([c$1.project],false,{planOnly:true,json:e.json,policyProfile:t.name,artifactRoot:b,artifactMirrorRoots:D,historyScope:"project"});}else if(e.fix||e.apply){let b=c$1.workspacePath??r,D=c$1.workspacePath&&d.resolve(c$1.workspacePath)!==d.resolve(r)?[r]:[];await fe([c$1.project],true,{skipConfirmation:e.apply===true,policyProfile:t.name,artifactRoot:b,artifactMirrorRoots:D,historyScope:"project"});}else h>0&&await fe([c$1.project],false);else console.log(m.bold.green(`
|
|
81
|
+
\u2705 All checks passed! Project is healthy.`));return Ze(c$1.healthScore,{profile:t.name})}else {let r=await Ht(),c=r.python,l=r.poetry,p=r.pipx,y=r.go,v=r.rapidkitCore,j=[c,l,p,y,v],k=qt(j,[]),g=[c,v].filter(w=>w.status==="error").length;if(e.json){let w={contract:$e(),policyProfile:t,scope:"system",status:g>0?"error":"ok",generatedAt:new Date().toISOString(),healthScore:k,system:{python:c,poetry:l,pipx:p,go:y,rapidkitCore:v},summary:{totalChecks:j.length,errors:g,warnings:j.filter(b=>b.status==="warn").length,recommendedScopes:["workspace","project"]},nextActions:["npx workspai doctor workspace --json","npx workspai doctor project --json"]};return e.quiet||console.log(JSON.stringify(w,null,2)),(e.strict||e.ci)&&g>0?1:0}return console.log(m.bold(`System Tools:
|
|
82
|
+
`)),W(c,"Python"),W(l,"Poetry"),W(p,"pipx"),W(y,"Go"),W(v,"RapidKit Core"),[c,v].some(w=>w.status==="error")?(console.log(m.bold.red(`
|
|
83
83
|
\u274C Some required tools are missing`)),(e.fix||e.apply)&&console.log(m.gray(`
|
|
84
84
|
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "workspai doctor workspace --fix"`)),console.log(m.gray(`
|
|
85
85
|
Tip: Run "workspai doctor workspace" for workspace-wide checks, or "workspai doctor project" for the current project`))):(console.log(m.bold.green(`
|
|
86
86
|
\u2705 All required tools are installed!`)),(e.fix||e.apply)&&console.log(m.gray(`
|
|
87
87
|
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "workspai doctor workspace --fix"`)),console.log(m.gray(`
|
|
88
|
-
Tip: Run "workspai doctor workspace" for workspace-wide checks, or "workspai doctor project" for the current project`))),console.log(""),(e.strict||e.ci)&&
|
|
88
|
+
Tip: Run "workspai doctor workspace" for workspace-wide checks, or "workspai doctor project" for the current project`))),console.log(""),(e.strict||e.ci)&&g>0?1:0}}export{_t as a,mt as b,yt as c,Ie as d,wr as e,be as f,jr as g,xr as h,Cr as i,Pr as j,Dr as k,Rr as l,Sr as m,Er as n,Ze as o,Qn as p,Ys as q};
|