oh-my-agent 8.40.0 → 8.40.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.
- package/bin/cli.js +2 -2
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1561,7 +1561,7 @@ ${XV.stringify(F)}`;if(hq2(G,j),z.push(`.agents/oma-config.yaml updated (model_p
|
|
|
1561
1561
|
`),z.push(".mcp.json (Claude Code project MCP refreshed)")}if(Fv(vz(dM5(),".claude.json"),"mcpServers","claude-code"))z.push("~/.claude.json (Serena uvx → uv tool install)");return z}};import{copyFileSync as sM5,existsSync as tM5,readFileSync as eM5,writeFileSync as $O5}from"node:fs";import{join as zO5}from"node:path";var lq2={"claude-only":"claude","codex-only":"codex","gemini-only":"gemini","qwen-only":"qwen","cursor-only":"cursor"},GO5=new Set(Object.keys(lq2)),dq2={name:"010-rename-preset-keys",up($){let z=[],G=zO5($,".agents","oma-config.yaml");if(!tM5(G))return z;let J;try{J=eM5(G,"utf-8")}catch{return z}let Q=J.match(/^(model_preset:\s*)([A-Za-z0-9_-]+)([ \t]*(?:#[^\n]*)?)$/m);if(!Q)return z;let K=Q[2];if(!K)return z;if(!GO5.has(K))return z;let U=lq2[K];if(!U)return z;let Z=`${G}.bak`;try{sM5(G,Z),z.push("Backed up .agents/oma-config.yaml → .agents/oma-config.yaml.bak")}catch{}let Y=J.replace(/^(model_preset:\s*)([A-Za-z0-9_-]+)([ \t]*(?:#[^\n]*)?)$/m,(W,V,B,L)=>`${V}${U}${L}`);return $O5(G,Y,"utf-8"),z.push(`.agents/oma-config.yaml: model_preset "${K}" → "${U}"`),z}};import{cpSync as JO5,existsSync as en,lstatSync as QO5,mkdirSync as KO5,readdirSync as UO5,readFileSync as ZO5,readlinkSync as WO5,rmSync as YO5}from"node:fs";import{dirname as pq2,join as U$,relative as VO5,resolve as nq2}from"node:path";var BO5="<!-- oma:generated -->",XO5=["claude","codex","qwen"];function LO5($){let z=U$($,"SKILL.md");if(!en(z))return!1;try{return ZO5(z,"utf-8").includes(BO5)}catch{return!1}}function HO5($,z,G,J){let Q=U$(z,".migration-backup","011",`.${G}`,"skills",J);KO5(pq2(Q),{recursive:!0}),JO5($,Q,{recursive:!0,force:!0})}var aq2={name:"011-unify-workflow-skills",up($){let z=[],G=U$($,".agents","skills");for(let J of XO5){let Q=U$($,`.${J}`,"skills");if(!en(Q))continue;let K;try{K=UO5(Q)}catch{continue}for(let U of K){let Z=U$(Q,U),Y;try{Y=QO5(Z)}catch{continue}if(Y.isSymbolicLink()){try{let B=WO5(Z),L=nq2(pq2(Z),B),X=nq2(U$(G,U));if(L!==X)z.push(`.${J}/skills/${U}: symlink points to unexpected target (skipped) — expected ${U$(".agents","skills",U)}, got ${B}`)}catch{}continue}if(!Y.isDirectory())continue;if(!LO5(Z))continue;let W=U$(G,U);if(!en(W)){z.push(`.${J}/skills/${U}: SSOT target missing at ${U$(".agents","skills",U)}, skipped (no dangling symlink)`);continue}try{HO5(Z,$,J,U),z.push(`.migration-backup/011/.${J}/skills/${U} (backed up)`)}catch{z.push(`.${J}/skills/${U}: backup failed, skipping conversion`);continue}try{YO5(Z,{recursive:!0,force:!0})}catch{z.push(`.${J}/skills/${U}: failed to remove real directory, skipping`);continue}let V=VO5(Q,W);try{qq(V,Z,"dir"),z.push(`.${J}/skills/${U} → ${U$(".agents","skills",U)} (symlinked)`)}catch{z.push(`.${J}/skills/${U}: symlink creation failed`)}}}return z}};import{existsSync as qO5,readFileSync as FO5,writeFileSync as jO5}from"node:fs";import{homedir as kO5}from"node:os";import{join as NO5}from"node:path";function AO5($){let z=[],G=NO5($,".agents","skills","_version.json");if(!qO5(G))return z;let J;try{J=JSON.parse(FO5(G,"utf-8"))}catch{return z}if(!J||typeof J!=="object"||Array.isArray(J)||typeof J.version!=="string")return z;if(J.mode==="project"||J.mode==="global")return z;let Q=$===kO5()?"global":"project",K={...J,schemaVersion:2,mode:Q};try{jO5(G,`${JSON.stringify(K,null,2)}
|
|
1562
1562
|
`,"utf-8"),z.push(`.agents/skills/_version.json: backfilled mode="${Q}", schemaVersion=2`)}catch{}return z}var oq2={name:"012-version-install-mode",up:AO5};import{cpSync as MO5,existsSync as jv,lstatSync as OO5,mkdirSync as IO5,readdirSync as eq2,readFileSync as DO5,readlinkSync as RO5,rmSync as rq2}from"node:fs";import{dirname as sq2,join as PJ,resolve as tq2}from"node:path";var vO5="<!-- oma:generated -->";function wO5($){if(!jv($))return[];return eq2($,{withFileTypes:!0}).filter((z)=>z.isFile()&&z.name.endsWith(".md")).map((z)=>z.name.slice(0,-3))}function TO5($){let z=PJ($,"SKILL.md");if(!jv(z))return!1;try{return DO5(z,"utf-8").includes(vO5)}catch{return!1}}var $F2={name:"013-workflow-direct-symlinks",up($){let z=[],G=PJ($,".agents","workflows"),J=PJ($,".agents","skills"),Q=wO5(G);if(Q.length===0)return z;let K=new Set(Q);for(let[U,Z]of Object.entries(G7))for(let Y of new Set([Z.projectPath,Z.homePath])){let W=PJ($,Y);if(!jv(W))continue;for(let V of Q){let B=PJ(W,V),L;try{L=OO5(B)}catch{continue}if(!L.isSymbolicLink())continue;let X;try{X=tq2(sq2(B),RO5(B))}catch{continue}let H=tq2(PJ(J,V));if(X!==H)continue;try{rq2(B,{force:!0}),z.push(`${Y}/${V}: removed legacy wrapper symlink (${U})`)}catch{}}}if(jv(J))for(let U of eq2(J,{withFileTypes:!0})){if(!U.isDirectory())continue;if(!K.has(U.name))continue;let Z=PJ(J,U.name);if(!TO5(Z))continue;let Y=PJ($,".migration-backup","013",".agents","skills",U.name);try{IO5(sq2(Y),{recursive:!0}),MO5(Z,Y,{recursive:!0,force:!0})}catch{}try{rq2(Z,{recursive:!0,force:!0}),z.push(`.agents/skills/${U.name}: removed generated workflow wrapper (backed up)`)}catch{}}return z}};var EO5=[jq2,Oq2,Rq2,wq2,Eq2,Pq2,yq2,gq2,cq2,dq2,aq2,oq2,$F2];function jU($){let z=[];for(let G of EO5)z.push(...G.up($));return z}var xO5={en:"English",ko:"한국어",ja:"日本語",zh:"中文",vi:"Tiếng Việt",de:"Deutsch",es:"Español",fr:"Français",nl:"Nederlands",pl:"Polski",pt:"Português",ru:"Русский"};function hO5($){let z=kU($,"docs"),G=["en"];if(_F(z))for(let J of zF2(z)){let Q=J.match(/^README\.(.+)\.md$/);if(Q?.[1])G.push(Q[1])}return G.map((J)=>({value:J,label:xO5[J]??J}))}function gO5($){let z=kU($,".agents","oma-config.yaml");if(!_F(z))return null;try{return kv(z,"utf-8").match(/^language:\s*([A-Za-z-]+)/m)?.[1]??null}catch{return null}}function fO5($){if(!_F($))return;let z;try{z=zF2($,{withFileTypes:!0,encoding:"utf-8"})}catch{return}for(let G of z){if(!G.isSymbolicLink())continue;let J=kU($,G.name),Q;try{Q=uO5(J)}catch{continue}let K=SO5($,Q),U;try{CO5(K),U=!0}catch{U=!1}if(!U)try{bO5(J),console.log(`cleaned broken symlink: ${J}`)}catch{}}}function GF2($={}){if($.yes)return!0;if(process.env.OMA_YES==="1"||process.env.OMA_YES==="true")return!0;return!1}function mO5($={}){if(GF2($))return!0;if(process.env.CI==="true"||process.env.CI==="1")return!0;return!1}function iO5($){let z=kU($,".agents","oma-config.yaml");if(!_F(z))return null;try{return kv(z,"utf-8").match(/^model_preset:\s*([A-Za-z0-9_-]+)/m)?.[1]??null}catch{return null}}function cO5($=()=>kv("/proc/version","utf-8")){if(process.platform!=="linux")return!1;try{return/microsoft|wsl/i.test($())}catch{return!1}}async function Nv($={}){let z=mO5($),G=GF2($);if(process.platform!=="win32"&&typeof process.geteuid==="function"&&process.geteuid()===0&&typeof process.env.SUDO_USER==="string"&&process.env.SUDO_USER.length>0)p4("Refusing to install under sudo. Re-run as the target user (without sudo) — oma writes to your HOME and runs as your user."),process.exit(1);if(C7()==="global"&&(process.env.CI==="true"||process.env.CI==="1"))s5.warn("Running `oma install --global` in CI. This will modify the CI user's HOME. Proceeding because --yes / non-interactive mode is set.");let Q=BY(),K=rR(Q);if(!K.ok)p4(`Another oma install/update is running (pid=${K.held.pid}). Try again in a moment.`),process.exit(1);let U=sR(K.release);try{if(console.clear(),L1(a4.default.bgMagenta(a4.default.white(" \uD83D\uDEF8 oh-my-agent "))),z)s5.info(a4.default.dim("Non-interactive mode — using defaults."));if(C7()==="project"&&process.cwd()===yO5())if(z)p4("Refusing to install in HOME without --global. Re-run with --global, or cd to a project directory first."),process.exit(1);else{let n=await g1({message:"You're running oma in your HOME directory without --global. This will scatter files in ~/. Are you sure?",initialValue:!1});if(J4(n)||!n)p4("Cancelled."),process.exit(0)}if(C7()==="global"&&cO5())s5.info(a4.default.dim("WSL detected: your $HOME ("+Q+") is the WSL Linux home and is distinct from your Windows %USERPROFILE%. oma will install only to the WSL HOME. If you want a Windows-side install, re-run this command from PowerShell."));if(C7()==="global"){if(!z){let f=await g1({message:`You're about to install oh-my-agent globally to ${Q}/.agents/. This will modify ~/.claude/, ~/.codex/, etc. Proceed?`,initialValue:!1});if(J4(f)||!f)p4("Cancelled."),process.exit(0)}if(xR(Q)!=="global"&&!z){a2(["This is your first global install of oh-my-agent.","Scope:"," - SSOT: ~/.agents/ (all skills, workflows, rules)"," - Vendor configs: ~/.claude/, ~/.codex/, ~/.gemini/, ~/.qwen/ (symlinks + settings)"," - Lock file: ~/.agents/_install.lock","Existing per-project installs are not affected."].join(`
|
|
1563
1563
|
`));let f=await g1({message:"Proceed with the global install?",initialValue:!1});if(J4(f)||!f)p4("Cancelled."),process.exit(0)}}let Z=jU(Q);if(Z.length>0)a2(Z.map((n)=>`${a4.default.green("✓")} ${n}`).join(`
|
|
1564
|
-
`),"Migration");if(!z)await aR(Q);let Y=r9();Y.start("Downloading...");let W,V;try{let n=await dY();W=n.dir,V=n.cleanup}catch(n){Y.stop("Download failed"),s5.error(n instanceof Error?n.message:String(n)),process.exit(1)}Y.stop("Downloaded!");let B=hO5(W),L=gO5(Q),X=B.some((n)=>n.value===L)?L:"en",H=z?X:await Lz({message:"Response language?",options:B,initialValue:X});if(J4(H))V(),p4("Cancelled."),process.exit(0);let q=[{value:"claude",label:"Claude Code only",hint:"Claude Max subscription holders"},{value:"codex",label:"Codex CLI only",hint:"ChatGPT Plus/Pro subscription holders"},{value:"gemini",label:"Gemini CLI only",hint:"Google AI Pro subscription holders"},{value:"qwen",label:"Qwen Code only",hint:"Qwen Code subscription holders"},{value:"antigravity",label:"Antigravity CLI (agy)",hint:"Gemini 3.1 Pro impl + Gemini 3.5 Flash orchestration"},{value:"mixed",label:"Mixed (cross-vendor)",hint:"Claude orchestrator + cross-vendor subagents"}],F=iO5(Q),j=q.some((n)=>n.value===F)?F:"claude",k=z?j:await Lz({message:"Model preset?",options:q,initialValue:j});if(J4(k))V(),p4("Cancelled."),process.exit(0);let N=z?"all":await Lz({message:"What type of project?",options:[{value:"all",label:"All",hint:"Install everything"},{value:"fullstack",label:"Fullstack",hint:"Web + Mobile + Infra (kitchen sink)"},{value:"fullstack-web",label:"Fullstack Web",hint:"Frontend + Backend + DB (no mobile/infra)"},{value:"fullstack-mobile",label:"Fullstack Mobile",hint:"Mobile + Backend + DB"},{value:"frontend",label:"Frontend",hint:"React/Next.js"},{value:"backend",label:"Backend",hint:"Python, Node.js, Rust, ..."},{value:"mobile",label:"Mobile",hint:"Flutter/Dart"},{value:"devops",label:"DevOps",hint:"Terraform + CI/CD + Observability"},{value:"research",label:"Research",hint:"Scholar + Market + PDF/HWP + Writer"},{value:"content",label:"Content",hint:"Image + Voice + Design + Writer"},{value:"custom",label:"Custom",hint:"Choose skills"}]});if(J4(N))p4("Cancelled."),process.exit(0);let A;if(N==="custom"){let n=xK(),f=await Hq({message:"Select skills:",options:n.map((g)=>({value:g.name,label:g.name,hint:g.desc})),required:!0});if(J4(f))p4("Cancelled."),process.exit(0);A=f}else A=$K2[N]??[];let M={};if(A.includes("oma-backend")){let n=z?"python":await Lz({message:"Backend language?",options:[{value:"python",label:"\uD83D\uDC0D Python",hint:"FastAPI/SQLAlchemy (default)"},{value:"node",label:"\uD83D\uDFE2 Node.js",hint:"NestJS/Hono + Prisma/Drizzle"},{value:"rust",label:"\uD83E\uDD80 Rust",hint:"Axum/Actix-web"},{value:"other",label:"\uD83D\uDD27 Other / Auto-detect",hint:"Configure later with /stack-set"}],initialValue:"python"});if(J4(n))p4("Cancelled."),process.exit(0);if(n!=="other")M["oma-backend"]=n}let D=process.platform!=="win32"&&!process.env.CI,I=[{value:"claude",label:"Claude Code",hint:"hooks + settings + CLAUDE.md"},{value:"codex",label:"Codex CLI",hint:"hooks + plugin"},{value:"copilot",label:"GitHub Copilot",hint:"skill symlinks + .github/prompts/ wrappers"},{value:"cursor",label:"Cursor",hint:".cursor/rules/ export + prompt hooks"},{value:"
|
|
1564
|
+
`),"Migration");if(!z)await aR(Q);let Y=r9();Y.start("Downloading...");let W,V;try{let n=await dY();W=n.dir,V=n.cleanup}catch(n){Y.stop("Download failed"),s5.error(n instanceof Error?n.message:String(n)),process.exit(1)}Y.stop("Downloaded!");let B=hO5(W),L=gO5(Q),X=B.some((n)=>n.value===L)?L:"en",H=z?X:await Lz({message:"Response language?",options:B,initialValue:X});if(J4(H))V(),p4("Cancelled."),process.exit(0);let q=[{value:"claude",label:"Claude Code only",hint:"Claude Max subscription holders"},{value:"codex",label:"Codex CLI only",hint:"ChatGPT Plus/Pro subscription holders"},{value:"gemini",label:"Gemini CLI only",hint:"Google AI Pro subscription holders"},{value:"qwen",label:"Qwen Code only",hint:"Qwen Code subscription holders"},{value:"antigravity",label:"Antigravity CLI (agy)",hint:"Gemini 3.1 Pro impl + Gemini 3.5 Flash orchestration"},{value:"mixed",label:"Mixed (cross-vendor)",hint:"Claude orchestrator + cross-vendor subagents"}],F=iO5(Q),j=q.some((n)=>n.value===F)?F:"claude",k=z?j:await Lz({message:"Model preset?",options:q,initialValue:j});if(J4(k))V(),p4("Cancelled."),process.exit(0);let N=z?"all":await Lz({message:"What type of project?",options:[{value:"all",label:"All",hint:"Install everything"},{value:"fullstack",label:"Fullstack",hint:"Web + Mobile + Infra (kitchen sink)"},{value:"fullstack-web",label:"Fullstack Web",hint:"Frontend + Backend + DB (no mobile/infra)"},{value:"fullstack-mobile",label:"Fullstack Mobile",hint:"Mobile + Backend + DB"},{value:"frontend",label:"Frontend",hint:"React/Next.js"},{value:"backend",label:"Backend",hint:"Python, Node.js, Rust, ..."},{value:"mobile",label:"Mobile",hint:"Flutter/Dart"},{value:"devops",label:"DevOps",hint:"Terraform + CI/CD + Observability"},{value:"research",label:"Research",hint:"Scholar + Market + PDF/HWP + Writer"},{value:"content",label:"Content",hint:"Image + Voice + Design + Writer"},{value:"custom",label:"Custom",hint:"Choose skills"}]});if(J4(N))p4("Cancelled."),process.exit(0);let A;if(N==="custom"){let n=xK(),f=await Hq({message:"Select skills:",options:n.map((g)=>({value:g.name,label:g.name,hint:g.desc})),required:!0});if(J4(f))p4("Cancelled."),process.exit(0);A=f}else A=$K2[N]??[];let M={};if(A.includes("oma-backend")){let n=z?"python":await Lz({message:"Backend language?",options:[{value:"python",label:"\uD83D\uDC0D Python",hint:"FastAPI/SQLAlchemy (default)"},{value:"node",label:"\uD83D\uDFE2 Node.js",hint:"NestJS/Hono + Prisma/Drizzle"},{value:"rust",label:"\uD83E\uDD80 Rust",hint:"Axum/Actix-web"},{value:"other",label:"\uD83D\uDD27 Other / Auto-detect",hint:"Configure later with /stack-set"}],initialValue:"python"});if(J4(n))p4("Cancelled."),process.exit(0);if(n!=="other")M["oma-backend"]=n}let D=process.platform!=="win32"&&!process.env.CI,I=[{value:"claude",label:"Claude Code",hint:"hooks + settings + CLAUDE.md"},{value:"codex",label:"Codex CLI",hint:"hooks + plugin"},{value:"copilot",label:"GitHub Copilot",hint:"skill symlinks + .github/prompts/ wrappers"},{value:"cursor",label:"Cursor",hint:".cursor/rules/ export + prompt hooks"},{value:"grok",label:"Grok",hint:"hooks + project MCP + .grok/agents/"},{value:"kiro",label:"Kiro CLI",hint:"hooks + Serena MCP + .kiro/agents/"},{value:"pi",label:"pi (Earendil)",hint:"in-process extension bridge — .pi/extensions/oma/"},...D?[{value:"antigravity",label:"Antigravity CLI (agy)",hint:"hooks + HUD + Serena MCP — HOME-shared (~/.gemini/antigravity-cli/)"},{value:"hermes",label:"Hermes Agent",hint:"skills only — workflows N/A, HOME-shared (no per-project isolation)"}]:[],{value:"qwen",label:"Qwen Code",hint:"hooks + settings"}],O=I.filter((n)=>{if(WD(n.value))return!1;return!G7[n.value]?.requiresHomeConsent}).map((n)=>n.value),v=z?O:await Hq({message:"CLI tools to configure:",options:I,initialValues:O,required:!0});if(J4(v))p4("Cancelled."),process.exit(0);let C=v,u=Object.keys(G7),S=C.filter((n)=>u.includes(n)),d=[];for(let n of S){if(jY(n)){if(z){s5.info(a4.default.dim(`Skipped ${n} export (HOME write requires -y opt-in).`));continue}let f=await g1({message:`${n} export writes to HOME (${a4.default.cyan(fK2(n))}). Proceed?`,initialValue:!1});if(J4(f))V(),p4("Cancelled."),process.exit(0);if(!f){s5.info(a4.default.dim(`Skipped ${n} export.`));continue}}d.push(n)}Y.start("Installing skills...");let o=null;try{try{let g=[".claude/skills",".codex/skills",".gemini/skills",".github/skills",".qwen/skills"];for(let E of g)fO5(kU(Q,E));ZD(W,Q),bK2(W,Q),SK2(W,Q),xK2(W,Q,!1);for(let E of A)Y.message(`Installing ${a4.default.cyan(E)}...`),UD(W,E,Q,M[E]);Y.stop("Skills installed!");let e=kU(Q,".agents","oma-config.yaml");if(_F(e)){let E=kv(e,"utf-8");if(E=E.replace(/^language:\s*.+$/m,`language: ${H}`),/^model_preset:/m.test(E))E=E.replace(/^model_preset:\s*.+$/m,`model_preset: ${k}`);else E=E.replace(/^(language:\s*.+)$/m,`$1
|
|
1565
1565
|
model_preset: ${k}`);_O5(e,E),uK2(Q,C)}Y.start("Installing vendor adaptations..."),o=BV({vendorFilter:C,quiet:!0,telemetry:RJ(Q),refreshSymlinks:!1}),Y.stop("Vendor adaptations installed!");let z2=await ZU(W);if(z2)await DF(Q,z2);let w=jU(Q);if(w.length>0)a2(w.map((E)=>`${a4.default.green("✓")} ${E}`).join(`
|
|
1566
1566
|
`),"Migration")}finally{V()}let n=kY(Q,d,A);if(FY(Q,d,qY(Q)),a2([...A.map((g)=>`${a4.default.green("✓")} ${g}`),"",a4.default.dim(`Location: ${kU(Q,X1)}`),...n.created.length>0?["",a4.default.cyan("Symlinks:"),...n.created.map((g)=>`${a4.default.green("→")} ${g}`)]:[],...n.skipped.length>0?["",a4.default.dim("Skipped:"),...n.skipped.map((g)=>a4.default.dim(` ${g}`))]:[]].join(`
|
|
1567
1567
|
`),"Installed"),C.includes("cursor"))s5.success(a4.default.green("Cursor rules exported (.cursor/rules/)"));for(let g of o?.mergedDocs??[])s5.success(a4.default.green(`oma guide merged into ${g}`));if(o?.agyInstalled)s5.success(a4.default.green("Antigravity HUD installed (~/.gemini/antigravity-cli/)"));else if(o?.agySkipReason)s5.warn(`agy: ${o.agySkipReason}`);{let g=DH2(A,M["oma-backend"]),{configured:e,registered:z2}=nR(Q,g);if(e)s5.success(a4.default.green(`Serena project configured (${g.join(", ")})`));if(z2)s5.success(a4.default.green("Project registered in Serena"))}s5.info(a4.default.dim("Skipped global HOME-level configuration updates."));let f=await ZU(Q).catch(()=>null);if(f)await DF(Q,f,C7());if(a2(["1. Open your project in your IDE","2. Type /orchestrate to spawn a multi-agent workflow","3. Run `oma doctor` if anything looks off"].join(`
|
|
@@ -2455,7 +2455,7 @@ ${$.reassignedActive.map((U)=>` ${U.category}: ${U.from} -> ${U.to}`).join(`
|
|
|
2455
2455
|
`);if(a2(H,"Overview"),X.totalSpawns>0){let F=Object.entries(X.byVendor).sort(([,k],[,N])=>N.tokens-k.tokens).map(([k,N])=>` ${k.padEnd(12)} ${jr2(N.tokens).padStart(12)} tokens · ${String(N.spawns).padStart(3)} spawns · ${kr2(N.usd).padStart(7)}`),j=[D7.default.bold("\uD83D\uDCB0 Cost Telemetry (all sessions)"),"┌─────────────────────┬──────────────┐",`│ ${D7.default.bold("Metric")} │ ${D7.default.bold("Value")} │`,"├─────────────────────┼──────────────┤",`│ Total tokens (est.) │ ${jr2(X.totalTokens).padEnd(12)} │`,`│ Total spawns │ ${String(X.totalSpawns).padEnd(12)} │`,`│ Estimated USD │ ${kr2(X.estimatedUsd).padEnd(12)} │`,"└─────────────────────┴──────────────┘",D7.default.dim("By vendor (sorted by tokens):"),...F,D7.default.dim("Estimate is input-only (prompt char approximation); output tokens not yet tracked."),D7.default.dim("Configure session.quota_cap in .agents/oma-config.yaml to enforce budgets.")].join(`
|
|
2456
2456
|
`);a2(j,"Cost")}let q=Object.entries(Q.skillsUsed).sort(([,F],[,j])=>j-F).slice(0,5);if(q.length>0){let F=[D7.default.bold("\uD83C\uDFC6 Top Skills Used"),...q.map(([j,k],N)=>` ${N+1}. ${j} (${k})`)].join(`
|
|
2457
2457
|
`);a2(F,"Skills")}R5(D7.default.dim(`Data stored in: ${J}`))}function Mr2($){b5($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(m2(async(z)=>{await Ar2(C5(z),z.reset)},{supportsJsonOutput:!0}))}U7();var y8=_2(k5(),1);import*as v6 from"node:fs";import*as Z3 from"node:path";var BY4="oma-config.yaml",XY4="mcp.json",LY4="<!-- oma:generated -->";function UW($){try{let z=v6.lstatSync($);if(z.isSymbolicLink())return"symlink";if(z.isDirectory())return"dir";return"file"}catch{return null}}function HY4($){try{return v6.readFileSync($,"utf-8").includes(LY4)}catch{return!1}}function qY4($,z){let G=Z3.join($,"SKILL.md");try{if(!v6.lstatSync(G).isSymbolicLink())return!1;let J=v6.realpathSync(G),Q=v6.realpathSync(Z3.join(z,".agents","workflows"));return J===Q||J.startsWith(Q+Z3.sep)}catch{return!1}}function $62($){try{return v6.readdirSync($,{withFileTypes:!0})}catch{return[]}}function FY4($){let z=[],G=[],J=Z3.join($,X1);for(let V of $62(J)){let B=Z3.join(J,V.name),L=UW(B);if(L===null)continue;let X;if(V.name==="_version.json")X="oma install metadata (saveLocalVersion)";else if(V.name==="_shared")X="shared assets (installShared)";else X="skill directory (installSkill)";z.push({path:B,kind:L,reason:X})}let Q=Z3.join($,".agents","workflows");if(UW(Q)==="dir")z.push({path:Q,kind:"dir",reason:"created by installWorkflows"});let K=Z3.join($,".agents","rules");if(UW(K)==="dir")z.push({path:K,kind:"dir",reason:"created by installRules"});let U=Z3.join($,".agents","config");if(UW(U)==="dir")z.push({path:U,kind:"dir",reason:"created by installConfigs"});let Z=Z3.join($,".agents",BY4);if(UW(Z)!==null)G.push({path:Z,kind:"file",reason:"user preferences"});let Y=Z3.join($,".agents",XY4);if(UW(Y)!==null)G.push({path:Y,kind:"file",reason:"may contain user MCP servers"});for(let[V,B]of Object.entries(G7)){let X=C7()==="global"?B.homePath:B.projectPath,H=Z3.join($,X);for(let q of $62(H)){let F=Z3.join(H,q.name),j=UW(F);if(j===null)continue;if(j==="symlink")z.push({path:F,kind:"symlink",reason:`created by createVendorSymlinks (${V})`});else if(j==="dir"&&qY4(F,$))z.push({path:F,kind:"dir",reason:`created by createVendorWorkflowSymlinks (${V})`});else G.push({path:F,kind:j,reason:"user-authored skill"})}}let W=Z3.join($,".github","prompts");for(let V of $62(W)){if(!V.isFile()||!V.name.endsWith(".prompt.md"))continue;let B=Z3.join(W,V.name);if(HY4(B))z.push({path:B,kind:"file",reason:"generated by installCopilotWorkflowPrompts (oma:generated)"})}return{omaOwned:z,userOwned:G}}function Or2($,z){let G=Z3.relative(z,$);return Z3.join("<root>",G)}function jY4($,z,G){let J=$.length===0?[y8.default.dim(" (nothing to remove)")]:$.map((U)=>` ${y8.default.red("✗")} ${Or2(U.path,G).padEnd(55)} ${y8.default.dim(`(${U.kind}, ${U.reason})`)}`),Q=z.length===0?[y8.default.dim(" (none)")]:z.map((U)=>` ${y8.default.green("✓")} ${Or2(U.path,G).padEnd(55)} ${y8.default.dim(`(${U.reason})`)}`),K=[y8.default.bold("The following oma-owned entries will be removed:"),...J,"",y8.default.bold("The following user-owned entries will be preserved:"),...Q].join(`
|
|
2458
|
-
`);a2(K,"Uninstall preview")}function kY4($){for(let G of $){if(G.kind!=="symlink")continue;try{v6.unlinkSync(G.path)}catch{}}for(let G of $){if(G.kind!=="file")continue;try{v6.unlinkSync(G.path)}catch{}}let z=$.filter((G)=>G.kind==="dir").sort((G,J)=>J.path.split(Z3.sep).length-G.path.split(Z3.sep).length);for(let G of z)try{v6.rmSync(G.path,{recursive:!0,force:!0})}catch{}}async function Ir2($={}){let z=BY(),G=$.yes===!0||process.env.OMA_YES==="1"||process.env.CI==="true"||process.env.CI==="1",{omaOwned:J,userOwned:Q}=FY4(z);if(jY4(J,Q,z),$.dryRun){R5(y8.default.yellow("Dry-run — no files were changed."));return}if(J.length===0){R5(y8.default.dim("Nothing to remove."));return}if(!G){let K=await g1({message:`Remove ${J.length} oma-owned entries from ${z}?`,initialValue:!1});if(J4(K)||!K){p4("Uninstall cancelled.");return}}kY4(J),R5(y8.default.green("Uninstall complete. User-owned files were preserved."))}function Dr2($){$.command("uninstall").description("Remove oh-my-agent's owned files (preserves oma-config.yaml, mcp.json, and user-authored skills)").option("--dry-run","Preview what would be removed without deleting").option("-y, --yes","Skip confirmation prompt").action(m2(async(z)=>{let G=$.opts();await Ir2({yes:z.yes,dryRun:z.dryRun,global:G.global})}))}U7();var Y1=_2(k5(),1);import{execSync as Er2}from"node:child_process";import{cpSync as nb,existsSync as o$,mkdirSync as z62,readFileSync as pb,rmSync as G62,writeFileSync as J62}from"node:fs";import{homedir as wY4,tmpdir as TY4}from"node:os";import{join as R7}from"node:path";var lb=_2(k5(),1);import{execSync as NY4,spawn as AY4}from"node:child_process";import{realpathSync as Rr2}from"node:fs";import PA from"node:process";var ZW="oh-my-agent";function MY4($=PA.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(PA.env.IS_BINARY==="true")return{packageManager:"binary",isGlobal:!0,updateMessage:"Running as a standalone binary. Download the latest release from GitHub."};let z;try{z=c8(Rr2($))}catch{return{packageManager:"unknown",isGlobal:!1}}if(z.includes("/.npm/_npx")||z.includes("/npm/_npx"))return{packageManager:"npx",isGlobal:!1,updateMessage:"Running via npx, auto-update not applicable."};if(z.includes("/.pnpm/_pnpx")||z.includes("/.cache/pnpm/dlx"))return{packageManager:"pnpx",isGlobal:!1,updateMessage:"Running via pnpx, auto-update not applicable."};if(z.includes("/.bun/install/cache"))return{packageManager:"bunx",isGlobal:!1,updateMessage:"Running via bunx, auto-update not applicable."};if(PA.platform==="darwin")try{let G=NY4(`brew --prefix ${ZW}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=c8(Rr2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${ZW}`,updateMessage:"Installed via Homebrew. Updating in background..."}}}catch{}if(z.includes("/.pnpm/global")||z.includes("/.local/share/pnpm"))return{packageManager:"pnpm",isGlobal:!0,updateCommand:`pnpm add -g ${ZW}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${ZW}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${ZW}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${ZW}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var vr2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function OY4($,z){let G=$.match(vr2),J=z.match(vr2);if(!G||!J)return!1;for(let Q=1;Q<=3;Q++){let K=Number(G[Q]),U=Number(J[Q]);if(K<U)return!0;if(K>U)return!1}return!1}async function IY4($=ZW,z=2000){try{let G=await m1.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function wr2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(PA.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(PA.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await IY4();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!OY4($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=MY4();if(!G.updateCommand)return $.onNotice?.(lb.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return AY4(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(lb.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(lb.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var db={name:"oh-my-agent",version:"8.40.
|
|
2458
|
+
`);a2(K,"Uninstall preview")}function kY4($){for(let G of $){if(G.kind!=="symlink")continue;try{v6.unlinkSync(G.path)}catch{}}for(let G of $){if(G.kind!=="file")continue;try{v6.unlinkSync(G.path)}catch{}}let z=$.filter((G)=>G.kind==="dir").sort((G,J)=>J.path.split(Z3.sep).length-G.path.split(Z3.sep).length);for(let G of z)try{v6.rmSync(G.path,{recursive:!0,force:!0})}catch{}}async function Ir2($={}){let z=BY(),G=$.yes===!0||process.env.OMA_YES==="1"||process.env.CI==="true"||process.env.CI==="1",{omaOwned:J,userOwned:Q}=FY4(z);if(jY4(J,Q,z),$.dryRun){R5(y8.default.yellow("Dry-run — no files were changed."));return}if(J.length===0){R5(y8.default.dim("Nothing to remove."));return}if(!G){let K=await g1({message:`Remove ${J.length} oma-owned entries from ${z}?`,initialValue:!1});if(J4(K)||!K){p4("Uninstall cancelled.");return}}kY4(J),R5(y8.default.green("Uninstall complete. User-owned files were preserved."))}function Dr2($){$.command("uninstall").description("Remove oh-my-agent's owned files (preserves oma-config.yaml, mcp.json, and user-authored skills)").option("--dry-run","Preview what would be removed without deleting").option("-y, --yes","Skip confirmation prompt").action(m2(async(z)=>{let G=$.opts();await Ir2({yes:z.yes,dryRun:z.dryRun,global:G.global})}))}U7();var Y1=_2(k5(),1);import{execSync as Er2}from"node:child_process";import{cpSync as nb,existsSync as o$,mkdirSync as z62,readFileSync as pb,rmSync as G62,writeFileSync as J62}from"node:fs";import{homedir as wY4,tmpdir as TY4}from"node:os";import{join as R7}from"node:path";var lb=_2(k5(),1);import{execSync as NY4,spawn as AY4}from"node:child_process";import{realpathSync as Rr2}from"node:fs";import PA from"node:process";var ZW="oh-my-agent";function MY4($=PA.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(PA.env.IS_BINARY==="true")return{packageManager:"binary",isGlobal:!0,updateMessage:"Running as a standalone binary. Download the latest release from GitHub."};let z;try{z=c8(Rr2($))}catch{return{packageManager:"unknown",isGlobal:!1}}if(z.includes("/.npm/_npx")||z.includes("/npm/_npx"))return{packageManager:"npx",isGlobal:!1,updateMessage:"Running via npx, auto-update not applicable."};if(z.includes("/.pnpm/_pnpx")||z.includes("/.cache/pnpm/dlx"))return{packageManager:"pnpx",isGlobal:!1,updateMessage:"Running via pnpx, auto-update not applicable."};if(z.includes("/.bun/install/cache"))return{packageManager:"bunx",isGlobal:!1,updateMessage:"Running via bunx, auto-update not applicable."};if(PA.platform==="darwin")try{let G=NY4(`brew --prefix ${ZW}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=c8(Rr2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${ZW}`,updateMessage:"Installed via Homebrew. Updating in background..."}}}catch{}if(z.includes("/.pnpm/global")||z.includes("/.local/share/pnpm"))return{packageManager:"pnpm",isGlobal:!0,updateCommand:`pnpm add -g ${ZW}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${ZW}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${ZW}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${ZW}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var vr2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function OY4($,z){let G=$.match(vr2),J=z.match(vr2);if(!G||!J)return!1;for(let Q=1;Q<=3;Q++){let K=Number(G[Q]),U=Number(J[Q]);if(K<U)return!0;if(K>U)return!1}return!1}async function IY4($=ZW,z=2000){try{let G=await m1.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function wr2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(PA.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(PA.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await IY4();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!OY4($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=MY4();if(!G.updateCommand)return $.onNotice?.(lb.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return AY4(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(lb.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(lb.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var db={name:"oh-my-agent",version:"8.40.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","generate:skill-data":"node ./scripts/generate-skill-data.mjs",build:"bun run generate:skill-data && bun run sync:readme && bun build cli.ts --outfile bin/cli.js --target node --minify --external @napi-rs/keyring",dev:"bun run generate:skill-data && bun run cli.ts",lint:"biome check .","lint:fix":"biome check --write --unsafe .","check:boundaries":"node ./scripts/check-boundaries.mjs",test:"vitest run","test:coverage":"vitest run --coverage",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^1.1.0","@date-fns/tz":"^1.4.1","@napi-rs/keyring":"^1.3.0",axios:"^1.15.0","better-sqlite3":"^12.9.0",chokidar:"^5.0.0",commander:"^14.0.3","date-fns":"^4.2.1",eld:"^2.0.3","fast-xml-parser":"^5",minimatch:"^10.2.5","p-map":"^7.0.4",picocolors:"^1.1.1","puppeteer-core":"^24",remark:"^15.0.1","remark-frontmatter":"^5.0.0","remark-parse":"^11.0.0","smol-toml":"^1.6.1",unified:"^11.0.5",ws:"^8.18.0",yaml:"^2.8.2",zod:"^4.3.6"},optionalDependencies:{pptxgenjs:"^3.12.0"},devDependencies:{"@biomejs/biome":"^2.4.15","@types/better-sqlite3":"^7.6.13","@types/mdast":"^4.0.4","@types/node":"^24","@types/ws":"^8.18.1","@vitest/coverage-v8":"^4.1.4",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"]}};qi();function RY4(){if((process.env.LANG??"").toLowerCase().startsWith("ko"))return"ko";return"en"}var vY4={"install.sudoRefused":{en:"Refusing to install under sudo. Re-run as the target user.",ko:"sudo로는 설치할 수 없습니다. 대상 사용자로 다시 실행하세요."},"install.cwdHomeWarn":{en:"Running in your HOME directory without --global. This will scatter files in ~/. Are you sure?",ko:"HOME 디렉토리에서 --global 없이 실행 중입니다. ~/ 에 파일이 흩어집니다. 진행할까요?"},"install.ciGlobalWarn":{en:"Running `oma install --global` in CI. This will modify the CI user's HOME.",ko:"CI에서 `oma install --global`을 실행합니다. CI 사용자의 HOME을 수정합니다."},"install.wslHomeInfo":{en:"WSL detected. $HOME is distinct from Windows %USERPROFILE%; oma installs only to the WSL HOME. To install on the Windows side, run from PowerShell.",ko:"WSL이 감지됐습니다. $HOME은 Windows %USERPROFILE%과 다릅니다; oma는 WSL HOME에만 설치합니다. Windows 쪽에 설치하려면 PowerShell에서 실행하세요."},"install.firstGlobalIntro":{en:"This is your first global install of oh-my-agent.",ko:"oh-my-agent를 글로벌로 처음 설치합니다."},"install.lockHeld":{en:"Another oma install/update is running (pid={pid}). Try again in a moment.",ko:"다른 oma install/update가 실행 중입니다 (pid={pid}). 잠시 후 다시 시도하세요."},"install.outroSuccess":{en:`Done! Next steps:
|
|
2459
2459
|
1. Open your project in your IDE
|
|
2460
2460
|
2. Type /orchestrate to spawn a multi-agent workflow
|
|
2461
2461
|
3. Run \`oma doctor\` if anything looks off`,ko:`완료! 다음 단계:
|
package/package.json
CHANGED