@kitelev/exocortex-cli 16.144.2 → 16.145.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.
Files changed (2) hide show
  1. package/dist/index.js +4 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // @kitelev/exocortex-cli v16.144.2
2
+ // @kitelev/exocortex-cli v16.145.0
3
3
  // CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
4
4
  // License: MIT
5
5
 
@@ -608,18 +608,18 @@ Next steps:
608
608
  \u2713 AssetSpace unmounted`),i(` Folder: ${c} (removed from vault + .gitmodules)`)):(i(`
609
609
  \u2713 AssetSpace already absent \u2014 .gitmodules stanza stripped (no-op)`),i(` Folder: ${c}`)),{exitCode:0,stdout:t,stderr:r,removed:!0,folder:c}}a(vse,"runAssetSpaceRemove");function X4(){return new xe("assetspace-remove").description("Unmount a single AssetSpace (inverse of assetspace-add). Strips its .gitmodules stanza and deletes the mount folder. TS-floor AssetSpaces ({exo}) are refused.").requiredOption("--vault <path>","Path to target vault").option("--folder <path>","Vault-relative mount path to unmount (e.g. assetspaces/kitelev/exoas-pmbok-ontology). Takes precedence over --url.").option("--url <url>","Public GitHub URL of the AssetSpace \u2014 derives the canonical mount path (parity with assetspace-add).").option("--json","Emit result as JSON",!1).action(async n=>{try{let e=await vse(n);process.exit(e.exitCode)}catch(e){he.handle(e)}})}a(X4,"assetSpaceRemoveCommand");var Z4=require("node:path"),ej=require("node:fs");var ib=ae(Co()),DA=ae(require("path"));var ob=ae(nt());var sb=class{static{a(this,"RegistryDependencyResolver")}constructor(e={}){this.warn=e.warn??(()=>{})}async resolve(e,t){let r=await this.scanRegistry(e),i=this.matchSelf(r,t);if(i===null)return{outcome:"self-not-found",selfIdentifier:t,descriptorCount:r.size};let s=new Map;for(let g of r.values())g.dependsOn.length>0&&s.set(g.uid,g.dependsOn);let o=(0,ob.transitiveDependsOnClosure)([i.uid],s);o.delete(i.uid);let c=[],l=new Set,u=new Set([i.uid]),f=[...i.dependsOn];for(;f.length>0;){let g=f.shift();if(g===void 0||u.has(g))continue;u.add(g),o.has(g)&&!l.has(g)&&(c.push(g),l.add(g));let b=r.get(g);if(b!==void 0)for(let w of b.dependsOn)u.has(w)||f.push(w)}for(let g of o)l.has(g)||(c.push(g),l.add(g));let d=[],h=[];for(let g of c){let b=r.get(g);b===void 0?h.push(g):d.push(b)}let p=d.filter(g=>g.source===null||g.source.length===0),y=d.filter(g=>g.source!==null&&g.source.length>0&&!Ese(g.source));return{outcome:"resolved",self:i,dependencies:d,missingDescriptors:h,sourceless:p,unsafeSources:y}}matchSelf(e,t){let r=J4(t);if(r!==null)for(let i of e.values()){if(i.source===null)continue;let s=J4(i.source);if(s!==null&&s===r)return i}for(let i of e.values())if(i.namespace!==null&&i.namespace===t)return i;return null}async scanRegistry(e){let t=new Map,r=DA.default.resolve(e);if(!await ib.default.pathExists(r))return this.warn(`[RegistryDependencyResolver] registry path does not exist: ${r}`),t;let i=[r];for(;i.length>0;){let s=i.pop(),o;try{o=await ib.default.readdir(s,{withFileTypes:!0})}catch{continue}for(let c of o){let l=DA.default.join(s,c.name);if(c.isDirectory()){if(c.name.startsWith(".")||c.name==="node_modules"||c.name===".obsidian"||c.name===".exocortex")continue;i.push(l);continue}if(!c.isFile()||!c.name.endsWith(".md"))continue;let u=await this.tryReadFrontmatter(l);if(u===null||!ko(u.exo__Instance_class).some(g=>g===dh))continue;let d=u.exo__Asset_uid;if(typeof d!="string"||d.length===0)continue;let h=typeof u.exo__AssetSpace_source=="string"?u.exo__AssetSpace_source:typeof u.exo__AssetSpace_git=="string"?u.exo__AssetSpace_git:null,p=typeof u.exo__AssetSpace_namespace=="string"?u.exo__AssetSpace_namespace:null,y=ko(u.exo__AssetSpace_dependsOn);t.has(d)&&this.warn(`[RegistryDependencyResolver] duplicate AssetSpace descriptor for uid=${d} \u2014 last wins (${l})`),t.set(d,{uid:d,namespace:p,source:h,dependsOn:y})}}return t}async tryReadFrontmatter(e){let t;try{t=await ib.default.readFile(e,"utf-8")}catch{return null}if(!t.startsWith("---"))return null;let r=t.match(/^---\r?\n([\s\S]*?)\r?\n---/);if(r===null)return null;try{let i=Ft.load(r[1]);return i&&typeof i=="object"&&!Array.isArray(i)?i:null}catch{return null}}};function J4(n){let e=n.trim();if(e.length===0)return null;let t=(0,ob.derivePath)(e);if(t!==null)return t.replace(/^assetspaces\//,"").toLowerCase();if(!e.includes("://")&&!e.includes("@")){let i=e.replace(/\.git$/i,"").replace(/\/+$/,"").split("/").filter(s=>s.length>0);if(i.length===2)return`${i[0]}/${i[1]}`.toLowerCase()}return null}a(J4,"ownerRepoSlug");function Ese(n){return typeof n!="string"||n.length===0||/[\s\x00-\x1f]/.test(n)||n.startsWith("-")||/^(ext|file|fd|ftp|ftps)::/i.test(n)?!1:!!(/^https?:\/\/[^\s]+$/i.test(n)||/^ssh:\/\/[^\s]+$/i.test(n)||/^git:\/\/[^\s]+$/i.test(n)||/^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+:[^\s]+$/.test(n))}a(Ese,"isSafeCloneUrl");async function Tse(n,e={}){let t=e.out??(l=>process.stdout.write(`${l}
