Dw Pitch Followup
Search the build
-
dcb29c42026-07-15 chore: lint, refactor (dedup repaint per unique email), v0.4.1 (session close) -
229cd172026-07-15 fix(notes): FileMaker note-save silently no-op'd — write rep-1 bare key + read-back verify -
109d6a32026-07-15 Make invoice # on the note chip + notes editor clickable — opens the invoice in FileMaker Pro via fmp:// GotoInvoice -
a923a042026-07-15 fix: ✓ emailed date chip appears immediately after send — repaint live cards by DOM lookup (active.card was detached after board re-renders), update SENT_IDX in memory for same-client cards in other lists, and refresh sent-index on tab focus for cross-device visibility -
177117e2026-07-15 Show invoice # + current internal note on every pitch card — batched FM read (50/query, 10-min cache), chip updates live on save -
58c847e2026-07-15 Add Internal-notes editor to pitch cards — 🗒 Notes button next to Done reads/writes FileMaker Invoice::Internal notes with dated entries -
e35cf912026-07-15 auto-save: 2026-07-15T10:35:56 (2 files) — server.js lib/fm-notes.js -
e90255c2026-07-15 pitch: scheduled refresh now also pre-triages the whole board (build-lists → pretriage), so every card is Follow-up scored -
5e218be2026-07-15 pitch: Follow up? YES/NO chip on every card + per-column ⚡ Triage (batch, cached) -
8e921dc2026-07-15 pitch: auto follow-up triage — reads the email thread → Follow up? YES/NO + notes (delays, deadlines, status) -
e039b5a2026-07-15 pitch: click any email in the history to expand its full body -
8f32c4b2026-07-15 pitch: add 3x/day launchd rebuild so the board never goes stale (bootstrap = Steve paste) -
e592d472026-07-15 pitch: email history collapsed by default, lazy-loads on expand (George search only fires when opened) -
a4bc2e82026-07-15 pitch: Details drawer shows full email history with each client -
71574cf2026-07-14 5x: 2 clean sweeps (7/7 six-way + 51 controls, 0 defects) after card/UX + George + FM batch -
9aa4cdc2026-07-14 pitch: letter panel shows product thumbnails + DW product-page links -
c6994a42026-07-14 pitch: list2 letter follows up on the specific QUOTE (number, total, items) not generic samples -
f9b63232026-07-14 pitch: Sent log is now LIVE — merge Gmail Sent (recipient-enriched) with the tool log -
6c560f32026-07-14 pitch: FIX critical George 401 — resolve GEORGE_AUTH from secrets master (restores sends + threading + last-corr) -
c6d56092026-07-14 pitch: card/UX batch — dismiss-completed, park vendor memos, quote/order label fix, FM deep-links, live sent-index, expandable columns -
d4a8d302026-07-14 auto-save: 2026-07-14T11:00:40 (1 files) — public/index.html -
a59c63b2026-07-14 pitch: redefine "Invoiced · No Order" list as real quotes never booked (totals + details) -
395d98e2026-07-13 chore: lint (esc XSS autofix + enrich-disco psql guard), refactor, v0.4.0 (session close) -
4c403792026-07-13 auto-save: 2026-07-13T12:24:56 (1 files) — public/index.html -
0b342302026-07-13 auto-save: 2026-07-13T11:54:48 (2 files) — public/index.html scripts/enrich-disco.js -
a22a58a2026-07-13 auto-save: 2026-07-13T11:24:39 (2 files) — public/index.html scripts/build-lists.js -
93dde312026-07-12 chore: v0.3.0 (session close — public tunnel + auth hardening: lockout, socket-guard, cred rotation, headers) -
02b62f22026-07-12 yolo contrarian-gate fixes: socket-anchored /api/send guard (#1) + suppress audit log (#2) -
211aef32026-07-12 yolo: baseline security headers (nosniff, frame-DENY, no-referrer) on public endpoint — closes contrarian 'no helmet' gap -
09bfb882026-07-12 contrarian FIX FIRST #3: rotate public cred off shared DW2024! via app-local .env (envLocal reader) -
577f14f2026-07-12 contrarian FIX FIRST #2: per-IP brute-force lockout on public Basic Auth (10 fails/15m → 429) -
cf2ad962026-07-12 contrarian FIX FIRST #1: block /api/send for tunnel-origin requests (loopback-only mail send) -
10b262d2026-07-12 5x: REPORT.md — 2 sweeps, app clean, M3 networkidle proven CDN artifact -
d29d6ef2026-07-12 5x sweep 1: add auth-exempt /favicon.ico 204 route (kills per-load console 404) -
d6916492026-07-08 chore: syntax-verified session changes, v0.1.1 → v0.2.0 (session close) -
ee864df2026-07-08 Schedule unsubscribe scan (launchd com.steve.dw-pitch-unsub-scan, 8am+8pm) — auto-honors client opt-outs with ?apply=1, logs every run; plist versioned in repo -
e2ce4dc2026-07-08 auto-save: 2026-07-08T06:34:26 (1 files) — scripts/scan-unsubscribes.sh -
a9f7c6a2026-07-08 CAN-SPAM: compliant footer (physical address 15442 Ventura Blvd #102 + UNSUBSCRIBE) on every send; suppression list honored at send (not overridable); tightened unsubscribe scanner (to:info@ + opt-out-at-start, dry-run by default, ?apply=1 to suppress) -
cc4f4682026-07-08 Stop leaking internal 'From job: dw-pitch-followup' banner onto client emails (no_source_tag:true); verified sent body is clean -
ff195582026-07-07 yolo/contrarian fixes: build-time TODAY (fix aging bug) + 30-day double-email frequency guard at send (list1∩list2 dedup) with 'Send anyway' override -
d191c5c2026-07-07 Auto-swap to a thank-you letter when client has a BOOKED order since sampling (references the order + project); quote-since-sampling still gets the follow-up (chase the close) -
4f8a57a2026-07-07 Flag invoices placed SINCE samples sent (possible conversion): card banner + panel detail with #, total, sku/item, quote/booked, date -
b6e57372026-07-07 Fix sticking Send button (reset #pSend/#pRegen/#pCopy on panel open); stamp emailed date/time in panel+card+sendstat; keep permanent sent-log.jsonl of every email + /api/sent + 'Sent log' viewer -
a4a77d72026-07-07 Make panel 'Send now (info@)' prominent — filled gold, bold, right-aligned with divider (was subtle outline, easy to miss) -
b2b886f2026-07-07 Email: thumbnail + product-link gallery for recent samples (dw_unified sku→handle/image, dashed-sku match, ACTIVE-only links); panel shows thumbnails too; separate sample-reminder heading from list -
eb905c72026-07-07 Letter greeting uses FileMaker contact first name (Find-a-client Name field); block letter + red 'Reorder Samples??' when samples ordered but 0 shipped (panel Generate disabled too) -
2246a8e2026-07-07 Rewrite client letter to spec: ~3 sentences, client-type aware (designer/architect trade line), final-purchase ask, witty stock/samples ask, project-details line, ends w/ question, rotating Steve/Samantha/Marcus sign-off, sample list w/ dates, url+phone (HTML href on send), PS; no new-year/no mfr#; fix name parsing (parentheticals/ALL-CAPS) -
a350bea2026-07-07 Right-panel detail view (context+last-corresponded on click+letter); quote/booked per invoice; lifetime sales (booked-only) on card+panel; current project from invoice sidemark; lifetime-sales sort -
53052462026-07-07 Expand sort to all fields incl Invoice total (merch_total); add sort control to One-list view (defaults to invoice-total desc) -
e3aa21c2026-07-07 Revert invoice links to file-open (skip GotoInvoice deep-link for now) -
43c0d5a2026-07-07 Invoice links: enable fmp:// record-jump (USE_FM_SCRIPT=true → GotoInvoice script param) -
56b23812026-07-07 Enrich cards with samples sent/pending + merchandise invoices (>$250, real orders) w/ fmp links + total; MERCH_MIN=250; sample SKUs shown as-is in admin details -
28a382b2026-07-07 auto-save: 2026-07-07T14:31:09 (2 files) — public/index.html scripts/build-lists.js -
c660a282026-07-07 Compact cards + Columns/One-list layout toggle + ▸details expander (samples/merch/last-corresponded); lazy /api/lastcorr via George -
306b7912026-07-07 Add 'Send now (info@)' — emails generated letter via George info@ account with external-send approval token (Steve-authorized), confirm-guard + in-thread + persisted sent marker -
182e2a62026-07-07 auto-save: 2026-07-07T14:01:00 (2 files) — public/index.html server.js -
5d7759e2026-07-07 Redesign viewer: 3-column board (all lists at once) + List/Grid toggle + density scale; per-column sort, cross-column select/export -
8a5b1ac2026-07-07 Frontend: build API URLs from location.host so fetches work even when page opened with inline credentials -
0524e782026-07-07 Skip Basic Auth for direct-loopback access so the localhost viewer loads without inline creds (tunnel still gated) -
25071562026-07-07 chore: version bump (session close — anti-hallucination guardrails) -
9abe8a22026-07-07 pitch-followup: anti-hallucination guardrails + LLM reliability -
90270262026-07-03 chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew) -
d2a48d92026-06-30 ui: show last-sample-sent date as a chip on every card (uses existing when_iso; removed redundant .when line) -
351e8f92026-06-30 Pitch follow-up: hide mfr# from UI + client letters (toggle), LLM-customized letters, Generate/Regenerate buttons -
91a8b822026-06-30 auto-save: 2026-06-30T14:41:08 (1 files) — deploy/ -
a518ea62026-06-30 DW client/vendor follow-up pitch viewer: 3 read-only FileMaker lists + George-grounded letters + select/export (no sends)
Authors
- Steve66
Agents used
- secrets-manager1
Skills used
- /index6
- /followup-cache2
- /sent2
- /build-lists2
- /send2
- /booked2
- /export2
- /query1
- /writes1
- /fm-notes1
- /followup-batch1
- /followup-analysis1
- /deadlines1
- /promises1
- /status1
- /day1
- /emails1
- /from1
- /out1
- /url1
- /order1
- /sent-index1
- /shrink1
- /enrich-disco1
- /favicon1
- /scan-unsubscribes1
- /contrarian1
- /item1
- /time1
- /image1
Creative ideas + design notes
229cd17 · 2026-07-15 · fix(notes): FileMaker note-save silently no-op'd — write rep-1 bare key + read-back verify
Root cause: repeating-field rep 1 must be written as the BARE field name ("Internal notes"), not "Internal notes(1)" — the Data API accepts the (1) form with success code 0 but silently ignores it, so notes logged as saved but never persisted (verified: a real save was empty on read-back). Also updateRecord reports committed:true after any non-erroring PATCH without confirming the field changed. Fix: write bare key AND read the record back, throwing if the note is not actually present — never report a save we cannot see.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5e218be · 2026-07-15 · pitch: Follow up? YES/NO chip on every card + per-column ⚡ Triage (batch, cached)
Server keeps a persistent follow-up cache (data/followup-cache.json): analyzeFollowup writes each verdict; drawer opens + a new POST /api/followup-batch (concurrency 3, skips <24h-fresh) fill it. GET /api/followup-cache feeds card badges at boot. Cards show a green "Follow up" / tan "Hold" chip from cache; ⚡ Triage per column batches all un-cached clients with live progress; opening a drawer lights that card immediately. All local Ollama, $0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8e921dc · 2026-07-15 · pitch: auto follow-up triage — reads the email thread → Follow up? YES/NO + notes (delays, deadlines, status)
New /api/followup-analysis reads the client thread via George and runs local Ollama (hermes3:8b, $0) to decide follow-up yes/no with a reason, concrete notes (delays/deadlines/promises/status), and a deadline date. Drawer shows a prominent Follow up? badge (green YES / red NO) auto-loaded on open, cached 6h per client, with a ↻ re-analyze. Deadline sanitized to real date-or-empty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e039b5a · 2026-07-15 · pitch: click any email in the history to expand its full body
New /api/email?id=&account= fetches the full message via George and strips HTML to readable text. Each email row is now clickable → lazy-loads + expands the body inline (caret ▸/▾), collapses on re-click, cached per message. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
a4bc2e8 · 2026-07-15 · pitch: Details drawer shows full email history with each client
New /api/emails?email= (George read-only) returns all emails to/from a client across info@ + steve-office, deduped, newest first, with in/out direction from the From header. Drawer renders the thread list (direction chip · date · subject · snippet), lazy-loaded on open alongside last-corresponded. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9aa4cdc · 2026-07-14 · pitch: letter panel shows product thumbnails + DW product-page links
renderLetterGallery draws a small strip under the letter — 40px thumbnail + link to the DW product page for each referenced sampled item (image/url from dw_unified). Shown on panel open. 476/600 list1 clients have images. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c6994a4 · 2026-07-14 · pitch: list2 letter follows up on the specific QUOTE (number, total, items) not generic samples
New quote-followup branch in composeDeterministic for list2: cites the actual quote #(s), total, and quoted items with amounts, and asks to convert to an order. Sanitizes leaked dimension strings out of the project ref and strips empty "(Ref.)" from item names. Verified against a real $6,693.60 two-quote client. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f9b6323 · 2026-07-14 · pitch: Sent log is now LIVE — merge Gmail Sent (recipient-enriched) with the tool log
georgeSentLetters now fetches each sent letter full message for its `to` (Gmail search omits recipient), bounded to 60 newest, parallel. collectSent merges live+local, dedups by recipient+day, 60s cache. Sent log + per-card emailed chip now show through today (was frozen at the last tool-send). Verified newest = Jul 14. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6c560f3 · 2026-07-14 · pitch: FIX critical George 401 — resolve GEORGE_AUTH from secrets master (restores sends + threading + last-corr)
The app resolved an empty George password, so every George call 401d — sends, reply-threading, and "last corresponded" were silently failing (and pm2 --update-env wiped the process-env cred on restart). Now resolves the canonical GEORGE_AUTH ("user:pass") from secrets-manager/.env, surviving restarts. Verified: lastcorr returns a real thread.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c6d5609 · 2026-07-14 · pitch: card/UX batch — dismiss-completed, park vendor memos, quote/order label fix, FM deep-links, live sent-index, expandable columns
- Dismiss any card as ✓ Done: instant DOM removal + persisted, never re-shown (localStorage done: flag; filterSort/flatRows exclude) - Park Vendor Memos Overdue (list3): dropped from board + bucket via PARKED set (un-park = 1 line); grid tracks now match visible column count - Fix quote-vs-order contradiction: postFlag shows BOOKED orders only; drawer relabels "Quoted since we sent samples" when none booked - Per-invoice details: drawer splits Orders vs Quotes, each row shows item detail; goodLbl drops stripMfr punctuation-junk items - FileMaker deep-links: invoice# and client acct now Find the exact record (fmpInvoice/fmpClient script+param, USE_FM_SCRIPT on) — needs GotoInvoice/GotoClient scripts in FM - Real "emailed on <date>" chip from server /api/sent-index (cross-browser, 311 recipients from the send log) - /api/sent now merges the local log with a live Gmail Sent view (George), 60s cache, invalidated on send - Expand/shrink any board column (⤢ toggle, persisted) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
a59c63b · 2026-07-14 · pitch: redefine "Invoiced · No Order" list as real quotes never booked (totals + details)
- buildList2 candidate pool flipped from sample-only (maxTotal<=$50) to real-dollar invoices - main() keeps only accounts with an open merch quote (quoted_total>0) and NO booked order (lifetime_sales==0), deriving quote_total / quote_count / quote_items - cards show "$X quoted · no order" chip + quoted item details; sorts now quote-based - drawer reads "No orders booked · $X in open quotes" for these never-booked prospects - list2: 57 accounts (e.g. $92,250 Briseyda Garcia quote, never ordered) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9abe8a2 · 2026-07-07 · pitch-followup: anti-hallucination guardrails + LLM reliability
- Whitelist product names: the writer may ONLY name a pattern that's in the client's actual sampled set (buildFacts now returns allowed[]); empty → model names nothing, speaks generically. Reject-guard throws on any ™/® or 'X Collection' name not on the whitelist → falls back to the accurate deterministic draft. No invented collection names can reach a client draft. - Fix subject-greeting leak (subject is now a standalone line) + guarantee the body opens with 'Hi <name>,'; strip stray ™/®. - Reliability: keep_alive 30m + widen Ollama timeout 30s→90s so drafts stop cold-timing-out to the generic fallback. Verified across seeds.
File tree
- .gitignore
- 5x/REPORT.md
- data/suppress.json
- deploy/finish-tunnel.sh
- launchd/com.steve.dw-pitch-rebuild.plist
- launchd/com.steve.dw-pitch-unsub-scan.plist
- lib/fm-notes.js
- lib/fm.js
- package-lock.json
- package.json
- public/index.html
- scripts/build-lists.js
- scripts/enrich-disco.js
- scripts/pretriage.js
- scripts/refresh.sh
- scripts/scan-unsubscribes.sh
- server.js