rapidkit 0.25.7 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -5
- package/dist/{create-27NVMJAR.js → create-3V7O72CO.js} +20 -15
- package/dist/demo-kit-HMJZ3A3M.js +141 -0
- package/dist/doctor-JEBQTQQE.js +38 -0
- package/dist/index.js +188 -169
- package/dist/package.json +4 -2
- package/dist/springboot-standard-AGTOOTNT.js +697 -0
- package/dist/{workspace-VXNLNKCM.js → workspace-7JHX7L3E.js} +86 -68
- package/package.json +4 -2
- package/dist/demo-kit-63CFMCPD.js +0 -141
- package/dist/doctor-P57TTWEP.js +0 -38
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
> RapidKit is an open-source workspace platform that standardizes how teams build, scale, and deploy backend services.
|
|
4
4
|
|
|
5
|
-
FastAPI, NestJS, Go/Fiber, and Go/Gin scaffolding with production-ready defaults.
|
|
6
|
-
**27+ plug-and-play modules** are available for FastAPI & NestJS projects.
|
|
5
|
+
FastAPI, NestJS, Spring Boot, Go/Fiber, and Go/Gin scaffolding with production-ready defaults.
|
|
6
|
+
**27+ plug-and-play modules** are available for FastAPI & NestJS projects. Spring Boot and Go kits run as npm-level generators.
|
|
7
7
|
Clean architecture • Zero boilerplate • Instant deployment.
|
|
8
8
|
|
|
9
9
|
> **💡 Recommended:** Install the [Workspai VS Code extension](https://github.com/getrapidkit/rapidkit-vscode) for AI-powered project creation, a visual workspace explorer, and context-aware coding assistance — all backed by this CLI.
|
|
@@ -17,7 +17,7 @@ Clean architecture • Zero boilerplate • Instant deployment.
|
|
|
17
17
|
Official CLI for creating and operating RapidKit workspaces and projects.
|
|
18
18
|
|
|
19
19
|
- Workspace-first lifecycle (`create workspace` → `bootstrap` → `setup` → `create project`)
|
|
20
|
-
- Multi-runtime support (Python, Node.js, Go)
|
|
20
|
+
- Multi-runtime support (Python, Node.js, Java, Go)
|
|
21
21
|
- Profile + policy enforcement (`warn` / `strict`)
|
|
22
22
|
- Cache and mirror lifecycle commands for stable environments
|
|
23
23
|
|
|
@@ -38,6 +38,7 @@ It works alongside Workspai, which is a product developed by RapidKit.
|
|
|
38
38
|
|
|
39
39
|
- Node.js `>= 20.19.6`
|
|
40
40
|
- Python `>= 3.10` (for Python/Core workflows)
|
|
41
|
+
- Java 21+ and Maven 3.9+ (optional, for Spring Boot projects)
|
|
41
42
|
- Go (optional, for Go projects)
|
|
42
43
|
|
|
43
44
|
## Install
|
|
@@ -69,6 +70,7 @@ cd my-workspace
|
|
|
69
70
|
npx rapidkit bootstrap --profile polyglot
|
|
70
71
|
npx rapidkit setup python
|
|
71
72
|
npx rapidkit setup node --warm-deps
|
|
73
|
+
npx rapidkit setup java --warm-deps
|
|
72
74
|
npx rapidkit setup go --warm-deps
|
|
73
75
|
```
|
|
74
76
|
|
|
@@ -76,7 +78,9 @@ npx rapidkit setup go --warm-deps
|
|
|
76
78
|
|
|
77
79
|
```bash
|
|
78
80
|
npx rapidkit create project fastapi.standard my-api --yes --skip-install
|
|
81
|
+
npx rapidkit create project fastapi.ddd my-api --yes --skip-install
|
|
79
82
|
npx rapidkit create project nestjs.standard my-nest --yes --skip-install
|
|
83
|
+
npx rapidkit create project springboot.standard my-spring --yes --skip-install
|
|
80
84
|
npx rapidkit create project gofiber.standard my-fiber --yes --skip-install
|
|
81
85
|
```
|
|
82
86
|
|
|
@@ -88,14 +92,38 @@ npx rapidkit create project gofiber.standard my-fiber --yes --skip-install
|
|
|
88
92
|
npx rapidkit create # Prompts: workspace | project
|
|
89
93
|
npx rapidkit create workspace <name> [--profile <profile>] [--author <name>] [--yes]
|
|
90
94
|
npx rapidkit bootstrap [--profile <profile>] [--json]
|
|
91
|
-
npx rapidkit setup <python|node|go> [--warm-deps]
|
|
95
|
+
npx rapidkit setup <python|node|go|java> [--warm-deps]
|
|
92
96
|
npx rapidkit workspace policy show
|
|
93
97
|
npx rapidkit workspace policy set <key> <value>
|
|
94
98
|
npx rapidkit doctor
|
|
95
99
|
npx rapidkit doctor workspace [--fix]
|
|
96
100
|
npx rapidkit workspace list # Display all workspaces created on this system
|
|
101
|
+
npx rapidkit workspace share [--output <file>] [--include-paths] [--no-doctor]
|
|
97
102
|
```
|
|
98
103
|
|
|
104
|
+
### Workspace collaboration bundle
|
|
105
|
+
|
|
106
|
+
Use `workspace share` to export a portable JSON snapshot for team handoff,
|
|
107
|
+
debugging, and cross-machine diagnostics.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npx rapidkit workspace share
|
|
111
|
+
# default output: .rapidkit/reports/share-bundle.json
|
|
112
|
+
|
|
113
|
+
npx rapidkit workspace share --output ./team-share.json
|
|
114
|
+
npx rapidkit workspace share --include-paths
|
|
115
|
+
npx rapidkit workspace share --no-doctor
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Bundle content includes:
|
|
119
|
+
|
|
120
|
+
- Workspace metadata (`name`, `profile`, RapidKit version)
|
|
121
|
+
- Discovered RapidKit projects (`relative_path`, runtime, kit)
|
|
122
|
+
- Workspace and project report file index
|
|
123
|
+
- Latest doctor evidence per project (unless `--no-doctor` is used)
|
|
124
|
+
|
|
125
|
+
`--include-paths` is intended for internal teams only because it includes absolute filesystem paths.
|
|
126
|
+
|
|
99
127
|
### Command ownership
|
|
100
128
|
|
|
101
129
|
RapidKit keeps the wrapper boundary explicit so users know which layer owns each action.
|
|
@@ -138,10 +166,11 @@ npx rapidkit mirror <status|sync|verify|rotate>
|
|
|
138
166
|
## Profiles
|
|
139
167
|
|
|
140
168
|
- `minimal` — baseline workspace scaffolding
|
|
169
|
+
- `java-only` — Java-focused workspace
|
|
141
170
|
- `python-only` — Python-focused workspace
|
|
142
171
|
- `node-only` — Node.js-focused workspace
|
|
143
172
|
- `go-only` — Go-focused workspace
|
|
144
|
-
- `polyglot` — Python + Node.js + Go
|
|
173
|
+
- `polyglot` — Python + Node.js + Go + Java
|
|
145
174
|
- `enterprise` — polyglot + governance-oriented checks
|
|
146
175
|
|
|
147
176
|
## Policy Modes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {i,d as d$2,l,k,f as f$1,g,h}from'./chunk-ZAZJEYYT.js';import {a
|
|
1
|
+
import {i,d as d$2,l,k,f as f$1,g,h}from'./chunk-ZAZJEYYT.js';import {a,d,b as b$1}from'./chunk-RV6HBTFC.js';import {a as a$2,e,d as d$1,f,c,k as k$1}from'./chunk-Z5LKRG57.js';import {b}from'./chunk-Q7ULIFQA.js';import {a as a$1}from'./chunk-VM2TOHNX.js';import {promises}from'fs';import*as v from'fs-extra';import m from'path';import U from'inquirer';import o from'chalk';import z from'ora';import {execa}from'execa';function C(){return c()}async function et(t,n,e,r){let s=d(n,b(),e);r&&(s.metadata||(s.metadata={}),s.metadata.python={version:r}),await b$1(t,s);}async function H(t){await v.outputFile(m.join(t,".gitignore"),`.venv/
|
|
2
2
|
__pycache__/
|
|
3
3
|
*.pyc
|
|
4
4
|
.env
|
|
@@ -20,7 +20,7 @@ rapidkit-core = "*"
|
|
|
20
20
|
[build-system]
|
|
21
21
|
requires = ["poetry-core"]
|
|
22
22
|
build-backend = "poetry.core.masonry.api"
|
|
23
|
-
`,"utf-8");}function mt(t,n,e,r){return JSON.stringify({schema_version:"1.0",workspace_name:t,rapidkit_version:b(),created_at:new Date().toISOString(),created_by:"rapidkit-npm",profile:r||"minimal",engine:{install_method:n,python_version:e||null}},null,2)}function yt(t,n,e,r){return JSON.stringify({schema_version:"1.0",generated_by:"rapidkit-npm",generated_at:new Date().toISOString(),runtime:{python:{version:n||null,install_method:t},node:{version:e||process.version},go:{version:r||null}}},null,2)}function gt(){return `version: "1.0"
|
|
23
|
+
`,"utf-8");}function mt(t,n,e,r){return JSON.stringify({schema_version:"1.0",workspace_name:t,rapidkit_version:b(),created_at:new Date().toISOString(),created_by:"rapidkit-npm",profile:r||"minimal",engine:{install_method:n,python_version:e||null}},null,2)}function yt(t,n,e,r){return JSON.stringify({schema_version:"1.0",generated_by:"rapidkit-npm",generated_at:new Date().toISOString(),runtime:{python:{version:n||null,install_method:t},node:{version:e||process.version},go:{version:r||null},java:{version:null,build_tool:null,build_tool_version:null}}},null,2)}function gt(){return `version: "1.0"
|
|
24
24
|
mode: warn # "warn" or "strict"
|
|
25
25
|
dependency_sharing_mode: isolated # "isolated" or "shared-runtime-caches" or "shared-node-deps"
|
|
26
26
|
# change profile (recommended): npx rapidkit bootstrap --profile polyglot
|
|
@@ -40,7 +40,7 @@ cache:
|
|
|
40
40
|
|
|
41
41
|
Try reopening your terminal or run: ${e} -m pipx ensurepath`))}}async function F(t,n){return t.kind==="binary"?execa("pipx",n):execa(t.pythonCmd,["-m","pipx",...n])}function Et(t){let n=t.match(/^(\d+)\.(\d+)/);return n?`${n[1]}.${n[2]}`:null}function ut(t){if(!t)return null;let n=t.match(/Python\s+(\d+)\.(\d+)(?:\.\d+)?/i);return n?`${n[1]}.${n[2]}`:null}function it(t,n){let[e,r]=t.split(".").map(u=>Number(u)),[s,d]=n.split(".").map(u=>Number(u));return e!==s?e-s:r-d}function K(t,n){return it(t,n)>=0}async function Ct(t){let n=new Set,e$1=e(14,10);for(let i of e$1)try{let a=await execa(i.command,i.args,{timeout:2500}),p=ut(`${a.stdout||""}
|
|
42
42
|
${a.stderr||""}`);p&&K(p,A)&&n.add(p);}catch{}let r=null;try{let i=await execa(C(),["--version"],{timeout:2500}),a=ut(`${i.stdout||""}
|
|
43
|
-
${i.stderr||""}`);a&&K(a,A)&&(r=a,n.add(a));}catch{}let s=ft.filter(i=>K(i,A)),d=new Set([...s,...n]),u=Array.from(d).sort((i,a)=>it(a,i)),g=t?Et(t):null,y=g&&K(g,A)?g:r||u[0]||A;return d.has(y)||d.add(y),{choices:Array.from(d).sort((i,a)=>it(a,i)).map(i=>{let a=[];return i===r&&a.push("current system"),i===A&&a.push("minimum supported"),n.has(i)&&i!==r&&a.push("detected"),{name:a.length>0?`${i} (${a.join(", ")})`:i,value:i}}),defaultValue:y}}async function $t(){D();let t=false,n=false;try{await execa("poetry",["--version"],{timeout:2500}),t=true;}catch{t=false;}try{await execa("pipx",["--version"],{timeout:2500}),n=true;}catch{let e=c();try{await execa(e,["-m","pipx","--version"],{timeout:2500}),n=true;}catch{n=false;}}return {poetry:t,pipx:n}}async function wt(){D();try{return await execa("poetry",["--version"],{timeout:2500}),true}catch{return false}}function
|
|
43
|
+
${i.stderr||""}`);a&&K(a,A)&&(r=a,n.add(a));}catch{}let s=ft.filter(i=>K(i,A)),d=new Set([...s,...n]),u=Array.from(d).sort((i,a)=>it(a,i)),g=t?Et(t):null,y=g&&K(g,A)?g:r||u[0]||A;return d.has(y)||d.add(y),{choices:Array.from(d).sort((i,a)=>it(a,i)).map(i=>{let a=[];return i===r&&a.push("current system"),i===A&&a.push("minimum supported"),n.has(i)&&i!==r&&a.push("detected"),{name:a.length>0?`${i} (${a.join(", ")})`:i,value:i}}),defaultValue:y}}async function $t(){D();let t=false,n=false;try{await execa("poetry",["--version"],{timeout:2500}),t=true;}catch{t=false;}try{await execa("pipx",["--version"],{timeout:2500}),n=true;}catch{let e=c();try{await execa(e,["-m","pipx","--version"],{timeout:2500}),n=true;}catch{n=false;}}return {poetry:t,pipx:n}}async function wt(){D();try{return await execa("poetry",["--version"],{timeout:2500}),true}catch{return false}}function St(t,n){return t==="poetry"&&n.poetry?"poetry":t==="pipx"&&n.pipx?"pipx":t==="venv"?"venv":n.poetry?"poetry":"venv"}async function Mt(t,n){D(),t.start("Checking Poetry installation");try{await execa("poetry",["--version"]),t.succeed("Poetry found");return}catch{}if(n)throw new g;let{installPoetry:e}=await U.prompt([{type:"confirm",name:"installPoetry",message:"Poetry is not installed. Install it now using pipx?",default:true}]);if(!e)throw new g;let r=await q(t,n);t.start("Installing Poetry with pipx");try{await F(r,["install","poetry"]);}catch(s){let d=s,u=String(d?.stderr||d?.shortMessage||d?.message||"");if(/already\s+installed|already\s+seems\s+to\s+be\s+installed|exists/i.test(u))try{await F(r,["upgrade","poetry"]);}catch{}else throw new k("Install Poetry with pipx",s instanceof Error?s:new Error(u))}t.succeed("Poetry installed"),D();try{await execa("poetry",["--version"]);}catch(s){let d=s,u=String(d?.stderr||d?.shortMessage||d?.message||"Poetry not found on PATH");throw new k("Verify Poetry after pipx install",new Error(`${u}
|
|
44
44
|
|
|
45
45
|
Poetry may be installed but not on PATH yet. Try reopening your terminal or run: pipx ensurepath`))}}function At(t){let n=t==="poetry";return `#!/usr/bin/env sh
|
|
46
46
|
set -eu
|
|
@@ -80,7 +80,7 @@ if %ERRORLEVEL%==0 if exist "%SCRIPT_DIR%\\pyproject.toml" (
|
|
|
80
80
|
`:""}echo RapidKit launcher could not find a local Python CLI. 1>&2
|
|
81
81
|
echo Tip: run .venv\\Scripts\\rapidkit.exe --help 1>&2
|
|
82
82
|
exit /b 1
|
|
83
|
-
`}async function vt(t,n){await v.outputFile(m.join(t,"rapidkit"),At(n),{encoding:"utf-8",mode:493}),await v.outputFile(m.join(t,"rapidkit.cmd"),Dt(n),"utf-8");}async function oe(t,n){let{skipGit:e=false,testMode:r=false,demoMode:s=false,dryRun:d=false,yes:u=false,userConfig:g={},installMethod:y,profile:h}=n,c=t||"rapidkit",i$1=m.resolve(process.cwd(),c);if(await v.pathExists(i$1))throw new i(c);if(d){await Ft(i$1,c,s,g);return}if(s){await Kt(i$1,c,e);return}let a=new Set(["python-only","polyglot","enterprise"]),p=h||"";if(!u&&!h){let{selectedProfile:f}=await U.prompt([{type:"rawlist",name:"selectedProfile",message:"Select workspace profile:",choices:[{name:"minimal \u2014 Foundation files only (fastest bootstrap, mixed projects)",value:"minimal"},{name:"python-only \u2014 Python + Poetry (FastAPI, Django, ML pipelines)",value:"python-only"},{name:"node-only \u2014 Node.js runtime (NestJS, Express, Next.js)",value:"node-only"},{name:"go-only \u2014 Go runtime (Fiber, Gin, gRPC, microservices)",value:"go-only"},{name:"polyglot \u2014 Python + Node.js + Go multi-runtime workspace",value:"polyglot"},{name:"enterprise \u2014 Polyglot + governance + Sigstore verification",value:"enterprise"}],default:1}]);p=f;}else p||(p="minimal");let b=!u&&a.has(p),E=typeof g.pythonVersion=="string"&&g.pythonVersion.trim().length>0?g.pythonVersion.trim():void 0,
|
|
83
|
+
`}async function vt(t,n){await v.outputFile(m.join(t,"rapidkit"),At(n),{encoding:"utf-8",mode:493}),await v.outputFile(m.join(t,"rapidkit.cmd"),Dt(n),"utf-8");}async function oe(t,n){let{skipGit:e=false,testMode:r=false,demoMode:s=false,dryRun:d=false,yes:u=false,userConfig:g={},installMethod:y,profile:h}=n,c=t||"rapidkit",i$1=m.resolve(process.cwd(),c);if(await v.pathExists(i$1))throw new i(c);if(d){await Ft(i$1,c,s,g);return}if(s){await Kt(i$1,c,e);return}let a=new Set(["python-only","polyglot","enterprise"]),p=h||"";if(!u&&!h){let{selectedProfile:f}=await U.prompt([{type:"rawlist",name:"selectedProfile",message:"Select workspace profile:",choices:[{name:"minimal \u2014 Foundation files only (fastest bootstrap, mixed projects)",value:"minimal"},{name:"java-only \u2014 Java runtime (Spring Boot services)",value:"java-only"},{name:"python-only \u2014 Python + Poetry (FastAPI, Django, ML pipelines)",value:"python-only"},{name:"node-only \u2014 Node.js runtime (NestJS, Express, Next.js)",value:"node-only"},{name:"go-only \u2014 Go runtime (Fiber, Gin, gRPC, microservices)",value:"go-only"},{name:"polyglot \u2014 Python + Node.js + Go + Java multi-runtime workspace",value:"polyglot"},{name:"enterprise \u2014 Polyglot + governance + Sigstore verification",value:"enterprise"}],default:1}]);p=f;}else p||(p="minimal");let b=!u&&a.has(p),E=typeof g.pythonVersion=="string"&&g.pythonVersion.trim().length>0?g.pythonVersion.trim():void 0,S=y||g.defaultInstallMethod||"poetry",I=b?await $t():{poetry:true,pipx:true},T=b?await Ct(E):{choices:ft.map(f=>({name:f,value:f})),defaultValue:A},Y=St(S,I),It=[{name:I.poetry?"\u{1F3AF} Poetry (Recommended - includes virtual env)":"\u{1F3AF} Poetry (Recommended - includes virtual env) \u2014 not detected (we can install it)",value:"poetry"},{name:"\u{1F4E6} pip with venv (Standard, zero extra tools)",value:"venv"},{name:I.pipx?"\u{1F527} pipx (Global isolated install)":"\u{1F527} pipx (Global isolated install) \u2014 not detected (we can install it)",value:"pipx"}],x=b?await U.prompt([{type:"rawlist",name:"pythonVersion",message:"Select Python version for RapidKit:",choices:T.choices,default:T.defaultValue},{type:"rawlist",name:"installMethod",message:"How would you like to manage the workspace environment?",choices:It,default:Y}]):await(async()=>{let f=y||g.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"}})();return {pythonVersion:g.pythonVersion||"3.10",installMethod:f}})();if(new Set(["go-only","java-only","node-only","minimal"]).has(p)){let f=z("Creating workspace").start();try{await v.ensureDir(i$1),f.succeed("Directory created"),await et(i$1,c,"venv",void 0),await nt(i$1,c,"venv",void 0,p),await H(i$1),await ot(i$1,c);let R={"go-only":"Go-only","java-only":"Java-only","node-only":"Node.js-only",minimal:"Minimal"};if(await v.outputFile(m.join(i$1,"README.md"),`# ${c}
|
|
84
84
|
|
|
85
85
|
RapidKit **${R[p]}** workspace.
|
|
86
86
|
|
|
@@ -91,6 +91,10 @@ RapidKit **${R[p]}** workspace.
|
|
|
91
91
|
cd my-api
|
|
92
92
|
npx rapidkit init
|
|
93
93
|
npx rapidkit dev
|
|
94
|
+
`:p==="java-only"?`npx rapidkit create project springboot.standard my-service
|
|
95
|
+
cd my-service
|
|
96
|
+
npx rapidkit init
|
|
97
|
+
npx rapidkit dev
|
|
94
98
|
`:p==="node-only"?`npx rapidkit create project nestjs.standard my-app
|
|
95
99
|
cd my-app
|
|
96
100
|
npx rapidkit init
|
|
@@ -99,28 +103,29 @@ npx rapidkit dev
|
|
|
99
103
|
cd <project-name>
|
|
100
104
|
npx rapidkit init
|
|
101
105
|
npx rapidkit dev
|
|
102
|
-
`)+"```\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-
|
|
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(`
|
|
103
107
|
\u2728 Workspace created!
|
|
104
108
|
`)),console.log(o.cyan("\u{1F4C2} Location:"),o.white(i$1)),console.log(o.cyan(`
|
|
105
109
|
\u{1F680} Get started:
|
|
106
110
|
`)),console.log(o.white(` cd ${c}`)),p==="go-only"){console.log(o.white(" npx rapidkit create project gofiber.standard my-api")),console.log(o.white(" cd my-api")),console.log(o.white(" npx rapidkit init")),console.log(o.white(` npx rapidkit dev
|
|
107
|
-
`)),console.log(o.gray("\u{1F4A1} No Python required \u2014 Go kits run entirely through the npm package."));try{let{stdout:k}=await execa("go",["version"],{timeout:3e3}),_=k.match(/go version go(\d+\.\d+(?:\.\d+)?)/),
|
|
108
|
-
\u26A0\uFE0F Go is not installed \u2014 install it from https://go.dev/dl/`));}}else p==="
|
|
111
|
+
`)),console.log(o.gray("\u{1F4A1} No Python required \u2014 Go kits run entirely through the npm package."));try{let{stdout:k}=await execa("go",["version"],{timeout:3e3}),_=k.match(/go version go(\d+\.\d+(?:\.\d+)?)/),M=_?_[1]:"unknown";console.log(o.gray(`\u{1F439} Go ${M} detected \u2014 ready for gofiber.standard / gogin.standard projects`));}catch{console.log(o.yellow(`
|
|
112
|
+
\u26A0\uFE0F Go is not installed \u2014 install it from https://go.dev/dl/`));}}else p==="java-only"?(console.log(o.white(" npx rapidkit create project springboot.standard my-service")),console.log(o.white(" cd my-service")),console.log(o.white(" npx rapidkit init")),console.log(o.white(` npx rapidkit dev
|
|
113
|
+
`)),console.log(o.gray("\u{1F4A1} No Python required \u2014 Spring Boot kit runs through the npm package with Java tooling."))):p==="node-only"?(console.log(o.white(" npx rapidkit create project nestjs.standard my-app")),console.log(o.white(" cd my-app")),console.log(o.white(" npx rapidkit init")),console.log(o.white(` npx rapidkit dev
|
|
109
114
|
`)),console.log(o.gray("\u{1F4A1} Python engine will be installed automatically on first `create project nestjs.standard`."))):(console.log(o.white(" npx rapidkit create project")),console.log(o.white(" cd <project-name>")),console.log(o.white(" npx rapidkit init")),console.log(o.white(` npx rapidkit dev
|
|
110
|
-
`)),console.log(o.gray("\u{1F4A1} Bootstrap a specific runtime any time: rapidkit bootstrap --profile python-only|node-only|go-only")));console.log("");}catch(R){throw f.fail("Failed to create workspace"),console.error(o.red(`
|
|
115
|
+
`)),console.log(o.gray("\u{1F4A1} Bootstrap a specific runtime any time: rapidkit bootstrap --profile java-only|python-only|node-only|go-only")));console.log("");}catch(R){throw f.fail("Failed to create workspace"),console.error(o.red(`
|
|
111
116
|
\u274C Error:`),R),R}return}{let f=C(),R=false;try{await execa(f,["--version"],{timeout:5e3}),R=true;}catch{try{await execa("python",["--version"],{timeout:5e3}),R=true;}catch{R=false;}}R||(console.log(o.red(`
|
|
112
117
|
\u274C Python 3.10+ is required for the "${p}" profile.
|
|
113
118
|
`)),console.log(o.cyan(`\u{1F4A1} How to install Python:
|
|
114
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
|
|
115
120
|
`)),console.log(o.gray(` After installing Python, run: npx rapidkit ${c}
|
|
116
|
-
`)),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-
|
|
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(`
|
|
117
122
|
\u2728 RapidKit environment created successfully!
|
|
118
123
|
`)),console.log(o.cyan("\u{1F4C2} Location:"),o.white(i$1)),console.log(o.cyan(`\u{1F680} Get started:
|
|
119
|
-
`)),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"]),
|
|
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(`
|
|
120
125
|
\u{1F4A1} For more information, check the README.md file.`)),console.log(o.cyan(`
|
|
121
126
|
\u{1F4DA} RapidKit commands:`)),console.log(o.white(" rapidkit create - Create a new project (interactive)")),console.log(o.white(" rapidkit dev - Run development server")),console.log(o.white(" rapidkit add module <name> - Add a module (e.g., settings)")),console.log(o.white(" rapidkit list - List available kits")),console.log(o.white(" rapidkit modules - List available modules")),console.log(o.white(` rapidkit --help - Show all commands
|
|
122
|
-
`));try{let{stdout:k}=await execa("go",["version"],{timeout:3e3}),_=k.match(/go version go(\d+\.\d+(?:\.\d+)?)/),
|
|
123
|
-
\u274C Error:`),f);try{await v.remove(i$1);}catch{}throw f}}async function kt(t){let n=[];if(!a$2())try{let{stdout:d}=await execa("pyenv",["which","python"]),u=d.trim();u&&n.push(u);}catch{}let e$1=Number(t.split(".")[1]),r=e(e$1,10).map(d=>d.command).filter(Boolean);n.push(`python${t}`,...r,...d$1());let s=[...new Set(n)];for(let d of s)try{let u=d==="py"?["-3","--version"]:["--version"],g=d==="py"?["-3","-c","import sys; sys.exit(0)"]:["-c","import sys; sys.exit(0)"],{stdout:y}=await execa(d,u,{timeout:2e3}),h=y.match(/Python (\d+\.\d+)/)?.[1];if(h&&K(h,t))return await execa(d,g,{timeout:2e3}),d}catch{continue}return null}async function bt(t,n,e,r,s,d=false){await
|
|
127
|
+
`));try{let{stdout:k}=await execa("go",["version"],{timeout:3e3}),_=k.match(/go version go(\d+\.\d+(?:\.\d+)?)/),M=_?_[1]:"unknown";console.log(o.gray(`\u{1F439} Go toolchain: Go ${M} detected \u2014 ready for gofiber.standard projects`));}catch{console.log(o.yellow("\u26A0\uFE0F Go toolchain not installed \u2014 needed for gofiber.standard projects")),console.log(o.gray(" Install: https://go.dev/dl/"));}console.log("");}catch(f){P.fail("Failed to create RapidKit environment"),console.error(o.red(`
|
|
128
|
+
\u274C Error:`),f);try{await v.remove(i$1);}catch{}throw f}}async function kt(t){let n=[];if(!a$2())try{let{stdout:d}=await execa("pyenv",["which","python"]),u=d.trim();u&&n.push(u);}catch{}let e$1=Number(t.split(".")[1]),r=e(e$1,10).map(d=>d.command).filter(Boolean);n.push(`python${t}`,...r,...d$1());let s=[...new Set(n)];for(let d of s)try{let u=d==="py"?["-3","--version"]:["--version"],g=d==="py"?["-3","-c","import sys; sys.exit(0)"]:["-c","import sys; sys.exit(0)"],{stdout:y}=await execa(d,u,{timeout:2e3}),h=y.match(/Python (\d+\.\d+)/)?.[1];if(h&&K(h,t))return await execa(d,g,{timeout:2e3}),d}catch{continue}return null}async function bt(t,n,e,r,s,d=false){await Mt(e,d),e.start("Finding Python interpreter");let u=await kt(n);u?(a$1.debug(`Found working Python: ${u}`),e.succeed("Python found")):e.warn("Could not verify Python path, proceeding with default"),e.start("Initializing Poetry project");let g=m.join(t,"pyproject.toml"),h=(await v.pathExists(g)?await promises.readFile(g,"utf-8"):"").includes("rapidkit-core");if(h)e.succeed("Poetry project initialized");else {await execa("poetry",["init","--no-interaction","--python",`^${n}`],{cwd:t}),e.succeed("Poetry project initialized");let p=await promises.readFile(g,"utf-8");p.includes("[tool.poetry]")?p=p.replace("[tool.poetry]",`[tool.poetry]
|
|
124
129
|
package-mode = false`):p.includes("[project]")&&(p.includes("[build-system]")?p=p.replace("[build-system]",`
|
|
125
130
|
[tool.poetry]
|
|
126
131
|
package-mode = false
|
|
@@ -129,13 +134,13 @@ package-mode = false
|
|
|
129
134
|
|
|
130
135
|
[tool.poetry]
|
|
131
136
|
package-mode = false
|
|
132
|
-
`),await promises.writeFile(g,p,"utf-8");}e.start("Configuring Poetry");try{await execa("poetry",["config","virtualenvs.in-project","true","--local"],{cwd:t}),e.succeed("Poetry configured");}catch{e.warn("Could not configure Poetry virtualenvs.in-project");}e.start("Creating virtualenv");let c=u||C(),i=f(m.join(t,".venv"));try{await execa(c,["-m","venv",".venv"],{cwd:t,timeout:6e4}),e.succeed("Virtualenv created");}catch(a){a$1.debug(`python -m venv failed: ${a}`),e.warn("Could not pre-create virtualenv, Poetry will try"),i=u||C();}try{await execa("poetry",["env","use",i||C()],{cwd:t}),a$1.debug(`Poetry env set to: ${i}`);}catch(a){a$1.debug(`Could not set Poetry env: ${a}`);}if(e.start("Installing RapidKit"),h&&!r){let a=d$2(s||{}),p=a?await v.pathExists(a):false,b=p&&a?a:"rapidkit-core";a&&!p&&a$1.warn(`RAPIDKIT_DEV_PATH is set but path does not exist: ${a}. Falling back to PyPI.`),e.text=p?"Installing RapidKit from local path":"Installing RapidKit from PyPI";let E=false,
|
|
137
|
+
`),await promises.writeFile(g,p,"utf-8");}e.start("Configuring Poetry");try{await execa("poetry",["config","virtualenvs.in-project","true","--local"],{cwd:t}),e.succeed("Poetry configured");}catch{e.warn("Could not configure Poetry virtualenvs.in-project");}e.start("Creating virtualenv");let c=u||C(),i=f(m.join(t,".venv"));try{await execa(c,["-m","venv",".venv"],{cwd:t,timeout:6e4}),e.succeed("Virtualenv created");}catch(a){a$1.debug(`python -m venv failed: ${a}`),e.warn("Could not pre-create virtualenv, Poetry will try"),i=u||C();}try{await execa("poetry",["env","use",i||C()],{cwd:t}),a$1.debug(`Poetry env set to: ${i}`);}catch(a){a$1.debug(`Could not set Poetry env: ${a}`);}if(e.start("Installing RapidKit"),h&&!r){let a=d$2(s||{}),p=a?await v.pathExists(a):false,b=p&&a?a:"rapidkit-core";a&&!p&&a$1.warn(`RAPIDKIT_DEV_PATH is set but path does not exist: ${a}. Falling back to PyPI.`),e.text=p?"Installing RapidKit from local path":"Installing RapidKit from PyPI";let E=false,S=null;for(let I=1;I<=3;I++)try{await execa(i,["-m","pip","install",b,"--quiet"],{cwd:t,timeout:18e4}),E=true;break}catch(T){S=T,a$1.debug(`pip install rapidkit-core attempt ${I} failed: ${T}`),I<3&&(e.text=`Retrying installation (attempt ${I+1}/3)`,await new Promise(Y=>setTimeout(Y,2e3)));}if(!E){let I=S?.stderr||S?.message||"Unknown error";throw a$1.debug(`All pip install attempts failed. Last error: ${I}`),I.includes("Could not find")||I.includes("No matching distribution")?new l:new k("Install rapidkit-core with pip",new Error(`Failed to install rapidkit-core after 3 attempts.
|
|
133
138
|
Error: ${I}
|
|
134
139
|
|
|
135
140
|
Possible solutions:
|
|
136
141
|
1. Check your internet connection
|
|
137
142
|
2. Try installing manually: cd ${m.basename(t)} && poetry add rapidkit-core
|
|
138
|
-
3. Use venv method instead: npx rapidkit ${m.basename(t)} --install-method=venv`))}}else {e.text="Syncing Poetry environment";try{await execa("poetry",["install","--no-root"],{cwd:t,timeout:12e4}),e.succeed("Poetry environment synced");}catch(a){a$1.debug(`poetry install --no-root failed: ${a}`),e.warn("Could not sync Poetry environment, proceeding with add command");}if(e.start("Installing RapidKit"),r){let a=d$2(s||{});if(!a)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: ${a}`),e.text="Installing RapidKit from local path (test mode)",await execa("poetry",["add",a],{cwd:t});}else {e.text="Installing RapidKit from PyPI";let a=false,p=null;for(let b=1;b<=3;b++)try{await execa("poetry",["add","rapidkit-core"],{cwd:t,timeout:6e4*b}),a=true;break}catch(E){p=E,a$1.debug(`Poetry add attempt ${b} failed: ${E}`),b<3&&(e.text=`Retrying installation (attempt ${b+1}/3)`,await new Promise(
|
|
143
|
+
3. Use venv method instead: npx rapidkit ${m.basename(t)} --install-method=venv`))}}else {e.text="Syncing Poetry environment";try{await execa("poetry",["install","--no-root"],{cwd:t,timeout:12e4}),e.succeed("Poetry environment synced");}catch(a){a$1.debug(`poetry install --no-root failed: ${a}`),e.warn("Could not sync Poetry environment, proceeding with add command");}if(e.start("Installing RapidKit"),r){let a=d$2(s||{});if(!a)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: ${a}`),e.text="Installing RapidKit from local path (test mode)",await execa("poetry",["add",a],{cwd:t});}else {e.text="Installing RapidKit from PyPI";let a=false,p=null;for(let b=1;b<=3;b++)try{await execa("poetry",["add","rapidkit-core"],{cwd:t,timeout:6e4*b}),a=true;break}catch(E){p=E,a$1.debug(`Poetry add attempt ${b} failed: ${E}`),b<3&&(e.text=`Retrying installation (attempt ${b+1}/3)`,await new Promise(S=>setTimeout(S,2e3)));}if(!a){let b=p?.stderr||p?.message||"Unknown error";throw a$1.debug(`All Poetry install attempts failed. Last error: ${b}`),b.includes("Could not find")||b.includes("No matching distribution")?new l:new k("Install rapidkit-core with Poetry",new Error(`Failed to install rapidkit-core after 3 attempts.
|
|
139
144
|
Error: ${b}
|
|
140
145
|
|
|
141
146
|
Possible solutions:
|
|
@@ -154,7 +159,7 @@ Possible solutions:
|
|
|
154
159
|
1. Check your internet connection
|
|
155
160
|
2. Try installing manually: cd ${m.basename(t)} && ${f(".venv")} -m pip install rapidkit-core
|
|
156
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
|
|
157
|
-
`,"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-
|
|
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
|
|
158
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):
|
|
159
164
|
./rapidkit --help
|
|
160
165
|
# or:
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {b}from'./chunk-Q7ULIFQA.js';import {promises}from'fs';import a from'path';import E from'nunjucks';import t from'chalk';import _ from'ora';import {fileURLToPath}from'url';import {execa}from'execa';import N from'crypto';var P=fileURLToPath(import.meta.url),K=a.dirname(P);function T(i=32){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",v=N.randomBytes(i),r="";for(let p=0;p<i;p++)r+=e[v[p]%e.length];return r}async function U(i,e){let r=(e.template||"fastapi")==="fastapi",p=r?"FastAPI":"NestJS",d=e.kit_name||(r?"fastapi.standard":"nestjs.standard"),I=d.replace(".","/"),h=_(`Generating ${p} project...`).start();try{let u=a.resolve(K,".."),l;d==="fastapi.ddd"?l="fastapi-ddd":d.startsWith("fastapi")?l="fastapi-standard":l="nestjs-standard";let k=a.join(u,"templates","kits",l),w=E.configure(k,{autoescape:false,trimBlocks:true,lstripBlocks:true});w.addFilter("generate_secret",function(n,o=32){return T(o)});let S={project_name:e.project_name,author:e.author||"RapidKit User",description:e.description||(r?"FastAPI service generated with RapidKit":"NestJS application generated with RapidKit"),app_version:e.app_version||"0.1.0",license:e.license||"MIT",package_manager:e.package_manager||"npm",node_version:e.node_version||"20.0.0",database_type:e.database_type||"postgresql",include_caching:e.include_caching||false,created_at:new Date().toISOString(),rapidkit_version:b()},j;r?j=["src/main.py.j2","src/__init__.py.j2","src/cli.py.j2","src/routing/__init__.py.j2","src/routing/health.py.j2","src/modules/__init__.py.j2","tests/__init__.py.j2","README.md.j2","pyproject.toml.j2","Makefile.j2",".rapidkit/__init__.py.j2",".rapidkit/project.json.j2",".rapidkit/cli.py.j2",".rapidkit/rapidkit.j2",".rapidkit/activate.j2","rapidkit.j2","rapidkit.cmd.j2"]:j=["src/main.ts.j2","src/app.module.ts.j2","src/app.controller.ts.j2","src/app.service.ts.j2","src/config/configuration.ts.j2","src/config/validation.ts.j2","src/config/index.ts.j2","src/modules/index.ts.j2","src/examples/examples.module.ts.j2","src/examples/examples.controller.ts.j2","src/examples/examples.service.ts.j2","src/examples/dto/create-note.dto.ts.j2","test/app.controller.spec.ts.j2","test/examples.controller.spec.ts.j2","test/app.e2e-spec.ts.j2","test/jest-e2e.json.j2","package.json.j2","tsconfig.json.j2","tsconfig.build.json.j2","nest-cli.json.j2","jest.config.ts.j2","eslint.config.cjs.j2",".env.example.j2","docker-compose.yml.j2","Dockerfile.j2","README.md.j2",".rapidkit/project.json.j2",".rapidkit/rapidkit.j2",".rapidkit/rapidkit.cmd.j2",".rapidkit/activate.j2","rapidkit.j2","rapidkit.cmd.j2"];for(let n of j){let o=a.join(k,n);try{await promises.access(o);}catch{continue}let y=await promises.readFile(o,"utf-8"),m;try{m=w.renderString(y,S);}catch(R){throw console.error(`Failed to render template: ${n}`),R}let c=n.replace(/\.j2$/,""),f=a.join(i,c);await promises.mkdir(a.dirname(f),{recursive:true}),await promises.writeFile(f,m),(c.endsWith(".rapidkit/rapidkit")||c.endsWith(".rapidkit/cli.py")||c.endsWith(".rapidkit/activate")||c==="rapidkit")&&await promises.chmod(f,493);}if(r){let n=a.join(k,".rapidkit","context.json"),o=a.join(i,".rapidkit","context.json");try{await promises.mkdir(a.join(i,".rapidkit"),{recursive:true}),await promises.copyFile(n,o);}catch{await promises.mkdir(a.join(i,".rapidkit"),{recursive:true});let m=e.engine||"pip";await promises.writeFile(o,JSON.stringify({engine:m,created_by:"rapidkit-npm-fallback"},null,2));}}let x=a.join(i,".rapidkit");await promises.mkdir(x,{recursive:true});let F=a.join(x,"project.json"),A={kit_name:d,profile:I,created_at:new Date().toISOString(),created_by:"rapidkit-npm-fallback",runtime:r?"python":"node"};await promises.writeFile(F,JSON.stringify(A,null,2),"utf-8");let D=r?`# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.venv/
|
|
25
|
+
venv/
|
|
26
|
+
ENV/
|
|
27
|
+
env/
|
|
28
|
+
|
|
29
|
+
# IDEs
|
|
30
|
+
.vscode/
|
|
31
|
+
.idea/
|
|
32
|
+
*.swp
|
|
33
|
+
*.swo
|
|
34
|
+
*~
|
|
35
|
+
|
|
36
|
+
# OS
|
|
37
|
+
.DS_Store
|
|
38
|
+
Thumbs.db
|
|
39
|
+
|
|
40
|
+
# Project specific
|
|
41
|
+
.env
|
|
42
|
+
.env.local
|
|
43
|
+
`:`# Node artifacts
|
|
44
|
+
node_modules/
|
|
45
|
+
dist/
|
|
46
|
+
.tmp/
|
|
47
|
+
.env
|
|
48
|
+
.env.*
|
|
49
|
+
!.env.example
|
|
50
|
+
|
|
51
|
+
# Logs
|
|
52
|
+
logs/
|
|
53
|
+
*.log
|
|
54
|
+
npm-debug.log*
|
|
55
|
+
yarn-debug.log*
|
|
56
|
+
yarn-error.log*
|
|
57
|
+
pnpm-debug.log*
|
|
58
|
+
|
|
59
|
+
# OS
|
|
60
|
+
.DS_Store
|
|
61
|
+
Thumbs.db
|
|
62
|
+
|
|
63
|
+
# IDEs
|
|
64
|
+
.idea/
|
|
65
|
+
.vscode/
|
|
66
|
+
|
|
67
|
+
# Coverage
|
|
68
|
+
coverage/
|
|
69
|
+
`;if(await promises.writeFile(a.join(i,".gitignore"),D),h.succeed(`${p} project generated!`),!e.skipGit){let n=_("Initializing git repository...").start();try{await execa("git",["init"],{cwd:i}),await execa("git",["add","."],{cwd:i}),await execa("git",["commit","-m",`Initial commit: ${p} project via RapidKit`],{cwd:i}),n.succeed("Git repository initialized");}catch{n.warn("Could not initialize git repository");}}if(!r&&!e.skipInstall){let n=e.package_manager||"npm",o=_(`Installing dependencies with ${n}...`).start();try{await execa(n,n==="yarn"?["install"]:n==="pnpm"?["install"]:["install"],{cwd:i}),o.succeed("Dependencies installed");}catch{o.warn(`Could not install dependencies. Run '${n} install' manually.`);}}let $=a.basename(i);console.log(`
|
|
70
|
+
${t.yellow("\u26A0\uFE0F Limited offline mode:")} This project was created using basic templates.
|
|
71
|
+
${t.gray("For full kit features, install Python 3.10+ and rapidkit-core:")}
|
|
72
|
+
${t.cyan(" sudo apt install python3 python3-pip python3-venv")}
|
|
73
|
+
${t.cyan(" pip install rapidkit-core")}
|
|
74
|
+
`),console.log(r?`
|
|
75
|
+
${t.green("\u2728 FastAPI project created successfully!")}
|
|
76
|
+
|
|
77
|
+
${t.bold("\u{1F4C2} Project structure:")}
|
|
78
|
+
${i}/
|
|
79
|
+
\u251C\u2500\u2500 .rapidkit/ # RapidKit CLI module
|
|
80
|
+
\u251C\u2500\u2500 src/
|
|
81
|
+
\u2502 \u251C\u2500\u2500 main.py # FastAPI application
|
|
82
|
+
\u2502 \u251C\u2500\u2500 cli.py # CLI commands
|
|
83
|
+
\u2502 \u251C\u2500\u2500 routing/ # API routes
|
|
84
|
+
\u2502 \u2514\u2500\u2500 modules/ # Module system
|
|
85
|
+
\u251C\u2500\u2500 tests/ # Test suite
|
|
86
|
+
\u251C\u2500\u2500 pyproject.toml # Poetry configuration
|
|
87
|
+
\u2514\u2500\u2500 README.md
|
|
88
|
+
|
|
89
|
+
${t.bold("\u{1F680} Get started:")}
|
|
90
|
+
${t.cyan(`cd ${$}`)}
|
|
91
|
+
${t.cyan("npx rapidkit init")} ${t.gray("# Install dependencies")}
|
|
92
|
+
${t.cyan("npx rapidkit dev")} ${t.gray("# Start dev server")}
|
|
93
|
+
|
|
94
|
+
${t.bold("\u{1F4DA} Available commands:")}
|
|
95
|
+
npx rapidkit init # Install dependencies (poetry install)
|
|
96
|
+
npx rapidkit dev # Start dev server with hot reload
|
|
97
|
+
npx rapidkit start # Start production server
|
|
98
|
+
npx rapidkit test # Run tests
|
|
99
|
+
npx rapidkit lint # Lint code
|
|
100
|
+
npx rapidkit format # Format code
|
|
101
|
+
|
|
102
|
+
${t.gray("Alternative: make dev, ./rapidkit dev, poetry run dev")}
|
|
103
|
+
${t.gray("\u{1F4A1} Tip: Install globally (npm i -g rapidkit) to use without npx")}
|
|
104
|
+
`:`
|
|
105
|
+
${t.green("\u2728 NestJS project created successfully!")}
|
|
106
|
+
|
|
107
|
+
${t.bold("\u{1F4C2} Project structure:")}
|
|
108
|
+
${i}/
|
|
109
|
+
\u251C\u2500\u2500 .rapidkit/ # RapidKit CLI module
|
|
110
|
+
\u251C\u2500\u2500 src/
|
|
111
|
+
\u2502 \u251C\u2500\u2500 main.ts # Application entry point
|
|
112
|
+
\u2502 \u251C\u2500\u2500 app.module.ts # Root module
|
|
113
|
+
\u2502 \u251C\u2500\u2500 config/ # Configuration
|
|
114
|
+
\u2502 \u2514\u2500\u2500 examples/ # Example module
|
|
115
|
+
\u251C\u2500\u2500 test/ # Test files
|
|
116
|
+
\u251C\u2500\u2500 package.json # Dependencies
|
|
117
|
+
\u2514\u2500\u2500 README.md
|
|
118
|
+
|
|
119
|
+
${t.bold("\u{1F680} Get started:")}
|
|
120
|
+
${t.cyan(`cd ${$}`)}
|
|
121
|
+
${t.cyan("npx rapidkit init")} ${t.gray("# Install dependencies")}
|
|
122
|
+
${t.cyan("cp .env.example .env")}
|
|
123
|
+
${t.cyan("npx rapidkit dev")} ${t.gray("# Start dev server")}
|
|
124
|
+
|
|
125
|
+
${t.bold("\u{1F4DA} Available commands:")}
|
|
126
|
+
npx rapidkit init # Install dependencies
|
|
127
|
+
npx rapidkit dev # Start dev server with hot reload
|
|
128
|
+
npx rapidkit start # Start production server
|
|
129
|
+
npx rapidkit build # Build for production
|
|
130
|
+
npx rapidkit test # Run tests
|
|
131
|
+
npx rapidkit lint # Lint code
|
|
132
|
+
npx rapidkit format # Format code
|
|
133
|
+
|
|
134
|
+
${t.bold("\u{1F310} API endpoints:")}
|
|
135
|
+
http://localhost:8000/health # Health check
|
|
136
|
+
http://localhost:8000/docs # Swagger docs
|
|
137
|
+
http://localhost:8000/examples/notes # Example API
|
|
138
|
+
|
|
139
|
+
${t.gray("Alternative: npm run start:dev, ./rapidkit dev")}
|
|
140
|
+
${t.gray("\u{1F4A1} Tip: Install globally (npm i -g rapidkit) to use without npx")}
|
|
141
|
+
`);}catch(u){throw h.fail(`Failed to generate ${p} project`),u}}export{U as generateDemoKit};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {b,f,d,a as a$1,k,g,i as i$1}from'./chunk-Z5LKRG57.js';import {a}from'./chunk-VM2TOHNX.js';import i from'chalk';import {execa}from'execa';import r from'fs-extra';import n from'path';import X from'inquirer';function z(t){return [...new Set(t.filter(s=>s&&s.trim().length>0))]}function Y(){let t=k().map(c=>n.join(c,a$1()?"poetry.exe":"poetry")),s=a$1()?[n.join(process.env.APPDATA||"","Python","Scripts","poetry.exe"),n.join(process.env.USERPROFILE||"","AppData","Roaming","Python","Scripts","poetry.exe")]:[],e=a$1()?[]:["/usr/local/bin/poetry","/usr/bin/poetry"];return z([...t,...s,...e])}function Z(t){let s=k().map(a=>({location:"Global (user-local)",path:n.join(a,a$1()?"rapidkit.exe":"rapidkit")})),e=[{location:"Global (pipx)",path:n.join(t,".local","bin","rapidkit")},{location:"Global (pipx)",path:n.join(t,"AppData","Roaming","Python","Scripts","rapidkit.exe")},{location:"Global (pyenv)",path:n.join(t,".pyenv","shims","rapidkit")},{location:"Global (system)",path:"/usr/local/bin/rapidkit"},{location:"Global (system)",path:"/usr/bin/rapidkit"}],c=g(n.join(process.cwd(),".venv")),o=i$1(process.cwd()),l=[{location:"Workspace (.venv)",path:c},...o.map(a=>({location:"Workspace (launcher)",path:a}))],p=[...s,...e,...l],d=new Set;return p.filter(a=>d.has(a.path)?false:(d.add(a.path),true))}function tt(t){let s=new Map([["Workspace (.venv)",0],["Global (user-local)",1],["Global (pipx)",2],["Global (pyenv)",3],["Global (system)",4]]);return [...t].sort((e,c)=>{let o=s.get(e.location)??Number.MAX_SAFE_INTEGER,l=s.get(c.location)??Number.MAX_SAFE_INTEGER;return o!==l?o-l:e.path.localeCompare(c.path)})}function j(t,s){return a$1()?`cd "${t}"; ${s}`:`cd ${t} && ${s}`}function W(t){return a$1()?j(t,"Copy-Item .env.example .env"):j(t,"cp .env.example .env")}async function J(t){try{let s=await r.stat(t);return `${n.basename(t)}:${s.isDirectory()?"d":"f"}:${s.size}:${s.mtimeMs}`}catch{return `${n.basename(t)}:missing`}}async function et(t){try{let s=new Set([".git",".venv","node_modules",".rapidkit","dist","build","coverage","__pycache__"]),e=new Set;await N(t)&&e.add(t);let c=async(o,l)=>{if(l<0)return;let p=await Q(o);for(let d of p){if(U(d,s))continue;let a=n.join(o,d);if(await N(a)){e.add(a);continue}l>0&&await c(a,l-1);}};return await c(t,1),e.size===0&&(await pt(t,3,s)).forEach(l=>e.add(l)),Array.from(e).sort((o,l)=>o.localeCompare(l))}catch{return []}}async function st(t,s){let e=[n.join(t,".rapidkit-workspace"),n.join(t,".rapidkit","workspace.json"),n.join(t,".rapidkit","policies.yml"),n.join(t,".rapidkit","toolchain.lock"),n.join(t,".rapidkit","cache-config.yml")],c=[".rapidkit/project.json",".rapidkit/context.json",".rapidkit/file-hashes.json","package.json","pyproject.toml","go.mod","go.sum","requirements.txt","Dockerfile","Makefile",".env",".env.example","src","modules","tests","test",".venv","node_modules"],o=await Promise.all(e.map(J)),l=await Promise.all(s.map(async p=>{let d=await Promise.all(c.map(a=>J(n.join(p,a))));return `${p}::${d.join("|")}`}));return [...o,...l].join("||")}async function ot(t,s){try{if(!await r.pathExists(t))return null;let e=await r.readJSON(t);return !e||e.signature!==s||!Array.isArray(e.projects)?null:e}catch{return null}}async function it(t,s){try{await r.ensureDir(n.dirname(t)),await r.writeJSON(t,s,{spaces:2});}catch{}}async function nt(t,s,e){let c=n.join(t,".rapidkit","reports","doctor-last-run.json");try{return await r.ensureDir(n.dirname(c)),await r.writeJSON(c,{generatedAt:new Date().toISOString(),workspacePath:t,workspaceName:s.workspaceName,projectScanCached:s.projectScanCached??false,projectScanSignature:s.projectScanSignature,cachePath:e,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((o,l)=>o+l.issues.length,0),hasSystemErrors:[s.python,s.rapidkitCore].some(o=>o.status==="error")}},{spaces:2}),c}catch{return}}async function B(){let[t,s,e,c,o]=await Promise.all([at(),rt(),ct(),lt(),dt()]);return {python:t,poetry:s,pipx:e,go:c,rapidkitCore:o}}async function at(){let t=d();for(let s of t)try{let{stdout:e}=await execa(s,["--version"],{timeout:3e3}),c=e.match(/Python (\d+\.\d+\.\d+)/);if(c){let o=c[1],[l,p]=o.split(".").map(Number);return l<3||l===3&&p<10?{status:"warn",message:`Python ${o} (requires 3.10+)`,details:`${s} found but version is below minimum requirement`}:{status:"ok",message:`Python ${o}`,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 rt(){try{let{stdout:t}=await execa("poetry",["--version"],{timeout:3e3}),s=t.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 t=d().map(s=>({cmd:s,args:s==="py"?["-3","-m","poetry","--version"]:["-m","poetry","--version"]}));for(let s of t)try{let{stdout:e}=await execa(s.cmd,s.args,{timeout:3e3,shell:b()}),c=e.match(/Poetry .*version ([\d.]+)/)||e.match(/([\d.]+)/);return {status:"ok",message:c?.[1]?`Poetry ${c[1]}`:"Poetry detected",details:`Available via ${s.cmd} ${s.args.join(" ")}`}}catch{continue}for(let s of Y())try{if(!await r.pathExists(s))continue;let{stdout:e}=await execa(s,["--version"],{timeout:3e3,shell:b()}),c=e.match(/Poetry .*version ([\d.]+)/)||e.match(/([\d.]+)/);return {status:"ok",message:c?.[1]?`Poetry ${c[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 ct(){try{let{stdout:t}=await execa("pipx",["--version"],{timeout:3e3});return {status:"ok",message:`pipx ${t.trim()}`,details:"Available for global tool installation"}}catch{let t=d();for(let s of t)try{let e=s==="py"?["-3","-m","pipx","--version"]:["-m","pipx","--version"],{stdout:c}=await execa(s,e,{timeout:3e3,shell:b()});return {status:"ok",message:`pipx ${c.trim()}`,details:`Available via ${s} ${e.join(" ")}`}}catch{continue}return {status:"warn",message:"pipx not installed",details:"Optional: Install for isolated Python tools"}}}async function lt(){try{let{stdout:t}=await execa("go",["version"],{timeout:3e3}),s=t.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 dt(){let t=process.env.HOME||process.env.USERPROFILE||"",s=[],e=Z(t);for(let{location:o,path:l}of e)try{if(await r.pathExists(l)){let{stdout:p,exitCode:d}=await execa(l,["--version"],{timeout:3e3,reject:false});if(d===0&&(p.includes("RapidKit Version")||p.includes("RapidKit"))){let a=p.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);a&&s.push({location:o,path:l,version:a[1]});}}}catch{continue}if(s.length>0){let o=s.filter(p=>p.location!=="Workspace (launcher)");if(o.length>0){let p=tt(o);return {status:"ok",message:`RapidKit Core ${p[0].version}`,paths:p.map(a=>({location:a.location,path:a.path,version:a.version}))}}return {status:"ok",message:`RapidKit Core ${s[0].version}`,details:"Detected via workspace launcher"}}try{let{stdout:o,exitCode:l}=await execa("rapidkit",["--version"],{timeout:3e3,reject:false});if(l===0&&(o.includes("RapidKit Version")||o.includes("RapidKit"))){let p=o.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(p)return {status:"ok",message:`RapidKit Core ${p[1]}`,details:"Available via PATH"}}}catch{}try{let{stdout:o,exitCode:l}=await execa("poetry",["run","rapidkit","--version"],{timeout:3e3,reject:false});if(l===0&&(o.includes("RapidKit Version")||o.includes("RapidKit"))){let p=o.match(/v?([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);if(p)return {status:"ok",message:`RapidKit Core ${p[1]}`,details:"Available via Poetry"}}}catch{}let c=d();for(let o of c)try{let{stdout:l,exitCode:p}=await execa(o,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:3e3,reject:false});if(p===0&&l&&!l.includes("Traceback")&&!l.includes("ModuleNotFoundError")){let d=l.trim();if(d)return {status:"ok",message:`RapidKit Core ${d}`,details:`Available in ${o} environment`}}}catch{continue}return {status:"error",message:"RapidKit Core not installed",details:"Install with: pipx install rapidkit-core"}}async function I(t,s){let e=n.join(t,"Dockerfile");s.hasDocker=await r.pathExists(e);let c=n.join(t,"tests"),o=n.join(t,"test"),l=n.join(t,"src","test"),p=await r.pathExists(c)||await r.pathExists(o)||await r.pathExists(l),d=false;if(s.framework==="Go/Fiber"||s.framework==="Go/Gin")try{let a=[{dir:t,depth:0}],u=4,m=new Set([".git",".venv","node_modules","dist","build","vendor"]);for(;a.length>0&&!d;){let h=a.shift();if(!h)break;let w=[];try{w=await r.readdir(h.dir);}catch{continue}for(let f of w){let g=n.join(h.dir,f),v;try{v=await r.stat(g);}catch{continue}if(v.isFile()&&f.endsWith("_test.go")){d=true;break}v.isDirectory()&&h.depth<u&&!m.has(f)&&!f.startsWith(".")&&a.push({dir:g,depth:h.depth+1});}}}catch{}if(s.hasTests=p||d,s.framework==="NestJS"){let a=n.join(t,".eslintrc.js"),u=n.join(t,".eslintrc.json");s.hasCodeQuality=await r.pathExists(a)||await r.pathExists(u);}else if(s.framework==="Go/Fiber"||s.framework==="Go/Gin"){let a=n.join(t,".golangci.yml"),u=n.join(t,".golangci.yaml"),m=n.join(t,"Makefile"),h=await r.pathExists(m)&&(await r.readFile(m,"utf8")).includes("golangci-lint");s.hasCodeQuality=await r.pathExists(a)||await r.pathExists(u)||h;}else if(s.framework==="FastAPI"){let a=n.join(t,"ruff.toml"),u=n.join(t,"pyproject.toml");if(await r.pathExists(u))try{let m=await r.readFile(u,"utf8");s.hasCodeQuality=m.includes("[tool.ruff]")||await r.pathExists(a);}catch{s.hasCodeQuality=await r.pathExists(a);}}else if(s.framework==="Spring Boot"){let a=n.join(t,"pom.xml");if(await r.pathExists(a))try{let u=await r.readFile(a,"utf8");s.hasCodeQuality=u.includes("spotless")||u.includes("checkstyle")||u.includes("pmd")||u.includes("maven-enforcer-plugin");}catch{s.hasCodeQuality=false;}}try{if(s.framework==="NestJS"){let{stdout:a}=await execa("npm",["audit","--json"],{cwd:t,reject:false});if(a)try{let m=JSON.parse(a).metadata?.vulnerabilities;m&&(s.vulnerabilities=(m.high||0)+(m.critical||0)+(m.moderate||0));}catch{}}else if(s.framework==="FastAPI"){let a=n.join(t,".venv"),u=f(a);if(await r.pathExists(u))try{let{stdout:m}=await execa(u,["-m","pip","list","--format=json"],{timeout:5e3,reject:false});if(m){JSON.parse(m);s.vulnerabilities=0;}}catch{}}}catch{}}async function ut(t){let e={name:n.basename(t),path:t,venvActive:false,depsInstalled:false,coreInstalled:false,issues:[],fixCommands:[]},c=n.join(t,".rapidkit");if(!await r.pathExists(c))return e.issues.push("Not a valid RapidKit project (missing .rapidkit directory)"),e;try{let f=n.join(t,"registry.json");if(await r.pathExists(f)){let g=await r.readJson(f);g.installed_modules&&(e.stats={modules:g.installed_modules.length});}}catch{}let o=null;try{let f=n.join(c,"project.json");if(await r.pathExists(f)){o=await r.readJson(f);let g=o?.kit_name||o?.kit;g&&(e.kit=g);}}catch{}try{let f=n.join(t,".git");if(await r.pathExists(f)){let{stdout:g}=await execa("git",["log","-1","--format=%cr"],{cwd:t,reject:false});g&&(e.lastModified=g.trim());}else {let g=await r.stat(t),x=Date.now()-g.mtime.getTime(),k=Math.floor(x/(1e3*60*60*24));e.lastModified=k===0?"today":`${k} day${k>1?"s":""} ago`;}}catch{}let l=n.join(t,"package.json"),p=n.join(t,"pyproject.toml"),d=n.join(t,"go.mod"),a=n.join(t,"pom.xml");if(await r.pathExists(d)||o?.runtime==="go"||typeof o?.kit_name=="string"&&(o.kit_name.startsWith("gofiber")||o.kit_name.startsWith("gogin"))){let f=o?.kit_name??"";e.framework=f.startsWith("gogin")?"Go/Gin":"Go/Fiber",e.isGoProject=true,e.venvActive=true,e.coreInstalled=false;try{await execa("go",["version"],{timeout:3e3});}catch{e.issues.push("Go toolchain not found \u2014 install from https://go.dev/dl/"),e.fixCommands?.push("https://go.dev/dl/");}let g=n.join(t,"go.sum");return await r.pathExists(g)?e.depsInstalled=true:(e.depsInstalled=false,e.issues.push("Go dependencies not downloaded (go.sum missing)"),e.fixCommands?.push(j(t,"go mod tidy"))),await I(t,e),e}if(await r.pathExists(a)||o?.runtime==="java"||typeof o?.kit_name=="string"&&o.kit_name.startsWith("springboot")){e.framework="Spring Boot",e.venvActive=true,e.coreInstalled=false;let f=await r.pathExists(a),g=await r.pathExists(n.join(t,"build.gradle"))||await r.pathExists(n.join(t,"build.gradle.kts")),v=await r.pathExists(n.join(t,"mvnw"))||await r.pathExists(n.join(t,"mvnw.cmd")),x=await r.pathExists(n.join(t,"gradlew"))||await r.pathExists(n.join(t,"gradlew.bat"));try{await execa("java",["-version"],{timeout:3e3,reject:false});}catch{e.issues.push("Java runtime not found \u2014 install JDK 21+ and ensure java is on PATH"),e.fixCommands?.push("https://adoptium.net/");}if(f){if(!v)try{await execa("mvn",["-version"],{timeout:3e3,reject:false});}catch{e.issues.push("Maven not found \u2014 install Maven 3.9+ or add Maven Wrapper"),e.fixCommands?.push("https://maven.apache.org/install.html");}}else if(g&&!x)try{await execa("gradle",["--version"],{timeout:3e3,reject:false});}catch{e.issues.push("Gradle not found \u2014 install Gradle 8+ or add Gradle Wrapper"),e.fixCommands?.push("https://gradle.org/install/");}let k=n.join(t,"target"),b=n.join(t,"build","libs"),G=n.join(t,".rapidkit","cache","java","m2"),F=n.join(t,".rapidkit","cache","java","gradle");e.depsInstalled=await r.pathExists(k)||await r.pathExists(b)||await r.pathExists(G)||await r.pathExists(F),e.depsInstalled||(e.issues.push("Java dependencies are not warmed or built yet"),e.fixCommands?.push(j(t,"rapidkit init")));let E=n.join(t,".env");if(e.hasEnvFile=await r.pathExists(E),!e.hasEnvFile){let S=n.join(t,".env.example");await r.pathExists(S)&&(e.issues.push("Environment file missing (found .env.example)"),e.fixCommands?.push(W(t)));}let A=n.join(t,"src","main","resources","application.yml");if(await r.pathExists(A))try{let S=await r.readFile(A,"utf-8");/include:\s*[^\n]*health/i.test(S)||/management:\s*[\s\S]*endpoint:\s*[\s\S]*health:/i.test(S)||(e.issues.push("Actuator health endpoint exposure is not clearly configured in application.yml"),e.fixCommands?.push(j(t,"Ensure management.endpoints.web.exposure.include contains health in src/main/resources/application.yml")));}catch{e.issues.push("Unable to read application.yml for Spring Actuator health checks");}return await I(t,e),e}let h=await r.pathExists(l),w=await r.pathExists(p);if(h){e.framework="NestJS",e.venvActive=true;let f=n.join(t,"node_modules");if(await r.pathExists(f))try{let k=(await r.readdir(f)).filter(b=>!b.startsWith(".")&&!b.startsWith("_"));e.depsInstalled=k.length>0;}catch{e.depsInstalled=false;}e.depsInstalled||(e.issues.push("Dependencies not installed (node_modules empty or missing)"),e.fixCommands?.push(j(t,"rapidkit init"))),e.coreInstalled=false;let g=n.join(t,".env");if(e.hasEnvFile=await r.pathExists(g),!e.hasEnvFile){let x=n.join(t,".env.example");await r.pathExists(x)&&(e.issues.push("Environment file missing (found .env.example)"),e.fixCommands?.push(W(t)));}let v=n.join(t,"src");if(e.modulesHealthy=true,e.missingModules=[],await r.pathExists(v))try{let x=await r.readdir(v);e.modulesHealthy=x.length>0;}catch{e.modulesHealthy=false;}return await I(t,e),e}if(w){e.framework="FastAPI";let f$1=n.join(t,".venv");if(await r.pathExists(f$1)){e.venvActive=true;let k=f(f$1);if(await r.pathExists(k)){try{let{stdout:b}=await execa(k,["-c","import rapidkit_core; print(rapidkit_core.__version__)"],{timeout:2e3});e.coreInstalled=true,e.coreVersion=b.trim();}catch{e.coreInstalled=false;}try{await execa(k,["-c","import fastapi"],{timeout:2e3}),e.depsInstalled=true;}catch{try{let b=n.join(f$1,"lib");if(await r.pathExists(b)){let F=(await r.readdir(b)).find(E=>E.startsWith("python"));if(F){let E=n.join(b,F,"site-packages");if(await r.pathExists(E)){let S=(await r.readdir(E)).filter(_=>!_.startsWith("_")&&!_.includes("dist-info")&&!["pip","setuptools","wheel","pkg_resources"].includes(_));e.depsInstalled=S.length>0;}}}e.depsInstalled||(e.issues.push("Dependencies not installed"),e.fixCommands?.push(j(t,"rapidkit init")));}catch{e.issues.push("Could not verify dependency installation");}}}else e.issues.push("Virtual environment exists but Python executable not found");}else e.issues.push("Virtual environment not created"),e.fixCommands?.push(j(t,"rapidkit init"));let g=n.join(t,".env");if(e.hasEnvFile=await r.pathExists(g),!e.hasEnvFile){let k=n.join(t,".env.example");await r.pathExists(k)&&(e.issues.push("Environment file missing (found .env.example)"),e.fixCommands?.push(W(t)));}let v=n.join(t,"src"),x=n.join(t,"modules");if(e.modulesHealthy=true,e.missingModules=[],await r.pathExists(v)){let k=n.join(v,"__init__.py");await r.pathExists(k)||(e.modulesHealthy=false,e.missingModules.push("src/__init__.py"));}if(await r.pathExists(x))try{let k=await Q(x);for(let b of k){let G=n.join(x,b,"__init__.py");await r.pathExists(G)||(e.modulesHealthy=false,e.missingModules.push(`modules/${b}/__init__.py`));}}catch{}return !e.modulesHealthy&&e.missingModules.length>0&&e.issues.push(`Missing module init files: ${e.missingModules.join(", ")}`),await I(t,e),e}return e.issues.push("Unknown project type (no package.json or pyproject.toml)"),await I(t,e),e}async function Q(t){try{return (await r.readdir(t,{withFileTypes:true})).filter(e=>e.isDirectory()).map(e=>e.name)}catch{try{let s=await r.readdir(t),e=[];for(let c of s)try{(await r.stat(n.join(t,c))).isDirectory()&&e.push(c);}catch{continue}return e}catch{return []}}}async function N(t){let s=n.join(t,".rapidkit");if(!await r.pathExists(s))return false;let e=["project.json","context.json","file-hashes.json"];for(let c of e)if(await r.pathExists(n.join(s,c)))return true;return false}function U(t,s){if(s.has(t))return true;let e=t.toLowerCase();return !!(e==="dist"||e.startsWith("dist-")||e.startsWith("dist_")||e==="build"||e.startsWith("build-")||e.startsWith("build_"))}async function pt(t,s,e){let c=new Set,o=[{dir:t,depth:0}];for(;o.length>0;){let l=o.shift();if(!l)break;try{let p=await r.readdir(l.dir);for(let d of p){if(U(d,e))continue;let a=n.join(l.dir,d),u;try{u=await r.stat(a);}catch{continue}if(u.isDirectory()){if(await N(a)){c.add(a);continue}l.depth<s&&o.push({dir:a,depth:l.depth+1});}}}catch{continue}}return Array.from(c)}async function K(t){let s=t,e=n.parse(s).root;for(;s!==e;){let c=[n.join(s,".rapidkit-workspace"),n.join(s,".rapidkit","workspace-marker.json"),n.join(s,".rapidkit","config.json")];for(let o of c)if(await r.pathExists(o))return s;s=n.dirname(s);}return null}function mt(t,s){let e=0,c=0,o=0;return t.forEach(p=>{p.status==="ok"?e++:p.status==="warn"?c++:p.status==="error"&&o++;}),s.forEach(p=>{(p.isGoProject?p.issues.length===0&&p.depsInstalled:p.issues.length===0&&p.venvActive&&p.depsInstalled)?e++:p.issues.length>0&&c++;}),{total:e+c+o,passed:e,warnings:c,errors:o}}async function O(t,s=true){let e=n.basename(t);try{let m=n.join(t,".rapidkit-workspace");await r.pathExists(m)&&(e=(await r.readJSON(m)).name||e);}catch{try{let m=n.join(t,".rapidkit","config.json");e=(await r.readJSON(m)).workspace_name||e;}catch{}}let[c,o]=await Promise.all([B(),et(t)]),l={workspacePath:t,workspaceName:e,python:c.python,poetry:c.poetry,pipx:c.pipx,go:c.go,rapidkitCore:c.rapidkitCore,projects:[]};a.debug(`Workspace scan found ${o.length} project(s)`);let p=await st(t,o),d=n.join(t,".rapidkit","reports","doctor-workspace-cache.json"),a$1=s?await ot(d,p):null;if(a$1)l.projects=a$1.projects,l.projectScanCached=true,a.debug(`Workspace project health cache hit: ${d}`);else try{let m=await Promise.all(o.map(h=>ut(h)));l.projects=m,l.projectScanCached=false,await it(d,{signature:p,generatedAt:new Date().toISOString(),projects:m}),a.debug(`Workspace project health cache refreshed: ${d}`);}catch(m){a.debug(`Failed to scan workspace projects: ${m}`);}l.projectScanSignature=p,l.projectScanCachePath=d;let u=[l.python,l.poetry,l.pipx,l.go,l.rapidkitCore];if(l.healthScore=mt(u,l.projects),l.rapidkitCore.status==="ok"){let m=l.rapidkitCore.message.match(/([\d.]+(?:rc\d+)?(?:a\d+)?(?:b\d+)?)/);m&&(l.coreVersion=m[1]);}return l.evidencePath=await nt(t,l,a$1?d:null),l}function C(t,s){let e=t.status==="ok"?"\u2705":t.status==="warn"?"\u26A0\uFE0F":"\u274C",c=t.status==="ok"?i.green:t.status==="warn"?i.yellow:i.red;console.log(`${e} ${i.bold(s)}: ${c(t.message)}`),t.paths&&t.paths.length>0?t.paths.forEach(o=>{let l=o.version?i.cyan(` -> ${o.version}`):"";console.log(` ${i.cyan("\u2022")} ${i.gray(o.location)}: ${i.dim(o.path)}${l}`);}):t.details&&console.log(` ${i.gray(t.details)}`);}function ht(t){let s=t.issues.length>0,e=s?"\u26A0\uFE0F":"\u2705",c=s?i.yellow:i.green;if(console.log(`
|
|
2
|
+
${e} ${i.bold("Project")}: ${c(t.name)}`),t.framework){let u=t.framework==="FastAPI"?"\u{1F40D}":t.framework==="NestJS"?"\u{1F985}":t.framework==="Spring Boot"?"\u2615":t.framework==="Go/Fiber"||t.framework==="Go/Gin"?"\u{1F439}":"\u{1F4E6}";console.log(` ${u} Framework: ${i.cyan(t.framework)}${t.kit?i.gray(` (${t.kit})`):""}`);}console.log(` ${i.gray(`Path: ${t.path}`)}`);let o=t.framework==="Go/Fiber"||t.framework==="Go/Gin",l=t.framework==="Spring Boot",p=t.framework==="NestJS";if(!o&&!p&&!l&&(t.venvActive?console.log(` \u2705 Virtual environment: ${i.green("Active")}`):console.log(` \u274C Virtual environment: ${i.red("Not found")}`),t.coreInstalled?console.log(` ${i.dim("\u2139")} RapidKit Core: ${i.gray(t.coreVersion||"In venv")} ${i.dim("(optional)")}`):console.log(` ${i.dim("\u2139")} RapidKit Core: ${i.gray("Using global installation")} ${i.dim("(recommended)")}`)),t.depsInstalled?console.log(` \u2705 Dependencies: ${i.green("Installed")}`):console.log(` \u26A0\uFE0F Dependencies: ${i.yellow("Not installed")}`),t.hasEnvFile!==void 0&&(t.hasEnvFile?console.log(` \u2705 Environment: ${i.green(".env configured")}`):console.log(` \u26A0\uFE0F Environment: ${i.yellow(".env missing")}`)),t.modulesHealthy!==void 0&&(t.modulesHealthy?console.log(` \u2705 Modules: ${i.green("Healthy")}`):t.missingModules&&t.missingModules.length>0&&console.log(` \u26A0\uFE0F Modules: ${i.yellow(`Missing ${t.missingModules.length} init file(s)`)}`)),t.stats){let u=[];t.stats.modules!==void 0&&u.push(`${t.stats.modules} module${t.stats.modules!==1?"s":""}`),u.length>0&&console.log(` \u{1F4CA} Stats: ${i.cyan(u.join(" \u2022 "))}`);}t.lastModified&&console.log(` \u{1F552} Last Modified: ${i.gray(t.lastModified)}`);let a=[];if(t.hasTests!==void 0&&a.push(t.hasTests?"\u2705 Tests":i.dim("\u2298 No tests")),t.hasDocker!==void 0&&a.push(t.hasDocker?"\u2705 Docker":i.dim("\u2298 No Docker")),t.hasCodeQuality!==void 0){let u=t.framework==="NestJS"?"ESLint":t.framework==="Spring Boot"?"Static analysis":t.framework==="Go/Fiber"||t.framework==="Go/Gin"?"golangci-lint":"Ruff";a.push(t.hasCodeQuality?`\u2705 ${u}`:i.dim(`\u2298 No ${u}`));}a.length>0&&console.log(` ${a.join(" \u2022 ")}`),t.vulnerabilities!==void 0&&t.vulnerabilities>0&&console.log(` \u26A0\uFE0F Security: ${i.yellow(`${t.vulnerabilities} vulnerability(ies) found`)}`),t.issues.length>0&&(console.log(` ${i.bold("Issues:")}`),t.issues.forEach(u=>{console.log(` \u2022 ${i.yellow(u)}`);}),t.fixCommands&&t.fixCommands.length>0&&(console.log(`
|
|
3
|
+
${i.bold.cyan("\u{1F527} Quick Fix:")}`),t.fixCommands.forEach(u=>{console.log(` ${i.cyan("$")} ${i.white(u)}`);})));}async function q(){try{return (await execa("go",["version"],{timeout:3e3,reject:false})).exitCode===0}catch{return false}}async function L(t,s=false){let e=t.filter(u=>u.fixCommands&&u.fixCommands.length>0),c=null;if(e.length===0){console.log(i.green(`
|
|
4
|
+
\u2705 No fixes needed - all projects are healthy!`));return}console.log(i.bold.cyan(`
|
|
5
|
+
\u{1F527} Available Fixes:
|
|
6
|
+
`));for(let u of e){let m=u.fixCommands??[];console.log(i.bold(`Project: ${i.yellow(u.name)}`)),m.forEach((h,w)=>{console.log(` ${w+1}. ${i.cyan(h)}`);}),console.log();}let o=0;for(let u of e){let m=u.fixCommands??[];for(let h of m){if(/^https?:\/\//i.test(h.trim()))continue;if(d(h,"cp\\s+\\.env\\.example\\s+\\.env")||d(h,"copy-item\\s+\\.env\\.example\\s+\\.env")||d(h,"rapidkit\\s+init")){o+=1;continue}if(d(h,"go\\s+mod\\s+tidy")){c===null&&(c=await q()),c&&(o+=1);continue}o+=1;}}if(o===0){console.log(i.gray("\u{1F4A1} No automatic fixes can be applied right now.")),c===false&&console.log(i.gray(" Install Go to enable go mod tidy fixes, then rerun `rapidkit doctor workspace --fix`."));return}if(!s){console.log(i.gray('\u{1F4A1} Run "npx rapidkit doctor workspace --fix" to apply fixes automatically'));return}let{confirm:l}=await X.prompt([{type:"confirm",name:"confirm",message:`Apply ${e.reduce((u,m)=>u+(m.fixCommands?.length??0),0)} fix(es)?`,default:false}]);if(!l){console.log(i.yellow(`
|
|
7
|
+
\u26A0\uFE0F Fixes cancelled by user`));return}console.log(i.bold.cyan(`
|
|
8
|
+
\u{1F680} Applying fixes...
|
|
9
|
+
`));let p=u=>/^https?:\/\//i.test(u.trim());function d(u,m){let h=[new RegExp(`^cd\\s+"([^"]+)"\\s*(?:&&|;)\\s*${m}\\s*$`,"i"),new RegExp(`^cd\\s+'([^']+)'\\s*(?:&&|;)\\s*${m}\\s*$`,"i"),new RegExp(`^cd\\s+(.+?)\\s*(?:&&|;)\\s*${m}\\s*$`,"i")];for(let w of h){let f=u.match(w);if(f?.[1])return {projectPath:f[1].trim()}}return null}function a(u){return d(u,"cp\\s+\\.env\\.example\\s+\\.env")||d(u,"copy-item\\s+\\.env\\.example\\s+\\.env")}for(let u of e){let m=u.fixCommands??[];console.log(i.bold(`Fixing ${i.cyan(u.name)}...`));for(let h of m)try{if(console.log(i.gray(` $ ${h}`)),p(h)){console.log(i.yellow(` \u2139 Manual action required: open ${h}`)),console.log(i.green(` \u2705 Recorded as guidance
|
|
10
|
+
`));continue}let w=a(h);if(w){let v=n.join(w.projectPath,".env.example"),x=n.join(w.projectPath,".env");if(!await r.pathExists(v))throw new Error(`.env.example not found at ${v}`);if(await r.pathExists(x)){console.log(i.green(` \u2705 .env already exists
|
|
11
|
+
`));continue}await r.copy(v,x,{overwrite:false,errorOnExist:false}),console.log(i.green(` \u2705 Success
|
|
12
|
+
`));continue}let f=d(h,"rapidkit\\s+init");if(f){await execa("rapidkit",["init"],{cwd:f.projectPath,shell:b(),stdio:"inherit"}),console.log(i.green(` \u2705 Success
|
|
13
|
+
`));continue}let g=d(h,"go\\s+mod\\s+tidy");if(g){if(c===null&&(c=await q()),!c){console.log(i.yellow(" \u26A0 Go toolchain is not installed \u2014 skipping go mod tidy; install Go to apply this fix.")),console.log(i.green(` \u2705 Recorded as guidance
|
|
14
|
+
`));continue}await execa("go",["mod","tidy"],{cwd:g.projectPath,shell:b(),stdio:"inherit"}),console.log(i.green(` \u2705 Success
|
|
15
|
+
`));continue}await execa(h,{shell:true,stdio:"inherit"}),console.log(i.green(` \u2705 Success
|
|
16
|
+
`));}catch(w){console.log(i.red(` \u274C Failed: ${w instanceof Error?w.message:String(w)}
|
|
17
|
+
`));}}console.log(i.bold.green(`
|
|
18
|
+
\u2705 Fix process completed!`));}async function jt(t={}){let s=!t.workspace&&t.fix?await K(process.cwd()):null,e=t.workspace||!!s;if(t.json||console.log(i.bold.cyan(`
|
|
19
|
+
\u{1FA7A} RapidKit Health Check
|
|
20
|
+
`)),e){let c=s??await K(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)),t.json||(s&&console.log(i.gray("\u2139\uFE0F Detected workspace context; enabling workspace checks for --fix")),console.log(i.bold(`Workspace: ${i.cyan(n.basename(c))}`)),console.log(i.gray(`Path: ${c}`)));let o=await O(c);if(t.json||(o.projectScanCached&&console.log(i.gray(`\u2139\uFE0F Reused cached project scan${o.projectScanCachePath?` (${n.basename(o.projectScanCachePath)})`:""}`)),o.evidencePath&&console.log(i.gray(`\u2139\uFE0F Evidence saved: ${o.evidencePath}`))),t.json){let d={workspace:{name:n.basename(c),path:c},cache:{projectScan:o.projectScanCached??false,projectScanPath:o.projectScanCachePath,evidencePath:o.evidencePath},healthScore:o.healthScore,system:{python:o.python,poetry:o.poetry,pipx:o.pipx,rapidkitCore:o.rapidkitCore,versions:{core:o.coreVersion,npm:o.npmVersion}},projects:o.projects.map(a=>({name:a.name,path:a.path,venvActive:a.venvActive,depsInstalled:a.depsInstalled,coreInstalled:a.coreInstalled,coreVersion:a.coreVersion,issues:a.issues,fixCommands:a.fixCommands})),summary:{totalProjects:o.projects.length,totalIssues:o.projects.reduce((a,u)=>a+u.issues.length,0),hasSystemErrors:[o.python,o.rapidkitCore].some(a=>a.status==="error")}};console.log(JSON.stringify(d,null,2));return}if(o.healthScore){let d=o.healthScore,a=Math.round(d.passed/d.total*100),u=a>=80?i.green:a>=50?i.yellow:i.red,m="\u2588".repeat(Math.floor(a/5))+"\u2591".repeat(20-Math.floor(a/5));console.log(i.bold(`
|
|
21
|
+
\u{1F4CA} Health Score:`)),console.log(` ${u(`${a}%`)} ${i.gray(m)}`),console.log(` ${i.green(`\u2705 ${d.passed} passed`)} ${i.gray("|")} ${i.yellow(`\u26A0\uFE0F ${d.warnings} warnings`)} ${i.gray("|")} ${i.red(`\u274C ${d.errors} errors`)}`);}if(console.log(i.bold(`
|
|
22
|
+
|
|
23
|
+
System Tools:
|
|
24
|
+
`)),C(o.python,"Python"),C(o.poetry,"Poetry"),C(o.pipx,"pipx"),C(o.go,"Go"),C(o.rapidkitCore,"RapidKit Core"),o.coreVersion&&o.npmVersion){let d=o.coreVersion.split(".")[1],a=o.npmVersion.split(".")[1];d!==a&&(console.log(i.yellow(`
|
|
25
|
+
\u26A0\uFE0F Version mismatch: Core ${o.coreVersion} / CLI ${o.npmVersion}`)),console.log(i.gray(" Consider updating to matching versions for best compatibility")));}o.projects.length>0?(console.log(i.bold(`
|
|
26
|
+
\u{1F4E6} Projects (${o.projects.length}):`)),o.projects.forEach(d=>ht(d))):(console.log(i.bold(`
|
|
27
|
+
\u{1F4E6} Projects:`)),console.log(i.gray(" No RapidKit projects found in workspace")));let l=o.projects.reduce((d,a)=>d+a.issues.length,0),p=[o.python,o.rapidkitCore].some(d=>d.status==="error");if(p||l>0)if(console.log(i.bold.yellow(`
|
|
28
|
+
\u26A0\uFE0F Found ${l} project issue(s)`)),p&&console.log(i.bold.red("\u274C System requirements not met")),t.fix){if(await L(o.projects,true),!t.json){let d=await O(c,false),a=d.projects.reduce((m,h)=>m+h.issues.length,0),u=[d.python,d.rapidkitCore].some(m=>m.status==="error");u||a>0?(console.log(i.bold.yellow(`
|
|
29
|
+
\u26A0\uFE0F Post-fix verification found ${a} remaining issue(s)`)),u&&console.log(i.bold.red("\u274C System requirements still not met"))):console.log(i.bold.green(`
|
|
30
|
+
\u2705 Post-fix verification passed. Workspace is healthy.`)),d.projectScanCached&&console.log(i.gray(`\u2139\uFE0F Reused cached project scan${d.projectScanCachePath?` (${n.basename(d.projectScanCachePath)})`:""}`)),d.evidencePath&&console.log(i.gray(`\u2139\uFE0F Evidence refreshed: ${d.evidencePath}`));}}else l>0&&await L(o.projects,false);else console.log(i.bold.green(`
|
|
31
|
+
\u2705 All checks passed! Workspace is healthy.`));}else {console.log(i.bold(`System Tools:
|
|
32
|
+
`));let c=await B(),o=c.python,l=c.poetry,p=c.pipx,d=c.go,a=c.rapidkitCore;C(o,"Python"),C(l,"Poetry"),C(p,"pipx"),C(d,"Go"),C(a,"RapidKit Core"),[o,a].some(m=>m.status==="error")?(console.log(i.bold.red(`
|
|
33
|
+
\u274C Some required tools are missing`)),t.fix&&console.log(i.gray(`
|
|
34
|
+
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(i.gray(`
|
|
35
|
+
Tip: Run "rapidkit doctor workspace" for detailed project checks`))):(console.log(i.bold.green(`
|
|
36
|
+
\u2705 All required tools are installed!`)),t.fix&&console.log(i.gray(`
|
|
37
|
+
Tip: Project auto-fix runs in workspace mode. Run from a workspace and use "rapidkit doctor workspace --fix"`)),console.log(i.gray(`
|
|
38
|
+
Tip: Run "rapidkit doctor workspace" for detailed project checks`)));}console.log("");}export{jt as runDoctor};
|