oh-my-agent 2.11.0 → 2.11.2

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 +2 -2
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -332,7 +332,7 @@ languages:
332
332
  ${D}`,initialValue:!0});if(N$(G)||!G)return{shouldCleanupBrain:!1,shouldCleanupImplicit:!1,shouldCleanupKnowledge:!1};return{shouldCleanupBrain:z,shouldCleanupImplicit:N,shouldCleanupKnowledge:J}}async function HQ($=!1,u=!1,g=!1){let U=process.cwd(),I=i$(U,".agents","results"),_=eA(),v={cleaned:0,skipped:0,details:[]},z=await sA(U,u,g),N=(T)=>{v.details.push($?`[DRY-RUN] ${T}`:`[CLEAN] ${T}`),v.cleaned++},J=(T)=>{v.details.push(`[SKIP] ${T}`),v.skipped++},D=(T)=>{if($)return;try{OQ(T,{force:!0})}catch{}},G=(T)=>{try{return process.kill(T,0),!0}catch{return!1}},X=async(T)=>{if($)return;try{process.kill(T)}catch{}await new Promise((q)=>setTimeout(q,1000));try{if(G(T))process.kill(T,"SIGKILL")}catch{}};try{let T=yI(_).filter((q)=>q.startsWith("subagent-")&&q.endsWith(".pid"));for(let q of T){let O=i$(_,q),H=h8(O,"utf-8").trim();if(!H){N(`Removing empty PID file: ${O}`),D(O);continue}let M=parseInt(H,10);if(Number.isNaN(M)){N(`Removing invalid PID file: ${O}`),D(O);continue}if(G(M))N(`Killing orphaned process PID=${M} (from ${O})`),await X(M),D(O);else N(`Removing stale PID file (process gone): ${O}`),D(O)}}catch{}try{let T=yI(_).filter((q)=>q.startsWith("subagent-")&&q.endsWith(".log"));for(let q of T){let O=i$(_,q),H=q.replace(".log",".pid"),M=i$(_,H);if(xu(M))try{let B=h8(M,"utf-8").trim(),L=parseInt(B,10);if(!Number.isNaN(L)){if(G(L)){J(`Log file has active process: ${O}`);continue}}}catch{}N(`Removing stale log file: ${O}`),D(O)}}catch{}if(xu(I))try{let T=yI(I).filter((q)=>q.startsWith("parallel-"));for(let q of T){let O=i$(I,q,"pids.txt");if(!xu(O))continue;let M=h8(O,"utf-8").split(`
333
333
  `).filter((L)=>L.trim()),B=!1;for(let L of M){let[R,K]=L.split(":"),Y=parseInt(R?.trim()||"",10);if(Number.isNaN(Y))continue;if(G(Y))B=!0,N(`Killing orphaned parallel agent PID=${Y} (${K?.trim()||"unknown"})`),await X(Y),D(O)}if(!B)N(`Removing stale PID list: ${O}`),D(O);else if(!$){await new Promise((L)=>setTimeout(L,1000));try{OQ(O,{force:!0})}catch{}}}}catch{}else J(`No results directory found: ${I}`);if(z.shouldCleanupBrain||z.shouldCleanupImplicit||z.shouldCleanupKnowledge){let T=i$(U,".gemini","antigravity");if(z.shouldCleanupBrain){let q=i$(T,"brain");try{if(xu(q)){let O=yI(q);for(let H of O){let M=i$(q,H);N(`Removing brain file: ${M}`),D(M)}}}catch{}}if(z.shouldCleanupImplicit){let q=i$(T,"implicit");try{if(xu(q)){let O=yI(q);for(let H of O){let M=i$(q,H);N(`Removing implicit file: ${M}`),D(M)}}}catch{}}if(z.shouldCleanupKnowledge){let q=i$(T,"knowledge");try{if(xu(q)){let O=yI(q);for(let H of O){let M=i$(q,H);N(`Removing knowledge file: ${M}`),D(M)}}}catch{}}}if(u){console.log(JSON.stringify(v,null,2));return}if(console.clear(),H$(o$.default.bgMagenta(o$.default.white(" \uD83E\uDDF9 oh-my-agent cleanup "))),$)f(o$.default.yellow("Dry-run mode — no changes will be made"),"Mode");if(v.details.length>0){let T=[o$.default.bold("Cleanup Details"),...v.details.map((q)=>{if(q.startsWith("[DRY-RUN]"))return o$.default.yellow(q);if(q.startsWith("[CLEAN]"))return o$.default.green(q);return o$.default.cyan(q)})].join(`
334
334
  `);f(T,"Details")}let Q=[o$.default.bold("Summary"),"┌─────────┬────────┐",`│ ${o$.default.bold("Action")} │ ${o$.default.bold("Count")} │`,"├─────────┼────────┤",`│ Cleaned │ ${String(v.cleaned).padEnd(6)} │`,`│ Skipped │ ${String(v.skipped).padEnd(6)} │`,"└─────────┴────────┘"].join(`
