@kitelev/exocortex-cli 17.6.2 → 17.7.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 +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 v17.6.2
2
+ // @kitelev/exocortex-cli v17.7.0
3
3
  // CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
4
4
  // License: MIT
5
5
 
@@ -552,7 +552,7 @@ Available prefixes: ${u}`,this.wellKnownPrefixes[n]&&c.push(`Add: PREFIX ${n}: <
552
552
  `)}formatForJSON(e){return{type:e.type,message:e.message,originalMessage:e.originalMessage,suggestions:e.suggestions,line:e.line,column:e.column,context:e.context?{startLine:e.context.startLine,endLine:e.context.endLine,errorLine:e.context.errorLine,errorColumn:e.context.errorColumn,lines:e.context.lines.map(t=>({number:t.number,content:t.content,isError:t.isError}))}:void 0}}};var fE=class r{static{a(this,"NTriplesFormatter")}static escapeString(e){let t=e.replace(/\\/g,"\\\\");return t=t.replace(/"/g,'\\"'),t=t.replace(/\n/g,"\\n"),t=t.replace(/\r/g,"\\r"),t=t.replace(/\t/g,"\\t"),t}static formatObject(e){return e.startsWith("http://")||e.startsWith("https://")||e.startsWith("urn:")?`<${e}>`:`"${r.escapeString(e)}"`}};var Lu=require("fs"),qP=require("path");function dE(r){let e=new Map,t="obsidian://vault/",n;try{n=(0,Lu.readdirSync)(r)}catch{return e}for(let i of n){let s=(0,qP.join)(r,i);if(i.startsWith("."))continue;let o;try{o=(0,Lu.statSync)(s)}catch{continue}if(!o.isDirectory())continue;let c;try{c=(0,Lu.readdirSync)(s)}catch{continue}for(let l of c){let u=(0,qP.join)(s,l);if(l.startsWith("."))continue;let f;try{f=(0,Lu.statSync)(u)}catch{continue}if(!f.isDirectory())continue;let d=!1;try{d=(0,Lu.readdirSync)(u).some(h=>h.endsWith(".md"))}catch{continue}if(d){let p=`${i}/${l}`,h=encodeURI(p),g=`${t}${h}/`;/^[a-zA-Z][a-zA-Z0-9_]*$/.test(l)&&e.set(l,g)}}}return e}a(dE,"scanVaultNamespaces");mE();var rbe=300,m7=3e4,nbe="EXOCORTEX_SPARQL_TIMEOUT";function ibe(){let r=process.env[nbe];if(!r)return m7;try{let e=sbe(r);if(e!==null&&e>0)return e}catch{}return m7}a(ibe,"getDefaultTimeout");function sbe(r){let e=r.trim().toLowerCase();if(!e)return null;if(e.endsWith("ms")){let n=parseInt(e.slice(0,-2),10);return isNaN(n)||n<=0?null:n}if(e.endsWith("s")){let n=parseInt(e.slice(0,-1),10);return isNaN(n)||n<=0?null:n*1e3}let t=parseInt(e,10);return isNaN(t)||t<=0?null:t*1e3}a(sbe,"parseTimeoutSafe");function obe(r){if(!r)return rbe;let e=parseInt(r.trim(),10);if(isNaN(e)||e<=0)throw new Ye(`Invalid cache TTL: "${r}". Must be a positive number (seconds).`,'exocortex query --cache-ttl 600 "SELECT * WHERE { ?s ?p ?o }"');return e}a(obe,"parseCacheTtl");function abe(r){let e=r.trim().toLowerCase();if(e.endsWith("ms")){let n=parseInt(e.slice(0,-2),10);if(isNaN(n)||n<=0)throw new Ye(`Invalid timeout format: "${r}". Value must be a positive number.`,'exocortex query --timeout "30s" or --timeout "5000ms"');return n}if(e.endsWith("s")){let n=parseInt(e.slice(0,-1),10);if(isNaN(n)||n<=0)throw new Ye(`Invalid timeout format: "${r}". Value must be a positive number.`,'exocortex query --timeout "30s" or --timeout "5000ms"');return n*1e3}let t=parseInt(e,10);if(isNaN(t)||t<=0)throw new Ye(`Invalid timeout format: "${r}". Use formats like "30s", "5000ms", or just a number (seconds).`,'exocortex query --timeout "30s" or --timeout "5000ms"');return t*1e3}a(abe,"parseTimeout");async function WP(r,e,t=Date.now()){let n,i=new Promise((s,o)=>{n=setTimeout(()=>{let c=Date.now()-t;o(new km(e,c))},e),n&&typeof n=="object"&&"unref"in n&&n.unref()});return Promise.race([r,i])}a(WP,"executeWithTimeout");function y7(){return new de("query").description("Execute SPARQL query against Obsidian vault").argument("[query]","SPARQL query string or path to .sparql file (optional if --template is used)").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--format <type>","Output format: table|json|csv|ntriples","table").option("--output <type>","Response format: text|json (for MCP tools)","text").option("--timeout <duration>","Query timeout (e.g., 30s, 5000ms)","30s").option("--dry-run","Validate query syntax without executing (no vault loading)").option("--explain","Show optimized query plan").option("--stats","Show execution statistics").option("--no-optimize","Disable query optimization").option("--use-cache","Use persistent triple cache (faster vault loading)").option("--cache-ttl <seconds>","Query result cache TTL in seconds (default: 300)").option("--no-cache","Bypass query result cache").option("--template <name>","Use a predefined query template").option("--param <params>","Template parameters (format: key=value,key2=value2)").option("--strict","Fail on unresolved label-form wikilinks in property paths (sets EXOCORTEX_SPARQL_STRICT=1, Issue #3282)").action(async(r,e)=>{let t=e.output||"text";le.setFormat(t);let n=process.env.EXOCORTEX_SPARQL_STRICT;e.strict&&(process.env.EXOCORTEX_SPARQL_STRICT="1");let i="";try{let s=Date.now(),o=e.timeout?abe(e.timeout):ibe(),c=obe(e.cacheTtl),l=e.cache!==!1;if(e.template){let B=new cE,M=e.param?B.parseParamString(e.param):{};if(i=B.applyTemplate(e.template,M),t==="text"){let ie=B.getTemplate(e.template);console.log(`\u{1F4CB} Using template: ${e.template}`),Object.keys(M).length>0&&console.log(` Parameters: ${Object.entries(M).map(([Z,te])=>`${Z}=${te}`).join(", ")}`),console.log()}}else if(r)i=cbe(r);else throw new Ye("Either a query argument or --template flag is required.",'exocortex query "SELECT * WHERE { ?s ?p ?o }" or exocortex query --template tasks-by-date --param date=2024-01-15');let u=i;if(e.dryRun){await lbe(i,e,t);return}let f=(0,zP.resolve)(e.vault),d=l?await U8(f):null;if(l){let M=await new Ha().get(u,c,d);if(M!==null){let ie=Date.now()-s;if(t==="json"){let Z=pt.success(M,{durationMs:ie,itemCount:M.count||0,queryResultCacheHit:!0});console.log(JSON.stringify(Z,null,2))}else{console.log(`\u{1F4E6} (cached) Query result loaded from cache in ${ie}ms
