oh-my-agent 4.18.2 → 4.18.3
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.
- package/README.md +2 -0
- package/bin/cli.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,6 +95,8 @@ oma agent:parallel -i backend:"Auth API" frontend:"Login form"
|
|
|
95
95
|
|
|
96
96
|
## Why oh-my-agent?
|
|
97
97
|
|
|
98
|
+
> [Read why →](https://github.com/first-fluke/oh-my-agent/issues/155#issuecomment-4142133589)
|
|
99
|
+
|
|
98
100
|
- **Portable** — `.agents/` travels with your project, not trapped in one IDE
|
|
99
101
|
- **Role-based** — Agents modeled like a real engineering team, not a pile of prompts
|
|
100
102
|
- **Token-efficient** — Two-layer skill design saves ~75% of tokens
|
package/bin/cli.js
CHANGED
|
@@ -492,7 +492,7 @@ Co-Authored-By: First Fluke <our.first.fluke@gmail.com>`,pr:"Generated with [oh-
|
|
|
492
492
|
</html>`;function LO(){let $=Jf();if(!_f($))gf($,{recursive:!0});let I=vf((z,v)=>{if(z.url==="/api/state")v.writeHead(200,{"Content-Type":"application/json"}),v.end(JSON.stringify(r9($)));else v.writeHead(200,{"Content-Type":"text/html"}),v.end(Tf)}),U=new i9.default({server:I}),_=null;function u(z,v){if(_)clearTimeout(_);_=setTimeout(()=>{let J=JSON.stringify({type:"update",event:z,file:v,data:r9($)});U.clients.forEach((N)=>{if(N.readyState===y9.default.OPEN)N.send(J)})},100)}let g=R2($,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:200,pollInterval:50}});g.on("all",(z,v)=>u(z,RO(v))),U.on("connection",(z)=>{z.send(JSON.stringify({type:"full",data:r9($)})),z.on("error",()=>z.terminate())}),process.on("SIGINT",()=>{console.log(`
|
|
493
493
|
Shutting down...`),g.close(),U.clients.forEach((z)=>{z.terminate()}),U.close(()=>I.close(()=>process.exit(0))),setTimeout(()=>process.exit(1),3000).unref()}),process.on("SIGTERM",()=>process.emit("SIGINT")),I.listen(KO,()=>{console.log(LI.magenta(`
|
|
494
494
|
\uD83D\uDEF8 Serena Memory Dashboard`)),console.log(LI.white(` http://localhost:${KO}`)),console.log(LI.dim(` Watching: ${$}
|
|
495
|
-
`))})}var WO={name:"oh-my-agent",version:"4.18.
|
|
495
|
+
`))})}var WO={name:"oh-my-agent",version:"4.18.3",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:"^6"},repository:{type:"git",url:"https://github.com/first-fluke/oh-my-agent"},antigravity:{skillsPath:".agents/skills",skills:["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-commit"]}};import{existsSync as Yf,mkdirSync as Of,readdirSync as $u,readFileSync as Vf,statSync as h9}from"node:fs";import{basename as Df,join as j4}from"node:path";var r$=q$(b$(),1),Bf="●",Mf="✓",Kf="✗",Rf="○",Lf="◌";function Wf(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let $=process.argv[3];if($)return j4($,".serena","memories");return j4(process.cwd(),".serena","memories")}function Iu($){try{return Vf($,"utf-8")}catch{return""}}function Pf($){try{let I=$u($);if(I.includes("orchestrator-session.md"))return j4($,"orchestrator-session.md");let U=I.filter((_)=>/^session-.*\.md$/.test(_)).map((_)=>({name:_,mtime:h9(j4($,_)).mtimeMs})).sort((_,u)=>u.mtime-_.mtime);if(U.length>0&&U[0])return j4($,U[0].name)}catch{}return null}function Zf($){let I=Pf($);if(!I)return{id:"N/A",status:"UNKNOWN"};let U=Iu(I);if(!U)return{id:"N/A",status:"UNKNOWN"};let _=(U.match(/session-id:\s*(.+)/i)||[])[1]||(U.match(/# Session:\s*(.+)/i)||[])[1]||U.match(/(session-\d{8}-\d{6})/)?.[1]||Df(I,".md"),u="UNKNOWN";if(/IN PROGRESS|RUNNING|## Active|\[IN PROGRESS\]/i.test(U))u="RUNNING";else if(/COMPLETED|DONE|## Completed|\[COMPLETED\]/i.test(U))u="COMPLETED";else if(/FAILED|ERROR|## Failed|\[FAILED\]/i.test(U))u="FAILED";else if(/Step \d+:.*\[/i.test(U))u="RUNNING";return{id:(_||"N/A").trim(),status:u}}function Af($){let I=Iu(j4($,"task-board.md"));if(!I)return[];let U=[],_=I.split(`
|
|
496
496
|
`);for(let u of _){if(!u.startsWith("|")||/^\|\s*-+/.test(u))continue;let g=u.split("|").map((N)=>N.trim()).filter(Boolean),z=g[0];if(g.length<2||!z||/^agent$/i.test(z))continue;let v=g[1],J=g[2];U.push({agent:z,status:v||"pending",task:J||""})}return U}function m9($,I){try{let U=$u($).filter((g)=>g.startsWith(`progress-${I}`)&&g.endsWith(".md")).sort().reverse();if(U.length===0||!U[0])return null;let u=Iu(j4($,U[0])).match(/turn[:\s]*(\d+)/i);return u?.[1]?parseInt(u[1],10):null}catch{return null}}function bf($){try{let I=$u($).filter((_)=>_.endsWith(".md")&&_!==".gitkeep").map((_)=>({name:_,mtime:h9(j4($,_)).mtimeMs})).sort((_,u)=>u.mtime-_.mtime).slice(0,5),U=[];for(let _ of I){let u=_.name.replace(/^(progress|result|session|debug|task)-?/,"").replace(/[-_]agent/,"").replace(/[-_]completion/,"").replace(/\.md$/,"").replace(/[-_]/g," ").trim()||_.name.replace(/\.md$/,""),z=Iu(j4($,_.name)).split(`
|
|
497
497
|
`).map((J)=>J.trim()).filter((J)=>J&&!J.startsWith("---")&&J.length>3),v="";for(let J=z.length-1;J>=0;J--){let N=z[J];if(!N)continue;if(/^\*\*|^#+|^-|^\d+\.|Status|Result|Action|Step/i.test(N)){if(v=N.replace(/^[#*\-\d.]+\s*/,"").replace(/\*\*/g,"").trim(),v.length>5)break}}if(v.length>52)v=`${v.substring(0,49)}...`;if(v)U.push({agent:u,message:v})}return U}catch{return[]}}function jf($){let I=[],U=new Set;try{let _=$u($).filter((u)=>u.endsWith(".md")&&u!==".gitkeep").map((u)=>({name:u,mtime:h9(j4($,u)).mtimeMs})).sort((u,g)=>g.mtime-u.mtime);for(let u of _){let g=Iu(j4($,u.name)),z=g.match(/\*\*Agent\*\*:\s*(.+)/i)||g.match(/Agent:\s*(.+)/i)||g.match(/^#+\s*(.+?)\s*Agent/im),v=null;if(z?.[1])v=z[1].trim();else if(/_agent|agent_|-agent/i.test(u.name))v=u.name.replace(/\.md$/,"").replace(/[-_]completion|[-_]progress|[-_]result/gi,"").replace(/[-_]/g," ").trim();if(v&&!U.has(v.toLowerCase())){U.add(v.toLowerCase());let J="unknown";if(/\[COMPLETED\]|## Completed|## Results/i.test(g))J="completed";else if(/\[IN PROGRESS\]|## Progress|IN PROGRESS/i.test(g))J="running";else if(/\[FAILED\]|## Failed|ERROR/i.test(g))J="failed";let N=g.match(/## Task\s*\n+(.+)/i)||g.match(/\*\*Task\*\*:\s*(.+)/i),X=N?.[1]?N[1].trim().substring(0,20):"";I.push({agent:v,status:J,task:X,turn:m9($,v)})}}}catch{}return I}function Ff($){let I=$.toLowerCase();if(["running","active","in_progress","in-progress"].includes(I))return`${r$.default.green(Bf)} running`;else if(["completed","done","finished"].includes(I))return`${r$.default.cyan(Mf)} completed`;else if(["failed","error"].includes(I))return`${r$.default.red(Kf)} failed`;else if(["blocked","waiting"].includes(I))return`${r$.default.yellow(Rf)} blocked`;return`${r$.default.dim(Lf)} pending`}function PO($){console.clear();let I=Zf($),_=Af($).map((Q)=>({...Q,turn:m9($,Q.agent)}));if(_.length===0)_=jf($);if(_.length===0)try{let Q=$u($).filter((Y)=>Y.startsWith("progress-")&&Y.endsWith(".md"));for(let Y of Q){let K=Y.replace(/^progress-/,"").replace(/\.md$/,"");_.push({agent:K,status:"running",task:"",turn:m9($,K)})}}catch{}let u=56,g="═".repeat(u),z=(Q)=>" ".repeat(Math.max(0,Q)),v=(Q)=>r$.default.magenta(Q),J=(Q)=>r$.default.bold(Q),N=(Q)=>r$.default.dim(Q),X=r$.default.yellow;if(I.status==="RUNNING")X=r$.default.green;else if(I.status==="COMPLETED")X=r$.default.cyan;else if(I.status==="FAILED")X=r$.default.red;console.log(`${v(`╔${g}╗`)}`),console.log(`${v("║")} ${J(v("Serena Memory Dashboard"))}${z(u-25)}${v("║")}`);let G=`Session: ${J(I.id.padEnd(20))} [${X(I.status)}]`;if(console.log(`${v("║")} ${G}${z(u-4-G.length-9)}${v("║")}`),console.log(`${v(`╠${g}╣`)}`),console.log(`${v("║")} ${J(`${"Agent".padEnd(12)} ${"Status".padEnd(12)} ${"Turn".padEnd(6)} ${"Task".padEnd(20)}`)} ${v("║")}`),console.log(`${v("║")} ${N(`${"──────────".padEnd(12)} ${"──────────".padEnd(12)} ${"────".padEnd(6)} ${"──────────────────".padEnd(20)}`)} ${v("║")}`),_.length===0)console.log(`${v("║")} ${N(`No agents detected yet${z(32)}`)}${v("║")}`);else for(let Q of _){let Y=Ff(Q.status),K=Q.turn!=null?String(Q.turn):"-",R=Q.task.substring(0,20);console.log(`${v("║")} ${Q.agent.padEnd(12)} ${Y.padEnd(22)} ${K.padEnd(6)} ${R.padEnd(20)}${v("║")}`)}console.log(`${v(`╠${g}╣`)}`),console.log(`${v("║")} ${J("Latest Activity:")}${z(u-18)}${v("║")}`);let q=bf($);if(q.length===0)console.log(`${v("║")} ${N(`No activity yet${z(38)}`)}${v("║")}`);else for(let Q of q){let Y=`[${Q.agent}] ${Q.message}`;console.log(`${v("║")} ${N(Y.substring(0,52).padEnd(52))}${v("║")}`)}console.log(`${v(`╠${g}╣`)}`);let H=`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(`${v("║")} ${N(H)}${z(u-4-H.length)}${v("║")}`),console.log(`${v(`╚${g}╝`)}`)}async function ZO(){let $=Wf();if(!Yf($))Of($,{recursive:!0}),console.log(r$.default.yellow(`Created ${$} — waiting for memory files...`));console.log(r$.default.magenta(`
|
|
498
498
|
\uD83D\uDEF8 Serena Terminal Dashboard`)),console.log(r$.default.dim(` Watching: ${$}
|
package/package.json
CHANGED