@kitelev/exocortex-cli 17.0.0 → 17.1.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 v17.
|
|
2
|
+
// @kitelev/exocortex-cli v17.1.0
|
|
3
3
|
// CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
|
|
4
4
|
// License: MIT
|
|
5
5
|
|
|
@@ -628,7 +628,7 @@ ${g}
|
|
|
628
628
|
`);return}e.dryRun||(0,mp.writeFileSync)(n,c,"utf-8"),process.stdout.write(JSON.stringify({path:i,changed:!0,dryRun:!!e.dryRun,removed:o.removed,...e.canonicalizeKeys?{canonicalized:l}:{},...u?{updatedAt:u}:{},...e.dryRun?{diff:p_e(s,c)}:{}})+`
|
|
629
629
|
`)}catch(t){ue.handle(t)}})}a(tV,"repairFrontmatterCommand");ct();var rV=require("fs"),nV=require("path"),gs=Q(Fe());Xs();St();Mt();tr();Jw();ep();var h_e="https://exocortex.my/ontology/find#Alias_sparql",m_e="https://exocortex.my/ontology/exo#Asset_label";function gp(r){if(r&&typeof r=="object"&&"value"in r){let e=r.value;return typeof e=="string"?e:String(e)}return String(r)}a(gp,"nodeValue");async function g_e(r,e){let t=await r.match(void 0,void 0,void 0),n=[];for(let s of t)gp(s.predicate)!==m_e||gp(s.object)!==e||n.push(gp(s.subject));if(n.length===0)return null;let i=[];for(let s of n)for(let o of t)gp(o.predicate)===h_e&&gp(o.subject)===s&&i.push(gp(o.object));if(i.length===0)return null;if(i.length>1)throw new Ye(`Ambiguous find__Alias "${e}" \u2014 ${i.length} instances define a sparql fragment`,`Ensure exactly one find__Alias asset has exo:Asset_label "${e}"`);return i[0]}a(g_e,"resolveAliasFragment");var y_e=new RegExp(`^(${Wa})__([A-Za-z0-9_]+)$`),b_e="https://exocortex.my/ontology/";function __e(r,e){let t=y_e.exec(e);if(t){let i=`<${b_e}${t[1]}#${t[2]}>`;return r.replace(/\?value\b/g,i)}let n=e.replace(/\\/g,"\\\\").replace(/"/g,'\\"');return r.replace(/\?value\b/g,`"${n}"`)}a(__e,"bindValueLiteral");function iV(){return new pe("find").description("Find vault assets via SPARQL \u2014 outputs file paths one per line (RFC 8e83442b T1.1)").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--sparql <query>","SPARQL SELECT query (must bind ?path)").option("--class <value>","Filter by class label via find__Alias 'class' (e.g. ems__Task)").action(async r=>{ue.setFormat("text");try{if(r.sparql&&r.class)throw new Ye("--sparql and --class are mutually exclusive","Pass either a raw --sparql query or a find__Alias-backed flag like --class");if(!r.sparql&&!r.class)throw new Ye("one of --sparql <query> or --class <value> is required",'exocortex find --class ems__Task OR exocortex find --sparql "SELECT ?path WHERE { ... }"');let e=(0,nV.resolve)(r.vault);if(!(0,rV.existsSync)(e))throw new Le(e);let t=new Ht(e),i=await new gs.NoteToRDFConverter(t).convertVault(),s=new gs.InMemoryTripleStore;await s.addAll(i);let o;if(r.class){let b=await g_e(s,"class");if(b===null)throw new Ye('No find__Alias with exo:Asset_label "class" was found in the vault',"Seed a find__Alias asset (label=class) or fall back to exocortex find --sparql");o=`SELECT ?path WHERE { ${__e(b,r.class)} }`}else o=r.sparql;let c=Xw(o);c=op(c);let l=new gs.ExoQLParser,u=Qw(Yw(e));u.size>0&&l.setVaultPrefixes(u);let f=l.parse(c),p=new gs.ExoQLAlgebraTranslator().translate(f);p.type!=="construct"&&(p=new gs.AlgebraOptimizer().optimize(p));let g=await new gs.ExoQLQueryExecutor(s).executeAll(p),m="obsidian://vault/";for(let b of g){let S=b.toJSON().path;if(typeof S!="string"||!S.startsWith(m))continue;let A=S.slice(m.length),E;try{E=decodeURIComponent(A)}catch{E=A}process.stdout.write(E+`
|
|
630
630
|
`)}}catch(e){ue.handle(e),process.exit(5)}})}a(iV,"findCommand");ct();var pV=Q(Fe()),nF=require("fs"),rc=require("path"),Ee=Q(Fe());St();Mt();tr();Xs();var Pn=Q(Fe());var vE=new Map([["exo__Asset_uid",Pn.Namespace.EXO.term("Asset_uid").value],["exo__Asset_label",Pn.Namespace.EXO.term("Asset_label").value],["aliases",Pn.Namespace.EXO.term("Asset_aliases").value]]),TE=class r extends Yn{constructor(t,n){super(t);this.source=n;this.indexPromise=null;this.pathKeys=new Map;this.stats={indexedLookups:0,scanFallbacks:0,candidateReads:0,zeroTripleReads:0}}static{a(this,"TripleStoreIndexedFsAdapter")}async findFilesByMetadata(t){let n=Object.entries(t);if(!(n.length>0&&n.every(([u,f])=>vE.has(u)&&this.normalizeValue(f).length>0)))return this.stats.scanFallbacks++,super.findFilesByMetadata(t);let s=await this.ensureIndex();this.stats.indexedLookups++;let o=null;for(let[u,f]of n){let d=s.get(u)?.get(this.normalizeValue(f))??[];if(o=o===null?[...d]:o.filter(p=>d.includes(p)),o.length===0)return[]}let c=[...o??[]].filter(u=>!r.hasDotSegment(u)).sort(),l=[];for(let u of c){this.stats.candidateReads++;try{let f=await this.getFileMetadata(u);this.matchesQuery(f,t)&&l.push(u)}catch{continue}}return l}async createFile(t,n){let i=await super.createFile(t,n);return await this.reindexOwnWrite(t,n),i}async updateFile(t,n){await super.updateFile(t,n),await this.reindexOwnWrite(t,n)}async writeFile(t,n){await super.writeFile(t,n),await this.reindexOwnWrite(t,n)}async deleteFile(t){await super.deleteFile(t),this.forget(await this.ensureIndex(),r.rel(t))}async renameFile(t,n){await super.renameFile(t,n);let i=await this.ensureIndex(),s=r.rel(t),o=[...this.pathKeys.get(s)??[]];this.forget(i,s);let c=r.rel(n);for(let[l,u]of o)this.addKey(i,l,u,c)}async reindexOwnWrite(t,n){let i=await this.ensureIndex(),s=r.rel(t);this.forget(i,s);let o;try{o=this.extractFrontmatter(n)}catch{return}this.indexFrontmatter(i,s,o)}static rel(t){return t.replace(/\\/g,"/").replace(/^\.\//,"")}static hasDotSegment(t){return t.split("/").some(n=>n.startsWith("."))}async ensureIndex(){return this.indexPromise===null&&(this.indexPromise=this.buildIndex()),this.indexPromise}async buildIndex(){let t=new Map;for(let u of vE.keys())t.set(u,new Map);let n=new Map;for(let[u,f]of vE)n.set(f,u);let i=new Map,s=new Map,o=new Map,c=[];for(let u of this.source.explicitTriples){let f=n.get(u.predicate.value);if(f===void 0)continue;let d=r.subjectToPath(u);if(d===null)continue;c.push([f,d,u.object]);let p=u.object;if(f==="exo__Asset_uid"){p instanceof Pn.Literal&&!i.has(d)&&i.set(d,p.value);continue}if(p instanceof Pn.Literal)r.push(s,d,p.value);else if(p instanceof Pn.IRI){let h=Pn.Namespace.fromTermIRI(p.value);h&&(r.push(s,d,`${h.namespace.prefix}__${h.localName}`),f==="exo__Asset_label"&&r.push(o,p.value,d))}}let l=new Map;for(let[u,f]of o)l.set(u,f.map(d=>i.get(d)).filter(d=>d!==void 0));for(let[u,f,d]of c){let p=r.keysForObject(d,l,s);for(let h of p)this.addKey(t,u,this.normalizeValue(h),f)}for(let u of this.source.zeroTriplePaths){this.stats.zeroTripleReads++;try{this.indexFrontmatter(t,u,await this.getFileMetadata(u))}catch{continue}}return t}indexFrontmatter(t,n,i){for(let s of vE.keys()){let o=i[s],c=Array.isArray(o)?o:[o];for(let l of c)this.addKey(t,s,this.normalizeValue(l),n)}}addKey(t,n,i,s){if(i.length===0)return;let o=t.get(n);if(o===void 0)return;let c=o.get(i);c===void 0?o.set(i,[s]):c.includes(s)||c.push(s),r.push(this.pathKeys,s,[n,i])}forget(t,n){let i=this.pathKeys.get(n);if(i){for(let[s,o]of i){let c=t.get(s)?.get(o);if(!c)continue;let l=c.indexOf(n);l>=0&&c.splice(l,1)}this.pathKeys.delete(n)}}static push(t,n,i){let s=t.get(n);s===void 0?t.set(n,[i]):s.push(i)}static subjectToPath(t){let n=t.subject;if(!(n instanceof Pn.IRI))return null;let i=(0,Pn.iriToVaultPath)(n.value);return i===null||i.startsWith("/")||i.startsWith("..")||i.includes("/../")?null:i}static keysForObject(t,n,i){if(t instanceof Pn.Literal)return[t.value];if(!(t instanceof Pn.IRI))return[];let s=Pn.Namespace.fromTermIRI(t.value);if(s)return[`${s.namespace.prefix}__${s.localName}`,...n.get(t.value)??[]];let o=(0,Pn.iriToVaultPath)(t.value);if(o!==null){let c=o.lastIndexOf("/"),l=c===-1?o:o.slice(c+1);return[l.endsWith(".md")?l.slice(0,-3):l,...i.get(o)??[]]}return[t.value]}};var fV=Q(Fe()),Kt=Q(cV());var lV="obsidian://vault/";function B_e(r){let e=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;return{async resolveTargetPath(t){if(!t)throw new Error("Cannot resolve empty targetIRI to a vault path");let n=t;if(n.startsWith(lV))n=decodeURI(n.slice(lV.length));else if(e.test(n)){let i=await r.findFileByUID(n);if(!i)throw new Error(`No vault file found for UID: ${n}`);n=i}if(n.endsWith(".md")||(n=`${n}.md`),!await r.fileExists(n))throw new Error(`Cannot resolve target file for IRI "${t}" (tried "${n}")`);return n}}}a(B_e,"createCliPathResolver");var V_e=["openFile","sparqlSelect","getActiveFileIRI","getActiveFilePath","trashFile","duplicateFile"],rF=class extends Error{constructor(t){super(`Service "${t}" is not implemented in the CLI (no-op stub). dyncommand exec on this service_call grounding cannot change vault state. See CLI parity issues #2865-#2868 for port status.`);this.serviceId=t;this.name="CliServiceNotImplementedError"}static{a(this,"CliServiceNotImplementedError")}};function uV(r){return{async execute(){throw new rF(r)}}}a(uV,"notImplementedService");function G_e(r){return e=>{let t=r.getFirstLinkpathDest(e,"");if(!t||!("basename"in t))return null;let i=r.getFrontmatter(t)?.exo__Asset_label;return typeof i=="string"&&i.length>0?i:null}}a(G_e,"createCliClassResolver");function dV(r,e){for(let t of V_e)r.register(t,uV(t));for(let t of["updateProperty","removeProperty","setStatus","createAsset"])r.register(t,uV(t));if(e){if(e.fsAdapter){let t=new fV.FrontmatterService,n=B_e(e.fsAdapter);r.register("updateProperty",(0,Kt.createUpdatePropertyService)(e.fsAdapter,t,n)),r.register("removeProperty",(0,Kt.createRemovePropertyService)(e.fsAdapter,t,n)),r.register("setStatus",(0,Kt.createSetStatusService)(e.fsAdapter,t,n)),r.register("createAsset",(0,Kt.createCreateAssetService)(e.vaultAdapter,e.fsAdapter,G_e(e.vaultAdapter))),r.register("instantiatePrototypeSubtree",(0,Kt.createInstantiatePrototypeSubtreeService)(e.vaultAdapter,e.fsAdapter))}r.register("createRelatedTask",(0,Kt.createCreateRelatedTaskService)(e.vaultAdapter,e.genericAssetCreationService)),r.register("createRelatedProject",(0,Kt.createCreateRelatedProjectService)(e.vaultAdapter,e.genericAssetCreationService)),r.register("archiveAsset",(0,Kt.createArchiveAssetService)(e.vaultAdapter,e.archiveAssetService)),r.register("planForEvening",(0,Kt.createPlanForEveningService)(e.vaultAdapter,e.taskStatusService)),r.register("cleanProperties",(0,Kt.createCleanPropertiesService)(e.vaultAdapter,e.propertyCleanupService)),r.register("renameToUid",(0,Kt.createRenameToUidService)(e.vaultAdapter,e.renameToUidService)),r.register("repairFolder",(0,Kt.createRepairFolderService)(e.vaultAdapter,e.folderRepairService)),r.register("fixMissingLabel",(0,Kt.createFixMissingLabelService)(e.vaultAdapter,e.fixMissingLabelService))}}a(dV,"populateCliServiceRegistry");za();function q_e(r,e){let t=r.getAbstractFileByPath(e),n=t!==null&&"basename"in t?t:null,i=n?r.getFrontmatter(n):null,s=i&&typeof i=="object"?i.exo__Asset_label:void 0;return{uuid:n?.basename??e.replace(/^.*\//,"").replace(/\.md$/,""),path:e,label:typeof s=="string"?s:""}}a(q_e,"buildCreatedAsset");var W_e=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;async function z_e(){if(process.stdin.isTTY)return[];let r=[];for await(let t of process.stdin)r.push(t);return Buffer.concat(r).toString("utf-8").split(`
|
|
631
|
-
`).map(t=>t.trim()).filter(t=>t.length>0)}a(z_e,"readStdinLines");function RE(r){if(r&&typeof r=="object"&&"value"in r){let e=r.value;return typeof e=="string"?e:String(e)}return String(r)}a(RE,"nodeValue");async function H_e(r,e){let t=new Ee.IRI("https://exocortex.my/ontology/exocmd#Command_cliName"),n=await r.match(void 0,t,void 0),i=[];for(let s of n)if(RE(s.object)===e){let l=RE(s.subject).match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.md$/i);l&&i.push(l[1])}if(i.length===0)return null;if(i.length>1)throw new Ye(`Ambiguous cliName "${e}" \u2014 resolves to ${i.length} commands: ${i.join(", ")}`,"Use the UUID directly: exocortex apply <uuid> <path>");return i[0]}a(H_e,"resolveSlugToUuid");async function K_e(r,e){let t=new Ee.IRI("https://exocortex.my/ontology/exocmd#Command_destructive"),n=await r.match(void 0,t,void 0);for(let i of n)if(RE(i.subject).includes(e)){let o=RE(i.object);if(o==="true"||o==="True")return!0}return!1}a(K_e,"isDestructive");async function Y_e(r,e,t,n,i,s,o,c,l){let u={ok:!1,created:[],executed:!1},f=(0,rc.resolve)(r,s);if(!(0,nF.existsSync)(f))return console.error(`\u274C Target file not found: ${s}`),u;let d=(0,rc.relative)(r,f);if(d===".."||d.startsWith(`..${rc.sep}`)||(0,rc.isAbsolute)(d))return console.error(`\u274C Target is outside the vault: ${s} (vault: ${r})`),u;let p=new Ee.CommandResolver(e,nE),h=await p.loadCommand(i);if(!h)return console.error(`\u274C Command with UID "${i}" not found.`),u;if(await K_e(e,i)&&!o.dryRun&&!o.yes)return console.error(`\u274C Command "${h.name}" is marked destructive. Add --dry-run to preview, or --yes to apply.`),u;let m=(0,Ee.vaultPathToIRI)(d),b=new Ht(r),_=new Ee.FolderRepairService(b),S=new Ee.PreconditionEvaluator(e,void 0,{clock:c});(0,Ee.registerDefaultHostFunctions)(S),S.registerHostFunction("isInWrongFolder",eE(b,_)),S.registerHostFunction("hasObsoleteProperties",tE(b));let A=b.getAbstractFileByPath(d),E=A!==null&&"basename"in A?A:null,w=E?b.getFrontmatter(E):null,R=w&&typeof w=="object"?w.exo__Asset_uid:void 0,C=await e.match(void 0,pV.Namespace.EXOCMD.term("CommandBinding_command"),void 0),O=!1,N=[];for(let W of C){if(String(W.object).includes(i)){O=!0;break}if(W.object instanceof Ee.IRI){let z=await(0,Ee.labelTermBearers)(e,W.object);if(z.some(re=>re.uid===i)){O=!0,z.length>1&&(N=z.map(re=>re.uid));break}}}if(O){let W=AO(w),z=await IO(e,m),re=[...new Set([...W,...z])];if(re.length>0){let Ce=iE(w?.exo__Asset_prototype);if(!(await p.resolveForAssetMulti(m,re,Ce??void 0)).some(fe=>fe.command.id===i))return console.error(`\u274C "${h.name}" is not bound to the target's class on "${d}".`),console.error(` Declared classes: ${re.join(", ")}.`),N.length>0&&console.error(` The command's label is ambiguous \u2014 borne by ${N.join(", ")} \u2014 so its binding reference cannot be resolved.`),u}}let V={targetIRI:m,filePath:d,fileBasename:E?.basename,assetUid:typeof R=="string"?R:void 0};if(!await S.evaluate(h.precondition,m,V))return console.error(`\u274C Precondition not satisfied for "${h.name}" on "${d}".`),u;let ee;if(o.input)try{let W=JSON.parse(o.input);if(typeof W!="object"||W===null||Array.isArray(W))throw new Error("must be a JSON object");ee=W}catch(W){let z=W instanceof Error?W.message:String(W);return console.error(`\u274C --input: invalid JSON object (${z})`),u}let K=(0,Ee.findInputSchemaViolation)(h.grounding,ee);if(K!==null)return console.error(`\u274C "${h.name}" cannot run on "${d}": ${K}`),u;if(o.dryRun){let W=(0,Ee.findMissingInput)(h.grounding,ee);return W!==null?(console.error(`\u274C "${h.name}" cannot run on "${d}": ${(0,Ee.missingInputError)(W)}`),u):(o.json||console.log(`\u{1F50D} Dry-run: would apply "${h.name}" to "${d}" (precondition passed).`),{ok:!0,created:[],executed:!1})}let M=new Ee.ServiceRegistry,ce=new Ee.GenericAssetCreationService(b).withDeterminism({clock:c,uidGenerator:l}),q=new Ee.ArchiveAssetService(b),oe=new Ee.PropertyCleanupService(b),X=new Ee.FixMissingLabelService(b),J=new Ee.RenameToUidService(b),ye=new Ee.TaskStatusService(b,new Ee.EffortStatusWorkflow,new Ee.StatusTimestampService(b));dV(M,{vaultAdapter:b,fsAdapter:n,genericAssetCreationService:ce,archiveAssetService:q,taskStatusService:ye,propertyCleanupService:oe,fixMissingLabelService:X,renameToUidService:J,folderRepairService:_});let ze=new Ee.NamedQueryRunner(new cp(e,n),e),Z=await new Ee.GroundingExecutor(n,n,M,(0,Ee.createVaultFrontmatterClassLabelResolver)(n),{clock:c,uidGenerator:l,workflowResolver:t,groundingLoader:a(W=>p.loadGroundingByUid(W),"groundingLoader"),templateLoader:a(async W=>{let z=await n.findFileByUID(W);return z?(0,Ee.stripTemplateFrontmatter)(await n.readFile(z)):null},"templateLoader"),namedQueryRunner:ze,refToFolder:(0,Ee.createVaultFrontmatterRefToFolderResolver)(n),refToFrontmatter:(0,Ee.createVaultFrontmatterRefToFrontmatterResolver)(n),declaredRanges:(0,Ee.createTripleStoreDeclaredRanges)(e)}).execute(h.grounding,m,d,ee);if(Z.success){let W=[];Z.openPath&&W.push(Z.openPath),Z.createdPaths&&W.push(...Z.createdPaths);let z=[],re=new Set;for(let Ce of W)re.has(Ce)||(re.add(Ce),z.push(q_e(b,Ce)));if(!o.json){let Ce=h.successMessage??`Applied "${h.name}" to "${d}".`,j=Z.openPath??Z.createdPaths?.[0],fe=j?` \u2192 ${j}`:"";console.log(`\u2705 ${Ce}${fe}`)}return{ok:!0,created:z,executed:!0}}else return console.error(`\u274C "${h.name}" failed on "${d}": ${Z.error}`),{ok:!1,created:[],executed:!0}}a(Y_e,"executeOnTarget");function hV(){return new pe("apply").description("Apply an exocmd__Command to one or more vault assets (RFC 8e83442b T1.2). Pass a path arg or pipe paths via stdin.").argument("<cmd>","Command UUID or cliName slug").argument("[path]","Vault-relative path to target asset (omit to read paths from stdin)").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--dry-run","Preview without writing").option("--yes","Skip destructive-command confirmation").option("--input <json>",`JSON userInput for a grounding. Value-setting commands need a value key, e.g. set-planned-start / set-scheduled-date: --input '{"value":"<ISO>"}'. A command whose grounding declares its own input key uses THAT key: set-label: --input '{"label":"New label"}'. Asset-reference inputs (set-parent: --input '{"parent":"<uid>"}'; set-blocker: --input '{"blocker":"<uid>"}'; set-ontology: --input '{"ontology":"<uid>"}') take a BARE uid; a copied [[uid]] or [[uid|alias]] is accepted and unwrapped, anything else that still looks like a link is refused. The required key is named in the error if omitted.`).option("--seed <uuid>","Deterministic UID seed for test/replay (uses seededUidGenerator)").option("--frozen-clock <iso>","Freeze clock to ISO timestamp for test/replay (uses frozenClock)").option("--json","Emit a machine-readable JSON result ({command,target,created:[{uuid,path,label}]}) instead of human-readable output").option("--use-cache","Use the persistent triple cache (hit / delta / rebuild) instead of a full vault parse; a mutation is picked up by the NEXT --use-cache process as a delta unless --write-through is also given").option("--write-through","With --use-cache: after a grounding executed, fold the mutation into the persistent cache in this process, so the next --use-cache process is a plain hit (the delta is paid by this writer instead of the next reader). Refused without --use-cache").action(async(r,e,t)=>{if(ue.setFormat("text"),t.writeThrough&&!t.useCache){process.stderr.write(`\u274C --write-through requires --use-cache (there is no cache to write through to without it); nothing was applied
|
|
631
|
+
`).map(t=>t.trim()).filter(t=>t.length>0)}a(z_e,"readStdinLines");function RE(r){if(r&&typeof r=="object"&&"value"in r){let e=r.value;return typeof e=="string"?e:String(e)}return String(r)}a(RE,"nodeValue");async function H_e(r,e){let t=new Ee.IRI("https://exocortex.my/ontology/exocmd#Command_cliName"),n=await r.match(void 0,t,void 0),i=[];for(let s of n)if(RE(s.object)===e){let l=RE(s.subject).match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.md$/i);l&&i.push(l[1])}if(i.length===0)return null;if(i.length>1)throw new Ye(`Ambiguous cliName "${e}" \u2014 resolves to ${i.length} commands: ${i.join(", ")}`,"Use the UUID directly: exocortex apply <uuid> <path>");return i[0]}a(H_e,"resolveSlugToUuid");async function K_e(r,e){let t=new Ee.IRI("https://exocortex.my/ontology/exocmd#Command_destructive"),n=await r.match(void 0,t,void 0);for(let i of n)if(RE(i.subject).includes(e)){let o=RE(i.object);if(o==="true"||o==="True")return!0}return!1}a(K_e,"isDestructive");async function Y_e(r,e,t,n,i,s,o,c,l){let u={ok:!1,created:[],executed:!1},f=(0,rc.resolve)(r,s);if(!(0,nF.existsSync)(f))return console.error(`\u274C Target file not found: ${s}`),u;let d=(0,rc.relative)(r,f);if(d===".."||d.startsWith(`..${rc.sep}`)||(0,rc.isAbsolute)(d))return console.error(`\u274C Target is outside the vault: ${s} (vault: ${r})`),u;let p=new Ee.CommandResolver(e,nE),h=await p.loadCommand(i);if(!h)return console.error(`\u274C Command with UID "${i}" not found.`),u;if(await K_e(e,i)&&!o.dryRun&&!o.yes)return console.error(`\u274C Command "${h.name}" is marked destructive. Add --dry-run to preview, or --yes to apply.`),u;let m=(0,Ee.vaultPathToIRI)(d),b=new Ht(r),_=new Ee.FolderRepairService(b),S=new Ee.PreconditionEvaluator(e,void 0,{clock:c});(0,Ee.registerDefaultHostFunctions)(S),S.registerHostFunction("isInWrongFolder",eE(b,_)),S.registerHostFunction("hasObsoleteProperties",tE(b));let A=b.getAbstractFileByPath(d),E=A!==null&&"basename"in A?A:null,w=E?b.getFrontmatter(E):null,R=w&&typeof w=="object"?w.exo__Asset_uid:void 0,C=await e.match(void 0,pV.Namespace.EXOCMD.term("CommandBinding_command"),void 0),O=!1,N=[];for(let W of C){if(String(W.object).includes(i)){O=!0;break}if(W.object instanceof Ee.IRI){let z=await(0,Ee.labelTermBearers)(e,W.object);if(z.some(re=>re.uid===i)){O=!0,z.length>1&&(N=z.map(re=>re.uid));break}}}if(O){let W=AO(w),z=await IO(e,m),re=[...new Set([...W,...z])];if(re.length>0){let Ce=iE(w?.exo__Asset_prototype);if(!(await p.resolveForAssetMulti(m,re,Ce??void 0)).some(fe=>fe.command.id===i))return console.error(`\u274C "${h.name}" is not bound to the target's class on "${d}".`),console.error(` Declared classes: ${re.join(", ")}.`),N.length>0&&console.error(` The command's label is ambiguous \u2014 borne by ${N.join(", ")} \u2014 so its binding reference cannot be resolved.`),u}}let V={targetIRI:m,filePath:d,fileBasename:E?.basename,assetUid:typeof R=="string"?R:void 0};if(!await S.evaluate(h.precondition,m,V))return console.error(`\u274C Precondition not satisfied for "${h.name}" on "${d}".`),u;let ee;if(o.input)try{let W=JSON.parse(o.input);if(typeof W!="object"||W===null||Array.isArray(W))throw new Error("must be a JSON object");ee=W}catch(W){let z=W instanceof Error?W.message:String(W);return console.error(`\u274C --input: invalid JSON object (${z})`),u}let K=(0,Ee.findInputSchemaViolation)(h.grounding,ee);if(K!==null)return console.error(`\u274C "${h.name}" cannot run on "${d}": ${K}`),u;if(o.dryRun){let W=(0,Ee.findMissingInput)(h.grounding,ee);return W!==null?(console.error(`\u274C "${h.name}" cannot run on "${d}": ${(0,Ee.missingInputError)(W)}`),u):(o.json||console.log(`\u{1F50D} Dry-run: would apply "${h.name}" to "${d}" (precondition passed).`),{ok:!0,created:[],executed:!1})}let M=new Ee.ServiceRegistry,ce=new Ee.GenericAssetCreationService(b).withDeterminism({clock:c,uidGenerator:l}),q=new Ee.ArchiveAssetService(b),oe=new Ee.PropertyCleanupService(b),X=new Ee.FixMissingLabelService(b),J=new Ee.RenameToUidService(b),ye=new Ee.TaskStatusService(b,new Ee.EffortStatusWorkflow,new Ee.StatusTimestampService(b));dV(M,{vaultAdapter:b,fsAdapter:n,genericAssetCreationService:ce,archiveAssetService:q,taskStatusService:ye,propertyCleanupService:oe,fixMissingLabelService:X,renameToUidService:J,folderRepairService:_});let ze=new Ee.NamedQueryRunner(new cp(e,n),e),Z=await new Ee.GroundingExecutor(n,n,M,(0,Ee.createVaultFrontmatterClassLabelResolver)(n),{clock:c,uidGenerator:l,workflowResolver:t,groundingLoader:a(W=>p.loadGroundingByUid(W),"groundingLoader"),templateLoader:a(async W=>{let z=await n.findFileByUID(W);return z?(0,Ee.stripTemplateFrontmatter)(await n.readFile(z)):null},"templateLoader"),namedQueryRunner:ze,refToFolder:(0,Ee.createVaultFrontmatterRefToFolderResolver)(n),refToFrontmatter:(0,Ee.createVaultFrontmatterRefToFrontmatterResolver)(n),declaredRanges:(0,Ee.createTripleStoreDeclaredRanges)(e)}).execute(h.grounding,m,d,ee);if(Z.success){let W=[];Z.openPath&&W.push(Z.openPath),Z.createdPaths&&W.push(...Z.createdPaths);let z=[],re=new Set;for(let Ce of W)re.has(Ce)||(re.add(Ce),z.push(q_e(b,Ce)));if(!o.json){let Ce=h.successMessage??`Applied "${h.name}" to "${d}".`,j=Z.openPath??Z.createdPaths?.[0],fe=j?` \u2192 ${j}`:"";console.log(`\u2705 ${Ce}${fe}`)}return{ok:!0,created:z,executed:!0}}else return console.error(`\u274C "${h.name}" failed on "${d}": ${Z.error}`),{ok:!1,created:[],executed:!0}}a(Y_e,"executeOnTarget");function hV(){return new pe("apply").description("Apply an exocmd__Command to one or more vault assets (RFC 8e83442b T1.2). Pass a path arg or pipe paths via stdin.").argument("<cmd>","Command UUID or cliName slug").argument("[path]","Vault-relative path to target asset (omit to read paths from stdin)").option("--vault <path>","Path to Obsidian vault",process.cwd()).option("--dry-run","Preview without writing").option("--yes","Skip destructive-command confirmation").option("--input <json>",`JSON userInput for a grounding. Value-setting commands need a value key, e.g. set-planned-start / set-scheduled-date: --input '{"value":"<ISO>"}'. A command whose grounding declares its own input key uses THAT key: set-label: --input '{"label":"New label"}' (set-label-keep-alias, which also keeps the previous label as an alias, takes the same key). Asset-reference inputs (set-parent: --input '{"parent":"<uid>"}'; set-blocker: --input '{"blocker":"<uid>"}'; set-ontology: --input '{"ontology":"<uid>"}') take a BARE uid; a copied [[uid]] or [[uid|alias]] is accepted and unwrapped, anything else that still looks like a link is refused. The required key is named in the error if omitted.`).option("--seed <uuid>","Deterministic UID seed for test/replay (uses seededUidGenerator)").option("--frozen-clock <iso>","Freeze clock to ISO timestamp for test/replay (uses frozenClock)").option("--json","Emit a machine-readable JSON result ({command,target,created:[{uuid,path,label}]}) instead of human-readable output").option("--use-cache","Use the persistent triple cache (hit / delta / rebuild) instead of a full vault parse; a mutation is picked up by the NEXT --use-cache process as a delta unless --write-through is also given").option("--write-through","With --use-cache: after a grounding executed, fold the mutation into the persistent cache in this process, so the next --use-cache process is a plain hit (the delta is paid by this writer instead of the next reader). Refused without --use-cache").action(async(r,e,t)=>{if(ue.setFormat("text"),t.writeThrough&&!t.useCache){process.stderr.write(`\u274C --write-through requires --use-cache (there is no cache to write through to without it); nothing was applied
|
|
632
632
|
`),process.exit(2);return}try{let n=(0,rc.resolve)(t.vault);if(!(0,nF.existsSync)(n))throw new Le(n);up(n);let i=t.frozenClock?(0,Ee.frozenClock)(t.frozenClock):(0,Ee.liveClock)(),s=t.seed?(0,Ee.seededUidGenerator)(t.seed):(0,Ee.liveUidGenerator)(),o=t.useCache??!1,c=await bi(n,{useCache:o});o&&process.stderr.write(`${Eu(c)}
|
|
633
633
|
`);let l=new Ee.InMemoryTripleStore;await l.addAll(c.triples);let u=new TE(n,{explicitTriples:c.triples.slice(0,c.explicitCount),zeroTriplePaths:c.zeroTriplePaths}),f=new Ee.WorkflowResolver(l),d;if(W_e.test(r))d=r;else{let _=await H_e(l,r);_||(console.error(`\u274C No command found with UUID or cliName "${r}".`),process.exit(3)),d=_}let p;if(e)p=[e];else if(p=await z_e(),p.length===0)throw new Ye("No target path provided and stdin is empty.","exocortex apply <uuid> <path> OR exocortex find ... | exocortex apply <uuid>");let h=0,g=0,m=!1,b=[];for(let _ of p){let S=await Y_e(n,l,f,u,d,_,t,i,s);S.ok?h++:g++,S.executed&&(m=!0),b.push(...S.created)}if(o&&t.writeThrough&&m&&c.cacheManager){let _=await qP(c.cacheManager);process.stderr.write(`${WP(_)}
|
|
634
634
|
`)}if(p.length>1&&!t.json&&console.log(`
|
|
@@ -705,7 +705,7 @@ Next steps:
|
|
|
705
705
|
`).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(Rwe,"parseLastJsonLine");function SG(r,e){return e.filter(t=>{let n=r[t];return typeof n!="string"||n.trim().length===0})}a(SG,"missingStringFields");var zE=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:_G,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:_G,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:Awe,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:bG}};case"tools/call":return{jsonrpc:"2.0",id:i,result:await this.callTool(e.params??{})};default:return{jsonrpc:"2.0",id:i,error:{code:Iwe,message:`Method not found: ${e.method}`}}}}async callTool(e){let t=e.name,n=e.arguments??{},i;if(t==="create_asset"){let c=SG(n,["vault","class","label"]);if(c.length>0)return Tp(`create_asset: missing required argument(s): ${c.join(", ")}`,!0);let l=mG(n);if(l!==null)return Tp(`create_asset: ${l}`,!0);i=gG(n)}else if(t==="create_effort"){let c=SG(n,["vault","command","target"]);if(c.length>0)return Tp(`create_effort: missing required argument(s): ${c.join(", ")}`,!0);i=yG(n)}else return Tp(`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 Tp(`exocortex-cli exited ${s.exitCode}
|
|
706
706
|
${c}`,!0)}let o=Rwe(s.stdout);return Tp(o===void 0?s.stdout.trim():JSON.stringify(o))}};var vG=require("child_process");var Cwe=32*1024*1024;function TG(r){return e=>new Promise(t=>{(0,vG.execFile)(process.execPath,[r,...e],{maxBuffer:Cwe},(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(TG,"createSelfCliRunner");async function xwe(r,e,t){let n=(0,AG.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:wG,message:"Parse error: invalid JSON"}})+`
|
|
707
707
|
`);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:EG,message:`Internal error: ${l instanceof Error?l.message:String(l)}`}}}c!==null&&t(JSON.stringify(c)+`
|
|
708
|
-
`)}}a(xwe,"runStdioServer");function IG(r){return new pe("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 zE({runCli:TG(t),version:r??"unknown"});await xwe(n,process.stdin,i=>process.stdout.write(i))})}a(IG,"mcpCommand");function HE(r){let e=new pe;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more").version(r??"17.
|
|
708
|
+
`)}}a(xwe,"runStdioServer");function IG(r){return new pe("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 zE({runCli:TG(t),version:r??"unknown"});await xwe(n,process.stdin,i=>process.stdout.write(i))})}a(IG,"mcpCommand");function HE(r){let e=new pe;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more").version(r??"17.1.0"),e.addCommand(iV()),e.addCommand(hV()),e.addCommand($8()),e.addCommand(G8()),e.addCommand(u7()),e.addCommand(q8()),e.addCommand(Y8()),e.addCommand(X8()),e.addCommand(b7()),e.addCommand(v7()),e.addCommand(V7()),e.addCommand(H7()),e.addCommand(Q7()),e.addCommand(J7()),e.addCommand(eV()),e.addCommand(tV()),e.addCommand(MV()),e.addCommand(UV()),e.addCommand(nG()),e.addCommand(sG()),e.addCommand(cG()),e.addCommand(lG()),e.addCommand(dG()),e.addCommand(zV()),e.addCommand(eG()),e.addCommand(pG()),e.addCommand(IG(r??"17.1.0")),e}a(HE,"createProgram");HE().parse();0&&(module.exports={createProgram});
|
|
709
709
|
/*! Bundled license information:
|
|
710
710
|
|
|
711
711
|
reflect-metadata/Reflect.js:
|