487 Commits

Author SHA1 Message Date
Ben Senescu
215ead8152
Replace dataforseo-client SDK with a thin fetch client (#532) 2026-08-25 22:23:55 -04:00
Ben Senescu
ac7ebfe13a
Add Dub referral conversion tracking (leads + sales) (#531) 2026-08-25 21:49:08 -04:00
Ben Senescu
7a611a7bad
Reorder onboarding source options by observed frequency, add Instagram (#533) 2026-08-25 20:49:46 -04:00
Ben Senescu
e0ed902f39
Allow commercial use in hosted terms Section 2.1 (#529)
Replace leftover 'personal, noncommercial' boilerplate with a license
covering internal business use and client-services work, permit using
generated Outputs in client deliverables, and carve Outputs out of the
Section 2.2 commercial-exploitation restriction.
2026-08-23 21:05:30 -04:00
Ben Senescu
c469a48ae9
Add Cursor marketplace plugin package (#521) 2026-08-23 20:18:24 -04:00
Ben Senescu
67f3743002 Update ChatGPT app submission metadata (#520) 2026-08-23 18:18:17 -04:00
Ben Senescu
6e02186a2b Add ChatGPT plugin submission manifest (#519) 2026-08-23 18:18:17 -04:00
Ben Senescu
d403954323 Add public support page (#518) 2026-08-23 18:18:17 -04:00
Ben Senescu
4ba2d6c175 Require exact hosted MCP origins (#515)
* Require exact hosted MCP origins

* Clarify exact MCP origin policy
2026-08-23 18:18:17 -04:00
Ben Senescu
e5e961bf48 Audit crawl: conservative OOM retries + window carry-over across chunks (#517)
* Audit crawl: retry chunks conservatively and stop re-learning the window per chunk

Production audits on heavy-page sites (500-700KB/page) died with
exceededMemory in the first crawl chunk, and the single step retry re-ran
the exact same profile and died again.

- claimChunk now reports isRetry (leftover leases from a dead attempt);
  a retried chunk crawls under RETRY_CRAWL_WINDOW (start 3, max 5,
  halved byte budget) instead of restarting at window 10.
- The adapted window carries across chunks via durable step results, so
  every ~200 pages no longer re-spikes to the initial window.
- First persist sub-batch shrinks to 5 pages so the byte bound sees the
  site's page weight before a full 25-page batch is in flight.
- In-flight HTML budget halved to 8 MiB (16 MiB never constrained the
  observed ~650KB pages: bound was 25, above the 20 max); growth now
  requires a full 25-page sample.
- Parse-time caps: 1,000 extracted links/images per page so mega-menu and
  crawler-trap pages can't bloat retained persist batches.

* Guard endWindow for instances replaying pre-deploy step results

* ci: un-export internal-only interfaces (knip)
2026-08-23 18:18:17 -04:00
Ben Senescu
4cd321e269 Blocked-audit alert: point to desktop crawlers instead of support email (#516)
* Blocked-audit alert: point to desktop crawlers instead of support email

* Soften blocked-audit alert opening

* Partial-block banner: recommend desktop crawlers, drop allowlist tip
2026-08-23 18:18:17 -04:00
Ben Senescu
5cb23418e1 Mask API key values in PostHog replays (#514) 2026-08-23 18:18:17 -04:00
Ben Senescu
6470b875ad Allow SurfMind Chrome extension MCP origin (#513) 2026-08-23 18:18:17 -04:00
Ben Senescu
47883b5d5a Fix GA4 measurement health for sparse API responses (#512) 2026-08-23 18:18:17 -04:00
Ben Senescu
b9c1b0255a Prompting post: add SEO skills overview section before FAQ (#511) 2026-08-23 18:18:17 -04:00
Jeremy Rivera
d2bfc256dc
feat(library): add FAQPage JSON-LD to the eight keyword-research spokes (#240) 2026-08-23 18:16:42 -04:00
Jeremy Rivera
56826f84d1
Competitive Analysis strategy library: pillar + 4 plays (#237) 2026-08-23 18:16:32 -04:00
Ben Senescu
cd6a782092
release: v0.1.6 (#509) 2026-08-19 14:34:24 -04:00
Ben Senescu
43265048df
Tame audit polling: SAM's status tool waits server-side; Lighthouse becomes opt-in for agents (#510) 2026-08-19 14:22:33 -04:00
Ben Senescu
a6f96c516e
Remove GA4 launch gating; dashboard shows an Organic traffic card once connected (#505) 2026-08-19 13:19:55 -04:00
Ben Senescu
9305ea89d6
Prompting post: keyword-optimized headers + FAQ (#508) 2026-08-19 13:03:52 -04:00
Ben Senescu
45d788d81d
Add prompting guide blog post; fix blog footer width, nav, and light-page theming (#507) 2026-08-19 12:48:46 -04:00
Ben Senescu
a5a953e478
Project memory + SAM skills: shared per-project AI context (spec 0010) (#493) 2026-08-19 09:46:07 -04:00
Ben Senescu
a3ca46a0c1
Add OpenSEO plugins for Claude Code and Codex CLI (#501) 2026-08-18 23:17:50 -04:00
Ben Senescu
a004759700
Revert "Prefix public agent skills with "openseo-" (#502)" (#503)
This reverts commit b9df03d20f0f20230072aaa49df1abf56422addb.
2026-08-18 23:00:37 -04:00
Ben Senescu
b9df03d20f
Prefix public agent skills with "openseo-" (#502) 2026-08-18 21:15:50 -04:00
Ben Senescu
cfa5bc2cf5
Gate GA4 MCP tools per-user; fix false ga4_malformed_response on empty comparison periods (#497) 2026-08-18 15:56:38 -04:00
Ben Senescu
7edb82192a
Update README.md 2026-08-18 15:22:45 -04:00
Ben Senescu
8149cd6c70
release: v0.1.5 (#496)
* release: v0.1.5

* save
2026-08-18 15:05:03 -04:00
Ben Senescu
7738f72333
Local SEO MCP tools: business profile, reviews, updates, categories, rank grid (#489) 2026-08-17 23:21:34 -04:00
Ben Senescu
052977f20d
Add Palestine as a Google-Ads-only country picker location (#492) 2026-08-17 22:52:47 -04:00
Ben Senescu
ff0ae47d19
Codex MCP “missing issuer” is a Codex 0.143–0.146 bug, not OpenSEO (#491) 2026-08-17 15:21:32 -04:00
Ben Senescu
61ebdb05ab
Google OAuth verification: privacy policy disclosures + GA4 reviewer access (#488)
* Add Google user data disclosures and Limited Use statement to privacy policy

* Show GA4 connect surfaces to the Google OAuth verification reviewer account

* List OpenAI as a potential AI model provider in the privacy policy
2026-08-15 18:27:59 -04:00
Ben Senescu
c8b3eb9b0a
Add exact URL / subfolder / domain / subdomain research scopes (EVE-56) (#487) 2026-08-14 21:52:32 -04:00
Ben Senescu
3df66ad9ae
Restore backlink feature URL (#484)
* Restore backlink feature URL

* Restore backlink checker page titles
2026-08-13 20:33:55 -04:00
Ben Senescu
db45a0dd6d
Fix MCP saved keyword metrics (#483) 2026-08-13 20:16:20 -04:00
Ben Senescu
72eaa09c32
Hide Analytics section when GA4 OAuth app is pending (#475) 2026-08-12 19:57:29 -04:00
Ben Senescu
75aec8424f
Detect paid plans from Autumn entitlement flags (#482) 2026-08-12 11:35:07 -04:00
Ben Senescu
a1ed6ece4b
Add strategy library index and navigation (#479)
* feat(web): add strategy library index

* fix(web): align strategy library review feedback

* fix(web): reorder resource links
2026-08-11 22:53:02 -04:00
Ben Senescu
bd402844fa
Add public product roadmap (#480) 2026-08-11 22:38:47 -04:00
Ben Senescu
0a11839a1c
Clarify contribution and pull request guidance (#457) 2026-08-11 21:51:15 -04:00
Ben Senescu
84e8d0be99
Serve legacy MCP JSON requests statelessly to stop per-request server retention (#478) 2026-08-11 20:15:48 -04:00
Ben Senescu
16eb599270
MCP API key support (hosted mode) (#438) 2026-08-11 19:20:44 -04:00
Ben Senescu
7a1748af4e
Exclude PDF assets from prerendering (#476) 2026-08-10 23:03:20 -04:00
Jeremy Rivera
edc2c07af2
Add blog post: Ranking for the Wrong Half of Your Audience (#185) 2026-08-10 13:43:53 -04:00
Jeremy Rivera
85095f4ac6
Library batch 2: plays 05-08, completing the Keyword Research library (#187) 2026-08-10 12:11:40 -04:00
Ben Senescu
d2d8f7e19a
release: v0.1.4 (#474)
* release: v0.1.4

* save
2026-08-09 15:51:55 -04:00
Ben Senescu
877782ad19 fix(gdpr): drop reddit_attributions count from erasure script
The reddit attribution tables were removed in #469; the erasure
script still counted them, breaking tsc in ci:check.
2026-08-08 19:21:47 -04:00
Ben Senescu
9edb18db60
feat(gdpr): user data erasure workflow (EVE-46) (#468) 2026-08-08 19:17:41 -04:00
Ben Senescu
13ada5b441
fix(sam): out-of-credits CoT leak, streaming scroll lock, rank-tracking language gap (#470)
* fix(sam): stream canned refusals without a provider call

Out-of-credits and session-gone refusals ran a real LLM turn with a
200-token cap; MiniMax M3 could spend the whole budget on reasoning
tokens, leaving the user a raw truncated chain-of-thought (which also
named the backing model) and no reply. Refusal turns now swap in a
static LanguageModelV3 that streams the refusal text through Think's
normal pipeline — rendered and persisted like any assistant message,
with no provider request at all.

Fixes every-app/open-seo#161

* fix(chat): stop pinning the transcript to the bottom while the user scrolls up

Both chat surfaces (SAM and onboarding) forced scrollTop to the bottom
on every streamed chunk, so scrolling up mid-reply was undone within
milliseconds. A shared stick-to-bottom hook now tracks pinned-ness from
real scroll events: scrolling away releases the pin, returning to the
bottom (or sending a message) re-arms it.

Fixes every-app/open-seo#160

* fix(rank-tracking): allow any SERP language for any country

The Add Domain modal restricted the language picker to the Labs
per-country subset and disabled it when only one option existed, so
e.g. tracking English searches in Czechia was impossible — even though
rank tracking runs against the SERP API, which serves every supported
language in every country. The picker now offers the full SERP language
list; create/update schemas validate codes against the master list so
unknown codes still fail before DataForSEO charges for them; and
keyword-metrics refreshes resolve a Labs-served language so an
unserved pair never reaches a charged Labs call.

Fixes every-app/open-seo#183

* fix(chat): surface silent turn failures in Workers logs

A provider stream dying mid-turn (chat:request:failed) and a DO restart
whose recovery gives up (chat:recovery:exhausted) leave the user a
replayed "Something went wrong" banner and a half-streamed message, but
never reach the onChatError hook — their only signal is the agents:chat
diagnostics channel, which was unsubscribed, so the chat agents' most
common failure modes produced zero log lines. A module-level
subscription now logs both for every chat DO.

SamChatAgent.onChatError also returns the error now: Think uses the
return value as the stored chat-terminal body that reconnecting clients
replay, and returning void stored the literal string "undefined".
2026-08-08 18:47:41 -04:00