halo-agent 2.4.1 → 2.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -429,12 +429,19 @@ async function detectRequiredEmptiesInRoot(page) {
429
429
  // control (not a shared group container with multiple inputs).
430
430
  const labelTextOf = (lblEl) => (lblEl && (lblEl.innerText || lblEl.textContent || '')).trim();
431
431
  const marks = (txt) => /\*\s*$/.test(txt) || /\(\s*required\s*\)/i.test(txt) || /\brequired\b\s*\*?$/i.test(txt);
432
+ // Class-marker required detection. Ashby renders the asterisk via a
433
+ // CSS ::after pseudo-element on a label whose className includes
434
+ // "_required_" / "required". The text-based `marks()` check above can't
435
+ // see pseudo-content, so we also accept a className match. Same idea
436
+ // covers many other React component-libraries (Workable, custom
437
+ // tailwind builds) that don't put the literal "*" in label text.
438
+ const labelHasRequiredClass = (lblEl) => !!(lblEl && lblEl.className && /(^|[\s_-])required($|[\s_-])/i.test(lblEl.className));
432
439
 
433
440
  if (el.id) {
434
441
  const lbl = document.querySelector(`label[for="${el.id}"]`);
435
- if (lbl) return marks(labelTextOf(lbl));
442
+ if (lbl) return marks(labelTextOf(lbl)) || labelHasRequiredClass(lbl);
436
443
  }
437
- if (el.labels && el.labels[0]) return marks(labelTextOf(el.labels[0]));
444
+ if (el.labels && el.labels[0]) return marks(labelTextOf(el.labels[0])) || labelHasRequiredClass(el.labels[0]);
438
445
 
439
446
  // Closest wrapping label/legend, but ONLY if that container holds a
440
447
  // single control (so we don't inherit a group asterisk meant for a
@@ -444,7 +451,7 @@ async function detectRequiredEmptiesInRoot(page) {
444
451
  const labelEl = p.querySelector(':scope > label, :scope > legend, :scope > [class*="label"]');
445
452
  if (labelEl) {
446
453
  const controlsInScope = p.querySelectorAll('input:not([type=hidden]), textarea, select, [role="combobox"], [contenteditable="true"]').length;
447
- if (controlsInScope <= 1) return marks(labelTextOf(labelEl));
454
+ if (controlsInScope <= 1) return marks(labelTextOf(labelEl)) || labelHasRequiredClass(labelEl);
448
455
  // Shared container with multiple controls — the asterisk isn't
449
456
  // necessarily ours. Stop; treat as not-required unless a
450
457
  // programmatic marker said otherwise (handled above).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "halo-agent",
3
- "version": "2.4.1",
3
+ "version": "2.4.3",
4
4
  "description": "HALO local apply agent — auto-fills job applications using your real Chrome session",
5
5
  "main": "index.js",
6
6
  "bin": {