@seldonframe/mcp 1.25.0 → 1.25.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 (1) hide show
  1. package/package.json +3 -1
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "@seldonframe/mcp",
3
- "version": "1.25.0",
3
+ "version": "1.25.2",
4
+ "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.25.2: TWO HOTFIXES from the v1.25.1 production smoke. (1) Operator session now PRECEDES NextAuth in helpers.ts. Pre-1.25.2 getCurrentUser/getOrgId/requireAuth checked NextAuth first, then operator-portal as a fallback. Smoke surfaced 2026-05-07: a user with BOTH a stale NextAuth cookie (from a prior /signup attempt that hit the Verification error) AND a fresh operator-portal cookie was treated as a NextAuth user — full SF admin nav showed instead of the trimmed operator nav. v1.25.2 reorders: operator portal cookie wins when present + valid. Falls through to NextAuth → admin-token otherwise. Intent-based — clicking an operator magic link clearly means the user wants operator portal access. Same precedence applied across getCurrentUser, getOrgId, requireAuth. (2) Dashboard page org_members + organizations queries now gate on isOperatorPortalUserId. Pre-1.25.2 the dashboard page had its own org_members lookup `where userId = synthetic-id` that bypassed the v1.25.0 helpers' opCtx check, crashing with PostgreSQL 22P02 'invalid input syntax for type uuid' (the synthetic id `__sf_operator_portal__:<orgId>` isn't a valid uuid). v1.25.2 short-circuits: when isOperatorPortalUserId(user.id), membershipRows = [{ orgId }] (the operator's single workspace) instead of querying org_members, and directWorkspaceRows queries by organizations.id only (skipping the ownerId/parentUserId clauses that also crash). Defense-in-depth: lib/billing/orgs.ts's listManagedOrganizations + listManagedOrganizationsForUser now early-return [] when user.id doesn't match the UUID_SHAPE regex (8-4-4-4-12 hex). NO migrations, NO new env vars. Backend redeploy required.",
5
+ "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.25.1: hotfix — operator-portal sessions on /dashboard see a TRIMMED nav (Dashboard / Contacts / Deals / Bookings + Help) instead of the full SF nav (Soul Marketplace, Pages, Email, Forms, Automations, Studio, Settings). Pre-1.25.1, v1.25.0 unlocked the admin dashboard for operator sessions but didn't gate the sidebar — operators could see + click into SF-internal pages they shouldn't. v1.25.1: Sidebar component takes new props isOperatorSession + agencyBrandName threaded from the (dashboard) layout. When isOperatorSession=true: nav groups become OVERVIEW (Dashboard) / CRM (Contacts/Deals/Bookings) / ACCOUNT (Help) — Soul Marketplace, Pages, Email, Forms, Automations, Studio, Settings hidden. When agencyBrandName is set (via getEffectiveBrandingForWorkspace), the sidebar's brand subtitle shows the agency name + 'Cypress & Pine HVAC's CRM' subtitle instead of the default 'SeldonFrame / Operating system for modern teams'. Defense-in-depth: hidden nav items are still ROUTABLE if the operator types the URL directly — v1.25.2 will add a server-side gate that 404s SF-internal routes for operator sessions. NO migrations, NO new env vars. Backend redeploy required.",
4
6
  "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.25.0: ARCHITECTURAL PIVOT — operator session unlocks the admin dashboard (one source of truth at the route level). Pre-1.25.0 the operator portal at /portal/<slug>/* was a parallel route tree with its own bespoke chrome (light-mode shell, sidebar, agency branding wrapper) that visually drifted from the admin dashboard (different fonts, sizes, spacing, dark vs light). v1.24.0 tried to fix this by sharing components but the bespoke shell was still a separate surface. v1.25.0 takes the cleaner approach: the operator session unlocks the SAME admin dashboard the SF agency operator uses. /dashboard, /contacts, /deals, /bookings — same routes, same nav, same fonts, same theme toggle (light/dark), same UX. Just (a) workspace-scoped to the operator's org via the sf_operator_session cookie and (b) the user can only access ONE workspace (no switcher). HOW IT WORKS: (1) New lib/auth/operator-portal-context.ts adds operator-portal session as a third auth source alongside NextAuth + admin-token. resolveOperatorPortalContext reads sf_operator_session cookie, verifies the JWT (kind=session), produces a synthetic Session-shaped user with `id` carrying the __sf_operator_portal__: prefix (recognizable via isOperatorPortalUserId so users-table writes can no-op, mirroring admin-token treatment), the workspace orgId, and NextAuth-shape fields (planId=null, subscriptionStatus='trialing', etc.) for type compatibility. (2) lib/auth/helpers.ts getCurrentUser / getOrgId / requireAuth / getCurrentWorkspaceRole all gain operator-portal as a third option. Resolution order: NextAuth → operator portal → admin-token. Operator-portal precedes admin-token because magic-link is the dominant white-label entry path. (3) /(dashboard)/layout.tsx detects operator session via isOperatorPortalUserId and skips users-table lookups (same skipUserLookup gate that admin-token already used) — synthesizes plan/billing defaults, hides the workspace switcher (no listManagedOrganizations call). (4) Operator magic-link verifier (/portal/<slug>/magic) and agency-support-session verifier (/portal/<slug>/support-magic) redirect targets switched from /portal/<slug> to /dashboard. Operator clicks email link → cookie set → land at /dashboard which renders the admin shell with their workspace's data. (5) The /portal/<slug>/(operator)/* route tree is collapsed: layout.tsx becomes a session-gate pass-through, page/contacts/deals/bookings/page.tsx all redirect to /dashboard /contacts /deals /bookings respectively. Existing magic-link emails in customer inboxes still work because they hit /portal/<slug>/magic (which now redirects to /dashboard). (6) Bespoke operator-portal-shell / operator-portal-nav / operator-portal-sidebar-nav components are no longer rendered (kept in repo as v1.20-v1.24 history; safe to delete in v1.25.1). v1.24.0's shared page-view components (contacts-list-page-view, deals-list-page-view, bookings-list-page-view) STAY — they're still the data-loading layer behind the admin pages. The hrefBase + readonly props are now vestigial for those components but harmless. WHAT THE OPERATOR SEES: admin dashboard chrome — search palette, light/dark toggle, sidebar nav (Dashboard / Contacts / Deals / Bookings / Pages / Email / Settings), agency-branded workspace name in header. Same fonts, same spacing, same UX as the SF agency operator's dashboard. NO migrations, NO new env vars, NO new MCP tools. Backend redeploy required. DEFERRED to v1.25.1: agency-branded banner on /dashboard when active partner-agency is set (currently the operator sees the SF default chrome — branding lands on emails + the operator portal login but not the dashboard yet); hide SF-internal nav items (Soul Marketplace, Agency, Settings/billing) for operator-portal sessions; dual-auth refactor for write actions like updateContactFieldAction so operator-portal users can edit (currently writes still target NextAuth getOrgId — which now resolves correctly via the new auth seam, so writes likely work; needs verification).",
