@kitelev/exocortex-cli 16.88.0 → 16.88.1

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 +3 -3
  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.88.0
2
+ // @kitelev/exocortex-cli v16.88.1
3
3
  // CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
4
4
  // License: MIT
5
5
 
@@ -663,7 +663,7 @@ Available prefixes: ${u}`,this.wellKnownPrefixes[r]&&c.push(`Add: PREFIX ${r}: <
663
663
  FILTER(!CONTAINS(STR(?class), "PropertyCardinality"))
664
664
  }
665
665
  OPTIONAL { ?s exo:Asset_label ?label }
666
- }`),i=t.parse(r),o=new Fe.ExoQLAlgebraTranslator().translate(i);o=new Fe.AlgebraOptimizer().optimize(o);let u=await new Fe.ExoQLQueryExecutor(e).executeAll(o),f=new Set;for(let d of u){let h=d.toJSON(),p=h.s;if(typeof p=="string"){let y=xre(p);if(y){let w=Bk(y);w&&f.add(w)}}let g=h.label;typeof g=="string"&&g.startsWith("https://exocortex.my/ontology/")&&f.add(g)}return f}a(Rre,"loadDeclaredProperties");function Cre(n,e,t){let r=[],i;try{i=(0,yi.readFileSync)(n,"utf-8")}catch{return[]}let s=$k(i);if(!s)return[];let o=Object.keys(s),{toValidate:c,unknownPrefix:l}=Are(o);for(let u of l)r.push({file:e,property:u,reason:`Unknown namespace prefix in "${u}"`});for(let u of c){let f=Bk(u);f&&!t.has(f)&&r.push({file:e,property:u,reason:`Property "${u}" is not declared in the ontology`})}return r}a(Cre,"validateFile");var Pre="http://www.w3.org/2000/01/rdf-schema#subClassOf",Ore="https://exocortex.my/ontology/exo#Class_superClass",Gk="http://www.w3.org/2000/01/rdf-schema#label";function W2(n){let e=n.indexOf("__");if(e===-1)return null;let t=n.slice(0,e+2),r=n.slice(e+2),i=q2.get(t);return!i||!r?null:i+r}a(W2,"labelToOntologyIRI");function Dre(n){let e=decodeURIComponent(n),t=e.lastIndexOf("/");if(t===-1)return null;let r=e.slice(t+1),i=r.endsWith(".md")?r.slice(0,-3):r;return W2(i)}a(Dre,"fileIriToOntologyURIFromFilename");function Fre(n){let e=a(r=>{if(r instanceof Fe.DomainIRI)return{type:"iri",value:r.value};if(r instanceof Fe.DomainLiteral){let i={type:"literal",value:r.value};return r.datatype&&(i.datatype=r.datatype.value),r.language&&(i.language=r.language),i}return null},"mapNode"),t=[];for(let r of n){let i=e(r.subject),s=e(r.predicate),o=e(r.object);i&&s&&o&&t.push({subject:i,predicate:s,object:o})}return t}a(Fre,"domainToAlgebraTriples");var G2=class{constructor(e){this.subClassMap=new Map;let t=new Map,r=new Set,i=a(o=>o===Pre||o===Ore,"isSubClassPredicate");for(let o of e)o.predicate instanceof Fe.DomainIRI&&i(o.predicate.value)&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainIRI&&(r.add(o.subject.value),r.add(o.object.value));for(let o of e)if(o.predicate instanceof Fe.DomainIRI&&o.predicate.value===Gk&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainLiteral){let c=W2(o.object.value);c&&t.set(o.subject.value,c)}for(let o of r)if(!t.has(o)){let c=Dre(o);c&&t.set(o,c)}for(let[o,c]of t){let l=this.subClassMap.get(o)??new Set;l.add(c),this.subClassMap.set(o,l)}for(let o of e)if(o.predicate instanceof Fe.DomainIRI&&i(o.predicate.value)&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainIRI){let c=o.subject.value,l=o.object.value,u=this.subClassMap.get(c)??new Set;u.add(l),this.subClassMap.set(c,u);let f=t.get(c),d=l.startsWith("obsidian://")?t.get(l):l;if(f&&d){let h=this.subClassMap.get(f)??new Set;h.add(d),this.subClassMap.set(f,h)}}let s=e.filter(o=>o.predicate instanceof Fe.DomainIRI&&o.predicate.value===jk&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainIRI);for(let o of s){let c=o.subject.value,l=o.object.value,u=this.collectAncestors(l);for(let d of u){if(c===d)continue;let h=this.subClassMap.get(c)??new Set;h.add(d),this.subClassMap.set(c,h)}let f=t.get(c);if(f)for(let d of u){let h=d.startsWith("obsidian://")?t.get(d):d;if(!h||f===h)continue;let p=this.subClassMap.get(f)??new Set;p.add(h),this.subClassMap.set(f,p)}}}static{a(this,"TripleClassHierarchy")}collectAncestors(e){let t=new Set,r=new Set,i=[e];for(;i.length>0;){let s=i.shift();if(r.has(s))continue;r.add(s);let o=this.subClassMap.get(s);if(o)for(let c of o)c!==e&&(t.add(c),r.has(c)||i.push(c))}return t}isSubClassOf(e,t){let r=new Set,i=[e];for(;i.length>0;){let s=i.shift();if(s===t)return!0;if(r.has(s))continue;r.add(s);let o=this.subClassMap.get(s);if(o)for(let c of o)i.push(c)}return!1}};function qk(n,e){let t=`file://${n}`,r="https://exocortex.my/cli/shacl-validator",i={earl:"http://www.w3.org/ns/earl#",dc:"http://purl.org/dc/terms/",xsd:"http://www.w3.org/2001/XMLSchema#",sh:"http://www.w3.org/ns/shacl#"},s=[{"@type":"earl:Assertor","@id":r,"dc:title":"Exocortex CLI SHACL-lite Validator"},{"@type":"earl:TestSubject","@id":t,"dc:title":n}];if(e.violations.length===0)s.push({"@type":"earl:Assertion","earl:assertedBy":{"@id":r},"earl:subject":{"@id":t},"earl:result":{"@type":"earl:TestResult","earl:outcome":{"@id":"earl:passed"},"dc:description":"All nodes conform to shapes"}});else for(let o of e.violations)s.push({"@type":"earl:Assertion","earl:assertedBy":{"@id":r},"earl:subject":{"@id":t},"earl:test":{"@id":o.propertyPath},"earl:result":{"@type":"earl:TestResult","earl:outcome":{"@id":"earl:failed"},"dc:description":o.message,"sh:focusNode":o.focusNode,"sh:resultPath":o.propertyPath,"sh:resultSeverity":{"@id":`sh:${o.severity.replace("sh:","")}`},...o.actualValue!==void 0?{"sh:value":o.actualValue}:{}}});return{"@context":i,"@graph":s}}a(qk,"buildEARLReport");var Lre="https://exocortex.my/ontology/exo#Asset_legacyValidationException";function Nre(n,e){let t=new Set(n.filter(i=>i.predicate instanceof Fe.DomainIRI&&i.predicate.value===Lre).map(i=>i.subject instanceof Fe.DomainIRI?i.subject.value:null).filter(i=>i!==null));if(t.size===0)return e;let r=e.violations.filter(i=>!t.has(i.focusNode));return{conforms:r.every(i=>i.severity!=="sh:Violation"),violations:r}}a(Nre,"applyLegacyExceptionFilter");async function kre(n,e,t=[]){let r=new Fe.InMemoryTripleStore;await r.addAll(e);let i=new Fe.ShaclShapeRegistry((await Fe.ShapeLoader.loadFromRDFGraph(r)).getAll()),s=new G2(e),o=Fre(e);return(0,Fe.shaclValidate)(o,i,s)}a(kre,"runShapesValidation");function Mre(n,e){let t="obsidian://vault/",r=n.violations.filter(i=>{if(!i.focusNode.startsWith(t))return!1;let s;try{s=decodeURIComponent(i.focusNode.substring(t.length))}catch{s=i.focusNode.substring(t.length)}return e.has(s)});return{conforms:r.every(i=>i.severity!=="sh:Violation"),violations:r}}a(Mre,"filterReportToStagedFocusNodes");function jre(n,e,t){if(t==="earl"){let r=qk(n,{conforms:!0,violations:[]});console.log(JSON.stringify(r,null,2))}else if(t==="json"){let r=$e.success({vaultPath:n,alsoPaths:e.map(i=>(0,En.resolve)(i)),conforms:!0,violationCount:0,violations:[]});console.log(JSON.stringify(r,null,2))}else console.log("\u2705 No staged .md files to validate.")}a(jre,"emitEmptyStagedShapesResult");async function $re(n,e={}){let t=n.format||"text",r=e.getStagedMdFiles??Vk;try{let i=(0,En.resolve)(n.vault);if(!(0,yi.existsSync)(i))throw new Ne(i);let s=n.also??[],o=[i,...s.map(w=>(0,En.resolve)(w))],c=null;if(n.staged){let w=r(i);if(w.length===0){jre(i,s,t);return}t==="text"&&s.length>0&&console.log("\u26A0\uFE0F --staged scopes git diff --cached to the primary vault; focusNode IRIs from --also vaults that match a staged relPath will also pass the filter."),c=new Set(w)}t==="text"&&console.log(`\u{1F4E6} Loading vault (shapes-mode): ${i}...`);let{triples:l,cacheHit:u}=await Mk(i,s,!!n.useCache,t==="text");t==="text"&&u&&console.log("\u{1F680} Cache hit! Loading from persistent cache..."),t==="text"&&(console.log(`\u2705 Loaded ${l.length} triples`),console.log("\u{1F50D} Running SHACL-lite validation..."));let f=await kre(i,l,s),d=Nre(l,f);c&&(d=Mre(d,c));let h=a(w=>o.length>1?Tre(w,o):w,"qualifyNode"),p=d.violations.filter(w=>w.severity==="sh:Violation"),g=d.violations.filter(w=>w.severity!=="sh:Violation"),y=g.filter(w=>w.constraint==="class").length;if(t==="earl"){let w=qk(i,d);console.log(JSON.stringify(w,null,2))}else if(t==="json"){let w=a(E=>({...E,vaultQualifiedPath:h(E.focusNode)}),"annotate"),b=$e.success({vaultPath:i,alsoPaths:s.map(E=>(0,En.resolve)(E)),conforms:d.conforms,violationCount:p.length,warningCount:g.length,crossVaultRefWarnings:y,violations:p.map(w),warnings:g.map(w)});console.log(JSON.stringify(b,null,2))}else{if(p.length>0){let w=new Map;for(let b of p){let E=w.get(b.focusNode)??[];E.push(b),w.set(b.focusNode,E)}console.log(`\u26A0\uFE0F Found ${p.length} SHACL violation(s) in ${w.size} node(s):
666
+ }`),i=t.parse(r),o=new Fe.ExoQLAlgebraTranslator().translate(i);o=new Fe.AlgebraOptimizer().optimize(o);let u=await new Fe.ExoQLQueryExecutor(e).executeAll(o),f=new Set;for(let d of u){let h=d.toJSON(),p=h.s;if(typeof p=="string"){let y=xre(p);if(y){let w=Bk(y);w&&f.add(w)}}let g=h.label;typeof g=="string"&&g.startsWith("https://exocortex.my/ontology/")&&f.add(g)}return f}a(Rre,"loadDeclaredProperties");function Cre(n,e,t){let r=[],i;try{i=(0,yi.readFileSync)(n,"utf-8")}catch{return[]}let s=$k(i);if(!s)return[];let o=Object.keys(s),{toValidate:c,unknownPrefix:l}=Are(o);for(let u of l)r.push({file:e,property:u,reason:`Unknown namespace prefix in "${u}"`});for(let u of c){let f=Bk(u);f&&!t.has(f)&&r.push({file:e,property:u,reason:`Property "${u}" is not declared in the ontology`})}return r}a(Cre,"validateFile");var Pre="http://www.w3.org/2000/01/rdf-schema#subClassOf",Ore="https://exocortex.my/ontology/exo#Class_superClass",Gk="http://www.w3.org/2000/01/rdf-schema#label";function W2(n){let e=n.indexOf("__");if(e===-1)return null;let t=n.slice(0,e+2),r=n.slice(0,e),i=n.slice(e+2);if(!i)return null;let s=q2.get(t);return s?s+i:/^[a-z][a-zA-Z0-9]*$/.test(r)&&!/[\s()]/.test(i)?`https://exocortex.my/ontology/${r}#${i}`:null}a(W2,"labelToOntologyIRI");function Dre(n){let e=decodeURIComponent(n),t=e.lastIndexOf("/");if(t===-1)return null;let r=e.slice(t+1),i=r.endsWith(".md")?r.slice(0,-3):r;return W2(i)}a(Dre,"fileIriToOntologyURIFromFilename");function Fre(n){let e=a(r=>{if(r instanceof Fe.DomainIRI)return{type:"iri",value:r.value};if(r instanceof Fe.DomainLiteral){let i={type:"literal",value:r.value};return r.datatype&&(i.datatype=r.datatype.value),r.language&&(i.language=r.language),i}return null},"mapNode"),t=[];for(let r of n){let i=e(r.subject),s=e(r.predicate),o=e(r.object);i&&s&&o&&t.push({subject:i,predicate:s,object:o})}return t}a(Fre,"domainToAlgebraTriples");var G2=class{constructor(e){this.subClassMap=new Map;let t=new Map,r=new Set,i=a(o=>o===Pre||o===Ore,"isSubClassPredicate");for(let o of e)o.predicate instanceof Fe.DomainIRI&&i(o.predicate.value)&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainIRI&&(r.add(o.subject.value),r.add(o.object.value));for(let o of e)if(o.predicate instanceof Fe.DomainIRI&&o.predicate.value===Gk&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainLiteral){let c=W2(o.object.value);c&&t.set(o.subject.value,c)}for(let o of r)if(!t.has(o)){let c=Dre(o);c&&t.set(o,c)}for(let[o,c]of t){let l=this.subClassMap.get(o)??new Set;l.add(c),this.subClassMap.set(o,l)}for(let o of e)if(o.predicate instanceof Fe.DomainIRI&&i(o.predicate.value)&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainIRI){let c=o.subject.value,l=o.object.value,u=this.subClassMap.get(c)??new Set;u.add(l),this.subClassMap.set(c,u);let f=t.get(c),d=l.startsWith("obsidian://")?t.get(l):l;if(f&&d){let h=this.subClassMap.get(f)??new Set;h.add(d),this.subClassMap.set(f,h)}}let s=e.filter(o=>o.predicate instanceof Fe.DomainIRI&&o.predicate.value===jk&&o.subject instanceof Fe.DomainIRI&&o.object instanceof Fe.DomainIRI);for(let o of s){let c=o.subject.value,l=o.object.value,u=this.collectAncestors(l);for(let d of u){if(c===d)continue;let h=this.subClassMap.get(c)??new Set;h.add(d),this.subClassMap.set(c,h)}let f=t.get(c);if(f)for(let d of u){let h=d.startsWith("obsidian://")?t.get(d):d;if(!h||f===h)continue;let p=this.subClassMap.get(f)??new Set;p.add(h),this.subClassMap.set(f,p)}}}static{a(this,"TripleClassHierarchy")}collectAncestors(e){let t=new Set,r=new Set,i=[e];for(;i.length>0;){let s=i.shift();if(r.has(s))continue;r.add(s);let o=this.subClassMap.get(s);if(o)for(let c of o)c!==e&&(t.add(c),r.has(c)||i.push(c))}return t}isSubClassOf(e,t){let r=new Set,i=[e];for(;i.length>0;){let s=i.shift();if(s===t)return!0;if(r.has(s))continue;r.add(s);let o=this.subClassMap.get(s);if(o)for(let c of o)i.push(c)}return!1}};function qk(n,e){let t=`file://${n}`,r="https://exocortex.my/cli/shacl-validator",i={earl:"http://www.w3.org/ns/earl#",dc:"http://purl.org/dc/terms/",xsd:"http://www.w3.org/2001/XMLSchema#",sh:"http://www.w3.org/ns/shacl#"},s=[{"@type":"earl:Assertor","@id":r,"dc:title":"Exocortex CLI SHACL-lite Validator"},{"@type":"earl:TestSubject","@id":t,"dc:title":n}];if(e.violations.length===0)s.push({"@type":"earl:Assertion","earl:assertedBy":{"@id":r},"earl:subject":{"@id":t},"earl:result":{"@type":"earl:TestResult","earl:outcome":{"@id":"earl:passed"},"dc:description":"All nodes conform to shapes"}});else for(let o of e.violations)s.push({"@type":"earl:Assertion","earl:assertedBy":{"@id":r},"earl:subject":{"@id":t},"earl:test":{"@id":o.propertyPath},"earl:result":{"@type":"earl:TestResult","earl:outcome":{"@id":"earl:failed"},"dc:description":o.message,"sh:focusNode":o.focusNode,"sh:resultPath":o.propertyPath,"sh:resultSeverity":{"@id":`sh:${o.severity.replace("sh:","")}`},...o.actualValue!==void 0?{"sh:value":o.actualValue}:{}}});return{"@context":i,"@graph":s}}a(qk,"buildEARLReport");var Lre="https://exocortex.my/ontology/exo#Asset_legacyValidationException";function Nre(n,e){let t=new Set(n.filter(i=>i.predicate instanceof Fe.DomainIRI&&i.predicate.value===Lre).map(i=>i.subject instanceof Fe.DomainIRI?i.subject.value:null).filter(i=>i!==null));if(t.size===0)return e;let r=e.violations.filter(i=>!t.has(i.focusNode));return{conforms:r.every(i=>i.severity!=="sh:Violation"),violations:r}}a(Nre,"applyLegacyExceptionFilter");async function kre(n,e,t=[]){let r=new Fe.InMemoryTripleStore;await r.addAll(e);let i=new Fe.ShaclShapeRegistry((await Fe.ShapeLoader.loadFromRDFGraph(r)).getAll()),s=new G2(e),o=Fre(e);return(0,Fe.shaclValidate)(o,i,s)}a(kre,"runShapesValidation");function Mre(n,e){let t="obsidian://vault/",r=n.violations.filter(i=>{if(!i.focusNode.startsWith(t))return!1;let s;try{s=decodeURIComponent(i.focusNode.substring(t.length))}catch{s=i.focusNode.substring(t.length)}return e.has(s)});return{conforms:r.every(i=>i.severity!=="sh:Violation"),violations:r}}a(Mre,"filterReportToStagedFocusNodes");function jre(n,e,t){if(t==="earl"){let r=qk(n,{conforms:!0,violations:[]});console.log(JSON.stringify(r,null,2))}else if(t==="json"){let r=$e.success({vaultPath:n,alsoPaths:e.map(i=>(0,En.resolve)(i)),conforms:!0,violationCount:0,violations:[]});console.log(JSON.stringify(r,null,2))}else console.log("\u2705 No staged .md files to validate.")}a(jre,"emitEmptyStagedShapesResult");async function $re(n,e={}){let t=n.format||"text",r=e.getStagedMdFiles??Vk;try{let i=(0,En.resolve)(n.vault);if(!(0,yi.existsSync)(i))throw new Ne(i);let s=n.also??[],o=[i,...s.map(w=>(0,En.resolve)(w))],c=null;if(n.staged){let w=r(i);if(w.length===0){jre(i,s,t);return}t==="text"&&s.length>0&&console.log("\u26A0\uFE0F --staged scopes git diff --cached to the primary vault; focusNode IRIs from --also vaults that match a staged relPath will also pass the filter."),c=new Set(w)}t==="text"&&console.log(`\u{1F4E6} Loading vault (shapes-mode): ${i}...`);let{triples:l,cacheHit:u}=await Mk(i,s,!!n.useCache,t==="text");t==="text"&&u&&console.log("\u{1F680} Cache hit! Loading from persistent cache..."),t==="text"&&(console.log(`\u2705 Loaded ${l.length} triples`),console.log("\u{1F50D} Running SHACL-lite validation..."));let f=await kre(i,l,s),d=Nre(l,f);c&&(d=Mre(d,c));let h=a(w=>o.length>1?Tre(w,o):w,"qualifyNode"),p=d.violations.filter(w=>w.severity==="sh:Violation"),g=d.violations.filter(w=>w.severity!=="sh:Violation"),y=g.filter(w=>w.constraint==="class").length;if(t==="earl"){let w=qk(i,d);console.log(JSON.stringify(w,null,2))}else if(t==="json"){let w=a(E=>({...E,vaultQualifiedPath:h(E.focusNode)}),"annotate"),b=$e.success({vaultPath:i,alsoPaths:s.map(E=>(0,En.resolve)(E)),conforms:d.conforms,violationCount:p.length,warningCount:g.length,crossVaultRefWarnings:y,violations:p.map(w),warnings:g.map(w)});console.log(JSON.stringify(b,null,2))}else{if(p.length>0){let w=new Map;for(let b of p){let E=w.get(b.focusNode)??[];E.push(b),w.set(b.focusNode,E)}console.log(`\u26A0\uFE0F Found ${p.length} SHACL violation(s) in ${w.size} node(s):
667
667
  `);for(let[b,E]of w){let T=o.length>1?h(b):b;console.log(` \u274C ${T}`);for(let I of E){let A=I.severity.replace("sh:","");console.log(` [${A}] ${I.message}`)}}}else console.log("\u2705 Vault conforms to all shapes (no violations).");g.length>0&&console.log(`
