Select a Contact
Click IMPORT or KB to start.
Click IMPORT or KB to start.
.csv file. Required columns: Name (or separate First Name + Last Name), Title (or Job Title / Role), Email. Existing contacts are matched by email.Lvl2 Intel is a single-file local web app that runs sales outreach: contact management, AI-driven account research, scheduled multi-step email campaigns, customer-event invitations, and reporting. All state lives in your browser's IndexedDB, with auto-backups to a disk folder. Nothing is sent to a server — Claude API calls go from your browser straight to Anthropic, Gmail sends go through Google OAuth.
The PG effort challenges include organization, research and relevance: many accounts in the territory, a deep product portfolio, outreach cadence management, account and industry intelligence, and contact intelligence. How do you know what to send, to whom, when, and with relevance?
The goal: cut the time spent per personalized email from ~60 minutes down to 3 or less.
| The challenge | How Lvl2 Intel solves it |
|---|---|
| Research takes hours per account. Earnings filings, ransomware history, tech stack, competitor footprint, CISO appointments — all scattered across the web. | 🚀 RUN ALL builds a 12-topic dossier (Strategic / Breach / Tech / Triggers / Competitors + 4 Focus Areas + Leaders / Hiring / Recent Movers) in ~5-8 min, ~$0.40-$1.20 per company. 🧬 SYNTHESIZE then distills it into per-Focus-Area signals + top trigger events + top displacement opportunities + top people to target. |
| Personalization vs scale tradeoff. Generic emails get ignored; personalized ones take 30-60 minutes each. | ✨ POV generates a Nugget / Bridge / Ask trio in ~10 seconds for ~$0.01-$0.03 per email. Reads the contact's notes, the company intel, and the Focus Area campaign frame. Per-contact mode personalizes; multi-select mode produces a company-level POV stamped to every selected participant's first-unsent step. |
| Finding the right people. Manual LinkedIn searches eat time and often hit junior ICs instead of decision-makers. | 🔍 DISCOVER searches for ICP roles, dedupes against your existing list, scores 1-10 by decision authority. 🎯 Leaders and 🚀 Recent Movers topics surface named CISO/CIO/CTO/VP candidates with relevance scoring and Focus Area mapping. |
| "Why now" hooks are scattered. M&A, CISO appointments, breaches, board cyber committees all matter for outreach timing but live in different sources. | ⚡ Triggers topic captures dated trigger events specifically for the "why now" sentence. Combined with 🚀 Recent Movers, sellers see which execs are inside their 90-day vendor-evaluation window — the highest-conversion timing. |
| Displacement opportunities are hidden. Veeam / Commvault / Cohesity / Druva / Semperis contract renewals and dissatisfaction signals are buried in press releases, job listings, earnings calls. | ⚔️ Competitors topic maps every visible competitor reference, estimates displacement timing (NOW / 3-6 mo / 6-12 mo), and tags which Focus Area would displace each one. |
| Multi-step cadences are tedious. Multi-touch sequences require scheduling, follow-up reminders, manual draft management. | Built-in 4-step cadences per Focus Area (PITCH → VALUE ADD → NEW ANGLE → BREAKUP) plus event-driven cadences. Per-step day offsets, Active Campaign tracking, 📨 GMAIL one-click send, 📨 BULK SEND throttled at ~100/min with mailto: fallback. |
| Picking the right pillar for the right person. There are 4 product Focus Areas; matching the pillar to the role is judgment-heavy. | Title-based auto-assignment tags every imported contact with a Focus Area. The POV prompt automatically pulls the matching Problem / Solution / Differentiator from state.campaignDefs so framing is consistent across every step. |
| Customer-event timing is project management. Pre-conference invites, day-of pushes, post-event follow-ups all need date-aware scheduling. | 📅 Events module supports Conference / Webinar / News with built-in PRE / DAY / POST cadences. Step offsets auto-fill from the event date; Event Link auto-appends to email bodies; POV system prompt receives an EVENT ANCHOR block with phase-appropriate ASK guidance. |
| Salesforce sync friction. Sellers maintain "shadow" lists; keeping CRM in sync is manual. | ☁️ Salesforce ID field on every contact + CSV column maps each record back to its SFDC contact. Visible on the card, workspace, and edit modal. CSV export includes the column for round-tripping into Salesforce. |
| No way to know what's working. Pipeline metrics are easy; outreach effectiveness by Focus Area, campaign, and step is hard. | 📈 Reports tabulates sends by Focus Area, by Campaign, by step. Today / 7d / 30d / All-time windows. CSV export. 📊 Usage tracks Claude AI spend so cost-per-touch stays visible. |
| Vendor lock-in for outreach data. Most outreach tools own your prospect lists, your sent history, your research notes. | Your data is yours: export a full JSON copy anytime from KB → Backup → Download, and move it anywhere. |
+ NEW next to the Company dropdown → enter a company name.📄 TEMPLATE to download the import format, then ⬆️ IMPORT your contacts CSV. Or click 🔍 DISCOVER to have Claude find ICP contacts.🧠 KB → Intel and click 🚀 RUN ALL to build the company dossier across 12 topics (~5-8 min, ~$0.40-$1.20).🧬 SYNTHESIZE to collapse the full dossier into a per-Focus-Area summary plus top trigger events / displacement opportunities / people to target (~$0.05-$0.15, no new searches).🚀 CAMPAIGNS → Events → add a webinar, conference, or news event with its Event Link.🚀 CAMPAIGNS → + NEW CAMPAIGN → pick type (Focus Area or Event), companies, focus-area filter, participants → Save & Start.✨ POV for a generated Nugget/Bridge/Ask → 📨 GMAIL to send.Every contact carries one Focus Area (stored as c.campaign). Exactly four canonical buckets — each represented by exactly one Intel Card and one Topic editor:
| Focus Area | Focused Intel key | Covers (merged content) |
|---|---|---|
| 🛡️ Cloud & Cyber | cyber | Cyber recovery, ransomware, Zero Trust, immutable / air-gapped backups + cloud workloads (AWS/Azure/GCP/OCI), cloud-native backup displacement, FinOps. (cyber + cloud topics merged · Jun 2026) |
| 🤖 DevOps & AI | devops | GitHub / GitLab / Azure DevOps / Bitbucket, CI/CD, source-code & repo protection + AI agent governance (agent registry, agent rewind/tuning), AI compliance (NIST AI RMF, ISO 42001, EU AI Act). (devops + agents topics merged · Jun 2026) |
| 👤 SaaS & Identity | identity | Active Directory, Entra ID, Okta, Ping (forest recovery, configuration drift, golden-ticket / DCSync defense) + Microsoft 365, Salesforce, Jira Cloud (4-layer security: WORM / retention-lock / BYOK / air gap). (identity + saas topics merged · Jun 2026) |
| 🗄️ File & NAS | unstructured | NAS Cloud Direct (NCD): NetApp / Isilon / Pure / VAST / Qumulo / Nutanix / Spectrum Scale, Azure NetApp Files, AWS FSx, GCP Filestore. PII discovery, DSPM, YARA threat hunting. |
The Focus Area drives: the POV content framing, the default cadence sequence (campaign:<key>), keyword scoring on intel quality, and the Campaigns editor's filter.
campaign:ai (legacy). The Focused-Intel topic for the same Focus Area is keyed devops. Both resolve to the user-facing name "DevOps & AI" via CAMPAIGN_NAMES / FOCUS_AREA_OF_TOPIC.On first load (gated by state.titleBasedFocusV2) the app scans every contact's title and assigns a Focus Area heuristically — IAM/SaaS keywords → SaaS & Identity, DevOps/AI/software → DevOps & AI, NAS/file → File & NAS, everything else → Cloud & Cyber. Re-run from console:
state.titleBasedFocusV2 = false; saveState(); location.reload();
➕ ADD — manual single-contact creation🔍 DISCOVER — Claude searches for ICP-fit people at the target company, dedupes against your existing list (~$0.10-$0.20)⬆️ Import CSV — opens a dialog where you can paste CSV rows (include the header row) or upload a .csv file — both run the same importer. Required columns: Name, Title, Email (aliases below; Name can also be supplied as separate First Name + Last Name columns). Optional Company column (aliases: Account, Employer, Organization) sets a per-contact company that overrides the Company name in the {{company}} / {{Company}} variable. Rows missing any required field are skipped — you'll see a summary listing the row number and the missing field(s). Rows whose Relevance Filter column starts with ❌ REMOVED or 🔁 DUPLICATE are automatically skipped, even in Merge mode. Choose Merge (blank cells keep the existing value) or Overwrite (blank cells clear it), and optionally check Remove contacts not in this file to delete existing contacts whose email isn't present in the upload (Do-Not-Touch contacts are never auto-deleted — they're listed separately for manual review). Existing contacts (matched by email, case-insensitive) get updated; new emails create new contacts.📄 TEMPLATE — downloads PG_Contact_Import_Template.csv with all valid columns (incl. Salesforce ID and Influence) + sample rows for each Focus Area. The header comment lists every accepted column-name alias.⬇️ EXPORT — exports current target's contacts as CSV.🎯 Re-align focus areas — Claude re-checks every contact's Focus Area against their title + saved intel and proposes corrections (~$0.01-0.05/run). Shows a preview of changed contacts before applying.🚩 Research relevance — Claude reviews title + Focus Area + saved intel (no web lookup) against a ICP rubric and writes a verdict into each contact's Relevance Filter: ✅ Relevant, ⚠️ Review, or ❌ Recommend removal (~$0.01-0.05/run). It only sets the field — nothing is deleted. For a deeper per-contact web-verified check, use 👤 BULK INTEL instead.❌, then use the existing select-all + bulk-delete to trim them.Each card shows name, badges (🎯 PG / 🚫 DNT / ✨ DISC), title, an optional ☁️ Salesforce ID line (when set), Influence badge, Focus Area, an optional purple Active Campaign bar (🚀 <name> if one is set; 🚀 in N campaign(s) otherwise), and sequence progress N/4 (campaign sequences are 4 steps · event sequences vary).
Salesforce ID (c.salesforceId) is an optional 15- or 18-char SFDC contact ID. Visible on the contact card, the workspace bar, and the edit modal. CSV column Salesforce ID (aliases: SalesforceId, SFDC ID, SFID) maps to this field on import and is included on export.
+ ADD TO… attaches this contact to any existing campaign, + NEW starts a fresh one.Two complementary controls sit above the contact list:
🚩 Flagged for removal — contacts whose Relevance Filter or any CI status field is a ❌, from 🚩 Research relevance). Multi-select: chips within a group are OR'd, across groups are AND'd, and an empty group means no filter. A ✕ Clear chip appears when any filter is active.| Tab | What it stores | Used by |
|---|---|---|
| 🏢 Intel | target.intelData | POV Claude prompt; intel-quality scoring |
| 📚 Library | state.productLibrary | POV prompt (product info); bridge stat extraction |
| 🎯 Focus Areas | state.campaignDefs[key] + sequence editor | POV prompt's "campaign frame"; bridge text |
| 💬 Stories | state.storyData | POV prompt (peer-win anchoring); heuristic bridge |
| ✉️ Templates | state.savedTemplates | Managed in the 📋 Template library (next to ✨ POV), not here. Each saved template can be applied verbatim to contacts, and (when "use in POV" is on) is matched to a contact's focus area as a voice/structure sample in the POV prompt. |
| 🎯 Topics | state.focusedIntelDims | The Focused Intel tiles on the Intel tab |
| 📈 Reports | (derived from sentEmails) | Send activity + by-campaign breakdown |
| 📊 Usage | Claude call log | Cost tracking |
| 💾 Backup | Manual export/restore, factory reset | Data portability |
Each tile triggers a 3-5-search Claude run on one research dimension, written to target.intelData under a --- 🎯 Focused Intel: <label> · timestamp --- header. Re-running a tile replaces that topic's previous block — each topic keeps exactly one current result, and other topics are left untouched (so old results don't pile up). Tile dot color = target.lastIntelByTopic[dim] freshness: 🟢 < 7d, 🟡 7-30d, ⚪ > 30d. Deleting a tile's intel block in the textarea also clears the dot. (🚀 RUN ALL rebuilds its own combined block each run.)
Cards are organized in 3 rows, all aligned to the 4 Focus Areas where applicable:
| Row | Tile | What it searches |
|---|---|---|
| 📊 General | 📈 Strategic | 10-K Risk Factors, earnings-call quotes on cyber/IT spend, digital-transformation programs |
| ☢️ Breach | Every public incident with date / threat actor / scope / downtime / ransom / recovery path; SEC 8-K Item 1.05 filings; regulatory enforcement; CISO post-incident statements; near-misses; peer-industry incidents | |
| ☁️ Tech Stack | Deployed clouds + backup vendors + identity + virtualization + containers; explicit displacement signals (RFPs, contract renewals, "moving off X") | |
| ⚡ Triggers (new) | M&A, IPO, leadership changes, board cyber committees, SEC 8-K filings, layoffs / restructuring — the "why now" pool | |
| ⚔️ Competitors (new) | Every visible Veeam / Commvault / Cohesity / Druva / Semperis / Quest / OwnBackup reference with renewal timing + dissatisfaction signals | |
| 🎯 Focus Area | 🛡️ Cloud & Cyber | Cyber recovery posture, ransomware history, clean-recovery readiness, cloud workload protection, Veeam / Commvault / Cohesity displacement |
| 🤖 DevOps & AI | DevOps platform footprint, CI/CD incidents, AI agent governance gaps, Cyber RTO awareness, agent-rewind / IAM gaps | |
| 👤 SaaS & Identity | AD / Entra / Okta posture, identity incidents, M365 / Salesforce footprint, OwnBackup / Semperis displacement | |
| 🗄️ File & NAS | Storage platforms (NetApp / Isilon / Pure / VAST), petabyte signals, NDMP pain, threat hunting / IOC posture | |
| 👥 People | 🎯 Leaders (new) | Named CISO / CIO / CTO / VP Security/Cloud/Identity at the company with relevance score 1-10 and Focus Area mapping |
| 📋 Hiring (new) | Open security / cloud / identity / DR roles; pain-signal JD language ("modernize backup", "AD forest recovery", "agent registry"); competitor-mention JDs | |
| 🚀 Recent Movers (new) | Execs who joined ≤6 months ago — in their 90-day vendor-evaluation window |
Iterates every topic sequentially (~5-8 min, ~$0.40-$1.20 for the current 12 topics). Each topic is an independent retryable call · individual failures don't halt the run.
Reads the entire target.intelData blob — no new web searches — and produces a structured synthesis appended to the bottom of Intel: per-Focus-Area signals (one section per of the 4), Top 3 Trigger Events (Why Now), Top 3 Displacement Opportunities (with vendor + timing), Top 3 People to Target. Cost ~$0.05-$0.15 per run depending on intel length.
Each Focused Intel card is editable: icon, label, section (General / Campaign / People), focus prompt (what Claude researches), query hint (boolean OR search pattern). For campaign-section topics the campaignName automatically mirrors the label — there is no separate Focus Area name input.
🤖 SUGGEST button on each topic regenerates the query hint from the focus prompt (~$0.005). + ADD TOPIC creates a custom topic. ↩ RESET DEFAULTS wipes customizations.
Events are time-bound outreach anchors — webinars, conferences, news articles. Each event owns a short cadence (event:<id>) tied to its dates. Manage in 🚀 Campaigns → Events.
| Type | Sequence | Email Link auto-appends as |
|---|---|---|
| 🎤 Conference | PRE (-7 days) → DAY (0) → POST (+3) | Register here: |
| 💻 Webinar | -14 → -7 → 0 days | Register here: |
| 📰 News event | Single timely-outreach step | Details here: |
✅ N Active / 📝 N Draft / ⏸ N Paused (hover for campaign names).🚀 Start Campaign (no campaign yet) → 🚀 View Campaign (active exists) → 📝 Continue Draft (draft exists) → ⏸ View Paused.sent/total slots.📦 Archive hides the event from the active list (sequences and tracking stay intact).An event can attach a fixed template email to any individual step instead of letting that step use AI POV. In the Event editor, each step row has a saved-template <select> plus an ✏️ button that opens an inline editor (write/import the email, save it to your Template Library, and link it to that step). The footer's Apply button stamps each templated step onto every participant — tokens {{First Name}} / {{Company}} / {{Title}} fill per contact, and the registration link still auto-appends to the Ask. Steps with no template attached stay on AI POV. Links stay aligned when you add, remove, or reorder steps.
Give an event a short "Short P.S. blurb" in the Event editor and it becomes toggleable in a row of chips (composer toolbar and the Bulk Send modal) — one chip per upcoming event that has a blurb. Toggle one or more on and every email you draft next (sequence step, Quick Email, or Bulk Send) gets the blurb + event link appended as P.S. / P.P.S. lines, independent of whether you're actually running that event's campaign. Selection persists until you change it; a pink ✕ chip clears all active P.S. events.
A Campaign is a scheduled, trackable outreach instance against a set of contacts. Open the Campaigns dashboard from the header.
campaign:<focusAreaKey>, generic ongoing cadence.event:<id>), step offsets pre-fill from the event's dates.Switching kinds resets the sequence + step overrides (with confirmation if you'd customized them).
All visible non-DNT to bulk-add, None to clear everything (including hidden).| Status | Means | How |
|---|---|---|
| DRAFT | Saved but not started | Editor → Save as Draft |
| ACTIVE | Sends count, picker shows it, cadence drives | Save & Start (or ▶ START from card) |
| PAUSED | Stops surfacing in pickers but record intact | ⏸ PAUSE from card |
| COMPLETED | Hidden from active dashboard; all stats preserved | ✅ COMPLETE from card. Reversible via ↩ REOPEN. |
campaignId but the lookup fails, so reports show (deleted <id>) instead of the name. COMPLETE keeps everything fully reportable.The three-part structure for personalized cold outreach:
Stored at tracking[cid].stepPOV[sequenceKey][stepIndex]. Inline edits propagate to all same-focus-area contacts at the same step (for campaign:* sequences) but stay contact-specific for event sequences.
| Selection | Mode | What runs |
|---|---|---|
| 0 checked | Personalized | Loaded contact at current step (Claude reads contact notes + active campaign) |
| 1 checked | Personalized | Selected contact at first unsent step in their active sequence |
| 2+ checked | Mode-choice modal | Opens a modal asking 🏢 Company & solution POV vs 👤 Per-contact personalized POV. |
🏢 Company & solution POV — one Claude call considering company intel + every distinct Focus Area + the campaign whose cadence row is in focus. If a contact is loaded on a campaign/event row, only that campaign frames the POV — it will not pull in other campaigns the selected contacts happen to share. With nothing specific in focus it falls back to active-campaign pointers + any event covering the selection. Same Nugget/Bridge/Ask is stamped to every selected contact's first-unsent step.
👤 Per-contact personalized POV — loops each selected contact and generates its own tailored email (own notes/intel/LinkedIn signals) at that contact's first-unsent step, one Claude call per contact (a ⏳ i/N counter tracks progress; cost estimate accumulates across all calls). Skips contacts with no unsent step or an existing POV at it. Use this when the selected contacts shouldn't all get the identical message.
Per-contact personalization (LinkedIn signals, tenure, hooks) flows through the 0- and 1-selected paths, and through the 2+ Per-contact mode; the 2+ Company-level mode is a single shared message for the whole group.
Above the Nugget/Bridge/Ask boxes is a row of focus-area chips (one per pillar: 🛡️ Cloud & Cyber · 🤖 DevOps & AI · 👤 SaaS & Identity · 🗄️ File & NAS). They pre-check to the loaded contact's own pillar. Check 2 or more and the next ✨ POV blends them into one message — leading on the contact's own pillar and reinforcing with the others (one hook, one CTA — it does not pitch each pillar separately). This works in both single-contact and company-level (2+ checked) modes; with 2+ chips set, the chosen blend overrides the focus areas auto-gathered from the selection. By default chips follow the Directory's focus-area filter (or the loaded contact's own pillar if no filter is set). Manually toggle any chip and the selection becomes sticky — it persists across contact navigation and filter changes — until you click the pink ⟲ match filter chip to resume auto-following the filter.
The ✍️ Quick Email button (on the POV Brief panel line, next to ✨ POV and 📋 Template) opens a paste box — no AI generation. Paste a finished email; the greeting and sign-off are stripped and the blank-line-separated paragraphs map to Nugget → Bridge → Ask (a Subject: line is detected). Click 📥 Use for contact(s) and it drops straight into the loaded/selected contact's POV Brief. Tokens {{First Name}} / {{Company}} / {{Title}} fill per contact. Then refine with 🌸 LAV / ✨ Suggest and send via 📨 GMAIL / ✉️ MAIL TO.
Single-step "Quick" cadence (one and done): applying a Quick Email puts the contact on a dedicated 1-step Quick cadence (a built-in "Quick (one-off)" campaign), so it's a true one-off — not a 4-step sequence. Their normal campaign cadence is untouched; switch back any time via the Active Campaign picker. If you check multiple contacts first, the same email is applied to each (tokens fill per person).
From the news briefings: when you open 📰 COMPANY NEWS or 🌐 INDUSTRY NEWS, the app injects a ✍️ Quick Email button next to each Conversation Starter (company news) and Seller Takeaway (industry news). Click it and Quick Email opens here with that text pre-filled in the paste box — edit it into a full email, then 📥 Use for contact(s). (The news HTML files aren't modified; the buttons are added on open, so they survive the briefings being regenerated.)
Once a contact completes a sequence (every step sent — for the standard 4-step cadence, the 4th email), they enter a 21-day contact-wide cool-down before any further send. A ❄️ Nd badge shows on the contact card and a banner appears in the composer; cooled-down contacts are excluded from Bulk Send and prompt a "Send anyway?" confirm on single sends. To send during cool-down, use the ⚡ Override link in the composer banner (or click the ❄️/⚡ badge on the card) — the override is tied to that specific cool-down, so a later completed sequence starts a fresh rest.
When the active sequence is an event sequence, the Claude prompt receives an EVENT ANCHOR block with:
SAVE-THE-DATE INVITATION, REMINDER INVITATION, DAY-OF LAST CALL, POST-EVENT FOLLOW-UP, PRE-CONFERENCE INVITATION, DAY-OF CONFERENCE, POST-CONFERENCE FOLLOW-UP, or TIMELY NEWS REACTION.The system prompt forbids generic "let's grab a call" asks when the phase is an invitation. The Event Link auto-appends at the end of the assembled body (Register here: for webinar/conference, Details here: for news_event) — Claude is told not to inline it.
🗑️ button in the POV panel clears that step's Nugget/Bridge/Ask. A touched step is authoritative — empty stays empty (no per-field fallback to contact-level fields). Then ✨ POV again to regenerate fresh.
campaignId from the active campaign.mailto:. You hit Send in the mail app, then come back and click 📤 SENT to record.Three tabs: Compose (subject + body with {{firstName}} placeholders, plus optional CC / BCC) → Preview → Send. CC and BCC are single addresses (comma-separate multiple) applied to every email in the batch — not personalized — and flow through both the Gmail API and mailto send paths. Two send options on the Send tab:
campaignId.mailto: link 300ms apart so your mail client opens N draft windows. You need to allow pop-ups for localhost:8000 the first time. Once all drafts are open and sent from the mail app, click ✅ MARK ALL SENT to record them here.KB → Reports. Time-window tiles (Today / 7d / 30d / All time) plus by-campaign breakdown.
Each tile counts: total sends, PG-Hit sends (🎯), sends by campaign (📅 event-kind shown), sends by Focus Area, sends by step.
The "Copy leadership summary" button dumps a markdown summary to clipboard for a weekly update.
CSV export: includes Date, Company, Contact, Focus Area, Sequence, Step, Subject, Campaign, Campaign Status, Sent via, DNT flags, PG Hit.
Every Claude action is built from a system prompt (the role + instructions, assembled with your KB context) plus a user message (the specific request). Two ways to inspect the exact text:
👁️ VIEW PROMPT in the bulk bar (next to 👤 BULK INTEL). It shows the exact system + user message Bulk Intel will send for the first selected contact. Nothing is sent.KB → 📊 Usage → 👁️ View Claude prompts lists the last 30 Claude calls this session (POV, Intel, Discover, Synthesize, Re-align…). Click any entry to see its full system + user message, each with a copy button.To run any of these on your own claude.ai subscription instead of the API (no API spend), click 📋 Copy for Claude Chat in the inspector. Because claude.ai has no separate system field, this copies the system prompt and the request folded into one paste-ready message. Open a new claude.ai chat and paste.
claudeBuildSystem.Your data lives in a private, secure cloud database tied to your account — not in this browser. Sign in from any device and your companies, contacts, and campaigns are all there. Nothing to configure, nothing to lose if you clear your browser or switch computers.
KB → Backup → Download exports your full account as a JSON file, anytime. Restore re-imports a JSON file (overwrites current data — you'll be asked to confirm).
CSV columns: name, title, email, phone, company, focusArea, influence, salesforceId, linkedinUrl, pgHit, sent, lastStep, notes, notesTruncated (RFC-4180 quoting; notes capped at 1000 chars).
| Symptom | Why | Fix |
|---|---|---|
| Active Campaign dropdown is empty for a contact | Contact isn't in any campaign's participants | Click + ADD TO… next to the dropdown, pick a campaign, contact gets added |
| A campaign's people show for one company but not another / fewer than expected | A filter chip is AND'ing with the campaign — most often a Seq chip (e.g. "In progress" hides participants with 0 sends) | (Improved) Picking a campaign now auto-clears chips. Otherwise click ✕ Clear on the chips. The per-contact Active Campaign picker only lists a campaign when that contact is loaded |
| POV says "already has a POV for Step N..." | Stale POV from a prior run | 🗑️ button to clear, then ✨ POV again |
| Cleared POV reappears immediately | (Fixed) per-field fallback used to re-inject contact-level POV | Hard-reload if still seen |
| Event link appears twice in email body | Claude inlined it despite the system prompt | (Fixed) genTemplates skips the auto-append when the URL is already present |
| Event tile dot stays green after deleting that block in Intel | (Fixed) delIntelSection now clears the topic's timestamp | Hard-reload |
| Select All in directory selects too many | (Fixed) old additive-set semantics; now exclusive — checked = exactly visible, unchecked = empty | Hard-reload |
| Bulk MAIL TO only opens first email | (Fixed) — now fires all 300ms apart; allow pop-ups for localhost:8000 | Hard-reload, accept pop-up prompt |
| Campaign editor focus-areas reset on re-open | (Fixed) — now persisted on the campaign record | Hard-reload |
| Server orphans after closing terminal | Older launcher missed HUP trap | Current PG-Launcher.command has trap … INT TERM HUP EXIT |
| Old CSV with "Target Value" column won't import the field | (Renamed Jun 2026) Field is now Influence | No action needed — import accepts Influence / Target Value / Priority as aliases for the same field |
| Cloud / SaaS / AI Agents Intel cards disappeared | (Consolidated Jun 2026) The 7 Focused-Intel campaign topics collapsed to the 4 canonical Focus Areas | No action needed — content was merged: cloud → 🛡️ Cloud & Cyber · saas → 👤 SaaS & Identity · agents → 🤖 DevOps & AI. Edit the merged focus prompts in KB → Topics if you want to trim them. |
Open DevTools (Cmd+Opt+J on Mac):
// Inspect current target
CT()
// Resolve sequence key for a contact
resolveActiveSequenceKey(CT().contacts.find(c => c.name === 'Some Name'))
// Find every campaign a contact is in
Object.values(state.campaigns)
.filter(c => c.status !== 'closed' && (c.participantContactIds||[]).includes('<contactId>'))
// List event-kind campaigns + linked events (debug count mismatches)
Object.values(state.campaigns)
.filter(c => c.kind === 'event')
.map(c => ({name:c.name, status:c.status, eventName: state.events[c.eventId]?.name}))
// Re-run title-based Focus Area assignment
state.titleBasedFocusV2 = false; saveState(); location.reload();
// Clear a stuck Active Campaign pointer
const t = CT(), cid = t.activeContactId;
t.tracking[cid].activeCampaignId = null;
saveState(); applyFilters();
// Dump recent sends across all targets
Object.values(state.targets).flatMap(t =>
Object.entries(t.tracking || {}).flatMap(([cid, trk]) =>
(trk.sentEmails || []).map(e => ({company:t.name, cid, step:e.step, sentAt:e.sentAt, campaignId:e.campaignId}))
)
).sort((a,b) => (b.sentAt||'').localeCompare(a.sentAt||'')).slice(0, 20)
// Audit a campaign's reach
const cmp = Object.values(state.campaigns).find(c => c.name.includes('M365'));
_campaignTargetIds(cmp); _campaignSentCount(cmp); _campaignNextDue(cmp);
// Hand-build a quick state snapshot
copy(JSON.stringify(state)); // then paste into a .json file
Deletes ALL data.
Find new ICP contacts at the current target. Duplicates against your existing contact list are flagged and disabled.
{{First Name}}, {{Company}}, {{Title}} fill per contact; a Subject: line is auto-detected. Save to reuse it; Apply stamps it onto the selected contacts with no AI.{{First Name}} / {{Company}} / {{Title}} fill per contact.Each contact receives a personalized email via To: line. Use {{firstName}} for personalization.
{{firstName}}
{{fullName}}
{{title}}
{{company}}
{{campaign}}
Two ways to send: Gmail API sends directly through your Google account (throttled ~100/min, auto-marks sent). Mailto opens each one in your default mail app for manual review.