@kitelev/exocortex-cli 15.176.1 → 15.176.3

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 +2 -2
  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.176.1
2
+ // @kitelev/exocortex-cli v15.176.3
3
3
  // CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
4
4
  // License: MIT
5
5
 
@@ -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.176.1");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});
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.3");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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitelev/exocortex-cli",
3
- "version": "15.176.1",
3
+ "version": "15.176.3",
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": {