553
553
  `);let Z=M;Z.type==="select"&&Z.bindings?(console.log(`\u2705 Found ${Z.bindings.length} result(s)
554
554
  `),dbe(Z.bindings,e.format)):Z.type==="construct"&&Z.triples&&(console.log(`\u2705 Generated ${Z.triples.length} triple(s)
555
- `),pbe(Z.triples,e.format))}return}}if(!(0,xg.existsSync)(f))throw new Fe(f);t==="text"&&console.log(`\u{1F4E6} Loading vault: ${f}...`);let p=Date.now(),h=e.useCache??!1,g=[],m=!1,b=await yi(f,{useCache:h});g=b.triples,m=b.cacheHit;let _=Ou(b);_!==null&&console.error(_);let S=b.skippedFiles&&b.skippedFiles.length>0?{skippedCount:b.skippedFiles.length,skippedFiles:b.skippedFiles}:{};t==="text"&&m&&console.log(b.mode==="delta"?`\u267B\uFE0F Cache refreshed incrementally (${b.reparsedFiles} file(s) re-parsed)...`:"\u{1F680} Cache hit! Loading from persistent cache...");let A=new Hr.InMemoryTripleStore;await A.addAll(g);let w=Date.now()-p;if(t==="text"){let B=m?" (from cache)":"";console.log(`\u2705 Loaded ${g.length} triples in ${w}ms${B}
555
+ `),pbe(Z.triples,e.format))}return}}if(!(0,xg.existsSync)(f))throw new Fe(f);t==="text"&&console.log(`\u{1F4E6} Loading vault: ${f}...`);let p=Date.now(),h=e.useCache??!1,g=[],m=!1,b=await yi(f,{useCache:h});g=b.triples,m=b.cacheHit;let _=Ou(b);_!==null&&console.error(_);let S=b.skippedFiles?b.skippedFiles.length===0?{}:{skippedCount:b.skippedFiles.length,skippedFiles:b.skippedFiles,skippedFilesAvailable:!0}:b.zeroTriplePaths.length===0?{}:{zeroTripleCount:b.zeroTriplePaths.length,skippedFilesAvailable:!1};t==="text"&&m&&console.log(b.mode==="delta"?`\u267B\uFE0F Cache refreshed incrementally (${b.reparsedFiles} file(s) re-parsed)...`:"\u{1F680} Cache hit! Loading from persistent cache...");let A=new Hr.InMemoryTripleStore;await A.addAll(g);let w=Date.now()-p;if(t==="text"){let B=m?" (from cache)":"";console.log(`\u2705 Loaded ${g.length} triples in ${w}ms${B}
556
556
  `),console.log("\u{1F50D} Parsing SPARQL query...")}let E=new Hr.ExoQLParser;i=pE(i),i=dp(i);let R=hE(dE(f));R.size>0&&E.setVaultPrefixes(R);let x=E.parse(i);if(x.type==="update"){t==="text"&&console.log("\u{1F504} Executing SPARQL UPDATE...");let B=Date.now(),M=new Hr.UpdateExecutor(A),ie=await WP(M.execute(x),o,B),Z=Date.now()-B,te=Date.now()-s;if(t==="json"){let V=pt.success({query:i,type:"update",results:ie},{durationMs:te,itemCount:ie.length,loadDurationMs:w,execDurationMs:Z,triplesScanned:g.length,cacheHit:m,...S});console.log(JSON.stringify(V,null,2))}else mbe(ie,e.format),console.log(),console.log("\u26A0\uFE0F Changes applied to in-memory store only (not persisted to vault files)"),e.stats&&(console.log(`
