rapidkit 0.27.3 → 0.27.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -126,10 +126,44 @@ npx rapidkit doctor workspace [--fix]
126
126
  npx rapidkit doctor project [--fix]
127
127
  npx rapidkit workspace list # Display all workspaces created on this system
128
128
  npx rapidkit workspace share [--output <file>] [--include-paths] [--no-doctor]
129
+ npx rapidkit import <path|git-url> [--workspace <path>] [--name <project-name>] [--git] [--json]
129
130
  npx rapidkit workspace init # Full-init alias (same behavior as root init/workspace run init at workspace root)
130
131
  npx rapidkit workspace run <init|test|build|start> [--affected] [--blast-radius] [--since <ref>] [--parallel] [--max-workers <n>] [--strict] [--json]
131
132
  ```
132
133
 
134
+ ### Project import into workspace
135
+
136
+ Use `import` to bring an existing backend project (local folder or git repository) into a RapidKit workspace.
137
+
138
+ ```bash
139
+ # Local folder import
140
+ npx rapidkit import ../orders-api
141
+
142
+ # Git import
143
+ npx rapidkit import https://github.com/acme/orders-api.git --git
144
+
145
+ # Explicit workspace and custom target name
146
+ npx rapidkit import ../orders-api --workspace ./my-workspace --name orders-api
147
+
148
+ # Machine-readable output
149
+ npx rapidkit import ../orders-api --json
150
+ ```
151
+
152
+ Import behavior:
153
+
154
+ - Local folders are copied; git sources are cloned with shallow history.
155
+ - If you run import outside any workspace and do not pass `--workspace`, RapidKit auto-creates/reuses the default workspace at `~/Workspai/rapidkits/default-workspace`.
156
+ - CLI cannot change your parent shell directory; instead it prints a next-step `cd ...` hint (and returns `suggestedCdCommand` in JSON mode).
157
+ - If workspace sync fails after import, RapidKit rolls back imported files and registry entries before returning an error.
158
+
159
+ JSON output (`--json`) includes:
160
+
161
+ - `workspacePath`
162
+ - `workspaceResolution` (`explicit` | `nearest` | `default-auto`)
163
+ - `defaultWorkspaceCreated`
164
+ - `suggestedCdCommand`
165
+ - `importedProject` (`name`, `path`, `stack`, `confidence`, `source`)
166
+
133
167
  ### Workspace collaboration bundle
134
168
 
135
169
  Use `workspace share` to export a portable JSON snapshot for team handoff,
@@ -163,6 +197,7 @@ RapidKit keeps the wrapper boundary explicit so users know which layer owns each
163
197
  | `init` | Wrapper orchestrated | Project init in project dirs; full-init alias at workspace root |
164
198
  | `dev`, `test`, `build`, `start` | Runtime aware | Delegates to the active project/runtime when available |
165
199
  | `readiness` | Wrapper release gate | Generates release-readiness evidence (`--json` for CI, `--strict` for fail-fast) |
200
+ | `import` | Workspace ingestion | Imports local folders or git backends with rollback-safe sync behavior |
166
201
  | `doctor` | Wrapper system check | Checks host prerequisites by default |
167
202
  | `doctor workspace` | Workspace health | Full workspace scan with project-level details and fixes |
168
203
  | `doctor project` | Project health | Current project (or nearest parent) diagnostics with project evidence and scoped fixes |
@@ -185,6 +220,8 @@ Use `npx rapidkit readiness` when you need machine-readable release evidence or
185
220
  `npx rapidkit doctor workspace --json` includes project-level runtime/profile metadata used by extension and AI tooling:
186
221
 
187
222
  - `framework`
223
+ - `frameworkKey`
224
+ - `importStack`
188
225
  - `runtimeFamily`
189
226
  - `projectKind`
190
227
  - `supportTier`
@@ -204,11 +241,25 @@ Use `npx rapidkit readiness` when you need machine-readable release evidence or
204
241
 
205
242
  - `scope` (`project`)
206
243
  - `contract` (doctor evidence contract + scoring policy version)
207
- - `project` (framework/runtime metadata, issues, fix commands, probes)
244
+ - `project` (framework/runtime metadata, canonical `frameworkKey` and `importStack`, issues, fix commands, probes)
208
245
  - `summary.scopeProvenance`
209
246
  - `driftDelta`
210
247
  - `scoreBreakdown`
211
248
 
249
+ ### Doctor evidence schema compatibility
250
+
251
+ Doctor persisted evidence now carries explicit schema tags:
252
+
253
+ - Workspace evidence: `schemaVersion = doctor-workspace-evidence-v1`, `evidenceType = workspace`
254
+ - Project evidence: `schemaVersion = doctor-project-evidence-v1`, `evidenceType = project`
255
+ - Workspace scan cache: `schemaVersion = doctor-workspace-cache-v1`
256
+
257
+ Compatibility policy for automation consumers:
258
+
259
+ - Legacy doctor evidence without `schemaVersion` is still accepted.
260
+ - Unknown or incompatible doctor evidence schema versions are treated as invalid evidence (safe fallback, no crash).
261
+ - `readiness` and `workspace share` use the same compatibility validation path, so behavior is consistent across CLI surfaces.
262
+
212
263
  ### Project lifecycle
213
264
 
214
265
  ```bash
@@ -0,0 +1 @@
1
+ var c="doctor-workspace-evidence-v1",i="doctor-project-evidence-v1";function s(r){return !r||typeof r!="object"||Array.isArray(r)?null:r}function p(r,n){let t=s(r);if(!t)return false;let e=t.schemaVersion,o=t.evidenceType;return !(typeof e=="string"&&(e!==c&&e!==i||n==="workspace"&&e!==c||n==="project"&&e!==i)||typeof o=="string"&&(o!=="workspace"&&o!=="project"||n&&o!==n))}export{c as a,i as b,p as c};
@@ -0,0 +1,4 @@
1
+ import a from'fs';import o from'path';var c={fastapi:{key:"fastapi",runtime:"python",displayName:"FastAPI",supportTier:"first-class",importStack:"fastapi",aliases:["fastapi"],kitPrefixes:["fastapi"]},django:{key:"django",runtime:"python",displayName:"Django",supportTier:"extended",importStack:"django",aliases:["django"]},flask:{key:"flask",runtime:"python",displayName:"Flask",supportTier:"extended",importStack:"flask",aliases:["flask"]},python:{key:"python",runtime:"python",displayName:"Python",supportTier:"observed",importStack:"unknown",aliases:["python"]},nestjs:{key:"nestjs",runtime:"node",displayName:"NestJS",supportTier:"first-class",importStack:"nestjs",aliases:["nestjs","nest"],kitPrefixes:["nestjs"]},express:{key:"express",runtime:"node",displayName:"Express",supportTier:"extended",importStack:"express",aliases:["express"]},fastify:{key:"fastify",runtime:"node",displayName:"Fastify",supportTier:"extended",importStack:"unknown",aliases:["fastify"]},koa:{key:"koa",runtime:"node",displayName:"Koa",supportTier:"extended",importStack:"koa",aliases:["koa"]},node:{key:"node",runtime:"node",displayName:"Node.js",supportTier:"observed",importStack:"unknown",aliases:["node","nodejs","typescript","javascript"]},gofiber:{key:"gofiber",runtime:"go",displayName:"Go/Fiber",supportTier:"first-class",importStack:"go",aliases:["gofiber","fiber","go-fiber","go/fiber"],kitPrefixes:["gofiber"]},gogin:{key:"gogin",runtime:"go",displayName:"Go/Gin",supportTier:"first-class",importStack:"go",aliases:["gogin","gin","go-gin","go/gin"],kitPrefixes:["gogin"]},echo:{key:"echo",runtime:"go",displayName:"Echo",supportTier:"extended",importStack:"go",aliases:["echo"]},go:{key:"go",runtime:"go",displayName:"Go",supportTier:"observed",importStack:"go",aliases:["go","golang"],kitPrefixes:["go"]},springboot:{key:"springboot",runtime:"java",displayName:"Spring Boot",supportTier:"first-class",importStack:"springboot",aliases:["springboot","spring","spring-boot"],kitPrefixes:["springboot"]},java:{key:"java",runtime:"java",displayName:"Java",supportTier:"observed",importStack:"unknown",aliases:["java"]},laravel:{key:"laravel",runtime:"php",displayName:"Laravel",supportTier:"extended",importStack:"unknown",aliases:["laravel"]},symfony:{key:"symfony",runtime:"php",displayName:"Symfony",supportTier:"extended",importStack:"unknown",aliases:["symfony"]},php:{key:"php",runtime:"php",displayName:"PHP",supportTier:"observed",importStack:"unknown",aliases:["php"]},rails:{key:"rails",runtime:"ruby",displayName:"Ruby on Rails",supportTier:"extended",importStack:"rails",aliases:["rails","ruby-on-rails","ruby on rails"]},sinatra:{key:"sinatra",runtime:"ruby",displayName:"Sinatra",supportTier:"extended",importStack:"unknown",aliases:["sinatra"]},ruby:{key:"ruby",runtime:"ruby",displayName:"Ruby",supportTier:"observed",importStack:"unknown",aliases:["ruby"]},dotnet:{key:"dotnet",runtime:"dotnet",displayName:"ASP.NET",supportTier:"extended",importStack:"dotnet",aliases:["dotnet","asp.net","aspnet","asp.net core","csharp","c#"]},actix:{key:"actix",runtime:"rust",displayName:"Actix-web",supportTier:"extended",importStack:"unknown",aliases:["actix","actix-web"]},axum:{key:"axum",runtime:"rust",displayName:"Axum",supportTier:"extended",importStack:"unknown",aliases:["axum"]},rocket:{key:"rocket",runtime:"rust",displayName:"Rocket",supportTier:"extended",importStack:"unknown",aliases:["rocket"]},rust:{key:"rust",runtime:"rust",displayName:"Rust",supportTier:"first-class",importStack:"unknown",aliases:["rust"]},phoenix:{key:"phoenix",runtime:"elixir",displayName:"Phoenix",supportTier:"first-class",importStack:"unknown",aliases:["phoenix"]},elixir:{key:"elixir",runtime:"elixir",displayName:"Elixir",supportTier:"extended",importStack:"unknown",aliases:["elixir"]},clojure:{key:"clojure",runtime:"clojure",displayName:"Clojure",supportTier:"extended",importStack:"unknown",aliases:["clojure"]},scala:{key:"scala",runtime:"scala",displayName:"Scala",supportTier:"extended",importStack:"unknown",aliases:["scala"]},kotlin:{key:"kotlin",runtime:"kotlin",displayName:"Kotlin",supportTier:"extended",importStack:"unknown",aliases:["kotlin"]},deno:{key:"deno",runtime:"deno",displayName:"Deno",supportTier:"extended",importStack:"unknown",aliases:["deno"]},bun:{key:"bun",runtime:"bun",displayName:"Bun",supportTier:"extended",importStack:"unknown",aliases:["bun"]},unknown:{key:"unknown",runtime:"unknown",displayName:"Unknown",supportTier:"observed",importStack:"unknown",aliases:["unknown"]}},l=new Map;for(let e of Object.values(c))for(let n of e.aliases)l.set(n,e.key);function i(e,n,t){let r=c[e]??c.unknown;return {key:r.key,runtime:r.runtime,displayName:r.displayName,supportTier:r.supportTier,importStack:r.importStack,confidence:n,source:t}}function p(e){return e.trim().toLowerCase().replace(/[_\s]+/g,"-")}function u(e){try{return a.existsSync(e)?a.readFileSync(e,"utf8").toLowerCase():""}catch{return ""}}function y(e){try{return a.existsSync(e)?JSON.parse(a.readFileSync(e,"utf8")):null}catch{return null}}function f(e,n){if(n<0||!a.existsSync(e))return [];let t=[],r=[];try{r=a.readdirSync(e,{withFileTypes:true});}catch{return []}for(let s of r){let d=o.join(e,s.name);s.isDirectory()?t.push(...f(d,n-1)):t.push(d);}return t}function k(e,n,t=2){return f(e,t).some(r=>r.toLowerCase().endsWith(n.toLowerCase()))}function g(e){let n=p(e??"");if(!n)return "unknown";for(let t of Object.values(c))if(t.kitPrefixes?.some(r=>n.startsWith(r)))return t.key;return "unknown"}function m(e){return e?l.get(p(e))??"unknown":"unknown"}function D(e){return m(e)}function E(e){let n=m(e);return n!=="unknown"?c[n].runtime:"unknown"}function w(e){let n=g(e.kitName);if(n!=="unknown")return i(n,"high","kit");let t=m(e.framework);if(t!=="unknown")return i(t,"high","framework");let r=m(e.runtime);return r!=="unknown"?i(r,"medium","runtime"):i("unknown","low","unknown")}function x(e){let n=y(o.join(e,"package.json"));if(!n)return i("unknown","low","unknown");let t={...n.dependencies??{},...n.devDependencies??{}},r=n.scripts??{},s=Object.values(r).filter(d=>typeof d=="string").join(" ").toLowerCase();return t["@nestjs/core"]||s.includes("nest start")?i("nestjs","high","manifest"):t.express?i("express","high","manifest"):t.fastify?i("fastify","high","manifest"):t.koa?i("koa","high","manifest"):i("node","medium","marker")}function b(e){let n=[u(o.join(e,"pyproject.toml")),u(o.join(e,"requirements.txt")),u(o.join(e,"requirements.in"))].join(`
2
+ `);return n.includes("fastapi")?i("fastapi","high","manifest"):n.includes("django")?i("django","high","manifest"):n.includes("flask")?i("flask","high","manifest"):n.trim()?i("python","medium","marker"):i("unknown","low","unknown")}function S(e){let n=[u(o.join(e,"go.mod")),u(o.join(e,"main.go"))].join(`
3
+ `);return n.includes("github.com/gofiber/fiber")?i("gofiber","high","manifest"):n.includes("github.com/gin-gonic/gin")?i("gogin","high","manifest"):n.includes("github.com/labstack/echo")?i("echo","high","manifest"):n.trim()?i("go","medium","marker"):i("unknown","low","unknown")}function h(e){let n=[u(o.join(e,"pom.xml")),u(o.join(e,"build.gradle")),u(o.join(e,"build.gradle.kts"))].join(`
4
+ `);return n.includes("spring-boot")||n.includes("org.springframework")?i("springboot","high","manifest"):n.trim()?i("java","medium","marker"):i("unknown","low","unknown")}function j(e){let n=u(o.join(e,"composer.json"));return n.includes("laravel/framework")?i("laravel","high","manifest"):n.includes("symfony/")?i("symfony","high","manifest"):n.trim()?i("php","medium","marker"):i("unknown","low","unknown")}function B(e){let n=u(o.join(e,"Gemfile"));return n.includes("gem 'rails'")||n.includes('gem "rails"')?i("rails","high","manifest"):n.includes("gem 'sinatra'")||n.includes('gem "sinatra"')?i("sinatra","high","manifest"):n.trim()?i("ruby","medium","marker"):i("unknown","low","unknown")}function N(e){let n=u(o.join(e,"Cargo.toml"));return n.includes("actix-web")?i("actix","high","manifest"):n.includes("axum")?i("axum","high","manifest"):n.includes("rocket")?i("rocket","high","manifest"):n.trim()?i("rust","medium","marker"):i("unknown","low","unknown")}function F(e){let n=u(o.join(e,"mix.exs"));return n.includes("phoenix")?i("phoenix","high","manifest"):n.trim()?i("elixir","medium","marker"):i("unknown","low","unknown")}function T(e){let n=[],t=r=>{n.includes(r)||n.push(r);};return a.existsSync(o.join(e,"go.mod"))&&t("go"),a.existsSync(o.join(e,"Cargo.toml"))&&t("rust"),(a.existsSync(o.join(e,"pom.xml"))||a.existsSync(o.join(e,"build.gradle"))||a.existsSync(o.join(e,"build.gradle.kts")))&&t("java"),a.existsSync(o.join(e,"mix.exs"))&&t("elixir"),a.existsSync(o.join(e,"composer.json"))&&t("php"),(k(e,".csproj")||k(e,".sln"))&&t("dotnet"),a.existsSync(o.join(e,"package.json"))&&t("node"),a.existsSync(o.join(e,"Gemfile"))&&t("ruby"),(a.existsSync(o.join(e,"pyproject.toml"))||a.existsSync(o.join(e,"setup.py"))||a.existsSync(o.join(e,"requirements.txt"))||a.existsSync(o.join(e,"requirements.in")))&&t("python"),(a.existsSync(o.join(e,"deps.edn"))||a.existsSync(o.join(e,"project.clj")))&&t("clojure"),a.existsSync(o.join(e,"build.sbt"))&&t("scala"),(a.existsSync(o.join(e,"deno.json"))||a.existsSync(o.join(e,"deno.jsonc")))&&t("deno"),(a.existsSync(o.join(e,"bun.lockb"))||a.existsSync(o.join(e,"bun.lock")))&&t("bun"),(a.existsSync(o.join(e,"settings.gradle.kts"))||k(o.join(e,"src"),".kt",3))&&t("kotlin"),n}function L(e,n){let t=w({framework:typeof n?.framework=="string"?n.framework:void 0,runtime:typeof n?.runtime=="string"?n.runtime:void 0,kitName:typeof n?.kit_name=="string"?n.kit_name:typeof n?.kit=="string"?n.kit:void 0});if(t.key!=="unknown")return t;let r=T(e);if(r.includes("node")){let s=x(e);if(s.key!=="unknown")return s}if(r.includes("python")){let s=b(e);if(s.key!=="unknown")return s}if(r.includes("go")){let s=S(e);if(s.key!=="unknown")return s}if(r.includes("java")){let s=h(e);if(s.key!=="unknown")return s}if(r.includes("php")){let s=j(e);if(s.key!=="unknown")return s}if(r.includes("ruby")){let s=B(e);if(s.key!=="unknown")return s}if(r.includes("rust")){let s=N(e);if(s.key!=="unknown")return s}if(r.includes("elixir")){let s=F(e);if(s.key!=="unknown")return s}return r.includes("dotnet")?i("dotnet","medium","marker"):r.includes("clojure")?i("clojure","medium","marker"):r.includes("scala")?i("scala","medium","marker"):r.includes("kotlin")?i("kotlin","medium","marker"):r.includes("deno")?i("deno","high","marker"):r.includes("bun")?i("bun","high","marker"):r.length>0?i(m(r[0]),"medium","runtime"):i("unknown","low","unknown")}export{D as a,E as b,w as c,T as d,L as e};
@@ -103,7 +103,7 @@ npx rapidkit dev
103
103
  cd <project-name>