668
668
  \u2139\uFE0F ${g.length} warning(s)`+(y>0?` (${y} unresolvable cross-vault/symbolic ref(s) \u2014 not validated, run with --also to resolve)`:"")+" \u2014 these do not affect the exit code.")}d.conforms||(process.exitCode=1)}catch(i){be.handle(i)}}a($re,"runShapesModeAction");function Wk(){return new Re("schema").description("Check frontmatter properties against ontology (Issue #2713)").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--also <path>","Additional vault to merge into validation graph (repeatable). --use-cache is disabled when --also is present.",_re,[]).option("--output <type>","Response format: text|json (for MCP tools)","text").option("--staged","Only validate git-staged .md files (for pre-commit hooks)").option("--use-cache","Use persistent triple cache (faster vault loading; disabled when --also is set)").option("--shapes-mode","Run SHACL-lite shapes validation instead of schema linting").option("--format <type>","Output format for shapes-mode: text|json|earl","text").option("--class <iri>","Only validate assets whose exo__Instance_class matches this IRI/slug (RFC 8e83442b T1.4)").action(async n=>{let e=n.output||"text";if(be.setFormat(e),n.shapesMode){await $re(n);return}try{let t=(0,En.resolve)(n.vault);if(!(0,yi.existsSync)(t))throw new Ne(t);let r;if(n.staged){if(r=Vk(t),r.length===0){if(e==="json"){let d=$e.success({vaultPath:t,filesChecked:0,violations:[],healthy:!0});console.log(JSON.stringify(d,null,2))}else console.log("\u2705 No staged .md files to validate.");return}}else r=Ire(t);if(n.class){let d=n.class;r=r.filter(h=>{try{let p=(0,yi.readFileSync)((0,En.resolve)(t,h),"utf-8"),g=$k(p);return bre(g,d)}catch{return!1}})}e==="text"&&console.log(`\u{1F4E6} Loading vault: ${t}...`);let i=n.also??[],{triples:s,cacheHit:o}=await Mk(t,i,!!n.useCache,e==="text"),c=s;e==="text"&&o&&console.log("\u{1F680} Cache hit! Loading from persistent cache..."),e==="text"&&(console.log(`\u2705 Loaded ${c.length} triples`),console.log("\u{1F50D} Querying ontology for declared properties..."));let l=await Rre(c);e==="text"&&(console.log(`\u{1F4CB} Found ${l.size} declared properties in ontology`),console.log(`\u{1F50D} Validating ${r.length} file(s)...
