Releases
Every Pectus release lists what changed and any required actions. If a
version adds a database migration or a config change, it shows up here
first. The CMS itself surfaces the same prompts inline when it detects
a missing migration.
v0.4.24
2026-05-17 GA4 fetch fixed, ATP CSV import, shared settings nav - GA4 fetch was failing with HTTP 400 because Google deprecated the `averageEngagementTime` metric. Swapped to `averageSessionDuration` (the current valid metric for session length in seconds). Existing brands can refresh their GA4 data again without any reconfiguration.
- Found and fixed a pre-existing silent bug: the Stage 1 GA4 reader was looking up metrics by GA4 API names (totalUsers, newUsers, engagedSessions) but the analytics_metrics table stores canonical names (total_users, new_users, engaged_sessions). Every metric except sessions, pageviews, and conversions was silently dropping out of the prompt. Stage 1 now sees the full set.
- Seed-keywords app activatable from the project sidebar for the first time. New Settings page at `/apps/seed-keywords/settings` with the first ATP (AnswerThePublic) CSV import. Parser accepts AnswerThePublic exports plus any CSV with a Text / Question / Phrase column. Optional Seed / Tab / Bucket / Locale columns with fuzzy header matching. If the CSV lacks a Seed column, a fallback input on the form supplies it. Upserts ignore duplicates so re-imports are idempotent.
- Settings nav (Overview / Account / Brand / Google / Environment / Updates / Users) now persists across Brand and Google integration pages — previously it disappeared the moment you clicked into a brand-scoped settings page. Extracted SettingsNav into a shared component mounted from both layouts.
- Seed-keywords settings page links to the existing Project keywords editor instead of duplicating it. One click into the canonical seed-keyword editor.
v0.4.23
2026-05-17 App directory clarity, GSC CSV fallback, fail-soft analysis Required action Apply migration 0007_gsc_pages.sql
Adds the `gsc_pages` table for the new Search Console Pages-CSV import. Per-(project_id, page) aggregate with impressions / clicks / position / CTR. Apply it from `/settings/updates` after pulling.
File: connectors/supabase/migrations/0007_gsc_pages.sql ↗
- Global /apps directory cleaned up. "Installed" and "Active · N" badges removed — they confused users into thinking the app was usable when it just meant the code was present. Replaced with an "Install from project →" CTA link and a "Coming soon" pill for apps that aren't built yet (Sources). The project-level Apps page hides coming-soon apps entirely; they only appear in the global directory.
- Every APP.md description rewritten to start with "Use this to…" in plain language. Cards read as user benefit ("Use this to pull Google Analytics 4 traffic into Pectus so the analysis knows which pages already work") instead of implementation detail.
- Shared Google service-account panel on GA4 + GSC settings pages collapsed into a single-line `<details>` summary when connected. The app-specific config (property ID / site URL / refresh / data) now dominates the page instead of the shared credential.
- **New: GSC CSV import.** Search Console settings page has an "Import from CSV" section with two slots. Queries CSV upserts into the keywords table (same shape `fetchGsc` writes); Pages CSV upserts into the new `gsc_pages` table for future page-level analysis. Both stamp project_data_freshness so Analyze treats the data as fresh. Unblocks brands where the Google service-account email is rejected by Search Console (a known Google bug).
- Insights flow is now fail-soft. If the Stage 1 interpretation throws (schema or API), a placeholder interpretation row saves so Recommend can always run. Stage 2 has a new hard constraint: "do not suggest topics the reader has already written. The EXISTING ARTICLES section above is everything they've already published." Plus an explicit "Always return 5. Never zero." The product contract is "5 post suggestions on demand, that don't duplicate existing articles" — the underlying interpretation flakiness no longer breaks that.
- Re-analyze demoted to a dotted-underline text link beneath the primary CTA. Previously it sat side-by-side with Recommend, which made it look like an alternate path to the same outcome (post suggestions). It refreshes the interpretation, not the suggestions.
- Project home gets a welcome banner above the page header with a copy-pasteable `npx pectus update` command. Pink-orange gradient, Copy button swaps to "Copied ✓" — consistent with the Insights SummaryBox.
v0.4.22
2026-05-17 Ideas-first Insights layout + sticky section nav - Insights page reordered so the actionable ideas sit at the top, with the analysis tables below. Real usage showed users scrolled past the interpretation to reach the work; now they don't have to.
- **New SectionNav** — sticky pill-tabs inside the canvas (Summary / Ideas[N] / Analysis). IntersectionObserver highlights the active section as you scroll; click to jump. Lives below the page header, sticks to the top of the viewport once the header scrolls past.
- **New SummaryBox** — the Stage 1 summary pulled out of InterpretationPanel into a prominent foldable card. Gradient pink-orange background, two-column 14px prose layout, "Interpreted X ago" timestamp. Open by default; collapse via the chevron to save space.
- InterpretationPanel renamed "Drill into the data" — the headline summary lives in the SummaryBox above, so the panel is now the table-by-table drill-down (top pages, declining pages, query movers, clusters, rising keywords, categories, negatives).
- IdeaCard tightened to roughly half its prior height. Single-line truncated title, chips + persona + projected traffic in one inline meta row, rationale moved into a `<details>` "Why" disclosure. Five cards now fit comfortably above the fold.
v0.4.21
2026-05-17 Two-step Insights: Analyze first, then Recommend - Insights splits into two distinct surfaces. **Analyze now** runs the data interpretation and shows the findings as a readable panel. **Recommend posts** then reads that interpretation and produces five ranked article ideas. The old single "Run analysis" button is gone.
- The interpretation panel is the new top-of-page surface. Traffic source mix, top-performing pages (with conversion rate), declining pages with refresh actions, weekly query movers (rising + declining), keyword clusters, rising keywords, suggested categories, and negatives — all rendered as tables you read before being told what to write.
- Stage 1 now consumes the v0.4.20 `analytics_metrics` and `gsc_daily` tables: GA4 last 30 days (overall daily, top 50 pages by sessions, top 20 traffic sources) and Search Console last 14 days (impression-weighted week-over-week query deltas, top 8 risers + top 8 decliners).
- Clicking Analyze auto-refreshes GA4 + Search Console first if their last-fetched timestamp is older than 24 hours. Best-effort — if a fetch fails, the snapshot row records the error and Stage 1 proceeds with whatever data is already in the tables.
- Recommend is reusable against the same Analyze run. Click Recommend repeatedly (or the existing Renew) and you get different idea passes without re-paying for the interpretation tokens. Re-analyze creates a fresh interpretation when the data has moved.
- Page state machine derived from current DB rows on every render — no client state. Refresh, new tab, and shared sessions all converge on the right surface (no interpretation → Analyze; has interpretation no ideas → Recommend; has ideas → cards + Renew + Re-analyze).
v0.4.20
2026-05-16 GA4 + Search Console fetch pipeline goes live Required action Apply migration 0006_analytics_metrics.sql
Adds the cross-source `analytics_metrics` table (every analytics-style inbound app writes here: GA4 today, Google Ads / Meta / LinkedIn / Microsoft Ads later) plus the `gsc_daily` time-series table. Apply it from `/settings/updates` after pulling.
File: connectors/supabase/migrations/0006_analytics_metrics.sql ↗
- GA4 and Search Console can now actually pull data. Each app's Settings page has a "Refresh now" button that calls the platform API and writes flattened rows into `analytics_metrics` (GA4) or upserts `keywords.metadata` + `gsc_daily` (Search Console).
- GA4 pulls three reports per refresh: overall daily (sessions, users, pageviews, engagement, conversions), per-landing-page (with conversions), and per-source/medium. All three land as rows in `analytics_metrics` with the dimensions stored in jsonb — same shape future Google Ads / Meta / LinkedIn writers will use, so consumer apps read across all sources from one table.
- Search Console writes the 28-day aggregate into `keywords.metadata` (preserves your existing search_volume / difficulty / intent) and the 7-day daily per-(query, page) grain into `gsc_daily` for trend analysis.
- New cross-source reader at `cms/src/lib/analytics.ts`: `readAnalyticsMetrics({projectId, sources?, metricNames?, since, until})`, `aggregateByDate`, and a `readBlendedCpa` helper that joins paid spend with organic conversions (ready for the next paid-source writers).
- Service-account auth only for now. The OAuth-via-user-Gmail path is parked — it works UX-better but requires running a Google-verified OAuth client. Defer until there's a real demand reason.
v0.4.19
2026-05-16 Connect inbound apps directly from their Settings page - GA4 and Search Console Settings pages now embed the actual setup forms — service account JSON paste, property ID / site URL field, Test connection button. No round-trip through the shared Google integration page to fill in credentials.
- The shared `/brands/[slug]/settings/integrations/google` page still exists as the canonical credential store; the inbound app Settings pages read from it and offer a write-through form when the credential is missing.
- Last-verified timestamp visible on each Settings page so you can tell whether the connection has been validated since the last credential change.
v0.4.18
2026-05-16 Inbound apps are settings-only; Sources arrives as coming-soon - Inbound apps (GA4, Search Console, Sources, future paid-media connectors) now have one user-facing surface each: a Settings page. No dashboards, no lists, no editors. The interpreter copy on each page explains what the data feeds in Pectus; the connection-state card shows current credential / property / site / last-verified; a link points at the shared Google integration page where setup lives.
- Sources broken out of Content Insights into its own inbound app with `comingSoon: true` in APP.md. It shows in the App Directory with a "Coming soon" pill and a disabled Activate button; the planned page+sitemap scraper is the next inbound build.
- Sidebar manifest changed: GA4 "Performance" → "Settings"; GSC added with "Settings"; Sources added with "Settings". Removed: `apps/ga4/performance/page.tsx`, `apps/content-insights/sources/page.tsx` (the dashboard placeholders that hadn't shipped and shouldn't have lived in inbound apps in the first place).
- New `comingSoon` field on `AppManifest`; the activate server action guards against it so users can read the planned-functionality page without being able to activate a stub.
- New `SidebarHeadingLink` component renders a "Browse apps" link styled like the Project settings section heading, placed above Project settings in the sidebar footer.
v0.4.17
2026-05-15 Content Hub renamed to Content Insights (163 files) Required action Apply migration 0005_rename_content_hub_to_insights.sql
Renames `projects.content_hub_repo` → `content_insights_repo` and updates `activated_apps.app_name` + `app_config.app_name` rows from `content-hub` to `content-insights`. Idempotent via `IF EXISTS` against `information_schema.columns`. Apply it from `/settings/updates`.
File: connectors/supabase/migrations/0005_rename_content_hub_to_insights.sql ↗
- App slug `content-hub` renamed to `content-insights` everywhere: folder paths, package name (`@pectus/content-insights`), tsconfig path aliases, install agent script, README, CHANGELOG, pectus.ai docs (with a `/docs/apps/content-hub` → `/docs/apps/content-insights` redirect added in `astro.config.mjs`), DB columns via migration 0005.
- `npx pectus update` now connects to Supabase, diffs migration files against the `_pectus_migrations` ledger, and prints a pending-update notice with a `/settings/updates` link if anything is unapplied. Graceful fallbacks for missing env, missing baseline, or unreachable DB.
- `apps/seed-keywords/` finally tracked in git (had been untracked while other tracked code referenced it as a registered app — fresh installs would have shipped broken references).
- Tag `v0.4.17` pushed so GitHub's "Latest Release" advances from v0.4.14.
v0.4.16
2026-05-15 Fresh-install grants + Insights gate tightening - `0001_pectus_v04.sql` appended with a `grant` block and `alter default privileges` clause that restores Supabase's stripped schema-public grants after the install flow's drop-and-recreate. Fixes the "permission denied for table brands" error on `npx pectus brand sync` against a fresh install.
- Install agent (`pectus.md`) cost copy in step 5 corrected from "$5–$15, load $20" to "under $1 for a typical week, $5 minimum if you want headroom." Anthropic API spend on Pectus's standard skills is much smaller than the original estimate.
- `pectus.md` step 6a teaches the multi-migration scenario silently and routes anything beyond `0001` through the in-CMS `/settings/updates` overlay. New step 8c reminds the user about the overlay if they pulled with pending migrations.
- Insights gate tightened: GA4 or Search Console is now required to unlock the Analyze button. Keywords alone no longer unlocks it — without a real data source, the analysis has nothing to interpret.
v0.4.15
2026-05-14 User-feedback triage + multi-brand path fixes - GA4 and Search Console deferral baked into the install flow: those connectors are no longer required to boot Pectus. Honest-disabled gating surfaces on every Google-data surface until a service account is added.
- Multi-brand path mismatch fixes at three layers: brand resolver, project lookup, and skill-runner brand context. Brand-prefixed routes resolve consistently when the brand slug contains non-ASCII characters.
- Inbound / outbound chip filter on both Apps pages (project-level and brand-level). Inactive apps still listed, but the chip filter narrows by app type.
- README reframe in the public repo: scaffolding for builders, four-layer ASCII diagram, APP.md example, honest scope sections, ecosystem-play closing.
- pectus.ai homepage reframed in the same direction: positioned as a builder framework, not a finished product. New honest-scope sections name what works today and what doesn't.
v0.4.14
2026-05-11 Pages builder UX + Files library - Pages builder preview now renders inside the CMS at `/pectus-preview/[variantId]`. Same origin as the rest of the CMS, no second dev server. The Astro app stays for publishing.
- Canonical env model: one `cms/.env.local` file. CMS auto-snapshots from `process.env` at boot; a settings UI edits them; a shared loader (`scripts/load-pectus-env.mjs`) hands the same values to any app with its own runtime.
- Make-it skill teaches the env pattern so new community apps inherit it by default.
- Files library in Content Insights: per-project Supabase bucket with thumbnail grid and drag-and-drop upload.
- Brand profile gains a Type sizes section (H1/H2/H3/body), persisted to `brands.font_sizes`.
- Eleven commits between `4477b4d` and `12a2a37` on main covering builder UX, env consolidation, and brand-profile polish.
v0.4.4 → v0.4.13
2026-05-09 Migration runner, Insights, Articles authoring Required action Apply migration 0002_content_insights.sql
Adds Content Insights Insights + Articles tables: article_transitions, data_snapshots, data_interpretations, idea_generations, idea_post_dismissals, llm_usage, brand example photo categories, image-gen API key slots (google_genai, fal, replicate), and the `_pectus_migrations` ledger. Apply it from `/settings/updates`.
File: connectors/supabase/migrations/0002_content_insights.sql ↗
- In-CMS migration runner at `/settings/updates`. Pasting `0001_pectus_v04.sql` is the one-time bootstrap; subsequent migrations apply via the Supabase Management API on the user's behalf, with copy-paste fallback when SUPABASE_ACCESS_TOKEN isn't set.
- Insights lands the Content Insights. Run analysis fires Stage 1 (Opus interpretation of GA4 / Search Console / keywords / articles snapshot) and Stage 2 (Opus 5 ranked ideas). Idea cards offer one-click Draft → AI Write → Sonnet 4.6 generated draft → article editor with status workflow → Publish.
- Articles index rebuilt: table with search, status filter, categories chip line, per-row Archive / Delete, bulk-select with action dropdown, Import for shells. AI Write fields persist across tab switches. Generate-article modal walks 8 stages with progress dots.
- Article editor on TipTap: H2/H3, B/I/S, link via inline popover, bullet/ordered/quote, undo/redo, image upload + AI image generation through Google (Imagen 4, Gemini 3 Pro), fal.ai (Flux Pro 1.1 Ultra), and Replicate (Flux Dev, Recraft v3).
- Status workflow: draft → brand_review → market_lead_review → published | archived, with a StatusBar at the top of the editor owning transitions.
- Brand example photos rebuilt per spec: categories with descriptions, drawer with Gemini 3 Flash describe, parallel upload of 5 with thumbnails + per-file XHR progress, auto-save on upload.
- Image-gen API keys (Google AI / fal.ai / Replicate) live in a power-up panel inside the brand profile's Image generation card. Stored in `integrations` per brand under jsonb `service_account_json: {"api_key": "..."}`.
- Article slug collisions now use incrementing `-2`, `-3` suffixes via `uniqueSlug()` instead of timestamp-base36.
- CSS hygiene: cms/CLAUDE.md documents the Tailwind-utilities-first policy. ~95 dead `.pectus-*` rules (~890 lines) removed from `globals.css` after a build-time cascade audit.
v0.4.2
2026-05-05 Connector framing + IA refactor Required action Wipe and reinstall: paste the squashed 0001_pectus_v04.sql
v0.4.2 squashes every previous migration (0001–0008) into a single `0001_pectus_v04.sql`, renames `workspaces` → `projects` everywhere (DB, routes, CLI), and re-keys app activation per-project. There is no automatic upgrade path. To move from v0.4.1: drop / reset your Supabase project, re-clone or `npx pectus init` from scratch, walk pectus.md to rebuild brand + first project, then apply the squashed migration via `/settings/updates`.
File: connectors/supabase/migrations/0001_pectus_v04.sql ↗
- Pectus is framed as a connector framework with a UI, not a CMS. Content-hub is one app among peers (alongside GSC, GA4, seed-keywords).
- Three gating principles enforced on every interactive surface: must-create-without-integrations, honest-disabled, article-authoring-never-gated.
- `workspace` → `project` rename across CMS, CLI, install agent, every app's APP.md, and every skill's SKILL.md. `pectus workspace add` keeps working as an alias for `pectus project add` for one release.
- Smart surfaces collapse into apps: pages, articles, sources, reviews, plan, gap, settings/site-url, settings/redirects, settings/review-policy all moved under apps/content-insights/. settings/seed-keywords moved under apps/seed-keywords/settings. performance moved under apps/ga4/.
- Apps page is project-level: `/brands/<slug>/projects/<code>/apps` lists installed apps with per-row Activate / Deactivate. Per-project sidebar derives groups from each activated app's manifest.
- Settings panel: /admin and /system/updates retired. New /settings hub at /settings/account, /settings/users, /settings/updates, plus brand-scoped /brands/<slug>/settings. NavBar shows Settings instead of Admin / Updates.
- Gating via <NeedsCard>: site plan, gap analysis, GA4 performance, GSC keyword sync, and Publish all gate honestly. Missing prerequisites render an inline CTA card with deep-links to the fix.
- Add-brand modal on /brands. Keyword importer accepts .csv / .tsv / .xls / .xlsx.
- Legacy redirects: `/brands/<slug>/workspaces/<code>/...` URLs 301 to the new `/projects/<code>/...` shape for one release cycle.
v0.4.1
2026-05-04 Slug fix + CMS-driven updates Required action Apply migration 0008_slug_unaccent.sql
Rewrites public._slugify to use the unaccent Postgres extension before character stripping. Re-slugifies every existing brand row whose stored slug differs from the canonical form. Idempotent. Apply it via the new /system/updates page or the Supabase SQL editor.
File: connectors/supabase/migrations/0008_slug_unaccent.sql ↗
- v0.4.0 alpha shipped with two slugify implementations that disagreed on Unicode. The CLI used NFKD; the SQL `_slugify` had no diacritic handling, so `Aström` produced two different slugs and broke every `/brands/<slug>/...` route for non-ASCII brand names. Migration 0008 fixes it.
- /system/updates page: lists every migration in connectors/supabase/migrations/. Click Apply to run a migration against your Supabase project via the Management API.
- runManagementSql helper wraps POST https://api.supabase.com/v1/projects/<ref>/database/query with project-ref derivation from NEXT_PUBLIC_SUPABASE_URL.
- NavBar gains an Updates link visible to every authenticated user.
v0.4.0
2026-05-04 Multi-brand alpha Required action Apply migration 0007_v0_4_multi_brand.sql on a fresh project
Renames `brand_profile` → `brands`, drops the singleton constraint, adds `slug` (NOT NULL UNIQUE) + `created_at`, and adds `brand_id` FK with ON DELETE CASCADE on 19 child tables. Backfills, then NOT NULL + indexes. Re-scopes `projects.code` and `integrations.provider` uniqueness per-brand. This migration is destructive on schema, so re-run on a fresh project or take a backup first. After upgrade: `npx pectus update` runs the disk migration that moves `brand/` → `brands/<slug>/` and `knowledge/` → `brands/<slug>/knowledge/`.
File: connectors/supabase/migrations/0007_v0_4_multi_brand.sql ↗
- Pectus now hosts multiple brands inside a single install. Every brand gets its own row, its own disk directory at brands/<slug>/, its own slug-prefixed URL space, and its own scoped DB rows.
- Brand-prefixed routes: (app)/{brand,apps,reviews,performance,projects} physically moved under (app)/brands/[slug]/. New /brands index page lists every brand.
- BrandSwitcher in the top nav: cascade-fallback server action that swaps the slug and lands on the deepest path that still resolves under the new brand.
- Middleware redirects: every legacy flat path (/brand, /apps, /reviews, /performance, /projects/...) resolves to the brand-prefixed equivalent based on the pectus.lastBrand cookie.
- Skill runner brand-aware: project lookup includes brand_id; brand row resolved once per run; gatherKnowledgeInsights(brandSlug) reads from brands/<slug>/knowledge/insights.md.
- CLI: `npx pectus brand add` is slug-parameterized. `npx pectus connect supabase` walks brands/<slug>/ directories and upserts each row.
- Install agent idempotency: pectus.md step 5 reads .env.local first and skips every variable already set, masking secret-shaped values to first 4 + last 4 characters.
v0.3.9
2026-05-04 Collect Supabase access token at install - Install agent (pectus.md step 5) now asks the user to generate a Supabase access token at https://supabase.com/dashboard/account/tokens and paste it back. Saved to .env.local as SUPABASE_ACCESS_TOKEN. Pectus needs this token to apply schema migrations and other Management-API operations on the user's behalf.
- .env.example documents SUPABASE_ACCESS_TOKEN with the token-page URL.
v0.3.8
2026-05-04 Fix stale /brand credential pointers - GSC sync error messages now point users to /apps/gsc instead of /brand for Google service account and Search Console site URL configuration.
- GscSyncButton UI hint updated for the same reason.
- Google OAuth init and callback routes redirect to /apps/ga4 on success/error instead of /brand.
v0.3.7
2026-05-04 Audit follow-up: auth, prompt caching, sidebar polish - Server actions in cms/src/app/(app)/apps/[name]/actions.ts now call requireUser() before mutating state.
- saveContentInsightsConfig switched from .single() to .maybeSingle() with a fallback redirect, so a missing project row no longer lands on /projects/undefined.
- Skill runner uses Anthropic prompt caching for stable input layers (BRAND, ICP, KNOWLEDGE INSIGHTS) and the system prompt. Successive runs in a 5-minute window read cached input tokens for the static layers.
- Sidebar groups no longer flash open on first paint when previously closed. Tooltips added to sidebar group labels and project header.
- Shared cms/src/app/components/InfoDot.tsx lifted from BrandForm.tsx so all '?' affordances reach for the same component.
v0.3.5
2026-05-03 Workspace sidebar + install polish - WordPress-style left sidebar inside /workspaces/[code], replacing the horizontal tab strip. Dashboard at top; activated apps render as their own collapsible groups; a Settings group holds ICP, Seed keywords, Keyword traffic, Sources, and Review policy. State persists per group in localStorage. Mobile collapses to an off-canvas drawer below 1024px.
- Settings → Site URL and Redirects moved out of the Settings group and into the Content Insights group, where they actually belong.
- Brand save no longer fails on the partial unique index.
- Three new install walkthroughs on pectus.ai: Anthropic API account, Supabase account, Google service account.
- Maintainer-specific identifiers replaced with generic acme-corp / your-brand examples.
v0.3.0
2026-05-03 Apps as plugins Required action Run migration 0006_activated_apps.sql
v0.3 adds two new tables (activated_apps, workspace_app_config) that gate which app surfaces render in the CMS. The migration also includes a backfill that auto-activates content-insights for any existing workspace with a mount slug or content_insights_repo set, so v0.2 users do not lose their Articles or Pages tabs after upgrading.
File: connectors/supabase/migrations/0006_activated_apps.sql ↗
- New top-nav entry Apps in the CMS. Lists every app under apps/* with status badges (Activated / Available), tooltips on type, and an Open button per card.
- Per-app settings pages at /apps/[name]. Each one is the real configuration UI: paste service account JSON for Google apps, pick GA4 property or Search Console site with live test, configure site shape and GitHub repo for Content Insights.
- Shared Google Cloud connection panel on GA4, Search Console, and Google Ads detail pages. One service account JSON powers all three.
- Content Insights becomes the first plugin. Workspace Pages and Articles tabs, plus Settings → Site URL and Redirects, only render when content-insights is activated.
- npx pectus workspace create now asks 4 prompts instead of 6. Site shape and GitHub repo moved into the Content Insights settings page.
- Updater (npx pectus update) now auto-stashes modified tracked files before rebase and pops after.
- Node.js floor pinned to ≥20.19 across root engines, pectus.md step 1, and pectus doctor.
v0.2.0
2026-05-01 Content Insights as website builder - Pages tab and visual page builder: 7 brand-aware templates (hero, feature grid, FAQ, pricing, testimonials, CTA, blog), 8 reusable blocks, locale chips, slug editor, draft preview iframe.
- Publish pipeline: URL resolution, automatic redirect generation when slugs change, single atomic commit per publish.
- Workspace Settings → Site URL and Redirects pages.
- Brand profile import from Claude Design (paste a Claude Design URL, get back a populated brand.json with colors, fonts, voice, and guidelines).
- Brand profile gains an Advanced subset (duotone accent, surface levels, semantic colors, mono font, radius preference).
- Insights architecture: per-skill insights table, base Insight type, skill-runner caches and re-runs interpretations only when stale.
- Seed Keywords app: per-workspace user-typed keyword list, used as the analysis spine when GSC traffic data isn't available yet.
- Workspace Getting Started checklist on the dashboard.
v0.1.0
2026-04-27 Initial scaffold - Repo skeleton: connectors/, apps/, skills/, knowledge/, brand/, cms/, cli/.
- Five seed skills: weekly-analysis, seo-strategy, jobs-to-be-done, internal-linking, knowledge-digest.
- Pre-installed content-insights app at apps/content-insights/ — a static Astro site that renders your articles and pages.
- CLI command stubs and reference documentation at https://pectus.ai/docs.