oh-my-agent 7.13.0 → 7.14.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/bin/cli.js +2 -2
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -962,7 +962,7 @@ ${JSON.stringify($)}
|
|
|
962
962
|
|
|
963
963
|
`}function Tg2($){let z=[],G=/```json\n([\s\S]*?)\n```/g;for(let J of $.matchAll(G))try{let U=JSON.parse(J[1]??"");if(U&&typeof U.sessionId==="string"&&typeof U.vendor==="string"&&typeof U.agentId==="string"&&typeof U.tokens==="number"&&typeof U.recordedAt==="string")z.push(U)}catch{}return z}function Eg2(){if(!Wt(sP))Ng2(sP,{recursive:!0})}function Rg2($){try{return Og2($,"utf-8")}catch{return""}}function jt($,z){let G=pU.resolve($),J=pU.parse(G).root;while(G!==J){let U=pU.join(G,z);if(Lt.existsSync(U))return U;G=pU.dirname(G)}return null}function vg2($){try{let z=Lt.readFileSync($,"utf-8"),G=Ht.parse(z);if(G&&typeof G==="object"&&!Array.isArray(G))return G;return{}}catch{return{}}}function wg2($){let z={};if(typeof $.tokens==="number")z.tokens=$.tokens;if(typeof $.spawn_count==="number")z.spawnCount=$.spawn_count;if($.per_vendor&&typeof $.per_vendor==="object")z.perVendor={...$.per_vendor};return z}function Bt($=process.cwd()){let z=[jt($,pU.join(".agents","oma-config.yaml")),jt($,pU.join(".agents","config","defaults.yaml"))];for(let G of z){if(!G)continue;let J=vg2(G);if(J.session?.quota_cap)return wg2(J.session.quota_cap)}return null}function Vt($,z){Eg2();let G={...z,sessionId:$,recordedAt:new Date().toISOString()},J=At($),U=Ig2(G);if(!Wt(J))kt(J,Mg2($)+U,"utf-8");else kt(J,U,"utf-8")}function Pg2($){let z=At($),G=Rg2(z);if(!G)return[];return Tg2(G)}function Ft($,z){let G=Pg2($);if(z.spawnCount!==void 0){let J=G.length;if(J>=z.spawnCount)return{exceeded:!0,reason:"spawnCount",current:J,limit:z.spawnCount}}if(z.tokens!==void 0){let J=G.reduce((U,K)=>U+K.tokens,0);if(J>=z.tokens)return{exceeded:!0,reason:"tokens",current:J,limit:z.tokens}}if(z.perVendor){let J={};for(let U of G)J[U.vendor]=(J[U.vendor]??0)+U.tokens;for(let[U,K]of Object.entries(z.perVendor)){if(K===void 0)continue;let X=J[U]??0;if(X>=K)return{exceeded:!0,reason:"perVendor",current:X,limit:K}}}return{exceeded:!1,current:G.reduce((J,U)=>J+U.tokens,0),limit:z.tokens??0}}function ut($){if(!$.exceeded)return"";switch($.reason){case"spawnCount":return`[Session quota] Spawn limit reached: ${$.current} of ${$.limit} spawns used. The orchestrator will not start the next agent until you confirm or increase the limit (session.quota_cap.spawn_count in oma-config.yaml).`;case"tokens":return`[Session quota] Token limit reached: ${$.current.toLocaleString()} of ${$.limit.toLocaleString()} tokens consumed. The orchestrator will not start the next agent until you confirm or increase the limit (session.quota_cap.tokens in oma-config.yaml).`;case"perVendor":return`[Session quota] Per-vendor token limit reached: ${$.current.toLocaleString()} of ${$.limit.toLocaleString()} tokens consumed for this vendor. The orchestrator will not start the next agent until you confirm or increase the limit (session.quota_cap.per_vendor in oma-config.yaml).`;default:return`[Session quota] Usage limit exceeded (current: ${$.current}, limit: ${$.limit}). The orchestrator will not start the next agent until you confirm or adjust your quota cap (session.quota_cap in oma-config.yaml).`}}var bg2=["refactor","architecture","cross-cutting","migration","redesign","overhaul","restructure","rewrite"];function Nt($,z,G){let J=$.toLowerCase(),U=bg2.some((Q)=>J.includes(Q));if(z>=5||G>=3||U)return"Complex";if($.length<200&&z<=2&&G<=1&&!U)return"Simple";return"Medium"}function _g2($,z){let G=z?.acCount??3,J=z?.filesInScope??2;return Nt($,G,J)}var Sg2=".serena/memories";function yg2($=process.cwd()){let z=aU.join($,Sg2);try{if(!T3.existsSync(z))T3.mkdirSync(z,{recursive:!0})}catch(G){console.warn(`[spawn] Could not pre-create memories dir ${z}: ${String(G)}`)}}async function Ot($,z,G,J,U,K){let X=J==="."?FB($):J,Q=aU.resolve(X);if(!T3.existsSync(Q))T3.mkdirSync(Q,{recursive:!0}),console.log(N7.default.dim(`[${$}] Created workspace: ${Q}`));else if(X!==J)console.log(N7.default.blue(`[${$}] Auto-detected workspace: ${X}`));let Z=aU.join(tP(),`subagent-${G}-${$}.log`),k=aU.join(tP(),`subagent-${G}-${$}.pid`);yg2(process.cwd());let Y=HB(z),j=_g2(Y,K);console.log(N7.default.dim(` Difficulty: ${j}`));try{let x=Bt(process.cwd());if(x!==null){let y=Ft(G,x);if(y.exceeded){let c=ut(y);throw console.error(N7.default.red(`[${$}] ${c}`)),Error(`[session-cost] Quota cap exceeded for session ${G}: ${y.reason} (current: ${y.current}, limit: ${y.limit})`)}}}catch(x){if(x instanceof Error&&x.message.startsWith("[session-cost]"))throw x;console.warn(`[${$}] session-cost checkCap error (non-fatal): ${String(x)}`)}let{vendor:W,config:L}=fU($,U),H=AB(W,process.cwd()),A=H?`${Y}
|
|
964
964
|
|
|
965
|
-
${H}`:Y,B=L?.vendors?.[W]||{},V=T3.openSync(Z,"w");console.log(N7.default.blue(`[${$}] Spawning subagent...`)),console.log(N7.default.dim(` Vendor: ${W}`)),console.log(N7.default.dim(` Workspace: ${Q}`)),console.log(N7.default.dim(` Log: ${Z}`));let F=WB(W,B.prompt_flag),u=VB($,W,B,F,A),{command:N,args:I,env:T}=u.invocation;console.log(N7.default.dim(` Dispatch: ${u.mode} (${u.runtimeVendor} -> ${u.targetVendor}, ${u.reason})`));let q=Cg2(N,I,{cwd:Q,stdio:["ignore",V,V],detached:!1,env:T});if(!q.pid)console.error(N7.default.red(`[${$}] Failed to spawn process`)),process.exit(1);T3.writeFileSync(k,q.pid.toString()),console.log(N7.default.green(`[${$}] Started with PID ${q.pid}`));let D=()=>{try{if(T3.existsSync(k))T3.unlinkSync(k);if(T3.existsSync(Z))T3.unlinkSync(Z)}catch{}},v=()=>{if(q.pid&&JG(q.pid))process.kill(q.pid);m(),D(),process.exit()},m=cU(v,v);q.on("exit",(x)=>{if(m(),console.log(N7.default.blue(`[${$}] Exited with code ${x}`)),x!==0&&T3.existsSync(Z)){let y=T3.readFileSync(Z,"utf-8").trim();if(y)console.log(N7.default.red(`[${$}] Log output:`)),console.log(y)}try{Vt(G,{vendor:W,agentId:$,tokens:Math.ceil(A.length/4),estimatedCostNote:`difficulty:${j}`})}catch(y){console.warn(`[${$}] session-cost recordUsage error (non-fatal): ${String(y)}`)}D(),process.exit(x??0)})}async function qt($,z,G=process.cwd()){let J={};for(let U of z){let K=aU.join(G,".serena","memories",`result-${U}.md`),X=aU.join(tP(),`subagent-${$}-${U}.pid`);if(T3.existsSync(K)){let Z=T3.readFileSync(K,"utf-8").match(/^## Status:\s*(\S+)/m);J[U]=Z?.[1]?Z[1]:"completed"}else if(T3.existsSync(X)){let Q=T3.readFileSync(X,"utf-8").trim(),Z=Number.parseInt(Q,10);J[U]=!Number.isNaN(Z)&&JG(Z)?"running":"crashed"}else J[U]="crashed"}for(let[U,K]of Object.entries(J))console.log(`${U}:${K}`)}function Dt($){$.command("agent:spawn <agent-id> <prompt> <session-id>").description("Spawn a subagent (prompt can be inline text or a file path)").option("-m, --model <vendor>","CLI vendor override (gemini/claude/codex/qwen)").option("-w, --workspace <path>","Working directory for the agent (auto-detected if omitted)").action(L5(async(z,G,J,U)=>{await Ot(z,G,J,U.workspace||".",U.model)})),$.command("agent:status <session-id> [agent-ids...]").description("Check status of subagents").option("-r, --root <path>","Root path for memory checks",process.cwd()).action(L5(async(z,G,J)=>{await qt(z,G,J.root)})),$.command("agent:parallel [tasks...]").description("Run multiple sub-agents in parallel").option("-m, --model <vendor>","CLI vendor override (gemini/claude/codex/qwen)").option("-i, --inline","Inline mode: specify tasks as agent:task arguments").option("--no-wait","Don't wait for completion (background mode)").action(L5(async(z,G)=>{await Xt(z,{vendor:G.model,inline:G.inline,noWait:!G.wait})})),$.command("agent:review").description("Run code review using external CLI (codex/claude/gemini)").option("-m, --model <vendor>","CLI vendor (codex/claude/gemini)").option("-p, --prompt <prompt>","Custom review prompt").option("-w, --workspace <path>","Working directory (default: current)").option("--no-uncommitted","Review committed changes only").action(L5(async(z)=>{await Zt({prompt:z.prompt,model:z.model,workspace:z.workspace,uncommitted:z.uncommitted})}))}O7();var YG=d2(q4(),1);import{execSync as vb}from"node:child_process";import*as h2 from"node:fs";import{homedir as Wf2}from"node:os";import{dirname as Ve,join as q5,relative as Fe,resolve as nk,sep as Hf2}from"node:path";var m7={domain:[{name:"oma-architecture",desc:"Architecture specialist for software/system design, module and service boundaries, tradeoff analysis, and stakeholder synthesis. Uses context-aware methods such as diagnostic routing, design-twice comparison, ATAM-style risk analysis, CBAM-style prioritization, and ADR-style decision records."},{name:"oma-backend",desc:"Backend specialist for APIs, databases, authentication with clean architecture (Repository/Service/Router pattern). Use for API, endpoint, REST, database, server, migration, and auth work."},{name:"oma-db",desc:"Database specialist for SQL, NoSQL, and vector database modeling, schema design, normalization, indexing, transactions, integrity, concurrency control, backup, capacity planning, data standards, anti-pattern review, and compliance-aware database design. Use for database, schema, ERD, table design, document model, vector index design, RAG retrieval architecture, migration, query tuning, glossary, capacity estimation, backup strategy, database anti-pattern remediation work, and ISO 27001, ISO 27002, or ISO 22301-aware database recommendations."},{name:"oma-frontend",desc:"Frontend specialist for React, Next.js, TypeScript with FSD-lite architecture, shadcn/ui, and design system alignment. Use for UI, component, page, layout, CSS, Tailwind, and shadcn work."},{name:"oma-mobile",desc:"Mobile specialist for Flutter, React Native, and cross-platform mobile development. Use for mobile app, Flutter, Dart, iOS, Android, Riverpod, and widget work."}],design:[{name:"oma-design",desc:"AI design specialist skill with DESIGN.md management, anti-pattern enforcement, optional Stitch MCP integration, and component library guidance. Covers typography, color systems, motion design (motion/react, GSAP, Three.js), responsive-first layouts, and accessibility (WCAG 2.2)."}],coordination:[{name:"oma-brainstorm",desc:"Design-first ideation that explores user intent, constraints, and approaches before any planning or implementation. Use for brainstorming, ideation, exploring concepts, and evaluating approaches."},{name:"oma-coordination",desc:"Guide for coordinating PM, Frontend, Backend, Mobile, and QA agents on complex projects via CLI. Use for manual step-by-step coordination and workflow guidance."},{name:"oma-orchestrator",desc:"Automated multi-agent orchestrator that spawns CLI subagents in parallel, coordinates via MCP Memory, and monitors progress. Use for orchestration, parallel execution, and automated multi-agent workflows."},{name:"oma-pm",desc:"Product manager that decomposes requirements into actionable tasks with priorities and dependencies. Use for planning, requirements, specification, scope, prioritization, task breakdown, and ISO 21500, ISO 31000, or ISO 38500-aligned planning recommendations."},{name:"oma-qa",desc:"Quality assurance specialist for security, performance, accessibility, comprehensive testing, and quality standard alignment. Use for test, review, security audit, OWASP, coverage, lint work, and ISO/IEC 25010 or ISO/IEC 29119-aligned QA recommendations."}],utility:[{name:"oma-academic-writer",desc:"Academic writing specialist for publication-grade English prose. Drafts, revises, and audits essays, reports, analysis sections, executive summaries, conclusions, and literature reviews while enforcing sentence-structure variation, high-frequency academic verbs, calibrated hedging, and anti-AI stylistic compliance. USE for academic writing, essay polish, paragraph rewrite, prose revision against any rubric tier (HD/D/C, A/B/C, top-band/mid-band, etc.), anti-AI audit, reverse outlining, claim-evidence mapping, and rubric enforcement on assignments."},{name:"oma-debug",desc:"Bug diagnosis and fixing specialist - analyzes errors, identifies root causes, provides fixes, and writes regression tests. Use for bug, debug, error, crash, traceback, exception, and regression work."},{name:"oma-deepsec",desc:"Drive Vercel's `deepsec` agent-powered vulnerability scanner end-to-end: installing the `.deepsec/` workspace, bootstrapping `INFO.md`, running cost-aware `scan` / `process` / `triage` / `revalidate` / `export` passes, gating PRs with `process --diff`, writing custom matchers, and triaging findings. Use whenever the user mentions deepsec, asks an agent to scan a repo for vulnerabilities, runs into `pnpm deepsec` / `bunx deepsec` commands, wants a CI-based PR security review, sees a `.deepsec/` directory, or asks about `INFO.md` / matchers / `process --diff` / `revalidate`, even when the tool name is not spoken. Deepsec scans are expensive (a single full scan can cost hundreds to tens of thousands of dollars) so the skill exists in part to keep the user from getting surprised."},{name:"oma-docs",desc:"Verify documentation references against the current codebase and propose updates for diff-affected docs. Use to check if docs still match reality (broken file paths, CLI commands, config keys, env vars, scripts) and to surface docs that may need updating after code changes."},{name:"oma-hwp",desc:"Convert HWP / HWPX / HWPML files to Markdown using kordoc. Extracts text, headings, tables, lists, images, footnotes, and hyperlinks. Use for Korean word processor files (Hangul), government documents, and AI-ready data preparation."},{name:"oma-image",desc:"Multi-vendor AI image generation with authentication-aware parallel dispatch. Routes to Codex (gpt-image-2 via ChatGPT OAuth) and Pollinations (flux/zimage, free with signup). Gemini provider is present but disabled by default (requires billing). Use for image generation, image creation, visual asset generation, and AI art."},{name:"oma-market",desc:"Market research skill for pain-point extraction, trend detection, competitor positioning, and discovery across community sources (Reddit, HN, Bluesky, Mastodon, GitHub Issues, web). Routes via oma-search transport, deterministic CLI compute, intent-auto SWOT/Porter's 5F/PESTEL frameworks. Use for market research, pain point analysis, trend detection, competitor research, user complaints, voice-of-customer, 시장조사, 사용자 페인, 트렌드, 경쟁구도."},{name:"oma-pdf",desc:"Convert PDF files to Markdown using opendataloader-pdf. Extracts text, tables, headings, lists, and images with correct reading order. Use for PDF parsing, PDF to Markdown conversion, document extraction, and AI-ready data preparation."},{name:"oma-recap",desc:"Analyze conversation histories from multiple AI tools (Claude, Codex, Gemini, Qwen, Cursor) and generate themed daily/period work summaries. Filter by date or time window."},{name:"oma-scholar",desc:"Scholarly research companion using Knows sidecar spec (.knows.yaml). Generates, validates, reviews, queries, and compares structured research-paper sidecars, and fetches them from knows.academy. Use for academic literature search, survey synthesis, paper authoring assistance, and peer review with token-efficient claim/evidence/relation access."},{name:"oma-scm",desc:"SCM (software configuration management) and Git: branching, merges, conflicts, worktrees, baselines, audit readiness, plus Conventional Commits and safe staging."},{name:"oma-search",desc:"Intent-based search router with trust scoring. Routes queries to optimal channels (Context7 docs, native web search, gh/glab code search, Serena local) and attaches domain trust labels. Use for search, find, lookup, reference, docs, code search, and web research."},{name:"oma-skill-creator",desc:"Create or update OMA skills in the SSL-lite human-readable format. Use when adding a new `.agents/skills/{skill-name}/SKILL.md`, converting an existing skill to the standardized Scheduling / Structural Flow / Logical Operations / References structure, or validating whether a skill has enough routing, execution, resource, and safety detail."},{name:"oma-translator",desc:"Context-aware translation that preserves tone, style, and natural word order. Use when translating UI strings, documentation, marketing copy, or any multilingual content. Infers register, domain, and style from the source text and surrounding codebase context."}],infrastructure:[{name:"oma-dev-workflow",desc:"Use when setting up or optimizing developer workflows in a monorepo, managing mise tasks, git hooks, CI/CD pipelines, database migrations, or release automation. Invoke for development environment setup, build automation, testing workflows, and release coordination."},{name:"oma-observability",desc:"Intent-based observability + traceability router across layers, boundaries, and signals. Routes to vendor-specific skills via category taxonomy; owns transport tuning, meta-observability, incident forensics. Use for observability, traceability, telemetry, APM, RUM, metrics, logs, traces, profiles, SLO, incident forensics, tracing architecture work."},{name:"oma-tf-infra",desc:"Infrastructure-as-code specialist for multi-cloud provisioning using Terraform across any provider (AWS, GCP, Azure, Oracle Cloud). Use for terraform plan/apply, state management, compute, databases, storage, networking, IAM, OIDC, cost optimization, policy-as-code, ISO/IEC 42001 AI controls, ISO 22301 continuity, and ISO/IEC/IEEE 42010 architecture documentation."}]},$e={fullstack:["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-tf-infra","oma-dev-workflow"],frontend:["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-pm","oma-qa","oma-debug","oma-scm"],backend:["oma-architecture","oma-brainstorm","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-dev-workflow"],mobile:["oma-architecture","oma-brainstorm","oma-mobile","oma-pm","oma-qa","oma-debug","oma-scm"],devops:["oma-architecture","oma-brainstorm","oma-tf-infra","oma-dev-workflow","oma-pm","oma-qa","oma-debug","oma-scm"],all:[...m7.domain,...m7.design,...m7.coordination,...m7.utility,...m7.infrastructure].map(($)=>$.name)};import*as oU from"node:fs";import{join as Zx5,sep as ze}from"node:path";function z9($){return ze==="/"?$:$.split(ze).join("/")}function r9($){try{if(!oU.lstatSync($).isDirectory())oU.unlinkSync($)}catch{}}import*as Y$ from"node:fs";import{dirname as Dm2,isAbsolute as Mm2,resolve as Im2}from"node:path";var Ge=new Set;function Db($,z,G){if(process.platform!=="win32")return Y$.symlinkSync($,z,G),"symlink";try{return Y$.symlinkSync($,z,G),"symlink"}catch(U){if(!Tm2(U))throw U}let J=Mm2($)?$:Im2(Dm2(z),$);if(G==="dir")return Y$.symlinkSync(J,z,"junction"),qb("junction"),"junction";try{return Y$.linkSync(J,z),qb("hardlink"),"hardlink"}catch{return Y$.copyFileSync(J,z),qb("copy"),"copy"}}function Tm2($){if(!$||typeof $!=="object")return!1;let z=$.code;return z==="EPERM"||z==="EACCES"}var Em2={symlink:"",junction:"note: using directory junctions because symlinks need admin or Developer Mode",hardlink:"note: using hardlinks because symlinks need admin or Developer Mode (content stays in sync via shared inode)",copy:"note: copying files because symlinks and hardlinks both failed (likely cross-volume) — re-run install after editing .agents/* to refresh"};function qb($){if(Ge.has($))return;Ge.add($);let z=Em2[$];if(z)console.warn(z)}import{existsSync as Ib,mkdirSync as vm2,readdirSync as wm2,readFileSync as Ue,writeFileSync as Pm2}from"node:fs";import{join as sU}from"node:path";var bB=d2(n3(),1);function Rm2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function Mb($){if($===void 0||$===null)return;if(Array.isArray($))return $.map((z)=>Mb(z)).filter((z)=>z!==void 0);if(Rm2($))return Object.fromEntries(Object.entries($).map(([z,G])=>[z,Mb(G)]).filter(([,z])=>z!==void 0));return $}function j$($){let z=$.trimStart();if(!z.startsWith("---"))return{frontmatter:{},body:$};let G=z.indexOf(`
|
|
965
|
+
${H}`:Y,B=L?.vendors?.[W]||{},V=T3.openSync(Z,"w");console.log(N7.default.blue(`[${$}] Spawning subagent...`)),console.log(N7.default.dim(` Vendor: ${W}`)),console.log(N7.default.dim(` Workspace: ${Q}`)),console.log(N7.default.dim(` Log: ${Z}`));let F=WB(W,B.prompt_flag),u=VB($,W,B,F,A),{command:N,args:I,env:T}=u.invocation;console.log(N7.default.dim(` Dispatch: ${u.mode} (${u.runtimeVendor} -> ${u.targetVendor}, ${u.reason})`));let q=Cg2(N,I,{cwd:Q,stdio:["ignore",V,V],detached:!1,env:T});if(!q.pid)console.error(N7.default.red(`[${$}] Failed to spawn process`)),process.exit(1);T3.writeFileSync(k,q.pid.toString()),console.log(N7.default.green(`[${$}] Started with PID ${q.pid}`));let D=()=>{try{if(T3.existsSync(k))T3.unlinkSync(k);if(T3.existsSync(Z))T3.unlinkSync(Z)}catch{}},v=()=>{if(q.pid&&JG(q.pid))process.kill(q.pid);m(),D(),process.exit()},m=cU(v,v);q.on("exit",(x)=>{if(m(),console.log(N7.default.blue(`[${$}] Exited with code ${x}`)),x!==0&&T3.existsSync(Z)){let y=T3.readFileSync(Z,"utf-8").trim();if(y)console.log(N7.default.red(`[${$}] Log output:`)),console.log(y)}try{Vt(G,{vendor:W,agentId:$,tokens:Math.ceil(A.length/4),estimatedCostNote:`difficulty:${j}`})}catch(y){console.warn(`[${$}] session-cost recordUsage error (non-fatal): ${String(y)}`)}D(),process.exit(x??0)})}async function qt($,z,G=process.cwd()){let J={};for(let U of z){let K=aU.join(G,".serena","memories",`result-${U}.md`),X=aU.join(tP(),`subagent-${$}-${U}.pid`);if(T3.existsSync(K)){let Z=T3.readFileSync(K,"utf-8").match(/^## Status:\s*(\S+)/m);J[U]=Z?.[1]?Z[1]:"completed"}else if(T3.existsSync(X)){let Q=T3.readFileSync(X,"utf-8").trim(),Z=Number.parseInt(Q,10);J[U]=!Number.isNaN(Z)&&JG(Z)?"running":"crashed"}else J[U]="crashed"}for(let[U,K]of Object.entries(J))console.log(`${U}:${K}`)}function Dt($){$.command("agent:spawn <agent-id> <prompt> <session-id>").description("Spawn a subagent (prompt can be inline text or a file path)").option("-m, --model <vendor>","CLI vendor override (gemini/claude/codex/qwen)").option("-w, --workspace <path>","Working directory for the agent (auto-detected if omitted)").action(L5(async(z,G,J,U)=>{await Ot(z,G,J,U.workspace||".",U.model)})),$.command("agent:status <session-id> [agent-ids...]").description("Check status of subagents").option("-r, --root <path>","Root path for memory checks",process.cwd()).action(L5(async(z,G,J)=>{await qt(z,G,J.root)})),$.command("agent:parallel [tasks...]").description("Run multiple sub-agents in parallel").option("-m, --model <vendor>","CLI vendor override (gemini/claude/codex/qwen)").option("-i, --inline","Inline mode: specify tasks as agent:task arguments").option("--no-wait","Don't wait for completion (background mode)").action(L5(async(z,G)=>{await Xt(z,{vendor:G.model,inline:G.inline,noWait:!G.wait})})),$.command("agent:review").description("Run code review using external CLI (codex/claude/gemini)").option("-m, --model <vendor>","CLI vendor (codex/claude/gemini)").option("-p, --prompt <prompt>","Custom review prompt").option("-w, --workspace <path>","Working directory (default: current)").option("--no-uncommitted","Review committed changes only").action(L5(async(z)=>{await Zt({prompt:z.prompt,model:z.model,workspace:z.workspace,uncommitted:z.uncommitted})}))}O7();var YG=d2(q4(),1);import{execSync as vb}from"node:child_process";import*as h2 from"node:fs";import{homedir as Wf2}from"node:os";import{dirname as Ve,join as q5,relative as Fe,resolve as nk,sep as Hf2}from"node:path";var m7={domain:[{name:"oma-architecture",desc:"Architecture specialist for software/system design, module and service boundaries, tradeoff analysis, and stakeholder synthesis. Uses context-aware methods such as diagnostic routing, design-twice comparison, ATAM-style risk analysis, CBAM-style prioritization, and ADR-style decision records."},{name:"oma-backend",desc:"Backend specialist for APIs, databases, authentication with clean architecture (Repository/Service/Router pattern). Use for API, endpoint, REST, database, server, migration, and auth work."},{name:"oma-db",desc:"Database specialist for SQL, NoSQL, and vector database modeling, schema design, normalization, indexing, transactions, integrity, concurrency control, backup, capacity planning, data standards, anti-pattern review, and compliance-aware database design. Use for database, schema, ERD, table design, document model, vector index design, RAG retrieval architecture, migration, query tuning, glossary, capacity estimation, backup strategy, database anti-pattern remediation work, and ISO 27001, ISO 27002, or ISO 22301-aware database recommendations."},{name:"oma-frontend",desc:"Frontend specialist for React, Next.js, TypeScript with FSD-lite architecture, shadcn/ui, and design system alignment. Use for UI, component, page, layout, CSS, Tailwind, and shadcn work."},{name:"oma-mobile",desc:"Mobile specialist for Flutter, React Native, and cross-platform mobile development. Use for mobile app, Flutter, Dart, iOS, Android, Riverpod, and widget work."}],design:[{name:"oma-design",desc:"AI design specialist skill with DESIGN.md management, anti-pattern enforcement, optional Stitch MCP integration, and component library guidance. Covers typography, color systems, motion design (motion/react, GSAP, Three.js), responsive-first layouts, and accessibility (WCAG 2.2)."}],coordination:[{name:"oma-brainstorm",desc:"Design-first ideation that explores user intent, constraints, and approaches before any planning or implementation. Use for brainstorming, ideation, exploring concepts, and evaluating approaches."},{name:"oma-coordination",desc:"Guide for coordinating PM, Frontend, Backend, Mobile, and QA agents on complex projects via CLI. Use for manual step-by-step coordination and workflow guidance."},{name:"oma-orchestrator",desc:"Automated multi-agent orchestrator that spawns CLI subagents in parallel, coordinates via MCP Memory, and monitors progress. Use for orchestration, parallel execution, and automated multi-agent workflows."},{name:"oma-pm",desc:"Product manager that decomposes requirements into actionable tasks with priorities and dependencies. Use for planning, requirements, specification, scope, prioritization, task breakdown, and ISO 21500, ISO 31000, or ISO 38500-aligned planning recommendations."},{name:"oma-qa",desc:"Quality assurance specialist for security, performance, accessibility, comprehensive testing, and quality standard alignment. Use for test, review, security audit, OWASP, coverage, lint work, and ISO/IEC 25010 or ISO/IEC 29119-aligned QA recommendations."}],utility:[{name:"oma-academic-writer",desc:"Academic writing specialist for publication-grade English prose. Drafts, revises, and audits essays, reports, analysis sections, executive summaries, conclusions, and literature reviews while enforcing sentence-structure variation, high-frequency academic verbs, calibrated hedging, and anti-AI stylistic compliance. USE for academic writing, essay polish, paragraph rewrite, prose revision against any rubric tier (HD/D/C, A/B/C, top-band/mid-band, etc.), anti-AI audit, reverse outlining, claim-evidence mapping, and rubric enforcement on assignments."},{name:"oma-debug",desc:"Bug diagnosis and fixing specialist - analyzes errors, identifies root causes, provides fixes, and writes regression tests. Use for bug, debug, error, crash, traceback, exception, and regression work."},{name:"oma-deepsec",desc:"Drive Vercel's `deepsec` agent-powered vulnerability scanner end-to-end: installing the `.deepsec/` workspace, bootstrapping `INFO.md`, running cost-aware `scan` / `process` / `triage` / `revalidate` / `export` passes, gating PRs with `process --diff`, writing custom matchers, and triaging findings. Use whenever the user mentions deepsec, asks an agent to scan a repo for vulnerabilities, runs into `pnpm deepsec` / `bunx deepsec` commands, wants a CI-based PR security review, sees a `.deepsec/` directory, or asks about `INFO.md` / matchers / `process --diff` / `revalidate`, even when the tool name is not spoken. Deepsec scans are expensive (a single full scan can cost hundreds to tens of thousands of dollars) so the skill exists in part to keep the user from getting surprised."},{name:"oma-docs",desc:"Verify documentation references against the current codebase and propose updates for diff-affected docs. Use to check if docs still match reality (broken file paths, CLI commands, config keys, env vars, scripts) and to surface docs that may need updating after code changes."},{name:"oma-hwp",desc:"Convert HWP / HWPX / HWPML files to Markdown using kordoc. Extracts text, headings, tables, lists, images, footnotes, and hyperlinks. Use for Korean word processor files (Hangul), government documents, and AI-ready data preparation."},{name:"oma-image",desc:"Multi-vendor AI image generation with authentication-aware parallel dispatch. Routes to Codex (gpt-image-2 via ChatGPT OAuth) and Pollinations (flux/zimage, free with signup). Gemini provider is present but disabled by default (requires billing). Use for image generation, image creation, visual asset generation, and AI art."},{name:"oma-market",desc:"Market research skill for pain-point extraction, trend detection, competitor positioning, and discovery across community sources (Reddit, HN, Bluesky, Mastodon, GitHub Issues, web). Routes via oma-search transport, deterministic CLI compute, intent-auto SWOT/Porter's 5F/PESTEL frameworks. Use for market research, pain point analysis, trend detection, competitor research, user complaints, voice-of-customer, 시장조사, 사용자 페인, 트렌드, 경쟁구도."},{name:"oma-pdf",desc:"Convert PDF files to Markdown using opendataloader-pdf. Extracts text, tables, headings, lists, and images with correct reading order. Use for PDF parsing, PDF to Markdown conversion, document extraction, and AI-ready data preparation."},{name:"oma-recap",desc:"Analyze conversation histories from multiple AI tools (Claude, Codex, Gemini, Qwen, Cursor) and generate themed daily/period work summaries. Filter by date or time window."},{name:"oma-scholar",desc:"Scholarly research companion using Knows sidecar spec (.knows.yaml). Generates, validates, reviews, queries, and compares structured research-paper sidecars, and fetches them from knows.academy. Use for academic literature search, survey synthesis, paper authoring assistance, and peer review with token-efficient claim/evidence/relation access."},{name:"oma-scm",desc:"SCM (software configuration management) and Git: branching, merges, conflicts, worktrees, baselines, audit readiness, plus Conventional Commits and safe staging."},{name:"oma-search",desc:"Intent-based search router with trust scoring. Routes queries to optimal channels (Context7 docs, native web search, gh/glab code search, Serena local) and attaches domain trust labels. Use for search, find, lookup, reference, docs, code search, and web research."},{name:"oma-skill-creator",desc:"Create or update OMA skills in the SSL-lite human-readable format. Use when adding a new `.agents/skills/{skill-name}/SKILL.md`, converting an existing skill to the standardized Scheduling / Structural Flow / Logical Operations / References structure, or validating whether a skill has enough routing, execution, resource, and safety detail."},{name:"oma-translator",desc:"Context-aware translation that preserves tone, style, and natural word order. Use when translating UI strings, documentation, marketing copy, or any multilingual content. Infers register, domain, and style from the source text and surrounding codebase context."},{name:"oma-voice",desc:"Local-first text-to-speech and speech-to-text via the Voicebox MCP server. Generates speech from cloned or preset voice profiles for agent notifications, content voiceovers, and audio asset creation, and transcribes audio files for meeting notes or memos. Runs entirely on-device with no cloud, no API keys, no per-call cost. Use for voice generation, TTS, STT, transcription, voiceover, narration, dictation, audio asset work."}],infrastructure:[{name:"oma-dev-workflow",desc:"Use when setting up or optimizing developer workflows in a monorepo, managing mise tasks, git hooks, CI/CD pipelines, database migrations, or release automation. Invoke for development environment setup, build automation, testing workflows, and release coordination."},{name:"oma-observability",desc:"Intent-based observability + traceability router across layers, boundaries, and signals. Routes to vendor-specific skills via category taxonomy; owns transport tuning, meta-observability, incident forensics. Use for observability, traceability, telemetry, APM, RUM, metrics, logs, traces, profiles, SLO, incident forensics, tracing architecture work."},{name:"oma-tf-infra",desc:"Infrastructure-as-code specialist for multi-cloud provisioning using Terraform across any provider (AWS, GCP, Azure, Oracle Cloud). Use for terraform plan/apply, state management, compute, databases, storage, networking, IAM, OIDC, cost optimization, policy-as-code, ISO/IEC 42001 AI controls, ISO 22301 continuity, and ISO/IEC/IEEE 42010 architecture documentation."}]},$e={fullstack:["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-tf-infra","oma-dev-workflow"],frontend:["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-pm","oma-qa","oma-debug","oma-scm"],backend:["oma-architecture","oma-brainstorm","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-dev-workflow"],mobile:["oma-architecture","oma-brainstorm","oma-mobile","oma-pm","oma-qa","oma-debug","oma-scm"],devops:["oma-architecture","oma-brainstorm","oma-tf-infra","oma-dev-workflow","oma-pm","oma-qa","oma-debug","oma-scm"],all:[...m7.domain,...m7.design,...m7.coordination,...m7.utility,...m7.infrastructure].map(($)=>$.name)};import*as oU from"node:fs";import{join as Zx5,sep as ze}from"node:path";function z9($){return ze==="/"?$:$.split(ze).join("/")}function r9($){try{if(!oU.lstatSync($).isDirectory())oU.unlinkSync($)}catch{}}import*as Y$ from"node:fs";import{dirname as Dm2,isAbsolute as Mm2,resolve as Im2}from"node:path";var Ge=new Set;function Db($,z,G){if(process.platform!=="win32")return Y$.symlinkSync($,z,G),"symlink";try{return Y$.symlinkSync($,z,G),"symlink"}catch(U){if(!Tm2(U))throw U}let J=Mm2($)?$:Im2(Dm2(z),$);if(G==="dir")return Y$.symlinkSync(J,z,"junction"),qb("junction"),"junction";try{return Y$.linkSync(J,z),qb("hardlink"),"hardlink"}catch{return Y$.copyFileSync(J,z),qb("copy"),"copy"}}function Tm2($){if(!$||typeof $!=="object")return!1;let z=$.code;return z==="EPERM"||z==="EACCES"}var Em2={symlink:"",junction:"note: using directory junctions because symlinks need admin or Developer Mode",hardlink:"note: using hardlinks because symlinks need admin or Developer Mode (content stays in sync via shared inode)",copy:"note: copying files because symlinks and hardlinks both failed (likely cross-volume) — re-run install after editing .agents/* to refresh"};function qb($){if(Ge.has($))return;Ge.add($);let z=Em2[$];if(z)console.warn(z)}import{existsSync as Ib,mkdirSync as vm2,readdirSync as wm2,readFileSync as Ue,writeFileSync as Pm2}from"node:fs";import{join as sU}from"node:path";var bB=d2(n3(),1);function Rm2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function Mb($){if($===void 0||$===null)return;if(Array.isArray($))return $.map((z)=>Mb(z)).filter((z)=>z!==void 0);if(Rm2($))return Object.fromEntries(Object.entries($).map(([z,G])=>[z,Mb(G)]).filter(([,z])=>z!==void 0));return $}function j$($){let z=$.trimStart();if(!z.startsWith("---"))return{frontmatter:{},body:$};let G=z.indexOf(`
|
|
966
966
|
---`,3);if(G===-1)return{frontmatter:{},body:$};let J=z.slice(3,G).trim(),U=z.slice(G+4);try{let K=bB.parse(J);return{frontmatter:K&&typeof K==="object"?K:{},body:U}}catch{return{frontmatter:{},body:U}}}function rU($,z){let G=Object.fromEntries(Object.entries($).map(([U,K])=>[U,Mb(K)]).filter(([,U])=>U!==void 0));if(Object.keys(G).length===0)return`---
|
|
967
967
|
---
|
|
968
968
|
|
|
@@ -1561,7 +1561,7 @@ ${cG.default.dim("Examples:")}
|
|
|
1561
1561
|
spawn_error:${Z.message}`})})})}async function xJ2($,z,G={}){let J=G.host??"github",U=G.limit??20,K=performance.now();if(J==="gitlab"){let Y=new URLSearchParams({scope:"blobs",search:$,per_page:String(U)}),{code:j,stdout:W,stderr:L}=await yJ2("glab",["api",`/search?${Y.toString()}`],z);return hJ2("gitlab",$,j,W,L,performance.now()-K)}let X=["search","code",$,"--limit",String(U),"--json","repository,path,url,textMatches"];if(G.language)X.push("--language",G.language);if(G.repo)X.push("--repo",G.repo);let{code:Q,stdout:Z,stderr:k}=await yJ2("gh",X,z);return hJ2("github",$,Q,Z,k,performance.now()-K)}function hJ2($,z,G,J,U,K){let X=Math.round(K);if(G===null||G!==0){let Q=U.trim();if(/command not found|ENOENT/i.test(Q))return{url:`search:${$}:${z}`,status:"error",strategy:"api",platform:`${$}-cli`,content:"",elapsedMs:X,signals:[],error:$==="github"?"GitHub CLI (gh) not installed. https://cli.github.com/":"GitLab CLI (glab) not installed. https://gitlab.com/gitlab-org/cli"};if(/rate limit/i.test(Q))return{url:`search:${$}:${z}`,status:"blocked",strategy:"api",platform:`${$}-cli`,content:"",elapsedMs:X,signals:[{kind:"rate-limit",detail:Q}],error:Q};return{url:`search:${$}:${z}`,status:"error",strategy:"api",platform:`${$}-cli`,content:"",elapsedMs:X,signals:[],error:Q||`${$} cli exited ${G}`}}return{url:`search:${$}:${z}`,status:"ok",strategy:"api",platform:`${$}-cli`,content:J.trim(),contentType:"application/json",elapsedMs:X,signals:[]}}import{spawn as R$5}from"node:child_process";function v$5(){return process.env.OMA_YTDLP??"yt-dlp"}async function w$5($,z){return new Promise((G)=>{let J=R$5(v$5(),$,{stdio:["ignore","pipe","pipe"]}),U="",K="";J.stdout.on("data",(Q)=>{U+=Q.toString()}),J.stderr.on("data",(Q)=>{K+=Q.toString()});let X=()=>J.kill("SIGTERM");z.signal?.addEventListener("abort",X),J.on("close",(Q)=>{z.signal?.removeEventListener("abort",X),G({code:Q,stdout:U,stderr:K})}),J.on("error",(Q)=>{z.signal?.removeEventListener("abort",X),G({code:-1,stdout:U,stderr:`${K}
|
|
1562
1562
|
spawn_error:${Q.message}`})})})}async function iJ2($,z,G={}){let J=performance.now(),U=["--dump-json","--no-warnings","--skip-download"];if(G.format)U.push("-f",G.format);if(G.subtitles){if(U.push("--write-sub","--write-auto-sub","--sub-format","vtt"),G.subLangs?.length)U.push("--sub-lang",G.subLangs.join(","))}U.push($.toString());let{code:K,stdout:X,stderr:Q}=await w$5(U,z),Z=Math.round(performance.now()-J);if(K===null||K!==0){let k=Q.trim();if(/executable not found|ENOENT/i.test(k))return{url:$.toString(),status:"error",strategy:"api",platform:"media",content:"",elapsedMs:Z,signals:[],error:"yt-dlp not installed. Install via `pip install yt-dlp` or `brew install yt-dlp`."};return{url:$.toString(),status:"error",strategy:"api",platform:"media",content:X,elapsedMs:Z,signals:[],error:k||`yt-dlp exited with code ${K}`}}return{url:$.toString(),status:"ok",strategy:"api",platform:"media",content:X.trim(),contentType:"application/json",elapsedMs:Z,signals:[]}}J8();var Ru=/<meta\s+([^>]+)>/gi,vu=/(\w[\w-]*)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/g,$x=/<script[^>]+type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi,P$5=/<title[^>]*>([\s\S]*?)<\/title>/i,zx=/<link\s+([^>]+)>/gi;function gJ2($){let z={};vu.lastIndex=0;let G=vu.exec($);while(G!==null){let J=G[1]?.toLowerCase();if(!J){G=vu.exec($);continue}z[J]=G[2]??G[3]??G[4]??"",G=vu.exec($)}return z}function wu($){let z={},G=[],J=[],U;Ru.lastIndex=0;let K=Ru.exec($);while(K!==null){let j=K[1];if(!j){K=Ru.exec($);continue}let W=gJ2(j),L=W.property??"",H=W.name??"",A=W.content??"";if(L.startsWith("og:"))z[L.slice(3)]=A;if(H==="description"&&!U)U=A;if(H==="twitter:description"&&!U)U=A;K=Ru.exec($)}zx.lastIndex=0;let X=zx.exec($);while(X!==null){let j=X[1];if(j){let W=gJ2(j);if(W.rel==="alternate"&&W.type&&(W.type.includes("rss")||W.type.includes("atom")))G.push({type:W.type,href:W.href??"",title:W.title})}X=zx.exec($)}$x.lastIndex=0;let Q=$x.exec($);while(Q!==null){let j=Q[1];if(j)try{J.push(JSON.parse(j))}catch{}Q=$x.exec($)}let k=P$5.exec($)?.[1]?.trim(),Y={};if(Object.keys(z).length>0)Y.ogp=z;if(J.length>0)Y.jsonLd=J;if(U)Y.description=U;if(k)Y.title=k;if(G.length>0)Y.alternate=G;return Y}async function mJ2($,z){try{let G=await f1($.toString(),{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal}),J=wu(G.text);return{url:$.toString(),status:G.ok?"ok":"error",strategy:"probe",platform:"metadata",httpStatus:G.status,content:G.text,contentType:G.headers.get("content-type")??void 0,elapsedMs:G.elapsedMs,signals:[],metadata:J}}catch(G){return{url:$.toString(),status:"error",strategy:"probe",platform:"metadata",content:"",elapsedMs:0,signals:[],error:G instanceof Error?G.message:String(G)}}}b$();iY();J8();b$();F3();var b$5=["archive.ph","archive.is","archive.md","archive.vn","archive.li"];function C$5($){return`https://${$.hostname.replace(/\./g,"-")}.cdn.ampproject.org/c/s/${$.hostname}${$.pathname}${$.search}`}async function _$5($,z){try{let G=C$5($),J=await f1(G,{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(!J.ok||J.text.length<200)return null;let U=z7(J);return{url:$.toString(),status:D6(J,U),strategy:"archive",provenance:"amp",platform:"amp",httpStatus:J.status,content:J.text,contentType:J.headers.get("content-type")??void 0,elapsedMs:J.elapsedMs,signals:U}}catch{return null}}async function S$5($,z){for(let G of b$5){if(z.signal?.aborted)break;try{let J=`https://${G}/newest/${$.toString()}`,U=await f1(J,{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(!U.ok||U.text.length<200)continue;let K=z7(U);return{url:$.toString(),status:D6(U,K),strategy:"archive",provenance:"archive-today",platform:G,httpStatus:U.status,content:U.text,contentType:U.headers.get("content-type")??void 0,elapsedMs:U.elapsedMs,signals:K}}catch{}}return null}async function y$5($,z){try{let G=await f1(`https://archive.org/wayback/available?url=${encodeURIComponent($.toString())}`,{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(!G.ok)return null;let U=JSON.parse(G.text).archived_snapshots?.closest;if(!U?.available||!U.url)return null;let K=await f1(U.url,{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(!K.ok||K.text.length<200)return null;let X=z7(K);return{url:$.toString(),status:D6(K,X),strategy:"archive",provenance:"wayback",platform:"wayback",httpStatus:K.status,content:K.text,contentType:K.headers.get("content-type")??void 0,elapsedMs:K.elapsedMs,signals:X}}catch{return null}}async function kj($,z){let G=[()=>_$5($,z),()=>S$5($,z),()=>y$5($,z)],J=performance.now();for(let U of G){if(z.signal?.aborted)break;let K=await U();if(K)return K}return{...K1({url:$.toString(),strategy:"archive",error:Error("all archive sources exhausted")}),elapsedMs:Math.round(performance.now()-J)}}b$();F3();import{existsSync as EM2}from"node:fs";import{platform as RE5}from"node:os";var vE5={darwin:["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","/Applications/Brave Browser.app/Contents/MacOS/Brave Browser","/Applications/Chromium.app/Contents/MacOS/Chromium"],linux:["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/usr/bin/chromium","/usr/bin/chromium-browser","/usr/bin/microsoft-edge","/usr/bin/brave-browser"],win32:["C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe","C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe","C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"]};function Gn(){if(process.env.OMA_CHROME_PATH&&EM2(process.env.OMA_CHROME_PATH))return process.env.OMA_CHROME_PATH;let $=vE5[RE5()]??[];for(let z of $)if(EM2(z))return z;return null}async function wE5(){try{let $=await Promise.resolve().then(() => (TM2(),IM2));return $.default??$}catch{return null}}async function RM2($,z,G={}){let J=await wE5();if(!J)return K1({url:$.toString(),strategy:"browser",error:Error("puppeteer-core not installed. Run: bun add puppeteer-core")});let U=Gn();if(!U)return K1({url:$.toString(),strategy:"browser",error:Error("Chrome/Chromium not found. Install a Chromium-based browser or set OMA_CHROME_PATH.")});let K=performance.now(),X=await J.launch({executablePath:U,headless:"new",args:["--disable-blink-features=AutomationControlled","--disable-dev-shm-usage","--no-sandbox"]});try{let Q=await X.newPage();if(await Q.setViewport({width:1280,height:900}),await Q.setExtraHTTPHeaders({"Accept-Language":z.locale}),z.userAgent)await Q.setUserAgent(z.userAgent);let Z=[];if(G.captureNetwork)Q.on("response",(B)=>{let V=B.url(),F=B.headers(),u=F["content-type"]??"";if(!V.startsWith($.origin))return;if(!u.includes("json")&&!u.includes("xml"))return;let N=F["access-control-request-method"]??"GET";Z.push({url:V,status:B.status(),method:N,contentType:u})});let k=await Q.goto($.toString(),{waitUntil:"networkidle2",timeout:z.timeoutMs});if(G.waitSelector)await Q.waitForFunction(`document.querySelector(${JSON.stringify(G.waitSelector)}) !== null`,{timeout:z.timeoutMs});else if(G.waitMs&&G.waitMs>0)await new Promise((B)=>setTimeout(B,G.waitMs));let Y=await Q.content(),j=k?.status()??0,W=new Headers;if(k)for(let[B,V]of Object.entries(k.headers()))try{W.set(B,V)}catch{}let L={ok:j>=200&&j<400,status:j,headers:W,url:$.toString(),text:Y,elapsedMs:Math.round(performance.now()-K),redirected:!1},H=z7(L),A=Math.round(performance.now()-K);return{url:$.toString(),status:T92(H)?"blocked":Y.length<200?"error":"ok",strategy:"browser",httpStatus:j,content:Y,contentType:W.get("content-type")??"text/html",elapsedMs:A,signals:H,hiddenApis:G.captureNetwork?Z:void 0}}catch(Q){let Z=Math.round(performance.now()-K);return{...K1({url:$.toString(),strategy:"browser",error:Q}),elapsedMs:Z}}finally{await X.close()}}IS();J8();b$();F3();var vM2="https://r.jina.ai/";function PE5($){let z=`${$.protocol}//${$.hostname}`,G=$.hostname.startsWith("m.")?$.hostname:`m.${$.hostname.replace(/^www\./,"")}`,J=new URL($.toString());return J.hostname=G,[{label:"jina",url:`${vM2}${$.toString()}`,headers:bG({accept:"text/plain"})},{label:"jina-json",url:`${vM2}${$.toString()}`,headers:bG({accept:"application/json"})},{label:"curl-desktop",url:$.toString(),headers:bG({userAgent:G8.desktopFirefox,referer:z})},{label:"curl-mobile",url:J.toString(),headers:bG({userAgent:G8.mobileSafari,referer:z})},{label:"curl-googlebot",url:$.toString(),headers:bG({userAgent:G8.googlebot})}]}function bE5($,z){if(!$.startsWith("jina"))return z;return z}async function wM2($,z){let G=PE5($),J=new AbortController;if(z.signal)if(z.signal.aborted)J.abort(z.signal.reason);else z.signal.addEventListener("abort",()=>J.abort(z.signal?.reason));let U=performance.now(),K={},X=null,Q=G.map(async(Z)=>{let k=await f1(Z.url,{headers:Z.headers,timeoutMs:z.timeoutMs,signal:J.signal,locale:z.locale}),Y=z7(k);if(Z.label.startsWith("jina")){let j=I92(k);if(j)throw X=j,Error(`jina-quota:${j.detail}`)}if(!CE5(k,Y))throw K[Z.label]=`status=${k.status} size=${k.text.length}`,Error(`weak-response:${Z.label}`);return{label:Z.label,resp:k,signals:Y}});try{let Z=await Promise.any(Q);J.abort();let k=Math.round(performance.now()-U);return{url:$.toString(),status:D6(Z.resp,Z.signals),strategy:"probe",platform:Z.label,httpStatus:Z.resp.status,content:bE5(Z.label,Z.resp.text),contentType:Z.resp.headers.get("content-type")??void 0,elapsedMs:k,signals:X?[...Z.signals,X]:Z.signals}}catch(Z){let k=Math.round(performance.now()-U),Y=Object.entries(K).map(([j,W])=>`${j}:${W}`).join(" ");if(X)return{...K1({url:$.toString(),error:Error(`probe failed — ${Y}`),strategy:"probe"}),elapsedMs:k,signals:[X]};return{...K1({url:$.toString(),error:Z instanceof AggregateError?Error(Y):Z,strategy:"probe"}),elapsedMs:k}}}function CE5($,z){if(!$.ok)return!1;if($.text.length<200)return!1;if(z.some((G)=>G.kind==="waf-body"||G.kind==="challenge-body"||G.kind==="js-essential"||G.kind==="http-status"))return!1;return!0}var _E5=["api","probe","impersonate","browser","archive"];function SE5($){if($.only?.length)return $.only;let z=_E5.slice();if(!$.includeArchive)z=z.filter((G)=>G!=="archive");if($.skip?.length)z=z.filter((G)=>!$.skip?.includes(G));return z}async function PM2($,z,G){switch($){case"api":return await jF(z,G)??null;case"probe":return wM2(z,G);case"impersonate":return YF(z,G);case"browser":return RM2(z,G);case"archive":return kj(z,G)}}function Jn($){if($.status==="ok")return!0;if($.status==="auth-required"&&R92($.signals))return!0;return!1}function yE5($){return $.status==="auth-required"||$.status==="invalid-input"||$.status==="not-found"}async function hE5($){let z=Math.floor(Math.random()*500);await new Promise((G)=>setTimeout(G,$+z))}function xE5($){let z=$.find((U)=>U.kind==="rate-limit");if(!z)return 1500;let G=z.detail.match(/retry-after=(\d+)/);if(!G?.[1])return 1500;let J=Number.parseInt(G[1],10);if(Number.isNaN(J)||J>10)return 1500;return J*1000}async function bM2($,z,G={}){let J=SE5(G),U=[],K=new Set,X=null,Q=!1;for(let Z of J){if(z.signal?.aborted)break;if(Q&&Z==="impersonate")continue;let k=await PM2(Z,$,z);if(!k)continue;if(U.push({strategy:Z,platform:k.platform,status:k.status,httpStatus:k.httpStatus,elapsedMs:k.elapsedMs,signals:k.signals,error:k.error}),k.signals.some((Y)=>Y.kind==="js-essential"))Q=!0;if(Jn(k))return k.attempts=U,k;if(yE5(k))return k.attempts=U,k;if(G.retryOnRateLimit!==!1&&v92(k.signals)&&!K.has(Z)){K.add(Z),await hE5(xE5(k.signals));let Y=await PM2(Z,$,z);if(Y){if(U.push({strategy:Z,platform:Y.platform,status:Y.status,httpStatus:Y.httpStatus,elapsedMs:Y.elapsedMs,signals:Y.signals,error:Y.error}),Jn(Y))return Y.attempts=U,Y;X=Y;continue}}X=k}if(!J.includes("archive")&&G.includeArchive!==!1){let Z=await kj($,z);if(U.push({strategy:"archive",platform:Z.platform,status:Z.status,httpStatus:Z.httpStatus,elapsedMs:Z.elapsedMs,signals:Z.signals,error:Z.error}),Jn(Z))return Z.attempts=U,Z;X=Z}if(X)return X.attempts=U,X;return{url:$.toString(),status:"error",strategy:J[0]??"probe",content:"",elapsedMs:0,signals:[],attempts:U,error:"all strategies failed"}}J8();var FI2=d2(BI2(),1);var Zv5=["/rss","/feed","/atom.xml","/rss.xml","/index.xml"],kv5=new FI2.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text"});function Yn($){if($===void 0||$===null)return[];return Array.isArray($)?$:[$]}function D3($){if($==null)return;if(typeof $==="string")return $;if(typeof $==="object"){let z=$;if(typeof z["#text"]==="string")return z["#text"];if(typeof z["#cdata"]==="string")return z["#cdata"]}return}function VI2($){for(let z of Yn($)){let G=z?.["@_href"],J=z?.["@_rel"];if(typeof G==="string"&&(J===void 0||J==="alternate"))return G}return}function uI2($){let z;try{z=kv5.parse($)}catch{return null}let G=z.rss;if(G){let U=G.channel;if(!U)return null;let K=Yn(U.item);return{kind:"rss",title:D3(U.title),description:D3(U.description),link:D3(U.link),entries:K.map((X)=>({title:D3(X.title),link:D3(X.link),pubDate:D3(X.pubDate),description:D3(X.description),content:D3(X["content:encoded"])??D3(X.content)}))}}let J=z.feed;if(J){let U=Yn(J.entry);return{kind:"atom",title:D3(J.title),description:D3(J.subtitle),link:VI2(J.link),entries:U.map((K)=>({title:D3(K.title),link:VI2(K.link),pubDate:D3(K.published)??D3(K.updated),description:D3(K.summary),content:D3(K.content)??D3(K.summary)}))}}return null}async function NI2($,z){let G=performance.now(),J;try{let K=await f1($.toString(),{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(K.ok)J=wu(K.text).alternate?.[0]?.href}catch{}let U=new Set;if(J)try{U.add(new URL(J,$).toString())}catch{}for(let K of Zv5)U.add(new URL(K,`${$.protocol}//${$.host}`).toString());for(let K of U){if(z.signal?.aborted)break;try{let X=await f1(K,{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(!X.ok||X.text.length<50)continue;let Q=uI2(X.text);if(!Q||Q.entries.length===0)continue;return{url:$.toString(),status:"ok",strategy:"probe",platform:"rss",httpStatus:X.status,content:X.text,contentType:X.headers.get("content-type")??void 0,elapsedMs:Math.round(performance.now()-G),signals:[],feedUrl:K,feed:Q}}catch{}}return{url:$.toString(),status:"not-found",strategy:"probe",platform:"rss",content:"",elapsedMs:Math.round(performance.now()-G),signals:[],error:"no RSS/Atom feed discovered"}}function OI2($,z="en-US"){let[G,J]=z.split("-"),U=new URL("https://news.google.com/rss/search");return U.searchParams.set("q",$),U.searchParams.set("hl",G??"en"),U.searchParams.set("gl",J??"US"),U.searchParams.set("ceid",`${J??"US"}:${G??"en"}`),U.toString()}iY();J8();var GM={"github.com":{domain:"github.com",level:"verified",score:0.95,tags:["code-host"],source:"registry"},"docs.github.com":{domain:"docs.github.com",level:"verified",score:0.95,tags:["lang-docs"],source:"registry"},"developer.mozilla.org":{domain:"developer.mozilla.org",level:"verified",score:0.95,tags:["lang-docs"],source:"registry"},"nextjs.org":{domain:"nextjs.org",level:"verified",score:0.9,tags:["vendor","lang-docs"],source:"registry"},"vercel.com":{domain:"vercel.com",level:"verified",score:0.9,tags:["vendor"],source:"registry"},"typescriptlang.org":{domain:"typescriptlang.org",level:"verified",score:0.95,tags:["lang-docs"],source:"registry"},"stackoverflow.com":{domain:"stackoverflow.com",level:"community",score:0.7,tags:["qna"],source:"registry"},"dev.to":{domain:"dev.to",level:"external",score:0.4,tags:["blog"],source:"registry"},"medium.com":{domain:"medium.com",level:"external",score:0.35,tags:["blog"],source:"registry"},"npmjs.com":{domain:"npmjs.com",level:"verified",score:0.9,tags:["registry"],source:"registry"},"pypi.org":{domain:"pypi.org",level:"verified",score:0.9,tags:["registry"],source:"registry"},"news.ycombinator.com":{domain:"news.ycombinator.com",level:"community",score:0.65,tags:["news"],source:"registry"},"reddit.com":{domain:"reddit.com",level:"community",score:0.55,tags:["forum"],source:"registry"},"wikipedia.org":{domain:"wikipedia.org",level:"community",score:0.75,tags:["encyclopedia"],source:"registry"},"arxiv.org":{domain:"arxiv.org",level:"verified",score:0.9,tags:["academic"],source:"registry"},"doi.org":{domain:"doi.org",level:"verified",score:0.95,tags:["academic"],source:"registry"}};function Yv5($){return $.replace(/^www\./,"")}function jv5($){if($ in GM){let G=GM[$];return G?{...G}:null}let z=Yv5($);if(z in GM){let G=GM[z];return G?{...G}:null}return null}function Lv5($){let z=$.split(".").pop();if(z==="gov"||z==="edu"||z==="mil")return{domain:$,level:"verified",score:0.9,tags:["institution"],source:"heuristic"};if(/\.gov\.[a-z]{2}$/.test($)||/\.ac\.[a-z]{2}$/.test($))return{domain:$,level:"verified",score:0.85,tags:["institution"],source:"heuristic"};return null}async function Wv5($){try{let z=await f1(`https://tranco-list.eu/api/ranks/domain/${$}`,{timeoutMs:5000});if(!z.ok)return null;let J=JSON.parse(z.text).ranks?.[0]?.rank;if(!J)return null;let U=J<1e4?0.6:J<1e5?0.4:0.2;return{domain:$,level:J<1e4?"community":"external",score:U,tags:["tranco"],source:"tranco",rank:J}}catch{return null}}async function qI2($){let z=jv5($);if(z)return z;let G=Lv5($);if(G)return G;let J=await Wv5($);if(J)return J;return{domain:$,level:"unknown",score:null,tags:[],source:"heuristic"}}var DI2=["api","probe","impersonate","browser","archive"];function MI2($){if(!$)return;let z=$.split(",").map((J)=>J.trim()).filter(Boolean),G=z.filter((J)=>!DI2.includes(J));if(G.length>0)throw Error(`Unknown strategy: ${G.join(", ")}. Valid: ${DI2.join(", ")}`);return z}function NZ($){try{return new URL($)}catch{throw Error(`Invalid URL: ${$}`)}}function _z($){return{timeoutMs:$.timeout?Math.max(1000,Math.floor(Number($.timeout)*1000)):15000,locale:$.locale??"en-US,en;q=0.9"}}function _0($,z){if(z)console.log(JSON.stringify($,null,2));else console.log(JSON.stringify($))}function aJ($){if(!$){process.exitCode=1;return}if($.status==="ok")process.exitCode=0;else if($.status==="blocked")process.exitCode=2;else if($.status==="not-found")process.exitCode=3;else if($.status==="invalid-input")process.exitCode=4;else if($.status==="auth-required")process.exitCode=5;else if($.status==="timeout")process.exitCode=6;else process.exitCode=1}function II2($){let z=$.command("search").description("Mechanical search primitives — fetch, meta, rss, media, trust, code").alias("s");z.command("fetch <url>").description("Fetch URL via auto-escalating strategy pipeline").option("--only <strategies>","Comma-separated strategies to run").option("--skip <strategies>","Comma-separated strategies to skip").option("--include-archive","Include archive strategy as last fallback").option("--timeout <seconds>","Per-strategy timeout","15").option("--locale <value>","Accept-Language header","en-US,en;q=0.9").option("--pretty","Pretty-print JSON output").action(async(G,J)=>{try{let U=NZ(G),K=_z(J),X=await bM2(U,K,{only:MI2(J.only),skip:MI2(J.skip),includeArchive:J.includeArchive});_0(X,Boolean(J.pretty)),aJ(X)}catch(U){console.error(E8.default.red(U.message)),process.exitCode=1}}),z.command("api <url>").description("Fetch via matched platform API (Phase 0)").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=NZ(G);if(!RS(U)){console.error(E8.default.yellow(`No API handler matches host ${U.hostname}`)),process.exitCode=3;return}let X=_z(J),Q=await jF(U,X);if(!Q){process.exitCode=3;return}_0(Q,Boolean(J.pretty)),aJ(Q)}catch(U){console.error(E8.default.red(U.message)),process.exitCode=1}}),z.command("api:search <query>").description("Fan-out keyword search across platforms that support it").option("--platforms <list>","Comma-separated platform ids").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{let U=_z(J),K=J.platforms?J.platforms.split(",").map((Q)=>Q.trim()).filter(Boolean):void 0,X=await C$(G,U,K);_0(X,Boolean(J.pretty))}),z.command("meta <url>").description("Extract OGP / JSON-LD / Schema.org from URL").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=NZ(G),K=_z(J),X=await mJ2(U,K),{content:Q,...Z}=X;_0(Z,Boolean(J.pretty)),aJ(X)}catch(U){console.error(E8.default.red(U.message)),process.exitCode=1}}),z.command("rss <url>").description("Discover and parse RSS/Atom feed for a URL").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=NZ(G),K=_z(J),X=await NI2(U,K),{content:Q,...Z}=X;_0(Z,Boolean(J.pretty)),aJ(X)}catch(U){console.error(E8.default.red(U.message)),process.exitCode=1}}),z.command("rss:google <query>").description("Build Google News RSS URL for a query").option("--locale <value>","Locale (e.g., ko-KR)","en-US").action((G,J)=>{let U=OI2(G,J.locale??"en-US");console.log(U)}),z.command("media <url>").description("Extract media metadata via yt-dlp (1858 sites)").option("--subs","Write subtitles").option("--sub-lang <list>","Subtitle languages (comma-separated)","en").option("--format <spec>","yt-dlp format spec").option("--timeout <seconds>","Timeout","30").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=NZ(G),K=_z(J),X=J.subLang?J.subLang.split(",").map((Z)=>Z.trim()).filter(Boolean):void 0,Q=await iJ2(U,K,{subtitles:J.subs,...X?{subLangs:X}:{},...J.format?{format:J.format}:{}});_0(Q,Boolean(J.pretty)),aJ(Q)}catch(U){console.error(E8.default.red(U.message)),process.exitCode=1}}),z.command("archive <url>").description("Fetch via AMP / archive.today / Wayback").option("--timeout <seconds>","Timeout","15").option("--locale <value>","Accept-Language","en-US,en;q=0.9").option("--pretty","Pretty-print JSON").action(async(G,J)=>{try{let U=NZ(G),K=_z(J),X=await kj(U,K);_0(X,Boolean(J.pretty)),aJ(X)}catch(U){console.error(E8.default.red(U.message)),process.exitCode=1}}),z.command("trust <domain>").description("Resolve trust level / score for a domain").option("--pretty","Pretty-print JSON").action(async(G,J)=>{let U=await qI2(G.toLowerCase());_0(U,Boolean(J.pretty))}),z.command("code <query>").description("Search code via gh / glab").option("--host <github|gitlab>","Host","github").option("--language <lang>","Language filter").option("--repo <owner/repo>","Scope to a repo").option("--limit <n>","Max results","20").option("--pretty","Pretty-print JSON").action(async(G,J)=>{let U=J.host==="gitlab"||J.host==="github"?J.host:"github",K=_z({}),X=await xJ2(G,K,{host:U,...J.language?{language:J.language}:{},...J.repo?{repo:J.repo}:{},...J.limit?{limit:Number.parseInt(J.limit,10)}:{}});_0(X,Boolean(J.pretty)),aJ(X)}),z.command("doctor").description("Check dependencies (Chrome, python3 curl_cffi, yt-dlp, gh)").action(async()=>{let G=[],J=Gn();G.push({name:"chrome",ok:Boolean(J),detail:J??"Install Chrome or set OMA_CHROME_PATH"}),G.push(await jn("python3",["--version"])),G.push(await Hv5()),G.push(await jn("yt-dlp",["--version"])),G.push(await jn("gh",["--version"]));for(let U of G){let K=U.ok?E8.default.green("✓"):E8.default.yellow("!");console.log(`${K} ${U.name}: ${U.detail}`)}if(G.some((U)=>!U.ok))process.exitCode=1})}async function jn($,z){return new Promise((G)=>{let{spawn:J}=K2("node:child_process"),U=J($,z,{stdio:["ignore","pipe","pipe"]}),K="";U.stdout?.on("data",(X)=>{K+=X.toString()}),U.on("error",()=>G({name:$,ok:!1,detail:"not found"})),U.on("close",(X)=>{if(X===0)G({name:$,ok:!0,detail:K.trim()});else G({name:$,ok:!1,detail:`exit code ${X}`})})})}async function Hv5(){return new Promise(($)=>{let{spawn:z}=K2("node:child_process"),G=z("python3",["-c","import curl_cffi; print(curl_cffi.__version__)"],{stdio:["ignore","pipe","pipe"]}),J="";G.stdout?.on("data",(U)=>{J+=U.toString()}),G.on("error",()=>$({name:"curl_cffi",ok:!1,detail:"python3 not found"})),G.on("close",(U)=>{if(U===0)$({name:"curl_cffi",ok:!0,detail:`v${J.trim()}`});else $({name:"curl_cffi",ok:!1,detail:"not installed (pip install curl_cffi)"})})})}O7();var Sz=d2(q4(),1);import{execSync as Av5,spawnSync as TI2}from"node:child_process";import{platform as Bv5}from"node:os";function Vv5(){let $=Bv5();if($==="darwin")return"brew install gh";if($==="win32")return"winget install GitHub.cli";return"sudo apt install gh"}async function EI2(){if(console.clear(),f4(Sz.default.bgMagenta(Sz.default.white(" ⭐ oh-my-agent star "))),!ZG()){let z=Vv5(),G=await L3({message:`GitHub CLI (gh) is not installed. Install with ${Sz.default.cyan(z)}?`});if(W4(G)||!G){v5("Install gh manually and try again.");return}let J=V6();J.start("Installing GitHub CLI...");let U=TI2(z,{shell:!0,stdio:"pipe"});if(U.status!==0){J.stop("Installation failed"),e5.error(U.stderr?.toString()||"Unknown error"),v5("Please install gh manually.");return}J.stop("GitHub CLI installed!")}if(!s9()){e5.warn("GitHub CLI is not authenticated.");let z=await L3({message:`Run ${Sz.default.cyan("gh auth login")} now?`});if(W4(z)||!z){v5("Authenticate and try again.");return}if(TI2("gh",["auth","login"],{stdio:"inherit"}),!s9()){v5("Authentication was not completed. Try again.");return}e5.success("Authenticated!")}if(kG()){v5(`Already starred ${Sz.default.cyan($1)}! Thank you! \uD83D\uDE4F`);return}let $=await L3({message:`Star ${Sz.default.cyan($1)} on GitHub?`});if(W4($)||!$){v5("Maybe next time!");return}try{Av5(`gh api -X PUT /user/starred/${$1}`,{stdio:"ignore"}),v5(`Starred ${Sz.default.cyan($1)}! Thank you! \uD83C\uDF1F`)}catch{e5.error("Failed to star the repository."),v5("Please try again later.")}}function RI2($){$.command("star").description("Star oh-my-agent on GitHub").action(L5(async()=>{await EI2()}))}O7();oh();ik();var w9=d2(q4(),1);import{existsSync as JM,mkdirSync as Fv5,readdirSync as uv5,readFileSync as Nv5,writeFileSync as vI2}from"node:fs";import{dirname as Ov5,join as wI2}from"node:path";function Wn($){return wI2($,".serena","metrics.json")}function Ln(){return{sessions:0,skillsUsed:{},tasksCompleted:0,totalSessionTime:0,filesChanged:0,linesAdded:0,linesRemoved:0,lastUpdated:new Date().toISOString(),startDate:new Date().toISOString()}}function qv5($){let z=Wn($);if(JM(z))try{return JSON.parse(Nv5(z,"utf-8"))}catch{return Ln()}return Ln()}function Dv5($,z){let G=Wn($),J=Ov5(G);if(!JM(J))Fv5(J,{recursive:!0});z.lastUpdated=new Date().toISOString(),vI2(G,JSON.stringify(z,null,2),"utf-8")}function Mv5($){let z=wI2($,".serena","memories"),G={};if(!JM(z))return G;try{let J=uv5(z);for(let U of J){let K=U.match(/(?:progress|result)-(\w+)/);if(K?.[1]){let X=K[1];G[X]=(G[X]||0)+1}}}catch{}return G}async function PI2($=!1,z=!1){let G=process.cwd(),J=Wn(G);if(z){if(JM(J))vI2(J,JSON.stringify(Ln(),null,2),"utf-8");if($)console.log(JSON.stringify({reset:!0}));else console.log(w9.default.green("✅ Metrics reset successfully."));return}let U=qv5(G),K=qu(G),X=Mv5(G),Q=ss(G),Z=NB(G),k=Z.startedAt?new Date(Z.startedAt):null,Y=k&&!Number.isNaN(k.getTime())?Math.max(0,Math.floor((Date.now()-k.getTime())/1000)):0;for(let[A,B]of Object.entries(X))U.skillsUsed[A]=(U.skillsUsed[A]||0)+B;if(Q>U.tasksCompleted)U.tasksCompleted=Q;if(Z.id){if(["completed","failed","aborted"].includes(Z.status||"")&&(U.lastSessionId!==Z.id||U.lastSessionStatus!==Z.status)&&Y>0)U.totalSessionTime+=Y;U.lastSessionId=Z.id,U.lastSessionStatus=Z.status,U.lastSessionStarted=Z.startedAt,U.lastSessionDuration=Y}U.filesChanged+=K.filesChanged,U.linesAdded+=K.linesAdded,U.linesRemoved+=K.linesRemoved,U.sessions+=1,Dv5(G,U);let j=Math.max(1,Math.ceil((Date.now()-new Date(U.startDate).getTime())/86400000)),W=U.sessions>0?Math.round(U.totalSessionTime/U.sessions):0;if($){console.log(JSON.stringify({...U,gitStats:K,daysSinceStart:j,avgSessionTime:W},null,2));return}console.clear(),f4(w9.default.bgMagenta(w9.default.white(" \uD83D\uDCCA oh-my-agent stats ")));let L=[w9.default.bold(`\uD83D\uDCC8 Productivity Metrics (${j} days)`),"┌─────────────────────┬──────────────┐",`│ ${w9.default.bold("Metric")} │ ${w9.default.bold("Value")} │`,"├─────────────────────┼──────────────┤",`│ Sessions │ ${String(U.sessions).padEnd(12)} │`,`│ Tasks Completed │ ${String(U.tasksCompleted).padEnd(12)} │`,`│ Files Changed │ ${String(U.filesChanged).padEnd(12)} │`,`│ Lines Added │ ${w9.default.green(`+${U.linesAdded}`).padEnd(12)} │`,`│ Lines Removed │ ${w9.default.red(`-${U.linesRemoved}`).padEnd(12)} │`,"└─────────────────────┴──────────────┘"].join(`
|
|
1563
1563
|
`);U5(L,"Overview");let H=Object.entries(U.skillsUsed).sort(([,A],[,B])=>B-A).slice(0,5);if(H.length>0){let A=[w9.default.bold("\uD83C\uDFC6 Top Skills Used"),...H.map(([B,V],F)=>` ${F+1}. ${B} (${V})`)].join(`
|
|
1564
|
-
`);U5(A,"Skills")}v5(w9.default.dim(`Data stored in: ${J}`))}function bI2($){r1($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(L5(async(z)=>{await PI2(g1(z),z.reset)},{supportsJsonOutput:!0}))}O7();var g4=d2(q4(),1);import{execSync as Pv5}from"node:child_process";import{cpSync as XM,existsSync as P9,mkdirSync as IW,readFileSync as OZ,rmSync as Hn,writeFileSync as rJ}from"node:fs";import{tmpdir as bv5}from"node:os";import{dirname as yI2,join as Z3}from"node:path";var UM=d2(q4(),1);import{execSync as Iv5,spawn as Tv5}from"node:child_process";import{realpathSync as CI2}from"node:fs";import MW from"node:process";var oJ="oh-my-agent";function Ev5($=MW.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(MW.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=z9(CI2($))}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(MW.platform==="darwin")try{let G=Iv5(`brew --prefix ${oJ}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=z9(CI2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${oJ}`,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 ${oJ}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${oJ}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${oJ}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${oJ}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var _I2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function Rv5($,z){let G=$.match(_I2),J=z.match(_I2);if(!G||!J)return!1;for(let U=1;U<=3;U++){let K=Number(G[U]),X=Number(J[U]);if(K<X)return!0;if(K>X)return!1}return!1}async function vv5($=oJ,z=2000){try{let G=await E$.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function SI2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(MW.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(MW.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await vv5();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!Rv5($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=Ev5();if(!G.updateCommand)return $.onNotice?.(UM.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return Tv5(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(UM.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(UM.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var KM={name:"oh-my-agent",version:"7.
|
|
1564
|
+
`);U5(A,"Skills")}v5(w9.default.dim(`Data stored in: ${J}`))}function bI2($){r1($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(L5(async(z)=>{await PI2(g1(z),z.reset)},{supportsJsonOutput:!0}))}O7();var g4=d2(q4(),1);import{execSync as Pv5}from"node:child_process";import{cpSync as XM,existsSync as P9,mkdirSync as IW,readFileSync as OZ,rmSync as Hn,writeFileSync as rJ}from"node:fs";import{tmpdir as bv5}from"node:os";import{dirname as yI2,join as Z3}from"node:path";var UM=d2(q4(),1);import{execSync as Iv5,spawn as Tv5}from"node:child_process";import{realpathSync as CI2}from"node:fs";import MW from"node:process";var oJ="oh-my-agent";function Ev5($=MW.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(MW.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=z9(CI2($))}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(MW.platform==="darwin")try{let G=Iv5(`brew --prefix ${oJ}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=z9(CI2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${oJ}`,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 ${oJ}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${oJ}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${oJ}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${oJ}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var _I2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function Rv5($,z){let G=$.match(_I2),J=z.match(_I2);if(!G||!J)return!1;for(let U=1;U<=3;U++){let K=Number(G[U]),X=Number(J[U]);if(K<X)return!0;if(K>X)return!1}return!1}async function vv5($=oJ,z=2000){try{let G=await E$.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function SI2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(MW.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(MW.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await vv5();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!Rv5($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=Ev5();if(!G.updateCommand)return $.onNotice?.(UM.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return Tv5(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(UM.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(UM.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var KM={name:"oh-my-agent",version:"7.14.0",description:"Portable multi-agent harness for .agents-based skills and workflows across Antigravity, Claude Code, Codex, OpenCode, and more",type:"module",bin:{"oh-my-agent":"./bin/cli.js",oma:"./bin/cli.js"},files:["bin"],keywords:["oh-my-agent","antigravity",".agents","agent","skills","agent-skills","multi-agent","orchestrator","claude","claude-code","codex","opencode","copilot","cursor","chatgpt","pm","frontend","backend","mobile","qa","debug","terraform","database","workflow","bug-fixing","gemini"],author:"our.first.fluke <our.first.fluke@gmail.com>",contributors:["gracefullight <gracefullight.dev@gmail.com>","gahyun-git <go4it.gh@gmail.com>"],license:"MIT",funding:[{type:"github",url:"https://github.com/sponsors/first-fluke"},{type:"buymeacoffee",url:"https://buymeacoffee.com/firstfluke"}],scripts:{"sync:readme":"node ./scripts/sync-readme.mjs","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",dev:"bun run generate:skill-data && bun run cli.ts",lint:"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",axios:"^1.15.0","better-sqlite3":"^12.9.0",chokidar:"^5.0.0",commander:"^14.0.3","date-fns":"^4.1.0",eld:"^2.0.3","fast-xml-parser":"^4",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"},devDependencies:{"@biomejs/biome":"2.4.5","@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"]}};function Cv5($){if(!$)return{intro:(G)=>f4(G),outro:(G)=>v5(G),note:(G,J)=>U5(G,J),logError:(G)=>e5.error(G),spinnerStart:(G)=>{let J=V6();return J.start(G),J}};let z={start(G){},stop(G){if(G)console.log(G)},message(G){console.log(G)}};return{intro:(G)=>console.log(G),outro:(G)=>console.log(G),note:(G,J)=>console.log(G),logError:(G)=>console.error(G),spinnerStart:(G)=>{return console.log(G),z}}}function _v5($,z){if($!==null)return"ready";return z?"legacy":"missing"}async function An($=!1,z=!1){if(!z&&process.stdout.isTTY)console.clear();let G=Cv5(z);G.intro(g4.default.bgMagenta(g4.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let J=process.cwd();await SI2({currentVersion:KM.version,enabled:E62(J),onSpawnStart:(Y)=>G.note(Y,"CLI auto-update"),onNotice:(Y)=>G.note(Y,"CLI update available")});let U=await pV(J),K=V62(J),X=_v5(U,K);if(X==="missing"){if(G.logError("oh-my-agent is not installed in this project. Run `oma install` first."),z)throw Error("oh-my-agent is not installed in this project. Run `oma install` first.");process.exit(1)}let Q=wG(J);if(Q.length>0)G.note(Q.map((Y)=>`${g4.default.green("✓")} ${Y}`).join(`
|
|
1565
1565
|
`),"Migration");let Z=Q.length>0||QS(J);if(Q.length>0&&!QS(J))ZS(J,!0);if(!z)await rV(J);if(X==="legacy")G.note("Existing .agents installation detected without _version.json. Updating in place and restoring version metadata.","Legacy install");let k;try{k=G.spinnerStart("Checking for updates...");let Y=await D62();if(U===Y.version&&!Z){k.stop(g4.default.green("Already up to date!")),G.outro(`Current version: ${g4.default.cyan(U)}`);return}let j=U===Y.version;k.message(`Downloading ${g4.default.cyan(Y.version)}...`);let{dir:W,cleanup:L}=await bK();try{k.message("Copying files..."),wG(J);let H=Z3(J,".agents","oma-config.yaml"),A=Z3(J,".agents","mcp.json"),B=!$&&P9(H)?OZ(H):null,V=!$&&P9(A)?OZ(A):null,F=Z3(bv5(),`oma-stack-backup-${Date.now()}`),u=Z3(J,".agents","skills","oma-backend","stack"),N=!$&&P9(u);if(N)IW(F,{recursive:!0}),XM(u,Z3(F,"oma-backend"),{recursive:!0});let I=["snippets.md","tech-stack.md","api-template.py"],T=Z3(J,".agents","skills","oma-backend","resources"),q=!$&&!N&&I.some((e)=>P9(Z3(T,e))),D=kS(J);if(XM(Z3(W,".agents"),Z3(J,".agents"),{recursive:!0,force:!0}),B)rJ(H,B);if(V)rJ(A,V);if(N)try{IW(u,{recursive:!0}),XM(Z3(F,"oma-backend"),u,{recursive:!0,force:!0})}finally{Hn(F,{recursive:!0,force:!0})}if(q){let e=Z3(W,".agents","skills","oma-backend","variants","python");if(P9(e))IW(u,{recursive:!0}),XM(e,u,{recursive:!0,force:!0}),rJ(Z3(u,"stack.yaml"),`language: python
|
|
1566
1566
|
framework: fastapi
|
|
1567
1567
|
orm: sqlalchemy
|
package/package.json
CHANGED