@kitelev/exocortex-cli 15.32.1 → 15.32.2

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 +5 -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 v15.32.1
2
+ // @kitelev/exocortex-cli v15.32.2
3
3
  // CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
4
4
  // License: MIT
5
5
 
@@ -598,10 +598,12 @@ Continue? (y/n): `,s=>{r.close(),i(s.toLowerCase()==="y"||s.toLowerCase()==="yes
598
598
  ORDER BY DESC(?usageCount)
599
599
  `;a=s.parse(p),c=new Xt.AlgebraTranslator,l=c.translate(a),u=new Xt.AlgebraOptimizer,l=u.optimize(l);let b=(await f.executeAll(l)).map(A=>{let C=A.get("property"),M=A.get("usageCount");return{name:C?eI(C.toString()):"unknown",usageCount:M?parseInt(M.toString(),10):0}}),E={name:e,instanceCount:d,properties:b};if(r==="json"||t.format==="json"){let A=_e.success(E);console.log(JSON.stringify(A,null,2))}else{if(console.log(`\u{1F4CB} Class: ${e}
600
600
  `),console.log(` Instances: ${d}`),console.log(` Properties: ${b.length}
601
- `),b.length===0){console.log(" No properties found.");return}let A=Math.max(...b.map(C=>C.name.length),10);console.log(" \u250C"+"\u2500".repeat(A+2)+"\u252C"+"\u2500".repeat(10)+"\u2510"),console.log(" \u2502 "+"Property".padEnd(A)+" \u2502 "+"Usage".padEnd(8)+" \u2502"),console.log(" \u251C"+"\u2500".repeat(A+2)+"\u253C"+"\u2500".repeat(10)+"\u2524");for(let C of b)console.log(" \u2502 "+C.name.padEnd(A)+" \u2502 "+C.usageCount.toString().padStart(8)+" \u2502");console.log(" \u2514"+"\u2500".repeat(A+2)+"\u2534"+"\u2500".repeat(10)+"\u2518")}}o(yU,"showClassDetails");function eI(n){let e=n.replace(/^<|>$/g,""),t=e.lastIndexOf("#");if(t!==-1)return e.substring(t+1);let r=e.lastIndexOf("/");return r!==-1?e.substring(r+1):e}o(eI,"extractLocalName");var rI=require("path"),mv=require("fs"),nI=require("fs");var dv=class extends Error{static{o(this,"ClassNotFoundError")}constructor(e){super(`Class '${e}' not found in vault`),this.name="ClassNotFoundError"}},hp=class{constructor(e){this.fsAdapter=e;this.cache=new Map}static{o(this,"ClassResolverService")}async resolve(e,t){if(this.isUUID(t))return t;let i=(await this.getOrBuildIndex(e)).get(t);if(!i)throw new dv(t);return i}async listClasses(e){let t=await this.getOrBuildIndex(e);return Array.from(t.keys())}async getOrBuildIndex(e){if(this.cache.has(e))return this.cache.get(e);let t=await this.buildIndex(e);return this.cache.set(e,t),t}async buildIndex(e){let t=new Map,r=await this.fsAdapter.getMarkdownFiles();for(let i of r)try{let s=await this.fsAdapter.getFileMetadata(i);if(!this.isClassDefinition(s))continue;let a=s.exo__Asset_uid;if(!a)continue;let c=this.getBasename(i),l=s.exo__Asset_label;c&&t.set(c,String(a)),l&&typeof l=="string"&&l!==c&&t.set(l,String(a))}catch{continue}return t}isClassDefinition(e){let t=e.exo__Instance_class;return t?(Array.isArray(t)?t:[t]).some(i=>String(i).includes("ims__Class")):!1}getBasename(e){let t=e.split("/");return t[t.length-1].replace(/\.md$/,"")}isUUID(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}};var pv=class extends Error{static{o(this,"WikilinkNotFoundError")}constructor(e,t){let r=t?`|${t}`:"";super(`Wikilink [[${e}${r}]] \u2014 file not found in vault`),this.name="WikilinkNotFoundError"}},dp=class{constructor(e){this.fsAdapter=e}static{o(this,"WikilinkValidator")}static{this.WIKILINK_PATTERN=/\[\[([^\]|]+)(?:\|[^\]]*)?]]/g}async validatePropertyValues(e){for(let[,t]of Object.entries(e))await this.validateValue(t)}async validateValue(e){let t=this.extractWikilinks(e);for(let r of t)await this.validateWikilink(r.uuid,r.label)}extractWikilinks(e){let t=[],r=/\[\[([^\]|]+)(?:\|([^\]]*))?\]\]/g,i;for(;(i=r.exec(e))!==null;)t.push({uuid:i[1].trim(),label:i[2]?.trim()});return t}async validateWikilink(e,t){if(!this.looksLikeUUID(e))return;if(!await this.fsAdapter.fileExists(`${e}.md`)&&!await this.fsAdapter.findFileByUID(e))throw new pv(e,t)}looksLikeUUID(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}};var tI=X(ar());var vU="de20a3f1-7483-4714-ab28-b45f5cf02c76",_U="Asia/Almaty",pp=class{constructor(e,t,r){this.fsAdapter=e;this.classResolver=t;this.wikilinkValidator=r}static{o(this,"AssetCreationService")}async create(e){if(!e.label||e.label.trim().length===0)throw new Error("Label cannot be empty");let t=e.label.trim(),r=await this.classResolver.resolve(e.vault,e.classShortName);e.properties&&!e.skipWikilinkValidation&&await this.wikilinkValidator.validatePropertyValues(e.properties);let i=ru(),s=this.generateTimestamp(e.timezone),a=this.buildFrontmatter({assetUuid:i,classShortName:e.classShortName,classUuid:r,label:t,aliases:e.aliases,properties:e.properties,createdBy:e.createdBy||vU,timestamp:s}),c=tI.MetadataHelpers.buildFileContent(a,e.body),l=`01 Inbox/${i}.md`;return e.dryRun||await this.fsAdapter.createFile(l,c),{uuid:i,path:l,label:t,frontmatter:a}}buildFrontmatter(e){let t={};t.exo__Asset_uid=e.assetUuid,t.exo__Asset_label=e.label,t.exo__Asset_createdAt=e.timestamp,t.exo__Asset_createdBy=`"[[${e.createdBy}]]"`,t.exo__Instance_class=[`"[[${e.classShortName}]]"`];let r=[e.label];if(e.aliases&&e.aliases.length>0)for(let i of e.aliases)r.includes(i)||r.push(i);if(t.aliases=r,e.properties)for(let[i,s]of Object.entries(e.properties))i==="exo__Asset_uid"||i==="exo__Asset_label"||i==="exo__Asset_createdAt"||i==="exo__Asset_createdBy"||i==="exo__Instance_class"||i==="aliases"||(t[i]=s);return t}generateTimestamp(e){let t=e||_U,r=new Date,s=new Intl.DateTimeFormat("en-CA",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).formatToParts(r),a=o(c=>s.find(l=>l.type===c)?.value||"00","get");return`${a("year")}-${a("month")}-${a("day")}T${a("hour")}:${a("minute")}:${a("second")}`}};function bU(n){if(!n||n.length===0)return{};let e={};for(let t of n){let r=t.indexOf("=");if(r===-1)throw new Error(`Invalid property format: "${t}". Expected "key=value" format.`);let i=t.substring(0,r).trim(),s=t.substring(r+1).trim();if(!i)throw new Error(`Invalid property format: "${t}". Key cannot be empty.`);e[i]=s}return e}o(bU,"parseProperties");async function SU(n){if(n.bodyFile){if(!(0,mv.existsSync)(n.bodyFile))throw new Error(`Body file not found: ${n.bodyFile}`);return(0,nI.readFileSync)(n.bodyFile,"utf-8")}if(n.body==="-")return wU(3e4);if(n.body)return n.body}o(SU,"resolveBody");function wU(n){return new Promise((e,t)=>{let r=[],i=setTimeout(()=>{process.stdin.removeAllListeners(),process.stdin.destroy(),t(new Error(`Stdin read timed out after ${n}ms. Ensure you pipe content to stdin or close the pipe.`))},n);process.stdin.on("data",s=>{r.push(s)}),process.stdin.on("end",()=>{clearTimeout(i),e(Buffer.concat(r).toString("utf-8"))}),process.stdin.on("error",s=>{clearTimeout(i),t(s)}),process.stdin.isTTY&&(clearTimeout(i),e("")),process.stdin.resume()})}o(wU,"readStdin");function iI(){return new st("create").description("Create a new vault asset with auto-generated UUID, timestamp, and frontmatter").requiredOption("--class <name>","Class short name (e.g. ztlk__PermanentNote) or UUID").requiredOption("--label <text>","Human-readable label for the asset").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--aliases <names...>","Additional aliases for the asset").option("--property <key=value...>","Property key-value pairs (repeatable)",EU,[]).option("--body <text>","Markdown body content (use '-' to read from stdin)").option("--body-file <path>","Read body content from file").option("--dry-run","Preview frontmatter without writing file").option("--created-by <uuid>","Creator UUID (defaults to ExoAssistant)").option("--timezone <tz>","Timezone for timestamps (defaults to Asia/Almaty)").option("--skip-wikilink-validation","Skip wikilink existence validation").action(async n=>{try{let e=(0,rI.resolve)(n.vault);if(!(0,mv.existsSync)(e))throw new yt(e);let t=bU(n.property),r=await SU(n),i=new Mi(e),s=new hp(i),a=new dp(i),l=await new pp(i,s,a).create({classShortName:n.class,label:n.label,aliases:n.aliases,properties:Object.keys(t).length>0?t:void 0,body:r,vault:e,dryRun:n.dryRun,createdBy:n.createdBy,timezone:n.timezone,skipWikilinkValidation:n.skipWikilinkValidation});if(n.dryRun){let f=TU(l.frontmatter,r);process.stderr.write(f+`
601
+ `),b.length===0){console.log(" No properties found.");return}let A=Math.max(...b.map(C=>C.name.length),10);console.log(" \u250C"+"\u2500".repeat(A+2)+"\u252C"+"\u2500".repeat(10)+"\u2510"),console.log(" \u2502 "+"Property".padEnd(A)+" \u2502 "+"Usage".padEnd(8)+" \u2502"),console.log(" \u251C"+"\u2500".repeat(A+2)+"\u253C"+"\u2500".repeat(10)+"\u2524");for(let C of b)console.log(" \u2502 "+C.name.padEnd(A)+" \u2502 "+C.usageCount.toString().padStart(8)+" \u2502");console.log(" \u2514"+"\u2500".repeat(A+2)+"\u2534"+"\u2500".repeat(10)+"\u2518")}}o(yU,"showClassDetails");function eI(n){let e=n.replace(/^<|>$/g,""),t=e.lastIndexOf("#");if(t!==-1)return e.substring(t+1);let r=e.lastIndexOf("/");return r!==-1?e.substring(r+1):e}o(eI,"extractLocalName");var rI=require("path"),mv=require("fs"),nI=require("fs");var dv=class extends Error{static{o(this,"ClassNotFoundError")}constructor(e,t){let r=`Class '${e}' not found in vault`;t&&t.length>0&&(r+=`
602
+ Available classes: ${t.join(", ")}`),super(r),this.name="ClassNotFoundError"}},hp=class{constructor(e){this.fsAdapter=e;this.cache=new Map}static{o(this,"ClassResolverService")}async resolve(e,t){if(this.isUUID(t))return t;let r=await this.getOrBuildIndex(e),i=r.get(t);if(!i){let s=Array.from(r.keys()).filter(a=>!this.isUUID(a));throw new dv(t,s)}return i}async listClasses(e){let t=await this.getOrBuildIndex(e);return Array.from(t.keys())}async getOrBuildIndex(e){if(this.cache.has(e))return this.cache.get(e);let t=await this.buildIndex(e);return this.cache.set(e,t),t}async buildIndex(e){let t=new Map,r=await this.fsAdapter.getMarkdownFiles();for(let i of r)try{let s=await this.fsAdapter.getFileMetadata(i);if(!this.isClassDefinition(s))continue;let a=this.getBasename(i),c=s.exo__Asset_uid;if(!c&&this.isUUID(a)&&(c=a),!c)continue;let l=String(c);a&&t.set(a,l);let u=s.exo__Asset_label;u&&typeof u=="string"&&u!==a&&t.set(u,l)}catch{continue}return t}isClassDefinition(e){let t=e.exo__Instance_class;return t?(Array.isArray(t)?t:[t]).some(i=>{let s=String(i);return s.includes("ims__Class")||s.includes("exo__Class")}):!1}getBasename(e){let t=e.split("/");return t[t.length-1].replace(/\.md$/,"")}isUUID(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}};var pv=class extends Error{static{o(this,"WikilinkNotFoundError")}constructor(e,t){let r=t?`|${t}`:"";super(`Wikilink [[${e}${r}]] \u2014 file not found in vault`),this.name="WikilinkNotFoundError"}},dp=class{constructor(e){this.fsAdapter=e}static{o(this,"WikilinkValidator")}static{this.WIKILINK_PATTERN=/\[\[([^\]|]+)(?:\|[^\]]*)?]]/g}async validatePropertyValues(e){for(let[,t]of Object.entries(e))await this.validateValue(t)}async validateValue(e){let t=this.extractWikilinks(e);for(let r of t)await this.validateWikilink(r.uuid,r.label)}extractWikilinks(e){let t=[],r=/\[\[([^\]|]+)(?:\|([^\]]*))?\]\]/g,i;for(;(i=r.exec(e))!==null;)t.push({uuid:i[1].trim(),label:i[2]?.trim()});return t}async validateWikilink(e,t){if(!this.looksLikeUUID(e))return;if(!await this.fsAdapter.fileExists(`${e}.md`)&&!await this.fsAdapter.findFileByUID(e))throw new pv(e,t)}looksLikeUUID(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}};var tI=X(ar());var vU="de20a3f1-7483-4714-ab28-b45f5cf02c76",_U="Asia/Almaty",pp=class{constructor(e,t,r){this.fsAdapter=e;this.classResolver=t;this.wikilinkValidator=r}static{o(this,"AssetCreationService")}async create(e){if(!e.label||e.label.trim().length===0)throw new Error("Label cannot be empty");let t=e.label.trim(),r=await this.classResolver.resolve(e.vault,e.classShortName);e.properties&&!e.skipWikilinkValidation&&await this.wikilinkValidator.validatePropertyValues(e.properties);let i=ru(),s=this.generateTimestamp(e.timezone),a=this.buildFrontmatter({assetUuid:i,classShortName:e.classShortName,classUuid:r,label:t,aliases:e.aliases,properties:e.properties,createdBy:e.createdBy||vU,timestamp:s}),c=tI.MetadataHelpers.buildFileContent(a,e.body),l=`01 Inbox/${i}.md`;return e.dryRun||await this.fsAdapter.createFile(l,c),{uuid:i,path:l,label:t,frontmatter:a}}buildFrontmatter(e){let t={};t.exo__Asset_uid=e.assetUuid,t.exo__Asset_label=e.label,t.exo__Asset_createdAt=e.timestamp,t.exo__Asset_createdBy=`"[[${e.createdBy}]]"`,t.exo__Instance_class=[`"[[${e.classUuid}|${e.classShortName}]]"`];let r=[e.label];if(e.aliases&&e.aliases.length>0)for(let i of e.aliases)r.includes(i)||r.push(i);if(t.aliases=r,e.properties)for(let[i,s]of Object.entries(e.properties))i==="exo__Asset_uid"||i==="exo__Asset_label"||i==="exo__Asset_createdAt"||i==="exo__Asset_createdBy"||i==="exo__Instance_class"||i==="aliases"||(t[i]=s);return t}generateTimestamp(e){let t=e||_U,r=new Date,s=new Intl.DateTimeFormat("en-CA",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).formatToParts(r),a=o(c=>s.find(l=>l.type===c)?.value||"00","get");return`${a("year")}-${a("month")}-${a("day")}T${a("hour")}:${a("minute")}:${a("second")}`}};function bU(n){if(!n||n.length===0)return{};let e={};for(let t of n){let r=t.indexOf("=");if(r===-1)throw new Error(`Invalid property format: "${t}". Expected "key=value" format.`);let i=t.substring(0,r).trim(),s=t.substring(r+1).trim();if(!i)throw new Error(`Invalid property format: "${t}". Key cannot be empty.`);e[i]=s}return e}o(bU,"parseProperties");async function SU(n){if(n.bodyFile){if(!(0,mv.existsSync)(n.bodyFile))throw new Error(`Body file not found: ${n.bodyFile}`);return(0,nI.readFileSync)(n.bodyFile,"utf-8")}if(n.body==="-")return wU(3e4);if(n.body)return n.body}o(SU,"resolveBody");function wU(n){return new Promise((e,t)=>{let r=[],i=setTimeout(()=>{process.stdin.removeAllListeners(),process.stdin.destroy(),t(new Error(`Stdin read timed out after ${n}ms. Ensure you pipe content to stdin or close the pipe.`))},n);process.stdin.on("data",s=>{r.push(s)}),process.stdin.on("end",()=>{clearTimeout(i),e(Buffer.concat(r).toString("utf-8"))}),process.stdin.on("error",s=>{clearTimeout(i),t(s)}),process.stdin.isTTY&&(clearTimeout(i),e("")),process.stdin.resume()})}o(wU,"readStdin");function iI(){return new st("create").description("Create a new vault asset with auto-generated UUID, timestamp, and frontmatter").requiredOption("--class <name>","Class short name (e.g. ztlk__PermanentNote) or UUID").requiredOption("--label <text>","Human-readable label for the asset").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--aliases <names...>","Additional aliases for the asset").option("--property <key=value...>","Property key-value pairs (repeatable)",EU,[]).option("--body <text>","Markdown body content (use '-' to read from stdin)").option("--body-file <path>","Read body content from file").option("--dry-run","Preview frontmatter without writing file").option("--created-by <uuid>","Creator UUID (defaults to ExoAssistant)").option("--timezone <tz>","Timezone for timestamps (defaults to Asia/Almaty)").option("--skip-wikilink-validation","Skip wikilink existence validation").action(async n=>{try{let e=(0,rI.resolve)(n.vault);if(!(0,mv.existsSync)(e))throw new yt(e);let t=bU(n.property),r=await SU(n);r&&(r=r.replace(/\\n/g,`
603
+ `));let i=new Mi(e),s=new hp(i),a=new dp(i),l=await new pp(i,s,a).create({classShortName:n.class,label:n.label,aliases:n.aliases,properties:Object.keys(t).length>0?t:void 0,body:r,vault:e,dryRun:n.dryRun,createdBy:n.createdBy,timezone:n.timezone,skipWikilinkValidation:n.skipWikilinkValidation});if(n.dryRun){let f=TU(l.frontmatter,r);process.stderr.write(f+`
602
604
  `)}let u={uuid:l.uuid,path:l.path,label:l.label};process.stdout.write(JSON.stringify(u)+`
603
605
  `),process.exit(0)}catch(e){W.handle(e)}})}o(iI,"createCommand");function EU(n,e){return e.concat([n])}o(EU,"collect");function TU(n,e){let t=["--- DRY RUN PREVIEW ---","---"];for(let[r,i]of Object.entries(n))if(Array.isArray(i)){t.push(`${r}:`);for(let s of i)t.push(` - ${s}`)}else t.push(`${r}: ${i}`);return t.push("---"),e&&(t.push(""),t.push(e)),t.push("--- END PREVIEW ---"),t.join(`
604
- `)}o(TU,"formatFrontmatterPreview");var un=new st;un.name("exocortex").description("CLI tool for Exocortex knowledge management system").version("15.32.1");var gv=un.command("sparql").description("SPARQL query execution and cache management");gv.addCommand(vA());gv.addCommand(wA());gv.addCommand(EA());un.addCommand(RC());un.addCommand(NC());un.addCommand(LC());un.addCommand(MC());un.addCommand(jC());un.addCommand(qC());un.addCommand(zC());un.addCommand(KC());un.addCommand(ZC());un.addCommand(iI());un.parse();
606
+ `)}o(TU,"formatFrontmatterPreview");var un=new st;un.name("exocortex").description("CLI tool for Exocortex knowledge management system").version("15.32.2");var gv=un.command("sparql").description("SPARQL query execution and cache management");gv.addCommand(vA());gv.addCommand(wA());gv.addCommand(EA());un.addCommand(RC());un.addCommand(NC());un.addCommand(LC());un.addCommand(MC());un.addCommand(jC());un.addCommand(qC());un.addCommand(zC());un.addCommand(KC());un.addCommand(ZC());un.addCommand(iI());un.parse();
605
607
  /*! Bundled license information:
606
608
 
607
609
  reflect-metadata/Reflect.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitelev/exocortex-cli",
3
- "version": "15.32.1",
3
+ "version": "15.32.2",
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": {