610
610
  `)),r=e.err??(l=>process.stderr.write(`${l}
611
- `));if(!n.registry)throw new et("--registry <path> is required");if(!n.self)throw new et("--self <owner/repo | git-url | namespace> is required");let i=(0,Z4.resolve)(n.registry);if(!(0,ej.existsSync)(i))throw new et(`Registry path does not exist: ${i}`,"Clone kitelev/exoas-registry first, then pass --registry <path>");let o=await new sb({warn:a(l=>r(l),"warn")}).resolve(i,n.self),c=n.format??"urls";if(o.outcome==="self-not-found"){let l=`[resolve-deps] self '${n.self}' not found among ${o.descriptorCount} registry descriptor(s) \u2014 validating standalone (no dependencies to materialise).`;return n.strict?(r(`[resolve-deps] STRICT: self '${n.self}' not registered. Add an exo__AssetSpace descriptor to kitelev/exoas-registry.`),c==="json"&&t(JSON.stringify(o,null,2)),{exitCode:2,outcome:o}):(r(l),c==="json"&&t(JSON.stringify(o,null,2)),{exitCode:0,outcome:o})}if(o.missingDescriptors.length>0&&r(`[resolve-deps] \u26A0\uFE0F ${o.missingDescriptors.length} dangling dependsOn edge(s) (no descriptor in registry): `+o.missingDescriptors.join(", ")),o.sourceless.length>0&&r(`[resolve-deps] \u26A0\uFE0F ${o.sourceless.length} dependency descriptor(s) have no source URL (cannot clone): `+o.sourceless.map(l=>l.namespace??l.uid).join(", ")),o.unsafeSources.length>0&&r(`[resolve-deps] \u26A0\uFE0F ${o.unsafeSources.length} dependency source(s) rejected as unsafe git-clone targets (option/transport injection) \u2014 NOT emitted: `+o.unsafeSources.map(l=>`${l.namespace??l.uid}=${l.source}`).join(", ")),c==="json")t(JSON.stringify(o,null,2));else{let l=new Set(o.unsafeSources.map(u=>u.uid));for(let u of o.dependencies)u.source&&u.source.length>0&&!l.has(u.uid)&&t(u.source)}return{exitCode:0,outcome:o}}a(Tse,"runResolveDeps");function tj(){return new xe("resolve-deps").description("Resolve an AssetSpace repo's transitive dependsOn closure from the central registry and print dependency clone URLs (issue #3513). Used by the per-AssetSpace SHACL CI gate to materialise dependent TBox.").requiredOption("--registry <path>","Path to a checked-out central registry (kitelev/exoas-registry)").requiredOption("--self <id>","Identity of the calling repo: an owner/repo slug (e.g. kitelev/exoas-exo, matches GitHub's github.repository), a full git URL, or a bare namespace").option("--format <type>","Output format: urls (one clone URL per line) | json (full diagnostics)","urls").option("--strict","Exit non-zero (2) when self is not registered, instead of validating standalone",!1).action(async n=>{try{let{exitCode:e}=await Tse(n);process.exit(e)}catch(e){he.handle(e)}})}a(tj,"resolveDepsCommand");var Hu=require("fs"),nj=ae(Co()),NA=require("path");var Ase="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",rj=new RegExp(`@req:(${Ase})`,"g"),xse=["**/*.test.ts","**/*.test.tsx","**/*.spec.ts","**/*.spec.tsx"],Ise=["**/node_modules/**","**/dist/**","**/.git/**"],Rse={unit:"unit",integration:"integration",e2e:"e2e",guibdd:"gui-bdd",uiacceptance:"ui-acceptance"},ij="ui-acceptance",Cse=new Set(["integration","e2e","gui-bdd",ij]);function LA(n){return n.bindingClasses.includes(ij)}a(LA,"isManuallyVerified");function kA(n){return n==null?[]:Array.isArray(n)?n.filter(e=>typeof e=="string"):typeof n=="string"?[n]:[]}a(kA,"asStringArray");function Ose(n){let e=kA(n)[0];if(!e)return null;let t=e.match(/RequirementPriority(P[0-3])\b/);return t?t[1]:null}a(Ose,"parsePriority");function Pse(n){let e=[];for(let t of kA(n)){let r=t.match(/RequirementBindingClass([A-Za-z0-9]+)/);if(!r)continue;let i=r[1].toLowerCase();e.push(Rse[i]??i)}return e}a(Pse,"parseBindingClasses");function Fse(n){let e=kA(n)[0];if(!e)return null;let t=e.match(/RequirementStatus([A-Za-z]+)/);return t?t[1]:null}a(Fse,"parseStatus");async function Dse(n){let t=await new Pa(n).indexedAssets(),r=[];for(let{path:i,metadata:s}of t){let o=i.split("/");if(o.includes("node_modules")||o.includes(".git")||s.req__Requirement_status===void 0)continue;let c=typeof s.exo__Asset_uid=="string"?s.exo__Asset_uid:i.replace(/^.*\//,"").replace(/\.md$/,""),l=typeof s.exo__Asset_label=="string"?s.exo__Asset_label:c;r.push({uid:c,label:l,path:i,priority:Ose(s.req__Requirement_priority),bindingClasses:Pse(s.req__Requirement_bindingClass),status:Fse(s.req__Requirement_status)})}return r}a(Dse,"loadRequirements");function Lse(n,e){let t=[],r=e.split(`
611
+ `));if(!n.registry)throw new et("--registry <path> is required");if(!n.self)throw new et("--self <owner/repo | git-url | namespace> is required");let i=(0,Z4.resolve)(n.registry);if(!(0,ej.existsSync)(i))throw new et(`Registry path does not exist: ${i}`,"Clone kitelev/exoas-registry first, then pass --registry <path>");let o=await new sb({warn:a(l=>r(l),"warn")}).resolve(i,n.self),c=n.format??"urls";if(o.outcome==="self-not-found"){let l=`[resolve-deps] self '${n.self}' not found among ${o.descriptorCount} registry descriptor(s) \u2014 validating standalone (no dependencies to materialise).`;return n.strict?(r(`[resolve-deps] STRICT: self '${n.self}' not registered. Add an exo__AssetSpace descriptor to kitelev/exoas-registry.`),c==="json"&&t(JSON.stringify(o,null,2)),{exitCode:2,outcome:o}):(r(l),c==="json"&&t(JSON.stringify(o,null,2)),{exitCode:0,outcome:o})}if(o.missingDescriptors.length>0&&r(`[resolve-deps] \u26A0\uFE0F ${o.missingDescriptors.length} dangling dependsOn edge(s) (no descriptor in registry): `+o.missingDescriptors.join(", ")),o.sourceless.length>0&&r(`[resolve-deps] \u26A0\uFE0F ${o.sourceless.length} dependency descriptor(s) have no source URL (cannot clone): `+o.sourceless.map(l=>l.namespace??l.uid).join(", ")),o.unsafeSources.length>0&&r(`[resolve-deps] \u26A0\uFE0F ${o.unsafeSources.length} dependency source(s) rejected as unsafe git-clone targets (option/transport injection) \u2014 NOT emitted: `+o.unsafeSources.map(l=>`${l.namespace??l.uid}=${l.source}`).join(", ")),c==="json")t(JSON.stringify(o,null,2));else{let l=new Set(o.unsafeSources.map(u=>u.uid));for(let u of o.dependencies)u.source&&u.source.length>0&&!l.has(u.uid)&&t(u.source)}return{exitCode:0,outcome:o}}a(Tse,"runResolveDeps");function tj(){return new xe("resolve-deps").description("Resolve an AssetSpace repo's transitive dependsOn closure from the central registry and print dependency clone URLs (issue #3513). Used by the per-AssetSpace SHACL CI gate to materialise dependent TBox.").requiredOption("--registry <path>","Path to a checked-out central registry (kitelev/exoas-registry)").requiredOption("--self <id>","Identity of the calling repo: an owner/repo slug (e.g. kitelev/exoas-exo, matches GitHub's github.repository), a full git URL, or a bare namespace").option("--format <type>","Output format: urls (one clone URL per line) | json (full diagnostics)","urls").option("--strict","Exit non-zero (2) when self is not registered, instead of validating standalone",!1).action(async n=>{try{let{exitCode:e}=await Tse(n);process.exit(e)}catch(e){he.handle(e)}})}a(tj,"resolveDepsCommand");var Hu=require("fs"),nj=ae(Co()),NA=require("path");var Ase="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",rj=new RegExp(`@req:(${Ase})`,"g"),xse=["**/*.test.ts","**/*.test.tsx","**/*.spec.ts","**/*.spec.tsx"],Ise=["**/node_modules/**","**/dist/**","**/.git/**"],Rse={unit:"unit",component:"component",integration:"integration",e2e:"e2e",guibdd:"gui-bdd",uiacceptance:"ui-acceptance"},ij="ui-acceptance",Cse=new Set(["integration","e2e","gui-bdd",ij]);function LA(n){return n.bindingClasses.includes(ij)}a(LA,"isManuallyVerified");function kA(n){return n==null?[]:Array.isArray(n)?n.filter(e=>typeof e=="string"):typeof n=="string"?[n]:[]}a(kA,"asStringArray");function Ose(n){let e=kA(n)[0];if(!e)return null;let t=e.match(/RequirementPriority(P[0-3])\b/);return t?t[1]:null}a(Ose,"parsePriority");function Pse(n){let e=[];for(let t of kA(n)){let r=t.match(/RequirementBindingClass([A-Za-z0-9]+)/);if(!r)continue;let i=r[1].toLowerCase();e.push(Rse[i]??i)}return e}a(Pse,"parseBindingClasses");function Fse(n){let e=kA(n)[0];if(!e)return null;let t=e.match(/RequirementStatus([A-Za-z]+)/);return t?t[1]:null}a(Fse,"parseStatus");async function Dse(n){let t=await new Pa(n).indexedAssets(),r=[];for(let{path:i,metadata:s}of t){let o=i.split("/");if(o.includes("node_modules")||o.includes(".git")||s.req__Requirement_status===void 0)continue;let c=typeof s.exo__Asset_uid=="string"?s.exo__Asset_uid:i.replace(/^.*\//,"").replace(/\.md$/,""),l=typeof s.exo__Asset_label=="string"?s.exo__Asset_label:c;r.push({uid:c,label:l,path:i,priority:Ose(s.req__Requirement_priority),bindingClasses:Pse(s.req__Requirement_bindingClass),status:Fse(s.req__Requirement_status)})}return r}a(Dse,"loadRequirements");function Lse(n,e){let t=[],r=e.split(`
612
612
  `);for(let i=0;i<r.length;i++){rj.lastIndex=0;let s;for(;(s=rj.exec(r[i]))!==null;)t.push({uid:s[1].toLowerCase(),file:n,line:i+1})}return t}a(Lse,"extractReqTags");async function Nse(n,e=xse){let t=await Ra(e,{cwd:n,nodir:!0,ignore:Ise,absolute:!0});t.sort();let r=[];for(let i of t){let s=await nj.default.readFile(i,"utf-8");s.includes("@req:")&&r.push(...Lse(i,s))}return r}a(Nse,"scanTestTags");function kse(n,e){let t=new Map;for(let T of n)t.set(T.uid.toLowerCase(),T);let r=new Map;for(let T of e){let A=T.uid.toLowerCase(),R=r.get(A);R?R.push(T):r.set(A,[T])}let i=[],s=0,o=0;for(let T of n)r.has(T.uid.toLowerCase())?s++:LA(T)?o++:i.push({uid:T.uid,label:T.label,path:T.path});let c=[];for(let T of e)t.has(T.uid.toLowerCase())||c.push(T);let l=[];for(let[T,A]of r)A.length>1&&t.has(T)&&l.push({uid:t.get(T).uid,occurrences:A});let u=[],f=0;for(let T of n){if(T.priority===null){f++;continue}if(T.priority!=="P0"||T.bindingClasses.length===0)continue;T.bindingClasses.some(R=>Cse.has(R))||u.push({uid:T.uid,label:T.label,priority:T.priority,bindingClasses:T.bindingClasses})}let d=0,h=0;for(let T of n)T.priority==="P0"&&(d++,(r.has(T.uid.toLowerCase())||LA(T))&&h++);let p=d-h,y=[],g=0;for(let T of n){if(T.status?.toLowerCase()!=="active")continue;g++,!r.has(T.uid.toLowerCase())&&!LA(T)&&y.push({uid:T.uid,label:T.label,path:T.path,reason:"active requirement has no @req binding (and is not ui-acceptance) \u2014 fix the binding or move it to Deprecated"})}let b=n.length,w=b===0?1:(s+o)/b,S=c.length===0&&u.length===0&&y.length===0,x=d>0&&p===0&&u.length===0&&c.length===0;return{requirementCount:b,tagCount:e.length,bound:s,manuallyVerified:o,coverage:w,orphans:i,dangling:c,duplicates:l,floorViolations:u,unknownPriority:f,clean:S,activeTotal:g,activeViolations:y,p0Total:d,p0Bound:h,p0Orphans:p,rampReady:x}}a(kse,"auditTraceability");function Mse(n){return`${(n*100).toFixed(1)}%`}a(Mse,"formatPercent");function jse(n,e="soft"){if(console.log(`Requirements: ${n.requirementCount} | bound: ${n.bound} | ui-acceptance: ${n.manuallyVerified} | coverage: ${Mse(n.coverage)} | tags: ${n.tagCount}`),console.log(`P0 checklist: ${n.p0Bound}/${n.p0Total} bound | ramp-ready: ${n.rampReady?"yes":"no"} | gate: ${e}`),console.log(`Active requirements: ${n.activeTotal} | invariant violations: ${n.activeViolations.length}`),n.activeViolations.length>0){console.error(`
