Skip to content

Release notes

What shipped,when, and why.

Every release, grouped by version. Features on top, fixes below, each bullet linked to the commit that introduced it. Generated automatically from the repository — no marketing spin, no missing entries.

v2.14.1

Fixes

  • none-tierwp.org "none"-tier UX fixes across wizard, diagnostics, and run screen
  • schedulerresolve webhook signing secret by workspace for "none" installs

v2.14.0

Features

  • campaignsshow posts created vs published on the campaign view

v2.13.0

Features

  • billingbundle Channels into all paid tiers + pricing-restructure spec
  • billingcollapse catalog to 3 graduated tiers (agency merge)
  • billingone-ladder pricing UI + regenerated catalog (Slice 2C)
  • billingretire audience gating — seats derive from site quantity
  • billingretire standalone Channels SKU, bundle into every paid plan
  • channelsdiscoverable multi-connection UX for LinkedIn (portal)
  • channelsmake the per-connection publish cooldown env-tunable
  • channelsportal post Channels tab — View post link + throttle display
  • channelspre-emptively gate the video Regenerate button
  • channelswp-admin LinkedIn connect radio choice (portal parity)
  • channelswrite an audit tombstone when a connection is deleted
  • functionsfoundingSeats endpoint for the live scarcity counter
  • wwwadd Video to the channels page, badged "New"
  • wwwFounding-Customer offer on the pricing page
  • wwwlive founding seat counter
  • wwwshow the Founding offer on the ad landing pages

Fixes

  • channelsclassify rate_limited as a skip, not a delivery failure
  • channelsgate video Regenerate on an active connection + quota
  • channelshide Notification language on publish-only channels
  • channelskey dispatch results by connectionId, not integrationId
  • channelsLinkedIn featured images — read bytes binary-safe, not as text
  • channelsLinkedIn Page picker — versioned organizationAcls contract
  • channelsreconcile LinkedIn Page names against a workspace cache
  • channelswait for LinkedIn image to be AVAILABLE before posting
  • referral-linksgate the referral-links editor to paid tiers
  • schedulercount posts published after manual review
  • workspacesrestore COLLECTION index on invitations.email
  • wwwfounding pricing page — design QA

v2.12.0

Features

  • functions,web,clientclient referral/affiliate links woven into relevant posts
  • webAI "Suggest competitors" on the site profile + subtitle fix

v2.11.0