335
- `);if(f(Q,"Results"),$)c(o$.default.yellow("Run without --dry-run to apply changes"));else c(o$.default.green("Cleanup complete!"))}vu();var l=Q$(A$(),1);import{execSync as a8}from"node:child_process";import{existsSync as cI,readdirSync as jQ,readFileSync as UZ}from"node:fs";import{join as P6}from"node:path";import{execSync as o8}from"node:child_process";import{cpSync as ku,existsSync as l$,lstatSync as YQ,mkdirSync as yu,readdirSync as d8,readlinkSync as $Z,symlinkSync as uZ,unlinkSync as MQ}from"node:fs";import{dirname as IZ,join as J$,relative as gZ,resolve as c8}from"node:path";var Xu="first-fluke/oh-my-agent",qu=".agents/skills",Au={domain:[{name:"frontend-agent",desc:"React/Next.js UI specialist"},{name:"backend-agent",desc:"FastAPI/SQLAlchemy API specialist"},{name:"db-agent",desc:"SQL/NoSQL data modeling, normalization, integrity, and capacity specialist"},{name:"mobile-agent",desc:"Flutter/Dart mobile specialist"}],coordination:[{name:"brainstorm",desc:"Design-first ideation before planning"},{name:"pm-agent",desc:"Product manager - task decomposition"},{name:"qa-agent",desc:"QA - OWASP, Lighthouse, WCAG"},{name:"workflow-guide",desc:"Manual multi-agent orchestration"},{name:"orchestrator",desc:"Automated parallel CLI execution"}],utility:[{name:"debug-agent",desc:"Bug fixing specialist"},{name:"commit",desc:"Conventional Commits helper"}],infrastructure:[{name:"tf-infra-agent",desc:"Multi-cloud infrastructure with Terraform - AWS, GCP, Azure, OCI support"},{name:"dev-workflow",desc:"Monorepo developer workflows - mise tasks, git hooks, CI/CD, release automation"}]},SQ={fullstack:["brainstorm","frontend-agent","backend-agent","db-agent","pm-agent","qa-agent","debug-agent","commit","tf-infra-agent","dev-workflow"],frontend:["brainstorm","frontend-agent","pm-agent","qa-agent","debug-agent","commit"],backend:["brainstorm","backend-agent","db-agent","pm-agent","qa-agent","debug-agent","commit","dev-workflow"],mobile:["brainstorm","mobile-agent","pm-agent","qa-agent","debug-agent","commit"],devops:["brainstorm","tf-infra-agent","dev-workflow","pm-agent","qa-agent","debug-agent","commit"],all:[...Au.domain,...Au.coordination,...Au.utility,...Au.infrastructure].map(($)=>$.name)};function mI($){try{if(!YQ($).isDirectory())MQ($)}catch{}}function MU($,u,g){let U=J$($,".agents","skills",u);if(!l$(U))return!1;let I=J$(g,qu,u);return mI(I),yu(I,{recursive:!0}),ku(U,I,{recursive:!0,force:!0}),!0}function SU($,u){let g=J$($,".agents","skills","_shared");if(!l$(g))return;let U=J$(u,qu,"_shared");mI(U),yu(U,{recursive:!0}),ku(g,U,{recursive:!0,force:!0})}function VQ($,u){let g=J$($,".agents","workflows");if(!l$(g))return;let U=J$(u,".agents","workflows");mI(U),yu(U,{recursive:!0}),ku(g,U,{recursive:!0,force:!0})}function LQ($,u,g=!1){let U=J$($,".agents","config");if(l$(U)){let _=J$(u,".agents","config");if(yu(_,{recursive:!0}),g)ku(U,_,{recursive:!0,force:!0});else for(let v of d8(U,{withFileTypes:!0})){let z=J$(_,v.name);if(!l$(z))ku(J$(U,v.name),z,v.isDirectory()?{recursive:!0}:{})}}let I=J$($,".agents","mcp.json");if(l$(I)){let _=J$(u,".agents");yu(_,{recursive:!0});let v=J$(_,"mcp.json");if(g||!l$(v))ku(I,v)}}function RQ($){let u=process.env.HOME||process.env.USERPROFILE||"",g=J$(u,".gemini","antigravity","global_workflows"),U=J$($,".agents","workflows");if(!l$(U))return;yu(g,{recursive:!0}),ku(U,g,{recursive:!0,force:!0})}function VU($,u){let g=J$($,".claude","skills"),U=J$($,".claude","agents"),I=J$(u,".claude","skills"),_=J$(u,".claude","agents");if(l$(g))mI(I),PQ(g,I),yu(I,{recursive:!0}),ku(g,I,{recursive:!0,force:!0});if(l$(U))mI(_),PQ(U,_),yu(_,{recursive:!0}),ku(U,_,{recursive:!0,force:!0})}function PQ($,u){if(!l$(u))return;try{for(let g of d8($,{withFileTypes:!0}))if(g.isDirectory())mI(J$(u,g.name))}catch{}}function hI(){return[...Au.domain,...Au.coordination,...Au.utility,...Au.infrastructure]}var BQ={claude:".claude/skills",copilot:".github/skills"};function LU($,u,g){let U=[],I=[],_=c8($,qu);for(let v of u){let z=BQ[v],N=J$($,z);if(!l$(N))yu(N,{recursive:!0});for(let J of g){let D=J$(_,J),G=J$(N,J);if(!l$(D)){I.push(`${z}/${J} (source missing)`);continue}try{if(YQ(G).isSymbolicLink()){if(c8(IZ(G),$Z(G))===c8(D)){I.push(`${z}/${J} (already linked)`);continue}MQ(G)}else{I.push(`${z}/${J} (real dir exists)`);continue}}catch(Q){}let X=gZ(N,D);uZ(X,G,"dir"),U.push(`${z}/${J}`)}}return{created:U,skipped:I}}function bQ($){let u=J$($,qu);if(!l$(u))return[];return d8(u,{withFileTypes:!0}).filter((g)=>g.isDirectory()&&!g.name.startsWith("_")).map((g)=>g.name)}function KQ($){let u=[];for(let[g,U]of Object.entries(BQ))if(l$(J$($,U)))u.push(g);return u}function p8(){try{return o8("gh --version",{stdio:"ignore"}),!0}catch{return!1}}function RU(){try{return o8("gh auth status",{stdio:"ignore"}),!0}catch{return!1}}function t8(){try{return o8(`gh api user/starred/${Xu}`,{stdio:"ignore"}),!0}catch{return!1}}function BU(){return p8()&&RU()&&t8()}async function bU($,u,g){try{let U=a8(`${u} --version`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim();return{name:$,installed:!0,version:U,installCmd:g}}catch{return{name:$,installed:!1,installCmd:g}}}async function _Z($){let u=process.env.HOME||process.env.USERPROFILE||"",U={gemini:{path:`${u}/.gemini/settings.json`,type:"json"},claude:{path:`${u}/.claude.json`,type:"json"},codex:{path:`${u}/.codex/config.toml`,type:"toml"}}[$];if(!U)return{configured:!1};if(cI(U.path))try{let I=UZ(U.path,"utf-8");if(U.type==="json"){let _=JSON.parse(I);return{configured:!!(_.mcpServers||_.mcp),path:U.path}}return{configured:!0,path:U.path}}catch{return{configured:!1}}return{configured:!1}}async function vZ(){let $=P6(process.cwd(),qu);if(!cI($))return[];let u=hI(),g=[];for(let U of u){let I=P6($,U.name),_=P6(I,"SKILL.md");g.push({name:U.name,installed:cI(I),hasSkillMd:cI(_)})}return g}async function zZ(){let $=process.env.HOME||process.env.USERPROFILE||"",u=P6($,".gemini","antigravity","global_workflows");if(!cI(u))return{installed:!1,count:0};try{return{installed:!0,count:jQ(u).filter((U)=>U.endsWith(".md")).length}}catch{return{installed:!1,count:0}}}async function WQ($=!1){let u=process.cwd(),g=await Promise.all([bU("gemini","gemini","bun install --global @google/gemini-cli"),bU("claude","claude","bun install --global @anthropic-ai/claude-code"),bU("codex","codex","bun install --global @openai/codex"),bU("qwen","qwen","bun install --global @qwen-code/qwen-code")]),U=await Promise.all(g.filter((T)=>T.installed).map(async(T)=>{let q=await _Z(T.name);return{...T,mcp:q}})),I=await vZ(),_=await zZ(),v=!1;try{v=a8("git config --get rerere.enabled",{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()==="true"}catch{}let z=P6(u,".serena","memories"),N=cI(z),J=0;if(N)try{J=jQ(z).length}catch{}let D=g.filter((T)=>!T.installed),G=I.length>0?I.filter((T)=>!T.installed||!T.hasSkillMd):hI().map((T)=>({name:T.name,installed:!1,hasSkillMd:!1})),X=D.length+G.length+(_.installed?0:1)+(v?0:1);if($){let T={ok:X===0,issues:X,clis:g.map((q)=>({name:q.name,installed:q.installed,version:q.version||null})),mcp:U.map((q)=>({name:q.name,configured:q.mcp.configured,path:q.mcp.path||null})),skills:I.length>0?I.map((q)=>({name:q.name,installed:q.installed,complete:q.hasSkillMd})):[],missingSkills:G.map((q)=>q.name),globalWorkflows:{installed:_.installed,count:_.count},serena:{exists:N,fileCount:J},gitRerere:{enabled:v}};console.log(JSON.stringify(T,null,2)),process.exit(X===0?0:1)}console.clear(),H$(l.default.bgMagenta(l.default.white(" \uD83E\uDE7A oh-my-agent doctor ")));let Q=_u();try{let T=[l.default.bold("\uD83D\uDD0D CLI Installation Status"),"┌─────────┬──────────┬─────────────┐",`│ ${l.default.bold("CLI")} │ ${l.default.bold("Status")} │ ${l.default.bold("Version")} │`,"├─────────┼──────────┼─────────────┤",...g.map((H)=>{let M=H.installed?l.default.green("✅ Installed"):l.default.red("❌ Missing"),B=H.version||"-";return`│ ${H.name.padEnd(7)} │ ${M.padEnd(8)} │ ${B.padEnd(11)} │`}),"└─────────┴──────────┴─────────────┘"].join(`
335
+ `);if(f(Q,"Results"),$)c(o$.default.yellow("Run without --dry-run to apply changes"));else c(o$.default.green("Cleanup complete!"))}vu();var l=Q$(A$(),1);import{execSync as a8}from"node:child_process";import{existsSync as cI,readdirSync as jQ,readFileSync as UZ}from"node:fs";import{join as P6}from"node:path";import{execSync as o8}from"node:child_process";import{cpSync as ku,existsSync as l$,lstatSync as YQ,mkdirSync as yu,readdirSync as d8,readlinkSync as $Z,symlinkSync as uZ,unlinkSync as MQ}from"node:fs";import{dirname as IZ,join as J$,relative as gZ,resolve as c8}from"node:path";var Xu="first-fluke/oh-my-agent",qu=".agents/skills",Au={domain:[{name:"frontend-agent",desc:"React/Next.js UI specialist"},{name:"backend-agent",desc:"FastAPI/SQLAlchemy API specialist"},{name:"db-agent",desc:"SQL/NoSQL data modeling, normalization, integrity, and capacity specialist"},{name:"mobile-agent",desc:"Flutter/Dart mobile specialist"}],coordination:[{name:"brainstorm",desc:"Design-first ideation before planning"},{name:"pm-agent",desc:"Product manager - task decomposition"},{name:"qa-agent",desc:"QA - OWASP, Lighthouse, WCAG"},{name:"workflow-guide",desc:"Manual multi-agent orchestration"},{name:"orchestrator",desc:"Automated parallel CLI execution"}],utility:[{name:"debug-agent",desc:"Bug fixing specialist"},{name:"commit",desc:"Conventional Commits helper"},{name:"translator",desc:"Context-aware multilingual translation"}],infrastructure:[{name:"tf-infra-agent",desc:"Multi-cloud infrastructure with Terraform - AWS, GCP, Azure, OCI support"},{name:"dev-workflow",desc:"Monorepo developer workflows - mise tasks, git hooks, CI/CD, release automation"}]},SQ={fullstack:["brainstorm","frontend-agent","backend-agent","db-agent","pm-agent","qa-agent","debug-agent","commit","tf-infra-agent","dev-workflow"],frontend:["brainstorm","frontend-agent","pm-agent","qa-agent","debug-agent","commit"],backend:["brainstorm","backend-agent","db-agent","pm-agent","qa-agent","debug-agent","commit","dev-workflow"],mobile:["brainstorm","mobile-agent","pm-agent","qa-agent","debug-agent","commit"],devops:["brainstorm","tf-infra-agent","dev-workflow","pm-agent","qa-agent","debug-agent","commit"],all:[...Au.domain,...Au.coordination,...Au.utility,...Au.infrastructure].map(($)=>$.name)};function mI($){try{if(!YQ($).isDirectory())MQ($)}catch{}}function MU($,u,g){let U=J$($,".agents","skills",u);if(!l$(U))return!1;let I=J$(g,qu,u);return mI(I),yu(I,{recursive:!0}),ku(U,I,{recursive:!0,force:!0}),!0}function SU($,u){let g=J$($,".agents","skills","_shared");if(!l$(g))return;let U=J$(u,qu,"_shared");mI(U),yu(U,{recursive:!0}),ku(g,U,{recursive:!0,force:!0})}function VQ($,u){let g=J$($,".agents","workflows");if(!l$(g))return;let U=J$(u,".agents","workflows");mI(U),yu(U,{recursive:!0}),ku(g,U,{recursive:!0,force:!0})}function LQ($,u,g=!1){let U=J$($,".agents","config");if(l$(U)){let _=J$(u,".agents","config");if(yu(_,{recursive:!0}),g)ku(U,_,{recursive:!0,force:!0});else for(let v of d8(U,{withFileTypes:!0})){let z=J$(_,v.name);if(!l$(z))ku(J$(U,v.name),z,v.isDirectory()?{recursive:!0}:{})}}let I=J$($,".agents","mcp.json");if(l$(I)){let _=J$(u,".agents");yu(_,{recursive:!0});let v=J$(_,"mcp.json");if(g||!l$(v))ku(I,v)}}function RQ($){let u=process.env.HOME||process.env.USERPROFILE||"",g=J$(u,".gemini","antigravity","global_workflows"),U=J$($,".agents","workflows");if(!l$(U))return;yu(g,{recursive:!0}),ku(U,g,{recursive:!0,force:!0})}function VU($,u){let g=J$($,".claude","skills"),U=J$($,".claude","agents"),I=J$(u,".claude","skills"),_=J$(u,".claude","agents");if(l$(g))mI(I),PQ(g,I),yu(I,{recursive:!0}),ku(g,I,{recursive:!0,force:!0});if(l$(U))mI(_),PQ(U,_),yu(_,{recursive:!0}),ku(U,_,{recursive:!0,force:!0})}function PQ($,u){if(!l$(u))return;try{for(let g of d8($,{withFileTypes:!0}))if(g.isDirectory())mI(J$(u,g.name))}catch{}}function hI(){return[...Au.domain,...Au.coordination,...Au.utility,...Au.infrastructure]}var BQ={claude:".claude/skills",copilot:".github/skills"};function LU($,u,g){let U=[],I=[],_=c8($,qu);for(let v of u){let z=BQ[v],N=J$($,z);if(!l$(N))yu(N,{recursive:!0});for(let J of g){let D=J$(_,J),G=J$(N,J);if(!l$(D)){I.push(`${z}/${J} (source missing)`);continue}try{if(YQ(G).isSymbolicLink()){if(c8(IZ(G),$Z(G))===c8(D)){I.push(`${z}/${J} (already linked)`);continue}MQ(G)}else{I.push(`${z}/${J} (real dir exists)`);continue}}catch(Q){}let X=gZ(N,D);uZ(X,G,"dir"),U.push(`${z}/${J}`)}}return{created:U,skipped:I}}function bQ($){let u=J$($,qu);if(!l$(u))return[];return d8(u,{withFileTypes:!0}).filter((g)=>g.isDirectory()&&!g.name.startsWith("_")).map((g)=>g.name)}function KQ($){let u=[];for(let[g,U]of Object.entries(BQ))if(l$(J$($,U)))u.push(g);return u}function p8(){try{return o8("gh --version",{stdio:"ignore"}),!0}catch{return!1}}function RU(){try{return o8("gh auth status",{stdio:"ignore"}),!0}catch{return!1}}function t8(){try{return o8(`gh api user/starred/${Xu}`,{stdio:"ignore"}),!0}catch{return!1}}function BU(){return p8()&&RU()&&t8()}async function bU($,u,g){try{let U=a8(`${u} --version`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim();return{name:$,installed:!0,version:U,installCmd:g}}catch{return{name:$,installed:!1,installCmd:g}}}async function _Z($){let u=process.env.HOME||process.env.USERPROFILE||"",U={gemini:{path:`${u}/.gemini/settings.json`,type:"json"},claude:{path:`${u}/.claude.json`,type:"json"},codex:{path:`${u}/.codex/config.toml`,type:"toml"}}[$];if(!U)return{configured:!1};if(cI(U.path))try{let I=UZ(U.path,"utf-8");if(U.type==="json"){let _=JSON.parse(I);return{configured:!!(_.mcpServers||_.mcp),path:U.path}}return{configured:!0,path:U.path}}catch{return{configured:!1}}return{configured:!1}}async function vZ(){let $=P6(process.cwd(),qu);if(!cI($))return[];let u=hI(),g=[];for(let U of u){let I=P6($,U.name),_=P6(I,"SKILL.md");g.push({name:U.name,installed:cI(I),hasSkillMd:cI(_)})}return g}async function zZ(){let $=process.env.HOME||process.env.USERPROFILE||"",u=P6($,".gemini","antigravity","global_workflows");if(!cI(u))return{installed:!1,count:0};try{return{installed:!0,count:jQ(u).filter((U)=>U.endsWith(".md")).length}}catch{return{installed:!1,count:0}}}async function WQ($=!1){let u=process.cwd(),g=await Promise.all([bU("gemini","gemini","bun install --global @google/gemini-cli"),bU("claude","claude","bun install --global @anthropic-ai/claude-code"),bU("codex","codex","bun install --global @openai/codex"),bU("qwen","qwen","bun install --global @qwen-code/qwen-code")]),U=await Promise.all(g.filter((T)=>T.installed).map(async(T)=>{let q=await _Z(T.name);return{...T,mcp:q}})),I=await vZ(),_=await zZ(),v=!1;try{v=a8("git config --get rerere.enabled",{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()==="true"}catch{}let z=P6(u,".serena","memories"),N=cI(z),J=0;if(N)try{J=jQ(z).length}catch{}let D=g.filter((T)=>!T.installed),G=I.length>0?I.filter((T)=>!T.installed||!T.hasSkillMd):hI().map((T)=>({name:T.name,installed:!1,hasSkillMd:!1})),X=D.length+G.length+(_.installed?0:1)+(v?0:1);if($){let T={ok:X===0,issues:X,clis:g.map((q)=>({name:q.name,installed:q.installed,version:q.version||null})),mcp:U.map((q)=>({name:q.name,configured:q.mcp.configured,path:q.mcp.path||null})),skills:I.length>0?I.map((q)=>({name:q.name,installed:q.installed,complete:q.hasSkillMd})):[],missingSkills:G.map((q)=>q.name),globalWorkflows:{installed:_.installed,count:_.count},serena:{exists:N,fileCount:J},gitRerere:{enabled:v}};console.log(JSON.stringify(T,null,2)),process.exit(X===0?0:1)}console.clear(),H$(l.default.bgMagenta(l.default.white(" \uD83E\uDE7A oh-my-agent doctor ")));let Q=_u();try{let T=[l.default.bold("\uD83D\uDD0D CLI Installation Status"),"┌─────────┬──────────┬─────────────┐",`│ ${l.default.bold("CLI")} │ ${l.default.bold("Status")} │ ${l.default.bold("Version")} │`,"├─────────┼──────────┼─────────────┤",...g.map((H)=>{let M=H.installed?l.default.green("✅ Installed"):l.default.red("❌ Missing"),B=H.version||"-";return`│ ${H.name.padEnd(7)} │ ${M.padEnd(8)} │ ${B.padEnd(11)} │`}),"└─────────┴──────────┴─────────────┘"].join(`
336
336
  `);if(f(T,"CLI Status"),D.length>0)f(D.map((H)=>`${l.default.yellow("→")} ${H.name}: ${l.default.dim(H.installCmd)}`).join(`
