@kitelev/exocortex-cli 16.96.11 → 16.96.13

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 v16.96.11
2
+ // @kitelev/exocortex-cli v16.96.13
3
3
  // CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
4
4
  // License: MIT
5
5
 
@@ -775,7 +775,7 @@ Next steps:
775
775
  `),process.stdout.write(` File: ${e.file}
776
776
  `),process.stdout.write(` Commit: ${e.sha}
777
777
  `),process.stdout.write(` URL: ${e.url}
778
- `)),process.exit(0)}catch(e){let t=e instanceof Error?e:new Error(String(e)),r=new vi;t.message=r.redact(t.message),t.stack&&(t.stack=r.redact(t.stack)),le.handle(t)}})}a(Mie,"restPushCommand");var jo=require("node:fs"),A4=require("node:crypto"),Ei=J(require("node:path"));var Ti=J(tt());var jie=a(async n=>{let e=await A4.webcrypto.subtle.digest("SHA-1",n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")},"nodeSha1"),$ie={parse:a(n=>Nt.load(n,{schema:Nt.CORE_SCHEMA}),"parse"),stringify:a(n=>Nt.dump(n,{schema:Nt.CORE_SCHEMA,lineWidth:-1}),"stringify")};function Uie(n,e){if(n.tokenFromGh===!0)return vi.resolveGhToken(e.ghTokenRunner);let t=e.env??process.env,r=n.token||t.GITHUB_TOKEN||t.GH_TOKEN||"";if(r.length===0)throw new Error("A GitHub token is required (private sync units read as 404 without one). Use --token-from-gh, --token <pat>, or set GITHUB_TOKEN / GH_TOKEN.");return r}a(Uie,"resolveToken");function Bie(n){let e=a(r=>Ei.join(n,r),"abs"),t=a(async(r,i)=>{let s;try{s=await jo.promises.readdir(r,{withFileTypes:!0})}catch{return}for(let o of s){let c=Ei.join(r,o.name);if(o.isDirectory()){if(o.name===".git")continue;await t(c,i)}else o.isFile()&&i.push(Ei.relative(n,c).split(Ei.sep).join("/"))}},"walk");return{async list(){let r=[];return(0,jo.existsSync)(n)&&await t(n,r),r},read:a(r=>jo.promises.readFile(e(r),"utf-8"),"read"),async readBinary(r){return new Uint8Array(await jo.promises.readFile(e(r)))},async write(){throw new Error("exosync-parity is read-only \u2014 write refused")},async delete(){throw new Error("exosync-parity is read-only \u2014 delete refused")}}}a(Bie,"nodeLocalFilesPort");function mA(n){let e=new dt(n),t=new Ti.SpaceSpecAccumulator;for(let r of e.getAllFiles()){let i=e.getFrontmatter(r);if(!i)continue;let s=(0,Ti.classifySpaceDeclaration)(i,r.path);if(s.kind==="not-space"||(s.warning!==void 0&&t.warnings.push(s.warning),s.kind==="skip"))continue;let o=t.offer(s.candidate);o!==null&&(0,jo.existsSync)(Ei.join(n,o.localPath))&&t.commit(s.candidate)}return{specs:t.specs,warnings:t.warnings}}a(mA,"collectVaultSpecs");function Vie(n,e){for(let t of n.repos){let r=t.headSha!==void 0?` @${t.headSha.slice(0,7)}`:"";e(`${t.repoKey}${r}: ${t.status} \u2014 ${t.inParity}/${t.filesChecked} in parity, M2 diffs ${t.m2SemanticDiffs}, accounted ${t.accountedCount}, M1 violations ${t.m1Violations.length}${t.attachmentHashSetIdentical!==void 0?`, attachment hash-set ${t.attachmentHashSetIdentical?"identical":"DIFFERS"}`:""}`),t.detail!==void 0&&e(` ${t.detail}`);for(let i of t.warnings)e(` warn: ${i}`);for(let i of t.discrepancies)e(` ${i.cls}: ${i.path}${i.detail!==void 0?` (${i.detail})`:""}`);for(let i of t.m1Violations)e(` M1 VIOLATION: ${i.path} \u2014 ${i.detail}`)}e((0,Ti.summarizeParityRound)(n))}a(Vie,"printHumanReport");async function Gie(n,e={}){let t=e.out??(y=>console.log(y)),r=Ei.resolve(n.vault);if(!(0,jo.existsSync)(r))throw new Error(`Vault path does not exist: ${r}`);let i=Uie(n,e),s=new vi({token:i,...n.apiBase!==void 0?{apiBase:n.apiBase}:{}}),o=e.transportFactory?.(i,n.apiBase)??s.transport(),{specs:c,warnings:l}=mA(r);for(let y of l)t(`warn: ${y}`);if(c.length===0)return t("Nothing to check \u2014 no materialized AssetSpaces with a GitHub source found in this vault."),2;let u=n.configDir??".obsidian",f=Ei.join(r,u,"plugins","exocortex",Ti.WATERMARK_STORE_FILENAME),d=new Ti.FileWatermarkStore({read:a(async()=>{try{return await jo.promises.readFile(f,"utf-8")}catch{return null}},"read"),writeAtomic:a(async()=>{throw new Error("exosync-parity: watermark access is read-only by contract")},"writeAtomic")}),h=new Ti.ParityValidator({transport:o,sha1:jie,localFilesFor:a(y=>Bie(Ei.join(r,y.localPath)),"localFilesFor"),watermarks:{get:a(y=>d.get(y),"get")},yaml:$ie,redact:a(y=>s.redact(y),"redact"),...n.apiBase!==void 0?{baseURL:n.apiBase}:{}});t(`ExoSync parity check: ${c.length} repo(s), vault ${r}`);let p=await h.runRound(c,{trigger:"standalone"});return n.json===!0?t(JSON.stringify(p,null,2)):Vie(p,t),p.vacuous?2:p.ok?0:1}a(Gie,"runExosyncParity");function I4(){return new Ae("exosync-parity").description("ExoSync M1/M2 parity report: compare materialized sync units against their remote heads (read-only; RFC 4e4dc453 Phase E)").requiredOption("--vault <path>","Vault root path").option("--config-dir <name>","Obsidian config dir name (watermark location)",".obsidian").option("--json","Print the full round record as JSON").option("--token <pat>","GitHub PAT (or env GITHUB_TOKEN / GH_TOKEN). Prefer --token-from-gh.").option("--token-from-gh","Resolve the PAT via `gh auth token`").option("--api-base <url>","GitHub API base (testing)").action(async n=>{try{process.exitCode=await Gie(n)}catch(e){le.handle(e,{command:"exosync-parity"}),process.exitCode=1}})}a(I4,"exosyncParityCommand");var Dr=require("node:fs"),R4=require("node:crypto"),xn=J(require("node:path"));var Fr=J(tt());var x4=a(async n=>{let e=await R4.webcrypto.subtle.digest("SHA-1",n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")},"nodeSha1"),qie={parse:a(n=>Nt.load(n,{schema:Nt.CORE_SCHEMA}),"parse"),stringify:a(n=>Nt.dump(n,{schema:Nt.CORE_SCHEMA,lineWidth:-1}),"stringify")};function Wie(n,e){if(n.tokenFromGh===!0)return vi.resolveGhToken(e.ghTokenRunner);let t=e.env??process.env,r=n.token||t.GITHUB_TOKEN||t.GH_TOKEN||"";if(r.length===0)throw new Error("A GitHub token is required (private sync units read as 404 and push needs write scope). Use --token-from-gh, --token <pat>, or set GITHUB_TOKEN / GH_TOKEN.");return r}a(Wie,"resolveToken");function zie(n){let e=/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/.exec(n.trim());if(e===null)throw new Error(`Invalid quarantine repo URL (expected https://github.com/<owner>/<repo>): ${n}`);return{owner:e[1],repo:e[2]}}a(zie,"parseGitHubRepoUrl");function Hie(n){let e=a(i=>xn.join(n,i),"abs"),t=a(async(i,s)=>{let o;try{o=await Dr.promises.readdir(i,{withFileTypes:!0})}catch{return}for(let c of o){let l=xn.join(i,c.name);if(c.isDirectory()){if(c.name===".git")continue;await t(l,s)}else c.isFile()&&s.push(xn.relative(n,l).split(xn.sep).join("/"))}},"walk"),r=a(async(i,s)=>{let o=xn.dirname(i);await Dr.promises.mkdir(o,{recursive:!0});let c=`${i}.local.tmp`;await s(c),await Dr.promises.rename(c,i)},"writeAtomic");return{async list(){let i=[];return(0,Dr.existsSync)(n)&&await t(n,i),i},read:a(i=>Dr.promises.readFile(e(i),"utf-8"),"read"),async write(i,s){await r(e(i),o=>Dr.promises.writeFile(o,s,"utf-8"))},async delete(i){await Dr.promises.rm(e(i),{force:!0})},async readBinary(i){return new Uint8Array(await Dr.promises.readFile(e(i)))},async writeBinary(i,s){let o=s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength);await r(e(i),c=>Dr.promises.writeFile(c,Buffer.from(o)))}}}a(Hie,"nodeLocalFilesPort");function Kie(n){return{async read(){try{return await Dr.promises.readFile(n,"utf-8")}catch{return null}},async writeAtomic(e){await Dr.promises.mkdir(xn.dirname(n),{recursive:!0});let t=`${n}.local.tmp`;await Dr.promises.writeFile(t,e,"utf-8"),await Dr.promises.rename(t,n)}}}a(Kie,"nodeWatermarkFileIO");function Qie(n){return{async check(e){let t=xn.join(n,e.localPath);if(!(0,Dr.existsSync)(t))return{fullyMaterialized:!1,reason:`mount folder ${e.localPath} does not exist`};let r=0;try{r=(await Dr.promises.readdir(t)).length}catch{return{fullyMaterialized:!1,reason:`mount folder ${e.localPath} is not readable`}}return r===0&&e.spaceKind!=="file"?{fullyMaterialized:!1,reason:`mount folder ${e.localPath} is empty (mid-mount?)`}:{fullyMaterialized:!0}}}}a(Qie,"nodeMaterializationCheck");function Xie(n,e){let t=n.pushedSha!==void 0?` \u2192@${n.pushedSha.slice(0,7)}`:"";e(`${n.repoKey}${t}: ${n.status} \u2014 pulled ${n.pulledCount}, pushed ${n.pushedCount}, merged ${n.mergedCount}, quarantined ${n.quarantinedCount}${(n.pushedDeletes?.length??0)>0?`, deleted ${n.pushedDeletes.length}`:""}`),n.detail!==void 0&&e(` ${n.detail}`);for(let r of n.warnings)e(` warn: ${r}`);(n.deferredPaths?.length??0)>0&&e(` deferred (\u2192 full sync): ${n.deferredPaths.join(", ")}`),(n.deferredDeletes?.length??0)>0&&e(` deferred deletes: ${n.deferredDeletes.join(", ")}`)}a(Xie,"printRepoResult");function Yie(n){return n==="conflict"||n==="full-conflict"||n==="retry-exhausted"||n==="busy"||n==="auth-required"||n==="error"}a(Yie,"isFailureStatus");async function Jie(n,e,t={}){let r=t.out??(_=>console.log(_)),i=xn.resolve(e.vault);if(!(0,Dr.existsSync)(i))throw new Error(`Vault path does not exist: ${i}`);let s=Wie(e,t),o=new vi({token:s,...e.apiBase!==void 0?{apiBase:e.apiBase}:{}}),c=t.transportFactory?.(s,e.apiBase)??o.transport(),{specs:l,warnings:u}=mA(i);for(let _ of u)r(`warn: ${_}`);if(l.length===0)return r("Nothing to sync \u2014 no materialized AssetSpaces with a GitHub source found in this vault."),2;let f=e.configDir??".obsidian",d=xn.join(i,f,"plugins","exocortex",Fr.WATERMARK_STORE_FILENAME),h,p=e.quarantineRepo?.trim()??"";if(p.length>0){let{owner:_,repo:S}=zie(p);h=new Fr.SyncedQuarantineStore({transport:(0,Fr.withRateLimitBackoff)(c),sha1:x4,owner:_,repo:S,branch:Fr.SYNC_BRANCH,redact:a(T=>o.redact(T),"redact")})}let y=new Fr.SyncEngine({transport:c,watermarkStore:new Fr.FileWatermarkStore(Kie(d)),materializationCheck:Qie(i),localFilesFor:a(_=>Hie(xn.join(i,_.localPath)),"localFilesFor"),sha1:x4,redact:a(_=>o.redact(_),"redact"),commitMessage:a((_,S,T=0)=>`exosync: ${S} change(s)${T>0?`, ${T} deletion(s)`:""} (CLI)`,"commitMessage"),mergeLayer:new Fr.GatedStructuredMerger(new Fr.StructuredMerger(qie)),...h!==void 0?{quarantine:h}:{},...e.apiBase!==void 0?{baseURL:e.apiBase}:{}});r(`ExoSync ${n}: ${l.length} repo(s), vault ${i}${h!==void 0?" (quarantine configured)":""}`);let g=(0,Fr.orderChildrenFirst)(l),v=await y.syncAll(g,n);if(e.json===!0)r(JSON.stringify(v,null,2));else{for(let S of v)Xie(S,r);let _=v.reduce((S,T)=>({pulled:S.pulled+T.pulledCount,pushed:S.pushed+T.pushedCount,merged:S.merged+T.mergedCount,quarantined:S.quarantined+T.quarantinedCount}),{pulled:0,pushed:0,merged:0,quarantined:0});r(`Summary: ${v.length} repo(s) \u2014 pulled ${_.pulled}, pushed ${_.pushed}, merged ${_.merged}, quarantined ${_.quarantined}`)}return v.some(_=>Yie(_.status))?1:0}a(Jie,"runExosyncSync");function gA(n){return n.requiredOption("--vault <path>","Vault root path").option("--config-dir <name>","Obsidian config dir name (watermark location)",".obsidian").option("--quarantine-repo <url>","Quarantine repo URL (https://github.com/<owner>/<repo>) \u2014 required for FileSpaces").option("--token <pat>","GitHub PAT (or env GITHUB_TOKEN / GH_TOKEN). Prefer --token-from-gh.").option("--token-from-gh","Resolve the PAT via `gh auth token`").option("--json","Print the full per-repo result array as JSON").option("--api-base <url>","GitHub API base (testing)")}a(gA,"withSyncOptions");function yA(n){return async e=>{try{process.exitCode=await Jie(n,e)}catch(t){le.handle(t,{command:`exosync ${n}`}),process.exitCode=1}}}a(yA,"makeDirectionAction");function P4(){let n=new Ae("exosync").description("ExoSync over the GitHub REST API: sync/pull/push the materialized AssetSpace set (CLI parity with the plugin; RFC 4e4dc453 Phase B). Read-only divergence check: `exosync-parity`.");return gA(n.command("sync").description("Full pull\u2192merge\u2192push cycle for every materialized repo")).action(yA("sync")),gA(n.command("pull").description("Apply remote changes only (nothing leaves the device; local changes re-derive)")).action(yA("pull")),gA(n.command("push").description("Send the local delta only (remote changes are pinned to re-derive on the next pull/sync)")).action(yA("push")),n}a(P4,"exosyncCommand");function C4(n){let e=new Ae;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.96.11"),e.addCommand(LM()),e.addCommand(qM()),e.addCommand(Ik()),e.addCommand(Pk()),e.addCommand(iM()),e.addCommand(Fk()),e.addCommand(Lk()),e.addCommand($k()),e.addCommand(aM()),e.addCommand(gM()),e.addCommand(bM()),e.addCommand(EM()),e.addCommand(FM()),e.addCommand(s4()),e.addCommand(f4()),e.addCommand(d4()),e.addCommand(m4()),e.addCommand(_4()),e.addCommand(T4()),e.addCommand(I4()),e.addCommand(P4()),e}a(C4,"createProgram");C4().parse();0&&(module.exports={createProgram});
778
+ `)),process.exit(0)}catch(e){let t=e instanceof Error?e:new Error(String(e)),r=new vi;t.message=r.redact(t.message),t.stack&&(t.stack=r.redact(t.stack)),le.handle(t)}})}a(Mie,"restPushCommand");var jo=require("node:fs"),A4=require("node:crypto"),Ei=J(require("node:path"));var Ti=J(tt());var jie=a(async n=>{let e=await A4.webcrypto.subtle.digest("SHA-1",n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")},"nodeSha1"),$ie={parse:a(n=>Nt.load(n,{schema:Nt.CORE_SCHEMA}),"parse"),stringify:a(n=>Nt.dump(n,{schema:Nt.CORE_SCHEMA,lineWidth:-1}),"stringify")};function Uie(n,e){if(n.tokenFromGh===!0)return vi.resolveGhToken(e.ghTokenRunner);let t=e.env??process.env,r=n.token||t.GITHUB_TOKEN||t.GH_TOKEN||"";if(r.length===0)throw new Error("A GitHub token is required (private sync units read as 404 without one). Use --token-from-gh, --token <pat>, or set GITHUB_TOKEN / GH_TOKEN.");return r}a(Uie,"resolveToken");function Bie(n){let e=a(r=>Ei.join(n,r),"abs"),t=a(async(r,i)=>{let s;try{s=await jo.promises.readdir(r,{withFileTypes:!0})}catch{return}for(let o of s){let c=Ei.join(r,o.name);if(o.isDirectory()){if(o.name===".git")continue;await t(c,i)}else o.isFile()&&i.push(Ei.relative(n,c).split(Ei.sep).join("/"))}},"walk");return{async list(){let r=[];return(0,jo.existsSync)(n)&&await t(n,r),r},read:a(r=>jo.promises.readFile(e(r),"utf-8"),"read"),async readBinary(r){return new Uint8Array(await jo.promises.readFile(e(r)))},async write(){throw new Error("exosync-parity is read-only \u2014 write refused")},async delete(){throw new Error("exosync-parity is read-only \u2014 delete refused")}}}a(Bie,"nodeLocalFilesPort");function mA(n){let e=new dt(n),t=new Ti.SpaceSpecAccumulator;for(let r of e.getAllFiles()){let i=e.getFrontmatter(r);if(!i)continue;let s=(0,Ti.classifySpaceDeclaration)(i,r.path);if(s.kind==="not-space"||(s.warning!==void 0&&t.warnings.push(s.warning),s.kind==="skip"))continue;let o=t.offer(s.candidate);o!==null&&(0,jo.existsSync)(Ei.join(n,o.localPath))&&t.commit(s.candidate)}return{specs:t.specs,warnings:t.warnings}}a(mA,"collectVaultSpecs");function Vie(n,e){for(let t of n.repos){let r=t.headSha!==void 0?` @${t.headSha.slice(0,7)}`:"";e(`${t.repoKey}${r}: ${t.status} \u2014 ${t.inParity}/${t.filesChecked} in parity, M2 diffs ${t.m2SemanticDiffs}, accounted ${t.accountedCount}, M1 violations ${t.m1Violations.length}${t.attachmentHashSetIdentical!==void 0?`, attachment hash-set ${t.attachmentHashSetIdentical?"identical":"DIFFERS"}`:""}`),t.detail!==void 0&&e(` ${t.detail}`);for(let i of t.warnings)e(` warn: ${i}`);for(let i of t.discrepancies)e(` ${i.cls}: ${i.path}${i.detail!==void 0?` (${i.detail})`:""}`);for(let i of t.m1Violations)e(` M1 VIOLATION: ${i.path} \u2014 ${i.detail}`)}e((0,Ti.summarizeParityRound)(n))}a(Vie,"printHumanReport");async function Gie(n,e={}){let t=e.out??(y=>console.log(y)),r=Ei.resolve(n.vault);if(!(0,jo.existsSync)(r))throw new Error(`Vault path does not exist: ${r}`);let i=Uie(n,e),s=new vi({token:i,...n.apiBase!==void 0?{apiBase:n.apiBase}:{}}),o=e.transportFactory?.(i,n.apiBase)??s.transport(),{specs:c,warnings:l}=mA(r);for(let y of l)t(`warn: ${y}`);if(c.length===0)return t("Nothing to check \u2014 no materialized AssetSpaces with a GitHub source found in this vault."),2;let u=n.configDir??".obsidian",f=Ei.join(r,u,"plugins","exocortex",Ti.WATERMARK_STORE_FILENAME),d=new Ti.FileWatermarkStore({read:a(async()=>{try{return await jo.promises.readFile(f,"utf-8")}catch{return null}},"read"),writeAtomic:a(async()=>{throw new Error("exosync-parity: watermark access is read-only by contract")},"writeAtomic")}),h=new Ti.ParityValidator({transport:o,sha1:jie,localFilesFor:a(y=>Bie(Ei.join(r,y.localPath)),"localFilesFor"),watermarks:{get:a(y=>d.get(y),"get")},yaml:$ie,redact:a(y=>s.redact(y),"redact"),...n.apiBase!==void 0?{baseURL:n.apiBase}:{}});t(`ExoSync parity check: ${c.length} repo(s), vault ${r}`);let p=await h.runRound(c,{trigger:"standalone"});return n.json===!0?t(JSON.stringify(p,null,2)):Vie(p,t),p.vacuous?2:p.ok?0:1}a(Gie,"runExosyncParity");function I4(){return new Ae("exosync-parity").description("ExoSync M1/M2 parity report: compare materialized sync units against their remote heads (read-only; RFC 4e4dc453 Phase E)").requiredOption("--vault <path>","Vault root path").option("--config-dir <name>","Obsidian config dir name (watermark location)",".obsidian").option("--json","Print the full round record as JSON").option("--token <pat>","GitHub PAT (or env GITHUB_TOKEN / GH_TOKEN). Prefer --token-from-gh.").option("--token-from-gh","Resolve the PAT via `gh auth token`").option("--api-base <url>","GitHub API base (testing)").action(async n=>{try{process.exitCode=await Gie(n)}catch(e){le.handle(e,{command:"exosync-parity"}),process.exitCode=1}})}a(I4,"exosyncParityCommand");var Dr=require("node:fs"),R4=require("node:crypto"),xn=J(require("node:path"));var Fr=J(tt());var x4=a(async n=>{let e=await R4.webcrypto.subtle.digest("SHA-1",n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")},"nodeSha1"),qie={parse:a(n=>Nt.load(n,{schema:Nt.CORE_SCHEMA}),"parse"),stringify:a(n=>Nt.dump(n,{schema:Nt.CORE_SCHEMA,lineWidth:-1}),"stringify")};function Wie(n,e){if(n.tokenFromGh===!0)return vi.resolveGhToken(e.ghTokenRunner);let t=e.env??process.env,r=n.token||t.GITHUB_TOKEN||t.GH_TOKEN||"";if(r.length===0)throw new Error("A GitHub token is required (private sync units read as 404 and push needs write scope). Use --token-from-gh, --token <pat>, or set GITHUB_TOKEN / GH_TOKEN.");return r}a(Wie,"resolveToken");function zie(n){let e=/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/.exec(n.trim());if(e===null)throw new Error(`Invalid quarantine repo URL (expected https://github.com/<owner>/<repo>): ${n}`);return{owner:e[1],repo:e[2]}}a(zie,"parseGitHubRepoUrl");function Hie(n){let e=a(i=>xn.join(n,i),"abs"),t=a(async(i,s)=>{let o;try{o=await Dr.promises.readdir(i,{withFileTypes:!0})}catch{return}for(let c of o){let l=xn.join(i,c.name);if(c.isDirectory()){if(c.name===".git")continue;await t(l,s)}else c.isFile()&&s.push(xn.relative(n,l).split(xn.sep).join("/"))}},"walk"),r=a(async(i,s)=>{let o=xn.dirname(i);await Dr.promises.mkdir(o,{recursive:!0});let c=`${i}.local.tmp`;await s(c),await Dr.promises.rename(c,i)},"writeAtomic");return{async list(){let i=[];return(0,Dr.existsSync)(n)&&await t(n,i),i},read:a(i=>Dr.promises.readFile(e(i),"utf-8"),"read"),async write(i,s){await r(e(i),o=>Dr.promises.writeFile(o,s,"utf-8"))},async delete(i){await Dr.promises.rm(e(i),{force:!0})},async readBinary(i){return new Uint8Array(await Dr.promises.readFile(e(i)))},async writeBinary(i,s){let o=s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength);await r(e(i),c=>Dr.promises.writeFile(c,Buffer.from(o)))}}}a(Hie,"nodeLocalFilesPort");function Kie(n){return{async read(){try{return await Dr.promises.readFile(n,"utf-8")}catch{return null}},async writeAtomic(e){await Dr.promises.mkdir(xn.dirname(n),{recursive:!0});let t=`${n}.local.tmp`;await Dr.promises.writeFile(t,e,"utf-8"),await Dr.promises.rename(t,n)}}}a(Kie,"nodeWatermarkFileIO");function Qie(n){return{async check(e){let t=xn.join(n,e.localPath);if(!(0,Dr.existsSync)(t))return{fullyMaterialized:!1,reason:`mount folder ${e.localPath} does not exist`};let r=0;try{r=(await Dr.promises.readdir(t)).length}catch{return{fullyMaterialized:!1,reason:`mount folder ${e.localPath} is not readable`}}return r===0&&e.spaceKind!=="file"?{fullyMaterialized:!1,reason:`mount folder ${e.localPath} is empty (mid-mount?)`}:{fullyMaterialized:!0}}}}a(Qie,"nodeMaterializationCheck");function Xie(n,e){let t=n.pushedSha!==void 0?` \u2192@${n.pushedSha.slice(0,7)}`:"";e(`${n.repoKey}${t}: ${n.status} \u2014 pulled ${n.pulledCount}, pushed ${n.pushedCount}, merged ${n.mergedCount}, quarantined ${n.quarantinedCount}${(n.pushedDeletes?.length??0)>0?`, deleted ${n.pushedDeletes.length}`:""}`),n.detail!==void 0&&e(` ${n.detail}`);for(let r of n.warnings)e(` warn: ${r}`);(n.deferredPaths?.length??0)>0&&e(` deferred (\u2192 full sync): ${n.deferredPaths.join(", ")}`),(n.deferredDeletes?.length??0)>0&&e(` deferred deletes: ${n.deferredDeletes.join(", ")}`)}a(Xie,"printRepoResult");function Yie(n){return n==="conflict"||n==="full-conflict"||n==="retry-exhausted"||n==="busy"||n==="auth-required"||n==="error"}a(Yie,"isFailureStatus");async function Jie(n,e,t={}){let r=t.out??(_=>console.log(_)),i=xn.resolve(e.vault);if(!(0,Dr.existsSync)(i))throw new Error(`Vault path does not exist: ${i}`);let s=Wie(e,t),o=new vi({token:s,...e.apiBase!==void 0?{apiBase:e.apiBase}:{}}),c=t.transportFactory?.(s,e.apiBase)??o.transport(),{specs:l,warnings:u}=mA(i);for(let _ of u)r(`warn: ${_}`);if(l.length===0)return r("Nothing to sync \u2014 no materialized AssetSpaces with a GitHub source found in this vault."),2;let f=e.configDir??".obsidian",d=xn.join(i,f,"plugins","exocortex",Fr.WATERMARK_STORE_FILENAME),h,p=e.quarantineRepo?.trim()??"";if(p.length>0){let{owner:_,repo:S}=zie(p);h=new Fr.SyncedQuarantineStore({transport:(0,Fr.withRateLimitBackoff)(c),sha1:x4,owner:_,repo:S,branch:Fr.SYNC_BRANCH,redact:a(T=>o.redact(T),"redact")})}let y=new Fr.SyncEngine({transport:c,watermarkStore:new Fr.FileWatermarkStore(Kie(d)),materializationCheck:Qie(i),localFilesFor:a(_=>Hie(xn.join(i,_.localPath)),"localFilesFor"),sha1:x4,redact:a(_=>o.redact(_),"redact"),commitMessage:a((_,S,T=0)=>`exosync: ${S} change(s)${T>0?`, ${T} deletion(s)`:""} (CLI)`,"commitMessage"),mergeLayer:new Fr.GatedStructuredMerger(new Fr.StructuredMerger(qie)),...h!==void 0?{quarantine:h}:{},...e.apiBase!==void 0?{baseURL:e.apiBase}:{}});r(`ExoSync ${n}: ${l.length} repo(s), vault ${i}${h!==void 0?" (quarantine configured)":""}`);let g=(0,Fr.orderChildrenFirst)(l),v=await y.syncAll(g,n);if(e.json===!0)r(JSON.stringify(v,null,2));else{for(let S of v)Xie(S,r);let _=v.reduce((S,T)=>({pulled:S.pulled+T.pulledCount,pushed:S.pushed+T.pushedCount,merged:S.merged+T.mergedCount,quarantined:S.quarantined+T.quarantinedCount}),{pulled:0,pushed:0,merged:0,quarantined:0});r(`Summary: ${v.length} repo(s) \u2014 pulled ${_.pulled}, pushed ${_.pushed}, merged ${_.merged}, quarantined ${_.quarantined}`)}return v.some(_=>Yie(_.status))?1:0}a(Jie,"runExosyncSync");function gA(n){return n.requiredOption("--vault <path>","Vault root path").option("--config-dir <name>","Obsidian config dir name (watermark location)",".obsidian").option("--quarantine-repo <url>","Quarantine repo URL (https://github.com/<owner>/<repo>) \u2014 required for FileSpaces").option("--token <pat>","GitHub PAT (or env GITHUB_TOKEN / GH_TOKEN). Prefer --token-from-gh.").option("--token-from-gh","Resolve the PAT via `gh auth token`").option("--json","Print the full per-repo result array as JSON").option("--api-base <url>","GitHub API base (testing)")}a(gA,"withSyncOptions");function yA(n){return async e=>{try{process.exitCode=await Jie(n,e)}catch(t){le.handle(t,{command:`exosync ${n}`}),process.exitCode=1}}}a(yA,"makeDirectionAction");function P4(){let n=new Ae("exosync").description("ExoSync over the GitHub REST API: sync/pull/push the materialized AssetSpace set (CLI parity with the plugin; RFC 4e4dc453 Phase B). Read-only divergence check: `exosync-parity`.");return gA(n.command("sync").description("Full pull\u2192merge\u2192push cycle for every materialized repo")).action(yA("sync")),gA(n.command("pull").description("Apply remote changes only (nothing leaves the device; local changes re-derive)")).action(yA("pull")),gA(n.command("push").description("Send the local delta only (remote changes are pinned to re-derive on the next pull/sync)")).action(yA("push")),n}a(P4,"exosyncCommand");function C4(n){let e=new Ae;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.96.13"),e.addCommand(LM()),e.addCommand(qM()),e.addCommand(Ik()),e.addCommand(Pk()),e.addCommand(iM()),e.addCommand(Fk()),e.addCommand(Lk()),e.addCommand($k()),e.addCommand(aM()),e.addCommand(gM()),e.addCommand(bM()),e.addCommand(EM()),e.addCommand(FM()),e.addCommand(s4()),e.addCommand(f4()),e.addCommand(d4()),e.addCommand(m4()),e.addCommand(_4()),e.addCommand(T4()),e.addCommand(I4()),e.addCommand(P4()),e}a(C4,"createProgram");C4().parse();0&&(module.exports={createProgram});
779
779
  /*! Bundled license information:
780
780
 
781
781
  reflect-metadata/Reflect.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitelev/exocortex-cli",
3
- "version": "16.96.11",
3
+ "version": "16.96.13",
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": {