@kitelev/exocortex-cli 15.175.0 → 15.176.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/dist/index.js +3 -3
- 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.
|
|
2
|
+
// @kitelev/exocortex-cli v15.176.0
|
|
3
3
|
// CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
|
|
4
4
|
// License: MIT
|
|
5
5
|
|
|
@@ -678,7 +678,7 @@ Continue? (y/n): `,s=>{r.close(),i(s.toLowerCase()==="y"||s.toLowerCase()==="yes
|
|
|
678
678
|
\u26A0\uFE0F Found ${i.length} file(s) with IRI issues:
|
|
679
679
|
`);for(let s of i)console.log(` \u274C ${s.path}`),console.log(` ${s.reason}`);console.log(`
|
|
680
680
|
\u{1F4DD} To fix these issues:`),console.log(" - Rename files to remove spaces and special characters"),console.log(" - Use dashes (-) or underscores (_) instead of spaces"),console.log(" - Avoid angle brackets (<>) and other special characters"),console.log(`
|
|
681
|
-
\u{1F4A1} Run 'exocortex sparql index --strict' to fail on first issue`)}i.length>0&&(process.exitCode=1)}catch(t){D.handle(t)}})}a(OX,"validateIriCommand");function KD(){let n=new se("validate").description("Validate vault files (IRI checks, schema linting, frontmatter shapes)");return n.addCommand(OX()),n.addCommand(UD()),n.addCommand(zD()),n}a(KD,"validateCommand");var YD=require("fs"),XD=require("path"),Pr=H(Pt());function JD(){return new se("classes").description("List RDF classes in
|
|
681
|
+
\u{1F4A1} Run 'exocortex sparql index --strict' to fail on first issue`)}i.length>0&&(process.exitCode=1)}catch(t){D.handle(t)}})}a(OX,"validateIriCommand");function KD(){let n=new se("validate").description("Validate vault files (IRI checks, schema linting, frontmatter shapes)");return n.addCommand(OX()),n.addCommand(UD()),n.addCommand(zD()),n}a(KD,"validateCommand");var YD=require("fs"),XD=require("path"),Pr=H(Pt());function JD(){return new se("classes").alias("describe-class").description("List RDF classes in vault, or describe a class (predicates + counts). Alias `describe-class` is provided per #3043 RFC \xA7B (schema introspection).").argument("[class-name]","Optional class name to show details (e.g., ems__Task)").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--format <type>","Output format: table|json","table").option("--output <type>","Response format: text|json (for MCP tools)","text").option("--use-cache","Use persistent cache (faster for repeated queries)").action(async(n,e)=>{let t=e.output||"text";D.setFormat(t);try{let r=Date.now(),i=(0,XD.resolve)(e.vault);if(!(0,YD.existsSync)(i))throw new Te(i);t==="text"&&console.log(`\u{1F4E6} Loading vault: ${i}...`);let s,o=!1;if(e.useCache){let f=await new Gn(i).loadOrBuild();s=f.triples,o=f.cacheHit,t==="text"&&o&&console.log("\u{1F680} Cache hit! Loading from persistent cache...")}else{let u=new Nt(i);s=await new Pr.NoteToRDFConverter(u).convertVault()}let c=new Pr.InMemoryTripleStore;await c.addAll(s);let l=Date.now()-r;if(t==="text"){let u=o?" (from cache)":"";console.log(`\u2705 Loaded ${s.length} triples in ${l}ms${u}
|
|
682
682
|
`)}n?await DX(c,n,e,t):await FX(c,e,t)}catch(r){D.handle(r)}})}a(JD,"classesCommand");async function FX(n,e,t){let s=new Pr.ExoQLParser().parse(`
|
|
683
683
|
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
684
684
|
SELECT ?class (COUNT(?instance) AS ?count)
|
|
@@ -813,7 +813,7 @@ exo__BacklinksTableBlock_columns:${f==="[]"?" []":f}
|
|
|
813
813
|
`),console.log(`${"Rank".padEnd(6)}${"Term".padEnd(30)}${"Freq".padEnd(8)}Sample UIDs`),console.log("-".repeat(90)),c.forEach((u,f)=>{let d=`#${f+1}`.padEnd(6),h=u.term.padEnd(30),p=String(u.frequency).padEnd(8),y=u.sample_uids.join(", ");console.log(`${d}${h}${p}${y}`)})})}a(jN,"backfillOrphanTermsCommand");function $N(){let n=new se("backfill").description("Concept backfill tools for aiKnow assets");return n.addCommand(MN()),n.addCommand(jN()),n}a($N,"backfillCommand");var ky=require("path"),HN=require("fs"),QN=require("os");var Ny=require("child_process"),Ly=require("fs"),qN=require("path");var Zi=require("fs"),Dy=H(require("path")),UN=require("crypto");var kJ=/^---\s*\r?\n([\s\S]*?)\r?\n---\s*(?:\r?\n([\s\S]*))?$/;function BN(n){let e=n.match(kJ);if(!e)return null;let[,t,r=""]=e,i=ar.load(t);if(i==null)return{frontmatter:{},body:r};if(typeof i!="object"||Array.isArray(i))throw new Error("frontmatter is not a YAML mapping");return{frontmatter:i,body:r}}a(BN,"parseFile");function MJ(n,e){let t=ar.dump(n,{lineWidth:-1,quotingType:'"',forceQuotes:!1,noRefs:!0}),r=e.length>0?e:"";return`---
|
|
814
814
|
${t}---
|
|
815
815
|
${r}`}a(MJ,"serializeFile");function VN(n,e,t={}){let r=Dy.default.dirname(n),i=Dy.default.basename(n),s=Dy.default.join(r,`.${i}.tmp.${process.pid}.${(0,UN.randomBytes)(6).toString("hex")}`);try{let o=(0,Zi.readFileSync)(n,"utf8"),c;try{c=BN(o)}catch(f){return{success:!1,verified:!1,reason:"parse-error",error:f.message}}if(!c)return{success:!1,verified:!1,reason:"no-frontmatter"};let l={...c.frontmatter,...e},u=MJ(l,c.body);if((0,Zi.writeFileSync)(s,u,"utf8"),(0,Zi.renameSync)(s,n),t.verifyKey!==void 0){let f=(0,Zi.readFileSync)(n,"utf8"),d;try{d=BN(f)}catch(p){return{success:!1,verified:!1,reason:"parse-error",error:p.message}}if(!d)return{success:!1,verified:!1,reason:"no-frontmatter"};let h=d.frontmatter[t.verifyKey];return h!==t.verifyValue?{success:!1,verified:!1,reason:"verify-mismatch",error:`expected ${t.verifyKey}=${String(t.verifyValue)}, got ${String(h)}`}:{success:!0,verified:!0}}return{success:!0,verified:!0}}catch(o){if((0,Zi.existsSync)(s))try{(0,Zi.unlinkSync)(s)}catch{}return{success:!1,verified:!1,reason:"fs-error",error:o.message}}}a(VN,"atomicUpdateFrontmatter");var jJ=/^claude-child-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/,$J=/^claude-child-([0-9a-f]{8})-(\d+)$/,BJ="EffortStatusDoing";function WN(n){return e=>new Promise((t,r)=>{n(e,(i,s,o)=>{i?r(Object.assign(i,{stdout:s,stderr:o})):t(s)})})}a(WN,"makeExecPromise");async function UJ(n=Ny.exec){let e=WN(n),t;try{t=await e("tmux list-sessions -F '#{session_name}' 2>/dev/null")}catch{return[]}let r=[];for(let i of t.split(`
|
|
816
|
-
`).map(s=>s.trim()).filter(Boolean)){let s=jJ.exec(i);if(s){r.push({sessionName:i,uuid:s[1],type:"full"});continue}let o=$J.exec(i);o&&r.push({sessionName:i,uuid:o[1],type:"short"})}return r}a(UJ,"listClaudeChildSessions");function VJ(n,e,t){let r=null,i=e.toLowerCase();function s(o){if(r)return;let c;try{c=(0,Ly.readdirSync)(o,{withFileTypes:!0})}catch{return}for(let l of c){if(r)return;if(l.name.startsWith(".")||l.name==="node_modules")continue;let u=(0,qN.join)(o,l.name);if(l.isDirectory())s(u);else if(l.name.endsWith(".md")){let f=l.name.slice(0,-3).toLowerCase();(t==="full"&&f===i||t==="short"&&f.startsWith(i))&&(r=u)}}}return a(s,"walk"),s(n),r}a(VJ,"findVaultFile");function qJ(n,e){try{let i=(e??(s=>(0,Ly.readFileSync)(s,"utf8")))(n).match(/ems__Effort_status\s*:.*\[\[([^\]]+)\]\]/);return i?i[1].includes(BJ):!1}catch{return!1}}a(qJ,"isTaskDoing");async function GN(n,e=Ny.exec,t){let r=await UJ(e),i=[];for(let s of r){let o=VJ(n,s.uuid,s.type);if(!o){i.push({sessionName:s.sessionName,taskUuid:s.uuid,taskFilePath:null,reason:"vault task not found"});continue}qJ(o,t)||i.push({sessionName:s.sessionName,taskUuid:s.uuid,taskFilePath:o,reason:"vault task status != Doing"})}return i}a(GN,"detectOrphans");async function zN(n,e,t=Ny.exec,r=VN){let i=WN(t);if(e)return{ok:!0};let s=new Date().toISOString();if(n.taskFilePath)try{r(n.taskFilePath,{ems__Effort_status:"[[ems__EffortStatusFailed]]",aiTask__Task_lastError:`orphan recovery: ${n.reason}`,exo__Asset_updatedAt:s})}catch(o){return{ok:!1,error:`vault update failed: ${o.message}`}}try{await i(`tmux kill-session -t ${JSON.stringify(n.sessionName)}`)}catch{}return{ok:!0}}a(zN,"recoverOrphan");function WJ(){return process.env.EXOCORTEX_VAULT??(0,ky.join)((0,QN.homedir)(),"vault-2025")}a(WJ,"defaultVault");function KN(){return new se("recover").description("Detect and recover orphaned claude-child tmux sessions. A session is orphaned when the corresponding vault task is not in Doing status. Default mode: dry-run (no changes). Use --apply to perform recovery.").option("--vault <path>","Path to Obsidian vault",WJ()).option("--dry-run","List orphans without applying changes (default)",!1).option("--apply","Apply orphan recovery: set Failed + kill tmux session",!1).action(async n=>{let e=(0,ky.resolve)(n.vault);if(!(0,HN.existsSync)(e)){console.error(`[recover] vault not found: ${e}`),process.exitCode=1;return}let t=!n.apply;console.log(`[recover] vault=${e} mode=${t?"dry-run":"apply"}`);let r=await GN(e);if(r.length===0){console.log("[recover] No orphaned claude-child sessions found.");return}console.log(`[recover] Found ${r.length} orphan(s):`);for(let o of r){let c=o.taskFilePath??"(not found in vault)";console.log(` session=${o.sessionName} uuid=${o.taskUuid} reason=${o.reason}`),console.log(` file=${c}`)}if(t){console.log("[recover] Dry-run mode: no changes applied. Use --apply to recover.");return}let i=0,s=0;for(let o of r){let c=await zN(o,!1);c.ok?(i++,console.log(`[recover] RECOVERED: ${o.sessionName}`)):(s++,console.error(`[recover] ERROR recovering ${o.sessionName}: ${c.error}`))}console.log(`[recover] Done: recovered=${i} errors=${s}`),s>0&&(process.exitCode=1)})}a(KN,"recoverCommand");function YN(n){n.addCommand(aD()),n.addCommand(fD()),n.addCommand(dD())}a(YN,"addQuerySubcommands");function XN(n){let e=new se;e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"15.
|
|
816
|
+
`).map(s=>s.trim()).filter(Boolean)){let s=jJ.exec(i);if(s){r.push({sessionName:i,uuid:s[1],type:"full"});continue}let o=$J.exec(i);o&&r.push({sessionName:i,uuid:o[1],type:"short"})}return r}a(UJ,"listClaudeChildSessions");function VJ(n,e,t){let r=null,i=e.toLowerCase();function s(o){if(r)return;let c;try{c=(0,Ly.readdirSync)(o,{withFileTypes:!0})}catch{return}for(let l of c){if(r)return;if(l.name.startsWith(".")||l.name==="node_modules")continue;let u=(0,qN.join)(o,l.name);if(l.isDirectory())s(u);else if(l.name.endsWith(".md")){let f=l.name.slice(0,-3).toLowerCase();(t==="full"&&f===i||t==="short"&&f.startsWith(i))&&(r=u)}}}return a(s,"walk"),s(n),r}a(VJ,"findVaultFile");function qJ(n,e){try{let i=(e??(s=>(0,Ly.readFileSync)(s,"utf8")))(n).match(/ems__Effort_status\s*:.*\[\[([^\]]+)\]\]/);return i?i[1].includes(BJ):!1}catch{return!1}}a(qJ,"isTaskDoing");async function GN(n,e=Ny.exec,t){let r=await UJ(e),i=[];for(let s of r){let o=VJ(n,s.uuid,s.type);if(!o){i.push({sessionName:s.sessionName,taskUuid:s.uuid,taskFilePath:null,reason:"vault task not found"});continue}qJ(o,t)||i.push({sessionName:s.sessionName,taskUuid:s.uuid,taskFilePath:o,reason:"vault task status != Doing"})}return i}a(GN,"detectOrphans");async function zN(n,e,t=Ny.exec,r=VN){let i=WN(t);if(e)return{ok:!0};let s=new Date().toISOString();if(n.taskFilePath)try{r(n.taskFilePath,{ems__Effort_status:"[[ems__EffortStatusFailed]]",aiTask__Task_lastError:`orphan recovery: ${n.reason}`,exo__Asset_updatedAt:s})}catch(o){return{ok:!1,error:`vault update failed: ${o.message}`}}try{await i(`tmux kill-session -t ${JSON.stringify(n.sessionName)}`)}catch{}return{ok:!0}}a(zN,"recoverOrphan");function WJ(){return process.env.EXOCORTEX_VAULT??(0,ky.join)((0,QN.homedir)(),"vault-2025")}a(WJ,"defaultVault");function KN(){return new se("recover").description("Detect and recover orphaned claude-child tmux sessions. A session is orphaned when the corresponding vault task is not in Doing status. Default mode: dry-run (no changes). Use --apply to perform recovery.").option("--vault <path>","Path to Obsidian vault",WJ()).option("--dry-run","List orphans without applying changes (default)",!1).option("--apply","Apply orphan recovery: set Failed + kill tmux session",!1).action(async n=>{let e=(0,ky.resolve)(n.vault);if(!(0,HN.existsSync)(e)){console.error(`[recover] vault not found: ${e}`),process.exitCode=1;return}let t=!n.apply;console.log(`[recover] vault=${e} mode=${t?"dry-run":"apply"}`);let r=await GN(e);if(r.length===0){console.log("[recover] No orphaned claude-child sessions found.");return}console.log(`[recover] Found ${r.length} orphan(s):`);for(let o of r){let c=o.taskFilePath??"(not found in vault)";console.log(` session=${o.sessionName} uuid=${o.taskUuid} reason=${o.reason}`),console.log(` file=${c}`)}if(t){console.log("[recover] Dry-run mode: no changes applied. Use --apply to recover.");return}let i=0,s=0;for(let o of r){let c=await zN(o,!1);c.ok?(i++,console.log(`[recover] RECOVERED: ${o.sessionName}`)):(s++,console.error(`[recover] ERROR recovering ${o.sessionName}: ${c.error}`))}console.log(`[recover] Done: recovered=${i} errors=${s}`),s>0&&(process.exitCode=1)})}a(KN,"recoverCommand");function YN(n){n.addCommand(aD()),n.addCommand(fD()),n.addCommand(dD())}a(YN,"addQuerySubcommands");function XN(n){let e=new se;e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"15.176.0");let t=e.command("exoql").description("ExoQL query execution and cache management");YN(t);let r=e.command("sparql").description("(deprecated) Use 'exoql' instead");return YN(r),r.hook("preAction",()=>{console.error('\u26A0\uFE0F "sparql" is deprecated. Use "exoql" instead.')}),e.addCommand(vD()),e.addCommand(ED()),e.addCommand(TD()),e.addCommand(xD()),e.addCommand(CD()),e.addCommand(FD()),e.addCommand(kD()),e.addCommand(KD()),e.addCommand(JD()),e.addCommand(nN()),e.addCommand(oN()),e.addCommand(aN()),e.addCommand(lN()),e.addCommand(vN()),e.addCommand(TN()),e.addCommand(ON()),e.addCommand(FN()),e.addCommand($N()),e.addCommand(KN()),e}a(XN,"createProgram");XN().parse();0&&(module.exports={createProgram});
|
|
817
817
|
/*! Bundled license information:
|
|
818
818
|
|
|
819
819
|
reflect-metadata/Reflect.js:
|
package/package.json
CHANGED