337
337
  `),"Install missing CLIs");if(U.length>0){let H=[l.default.bold("\uD83D\uDD17 MCP Connection Status"),"┌─────────┬──────────┬─────────────────────┐",`│ ${l.default.bold("CLI")} │ ${l.default.bold("MCP Config")} │ ${l.default.bold("Path")} │`,"├─────────┼──────────┼─────────────────────┤",...U.map((M)=>{let B=M.mcp.configured?l.default.green("✅ Configured"):l.default.yellow("⚠️ Not configured"),L=M.mcp.path?M.mcp.path.split("/").pop()||"":"-";return`│ ${M.name.padEnd(7)} │ ${B.padEnd(8)} │ ${L.padEnd(19)} │`}),"└─────────┴──────────┴─────────────────────┘"].join(`
338
338
  `);f(H,"MCP Status")}let q=I.filter((H)=>H.installed).length,O=I.filter((H)=>H.hasSkillMd).length;if(I.length>0){let H=[l.default.bold(`\uD83D\uDCE6 Skills (${q}/${I.length} installed, ${O} complete)`),"┌────────────────────┬──────────┬─────────────┐",`│ ${l.default.bold("Skill")} │ ${l.default.bold("Installed")} │ ${l.default.bold("SKILL.md")} │`,"├────────────────────┼──────────┼─────────────┤",...I.map((M)=>{let B=M.installed?l.default.green("✅"):l.default.red("❌"),L=M.hasSkillMd?l.default.green("✅"):l.default.red("❌");return`│ ${M.name.padEnd(18)} │ ${B.padEnd(8)} │ ${L.padEnd(11)} │`}),"└────────────────────┴──────────┴─────────────┘"].join(`
