oh-my-agent 6.0.0 → 6.0.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
@@ -1382,7 +1382,7 @@ print(json.dumps({
1382
1382
  }))
1383
1383
  `;function YW$(){return process.env.OMA_PYTHON??"python3"}function ZW$($){if(GW$.some((J)=>$===J||$.endsWith(`.${J}`)))return["safari","chrome","firefox"];return["chrome","safari","firefox"]}async function KW$($,J,X){return new Promise((G)=>{let Q=XW$(YW$(),["-c",QW$],{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 UW$($,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 DB0($,J){let X=ZW$($.hostname),G=[],Q=performance.now();for(let K of X){if(J.signal?.aborted)break;let U=performance.now(),W=await KW$($,K,J),H=Math.round(performance.now()-U);if(W.error==="curl_cffi_not_installed")return I6({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=UW$(W,$.toString(),H),B=k4(z);if(q60(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:$9(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{...I6({url:$.toString(),strategy:"impersonate",error:Error(Z?`impersonate_failed: ${Z}`:"impersonate_failed")}),elapsedMs:Y,signals:[]}}var TB0="https://r.jina.ai/";function WW$($){let J=`${$.protocol}//${$.hostname}`,X=$.hostname.startsWith("m.")?$.hostname:`m.${$.hostname.replace(/^www\./,"")}`,G=new URL($.toString());return G.hostname=X,[{label:"jina",url:`${TB0}${$.toString()}`,headers:f3({accept:"text/plain"})},{label:"jina-json",url:`${TB0}${$.toString()}`,headers:f3({accept:"application/json"})},{label:"curl-desktop",url:$.toString(),headers:f3({userAgent:P5.desktopFirefox,referer:J})},{label:"curl-mobile",url:G.toString(),headers:f3({userAgent:P5.mobileSafari,referer:J})},{label:"curl-googlebot",url:$.toString(),headers:f3({userAgent:P5.googlebot})}]}function HW$($,J){if(!$.startsWith("jina"))return J;return J}async function EB0($,J){let X=WW$($),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 S6(U.url,{headers:U.headers,timeoutMs:J.timeoutMs,signal:G.signal,locale:J.locale}),H=k4(W);if(U.label.startsWith("jina")){let z=z60(W);if(z)throw Z=z,Error(`jina-quota:${z.detail}`)}if(!zW$(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:$9(U.resp,U.signals),strategy:"probe",platform:U.label,httpStatus:U.resp.status,content:HW$(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{...I6({url:$.toString(),error:Error(`probe failed — ${H}`),strategy:"probe"}),elapsedMs:W,signals:[Z]};return{...I6({url:$.toString(),error:U instanceof AggregateError?Error(H):U,strategy:"probe"}),elapsedMs:W}}}function zW$($,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 VW$=["api","probe","impersonate","browser","archive"];function qW$($){if($.only?.length)return $.only;let J=VW$.slice();if(!$.includeArchive)J=J.filter((X)=>X!=="archive");if($.skip?.length)J=J.filter((X)=>!$.skip?.includes(X));return J}async function PB0($,J,X){switch($){case"api":return await rL(J,X)??null;case"probe":return EB0(J,X);case"impersonate":return DB0(J,X);case"browser":return RB0(J,X);case"archive":return MW(J,X)}}function Cg($){if($.status==="ok")return!0;if($.status==="auth-required"&&B60($.signals))return!0;return!1}function BW$($){return $.status==="auth-required"||$.status==="invalid-input"||$.status==="not-found"}async function OW$($){let J=Math.floor(Math.random()*500);await new Promise((X)=>setTimeout(X,$+J))}function LW$($){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 wB0($,J,X={}){let G=qW$(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 PB0(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(Cg(W))return W.attempts=Q,W;if(BW$(W))return W.attempts=Q,W;if(X.retryOnRateLimit!==!1&&O60(W.signals)&&!Y.has(U)){Y.add(U),await OW$(LW$(W.signals));let H=await PB0(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}),Cg(H))return H.attempts=Q,H;Z=H;continue}}Z=W}if(!G.includes("archive")&&X.includeArchive!==!1){let U=await MW($,J);if(Q.push({strategy:"archive",platform:U.platform,status:U.status,httpStatus:U.httpStatus,elapsedMs:U.elapsedMs,signals:U.signals,error:U.error}),Cg(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 qO0=l0(zO0(),1);var gH$=["/rss","/feed","/atom.xml","/rss.xml","/index.xml"],mH$=new qO0.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text"});function yg($){if($===void 0||$===null)return[];return Array.isArray($)?$:[$]}function G4($){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 VO0($){for(let J of yg($)){let X=J?.["@_href"],G=J?.["@_rel"];if(typeof X==="string"&&(G===void 0||G==="alternate"))return X}return}function BO0($){let J;try{J=mH$.parse($)}catch{return null}let X=J.rss;if(X){let Q=X.channel;if(!Q)return null;let Y=yg(Q.item);return{kind:"rss",title:G4(Q.title),description:G4(Q.description),link:G4(Q.link),entries:Y.map((Z)=>({title:G4(Z.title),link:G4(Z.link),pubDate:G4(Z.pubDate),description:G4(Z.description),content:G4(Z["content:encoded"])??G4(Z.content)}))}}let G=J.feed;if(G){let Q=yg(G.entry);return{kind:"atom",title:G4(G.title),description:G4(G.subtitle),link:VO0(G.link),entries:Q.map((Y)=>({title:G4(Y.title),link:VO0(Y.link),pubDate:G4(Y.published)??G4(Y.updated),description:G4(Y.summary),content:G4(Y.content)??G4(Y.summary)}))}}return null}async function OO0($,J){let X=performance.now(),G;try{let Y=await S6($.toString(),{timeoutMs:J.timeoutMs,locale:J.locale,signal:J.signal});if(Y.ok)G=sL(Y.text).alternate?.[0]?.href}catch{}let Q=new Set;if(G)try{Q.add(new URL(G,$).toString())}catch{}for(let Y of gH$)Q.add(new URL(Y,`${$.protocol}//${$.host}`).toString());for(let Y of Q){if(J.signal?.aborted)break;try{let Z=await S6(Y,{timeoutMs:J.timeoutMs,locale:J.locale,signal:J.signal});if(!Z.ok||Z.text.length<50)continue;let K=BO0(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 LO0($,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 DI={"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 cH$($){return $.replace(/^www\./,"")}function pH$($){if($ in DI){let X=DI[$];return X?{...X}:null}let J=cH$($);if(J in DI){let X=DI[J];return X?{...X}:null}return null}function lH$($){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 dH$($){try{let J=await S6(`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 FO0($){let J=pH$($);if(J)return J;let X=lH$($);if(X)return X;let G=await dH$($);if(G)return G;return{domain:$,level:"unknown",score:null,tags:[],source:"heuristic"}}var NO0=["api","probe","impersonate","browser","archive"];function MO0($){if(!$)return;let J=$.split(",").map((G)=>G.trim()).filter(Boolean),X=J.filter((G)=>!NO0.includes(G));if(X.length>0)throw Error(`Unknown strategy: ${X.join(", ")}. Valid: ${NO0.join(", ")}`);return J}function GK($){try{return new URL($)}catch{throw Error(`Invalid URL: ${$}`)}}function vX($){return{timeoutMs:$.timeout?Math.max(1000,Math.floor(Number($.timeout)*1000)):15000,locale:$.locale??"en-US,en;q=0.9"}}function d7($,J){if(J)console.log(JSON.stringify($,null,2));else console.log(JSON.stringify($))}function cG($){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 AO0($){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=GK(X),Y=vX(G),Z=await wB0(Q,Y,{only:MO0(G.only),skip:MO0(G.skip),includeArchive:G.includeArchive});d7(Z,Boolean(G.pretty)),cG(Z)}catch(Q){console.error(d5.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=GK(X);if(!wv(Q)){console.error(d5.default.yellow(`No API handler matches host ${Q.hostname}`)),process.exitCode=3;return}let Z=vX(G),K=await rL(Q,Z);if(!K){process.exitCode=3;return}d7(K,Boolean(G.pretty)),cG(K)}catch(Q){console.error(d5.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=vX(G),Y=G.platforms?G.platforms.split(",").map((K)=>K.trim()).filter(Boolean):void 0,Z=await k60(X,Q,Y);d7(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=GK(X),Y=vX(G),Z=await H60(Q,Y),{content:K,...U}=Z;d7(U,Boolean(G.pretty)),cG(Z)}catch(Q){console.error(d5.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=GK(X),Y=vX(G),Z=await OO0(Q,Y),{content:K,...U}=Z;d7(U,Boolean(G.pretty)),cG(Z)}catch(Q){console.error(d5.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=LO0(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=GK(X),Y=vX(G),Z=G.subLang?G.subLang.split(",").map((U)=>U.trim()).filter(Boolean):void 0,K=await U60(Q,Y,{subtitles:G.subs,...Z?{subLangs:Z}:{},...G.format?{format:G.format}:{}});d7(K,Boolean(G.pretty)),cG(K)}catch(Q){console.error(d5.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=GK(X),Y=vX(G),Z=await MW(Q,Y);d7(Z,Boolean(G.pretty)),cG(Z)}catch(Q){console.error(d5.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 FO0(X.toLowerCase());d7(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=vX({}),Z=await K60(X,Y,{host:Q,...G.language?{language:G.language}:{},...G.repo?{repo:G.repo}:{},...G.limit?{limit:Number.parseInt(G.limit,10)}:{}});d7(Z,Boolean(G.pretty)),cG(Z)}),J.command("doctor").description("Check dependencies (Chrome, python3 curl_cffi, yt-dlp, gh)").action(async()=>{let X=[],G=jg();X.push({name:"chrome",ok:Boolean(G),detail:G??"Install Chrome or set OMA_CHROME_PATH"}),X.push(await hg("python3",["--version"])),X.push(await iH$()),X.push(await hg("yt-dlp",["--version"])),X.push(await hg("gh",["--version"]));for(let Q of X){let Y=Q.ok?d5.default.green("✓"):d5.default.yellow("!");console.log(`${Y} ${Q.name}: ${Q.detail}`)}if(X.some((Q)=>!Q.ok))process.exitCode=1})}async function hg($,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 iH$(){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)"})})})}e4();var bX=l0(A1(),1);import{execSync as nH$,spawnSync as IO0}from"node:child_process";import{platform as oH$}from"node:os";function aH$(){let $=oH$();if($==="darwin")return"brew install gh";if($==="win32")return"winget install GitHub.cli";return"sudo apt install gh"}async function RO0(){if(console.clear(),w1(bX.default.bgMagenta(bX.default.white(" ⭐ oh-my-agent star "))),!U3()){let J=aH$(),X=await U4({message:`GitHub CLI (gh) is not installed. Install with ${bX.default.cyan(J)}?`});if(U1(X)||!X){L$("Install gh manually and try again.");return}let G=i8();G.start("Installing GitHub CLI...");let Q=IO0(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(!M5()){o$.warn("GitHub CLI is not authenticated.");let J=await U4({message:`Run ${bX.default.cyan("gh auth login")} now?`});if(U1(J)||!J){L$("Authenticate and try again.");return}if(IO0("gh",["auth","login"],{stdio:"inherit"}),!M5()){L$("Authentication was not completed. Try again.");return}o$.success("Authenticated!")}if(W3()){L$(`Already starred ${bX.default.cyan(g1)}! Thank you! \uD83D\uDE4F`);return}let $=await U4({message:`Star ${bX.default.cyan(g1)} on GitHub?`});if(U1($)||!$){L$("Maybe next time!");return}try{nH$(`gh api -X PUT /user/starred/${g1}`,{stdio:"ignore"}),L$(`Starred ${bX.default.cyan(g1)}! Thank you! \uD83C\uDF1F`)}catch{o$.error("Failed to star the repository."),L$("Please try again later.")}}function DO0($){$.command("star").description("Star oh-my-agent on GitHub").action(N$(async()=>{await RO0()}))}e4();Av();FU();var $5=l0(A1(),1);import{existsSync as TI,mkdirSync as sH$,readdirSync as rH$,readFileSync as tH$,writeFileSync as TO0}from"node:fs";import{dirname as eH$,join as EO0}from"node:path";function ug($){return EO0($,".serena","metrics.json")}function fg(){return{sessions:0,skillsUsed:{},tasksCompleted:0,totalSessionTime:0,filesChanged:0,linesAdded:0,linesRemoved:0,lastUpdated:new Date().toISOString(),startDate:new Date().toISOString()}}function $z$($){let J=ug($);if(TI(J))try{return JSON.parse(tH$(J,"utf-8"))}catch{return fg()}return fg()}function Jz$($,J){let X=ug($),G=eH$(X);if(!TI(G))sH$(G,{recursive:!0});J.lastUpdated=new Date().toISOString(),TO0(X,JSON.stringify(J,null,2),"utf-8")}function Xz$($){let J=EO0($,".serena","memories"),X={};if(!TI(J))return X;try{let G=rH$(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 PO0($=!1,J=!1){let X=process.cwd(),G=ug(X);if(J){if(TI(G))TO0(G,JSON.stringify(fg(),null,2),"utf-8");if($)console.log(JSON.stringify({reset:!0}));else console.log($5.default.green("✅ Metrics reset successfully."));return}let Q=$z$(X),Y=nL(X),Z=Xz$(X),K=Zi(X),U=TB(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,Jz$(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($5.default.bgMagenta($5.default.white(" \uD83D\uDCCA oh-my-agent stats ")));let V=[$5.default.bold(`\uD83D\uDCC8 Productivity Metrics (${z} days)`),"┌─────────────────────┬──────────────┐",`│ ${$5.default.bold("Metric")} │ ${$5.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 │ ${$5.default.green(`+${Q.linesAdded}`).padEnd(12)} │`,`│ Lines Removed │ ${$5.default.red(`-${Q.linesRemoved}`).padEnd(12)} │`,"└─────────────────────┴──────────────┘"].join(`
