Every Chrome extension build we ship — new features, fixes, and improvements. Reload the extension after updating from the Web Store to see the latest in-app.
Fix Maximum call stack size exceeded when creating proposals (safe text coercion + JSON publish)
Stops re-processing variants 3× before publish; repair pass can re-run post-process safely
Landing project_scope no longer steals ambiguous scope field or fails 70/20/10 master validation
Version 10.88
Update
Landing page: detailed Project Scope (separate from short Upwork 70/20/10 letters)
Architecture defaults to 3 rich phases with 2–4 components each (like reference proposals)
Viewer section renamed from Cover Letter to Project Scope
Version 10.87
Update
Fix missing Regards + proposal link on Upwork job panel (content script now runs the same letter polish as the popup)
Always append Full breakdown + URL when publish returns a slug, even if the popup re-parses the result
Sign-off uses profile name or title; Regards still added when name is blank
Version 10.86
Update
Cover letters: no pricing or budget lines (Upwork + landing page hold commercial terms)
Strips duplicate closings and re-appends Full breakdown click below + proposal URL after publish
Fixes missing proposal link when the popup re-processed generation without the published URL
Version 10.85
Update
Cover letter close: invite scope discussion instead of access/credential homework (no more "Reply with HubSpot access…")
Standard sign-off: Regards + your profile name, then Full breakdown click below + proposal URL
Post-process rewrites bad milestone/access closings and enforces the new ending template
Version 10.84
Update
Landing page diagrams backfill when Claude JSON truncates before proposal.diagrams
Synthesizes architecture, workflow, and stack Mermaid from job scope (Make.com, HubSpot, CRM builds, etc.)
Accepts graph TD/LR from Claude and normalizes to flowchart for rendering
Version 10.83
Update
70/20/10 cover letters: markdown format with max 3 sentences per paragraph (no wall-of-text blocks)
Auto-split oversized paragraphs after generation; tighter sentence caps for scannable letters
Landing page Cover Letter renders markdown (bold, subheads, paragraph breaks)
Version 10.82
Update
Fix sparse landing pages when Claude JSON truncates: hydrate cover letter, key requirements, and architecture from variants + job scope before publish
Salvage partial proposal/estimate objects from truncated responses
Proposal viewer backfills missing sections from stored variants on read (existing slugs)
Version 10.81
Update
Landing page Architecture: infer milestone count from job post (up to 10 phases) instead of always 3–4
Prompt tells Claude to mirror numbered milestones — not compress seven steps into three generic phases
Version 10.80
Update
Sanitize restored proposal cache so object-shaped cover letters cannot crash the popup on load
Detect JSON-dump payloads stored as objects, not only strings
Version 10.79
Update
Fix txt.replace is not a function when cover letters or answers are non-string values
Coerce all variant and answer fields to plain text before display and fill
Version 10.78
Fix
raw JSON no longer dumped into the cover letter when Claude output is truncated
Update
Salvage all four variant letters from partial JSON; normalize coverletterproblem field names
max_tokens raised to 8192 for full 70/20/10 payloads
Version 10.77
Update
Client scoring: heavy spenders ($50k+) no longer penalized hard for 3.5–3.9 ratings
Spend tiers up to +4 for $100k+; hire rate 55%+ earns +1; jobs posted and member tenure count
Shared client-scorer.js for panel, popup, and queue
Version 10.76
Update
Proposals now use the 70/20/10 framework (problem 70%, solution 20%, price + one next step 10%) — replaces winning formula
Client language bank from job post, uploads, and regen notes; four opener tones kept
Validator + one automatic repair pass if problem section is not longest
Cover letter length: medium default; short option removed
Version 10.75
Update
Critical fix: content script syntax error (extra brace) that prevented the extension from loading on Upwork tabs
Added parseFixedBudgetAmount for $4,000 Fixed-price sidebar detection
Version 1.0.447
Update
Fixed-price on apply page: read bridge budget, parse $4,000 Fixed-price from sidebar, ignore client avg hourly in scope
Hourly vs fixed classification no longer treats $4k fixed jobs as hourly when budget line says Fixed-price
Version 10.74
Update
Proposal prompts enforce winning formula: clearest specialist, insight-first open, fast proof, low-risk close
Four variants and master cover letter must pass the formula checklist before output
Version 10.73
Update
Hardened job scrape and panel (scoped budget, fewer runtime errors on apply page)
Fixed-price detection from $100+ including $500 jobs
Version 10.72
Fix
fixed-price jobs ($500, etc.) detected again — ignore client "avg hourly rate paid" on apply page
Update
Parse budgets like "$500 Fixed-price" from job details sidebar
Version 10.71
Fix
Generate Application panel opens again (removed broken isApplyPage reference in buildJobPanel)
Version 10.70
Fix
Generate Application button works again after reloading the extension (no tab refresh required)
Update
Proposal panel starts hidden until opened; safer toggle after upgrade
Version 10.69
Fix
Create Proposal no longer throws when job scrape or panel UI elements are missing
Update
Job panel shows Generate/Fill after SPA navigation to the apply page
Version 10.68
Update
Release build v10.68 — refreshed Chrome Web Store package (upworkwizz.zip)
Version 10.67
Update
Cover letter CTA: 'Full breakdown click below 👇' with proposal URL on the next line (replaces click HERE inline)
Landing page strips the CTA block; legacy HERE format still supported
Version 10.66
Fix
project proposals missing Timeline/Deliverables when Claude JSON omits deliverables[] — auto-synthesize from phases + budget before publish
Update
Landing page shows Timeline/Deliverables for older publishes that stored phases but no deliverables array
Version 10.65
Update
Deliverable due dates scale with job duration (e.g. 1–3 months → ~5 week advance, ~8 week final) instead of fixed +14/+28 days
Scrape project duration from Upwork job details; landing page shows readable dates (16 Jun 2026)
Version 10.64
Fix
apply page reads full job description + budget from Upwork Nuxt state (not only visible DOM)
$5k+ budgets in post text set fixed-price even when Upwork omits the “Fixed” label
Update
Healthcare / platform team SOW titles classify as project mode; progress shows Project vs Discovery before Claude runs
Landing page trusts engagement_mode project (no false discovery layout from empty deliverables alone)
Version 10.63
Fix
$80k+ SOW posts no longer stay discovery when Claude returns interview layout — scoped job post overrides model JSON
Update
Scope detection uses full apply-page text (rawPageText), not truncated sidebar description
Prompt includes up to 12k chars of job scope for large enterprise posts
Version 10.62
Update
Large fixed-price SOW posts (budget in description, numbered modules, advance/final payment) classify as project mode even when Upwork omits budget on the DOM
Parse fixed budget from job description for $5k+ posts before engagement detection and proposal economics
Version 10.61
Update
Floating pill on the job page: "Generate Application" opens the panel; inside the panel the green action stays "Create Proposal"
Version 10.60
Update
Restore Proposal economics on apply page for all jobs (was hidden on discovery/unscoped posts in v10.56)
Discovery jobs: hourly rate override only — fixed total hidden so vague posts are not forced into priced milestones
Scoped fixed-price jobs: fixed total + hourly overrides work as before
Version 10.58
Update
Scoped project landing pages can include optional architecture, workflow, and tech-stack Mermaid diagrams when the job warrants them
Discovery/unscoped jobs never publish diagrams; non-technical posts skip diagram generation
Version 10.57
Update
Widget and popup: primary action renamed from "Generate Application" to "Create Proposal" (clearer vs submitting on Upwork)
In-panel loading state shows "Creating…" while drafts generate
Version 10.56
Update
Unscoped/vague job posts (no budget, milestones, or real SOW) auto-detect as discovery — no fabricated hours, $ totals, or paid phase breakdown
Proposal publish URLs and My Proposals links use your active custom domain when enabled
Version 10.35
Update
My Proposals: dark cards (no bright white), Draft label removed, proposals grouped by date in collapsible accordions for easier scrolling
Version 10.34
Update
Added n8n import files 11-proposals-list, 12-proposal-update, 13-profile-update — fixes My Proposals 'List failed (500)' when workflows were never deployed
Clearer error hint when proposals/list webhook is missing on the server
Version 10.33
Update
Profile proposals stats: '8 proposals sent', bar labels, and Last 7 days pill now use light text on dark surfaces (were dark gray on black)
Version 10.32
Update
Fix unreadable GitHub pills on Apply tab and Profile — repo stats and @user badge now use dark surfaces with light text (were white boxes with pale gray text)
Version 10.31
Update
Extension UI matches upworkwizz.com: dark surfaces (#0a0a0a / #111), green accent #14a800, Manrope + Inter
Popup, job application panel, and AI Reply panel restyled — removed leftover light/blue button styles
Transactional email uses proposal.upworkwizz.com: n8n sends from hello@proposal.upworkwizz.com with reply-to on the same address
Proposal page URLs unchanged — still www.upworkwizz.com/<slug>
Version 10.29
Update
One email per account: license key must match the email registered at Stripe checkout — server rejects mismatches
Restore my account only looks up existing Supabase rows; new signups must subscribe at upworkwizz.com (no free active keys from the extension)
Publishing proposals sends your locked email to n8n so the backend can verify key + email together
Version 10.28
Update
Settings: license key and licensed email lock after first save — fields become read-only so a shared key cannot be copied or swapped to another account
Locked license key displays as UPWK-****-****-****-XXXX (last segment only); email shows as d***@d***.com with middle characters hidden
Generate Key and email entry are hidden once locked; use Clear all saved data to enter a different license
Version 10.27
Update
Settings → Subscription: new link to manage your Stripe subscription (cancel, renew, update card, view invoices)
Opens the Stripe Customer Portal — sign in with the email you used at checkout
Version 10.26
Update
Removed the n8n Host field from Settings — the webhook base URL is now baked into the extension and cannot be changed by users
License key generation and proposal publishing always use the preset n8n host (https://n8n.srv1362157.hstgr.cloud)
Version 10.25
Update
Rebranded the extension popup header from 'Autofill v…' to 'Wizz v…' — matches the Upwork Wizz product name
Chrome extension list name updated from 'Upwork AI Autofill' to 'Upwork Wizz'
Version 10.22
Update
Fixed job-title extraction on the Apply page (/nx/proposals/job/.../apply/) — the H1 is 'Submit a proposal' there, not the real title. New extractor: tries [data-test="job-title"], [data-cy="job-title"], .job-title, [class*="JobTitle"] and the Job Details sidebar selectors first; blacklists page-heading phrases like 'Submit a proposal', 'Apply now', 'Application'; only falls back to a generic H1 if it passes the blacklist; finally falls back to document.title with Apply/Submit prefixes stripped
Result: proposals generated from the apply page now correctly capture the actual job title (e.g. 'AI Implementation Manager – Automation & SaaS Integration (Legal Tech)') and bake it into the cover letter, landing page H1, Supabase upwizz_proposals.job_title column, and notification messages
Version 10.21
Update
Removed stale 'proposal.upworkwizz.com' subdomain references throughout the extension UI — Proposals tab card links, popup help copy, and publishing toast now all show 'www.upworkwizz.com/<slug>' matching the live custom domain
Reminder: n8n's WF10 (Proposal Create) Build Response node generates the URL server-side — if you still see Vercel URLs in cover letters, re-import 10-proposal-create.json into n8n (or manually update BASE_URL in the Build Response Code node) and re-activate the workflow
Version 10.20
Update
Cover letter CTA reworded to 'Full breakdown — click HERE: <URL>'. Upwork shows the URL auto-linked next to the call-to-action. On the landing page, this exact sentence is re-rendered as 'Full breakdown — click HERE' with HERE itself as a bold underlined link (raw URL hidden) — a polished hyperlinked CTA, matching the proposal-style landing pages
Updated Claude prompt to emit the exact CTA sentence so well-formed cover letters come out clean before any post-processing
Landing-page CoverLetter component now detects the 'click HERE: <url>' pattern (em-dash, hyphen, or colon variants tolerated) and renders HERE as the link
Version 10.19
Update
Cleaner URL in cover letter: instead of dumping the full URL inline ('Full breakdown of the architecture, deliverables and timeline here: https://www.upworkwizz.com/abc...'), the cover letter now ends with a short two-line label/URL pair ('Full breakdown:\nhttps://www.upworkwizz.com/abc') so Upwork's chat auto-linker renders it as a clean clickable link on its own line
Updated Claude prompt to emit the URL placeholder on its own line with a short lead-in, so well-formed cover letters come out clean before any post-processing
Landing page CoverLetter component now auto-detects URLs in the cover letter text and renders them as styled text links (green accent, underline) showing the domain + path label instead of the raw https:// URL — clients see 'www.upworkwizz.com/abc' clickable, not the full noisy URL
Custom domain live: proposal landing pages now use https://www.upworkwizz.com instead of the temporary https://upwork-wizz.vercel.app. Updated DEFAULT_PROPOSAL_BASE in background.js — every new proposal URL embedded in cover letters and new-view notifications routes through the branded domain
WF10 Build Response node updated to use the new base URL. Re-import 10-proposal-create.json to apply
Version 10.17
Update
Profile avatar now renders at the top of every proposal landing page (right next to 'Proposal from <name>') AND in the About section, replacing the green initial-letter circle once you have an avatar URL set
GitHub Connect: when you connect your GitHub account, the GitHub avatar is auto-saved to settings.profile.avatarUrl (unless you've manually set one) — so the next published proposal renders your photo with zero extra clicks
Avatar / display_name / headline / bio now sync to Supabase on EVERY proposal publish — WF10 was extended with a CTE that updates upwizz_licenses in the same transaction as inserting the proposal. Edit your profile in the extension, publish, and the next proposal landing page picks up the change automatically
WF00 license/create: when an existing email regenerates a key (Use Existing branch), profile fields are now refreshed via a new 'Refresh Profile' Postgres node — so old licenses with empty avatar_url get backfilled the next time you click Generate Key
Version 10.16
Update
Critical fix: cover letter populated with raw JSON dump — Claude's response was being truncated mid-JSON at 4000 max_tokens (4 variants + master proposal + phases + deliverables + estimate easily exceeds that). Bumped max_tokens to 8000 (Sonnet's safe upper bound) so the closing braces always make it through
Robust JSON extraction: replaced the brittle /^```json/ regex with a balanced-brace walker (extractFirstJsonObject) that survives every Claude output shape — ```json fences, ``` fences with 'json' on its own line, prose-prefixed responses, trailing notes after the closing brace. Same extractor mirrored in popup.js so cached results parse too
Safety net: when parsing fails the cover letter is no longer populated with the raw JSON dump (which is what put 12,908 chars of '{"bestVariant":1,...}' into Upwork's composer). Cover letter stays empty, Fill Into Page is hard-blocked, and a red error banner explains what happened with an expandable raw-response viewer for debugging
Stale-cache cleanup: on popup open, if the cached generatedData for this URL looks like a JSON dump from a pre-v10.16 broken run, it's wiped automatically so you don't keep seeing the old garbage every time you reopen the popup
Parse failure also blocks the publish step (no JSON → nothing to publish → no spurious /webhook/proposal/create call with broken data)
Version 10.15
Fix
'nothing was sent to WF10 /proposal/create' — the license key generated via the Settings tab no longer requires a separate 'Save Settings' click. The key + n8n host are now persisted to chrome.storage.local.settings immediately on generation so the very next proposal publish has the credentials it needs
landing page link missing from cover letter — Claude was outputting {{PROPOSALURL}} (no underscore) and field names like coverletter / isfixedprice / whatyouget instead of the expected snake_case. Added two safeguards: (1) a lenient placeholder regex that matches {{PROPOSAL_URL}}, {{PROPOSALURL}}, {{proposal-url}}, etc., and (2) a normalizeProposalFields() pass that maps every common misspelling back to the canonical snake_case names
WF06 webhook URL had a UUID prefix (/webhook/<uuid>/proposal/:slug) because n8n auto-prefixes webhooks with path parameters. Switched 06-proposal-public-read.json to read slug from a query string (?slug=abc), giving a clean /webhook/proposal-read URL. proposal-viewer/src/lib/n8n.ts updated to match — Vercel viewer now calls /webhook/proposal-read?slug=<slug>
Update
Visible publish status: during proposal generation the progress bar now shows 'Publishing landing page to Supabase…' between Claude finishing and the popup rendering. On success: '✓ Landing page <url>'. On failure: '⚠ Publish failed: <reason>' so silent skips never happen again
Apply page now renders a red banner with the publish error and a hint pointing to Settings → License Key / n8n workflow Active toggle when the proposal generated but the landing page didn't
Version 10.14
Update
Proposal viewer base URL is now driven by DEFAULT_PROPOSAL_BASE constant (https://upwork-wizz.vercel.app) with optional override via settings.proposalBaseUrl — flip to proposal.upworkwizz.com once the custom domain is wired
Notification click handler no longer hardcodes proposal.upworkwizz.com — opens the resolved base URL instead, so view-notification clicks land on the actual Vercel deployment
Added two new importable n8n workflows: 10-proposal-create.json (extension publishes a proposal here, returns slug + URL) and 06-proposal-public-read.json (Vercel viewer reads from here on every page render)
Both new workflows follow the upwizz_ prefixed schema + SQL-quote escaping pattern proven in 00-license-create.json
Version 10.13
Update
AI Reply: strict no-markdown output — Claude prompt now explicitly bans **bold**, *italics*, # headers, `backticks`, ### sub-headers, [links](url), and other markdown that would appear as literal asterisks/hashes in Upwork's plain-text composer
AI Reply: paragraph structure preserved — multi-question answers now use plain '1.', '2.', '3.' numbered paragraphs (no markdown emphasis around the numbers)
AI Reply: subtle emoji allowed — 0 to 2 professional emojis per reply (👋 ✅ 👍 🙌 💡 ⚡ 🚀) to feel more human; never at the start of the message, never two in a row; emojis like 🤖 / 😂 / 🎉 / 💯 / 🔥 explicitly banned
AI Reply: em-dash and en-dash still banned (use commas/periods/and instead) — keeps replies looking human-written
Version 10.12
Fix
clicking into the composer after Insert wiped the reply (Tiptap RangeError: Position X out of range) — root cause was the v10.10 insertReply falling back to innerText assignment + chunked execCommand, which corrupts ProseMirror's internal document model
Update
Insert now uses ONLY a synthetic paste event for contenteditable composers (the safe ProseMirror-friendly path); if that doesn't take, falls straight to clipboard with a clear 'click the box and press Ctrl+V' message
Removed all direct DOM mutation strategies (innerText, chunked execCommand) — they were the cause of the disappearing text
Detection more lenient: whitespace-normalized probe + length-grew heuristic so Tiptap's paragraph normalization no longer triggers false 'paste failed' falsebacks
Status message updated after insert: '✓ Inserted — click in the box to edit, then press Send'
Version 10.11
Update
AI Reply length selector: selected option now lights up bright brand-green (was a subtle white pill that was easy to miss) — Short/Medium/Detailed is clearly a 'pick one length, generate one reply' setting, not three different generation actions
Default still Medium; choice persists across sessions; click Generate to produce ONE reply at the chosen length
Version 10.10
Update
AI Reply panel (Upwork messages): new Short / Medium / Detailed length selector — segmented pill control above the textarea, choice persists across sessions
AI Reply: Detailed mode now uses up to 2500 max_tokens and explicitly instructs Claude to answer EVERY numbered question (was truncating multi-part answers at 2/3 questions)
AI Reply: when the client's latest message contains numbered items (Question 1, 2, 3...), the prompt explicitly counts them and tells Claude not to stop early
AI Reply: max_tokens now scales with length — Short=400, Medium=900, Detailed=2500 (was hardcoded 400 for everything)
Insert button: completely rewritten for long text + React/Slate-controlled composers — tries synthetic paste event first (best for Slate/Draft/ProseMirror), falls back to chunked insertText with micro-waits, then direct innerText, then clipboard. Long replies that previously failed silently now insert reliably
Insert button: better composer detection — finds the real visible editable, skips the AI Reply panel's own textarea, drills into Upwork's wrapper divs
Insert timeout for Detailed replies bumped to 60s (large generations can take longer)
Version 10.9
Fix
license generation crashed when profile bio contained an apostrophe (e.g. "If you're losing time...") — n8n workflow now SQL-escapes single quotes before inserting
Update
00-license-create.json + 01-trial-start.json: Validate Input/Email nodes now double up ' to '' (PostgreSQL string-literal escape) for email + all profile fields
01-trial-start.json: Check Existing License set to Always Output Data + Already Exists? now checks for a non-empty email field (matches the fix shipped in 00-license-create.json)
Version 10.8
Update
Settings → license email field is now a full-width input on its own row (was cramped next to the Generate Key button)
Generate Key button is now full-width below the email field — much easier to read and tap
Version 10.7
Update
n8n host is now baked-in (https://n8n.srv1362157.hstgr.cloud) — no setup needed; field is pre-filled and the host is in manifest host_permissions so Chrome doesn't ask for permission
Generate License Key now works with just an email — host field can be left untouched
Publishing badge now reflects license-key state only (host is always available)
Settings field labelled 'preset — leave as-is unless you self-host'
background.js + popup.js fall back to DEFAULT_N8N_HOST whenever settings.n8nHost is blank
Version 10.6
Update
Supabase: all tables renamed with upwizz_ prefix (upwizz_licenses, upwizz_proposals, upwizz_proposal_views) so you can host other apps in the same project
Views, indexes, triggers and the proposals_with_stats view all carry the new prefix
n8n workflows 00-license-create.json and 01-trial-start.json updated to target the prefixed tables
SUPABASE.sql ships with an optional ALTER TABLE rename block (commented out) for installs that already ran the old un-prefixed schema
Workflow specs (02-10) + SETUP.md + SPEC.md updated to reflect new table names — no behaviour changes, just a clean migration
Version 10.5
Update
Settings: Generate License Key button — calls the new 00-license-create.json n8n workflow to self-issue a UPWK-... key (status='active', unlimited proposals) without needing the email/trial flow
Generate Key flow auto-pushes your current Profile fields (name, title, bio, avatar) into the new licenses row so landing pages have an About block immediately
n8n host moved above License Key in Settings (you need the host first to generate a key)
Version 10.4
Update
Stronger cover letters — new prompt produces nedthomas.co.uk-style master letter: direct opening, specific past project as proof, sharp framing, week-by-week phases, Bonus paragraph, concrete next step
Every generated proposal can now be published to proposal.upworkwizz.com/<slug> automatically (when license key + n8n host are set in Settings)
Proposal landing pages include Key Requirements, Architecture phases with components, Cover Letter, What You'll Get, Deliverables table, Timeline, About
Link is woven into the cover letter and a Full breakdown here line is appended as a safety net
NEW Settings: Upwork Wizz License Key + n8n Host (optional — leave blank to keep current direct-Anthropic flow)
NEW Profile field: Avatar URL — shown on every proposal landing page
NEW tab: My Proposals — list every proposal with view counts, status (draft/sent/replied/archived), visibility toggle (unlisted/private), copy/open link
Profile save now syncs the About block (display name, headline, bio, avatar) to Supabase so landing pages always show current info
First-view notifications: Chrome alert when a client opens your proposal link for the first time (and on each new view); click the notification to open the landing page
Version 10.3
Update
Infrastructure groundwork for shareable proposal landing pages at proposal.upworkwizz.com/<slug>
Supabase: new proposals + proposal_views tables, license About fields (display_name, headline, bio, avatar_url)
n8n: /generate now inserts each proposal into Supabase, returns slug + URL, auto-appends Full breakdown link to every variant
n8n: new workflows for GET /proposal/:slug, POST /proposals/list, POST /proposal/update, POST /profile/update
New Next.js proposal viewer app under proposal-viewer/ ready to deploy to Vercel (unlisted by default, password-protectable)
Version 10.2
Update
AI Reply: improved sender ownership detection so thread owner/client messages are distinguished from your own messages
AI Reply prompt now explicitly treats 'Me:' lines as your previous messages and replies only to the latest client context