@@ -448,7 +448,7 @@ Comparing: ${D.label} (current) vs ${G.label} (prior)
448
448
  </html>`;function ZO(){let $=mi();if(!li($))xi($,{recursive:!0});let u=yi((v,z)=>{if(v.url==="/api/state")z.writeHead(200,{"Content-Type":"application/json"}),z.end(JSON.stringify(mD($)));else z.writeHead(200,{"Content-Type":"text/html"}),z.end(ti)}),g=new yD.default({server:u}),U=null;function I(v,z){if(U)clearTimeout(U);U=setTimeout(()=>{let N=JSON.stringify({type:"update",event:v,file:z,data:mD($)});g.clients.forEach((J)=>{if(J.readyState===kD.default.OPEN)J.send(N)})},100)}let _=mU($,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:200,pollInterval:50}});_.on("all",(v,z)=>I(v,AO(z))),g.on("connection",(v)=>{v.send(JSON.stringify({type:"full",data:mD($)})),v.on("error",()=>v.terminate())}),process.on("SIGINT",()=>{console.log(`
449
449
  Shutting down...`),_.close(),g.clients.forEach((v)=>{v.terminate()}),g.close(()=>u.close(()=>process.exit(0))),setTimeout(()=>process.exit(1),3000).unref()}),process.on("SIGTERM",()=>process.emit("SIGINT")),u.listen(WO,()=>{console.log(U1.magenta(`
