Matthew Meszaros
17635a99cc
feat: restore the app store's mailbox and tag slices by syncing them in DataSyncProvider (paged /emails directory query under the audit-spine-invalidated ['emails','list'] key plus profile tag definitions), un-breaking every surface that resolves mailbox-to-tag membership from the store: the compose From picker's tag filter chips, the unibox filter sheet's tag resolution, and the tag scope in the rail
2026-07-19 10:02:43 +02:00
Matthew Meszaros
22fddad234
feat: stop the dashboard-wide reload flashing: the reconnect catch-up invalidated every query on any socket RE-connect, so a flapping websocket refetch-stormed the whole app; now it only fires after a real outage (over 5s down) and at most once every 30s
2026-07-19 09:16:55 +02:00
Matthew Meszaros
6f8db3ae05
feat: de-template the cold-email humanizer (drop the quotable example asks and subject that models parroted verbatim, add a VARIATION section mandating a fresh skeleton per email and capping punchy standalone lines at one) and add compose drafts: autosaved per-user working copies (client-generated ids, idempotent PUT on a 1.2s debounce, migration 000072) with Saving/Saved in the window header, close-keeps-draft instead of the discard confirm, delete on send or when emptied, and a Drafts list under the rail Compose button to resume or delete, documented in the guide and endpoints scope map
2026-07-19 08:52:56 +02:00
Matthew Meszaros
0c4e63ab01
feat: make the compose window behave like a real docked draft: minimize to a compact corner bar (draft state stays mounted while you browse other pages, header click or chevron restores, n or any openCompose restores instead of clobbering the draft), a serious single-icon header that reads New email to <name>, <company> as the recipient resolves, and the body textarea aligned to the same horizontal padding as the subject and header rows
2026-07-19 08:31:53 +02:00
Matthew Meszaros
6790eabd74
feat: wire compose entry points: mount the window globally in the app layout, add the Compose button with an n shortcut tooltip to the unibox header, register the global n key (and update the shortcuts modal entry), and add an Email action to the contact drawer that opens compose prefilled with the contact's address
2026-07-19 07:38:48 +02:00
Matthew Meszaros
44bfe7840f
feat: add the compose web API layer (candidates + send clients, hooks with unibox invalidation, address/direction params on unibox search), a global useComposeStore zustand store so any surface can open the composer, and configurable draft row label/cost on TextareaAICaret so compose can say Draft this email with AI instead of the reply wording
2026-07-19 07:38:48 +02:00
Matthew Meszaros
1823f03a80
feat: live usage-based credit feedback — every fresh debit publishes BILLING_CREDITS_CHANGED through the creditwatch monitor so the header meter counts down in real time (AnimatedNumber tween, plus client-side invalidation on write/edit/draft success), generation responses now return the real credits_charged and tokens_used from the usage settle and every AI surface shows the true cost instead of flat labels, and the composer AI became overlay-based: the draft bar floats over the body instead of pushing layout, a sky sheen sweeps the input while the model writes, and the selection being rewritten is painted with pulsing highlight rects that grow as the rewrite types in
2026-07-18 16:30:05 +02:00
Matthew Meszaros
053ca6a71d
feat: usage-based AI credit system — every AI call reserves its flat minimum then settles the real token cost per model (light 1500/standard 400 tokens per credit, drain-to-zero overage settle wired into writing assistant, reply drafts, dashboard agent, inbox agent, research, automation nodes, and campaign switches), org spend controls in a new org_ai_settings table (day/week/month hard limits enforced in Consume, low-balance alert threshold, auto top-up config), a credit-watch monitor hook that fires BILLING_CREDITS_LOW realtime alerts once per day and buys the configured pack off-session via a new Stripe AutoTopUpCredits (idempotent on the PaymentIntent, bounded per month, Redis-locked), GET /subscription/credits/usage + GET/PATCH settings endpoints, and an AI usage & spend controls billing card (spend vs limits, 30-day chart, per-feature and per-model breakdowns, limits/reminder/auto-top-up form) with a realtime low-credit toast
2026-07-18 08:39:41 +02:00
Matthew Meszaros
e4a391c8a4
feat: make the assistant panel fully placeable: drag the inner edge to resize (360-720px, persisted), dock to the left or right screen edge from the header (persisted, dock bar follows), and panel-scoped shortcuts (Cmd/Ctrl+]/[ switch tabs, Alt+N new chat, Alt+W close tab, Alt+M minimize) listed in the shortcuts dialog
2026-07-16 07:50:24 +02:00
Matthew Meszaros
e87adf1251
feat: add agentMinimized and per-tab unseen state to agentSlice and make Cmd+I dock-aware (restores a minimized panel instead of closing it)
2026-07-16 06:52:30 +02:00
Matthew Meszaros
56de65380b
feat: inbox agent that drafts a suggested unibox reply on inbound human replies for human approve/edit/discard - paid + per-org opt-in (organizations.inbox_agent_enabled) feature where the consumer's reply hook, on a non-automated reply, detaches a goroutine (panic-contained, never blocks ingest) that checks entitlement, dedupes via ai_thread_drafts partial unique indexes (one pending per thread, unique source_message_id), pre-checks balance, grounds a reply in the thread history + org voice + skills via generation.Provider.Complete, reserves a draft row then charges 5 credits (idempotency inbox_agent:<draft.ID>, row unwound on a fresh context if the charge fails so no unpaid draft lingers), and emits an org-scoped AI_DRAFT_READY event gated on access_unibox; the agent never sends - only a human POST to /unibox/agent-drafts/:id/approve sends through the normal reply path, claiming pending->approved before send with an approved->pending revert on send failure, alongside list + discard endpoints; plus the unibox awaiting_agent_draft badge + agent_drafts search scope, an AgentDraftCard in the thread view with inline-editable approve-and-send/discard, the workspace settings opt-in toggle, CanUseInboxAgent paid gate, migration 000065, and docs (inbox-agent guide, endpoints, realtime)
2026-07-14 06:13:27 +02:00
Matthew Meszaros
2aec6745fa
feat: connect external MCP servers whose tools the AI assistant can use - ai_mcp_servers table with bearer tokens sealed by the org DEK cipher (never returned) and SSRF-validated https urls, a dependency-free streamable-HTTP JSON-RPC client (initialize/tools/list/tools/call over safehttp dial-time IP blocking with SSE+JSON handling and body caps), an mcp service that discovers tools on connect and contributes only enabled servers' tools to the dashboard agent as namespaced mcp_<server>_<tool> defs that are always write-class and never auto-allowed, a registry DynamicToolSource hook so per-org tools join the agent's tool set and resume executes them through ToolDefs, /ai/connections CRUD gated on manage_settings with an mcp_server audit entity and spine, a Connections settings page to add servers and review/enable discovered tools, and docs
2026-07-13 20:05:24 +02:00
Matthew Meszaros
a2f50b6572
feat: org AI skills (playbooks) that every AI feature loads and follows - ai_skills table (org-scoped, unique name per org, 32KB content cap) with a skills service exposing CRUD plus an enabled-skills preamble injected into the dashboard agent, contact research, and reply-draft prompts and a load_skill read-tool that returns a playbook's full content by name, /ai/skills CRUD gated on manage_settings (JWT) or the AI_AGENT scope (API) with an ai_skill audit entity and spine entry, an AI skills settings page (list rows opening a right-side drawer with name, one-line description, enable toggle, and a markdown body), and docs with two example playbooks
2026-07-13 19:46:25 +02:00
Matthew Meszaros
f48d51bf16
feat: AI contact research agent that gathers cited web findings per contact with sync and background-batch runs - contact_research_runs table plus a strict save_research schema (every signal and public_artifact must carry a url, confidence high/medium/low, signals<=5 hooks<=3, reject-and-reprompt once then fail), a text/template runtime prompt injecting org voice, contact record, objective, and 5-search/6-fetch budgets, a research service that drives search_web/fetch_url through the provider loop and charges 2 credits on save (billable even for nothing_found, refund-free since charged only on save, balance and abuse-cap pre-checked so a capped org never does free work), POST/GET /contacts/:id/research plus a 500-cap /contacts/research/batch draining through a bounded pool of 4 workers over FOR-UPDATE-SKIP-LOCKED claims (no new Kafka), an org-scoped AI_RESEARCH_PROGRESS realtime event gated to view_contacts, APIPermAIResearch bit 23, a ContactEdit Research tab and a ContactsTable bulk Research action, and docs; also org-scopes every credit and research idempotency key so a client-supplied Idempotency-Key can never replay across tenants
2026-07-13 19:34:11 +02:00
Matthew Meszaros
7f425c1624
feat: dashboard-wide AI assistant with streamed tool-use runs, per-action approvals, and per-iteration credits - agent_sessions/agent_messages/ai_tool_policies migration, aiagent service runs the M2 registry through the provider loop over a resumable jsonb transcript, streams text/tool-step/approval/done events over SSE, gates write tools behind approve/deny/always-allow (send always per-action) and charges 1 credit per iteration (budget 20, refund on provider failure, out-of-credits 402 insufficient_credits, cap 429 usage_cap_exceeded) with a resume-safe idempotency namespace, provider PreIteration budget hook, /ai/sessions endpoints (cursor list + two SSE runs) gated by membership with tools bound to the member's org-permission bits, APIPermAIAgent bit 22, ai_session audit entity + spine, and a right-side resizable panel (Cmd+I / sparkle button) with streamed text, collapsible tool steps, inline approval and draft-artifact deep-link cards, stop, new chat, and a credits/budget meter; tenancy enforced at the SQL layer and docs for the assistant, endpoints, permissions, and error codes
2026-07-13 18:46:43 +02:00
Matthew Meszaros
5d6ed2a068
feat: AI credit economy with monthly plan grants, non-expiring purchased top-ups, and Stripe billing - two-pool credit_ledger (monthly allowance reset each cycle on invoice.paid, purchased pool via checkout mode=payment fulfilled webhook-only), consume drains monthly-then-purchased, 3 fixed top-up packs, /subscription/credits balance+checkout+paginated transactions gated on manage_billing, one-time trial grant, billing credits card with balance ring and pack buttons, credit_purchase/credit_grant audit entities and spine, wired plan.monthly_credits through pg_plan reads/writes, retry-safe webhook idempotency, and an AI credits guide
2026-07-13 17:40:20 +02:00
Matthew Meszaros
c311529576
feat: guard cursor chat against IME composition keys, keep a sent message lingering through an incidental blur, broadcast chat typed while the pointer is off the tracked surface, and close the input on page navigation
2026-07-02 20:33:44 +02:00
Matthew Meszaros
f804538ff5
feat: make canvas selections self-healing with a receiver-side TTL, a heartbeat that retries unsent deselects, and a clear frame for the old surface on in-place resource changes
2026-07-02 20:33:44 +02:00
Matthew Meszaros
9f2b5d5586
feat: show each teammate's selected cards on the automation and sequence canvases as a name-tagged outline in their cursor color, with a selection heartbeat for late joiners and an unmount clear, plus cursor chat on both canvases
2026-07-02 07:40:06 +02:00
Matthew Meszaros
b1e68b3048
feat: add cursor chat to every collaborative surface, press / to type a message that floats next to your live cursor for teammates, riding the existing cursor frames with Enter-to-send and a linger-then-fade
2026-07-02 07:40:06 +02:00
Matthew Meszaros
c21f170429
fix: ignore live:patch frames in useLivePatch when the subscriber has no resource yet, instead of receiving every org patch
2026-06-30 19:20:08 +02:00
Matthew Meszaros
c1ad213dda
feat: make useLivePatch send-only when given no onPatch so mutation hooks can broadcast a live:patch without opening a channel subscription
2026-06-30 19:18:55 +02:00
Matthew Meszaros
cca4ea5817
feat: add a reusable useLivePatch hook over the live:patch transport for optimistic collaborative state updates scoped by resource
2026-06-30 10:34:14 +02:00
Matthew Meszaros
4111a1960b
feat: skip ephemeral LIVE_ frames in useRealtimeEvents so cursor and drag traffic never triggers react-query invalidation
2026-06-30 10:06:31 +02:00
Matthew Meszaros
4ca46317a5
feat: add the reusable useLiveCursors transport (throttle, heartbeat, TTL prune, gone-on-leave, gone-on-resource-change) and a useLiveCanvas wrapper that adds the live node-drag stream
2026-06-30 10:06:31 +02:00
Matthew Meszaros
8aec22ba71
feat: invalidate referral query keys on the referral and referral_credit realtime audit events in the web spine
2026-06-28 05:10:04 +00:00
Matthew Meszaros
38e9ca980f
fix: correct the dashboard /auth/me avatar and password endpoints, guard self-row actions on the members page, align the steps-page permission gate with the server, harden realtime event handling, and remove the dead admin roles client
2026-06-15 08:12:35 +02:00
Matthew Meszaros
c51946e4da
fix: track the current user's own audited mutations from the realtime actor id so collaborative editors can tell a self-made change (list-row toggle, another tab) apart from a teammate's edit
2026-06-14 11:12:07 +02:00
Matthew Meszaros
5cee0375f9
fix: let portaled pickers/menus nest inside capture-phase and popover containers via a shared data-floating marker, and migrate the last native date/time inputs (contact activity range, unibox snooze + send-later) to the themed pickers
2026-06-14 10:48:06 +02:00
Matthew Meszaros
fc5e014766
fix: remove dead admin Roles/Users/Plans tabs, point the deliverability 'all mailboxes' link at /app/emails, and add the missing document titles so those dashboard tabs no longer read 'Page not found'
2026-06-14 09:52:49 +02:00
Matthew Meszaros
587eae774e
feat: serve the entire customer API (auth + resources) only under /v1 with no unversioned alias, and repoint the web and admin clients to the versioned base accordingly
2026-06-13 07:18:23 +02:00
Matthew Meszaros
eb74b7dafb
feat: fix the Steps tab still pointing at /sequences and replace remaining user-facing Sequences with Steps (route page + folder renamed to steps, document title regex, permission labels, not-found hint, campaign count)
2026-06-12 10:03:02 +02:00
Matthew Meszaros
a7a43e0c4c
feat: rename the campaign sequences resource to steps across the API and URL (/campaigns/:id/steps), the JSON fields (target_step_id, step_id/step_name/step_index, analytics steps[], create body steps), the web client/models/route segment/labels, the audit step entity type, and the wire-contract docs; internal Go type names and the Kafka avro schema stay
2026-06-12 09:38:11 +02:00
Matthew Meszaros
f6540d9f2f
feat: rejoin org/user channels and force isConnected toggle on zombie-socket wake so a backgrounded dashboard tab resumes realtime events and presence without a reload
2026-06-12 04:34:13 +02:00
Matthew Meszaros
801c6b8619
fix: faster, research-backed websocket reconnect — replace the slow 1s/2s/4s exponential backoff with a fast-start schedule (first retry ~120ms) plus jitter, lower the heartbeat to 25s/8s for quicker dead-connection detection, retry token-fetch failures on the same fast backoff, and clear a Safari-suspended CONNECTING zombie socket on tab refocus so it reconnects instantly instead of hanging
2026-06-11 19:52:55 +02:00
Matthew Meszaros
9024d6bc21
feat: add proactive write-permission primitives — useWriteGuard (blocks a denied action before any request and pops the permission dialog) and PermissionButton (auto-locks with a lock icon when the member lacks the permission)
2026-06-11 18:51:59 +02:00
Matthew Meszaros
44d7c2a0c1
fix: make the realtime websocket reconnect reliably — reconnect on every unintended close (not just unclean ones), detect silently-dropped connections via a heartbeat watchdog that force-closes to trigger reconnect, and reconnect immediately when the network returns or the tab is refocused
2026-06-11 18:18:24 +02:00
Matthew Meszaros
b07d21b907
feat: add usePermission hook + a NoAccess surface that explains which permission a member is missing instead of rendering a blank page
2026-06-11 13:19:24 +02:00
Matthew Meszaros
aa9273fe06
feat: add autosave primitives — useAutosave hook (instant for toggles, debounced for text, with dirty/flush/retry status), an unsaved-changes registry context, and a Saving/Saved/retry header indicator
2026-06-11 13:00:18 +02:00
Matthew Meszaros
3473d09bcc
feat: fix review findings in the roles redesign — GetMembers role_id column (members endpoint 500), TransferOwnership role_id hygiene, accept-time role re-resolution, race-free in-use delete guard covering invitations, assignment anti-escalation with self-role-change block, canManage-gated members UI, colored RolePills, fresh currentOrganization on refetch, dev JWT_SECRET wiring for make realtime, docs corrections
2026-06-11 10:45:21 +02:00
Matthew Meszaros
0b253337fc
feat: integrate custom roles across Roles & access settings (manager replaces the coming-soon placeholder, custom roles join the permission matrix and summary cards, permission-aware canManage gating via the org context bitmask)
2026-06-11 10:08:46 +02:00
Matthew Meszaros
63b2b046f9
feat: custom roles dashboard UI (roles manager with built-in reference rows, permission-checkbox editor with start-from presets, custom roles in member role picker and invite flow, realtime spine refresh)
2026-06-11 09:45:23 +02:00
Matthew Meszaros
8af2950d0b
feat: reconcile missed realtime events by invalidating all queries when the websocket reconnects after a gap
2026-06-11 08:25:00 +02:00
Matthew Meszaros
a06a525cf9
feat: live team presence across the dashboard (online avatar stack in header, viewing/replying indicators on unibox threads and rows, editing collaborators in the automation builder, campaign and contact viewers) plus audit-spine query invalidation
2026-06-11 08:04:11 +02:00
Matthew Meszaros
defeacee5d
feat: show realtime notifications
...
Adds the dashboard notification bell, marks feed items read, and refreshes the feed from realtime notification events.
2026-06-08 15:05:13 +02:00
Matthew Meszaros
cb85c13135
feat: refresh automations in realtime
2026-06-08 12:04:13 +02:00
Matthew Meszaros
82e753735c
feat: add integration and meetings dashboard
2026-06-08 06:25:44 +02:00
Matthew Meszaros
1663065b56
feat: fix analytics share image edge
...
Pin analytics share exports to the card dimensions and avoid white fallback pixels along the generated image edge.
2026-06-05 16:36:34 +02:00
Matthew Meszaros
e4cd88d491
feat: upgrade campaign step composer
...
Replace the legacy email body editor with the rich step composer, add preview/template controls, expose AI writing in campaigns and unibox replies, and close confirms after successful actions.
2026-06-05 06:04:31 +02:00
Matthew Meszaros
cdb2eaa229
feat: add analytics share preview
...
Add preview sizing, copy-to-clipboard, and improved PNG rendering for analytics share cards. Refresh the exported share card visuals and keep chart bars constrained for compact layouts.
2026-06-04 18:57:08 +02:00