rapidkit 0.30.0 → 0.31.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 +61 -1
- package/dist/{autopilot-release-OLDRCIPK.js → autopilot-release-T4N4KHO6.js} +1 -1
- package/dist/chunk-CQXWD2ZG.js +3 -0
- package/dist/{create-RDLT34XT.js → create-KZYI3QRI.js} +5 -5
- package/dist/index.d.ts +3 -2
- package/dist/index.js +196 -185
- package/dist/{workspace-2JHFIZ3J.js → workspace-YLFC25EZ.js} +17 -17
- package/dist/workspace-archive-LVP3EMGI.js +3 -0
- package/dist/workspace-contract-4UCEM44I.js +2 -0
- package/dist/workspace-run-TGNMTL2V.js +1 -0
- package/package.json +8 -4
- package/scripts/check-cli-resolution.cjs +69 -0
- package/dist/chunk-SCMT5HXC.js +0 -3
- package/dist/workspace-run-AVX2C5IF.js +0 -1
package/README.md
CHANGED
|
@@ -146,6 +146,15 @@ npx rapidkit doctor workspace [--fix] [--plan] [--apply]
|
|
|
146
146
|
npx rapidkit doctor project [--fix] [--plan] [--apply]
|
|
147
147
|
npx rapidkit workspace list # Display all workspaces created on this system
|
|
148
148
|
npx rapidkit workspace share [--output <file>] [--include-paths] [--no-doctor]
|
|
149
|
+
npx rapidkit workspace contract init [--force] [--json]
|
|
150
|
+
npx rapidkit workspace contract inspect [--json]
|
|
151
|
+
npx rapidkit workspace contract verify [--strict] [--json]
|
|
152
|
+
npx rapidkit workspace contract graph [--json]
|
|
153
|
+
npx rapidkit workspace export --output team-workspace.rapidkit-archive.zip
|
|
154
|
+
npx rapidkit workspace archive inspect team-workspace.rapidkit-archive.zip [--json]
|
|
155
|
+
npx rapidkit workspace archive verify team-workspace.rapidkit-archive.zip [--strict] [--json]
|
|
156
|
+
npx rapidkit workspace archive doctor team-workspace.rapidkit-archive.zip [--strict] [--json]
|
|
157
|
+
npx rapidkit workspace hydrate team-workspace.rapidkit-archive.zip --output ./team-workspace
|
|
149
158
|
npx rapidkit import <path|git-url> [--workspace <path>] [--name <project-name>] [--git] [--json]
|
|
150
159
|
npx rapidkit snapshot create [name] [--include-projects] [--reason <text>] [--json]
|
|
151
160
|
npx rapidkit snapshot list [--json]
|
|
@@ -248,6 +257,53 @@ Bundle content includes:
|
|
|
248
257
|
|
|
249
258
|
`--include-paths` is intended for internal teams only because it includes absolute filesystem paths.
|
|
250
259
|
|
|
260
|
+
### Workspace contract registry
|
|
261
|
+
|
|
262
|
+
Use `workspace contract` when multiple projects in one workspace need a shared source of truth for
|
|
263
|
+
services, ports, APIs, events, owners, dependencies, and required environment variables.
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
npx rapidkit workspace contract init
|
|
267
|
+
npx rapidkit workspace contract inspect
|
|
268
|
+
npx rapidkit workspace contract verify --strict
|
|
269
|
+
npx rapidkit workspace contract graph
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The contract is written to `.rapidkit/workspace.contract.json`. It starts from discovered RapidKit
|
|
273
|
+
projects and gives teams a stable place to declare cross-project service contracts. Verification
|
|
274
|
+
checks schema validity, duplicate project slugs, invalid or colliding ports, and dependencies that
|
|
275
|
+
point to unknown projects.
|
|
276
|
+
|
|
277
|
+
RapidKit keeps this contract alive during normal workspace work:
|
|
278
|
+
|
|
279
|
+
- `create project` syncs the contract after successful project creation inside a workspace.
|
|
280
|
+
- `workspace sync` reconciles discovered projects into the contract without overwriting manually declared APIs, events, owners, dependencies, env vars, or custom ports.
|
|
281
|
+
- New projects receive a framework-aware default HTTP port when possible, and the next free port is selected if the default is already claimed.
|
|
282
|
+
- `workspace share` includes the contract snapshot so teammates can inspect service topology before reproducing or importing the workspace.
|
|
283
|
+
- `workspace contract graph` renders the service/dependency/event topology for humans or returns a JSON graph for tools and UI surfaces.
|
|
284
|
+
|
|
285
|
+
### Portable workspace archives
|
|
286
|
+
|
|
287
|
+
Use `workspace export` when you need to send a full workspace to a teammate or move it to another machine.
|
|
288
|
+
Export excludes dependency folders, build output, git history, logs, `.env` files, and private keys by default.
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
npx rapidkit workspace export --output team-workspace.rapidkit-archive.zip
|
|
292
|
+
npx rapidkit workspace archive inspect team-workspace.rapidkit-archive.zip
|
|
293
|
+
npx rapidkit workspace archive verify team-workspace.rapidkit-archive.zip --strict
|
|
294
|
+
npx rapidkit workspace archive doctor team-workspace.rapidkit-archive.zip
|
|
295
|
+
npx rapidkit workspace hydrate team-workspace.rapidkit-archive.zip --output ./team-workspace
|
|
296
|
+
|
|
297
|
+
# Preview a hydrate without writing files
|
|
298
|
+
npx rapidkit workspace hydrate team-workspace.rapidkit-archive.zip --output ./team-workspace --dry-run
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Archives include a RapidKit/Workspai manifest with file sizes and SHA-256 checksums. `workspace hydrate`
|
|
302
|
+
verifies the archive before writing files. Use `workspace archive verify --strict` as a handoff or CI gate,
|
|
303
|
+
and `workspace archive doctor` when you want human-readable readiness/security guidance before a teammate
|
|
304
|
+
imports the workspace. Use `--include-env` only for trusted internal handoffs when you intentionally need
|
|
305
|
+
environment files inside the archive.
|
|
306
|
+
|
|
251
307
|
### Command ownership
|
|
252
308
|
|
|
253
309
|
RapidKit keeps the wrapper boundary explicit so users know which layer owns each action.
|
|
@@ -476,13 +532,17 @@ npx rapidkit workspace run test --parallel
|
|
|
476
532
|
# Test only affected projects since last commit
|
|
477
533
|
npx rapidkit workspace run test --affected --since HEAD~1
|
|
478
534
|
|
|
479
|
-
# Test affected +
|
|
535
|
+
# Test affected + downstream dependents from workspace.contract.json
|
|
480
536
|
npx rapidkit workspace run test --affected --blast-radius
|
|
481
537
|
|
|
482
538
|
# Build specific projects with custom stages (if defined in .rapidkit/context.json)
|
|
483
539
|
npx rapidkit workspace run build --json --max-workers 8
|
|
484
540
|
```
|
|
485
541
|
|
|
542
|
+
`--blast-radius` uses `.rapidkit/workspace.contract.json` when available. It expands direct
|
|
543
|
+
`dependsOn` relationships and event relationships where one project `publishes` an event and another
|
|
544
|
+
project `consumes` it. Legacy `.rapidkit/workspace-dependency-graph.json` remains supported as a fallback.
|
|
545
|
+
|
|
486
546
|
### Supported Runtimes & Frameworks
|
|
487
547
|
|
|
488
548
|
| Runtime | Frameworks | Status |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {a}from'./chunk-
|
|
1
|
+
import {a}from'./chunk-CQXWD2ZG.js';import n from'chalk';import W from'fs';import g from'path';import {execa}from'execa';function b(s){try{return JSON.parse(s)}catch{return null}}function ie(s){let t=g.resolve(s);for(;;){if(W.existsSync(g.join(t,".rapidkit-workspace"))||W.existsSync(g.join(t,".rapidkit","workspace.json")))return t;let a=g.dirname(t);if(a===t)return null;t=a;}}function le(s){let t=g.resolve(s),a=ie(t);if(!a)throw new Error("No RapidKit workspace found in current directory or parents");return a}async function S(s,t){let a=process.argv[1];if(!a)return {exitCode:1,stdout:"",stderr:"RapidKit entrypoint is unavailable for autopilot execution.",crashed:true};try{let o=await execa(process.execPath,[a,...s],{cwd:t,reject:false,env:{...process.env,RAPIDKIT_AUTOPILOT_CHILD:"1"}});return {exitCode:Number(o.exitCode??1),stdout:o.stdout,stderr:o.stderr,crashed:false}}catch(o){return {exitCode:1,stdout:"",stderr:o instanceof Error?o.message:String(o),crashed:true}}}function H(s){let t=s.toLowerCase();return t==="pass"?"pass":t==="warn"?"warn":t==="fail"?"fail":"warn"}function U(s){return s.summary.failed>0?"fail":s.gates.results.some(t=>t.status==="warn")?"warn":"pass"}function ce(s){let t=s.filter(o=>o.status!=="skipped");if(t.length===0)return 100;let a=t.reduce((o,r)=>r.status==="pass"?o+1:r.status==="warn"?o+.6:o,0);return Math.round(a/t.length*100)}function ue(s){return s.executionError?["Re-run: npx rapidkit autopilot release --mode audit --json","Inspect .rapidkit/reports/autopilot-release-last-run.json for execution failure details"]:s.blockers.length>0?["Run: npx rapidkit doctor workspace --plan","Run: npx rapidkit readiness --json --strict","Run: npx rapidkit workspace run test --affected --strict"]:s.hasWarnings&&s.mode!=="enforce"?["Review warning-level findings in autopilot report","Optionally run: npx rapidkit autopilot release --mode safe-fix"]:["Workspace is release-ready based on current autopilot policy"]}async function N(s,t){await W.promises.mkdir(g.dirname(s),{recursive:true}),await W.promises.writeFile(s,`${JSON.stringify(t,null,2)}
|
|
2
2
|
`,"utf-8");}async function ke(s){let t=le(s.workspacePath),a$1=s.mode,o=[],r=[],M,F,E,J=0,f=false,I=0,T=0,_=Date.now(),x=await S(["doctor","workspace","--json"],t),q=Date.now()-_,u="pass";if(x.crashed)u="fail",f=true,r.push(`doctor workspace execution error: ${x.stderr||"unknown error"}`);else if(x.exitCode!==0)u="fail",r.push("doctor workspace command failed");else {let e=b(x.stdout),i=e&&e.healthScore&&typeof e.healthScore=="object"?e.healthScore:{},l=Number(i.errors??0),c=Number(i.warnings??0);Number.isFinite(l)&&l>0?(u="fail",r.push(`doctor workspace reports ${l} error(s)`)):Number.isFinite(c)&&c>0&&(u="warn");}let L=o.push({name:"doctor-workspace",status:u,durationMs:q,summary:u==="pass"?"doctor workspace passed":u==="warn"?"doctor workspace reported warnings":"doctor workspace reported errors"})-1;a$1==="enforce"&&u==="warn"&&r.push("doctor workspace reported warnings under enforce mode");let z=Date.now(),A=await S(["readiness","--json"],t),O=Date.now()-z,p="fail";if(A.crashed)p="fail",f=true,r.push(`readiness execution error: ${A.stderr||"unknown error"}`);else if(A.exitCode!==0)p="fail",r.push("readiness command failed");else {let e=b(A.stdout),i=String(e?.overallStatus??"fail");if(p=H(i),typeof e?.evidencePath=="string"&&e.evidencePath.trim().length>0&&(M=e.evidencePath),p==="fail"){let l=Array.isArray(e?.blockingReasons)?e?.blockingReasons.filter(c=>typeof c=="string"):[];l.length>0?r.push(...l.map(c=>`readiness: ${c}`)):r.push("readiness overall status is fail");}}let V=o.push({name:"readiness",status:p,durationMs:O,summary:`readiness overall status is ${p}`})-1;a$1==="enforce"&&p==="warn"&&r.push("readiness reported warnings under enforce mode");let Q=Date.now(),v=await S(["doctor","workspace","--plan","--json"],t),X=Date.now()-Q,w="warn";if(v.crashed)w="fail",f=true,r.push(`doctor remediation plan execution error: ${v.stderr||"unknown error"}`);else if(v.exitCode!==0)w="fail",r.push("doctor remediation plan command failed");else {let e=b(v.stdout),i=e&&e.remediationPlan&&typeof e.remediationPlan=="object"?e.remediationPlan:null,l=Number(i?.totalSteps??0),c=Number(i?.executableSteps??0);Number.isFinite(l)&&l>0&&(I=l),Number.isFinite(c)&&c>0&&(T=c),Number.isFinite(l)&&l===0?w="pass":w="warn";}if(o.push({name:"remediation-plan",status:w,durationMs:X,summary:w==="pass"?"no remediation steps required":"remediation steps available"}),a$1==="enforce"&&w==="warn"&&r.push("remediation plan has pending steps under enforce mode"),a$1==="safe-fix"){let e=Date.now(),i=await S(["doctor","workspace","--apply"],t),l=Date.now()-e,c=i.crashed||i.exitCode!==0?"fail":"pass";if(i.crashed)f=true,r.push(`doctor remediation apply execution error: ${i.stderr||"unknown error"}`);else if(c==="fail")r.push("doctor remediation apply failed");else {J=T>0?T:I>0?I:1;let $=await S(["doctor","workspace","--json"],t);if($.crashed)u="fail",f=true,r.push(`post-apply doctor execution error: ${$.stderr||"unknown error"}`);else if($.exitCode!==0)u="fail",r.push("post-apply doctor workspace command failed");else {let m=b($.stdout),C=m&&m.healthScore&&typeof m.healthScore=="object"?m.healthScore:{},R=Number(C.errors??0),y=Number(C.warnings??0);Number.isFinite(R)&&R>0?(u="fail",r.push(`post-apply doctor reports ${R} error(s)`)):Number.isFinite(y)&&y>0?u="warn":u="pass";}o[L].status=u,o[L].summary=`doctor workspace post-apply status is ${u}`;let D=await S(["readiness","--json"],t);if(D.crashed)p="fail",f=true,r.push(`post-apply readiness execution error: ${D.stderr||"unknown error"}`);else if(D.exitCode!==0)p="fail",r.push("post-apply readiness command failed");else {let m=b(D.stdout),C=String(m?.overallStatus??"fail");if(p=H(C),typeof m?.evidencePath=="string"&&m.evidencePath.trim().length>0&&(M=m.evidencePath),p==="fail"){let R=Array.isArray(m?.blockingReasons)?m?.blockingReasons.filter(y=>typeof y=="string"):[];R.length>0?r.push(...R.map(y=>`post-apply readiness: ${y}`)):r.push("post-apply readiness overall status is fail");}}o[V].status=p,o[V].summary=`readiness post-apply overall status is ${p}`;}o.push({name:"remediation-apply",status:c,durationMs:l,summary:c==="pass"?"safe remediation apply completed":"safe remediation apply failed"});}else o.push({name:"remediation-apply",status:"skipped",durationMs:0,summary:"remediation apply is skipped for this mode"});let Y=Date.now(),h="pass",k="workspace test/build completed for selected projects";try{let e=await a({workspacePath:t,stage:"test",affected:true,since:s.since,parallel:s.parallel,maxWorkers:s.maxWorkers,strict:true,json:true,enforceGates:false});F=g.join(t,".rapidkit","reports","autopilot-workspace-run-test.json"),await N(F,e);let i=U(e);if(i==="fail")h="fail",k="workspace test stage failed for selected projects",r.push("workspace run test failed for selected projects");else {i==="warn"&&(h="warn",k="workspace test stage completed with warnings",a$1==="enforce"&&r.push("workspace run test reported warnings under enforce mode"));let l=await a({workspacePath:t,stage:"build",affected:true,since:s.since,parallel:s.parallel,maxWorkers:s.maxWorkers,strict:true,json:true,enforceGates:false});E=g.join(t,".rapidkit","reports","autopilot-workspace-run-build.json"),await N(E,l);let c=U(l);c==="fail"?(h="fail",k="workspace build stage failed for selected projects",r.push("workspace run build failed for selected projects")):c==="warn"&&(h="warn",k="workspace test/build completed with warnings",a$1==="enforce"&&r.push("workspace run test/build reported warnings under enforce mode"));}}catch(e){h="fail",k="workspace test/build orchestration failed",f=true,r.push(`workspace run orchestration error: ${e instanceof Error?e.message:String(e)}`);}let Z=Date.now()-Y;o.push({name:"workspace-run-test-build",status:h,durationMs:Z,summary:k});let P=o.filter(e=>e.status==="warn").length,ee=o.filter(e=>e.status==="fail").length,B=a$1==="enforce"?o.some(e=>e.status==="warn"||e.status==="fail"):ee>0,j=[...new Set(r)],te=f||B?Math.max(1,j.length):0,se=ce(o),re=f||B?"blocked":P>0?"partial":"approved",oe=f?3:B?1:P>0?2:0,ae=ue({mode:a$1,executionError:f,blockers:j,hasWarnings:P>0}),G=g.join(t,".rapidkit","reports","autopilot-release-last-run.json"),d={schemaVersion:"autopilot-release-v1",generatedAt:new Date().toISOString(),workspacePath:t,mode:a$1,summary:{releaseScore:se,verdict:re,blockers:te,warnings:P,safeFixesApplied:J,manualActions:j.length,exitCode:oe},stages:o,blockingReasons:j,nextActions:ae,artifacts:{reportPath:G,readinessEvidencePath:M,workspaceRunTestPath:F,workspaceRunBuildPath:E}};if(await N(G,d),s.output&&await N(g.resolve(s.output),d),!s.json){console.log(n.bold.cyan(`
|
|
3
3
|
\u{1F680} RapidKit Autopilot Release
|
|
4
4
|
`)),console.log(n.bold(`Workspace: ${n.cyan(g.basename(t))}`)),console.log(n.gray(`Path: ${t}`)),console.log(n.white(`Mode: ${a$1}`)),console.log(n.white(`Verdict: ${d.summary.verdict==="approved"?n.green("approved"):d.summary.verdict==="partial"?n.yellow("partial"):n.red("blocked")}`)),console.log(n.white(`Release score: ${d.summary.releaseScore}`));for(let e of d.stages){let i=e.status==="pass"?n.green("PASS"):e.status==="warn"?n.yellow("WARN"):e.status==="skipped"?n.gray("SKIP"):n.red("FAIL");console.log(` - ${e.name}: ${i} ${e.summary} (${e.durationMs}ms)`);}if(d.blockingReasons.length>0){console.log(n.bold.red(`
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {d,e,a as a$1,b}from'./chunk-TYC54P7X.js';import {a}from'./chunk-VKLL63TL.js';import D from'fs';import w from'path';import P from'chalk';import {execa}from'execa';var de={"python-fastapi":{runtime:"python",framework:"FastAPI",markers:["pyproject.toml","fastapi"],commands:{init:"python -m pip install -e .",test:"pytest",build:"python -m build",start:"uvicorn main:app --reload"},errorPatterns:{setup:["ModuleNotFoundError","No module named","pip: command not found"],"test-failure":["FAILED","ERROR","test session started"],dependency:["ImportError","missing.*dependency"],runtime:["TypeError","AttributeError","ValueError"],timeout:["timeout","Timeout","timed out"],unknown:[]},healthCheck:{stage:"start",type:"http",value:"http://localhost:8000/docs"},validation:{command:"python -m pip list | grep fastapi",error:"FastAPI not installed"}},"python-django":{runtime:"python",framework:"Django",markers:["manage.py","django"],commands:{init:"python manage.py migrate",test:"python manage.py test",build:"python manage.py collectstatic --noinput",start:"python manage.py runserver 0.0.0.0:8000"},errorPatterns:{setup:["ModuleNotFoundError","ProgrammingError.*migrate"],"test-failure":["FAILED","ERROR","Ran.*test"],dependency:["ImportError","missing.*dependency"],runtime:["DatabaseError","ImproperlyConfigured"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8e3},dependencies:["init"]},"node-nestjs":{runtime:"node",framework:"NestJS",markers:["package.json","@nestjs/core"],commands:{init:"npm install",test:"npm run test",build:"npm run build",start:"npm run start"},errorPatterns:{setup:["npm ERR!","ENOENT","not found"],"test-failure":["Tests.*failed","FAIL","fail.*test"],dependency:["Cannot find module","ERR_MODULE_NOT_FOUND"],runtime:["TypeError","Error: ","ReferenceError"],timeout:["timeout","TIMEOUT"],unknown:[]},healthCheck:{stage:"start",type:"port",value:3e3}},"node-express":{runtime:"node",framework:"Express",markers:["package.json","express"],commands:{init:"npm install",test:"npm run test",build:"npm run build",start:"npm start"},errorPatterns:{setup:["npm ERR!","ENOENT"],"test-failure":["failed","FAIL"],dependency:["Cannot find module"],runtime:["Error","TypeError"],timeout:["timeout"],unknown:[]}},"go-fiber":{runtime:"go",framework:"Fiber",markers:["go.mod","fiber"],commands:{init:"go mod download && go mod tidy",test:"go test ./...",build:"go build -o app .",start:"./app"},errorPatterns:{setup:["go: .*not found","cannot find","go mod tidy"],"test-failure":["FAIL","--- FAIL"],dependency:["missing.*module"],runtime:["panic","fatal","Error"],timeout:["timeout","context deadline"],unknown:[]},dependencies:["init"]},"go-gin":{runtime:"go",framework:"Gin",markers:["go.mod","gin-gonic"],commands:{init:"go mod download && go mod tidy",test:"go test ./...",build:"go build -o app .",start:"./app"},errorPatterns:{setup:["go: .*not found"],"test-failure":["FAIL"],dependency:["missing.*module"],runtime:["panic"],timeout:["timeout"],unknown:[]}},"java-springboot":{runtime:"java",framework:"Spring Boot",markers:["pom.xml","build.gradle","spring-boot"],commands:{init:"mvn dependency:go-offline",test:"mvn test",build:"mvn package -DskipTests",start:"mvn spring-boot:run"},errorPatterns:{setup:["\\[ERROR\\]","BUILD FAILURE","missing dependencies"],"test-failure":["\\[ERROR\\] Tests run:","BUILD FAILURE"],dependency:["missing.*dependency"],runtime:["Exception","Error","NullPointerException"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8080}},"php-laravel":{runtime:"php",framework:"Laravel",markers:["composer.json","artisan","app/Models"],commands:{init:"composer install && php artisan migrate:fresh --seed",test:"php artisan test",build:"php artisan config:cache && php artisan route:cache && php artisan view:cache",start:"php artisan serve --host=0.0.0.0 --port=8000"},errorPatterns:{setup:["Composer.*lock","Fatal error","Class.*not found"],"test-failure":["FAILED","Tests.*failed"],dependency:["Class.*not found","require.*failed"],runtime:["Fatal error","Exception","Error"],timeout:["timeout","Timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:8e3},dependencies:["init"]},"php-symfony":{runtime:"php",framework:"Symfony",markers:["composer.json","symfony.lock","bin/console"],commands:{init:"composer install && php bin/console doctrine:database:create",test:"php bin/phpunit",build:"php bin/console cache:clear --env=prod",start:"symfony serve --no-tls"},errorPatterns:{setup:["Composer.*error","Fatal error"],"test-failure":["FAILED","failure"],dependency:["Class.*not found"],runtime:["Fatal error","Exception"],timeout:["timeout"],unknown:[]},dependencies:["init"]},"rust-actix":{runtime:"rust",framework:"Actix-web",markers:["Cargo.toml","actix"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find","failed.*download"],"test-failure":["test result:","FAILED"],dependency:["can.t find.*crate"],runtime:["error\\[E","thread.*panicked"],timeout:["timeout"],unknown:[]},validation:{command:"cargo --version",error:"Rust/Cargo not installed"}},"rust-axum":{runtime:"rust",framework:"Axum",markers:["Cargo.toml","axum"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find"],"test-failure":["test result:","FAILED"],dependency:["can.t find.*crate"],runtime:["error\\[E"],timeout:["timeout"],unknown:[]}},"rust-rocket":{runtime:"rust",framework:"Rocket",markers:["Cargo.toml","rocket"],commands:{init:"cargo fetch",test:"cargo test",build:"cargo build --release",start:"cargo run --release"},errorPatterns:{setup:["error: .*could not find"],"test-failure":["FAILED"],dependency:["can.t find"],runtime:["error\\[E"],timeout:["timeout"],unknown:[]}},"dotnet-aspnetcore":{runtime:"dotnet",framework:"ASP.NET Core",markers:[".csproj",".sln","Program.cs"],commands:{init:"dotnet restore",test:"dotnet test",build:"dotnet build -c Release",start:"dotnet run"},errorPatterns:{setup:["error CS","CSPROJ.*not found","NuGet.*restore"],"test-failure":["Failed:.*test","FAILED"],dependency:["error NU1101"],runtime:["error CS","Exception"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:5e3}},"elixir-phoenix":{runtime:"elixir",framework:"Phoenix",markers:["mix.exs","phoenix"],commands:{init:"mix setup",test:"mix test",build:"mix compile --all-warnings",start:"mix phx.server"},errorPatterns:{setup:["\\*\\* \\(.*Error\\)","Mix.InstallError"],"test-failure":["\\d+\\sfailed","FAILED"],dependency:["dependencies are not available"],runtime:["\\*\\* \\(","RuntimeError"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:4e3},dependencies:["init"]},"ruby-rails":{runtime:"ruby",framework:"Rails",markers:["Gemfile","config/application.rb","bin/rails"],commands:{init:"bundle install && rails db:prepare",test:"rails test",build:"rails assets:precompile",start:"rails server --binding=0.0.0.0 --port=3000"},errorPatterns:{setup:["Bundler::.*Error","Gem::.*Error"],"test-failure":["failures,","error,","FAILED"],dependency:["Could not find.*gem"],runtime:["Error","Exception","NoMethodError"],timeout:["timeout"],unknown:[]},healthCheck:{stage:"start",type:"port",value:3e3},dependencies:["init"]},"ruby-sinatra":{runtime:"ruby",framework:"Sinatra",markers:["Gemfile","app.rb","sinatra"],commands:{init:"bundle install",test:"rspec",build:`echo "Sinatra apps don't require build"`,start:"ruby app.rb"},errorPatterns:{setup:["Bundler.*Error","Gem.*Error"],"test-failure":["failure","FAILED"],dependency:["Could not find.*gem"],runtime:["Error","NoMethodError"],timeout:["timeout"],unknown:[]}}},le={init:{python:["pip install -e .","poetry install","pip install -r requirements.txt"],node:["npm install","pnpm install","yarn install"],go:["go mod download && go mod tidy","go get ./..."],java:["mvn dependency:go-offline","gradle dependencies"],php:["composer install"],rust:["cargo fetch"],dotnet:["dotnet restore"],elixir:["mix deps.get"],ruby:["bundle install"],"jvm-generic":["mvn dependency:go-offline","gradle dependencies"],unknown:[]},test:{python:["pytest","python -m unittest","python -m pytest"],node:["npm test","npm run test"],go:["go test ./...","make test"],java:["mvn test","gradle test"],php:["php artisan test","phpunit","pest"],rust:["cargo test"],dotnet:["dotnet test"],elixir:["mix test"],ruby:["rspec","ruby -m minitest"],"jvm-generic":["mvn test","gradle test"],unknown:[]},build:{python:["python -m build","python setup.py build"],node:["npm run build"],go:["go build -o app .","go build ./..."],java:["mvn package -DskipTests","gradle build -x test"],php:['echo "PHP build: typically no build step"'],rust:["cargo build --release"],dotnet:["dotnet build -c Release"],elixir:["mix compile"],ruby:["gem build *.gemspec"],"jvm-generic":["mvn package -DskipTests","gradle build"],unknown:[]},start:{python:["python app.py","python main.py","uvicorn main:app --reload"],node:["npm start","node index.js","node src/index.js"],go:["./app","go run main.go","go run ./..."],java:["mvn spring-boot:run","gradle bootRun","java -jar target/*.jar"],php:["php -S 0.0.0.0:8000","php artisan serve"],rust:["cargo run --release","./target/release/app"],dotnet:["dotnet run"],elixir:["mix phx.server","iex -S mix"],ruby:["rails server","ruby app.rb","bundle exec puma"],"jvm-generic":["java -jar *.jar","gradle run"],unknown:[]}};function q(e,r,t){if(r){let s=r.trim().toLowerCase().replace(/[_.\s]+/g,"-"),u=a$1(r),a=`${e}-${u==="gofiber"?"fiber":u==="gogin"?"gin":u==="dotnet"?"aspnetcore":u!=="unknown"?u:s==="fiber"?"fiber":s==="aspnetcore"||s==="asp-net-core"?"aspnetcore":s}`,n=de[a];if(n&&n.commands[t])return n.commands[t]}let o=le[t]?.[e]??[];return o.length>0?o[0]:void 0}function pe(e){let r=d(e).map(t=>t==="python"?"python":t==="node"||t==="bun"?"node":t==="go"?"go":t==="java"?"java":t==="php"?"php":t==="rust"?"rust":t==="dotnet"?"dotnet":t==="elixir"?"elixir":t==="ruby"?"ruby":t==="clojure"||t==="scala"||t==="kotlin"?"jvm-generic":null).filter(t=>t!==null).filter((t,o,s)=>s.indexOf(t)===o);return {primary:r.length>0?r[0]:"unknown",secondary:r.slice(1)}}function Y(e){return pe(e).primary}function Q(e,r){if(!e)return "unknown";r||(r={setup:["ModuleNotFoundError","npm ERR!","error:","not found"],"test-failure":["FAILED","FAIL","failed"],dependency:["cannot find module","import.*error"],runtime:["Exception","Error:","panic","TypeError"],timeout:["timeout","Timeout","deadline exceeded"],unknown:[]});for(let[t,o]of Object.entries(r))for(let s of o)if(new RegExp(s,"i").test(e))return t;return "unknown"}async function X(e){let r=e.split(/[&|;]\s*/)[0].trim().split(/\s+/)[0];if(["echo","cd","pwd","test","true","false","exit"].includes(r))return {valid:true};try{let o=process.platform==="win32"?"where":"which";if((await execa(o,[r],{reject:false})).exitCode===0)return {valid:true}}catch{}return {valid:false,reason:`Command '${r}' not found or not executable`}}function Z(e,r,t){return r?t&&typeof r[t]=="string"?r[t]:typeof r.default=="string"?r.default:e:e}var me=new Set(["init","test","build","start"]),ge=new Set([".git","node_modules",".rapidkit",".venv","dist","build","coverage","htmlcov"]);async function W(e){try{return await D.promises.access(e,D.constants.F_OK),true}catch{return false}}async function te(e){let r=await D.promises.readFile(e,"utf-8");return JSON.parse(r)}async function fe(e,r){await D.promises.mkdir(w.dirname(e),{recursive:true}),await D.promises.writeFile(e,`${JSON.stringify(r,null,2)}
|
|
2
|
+
`,"utf-8");}function O(e){return e.replace(/\\/g,"/")}async function ye(e){return a(e,{skipDirs:ge,includeHiddenDirs:false,descendIntoMatchedProjects:false,isProjectDir:async(r,t)=>await W(w.join(r,".rapidkit","context.json"))||await W(w.join(r,".rapidkit","project.json"))?true:w.resolve(r)===w.resolve(t)?false:d(r).length>0})}async function he(e,r,t){let o=await execa("git",["diff","--name-only",`${t}...HEAD`],{cwd:e,reject:false});if(o.exitCode!==0)return new Set(r);let s=o.stdout.split(/\r?\n/).map(c=>c.trim()).filter(c=>c.length>0).map(c=>O(c));if(s.length===0)return new Set;let u=new Set;for(let c of r){let a=O(w.relative(e,c));if(!a||a===".")continue;let n=`${a}/`;s.some(p=>p===a||p.startsWith(n))&&u.add(c);}return u}async function ke(e,r,t){let o=w.join(e,".rapidkit","workspace.contract.json");if(await W(o))try{let g=await we(e,r,t,o);if(g.graphStatus!=="missing")return g}catch{return {expanded:t,graphStatus:"invalid",expansionDepth:0}}let s=w.join(e,".rapidkit","workspace-dependency-graph.json");if(!await W(s))return {expanded:t,graphStatus:"missing",expansionDepth:0};let u;try{u=await te(s);}catch{return {expanded:t,graphStatus:"invalid",expansionDepth:0}}let c=new Set(r.map(g=>w.resolve(g))),a=new Map;if(!u||typeof u!="object"||Array.isArray(u))return {expanded:t,graphStatus:"invalid",expansionDepth:0};let n=Array.isArray(u.projects)?u.projects:[];for(let g of n){if(!g||typeof g!="object"||Array.isArray(g))continue;let E=g,l=typeof E.path=="string"?E.path:"",i=w.resolve(e,l);if(!c.has(i))continue;let m=Array.isArray(E.dependsOn)?E.dependsOn.filter(y=>typeof y=="string"):[];for(let y of m){let h=w.resolve(e,y);c.has(h)&&(a.has(h)||a.set(h,new Set),a.get(h)?.add(i));}}let p=new Set(t),v=[...p],b=0;for(;v.length>0;){let g=v.shift();if(!g)continue;let E=a.get(g);if(E)for(let l of E)p.has(l)||(p.add(l),v.push(l),b+=1);}return {expanded:p,graphStatus:"loaded",expansionDepth:b}}async function we(e,r,t,o){let s=await te(o);if(!s||typeof s!="object"||Array.isArray(s))return {expanded:t,graphStatus:"invalid",expansionDepth:0};let u=s,c=Array.isArray(u.projects)?u.projects:null;if(!c)return {expanded:t,graphStatus:"invalid",expansionDepth:0};let a=new Map,n=new Map;for(let i of r){let m=O(w.relative(e,i));n.set(m,w.resolve(i));}let p=new Map,v=new Map,b=new Map;for(let i of c){if(!i||typeof i!="object"||Array.isArray(i))continue;let m=i,y=typeof m.slug=="string"?m.slug:"",h=typeof m.relativePath=="string"?O(m.relativePath):y,x=n.get(h);!y||!x||a.set(y,x);}for(let i of c){if(!i||typeof i!="object"||Array.isArray(i))continue;let m=i,y=typeof m.slug=="string"?m.slug:"",h=a.get(y);if(!h)continue;let x=m.contracts&&typeof m.contracts=="object"&&!Array.isArray(m.contracts)?m.contracts:{},I=Array.isArray(x.dependsOn)?x.dependsOn.filter(R=>typeof R=="string"):[],j=Array.isArray(x.publishes)?x.publishes.filter(R=>typeof R=="string"):[],T=Array.isArray(x.consumes)?x.consumes.filter(R=>typeof R=="string"):[];for(let R of I){let F=a.get(R);F&&(b.has(F)||b.set(F,new Set),b.get(F)?.add(h));}for(let R of j)p.has(R)||p.set(R,new Set),p.get(R)?.add(h);for(let R of T)v.has(R)||v.set(R,new Set),v.get(R)?.add(h);}for(let[i,m]of p.entries()){let y=v.get(i);if(y)for(let h of m){b.has(h)||b.set(h,new Set);for(let x of y)x!==h&&b.get(h)?.add(x);}}let g=new Set(t),E=[...g],l=0;for(;E.length>0;){let i=E.shift();if(!i)continue;let m=b.get(i);if(m)for(let y of m)g.has(y)||(g.add(y),E.push(y),l+=1);}return {expanded:g,graphStatus:"loaded",expansionDepth:l}}async function be(e,r){if(typeof r=="boolean")return r;let t=w.join(e,".rapidkit","policies.yml");if(!await W(t))return true;let o="";try{o=await D.promises.readFile(t,"utf-8");}catch{return true}let s=o.match(/^[\t ]*rules\.enforce_workspace_run_gates:\s*(true|false)\s*(?:#.*)?$/m);return s?s[1]==="true":true}async function G(e,r){let t=process.argv[1];if(!t)return {exitCode:1,stdout:"",stderr:"RapidKit entrypoint is unavailable for nested workspace-run execution."};let o=await execa(process.execPath,[t,...e],{cwd:r,reject:false,env:{...process.env,RAPIDKIT_WORKSPACE_RUN_CHILD:"1"}});return {exitCode:Number(o.exitCode??1),stdout:o.stdout,stderr:o.stderr}}function xe(e){return e==="node"||e==="go"||e==="java"||e==="python"}function Re(){return process.env.VITEST==="true"||process.env.VITEST==="1"||process.env.NODE_ENV==="test"}async function ve(e){let r=process.cwd();try{process.chdir(e);let{handleInitCommand:t}=await import('./index.js');return {exitCode:await t(["init"]),stdout:"",stderr:""}}finally{process.chdir(r);}}async function Ee(e$1){let r=a=>{let n=b(a);return n==="node"||n==="bun"?"node":n==="python"?"python":n==="go"?"go":n==="java"?"java":n==="php"?"php":n==="ruby"?"ruby":n==="rust"?"rust":n==="dotnet"?"dotnet":n==="elixir"?"elixir":n==="clojure"||n==="scala"||n==="kotlin"?"jvm-generic":Y(e$1)},t=a=>{if(!a)return;let n=a$1(a);if(new Set(["fastapi","django","flask","nestjs","express","fastify","koa","gofiber","gogin","echo","springboot","laravel","symfony","rails","sinatra","dotnet","actix","axum","rocket","phoenix"]).has(n))return n},o=w.join(e$1,".rapidkit","context.json");if(D.existsSync(o))try{let a=JSON.parse(D.readFileSync(o,"utf-8"));if(typeof a.runtime=="string"){let n={};if(a.commands&&typeof a.commands=="object")for(let[p,v]of Object.entries(a.commands))typeof v=="string"&&(n[p]=v);return {runtime:r(a.runtime),framework:t(typeof a.framework=="string"?a.framework:void 0),commandOverrides:Object.keys(n).length>0?n:void 0,environment:typeof a.environment=="string"?a.environment:void 0}}}catch{}let s=e(e$1),u=r(s.runtime),c=t(s.key);return {runtime:u,framework:c}}async function Se(e,r,t,o,s,u){let c=!s?.[r]&&xe(t),a;if(s&&s[r]?a=s[r]:c?a=`rapidkit ${r}`:a=q(t,o,r),!a)return {exitCode:127,command:`<stage not supported for ${t}>`,message:`No stage command found for runtime '${t}' and framework '${o||"unknown"}'`,errorCategory:"runtime"};let n=Z(a,s,u);if(!n)return {exitCode:127,command:a,message:"Failed to resolve stage command",errorCategory:"runtime"};if(!c){let l=await X(n);if(!l.valid)return {exitCode:127,command:n,message:l.reason||"Command not available",errorCategory:"setup"}}let p=0,v="",b="",g;try{let l=c?r==="init"&&Re()?await ve(e):await G([r],e):await execa(n,[],{cwd:e,reject:false,shell:true});if(p=Number(l.exitCode??0),v=l.stdout,b=l.stderr,p!==0){let i=`${v}
|
|
3
|
+
${b}`;g=Q(i);}}catch(l){return {exitCode:1,command:n,message:l instanceof Error?l.message:"Command execution failed",errorCategory:"runtime"}}return {exitCode:p,command:n,errorCategory:g,healthStatus:void 0,message:p!==0?`Stage failed with exit code ${p}`:void 0}}function ee(e){try{return JSON.parse(e)}catch{return null}}async function je(e){let r=[],t=await G(["doctor","workspace","--json"],e);if(t.exitCode!==0)r.push({gate:"doctor-workspace",status:"fail",summary:"doctor workspace command failed"});else {let u=ee(t.stdout)?.healthScore,c=Number(u?.errors??0);Number.isFinite(c)&&c>0?r.push({gate:"doctor-workspace",status:"fail",summary:`doctor workspace reports ${c} error(s)`}):r.push({gate:"doctor-workspace",status:"pass",summary:"doctor workspace passed"});}let o=await G(["readiness","--json"],e);if(o.exitCode!==0)r.push({gate:"readiness",status:"fail",summary:"readiness command failed"});else {let s=ee(o.stdout),u=String(s?.overallStatus??"").toLowerCase();u==="fail"?r.push({gate:"readiness",status:"fail",summary:"readiness overall status is fail"}):u==="warn"?r.push({gate:"readiness",status:"warn",summary:"readiness overall status is warn"}):r.push({gate:"readiness",status:"pass",summary:"readiness overall status is pass"});}return r}function Ce(e){return me.has(e)}function Pe(e,r){let t=Math.max(1,Math.min(4,r)),o=Number(e??t);return Number.isFinite(o)?Math.max(1,Math.min(16,Math.trunc(o))):t}async function Ve(e){if(!Ce(e.stage))throw new Error(`Unsupported workspace run stage: ${e.stage}`);let r=Date.now(),t=w.resolve(e.workspacePath),o=await ye(t),s=e.affected===true,u=e.blastRadius===true,c=e.since?.trim()||"HEAD~1",a=s?await he(t,o,c):new Set(o),n,p="not-applicable",v=0,b="all";if(s&&u){let d=await ke(t,o,a);n=d.expanded,p=d.graphStatus,v=d.expansionDepth,b="affected+blast-radius";}else s?(n=a,b="affected"):(n=a,b="all");let g=e.stage==="init"?false:await be(t,e.enforceGates),E=g?await je(t):[{gate:"doctor-workspace",status:"skipped",summary:"workspace run gates disabled"},{gate:"readiness",status:"skipped",summary:"workspace run gates disabled"}],l=E.find(d=>d.status==="fail"),i=o.filter(d=>n.has(d)),m=e.continueOnError===true,y=e.parallel===true,h=Pe(e.maxWorkers,i.length),x=i.length,I=0;e.json||console.log(P.gray(`Workspace run (${e.stage}) started: ${x} target(s), ${y?`parallel x${h}`:"sequential"}`));let j=new Map;for(let d of o)j.set(d,{path:d,relativePath:O(w.relative(t,d)),selected:n.has(d),affected:n.has(d),status:(n.has(d),"skipped"),exitCode:null,durationMs:0,reason:n.has(d)?void 0:"not affected",framework:void 0,runtimeDetected:void 0,executionCommand:void 0});if(l)for(let d of i){let k=j.get(d);k&&(k.status="skipped",k.reason=`blocked by ${l.gate}`);}else {let d=async k=>{let f=j.get(k);if(!f)return;let M=O(w.relative(t,k));e.json||console.log(P.gray(`\u23F3 [${I}/${x}] ${e.stage} ${M}`)),f.selected=true,f.affected=true;let A=Date.now(),{runtime:S,framework:C,commandOverrides:ne,environment:oe}=await Ee(k);f.runtimeDetected=S,f.framework=C;let $=await Se(k,e.stage,S,C,ne,oe);if(f.executionCommand=$.command,f.errorCategory=$.errorCategory,f.healthStatus=$.healthStatus,f.durationMs=Date.now()-A,f.exitCode=$.exitCode,$.exitCode===0?(f.status="passed",f.reason=void 0):(f.status="failed",f.reason=$.message||"stage command failed",f.errorMessage=$.message),I+=1,!e.json){let se=x>0?Math.round(I/x*100):100,ae=f.status==="passed"?P.green("\u2705"):P.red("\u274C");console.log(P.gray(`${ae} [${I}/${x}] (${se}%) ${M} ${f.durationMs}ms`));}};if(y&&i.length>1){let k=0,f=false,M=new Array(h).fill(null).map(async()=>{for(;k<i.length;){if(f&&!m)return;let A=k;k+=1;let S=i[A];await d(S),j.get(S)?.status==="failed"&&(f=true);}});if(await Promise.all(M),!m&&f){let A=false;for(let S of i){let C=j.get(S);if(C){if(C.status==="failed"){A=true;continue}A&&C.status==="skipped"&&(C.reason=C.reason||"stopped after failure");}}}}else for(let k of i){await d(k);let f=j.get(k);if(!m&&f?.status==="failed"){let M=i.slice(i.indexOf(k)+1);for(let A of M){let S=j.get(A);S&&(S.status="skipped",S.reason="stopped after failure");}break}}}let T=[];for(let d of o){let k=j.get(d);k&&T.push(k);}let R=T.filter(d=>d.status==="passed").length,F=T.filter(d=>d.status==="failed").length,_=T.filter(d=>d.status==="skipped").length,H=e.strict===true,re=F>0||H&&E.some(d=>d.status!=="pass")?1:0,V={schemaVersion:"1.0",workspacePath:t,stage:e.stage,generatedAt:new Date().toISOString(),durationMs:Date.now()-r,options:{affected:s,blastRadius:u,since:s?c:null,parallel:y,maxWorkers:h,continueOnError:m,strict:H,enforceGates:g},selection:{mode:b,since:s?c:null,graphStatus:p,expansionDepth:v},gates:{enforced:g,results:E,blocked:!!l,blockingGate:l?.gate},summary:{projectCount:o.length,selectedCount:i.length,passed:R,failed:F,skipped:_,exitCode:re},projects:T},J=w.join(t,".rapidkit","reports","workspace-run-last.json");return await fe(J,V),e.json||(l&&(console.log(P.red(`\u274C Workspace run blocked by ${l.gate}`)),console.log(P.gray(` ${l.summary}`))),console.log(P.cyan(`Workspace run (${e.stage}) => passed: ${R}, failed: ${F}, skipped: ${_}`)),console.log(P.gray(`Report: ${J}`))),V}export{Ve as a};
|
|
@@ -104,7 +104,7 @@ npx rapidkit dev
|
|
|
104
104
|
cd <project-name>
|
|
105
105
|
npx rapidkit init
|
|
106
106
|
npx rapidkit dev
|
|
107
|
-
`)+"```\n","utf-8"),!o){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:P}=await import('./workspace-
|
|
107
|
+
`)+"```\n","utf-8"),!o){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:P}=await import('./workspace-YLFC25EZ.js');await P(i$1,a);}catch{}if(console.log(t.green(`
|
|
108
108
|
\u2728 Workspace created!
|
|
109
109
|
`)),console.log(t.cyan("\u{1F4C2} Location:"),t.white(i$1)),console.log(t.cyan(`
|
|
110
110
|
\u{1F680} Get started:
|
|
@@ -154,7 +154,7 @@ npx rapidkit dev
|
|
|
154
154
|
cd <project-name>
|
|
155
155
|
npx rapidkit init
|
|
156
156
|
npx rapidkit dev
|
|
157
|
-
`)+"```\n","utf-8"),!o){C.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 (${w} profile)`],{cwd:i$1}),C.succeed("Git repository initialized");}catch{C.warn("Could not initialize git repository");}}try{let{registerWorkspace:Et}=await import('./workspace-
|
|
157
|
+
`)+"```\n","utf-8"),!o){C.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 (${w} profile)`],{cwd:i$1}),C.succeed("Git repository initialized");}catch{C.warn("Could not initialize git repository");}}try{let{registerWorkspace:Et}=await import('./workspace-YLFC25EZ.js');await Et(i$1,a);}catch{}console.log(t.green(`
|
|
158
158
|
\u2728 Workspace created with fallback profile!
|
|
159
159
|
`)),console.log(t.cyan("\u{1F4C2} Location:"),t.white(i$1)),console.log(t.cyan(`
|
|
160
160
|
\u{1F680} Get started:
|
|
@@ -164,7 +164,7 @@ npx rapidkit dev
|
|
|
164
164
|
`)),console.log("");return}catch(B){throw C.fail("Failed to create workspace"),console.error(t.red(`
|
|
165
165
|
\u274C Error:`),B),B}}}else if(console.log(t.yellow(`
|
|
166
166
|
\u26A0\uFE0F Python not detected. Auto-switching to "${w}" profile (no Python required).
|
|
167
|
-
`)),d=w,new Set(["go-only","java-only","node-only","minimal"]).has(w)){let E=O("Creating workspace").start();try{if(await k.ensureDir(i$1),E.succeed("Directory created"),await z(i$1,a,"venv",void 0),await Y(i$1,a,"venv",void 0,w),await V(i$1),await U(i$1,a),!o){E.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 (${w})`],{cwd:i$1}),E.succeed("Git repository initialized");}catch{E.warn("Could not initialize git repository");}}try{let{registerWorkspace:C}=await import('./workspace-
|
|
167
|
+
`)),d=w,new Set(["go-only","java-only","node-only","minimal"]).has(w)){let E=O("Creating workspace").start();try{if(await k.ensureDir(i$1),E.succeed("Directory created"),await z(i$1,a,"venv",void 0),await Y(i$1,a,"venv",void 0,w),await V(i$1),await U(i$1,a),!o){E.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 (${w})`],{cwd:i$1}),E.succeed("Git repository initialized");}catch{E.warn("Could not initialize git repository");}}try{let{registerWorkspace:C}=await import('./workspace-YLFC25EZ.js');await C(i$1,a);}catch{}console.log(t.green(`
|
|
168
168
|
\u2728 Workspace created (auto-fallback profile)!
|
|
169
169
|
`)),console.log(t.cyan("\u{1F4C2} Location:"),t.white(i$1)),console.log(t.cyan("\u{1F4E6} Profile:"),t.yellow(w)),console.log(t.cyan("\u{1F4A1} Reason:"),t.gray("Python not detected; switched from "+d)),console.log(t.cyan(`
|
|
170
170
|
\u{1F680} Get started:
|
|
@@ -172,7 +172,7 @@ npx rapidkit dev
|
|
|
172
172
|
`)),console.log(t.cyan(`\u{1F4A1} Add Python later:
|
|
173
173
|
`)),console.log(t.gray(" 1. Install Python 3.10+")),console.log(t.gray(` 2. Run: cd ${a} && rapidkit bootstrap --profile ${d}
|
|
174
174
|
`)),console.log("");return}catch(C){throw E.fail("Failed to create workspace"),console.error(t.red(`
|
|
175
|
-
\u274C Error:`),C),C}}}}a$1.step(1,3,"Setting up RapidKit environment");let I=O("Creating directory").start();try{await k.ensureDir(i$1),I.succeed("Directory created"),I.start("Detecting Python version");let f=null,R=await xt(b.pythonVersion);if(R)f=await gt(R),f?(a$1.info(` Detected Python ${f}`),I.succeed(`Python ${f} detected`)):I.warn("Could not detect exact Python version");else {let P=S();f=await gt(P),f?I.succeed(`Python ${f} detected`):I.warn("Could not detect Python version, proceeding with defaults");}if(b.installMethod==="poetry"&&!await bt()&&(I.warn("Poetry not found \u2014 auto-fallback to pip + venv"),b.installMethod="venv"),await z(i$1,a,b.installMethod,f||void 0),f&&await St(i$1,f),await Y(i$1,a,b.installMethod,f||b.pythonVersion,d||h),await V(i$1),await U(i$1,a),b.installMethod==="poetry")try{await It(i$1,b.pythonVersion,I,r,y,u);}catch(P){let w=P?.details||P?.message||String(P);if(w.includes("pyenv")||w.includes("exit status 127")||w.includes("returned non-zero exit status 127")){I.warn("Poetry encountered Python discovery issues, trying venv method"),a$1.debug(`Poetry error (attempting venv fallback): ${w}`);try{await ct(i$1,b.pythonVersion,I,r,y),b.installMethod="venv";}catch(K){throw K}}else throw P}else b.installMethod==="venv"?await ct(i$1,b.pythonVersion,I,r,y):await Rt(i$1,I,r,y,u);if(await Pt(i$1,b.installMethod),await _t(i$1,b.installMethod),I.succeed("RapidKit environment ready!"),!n.skipGit){I.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}),I.succeed("Git repository initialized");}catch{I.warn("Could not initialize git repository");}}try{let{registerWorkspace:P}=await import('./workspace-
|
|
175
|
+
\u274C Error:`),C),C}}}}a$1.step(1,3,"Setting up RapidKit environment");let I=O("Creating directory").start();try{await k.ensureDir(i$1),I.succeed("Directory created"),I.start("Detecting Python version");let f=null,R=await xt(b.pythonVersion);if(R)f=await gt(R),f?(a$1.info(` Detected Python ${f}`),I.succeed(`Python ${f} detected`)):I.warn("Could not detect exact Python version");else {let P=S();f=await gt(P),f?I.succeed(`Python ${f} detected`):I.warn("Could not detect Python version, proceeding with defaults");}if(b.installMethod==="poetry"&&!await bt()&&(I.warn("Poetry not found \u2014 auto-fallback to pip + venv"),b.installMethod="venv"),await z(i$1,a,b.installMethod,f||void 0),f&&await St(i$1,f),await Y(i$1,a,b.installMethod,f||b.pythonVersion,d||h),await V(i$1),await U(i$1,a),b.installMethod==="poetry")try{await It(i$1,b.pythonVersion,I,r,y,u);}catch(P){let w=P?.details||P?.message||String(P);if(w.includes("pyenv")||w.includes("exit status 127")||w.includes("returned non-zero exit status 127")){I.warn("Poetry encountered Python discovery issues, trying venv method"),a$1.debug(`Poetry error (attempting venv fallback): ${w}`);try{await ct(i$1,b.pythonVersion,I,r,y),b.installMethod="venv";}catch(K){throw K}}else throw P}else b.installMethod==="venv"?await ct(i$1,b.pythonVersion,I,r,y):await Rt(i$1,I,r,y,u);if(await Pt(i$1,b.installMethod),await _t(i$1,b.installMethod),I.succeed("RapidKit environment ready!"),!n.skipGit){I.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}),I.succeed("Git repository initialized");}catch{I.warn("Could not initialize git repository");}}try{let{registerWorkspace:P}=await import('./workspace-YLFC25EZ.js');await P(i$1,a);}catch{console.warn(t.gray("Note: Could not register workspace in shared registry"));}if(console.log(t.green(`
|
|
176
176
|
\u2728 RapidKit environment created successfully!
|
|
177
177
|
`)),console.log(t.cyan("\u{1F4C2} Location:"),t.white(i$1)),console.log(t.cyan("\u2699\uFE0F Configuration:")),console.log(t.gray(` \u2022 Profile: ${d}`)),console.log(t.gray(` \u2022 Python: ${b.pythonVersion}`)),console.log(t.gray(` \u2022 Install method: ${b.installMethod}`)),console.log(t.cyan(`
|
|
178
178
|
\u{1F680} Get started:
|
|
@@ -219,7 +219,7 @@ Possible solutions:
|
|
|
219
219
|
2. Try installing manually: cd ${m.basename(e)} && ${f(".venv")} -m pip install rapidkit-core
|
|
220
220
|
3. Use Poetry instead: npx rapidkit ${m.basename(e)} --install-method=poetry`))}}o.succeed("RapidKit installed in project virtualenv");try{let{checkRapidkitCoreAvailable:g}=await import('./pythonRapidkitExec-4MP62M5R.js');if(!await g()&&!r){o.start("Checking optional global pipx installation");let a=await tt(o,true);try{o.start("Installing RapidKit globally with pipx for CLI access"),await T(a,["install","rapidkit-core"]),o.succeed("RapidKit installed globally");}catch(i){o.warn("Could not install globally (non-fatal, project virtualenv has RapidKit)"),a$1.debug(`pipx install failed: ${i}`);}}}catch(g){o.succeed("Skipped optional global pipx installation"),a$1.debug(`Global install check skipped: ${g}`);}}async function Rt(e,n,o,r,l$1=false){if(!o)try{let{checkRapidkitCoreVersionCompatible:u}=await import('./pythonRapidkitExec-4MP62M5R.js'),y=await u();if(y.isCompatible){n.succeed(`RapidKit ${y.installedVersion??""} already compatible globally; skipping pipx installation`),await k.outputFile(m.join(e,".rapidkit-global"),`RapidKit already available globally (version ${y.installedVersion??"unknown"}) and satisfies expected constraint ${y.expectedConstraint??"n/a"}; workspace will reuse the existing installation
|
|
221
221
|
`,"utf-8");return}y.reason==="constraint-missing"?n.warn('Version-aware global reuse skipped: no explicit rapidkit-core version constraint found. Set RAPIDKIT_CORE_PYTHON_PACKAGE (example: RAPIDKIT_CORE_PYTHON_PACKAGE="rapidkit-core>=0.4.0,<0.9.0") to enable version-aware reuse. Proceeding with pipx install/upgrade.'):y.reason==="constraint-unsupported"&&n.warn('Version-aware global reuse skipped: RAPIDKIT_CORE_PYTHON_PACKAGE uses an unsupported spec (path/url/git). Use a version range instead (example: RAPIDKIT_CORE_PYTHON_PACKAGE="rapidkit-core==0.4.0" or "rapidkit-core>=0.4.0,<0.9.0"). Proceeding with pipx install/upgrade.'),a$1.debug(`Global RapidKit install is not reusable via version-aware policy (reason=${y.reason}, installed=${y.installedVersion??"unknown"}, expected=${y.expectedConstraint??"none"}). Proceeding with pipx install/upgrade.`);}catch(u){a$1.debug(`Global RapidKit version-aware check failed before pipx install: ${u}`);}let p=await tt(n,l$1);if(n.start("Installing RapidKit globally with pipx"),o){let u=d$2(r||{});if(!u)throw new k$1("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 T(p,["install","-e",u]);}else {n.text="Installing RapidKit from PyPI";try{await T(p,["install","rapidkit-core"]);}catch(u){try{n.text="RapidKit already installed globally, upgrading to match expected version",await T(p,["upgrade","rapidkit-core"]);}catch(y){throw a$1.debug(`pipx install/upgrade failed: install=${u}, upgrade=${y}`),new l}}}n.succeed("RapidKit installed globally"),await k.outputFile(m.join(e,".rapidkit-global"),`RapidKit installed globally with pipx
|
|
222
|
-
`,"utf-8");}async function se(e,n){let{skipGit:o=false,testMode:r=false,userConfig:l={},yes:p=false,installMethod:u,pythonVersion:y="3.10"}=n||{},g=u||l.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=g==="poetry"&&!await bt()?"venv":g;await z(e,m.basename(e),h),await V(e),await Y(e,m.basename(e),h,y,n?.profile);let a=O("Registering workspace").start();try{h==="poetry"?(await U(e,m.basename(e)),await It(e,y,a,r,l,p)):h==="venv"?await ct(e,y,a,r,l):await Rt(e,a,r,l,p),await Pt(e,h),await _t(e,h),a.succeed("Workspace registered");try{let{registerWorkspace:i}=await import('./workspace-
|
|
222
|
+
`,"utf-8");}async function se(e,n){let{skipGit:o=false,testMode:r=false,userConfig:l={},yes:p=false,installMethod:u,pythonVersion:y="3.10"}=n||{},g=u||l.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=g==="poetry"&&!await bt()?"venv":g;await z(e,m.basename(e),h),await V(e),await Y(e,m.basename(e),h,y,n?.profile);let a=O("Registering workspace").start();try{h==="poetry"?(await U(e,m.basename(e)),await It(e,y,a,r,l,p)):h==="venv"?await ct(e,y,a,r,l):await Rt(e,a,r,l,p),await Pt(e,h),await _t(e,h),a.succeed("Workspace registered");try{let{registerWorkspace:i}=await import('./workspace-YLFC25EZ.js');await i(e,m.basename(e));}catch{}if(!o){a.start("Initializing git repository");try{await execa("git",["init"],{cwd:e}),await execa("git",["add","."],{cwd:e}),await execa("git",["commit","-m","Initial commit: RapidKit workspace"],{cwd:e}),a.succeed("Git repository initialized");}catch{a.warn("Could not initialize git repository");}}}catch(i){throw a.fail("Failed to register workspace"),i}}async function _t(e,n){let o=n==="poetry"?`source $(poetry env info --path)/bin/activate
|
|
223
223
|
# 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):
|
|
224
224
|
./rapidkit --help
|
|
225
225
|
# or:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
declare function handleCreateOrFallback(args: string[]): Promise<number>;
|
|
3
|
-
declare const NPM_ONLY_TOP_LEVEL_COMMANDS: readonly ["analyze", "readiness", "doctor", "autopilot", "import", "snapshot", "project", "workspace", "bootstrap", "setup", "cache", "mirror", "ai", "config", "shell"];
|
|
3
|
+
declare const NPM_ONLY_TOP_LEVEL_COMMANDS: readonly ["analyze", "readiness", "doctor", "autopilot", "import", "snapshot", "project", "workspace", "bootstrap", "setup", "cache", "mirror", "ai", "config", "product", "shell"];
|
|
4
4
|
declare const WRAPPER_ORCHESTRATED_PROJECT_COMMANDS: readonly ["init"];
|
|
5
|
+
declare function isNpmExecInvocation(env?: NodeJS.ProcessEnv): boolean;
|
|
5
6
|
interface DoctorWorkspaceShadowDiagnostic {
|
|
6
7
|
detected: boolean;
|
|
7
8
|
candidatePath?: string;
|
|
@@ -28,4 +29,4 @@ declare function handleMirrorCommand(args: string[]): Promise<number>;
|
|
|
28
29
|
declare function handleInitCommand(args: string[]): Promise<number>;
|
|
29
30
|
declare function shouldForwardToCore(args: string[]): Promise<boolean>;
|
|
30
31
|
|
|
31
|
-
export { type DoctorWorkspaceShadowDiagnostic, NPM_ONLY_TOP_LEVEL_COMMANDS, WRAPPER_ORCHESTRATED_PROJECT_COMMANDS, detectWindowsDoctorWorkspaceShadow, handleBootstrapCommand, handleCacheCommand, handleCreateOrFallback, handleImportCommand, handleInitCommand, handleMirrorCommand, handleSetupCommand, installWorkspaceDependencies, shouldForwardToCore };
|
|
32
|
+
export { type DoctorWorkspaceShadowDiagnostic, NPM_ONLY_TOP_LEVEL_COMMANDS, WRAPPER_ORCHESTRATED_PROJECT_COMMANDS, detectWindowsDoctorWorkspaceShadow, handleBootstrapCommand, handleCacheCommand, handleCreateOrFallback, handleImportCommand, handleInitCommand, handleMirrorCommand, handleSetupCommand, installWorkspaceDependencies, isNpmExecInvocation, shouldForwardToCore };
|