5
7
  "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.24.0: ONE SOURCE OF TRUTH — operator portal /contacts /deals /bookings now render the EXACT SAME COMPONENTS as the admin dashboard equivalents. Pre-1.24.0 the operator portal mirrors I shipped in v1.22 were simpler bespoke versions (basic Twenty-CRM-style tables) that visually didn't match the admin pages. v1.24.0 refactors so /contacts, /deals, and /bookings each have ONE shared view component used by BOTH admin route AND operator portal route — same data fetching, same UI, same UX. ARCHITECTURAL CHANGES: (1) Data primitives accept orgId override. listContacts(options.orgId), listDeals(orgId), listBookings(orgId), listAppointmentTypes(orgId), getDefaultPipeline(orgId), getSoul(orgId), getLabels(orgId), getPersonality(orgId) — all gain optional orgId parameter. When set, skips the session-based getOrgId() call; when null, falls through to the existing session resolution. This is the seam that lets the same query helpers serve both the admin's NextAuth-resolved orgId AND the operator-portal's sf_operator_session-resolved orgId. (2) Three new shared components: <ContactsListPageView orgId searchParams baseHref contactDetailHrefBase dealDetailHrefBase readonly>, <DealsListPageView orgId searchParams readonly>, <BookingsListPageView orgId readonly>. Each does the entire page load + render. The admin /contacts /deals /bookings pages are now 5-line thin wrappers that resolve session→orgId and pass through. (3) ContactsTableView gains contactDetailHrefBase + dealDetailHrefBase + readonly props. /contacts row clicks route to /contacts/<id> (admin) or /portal/<slug>/contacts/<id> (operator) based on the prop. SidePanel + DealsTab + OverviewTab thread these props down. (4) Operator portal mirror pages are now 5-line wrappers too: resolve operator session → orgId → render the same shared component with `readonly` set + workspace-aware hrefBase props. The v1.22 bespoke operator pages (smaller Twenty-CRM tables) are deleted. READ-ONLY MODE: v1.24.0 ships read-only operator mirrors. Inline edit, drag-drop, status changes, bulk-select are wired to NextAuth-backed server actions (e.g. updateContactFieldAction calls getOrgId() which reads NextAuth) that the operator-portal session can't satisfy. ContactsListPageView passes readonly=true from operator routes; the ContactsPageActions header (CSV import + add new) is hidden in readonly mode. v1.24.1 will refactor the write actions for dual-auth so operator-portal users can edit too. DEFERRED TO v1.24.1: /dashboard mirror (1,359-line page; needs careful extraction to avoid regressions); /contacts/<id> detail mirror (Overview/Activity/Deals/Emails/Bookings/Documents/Notes tabs); dual-auth refactor of write server actions so operator portal becomes write-capable. NO migrations, NO new env vars, NO new MCP tools. Backend redeploy required.",