Features

  • client,pluginvideo styling moves onto the visual preset (wp-admin surfaces)
  • clientper-platform caption packages on the video Ready row
  • clientRegenerate on ready videos behind a quota confirmation
  • clientVideo channel UI in wp-admin — premium store card, config modal, activity lifecycle, quota, gates
  • discoverylocalize explicit topic seeds + thin-pool augmentation
  • functions,typesStripe price-metadata video entitlement + per-site video quota
  • functions,websuper-admin "Regenerate (sandbox)" via Shotstack's free stage env
  • functions'your video is ready' owner email (en/de/es/fr)
  • functionsallowedActivationIds on the workspace member model
  • functionsbackfill channel adapt bodyText from generations store
  • functionscaption placement + palette accents in the video EDL
  • functionsconfigurable Shotstack environment (stage sandbox vs v1)
  • functionsdisconnected flag on cycle rows + discount on billing overview
  • functionsfan headless posts out to channels
  • functionsfan out channels when a review post is manually published
  • functionsfirst-render feedback batch — useful scripts, safe captions, brand mood, persona voice, real filenames, run milestone
  • functionsjoin video jobs into channelsListEvents + video category
  • functionskaraoke captions — word-synced chunks + SRT sidecar
  • functionslive video quota snapshot for the meter UI
  • functionsmake the video channel credential-installable
  • functionsmember access-change notification emails
  • functionsmode:'video' usage metering + cloud_pro quota gate
  • functionsmotion-graphics video assembly — branded cards, numbered step headlines, pipeline seam
  • functionsopen the Video channel in the store (drop comingSoon)
  • functionspage ops on permanent video render failures
  • functionsper-platform social paste packages for the Video channel
  • functionsprefer preset.videoArtDirection in the video adapt art-direction resolver
  • functionsrunVideoSynthesis worker + video channel wiring
  • functionsship boundVisualPreset digest on channelsListConnections
  • functionsShotstack EDL builder for the video channel
  • functionssite-access endpoint + restricted activation listing
  • functionsstock-served headless posts get channels dispatch + owner email + persona stamp
  • functionssuppress owner-signup artifacts for invite-driven signups
  • functionsthread invite-time site scope through invite → accept
  • functionsTTS, Pexels, and Shotstack clients for video synthesis
  • functionsvideo job metadata for the activity UI + kinetic preset
  • functionsvideo retry/regenerate endpoint (bearer + portal)
  • functionsvideo synthesis orchestrator
  • functionsvideo worker resolves style/placement/accent from the bound visual preset
  • functionsvideo-ready email deep-links to the post view Channels tab
  • functionsvideo-script prompt template, parser, adapt-fn factory
  • functionsVideoIntegration (adapt→script, publish→enqueue)
  • functionsvisual suggest pass also drafts videoArtDirection + extracts brand palette
  • functionsvoice personas + video connection settings wire fields
  • functionsworkspace-aware headless gate for operate-on-site endpoints
  • getHeadlessAccess honors workspace-aware gating for the post editor
  • rulesscope activation reads to the member's allowedActivationIds
  • typesadd video styling fields to VisualPreset (packages/types + functions twin)
  • uishared VideoChannelGlyph mark (9:16 frame + play wedge)
  • uiTabs size=xs + stretch — in-card platform switcher variant
  • uivideo-channel primitives — ProgressBar, QuotaMeter, MediaLightbox, PresetRadioCard, Badge dot, Select adornment
  • uivideo-visuals primitives — VideoStylePreview, PlacementRadio, SectionGateTeaser, PaletteSwatches
  • web,clientCaptions (.srt) download on ready videos
  • web,uiportal single-post detail view per design handoff
  • webbilling display modes — unmetered usage, renewal variants, site states
  • webbrand-derived preset swatches + site-named default presets
  • webmove video styling into Visuals — preset editor #video section, slimmed channel dialog, wizard row
  • webper-doc site subscriptions for restricted members
  • webper-platform caption packages on the video Ready card
  • webRegenerate on ready videos behind a quota confirmation
  • webrestructure site Channels page into Store/Connections/Activity tabs
  • webrestyle Channel Store to the board's uniform card grid + local channel glyphs
  • website access controls on the Members page and invite dialog
  • webVideo channel UI in the customer portal (store, config, activity, quota)

Fixes

  • adminresolve firebase-admin via functions/node_modules in voice-sample script
  • clientconnection-row video meta reads the bound preset's style, not the frozen legacy field
  • clientdefer the Visuals video-section highlight out of the deep-link effect
  • clientmake the Ready video thumbnail a Preview button opening the lightbox
  • clientshow loading state on single stock-post discard confirm
  • discoveryrewrite-tolerant re-rank guard + collapse retry
  • e2eboot portal e2e with committed .env.test firebase config
  • functions,pluginprevent auto-mode category sprawl
  • functionsblank-line paragraph gaps in the Shorts description package
  • functionsdark outline on white video captions for bright footage
  • functionsgate portal stock reads on campaigns.read
  • functionsheadless site names in usage rows + unmetered flag on cycle view
  • functionslet the video styling fields through every visual-preset allowlist
  • functionsscrim captions (Shotstack drops text-shadow) + video fields on the portal preset list
  • functionssnug inline caption scrim + Montserrat font registration + darker pill
  • uipreview thumbs show the scrim pill the render actually produces
  • web,clientclarify voice previews are English-only samples
  • web,functionscorrect public post URLs + persona provenance in the post view
  • webcampaign Posts tab + run detail link to the post view, not the editor
  • webcaption package as full-width row below hero media + clickable video thumbnails
  • webdefault body images ON for portal-created campaigns
  • webgetInitials survives partial pre-provisioning user profiles
  • webkeep disconnected sites out of the site-access pickers
  • webresolve persona names from the workspace library on run + post views
  • webstop Finish setup crashing with React #185 after the draft clears
  • webwizard Persona step scopes to site membership + seeds a tailored voice
  • www,e2efix pricing FAQ invalid dt/dd nesting (hydration crash) + make portal e2e self-seed
  • www,web,uimake Cloud most popular, catalog-drive all prices, fix plan/model/provider copy

