oh-my-agent 4.6.0 → 4.7.0
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 +9 -0
- package/bin/cli.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -138,6 +138,13 @@ You'll also need at least one CLI tool:
|
|
|
138
138
|
→ Analyze changes, suggest commit type/scope, create commit with Co-Author
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
+
**Design system** (DESIGN.md + anti-patterns + optional Stitch MCP):
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
/design
|
|
145
|
+
→ 7-phase workflow: Setup → Extract → Enhance → Propose → Generate → Audit → Handoff
|
|
146
|
+
```
|
|
147
|
+
|
|
141
148
|
### 3. Monitor with Dashboards
|
|
142
149
|
|
|
143
150
|
For dashboard setup and usage details, see [`web/content/en/guide/usage.md`](https://github.com/first-fluke/oh-my-agent/blob/main/web/content/en/guide/usage.md#real-time-dashboards).
|
|
@@ -158,6 +165,7 @@ flowchart TD
|
|
|
158
165
|
W4["/review"]
|
|
159
166
|
W5["/debug"]
|
|
160
167
|
W6["/deepinit"]
|
|
168
|
+
W7["/design"]
|
|
161
169
|
end
|
|
162
170
|
|
|
163
171
|
subgraph Orchestration["Orchestration"]
|
|
@@ -172,6 +180,7 @@ flowchart TD
|
|
|
172
180
|
BE[oma-backend]
|
|
173
181
|
DB[oma-db]
|
|
174
182
|
MB[oma-mobile]
|
|
183
|
+
DES[oma-design]
|
|
175
184
|
TF[oma-tf-infra]
|
|
176
185
|
end
|
|
177
186
|
|
package/bin/cli.js
CHANGED
|
@@ -475,7 +475,7 @@ source: migrated
|
|
|
475
475
|
</html>`;function JY(){let $=kf();if(!nf($))xf($,{recursive:!0});let u=rf((v,z)=>{if(v.url==="/api/state")z.writeHead(200,{"Content-Type":"application/json"}),z.end(JSON.stringify(D9($)));else z.writeHead(200,{"Content-Type":"text/html"}),z.end(of)}),g=new Y9.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:D9($)});g.clients.forEach((J)=>{if(J.readyState===H9.default.OPEN)J.send(N)})},100)}let _=z_($,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:200,pollInterval:50}});_.on("all",(v,z)=>I(v,NY(z))),g.on("connection",(v)=>{v.send(JSON.stringify({type:"full",data:D9($)})),v.on("error",()=>v.terminate())}),process.on("SIGINT",()=>{console.log(`
|
|
476
476
|
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(zY,()=>{console.log(X6.magenta(`
|
|
477
477
|
\uD83D\uDEF8 Serena Memory Dashboard`)),console.log(X6.white(` http://localhost:${zY}`)),console.log(X6.dim(` Watching: ${$}
|
|
478
|
-
`))})}var GY={name:"oh-my-agent",version:"4.
|
|
478
|
+
`))})}var GY={name:"oh-my-agent",version:"4.7.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:["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 tf,mkdirSync as af,readdirSync as kI,readFileSync as ef,statSync as P9}from"node:fs";import{basename as sf,join as Ku}from"node:path";var x$=G$(W$(),1),$C="●",uC="✓",IC="✗",gC="○",UC="◌";function _C(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let $=process.argv[3];if($)return Ku($,".serena","memories");return Ku(process.cwd(),".serena","memories")}function yI($){try{return ef($,"utf-8")}catch{return""}}function vC($){try{let u=kI($);if(u.includes("orchestrator-session.md"))return Ku($,"orchestrator-session.md");let g=u.filter((U)=>/^session-.*\.md$/.test(U)).map((U)=>({name:U,mtime:P9(Ku($,U)).mtimeMs})).sort((U,I)=>I.mtime-U.mtime);if(g.length>0&&g[0])return Ku($,g[0].name)}catch{}return null}function zC($){let u=vC($);if(!u)return{id:"N/A",status:"UNKNOWN"};let g=yI(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]||sf(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 NC($){let u=yI(Ku($,"task-board.md"));if(!u)return[];let g=[],U=u.split(`
|
|
479
479
|
`);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 R9($,u){try{let g=kI($).filter((_)=>_.startsWith(`progress-${u}`)&&_.endsWith(".md")).sort().reverse();if(g.length===0||!g[0])return null;let I=yI(Ku($,g[0])).match(/turn[:\s]*(\d+)/i);return I?.[1]?parseInt(I[1],10):null}catch{return null}}function JC($){try{let u=kI($).filter((U)=>U.endsWith(".md")&&U!==".gitkeep").map((U)=>({name:U,mtime:P9(Ku($,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=yI(Ku($,U.name)).split(`
|
|
480
480
|
`).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 GC($){let u=[],g=new Set;try{let U=kI($).filter((I)=>I.endsWith(".md")&&I!==".gitkeep").map((I)=>({name:I,mtime:P9(Ku($,I)).mtimeMs})).sort((I,_)=>_.mtime-I.mtime);for(let I of U){let _=yI(Ku($,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),q=J?.[1]?J[1].trim().substring(0,20):"";u.push({agent:z,status:N,task:q,turn:R9($,z)})}}}catch{}return u}function qC($){let u=$.toLowerCase();if(["running","active","in_progress","in-progress"].includes(u))return`${x$.default.green($C)} running`;else if(["completed","done","finished"].includes(u))return`${x$.default.cyan(uC)} completed`;else if(["failed","error"].includes(u))return`${x$.default.red(IC)} failed`;else if(["blocked","waiting"].includes(u))return`${x$.default.yellow(gC)} blocked`;return`${x$.default.dim(UC)} pending`}function qY($){console.clear();let u=zC($),U=NC($).map((Q)=>({...Q,turn:R9($,Q.agent)}));if(U.length===0)U=GC($);if(U.length===0)try{let Q=kI($).filter((H)=>H.startsWith("progress-")&&H.endsWith(".md"));for(let H of Q){let M=H.replace(/^progress-/,"").replace(/\.md$/,"");U.push({agent:M,status:"running",task:"",turn:R9($,M)})}}catch{}let I=56,_="═".repeat(I),v=(Q)=>" ".repeat(Math.max(0,Q)),z=(Q)=>x$.default.magenta(Q),N=(Q)=>x$.default.bold(Q),J=(Q)=>x$.default.dim(Q),q=x$.default.yellow;if(u.status==="RUNNING")q=x$.default.green;else if(u.status==="COMPLETED")q=x$.default.cyan;else if(u.status==="FAILED")q=x$.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))} [${q(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 H=qC(Q.status),M=Q.turn!=null?String(Q.turn):"-",Y=Q.task.substring(0,20);console.log(`${z("║")} ${Q.agent.padEnd(12)} ${H.padEnd(22)} ${M.padEnd(6)} ${Y.padEnd(20)}${z("║")}`)}console.log(`${z(`╠${_}╣`)}`),console.log(`${z("║")} ${N("Latest Activity:")}${v(I-18)}${z("║")}`);let X=JC($);if(X.length===0)console.log(`${z("║")} ${J(`No activity yet${v(38)}`)}${z("║")}`);else for(let Q of X){let H=`[${Q.agent}] ${Q.message}`;console.log(`${z("║")} ${J(H.substring(0,52).padEnd(52))}${z("║")}`)}console.log(`${z(`╠${_}╣`)}`);let O=`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(O)}${v(I-4-O.length)}${z("║")}`),console.log(`${z(`╚${_}╝`)}`)}async function XY(){let $=_C();if(!tf($))af($,{recursive:!0}),console.log(x$.default.yellow(`Created ${$} — waiting for memory files...`));console.log(x$.default.magenta(`
|
|
481
481
|
\uD83D\uDEF8 Serena Terminal Dashboard`)),console.log(x$.default.dim(` Watching: ${$}
|
package/package.json
CHANGED