557
557
  \u{1F4CA} Execution Statistics:`),console.log(` Vault loading: ${w}ms${m?" (from cache)":""}`),console.log(` Query execution: ${Z}ms`),console.log(` Total time: ${te}ms`),console.log(` Triples scanned: ${g.length}`));return}t==="text"&&console.log("\u{1F504} Translating to algebra...");let N=new Hr.ExoQLAlgebraTranslator().translate(x);if(!e.noOptimize&&N.type!=="construct")N=new Hr.AlgebraOptimizer().optimize(N);else if(!e.noOptimize&&N.type==="construct"){let B=new Hr.AlgebraOptimizer,M=N;N={...M,where:B.optimize(M.where)}}if(e.explain&&t==="text"){console.log("\u{1F4CA} Query Plan:");let B=new Hr.AlgebraSerializer;if(N.type==="construct"){let M=N;console.log("CONSTRUCT Template:"),console.log(" (template patterns)"),console.log("WHERE:"),console.log(B.toString(M.where))}else console.log(B.toString(N));console.log()}let $=Date.now(),k=new Hr.ExoQLQueryExecutor(A),G=t==="text"?new sE("Executing query",{delayMs:2e3}):null;if(k.isConstructQuery(N)){G?.start();let B=await WP(k.executeConstruct(N),o,$),M=Date.now()-$;G?.stop();let ie=Date.now()-s;if(l){let Z=new jd,te={type:"construct",count:B.length,triples:JSON.parse(Z.formatJson(B))};await new Ha().set(u,te,c,d)}if(t==="json"){let Z=new jd,te={query:i,count:B.length,triples:JSON.parse(Z.formatJson(B))},V=pt.success(te,{durationMs:ie,itemCount:B.length,loadDurationMs:w,execDurationMs:M,triplesScanned:g.length,cacheHit:m,queryResultCacheHit:!1,...S});console.log(JSON.stringify(V,null,2))}else console.log(`\u2705 Generated ${B.length} triple(s) in ${M}ms