6
8
  "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.23.0: month-calendar reschedule + operator dashboard cleanup. WHAT SHIPS: (1) RESCHEDULE NOW USES THE SAME CALENDAR AS /book. v1.22 shipped a date-tabs + slot-grid layout that worked but visually didn't match the /book/<slug> calendar (3-step indicator, full month-grid). v1.23 swaps in CustomerRescheduleCalendar (React) — 3-step indicator (Pick a date / Choose a time / Confirm reschedule), MON-SUN month grid with prev/next navigation, today highlight, past dates disabled, click-day → time-slots fetched via new /api/v1/public/booking-slots endpoint, click-slot → confirmation panel → atomic rescheduleBookingAction. Same backend (single source of truth via listPublicBookingSlotsAction); just better-matched UX surface. New thin GET endpoint /api/v1/public/booking-slots wraps the existing slot enumerator so client-side calendars can fetch availability without re-running the full /book renderer. (2) OPERATOR DASHBOARD CLEANUP. Removed the stale 'Coming in v1.21' card from /portal/<orgSlug> dashboard — those mirror pages (/contacts /deals /bookings) shipped in v1.22 so the placeholder was incorrect. The 'last 8' / 'v1.21 — full activity feed' label on Recent activity replaced with a count-based subtitle ('last N'). Customer-reschedule-client (v1.22 date-tabs implementation) deleted. NO migrations, NO new env vars, NO new MCP tools. Backend redeploy required. v1.24 queued: extract admin /contacts /deals /bookings/<id> into shared components, wire operator portal mirrors to render the same components — true one-source-of-truth so /portal/<slug>/contacts looks IDENTICAL to /contacts (just scoped). Currently the operator-portal mirrors are simpler bespoke versions; v1.24 makes them indistinguishable from the admin pages.",