v2.10.2

Fixes

  • aimanaged tiers own the model server-side; alert on batch image failures

v2.10.1

Fixes

  • campaignsdefault core/code block off for new portal campaigns

v2.10.0

Features

  • aimake Gemini Flash Image the recommended default; seed-tooling fixes
  • discoverytune keyword bank for blog reach; hide difficulty selector

Fixes

  • aistop heading keyword-stuffing + never inject unverified authority URLs
  • campaignstolerate object-shaped authorityDomains in cluster adapter
  • headlessscope internal-link suggestions to the campaign language

v2.9.0

Features

  • campaignsmake competitors a site-level fact only

v2.8.0

Features

  • campaignclearer discovery actions — "Re-discover" (fresh) vs "Find more" (append)
  • converttell users on the Done step that campaigns came over paused
  • deliverypull fallback when the webhook push is blocked
  • discoverybuyer-intent keyword seeds, winnability filter, clear-on-language
  • discoverykeyword difficulty modes (winnable / balanced / authority)
  • discoveryper-language positioning for multilingual campaigns
  • discoverywebsite-grounded seeds, diversity, and precision filters
  • growthlet users request an unshipped content language from the campaign builder
  • headless-editoreditable publish date + status-change confirmations
  • migratefix in-body internal links after WP→headless import
  • migratevision-derived image alt + scene topic for imported posts
  • migrationshandle unsupported source language on import
  • onboardingcapture the full service range in AI positioning
  • permalinkmake %year% and %category% tokens actually resolve
  • postsadd Published-date column; drop redundant title hover-underline
  • profileinline-editable positioning with AI re-suggest in settings
  • profilemove headless site identity from Settings to the profile
  • visual-suggestground image-style on homepage screenshot, demote logo
  • wwwserve the blog from the headless API (cursor pagination, no search)

