@seoagent-official/seoagent 1.119.1 → 1.119.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +10 -10
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -7,16 +7,16 @@ content/images/*
7
7
  .ack-queue.json
8
8
  .sync.lock
9
9
  .sync-cursor
10
- `,Nf=process.env.XDG_CONFIG_HOME&&process.env.XDG_CONFIG_HOME.trim().length>0?process.env.XDG_CONFIG_HOME:jt(Lf(),".config"),ee=jt(Nf,"seoagent"),et=jt(ee,"auth.json"),Qo=jt(ee,"state"),hr=jt(ee,"update-check.json"),yr=jt(ee,"projects.json");var ze="https://seoagent.com",Ft=process.env.SEOAGENT_API_BASE&&process.env.SEOAGENT_API_BASE.trim().length>0?process.env.SEOAGENT_API_BASE.replace(/\/$/,""):ze,M={BASE:Ft,PRICING:`${Ft}/pricing`,LEAD_API:`${Ft}/api/cli/lead`,CLI_AUTH_PAGE:`${Ft}/cli/auth`,CLI_AUTH_POLL:`${Ft}/api/cli/auth/poll`,CLI_SYNC:`${Ft}/api/cli/sync`};function Re(e,t){let n=t&&t!=="unknown"?`&domain=${encodeURIComponent(t)}`:"";return`${M.PRICING}?ref=${encodeURIComponent(e)}${n}`}import{readFileSync as Df}from"fs";import{fileURLToPath as jf}from"url";import{dirname as Ff,join as Mf}from"path";var La="0.0.0";function Uf(e){try{let t=JSON.parse(e);if(typeof t.version=="string"&&/^\d+\.\d+\.\d+/.test(t.version))return t.version}catch{}return La}function Bf(e=t=>Df(t,"utf-8")){try{let t=Ff(jf(import.meta.url));return Uf(e(Mf(t,"package.json")))}catch{return La}}var I=Bf();function Zo(e=process.argv[1]){let t=process.env.SEOAGENT_INSTALL_FORM;return t==="global"?!0:t==="npx"||!e?!1:(e.split(/[/\\]/).pop()??"").replace(/\.(cmd|ps1|exe)$/i,"").toLowerCase()==="seoagent"}function h(e,t=Zo()){return t?`seoagent ${e}`:`npx -y ${mr} ${e}`}import{randomUUID as ig}from"crypto";import{existsSync as Ba,mkdirSync as Ha,readFileSync as sg,writeFileSync as Ga}from"fs";import{join as ri}from"path";import{existsSync as Hf,readFileSync as Gf}from"fs";var wr="---";function Wf(e){let t=e.trim();return t==="null"||t==="~"?null:t==="true"?!0:t==="false"?!1:t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):/^-?\d+$/.test(t)||/^-?\d+\.\d+$/.test(t)?Number(t):t}function Kf(e){let t=[];for(let n of e){let r=n.trim();if(r===""||r.startsWith("#"))continue;let o=n.indexOf(":");if(o===-1)continue;let i=n.slice(0,o).trim();if(!i)continue;let s=n.slice(o+1),a=n.length-n.replace(/^\s+/,"").length;t.push({indent:a,key:i,valueRaw:s,value:s.trim()})}return t}function Na(e,t,n){let r={},o=t;for(;o<e.length;){let i=e[o];if(i.indent<n)break;if(i.indent>n){o++;continue}if(i.value===""){let s=e[o+1];if(s&&s.indent>n){let[a,l]=Na(e,o+1,s.indent);r[i.key]=a,o=l}else r[i.key]="",o++}else r[i.key]=Wf(i.valueRaw),o++}return[r,o]}function te(e){let t=e.split(/\r?\n/);if(t[0]?.trim()!==wr)return{data:{},body:e};let n=-1;for(let l=1;l<t.length;l++)if(t[l].trim()===wr){n=l;break}let r=n===-1?t.slice(1):t.slice(1,n),o=n===-1?"":t.slice(n+1).join(`
11
- `),i=Kf(r),s=i.length>0?i[0].indent:0,[a]=Na(i,0,s);return{data:a,body:o}}function tt(e){if(!Hf(e))return null;try{return te(Gf(e,"utf-8"))}catch{return null}}function qf(e){if(e===null)return"null";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number")return String(e);let t=String(e);return t===""||/[:#\[\]{}&*!|>'"%@`,]/.test(t)||/^\s|\s$/.test(t)?`"${t.replace(/"/g,'\\"')}"`:t}function Da(e,t,n){let r=" ".repeat(t);for(let[o,i]of Object.entries(e))i!==void 0&&(i!==null&&typeof i=="object"?(n.push(`${r}${o}:`),Da(i,t+1,n)):n.push(`${r}${o}: ${qf(i)}`))}function ei(e,t=""){let n=[wr];Da(e,0,n),n.push(wr);let r=t.length===0?"":t.startsWith(`
10
+ `,Nf=process.env.XDG_CONFIG_HOME&&process.env.XDG_CONFIG_HOME.trim().length>0?process.env.XDG_CONFIG_HOME:jt(Lf(),".config"),ee=jt(Nf,"seoagent"),tt=jt(ee,"auth.json"),Qo=jt(ee,"state"),hr=jt(ee,"update-check.json"),yr=jt(ee,"projects.json");var ze="https://seoagent.com",Ft=process.env.SEOAGENT_API_BASE&&process.env.SEOAGENT_API_BASE.trim().length>0?process.env.SEOAGENT_API_BASE.replace(/\/$/,""):ze,M={BASE:Ft,PRICING:`${Ft}/pricing`,LEAD_API:`${Ft}/api/cli/lead`,CLI_AUTH_PAGE:`${Ft}/cli/auth`,CLI_AUTH_POLL:`${Ft}/api/cli/auth/poll`,CLI_SYNC:`${Ft}/api/cli/sync`};function Re(e,t){let n=t&&t!=="unknown"?`&domain=${encodeURIComponent(t)}`:"";return`${M.PRICING}?ref=${encodeURIComponent(e)}${n}`}import{readFileSync as Df}from"fs";import{fileURLToPath as jf}from"url";import{dirname as Ff,join as Mf}from"path";var La="0.0.0";function Uf(e){try{let t=JSON.parse(e);if(typeof t.version=="string"&&/^\d+\.\d+\.\d+/.test(t.version))return t.version}catch{}return La}function Bf(e=t=>Df(t,"utf-8")){try{let t=Ff(jf(import.meta.url));return Uf(e(Mf(t,"package.json")))}catch{return La}}var I=Bf();function Zo(e=process.argv[1]){let t=process.env.SEOAGENT_INSTALL_FORM;return t==="global"?!0:t==="npx"||!e?!1:(e.split(/[/\\]/).pop()??"").replace(/\.(cmd|ps1|exe)$/i,"").toLowerCase()==="seoagent"}function h(e,t=Zo()){return t?`seoagent ${e}`:`npx -y ${mr} ${e}`}import{randomUUID as ig}from"crypto";import{existsSync as Ba,mkdirSync as Ha,readFileSync as sg,writeFileSync as Ga}from"fs";import{join as ri}from"path";import{existsSync as Hf,readFileSync as Gf}from"fs";var wr="---";function Wf(e){let t=e.trim();return t==="null"||t==="~"?null:t==="true"?!0:t==="false"?!1:t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):/^-?\d+$/.test(t)||/^-?\d+\.\d+$/.test(t)?Number(t):t}function Kf(e){let t=[];for(let n of e){let r=n.trim();if(r===""||r.startsWith("#"))continue;let o=n.indexOf(":");if(o===-1)continue;let i=n.slice(0,o).trim();if(!i)continue;let s=n.slice(o+1),a=n.length-n.replace(/^\s+/,"").length;t.push({indent:a,key:i,valueRaw:s,value:s.trim()})}return t}function Na(e,t,n){let r={},o=t;for(;o<e.length;){let i=e[o];if(i.indent<n)break;if(i.indent>n){o++;continue}if(i.value===""){let s=e[o+1];if(s&&s.indent>n){let[a,l]=Na(e,o+1,s.indent);r[i.key]=a,o=l}else r[i.key]="",o++}else r[i.key]=Wf(i.valueRaw),o++}return[r,o]}function te(e){let t=e.split(/\r?\n/);if(t[0]?.trim()!==wr)return{data:{},body:e};let n=-1;for(let l=1;l<t.length;l++)if(t[l].trim()===wr){n=l;break}let r=n===-1?t.slice(1):t.slice(1,n),o=n===-1?"":t.slice(n+1).join(`
11
+ `),i=Kf(r),s=i.length>0?i[0].indent:0,[a]=Na(i,0,s);return{data:a,body:o}}function nt(e){if(!Hf(e))return null;try{return te(Gf(e,"utf-8"))}catch{return null}}function qf(e){if(e===null)return"null";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number")return String(e);let t=String(e);return t===""||/[:#\[\]{}&*!|>'"%@`,]/.test(t)||/^\s|\s$/.test(t)?`"${t.replace(/"/g,'\\"')}"`:t}function Da(e,t,n){let r=" ".repeat(t);for(let[o,i]of Object.entries(e))i!==void 0&&(i!==null&&typeof i=="object"?(n.push(`${r}${o}:`),Da(i,t+1,n)):n.push(`${r}${o}: ${qf(i)}`))}function ei(e,t=""){let n=[wr];Da(e,0,n),n.push(wr);let r=t.length===0?"":t.startsWith(`
12
12
  `)?t:`
13
13
  ${t}`;return n.join(`
14
14
  `)+r+(r.endsWith(`
15
15
  `)?"":`
16
16
  `)}import{existsSync as kr,readdirSync as Vf,statSync as Yf}from"fs";import{join as Je}from"path";var Fa=["svelte.config.js","svelte.config.ts","svelte.config.mjs","svelte.config.cjs","gatsby-config.js","gatsby-config.ts","gatsby-config.mjs","docusaurus.config.js","docusaurus.config.ts","docusaurus.config.mjs","hugo.toml","hugo.yaml","hugo.json"],Ma=["next.config.js","next.config.ts","next.config.mjs","next.config.cjs","astro.config.js","astro.config.ts","astro.config.mjs","nuxt.config.js","nuxt.config.ts","nuxt.config.mjs","remix.config.js","remix.config.ts","vite.config.js","vite.config.ts","vite.config.mjs","vite.config.cjs"],zf=["apps","packages"];function ti(e){for(let t of Fa)if(kr(Je(e,t)))return"static";for(let t of Ma)if(kr(Je(e,t)))return"public";return null}function ja(e){for(let t of[...Fa,...Ma])if(kr(Je(e,t)))return t;return null}function ni(e){let t=[];for(let n of zf){let r;try{r=Vf(Je(e,n),{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name).sort()}catch{continue}for(let o of r){let i=`${n}/${o}`;ti(Je(e,i))&&t.push(i)}}return t.length===1?t[0]:null}function xr(e){if(typeof e!="string")return null;let t=e.trim().replace(/^\.\//,"").replace(/\/+$/,"");return!t||t.startsWith("/")||/^[A-Za-z]:[\\/]/.test(t)||t.split(/[\\/]/).some(n=>n==="..")?null:t.replace(/\\/g,"/")}function br(e,t){try{return Yf(Je(e,t)).isDirectory()}catch{return!1}}function vr(e,t){let n=xr(t);if(n)return{dir:n,source:"configured",evidence:"public_dir in .seoagent/project.md",exists:br(e,n)};let r=ti(e);if(r)return{dir:r,source:"framework",evidence:ja(e),exists:br(e,r)};let o=ni(e);if(o){let i=ti(Je(e,o));if(i){let s=`${o}/${i}`;return{dir:s,source:"framework",evidence:`${o}/${ja(Je(e,o))}`,exists:br(e,s)}}}for(let i of["public","static"])if(br(e,i))return{dir:i,source:"existing",evidence:`${i}/ exists`,exists:!0};return{dir:null,source:null,evidence:null,exists:!1}}var Jf=["app/llms.txt/route.ts","app/llms.txt/route.tsx","app/llms.txt/route.js","src/app/llms.txt/route.ts","src/app/llms.txt/route.tsx","src/app/llms.txt/route.js","pages/llms.txt.ts","pages/llms.txt.js","src/pages/llms.txt.ts","src/pages/llms.txt.js","src/routes/llms.txt/+server.ts","src/routes/llms.txt/+server.js","routes/llms.txt/+server.ts","routes/llms.txt/+server.js"];function Ua(e,t){let n=new Set([""]),r=xr(t);if(r){let o=r.split("/").slice(0,-1).join("/");o&&n.add(o)}for(let o of n)for(let i of Jf){let s=o?`${o}/${i}`:i;if(kr(Je(e,s)))return s}return null}import{execFileSync as Xf}from"child_process";import{existsSync as Qf}from"fs";import{join as Zf}from"path";var eg=3e3,tg=(e,t)=>Xf("git",["-C",e,...t],{encoding:"utf8",timeout:eg,stdio:["ignore","pipe","ignore"],windowsHide:!0,env:{...process.env,GIT_TERMINAL_PROMPT:"0"}}),$r=/^[0-9a-f]{7,40}$/i,ng=5;function rg(e){let n=(e.trim().split(/\s+/)[0]??"").replace(/^`+|`+$/g,"");return!n||/^[a-z][a-z0-9+.-]*:\/\//i.test(n)||(n=n.replace(/#L\d+(?:-L?\d+)?$/i,"").replace(/:\d+(?:-\d+)?$/,"").replace(/\\/g,"/").replace(/^\.\//,"").replace(/^\/+/,""),!n||n.split("/").includes(".."))?null:n}function og(e){return/^https?:\/\//i.test(e.trim().replace(/^`+/,""))}function mt(e,t,n){try{return e(t,n)}catch{return null}}function _r(e){return e?e.split(`
17
- `).map(t=>t.trim()).filter(Boolean):[]}function Sr(e,t,n={}){let r=n.execGit??tg,o=n.sourceExists??((m,w)=>Qf(Zf(m,w))),i=n.checkedCommit&&$r.test(n.checkedCommit)?n.checkedCommit:null,s=n.checkedAt&&!Number.isNaN(Date.parse(n.checkedAt))?n.checkedAt:null,a={status:"no_facts",head:null,checkedCommit:i,checkedAt:s,basis:null,changed:[],unsourced:[],urlSourced:[],missingSource:[],repoSourcedCount:0},l=[];for(let m of t)if(!m.source.trim())a.unsourced.push(m);else if(og(m.source))a.urlSourced.push(m);else{let w=rg(m.source);w?l.push({fact:m,path:w}):a.unsourced.push(m)}if(a.repoSourcedCount=l.length,t.length===0)return a;let c=_r(mt(r,e,["rev-parse","HEAD"]))[0]??null;if(!c||!$r.test(c))return a.status="not_git",a;a.head=c;let u=(mt(r,e,["rev-parse","--show-prefix"])??"").trim(),p=(mt(r,e,["rev-parse","--show-toplevel"])??"").trim();for(let{fact:m,path:w}of l)o(e,w)||p!==""&&u!==""&&o(p,w)||a.missingSource.push(m);let g=null,f=[];if(i&&mt(r,e,["cat-file","-e",`${i}^{commit}`])!==null){let m=mt(r,e,["diff","--name-only",i,"HEAD"]);m!==null&&(g=_r(m),a.basis="commit",f=[`${i}..HEAD`])}if(g===null&&s){let m=mt(r,e,["log",`--since=${s}`,"--name-only","--format="]);m!==null&&(g=_r(m),a.basis="date",f=[`--since=${s}`])}if(g===null)return a.status="unchecked",a;let y=new Set(g);for(let{fact:m,path:w}of l){let S=(u?[`${u}${w}`,w]:[w]).find(b=>y.has(b));if(!S)continue;let T=_r(mt(r,e,["log","--format=%h %s","-n",String(ng),...f,"--",`:(top)${S}`]));a.changed.push({...m,commits:T})}return a.status=a.changed.length>0?"changed":"clean",a}var ag=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ht(){return ig()}var lg=new Set(["strapi","wordpress","sanity","contentful","ghost","webflow","shopify","payload","directus","wix","squarespace","blogger","mdx-local","none"]),cg="project.md";function Xe(e){return ri(e,x)}function Rr(e){return ri(Xe(e),cg)}function Wa(e){return Ba(Rr(e))}function A(e){let t=tt(Rr(e));if(!t)return null;let n=t.data;if(typeof n.domain!="string"||!n.domain)return null;let r=typeof n.image_provider=="string"?n.image_provider:void 0,o=typeof n.cms=="string"?n.cms:void 0,i=o&&lg.has(o)?o:void 0,s=typeof n.install_id=="string"?n.install_id:void 0,a=typeof n.publishing=="object"&&n.publishing!==null?n.publishing:void 0,l=typeof n.content_dir=="string"&&n.content_dir?n.content_dir:a&&typeof a.content_dir=="string"&&a.content_dir?a.content_dir:void 0,c=typeof n.public_dir=="string"&&n.public_dir?n.public_dir:a&&typeof a.public_dir=="string"&&a.public_dir?a.public_dir:void 0;return{domain:n.domain,site_type:typeof n.site_type=="string"?n.site_type:"unknown",language:typeof n.language=="string"?n.language:"en",initialized_at:typeof n.initialized_at=="string"?n.initialized_at:"",seoagent_version:typeof n.seoagent_version=="string"?n.seoagent_version:"",skill_version:typeof n.skill_version=="string"&&n.skill_version?n.skill_version:void 0,skill_hash:typeof n.skill_hash=="string"&&/^[0-9a-f]{64}$/.test(n.skill_hash)?n.skill_hash:void 0,install_id:s&&ag.test(s)?s:void 0,schedule:typeof n.schedule=="string"&&n.schedule.trim()?n.schedule.trim():void 0,facts_checked_commit:typeof n.facts_checked_commit=="string"&&$r.test(n.facts_checked_commit)?n.facts_checked_commit:void 0,facts_checked_at:typeof n.facts_checked_at=="string"&&!Number.isNaN(Date.parse(n.facts_checked_at))?n.facts_checked_at:void 0,image_provider:r==="openai"||r==="fal"||r==="replicate"||r==="none"?r:void 0,cms:i,blog_path:typeof n.blog_path=="string"&&n.blog_path?n.blog_path:void 0,content_dir:l?l.replace(/\/+$/,""):void 0,public_dir:xr(c)??void 0,llms_owner:n.llms_owner==="route"?"route":void 0,live_url:typeof n.live_url=="string"&&n.live_url?n.live_url:void 0}}function Ee(e){let t=A(e);if(!t)return null;if(t.install_id)return t.install_id;let n=ht();return X(e,{install_id:n}),n}function ug(e){return["",`# SEOAgent Project \u2014 ${e.domain}`,"","This file holds project-level configuration for the SEOAgent skill.","The skill reads it on every session to know which domain it is working on.","",`Initialized ${e.initialized_at} with seoagent ${e.seoagent_version}.`,""].join(`
18
- `)}function dg(e){let t={domain:e.domain,site_type:e.site_type,language:e.language,initialized_at:e.initialized_at,seoagent_version:e.seoagent_version};return e.skill_version&&(t.skill_version=e.skill_version),e.skill_hash&&(t.skill_hash=e.skill_hash),e.install_id&&(t.install_id=e.install_id),e.facts_checked_commit&&(t.facts_checked_commit=e.facts_checked_commit),e.facts_checked_at&&(t.facts_checked_at=e.facts_checked_at),e.image_provider&&(t.image_provider=e.image_provider),e.cms&&(t.cms=e.cms),e.blog_path&&(t.blog_path=e.blog_path),e.content_dir&&(t.content_dir=e.content_dir),e.public_dir&&(t.public_dir=e.public_dir),e.llms_owner&&(t.llms_owner=e.llms_owner),e.live_url&&(t.live_url=e.live_url),t}function Ka(e,t){let n=Xe(e);Ha(n,{recursive:!0});let r=ei(dg(t),ug(t));Ga(Rr(e),r,"utf-8")}function X(e,t){let n=Rr(e);if(!Ba(n))return!1;let r=te(sg(n,"utf-8")),o={...r.data,...t};return Ga(n,ei(o,r.body),"utf-8"),!0}function qa(e){let t=Xe(e);for(let n of Pa)Ha(ri(t,n),{recursive:!0})}var oi="Sent an anonymous install ping (random id + CLI version, plus a partial setup-code prefix when --code is used \u2014 no domain, no paths). Opt out: SEOAGENT_TELEMETRY=0",Va="Sent an anonymous ping naming this project's site so its owner can be told the run had no credential (random id + CLI version + domain \u2014 no paths, no secrets). Opt out: SEOAGENT_TELEMETRY=0",pg=2500;function be(e=process.env){let t=(e.SEOAGENT_TELEMETRY??"").trim().toLowerCase();if(t==="0"||t==="false"||t==="off")return!0;let n=(e.DO_NOT_TRACK??"").trim().toLowerCase();return n==="1"||n==="true"}function ii(e=process.env){return(e.GITHUB_ACTIONS??"").trim().toLowerCase()==="true"}function si(e,t=process.env){return ii(t)?`${e}_ci`:e}function fg(e){let t=e.meta&&Object.values(e.meta).some(n=>n!==void 0)?e.meta:null;return{install_id:e.installId,event:e.event,cli_version:e.cliVersion,platform:process.platform,...e.codeHint?{code_hint:e.codeHint}:{},...t?{meta:t}:{}}}async function Qe(e){let t=(e.apiBase||M.BASE).replace(/\/$/,""),n=e.fetchImpl??fetch;try{return(await n(`${t}/api/cli/telemetry`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(fg(e)),signal:AbortSignal.timeout(e.timeoutMs??pg)})).ok}catch{return!1}}var Er=/^sa_[0-9a-f]{24}$/;function Cr(e){let t=(e??"").trim();return Er.test(t)?t.slice(3,11):null}function gg(e){let t=(e??"").trim(),n=t.startsWith("sa_"),r=n?t.slice(3):t,o=r.length>0&&/^[0-9a-f]+$/.test(r),i=/^sa_x+$/i.test(t)||/^sa_[x0.…_-]+$/i.test(t)||/^<.*>$/.test(t)||/^\$\{?[A-Z_]+\}?$/.test(t)||/(your|paste|code|setup)/i.test(t);return{len:t.length,prefix_ok:n,hex_ok:o,well_formed:Er.test(t),placeholder:i}}function ai(e){let t=(e??"").trim();return t?Cr(t)?{with_code:!0}:{with_code:!0,code_shape:gg(t)}:{with_code:!1}}function Ya(e){switch(e){case"code_not_found":return"That setup code was not recognized: it was never issued. Codes cannot be guessed or retyped from memory; copy one exactly from seoagent.com/grok. A scheduled run on a fresh machine needs the SEOAGENT_AUTH secret (`seoagent whoami --env` on the bound machine), not a setup code.";case"code_already_used":return"That setup code has already been used \u2014 each code works exactly once. Generate a new one at seoagent.com/grok.";case"code_revoked":return"That setup code was replaced by a newer one. Use the latest code, or generate a new one at seoagent.com/grok.";case"code_expired":return"That setup code has expired. Generate a new one at seoagent.com/grok.";case"setup_codes_unavailable":return"Setup codes are not enabled on this server yet. Run `seoagent login` (browser flow) instead.";case"domain_required":return"This code has no site attached and the project has no domain. Your code has NOT been used \u2014 run `seoagent init` in the project root (or pass `--domain example.com`) and retry with the same code.";default:return typeof e=="string"&&e?`Login failed: ${e}`:"Login failed."}}function za(e,t){let n=t&&typeof t=="object"?t:null;if(e>=500)return e===503&&n?.error==="setup_codes_unavailable"?{status:"error",terminal:!0,message:Ya(n.error)}:{status:"error",terminal:!1,message:`HTTP ${e} (server error)`};if(e>=400){let r=typeof n?.error=="string"&&n.error?n.error:void 0;return{status:"error",terminal:!0,message:Ya(n?.error),...r?{code:r}:{}}}if(!n)return{status:"error",terminal:!0,message:`Malformed response: expected an object, got ${typeof t}`};if(n.status==="ready"){if(typeof n.user_token=="string"&&typeof n.website_token=="string"){let r=typeof n.email=="string"&&n.email?n.email:void 0,o=typeof n.domain=="string"&&n.domain?n.domain:void 0;return{status:"ready",user_token:n.user_token,website_token:n.website_token,...r?{email:r}:{},...o?{domain:o}:{}}}return{status:"error",terminal:!0,message:"Malformed response: status=ready without user_token+website_token"}}return{status:"error",terminal:!0,message:`Malformed response: unknown status=${JSON.stringify(n.status)}`}}import{existsSync as kg,mkdirSync as Qa,readFileSync as xg,writeFileSync as vg,chmodSync as _g,unlinkSync as Za}from"fs";import{dirname as $g}from"path";var mg=new Set([502,503,504]),hg=1e4;async function F(e,t,n={}){let r=Math.max(1,n.attempts??3),o=Math.max(0,n.baseDelayMs??500),i=n.timeoutMs??hg,s=n.fetchImpl??fetch,a=n.sleep??yg,l=n.transientStatuses??mg,c=null;for(let u=0;u<r;u++){let{init:p,cleanup:g}=wg(t,i);try{let f=await s(e,p);if(l.has(f.status)&&u<r-1){await a(Ja(o,u));continue}return f}catch(f){if(c=f,u<r-1){await a(Ja(o,u));continue}}finally{g()}}throw c instanceof Error?c:new Error(String(c))}function Ja(e,t){return e*Math.pow(3,t)}function yg(e){return new Promise(t=>setTimeout(t,e))}function wg(e,t){if(t<=0)return{init:e,cleanup:()=>{}};let n=new AbortController,r=setTimeout(()=>n.abort(new Error(`Request timed out after ${t}ms`)),t),o=e?.signal??void 0,i;o&&(o.aborted?n.abort(o.reason):(i=()=>n.abort(o.reason),o.addEventListener("abort",i,{once:!0})));let s=()=>{clearTimeout(r),o&&i&&o.removeEventListener("abort",i)};return{init:{...e,signal:n.signal},cleanup:s}}var nt="unknown";function je(e){return e?e.trim().toLowerCase().replace(/^sc-domain:/,"").replace(/^https?:\/\//,"").replace(/^www\./,"").replace(/\/.*$/,""):""}function bg(e,t){let n=je(e),r=je(t);return!n||!r||n===nt||r===nt?!1:n===r}async function rt(e){let t;try{t=await F(`${e.apiBase}/api/cli/whoami`,{method:"GET",headers:{Authorization:e.authHeader,Accept:"application/json"}},e.fetchImpl?{fetchImpl:e.fetchImpl}:{})}catch(o){return{verdict:"unverified",detail:o.message||"network error"}}if(t.status===404)return{verdict:"unverified",detail:"server does not support /api/cli/whoami"};if(!t.ok)return{verdict:"unverified",detail:`whoami returned HTTP ${t.status}`};let n=null;try{n=await t.json()}catch{n=null}if(!n||n.status!=="ok")return{verdict:"unverified",detail:"malformed whoami response"};let r=typeof n.domain=="string"?n.domain.trim():"";return r?bg(r,e.localDomain)?{verdict:"match",cloudDomain:r}:{verdict:"mismatch",cloudDomain:r}:{verdict:"unverified",detail:"whoami did not return a bound domain"}}function Xa(e,t){return`Cloud project is ${je(e)||e} but this workspace is ${je(t)||t} \u2014 not syncing. Run \`seoagent login\` from this directory to connect the right site \u2014 the CLI can stay logged into both sites at once, no need to log out first.`}var li="SEOAGENT_AUTH";function el(e,t=ze){let n=(e??"").trim();if(!n)return null;let r=n.indexOf(":");if(r<=0||r===n.length-1)return null;let o=n.slice(0,r).trim(),i=n.slice(r+1).trim();return!o||!i?null:{user_token:o,website_token:i,api_base:t}}function tl(e){return`${li}=${e.user_token}:${e.website_token}`}function Ar(e=process.env){return ci(e)?"env":"file"}function Pr(e=process.env){let t=(e[li]??"").trim();return t?el(t)?"ok":"malformed":"absent"}function ci(e=process.env){let t=(e.SEOAGENT_API_BASE??"").trim()||ze;return el(e[li],t)}function Ir(e){if(!e)return"";let t=je(e);return t&&t!==nt?t:""}function mn(){if(!kg(et))return null;try{return JSON.parse(xg(et,"utf-8"))}catch{return null}}function yt(e){return!e||!e.user_token||!e.website_token?null:{user_token:e.user_token,website_token:e.website_token,api_base:e.api_base||ze}}function nl(e){Qa(ee,{recursive:!0}),Qa($g(et),{recursive:!0}),vg(et,JSON.stringify(e,null,2)+`
19
- `,"utf-8");try{_g(et,384)}catch{}}function B(e){let t=ci();if(t)return t;let n=mn();if(!n)return null;if(!e)return yt(n);let r=Ir(e);return r&&Object.keys(n.sites??{}).length>0?yt(n.sites?.[r]):yt(n)}function Tr(e){if(ci())return!0;let t=mn();if(!t)return!1;let n=Ir(e);return n?yt(t.sites?.[n])!==null:!1}function ui(e,t){let n=mn()??{},r=Ir(t),o={...n.sites??{}};r&&(o[r]=e),nl({...e,sites:Object.keys(o).length>0?o:void 0})}function rl(e){let t=mn();if(!t)return!1;let n=Ir(e),r=Object.keys(t.sites??{}).length>0;if(!n||!r)try{return Za(et),!0}catch{return!1}let o=t.sites?.[n];if(!o)return!1;let i={...t.sites};delete i[n];let s=Object.keys(i),a=t.website_token===o.website_token,l=yt(a?i[s[0]]:t);if(!l&&s.length===0)try{return Za(et),!0}catch{return!1}return nl({...l??{},sites:s.length>0?i:void 0}),!0}function ot(){let e=mn();return e?.sites?Object.keys(e.sites).sort():[]}var Sg=new Set(["co","com","net","org","ac","gov","edu"]);function Rg(e){let t=e.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//,"").replace(/[/?#].*$/,"").replace(/:\d+$/,"").replace(/^www\./,"");if(!t)return null;let n=t.split(".").filter(Boolean);if(n.length===0)return null;if(n.length===1)return n[0];let r=n.length>=3&&Sg.has(n[n.length-2])?n.length-3:n.length-2;return n[Math.max(0,r)]||null}async function ol(e){let t=Rg(e.domain);if(!t)return{status:"unavailable"};let n=(e.apiBase||M.BASE).replace(/\/$/,"");try{let r=await F(`${n}/api/cli/keywords/peek`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({install_id:e.installId,keyword:t,domain:e.domain})},{attempts:2,timeoutMs:6e3,fetchImpl:e.fetchImpl});if(!r.ok)return{status:"unavailable"};let o=await r.json();return!o?.ok||!o.opportunity?{status:"unavailable"}:o.opportunity.volume==null?{status:"no-data",keyword:t}:{status:"data",keyword:t,volume:o.opportunity.volume,difficulty:o.opportunity.difficulty,intent:o.opportunity.intent}}catch{return{status:"unavailable"}}}import{existsSync as it,lstatSync as Eg,mkdirSync as wt,readFileSync as di,readdirSync as Cg,rmSync as Ag,statSync as pi,symlinkSync as Pg,writeFileSync as hn}from"fs";import{dirname as Mt,join as se,relative as fi,sep as Ig}from"path";import{fileURLToPath as Tg}from"url";var Og=Mt(Tg(import.meta.url));function il(){return se(Og,"skills")}function Lg(){let e=se(il(),"seoagent.md");if(it(e))return di(e,"utf-8");throw new Error(`Could not find skill file at: ${e}`)}function sl(e,t){let n=[];if(!it(e))return n;for(let r of Cg(e,{withFileTypes:!0})){let o=se(e,r.name),i=se(t,r.name);r.isDirectory()?(wt(i,{recursive:!0}),n.push(...sl(o,i))):r.isFile()&&(wt(Mt(i),{recursive:!0}),hn(i,di(o)),n.push(i))}return n}function bt(e){return it(se(e,"apps/skills-cli/skills/seoagent.md"))}function Ng(e){let t=it(se(e,".agents"));return se(e,t?Ye.AGENTS:Ye.CLAUDE)}function al(e,t){if(bt(e))return[];let n=Ng(e),r=[];for(let[o,i]of Object.entries(t)){let s=se(n,o);wt(Mt(s),{recursive:!0}),hn(s,i,"utf-8"),r.push(s)}return r}function Ut(e,t){let n=it(se(e,".agents")),r=se(e,n?Ye.AGENTS:Ye.CLAUDE),o=se(r,"SKILL.md");if(bt(e))return{skillFile:o,referenceFiles:[]};wt(r,{recursive:!0}),hn(o,t??Lg(),"utf-8");let i=se(il(),"references"),s=se(r,"references"),a=[];try{it(i)&&pi(i).isDirectory()&&(wt(s,{recursive:!0}),a=sl(i,s).map(p=>fi(r,p)))}catch{}let l=n?Dg(e,r):void 0,c=Fg(e,o),u=Mg(e,o);return{skillFile:o,referenceFiles:a,claudeSymlink:l,agentsMdPath:c,cursorRulePath:u}}function Dg(e,t){let n=se(e,Ye.CLAUDE),r=null;try{r=Eg(n)}catch{}if(r){if(!r.isSymbolicLink())return;try{Ag(n,{force:!0})}catch{return}}try{wt(Mt(n),{recursive:!0});let o=fi(Mt(n),t);return Pg(o,n,"dir"),n}catch{return}}var jg="<!-- seoagent:skill -->";function ll(e,t){return fi(e,t).split(Ig).join("/")}function Fg(e,t){let n=se(e,"AGENTS.md"),r=ll(e,t);try{let o="";if(it(n)&&(!pi(n).isFile()||(o=di(n,"utf-8"),/seoagent/i.test(o))))return;let i=[jg,"","## SEOAgent","","This repo uses SEOAgent \u2014 a persistent AI SEO agent. Its state lives in `.seoagent/`.","",`- At session start, read \`${r}\` \u2014 the working contract for all SEO tasks.`,"- At the start of each session, run `seoagent sync`. If it lists pending inbox actions, work them unless the user asked for something else first: read `.seoagent/inbox/README.md`, do each one, then `seoagent ack <id>`.",""].join(`
17
+ `).map(t=>t.trim()).filter(Boolean):[]}function Sr(e,t,n={}){let r=n.execGit??tg,o=n.sourceExists??((m,w)=>Qf(Zf(m,w))),i=n.checkedCommit&&$r.test(n.checkedCommit)?n.checkedCommit:null,s=n.checkedAt&&!Number.isNaN(Date.parse(n.checkedAt))?n.checkedAt:null,a={status:"no_facts",head:null,checkedCommit:i,checkedAt:s,basis:null,changed:[],unsourced:[],urlSourced:[],missingSource:[],repoSourcedCount:0},l=[];for(let m of t)if(!m.source.trim())a.unsourced.push(m);else if(og(m.source))a.urlSourced.push(m);else{let w=rg(m.source);w?l.push({fact:m,path:w}):a.unsourced.push(m)}if(a.repoSourcedCount=l.length,t.length===0)return a;let c=_r(mt(r,e,["rev-parse","HEAD"]))[0]??null;if(!c||!$r.test(c))return a.status="not_git",a;a.head=c;let u=(mt(r,e,["rev-parse","--show-prefix"])??"").trim(),p=(mt(r,e,["rev-parse","--show-toplevel"])??"").trim();for(let{fact:m,path:w}of l)o(e,w)||p!==""&&u!==""&&o(p,w)||a.missingSource.push(m);let g=null,f=[];if(i&&mt(r,e,["cat-file","-e",`${i}^{commit}`])!==null){let m=mt(r,e,["diff","--name-only",i,"HEAD"]);m!==null&&(g=_r(m),a.basis="commit",f=[`${i}..HEAD`])}if(g===null&&s){let m=mt(r,e,["log",`--since=${s}`,"--name-only","--format="]);m!==null&&(g=_r(m),a.basis="date",f=[`--since=${s}`])}if(g===null)return a.status="unchecked",a;let y=new Set(g);for(let{fact:m,path:w}of l){let S=(u?[`${u}${w}`,w]:[w]).find(b=>y.has(b));if(!S)continue;let T=_r(mt(r,e,["log","--format=%h %s","-n",String(ng),...f,"--",`:(top)${S}`]));a.changed.push({...m,commits:T})}return a.status=a.changed.length>0?"changed":"clean",a}var ag=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ht(){return ig()}var lg=new Set(["strapi","wordpress","sanity","contentful","ghost","webflow","shopify","payload","directus","wix","squarespace","blogger","mdx-local","none"]),cg="project.md";function Xe(e){return ri(e,x)}function Rr(e){return ri(Xe(e),cg)}function Wa(e){return Ba(Rr(e))}function A(e){let t=nt(Rr(e));if(!t)return null;let n=t.data;if(typeof n.domain!="string"||!n.domain)return null;let r=typeof n.image_provider=="string"?n.image_provider:void 0,o=typeof n.cms=="string"?n.cms:void 0,i=o&&lg.has(o)?o:void 0,s=typeof n.install_id=="string"?n.install_id:void 0,a=typeof n.publishing=="object"&&n.publishing!==null?n.publishing:void 0,l=typeof n.content_dir=="string"&&n.content_dir?n.content_dir:a&&typeof a.content_dir=="string"&&a.content_dir?a.content_dir:void 0,c=typeof n.public_dir=="string"&&n.public_dir?n.public_dir:a&&typeof a.public_dir=="string"&&a.public_dir?a.public_dir:void 0;return{domain:n.domain,site_type:typeof n.site_type=="string"?n.site_type:"unknown",language:typeof n.language=="string"?n.language:"en",initialized_at:typeof n.initialized_at=="string"?n.initialized_at:"",seoagent_version:typeof n.seoagent_version=="string"?n.seoagent_version:"",skill_version:typeof n.skill_version=="string"&&n.skill_version?n.skill_version:void 0,skill_hash:typeof n.skill_hash=="string"&&/^[0-9a-f]{64}$/.test(n.skill_hash)?n.skill_hash:void 0,install_id:s&&ag.test(s)?s:void 0,schedule:typeof n.schedule=="string"&&n.schedule.trim()?n.schedule.trim():void 0,facts_checked_commit:typeof n.facts_checked_commit=="string"&&$r.test(n.facts_checked_commit)?n.facts_checked_commit:void 0,facts_checked_at:typeof n.facts_checked_at=="string"&&!Number.isNaN(Date.parse(n.facts_checked_at))?n.facts_checked_at:void 0,image_provider:r==="openai"||r==="fal"||r==="replicate"||r==="none"?r:void 0,cms:i,blog_path:typeof n.blog_path=="string"&&n.blog_path?n.blog_path:void 0,content_dir:l?l.replace(/\/+$/,""):void 0,public_dir:xr(c)??void 0,llms_owner:n.llms_owner==="route"?"route":void 0,live_url:typeof n.live_url=="string"&&n.live_url?n.live_url:void 0}}function Ee(e){let t=A(e);if(!t)return null;if(t.install_id)return t.install_id;let n=ht();return X(e,{install_id:n}),n}function ug(e){return["",`# SEOAgent Project \u2014 ${e.domain}`,"","This file holds project-level configuration for the SEOAgent skill.","The skill reads it on every session to know which domain it is working on.","",`Initialized ${e.initialized_at} with seoagent ${e.seoagent_version}.`,""].join(`
18
+ `)}function dg(e){let t={domain:e.domain,site_type:e.site_type,language:e.language,initialized_at:e.initialized_at,seoagent_version:e.seoagent_version};return e.skill_version&&(t.skill_version=e.skill_version),e.skill_hash&&(t.skill_hash=e.skill_hash),e.install_id&&(t.install_id=e.install_id),e.facts_checked_commit&&(t.facts_checked_commit=e.facts_checked_commit),e.facts_checked_at&&(t.facts_checked_at=e.facts_checked_at),e.image_provider&&(t.image_provider=e.image_provider),e.cms&&(t.cms=e.cms),e.blog_path&&(t.blog_path=e.blog_path),e.content_dir&&(t.content_dir=e.content_dir),e.public_dir&&(t.public_dir=e.public_dir),e.llms_owner&&(t.llms_owner=e.llms_owner),e.live_url&&(t.live_url=e.live_url),t}function Ka(e,t){let n=Xe(e);Ha(n,{recursive:!0});let r=ei(dg(t),ug(t));Ga(Rr(e),r,"utf-8")}function X(e,t){let n=Rr(e);if(!Ba(n))return!1;let r=te(sg(n,"utf-8")),o={...r.data,...t};return Ga(n,ei(o,r.body),"utf-8"),!0}function qa(e){let t=Xe(e);for(let n of Pa)Ha(ri(t,n),{recursive:!0})}var oi="Sent an anonymous install ping (random id + CLI version, plus a partial setup-code prefix when --code is used \u2014 no domain, no paths). Opt out: SEOAGENT_TELEMETRY=0",Va="Sent an anonymous ping naming this project's site so its owner can be told the run had no credential (random id + CLI version + domain \u2014 no paths, no secrets). Opt out: SEOAGENT_TELEMETRY=0",pg=2500;function be(e=process.env){let t=(e.SEOAGENT_TELEMETRY??"").trim().toLowerCase();if(t==="0"||t==="false"||t==="off")return!0;let n=(e.DO_NOT_TRACK??"").trim().toLowerCase();return n==="1"||n==="true"}function ii(e=process.env){return(e.GITHUB_ACTIONS??"").trim().toLowerCase()==="true"}function si(e,t=process.env){return ii(t)?`${e}_ci`:e}function fg(e){let t=e.meta&&Object.values(e.meta).some(n=>n!==void 0)?e.meta:null;return{install_id:e.installId,event:e.event,cli_version:e.cliVersion,platform:process.platform,...e.codeHint?{code_hint:e.codeHint}:{},...t?{meta:t}:{}}}async function Qe(e){let t=(e.apiBase||M.BASE).replace(/\/$/,""),n=e.fetchImpl??fetch;try{return(await n(`${t}/api/cli/telemetry`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(fg(e)),signal:AbortSignal.timeout(e.timeoutMs??pg)})).ok}catch{return!1}}var Er=/^sa_[0-9a-f]{24}$/;function Cr(e){let t=(e??"").trim();return Er.test(t)?t.slice(3,11):null}function gg(e){let t=(e??"").trim(),n=t.startsWith("sa_"),r=n?t.slice(3):t,o=r.length>0&&/^[0-9a-f]+$/.test(r),i=/^sa_x+$/i.test(t)||/^sa_[x0.…_-]+$/i.test(t)||/^<.*>$/.test(t)||/^\$\{?[A-Z_]+\}?$/.test(t)||/(your|paste|code|setup)/i.test(t);return{len:t.length,prefix_ok:n,hex_ok:o,well_formed:Er.test(t),placeholder:i}}function ai(e){let t=(e??"").trim();return t?Cr(t)?{with_code:!0}:{with_code:!0,code_shape:gg(t)}:{with_code:!1}}function Ya(e){switch(e){case"code_not_found":return"That setup code was not recognized: it was never issued. Codes cannot be guessed or retyped from memory; copy one exactly from seoagent.com/grok. A scheduled run on a fresh machine needs the SEOAGENT_AUTH secret (`seoagent whoami --env` on the bound machine), not a setup code.";case"code_already_used":return"That setup code has already been used \u2014 each code works exactly once. Generate a new one at seoagent.com/grok.";case"code_revoked":return"That setup code was replaced by a newer one. Use the latest code, or generate a new one at seoagent.com/grok.";case"code_expired":return"That setup code has expired. Generate a new one at seoagent.com/grok.";case"setup_codes_unavailable":return"Setup codes are not enabled on this server yet. Run `seoagent login` (browser flow) instead.";case"domain_required":return"This code has no site attached and the project has no domain. Your code has NOT been used \u2014 run `seoagent init` in the project root (or pass `--domain example.com`) and retry with the same code.";default:return typeof e=="string"&&e?`Login failed: ${e}`:"Login failed."}}function za(e,t){let n=t&&typeof t=="object"?t:null;if(e>=500)return e===503&&n?.error==="setup_codes_unavailable"?{status:"error",terminal:!0,message:Ya(n.error)}:{status:"error",terminal:!1,message:`HTTP ${e} (server error)`};if(e>=400){let r=typeof n?.error=="string"&&n.error?n.error:void 0;return{status:"error",terminal:!0,message:Ya(n?.error),...r?{code:r}:{}}}if(!n)return{status:"error",terminal:!0,message:`Malformed response: expected an object, got ${typeof t}`};if(n.status==="ready"){if(typeof n.user_token=="string"&&typeof n.website_token=="string"){let r=typeof n.email=="string"&&n.email?n.email:void 0,o=typeof n.domain=="string"&&n.domain?n.domain:void 0;return{status:"ready",user_token:n.user_token,website_token:n.website_token,...r?{email:r}:{},...o?{domain:o}:{}}}return{status:"error",terminal:!0,message:"Malformed response: status=ready without user_token+website_token"}}return{status:"error",terminal:!0,message:`Malformed response: unknown status=${JSON.stringify(n.status)}`}}import{existsSync as kg,mkdirSync as Qa,readFileSync as xg,writeFileSync as vg,chmodSync as _g,unlinkSync as Za}from"fs";import{dirname as $g}from"path";var mg=new Set([502,503,504]),hg=1e4;async function F(e,t,n={}){let r=Math.max(1,n.attempts??3),o=Math.max(0,n.baseDelayMs??500),i=n.timeoutMs??hg,s=n.fetchImpl??fetch,a=n.sleep??yg,l=n.transientStatuses??mg,c=null;for(let u=0;u<r;u++){let{init:p,cleanup:g}=wg(t,i);try{let f=await s(e,p);if(l.has(f.status)&&u<r-1){await a(Ja(o,u));continue}return f}catch(f){if(c=f,u<r-1){await a(Ja(o,u));continue}}finally{g()}}throw c instanceof Error?c:new Error(String(c))}function Ja(e,t){return e*Math.pow(3,t)}function yg(e){return new Promise(t=>setTimeout(t,e))}function wg(e,t){if(t<=0)return{init:e,cleanup:()=>{}};let n=new AbortController,r=setTimeout(()=>n.abort(new Error(`Request timed out after ${t}ms`)),t),o=e?.signal??void 0,i;o&&(o.aborted?n.abort(o.reason):(i=()=>n.abort(o.reason),o.addEventListener("abort",i,{once:!0})));let s=()=>{clearTimeout(r),o&&i&&o.removeEventListener("abort",i)};return{init:{...e,signal:n.signal},cleanup:s}}var Ze="unknown";function je(e){return e?e.trim().toLowerCase().replace(/^sc-domain:/,"").replace(/^https?:\/\//,"").replace(/^www\./,"").replace(/\/.*$/,""):""}function bg(e,t){let n=je(e),r=je(t);return!n||!r||n===Ze||r===Ze?!1:n===r}async function rt(e){let t;try{t=await F(`${e.apiBase}/api/cli/whoami`,{method:"GET",headers:{Authorization:e.authHeader,Accept:"application/json"}},e.fetchImpl?{fetchImpl:e.fetchImpl}:{})}catch(o){return{verdict:"unverified",detail:o.message||"network error"}}if(t.status===404)return{verdict:"unverified",detail:"server does not support /api/cli/whoami"};if(!t.ok)return{verdict:"unverified",detail:`whoami returned HTTP ${t.status}`};let n=null;try{n=await t.json()}catch{n=null}if(!n||n.status!=="ok")return{verdict:"unverified",detail:"malformed whoami response"};let r=typeof n.domain=="string"?n.domain.trim():"";return r?bg(r,e.localDomain)?{verdict:"match",cloudDomain:r}:{verdict:"mismatch",cloudDomain:r}:{verdict:"unverified",detail:"whoami did not return a bound domain"}}function Xa(e,t){return`Cloud project is ${je(e)||e} but this workspace is ${je(t)||t} \u2014 not syncing. Run \`seoagent login\` from this directory to connect the right site \u2014 the CLI can stay logged into both sites at once, no need to log out first.`}var li="SEOAGENT_AUTH";function el(e,t=ze){let n=(e??"").trim();if(!n)return null;let r=n.indexOf(":");if(r<=0||r===n.length-1)return null;let o=n.slice(0,r).trim(),i=n.slice(r+1).trim();return!o||!i?null:{user_token:o,website_token:i,api_base:t}}function tl(e){return`${li}=${e.user_token}:${e.website_token}`}function Ar(e=process.env){return ci(e)?"env":"file"}function Pr(e=process.env){let t=(e[li]??"").trim();return t?el(t)?"ok":"malformed":"absent"}function ci(e=process.env){let t=(e.SEOAGENT_API_BASE??"").trim()||ze;return el(e[li],t)}function Ir(e){if(!e)return"";let t=je(e);return t&&t!==Ze?t:""}function mn(){if(!kg(tt))return null;try{return JSON.parse(xg(tt,"utf-8"))}catch{return null}}function yt(e){return!e||!e.user_token||!e.website_token?null:{user_token:e.user_token,website_token:e.website_token,api_base:e.api_base||ze}}function nl(e){Qa(ee,{recursive:!0}),Qa($g(tt),{recursive:!0}),vg(tt,JSON.stringify(e,null,2)+`
19
+ `,"utf-8");try{_g(tt,384)}catch{}}function B(e){let t=ci();if(t)return t;let n=mn();if(!n)return null;if(!e)return yt(n);let r=Ir(e);return r&&Object.keys(n.sites??{}).length>0?yt(n.sites?.[r]):yt(n)}function Tr(e){if(ci())return!0;let t=mn();if(!t)return!1;let n=Ir(e);return n?yt(t.sites?.[n])!==null:!1}function ui(e,t){let n=mn()??{},r=Ir(t),o={...n.sites??{}};r&&(o[r]=e),nl({...e,sites:Object.keys(o).length>0?o:void 0})}function rl(e){let t=mn();if(!t)return!1;let n=Ir(e),r=Object.keys(t.sites??{}).length>0;if(!n||!r)try{return Za(tt),!0}catch{return!1}let o=t.sites?.[n];if(!o)return!1;let i={...t.sites};delete i[n];let s=Object.keys(i),a=t.website_token===o.website_token,l=yt(a?i[s[0]]:t);if(!l&&s.length===0)try{return Za(tt),!0}catch{return!1}return nl({...l??{},sites:s.length>0?i:void 0}),!0}function ot(){let e=mn();return e?.sites?Object.keys(e.sites).sort():[]}var Sg=new Set(["co","com","net","org","ac","gov","edu"]);function Rg(e){let t=e.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//,"").replace(/[/?#].*$/,"").replace(/:\d+$/,"").replace(/^www\./,"");if(!t)return null;let n=t.split(".").filter(Boolean);if(n.length===0)return null;if(n.length===1)return n[0];let r=n.length>=3&&Sg.has(n[n.length-2])?n.length-3:n.length-2;return n[Math.max(0,r)]||null}async function ol(e){let t=Rg(e.domain);if(!t)return{status:"unavailable"};let n=(e.apiBase||M.BASE).replace(/\/$/,"");try{let r=await F(`${n}/api/cli/keywords/peek`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({install_id:e.installId,keyword:t,domain:e.domain})},{attempts:2,timeoutMs:6e3,fetchImpl:e.fetchImpl});if(!r.ok)return{status:"unavailable"};let o=await r.json();return!o?.ok||!o.opportunity?{status:"unavailable"}:o.opportunity.volume==null?{status:"no-data",keyword:t}:{status:"data",keyword:t,volume:o.opportunity.volume,difficulty:o.opportunity.difficulty,intent:o.opportunity.intent}}catch{return{status:"unavailable"}}}import{existsSync as it,lstatSync as Eg,mkdirSync as wt,readFileSync as di,readdirSync as Cg,rmSync as Ag,statSync as pi,symlinkSync as Pg,writeFileSync as hn}from"fs";import{dirname as Mt,join as se,relative as fi,sep as Ig}from"path";import{fileURLToPath as Tg}from"url";var Og=Mt(Tg(import.meta.url));function il(){return se(Og,"skills")}function Lg(){let e=se(il(),"seoagent.md");if(it(e))return di(e,"utf-8");throw new Error(`Could not find skill file at: ${e}`)}function sl(e,t){let n=[];if(!it(e))return n;for(let r of Cg(e,{withFileTypes:!0})){let o=se(e,r.name),i=se(t,r.name);r.isDirectory()?(wt(i,{recursive:!0}),n.push(...sl(o,i))):r.isFile()&&(wt(Mt(i),{recursive:!0}),hn(i,di(o)),n.push(i))}return n}function bt(e){return it(se(e,"apps/skills-cli/skills/seoagent.md"))}function Ng(e){let t=it(se(e,".agents"));return se(e,t?Ye.AGENTS:Ye.CLAUDE)}function al(e,t){if(bt(e))return[];let n=Ng(e),r=[];for(let[o,i]of Object.entries(t)){let s=se(n,o);wt(Mt(s),{recursive:!0}),hn(s,i,"utf-8"),r.push(s)}return r}function Ut(e,t){let n=it(se(e,".agents")),r=se(e,n?Ye.AGENTS:Ye.CLAUDE),o=se(r,"SKILL.md");if(bt(e))return{skillFile:o,referenceFiles:[]};wt(r,{recursive:!0}),hn(o,t??Lg(),"utf-8");let i=se(il(),"references"),s=se(r,"references"),a=[];try{it(i)&&pi(i).isDirectory()&&(wt(s,{recursive:!0}),a=sl(i,s).map(p=>fi(r,p)))}catch{}let l=n?Dg(e,r):void 0,c=Fg(e,o),u=Mg(e,o);return{skillFile:o,referenceFiles:a,claudeSymlink:l,agentsMdPath:c,cursorRulePath:u}}function Dg(e,t){let n=se(e,Ye.CLAUDE),r=null;try{r=Eg(n)}catch{}if(r){if(!r.isSymbolicLink())return;try{Ag(n,{force:!0})}catch{return}}try{wt(Mt(n),{recursive:!0});let o=fi(Mt(n),t);return Pg(o,n,"dir"),n}catch{return}}var jg="<!-- seoagent:skill -->";function ll(e,t){return fi(e,t).split(Ig).join("/")}function Fg(e,t){let n=se(e,"AGENTS.md"),r=ll(e,t);try{let o="";if(it(n)&&(!pi(n).isFile()||(o=di(n,"utf-8"),/seoagent/i.test(o))))return;let i=[jg,"","## SEOAgent","","This repo uses SEOAgent \u2014 a persistent AI SEO agent. Its state lives in `.seoagent/`.","",`- At session start, read \`${r}\` \u2014 the working contract for all SEO tasks.`,"- At the start of each session, run `seoagent sync`. If it lists pending inbox actions, work them unless the user asked for something else first: read `.seoagent/inbox/README.md`, do each one, then `seoagent ack <id>`.",""].join(`
20
20
  `),s=o.length===0?i:o.endsWith(`
21
21
  `)?`${o}
22
22
  ${i}`:`${o}
@@ -51,7 +51,7 @@ page), fill in:
51
51
 
52
52
  Then show the owner the draft for review, and delete this comment.
53
53
  -->
54
- `;function Ce(e){let t=bi(e,".seoagent",ki);if(!wi(t))return null;let n=vl(t,"utf-8");return yi(n)}function _l(e,t){let n=bi(e,".seoagent",ki);return wi(n)?!1:(Qg(n,Zg+xl({business:{type:t||""},writingInstructions:[],referenceUrls:[],facts:[],topicsToAvoid:[],contentTone:null,additionalNotes:null}),"utf-8"),!0)}function Bt(e){let t=bi(e,".seoagent",ki);if(!wi(t))return!0;try{return Fe(vl(t,"utf-8"))}catch{return!1}}import{existsSync as kn,readFileSync as $l,readdirSync as em,statSync as Sl}from"fs";import{join as _t}from"path";var tm=[{cms:"strapi",deps:["strapi","@strapi/strapi","@strapi/"],envKeys:["STRAPI_URL","STRAPI_API_URL","NEXT_PUBLIC_STRAPI_URL","STRAPI_API_TOKEN"],fsMarkers:["strapi/","apps/strapi/","packages/strapi/","cms/"]},{cms:"wordpress",deps:["wpapi","wp-graphql","@wordpress/api-fetch","@wordpress/"],envKeys:["WORDPRESS_API_URL","WP_API_URL","NEXT_PUBLIC_WORDPRESS_URL"],fsMarkers:[]},{cms:"sanity",deps:["@sanity/client","next-sanity","sanity"],envKeys:["SANITY_PROJECT_ID","NEXT_PUBLIC_SANITY_PROJECT_ID","SANITY_API_TOKEN"],fsMarkers:["sanity/","studio/","sanity.config.ts","sanity.config.js"]},{cms:"contentful",deps:["contentful","@contentful/rich-text-react-renderer","@contentful/"],envKeys:["CONTENTFUL_SPACE_ID","CONTENTFUL_ACCESS_TOKEN","NEXT_PUBLIC_CONTENTFUL_SPACE_ID"],fsMarkers:[]},{cms:"ghost",deps:["@tryghost/content-api","@tryghost/"],envKeys:["GHOST_URL","GHOST_API_KEY","NEXT_PUBLIC_GHOST_URL"],fsMarkers:[]},{cms:"webflow",deps:["webflow-api"],envKeys:["WEBFLOW_API_TOKEN","WEBFLOW_SITE_ID"],fsMarkers:[]},{cms:"shopify",deps:["@shopify/hydrogen","@shopify/storefront-api-client","@shopify/shopify-api","@shopify/"],envKeys:["SHOPIFY_STOREFRONT_TOKEN","SHOPIFY_STORE_DOMAIN","SHOPIFY_ADMIN_API_TOKEN"],fsMarkers:["shopify.config.ts","shopify.config.js"]},{cms:"payload",deps:["payload","@payloadcms/next","@payloadcms/"],envKeys:["PAYLOAD_SECRET","PAYLOAD_PUBLIC_SERVER_URL"],fsMarkers:["payload.config.ts","payload.config.js"]},{cms:"directus",deps:["@directus/sdk","directus"],envKeys:["DIRECTUS_URL","DIRECTUS_TOKEN"],fsMarkers:[]}];function nm(e){let t=_t(e,"package.json");if(!kn(t))return{deps:{},source:"package.json"};try{let n=JSON.parse($l(t,"utf-8"));return{deps:{...n.dependencies,...n.devDependencies,...n.peerDependencies},source:"package.json"}}catch{return{deps:{},source:"package.json"}}}function rm(e,t){for(let n of t)if(n.endsWith("/")){if(e.startsWith(n))return!0}else if(e===n)return!0;return!1}function om(e){let t={};for(let n of Dt){let r=_t(e,n);if(kn(r))try{let o=$l(r,"utf-8");for(let i of o.split(/\r?\n/)){let s=i.trim();if(!s||s.startsWith("#"))continue;let a=s.indexOf("=");if(a===-1)continue;let l=s.slice(0,a).trim();l&&!(l in t)&&(t[l]=n)}}catch{}}return t}function im(e,t){let n=_t(e,t.replace(/\/$/,""));if(!kn(n))return!1;if(t.endsWith("/"))try{return Sl(n).isDirectory()}catch{return!1}return!0}function sm(e){let t=["content","_posts","posts",_t("src","content")];for(let n of t){let r=_t(e,n);if(kn(r))try{if(!Sl(r).isDirectory())continue;let o=[r],i=0;for(;o.length>0&&i<50;){let s=o.pop();for(let a of em(s,{withFileTypes:!0}))if(i++,!a.name.startsWith(".")){if(a.isDirectory()&&o.length<5){o.push(_t(s,a.name));continue}if(a.isFile()&&/\.(md|mdx)$/i.test(a.name))return{type:"directory",detail:n,source:`${n}/${a.name}`}}}}catch{}}return null}function am(e){let t=[{marker:"app/blog/page.tsx",path:"/blog"},{marker:"app/blog/page.jsx",path:"/blog"},{marker:"app/blog/page.js",path:"/blog"},{marker:"src/app/blog/page.tsx",path:"/blog"},{marker:"src/app/blog/page.jsx",path:"/blog"},{marker:"pages/blog/index.tsx",path:"/blog"},{marker:"pages/blog/index.jsx",path:"/blog"},{marker:"pages/blog/index.js",path:"/blog"},{marker:"src/pages/blog/index.tsx",path:"/blog"},{marker:"app/(blog)/page.tsx",path:"/blog"},{marker:"app/articles/page.tsx",path:"/articles"},{marker:"pages/articles/index.tsx",path:"/articles"},{marker:"app/posts/page.tsx",path:"/posts"},{marker:"pages/posts/index.tsx",path:"/posts"},{marker:"app/learn/page.tsx",path:"/learn"},{marker:"app/resources/page.tsx",path:"/resources"}],n=[""],r=ni(e);r&&n.push(r);for(let o of n)for(let i of t){let s=o?`${o}/${i.marker}`:i.marker;if(kn(_t(e,s)))return i.path}return null}function Rl(e){let t=[],{deps:n}=nm(e),r=om(e),o="none";for(let s of tm){let a=[];for(let l of Object.keys(n))if(rm(l,s.deps)){a.push({type:"dep",detail:l,source:"package.json"});break}for(let l of s.envKeys)if(r[l]){a.push({type:"env",detail:l,source:r[l]});break}for(let l of s.fsMarkers)if(im(e,l)){let c=l.endsWith("/")?"directory":"file";a.push({type:c,detail:l,source:l});break}if(a.length>0){o=s.cms,t.push(...a);break}}if(o==="none"){let s=sm(e);s&&(o="mdx-local",t.push(s))}let i=am(e);return{cms:o,blog_path:i,evidence:t}}import{existsSync as lm,readFileSync as cm}from"fs";import{join as um}from"path";var El=["openai","fal","replicate"],Ht={openai:["OPENAI_API_KEY"],fal:["FAL_KEY","FAL_API_KEY"],replicate:["REPLICATE_API_TOKEN","REPLICATE_API_KEY"]};function dm(e){let t={};if(!lm(e))return t;let n=cm(e,"utf-8");for(let r of n.split(/\r?\n/)){let o=r.trim();if(!o||o.startsWith("#"))continue;let i=o.indexOf("=");if(i===-1)continue;let s=o.slice(0,i).trim(),a=o.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),t[s]=a}return t}function Cl(e,t){let n={};for(let r of t){let o=process.env[r];o&&o.trim().length>0&&(n[r]={value:o,source:"process"})}for(let r of Dt){let o=um(e,r),i=dm(o);for(let s of t){if(n[s])continue;let a=i[s];a&&a.length>0&&(n[s]={value:a,source:r})}}return{found:n}}function st(e){let t=[].concat(...El.map(a=>Ht[a])),n=Cl(e,t),r=[];for(let a of El)Ht[a].some(l=>n.found[l])&&r.push(a);if(r.length===0)return{provider:"none",matched_key:null,source:null,available_providers:[]};let o=r[0],i=Ht[o].find(a=>n.found[a])??null,s=i?n.found[i].source:null;return{provider:o,matched_key:i,source:s,available_providers:r}}function Al(e,t){let n=Cl(e,Ht[t]);for(let r of Ht[t])if(n.found[r])return{key:n.found[r].value,envName:r};return null}function Pl(){return Ht}import{existsSync as $t,readFileSync as xi}from"fs";import{join as St}from"path";function Il(e){try{return new URL(e).hostname}catch{return e}}function Tl(e){let t=e.toLowerCase();return!!(t==="github.com"||t.endsWith(".github.com")||t==="gitlab.com"||t.endsWith(".gitlab.com")||t==="bitbucket.org"||t.endsWith(".bitbucket.org")||t==="dev.azure.com"||t==="visualstudio.com"||t.endsWith(".visualstudio.com")||t==="npmjs.com"||t.endsWith(".npmjs.com"))}function Ol(e){let t=e.trim().toLowerCase().replace(/^\[([^\]]+)\](?::\d{1,5})?$/,"$1").replace(/^((?:\d{1,3}\.){3}\d{1,3}|localhost|[a-z0-9.-]*\.localhost)(?::\d{1,5})?$/,"$1");return t==="localhost"||t.endsWith(".localhost")||t==="::1"||t==="0.0.0.0"?!0:/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t)}function pm(e){for(let t of Dt){let n=St(e,t);if(!$t(n))continue;let r=xi(n,"utf-8");for(let o of Aa){let i=r.match(new RegExp(`^${o}=(.+)$`,"m"));if(i){let s=i[1].trim().replace(/^["']|["']$/g,""),a=Il(s);if(Tl(a)||Ol(a))continue;return{value:a,source:`${t} (${o})`}}}}return null}function fm(e){let t=St(e,"package.json");if(!$t(t))return null;try{let n=JSON.parse(xi(t,"utf-8"));if(!n.homepage)return null;let r=Il(n.homepage);return Tl(r)||Ol(r)?null:{value:r,source:"package.json (homepage)"}}catch{return null}}function Ll(e,t){let n=[];t?.("Checking for monorepo / workspace layout\u2026"),$t(St(e,"pnpm-workspace.yaml"))&&n.push({field:"context",detail:"Monorepo workspace detected",source:"pnpm-workspace.yaml \u2014 using this directory for project signals"});let r=null;t?.("Scanning .env files for public / site URLs\u2026");let o=pm(e);if(o)r=o.value,n.push({field:"domain",detail:o.value,source:o.source});else{t?.("Reading package.json homepage (skipping GitHub/GitLab repo URLs)\u2026");let a=fm(e);a&&(r=a.value,n.push({field:"domain",detail:a.value,source:a.source}))}let i=St(e,"package.json"),s=null;if($t(i))try{t?.("Reading dependencies to infer site type\u2026");let a=JSON.parse(xi(i,"utf-8")),l=Object.keys({...a.dependencies,...a.devDependencies}),c=(...u)=>u.some(p=>l.includes(p));if(c("@shopify/hydrogen","@shopify/polaris")||$t(St(e,"shopify.config.js"))||$t(St(e,"shopify.config.ts"))){s="product";let u=c("@shopify/hydrogen","@shopify/polaris")?"Shopify-related dependencies in package.json":$t(St(e,"shopify.config.ts"))?"shopify.config.ts":"shopify.config.js";n.push({field:"site_type",detail:"product",source:u})}else{let u=c("stripe","@stripe/stripe-js","@stripe/react-stripe-js","paddle","@paddle/paddle-js"),p=c("next-auth","@auth/core","lucia","clerk","@clerk/nextjs","@clerk/clerk-react"),g=c("next");u&&(g||p)?(s="saas",n.push({field:"site_type",detail:"saas",source:g?"payment SDK + Next.js in package.json":"payment SDK + auth library in package.json"})):!u&&c("astro","gatsby","contentlayer","next-mdx-remote","mdx-bundler","vitepress","vuepress","@docusaurus/core","docusaurus","nextra")&&(s="content",n.push({field:"site_type",detail:"content",source:c("vitepress","vuepress","@docusaurus/core","docusaurus","nextra")?"documentation / site generator in package.json (VitePress, Docusaurus, Nextra, etc.)":"content-oriented dependencies in package.json (no payment SDKs detected)"}))}}catch{}return{domain:r,siteType:s,evidence:n}}import{existsSync as Wm,readFileSync as Mr,readdirSync as nc,statSync as Km}from"fs";import{join as me,sep as qm}from"path";var gm=/^\/(?:cdn-cgi|wp-json|wp-admin|wp-includes|wp-content\/(?:plugins|themes|uploads)|\.well-known|xmlrpc\.php|wp-login\.php|wp-cron\.php|feed|comments\/feed)(?:\/|$)/i;function Dr(e){let t=e;if(/^https?:\/\//i.test(e))try{t=new URL(e).pathname}catch{return!1}return gm.test(t)}var vi=new Set([202,403,429,503]),Nl="bot challenge",mm=[[/\/\.well-known\/sgcaptcha\//i,"SiteGround"],[/\/cdn-cgi\/challenge-platform\/|cf-chl-|cf_chl_opt|<title>\s*Just a moment\.{0,3}\s*<\/title>/i,"Cloudflare"],[/Vercel Security Checkpoint/i,"Vercel"],[/_Incapsula_Resource|incapsula/i,"Imperva"],[/captcha-delivery\.com|datadome/i,"DataDome"],[/px-captcha|_pxhd|perimeterx/i,"PerimeterX"],[/awswaf|aws-waf-token/i,"AWS WAF"]];function _i(e,t){if(!e)return null;let n=e.slice(0,2e4);for(let[r,o]of mm)if(r.test(n))return o;return t!=null&&vi.has(t)&&/captcha|challenge/i.test(n)&&n.replace(/<script[\s\S]*?<\/script>|<style[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").trim().split(/\s+/).filter(Boolean).length<120?"bot protection":null}function Dl(e){return`${Nl} (${e})`}function xn(e){return typeof e=="string"&&e.startsWith(Nl)}var Fl=[/^\/admin(\/|$)/i,/^\/(o)?auth(\/|$)/i,/^\/account(s)?(\/|$)/i,/^\/dashboard(\/|$)/i,/^\/settings(\/|$)/i,/^\/login(\/|$)/i,/^\/logout(\/|$)/i,/^\/sign[-_]?in(\/|$)/i,/^\/sign[-_]?up(\/|$)/i,/^\/register(\/|$)/i,/^\/reset[-_]?password(\/|$)/i,/^\/verify(\/|$)/i,/^\/api(\/|$)/i,/^\/_next(\/|$)/i,/^\/checkout(\/|$)/i,/^\/cart(\/|$)/i],hm=[/^\/[a-z0-9]+-(?:onboarding|login|logout|signin|sign-in|signup|sign-up|dashboard|checkout|account)$/i];function Ae(e){let t=[],n=/<loc>\s*([^<\s][^<]*?)\s*<\/loc>/gi,r;for(;(r=n.exec(e))!==null;){let o=r[1].replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&#39;/g,"'").replace(/&quot;/g,'"').trim();o&&t.push(o)}return t}function ym(e){let t=[],n=/<lastmod>\s*([^<\s][^<]*?)\s*<\/lastmod>/gi,r;for(;(r=n.exec(e))!==null;)t.push(r[1].trim());return t}var wm=10,jl=.9;function bm(e,t){if(t<wm||e.length<t*jl)return null;let n=new Map;for(let r of e)n.set(r,(n.get(r)||0)+1);for(let[r,o]of n)if(o>=t*jl)return r;return null}function L(e){let t=e;try{t=new URL(e).pathname}catch{let n=t.indexOf("#");n!==-1&&(t=t.slice(0,n));let r=t.indexOf("?");r!==-1&&(t=t.slice(0,r))}return t.length>1&&t.endsWith("/")&&(t=t.slice(0,-1)),t||"/"}function Me(e){return Fl.some(t=>t.test(e))||hm.some(t=>t.test(e))}function Ml(e){return Fl.some(t=>t.test(e))}function km(e){return e.filter(t=>Me(L(t)))}function xm(e,t){let n=new Set(e.map(L)),r=[],o=new Set;for(let i of t){let s=L(i);Me(s)||n.has(s)||o.has(s)||(o.add(s),r.push(s))}return r}function vn(e){return`https://${e.replace(/^https?:\/\//,"").replace(/\/+$/,"")}/sitemap.xml`}async function Ul(e){let t=e.sitemapUrl||vn(e.domain),n=[],r={ok:!1,sitemapUrl:t,fetched:!1,status:null,urls:[],privateUrls:[],missing:[],hasLastmod:!1,lastmods:[],uniformLastmod:null,issues:n},o="";try{let i=await F(t,{headers:{"user-agent":"SEOAgent-CLI/sitemap-check"}},{attempts:2,timeoutMs:1e4,fetchImpl:e.fetchImpl});if(r.status=i.status,r.fetched=!0,!i.ok)return n.push({level:"error",message:`Sitemap returned HTTP ${i.status} \u2014 Google can't fetch it. Make sure ${t} serves 200.`}),r;o=await i.text()}catch(i){return n.push({level:"error",message:`Could not reach ${t} (${i instanceof Error?i.message:String(i)}). If the site isn't deployed yet, that's expected.`}),r}return/<urlset|<sitemapindex/i.test(o)?(r.urls=Ae(o),r.lastmods=ym(o),r.hasLastmod=r.lastmods.length>0,r.urls.length===0?(n.push({level:"error",message:"Sitemap is valid XML but contains zero <loc> URLs."}),r):(/<sitemapindex/i.test(o)&&n.push({level:"info",message:`Sitemap index with ${r.urls.length} child sitemap(s). Child URLs are not expanded by this check.`}),r.privateUrls=km(r.urls),r.privateUrls.length>0&&n.push({level:"warning",message:`${r.privateUrls.length} private/noindex URL(s) leaked into the sitemap (e.g. ${r.privateUrls.slice(0,3).map(L).join(", ")}). Remove auth/admin/api routes from the generator.`}),r.uniformLastmod=bm(r.lastmods,r.urls.length),r.uniformLastmod?n.push({level:"warning",message:`Every URL carries the same <lastmod> (${r.uniformLastmod}) \u2014 that is the sitemap's own build time, not a content date. Google discounts <lastmod> for the WHOLE sitemap when it looks generated, including pages whose dates are real. Emit a per-page date where you have one and omit <lastmod> everywhere else.`}):r.hasLastmod||n.push({level:"info",message:"No <lastmod> dates. That is fine \u2014 omitting them is honest. Add a per-page date only where you have a real one (CMS updatedAt, file mtime); a single bulk date on every URL is worse than none."}),e.knownUrls&&e.knownUrls.length>0&&(r.missing=xm(r.urls,e.knownUrls),r.missing.length>0&&n.push({level:"warning",message:`${r.missing.length} public page(s) in the repo are missing from the sitemap (e.g. ${r.missing.slice(0,3).join(", ")}). Add them to the generator so Google can find them.`})),r.ok=!n.some(i=>i.level==="error"),r)):(n.push({level:"error",message:`Response is not a valid XML sitemap (no <urlset>/<sitemapindex>). Got ${o.length} bytes.`}),r)}var Si=/<(script|style|noscript|template|svg|nav|header|footer)\b[^>]*>[\s\S]*?<\/\1>/gi,Bl=30;function _n(e){let t=/<body\b[^>]*>([\s\S]*?)<\/body>/i.exec(e);return t?t[1]:e}var vm={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:" "};function Rt(e){return e.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z]+);/gi,(t,n)=>{if(n[0]!=="#")return vm[n.toLowerCase()]??t;let r=n[1]==="x"||n[1]==="X",o=Number.parseInt(n.slice(r?2:1),r?16:10);return o>0&&o<=1114111?String.fromCodePoint(o):t})}function Ze(e,t){let n=new RegExp(`\\b${t}\\s*=\\s*"([^"]*)"`,"i").exec(e);if(n)return Rt(n[1]).trim();let r=new RegExp(`\\b${t}\\s*=\\s*'([^']*)'`,"i").exec(e);if(r)return Rt(r[1]).trim();let o=new RegExp(`\\b${t}\\s*=\\s*([^\\s>]+)`,"i").exec(e);return o?Rt(o[1]).trim():null}function Et(e){return e?(e.match(/<meta\b[^>]*>/gi)??[]).some(n=>/\bname\s*=\s*["']?\s*(robots|googlebot)\b/i.test(n)&&/\bnoindex\b/i.test(n)):!1}function _m(e){return typeof e=="string"&&/\bnoindex\b/i.test(e)}function $m(e){let t=/<title\b[^>]*>([\s\S]*?)<\/title>/i.exec(e);return t&&Rt(t[1].replace(/\s+/g," ")).trim()||null}function Sm(e){let t=e.match(/<meta\b[^>]*>/gi)??[];for(let n of t){let r=Ze(n,"name");if(r&&r.toLowerCase()==="description"){let o=Ze(n,"content");return o&&o.trim()?o.trim():null}}return null}function Rm(e){let t=_n(e),n=[],r=/<h1\b[^>]*>([\s\S]*?)<\/h1>/gi,o;for(;(o=r.exec(t))!==null;){let i=Rt(o[1].replace(/<[^>]+>/g," ").replace(/\s+/g," ")).trim();i&&n.push(i)}return n}function Em(e){let t=e.match(/<link\b[^>]*>/gi)??[];for(let n of t){let r=Ze(n,"rel");if(r&&r.toLowerCase().split(/\s+/).includes("canonical")){let o=Ze(n,"href");return o&&o.trim()?o.trim():null}}return null}function Cm(e){let t=[],n=/<script\b[^>]*type\s*=\s*['"]application\/ld\+json['"][^>]*>([\s\S]*?)<\/script>/gi,r;for(;(r=n.exec(e))!==null;){let o=r[1].trim();if(o)try{let i=JSON.parse(o);t.push({types:$i(i),valid:!0})}catch{let i=Array.from(o.matchAll(/"@type"\s*:\s*"([^"]+)"/g)).map(s=>s[1]);t.push({types:i,valid:!1})}}return t}function $i(e,t=[]){if(Array.isArray(e)){for(let n of e)$i(n,t);return t}if(e&&typeof e=="object"){let n=e,r=n["@type"];if(typeof r=="string")t.push(r);else if(Array.isArray(r))for(let o of r)typeof o=="string"&&t.push(o);Array.isArray(n["@graph"])&&$i(n["@graph"],t)}return t}function Vl(e,t){let n={},r=e.match(/<meta\b[^>]*>/gi)??[];for(let o of r){let i=(Ze(o,"property")||Ze(o,"name")||"").toLowerCase();if(i.startsWith(t)){let s=Ze(o,"content");s!==null&&(n[i.slice(t.length)]=s)}}return n}function Am(e){return Vl(e,"og:")}function Pm(e){return Vl(e,"twitter:")}function Im(e,t=5){let r=_n(e).match(/<img\b[^>]*>/gi)??[],o=0,i=[];for(let s of r)if(!/\salt(?=[\s=/>])/i.test(s)&&(o++,i.length<t)){let l=Ze(s,"src");l&&i.push(l)}return{imgCount:r.length,missingAlt:o,missingAltSrcs:i}}var Tm=/\.(png|jpe?g|gif|svg|webp|avif|ico|css|js|mjs|json|pdf|zip|gz|mp4|webm|mp3|woff2?|ttf|xml|txt)$/i;function Ri(e,t,n=100){let r;try{r=new URL(t).origin}catch{return[]}let o=[],i=new Set,s=e.match(/<a\b[^>]*>/gi)??[];for(let a of s){if(o.length>=n)break;let l=Ze(a,"href");if(!l||l.startsWith("#")||/^(mailto:|tel:|javascript:|data:)/i.test(l))continue;let c;try{c=new URL(l,t)}catch{continue}if(c.origin!==r||Tm.test(c.pathname)||Dr(c.pathname)||Me(c.pathname)||/^\/cdn-cgi(\/|$)/i.test(c.pathname))continue;c.hash="";let u=c.pathname==="/"?`${c.origin}/${c.search}`:`${c.origin}${c.pathname.replace(/\/+$/,"")}${c.search}`;i.has(u)||(i.add(u),o.push(u))}return o}function Yl(e){return(_n(e).replace(Si," ").match(/<a\b[^>]*\bhref\s*=/gi)??[]).length}function zl(e){let t=_n(e).replace(Si," ").replace(/<!--[\s\S]*?-->/g," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/gi," ").replace(/&[a-z]+;/gi," ").replace(/\s+/g," ").trim();return t===""?0:t.split(" ").filter(Boolean).length}var Om=/\b(loading|please wait|just a moment|redirecting)\b[\s.…]*/i;function Lm(e){let t=zl(e),n=Yl(e),r=_n(e).replace(Si," ").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim(),o=t<Bl&&Om.test(r),i=t<Bl&&n===0;return o||i}function Nm(e,t,n=200,r=null){let o=Cm(t),i=Array.from(new Set(o.flatMap(l=>l.types))),s=Em(t),a=Im(t);return{url:e,status:n,fetched:!0,title:$m(t),metaDescription:Sm(t),h1s:Rm(t),canonical:s,canonicalServerRendered:s===null?null:!0,jsonLd:o,jsonLdTypes:i,openGraph:Am(t),twitter:Pm(t),wordCount:zl(t),clientRenderedShell:Lm(t),bodyLinkCount:Yl(t),robotsNoindex:Et(t)||_m(r),robotsNoindexMeta:Et(t),imgCount:a.imgCount,imgsMissingAlt:a.missingAlt,imgsMissingAltSrcs:a.missingAltSrcs,failureReason:null}}function Jl(e,t=null){return{url:e,status:null,fetched:!1,title:null,metaDescription:null,h1s:[],canonical:null,canonicalServerRendered:null,jsonLd:[],jsonLdTypes:[],openGraph:{},twitter:{},wordCount:0,clientRenderedShell:!1,bodyLinkCount:0,robotsNoindex:!1,robotsNoindexMeta:!1,imgCount:0,imgsMissingAlt:0,imgsMissingAltSrcs:[],failureReason:t}}function Dm(e){return typeof e=="function"?{fetchImpl:e}:e??{}}function jm(e){if(e instanceof Error){let t=e.cause,n=t?.code??(t?.message&&t.message!==e.message?t.message:null);return`network error: ${e.message}${n?` (${n})`:""}`}return`network error: ${String(e)}`}async function jr(e,t){let n=Dm(t),r=Jl(e);try{let o=await F(e,{headers:{"user-agent":"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) SEOAgent-CLI"},redirect:"follow"},{attempts:n.attempts??3,timeoutMs:n.timeoutMs??1e4,fetchImpl:n.fetchImpl});if(!o.ok){let a=vi.has(o.status)?_i(await Fm(o),o.status):null;return a?{evidence:Hl(r,o.status,a),html:null}:{evidence:{...r,status:o.status,failureReason:`HTTP ${o.status}`},html:null}}let i=await o.text(),s=_i(i,o.status);return s?{evidence:Hl(r,o.status,s),html:null}:{evidence:Nm(e,i,o.status,o.headers?.get?.("x-robots-tag")??null),html:i}}catch(o){return{evidence:{...r,failureReason:jm(o)},html:null}}}async function Fm(e){try{return await e.text()}catch{return""}}function Hl(e,t,n){return{...e,status:t,failureReason:Dl(n),blockedBy:n}}async function Xl(e,t){return(await jr(e,t)).evidence}async function Ei(e,t={}){let n=Math.max(1,t.concurrency??5),r=new Array(e.length),o=0;async function i(){for(;;){let s=o++;if(s>=e.length)return;if(t.deadlineMs!==void 0&&Date.now()>=t.deadlineMs){r[s]=Jl(e[s],"crawl time budget exhausted before this page could be fetched");continue}let{evidence:a,html:l}=await jr(e[s],{attempts:t.attempts,timeoutMs:t.timeoutMs,fetchImpl:t.fetchImpl});r[s]=a,l!==null&&t.onHtml?.(e[s],l)}}return await Promise.all(Array.from({length:Math.min(n,e.length)},()=>i())),r}function Mm(e){let t=[],n=[],r=null,o=!1;for(let i of e.split(/\r?\n/)){let s=i.replace(/#.*$/,"").trim();if(!s)continue;let a=s.indexOf(":");if(a===-1)continue;let l=s.slice(0,a).trim().toLowerCase(),c=s.slice(a+1).trim();if(l==="user-agent"){(!r||!o)&&(r={userAgents:[],disallow:[],allow:[]},t.push(r)),r.userAgents.push(c.toLowerCase()),o=!0;continue}if(o=!1,l==="sitemap"){c&&n.push(c);continue}r||(r={userAgents:["*"],disallow:[],allow:[]},t.push(r)),l==="disallow"?r.disallow.push(c):l==="allow"&&r.allow.push(c)}return{groups:t,sitemaps:n}}function Gl(e,t){if(e==="")return!1;let n=e.endsWith("$"),o=(n?e.slice(0,-1):e).replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${o}${n?"$":""}`).test(t)}function Fr(e,t,n="*"){if(!e.fetched)return!1;let r;try{let c=new URL(t);r=`${c.pathname}${c.search}`}catch{r=t}let o=n.toLowerCase(),i=e.groups.filter(c=>c.userAgents.includes(o)),s=i.length>0?i:e.groups.filter(c=>c.userAgents.includes("*")),a=-1,l=-1;for(let c of s){for(let u of c.allow)Gl(u,r)&&(a=Math.max(a,u.length));for(let u of c.disallow)Gl(u,r)&&(l=Math.max(l,u.length))}return l>a}function Ql(e){let t=e.trim().replace(/\/+$/,"");return/^https?:\/\//i.test(t)?t:`https://${t}`}async function Zl(e,t){let n=`${Ql(e)}/robots.txt`,r={fetched:!1,status:null,raw:"",groups:[],sitemaps:[]};try{let o=await F(n,{headers:{"user-agent":"SEOAgent-CLI/robots-check"}},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!o.ok)return{...r,status:o.status};let i=await o.text();return/^\s*</.test(i)?{...r,status:o.status,raw:""}:{fetched:!0,status:o.status,raw:i,...Mm(i)}}catch{return r}}var Um=50,Bm=5;function Ci(e){return/<sitemapindex[\s>]/i.test(e)}function Wl(e){try{return/\.xml(\.gz)?$/i.test(new URL(e).pathname)}catch{return/\.xml(\.gz)?(\?.*)?$/i.test(e)}}function Hm(e,t){try{let n=r=>r.toLowerCase().replace(/^www\./,"");return n(new URL(e).hostname)===n(new URL(t).hostname)}catch{return!1}}var Gm=/\/(blog|posts?|articles?|news)\//i;function Kl(e){return e.filter(t=>Gm.test(t)).length}async function ec(e,t){let n=`${Ql(e)}/sitemap.xml`,r={fetched:!1,status:null,urls:[],count:0,blogUrlCount:0};try{let o=await F(n,{headers:{"user-agent":"SEOAgent-CLI/sitemap-facts"}},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!o.ok)return{...r,status:o.status};let i=await o.text();if(!/<urlset|<sitemapindex/i.test(i))return{...r,status:o.status};let s=Ae(i);if(!Ci(i)){let y=ql(s.filter(m=>!Wl(m)));return{fetched:!0,status:o.status,urls:y,count:y.length,blogUrlCount:Kl(y)}}let a=s.filter(y=>Hm(y,n)).slice(0,Um),l=[],c=[],u=0,p=0,g=async()=>{for(;p<a.length;){let y=a[p++];try{let m=await F(y,{headers:{"user-agent":"SEOAgent-CLI/sitemap-facts"}},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!m.ok){l.push(y);continue}let w=await m.text();if(!/<urlset|<sitemapindex/i.test(w)){l.push(y);continue}u++;for(let k of Ae(w))Wl(k)||c.push(k)}catch{l.push(y)}}};await Promise.all(Array.from({length:Math.min(Bm,a.length)},()=>g()));let f=ql(c);return{fetched:!0,status:o.status,urls:f,count:f.length,blogUrlCount:Kl(f),index:{children:s.length,expanded:u,unreachable:l}}}catch{return r}}function ql(e){return[...new Set(e)]}var rc=["tsx","jsx","js","mdx","md"],Vm=["astro","md","mdx"],Ym=5e3,zm=2e3,Jm=10;function Ue(e,t){let n=new Map,r=0,o=(l,c,u=!1)=>{let p=ac(l);if(p===null){r++;return}let g=n.get(p);if(g){g.in_sitemap=g.in_sitemap||u,g.source.includes(c)||(g.source+=`, ${c}`);return}n.set(p,{route:p,url:cc(t,p),in_sitemap:u,source:c})};for(let l of Ur(e))rh(l,o);let i=Xm(e,t),s=l=>i.some(c=>c.test(l)),a=[...n.values()].filter(l=>!Me(l.route));return{pages:a.filter(l=>!s(l.route)).sort((l,c)=>l.route.localeCompare(c.route)),dynamicCount:r,offOriginCount:a.filter(l=>s(l.route)).length}}function Xm(e,t){let n=tc(t);if(!n)return[];let r=[];for(let o of Ur(e)){let i;try{i=JSON.parse(Mr(me(o,"vercel.json"),"utf-8"))}catch{continue}if(Array.isArray(i.redirects))for(let s of i.redirects){if(!s||typeof s.source!="string"||typeof s.destination!="string")continue;let a=tc(s.destination);if(!a||oc(a,n)||!Qm(s,n))continue;let l=Zm(s.source);l&&r.push(l)}}return r}function tc(e){if(!e)return null;let t=e.trim();if(!t||t.startsWith("/"))return null;try{return new URL(/^https?:\/\//i.test(t)?t:`https://${t}`).hostname.toLowerCase()}catch{return null}}function oc(e,t){let n=r=>r.replace(/^www\./,"");return n(e)===n(t)}function Qm(e,t){if(Array.isArray(e.missing)&&e.missing.length>0)return!1;let n=e.has;return!Array.isArray(n)||n.length===0?!0:n.every(r=>r&&r.type==="host"&&typeof r.value=="string"&&oc(r.value.toLowerCase(),t))}function Zm(e){if(!e.startsWith("/")||/[(){}[\]?+*]/.test(e.replace(/:[A-Za-z0-9_]+(?:\([^)]*\))?[*+?]?/g,"")))return null;let t="",n=0;for(;n<e.length;){let r=e[n];if(r!==":"){t+=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n++;continue}let o=/^:([A-Za-z0-9_]+)(\(([^)]*)\))?([*+?])?/.exec(e.slice(n));if(!o)return null;let[,,,i,s]=o;i!==void 0?t+=`(?:${i})`:s==="*"?t+=".*":s==="+"?t+=".+":s==="?"?t+="[^/]*":t+="[^/]+",n+=o[0].length}try{return new RegExp(`^${t}$`,"i")}catch{return null}}async function ic(e,t,n){let r={checked:!1,liveCount:0,flipped:0,added:0},o=await eh(t,n);if(o.length===0)return r;let i=new Set(o.map(L)),s=0;for(let c of e)!c.in_sitemap&&i.has(L(c.url||c.route))&&(c.in_sitemap=!0,s++,c.source.includes("live-sitemap")||(c.source+=", live-sitemap"));let a=new Set(e.map(c=>L(c.url||c.route))),l=0;for(let c of o){if(l>=zm)break;let u=nh(c,t);u===null||a.has(u)||(a.add(u),e.push({route:u,url:cc(t,u),in_sitemap:!0,source:"live-sitemap"}),l++)}return l>0&&e.sort((c,u)=>c.route.localeCompare(u.route)),{checked:!0,liveCount:o.length,flipped:s,added:l}}async function eh(e,t){let n=async l=>{try{let c=await F(l,{headers:{"user-agent":"SEOAgent-CLI/sitemap-check"}},{attempts:1,timeoutMs:5e3,fetchImpl:t});return{status:c.status,xml:c.ok?await c.text():""}}catch{return null}},r=vn(e),o=await n(r);if(o?.status===404&&(o=await n(r.replace(/\/sitemap\.xml$/,"/sitemap-index.xml"))),!o||!o.xml)return[];let i=Ae(o.xml);if(!Ci(o.xml))return i;let s=i.filter(l=>sc(l,e)).slice(0,Jm);return(await Promise.all(s.map(l=>n(l)))).flatMap(l=>l?.xml?Ae(l.xml):[])}function th(e){return e.replace(/^https?:\/\//,"").replace(/\/.*$/,"").toLowerCase().replace(/^www\./,"")}function sc(e,t){let n;try{n=new URL(e)}catch{return!1}return n.protocol!=="https:"&&n.protocol!=="http:"?!1:n.hostname.toLowerCase().replace(/^www\./,"")===th(t)}function nh(e,t){if(!sc(e,t))return null;let n=L(e);return/\.xml$/i.test(n)||Ml(n)?null:ac(n)}function rh(e,t){for(let n of["app",me("src","app")]){let r=me(e,n);if($n(r))for(let o of Ai(r)){let i=Pi(r,o),s=i[i.length-1];uh(s)&&(i.some(a=>a.startsWith("@"))||t(sh(i.slice(0,-1)),"app router"))}}for(let n of["pages",me("src","pages")]){let r=me(e,n);if($n(r))for(let o of Ai(r)){let i=Pi(r,o);if(i[0]==="api")continue;let s=i[i.length-1],a=Ii(s),l=rc.includes(a),c=Vm.includes(a);if(!l&&!c)continue;let u=Br(s);dh(u)||t(ah(i),c?"astro":"pages router")}}for(let n of[".","public"]){let r=me(e,n);if($n(r))for(let o of Ai(r,n==="."?1:1/0)){let i=Pi(r,o),s=i[i.length-1];Ii(s)==="html"&&(i.some(a=>a==="node_modules"||a.startsWith("."))||t(lh(i),"static html"))}}for(let n of["public/sitemap.xml","sitemap.xml"]){let r=me(e,...n.split("/"));if(Wm(r)){for(let o of ph(r)){let i=ch(o);i!==null&&t(i,"sitemap.xml",!0)}break}}}function Ur(e){let t=[e],n=new Set([e]);for(let r of oh(e))for(let o of ih(e,r))n.has(o)||(n.add(o),t.push(o));return t}function oh(e){let t=[];try{let n=Mr(me(e,"pnpm-workspace.yaml"),"utf-8"),r=!1;for(let o of n.split(/\r?\n/)){let i=o.replace(/#.*$/,"");if(/^\s*packages\s*:/.test(i)){r=!0;continue}if(r){let s=i.match(/^\s*-\s*['"]?([^'"\s]+)['"]?\s*$/);s?t.push(s[1]):/^\S/.test(i)&&(r=!1)}}}catch{}try{let r=JSON.parse(Mr(me(e,"package.json"),"utf-8")).workspaces,o=Array.isArray(r)?r:Array.isArray(r?.packages)?r.packages:[];for(let i of o??[])typeof i=="string"&&t.push(i)}catch{}return t}function ih(e,t){if(!t||t.startsWith("!"))return[];let n=t.replace(/\/\*\*?$/,"/*"),r=n.indexOf("*");if(r===-1){let a=me(e,...n.split("/").filter(Boolean));return $n(a)?[a]:[]}let o=n.slice(0,r).replace(/\/$/,""),i=me(e,...o.split("/").filter(Boolean));if(!$n(i))return[];let s=[];try{for(let a of nc(i,{withFileTypes:!0}))if(a.isDirectory()&&!a.name.startsWith(".")&&!lc.has(a.name)&&(s.push(me(i,a.name)),s.length>=200))break}catch{}return s}function ac(e){let t=e.trim();return t===""||t==="/"||(t.startsWith("/")||(t=`/${t}`),t=t.replace(/\/+$/,""),t==="")?"/":/\[.*\]/.test(t)?null:t}function sh(e){return"/"+e.filter(n=>!(n.startsWith("(")&&n.endsWith(")"))).join("/")}function ah(e){let t=[...e],n=Br(t[t.length-1]);return n==="index"?t.pop():t[t.length-1]=n,"/"+t.join("/")}function lh(e){let t=[...e],n=Br(t[t.length-1]);return n==="index"?t.pop():t[t.length-1]=n,"/"+t.join("/")}function ch(e){try{return new URL(e).pathname||"/"}catch{return e.startsWith("/")?e:null}}function uh(e){return Br(e)==="page"&&rc.includes(Ii(e))}function dh(e){return["_app","_document","_error","404","500","middleware"].includes(e)}function ph(e){try{let t=Mr(e,"utf-8"),n=[],r=/<loc>\s*([^<\s]+)\s*<\/loc>/gi,o;for(;(o=r.exec(t))!==null;)n.push(o[1].trim());return n}catch{return[]}}var lc=new Set(["node_modules",".git",".next","dist","build",".vercel","out"]);function $n(e){try{return Km(e).isDirectory()}catch{return!1}}function*Ai(e,t=1/0){let n=0;function*r(o,i){if(i>t)return;let s;try{s=nc(o,{withFileTypes:!0})}catch{return}for(let a of s){if(n>=Ym)return;if(a.name.startsWith("."))continue;let l=me(o,a.name);if(a.isDirectory()){if(lc.has(a.name))continue;yield*r(l,i+1)}else a.isFile()&&(n++,yield l)}}yield*r(e,1)}function Pi(e,t){return t.slice(e.length).replace(/^[/\\]+/,"").split(qm).filter(Boolean)}function Ii(e){let t=e.lastIndexOf(".");return t===-1?"":e.slice(t+1).toLowerCase()}function Br(e){let t=e.lastIndexOf(".");return t===-1?e:e.slice(0,t)}function cc(e,t){return e?`https://${e.replace(/^https?:\/\//,"").replace(/\/$/,"")}${t==="/"?"/":t}`:t}import{existsSync as fh,mkdirSync as gh,readFileSync as mh,writeFileSync as hh}from"fs";import{join as Ti}from"path";var Sn="pages.md",Hr="pages-discovered.md";function yh(e){return tt(Ti(e,x,Sn))?.data?.generated===!0}function wh(e){let t=yh(e);return{rel:t?Hr:Sn,cloudOwned:t}}function uc(e,t){let n=!1,r=t.status!==null?String(t.status):"\u2014";e.status!==r&&(e.status=r,n=!0),e.rendered!==t.rendered&&(e.rendered=t.rendered,n=!0);let o=t.rendered==="error"?"\u2014":String(t.wordCount);return e.word_count!==o&&(e.word_count=o,n=!0),n}function Gr(e,t,n){let r=wh(e),o=Ti(e,x,r.rel),i=fh(o),s=i?Wr(o):new Map;if(t.length===0&&!i)return{wrote:!1,added:0,total:0,merged:!1,file:r.rel};let a=new Map(s),l=0,c=!1;for(let p of t){let g=pc(p.url),f=n?.get(p.url),y=a.get(g);if(y)p.in_sitemap&&y.in_sitemap!=="yes"&&(y.in_sitemap="yes",c=!0),f&&uc(y,f)&&(c=!0);else{let m={url:g,in_sitemap:p.in_sitemap?"yes":"no",in_nav:"\u2014",status:"\u2014",rendered:"\u2014",word_count:"\u2014",notes:pc(p.source)};f&&uc(m,f),a.set(g,m),l++,c=!0}}if(i&&!c)return{wrote:!1,added:0,total:a.size,merged:!0,file:r.rel};let u=[...a.values()];return gh(Ti(e,x),{recursive:!0}),hh(o,bh(u,r.cloudOwned),"utf-8"),{wrote:!0,added:l,total:u.length,merged:i,file:r.rel}}function bh(e,t){let n=["---","generated: false",`discovered_at: ${new Date().toISOString()}`,`row_count: ${e.length}`,"---"].join(`
54
+ `;function Ce(e){let t=bi(e,".seoagent",ki);if(!wi(t))return null;let n=vl(t,"utf-8");return yi(n)}function _l(e,t){let n=bi(e,".seoagent",ki);return wi(n)?!1:(Qg(n,Zg+xl({business:{type:t||""},writingInstructions:[],referenceUrls:[],facts:[],topicsToAvoid:[],contentTone:null,additionalNotes:null}),"utf-8"),!0)}function Bt(e){let t=bi(e,".seoagent",ki);if(!wi(t))return!0;try{return Fe(vl(t,"utf-8"))}catch{return!1}}import{existsSync as kn,readFileSync as $l,readdirSync as em,statSync as Sl}from"fs";import{join as _t}from"path";var tm=[{cms:"strapi",deps:["strapi","@strapi/strapi","@strapi/"],envKeys:["STRAPI_URL","STRAPI_API_URL","NEXT_PUBLIC_STRAPI_URL","STRAPI_API_TOKEN"],fsMarkers:["strapi/","apps/strapi/","packages/strapi/","cms/"]},{cms:"wordpress",deps:["wpapi","wp-graphql","@wordpress/api-fetch","@wordpress/"],envKeys:["WORDPRESS_API_URL","WP_API_URL","NEXT_PUBLIC_WORDPRESS_URL"],fsMarkers:[]},{cms:"sanity",deps:["@sanity/client","next-sanity","sanity"],envKeys:["SANITY_PROJECT_ID","NEXT_PUBLIC_SANITY_PROJECT_ID","SANITY_API_TOKEN"],fsMarkers:["sanity/","studio/","sanity.config.ts","sanity.config.js"]},{cms:"contentful",deps:["contentful","@contentful/rich-text-react-renderer","@contentful/"],envKeys:["CONTENTFUL_SPACE_ID","CONTENTFUL_ACCESS_TOKEN","NEXT_PUBLIC_CONTENTFUL_SPACE_ID"],fsMarkers:[]},{cms:"ghost",deps:["@tryghost/content-api","@tryghost/"],envKeys:["GHOST_URL","GHOST_API_KEY","NEXT_PUBLIC_GHOST_URL"],fsMarkers:[]},{cms:"webflow",deps:["webflow-api"],envKeys:["WEBFLOW_API_TOKEN","WEBFLOW_SITE_ID"],fsMarkers:[]},{cms:"shopify",deps:["@shopify/hydrogen","@shopify/storefront-api-client","@shopify/shopify-api","@shopify/"],envKeys:["SHOPIFY_STOREFRONT_TOKEN","SHOPIFY_STORE_DOMAIN","SHOPIFY_ADMIN_API_TOKEN"],fsMarkers:["shopify.config.ts","shopify.config.js"]},{cms:"payload",deps:["payload","@payloadcms/next","@payloadcms/"],envKeys:["PAYLOAD_SECRET","PAYLOAD_PUBLIC_SERVER_URL"],fsMarkers:["payload.config.ts","payload.config.js"]},{cms:"directus",deps:["@directus/sdk","directus"],envKeys:["DIRECTUS_URL","DIRECTUS_TOKEN"],fsMarkers:[]}];function nm(e){let t=_t(e,"package.json");if(!kn(t))return{deps:{},source:"package.json"};try{let n=JSON.parse($l(t,"utf-8"));return{deps:{...n.dependencies,...n.devDependencies,...n.peerDependencies},source:"package.json"}}catch{return{deps:{},source:"package.json"}}}function rm(e,t){for(let n of t)if(n.endsWith("/")){if(e.startsWith(n))return!0}else if(e===n)return!0;return!1}function om(e){let t={};for(let n of Dt){let r=_t(e,n);if(kn(r))try{let o=$l(r,"utf-8");for(let i of o.split(/\r?\n/)){let s=i.trim();if(!s||s.startsWith("#"))continue;let a=s.indexOf("=");if(a===-1)continue;let l=s.slice(0,a).trim();l&&!(l in t)&&(t[l]=n)}}catch{}}return t}function im(e,t){let n=_t(e,t.replace(/\/$/,""));if(!kn(n))return!1;if(t.endsWith("/"))try{return Sl(n).isDirectory()}catch{return!1}return!0}function sm(e){let t=["content","_posts","posts",_t("src","content")];for(let n of t){let r=_t(e,n);if(kn(r))try{if(!Sl(r).isDirectory())continue;let o=[r],i=0;for(;o.length>0&&i<50;){let s=o.pop();for(let a of em(s,{withFileTypes:!0}))if(i++,!a.name.startsWith(".")){if(a.isDirectory()&&o.length<5){o.push(_t(s,a.name));continue}if(a.isFile()&&/\.(md|mdx)$/i.test(a.name))return{type:"directory",detail:n,source:`${n}/${a.name}`}}}}catch{}}return null}function am(e){let t=[{marker:"app/blog/page.tsx",path:"/blog"},{marker:"app/blog/page.jsx",path:"/blog"},{marker:"app/blog/page.js",path:"/blog"},{marker:"src/app/blog/page.tsx",path:"/blog"},{marker:"src/app/blog/page.jsx",path:"/blog"},{marker:"pages/blog/index.tsx",path:"/blog"},{marker:"pages/blog/index.jsx",path:"/blog"},{marker:"pages/blog/index.js",path:"/blog"},{marker:"src/pages/blog/index.tsx",path:"/blog"},{marker:"app/(blog)/page.tsx",path:"/blog"},{marker:"app/articles/page.tsx",path:"/articles"},{marker:"pages/articles/index.tsx",path:"/articles"},{marker:"app/posts/page.tsx",path:"/posts"},{marker:"pages/posts/index.tsx",path:"/posts"},{marker:"app/learn/page.tsx",path:"/learn"},{marker:"app/resources/page.tsx",path:"/resources"}],n=[""],r=ni(e);r&&n.push(r);for(let o of n)for(let i of t){let s=o?`${o}/${i.marker}`:i.marker;if(kn(_t(e,s)))return i.path}return null}function Rl(e){let t=[],{deps:n}=nm(e),r=om(e),o="none";for(let s of tm){let a=[];for(let l of Object.keys(n))if(rm(l,s.deps)){a.push({type:"dep",detail:l,source:"package.json"});break}for(let l of s.envKeys)if(r[l]){a.push({type:"env",detail:l,source:r[l]});break}for(let l of s.fsMarkers)if(im(e,l)){let c=l.endsWith("/")?"directory":"file";a.push({type:c,detail:l,source:l});break}if(a.length>0){o=s.cms,t.push(...a);break}}if(o==="none"){let s=sm(e);s&&(o="mdx-local",t.push(s))}let i=am(e);return{cms:o,blog_path:i,evidence:t}}import{existsSync as lm,readFileSync as cm}from"fs";import{join as um}from"path";var El=["openai","fal","replicate"],Ht={openai:["OPENAI_API_KEY"],fal:["FAL_KEY","FAL_API_KEY"],replicate:["REPLICATE_API_TOKEN","REPLICATE_API_KEY"]};function dm(e){let t={};if(!lm(e))return t;let n=cm(e,"utf-8");for(let r of n.split(/\r?\n/)){let o=r.trim();if(!o||o.startsWith("#"))continue;let i=o.indexOf("=");if(i===-1)continue;let s=o.slice(0,i).trim(),a=o.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),t[s]=a}return t}function Cl(e,t){let n={};for(let r of t){let o=process.env[r];o&&o.trim().length>0&&(n[r]={value:o,source:"process"})}for(let r of Dt){let o=um(e,r),i=dm(o);for(let s of t){if(n[s])continue;let a=i[s];a&&a.length>0&&(n[s]={value:a,source:r})}}return{found:n}}function st(e){let t=[].concat(...El.map(a=>Ht[a])),n=Cl(e,t),r=[];for(let a of El)Ht[a].some(l=>n.found[l])&&r.push(a);if(r.length===0)return{provider:"none",matched_key:null,source:null,available_providers:[]};let o=r[0],i=Ht[o].find(a=>n.found[a])??null,s=i?n.found[i].source:null;return{provider:o,matched_key:i,source:s,available_providers:r}}function Al(e,t){let n=Cl(e,Ht[t]);for(let r of Ht[t])if(n.found[r])return{key:n.found[r].value,envName:r};return null}function Pl(){return Ht}import{existsSync as $t,readFileSync as xi}from"fs";import{join as St}from"path";function Il(e){try{return new URL(e).hostname}catch{return e}}function Tl(e){let t=e.toLowerCase();return!!(t==="github.com"||t.endsWith(".github.com")||t==="gitlab.com"||t.endsWith(".gitlab.com")||t==="bitbucket.org"||t.endsWith(".bitbucket.org")||t==="dev.azure.com"||t==="visualstudio.com"||t.endsWith(".visualstudio.com")||t==="npmjs.com"||t.endsWith(".npmjs.com"))}function Ol(e){let t=e.trim().toLowerCase().replace(/^\[([^\]]+)\](?::\d{1,5})?$/,"$1").replace(/^((?:\d{1,3}\.){3}\d{1,3}|localhost|[a-z0-9.-]*\.localhost)(?::\d{1,5})?$/,"$1");return t==="localhost"||t.endsWith(".localhost")||t==="::1"||t==="0.0.0.0"?!0:/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t)}function pm(e){for(let t of Dt){let n=St(e,t);if(!$t(n))continue;let r=xi(n,"utf-8");for(let o of Aa){let i=r.match(new RegExp(`^${o}=(.+)$`,"m"));if(i){let s=i[1].trim().replace(/^["']|["']$/g,""),a=Il(s);if(Tl(a)||Ol(a))continue;return{value:a,source:`${t} (${o})`}}}}return null}function fm(e){let t=St(e,"package.json");if(!$t(t))return null;try{let n=JSON.parse(xi(t,"utf-8"));if(!n.homepage)return null;let r=Il(n.homepage);return Tl(r)||Ol(r)?null:{value:r,source:"package.json (homepage)"}}catch{return null}}function Ll(e,t){let n=[];t?.("Checking for monorepo / workspace layout\u2026"),$t(St(e,"pnpm-workspace.yaml"))&&n.push({field:"context",detail:"Monorepo workspace detected",source:"pnpm-workspace.yaml \u2014 using this directory for project signals"});let r=null;t?.("Scanning .env files for public / site URLs\u2026");let o=pm(e);if(o)r=o.value,n.push({field:"domain",detail:o.value,source:o.source});else{t?.("Reading package.json homepage (skipping GitHub/GitLab repo URLs)\u2026");let a=fm(e);a&&(r=a.value,n.push({field:"domain",detail:a.value,source:a.source}))}let i=St(e,"package.json"),s=null;if($t(i))try{t?.("Reading dependencies to infer site type\u2026");let a=JSON.parse(xi(i,"utf-8")),l=Object.keys({...a.dependencies,...a.devDependencies}),c=(...u)=>u.some(p=>l.includes(p));if(c("@shopify/hydrogen","@shopify/polaris")||$t(St(e,"shopify.config.js"))||$t(St(e,"shopify.config.ts"))){s="product";let u=c("@shopify/hydrogen","@shopify/polaris")?"Shopify-related dependencies in package.json":$t(St(e,"shopify.config.ts"))?"shopify.config.ts":"shopify.config.js";n.push({field:"site_type",detail:"product",source:u})}else{let u=c("stripe","@stripe/stripe-js","@stripe/react-stripe-js","paddle","@paddle/paddle-js"),p=c("next-auth","@auth/core","lucia","clerk","@clerk/nextjs","@clerk/clerk-react"),g=c("next");u&&(g||p)?(s="saas",n.push({field:"site_type",detail:"saas",source:g?"payment SDK + Next.js in package.json":"payment SDK + auth library in package.json"})):!u&&c("astro","gatsby","contentlayer","next-mdx-remote","mdx-bundler","vitepress","vuepress","@docusaurus/core","docusaurus","nextra")&&(s="content",n.push({field:"site_type",detail:"content",source:c("vitepress","vuepress","@docusaurus/core","docusaurus","nextra")?"documentation / site generator in package.json (VitePress, Docusaurus, Nextra, etc.)":"content-oriented dependencies in package.json (no payment SDKs detected)"}))}}catch{}return{domain:r,siteType:s,evidence:n}}import{existsSync as Wm,readFileSync as Mr,readdirSync as nc,statSync as Km}from"fs";import{join as me,sep as qm}from"path";var gm=/^\/(?:cdn-cgi|wp-json|wp-admin|wp-includes|wp-content\/(?:plugins|themes|uploads)|\.well-known|xmlrpc\.php|wp-login\.php|wp-cron\.php|feed|comments\/feed)(?:\/|$)/i;function Dr(e){let t=e;if(/^https?:\/\//i.test(e))try{t=new URL(e).pathname}catch{return!1}return gm.test(t)}var vi=new Set([202,403,429,503]),Nl="bot challenge",mm=[[/\/\.well-known\/sgcaptcha\//i,"SiteGround"],[/\/cdn-cgi\/challenge-platform\/|cf-chl-|cf_chl_opt|<title>\s*Just a moment\.{0,3}\s*<\/title>/i,"Cloudflare"],[/Vercel Security Checkpoint/i,"Vercel"],[/_Incapsula_Resource|incapsula/i,"Imperva"],[/captcha-delivery\.com|datadome/i,"DataDome"],[/px-captcha|_pxhd|perimeterx/i,"PerimeterX"],[/awswaf|aws-waf-token/i,"AWS WAF"]];function _i(e,t){if(!e)return null;let n=e.slice(0,2e4);for(let[r,o]of mm)if(r.test(n))return o;return t!=null&&vi.has(t)&&/captcha|challenge/i.test(n)&&n.replace(/<script[\s\S]*?<\/script>|<style[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").trim().split(/\s+/).filter(Boolean).length<120?"bot protection":null}function Dl(e){return`${Nl} (${e})`}function xn(e){return typeof e=="string"&&e.startsWith(Nl)}var Fl=[/^\/admin(\/|$)/i,/^\/(o)?auth(\/|$)/i,/^\/account(s)?(\/|$)/i,/^\/dashboard(\/|$)/i,/^\/settings(\/|$)/i,/^\/login(\/|$)/i,/^\/logout(\/|$)/i,/^\/sign[-_]?in(\/|$)/i,/^\/sign[-_]?up(\/|$)/i,/^\/register(\/|$)/i,/^\/reset[-_]?password(\/|$)/i,/^\/verify(\/|$)/i,/^\/api(\/|$)/i,/^\/_next(\/|$)/i,/^\/checkout(\/|$)/i,/^\/cart(\/|$)/i],hm=[/^\/[a-z0-9]+-(?:onboarding|login|logout|signin|sign-in|signup|sign-up|dashboard|checkout|account)$/i];function Ae(e){let t=[],n=/<loc>\s*([^<\s][^<]*?)\s*<\/loc>/gi,r;for(;(r=n.exec(e))!==null;){let o=r[1].replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&#39;/g,"'").replace(/&quot;/g,'"').trim();o&&t.push(o)}return t}function ym(e){let t=[],n=/<lastmod>\s*([^<\s][^<]*?)\s*<\/lastmod>/gi,r;for(;(r=n.exec(e))!==null;)t.push(r[1].trim());return t}var wm=10,jl=.9;function bm(e,t){if(t<wm||e.length<t*jl)return null;let n=new Map;for(let r of e)n.set(r,(n.get(r)||0)+1);for(let[r,o]of n)if(o>=t*jl)return r;return null}function L(e){let t=e;try{t=new URL(e).pathname}catch{let n=t.indexOf("#");n!==-1&&(t=t.slice(0,n));let r=t.indexOf("?");r!==-1&&(t=t.slice(0,r))}return t.length>1&&t.endsWith("/")&&(t=t.slice(0,-1)),t||"/"}function Me(e){return Fl.some(t=>t.test(e))||hm.some(t=>t.test(e))}function Ml(e){return Fl.some(t=>t.test(e))}function km(e){return e.filter(t=>Me(L(t)))}function xm(e,t){let n=new Set(e.map(L)),r=[],o=new Set;for(let i of t){let s=L(i);Me(s)||n.has(s)||o.has(s)||(o.add(s),r.push(s))}return r}function vn(e){return`https://${e.replace(/^https?:\/\//,"").replace(/\/+$/,"")}/sitemap.xml`}async function Ul(e){let t=e.sitemapUrl||vn(e.domain),n=[],r={ok:!1,sitemapUrl:t,fetched:!1,status:null,urls:[],privateUrls:[],missing:[],hasLastmod:!1,lastmods:[],uniformLastmod:null,issues:n},o="";try{let i=await F(t,{headers:{"user-agent":"SEOAgent-CLI/sitemap-check"}},{attempts:2,timeoutMs:1e4,fetchImpl:e.fetchImpl});if(r.status=i.status,r.fetched=!0,!i.ok)return n.push({level:"error",message:`Sitemap returned HTTP ${i.status} \u2014 Google can't fetch it. Make sure ${t} serves 200.`}),r;o=await i.text()}catch(i){return n.push({level:"error",message:`Could not reach ${t} (${i instanceof Error?i.message:String(i)}). If the site isn't deployed yet, that's expected.`}),r}return/<urlset|<sitemapindex/i.test(o)?(r.urls=Ae(o),r.lastmods=ym(o),r.hasLastmod=r.lastmods.length>0,r.urls.length===0?(n.push({level:"error",message:"Sitemap is valid XML but contains zero <loc> URLs."}),r):(/<sitemapindex/i.test(o)&&n.push({level:"info",message:`Sitemap index with ${r.urls.length} child sitemap(s). Child URLs are not expanded by this check.`}),r.privateUrls=km(r.urls),r.privateUrls.length>0&&n.push({level:"warning",message:`${r.privateUrls.length} private/noindex URL(s) leaked into the sitemap (e.g. ${r.privateUrls.slice(0,3).map(L).join(", ")}). Remove auth/admin/api routes from the generator.`}),r.uniformLastmod=bm(r.lastmods,r.urls.length),r.uniformLastmod?n.push({level:"warning",message:`Every URL carries the same <lastmod> (${r.uniformLastmod}) \u2014 that is the sitemap's own build time, not a content date. Google discounts <lastmod> for the WHOLE sitemap when it looks generated, including pages whose dates are real. Emit a per-page date where you have one and omit <lastmod> everywhere else.`}):r.hasLastmod||n.push({level:"info",message:"No <lastmod> dates. That is fine \u2014 omitting them is honest. Add a per-page date only where you have a real one (CMS updatedAt, file mtime); a single bulk date on every URL is worse than none."}),e.knownUrls&&e.knownUrls.length>0&&(r.missing=xm(r.urls,e.knownUrls),r.missing.length>0&&n.push({level:"warning",message:`${r.missing.length} public page(s) in the repo are missing from the sitemap (e.g. ${r.missing.slice(0,3).join(", ")}). Add them to the generator so Google can find them.`})),r.ok=!n.some(i=>i.level==="error"),r)):(n.push({level:"error",message:`Response is not a valid XML sitemap (no <urlset>/<sitemapindex>). Got ${o.length} bytes.`}),r)}var Si=/<(script|style|noscript|template|svg|nav|header|footer)\b[^>]*>[\s\S]*?<\/\1>/gi,Bl=30;function _n(e){let t=/<body\b[^>]*>([\s\S]*?)<\/body>/i.exec(e);return t?t[1]:e}var vm={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:" "};function Rt(e){return e.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z]+);/gi,(t,n)=>{if(n[0]!=="#")return vm[n.toLowerCase()]??t;let r=n[1]==="x"||n[1]==="X",o=Number.parseInt(n.slice(r?2:1),r?16:10);return o>0&&o<=1114111?String.fromCodePoint(o):t})}function et(e,t){let n=new RegExp(`\\b${t}\\s*=\\s*"([^"]*)"`,"i").exec(e);if(n)return Rt(n[1]).trim();let r=new RegExp(`\\b${t}\\s*=\\s*'([^']*)'`,"i").exec(e);if(r)return Rt(r[1]).trim();let o=new RegExp(`\\b${t}\\s*=\\s*([^\\s>]+)`,"i").exec(e);return o?Rt(o[1]).trim():null}function Et(e){return e?(e.match(/<meta\b[^>]*>/gi)??[]).some(n=>/\bname\s*=\s*["']?\s*(robots|googlebot)\b/i.test(n)&&/\bnoindex\b/i.test(n)):!1}function _m(e){return typeof e=="string"&&/\bnoindex\b/i.test(e)}function $m(e){let t=/<title\b[^>]*>([\s\S]*?)<\/title>/i.exec(e);return t&&Rt(t[1].replace(/\s+/g," ")).trim()||null}function Sm(e){let t=e.match(/<meta\b[^>]*>/gi)??[];for(let n of t){let r=et(n,"name");if(r&&r.toLowerCase()==="description"){let o=et(n,"content");return o&&o.trim()?o.trim():null}}return null}function Rm(e){let t=_n(e),n=[],r=/<h1\b[^>]*>([\s\S]*?)<\/h1>/gi,o;for(;(o=r.exec(t))!==null;){let i=Rt(o[1].replace(/<[^>]+>/g," ").replace(/\s+/g," ")).trim();i&&n.push(i)}return n}function Em(e){let t=e.match(/<link\b[^>]*>/gi)??[];for(let n of t){let r=et(n,"rel");if(r&&r.toLowerCase().split(/\s+/).includes("canonical")){let o=et(n,"href");return o&&o.trim()?o.trim():null}}return null}function Cm(e){let t=[],n=/<script\b[^>]*type\s*=\s*['"]application\/ld\+json['"][^>]*>([\s\S]*?)<\/script>/gi,r;for(;(r=n.exec(e))!==null;){let o=r[1].trim();if(o)try{let i=JSON.parse(o);t.push({types:$i(i),valid:!0})}catch{let i=Array.from(o.matchAll(/"@type"\s*:\s*"([^"]+)"/g)).map(s=>s[1]);t.push({types:i,valid:!1})}}return t}function $i(e,t=[]){if(Array.isArray(e)){for(let n of e)$i(n,t);return t}if(e&&typeof e=="object"){let n=e,r=n["@type"];if(typeof r=="string")t.push(r);else if(Array.isArray(r))for(let o of r)typeof o=="string"&&t.push(o);Array.isArray(n["@graph"])&&$i(n["@graph"],t)}return t}function Vl(e,t){let n={},r=e.match(/<meta\b[^>]*>/gi)??[];for(let o of r){let i=(et(o,"property")||et(o,"name")||"").toLowerCase();if(i.startsWith(t)){let s=et(o,"content");s!==null&&(n[i.slice(t.length)]=s)}}return n}function Am(e){return Vl(e,"og:")}function Pm(e){return Vl(e,"twitter:")}function Im(e,t=5){let r=_n(e).match(/<img\b[^>]*>/gi)??[],o=0,i=[];for(let s of r)if(!/\salt(?=[\s=/>])/i.test(s)&&(o++,i.length<t)){let l=et(s,"src");l&&i.push(l)}return{imgCount:r.length,missingAlt:o,missingAltSrcs:i}}var Tm=/\.(png|jpe?g|gif|svg|webp|avif|ico|css|js|mjs|json|pdf|zip|gz|mp4|webm|mp3|woff2?|ttf|xml|txt)$/i;function Ri(e,t,n=100){let r;try{r=new URL(t).origin}catch{return[]}let o=[],i=new Set,s=e.match(/<a\b[^>]*>/gi)??[];for(let a of s){if(o.length>=n)break;let l=et(a,"href");if(!l||l.startsWith("#")||/^(mailto:|tel:|javascript:|data:)/i.test(l))continue;let c;try{c=new URL(l,t)}catch{continue}if(c.origin!==r||Tm.test(c.pathname)||Dr(c.pathname)||Me(c.pathname)||/^\/cdn-cgi(\/|$)/i.test(c.pathname))continue;c.hash="";let u=c.pathname==="/"?`${c.origin}/${c.search}`:`${c.origin}${c.pathname.replace(/\/+$/,"")}${c.search}`;i.has(u)||(i.add(u),o.push(u))}return o}function Yl(e){return(_n(e).replace(Si," ").match(/<a\b[^>]*\bhref\s*=/gi)??[]).length}function zl(e){let t=_n(e).replace(Si," ").replace(/<!--[\s\S]*?-->/g," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/gi," ").replace(/&[a-z]+;/gi," ").replace(/\s+/g," ").trim();return t===""?0:t.split(" ").filter(Boolean).length}var Om=/\b(loading|please wait|just a moment|redirecting)\b[\s.…]*/i;function Lm(e){let t=zl(e),n=Yl(e),r=_n(e).replace(Si," ").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim(),o=t<Bl&&Om.test(r),i=t<Bl&&n===0;return o||i}function Nm(e,t,n=200,r=null){let o=Cm(t),i=Array.from(new Set(o.flatMap(l=>l.types))),s=Em(t),a=Im(t);return{url:e,status:n,fetched:!0,title:$m(t),metaDescription:Sm(t),h1s:Rm(t),canonical:s,canonicalServerRendered:s===null?null:!0,jsonLd:o,jsonLdTypes:i,openGraph:Am(t),twitter:Pm(t),wordCount:zl(t),clientRenderedShell:Lm(t),bodyLinkCount:Yl(t),robotsNoindex:Et(t)||_m(r),robotsNoindexMeta:Et(t),imgCount:a.imgCount,imgsMissingAlt:a.missingAlt,imgsMissingAltSrcs:a.missingAltSrcs,failureReason:null}}function Jl(e,t=null){return{url:e,status:null,fetched:!1,title:null,metaDescription:null,h1s:[],canonical:null,canonicalServerRendered:null,jsonLd:[],jsonLdTypes:[],openGraph:{},twitter:{},wordCount:0,clientRenderedShell:!1,bodyLinkCount:0,robotsNoindex:!1,robotsNoindexMeta:!1,imgCount:0,imgsMissingAlt:0,imgsMissingAltSrcs:[],failureReason:t}}function Dm(e){return typeof e=="function"?{fetchImpl:e}:e??{}}function jm(e){if(e instanceof Error){let t=e.cause,n=t?.code??(t?.message&&t.message!==e.message?t.message:null);return`network error: ${e.message}${n?` (${n})`:""}`}return`network error: ${String(e)}`}async function jr(e,t){let n=Dm(t),r=Jl(e);try{let o=await F(e,{headers:{"user-agent":"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) SEOAgent-CLI"},redirect:"follow"},{attempts:n.attempts??3,timeoutMs:n.timeoutMs??1e4,fetchImpl:n.fetchImpl});if(!o.ok){let a=vi.has(o.status)?_i(await Fm(o),o.status):null;return a?{evidence:Hl(r,o.status,a),html:null}:{evidence:{...r,status:o.status,failureReason:`HTTP ${o.status}`},html:null}}let i=await o.text(),s=_i(i,o.status);return s?{evidence:Hl(r,o.status,s),html:null}:{evidence:Nm(e,i,o.status,o.headers?.get?.("x-robots-tag")??null),html:i}}catch(o){return{evidence:{...r,failureReason:jm(o)},html:null}}}async function Fm(e){try{return await e.text()}catch{return""}}function Hl(e,t,n){return{...e,status:t,failureReason:Dl(n),blockedBy:n}}async function Xl(e,t){return(await jr(e,t)).evidence}async function Ei(e,t={}){let n=Math.max(1,t.concurrency??5),r=new Array(e.length),o=0;async function i(){for(;;){let s=o++;if(s>=e.length)return;if(t.deadlineMs!==void 0&&Date.now()>=t.deadlineMs){r[s]=Jl(e[s],"crawl time budget exhausted before this page could be fetched");continue}let{evidence:a,html:l}=await jr(e[s],{attempts:t.attempts,timeoutMs:t.timeoutMs,fetchImpl:t.fetchImpl});r[s]=a,l!==null&&t.onHtml?.(e[s],l)}}return await Promise.all(Array.from({length:Math.min(n,e.length)},()=>i())),r}function Mm(e){let t=[],n=[],r=null,o=!1;for(let i of e.split(/\r?\n/)){let s=i.replace(/#.*$/,"").trim();if(!s)continue;let a=s.indexOf(":");if(a===-1)continue;let l=s.slice(0,a).trim().toLowerCase(),c=s.slice(a+1).trim();if(l==="user-agent"){(!r||!o)&&(r={userAgents:[],disallow:[],allow:[]},t.push(r)),r.userAgents.push(c.toLowerCase()),o=!0;continue}if(o=!1,l==="sitemap"){c&&n.push(c);continue}r||(r={userAgents:["*"],disallow:[],allow:[]},t.push(r)),l==="disallow"?r.disallow.push(c):l==="allow"&&r.allow.push(c)}return{groups:t,sitemaps:n}}function Gl(e,t){if(e==="")return!1;let n=e.endsWith("$"),o=(n?e.slice(0,-1):e).replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${o}${n?"$":""}`).test(t)}function Fr(e,t,n="*"){if(!e.fetched)return!1;let r;try{let c=new URL(t);r=`${c.pathname}${c.search}`}catch{r=t}let o=n.toLowerCase(),i=e.groups.filter(c=>c.userAgents.includes(o)),s=i.length>0?i:e.groups.filter(c=>c.userAgents.includes("*")),a=-1,l=-1;for(let c of s){for(let u of c.allow)Gl(u,r)&&(a=Math.max(a,u.length));for(let u of c.disallow)Gl(u,r)&&(l=Math.max(l,u.length))}return l>a}function Ql(e){let t=e.trim().replace(/\/+$/,"");return/^https?:\/\//i.test(t)?t:`https://${t}`}async function Zl(e,t){let n=`${Ql(e)}/robots.txt`,r={fetched:!1,status:null,raw:"",groups:[],sitemaps:[]};try{let o=await F(n,{headers:{"user-agent":"SEOAgent-CLI/robots-check"}},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!o.ok)return{...r,status:o.status};let i=await o.text();return/^\s*</.test(i)?{...r,status:o.status,raw:""}:{fetched:!0,status:o.status,raw:i,...Mm(i)}}catch{return r}}var Um=50,Bm=5;function Ci(e){return/<sitemapindex[\s>]/i.test(e)}function Wl(e){try{return/\.xml(\.gz)?$/i.test(new URL(e).pathname)}catch{return/\.xml(\.gz)?(\?.*)?$/i.test(e)}}function Hm(e,t){try{let n=r=>r.toLowerCase().replace(/^www\./,"");return n(new URL(e).hostname)===n(new URL(t).hostname)}catch{return!1}}var Gm=/\/(blog|posts?|articles?|news)\//i;function Kl(e){return e.filter(t=>Gm.test(t)).length}async function ec(e,t){let n=`${Ql(e)}/sitemap.xml`,r={fetched:!1,status:null,urls:[],count:0,blogUrlCount:0};try{let o=await F(n,{headers:{"user-agent":"SEOAgent-CLI/sitemap-facts"}},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!o.ok)return{...r,status:o.status};let i=await o.text();if(!/<urlset|<sitemapindex/i.test(i))return{...r,status:o.status};let s=Ae(i);if(!Ci(i)){let y=ql(s.filter(m=>!Wl(m)));return{fetched:!0,status:o.status,urls:y,count:y.length,blogUrlCount:Kl(y)}}let a=s.filter(y=>Hm(y,n)).slice(0,Um),l=[],c=[],u=0,p=0,g=async()=>{for(;p<a.length;){let y=a[p++];try{let m=await F(y,{headers:{"user-agent":"SEOAgent-CLI/sitemap-facts"}},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!m.ok){l.push(y);continue}let w=await m.text();if(!/<urlset|<sitemapindex/i.test(w)){l.push(y);continue}u++;for(let k of Ae(w))Wl(k)||c.push(k)}catch{l.push(y)}}};await Promise.all(Array.from({length:Math.min(Bm,a.length)},()=>g()));let f=ql(c);return{fetched:!0,status:o.status,urls:f,count:f.length,blogUrlCount:Kl(f),index:{children:s.length,expanded:u,unreachable:l}}}catch{return r}}function ql(e){return[...new Set(e)]}var rc=["tsx","jsx","js","mdx","md"],Vm=["astro","md","mdx"],Ym=5e3,zm=2e3,Jm=10;function Ue(e,t){let n=new Map,r=0,o=(l,c,u=!1)=>{let p=ac(l);if(p===null){r++;return}let g=n.get(p);if(g){g.in_sitemap=g.in_sitemap||u,g.source.includes(c)||(g.source+=`, ${c}`);return}n.set(p,{route:p,url:cc(t,p),in_sitemap:u,source:c})};for(let l of Ur(e))rh(l,o);let i=Xm(e,t),s=l=>i.some(c=>c.test(l)),a=[...n.values()].filter(l=>!Me(l.route));return{pages:a.filter(l=>!s(l.route)).sort((l,c)=>l.route.localeCompare(c.route)),dynamicCount:r,offOriginCount:a.filter(l=>s(l.route)).length}}function Xm(e,t){let n=tc(t);if(!n)return[];let r=[];for(let o of Ur(e)){let i;try{i=JSON.parse(Mr(me(o,"vercel.json"),"utf-8"))}catch{continue}if(Array.isArray(i.redirects))for(let s of i.redirects){if(!s||typeof s.source!="string"||typeof s.destination!="string")continue;let a=tc(s.destination);if(!a||oc(a,n)||!Qm(s,n))continue;let l=Zm(s.source);l&&r.push(l)}}return r}function tc(e){if(!e)return null;let t=e.trim();if(!t||t.startsWith("/"))return null;try{return new URL(/^https?:\/\//i.test(t)?t:`https://${t}`).hostname.toLowerCase()}catch{return null}}function oc(e,t){let n=r=>r.replace(/^www\./,"");return n(e)===n(t)}function Qm(e,t){if(Array.isArray(e.missing)&&e.missing.length>0)return!1;let n=e.has;return!Array.isArray(n)||n.length===0?!0:n.every(r=>r&&r.type==="host"&&typeof r.value=="string"&&oc(r.value.toLowerCase(),t))}function Zm(e){if(!e.startsWith("/")||/[(){}[\]?+*]/.test(e.replace(/:[A-Za-z0-9_]+(?:\([^)]*\))?[*+?]?/g,"")))return null;let t="",n=0;for(;n<e.length;){let r=e[n];if(r!==":"){t+=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n++;continue}let o=/^:([A-Za-z0-9_]+)(\(([^)]*)\))?([*+?])?/.exec(e.slice(n));if(!o)return null;let[,,,i,s]=o;i!==void 0?t+=`(?:${i})`:s==="*"?t+=".*":s==="+"?t+=".+":s==="?"?t+="[^/]*":t+="[^/]+",n+=o[0].length}try{return new RegExp(`^${t}$`,"i")}catch{return null}}async function ic(e,t,n){let r={checked:!1,liveCount:0,flipped:0,added:0},o=await eh(t,n);if(o.length===0)return r;let i=new Set(o.map(L)),s=0;for(let c of e)!c.in_sitemap&&i.has(L(c.url||c.route))&&(c.in_sitemap=!0,s++,c.source.includes("live-sitemap")||(c.source+=", live-sitemap"));let a=new Set(e.map(c=>L(c.url||c.route))),l=0;for(let c of o){if(l>=zm)break;let u=nh(c,t);u===null||a.has(u)||(a.add(u),e.push({route:u,url:cc(t,u),in_sitemap:!0,source:"live-sitemap"}),l++)}return l>0&&e.sort((c,u)=>c.route.localeCompare(u.route)),{checked:!0,liveCount:o.length,flipped:s,added:l}}async function eh(e,t){let n=async l=>{try{let c=await F(l,{headers:{"user-agent":"SEOAgent-CLI/sitemap-check"}},{attempts:1,timeoutMs:5e3,fetchImpl:t});return{status:c.status,xml:c.ok?await c.text():""}}catch{return null}},r=vn(e),o=await n(r);if(o?.status===404&&(o=await n(r.replace(/\/sitemap\.xml$/,"/sitemap-index.xml"))),!o||!o.xml)return[];let i=Ae(o.xml);if(!Ci(o.xml))return i;let s=i.filter(l=>sc(l,e)).slice(0,Jm);return(await Promise.all(s.map(l=>n(l)))).flatMap(l=>l?.xml?Ae(l.xml):[])}function th(e){return e.replace(/^https?:\/\//,"").replace(/\/.*$/,"").toLowerCase().replace(/^www\./,"")}function sc(e,t){let n;try{n=new URL(e)}catch{return!1}return n.protocol!=="https:"&&n.protocol!=="http:"?!1:n.hostname.toLowerCase().replace(/^www\./,"")===th(t)}function nh(e,t){if(!sc(e,t))return null;let n=L(e);return/\.xml$/i.test(n)||Ml(n)?null:ac(n)}function rh(e,t){for(let n of["app",me("src","app")]){let r=me(e,n);if($n(r))for(let o of Ai(r)){let i=Pi(r,o),s=i[i.length-1];uh(s)&&(i.some(a=>a.startsWith("@"))||t(sh(i.slice(0,-1)),"app router"))}}for(let n of["pages",me("src","pages")]){let r=me(e,n);if($n(r))for(let o of Ai(r)){let i=Pi(r,o);if(i[0]==="api")continue;let s=i[i.length-1],a=Ii(s),l=rc.includes(a),c=Vm.includes(a);if(!l&&!c)continue;let u=Br(s);dh(u)||t(ah(i),c?"astro":"pages router")}}for(let n of[".","public"]){let r=me(e,n);if($n(r))for(let o of Ai(r,n==="."?1:1/0)){let i=Pi(r,o),s=i[i.length-1];Ii(s)==="html"&&(i.some(a=>a==="node_modules"||a.startsWith("."))||t(lh(i),"static html"))}}for(let n of["public/sitemap.xml","sitemap.xml"]){let r=me(e,...n.split("/"));if(Wm(r)){for(let o of ph(r)){let i=ch(o);i!==null&&t(i,"sitemap.xml",!0)}break}}}function Ur(e){let t=[e],n=new Set([e]);for(let r of oh(e))for(let o of ih(e,r))n.has(o)||(n.add(o),t.push(o));return t}function oh(e){let t=[];try{let n=Mr(me(e,"pnpm-workspace.yaml"),"utf-8"),r=!1;for(let o of n.split(/\r?\n/)){let i=o.replace(/#.*$/,"");if(/^\s*packages\s*:/.test(i)){r=!0;continue}if(r){let s=i.match(/^\s*-\s*['"]?([^'"\s]+)['"]?\s*$/);s?t.push(s[1]):/^\S/.test(i)&&(r=!1)}}}catch{}try{let r=JSON.parse(Mr(me(e,"package.json"),"utf-8")).workspaces,o=Array.isArray(r)?r:Array.isArray(r?.packages)?r.packages:[];for(let i of o??[])typeof i=="string"&&t.push(i)}catch{}return t}function ih(e,t){if(!t||t.startsWith("!"))return[];let n=t.replace(/\/\*\*?$/,"/*"),r=n.indexOf("*");if(r===-1){let a=me(e,...n.split("/").filter(Boolean));return $n(a)?[a]:[]}let o=n.slice(0,r).replace(/\/$/,""),i=me(e,...o.split("/").filter(Boolean));if(!$n(i))return[];let s=[];try{for(let a of nc(i,{withFileTypes:!0}))if(a.isDirectory()&&!a.name.startsWith(".")&&!lc.has(a.name)&&(s.push(me(i,a.name)),s.length>=200))break}catch{}return s}function ac(e){let t=e.trim();return t===""||t==="/"||(t.startsWith("/")||(t=`/${t}`),t=t.replace(/\/+$/,""),t==="")?"/":/\[.*\]/.test(t)?null:t}function sh(e){return"/"+e.filter(n=>!(n.startsWith("(")&&n.endsWith(")"))).join("/")}function ah(e){let t=[...e],n=Br(t[t.length-1]);return n==="index"?t.pop():t[t.length-1]=n,"/"+t.join("/")}function lh(e){let t=[...e],n=Br(t[t.length-1]);return n==="index"?t.pop():t[t.length-1]=n,"/"+t.join("/")}function ch(e){try{return new URL(e).pathname||"/"}catch{return e.startsWith("/")?e:null}}function uh(e){return Br(e)==="page"&&rc.includes(Ii(e))}function dh(e){return["_app","_document","_error","404","500","middleware"].includes(e)}function ph(e){try{let t=Mr(e,"utf-8"),n=[],r=/<loc>\s*([^<\s]+)\s*<\/loc>/gi,o;for(;(o=r.exec(t))!==null;)n.push(o[1].trim());return n}catch{return[]}}var lc=new Set(["node_modules",".git",".next","dist","build",".vercel","out"]);function $n(e){try{return Km(e).isDirectory()}catch{return!1}}function*Ai(e,t=1/0){let n=0;function*r(o,i){if(i>t)return;let s;try{s=nc(o,{withFileTypes:!0})}catch{return}for(let a of s){if(n>=Ym)return;if(a.name.startsWith("."))continue;let l=me(o,a.name);if(a.isDirectory()){if(lc.has(a.name))continue;yield*r(l,i+1)}else a.isFile()&&(n++,yield l)}}yield*r(e,1)}function Pi(e,t){return t.slice(e.length).replace(/^[/\\]+/,"").split(qm).filter(Boolean)}function Ii(e){let t=e.lastIndexOf(".");return t===-1?"":e.slice(t+1).toLowerCase()}function Br(e){let t=e.lastIndexOf(".");return t===-1?e:e.slice(0,t)}function cc(e,t){return e?`https://${e.replace(/^https?:\/\//,"").replace(/\/$/,"")}${t==="/"?"/":t}`:t}import{existsSync as fh,mkdirSync as gh,readFileSync as mh,writeFileSync as hh}from"fs";import{join as Ti}from"path";var Sn="pages.md",Hr="pages-discovered.md";function yh(e){return nt(Ti(e,x,Sn))?.data?.generated===!0}function wh(e){let t=yh(e);return{rel:t?Hr:Sn,cloudOwned:t}}function uc(e,t){let n=!1,r=t.status!==null?String(t.status):"\u2014";e.status!==r&&(e.status=r,n=!0),e.rendered!==t.rendered&&(e.rendered=t.rendered,n=!0);let o=t.rendered==="error"?"\u2014":String(t.wordCount);return e.word_count!==o&&(e.word_count=o,n=!0),n}function Gr(e,t,n){let r=wh(e),o=Ti(e,x,r.rel),i=fh(o),s=i?Wr(o):new Map;if(t.length===0&&!i)return{wrote:!1,added:0,total:0,merged:!1,file:r.rel};let a=new Map(s),l=0,c=!1;for(let p of t){let g=pc(p.url),f=n?.get(p.url),y=a.get(g);if(y)p.in_sitemap&&y.in_sitemap!=="yes"&&(y.in_sitemap="yes",c=!0),f&&uc(y,f)&&(c=!0);else{let m={url:g,in_sitemap:p.in_sitemap?"yes":"no",in_nav:"\u2014",status:"\u2014",rendered:"\u2014",word_count:"\u2014",notes:pc(p.source)};f&&uc(m,f),a.set(g,m),l++,c=!0}}if(i&&!c)return{wrote:!1,added:0,total:a.size,merged:!0,file:r.rel};let u=[...a.values()];return gh(Ti(e,x),{recursive:!0}),hh(o,bh(u,r.cloudOwned),"utf-8"),{wrote:!0,added:l,total:u.length,merged:i,file:r.rel}}function bh(e,t){let n=["---","generated: false",`discovered_at: ${new Date().toISOString()}`,`row_count: ${e.length}`,"---"].join(`
55
55
  `),r=[t?"# Pages discovered in the codebase":"# Pages","",t?"Inventory of pages the codebase scan found. `pages.md` is now a cloud":"Inventory of pages discovered in your codebase. Every `seoagent sync`,",t?"projection (GSC traffic per page, edited in the dashboard), so the scan":"`seoagent init` and `seoagent refresh` re-scan and merge in newly-added",t?"writes here instead; every `seoagent sync` re-scans, merges in new pages":"pages without touching rows you or the audit have edited. `In sitemap` is",t?"and pushes them so the cloud inventory stays current. `In sitemap` is":"refreshed from the live sitemap; `Status` / `Rendered` / `Word count` are",t?"refreshed from the live sitemap; `Status` / `Rendered` / `Word count` are":"filled by `seoagent refresh --crawl` (a live fetch of each page). This file",t?"filled by `seoagent refresh --crawl` (a live fetch of each page).":"syncs to the cloud on login."].join(`
56
56
  `),o="| URL | In sitemap | In nav | Status | Rendered | Word count | Notes |",i="|---|---|---|---|---|---|---|",s=e.map(a=>`| ${a.url} | ${a.in_sitemap} | ${a.in_nav} | ${a.status} | ${a.rendered} | ${a.word_count} | ${a.notes} |`);return[n,"",r,"",o,i,...s,""].join(`
57
57
  `)}function Wr(e){let t=new Map,n;try{n=mh(e,"utf-8")}catch{return t}let r=n.split(/\r?\n/);for(let o=0;o<r.length-1;o++){if(!Oi(r[o])||!kh(r[o+1]))continue;let i=dc(r[o]).map(a=>a.toLowerCase()),s={url:i.findIndex(a=>a.includes("url")),in_sitemap:i.findIndex(a=>a.includes("sitemap")),in_nav:i.findIndex(a=>a.includes("nav")),status:i.findIndex(a=>a.includes("status")||a.includes("http")),rendered:i.findIndex(a=>a.includes("render")),word_count:i.findIndex(a=>a.includes("word")),notes:i.findIndex(a=>a.includes("note"))};if(s.url===-1)return t;for(let a=o+2;a<r.length&&Oi(r[a]);a++){let l=dc(r[a]),c=(l[s.url]??"").trim();!c||c==="\u2014"||c==="-"||t.set(c,{url:c,in_sitemap:Gt(l,s.in_sitemap),in_nav:Gt(l,s.in_nav),status:Gt(l,s.status),rendered:Gt(l,s.rendered),word_count:Gt(l,s.word_count),notes:Gt(l,s.notes)})}break}return t}function Gt(e,t){let n=t>=0?(e[t]??"").trim():"";return n===""?"\u2014":n}function Oi(e){let t=e.trim();return t.startsWith("|")&&t.endsWith("|")&&t.length>1}function kh(e){let t=e.trim();return Oi(t)&&/^\|(?:\s*:?-+:?\s*\|)+$/.test(t)}function dc(e){return e.trim().slice(1,-1).split("|").map(t=>t.trim())}function pc(e){return e.replace(/\r?\n/g," ").replace(/\|/g,"/").trim()}import{existsSync as xh,readFileSync as vh,statSync as _h}from"fs";import{dirname as Li,isAbsolute as $h,join as Sh,resolve as Ni,sep as Rn}from"path";var Rh={isWorktree:!1,mainRoot:null,reason:null};function fc(e){let t=Sh(e,".git");try{if(xh(t)&&_h(t).isFile()){let i=vh(t,"utf-8").match(/^gitdir:\s*(.+)\s*$/m),s=null;if(i){let a=$h(i[1])?i[1]:Ni(e,i[1]),l=Li(a),c=Li(l);l.endsWith(`${Rn}worktrees`)&&c.endsWith(`${Rn}.git`)&&(s=Li(c))}return{isWorktree:!0,mainRoot:s,reason:"gitfile"}}}catch{}let n=`${Rn}.claude${Rn}worktrees${Rn}`,r=Ni(e).indexOf(n);return r>=0?{isWorktree:!0,mainRoot:Ni(e).slice(0,r),reason:"agent-worktree-path"}:Rh}import{existsSync as at,mkdirSync as Kr,readdirSync as Eh,readFileSync as Di,statSync as yC,writeFileSync as gc}from"fs";import{dirname as mc,join as Pe,relative as ji,resolve as hc,sep as yc}from"path";var Wt="okf";function Kt(e){return Pe(e,x,Wt)}var Ch=/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})?)?$/;function qr(e){let t=[];for(let n of Eh(e,{withFileTypes:!0})){let r=Pe(e,n.name);n.isDirectory()?t.push(...qr(r)):n.isFile()&&n.name.toLowerCase().endsWith(".md")&&t.push(r)}return t}function wc(e){let t=[],n=/\[[^\]]*\]\(([^)]+)\)/g,r;for(;(r=n.exec(e))!==null;){let o=r[1].trim().split(/\s+/)[0];o&&(/^[a-z][a-z0-9+.-]*:/i.test(o)||o.startsWith("#")||t.push(o))}return t}function Vr(e){let t=[],n=[];if(!at(e))return{ok:!1,fileCount:0,errors:[{file:Wt,message:"No OKF bundle found. Run `seoagent okf scaffold` first."}],warnings:[]};let r=qr(e);if(r.length===0)return{ok:!1,fileCount:0,errors:[{file:Wt,message:"OKF directory exists but contains no markdown files."}],warnings:[]};at(Pe(e,"index.md"))||n.push({file:Wt,message:"No top-level index.md \u2014 agents use it for progressive disclosure."});for(let i of r){let s=ji(e,i),a;try{a=te(Di(i,"utf-8"))}catch{t.push({file:s,message:"Could not read or parse file."});continue}let l=a.data.type;(l==null||String(l).trim()==="")&&t.push({file:s,message:"Missing required frontmatter field `type`."});let c=a.data.timestamp;c!=null&&c!==""&&!Ch.test(String(c))&&t.push({file:s,message:`\`timestamp\` is not ISO-8601: "${String(c)}"`});let u=a.data.description;typeof u=="string"&&u.length>200&&n.push({file:s,message:`\`description\` is ${u.length} chars (keep \u2264 200).`});for(let p of wc(a.body)){let g=p.split("#")[0];if(!g)continue;let f=hc(mc(i),g);at(f)||t.push({file:s,message:`Broken link \u2192 "${p}" (target does not exist).`})}}return{ok:t.length===0,fileCount:r.length,errors:t,warnings:n}}function Yr(e){let t=Kt(e);if(!at(t))return{exists:!1,fileCount:0};try{return{exists:!0,fileCount:qr(t).length}}catch{return{exists:!0,fileCount:0}}}var bc=["_Describe the business in","_Link concept files here","_Link FAQ files here","_Link article files here"];var Ah="- Bundle scaffolded.";function Fi(e,t){if(e==="okf/index.md")return bc.some(n=>t.includes(n));if(e==="okf/log.md"){let n=t.replace(/\r\n/g,`
@@ -1110,8 +1110,8 @@ skill knows what to do.
1110
1110
  `):[...n.slice(0,o),...t,...n.slice(i)].join(`
1111
1111
  `)}function lk(e){let t=ks(e.served);if(!t)return e.generated;let n=ks(e.generated)?.text??"";if(t.text===n)return e.generated;let r=ks(e.lastSource)?.text;if(r!==void 0&&t.text===r)return e.generated;if(t.text.endsWith("\u2026")){let o=t.text.slice(0,-1).trimEnd();if(o&&n.startsWith(o))return e.generated}return ak(e.generated,t.lines)}function xs(e,t){try{return ko(e)&&Bn(e,"utf-8")===t?!1:(rk(sk(e),{recursive:!0}),ik(e,t,"utf-8"),!0)}catch{return!1}}function nn(e,t){if(!t.domain||t.domain==="unknown")return{...id,skipped:["no-domain"]};let n=vr(e,t.public_dir??null),r;try{r=to(e)}catch{r=new Set}let o={...id,publicDir:n.dir,publicDirSource:n.source,removedPaths:[...r].sort(),okfWithheld:[],skipped:[]},i=null;try{let a=Yc(e,t,r);i=a?Wc(a):null}catch{i=null}if(i===null)o.skipped.push("llms-no-content");else{let a=sd(ut(e,x,Tn));if(o.llmsSourceWritten=xs(ut(e,x,Tn),i),o.llmsRoute=Ua(e,n.dir),o.llmsRoute){if(o.skipped.push("llms-route-owned"),o.llmsRouteDrift=o.llmsSourceWritten&&t.llms_owner!=="route",t.llms_owner!=="route")try{X(e,{llms_owner:"route"})&&(t.llms_owner="route")}catch{}}else if(n.dir){let l=ut(e,n.dir,od),c=lk({generated:i,served:sd(l),lastSource:a});o.llmsSummaryKept=c!==i,xs(l,c)&&(o.llmsPublished=`${n.dir}/${od}`)}}let s=Kt(e);if(!ko(s))o.skipped.push("okf-missing");else if(kc(s))o.skipped.push("okf-placeholder");else if(!Vr(s).ok)o.skipped.push("okf-invalid");else if(n.dir){let a=ut(e,n.dir,xo),{files:l,withheld:c}=ck(s,r);o.okfWithheld=c;let u=0;for(let[p,g]of l)xs(ut(a,p),g)&&u++;for(let p of c){let g=ut(a,p);try{ko(g)&&Bn(g,"utf-8")===Bn(ut(s,p),"utf-8")&&(ok(g),u++)}catch{}}u>0&&(o.okfPublished=u,o.okfPublishedDir=`${n.dir}/${xo}`)}return n.dir||o.skipped.push("no-public-dir"),o}function ck(e,t){let n=new Map;for(let i of xc(e))try{n.set(i,Bn(ut(e,i),"utf-8"))}catch{continue}if(t.size===0)return{files:n,withheld:[]};let r=new Set;for(let[i,s]of n){if(i==="index.md"||i==="log.md")continue;let a;try{a=te(s).data.resource}catch{continue}typeof a!="string"||!/^https?:\/\//i.test(a.trim())||t.has(L(a.trim()))&&r.add(i)}if(r.size===0)return{files:n,withheld:[]};let o=new Map;for(let[i,s]of n)r.has(i)||o.set(i,fk(i,s,r));return{files:o,withheld:[...r].sort()}}function uk(e,t){let n=t.trim().split("#")[0];if(!n||/^[a-z][a-z0-9+.-]*:/i.test(n)||n.startsWith("/"))return null;let r=bs.normalize(bs.join(bs.dirname(e),n));return r.startsWith("..")?null:r}var dk=/\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g,pk=/^\s*(?:[-*+]|\d+\.)\s+\[[^\]]*\]\(([^)\s]+)(?:\s+"[^"]*")?\)/;function fk(e,t,n){let r=s=>{let a=uk(e,s);return a!==null&&n.has(a)},o=[],i=!1;for(let s of t.split(`
1112
1112
  `)){let a=pk.exec(s);if(a&&r(a[1])){i=!0;continue}let l=s.replace(dk,(c,u,p)=>r(p)?u:c);l!==s&&(i=!0),o.push(l)}return i?o.join(`
1113
- `):t}function ad(e,t){if(!e)return[];let n=[],r=[];return e.llmsPublished&&r.push(e.llmsPublished),e.okfPublishedDir&&r.push(`${e.okfPublishedDir}/ (${e.okfPublished} file${e.okfPublished===1?"":"s"})`),r.length>0&&n.push({text:`ai-files: published ${r.join(" and ")} \u2014 commit these so answer engines can read them.`,tone:"dim",always:!0}),e.skipped.includes("okf-placeholder")&&n.push({text:"ai-files: .seoagent/okf/ is still the scaffold. Fill it (see references/open-knowledge-format.md) and it publishes itself on the next sync.",tone:"dim",always:!1}),e.skipped.includes("okf-invalid")&&n.push({text:`ai-files: .seoagent/okf/ has validation errors, so it was NOT published. Run \`${t("okf validate")}\` and fix them.`,tone:"warn",always:!1}),e.llmsRouteDrift&&n.push({text:`ai-files: .seoagent/llms.md changed, but ${e.llmsRoute} already serves /llms.txt, so nothing was published \u2014 a file in your static dir would shadow that route. Compare the two, or set \`llms_owner: route\` in .seoagent/project.md to own the file yourself and stop this notice.`,tone:"dim",always:!1}),e.skipped.includes("no-public-dir")&&n.push({text:"ai-files: couldn't tell which directory this project serves as static files. Set `public_dir:` in .seoagent/project.md (`public`, `static`, or a nested path like `apps/web/public` in a monorepo) so llms.txt and the OKF bundle actually get served.",tone:"dim",always:!1}),n}var gk=30,mk=/<(script|style|noscript|template|svg|nav|header|footer)\b[^>]*>[\s\S]*?<\/\1>/gi;function hk(e){let t=e,n=/<body\b[^>]*>([\s\S]*?)<\/body>/i.exec(t);n&&(t=n[1]),t=t.replace(mk," ").replace(/<!--[\s\S]*?-->/g," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/gi," ").replace(/&[a-z]+;/gi," ").replace(/\s+/g," ").trim();let r=t===""?0:t.split(" ").filter(Boolean).length;return{wordCount:r,rendered:r<gk?"empty":"yes"}}async function yk(e,t){try{let n=await F(e,{headers:{"user-agent":"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) SEOAgent-CLI"},redirect:"follow"},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!n.ok)return{status:n.status,rendered:"error",wordCount:0};let r=await n.text(),{wordCount:o,rendered:i}=hk(r);return{status:n.status,rendered:i,wordCount:o}}catch{return{status:null,rendered:"error",wordCount:0}}}async function ld(e,t={}){let n=Math.max(1,t.concurrency??5),r=new Map,o=[...e],i=0;async function s(){for(;;){let a=o.shift();if(a===void 0)return;r.set(a,await yk(a,t.fetchImpl)),i+=1,t.onProgress?.(i,e.length)}}return await Promise.all(Array.from({length:Math.min(n,e.length)},()=>s())),r}var vs=300;async function Hn(e,t={}){try{let n=A(e),r=n?.domain&&n.domain!=="unknown"?n.domain:null,{pages:o}=Ue(e,r);t.enrichSitemap&&r&&await ic(o,r);let i,s;if(t.crawl&&r){let l=o.map(u=>u.url).filter(u=>/^https?:\/\//.test(u)),c=l.slice(0,vs);if(l.length>vs&&d.info(`Crawling the first ${vs} of ${l.length} pages (cap).`),c.length>0){d.info(`Crawling ${c.length} page${c.length===1?"":"s"}\u2026`),s=await ld(c);let u=0,p=0;for(let g of s.values())g.rendered==="empty"?u++:g.rendered==="error"&&p++;i={crawled:s.size,empty:u,errors:p}}}let a=Gr(e,o,s);return{added:a.added,total:a.total,file:a.file,crawl:i}}catch{return{added:0,total:0,file:"pages.md"}}}function vk(e){try{let t=en(e);return t.evidenceFound?t:void 0}catch{return}}var _k=new Set([".md"]),$k=new Set(["inbox"]);function Sk(e){let t=[];function n(r,o){if(_s(r))for(let i of bk(r,{withFileTypes:!0})){if(i.name.startsWith(".")||o===""&&$k.has(i.name))continue;let s=$s(r,i.name);if(i.isDirectory())n(s,o?`${o}/${i.name}`:i.name);else if(i.isFile()){let a=i.name.lastIndexOf("."),l=a===-1?"":i.name.slice(a);_k.has(l)&&t.push(s)}}}return n(e,""),t}var Rk=14400*1e3;function Ek(e,t){return kk(e,t).split(xk).join("/")}async function Ck(e,t){try{let n=await F(`${e}/api/cli/actions/fetch`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:t,...jc()},body:JSON.stringify({})});if(!n.ok){let o=await n.text().catch(()=>"");return{ok:!1,actions:[],declined:[],error:`${n.status} ${o.slice(0,200)}`}}let r=await n.json().catch(()=>null);return!r||r.status!=="ok"||!Array.isArray(r.actions)?{ok:!1,actions:[],declined:[],error:"Malformed response"}:{ok:!0,actions:r.actions,declined:is(r.declined)}}catch(n){return{ok:!1,actions:[],declined:[],error:n.message}}}async function cd(e,t,n){try{let r=await F(`${e}/api/cli/sync`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:n},body:JSON.stringify(t)});if(!r.ok){let i=await r.text().catch(()=>"");return{ok:!1,status:r.status,error:i.slice(0,200)}}let o=typeof r.json=="function"?await r.json().catch(()=>null):null;return{ok:!0,status:r.status,...o?.agent_notice?{agentNotice:o.agent_notice}:{}}}catch(r){return{ok:!1,status:0,error:r.message}}}var Ak=12e3;function Pk(e,t){return e===void 0?!1:t>=e-Ak}var Ik=6,Tk=new Set(["briefs","content","okf"]);function Ok(e){let t=[],n=null;for(let r of e){let o=r.rel.indexOf("/"),i=o===-1?null:r.rel.slice(0,o),s=i!==null&&Tk.has(i);s&&i===n?t[t.length-1].push(r):(t.push([r]),n=s?i:null)}return t}async function vo(e,t={}){let n=vk(e),r=u=>{let p=n?{...u,verifyRecs:n}:{...u};return s&&(p={...p,aiFiles:s}),i&&i.added>0&&(p={...p,pagesRescan:{added:i.added,total:i.total,file:i.file}}),p},o=A(e),i=null;if(o&&!t.pullOnly)try{i=await Hn(e)}catch{}let s=null;if(o)try{s=nn(e,o)}catch{}let a=B(o?.domain);if(!a)return r({ok:!0,reason:"no-auth",synced:0,failed:0,errors:[]});if(!o)return r({ok:!0,reason:"no-project",synced:0,failed:0,errors:[]});if(o.domain===nt)return r({ok:!0,reason:"domain-unknown",synced:0,failed:0,errors:[]});let l=$s(e,x);if(!_s(l))return r({ok:!0,reason:"no-project",synced:0,failed:0,errors:[]});if(!nd(e).acquired)return r({ok:!0,reason:"busy",synced:0,failed:0,errors:[]});try{return r(await Lk(e,t,a,o,l))}finally{bo(e)}}async function Lk(e,t,n,r,o){let i=n.api_base||M.BASE,s=`Bearer ${n.user_token}:${n.website_token}`;t.onPhase?.("binding");let a=await rt({apiBase:i,authHeader:s,localDomain:r.domain});if(a.verdict==="mismatch")return{ok:!0,reason:"project-mismatch",synced:0,failed:0,errors:[],cloudDomain:a.cloudDomain,localDomain:r.domain};if(a.verdict==="unverified")return{ok:!0,reason:"unverified",synced:0,failed:0,errors:[`could not verify cloud project binding: ${a.detail}`]};let l=Un(r.domain);try{eu(e,r)}catch{}let c=Sk(o),u=0,p=0,g=[],f=[],y=0;t.onPhase?.("ack-flush");let m=await jk(e,i,s),w={restored:!1,blockPush:!1,notices:[]};(!t.pathFilter||"context.md".endsWith(t.pathFilter))&&(w=await Ku({seoagentDir:o,apiBase:i,authHeader:s,stateFiles:l.files,force:t.force,forcePaths:t.forcePaths}),g.push(...w.notices));let k=0;if(!t.pullOnly){t.onPhase?.("push");for(let J of t.deletedPaths??[]){y++;let ce=await cd(i,{path:J,domain:r.domain,deleted:!0},s);ce.ok?(delete l.files[J],u++,ho(r.domain,l)):(p++,f.push(`${J}: ${ce.status} ${ce.error??""}`.trim()))}let K=[];for(let J of c){let ce=Ek(o,J);if(t.pathFilter&&!ce.endsWith(t.pathFilter)||ce==="context.md"&&w.blockPush)continue;let De=wk(J,"utf-8"),ye=_e(De),we=l.files[ce];!(!we||we.hash!==ye)&&!t.force||K.push({rel:ce,contents:De,hash:ye})}let q=async({rel:J,contents:ce,hash:De})=>{y++;let ye=await cd(i,{path:J,contents:ce,domain:r.domain},s);ye.ok?(l.files[J]={hash:De},u++,ye.agentNotice&&g.push(`${J}: ${ye.agentNotice}`),ho(r.domain,l)):(p++,f.push(`${J}: ${ye.status} ${ye.error??""}`.trim()))},Z=0;for(let J of Ok(K)){let ce=0,De=async()=>{for(;ce<J.length&&!Pk(t.deadlineAt,Date.now());){let ye=J[ce++];Z++,await q(ye)}};if(await Promise.all(Array.from({length:Math.min(Ik,J.length)},De)),ce<J.length)break}Z<K.length&&(k=K.length-Z)}t.onPhase?.("inbox-pull");let S=await Ck(i,s),T=0,b=0,v=[],R=0,D=0;!S.ok&&S.error&&f.push(`pull actions: ${S.error}`);let _,N=[],V=new Map,U=!1,re=[],Y=l.last_synced_at,Lt=Uu(l.last_synced_at,Bu(o)),Q=!1;if(!t.pushOnly){t.onPhase?.("artifact-pull");let K=await Wu({projectDir:e,apiBase:i,authHeader:s,since:Lt,stateFiles:l.files,force:t.force,forcePaths:t.forcePaths,meta:Nk(e,!!t.silent)});re=K.directives??[],K.ok?(Y=K.cursor,Q=!0):(U=!0,K.error&&f.push(`pull: ${K.error}`)),_={written:K.written,overwritten:K.overwritten,skipped:K.skipped,conflicts:K.conflicts,deleted:K.deleted,warnings:K.warnings},N=K.conflictPaths;for(let[q,Z]of Object.entries(K.pointerOverwrites)){let J=q.match(/^content\/(.+)\.md$/)?.[1];J&&V.set(J,Z)}}if(S.ok&&!t.pushOnly&&!U){let K=new Set(N),q=[...ls(S.actions).keys()].filter(Z=>!K.has(Z)&&!_s($s(o,Z)));if(q.length>0){t.onPhase?.("draft-heal");let Z=await Gu({projectDir:e,apiBase:i,authHeader:s,paths:q,stateFiles:l.files});if(_&&(_.written+=Z.written.length),!Z.ok&&Z.error&&f.push(`pull drafts: ${Z.error}`),Z.absent.length>0&&_)for(let J of Z.absent)_.warnings.push(`${J}: an inbox task points at this draft, but the cloud has no copy of it`)}}if(S.ok){t.onPhase?.("inbox-write");let K=as(e);for(let[we,gt]of V)K.set(we,gt);let q=gu(e,S.actions,{conflictedPaths:new Set(N),localPointers:K,declined:S.declined});T=q.wrote,b=q.removed,R=q.skippedUnknown;let Z=l.announced_at?Date.parse(l.announced_at):NaN,ce=q.pendingIds.length>0&&(Number.isNaN(Z)||Date.now()-Z>=Rk)?new Set:new Set(l.announced_action_ids??[]),De=new Set(q.pendingIds.filter(we=>!ce.has(we)));v=q.pending.filter(we=>De.has(we.id)),D=De.size-v.length,l.announced_action_ids=q.pendingIds,De.size>0&&(l.announced_at=new Date().toISOString()),l.inbox_pulled_at=new Date().toISOString();let ye=ls(S.actions);_&&N.length>0&&(_.warnings=_.warnings.map(we=>{let gt=N.find(zo=>we.startsWith(`${zo}:`)),Yo=gt?ye.get(gt):void 0;return!gt||!Yo?.length?we:`${we} \u2014 blocks inbox action${Yo.length===1?"":"s"} ${Yo.map(zo=>`#${zo}`).join(", ")}; take the cloud copy with \`seoagent sync --force ${gt}\``}))}let Nt=!!_&&_.written+_.overwritten+_.deleted+_.conflicts>0;if(l.last_synced_at=Y,l.last_run_at=new Date().toISOString(),ho(r.domain,l),Q&&Hu(o,Y),t.onPhase?.("done"),y===0&&k===0&&T===0&&b===0&&!Nt&&!w.restored&&w.notices.length===0&&m.flushed===0&&m.dropped===0&&!U&&p===0)return{ok:!0,reason:"no-changes",synced:0,failed:0,errors:f,actionsPulled:0,actionsRemoved:0,actionsNew:[],actionsUnknown:R,actionsUnknownNew:D,acksFlushed:0,acksDropped:0,pull:_,directives:re};let Ne=p===0&&!U;return{ok:Ne,reason:Ne?void 0:"error",synced:u,failed:p,errors:f,...g.length>0?{notices:g}:{},...k>0?{pushDeferred:k}:{},actionsPulled:T,actionsRemoved:b,actionsNew:v,actionsUnknown:R,actionsUnknownNew:D,acksFlushed:m.flushed,acksDropped:m.dropped,pull:_,directives:re}}function Nk(e,t){let n=be(),r=n?null:A(e)?.install_id??null;return{cliVersion:n?null:I,agent:Dc(),authSource:Ar(),installId:r||null,silent:t,...n?{}:Dk(e)}}function Dk(e){let t=Xr(e);return t?{repo:t}:{}}async function jk(e,t,n){let r=yo(e);if(r.length===0)return{flushed:0,dropped:0};let o=0,i=0,s=[];for(let a of r){let l=await Fk(a,t,n);l==="flushed"?(o++,s.push(a.action_id)):l==="already-settled"&&(i++,s.push(a.action_id))}return s.length>0&&Zu(e,s),{flushed:o,dropped:i}}async function Fk(e,t,n){try{let r=await F(`${t}/api/cli/actions/${e.action_id}/ack`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:n},body:JSON.stringify({status:e.status,error_message:e.status==="failed"?e.reason:null,result:e.status==="failed"?{declined:!0,reason:e.reason}:{applied:!0,...e.details??{}}})});return r.ok?"flushed":r.status===409||r.status>=400&&r.status<500?"already-settled":"transient"}catch{return"transient"}}function ud(e,t=3e4){let n=Date.now()+t,r=setTimeout(e,t);return r.unref?.(),{cancel:()=>clearTimeout(r),deadlineAt:n}}function dt(e,t){let n=i=>i.replace(/[-+].*$/,"").split(".").map(s=>Number.parseInt(s,10)||0).slice(0,3),r=n(e),o=n(t);for(let i=0;i<3;i++){let s=(r[i]??0)-(o[i]??0);if(s!==0)return s}return 0}function dd(e){let t;try{t=A(e)}catch{return{refreshed:!1,reason:"error"}}if(!t)return{refreshed:!1,reason:"no-project"};if(bt(e))return{refreshed:!1,reason:"source-repo"};let n=t.skill_version||t.seoagent_version||"0.0.0";if(dt(I,n)<=0){if(!t.skill_version)try{X(e,{skill_version:n})}catch{}return{refreshed:!1,reason:"up-to-date"}}try{return Ut(e),X(e,{skill_version:I}),{refreshed:!0,from:n,to:I,reason:"refreshed"}}catch{return{refreshed:!1,reason:"error"}}}function Ss(e){let t;try{t=A(e)}catch{return{refreshed:!1,from:null,to:I,reason:"error"}}if(!t)return{refreshed:!1,from:null,to:I,reason:"no-project"};if(bt(e))return{refreshed:!1,from:null,to:I,reason:"source-repo"};let n=t.skill_version||t.seoagent_version||null;try{return Ut(e),X(e,{skill_version:I}),{refreshed:!0,from:n,to:I,reason:"refreshed"}}catch{return{refreshed:!1,from:n,to:I,reason:"error"}}}import{createHash as Mk}from"crypto";import{existsSync as gI,mkdirSync as Uk,readFileSync as Bk,writeFileSync as Hk}from"fs";import{join as Gk}from"path";var Wk="/cli-skill/manifest.json",Kk=360*60*1e3,qk=4e3,Vk=64,Yk=4*1024*1024,pd=Gk(ee,"skill-check.json"),zk=e=>Mk("sha256").update(e).digest("hex");function Jk(e){if(typeof e!="object"||e===null)return null;let t=e;if(typeof t.hash!="string"||!/^[0-9a-f]{64}$/.test(t.hash)||typeof t.min_cli!="string"||!/^\d+\.\d+\.\d+/.test(t.min_cli)||!Array.isArray(t.files)||t.files.length===0||t.files.length>Vk)return null;let n=[],r=0;for(let o of t.files){if(typeof o!="object"||o===null)return null;let i=o;if(typeof i.path!="string"||typeof i.sha256!="string"||!/^[A-Za-z0-9._/-]+$/.test(i.path)||i.path.startsWith("/")||i.path.split("/").includes("..")||!i.path.endsWith(".md")||!/^[0-9a-f]{64}$/.test(i.sha256))return null;let s=typeof i.bytes=="number"?i.bytes:0;r+=s,n.push({path:i.path,sha256:i.sha256,bytes:s})}return r>Yk||!n.some(o=>o.path==="SKILL.md")?null:{hash:t.hash,min_cli:t.min_cli,files:n}}function Xk(e,t,n=Kk){if(!e)return!0;let r=Date.parse(e);return Number.isNaN(r)?!0:t.getTime()-r>=n}function Qk(){try{return JSON.parse(Bk(pd,"utf-8"))}catch{return{}}}function Zk(e){try{Uk(ee,{recursive:!0}),Hk(pd,JSON.stringify({checkedAt:e}),"utf-8")}catch{}}async function ex(e){try{let t=await fetch(e,{signal:AbortSignal.timeout(qk),headers:{"User-Agent":`seoagent-cli/${I}`}});return t.ok?await t.text():null}catch{return null}}async function fd(e,t={}){try{let n=A(e);if(!n)return{updated:!1,reason:"no-project"};if(bt(e))return{updated:!1,reason:"source-repo"};let r=t.now??new Date,o=Qk();if(!t.force&&!Xk(o.checkedAt,r))return{updated:!1,reason:"throttled"};let i=(t.baseUrl??M.BASE).replace(/\/$/,""),s=t.fetchText??ex,a=await s(`${i}${Wk}`);if(Zk(r.toISOString()),a===null)return{updated:!1,reason:"unreachable"};let l;try{l=Jk(JSON.parse(a))}catch{l=null}if(!l)return{updated:!1,reason:"malformed"};if(n.skill_hash===l.hash)return{updated:!1,reason:"up-to-date"};if(dt(I,l.min_cli)<0)return{updated:!1,reason:"cli-too-old",minCli:l.min_cli};let c={};for(let u of l.files){let p=await s(`${i}/cli-skill/${u.path}`);if(p===null)return{updated:!1,reason:"unreachable"};if(zk(p)!==u.sha256)return{updated:!1,reason:"verify-failed"};c[u.path]=p}return al(e,c),X(e,{skill_hash:l.hash}),{updated:!0,reason:"updated",fileCount:l.files.length}}catch{return{updated:!1,reason:"error"}}}import{existsSync as tx,mkdirSync as nx,readFileSync as rx,writeFileSync as ox}from"fs";var ix="https://registry.npmjs.org/@seoagent-official/seoagent/latest",sx=1440*60*1e3,ax=720*60*1e3,lx=2e3;function cx(e,t,n=sx){if(!e.checkedAt)return!0;let r=Date.parse(e.checkedAt);return Number.isNaN(r)?!0:t.getTime()-r>=n}function ux(e){let{current:t,latest:n,cache:r,now:o}=e,i=e.notifyIntervalMs??ax;if(!n||dt(n,t)<=0)return null;if(r.notifiedVersion===n&&r.notifiedAt){let s=Date.parse(r.notifiedAt);if(!Number.isNaN(s)&&o.getTime()-s<i)return null}return`\u2191 SEOAgent ${n} is available (you have ${t}). Ask me to run \`seoagent update-cli\`, or run it yourself, to upgrade the CLI + all your projects.`}async function dx(e){let t=e.readCache();if(cx(t,e.now,e.checkIntervalMs)){let r=await e.fetchLatest();t={...t,checkedAt:e.now.toISOString(),...r?{latest:r}:{}},e.writeCache(t)}let n=ux({current:e.current,latest:t.latest,cache:t,now:e.now,notifyIntervalMs:e.notifyIntervalMs});return n&&t.latest&&e.writeCache({...t,notifiedVersion:t.latest,notifiedAt:e.now.toISOString()}),n}function px(){try{return tx(hr)?JSON.parse(rx(hr,"utf-8")):{}}catch{return{}}}function fx(e){try{nx(ee,{recursive:!0}),ox(hr,JSON.stringify(e,null,2)+`
1114
- `,"utf-8")}catch{}}async function gx(){try{let e=await fetch(ix,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(lx)});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}async function gd(e){try{return await dx({current:e,now:new Date,fetchLatest:gx,readCache:px,writeCache:fx})}catch{return null}}import{existsSync as md,readdirSync as hd}from"fs";import{join as Rs}from"path";var yd={PILLAR:0,SUB_PILLAR:1,LONG_TAIL:2},wd={high:0,medium:1,low:2},mx=new Set(["drafted","published","dismissed","superseded","done"]);function hx(e){let t=e.filter(n=>!mx.has((n.status??"").toLowerCase()));return t.length===0?null:[...t].sort((n,r)=>{let o=yd[(n.role??"").toUpperCase()]??3,i=yd[(r.role??"").toUpperCase()]??3;if(o!==i)return o-i;let s=wd[(n.priority??"").toLowerCase()]??3,a=wd[(r.priority??"").toLowerCase()]??3;return s!==a?s-a:n.slug.localeCompare(r.slug)})[0]}function bd(e,t,n){if(t>0)return null;let r=hx(e);if(!r)return null;let o=r.role?` (${r.role})`:"";return`Next: no article yet \u2014 write .seoagent/briefs/${r.slug}.md${o} first, then run \`${n("content track")} <path-to-article>\` so the board advances. ${e.length} brief${e.length===1?"":"s"} waiting.`}function kd(e){let t={briefs:[],articleCount:0};try{let n=Rs(e,"briefs");if(md(n))for(let o of hd(n).filter(i=>i.endsWith(".md"))){let s=tt(Rs(n,o))?.data??{};t.briefs.push({slug:o.replace(/\.md$/,""),role:typeof s.role=="string"?s.role:null,priority:typeof s.priority=="string"?s.priority:null,status:typeof s.status=="string"?s.status:null})}let r=Rs(e,"content");md(r)&&(t.articleCount=hd(r).filter(o=>o.endsWith(".md")).length)}catch{}return t}var yx=1500;function wx(e=process.env){switch(Pr(e)){case"absent":return"sync_unauthenticated";case"malformed":return"sync_unauthenticated_malformed";default:return null}}function bx(e){try{let n=A(e)?.domain?.trim();return!n||n.toLowerCase()==="unknown"?null:n}catch{return null}}async function xd(e){let t=e.env??process.env,n=wx(t);if(!n)return{sent:!1,event:null,skipped:"authenticated",throwawayInstallId:!1};if(be(t))return{sent:!1,event:n,skipped:"opted-out",throwawayInstallId:!1};let r=null;try{r=Ee(e.cwd)}catch{r=null}let o=!r,i=bx(e.cwd),s=i?{domain:i}:null;return{sent:await Qe({installId:r??ht(),event:n,cliVersion:I,meta:s,apiBase:e.apiBase,fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??yx}),event:n,throwawayInstallId:o,domain:i}}import{isAbsolute as vd,relative as kx,resolve as _d,sep as xx}from"path";var vx=new Set(["posttooluse","afterfileedit"]),_x=120*1e3,$x=250;function Sx(e){let t=e.trim();if(!t.startsWith("{"))return null;try{let n=JSON.parse(t),r=typeof n.hook_event_name=="string"?n.hook_event_name:null,o=n.tool_input??null,i=o&&typeof o.file_path=="string"&&o.file_path.length>0?o.file_path:typeof n.file_path=="string"&&n.file_path.length>0?n.file_path:null;return!r&&!i?null:{event:r,filePath:i}}catch{return null}}function Es(e){return!!e?.event&&vx.has(e.event.toLowerCase())}function $d(e){return!!e?.event&&e.event.toLowerCase()==="sessionstart"}function Rx(e,t){let n=vd(e)?e:_d(t,e),r=kx(_d(t,x),n);return r===""||!r.startsWith("..")&&!vd(r)&&!r.startsWith(`..${xx}`)}function Sd(e){if(!Es(e.input)||e.input?.filePath&&Rx(e.input.filePath,e.projectDir)||!e.lastRunAt)return!1;let t=Date.parse(e.lastRunAt);if(!Number.isFinite(t))return!1;let n=e.now??Date.now();return n-t>=0&&n-t<(e.minGapMs??_x)}function Ex(e){return e.replace(/\u001b\[[0-9;]*m/g,"")}function Rd(e){let t=Ex(e).trim();return t?JSON.stringify({hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:t}}):null}async function Ed(e=process.stdin,t=$x){return e.isTTY?null:new Promise(n=>{let r="",o=!1,i=()=>{if(!o){o=!0,clearTimeout(a),e.removeListener("data",s),e.removeListener("end",i),e.removeListener("error",i);try{e.pause(),e.unref?.()}catch{}n(Sx(r))}},s=l=>{r+=l.toString(),r.length>1e6&&i()},a=setTimeout(i,t);try{e.setEncoding?.("utf-8"),e.on("data",s),e.once("end",i),e.once("error",i),e.resume()}catch{i()}})}var Px=new Set(["no-auth","no-project","domain-unknown","project-mismatch","unverified"]);function Cs(e){return Px.has(e)}var Ix=new Set(["inbox-write","done"]);function Tx(e,t,n){let r=Math.round(t/1e3),o=e!==null&&Ix.has(e),i=e?` during the ${e} pass`:"";return o?{text:`Sync gave up after ${r}s${i} (network too slow or stalled). Pushed files are remembered; the rest goes on the next run.`,inboxRefreshed:o}:{text:`Sync gave up after ${r}s${i} \u2014 pending dashboard actions were NOT pulled this run, so .seoagent/inbox/ and \`${n("inbox")}\` may be stale. Run \`${n("pull")}\` to refresh them; pushed files are remembered and the rest goes on the next sync.`,inboxRefreshed:o}}function Ox(e,t){return e==="malformed"?`SEOAGENT_AUTH is set but is not \`<user_token>:<website_token>\` - nothing was synced and no work was pulled. Run \`${t("whoami")} --env\` on the machine that is logged in, store its output as the secret exactly (no quotes, and without the \`SEOAGENT_AUTH=\` prefix inside the value), then run \`${t("sync")}\` again.`:`Not logged in - nothing was synced and no work was pulled. This directory is not connected to SEOAgent. Fix: run \`${t("login")} --code <code>\` here (get a code at seoagent.com/grok or from the dashboard install prompt), then \`${t("sync")}\` again. Scheduled run? Export the SEOAGENT_AUTH secret before this command (\`${t("whoami")} --env\` on the logged-in machine prints it).`}function Cd(e,t=e.length){let n=e.slice(0,5).map(o=>` - ${o.title||o.action_type} (id ${o.id})`).join(`
1113
+ `):t}function ad(e,t){if(!e)return[];let n=[],r=[];return e.llmsPublished&&r.push(e.llmsPublished),e.okfPublishedDir&&r.push(`${e.okfPublishedDir}/ (${e.okfPublished} file${e.okfPublished===1?"":"s"})`),r.length>0&&n.push({text:`ai-files: published ${r.join(" and ")} \u2014 commit these so answer engines can read them.`,tone:"dim",always:!0}),e.skipped.includes("okf-placeholder")&&n.push({text:"ai-files: .seoagent/okf/ is still the scaffold. Fill it (see references/open-knowledge-format.md) and it publishes itself on the next sync.",tone:"dim",always:!1}),e.skipped.includes("okf-invalid")&&n.push({text:`ai-files: .seoagent/okf/ has validation errors, so it was NOT published. Run \`${t("okf validate")}\` and fix them.`,tone:"warn",always:!1}),e.llmsRouteDrift&&n.push({text:`ai-files: .seoagent/llms.md changed, but ${e.llmsRoute} already serves /llms.txt, so nothing was published \u2014 a file in your static dir would shadow that route. Compare the two, or set \`llms_owner: route\` in .seoagent/project.md to own the file yourself and stop this notice.`,tone:"dim",always:!1}),e.skipped.includes("no-public-dir")&&n.push({text:"ai-files: couldn't tell which directory this project serves as static files. Set `public_dir:` in .seoagent/project.md (`public`, `static`, or a nested path like `apps/web/public` in a monorepo) so llms.txt and the OKF bundle actually get served.",tone:"dim",always:!1}),n}var gk=30,mk=/<(script|style|noscript|template|svg|nav|header|footer)\b[^>]*>[\s\S]*?<\/\1>/gi;function hk(e){let t=e,n=/<body\b[^>]*>([\s\S]*?)<\/body>/i.exec(t);n&&(t=n[1]),t=t.replace(mk," ").replace(/<!--[\s\S]*?-->/g," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/gi," ").replace(/&[a-z]+;/gi," ").replace(/\s+/g," ").trim();let r=t===""?0:t.split(" ").filter(Boolean).length;return{wordCount:r,rendered:r<gk?"empty":"yes"}}async function yk(e,t){try{let n=await F(e,{headers:{"user-agent":"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) SEOAgent-CLI"},redirect:"follow"},{attempts:2,timeoutMs:1e4,fetchImpl:t});if(!n.ok)return{status:n.status,rendered:"error",wordCount:0};let r=await n.text(),{wordCount:o,rendered:i}=hk(r);return{status:n.status,rendered:i,wordCount:o}}catch{return{status:null,rendered:"error",wordCount:0}}}async function ld(e,t={}){let n=Math.max(1,t.concurrency??5),r=new Map,o=[...e],i=0;async function s(){for(;;){let a=o.shift();if(a===void 0)return;r.set(a,await yk(a,t.fetchImpl)),i+=1,t.onProgress?.(i,e.length)}}return await Promise.all(Array.from({length:Math.min(n,e.length)},()=>s())),r}var vs=300;async function Hn(e,t={}){try{let n=A(e),r=n?.domain&&n.domain!=="unknown"?n.domain:null,{pages:o}=Ue(e,r);t.enrichSitemap&&r&&await ic(o,r);let i,s;if(t.crawl&&r){let l=o.map(u=>u.url).filter(u=>/^https?:\/\//.test(u)),c=l.slice(0,vs);if(l.length>vs&&d.info(`Crawling the first ${vs} of ${l.length} pages (cap).`),c.length>0){d.info(`Crawling ${c.length} page${c.length===1?"":"s"}\u2026`),s=await ld(c);let u=0,p=0;for(let g of s.values())g.rendered==="empty"?u++:g.rendered==="error"&&p++;i={crawled:s.size,empty:u,errors:p}}}let a=Gr(e,o,s);return{added:a.added,total:a.total,file:a.file,crawl:i}}catch{return{added:0,total:0,file:"pages.md"}}}function vk(e){try{let t=en(e);return t.evidenceFound?t:void 0}catch{return}}var _k=new Set([".md"]),$k=new Set(["inbox"]);function Sk(e){let t=[];function n(r,o){if(_s(r))for(let i of bk(r,{withFileTypes:!0})){if(i.name.startsWith(".")||o===""&&$k.has(i.name))continue;let s=$s(r,i.name);if(i.isDirectory())n(s,o?`${o}/${i.name}`:i.name);else if(i.isFile()){let a=i.name.lastIndexOf("."),l=a===-1?"":i.name.slice(a);_k.has(l)&&t.push(s)}}}return n(e,""),t}var Rk=14400*1e3;function Ek(e,t){return kk(e,t).split(xk).join("/")}async function Ck(e,t){try{let n=await F(`${e}/api/cli/actions/fetch`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:t,...jc()},body:JSON.stringify({})});if(!n.ok){let o=await n.text().catch(()=>"");return{ok:!1,actions:[],declined:[],error:`${n.status} ${o.slice(0,200)}`}}let r=await n.json().catch(()=>null);return!r||r.status!=="ok"||!Array.isArray(r.actions)?{ok:!1,actions:[],declined:[],error:"Malformed response"}:{ok:!0,actions:r.actions,declined:is(r.declined)}}catch(n){return{ok:!1,actions:[],declined:[],error:n.message}}}async function cd(e,t,n){try{let r=await F(`${e}/api/cli/sync`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:n},body:JSON.stringify(t)});if(!r.ok){let i=await r.text().catch(()=>"");return{ok:!1,status:r.status,error:i.slice(0,200)}}let o=typeof r.json=="function"?await r.json().catch(()=>null):null;return{ok:!0,status:r.status,...o?.agent_notice?{agentNotice:o.agent_notice}:{}}}catch(r){return{ok:!1,status:0,error:r.message}}}var Ak=12e3;function Pk(e,t){return e===void 0?!1:t>=e-Ak}var Ik=6,Tk=new Set(["briefs","content","okf"]);function Ok(e){let t=[],n=null;for(let r of e){let o=r.rel.indexOf("/"),i=o===-1?null:r.rel.slice(0,o),s=i!==null&&Tk.has(i);s&&i===n?t[t.length-1].push(r):(t.push([r]),n=s?i:null)}return t}async function vo(e,t={}){let n=vk(e),r=u=>{let p=n?{...u,verifyRecs:n}:{...u};return s&&(p={...p,aiFiles:s}),i&&i.added>0&&(p={...p,pagesRescan:{added:i.added,total:i.total,file:i.file}}),p},o=A(e),i=null;if(o&&!t.pullOnly)try{i=await Hn(e)}catch{}if(o?.domain&&o.domain!==Ze)try{eu(e,o)}catch{}let s=null;if(o)try{s=nn(e,o)}catch{}let a=B(o?.domain);if(!a)return r({ok:!0,reason:"no-auth",synced:0,failed:0,errors:[]});if(!o)return r({ok:!0,reason:"no-project",synced:0,failed:0,errors:[]});if(o.domain===Ze)return r({ok:!0,reason:"domain-unknown",synced:0,failed:0,errors:[]});let l=$s(e,x);if(!_s(l))return r({ok:!0,reason:"no-project",synced:0,failed:0,errors:[]});if(!nd(e).acquired)return r({ok:!0,reason:"busy",synced:0,failed:0,errors:[]});try{return r(await Lk(e,t,a,o,l))}finally{bo(e)}}async function Lk(e,t,n,r,o){let i=n.api_base||M.BASE,s=`Bearer ${n.user_token}:${n.website_token}`;t.onPhase?.("binding");let a=await rt({apiBase:i,authHeader:s,localDomain:r.domain});if(a.verdict==="mismatch")return{ok:!0,reason:"project-mismatch",synced:0,failed:0,errors:[],cloudDomain:a.cloudDomain,localDomain:r.domain};if(a.verdict==="unverified")return{ok:!0,reason:"unverified",synced:0,failed:0,errors:[`could not verify cloud project binding: ${a.detail}`]};let l=Un(r.domain),c=Sk(o),u=0,p=0,g=[],f=[],y=0;t.onPhase?.("ack-flush");let m=await jk(e,i,s),w={restored:!1,blockPush:!1,notices:[]};(!t.pathFilter||"context.md".endsWith(t.pathFilter))&&(w=await Ku({seoagentDir:o,apiBase:i,authHeader:s,stateFiles:l.files,force:t.force,forcePaths:t.forcePaths}),g.push(...w.notices));let k=0;if(!t.pullOnly){t.onPhase?.("push");for(let J of t.deletedPaths??[]){y++;let ce=await cd(i,{path:J,domain:r.domain,deleted:!0},s);ce.ok?(delete l.files[J],u++,ho(r.domain,l)):(p++,f.push(`${J}: ${ce.status} ${ce.error??""}`.trim()))}let K=[];for(let J of c){let ce=Ek(o,J);if(t.pathFilter&&!ce.endsWith(t.pathFilter)||ce==="context.md"&&w.blockPush)continue;let De=wk(J,"utf-8"),ye=_e(De),we=l.files[ce];!(!we||we.hash!==ye)&&!t.force||K.push({rel:ce,contents:De,hash:ye})}let q=async({rel:J,contents:ce,hash:De})=>{y++;let ye=await cd(i,{path:J,contents:ce,domain:r.domain},s);ye.ok?(l.files[J]={hash:De},u++,ye.agentNotice&&g.push(`${J}: ${ye.agentNotice}`),ho(r.domain,l)):(p++,f.push(`${J}: ${ye.status} ${ye.error??""}`.trim()))},Z=0;for(let J of Ok(K)){let ce=0,De=async()=>{for(;ce<J.length&&!Pk(t.deadlineAt,Date.now());){let ye=J[ce++];Z++,await q(ye)}};if(await Promise.all(Array.from({length:Math.min(Ik,J.length)},De)),ce<J.length)break}Z<K.length&&(k=K.length-Z)}t.onPhase?.("inbox-pull");let S=await Ck(i,s),T=0,b=0,v=[],R=0,D=0;!S.ok&&S.error&&f.push(`pull actions: ${S.error}`);let _,N=[],V=new Map,U=!1,re=[],Y=l.last_synced_at,Lt=Uu(l.last_synced_at,Bu(o)),Q=!1;if(!t.pushOnly){t.onPhase?.("artifact-pull");let K=await Wu({projectDir:e,apiBase:i,authHeader:s,since:Lt,stateFiles:l.files,force:t.force,forcePaths:t.forcePaths,meta:Nk(e,!!t.silent)});re=K.directives??[],K.ok?(Y=K.cursor,Q=!0):(U=!0,K.error&&f.push(`pull: ${K.error}`)),_={written:K.written,overwritten:K.overwritten,skipped:K.skipped,conflicts:K.conflicts,deleted:K.deleted,warnings:K.warnings},N=K.conflictPaths;for(let[q,Z]of Object.entries(K.pointerOverwrites)){let J=q.match(/^content\/(.+)\.md$/)?.[1];J&&V.set(J,Z)}}if(S.ok&&!t.pushOnly&&!U){let K=new Set(N),q=[...ls(S.actions).keys()].filter(Z=>!K.has(Z)&&!_s($s(o,Z)));if(q.length>0){t.onPhase?.("draft-heal");let Z=await Gu({projectDir:e,apiBase:i,authHeader:s,paths:q,stateFiles:l.files});if(_&&(_.written+=Z.written.length),!Z.ok&&Z.error&&f.push(`pull drafts: ${Z.error}`),Z.absent.length>0&&_)for(let J of Z.absent)_.warnings.push(`${J}: an inbox task points at this draft, but the cloud has no copy of it`)}}if(S.ok){t.onPhase?.("inbox-write");let K=as(e);for(let[we,gt]of V)K.set(we,gt);let q=gu(e,S.actions,{conflictedPaths:new Set(N),localPointers:K,declined:S.declined});T=q.wrote,b=q.removed,R=q.skippedUnknown;let Z=l.announced_at?Date.parse(l.announced_at):NaN,ce=q.pendingIds.length>0&&(Number.isNaN(Z)||Date.now()-Z>=Rk)?new Set:new Set(l.announced_action_ids??[]),De=new Set(q.pendingIds.filter(we=>!ce.has(we)));v=q.pending.filter(we=>De.has(we.id)),D=De.size-v.length,l.announced_action_ids=q.pendingIds,De.size>0&&(l.announced_at=new Date().toISOString()),l.inbox_pulled_at=new Date().toISOString();let ye=ls(S.actions);_&&N.length>0&&(_.warnings=_.warnings.map(we=>{let gt=N.find(zo=>we.startsWith(`${zo}:`)),Yo=gt?ye.get(gt):void 0;return!gt||!Yo?.length?we:`${we} \u2014 blocks inbox action${Yo.length===1?"":"s"} ${Yo.map(zo=>`#${zo}`).join(", ")}; take the cloud copy with \`seoagent sync --force ${gt}\``}))}let Nt=!!_&&_.written+_.overwritten+_.deleted+_.conflicts>0;if(l.last_synced_at=Y,l.last_run_at=new Date().toISOString(),ho(r.domain,l),Q&&Hu(o,Y),t.onPhase?.("done"),y===0&&k===0&&T===0&&b===0&&!Nt&&!w.restored&&w.notices.length===0&&m.flushed===0&&m.dropped===0&&!U&&p===0)return{ok:!0,reason:"no-changes",synced:0,failed:0,errors:f,actionsPulled:0,actionsRemoved:0,actionsNew:[],actionsUnknown:R,actionsUnknownNew:D,acksFlushed:0,acksDropped:0,pull:_,directives:re};let Ne=p===0&&!U;return{ok:Ne,reason:Ne?void 0:"error",synced:u,failed:p,errors:f,...g.length>0?{notices:g}:{},...k>0?{pushDeferred:k}:{},actionsPulled:T,actionsRemoved:b,actionsNew:v,actionsUnknown:R,actionsUnknownNew:D,acksFlushed:m.flushed,acksDropped:m.dropped,pull:_,directives:re}}function Nk(e,t){let n=be(),r=n?null:A(e)?.install_id??null;return{cliVersion:n?null:I,agent:Dc(),authSource:Ar(),installId:r||null,silent:t,...n?{}:Dk(e)}}function Dk(e){let t=Xr(e);return t?{repo:t}:{}}async function jk(e,t,n){let r=yo(e);if(r.length===0)return{flushed:0,dropped:0};let o=0,i=0,s=[];for(let a of r){let l=await Fk(a,t,n);l==="flushed"?(o++,s.push(a.action_id)):l==="already-settled"&&(i++,s.push(a.action_id))}return s.length>0&&Zu(e,s),{flushed:o,dropped:i}}async function Fk(e,t,n){try{let r=await F(`${t}/api/cli/actions/${e.action_id}/ack`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:n},body:JSON.stringify({status:e.status,error_message:e.status==="failed"?e.reason:null,result:e.status==="failed"?{declined:!0,reason:e.reason}:{applied:!0,...e.details??{}}})});return r.ok?"flushed":r.status===409||r.status>=400&&r.status<500?"already-settled":"transient"}catch{return"transient"}}function ud(e,t=3e4){let n=Date.now()+t,r=setTimeout(e,t);return r.unref?.(),{cancel:()=>clearTimeout(r),deadlineAt:n}}function dt(e,t){let n=i=>i.replace(/[-+].*$/,"").split(".").map(s=>Number.parseInt(s,10)||0).slice(0,3),r=n(e),o=n(t);for(let i=0;i<3;i++){let s=(r[i]??0)-(o[i]??0);if(s!==0)return s}return 0}function dd(e){let t;try{t=A(e)}catch{return{refreshed:!1,reason:"error"}}if(!t)return{refreshed:!1,reason:"no-project"};if(bt(e))return{refreshed:!1,reason:"source-repo"};let n=t.skill_version||t.seoagent_version||"0.0.0";if(dt(I,n)<=0){if(!t.skill_version)try{X(e,{skill_version:n})}catch{}return{refreshed:!1,reason:"up-to-date"}}try{return Ut(e),X(e,{skill_version:I}),{refreshed:!0,from:n,to:I,reason:"refreshed"}}catch{return{refreshed:!1,reason:"error"}}}function Ss(e){let t;try{t=A(e)}catch{return{refreshed:!1,from:null,to:I,reason:"error"}}if(!t)return{refreshed:!1,from:null,to:I,reason:"no-project"};if(bt(e))return{refreshed:!1,from:null,to:I,reason:"source-repo"};let n=t.skill_version||t.seoagent_version||null;try{return Ut(e),X(e,{skill_version:I}),{refreshed:!0,from:n,to:I,reason:"refreshed"}}catch{return{refreshed:!1,from:n,to:I,reason:"error"}}}import{createHash as Mk}from"crypto";import{existsSync as gI,mkdirSync as Uk,readFileSync as Bk,writeFileSync as Hk}from"fs";import{join as Gk}from"path";var Wk="/cli-skill/manifest.json",Kk=360*60*1e3,qk=4e3,Vk=64,Yk=4*1024*1024,pd=Gk(ee,"skill-check.json"),zk=e=>Mk("sha256").update(e).digest("hex");function Jk(e){if(typeof e!="object"||e===null)return null;let t=e;if(typeof t.hash!="string"||!/^[0-9a-f]{64}$/.test(t.hash)||typeof t.min_cli!="string"||!/^\d+\.\d+\.\d+/.test(t.min_cli)||!Array.isArray(t.files)||t.files.length===0||t.files.length>Vk)return null;let n=[],r=0;for(let o of t.files){if(typeof o!="object"||o===null)return null;let i=o;if(typeof i.path!="string"||typeof i.sha256!="string"||!/^[A-Za-z0-9._/-]+$/.test(i.path)||i.path.startsWith("/")||i.path.split("/").includes("..")||!i.path.endsWith(".md")||!/^[0-9a-f]{64}$/.test(i.sha256))return null;let s=typeof i.bytes=="number"?i.bytes:0;r+=s,n.push({path:i.path,sha256:i.sha256,bytes:s})}return r>Yk||!n.some(o=>o.path==="SKILL.md")?null:{hash:t.hash,min_cli:t.min_cli,files:n}}function Xk(e,t,n=Kk){if(!e)return!0;let r=Date.parse(e);return Number.isNaN(r)?!0:t.getTime()-r>=n}function Qk(){try{return JSON.parse(Bk(pd,"utf-8"))}catch{return{}}}function Zk(e){try{Uk(ee,{recursive:!0}),Hk(pd,JSON.stringify({checkedAt:e}),"utf-8")}catch{}}async function ex(e){try{let t=await fetch(e,{signal:AbortSignal.timeout(qk),headers:{"User-Agent":`seoagent-cli/${I}`}});return t.ok?await t.text():null}catch{return null}}async function fd(e,t={}){try{let n=A(e);if(!n)return{updated:!1,reason:"no-project"};if(bt(e))return{updated:!1,reason:"source-repo"};let r=t.now??new Date,o=Qk();if(!t.force&&!Xk(o.checkedAt,r))return{updated:!1,reason:"throttled"};let i=(t.baseUrl??M.BASE).replace(/\/$/,""),s=t.fetchText??ex,a=await s(`${i}${Wk}`);if(Zk(r.toISOString()),a===null)return{updated:!1,reason:"unreachable"};let l;try{l=Jk(JSON.parse(a))}catch{l=null}if(!l)return{updated:!1,reason:"malformed"};if(n.skill_hash===l.hash)return{updated:!1,reason:"up-to-date"};if(dt(I,l.min_cli)<0)return{updated:!1,reason:"cli-too-old",minCli:l.min_cli};let c={};for(let u of l.files){let p=await s(`${i}/cli-skill/${u.path}`);if(p===null)return{updated:!1,reason:"unreachable"};if(zk(p)!==u.sha256)return{updated:!1,reason:"verify-failed"};c[u.path]=p}return al(e,c),X(e,{skill_hash:l.hash}),{updated:!0,reason:"updated",fileCount:l.files.length}}catch{return{updated:!1,reason:"error"}}}import{existsSync as tx,mkdirSync as nx,readFileSync as rx,writeFileSync as ox}from"fs";var ix="https://registry.npmjs.org/@seoagent-official/seoagent/latest",sx=1440*60*1e3,ax=720*60*1e3,lx=2e3;function cx(e,t,n=sx){if(!e.checkedAt)return!0;let r=Date.parse(e.checkedAt);return Number.isNaN(r)?!0:t.getTime()-r>=n}function ux(e){let{current:t,latest:n,cache:r,now:o}=e,i=e.notifyIntervalMs??ax;if(!n||dt(n,t)<=0)return null;if(r.notifiedVersion===n&&r.notifiedAt){let s=Date.parse(r.notifiedAt);if(!Number.isNaN(s)&&o.getTime()-s<i)return null}return`\u2191 SEOAgent ${n} is available (you have ${t}). Ask me to run \`seoagent update-cli\`, or run it yourself, to upgrade the CLI + all your projects.`}async function dx(e){let t=e.readCache();if(cx(t,e.now,e.checkIntervalMs)){let r=await e.fetchLatest();t={...t,checkedAt:e.now.toISOString(),...r?{latest:r}:{}},e.writeCache(t)}let n=ux({current:e.current,latest:t.latest,cache:t,now:e.now,notifyIntervalMs:e.notifyIntervalMs});return n&&t.latest&&e.writeCache({...t,notifiedVersion:t.latest,notifiedAt:e.now.toISOString()}),n}function px(){try{return tx(hr)?JSON.parse(rx(hr,"utf-8")):{}}catch{return{}}}function fx(e){try{nx(ee,{recursive:!0}),ox(hr,JSON.stringify(e,null,2)+`
1114
+ `,"utf-8")}catch{}}async function gx(){try{let e=await fetch(ix,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(lx)});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}async function gd(e){try{return await dx({current:e,now:new Date,fetchLatest:gx,readCache:px,writeCache:fx})}catch{return null}}import{existsSync as md,readdirSync as hd}from"fs";import{join as Rs}from"path";var yd={PILLAR:0,SUB_PILLAR:1,LONG_TAIL:2},wd={high:0,medium:1,low:2},mx=new Set(["drafted","published","dismissed","superseded","done"]);function hx(e){let t=e.filter(n=>!mx.has((n.status??"").toLowerCase()));return t.length===0?null:[...t].sort((n,r)=>{let o=yd[(n.role??"").toUpperCase()]??3,i=yd[(r.role??"").toUpperCase()]??3;if(o!==i)return o-i;let s=wd[(n.priority??"").toLowerCase()]??3,a=wd[(r.priority??"").toLowerCase()]??3;return s!==a?s-a:n.slug.localeCompare(r.slug)})[0]}function bd(e,t,n){if(t>0)return null;let r=hx(e);if(!r)return null;let o=r.role?` (${r.role})`:"";return`Next: no article yet \u2014 write .seoagent/briefs/${r.slug}.md${o} first, then run \`${n("content track")} <path-to-article>\` so the board advances. ${e.length} brief${e.length===1?"":"s"} waiting.`}function kd(e){let t={briefs:[],articleCount:0};try{let n=Rs(e,"briefs");if(md(n))for(let o of hd(n).filter(i=>i.endsWith(".md"))){let s=nt(Rs(n,o))?.data??{};t.briefs.push({slug:o.replace(/\.md$/,""),role:typeof s.role=="string"?s.role:null,priority:typeof s.priority=="string"?s.priority:null,status:typeof s.status=="string"?s.status:null})}let r=Rs(e,"content");md(r)&&(t.articleCount=hd(r).filter(o=>o.endsWith(".md")).length)}catch{}return t}var yx=1500;function wx(e=process.env){switch(Pr(e)){case"absent":return"sync_unauthenticated";case"malformed":return"sync_unauthenticated_malformed";default:return null}}function bx(e){try{let n=A(e)?.domain?.trim();return!n||n.toLowerCase()==="unknown"?null:n}catch{return null}}async function xd(e){let t=e.env??process.env,n=wx(t);if(!n)return{sent:!1,event:null,skipped:"authenticated",throwawayInstallId:!1};if(be(t))return{sent:!1,event:n,skipped:"opted-out",throwawayInstallId:!1};let r=null;try{r=Ee(e.cwd)}catch{r=null}let o=!r,i=bx(e.cwd),s=i?{domain:i}:null;return{sent:await Qe({installId:r??ht(),event:n,cliVersion:I,meta:s,apiBase:e.apiBase,fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??yx}),event:n,throwawayInstallId:o,domain:i}}import{isAbsolute as vd,relative as kx,resolve as _d,sep as xx}from"path";var vx=new Set(["posttooluse","afterfileedit"]),_x=120*1e3,$x=250;function Sx(e){let t=e.trim();if(!t.startsWith("{"))return null;try{let n=JSON.parse(t),r=typeof n.hook_event_name=="string"?n.hook_event_name:null,o=n.tool_input??null,i=o&&typeof o.file_path=="string"&&o.file_path.length>0?o.file_path:typeof n.file_path=="string"&&n.file_path.length>0?n.file_path:null;return!r&&!i?null:{event:r,filePath:i}}catch{return null}}function Es(e){return!!e?.event&&vx.has(e.event.toLowerCase())}function $d(e){return!!e?.event&&e.event.toLowerCase()==="sessionstart"}function Rx(e,t){let n=vd(e)?e:_d(t,e),r=kx(_d(t,x),n);return r===""||!r.startsWith("..")&&!vd(r)&&!r.startsWith(`..${xx}`)}function Sd(e){if(!Es(e.input)||e.input?.filePath&&Rx(e.input.filePath,e.projectDir)||!e.lastRunAt)return!1;let t=Date.parse(e.lastRunAt);if(!Number.isFinite(t))return!1;let n=e.now??Date.now();return n-t>=0&&n-t<(e.minGapMs??_x)}function Ex(e){return e.replace(/\u001b\[[0-9;]*m/g,"")}function Rd(e){let t=Ex(e).trim();return t?JSON.stringify({hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:t}}):null}async function Ed(e=process.stdin,t=$x){return e.isTTY?null:new Promise(n=>{let r="",o=!1,i=()=>{if(!o){o=!0,clearTimeout(a),e.removeListener("data",s),e.removeListener("end",i),e.removeListener("error",i);try{e.pause(),e.unref?.()}catch{}n(Sx(r))}},s=l=>{r+=l.toString(),r.length>1e6&&i()},a=setTimeout(i,t);try{e.setEncoding?.("utf-8"),e.on("data",s),e.once("end",i),e.once("error",i),e.resume()}catch{i()}})}var Px=new Set(["no-auth","no-project","domain-unknown","project-mismatch","unverified"]);function Cs(e){return Px.has(e)}var Ix=new Set(["inbox-write","done"]);function Tx(e,t,n){let r=Math.round(t/1e3),o=e!==null&&Ix.has(e),i=e?` during the ${e} pass`:"";return o?{text:`Sync gave up after ${r}s${i} (network too slow or stalled). Pushed files are remembered; the rest goes on the next run.`,inboxRefreshed:o}:{text:`Sync gave up after ${r}s${i} \u2014 pending dashboard actions were NOT pulled this run, so .seoagent/inbox/ and \`${n("inbox")}\` may be stale. Run \`${n("pull")}\` to refresh them; pushed files are remembered and the rest goes on the next sync.`,inboxRefreshed:o}}function Ox(e,t){return e==="malformed"?`SEOAGENT_AUTH is set but is not \`<user_token>:<website_token>\` - nothing was synced and no work was pulled. Run \`${t("whoami")} --env\` on the machine that is logged in, store its output as the secret exactly (no quotes, and without the \`SEOAGENT_AUTH=\` prefix inside the value), then run \`${t("sync")}\` again.`:`Not logged in - nothing was synced and no work was pulled. This directory is not connected to SEOAgent. Fix: run \`${t("login")} --code <code>\` here (get a code at seoagent.com/grok or from the dashboard install prompt), then \`${t("sync")}\` again. Scheduled run? Export the SEOAGENT_AUTH secret before this command (\`${t("whoami")} --env\` on the logged-in machine prints it).`}function Cd(e,t=e.length){let n=e.slice(0,5).map(o=>` - ${o.title||o.action_type} (id ${o.id})`).join(`
1115
1115
  `),r=t>5?`
1116
1116
  \u2026 and ${t-5} more`:"";return`inbox: ${t} pending SEOAgent action${t===1?"":"s"} waiting in .seoagent/inbox/:
1117
1117
  ${n}${r}
@@ -1122,8 +1122,8 @@ ${n}${r}
1122
1122
  ${o}`);let s=await zx({message:"Remove these and start fresh?"});if(Jx(s)||!s){Xx("Cancelled \u2014 nothing was removed.");return}}Ud(t,n);let i=n.map(s=>` \u2713 ${s.label}`).join(`
1123
1123
  `);r?d.success(`Removed:
1124
1124
  ${i}`):Yx(`Removed:
1125
- ${i}`),!e.global&&Bd(ee)&&d.info("Your seoagent.com login (~/.config/seoagent/) was kept \u2014 it is shared across projects. Run `uninstall --global` to wipe it too."),d.info(`Re-install any time with \`${h("init")}\`.`)}import j from"picocolors";import{existsSync as Kn,readdirSync as Ps,statSync as Qx,readFileSync as Hd}from"fs";import{join as on}from"path";function Zx(e){let t=(e.match(/^\s*-\s+\[\s\]/gm)??[]).length,n=(e.match(/^\s*-\s+\[x\]/gim)??[]).length;return{open:t,done:n}}function ev(e){let t=on(e,"audit","latest.md");if(!Kn(t))return null;let n=tt(t);if(!n)return null;let r=Hd(t,"utf-8"),o=Zx(r);return{exists:!0,date:typeof n.data.audited_at=="string"?n.data.audited_at:void 0,issueCount:o.open}}function tv(e){try{let n=Hd(e,"utf-8").split(/\r?\n/),r=!1,o=0;for(let i of n){let s=i.trim();if(s.startsWith("|")&&s.endsWith("|")){if(/^\|\s*-+\s*(\|\s*-+\s*)+\|$/.test(s)){r=!0;continue}r&&o++}else if(r&&s==="")break}return o}catch{return 0}}function nv(e){let t=on(e,"strategy","clusters");if(!Kn(t))return null;let n=Ps(t).filter(o=>o.endsWith(".md"));if(n.length===0)return null;let r=0;for(let o of n)r+=tv(on(t,o));return{exists:!0,clusterCount:n.length,articleCount:r}}function rv(e){let t=on(e,"briefs");if(!Kn(t))return null;let n=Ps(t).filter(r=>r.endsWith(".md"));return n.length>0?{exists:!0,count:n.length}:null}function ov(e){let t=on(e,"content");if(!Kn(t))return null;let n=Ps(t).filter(r=>r.endsWith(".md"));return n.length===0?null:{exists:!0,count:n.length}}function iv(e){let t=on(e,"roadmap.md");return Kn(t)?{exists:!0,updatedAt:Qx(t).mtime.toISOString()}:null}function Gd(e){let t=A(e);if(!t)return null;let n=Xe(e);return{domain:t.domain,audit:ev(n),strategy:nv(n),briefs:rv(n),content:ov(n),roadmap:iv(n)}}import pt from"picocolors";var Wd=/\x1b\[[0-9;]*m/g;function qn(e){return e.replace(Wd,"").length}var sv=51,av=24,lv=80;function cv(e,t,n=sv){let r=0;for(let c of e)"sep"in c||(r=Math.max(r,qn(c.content)));let o=t?qn(t)+6:0,i=Math.max(n,r+4,o),s=process.stdout?.columns,a=(typeof s=="number"&&s>0?s:lv)-2,l=Math.max(av,a);return Math.min(i,l)}function uv(e,t){if(qn(e)<=t)return e;if(t<=0)return"";let n=t-1,r="",o=0,i=!1,s=u=>{for(let p of u){if(o+p.length>n)return;r+=p,o+=p.length}},a=new RegExp(Wd.source,"g"),l=0,c;for(;(c=a.exec(e))!==null;)s(e.slice(l,c.index)),r+=c[0],i=!0,l=c.index+c[0].length;return s(e.slice(l)),`${r}\u2026${i?"\x1B[0m":""}`}function z(e,t={}){let n=cv(e,t.title,t.width),r=n-4,o="\u2500".repeat(n-2),i=dv(n,t.title),s=pt.dim(`\u251C${o}\u2524`),a=pt.dim(`\u2514${o}\u2518`),l=[i];for(let c of e){if("sep"in c){l.push(s);continue}l.push(pv(c.content,r))}return l.push(a),l.join(`
1126
- `)}function dv(e,t){if(!t)return pt.dim(`\u250C${"\u2500".repeat(e-2)}\u2510`);let n=qn(t),r=e-5-n;return r<1?pt.dim(`\u250C${"\u2500".repeat(e-2)}\u2510`):`${pt.dim("\u250C\u2500 ")}${t}${pt.dim(` ${"\u2500".repeat(r)}\u2510`)}`}function pv(e,t){let n=qn(e),r=n<=t?e+" ".repeat(t-n):uv(e,t);return`${pt.dim("\u2502")} ${r} ${pt.dim("\u2502")}`}function Is(e){let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4);if(n<60)return`${n} minutes ago`;let r=Math.floor(n/60);return r<24?`${r} hours ago`:`${Math.floor(r/24)} days ago`}function Vn(){let e=Gd(process.cwd());if(!e){d.warn("No SEOAgent project found in this directory."),d.info(`Run \`${h("init")}\` to get started.`);return}d.message(fv(e))}function fv(e){if(!e)return"";let t=11,n=s=>j.dim(s.padEnd(t)),r=[];B(e.domain)?(r.push({content:`${j.green("\u2713")} ${j.dim("Logged in")}`}),r.push({content:j.dim(` Run \`${h("whoami")}\` for email / plan.`)})):(r.push({content:`${j.dim("\u25CB Not logged in")}`}),r.push({content:j.dim(` Run \`${h("login")}\` to connect.`)})),r.push({sep:!0}),r.push({content:e.audit?.exists?`${n("Audit:")}${j.green(`last run ${Is(e.audit.date??"")}`)} ${j.dim(`(${e.audit.issueCount??0} issues)`)}`:`${n("Audit:")}${j.dim("not yet run")}`}),r.push({content:e.strategy?.exists?`${n("Strategy:")}${j.bold(j.cyan(String(e.strategy.clusterCount??0)))} ${j.dim("clusters")} \xB7 ${j.bold(j.cyan(String(e.strategy.articleCount??0)))} ${j.dim("ideas")}`:`${n("Strategy:")}${j.dim("not yet created")}`}),r.push({content:e.briefs?.exists?`${n("Briefs:")}${j.bold(j.cyan(String(e.briefs.count??0)))} ${j.dim("ready")}`:`${n("Briefs:")}${j.dim("none created")}`}),r.push({content:e.content?.exists?`${n("Content:")}${j.green("\u2713")} ${j.bold(j.cyan(String(e.content.count??0)))} ${j.dim("articles written")}`:`${n("Content:")}${j.dim("no articles yet")}`}),r.push({content:e.roadmap?.exists?`${n("Roadmap:")}${j.green("updated")} ${j.dim(Is(e.roadmap.updatedAt??""))}`:`${n("Roadmap:")}${j.dim("not yet created")}`});let i=`${j.bold(j.cyan("SEOAgent"))} ${j.dim("\xB7")} ${j.bold(e.domain)}`;return z(r,{width:78,title:i})}import{exec as gv,spawn as Kd}from"child_process";import{confirm as mv,isCancel as hv}from"@clack/prompts";import ae from"picocolors";var yv=`https://registry.npmjs.org/${Ve}/latest`,Yn=["free","starter","pro","scale","enterprise"],Eo={free:"Free",starter:"Starter",pro:"Pro",scale:"Scale",enterprise:"Enterprise"};function wv(e){let t=e.trim().toLowerCase().split(/\s+/)[0];return Yn.includes(t)?t:null}function bv(e){let t=Yn.indexOf(e);return t===-1||t===Yn.length-1?null:Yn[t+1]}async function kv(e,t=fetch){if(!e)return null;try{let n=(e.api_base||M.BASE).replace(/\/$/,""),r=await t(`${n}/api/cli/whoami`,{headers:{Authorization:`Bearer ${e.user_token}:${e.website_token}`,Accept:"application/json"}});if(!r.ok)return null;let o=await r.json();return typeof o.plan!="string"||!o.plan?null:{plan:o.plan,email:typeof o.email=="string"&&o.email?o.email:void 0,domain:typeof o.domain=="string"&&o.domain?o.domain:void 0}}catch{return null}}function xv(e){let t=[],r=s=>ae.dim(s.padEnd(10)),o=!1;e.email&&(t.push({content:`${r("Email:")}${ae.bold(e.email)}`}),o=!0),e.domain&&(t.push({content:`${r("Website:")}${ae.cyan(e.domain)}`}),o=!0),o&&t.push({sep:!0});for(let s of Yn){let a=Eo[s];s===e.current?t.push({content:`${ae.bold(ae.green("\u25CF"))} ${ae.bold(ae.green(a.padEnd(11)))} ${ae.dim("\u2190 you are here")}`}):s===e.next?t.push({content:`${ae.yellow("\u25C6")} ${ae.bold(ae.yellow(a.padEnd(11)))} ${ae.yellow("next tier")}`}):t.push({content:ae.dim(` ${a}`)})}let i=`${ae.bold(ae.cyan("SEOAgent Cloud"))} ${ae.dim("\xB7")} ${ae.dim("your plan")}`;return z(t,{width:55,title:i})}async function zn(){let e=A(process.cwd()),t=B(e?.domain),n=!!process.stdin.isTTY;if(t&&n){let r=await kv(t);if(r){let o=wv(r.plan),i=o?bv(o):null;if(o&&d.message(xv({email:r.email,domain:r.domain,current:o,next:i})),o&&!i){d.success(`You're on ${Eo[o]} (highest tier).`);return}if(o&&i){let s=await mv({message:`Upgrade from ${Eo[o]} to ${Eo[i]}?`});if(hv(s)||!s){d.info("No changes.");return}}}}vv()}function vv(){let e=_v();d.info("Opening SEOAgent Cloud pricing..."),d.message(`URL: ${e}`);let t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "${e}"`:`xdg-open "${e}"`;gv(t,n=>{n&&d.warn("Could not open browser. Visit the URL above to upgrade.")})}function _v(){let e=A(process.cwd());return Re("cli-upgrade",e?.domain)}async function Jn(e={}){let t=I,n=await Sv();if(!n){d.warn("Couldn't reach the npm registry to check for a newer version."),d.message(`You're on ${t}. To force-update: npm install -g ${Ve}@latest`);return}if(dt(t,n)>=0){d.success(`You're on the latest CLI (${t}).`);return}if(!Zo()){d.info(`A newer CLI is available: ${t} \u2192 ${n}.`),d.message("You're running via npx, which caches the package \u2014 an unpinned spec won't auto-upgrade."),d.message(`Run the latest now by pinning the tag: npx -y ${Ve}@latest <cmd>`),d.message(`Still on ${t} after that? Clear the npx cache: rm -rf ~/.npm/_npx`),d.message(`Or install globally once so \`seoagent <cmd>\` + \`update-cli\` work in place: npm install -g ${Ve}@latest`);return}if(e.dryRun){d.info(`(dry-run) would run: npm install -g ${Ve}@latest`);return}if(d.info(`Updating CLI: ${t} \u2192 ${n}\u2026`),!await Rv()){d.error(`Update failed. Try manually: npm install -g ${Ve}@latest (you may need sudo on Linux/macOS).`),d.message('If npm said "notarget" or "No matching version found", the release is still propagating: wait 30s and retry with --prefer-online.');return}if(d.success(`Updated to ${n}.`),e.projects===!1){d.info("Skipped project refresh (--no-projects). Each project updates itself on its next sync.");return}d.info("Refreshing your other projects to the new version\u2026"),await $v()||d.info("Could not run the project sweep automatically \u2014 run `seoagent refresh --all` to update all projects now (otherwise each updates itself the next time you open it in Claude Code).")}function $v(){return new Promise(e=>{try{let t=Kd("seoagent",["refresh","--all"],{stdio:"inherit"});t.on("error",()=>e(!1)),t.on("exit",n=>e(n===0))}catch{e(!1)}})}async function Sv(e=fetch){try{let t=await e(yv,{headers:{Accept:"application/json"}});if(!t.ok)return null;let n=await t.json();return typeof n.version=="string"?n.version:null}catch{return null}}function Rv(){return new Promise(e=>{let t=Kd("npm",["install","-g",`${Ve}@latest`],{stdio:"inherit"});t.on("error",()=>e(!1)),t.on("exit",n=>e(n===0))})}function G(e){let t=A(e);return t||(d.error(`No SEOAgent project here. Run \`${h("init")}\` first.`),process.exitCode=1,null)}async function Tt(e={}){if(e.print){let t=A(process.cwd())?.domain,n=B(t);if(!n){d.error(`Not logged in. Run \`${h("login")}\` first.`),process.exitCode=1;return}let r=G(process.cwd());if(!r)return;let o=n.api_base||M.BASE,i=`Bearer ${n.user_token}:${n.website_token}`;if(r.domain===nt){d.warn("`.seoagent/project.md` has `domain: unknown` \u2014 set your site's domain before pulling from the cloud."),process.exitCode=1;return}let s=await rt({apiBase:o,authHeader:i,localDomain:r.domain});if(s.verdict==="mismatch"){d.warn(Xa(s.cloudDomain,r.domain)),process.exitCode=1;return}if(s.verdict==="unverified"){d.warn(`Could not verify which cloud site this login is connected to (${s.detail}) \u2014 not pulling.`),process.exitCode=1;return}let a=await Mu({apiBase:o,authHeader:i,path:e.print});if(!a.ok){d.warn(a.error),process.exitCode=1;return}process.stdout.write(a.body),a.body.endsWith(`
1125
+ ${i}`),!e.global&&Bd(ee)&&d.info("Your seoagent.com login (~/.config/seoagent/) was kept \u2014 it is shared across projects. Run `uninstall --global` to wipe it too."),d.info(`Re-install any time with \`${h("init")}\`.`)}import j from"picocolors";import{existsSync as Kn,readdirSync as Ps,statSync as Qx,readFileSync as Hd}from"fs";import{join as on}from"path";function Zx(e){let t=(e.match(/^\s*-\s+\[\s\]/gm)??[]).length,n=(e.match(/^\s*-\s+\[x\]/gim)??[]).length;return{open:t,done:n}}function ev(e){let t=on(e,"audit","latest.md");if(!Kn(t))return null;let n=nt(t);if(!n)return null;let r=Hd(t,"utf-8"),o=Zx(r);return{exists:!0,date:typeof n.data.audited_at=="string"?n.data.audited_at:void 0,issueCount:o.open}}function tv(e){try{let n=Hd(e,"utf-8").split(/\r?\n/),r=!1,o=0;for(let i of n){let s=i.trim();if(s.startsWith("|")&&s.endsWith("|")){if(/^\|\s*-+\s*(\|\s*-+\s*)+\|$/.test(s)){r=!0;continue}r&&o++}else if(r&&s==="")break}return o}catch{return 0}}function nv(e){let t=on(e,"strategy","clusters");if(!Kn(t))return null;let n=Ps(t).filter(o=>o.endsWith(".md"));if(n.length===0)return null;let r=0;for(let o of n)r+=tv(on(t,o));return{exists:!0,clusterCount:n.length,articleCount:r}}function rv(e){let t=on(e,"briefs");if(!Kn(t))return null;let n=Ps(t).filter(r=>r.endsWith(".md"));return n.length>0?{exists:!0,count:n.length}:null}function ov(e){let t=on(e,"content");if(!Kn(t))return null;let n=Ps(t).filter(r=>r.endsWith(".md"));return n.length===0?null:{exists:!0,count:n.length}}function iv(e){let t=on(e,"roadmap.md");return Kn(t)?{exists:!0,updatedAt:Qx(t).mtime.toISOString()}:null}function Gd(e){let t=A(e);if(!t)return null;let n=Xe(e);return{domain:t.domain,audit:ev(n),strategy:nv(n),briefs:rv(n),content:ov(n),roadmap:iv(n)}}import pt from"picocolors";var Wd=/\x1b\[[0-9;]*m/g;function qn(e){return e.replace(Wd,"").length}var sv=51,av=24,lv=80;function cv(e,t,n=sv){let r=0;for(let c of e)"sep"in c||(r=Math.max(r,qn(c.content)));let o=t?qn(t)+6:0,i=Math.max(n,r+4,o),s=process.stdout?.columns,a=(typeof s=="number"&&s>0?s:lv)-2,l=Math.max(av,a);return Math.min(i,l)}function uv(e,t){if(qn(e)<=t)return e;if(t<=0)return"";let n=t-1,r="",o=0,i=!1,s=u=>{for(let p of u){if(o+p.length>n)return;r+=p,o+=p.length}},a=new RegExp(Wd.source,"g"),l=0,c;for(;(c=a.exec(e))!==null;)s(e.slice(l,c.index)),r+=c[0],i=!0,l=c.index+c[0].length;return s(e.slice(l)),`${r}\u2026${i?"\x1B[0m":""}`}function z(e,t={}){let n=cv(e,t.title,t.width),r=n-4,o="\u2500".repeat(n-2),i=dv(n,t.title),s=pt.dim(`\u251C${o}\u2524`),a=pt.dim(`\u2514${o}\u2518`),l=[i];for(let c of e){if("sep"in c){l.push(s);continue}l.push(pv(c.content,r))}return l.push(a),l.join(`
1126
+ `)}function dv(e,t){if(!t)return pt.dim(`\u250C${"\u2500".repeat(e-2)}\u2510`);let n=qn(t),r=e-5-n;return r<1?pt.dim(`\u250C${"\u2500".repeat(e-2)}\u2510`):`${pt.dim("\u250C\u2500 ")}${t}${pt.dim(` ${"\u2500".repeat(r)}\u2510`)}`}function pv(e,t){let n=qn(e),r=n<=t?e+" ".repeat(t-n):uv(e,t);return`${pt.dim("\u2502")} ${r} ${pt.dim("\u2502")}`}function Is(e){let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4);if(n<60)return`${n} minutes ago`;let r=Math.floor(n/60);return r<24?`${r} hours ago`:`${Math.floor(r/24)} days ago`}function Vn(){let e=Gd(process.cwd());if(!e){d.warn("No SEOAgent project found in this directory."),d.info(`Run \`${h("init")}\` to get started.`);return}d.message(fv(e))}function fv(e){if(!e)return"";let t=11,n=s=>j.dim(s.padEnd(t)),r=[];B(e.domain)?(r.push({content:`${j.green("\u2713")} ${j.dim("Logged in")}`}),r.push({content:j.dim(` Run \`${h("whoami")}\` for email / plan.`)})):(r.push({content:`${j.dim("\u25CB Not logged in")}`}),r.push({content:j.dim(` Run \`${h("login")}\` to connect.`)})),r.push({sep:!0}),r.push({content:e.audit?.exists?`${n("Audit:")}${j.green(`last run ${Is(e.audit.date??"")}`)} ${j.dim(`(${e.audit.issueCount??0} issues)`)}`:`${n("Audit:")}${j.dim("not yet run")}`}),r.push({content:e.strategy?.exists?`${n("Strategy:")}${j.bold(j.cyan(String(e.strategy.clusterCount??0)))} ${j.dim("clusters")} \xB7 ${j.bold(j.cyan(String(e.strategy.articleCount??0)))} ${j.dim("ideas")}`:`${n("Strategy:")}${j.dim("not yet created")}`}),r.push({content:e.briefs?.exists?`${n("Briefs:")}${j.bold(j.cyan(String(e.briefs.count??0)))} ${j.dim("ready")}`:`${n("Briefs:")}${j.dim("none created")}`}),r.push({content:e.content?.exists?`${n("Content:")}${j.green("\u2713")} ${j.bold(j.cyan(String(e.content.count??0)))} ${j.dim("articles written")}`:`${n("Content:")}${j.dim("no articles yet")}`}),r.push({content:e.roadmap?.exists?`${n("Roadmap:")}${j.green("updated")} ${j.dim(Is(e.roadmap.updatedAt??""))}`:`${n("Roadmap:")}${j.dim("not yet created")}`});let i=`${j.bold(j.cyan("SEOAgent"))} ${j.dim("\xB7")} ${j.bold(e.domain)}`;return z(r,{width:78,title:i})}import{exec as gv,spawn as Kd}from"child_process";import{confirm as mv,isCancel as hv}from"@clack/prompts";import ae from"picocolors";var yv=`https://registry.npmjs.org/${Ve}/latest`,Yn=["free","starter","pro","scale","enterprise"],Eo={free:"Free",starter:"Starter",pro:"Pro",scale:"Scale",enterprise:"Enterprise"};function wv(e){let t=e.trim().toLowerCase().split(/\s+/)[0];return Yn.includes(t)?t:null}function bv(e){let t=Yn.indexOf(e);return t===-1||t===Yn.length-1?null:Yn[t+1]}async function kv(e,t=fetch){if(!e)return null;try{let n=(e.api_base||M.BASE).replace(/\/$/,""),r=await t(`${n}/api/cli/whoami`,{headers:{Authorization:`Bearer ${e.user_token}:${e.website_token}`,Accept:"application/json"}});if(!r.ok)return null;let o=await r.json();return typeof o.plan!="string"||!o.plan?null:{plan:o.plan,email:typeof o.email=="string"&&o.email?o.email:void 0,domain:typeof o.domain=="string"&&o.domain?o.domain:void 0}}catch{return null}}function xv(e){let t=[],r=s=>ae.dim(s.padEnd(10)),o=!1;e.email&&(t.push({content:`${r("Email:")}${ae.bold(e.email)}`}),o=!0),e.domain&&(t.push({content:`${r("Website:")}${ae.cyan(e.domain)}`}),o=!0),o&&t.push({sep:!0});for(let s of Yn){let a=Eo[s];s===e.current?t.push({content:`${ae.bold(ae.green("\u25CF"))} ${ae.bold(ae.green(a.padEnd(11)))} ${ae.dim("\u2190 you are here")}`}):s===e.next?t.push({content:`${ae.yellow("\u25C6")} ${ae.bold(ae.yellow(a.padEnd(11)))} ${ae.yellow("next tier")}`}):t.push({content:ae.dim(` ${a}`)})}let i=`${ae.bold(ae.cyan("SEOAgent Cloud"))} ${ae.dim("\xB7")} ${ae.dim("your plan")}`;return z(t,{width:55,title:i})}async function zn(){let e=A(process.cwd()),t=B(e?.domain),n=!!process.stdin.isTTY;if(t&&n){let r=await kv(t);if(r){let o=wv(r.plan),i=o?bv(o):null;if(o&&d.message(xv({email:r.email,domain:r.domain,current:o,next:i})),o&&!i){d.success(`You're on ${Eo[o]} (highest tier).`);return}if(o&&i){let s=await mv({message:`Upgrade from ${Eo[o]} to ${Eo[i]}?`});if(hv(s)||!s){d.info("No changes.");return}}}}vv()}function vv(){let e=_v();d.info("Opening SEOAgent Cloud pricing..."),d.message(`URL: ${e}`);let t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "${e}"`:`xdg-open "${e}"`;gv(t,n=>{n&&d.warn("Could not open browser. Visit the URL above to upgrade.")})}function _v(){let e=A(process.cwd());return Re("cli-upgrade",e?.domain)}async function Jn(e={}){let t=I,n=await Sv();if(!n){d.warn("Couldn't reach the npm registry to check for a newer version."),d.message(`You're on ${t}. To force-update: npm install -g ${Ve}@latest`);return}if(dt(t,n)>=0){d.success(`You're on the latest CLI (${t}).`);return}if(!Zo()){d.info(`A newer CLI is available: ${t} \u2192 ${n}.`),d.message("You're running via npx, which caches the package \u2014 an unpinned spec won't auto-upgrade."),d.message(`Run the latest now by pinning the tag: npx -y ${Ve}@latest <cmd>`),d.message(`Still on ${t} after that? Clear the npx cache: rm -rf ~/.npm/_npx`),d.message(`Or install globally once so \`seoagent <cmd>\` + \`update-cli\` work in place: npm install -g ${Ve}@latest`);return}if(e.dryRun){d.info(`(dry-run) would run: npm install -g ${Ve}@latest`);return}if(d.info(`Updating CLI: ${t} \u2192 ${n}\u2026`),!await Rv()){d.error(`Update failed. Try manually: npm install -g ${Ve}@latest (you may need sudo on Linux/macOS).`),d.message('If npm said "notarget" or "No matching version found", the release is still propagating: wait 30s and retry with --prefer-online.');return}if(d.success(`Updated to ${n}.`),e.projects===!1){d.info("Skipped project refresh (--no-projects). Each project updates itself on its next sync.");return}d.info("Refreshing your other projects to the new version\u2026"),await $v()||d.info("Could not run the project sweep automatically \u2014 run `seoagent refresh --all` to update all projects now (otherwise each updates itself the next time you open it in Claude Code).")}function $v(){return new Promise(e=>{try{let t=Kd("seoagent",["refresh","--all"],{stdio:"inherit"});t.on("error",()=>e(!1)),t.on("exit",n=>e(n===0))}catch{e(!1)}})}async function Sv(e=fetch){try{let t=await e(yv,{headers:{Accept:"application/json"}});if(!t.ok)return null;let n=await t.json();return typeof n.version=="string"?n.version:null}catch{return null}}function Rv(){return new Promise(e=>{let t=Kd("npm",["install","-g",`${Ve}@latest`],{stdio:"inherit"});t.on("error",()=>e(!1)),t.on("exit",n=>e(n===0))})}function G(e){let t=A(e);return t||(d.error(`No SEOAgent project here. Run \`${h("init")}\` first.`),process.exitCode=1,null)}async function Tt(e={}){if(e.print){let t=A(process.cwd())?.domain,n=B(t);if(!n){d.error(`Not logged in. Run \`${h("login")}\` first.`),process.exitCode=1;return}let r=G(process.cwd());if(!r)return;let o=n.api_base||M.BASE,i=`Bearer ${n.user_token}:${n.website_token}`;if(r.domain===Ze){d.warn("`.seoagent/project.md` has `domain: unknown` \u2014 set your site's domain before pulling from the cloud."),process.exitCode=1;return}let s=await rt({apiBase:o,authHeader:i,localDomain:r.domain});if(s.verdict==="mismatch"){d.warn(Xa(s.cloudDomain,r.domain)),process.exitCode=1;return}if(s.verdict==="unverified"){d.warn(`Could not verify which cloud site this login is connected to (${s.detail}) \u2014 not pulling.`),process.exitCode=1;return}let a=await Mu({apiBase:o,authHeader:i,path:e.print});if(!a.ok){d.warn(a.error),process.exitCode=1;return}process.stdout.write(a.body),a.body.endsWith(`
1127
1127
  `)||process.stdout.write(`
1128
1128
  `);return}await ge({pullOnly:!0,force:e.force,silent:e.silent,embedded:e.embedded})}import{existsSync as Ev,readdirSync as Cv,unlinkSync as Av}from"fs";import{join as qd}from"path";import{isCancel as Pv,select as Iv}from"@clack/prompts";var Vd=e=>/^https?:\/\/\S+$/i.test(e);function Yd(e){let t=e.split("|").map(s=>s.trim());if(t.length<3)return null;let[n,r,...o]=t,i=o.join(" | ").trim();return!n||n.length>120||!Vd(r)||!i?null:{target_query:n,competitor_url:r,adds:i}}function zd(e){let t=e.indexOf("|");if(t<0)return null;let n=e.slice(0,t).trim(),r=e.slice(t+1).trim();return!Vd(n)||!r?null:{competitor_url:n,reason:r}}function Tv(e){let t=[];for(let n of e.plan??[])Yd(n)||t.push(`--plan "${n}" (expected "<target query> | <their url> | <what ours adds>")`);for(let n of e.skip??[])zd(n)||t.push(`--skip "${n}" (expected "<their url> | <reason>")`);return t}var Ov=["code","postcard","call","email"];function Lv(e){let t={};e.awaitingDeploy?(t.awaiting_deploy="true",e.reason?.trim()&&(t.deploy_note=e.reason.trim())):e.reason?.trim()&&(t.note=e.reason.trim()),e.verify?.trim()&&(t.outcome="owner_verification_required",t.owner_action=e.verify.trim(),e.verifyType&&Ov.includes(e.verifyType)&&(t.owner_action_type=e.verifyType)),e.url?.trim()&&(t.listing_url=e.url.trim());let n=(e.plan??[]).map(Yd).filter(o=>o!==null);n.length&&(t.planned_json=JSON.stringify(n));let r=(e.skip??[]).map(zd).filter(o=>o!==null);return r.length&&(t.skipped_json=JSON.stringify(r)),Object.keys(t).length?t:null}async function Os(e,t={}){if(e.length<=1)return He(e[0],t);let n=0,r=[];for(let o of e)await He(o,{...t,silent:!0})?n++:r.push(o);if(!t.silent){let o=t.failed?"declined":t.awaitingDeploy?"applied, awaiting deploy":"completed";r.length===0?d.success(`${n} action${n===1?"":"s"} marked ${o}${t.failed&&t.reason?` (reason: ${t.reason})`:""}.`):d.warn(`${n} of ${e.length} actions marked ${o}; still pending: ${r.join(", ")}.`)}return r.length===0}async function He(e,t={}){let n=Tv(t);if(n.length)return d.error(`Not acked \u2014 fix these and run the ack again:
1129
1129
  ${n.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seoagent-official/seoagent",
3
- "version": "1.119.1",
3
+ "version": "1.119.2",
4
4
  "description": "The persistent AI SEO agent for Claude Code. Audits, keyword strategy, briefs, articles, real product screenshots from your repo, and the autopilot loop (cloud detects → CLI executes → ack closes) — other SEO tools write the prompt, SEOAgent runs it.",
5
5
  "type": "module",
6
6
  "bin": {