Added auto-drip follow-up email sequencing and a complete dashboard redesign with a modern UI.#1
Open
whrit wants to merge 80 commits into
Open
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restructured CLAUDE.md to focus on Claude Code guidance - Added commands section with detailed instructions - Updated architecture and tech stack descriptions - Included key patterns and storage schema details - Moved setup instructions to separate document - Created .claude/settings.local.json for local configuration
- Added support for one-off follow-up sequences in gmail.js - Enhanced analytics to track sequence creation, completion, and stopping - Improved error handling and logging in cron.js - Updated manifest.json to remove unused permissions - Introduced ESLint configuration for better code quality - Modified settings.local.json to allow additional Bash commands - Various bug fixes and optimizations across multiple modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the standalone dashboard HTML with the shared layout, stat cards, filter tabs, list panel, sparkline, and sequence/OAuth stats. Updates the GET / route in index.js to compute sparkline data (7-day open histogram), aggregate sequence status counts, and check OAuth connection state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements a chronological activity feed that aggregates opens, filtered events, tracker creations, and sequence events into a single timeline view with client-side filtering tabs and pagination. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite sequences-page.js to use renderLayout, renderFilterTabs, renderStepProgress, renderBadge, and safeJson from the shared component library. Add oauthConnected param to the GET /sequences HTML route in index.js. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite templates-page.js to use renderLayout, design system classes (.list-panel, .list-row, .panel, .btn-*, .input), and proper esc() escaping. Update GET /templates HTML route to pass oauthConnected. Fix pre-existing unused var lint error in detail.js. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added specific Bash commands to settings.local.json for superpowers functionality - Included node script execution and error handling - Ignored .superpowers directory in .gitignore to prevent version control issues
- Introduced autospintax functionality to replace common phrases with spintax alternatives - Added a spam checker panel to analyze and provide recommendations based on email content quality - Enhanced UI with buttons and visual indicators for both features
Spintax bar was green→red (low=good) but should be red→green since higher spintax usage is better. Word count bar now uses a custom gradient (red-yellow-green-yellow-red) showing the 25-100 sweet spot in the green zone. Also added inverted parameter to addMetric helper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced the purple gradient + emoji sparkle button with a clean blue accent style (matching the design system) and a proper Lucide-style wand-sparkles SVG icon. Button now uses border + tinted background instead of a gradient fill. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…main Derives company name from the email domain (e.g., bob@acme-inc.com -> "Acme Inc"). Strips TLD, replaces hyphens/dots with spaces, capitalizes. Added to the variable engine, template editor dropdown, editor preview sample data, and extension one-off builder variable pills. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ubject}}
Removed the !step.subject check from template and sequence validation.
Empty subjects are now valid and default to "Re: {{subject}}" at send
time in the cron handler, matching Gmail reply behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ender_first_name)
The preview's replaceVars function only matched {{word}} patterns and
didn't handle spintax {{opt1|opt2|opt3}} or snake_case variable names.
Now matches any content inside {{ }}, randomly picks spintax options,
and resolves first_name/sender_first_name aliases. Also added aliases
to the backend variable engine so they work at send time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… overlap The 32px dark circle was sitting right next to Send and overlapping its dropdown arrow. Now the selector: - Tries to insert into Gmail's formatting toolbar row (with Aa, emoji, etc.) - Falls back to after Send with a visual separator (border + padding) - Uses transparent background matching Gmail's toolbar icon style - Gray icon (#5f6368) when unselected, blue when a sequence is chosen - 28px instead of 32px to match Gmail's toolbar icon sizing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Place button at end of send row (not after Send) to avoid overlap - Make sequence button lookup more robust — searches entire compose dialog, not just the form subtree - Add response logging for sequence creation (logs success/failure with status code to console for debugging) - Simplified insertion: always appends to sendRow Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fixed hash comparison: startsWith('#sent') instead of === '#sent'
to match #sent, #sent/, #sent?compose=new, etc.
- Added 30-second periodic refresh while in sent view so indicators
update as emails get opened
- Initial load fires with a 1.5s delay if already in sent folder
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added detailed location and device information to event details - Included ISP and IP address for filtered events - Improved formatting consistency across different sections
…uence creation - recordOpenForAnalytics now records opens even before follow-ups are sent, attributing them to step 0 (original email) - createSequence initializes the analytics entry and increments totalSequences immediately, so analytics show data right away - Analytics page labels step 0 as "Original" when no sends recorded for that step (distinguishing original email from first follow-up) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Narrowed host_permissions from *://*/* to only mail.google.com and *.workers.dev (for API calls to the worker) - Popup is disabled on non-Gmail tabs (clicking icon does nothing) - Full popup enabled when on mail.google.com - Added tabs permission for tab URL detection - Bumped version to 1.2.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added a new button in the popup header to open the dashboard - Updated `popup.html` to include the new button element - Modified `popup.js` to handle click events on the new dashboard button, opening a new tab with the server URL if available
… overlap Tries multiple selectors to find Gmail's compose toolbar (the icon row with Aa, attach, emoji, etc.) and appends the sequence button there. Falls back to placing in the next table cell from Send, then as a last resort after Send with a visual separator. Also adds dashboard button to extension popup header. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Used the actual Gmail DOM structure from DevTools to find the correct target: div.bAK inside td.a8X is the toolbar container holding attach, link, emoji, drive, photo icons. Our button now appends there, matching Gmail's icon sizing (20x20 with 5px padding). Falls back to td.a8X or a td offset from Send if div.bAK isn't found. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced the abstract 3-dots timeline icon with a recognizable blue paper airplane (send) with a small clock in the corner, clearly representing "scheduled follow-up." Icon is always blue (#3b82f6), with a subtle blue background highlight when a sequence is selected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shield icon button in the compose toolbar that analyzes the current draft for spam potential. Shows a floating white panel with score ring, spam word tags, spintax %, links, images, emojis, word count — same analysis as the template editor, adapted for Gmail's light theme. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Part A: The extension now filters HubSpot BCC logging addresses (*.bcc.*.hubspot.com) from recipient tracking — no more duplicate trackers cluttering the dashboard. Also filters Salesforce BCC. Part B: BCC addresses are captured separately and stored on the sequence as hubspotBcc. The cron handler includes this BCC when sending follow-ups via Gmail API, so all follow-up emails still get logged in HubSpot CRM automatically. Changes: - gmail.js: isBccLoggingAddress(), getBccLoggingAddresses() filters - gmail.js: passes hubspotBcc in sequence creation payload - sequences.js: stores hubspotBcc on sequence object - gmail-api.js: buildMimeMessage/sendFollowUp accept bcc param - cron.js: passes seq.hubspotBcc when sending follow-ups Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers HubSpot integration, timezone-optimized email scheduling, smart send time optimization, and thread intelligence sidebar. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…(6 tasks) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eatures - Implement smart scheduling with timezone optimization and recipient-specific timing - Integrate HubSpot for enhanced recipient information and timezone detection - Add thread intelligence sidebar for detailed email interaction insights - Update API endpoints for managing scheduled emails and retrieving recipient data
…dings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… edge Sequence dropdown, spam checker panel, and thread intelligence panel all positioned from left edge without checking viewport bounds. Now all three detect when they'd overflow the right edge and anchor from the right instead (dropdown: right:0 instead of left:0, fixed panels: anchor to button's right edge minus panel width). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Strips Gmail signatures (div.gmail_signature and -- delimiter) from analysis so signature links/content don't inflate the spam score - Reduced link penalty: first link is free, 2nd adds 5pts, 3+ adds 10 each (was 15pts per link which flagged normal emails as high risk) - Word count penalty now graduated: <15 or >150 = 10pts, 25-100 sweet spot, 15-25 or 100-150 = 5pts - Spintax penalty only applies if email has >10 words (empty/signature only bodies aren't penalized for lacking spintax) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rd triggers Completely rewrote the spam dictionaries based on industry research: Red tier (10pts): Now multi-word phrases only — "buy now", "earn money", "100% free", "get rich", etc. Single words like "free", "cash", "credit" removed from red (too many false positives in business email). Orange tier (5pts): Aggressive sales tactics — "exclusive deal", "limited time", "guaranteed results", "free trial", etc. Yellow tier (2pts): Soft single-word signals matching Salesforge-style detection — "free", "guarantee", "millions", "save", "get", "now", "all". These are informational, not alarming. Also rebalanced scoring in template editor to match gmail.js: - Link penalty: 1st free, 2nd=5pts, 3+=10pts each - Word count: graduated (very short/long=10pts, slightly off=5pts) - Spintax penalty only if >10 words Both gmail.js and template-editor.js now use identical word lists and scoring logic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a HubSpot contact has city/state/country but no hs_timezone field, the system now infers the timezone from their location data. Covers 50+ countries with direct mapping, plus city/state-level resolution for multi-timezone countries (US, Canada, Australia, Brazil, Russia). Fixes: ezhil@presentations.ai in Bengaluru, India was defaulting to US Eastern because hs_timezone was empty and .ai TLD isn't mapped. Now correctly resolves to Asia/Kolkata. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cached recipient-info entries from before the country inference fix had timezoneSource='default' with the wrong timezone. Now cache hits with 'default' source are re-fetched to pick up the country inference. Entries with hubspot/tld/open_history source are still served from cache. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… toggle Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major release adding auto-drip follow-up email sequencing and a complete dashboard redesign with a modern UI.
Drip Sequencing & Automation
{{firstName}},{{subject}},{{daysSince}}, and more in email templatesDashboard Redesign
styles.js(CSS tokens),layout.js(page shell + sidebar),components.js(stat cards, badges, filter tabs, step progress)/activitypage with chronological event timeline across all trackers and sequences, filterable by type/settingspage with Gmail OAuth status, webhook info, system stats/templates/newand/templates/:id/edit, with formatting toolbar (B/I/link/list), variable insertion dropdown,and email preview toggle
Extension Improvements
Code Quality
</script>prevention (safeJson), constant-time password comparison, single-quote escaping inesc(),request.json()error handling, OAuth CSRF state validationlist(), idempotent crash recovery, batched processing with cursor, differentiated Gmail API error handling (400/403/404/5xx), reply stopcondition checked before send
New backend modules
src/variables.js{{variable}}substitution enginesrc/templates.jssrc/sequences.jssrc/gmail-api.jssrc/cron.jsNew dashboard pages
//s/:id/sequences/templates/templates/new/templates/:id/edit/analytics/activity/settingsSetup requirements
SEQUENCES(add towrangler.toml)GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET(for Gmail OAuth)*/5 * * * *(add towrangler.toml)wrangler.example.tomlfor configuration template