Fixes

  • campaign-viewuse favicons for authority domains (not letter monograms)
  • campaignscoerce keywordBank entries to strings (no more [object Object])
  • campaignshonor campaign language across all discovery explorations
  • convertcarry WP persona bindings (subcollection) onto headless site
  • convertmake the delete-confirm checkbox checkable on the Done step
  • convertpreserve campaign pregenerationEnabled (don't force it off)
  • wwwallow the headless media bucket in next/image remotePatterns

v2.7.0

Features

  • convertoptional source WP app password → authenticated import
  • seoAI strategy suggest on single post + tighter SEO Targeting UI
  • seoescalate a missing SERPER key to an incident instead of silent decay
  • seoportal AI "Generate post strategy" on the single-post page
  • webadd "Generate now" to the portal Stock tab's empty state (plugin parity)

Fixes

  • stockcoerce object keyword-bank entries to strings before research
  • stockmount SERPER + JINA secrets on the stock-generation functions
  • stockreap FROZEN pending entries in the cleanup cron

v2.6.0

Features

  • functionsground campaign keyword discovery in activation positioning
  • growthserver-side Google Ads OCI for signup + purchase (magic-link fix)
  • migratecapture protected SEO meta via new plugin endpoint
  • schedulerreject host-intercepted webhook responses (no phantom publish)
  • seoground per-post focus keyphrase in real DFS long-tails
  • seoground single-post generation in a real keyphrase + authority
  • uishare DiscoverableChipList + add EmptyState across surfaces
  • webcollapse campaign create/edit into the redesign's Discovery step
  • webDiscovery "Replace" — guarded discard-and-rediscover
  • webedit campaign as one scrollable form + sticky section-nav
  • webEditor/Edit polish — section icon headers + consolidated Discovery
  • webInterview pass — match the create prototype
  • webList card "in stock" chip — reuse existing stock-summary hook
  • webList filters + loading skeleton + View output-progress bar
  • webLOW cosmetic batch — paused hint, mode check, neutral tile, recent×3
  • webpersist the grounded long-tail pool when discovering campaign keywords
  • webprototype polish — keyword volume arrows + Strategy validity dots
  • webprototype polish — SEO live-data pill, tier pills, stepper gating, delete side-effects
  • webrebuild campaign List card to the prototype; drop "dark-first" doctrine
  • webStrategy progressive disclosure + shared Collapsible primitive
  • webView/Delete polish — mode tile, SEO row, competitor chips, dup toast
  • webwire site-runs into List cards — needs-attention pill + live-run strip

Fixes

  • campaignsforward authorityDomains through campaignDocToCluster
  • campaignsnormalize legacy object-shaped keyword/authority arrays in edit form
  • campaignstopic interview step shows AI seeds only, not bank keywords
  • convertcorrect Review previews — personas count, provider logos, keywords, switch
  • convertschemeless source siteUrl 400'd the move; calmer convert step
  • editorauto-size + soft-wrap the code block
  • growthkeep recordAttribution bound to GROWTH_EVENT_SECRETS
  • growthretry OCI uploads + never permanently lose a signup conversion
  • headlesshonor postStatus on stock-served posts + diversify authority links
  • headlessstrip keyphrase-bolding the model emits despite the prompt
  • migratestrip stray <code> wrapper from imported code blocks
  • portalcount posts-this-week from workspace-rooted runs
  • seoAI-relevance-filter the long-tail pool, not just token-match
  • seofilter long-tail pool to genuine variations of bank keywords
  • seostop the monthly keyword refresh from drifting the bank off-topic
  • webmove campaign filter/needs-attention keys into the campaigns namespace
  • webno auto-discovery on the campaign edit screen
  • webrefetch the raw campaign doc after edit so the view isn't stale

v2.5.0

Features

  • clientdisable campaign image toggles when uploads dir is unwritable
  • pluginwarn + guide when the uploads dir blocks image saves
  • surface plugin image-sideload failures as "completed with warnings"

Fixes

  • generatehonor post status on single-post gen; never surprise-publish
  • pluginan image sideload failure must not destroy the post
  • uicenter the logo + give the page a dark-mode background

v2.4.0

Features

  • conversionWP→headless site conversion backend (preview + start)
  • convert"Move to Headless" wizard (portal frontend)
  • headlessadd a distinct "draft" post status
  • migratere-polish imported posts + richer html-to-blocks parse
  • opsdaily reconciliation cron for paid-but-unprovisioned accounts
  • opspage ops on billing-webhook + signup-provisioning failures
  • sitesDrafts tab + DRAFT badge + 3-way editor status control
  • sitesre-polish action for imported posts + open imports in editor
  • webBetter Stack error tracking (Sentry SDK) + copyable error block
  • webpage-level error boundary so a page failure degrades in-shell

Fixes

  • authoritybroaden per-post authority search beyond top-3 domains
  • billingdon't 500 the overview when the invoice list 403s
  • growthsupport gbraid/wbraid in Google Ads OCI + bump sunset API version
  • headlessrespect campaign "Publish immediately" on delivery
  • signupkey provisioning idempotency on the license, not the user doc
  • uifull-viewport height on AppLoader splash screen

v2.3.0

Features

  • headlessemail the site owner when a new draft is ready to review
  • sitestop-right "Re-discover" button in campaign discovery steps
  • supportsend the ticket submitter a branded confirmation email

Fixes

  • billingredirect checkout to the hosted session url
  • billingstop expanding past Stripe's 4-level limit in overview
  • headlessresolve %lang% permalink token so URLs/redirects don't emit a literal
  • headlesssupply internal-link candidates to stock-generated posts
  • seo-intelground campaign keyword re-rank on the objective
  • sitesraise discovery callable client timeout (deadline-exceeded)

v2.2.1

Fixes

  • connectredirect into new site after WordPress connect celebration
  • onboardingdrop "What does your site do?" from the wp-admin wizard
  • workspaceshide retired/merged workspaces from listMyWorkspaces

v2.2.0

Features

  • onboardingper-site persona membership in the wp-admin wizard
  • personasbearer-auth membership endpoints for the plugin wizard
  • pluginpersona membership REST routes + envelope for the wizard

Fixes

  • onboardingSEO auto-draft retry + manual competitor suggest
  • plugin/wizard/state returns a quiet fresh state when license-less
  • portalredirect to Sites when a site route resolves to a deleted site

v2.1.0

Features

  • keywordsshow real DFS monthly search volume on keyword chips
  • onboardingauto-add DFS-measured competitors in the wizard SEO step
  • plugin"permanently delete all data" checkbox in the disconnect dialog
  • portal"permanently delete all data" checkbox in the removal dialog
  • portalkeep AI-guessed competitors as suggestions in onboarding SEO step
  • workspaceshard-purge path for site removal (+ last-site teardown)

Fixes

  • campaigns/sitepoll next-run, human model names, no auto-discover
  • clientgraceful recovery in the error boundary for a stale connection
  • i18nre-merge + complete de/de_AT/es/fr translations after wizard rebuild
  • seostop interstitial pages poisoning keyword/positioning discovery
  • usagescope the wp-admin cycle-usage widget to the current site

v2.0.0

⚠ BREAKING CHANGES

  • pluginremove site-level keywords + authorities (now campaign-scoped)
  • webremove site-level keywords + authorities (now campaign-scoped)

Features

  • campaignscampaign-level competitor augmentation (language-aware)
  • channelsmanage channels from the portal for non-WP surfaces
  • competitorsthread campaign language through the plugin suggestion path
  • keywordsdrive gap analysis from the campaign's competitor list
  • migratemigrate a WordPress blog into a headless site
  • onboardingadd the image-medium switcher to the wizard Visuals step
  • onboardingseed a site-specific persona even in a populated workspace
  • plugincampaign Competitors step + campaign-scoped persistence
  • pluginremove site-level keywords + authorities (now campaign-scoped)
  • seo-intelDFS-first multi-seed keyword discovery with smart-model re-rank
  • setupland SEO step prefilled, drop redundant step-1 description
  • webcampaign Competitors step (portal) — language-aware augmentation
  • webremove site-level keywords + authorities (now campaign-scoped)

Fixes

  • ai-enginekeep workspace-key rows single-line for long site names
  • authmagic-link deliverability + signup inbox recovery UX
  • authpolish magic-link "check inbox" panel
  • diagnosticsmake "Run a connection check" actually run the check
  • onboardinglocalize wizard AI drafts + decode entity in key picker
  • runsscope the "Recent generations" widget to the current site
  • siteskeleton the positioning editor while it loads
  • taxonomystop feeding the default category to the model; nudge it to create

v1.89.0

Features

  • channels/linkedinbrand-voice prompt variant for company Page posts

Fixes

  • channels/linkedinhide unreachable "Personal profile" target on org connections
  • channels/linkedinpopulate company-Page picker via versioned org-ACL read
  • channelsauto-open Configure modal after OAuth connect (hash params)