100 Commits
Author SHA1 Message Date
Federico Elia 4ea915ffb4 Merge pull request #1487 from feder-cr/sites-dry-runs
A menus plugin for every form, three sites' lists learned from dry runs
2026-11-07 13:24:42 +01:00
Federico Elia 4b9ea72dcb Merge pull request #1486 from feder-cr/workday-plugin
Workday plugin, the mail code read from Gmail, answers in the store, costs, and the minimal screen
2026-11-07 11:11:04 +01:00
Federico Elia ba2303b437 Merge pull request #1485 from feder-cr/jobs-every-5-hours
Job database: rebuilt every five hours
2026-11-07 03:40:14 +01:00
Federico Elia b78169d7cc Merge pull request #1484 from feder-cr/readme-job-application-wording
README: say job application bot, job search and auto-apply in the first lines
2026-11-07 03:39:50 +01:00
Federico Elia 0212a10580 Merge pull request #1482 from feder-cr/captcha-sites
docs/sites.md: a new run each on JazzHR and BambooHR
2026-11-05 20:10:49 +01:00
feder-cr d1e8cb3bee docs/sites.md: a new run each on JazzHR and BambooHR 2026-11-05 20:07:38 +01:00
Federico Elia 1cc83c524f Merge pull request #1481 from feder-cr/sites-two-runs
docs/sites.md: two runs each on SmartRecruiters and Paylocity reached the send button
2026-11-05 19:58:15 +01:00
feder-cr 9f22016d23 docs/sites.md: two runs each on SmartRecruiters and Paylocity reached the send button 2026-11-05 19:54:58 +01:00
Federico Elia 0a88535eba Merge pull request #1480 from feder-cr/forms-not-stuck
A form does not run out of steps repeating what changed nothing
2026-11-05 19:38:35 +01:00
feder-cr 7737d2293e A form does not run out of steps repeating what changed nothing
Recorded on a real SmartRecruiters form: about 40 of 150 steps went on PageUp and a screenshot, in a form that scrolls inside its own container. The model is told not to repeat an action that changed nothing, and the plugin says how that form scrolls. On the next runs SmartRecruiters and Paylocity reached the send button; nothing was sent. Also the last mentions of the per-job CV.
2026-11-05 19:34:37 +01:00
Federico Elia 0f6b9b02ca Merge pull request #1479 from feder-cr/readme-how
README: what it does before the install, and a banner that shows the two windows at work
2026-11-05 19:15:13 +01:00
feder-cr 7ea02ac86e README: what it does before the install, and a banner that shows the two windows at work
A step table and four reasons, as the projects people use in this field do it, so that a reader knows what the program does before installing it. In the banner the app answers each send beside Firefox, the confirmations can be read, and the counter has its time.
2026-11-05 19:11:31 +01:00
Federico Elia 2f342b721d Merge pull request #1478 from feder-cr/readme-small
README: a banner for the smallest screens, and the press line as Featured in
2026-11-05 19:00:05 +01:00
feder-cr 0a483f97d2 README: a banner for the smallest screens, and the press line as Featured in 2026-11-05 18:56:32 +01:00
Federico Elia 81a4cac39c Merge pull request #1477 from feder-cr/readme-breakpoint
README: the phone banner below 1239 pixels, as in the other projects
2026-11-05 18:51:09 +01:00
feder-cr 42109ed275 README: the phone banner below 1239 pixels, as in the other projects 2026-11-05 18:47:15 +01:00
Federico Elia c3f5ab3912 Merge pull request #1476 from feder-cr/banner-windows
Banner: the app at work, in the grammar of the other projects' banners
2026-11-05 18:45:52 +01:00
feder-cr c61ab594d3 Banner: the app at work, in the grammar of the other projects' banners
Logo, four short chapters, and windows that open and work: the terminal, AIHawk matching the jobs, Firefox applying form after form. On GitHub's exact background, so the banner has no edge.
2026-11-05 18:42:39 +01:00
Federico Elia 0bd868fc53 Merge pull request #1475 from feder-cr/send-reading
A send's page is read until it says something, and an error comes out as itself
2026-11-05 18:34:04 +01:00
feder-cr 09b8b75e90 A send's page is read until it says something, and an error comes out as itself
The MCP client's task groups wrapped every failure during a form, so a refused key was not recognised and the person read 'unhandled errors in a TaskGroup'. A page still showing 'Submitting...' was judged at once and the browser closed. docs/sites.md records the real runs on Workable, SmartRecruiters and Paylocity.
2026-11-05 18:30:49 +01:00
Federico Elia 3da4faa3c9 Merge pull request #1474 from feder-cr/readme-voice
README: what it is in one line, the command, three steps
2026-11-05 18:30:25 +01:00
feder-cr 524f9dd241 README: what it is in one line, the command, three steps
For the person looking for a job. The warnings move to SECURITY.md, and the film is 21 seconds and ends on the same line as the page.
2026-11-05 18:26:08 +01:00
Federico Elia 17c70e76dc Merge pull request #1473 from feder-cr/readme-film
README: a short film in place of the banner and the demo, and no site table
2026-11-05 18:26:06 +01:00
feder-cr d559055ef2 README: say it in two lines, then the commands
In the voice of the other READMEs: what others do, what this one does, and the install. The measurements move to docs/sites.md.
2026-11-05 18:17:48 +01:00
feder-cr 7987df831b README: a short film in place of the banner and the demo, and no site table
One film, in the formats of the other projects' banners. It says one thing: nobody wants to apply for a job, you want the job. The table of sites stays in docs/sites.md.
2026-11-05 18:14:21 +01:00
Federico Elia 7793e25fad Every posting is tried, and the README in the shape of the others (#1472) 2026-11-05 18:04:32 +01:00
feder-cr 5358834a9f Every posting is tried: a plugin helps where there is one 2026-11-05 18:00:58 +01:00
feder-cr 9b26b349d7 Lever: a send confirmed through the app as it is now 2026-11-05 17:42:18 +01:00
feder-cr b3a1a5a0f0 README: the shape of the other READMEs, with a banner and what has been measured 2026-11-05 17:41:49 +01:00
Federico Elia 5437d7cd15 Four more sites reach the send button, and their plugins name it (#1470) 2026-11-05 17:12:51 +01:00
feder-cr 708c28917f The rest: the plugins name the send control, and the counts' words 2026-11-05 17:08:20 +01:00
feder-cr a7121c7c98 Four more sites reach the send button, and their plugins name it 2026-11-05 17:07:46 +01:00
Federico Elia 7acc7899b2 Your own CV with every form, one gateway and one folder, no warnings about an old database (#1469) 2026-11-05 16:32:20 +01:00
feder-cr 3146c3f891 The key's link on the screen too 2026-11-05 16:28:56 +01:00
feder-cr 6f04dd0b3e README: where to get a key, with the referral stated 2026-11-05 16:26:42 +01:00
feder-cr 9f72278f35 The real-browser tests make their own CV file 2026-11-05 16:26:14 +01:00
feder-cr 0a331e936c Your own CV with every form, one gateway and one folder, no warnings about an old database 2026-11-05 16:22:02 +01:00
Federico Elia cd37c8f9fd One command, everything on the screen, and no more checks on the model (#1468) 2026-11-05 15:19:50 +01:00
feder-cr 844f2d5684 150 steps: long forms were stopped at their last page 2026-11-05 15:15:34 +01:00
feder-cr 69d93438cd The repository's new name 2026-11-05 14:48:34 +01:00
feder-cr b23cadb276 One command, everything on the screen, and no more checks on the model 2026-11-05 14:47:50 +01:00
Federico Elia 19465fc04f The screen says how each send went and what to do next, and fits 80 columns (#1467) 2026-11-05 12:46:12 +01:00
feder-cr a43d74c798 The screen says how each send went and what to do next, and fits 80 columns 2026-11-05 12:42:16 +01:00
Federico Elia e758bd61e0 Score a job with no stored text on its own page, and show the real screen in the README (#1466) 2026-11-05 12:23:20 +01:00
feder-cr 290de45e4d Score a job with no stored text on its own page, and show the real screen in the README 2026-11-05 12:19:53 +01:00
Federico Elia 8804a31ffd One posting cannot stop the screen, one CV cannot stop the selection, no local file by address (#1465) 2026-11-05 11:54:02 +01:00
feder-cr 02ba09f666 A simpler test, as the newest ruff asks, and what the file address could really reach 2026-11-05 11:50:03 +01:00
feder-cr a7bbca6ed0 One posting cannot stop the screen or read a local file, and one CV cannot stop the selection 2026-11-05 11:45:57 +01:00
Federico Elia f3223b8569 Plugins: what real forms taught about each site, and a confirmed send on Teamtailor (#1464) 2026-11-05 11:38:07 +01:00
feder-cr 8966ec97a3 Plugins: what real forms taught about each site, and a confirmed send on Teamtailor 2026-11-05 11:34:41 +01:00
Federico Elia 7b193af502 Sites: a confirmed send on Recruitee, and Lever's own words (#1463) 2026-11-05 10:17:16 +01:00
feder-cr 881badd0ee Sites: a confirmed send on Recruitee, and Lever's own words 2026-11-05 10:12:55 +01:00
Federico Elia e74f532b83 Read the page after a send once it has settled, and what the test sends showed (#1462) 2026-11-05 08:48:59 +01:00
feder-cr 5e55568f53 Sites: what one round of labelled test sends showed 2026-11-05 08:45:27 +01:00
feder-cr a9ed365344 After a send, read the page once it has settled, and judge it with its address 2026-11-05 07:58:25 +01:00
Federico Elia 4d61118129 What a stranger needs: forms, send check, CVs, judging, sources and limits (#1461) 2026-11-05 07:29:29 +01:00
feder-cr 4c98668d75 Changelog: the last fixes 2026-11-05 07:04:16 +01:00
feder-cr 78d7809c6a Merge branch 'send-code-exemption' into data-sources 2026-11-05 06:58:50 +01:00
feder-cr 10712972e8 Code-request exemption covers only the request; Enter limit stated 2026-11-05 06:58:28 +01:00
feder-cr 60039535b3 Engine defects: stale CVs, judge failures, config types, font wording, settings rewrite 2026-11-05 06:52:10 +01:00
feder-cr 33234f9eb3 Asking for a sign-in code is not a send, and the limits of the send check are stated 2026-11-05 06:33:19 +01:00
feder-cr 2fe2f31fea Merge branch 'docs-claims' into data-sources 2026-11-05 06:27:36 +01:00
feder-cr d3573d06b3 Merge branch 'send-words' into data-sources 2026-11-05 06:27:36 +01:00
feder-cr 60d252d49c Engine defects: CV glyphs, judge splits, database age, plugin encoding
- CV: a tailored CV the font cannot draw is not written; the person's own CV is sent, with one line saying why.
- Judge: only a request too large for the endpoint is split; other failures end at once, and the funnel says how many
  postings were not judged and why.
- Database: the date is the manifest's; a database older than 7 days is said to be stale; an empty search says when the
  60-day age limit is the reason.
- Plugins: a plugin that is not UTF-8 raises PluginError naming the file, as a bad plugin already does.
2026-11-05 06:27:13 +01:00
feder-cr c843b75165 Send words: Candidatar and its forms; Confirm, Finish, Complete only as the label or before an application 2026-11-05 06:24:17 +01:00
feder-cr 9d8c6849d9 Docs: fix README and doc claims, document the config keys 2026-11-05 06:21:47 +01:00
feder-cr a2dc29b491 Data sources: what each source's own licence says, and the credit they ask for 2026-11-05 04:58:15 +01:00
feder-cr cc598fddd7 Merge branch 'aihawk-app' into data-sources 2026-11-05 04:58:14 +01:00
feder-cr 1c054dc6d3 Data sources: list all 24, their licences and how to remove one 2026-11-05 04:56:20 +01:00
feder-cr 3cfdd23581 A test helper as a function, as ruff asks 2026-11-05 04:56:05 +01:00
feder-cr bffe28e385 Merge branch 'code-for-adopters' into aihawk-app 2026-11-05 04:13:04 +01:00
feder-cr 4ccd937475 Fix what a cold review found in the engine, the config and the dependencies
The browser gets the environment without the model key: the one the settings name, and the default.
rich is declared, as tui.py imports it.
Dead code removed: Store.to_apply, the threshold setting, and tests of removed names.
A new resume replaces the plan and keeps the person's filters, such as exclude.
An unreadable description database is reported once per search, and the search goes on.
_places has no empty part, so a place without a city no longer reads ", Italy".
The apply protocol is named Browser, not Session.
Confirm, Finish and Complete are held back from any element, as sends do.
Judge comments say why, with no numbers a reader cannot check.
2026-11-05 02:39:27 +01:00
feder-cr 90e63afe8f Docs for adopters: data, cost, responsibility, updates
README says what leaves the computer and what it costs, who answers for what is sent, how to update and uninstall, and where the search is changed. It states that the mail plugins' read-only rule is an instruction to the model, not enforced in code.

CONTRIBUTING: CI runs on Ubuntu, Windows and macOS, Python 3.11 and 3.12; ruff check runs the default rules, so the 160 line length is not enforced.
docs/plugins.md: the example is lever.md as it is.
SECURITY.md: the mail plugins' read-only rule is an instruction, not a guarantee.
Phone numbers removed from docs/sites.md and the SmartRecruiters plugin; the plugin gives a placeholder.
LLDB engine credit reworded in NOTICE and profile.py comment; CHANGELOG says what the repository was.
2026-11-05 02:24:27 +01:00
feder-cr efa34bd88e Send check: read a click's selector the way the engine finds its element, shadow roots and >> chains included 2026-11-05 02:07:43 +01:00
feder-cr 744d710e34 SmartRecruiters: the plugin says how the country, phone, CV and menus work; sites row updated from five real runs 2026-11-05 01:51:02 +01:00
feder-cr f1e764854f Sites: what forms did on real sites, without calling them unfinished 2026-11-05 01:07:58 +01:00
feder-cr 5356361bbb Docs: each site's real status in docs/sites.md, linked from the README
The README site list is replaced by a one-line summary and a link to a
table of status per site, from the real forms trials and the index counts.
Ashby's after-sending section quotes the page a real send showed; the
SmartRecruiters plugin says what stops it today.
2026-11-05 01:07:18 +01:00
feder-cr fd80fa6181 Forms: a navigating call is read until its page has changed, and only the latest picture stays in the prompt
A select, click or key press that leaves the site returns before the new page has begun to load, so the address read
right after it could still be the form's and the form went on. The page is now read again, for a short while, until its
document has changed (its time origin) or its address has. A page that stays the same is the answer, not a fault.

Each screenshot the model is sent stayed in every later call. Now only the latest one stays, and an older one is a note
that it was taken. The model acts on the latest picture.
2026-11-05 00:49:21 +01:00
feder-cr 9a4858ab52 Forms: refused selectors say what to do, shadow-root clicks are checked where they land, and a form that cannot finish stops with its report
A click the check cannot read (Playwright >> chains, :has-text, a control inside a shadow root) is refused with the way
to click it instead: browser_click_at on its centre. The point check reads the innermost element inside open shadow
roots, as the mouse reaches it, so a send control there is refused. A selector that also matches inside a shadow root is
not read. Space and Enter read the focused element inside shadow roots too.

A call refused three times in a row stops the form, and a form that reaches the step limit stops too. Either way the
model is asked once, with only finish_form, what is filled and what did not stick. It never comes back ready, and
needs_input keeps its questions. The step limit is unchanged.

The system rules say a >> or text-syntax selector is refused and what to click instead, and the SmartRecruiters plugin
says the Easy Apply form is in a shadow root.
2026-11-05 00:38:23 +01:00
feder-cr afd7e0a688 Merge branch 'hard-controls' into aihawk-app 2026-11-05 00:08:22 +01:00
feder-cr cde65e964b Teamtailor plugin: how a custom menu opens and reads, and what a refused tag field means 2026-11-04 23:05:05 +01:00
Federico Elia eb54b9b4f7 First-run fixes, forms on real sites, and what contributors need 2026-11-04 23:01:27 +01:00
feder-cr 4c68f897a0 Merge branch 'first-run-fixes' into aihawk-app 2026-11-04 22:52:27 +01:00
feder-cr f7ef2564bb First run: a refused key, quitting, 80 columns, plain errors, BOM files, install and CI
A key that OrcaRouter refuses is forgotten when it came from the key file, and asked for again; a key from the
environment is named by its variable and not forgotten. Ctrl+C leaves at every prompt, and leaving while a prompt
is open no longer raises NoMatches from the heading. Log lines wrap to the whole width, and Quit stays on the
footer at 80 columns. Database and model failures say what happened in plain words, with the detail after them.
Files saved with a byte-order mark are read. The README gives the install commands checked in new venvs, the
index size from the manifest, and how to change the key. CI runs the unit job on Python 3.11 and 3.12 on Ubuntu,
Windows and macOS; gate still needs all of it. The classifiers name the three systems.
2026-11-04 22:52:08 +01:00
feder-cr 7e2da5ab31 Merge branch 'captcha-click' into aihawk-app 2026-11-04 22:38:30 +01:00
feder-cr d2f93b5850 Texts: the one sentence about AIHawk everywhere, the README for a one-minute read, and true statements about models, mail and the database 2026-11-04 22:24:51 +01:00
feder-cr dcec5023b5 Captcha: a box to tick is clicked once, a puzzle is blocked
The form model may click a captcha shown as a box to tick (Turnstile,
reCAPTCHA), usually at its coordinates, wait a few seconds, read the page
again and try once more if the box is still unticked. A puzzle or image
challenge, a login wall or a closed posting is still blocked. No solving
service and no script on a captcha.

Tests: a click on the captcha's frame passes the guard, a captcha frame
does not count as sending or as touching the form, and a captcha click
followed by a send is handled through fill_form.
2026-11-04 22:17:10 +01:00
feder-cr 9094020f7f Open-source basics: CONTRIBUTING, the plugin guide, SECURITY, issue and pull request templates, CHANGELOG 2026-11-04 22:15:46 +01:00
feder-cr d1c3e2d0e6 Forms: deepseek-v4.1-flash by default; Enter allowed in a tag field that asks for it
The default form model moves to deepseek/deepseek-v4.1-flash: about 3 minutes and 1.5 US cents a form on 11 real sites,
85 of 100 on the hard local forms, level with the best within noise, where glm-5.3-flash took twice as long at three
times the cost.

Enter is refused everywhere except a bare Enter in a text input or textarea whose own placeholder or aria-label asks
for it (Paylocity's skills, Teamtailor's tags). Control+Enter and other combinations stay refused.
2026-11-04 21:18:09 +01:00
Federico Elia 69be2d40b5 AIHawk: find the jobs that fit your CV and apply to them 2026-11-04 19:15:02 +01:00
feder-cr ce01c37a31 Docstrings and plugin text: the selection and one Enter is the yes, no auto-submit; plugin after-sending notes say only what to read 2026-11-04 19:10:53 +01:00
feder-cr cdf2129e86 Merge branch 'send-and-list' into aihawk-app
# Conflicts:
#	README.md
#	tests/test_apply.py
#	tests/test_jobs.py
2026-11-04 19:06:20 +01:00
feder-cr 9840ed6da4 Send the selected jobs on one yes, keep what each page said, and list what was sent
One question before a batch is sent (Enter sends, Escape cancels); no per-job confirmation and no --auto-submit.
A form's questions are asked after the others are sent, then the form is tried again.
After the click the verifying model gets the plugin's text as its rules and the page as untrusted text.
Each clicked job keeps its time, final address, verdict and evidence, page text and a screenshot under data/proofs.
Key s lists every job tried with its plain status; applied.csv is rewritten after each attempt, cells that start like a formula are made text.
2026-11-04 19:04:47 +01:00
feder-cr 193b5ed027 Merge branch 'small-description-files' into aihawk-app 2026-11-04 18:58:54 +01:00
feder-cr a5ac30fbba Descriptions read one query per file: 128 MB files and 2048-row groups, measured at 470 MB to 111 MB per search 2026-11-04 18:58:31 +01:00
feder-cr 2d036b1d2c Lint: what the full rule set finds, unused noqa and an explicit check 2026-11-04 18:57:09 +01:00
feder-cr 776bfee32b Merge branch 'script-rung' into aihawk-app 2026-11-04 18:53:27 +01:00
feder-cr e9a9c7746e AIHawk: offer browser_evaluate as the last rung, watched after each call
The model may run script again, by the owner's decision, knowing a script could send a form without the person's yes.
NEVER_OFFERED is gone. The system prompt says script comes only after selectors, coordinates and a screenshot have
failed, and never to send the application. browser_evaluate counts as acting, so a script that leaves the form's host
stops the form as unconfirmed. The docstrings and the README say what holds.
2026-11-04 18:53:17 +01:00
feder-cr 0c82d4317a plugins: how to tell a sent application was received, per ATS
Each of the 12 site plugins gets a last section: what follows a submit,
with the evidence level per site (real send, saved page, documentation or
nothing). No form was submitted for this.
2026-11-04 18:50:12 +01:00
feder-cr 7179db6da6 Judge with Jev in batches: up to 85 postings and 180k tokens a request, split on failure 2026-11-04 18:33:55 +01:00