rapidkit 0.27.3 → 0.27.5

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,33 @@
1
+ import {a,d,e,f,c,g}from'./chunk-Z5LKRG57.js';import ct from'crypto';import z from'os';import u from'path';import*as p from'fs-extra';import {execa}from'execa';var at=["version","project","create","add","list","info","upgrade","diff","doctor","license","commands","reconcile","rollback","uninstall","checkpoint","optimize","snapshot","frameworks","modules","merge"],$=new Set(at);function W(){return d()}function w(t,n){return t==="py"?["-3",...n]:n}function F(t){if(!t)return t;let n=["Installed Poetry version does not support '--no-update'. Falling back to 'poetry lock'."];return t.split(/\r?\n/).filter(i=>!n.some(o=>i.includes(o))).join(`
2
+ `)}var y=class extends Error{code;constructor(n,r){super(r),this.code=n;}};function R(t){if(t instanceof y)switch(t.code){case "PYTHON_NOT_FOUND":return `RapidKit (npm) could not find Python (python3/python/py) on your PATH.
3
+ Install Python 3.10+ and ensure \`${c()}\` is available, then retry.
4
+ Tip: if you are inside a RapidKit project, use the local ./rapidkit launcher.`;case "BRIDGE_VENV_CREATE_FAILED":return `RapidKit (npm) failed to create its bridge virtual environment.
5
+ `+(a()?`Ensure Python is installed with venv support.
6
+ `:`Ensure Python venv support is installed (e.g., python3-venv).
7
+ `)+`Details: ${t.message}`;case "BRIDGE_PIP_BOOTSTRAP_FAILED":return `RapidKit (npm) could not bootstrap pip inside the bridge virtual environment.
8
+ `+(a()?`Ensure pip is available for your Python installation and retry.
9
+ `:`Install python3-venv/python3-pip and retry.
10
+ `)+`Details: ${t.message}`;case "BRIDGE_PIP_UPGRADE_FAILED":return `RapidKit (npm) could not upgrade pip in the bridge virtual environment.
11
+ Check your network/proxy or disable RAPIDKIT_BRIDGE_UPGRADE_PIP.
12
+ Details: ${t.message}`;case "BRIDGE_PIP_INSTALL_FAILED":return `RapidKit (npm) could not install rapidkit-core in the bridge virtual environment.
13
+ Check your network/proxy, or install manually with: pipx install rapidkit-core.
14
+ Details: ${t.message}`;default:return `RapidKit (npm) bridge error: ${t.message}`}return `RapidKit (npm) failed to run the Python core engine: ${t instanceof Error?t.message:String(t)}`}function b(){let t=process.env.RAPIDKIT_CORE_PYTHON_PACKAGE;return t&&t.trim()?t.trim():"rapidkit-core"}function dt(){let t=b(),n=process.env.RAPIDKIT_CORE_PYTHON_PACKAGE_ID,r=n&&n.trim()?`${t}|${n.trim()}`:t;return ct.createHash("sha256").update(r).digest("hex").slice(0,12)}function S(){let t=process.env.XDG_CACHE_HOME;return t&&t.trim()?t:u.join(z.homedir(),".cache")}function pt(){return u.join(S(),"rapidkit","npm-bridge","venv")}function Z(){let t=dt();return u.join(S(),"rapidkit","npm-bridge",`venv-${t}`)}function G(t){return f(t)}function K(t){return g(t)}function X(t){return /[<>=!~]=|@|\.whl$|\.tar\.gz$|\.zip$|git\+|https?:\/\//.test(t)}function ut(t){return u.dirname(u.dirname(t))}function q(){return u.join(S(),"rapidkit","npm-bridge","core-commands.json")}async function Q(t){let n=!!process.env.RAPIDKIT_DEBUG,r=e=>{n&&process.stderr.write(`[DEBUG] tryRapidkit(${t}): ${e}
15
+ `);};try{r("probing interpreter-specific rapidkit script");let i=((await execa(t,w(t,["-c","import sysconfig, os; print(os.path.join(sysconfig.get_path('scripts'), 'rapidkit'))"]),{reject:false,stdio:"pipe",timeout:2e3})).stdout??"").toString().trim();if(r(`script path: ${i}`),i)try{if(await p.pathExists(i)){r(`found script at ${i}; invoking --version --json`);let o=await execa(i,["--version","--json"],{reject:false,stdio:"pipe",timeout:4e3});if(r(`script exitCode=${o.exitCode}`),o.exitCode===0){let s=(o.stdout??"").toString().trim();try{let a=JSON.parse(s),c=!!a&&typeof a=="object"&&a!==null&&"version"in a;if(r(`script JSON parse ok=${c}`),c)return true}catch{r("script output not valid JSON");}}}}catch(o){r(`interpreter-specific script probe failed: ${String(o)}`);}}catch(e){r(`interpreter-specific script probe error: ${String(e)}`);}try{r('probing importlib.find_spec("rapidkit")');let e=await execa(t,w(t,["-c","import importlib.util; print(1 if importlib.util.find_spec('rapidkit') else 0)"]),{reject:false,stdio:"pipe",timeout:2e3});if(r(`import probe exitCode=${e.exitCode} stdout=${(e.stdout??"").toString().trim()}`),e.exitCode===0&&(e.stdout??"").toString().trim()==="1")return true}catch(e){r(`import probe error: ${String(e)}`);}try{r("probing python -m rapidkit");let e=await execa(t,w(t,["-m","rapidkit","--version","--json"]),{reject:false,stdio:"pipe",timeout:8e3});if(r(`-m probe exitCode=${e.exitCode}`),e.exitCode===0)return true}catch(e){r(`-m probe error: ${String(e)}`);}try{r("probing PATH for rapidkit executables");let e=(process.env.PATH??"").split(u.delimiter).filter(Boolean);for(let i of e){let o=u.join(i,a()?"rapidkit.exe":"rapidkit");try{if(await p.pathExists(o)){r(`found candidate on PATH: ${o}; invoking --version --json`);let s=await execa(o,["--version","--json"],{reject:false,stdio:"pipe",timeout:4e3});if(r(`candidate exitCode=${s.exitCode}`),s.exitCode===0){let a=(s.stdout??"").toString().trim();try{let c=JSON.parse(a);if(c&&typeof c=="object"&&c!==null&&"version"in c)return true}catch{r("candidate output not valid JSON, skipping");}}}}catch(s){r(`error probing candidate ${o}: ${String(s)}`);}}return r("no valid rapidkit found on PATH"),false}catch(e){return r(`PATH probe error: ${String(e)}`),false}}async function T(t){let n=(t??"").toString().trim();if(!n)return false;try{let r=JSON.parse(n);return !!r&&typeof r=="object"&&r!==null&&"version"in r}catch{return false}}async function lt(t){let n=u.relative(".",g(".venv")),r=u.relative(".",f(".venv")),e=t;for(let i=0;i<25;i+=1){let o=u.join(e,n);if(await p.pathExists(o)){let c=await execa(o,["--version","--json"],{reject:false,stdio:"pipe",timeout:1500,cwd:e});if(c.exitCode===0&&await T(c.stdout))return {cmd:o,baseArgs:[]}}let s=u.join(e,r);if(await p.pathExists(s)){let c=await execa(s,["-m","rapidkit","--version","--json"],{reject:false,stdio:"pipe",timeout:1500,cwd:e});if(c.exitCode===0&&await T(c.stdout))return {cmd:s,baseArgs:["-m","rapidkit"]}}let a=u.dirname(e);if(a===e)break;e=a;}return null}async function mt(t){try{let n=u.join(t,".python-version");if(await p.pathExists(n)){let e=(await p.readFile(n,"utf-8")).trim();if(e)return e}}catch{}try{let n=u.join(t,".rapidkit-workspace");if(await p.pathExists(n)){let r=await p.readFile(n,"utf-8"),e=JSON.parse(r);if(e.pythonVersion)return e.pythonVersion}}catch{}return null}async function M(t){if(t&&t.trim())try{let o=await lt(t);if(o){let s=u.dirname(o.cmd).includes(".venv")?u.dirname(u.dirname(u.dirname(o.cmd))):u.dirname(o.cmd),a=await mt(s);return a&&(process.env.PYENV_VERSION=a),o}}catch{}let n=await Ct();if(n.kind==="venv"){let o=ut(n.pythonPath),s=K(o);return await p.pathExists(s)?{cmd:s,baseArgs:[]}:{cmd:n.pythonPath,baseArgs:["-m","rapidkit"]}}try{if((await execa(n.cmd,["-m","rapidkit","--version","--json"],{reject:false,stdio:"pipe",timeout:4e3})).exitCode===0)return {cmd:n.cmd,baseArgs:["-m","rapidkit"]}}catch{}try{let s=((await execa(n.cmd,["-c","import sysconfig, os; print(os.path.join(sysconfig.get_path('scripts'), 'rapidkit'))"],{reject:false,stdio:"pipe",timeout:2e3})).stdout??"").toString().trim();if(s&&await p.pathExists(s))try{let a=await execa(s,["--version","--json"],{reject:false,stdio:"pipe",timeout:4e3});if(a.exitCode===0&&await T(a.stdout))return {cmd:s,baseArgs:[]}}catch{}}catch{}let r=Z(),e=await A(n.cmd),i=K(r);return await p.pathExists(i)?{cmd:i,baseArgs:[]}:{cmd:e,baseArgs:["-m","rapidkit"]}}async function V(){for(let t of W())try{return await execa(t,w(t,["--version"]),{reject:false,stdio:"pipe",timeout:2e3}),t}catch{}return null}async function ft(){let t=!!process.env.RAPIDKIT_DEBUG,n=e=>{t&&process.stderr.write(`[DEBUG] checkRapidkitCore: ${e}
16
+ `);},r=Array.from(new Set([...d(),...e(14,10).map(e=>e.command)]));for(let e of r)try{n(`Method 1: trying ${e} import`);let i=await execa(e,w(e,["-c","import rapidkit_core; print(1)"]),{reject:false,stdio:"pipe",timeout:3e3});if(i.exitCode===0&&i.stdout?.trim()==="1")return n(`\u2713 Found via ${e} import`),true}catch{continue}for(let e of r)try{n(`Method 2: trying ${e} -m pip show`);let i=await execa(e,w(e,["-m","pip","show","rapidkit-core"]),{reject:false,stdio:"pipe",timeout:3e3});if(i.exitCode===0&&i.stdout?.includes("Name: rapidkit-core"))return n(`\u2713 Found via ${e} -m pip show`),true}catch{continue}for(let e of ["pip","pip3"])try{n(`Method 3: trying ${e} show`);let i=await execa(e,["show","rapidkit-core"],{reject:false,stdio:"pipe",timeout:3e3});if(i.exitCode===0&&i.stdout?.includes("Name: rapidkit-core"))return n(`\u2713 Found via ${e} show`),true}catch{continue}try{n("Method 4: checking pyenv versions");let e=await execa("pyenv",["versions","--bare"],{reject:false,stdio:"pipe",timeout:3e3});if(e.exitCode===0&&e.stdout){let i=e.stdout.split(`
17
+ `).filter(o=>o.trim());n(`Found pyenv versions: ${i.join(", ")}`);for(let o of i){let s=process.env.PYENV_ROOT||u.join(z.homedir(),".pyenv"),a=u.join(s,"versions",o.trim(),"bin","pip");try{let c=await execa(a,["show","rapidkit-core"],{reject:false,stdio:"pipe",timeout:3e3});if(c.exitCode===0&&c.stdout?.includes("Name: rapidkit-core"))return n(`\u2713 Found in pyenv ${o}`),true}catch{try{let c=await execa("pyenv",["exec","pip","show","rapidkit-core"],{reject:false,stdio:"pipe",timeout:3e3,env:{...process.env,PYENV_VERSION:o.trim()}});if(c.exitCode===0&&c.stdout?.includes("Name: rapidkit-core"))return n(`\u2713 Found in pyenv ${o} via PYENV_VERSION`),true}catch{continue}}}}}catch{n("pyenv not available");}for(let e of r)try{n(`Method 5: checking ${e} user site`);let i=await execa(e,w(e,["-m","site","--user-site"]),{reject:false,stdio:"pipe",timeout:3e3});if(i.exitCode===0&&i.stdout){let o=i.stdout.trim(),s=u.join(o,"rapidkit_core");if(await p.pathExists(s))return n("\u2713 Found in user site-packages"),true}}catch{continue}try{n("Method 6: checking pipx");let e=await execa("pipx",["list"],{reject:false,stdio:"pipe",timeout:3e3});if(e.exitCode===0&&e.stdout?.includes("rapidkit-core"))return n("\u2713 Found via pipx"),true}catch{n("pipx not available");}for(let e of r)try{n(`Method 6: checking ${e} -m pipx list`);let i=await execa(e,w(e,["-m","pipx","list"]),{reject:false,stdio:"pipe",timeout:3e3});if(i.exitCode===0&&i.stdout?.includes("rapidkit-core"))return n(`\u2713 Found via ${e} -m pipx list`),true}catch{continue}try{if(n("Method 7: checking poetry"),(await execa("poetry",["show","rapidkit-core"],{reject:false,stdio:"pipe",timeout:3e3})).exitCode===0)return n("\u2713 Found via poetry"),true}catch{n("poetry check failed");}for(let e of r)try{if(n(`Method 7: checking ${e} -m poetry show rapidkit-core`),(await execa(e,w(e,["-m","poetry","show","rapidkit-core"]),{reject:false,stdio:"pipe",timeout:3e3})).exitCode===0)return n(`\u2713 Found via ${e} -m poetry`),true}catch{continue}try{n("Method 8: checking conda");let e=await execa("conda",["list","rapidkit-core"],{reject:false,stdio:"pipe",timeout:3e3});if(e.exitCode===0&&e.stdout?.includes("rapidkit-core"))return n("\u2713 Found via conda"),true}catch{n("conda not available");}return n("\u2717 Not found in any environment"),false}function ht(t){let n=t.trim();if(!n||!n.startsWith("rapidkit-core"))return null;let r=n.slice(13).trim();return !r||/[\/@]|\.whl$|\.tar\.gz$|\.zip$|git\+|https?:\/\//.test(r)?null:r}function L(t){let n=t.trim();if(!n)return null;let r=n.split("."),e=[];for(let i of r){let o=i.match(/^(\d+)/);if(!o){e.push(0);continue}e.push(Number.parseInt(o[1],10));}return e}function J(t,n){let r=Math.max(t.length,n.length);for(let e=0;e<r;e+=1){let i=e<t.length?t[e]:0,o=e<n.length?n[e]:0;if(i>o)return 1;if(i<o)return -1}return 0}function gt(t){return t.length<=1?[t[0]+1]:t.length===2?[t[0]+1,0]:[t[0],t[1]+1,0]}function yt(t){let n=t.split(",").map(e=>e.trim()).filter(Boolean);if(n.length===0)return null;let r=[];for(let e of n){let i=e.match(/^(==|>=|<=|>|<|~=)\s*([0-9][0-9A-Za-z+._-]*)$/);if(!i)return null;r.push({op:i[1],version:i[2]});}return r}function tt(t,n){let r=L(t);if(!r)return false;let e=yt(n);if(!e)return false;for(let i of e){let o=L(i.version);if(!o)return false;let s=J(r,o);if(i.op==="=="&&s!==0||i.op===">="&&s<0||i.op==="<="&&s>0||i.op===">"&&s<=0||i.op==="<"&&s>=0)return false;if(i.op==="~="){if(s<0)return false;let a=gt(o);if(J(r,a)>=0)return false}}return true}async function wt(){let t=Array.from(new Set([...d(),...e(14,10).map(r=>r.command)])),n=r=>{let e=r.match(/^Version:\s*(.+)$/m);return e?e[1].trim():null};for(let r of t)try{let e=await execa(r,w(r,["-m","pip","show","rapidkit-core"]),{reject:false,stdio:"pipe",timeout:3e3});if(e.exitCode===0){let i=n(e.stdout||"");if(i)return i}}catch{continue}for(let r of ["pip","pip3"])try{let e=await execa(r,["show","rapidkit-core"],{reject:false,stdio:"pipe",timeout:3e3});if(e.exitCode===0){let i=n(e.stdout||"");if(i)return i}}catch{continue}try{let r=await execa("pipx",["list"],{reject:false,stdio:"pipe",timeout:3e3});if(r.exitCode===0&&r.stdout){let e=r.stdout.match(/rapidkit-core\s+([0-9][0-9A-Za-z+._-]*)/i);if(e?.[1])return e[1]}}catch{}return null}async function vt(){let t=b(),n=ht(t);if(!n)return {isCompatible:false,installedVersion:null,expectedConstraint:null,reason:X(t)?"constraint-unsupported":"constraint-missing"};let r=await wt();if(!r)return {isCompatible:false,installedVersion:null,expectedConstraint:n,reason:"version-not-detected"};let e=tt(r,n);return {isCompatible:e,installedVersion:r,expectedConstraint:n,reason:e?"compatible":"incompatible-version"}}async function A(t){let n=Z(),r=pt(),e=b(),i=[n];!X(e)&&!await p.pathExists(n)&&await p.pathExists(r)&&i.push(r);for(let l of i){let h=G(l);if(await p.pathExists(h))try{let f=await execa(h,["-c","import importlib.util; print(1 if importlib.util.find_spec('rapidkit') else 0)"],{reject:false,stdio:"pipe",timeout:2e3});if(f.exitCode===0&&(f.stdout??"").toString().trim()==="1")return h;await p.remove(l);}catch{await p.remove(l);}}let o=n,s={...process.env,PIP_DISABLE_PIP_VERSION_CHECK:"1",PIP_NO_PYTHON_VERSION_WARNING:"1"},a=Math.max(0,Number(process.env.RAPIDKIT_BRIDGE_PIP_RETRY??"2")),c=Math.max(200,Number(process.env.RAPIDKIT_BRIDGE_PIP_RETRY_DELAY_MS??"800")),m=Math.max(1e4,Number(process.env.RAPIDKIT_BRIDGE_PIP_TIMEOUT_MS??"120000")),v=l=>new Promise(h=>setTimeout(h,l)),C=async(l,h,f)=>{let g=await execa(l,h,{reject:false,stdio:["ignore","pipe","inherit"],env:s,timeout:f});if(g.exitCode===0)return;let I=(g.stdout??"").toString(),D=(g.stderr??"").toString(),E=[I,D].filter(Boolean).join(`
18
+ `),it=E?`${l} ${h.join(" ")}
19
+ ${E}`:`${l} ${h.join(" ")}`;throw new Error(it)},_=async(l,h,f)=>{let g=0;for(;;)try{await C(l,h,f);return}catch(I){if(g>=a)throw I;let D=Math.floor(Math.random()*200),E=c*Math.pow(2,g)+D;g+=1,await v(E);}};try{await p.ensureDir(u.dirname(o));try{await C(t,w(t,["-m","venv",o]),6e4);}catch(f){let g=f instanceof Error?f.message:String(f);throw new y("BRIDGE_VENV_CREATE_FAILED",g)}let l=G(o);if((await execa(l,["-m","pip","--version"],{reject:false,stdio:"pipe",timeout:2e3})).exitCode!==0&&(await execa(l,["-m","ensurepip","--default-pip"],{reject:false,stdio:["ignore","pipe","inherit"],env:s,timeout:6e4})).exitCode!==0)throw new y("BRIDGE_PIP_BOOTSTRAP_FAILED","ensurepip failed; install python3-venv/python3-pip and retry.");if(process.env.RAPIDKIT_BRIDGE_UPGRADE_PIP==="1")try{await _(l,["-m","pip","install","-U","pip"],m);}catch(f){let g=f instanceof Error?f.message:String(f);throw new y("BRIDGE_PIP_UPGRADE_FAILED",g)}try{await _(l,["-m","pip","install","-U",b()],m);}catch(f){let g=f instanceof Error?f.message:String(f);throw new y("BRIDGE_PIP_INSTALL_FAILED",g)}return l}catch(l){if(l instanceof y)throw l;let h=l instanceof Error?l.message:String(l);throw new y("BRIDGE_VENV_BOOTSTRAP_FAILED",h)}}async function Ct(){if(process.env.RAPIDKIT_BRIDGE_FORCE_VENV==="1"){let r=await V();if(!r)throw new y("PYTHON_NOT_FOUND","No Python interpreter found (python3/python/py).");return {kind:"venv",pythonPath:await A(r)}}for(let r of W())if(await Q(r))return {kind:"system",cmd:r};let t=await V();if(!t)throw new y("PYTHON_NOT_FOUND","No Python interpreter found (python3/python/py).");return {kind:"venv",pythonPath:await A(t)}}async function jt(t,n){try{let r=await M(n?.cwd),e=r.cmd,i=[...r.baseArgs,...t];if(t[0]==="init"){let a=await execa(e,i,{cwd:n?.cwd,env:{...process.env,...n?.env},reject:false,stdio:"pipe"}),c=F((a.stdout??"").toString()),m=F((a.stderr??"").toString());return c&&process.stdout.write(c.endsWith(`
20
+ `)?c:`${c}
21
+ `),m&&process.stderr.write(m.endsWith(`
22
+ `)?m:`${m}
23
+ `),typeof a.exitCode=="number"?a.exitCode:1}let s=await execa(e,i,{cwd:n?.cwd,env:{...process.env,...n?.env},reject:false,stdio:"inherit"});return typeof s.exitCode=="number"?s.exitCode:1}catch(r){return process.stderr.write(`${R(r)}
24
+ `),1}}var Pt=[{pattern:/RapidKitError:\s*Directory '([^']+)' exists and force is not set/,message:t=>`\u274C Directory "${u.basename(t[1])}" already exists.
25
+ \u{1F4A1} Choose a different name, or remove the existing directory first:
26
+ rm -rf ${t[1]}`},{pattern:/RapidKitError:\s*Project name '([^']+)' is (invalid|not allowed)/i,message:t=>`\u274C Invalid project name: "${t[1]}"
27
+ \u{1F4A1} Use lowercase letters, numbers, and hyphens only (e.g. my-api).`},{pattern:/RapidKitError:\s*Kit '([^']+)' not found/i,message:t=>`\u274C Unknown kit: "${t[1]}"
28
+ \u{1F4A1} Run "npx rapidkit list" to see available kits.`},{pattern:/RapidKitError:\s*(.+)/,message:t=>`\u274C ${t[1].trim()}`}];async function Nt(t,n){let{spawn:r}=await import('child_process');try{let e=await M(n?.cwd),i=e.cmd,o=[...e.baseArgs,...t];return await new Promise(s=>{let a=r(i,o,{cwd:n?.cwd,env:{...process.env,...n?.env},stdio:["inherit","inherit","pipe"]}),c=[];a.stderr?.on("data",m=>{c.push(m);}),a.on("close",m=>{let v=m??1;if(v!==0&&c.length>0){let C=Buffer.concat(c).toString("utf8");for(let{pattern:_,message:l}of Pt){let h=C.match(_);if(h){process.stderr.write(l(h)+`
29
+ `),s(v);return}}process.stderr.write(C);}s(v);}),a.on("error",m=>{process.stderr.write(`${R(m)}
30
+ `),s(1);});})}catch(e){return process.stderr.write(`${R(e)}
31
+ `),1}}async function P(t,n){try{let r=await M(n?.cwd),e=r.cmd,i=[...r.baseArgs,...t],o=await execa(e,i,{cwd:n?.cwd,env:{...process.env,...n?.env},reject:false,stdio:"pipe"});return {exitCode:typeof o.exitCode=="number"?o.exitCode:1,stdout:(o.stdout??"").toString(),stderr:(o.stderr??"").toString()}}catch(r){return {exitCode:1,stdout:"",stderr:`${R(r)}
32
+ `}}}function et(t){let n=new Set,r=t.split(`
33
+ `),e=false;for(let i of r){let o=i.replace(/\r$/,"");if(!e){/^\s*Commands:\s*$/i.test(o)&&(e=true);let c=o.match(/^\s*rapidkit\s+([a-z0-9_-]+)\b/i);if(c){let m=c[1].trim();m&&!m.startsWith("-")&&n.add(m);}continue}if(!o.trim())break;if(/^\s*(Options|Arguments|Usage|Commands)\s*:/i.test(o))continue;let s=o.match(/^\s*([a-z0-9][a-z0-9_-]*)\b/i);if(!s)continue;let a=s[1].trim();a&&!a.startsWith("-")&&n.add(a);}return n}async function nt(){let t=q();if(!await p.pathExists(t))return null;try{let n=await p.readJson(t);if(n&&n.schema_version===1&&Array.isArray(n.commands))return n}catch{}return null}async function U(t){let n=q();await p.ensureDir(u.dirname(n)),await p.writeJson(n,t,{spaces:2});}async function _t(){let t=await P(["version","--json"],{cwd:process.cwd()});if(t.exitCode===0)try{let r=JSON.parse(t.stdout)?.version;return typeof r=="string"?r:void 0}catch{return}}async function Et(){let t=await P(["commands","--json"],{cwd:process.cwd()});if(t.exitCode!==0)return null;try{let n=JSON.parse(t.stdout);if(n?.schema_version!==1||!Array.isArray(n.commands))return null;let r=n.commands.filter(e=>typeof e=="string");return r.length?r:null}catch{return null}}async function $t(){let n=Date.now(),r=await nt(),e=await _t(),i=!!r?.commands?.length;if(i&&n-r.fetched_at<864e5&&(!e||!r.rapidkit_version||r.rapidkit_version===e))return new Set(r.commands);let o=await Et();if(o?.length){let m=Array.from(new Set(o)).sort();return await U({schema_version:1,fetched_at:n,rapidkit_version:e,commands:m}),new Set(m)}let s=await P(["--help"],{cwd:process.cwd()});if(s.exitCode!==0)return i&&r?.commands?new Set(r.commands):new Set($);let a=et(s.stdout);if(a.size===0)return new Set($);let c=Array.from(a).sort();return await U({schema_version:1,fetched_at:n,rapidkit_version:e,commands:c}),a}async function Tt(){let n=Date.now(),r=await nt();return !r||n-r.fetched_at>=864e5||!r.commands?.length?null:new Set(r.commands)}function rt(){return u.join(S(),"rapidkit","npm-bridge","modules-catalog.json")}async function xt(){let t=rt();if(!await p.pathExists(t))return null;try{let n=await p.readJson(t);if(n&&n.schema_version===1&&Array.isArray(n.modules))return n}catch{}return null}async function H(t){let n=rt();await p.ensureDir(u.dirname(n)),await p.writeJson(n,t,{spaces:2});}function Y(t){try{return JSON.parse(t)}catch{return null}}async function Vt(t={}){let n=typeof t.ttlMs=="number"?t.ttlMs:18e5,r=Date.now(),e=await xt();if(e?.fetched_at&&r-e.fetched_at<n)return e;let i=["modules","list","--json-schema","1"];t.category&&i.push("--category",t.category),t.tag&&i.push("--tag",t.tag),t.detailed&&i.push("--detailed");let o=await P(i,{cwd:t.cwd,env:t.env});if(o.exitCode===0){let a=Y(o.stdout);if(a&&a.schema_version===1&&Array.isArray(a.modules)){let c={...a,fetched_at:r};return await H(c),c}}let s=await P(["modules","list","--json"],{cwd:t.cwd,env:t.env});if(s.exitCode===0){let a=Y(s.stdout);if(Array.isArray(a)){let c={schema_version:1,generated_at:new Date().toISOString(),filters:{category:t.category??null,tag:t.tag??null,detailed:!!t.detailed},stats:{total:a.length,returned:a.length,invalid:0},modules:a,source:"legacy-json",fetched_at:r};return await H(c),c}}return e||null}var Mt={pickSystemPython:V,ensureBridgeVenv:A,parseCoreCommandsFromHelp:et,tryRapidkit:Q,checkRapidkitCoreAvailable:ft,checkRapidkitCoreVersionCompatible:vt,isVersionSatisfyingConstraint:tt};export{$ as a,ft as b,vt as c,Ct as d,jt as e,Nt as f,P as g,$t as h,Tt as i,Vt as j,Mt as k};
@@ -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};