104
104
  npx rapidkit init
105
105
  npx rapidkit dev
106
- `)+"```\n","utf-8"),!e){f.start("Initializing git repository");try{await execa("git",["init"],{cwd:i$1}),await execa("git",["add","."],{cwd:i$1}),await execa("git",["commit","-m","Initial commit: RapidKit workspace"],{cwd:i$1}),f.succeed("Git repository initialized");}catch{f.warn("Could not initialize git repository");}}try{let{registerWorkspace:k}=await import('./workspace-7JHX7L3E.js');await k(i$1,c);}catch{}if(console.log(o.green(`
106
+ `)+"```\n","utf-8"),!e){f.start("Initializing git repository");try{await execa("git",["init"],{cwd:i$1}),await execa("git",["add","."],{cwd:i$1}),await execa("git",["commit","-m","Initial commit: RapidKit workspace"],{cwd:i$1}),f.succeed("Git repository initialized");}catch{f.warn("Could not initialize git repository");}}try{let{registerWorkspace:k}=await import('./workspace-HEHMJ3QC.js');await k(i$1,c);}catch{}if(console.log(o.green(`
107
107
  \u2728 Workspace created!
108
108
  `)),console.log(o.cyan("\u{1F4C2} Location:"),o.white(i$1)),console.log(o.cyan(`
109
109
  \u{1F680} Get started:
@@ -118,7 +118,7 @@ npx rapidkit dev
118
118
  `)),console.log(o.cyan(`\u{1F4A1} How to install Python:
119
119
  `)),console.log(o.white(" Ubuntu / Debian: sudo apt install python3.10")),console.log(o.white(" macOS (Homebrew): brew install python@3.10")),console.log(o.white(` Windows: https://python.org/downloads
120
120
  `)),console.log(o.gray(` After installing Python, run: npx rapidkit ${c}
121
- `)),process.exit(1));}a$1.step(1,3,"Setting up RapidKit environment");let P=z("Creating directory").start();try{await v.ensureDir(i$1),P.succeed("Directory created"),P.start("Detecting Python version");let f=null,R=await kt(x.pythonVersion);if(R)f=await pt(R),f?(a$1.info(` Detected Python ${f}`),P.succeed(`Python ${f} detected`)):P.warn("Could not detect exact Python version");else {let k=C();f=await pt(k),f?P.succeed(`Python ${f} detected`):P.warn("Could not detect Python version, proceeding with defaults");}if(x.installMethod==="poetry"&&!await wt()&&(P.warn("Poetry not found \u2014 auto-fallback to pip + venv"),x.installMethod="venv"),await et(i$1,c,x.installMethod,f||void 0),f&&await jt(i$1,f),await nt(i$1,c,x.installMethod,f||x.pythonVersion,p||h),await H(i$1),await ot(i$1,c),x.installMethod==="poetry")try{await bt(i$1,x.pythonVersion,P,r,g,u);}catch(k){let _=k?.details||k?.message||String(k);if(_.includes("pyenv")||_.includes("exit status 127")||_.includes("returned non-zero exit status 127")){P.warn("Poetry encountered Python discovery issues, trying venv method"),a$1.debug(`Poetry error (attempting venv fallback): ${_}`);try{await rt(i$1,x.pythonVersion,P,r,g),x.installMethod="venv";}catch(at){throw at}}else throw k}else x.installMethod==="venv"?await rt(i$1,x.pythonVersion,P,r,g):await Pt(i$1,P,r,g,u);if(await vt(i$1,x.installMethod),await xt(i$1,x.installMethod),P.succeed("RapidKit environment ready!"),!n.skipGit){P.start("Initializing git repository");try{await execa("git",["init"],{cwd:i$1}),await execa("git",["add","."],{cwd:i$1}),await execa("git",["commit","-m","Initial commit: RapidKit environment"],{cwd:i$1}),P.succeed("Git repository initialized");}catch{P.warn("Could not initialize git repository");}}try{let{registerWorkspace:k}=await import('./workspace-7JHX7L3E.js');await k(i$1,c);}catch{console.warn(o.gray("Note: Could not register workspace in shared registry"));}if(console.log(o.green(`
121
+ `)),process.exit(1));}a$1.step(1,3,"Setting up RapidKit environment");let P=z("Creating directory").start();try{await v.ensureDir(i$1),P.succeed("Directory created"),P.start("Detecting Python version");let f=null,R=await kt(x.pythonVersion);if(R)f=await pt(R),f?(a$1.info(` Detected Python ${f}`),P.succeed(`Python ${f} detected`)):P.warn("Could not detect exact Python version");else {let k=C();f=await pt(k),f?P.succeed(`Python ${f} detected`):P.warn("Could not detect Python version, proceeding with defaults");}if(x.installMethod==="poetry"&&!await wt()&&(P.warn("Poetry not found \u2014 auto-fallback to pip + venv"),x.installMethod="venv"),await et(i$1,c,x.installMethod,f||void 0),f&&await jt(i$1,f),await nt(i$1,c,x.installMethod,f||x.pythonVersion,p||h),await H(i$1),await ot(i$1,c),x.installMethod==="poetry")try{await bt(i$1,x.pythonVersion,P,r,g,u);}catch(k){let _=k?.details||k?.message||String(k);if(_.includes("pyenv")||_.includes("exit status 127")||_.includes("returned non-zero exit status 127")){P.warn("Poetry encountered Python discovery issues, trying venv method"),a$1.debug(`Poetry error (attempting venv fallback): ${_}`);try{await rt(i$1,x.pythonVersion,P,r,g),x.installMethod="venv";}catch(at){throw at}}else throw k}else x.installMethod==="venv"?await rt(i$1,x.pythonVersion,P,r,g):await Pt(i$1,P,r,g,u);if(await vt(i$1,x.installMethod),await xt(i$1,x.installMethod),P.succeed("RapidKit environment ready!"),!n.skipGit){P.start("Initializing git repository");try{await execa("git",["init"],{cwd:i$1}),await execa("git",["add","."],{cwd:i$1}),await execa("git",["commit","-m","Initial commit: RapidKit environment"],{cwd:i$1}),P.succeed("Git repository initialized");}catch{P.warn("Could not initialize git repository");}}try{let{registerWorkspace:k}=await import('./workspace-HEHMJ3QC.js');await k(i$1,c);}catch{console.warn(o.gray("Note: Could not register workspace in shared registry"));}if(console.log(o.green(`
122
122
  \u2728 RapidKit environment created successfully!
123
123
  `)),console.log(o.cyan("\u{1F4C2} Location:"),o.white(i$1)),console.log(o.cyan(`\u{1F680} Get started:
124
124
  `)),console.log(o.white(` cd ${c}`)),x.installMethod==="poetry"){let k="source $(poetry env info --path)/bin/activate";try{D();let{stdout:_}=await execa("poetry",["--version"]),M=_.match(/Poetry.*?(\d+)\.(\d+)/);M&&(parseInt(M[1])>=2?k="source $(poetry env info --path)/bin/activate":k="poetry shell");}catch{}console.log(o.white(` ${k} # Or: poetry run rapidkit`)),console.log(o.white(" rapidkit create # Interactive mode")),console.log(o.white(" cd <project-name>")),console.log(o.white(" rapidkit init")),console.log(o.white(" rapidkit dev"));}else x.installMethod==="venv"?(console.log(o.white(" source .venv/bin/activate # On Windows: .venv\\Scripts\\activate")),console.log(o.white(" rapidkit create # Interactive mode")),console.log(o.white(" cd <project-name>")),console.log(o.white(" rapidkit init")),console.log(o.white(" rapidkit dev"))):(console.log(o.white(" rapidkit create # Interactive mode")),console.log(o.white(" cd <project-name>")),console.log(o.white(" rapidkit init")),console.log(o.white(" rapidkit dev")));console.log(o.white(`
@@ -159,7 +159,7 @@ Possible solutions:
159
159
  1. Check your internet connection
160
160
  2. Try installing manually: cd ${m.basename(t)} && ${f(".venv")} -m pip install rapidkit-core
161
161
  3. Use Poetry instead: npx rapidkit ${m.basename(t)} --install-method=poetry`))}}e.succeed("RapidKit installed in project virtualenv");try{let{checkRapidkitCoreAvailable:y}=await import('./pythonRapidkitExec-K2SFGAYJ.js');if(!await y()&&!r){e.start("Checking optional global pipx installation");let c=await q(e,true);try{e.start("Installing RapidKit globally with pipx for CLI access"),await F(c,["install","rapidkit-core"]),e.succeed("RapidKit installed globally");}catch(i){e.warn("Could not install globally (non-fatal, project virtualenv has RapidKit)"),a$1.debug(`pipx install failed: ${i}`);}}}catch(y){e.succeed("Skipped optional global pipx installation"),a$1.debug(`Global install check skipped: ${y}`);}}async function Pt(t,n,e,r,s=false){let d=await q(n,s);if(n.start("Installing RapidKit globally with pipx"),e){let u=d$2(r||{});if(!u)throw new k("Test mode installation",new Error("No local RapidKit path configured. Set RAPIDKIT_DEV_PATH environment variable."));a$1.debug(`Installing from local path: ${u}`),n.text="Installing RapidKit from local path (test mode)",await F(d,["install","-e",u]);}else {n.text="Installing RapidKit from PyPI";try{await F(d,["install","rapidkit-core"]);}catch{throw new l}}n.succeed("RapidKit installed globally"),await v.outputFile(m.join(t,".rapidkit-global"),`RapidKit installed globally with pipx