558
558
  `),B.length>0?fbe(B,e.format):console.log("No triples generated."),e.stats&&(console.log(`
@@ -713,7 +713,7 @@ Next steps:
713
713
  `).map(n=>n.trim()).filter(n=>n.length>0),t=e[e.length-1];if(t!==void 0)try{return JSON.parse(t)}catch{return}}a(REe,"parseLastJsonLine");function lq(r,e){return e.filter(t=>{let n=r[t];return typeof n!="string"||n.trim().length===0})}a(lq,"missingStringFields");var hv=class{constructor(e){this.deps=e}static{a(this,"McpServer")}async handle(e){if(typeof e!="object"||e===null||Array.isArray(e))return{jsonrpc:"2.0",id:null,error:{code:cq,message:"Invalid request: expected a JSON-RPC object"}};let t=e.id,n=t===void 0;if(typeof e.method!="string")return n?null:{jsonrpc:"2.0",id:t??null,error:{code:cq,message:"Invalid request: missing method"}};if(n)return null;let i=t??null;switch(e.method){case"initialize":return{jsonrpc:"2.0",id:i,result:{protocolVersion:AEe,capabilities:{tools:{}},serverInfo:{name:"exocortex",version:this.deps.version}}};case"ping":return{jsonrpc:"2.0",id:i,result:{}};case"tools/list":return{jsonrpc:"2.0",id:i,result:{tools:aq}};case"tools/call":return{jsonrpc:"2.0",id:i,result:await this.callTool(e.params??{})};default:return{jsonrpc:"2.0",id:i,error:{code:IEe,message:`Method not found: ${e.method}`}}}}async callTool(e){let t=e.name,n=e.arguments??{},i;if(t==="create_asset"){let c=lq(n,["vault","class","label"]);if(c.length>0)return Dp(`create_asset: missing required argument(s): ${c.join(", ")}`,!0);let l=iq(n);if(l!==null)return Dp(`create_asset: ${l}`,!0);i=sq(n)}else if(t==="create_effort"){let c=lq(n,["vault","command","target"]);if(c.length>0)return Dp(`create_effort: missing required argument(s): ${c.join(", ")}`,!0);i=oq(n)}else return Dp(`Unknown tool: ${String(t)}`,!0);let s=await this.deps.runCli(i);if(s.exitCode!==0){let c=s.stderr.trim()||s.stdout.trim()||"(no diagnostic output)";return Dp(`exocortex-cli exited ${s.exitCode}
