oh-my-agent 7.7.0 → 7.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +2 -3
  2. package/bin/cli.js +1 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -67,10 +67,9 @@ Pick a preset and you're ready:
67
67
  | **oma-architecture** | Architectural tradeoffs, boundaries, ADR/ATAM/CBAM-aware analysis |
68
68
  | **oma-backend** | APIs in Python, Node.js, or Rust |
69
69
  | **oma-brainstorm** | Explores ideas before you commit to building |
70
- | **oma-coordination** | Manual step-by-step multi-agent coordination guide |
71
70
  | **oma-db** | Schema design, migrations, indexing, vector DB |
72
71
  | **oma-debug** | Root cause analysis, fixes, regression tests |
73
- | **oma-deepsec** | Agent-powered vulnerability scanner (Vercel deepsec) with PR gates and custom matchers |
72
+ | **oma-deepsec** | Agent-powered vulnerability scanner with PR gates and custom matchers |
74
73
  | **oma-design** | Design systems, tokens, accessibility, responsive |
75
74
  | **oma-dev-workflow** | CI/CD, releases, monorepo automation |
76
75
  | **oma-docs** | Reference integrity checks, diff-affected doc detection |
@@ -119,7 +118,7 @@ Or use slash commands for structured workflows:
119
118
  | 3 | `/ultrawork` | 5-phase quality workflow with 11 review gates |
120
119
  | 3 | `/ralph` | Wraps `/ultrawork` in an independent verifier loop until criteria pass |
121
120
  | 4 | `/review` | Security + performance + accessibility audit |
122
- | 4 | `/deepsec` | Deep agent-powered security scan (Vercel deepsec) |
121
+ | 4 | `/deepsec` | Deep agent-powered security scan |
123
122
  | 5 | `/debug` | Structured root-cause debugging |
124
123
  | 5 | `/docs` | Documentation drift verify + sync via `oma-docs` |
125
124
  | 6 | `/scm` | SCM + Git workflow and Conventional Commit support |
package/bin/cli.js CHANGED
@@ -1463,7 +1463,7 @@ print(json.dumps({
1463
1463
  }))
