oh-my-agent 5.2.0 → 5.2.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 +3 -2
package/bin/cli.js CHANGED
@@ -743,7 +743,7 @@ source: migrated
743
743
  `).filter(Boolean),u=[];for(let Q of q)if(!J.some((H)=>Q.startsWith(H)))u.push(Q);if(u.length>0)return n("Scope Check","fail",`${u.length} out-of-scope: ${u[0]}${u.length>1?` +${u.length-1}`:""}`);return n("Scope Check","pass",`All ${q.length} files in scope`)}function Ar($,I){let U=Vr($,I);if(!U)return n("Charter Preflight","skip","Result file not found");let G=yH(U,"utf-8");if(!G.includes("CHARTER_CHECK:"))return n("Charter Preflight","warn","Block missing from result");if(/\{[^}]+\}/.test(G.split("CHARTER_CHECK:")[1]?.split("```")[0]||""))return n("Charter Preflight","warn","Contains unfilled placeholders");return n("Charter Preflight","pass","Properly filled")}function Rr($){let I=["*.py","*.ts","*.tsx","*.js","*.dart"],U=`(password|secret|api_key|token)\\s*=\\s*['"][^'"]{8,}`;for(let G of I){let _=y$(`grep -rn --include="${G}" -E "(password|secret|api_key|token)\\s*=\\s*['"][^'"]{8,}" . 2>/dev/null | grep -v test | grep -v example | grep -v node_modules | head -1`,$);if(_)return n("Hardcoded Secrets","fail",`Found in: ${_.split(":")[0]}`)}return n("Hardcoded Secrets","pass","None detected")}function gr($){let I=y$('grep -rn --include="*.py" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.dart" -E "TODO|FIXME|HACK|XXX" . 2>/dev/null | grep -v node_modules | grep -v ".agents/" | wc -l',$),U=Number.parseInt(I||"0",10);if(U>0)return n("TODO/FIXME Comments","warn",`${U} found`);return n("TODO/FIXME Comments","pass","None found")}function Wr($){if(!y$("which uv",$))return n("Python Syntax","skip","uv not available");let U=y$('find . -name "*.py" -not -path "*/node_modules/*" -not -path "*/.venv/*" -exec uv run python -m py_compile {} \\; 2>&1 | head -5',$);if(U&&U.length>0)return n("Python Syntax","fail","Syntax errors found");return n("Python Syntax","pass","Valid")}function Zr($){if(y$(`grep -rn --include="*.py" -E "f['"].*SELECT|f['"].*INSERT|f['"].*UPDATE|f['"].*DELETE" . 2>/dev/null | grep -v test | grep -v node_modules | head -1`,$))return n("SQL Injection","fail","f-string with SQL keywords detected");return n("SQL Injection","pass","None detected")}function bR($){let I=y$("which uv",$),U=w1(u1($,"pyproject.toml"));if(!I||!U)return n("Python Tests","skip",!I?"uv not available":"pyproject.toml not found");let G=y$("uv run pytest -q --tb=no 2>&1",$);if(G?.includes("passed")||G?.includes("no tests ran"))return n("Python Tests","pass","Tests pass");return n("Python Tests","fail","Tests failing")}function Or($){if(!w1(u1($,"tsconfig.json")))return n("TypeScript","skip","Not configured");let I=y$("npx tsc --noEmit 2>&1",$);if(I===null||I==="")return n("TypeScript","pass","Compilation clean");if(I.includes("error"))return n("TypeScript","fail","Type errors found");return n("TypeScript","pass","Compilation clean")}function br($){let I=y$(`grep -rn --include="*.tsx" --include="*.jsx" 'style={{' . 2>/dev/null | grep -v node_modules | wc -l`,$),U=Number.parseInt(I||"0",10);if(U>0)return n("Inline Styles","warn",`${U} found (prefer Tailwind)`);return n("Inline Styles","pass","None found")}function Pr($){let I=y$(`grep -rn --include="*.ts" --include="*.tsx" ': any' . 2>/dev/null | grep -v node_modules | grep -v ".d.ts" | wc -l`,$),U=Number.parseInt(I||"0",10);if(U>3)return n("Any Types","fail",`${U} found (limit: 3)`);if(U>0)return n("Any Types","warn",`${U} found`);return n("Any Types","pass","None found")}function PR($){if(!w1(u1($,"package.json")))return n("Frontend Tests","skip","No package.json");let I=y$("npx vitest run --reporter=verbose 2>&1",$);if(I?.includes("passed")||I?.includes("✓"))return n("Frontend Tests","pass","Tests pass");return n("Frontend Tests","warn","Tests failed or vitest not configured")}function wr($){if(!y$("which flutter",$)){if(!y$("which dart",$))return n("Flutter/Dart Analysis","skip","Not available");if(y$("dart analyze 2>&1",$)?.includes("No issues found"))return n("Dart Analysis","pass","Clean");return n("Dart Analysis","fail","Issues found")}if(y$("flutter analyze 2>&1",$)?.includes("No issues found"))return n("Flutter Analysis","pass","Clean");return n("Flutter Analysis","fail","Issues found")}function Dr($){if(!y$("which flutter",$))return n("Flutter Tests","skip","Flutter not available");if(y$("flutter test 2>&1",$)?.includes("All tests passed"))return n("Flutter Tests","pass","All tests pass");return n("Flutter Tests","fail","Tests failed")}function DR($){let I=u1($,".agents","results");if(w1(I))try{let G=wR(I).filter((_)=>_.startsWith("plan-")&&_.endsWith(".json")).sort().reverse();if(G.length>0&&G[0])return u1(I,G[0])}catch{}let U=u1($,".agents","plan.json");return w1(U)?U:null}function jr($){let I=DR($);if(!I)return n("PM Plan","warn","No plan file found");try{return JSON.parse(yH(I,"utf-8")),n("PM Plan","pass","Valid JSON")}catch{return n("PM Plan","fail","Invalid JSON")}}function Er($,I){let U=[];switch($){case"backend":U.push(Wr(I)),U.push(Zr(I)),U.push(bR(I));break;case"frontend":U.push(Or(I)),U.push(br(I)),U.push(Pr(I)),U.push(PR(I));break;case"mobile":U.push(wr(I)),U.push(Dr(I));break;case"qa":U.push(n("QA Report","pass","Verified by self-check.md"));break;case"debug":if(w1(u1(I,"pyproject.toml")))U.push(bR(I));else if(w1(u1(I,"package.json")))U.push(PR(I));else U.push(n("Debug Tests","skip","No test runner detected"));break;case"pm":U.push(jr(I));break}return U}async function jR($,I,U=!1){let G=$.toLowerCase();if(!OR.includes(G)){let Y=`Invalid agent type: ${$}. Valid types: ${OR.join(", ")}`;if(U)console.log(JSON.stringify({ok:!1,error:Y}));else Q$.error(Y);process.exit(2)}let _=I||process.cwd();if(!w1(_)){let Y=`Workspace not found: ${_}`;if(U)console.log(JSON.stringify({ok:!1,error:Y}));else Q$.error(Y);process.exit(2)}let J=[];J.push(vr(_,G)),J.push(Ar(_,G)),J.push(Rr(_)),J.push(gr(_)),J.push(...Er(G,_));let X=J.filter((Y)=>Y.status==="pass").length,q=J.filter((Y)=>Y.status==="fail").length,u=J.filter((Y)=>Y.status==="warn").length,Q={ok:q===0,agent:G,workspace:_,checks:J,summary:{passed:X,failed:q,warned:u}};if(U)console.log(JSON.stringify(Q,null,2)),process.exit(q>0?1:0);console.clear(),b$(a$.default.bgCyan(a$.default.white(` \uD83D\uDD0D Verify: ${G} agent `))),m(a$.default.dim(_),"Workspace");let N=["┌────────────────────────────┬────────┬─────────────────────────────┐",`│ ${a$.default.bold("Check")} │ ${a$.default.bold("Status")} │ ${a$.default.bold("Details")} │`,"├────────────────────────────┼────────┼─────────────────────────────┤",...J.map((Y)=>{let T;switch(Y.status){case"pass":T=a$.default.green("PASS");break;case"fail":T=a$.default.red("FAIL");break;case"warn":T=a$.default.yellow("WARN");break;default:T=a$.default.dim("SKIP")}let z=Y.name.padEnd(26),B=T.padEnd(6),K=(Y.message||"-").slice(0,27).padEnd(27);return`│ ${z} │ ${B} │ ${K} │`}),"└────────────────────────────┴────────┴─────────────────────────────┘"].join(`
744
744
  `);console.log(N),console.log();let H=`${a$.default.green(`${X} passed`)}, ${a$.default.red(`${q} failed`)}, ${a$.default.yellow(`${u} warnings`)}`;if(q>0)o(a$.default.red(`❌ Verification failed: ${H}`)),process.exit(1);o(a$.default.green(`✅ Verification passed: ${H}`)),process.exit(0)}var Z$=M$(E$(),1);import{existsSync as Fr,readdirSync as ER,readFileSync as xr}from"node:fs";import{join as r0}from"node:path";var FR=Object.fromEntries(Object.entries(L0).map(([$,I])=>[$,I.map((U)=>U.name)])),Sr={"backend-engineer":"oma-backend","frontend-engineer":"oma-frontend","db-engineer":"oma-db","mobile-engineer":"oma-mobile","pm-planner":"oma-pm","qa-reviewer":"oma-qa","debug-investigator":"oma-debug"};function kH($){let I=new Set;for(let U of $.matchAll(/_shared\/((?:[a-z][a-z0-9_-]*\/)*[a-z][a-z0-9_-]*)(?:\.md)?(?=[`)\s/}]|$)/gi))if(U[1])I.add(U[1]);return[...I]}function g9($){try{return xr($,"utf-8")}catch{return""}}function mH($){try{return ER($).filter((I)=>!I.startsWith("."))}catch{return[]}}function Cr($){try{return ER($,{withFileTypes:!0}).filter((I)=>!I.name.startsWith("."))}catch{return[]}}function xR($,I=""){let U=[];for(let G of Cr($)){let _=I?`${I}/${G.name}`:G.name;if(G.isDirectory()){U.push({path:_,isDirectory:!0}),U.push(...xR(r0($,G.name),_));continue}if(!G.name.endsWith(".md"))continue;U.push({path:_.replace(/\.md$/,""),isDirectory:!1})}return U}function SR($){let I=[{id:"root",label:"oh-my-agent",category:"root"}],U=new Set,G=[];function _(H,Y,T){let z=`${H}|${Y}`;if(U.has(z))return;U.add(z),G.push({from:H,to:Y,type:T})}let J=r0($,".agents","skills");for(let[H,Y]of Object.entries(FR))for(let T of Y){let z=r0(J,T);if(!Fr(z))continue;let B=`skill:${T}`;I.push({id:B,label:T,category:"skill",group:"Skills",subgroup:H});let K=[g9(r0(z,"SKILL.md")),g9(r0(z,"resources","execution-protocol.md"))].join(`
745
745
  `);for(let L of kH(K))_(B,`shared:${L}`,"references")}let X=r0($,".agents","workflows");for(let H of mH(X).filter((Y)=>Y.endsWith(".md"))){let Y=H.replace(".md",""),T=`workflow:${Y}`;I.push({id:T,label:Y,category:"workflow",group:"Workflows"});for(let z of kH(g9(r0(X,H))))_(T,`shared:${z}`,"references")}let q=r0(J,"_shared");for(let H of xR(q)){let Y=`shared:${H.path}`;if(I.push({id:Y,label:H.path,category:"shared",group:"Shared"}),!H.isDirectory){for(let T of kH(g9(r0(q,`${H.path}.md`))))if(T!==H.path)_(Y,`shared:${T}`,"references")}}let u=r0($,".claude","agents");for(let H of mH(u).filter((Y)=>Y.endsWith(".md"))){let Y=H.replace(".md",""),T=`agent:${Y}`;I.push({id:T,label:Y,category:"agent",group:"Claude Agents"});let z=Sr[Y];if(z)_(T,`skill:${z}`,"implements")}let Q=r0($,".serena","memories");for(let H of mH(Q).filter((Y)=>Y.endsWith(".md")))I.push({id:`memory:${H.replace(".md","")}`,label:H.replace(".md",""),category:"memory",group:"Serena Memories"});let N=new Set(I.map((H)=>H.id));return{nodes:I,edges:G.filter((H)=>N.has(H.from)&&N.has(H.to))}}var fr={root:($)=>Z$.default.bold(Z$.default.white($)),skill:Z$.default.green,workflow:Z$.default.blue,shared:Z$.default.yellow,agent:Z$.default.magenta,memory:Z$.default.cyan};function A0($,I){return(fr[I]??Z$.default.white)($)}function Q1(...$){let I=$.sort((_,J)=>_[0]-J[0]),U="",G=0;for(let[_,J,X]of I){if(_>G)U+=" ".repeat(_-G);U+=J,G=_+X}return U}function yr($){let I=[],U=$.nodes.filter((F)=>F.category==="skill").length,G=$.nodes.filter((F)=>F.category==="workflow").length,_=$.nodes.filter((F)=>F.category==="shared").length,J=$.nodes.filter((F)=>F.category==="agent").length,X=$.nodes.filter((F)=>F.category==="memory").length,q=$.edges.filter((F)=>F.from.startsWith("skill:")&&F.to.startsWith("shared:")).length,u=$.edges.filter((F)=>F.from.startsWith("workflow:")&&F.to.startsWith("shared:")).length,Q=$.edges.filter((F)=>F.type==="implements").length,N=$.edges.filter((F)=>F.from.startsWith("shared:")&&F.to.startsWith("shared:")).length,H=`Skills (${U})`,Y=`Workflows (${G})`,T=`Shared (${_})`,z=`Agents (${J})`,B=`Memories (${X})`,K=10,L=29,A=48,V=19;I.push(Q1([24,A0("oh-my-agent","root"),11])),I.push(Q1([29,"│",1]));let R=Array(49).fill(" ");R[10]="┌",R[29]="┼",R[48]="┐";for(let F=11;F<48;F++)if(F!==29)R[F]="─";I.push(R.join("")),I.push(Q1([10,"▼",1],[29,"▼",1],[48,"▼",1])),I.push(Q1([10-(H.length>>1),A0(H,"skill"),H.length],[29-(Y.length>>1),A0(Y,"workflow"),Y.length],[48-(B.length>>1),A0(B,"memory"),B.length])),I.push(Q1([10,"│",1],[29,"│",1]));let W=`${q} refs`,Z=`${u} refs`;I.push(Q1([10-(W.length>>1),Z$.default.dim(W),W.length],[29-(Z.length>>1),Z$.default.dim(Z),Z.length])),I.push(Q1([10,"│",1],[29,"│",1]));let M=Array(30).fill(" ");M[10]="└",M[19]="┬",M[29]="┘";for(let F=11;F<29;F++)if(F!==19)M[F]="─";I.push(M.join("")),I.push(Q1([19,"▼",1]));let g=19-(T.length>>1),x=Q1([g,A0(T,"shared"),T.length]);if(N>0)x+=` ${Z$.default.dim(`◂── ${N} internal`)}`;I.push(x),I.push("");let S=10-(z.length>>1),k=`──[${Q} implements]──▸`;return I.push(Q1([S,A0(z,"agent"),z.length])+` ${Z$.default.dim(k)} ${A0("Skills","skill")}`),I}function CR($){let I=[];I.push(...yr($)),I.push(""),I.push(Z$.default.dim("─".repeat(56))),I.push("");let U=new Map,G=new Map;for(let H of $.edges){if(!U.has(H.from))U.set(H.from,[]);if(U.get(H.from)?.push(H),H.to.startsWith("shared:"))G.set(H.to,(G.get(H.to)??0)+1)}function _(H){let Y=U.get(H);if(!Y?.length)return"";let T=Y.map((B)=>$.nodes.find((K)=>K.id===B.to)?.label.replace(/\.md$/,"")??B.to.split(":")[1]),z=T.length>4?`${T.slice(0,3).join(", ")} +${T.length-3}`:T.join(", ");return` ${Z$.default.dim("──▸")} ${Z$.default.dim(z)}`}let J=$.nodes.filter((H)=>H.category==="skill"),X=Object.keys(FR);I.push(Z$.default.bold(`Skills (${J.length})`));for(let H=0;H<X.length;H++){let Y=X[H],T=J.filter((K)=>K.subgroup===Y);if(!T.length)continue;let z=H===X.length-1;I.push(`${z?"└─":"├─"} ${Z$.default.dim(Y)}`);let B=z?" ":"│ ";for(let K of T){let L=K===T.at(-1)?"└─":"├─";I.push(`${B}${L} ${A0(K.label,"skill")}${_(K.id)}`)}}I.push("");let q=$.nodes.filter((H)=>H.category==="workflow");I.push(Z$.default.bold(`Workflows (${q.length})`));for(let H of q){let Y=H===q.at(-1)?"└─":"├─";I.push(`${Y} ${A0(H.label,"workflow")}${_(H.id)}`)}I.push("");let u=[...$.nodes.filter((H)=>H.category==="shared")].sort((H,Y)=>(G.get(Y.id)??0)-(G.get(H.id)??0));I.push(Z$.default.bold(`Shared (${u.length})`));for(let H of u){let Y=H===u.at(-1)?"└─":"├─",T=G.get(H.id)??0,z=T>0?Z$.default.dim(` (${T} refs)`):"";I.push(`${Y} ${A0(H.label,"shared")}${z}${_(H.id)}`)}I.push("");let Q=$.nodes.filter((H)=>H.category==="agent");I.push(Z$.default.bold(`Claude Agents (${Q.length})`));for(let H of Q){let Y=H===Q.at(-1)?"└─":"├─",T=$.edges.find((B)=>B.from===H.id&&B.type==="implements"),z=T?` ${Z$.default.dim("──▸")} ${A0(T.to.split(":")[1]??"","skill")}`:"";I.push(`${Y} ${A0(H.label,"agent")}${z}`)}I.push("");let N=$.nodes.filter((H)=>H.category==="memory");if(I.push(Z$.default.bold(`Serena Memories (${N.length})`)),!N.length)I.push(`└─ ${Z$.default.dim("(none)")}`);else for(let H of N){let Y=H===N.at(-1)?"└─":"├─";I.push(`${Y} ${A0(H.label,"memory")}`)}return I.join(`
746
- `)}async function fR($){let I=SR(process.cwd());if($.json){console.log(JSON.stringify(I,null,2));return}console.log(CR(I))}var yR={name:"oh-my-agent",version:"5.2.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 .",test:"vitest run",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^1.1.0","@date-fns/tz":"^1.4.1","better-sqlite3":"^12.9.0",chokidar:"^5.0.0",commander:"^14.0.3","date-fns":"^4.1.0","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/better-sqlite3":"^7.6.13","@types/bun":"^1.3.10","@types/ws":"^8.18.1",vitest:"^4.0.18"},peerDependencies:{typescript:"^6"},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"]}};import{existsSync as mr,mkdirSync as lr,readdirSync as u2,readFileSync as hr,statSync as hH}from"node:fs";import{basename as ir,join as n0}from"node:path";var s$=M$(E$(),1),rr="●",nr="✓",cr="✗",dr="○",pr="◌";function or(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let $=process.argv[3];if($)return n0($,".serena","memories");return n0(process.cwd(),".serena","memories")}function Q2($){try{return hr($,"utf-8")}catch{return""}}function tr($){try{let I=u2($);if(I.includes("orchestrator-session.md"))return n0($,"orchestrator-session.md");let U=I.filter((G)=>/^session-.*\.md$/.test(G)).map((G)=>({name:G,mtime:hH(n0($,G)).mtimeMs})).sort((G,_)=>_.mtime-G.mtime);if(U.length>0&&U[0])return n0($,U[0].name)}catch{}return null}function ar($){let I=tr($);if(!I)return{id:"N/A",status:"UNKNOWN"};let U=Q2(I);if(!U)return{id:"N/A",status:"UNKNOWN"};let G=(U.match(/session-id:\s*(.+)/i)||[])[1]||(U.match(/# Session:\s*(.+)/i)||[])[1]||U.match(/(session-\d{8}-\d{6})/)?.[1]||ir(I,".md"),_="UNKNOWN";if(/IN PROGRESS|RUNNING|## Active|\[IN PROGRESS\]/i.test(U))_="RUNNING";else if(/COMPLETED|DONE|## Completed|\[COMPLETED\]/i.test(U))_="COMPLETED";else if(/FAILED|ERROR|## Failed|\[FAILED\]/i.test(U))_="FAILED";else if(/Step \d+:.*\[/i.test(U))_="RUNNING";return{id:(G||"N/A").trim(),status:_}}function sr($){let I=Q2(n0($,"task-board.md"));if(!I)return[];let U=[],G=I.split(`
746
+ `)}async function fR($){let I=SR(process.cwd());if($.json){console.log(JSON.stringify(I,null,2));return}console.log(CR(I))}var yR={name:"oh-my-agent",version:"5.2.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 .",test:"vitest run",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^1.1.0","@date-fns/tz":"^1.4.1","better-sqlite3":"^12.9.0",chokidar:"^5.0.0",commander:"^14.0.3","date-fns":"^4.1.0","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/better-sqlite3":"^7.6.13","@types/bun":"^1.3.10","@types/ws":"^8.18.1",vitest:"^4.0.18"},peerDependencies:{typescript:"^6"},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"]}};import{existsSync as mr,mkdirSync as lr,readdirSync as u2,readFileSync as hr,statSync as hH}from"node:fs";import{basename as ir,join as n0}from"node:path";var s$=M$(E$(),1),rr="●",nr="✓",cr="✗",dr="○",pr="◌";function or(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let $=process.argv[3];if($)return n0($,".serena","memories");return n0(process.cwd(),".serena","memories")}function Q2($){try{return hr($,"utf-8")}catch{return""}}function tr($){try{let I=u2($);if(I.includes("orchestrator-session.md"))return n0($,"orchestrator-session.md");let U=I.filter((G)=>/^session-.*\.md$/.test(G)).map((G)=>({name:G,mtime:hH(n0($,G)).mtimeMs})).sort((G,_)=>_.mtime-G.mtime);if(U.length>0&&U[0])return n0($,U[0].name)}catch{}return null}function ar($){let I=tr($);if(!I)return{id:"N/A",status:"UNKNOWN"};let U=Q2(I);if(!U)return{id:"N/A",status:"UNKNOWN"};let G=(U.match(/session-id:\s*(.+)/i)||[])[1]||(U.match(/# Session:\s*(.+)/i)||[])[1]||U.match(/(session-\d{8}-\d{6})/)?.[1]||ir(I,".md"),_="UNKNOWN";if(/IN PROGRESS|RUNNING|## Active|\[IN PROGRESS\]/i.test(U))_="RUNNING";else if(/COMPLETED|DONE|## Completed|\[COMPLETED\]/i.test(U))_="COMPLETED";else if(/FAILED|ERROR|## Failed|\[FAILED\]/i.test(U))_="FAILED";else if(/Step \d+:.*\[/i.test(U))_="RUNNING";return{id:(G||"N/A").trim(),status:_}}function sr($){let I=Q2(n0($,"task-board.md"));if(!I)return[];let U=[],G=I.split(`
747
747
  `);for(let _ of G){if(!_.startsWith("|")||/^\|\s*-+/.test(_))continue;let J=_.split("|").map((Q)=>Q.trim()).filter(Boolean),X=J[0];if(J.length<2||!X||/^agent$/i.test(X))continue;let q=J[1],u=J[2];U.push({agent:X,status:q||"pending",task:u||""})}return U}function lH($,I){try{let U=u2($).filter((J)=>J.startsWith(`progress-${I}`)&&J.endsWith(".md")).sort().reverse();if(U.length===0||!U[0])return null;let _=Q2(n0($,U[0])).match(/turn[:\s]*(\d+)/i);return _?.[1]?parseInt(_[1],10):null}catch{return null}}function er($){try{let I=u2($).filter((G)=>G.endsWith(".md")&&G!==".gitkeep").map((G)=>({name:G,mtime:hH(n0($,G)).mtimeMs})).sort((G,_)=>_.mtime-G.mtime).slice(0,5),U=[];for(let G of I){let _=G.name.replace(/^(progress|result|session|debug|task)-?/,"").replace(/[-_]agent/,"").replace(/[-_]completion/,"").replace(/\.md$/,"").replace(/[-_]/g," ").trim()||G.name.replace(/\.md$/,""),X=Q2(n0($,G.name)).split(`
748
748
  `).map((u)=>u.trim()).filter((u)=>u&&!u.startsWith("---")&&u.length>3),q="";for(let u=X.length-1;u>=0;u--){let Q=X[u];if(!Q)continue;if(/^\*\*|^#+|^-|^\d+\.|Status|Result|Action|Step/i.test(Q)){if(q=Q.replace(/^[#*\-\d.]+\s*/,"").replace(/\*\*/g,"").trim(),q.length>5)break}}if(q.length>52)q=`${q.substring(0,49)}...`;if(q)U.push({agent:_,message:q})}return U}catch{return[]}}function $n($){let I=[],U=new Set;try{let G=u2($).filter((_)=>_.endsWith(".md")&&_!==".gitkeep").map((_)=>({name:_,mtime:hH(n0($,_)).mtimeMs})).sort((_,J)=>J.mtime-_.mtime);for(let _ of G){let J=Q2(n0($,_.name)),X=J.match(/\*\*Agent\*\*:\s*(.+)/i)||J.match(/Agent:\s*(.+)/i)||J.match(/^#+\s*(.+?)\s*Agent/im),q=null;if(X?.[1])q=X[1].trim();else if(/_agent|agent_|-agent/i.test(_.name))q=_.name.replace(/\.md$/,"").replace(/[-_]completion|[-_]progress|[-_]result/gi,"").replace(/[-_]/g," ").trim();if(q&&!U.has(q.toLowerCase())){U.add(q.toLowerCase());let u="unknown";if(/\[COMPLETED\]|## Completed|## Results/i.test(J))u="completed";else if(/\[IN PROGRESS\]|## Progress|IN PROGRESS/i.test(J))u="running";else if(/\[FAILED\]|## Failed|ERROR/i.test(J))u="failed";let Q=J.match(/## Task\s*\n+(.+)/i)||J.match(/\*\*Task\*\*:\s*(.+)/i),N=Q?.[1]?Q[1].trim().substring(0,20):"";I.push({agent:q,status:u,task:N,turn:lH($,q)})}}}catch{}return I}function In($){let I=$.toLowerCase();if(["running","active","in_progress","in-progress"].includes(I))return`${s$.default.green(rr)} running`;else if(["completed","done","finished"].includes(I))return`${s$.default.cyan(nr)} completed`;else if(["failed","error"].includes(I))return`${s$.default.red(cr)} failed`;else if(["blocked","waiting"].includes(I))return`${s$.default.yellow(dr)} blocked`;return`${s$.default.dim(pr)} pending`}function kR($){console.clear();let I=ar($),G=sr($).map((B)=>({...B,turn:lH($,B.agent)}));if(G.length===0)G=$n($);if(G.length===0)try{let B=u2($).filter((K)=>K.startsWith("progress-")&&K.endsWith(".md"));for(let K of B){let L=K.replace(/^progress-/,"").replace(/\.md$/,"");G.push({agent:L,status:"running",task:"",turn:lH($,L)})}}catch{}let _=56,J="═".repeat(_),X=(B)=>" ".repeat(Math.max(0,B)),q=(B)=>s$.default.magenta(B),u=(B)=>s$.default.bold(B),Q=(B)=>s$.default.dim(B),N=s$.default.yellow;if(I.status==="RUNNING")N=s$.default.green;else if(I.status==="COMPLETED")N=s$.default.cyan;else if(I.status==="FAILED")N=s$.default.red;console.log(`${q(`╔${J}╗`)}`),console.log(`${q("║")} ${u(q("Serena Memory Dashboard"))}${X(_-25)}${q("║")}`);let H=`Session: ${u(I.id.padEnd(20))} [${N(I.status)}]`;if(console.log(`${q("║")} ${H}${X(_-4-H.length-9)}${q("║")}`),console.log(`${q(`╠${J}╣`)}`),console.log(`${q("║")} ${u(`${"Agent".padEnd(12)} ${"Status".padEnd(12)} ${"Turn".padEnd(6)} ${"Task".padEnd(20)}`)} ${q("║")}`),console.log(`${q("║")} ${Q(`${"──────────".padEnd(12)} ${"──────────".padEnd(12)} ${"────".padEnd(6)} ${"──────────────────".padEnd(20)}`)} ${q("║")}`),G.length===0)console.log(`${q("║")} ${Q(`No agents detected yet${X(32)}`)}${q("║")}`);else for(let B of G){let K=In(B.status),L=B.turn!=null?String(B.turn):"-",A=B.task.substring(0,20);console.log(`${q("║")} ${B.agent.padEnd(12)} ${K.padEnd(22)} ${L.padEnd(6)} ${A.padEnd(20)}${q("║")}`)}console.log(`${q(`╠${J}╣`)}`),console.log(`${q("║")} ${u("Latest Activity:")}${X(_-18)}${q("║")}`);let Y=er($);if(Y.length===0)console.log(`${q("║")} ${Q(`No activity yet${X(38)}`)}${q("║")}`);else for(let B of Y){let K=`[${B.agent}] ${B.message}`;console.log(`${q("║")} ${Q(K.substring(0,52).padEnd(52))}${q("║")}`)}console.log(`${q(`╠${J}╣`)}`);let z=`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(`${q("║")} ${Q(z)}${X(_-4-z.length)}${q("║")}`),console.log(`${q(`╚${J}╝`)}`)}async function mR(){let $=or();if(!mr($))lr($,{recursive:!0}),console.log(s$.default.yellow(`Created ${$} — waiting for memory files...`));console.log(s$.default.magenta(`
749
749
  \uD83D\uDEF8 Serena Terminal Dashboard`)),console.log(s$.default.dim(` Watching: ${$}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-agent",
3
- "version": "5.2.0",
3
+ "version": "5.2.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": {
@@ -106,7 +106,8 @@
106
106
  "oma-dev-workflow",
107
107
  "oma-tf-infra",
108
108
  "oma-scm",
109
- "oma-pdf"
109
+ "oma-pdf",
110
+ "oma-recap"
110
111
  ]
111
112
  }
112
113
  }