oh-my-agent 5.4.3 → 5.4.4

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
@@ -833,7 +833,7 @@ source: migrated
833
833
  `).filter(Boolean),$=[];for(let x of m)if(!r.some((v)=>x.startsWith(v)))$.push(x);if($.length>0)return d("Scope Check","fail",`${$.length} out-of-scope: ${$[0]}${$.length>1?` +${$.length-1}`:""}`);return d("Scope Check","pass",`All ${m.length} files in scope`)}function Fui(i,n){let u=jui(i,n);if(!u)return d("Charter Preflight","skip","Result file not found");let o=d8(u,"utf-8");if(!o.includes("CHARTER_CHECK:"))return d("Charter Preflight","warn","Block missing from result");if(/\{[^}]+\}/.test(o.split("CHARTER_CHECK:")[1]?.split("```")[0]||""))return d("Charter Preflight","warn","Contains unfilled placeholders");return d("Charter Preflight","pass","Properly filled")}function Dui(i){let n=["*.py","*.ts","*.tsx","*.js","*.dart"],u=`(password|secret|api_key|token)\\s*=\\s*['"][^'"]{8,}`;for(let o of n){let c=si(`grep -rn --include="${o}" -E "(password|secret|api_key|token)\\s*=\\s*['"][^'"]{8,}" . 2>/dev/null | grep -v test | grep -v example | grep -v node_modules | head -1`,i);if(c)return d("Hardcoded Secrets","fail",`Found in: ${c.split(":")[0]}`)}return d("Hardcoded Secrets","pass","None detected")}function Eui(i){let n=si('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',i),u=Number.parseInt(n||"0",10);if(u>0)return d("TODO/FIXME Comments","warn",`${u} found`);return d("TODO/FIXME Comments","pass","None found")}function Cui(i){if(!si("which uv",i))return d("Python Syntax","skip","uv not available");let u=si('find . -name "*.py" -not -path "*/node_modules/*" -not -path "*/.venv/*" -exec uv run python -m py_compile {} \\; 2>&1 | head -5',i);if(u&&u.length>0)return d("Python Syntax","fail","Syntax errors found");return d("Python Syntax","pass","Valid")}function tui(i){if(si(`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`,i))return d("SQL Injection","fail","f-string with SQL keywords detected");return d("SQL Injection","pass","None detected")}function cB(i){let n=si("which uv",i),u=vc(Fu(i,"pyproject.toml"));if(!n||!u)return d("Python Tests","skip",!n?"uv not available":"pyproject.toml not found");let o=si("uv run pytest -q --tb=no 2>&1",i);if(o?.includes("passed")||o?.includes("no tests ran"))return d("Python Tests","pass","Tests pass");return d("Python Tests","fail","Tests failing")}function dui(i){if(!vc(Fu(i,"tsconfig.json")))return d("TypeScript","skip","Not configured");let n=si("npx tsc --noEmit 2>&1",i);if(n===null||n==="")return d("TypeScript","pass","Compilation clean");if(n.includes("error"))return d("TypeScript","fail","Type errors found");return d("TypeScript","pass","Compilation clean")}function yui(i){let n=si(`grep -rn --include="*.tsx" --include="*.jsx" 'style={{' . 2>/dev/null | grep -v node_modules | wc -l`,i),u=Number.parseInt(n||"0",10);if(u>0)return d("Inline Styles","warn",`${u} found (prefer Tailwind)`);return d("Inline Styles","pass","None found")}function kui(i){let n=si(`grep -rn --include="*.ts" --include="*.tsx" ': any' . 2>/dev/null | grep -v node_modules | grep -v ".d.ts" | wc -l`,i),u=Number.parseInt(n||"0",10);if(u>3)return d("Any Types","fail",`${u} found (limit: 3)`);if(u>0)return d("Any Types","warn",`${u} found`);return d("Any Types","pass","None found")}function oB(i){if(!vc(Fu(i,"package.json")))return d("Frontend Tests","skip","No package.json");let n=si("npx vitest run --reporter=verbose 2>&1",i);if(n?.includes("passed")||n?.includes("✓"))return d("Frontend Tests","pass","Tests pass");return d("Frontend Tests","warn","Tests failed or vitest not configured")}function hui(i){if(!si("which flutter",i)){if(!si("which dart",i))return d("Flutter/Dart Analysis","skip","Not available");if(si("dart analyze 2>&1",i)?.includes("No issues found"))return d("Dart Analysis","pass","Clean");return d("Dart Analysis","fail","Issues found")}if(si("flutter analyze 2>&1",i)?.includes("No issues found"))return d("Flutter Analysis","pass","Clean");return d("Flutter Analysis","fail","Issues found")}function sui(i){if(!si("which flutter",i))return d("Flutter Tests","skip","Flutter not available");if(si("flutter test 2>&1",i)?.includes("All tests passed"))return d("Flutter Tests","pass","All tests pass");return d("Flutter Tests","fail","Tests failed")}function lB(i){let n=Fu(i,".agents","results");if(vc(n))try{let o=rB(n).filter((c)=>c.startsWith("plan-")&&c.endsWith(".json")).sort().reverse();if(o.length>0&&o[0])return Fu(n,o[0])}catch{}let u=Fu(i,".agents","plan.json");return vc(u)?u:null}function eui(i){let n=lB(i);if(!n)return d("PM Plan","warn","No plan file found");try{return JSON.parse(d8(n,"utf-8")),d("PM Plan","pass","Valid JSON")}catch{return d("PM Plan","fail","Invalid JSON")}}function ici(i,n){let u=[];switch(i){case"backend":u.push(Cui(n)),u.push(tui(n)),u.push(cB(n));break;case"frontend":u.push(dui(n)),u.push(yui(n)),u.push(kui(n)),u.push(oB(n));break;case"mobile":u.push(hui(n)),u.push(sui(n));break;case"qa":u.push(d("QA Report","pass","Verified by self-check.md"));break;case"debug":if(vc(Fu(n,"pyproject.toml")))u.push(cB(n));else if(vc(Fu(n,"package.json")))u.push(oB(n));else u.push(d("Debug Tests","skip","No test runner detected"));break;case"pm":u.push(eui(n));break}return u}async function mB(i,n,u=!1){let o=i.toLowerCase();if(!uB.includes(o)){let b=`Invalid agent type: ${i}. Valid types: ${uB.join(", ")}`;if(u)console.log(JSON.stringify({ok:!1,error:b}));else wi.error(b);process.exit(2)}let c=n||process.cwd();if(!vc(c)){let b=`Workspace not found: ${c}`;if(u)console.log(JSON.stringify({ok:!1,error:b}));else wi.error(b);process.exit(2)}let r=[];r.push(Sui(c,o)),r.push(Fui(c,o)),r.push(Dui(c)),r.push(Eui(c)),r.push(...ici(o,c));let l=r.filter((b)=>b.status==="pass").length,m=r.filter((b)=>b.status==="fail").length,$=r.filter((b)=>b.status==="warn").length,x={ok:m===0,agent:o,workspace:c,checks:r,summary:{passed:l,failed:m,warned:$}};if(u)console.log(JSON.stringify(x,null,2)),process.exit(m>0?1:0);console.clear(),Wi(bn.default.bgCyan(bn.default.white(` \uD83D\uDD0D Verify: ${o} agent `))),S(bn.default.dim(c),"Workspace");let p=["┌────────────────────────────┬────────┬─────────────────────────────┐",`│ ${bn.default.bold("Check")} │ ${bn.default.bold("Status")} │ ${bn.default.bold("Details")} │`,"├────────────────────────────┼────────┼─────────────────────────────┤",...r.map((b)=>{let I;switch(b.status){case"pass":I=bn.default.green("PASS");break;case"fail":I=bn.default.red("FAIL");break;case"warn":I=bn.default.yellow("WARN");break;default:I=bn.default.dim("SKIP")}let a=b.name.padEnd(26),g=I.padEnd(6),_=(b.message||"-").slice(0,27).padEnd(27);return`│ ${a} │ ${g} │ ${_} │`}),"└────────────────────────────┴────────┴─────────────────────────────┘"].join(`
834
834
  `);console.log(p),console.log();let v=`${bn.default.green(`${l} passed`)}, ${bn.default.red(`${m} failed`)}, ${bn.default.yellow(`${$} warnings`)}`;if(m>0)ii(bn.default.red(`❌ Verification failed: ${v}`)),process.exit(1);ii(bn.default.green(`✅ Verification passed: ${v}`)),process.exit(0)}var Ti=ai(Ri(),1);import{existsSync as nci,readdirSync as $B,readFileSync as uci}from"node:fs";import{join as Qu}from"node:path";var xB=Object.fromEntries(Object.entries(On).map(([i,n])=>[i,n.map((u)=>u.name)])),cci={"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","architecture-reviewer":"oma-architecture","tf-infra-engineer":"oma-tf-infra"};function y8(i){let n=new Set;for(let u of i.matchAll(/_shared\/((?:[a-z][a-z0-9_-]*\/)*[a-z][a-z0-9_-]*)(?:\.md)?(?=[`)\s/}]|$)/gi))if(u[1])n.add(u[1]);return[...n]}function u4(i){try{return uci(i,"utf-8")}catch{return""}}function k8(i){try{return $B(i).filter((n)=>!n.startsWith("."))}catch{return[]}}function oci(i){try{return $B(i,{withFileTypes:!0}).filter((n)=>!n.name.startsWith("."))}catch{return[]}}function pB(i,n=""){let u=[];for(let o of oci(i)){let c=n?`${n}/${o.name}`:o.name;if(o.isDirectory()){u.push({path:c,isDirectory:!0}),u.push(...pB(Qu(i,o.name),c));continue}if(!o.name.endsWith(".md"))continue;u.push({path:c.replace(/\.md$/,""),isDirectory:!1})}return u}function vB(i){let n=[{id:"root",label:"oh-my-agent",category:"root"}],u=new Set,o=[];function c(v,b,I){let a=`${v}|${b}`;if(u.has(a))return;u.add(a),o.push({from:v,to:b,type:I})}let r=Qu(i,".agents","skills");for(let[v,b]of Object.entries(xB))for(let I of b){let a=Qu(r,I);if(!nci(a))continue;let g=`skill:${I}`;n.push({id:g,label:I,category:"skill",group:"Skills",subgroup:v});let _=[u4(Qu(a,"SKILL.md")),u4(Qu(a,"resources","execution-protocol.md"))].join(`
835
835
  `);for(let U of y8(_))c(g,`shared:${U}`,"references")}let l=Qu(i,".agents","workflows");for(let v of k8(l).filter((b)=>b.endsWith(".md"))){let b=v.replace(".md",""),I=`workflow:${b}`;n.push({id:I,label:b,category:"workflow",group:"Workflows"});for(let a of y8(u4(Qu(l,v))))c(I,`shared:${a}`,"references")}let m=Qu(r,"_shared");for(let v of pB(m)){let b=`shared:${v.path}`;if(n.push({id:b,label:v.path,category:"shared",group:"Shared"}),!v.isDirectory){for(let I of y8(u4(Qu(m,`${v.path}.md`))))if(I!==v.path)c(b,`shared:${I}`,"references")}}let $=Qu(i,".claude","agents");for(let v of k8($).filter((b)=>b.endsWith(".md"))){let b=v.replace(".md",""),I=`agent:${b}`;n.push({id:I,label:b,category:"agent",group:"Claude Agents"});let a=cci[b];if(a)c(I,`skill:${a}`,"implements")}let x=Qu(i,".serena","memories");for(let v of k8(x).filter((b)=>b.endsWith(".md")))n.push({id:`memory:${v.replace(".md","")}`,label:v.replace(".md",""),category:"memory",group:"Serena Memories"});let p=new Set(n.map((v)=>v.id));return{nodes:n,edges:o.filter((v)=>p.has(v.from)&&p.has(v.to))}}var rci={root:(i)=>Ti.default.bold(Ti.default.white(i)),skill:Ti.default.green,workflow:Ti.default.blue,shared:Ti.default.yellow,agent:Ti.default.magenta,memory:Ti.default.cyan};function En(i,n){return(rci[n]??Ti.default.white)(i)}function Du(...i){let n=i.sort((c,r)=>c[0]-r[0]),u="",o=0;for(let[c,r,l]of n){if(c>o)u+=" ".repeat(c-o);u+=r,o=c+l}return u}function lci(i){let n=[],u=i.nodes.filter((W)=>W.category==="skill").length,o=i.nodes.filter((W)=>W.category==="workflow").length,c=i.nodes.filter((W)=>W.category==="shared").length,r=i.nodes.filter((W)=>W.category==="agent").length,l=i.nodes.filter((W)=>W.category==="memory").length,m=i.edges.filter((W)=>W.from.startsWith("skill:")&&W.to.startsWith("shared:")).length,$=i.edges.filter((W)=>W.from.startsWith("workflow:")&&W.to.startsWith("shared:")).length,x=i.edges.filter((W)=>W.type==="implements").length,p=i.edges.filter((W)=>W.from.startsWith("shared:")&&W.to.startsWith("shared:")).length,v=`Skills (${u})`,b=`Workflows (${o})`,I=`Shared (${c})`,a=`Agents (${r})`,g=`Memories (${l})`,_=10,U=29,G=48,w=19;n.push(Du([24,En("oh-my-agent","root"),11])),n.push(Du([29,"│",1]));let z=Array(49).fill(" ");z[10]="┌",z[29]="┼",z[48]="┐";for(let W=11;W<48;W++)if(W!==29)z[W]="─";n.push(z.join("")),n.push(Du([10,"▼",1],[29,"▼",1],[48,"▼",1])),n.push(Du([10-(v.length>>1),En(v,"skill"),v.length],[29-(b.length>>1),En(b,"workflow"),b.length],[48-(g.length>>1),En(g,"memory"),g.length])),n.push(Du([10,"│",1],[29,"│",1]));let Y=`${m} refs`,X=`${$} refs`;n.push(Du([10-(Y.length>>1),Ti.default.dim(Y),Y.length],[29-(X.length>>1),Ti.default.dim(X),X.length])),n.push(Du([10,"│",1],[29,"│",1]));let f=Array(30).fill(" ");f[10]="└",f[19]="┬",f[29]="┘";for(let W=11;W<29;W++)if(W!==19)f[W]="─";n.push(f.join("")),n.push(Du([19,"▼",1]));let Q=19-(I.length>>1),V=Du([Q,En(I,"shared"),I.length]);if(p>0)V+=` ${Ti.default.dim(`◂── ${p} internal`)}`;n.push(V),n.push("");let R=10-(a.length>>1),F=`──[${x} implements]──▸`;return n.push(Du([R,En(a,"agent"),a.length])+` ${Ti.default.dim(F)} ${En("Skills","skill")}`),n}function bB(i){let n=[];n.push(...lci(i)),n.push(""),n.push(Ti.default.dim("─".repeat(56))),n.push("");let u=new Map,o=new Map;for(let v of i.edges){if(!u.has(v.from))u.set(v.from,[]);if(u.get(v.from)?.push(v),v.to.startsWith("shared:"))o.set(v.to,(o.get(v.to)??0)+1)}function c(v){let b=u.get(v);if(!b?.length)return"";let I=b.map((g)=>i.nodes.find((_)=>_.id===g.to)?.label.replace(/\.md$/,"")??g.to.split(":")[1]),a=I.length>4?`${I.slice(0,3).join(", ")} +${I.length-3}`:I.join(", ");return` ${Ti.default.dim("──▸")} ${Ti.default.dim(a)}`}let r=i.nodes.filter((v)=>v.category==="skill"),l=Object.keys(xB);n.push(Ti.default.bold(`Skills (${r.length})`));for(let v=0;v<l.length;v++){let b=l[v],I=r.filter((_)=>_.subgroup===b);if(!I.length)continue;let a=v===l.length-1;n.push(`${a?"└─":"├─"} ${Ti.default.dim(b)}`);let g=a?" ":"│ ";for(let _ of I){let U=_===I.at(-1)?"└─":"├─";n.push(`${g}${U} ${En(_.label,"skill")}${c(_.id)}`)}}n.push("");let m=i.nodes.filter((v)=>v.category==="workflow");n.push(Ti.default.bold(`Workflows (${m.length})`));for(let v of m){let b=v===m.at(-1)?"└─":"├─";n.push(`${b} ${En(v.label,"workflow")}${c(v.id)}`)}n.push("");let $=[...i.nodes.filter((v)=>v.category==="shared")].sort((v,b)=>(o.get(b.id)??0)-(o.get(v.id)??0));n.push(Ti.default.bold(`Shared (${$.length})`));for(let v of $){let b=v===$.at(-1)?"└─":"├─",I=o.get(v.id)??0,a=I>0?Ti.default.dim(` (${I} refs)`):"";n.push(`${b} ${En(v.label,"shared")}${a}${c(v.id)}`)}n.push("");let x=i.nodes.filter((v)=>v.category==="agent");n.push(Ti.default.bold(`Claude Agents (${x.length})`));for(let v of x){let b=v===x.at(-1)?"└─":"├─",I=i.edges.find((g)=>g.from===v.id&&g.type==="implements"),a=I?` ${Ti.default.dim("──▸")} ${En(I.to.split(":")[1]??"","skill")}`:"";n.push(`${b} ${En(v.label,"agent")}${a}`)}n.push("");let p=i.nodes.filter((v)=>v.category==="memory");if(n.push(Ti.default.bold(`Serena Memories (${p.length})`)),!p.length)n.push(`└─ ${Ti.default.dim("(none)")}`);else for(let v of p){let b=v===p.at(-1)?"└─":"├─";n.push(`${b} ${En(v.label,"memory")}`)}return n.join(`
836
- `)}async function aB(i){let n=vB(process.cwd());if(i.json){console.log(JSON.stringify(n,null,2));return}console.log(bB(n))}var UB="OH_MY_AG_OUTPUT_FORMAT",h$=["text","json"],IB=["gemini","claude","codex","qwen"],gB=["backend","frontend","mobile","qa","debug","pm"];function qu(i,n="Output as JSON"){return i.option("--json",n).option("--output <format>","Output format (text/json)",(u)=>{let o=u.trim().toLowerCase();if(!h$.includes(o))throw Error(`Invalid output format: ${u}. Expected one of ${h$.join(", ")}`);return o})}function mci(i){if(i?.json)return"json";let n=i?.output?.trim().toLowerCase();if(n&&h$.includes(n))return n;if(process.env[UB]?.trim().toLowerCase()==="json")return"json";return"text"}function mu(i){return mci(i)==="json"}function wB(i){let n=i.at(-1);return n instanceof cx?n:null}function $ci(i){let n=wB(i);if(n)return n.opts();let u=i.at(-1);return u&&typeof u==="object"?u:{}}function xci(i){if(i instanceof Error)return i.message;return String(i)}function ec(i){throw Error(i)}function s8(i,n){for(let u of i){let o=u.charCodeAt(0);if(o>=0&&o<=31||o===127)ec(`${n} must not contain control characters`)}}function pci(i,n){if(s8(i,n),/[?#%]/.test(i))ec(`${n} must not contain ?, #, or %`);if(i.includes(".."))ec(`${n} must not contain '..'`)}function vci(i,n){s8(i,n);try{new URL(i)}catch{ec(`${n} must be a valid absolute URL`)}}function h8(i,n,u="text"){if(typeof i==="string"){if(u==="identifier"){pci(i,n);return}if(u==="url"){vci(i,n);return}s8(i,n);return}if(Array.isArray(i))for(let[o,c]of i.entries())h8(c,`${n}[${o}]`,u)}function _B(i){let n=i.toLowerCase();if(n==="url"||n.endsWith("url"))return"url";if(n.includes("id")||n.includes("type")||n.includes("vendor")||n.includes("session"))return"identifier";return"text"}function bci(i){let n=i.vendor;if(typeof n==="string"&&!IB.includes(n))ec(`vendor must be one of ${IB.join(", ")}`);let u=i.output;if(typeof u==="string"&&!h$.includes(u))ec(`output must be one of ${h$.join(", ")}`)}function aci(i){let n=i.processedArgs??i.args??[];(i.registeredArguments??[]).forEach((c,r)=>{let l=c.name?.()||String(r),m=n[r];if(h8(m,l,_B(l)),l==="agent-type"&&typeof m==="string"&&!gB.includes(m))ec(`agent-type must be one of ${gB.join(", ")}`)});let o=i.opts();bci(o);for(let[c,r]of Object.entries(o))h8(r,c,_B(c))}function Ici(i){return(i.registeredArguments??[]).map((n)=>({name:n.name?.()||"",required:!!n.required,variadic:!!n.variadic}))}function gci(i){return i.options.map((n)=>({flags:n.flags,long:n.long||void 0,short:n.short||void 0,description:n.description||"",required:!!n.required||!!n.mandatory,optional:!!n.optional,defaultValue:n.defaultValue}))}function JB(i){let n=[],u=i;while(u?.parent)n.unshift(u.name()),u=u.parent;return n.join(" ")}function _ci(i){return i.options.some((n)=>n.long==="--json"||n.long==="--output")}function Uci(i){return i.options.some((n)=>n.long==="--dry-run")}function GB(i){return{name:i.name(),path:JB(i),summary:i.summary()||void 0,description:i.description(),arguments:Ici(i),options:gci(i),supportsJsonOutput:_ci(i),supportsDryRun:Uci(i),subcommands:i.commands.map((n)=>GB(n))}}function wci(i,n){if(!n?.trim())return i;let u=n.trim(),o=[...i.commands];while(o.length>0){let c=o.shift();if(!c)continue;if(c.name()===u||JB(c)===u)return c;o.push(...c.commands)}return null}function fB(i,n){let u=wci(i,n);if(!u)ec(`Unknown command: ${n}`);let o={name:i.name(),version:i.version(),description:i.description(),env:{[UB]:"Set to json to force machine-readable output on commands that support it."},command:GB(u)};console.log(JSON.stringify(o,null,2))}function Ki(i,n={}){return async(...u)=>{let o=wB(u),c=$ci(u);try{if(o)aci(o);await i(...u)}catch(r){let l=xci(r);if(n.supportsJsonOutput&&mu(c))console.log(JSON.stringify({error:l},null,2));else console.error(l);process.exitCode=1}}}var zB={name:"oh-my-agent",version:"5.4.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-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",axios:"^1.15.0","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/ws":"^8.18.1",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"]}};import{existsSync as Gci,mkdirSync as fci,readdirSync as s$,readFileSync as zci,statSync as i5}from"node:fs";import{basename as Nci,join as Yu}from"node:path";var an=ai(Ri(),1),Xci="●",Qci="✓",qci="✗",Yci="○",Hci="◌";function Mci(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let i=process.argv[3];if(i)return Yu(i,".serena","memories");return Yu(process.cwd(),".serena","memories")}function e$(i){try{return zci(i,"utf-8")}catch{return""}}function Bci(i){try{let n=s$(i);if(n.includes("orchestrator-session.md"))return Yu(i,"orchestrator-session.md");let u=n.filter((o)=>/^session-.*\.md$/.test(o)).map((o)=>({name:o,mtime:i5(Yu(i,o)).mtimeMs})).sort((o,c)=>c.mtime-o.mtime);if(u.length>0&&u[0])return Yu(i,u[0].name)}catch{}return null}function Kci(i){let n=Bci(i);if(!n)return{id:"N/A",status:"UNKNOWN"};let u=e$(n);if(!u)return{id:"N/A",status:"UNKNOWN"};let o=(u.match(/session-id:\s*(.+)/i)||[])[1]||(u.match(/# Session:\s*(.+)/i)||[])[1]||u.match(/(session-\d{8}-\d{6})/)?.[1]||Nci(n,".md"),c="UNKNOWN";if(/IN PROGRESS|RUNNING|## Active|\[IN PROGRESS\]/i.test(u))c="RUNNING";else if(/COMPLETED|DONE|## Completed|\[COMPLETED\]/i.test(u))c="COMPLETED";else if(/FAILED|ERROR|## Failed|\[FAILED\]/i.test(u))c="FAILED";else if(/Step \d+:.*\[/i.test(u))c="RUNNING";return{id:(o||"N/A").trim(),status:c}}function Lci(i){let n=e$(Yu(i,"task-board.md"));if(!n)return[];let u=[],o=n.split(`
836
+ `)}async function aB(i){let n=vB(process.cwd());if(i.json){console.log(JSON.stringify(n,null,2));return}console.log(bB(n))}var UB="OH_MY_AG_OUTPUT_FORMAT",h$=["text","json"],IB=["gemini","claude","codex","qwen"],gB=["backend","frontend","mobile","qa","debug","pm"];function qu(i,n="Output as JSON"){return i.option("--json",n).option("--output <format>","Output format (text/json)",(u)=>{let o=u.trim().toLowerCase();if(!h$.includes(o))throw Error(`Invalid output format: ${u}. Expected one of ${h$.join(", ")}`);return o})}function mci(i){if(i?.json)return"json";let n=i?.output?.trim().toLowerCase();if(n&&h$.includes(n))return n;if(process.env[UB]?.trim().toLowerCase()==="json")return"json";return"text"}function mu(i){return mci(i)==="json"}function wB(i){let n=i.at(-1);return n instanceof cx?n:null}function $ci(i){let n=wB(i);if(n)return n.opts();let u=i.at(-1);return u&&typeof u==="object"?u:{}}function xci(i){if(i instanceof Error)return i.message;return String(i)}function ec(i){throw Error(i)}function s8(i,n){for(let u of i){let o=u.charCodeAt(0);if(o>=0&&o<=31||o===127)ec(`${n} must not contain control characters`)}}function pci(i,n){if(s8(i,n),/[?#%]/.test(i))ec(`${n} must not contain ?, #, or %`);if(i.includes(".."))ec(`${n} must not contain '..'`)}function vci(i,n){s8(i,n);try{new URL(i)}catch{ec(`${n} must be a valid absolute URL`)}}function h8(i,n,u="text"){if(typeof i==="string"){if(u==="identifier"){pci(i,n);return}if(u==="url"){vci(i,n);return}s8(i,n);return}if(Array.isArray(i))for(let[o,c]of i.entries())h8(c,`${n}[${o}]`,u)}function _B(i){let n=i.toLowerCase();if(n==="url"||n.endsWith("url"))return"url";if(n.includes("id")||n.includes("type")||n.includes("vendor")||n.includes("session"))return"identifier";return"text"}function bci(i){let n=i.vendor;if(typeof n==="string"&&!IB.includes(n))ec(`vendor must be one of ${IB.join(", ")}`);let u=i.output;if(typeof u==="string"&&!h$.includes(u))ec(`output must be one of ${h$.join(", ")}`)}function aci(i){let n=i.processedArgs??i.args??[];(i.registeredArguments??[]).forEach((c,r)=>{let l=c.name?.()||String(r),m=n[r];if(h8(m,l,_B(l)),l==="agent-type"&&typeof m==="string"&&!gB.includes(m))ec(`agent-type must be one of ${gB.join(", ")}`)});let o=i.opts();bci(o);for(let[c,r]of Object.entries(o))h8(r,c,_B(c))}function Ici(i){return(i.registeredArguments??[]).map((n)=>({name:n.name?.()||"",required:!!n.required,variadic:!!n.variadic}))}function gci(i){return i.options.map((n)=>({flags:n.flags,long:n.long||void 0,short:n.short||void 0,description:n.description||"",required:!!n.required||!!n.mandatory,optional:!!n.optional,defaultValue:n.defaultValue}))}function JB(i){let n=[],u=i;while(u?.parent)n.unshift(u.name()),u=u.parent;return n.join(" ")}function _ci(i){return i.options.some((n)=>n.long==="--json"||n.long==="--output")}function Uci(i){return i.options.some((n)=>n.long==="--dry-run")}function GB(i){return{name:i.name(),path:JB(i),summary:i.summary()||void 0,description:i.description(),arguments:Ici(i),options:gci(i),supportsJsonOutput:_ci(i),supportsDryRun:Uci(i),subcommands:i.commands.map((n)=>GB(n))}}function wci(i,n){if(!n?.trim())return i;let u=n.trim(),o=[...i.commands];while(o.length>0){let c=o.shift();if(!c)continue;if(c.name()===u||JB(c)===u)return c;o.push(...c.commands)}return null}function fB(i,n){let u=wci(i,n);if(!u)ec(`Unknown command: ${n}`);let o={name:i.name(),version:i.version(),description:i.description(),env:{[UB]:"Set to json to force machine-readable output on commands that support it."},command:GB(u)};console.log(JSON.stringify(o,null,2))}function Ki(i,n={}){return async(...u)=>{let o=wB(u),c=$ci(u);try{if(o)aci(o);await i(...u)}catch(r){let l=xci(r);if(n.supportsJsonOutput&&mu(c))console.log(JSON.stringify({error:l},null,2));else console.error(l);process.exitCode=1}}}var zB={name:"oh-my-agent",version:"5.4.4",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",axios:"^1.15.0","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/ws":"^8.18.1",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"]}};import{existsSync as Gci,mkdirSync as fci,readdirSync as s$,readFileSync as zci,statSync as i5}from"node:fs";import{basename as Nci,join as Yu}from"node:path";var an=ai(Ri(),1),Xci="●",Qci="✓",qci="✗",Yci="○",Hci="◌";function Mci(){if(process.env.MEMORIES_DIR)return process.env.MEMORIES_DIR;let i=process.argv[3];if(i)return Yu(i,".serena","memories");return Yu(process.cwd(),".serena","memories")}function e$(i){try{return zci(i,"utf-8")}catch{return""}}function Bci(i){try{let n=s$(i);if(n.includes("orchestrator-session.md"))return Yu(i,"orchestrator-session.md");let u=n.filter((o)=>/^session-.*\.md$/.test(o)).map((o)=>({name:o,mtime:i5(Yu(i,o)).mtimeMs})).sort((o,c)=>c.mtime-o.mtime);if(u.length>0&&u[0])return Yu(i,u[0].name)}catch{}return null}function Kci(i){let n=Bci(i);if(!n)return{id:"N/A",status:"UNKNOWN"};let u=e$(n);if(!u)return{id:"N/A",status:"UNKNOWN"};let o=(u.match(/session-id:\s*(.+)/i)||[])[1]||(u.match(/# Session:\s*(.+)/i)||[])[1]||u.match(/(session-\d{8}-\d{6})/)?.[1]||Nci(n,".md"),c="UNKNOWN";if(/IN PROGRESS|RUNNING|## Active|\[IN PROGRESS\]/i.test(u))c="RUNNING";else if(/COMPLETED|DONE|## Completed|\[COMPLETED\]/i.test(u))c="COMPLETED";else if(/FAILED|ERROR|## Failed|\[FAILED\]/i.test(u))c="FAILED";else if(/Step \d+:.*\[/i.test(u))c="RUNNING";return{id:(o||"N/A").trim(),status:c}}function Lci(i){let n=e$(Yu(i,"task-board.md"));if(!n)return[];let u=[],o=n.split(`
837
837
  `);for(let c of o){if(!c.startsWith("|")||/^\|\s*-+/.test(c))continue;let r=c.split("|").map((x)=>x.trim()).filter(Boolean),l=r[0];if(r.length<2||!l||/^agent$/i.test(l))continue;let m=r[1],$=r[2];u.push({agent:l,status:m||"pending",task:$||""})}return u}function e8(i,n){try{let u=s$(i).filter((r)=>r.startsWith(`progress-${n}`)&&r.endsWith(".md")).sort().reverse();if(u.length===0||!u[0])return null;let c=e$(Yu(i,u[0])).match(/turn[:\s]*(\d+)/i);return c?.[1]?parseInt(c[1],10):null}catch{return null}}function Tci(i){try{let n=s$(i).filter((o)=>o.endsWith(".md")&&o!==".gitkeep").map((o)=>({name:o,mtime:i5(Yu(i,o)).mtimeMs})).sort((o,c)=>c.mtime-o.mtime).slice(0,5),u=[];for(let o of n){let c=o.name.replace(/^(progress|result|session|debug|task)-?/,"").replace(/[-_]agent/,"").replace(/[-_]completion/,"").replace(/\.md$/,"").replace(/[-_]/g," ").trim()||o.name.replace(/\.md$/,""),l=e$(Yu(i,o.name)).split(`
838
838
  `).map(($)=>$.trim()).filter(($)=>$&&!$.startsWith("---")&&$.length>3),m="";for(let $=l.length-1;$>=0;$--){let x=l[$];if(!x)continue;if(/^\*\*|^#+|^-|^\d+\.|Status|Result|Action|Step/i.test(x)){if(m=x.replace(/^[#*\-\d.]+\s*/,"").replace(/\*\*/g,"").trim(),m.length>5)break}}if(m.length>52)m=`${m.substring(0,49)}...`;if(m)u.push({agent:c,message:m})}return u}catch{return[]}}function Wci(i){let n=[],u=new Set;try{let o=s$(i).filter((c)=>c.endsWith(".md")&&c!==".gitkeep").map((c)=>({name:c,mtime:i5(Yu(i,c)).mtimeMs})).sort((c,r)=>r.mtime-c.mtime);for(let c of o){let r=e$(Yu(i,c.name)),l=r.match(/\*\*Agent\*\*:\s*(.+)/i)||r.match(/Agent:\s*(.+)/i)||r.match(/^#+\s*(.+?)\s*Agent/im),m=null;if(l?.[1])m=l[1].trim();else if(/_agent|agent_|-agent/i.test(c.name))m=c.name.replace(/\.md$/,"").replace(/[-_]completion|[-_]progress|[-_]result/gi,"").replace(/[-_]/g," ").trim();if(m&&!u.has(m.toLowerCase())){u.add(m.toLowerCase());let $="unknown";if(/\[COMPLETED\]|## Completed|## Results/i.test(r))$="completed";else if(/\[IN PROGRESS\]|## Progress|IN PROGRESS/i.test(r))$="running";else if(/\[FAILED\]|## Failed|ERROR/i.test(r))$="failed";let x=r.match(/## Task\s*\n+(.+)/i)||r.match(/\*\*Task\*\*:\s*(.+)/i),p=x?.[1]?x[1].trim().substring(0,20):"";n.push({agent:m,status:$,task:p,turn:e8(i,m)})}}}catch{}return n}function Vci(i){let n=i.toLowerCase();if(["running","active","in_progress","in-progress"].includes(n))return`${an.default.green(Xci)} running`;else if(["completed","done","finished"].includes(n))return`${an.default.cyan(Qci)} completed`;else if(["failed","error"].includes(n))return`${an.default.red(qci)} failed`;else if(["blocked","waiting"].includes(n))return`${an.default.yellow(Yci)} blocked`;return`${an.default.dim(Hci)} pending`}function NB(i){console.clear();let n=Kci(i),o=Lci(i).map((g)=>({...g,turn:e8(i,g.agent)}));if(o.length===0)o=Wci(i);if(o.length===0)try{let g=s$(i).filter((_)=>_.startsWith("progress-")&&_.endsWith(".md"));for(let _ of g){let U=_.replace(/^progress-/,"").replace(/\.md$/,"");o.push({agent:U,status:"running",task:"",turn:e8(i,U)})}}catch{}let c=56,r="═".repeat(c),l=(g)=>" ".repeat(Math.max(0,g)),m=(g)=>an.default.magenta(g),$=(g)=>an.default.bold(g),x=(g)=>an.default.dim(g),p=an.default.yellow;if(n.status==="RUNNING")p=an.default.green;else if(n.status==="COMPLETED")p=an.default.cyan;else if(n.status==="FAILED")p=an.default.red;console.log(`${m(`╔${r}╗`)}`),console.log(`${m("║")} ${$(m("Serena Memory Dashboard"))}${l(c-25)}${m("║")}`);let v=`Session: ${$(n.id.padEnd(20))} [${p(n.status)}]`;if(console.log(`${m("║")} ${v}${l(c-4-v.length-9)}${m("║")}`),console.log(`${m(`╠${r}╣`)}`),console.log(`${m("║")} ${$(`${"Agent".padEnd(12)} ${"Status".padEnd(12)} ${"Turn".padEnd(6)} ${"Task".padEnd(20)}`)} ${m("║")}`),console.log(`${m("║")} ${x(`${"──────────".padEnd(12)} ${"──────────".padEnd(12)} ${"────".padEnd(6)} ${"──────────────────".padEnd(20)}`)} ${m("║")}`),o.length===0)console.log(`${m("║")} ${x(`No agents detected yet${l(32)}`)}${m("║")}`);else for(let g of o){let _=Vci(g.status),U=g.turn!=null?String(g.turn):"-",G=g.task.substring(0,20);console.log(`${m("║")} ${g.agent.padEnd(12)} ${_.padEnd(22)} ${U.padEnd(6)} ${G.padEnd(20)}${m("║")}`)}console.log(`${m(`╠${r}╣`)}`),console.log(`${m("║")} ${$("Latest Activity:")}${l(c-18)}${m("║")}`);let b=Tci(i);if(b.length===0)console.log(`${m("║")} ${x(`No activity yet${l(38)}`)}${m("║")}`);else for(let g of b){let _=`[${g.agent}] ${g.message}`;console.log(`${m("║")} ${x(_.substring(0,52).padEnd(52))}${m("║")}`)}console.log(`${m(`╠${r}╣`)}`);let a=`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(`${m("║")} ${x(a)}${l(c-4-a.length)}${m("║")}`),console.log(`${m(`╚${r}╝`)}`)}async function XB(){let i=Mci();if(!Gci(i))fci(i,{recursive:!0}),console.log(an.default.yellow(`Created ${i} — waiting for memory files...`));console.log(an.default.magenta(`
839
839
  \uD83D\uDEF8 Serena Terminal Dashboard`)),console.log(an.default.dim(` Watching: ${i}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-agent",
3
- "version": "5.4.3",
3
+ "version": "5.4.4",
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": {