2026-09-27 06:16:54 +00:00
..
2026-09-17 04:15:05 -07:00
2026-09-21 02:11:38 -07:00
2026-09-13 03:07:10 -07:00
2026-09-21 02:11:38 -07:00
2026-09-14 12:20:47 -07:00
2026-09-26 21:28:06 -07:00
2026-07-30 17:15:09 +02:00
2026-07-19 13:22:56 +02:00
2026-09-26 23:00:30 -07:00
2026-09-10 05:02:05 -07:00
2026-09-01 01:32:56 -07:00
feat: add Delete and Duplicate campaign actions to the dashboard (issue #185): every campaign row and the detail header get a ⋯ menu (Edit, Duplicate, Start/Pause, Delete) plus a Delete card at the bottom of Settings, all permission-gated with a confirm that spells out what goes; DELETE /campaigns/:id is now organization-scoped instead of user_id-scoped so teammates can delete, runs in one transaction that also deletes the campaign's pending tasks and cancels a wakeup tick claimed at that moment (campaign_tasks only nulls its link, so those rows kept firing), removes attachment objects and publishes CAMPAIGN_DELETED so a teammate's open detail page is sent back to the list; new POST /campaigns/:id/duplicate copies the campaign row as a draft with steps and their branch graph rewired onto new step ids, tags, folders, senders with rotation reset, A/B variants, advanced settings and attachments (quota-checked, blobs undone if the copy fails) and none of the leads, progress, logs, counters, ramp level, guardrail trip or past dates, naming it (copy)/(copy N) inside the 50 byte cap without splitting runes; a claimed campaign tick whose campaign vanished now ends the chain instead of staying active forever; covered by TestLiveCampaignLifecycle* against real SQL, RemapBranchTargets and duplicateName unit tests and a react-query vitest for the list cache, with API reference, endpoint map and campaigns guide updated
2026-08-25 08:54:51 -07:00
2026-09-25 20:48:15 -07:00
2026-08-28 01:44:39 -07:00
2026-07-22 10:58:35 +02:00
feat: give each mailbox a human sending persona (randomized daily and hourly caps, send spacing, work start/end, lunch break and working weekdays, rolled once per local day in the mailbox's own timezone and applied across the campaign, warmup and smart-send schedulers), add campaign auto-pause guardrails that stop a campaign when its bounce, complaint or reply rate leaves the configured band, make mailbox rotation actually rotate for tag-resolved and all-mailbox campaigns, stop every scheduler from ever returning a slot in the past, and correct the mailbox min-gap field that stored seconds while labelling them minutes
2026-08-13 16:51:29 +02:00
2026-01-29 05:59:04 +01:00
2026-09-24 19:56:14 -07:00
2026-09-22 20:13:55 -07:00
2026-09-04 20:14:27 -07:00
2026-08-28 10:40:25 -07:00
2026-08-28 10:40:25 -07:00
2026-09-14 09:26:06 -07:00
feat: add recipient-level engagement to the campaign Leads view by adding an engagement search filter (opened, not_opened, clicked, not_clicked, replied, not_replied, bounced) that composes with lead_status as AND and rejects unknown values with stable 400 codes, counting only human opens so machine opens never read as engagement, adding contacted/opened/clicked/replied_any totals to lead_counts, rendering Opened/Clicked/Replied columns and clickable server-backed status and engagement chips in the Leads table with matching Filters sheet sections, offering lead_status/lead_opened/lead_clicked/lead_replied export columns from a campaign, covering every filter value with a live Postgres test, and documenting the columns, filters, error codes and export fields (issue #250)
2026-08-29 03:12:02 -07:00
2026-09-22 20:22:40 -07:00
2026-09-03 20:21:42 -07:00
2026-09-26 06:47:29 -07:00
2026-05-18 13:09:11 +00:00
2026-09-17 15:25:35 +02:00
2026-09-14 12:20:47 -07:00
2026-09-14 12:20:47 -07:00
2026-05-24 04:42:43 +00:00
2026-09-21 02:11:38 -07:00
2026-08-22 09:37:26 -07:00
2026-09-22 20:13:55 -07:00
2026-09-08 21:17:36 -07:00
feat: rebuild mailbox import around column mapping and automatic host and sign-in detection (CSV, XLSX, pasted lists, saved mappings, retryable rows with fixes, migrations 000205-000206), connect whole Google Workspace domains and Microsoft 365 organizations through a proved administrator grant, import from inbox vendors (InboxKit, Zapmail, Mailforge, Infraforge, Maildoso, Cheap Inboxes, ScaledMail) with vendor-managed forwarding and DNS, add a sending domains page with per-domain tracking and verified root redirects, unify Add account into one Google and one Microsoft entry with per-method choices, mark per-mailbox Google sign-in as retiring with in-place moves to the admin grant or an app password, allow the loopback security mode in the credential columns (migration 000207), read semicolon-separated CSVs, and add a mock vendor API to the sandbox
2026-09-23 08:41:01 -07:00
2026-09-18 11:29:48 +02:00
2026-09-18 11:29:48 +02:00
2026-09-15 20:25:21 -07:00
2026-09-15 10:50:30 -07:00
2026-09-15 20:25:21 -07:00
2026-09-18 11:29:48 +02:00
2026-09-15 10:50:30 -07:00
2026-09-15 10:50:30 -07:00
2026-09-15 10:50:30 -07:00
2026-09-15 10:50:30 -07:00
2026-09-22 05:15:49 -07:00
2026-09-15 10:50:30 -07:00
2026-09-15 10:50:30 -07:00
2026-05-27 15:56:01 +00:00
2026-09-22 05:15:49 -07:00
feat: tell a person connecting a mailbox what the mail server actually said instead of "invalid credentials" for everything, by having the worker's SMTP and IMAP probes classify a refused sign-in, an unreachable host, a failed TLS handshake, a retry-later reply and a timeout and publish that verdict as JSON ahead of the legacy digit, mapping it on the backend to mailbox_auth_refused, mailbox_unreachable, mailbox_tls_failed and mailbox_server_declined with the server's reply and a Gmail app-password hint in the message, starting the probe budget after the credentials are unsealed and bounding the SMTP conversation so a silent server no longer parks the worker, and normalizing passwords on every connect path so a Google app password pasted with its spaces works from the form, the CSV import, the API and the re-authorize dialog alike
2026-09-19 23:53:40 -07:00
2026-09-24 11:44:58 +02:00
2026-09-14 21:28:07 -07:00
2026-09-17 04:15:05 -07:00
2026-09-09 04:54:01 -07:00
feat: forms v2, a full redesign of the hosted form and its builder: eight one-click themes, card/wide/split layouts with a brand cover panel, classic paged and Typeform-style focus modes split on a new page_break block, logo/cover/background uploads with size, fit and veil controls, an optional header bar that can span the page or sit with the form, a real HSV colour picker and font preview, per-contact personalized links that prefill and attribute without email verification, a render-token gate so the form JSON cannot be scraped without loading the page, funnel analytics with per-page drop-off and identified visitors, a leads-style forms list and responses table, and an organization custom forms domain verified by CNAME with hourly re-checks
2026-09-01 09:27:28 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
2026-01-17 14:11:14 +00:00
feat: make self-hosted auth work without a mail relay by rewriting the platform SMTP transport with real AUTH and TLS (it did neither, so SMTP_USERNAME/SMTP_PASSWORD were dead and every documented relay was unreachable), adding MAIL_TRANSPORT=smtp|log|ses with a log transport that prints codes so a fresh install can sign in with no relay, demoting the emailed login code to AUTH_LOGIN_CODE=always|new_device|off (off on self-host, per NIST SP 800-63B and OWASP ASVS), claiming the first owner through a single-use setup link or WARMBLY_BOOTSTRAP_* instead of register-then-psql, deriving every emailed URL from APP_URL rather than a hardcoded app.warmbly.com that leaked live reset tokens to the vendor, fixing the confirm hooks that read path params against paramless routes and broke login, register and reset confirmation in the dashboard everywhere, adding generic OIDC with PKCE, one-time state, verified nonce and (issuer,subject) identity binding, enforcing 2FA on the social paths that skipped it, adding a per-IP limiter and trusted-proxy handling to the unthrottled auth group, refusing boot on the published default secrets, and dropping mailpit from the default stack (#99)
2026-08-14 14:57:09 +02:00
2026-06-28 19:09:37 +02:00
2026-08-21 18:45:09 +02:00
2026-09-24 21:08:35 -07:00
2026-06-08 06:25:40 +02:00
2026-06-08 06:25:40 +02:00
2026-09-10 20:06:29 +01:00
2026-09-08 04:59:18 -07:00
2026-01-17 14:11:14 +00:00
2026-09-07 08:27:54 -07:00
2026-09-25 09:30:36 -07:00
2026-09-22 05:15:49 -07:00
2026-07-13 20:05:24 +02:00
2026-09-26 21:28:06 -07:00
2026-09-16 04:04:09 -07:00
2026-09-16 04:04:09 -07:00
2026-07-16 08:57:19 +02:00
2026-01-17 14:11:14 +00:00
2026-09-12 03:37:31 -07:00
2026-09-07 05:45:11 -07:00
2026-09-07 05:45:11 -07:00
2026-07-19 11:04:58 +02:00
2026-09-22 20:13:55 -07:00
feat: give a suspended workspace a way back, because risk_state was a one-way door: the derived band is no longer pinned at suspended by the UPDATE in pg_org_risk, an operator's decision is now an explicit risk_override that outranks the score and survives every later detector write until it is lifted, the one-shot detectors (signup origin, import list quality, repeated sign-in anomalies) file findings with a 30-day expiry that a six-hourly consumer sweep retires so a score falls on its own, migration 000104 backfills that expiry onto findings already on file, and four admin endpoints plus an Abuse posture panel in admin/ let an operator finally read the evidence the customer endpoint withholds, retract a finding, pin a band and lift the pin; also stops the reviewing admin's identity reaching the tenant's own audit feed (which resolves an actor to a name and email) by recording the platform as the actor there and the operator in the admin trail, and stops risk_signals riding along in a customer-downloadable org export
2026-08-28 22:42:57 -07:00
2026-06-13 07:18:23 +02:00
2026-09-21 02:11:38 -07:00
2026-09-21 02:11:38 -07:00
2026-09-25 21:46:09 -07:00
2026-09-24 18:38:47 +02:00
2026-05-27 16:40:23 +00:00
2026-05-27 12:06:18 +00:00
2026-06-08 06:25:40 +02:00
2026-06-28 05:09:50 +00:00
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
2026-09-09 04:54:01 -07:00
2026-08-29 23:45:05 -07:00
2026-09-26 06:33:44 -07:00
2026-08-28 22:47:31 -07:00
2026-08-28 22:47:31 -07:00
2026-09-13 20:51:41 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
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
2026-09-12 22:32:14 -07:00
2026-09-12 09:45:31 -07:00
2026-09-13 21:22:12 -07:00
2026-09-22 05:15:49 -07:00
2026-06-07 07:03:49 +02:00
2026-05-24 12:01:37 +00:00
2026-09-21 03:35:17 -07:00
2026-09-19 08:15:31 -07:00
2026-09-11 03:23:19 -07:00
feat: keep conversations the inbox tagger judges automated (security alerts, verification codes, notifications, bounces, auto-replies) out of Inbox, Unread, mailbox and tag views and the unread badge and list them in the Automated view via a new unibox automated filter and overview counts, map no-reply header verdicts to Notification, and rename the automatic labels to plain words (Interested, Meeting, Needs reply, Follow up, Gone quiet and more) with a migration that renames, merges and prunes the old ones
2026-09-24 20:08:45 -07:00
feat: complete the ADA CASA v2.1.1 AL1 control set across authentication, sessions, access control, cryptography, input validation and configuration, adding a breached-password denylist and per-account login throttling, enforced multi-factor authentication on the admin panel, step-up confirmation before an action that mints a lasting credential, purpose-scoped session tokens, single-use TOTP steps, tenant verification on every cross-referenced identifier, security headers on every surface, encrypted webhook signing secrets, per-organization idempotency, PKCE and a minimal two-scope Gmail consent on the mailbox OAuth flow, bounded spreadsheet and archive decoding, a patched Go toolchain with govulncheck in CI, and the evidence pack under compliance/casa
2026-09-19 08:18:35 +02:00
2026-09-26 06:33:44 -07:00
2026-09-25 20:18:26 -07:00
2026-09-26 22:26:58 -07:00
2026-09-26 22:26:58 -07:00
feat: make warmup spam placement only slow a mailbox down (watch at 10%, half-volume throttle at 20%, never quarantine, block or appeal) and judge it only at Google, Microsoft and Yahoo over verified deliveries, keep small-host spam out of the health bands, warmup and cold ramps and the advisor while still showing it beside the headline rate on the drawer and Deliverability, draw small-host partners whose own filter junks warmup mail less often, send each quarantine or block webhook once plus health_changed, release placement-only quarantines in 000220, and update the warmup, deliverability, advisor and API docs
2026-09-26 22:26:58 -07:00
2026-09-17 20:46:03 -07:00
2026-09-21 00:52:02 -07:00
2026-05-25 15:42:50 +00:00
2026-05-27 16:17:53 +00:00
2026-09-26 22:26:58 -07:00
2026-06-01 03:09:17 +02:00
2026-06-15 08:11:20 +02:00
feat: turn automations into a lead-intake path so a Facebook, Instagram, LinkedIn or TikTok lead form pushed by Zapier, Make, n8n or any webhook becomes a tagged, campaign-enrolled contact without leaving Warmbly: add the warmbly.upsert_contact and warmbly.add_to_campaign built-in actions with templated field mapping, custom fields, tags, campaign and an if-exists policy, fire a rich contact.created event from the one contact write path (silent for file imports, sheet syncs and API batches over 100) and expose contact.created and form.submitted as automation triggers with condition fields, variables and sample data, carry an automation depth through events raised by an action so a flow that creates a contact cannot re-trigger itself past five hops, stamp automation-created contacts with the new automation source (migration 000129), share the campaign picker between the sheet sync wizard and the automation builder, document lead intake in the automations, Zapier, Make, contacts, forms, integrations, expressions and webhook pages plus a new n8n guide, mirror the new triggers and actions on the marketing automations page, and drop the 34 MB cli binary that was committed by mistake
2026-09-06 00:36:05 -07:00
feat: add website visitor tracking for issue #255 with migration 000106 (website_tracking_settings, website_visitors, website_page_hits, all registered in the orgtransfer spec), a consent-gated dependency-free tracking.js served by the Rust tracking service with a rate-limited, size-capped, prefetch-filtered POST /p ingest that forwards to a new backend internal page-hits endpoint for server-side user-agent and GeoIP enrichment, contact identification only through the click ticket the redirect appends to registered hosts, a per-workspace retention job, page_hit events with an expandable detail view in the contact Activity timeline, a Settings > Website tracking page for the snippet and consent, location and retention configuration, realtime PAGE_HIT fanout, and a website tracking guide plus endpoint, export and configuration docs
2026-08-29 03:25:50 -07:00
feat: rebuild mailbox import around column mapping and automatic host and sign-in detection (CSV, XLSX, pasted lists, saved mappings, retryable rows with fixes, migrations 000205-000206), connect whole Google Workspace domains and Microsoft 365 organizations through a proved administrator grant, import from inbox vendors (InboxKit, Zapmail, Mailforge, Infraforge, Maildoso, Cheap Inboxes, ScaledMail) with vendor-managed forwarding and DNS, add a sending domains page with per-domain tracking and verified root redirects, unify Add account into one Google and one Microsoft entry with per-method choices, mark per-mailbox Google sign-in as retiring with in-place moves to the admin grant or an app password, allow the loopback security mode in the credential columns (migration 000207), read semicolon-separated CSVs, and add a mock vendor API to the sandbox
2026-09-23 08:41:01 -07:00