450
450
  \uD83D\uDEF8 Serena Memory Dashboard`)),console.log(U1.white(` http://localhost:${WO}`)),console.log(U1.dim(` Watching: ${$}
451
- `))})}var FO={name:"oh-my-agent",version:"2.11.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-ag":"./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 .",test:"vitest run",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^1.1.0",chokidar:"^5.0.0",commander:"^14.0.3","p-map":"^7.0.4",picocolors:"^1.1.1",ws:"^8.18.0",yaml:"^2.8.2",zod:"^4.3.6"},devDependencies:{"@biomejs/biome":"2.4.5","@types/bun":"^1.3.10","@types/ws":"^8.18.1",vitest:"^4.0.18"},peerDependencies:{typescript:"^5"},repository:{type:"git",url:"https://github.com/first-fluke/oh-my-agent"},antigravity:{skillsPath:".agents/skills",skills:["brainstorm","workflow-guide","pm-agent","frontend-agent","backend-agent","db-agent","mobile-agent","qa-agent","debug-agent","orchestrator","dev-workflow","tf-infra-agent","commit"]}};import{existsSync as ei,mkdirSync as si,readdirSync as Z6,readFileSync as $n,statSync as oD}from"node:fs";import{basename as un,join as Yu}from"node:path";var E$=Q$(A$(),1),In="●",gn="✓",Un="✗",_n="○",vn="◌";function zn(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let $=process.argv[3];if($)return Yu($,".serena","memories");return Yu(process.cwd(),".serena","memories")}function F6($){try{return $n($,"utf-8")}catch{return""}}function Nn($){try{let u=Z6($);if(u.includes("orchestrator-session.md"))return Yu($,"orchestrator-session.md");let g=u.filter((U)=>/^session-.*\.md$/.test(U)).map((U)=>({name:U,mtime:oD(Yu($,U)).mtimeMs})).sort((U,I)=>I.mtime-U.mtime);if(g.length>0&&g[0])return Yu($,g[0].name)}catch{}return null}function Jn($){let u=Nn($);if(!u)return{id:"N/A",status:"UNKNOWN"};let g=F6(u);if(!g)return{id:"N/A",status:"UNKNOWN"};let U=(g.match(/session-id:\s*(.+)/i)||[])[1]||(g.match(/# Session:\s*(.+)/i)||[])[1]||g.match(/(session-\d{8}-\d{6})/)?.[1]||un(u,".md"),I="UNKNOWN";if(/IN PROGRESS|RUNNING|## Active|\[IN PROGRESS\]/i.test(g))I="RUNNING";else if(/COMPLETED|DONE|## Completed|\[COMPLETED\]/i.test(g))I="COMPLETED";else if(/FAILED|ERROR|## Failed|\[FAILED\]/i.test(g))I="FAILED";else if(/Step \d+:.*\[/i.test(g))I="RUNNING";return{id:(U||"N/A").trim(),status:I}}function Gn($){let u=F6(Yu($,"task-board.md"));if(!u)return[];let g=[],U=u.split(`
451
+ `))})}var FO={name:"oh-my-agent",version:"2.11.2",description:"Portable multi-agent harness for .agents-based skills and workflows across Antigravity, Claude Code, Codex, OpenCode, and more",type:"module",bin:{"oh-my-ag":"./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 .",test:"vitest run",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^1.1.0",chokidar:"^5.0.0",commander:"^14.0.3","p-map":"^7.0.4",picocolors:"^1.1.1",ws:"^8.18.0",yaml:"^2.8.2",zod:"^4.3.6"},devDependencies:{"@biomejs/biome":"2.4.5","@types/bun":"^1.3.10","@types/ws":"^8.18.1",vitest:"^4.0.18"},peerDependencies:{typescript:"^5"},repository:{type:"git",url:"https://github.com/first-fluke/oh-my-agent"},antigravity:{skillsPath:".agents/skills",skills:["brainstorm","workflow-guide","pm-agent","frontend-agent","backend-agent","db-agent","mobile-agent","qa-agent","debug-agent","orchestrator","dev-workflow","tf-infra-agent","commit"]}};import{existsSync as ei,mkdirSync as si,readdirSync as Z6,readFileSync as $n,statSync as oD}from"node:fs";import{basename as un,join as Yu}from"node:path";var E$=Q$(A$(),1),In="●",gn="✓",Un="✗",_n="○",vn="◌";function zn(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let $=process.argv[3];if($)return Yu($,".serena","memories");return Yu(process.cwd(),".serena","memories")}function F6($){try{return $n($,"utf-8")}catch{return""}}function Nn($){try{let u=Z6($);if(u.includes("orchestrator-session.md"))return Yu($,"orchestrator-session.md");let g=u.filter((U)=>/^session-.*\.md$/.test(U)).map((U)=>({name:U,mtime:oD(Yu($,U)).mtimeMs})).sort((U,I)=>I.mtime-U.mtime);if(g.length>0&&g[0])return Yu($,g[0].name)}catch{}return null}function Jn($){let u=Nn($);if(!u)return{id:"N/A",status:"UNKNOWN"};let g=F6(u);if(!g)return{id:"N/A",status:"UNKNOWN"};let U=(g.match(/session-id:\s*(.+)/i)||[])[1]||(g.match(/# Session:\s*(.+)/i)||[])[1]||g.match(/(session-\d{8}-\d{6})/)?.[1]||un(u,".md"),I="UNKNOWN";if(/IN PROGRESS|RUNNING|## Active|\[IN PROGRESS\]/i.test(g))I="RUNNING";else if(/COMPLETED|DONE|## Completed|\[COMPLETED\]/i.test(g))I="COMPLETED";else if(/FAILED|ERROR|## Failed|\[FAILED\]/i.test(g))I="FAILED";else if(/Step \d+:.*\[/i.test(g))I="RUNNING";return{id:(U||"N/A").trim(),status:I}}function Gn($){let u=F6(Yu($,"task-board.md"));if(!u)return[];let g=[],U=u.split(`
452
452
  `);for(let I of U){if(!I.startsWith("|")||/^\|\s*-+/.test(I))continue;let _=I.split("|").map((J)=>J.trim()).filter(Boolean),v=_[0];if(_.length<2||!v||/^agent$/i.test(v))continue;let z=_[1],N=_[2];g.push({agent:v,status:z||"pending",task:N||""})}return g}function dD($,u){try{let g=Z6($).filter((_)=>_.startsWith(`progress-${u}`)&&_.endsWith(".md")).sort().reverse();if(g.length===0||!g[0])return null;let I=F6(Yu($,g[0])).match(/turn[:\s]*(\d+)/i);return I?.[1]?parseInt(I[1],10):null}catch{return null}}function Dn($){try{let u=Z6($).filter((U)=>U.endsWith(".md")&&U!==".gitkeep").map((U)=>({name:U,mtime:oD(Yu($,U)).mtimeMs})).sort((U,I)=>I.mtime-U.mtime).slice(0,5),g=[];for(let U of u){let I=U.name.replace(/^(progress|result|session|debug|task)-?/,"").replace(/[-_]agent/,"").replace(/[-_]completion/,"").replace(/\.md$/,"").replace(/[-_]/g," ").trim()||U.name.replace(/\.md$/,""),v=F6(Yu($,U.name)).split(`
