halo-agent 2.3.0 → 2.4.0

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.
Files changed (2) hide show
  1. package/orchestrator.js +32 -0
  2. package/package.json +1 -1
package/orchestrator.js CHANGED
@@ -54,6 +54,8 @@ async function fillFields(page, aep, opts) {
54
54
  const { detectCaptcha, solveCaptcha, injectCaptchaToken } = require('./captcha');
55
55
  const { visionFill, visionNavigateAndSubmit, visionFillSkipped } = require('./vision');
56
56
  const { scanWorkday } = require('./scanWorkday');
57
+ const { scanAccessibility } = require('./scanAccessibility');
58
+ const { findApplyPath } = require('./findApplyPath');
57
59
 
58
60
  // ATS types that need vision fallback due to shadow DOM / canvas.
59
61
  // 'workday' was here historically because the AX-tree scan returned no usable
@@ -164,6 +166,36 @@ async function runJob(queueItem, chromeConn, config, reportStatus) {
164
166
  // May return a new page object if Apply opened a new tab.
165
167
  page = await clickApplyIfNeeded(page);
166
168
 
169
+ // STEP 1.5: Find the apply path if the page still has no fields.
170
+ //
171
+ // clickApplyIfNeeded only handles obvious cases (a literal "Apply" button
172
+ // outside the form). It misses:
173
+ // - tabs (Overview / Application on Mercor's Ashby-wrapped careers page)
174
+ // - "Continue to application" CTAs below the fold
175
+ // - non-semantic styled divs that act as the entry point
176
+ //
177
+ // findApplyPath checks the cache, then probes the AX tree for apply-keyword
178
+ // clickables, then falls back to vision. Bounded to 2 click hops. If it
179
+ // still can't find fields, we surface NEEDS_ATTENTION below instead of the
180
+ // blind resume-uploader hack.
181
+ try {
182
+ const earlyScan = await scanAccessibility(page);
183
+ if (!earlyScan || earlyScan.length === 0) {
184
+ console.log('[orchestrator] No fields after clickApplyIfNeeded invoking findApplyPath');
185
+ const result = await findApplyPath(page, { config, anthropicKey });
186
+ if (result.found) {
187
+ console.log(`[orchestrator] findApplyPath: ${result.method} succeeded (${result.fields_after} fields)`);
188
+ } else {
189
+ console.warn('[orchestrator] findApplyPath: no apply path found form may need manual navigation');
190
+ // We continue anyway handlePageGate / smartFill may still find
191
+ // something. If everything fails downstream, the existing NEEDS_ATTENTION
192
+ // surface fires from the orchestrator's terminal error handler.
193
+ }
194
+ }
195
+ } catch (e) {
196
+ console.warn(`[orchestrator] findApplyPath threw: ${e.message}`);
197
+ }
198
+
167
199
  // STEP 2: Vision gate detection — handles modals, resume prompts, login walls, preamble screens.
168
200
  // Runs before captcha check so the form is actually visible before we try to fill it.
169
201
  const gateResult = await handlePageGate(page, aep, tempResumeFile, config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "halo-agent",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "HALO local apply agent — auto-fills job applications using your real Chrome session",
5
5
  "main": "index.js",
6
6
  "bin": {