669
669
  `));let u=[];for(let d of r){let h=(0,En.resolve)(t,d),p=Cre(h,d,l);u.push(...p)}let f={vaultPath:t,filesChecked:r.length,violations:u,healthy:u.length===0};if(e==="json"){let d=$e.success(f);console.log(JSON.stringify(d,null,2))}else if(u.length===0)console.log(`\u2705 All ${r.length} file(s) pass schema validation.`);else{let d=new Map;for(let h of u){let p=d.get(h.file)||[];p.push(h),d.set(h.file,p)}console.log(`\u26A0\uFE0F Found ${u.length} schema violation(s) in ${d.size} file(s):
@@ -773,7 +773,7 @@ Next steps:
773
773
  `),process.stdout.write(` File: ${e.file}
774
774
  `),process.stdout.write(` Commit: ${e.sha}
775
775
  `),process.stdout.write(` URL: ${e.url}
776
- `)),process.exit(0)}catch(e){let t=e instanceof Error?e:new Error(String(e)),r=new Do;t.message=r.redact(t.message),t.stack&&(t.stack=r.redact(t.stack)),be.handle(t)}})}a(Eie,"restPushCommand");var Fo=require("node:fs"),p4=require("node:crypto"),_i=re(require("node:path"));var Si=re(it());var vie=a(async n=>{let e=await p4.webcrypto.subtle.digest("SHA-1",n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")},"nodeSha1"),Tie={parse:a(n=>Br.load(n,{schema:Br.CORE_SCHEMA}),"parse"),stringify:a(n=>Br.dump(n,{schema:Br.CORE_SCHEMA,lineWidth:-1}),"stringify")};function Aie(n,e){if(n.tokenFromGh===!0)return Do.resolveGhToken(e.ghTokenRunner);let t=e.env??process.env,r=n.token||t.GITHUB_TOKEN||t.GH_TOKEN||"";if(r.length===0)throw new Error("A GitHub token is required (private sync units read as 404 without one). Use --token-from-gh, --token <pat>, or set GITHUB_TOKEN / GH_TOKEN.");return r}a(Aie,"resolveToken");function Iie(n){let e=a(r=>_i.join(n,r),"abs"),t=a(async(r,i)=>{let s;try{s=await Fo.promises.readdir(r,{withFileTypes:!0})}catch{return}for(let o of s){let c=_i.join(r,o.name);if(o.isDirectory()){if(o.name===".git")continue;await t(c,i)}else o.isFile()&&i.push(_i.relative(n,c).split(_i.sep).join("/"))}},"walk");return{async list(){let r=[];return(0,Fo.existsSync)(n)&&await t(n,r),r},read:a(r=>Fo.promises.readFile(e(r),"utf-8"),"read"),async readBinary(r){return new Uint8Array(await Fo.promises.readFile(e(r)))},async write(){throw new Error("exosync-parity is read-only \u2014 write refused")},async delete(){throw new Error("exosync-parity is read-only \u2014 delete refused")}}}a(Iie,"nodeLocalFilesPort");function xie(n){let e=new ht(n),t=new Si.SpaceSpecAccumulator;for(let r of e.getAllFiles()){let i=e.getFrontmatter(r);if(!i)continue;let s=(0,Si.classifySpaceDeclaration)(i,r.path);if(s.kind==="not-space"||(s.warning!==void 0&&t.warnings.push(s.warning),s.kind==="skip"))continue;let o=t.offer(s.candidate);o!==null&&(0,Fo.existsSync)(_i.join(n,o.localPath))&&t.commit(s.candidate)}return{specs:t.specs,warnings:t.warnings}}a(xie,"collectVaultSpecs");function Rie(n,e){for(let t of n.repos){let r=t.headSha!==void 0?` @${t.headSha.slice(0,7)}`:"";e(`${t.repoKey}${r}: ${t.status} \u2014 ${t.inParity}/${t.filesChecked} in parity, M2 diffs ${t.m2SemanticDiffs}, accounted ${t.accountedCount}, M1 violations ${t.m1Violations.length}${t.attachmentHashSetIdentical!==void 0?`, attachment hash-set ${t.attachmentHashSetIdentical?"identical":"DIFFERS"}`:""}`),t.detail!==void 0&&e(` ${t.detail}`);for(let i of t.warnings)e(` warn: ${i}`);for(let i of t.discrepancies)e(` ${i.cls}: ${i.path}${i.detail!==void 0?` (${i.detail})`:""}`);for(let i of t.m1Violations)e(` M1 VIOLATION: ${i.path} \u2014 ${i.detail}`)}e((0,Si.summarizeParityRound)(n))}a(Rie,"printHumanReport");async function Cie(n,e={}){let t=e.out??(g=>console.log(g)),r=_i.resolve(n.vault);if(!(0,Fo.existsSync)(r))throw new Error(`Vault path does not exist: ${r}`);let i=Aie(n,e),s=new Do({token:i,...n.apiBase!==void 0?{apiBase:n.apiBase}:{}}),o=e.transportFactory?.(i,n.apiBase)??s.transport(),{specs:c,warnings:l}=xie(r);for(let g of l)t(`warn: ${g}`);if(c.length===0)return t("Nothing to check \u2014 no materialized AssetSpaces with a GitHub source found in this vault."),2;let u=n.configDir??".obsidian",f=_i.join(r,u,"plugins","exocortex",Si.WATERMARK_STORE_FILENAME),d=new Si.FileWatermarkStore({read:a(async()=>{try{return await Fo.promises.readFile(f,"utf-8")}catch{return null}},"read"),writeAtomic:a(async()=>{throw new Error("exosync-parity: watermark access is read-only by contract")},"writeAtomic")}),h=new Si.ParityValidator({transport:o,sha1:vie,localFilesFor:a(g=>Iie(_i.join(r,g.localPath)),"localFilesFor"),watermarks:{get:a(g=>d.get(g),"get")},yaml:Tie,redact:a(g=>s.redact(g),"redact"),...n.apiBase!==void 0?{baseURL:n.apiBase}:{}});t(`ExoSync parity check: ${c.length} repo(s), vault ${r}`);let p=await h.runRound(c,{trigger:"standalone"});return n.json===!0?t(JSON.stringify(p,null,2)):Rie(p,t),p.vacuous?2:p.ok?0:1}a(Cie,"runExosyncParity");function m4(){return new Re("exosync-parity").description("ExoSync M1/M2 parity report: compare materialized sync units against their remote heads (read-only; RFC 4e4dc453 Phase E)").requiredOption("--vault <path>","Vault root path").option("--config-dir <name>","Obsidian config dir name (watermark location)",".obsidian").option("--json","Print the full round record as JSON").option("--token <pat>","GitHub PAT (or env GITHUB_TOKEN / GH_TOKEN). Prefer --token-from-gh.").option("--token-from-gh","Resolve the PAT via `gh auth token`").option("--api-base <url>","GitHub API base (testing)").action(async n=>{try{process.exitCode=await Cie(n)}catch(e){be.handle(e,{command:"exosync-parity"}),process.exitCode=1}})}a(m4,"exosyncParityCommand");function g4(n){let e=new Re;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.88.0"),e.addCommand(xM()),e.addCommand(MM()),e.addCommand(wk()),e.addCommand(Tk()),e.addCommand(Zk()),e.addCommand(Rk()),e.addCommand(Ck()),e.addCommand(Lk()),e.addCommand(rM()),e.addCommand(lM()),e.addCommand(fM()),e.addCommand(gM()),e.addCommand(IM()),e.addCommand(JM()),e.addCommand(s4()),e.addCommand(o4()),e.addCommand(c4()),e.addCommand(h4()),e.addCommand(m4()),e}a(g4,"createProgram");g4().parse();0&&(module.exports={createProgram});
776
+ `)),process.exit(0)}catch(e){let t=e instanceof Error?e:new Error(String(e)),r=new Do;t.message=r.redact(t.message),t.stack&&(t.stack=r.redact(t.stack)),be.handle(t)}})}a(Eie,"restPushCommand");var Fo=require("node:fs"),p4=require("node:crypto"),_i=re(require("node:path"));var Si=re(it());var vie=a(async n=>{let e=await p4.webcrypto.subtle.digest("SHA-1",n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")},"nodeSha1"),Tie={parse:a(n=>Br.load(n,{schema:Br.CORE_SCHEMA}),"parse"),stringify:a(n=>Br.dump(n,{schema:Br.CORE_SCHEMA,lineWidth:-1}),"stringify")};function Aie(n,e){if(n.tokenFromGh===!0)return Do.resolveGhToken(e.ghTokenRunner);let t=e.env??process.env,r=n.token||t.GITHUB_TOKEN||t.GH_TOKEN||"";if(r.length===0)throw new Error("A GitHub token is required (private sync units read as 404 without one). Use --token-from-gh, --token <pat>, or set GITHUB_TOKEN / GH_TOKEN.");return r}a(Aie,"resolveToken");function Iie(n){let e=a(r=>_i.join(n,r),"abs"),t=a(async(r,i)=>{let s;try{s=await Fo.promises.readdir(r,{withFileTypes:!0})}catch{return}for(let o of s){let c=_i.join(r,o.name);if(o.isDirectory()){if(o.name===".git")continue;await t(c,i)}else o.isFile()&&i.push(_i.relative(n,c).split(_i.sep).join("/"))}},"walk");return{async list(){let r=[];return(0,Fo.existsSync)(n)&&await t(n,r),r},read:a(r=>Fo.promises.readFile(e(r),"utf-8"),"read"),async readBinary(r){return new Uint8Array(await Fo.promises.readFile(e(r)))},async write(){throw new Error("exosync-parity is read-only \u2014 write refused")},async delete(){throw new Error("exosync-parity is read-only \u2014 delete refused")}}}a(Iie,"nodeLocalFilesPort");function xie(n){let e=new ht(n),t=new Si.SpaceSpecAccumulator;for(let r of e.getAllFiles()){let i=e.getFrontmatter(r);if(!i)continue;let s=(0,Si.classifySpaceDeclaration)(i,r.path);if(s.kind==="not-space"||(s.warning!==void 0&&t.warnings.push(s.warning),s.kind==="skip"))continue;let o=t.offer(s.candidate);o!==null&&(0,Fo.existsSync)(_i.join(n,o.localPath))&&t.commit(s.candidate)}return{specs:t.specs,warnings:t.warnings}}a(xie,"collectVaultSpecs");function Rie(n,e){for(let t of n.repos){let r=t.headSha!==void 0?` @${t.headSha.slice(0,7)}`:"";e(`${t.repoKey}${r}: ${t.status} \u2014 ${t.inParity}/${t.filesChecked} in parity, M2 diffs ${t.m2SemanticDiffs}, accounted ${t.accountedCount}, M1 violations ${t.m1Violations.length}${t.attachmentHashSetIdentical!==void 0?`, attachment hash-set ${t.attachmentHashSetIdentical?"identical":"DIFFERS"}`:""}`),t.detail!==void 0&&e(` ${t.detail}`);for(let i of t.warnings)e(` warn: ${i}`);for(let i of t.discrepancies)e(` ${i.cls}: ${i.path}${i.detail!==void 0?` (${i.detail})`:""}`);for(let i of t.m1Violations)e(` M1 VIOLATION: ${i.path} \u2014 ${i.detail}`)}e((0,Si.summarizeParityRound)(n))}a(Rie,"printHumanReport");async function Cie(n,e={}){let t=e.out??(g=>console.log(g)),r=_i.resolve(n.vault);if(!(0,Fo.existsSync)(r))throw new Error(`Vault path does not exist: ${r}`);let i=Aie(n,e),s=new Do({token:i,...n.apiBase!==void 0?{apiBase:n.apiBase}:{}}),o=e.transportFactory?.(i,n.apiBase)??s.transport(),{specs:c,warnings:l}=xie(r);for(let g of l)t(`warn: ${g}`);if(c.length===0)return t("Nothing to check \u2014 no materialized AssetSpaces with a GitHub source found in this vault."),2;let u=n.configDir??".obsidian",f=_i.join(r,u,"plugins","exocortex",Si.WATERMARK_STORE_FILENAME),d=new Si.FileWatermarkStore({read:a(async()=>{try{return await Fo.promises.readFile(f,"utf-8")}catch{return null}},"read"),writeAtomic:a(async()=>{throw new Error("exosync-parity: watermark access is read-only by contract")},"writeAtomic")}),h=new Si.ParityValidator({transport:o,sha1:vie,localFilesFor:a(g=>Iie(_i.join(r,g.localPath)),"localFilesFor"),watermarks:{get:a(g=>d.get(g),"get")},yaml:Tie,redact:a(g=>s.redact(g),"redact"),...n.apiBase!==void 0?{baseURL:n.apiBase}:{}});t(`ExoSync parity check: ${c.length} repo(s), vault ${r}`);let p=await h.runRound(c,{trigger:"standalone"});return n.json===!0?t(JSON.stringify(p,null,2)):Rie(p,t),p.vacuous?2:p.ok?0:1}a(Cie,"runExosyncParity");function m4(){return new Re("exosync-parity").description("ExoSync M1/M2 parity report: compare materialized sync units against their remote heads (read-only; RFC 4e4dc453 Phase E)").requiredOption("--vault <path>","Vault root path").option("--config-dir <name>","Obsidian config dir name (watermark location)",".obsidian").option("--json","Print the full round record as JSON").option("--token <pat>","GitHub PAT (or env GITHUB_TOKEN / GH_TOKEN). Prefer --token-from-gh.").option("--token-from-gh","Resolve the PAT via `gh auth token`").option("--api-base <url>","GitHub API base (testing)").action(async n=>{try{process.exitCode=await Cie(n)}catch(e){be.handle(e,{command:"exosync-parity"}),process.exitCode=1}})}a(m4,"exosyncParityCommand");function g4(n){let e=new Re;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.88.1"),e.addCommand(xM()),e.addCommand(MM()),e.addCommand(wk()),e.addCommand(Tk()),e.addCommand(Zk()),e.addCommand(Rk()),e.addCommand(Ck()),e.addCommand(Lk()),e.addCommand(rM()),e.addCommand(lM()),e.addCommand(fM()),e.addCommand(gM()),e.addCommand(IM()),e.addCommand(JM()),e.addCommand(s4()),e.addCommand(o4()),e.addCommand(c4()),e.addCommand(h4()),e.addCommand(m4()),e}a(g4,"createProgram");g4().parse();0&&(module.exports={createProgram});
777
777
  /*! Bundled license information:
778
778
 
779
779
  reflect-metadata/Reflect.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitelev/exocortex-cli",
3
- "version": "16.88.0",
3
+ "version": "16.88.1",
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": {