oh-my-agent 8.5.1 → 8.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -29
- package/bin/cli.js +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -127,34 +127,34 @@ Pick a preset and you're ready:
|
|
|
127
127
|
|
|
128
128
|
| Agent | What They Do |
|
|
129
129
|
|-------|-------------|
|
|
130
|
-
| **oma-academic-writer** |
|
|
131
|
-
| **oma-architecture** |
|
|
132
|
-
| **oma-backend** | APIs in Python, Node.js, or Rust |
|
|
133
|
-
| **oma-brainstorm** | Explores ideas before you commit to building |
|
|
134
|
-
| **oma-db** |
|
|
135
|
-
| **oma-debug** |
|
|
136
|
-
| **oma-deepsec** |
|
|
137
|
-
| **oma-design** |
|
|
138
|
-
| **oma-dev-workflow** | CI/CD, releases, monorepo
|
|
139
|
-
| **oma-docs** |
|
|
140
|
-
| **oma-frontend** | React/Next.js, TypeScript, Tailwind CSS v4, shadcn/ui |
|
|
141
|
-
| **oma-hwp** | HWP
|
|
142
|
-
| **oma-image** |
|
|
143
|
-
| **oma-market** |
|
|
144
|
-
| **oma-mobile** |
|
|
145
|
-
| **oma-observability** |
|
|
146
|
-
| **oma-orchestrator** |
|
|
147
|
-
| **oma-pdf** | PDF to Markdown
|
|
148
|
-
| **oma-pm** | Plans tasks, breaks down requirements, defines API contracts |
|
|
149
|
-
| **oma-qa** | OWASP security, performance, accessibility
|
|
150
|
-
| **oma-recap** |
|
|
151
|
-
| **oma-scholar** |
|
|
152
|
-
| **oma-scm** |
|
|
153
|
-
| **oma-search** |
|
|
154
|
-
| **oma-skill-creator** |
|
|
155
|
-
| **oma-tf-infra** |
|
|
156
|
-
| **oma-translator** |
|
|
157
|
-
| **oma-voice** |
|
|
130
|
+
| **oma-academic-writer** | Drafts, revises, and audits academic prose to publication quality. |
|
|
131
|
+
| **oma-architecture** | Weighs architecture tradeoffs and draws module boundaries, with ADR/ATAM/CBAM analysis. |
|
|
132
|
+
| **oma-backend** | Builds and secures your APIs in Python, Node.js, or Rust. |
|
|
133
|
+
| **oma-brainstorm** | Explores ideas with you before you commit to building. |
|
|
134
|
+
| **oma-db** | Designs your schema, migrations, indexes, and vector stores. |
|
|
135
|
+
| **oma-debug** | Finds the root cause, fixes the bug, and writes a regression test. |
|
|
136
|
+
| **oma-deepsec** | Scans your code for security holes and blocks risky pull requests. |
|
|
137
|
+
| **oma-design** | Builds design systems with tokens, accessibility, and responsive layouts. |
|
|
138
|
+
| **oma-dev-workflow** | Automates your CI/CD, releases, and monorepo tasks. |
|
|
139
|
+
| **oma-docs** | Checks your docs for broken references and flags ones a code change touched. |
|
|
140
|
+
| **oma-frontend** | Builds your UI with React/Next.js, TypeScript, Tailwind CSS v4, and shadcn/ui. |
|
|
141
|
+
| **oma-hwp** | Converts HWP, HWPX, and HWPML files to Markdown. |
|
|
142
|
+
| **oma-image** | Generates images through several AI providers at once. |
|
|
143
|
+
| **oma-market** | Researches your market from community signals and frames it with SWOT, 5F, and PESTEL. |
|
|
144
|
+
| **oma-mobile** | Builds cross-platform mobile apps with Flutter. |
|
|
145
|
+
| **oma-observability** | Routes observability work across metrics, logs, traces, SLOs, and incident forensics. |
|
|
146
|
+
| **oma-orchestrator** | Runs multiple agents in parallel from the CLI. |
|
|
147
|
+
| **oma-pdf** | Converts PDF files to Markdown. |
|
|
148
|
+
| **oma-pm** | Plans tasks, breaks down requirements, and defines API contracts. |
|
|
149
|
+
| **oma-qa** | Reviews your code for OWASP security, performance, and accessibility issues. |
|
|
150
|
+
| **oma-recap** | Recaps your conversation history into themed work summaries. |
|
|
151
|
+
| **oma-scholar** | Searches academic literature and helps you run peer review. |
|
|
152
|
+
| **oma-scm** | Manages your branches, merges, worktrees, and Conventional Commits. |
|
|
153
|
+
| **oma-search** | Routes each query to the best source and scores how much you can trust the result. |
|
|
154
|
+
| **oma-skill-creator** | Writes and audits new OMA skills in the SSL-lite format. |
|
|
155
|
+
| **oma-tf-infra** | Provisions multi-cloud infrastructure with Terraform. |
|
|
156
|
+
| **oma-translator** | Translates between languages so it reads like a native wrote it. |
|
|
157
|
+
| **oma-voice** | Generates voiceovers and transcribes audio on-device, no cloud needed. |
|
|
158
158
|
|
|
159
159
|
## How It Works
|
|
160
160
|
|
|
@@ -220,7 +220,7 @@ Set `model_preset` in `.agents/oma-config.yaml` to choose which AI models each a
|
|
|
220
220
|
|
|
221
221
|
```yaml
|
|
222
222
|
language: en
|
|
223
|
-
model_preset: mixed #
|
|
223
|
+
model_preset: mixed # antigravity | claude | codex | qwen | cursor | mixed
|
|
224
224
|
|
|
225
225
|
# Optional per-agent overrides
|
|
226
226
|
agents:
|
package/bin/cli.js
CHANGED
|
@@ -982,7 +982,7 @@ ${z}`}function Ye($,z,G){let J=G.command||"claude",U=["--agent",$];if(G.output_f
|
|
|
982
982
|
`)}function Oe($="default"){if(Ve.has($))return;Ve.add($);for(let z of hb().split(`
|
|
983
983
|
`))console.warn(`[gemini-deprecation] ${z}`)}var Me=p2(C3(),1);import qe from"node:fs";import aj from"node:path";var xf2=new Set(["claude-only","codex-only","gemini-only","qwen-only","cursor-only"]),if2={"claude-only":"claude","codex-only":"codex","gemini-only":"gemini","qwen-only":"qwen","cursor-only":"cursor"};function gf2($,z){if(xf2.has($)){let G=if2[$]??$;throw new b3(`Legacy preset name "${$}" is no longer valid in ${z}.
|
|
984
984
|
Rename it to "${G}" — or run \`oma update\` for automatic migration.
|
|
985
|
-
`+" Built-in presets: antigravity | claude | codex | gemini | qwen | cursor | mixed")}}function mf2($,z){let G=aj.resolve($),J=aj.parse(G).root;while(G!==J){let U=aj.join(G,z);if(qe.existsSync(U))return U;G=aj.dirname(G)}return null}function De($){let z=mf2($,aj.join(".agents","oma-config.yaml"));if(!z)return{};let G;try{G=qe.readFileSync(z,"utf-8")}catch{return{}}try{let J=Me.parse(G);if(J&&typeof J==="object"&&!Array.isArray(J)){let U=J;if(typeof U.model_preset==="string")gf2(U.model_preset,z);return U}return{}}catch(J){if(J instanceof b3)throw J;let U=J&&typeof J==="object"&&"linePos"in J&&Array.isArray(J.linePos)&&J.linePos.length>0?J.linePos[0]:null,K=U?`${z}:${U.line}:${U.col}`:z;throw new b3(`Failed to parse YAML at ${K}: ${J instanceof Error?J.message:String(J)}`)}}function Ie($,z,G,J){if(J.has(z))throw new b3(`Circular extends chain detected at preset "${z}". Chain: ${[...J].join(" → ")} → ${z}`);J.add(z);let U=G3[z];if(U)return{description:$.description,agent_defaults:{...U.agent_defaults,...$.agent_defaults}};let K=G.custom_presets?.[z];if(K){let X=K;if(K.extends)X=Ie(K,K.extends,G,J);return{description:$.description,agent_defaults:{...X.agent_defaults,...$.agent_defaults}}}throw new b3(`Preset "${z}" referenced in 'extends' is not a built-in preset and not found in custom_presets.`)}function Ee($,z,G){let J=z.model_preset;if(!J)throw new b3("'model_preset' is missing from .agents/oma-config.yaml. Run 'oma install --preset <name>' to set one.");let U=o9[J]??J,K=G3[U],X=z.custom_presets?.[U],Q;if(K){if(U!==J)console.warn(`[resolve-agent-plan] Preset alias "${J}" redirected to "${U}". Update your config to use the canonical key.`);Q=K}else if(X)if(X.extends)Q=Ie(X,X.extends,z,new Set([U]));else Q=X;else{let V=Object.keys(G3).join(", ");throw new b3(`Unknown model_preset "${J}". Built-in presets: ${V}. Custom presets defined: ${Object.keys(z.custom_presets??{}).join(", ")||"(none)"}.`)}let Z=Qe($)??$,j=Q.agent_defaults[Z]??Q.agent_defaults.orchestrator;if(!j)throw new b3(`Preset "${U}" has no agent_defaults for "${$}" and no orchestrator fallback. Custom presets without 'extends' must define every canonical agent role.`);let Y=z.agents?.[Z],W=Y?{...j,...Y}:j;if(Y&&JSON.stringify(Y)===JSON.stringify(j))console.debug(`[resolve-agent-plan] ${$}: override is identical to preset entry (no-op).`);let k=k$(W.model,z.models);if(!k)throw new b3(Ue(W.model,$));if(k.supports.api_only)throw new b3(`Model "${W.model}" has api_only: true. CLI dispatch is not supported. Use a supported model.`);let L=G??process.env.OMA_RUNTIME_VENDOR?.trim().toLowerCase(),H=k.cli;if(L)if(k.supports.native_dispatch_from.includes(L))H=L;else console.warn(`[resolve-agent-plan] ${$} agent: "${L}" is not in native_dispatch_from [${k.supports.native_dispatch_from.join(", ")}]. Falling back to external subprocess.`);let B=W.effort;if(k.supports.effort?.type==="cli-session"&&B!==void 0)console.warn(`[resolve-agent-plan] effort field is ignored for Claude CLI (cli-session model). Remove 'effort' from agents.${$} in .agents/oma-config.yaml.`),B=void 0;if(H==="gemini")Oe("runtime");let A={cli:H,cliModel:k.cli_model,spec:k};if(B!==void 0)A.effort=B;if(W.thinking!==void 0)A.thinking=W.thinking;if(W.memory!==void 0)A.memory=W.memory;return A}function xb($,z){let G=process.cwd(),J=De(G);return Ee($,J,z)}function ff2($){let{default_model:z,...G}=$;return G}function lf2($,z){let G=yb(z);return $.args.push(...G),$}function cf2($,z){let G=$.args.pop();if(G===void 0)return $;return $.args.push("--model",z),$.args.push(G),$}function nf2($,z){return $?.cli===z}function LG($,z,G){if(!z)return $;if(G==="cursor")return cf2($,z.cliModel);return lf2($,z)}function rA($,z,G,J,U,K=process.env){let X=yZ(K),Q=null;try{Q=xb($)}catch(W){if(W instanceof b3)console.warn(`[runtime-dispatch] ${$}: ${W.message} — falling back to vendor config defaults`);else throw W}let Z=nf2(Q,z)?Q:null;if(Q&&!Z)console.warn(`[runtime-dispatch] ${$}: resolved model targets ${Q.cli}, but dispatch target is ${z}; using ${z} vendor defaults.`);let j=Z?ff2(G):G;if(Z?.cli==="codex"&&Z.effort!==void 0)Sp(process.cwd(),Z.effort);if(X==="qwen"){console.warn(`[runtime-dispatch] ${X} runtime: all agents dispatched as external subprocess`);let W=aA(z,j,J,U);if(Z)LG(W,Z,z);return{mode:"external",runtimeVendor:X,targetVendor:z,reason:`${X} runtime has no native parallel dispatch`,invocation:W}}if(X==="antigravity"&&z==="antigravity"){let W=ke($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Antigravity (agy) runtime detected",invocation:W}}if(X==="claude"&&z==="claude"){let W=Ye($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Claude runtime detected",invocation:W}}if(X==="codex"&&z==="codex"){let W=We($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Codex runtime detected",invocation:W}}if(X==="gemini"&&z==="gemini"){let W=Le($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Gemini runtime detected",invocation:W}}if(X==="cursor"&&z==="cursor"){let W=He($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Cursor agent CLI (--print)",invocation:W}}let Y=aA(z,j,J,U);if(Z)LG(Y,Z,z);return{mode:"external",runtimeVendor:X,targetVendor:z,reason:X==="unknown"?"runtime vendor not detected":"cross-vendor or unsupported native path",invocation:Y}}var Te=p2(C3(),1);import A3 from"node:fs";import r9 from"node:path";var df2={frontend:["web","frontend","client","ui","app","dashboard","admin","portal"],backend:["api","backend","server","service","gateway","core"],mobile:["mobile","ios","android","native","rn","expo"]},pf2={frontend:["apps/web","apps/frontend","apps/client","packages/web","packages/frontend","frontend","web","client"],backend:["apps/api","apps/backend","apps/server","packages/api","packages/backend","backend","api","server"],mobile:["apps/mobile","apps/app","packages/mobile","mobile","app"]};function Re($,z){if($.startsWith("!"))return[];let G=$.replace(/\/\*\*?$/,"").replace(/\/$/,"");if(!$.includes("*")){let U=r9.join(z,G);if(A3.existsSync(U)&&A3.statSync(U).isDirectory())return[G];return[]}let J=r9.join(z,G);if(!A3.existsSync(J)||!A3.statSync(J).isDirectory())return[];try{return A3.readdirSync(J,{withFileTypes:!0}).filter((K)=>K.isDirectory()&&!K.name.startsWith(".")).map((K)=>`${G}/${K.name}`)}catch{return[]}}function af2($){let z=r9.join($,"pnpm-workspace.yaml");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8");return Te.parse(G)?.packages??[]}catch{return[]}}function ve($){let z=r9.join($,"package.json");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8"),J=JSON.parse(G);if(Array.isArray(J?.workspaces))return J.workspaces;if(J?.workspaces&&typeof J.workspaces==="object")return J.workspaces.packages??[];return[]}catch{return[]}}function of2($){let z=r9.join($,"lerna.json");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8");return JSON.parse(G)?.packages??[]}catch{return[]}}function rf2($){let z=r9.join($,"nx.json");if(!A3.existsSync(z))return[];return["apps/*","libs/*","packages/*"].flatMap((G)=>Re(G,$))}function sf2($){let z=r9.join($,"turbo.json");if(!A3.existsSync(z))return[];return ve($)}function tf2($){let z=r9.join($,"mise.toml");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8"),J=[],U=G.match(/workspaces\s*=\s*\[([^\]]+)\]/);if(U?.[1]){let K=U[1].match(/"([^"]+)"|'([^']+)'/g);if(K)J.push(...K.map((X)=>X.replace(/["']/g,"")))}return J}catch{return[]}}function ef2($){let z=new Set,G=[af2($),ve($),of2($),rf2($),sf2($),tf2($)];for(let U of G)for(let K of U)z.add(K);let J=new Set;for(let U of z)for(let K of Re(U,$))J.add(K);return[...J]}function $l2($,z){let G=df2[z];if(!G)return 0;let J=r9.basename($).toLowerCase(),U=$.toLowerCase();for(let K=0;K<G.length;K++){let X=G[K];if(!X)continue;if(J===X)return 100-K;if(J.includes(X))return 50-K;if(U.includes(X))return 25-K}return 0}function sA($){let z=process.cwd(),G=ef2(z);if(G.length>0){let U=G.map((K)=>({workspace:K,score:$l2(K,$)})).filter((K)=>K.score>0).sort((K,X)=>X.score-K.score);if(U.length>0&&U[0])return U[0].workspace}let J=pf2[$];if(J)for(let U of J){let K=r9.resolve(U);if(A3.existsSync(K)&&A3.statSync(K).isDirectory())return U}return"."}var ib=new Set,gb=new Set;function we($){for(let z of[...$])z()}function zl2(){we(ib)}function Gl2(){we(gb)}var Pe=!1;function Jl2(){if(Pe)return;process.on("SIGINT",zl2),process.on("SIGTERM",Gl2),Pe=!0}function $K($,z){return Jl2(),ib.add($),gb.add(z),()=>{ib.delete($),gb.delete(z)}}oj();function BG($){try{return process.kill($,0),!0}catch{return!1}}function ie(){let $=eA(process.cwd());if($.id&&$.status!=="completed"&&$.status!=="failed")return $.id;return fb(new Date)}YG();var me=p2(C3(),1);import ge from"node:fs";var jl2=Y2.object({agent:Y2.string(),task:Y2.string(),workspace:Y2.string().optional()}),Yl2=Y2.object({tasks:Y2.array(jl2)});function fe($){if(!ge.existsSync($))throw Error(`Tasks file not found: ${$}`);let z=ge.readFileSync($,"utf-8"),G=me.parse(z),J=Yl2.safeParse(G);if(!J.success)throw Error(`Invalid tasks file format: ${J.error.message}`);return J.data.tasks}function le($){return $.map((z)=>{let G=z.split(":");if(G.length<2||!G[0])throw Error(`Invalid task format: "${z}". Expected "agent:task" or "agent:task:workspace"`);let J=G[0],U=G.slice(1),K,X;if(U.length>=2){let Q=U[U.length-1]??"";if(Q.startsWith("./")||Q.startsWith("/")||Q===".")X=Q,K=U.slice(0,-1).join(":");else K=U.join(":")}else K=U.join(":");return{agent:J,task:K,workspace:X}})}async function ce($,z={}){let G=process.cwd(),J=GK.join(G,".agents","results"),U=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),K=GK.join(J,`parallel-${U}`);q6.mkdirSync(K,{recursive:!0});let X=GK.join(K,"pids.txt"),Q;try{if(z.inline){if($.length===0)console.error(T4.default.red("Error: No tasks specified")),console.log('Usage: oh-my-ag agent:parallel --inline "agent:task" "agent:task" ...'),process.exit(1);Q=le($)}else{if($.length===0)console.error(T4.default.red("Error: No tasks file specified")),console.log("Usage: oh-my-ag agent:parallel <tasks-file.yaml>"),process.exit(1);let A=$[0];if(!A)console.error(T4.default.red("Error: No tasks file specified")),process.exit(1);Q=fe(A)}}catch(A){console.error(T4.default.red(`Error: ${A.message}`)),process.exit(1)}console.log(T4.default.cyan("======================================")),console.log(T4.default.cyan(" Parallel SubAgent Execution")),console.log(T4.default.cyan("======================================")),console.log(""),console.log(T4.default.blue("Starting parallel execution...")),console.log("");let Z=[];for(let A=0;A<Q.length;A++){let V=Q[A];if(!V)continue;let{agent:F,task:N,workspace:u="."}=V,q=u==="."?sA(F):u,I=GK.resolve(q),D=GK.join(K,`${F}-${A}.log`);if(console.log(`${T4.default.blue(`[${A}]`)} Spawning ${T4.default.yellow(F)} agent...`),console.log(` Task: ${N.slice(0,60)}${N.length>60?"...":""}`),console.log(` Workspace: ${q}`),!q6.existsSync(I))q6.mkdirSync(I,{recursive:!0});let{vendor:M,config:T}=eU(F,z.vendor),i=T?.vendors?.[M]||{},x=nA(M,i.prompt_flag),y=dA(N),l=pA(M,G),a=l?`${y}
|
|
985
|
+
`+" Built-in presets: antigravity | claude | codex | qwen | cursor | mixed")}}function mf2($,z){let G=aj.resolve($),J=aj.parse(G).root;while(G!==J){let U=aj.join(G,z);if(qe.existsSync(U))return U;G=aj.dirname(G)}return null}function De($){let z=mf2($,aj.join(".agents","oma-config.yaml"));if(!z)return{};let G;try{G=qe.readFileSync(z,"utf-8")}catch{return{}}try{let J=Me.parse(G);if(J&&typeof J==="object"&&!Array.isArray(J)){let U=J;if(typeof U.model_preset==="string")gf2(U.model_preset,z);return U}return{}}catch(J){if(J instanceof b3)throw J;let U=J&&typeof J==="object"&&"linePos"in J&&Array.isArray(J.linePos)&&J.linePos.length>0?J.linePos[0]:null,K=U?`${z}:${U.line}:${U.col}`:z;throw new b3(`Failed to parse YAML at ${K}: ${J instanceof Error?J.message:String(J)}`)}}function Ie($,z,G,J){if(J.has(z))throw new b3(`Circular extends chain detected at preset "${z}". Chain: ${[...J].join(" → ")} → ${z}`);J.add(z);let U=G3[z];if(U)return{description:$.description,agent_defaults:{...U.agent_defaults,...$.agent_defaults}};let K=G.custom_presets?.[z];if(K){let X=K;if(K.extends)X=Ie(K,K.extends,G,J);return{description:$.description,agent_defaults:{...X.agent_defaults,...$.agent_defaults}}}throw new b3(`Preset "${z}" referenced in 'extends' is not a built-in preset and not found in custom_presets.`)}function Ee($,z,G){let J=z.model_preset;if(!J)throw new b3("'model_preset' is missing from .agents/oma-config.yaml. Run 'oma install --preset <name>' to set one.");let U=o9[J]??J,K=G3[U],X=z.custom_presets?.[U],Q;if(K){if(U!==J)console.warn(`[resolve-agent-plan] Preset alias "${J}" redirected to "${U}". Update your config to use the canonical key.`);Q=K}else if(X)if(X.extends)Q=Ie(X,X.extends,z,new Set([U]));else Q=X;else{let V=Object.keys(G3).join(", ");throw new b3(`Unknown model_preset "${J}". Built-in presets: ${V}. Custom presets defined: ${Object.keys(z.custom_presets??{}).join(", ")||"(none)"}.`)}let Z=Qe($)??$,j=Q.agent_defaults[Z]??Q.agent_defaults.orchestrator;if(!j)throw new b3(`Preset "${U}" has no agent_defaults for "${$}" and no orchestrator fallback. Custom presets without 'extends' must define every canonical agent role.`);let Y=z.agents?.[Z],W=Y?{...j,...Y}:j;if(Y&&JSON.stringify(Y)===JSON.stringify(j))console.debug(`[resolve-agent-plan] ${$}: override is identical to preset entry (no-op).`);let k=k$(W.model,z.models);if(!k)throw new b3(Ue(W.model,$));if(k.supports.api_only)throw new b3(`Model "${W.model}" has api_only: true. CLI dispatch is not supported. Use a supported model.`);let L=G??process.env.OMA_RUNTIME_VENDOR?.trim().toLowerCase(),H=k.cli;if(L)if(k.supports.native_dispatch_from.includes(L))H=L;else console.warn(`[resolve-agent-plan] ${$} agent: "${L}" is not in native_dispatch_from [${k.supports.native_dispatch_from.join(", ")}]. Falling back to external subprocess.`);let B=W.effort;if(k.supports.effort?.type==="cli-session"&&B!==void 0)console.warn(`[resolve-agent-plan] effort field is ignored for Claude CLI (cli-session model). Remove 'effort' from agents.${$} in .agents/oma-config.yaml.`),B=void 0;if(H==="gemini")Oe("runtime");let A={cli:H,cliModel:k.cli_model,spec:k};if(B!==void 0)A.effort=B;if(W.thinking!==void 0)A.thinking=W.thinking;if(W.memory!==void 0)A.memory=W.memory;return A}function xb($,z){let G=process.cwd(),J=De(G);return Ee($,J,z)}function ff2($){let{default_model:z,...G}=$;return G}function lf2($,z){let G=yb(z);return $.args.push(...G),$}function cf2($,z){let G=$.args.pop();if(G===void 0)return $;return $.args.push("--model",z),$.args.push(G),$}function nf2($,z){return $?.cli===z}function LG($,z,G){if(!z)return $;if(G==="cursor")return cf2($,z.cliModel);return lf2($,z)}function rA($,z,G,J,U,K=process.env){let X=yZ(K),Q=null;try{Q=xb($)}catch(W){if(W instanceof b3)console.warn(`[runtime-dispatch] ${$}: ${W.message} — falling back to vendor config defaults`);else throw W}let Z=nf2(Q,z)?Q:null;if(Q&&!Z)console.warn(`[runtime-dispatch] ${$}: resolved model targets ${Q.cli}, but dispatch target is ${z}; using ${z} vendor defaults.`);let j=Z?ff2(G):G;if(Z?.cli==="codex"&&Z.effort!==void 0)Sp(process.cwd(),Z.effort);if(X==="qwen"){console.warn(`[runtime-dispatch] ${X} runtime: all agents dispatched as external subprocess`);let W=aA(z,j,J,U);if(Z)LG(W,Z,z);return{mode:"external",runtimeVendor:X,targetVendor:z,reason:`${X} runtime has no native parallel dispatch`,invocation:W}}if(X==="antigravity"&&z==="antigravity"){let W=ke($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Antigravity (agy) runtime detected",invocation:W}}if(X==="claude"&&z==="claude"){let W=Ye($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Claude runtime detected",invocation:W}}if(X==="codex"&&z==="codex"){let W=We($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Codex runtime detected",invocation:W}}if(X==="gemini"&&z==="gemini"){let W=Le($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Gemini runtime detected",invocation:W}}if(X==="cursor"&&z==="cursor"){let W=He($,U,j);if(Z)LG(W,Z,z);return{mode:"native",runtimeVendor:X,targetVendor:z,reason:"same-vendor Cursor agent CLI (--print)",invocation:W}}let Y=aA(z,j,J,U);if(Z)LG(Y,Z,z);return{mode:"external",runtimeVendor:X,targetVendor:z,reason:X==="unknown"?"runtime vendor not detected":"cross-vendor or unsupported native path",invocation:Y}}var Te=p2(C3(),1);import A3 from"node:fs";import r9 from"node:path";var df2={frontend:["web","frontend","client","ui","app","dashboard","admin","portal"],backend:["api","backend","server","service","gateway","core"],mobile:["mobile","ios","android","native","rn","expo"]},pf2={frontend:["apps/web","apps/frontend","apps/client","packages/web","packages/frontend","frontend","web","client"],backend:["apps/api","apps/backend","apps/server","packages/api","packages/backend","backend","api","server"],mobile:["apps/mobile","apps/app","packages/mobile","mobile","app"]};function Re($,z){if($.startsWith("!"))return[];let G=$.replace(/\/\*\*?$/,"").replace(/\/$/,"");if(!$.includes("*")){let U=r9.join(z,G);if(A3.existsSync(U)&&A3.statSync(U).isDirectory())return[G];return[]}let J=r9.join(z,G);if(!A3.existsSync(J)||!A3.statSync(J).isDirectory())return[];try{return A3.readdirSync(J,{withFileTypes:!0}).filter((K)=>K.isDirectory()&&!K.name.startsWith(".")).map((K)=>`${G}/${K.name}`)}catch{return[]}}function af2($){let z=r9.join($,"pnpm-workspace.yaml");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8");return Te.parse(G)?.packages??[]}catch{return[]}}function ve($){let z=r9.join($,"package.json");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8"),J=JSON.parse(G);if(Array.isArray(J?.workspaces))return J.workspaces;if(J?.workspaces&&typeof J.workspaces==="object")return J.workspaces.packages??[];return[]}catch{return[]}}function of2($){let z=r9.join($,"lerna.json");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8");return JSON.parse(G)?.packages??[]}catch{return[]}}function rf2($){let z=r9.join($,"nx.json");if(!A3.existsSync(z))return[];return["apps/*","libs/*","packages/*"].flatMap((G)=>Re(G,$))}function sf2($){let z=r9.join($,"turbo.json");if(!A3.existsSync(z))return[];return ve($)}function tf2($){let z=r9.join($,"mise.toml");if(!A3.existsSync(z))return[];try{let G=A3.readFileSync(z,"utf-8"),J=[],U=G.match(/workspaces\s*=\s*\[([^\]]+)\]/);if(U?.[1]){let K=U[1].match(/"([^"]+)"|'([^']+)'/g);if(K)J.push(...K.map((X)=>X.replace(/["']/g,"")))}return J}catch{return[]}}function ef2($){let z=new Set,G=[af2($),ve($),of2($),rf2($),sf2($),tf2($)];for(let U of G)for(let K of U)z.add(K);let J=new Set;for(let U of z)for(let K of Re(U,$))J.add(K);return[...J]}function $l2($,z){let G=df2[z];if(!G)return 0;let J=r9.basename($).toLowerCase(),U=$.toLowerCase();for(let K=0;K<G.length;K++){let X=G[K];if(!X)continue;if(J===X)return 100-K;if(J.includes(X))return 50-K;if(U.includes(X))return 25-K}return 0}function sA($){let z=process.cwd(),G=ef2(z);if(G.length>0){let U=G.map((K)=>({workspace:K,score:$l2(K,$)})).filter((K)=>K.score>0).sort((K,X)=>X.score-K.score);if(U.length>0&&U[0])return U[0].workspace}let J=pf2[$];if(J)for(let U of J){let K=r9.resolve(U);if(A3.existsSync(K)&&A3.statSync(K).isDirectory())return U}return"."}var ib=new Set,gb=new Set;function we($){for(let z of[...$])z()}function zl2(){we(ib)}function Gl2(){we(gb)}var Pe=!1;function Jl2(){if(Pe)return;process.on("SIGINT",zl2),process.on("SIGTERM",Gl2),Pe=!0}function $K($,z){return Jl2(),ib.add($),gb.add(z),()=>{ib.delete($),gb.delete(z)}}oj();function BG($){try{return process.kill($,0),!0}catch{return!1}}function ie(){let $=eA(process.cwd());if($.id&&$.status!=="completed"&&$.status!=="failed")return $.id;return fb(new Date)}YG();var me=p2(C3(),1);import ge from"node:fs";var jl2=Y2.object({agent:Y2.string(),task:Y2.string(),workspace:Y2.string().optional()}),Yl2=Y2.object({tasks:Y2.array(jl2)});function fe($){if(!ge.existsSync($))throw Error(`Tasks file not found: ${$}`);let z=ge.readFileSync($,"utf-8"),G=me.parse(z),J=Yl2.safeParse(G);if(!J.success)throw Error(`Invalid tasks file format: ${J.error.message}`);return J.data.tasks}function le($){return $.map((z)=>{let G=z.split(":");if(G.length<2||!G[0])throw Error(`Invalid task format: "${z}". Expected "agent:task" or "agent:task:workspace"`);let J=G[0],U=G.slice(1),K,X;if(U.length>=2){let Q=U[U.length-1]??"";if(Q.startsWith("./")||Q.startsWith("/")||Q===".")X=Q,K=U.slice(0,-1).join(":");else K=U.join(":")}else K=U.join(":");return{agent:J,task:K,workspace:X}})}async function ce($,z={}){let G=process.cwd(),J=GK.join(G,".agents","results"),U=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),K=GK.join(J,`parallel-${U}`);q6.mkdirSync(K,{recursive:!0});let X=GK.join(K,"pids.txt"),Q;try{if(z.inline){if($.length===0)console.error(T4.default.red("Error: No tasks specified")),console.log('Usage: oh-my-ag agent:parallel --inline "agent:task" "agent:task" ...'),process.exit(1);Q=le($)}else{if($.length===0)console.error(T4.default.red("Error: No tasks file specified")),console.log("Usage: oh-my-ag agent:parallel <tasks-file.yaml>"),process.exit(1);let A=$[0];if(!A)console.error(T4.default.red("Error: No tasks file specified")),process.exit(1);Q=fe(A)}}catch(A){console.error(T4.default.red(`Error: ${A.message}`)),process.exit(1)}console.log(T4.default.cyan("======================================")),console.log(T4.default.cyan(" Parallel SubAgent Execution")),console.log(T4.default.cyan("======================================")),console.log(""),console.log(T4.default.blue("Starting parallel execution...")),console.log("");let Z=[];for(let A=0;A<Q.length;A++){let V=Q[A];if(!V)continue;let{agent:F,task:N,workspace:u="."}=V,q=u==="."?sA(F):u,I=GK.resolve(q),D=GK.join(K,`${F}-${A}.log`);if(console.log(`${T4.default.blue(`[${A}]`)} Spawning ${T4.default.yellow(F)} agent...`),console.log(` Task: ${N.slice(0,60)}${N.length>60?"...":""}`),console.log(` Workspace: ${q}`),!q6.existsSync(I))q6.mkdirSync(I,{recursive:!0});let{vendor:M,config:T}=eU(F,z.vendor),i=T?.vendors?.[M]||{},x=nA(M,i.prompt_flag),y=dA(N),l=pA(M,G),a=l?`${y}
|
|
986
986
|
|
|
987
987
|
${l}`:y,r=rA(F,M,i,x,a),{command:m,args:h,env:F2}=r.invocation;console.log(` Dispatch: ${r.mode} (${r.runtimeVendor} -> ${r.targetVendor})`);let U2=q6.openSync(D,"w"),E=Wl2(m,h,{cwd:I,stdio:["ignore",U2,U2],detached:!1,env:F2});if(!E.pid){console.error(T4.default.red(`[${A}] Failed to spawn ${F} process`));continue}q6.appendFileSync(X,`${E.pid}:${F}
|
|
988
988
|
`);let v=new Promise((J2)=>{E.on("exit",(C)=>{q6.closeSync(U2),J2(C)}),E.on("error",()=>{q6.closeSync(U2),J2(null)})});Z.push({pid:E.pid,agent:F,idx:A,promise:v})}if(console.log(""),console.log(T4.default.blue("[Parallel]")+` Started ${T4.default.yellow(String(Z.length))} agents`),z.noWait){console.log(`${T4.default.blue("[Parallel]")} Running in background mode`),console.log(`${T4.default.blue("[Parallel]")} Results will be in: ${K}`),console.log(`${T4.default.blue("[Parallel]")} PID list: ${X}`);return}console.log(`${T4.default.blue("[Parallel]")} Waiting for completion...`),console.log("");let j=()=>{console.log(""),console.log(`${T4.default.yellow("[Parallel]")} Cleaning up child processes...`);for(let{pid:A,agent:V}of Z){if(!BG(A))continue;try{process.kill(A),console.log(`${T4.default.yellow("[Parallel]")} Killed PID ${A} (${V})`)}catch{}}try{if(q6.existsSync(X))q6.unlinkSync(X)}catch{}},k=$K(()=>{k(),j(),process.exit(130)},()=>{k(),j(),process.exit(143)}),L=0,H=0;for(let{agent:A,idx:V,promise:F}of Z){let N=await F;if(N===0)console.log(`${T4.default.green("[DONE]")} ${A} agent (${V}) completed`),L++;else console.log(T4.default.red("[FAIL]")+` ${A} agent (${V}) failed (exit code: ${N})`),H++}try{if(q6.existsSync(X))q6.unlinkSync(X)}catch{}k(),console.log(""),console.log(T4.default.cyan("======================================")),console.log(T4.default.cyan(" Execution Summary")),console.log(T4.default.cyan("======================================")),console.log(`Total: ${Z.length}`),console.log(`Completed: ${T4.default.green(String(L))}`),console.log(`Failed: ${T4.default.red(String(H))}`),console.log(`Results: ${K}`),console.log(T4.default.cyan("======================================")),console.log(""),console.log(T4.default.blue("Result files:"));let B=q6.readdirSync(K).filter((A)=>A.endsWith(".log"));for(let A of B)console.log(` - ${GK.join(K,A)}`);if(H>0)process.exit(1)}var s9=p2(I4(),1);import{execSync as Ll2,spawn as kl2}from"node:child_process";import B$ from"node:fs";import{tmpdir as ne}from"node:os";import cb from"node:path";var Hl2="codex",Bl2=["codex","claude","gemini","qwen"];function Al2($,z,G){if(z)return`Review the uncommitted changes (git diff) in this repository. ${$}`;try{let J=Ll2("git diff HEAD~1",{cwd:G,encoding:"utf-8"}).trim();if(!J)return`No committed changes found. ${$}`;return`Review the following committed diff:
|
|
@@ -1008,7 +1008,7 @@ merge: git -C ${JSON.stringify($.path)} log --oneline; git merge ${$.branch}
|
|
|
1008
1008
|
discard: git worktree remove ${JSON.stringify($.path)} --force && git branch -D ${$.branch}`}var _l2=["refactor","architecture","cross-cutting","migration","redesign","overhaul","restructure","rewrite"];function W22($,z,G){let J=$.toLowerCase(),U=_l2.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 hl2($,z){let G=z?.acCount??3,J=z?.filesInScope??2;return W22($,G,J)}var xl2=".serena/memories";function il2($=process.cwd()){let z=JK.join($,xl2);try{if(!_3.existsSync(z))_3.mkdirSync(z,{recursive:!0})}catch(G){console.warn(`[spawn] Could not pre-create memories dir ${z}: ${String(G)}`)}}async function L22($,z,G,J,U,K,X){let Q=null;if(X==="worktree")Q=j22(G,$),console.log(V3.default.blue(`[${$}] Isolated worktree: ${Q.path} (branch ${Q.branch})`));else if(X&&X!=="none")throw Error(`Unknown --isolation mode: ${JSON.stringify(X)}. Supported: worktree`);let Z=Q?Q.path:J==="."?sA($):J,j=JK.resolve(Z);if(!_3.existsSync(j))_3.mkdirSync(j,{recursive:!0}),console.log(V3.default.dim(`[${$}] Created workspace: ${j}`));else if(!Q&&Z!==J)console.log(V3.default.blue(`[${$}] Auto-detected workspace: ${Z}`));let Y=JK.join(pb(),`subagent-${G}-${$}.log`),W=JK.join(pb(),`subagent-${G}-${$}.pid`);il2(process.cwd());let k=dA(z),L=hl2(k,K);console.log(V3.default.dim(` Difficulty: ${L}`));try{let l=z22(process.cwd());if(l!==null){let a=K22(G,l);if(a.exceeded){let r=X22(a);throw console.error(V3.default.red(`[${$}] ${r}`)),Error(`[session-cost] Quota cap exceeded for session ${G}: ${a.reason} (current: ${a.current}, limit: ${a.limit})`)}}}catch(l){if(l instanceof Error&&l.message.startsWith("[session-cost]"))throw l;console.warn(`[${$}] session-cost checkCap error (non-fatal): ${String(l)}`)}let{vendor:H,config:B}=eU($,U),A=pA(H,process.cwd()),V=A?`${k}
|
|
1009
1009
|
|
|
1010
1010
|
${A}`:k,F=B?.vendors?.[H]||{},N=_3.openSync(Y,"w");console.log(V3.default.blue(`[${$}] Spawning subagent...`)),console.log(V3.default.dim(` Vendor: ${H}`)),console.log(V3.default.dim(` Workspace: ${j}`)),console.log(V3.default.dim(` Log: ${Y}`));let u=nA(H,F.prompt_flag),q=rA($,H,F,u,V),{command:I,args:D,env:M}=q.invocation;console.log(V3.default.dim(` Dispatch: ${q.mode} (${q.runtimeVendor} -> ${q.targetVendor}, ${q.reason})`));let T=yl2(I,D,{cwd:j,stdio:["ignore",N,N],detached:!1,env:M});if(!T.pid)console.error(V3.default.red(`[${$}] Failed to spawn process`)),process.exit(1);_3.writeFileSync(W,T.pid.toString()),console.log(V3.default.green(`[${$}] Started with PID ${T.pid}`));let i=()=>{try{if(_3.existsSync(W))_3.unlinkSync(W);if(_3.existsSync(Y))_3.unlinkSync(Y)}catch{}},x=()=>{if(T.pid&&BG(T.pid))process.kill(T.pid);y(),i(),process.exit()},y=$K(x,x);T.on("exit",(l)=>{if(y(),console.log(V3.default.blue(`[${$}] Exited with code ${l}`)),l!==0&&_3.existsSync(Y)){let a=_3.readFileSync(Y,"utf-8").trim();if(a)console.log(V3.default.red(`[${$}] Log output:`)),console.log(a)}try{G22(G,{vendor:H,agentId:$,tokens:Math.ceil(V.length/4),estimatedCostNote:`difficulty:${L}`})}catch(a){console.warn(`[${$}] session-cost recordUsage error (non-fatal): ${String(a)}`)}if(Q){console.log(V3.default.blue(`[${$}] Worktree retained for review:`));for(let a of Y22(Q).split(`
|
|
1011
|
-
`))console.log(V3.default.dim(` ${a}`))}i(),process.exit(l??0)})}async function k22($,z,G=process.cwd()){let J={};for(let U of z){let K=JK.join(G,".serena","memories",`result-${U}.md`),X=JK.join(pb(),`subagent-${$}-${U}.pid`);if(_3.existsSync(K)){let Z=_3.readFileSync(K,"utf-8").match(/^## Status:\s*(\S+)/m);J[U]=Z?.[1]?Z[1]:"completed"}else if(_3.existsSync(X)){let Q=_3.readFileSync(X,"utf-8").trim(),Z=Number.parseInt(Q,10);J[U]=!Number.isNaN(Z)&&BG(Z)?"running":"crashed"}else J[U]="crashed"}for(let[U,K]of Object.entries(J))console.log(`${U}:${K}`)}function H22($){$.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/cursor/qwen)").option("-w, --workspace <path>","Working directory for the agent (auto-detected if omitted)").option("--isolation <mode>","Isolation mode: 'worktree' creates a git worktree per spawn (default: none)").action(W5(async(z,G,J,U)=>{await L22(z,G,J,U.workspace||".",U.model,void 0,U.isolation)})),$.command("agent:status <session-id> [agent-ids...]").description("Check status of subagents").option("-r, --root <path>","Root path for memory checks",process.cwd()).action(W5(async(z,G,J)=>{await k22(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/cursor/qwen)").option("-i, --inline","Inline mode: specify tasks as agent:task arguments").option("--no-wait","Don't wait for completion (background mode)").action(W5(async(z,G)=>{await ce(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(W5(async(z)=>{await de({prompt:z.prompt,model:z.model,workspace:z.workspace,uncommitted:z.uncommitted})}))}U7();var OG=p2(I4(),1);import{execSync as MC}from"node:child_process";import*as m2 from"node:fs";import{homedir as On2}from"node:os";import{dirname as qn2,join as I5,relative as Mn2,resolve as OC,sep as Dn2}from"node:path";var a7={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), Antigravity (gemini-2.5-flash-image aka nano-banana via `agy` CLI + Gemini Code Assist), and Pollinations (flux/zimage, free with signup). 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."}]},r22={fullstack:["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-backend","oma-mobile","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-tf-infra","oma-dev-workflow"],"fullstack-web":["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-dev-workflow"],"fullstack-mobile":["oma-architecture","oma-brainstorm","oma-design","oma-mobile","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","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-observability","oma-pm","oma-qa","oma-debug","oma-scm"],research:["oma-scholar","oma-market","oma-pdf","oma-hwp","oma-academic-writer","oma-search","oma-translator","oma-scm"],content:["oma-design","oma-image","oma-voice","oma-academic-writer","oma-translator","oma-scm"],all:[...a7.domain,...a7.design,...a7.coordination,...a7.utility,...a7.infrastructure].map(($)=>$.name)};import*as KK from"node:fs";import{join as Nl5,sep as s22}from"node:path";function j9($){return s22==="/"?$:$.split(s22).join("/")}function I6($){try{if(!KK.lstatSync($).isDirectory())KK.unlinkSync($)}catch{}}var Pc2={serena:{command:"serena",args:["start-mcp-server","--context","ide","--project","."],env:{SERENA_LOG_LEVEL:"info"}}};function t22($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function e22($){let z=t22($)?$:{},G=t22(z.mcpServers)?z.mcpServers:{};return z.mcpServers={...G,serena:{...Pc2.serena}},z}import*as N$ from"node:fs";import{dirname as wc2,isAbsolute as bc2,resolve as Cc2}from"node:path";var $52=new Set;function z52($,z,G){if(process.platform!=="win32")return N$.symlinkSync($,z,G),"symlink";try{return N$.symlinkSync($,z,G),"symlink"}catch(U){if(!Sc2(U))throw U}let J=bc2($)?$:Cc2(wc2(z),$);if(G==="dir")return N$.symlinkSync(J,z,"junction"),BC("junction"),"junction";try{return N$.linkSync(J,z),BC("hardlink"),"hardlink"}catch{return N$.copyFileSync(J,z),BC("copy"),"copy"}}function Sc2($){if(!$||typeof $!=="object")return!1;let z=$.code;return z==="EPERM"||z==="EACCES"}var _c2={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 BC($){if($52.has($))return;$52.add($);let z=_c2[$];if(z)console.warn(z)}import{existsSync as VC,mkdirSync as hc2,readdirSync as xc2,readFileSync as J52,writeFileSync as ic2}from"node:fs";import{join as QK}from"node:path";var jV=p2(C3(),1);function yc2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function AC($){if($===void 0||$===null)return;if(Array.isArray($))return $.map((z)=>AC(z)).filter((z)=>z!==void 0);if(yc2($))return Object.fromEntries(Object.entries($).map(([z,G])=>[z,AC(G)]).filter(([,z])=>z!==void 0));return $}function $8($){let z=$.trimStart();if(!z.startsWith("---"))return{frontmatter:{},body:$};let G=z.indexOf(`
|
|
1011
|
+
`))console.log(V3.default.dim(` ${a}`))}i(),process.exit(l??0)})}async function k22($,z,G=process.cwd()){let J={};for(let U of z){let K=JK.join(G,".serena","memories",`result-${U}.md`),X=JK.join(pb(),`subagent-${$}-${U}.pid`);if(_3.existsSync(K)){let Z=_3.readFileSync(K,"utf-8").match(/^## Status:\s*(\S+)/m);J[U]=Z?.[1]?Z[1]:"completed"}else if(_3.existsSync(X)){let Q=_3.readFileSync(X,"utf-8").trim(),Z=Number.parseInt(Q,10);J[U]=!Number.isNaN(Z)&&BG(Z)?"running":"crashed"}else J[U]="crashed"}for(let[U,K]of Object.entries(J))console.log(`${U}:${K}`)}function H22($){$.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 (antigravity/claude/codex/cursor/qwen)").option("-w, --workspace <path>","Working directory for the agent (auto-detected if omitted)").option("--isolation <mode>","Isolation mode: 'worktree' creates a git worktree per spawn (default: none)").action(W5(async(z,G,J,U)=>{await L22(z,G,J,U.workspace||".",U.model,void 0,U.isolation)})),$.command("agent:status <session-id> [agent-ids...]").description("Check status of subagents").option("-r, --root <path>","Root path for memory checks",process.cwd()).action(W5(async(z,G,J)=>{await k22(z,G,J.root)})),$.command("agent:parallel [tasks...]").description("Run multiple sub-agents in parallel").option("-m, --model <vendor>","CLI vendor override (antigravity/claude/codex/cursor/qwen)").option("-i, --inline","Inline mode: specify tasks as agent:task arguments").option("--no-wait","Don't wait for completion (background mode)").action(W5(async(z,G)=>{await ce(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(W5(async(z)=>{await de({prompt:z.prompt,model:z.model,workspace:z.workspace,uncommitted:z.uncommitted})}))}U7();var OG=p2(I4(),1);import{execSync as MC}from"node:child_process";import*as m2 from"node:fs";import{homedir as On2}from"node:os";import{dirname as qn2,join as I5,relative as Mn2,resolve as OC,sep as Dn2}from"node:path";var a7={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), Antigravity (gemini-2.5-flash-image aka nano-banana via `agy` CLI + Gemini Code Assist), and Pollinations (flux/zimage, free with signup). 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."}]},r22={fullstack:["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-backend","oma-mobile","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-tf-infra","oma-dev-workflow"],"fullstack-web":["oma-architecture","oma-brainstorm","oma-design","oma-frontend","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","oma-dev-workflow"],"fullstack-mobile":["oma-architecture","oma-brainstorm","oma-design","oma-mobile","oma-backend","oma-db","oma-pm","oma-qa","oma-debug","oma-scm","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-observability","oma-pm","oma-qa","oma-debug","oma-scm"],research:["oma-scholar","oma-market","oma-pdf","oma-hwp","oma-academic-writer","oma-search","oma-translator","oma-scm"],content:["oma-design","oma-image","oma-voice","oma-academic-writer","oma-translator","oma-scm"],all:[...a7.domain,...a7.design,...a7.coordination,...a7.utility,...a7.infrastructure].map(($)=>$.name)};import*as KK from"node:fs";import{join as Nl5,sep as s22}from"node:path";function j9($){return s22==="/"?$:$.split(s22).join("/")}function I6($){try{if(!KK.lstatSync($).isDirectory())KK.unlinkSync($)}catch{}}var Pc2={serena:{command:"serena",args:["start-mcp-server","--context","ide","--project","."],env:{SERENA_LOG_LEVEL:"info"}}};function t22($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function e22($){let z=t22($)?$:{},G=t22(z.mcpServers)?z.mcpServers:{};return z.mcpServers={...G,serena:{...Pc2.serena}},z}import*as N$ from"node:fs";import{dirname as wc2,isAbsolute as bc2,resolve as Cc2}from"node:path";var $52=new Set;function z52($,z,G){if(process.platform!=="win32")return N$.symlinkSync($,z,G),"symlink";try{return N$.symlinkSync($,z,G),"symlink"}catch(U){if(!Sc2(U))throw U}let J=bc2($)?$:Cc2(wc2(z),$);if(G==="dir")return N$.symlinkSync(J,z,"junction"),BC("junction"),"junction";try{return N$.linkSync(J,z),BC("hardlink"),"hardlink"}catch{return N$.copyFileSync(J,z),BC("copy"),"copy"}}function Sc2($){if(!$||typeof $!=="object")return!1;let z=$.code;return z==="EPERM"||z==="EACCES"}var _c2={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 BC($){if($52.has($))return;$52.add($);let z=_c2[$];if(z)console.warn(z)}import{existsSync as VC,mkdirSync as hc2,readdirSync as xc2,readFileSync as J52,writeFileSync as ic2}from"node:fs";import{join as QK}from"node:path";var jV=p2(C3(),1);function yc2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function AC($){if($===void 0||$===null)return;if(Array.isArray($))return $.map((z)=>AC(z)).filter((z)=>z!==void 0);if(yc2($))return Object.fromEntries(Object.entries($).map(([z,G])=>[z,AC(G)]).filter(([,z])=>z!==void 0));return $}function $8($){let z=$.trimStart();if(!z.startsWith("---"))return{frontmatter:{},body:$};let G=z.indexOf(`
|
|
1012
1012
|
---`,3);if(G===-1)return{frontmatter:{},body:$};let J=z.slice(3,G).trim(),U=z.slice(G+4);try{let K=jV.parse(J);return{frontmatter:K&&typeof K==="object"?K:{},body:U}}catch{return{frontmatter:{},body:U}}}function XK($,z){let G=Object.fromEntries(Object.entries($).map(([U,K])=>[U,AC(K)]).filter(([,U])=>U!==void 0));if(Object.keys(G).length===0)return`---
|
|
1013
1013
|
---
|
|
1014
1014
|
|
|
@@ -1606,7 +1606,7 @@ Shutting down...`),W().then(()=>process.exit(0)),setTimeout(()=>process.exit(1),
|
|
|
1606
1606
|
|
|
1607
1607
|
${Z}`,"By Tool"),z.topProjects.length>0){let W=Math.max(...z.topProjects.map((L)=>L.count)),k=z.topProjects.map((L)=>{let H=L.duration?Y7.default.dim(` (${VU5(L.duration)})`):"";return`${Y7.default.bold(L.name)} ${tU2(L.count,W,15)} ${L.count}${H}`}).join(`
|
|
1608
1608
|
`);$5(k,"Top Projects")}let j=new Map;for(let W of G){let k=`${AU5(W.timestamp).slice(0,2)}:00`,L=`${Mx(W.timestamp)} ${k}`,H=j.get(L)||[];H.push(W),j.set(L,H)}let Y=[...j.entries()].map(([W,k])=>{let L=[...new Set(k.map((H)=>H.tool))].map((H)=>sU2(H)).join(" ");return`${Y7.default.dim(W)} ${L} ${Y7.default.dim(`${k.length} prompts`)}`}).join(`
|
|
1609
|
-
`);$5(Y,"Timeline"),T5(Y7.default.dim("Use --json for raw data or --mermaid for Mermaid gantt chart"))}async function $K2($=!1,z={}){if(z.graph){let J=dN({route:"/recap"});setTimeout(()=>{let U=process.platform==="darwin"?{command:"open",args:[J.url]}:process.platform==="win32"?{command:"cmd",args:["/c","start","",J.url]}:{command:"xdg-open",args:[J.url]},K=FU5(U.command,U.args,{detached:!0,stdio:"ignore"});K.on("error",()=>{return}),K.unref()},500);return}let G=await lN(z);if($){console.log(aU2(G));return}if(z.mermaid){console.log(rU2(G));return}eU2(G)}function zK2($){S1($.command("recap").description("Recap AI tool conversation history").option("--window <period>","Time window: 1d, 3d, 7d, 2w, 30d","1d").option("--date <date>","Specific date (YYYY-MM-DD)").option("--tool <tools>","Filter by tools (comma-separated: claude,codex,
|
|
1609
|
+
`);$5(Y,"Timeline"),T5(Y7.default.dim("Use --json for raw data or --mermaid for Mermaid gantt chart"))}async function $K2($=!1,z={}){if(z.graph){let J=dN({route:"/recap"});setTimeout(()=>{let U=process.platform==="darwin"?{command:"open",args:[J.url]}:process.platform==="win32"?{command:"cmd",args:["/c","start","",J.url]}:{command:"xdg-open",args:[J.url]},K=FU5(U.command,U.args,{detached:!0,stdio:"ignore"});K.on("error",()=>{return}),K.unref()},500);return}let G=await lN(z);if($){console.log(aU2(G));return}if(z.mermaid){console.log(rU2(G));return}eU2(G)}function zK2($){S1($.command("recap").description("Recap AI tool conversation history").option("--window <period>","Time window: 1d, 3d, 7d, 2w, 30d","1d").option("--date <date>","Specific date (YYYY-MM-DD)").option("--tool <tools>","Filter by tools (comma-separated: claude,codex,qwen,cursor)").option("--top <n>","Show top N projects/topics",Number.parseInt).option("--sort <metric>","Sort by: count, duration","count").option("--mermaid","Output Mermaid gantt chart").option("--graph","Open interactive graph in browser")).action(W5(async(z)=>{await $K2(O1(z),{window:z.window,date:z.date,tool:z.tool,top:z.top,sort:z.sort,mermaid:z.mermaid,graph:z.graph})},{supportsJsonOutput:!0}))}U7();var i1=p2(I4(),1);import{execSync as NU5}from"node:child_process";function d$($,z){try{return NU5(z,{cwd:$,encoding:"utf-8",stdio:["pipe","pipe","ignore"],maxBuffer:10485760}).trim()}catch{return""}}function Ix($){d$($,"git fetch origin --quiet 2>/dev/null || true")}function pN($){return d$($,"git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'")||"main"}function Ex($){return d$($,"git config user.name")||"Unknown"}function aN($,z,G){let J=z.until?` --until="${z.until}"`:"",U=d$($,`git log ${G} --since="${z.since}"${J} --format="COMMIT:%H|%aN|%ae|%at|%s" --shortstat`);if(!U)return[];let K=[],X=null;for(let Q of U.split(`
|
|
1610
1610
|
`))if(Q.startsWith("COMMIT:")){if(X?.hash)K.push({hash:X.hash,author:X.author||"",email:X.email||"",timestamp:X.timestamp||0,subject:X.subject||"",insertions:X.insertions||0,deletions:X.deletions||0});let Z=Q.slice(7).split("|");X={hash:Z[0],author:Z[1],email:Z[2],timestamp:Number.parseInt(Z[3]||"0",10),subject:Z.slice(4).join("|"),insertions:0,deletions:0}}else if(X&&Q.trim()){let Z=Q.match(/(\d+) insertions?\(\+\)/),j=Q.match(/(\d+) deletions?\(-\)/);if(Z)X.insertions=Number.parseInt(Z[1]||"0",10);if(j)X.deletions=Number.parseInt(j[1]||"0",10)}if(X?.hash)K.push({hash:X.hash,author:X.author||"",email:X.email||"",timestamp:X.timestamp||0,subject:X.subject||"",insertions:X.insertions||0,deletions:X.deletions||0});return K}function Tx($,z,G){let J=z.until?` --until="${z.until}"`:"",U=d$($,`git log ${G} --since="${z.since}"${J} --format="COMMIT:%H|%aN" --numstat`);if(!U)return[];let K=[],X="";for(let Q of U.split(`
|
|
1611
1611
|
`))if(Q.startsWith("COMMIT:"))X=Q.slice(7).split("|")[1]||"";else if(Q.trim()&&X){let Z=Q.split("\t");if(Z.length>=3){let j=Number.parseInt(Z[0]||"0",10),Y=Number.parseInt(Z[1]||"0",10);if(!Number.isNaN(j)&&!Number.isNaN(Y)&&Z[2])K.push({file:Z[2],insertions:j,deletions:Y,author:X})}}return K}function Rx($,z,G,J=10){let U=z.until?` --until="${z.until}"`:"",K=d$($,`git log ${G} --since="${z.since}"${U} --format="" --name-only | grep -v '^$' | sort | uniq -c | sort -rn | head -${J}`);if(!K)return[];return K.split(`
|
|
1612
1612
|
`).filter(Boolean).map((X)=>{let Q=X.trim().match(/^\s*(\d+)\s+(.+)$/);if(!Q)return null;return{count:Number.parseInt(Q[1]||"0",10),file:Q[2]||""}}).filter((X)=>X!==null)}function vx($,z,G){let J=G?` --author="${G}"`:"",U=d$($,`git log ${z}${J} --format="%ad" --date=format:"%Y-%m-%d" | sort -u`);if(!U)return 0;let K=U.split(`
|
|
@@ -1642,7 +1642,7 @@ spawn_error:${Q.message}`})})})}async function dK2($,z,G={}){let J=performance.n
|
|
|
1642
1642
|
`);let z=new V6("!xml"),G=z,J="";this.matcher.reset(),this.entityDecoder.reset(),this.entityExpansionCount=0,this.currentExpandedLength=0;let U=this.options,K=new mD(U.processEntities),X=$.length;for(let Q=0;Q<X;Q++)if($[Q]==="<"){let j=$.charCodeAt(Q+1);if(j===47){let Y=PZ($,">",Q,"Closing Tag is not closed."),W=$.substring(Q+2,Y).trim();if(U.removeNSPrefix){let L=W.indexOf(":");if(L!==-1)W=W.substr(L+1)}if(W=Md(U.transformTagName,W,"",U).tagName,G)J=this.saveTextToParentTag(J,G,this.readonlyMatcher);let k=this.matcher.getCurrentTag();if(W&&U.unpairedTagsSet.has(W))throw Error(`Unpaired tag can not be used as closing tag: </${W}>`);if(k&&U.unpairedTagsSet.has(k))this.matcher.pop(),this.tagsNodeStack.pop();this.matcher.pop(),this.isCurrentNodeStopNode=!1,G=this.tagsNodeStack.pop(),J="",Q=Y}else if(j===63){let Y=Dd($,Q,!1,"?>");if(!Y)throw Error("Pi Tag is not closed.");J=this.saveTextToParentTag(J,G,this.readonlyMatcher);let W=this.buildAttributesMap(Y.tagExp,this.matcher,Y.tagName,!0);if(W){let k=W[this.options.attributeNamePrefix+"version"];this.entityDecoder.setXmlVersion(Number(k)||1),K.setXmlVersion(Number(k)||1)}if(U.ignoreDeclaration&&Y.tagName==="?xml"||U.ignorePiTags);else{let k=new V6(Y.tagName);if(k.add(U.textNodeName,""),Y.tagName!==Y.tagExp&&Y.attrExpPresent&&U.ignoreAttributes!==!0)k[":@"]=W;this.addChild(G,k,this.readonlyMatcher,Q)}Q=Y.closeIndex+1}else if(j===33&&$.charCodeAt(Q+2)===45&&$.charCodeAt(Q+3)===45){let Y=PZ($,"-->",Q+4,"Comment is not closed.");if(U.commentPropName){let W=$.substring(Q+4,Y-2);J=this.saveTextToParentTag(J,G,this.readonlyMatcher),G.add(U.commentPropName,[{[U.textNodeName]:W}])}Q=Y}else if(j===33&&$.charCodeAt(Q+2)===68){let Y=K.readDocType($,Q);this.entityDecoder.addInputEntities(Y.entities),Q=Y.i}else if(j===33&&$.charCodeAt(Q+2)===91){let Y=PZ($,"]]>",Q,"CDATA is not closed.")-2,W=$.substring(Q+9,Y);J=this.saveTextToParentTag(J,G,this.readonlyMatcher);let k=this.parseTextData(W,G.tagname,this.readonlyMatcher,!0,!1,!0,!0);if(k==null)k="";if(U.cdataPropName)G.add(U.cdataPropName,[{[U.textNodeName]:W}]);else G.add(U.textNodeName,k);Q=Y+2}else{let Y=Dd($,Q,U.removeNSPrefix);if(!Y){let I=$.substring(Math.max(0,Q-50),Math.min(X,Q+50));throw Error(`readTagExp returned undefined at position ${Q}. Context: "${I}"`)}let{tagName:W,rawTagName:k,tagExp:L,attrExpPresent:H,closeIndex:B}=Y;if({tagName:W,tagExp:L}=Md(U.transformTagName,W,L,U),U.strictReservedNames&&(W===U.commentPropName||W===U.cdataPropName||W===U.textNodeName||W===U.attributesGroupName))throw Error(`Invalid tag name: ${W}`);if(G&&J){if(G.tagname!=="!xml")J=this.saveTextToParentTag(J,G,this.readonlyMatcher,!1)}let A=G;if(A&&U.unpairedTagsSet.has(A.tagname))G=this.tagsNodeStack.pop(),this.matcher.pop();let V=!1;if(L.length>0&&L.lastIndexOf("/")===L.length-1){if(V=!0,W[W.length-1]==="/")W=W.substr(0,W.length-1),L=W;else L=L.substr(0,L.length-1);H=W!==L}let F=null,N={},u=void 0;if(u=TC5(k),W!==z.tagname)this.matcher.push(W,{},u);if(W!==L&&H){if(F=this.buildAttributesMap(L,this.matcher,W),F)N=EC5(F,U)}if(W!==z.tagname)this.isCurrentNodeStopNode=this.isItStopNode();let q=Q;if(this.isCurrentNodeStopNode){let I="";if(V)Q=Y.closeIndex;else if(U.unpairedTagsSet.has(W))Q=Y.closeIndex;else{let M=this.readStopNodeData($,k,B+1);if(!M)throw Error(`Unexpected end of ${k}`);Q=M.i,I=M.tagContent}let D=new V6(W);if(F)D[":@"]=F;D.add(U.textNodeName,I),this.matcher.pop(),this.isCurrentNodeStopNode=!1,this.addChild(G,D,this.readonlyMatcher,q)}else{if(V){({tagName:W,tagExp:L}=Md(U.transformTagName,W,L,U));let I=new V6(W);if(F)I[":@"]=F;this.addChild(G,I,this.readonlyMatcher,q),this.matcher.pop(),this.isCurrentNodeStopNode=!1}else if(U.unpairedTagsSet.has(W)){let I=new V6(W);if(F)I[":@"]=F;this.addChild(G,I,this.readonlyMatcher,q),this.matcher.pop(),this.isCurrentNodeStopNode=!1,Q=Y.closeIndex;continue}else{let I=new V6(W);if(this.tagsNodeStack.length>U.maxNestedTags)throw Error("Maximum nested tags exceeded");if(this.tagsNodeStack.push(G),F)I[":@"]=F;this.addChild(G,I,this.readonlyMatcher,q),G=I}J="",Q=B}}}else J+=$[Q];return z.child};function CC5($,z,G,J){if(!this.options.captureMetaData)J=void 0;let U=this.options.jPath?G.toString():G,K=this.options.updateTag(z.tagname,U,z[":@"]);if(K===!1);else if(typeof K==="string")z.tagname=K,$.addChild(z,J);else $.addChild(z,J)}function SC5($,z,G){let J=this.options.processEntities;if(!J||!J.enabled)return $;if(J.allowedTags){let U=this.options.jPath?G.toString():G;if(!(Array.isArray(J.allowedTags)?J.allowedTags.includes(z):J.allowedTags(z,U)))return $}if(J.tagFilter){let U=this.options.jPath?G.toString():G;if(!J.tagFilter(z,U))return $}return this.entityDecoder.decode($)}function _C5($,z,G,J){if($){if(J===void 0)J=z.child.length===0;if($=this.parseTextData($,z.tagname,G,!1,z[":@"]?Object.keys(z[":@"]).length!==0:!1,J),$!==void 0&&$!=="")z.add(this.options.textNodeName,$);$=""}return $}function yC5(){if(this.stopNodeExpressionsSet.size===0)return!1;return this.matcher.matchesAny(this.stopNodeExpressionsSet)}function hC5($,z,G=">"){let J=0,U=$.length,K=G.charCodeAt(0),X=G.length>1?G.charCodeAt(1):-1,Q="",Z=z;for(let j=z;j<U;j++){let Y=$.charCodeAt(j);if(J){if(Y===J)J=0}else if(Y===34||Y===39)J=Y;else if(Y===K)if(X!==-1){if($.charCodeAt(j+1)===X)return Q+=$.substring(Z,j),{data:Q,index:j}}else return Q+=$.substring(Z,j),{data:Q,index:j};else if(Y===9&&!J)Q+=$.substring(Z,j)+" ",Z=j+1}}function PZ($,z,G,J){let U=$.indexOf(z,G);if(U===-1)throw Error(J);else return U+z.length-1}function xC5($,z,G,J){let U=$.indexOf(z,G);if(U===-1)throw Error(J);return U}function Dd($,z,G,J=">"){let U=hC5($,z+1,J);if(!U)return;let{data:K,index:X}=U,Q=K.search(/\s/),Z=K,j=!0;if(Q!==-1)Z=K.substring(0,Q),K=K.substring(Q+1).trimStart();let Y=Z;if(G){let W=Z.indexOf(":");if(W!==-1)Z=Z.substr(W+1),j=Z!==U.data.substr(W+1)}return{tagName:Z,tagExp:K,closeIndex:X,attrExpPresent:j,rawTagName:Y}}function iC5($,z,G){let J=G,U=1,K=$.length;for(;G<K;G++)if($[G]==="<"){let X=$.charCodeAt(G+1);if(X===47){let Q=xC5($,">",G,`${z} is not closed`);if($.substring(G+2,Q).trim()===z){if(U--,U===0)return{tagContent:$.substring(J,G),i:Q}}G=Q}else if(X===63)G=PZ($,"?>",G+1,"StopNode is not closed.");else if(X===33&&$.charCodeAt(G+2)===45&&$.charCodeAt(G+3)===45)G=PZ($,"-->",G+3,"StopNode is not closed.");else if(X===33&&$.charCodeAt(G+2)===91)G=PZ($,"]]>",G,"StopNode is not closed.")-2;else{let Q=Dd($,G,!1);if(Q){if((Q&&Q.tagName)===z&&Q.tagExp[Q.tagExp.length-1]!=="/")U++;G=Q.closeIndex}}}}function Id($,z,G){if(z&&typeof $==="string"){let J=$.trim();if(J==="true")return!0;else if(J==="false")return!1;else return Od($,G)}else if(LT2($))return $;else return""}function Md($,z,G,J){if($){let U=$(z);if(G===z)G=U;z=U}return z=xT2(z,J),{tagName:z,tagExp:G}}function xT2($,z){if(hD.includes($))throw Error(`[SECURITY] Invalid name: "${$}" is a reserved JavaScript keyword that could cause prototype pollution`);else if(lk.includes($))return z.onDangerousProperty($);return $}var Ed=V6.getMetaDataSymbol();function gC5($,z){if(!$||typeof $!=="object")return{};if(!z)return $;let G={};for(let J in $)if(J.startsWith(z)){let U=J.substring(z.length);G[U]=$[J]}else G[J]=$[J];return G}function Td($,z,G,J){return iT2($,z,G,J)}function iT2($,z,G,J){let U,K={};for(let X=0;X<$.length;X++){let Q=$[X],Z=mC5(Q);if(Z!==void 0&&Z!==z.textNodeName){let j=gC5(Q[":@"]||{},z.attributeNamePrefix);G.push(Z,j)}if(Z===z.textNodeName)if(U===void 0)U=Q[Z];else U+=""+Q[Z];else if(Z===void 0)continue;else if(Q[Z]){let j=iT2(Q[Z],z,G,J),Y=lC5(j,z);if(Object.keys(j).length===0&&z.alwaysCreateTextNode)j[z.textNodeName]="";if(Q[":@"])fC5(j,Q[":@"],J,z);else if(Object.keys(j).length===1&&j[z.textNodeName]!==void 0&&!z.alwaysCreateTextNode)j=j[z.textNodeName];else if(Object.keys(j).length===0)if(z.alwaysCreateTextNode)j[z.textNodeName]="";else j="";if(Q[Ed]!==void 0&&typeof j==="object"&&j!==null)j[Ed]=Q[Ed];if(K[Z]!==void 0&&Object.prototype.hasOwnProperty.call(K,Z)){if(!Array.isArray(K[Z]))K[Z]=[K[Z]];K[Z].push(j)}else{let W=z.jPath?J.toString():J;if(z.isArray(Z,W,Y))K[Z]=[j];else K[Z]=j}if(Z!==void 0&&Z!==z.textNodeName)G.pop()}}if(typeof U==="string"){if(U.length>0)K[z.textNodeName]=U}else if(U!==void 0)K[z.textNodeName]=U;return K}function mC5($){let z=Object.keys($);for(let G=0;G<z.length;G++){let J=z[G];if(J!==":@")return J}}function fC5($,z,G,J){if(z){let U=Object.keys(z),K=U.length;for(let X=0;X<K;X++){let Q=U[X],Z=Q.startsWith(J.attributeNamePrefix)?Q.substring(J.attributeNamePrefix.length):Q,j=J.jPath?G.toString()+"."+Z:G;if(J.isArray(Q,j,!0,!0))$[Q]=[z[Q]];else $[Q]=z[Q]}}}function lC5($,z){let{textNodeName:G}=z,J=Object.keys($).length;if(J===0)return!0;if(J===1&&($[G]||typeof $[G]==="boolean"||$[G]===0))return!0;return!1}class rk{constructor($){this.externalEntities={},this.options=CT2($)}parse($,z){if(typeof $!=="string"&&$.toString)$=$.toString();else if(typeof $!=="string")throw Error("XML data is accepted in String or Bytes[] form.");if(z){if(z===!0)z={};let U=VT2($,z);if(U!==!0)throw Error(`${U.err.msg}:${U.err.line}:${U.err.col}`)}let G=new fD(this.options,this.externalEntities),J=G.parseXml($);if(this.options.preserveOrder||J===void 0)return J;else return Td(J,this.options,G.matcher,G.readonlyMatcher)}addEntity($,z){if(z.indexOf("&")!==-1)throw Error("Entity value can't have '&'");else if($.indexOf("&")!==-1||$.indexOf(";")!==-1)throw Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '
'");else if(z==="&")throw Error("An entity with value '&' is not permitted");else this.externalEntities[$]=z}static getMetaDataSymbol(){return V6.getMetaDataSymbol()}}Q8();var cC5=["/rss","/feed","/atom.xml","/rss.xml","/index.xml"],nC5=new rk({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text"});function Rd($){if($===void 0||$===null)return[];return Array.isArray($)?$:[$]}function P3($){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 gT2($){for(let z of Rd($)){let G=z?.["@_href"],J=z?.["@_rel"];if(typeof G==="string"&&(J===void 0||J==="alternate"))return G}return}function mT2($){let z;try{z=nC5.parse($)}catch{return null}let G=z.rss;if(G){let U=G.channel;if(!U)return null;let K=Rd(U.item);return{kind:"rss",title:P3(U.title),description:P3(U.description),link:P3(U.link),entries:K.map((X)=>({title:P3(X.title),link:P3(X.link),pubDate:P3(X.pubDate),description:P3(X.description),content:P3(X["content:encoded"])??P3(X.content)}))}}let J=z.feed;if(J){let U=Rd(J.entry);return{kind:"atom",title:P3(J.title),description:P3(J.subtitle),link:gT2(J.link),entries:U.map((K)=>({title:P3(K.title),link:gT2(K.link),pubDate:P3(K.published)??P3(K.updated),description:P3(K.summary),content:P3(K.content)??P3(K.summary)}))}}return null}async function fT2($,z){let G=performance.now(),J;try{let K=await a1($.toString(),{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(K.ok)J=Zu(K.text).alternate?.[0]?.href}catch{}let U=new Set;if(J)try{U.add(new URL(J,$).toString())}catch{}for(let K of cC5)U.add(new URL(K,`${$.protocol}//${$.host}`).toString());for(let K of U){if(z.signal?.aborted)break;try{let X=await a1(K,{timeoutMs:z.timeoutMs,locale:z.locale,signal:z.signal});if(!X.ok||X.text.length<50)continue;let Q=mT2(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 lT2($,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()}KW();Q8();var lD={"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 dC5($){return $.replace(/^www\./,"")}function pC5($){if($ in lD){let G=lD[$];return G?{...G}:null}let z=dC5($);if(z in lD){let G=lD[z];return G?{...G}:null}return null}function aC5($){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 oC5($){try{let z=await a1(`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 cT2($){let z=pC5($);if(z)return z;let G=aC5($);if(G)return G;let J=await oC5($);if(J)return J;return{domain:$,level:"unknown",score:null,tags:[],source:"heuristic"}}var nT2=["api","probe","impersonate","browser","archive"];function dT2($){if(!$)return;let z=$.split(",").map((J)=>J.trim()).filter(Boolean),G=z.filter((J)=>!nT2.includes(J));if(G.length>0)throw Error(`Unknown strategy: ${G.join(", ")}. Valid: ${nT2.join(", ")}`);return z}function wZ($){try{return new URL($)}catch{throw Error(`Invalid URL: ${$}`)}}function lz($){return{timeoutMs:$.timeout?Math.max(1000,Math.floor(Number($.timeout)*1000)):15000,locale:$.locale??"en-US,en;q=0.9"}}function f0($,z){if(z)console.log(JSON.stringify($,null,2));else console.log(JSON.stringify($))}function XU($){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 pT2($){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=wZ(G),K=lz(J),X=await WT2(U,K,{only:dT2(J.only),skip:dT2(J.skip),includeArchive:J.includeArchive});f0(X,Boolean(J.pretty)),XU(X)}catch(U){console.error(b8.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=wZ(G);if(!Py(U)){console.error(b8.default.yellow(`No API handler matches host ${U.hostname}`)),process.exitCode=3;return}let X=lz(J),Q=await tF(U,X);if(!Q){process.exitCode=3;return}f0(Q,Boolean(J.pretty)),XU(Q)}catch(U){console.error(b8.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=lz(J),K=J.platforms?J.platforms.split(",").map((Q)=>Q.trim()).filter(Boolean):void 0,X=await x$(G,U,K);f0(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=wZ(G),K=lz(J),X=await aK2(U,K),{content:Q,...Z}=X;f0(Z,Boolean(J.pretty)),XU(X)}catch(U){console.error(b8.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=wZ(G),K=lz(J),X=await fT2(U,K),{content:Q,...Z}=X;f0(Z,Boolean(J.pretty)),XU(X)}catch(U){console.error(b8.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=lT2(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=wZ(G),K=lz(J),X=J.subLang?J.subLang.split(",").map((Z)=>Z.trim()).filter(Boolean):void 0,Q=await dK2(U,K,{subtitles:J.subs,...X?{subLangs:X}:{},...J.format?{format:J.format}:{}});f0(Q,Boolean(J.pretty)),XU(Q)}catch(U){console.error(b8.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=wZ(G),K=lz(J),X=await bW(U,K);f0(X,Boolean(J.pretty)),XU(X)}catch(U){console.error(b8.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 cT2(G.toLowerCase());f0(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=lz({}),X=await nK2(G,K,{host:U,...J.language?{language:J.language}:{},...J.repo?{repo:J.repo}:{},...J.limit?{limit:Number.parseInt(J.limit,10)}:{}});f0(X,Boolean(J.pretty)),XU(X)}),z.command("doctor").description("Check dependencies (Chrome, python3 curl_cffi, yt-dlp, gh)").action(async()=>{let G=[],J=kd();G.push({name:"chrome",ok:Boolean(J),detail:J??"Install Chrome or set OMA_CHROME_PATH"}),G.push(await vd("python3",["--version"])),G.push(await rC5()),G.push(await vd("yt-dlp",["--version"])),G.push(await vd("gh",["--version"]));for(let U of G){let K=U.ok?b8.default.green("✓"):b8.default.yellow("!");console.log(`${K} ${U.name}: ${U.detail}`)}if(G.some((U)=>!U.ok))process.exitCode=1})}async function vd($,z){return new Promise((G)=>{let{spawn:J}=X2("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 rC5(){return new Promise(($)=>{let{spawn:z}=X2("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)"})})})}function aT2($){let z=$.command("skills").description("Inspect and audit installed skills");S1(z.command("audit").description("Check frontmatter description similarity between installed skills"),"Output as JSON for CI/CD").action(W5((G)=>{t92(O1(G))},{supportsJsonOutput:!0}))}U7();var cz=p2(I4(),1);import{execSync as sC5,spawnSync as oT2}from"node:child_process";import{platform as tC5}from"node:os";function eC5(){let $=tC5();if($==="darwin")return"brew install gh";if($==="win32")return"winget install GitHub.cli";return"sudo apt install gh"}async function rT2(){if(console.clear(),d4(cz.default.bgMagenta(cz.default.white(" ⭐ oh-my-agent star "))),!NG()){let z=eC5(),G=await F3({message:`GitHub CLI (gh) is not installed. Install with ${cz.default.cyan(z)}?`});if(Y4(G)||!G){T5("Install gh manually and try again.");return}let J=D6();J.start("Installing GitHub CLI...");let U=oT2(z,{shell:!0,stdio:"pipe"});if(U.status!==0){J.stop("Installation failed"),c5.error(U.stderr?.toString()||"Unknown error"),T5("Please install gh manually.");return}J.stop("GitHub CLI installed!")}if(!z8()){c5.warn("GitHub CLI is not authenticated.");let z=await F3({message:`Run ${cz.default.cyan("gh auth login")} now?`});if(Y4(z)||!z){T5("Authenticate and try again.");return}if(oT2("gh",["auth","login"],{stdio:"inherit"}),!z8()){T5("Authentication was not completed. Try again.");return}c5.success("Authenticated!")}if(uG()){T5(`Already starred ${cz.default.cyan(K1)}! Thank you! \uD83D\uDE4F`);return}let $=await F3({message:`Star ${cz.default.cyan(K1)} on GitHub?`});if(Y4($)||!$){T5("Maybe next time!");return}try{sC5(`gh api -X PUT /user/starred/${K1}`,{stdio:"ignore"}),T5(`Starred ${cz.default.cyan(K1)}! Thank you! \uD83C\uDF1F`)}catch{c5.error("Failed to star the repository."),T5("Please try again later.")}}function sT2($){$.command("star").description("Star oh-my-agent on GitHub").action(W5(async()=>{await rT2()}))}U7();nx();oj();var w3=p2(I4(),1);import{existsSync as sk,mkdirSync as $S5,readdirSync as zS5,readFileSync as tT2,writeFileSync as zR2}from"node:fs";import{dirname as GS5,join as Pd}from"node:path";function JS5($){let z=U22($),G={},J=0,U=0;for(let K of z){J+=K.tokens;let X=J22(K.tokens,K.vendor);U+=X;let Q=G[K.vendor]??{tokens:0,spawns:0,usd:0};Q.tokens+=K.tokens,Q.spawns+=1,Q.usd+=X,G[K.vendor]=Q}return{totalTokens:J,totalSpawns:z.length,estimatedUsd:U,byVendor:G}}function eT2($){return $.toLocaleString("en-US")}function $R2($){if($===0)return"$0.00";if($<0.01)return"<$0.01";return`$${$.toFixed(2)}`}function wd($){return Pd($,".agents","state","metrics.json")}function US5($){return Pd($,".serena","metrics.json")}function cD(){return{sessions:0,skillsUsed:{},tasksCompleted:0,totalSessionTime:0,filesChanged:0,linesAdded:0,linesRemoved:0,lastUpdated:new Date().toISOString(),startDate:new Date().toISOString()}}function KS5($){let z=wd($);if(sk(z))try{return JSON.parse(tT2(z,"utf-8"))}catch{return cD()}let G=US5($);if(sk(G))try{return JSON.parse(tT2(G,"utf-8"))}catch{return cD()}return cD()}function XS5($,z){let G=wd($),J=GS5(G);if(!sk(J))$S5(J,{recursive:!0});z.lastUpdated=new Date().toISOString(),zR2(G,JSON.stringify(z,null,2),"utf-8")}function QS5($){let z=Pd($,".serena","memories"),G={};if(!sk(z))return G;try{let J=zS5(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 GR2($=!1,z=!1){let G=process.cwd(),J=wd(G);if(z){if(sk(J))zR2(J,JSON.stringify(cD(),null,2),"utf-8");if($)console.log(JSON.stringify({reset:!0}));else console.log(w3.default.green("✅ Metrics reset successfully."));return}let U=KS5(G),K=$u(G),X=QS5(G),Q=_e(G),Z=eA(G),j=Z.startedAt?new Date(Z.startedAt):null,Y=j&&!Number.isNaN(j.getTime())?Math.max(0,Math.floor((Date.now()-j.getTime())/1000)):0;for(let[A,V]of Object.entries(X))U.skillsUsed[A]=(U.skillsUsed[A]||0)+V;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,XS5(G,U);let W=Math.max(1,Math.ceil((Date.now()-new Date(U.startDate).getTime())/86400000)),k=U.sessions>0?Math.round(U.totalSessionTime/U.sessions):0,L=JS5(G);if($){console.log(JSON.stringify({...U,gitStats:K,daysSinceStart:W,avgSessionTime:k,cost:L},null,2));return}console.clear(),d4(w3.default.bgMagenta(w3.default.white(" \uD83D\uDCCA oh-my-agent stats ")));let H=[w3.default.bold(`\uD83D\uDCC8 Productivity Metrics (${W} days)`),"┌─────────────────────┬──────────────┐",`│ ${w3.default.bold("Metric")} │ ${w3.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 │ ${w3.default.green(`+${U.linesAdded}`.padEnd(12))} │`,`│ Lines Removed │ ${w3.default.red(`-${U.linesRemoved}`.padEnd(12))} │`,"└─────────────────────┴──────────────┘"].join(`
|
|
1643
1643
|
`);if($5(H,"Overview"),L.totalSpawns>0){let A=Object.entries(L.byVendor).sort(([,F],[,N])=>N.tokens-F.tokens).map(([F,N])=>` ${F.padEnd(12)} ${eT2(N.tokens).padStart(12)} tokens · ${String(N.spawns).padStart(3)} spawns · ${$R2(N.usd).padStart(7)}`),V=[w3.default.bold("\uD83D\uDCB0 Cost Telemetry (all sessions)"),"┌─────────────────────┬──────────────┐",`│ ${w3.default.bold("Metric")} │ ${w3.default.bold("Value")} │`,"├─────────────────────┼──────────────┤",`│ Total tokens (est.) │ ${eT2(L.totalTokens).padEnd(12)} │`,`│ Total spawns │ ${String(L.totalSpawns).padEnd(12)} │`,`│ Estimated USD │ ${$R2(L.estimatedUsd).padEnd(12)} │`,"└─────────────────────┴──────────────┘",w3.default.dim("By vendor (sorted by tokens):"),...A,w3.default.dim("Estimate is input-only (prompt char approximation); output tokens not yet tracked."),w3.default.dim("Configure session.quota_cap in .agents/oma-config.yaml to enforce budgets.")].join(`
|
|
1644
1644
|
`);$5(V,"Cost")}let B=Object.entries(U.skillsUsed).sort(([,A],[,V])=>V-A).slice(0,5);if(B.length>0){let A=[w3.default.bold("\uD83C\uDFC6 Top Skills Used"),...B.map(([V,F],N)=>` ${N+1}. ${V} (${F})`)].join(`
|
|
1645
|
-
`);$5(A,"Skills")}T5(w3.default.dim(`Data stored in: ${J}`))}function JR2($){S1($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(W5(async(z)=>{await GR2(O1(z),z.reset)},{supportsJsonOutput:!0}))}U7();var c4=p2(I4(),1);import{execSync as QR2}from"node:child_process";import{cpSync as pD,existsSync as ZU,mkdirSync as bd,readFileSync as ZR2,rmSync as Cd,writeFileSync as Sd}from"node:fs";import{tmpdir as HS5}from"node:os";import{join as l7}from"node:path";var nD=p2(I4(),1);import{execSync as ZS5,spawn as jS5}from"node:child_process";import{realpathSync as UR2}from"node:fs";import tk from"node:process";var QU="oh-my-agent";function YS5($=tk.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(tk.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=j9(UR2($))}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(tk.platform==="darwin")try{let G=ZS5(`brew --prefix ${QU}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=j9(UR2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${QU}`,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 ${QU}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${QU}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${QU}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${QU}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var KR2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function WS5($,z){let G=$.match(KR2),J=z.match(KR2);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 LS5($=QU,z=2000){try{let G=await S$.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function XR2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(tk.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(tk.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await LS5();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!WS5($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=YS5();if(!G.updateCommand)return $.onNotice?.(nD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return jS5(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(nD.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(nD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var dD={name:"oh-my-agent",version:"8.5.
|
|
1645
|
+
`);$5(A,"Skills")}T5(w3.default.dim(`Data stored in: ${J}`))}function JR2($){S1($.command("stats").description("View productivity metrics").option("--reset","Reset metrics data")).action(W5(async(z)=>{await GR2(O1(z),z.reset)},{supportsJsonOutput:!0}))}U7();var c4=p2(I4(),1);import{execSync as QR2}from"node:child_process";import{cpSync as pD,existsSync as ZU,mkdirSync as bd,readFileSync as ZR2,rmSync as Cd,writeFileSync as Sd}from"node:fs";import{tmpdir as HS5}from"node:os";import{join as l7}from"node:path";var nD=p2(I4(),1);import{execSync as ZS5,spawn as jS5}from"node:child_process";import{realpathSync as UR2}from"node:fs";import tk from"node:process";var QU="oh-my-agent";function YS5($=tk.argv[1]){if(!$)return{packageManager:"unknown",isGlobal:!1};if(tk.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=j9(UR2($))}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(tk.platform==="darwin")try{let G=ZS5(`brew --prefix ${QU}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(G){let J=j9(UR2(G));if(z.startsWith(J))return{packageManager:"homebrew",isGlobal:!0,updateCommand:`brew upgrade ${QU}`,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 ${QU}@latest`,updateMessage:"Installed via pnpm. Updating in background..."};if(z.includes("/.yarn/global"))return{packageManager:"yarn",isGlobal:!0,updateCommand:`yarn global add ${QU}@latest`,updateMessage:"Installed via yarn. Updating in background..."};if(z.includes("/.bun/install/global"))return{packageManager:"bun",isGlobal:!0,updateCommand:`bun add -g ${QU}@latest`,updateMessage:"Installed via bun. Updating in background..."};return{packageManager:"npm",isGlobal:!0,updateCommand:`npm install -g ${QU}@latest`,updateMessage:"Installed via npm. Updating in background..."}}var KR2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;function WS5($,z){let G=$.match(KR2),J=z.match(KR2);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 LS5($=QU,z=2000){try{let G=await S$.get(`https://registry.npmjs.org/${$}/latest`,{timeout:z});return typeof G.data?.version==="string"?G.data.version:null}catch{return null}}async function XR2($){if(!$.enabled)return{triggered:!1,reason:"disabled"};if(tk.env.OMA_SKIP_VERSION_CHECK==="1")return{triggered:!1,reason:"skipped-env"};if(tk.env.NODE_ENV==="development")return{triggered:!1,reason:"skipped-env"};let z=await LS5();if(!z)return{triggered:!1,reason:"fetch-failed"};if(!WS5($.currentVersion,z))return{triggered:!1,reason:"up-to-date",latest:z};let G=YS5();if(!G.updateCommand)return $.onNotice?.(nD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. ${G.updateMessage??"Update manually."}`)),{triggered:!1,reason:"non-upgradable",latest:z};try{return jS5(G.updateCommand,{stdio:"ignore",shell:!0,detached:!0}).unref(),$.onSpawnStart?.(nD.default.cyan(`global oh-my-agent ${$.currentVersion} → ${z} updating in background. New version applies on next run.`)),{triggered:!0,latest:z}}catch{return $.onNotice?.(nD.default.yellow(`global oh-my-agent ${$.currentVersion} → ${z} available. Run: ${G.updateCommand}`)),{triggered:!1,reason:"spawn-failed",latest:z}}}var dD={name:"oh-my-agent",version:"8.5.3",description:"Portable multi-agent harness for .agents-based skills and workflows across Antigravity, Claude Code, Codex, OpenCode, and more",type:"module",bin:{"oh-my-agent":"./bin/cli.js",oma:"./bin/cli.js"},files:["bin"],keywords:["oh-my-agent","antigravity",".agents","agent","skills","agent-skills","multi-agent","orchestrator","claude","claude-code","codex","opencode","copilot","cursor","chatgpt","pm","frontend","backend","mobile","qa","debug","terraform","database","workflow","bug-fixing","gemini"],author:"our.first.fluke <our.first.fluke@gmail.com>",contributors:["gracefullight <gracefullight.dev@gmail.com>","gahyun-git <go4it.gh@gmail.com>"],license:"MIT",funding:[{type:"github",url:"https://github.com/sponsors/first-fluke"},{type:"buymeacoffee",url:"https://buymeacoffee.com/firstfluke"}],scripts:{"sync:readme":"node ./scripts/sync-readme.mjs","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"},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"]}};function BS5($){if(!$)return{intro:(G)=>d4(G),outro:(G)=>T5(G),note:(G,J)=>$5(G,J),logError:(G)=>c5.error(G),spinnerStart:(G)=>{let J=D6();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 AS5($,z){if($!==null)return"ready";return z?"legacy":"missing"}async function _d($=!1,z=!1){if(!z&&process.stdout.isTTY)console.clear();let G=BS5(z);G.intro(c4.default.bgMagenta(c4.default.white(" \uD83D\uDEF8 oh-my-agent update ")));let J=process.cwd();await XR2({currentVersion:dD.version,enabled:t82(J),onSpawnStart:(Y)=>G.note(Y,"CLI auto-update"),onNotice:(Y)=>G.note(Y,"CLI update available")});let U=await vF(J),K=f82(J),X=AS5(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=cG(J);if(Q.length>0)G.note(Q.map((Y)=>`${c4.default.green("✓")} ${Y}`).join(`
|
|
1646
1646
|
`),"Migration");let Z=Q.length>0||Zy(J);if(Q.length>0&&!Zy(J))jy(J,!0);if(!z)await bF(J);if(X==="legacy")G.note("Existing .agents installation detected without _version.json. Updating in place and restoring version metadata.","Legacy install");let j;try{j=G.spinnerStart("Checking for updates...");let Y=await a82();if(U===Y.version&&!Z){j.stop(c4.default.green("Already up to date!")),G.outro(`Current version: ${c4.default.cyan(U)}`);return}let W=U===Y.version;j.message(`Downloading ${c4.default.cyan(Y.version)}...`);let{dir:k,cleanup:L}=await hK();try{j.message("Copying files..."),cG(J);let H=l7(J,".agents","oma-config.yaml"),B=l7(J,".agents","mcp.json"),A=!$&&ZU(H)?ZR2(H):null,V=!$&&ZU(B)?ZR2(B):null,F=l7(HS5(),`oma-stack-backup-${Date.now()}`),N=l7(J,".agents","skills","oma-backend","stack"),u=!$&&ZU(N);if(u)bd(F,{recursive:!0}),pD(N,l7(F,"oma-backend"),{recursive:!0});let q=["snippets.md","tech-stack.md","api-template.py"],I=l7(J,".agents","skills","oma-backend","resources"),D=!$&&!u&&q.some((r)=>ZU(l7(I,r))),M=Yy(J);if(pD(l7(k,".agents"),l7(J,".agents"),{recursive:!0,force:!0}),A)Sd(H,A);if(V)Sd(B,V);if(u)try{bd(N,{recursive:!0}),pD(l7(F,"oma-backend"),N,{recursive:!0,force:!0})}finally{Cd(F,{recursive:!0,force:!0})}if(D){let r=l7(k,".agents","skills","oma-backend","variants","python");if(ZU(r))bd(N,{recursive:!0}),pD(r,N,{recursive:!0,force:!0}),Sd(l7(N,"stack.yaml"),`language: python
|
|
1647
1647
|
framework: fastapi
|
|
1648
1648
|
orm: sqlalchemy
|
package/package.json
CHANGED