{
  "slug": "bw-lead-ai",
  "name": "BW Lead Attribution Intelligence",
  "version": "1.2.2",
  "download_url": "https://plugins.bowden.works/wp-content/uploads/plugin-updates/bw-lead-ai-1.2.2.zip",
  "download_hash": "sha256:a206dd83ec085ee40042757ffbbdcb3b3d6431023de4215a9f2ede4e272556a0",
  "download_size": 246288,
  "requires": "6.0",
  "tested": "",
  "requires_php": "7.4",
  "last_updated": "2026-07-27",
  "homepage": "https://plugins.bowden.works/bw-lead-ai/",
  "author": "Bowden Works",
  "description": "Capture traffic source, attribute it to every lead, and understand where your leads are coming from.",
  "changelog": "## [1.2.2] - 2026-07-27\n\n### Changed\n- **Summary data points now render as `<input type=\"hidden\">` instead of a hidden\n  `<textarea>`**, making every BW Lead Data field the same shape on the front end.\n\n  This is integration hardening rather than a bug fix — the old markup was hidden\n  correctly and never leaked on its own. But third-party code that walks a form and\n  skips `input[type=hidden]` *by type* — a common shortcut — would sail straight past\n  a hidden `<textarea>` and treat Summary as a user-facing field. A multi-page form\n  with a custom \"review your answers\" step hit exactly that and displayed the\n  attribution summary back to the visitor. Channel was never affected, because it\n  was already a hidden input; that asymmetry is what made the symptom confusing.\n\n  Line breaks are unaffected. The HTML spec applies no value sanitization algorithm\n  to `type=hidden`, so newlines survive both `.value` and form submission\n  byte-identically to a textarea — verified in a browser, and covered by the\n  acceptance suite. (`type=text` *does* strip them, which is where the \"inputs can't\n  hold multiline\" assumption comes from.) Entry detail and debug mode still render a\n  `<textarea>`, where the value is meant to be read and edited.\n\n### Added\n- **README now documents the integration contract** for theme and plugin developers.\n  A BW Lead Data field is necessarily `gfield_visibility_visible` — a field the\n  browser populates has to render — and its wrapper carries **`gform_hidden`**. Code\n  deciding \"is this field user-facing?\" must key on `gform_hidden`, not on\n  `gfield_visibility_hidden` and not on an inline `display:none` (which only appears\n  for Gravity Forms conditional logic). Also documents the sharp edge that debug mode\n  swaps `gform_hidden` for `bw-lead-ai-debug-visible`.\n- README filled out generally — feature list, full merge-tag reference, and FAQ\n  covering non-Gravity-Forms use and what is stored client-side. It was a stub.\n- **`tests/acceptance.js`** — a dependency-free acceptance suite (`node\n  tests/acceptance.js`, 70 checks) covering the resolution cascade, referrer\n  classification, visit-history capping, custom dimensions, merge-tag substitution,\n  legacy selector targets and interaction storage. Exits non-zero so it can gate a\n  release; excluded from the release zip. Added in response to acceptance criterion\n  R3 having sat unverified since 0.5.0 while hiding the 1.2.1 referrer bug.\n- SPEC.md's acceptance table now records **how** each row was verified — `auto`,\n  `wp-cli` or `browser` — so an unchecked box is never ambiguous about what is\n  actually missing."
}