453
453
  `).map((N)=>N.trim()).filter((N)=>N&&!N.startsWith("---")&&N.length>3),z="";for(let N=v.length-1;N>=0;N--){let J=v[N];if(!J)continue;if(/^\*\*|^#+|^-|^\d+\.|Status|Result|Action|Step/i.test(J)){if(z=J.replace(/^[#*\-\d.]+\s*/,"").replace(/\*\*/g,"").trim(),z.length>5)break}}if(z.length>52)z=`${z.substring(0,49)}...`;if(z)g.push({agent:I,message:z})}return g}catch{return[]}}function Xn($){let u=[],g=new Set;try{let U=Z6($).filter((I)=>I.endsWith(".md")&&I!==".gitkeep").map((I)=>({name:I,mtime:oD(Yu($,I)).mtimeMs})).sort((I,_)=>_.mtime-I.mtime);for(let I of U){let _=F6(Yu($,I.name)),v=_.match(/\*\*Agent\*\*:\s*(.+)/i)||_.match(/Agent:\s*(.+)/i)||_.match(/^#+\s*(.+?)\s*Agent/im),z=null;if(v?.[1])z=v[1].trim();else if(/_agent|agent_|-agent/i.test(I.name))z=I.name.replace(/\.md$/,"").replace(/[-_]completion|[-_]progress|[-_]result/gi,"").replace(/[-_]/g," ").trim();if(z&&!g.has(z.toLowerCase())){g.add(z.toLowerCase());let N="unknown";if(/\[COMPLETED\]|## Completed|## Results/i.test(_))N="completed";else if(/\[IN PROGRESS\]|## Progress|IN PROGRESS/i.test(_))N="running";else if(/\[FAILED\]|## Failed|ERROR/i.test(_))N="failed";let J=_.match(/## Task\s*\n+(.+)/i)||_.match(/\*\*Task\*\*:\s*(.+)/i),D=J?.[1]?J[1].trim().substring(0,20):"";u.push({agent:z,status:N,task:D,turn:dD($,z)})}}}catch{}return u}function qn($){let u=$.toLowerCase();if(["running","active","in_progress","in-progress"].includes(u))return`${E$.default.green(In)} running`;else if(["completed","done","finished"].includes(u))return`${E$.default.cyan(gn)} completed`;else if(["failed","error"].includes(u))return`${E$.default.red(Un)} failed`;else if(["blocked","waiting"].includes(u))return`${E$.default.yellow(_n)} blocked`;return`${E$.default.dim(vn)} pending`}function wO($){console.clear();let u=Jn($),U=Gn($).map((q)=>({...q,turn:dD($,q.agent)}));if(U.length===0)U=Xn($);if(U.length===0)try{let q=Z6($).filter((O)=>O.startsWith("progress-")&&O.endsWith(".md"));for(let O of q){let H=O.replace(/^progress-/,"").replace(/\.md$/,"");U.push({agent:H,status:"running",task:"",turn:dD($,H)})}}catch{}let I=56,_="═".repeat(I),v=(q)=>" ".repeat(Math.max(0,q)),z=(q)=>E$.default.magenta(q),N=(q)=>E$.default.bold(q),J=(q)=>E$.default.dim(q),D=E$.default.yellow;if(u.status==="RUNNING")D=E$.default.green;else if(u.status==="COMPLETED")D=E$.default.cyan;else if(u.status==="FAILED")D=E$.default.red;console.log(`${z(`╔${_}╗`)}`),console.log(`${z("║")} ${N(z("Serena Memory Dashboard"))}${v(I-25)}${z("║")}`);let G=`Session: ${N(u.id.padEnd(20))} [${D(u.status)}]`;if(console.log(`${z("║")} ${G}${v(I-4-G.length-9)}${z("║")}`),console.log(`${z(`╠${_}╣`)}`),console.log(`${z("║")} ${N(`${"Agent".padEnd(12)} ${"Status".padEnd(12)} ${"Turn".padEnd(6)} ${"Task".padEnd(20)}`)} ${z("║")}`),console.log(`${z("║")} ${J(`${"──────────".padEnd(12)} ${"──────────".padEnd(12)} ${"────".padEnd(6)} ${"──────────────────".padEnd(20)}`)} ${z("║")}`),U.length===0)console.log(`${z("║")} ${J(`No agents detected yet${v(32)}`)}${z("║")}`);else for(let q of U){let O=qn(q.status),H=q.turn!=null?String(q.turn):"-",M=q.task.substring(0,20);console.log(`${z("║")} ${q.agent.padEnd(12)} ${O.padEnd(22)} ${H.padEnd(6)} ${M.padEnd(20)}${z("║")}`)}console.log(`${z(`╠${_}╣`)}`),console.log(`${z("║")} ${N("Latest Activity:")}${v(I-18)}${z("║")}`);let X=Dn($);if(X.length===0)console.log(`${z("║")} ${J(`No activity yet${v(38)}`)}${z("║")}`);else for(let q of X){let O=`[${q.agent}] ${q.message}`;console.log(`${z("║")} ${J(O.substring(0,52).padEnd(52))}${z("║")}`)}console.log(`${z(`╠${_}╣`)}`);let T=`Updated: ${new Date().toLocaleString("en-US",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"})} | Ctrl+C to exit`;console.log(`${z("║")} ${J(T)}${v(I-4-T.length)}${z("║")}`),console.log(`${z(`╚${_}╝`)}`)}async function iO(){let $=zn();if(!ei($))si($,{recursive:!0}),console.log(E$.default.yellow(`Created ${$} — waiting for memory files...`));console.log(E$.default.magenta(`
454
454
  \uD83D\uDEF8 Serena Terminal Dashboard`)),console.log(E$.default.dim(` Watching: ${$}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-agent",
3
- "version": "2.11.0",
3
+ "version": "2.11.2",
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": {