1464
1464
  `;function SN5(){return process.env.OMA_PYTHON??"python3"}function _N5($){if(PN5.some((z)=>$===z||$.endsWith(`.${z}`)))return["safari","chrome","firefox"];return["chrome","safari","firefox"]}async function yN5($,z,G){return new Promise((J)=>{let U=bN5(SN5(),["-c",CN5],{env:{...process.env,OMA_IMPERSONATE_URL:$.toString(),OMA_IMPERSONATE_TARGET:z,OMA_IMPERSONATE_LOCALE:G.locale,OMA_IMPERSONATE_TIMEOUT:String(G.timeoutMs)},stdio:["ignore","pipe","pipe"]}),K="",k="";U.stdout.on("data",(Q)=>{K+=Q.toString()}),U.stderr.on("data",(Q)=>{k+=Q.toString()});let X=()=>{U.kill("SIGTERM")};G.signal?.addEventListener("abort",X),U.on("close",(Q)=>{if(G.signal?.removeEventListener("abort",X),Q!==0&&!K){J({error:`python_exit:${Q}:${k.trim().slice(0,200)}`});return}let Z=K.trim();if(!Z){J({error:"empty_stdout"});return}try{J(JSON.parse(Z))}catch(L){J({error:`parse_error:${L.message}:${Z.slice(0,200)}`})}}),U.on("error",(Q)=>{G.signal?.removeEventListener("abort",X),J({error:`spawn_error:${Q.message}`})})})}function hN5($,z,G){let J=new Headers;if($.headers)for(let[U,K]of Object.entries($.headers))try{J.set(U,K)}catch{}return{ok:($.status??0)>=200&&($.status??0)<400,status:$.status??0,headers:J,url:$.url??z,text:$.body??"",elapsedMs:G,redirected:($.url??z)!==z}}async function aN2($,z){let G=_N5($.hostname),J=[],U=performance.now();for(let X of G){if(z.signal?.aborted)break;let Q=performance.now(),Z=await yN5($,X,z),L=Math.round(performance.now()-Q);if(Z.error==="curl_cffi_not_installed")return C1({url:$.toString(),strategy:"impersonate",error:Error("curl_cffi is not installed. Run: pip install curl_cffi")});if(Z.error){J.push({target:X,detail:Z.error});continue}let j=hN5(Z,$.toString(),L),u=$7(j);if(i02(u))return{url:$.toString(),status:"blocked",strategy:"impersonate",platform:X,httpStatus:j.status,content:j.text,contentType:j.headers.get("content-type")??void 0,elapsedMs:Math.round(performance.now()-U),signals:u,error:"js-essential-markers-detected"};if(j.ok&&j.text.length>=200)return{url:$.toString(),status:I6(j,u),strategy:"impersonate",platform:X,httpStatus:j.status,content:j.text,contentType:j.headers.get("content-type")??void 0,elapsedMs:Math.round(performance.now()-U),signals:u};J.push({target:X,detail:`status=${j.status} size=${j.text.length}`})}let K=Math.round(performance.now()-U),k=J.map((X)=>`${X.target}(${X.detail})`).join(" | ");return{...C1({url:$.toString(),strategy:"impersonate",error:Error(k?`impersonate_failed: ${k}`:"impersonate_failed")}),elapsedMs:K,signals:[]}}var oN2="https://r.jina.ai/";function iN5($){let z=`${$.protocol}//${$.hostname}`,G=$.hostname.startsWith("m.")?$.hostname:`m.${$.hostname.replace(/^www\./,"")}`,J=new URL($.toString());return J.hostname=G,[{label:"jina",url:`${oN2}${$.toString()}`,headers:SG({accept:"text/plain"})},{label:"jina-json",url:`${oN2}${$.toString()}`,headers:SG({accept:"application/json"})},{label:"curl-desktop",url:$.toString(),headers:SG({userAgent:G8.desktopFirefox,referer:z})},{label:"curl-mobile",url:J.toString(),headers:SG({userAgent:G8.mobileSafari,referer:z})},{label:"curl-googlebot",url:$.toString(),headers:SG({userAgent:G8.googlebot})}]}function xN5($,z){if(!$.startsWith("jina"))return z;return z}async function rN2($,z){let G=iN5($),J=new AbortController;if(z.signal)if(z.signal.aborted)J.abort(z.signal.reason);else z.signal.addEventListener("abort",()=>J.abort(z.signal?.reason));let U=performance.now(),K={},k=null,X=G.map(async(Q)=>{let Z=await g1(Q.url,{headers:Q.headers,timeoutMs:z.timeoutMs,signal:J.signal,locale:z.locale}),L=$7(Z);if(Q.label.startsWith("jina")){let j=y02(Z);if(j)throw k=j,Error(`jina-quota:${j.detail}`)}if(!mN5(Z,L))throw K[Q.label]=`status=${Z.status} size=${Z.text.length}`,Error(`weak-response:${Q.label}`);return{label:Q.label,resp:Z,signals:L}});try{let Q=await Promise.any(X);J.abort();let Z=Math.round(performance.now()-U);return{url:$.toString(),status:I6(Q.resp,Q.signals),strategy:"probe",platform:Q.label,httpStatus:Q.resp.status,content:xN5(Q.label,Q.resp.text),contentType:Q.resp.headers.get("content-type")??void 0,elapsedMs:Z,signals:k?[...Q.signals,k]:Q.signals}}catch(Q){let Z=Math.round(performance.now()-U),L=Object.entries(K).map(([j,u])=>`${j}:${u}`).join(" ");if(k)return{...C1({url:$.toString(),error:Error(`probe failed — ${L}`),strategy:"probe"}),elapsedMs:Z,signals:[k]};return{...C1({url:$.toString(),error:Q instanceof AggregateError?Error(L):Q,strategy:"probe"}),elapsedMs:Z}}}function mN5($,z){if(!$.ok)return!1;if($.text.length<200)return!1;if(z.some((G)=>G.kind==="waf-body"||G.kind==="challenge-body"||G.kind==="js-essential"||G.kind==="http-status"))return!1;return!0}var gN5=["api","probe","impersonate","browser","archive"];function fN5($){if($.only?.length)return $.only;let z=gN5.slice();if(!$.includeArchive)z=z.filter((G)=>G!=="archive");if($.skip?.length)z=z.filter((G)=>!$.skip?.includes(G));return z}async function sN2($,z,G){switch($){case"api":return await eV(z,G)??null;case"probe":return rN2(z,G);case"impersonate":return aN2(z,G);case"browser":return pN2(z,G);case"archive":return gL(z,G)}}function dl($){if($.status==="ok")return!0;if($.status==="auth-required"&&x02($.signals))return!0;return!1}function lN5($){return $.status==="auth-required"||$.status==="invalid-input"||$.status==="not-found"}async function nN5($){let z=Math.floor(Math.random()*500);await new Promise((G)=>setTimeout(G,$+z))}function cN5($){let z=$.find((U)=>U.kind==="rate-limit");if(!z)return 1500;let G=z.detail.match(/retry-after=(\d+)/);if(!G?.[1])return 1500;let J=Number.parseInt(G[1],10);if(Number.isNaN(J)||J>10)return 1500;return J*1000}async function tN2($,z,G={}){let J=fN5(G),U=[],K=new Set,k=null,X=!1;for(let Q of J){if(z.signal?.aborted)break;if(X&&Q==="impersonate")continue;let Z=await sN2(Q,$,z);if(!Z)continue;if(U.push({strategy:Q,platform:Z.platform,status:Z.status,httpStatus:Z.httpStatus,elapsedMs:Z.elapsedMs,signals:Z.signals,error:Z.error}),Z.signals.some((L)=>L.kind==="js-essential"))X=!0;if(dl(Z))return Z.attempts=U,Z;if(lN5(Z))return Z.attempts=U,Z;if(G.retryOnRateLimit!==!1&&m02(Z.signals)&&!K.has(Q)){K.add(Q),await nN5(cN5(Z.signals));let L=await sN2(Q,$,z);if(L){if(U.push({strategy:Q,platform:L.platform,status:L.status,httpStatus:L.httpStatus,elapsedMs:L.elapsedMs,signals:L.signals,error:L.error}),dl(L))return L.attempts=U,L;k=L;continue}}k=Z}if(!J.includes("archive")&&G.includeArchive!==!1){let Q=await gL($,z);if(U.push({strategy:"archive",platform:Q.platform,status:Q.status,httpStatus:Q.httpStatus,elapsedMs:Q.elapsedMs,signals:Q.signals,error:Q.error}),dl(Q))return Q.attempts=U,Q;k=Q}if(k)return k.attempts=U,k;return{url:$.toString(),status:"error",strategy:J[0]??"probe",content:"",elapsedMs:0,signals:[],attempts:U,error:"all strategies failed"}}var iO2=d2(yO2(),1);var Wq5=["/rss","/feed","/atom.xml","/rss.xml","/index.xml"],Hq5=new iO2.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text"});function el($){if($===void 0||$===null)return[];return Array.isArray($)?$:[$]}function O3($){if($==null)return;if(typeof $==="string")return $;if(typeof $==="object"){let z=$;if(typeof z["#text"]==="string")return z["#text"];if(typeof z["#cdata"]==="string")return z["#cdata"]}return}function hO2($){for(let z of el($)){let G=z?.["@_href"],J=z?.["@_rel"];if(typeof G==="string"&&(J===void 0||J==="alternate"))return G}return}function xO2($){let z;try{z=Hq5.parse($)}catch{return null}let G=z.rss;if(G){let U=G.channel;if(!U)return null;let K=el(U.item);return{kind:"rss",title:O3(U.title),description:O3(U.description),link:O3(U.link),entries:K.map((k)=>({title:O3(k.title),link:O3(k.link),pubDate:O3(k.pubDate),description:O3(k.description),content:O3(k["content:encoded"])??O3(k.content)}))}}let J=z.feed;if(J){let U=el(J.entry);return{kind:"atom",title:O3(J.title),description:O3(J.subtitle),link:hO2(J.link),entries:U.map((K)=>({title:O3(K.title),link:hO2(K.link),pubDate:O3(K.published)??O3(K.updated),description:O3(K.summary),content:O3(K.content)??O3(K.summary)}))}}return null}async function mO2($,z){let G=performance.now(),J;try{let K=await g1($.toString(),{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(K.ok)J=tV(K.text).alternate?.[0]?.href}catch{}let U=new Set;if(J)try{U.add(new URL(J,$).toString())}catch{}for(let K of Wq5)U.add(new URL(K,`${$.protocol}//${$.host}`).toString());for(let K of U){if(z.signal?.aborted)break;try{let k=await g1(K,{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(!k.ok||k.text.length<50)continue;let X=xO2(k.text);if(!X||X.entries.length===0)continue;return{url:$.toString(),status:"ok",strategy:"probe",platform:"rss",httpStatus:k.status,content:k.text,contentType:k.headers.get("content-type")??void 0,elapsedMs:Math.round(performance.now()-G),signals:[],feedUrl:K,feed:X}}catch{}}return{url:$.toString(),status:"not-found",strategy:"probe",platform:"rss",content:"",elapsedMs:Math.round(performance.now()-G),signals:[],error:"no RSS/Atom feed discovered"}}function gO2($,z="en-US"){let[G,J]=z.split("-"),U=new URL("https://news.google.com/rss/search");return U.searchParams.set("q",$),U.searchParams.set("hl",G??"en"),U.searchParams.set("gl",J??"US"),U.searchParams.set("ceid",`${J??"US"}:${G??"en"}`),U.toString()}var ID={"github.com":{domain:"github.com",level:"verified",score:0.95,tags:["code-host"],source:"registry"},"docs.github.com":{domain:"docs.github.com",level:"verified",score:0.95,tags:["lang-docs"],source:"registry"},"developer.mozilla.org":{domain:"developer.mozilla.org",level:"verified",score:0.95,tags:["lang-docs"],source:"registry"},"nextjs.org":{domain:"nextjs.org",level:"verified",score:0.9,tags:["vendor","lang-docs"],source:"registry"},"vercel.com":{domain:"vercel.com",level:"verified",score:0.9,tags:["vendor"],source:"registry"},"typescriptlang.org":{domain:"typescriptlang.org",level:"verified",score:0.95,tags:["lang-docs"],source:"registry"},"stackoverflow.com":{domain:"stackoverflow.com",level:"community",score:0.7,tags:["qna"],source:"registry"},"dev.to":{domain:"dev.to",level:"external",score:0.4,tags:["blog"],source:"registry"},"medium.com":{domain:"medium.com",level:"external",score:0.35,tags:["blog"],source:"registry"},"npmjs.com":{domain:"npmjs.com",level:"verified",score:0.9,tags:["registry"],source:"registry"},"pypi.org":{domain:"pypi.org",level:"verified",score:0.9,tags:["registry"],source:"registry"},"news.ycombinator.com":{domain:"news.ycombinator.com",level:"community",score:0.65,tags:["news"],source:"registry"},"reddit.com":{domain:"reddit.com",level:"community",score:0.55,tags:["forum"],source:"registry"},"wikipedia.org":{domain:"wikipedia.org",level:"community",score:0.75,tags:["encyclopedia"],source:"registry"},"arxiv.org":{domain:"arxiv.org",level:"verified",score:0.9,tags:["academic"],source:"registry"},"doi.org":{domain:"doi.org",level:"verified",score:0.95,tags:["academic"],source:"registry"}};function Bq5($){return $.replace(/^www\./,"")}function Vq5($){if($ in ID){let G=ID[$];return G?{...G}:null}let z=Bq5($);if(z in ID){let G=ID[z];return G?{...G}:null}return null}function Fq5($){let z=$.split(".").pop();if(z==="gov"||z==="edu"||z==="mil")return{domain:$,level:"verified",score:0.9,tags:["institution"],source:"heuristic"};if(/\.gov\.[a-z]{2}$/.test($)||/\.ac\.[a-z]{2}$/.test($))return{domain:$,level:"verified",score:0.85,tags:["institution"],source:"heuristic"};return null}async function Nq5($){try{let z=await g1(`https://tranco-list.eu/api/ranks/domain/${$}`,{timeoutMs:5000});if(!z.ok)return null;let J=JSON.parse(z.text).ranks?.[0]?.rank;if(!J)return null;let U=J<1e4?0.6:J<1e5?0.4:0.2;return{domain:$,level:J<1e4?"community":"external",score:U,tags:["tranco"],source:"tranco",rank:J}}catch{return null}}async function fO2($){let z=Vq5($);if(z)return z;let G=Fq5($);if(G)return G;let J=await Nq5($);if(J)return J;return{domain:$,level:"unknown",score:null,tags:[],source:"heuristic"}}var lO2=["api","probe","impersonate","browser","archive"];function nO2($){if(!$)return;let z=$.split(",").map((J)=>J.trim()).filter(Boolean),G=z.filter((J)=>!lO2.includes(J));if(G.length>0)throw Error(`Unknown strategy: ${G.join(", ")}. Valid: ${lO2.join(", ")}`);return z}function XQ($){try{return new URL($)}catch{throw Error(`Invalid URL: ${$}`)}}function Mz($){return{timeoutMs:$.timeout?Math.max(1000,Math.floor(Number($.timeout)*1000)):15000,locale:$.locale??"en-US,en;q=0.9"}}function T0($,z){if(z)console.log(JSON.stringify($,null,2));else console.log(JSON.stringify($))}function iJ($){if(!$){process.exitCode=1;return}if($.status==="ok")process.exitCode=0;else if($.status==="blocked")process.exitCode=2;else if($.status==="not-found")process.exitCode=3;else if($.status==="invalid-input")process.exitCode=4;else if($.status==="auth-required")process.exitCode=5;else if($.status==="timeout")process.exitCode=6;else process.exitCode=1}function cO2($){let z=$.command("search").description("Mechanical search primitives — fetch, meta, rss, media, trust, code").alias("s");z.command("fetch <url>").description("Fetch URL via auto-escalating strategy pipeline").option("--only <strategies>","Comma-separated strategies to run").option("--skip <strategies>","Comma-separated strategies to skip").option("--include-archive","Include archive strategy as last fallback").option("--timeout <seconds>","Per-strategy timeout","15").option("--locale <value>","Accept-Language header","en-US,en;q=0.9").option("--pretty","Pretty-print JSON output").action(async(G,J)=>{try{let U=XQ(G),K=Mz(J),k=await tN2(U,K,{only:nO2(J.only),skip:nO2(J.skip),includeArchive:J.includeArchive});T0(k,Boolean(J.pretty)),iJ(k)}catch(U){console.error(O8.default.red(U.message)),process.exitCode=1}}),z.command("api <url>").description("Fetch via matched platform API (Phase 0)").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=XQ(G);if(!ny(U)){console.error(O8.default.yellow(`No API handler matches host ${U.hostname}`)),process.exitCode=3;return}let k=Mz(J),X=await eV(U,k);if(!X){process.exitCode=3;return}T0(X,Boolean(J.pretty)),iJ(X)}catch(U){console.error(O8.default.red(U.message)),process.exitCode=1}}),z.command("api:search <query>").description("Fan-out keyword search across platforms that support it").option("--platforms <list>","Comma-separated platform ids").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{let U=Mz(J),K=J.platforms?J.platforms.split(",").map((X)=>X.trim()).filter(Boolean):void 0,k=await k$2(G,U,K);T0(k,Boolean(J.pretty))}),z.command("meta <url>").description("Extract OGP / JSON-LD / Schema.org from URL").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=XQ(G),K=Mz(J),k=await _02(U,K),{content:X,...Q}=k;T0(Q,Boolean(J.pretty)),iJ(k)}catch(U){console.error(O8.default.red(U.message)),process.exitCode=1}}),z.command("rss <url>").description("Discover and parse RSS/Atom feed for a URL").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=XQ(G),K=Mz(J),k=await mO2(U,K),{content:X,...Q}=k;T0(Q,Boolean(J.pretty)),iJ(k)}catch(U){console.error(O8.default.red(U.message)),process.exitCode=1}}),z.command("rss:google <query>").description("Build Google News RSS URL for a query").option("--locale <value>","Locale (e.g., ko-KR)","en-US").action((G,J)=>{let U=gO2(G,J.locale??"en-US");console.log(U)}),z.command("media <url>").description("Extract media metadata via yt-dlp (1858 sites)").option("--subs","Write subtitles").option("--sub-lang <list>","Subtitle languages (comma-separated)","en").option("--format <spec>","yt-dlp format spec").option("--timeout <seconds>","Timeout","30").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=XQ(G),K=Mz(J),k=J.subLang?J.subLang.split(",").map((Q)=>Q.trim()).filter(Boolean):void 0,X=await C02(U,K,{subtitles:J.subs,...k?{subLangs:k}:{},...J.format?{format:J.format}:{}});T0(X,Boolean(J.pretty)),iJ(X)}catch(U){console.error(O8.default.red(U.message)),process.exitCode=1}}),z.command("archive <url>").description("Fetch via AMP / archive.today / Wayback").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=XQ(G),K=Mz(J),k=await gL(U,K);T0(k,Boolean(J.pretty)),iJ(k)}catch(U){console.error(O8.default.red(U.message)),process.exitCode=1}}),z.command("trust <domain>").description("Resolve trust level / score for a domain").option("--pretty","Pretty-print JSON").action(async(G,J)=>{let U=await fO2(G.toLowerCase());T0(U,Boolean(J.pretty))}),z.command("code <query>").description("Search code via gh / glab").option("--host <github|gitlab>","Host","github").option("--language <lang>","Language filter").option("--repo <owner/repo>","Scope to a repo").option("--limit <n>","Max results","20").option("--pretty","Pretty-print JSON").action(async(G,J)=>{let U=J.host==="gitlab"||J.host==="github"?J.host:"github",K=Mz({}),k=await P02(G,K,{host:U,...J.language?{language:J.language}:{},...J.repo?{repo:J.repo}:{},...J.limit?{limit:Number.parseInt(J.limit,10)}:{}});T0(k,Boolean(J.pretty)),iJ(k)}),z.command("doctor").description("Check dependencies (Chrome, python3 curl_cffi, yt-dlp, gh)").action(async()=>{let G=[],J=cl();G.push({name:"chrome",ok:Boolean(J),detail:J??"Install Chrome or set OMA_CHROME_PATH"}),G.push(await $n("python3",["--version"])),G.push(await Oq5()),G.push(await $n("yt-dlp",["--version"])),G.push(await $n("gh",["--version"]));for(let U of G){let K=U.ok?O8.default.green("✓"):O8.default.yellow("!");console.log(`${K} ${U.name}: ${U.detail}`)}if(G.some((U)=>!U.ok))process.exitCode=1})}async function $n($,z){return new Promise((G)=>{let{spawn:J}=K2("node:child_process"),U=J($,z,{stdio:["ignore","pipe","pipe"]}),K="";U.stdout?.on("data",(k)=>{K+=k.toString()}),U.on("error",()=>G({name:$,ok:!1,detail:"not found"})),U.on("close",(k)=>{if(k===0)G({name:$,ok:!0,detail:K.trim()});else G({name:$,ok:!1,detail:`exit code ${k}`})})})}async function Oq5(){return new Promise(($)=>{let{spawn:z}=K2("node:child_process"),G=z("python3",["-c","import curl_cffi; print(curl_cffi.__version__)"],{stdio:["ignore","pipe","pipe"]}),J="";G.stdout?.on("data",(U)=>{J+=U.toString()}),G.on("error",()=>$({name:"curl_cffi",ok:!1,detail:"python3 not found"})),G.on("close",(U)=>{if(U===0)$({name:"curl_cffi",ok:!0,detail:`v${J.trim()}`});else $({name:"curl_cffi",ok:!1,detail:"not installed (pip install curl_cffi)"})})})}F7();var Iz=d2(N4(),1);import{execSync as qq5,spawnSync as dO2}from"node:child_process";import{platform as Dq5}from"node:os";function Mq5(){let $=Dq5();if($==="darwin")return"brew install gh";if($==="win32")return"winget install GitHub.cli";return"sudo apt install gh"}async function pO2(){if(console.clear(),x4(Iz.default.bgMagenta(Iz.default.white(" ⭐ oh-my-agent star "))),!tz()){let z=Mq5(),G=await j3({message:`GitHub CLI (gh) is not installed. Install with ${Iz.default.cyan(z)}?`});if(j4(G)||!G){R5("Install gh manually and try again.");return}let J=A6();J.start("Installing GitHub CLI...");let U=dO2(z,{shell:!0,stdio:"pipe"});if(U.status!==0){J.stop("Installation failed"),s5.error(U.stderr?.toString()||"Unknown error"),R5("Please install gh manually.");return}J.stop("GitHub CLI installed!")}if(!p9()){s5.warn("GitHub CLI is not authenticated.");let z=await j3({message:`Run ${Iz.default.cyan("gh auth login")} now?`});if(j4(z)||!z){R5("Authenticate and try again.");return}if(dO2("gh",["auth","login"],{stdio:"inherit"}),!p9()){R5("Authentication was not completed. Try again.");return}s5.success("Authenticated!")}if(ez()){R5(`Already starred ${Iz.default.cyan(t4)}! Thank you! \uD83D\uDE4F`);return}let $=await j3({message:`Star ${Iz.default.cyan(t4)} on GitHub?`});if(j4($)||!$){R5("Maybe next time!");return}try{qq5(`gh api -X PUT /user/starred/${t4}`,{stdio:"ignore"}),R5(`Starred ${Iz.default.cyan(t4)}! Thank you! \uD83C\uDF1F`)}catch{s5.error("Failed to star the repository."),R5("Please try again later.")}}function aO2($){$.command("star").description("Star oh-my-agent on GitHub").action(j5(async()=>{await pO2()}))}F7();_y();OZ();var T9=d2(N4(),1);import{existsSync as ED,mkdirSync as Iq5,readdirSync as Eq5,readFileSync as Tq5,writeFileSync as oO2}from"node:fs";import{dirname as Rq5,join as rO2}from"node:path";function Gn($){return rO2($,".serena","metrics.json")}function zn(){return{sessions:0,skillsUsed:{},tasksCompleted:0,totalSessionTime:0,filesChanged:0,linesAdded:0,linesRemoved:0,lastUpdated:new Date().toISOString(),startDate:new Date().toISOString()}}function vq5($){let z=Gn($);if(ED(z))try{return JSON.parse(Tq5(z,"utf-8"))}catch{return zn()}return zn()}function wq5($,z){let G=Gn($),J=Rq5(G);if(!ED(J))Iq5(J,{recursive:!0});z.lastUpdated=new Date().toISOString(),oO2(G,JSON.stringify(z,null,2),"utf-8")}function bq5($){let z=rO2($,".serena","memories"),G={};if(!ED(z))return G;try{let J=Eq5(z);for(let U of J){let K=U.match(/(?:progress|result)-(\w+)/);if(K?.[1]){let k=K[1];G[k]=(G[k]||0)+1}}}catch{}return G}async function sO2($=!1,z=!1){let G=process.cwd(),J=Gn(G);if(z){if(ED(J))oO2(J,JSON.stringify(zn(),null,2),"utf-8");if($)console.log(JSON.stringify({reset:!0}));else console.log(T9.default.green("✅ Metrics reset successfully."));return}let U=vq5(G),K=nV(G),k=bq5(G),X=xo(G),Q=oW(G),Z=Q.startedAt?new Date(Q.startedAt):null,L=Z&&!Number.isNaN(Z.getTime())?Math.max(0,Math.floor((Date.now()-Z.getTime())/1000)):0;for(let[W,H]of Object.entries(k))U.skillsUsed[W]=(U.skillsUsed[W]||0)+H;if(X>U.tasksCompleted)U.tasksCompleted=X;if(Q.id){if(["completed","failed","aborted"].includes(Q.status||"")&&(U.lastSessionId!==Q.id||U.lastSessionStatus!==Q.status)&&L>0)U.totalSessionTime+=L;U.lastSessionId=Q.id,U.lastSessionStatus=Q.status,U.lastSessionStarted=Q.startedAt,U.lastSessionDuration=L}U.filesChanged+=K.filesChanged,U.linesAdded+=K.linesAdded,U.linesRemoved+=K.linesRemoved,U.sessions+=1,wq5(G,U);let j=Math.max(1,Math.ceil((Date.now()-new Date(U.startDate).getTime())/86400000)),u=U.sessions>0?Math.round(U.totalSessionTime/U.sessions):0;if($){console.log(JSON.stringify({...U,gitStats:K,daysSinceStart:j,avgSessionTime:u},null,2));return}console.clear(),x4(T9.default.bgMagenta(T9.default.white(" \uD83D\uDCCA oh-my-agent stats ")));let Y=[T9.default.bold(`\uD83D\uDCC8 Productivity Metrics (${j} days)`),"┌─────────────────────┬──────────────┐",`│ ${T9.default.bold("Metric")} │ ${T9.default.bold("Value")} │`,"├─────────────────────┼──────────────┤",`│ Sessions │ ${String(U.sessions).padEnd(12)} │`,`│ Tasks Completed │ ${String(U.tasksCompleted).padEnd(12)} │`,`│ Files Changed │ ${String(U.filesChanged).padEnd(12)} │`,`│ Lines Added │ ${T9.default.green(`+${U.linesAdded}`).padEnd(12)} │`,`│ Lines Removed │ ${T9.default.red(`-${U.linesRemoved}`).padEnd(12)} │`,"└─────────────────────┴──────────────┘"].join(`
