oh-my-agent 5.20.0 → 5.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/cli.js +1 -1
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -1379,7 +1379,7 @@ print(json.dumps({
1379
1379
  }))
1380
1380
  `;function fU$(){return process.env.OMA_PYTHON??"python3"}function uU$($){if(yU$.some((J)=>$===J||$.endsWith(`.${J}`)))return["safari","chrome","firefox"];return["chrome","safari","firefox"]}async function gU$($,J,X){return new Promise((G)=>{let Q=kU$(fU$(),["-c",hU$],{env:{...process.env,OMA_IMPERSONATE_URL:$.toString(),OMA_IMPERSONATE_TARGET:J,OMA_IMPERSONATE_LOCALE:X.locale,OMA_IMPERSONATE_TIMEOUT:String(X.timeoutMs)},stdio:["ignore","pipe","pipe"]}),Y="",Z="";Q.stdout.on("data",(U)=>{Y+=U.toString()}),Q.stderr.on("data",(U)=>{Z+=U.toString()});let K=()=>{Q.kill("SIGTERM")};X.signal?.addEventListener("abort",K),Q.on("close",(U)=>{if(X.signal?.removeEventListener("abort",K),U!==0&&!Y){G({error:`python_exit:${U}:${Z.trim().slice(0,200)}`});return}let W=Y.trim();if(!W){G({error:"empty_stdout"});return}try{G(JSON.parse(W))}catch(H){G({error:`parse_error:${H.message}:${W.slice(0,200)}`})}}),Q.on("error",(U)=>{X.signal?.removeEventListener("abort",K),G({error:`spawn_error:${U.message}`})})})}function mU$($,J,X){let G=new Headers;if($.headers)for(let[Q,Y]of Object.entries($.headers))try{G.set(Q,Y)}catch{}return{ok:($.status??0)>=200&&($.status??0)<400,status:$.status??0,headers:G,url:$.url??J,text:$.body??"",elapsedMs:X,redirected:($.url??J)!==J}}async function UB0($,J){let X=uU$($.hostname),G=[],Q=performance.now();for(let K of X){if(J.signal?.aborted)break;let U=performance.now(),W=await gU$($,K,J),H=Math.round(performance.now()-U);if(W.error==="curl_cffi_not_installed")return I4({url:$.toString(),strategy:"impersonate",error:Error("curl_cffi is not installed. Run: pip install curl_cffi")});if(W.error){G.push({target:K,detail:W.error});continue}let z=mU$(W,$.toString(),H),B=b6(z);if(t10(B))return{url:$.toString(),status:"blocked",strategy:"impersonate",platform:K,httpStatus:z.status,content:z.text,contentType:z.headers.get("content-type")??void 0,elapsedMs:Math.round(performance.now()-Q),signals:B,error:"js-essential-markers-detected"};if(z.ok&&z.text.length>=200)return{url:$.toString(),status:e8(z,B),strategy:"impersonate",platform:K,httpStatus:z.status,content:z.text,contentType:z.headers.get("content-type")??void 0,elapsedMs:Math.round(performance.now()-Q),signals:B};G.push({target:K,detail:`status=${z.status} size=${z.text.length}`})}let Y=Math.round(performance.now()-Q),Z=G.map((K)=>`${K.target}(${K.detail})`).join(" | ");return{...I4({url:$.toString(),strategy:"impersonate",error:Error(Z?`impersonate_failed: ${Z}`:"impersonate_failed")}),elapsedMs:Y,signals:[]}}var WB0="https://r.jina.ai/";function cU$($){let J=`${$.protocol}//${$.hostname}`,X=$.hostname.startsWith("m.")?$.hostname:`m.${$.hostname.replace(/^www\./,"")}`,G=new URL($.toString());return G.hostname=X,[{label:"jina",url:`${WB0}${$.toString()}`,headers:xG({accept:"text/plain"})},{label:"jina-json",url:`${WB0}${$.toString()}`,headers:xG({accept:"application/json"})},{label:"curl-desktop",url:$.toString(),headers:xG({userAgent:R5.desktopFirefox,referer:J})},{label:"curl-mobile",url:G.toString(),headers:xG({userAgent:R5.mobileSafari,referer:J})},{label:"curl-googlebot",url:$.toString(),headers:xG({userAgent:R5.googlebot})}]}function pU$($,J){if(!$.startsWith("jina"))return J;return J}async function HB0($,J){let X=cU$($),G=new AbortController;if(J.signal)if(J.signal.aborted)G.abort(J.signal.reason);else J.signal.addEventListener("abort",()=>G.abort(J.signal?.reason));let Q=performance.now(),Y={},Z=null,K=X.map(async(U)=>{let W=await S4(U.url,{headers:U.headers,timeoutMs:J.timeoutMs,signal:G.signal,locale:J.locale}),H=b6(W);if(U.label.startsWith("jina")){let z=s10(W);if(z)throw Z=z,Error(`jina-quota:${z.detail}`)}if(!lU$(W,H))throw Y[U.label]=`status=${W.status} size=${W.text.length}`,Error(`weak-response:${U.label}`);return{label:U.label,resp:W,signals:H}});try{let U=await Promise.any(K);G.abort();let W=Math.round(performance.now()-Q);return{url:$.toString(),status:e8(U.resp,U.signals),strategy:"probe",platform:U.label,httpStatus:U.resp.status,content:pU$(U.label,U.resp.text),contentType:U.resp.headers.get("content-type")??void 0,elapsedMs:W,signals:Z?[...U.signals,Z]:U.signals}}catch(U){let W=Math.round(performance.now()-Q),H=Object.entries(Y).map(([z,B])=>`${z}:${B}`).join(" ");if(Z)return{...I4({url:$.toString(),error:Error(`probe failed — ${H}`),strategy:"probe"}),elapsedMs:W,signals:[Z]};return{...I4({url:$.toString(),error:U instanceof AggregateError?Error(H):U,strategy:"probe"}),elapsedMs:W}}}function lU$($,J){if(!$.ok)return!1;if($.text.length<200)return!1;if(J.some((X)=>X.kind==="waf-body"||X.kind==="challenge-body"||X.kind==="js-essential"||X.kind==="http-status"))return!1;return!0}var dU$=["api","probe","impersonate","browser","archive"];function iU$($){if($.only?.length)return $.only;let J=dU$.slice();if(!$.includeArchive)J=J.filter((X)=>X!=="archive");if($.skip?.length)J=J.filter((X)=>!$.skip?.includes(X));return J}async function zB0($,J,X){switch($){case"api":return await pL(J,X)??null;case"probe":return HB0(J,X);case"impersonate":return UB0(J,X);case"browser":return KB0(J,X);case"archive":return VW(J,X)}}function Ig($){if($.status==="ok")return!0;if($.status==="auth-required"&&e10($.signals))return!0;return!1}function nU$($){return $.status==="auth-required"||$.status==="invalid-input"||$.status==="not-found"}async function oU$($){let J=Math.floor(Math.random()*500);await new Promise((X)=>setTimeout(X,$+J))}function aU$($){let J=$.find((Q)=>Q.kind==="rate-limit");if(!J)return 1500;let X=J.detail.match(/retry-after=(\d+)/);if(!X?.[1])return 1500;let G=Number.parseInt(X[1],10);if(Number.isNaN(G)||G>10)return 1500;return G*1000}async function VB0($,J,X={}){let G=iU$(X),Q=[],Y=new Set,Z=null,K=!1;for(let U of G){if(J.signal?.aborted)break;if(K&&U==="impersonate")continue;let W=await zB0(U,$,J);if(!W)continue;if(Q.push({strategy:U,platform:W.platform,status:W.status,httpStatus:W.httpStatus,elapsedMs:W.elapsedMs,signals:W.signals,error:W.error}),W.signals.some((H)=>H.kind==="js-essential"))K=!0;if(Ig(W))return W.attempts=Q,W;if(nU$(W))return W.attempts=Q,W;if(X.retryOnRateLimit!==!1&&$40(W.signals)&&!Y.has(U)){Y.add(U),await oU$(aU$(W.signals));let H=await zB0(U,$,J);if(H){if(Q.push({strategy:U,platform:H.platform,status:H.status,httpStatus:H.httpStatus,elapsedMs:H.elapsedMs,signals:H.signals,error:H.error}),Ig(H))return H.attempts=Q,H;Z=H;continue}}Z=W}if(!G.includes("archive")&&X.includeArchive!==!1){let U=await VW($,J);if(Q.push({strategy:"archive",platform:U.platform,status:U.status,httpStatus:U.httpStatus,elapsedMs:U.elapsedMs,signals:U.signals,error:U.error}),Ig(U))return U.attempts=Q,U;Z=U}if(Z)return Z.attempts=Q,Z;return{url:$.toString(),status:"error",strategy:G[0]??"probe",content:"",elapsedMs:0,signals:[],attempts:Q,error:"all strategies failed"}}var tB0=d0(sB0(),1);var MH$=["/rss","/feed","/atom.xml","/rss.xml","/index.xml"],AH$=new tB0.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text"});function jg($){if($===void 0||$===null)return[];return Array.isArray($)?$:[$]}function G6($){if($==null)return;if(typeof $==="string")return $;if(typeof $==="object"){let J=$;if(typeof J["#text"]==="string")return J["#text"];if(typeof J["#cdata"]==="string")return J["#cdata"]}return}function rB0($){for(let J of jg($)){let X=J?.["@_href"],G=J?.["@_rel"];if(typeof X==="string"&&(G===void 0||G==="alternate"))return X}return}function eB0($){let J;try{J=AH$.parse($)}catch{return null}let X=J.rss;if(X){let Q=X.channel;if(!Q)return null;let Y=jg(Q.item);return{kind:"rss",title:G6(Q.title),description:G6(Q.description),link:G6(Q.link),entries:Y.map((Z)=>({title:G6(Z.title),link:G6(Z.link),pubDate:G6(Z.pubDate),description:G6(Z.description),content:G6(Z["content:encoded"])??G6(Z.content)}))}}let G=J.feed;if(G){let Q=jg(G.entry);return{kind:"atom",title:G6(G.title),description:G6(G.subtitle),link:rB0(G.link),entries:Q.map((Y)=>({title:G6(Y.title),link:rB0(Y.link),pubDate:G6(Y.published)??G6(Y.updated),description:G6(Y.summary),content:G6(Y.content)??G6(Y.summary)}))}}return null}async function $O0($,J){let X=performance.now(),G;try{let Y=await S4($.toString(),{timeoutMs:J.timeoutMs,locale:J.locale,signal:J.signal});if(Y.ok)G=cL(Y.text).alternate?.[0]?.href}catch{}let Q=new Set;if(G)try{Q.add(new URL(G,$).toString())}catch{}for(let Y of MH$)Q.add(new URL(Y,`${$.protocol}//${$.host}`).toString());for(let Y of Q){if(J.signal?.aborted)break;try{let Z=await S4(Y,{timeoutMs:J.timeoutMs,locale:J.locale,signal:J.signal});if(!Z.ok||Z.text.length<50)continue;let K=eB0(Z.text);if(!K||K.entries.length===0)continue;return{url:$.toString(),status:"ok",strategy:"probe",platform:"rss",httpStatus:Z.status,content:Z.text,contentType:Z.headers.get("content-type")??void 0,elapsedMs:Math.round(performance.now()-X),signals:[],feedUrl:Y,feed:K}}catch{}}return{url:$.toString(),status:"not-found",strategy:"probe",platform:"rss",content:"",elapsedMs:Math.round(performance.now()-X),signals:[],error:"no RSS/Atom feed discovered"}}function JO0($,J="en-US"){let[X,G]=J.split("-"),Q=new URL("https://news.google.com/rss/search");return Q.searchParams.set("q",$),Q.searchParams.set("hl",X??"en"),Q.searchParams.set("gl",G??"US"),Q.searchParams.set("ceid",`${G??"US"}:${X??"en"}`),Q.toString()}var OI={"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 IH$($){return $.replace(/^www\./,"")}function RH$($){if($ in OI){let X=OI[$];return X?{...X}:null}let J=IH$($);if(J in OI){let X=OI[J];return X?{...X}:null}return null}function DH$($){let J=$.split(".").pop();if(J==="gov"||J==="edu"||J==="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 TH$($){try{let J=await S4(`https://tranco-list.eu/api/ranks/domain/${$}`,{timeoutMs:5000});if(!J.ok)return null;let G=JSON.parse(J.text).ranks?.[0]?.rank;if(!G)return null;let Q=G<1e4?0.6:G<1e5?0.4:0.2;return{domain:$,level:G<1e4?"community":"external",score:Q,tags:["tranco"],source:"tranco",rank:G}}catch{return null}}async function XO0($){let J=RH$($);if(J)return J;let X=DH$($);if(X)return X;let G=await TH$($);if(G)return G;return{domain:$,level:"unknown",score:null,tags:[],source:"heuristic"}}var GO0=["api","probe","impersonate","browser","archive"];function QO0($){if(!$)return;let J=$.split(",").map((G)=>G.trim()).filter(Boolean),X=J.filter((G)=>!GO0.includes(G));if(X.length>0)throw Error(`Unknown strategy: ${X.join(", ")}. Valid: ${GO0.join(", ")}`);return J}function aZ($){try{return new URL($)}catch{throw Error(`Invalid URL: ${$}`)}}function jX($){return{timeoutMs:$.timeout?Math.max(1000,Math.floor(Number($.timeout)*1000)):15000,locale:$.locale??"en-US,en;q=0.9"}}function f7($,J){if(J)console.log(JSON.stringify($,null,2));else console.log(JSON.stringify($))}function y3($){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 YO0($){let J=$.command("search").description("Mechanical search primitives — fetch, meta, rss, media, trust, code").alias("s");J.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(X,G)=>{try{let Q=aZ(X),Y=jX(G),Z=await VB0(Q,Y,{only:QO0(G.only),skip:QO0(G.skip),includeArchive:G.includeArchive});f7(Z,Boolean(G.pretty)),y3(Z)}catch(Q){console.error(m5.default.red(Q.message)),process.exitCode=1}}),J.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(X,G)=>{try{let Q=aZ(X);if(!Mv(Q)){console.error(m5.default.yellow(`No API handler matches host ${Q.hostname}`)),process.exitCode=3;return}let Z=jX(G),K=await pL(Q,Z);if(!K){process.exitCode=3;return}f7(K,Boolean(G.pretty)),y3(K)}catch(Q){console.error(m5.default.red(Q.message)),process.exitCode=1}}),J.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(X,G)=>{let Q=jX(G),Y=G.platforms?G.platforms.split(",").map((K)=>K.trim()).filter(Boolean):void 0,Z=await A40(X,Q,Y);f7(Z,Boolean(G.pretty))}),J.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(X,G)=>{try{let Q=aZ(X),Y=jX(G),Z=await a10(Q,Y),{content:K,...U}=Z;f7(U,Boolean(G.pretty)),y3(Z)}catch(Q){console.error(m5.default.red(Q.message)),process.exitCode=1}}),J.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(X,G)=>{try{let Q=aZ(X),Y=jX(G),Z=await $O0(Q,Y),{content:K,...U}=Z;f7(U,Boolean(G.pretty)),y3(Z)}catch(Q){console.error(m5.default.red(Q.message)),process.exitCode=1}}),J.command("rss:google <query>").description("Build Google News RSS URL for a query").option("--locale <value>","Locale (e.g., ko-KR)","en-US").action((X,G)=>{let Q=JO0(X,G.locale??"en-US");console.log(Q)}),J.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(X,G)=>{try{let Q=aZ(X),Y=jX(G),Z=G.subLang?G.subLang.split(",").map((U)=>U.trim()).filter(Boolean):void 0,K=await n10(Q,Y,{subtitles:G.subs,...Z?{subLangs:Z}:{},...G.format?{format:G.format}:{}});f7(K,Boolean(G.pretty)),y3(K)}catch(Q){console.error(m5.default.red(Q.message)),process.exitCode=1}}),J.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(X,G)=>{try{let Q=aZ(X),Y=jX(G),Z=await VW(Q,Y);f7(Z,Boolean(G.pretty)),y3(Z)}catch(Q){console.error(m5.default.red(Q.message)),process.exitCode=1}}),J.command("trust <domain>").description("Resolve trust level / score for a domain").option("--pretty","Pretty-print JSON").action(async(X,G)=>{let Q=await XO0(X.toLowerCase());f7(Q,Boolean(G.pretty))}),J.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(X,G)=>{let Q=G.host==="gitlab"||G.host==="github"?G.host:"github",Y=jX({}),Z=await i10(X,Y,{host:Q,...G.language?{language:G.language}:{},...G.repo?{repo:G.repo}:{},...G.limit?{limit:Number.parseInt(G.limit,10)}:{}});f7(Z,Boolean(G.pretty)),y3(Z)}),J.command("doctor").description("Check dependencies (Chrome, python3 curl_cffi, yt-dlp, gh)").action(async()=>{let X=[],G=Ag();X.push({name:"chrome",ok:Boolean(G),detail:G??"Install Chrome or set OMA_CHROME_PATH"}),X.push(await Cg("python3",["--version"])),X.push(await EH$()),X.push(await Cg("yt-dlp",["--version"])),X.push(await Cg("gh",["--version"]));for(let Q of X){let Y=Q.ok?m5.default.green("✓"):m5.default.yellow("!");console.log(`${Y} ${Q.name}: ${Q.detail}`)}if(X.some((Q)=>!Q.ok))process.exitCode=1})}async function Cg($,J){return new Promise((X)=>{let{spawn:G}=r("node:child_process"),Q=G($,J,{stdio:["ignore","pipe","pipe"]}),Y="";Q.stdout?.on("data",(Z)=>{Y+=Z.toString()}),Q.on("error",()=>X({name:$,ok:!1,detail:"not found"})),Q.on("close",(Z)=>{if(Z===0)X({name:$,ok:!0,detail:Y.trim()});else X({name:$,ok:!1,detail:`exit code ${Z}`})})})}async function EH$(){return new Promise(($)=>{let{spawn:J}=r("node:child_process"),X=J("python3",["-c","import curl_cffi; print(curl_cffi.__version__)"],{stdio:["ignore","pipe","pipe"]}),G="";X.stdout?.on("data",(Q)=>{G+=Q.toString()}),X.on("error",()=>$({name:"curl_cffi",ok:!1,detail:"python3 not found"})),X.on("close",(Q)=>{if(Q===0)$({name:"curl_cffi",ok:!0,detail:`v${G.trim()}`});else $({name:"curl_cffi",ok:!1,detail:"not installed (pip install curl_cffi)"})})})}t6();var CX=d0(A1(),1);import{execSync as PH$,spawnSync as ZO0}from"node:child_process";import{platform as wH$}from"node:os";function jH$(){let $=wH$();if($==="darwin")return"brew install gh";if($==="win32")return"winget install GitHub.cli";return"sudo apt install gh"}async function KO0(){if(console.clear(),w1(CX.default.bgMagenta(CX.default.white(" ⭐ oh-my-agent star "))),!GG()){let J=jH$(),X=await K6({message:`GitHub CLI (gh) is not installed. Install with ${CX.default.cyan(J)}?`});if(W1(X)||!X){L$("Install gh manually and try again.");return}let G=d8();G.start("Installing GitHub CLI...");let Q=ZO0(J,{shell:!0,stdio:"pipe"});if(Q.status!==0){G.stop("Installation failed"),o$.error(Q.stderr?.toString()||"Unknown error"),L$("Please install gh manually.");return}G.stop("GitHub CLI installed!")}if(!B5()){o$.warn("GitHub CLI is not authenticated.");let J=await K6({message:`Run ${CX.default.cyan("gh auth login")} now?`});if(W1(J)||!J){L$("Authenticate and try again.");return}if(ZO0("gh",["auth","login"],{stdio:"inherit"}),!B5()){L$("Authentication was not completed. Try again.");return}o$.success("Authenticated!")}if(QG()){L$(`Already starred ${CX.default.cyan(g1)}! Thank you! \uD83D\uDE4F`);return}let $=await K6({message:`Star ${CX.default.cyan(g1)} on GitHub?`});if(W1($)||!$){L$("Maybe next time!");return}try{PH$(`gh api -X PUT /user/starred/${g1}`,{stdio:"ignore"}),L$(`Starred ${CX.default.cyan(g1)}! Thank you! \uD83C\uDF1F`)}catch{o$.error("Failed to star the repository."),L$("Please try again later.")}}function UO0($){$.command("star").description("Star oh-my-agent on GitHub").action(N$(async()=>{await KO0()}))}t6();Vv();HU();var s9=d0(A1(),1);import{existsSync as LI,mkdirSync as CH$,readdirSync as SH$,readFileSync as _H$,writeFileSync as WO0}from"node:fs";import{dirname as xH$,join as HO0}from"node:path";function _g($){return HO0($,".serena","metrics.json")}function Sg(){return{sessions:0,skillsUsed:{},tasksCompleted:0,totalSessionTime:0,filesChanged:0,linesAdded:0,linesRemoved:0,lastUpdated:new Date().toISOString(),startDate:new Date().toISOString()}}function vH$($){let J=_g($);if(LI(J))try{return JSON.parse(_H$(J,"utf-8"))}catch{return Sg()}return Sg()}function bH$($,J){let X=_g($),G=xH$(X);if(!LI(G))CH$(G,{recursive:!0});J.lastUpdated=new Date().toISOString(),WO0(X,JSON.stringify(J,null,2),"utf-8")}function kH$($){let J=HO0($,".serena","memories"),X={};if(!LI(J))return X;try{let G=SH$(J);for(let Q of G){let Y=Q.match(/(?:progress|result)-(\w+)/);if(Y?.[1]){let Z=Y[1];X[Z]=(X[Z]||0)+1}}}catch{}return X}async function zO0($=!1,J=!1){let X=process.cwd(),G=_g(X);if(J){if(LI(G))WO0(G,JSON.stringify(Sg(),null,2),"utf-8");if($)console.log(JSON.stringify({reset:!0}));else console.log(s9.default.green("✅ Metrics reset successfully."));return}let Q=vH$(X),Y=uL(X),Z=kH$(X),K=sd(X),U=OB(X),W=U.startedAt?new Date(U.startedAt):null,H=W&&!Number.isNaN(W.getTime())?Math.max(0,Math.floor((Date.now()-W.getTime())/1000)):0;for(let[O,L]of Object.entries(Z))Q.skillsUsed[O]=(Q.skillsUsed[O]||0)+L;if(K>Q.tasksCompleted)Q.tasksCompleted=K;if(U.id){if(["completed","failed","aborted"].includes(U.status||"")&&(Q.lastSessionId!==U.id||Q.lastSessionStatus!==U.status)&&H>0)Q.totalSessionTime+=H;Q.lastSessionId=U.id,Q.lastSessionStatus=U.status,Q.lastSessionStarted=U.startedAt,Q.lastSessionDuration=H}Q.filesChanged+=Y.filesChanged,Q.linesAdded+=Y.linesAdded,Q.linesRemoved+=Y.linesRemoved,Q.sessions+=1,bH$(X,Q);let z=Math.max(1,Math.ceil((Date.now()-new Date(Q.startDate).getTime())/86400000)),B=Q.sessions>0?Math.round(Q.totalSessionTime/Q.sessions):0;if($){console.log(JSON.stringify({...Q,gitStats:Y,daysSinceStart:z,avgSessionTime:B},null,2));return}console.clear(),w1(s9.default.bgMagenta(s9.default.white(" \uD83D\uDCCA oh-my-agent stats ")));let V=[s9.default.bold(`\uD83D\uDCC8 Productivity Metrics (${z} days)`),"┌─────────────────────┬──────────────┐",`│ ${s9.default.bold("Metric")} │ ${s9.default.bold("Value")} │`,"├─────────────────────┼──────────────┤",`│ Sessions │ ${String(Q.sessions).padEnd(12)} │`,`│ Tasks Completed │ ${String(Q.tasksCompleted).padEnd(12)} │`,`│ Files Changed │ ${String(Q.filesChanged).padEnd(12)} │`,`│ Lines Added │ ${s9.default.green(`+${Q.linesAdded}`).padEnd(12)} │`,`│ Lines Removed │ ${s9.default.red(`-${Q.linesRemoved}`).padEnd(12)} │`,"└─────────────────────┴──────────────┘"].join(`
