rapidkit 0.38.0 → 0.39.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 +36 -9
- package/contracts/runtime-command-surface.v1.json +33 -0
- package/contracts/workspace-intelligence/workspace-dependency-graph.v1.json +92 -0
- package/contracts/workspace-intelligence/workspace-impact.v1.json +32 -2
- package/contracts/workspace-intelligence/workspace-model.v1.json +5 -0
- package/contracts/workspace-intelligence/workspace-verify.v1.json +103 -1
- package/dist/analyze-RHQM4AB2.js +1 -0
- package/dist/autopilot-release-FWKOY2BD.js +1 -0
- package/dist/chunk-3YLMCP3V.js +1 -0
- package/dist/chunk-4FJQWL7P.js +4 -0
- package/dist/chunk-4Q2ZZKGB.js +1 -0
- package/dist/chunk-6G2KSHP6.js +2 -0
- package/dist/{chunk-PPQYTYQG.js → chunk-6KD5F6LX.js} +4 -4
- package/dist/{chunk-TVIOAZ6E.js → chunk-ERCD6NFF.js} +15 -15
- package/dist/chunk-G76C74EV.js +1 -0
- package/dist/chunk-GOM3RFB3.js +2 -0
- package/dist/{chunk-NKNMGWAZ.js → chunk-GYNIVEYP.js} +1 -1
- package/dist/chunk-HTYMXMQM.js +1 -0
- package/dist/chunk-KYH364KQ.js +1 -0
- package/dist/chunk-OWNGSAO3.js +2 -0
- package/dist/chunk-PYCJWW4B.js +1 -0
- package/dist/chunk-QPEBI6AB.js +2 -0
- package/dist/{chunk-5NBYSXOZ.js → chunk-RXWM5DSC.js} +2 -2
- package/dist/chunk-S5KTATOU.js +1 -0
- package/dist/chunk-TYZPPUBH.js +1 -0
- package/dist/chunk-UY4KRFNL.js +2 -0
- package/dist/chunk-VQMZC5TC.js +9 -0
- package/dist/{chunk-JBDQADHY.js → chunk-WHCON2VN.js} +11 -11
- package/dist/chunk-X7PWDIQW.js +1 -0
- package/dist/{chunk-7XW2I6MP.js → chunk-ZWKLRZE5.js} +2 -2
- package/dist/{create-Y3XJOKL5.js → create-XVDDQA42.js} +1 -1
- package/dist/{demo-kit-3VTLJBP7.js → demo-kit-RWGOEDW4.js} +1 -1
- package/dist/{doctor-QC662YLH.js → doctor-UOLOGJ2Z.js} +1 -1
- package/dist/{dotnet-webapi-clean-FX533F5U.js → dotnet-webapi-clean-RTBRPDPL.js} +1 -1
- package/dist/{gofiber-standard-35CJZ7S3.js → gofiber-standard-UGIRKPKL.js} +1 -1
- package/dist/{gogin-standard-SAX6C4ZK.js → gogin-standard-HJ7SPFNT.js} +1 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +153 -153
- package/dist/pipeline-O5ANBQMK.js +5 -0
- package/dist/{springboot-standard-SFMSLTX4.js → springboot-standard-IWJSVDLZ.js} +1 -1
- package/dist/{workspace-WBKFXH4Z.js → workspace-L4ITCKMM.js} +1 -1
- package/dist/{workspace-agent-sync-3FFFJYKF.js → workspace-agent-sync-SALW6TVR.js} +1 -1
- package/dist/{workspace-context-V4UGIHSC.js → workspace-context-NMMQMHNU.js} +1 -1
- package/dist/{workspace-foundation-T45HAWKL.js → workspace-foundation-HNIRAIBF.js} +1 -1
- package/dist/workspace-graph-ICB7OVAZ.js +3 -0
- package/dist/workspace-history-LHUTLE3S.js +1 -0
- package/dist/{workspace-intelligence-MGL3Z25K.js → workspace-intelligence-64IWAYHS.js} +1 -1
- package/dist/workspace-model-SDHH5RBC.js +1 -0
- package/dist/workspace-run-EP7XGEM6.js +1 -0
- package/dist/workspace-verify-6Q6MGRG6.js +1 -0
- package/dist/workspace-watch-JDXVGW4H.js +1 -0
- package/docs/contracts/ARTIFACT_CATALOG.md +148 -0
- package/docs/contracts/CLI_LOG_EVENT_STREAM.md +123 -0
- package/package.json +8 -5
- package/dist/analyze-6RFG7C7Z.js +0 -1
- package/dist/autopilot-release-SBPGNGAB.js +0 -1
- package/dist/chunk-2ED6SPXP.js +0 -1
- package/dist/chunk-3R7UJAX5.js +0 -1
- package/dist/chunk-6E5TBB2C.js +0 -2
- package/dist/chunk-6P5DCHBQ.js +0 -4
- package/dist/chunk-ABPDGFVD.js +0 -2
- package/dist/chunk-B2KOIORF.js +0 -1
- package/dist/chunk-C7WILE56.js +0 -1
- package/dist/chunk-HEG6DIGW.js +0 -2
- package/dist/chunk-IW3KLQXE.js +0 -2
- package/dist/chunk-RELR4O5E.js +0 -2
- package/dist/chunk-T5LN7EO5.js +0 -9
- package/dist/chunk-XESEBTPE.js +0 -1
- package/dist/pipeline-C4UCLETO.js +0 -5
- package/dist/workspace-model-IKMGY2BX.js +0 -1
- package/dist/workspace-run-HOR56FON.js +0 -1
- package/dist/workspace-verify-A3J6D7T2.js +0 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import {c}from'./chunk-GYNIVEYP.js';import {b}from'./chunk-WHCON2VN.js';import {b as b$1}from'./chunk-RXWM5DSC.js';import {a as a$1}from'./chunk-VQMZC5TC.js';import {a as a$2}from'./chunk-4FJQWL7P.js';import {a}from'./chunk-KMUWWZRT.js';import {f,e}from'./chunk-4Q2ZZKGB.js';import c$1 from'chalk';import D from'fs-extra';import u from'path';function C(t){return t===0?"pass":t===2?"warn":"fail"}function M(t){return t.some(s=>s.status==="fail")?"blocked":t.some(s=>s.status==="warn")?"needs-attention":"ready"}function F(t,s){if(s)return 3;let a=t.some(i=>i.status==="fail"),r=t.some(i=>i.status==="warn");return a?1:r?2:0}async function j(t){let s=await b$1(t,true),a=false;try{let{syncWorkspaceContract:r}=await import('./workspace-contract-D5O4OZD5.js');await r({workspacePath:t}),a=true;}catch{a=false;}return {sync:s,contractSynced:a}}async function G(t={}){let s=u.resolve(t.workspacePath??process.cwd()),a$3=a(s);if(!a$3)throw new Error("No RapidKit workspace found in current directory or parents");let r=[],i=[],l=false,p,y,m,f$1=Date.now();try{let{sync:e,contractSynced:n}=await j(a$3),o=e.workspaceFound&&(e.added.length>0||e.skipped>=0)||e.workspaceFound?"pass":"warn";r.push({name:"sync",status:o,durationMs:Date.now()-f$1,summary:e.workspaceFound?`registry sync complete (${e.added.length} added, ${e.skipped} existing)${n?", contract synced":""}`:"workspace not registered in global registry; contract sync attempted"}),e.workspaceFound||i.push("workspace registry entry missing \u2014 run rapidkit create workspace or register manually");}catch(e){l=true,r.push({name:"sync",status:"fail",durationMs:Date.now()-f$1,summary:`sync failed: ${e instanceof Error?e.message:String(e)}`}),i.push("workspace sync stage failed");}let w=Date.now();try{let e=await b({workspace:true,json:true,quiet:true,strict:t.strict===true,ci:t.strict!==true}),n=C(e),o=u.join(a$3,".rapidkit","reports","doctor-last-run.json");r.push({name:"doctor",status:n,durationMs:Date.now()-w,summary:n==="pass"?"doctor workspace passed":n==="warn"?"doctor workspace reported warnings":"doctor workspace reported errors",exitCode:e,evidencePath:o}),n==="fail"?i.push("doctor workspace gate failed"):n==="warn"&&i.push("doctor workspace reported warnings");}catch(e){l=true,r.push({name:"doctor",status:"fail",durationMs:Date.now()-w,summary:`doctor failed: ${e instanceof Error?e.message:String(e)}`}),i.push("doctor workspace stage failed");}if(t.skipAnalyze)r.push({name:"analyze",status:"skipped",durationMs:0,summary:"analyze stage skipped"});else {let e=Date.now();try{let n=await a$1({workspacePath:a$3,json:true,strict:t.strict===true});p=u.join(a$3,".rapidkit","reports","analyze-last-run.json");let o=n.summary.verdict==="blocked"?"fail":n.summary.verdict==="needs-attention"?"warn":"pass";r.push({name:"analyze",status:o,durationMs:Date.now()-e,summary:`analyze verdict: ${n.summary.verdict} (score ${n.summary.score}/100)`,evidencePath:p}),o==="fail"?i.push("analyze reported blocked verdict"):o==="warn"&&i.push("analyze reported needs-attention verdict");}catch(n){l=true,r.push({name:"analyze",status:"fail",durationMs:Date.now()-e,summary:`analyze failed: ${n instanceof Error?n.message:String(n)}`}),i.push("analyze stage failed");}}let h=Date.now();try{let e=await a$2({startPath:a$3,writeReport:true,skipVerify:t.skipVerify===true});y=e.evidencePath;let n=e.overallStatus==="pass"?"pass":e.overallStatus==="warn"?"warn":"fail";r.push({name:"readiness",status:n,durationMs:Date.now()-h,summary:`readiness overall: ${e.overallStatus}`,evidencePath:e.evidencePath}),n==="fail"?i.push(...e.blockingReasons.map(o=>`readiness: ${o}`)):n==="warn"&&i.push(...e.gates.filter(o=>o.status==="warn").map(o=>`readiness warn: ${o.gate}: ${o.summary}`));}catch(e){l=true,r.push({name:"readiness",status:"fail",durationMs:Date.now()-h,summary:`readiness failed: ${e instanceof Error?e.message:String(e)}`}),i.push("readiness stage failed");}if(t.skipAutopilot)r.push({name:"autopilot",status:"skipped",durationMs:0,summary:"autopilot stage skipped"});else {let e=Date.now(),n=t.autopilotMode??"audit";try{let o=await c({workspacePath:a$3,mode:n,json:true,skipPipelineStages:true});m=o.artifacts.reportPath;let P=o.summary.verdict==="approved"?"pass":o.summary.verdict==="partial"?"warn":"fail";r.push({name:"autopilot",status:P,durationMs:Date.now()-e,summary:`autopilot ${n}: ${o.summary.verdict}`,exitCode:o.summary.exitCode,evidencePath:m}),P!=="pass"&&i.push(...o.blockingReasons.slice(0,5));}catch(o){l=true,r.push({name:"autopilot",status:"fail",durationMs:Date.now()-e,summary:`autopilot failed: ${o instanceof Error?o.message:String(o)}`}),i.push("autopilot release stage failed");}}let z=M(r),k=F(r,l),g=u.join(a$3,".rapidkit","reports","pipeline-last-run.json"),d={schemaVersion:"rapidkit-pipeline-v1",generatedAt:new Date().toISOString(),workspacePath:a$3,summary:{verdict:z,exitCode:k,stagesPassed:r.filter(e=>e.status==="pass").length,stagesWarn:r.filter(e=>e.status==="warn").length,stagesFailed:r.filter(e=>e.status==="fail").length},stages:r,blockingReasons:[...new Set(i)],artifacts:{reportPath:g,analyzeEvidencePath:p,readinessEvidencePath:y,autopilotEvidencePath:m}};if(t.writeReport!==false){await D.ensureDir(u.dirname(g));let e$1=f(d,{commandId:"workspacePipeline",exitCode:k,generatedAt:d.generatedAt,blockers:d.blockingReasons,runId:e()});await D.writeJSON(g,e$1,{spaces:2});}if(t.writeReport!==false&&t.noAgentSync!==true&&process.env.RAPIDKIT_NO_AGENT_SYNC!=="1"&&t.agentSync!==false)try{let{syncWorkspaceAgentGrounding:e}=await import('./workspace-agent-sync-SALW6TVR.js'),n=await e({workspacePath:a$3,write:true,refreshContext:true,strict:false});d.agentGrounding={indexPath:n.indexPath,writtenFiles:n.writtenFiles,blockers:n.blockers};}catch{}return d}async function X(t){let s;try{s=await G(t);}catch(a){let r=a instanceof Error?a.message:String(a);t.json?console.log(JSON.stringify({schemaVersion:"rapidkit-pipeline-error-v1",ok:false,error:{message:r}},null,2)):console.log(c$1.red(`Pipeline failed: ${r}`)),process.exit(1);}if(t.json)console.log(JSON.stringify(s,null,2));else {console.log(c$1.bold.cyan(`
|
|
2
|
+
\u{1F517} RapidKit Governance Pipeline
|
|
3
|
+
`)),console.log(c$1.bold(`Workspace: ${c$1.cyan(u.basename(s.workspacePath))}`)),console.log(c$1.gray(`Path: ${s.workspacePath}`)),console.log(c$1.white(`Verdict: ${s.summary.verdict} Exit: ${s.summary.exitCode} (${s.summary.stagesPassed} pass / ${s.summary.stagesWarn} warn / ${s.summary.stagesFailed} fail)`));for(let a of s.stages){let r=a.status==="pass"?c$1.green("PASS"):a.status==="warn"?c$1.yellow("WARN"):a.status==="skipped"?c$1.gray("SKIP"):c$1.red("FAIL");console.log(` - ${a.name}: ${r} ${a.summary}`);}if(s.blockingReasons.length>0){console.log(c$1.bold(`
|
|
4
|
+
Blocking reasons:`));for(let a of s.blockingReasons.slice(0,8))console.log(c$1.gray(` \u2022 ${a}`));}console.log(c$1.gray(`
|
|
5
|
+
Evidence: ${s.artifacts.reportPath}`)),s.agentGrounding?.writtenFiles.length&&console.log(c$1.gray(`Agent grounding: ${s.agentGrounding.writtenFiles.length} file(s) synced (INDEX + AGENTS.md + Copilot/Cursor/Claude hooks)`));}s.summary.exitCode!==0&&process.exit(s.summary.exitCode);}export{G as runPipeline,X as runPipelineCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {b as b$1,c}from'./chunk-3Q7264EJ.js';import {b}from'./chunk-
|
|
1
|
+
import {b as b$1,c}from'./chunk-3Q7264EJ.js';import {b}from'./chunk-6KD5F6LX.js';import {promises}from'fs';import g from'path';import r from'chalk';import R from'ora';import {execa}from'execa';var y="21",$="3.5.0",j="2.8.9";function u(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,".").replace(/^\.+|\.+$/g,"").replace(/\.{2,}/g,".").split(".").map(p=>p.replace(/^[^a-z]+/,"").replace(/[^a-z0-9]/g,"")).filter(Boolean).join(".")}function _(e,t){return e.replace(/[\r\n\t]+/g," ").trim()||t}function x(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-")}function M(e,t){let s=u(e)||"com.rapidkit.apps",p=u(t)||"service";return `${s}.${p}`}function E(e){return e.replace(/\./g,"/")}function T(){return JSON.stringify({engine:"npm",runtime:"java"},null,2)}function A(e,t){return JSON.stringify({kit_name:"springboot.standard",runtime:"java",module_support:false,project_name:e.project_name,artifact_id:e.artifact_id,group_id:e.group_id,package_name:e.package_name,app_version:e.app_version,created_by:"rapidkit-npm",rapidkit_version:t,created_at:new Date().toISOString()},null,2)}function P(e){return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
3
3
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
4
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{e as createProject,d as createWorkspace,g as createWorkspaceShareBundle,f as listWorkspaces,c as registerProjectInWorkspace,a as registerWorkspace,b as syncWorkspaceProjects}from'./chunk-
|
|
1
|
+
export{e as createProject,d as createWorkspace,g as createWorkspaceShareBundle,f as listWorkspaces,c as registerProjectInWorkspace,a as registerWorkspace,b as syncWorkspaceProjects}from'./chunk-RXWM5DSC.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {b,c,d}from'./chunk-
|
|
1
|
+
import {b,c,d}from'./chunk-OWNGSAO3.js';import i from'path';import c$1 from'fs-extra';var O="rapidkit-agent-reports-index.v1",E=".rapidkit/reports/INDEX.json",G=".rapidkit/AGENT-GROUNDING.md",S=[{relativePath:b,label:"Agent context pack",required:true},{relativePath:".rapidkit/reports/workspace-model.json",label:"Workspace model graph",required:false},{relativePath:".rapidkit/reports/doctor-last-run.json",label:"Workspace doctor",required:false},{relativePath:".rapidkit/reports/analyze-last-run.json",label:"Workspace analyze",required:false},{relativePath:".rapidkit/reports/pipeline-last-run.json",label:"Governance pipeline",required:false},{relativePath:".rapidkit/reports/release-readiness-last-run.json",label:"Release readiness",required:false},{relativePath:".rapidkit/reports/workspace-impact-last-run.json",label:"Workspace impact",required:false},{relativePath:".rapidkit/reports/workspace-verify-last-run.json",label:"Workspace verify",required:false}];function k(e){return `npx rapidkit ${e}`.trim()}function I(e){return e&&typeof e=="object"?e:null}function j(e,t=12){return Array.isArray(e)?e.filter(r=>typeof r=="string"&&r.trim().length>0).slice(0,t):[]}function q(e){let t=j(e.blockers,12);if(t.length>0)return t;let r=j(e.blockingReasons,12);if(r.length>0)return r;let n=I(e.summary);return n&&Array.isArray(n.blockingReasons)?j(n.blockingReasons,12):[]}function _(e){for(let t of ["generatedAt","timestamp"]){let r=e[t];if(typeof r=="string"&&r.trim())return r.trim()}}function $(e,t,r){if(!e)return true;let n=Date.parse(e);return Number.isFinite(n)?r.getTime()-n>t*60*60*1e3:true}function K(e){let t=e&&e.length>0?e:["all"];return t.includes("all")?new Set(["all","agents","copilot","cursor","claude","codex","orca"]):new Set(t)}function u(e,t){return e.has("all")||e.has(t)}async function X(e){try{if(!await c$1.pathExists(e))return null;let t=await c$1.readJson(e);return I(t)}catch{return null}}async function F(e){let t=e.now??new Date,r=e.staleAfterHours??24,n=[],d=[];for(let l of S){let h=i.join(e.workspacePath,l.relativePath),a=await X(h),p=a!==null;p&&a&&d.push(...q(a)),n.push({path:l.relativePath,label:l.label,required:l.required,exists:p,generatedAt:a?_(a):void 0,commandId:typeof a?.commandId=="string"?a.commandId:void 0,exitCode:typeof a?.exitCode=="number"?a.exitCode:void 0});}let s=[...new Set(d.map(l=>l.trim()).filter(Boolean))].slice(0,16);return {schemaVersion:O,generatedAt:t.toISOString(),workspaceRoot:e.workspacePath,readOrder:S.map(l=>l.relativePath),blockers:s,staleAfterHours:r,reports:n,refreshCommand:k("workspace agent-sync --write --refresh-context")}}function N(e){let t=["# RapidKit agent grounding","","Cross-tool instructions for Copilot, Cursor, Claude Code, Codex, Grok, and other agents.","","## Read order (mandatory before workspace diagnosis)","","1. `.rapidkit/reports/INDEX.json` \u2014 latest blockers, timestamps, and report paths","2. `.rapidkit/reports/workspace-context-agent.json` \u2014 canonical agent context pack","3. Evidence artifacts listed in the index (doctor, analyze, pipeline, readiness, impact, verify)","","Do **not** full-repo scan until these reports are read or regenerated.","","## Regenerate intelligence","","```bash",k("workspace agent-sync --write --refresh-context"),k("workspace context --for-agent --json --write"),k("pipeline --json --write"),"```",""];if(e.index.blockers.length>0){t.push("## Current blockers","");for(let r of e.index.blockers.slice(0,12))t.push(`- ${r}`);t.push("");}if(e.context?.safeCommands?.length){t.push("## Safe commands (prefer these)","");for(let r of e.context.safeCommands.slice(0,10))t.push(`- \`${r.display}\` \u2014 ${r.description}`);t.push("");}return t.push("## Rules","","- Treat `.rapidkit/reports/*` as the source of truth for health, gates, and release posture.","- Prefer deterministic RapidKit CLI commands over heuristic framework guesses.","- If evidence is missing or stale, run the refresh commands above before proposing fixes.","- Keep project-scoped advice aligned with the active project named in the context pack.",""),t.join(`
|
|
2
2
|
`)}function B(e){return ["# RapidKit agent grounding","",`Generated: ${e.generatedAt}`,"","This file is tool-agnostic. Synced agents should read it together with `.rapidkit/reports/INDEX.json`.","","## Mandatory read order","",...e.readOrder.map((t,r)=>`${r+1}. \`${t}\``),"",e.blockers.length>0?"## Blockers":"",...e.blockers.length>0?e.blockers.map(t=>`- ${t}`):[],"","## Refresh","","```bash",e.refreshCommand,"```",""].filter(t=>t!=="").join(`
|
|
3
3
|
`)}function H(){return ["# RapidKit workspace grounding","","Before answering workspace, release, or architecture questions:","","1. Read `AGENTS.md` (managed RapidKit section).","2. Read `.rapidkit/reports/INDEX.json` and `.rapidkit/reports/workspace-context-agent.json`.","3. Use evidence reports before scanning the full repository.","","Regenerate stale intelligence:","","```bash",k("workspace agent-sync --write --refresh-context"),"```",""].join(`
|
|
4
4
|
`)}function L(){return ["## Claude Code","","- Load `.rapidkit/reports/INDEX.json` before diagnosing blockers.","- Use `.claude/rules/rapidkit-evidence.md` when editing files under `.rapidkit/`.","- Refresh grounding with `npx rapidkit workspace agent-sync --write`.",""].join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{b as WORKSPACE_CONTEXT_AGENT_REPORT_PATH,a as WORKSPACE_CONTEXT_SCHEMA_VERSION,c as buildWorkspaceAgentContext,d as writeWorkspaceAgentContext}from'./chunk-
|
|
1
|
+
export{b as WORKSPACE_CONTEXT_AGENT_REPORT_PATH,a as WORKSPACE_CONTEXT_SCHEMA_VERSION,c as buildWorkspaceAgentContext,d as writeWorkspaceAgentContext}from'./chunk-OWNGSAO3.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import {b}from'./chunk-
|
|
1
|
+
import {b}from'./chunk-ERCD6NFF.js';import {a}from'./chunk-RV6HBTFC.js';import c from'path';import u from'fs-extra';async function W(t,r){let o=await a(t),d=o?.name||c.basename(t),n,i=c.join(t,".python-version");if(await u.pathExists(i)){let a=(await u.readFile(i,"utf-8")).trim();a&&(n=a);}let e=r?.profile||"polyglot",m=e==="python-only"||e==="polyglot"||e==="enterprise",f=r?.installMethod||o?.metadata?.npm?.installMethod||(m?"poetry":"venv"),s=await b(t,{workspaceName:d,installMethod:f,pythonVersion:n,profile:e,writeMarker:true,writeGitignore:true,onlyIfMissing:!r?.force}),{publishWorkspaceRegistrySummary:y}=await import('./workspace-registry-summary-MIPHVB56.js');return await y(t),{workspacePath:t,created:s,status:s.length>0?"passed":"skipped"}}export{W as ensureWorkspaceFoundation};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {a as a$2}from'./chunk-PYCJWW4B.js';import {a as a$1}from'./chunk-HTYMXMQM.js';import {a,b}from'./chunk-S5KTATOU.js';function m(t,n){return [...t.values()].filter(r=>r.id!==n).map(r=>({id:r.id,distance:r.distance,path:r.path,via:r.via})).sort((r,s)=>r.distance-s.distance||r.id.localeCompare(s.id))}function x(t,n){let r=a(t);if(!r.nodeIds.has(n))return {project:n,found:false,centrality:null,directDependents:[],directDependencies:[],transitiveDependents:[],transitiveDependencies:[]};let e=a$1(t).byId.get(n)??null,o=b(r,[n],{direction:"dependents"}),u=b(r,[n],{direction:"dependencies"}),f=(r.reverse.get(n)??[]).slice().sort((d,i)=>d.localeCompare(i)),k=(r.forward.get(n)??[]).slice().sort((d,i)=>d.localeCompare(i));return {project:n,found:true,centrality:e,directDependents:f,directDependencies:k,transitiveDependents:m(o,n),transitiveDependencies:m(u,n)}}function c(t){return t.replace(/"/g,'\\"')}var G={"code-import":"solid","package-dep":"solid","event-pub-sub":"dashed","service-dependsOn":"bold","shared-resource":"dotted"};function C(t){let n=[...t.nodes].sort((e,o)=>e.id.localeCompare(o.id)),r=[...t.edges].sort((e,o)=>e.from.localeCompare(o.from)||e.to.localeCompare(o.to)||e.kind.localeCompare(o.kind)),s=["digraph workspace {"," rankdir=LR;"," node [shape=box];"];for(let e of n)s.push(` "${c(e.id)}";`);for(let e of r){let o=G[e.kind]??"solid";s.push(` "${c(e.from)}" -> "${c(e.to)}" [label="${e.kind}", style=${o}];`);}return s.push("}"),s.join(`
|
|
2
|
+
`)}function l(t){let n=t.replace(/[^A-Za-z0-9_]/g,"_");return /^[A-Za-z_]/.test(n)?n:`n_${n}`}function I(t){let n=[...t.nodes].sort((e,o)=>e.id.localeCompare(o.id)),r=[...t.edges].sort((e,o)=>e.from.localeCompare(o.from)||e.to.localeCompare(o.to)||e.kind.localeCompare(o.kind)),s=["flowchart LR"];for(let e of n)s.push(` ${l(e.id)}["${e.id}"]`);for(let e of r)s.push(` ${l(e.from)} -->|${e.kind}| ${l(e.to)}`);return s.join(`
|
|
3
|
+
`)}function $(t){return {graph:t,integrity:a$2(t),hotspots:a$1(t).hotspots}}export{$ as buildGraphEmit,x as explainGraphNode,C as renderGraphDot,I as renderGraphMermaid};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import a from'path';import i from'fs-extra';var c="workspace-intelligence-history.v1",y=".rapidkit/reports/workspace-intelligence-history.json",p=50;function H(e,t){return {generatedAt:e.generatedAt,kind:"verify",verdict:e.summary.verdict,risk:e.impact.risk,affectedProjects:e.impact.affectedProjects,freshness:e.freshness.verdict,gatePassed:t,blockingReasons:e.blockingReasons.length,policyViolations:e.policyViolations.length}}async function l(e){let t=a.join(e,y);try{if(!await i.pathExists(t))return null;let r=await i.readJson(t);return r?.schemaVersion!==c||!Array.isArray(r.entries)?null:{schemaVersion:c,retention:typeof r.retention=="number"?r.retention:p,entries:r.entries}}catch{return null}}function m(e,t,r=p){let o=Math.max(1,Math.floor(r)),s=[...e?.entries??[],t],n=s.slice(Math.max(0,s.length-o));return {schemaVersion:c,retention:o,entries:n}}async function h(e,t,r){let o=await l(e),s=m(o,t,r?.retention??p),n=a.join(e,y);return await i.ensureDir(a.dirname(n)),await i.writeJson(n,s,{spaces:2}),s}export{p as DEFAULT_HISTORY_RETENTION,y as WORKSPACE_HISTORY_PATH,c as WORKSPACE_HISTORY_SCHEMA_VERSION,m as appendHistoryEntry,H as historyEntryFromVerify,l as readWorkspaceHistory,h as recordWorkspaceHistory};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{f as WORKSPACE_IMPACT_REPORT_PATH,e as WORKSPACE_IMPACT_SCHEMA_VERSION,d as WORKSPACE_MODEL_DIFF_REPORT_PATH,b as WORKSPACE_MODEL_DIFF_SCHEMA_VERSION,c as WORKSPACE_MODEL_SNAPSHOT_REPORT_PATH,a as WORKSPACE_MODEL_SNAPSHOT_SCHEMA_VERSION,n as buildWorkspaceImpact,i as buildWorkspaceModelSnapshot,k as diffWorkspaceModel,g as isGitDiffSource,h as parseGitDiffRef,m as workspaceVerificationPlan,o as writeWorkspaceImpact,l as writeWorkspaceModelDiff,j as writeWorkspaceModelSnapshot}from'./chunk-
|
|
1
|
+
export{f as WORKSPACE_IMPACT_REPORT_PATH,e as WORKSPACE_IMPACT_SCHEMA_VERSION,d as WORKSPACE_MODEL_DIFF_REPORT_PATH,b as WORKSPACE_MODEL_DIFF_SCHEMA_VERSION,c as WORKSPACE_MODEL_SNAPSHOT_REPORT_PATH,a as WORKSPACE_MODEL_SNAPSHOT_SCHEMA_VERSION,n as buildWorkspaceImpact,i as buildWorkspaceModelSnapshot,k as diffWorkspaceModel,g as isGitDiffSource,h as parseGitDiffRef,m as workspaceVerificationPlan,o as writeWorkspaceImpact,l as writeWorkspaceModelDiff,j as writeWorkspaceModelSnapshot}from'./chunk-QPEBI6AB.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{c as WORKSPACE_MODEL_REPORT_PATH,b as WORKSPACE_MODEL_SCHEMA_VERSION,e as buildWorkspaceModel,f as buildWorkspaceModelCached,g as buildWorkspaceModelIncremental,d as validateWorkspaceModelStrict,h as writeWorkspaceModel}from'./chunk-TYZPPUBH.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{a as runWorkspaceStage}from'./chunk-UY4KRFNL.js';export{a as WORKSPACE_RUN_LAST_REPORT_FILENAME}from'./chunk-FV5A3N3I.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {a,b as b$2}from'./chunk-PYCJWW4B.js';import {b as b$1,c,d}from'./chunk-KYH364KQ.js';import {m,f,c as c$1,n,e as e$1}from'./chunk-QPEBI6AB.js';import {e}from'./chunk-TYZPPUBH.js';import {c as c$2}from'./chunk-FV5A3N3I.js';import u from'path';import h from'fs-extra';var _="workspace-verify.v1",H=".rapidkit/reports/workspace-verify-last-run.json";function T(e,s){return u.isAbsolute(s)?s:u.join(e,s)}async function q(e){let s=await h.readJson(e);if(!s||typeof s!="object"||Array.isArray(s))throw new Error(`Workspace impact input is not a JSON object: ${e}`);let t=s;if(t.schemaVersion!==e$1)throw new Error(`Unsupported workspace impact schema: ${String(t.schemaVersion)}`);return t}function z(e){let s=new Set,t=[];for(let r of e){let n=`${r.scope}:${r.project??""}:${r.display}`;s.has(n)||(s.add(n),t.push(r));}return t}function L(e,s){if(!e||e==="workspace")return true;let t=(e.startsWith("project:")?e.slice(8):e).trim().toLowerCase();return s.scope==="workspace"?true:(s.project??"").trim().toLowerCase()===t}function B(e,s){if(e.id==="workspace.doctor")return u.join(s,".rapidkit","reports","doctor-last-run.json");if(e.id==="workspace.contract.verify")return u.join(s,".rapidkit","reports","workspace-contract-verify-last-run.json");if(e.id==="workspace.readiness")return u.join(s,".rapidkit","reports","release-readiness-last-run.json");if(e.id==="workspace.analyze")return u.join(s,".rapidkit","reports","analyze-last-run.json");if(e.id==="workspace.pipeline")return u.join(s,".rapidkit","reports","pipeline-last-run.json");if(e.id.startsWith("project.")&&(e.id.endsWith(".test")||e.id.endsWith(".build")))return u.join(s,".rapidkit","reports","workspace-run-last.json")}function b(e){return !e||typeof e!="object"||Array.isArray(e)?null:e}function J(e){let s=b(e.healthScore),t=typeof s?.errors=="number"?s.errors:0,r=typeof s?.percent=="number"?s.percent:void 0;return t>0?{status:"fail",message:`Doctor evidence reports ${t} error(s).`}:typeof r=="number"&&r<70?{status:"warn",message:`Doctor health score is ${r}%.`}:{status:"pass",message:"Doctor evidence is present and healthy."}}function K(e){let s=typeof e.overallStatus=="string"?e.overallStatus:"unknown";return s==="fail"?{status:"fail",message:"Release readiness evidence reports blocking failures."}:s==="warn"?{status:"warn",message:"Release readiness evidence reports warnings."}:s==="pass"?{status:"pass",message:"Release readiness evidence passed."}:{status:"warn",message:`Release readiness evidence status is ${s}.`}}function G(e){let s=typeof e.status=="string"?e.status:"unknown";return s==="failed"||s==="fail"?{status:"fail",message:"Workspace contract verify evidence failed."}:s==="passed"||s==="pass"?{status:"pass",message:"Workspace contract verify evidence passed."}:{status:"warn",message:`Workspace contract verify evidence status is ${s}.`}}function Y(e){let s=b(e.summary);if(s?.blocking===true||e.blocking===true)return {status:"fail",message:"Analyze evidence reports blocking findings."};let r=typeof s?.status=="string"?s.status:void 0;return r==="warn"||r==="warning"?{status:"warn",message:"Analyze evidence reports warnings."}:{status:"pass",message:"Analyze evidence is present."}}function U(e){let s=b(e.summary),t=typeof s?.verdict=="string"?s.verdict:void 0;return t==="blocked"?{status:"fail",message:"Pipeline evidence is blocked."}:t==="needs-attention"?{status:"warn",message:"Pipeline evidence needs attention."}:t==="ready"?{status:"pass",message:"Pipeline evidence is ready."}:{status:"warn",message:"Pipeline evidence status is unknown."}}function Q(e,s,t){let r=s.id.endsWith(".build")?"build":s.id.endsWith(".test")?"test":null,n=c$2(e,r);if(!n)return {status:"missing",message:"Workspace run evidence is missing or unreadable."};let c=n.stage;if(r&&c!==r)return {status:"missing",message:`Workspace run evidence is for stage "${c}", expected "${r}".`};let d=Array.isArray(n.projects)?n.projects:[],o=s.project?.toLowerCase();if(!o)return {status:"missing",message:"Project-scoped workspace run evidence is missing a project identifier."};let p=d.find(g=>{let f=b(g);if(!f)return false;let i=typeof f.projectName=="string"?f.projectName.toLowerCase():"",a=["projectPath","relativePath","path"].map(l=>f[l]).filter(l=>typeof l=="string"&&l.trim().length>0).map(l=>l.replace(/\\/g,"/").toLowerCase());return i===o||a.some(l=>l.endsWith(`/${o}`)||l===o)});if(p){let g=v(n.generatedAt,t,`Workspace run evidence for ${s.project??s.id}`);if(g)return {status:"fail",message:g};let f=b(p),i=typeof f?.status=="string"?f.status:"unknown";return i==="failed"?{status:"fail",message:`Workspace run evidence failed for ${s.project}.`}:i==="passed"?{status:"pass",message:`Workspace run evidence passed for ${s.project}.`}:i==="skipped"?{status:"warn",message:`Workspace run evidence skipped for ${s.project}.`}:{status:"warn",message:`Workspace run evidence status is ${i} for ${s.project}.`}}return {status:"missing",message:`Workspace run evidence does not include project ${s.project}.`}}function v(e,s,t){if(typeof e!="string"||!s)return null;let r=Date.parse(e),n=Date.parse(s);return !Number.isFinite(r)||!Number.isFinite(n)?null:r<n?`${t} is stale: generated at ${e}, before impact ${s}.`:null}async function X(e,s,t,r){let n=B(e,s),c=n?u.relative(s,n).split(u.sep).join("/"):void 0;if(e.id==="workspace.contract.verify"&&!t)return {id:e.id,label:e.label,scope:e.scope,project:e.project,command:e,status:"skipped",required:e.required,message:"Workspace contract is not present; contract verify skipped."};if(!n||!await h.pathExists(n))return {id:e.id,label:e.label,scope:e.scope,project:e.project,command:e,status:"missing",required:e.required,evidencePath:c,message:c?`Missing evidence report: ${c}`:"No evidence mapping exists for this command."};let d=b(await h.readJson(n));if(!d)return {id:e.id,label:e.label,scope:e.scope,project:e.project,command:e,status:"fail",required:e.required,evidencePath:c,message:"Evidence report is not a JSON object."};let o;if(e.id==="workspace.doctor"){let p=v(d.generatedAt,r,"Doctor evidence");p?o={status:"fail",message:p}:o=J(d);}else if(e.id==="workspace.readiness"){let p=v(d.generatedAt,r,"Release readiness evidence");p?o={status:"fail",message:p}:o=K(d);}else if(e.id==="workspace.contract.verify"){let p=v(d.generatedAt,r,"Workspace contract verify evidence");p?o={status:"fail",message:p}:o=G(d);}else if(e.id==="workspace.analyze"){let p=v(d.generatedAt,r,"Analyze evidence");p?o={status:"fail",message:p}:o=Y(d);}else if(e.id==="workspace.pipeline"){let p=v(d.generatedAt,r,"Pipeline evidence");p?o={status:"fail",message:p}:o=U(d);}else if(e.id.startsWith("project."))o=Q(d,e,r);else {let p=v(d.generatedAt,r,"Evidence report");p?o={status:"fail",message:p}:o={status:"pass",message:"Evidence report is present."};}return {id:e.id,label:e.label,scope:e.scope,project:e.project,command:e,status:o.status,required:e.required,evidencePath:c,message:o.message}}function Z(e,s={blockingReasons:[],needsAttention:false}){let t=e.filter(i=>i.status==="pass").length,r=e.filter(i=>i.status==="warn").length,n=e.filter(i=>i.status==="fail").length,c=e.filter(i=>i.status==="missing").length,d=e.filter(i=>i.status==="skipped").length,o=e.filter(i=>i.required&&(i.status==="fail"||i.status==="missing")).map(i=>`${i.id}: ${i.message}`),p=e.filter(i=>i.required&&i.status==="missing").length,g="ready",f=0;return o.length>0||s.blockingReasons.length>0?(g="blocked",f=2):(r>0||p>0||s.needsAttention)&&(g="needs-attention",f=1),{verdict:g,exitCode:f,stepsPassed:t,stepsWarn:r,stepsFailed:n,stepsMissing:c,stepsSkipped:d}}function ee(e,s){let t=j(e.affectedProjects.map(a=>a.project?.name).filter(a=>typeof a=="string")),r=new Set(t.map(a=>a.toLowerCase())),n=j(e.transitiveImpact.map(a=>a.project?.name).filter(a=>typeof a=="string").filter(a=>!r.has(a.toLowerCase()))),c=new Map;for(let a of s){if(a.scope!=="project"||!a.project)continue;let l=a.project.toLowerCase(),y=c.get(l)??[];y.push(a),c.set(l,y);}let d=[],o=[],p=[],g=[],f=false,i=(a,l)=>{let y=c.get(a.toLowerCase())??[];if(y.length===0){p.push(a);return}let W=y.filter(k=>k.status==="fail"),w=y.filter(k=>k.status==="missing"),P=w.filter(k=>k.required),V=y.some(k=>k.status==="pass"||k.status==="warn");if(W.length>0){o.push(a),g.push(`graph.subgraph.${a}: ${l} has failed verification evidence (${W.map(k=>k.id).join(", ")}).`);return}if(P.length>0){o.push(a),g.push(`graph.subgraph.${a}: ${l} has missing required verification evidence (${P.map(k=>k.id).join(", ")}).`);return}if(w.length>0){o.push(a),f=true;return}if(V){d.push(a);return}p.push(a);};for(let a of t)i(a,"directly-changed");for(let a of n)i(a,"transitive dependent");return {subgraph:{totalProjects:t.length+n.length,directlyChanged:t,transitiveDependents:n,covered:j(d),uncovered:j(o),unverifiable:j(p)},blockingReasons:g,needsAttention:f}}function j(e){return [...new Set(e)].sort((s,t)=>s.localeCompare(t))}async function se(e$2){let s=u.resolve(e$2.workspacePath);if(e$2.fromImpactPath){let c=T(s,e$2.fromImpactPath);return {impact:await q(c),fromImpactRef:u.relative(s,c).split(u.sep).join("/")}}let t=u.join(s,f);if(await h.pathExists(t))return {impact:await q(t),fromImpactRef:f};let r=u.join(s,c$1);if(await h.pathExists(r))return {impact:await n({workspacePath:s,fromPath:c$1,scope:e$2.scope,includeAbsolutePaths:e$2.includeAbsolutePaths,includeEvidence:e$2.includeEvidence,observableScanDepth:e$2.observableScanDepth,now:e$2.now}),fromImpactRef:c$1};let n$1=await e({workspacePath:s,includeAbsolutePaths:e$2.includeAbsolutePaths,includeEvidence:e$2.includeEvidence,observableScanDepth:e$2.observableScanDepth,now:e$2.now});return {impact:{schemaVersion:e$1,generatedAt:(e$2.now??new Date).toISOString(),fromRef:"baseline",diffRef:".rapidkit/reports/workspace-model-diff-last-run.json",workspace:{name:n$1.workspace.name,profile:n$1.workspace.profile,type:n$1.workspace.type},summary:{changed:false,risk:"none",affectedProjects:0,workspaceItems:0,recommendedCommands:0,blastRadius:{directlyAffected:0,transitivelyAffected:0,maxDistance:0,graphEdges:n$1.graph?.edges.length??0}},affectedProjects:[],transitiveImpact:[],criticalPathHotspots:[],workspaceImpact:[],verificationPlan:[],agentBrief:{headline:"Baseline workspace verify run.",bullets:["No impact report or snapshot was available; baseline gates were evaluated."],unsafeAssumptions:["Do not claim runtime verification passed unless evidence exists."]},diff:{schemaVersion:"workspace-model-diff.v1",generatedAt:(e$2.now??new Date).toISOString(),fromRef:"baseline",toRef:".rapidkit/reports/workspace-model.json",fromHash:"baseline",toHash:"baseline",summary:{changed:false,addedProjects:0,removedProjects:0,changedProjects:0,workspaceChanges:0,validationChanges:0,gitChangedFiles:0},git:{available:false,dirty:false,changedFiles:0,untrackedFiles:0,deletedFiles:0},changes:[],currentModel:n$1}}}}async function me(e){let s=u.resolve(e.workspacePath),{impact:t,fromImpactRef:r}=await se(e),n=t.diff.currentModel,c$1=z([...m(),...t.verificationPlan]).filter(m=>L(e.scope,m)),d$1=[];for(let m of c$1)d$1.push(await X(m,s,n.contracts.exists===true,t.generatedAt));let o=ee(t,d$1),p=a(n.graph??{nodes:[],edges:[]}),g=b$1(n),f=await ne(s),i=c(g,f?.freshness?.projectHashes),a$1={verdict:i.verdict,baseline:i.baseline,changed:i.changed,added:i.added,removed:i.removed,projectHashes:d(g)},l=b$2(p),y=n.policies?.mode??"warn",W=await te(n,s),w=re(y,W),P=Z(d$1,{blockingReasons:[...o.blockingReasons,...l,...w.blockingReasons],needsAttention:o.needsAttention||w.needsAttention}),V=d$1.filter(m=>m.status==="missing"&&m.evidencePath).map(m=>m.evidencePath),N=[...d$1.filter(m=>m.required&&(m.status==="fail"||m.status==="missing")).map(m=>`${m.id}: ${m.message}`),...o.blockingReasons,...l,...w.blockingReasons];return {schemaVersion:_,generatedAt:(e.now??new Date).toISOString(),workspacePath:s,mode:"evidence",fromImpactRef:r,scope:e.scope,impact:{changed:t.summary.changed,risk:t.summary.risk,affectedProjects:t.summary.affectedProjects,recommendedCommands:t.summary.recommendedCommands},summary:P,steps:d$1,missingEvidence:V,blockingReasons:N,verificationPlan:c$1,affectedSubgraph:o.subgraph,graphIntegrity:p,freshness:a$1,policyMode:y,policyViolations:W}}async function te(e,s){let t=[];for(let n of e.validation?.issues??[])t.push({source:"model",severity:n.severity,code:n.code,message:n.message,target:n.target});let r=u.join(s,".rapidkit","reports","workspace-contract-verify-last-run.json");try{if(await h.pathExists(r)){let n=await h.readJson(r);if(Array.isArray(n.violations))for(let c of n.violations)typeof c=="string"&&c.trim().length>0&&t.push({source:"contract",severity:"error",code:"contract.violation",message:c});}}catch{}return t.sort((n,c)=>n.source!==c.source?n.source.localeCompare(c.source):n.code!==c.code?n.code.localeCompare(c.code):n.message.localeCompare(c.message))}function re(e,s){let t=s.filter(r=>r.severity==="error");return e==="enforce"&&t.length>0?{blockingReasons:t.map(r=>`policy.${r.code}: ${r.message}`),needsAttention:false}:{blockingReasons:[],needsAttention:t.length>0}}async function ne(e){let s=u.join(e,H);try{if(!await h.pathExists(s))return null;let t=await h.readJson(s);return t&&t.schemaVersion===_?t:null}catch{return null}}async function ke(e,s){let t=u.join(s,H);return await h.ensureDir(u.dirname(t)),await h.writeJson(t,e,{spaces:2}),t}function ie(e,s){let t=s?.strict?"strict":"default",r=[];if(e.summary.verdict==="blocked")return r.push(...e.blockingReasons),r.length===0&&r.push("verify verdict is blocked."),{passed:false,mode:t,exitCode:2,reasons:r};if(t==="strict"){if(e.summary.verdict!=="ready"&&r.push(`verify verdict is ${e.summary.verdict} (strict requires ready).`),e.freshness.verdict==="stale"){let n=[...e.freshness.changed,...e.freshness.added].slice(0,5);r.push(`freshness is stale${n.length>0?`: ${n.join(", ")}`:""} (strict requires fresh).`);}if(r.length>0)return {passed:false,mode:t,exitCode:1,reasons:r}}return {passed:true,mode:t,exitCode:e.summary.exitCode===2?0:e.summary.exitCode,reasons:r}}function he(e,s){let t=ie(e,s);return t.passed?e.summary.verdict==="blocked"?2:s?.strict&&e.summary.verdict!=="ready"?1:e.summary.exitCode:t.exitCode}export{H as WORKSPACE_VERIFY_REPORT_PATH,_ as WORKSPACE_VERIFY_SCHEMA_VERSION,me as buildWorkspaceVerify,ee as computeAffectedSubgraphGate,ie as evaluateWorkspaceVerifyGate,he as workspaceVerifyExitCode,ke as writeWorkspaceVerify};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {a}from'./chunk-KYH364KQ.js';import {g as g$1}from'./chunk-TYZPPUBH.js';import {d}from'./chunk-X7PWDIQW.js';import b from'fs';var M="workspace-watch-event.v1";function g(t){return `${t.from}\0${t.to}\0${t.kind}`}function f(t){return (t.graph?.edges??[]).map(r=>({from:r.from,to:r.to,kind:r.kind}))}function m(t){let o=[...a(t).entries()].sort((a,n)=>a[0].localeCompare(n[0])).map(([a,n])=>({id:a,hash:n})),c=f(t).map(g).sort((a,n)=>a.localeCompare(n));return d({projects:o,edges:c})}function w(t,r){let o=a(r),c=t?a(t):new Map,a$1=[],n=[];for(let[e,s]of o.entries())c.has(e)?c.get(e)!==s&&a$1.push(e):n.push(e);let d=[];for(let e of c.keys())o.has(e)||d.push(e);let i=new Map(t?f(t).map(e=>[g(e),e]):[]),l=new Map(f(r).map(e=>[g(e),e])),p=[];for(let[e,s]of l.entries())i.has(e)||p.push(s);let h=[];for(let[e,s]of i.entries())l.has(e)||h.push(s);let u=(e,s)=>g(e).localeCompare(g(s));return a$1.sort((e,s)=>e.localeCompare(s)),n.sort((e,s)=>e.localeCompare(s)),d.sort((e,s)=>e.localeCompare(s)),p.sort(u),h.sort(u),{changedProjects:a$1,addedProjects:n,removedProjects:d,edgesAdded:p,edgesRemoved:h}}var k=class{model=null;sequence=0;rebuild;now;constructor(r,o){this.rebuild=o?.rebuild??(()=>g$1({...r})),this.now=o?.now??(()=>new Date);}get currentModel(){return this.model}async start(){let r=Date.now(),{model:o}=await this.rebuild();return this.model=o,this.buildEvent("ready","initial",null,o,Date.now()-r)}async pulse(){let r=Date.now(),o=this.model,{model:c,mode:a}=await this.rebuild(),n=this.buildEvent(this.hasStructuralChange(o,c)?"changed":"unchanged",a,o,c,Date.now()-r);return this.model=c,n}hasStructuralChange(r,o){return r?m(r)!==m(o):true}buildEvent(r,o,c,a,n){let d=w(c,a),i=m(a),l=c?m(c)!==i:true;return {schemaVersion:M,kind:r,sequence:this.sequence++,timestamp:this.now().toISOString(),mode:o,modelHash:i,modelHashChanged:l,changedProjects:d.changedProjects,addedProjects:d.addedProjects,removedProjects:d.removedProjects,graph:{nodeCount:a.graph?.nodes.length??0,edgeCount:a.graph?.edges.length??0,edgesAdded:d.edgesAdded,edgesRemoved:d.edgesRemoved},durationMs:n}}},P=new Set([".git",".hg",".svn","node_modules",".venv","venv","dist","build","out","target","coverage","htmlcov",".next",".turbo",".cache"]),R=new Set(["reports","cache","tmp",".cache"]);function y(t){if(!t)return false;let r=t.split(/[\\/]/).filter(Boolean);if(r.some(o=>P.has(o)))return false;for(let o=0;o<r.length-1;o+=1)if(r[o]===".rapidkit"&&R.has(r[o+1]))return false;return true}async function D(t){let r=new k(t.buildOptions,t.engineOptions),o=await r.start();if(t.emit(o),t.once)return;let c=t.debounceMs??250,a=t.selfWriteSuppressionMs??Math.max(400,c+150),n=null,d=false,i=false,l=0,p=async()=>{if(d){i=true;return}d=true;try{let e=await r.pulse();t.emit(e);}catch(e){t.emit({schemaVersion:M,kind:"error",sequence:-1,timestamp:new Date().toISOString(),mode:"full",modelHash:r.currentModel?m(r.currentModel):"",modelHashChanged:false,changedProjects:[],addedProjects:[],removedProjects:[],graph:{nodeCount:0,edgeCount:0,edgesAdded:[],edgesRemoved:[]},durationMs:0,error:e instanceof Error?e.message:String(e)});}finally{d=false,l=Date.now()+a,i&&(i=false,p());}},h=e=>{y(e)&&(d||Date.now()<l||(n&&clearTimeout(n),n=setTimeout(()=>{n=null,p();},c)));};t.onProgress?.(`Watching ${t.workspacePath} for changes (Ctrl+C to stop).`);let u=b.watch(t.workspacePath,{recursive:true},(e,s)=>{typeof s=="string"?h(s):s&&h(Buffer.from(s).toString("utf8"));});await new Promise(e=>{let s=()=>{n&&clearTimeout(n),u.close(),e();};if(t.signal){if(t.signal.aborted){s();return}t.signal.addEventListener("abort",s,{once:true});}u.on("error",()=>s());});}export{M as WORKSPACE_WATCH_EVENT_SCHEMA_VERSION,k as WorkspaceWatchEngine,m as computeWatchModelHash,w as diffWatchModels,y as isWatchRelevantPath,D as runWorkspaceWatch};
|
|
@@ -47,6 +47,140 @@ Side/cache (not gates): `.rapidkit/reports/doctor-workspace-cache.json` (`doctor
|
|
|
47
47
|
|
|
48
48
|
**CLI semantics:** `workspace diff --from` expects a **model or snapshot** baseline. `workspace impact --from` expects a **diff report**.
|
|
49
49
|
|
|
50
|
+
### Dependency graph (`workspace-dependency-graph.v1`)
|
|
51
|
+
|
|
52
|
+
The dependency graph is the first-class structure that promotes inter-project
|
|
53
|
+
relationships out of `workspace run`'s private logic into one versioned source
|
|
54
|
+
of truth consumed by `impact` (transitive blast radius), `verify`
|
|
55
|
+
(subgraph-scoped gating), `run --blast-radius`, and risk weighting.
|
|
56
|
+
|
|
57
|
+
| Field | Meaning |
|
|
58
|
+
| ----- | ------- |
|
|
59
|
+
| `nodes` | Projects in the workspace (`id`, workspace-relative `path`). |
|
|
60
|
+
| `edges` | Directed `from → to` relationships (`from` depends on `to`). Each edge carries a typed `kind`, a `source` (provenance), a `confidence` bucket, and `evidence` (the files that justify it). |
|
|
61
|
+
| `stats` | Counts (`nodeCount`, `edgeCount`, per-source edge counts) and `hasCycle` for the integrity gate. |
|
|
62
|
+
|
|
63
|
+
Edge `kind` ∈ `code-import`, `package-dep`, `event-pub-sub`, `service-dependsOn`,
|
|
64
|
+
`shared-resource`. Edge `source` ∈ `inferred`, `contract`, `manual` (`manual`/`contract`
|
|
65
|
+
are authoritative and override an `inferred` edge of the same kind between the same
|
|
66
|
+
nodes). Canonical source: `src/contracts/workspace-dependency-graph-contract.ts`;
|
|
67
|
+
JSON Schema: `contracts/workspace-intelligence/workspace-dependency-graph.v1.json`.
|
|
68
|
+
|
|
69
|
+
**Inference engine.** The graph is derived deterministically by
|
|
70
|
+
`src/workspace-dependency-graph.ts` (`inferWorkspaceDependencyGraph`) from multiple
|
|
71
|
+
sources: package manifests (`package.json` deps, `pyproject.toml` path deps, `go.mod`
|
|
72
|
+
replace → `package-dep`), cross-boundary JS/TS source imports (`code-import`), the
|
|
73
|
+
workspace contract (`dependsOn` → `service-dependsOn`, matched `publishes`/`consumes`
|
|
74
|
+
→ `event-pub-sub`, env↔port references → `shared-resource`), and an optional manual
|
|
75
|
+
override file. Node/edge ordering and `hashDependencyGraph` are stable, so the graph is
|
|
76
|
+
embedded as a first-class field of `workspace-model.v1` (`model.graph`) on every
|
|
77
|
+
`buildWorkspaceModel` run; `hashModel` normalizes the embedded `graph.generatedAt` so the
|
|
78
|
+
structural graph participates in the model hash without causing timestamp drift.
|
|
79
|
+
(`model.graph` is additive/optional for pre-graph readers.)
|
|
80
|
+
|
|
81
|
+
**Manual overrides.** `.rapidkit/workspace-graph.overrides.json` (`{ "edges": [{ "from",
|
|
82
|
+
"to", "kind", "evidence" }] }`) declares authoritative edges that win over inference for
|
|
83
|
+
the same `(from, to, kind)`.
|
|
84
|
+
|
|
85
|
+
**Graph-aware impact.** `workspace impact` consumes the graph for a true transitive
|
|
86
|
+
blast radius: alongside `affectedProjects` (directly changed) it emits `transitiveImpact[]`
|
|
87
|
+
— projects reached only through the graph, each with `origin: 'transitive'`, `distance`,
|
|
88
|
+
the shortest dependency `path`, and `via` (edge kind). `summary.blastRadius`
|
|
89
|
+
(`directlyAffected`, `transitivelyAffected`, `maxDistance`, `graphEdges`) summarizes the
|
|
90
|
+
reach. Both arrays feed the `verificationPlan`.
|
|
91
|
+
|
|
92
|
+
**Graph-aware verify.** `workspace verify` gates the **whole affected subgraph**, not just
|
|
93
|
+
the changed node. `affectedSubgraph` (`directlyChanged`, `transitiveDependents`, `covered`,
|
|
94
|
+
`uncovered`, `unverifiable`) records coverage per project: a dependent with failed or
|
|
95
|
+
missing-required verification evidence becomes a `graph.subgraph.<project>` blocking reason;
|
|
96
|
+
missing non-required evidence escalates the verdict to `needs-attention`; a dependent with no
|
|
97
|
+
applicable verification command is `unverifiable` (informational, never blocking).
|
|
98
|
+
|
|
99
|
+
**Centrality-weighted risk.** `workspace impact` computes graph centrality
|
|
100
|
+
(`fanIn`/`fanOut`/`reach`/`betweenness`) per project; each impact item carries `centrality`,
|
|
101
|
+
a directly-changed critical-path hotspot escalates its risk one level, and the report lists
|
|
102
|
+
`criticalPathHotspots[]` (ranked by reach then betweenness). Canonical source:
|
|
103
|
+
`src/workspace-graph-centrality.ts` (`computeGraphCentrality`).
|
|
104
|
+
|
|
105
|
+
**Graph integrity gate.** `workspace verify` emits `graphIntegrity` (`ok`, `cycles`,
|
|
106
|
+
`danglingEdges`, `orphans`, `stats`). Cycles and dangling edges are blocking
|
|
107
|
+
(`graph.integrity.cycle` / `graph.integrity.dangling` reasons); orphans are informational.
|
|
108
|
+
Canonical source: `src/workspace-graph-integrity.ts` (`checkGraphIntegrity`).
|
|
109
|
+
|
|
110
|
+
**Watch / daemon mode.** `workspace watch [--json] [--once]` keeps the model + graph in
|
|
111
|
+
memory and streams `workspace-watch-event.v1` records (`ready`/`changed`/`unchanged`/`error`)
|
|
112
|
+
on each settled change, driven by graph-aware incremental rebuilds. Events carry changed/added/
|
|
113
|
+
removed projects, graph edge deltas, structural `modelHash`, and `mode`/`durationMs`. Canonical
|
|
114
|
+
source: `src/workspace-watch.ts`.
|
|
115
|
+
|
|
116
|
+
**Health/impact history.** Each `workspace verify` run appends a compact record to
|
|
117
|
+
`.rapidkit/reports/workspace-intelligence-history.json` (`workspace-intelligence-history.v1`),
|
|
118
|
+
a ring buffer capped at the 50 most-recent entries (verdict, risk, freshness, gate, counts).
|
|
119
|
+
Canonical source: `src/workspace-history.ts`.
|
|
120
|
+
|
|
121
|
+
**Verify gate + policy violations.** `workspace verify --json` emits a `gate`
|
|
122
|
+
object (`passed`, `mode`, `exitCode`, `reasons`) from `evaluateWorkspaceVerifyGate` — the
|
|
123
|
+
definitive pre-action gate (default fails on `blocked`; `--strict` also fails on
|
|
124
|
+
`needs-attention` and `stale` freshness). It also emits `policyMode` + `policyViolations[]`
|
|
125
|
+
(model validation issues + contract `violations`); in `enforce` mode error-severity violations
|
|
126
|
+
block, in `warn` mode they escalate to needs-attention.
|
|
127
|
+
|
|
128
|
+
**Graph-aware freshness.** `workspace verify` emits a `freshness` block
|
|
129
|
+
(`verdict: fresh|stale|unknown`, `changed`/`added`/`removed`, `projectHashes`). Each project's
|
|
130
|
+
`transitiveInputsHash` chains its own content hash with its transitive dependencies' hashes, so
|
|
131
|
+
a dependency change makes every dependent stale deterministically. The verdict compares against
|
|
132
|
+
the previously written verify report. Canonical source: `src/workspace-graph-freshness.ts`.
|
|
133
|
+
|
|
134
|
+
**Graph command surface.** `workspace graph` emits the graph plus integrity + hotspots;
|
|
135
|
+
`workspace graph explain <project>` returns centrality and direct/transitive relationships;
|
|
136
|
+
`workspace graph dot|mermaid` render deterministic visualizations. Canonical source:
|
|
137
|
+
`src/workspace-graph.ts`. The `graph` subcommand is part of `WORKSPACE_SUBCOMMANDS` and is
|
|
138
|
+
published via `runtime-command-surface.v1` for IDE/CI capability detection.
|
|
139
|
+
|
|
140
|
+
### Model cache (`workspace-model-cache.v1`)
|
|
141
|
+
|
|
142
|
+
On-disk path: `.rapidkit/cache/workspace-model.v1.json`. Opt-in (`workspace model --cache`)
|
|
143
|
+
cache keyed by `inputsHash` — a deterministic fingerprint of the project set, per-project
|
|
144
|
+
manifest contents, workspace files (contract/workspace.json/policies), build flags, and CLI
|
|
145
|
+
version. On a hit the stored model is returned byte-for-byte; on a miss it is rebuilt and
|
|
146
|
+
rewritten. Canonical source: `src/workspace-model-cache.ts` (`computeModelInputsHash`,
|
|
147
|
+
`buildWorkspaceModelCached`). Granularity is manifest/project-set level, not per-source-file.
|
|
148
|
+
|
|
149
|
+
The envelope also stores per-project signatures (`computeProjectSignatures`: manifest hashes +
|
|
150
|
+
a source fingerprint of `path:size:mtime`) and workspace-file signatures, powering
|
|
151
|
+
`workspace model --incremental` (`buildWorkspaceModelIncremental`): unchanged project models are
|
|
152
|
+
reused and the dependency graph re-infers only edges incident to changed projects
|
|
153
|
+
(`inferWorkspaceDependencyGraphIncremental`). It falls back to a full rebuild on workspace-file
|
|
154
|
+
changes or project renames, and rescans code-imports fully when the node set changes. Reported
|
|
155
|
+
modes: `full` / `incremental` / `unchanged`.
|
|
156
|
+
|
|
157
|
+
### Freshness metadata (`rapidkit-freshness-metadata-v1`)
|
|
158
|
+
|
|
159
|
+
Intelligence reports carry a shared freshness envelope so any consumer (CLI
|
|
160
|
+
`workspace verify`, Workspai, CI) can detect staleness **without** re-running the
|
|
161
|
+
whole chain:
|
|
162
|
+
|
|
163
|
+
| Field | Meaning |
|
|
164
|
+
| ----- | ------- |
|
|
165
|
+
| `generatedAt` | ISO-8601 timestamp the report was produced. |
|
|
166
|
+
| `inputsHash` | Stable sha256 of the inputs that produced the report. If a freshly recomputed inputs hash differs, the report is stale. |
|
|
167
|
+
|
|
168
|
+
Canonical source: `src/contracts/freshness-metadata-contract.ts`
|
|
169
|
+
(`computeInputsHash`, `buildFreshnessMetadata`, `assessFreshness`). Verdicts:
|
|
170
|
+
`fresh` (hashes match), `stale` (hashes differ), `unknown` (either side missing,
|
|
171
|
+
e.g. legacy reports).
|
|
172
|
+
|
|
173
|
+
### Run correlation (`runId`)
|
|
174
|
+
|
|
175
|
+
When a command runs through the CLI with the structured log stream active, the
|
|
176
|
+
persisted intelligence artifacts (`workspace-model.json`, `workspace-model-snapshot.json`,
|
|
177
|
+
`workspace-model-diff-last-run.json`, `workspace-impact*.json`, `workspace-context-agent.json`)
|
|
178
|
+
carry a top-level `runId`. It matches the `runId` on the `cli-log-event.v1` stream
|
|
179
|
+
(`run.started`/`progress`/`run.completed`), so a consumer can tie an on-disk report
|
|
180
|
+
to the exact run that produced it. `runId` is added at write time only and is
|
|
181
|
+
ignored by `modelHash`/diff comparisons, so deterministic hashing is unaffected.
|
|
182
|
+
Canonical source: `src/observability/run-correlation.ts` (`attachRunCorrelation`).
|
|
183
|
+
|
|
50
184
|
## Operational / platform
|
|
51
185
|
|
|
52
186
|
| Command | Artifact | Notes |
|
|
@@ -69,6 +203,19 @@ Side/cache (not gates): `.rapidkit/reports/doctor-workspace-cache.json` (`doctor
|
|
|
69
203
|
| `contracts/runtime-command-surface.v1.json` | `rapidkit-runtime-command-surface-v1` | Runtime commands, scaffold kits, and create planner summary |
|
|
70
204
|
| `contracts/create-planner-capabilities.v1.json` | `rapidkit-create-planner-capabilities-v1` | Native create, external-create-adopt, and adopt-only lanes for CLI, CI, VS Code, and AI planners |
|
|
71
205
|
|
|
206
|
+
## Observability stream (not on-disk)
|
|
207
|
+
|
|
208
|
+
Separate from the on-disk artifacts above, `rapidkit-npm` emits a structured
|
|
209
|
+
**NDJSON log stream on stderr** when `--log-format json` (or `RAPIDKIT_LOG_FORMAT=json`)
|
|
210
|
+
is set. This is the deterministic progress/outcome channel for IDEs and CI.
|
|
211
|
+
|
|
212
|
+
| Stream | Schema version | Contract file | Doc |
|
|
213
|
+
| ------ | -------------- | ------------- | --- |
|
|
214
|
+
| CLI log events (stderr) | `cli-log-event-v1` | `contracts/cli-log-event.v1.json` | [CLI_LOG_EVENT_STREAM.md](./CLI_LOG_EVENT_STREAM.md) |
|
|
215
|
+
|
|
216
|
+
**Channel rule:** command **results** go to stdout (`--json`); **progress/lifecycle**
|
|
217
|
+
events go to stderr (`--log-format json`). The two never mix.
|
|
218
|
+
|
|
72
219
|
## Registry commands
|
|
73
220
|
|
|
74
221
|
| Command | Output |
|
|
@@ -108,4 +255,5 @@ Written by `workspace agent-sync --write` (and by default after `workspace conte
|
|
|
108
255
|
|
|
109
256
|
- [README.md](./README.md)
|
|
110
257
|
- [COMMAND_OWNERSHIP_MATRIX.md](./COMMAND_OWNERSHIP_MATRIX.md)
|
|
258
|
+
- [CLI_LOG_EVENT_STREAM.md](./CLI_LOG_EVENT_STREAM.md)
|
|
111
259
|
- [commands-reference.md](../commands-reference.md)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# RapidKit CLI Log Event Stream (`cli-log-event.v1`)
|
|
2
|
+
|
|
3
|
+
Structured NDJSON observability stream emitted by `rapidkit-npm` so IDEs (Workspai),
|
|
4
|
+
CI, and agents can track command progress and outcome **without scraping human
|
|
5
|
+
terminal text**.
|
|
6
|
+
|
|
7
|
+
- **Schema version:** `cli-log-event-v1`
|
|
8
|
+
- **JSON Schema:** [`contracts/cli-log-event.v1.json`](../../contracts/cli-log-event.v1.json)
|
|
9
|
+
- **TypeScript contract:** `src/contracts/cli-log-event-contract.ts` (single runtime
|
|
10
|
+
source of `CLI_LOG_LEVELS`, `CLI_LOG_EVENT_KINDS`, `CLI_LOG_EVENT_REQUIRED_FIELDS`)
|
|
11
|
+
- **Drift guard:** `src/__tests__/contracts/cli-log-event-contract.test.ts` pins the
|
|
12
|
+
TypeScript contract to the JSON schema so the two can never diverge silently.
|
|
13
|
+
|
|
14
|
+
## Channel separation (critical)
|
|
15
|
+
|
|
16
|
+
RapidKit keeps two machine-readable channels strictly separate:
|
|
17
|
+
|
|
18
|
+
| Channel | Flag | Content |
|
|
19
|
+
| ------- | ---- | ------- |
|
|
20
|
+
| **stdout** | `--json` | The command **result** payload (e.g. workspace model, analyze report). One JSON document. |
|
|
21
|
+
| **stderr** | `--log-format json` (or `--log-json`, or `RAPIDKIT_LOG_FORMAT=json`) | The **NDJSON log stream** — one `cli-log-event.v1` object per line. |
|
|
22
|
+
|
|
23
|
+
Because the two channels are independent, a consumer can request structured
|
|
24
|
+
progress (`--log-format json`) **and** a structured result (`--json`) at the same
|
|
25
|
+
time without corrupting either stream.
|
|
26
|
+
|
|
27
|
+
## Activation
|
|
28
|
+
|
|
29
|
+
Any of the following enables the stream:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
rapidkit workspace model --json --log-format json
|
|
33
|
+
RAPIDKIT_LOG_FORMAT=json rapidkit workspace verify --json
|
|
34
|
+
rapidkit doctor workspace --log-json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
In text mode (the default) no structured log events are written to stderr.
|
|
38
|
+
|
|
39
|
+
### Flag normalization (why it works for every command)
|
|
40
|
+
|
|
41
|
+
`--log-format json` / `--log-json` are **not** registered as per-command options. On
|
|
42
|
+
startup the CLI resolves the requested format once, makes it sticky via
|
|
43
|
+
`RAPIDKIT_LOG_FORMAT=json`, and strips the observability flags from `process.argv`
|
|
44
|
+
before any command parser runs. This guarantees the stream works uniformly for
|
|
45
|
+
commander-parsed commands (e.g. `workspace model`), manually handled commands
|
|
46
|
+
(e.g. `create`), and delegated child CLIs (which inherit the env var) — without a
|
|
47
|
+
command ever rejecting the flag as an "unknown option". The result flag (`--json`)
|
|
48
|
+
is preserved, so the stdout result and the stderr stream stay independent.
|
|
49
|
+
|
|
50
|
+
## Workspace intelligence phase events
|
|
51
|
+
|
|
52
|
+
Every workspace intelligence subcommand (`model`, `snapshot`, `diff`, `impact`,
|
|
53
|
+
`verify`, `context`, `agent-sync`) emits at least a `progress` event when the
|
|
54
|
+
stream is active:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{ "event": "progress", "component": "workspace",
|
|
58
|
+
"metadata": { "phase": "workspace.model", "action": "model", "status": "started" } }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The terminal outcome is always covered by the run lifecycle (`run.completed` /
|
|
62
|
+
`run.failed`), so a consumer can settle UI state deterministically.
|
|
63
|
+
|
|
64
|
+
## Event shape
|
|
65
|
+
|
|
66
|
+
Each stderr line is a single JSON object:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"schemaVersion": "cli-log-event-v1",
|
|
71
|
+
"runId": "5f1d…",
|
|
72
|
+
"timestamp": "2026-06-22T13:59:01.123Z",
|
|
73
|
+
"level": "info",
|
|
74
|
+
"event": "run.started",
|
|
75
|
+
"component": "cli",
|
|
76
|
+
"message": "CLI run started",
|
|
77
|
+
"command": ["workspace", "model"],
|
|
78
|
+
"metadata": { "cwd": "/path/to/workspace", "rapidkitVersion": "0.38.0" }
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Fields
|
|
83
|
+
|
|
84
|
+
| Field | Required | Notes |
|
|
85
|
+
| ----- | -------- | ----- |
|
|
86
|
+
| `schemaVersion` | yes | Always `cli-log-event-v1`. |
|
|
87
|
+
| `runId` | yes | Stable UUID for the whole CLI invocation; correlates every event in one run. |
|
|
88
|
+
| `timestamp` | yes | ISO-8601 date-time. |
|
|
89
|
+
| `level` | yes | `debug` \| `info` \| `warn` \| `error`. |
|
|
90
|
+
| `event` | yes | `log` \| `progress` \| `run.started` \| `run.completed` \| `run.failed`. |
|
|
91
|
+
| `component` | yes | Emitting component (e.g. `cli`, `create`). |
|
|
92
|
+
| `message` | yes | Human-readable message. |
|
|
93
|
+
| `command` | no | Command argv (observability flags stripped). |
|
|
94
|
+
| `metadata` | no | Sanitized key/value context (e.g. `exitCode`, `cwd`, `rapidkitVersion`). |
|
|
95
|
+
|
|
96
|
+
## Run lifecycle events
|
|
97
|
+
|
|
98
|
+
Every invocation that runs through the CLI run context emits a deterministic
|
|
99
|
+
lifecycle, keyed by a shared `runId`:
|
|
100
|
+
|
|
101
|
+
1. `run.started` — emitted on initialization (`level: info`).
|
|
102
|
+
2. `run.completed` — emitted on exit code `0` (`level: info`, `metadata.exitCode: 0`).
|
|
103
|
+
3. `run.failed` — emitted on any non-zero exit (`level: error`, `metadata.exitCode: <n>`).
|
|
104
|
+
|
|
105
|
+
`run.completed` / `run.failed` are guaranteed even when a command calls
|
|
106
|
+
`process.exit()`, because the CLI installs a process-exit hook that finalizes the
|
|
107
|
+
run context.
|
|
108
|
+
|
|
109
|
+
## Consumer guidance (IDE / CI)
|
|
110
|
+
|
|
111
|
+
1. Spawn with `--log-format json` to receive progress; parse stderr line-by-line.
|
|
112
|
+
2. Treat a line as an event only if it parses as JSON and matches the schema
|
|
113
|
+
(`schemaVersion === 'cli-log-event-v1'`). Ignore non-matching lines.
|
|
114
|
+
3. Use `runId` to group events; show progress on `progress`/`log`, settle UI state
|
|
115
|
+
on `run.completed` / `run.failed`.
|
|
116
|
+
4. Read the command **result** from stdout `--json`, not from the log stream.
|
|
117
|
+
5. Workspai consumes this stream via `src/core/cliLogEventContract.ts`
|
|
118
|
+
(`parseCliLogEventLine`) to drive deterministic progress and evidence refresh.
|
|
119
|
+
|
|
120
|
+
## See also
|
|
121
|
+
|
|
122
|
+
- [ARTIFACT_CATALOG.md](./ARTIFACT_CATALOG.md) — on-disk artifacts produced by commands
|
|
123
|
+
- [COMMAND_OWNERSHIP_MATRIX.md](./COMMAND_OWNERSHIP_MATRIX.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rapidkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Open-source workspace intelligence CLI for software systems: create, adopt, govern, verify, and align polyglot workspaces for humans, CI, IDEs, and AI agents.",
|
|
6
6
|
"keywords": [
|
|
@@ -64,12 +64,15 @@
|
|
|
64
64
|
"test:e2e:user-first-install": "bash scripts/e2e-user-first-install.sh",
|
|
65
65
|
"test": "vitest run",
|
|
66
66
|
"test:drift": "node scripts/run-drift-guard.mjs",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
67
|
+
"benchmark:intelligence": "vitest run src/__tests__/workspace-intelligence-benchmark.test.ts",
|
|
68
|
+
"sync:shared-contracts": "node scripts/sync-shared-contracts.mjs",
|
|
69
|
+
"check:shared-contracts": "node scripts/sync-shared-contracts.mjs --check",
|
|
70
|
+
"sync:parity-snapshot": "node scripts/sync-shared-contracts.mjs",
|
|
71
|
+
"check:parity-snapshot": "node scripts/sync-shared-contracts.mjs --check",
|
|
69
72
|
"generate:contracts": "node scripts/generate-shared-contracts.mjs",
|
|
70
73
|
"check:generated-contracts": "node scripts/generate-shared-contracts.mjs --check",
|
|
71
|
-
"validate:contracts": "npm run check:
|
|
72
|
-
"test:parity-contract": "npm run check:
|
|
74
|
+
"validate:contracts": "npm run check:shared-contracts && vitest run src/__tests__/contracts/",
|
|
75
|
+
"test:parity-contract": "npm run check:shared-contracts && vitest run src/__tests__/contracts/import-stack-parity.snapshot.test.ts",
|
|
73
76
|
"test:watch": "vitest",
|
|
74
77
|
"test:coverage": "vitest run --coverage",
|
|
75
78
|
"test:prepare-embeddings": "node scripts/prepare-mock-embeddings.mjs",
|
package/dist/analyze-6RFG7C7Z.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export{b as printAnalyzeReport,a as runAnalyze}from'./chunk-T5LN7EO5.js';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export{b as AUTOPILOT_RELEASE_ALIAS_FILENAME,a as AUTOPILOT_RELEASE_LAST_RUN_FILENAME,c as runAutopilotRelease}from'./chunk-NKNMGWAZ.js';
|
package/dist/chunk-2ED6SPXP.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {r,j,q}from'./chunk-7XW2I6MP.js';import l from'path';import c from'fs-extra';var x=new Set([...r().map(e=>e.id),...j().map(e=>e.kitId)]),v=[{id:"wordpress-site",aliases:["wordpress","wordpress-site","wp","wp-site"],ecosystem:"wordpress",status:"planned",officialCommands:["wp core download","wp config create","wp db create","wp core install"],adoptAfterCreate:true},{id:"wordpress-block",aliases:["wordpress-block","wp-block","gutenberg-block"],ecosystem:"wordpress",status:"planned",officialCommands:["npx @wordpress/create-block@latest <slug>"],adoptAfterCreate:true},{id:"laravel",aliases:["laravel","php-laravel"],ecosystem:"php",status:"planned",officialCommands:["composer create-project laravel/laravel <name>"],adoptAfterCreate:true},{id:"symfony",aliases:["symfony","php-symfony"],ecosystem:"php",status:"planned",officialCommands:["composer create-project symfony/skeleton <name>"],adoptAfterCreate:true},{id:"rails",aliases:["rails","ruby-on-rails","ruby-rails"],ecosystem:"ruby",status:"planned",officialCommands:["rails new <name>"],adoptAfterCreate:true}],i=new Map;for(let e of v){i.set(e.id,e);for(let t of e.aliases)i.set(t,e);}var E=new Set(["php","ruby","rust","elixir","clojure","scala","kotlin","unknown"]);function s(e){return e?.trim().toLowerCase()||void 0}function I(e){let t=s(e.kitId)??s(e.framework)??s(e.runtime)??"unknown";if(e.projectExists)return {lane:"adopt-only",status:"available",canExecuteCreate:false,requested:t,reason:"Existing projects enter Workspace Intelligence through adopt/import."};let o=e.kitId?q(e.kitId):void 0;if(o&&x.has(o))return {lane:"native-create",status:"available",canExecuteCreate:true,requested:t,resolved:o,reason:"RapidKit owns the create contract, project marker, registry, doctor, and workspace model path."};let r=i.get(t)??i.get(s(e.framework)??"")??i.get(s(e.runtime)??"");if(r)return {lane:"external-create-adopt",status:r.status,canExecuteCreate:false,requested:t,resolved:r.id,officialCommands:r.officialCommands,fallbackLane:"adopt-only",reason:"External generator support is planned but not enabled; use adopt/import until RapidKit owns the post-create contract."};let n=s(e.runtime);return n&&E.has(n)?{lane:"adopt-only",status:"available",canExecuteCreate:false,requested:t,resolved:n,reason:"Runtime can be governed through Workspace Intelligence, but native create is not supported."}:{lane:"adopt-only",status:"available",canExecuteCreate:false,requested:t,reason:"No native create contract is available; use adopt/import to enter Workspace Intelligence."}}function h(e){return !e.canExecuteCreate&&(e.lane==="external-create-adopt"||e.lane==="adopt-only"&&e.resolved!==void 0)}var b=new Set(["service","frontend","worker","library","infra","docs","test-suite","unknown"]);async function m(e){try{if(!await c.pathExists(e))return null;let t=await c.readJSON(e);return t&&typeof t=="object"?t:null}catch{return null}}function w(e){if(typeof e!="string")return null;let t=e.trim().toLowerCase();return b.has(t)?t:null}async function S(e,t){let o=t??await m(l.join(e,".rapidkit","project.json")),r=w(o?.kind)??w(o?.type);if(r)return r;let n=await m(l.join(e,"package.json"));if(n){let a={...n.dependencies??{},...n.devDependencies??{}},k=n.scripts??{},d=Object.values(k).filter(C=>typeof C=="string").join(" ").toLowerCase();if(a.next||a.react||a.vue||a.svelte||a.vite||a["@angular/core"]||d.includes("next ")||d.includes("vite "))return "frontend";if(n.private===true&&!a.express&&!a["@nestjs/core"])return "library"}return await c.pathExists(l.join(e,"Dockerfile"))||await c.pathExists(l.join(e,"docker-compose.yml"))||await c.pathExists(l.join(e,"terraform.tf"))?"infra":"service"}export{I as a,h as b,S as c};
|
package/dist/chunk-3R7UJAX5.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {b}from'./chunk-C7WILE56.js';import {r,j as j$1}from'./chunk-7XW2I6MP.js';import {e}from'./chunk-RELR4O5E.js';import {a}from'./chunk-HEG6DIGW.js';import f,{promises}from'fs';import i from'path';import E,{homedir}from'os';import {pathToFileURL}from'url';import l from'process';function R(t){let r=t.label.indexOf(" \u2014 ");return r>=0?t.label.slice(r+3).trim():t.label.trim()}function j(){let t=r().map(r=>({value:r.id,label:R(r),hint:r.description,name:r.label})),e=j$1().map(r=>({value:r.kitId,label:r.displayName,hint:r.commandDisplay("my-app"),name:`${r.displayName} \u2014 ${r.framework}`}));return [...t,...e]}var _=".rapidkitrc.json",F=["rapidkit.config.js","rapidkit.config.mjs","rapidkit.config.cjs"];async function yt(){let t=i.join(E.homedir(),_);try{let e$1=await promises.readFile(t,"utf-8"),r=JSON.parse(e$1);return e.debug(`Loaded config from ${t}`),r}catch{return e.debug("No user config found, using defaults"),{}}}async function vt(t=process.cwd()){let e$1=t,r=i.parse(e$1).root;for(;e$1!==r;){for(let n of F){let o=i.join(e$1,n);try{await promises.access(o),e.debug(`Found config file: ${o}`);let m=await import(pathToFileURL(o).href),P=m.default||m;return e.debug(`Loaded RapidKit config from ${n}`),P}catch{continue}}e$1=i.dirname(e$1);}return e.debug("No RapidKit config file found, using defaults"),{}}function bt(t,e,r){return {author:r.author||e.workspace?.defaultAuthor||t.author,pythonVersion:r.pythonVersion||e.workspace?.pythonVersion||t.pythonVersion,defaultInstallMethod:r.defaultInstallMethod||e.workspace?.installMethod||t.defaultInstallMethod,defaultKit:r.defaultKit||e.projects?.defaultKit||t.defaultKit,skipGit:r.skipGit??e.projects?.skipGit??t.skipGit,license:r.license||t.license,testRapidKitPath:r.testRapidKitPath||t.testRapidKitPath}}function wt(t){return process.env.RAPIDKIT_DEV_PATH||t.testRapidKitPath||void 0}var x="workspai",Rt="Workspai";function L(t){return f.existsSync(i.join(t,".rapidkit-workspace"))||f.existsSync(i.join(t,".rapidkit","workspace.json"))}function g(t=homedir()){return i.join(t,"rapidkit","workspaces")}function K(t=homedir()){return i.join(t,"Workspai","rapidkits")}function y(t,e=homedir()){return i.join(g(e),t)}function U(t,e=homedir()){return [y(t,e),i.join(K(e),t)]}function D(t,e={}){let r=e.homeDir??homedir();return e.outputDir?i.resolve(e.outputDir,t):y(t,r)}function jt(t,e=homedir()){for(let r of U(t,e))if(f.existsSync(r))return r}function Et(t,e="my-workspace"){let r=1;for(;;){let n=r===1?e:`${e}-${r}`,o=i.join(t,n);if(!f.existsSync(o))return {name:n,targetPath:o};r+=1;}}function S(t=homedir()){return [i.join(g(t),x),i.join(K(t),x)]}function Mt(t=homedir()){for(let e of S(t))if(L(e))return e;return y(x,t)}function T(t,e){let r=t.indexOf(e);if(r>=0&&r+1<t.length)return t[r+1];let n=t.find(o=>o.startsWith(`${e}=`));if(n)return n.slice(e.length+1)}function N(t){return t.includes("--here")}function W(t,e=l.cwd()){if(N(t))return i.resolve(e);let r=T(t,"--output");if(r)return i.resolve(r)}function $t(t,e=l.cwd()){let r=i.resolve(t),n=i.resolve(e),o=i.relative(n,r);return o.length>0&&!o.startsWith("..")&&!i.isAbsolute(o)?`cd ${o}`:`cd ${r}`}function Gt(t,e={}){let r=e.argv??[],n=e.outputParent??W(r,l.cwd());return D(t.trim(),{homeDir:e.homeDir,outputDir:n})}async function Ot(t,e={}){let r=e.cwd??l.cwd(),n=e.homeDir??homedir(),o=W(t,r);if(o!==void 0)return o;let h=e.hasYes??(t.includes("--yes")||t.includes("-y"));if(!(e.interactive??(!h&&!!l.stdin.isTTY&&!a())))return;let P=g(n),{location:A}=await b([{type:"rawlist",name:"location",message:"Where should the workspace be created?",choices:[{value:"managed",label:"Managed home",hint:P},{value:"here",label:"Current directory",hint:r}],default:0}]);if(A==="here")return i.resolve(r)}export{j as a,yt as b,vt as c,bt as d,wt as e,Rt as f,g,jt as h,Et as i,Mt as j,$t as k,Gt as l,Ot as m};
|
package/dist/chunk-6E5TBB2C.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import {a,b,d}from'./chunk-FV5A3N3I.js';import {n,q,g}from'./chunk-YBS2HGO3.js';import {h,i,f,e}from'./chunk-UZW5QFRW.js';import {a as a$1}from'./chunk-VKLL63TL.js';import M from'fs';import w from'path';import j from'chalk';import {execa}from'execa';function le(e){return M.existsSync(w.join(e,"bun.lock"))||M.existsSync(w.join(e,"bunfig.toml"))?"bun":M.existsSync(w.join(e,"pnpm-lock.yaml"))?"pnpm":M.existsSync(w.join(e,"yarn.lock"))?"yarn":(M.existsSync(w.join(e,"package-lock.json")),"npm")}function pe(e,r,t=le(e)){return t==="npm"?`npm run ${r}`:`${t} run ${r}`}function me(e,r=le(e)){return `${r} install`}var Fe={"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:[]}}},Ae={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 fe(e$1,r,t){if(r){let o=r.trim().toLowerCase().replace(/[_.\s]+/g,"-"),a=e(r),f=`${e$1}-${a==="gofiber"?"fiber":a==="gogin"?"gin":a==="dotnet"?"aspnetcore":a!=="unknown"?a:o==="fiber"?"fiber":o==="aspnetcore"||o==="asp-net-core"?"aspnetcore":o}`,g=Fe[f];if(g&&g.commands[t])return g.commands[t]}let n=Ae[t]?.[e$1]??[];return n.length>0?n[0]:void 0}var Te={test:"test",build:"build",start:"start"};function U(e){if(e.stage==="init")return e.runtime==="node"?me(e.projectPath):fe(e.runtime,e.framework,e.stage);if(e.runtime==="node"){let r=Te[e.stage];if(r){let t=g(e.projectPath,r,{framework:e.framework});if(t)return pe(e.projectPath,t.scriptName)}}return fe(e.runtime,e.framework,e.stage)}function Ne(e){let r=h(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,n,o)=>o.indexOf(t)===n);return {primary:r.length>0?r[0]:"unknown",secondary:r.slice(1)}}function ge(e){return Ne(e).primary}function ye(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,n]of Object.entries(r))for(let o of n)if(new RegExp(o,"i").test(e))return t;return "unknown"}async function G(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 n=process.platform==="win32"?"where":"which";if((await execa(n,[r],{reject:false})).exitCode===0)return {valid:true}}catch{}return {valid:false,reason:`Command '${r}' not found or not executable`}}function he(e,r,t){if(!r)return e;let n=typeof r=="object"&&!Array.isArray(r)&&("dev"in r||"staging"in r||"prod"in r||"default"in r)&&!Object.keys(r).some(o=>["init","test","build","start"].includes(o))?r:{};return t&&typeof n[t]=="string"?n[t]:typeof n.default=="string"?n.default:e}var ke={init:"init",test:"test",build:"build",start:"start"};function Ie(e){return e in ke?ke[e]:null}function we(e,r,t=q(e)){let n=Ie(r);if(!n)return {supported:false,reason:`Workspace stage "${r}" is not part of the RapidKit fleet contract.`};if(!t.projectRoot)return {supported:false,reason:"No RapidKit project metadata was detected for this target."};let o=t.commandMap[n];return !o||o.status!=="supported"?{supported:false,reason:o?.reason??`Command "${n}" is not supported for this project runtime/framework.`}:{supported:true}}var We=new Set(["init","test","build","start"]),$e=new Set([".git","node_modules",".rapidkit",".venv","dist","build","coverage","htmlcov"]);async function W(e){try{return await M.promises.access(e,M.constants.F_OK),true}catch{return false}}async function De(e,r,t){if(r==="python"){let n=w.join(e,".rapidkit","cli.py");return await W(n)?{valid:true}:{valid:false,reason:"Project-local .rapidkit/cli.py is missing. Run `rapidkit init` in this project first."}}return G(t)}async function Y(e){let r=await M.promises.readFile(e,"utf-8");return JSON.parse(r)}function A(e){return e.replace(/\\/g,"/")}function Me(e){let r=e?.trim();return r?r.startsWith("project:")?r.slice(8).trim()||null:r:null}async function Oe(e){return a$1(e,{skipDirs:$e,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:h(r).length>0})}async function Le(e){for(let r of [w.join(".rapidkit","project.json"),w.join(".rapidkit","context.json")]){let t=w.join(e,r);if(await W(t))try{let n=await Y(t),o=n.name??n.projectName??n.slug;if(typeof o=="string"&&o.trim())return o.trim()}catch{}}return null}async function _e(e,r,t){let n=Me(t);if(!n)return {projects:r,normalizedScope:null};let o=A(n).toLowerCase(),a=[];for(let d of r){let f=A(w.relative(e,d)),g=w.basename(d),m=await Le(d);[f,g,m].filter(i=>typeof i=="string"&&i.length>0).map(i=>A(i).toLowerCase()).includes(o)&&a.push(d);}if(a.length===0)throw new Error(`Workspace run scope did not match any project: ${t}`);return {projects:a,normalizedScope:n}}async function Ge(e,r,t){let n=await execa("git",["diff","--name-only",`${t}...HEAD`],{cwd:e,reject:false});if(n.exitCode!==0)return new Set(r);let o=n.stdout.split(/\r?\n/).map(d=>d.trim()).filter(d=>d.length>0).map(d=>A(d));if(o.length===0)return new Set;let a=new Set;for(let d of r){let f=A(w.relative(e,d));if(!f||f===".")continue;let g=`${f}/`;o.some(m=>m===f||m.startsWith(g))&&a.add(d);}return a}async function Be(e,r,t){let n=w.join(e,".rapidkit","workspace.contract.json");if(await W(n))try{let s=await Ke(e,r,t,n);if(s.graphStatus!=="missing")return s}catch{return {expanded:t,graphStatus:"invalid",expansionDepth:0}}let o=w.join(e,".rapidkit","workspace-dependency-graph.json");if(!await W(o))return {expanded:t,graphStatus:"missing",expansionDepth:0};let a;try{a=await Y(o);}catch{return {expanded:t,graphStatus:"invalid",expansionDepth:0}}let d=new Set(r.map(s=>w.resolve(s))),f=new Map;if(!a||typeof a!="object"||Array.isArray(a))return {expanded:t,graphStatus:"invalid",expansionDepth:0};let g=Array.isArray(a.projects)?a.projects:[];for(let s of g){if(!s||typeof s!="object"||Array.isArray(s))continue;let x=s,S=typeof x.path=="string"?x.path:"",y=w.resolve(e,S);if(!d.has(y))continue;let c=Array.isArray(x.dependsOn)?x.dependsOn.filter(l=>typeof l=="string"):[];for(let l of c){let R=w.resolve(e,l);d.has(R)&&(f.has(R)||f.set(R,new Set),f.get(R)?.add(y));}}let m=new Set(t),b=[...m],i=0;for(;b.length>0;){let s=b.shift();if(!s)continue;let x=f.get(s);if(x)for(let S of x)m.has(S)||(m.add(S),b.push(S),i+=1);}return {expanded:m,graphStatus:"loaded",expansionDepth:i}}async function Ke(e,r,t,n){let o=await Y(n);if(!o||typeof o!="object"||Array.isArray(o))return {expanded:t,graphStatus:"invalid",expansionDepth:0};let a=o,d=Array.isArray(a.projects)?a.projects:null;if(!d)return {expanded:t,graphStatus:"invalid",expansionDepth:0};let f=new Map,g=new Map;for(let y of r){let c=A(w.relative(e,y));g.set(c,w.resolve(y));}let m=new Map,b=new Map,i=new Map;for(let y of d){if(!y||typeof y!="object"||Array.isArray(y))continue;let c=y,l=typeof c.slug=="string"?c.slug:"",R=typeof c.relativePath=="string"?A(c.relativePath):l,v=g.get(R);!l||!v||f.set(l,v);}for(let y of d){if(!y||typeof y!="object"||Array.isArray(y))continue;let c=y,l=typeof c.slug=="string"?c.slug:"",R=f.get(l);if(!R)continue;let v=c.contracts&&typeof c.contracts=="object"&&!Array.isArray(c.contracts)?c.contracts:{},D=Array.isArray(v.dependsOn)?v.dependsOn.filter(h=>typeof h=="string"):[],T=Array.isArray(v.publishes)?v.publishes.filter(h=>typeof h=="string"):[],N=Array.isArray(v.consumes)?v.consumes.filter(h=>typeof h=="string"):[];for(let h of D){let C=f.get(h);C&&(i.has(C)||i.set(C,new Set),i.get(C)?.add(R));}for(let h of T)m.has(h)||m.set(h,new Set),m.get(h)?.add(R);for(let h of N)b.has(h)||b.set(h,new Set),b.get(h)?.add(R);}for(let[y,c]of m.entries()){let l=b.get(y);if(l)for(let R of c){i.has(R)||i.set(R,new Set);for(let v of l)v!==R&&i.get(R)?.add(v);}}let s=new Set(t),x=[...s],S=0;for(;x.length>0;){let y=x.shift();if(!y)continue;let c=i.get(y);if(c)for(let l of c)s.has(l)||(s.add(l),x.push(l),S+=1);}return {expanded:s,graphStatus:"loaded",expansionDepth:S}}async function Ve(e,r){if(typeof r=="boolean")return r;let t=w.join(e,".rapidkit","policies.yml");if(!await W(t))return true;let n="";try{n=await M.promises.readFile(t,"utf-8");}catch{return true}let o=n.match(/^[\t ]*rules\.enforce_workspace_run_gates:\s*(true|false)\s*(?:#.*)?$/m);return o?o[1]==="true":true}async function J(e,r){let t=process.argv[1];if(!t)return {exitCode:1,stdout:"",stderr:"RapidKit entrypoint is unavailable for nested workspace-run execution."};let n=await execa(process.execPath,[t,...e],{cwd:r,reject:false,env:{...process.env,RAPIDKIT_WORKSPACE_RUN_CHILD:"1"}});return {exitCode:Number(n.exitCode??1),stdout:n.stdout,stderr:n.stderr}}function He(e){return e==="node"||e==="go"||e==="java"||e==="python"||e==="dotnet"}function ze(){return process.env.VITEST==="true"||process.env.VITEST==="1"||process.env.NODE_ENV==="test"}async function Ue(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 Je(e$1){let r=i=>{let s=f(i);return s==="node"||s==="bun"?"node":s==="python"?"python":s==="go"?"go":s==="java"?"java":s==="php"?"php":s==="ruby"?"ruby":s==="rust"?"rust":s==="dotnet"?"dotnet":s==="elixir"?"elixir":s==="clojure"||s==="scala"||s==="kotlin"?"jvm-generic":ge(e$1)},t=i=>{if(!i)return;let s=e(i);if(new Set(["fastapi","django","flask","nestjs","express","fastify","koa","gofiber","gogin","echo","springboot","laravel","symfony","rails","sinatra","dotnet","actix","axum","rocket","phoenix"]).has(s))return s},n$1=n(e$1),o=n$1?.detection??i(e$1,n$1?.projectJson??null),a=n$1?.contextJson,d=r(o.runtime),f$1=t(o.key),g={},m=new Set(["init","test","build","start"]);if(a?.commands&&typeof a.commands=="object")for(let[i,s]of Object.entries(a.commands))typeof s=="string"&&m.has(i)&&(g[i]=s);let b;if(a?.commandEnvironments&&typeof a.commandEnvironments=="object"){let i=a.commandEnvironments;b={dev:typeof i.dev=="string"?i.dev:void 0,staging:typeof i.staging=="string"?i.staging:void 0,prod:typeof i.prod=="string"?i.prod:void 0,default:typeof i.default=="string"?i.default:void 0};}return {runtime:d,framework:f$1,commandOverrides:Object.keys(g).length>0?g:void 0,environmentCommandVariants:b,environment:typeof a?.environment=="string"?a.environment:void 0}}async function qe(e,r,t,n,o,a,d){let f=!o?.[r]&&He(t),g;if(o&&o[r]?g=o[r]:f?g=`rapidkit ${r}`:g=U({projectPath:e,runtime:t,framework:n,stage:r}),!g)return {exitCode:127,command:`<stage not supported for ${t}>`,message:`No stage command found for runtime '${t}' and framework '${n||"unknown"}'`,errorCategory:"runtime"};let m=he(g,a,d);if(!m)return {exitCode:127,command:g,message:"Failed to resolve stage command",errorCategory:"runtime"};let b=U({projectPath:e,runtime:t,framework:n,stage:r});if(f){if(b){let c=f?await De(e,t,b):await G(b);if(!c.valid)return {exitCode:127,command:m,message:c.reason||"Command not available",errorCategory:"setup"}}}else {let c=await G(m);if(!c.valid)return {exitCode:127,command:m,message:c.reason||"Command not available",errorCategory:"setup"}}let i=0,s="",x="",S;try{let c=f?r==="init"&&ze()?await Ue(e):await J([r],e):await execa(m,[],{cwd:e,reject:false,shell:true});if(i=Number(c.exitCode??0),s=c.stdout,x=c.stderr,i!==0){let l=`${s}
|
|
2
|
-
${x}`;S=ye(l);}}catch(c){return {exitCode:1,command:m,message:c instanceof Error?c.message:"Command execution failed",errorCategory:"runtime"}}return {exitCode:i,command:m,errorCategory:S,healthStatus:void 0,message:i!==0?`Stage failed with exit code ${i}`:void 0}}function be(e){try{return JSON.parse(e)}catch{return null}}function Ye(e){switch(e){case "dotnet":return "Install .NET 8+ SDK, then rerun `npx rapidkit setup dotnet` or `npx rapidkit init`.";case "go":return "Install Go 1.21+, then rerun `npx rapidkit setup go` or `npx rapidkit init`.";case "java":case "jvm-generic":return "Install Java 21+ and Maven/Gradle, then rerun `npx rapidkit setup java` or `npx rapidkit init`.";case "node":return "Install Node.js LTS and npm/pnpm/yarn, then rerun `npx rapidkit setup node` or `npx rapidkit init`.";case "python":return "Install Python 3.10+ and pip/Poetry, then rerun `npx rapidkit setup python` or `npx rapidkit init`.";default:return null}}async function Qe(e){let r=[],t=await J(["doctor","workspace","--json"],e);if(t.exitCode!==0)r.push({gate:"doctor-workspace",status:"fail",summary:"doctor workspace command failed"});else {let a=be(t.stdout)?.healthScore,d=Number(a?.errors??0);Number.isFinite(d)&&d>0?r.push({gate:"doctor-workspace",status:"fail",summary:`doctor workspace reports ${d} error(s)`}):r.push({gate:"doctor-workspace",status:"pass",summary:"doctor workspace passed"});}let n=await J(["readiness","--json"],e);if(n.exitCode!==0)r.push({gate:"readiness",status:"fail",summary:"readiness command failed"});else {let o=be(n.stdout),a=String(o?.overallStatus??"").toLowerCase();a==="fail"?r.push({gate:"readiness",status:"fail",summary:"readiness overall status is fail"}):a==="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 Xe(e){return We.has(e)}function Ze(e,r){let t=Math.max(1,Math.min(4,r)),n=Number(e??t);return Number.isFinite(n)?Math.max(1,Math.min(16,Math.trunc(n))):t}async function Ct(e){if(!Xe(e.stage))throw new Error(`Unsupported workspace run stage: ${e.stage}`);let r=Date.now(),t=w.resolve(e.workspacePath),n=await Oe(t),{projects:o,normalizedScope:a$1}=await _e(t,n,e.scope),d$1=e.affected===true,f=e.blastRadius===true,g=e.since?.trim()||"HEAD~1",m=d$1?await Ge(t,o,g):new Set(o),b$1,i="not-applicable",s=0,x="all";if(d$1&&f){let p=await Be(t,n,m);b$1=p.expanded,i=p.graphStatus,s=p.expansionDepth,x="affected+blast-radius";}else d$1?(b$1=m,x="affected"):(b$1=m,x="all");let S=e.stage==="init"?false:await Ve(t,e.enforceGates),y=S?await Qe(t):[{gate:"doctor-workspace",status:"skipped",summary:"workspace run gates disabled"},{gate:"readiness",status:"skipped",summary:"workspace run gates disabled"}],c=y.find(p=>p.status==="fail"),l=o.filter(p=>b$1.has(p)),R=e.continueOnError===true||e.stage==="init",v=e.parallel===true,D=Ze(e.maxWorkers,l.length),T=l.length,N=0;e.json||console.log(j.gray(`Workspace run (${e.stage}) started: ${T} target(s), ${v?`parallel x${D}`:"sequential"}`));let h=new Map;for(let p of n){let k=o.includes(p),u=k&&b$1.has(p);h.set(p,{path:p,relativePath:A(w.relative(t,p)),selected:u,affected:u,status:"skipped",exitCode:null,durationMs:0,reason:u?void 0:k?"not affected":"outside scope",framework:void 0,runtimeDetected:void 0,executionCommand:void 0});}if(c)for(let p of l){let k=h.get(p);k&&(k.status="skipped",k.reason=`blocked by ${c.gate}`);}else {let p=async k=>{let u=h.get(k);if(!u)return;let $=A(w.relative(t,k));e.json||console.log(j.gray(`\u23F3 [${N}/${T}] ${e.stage} ${$}`)),u.selected=true,u.affected=true;let P=Date.now(),{runtime:E,framework:F,commandOverrides:ve,environmentCommandVariants:Se,environment:je}=await Je(k);u.runtimeDetected=E,u.framework=F;let te=we(k,e.stage);if(!te.supported){u.status="skipped",u.reason=te.reason??`stage "${e.stage}" unsupported for project`,u.durationMs=Date.now()-P,u.exitCode=null,N+=1;return}let I=await qe(k,e.stage,E,F,ve,Se,je);if(u.executionCommand=I.command,u.errorCategory=I.errorCategory,u.healthStatus=I.healthStatus,u.durationMs=Date.now()-P,u.exitCode=I.exitCode,I.exitCode===0?(u.status="passed",u.reason=void 0):(u.status="failed",u.reason=I.message||"stage command failed",u.errorMessage=I.message),N+=1,!e.json){let Ee=T>0?Math.round(N/T*100):100,Ce=u.status==="passed"?j.green("\u2705"):j.red("\u274C");if(console.log(j.gray(`${Ce} [${N}/${T}] (${Ee}%) ${$} ${u.durationMs}ms`)),u.status==="failed"){u.reason&&console.log(j.red(` Reason: ${u.reason}`)),u.executionCommand&&console.log(j.gray(` Command: ${u.executionCommand}`));let re=Ye(u.runtimeDetected);re&&u.errorCategory==="setup"&&console.log(j.gray(` Hint: ${re}`));}}};if(v&&l.length>1){let k=0,u=false,$=new Array(D).fill(null).map(async()=>{for(;k<l.length;){if(u&&!R)return;let P=k;k+=1;let E=l[P];await p(E),h.get(E)?.status==="failed"&&(u=true);}});if(await Promise.all($),!R&&u){let P=false;for(let E of l){let F=h.get(E);if(F){if(F.status==="failed"){P=true;continue}P&&F.status==="skipped"&&(F.reason=F.reason||"stopped after failure");}}}}else for(let k of l){await p(k);let u=h.get(k);if(!R&&u?.status==="failed"){let $=l.slice(l.indexOf(k)+1);for(let P of $){let E=h.get(P);E&&(E.status="skipped",E.reason="stopped after failure");}break}}}let C=[];for(let p of n){let k=h.get(p);k&&C.push(k);}let Q=C.filter(p=>p.status==="passed").length,K=C.filter(p=>p.status==="failed").length,X=C.filter(p=>p.status==="skipped").length,Z=e.strict===true,xe=K>0||Z&&y.some(p=>p.status==="fail"||p.status==="warn")?1:0,ee={schemaVersion:"1.0",workspacePath:t,stage:e.stage,generatedAt:new Date().toISOString(),durationMs:Date.now()-r,options:{affected:d$1,blastRadius:f,since:d$1?g:null,parallel:v,maxWorkers:D,continueOnError:R,strict:Z,enforceGates:S,scope:a$1},selection:{mode:x,since:d$1?g:null,scope:a$1,graphStatus:i,expansionDepth:s},gates:{enforced:S,results:y,blocked:!!c,blockingGate:c?.gate},summary:{projectCount:n.length,selectedCount:l.length,passed:Q,failed:K,skipped:X,exitCode:xe},projects:C,enterpriseControls:{jsonReady:true,evidencePath:b}},Re=w.join(t,".rapidkit","reports",a);return await d(t,ee),e.json||(c&&(console.log(j.red(`\u274C Workspace run blocked by ${c.gate}`)),console.log(j.gray(` ${c.summary}`))),console.log(j.cyan(`Workspace run (${e.stage}) => passed: ${Q}, failed: ${K}, skipped: ${X}`)),console.log(j.gray(`Report: ${Re}`))),ee}export{Ct as a};
|