omo-ai 5.1.21 → 5.1.23

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.
@@ -1,2 +1,2 @@
1
- // omo:kYqpIUFJhCJlUe7TxhpuDFE9-s2wmL-4C_NzHIlcrpQ:t442sbFCSKYdQLnd8PNHMSS7uXJ13QdQ3kBtNotPNi8
2
- import{Buffer as t}from"node:buffer";import*as e from"node:fs";import*as n from"node:fs/promises";function i(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}async function r(t){for(let e=0;;e+=1)try{return await t()}catch(t){if("EINTR"!==i(t)||e>=128)throw t}}function a(t){for(let e=0;;e+=1)try{return t()}catch(t){if("EINTR"!==i(t)||e>=128)throw t}}var o=new Set(["EPERM","EBUSY","EACCES"]),s=[10,25,50,100,200,400],l=t=>new Promise(e=>setTimeout(e,t));import{Buffer as c}from"node:buffer";import{constants as u}from"node:fs";import*as f from"node:fs/promises";function d(t){return"number"==typeof t?0!==(t&u.O_EXCL):"string"==typeof t&&t.toLowerCase().includes("x")}async function h(t,e,n,i){let a="string"==typeof e?c.from(e,n??"utf8"):e,o=0;for(;o<a.length;){i?.throwIfAborted();let{bytesWritten:e}=await r(()=>t.write(a,o));if(e<=0)throw Error(`fs write made no progress at offset ${o}`);o+=e}}function p(t){return"function"==typeof t}function m(t){return(...e)=>r(async()=>t(...e))}function y(t){return(...e)=>a(()=>t(...e))}function w(t,e){let n="async"===e?m:y,i=new Map;return new Proxy(t,{get(t,e){if(i.has(e))return i.get(e);let r=Reflect.get(t,e);if(!p(r))return r;let a=n(r),o=Reflect.get(r,"native");return p(o)&&Object.assign(a,{native:n(o)}),i.set(e,a),a}})}var g=new Set(["stat","sync","datasync","chmod","chown","utimes","truncate"]);var $=w(n,"async");function v(t,e){return async function(t,e,n){let r="win32"===n.platform?n.delaysMs??s:[],a=n.sleep??l;for(let s=0;;s+=1)try{return void await n.rename(t,e)}catch(t){let e=r[s],n=i(t);if(void 0===e||void 0===n||!o.has(n))throw t;await a(e)}}(t,e,{rename:$.rename,platform:process.platform})}var k=w(e,"sync"),{access:b,chmod:x,copyFile:E,cp:S,link:I,lstat:A,mkdir:N,mkdtemp:_,readFile:P,readdir:T,realpath:L,rm:M,rmdir:O,stat:R,unlink:B}=$,{accessSync:D,chmodSync:j,fsyncSync:C,linkSync:H,lstatSync:U,mkdirSync:F,readFileSync:W,readdirSync:G,realpathSync:z,statSync:q,unlinkSync:K,writeFileSync:Y,writeSync:X}=k,Z=async(...t)=>{let e=()=>n.open(...t);return function(t){return new Proxy(t,{get(t,e){let n=Reflect.get(t,e);if(!p(n))return n;let a=e=>Reflect.apply(n,t,[...e]);return"close"===e||e===Symbol.asyncDispose?(...t)=>{let e=a(t);return e instanceof Promise?e.catch(t=>{if("EINTR"!==i(t))throw t}):e}:"string"==typeof e&&g.has(e)?(...t)=>{let e=a(t);return e instanceof Promise?e.catch(e=>{if("EINTR"!==i(e))throw e;return r(async()=>a(t))}):e}:(...t)=>a(t)}})}(await(d(t[1]??"r")?e():r(e)))};var J=async(e,a,o)=>{if("string"!=typeof a&&!(a instanceof Uint8Array))return n.writeFile(e,a,o);if("object"==typeof(s=e)&&!(s instanceof URL)&&!t.isBuffer(s)&&"fd"in s){let t="string"==typeof o?{encoding:o}:o??{};return t.signal?.throwIfAborted(),await h(e,a,t.encoding??void 0,t.signal),void(!0===t.flush&&await r(()=>e.sync()))}var s;return async function(t,e,n,a){let o="string"==typeof n?{encoding:n}:n??{};o.signal?.throwIfAborted();let s=o.flag??a,l=()=>f.open(t,s,o.mode),c=await(d(s)?l():r(l));try{await h(c,e,o.encoding??"utf8",o.signal),!0===o.flush&&await r(()=>c.sync())}finally{await c.close().catch(t=>{if("EINTR"!==i(t))throw t})}}(e,a,o??void 0,"w")};function V(t){try{return a(()=>e.statSync(t)),!0}catch{return!1}}import{join as Q}from"node:path";import{resolve as tt}from"node:path";var et=/(could not lock config file|unable to create '[^']*config\.lock')/i,nt=/(could not lock config file|unable to create '[^']*\.lock'|cannot lock ref|another git process seems to be running)/i,it=new Map;function rt(t){return et.test(ot(t))}function at(t){return nt.test(ot(t))}function ot(t){return t instanceof Error?t.message:String(t)}async function st(t,e){let n=tt(t),i=(it.get(n)??Promise.resolve()).catch(()=>{}).then(()=>async function(t){for(let e=1;e<=5;e+=1)try{return void await t()}catch(t){if(!rt(t)||5===e)throw t;await ct(25*2**(e-1))}}(e));it.set(n,i);try{await i}finally{it.get(n)===i&&it.delete(n)}}async function lt(t){for(let e=1;e<=5;e+=1)try{return await t()}catch(t){if(!at(t)||5===e)throw t;await ct(25*2**(e-1))}throw Error("unreachable: git lock retry exhausted without result")}function ct(t){return new Promise(e=>setTimeout(e,t))}class ut extends Error{constructor(t,e){super(t,e),this.name=new.target.name}}class ft extends ut{argv;code;stdout;stderr;constructor(t,e,n,i){let r=i.trim()||n.trim()||`exit code ${e}`;super(`git ${t.join(" ")} failed: ${r}`),this.argv=t,this.code=e,this.stdout=n,this.stderr=i}}class dt extends ut{argv;timeoutMs;constructor(t,e){super(`git ${t.join(" ")} timed out after ${e}ms`),this.argv=t,this.timeoutMs=e}}class ht extends ut{constructor(t){super("Git is required for memory storage but was not found on PATH.",t)}}class pt extends ut{porcelain;encodingDiagnostics;constructor(t,e){let n=e.length>0?` Dirty markdown encoding issue(s): ${e.join("; ")}.`:"";super(`Memory repo has uncommitted changes. Commit, discard, or sync them before using memory tools.\n${t.trimEnd()}${n}`),this.porcelain=t,this.encodingDiagnostics=e}}class mt extends ut{paths;constructor(t){super(`Memory write produced no effective changes for: ${t.join(", ")}`),this.paths=t}}class yt extends ut{}import{spawn as wt}from"node:child_process";import{win32 as gt}from"node:path";var $t=[["ProgramFiles",["Git","cmd","git.exe"]],["ProgramW6432",["Git","cmd","git.exe"]],["ProgramFiles(x86)",["Git","cmd","git.exe"]],["LOCALAPPDATA",["Programs","Git","cmd","git.exe"]]];function vt(t,e){for(let[n,i]of Object.entries(t)){if(n.toLowerCase()!==e.toLowerCase()||void 0===i)continue;let t=i.trim();if(t.length>0)return t}}function kt(t){return t instanceof ht&&t.cause instanceof Error&&"ENOENT"===t.cause.code}function bt(t,e,n,i){return new Promise((r,a)=>{let o=void 0!==n.stdin,s=wt(t,[...e],{cwd:n.cwd,env:i,shell:!1,stdio:[o?"pipe":"ignore","pipe","pipe"],windowsHide:!0}),l=[],c=[],u=!1,f=!1,d=setTimeout(()=>{f=!0,s.kill("SIGKILL")},n.timeoutMs);s.stdout.on("data",t=>l.push(t)),s.stderr.on("data",t=>c.push(t)),o&&s.stdin.end(n.stdin),s.on("error",t=>{if(!u)if(u=!0,clearTimeout(d),"ENOENT"===t.code){if(!V(n.cwd))return void r({code:128,stdout:"",stderr:`fatal: cannot change to '${n.cwd}': No such file or directory`});a(new ht({cause:t}))}else a(t)}),s.on("close",t=>{if(u)return;if(u=!0,clearTimeout(d),f)return void a(new dt(e,n.timeoutMs));let i=Buffer.concat(l);r({code:t??1,stdout:i.toString("utf8"),stderr:Buffer.concat(c).toString("utf8"),stdoutBytes:i})})})}function xt(t={}){let e=t.platform??process.platform,n=t.runCommand??bt;return{async run(t,i){let r=i.env??process.env;try{return await n("git",t,i,r)}catch(a){if("win32"!==e||!kt(a))throw a;for(let e of function(t){let e=new Set,n=[];for(let[i,r]of $t){let a=vt(t,i);if(void 0===a||!/^[A-Za-z]:[\\/]/.test(a))continue;let o=gt.join(a,...r),s=gt.normalize(o).toLowerCase();e.has(s)||(e.add(s),n.push(o))}return n}(r))try{return await n(e,t,i,r)}catch(t){if(kt(t))continue;throw t}throw a}}}}import{join as Et}from"node:path";function St(t){return["-c",`user.name=${t.authorName.trim()||t.agentId}`,"-c",`user.email=${t.authorEmail??`${t.agentId}@omo.local`}`]}function It(t){return[...new Set(t.map(t=>t.replace(/\\/g,"/")).filter(t=>t.trim()))]}function At(t){let e=t.replace(/\\/g,"/"),n=e.split("/").filter(Boolean);if(!e||e.startsWith("/")||n.some(t=>"."===t||".."===t))throw new yt(`Invalid memory seed path: ${t}`);return n.join("/")}function Nt(t,e){return new ft(t,e.code,e.stdout,e.stderr)}import{randomUUID as _t}from"node:crypto";import{isAbsolute as Pt,resolve as Tt}from"node:path";import{randomUUID as Lt}from"node:crypto";import{basename as Mt,dirname as Ot,join as Rt}from"node:path";async function Bt(t,e,n,i,r){let a=Rt(t,e);await Ct(t,e),r||await async function(t){try{let e=await A(t);if(!e.isFile())throw Ht(t,e.isSymbolicLink()?"symlink":"non-file")}catch(t){if("ENOENT"!==Ut(t))throw t}}(a),await N(Ot(a),{recursive:!0}),await Ct(t,e);let o=Rt(Ot(a),`.${Mt(a)}.omo-${process.pid}-${Lt()}`),s=await Z(o,"wx",i);try{await h(s,n,"utf8"),await x(o,i),await s.sync()}catch(t){throw await s.close(),await M(o,{force:!0}),t}if(await s.close(),r){try{await I(o,a)}catch(t){if(await M(o,{force:!0}),"EEXIST"===Ut(t))return!1;throw t}await M(o)}else await v(o,a);return await Ft(Ot(a)),!0}async function Dt(t,e,n){let i=Rt(t,e);try{await I(n,i)}catch(t){if("EEXIST"===Ut(t))return!1;throw t}return await M(n),await Ft(Ot(i)),!0}async function jt(t){await M(t,{force:!0})}async function Ct(t,e){let n=e.split("/").slice(0,-1),i=t;for(let t of n){i=Rt(i,t);try{let t=await A(i);if(t.isSymbolicLink()||!t.isDirectory())throw Ht(e,"unsafe parent")}catch(t){if("ENOENT"===Ut(t))return;throw t}}}function Ht(t,e){return new qt(`Unsupported worktree ${e} at path: ${t}`)}function Ut(t){return t instanceof Error&&"code"in t&&"string"==typeof t.code?t.code:void 0}async function Ft(t){try{let e=await Z(t,"r");try{await e.sync()}finally{await e.close()}}catch(t){if("win32"!==process.platform||!["EISDIR","EPERM","EACCES","EINVAL"].includes(Ut(t)??""))throw t}}async function Wt(t){let e,n=(await Gt(t,["rev-parse","--git-path","index"])).stdout.trim(),i=Pt(n)?n:Tt(t.dir,n),r=`${i}.lock`,a=`${i}.omo-${process.pid}-${_t()}`;try{e=await Z(r,"wx")}catch(t){if("EEXIST"===Ut(t))return!1;throw t}let o=!1;try{if(s=await t.capture(),l=t.expected,JSON.stringify(s)!==JSON.stringify(l))return!1;await E(i,a);let n=null===t.next?["update-index","--force-remove","--",t.path]:["update-index","--add","--cacheinfo",t.next.mode,t.next.oid,t.path];return await Gt(t,n,{GIT_INDEX_FILE:a}),await h(e,await P(a)),await e.sync(),await e.close(),await v(r,i),o=!0,!0}finally{o||await e.close().catch(()=>{}),await M(a,{force:!0}),o||await M(r,{force:!0})}var s,l}async function Gt(t,e,n={}){let i=await t.exec.run(e,{cwd:t.dir,timeoutMs:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0",...n}});if(0!==i.code)throw Nt(e,i);return i}var zt=new Set(["100644","100755"]);class qt extends Error{constructor(t,e){super(t,e),this.name="GitPathStateError"}}class Kt{dir;exec;ownershipLossRecoveryPath;constructor(t,e){this.dir=t,this.exec=e}async capture(t){let e=Yt(t);return{index:await this.captureIndex(e),worktree:await this.captureWorktree(e)}}async captureAll(t){let e=[...new Set(t.map(Yt))],n=await Promise.all(e.map(async t=>[t,await this.capture(t)]));return new Map(n)}async hashWorktreeBlob(t,e=!1){return this.hashBlob([...e?["-w"]:[],"--no-filters","--stdin"],t)}async hashIndexBlob(t,e,n=!1){let i=Yt(t);return this.hashBlob([...n?["-w"]:[],`--path=${i}`,"--stdin"],e)}async readBlob(t){return Zt(t),(await this.git(["cat-file","blob",t])).stdout}async setIndex(t,e){let n=Yt(t);Jt(e),await this.git(["update-index","--add","--cacheinfo",e.mode,e.oid,n])}async writeIndexIfIdentity(t,e,n){let i=Yt(t);return null!==n&&Jt(n),Wt({dir:this.dir,exec:this.exec,path:i,expected:e,next:n,capture:()=>this.captureIndex(i)})}async removeIndex(t){let e=Yt(t);await this.git(["update-index","--force-remove","--",e])}async writeWorktree(t,e){let n=Yt(t);Vt(e),await Bt(this.dir,n,await this.readBlob(e.oid),e.mode,!1)}async writeWorktreeIfIdentity(t,e,n){this.ownershipLossRecoveryPath=void 0;let i=Yt(t);if("missing"===e.kind)return"missing"===(await this.captureWorktree(i)).kind&&("missing"===n.kind||(Vt(n),Bt(this.dir,i,await this.readBlob(n.oid),n.mode,!0)));let r=await async function(t,e){let n=Rt(t,e);await Ct(t,e);try{let t=await A(n);if(!t.isFile())throw Ht(e,t.isSymbolicLink()?"symlink":"non-file");let i=Rt(Ot(n),`.${Mt(n)}.omo-moved-${process.pid}-${Lt()}`);return await v(n,i),i}catch(t){if("ENOENT"===Ut(t))return;throw t}}(this.dir,i);if(void 0===r)return!1;try{let t=await this.captureMovedWorktree(r);if(a=t,o=e,JSON.stringify(a)!==JSON.stringify(o))return await Dt(this.dir,i,r)||await jt(r),!1;if("missing"===n.kind){let t=await this.reserveWorktreeDeletion(i,r);if(void 0===t)return await jt(r),!1;let e=await t.verify();if(void 0===e)return await jt(r),!1;let n=await e.finish();return!0!==n&&await jt(r),"string"==typeof n&&(this.ownershipLossRecoveryPath=n),!0===n}Vt(n);let s=await Bt(this.dir,i,await this.readBlob(n.oid),n.mode,!0);return await jt(r),s}catch(t){throw await Dt(this.dir,i,r)||await jt(r),t}var a,o}consumeOwnershipLossRecoveryPath(){let t=this.ownershipLossRecoveryPath;return this.ownershipLossRecoveryPath=void 0,t}async reserveWorktreeDeletion(t,e){return async function(t,e,n,i){let r=Rt(t,e),a=Lt();try{await N(r,{mode:448}),await J(Rt(r,".omo-reservation"),a,"utf8")}catch(t){if("EEXIST"===Ut(t))return;throw t}let o=await A(r);return{verify:async()=>{let t;try{t=await A(r)}catch(t){if("ENOENT"===Ut(t))return;throw t}if(t.isDirectory()&&t.dev===o.dev&&t.ino===o.ino){try{if(await P(Rt(r,".omo-reservation"),"utf8")!==a)return}catch(t){if("ENOENT"===Ut(t))return;throw t}return{finish:async()=>{let t=Rt(Ot(r),`.${Mt(r)}.omo-reserved-${process.pid}-${Lt()}`);try{await v(r,t)}catch(t){if("ENOENT"===Ut(t))return!1;throw t}let e,s=await A(t);if(s.isDirectory())try{e=await P(Rt(t,".omo-reservation"),"utf8")}catch(t){if("ENOENT"!==Ut(t))throw t}if(!s.isDirectory()||s.dev!==o.dev||s.ino!==o.ino||e!==a){let e=await i(t);return!0!==e&&e}await M(n),await M(t,{recursive:!0}),await Ft(Ot(r));try{return await A(r),!1}catch(t){if("ENOENT"===Ut(t))return!0;throw t}}}}}}}(this.dir,t,e,e=>this.restoreWorktreeClaim(t,e))}async restoreWorktreeClaim(t,e){return async function(t,e,n){if(!(await A(n)).isFile())return n;try{await I(n,Rt(t,e))}catch(t){if("EEXIST"===Ut(t))return n;throw t}return await M(n),!0}(this.dir,t,e)}async removeWorktree(t){await async function(t,e){let n,i=Rt(t,e);await Ct(t,e);try{n=await A(i)}catch(t){if("ENOENT"===Ut(t))return;throw t}if(!n.isFile())throw Ht(e,n.isSymbolicLink()?"symlink":"non-file");await M(i),await Ft(Ot(i))}(this.dir,Yt(t))}async captureIndex(t){let e=(await this.git(["--literal-pathspecs","ls-files","--stage","-z","--",t])).stdout.split("\0").filter(Boolean);if(0===e.length)return null;let n=e.map(Xt);if(n.some(t=>"0"!==t.stage))throw new qt(`Git path is unmerged and cannot be recovered safely: ${t}`);if(1!==n.length||n[0]?.path!==t)throw new qt(`Git path did not resolve to one stage-zero index entry: ${t}`);let i=n[0];if(!zt.has(i.mode))throw new qt(`Unsupported Git index mode ${i.mode} for path: ${t}`);return{mode:i.mode,oid:i.oid}}async captureWorktree(t){await Ct(this.dir,t);let e,n=Et(this.dir,t);try{e=await A(n)}catch(t){if("ENOENT"===Ut(t))return{kind:"missing"};throw t}if(!e.isFile())throw Ht(t,e.isSymbolicLink()?"symlink":"non-file");let i=await this.hashWorktreeBlob(await P(n),!0);return{kind:"file",mode:Qt(e.mode),oid:i}}async captureMovedWorktree(t){let e=await A(t);if(!e.isFile())throw Ht(t,e.isSymbolicLink()?"symlink":"non-file");return{kind:"file",mode:Qt(e.mode),oid:await this.hashWorktreeBlob(await P(t),!0)}}async hashBlob(t,e){let n=(await this.git(["hash-object",...t],e)).stdout.trim();return Zt(n),n}async git(t,e){let n=await this.exec.run(t,{cwd:this.dir,timeoutMs:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0"},...void 0===e?{}:{stdin:e}});if(0!==n.code)throw Nt(t,n);return n}}function Yt(t){let e=t.replace(/\\/g,"/"),n=e.split("/");if(!e||e.includes("\0")||e.startsWith("/")||/^[A-Za-z]:\//.test(e)||n.some(t=>!t||"."===t||".."===t||".git"===t.toLowerCase()))throw new qt(`Invalid repository-relative Git path: ${t}`);return e}function Xt(t){let e=/^(\d{6}) ([0-9a-f]+) ([0-3])\t([\s\S]+)$/.exec(t);if(null===e)throw new qt("Git returned a malformed index entry");return{mode:e[1],oid:e[2],stage:e[3],path:e[4]}}function Zt(t){if(!/^[0-9a-f]+$/.test(t))throw new qt(`Invalid Git object ID: ${t}`)}function Jt(t){if(!zt.has(t.mode))throw new qt(`Unsupported Git index mode: ${t.mode}`);Zt(t.oid)}function Vt(t){if("file"!==t.kind||!Number.isInteger(t.mode)||t.mode<0||t.mode>511)throw new qt("Invalid worktree file identity");Zt(t.oid)}function Qt(t){return"win32"===process.platform?420:511&t}import{join as te}from"node:path";function ee(t,e){return e.split(/\r?\n/).map(t=>t.trimEnd()).filter(Boolean).map(ne).filter(t=>t?.endsWith(".md")??!1).map(e=>function(t,e){let n=te(t,e);if(!V(n))return null;let i=W(n);return i.length>=2&&255===i[0]&&254===i[1]?`${e} has UTF-16 LE BOM`:i.length>=2&&254===i[0]&&255===i[1]?`${e} has UTF-16 BE BOM`:i.includes(0)?`${e} contains NUL bytes, possibly UTF-16`:null}(t,e)).filter(t=>null!==t)}function ne(t){if(t.length<4)return null;let e=t.slice(0,2);if(" D"===e||"D "===e||"DD"===e)return null;let n=t.slice(3);return(n.includes(" -> ")?n.split(" -> ").pop()??n:n).replace(/^"|"$/g,"")}import{dirname as ie,join as re}from"node:path";function ae(t){return t.split("\0").filter(Boolean)}function oe(t){let e={};for(let n of t.split(/\r?\n/)){let t=/^([^:\s][^:]*):\s*(.*)$/.exec(n);if(null===t)continue;let i=t[1]?.trim();void 0!==i&&i.length>0&&(e[i]=t[2]??"")}return e}async function se(t,e,n){let i=(await n()).split(/\r?\n/).filter(Boolean).filter(t=>{let n=ne(t);return null!==n&&!e.some(t=>n===t||n.startsWith(`${t}/`)||t.startsWith(n.endsWith("/")?n:`${n}/`))});if(0===i.length)return;let r=`${i.join("\n")}\n`;throw new pt(r,ee(t,r))}import{resolve as le}from"node:path";var ce=new Map;async function ue(t,e){let n=le(t),i=(ce.get(n)?.then(()=>{},()=>{})??Promise.resolve()).then(e),r=i.then(()=>{},()=>{});ce.set(n,r);try{return await i}finally{ce.get(n)===r&&ce.delete(n)}}class fe{dir;agentId;pathState;exec;hookInstaller;constructor(t){this.dir=t.dir,this.agentId=t.agentId,this.exec=t.exec??xt(),this.pathState=new Kt(this.dir,this.exec),this.hookInstaller=t.installHooks??(()=>{})}async init(t={}){await N(this.dir,{recursive:!0}),V(re(this.dir,".git"))||(await lt(()=>this.git(["init","--template="])),await lt(()=>this.git(["symbolic-ref","HEAD","refs/heads/main"]))),await(t.installHooks??this.hookInstaller)(this.dir),await this.ensureIdentity(t.authorName?.trim()||"OmO Agent");let e=await this.head();if(e)return e;let n=[];for(let e of t.seedFiles??[]){let t=At(e.relativePath),i=re(this.dir,t);await N(ie(i),{recursive:!0}),await J(i,e.content,"utf8"),n.push(t)}let i={agentId:this.agentId,authorName:t.authorName?.trim()||"OmO Agent"};return n.length>0&&(await this.stage(n),await this.hasPathChanges(n))?(await this.commitStaged("chore: initialize local memory",i)).sha:(await lt(()=>this.git([...St(i),"commit","--allow-empty","-m","chore: initialize empty local memory"])),this.requireHead())}async cleanCheck(){await this.hookInstaller(this.dir);let t=await this.status();if(t.trim())throw new pt(t,ee(this.dir,t))}async commitWrite(t,e,n){await this.hookInstaller(this.dir);let i=It(t);if(0===i.length)throw new mt(i);return await se(this.dir,i,()=>this.status()),await this.stage(i),this.commitPrepared(i,e,n)}async commitPrepared(t,e,n){await this.hookInstaller(this.dir);let i=It(t);if(0===i.length)throw new mt(i);if(await se(this.dir,i,()=>this.status()),!await this.hasPathChanges(i))throw new mt(i);return this.commitStaged(e,n)}async status(t=[]){let e=It(t),n=e.length>0?["--",...e]:[];return(await this.git(["-c","core.quotePath=false","status","--porcelain","--untracked-files=all",...n])).stdout}async head(){let t=await this.gitResult(["rev-parse","--verify","HEAD"]);return 0!==t.code?null:t.stdout.trim()||null}async headCommitTimestamp(){let t=await this.gitResult(["show","-s","--format=%ct","HEAD"]);if(0!==t.code)return null;let e=Number.parseInt(t.stdout.trim(),10);return Number.isSafeInteger(e)&&e>=0?e:null}async lsTree(t="HEAD",e){let n=e?["--",e]:[];return(await this.git(["ls-tree","-r","--name-only","-z",t,...n])).stdout.split("\0").filter(Boolean)}async lsTreeSized(t="HEAD"){return function(t){let e=[];for(let n of t.split("\0")){if(0===n.length)continue;let t=n.indexOf("\t");if(-1===t)continue;let i=n.slice(0,t).trim().split(/\s+/),r=n.slice(t+1);if(i.length<4||0===r.length)continue;let a=i[3];if(void 0===a||"-"===a)continue;let o=Number.parseInt(a,10);!Number.isSafeInteger(o)||o<0||e.push({path:r,bytes:o})}return e}((await this.git(["ls-tree","-r","-l","-z",t])).stdout)}async lsTreeBlobs(t="HEAD"){return function(t){let e=[];for(let n of t.split("\0")){let t=n.indexOf("\t");if(-1===t)continue;let[,i,r]=n.slice(0,t).trim().split(/\s+/),a=n.slice(t+1);"blob"===i&&void 0!==r&&0!==a.length&&e.push({path:a,oid:r})}return e}((await this.git(["ls-tree","-r","-z",t])).stdout)}async show(t,e){return(await this.git(["show",`${t}:${e}`])).stdout}async readBlobs(t){let e=[...new Set(t)];if(0===e.length)return new Map;let n=["cat-file","--batch"],i=await this.gitResult(n,`${e.join("\n")}\n`);if(0!==i.code)throw Nt(n,i);return function(t){let e=new Map,n=0;for(;n<t.length;){let i=t.indexOf(10,n);if(-1===i)throw Error("git cat-file --batch output ended inside a record header");let r=t.toString("utf8",n,i);n=i+1;let[a,o,s]=r.split(" ");if(void 0===s)continue;let l=Number.parseInt(s,10);if(void 0===a||!Number.isSafeInteger(l)||l<0||n+l>t.length)throw Error(`git cat-file --batch output is malformed at "${r}"`);"blob"===o&&e.set(a,t.toString("utf8",n,n+l)),n+=l+1}return e}(i.stdoutBytes??Buffer.from(i.stdout,"utf8"))}async log(t={}){let e=["log","--format=%x1e%H%x1f%s%x1f%b%x1f%an%x1f%ae%x1f%cI"];void 0!==t.grep&&t.grep.length>0&&e.push("--fixed-strings","--all-match",...t.grep.map(t=>`--grep=${t}`)),void 0!==t.limit&&e.push("-n",String(t.limit)),void 0!==t.range&&e.push(t.range),void 0!==t.paths&&t.paths.length>0&&e.push("--",...t.paths);let n=(await this.git(e)).stdout.split("").slice(1).map(t=>{let[e="",n="",i="",r="",a="",o=""]=t.split(""),s=i.replace(/\r?\n$/,"");return{sha:e,subject:n,body:s,authorName:r,authorEmail:a,committedAt:o.trim(),trailers:oe(s)}});return!0!==t.includePaths?n:Promise.all(n.map(async t=>({...t,paths:ae((await this.git(["diff-tree","--no-commit-id","--name-only","-z","-r",t.sha])).stdout)})))}async worktreeAdd(t,e,n="HEAD"){await ue(this.dir,()=>lt(()=>this.git(["worktree","add","-b",e,t,n])))}async worktreeRemove(t,e=!0){await ue(this.dir,()=>lt(()=>this.git(["worktree","remove",...e?["--force"]:[],t])))}async merge(t,e={}){let n=["merge"];return(e.noFF??!0)&&n.push("--no-ff"),e.message&&n.push("-m",e.message),n.push(t),await lt(()=>this.git(n)),this.requireHead()}async configGet(t){let e=await this.gitResult(["config","--local","--get",t]);if(1===e.code)return null;if(0!==e.code)throw Nt(["config","--local","--get",t],e);return e.stdout.trim()||null}async configSet(t,e){await st(this.dir,async()=>{await this.git(["config","--local",t,e])})}async ensureIdentity(t){await this.configGet("omo.agentId")!==this.agentId&&await this.configSet("omo.agentId",this.agentId),await this.configGet("user.email")||await this.configSet("user.email",`${this.agentId}@omo.local`),await this.configGet("user.name")||await this.configSet("user.name",t),null===await this.configGet("commit.gpgsign")&&await this.configSet("commit.gpgsign","false"),null===await this.configGet("gc.auto")&&await this.configSet("gc.auto","0")}async stage(t){await lt(()=>this.git(["add","-A","--",...t]))}async hasPathChanges(t){return(await this.status(t)).trim().length>0}async commitStaged(t,e){return await lt(()=>this.git([...St(e),"commit","-m",t])),{committed:!0,sha:await this.requireHead()}}async requireHead(){let t=await this.head();if(!t)throw Error("Memory repository has no HEAD commit");return t}async git(t){let e=await this.gitResult(t);if(0!==e.code)throw Nt(t,e);return e}gitResult(t,e){return this.exec.run(t,{cwd:this.dir,timeoutMs:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0"},...void 0===e?{}:{stdin:e}})}}import{execFile as de}from"node:child_process";var he=null;function pe(){return he??=async function(){if("darwin"!==process.platform)return null;try{let{dlopen:t,FFIType:e}=await(import("bun:ffi")),n=t("/usr/lib/libSystem.B.dylib",{proc_pidinfo:{args:[e.i32,e.i32,e.u64,e.ptr,e.i32],returns:e.i32}});return(t,e,i,r,a)=>Number(n.symbols.proc_pidinfo(t,e,i,r,a))}catch{return null}}(),he}var me=null;async function ye(t){if("win32"!==process.platform)return null;if(!Number.isSafeInteger(t)||t<=0)return null;me??=async function(){if("win32"!==process.platform)return null;try{let{dlopen:t,FFIType:e}=await(import("bun:ffi"));return t("kernel32.dll",{OpenProcess:{args:[e.u32,e.i32,e.u32],returns:e.ptr},GetProcessTimes:{args:[e.ptr,e.ptr,e.ptr,e.ptr,e.ptr],returns:e.i32},CloseHandle:{args:[e.ptr],returns:e.i32}}).symbols}catch{return null}}();let e=await me;if(null===e)return null;let n=e.OpenProcess(4096,0,t);if(null===n||0===n||0n===n)return null;try{let t=new BigUint64Array(1),i=e.GetProcessTimes(n,t,new BigUint64Array(1),new BigUint64Array(1),new BigUint64Array(1)),r=t[0]??0n;return 0===i||0n===r?null:r}finally{e.CloseHandle(n)}}async function we(t,e){return await new Promise(n=>{de(t,e,{encoding:"utf8",timeout:2e3,windowsHide:!0},(t,e)=>{if(null!==t)return void n(null);let i=e.trim();n(i.length>0?i:null)})})}!function(t,e){let n}(async function(t){if("linux"===process.platform)return await async function(t){try{let e=await P(`/proc/${t}/stat`,"utf8"),n=e.lastIndexOf(")");if(n<0)return null;let i=e.slice(n+2).trim().split(/\s+/)[19];return void 0===i?null:`linux-proc-start-ticks:${i}`}catch{return null}}(t);if("darwin"===process.platform||"freebsd"===process.platform){if("dead"===ge(t))return null;let e=await async function(t){if("darwin"!==process.platform)return null;if(!Number.isSafeInteger(t)||t<=0)return null;let e=await pe();if(null===e)return null;let n=new Uint8Array(136),i=0;try{i=e(t,3,0n,n,136)}catch{return null}if(136!==i)return null;let r=new DataView(n.buffer,n.byteOffset,n.byteLength),a=Number(r.getBigUint64(120,!0));return a>0?a:null}(t);if(null!==e)return`proc-start-epoch:${e}`;let n=await we("/bin/ps",["-o","lstart=","-p",String(t)]);return null===n?null:`ps-lstart:${n.replace(/\s+/g," ")}`}return"win32"===process.platform?await async function(t){if("dead"===ge(t))return null;let e=await ye(t);if(null!==e)return`win32-creation-filetime:${e}`;let n=await we("powershell.exe",["-NoProfile","-Command",`(Get-Process -Id ${t} -ErrorAction SilentlyContinue).StartTime.ToUniversalTime().ToString('o')`]);return null===n?null:`win32-creation-date:${n}`}(t):null},process.pid);function ge(t){try{return process.kill(t,0),"alive"}catch(t){let e=function(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}(t);return"ESRCH"===e?"dead":"EPERM"===e?"alive":"unknown"}}Promise.resolve();import{isAbsolute as $e,join as ve,resolve as ke}from"node:path";import{join as be}from"node:path";var xe=[["\\bAKIA[0-9A-Z]{16}\\b",""],["\\b(?:bearer|token|api[_-]?key|secret|password|passwd|pwd)\\s*[=:]\\s*\\S{1,256}","i"],["\\bAuthorization\\s*:\\s*Bearer\\s+\\S{1,256}","i"],["\\bsk-(?:proj-)?[-_A-Za-z0-9]+\\b",""],["\\b(?:ghp|github_pat|glpat|xox[baprs])-[-_A-Za-z0-9]+\\b",""]],Ee=(xe.map(([t,e])=>new RegExp(t,e)),xe.map(([t,e])=>new RegExp(t,`${e}g`)));function Se(t,e=0){let n=t.indexOf("-----BEGIN ",e);if(n<0)return;let i=t.indexOf("-----",n+11);if(i<0||i-(n+11)>64)return;let r=t.slice(n+11,i);if(0===r.length||/[^A-Za-z0-9 ]/.test(r))return;let a=t.indexOf("-----END ",i+5);for(;a>=0;){let e=a+9,i=t.indexOf("-----",e);if(i>=0&&t.slice(e,i)===r)return{start:n,end:i+5};a=t.indexOf("-----END ",i>=0?i+5:e)}}var Ie=/([a-z][a-z0-9+.-]*:\/\/)([^/@\s:]{1,256})(?::([^/@\s]{0,256}))?@/gi,Ae=/(^|[\s'"(<])([^\s:/@]{1,256})@([^\s:/@]{1,256}):/g;function Ne(t){if(!t)return"";let e=t.includes("://")?t.replace(Ie,(t,e,n,i)=>void 0===i?`${e}***@`:`${e}***:***@`):t;return function(t){let e=Ee.reduce((t,e)=>t.replace(e,"***"),t),n=0;for(;;){let t=Se(e,n);if(void 0===t)return e;e=`${e.slice(0,t.start)}***${e.slice(t.end)}`,n=t.start+3}}(e.includes("@")?e.replace(Ae,(t,e,n,i)=>`${e}***@${i}:`):e)}var _e="omo.memoryRepository.url",Pe="memory-repository-push.log",Te="main",Le=1e4;class Me{repo;exec;constructor(t){this.repo=t.repo,this.exec=t.exec??xt()}async set(t){let e=Oe(t);if(!e)throw Error("Memory repository URL must not be empty");return await this.repo.configSet(_e,e),{url:e,...await this.push(e,1e4)}}async unset(){await st(this.repo.dir,async()=>{let t=await this.run(["config","--local","--unset-all",_e],Le);if(0!==t.code&&5!==t.code)throw Error(Re(t))})}async status(){let t=await this.configuredUrl(),e=this.readLogTail();return t?{url:t,redactedUrl:Ne(t),lastLogLines:e,aheadCount:await this.aheadCount(t)}:{lastLogLines:e,aheadCount:0}}async pushNow(){let t=await this.configuredUrl();return t?this.push(t,6e4):{pushed:!1,detail:"No memory repository configured. Set one first."}}async configuredUrl(){return Oe(await this.repo.configGet(_e)??"")||void 0}async push(t,e){let n=await this.run(["push","--quiet",t,`${Te}:${Te}`],e);return 0===n.code?{pushed:!0,detail:""}:{pushed:!1,detail:Ne(Re(n))}}async aheadCount(t){let e=await this.run(["ls-remote",t,`refs/heads/${Te}`],Le),n=0===e.code?e.stdout.trim().split(/\s+/)[0]??"":"",i=n?`${n}..${Te}`:Te,r=await this.run(["rev-list","--count",i],Le);return 0!==r.code?0:Number.parseInt(r.stdout.trim(),10)||0}readLogTail(){let t;try{t=W((e=this.repo.dir,be(e,".git",Pe)),"utf8")}catch{return[]}var e;return t.split(/\r?\n/).filter(t=>t.trim().length>0).slice(-20).map(Ne)}async run(t,e){try{return await this.exec.run(t,{cwd:this.repo.dir,timeoutMs:e,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}})}catch(t){return{code:1,stdout:"",stderr:t instanceof Error?t.message:String(t)}}}}function Oe(t){let e=t.trim();return e.replace(/\/+$/,"")||e}function Re(t){return t.stderr.trim()||t.stdout.trim()||`git exited with code ${t.code}`}var Be=[{name:"pre-commit",script:'#!/bin/sh\n# Validate frontmatter in staged memory .md files.\n# Installed by omo memory-core. Do not edit by hand - regenerated on startup.\n\nALL_KNOWN_KEYS="description read_only limit kind aliases"\nTAB=$(printf \'\\t\')\n\nfm_value() {\n # $1 = file content, $2 = key. Prints the value of a top-level frontmatter\n # key, or nothing when the key is absent.\n closing=$(printf \'%s\\n\' "$1" | tail -n +2 | grep -n \'^---$\' | head -1 | cut -d: -f1)\n [ -z "$closing" ] && return 0\n printf \'%s\\n\' "$1" | tail -n +2 | head -n $((closing - 1)) |\n grep "^$2:" | head -1 | cut -d: -f2- | sed \'s/^ *//;s/ *$//\'\n}\n\ncheck_plain_scalar() {\n # $1 = file, $2 = key, $3 = value. A quoted value is the renderer\'s own\n # output; a plain value must be one that strict YAML reads back verbatim.\n case "$3" in\n \\"*|\\\'*|"") return 0 ;;\n *": "*|*":"|*" #"*|"#"*|"["*|"]"*|"{"*|"}"*|"&"*|"*"*|"!"*|"|"*|">"*|"%"*|"@"*|"\\`"*|","*|"?"*|"-"|"- "*)\n printf " %s: \'%s\' is not a safe YAML plain scalar (quote it, or remove \': \' and \' #\'): %s\\n" "$1" "$2" "$3"\n ;;\n esac\n}\n\ncheck_keys() {\n # $1 = file, $2 = HEAD content, $3 = frontmatter, $4 = key policy\n # ("contract" = memory key allowlist, "skill" = any key). Prints one error\n # line per offending frontmatter key. Runs in a pipeline subshell, so it\n # must never rely on assignments leaking to the caller.\n printf \'%s\\n\' "$3" | while IFS= read -r line; do\n [ -z "$line" ] && continue\n # Indented lines are YAML continuations of the previous key.\n case "$line" in " "*|"$TAB"*) continue ;; esac\n\n key=$(printf \'%s\\n\' "$line" | cut -d: -f1 | tr -d \' \')\n value=$(printf \'%s\\n\' "$line" | cut -d: -f2- | sed \'s/^ *//;s/ *$//\')\n\n if [ "$4" != skill ]; then\n known=false\n for k in $ALL_KNOWN_KEYS; do\n [ "$key" = "$k" ] && known=true && break\n done\n if [ "$known" = false ]; then\n printf " %s: unknown frontmatter key \'%s\' (allowed: %s)\\n" "$1" "$key" "$ALL_KNOWN_KEYS"\n continue\n fi\n fi\n\n if [ "$key" != description ] && [ "$key" != aliases ] && [ "$key" != read_only ]; then\n check_plain_scalar "$1" "$key" "$value"\n fi\n\n if [ "$key" = read_only ]; then\n if [ -n "$2" ]; then\n [ "$value" != "$(fm_value "$2" read_only)" ] &&\n printf " %s: \'read_only\' is a protected field and cannot be changed by the agent\\n" "$1"\n else\n printf " %s: \'read_only\' is a protected field and cannot be set by the agent\\n" "$1"\n fi\n fi\n\n # Deviation from letta: a YAML block scalar (\'>\' or \'|\', with optional\n # chomping or indent modifiers) is rejected. letta accepted the indicator\n # as the value, which silently stored \'>\' as the description.\n if [ "$key" = description ]; then\n case "$value" in\n "") printf " %s: \'description\' must not be empty\\n" "$1" ;;\n [\\>\\|]*) printf " %s: \'description\' must be a non-empty single line\\n" "$1" ;;\n *) check_plain_scalar "$1" description "$value" ;;\n esac\n fi\n done\n}\n\ncheck_file() {\n # $1 = file, $2 = key policy ("contract" or "skill")\n file="$1"\n policy="${2:-contract}"\n staged=$(git show ":$file")\n\n if [ "$(printf \'%s\\n\' "$staged" | head -1)" != "---" ]; then\n printf \' %s: missing frontmatter (must start with ---)\\n\' "$file"\n return 0\n fi\n\n closing_line=$(printf \'%s\\n\' "$staged" | tail -n +2 | grep -n \'^---$\' | head -1 | cut -d: -f1)\n if [ -z "$closing_line" ]; then\n printf \' %s: frontmatter opened but never closed (missing closing ---)\\n\' "$file"\n return 0\n fi\n\n head_content=$(git show "HEAD:$file" 2>/dev/null || true)\n if [ -n "$head_content" ] && [ "$(fm_value "$head_content" read_only)" = "true" ]; then\n printf \' %s: file is read_only and cannot be modified\\n\' "$file"\n return 0\n fi\n\n frontmatter=$(printf \'%s\\n\' "$staged" | tail -n +2 | head -n $((closing_line - 1)))\n check_keys "$file" "$head_content" "$frontmatter" "$policy"\n\n if ! printf \'%s\\n\' "$frontmatter" | grep -q \'^description:\'; then\n printf " %s: missing required field \'description\'\\n" "$file"\n fi\n\n if [ -n "$head_content" ] && [ -n "$(fm_value "$head_content" read_only)" ] &&\n [ -z "$(fm_value "$staged" read_only)" ]; then\n printf " %s: \'read_only\' is a protected field and cannot be removed by the agent\\n" "$file"\n fi\n}\n\nerrors=$(\n # Skills must always be directories: skills/<name>/SKILL.md.\n git diff --cached --name-only --diff-filter=ACMR |\n grep -E \'^(memory/)?skills/[^/]+\\.md$\' |\n while IFS= read -r skill_file; do\n printf \' %s: invalid skill path (skills must be folders). Use skills/<name>/SKILL.md\\n\' "$skill_file"\n done\n\n # Memory content keys are an allowlist under system/, reference/ and people/.\n git diff --cached --name-only --diff-filter=ACM |\n grep -E \'^(memory/)?(system|reference|people)/.*\\.md$\' |\n while IFS= read -r file; do\n check_file "$file" contract\n done\n\n # SKILL.md is read by the skill loader as strict YAML: same value rules,\n # description required, any key allowed.\n git diff --cached --name-only --diff-filter=ACM |\n grep -E \'^(memory/)?skills/.+/SKILL\\.md$\' |\n while IFS= read -r file; do\n check_file "$file" skill\n done\n)\n\nif [ -n "$errors" ]; then\n echo "Frontmatter validation failed:"\n printf \'%s\\n\' "$errors"\n exit 1\nfi\n\nexit 0\n'},{name:"post-commit",script:`#!/bin/sh\n# Push memory commits to the configured memory-repository mirror.\n# Installed by omo memory-core. Do not edit by hand - regenerated on startup.\nurl=$(git config --local --get ${_e} 2>/dev/null)\n[ -z "$url" ] && exit 0\n\nbranch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || exit 0\n[ -z "$branch" ] && exit 0\n[ "$branch" != "${Te}" ] && exit 0\n\nlog="$(git rev-parse --git-dir)/${Pe}"\n\npush_to_mirror() {\n {\n printf '\\n--- %s %s on %s ---\\n' "$(date '+%Y-%m-%dT%H:%M:%S')" "$(git rev-parse --short HEAD)" "$branch"\n git push --quiet "$url" "$branch:$branch" 2>&1\n echo "exit=$?"\n } >> "$log" 2>&1\n}\n\nif [ "$OMO_MEMORY_PUSH_SYNC" = "1" ]; then\n push_to_mirror\n exit 0\nfi\n\npush_to_mirror &\nexit 0\n`}];function De(t){let e=function(t){return ve(function(t){let e=ve(t,".git");if(!V(e)||q(e).isDirectory())return e;let n=W(e,"utf8").trim(),i=/^gitdir:\s*(.+)$/.exec(n);if(!i?.[1])return e;let r=je(i[1].trim(),t),a=ve(r,"commondir");return V(a)?je(W(a,"utf8").trim(),r):r}(t),"hooks")}(t);return F(e,{recursive:!0}),Be.map(({name:t,script:n})=>{let i=ve(e,t);return Y(i,n,"utf8"),j(i,493),{name:t,path:i}})}function je(t,e){return $e(t)?t:ke(e,t)}new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0});import{dirname as Ce}from"node:path";import{fileURLToPath as He}from"node:url";Ce(He(import.meta.url));import{dirname as Ue}from"node:path";import{fileURLToPath as Fe}from"node:url";Ue(Fe(import.meta.url)),new Date(0).toISOString();var We="\\p{Script=Hangul}\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\u30fc";new RegExp(`[${We}]+|(?:(?![${We}])[\\p{L}\\p{M}\\p{N}])+`,"gu"),new RegExp(`^[${We}]+$`,"u"),new RegExp(`[${We}]`,"u"),new RegExp(`[${We}]`,"gu"),new RegExp(`[\\p{L}${We}]`,"gu");import{dirname as Ge}from"node:path";import{fileURLToPath as ze}from"node:url";Ge(ze(import.meta.url));import{join as qe}from"node:path";var Ke="memory-backup-";function Ye(t){return t.identityPaths.root}async function Xe(t,e){let n=function(t){let e=new Date(t).toISOString();return`${e.slice(0,10).replace(/-/g,"")}-${e.slice(11,19).replace(/:/g,"")}`}((t.now??Date.now)()),i=Ye(e),r=qe(i,`${Ke}${n}`),a=2;for(;V(r);)r=qe(i,`${Ke}${n}-${a}`),a+=1;return await S(e.identityPaths.repo,r,{recursive:!0}),r}import{join as Ze}from"node:path";function Je(t,e){return new fe({dir:e.identityPaths.repo,agentId:e.identity,installHooks:t=>{De(t)},...void 0===t.exec?{}:{exec:t.exec}})}function Ve(t){return t.slice(0,8)}function Qe(t){return V(Ze(t.identityPaths.repo,".git"))}function tn(t,e){return Qe(e)?Je(t,e):function(t){return`no memory repository for ${t.identity} at ${t.identityPaths.repo}; run /memfs init first`}(e)}import{join as en}from"node:path";async function nn(t,e){let n;try{n=await T(en(t,e),{withFileTypes:!0})}catch{return[]}let i=[];for(let r of n){let n=""===e?r.name:`${e}/${r.name}`;r.isDirectory()?i.push(...await nn(t,n)):r.isFile()&&r.name.endsWith(".md")&&i.push(n)}return i}async function rn(t){let e=await nn(t,"system"),n=[];for(let i of e){let e=await P(en(t,i),"utf8"),r=Buffer.byteLength(e,"utf8");n.push({path:i,bytes:r,tokens:Math.ceil(r/4)})}return n.sort((t,e)=>e.tokens-t.tokens||t.path.localeCompare(e.path)),{totalBytes:n.reduce((t,e)=>t+e.bytes,0),totalTokens:n.reduce((t,e)=>t+e.tokens,0),files:n}}function an(t,e,n="info"){return t.ui?.notify(e,n),e}function on(t,e){let n=function(t){return t.sessionManager?.getSessionId()}(e);if(void 0!==n)return t.contextForSession(n)}function sn(t){return!0===t.hasUI&&"function"==typeof t.ui?.confirm}import{basename as ln,dirname as cn,join as un,relative as fn}from"node:path";var dn=/^(---\r?\n)([\s\S]*?)(\r?\n---(?:\r?\n|$))/;async function hn(t){let e=await T(t,{withFileTypes:!0}),n=[];for(let i of e){if(".git"===i.name||"node_modules"===i.name)continue;let e=un(t,i.name);i.isSymbolicLink()||(i.isDirectory()?n.push(...await hn(e)):i.isFile()&&"SKILL.md"===i.name&&n.push(e))}return n}function pn(t,e){if(!e.trim())return{content:t,changed:!1,reason:"skill directory name is empty"};let n=t.match(dn);if(!n)return{content:t,changed:!1,reason:"missing YAML frontmatter"};let i=n[1]??"",r=n[2]??"",a=n[3]??"",o=i.includes("\r\n")?"\r\n":"\n",s=r.replace(/\r\n/g,"\n").split("\n"),l=s.findIndex(t=>/^\s*name\s*:/.test(t));if(l>=0&&function(t){let e=t.match(/^\s*name\s*:\s*(.*?)\s*$/);return Boolean(e?.[1]?.trim())}(s[l]??""))return{content:t,changed:!1};let c=`name: ${u=e.trim(),/^[A-Za-z0-9_-]+$/.test(u)?u:JSON.stringify(u)}`;var u;return l>=0?s[l]=c:s.unshift(c),{content:`${i}${s.join(o)}${a}${t.slice(n[0].length)}`,changed:!0}}async function mn(t){let e={scanned:0,repaired:[],skipped:[]};if(!t)return e;let n,i=un(t,"skills");if(!await async function(t){try{return await R(t),!0}catch{return!1}}(i))return e;try{n=await hn(i)}catch(t){return e.skipped.push({path:"skills/",reason:`failed to scan skills directory: ${t instanceof Error?t.message:String(t)}`}),e}for(let i of n.sort()){let n=fn(t,i).replace(/\\/g,"/");e.scanned+=1;try{let t=pn(await P(i,"utf8"),ln(cn(i)));if(void 0!==t.reason){e.skipped.push({path:n,reason:t.reason});continue}if(!t.changed)continue;await J(i,t.content,"utf8"),e.repaired.push(n)}catch(t){e.skipped.push({path:n,reason:t instanceof Error?t.message:String(t)})}}return e}var yn=["status","init","sync","repair","reset","backup","restore","diff","tokens"],wn="skills-usage.json";var gn={status:async({deps:t,ctx:e,identity:n})=>{let i=tn(t,n);if("string"==typeof i)return an(e,i,"error");let r=await i.head(),a=(await i.status()).split(/\r?\n/).filter(t=>t.trim().length>0),o=await new Me({repo:i,...void 0===t.exec?{}:{exec:t.exec}}).status(),s=a.length>0,l=[`# Memfs status: ${n.identity}`,`Repository: ${n.identityPaths.repo}`,`HEAD: ${null===r?"(no commits)":Ve(r)}`,"Working tree: "+(s?`dirty — ${a.length} entr${1===a.length?"y":"ies"}`:"clean"),`Mirror: ${o.redactedUrl??"not configured"}${void 0===o.url?"":` (${o.aheadCount} ahead)`}`];s&&l.push("",...a,"","uncommitted changes present; inspect with /memfs diff or commit through the memory tools");let c=await async function(t){let e,n;try{e=await P(Q(t,wn),"utf8")}catch{return}try{n=JSON.parse(e)}catch{return}if(null===n||"object"!=typeof n||Array.isArray(n))return;let i=Object.entries(n);if(0===i.length)return;let r=["","## Skills usage"];for(let[t,e]of i){if(null===e||"object"!=typeof e||Array.isArray(e))continue;let n=e,i="number"==typeof n.count?n.count:0,a="string"==typeof n.lastUsedAt?n.lastUsedAt:"unknown";r.push(` ${t}: ${i} read${1===i?"":"s"}, last ${a}`)}return r.length>2?r.join("\n"):void 0}(n.identityPaths.runtime);return void 0!==c&&l.push(c),an(e,l.join("\n"),s?"warning":"info")},init:async({deps:t,ctx:e,identity:n})=>{if(Qe(n)){let i=await Je(t,n).head();return an(e,`memory repository already initialized at ${n.identityPaths.repo}${null===i?"":` (HEAD ${Ve(i)})`}`)}let i=await Je(t,n).init();return an(e,`initialized memory repository at ${n.identityPaths.repo} (HEAD ${Ve(i)})`)},sync:async({deps:t,ctx:e,identity:n})=>{let i=tn(t,n);if("string"==typeof i)return an(e,i,"error");let r=new Me({repo:i,...void 0===t.exec?{}:{exec:t.exec}}),a=await r.status();if(void 0===a.url)return an(e,"no memory repository mirror configured; set one with /memory-repository set <url>","error");let o=await r.pushNow();return o.pushed?an(e,`pushed main to ${a.redactedUrl}`):an(e,`push to ${a.redactedUrl} failed: ${o.detail}`,"error")},repair:async({deps:t,ctx:e,identity:n})=>{let i=tn(t,n);if("string"==typeof i)return an(e,i,"error");let r=De(i.dir),a=await mn(i.dir),o=function(t){let e=[];return t.repaired.length>0&&e.push(`added missing \`name:\` frontmatter to ${t.repaired.length} skill${1===t.repaired.length?"":"s"}: ${t.repaired.map(t=>`\`${t}\``).join(", ")}`),t.skipped.length>0&&e.push(`could not repair ${t.skipped.length} skill${1===t.skipped.length?"":"s"}: ${t.skipped.map(t=>`\`${t.path}\` (${t.reason})`).join(", ")}`),e.join("\n")}(a),s=[`# Memfs repair: ${n.identity}`,`- reinstalled ${r.length} git hook${1===r.length?"":"s"}`,`- scanned ${a.scanned} skill file${1===a.scanned?"":"s"}`];return o.length>0&&s.push(...o.split("\n").map(t=>`- ${t}`)),an(e,s.join("\n"))},reset:async({deps:t,ctx:e,parsed:n,identity:i})=>{let r=tn(t,i);if("string"==typeof r)return an(e,r,"error");if(sn(e)){if(!0!==await(e.ui?.confirm?.("Reset memory repository",`This deletes ${i.identityPaths.repo} and starts an empty history. A backup is written first.`)))return an(e,"reset aborted; nothing changed")}else if(!0!==n.flags.get("force"))return an(e,"reset requires --force in a noninteractive session (no confirmation UI available): /memfs reset --force","error");let a=await Xe(t,i);return await M(i.identityPaths.repo,{recursive:!0,force:!0}),an(e,`reset complete; backup at ${a}; new HEAD ${Ve(await Je(t,i).init())}`)},backup:async({deps:t,ctx:e,identity:n})=>{let i=tn(t,n);return"string"==typeof i?an(e,i,"error"):an(e,`backup written to ${await Xe(t,n)}`)},restore:async({deps:t,ctx:e,parsed:n,identity:i})=>{let r=await async function(t){let e;try{e=await T(Ye(t))}catch{return[]}return e.filter(t=>t.startsWith(Ke)).sort()}(i);if(0===r.length)return an(e,`no backups found for ${i.identity} in ${i.identityPaths.root}`,"error");let a,o=n.positionals[1];if(void 0===o){if(!sn(e))return an(e,`specify a backup name: /memfs restore <name>; available: ${r.join(", ")}`,"error");let t=await(e.ui?.select?.("Restore memory backup",[...r]));if(void 0===t)return an(e,"restore cancelled; nothing changed");a=t}else a=o;if(!r.includes(a))return an(e,`unknown backup: ${a}; available: ${r.join(", ")}`,"error");let s=await async function(t,e,n){let i=qe(Ye(e),n),r=e.identityPaths.repo,a=V(r)?await Xe(t,e):void 0;return await M(r,{recursive:!0,force:!0}),await S(i,r,{recursive:!0}),{restored:n,safetyBackup:a}}(t,i,a),l=void 0===s.safetyBackup?"":`; safety backup at ${s.safetyBackup}`;return an(e,`restored ${s.restored} into ${i.identityPaths.repo}${l}`)},diff:async({deps:t,ctx:e,identity:n})=>{let i=tn(t,n);if("string"==typeof i)return an(e,i,"error");let r=await function(t,e,n){return(t.exec??xt()).run(n,{cwd:e,timeoutMs:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}})}(t,i.dir,["diff"]);if(0!==r.code)return an(e,`git diff failed: ${r.stderr.trim()||`exit ${r.code}`}`,"error");let a=r.stdout.trim();return 0===a.length?an(e,"No changes."):an(e,`# Memfs diff: ${n.identity}\n\n${a}`,"warning")},tokens:async({deps:t,ctx:e,identity:n})=>{let i=tn(t,n);if("string"==typeof i)return an(e,i,"error");let r=await rn(i.dir),a=[`# System prompt token estimate (bytes/4): ${n.identity}`,`Total: ~${r.totalTokens} tokens (${r.totalBytes} bytes)`];if(r.files.length>0){a.push(""," tokens path");for(let t of r.files)a.push(` ${String(t.tokens).padStart(6)} ${t.path}`)}return an(e,a.join("\n"))}};async function $n(t,e,n){let i=function(t,e={}){let n=new Set(e.booleans??[]),i=[],r=new Map,a=t.trim().split(/\s+/).filter(Boolean);for(let t=0;t<a.length;t+=1){let e=a[t]??"";if(!e.startsWith("--")){i.push(e);continue}let o=e.slice(2),s=o.indexOf("=");if(s>=0){r.set(o.slice(0,s),o.slice(s+1));continue}let l=a[t+1];n.has(o)||void 0===l||l.startsWith("--")?r.set(o,!0):(r.set(o,l),t+=1)}return{positionals:i,flags:r}}(e,{booleans:["force"]}),[r]=i.positionals;if(void 0===r)return an(n,`usage: /memfs <${yn.join("|")}>`,"error");let a=gn[r];if(void 0===a)return an(n,`unknown /memfs subcommand: ${r}; expected one of ${yn.join(", ")}`,"error");let o="init"===r?function(t,e){return on(t,e)??t.resolveIdentity?.()}(t,n):function(t,e){let n=on(t,e);return void 0!==n?n:"memory is not bound to this session; start a session with memory enabled and retry"}(t,n);return void 0===o?an(n,"no memory identity resolved; check the memory config for this project","error"):"string"==typeof o?an(n,o,"error"):a({deps:t,ctx:n,parsed:i,identity:o})}export{$n as runMemfs};
1
+ // omo:WZ47QadUHT8tICEri7wLm31SJQIn7CQdymFl75yg-F4:J1ATJvoU_roB1dst5WvKFh8HMvMS_e2SNWn9WtddDs0
2
+ import{Buffer as t}from"node:buffer";import*as e from"node:fs";import*as n from"node:fs/promises";function r(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}async function i(t){for(let e=0;;e+=1)try{return await t()}catch(t){if("EINTR"!==r(t)||e>=128)throw t}}function a(t){for(let e=0;;e+=1)try{return t()}catch(t){if("EINTR"!==r(t)||e>=128)throw t}}var s=new Set(["EPERM","EBUSY","EACCES"]),o=[10,25,50,100,200,400],l=t=>new Promise(e=>setTimeout(e,t));import{Buffer as c}from"node:buffer";import{constants as u}from"node:fs";import*as d from"node:fs/promises";function f(t){return"number"==typeof t?0!==(t&u.O_EXCL):"string"==typeof t&&t.toLowerCase().includes("x")}async function h(t,e,n,r){let a="string"==typeof e?c.from(e,n??"utf8"):e,s=0;for(;s<a.length;){r?.throwIfAborted();let{bytesWritten:e}=await i(()=>t.write(a,s));if(e<=0)throw Error(`fs write made no progress at offset ${s}`);s+=e}}function p(t){return"function"==typeof t}function m(t){return(...e)=>i(async()=>t(...e))}function w(t){return(...e)=>a(()=>t(...e))}function y(t,e){let n="async"===e?m:w,r=new Map;return new Proxy(t,{get(t,e){if(r.has(e))return r.get(e);let i=Reflect.get(t,e);if(!p(i))return i;let a=n(i),s=Reflect.get(i,"native");return p(s)&&Object.assign(a,{native:n(s)}),r.set(e,a),a}})}var g=new Set(["stat","sync","datasync","chmod","chown","utimes","truncate"]);var $=y(n,"async");function v(t,e){return async function(t,e,n){let i="win32"===n.platform?n.delaysMs??o:[],a=n.sleep??l;for(let o=0;;o+=1)try{return void await n.rename(t,e)}catch(t){let e=i[o],n=r(t);if(void 0===e||void 0===n||!s.has(n))throw t;await a(e)}}(t,e,{rename:$.rename,platform:process.platform})}var k=y(e,"sync"),{access:b,chmod:x,copyFile:S,cp:E,link:I,lstat:A,mkdir:_,mkdtemp:T,readFile:N,readdir:P,realpath:L,rm:M,rmdir:O,stat:R,unlink:j}=$,{accessSync:B,chmodSync:D,fsyncSync:C,linkSync:z,lstatSync:H,mkdirSync:U,readFileSync:W,readdirSync:F,realpathSync:G,statSync:q,unlinkSync:Z,writeFileSync:K,writeSync:Y}=k,J=async(...t)=>{let e=()=>n.open(...t);return function(t){return new Proxy(t,{get(t,e){let n=Reflect.get(t,e);if(!p(n))return n;let a=e=>Reflect.apply(n,t,[...e]);return"close"===e||e===Symbol.asyncDispose?(...t)=>{let e=a(t);return e instanceof Promise?e.catch(t=>{if("EINTR"!==r(t))throw t}):e}:"string"==typeof e&&g.has(e)?(...t)=>{let e=a(t);return e instanceof Promise?e.catch(e=>{if("EINTR"!==r(e))throw e;return i(async()=>a(t))}):e}:(...t)=>a(t)}})}(await(f(t[1]??"r")?e():i(e)))};var X=async(e,a,s)=>{if("string"!=typeof a&&!(a instanceof Uint8Array))return n.writeFile(e,a,s);if("object"==typeof(o=e)&&!(o instanceof URL)&&!t.isBuffer(o)&&"fd"in o){let t="string"==typeof s?{encoding:s}:s??{};return t.signal?.throwIfAborted(),await h(e,a,t.encoding??void 0,t.signal),void(!0===t.flush&&await i(()=>e.sync()))}var o;return async function(t,e,n,a){let s="string"==typeof n?{encoding:n}:n??{};s.signal?.throwIfAborted();let o=s.flag??a,l=()=>d.open(t,o,s.mode),c=await(f(o)?l():i(l));try{await h(c,e,s.encoding??"utf8",s.signal),!0===s.flush&&await i(()=>c.sync())}finally{await c.close().catch(t=>{if("EINTR"!==r(t))throw t})}}(e,a,s??void 0,"w")};function V(t){try{return a(()=>e.statSync(t)),!0}catch{return!1}}import{join as Q}from"node:path";import{resolve as tt}from"node:path";var et=/(could not lock config file|unable to create '[^']*config\.lock')/i,nt=/(could not lock config file|unable to create '[^']*\.lock'|cannot lock ref|another git process seems to be running)/i,rt=new Map;function it(t){return et.test(st(t))}function at(t){return nt.test(st(t))}function st(t){return t instanceof Error?t.message:String(t)}async function ot(t,e){let n=tt(t),r=(rt.get(n)??Promise.resolve()).catch(()=>{}).then(()=>async function(t){for(let e=1;e<=5;e+=1)try{return void await t()}catch(t){if(!it(t)||5===e)throw t;await ct(25*2**(e-1))}}(e));rt.set(n,r);try{await r}finally{rt.get(n)===r&&rt.delete(n)}}async function lt(t){for(let e=1;e<=5;e+=1)try{return await t()}catch(t){if(!at(t)||5===e)throw t;await ct(25*2**(e-1))}throw Error("unreachable: git lock retry exhausted without result")}function ct(t){return new Promise(e=>setTimeout(e,t))}class ut extends Error{constructor(t,e){super(t,e),this.name=new.target.name}}class dt extends ut{argv;code;stdout;stderr;constructor(t,e,n,r){let i=r.trim()||n.trim()||`exit code ${e}`;super(`git ${t.join(" ")} failed: ${i}`),this.argv=t,this.code=e,this.stdout=n,this.stderr=r}}class ft extends ut{argv;timeoutMs;constructor(t,e){super(`git ${t.join(" ")} timed out after ${e}ms`),this.argv=t,this.timeoutMs=e}}class ht extends ut{argv;constructor(t){super(`git ${t.join(" ")} was cancelled`),this.argv=t}}class pt extends ut{constructor(t){super("Git is required for memory storage but was not found on PATH.",t)}}class mt extends ut{porcelain;encodingDiagnostics;constructor(t,e){let n=e.length>0?` Dirty markdown encoding issue(s): ${e.join("; ")}.`:"";super(`Memory repo has uncommitted changes. Commit, discard, or sync them before using memory tools.\n${t.trimEnd()}${n}`),this.porcelain=t,this.encodingDiagnostics=e}}class wt extends ut{paths;constructor(t){super(`Memory write produced no effective changes for: ${t.join(", ")}`),this.paths=t}}class yt extends ut{}import{spawn as gt}from"node:child_process";import{win32 as $t}from"node:path";var vt=[["ProgramFiles",["Git","cmd","git.exe"]],["ProgramW6432",["Git","cmd","git.exe"]],["ProgramFiles(x86)",["Git","cmd","git.exe"]],["LOCALAPPDATA",["Programs","Git","cmd","git.exe"]]];function kt(t,e){for(let[n,r]of Object.entries(t)){if(n.toLowerCase()!==e.toLowerCase()||void 0===r)continue;let t=r.trim();if(t.length>0)return t}}function bt(t){return t instanceof pt&&t.cause instanceof Error&&"ENOENT"===t.cause.code}function xt(t,e,n,r){return new Promise((i,a)=>{let s=void 0!==n.stdin,o=gt(t,[...e],{cwd:n.cwd,env:r,shell:!1,stdio:[s?"pipe":"ignore","pipe","pipe"],windowsHide:!0}),l=[],c=[],u=!1,d=!1,f=setTimeout(()=>{d=!0,o.kill("SIGKILL")},n.timeoutMs),h=!1,p=()=>{h=!0,o.kill("SIGTERM")};!0===n.signal?.aborted?p():n.signal?.addEventListener("abort",p,{once:!0}),o.stdout.on("data",t=>l.push(t)),o.stderr.on("data",t=>c.push(t)),s&&o.stdin.end(n.stdin),o.on("error",t=>{if(!u)if(u=!0,clearTimeout(f),n.signal?.removeEventListener("abort",p),"ENOENT"===t.code){if(!V(n.cwd))return void i({code:128,stdout:"",stderr:`fatal: cannot change to '${n.cwd}': No such file or directory`});a(new pt({cause:t}))}else a(t)}),o.on("close",t=>{if(u)return;if(u=!0,clearTimeout(f),n.signal?.removeEventListener("abort",p),h)return void a(new ht(e));if(d)return void a(new ft(e,n.timeoutMs));let r=Buffer.concat(l);i({code:t??1,stdout:r.toString("utf8"),stderr:Buffer.concat(c).toString("utf8"),stdoutBytes:r})})})}function St(t={}){let e=t.platform??process.platform,n=t.runCommand??xt;return{async run(t,r){let i=r.env??process.env;try{return await n("git",t,r,i)}catch(a){if("win32"!==e||!bt(a))throw a;for(let e of function(t){let e=new Set,n=[];for(let[r,i]of vt){let a=kt(t,r);if(void 0===a||!/^[A-Za-z]:[\\/]/.test(a))continue;let s=$t.join(a,...i),o=$t.normalize(s).toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}(i))try{return await n(e,t,r,i)}catch(t){if(bt(t))continue;throw t}throw a}}}}import{join as Et}from"node:path";function It(t){return["-c",`user.name=${t.authorName.trim()||t.agentId}`,"-c",`user.email=${t.authorEmail??`${t.agentId}@omo.local`}`]}function At(t){return[...new Set(t.map(t=>t.replace(/\\/g,"/")).filter(t=>t.trim()))]}function _t(t){let e=t.replace(/\\/g,"/"),n=e.split("/").filter(Boolean);if(!e||e.startsWith("/")||n.some(t=>"."===t||".."===t))throw new yt(`Invalid memory seed path: ${t}`);return n.join("/")}function Tt(t,e){return new dt(t,e.code,e.stdout,e.stderr)}import{randomUUID as Nt}from"node:crypto";import{isAbsolute as Pt,resolve as Lt}from"node:path";import{randomUUID as Mt}from"node:crypto";import{basename as Ot,dirname as Rt,join as jt}from"node:path";async function Bt(t,e,n,r,i){let a=jt(t,e);await zt(t,e),i||await async function(t){try{let e=await A(t);if(!e.isFile())throw Ht(t,e.isSymbolicLink()?"symlink":"non-file")}catch(t){if("ENOENT"!==Ut(t))throw t}}(a),await _(Rt(a),{recursive:!0}),await zt(t,e);let s=jt(Rt(a),`.${Ot(a)}.omo-${process.pid}-${Mt()}`),o=await J(s,"wx",r);try{await h(o,n,"utf8"),await x(s,r),await o.sync()}catch(t){throw await o.close(),await M(s,{force:!0}),t}if(await o.close(),i){try{await I(s,a)}catch(t){if(await M(s,{force:!0}),"EEXIST"===Ut(t))return!1;throw t}await M(s)}else await v(s,a);return await Wt(Rt(a)),!0}async function Dt(t,e,n){let r=jt(t,e);try{await I(n,r)}catch(t){if("EEXIST"===Ut(t))return!1;throw t}return await M(n),await Wt(Rt(r)),!0}async function Ct(t){await M(t,{force:!0})}async function zt(t,e){let n=e.split("/").slice(0,-1),r=t;for(let t of n){r=jt(r,t);try{let t=await A(r);if(t.isSymbolicLink()||!t.isDirectory())throw Ht(e,"unsafe parent")}catch(t){if("ENOENT"===Ut(t))return;throw t}}}function Ht(t,e){return new Zt(`Unsupported worktree ${e} at path: ${t}`)}function Ut(t){return t instanceof Error&&"code"in t&&"string"==typeof t.code?t.code:void 0}async function Wt(t){try{let e=await J(t,"r");try{await e.sync()}finally{await e.close()}}catch(t){if("win32"!==process.platform||!["EISDIR","EPERM","EACCES","EINVAL"].includes(Ut(t)??""))throw t}}async function Ft(t){let e,n=(await Gt(t,["rev-parse","--git-path","index"])).stdout.trim(),r=Pt(n)?n:Lt(t.dir,n),i=`${r}.lock`,a=`${r}.omo-${process.pid}-${Nt()}`;try{e=await J(i,"wx")}catch(t){if("EEXIST"===Ut(t))return!1;throw t}let s=!1;try{if(o=await t.capture(),l=t.expected,JSON.stringify(o)!==JSON.stringify(l))return!1;await S(r,a);let n=null===t.next?["update-index","--force-remove","--",t.path]:["update-index","--add","--cacheinfo",t.next.mode,t.next.oid,t.path];return await Gt(t,n,{GIT_INDEX_FILE:a}),await h(e,await N(a)),await e.sync(),await e.close(),await v(i,r),s=!0,!0}finally{s||await e.close().catch(()=>{}),await M(a,{force:!0}),s||await M(i,{force:!0})}var o,l}async function Gt(t,e,n={}){let r=await t.exec.run(e,{cwd:t.dir,timeoutMs:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0",...n}});if(0!==r.code)throw Tt(e,r);return r}var qt=new Set(["100644","100755"]);class Zt extends Error{constructor(t,e){super(t,e),this.name="GitPathStateError"}}class Kt{dir;exec;ownershipLossRecoveryPath;constructor(t,e){this.dir=t,this.exec=e}async capture(t){let e=Yt(t);return{index:await this.captureIndex(e),worktree:await this.captureWorktree(e)}}async captureAll(t){let e=[...new Set(t.map(Yt))],n=await Promise.all(e.map(async t=>[t,await this.capture(t)]));return new Map(n)}async hashWorktreeBlob(t,e=!1){return this.hashBlob([...e?["-w"]:[],"--no-filters","--stdin"],t)}async hashIndexBlob(t,e,n=!1){let r=Yt(t);return this.hashBlob([...n?["-w"]:[],`--path=${r}`,"--stdin"],e)}async readBlob(t){return Xt(t),(await this.git(["cat-file","blob",t])).stdout}async setIndex(t,e){let n=Yt(t);Vt(e),await this.git(["update-index","--add","--cacheinfo",e.mode,e.oid,n])}async writeIndexIfIdentity(t,e,n){let r=Yt(t);return null!==n&&Vt(n),Ft({dir:this.dir,exec:this.exec,path:r,expected:e,next:n,capture:()=>this.captureIndex(r)})}async removeIndex(t){let e=Yt(t);await this.git(["update-index","--force-remove","--",e])}async writeWorktree(t,e){let n=Yt(t);Qt(e),await Bt(this.dir,n,await this.readBlob(e.oid),e.mode,!1)}async writeWorktreeIfIdentity(t,e,n){this.ownershipLossRecoveryPath=void 0;let r=Yt(t);if("missing"===e.kind)return"missing"===(await this.captureWorktree(r)).kind&&("missing"===n.kind||(Qt(n),Bt(this.dir,r,await this.readBlob(n.oid),n.mode,!0)));let i=await async function(t,e){let n=jt(t,e);await zt(t,e);try{let t=await A(n);if(!t.isFile())throw Ht(e,t.isSymbolicLink()?"symlink":"non-file");let r=jt(Rt(n),`.${Ot(n)}.omo-moved-${process.pid}-${Mt()}`);return await v(n,r),r}catch(t){if("ENOENT"===Ut(t))return;throw t}}(this.dir,r);if(void 0===i)return!1;try{let t=await this.captureMovedWorktree(i);if(a=t,s=e,JSON.stringify(a)!==JSON.stringify(s))return await Dt(this.dir,r,i)||await Ct(i),!1;if("missing"===n.kind){let t=await this.reserveWorktreeDeletion(r,i);if(void 0===t)return await Ct(i),!1;let e=await t.verify();if(void 0===e)return await Ct(i),!1;let n=await e.finish();return!0!==n&&await Ct(i),"string"==typeof n&&(this.ownershipLossRecoveryPath=n),!0===n}Qt(n);let o=await Bt(this.dir,r,await this.readBlob(n.oid),n.mode,!0);return await Ct(i),o}catch(t){throw await Dt(this.dir,r,i)||await Ct(i),t}var a,s}consumeOwnershipLossRecoveryPath(){let t=this.ownershipLossRecoveryPath;return this.ownershipLossRecoveryPath=void 0,t}async reserveWorktreeDeletion(t,e){return async function(t,e,n,r){let i=jt(t,e),a=Mt();try{await _(i,{mode:448}),await X(jt(i,".omo-reservation"),a,"utf8")}catch(t){if("EEXIST"===Ut(t))return;throw t}let s=await A(i);return{verify:async()=>{let t;try{t=await A(i)}catch(t){if("ENOENT"===Ut(t))return;throw t}if(t.isDirectory()&&t.dev===s.dev&&t.ino===s.ino){try{if(await N(jt(i,".omo-reservation"),"utf8")!==a)return}catch(t){if("ENOENT"===Ut(t))return;throw t}return{finish:async()=>{let t=jt(Rt(i),`.${Ot(i)}.omo-reserved-${process.pid}-${Mt()}`);try{await v(i,t)}catch(t){if("ENOENT"===Ut(t))return!1;throw t}let e,o=await A(t);if(o.isDirectory())try{e=await N(jt(t,".omo-reservation"),"utf8")}catch(t){if("ENOENT"!==Ut(t))throw t}if(!o.isDirectory()||o.dev!==s.dev||o.ino!==s.ino||e!==a){let e=await r(t);return!0!==e&&e}await M(n),await M(t,{recursive:!0}),await Wt(Rt(i));try{return await A(i),!1}catch(t){if("ENOENT"===Ut(t))return!0;throw t}}}}}}}(this.dir,t,e,e=>this.restoreWorktreeClaim(t,e))}async restoreWorktreeClaim(t,e){return async function(t,e,n){if(!(await A(n)).isFile())return n;try{await I(n,jt(t,e))}catch(t){if("EEXIST"===Ut(t))return n;throw t}return await M(n),!0}(this.dir,t,e)}async removeWorktree(t){await async function(t,e){let n,r=jt(t,e);await zt(t,e);try{n=await A(r)}catch(t){if("ENOENT"===Ut(t))return;throw t}if(!n.isFile())throw Ht(e,n.isSymbolicLink()?"symlink":"non-file");await M(r),await Wt(Rt(r))}(this.dir,Yt(t))}async captureIndex(t){let e=(await this.git(["--literal-pathspecs","ls-files","--stage","-z","--",t])).stdout.split("\0").filter(Boolean);if(0===e.length)return null;let n=e.map(Jt);if(n.some(t=>"0"!==t.stage))throw new Zt(`Git path is unmerged and cannot be recovered safely: ${t}`);if(1!==n.length||n[0]?.path!==t)throw new Zt(`Git path did not resolve to one stage-zero index entry: ${t}`);let r=n[0];if(!qt.has(r.mode))throw new Zt(`Unsupported Git index mode ${r.mode} for path: ${t}`);return{mode:r.mode,oid:r.oid}}async captureWorktree(t){await zt(this.dir,t);let e,n=Et(this.dir,t);try{e=await A(n)}catch(t){if("ENOENT"===Ut(t))return{kind:"missing"};throw t}if(!e.isFile())throw Ht(t,e.isSymbolicLink()?"symlink":"non-file");let r=await this.hashWorktreeBlob(await N(n),!0);return{kind:"file",mode:te(e.mode),oid:r}}async captureMovedWorktree(t){let e=await A(t);if(!e.isFile())throw Ht(t,e.isSymbolicLink()?"symlink":"non-file");return{kind:"file",mode:te(e.mode),oid:await this.hashWorktreeBlob(await N(t),!0)}}async hashBlob(t,e){let n=(await this.git(["hash-object",...t],e)).stdout.trim();return Xt(n),n}async git(t,e){let n=await this.exec.run(t,{cwd:this.dir,timeoutMs:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0"},...void 0===e?{}:{stdin:e}});if(0!==n.code)throw Tt(t,n);return n}}function Yt(t){let e=t.replace(/\\/g,"/"),n=e.split("/");if(!e||e.includes("\0")||e.startsWith("/")||/^[A-Za-z]:\//.test(e)||n.some(t=>!t||"."===t||".."===t||".git"===t.toLowerCase()))throw new Zt(`Invalid repository-relative Git path: ${t}`);return e}function Jt(t){let e=/^(\d{6}) ([0-9a-f]+) ([0-3])\t([\s\S]+)$/.exec(t);if(null===e)throw new Zt("Git returned a malformed index entry");return{mode:e[1],oid:e[2],stage:e[3],path:e[4]}}function Xt(t){if(!/^[0-9a-f]+$/.test(t))throw new Zt(`Invalid Git object ID: ${t}`)}function Vt(t){if(!qt.has(t.mode))throw new Zt(`Unsupported Git index mode: ${t.mode}`);Xt(t.oid)}function Qt(t){if("file"!==t.kind||!Number.isInteger(t.mode)||t.mode<0||t.mode>511)throw new Zt("Invalid worktree file identity");Xt(t.oid)}function te(t){return"win32"===process.platform?420:511&t}import{join as ee}from"node:path";function ne(t,e){return e.split(/\r?\n/).map(t=>t.trimEnd()).filter(Boolean).map(re).filter(t=>t?.endsWith(".md")??!1).map(e=>function(t,e){let n=ee(t,e);if(!V(n))return null;let r=W(n);return r.length>=2&&255===r[0]&&254===r[1]?`${e} has UTF-16 LE BOM`:r.length>=2&&254===r[0]&&255===r[1]?`${e} has UTF-16 BE BOM`:r.includes(0)?`${e} contains NUL bytes, possibly UTF-16`:null}(t,e)).filter(t=>null!==t)}function re(t){if(t.length<4)return null;let e=t.slice(0,2);if(" D"===e||"D "===e||"DD"===e)return null;let n=t.slice(3);return(n.includes(" -> ")?n.split(" -> ").pop()??n:n).replace(/^"|"$/g,"")}import{dirname as ie,join as ae}from"node:path";async function se(t){let{stdout:e}=await t(["count-objects","-v"]),n=/^count: (\d+)$/m.exec(e)?.[1];return void 0===n?0:Number(n)}import{randomUUID as oe}from"node:crypto";import{isAbsolute as le,join as ce}from"node:path";var ue=/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;class de{dir;git;lsTree;computed=new Map;constructor(t,e,n){this.dir=t,this.git=e,this.lsTree=n}async at(t){let e=ue.test(t)?t:await this.resolve(t),n=this.computed.get(e);if(void 0!==n)return this.computed.delete(e),this.computed.set(e,n),(await n).live;let r=[...this.computed.entries()].reverse(),i=this.compute(e,r);this.computed.set(e,i),i.catch(()=>{this.computed.get(e)===i&&this.computed.delete(e)});let a=this.computed.keys().next().value;return this.computed.size>4&&void 0!==a&&this.computed.delete(a),(await i).live}async resolve(t){return(await this.git.run(["rev-parse","--verify",`${t}^{commit}`])).stdout.trim()}async compute(t,e){let n=await this.lsTree(t),r=await this.reachableTimes(t,e);return{all:r,live:pe(n,r)}}async reachableTimes(t,e){let n=await this.readStore(),r=[...e.map(([t,e])=>[t,()=>e.then(t=>t.all,()=>null)]),...null===n?[]:[[n.revision,async()=>n.times]]];for(let[e,i]of r){if(e===t){let t=await i();if(null!==t)return t;continue}if(!await this.isAncestor(e,t))continue;let r=await i();if(null===r)continue;let a=he(r,fe((await this.log([`${e}..${t}`])).stdout));return e===n?.revision&&await this.writeStore(t,a),a}let i=fe((await this.log([t],3e5)).stdout);return(null===n||await this.isAncestor(n.revision,t))&&await this.writeStore(t,i),i}log(t,e){return this.git.run(["log","--format=%x01%ct","--name-only","-z","--no-renames","--diff-merges=first-parent","--diff-filter=d",...t,"--"],e)}async isAncestor(t,e){return 0===(await this.git.result(["merge-base","--is-ancestor",t,e])).code}async storePath(){let t=(await this.git.run(["rev-parse","--git-common-dir"])).stdout.trim();return ce(le(t)?t:ce(this.dir,t),"omo-path-commit-times.json")}async readStore(){let t;try{t=JSON.parse(await N(await this.storePath(),"utf8"))}catch{return null}if("object"!=typeof t||null===t)return null;let{version:e,revision:n,times:r}=t;if(2!==e||"string"!=typeof n||!ue.test(n))return null;if("object"!=typeof r||null===r||Array.isArray(r))return null;let i=Object.entries(r);return i.every(t=>Number.isSafeInteger(t[1]))?{revision:n,times:new Map(i)}:null}async writeStore(t,e){let n;try{let r=await this.storePath();n=`${r}.${process.pid}.${oe()}.tmp`,await X(n,`${JSON.stringify({version:2,revision:t,times:Object.fromEntries(e)})}\n`,"utf8"),await v(n,r)}catch{void 0!==n&&await M(n,{force:!0}).catch(()=>{})}}}function fe(t){let e=new Map,n=Number.NaN;for(let r of t.split("\0")){if(r.startsWith("")){n=Number.parseInt(r.slice(1),10);continue}let t=r.replace(/^\n/,"");0!==t.length&&Number.isSafeInteger(n)&&e.set(t,Math.max(e.get(t)??n,n))}return e}function he(t,e){let n=new Map(t);for(let[t,r]of e)n.set(t,Math.max(n.get(t)??r,r));return n}function pe(t,e){let n=new Map;for(let r of t){let t=e.get(r);void 0!==t&&n.set(r,t)}return n}function me(t){return t.split("\0").filter(Boolean)}function we(t){let e={};for(let n of t.split(/\r?\n/)){let t=/^([^:\s][^:]*):\s*(.*)$/.exec(n);if(null===t)continue;let r=t[1]?.trim();void 0!==r&&r.length>0&&(e[r]=t[2]??"")}return e}class ye{git;constructor(t){this.git=t}async head(){let t=await this.git.result(["rev-parse","--verify","HEAD"]);return 0!==t.code?null:t.stdout.trim()||null}async headCommitTimestamp(){let t=await this.git.result(["show","-s","--format=%ct","HEAD"]);if(0!==t.code)return null;let e=Number.parseInt(t.stdout.trim(),10);return Number.isSafeInteger(e)&&e>=0?e:null}async lsTree(t="HEAD",e){let n=e?["--",e]:[];return(await this.git.run(["ls-tree","-r","--name-only","-z",t,...n])).stdout.split("\0").filter(Boolean)}async lsTreeSized(t="HEAD"){return function(t){let e=[];for(let n of t.split("\0")){if(0===n.length)continue;let t=n.indexOf("\t");if(-1===t)continue;let r=n.slice(0,t).trim().split(/\s+/),i=n.slice(t+1);if(r.length<4||0===i.length)continue;let a=r[3];if(void 0===a||"-"===a)continue;let s=Number.parseInt(a,10);!Number.isSafeInteger(s)||s<0||e.push({path:i,bytes:s})}return e}((await this.git.run(["ls-tree","-r","-l","-z",t])).stdout)}async lsTreeBlobs(t="HEAD"){return function(t){let e=[];for(let n of t.split("\0")){let t=n.indexOf("\t");if(-1===t)continue;let[,r,i]=n.slice(0,t).trim().split(/\s+/),a=n.slice(t+1);"blob"===r&&void 0!==i&&0!==a.length&&e.push({path:a,oid:i})}return e}((await this.git.run(["ls-tree","-r","-z",t])).stdout)}async show(t,e){return(await this.git.run(["show",`${t}:${e}`])).stdout}async readBlobs(t){let e=[...new Set(t)];if(0===e.length)return new Map;let n=["cat-file","--batch"],r=await this.git.result(n,`${e.join("\n")}\n`);if(0!==r.code)throw Tt(n,r);return function(t){let e=new Map,n=0;for(;n<t.length;){let r=t.indexOf(10,n);if(-1===r)throw Error("git cat-file --batch output ended inside a record header");let i=t.toString("utf8",n,r);n=r+1;let[a,s,o]=i.split(" ");if(void 0===o)continue;let l=Number.parseInt(o,10);if(void 0===a||!Number.isSafeInteger(l)||l<0||n+l>t.length)throw Error(`git cat-file --batch output is malformed at "${i}"`);"blob"===s&&e.set(a,t.toString("utf8",n,n+l)),n+=l+1}return e}(r.stdoutBytes??Buffer.from(r.stdout,"utf8"))}async log(t={}){let e=["log","--format=%x1e%H%x1f%s%x1f%b%x1f%an%x1f%ae%x1f%cI"];void 0!==t.grep&&t.grep.length>0&&e.push("--fixed-strings","--all-match",...t.grep.map(t=>`--grep=${t}`)),void 0!==t.limit&&e.push("-n",String(t.limit)),void 0!==t.since&&e.push(`--since=${t.since.toISOString()}`),void 0!==t.range&&e.push(t.range),void 0!==t.paths&&t.paths.length>0&&e.push("--",...t.paths);let n=(await this.git.run(e,t.timeoutMs)).stdout.split("").slice(1).map(t=>{let[e="",n="",r="",i="",a="",s=""]=t.split(""),o=r.replace(/\r?\n$/,"");return{sha:e,subject:n,body:o,authorName:i,authorEmail:a,committedAt:s.trim(),trailers:we(o)}});return!0!==t.includePaths?n:Promise.all(n.map(async t=>({...t,paths:me((await this.git.run(["diff-tree","--no-commit-id","--name-only","-z","-r",t.sha])).stdout)})))}}async function ge(t,e,n){let r=(await n()).split(/\r?\n/).filter(Boolean).filter(t=>{let n=re(t);return null!==n&&!e.some(t=>n===t||n.startsWith(`${t}/`)||t.startsWith(n.endsWith("/")?n:`${n}/`))});if(0===r.length)return;let i=`${r.join("\n")}\n`;throw new mt(i,ne(t,i))}var $e=[["aws_access_key","\\bAKIA[0-9A-Z]{16}\\b",""],["credential_assignment","\\b(?:bearer|token|api[_-]?key|secret|password|passwd|pwd)\\s*[=:]\\s*[^\\s\"'<>,}\\])]{1,256}","i"],["authorization_header","\\bAuthorization\\s*:\\s*Bearer\\s+[^\\s\"'<>,}\\])]{1,256}","i"],["openai_key","\\bsk-(?:proj-)?[-_A-Za-z0-9]+\\b",""],["vendor_token","\\b(?:ghp|github_pat|glpat|xox[baprs])[-_][-_A-Za-z0-9]+\\b",""]],ve=/\p{Cf}/u;function ke(t){if(!t)return[];let e=[],{shadow:n,map:r}=function(t){let e="",n=[];for(let r=0;r<t.length;r+=1){let i=t.charCodeAt(r);if(160===i){e+=" ",n.push(r);continue}let a=t.charAt(r);i<32&&10!==i&&9!==i||ve.test(a)||(e+=a,n.push(r))}return{shadow:e,map:n}}(t),i=(t,e)=>{let n=r[t],i=r[e-1];if(void 0!==n&&void 0!==i)return{start:n,end:i+1}},a=0;for(;;){let t=xe(n,a);if(void 0===t)break;let r=i(t.start,t.end);void 0!==r&&e.push({class:"pem_block",...r}),a=t.end}for(let[t,r,a]of $e){let s,o=new RegExp(r,`${a}g`);for(;null!==(s=o.exec(n));){let n=i(s.index,s.index+s[0].length);void 0!==n&&e.push({class:t,...n})}}let s,o=new RegExp("(?:a\\s*u\\s*t\\s*h\\s*o\\s*r\\s*i\\s*z\\s*a\\s*t\\s*i\\s*o\\s*n|p\\s*a\\s*s\\s*s\\s*w\\s*(?:o\\s*r\\s*)?d|s\\s*e\\s*c\\s*r\\s*e\\s*t|t\\s*o\\s*k\\s*e\\s*n|a\\s*p\\s*i\\s*[_-]?\\s*k\\s*e\\s*y)\\s*[:=]\\s*[^\\s\"'<>,}\\])]{6,256}","gi");for(;null!==(s=o.exec(n));){let t=i(s.index,s.index+s[0].length);void 0!==t&&(e.some(e=>e.start<t.end&&t.start<e.end)||e.push({class:"split_credential_assignment",...t}))}return e.sort((t,e)=>t.start-e.start||t.end-e.end)}function be(t){if(!t)return"";let e=ke(t);if(0===e.length)return t;let n=[];for(let t of e){let e=n[n.length-1];void 0!==e&&t.start<=e.end?e.end=Math.max(e.end,t.end):n.push({start:t.start,end:t.end})}let r="",i=0;for(let e of n)r+=`${t.slice(i,e.start)}***`,i=e.end;return`${r}${t.slice(i)}`}function xe(t,e=0){let n=t.indexOf("-----BEGIN ",e);if(n<0)return;let r=t.indexOf("-----",n+11);if(r<0||r-(n+11)>64)return;let i=t.slice(n+11,r);if(0===i.length||/[^A-Za-z0-9 ]/.test(i))return;let a=t.indexOf("-----END ",r+5);for(;a>=0;){let e=a+9,r=t.indexOf("-----",e);if(r>=0&&t.slice(e,r)===i)return{start:n,end:r+5};a=t.indexOf("-----END ",r>=0?r+5:e)}}var Se=/([a-z][a-z0-9+.-]*:\/\/)([^/@\s:]{1,256})(?::([^/@\s]{0,256}))?@/gi,Ee=/(^|[\s'"(<])([^\s:/@]{1,256})@([^\s:/@]{1,256}):/g;function Ie(t){if(!t)return"";let e=t.includes("://")?t.replace(Se,(t,e,n,r)=>void 0===r?`${e}***@`:`${e}***:***@`):t;return be(e.includes("@")?e.replace(Ee,(t,e,n,r)=>`${e}***@${r}:`):e)}class Ae extends Error{name="MemorySecretError";path;patternClass;where;constructor(t){super("path"===t.where?`refused: ${be(t.path)} is a secret-like file name (${t.patternClass})`:`refused: ${t.path} contains secret-like content (${t.patternClass}); remove it and retry`),this.path=t.path,this.patternClass=t.patternClass,this.where=t.where}}function _e(t){return ke(t)[0]?.class}import{resolve as Te}from"node:path";var Ne=new Map;async function Pe(t,e){let n=Te(t),r=(Ne.get(n)?.then(()=>{},()=>{})??Promise.resolve()).then(e),i=r.then(()=>{},()=>{});Ne.set(n,i);try{return await r}finally{Ne.get(n)===i&&Ne.delete(n)}}class Le{dir;agentId;pathState;exec;hookInstaller;reads;commitTimes;constructor(t){this.dir=t.dir,this.agentId=t.agentId,this.exec=t.exec??St(),this.pathState=new Kt(this.dir,this.exec),this.hookInstaller=t.installHooks??(()=>{}),this.reads=new ye({run:(t,e)=>this.git(t,e),result:(t,e)=>this.gitResult(t,e)}),this.commitTimes=new de(this.dir,{run:(t,e)=>this.git(t,e),result:(t,e)=>this.gitResult(t,e)},t=>this.reads.lsTree(t))}async init(t={}){await _(this.dir,{recursive:!0}),V(ae(this.dir,".git"))||(await lt(()=>this.git(["init","--template="])),await lt(()=>this.git(["symbolic-ref","HEAD","refs/heads/main"]))),await(t.installHooks??this.hookInstaller)(this.dir),await this.ensureIdentity(t.authorName?.trim()||"OmO Agent");let e=await this.head();if(e)return e;let n=[];for(let e of t.seedFiles??[]){let t=_t(e.relativePath),r=ae(this.dir,t);await _(ie(r),{recursive:!0}),await X(r,e.content,"utf8"),n.push(t)}let r={agentId:this.agentId,authorName:t.authorName?.trim()||"OmO Agent"};return n.length>0&&(await this.stage(n),await this.hasPathChanges(n))?(await this.commitStaged("chore: initialize local memory",r)).sha:(await lt(()=>this.git([...It(r),"commit","--allow-empty","-m","chore: initialize empty local memory"])),this.requireHead())}async cleanCheck(){await this.hookInstaller(this.dir);let t=await this.status();if(t.trim())throw new mt(t,ne(this.dir,t))}async commitWrite(t,e,n){await this.hookInstaller(this.dir);let r=At(t);if(0===r.length)throw new wt(r);return await ge(this.dir,r,()=>this.status()),await this.stage(r),this.commitPrepared(r,e,n)}async commitPrepared(t,e,n){await this.hookInstaller(this.dir);let r=At(t);if(0===r.length)throw new wt(r);if(await ge(this.dir,r,()=>this.status()),!await this.hasPathChanges(r))throw new wt(r);return await this.assertNoSecretLikeStaging(r),this.commitStaged(e,n)}async status(t=[]){let e=At(t),n=e.length>0?["--",...e]:[];return(await this.git(["-c","core.quotePath=false","status","--porcelain","--untracked-files=all",...n])).stdout}head(){return this.reads.head()}headCommitTimestamp(){return this.reads.headCommitTimestamp()}lsTree(t="HEAD",e){return this.reads.lsTree(t,e)}lsTreeSized(t="HEAD"){return this.reads.lsTreeSized(t)}lsTreeBlobs(t="HEAD"){return this.reads.lsTreeBlobs(t)}show(t,e){return this.reads.show(t,e)}pathCommitTimes(t){return this.commitTimes.at(t)}readBlobs(t){return this.reads.readBlobs(t)}log(t={}){return this.reads.log(t)}async restorePaths(t){let e=At(t);if(0===e.length)return;let n=new Set(await this.lsTree("HEAD")),r=e.filter(t=>n.has(t)),i=e.filter(t=>!n.has(t));r.length>0&&await lt(()=>this.git(["restore","--source=HEAD","--staged","--worktree","--",...r]));for(let t of i)await lt(()=>this.git(["rm","-q","--cached","--ignore-unmatch","--",t])),await M(ae(this.dir,t),{force:!0})}async assertNoSecretLikeStaging(t){for(let e of t){let t=_e(e);if(void 0!==t)throw new Ae({path:e,patternClass:t,where:"path"})}for(let e of t){let t=await this.gitResult(["show",`:${e}`]);if(0!==t.code)continue;let n=_e(t.stdout);if(void 0!==n)throw new Ae({path:e,patternClass:n,where:"content"})}}maintain(t){return async function(t,e){let n=await se(t);return n<e.minLooseObjects?{status:"skipped",looseObjects:n}:(await t(["maintenance","run","--task=loose-objects","--quiet"],e.timeoutMs,e.signal),e.signal?.throwIfAborted(),await t(["prune-packed","--quiet"],e.timeoutMs,e.signal),{status:"packed",looseObjectsBefore:n,looseObjectsAfter:await se(t)})}((t,e,n)=>this.git(t,e,n),t)}async worktreeAdd(t,e,n="HEAD"){await Pe(this.dir,()=>lt(()=>this.git(["worktree","add","-b",e,t,n])))}async worktreeRemove(t,e=!0){await Pe(this.dir,()=>lt(()=>this.git(["worktree","remove",...e?["--force"]:[],t])))}async merge(t,e={}){let n=["merge"];return(e.noFF??!0)&&n.push("--no-ff"),e.message&&n.push("-m",e.message),n.push(t),await lt(()=>this.git(n)),this.requireHead()}async configGet(t){let e=await this.gitResult(["config","--local","--get",t]);if(1===e.code)return null;if(0!==e.code)throw Tt(["config","--local","--get",t],e);return e.stdout.trim()||null}async configSet(t,e){await ot(this.dir,async()=>{await this.git(["config","--local",t,e])})}async ensureIdentity(t){await this.configGet("omo.agentId")!==this.agentId&&await this.configSet("omo.agentId",this.agentId),await this.configGet("user.email")||await this.configSet("user.email",`${this.agentId}@omo.local`),await this.configGet("user.name")||await this.configSet("user.name",t),null===await this.configGet("commit.gpgsign")&&await this.configSet("commit.gpgsign","false"),null===await this.configGet("gc.auto")&&await this.configSet("gc.auto","0")}async stage(t){await lt(()=>this.git(["add","-A","--",...t]))}async hasPathChanges(t){return(await this.status(t)).trim().length>0}async commitStaged(t,e){return await lt(()=>this.git([...It(e),"commit","-m",t])),{committed:!0,sha:await this.requireHead()}}async requireHead(){let t=await this.head();if(!t)throw Error("Memory repository has no HEAD commit");return t}async git(t,e,n){let r=await this.gitResult(t,void 0,e,n);if(0!==r.code)throw Tt(t,r);return r}gitResult(t,e,n=3e4,r){return this.exec.run(t,{cwd:this.dir,timeoutMs:n,...void 0===r?{}:{signal:r},env:{...process.env,GIT_TERMINAL_PROMPT:"0"},...void 0===e?{}:{stdin:e}})}}import{execFile as Me}from"node:child_process";var Oe=null;function Re(){return Oe??=async function(){if("darwin"!==process.platform)return null;try{let{dlopen:t,FFIType:e}=await(import("bun:ffi")),n=t("/usr/lib/libSystem.B.dylib",{proc_pidinfo:{args:[e.i32,e.i32,e.u64,e.ptr,e.i32],returns:e.i32}});return(t,e,r,i,a)=>Number(n.symbols.proc_pidinfo(t,e,r,i,a))}catch{return null}}(),Oe}var je=null;async function Be(t){if("win32"!==process.platform)return null;if(!Number.isSafeInteger(t)||t<=0)return null;je??=async function(){if("win32"!==process.platform)return null;try{let{dlopen:t,FFIType:e}=await(import("bun:ffi"));return t("kernel32.dll",{OpenProcess:{args:[e.u32,e.i32,e.u32],returns:e.ptr},GetProcessTimes:{args:[e.ptr,e.ptr,e.ptr,e.ptr,e.ptr],returns:e.i32},CloseHandle:{args:[e.ptr],returns:e.i32}}).symbols}catch{return null}}();let e=await je;if(null===e)return null;let n=e.OpenProcess(4096,0,t);if(null===n||0===n||0n===n)return null;try{let t=new BigUint64Array(1),r=e.GetProcessTimes(n,t,new BigUint64Array(1),new BigUint64Array(1),new BigUint64Array(1)),i=t[0]??0n;return 0===r||0n===i?null:i}finally{e.CloseHandle(n)}}async function De(t,e){return await new Promise(n=>{Me(t,e,{encoding:"utf8",timeout:2e3,windowsHide:!0},(t,e)=>{if(null!==t)return void n(null);let r=e.trim();n(r.length>0?r:null)})})}!function(t,e){let n}(async function(t){if("linux"===process.platform)return await async function(t){try{let e=await N(`/proc/${t}/stat`,"utf8"),n=e.lastIndexOf(")");if(n<0)return null;let r=e.slice(n+2).trim().split(/\s+/)[19];return void 0===r?null:`linux-proc-start-ticks:${r}`}catch{return null}}(t);if("darwin"===process.platform||"freebsd"===process.platform){if("dead"===Ce(t))return null;let e=await async function(t){if("darwin"!==process.platform)return null;if(!Number.isSafeInteger(t)||t<=0)return null;let e=await Re();if(null===e)return null;let n=new Uint8Array(136),r=0;try{r=e(t,3,0n,n,136)}catch{return null}if(136!==r)return null;let i=new DataView(n.buffer,n.byteOffset,n.byteLength),a=Number(i.getBigUint64(120,!0));return a>0?a:null}(t);if(null!==e)return`proc-start-epoch:${e}`;let n=await De("/bin/ps",["-o","lstart=","-p",String(t)]);return null===n?null:`ps-lstart:${n.replace(/\s+/g," ")}`}return"win32"===process.platform?await async function(t){if("dead"===Ce(t))return null;let e=await Be(t);if(null!==e)return`win32-creation-filetime:${e}`;let n=await De("powershell.exe",["-NoProfile","-Command",`(Get-Process -Id ${t} -ErrorAction SilentlyContinue).StartTime.ToUniversalTime().ToString('o')`]);return null===n?null:`win32-creation-date:${n}`}(t):null},process.pid);function Ce(t){try{return process.kill(t,0),"alive"}catch(t){let e=function(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}(t);return"ESRCH"===e?"dead":"EPERM"===e?"alive":"unknown"}}Promise.resolve();import{isAbsolute as ze,join as He,resolve as Ue}from"node:path";import{join as We}from"node:path";var Fe="omo.memoryRepository.url",Ge="memory-repository-push.log",qe="main",Ze=1e4;class Ke{repo;exec;constructor(t){this.repo=t.repo,this.exec=t.exec??St()}async set(t){let e=Ye(t);if(!e)throw Error("Memory repository URL must not be empty");return await this.repo.configSet(Fe,e),{url:e,...await this.push(e,1e4)}}async unset(){await ot(this.repo.dir,async()=>{let t=await this.run(["config","--local","--unset-all",Fe],Ze);if(0!==t.code&&5!==t.code)throw Error(Je(t))})}async status(){let t=await this.configuredUrl(),e=this.readLogTail();return t?{url:t,redactedUrl:Ie(t),lastLogLines:e,aheadCount:await this.aheadCount(t)}:{lastLogLines:e,aheadCount:0}}async pushNow(){let t=await this.configuredUrl();return t?this.push(t,6e4):{pushed:!1,detail:"No memory repository configured. Set one first."}}async configuredUrl(){return Ye(await this.repo.configGet(Fe)??"")||void 0}async push(t,e){let n=await this.run(["push","--quiet",t,`${qe}:${qe}`],e);return 0===n.code?{pushed:!0,detail:""}:{pushed:!1,detail:Ie(Je(n))}}async aheadCount(t){let e=await this.run(["ls-remote",t,`refs/heads/${qe}`],Ze),n=0===e.code?e.stdout.trim().split(/\s+/)[0]??"":"",r=n?`${n}..${qe}`:qe,i=await this.run(["rev-list","--count",r],Ze);return 0!==i.code?0:Number.parseInt(i.stdout.trim(),10)||0}readLogTail(){let t;try{t=W((e=this.repo.dir,We(e,".git",Ge)),"utf8")}catch{return[]}var e;return t.split(/\r?\n/).filter(t=>t.trim().length>0).slice(-20).map(Ie)}async run(t,e){try{return await this.exec.run(t,{cwd:this.repo.dir,timeoutMs:e,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}})}catch(t){return{code:1,stdout:"",stderr:t instanceof Error?t.message:String(t)}}}}function Ye(t){let e=t.trim();return e.replace(/\/+$/,"")||e}function Je(t){return t.stderr.trim()||t.stdout.trim()||`git exited with code ${t.code}`}var Xe=[{class:"aws_access_key",ere:"(^|[^A-Za-z0-9_])AKIA[0-9A-Z]{16}([^A-Za-z0-9_]|$)"},{class:"credential_assignment",ere:"(^|[^A-Za-z0-9_])([Bb][Ee][Aa][Rr][Ee][Rr]|[Tt][Oo][Kk][Ee][Nn]|[Aa][Pp][Ii][-_]?[Kk][Ee][Yy]|[Ss][Ee][Cc][Rr][Ee][Tt]|[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|[Pp][Aa][Ss][Ss][Ww][Dd]|[Pp][Ww][Dd])[[:space:]]*[=:][[:space:]]*[^[:space:]]{1,255}"},{class:"authorization_header",ere:"(^|[^A-Za-z0-9_])[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn][[:space:]]*:[[:space:]]*[Bb][Ee][Aa][Rr][Ee][Rr][[:space:]]+[^[:space:]]{1,255}"},{class:"openai_key",ere:"(^|[^A-Za-z0-9_])sk-(proj-)?[-_A-Za-z0-9]+([^A-Za-z0-9_-]|$)"},{class:"vendor_token",ere:"(^|[^A-Za-z0-9_])(ghp|github_pat|glpat|xox[baprs])[-_][-_A-Za-z0-9]+([^A-Za-z0-9_-]|$)"}].map(({class:t,ere:e})=>[` if printf '%s' "$blob" | grep -E -q -e '${e}'; then`,` printf 'memory pre-commit: %s contains secret-like content (${t})\\n' "$p"`," fi"].join("\n")).join("\n"),Ve=[{name:"pre-commit",script:`#!/bin/sh\n# Validate frontmatter in staged memory .md files.\n# Installed by omo memory-core. Do not edit by hand - regenerated on startup.\n\nALL_KNOWN_KEYS="description read_only limit kind aliases"\nTAB=$(printf '\\t')\n\nfm_value() {\n # $1 = file content, $2 = key. Prints the value of a top-level frontmatter\n # key, or nothing when the key is absent.\n closing=$(printf '%s\\n' "$1" | tail -n +2 | grep -n '^---$' | head -1 | cut -d: -f1)\n [ -z "$closing" ] && return 0\n printf '%s\\n' "$1" | tail -n +2 | head -n $((closing - 1)) |\n grep "^$2:" | head -1 | cut -d: -f2- | sed 's/^ *//;s/ *$//'\n}\n\ncheck_plain_scalar() {\n # $1 = file, $2 = key, $3 = value. A quoted value is the renderer's own\n # output; a plain value must be one that strict YAML reads back verbatim.\n case "$3" in\n \\"*|\\'*|"") return 0 ;;\n *": "*|*":"|*" #"*|"#"*|"["*|"]"*|"{"*|"}"*|"&"*|"*"*|"!"*|"|"*|">"*|"%"*|"@"*|"\\\`"*|","*|"?"*|"-"|"- "*)\n printf " %s: '%s' is not a safe YAML plain scalar (quote it, or remove ': ' and ' #'): %s\\n" "$1" "$2" "$3"\n ;;\n esac\n}\n\ncheck_keys() {\n # $1 = file, $2 = HEAD content, $3 = frontmatter, $4 = key policy\n # ("contract" = memory key allowlist, "skill" = any key). Prints one error\n # line per offending frontmatter key. Runs in a pipeline subshell, so it\n # must never rely on assignments leaking to the caller.\n printf '%s\\n' "$3" | while IFS= read -r line; do\n [ -z "$line" ] && continue\n # Indented lines are YAML continuations of the previous key.\n case "$line" in " "*|"$TAB"*) continue ;; esac\n\n key=$(printf '%s\\n' "$line" | cut -d: -f1 | tr -d ' ')\n value=$(printf '%s\\n' "$line" | cut -d: -f2- | sed 's/^ *//;s/ *$//')\n\n if [ "$4" != skill ]; then\n known=false\n for k in $ALL_KNOWN_KEYS; do\n [ "$key" = "$k" ] && known=true && break\n done\n if [ "$known" = false ]; then\n printf " %s: unknown frontmatter key '%s' (allowed: %s)\\n" "$1" "$key" "$ALL_KNOWN_KEYS"\n continue\n fi\n fi\n\n if [ "$key" != description ] && [ "$key" != aliases ] && [ "$key" != read_only ]; then\n check_plain_scalar "$1" "$key" "$value"\n fi\n\n if [ "$key" = read_only ]; then\n if [ -n "$2" ]; then\n [ "$value" != "$(fm_value "$2" read_only)" ] &&\n printf " %s: 'read_only' is a protected field and cannot be changed by the agent\\n" "$1"\n else\n printf " %s: 'read_only' is a protected field and cannot be set by the agent\\n" "$1"\n fi\n fi\n\n # Deviation from letta: a YAML block scalar ('>' or '|', with optional\n # chomping or indent modifiers) is rejected. letta accepted the indicator\n # as the value, which silently stored '>' as the description.\n if [ "$key" = description ]; then\n case "$value" in\n "") printf " %s: 'description' must not be empty\\n" "$1" ;;\n [\\>\\|]*) printf " %s: 'description' must be a non-empty single line\\n" "$1" ;;\n *) check_plain_scalar "$1" description "$value" ;;\n esac\n fi\n done\n}\n\ncheck_file() {\n # $1 = file, $2 = key policy ("contract" or "skill")\n file="$1"\n policy="\${2:-contract}"\n staged=$(git show ":$file")\n\n if [ "$(printf '%s\\n' "$staged" | head -1)" != "---" ]; then\n printf ' %s: missing frontmatter (must start with ---)\\n' "$file"\n return 0\n fi\n\n closing_line=$(printf '%s\\n' "$staged" | tail -n +2 | grep -n '^---$' | head -1 | cut -d: -f1)\n if [ -z "$closing_line" ]; then\n printf ' %s: frontmatter opened but never closed (missing closing ---)\\n' "$file"\n return 0\n fi\n\n head_content=$(git show "HEAD:$file" 2>/dev/null || true)\n if [ -n "$head_content" ] && [ "$(fm_value "$head_content" read_only)" = "true" ]; then\n printf ' %s: file is read_only and cannot be modified\\n' "$file"\n return 0\n fi\n\n frontmatter=$(printf '%s\\n' "$staged" | tail -n +2 | head -n $((closing_line - 1)))\n check_keys "$file" "$head_content" "$frontmatter" "$policy"\n\n if ! printf '%s\\n' "$frontmatter" | grep -q '^description:'; then\n printf " %s: missing required field 'description'\\n" "$file"\n fi\n\n if [ -n "$head_content" ] && [ -n "$(fm_value "$head_content" read_only)" ] &&\n [ -z "$(fm_value "$staged" read_only)" ]; then\n printf " %s: 'read_only' is a protected field and cannot be removed by the agent\\n" "$file"\n fi\n}\n\nerrors=$(\n # Skills must always be directories: skills/<name>/SKILL.md.\n git diff --cached --name-only --diff-filter=ACMR |\n grep -E '^(memory/)?skills/[^/]+\\.md$' |\n while IFS= read -r skill_file; do\n printf ' %s: invalid skill path (skills must be folders). Use skills/<name>/SKILL.md\\n' "$skill_file"\n done\n\n # Memory content keys are an allowlist under system/, reference/ and people/.\n git diff --cached --name-only --diff-filter=ACM |\n grep -E '^(memory/)?(system|reference|people)/.*\\.md$' |\n while IFS= read -r file; do\n check_file "$file" contract\n done\n\n # SKILL.md is read by the skill loader as strict YAML: same value rules,\n # description required, any key allowed.\n git diff --cached --name-only --diff-filter=ACM |\n grep -E '^(memory/)?skills/.+/SKILL\\.md$' |\n while IFS= read -r file; do\n check_file "$file" skill\n done\n)\n\nif [ -n "$errors" ]; then\n echo "Frontmatter validation failed:"\n printf '%s\\n' "$errors"\n exit 1\nfi\n\n\n# Secret-like material backstop for hand commits (regex-only defense in depth;\n# the authoritative gates scan with evasion normalisation before this runs).\n# Content is read by blob id from the raw diff (renames shown as an add, so a\n# moved file is scanned too), so no file name (quoted,\n# non-ASCII or carrying shell metacharacters) decides what gets scanned; the\n# name is only ever printed, as data, in git's own quoting.\nsecret_failed=$(\n git diff --cached --no-renames --diff-filter=AMT --raw --no-abbrev |\n while IFS= read -r line; do\n meta=\${line%%"$TAB"*}\n p=\${line#*"$TAB"}\n set -- $meta\n [ "$2" = "160000" ] && continue\n blob=$(git cat-file blob "$4" 2>/dev/null) || {\n printf 'memory pre-commit: %s could not be read for secret screening\\n' "$p"\n continue\n }\n${Xe}\n done\n)\nif [ -n "$secret_failed" ]; then\n printf '%s\\n' "$secret_failed"\n exit 1\nfi\n\nexit 0\n`},{name:"post-commit",script:`#!/bin/sh\n# Push memory commits to the configured memory-repository mirror.\n# Installed by omo memory-core. Do not edit by hand - regenerated on startup.\nurl=$(git config --local --get ${Fe} 2>/dev/null)\n[ -z "$url" ] && exit 0\n\nbranch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || exit 0\n[ -z "$branch" ] && exit 0\n[ "$branch" != "${qe}" ] && exit 0\n\nlog="$(git rev-parse --git-dir)/${Ge}"\n\npush_to_mirror() {\n {\n printf '\\n--- %s %s on %s ---\\n' "$(date '+%Y-%m-%dT%H:%M:%S')" "$(git rev-parse --short HEAD)" "$branch"\n git push --quiet "$url" "$branch:$branch" 2>&1\n echo "exit=$?"\n } >> "$log" 2>&1\n}\n\nif [ "$OMO_MEMORY_PUSH_SYNC" = "1" ]; then\n push_to_mirror\n exit 0\nfi\n\npush_to_mirror &\nexit 0\n`}];function Qe(t){let e=function(t){return He(function(t){let e=He(t,".git");if(!V(e)||q(e).isDirectory())return e;let n=W(e,"utf8").trim(),r=/^gitdir:\s*(.+)$/.exec(n);if(!r?.[1])return e;let i=tn(r[1].trim(),t),a=He(i,"commondir");return V(a)?tn(W(a,"utf8").trim(),i):i}(t),"hooks")}(t);return U(e,{recursive:!0}),Ve.map(({name:t,script:n})=>{let r=He(e,t);return K(r,n,"utf8"),D(r,493),{name:t,path:r}})}function tn(t,e){return ze(t)?t:Ue(e,t)}new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0});import{dirname as en}from"node:path";import{fileURLToPath as nn}from"node:url";en(nn(import.meta.url));import{dirname as rn}from"node:path";import{fileURLToPath as an}from"node:url";rn(an(import.meta.url)),new Date(0).toISOString();var sn="\\p{Script=Hangul}\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\u30fc";new RegExp(`[${sn}]+|(?:(?![${sn}])[\\p{L}\\p{M}\\p{N}])+`,"gu"),new RegExp(`^[${sn}]+$`,"u"),new RegExp(`[${sn}]`,"u"),new RegExp(`[${sn}]`,"gu"),new RegExp(`[\\p{L}${sn}]`,"gu");import{dirname as on}from"node:path";import{fileURLToPath as ln}from"node:url";on(ln(import.meta.url));import{join as cn}from"node:path";var un="memory-backup-";function dn(t){return t.identityPaths.root}async function fn(t,e){let n=function(t){let e=new Date(t).toISOString();return`${e.slice(0,10).replace(/-/g,"")}-${e.slice(11,19).replace(/:/g,"")}`}((t.now??Date.now)()),r=dn(e),i=cn(r,`${un}${n}`),a=2;for(;V(i);)i=cn(r,`${un}${n}-${a}`),a+=1;return await E(e.identityPaths.repo,i,{recursive:!0}),i}import{join as hn}from"node:path";function pn(t,e){return new Le({dir:e.identityPaths.repo,agentId:e.identity,installHooks:t=>{Qe(t)},...void 0===t.exec?{}:{exec:t.exec}})}function mn(t){return t.slice(0,8)}function wn(t){return V(hn(t.identityPaths.repo,".git"))}function yn(t,e){return wn(e)?pn(t,e):function(t){return`no memory repository for ${t.identity} at ${t.identityPaths.repo}; run /memfs init first`}(e)}import{join as gn}from"node:path";async function $n(t,e){let n;try{n=await P(gn(t,e),{withFileTypes:!0})}catch{return[]}let r=[];for(let i of n){let n=""===e?i.name:`${e}/${i.name}`;i.isDirectory()?r.push(...await $n(t,n)):i.isFile()&&i.name.endsWith(".md")&&r.push(n)}return r}async function vn(t){let e=await $n(t,"system"),n=[];for(let r of e){let e=await N(gn(t,r),"utf8"),i=Buffer.byteLength(e,"utf8");n.push({path:r,bytes:i,tokens:Math.ceil(i/4)})}return n.sort((t,e)=>e.tokens-t.tokens||t.path.localeCompare(e.path)),{totalBytes:n.reduce((t,e)=>t+e.bytes,0),totalTokens:n.reduce((t,e)=>t+e.tokens,0),files:n}}function kn(t,e,n="info"){let r=be(e);return t.ui?.notify(r,n),r}function bn(t,e){let n=function(t){return t.sessionManager?.getSessionId()}(e);if(void 0!==n)return t.contextForSession(n)}function xn(t){return!0===t.hasUI&&"function"==typeof t.ui?.confirm}import{basename as Sn,dirname as En,join as In,relative as An}from"node:path";var _n=/^(---\r?\n)([\s\S]*?)(\r?\n---(?:\r?\n|$))/;async function Tn(t){let e=await P(t,{withFileTypes:!0}),n=[];for(let r of e){if(".git"===r.name||"node_modules"===r.name)continue;let e=In(t,r.name);r.isSymbolicLink()||(r.isDirectory()?n.push(...await Tn(e)):r.isFile()&&"SKILL.md"===r.name&&n.push(e))}return n}function Nn(t,e){if(!e.trim())return{content:t,changed:!1,reason:"skill directory name is empty"};let n=t.match(_n);if(!n)return{content:t,changed:!1,reason:"missing YAML frontmatter"};let r=n[1]??"",i=n[2]??"",a=n[3]??"",s=r.includes("\r\n")?"\r\n":"\n",o=i.replace(/\r\n/g,"\n").split("\n"),l=o.findIndex(t=>/^\s*name\s*:/.test(t));if(l>=0&&function(t){let e=t.match(/^\s*name\s*:\s*(.*?)\s*$/);return Boolean(e?.[1]?.trim())}(o[l]??""))return{content:t,changed:!1};let c=`name: ${u=e.trim(),/^[A-Za-z0-9_-]+$/.test(u)?u:JSON.stringify(u)}`;var u;return l>=0?o[l]=c:o.unshift(c),{content:`${r}${o.join(s)}${a}${t.slice(n[0].length)}`,changed:!0}}async function Pn(t){let e={scanned:0,repaired:[],skipped:[]};if(!t)return e;let n,r=In(t,"skills");if(!await async function(t){try{return await R(t),!0}catch{return!1}}(r))return e;try{n=await Tn(r)}catch(t){return e.skipped.push({path:"skills/",reason:`failed to scan skills directory: ${t instanceof Error?t.message:String(t)}`}),e}for(let r of n.sort()){let n=An(t,r).replace(/\\/g,"/");e.scanned+=1;try{let t=Nn(await N(r,"utf8"),Sn(En(r)));if(void 0!==t.reason){e.skipped.push({path:n,reason:t.reason});continue}if(!t.changed)continue;await X(r,t.content,"utf8"),e.repaired.push(n)}catch(t){e.skipped.push({path:n,reason:t instanceof Error?t.message:String(t)})}}return e}var Ln=["status","init","sync","repair","reset","backup","restore","diff","tokens"],Mn="skills-usage.json";var On={status:async({deps:t,ctx:e,identity:n})=>{let r=yn(t,n);if("string"==typeof r)return kn(e,r,"error");let i=await r.head(),a=(await r.status()).split(/\r?\n/).filter(t=>t.trim().length>0),s=await new Ke({repo:r,...void 0===t.exec?{}:{exec:t.exec}}).status(),o=a.length>0,l=[`# Memfs status: ${n.identity}`,`Repository: ${n.identityPaths.repo}`,`HEAD: ${null===i?"(no commits)":mn(i)}`,"Working tree: "+(o?`dirty — ${a.length} entr${1===a.length?"y":"ies"}`:"clean"),`Mirror: ${s.redactedUrl??"not configured"}${void 0===s.url?"":` (${s.aheadCount} ahead)`}`];o&&l.push("",...a,"","uncommitted changes present; inspect with /memfs diff or commit through the memory tools");let c=await async function(t){let e,n;try{e=await N(Q(t,Mn),"utf8")}catch{return}try{n=JSON.parse(e)}catch{return}if(null===n||"object"!=typeof n||Array.isArray(n))return;let r=Object.entries(n);if(0===r.length)return;let i=["","## Skills usage"];for(let[t,e]of r){if(null===e||"object"!=typeof e||Array.isArray(e))continue;let n=e,r="number"==typeof n.count?n.count:0,a="string"==typeof n.lastUsedAt?n.lastUsedAt:"unknown";i.push(` ${t}: ${r} read${1===r?"":"s"}, last ${a}`)}return i.length>2?i.join("\n"):void 0}(n.identityPaths.runtime);return void 0!==c&&l.push(c),kn(e,l.join("\n"),o?"warning":"info")},init:async({deps:t,ctx:e,identity:n})=>{if(wn(n)){let r=await pn(t,n).head();return kn(e,`memory repository already initialized at ${n.identityPaths.repo}${null===r?"":` (HEAD ${mn(r)})`}`)}let r=await pn(t,n).init();return kn(e,`initialized memory repository at ${n.identityPaths.repo} (HEAD ${mn(r)})`)},sync:async({deps:t,ctx:e,identity:n})=>{let r=yn(t,n);if("string"==typeof r)return kn(e,r,"error");let i=new Ke({repo:r,...void 0===t.exec?{}:{exec:t.exec}}),a=await i.status();if(void 0===a.url)return kn(e,"no memory repository mirror configured; set one with /memory-repository set <url>","error");let s=await i.pushNow();return s.pushed?kn(e,`pushed main to ${a.redactedUrl}`):kn(e,`push to ${a.redactedUrl} failed: ${s.detail}`,"error")},repair:async({deps:t,ctx:e,identity:n})=>{let r=yn(t,n);if("string"==typeof r)return kn(e,r,"error");let i=Qe(r.dir),a=await Pn(r.dir),s=function(t){let e=[];return t.repaired.length>0&&e.push(`added missing \`name:\` frontmatter to ${t.repaired.length} skill${1===t.repaired.length?"":"s"}: ${t.repaired.map(t=>`\`${t}\``).join(", ")}`),t.skipped.length>0&&e.push(`could not repair ${t.skipped.length} skill${1===t.skipped.length?"":"s"}: ${t.skipped.map(t=>`\`${t.path}\` (${t.reason})`).join(", ")}`),e.join("\n")}(a),o=[`# Memfs repair: ${n.identity}`,`- reinstalled ${i.length} git hook${1===i.length?"":"s"}`,`- scanned ${a.scanned} skill file${1===a.scanned?"":"s"}`];return s.length>0&&o.push(...s.split("\n").map(t=>`- ${t}`)),kn(e,o.join("\n"))},reset:async({deps:t,ctx:e,parsed:n,identity:r})=>{let i=yn(t,r);if("string"==typeof i)return kn(e,i,"error");if(xn(e)){if(!0!==await(e.ui?.confirm?.("Reset memory repository",`This deletes ${r.identityPaths.repo} and starts an empty history. A backup is written first.`)))return kn(e,"reset aborted; nothing changed")}else if(!0!==n.flags.get("force"))return kn(e,"reset requires --force in a noninteractive session (no confirmation UI available): /memfs reset --force","error");let a=await fn(t,r);return await M(r.identityPaths.repo,{recursive:!0,force:!0}),kn(e,`reset complete; backup at ${a}; new HEAD ${mn(await pn(t,r).init())}`)},backup:async({deps:t,ctx:e,identity:n})=>{let r=yn(t,n);return"string"==typeof r?kn(e,r,"error"):kn(e,`backup written to ${await fn(t,n)}`)},restore:async({deps:t,ctx:e,parsed:n,identity:r})=>{let i=await async function(t){let e;try{e=await P(dn(t))}catch{return[]}return e.filter(t=>t.startsWith(un)).sort()}(r);if(0===i.length)return kn(e,`no backups found for ${r.identity} in ${r.identityPaths.root}`,"error");let a,s=n.positionals[1];if(void 0===s){if(!xn(e))return kn(e,`specify a backup name: /memfs restore <name>; available: ${i.join(", ")}`,"error");let t=await(e.ui?.select?.("Restore memory backup",[...i]));if(void 0===t)return kn(e,"restore cancelled; nothing changed");a=t}else a=s;if(!i.includes(a))return kn(e,`unknown backup: ${a}; available: ${i.join(", ")}`,"error");let o=await async function(t,e,n){let r=cn(dn(e),n),i=e.identityPaths.repo,a=V(i)?await fn(t,e):void 0;return await M(i,{recursive:!0,force:!0}),await E(r,i,{recursive:!0}),{restored:n,safetyBackup:a}}(t,r,a),l=void 0===o.safetyBackup?"":`; safety backup at ${o.safetyBackup}`;return kn(e,`restored ${o.restored} into ${r.identityPaths.repo}${l}`)},diff:async({deps:t,ctx:e,identity:n})=>{let r=yn(t,n);if("string"==typeof r)return kn(e,r,"error");let i=await function(t,e,n){return(t.exec??St()).run(n,{cwd:e,timeoutMs:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}})}(t,r.dir,["diff"]);if(0!==i.code)return kn(e,`git diff failed: ${i.stderr.trim()||`exit ${i.code}`}`,"error");let a=i.stdout.trim();return 0===a.length?kn(e,"No changes."):kn(e,`# Memfs diff: ${n.identity}\n\n${a}`,"warning")},tokens:async({deps:t,ctx:e,identity:n})=>{let r=yn(t,n);if("string"==typeof r)return kn(e,r,"error");let i=await vn(r.dir),a=[`# System prompt token estimate (bytes/4): ${n.identity}`,`Total: ~${i.totalTokens} tokens (${i.totalBytes} bytes)`];if(i.files.length>0){a.push(""," tokens path");for(let t of i.files)a.push(` ${String(t.tokens).padStart(6)} ${t.path}`)}return kn(e,a.join("\n"))}};async function Rn(t,e,n){let r=function(t,e={}){let n=new Set(e.booleans??[]),r=[],i=new Map,a=t.trim().split(/\s+/).filter(Boolean);for(let t=0;t<a.length;t+=1){let e=a[t]??"";if(!e.startsWith("--")){r.push(e);continue}let s=e.slice(2),o=s.indexOf("=");if(o>=0){i.set(s.slice(0,o),s.slice(o+1));continue}let l=a[t+1];n.has(s)||void 0===l||l.startsWith("--")?i.set(s,!0):(i.set(s,l),t+=1)}return{positionals:r,flags:i}}(e,{booleans:["force"]}),[i]=r.positionals;if(void 0===i)return kn(n,`usage: /memfs <${Ln.join("|")}>`,"error");let a=On[i];if(void 0===a)return kn(n,`unknown /memfs subcommand: ${i}; expected one of ${Ln.join(", ")}`,"error");let s="init"===i?function(t,e){return bn(t,e)??t.resolveIdentity?.()}(t,n):function(t,e){let n=bn(t,e);return void 0!==n?n:"memory is not bound to this session; start a session with memory enabled and retry"}(t,n);return void 0===s?kn(n,"no memory identity resolved; check the memory config for this project","error"):"string"==typeof s?kn(n,s,"error"):a({deps:t,ctx:n,parsed:r,identity:s})}export{Rn as runMemfs};