1381
1381
  `);o0(V,"Overview");let q=Object.entries(Q.skillsUsed).sort(([,O],[,L])=>L-O).slice(0,5);if(q.length>0){let O=[s9.default.bold("\uD83C\uDFC6 Top Skills Used"),...q.map(([L,F],N)=>` ${N+1}. ${L} (${F})`)].join(`
1382
- `);o0(O,"Skills")}L$(s9.default.dim(`Data stored in: ${G}`))}function VO0($){L4($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(N$(async(J)=>{await zO0(G4(J),J.reset)},{supportsJsonOutput:!0}))}t6();var I6=d0(A1(),1);import{execSync as cH$}from"node:child_process";import{cpSync as MI,existsSync as r9,mkdirSync as jz,readFileSync as sZ,rmSync as xg,writeFileSync as f3}from"node:fs";import{tmpdir as pH$}from"node:os";import{dirname as LO0,join as a4}from"node:path";var FI=d0(A1(),1);import{execSync as yH$,spawn as hH$}from"node:child_process";import{realpathSync as qO0}from"node:fs";import wz from"node:process";var h3="oh-my-agent";function fH$($=wz.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(wz.env.IS_BINARY==="true")return{packageManager:"binary",isGlobal:!0,updateMessage:"Running as a standalone binary. Download the latest release from GitHub."};let J;try{J=qO0($).replace(/\\/g,"/")}catch{return{packageManager:"unknown",isGlobal:!1}}if(J.includes("/.npm/_npx")||J.includes("/npm/_npx"))return{packageManager:"npx",isGlobal:!1,updateMessage:"Running via npx, auto-update not applicable."};if(J.includes("/.pnpm/_pnpx")||J.includes("/.cache/pnpm/dlx"))return{packageManager:"pnpx",isGlobal:!1,updateMessage:"Running via pnpx, auto-update not applicable."};if(J.includes("/.bun/install/cache"))return{packageManager:"bunx",isGlobal:!1,updateMessage:"Running via bunx, auto-update not applicable."};if(wz.platform==="darwin")try{let X=yH$(`brew --prefix ${h3}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(X){let G=qO0(X).replace(/\\/g,"/");if(J.startsWith(G))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${h3}`,updateMessage:"Installed via Homebrew. Updating in background..."}}}catch{}if(J.includes("/.pnpm/global")||J.includes("/.local/share/pnpm"))return{packageManager:"pnpm",isGlobal:!0,updateCommand:`pnpm add -g ${h3}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(J.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${h3}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(J.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${h3}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${h3}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var BO0=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function uH$($,J){let X=$.match(BO0),G=J.match(BO0);if(!X||!G)return!1;for(let Q=1;Q<=3;Q++){let Y=Number(X[Q]),Z=Number(G[Q]);if(Y<Z)return!0;if(Y>Z)return!1}return!1}async function gH$($=h3,J=2000){try{let X=await OY.get(`https://registry.npmjs.org/${$}/latest`,{timeout:J});return typeof X.data?.version==="string"?X.data.version:null}catch{return null}}async function OO0($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(wz.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(wz.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let J=await gH$();if(!J)return{triggered:!1,reason:"fetch-failed"};if(!uH$($.currentVersion,J))return{triggered:!1,reason:"up-to-date",latest:J};let X=fH$();if(!X.updateCommand)return $.onNotice?.(FI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. ${X.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:J};try{return hH$(X.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(FI.default.cyan(`global oh-my-agent ${$.currentVersion} → ${J} updating in background. New version applies on next run.`)),{triggered:!0,latest:J}}catch{return $.onNotice?.(FI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. Run: ${X.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:J}}}var NI={name:"oh-my-agent",version:"5.20.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",build:"bun run sync:readme && bun build cli.ts --outfile bin/cli.js --target node --minify",dev:"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","fast-xml-parser":"^4","p-map":"^7.0.4",picocolors:"^1.1.1","puppeteer-core":"^24","smol-toml":"^1.6.1",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/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 lH$($){if(!$)return{intro:(X)=>w1(X),outro:(X)=>L$(X),note:(X,G)=>o0(X,G),logError:(X)=>o$.error(X),spinnerStart:(X)=>{let G=d8();return G.start(X),G}};let J={start(X){},stop(X){if(X)console.log(X)},message(X){console.log(X)}};return{intro:(X)=>console.log(X),outro:(X)=>console.log(X),note:(X,G)=>console.log(X),logError:(X)=>console.error(X),spinnerStart:(X)=>{return console.log(X),J}}}function dH$($,J){if($!==null)return"ready";return J?"legacy":"missing"}async function vg($=!1,J=!1){if(!J&&process.stdout.isTTY)console.clear();let X=lH$(J);X.intro(I6.default.bgMagenta(I6.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let G=process.cwd();await OO0({currentVersion:NI.version,enabled:I$0(G),onSpawnStart:(H)=>X.note(H,"CLI auto-update"),onNotice:(H)=>X.note(H,"CLI update available")});let Q=await RO(G),Y=Ht(G),Z=dH$(Q,Y);if(Z==="missing"){if(X.logError("oh-my-agent is not installed in this project. Run `oma install` first."),J)throw Error("oh-my-agent is not installed in this project. Run `oma install` first.");process.exit(1)}let K=AG(G);if(K.length>0)X.note(K.map((H)=>`${I6.default.green("✓")} ${H}`).join(`
1382
+ `);o0(O,"Skills")}L$(s9.default.dim(`Data stored in: ${G}`))}function VO0($){L4($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(N$(async(J)=>{await zO0(G4(J),J.reset)},{supportsJsonOutput:!0}))}t6();var I6=d0(A1(),1);import{execSync as cH$}from"node:child_process";import{cpSync as MI,existsSync as r9,mkdirSync as jz,readFileSync as sZ,rmSync as xg,writeFileSync as f3}from"node:fs";import{tmpdir as pH$}from"node:os";import{dirname as LO0,join as a4}from"node:path";var FI=d0(A1(),1);import{execSync as yH$,spawn as hH$}from"node:child_process";import{realpathSync as qO0}from"node:fs";import wz from"node:process";var h3="oh-my-agent";function fH$($=wz.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(wz.env.IS_BINARY==="true")return{packageManager:"binary",isGlobal:!0,updateMessage:"Running as a standalone binary. Download the latest release from GitHub."};let J;try{J=qO0($).replace(/\\/g,"/")}catch{return{packageManager:"unknown",isGlobal:!1}}if(J.includes("/.npm/_npx")||J.includes("/npm/_npx"))return{packageManager:"npx",isGlobal:!1,updateMessage:"Running via npx, auto-update not applicable."};if(J.includes("/.pnpm/_pnpx")||J.includes("/.cache/pnpm/dlx"))return{packageManager:"pnpx",isGlobal:!1,updateMessage:"Running via pnpx, auto-update not applicable."};if(J.includes("/.bun/install/cache"))return{packageManager:"bunx",isGlobal:!1,updateMessage:"Running via bunx, auto-update not applicable."};if(wz.platform==="darwin")try{let X=yH$(`brew --prefix ${h3}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(X){let G=qO0(X).replace(/\\/g,"/");if(J.startsWith(G))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${h3}`,updateMessage:"Installed via Homebrew. Updating in background..."}}}catch{}if(J.includes("/.pnpm/global")||J.includes("/.local/share/pnpm"))return{packageManager:"pnpm",isGlobal:!0,updateCommand:`pnpm add -g ${h3}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(J.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${h3}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(J.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${h3}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${h3}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var BO0=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function uH$($,J){let X=$.match(BO0),G=J.match(BO0);if(!X||!G)return!1;for(let Q=1;Q<=3;Q++){let Y=Number(X[Q]),Z=Number(G[Q]);if(Y<Z)return!0;if(Y>Z)return!1}return!1}async function gH$($=h3,J=2000){try{let X=await OY.get(`https://registry.npmjs.org/${$}/latest`,{timeout:J});return typeof X.data?.version==="string"?X.data.version:null}catch{return null}}async function OO0($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(wz.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(wz.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let J=await gH$();if(!J)return{triggered:!1,reason:"fetch-failed"};if(!uH$($.currentVersion,J))return{triggered:!1,reason:"up-to-date",latest:J};let X=fH$();if(!X.updateCommand)return $.onNotice?.(FI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. ${X.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:J};try{return hH$(X.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(FI.default.cyan(`global oh-my-agent ${$.currentVersion} → ${J} updating in background. New version applies on next run.`)),{triggered:!0,latest:J}}catch{return $.onNotice?.(FI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. Run: ${X.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:J}}}var NI={name:"oh-my-agent",version:"5.20.1",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",build:"bun run sync:readme && bun build cli.ts --outfile bin/cli.js --target node --minify",dev:"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","fast-xml-parser":"^4","p-map":"^7.0.4",picocolors:"^1.1.1","puppeteer-core":"^24","smol-toml":"^1.6.1",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/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 lH$($){if(!$)return{intro:(X)=>w1(X),outro:(X)=>L$(X),note:(X,G)=>o0(X,G),logError:(X)=>o$.error(X),spinnerStart:(X)=>{let G=d8();return G.start(X),G}};let J={start(X){},stop(X){if(X)console.log(X)},message(X){console.log(X)}};return{intro:(X)=>console.log(X),outro:(X)=>console.log(X),note:(X,G)=>console.log(X),logError:(X)=>console.error(X),spinnerStart:(X)=>{return console.log(X),J}}}function dH$($,J){if($!==null)return"ready";return J?"legacy":"missing"}async function vg($=!1,J=!1){if(!J&&process.stdout.isTTY)console.clear();let X=lH$(J);X.intro(I6.default.bgMagenta(I6.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let G=process.cwd();await OO0({currentVersion:NI.version,enabled:I$0(G),onSpawnStart:(H)=>X.note(H,"CLI auto-update"),onNotice:(H)=>X.note(H,"CLI update available")});let Q=await RO(G),Y=Ht(G),Z=dH$(Q,Y);if(Z==="missing"){if(X.logError("oh-my-agent is not installed in this project. Run `oma install` first."),J)throw Error("oh-my-agent is not installed in this project. Run `oma install` first.");process.exit(1)}let K=AG(G);if(K.length>0)X.note(K.map((H)=>`${I6.default.green("✓")} ${H}`).join(`
1383
1383
  `),"Migration");let U=K.length>0||Z_(G);if(K.length>0&&!Z_(G))K_(G,!0);if(!J)await pB(G);if(Z==="legacy")X.note("Existing .agents installation detected without _version.json. Updating in place and restoring version metadata.","Legacy install");let W;try{W=X.spinnerStart("Checking for updates...");let H=await zt();if(Q===H.version&&!U){W.stop(I6.default.green("Already up to date!")),X.outro(`Current version: ${I6.default.cyan(Q)}`);return}let z=Q===H.version;W.message(`Downloading ${I6.default.cyan(H.version)}...`);let{dir:B,cleanup:V}=await IO();try{W.message("Copying files..."),AG(G);let q=a4(G,".agents","oma-config.yaml"),O=a4(G,".agents","mcp.json"),L=!$&&r9(q)?sZ(q):null,F=!$&&r9(O)?sZ(O):null,N=a4(pH$(),`oma-stack-backup-${Date.now()}`),A=a4(G,".agents","skills","oma-backend","stack"),I=!$&&r9(A);if(I)jz(N,{recursive:!0}),MI(A,a4(N,"oma-backend"),{recursive:!0});let D=["snippets.md","tech-stack.md","api-template.py"],j=a4(G,".agents","skills","oma-backend","resources"),T=!$&&!I&&D.some((n)=>r9(a4(j,n)));if(MI(a4(B,".agents"),a4(G,".agents"),{recursive:!0,force:!0}),L)f3(q,L);if(F)f3(O,F);if(I)try{jz(A,{recursive:!0}),MI(a4(N,"oma-backend"),A,{recursive:!0,force:!0})}finally{xg(N,{recursive:!0,force:!0})}if(T){let n=a4(B,".agents","skills","oma-backend","variants","python");if(r9(n))jz(A,{recursive:!0}),MI(n,A,{recursive:!0,force:!0}),f3(a4(A,"stack.yaml"),`language: python
1384
1384
  framework: fastapi
1385
1385
  orm: sqlalchemy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-agent",
3
- "version": "5.20.0",
3
+ "version": "5.20.1",
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": {