@eternify-labs/seo-audit 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,7 +23,7 @@ CLIs. This tool orchestrates them; it does not reimplement their agent loops.
23
23
 
24
24
  **Required**
25
25
 
26
- - **Node.js ≥ 20** (`node --version`)
26
+ - **Node.js ≥ 22.12** (`node --version`)
27
27
  - **An AI account**, one of:
28
28
  - *Claude (recommended)* — a Claude subscription with Claude Code logged in
29
29
  on this machine (run `claude` once and sign in), **or** an
@@ -132,7 +132,7 @@ installed Google Chrome (or Edge), the same browser `--render` uses.
132
132
 
133
133
  **Economy mode** (default on): mechanical tasks — visibility classification,
134
134
  the dissenter lens, paste tests, SERP-type classification — automatically run
135
- on a lighter, cheaper model (Haiku 4.5 / Gemini Flash), while audits, briefs
135
+ on a lighter, cheaper model (the latest Haiku / Gemini Flash), while audits, briefs
136
136
  and reports keep your selected model. Toggle in Settings.
137
137
 
138
138
  ## When something fails
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import{a as T,i as a}from"./chunk-QCEC2HDC.js";import R from"fs";import f from"path";import N from"better-sqlite3";import n from"fs";import d from"path";import O from"os";var s=d.join(O.homedir(),".pulsemedia"),i=d.join(s,"config.json"),c=d.join(s,"reports"),m=d.join(O.homedir(),".eternify");function A(){if(!(n.existsSync(s)||!n.existsSync(m)))try{n.cpSync(m,s,{recursive:!0}),n.existsSync(i)&&n.chmodSync(i,384)}catch{}}A();function l(){n.mkdirSync(c,{recursive:!0})}var v={"claude-haiku-4-5":"haiku","claude-sonnet-5":"sonnet","claude-opus-5":"opus"};function g(e){return e&&(v[e]??e)}function C(){try{let e=n.readFileSync(i,"utf8"),t=T.parse(JSON.parse(e));return{...t,model:g(t.model),lightModel:g(t.lightModel)}}catch{return null}}function w(e){l();let t=new Date().toISOString(),r={...e,createdAt:e.createdAt??t,updatedAt:t};n.writeFileSync(i,JSON.stringify(r,null,2)+`
3
+ `,{mode:384}),n.chmodSync(i,384)}function b(e){switch(e.type){case"codebase":return e.path;case"content-brief":return`${e.keyword} \u2014 ${e.domain}`;default:return e.domain}}function h(e){return"scorecard"in e?e.scorecard.overall:e.type==="ai-visibility"?e.visibilityScore:null}var y=class{db;constructor(t,r){R.mkdirSync(f.dirname(t),{recursive:!0}),this.db=new N(t),this.db.pragma("journal_mode = WAL"),this.db.exec(`
4
+ CREATE TABLE IF NOT EXISTS reports (
5
+ id TEXT PRIMARY KEY,
6
+ type TEXT NOT NULL,
7
+ subject TEXT NOT NULL,
8
+ created_at TEXT NOT NULL,
9
+ overall INTEGER,
10
+ data TEXT NOT NULL
11
+ );
12
+ CREATE INDEX IF NOT EXISTS idx_reports_created ON reports(created_at DESC);
13
+ CREATE INDEX IF NOT EXISTS idx_reports_type_subject ON reports(type, subject);
14
+ CREATE TABLE IF NOT EXISTS kv (
15
+ key TEXT PRIMARY KEY,
16
+ value TEXT NOT NULL,
17
+ updated_at TEXT NOT NULL
18
+ );
19
+ `),r&&this.importLegacyJson(r)}importLegacyJson(t){let r;try{r=R.readdirSync(t).filter(u=>u.endsWith(".json"))}catch{return}if(r.length===0)return;let o=this.db.prepare("SELECT 1 FROM reports WHERE id = ?");for(let u of r)try{let S=a.parse(JSON.parse(R.readFileSync(f.join(t,u),"utf8")));o.get(S.id)||this.saveReport(S)}catch{}}saveReport(t){this.db.prepare("INSERT OR REPLACE INTO reports (id, type, subject, created_at, overall, data) VALUES (?, ?, ?, ?, ?, ?)").run(t.id,t.type,b(t),t.createdAt,h(t),JSON.stringify(t))}loadReport(t){let r=this.db.prepare("SELECT data FROM reports WHERE id = ?").get(t);if(!r)return null;try{return a.parse(JSON.parse(r.data))}catch{return null}}listReportSummaries(){return this.db.prepare("SELECT id, type, subject, created_at, overall FROM reports ORDER BY created_at DESC").all().map(r=>({id:r.id,type:r.type,subject:r.subject,createdAt:r.created_at,overall:r.overall??void 0}))}listReports(){let t=this.db.prepare("SELECT data FROM reports ORDER BY created_at DESC").all(),r=[];for(let o of t)try{r.push(a.parse(JSON.parse(o.data)))}catch{}return r}findLatestDomainReport(t){let r=this.db.prepare("SELECT data FROM reports WHERE type = 'domain' AND subject = ? ORDER BY created_at DESC LIMIT 1").get(t);if(!r)return null;try{return a.parse(JSON.parse(r.data))}catch{return null}}deleteReport(t){return this.db.prepare("DELETE FROM reports WHERE id = ?").run(t).changes>0}kvGet(t,r){let o=this.db.prepare("SELECT value, updated_at FROM kv WHERE key = ?").get(t);if(!o||r!==void 0&&Date.now()-Date.parse(o.updated_at)>r)return null;try{return JSON.parse(o.value)}catch{return null}}kvSet(t,r){this.db.prepare("INSERT OR REPLACE INTO kv (key, value, updated_at) VALUES (?, ?, ?)").run(t,JSON.stringify(r),new Date().toISOString())}close(){this.db.close()}},E=null;function p(){return E||(l(),E=new y(f.join(s,"data.db"),c)),E}var J=e=>p().saveReport(e),U=e=>/^[a-zA-Z0-9-]+$/.test(e)?p().loadReport(e):null,Y=()=>p().listReports(),W=()=>p().listReportSummaries(),G=e=>/^[a-zA-Z0-9-]+$/.test(e)?p().deleteReport(e):!1;export{s as a,i as b,C as c,w as d,y as e,p as f,J as g,U as h,Y as i,W as j,G as k};