613
613
  Active-requirement invariant violations (${n.activeViolations.length}) \u2014 an active requirement has no verification binding (HARD, always blocks):`);for(let t of n.activeViolations)console.error(` ${t.uid} ${t.label}
614
614
  \u2192 ${t.reason}`)}if(n.dangling.length>0){console.error(`
615
615
  Dangling @req tags (${n.dangling.length}) \u2014 uid has no requirement:`);for(let t of n.dangling)console.error(` @req:${t.uid} ${t.file}:${t.line}`)}if(n.floorViolations.length>0){console.error(`
616
- Binding-class floor violations (${n.floorViolations.length}) \u2014 P0 bound solely to unit:`);for(let t of n.floorViolations)console.error(` ${t.uid} [${t.bindingClasses.join(", ")}] ${t.label}`)}if(n.orphans.length>0){console.error(`
616
+ Binding-class floor violations (${n.floorViolations.length}) \u2014 P0 bound solely to below-floor classes (unit/component):`);for(let t of n.floorViolations)console.error(` ${t.uid} [${t.bindingClasses.join(", ")}] ${t.label}`)}if(n.orphans.length>0){console.error(`
617
617
  Orphan requirements (${n.orphans.length}) \u2014 no @req binding (warning):`);for(let t of n.orphans)console.error(` ${t.uid} ${t.label}`)}if(n.duplicates.length>0){console.error(`