714
714
  ${c}`,!0)}let o=REe(s.stdout);return Dp(o===void 0?s.stdout.trim():JSON.stringify(o))}};var dq=require("child_process");var CEe=32*1024*1024;function pq(r){return e=>new Promise(t=>{(0,dq.execFile)(process.execPath,[r,...e],{maxBuffer:CEe},(n,i,s)=>{let o=0;if(n){let c=n.code;o=typeof c=="number"?c:1}t({stdout:i,stderr:s,exitCode:o})})})}a(pq,"createSelfCliRunner");async function xEe(r,e,t){let n=(0,hq.createInterface)({input:e,crlfDelay:1/0});for await(let i of n){let s=i.trim();if(s.length===0)continue;let o;try{o=JSON.parse(s)}catch{t(JSON.stringify({jsonrpc:"2.0",id:null,error:{code:uq,message:"Parse error: invalid JSON"}})+`
715
715
  `);continue}let c;try{c=await r.handle(o)}catch(l){c={jsonrpc:"2.0",id:typeof o?.id=="string"||typeof o?.id=="number"?o.id:null,error:{code:fq,message:`Internal error: ${l instanceof Error?l.message:String(l)}`}}}c!==null&&t(JSON.stringify(c)+`
716
- `)}}a(xEe,"runStdioServer");function mq(r){return new de("mcp").description("Run an MCP (Model Context Protocol) stdio server exposing create_asset / create_effort tools backed by this CLI").option("--entry <path>","Path to the CLI entry script the tools invoke (defaults to this process's script)").action(async e=>{let t=e.entry??process.argv[1],n=new hv({runCli:pq(t),version:r??"unknown"});await xEe(n,process.stdin,i=>process.stdout.write(i))})}a(mq,"mcpCommand");function mv(r){let e=new de;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more").version(r??"17.6.2"),e.addCommand(jV()),e.addCommand(KV()),e.addCommand(y7()),e.addCommand(w7()),e.addCommand(V7()),e.addCommand(E7()),e.addCommand(R7()),e.addCommand(C7()),e.addCommand(X7()),e.addCommand(tV()),e.addCommand(SV()),e.addCommand(AV()),e.addCommand(xV()),e.addCommand(OV()),e.addCommand(FV()),e.addCommand(LV()),e.addCommand(NV()),e.addCommand(yG()),e.addCommand(SG()),e.addCommand(zG()),e.addCommand(KG()),e.addCommand(QG()),e.addCommand(JG()),e.addCommand(tq()),e.addCommand(NG()),e.addCommand(GG()),e.addCommand(rq()),e.addCommand(mq(r??"17.6.2")),e}a(mv,"createProgram");mv().parse();0&&(module.exports={createProgram});
716
+ `)}}a(xEe,"runStdioServer");function mq(r){return new de("mcp").description("Run an MCP (Model Context Protocol) stdio server exposing create_asset / create_effort tools backed by this CLI").option("--entry <path>","Path to the CLI entry script the tools invoke (defaults to this process's script)").action(async e=>{let t=e.entry??process.argv[1],n=new hv({runCli:pq(t),version:r??"unknown"});await xEe(n,process.stdin,i=>process.stdout.write(i))})}a(mq,"mcpCommand");function mv(r){let e=new de;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more").version(r??"17.7.0"),e.addCommand(jV()),e.addCommand(KV()),e.addCommand(y7()),e.addCommand(w7()),e.addCommand(V7()),e.addCommand(E7()),e.addCommand(R7()),e.addCommand(C7()),e.addCommand(X7()),e.addCommand(tV()),e.addCommand(SV()),e.addCommand(AV()),e.addCommand(xV()),e.addCommand(OV()),e.addCommand(FV()),e.addCommand(LV()),e.addCommand(NV()),e.addCommand(yG()),e.addCommand(SG()),e.addCommand(zG()),e.addCommand(KG()),e.addCommand(QG()),e.addCommand(JG()),e.addCommand(tq()),e.addCommand(NG()),e.addCommand(GG()),e.addCommand(rq()),e.addCommand(mq(r??"17.7.0")),e}a(mv,"createProgram");mv().parse();0&&(module.exports={createProgram});
717
717
  /*! Bundled license information:
718
718
 
719
719
  reflect-metadata/Reflect.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitelev/exocortex-cli",
3
- "version": "17.6.2",
3
+ "version": "17.7.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": {