rapidkit 0.27.6 → 0.28.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 CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  > RapidKit is an open-source workspace platform that standardizes how teams build, scale, and deploy backend services.
4
4
 
5
- FastAPI, NestJS, Spring Boot, Go/Fiber, and Go/Gin scaffolding with production-ready defaults.
6
- **27+ plug-and-play modules** are available for FastAPI & NestJS projects. Spring Boot and Go kits run as npm-level generators.
7
- Clean architecture Zero boilerplate Instant deployment.
5
+ Production-ready scaffolding for FastAPI, NestJS, Spring Boot, Go/Fiber, and Go/Gin.
6
+ **27+ plug-and-play modules** are available for FastAPI and NestJS projects. Spring Boot and Go kits run as npm-level generators.
7
+ Built for clean architecture, minimal boilerplate, and fast deployment.
8
8
 
9
- > **💡 Recommended:** Install the [Workspai VS Code extension](https://marketplace.visualstudio.com/items?itemName=rapidkit.rapidkit-vscode) for AI-powered project creation, a visual workspace explorer, and context-aware coding assistance — all backed by this CLI.
9
+ > **💡 Recommended:** Install the [Workspai VS Code extension](https://marketplace.visualstudio.com/items?itemName=rapidkit.rapidkit-vscode) for AI-assisted project creation, workspace exploration, and context-aware coding — all backed by this CLI.
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/rapidkit.svg?style=flat-square)](https://www.npmjs.com/package/rapidkit)
12
12
  [![Downloads](https://img.shields.io/npm/dm/rapidkit.svg?style=flat-square)](https://www.npmjs.com/package/rapidkit)
@@ -14,25 +14,36 @@ Clean architecture • Zero boilerplate • Instant deployment.
14
14
  [![GitHub Stars](https://img.shields.io/github/stars/getrapidkit/rapidkit-npm.svg?style=flat-square)](https://github.com/getrapidkit/rapidkit-npm/stargazers)
15
15
  [![Built by RapidKit](https://img.shields.io/badge/Built%20by-RapidKit-0f172a?logo=github)](https://www.getrapidkit.com)
16
16
 
17
- Official CLI for creating and operating RapidKit workspaces and projects.
17
+ The official RapidKit npm CLI for creating and operating workspaces and projects.
18
18
 
19
19
  - Workspace-first lifecycle (`create workspace` → `bootstrap` → `setup` → `create project`)
20
- - Multi-runtime support (Python, Node.js, Java, Go)
21
- - Profile + policy enforcement (`warn` / `strict`)
20
+ - Multi-runtime support across Python, Node.js, Java, and Go
21
+ - Policy enforcement with `warn` / `strict` modes
22
22
  - Cache and mirror lifecycle commands for stable environments
23
23
 
24
+ ## Workspace-First Architecture
25
+
26
+ RapidKit is designed around the workspace as the operational boundary.
27
+
28
+ - The workspace owns policy, readiness, and shared tooling state.
29
+ - Projects are discovered and managed inside that workspace boundary.
30
+ - Wrapper-owned commands stay in the npm CLI; runtime-specific execution is delegated only when appropriate.
31
+ - Release evidence is written into `.rapidkit/reports/` so CI, docs, and local workflows use the same contract surface.
32
+
33
+ This layout keeps workspace setup deterministic, makes cross-project orchestration explicit, and avoids drifting behavior between the CLI and the core runtime.
34
+
24
35
  ## RapidKit CLI in the Workspai Ecosystem
25
36
 
26
37
  The `rapidkit` npm package remains the official RapidKit CLI.
27
38
 
28
- It works alongside Workspai, which is a product developed by RapidKit.
39
+ It works alongside Workspai, a product developed by RapidKit.
29
40
 
30
- | Component | Repository | Role |
31
- |---|---|---|
32
- | CLI | [getrapidkit/rapidkit-npm](https://github.com/getrapidkit/rapidkit-npm) | Official RapidKit npm CLI |
33
- | VS Code Extension | [getrapidkit/rapidkit-vscode](https://github.com/getrapidkit/rapidkit-vscode) | **Workspai** — visual explorer + AI features (recommended) |
34
- | Core Engine | [getrapidkit/rapidkit-core](https://github.com/getrapidkit/rapidkit-core) | Official RapidKit Core |
35
- | Examples | [getrapidkit/rapidkit-examples](https://github.com/getrapidkit/rapidkit-examples) | Example workspaces and starter references |
41
+ | Component | Repository | Role |
42
+ | ----------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------- |
43
+ | CLI | [getrapidkit/rapidkit-npm](https://github.com/getrapidkit/rapidkit-npm) | Official RapidKit npm CLI |
44
+ | VS Code Extension | [getrapidkit/rapidkit-vscode](https://github.com/getrapidkit/rapidkit-vscode) | **Workspai** — visual explorer + AI features (recommended) |
45
+ | Core Engine | [getrapidkit/rapidkit-core](https://github.com/getrapidkit/rapidkit-core) | Official RapidKit Core |
46
+ | Examples | [getrapidkit/rapidkit-examples](https://github.com/getrapidkit/rapidkit-examples) | Example workspaces and starter references |
36
47
 
37
48
  ## Requirements
38
49
 
@@ -43,6 +54,8 @@ It works alongside Workspai, which is a product developed by RapidKit.
43
54
 
44
55
  ## Install
45
56
 
57
+ Install the RapidKit CLI npm package (`rapidkit`) globally:
58
+
46
59
  ```bash
47
60
  npm install -g rapidkit
48
61
  ```
@@ -119,6 +132,12 @@ npx rapidkit create workspace <name> [--profile <profile>] [--author <name>] [--
119
132
  npx rapidkit bootstrap [--profile <profile>] [--json]
120
133
  npx rapidkit setup <python|node|go|java> [--warm-deps]
121
134
  npx rapidkit readiness [--json] [--strict]
135
+ npx rapidkit autopilot release [--mode <audit|safe-fix|enforce>] [--json] [--output <file>] [--since <ref>] [--parallel] [--max-workers <n>]
136
+ ```
137
+
138
+ Recommended for CI: `npx rapidkit autopilot release --mode enforce --json --output .rapidkit/reports/autopilot-release.json`
139
+
140
+ ```bash
122
141
  npx rapidkit workspace policy show
123
142
  npx rapidkit workspace policy set <key> <value>
124
143
  npx rapidkit doctor
@@ -191,22 +210,24 @@ Bundle content includes:
191
210
 
192
211
  RapidKit keeps the wrapper boundary explicit so users know which layer owns each action.
193
212
 
194
- | Command family | Owner | Notes |
195
- |---|---|---|
196
- | `create workspace`, `workspace`, `cache`, `mirror` | RapidKit wrapper | Platform-level orchestration |
197
- | `init` | Wrapper orchestrated | Project init in project dirs; full-init alias at workspace root |
198
- | `dev`, `test`, `build`, `start` | Runtime aware | Delegates to the active project/runtime when available |
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 |
201
- | `doctor` | Wrapper system check | Checks host prerequisites by default |
202
- | `doctor workspace` | Workspace health | Full workspace scan with project-level details and fixes |
203
- | `doctor project` | Project health | Current project (or nearest parent) diagnostics with project evidence and scoped fixes |
204
- | `workspace run` | Workspace orchestrator | Stage execution across discovered projects with optional affected-only, blast-radius expansion, and policy-gated pre-checks |
213
+ | Command family | Owner | Notes |
214
+ | -------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------- |
215
+ | `create workspace`, `workspace`, `cache`, `mirror` | RapidKit wrapper | Platform-level orchestration |
216
+ | `init` | Wrapper orchestrated | Project init in project dirs; full-init alias at workspace root |
217
+ | `dev`, `test`, `build`, `start` | Runtime aware | Delegates to the active project/runtime when available |
218
+ | `readiness` | Wrapper release gate | Generates release-readiness evidence (`--json` for CI, `--strict` for fail-fast) |
219
+ | `autopilot release` | Wrapper orchestrator | Runs doctor/readiness/remediation/workspace-run gates and emits release verdict evidence |
220
+ | `import` | Workspace ingestion | Imports local folders or git backends with rollback-safe sync behavior |
221
+ | `doctor` | Wrapper system check | Checks host prerequisites by default |
222
+ | `doctor workspace` | Workspace health | Full workspace scan with project-level details and fixes |
223
+ | `doctor project` | Project health | Current project (or nearest parent) diagnostics with project evidence and scoped fixes |
224
+ | `workspace run` | Workspace orchestrator | Stage execution across discovered projects with optional affected-only, blast-radius expansion, and policy-gated pre-checks |
205
225
 
206
226
  Use `npx rapidkit doctor` for a quick host pre-flight, `npx rapidkit doctor project` for a service-level check, and `npx rapidkit doctor workspace` for the full workspace picture.
207
227
  Use `npx rapidkit doctor workspace --plan` or `npx rapidkit doctor project --plan` to preview remediation safely.
208
228
  Use `npx rapidkit doctor workspace --apply` or `npx rapidkit doctor project --apply` for non-interactive remediation runs.
209
229
  Use `npx rapidkit readiness` when you need machine-readable release evidence or strict CI gating.
230
+ Use `npx rapidkit autopilot release` to run an end-to-end pre-merge release gate in one command.
210
231
 
211
232
  ### Doctor workspace fix behavior
212
233
 
@@ -315,6 +336,7 @@ npx rapidkit workspace policy set rules.enforce_toolchain_lock true
315
336
  ```
316
337
 
317
338
  Supported keys:
339
+
318
340
  - `mode`
319
341
  - `dependency_sharing_mode`
320
342
  - `rules.enforce_workspace_marker`
@@ -342,15 +364,15 @@ visual workspace explorer, AI-powered project creation, and context-aware coding
342
364
 
343
365
  ### Why use the extension?
344
366
 
345
- | Feature | CLI | Extension |
346
- |---|---|---|
347
- | Create workspace / project | ✅ | ✅ Visual wizard |
348
- | AI Create — describe → scaffold | ❌ | ✅ |
349
- | Project Assistant (context-aware Q&A) | ❌ | ✅ |
350
- | Workspace tree explorer | ❌ | ✅ |
351
- | Module catalog browser | ❌ | ✅ |
352
- | One-click `rapidkit init / dev / test` | ❌ | ✅ |
353
- | Inline AI on every workspace item | ❌ | ✅ |
367
+ | Feature | CLI | Extension |
368
+ | -------------------------------------- | --- | ---------------- |
369
+ | Create workspace / project | ✅ | ✅ Visual wizard |
370
+ | AI Create — describe → scaffold | ❌ | ✅ |
371
+ | Project Assistant (context-aware Q&A) | ❌ | ✅ |
372
+ | Workspace tree explorer | ❌ | ✅ |
373
+ | Module catalog browser | ❌ | ✅ |
374
+ | One-click `rapidkit init / dev / test` | ❌ | ✅ |
375
+ | Inline AI on every workspace item | ❌ | ✅ |
354
376
 
355
377
  ### Install
356
378
 
@@ -418,17 +440,17 @@ npx rapidkit workspace run build --json --max-workers 8
418
440
 
419
441
  ### Supported Runtimes & Frameworks
420
442
 
421
- | Runtime | Frameworks | Status |
422
- |---------|-----------|--------|
423
- | **Node** | NestJS, Express, Next.js, Nuxt | Built-in |
424
- | **Go** | Fiber, Gin, Echo, Chi | Built-in |
425
- | **Java** | Spring Boot, Quarkus, Gradle | Built-in |
443
+ | Runtime | Frameworks | Status |
444
+ | ---------- | ------------------------------ | -------- |
445
+ | **Node** | NestJS, Express, Next.js, Nuxt | Built-in |
446
+ | **Go** | Fiber, Gin, Echo, Chi | Built-in |
447
+ | **Java** | Spring Boot, Quarkus, Gradle | Built-in |
426
448
  | **Python** | FastAPI, Django, Flask, Poetry | Built-in |
427
- | **PHP** | Laravel, Symfony, Slim | Stable |
428
- | **Rust** | Actix, Axum, Rocket, Tokio | Stable |
429
- | **.NET** | ASP.NET Core, Entity Framework | Stable |
430
- | **Elixir** | Phoenix, Umbrella Projects | Stable |
431
- | **Ruby** | Rails, Sinatra, RSpec | Stable |
449
+ | **PHP** | Laravel, Symfony, Slim | Stable |
450
+ | **Rust** | Actix, Axum, Rocket, Tokio | Stable |
451
+ | **.NET** | ASP.NET Core, Entity Framework | Stable |
452
+ | **Elixir** | Phoenix, Umbrella Projects | Stable |
453
+ | **Ruby** | Rails, Sinatra, RSpec | Stable |
432
454
 
433
455
  ### Enterprise Features
434
456
 
@@ -444,6 +466,7 @@ npx rapidkit workspace run build --json --max-workers 8
444
466
  10. **Composite Steps** — Multi-step build logic
445
467
 
446
468
  For deeper enterprise deployment and governance details, see:
469
+
447
470
  - [docs/README.md](docs/README.md)
448
471
  - [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
449
472
  - [docs/SECURITY.md](docs/SECURITY.md)
@@ -484,11 +507,11 @@ cat test-results.json | jq '.projects[] | {path, status, errorCategory}'
484
507
 
485
508
  RapidKit has two workspace-level execution surfaces, and three equivalent full-init aliases at workspace root:
486
509
 
487
- | Command | Intent | Scope |
488
- |---|---|---|
510
+ | Command | Intent | Scope |
511
+ | ------------------------------------------------------------------ | --------------------------------------------------------------------------------- | ----------------------------------------- |
489
512
  | `init` (at workspace root), `workspace init`, `workspace run init` | Mirrored full-init orchestration (workspace-profile deps + selected project init) | Workspace root + discovered project fleet |
490
- | `workspace run <test\|build\|start>` | Fleet stage execution — run a CI-safe stage across discovered projects | Selected project fleet |
491
- | `init`, `test`, `build`, `start`, `dev` (inside project directory) | Project primitive — run one stage in the current project only | Single project |
513
+ | `workspace run <test\|build\|start>` | Fleet stage execution — run a CI-safe stage across discovered projects | Selected project fleet |
514
+ | `init`, `test`, `build`, `start`, `dev` (inside project directory) | Project primitive — run one stage in the current project only | Single project |
492
515
 
493
516
  **Key design rule:** at workspace root, these are equivalent aliases: `npx rapidkit init`, `npx rapidkit workspace init`, `npx rapidkit workspace run init`.
494
517
  Inside a project directory, `npx rapidkit init` remains a project-scoped primitive.
@@ -518,13 +541,13 @@ npx rapidkit --version
518
541
 
519
542
  ### Quick fixes matrix
520
543
 
521
- | Problem | Quick check | Fix |
522
- |---|---|---|
523
- | `python3` not found | `python3 --version` | Install Python 3.10+ and re-run `npx rapidkit create workspace ...` |
524
- | `setup --warm-deps` skipped | Check for `package.json` / `go.mod` in current dir | Run from the target project directory |
525
- | strict policy blocks command | Review `.rapidkit/policies.yml` | Set policy intentionally via `npx rapidkit workspace policy set ...` |
526
- | doctor output seems stale | Check report timestamp in `.rapidkit/reports/` | Re-run `npx rapidkit doctor workspace` or `npx rapidkit doctor project` |
527
- | affected run scope seems wrong | Verify git ref | Use `--since <ref>` explicitly |
544
+ | Problem | Quick check | Fix |
545
+ | ------------------------------ | -------------------------------------------------- | ----------------------------------------------------------------------- |
546
+ | `python3` not found | `python3 --version` | Install Python 3.10+ and re-run `npx rapidkit create workspace ...` |
547
+ | `setup --warm-deps` skipped | Check for `package.json` / `go.mod` in current dir | Run from the target project directory |
548
+ | strict policy blocks command | Review `.rapidkit/policies.yml` | Set policy intentionally via `npx rapidkit workspace policy set ...` |
549
+ | doctor output seems stale | Check report timestamp in `.rapidkit/reports/` | Re-run `npx rapidkit doctor workspace` or `npx rapidkit doctor project` |
550
+ | affected run scope seems wrong | Verify git ref | Use `--since <ref>` explicitly |
528
551
 
529
552
  - If setup output looks stale, run `npx rapidkit setup <runtime>` again to refresh `.rapidkit/toolchain.lock`.
530
553
  - If dependency warm-up is skipped, verify you are inside the corresponding project directory (`package.json` for Node, `go.mod` for Go).
@@ -0,0 +1,7 @@
1
+ import {a}from'./chunk-TXJX4GUZ.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
+ `,"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
+ \u{1F680} RapidKit Autopilot Release
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(`
5
+ Blocking reasons:`));for(let e of d.blockingReasons)console.log(n.red(` - ${e}`));}if(d.nextActions.length>0){console.log(n.bold(`
6
+ Next actions:`));for(let e of d.nextActions)console.log(n.gray(` - ${e}`));}console.log(n.gray(`
7
+ Report: ${d.artifacts.reportPath}`));}return d}export{ke as runAutopilotRelease};
@@ -1,3 +1,3 @@
1
1
  import {d,e,a as a$1,b}from'./chunk-TYC54P7X.js';import {a}from'./chunk-VKLL63TL.js';import j from'fs';import g from'path';import R from'chalk';import {execa}from'execa';var ce={"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:[]}}},de={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 a=r.trim().toLowerCase().replace(/[_.\s]+/g,"-"),c=a$1(r),s=`${e}-${c==="gofiber"?"fiber":c==="gogin"?"gin":c==="dotnet"?"aspnetcore":c!=="unknown"?c:a==="fiber"?"fiber":a==="aspnetcore"||a==="asp-net-core"?"aspnetcore":a}`,n=ce[s];if(n&&n.commands[t])return n.commands[t]}let o=de[t]?.[e]??[];return o.length>0?o[0]:void 0}function le(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,a)=>a.indexOf(t)===o);return {primary:r.length>0?r[0]:"unknown",secondary:r.slice(1)}}function Y(e){return le(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 a of o)if(new RegExp(a,"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"]),pe=new Set([".git","node_modules",".rapidkit",".venv","dist","build","coverage","htmlcov"]);async function O(e){try{return await j.promises.access(e,j.constants.F_OK),true}catch{return false}}async function fe(e){let r=await j.promises.readFile(e,"utf-8");return JSON.parse(r)}async function ge(e,r){await j.promises.mkdir(g.dirname(e),{recursive:true}),await j.promises.writeFile(e,`${JSON.stringify(r,null,2)}
2
2
  `,"utf-8");}function M(e){return e.replace(/\\/g,"/")}async function he(e){return a(e,{skipDirs:pe,includeHiddenDirs:false,descendIntoMatchedProjects:false,isProjectDir:async(r,t)=>await O(g.join(r,".rapidkit","context.json"))||await O(g.join(r,".rapidkit","project.json"))?true:g.resolve(r)===g.resolve(t)?false:d(r).length>0})}async function ye(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 a=o.stdout.split(/\r?\n/).map(u=>u.trim()).filter(u=>u.length>0).map(u=>M(u));if(a.length===0)return new Set;let c=new Set;for(let u of r){let s=M(g.relative(e,u));if(!s||s===".")continue;let n=`${s}/`;a.some(m=>m===s||m.startsWith(n))&&c.add(u);}return c}async function ke(e,r,t){let o=g.join(e,".rapidkit","workspace-dependency-graph.json");if(!await O(o))return {expanded:t,graphStatus:"missing",expansionDepth:0};let a;try{a=await fe(o);}catch{return {expanded:t,graphStatus:"invalid",expansionDepth:0}}let c=new Set(r.map(f=>g.resolve(f))),u=new Map;if(!a||typeof a!="object"||Array.isArray(a))return {expanded:t,graphStatus:"invalid",expansionDepth:0};let s=Array.isArray(a.projects)?a.projects:[];for(let f of s){if(!f||typeof f!="object"||Array.isArray(f))continue;let y=f,b=typeof y.path=="string"?y.path:"",l=g.resolve(e,b);if(!c.has(l))continue;let h=Array.isArray(y.dependsOn)?y.dependsOn.filter(v=>typeof v=="string"):[];for(let v of h){let E=g.resolve(e,v);c.has(E)&&(u.has(E)||u.set(E,new Set),u.get(E)?.add(l));}}let n=new Set(t),m=[...n],k=0;for(;m.length>0;){let f=m.shift();if(!f)continue;let y=u.get(f);if(y)for(let b of y)n.has(b)||(n.add(b),m.push(b),k+=1);}return {expanded:n,graphStatus:"loaded",expansionDepth:k}}async function we(e,r){if(typeof r=="boolean")return r;let t=g.join(e,".rapidkit","policies.yml");if(!await O(t))return true;let o="";try{o=await j.promises.readFile(t,"utf-8");}catch{return true}let a=o.match(/^[\t ]*rules\.enforce_workspace_run_gates:\s*(true|false)\s*(?:#.*)?$/m);return a?a[1]==="true":true}async function N(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 be(e){return e==="node"||e==="go"||e==="java"||e==="python"}function xe(){return process.env.VITEST==="true"||process.env.VITEST==="1"||process.env.NODE_ENV==="test"}async function Re(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 ve(e$1){let r=s=>{let n=b(s);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=s=>{if(!s)return;let n=a$1(s);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=g.join(e$1,".rapidkit","context.json");if(j.existsSync(o))try{let s=JSON.parse(j.readFileSync(o,"utf-8"));if(typeof s.runtime=="string"){let n={};if(s.commands&&typeof s.commands=="object")for(let[m,k]of Object.entries(s.commands))typeof k=="string"&&(n[m]=k);return {runtime:r(s.runtime),framework:t(typeof s.framework=="string"?s.framework:void 0),commandOverrides:Object.keys(n).length>0?n:void 0,environment:typeof s.environment=="string"?s.environment:void 0}}}catch{}let a=e(e$1),c=r(a.runtime),u=t(a.key);return {runtime:c,framework:u}}async function Ee(e,r,t,o,a,c){let u=!a?.[r]&&be(t),s;if(a&&a[r]?s=a[r]:u?s=`rapidkit ${r}`:s=q(t,o,r),!s)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(s,a,c);if(!n)return {exitCode:127,command:s,message:"Failed to resolve stage command",errorCategory:"runtime"};if(!u){let l=await X(n);if(!l.valid)return {exitCode:127,command:n,message:l.reason||"Command not available",errorCategory:"setup"}}let m=0,k="",f="",y;try{let l=u?r==="init"&&xe()?await Re(e):await N([r],e):await execa(n,[],{cwd:e,reject:false,shell:true});if(m=Number(l.exitCode??0),k=l.stdout,f=l.stderr,m!==0){let h=`${k}
3
- ${f}`;y=Q(h);}}catch(l){return {exitCode:1,command:n,message:l instanceof Error?l.message:"Command execution failed",errorCategory:"runtime"}}return {exitCode:m,command:n,errorCategory:y,healthStatus:void 0,message:m!==0?`Stage failed with exit code ${m}`:void 0}}function ee(e){try{return JSON.parse(e)}catch{return null}}async function Se(e){let r=[],t=await N(["doctor","workspace","--json"],e);if(t.exitCode!==0)r.push({gate:"doctor-workspace",status:"fail",summary:"doctor workspace command failed"});else {let c=ee(t.stdout)?.healthScore,u=Number(c?.errors??0);Number.isFinite(u)&&u>0?r.push({gate:"doctor-workspace",status:"fail",summary:`doctor workspace reports ${u} error(s)`}):r.push({gate:"doctor-workspace",status:"pass",summary:"doctor workspace passed"});}let o=await N(["readiness","--json"],e);if(o.exitCode!==0)r.push({gate:"readiness",status:"fail",summary:"readiness command failed"});else {let a=ee(o.stdout),c=String(a?.overallStatus??"").toLowerCase();c==="fail"?r.push({gate:"readiness",status:"fail",summary:"readiness overall status is fail"}):c==="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 je(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 He(e){if(!Ce(e.stage))throw new Error(`Unsupported workspace run stage: ${e.stage}`);let r=Date.now(),t=g.resolve(e.workspacePath),o=await he(t),a=e.affected===true,c=e.blastRadius===true,u=e.since?.trim()||"HEAD~1",s=a?await ye(t,o,u):new Set(o),n,m="not-applicable",k=0,f="all";if(a&&c){let i=await ke(t,o,s);n=i.expanded,m=i.graphStatus,k=i.expansionDepth,f="affected+blast-radius";}else a?(n=s,f="affected"):(n=s,f="all");let y=e.stage==="init"?false:await we(t,e.enforceGates),b=y?await Se(t):[{gate:"doctor-workspace",status:"skipped",summary:"workspace run gates disabled"},{gate:"readiness",status:"skipped",summary:"workspace run gates disabled"}],l=b.find(i=>i.status==="fail"),h=o.filter(i=>n.has(i)),v=e.continueOnError===true,E=e.parallel===true,W=je(e.maxWorkers,h.length),A=h.length,$=0;e.json||console.log(R.gray(`Workspace run (${e.stage}) started: ${A} target(s), ${E?`parallel x${W}`:"sequential"}`));let S=new Map;for(let i of o)S.set(i,{path:i,relativePath:M(g.relative(t,i)),selected:n.has(i),affected:n.has(i),status:(n.has(i),"skipped"),exitCode:null,durationMs:0,reason:n.has(i)?void 0:"not affected",framework:void 0,runtimeDetected:void 0,executionCommand:void 0});if(l)for(let i of h){let p=S.get(i);p&&(p.status="skipped",p.reason=`blocked by ${l.gate}`);}else {let i=async p=>{let d=S.get(p);if(!d)return;let P=M(g.relative(t,p));e.json||console.log(R.gray(`\u23F3 [${$}/${A}] ${e.stage} ${P}`)),d.selected=true,d.affected=true;let C=Date.now(),{runtime:w,framework:x,commandOverrides:re,environment:ne}=await ve(p);d.runtimeDetected=w,d.framework=x;let F=await Ee(p,e.stage,w,x,re,ne);if(d.executionCommand=F.command,d.errorCategory=F.errorCategory,d.healthStatus=F.healthStatus,d.durationMs=Date.now()-C,d.exitCode=F.exitCode,F.exitCode===0?(d.status="passed",d.reason=void 0):(d.status="failed",d.reason=F.message||"stage command failed",d.errorMessage=F.message),$+=1,!e.json){let oe=A>0?Math.round($/A*100):100,ae=d.status==="passed"?R.green("\u2705"):R.red("\u274C");console.log(R.gray(`${ae} [${$}/${A}] (${oe}%) ${P} ${d.durationMs}ms`));}};if(E&&h.length>1){let p=0,d=false,P=new Array(W).fill(null).map(async()=>{for(;p<h.length;){if(d&&!v)return;let C=p;p+=1;let w=h[C];await i(w),S.get(w)?.status==="failed"&&(d=true);}});if(await Promise.all(P),!v&&d){let C=false;for(let w of h){let x=S.get(w);if(x){if(x.status==="failed"){C=true;continue}C&&x.status==="skipped"&&(x.reason=x.reason||"stopped after failure");}}}}else for(let p of h){await i(p);let d=S.get(p);if(!v&&d?.status==="failed"){let P=h.slice(h.indexOf(p)+1);for(let C of P){let w=S.get(C);w&&(w.status="skipped",w.reason="stopped after failure");}break}}}let T=[];for(let i of o){let p=S.get(i);p&&T.push(p);}let B=T.filter(i=>i.status==="passed").length,L=T.filter(i=>i.status==="failed").length,_=T.filter(i=>i.status==="skipped").length,H=e.strict===true,te=L>0||H&&b.some(i=>i.status!=="pass")?1:0,V={schemaVersion:"1.0",workspacePath:t,stage:e.stage,generatedAt:new Date().toISOString(),durationMs:Date.now()-r,options:{affected:a,blastRadius:c,since:a?u:null,parallel:E,maxWorkers:W,continueOnError:v,strict:H,enforceGates:y},selection:{mode:f,since:a?u:null,graphStatus:m,expansionDepth:k},gates:{enforced:y,results:b,blocked:!!l,blockingGate:l?.gate},summary:{projectCount:o.length,selectedCount:h.length,passed:B,failed:L,skipped:_,exitCode:te},projects:T},J=g.join(t,".rapidkit","reports","workspace-run-last.json");return await ge(J,V),e.json||(l&&(console.log(R.red(`\u274C Workspace run blocked by ${l.gate}`)),console.log(R.gray(` ${l.summary}`))),console.log(R.cyan(`Workspace run (${e.stage}) => passed: ${B}, failed: ${L}, skipped: ${_}`)),console.log(R.gray(`Report: ${J}`))),V}export{He as runWorkspaceStage};
3
+ ${f}`;y=Q(h);}}catch(l){return {exitCode:1,command:n,message:l instanceof Error?l.message:"Command execution failed",errorCategory:"runtime"}}return {exitCode:m,command:n,errorCategory:y,healthStatus:void 0,message:m!==0?`Stage failed with exit code ${m}`:void 0}}function ee(e){try{return JSON.parse(e)}catch{return null}}async function Se(e){let r=[],t=await N(["doctor","workspace","--json"],e);if(t.exitCode!==0)r.push({gate:"doctor-workspace",status:"fail",summary:"doctor workspace command failed"});else {let c=ee(t.stdout)?.healthScore,u=Number(c?.errors??0);Number.isFinite(u)&&u>0?r.push({gate:"doctor-workspace",status:"fail",summary:`doctor workspace reports ${u} error(s)`}):r.push({gate:"doctor-workspace",status:"pass",summary:"doctor workspace passed"});}let o=await N(["readiness","--json"],e);if(o.exitCode!==0)r.push({gate:"readiness",status:"fail",summary:"readiness command failed"});else {let a=ee(o.stdout),c=String(a?.overallStatus??"").toLowerCase();c==="fail"?r.push({gate:"readiness",status:"fail",summary:"readiness overall status is fail"}):c==="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 je(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 He(e){if(!Ce(e.stage))throw new Error(`Unsupported workspace run stage: ${e.stage}`);let r=Date.now(),t=g.resolve(e.workspacePath),o=await he(t),a=e.affected===true,c=e.blastRadius===true,u=e.since?.trim()||"HEAD~1",s=a?await ye(t,o,u):new Set(o),n,m="not-applicable",k=0,f="all";if(a&&c){let i=await ke(t,o,s);n=i.expanded,m=i.graphStatus,k=i.expansionDepth,f="affected+blast-radius";}else a?(n=s,f="affected"):(n=s,f="all");let y=e.stage==="init"?false:await we(t,e.enforceGates),b=y?await Se(t):[{gate:"doctor-workspace",status:"skipped",summary:"workspace run gates disabled"},{gate:"readiness",status:"skipped",summary:"workspace run gates disabled"}],l=b.find(i=>i.status==="fail"),h=o.filter(i=>n.has(i)),v=e.continueOnError===true,E=e.parallel===true,W=je(e.maxWorkers,h.length),A=h.length,$=0;e.json||console.log(R.gray(`Workspace run (${e.stage}) started: ${A} target(s), ${E?`parallel x${W}`:"sequential"}`));let S=new Map;for(let i of o)S.set(i,{path:i,relativePath:M(g.relative(t,i)),selected:n.has(i),affected:n.has(i),status:(n.has(i),"skipped"),exitCode:null,durationMs:0,reason:n.has(i)?void 0:"not affected",framework:void 0,runtimeDetected:void 0,executionCommand:void 0});if(l)for(let i of h){let p=S.get(i);p&&(p.status="skipped",p.reason=`blocked by ${l.gate}`);}else {let i=async p=>{let d=S.get(p);if(!d)return;let P=M(g.relative(t,p));e.json||console.log(R.gray(`\u23F3 [${$}/${A}] ${e.stage} ${P}`)),d.selected=true,d.affected=true;let C=Date.now(),{runtime:w,framework:x,commandOverrides:re,environment:ne}=await ve(p);d.runtimeDetected=w,d.framework=x;let F=await Ee(p,e.stage,w,x,re,ne);if(d.executionCommand=F.command,d.errorCategory=F.errorCategory,d.healthStatus=F.healthStatus,d.durationMs=Date.now()-C,d.exitCode=F.exitCode,F.exitCode===0?(d.status="passed",d.reason=void 0):(d.status="failed",d.reason=F.message||"stage command failed",d.errorMessage=F.message),$+=1,!e.json){let oe=A>0?Math.round($/A*100):100,ae=d.status==="passed"?R.green("\u2705"):R.red("\u274C");console.log(R.gray(`${ae} [${$}/${A}] (${oe}%) ${P} ${d.durationMs}ms`));}};if(E&&h.length>1){let p=0,d=false,P=new Array(W).fill(null).map(async()=>{for(;p<h.length;){if(d&&!v)return;let C=p;p+=1;let w=h[C];await i(w),S.get(w)?.status==="failed"&&(d=true);}});if(await Promise.all(P),!v&&d){let C=false;for(let w of h){let x=S.get(w);if(x){if(x.status==="failed"){C=true;continue}C&&x.status==="skipped"&&(x.reason=x.reason||"stopped after failure");}}}}else for(let p of h){await i(p);let d=S.get(p);if(!v&&d?.status==="failed"){let P=h.slice(h.indexOf(p)+1);for(let C of P){let w=S.get(C);w&&(w.status="skipped",w.reason="stopped after failure");}break}}}let T=[];for(let i of o){let p=S.get(i);p&&T.push(p);}let B=T.filter(i=>i.status==="passed").length,L=T.filter(i=>i.status==="failed").length,_=T.filter(i=>i.status==="skipped").length,H=e.strict===true,te=L>0||H&&b.some(i=>i.status!=="pass")?1:0,V={schemaVersion:"1.0",workspacePath:t,stage:e.stage,generatedAt:new Date().toISOString(),durationMs:Date.now()-r,options:{affected:a,blastRadius:c,since:a?u:null,parallel:E,maxWorkers:W,continueOnError:v,strict:H,enforceGates:y},selection:{mode:f,since:a?u:null,graphStatus:m,expansionDepth:k},gates:{enforced:y,results:b,blocked:!!l,blockingGate:l?.gate},summary:{projectCount:o.length,selectedCount:h.length,passed:B,failed:L,skipped:_,exitCode:te},projects:T},J=g.join(t,".rapidkit","reports","workspace-run-last.json");return await ge(J,V),e.json||(l&&(console.log(R.red(`\u274C Workspace run blocked by ${l.gate}`)),console.log(R.gray(` ${l.summary}`))),console.log(R.cyan(`Workspace run (${e.stage}) => passed: ${B}, failed: ${L}, skipped: ${_}`)),console.log(R.gray(`Report: ${J}`))),V}export{He as a};
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  declare function handleCreateOrFallback(args: string[]): Promise<number>;
3
- declare const NPM_ONLY_TOP_LEVEL_COMMANDS: readonly ["readiness", "doctor", "import", "workspace", "bootstrap", "setup", "cache", "mirror", "ai", "config", "shell"];
3
+ declare const NPM_ONLY_TOP_LEVEL_COMMANDS: readonly ["readiness", "doctor", "autopilot", "import", "workspace", "bootstrap", "setup", "cache", "mirror", "ai", "config", "shell"];
4
4
  declare const WRAPPER_ORCHESTRATED_PROJECT_COMMANDS: readonly ["init"];
5
5
  interface DoctorWorkspaceShadowDiagnostic {
6
6
  detected: boolean;