618
618
  Duplicate bindings (${n.duplicates.length}) \u2014 uid claimed by >1 test (warning):`);for(let t of n.duplicates){console.error(` ${t.uid}:`);for(let r of t.occurrences)console.error(` ${r.file}:${r.line}`)}}n.unknownPriority>0&&console.error(`
619
619
  Skipped floor check for ${n.unknownPriority} requirement(s) with unparseable priority (fail-open).`),n.clean?e==="hard"&&!n.rampReady?console.error(`
620
620
  FAIL (hard gate): ramp not ready \u2014 ${n.p0Orphans} P0 requirement(s) unbound`+(n.p0Total===0?" (no P0 requirements found)":"")+"."):console.log(`
621
621
  OK: no hard findings (dangling tags + binding-class floor are clean).`):console.error(`
622
- FAIL: ${n.dangling.length} dangling + ${n.floorViolations.length} floor violation(s) + ${n.activeViolations.length} active-requirement invariant violation(s).`)}a(jse,"renderText");function $se(n,e,t){return!n.clean||t&&n.orphans.length>0||e==="hard"&&!n.rampReady}a($se,"isHardFail");function sj(){return new xe("audit").description("Audit requirement\u2194test traceability: orphans, dangling @req tags, duplicate bindings, binding-class floor, coverage, P0 ramp-readiness").requiredOption("--reqs <path>","Directory tree containing req__Requirement assets (a vault or a reqs assetspace clone)").option("--tests <path>","Test-corpus root scanned for @req:<uid> tags",".").option("--output <type>","Response format: text|json","text").option("--strict","Also exit 1 on orphan requirements",!1).option("--gate <mode>","Gate mode: soft (warn only on hard findings) | hard (also block when the P0 checklist is not ramp-ready)","soft").action(async n=>{let e=n.output??"text";he.setFormat(e);let t=n.gate==="hard"?"hard":"soft";try{let r=(0,NA.resolve)(n.reqs);if(!(0,Hu.existsSync)(r)||!(0,Hu.statSync)(r).isDirectory())throw new He(r);let i=(0,NA.resolve)(n.tests??".");if(!(0,Hu.existsSync)(i)||!(0,Hu.statSync)(i).isDirectory())throw new He(i);let[s,o]=await Promise.all([Dse(r),Nse(i)]),c=kse(s,o);e==="json"?console.log(JSON.stringify({...c,gate:t},null,2)):jse(c,t),$se(c,t,n.strict===!0)&&(process.exitCode=1)}catch(r){he.handle(r)}})}a(sj,"requirementsAuditCommand");function oj(){let n=new xe("requirements").description("Requirements-management tooling (RFC 0003): traceability checker");return n.addCommand(sj()),n}a(oj,"requirementsCommand");function ab(n){let e=new xe;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.144.2"),e.addCommand(n4()),e.addCommand(h4()),e.addCommand(rM()),e.addCommand(oM()),e.addCommand(xM()),e.addCommand(aM()),e.addCommand(CM()),e.addCommand(jM()),e.addCommand(UM()),e.addCommand(e4()),e.addCommand(C4()),e.addCommand(z4()),e.addCommand(H4()),e.addCommand(Q4()),e.addCommand(X4()),e.addCommand(tj()),e.addCommand(k4()),e.addCommand(q4()),e.addCommand(oj()),e}a(ab,"createProgram");ab().parse();0&&(module.exports={createProgram});
622
+ FAIL: ${n.dangling.length} dangling + ${n.floorViolations.length} floor violation(s) + ${n.activeViolations.length} active-requirement invariant violation(s).`)}a(jse,"renderText");function $se(n,e,t){return!n.clean||t&&n.orphans.length>0||e==="hard"&&!n.rampReady}a($se,"isHardFail");function sj(){return new xe("audit").description("Audit requirement\u2194test traceability: orphans, dangling @req tags, duplicate bindings, binding-class floor, coverage, P0 ramp-readiness").requiredOption("--reqs <path>","Directory tree containing req__Requirement assets (a vault or a reqs assetspace clone)").option("--tests <path>","Test-corpus root scanned for @req:<uid> tags",".").option("--output <type>","Response format: text|json","text").option("--strict","Also exit 1 on orphan requirements",!1).option("--gate <mode>","Gate mode: soft (warn only on hard findings) | hard (also block when the P0 checklist is not ramp-ready)","soft").action(async n=>{let e=n.output??"text";he.setFormat(e);let t=n.gate==="hard"?"hard":"soft";try{let r=(0,NA.resolve)(n.reqs);if(!(0,Hu.existsSync)(r)||!(0,Hu.statSync)(r).isDirectory())throw new He(r);let i=(0,NA.resolve)(n.tests??".");if(!(0,Hu.existsSync)(i)||!(0,Hu.statSync)(i).isDirectory())throw new He(i);let[s,o]=await Promise.all([Dse(r),Nse(i)]),c=kse(s,o);e==="json"?console.log(JSON.stringify({...c,gate:t},null,2)):jse(c,t),$se(c,t,n.strict===!0)&&(process.exitCode=1)}catch(r){he.handle(r)}})}a(sj,"requirementsAuditCommand");function oj(){let n=new xe("requirements").description("Requirements-management tooling (RFC 0003): traceability checker");return n.addCommand(sj()),n}a(oj,"requirementsCommand");function ab(n){let e=new xe;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.145.0"),e.addCommand(n4()),e.addCommand(h4()),e.addCommand(rM()),e.addCommand(oM()),e.addCommand(xM()),e.addCommand(aM()),e.addCommand(CM()),e.addCommand(jM()),e.addCommand(UM()),e.addCommand(e4()),e.addCommand(C4()),e.addCommand(z4()),e.addCommand(H4()),e.addCommand(Q4()),e.addCommand(X4()),e.addCommand(tj()),e.addCommand(k4()),e.addCommand(q4()),e.addCommand(oj()),e}a(ab,"createProgram");ab().parse();0&&(module.exports={createProgram});
623
623
  /*! Bundled license information:
624
624
 
625
625
  reflect-metadata/Reflect.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitelev/exocortex-cli",
3
- "version": "16.144.2",
3
+ "version": "16.145.0",
4
4
  "description": "CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more",
5
5
  "main": "dist/index.js",
6
6
  "bin": {