162
- `,"utf-8");}async function ne(t,n){let{skipGit:e=false,testMode:r=false,userConfig:s={},yes:d=false,installMethod:u,pythonVersion:g="3.10"}=n||{},y=u||s.defaultInstallMethod||await(async()=>{try{return await execa("poetry",["--version"],{timeout:3e3}),"poetry"}catch{return a$1.warn("Poetry not found \u2014 auto-selecting venv. Pass --install-method poetry to override."),"venv"}})(),h=y==="poetry"&&!await wt()?"venv":y;await et(t,m.basename(t),h),await H(t),await nt(t,m.basename(t),h,g,n?.profile);let c=z("Registering workspace").start();try{h==="poetry"?(await ot(t,m.basename(t)),await bt(t,g,c,r,s,d)):h==="venv"?await rt(t,g,c,r,s):await Pt(t,c,r,s,d),await vt(t,h),await xt(t,h),c.succeed("Workspace registered");try{let{registerWorkspace:i}=await import('./workspace-7JHX7L3E.js');await i(t,m.basename(t));}catch{}if(!e){c.start("Initializing git repository");try{await execa("git",["init"],{cwd:t}),await execa("git",["add","."],{cwd:t}),await execa("git",["commit","-m","Initial commit: RapidKit workspace"],{cwd:t}),c.succeed("Git repository initialized");}catch{c.warn("Could not initialize git repository");}}}catch(i){throw c.fail("Failed to register workspace"),i}}async function xt(t,n){let e=n==="poetry"?`source $(poetry env info --path)/bin/activate
162
+ `,"utf-8");}async function ne(t,n){let{skipGit:e=false,testMode:r=false,userConfig:s={},yes:d=false,installMethod:u,pythonVersion:g="3.10"}=n||{},y=u||s.defaultInstallMethod||await(async()=>{try{return await execa("poetry",["--version"],{timeout:3e3}),"poetry"}catch{return a$1.warn("Poetry not found \u2014 auto-selecting venv. Pass --install-method poetry to override."),"venv"}})(),h=y==="poetry"&&!await wt()?"venv":y;await et(t,m.basename(t),h),await H(t),await nt(t,m.basename(t),h,g,n?.profile);let c=z("Registering workspace").start();try{h==="poetry"?(await ot(t,m.basename(t)),await bt(t,g,c,r,s,d)):h==="venv"?await rt(t,g,c,r,s):await Pt(t,c,r,s,d),await vt(t,h),await xt(t,h),c.succeed("Workspace registered");try{let{registerWorkspace:i}=await import('./workspace-HEHMJ3QC.js');await i(t,m.basename(t));}catch{}if(!e){c.start("Initializing git repository");try{await execa("git",["init"],{cwd:t}),await execa("git",["add","."],{cwd:t}),await execa("git",["commit","-m","Initial commit: RapidKit workspace"],{cwd:t}),c.succeed("Git repository initialized");}catch{c.warn("Could not initialize git repository");}}}catch(i){throw c.fail("Failed to register workspace"),i}}async function xt(t,n){let e=n==="poetry"?`source $(poetry env info --path)/bin/activate
163
163
  # Or simply use: poetry run rapidkit <command>`:n==="venv"?"source .venv/bin/activate # On Windows: .venv\\Scripts\\activate":"N/A (globally installed)",r=n==="poetry"?`# No activation needed (recommended):
164
164
  ./rapidkit --help
165
165
  # or:
@@ -0,0 +1,47 @@
1
+ import {e}from'./chunk-TYC54P7X.js';import {c,a as a$1,b as b$1}from'./chunk-NFUXULIF.js';import {b,f,d,a as a$2,k,g,i as i$1}from'./chunk-Z5LKRG57.js';import {a}from'./chunk-VM2TOHNX.js';import l from'chalk';import {execa}from'execa';import i from'fs-extra';import o from'path';import Qe from'inquirer';function Xe(e){return [...new Set(e.filter(s=>s&&s.trim().length>0))]}function Ye(){let e=k().map(t=>o.join(t,a$2()?"poetry.exe":"poetry")),s=a$2()?[o.join(process.env.APPDATA||"","Python","Scripts","poetry.exe"),o.join(process.env.USERPROFILE||"","AppData","Roaming","Python","Scripts","poetry.exe")]:[],a=a$2()?[]:["/usr/local/bin/poetry","/usr/bin/poetry"];return Xe([...e,...s,...a])}function Ze(e){let s=k().map(u=>({location:"Global (user-local)",path:o.join(u,a$2()?"rapidkit.exe":"rapidkit")})),a=[{location:"Global (pipx)",path:o.join(e,".local","bin","rapidkit")},{location:"Global (pipx)",path:o.join(e,"AppData","Roaming","Python","Scripts","rapidkit.exe")},{location:"Global (pyenv)",path:o.join(e,".pyenv","shims","rapidkit")},{location:"Global (system)",path:"/usr/local/bin/rapidkit"},{location:"Global (system)",path:"/usr/bin/rapidkit"}],t=g(o.join(process.cwd(),".venv")),c=i$1(process.cwd()),n=[{location:"Workspace (.venv)",path:t},...c.map(u=>({location:"Workspace (launcher)",path:u}))],r=[...s,...a,...n],d=new Set;return r.filter(u=>d.has(u.path)?false:(d.add(u.path),true))}function et(e){let s=new Map([["Workspace (.venv)",0],["Global (user-local)",1],["Global (pipx)",2],["Global (pyenv)",3],["Global (system)",4]]);return [...e].sort((a,t)=>{let c=s.get(a.location)??Number.MAX_SAFE_INTEGER,n=s.get(t.location)??Number.MAX_SAFE_INTEGER;return c!==n?c-n:a.path.localeCompare(t.path)})}function Q(e){let s=0,a=e.issues.some(t=>t.toLowerCase().includes("environment file missing"));return e.hasEnvFile===false&&!a&&(s+=1),typeof e.vulnerabilities=="number"&&e.vulnerabilities>0&&(s+=1),s}function ge(e){return e.filter(s=>Q(s)>0).length}function he(e){return e.reduce((s,a)=>s+Q(a),0)}var tt="doctor-project-scan-v2",De="doctor-workspace-cache-v1",st=Object.freeze({version:"doctor-evidence-v1",scoringPolicyVersion:"doctor-score-policy-v1",generatedBy:"rapidkit-npm",deterministicScoreBreakdown:true,scopeModel:"workspace-aggregate-or-project-scoped"});function re(){return {...st}}function ce(e){return !e||e.total<=0?null:Math.round(e.passed/e.total*100)}function Ae(e){return typeof e=="number"?e:Array.isArray(e)?e.length:0}async function Ie(e,s){try{if(!await i.pathExists(e))return null;let a=await i.readJSON(e);return c(a,s)?a:null}catch{return null}}function He(e,s){if(!e?.system)return [];let a=[{id:"python",current:s.python},{id:"poetry",current:s.poetry},{id:"pipx",current:s.pipx},{id:"go",current:s.go},{id:"rapidkitCore",current:s.rapidkitCore}],t=[];for(let c of a){let n=e.system?.[c.id]?.status;!n||n===c.current.status||t.push({id:c.id,from:n,to:c.current.status});}return t}function nt(e,s){let a=new Map;for(let f of s.projects)a.set(f.path||f.name,f.issues.length);if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let t=Array.isArray(e.projects)?e.projects:[],c=new Map;for(let f of t){let y=f.path||f.name;y&&c.set(y,Ae(f.issues));}let n=0,r=0,d=new Set,u=new Set,m=new Set([...Array.from(c.keys()),...Array.from(a.keys())]);for(let f of m){let y=c.get(f)??0,h=a.get(f)??0;h>y?(n+=h-y,d.add(f)):h<y&&(r+=y-h,u.add(f));}let p=ce(e.healthScore),g=ce(s.healthScore);return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:n,resolvedIssueCount:r,netIssueDelta:n-r,scoreDeltaPercent:p===null||g===null?null:g-p,systemStatusChanges:He(e,{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore}),regressedProjects:Array.from(d).sort(),improvedProjects:Array.from(u).sort()}}function ot(e,s){if(!e)return {baselineAvailable:false,newIssueCount:0,resolvedIssueCount:0,netIssueDelta:0,scoreDeltaPercent:null,systemStatusChanges:[],regressedProjects:[],improvedProjects:[]};let a=Ae(e.project?.issues),t=s.project.issues.length,c=Math.max(t-a,0),n=Math.max(a-t,0),r=ce(e.healthScore),d=ce(s.healthScore),u=s.project.path||s.project.name;return {baselineAvailable:true,previousGeneratedAt:e.generatedAt,newIssueCount:c,resolvedIssueCount:n,netIssueDelta:c-n,scoreDeltaPercent:r===null||d===null?null:d-r,systemStatusChanges:He(e,{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore}),regressedProjects:c>0?[u]:[],improvedProjects:n>0?[u]:[]}}function Ne(e){let s=e??[],a=0,t=0;for(let r of s){if(r.scope==="project-scoped"){a+=1;continue}(r.scope==="workspace-aggregate"||r.scope==="host-system")&&(t+=1);}let c=a>0&&t>0?1:0,n=c>0?"mixed":a>0?"scoped":t>0?"aggregated":"unknown";return {scopedCount:a,aggregatedCount:t,mixedCount:c,dominantScope:n}}function E(e,s){return a$2()?`cd "${e}"; ${s}`:`cd ${e} && ${s}`}function V(e){return a$2()?E(e,"Copy-Item .env.example .env"):E(e,"cp .env.example .env")}function it(e){return e==="FastAPI"||e==="NestJS"||e==="Go/Fiber"||e==="Go/Gin"||e==="Spring Boot"||e==="Rust"||e==="Phoenix"?"first-class":e==="Django"||e==="Flask"||e==="Express"||e==="Fastify"||e==="Koa"||e==="Elixir"||e==="Clojure"||e==="Scala"||e==="Kotlin"||e==="Deno"||e==="Bun"||e==="PHP"||e==="Laravel"||e==="Ruby"||e==="Ruby on Rails"||e==="ASP.NET"?"extended":"observed"}function at(e){return e==="Next.js"||e==="Nuxt"||e==="React"||e==="Vue"||e==="Angular"||e==="SvelteKit"?"frontend":e==="Unknown"||e==="Node.js"||e==="Python"?"generic":"backend"}function rt(e){return e==="NestJS"||e==="Next.js"||e==="Nuxt"||e==="React"||e==="Vue"||e==="Angular"||e==="SvelteKit"||e==="Bun"||e==="Express"||e==="Fastify"||e==="Koa"||e==="Node.js"?"node":e==="FastAPI"||e==="Django"||e==="Flask"||e==="Python"?"python":e==="Go/Fiber"||e==="Go/Gin"?"go":e==="Spring Boot"?"java":e==="Rust"?"rust":e==="Elixir"||e==="Phoenix"?"elixir":e==="Clojure"?"clojure":e==="Deno"?"deno":e==="Laravel"||e==="PHP"?"php":e==="Ruby on Rails"||e==="Ruby"?"ruby":e==="ASP.NET"?"dotnet":"unknown"}function ie(e,s,a){e.framework=s,e.frameworkConfidence=a,e.supportTier=it(s),e.projectKind=at(s),e.runtimeFamily=rt(s);}function ct(e){return e==="python"?"python":e==="node"||e==="bun"?"node":e==="go"?"go":e==="java"?"java":e==="rust"?"rust":e==="elixir"?"elixir":e==="clojure"?"clojure":e==="deno"?"deno":e==="php"?"php":e==="ruby"?"ruby":e==="dotnet"?"dotnet":"unknown"}function Me(e){switch(e.key){case "fastapi":return "FastAPI";case "django":return "Django";case "flask":return "Flask";case "python":return "Python";case "nestjs":return "NestJS";case "express":return "Express";case "fastify":return "Fastify";case "koa":return "Koa";case "node":return "Node.js";case "gofiber":return "Go/Fiber";case "gogin":return "Go/Gin";case "echo":return "Echo";case "go":return "Go";case "springboot":return "Spring Boot";case "java":return "Java";case "laravel":return "Laravel";case "php":return "PHP";case "rails":return "Ruby on Rails";case "ruby":return "Ruby";case "dotnet":return "ASP.NET";case "phoenix":return "Phoenix";case "elixir":return "Elixir";case "clojure":return "Clojure";case "scala":return "Scala";case "kotlin":return "Kotlin";case "deno":return "Deno";case "bun":return "Bun";case "actix":case "axum":case "rocket":case "rust":return "Rust";case "sinatra":case "symfony":case "unknown":return "Unknown";default:return "Unknown"}}function lt(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 _(e,s){e.framework=Me(s),e.frameworkKey=s.key,e.importStack=s.importStack,e.frameworkConfidence=s.confidence,e.supportTier=s.supportTier,e.projectKind=lt(s)?"generic":"backend",e.runtimeFamily=ct(s.runtime);}function dt(e){let s=e.dependencies,a=e.scripts??{},t=(e.kitName??"").toLowerCase(),c=r=>!!s[r],n=Object.values(a).filter(r=>typeof r=="string").join(" ").toLowerCase();return c("next")||n.includes("next ")?{framework:"Next.js",confidence:"high"}:c("nuxt")||n.includes("nuxt ")?{framework:"Nuxt",confidence:"high"}:c("@nestjs/core")||t.startsWith("nestjs.")?{framework:"NestJS",confidence:"high"}:c("express")?{framework:"Express",confidence:"high"}:c("fastify")?{framework:"Fastify",confidence:"high"}:c("koa")?{framework:"Koa",confidence:"high"}:c("@angular/core")?{framework:"Angular",confidence:"high"}:c("@sveltejs/kit")||n.includes("svelte-kit")?{framework:"SvelteKit",confidence:"high"}:c("vue")?{framework:"Vue",confidence:"medium"}:c("react")&&c("react-dom")?{framework:"React",confidence:"medium"}:{framework:"Node.js",confidence:"low"}}async function ut(e$1){let s=e(e$1);return s.runtime!=="python"?{framework:"Python",confidence:"low"}:{framework:Me(s),confidence:s.confidence}}async function Ee(e){try{let s=await i.stat(e);return `${o.basename(e)}:${s.isDirectory()?"d":"f"}:${s.size}:${s.mtimeMs}`}catch{return `${o.basename(e)}:missing`}}async function pt(e){try{let s=new Set([".git",".venv","node_modules",".rapidkit","dist","build","coverage","__pycache__"]),a=new Set;await le(e)&&a.add(e);let t=async(c,n)=>{if(n<0)return;let r=await Ge(c);for(let d of r){if(Be(d,s))continue;let u=o.join(c,d);if(await le(u)){a.add(u);continue}n>0&&await t(u,n-1);}};return await t(e,1),a.size===0&&(await Ct(e,3,s)).forEach(n=>a.add(n)),Array.from(a).sort((c,n)=>c.localeCompare(n))}catch{return []}}async function mt(e,s){let a=[o.join(e,".rapidkit-workspace"),o.join(e,".rapidkit","workspace.json"),o.join(e,".rapidkit","policies.yml"),o.join(e,".rapidkit","toolchain.lock"),o.join(e,".rapidkit","cache-config.yml")],t=[".rapidkit/project.json",".rapidkit/context.json",".rapidkit/file-hashes.json","package.json","pyproject.toml","composer.json","Gemfile","Gemfile.lock","go.mod","go.sum","pom.xml","requirements.txt","Dockerfile","Makefile",".env",".env.example","src","modules","tests","test",".venv","node_modules"],c=await Promise.all(a.map(Ee)),n=await Promise.all(s.map(async r=>{let d=await Promise.all(t.map(u=>Ee(o.join(r,u))));return `${r}::${d.join("|")}`}));return [tt,...c,...n].join("||")}async function ft(e,s){try{if(!await i.pathExists(e))return null;let a=await i.readJSON(e);return !a||a.signature!==s||!Array.isArray(a.projects)||typeof a.schemaVersion=="string"&&a.schemaVersion!==De?null:a}catch{return null}}async function gt(e,s){try{await i.ensureDir(o.dirname(e)),await i.writeJSON(e,s,{spaces:2});}catch{}}async function ht(e,s,a){let t=o.join(e,".rapidkit","reports","doctor-last-run.json");try{return await i.ensureDir(o.dirname(t)),await i.writeJSON(t,{schemaVersion:a$1,evidenceType:"workspace",generatedAt:new Date().toISOString(),contract:re(),workspacePath:e,workspaceName:s.workspaceName,projectScanCached:s.projectScanCached??false,projectScanSignature:s.projectScanSignature,cachePath:a,healthScore:s.healthScore,system:{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore,versions:{core:s.coreVersion,npm:s.npmVersion}},projects:s.projects,summary:{totalProjects:s.projects.length,totalIssues:s.projects.reduce((c,n)=>c+n.issues.length,0),projectAdvisoryWarningProjects:ge(s.projects),projectAdvisoryWarnings:he(s.projects),hasSystemErrors:[s.python,s.rapidkitCore].some(c=>c.status==="error"),scopeProvenance:s.scopeProvenance},driftDelta:s.driftDelta,scoreBreakdown:s.scoreBreakdown??[]},{spaces:2}),t}catch{return}}async function ye(){let[e,s,a,t,c]=await Promise.all([yt(),kt(),wt(),vt(),xt()]);return {python:e,poetry:s,pipx:a,go:t,rapidkitCore:c}}async function yt(){let e=d();for(let s of e)try{let{stdout:a}=await execa(s,["--version"],{timeout:3e3}),t=a.match(/Python (\d+\.\d+\.\d+)/);if(t){let c=t[1],[n,r]=c.split(".").map(Number);return n<3||n===3&&r<10?{status:"warn",message:`Python ${c} (requires 3.10+)`,details:`${s} found but version is below minimum requirement`}:{status:"ok",message:`Python ${c}`,details:`Using ${s}`}}}catch{continue}return {status:"error",message:"Python not found",details:"Install Python 3.10+ and ensure it's in PATH"}}async function kt(){try{let{stdout:e}=await execa("poetry",["--version"],{timeout:3e3}),s=e.match(/Poetry .*version ([\d.]+)/);return s?{status:"ok",message:`Poetry ${s[1]}`,details:"Available for dependency management"}:{status:"warn",message:"Poetry version unknown"}}catch{let e=d().map(s=>({cmd:s,args:s==="py"?["-3","-m","poetry","--version"]:["-m","poetry","--version"]}));for(let s of e)try{let{stdout:a}=await execa(s.cmd,s.args,{timeout:3e3,shell:b()}),t=a.match(/Poetry .*version ([\d.]+)/)||a.match(/([\d.]+)/);return {status:"ok",message:t?.[1]?`Poetry ${t[1]}`:"Poetry detected",details:`Available via ${s.cmd} ${s.args.join(" ")}`}}catch{continue}for(let s of Ye())try{if(!await i.pathExists(s))continue;let{stdout:a}=await execa(s,["--version"],{timeout:3e3,shell:b()}),t=a.match(/Poetry .*version ([\d.]+)/)||a.match(/([\d.]+)/);return {status:"ok",message:t?.[1]?`Poetry ${t[1]}`:"Poetry detected",details:`Available at ${s}`}}catch{continue}return {status:"warn",message:"Poetry not installed",details:"Optional: Install for better dependency management"}}}async function wt(){try{let{stdout:e}=await execa("pipx",["--version"],{timeout:3e3});return {status:"ok",message:`pipx ${e.trim()}`,details:"Available for global tool installation"}}catch{let e=d();for(let s of e)try{let a=s==="py"?["-3","-m","pipx","--version"]:["-m","pipx","--version"],{stdout:t}=await execa(s,a,{timeout:3e3,shell:b()});return {status:"ok",message:`pipx ${t.trim()}`,details:`Available via ${s} ${a.join(" ")}`}}catch{continue}return {status:"warn",message:"pipx not installed",details:"Optional: Install for isolated Python tools"}}}async function vt(){try{let{stdout:e}=await execa("go",["version"],{timeout:3e3}),s=e.match(/go version go(\d+\.\d+(?:\.\d+)?)/);return s?{status:"ok",message:`Go ${s[1]}`,details:"Available for Go/Fiber and Go/Gin projects"}:{status:"ok",message:"Go (version unknown)",details:"go found in PATH"}}catch{return {status:"warn",message:"Go not installed",details:"Optional: Required only for gofiber.standard / gogin.standard projects \u2014 https://go.dev/dl/"}}}async function xt(){let e=process.env.HOME||process.env.USERPROFILE||"",s=[],a=Ze(e);for(let{location:c,path:n}of a)try{if(await i.pathExists(n)){let{stdout:r,exitCode:d}=await execa(n,["--version"],{timeout:3e3,reject:false});if(d===0&&(r.includes("RapidKit Version")||r.includes("RapidKit"))){let u=r.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);u&&s.push({location:c,path:n,version:u[1]});}}}catch{continue}if(s.length>0){let c=s.filter(r=>r.location!=="Workspace (launcher)");if(c.length>0){let r=et(c);return {status:"ok",message:`RapidKit Core ${r[0].version}`,paths:r.map(u=>({location:u.location,path:u.path,version:u.version}))}}return {status:"ok",message:`RapidKit Core ${s[0].version}`,details:"Detected via workspace launcher"}}try{let{stdout:c,exitCode:n}=await execa("rapidkit",["--version"],{timeout:3e3,reject:false});if(n===0&&(c.includes("RapidKit Version")||c.includes("RapidKit"))){let r=c.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(r)return {status:"ok",message:`RapidKit Core ${r[1]}`,details:"Available via PATH"}}}catch{}try{let{stdout:c,exitCode:n}=await execa("poetry",["run","rapidkit","--version"],{timeout:3e3,reject:false});if(n===0&&(c.includes("RapidKit Version")||c.includes("RapidKit"))){let r=c.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(r)return {status:"ok",message:`RapidKit Core ${r[1]}`,details:"Available via Poetry"}}}catch{}let t=d();for(let c of t)try{let{stdout:n,exitCode:r}=await execa(c,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:3e3,reject:false});if(r===0&&n&&!n.includes("Traceback")&&!n.includes("ModuleNotFoundError")){let d=n.trim();if(d)return {status:"ok",message:`RapidKit Core ${d}`,details:`Available in ${c} environment`}}}catch{continue}return {status:"error",message:"RapidKit Core not installed",details:"Install with: pipx install rapidkit-core"}}async function A(e,s){let a=o.join(e,"Dockerfile");s.hasDocker=await i.pathExists(a);let t=o.join(e,"tests"),c=o.join(e,"test"),n=o.join(e,"src","test"),r=await i.pathExists(t)||await i.pathExists(c)||await i.pathExists(n),d=false;if(s.framework==="Go/Fiber"||s.framework==="Go/Gin")try{let u=[{dir:e,depth:0}],m=4,p=new Set([".git",".venv","node_modules","dist","build","vendor"]);for(;u.length>0&&!d;){let g=u.shift();if(!g)break;let f=[];try{f=await i.readdir(g.dir);}catch{continue}for(let y of f){let h=o.join(g.dir,y),v;try{v=await i.stat(h);}catch{continue}if(v.isFile()&&y.endsWith("_test.go")){d=true;break}v.isDirectory()&&g.depth<m&&!p.has(y)&&!y.startsWith(".")&&u.push({dir:h,depth:g.depth+1});}}}catch{}if(s.hasTests=r||d,s.runtimeFamily==="node"){let u=o.join(e,".eslintrc.js"),m=o.join(e,".eslintrc.json");s.hasCodeQuality=await i.pathExists(u)||await i.pathExists(m);}else if(s.framework==="Go/Fiber"||s.framework==="Go/Gin"){let u=o.join(e,".golangci.yml"),m=o.join(e,".golangci.yaml"),p=o.join(e,"Makefile"),g=await i.pathExists(p)&&(await i.readFile(p,"utf8")).includes("golangci-lint");s.hasCodeQuality=await i.pathExists(u)||await i.pathExists(m)||g;}else if(s.runtimeFamily==="python"){let u=o.join(e,"ruff.toml"),m=o.join(e,"pyproject.toml");if(await i.pathExists(m))try{let p=await i.readFile(m,"utf8");s.hasCodeQuality=p.includes("[tool.ruff]")||await i.pathExists(u);}catch{s.hasCodeQuality=await i.pathExists(u);}}else if(s.framework==="Spring Boot"){let u=o.join(e,"pom.xml");if(await i.pathExists(u))try{let m=await i.readFile(u,"utf8");s.hasCodeQuality=m.includes("spotless")||m.includes("checkstyle")||m.includes("pmd")||m.includes("maven-enforcer-plugin");}catch{s.hasCodeQuality=false;}}try{if(s.runtimeFamily==="node"){let{stdout:u}=await execa("npm",["audit","--json"],{cwd:e,reject:false});if(u)try{let p=JSON.parse(u).metadata?.vulnerabilities;p&&(s.vulnerabilities=(p.high||0)+(p.critical||0)+(p.moderate||0));}catch{}}else if(s.runtimeFamily==="python"){let u=o.join(e,".venv"),m=f(u);if(await i.pathExists(m))try{let{stdout:p}=await execa(m,["-m","pip","list","--format=json"],{timeout:5e3,reject:false});if(p){JSON.parse(p);s.vulnerabilities=0;}}catch{}}}catch{}}function I(e,s){e.probes||(e.probes=[]),e.probes.push(s);}async function bt(e,s){let a=s.runtimeFamily||"unknown";if(s.projectKind==="backend"||s.projectKind==="generic"){if(a==="node"){let c=await i.pathExists(o.join(e,"package-lock.json"))||await i.pathExists(o.join(e,"pnpm-lock.yaml"))||await i.pathExists(o.join(e,"yarn.lock"));I(s,{id:"adapter-node-lockfile-integrity",label:"Node adapter lockfile integrity",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Node lockfile detected for deterministic dependency restore.":"No Node lockfile detected (package-lock/yarn.lock/pnpm-lock.yaml).",recommendation:c?void 0:"Commit a lockfile for deterministic installs and CI parity."});let n=await i.pathExists(o.join(e,"src/main.ts"))||await i.pathExists(o.join(e,"src/main.js"))||await i.pathExists(o.join(e,"src/server.ts"))||await i.pathExists(o.join(e,"src/server.js"));I(s,{id:"adapter-node-boot-entrypoint",label:"Node adapter boot entrypoint",status:n?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?"Boot entrypoint markers detected for service startup path.":"No canonical Node boot entrypoint markers detected.",recommendation:n?void 0:"Define and document service bootstrap entrypoint (main/server)."});return}if(a==="python"){let c=await i.pathExists(o.join(e,"poetry.lock"))||await i.pathExists(o.join(e,"requirements.txt"))||await i.pathExists(o.join(e,"uv.lock"));I(s,{id:"adapter-python-lockfile-integrity",label:"Python adapter dependency integrity",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Python dependency contract file detected.":"No Python dependency contract file detected (poetry.lock/requirements/uv.lock).",recommendation:c?void 0:"Pin dependency contract for deterministic setup and reproducible CI."});let n=await i.pathExists(o.join(e,"app/main.py"))||await i.pathExists(o.join(e,"main.py"))||await i.pathExists(o.join(e,"manage.py"));I(s,{id:"adapter-python-boot-entrypoint",label:"Python adapter boot entrypoint",status:n?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?"Python application entrypoint markers detected.":"No Python application entrypoint markers detected.",recommendation:n?void 0:"Expose explicit app/main entrypoint for deterministic boot probes."});return}if(a==="java"){let c=await i.pathExists(o.join(e,"mvnw"))||await i.pathExists(o.join(e,"gradlew"));I(s,{id:"adapter-java-build-wrapper",label:"Java adapter build wrapper",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"Build wrapper detected (mvnw/gradlew).":"No Java build wrapper detected.",recommendation:c?void 0:"Commit mvnw or gradlew for reproducible enterprise pipelines."});return}if(a==="go"){let c=await i.pathExists(o.join(e,"go.sum"));I(s,{id:"adapter-go-module-integrity",label:"Go adapter module integrity",status:c?"pass":"warn",severity:"warn",scope:"project-scoped",reason:c?"go.sum detected for deterministic module verification.":"go.sum missing; module integrity baseline is incomplete.",recommendation:c?void 0:"Generate and commit go.sum in the repository baseline."});}}}async function jt(e,s){let a=[o.join(e,".rapidkit","doctor.adapters.json"),o.join(e,"doctor.adapters.json")];for(let t of a)if(await i.pathExists(t))try{let c=await i.readJSON(t),n=Array.isArray(c?.checks)?c.checks:[];for(let r=0;r<n.length;r+=1){let d=n[r]||{},u=Array.isArray(d.runtimes)?d.runtimes:[];if(u.length>0&&!u.includes(s.runtimeFamily||"unknown"))continue;let m=typeof d.id=="string"&&d.id.trim().length>0?d.id.trim():`adapter-check-${r+1}`,p=typeof d.label=="string"&&d.label.trim().length>0?d.label.trim():m,g=d.severity||"warn",f=Array.isArray(d.anyOfPaths)?d.anyOfPaths.filter(Boolean):[],y=Array.isArray(d.allOfPaths)?d.allOfPaths.filter(Boolean):[],h=f.length===0;for(let R of f)if(await i.pathExists(o.join(e,R))){h=true;break}let v=true;for(let R of y)if(!await i.pathExists(o.join(e,R))){v=false;break}let P=h&&v;I(s,{id:m,label:p,status:P?"pass":g==="error"?"fail":"warn",severity:g,scope:"project-scoped",reason:P?d.passReason||"Custom adapter contract satisfied.":d.failReason||`Custom adapter check failed from ${o.basename(t)}.`,recommendation:d.recommendation});}}catch{I(s,{id:"custom-adapter-config",label:"Custom doctor adapter configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${o.basename(t)}.`,recommendation:"Fix JSON syntax in doctor.adapters.json to re-enable adapter checks."});}}async function B(e,s){if(!(s.projectKind==="backend"||s.projectKind==="generic"))return;let t=o.join(e,".env"),c=o.join(e,".env.example"),n=await i.pathExists(t)||await i.pathExists(c)||await i.pathExists(o.join(e,"config"));I(s,{id:"config-surface",label:"Configuration contract surface",status:n?"pass":"warn",severity:"warn",scope:"project-scoped",reason:n?"Configuration artifacts detected (.env/.env.example/config).":"No explicit configuration contract artifacts detected.",recommendation:n?void 0:"Add .env.example or explicit config contract documentation for deterministic setup."});let r={python:["alembic.ini","migrations","versions"],node:["prisma/schema.prisma","migrations","typeorm.config.ts","typeorm.config.js"],go:["migrations","db/migrations"],java:["src/main/resources/db/migration","src/main/resources/liquibase"],rust:["migrations","sqlx-data.json"],elixir:["priv/repo/migrations"],clojure:["resources/migrations","migrations"],deno:["migrations"],php:["database/migrations","migrations"],ruby:["db/migrate"],dotnet:["Migrations","Data/Migrations"],unknown:["migrations"]},d=s.runtimeFamily||"unknown",u=r[d]||r.unknown,m=false;for(let f of u)if(await i.pathExists(o.join(e,f))){m=true;break}I(s,{id:"migration-surface",label:"Migration/readiness surface",status:m?"pass":"warn",severity:"warn",scope:"project-scoped",reason:m?"Migration or schema evolution markers detected.":"No migration markers detected for this backend runtime.",recommendation:m?void 0:"Add migration tooling baseline (migrations dir or runtime-native migration config)."});let p=["src/health","src/healthcheck","src/main/resources/application.yml","src/main/resources/application.properties","app/health.py","routes/health.ts","routes/health.js"],g=false;for(let f of p)if(await i.pathExists(o.join(e,f))){g=true;break}I(s,{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 bt(e,s);}async function W(e,s){let a=[o.join(e,".rapidkit","doctor.probes.json"),o.join(e,"doctor.probes.json")];for(let t of a)if(await i.pathExists(t))try{let c=await i.readJSON(t),n=Array.isArray(c?.probes)?c.probes:[];for(let r=0;r<n.length;r+=1){let d=n[r]||{},u=typeof d.id=="string"&&d.id.trim().length>0?d.id.trim():`custom-probe-${r+1}`,m=typeof d.label=="string"&&d.label.trim().length>0?d.label.trim():u,p=d.severity||"warn",g=Array.isArray(d.anyOfPaths)?d.anyOfPaths.filter(Boolean):[],f=Array.isArray(d.allOfPaths)?d.allOfPaths.filter(Boolean):[],y=g.length===0;for(let P of g)if(await i.pathExists(o.join(e,P))){y=true;break}let h=true;for(let P of f)if(!await i.pathExists(o.join(e,P))){h=false;break}let v=y&&h;I(s,{id:u,label:m,status:v?"pass":p==="error"?"fail":"warn",severity:p,scope:"project-scoped",reason:v?"Custom probe contract satisfied.":`Custom probe failed from ${o.basename(t)}.`,recommendation:d.recommendation});}}catch{I(s,{id:"custom-probe-config",label:"Custom doctor probe configuration",status:"warn",severity:"warn",scope:"project-scoped",reason:`Failed to parse ${o.basename(t)}.`,recommendation:"Fix JSON syntax in doctor.probes.json to re-enable custom probes."});}await jt(e,s);}async function ke(e$1,s={}){let t={name:o.basename(e$1),path:e$1,venvActive:false,depsInstalled:false,coreInstalled:false,issues:[],fixCommands:[]},c=s.allowNonRapidkit===true,n=o.join(e$1,".rapidkit");if(!await i.pathExists(n)){if(!c)return t.issues.push("Not a valid RapidKit project (missing .rapidkit directory)"),t;t.issues.push("Not a RapidKit-managed project (running generic backend diagnostics)");}try{let k=o.join(e$1,"registry.json");if(await i.pathExists(k)){let w=await i.readJson(k);w.installed_modules&&(t.stats={modules:w.installed_modules.length});}}catch{}let r=null;try{let k=o.join(n,"project.json");if(await i.pathExists(k)){r=await i.readJson(k);let w=r?.kit_name||r?.kit;w&&(t.kit=w);}}catch{}try{let k=o.join(e$1,".git");if(await i.pathExists(k)){let{stdout:w}=await execa("git",["log","-1","--format=%cr"],{cwd:e$1,reject:false});w&&(t.lastModified=w.trim());}else {let w=await i.stat(e$1),N=Date.now()-w.mtime.getTime(),M=Math.floor(N/(1e3*60*60*24));t.lastModified=M===0?"today":`${M} day${M>1?"s":""} ago`;}}catch{}let d=o.join(e$1,"package.json"),u=o.join(e$1,"pyproject.toml"),m=o.join(e$1,"requirements.txt"),p=o.join(e$1,"go.mod"),g=o.join(e$1,"pom.xml"),f$1=o.join(e$1,"build.sbt"),y=o.join(e$1,"Cargo.toml"),h=o.join(e$1,"mix.exs"),v=o.join(e$1,"deps.edn"),P=o.join(e$1,"project.clj"),R=o.join(e$1,"deno.json"),L=o.join(e$1,"deno.jsonc"),J=o.join(e$1,"bun.lockb"),T=o.join(e$1,"bun.lock"),ee=o.join(e$1,"composer.json"),Y=o.join(e$1,"Gemfile"),H=await i.pathExists(d),$=await i.pathExists(u)||await i.pathExists(m),Z=await i.pathExists(ee),te=await i.pathExists(Y),Oe=await i.pathExists(y),Ve=await i.pathExists(h),Le=await i.pathExists(v)||await i.pathExists(P),Je=await i.pathExists(f$1),qe=await i.pathExists(R)||await i.pathExists(L),de=false;try{de=(await i.readdir(e$1)).some(w=>w.endsWith(".csproj")||w.endsWith(".sln"));}catch{de=false;}let Ue=await i.pathExists(p)||r?.runtime==="go"||typeof r?.kit_name=="string"&&(r.kit_name.startsWith("gofiber")||r.kit_name.startsWith("gogin")),we=H&&(await i.pathExists(J)||await i.pathExists(T)||typeof r?.packageManager=="string"&&(r?.packageManager).toLowerCase().startsWith("bun@"));if(Ue){_(t,e(e$1,r??null)),t.isGoProject=true,t.venvActive=true,t.coreInstalled=false;try{await execa("go",["version"],{timeout:3e3});}catch{t.issues.push("Go toolchain not found \u2014 install from https://go.dev/dl/"),t.fixCommands?.push("https://go.dev/dl/");}let k=o.join(e$1,"go.sum");return await i.pathExists(k)?t.depsInstalled=true:(t.depsInstalled=false,t.issues.push("Go dependencies not downloaded (go.sum missing)"),t.fixCommands?.push(E(e$1,"go mod tidy"))),await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(await i.pathExists(g)||r?.runtime==="java"||typeof r?.kit_name=="string"&&r.kit_name.startsWith("springboot")){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=await i.pathExists(g),w=await i.pathExists(o.join(e$1,"build.gradle"))||await i.pathExists(o.join(e$1,"build.gradle.kts")),b=await i.pathExists(o.join(e$1,"mvnw"))||await i.pathExists(o.join(e$1,"mvnw.cmd")),N=await i.pathExists(o.join(e$1,"gradlew"))||await i.pathExists(o.join(e$1,"gradlew.bat"));try{await execa("java",["-version"],{timeout:3e3,reject:false});}catch{t.issues.push("Java runtime not found \u2014 install JDK 21+ and ensure java is on PATH"),t.fixCommands?.push("https://adoptium.net/");}if(k){if(!b)try{await execa("mvn",["-version"],{timeout:3e3,reject:false});}catch{t.issues.push("Maven not found \u2014 install Maven 3.9+ or add Maven Wrapper"),t.fixCommands?.push("https://maven.apache.org/install.html");}}else if(w&&!N)try{await execa("gradle",["--version"],{timeout:3e3,reject:false});}catch{t.issues.push("Gradle not found \u2014 install Gradle 8+ or add Gradle Wrapper"),t.fixCommands?.push("https://gradle.org/install/");}let M=o.join(e$1,"target"),S=o.join(e$1,"build","libs"),F=o.join(e$1,".rapidkit","cache","java","m2"),j=o.join(e$1,".rapidkit","cache","java","gradle");t.depsInstalled=await i.pathExists(M)||await i.pathExists(S)||await i.pathExists(F)||await i.pathExists(j),t.depsInstalled||(t.issues.push("Java dependencies are not warmed or built yet"),t.fixCommands?.push(E(e$1,"rapidkit init")));let G=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(G),!t.hasEnvFile){let q=o.join(e$1,".env.example");await i.pathExists(q)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}let O=o.join(e$1,"src","main","resources","application.yml");if(await i.pathExists(O))try{let q=await i.readFile(O,"utf-8");/include:\s*[^\n]*health/i.test(q)||/management:\s*[\s\S]*endpoint:\s*[\s\S]*health:/i.test(q)||(t.issues.push("Actuator health endpoint exposure is not clearly configured in application.yml"),t.fixCommands?.push(E(e$1,"Ensure management.endpoints.web.exposure.include contains health in src/main/resources/application.yml")));}catch{t.issues.push("Unable to read application.yml for Spring Actuator health checks");}return await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(Oe){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=o.join(e$1,"Cargo.lock"),w=o.join(e$1,"target");t.depsInstalled=await i.pathExists(k)||await i.pathExists(w),t.depsInstalled||(t.issues.push("Rust dependencies are not resolved yet (Cargo.lock/target missing)"),t.fixCommands?.push(E(e$1,"cargo fetch")));let b=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(b),!t.hasEnvFile){let N=o.join(e$1,".env.example");await i.pathExists(N)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}return await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(Ve){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=o.join(e$1,"mix.lock"),w=o.join(e$1,"deps");t.depsInstalled=await i.pathExists(k)||await i.pathExists(w),t.depsInstalled||(t.issues.push("Elixir dependencies not installed (mix.lock/deps missing)"),t.fixCommands?.push(E(e$1,"mix deps.get")));let b=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(b),!t.hasEnvFile){let N=o.join(e$1,".env.example");await i.pathExists(N)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}return await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(Le){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=o.join(e$1,".cpcache"),w=o.join(e$1,"target"),b=await i.pathExists(v)||await i.pathExists(P);return t.depsInstalled=await i.pathExists(k)||await i.pathExists(w)||b,t.depsInstalled||(t.issues.push("Clojure dependency cache not initialized"),t.fixCommands?.push(E(e$1,"clojure -P"))),await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(Je){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=o.join(e$1,"target");t.depsInstalled=await i.pathExists(k),t.depsInstalled||(t.issues.push("Scala build artifacts missing (run dependency/build warmup)"),t.fixCommands?.push(E(e$1,"sbt compile")));let w=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(w),!t.hasEnvFile){let b=o.join(e$1,".env.example");await i.pathExists(b)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}return await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(qe){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false,t.depsInstalled=true;let k=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(k),!t.hasEnvFile){let w=o.join(e$1,".env.example");await i.pathExists(w)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}return await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(H){let k=null;try{k=await i.readJson(d);}catch{k=null;}let w={...k?.dependencies??{},...k?.devDependencies??{}},b=k?.scripts??{},N=typeof r?.kit_name=="string"?r.kit_name.toLowerCase():typeof r?.kit=="string"?r.kit.toLowerCase():"",M=dt({dependencies:w,scripts:b,kitName:N});if(we)ie(t,"Bun","high");else {let j=e(e$1,r??null);j.key==="nestjs"||j.key==="express"||j.key==="fastify"||j.key==="koa"?_(t,j):ie(t,M.framework,M.confidence);}t.venvActive=true;let S=o.join(e$1,"node_modules");if(await i.pathExists(S))try{let G=(await i.readdir(S)).filter(O=>!O.startsWith(".")&&!O.startsWith("_"));t.depsInstalled=G.length>0;}catch{t.depsInstalled=false;}if(t.depsInstalled||(t.issues.push("Dependencies not installed (node_modules empty or missing)"),t.fixCommands?.push(E(e$1,we?"bun install":"rapidkit init"))),t.coreInstalled=false,t.projectKind==="frontend"){let j=[".env",".env.local",".env.development",".env.development.local",".env.production",".env.production.local"];if((await Promise.all(j.map(O=>i.pathExists(o.join(e$1,O))))).some(Boolean))t.hasEnvFile=true;else {let O=o.join(e$1,".env.example");await i.pathExists(O)&&(t.hasEnvFile=false,t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}}else {let j=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(j),!t.hasEnvFile){let G=o.join(e$1,".env.example");await i.pathExists(G)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}}let F=o.join(e$1,"src");if(t.modulesHealthy=true,t.missingModules=[],await i.pathExists(F))try{let j=await i.readdir(F);t.modulesHealthy=j.length>0;}catch{t.modulesHealthy=false;}return await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if($){let k=await ut(e$1);ie(t,k.framework,k.confidence);let w=o.join(e$1,".venv");if(await i.pathExists(w)){t.venvActive=true;let S=f(w);if(await i.pathExists(S)){try{let{stdout:G}=await execa(S,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:2e3});t.coreInstalled=true,t.coreVersion=G.trim();}catch{t.coreInstalled=false;}let F="fastapi";t.framework==="Django"?F="django":t.framework==="Flask"?F="flask":t.framework==="Python"&&(F="");let j=true;if(F)try{await execa(S,["-c",`import ${F}`],{timeout:2e3}),t.depsInstalled=true,j=false;}catch{j=true;}if(j)try{let G=o.join(w,"lib");if(await i.pathExists(G)){let q=(await i.readdir(G)).find(se=>se.startsWith("python"));if(q){let se=o.join(G,q,"site-packages");if(await i.pathExists(se)){let ze=(await i.readdir(se)).filter(ue=>!ue.startsWith("_")&&!ue.includes("dist-info")&&!["pip","setuptools","wheel","pkg_resources"].includes(ue));t.depsInstalled=ze.length>0;}}}t.depsInstalled||(t.issues.push("Dependencies not installed"),t.fixCommands?.push(E(e$1,"rapidkit init")));}catch{t.issues.push("Could not verify dependency installation");}}else t.issues.push("Virtual environment exists but Python executable not found");}else t.issues.push("Virtual environment not created"),t.fixCommands?.push(E(e$1,"rapidkit init"));let b=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(b),!t.hasEnvFile){let S=o.join(e$1,".env.example");await i.pathExists(S)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}let N=o.join(e$1,"src"),M=o.join(e$1,"modules");if(t.modulesHealthy=true,t.missingModules=[],await i.pathExists(N)){let S=o.join(N,"__init__.py");await i.pathExists(S)||(t.modulesHealthy=false,t.missingModules.push("src/__init__.py"));}if(await i.pathExists(M))try{let S=await Ge(M);for(let F of S){let j=o.join(M,F,"__init__.py");await i.pathExists(j)||(t.modulesHealthy=false,t.missingModules.push(`modules/${F}/__init__.py`));}}catch{}return !t.modulesHealthy&&t.missingModules.length>0&&t.issues.push(`Missing module init files: ${t.missingModules.join(", ")}`),await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(Z){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=o.join(e$1,"vendor");t.depsInstalled=await i.pathExists(k),t.depsInstalled||(t.issues.push("PHP dependencies not installed (vendor missing)"),t.fixCommands?.push(E(e$1,"composer install")));let w=o.join(e$1,".env");if(t.hasEnvFile=await i.pathExists(w),!t.hasEnvFile){let b=o.join(e$1,".env.example");await i.pathExists(b)&&(t.issues.push("Environment file missing (found .env.example)"),t.fixCommands?.push(V(e$1)));}return await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(te){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=await i.pathExists(o.join(e$1,"Gemfile.lock")),w=await i.pathExists(o.join(e$1,"vendor","bundle"));t.depsInstalled=k||w,t.depsInstalled||(t.issues.push("Ruby dependencies not installed (Gemfile.lock/vendor missing)"),t.fixCommands?.push(E(e$1,"bundle install")));let b=o.join(e$1,".env");return t.hasEnvFile=await i.pathExists(b),await A(e$1,t),await B(e$1,t),await W(e$1,t),t}if(de){_(t,e(e$1,r??null)),t.venvActive=true,t.coreInstalled=false;let k=o.join(e$1,"obj"),w=o.join(e$1,"packages.lock.json");t.depsInstalled=await i.pathExists(k)||await i.pathExists(w),t.depsInstalled||(t.issues.push(".NET restore/build artifacts not found"),t.fixCommands?.push(E(e$1,"dotnet restore")));let b=o.join(e$1,".env");return t.hasEnvFile=await i.pathExists(b),await A(e$1,t),t}return ie(t,"Unknown","low"),t.issues.push("Unknown project type (no recognized runtime marker files)"),await A(e$1,t),await B(e$1,t),await W(e$1,t),t}async function Ge(e){try{return (await i.readdir(e,{withFileTypes:true})).filter(a=>a.isDirectory()).map(a=>a.name)}catch{try{let s=await i.readdir(e),a=[];for(let t of s)try{(await i.stat(o.join(e,t))).isDirectory()&&a.push(t);}catch{continue}return a}catch{return []}}}async function le(e){let s=o.join(e,".rapidkit");if(!await i.pathExists(s))return false;let a=["project.json","context.json","file-hashes.json"];for(let t of a)if(await i.pathExists(o.join(s,t)))return true;return false}function Be(e,s){if(s.has(e))return true;let a=e.toLowerCase();return !!(a==="dist"||a.startsWith("dist-")||a.startsWith("dist_")||a==="build"||a.startsWith("build-")||a.startsWith("build_"))}async function Ct(e,s,a){let t=new Set,c=[{dir:e,depth:0}];for(;c.length>0;){let n=c.shift();if(!n)break;try{let r=await i.readdir(n.dir);for(let d of r){if(Be(d,a))continue;let u=o.join(n.dir,d),m;try{m=await i.stat(u);}catch{continue}if(m.isDirectory()){if(await le(u)){t.add(u);continue}n.depth<s&&c.push({dir:u,depth:n.depth+1});}}}catch{continue}}return Array.from(t)}async function oe(e){let s=o.resolve(e),a=o.parse(s).root;for(;;){if(await St(s))return s;if(s===a)break;s=o.dirname(s);}return null}async function Et(e){let s=o.resolve(e),a=await oe(s),t=a??o.parse(s).root;for(;;){if(await le(s)||await Pt(s)&&(!a||s!==a))return s;if(s===t)break;s=o.dirname(s);}return null}function Pe(e){let s=o.resolve(e);return process.platform==="darwin"?s.replace(/^\/private(?=\/var\/)/,""):s}async function Pt(e){let s=["package.json","pyproject.toml","requirements.txt","go.mod","pom.xml","build.sbt","Cargo.toml","mix.exs","deps.edn","project.clj","deno.json","deno.jsonc","composer.json","Gemfile"];for(let a of s)if(await i.pathExists(o.join(e,a)))return true;return false}async function St(e){let s=[o.join(e,".rapidkit-workspace"),o.join(e,".rapidkit","workspace-marker.json"),o.join(e,".rapidkit","config.json")];return await Promise.all(s.map(t=>i.pathExists(t))).then(t=>t.some(Boolean))?i.pathExists(o.join(e,".rapidkit")):false}function We(e,s){let a=0,t=0,c=0;return e.forEach(r=>{r.status==="ok"?a++:r.status==="warn"?t++:r.status==="error"&&c++;}),s.forEach(r=>{let d=Q(r),u=r.isGoProject?r.issues.length===0&&r.depsInstalled:r.issues.length===0&&r.venvActive&&r.depsInstalled;if(r.issues.length>0||d>0||!u){t++;return}a++;}),{total:a+t+c,passed:a,warnings:t,errors:c}}function Ke(e,s,a={}){let t=[];for(let n of e)t.push({id:n.id,label:n.label,status:n.result.status,scope:"host-system",policyRuleId:"system-status-derived",reason:n.result.details||n.result.message});let c=[...s].sort((n,r)=>{let d=`${n.path||""}|${n.name||""}`.toLowerCase(),u=`${r.path||""}|${r.name||""}`.toLowerCase();return d.localeCompare(u)});for(let n of c){let r=n.issues.length>0,d=Q(n),u=r||d>0?"warn":"ok",m=r?`${n.issues.length} blocking issue(s)`:d>0?`${d} advisory warning(s)`:"Project checks passed";t.push({id:`project:${n.name}`,label:`Project ${n.name}`,status:u,scope:"project-scoped",policyRuleId:r?"project-blocking-issues":d>0?"project-advisory-warnings":"project-checks-passed",reason:m});}if(a.includeWorkspaceAggregateRules){let n=s.reduce((u,m)=>u+m.issues.length,0),r=he(s),d=e.filter(u=>u.result.status==="error").length;t.push({id:"workspace:projects-discovered",label:"Workspace projects discovered",status:s.length>0?"ok":"warn",scope:"workspace-aggregate",policyRuleId:"workspace-project-discovery",reason:s.length>0?`${s.length} project(s) discovered for workspace analysis.`:"No projects discovered for workspace analysis."}),t.push({id:"workspace:system-error-gate",label:"Workspace system error gate",status:d>0?"error":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-system-error-gate",reason:d>0?`${d} system requirement gate(s) failed.`:"All system requirement gates passed."}),t.push({id:"workspace:blocking-issues-gate",label:"Workspace blocking issues gate",status:n>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-blocking-issues-gate",reason:n>0?`${n} blocking project issue(s) detected.`:"No blocking project issues detected."}),t.push({id:"workspace:advisory-warnings-gate",label:"Workspace advisory warnings gate",status:r>0?"warn":"ok",scope:"workspace-aggregate",policyRuleId:"workspace-advisory-warning-gate",reason:r>0?`${r} advisory warning(s) detected.`:"No advisory warnings detected."});}return t}async function Se(e,s=true){let a$1=o.basename(e);try{let f=o.join(e,".rapidkit-workspace");await i.pathExists(f)&&(a$1=(await i.readJSON(f)).name||a$1);}catch{try{let f=o.join(e,".rapidkit","config.json");a$1=(await i.readJSON(f)).workspace_name||a$1;}catch{}}let[t,c]=await Promise.all([ye(),pt(e)]),n={workspacePath:e,workspaceName:a$1,python:t.python,poetry:t.poetry,pipx:t.pipx,go:t.go,rapidkitCore:t.rapidkitCore,projects:[]};a.debug(`Workspace scan found ${c.length} project(s)`);let r=await mt(e,c),d=o.join(e,".rapidkit","reports","doctor-workspace-cache.json"),u=s?await ft(d,r):null;if(u)n.projects=u.projects,n.projectScanCached=true,a.debug(`Workspace project health cache hit: ${d}`);else try{let f=await Promise.all(c.map(y=>ke(y)));n.projects=f,n.projectScanCached=false,await gt(d,{schemaVersion:De,signature:r,generatedAt:new Date().toISOString(),projects:f}),a.debug(`Workspace project health cache refreshed: ${d}`);}catch(f){a.debug(`Failed to scan workspace projects: ${f}`);}n.projectScanSignature=r,n.projectScanCachePath=d;let m=[n.python,n.poetry,n.pipx,n.go,n.rapidkitCore];if(n.healthScore=We(m,n.projects),n.scoreBreakdown=Ke([{id:"system-python",label:"Python",result:n.python},{id:"system-poetry",label:"Poetry",result:n.poetry},{id:"system-pipx",label:"pipx",result:n.pipx},{id:"system-go",label:"Go",result:n.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:n.rapidkitCore}],n.projects,{includeWorkspaceAggregateRules:true}),n.scopeProvenance=Ne(n.scoreBreakdown),n.rapidkitCore.status==="ok"){let f=n.rapidkitCore.message.match(/([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);f&&(n.coreVersion=f[1]);}let p=o.join(e,".rapidkit","reports","doctor-last-run.json"),g=await Ie(p,"workspace");return n.driftDelta=nt(g,n),n.evidencePath=await ht(e,n,u?d:null),n}async function Rt(e,s){let a=e||s.projectPath,t=o.join(a,".rapidkit","reports","doctor-project-last-run.json");try{return await i.ensureDir(o.dirname(t)),await i.writeJSON(t,{schemaVersion:b$1,evidenceType:"project",generatedAt:new Date().toISOString(),contract:re(),workspacePath:e||null,projectPath:s.projectPath,projectName:s.projectName,healthScore:s.healthScore,system:{python:s.python,poetry:s.poetry,pipx:s.pipx,go:s.go,rapidkitCore:s.rapidkitCore},project:s.project,driftDelta:s.driftDelta,summary:{scopeProvenance:s.scopeProvenance},scoreBreakdown:s.scoreBreakdown??[]},{spaces:2}),t}catch{return}}async function $t(e){let s=await oe(e),a=await ye(),t=await ke(e,{allowNonRapidkit:true}),c=We([a.python,a.poetry,a.pipx,a.go,a.rapidkitCore],[t]),n={workspacePath:s||void 0,projectPath:e,projectName:o.basename(e),python:a.python,poetry:a.poetry,pipx:a.pipx,go:a.go,rapidkitCore:a.rapidkitCore,project:t,healthScore:c};n.scoreBreakdown=Ke([{id:"system-python",label:"Python",result:n.python},{id:"system-poetry",label:"Poetry",result:n.poetry},{id:"system-pipx",label:"pipx",result:n.pipx},{id:"system-go",label:"Go",result:n.go},{id:"system-rapidkit-core",label:"RapidKit Core",result:n.rapidkitCore}],[n.project]),n.scopeProvenance=Ne(n.scoreBreakdown);let r=s||e,d=o.join(r,".rapidkit","reports","doctor-project-last-run.json"),u=await Ie(d,"project");return n.driftDelta=ot(u,n),n.evidencePath=await Rt(s||void 0,n),n}function C(e,s){let a=e.status==="ok"?"\u2705":e.status==="warn"?"\u26A0\uFE0F":"\u274C",t=e.status==="ok"?l.green:e.status==="warn"?l.yellow:l.red;console.log(`${a} ${l.bold(s)}: ${t(e.message)}`),e.paths&&e.paths.length>0?e.paths.forEach(c=>{let n=c.version?l.cyan(` -> ${c.version}`):"";console.log(` ${l.cyan("\u2022")} ${l.gray(c.location)}: ${l.dim(c.path)}${n}`);}):e.details&&console.log(` ${l.gray(e.details)}`);}function Re(e){let s=e.issues.length>0,a=s?"\u26A0\uFE0F":"\u2705",t=s?l.yellow:l.green;if(console.log(`
2
+ ${a} ${l.bold("Project")}: ${t(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"?"\u25B2":e.framework==="React"?"\u269B\uFE0F":e.framework==="Vue"?"\u{1F7E2}":e.framework==="Angular"?"\u{1F170}\uFE0F":e.framework==="SvelteKit"?"\u{1F9E1}":e.framework==="Spring Boot"?"\u2615":e.framework==="Rust"?"\u{1F980}":e.framework==="Elixir"||e.framework==="Phoenix"?"\u{1F9EA}":e.framework==="Clojure"?"\u2699\uFE0F":e.framework==="Scala"?"\u{1F53A}":e.framework==="Kotlin"?"\u{1F7E3}":e.framework==="Deno"?"\u{1F995}":e.framework==="Bun"?"\u{1F956}":e.framework==="Go/Fiber"||e.framework==="Go/Gin"?"\u{1F439}":e.framework==="Laravel"||e.framework==="PHP"?"\u{1F418}":e.framework==="Ruby on Rails"||e.framework==="Ruby"?"\u{1F48E}":e.framework==="ASP.NET"?"\u{1F537}":"\u{1F4E6}";console.log(` ${r} Framework: ${l.cyan(e.framework)}${e.kit?l.gray(` (${e.kit})`):""}`);let d=[];e.runtimeFamily&&d.push(`runtime: ${e.runtimeFamily}`),e.projectKind&&d.push(`kind: ${e.projectKind}`),e.supportTier&&d.push(`support: ${e.supportTier}`),e.frameworkConfidence&&d.push(`confidence: ${e.frameworkConfidence}`),d.length>0&&console.log(` ${l.dim("\u21B3")} ${l.gray(d.join(" \u2022 "))}`);}if(console.log(` ${l.gray(`Path: ${e.path}`)}`),e.runtimeFamily==="python"&&(e.venvActive?console.log(` \u2705 Virtual environment: ${l.green("Active")}`):console.log(` \u274C Virtual environment: ${l.red("Not found")}`),e.coreInstalled?console.log(` ${l.dim("\u2139")} RapidKit Core: ${l.gray(e.coreVersion||"In venv")} ${l.dim("(optional)")}`):console.log(` ${l.dim("\u2139")} RapidKit Core: ${l.gray("Using global installation")} ${l.dim("(recommended)")}`)),e.depsInstalled?console.log(` \u2705 Dependencies: ${l.green("Installed")}`):console.log(` \u26A0\uFE0F Dependencies: ${l.yellow("Not installed")}`),e.hasEnvFile!==void 0&&(e.hasEnvFile?console.log(` \u2705 Environment: ${l.green(".env configured")}`):console.log(` \u26A0\uFE0F Environment: ${l.yellow(".env missing")}`)),e.modulesHealthy!==void 0&&(e.modulesHealthy?console.log(` \u2705 Modules: ${l.green("Healthy")}`):e.missingModules&&e.missingModules.length>0&&console.log(` \u26A0\uFE0F Modules: ${l.yellow(`Missing ${e.missingModules.length} init file(s)`)}`)),e.stats){let 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: ${l.cyan(r.join(" \u2022 "))}`);}e.lastModified&&console.log(` \u{1F552} Last Modified: ${l.gray(e.lastModified)}`);let n=[];if(e.hasTests!==void 0&&n.push(e.hasTests?"\u2705 Tests":l.dim("\u2298 No tests")),e.hasDocker!==void 0&&n.push(e.hasDocker?"\u2705 Docker":l.dim("\u2298 No Docker")),e.hasCodeQuality!==void 0){let r=e.runtimeFamily==="node"?"ESLint":e.runtimeFamily==="rust"?"clippy":e.runtimeFamily==="elixir"?"Credo":e.runtimeFamily==="clojure"?"clj-kondo":e.runtimeFamily==="deno"?"deno lint":e.framework==="Spring Boot"?"Static analysis":e.framework==="Go/Fiber"||e.framework==="Go/Gin"?"golangci-lint":e.runtimeFamily==="python"?"Ruff":"Lint";n.push(e.hasCodeQuality?`\u2705 ${r}`:l.dim(`\u2298 No ${r}`));}if(n.length>0&&console.log(` ${n.join(" \u2022 ")}`),e.vulnerabilities!==void 0&&e.vulnerabilities>0&&console.log(` \u26A0\uFE0F Security: ${l.yellow(`${e.vulnerabilities} vulnerability(ies) found`)}`),e.issues.length>0&&(console.log(` ${l.bold("Issues:")}`),e.issues.forEach(r=>{console.log(` \u2022 ${l.yellow(r)}`);}),e.fixCommands&&e.fixCommands.length>0&&(console.log(`
3
+ ${l.bold.cyan("\u{1F527} Quick Fix:")}`),e.fixCommands.forEach(r=>{console.log(` ${l.cyan("$")} ${l.white(r)}`);}))),e.probes&&e.probes.length>0){console.log(` ${l.bold("Probe checks:")}`);for(let r of e.probes){let d=r.status==="pass"?"\u2705":r.status==="warn"?"\u26A0\uFE0F":"\u274C";console.log(` ${d} ${r.label}: ${l.gray(r.reason)}`),r.recommendation&&console.log(` ${l.dim("\u21B3")} ${l.gray(r.recommendation)}`);}}}async function $e(){try{return (await execa("go",["version"],{timeout:3e3,reject:false})).exitCode===0}catch{return false}}function X(e,s){let a=[new RegExp(`^cd\\s+"([^"]+)"\\s*(?:&&|;)\\s*${s}\\s*$`,"i"),new RegExp(`^cd\\s+'([^']+)'\\s*(?:&&|;)\\s*${s}\\s*$`,"i"),new RegExp(`^cd\\s+(.+?)\\s*(?:&&|;)\\s*${s}\\s*$`,"i")];for(let t of a){let c=e.match(t);if(c?.[1])return {projectPath:c[1].trim()}}return null}function _e(e){return X(e,"cp\\s+\\.env\\.example\\s+\\.env")||X(e,"copy-item\\s+\\.env\\.example\\s+\\.env")}function Te(e){let s=[{pattern:"npm\\s+install",command:"npm",args:["install"]},{pattern:"npm\\s+ci",command:"npm",args:["ci"]},{pattern:"pnpm\\s+install",command:"pnpm",args:["install"]},{pattern:"yarn\\s+install",command:"yarn",args:["install"]},{pattern:"poetry\\s+install",command:"poetry",args:["install"]},{pattern:"pip\\s+install\\s+-r\\s+requirements\\.txt",command:"pip",args:["install","-r","requirements.txt"]},{pattern:"composer\\s+install",command:"composer",args:["install"]},{pattern:"bundle\\s+install",command:"bundle",args:["install"]},{pattern:"dotnet\\s+restore",command:"dotnet",args:["restore"]},{pattern:"cargo\\s+fetch",command:"cargo",args:["fetch"]},{pattern:"mix\\s+deps\\.get",command:"mix",args:["deps.get"]},{pattern:"clojure\\s+-P",command:"clojure",args:["-P"]},{pattern:"sbt\\s+compile",command:"sbt",args:["compile"]}];for(let a of s){let t=X(e,a.pattern);if(t)return {projectPath:t.projectPath,command:a.command,args:a.args}}return null}function fe(e,s){return /^https?:\/\//i.test(s.trim())?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"manual-url",risk:"safe",executable:false,reason:"Manual guidance URL"}:_e(s)?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"env-copy",risk:"safe",executable:true,reason:"Environment seed copy"}:X(s,"rapidkit\\s+init")?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"rapidkit-init",risk:"guarded",executable:true,reason:"RapidKit initializer may mutate dependencies and configs"}:X(s,"go\\s+mod\\s+tidy")?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"go-mod-tidy",risk:"guarded",executable:true,reason:"Go module graph reconciliation"}:Te(s)?{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"dependency-sync",risk:"guarded",executable:true,reason:"Dependency synchronization command"}:{projectName:e.name,projectPath:e.path,originalCommand:s,kind:"shell",risk:"invasive",executable:true,reason:"Generic shell command"}}function Fe(e){let s=e instanceof Error?e.message:String(e),a=["ETIMEDOUT","ECONNRESET","ECONNREFUSED","EAI_AGAIN","ENOTFOUND","network","503","504"],t=s.toLowerCase();return a.some(c=>t.includes(c.toLowerCase()))}async function Ft(e,s){let a=e.get(s);if(a)return a;let t=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,c=o.basename(s).replace(/[^a-zA-Z0-9._-]/g,"_"),n=o.join(s,".rapidkit","reports","fix-snapshots",`${c}-${t}`);await i.ensureDir(n);let r=[".env","package-lock.json","pnpm-lock.yaml","yarn.lock","poetry.lock","requirements.txt","go.mod","go.sum","Cargo.lock","composer.lock","Gemfile.lock","pom.xml","build.gradle","build.gradle.kts","gradle.lockfile"],d=new Map;for(let m of r){let p=o.join(s,m);if(!await i.pathExists(p))continue;let g=o.join(n,m);await i.ensureDir(o.dirname(g)),await i.copy(p,g,{overwrite:true}),d.set(p,g);}let u={snapshotRoot:n,files:d};return e.set(s,u),u}async function Dt(e){for(let[s,a]of e.files.entries())await i.pathExists(a)&&(await i.ensureDir(o.dirname(s)),await i.copy(a,s,{overwrite:true}));}async function At(e){let s=await ke(e,{allowNonRapidkit:true});return {issues:s.issues.length,healthy:s.issues.length===0}}async function ae(e,s=false){let a=e.filter(f=>f.fixCommands&&f.fixCommands.length>0),t=null,c=new Map;if(a.length===0){console.log(l.green(`
4
+ \u2705 No fixes needed - all projects are healthy!`));return}let n=a.flatMap(f=>(f.fixCommands??[]).map(y=>fe(f,y)));console.log(l.bold.cyan(`
5
+ \u{1F527} Available Fixes:
6
+ `));for(let f of a){let y=f.fixCommands??[];console.log(l.bold(`Project: ${l.yellow(f.name)}`)),y.forEach((h,v)=>{console.log(` ${v+1}. ${l.cyan(h)}`);}),console.log();}let r=0,d=0,u=0,m=0;for(let f of n)f.executable&&(f.kind==="go-mod-tidy"&&(t===null&&(t=await $e()),!t)||(r+=1,f.risk==="safe"&&(d+=1),f.risk==="guarded"&&(u+=1),f.risk==="invasive"&&(m+=1)));if(r===0){console.log(l.gray("\u{1F4A1} No automatic fixes can be applied right now.")),t===false&&console.log(l.gray(" Install Go to enable go mod tidy fixes, then rerun `rapidkit doctor workspace --fix`."));return}if(!s){console.log(l.gray('\u{1F4A1} Run "npx rapidkit doctor workspace --fix" to apply fixes automatically'));return}console.log(l.gray(`Risk policy: safe=${d}, guarded=${u}, invasive=${m}. Guarded/invasive fixes use snapshot + rollback.`));let{confirm:p}=await Qe.prompt([{type:"confirm",name:"confirm",message:`Apply ${a.reduce((f,y)=>f+(y.fixCommands?.length??0),0)} fix(es)?`,default:false}]);if(!p){console.log(l.yellow(`
7
+ \u26A0\uFE0F Fixes cancelled by user`));return}console.log(l.bold.cyan(`
8
+ \u{1F680} Applying fixes...
9
+ `));let g=new Set;for(let f of a){let y=f.fixCommands??[];console.log(l.bold(`Fixing ${l.cyan(f.name)}...`));for(let h of y){let v=fe(f,h),P=`${f.path}::${h}`;if(!g.has(P)){g.add(P);try{if(console.log(l.gray(` $ ${h}`)),v.kind==="manual-url"){console.log(l.yellow(` \u2139 Manual action required: open ${h}`)),console.log(l.green(` \u2705 Recorded as guidance
10
+ `));continue}if(!v.executable){console.log(l.yellow(" \u26A0 Step is non-executable by policy")),console.log(l.green(` \u2705 Recorded as guidance
11
+ `));continue}v.risk!=="safe"&&await Ft(c,v.projectPath);let R=_e(h);if(R){let H=o.join(R.projectPath,".env.example"),$=o.join(R.projectPath,".env");if(!await i.pathExists(H))throw new Error(`.env.example not found at ${H}`);if(await i.pathExists($)){console.log(l.green(` \u2705 .env already exists
12
+ `));continue}await i.copy(H,$,{overwrite:false,errorOnExist:false}),console.log(l.green(` \u2705 Success
13
+ `));continue}let L=X(h,"rapidkit\\s+init");if(L){await execa("rapidkit",["init"],{cwd:L.projectPath,shell:b(),stdio:"inherit"}),console.log(l.green(` \u2705 Success
14
+ `));continue}let J=X(h,"go\\s+mod\\s+tidy");if(J){if(t===null&&(t=await $e()),!t){console.log(l.yellow(" \u26A0 Go toolchain is not installed \u2014 skipping go mod tidy; install Go to apply this fix.")),console.log(l.green(` \u2705 Recorded as guidance
15
+ `));continue}await execa("go",["mod","tidy"],{cwd:J.projectPath,shell:b(),stdio:"inherit"}),console.log(l.green(` \u2705 Success
16
+ `));continue}let T=Te(h);if(T){let $;for(let Z=1;Z<=2;Z+=1)try{await execa(T.command,T.args,{cwd:T.projectPath,shell:b(),stdio:"inherit"}),$=null;break}catch(te){if($=te,Z<2&&Fe(te)){console.log(l.yellow(` \u26A0 Retrying dependency sync (${Z}/1)...`));continue}throw te}if($)throw $;console.log(l.green(` \u2705 Success
17
+ `));continue}let ee=v.kind==="shell"?2:1,Y;for(let H=1;H<=ee;H+=1)try{await execa(h,{shell:true,stdio:"inherit"}),Y=null;break}catch($){if(Y=$,H<ee&&Fe($)){console.log(l.yellow(` \u26A0 Retrying command (${H}/${ee-1})...`));continue}throw $}if(Y)throw Y;console.log(l.green(` \u2705 Success
18
+ `));}catch(R){let L=fe(f,h);if(L.risk!=="safe"){let J=c.get(L.projectPath);if(J)try{await Dt(J),console.log(l.yellow(" \u21A9 Rolled back snapshot after failed fix"));}catch(T){console.log(l.red(` \u274C Rollback failed: ${T instanceof Error?T.message:String(T)}`));}}console.log(l.red(` \u274C Failed: ${R instanceof Error?R.message:String(R)}
19
+ `));}}}try{let h=await At(f.path);console.log(h.healthy?l.green(` \u2705 Post-fix verification passed for ${f.name}`):l.yellow(` \u26A0 Post-fix verification: ${h.issues} issue(s) remain for ${f.name}`));}catch(h){console.log(l.yellow(` \u26A0 Post-fix verification skipped: ${h instanceof Error?h.message:String(h)}`));}}console.log(l.bold.green(`
20
+ \u2705 Fix process completed!`));}async function Jt(e={}){let s=!e.workspace&&!e.project&&e.fix?await oe(process.cwd()):null,a$1=e.workspace||!!s,t=!!e.project&&!a$1;if(e.json||console.log(l.bold.cyan(`
21
+ \u{1FA7A} RapidKit Health Check
22
+ `)),a$1){let c=s??await oe(process.cwd());c||(a.error("No RapidKit workspace found in current directory or parents"),a.info('Run this command from within a workspace, or use "rapidkit doctor" for system check'),process.exit(1)),e.json||(s&&console.log(l.gray("\u2139\uFE0F Detected workspace context; enabling workspace checks for --fix")),console.log(l.bold(`Workspace: ${l.cyan(o.basename(c))}`)),console.log(l.gray(`Path: ${c}`)));let n=await Se(c);if(e.json||(n.projectScanCached&&console.log(l.gray(`\u2139\uFE0F Reused cached project scan${n.projectScanCachePath?` (${o.basename(n.projectScanCachePath)})`:""}`)),n.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence saved: ${n.evidencePath}`))),e.json){let m={contract:re(),workspace:{name:o.basename(c),path:c},cache:{projectScan:n.projectScanCached??false,projectScanPath:n.projectScanCachePath,evidencePath:n.evidencePath},healthScore:n.healthScore,system:{python:n.python,poetry:n.poetry,pipx:n.pipx,rapidkitCore:n.rapidkitCore,versions:{core:n.coreVersion,npm:n.npmVersion}},projects:n.projects.map(p=>({name:p.name,path:p.path,framework:p.framework,frameworkKey:p.frameworkKey,importStack:p.importStack,runtimeFamily:p.runtimeFamily,projectKind:p.projectKind,supportTier:p.supportTier,frameworkConfidence:p.frameworkConfidence,venvActive:p.venvActive,depsInstalled:p.depsInstalled,hasEnvFile:p.hasEnvFile,vulnerabilities:p.vulnerabilities,coreInstalled:p.coreInstalled,coreVersion:p.coreVersion,issues:p.issues,fixCommands:p.fixCommands,probes:p.probes})),summary:{totalProjects:n.projects.length,totalIssues:n.projects.reduce((p,g)=>p+g.issues.length,0),projectAdvisoryWarningProjects:ge(n.projects),projectAdvisoryWarnings:he(n.projects),hasSystemErrors:[n.python,n.rapidkitCore].some(p=>p.status==="error"),scopeProvenance:n.scopeProvenance},driftDelta:n.driftDelta,scoreBreakdown:n.scoreBreakdown??[]};console.log(JSON.stringify(m,null,2));return}if(n.healthScore){let m=n.healthScore,p=Math.round(m.passed/m.total*100),g=p>=80?l.green:p>=50?l.yellow:l.red,f="\u2588".repeat(Math.floor(p/5))+"\u2591".repeat(20-Math.floor(p/5));console.log(l.bold(`
23
+ \u{1F4CA} Health Score:`)),console.log(` ${g(`${p}%`)} ${l.gray(f)}`),console.log(` ${l.green(`\u2705 ${m.passed} passed`)} ${l.gray("|")} ${l.yellow(`\u26A0\uFE0F ${m.warnings} warnings`)} ${l.gray("|")} ${l.red(`\u274C ${m.errors} errors`)}`);}if(console.log(l.bold(`
24
+
25
+ System Tools:
26
+ `)),C(n.python,"Python"),C(n.poetry,"Poetry"),C(n.pipx,"pipx"),C(n.go,"Go"),C(n.rapidkitCore,"RapidKit Core"),n.coreVersion&&n.npmVersion){let m=n.coreVersion.split(".")[1],p=n.npmVersion.split(".")[1];m!==p&&(console.log(l.yellow(`
27
+ \u26A0\uFE0F Version mismatch: Core ${n.coreVersion} / CLI ${n.npmVersion}`)),console.log(l.gray(" Consider updating to matching versions for best compatibility")));}n.projects.length>0?(console.log(l.bold(`
28
+ \u{1F4E6} Projects (${n.projects.length}):`)),n.projects.forEach(m=>Re(m))):(console.log(l.bold(`
29
+ \u{1F4E6} Projects:`)),console.log(l.gray(" No RapidKit projects found in workspace")));let r=n.projects.reduce((m,p)=>m+p.issues.length,0),d=ge(n.projects),u=[n.python,n.rapidkitCore].some(m=>m.status==="error");if(u||r>0||d>0){let m=d>0?` and ${d} advisory warning project(s)`:"";if(console.log(l.bold.yellow(`
30
+ \u26A0\uFE0F Found ${r} project issue(s)${m}`)),u&&console.log(l.bold.red("\u274C System requirements not met")),e.fix){if(await ae(n.projects,true),!e.json){let p=await Se(c,false),g=p.projects.reduce((y,h)=>y+h.issues.length,0),f=[p.python,p.rapidkitCore].some(y=>y.status==="error");f||g>0?(console.log(l.bold.yellow(`
31
+ \u26A0\uFE0F Post-fix verification found ${g} remaining issue(s)`)),f&&console.log(l.bold.red("\u274C System requirements still not met"))):console.log(l.bold.green(`
32
+ \u2705 Post-fix verification passed. Workspace is healthy.`)),p.projectScanCached&&console.log(l.gray(`\u2139\uFE0F Reused cached project scan${p.projectScanCachePath?` (${o.basename(p.projectScanCachePath)})`:""}`)),p.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence refreshed: ${p.evidencePath}`));}}else r>0&&await ae(n.projects,false);}else console.log(l.bold.green(`
33
+ \u2705 All checks passed! Workspace is healthy.`));}else if(t){let c=await Et(process.cwd());c||(await oe(process.cwd())?(a.error("No backend project found in current directory within this workspace"),a.info("Run this command from inside a project directory in the workspace")):a.error("No RapidKit project found in current directory or parents"),a.info('Run this command from within a project, or use "rapidkit doctor workspace" for workspace checks'),process.exit(1));let n=await $t(c),r=n.workspacePath?Pe(n.workspacePath):null,d=Pe(n.project.path);if(e.json){let v={contract:re(),scope:"project",workspace:r?{name:o.basename(r),path:r}:null,project:{name:n.project.name,path:d,framework:n.project.framework,frameworkKey:n.project.frameworkKey,importStack:n.project.importStack,runtimeFamily:n.project.runtimeFamily,projectKind:n.project.projectKind,supportTier:n.project.supportTier,frameworkConfidence:n.project.frameworkConfidence,venvActive:n.project.venvActive,depsInstalled:n.project.depsInstalled,hasEnvFile:n.project.hasEnvFile,vulnerabilities:n.project.vulnerabilities,coreInstalled:n.project.coreInstalled,coreVersion:n.project.coreVersion,issues:n.project.issues,fixCommands:n.project.fixCommands,probes:n.project.probes},evidencePath:n.evidencePath,healthScore:n.healthScore,system:{python:n.python,poetry:n.poetry,pipx:n.pipx,go:n.go,rapidkitCore:n.rapidkitCore},summary:{totalProjects:1,totalIssues:n.project.issues.length,projectAdvisoryWarningProjects:Q(n.project)>0?1:0,projectAdvisoryWarnings:Q(n.project),hasSystemErrors:[n.python,n.rapidkitCore].some(P=>P.status==="error"),scopeProvenance:n.scopeProvenance},driftDelta:n.driftDelta,scoreBreakdown:n.scoreBreakdown??[]};console.log(JSON.stringify(v,null,2));return}console.log(l.bold(`Project: ${l.cyan(o.basename(c))}`)),console.log(l.gray(`Path: ${c}`)),n.workspacePath&&console.log(l.gray(`Workspace: ${o.basename(n.workspacePath)}`)),n.evidencePath&&console.log(l.gray(`\u2139\uFE0F Evidence saved: ${n.evidencePath}`));let u=n.healthScore,m=u.total>0?Math.round(u.passed/u.total*100):0,p=m>=80?l.green:m>=50?l.yellow:l.red,g="\u2588".repeat(Math.floor(m/5))+"\u2591".repeat(20-Math.floor(m/5));console.log(l.bold(`
34
+ \u{1F4CA} Health Score:`)),console.log(` ${p(`${m}%`)} ${l.gray(g)}`),console.log(` ${l.green(`\u2705 ${u.passed} passed`)} ${l.gray("|")} ${l.yellow(`\u26A0\uFE0F ${u.warnings} warnings`)} ${l.gray("|")} ${l.red(`\u274C ${u.errors} errors`)}`),console.log(l.bold(`
35
+
36
+ System Tools:
37
+ `)),C(n.python,"Python"),C(n.poetry,"Poetry"),C(n.pipx,"pipx"),C(n.go,"Go"),C(n.rapidkitCore,"RapidKit Core"),console.log(l.bold(`
38
+ \u{1F4E6} Project (1):`)),Re(n.project);let f=[n.python,n.rapidkitCore].some(v=>v.status==="error"),y=n.project.issues.length,h=Q(n.project);if(f||y>0||h>0){let v=h>0?` and ${h} advisory warning(s)`:"";console.log(l.bold.yellow(`
39
+ \u26A0\uFE0F Found ${y} project issue(s)${v}`)),f&&console.log(l.bold.red("\u274C System requirements not met")),e.fix?await ae([n.project],true):y>0&&await ae([n.project],false);}else console.log(l.bold.green(`
40
+ \u2705 All checks passed! Project is healthy.`));}else {console.log(l.bold(`System Tools:
41
+ `));let c=await ye(),n=c.python,r=c.poetry,d=c.pipx,u=c.go,m=c.rapidkitCore;C(n,"Python"),C(r,"Poetry"),C(d,"pipx"),C(u,"Go"),C(m,"RapidKit Core"),[n,m].some(g=>g.status==="error")?(console.log(l.bold.red(`
42
+ \u274C Some required tools are missing`)),e.fix&&console.log(l.gray(`
43
+ Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(l.gray(`
44
+ Tip: Run "rapidkit doctor workspace" for detailed project checks`))):(console.log(l.bold.green(`
45
+ \u2705 All required tools are installed!`)),e.fix&&console.log(l.gray(`
46
+ Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(l.gray(`
47
+ Tip: Run "rapidkit doctor workspace" for detailed project checks`)));}console.log("");}export{Jt as runDoctor};
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  declare function handleCreateOrFallback(args: string[]): Promise<number>;
3
- declare const NPM_ONLY_TOP_LEVEL_COMMANDS: readonly ["readiness", "doctor", "workspace", "bootstrap", "setup", "cache", "mirror", "ai", "config", "shell"];
3
+ declare const NPM_ONLY_TOP_LEVEL_COMMANDS: readonly ["readiness", "doctor", "import", "workspace", "bootstrap", "setup", "cache", "mirror", "ai", "config", "shell"];
4
4
  declare const WRAPPER_ORCHESTRATED_PROJECT_COMMANDS: readonly ["init"];
5
5
  interface DoctorWorkspaceShadowDiagnostic {
6
6
  detected: boolean;
@@ -11,6 +11,15 @@ declare function detectWindowsDoctorWorkspaceShadow(params: {
11
11
  scope?: string;
12
12
  workspaceFlag?: boolean;
13
13
  }, cwd?: string, platform?: NodeJS.Platform): Promise<DoctorWorkspaceShadowDiagnostic>;
14
+ declare function handleImportCommand(source: string, options: {
15
+ workspace?: string;
16
+ name?: string;
17
+ git?: boolean;
18
+ json?: boolean;
19
+ }, dependencies?: {
20
+ syncWorkspaceProjects?: (workspacePath: string) => Promise<void>;
21
+ rollbackImportedProjectImport?: (workspacePath: string, projectPath: string) => Promise<void>;
22
+ }): Promise<number>;
14
23
  declare function installWorkspaceDependencies(workspacePath: string): Promise<number>;
15
24
  declare function handleBootstrapCommand(args: string[], initRunner?: (nextArgs: string[]) => Promise<number>): Promise<number>;
16
25
  declare function handleSetupCommand(args: string[]): Promise<number>;
@@ -19,4 +28,4 @@ declare function handleMirrorCommand(args: string[]): Promise<number>;
19
28
  declare function handleInitCommand(args: string[]): Promise<number>;
20
29
  declare function shouldForwardToCore(args: string[]): Promise<boolean>;
21
30
 
22
- export { type DoctorWorkspaceShadowDiagnostic, NPM_ONLY_TOP_LEVEL_COMMANDS, WRAPPER_ORCHESTRATED_PROJECT_COMMANDS, detectWindowsDoctorWorkspaceShadow, handleBootstrapCommand, handleCacheCommand, handleCreateOrFallback, handleInitCommand, handleMirrorCommand, handleSetupCommand, installWorkspaceDependencies, shouldForwardToCore };
31
+ export { type DoctorWorkspaceShadowDiagnostic, NPM_ONLY_TOP_LEVEL_COMMANDS, WRAPPER_ORCHESTRATED_PROJECT_COMMANDS, detectWindowsDoctorWorkspaceShadow, handleBootstrapCommand, handleCacheCommand, handleCreateOrFallback, handleImportCommand, handleInitCommand, handleMirrorCommand, handleSetupCommand, installWorkspaceDependencies, shouldForwardToCore };