1384
1384
  `);i0(V,"Overview");let q=Object.entries(Q.skillsUsed).sort(([,O],[,L])=>L-O).slice(0,5);if(q.length>0){let O=[$5.default.bold("\uD83C\uDFC6 Top Skills Used"),...q.map(([L,F],N)=>` ${N+1}. ${L} (${F})`)].join(`
1385
- `);i0(O,"Skills")}L$($5.default.dim(`Data stored in: ${G}`))}function wO0($){L6($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(N$(async(J)=>{await PO0(G6(J),J.reset)},{supportsJsonOutput:!0}))}e4();var D4=l0(A1(),1);import{execSync as Wz$}from"node:child_process";import{cpSync as wI,existsSync as J5,mkdirSync as kz,readFileSync as QK,rmSync as gg,writeFileSync as lG}from"node:fs";import{tmpdir as Hz$}from"node:os";import{dirname as _O0,join as a6}from"node:path";var EI=l0(A1(),1);import{execSync as Gz$,spawn as Qz$}from"node:child_process";import{realpathSync as jO0}from"node:fs";import bz from"node:process";var pG="oh-my-agent";function Yz$($=bz.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(bz.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=jO0($).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(bz.platform==="darwin")try{let X=Gz$(`brew --prefix ${pG}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(X){let G=jO0(X).replace(/\\/g,"/");if(J.startsWith(G))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${pG}`,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 ${pG}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(J.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${pG}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(J.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${pG}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${pG}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var CO0=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function Zz$($,J){let X=$.match(CO0),G=J.match(CO0);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 Kz$($=pG,J=2000){try{let X=await DY.get(`https://registry.npmjs.org/${$}/latest`,{timeout:J});return typeof X.data?.version==="string"?X.data.version:null}catch{return null}}async function SO0($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(bz.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(bz.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let J=await Kz$();if(!J)return{triggered:!1,reason:"fetch-failed"};if(!Zz$($.currentVersion,J))return{triggered:!1,reason:"up-to-date",latest:J};let X=Yz$();if(!X.updateCommand)return $.onNotice?.(EI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. ${X.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:J};try{return Qz$(X.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(EI.default.cyan(`global oh-my-agent ${$.currentVersion} → ${J} updating in background. New version applies on next run.`)),{triggered:!0,latest:J}}catch{return $.onNotice?.(EI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. Run: ${X.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:J}}}var PI={name:"oh-my-agent",version:"6.0.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 zz$($){if(!$)return{intro:(X)=>w1(X),outro:(X)=>L$(X),note:(X,G)=>i0(X,G),logError:(X)=>o$.error(X),spinnerStart:(X)=>{let G=i8();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 Vz$($,J){if($!==null)return"ready";return J?"legacy":"missing"}async function mg($=!1,J=!1){if(!J&&process.stdout.isTTY)console.clear();let X=zz$(J);X.intro(D4.default.bgMagenta(D4.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let G=process.cwd();await SO0({currentVersion:PI.version,enabled:y$0(G),onSpawnStart:(H)=>X.note(H,"CLI auto-update"),onNotice:(H)=>X.note(H,"CLI update available")});let Q=await CO(G),Y=It(G),Z=Vz$(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=E3(G);if(K.length>0)X.note(K.map((H)=>`${D4.default.green("✓")} ${H}`).join(`
1385
+ `);i0(O,"Skills")}L$($5.default.dim(`Data stored in: ${G}`))}function wO0($){L6($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(N$(async(J)=>{await PO0(G6(J),J.reset)},{supportsJsonOutput:!0}))}e4();var D4=l0(A1(),1);import{execSync as Wz$}from"node:child_process";import{cpSync as wI,existsSync as J5,mkdirSync as kz,readFileSync as QK,rmSync as gg,writeFileSync as lG}from"node:fs";import{tmpdir as Hz$}from"node:os";import{dirname as _O0,join as a6}from"node:path";var EI=l0(A1(),1);import{execSync as Gz$,spawn as Qz$}from"node:child_process";import{realpathSync as jO0}from"node:fs";import bz from"node:process";var pG="oh-my-agent";function Yz$($=bz.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(bz.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=jO0($).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(bz.platform==="darwin")try{let X=Gz$(`brew --prefix ${pG}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(X){let G=jO0(X).replace(/\\/g,"/");if(J.startsWith(G))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${pG}`,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 ${pG}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(J.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${pG}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(J.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${pG}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${pG}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var CO0=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function Zz$($,J){let X=$.match(CO0),G=J.match(CO0);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 Kz$($=pG,J=2000){try{let X=await DY.get(`https://registry.npmjs.org/${$}/latest`,{timeout:J});return typeof X.data?.version==="string"?X.data.version:null}catch{return null}}async function SO0($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(bz.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(bz.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let J=await Kz$();if(!J)return{triggered:!1,reason:"fetch-failed"};if(!Zz$($.currentVersion,J))return{triggered:!1,reason:"up-to-date",latest:J};let X=Yz$();if(!X.updateCommand)return $.onNotice?.(EI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. ${X.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:J};try{return Qz$(X.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(EI.default.cyan(`global oh-my-agent ${$.currentVersion} → ${J} updating in background. New version applies on next run.`)),{triggered:!0,latest:J}}catch{return $.onNotice?.(EI.default.yellow(`global oh-my-agent ${$.currentVersion} → ${J} available. Run: ${X.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:J}}}var PI={name:"oh-my-agent",version:"6.0.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 zz$($){if(!$)return{intro:(X)=>w1(X),outro:(X)=>L$(X),note:(X,G)=>i0(X,G),logError:(X)=>o$.error(X),spinnerStart:(X)=>{let G=i8();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 Vz$($,J){if($!==null)return"ready";return J?"legacy":"missing"}async function mg($=!1,J=!1){if(!J&&process.stdout.isTTY)console.clear();let X=zz$(J);X.intro(D4.default.bgMagenta(D4.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let G=process.cwd();await SO0({currentVersion:PI.version,enabled:y$0(G),onSpawnStart:(H)=>X.note(H,"CLI auto-update"),onNotice:(H)=>X.note(H,"CLI update available")});let Q=await CO(G),Y=It(G),Z=Vz$(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=E3(G);if(K.length>0)X.note(K.map((H)=>`${D4.default.green("✓")} ${H}`).join(`
1386
1386
  `),"Migration");let U=K.length>0||W_(G);if(K.length>0&&!W_(G))H_(G,!0);if(!J)await sB(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 Rt();if(Q===H.version&&!U){W.stop(D4.default.green("Already up to date!")),X.outro(`Current version: ${D4.default.cyan(Q)}`);return}let z=Q===H.version;W.message(`Downloading ${D4.default.cyan(H.version)}...`);let{dir:B,cleanup:V}=await jO();try{W.message("Copying files..."),E3(G);let q=a6(G,".agents","oma-config.yaml"),O=a6(G,".agents","mcp.json"),L=!$&&J5(q)?QK(q):null,F=!$&&J5(O)?QK(O):null,N=a6(Hz$(),`oma-stack-backup-${Date.now()}`),M=a6(G,".agents","skills","oma-backend","stack"),I=!$&&J5(M);if(I)kz(N,{recursive:!0}),wI(M,a6(N,"oma-backend"),{recursive:!0});let D=["snippets.md","tech-stack.md","api-template.py"],w=a6(G,".agents","skills","oma-backend","resources"),T=!$&&!I&&D.some((o)=>J5(a6(w,o)));if(wI(a6(B,".agents"),a6(G,".agents"),{recursive:!0,force:!0}),L)lG(q,L);if(F)lG(O,F);if(I)try{kz(M,{recursive:!0}),wI(a6(N,"oma-backend"),M,{recursive:!0,force:!0})}finally{gg(N,{recursive:!0,force:!0})}if(T){let o=a6(B,".agents","skills","oma-backend","variants","python");if(J5(o))kz(M,{recursive:!0}),wI(o,M,{recursive:!0,force:!0}),lG(a6(M,"stack.yaml"),`language: python
1387
1387
  framework: fastapi
1388
1388
  orm: sqlalchemy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-agent",
3
- "version": "6.0.0",
3
+ "version": "6.0.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": {