1465
1465
  `);J5(Y,"Overview");let A=Object.entries(U.skillsUsed).sort(([,W],[,H])=>H-W).slice(0,5);if(A.length>0){let W=[T9.default.bold("\uD83C\uDFC6 Top Skills Used"),...A.map(([H,B],V)=>` ${V+1}. ${H} (${B})`)].join(`
1466
- `);J5(W,"Skills")}R5(T9.default.dim(`Data stored in: ${J}`))}function tO2($){o1($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(j5(async(z)=>{await sO2(x1(z),z.reset)},{supportsJsonOutput:!0}))}F7();var h4=d2(N4(),1);import{execSync as iq5}from"node:child_process";import{cpSync as vD,existsSync as R9,mkdirSync as Ju,readFileSync as QQ,rmSync as Jn,writeFileSync as mJ}from"node:fs";import{tmpdir as xq5}from"node:os";import{dirname as Gq2,join as X3}from"node:path";var TD=d2(N4(),1);import{execSync as Pq5,spawn as Cq5}from"node:child_process";import{realpathSync as eO2}from"node:fs";import Gu from"node:process";var xJ="oh-my-agent";function Sq5($=Gu.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(Gu.env.IS_BINARY==="true")return{packageManager:"binary",isGlobal:!0,updateMessage:"Running as a standalone binary. Download the latest release from GitHub."};let z;try{z=t6(eO2($))}catch{return{packageManager:"unknown",isGlobal:!1}}if(z.includes("/.npm/_npx")||z.includes("/npm/_npx"))return{packageManager:"npx",isGlobal:!1,updateMessage:"Running via npx, auto-update not applicable."};if(z.includes("/.pnpm/_pnpx")||z.includes("/.cache/pnpm/dlx"))return{packageManager:"pnpx",isGlobal:!1,updateMessage:"Running via pnpx, auto-update not applicable."};if(z.includes("/.bun/install/cache"))return{packageManager:"bunx",isGlobal:!1,updateMessage:"Running via bunx, auto-update not applicable."};if(Gu.platform==="darwin")try{let G=Pq5(`brew --prefix ${xJ}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=t6(eO2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${xJ}`,updateMessage:"Installed via Homebrew. Updating in background..."}}}catch{}if(z.includes("/.pnpm/global")||z.includes("/.local/share/pnpm"))return{packageManager:"pnpm",isGlobal:!0,updateCommand:`pnpm add -g ${xJ}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${xJ}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${xJ}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${xJ}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var $q2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function _q5($,z){let G=$.match($q2),J=z.match($q2);if(!G||!J)return!1;for(let U=1;U<=3;U++){let K=Number(G[U]),k=Number(J[U]);if(K<k)return!0;if(K>k)return!1}return!1}async function yq5($=xJ,z=2000){try{let G=await N$.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function zq2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(Gu.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(Gu.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await yq5();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!_q5($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=Sq5();if(!G.updateCommand)return $.onNotice?.(TD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return Cq5(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(TD.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(TD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var RD={name:"oh-my-agent",version:"7.7.0",description:"Portable multi-agent harness for .agents-based skills and workflows across Antigravity, Claude Code, Codex, OpenCode, and more",type:"module",bin:{"oh-my-agent":"./bin/cli.js",oma:"./bin/cli.js"},files:["bin"],keywords:["oh-my-agent","antigravity",".agents","agent","skills","agent-skills","multi-agent","orchestrator","claude","claude-code","codex","opencode","copilot","cursor","chatgpt","pm","frontend","backend","mobile","qa","debug","terraform","database","workflow","bug-fixing","gemini"],author:"our.first.fluke <our.first.fluke@gmail.com>",contributors:["gracefullight <gracefullight.dev@gmail.com>","gahyun-git <go4it.gh@gmail.com>"],license:"MIT",funding:[{type:"github",url:"https://github.com/sponsors/first-fluke"},{type:"buymeacoffee",url:"https://buymeacoffee.com/firstfluke"}],scripts:{"sync:readme":"node ./scripts/sync-readme.mjs","generate:skill-data":"node ./scripts/generate-skill-data.mjs",build:"bun run generate:skill-data && bun run sync:readme && bun build cli.ts --outfile bin/cli.js --target node --minify",dev:"bun run generate:skill-data && bun run cli.ts",lint:"biome check --write --unsafe .","check:boundaries":"node ./scripts/check-boundaries.mjs",test:"vitest run","test:coverage":"vitest run --coverage",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^1.1.0","@date-fns/tz":"^1.4.1",axios:"^1.15.0","better-sqlite3":"^12.9.0",chokidar:"^5.0.0",commander:"^14.0.3","date-fns":"^4.1.0",eld:"^2.0.3","fast-xml-parser":"^4",minimatch:"^10.2.5","p-map":"^7.0.4",picocolors:"^1.1.1","puppeteer-core":"^24",remark:"^15.0.1","remark-frontmatter":"^5.0.0","remark-parse":"^11.0.0","smol-toml":"^1.6.1",unified:"^11.0.5",ws:"^8.18.0",yaml:"^2.8.2",zod:"^4.3.6"},devDependencies:{"@biomejs/biome":"2.4.5","@types/better-sqlite3":"^7.6.13","@types/mdast":"^4.0.4","@types/node":"^24","@types/ws":"^8.18.1","@vitest/coverage-v8":"^4.1.4",typescript:"^6",vitest:"^4.0.18"},repository:{type:"git",url:"https://github.com/first-fluke/oh-my-agent"},antigravity:{skillsPath:".agents/skills",skills:["oma-architecture","oma-brainstorm","oma-coordination","oma-pm","oma-frontend","oma-backend","oma-db","oma-mobile","oma-qa","oma-debug","oma-orchestrator","oma-dev-workflow","oma-tf-infra","oma-scm","oma-pdf","oma-recap"]}};function mq5($){if(!$)return{intro:(G)=>x4(G),outro:(G)=>R5(G),note:(G,J)=>J5(G,J),logError:(G)=>s5.error(G),spinnerStart:(G)=>{let J=A6();return J.start(G),J}};let z={start(G){},stop(G){if(G)console.log(G)},message(G){console.log(G)}};return{intro:(G)=>console.log(G),outro:(G)=>console.log(G),note:(G,J)=>console.log(G),logError:(G)=>console.error(G),spinnerStart:(G)=>{return console.log(G),z}}}function gq5($,z){if($!==null)return"ready";return z?"legacy":"missing"}async function Un($=!1,z=!1){if(!z&&process.stdout.isTTY)console.clear();let G=mq5(z);G.intro(h4.default.bgMagenta(h4.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let J=process.cwd();await zq2({currentVersion:RD.version,enabled:i92(J),onSpawnStart:(L)=>G.note(L,"CLI auto-update"),onNotice:(L)=>G.note(L,"CLI update available")});let U=await qB(J),K=k32(J),k=gq5(U,K);if(k==="missing"){if(G.logError("oh-my-agent is not installed in this project. Run `oma install` first."),z)throw Error("oh-my-agent is not installed in this project. Run `oma install` first.");process.exit(1)}let X=NG(J);if(X.length>0)G.note(X.map((L)=>`${h4.default.green("✓")} ${L}`).join(`
1466
+ `);J5(W,"Skills")}R5(T9.default.dim(`Data stored in: ${J}`))}function tO2($){o1($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(j5(async(z)=>{await sO2(x1(z),z.reset)},{supportsJsonOutput:!0}))}F7();var h4=d2(N4(),1);import{execSync as iq5}from"node:child_process";import{cpSync as vD,existsSync as R9,mkdirSync as Ju,readFileSync as QQ,rmSync as Jn,writeFileSync as mJ}from"node:fs";import{tmpdir as xq5}from"node:os";import{dirname as Gq2,join as X3}from"node:path";var TD=d2(N4(),1);import{execSync as Pq5,spawn as Cq5}from"node:child_process";import{realpathSync as eO2}from"node:fs";import Gu from"node:process";var xJ="oh-my-agent";function Sq5($=Gu.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(Gu.env.IS_BINARY==="true")return{packageManager:"binary",isGlobal:!0,updateMessage:"Running as a standalone binary. Download the latest release from GitHub."};let z;try{z=t6(eO2($))}catch{return{packageManager:"unknown",isGlobal:!1}}if(z.includes("/.npm/_npx")||z.includes("/npm/_npx"))return{packageManager:"npx",isGlobal:!1,updateMessage:"Running via npx, auto-update not applicable."};if(z.includes("/.pnpm/_pnpx")||z.includes("/.cache/pnpm/dlx"))return{packageManager:"pnpx",isGlobal:!1,updateMessage:"Running via pnpx, auto-update not applicable."};if(z.includes("/.bun/install/cache"))return{packageManager:"bunx",isGlobal:!1,updateMessage:"Running via bunx, auto-update not applicable."};if(Gu.platform==="darwin")try{let G=Pq5(`brew --prefix ${xJ}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=t6(eO2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${xJ}`,updateMessage:"Installed via Homebrew. Updating in background..."}}}catch{}if(z.includes("/.pnpm/global")||z.includes("/.local/share/pnpm"))return{packageManager:"pnpm",isGlobal:!0,updateCommand:`pnpm add -g ${xJ}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${xJ}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${xJ}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${xJ}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var $q2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function _q5($,z){let G=$.match($q2),J=z.match($q2);if(!G||!J)return!1;for(let U=1;U<=3;U++){let K=Number(G[U]),k=Number(J[U]);if(K<k)return!0;if(K>k)return!1}return!1}async function yq5($=xJ,z=2000){try{let G=await N$.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function zq2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(Gu.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(Gu.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await yq5();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!_q5($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=Sq5();if(!G.updateCommand)return $.onNotice?.(TD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return Cq5(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(TD.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(TD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var RD={name:"oh-my-agent",version:"7.8.0",description:"Portable multi-agent harness for .agents-based skills and workflows across Antigravity, Claude Code, Codex, OpenCode, and more",type:"module",bin:{"oh-my-agent":"./bin/cli.js",oma:"./bin/cli.js"},files:["bin"],keywords:["oh-my-agent","antigravity",".agents","agent","skills","agent-skills","multi-agent","orchestrator","claude","claude-code","codex","opencode","copilot","cursor","chatgpt","pm","frontend","backend","mobile","qa","debug","terraform","database","workflow","bug-fixing","gemini"],author:"our.first.fluke <our.first.fluke@gmail.com>",contributors:["gracefullight <gracefullight.dev@gmail.com>","gahyun-git <go4it.gh@gmail.com>"],license:"MIT",funding:[{type:"github",url:"https://github.com/sponsors/first-fluke"},{type:"buymeacoffee",url:"https://buymeacoffee.com/firstfluke"}],scripts:{"sync:readme":"node ./scripts/sync-readme.mjs","generate:skill-data":"node ./scripts/generate-skill-data.mjs",build:"bun run generate:skill-data && bun run sync:readme && bun build cli.ts --outfile bin/cli.js --target node --minify",dev:"bun run generate:skill-data && bun run cli.ts",lint:"biome check --write --unsafe .","check:boundaries":"node ./scripts/check-boundaries.mjs",test:"vitest run","test:coverage":"vitest run --coverage",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^1.1.0","@date-fns/tz":"^1.4.1",axios:"^1.15.0","better-sqlite3":"^12.9.0",chokidar:"^5.0.0",commander:"^14.0.3","date-fns":"^4.1.0",eld:"^2.0.3","fast-xml-parser":"^4",minimatch:"^10.2.5","p-map":"^7.0.4",picocolors:"^1.1.1","puppeteer-core":"^24",remark:"^15.0.1","remark-frontmatter":"^5.0.0","remark-parse":"^11.0.0","smol-toml":"^1.6.1",unified:"^11.0.5",ws:"^8.18.0",yaml:"^2.8.2",zod:"^4.3.6"},devDependencies:{"@biomejs/biome":"2.4.5","@types/better-sqlite3":"^7.6.13","@types/mdast":"^4.0.4","@types/node":"^24","@types/ws":"^8.18.1","@vitest/coverage-v8":"^4.1.4",typescript:"^6",vitest:"^4.0.18"},repository:{type:"git",url:"https://github.com/first-fluke/oh-my-agent"},antigravity:{skillsPath:".agents/skills",skills:["oma-architecture","oma-brainstorm","oma-coordination","oma-pm","oma-frontend","oma-backend","oma-db","oma-mobile","oma-qa","oma-debug","oma-orchestrator","oma-dev-workflow","oma-tf-infra","oma-scm","oma-pdf","oma-recap"]}};function mq5($){if(!$)return{intro:(G)=>x4(G),outro:(G)=>R5(G),note:(G,J)=>J5(G,J),logError:(G)=>s5.error(G),spinnerStart:(G)=>{let J=A6();return J.start(G),J}};let z={start(G){},stop(G){if(G)console.log(G)},message(G){console.log(G)}};return{intro:(G)=>console.log(G),outro:(G)=>console.log(G),note:(G,J)=>console.log(G),logError:(G)=>console.error(G),spinnerStart:(G)=>{return console.log(G),z}}}function gq5($,z){if($!==null)return"ready";return z?"legacy":"missing"}async function Un($=!1,z=!1){if(!z&&process.stdout.isTTY)console.clear();let G=mq5(z);G.intro(h4.default.bgMagenta(h4.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let J=process.cwd();await zq2({currentVersion:RD.version,enabled:i92(J),onSpawnStart:(L)=>G.note(L,"CLI auto-update"),onNotice:(L)=>G.note(L,"CLI update available")});let U=await qB(J),K=k32(J),k=gq5(U,K);if(k==="missing"){if(G.logError("oh-my-agent is not installed in this project. Run `oma install` first."),z)throw Error("oh-my-agent is not installed in this project. Run `oma install` first.");process.exit(1)}let X=NG(J);if(X.length>0)G.note(X.map((L)=>`${h4.default.green("✓")} ${L}`).join(`
1467
1467
  `),"Migration");let Q=X.length>0||FS(J);if(X.length>0&&!FS(J))NS(J,!0);if(!z)await IB(J);if(k==="legacy")G.note("Existing .agents installation detected without _version.json. Updating in place and restoring version metadata.","Legacy install");let Z;try{Z=G.spinnerStart("Checking for updates...");let L=await Y32();if(U===L.version&&!Q){Z.stop(h4.default.green("Already up to date!")),G.outro(`Current version: ${h4.default.cyan(U)}`);return}let j=U===L.version;Z.message(`Downloading ${h4.default.cyan(L.version)}...`);let{dir:u,cleanup:Y}=await OK();try{Z.message("Copying files..."),NG(J);let A=X3(J,".agents","oma-config.yaml"),W=X3(J,".agents","mcp.json"),H=!$&&R9(A)?QQ(A):null,B=!$&&R9(W)?QQ(W):null,V=X3(xq5(),`oma-stack-backup-${Date.now()}`),F=X3(J,".agents","skills","oma-backend","stack"),N=!$&&R9(F);if(N)Ju(V,{recursive:!0}),vD(F,X3(V,"oma-backend"),{recursive:!0});let M=["snippets.md","tech-stack.md","api-template.py"],E=X3(J,".agents","skills","oma-backend","resources"),q=!$&&!N&&M.some((S)=>R9(X3(E,S))),D=OS(J);if(vD(X3(u,".agents"),X3(J,".agents"),{recursive:!0,force:!0}),H)mJ(A,H);if(B)mJ(W,B);if(N)try{Ju(F,{recursive:!0}),vD(X3(V,"oma-backend"),F,{recursive:!0,force:!0})}finally{Jn(V,{recursive:!0,force:!0})}if(q){let S=X3(u,".agents","skills","oma-backend","variants","python");if(R9(S))Ju(F,{recursive:!0}),vD(S,F,{recursive:!0,force:!0}),mJ(X3(F,"stack.yaml"),`language: python
1468
1468
  framework: fastapi
1469
1469
  orm: sqlalchemy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-agent",
3
- "version": "7.7.0",
3
+ "version": "7.8.0",
4
4
  "description": "Portable multi-agent harness for .agents-based skills and workflows across Antigravity, Claude Code, Codex, OpenCode, and more",
5
5
  "type": "module",
6
6
  "bin": {