atsfill 0.0.4.dev89__tar.gz → 0.0.4.dev90__tar.gz

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 (46) hide show
  1. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/PKG-INFO +3 -3
  2. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/README.md +2 -2
  3. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/pyproject.toml +1 -1
  4. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/pyproject.toml.orig +1 -1
  5. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/phenom.py +1 -1
  6. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/workday.py +1 -1
  7. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/wttj.py +4 -4
  8. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/browser.py +1 -1
  9. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/results.py +1 -1
  10. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/registry.toml +2 -2
  11. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/LICENSE +0 -0
  12. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/__init__.py +0 -0
  13. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/__init__.py +0 -0
  14. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/ashby.py +0 -0
  15. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/bamboohr.py +0 -0
  16. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/breezy.py +0 -0
  17. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/dayforce.py +0 -0
  18. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/eightfold.py +0 -0
  19. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/greenhouse.py +0 -0
  20. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/hireology.py +0 -0
  21. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/hiringthing.py +0 -0
  22. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/jazzhr.py +0 -0
  23. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/lever.py +0 -0
  24. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/manatal.py +0 -0
  25. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/oracle.py +0 -0
  26. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/paycor.py +0 -0
  27. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/paylocity.py +0 -0
  28. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/personio.py +0 -0
  29. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/pinpoint.py +0 -0
  30. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/recruitee.py +0 -0
  31. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/rippling.py +0 -0
  32. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/smartrecruiters.py +0 -0
  33. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/teamtailor.py +0 -0
  34. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/workable.py +0 -0
  35. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/adapters/zohorecruit.py +0 -0
  36. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/cli.py +0 -0
  37. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/__init__.py +0 -0
  38. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/accounts.py +0 -0
  39. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/adapter.py +0 -0
  40. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/attempts.py +0 -0
  41. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/commands.py +0 -0
  42. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/matching.py +0 -0
  43. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/passwords.py +0 -0
  44. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/paths.py +0 -0
  45. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/core/registry.py +0 -0
  46. {atsfill-0.0.4.dev89 → atsfill-0.0.4.dev90}/src/atsfill/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atsfill
3
- Version: 0.0.4.dev89
3
+ Version: 0.0.4.dev90
4
4
  Summary: Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle.
5
5
  Keywords: job-applications,ats,ashby,greenhouse,teamtailor,ai-agents,cli
6
6
  Author: shbernal
@@ -65,7 +65,7 @@ It is built for agents with a shell: every command prints one JSON document and
65
65
  | Teamtailor | no | no |
66
66
  | Welcome to the Jungle | yes, `atsfill login wttj` | no |
67
67
 
68
- Any other system returns `unsupported`, so the caller can fall back to driving a browser itself.
68
+ Any other system returns `unsupported`, so the consumer can fall back to driving a browser itself.
69
69
 
70
70
  ## Why atsfill?
71
71
 
@@ -133,7 +133,7 @@ A dry run is not invisible: some systems save answers or the resume as they are
133
133
  `atsfill status` lists each system's side effects, whether it is allowed to submit, and how far atsfill has verified it: [the systems](docs/adapters/README.md).
134
134
  A dry run or a `send` through an adapter no send was verified on carries a `warning`; the send goes ahead anyway.
135
135
 
136
- One home can apply for more than one person: `--user <name>` gives each their own sessions, double-send guard and `[users.<name>]` section in the config file ([ADR 0015](docs/adr/0015-users-and-accounts.md)).
136
+ One home can send for more than one user: `--user <name>` gives each their own sessions, double-send guard and `[users.<name>]` section in the config file ([ADR 0015](docs/adr/0015-users-and-accounts.md)).
137
137
  Given an account's email (`atsfill login <adapter> --email`) and a password source (a `[password-commands]` entry such as `rbw get example.com {email}`, or `--password -` on stdin), atsfill signs in by itself, and again whenever a form command finds the session signed out.
138
138
  Where a system's sign-up allows it, `atsfill login <adapter> --create --email <address>` creates the account with a password atsfill generates and keeps in the system's secret store, never printed; creating an account is a side effect, never part of `fill` or `send`.
139
139
 
@@ -39,7 +39,7 @@ It is built for agents with a shell: every command prints one JSON document and
39
39
  | Teamtailor | no | no |
40
40
  | Welcome to the Jungle | yes, `atsfill login wttj` | no |
41
41
 
42
- Any other system returns `unsupported`, so the caller can fall back to driving a browser itself.
42
+ Any other system returns `unsupported`, so the consumer can fall back to driving a browser itself.
43
43
 
44
44
  ## Why atsfill?
45
45
 
@@ -107,7 +107,7 @@ A dry run is not invisible: some systems save answers or the resume as they are
107
107
  `atsfill status` lists each system's side effects, whether it is allowed to submit, and how far atsfill has verified it: [the systems](docs/adapters/README.md).
108
108
  A dry run or a `send` through an adapter no send was verified on carries a `warning`; the send goes ahead anyway.
109
109
 
110
- One home can apply for more than one person: `--user <name>` gives each their own sessions, double-send guard and `[users.<name>]` section in the config file ([ADR 0015](docs/adr/0015-users-and-accounts.md)).
110
+ One home can send for more than one user: `--user <name>` gives each their own sessions, double-send guard and `[users.<name>]` section in the config file ([ADR 0015](docs/adr/0015-users-and-accounts.md)).
111
111
  Given an account's email (`atsfill login <adapter> --email`) and a password source (a `[password-commands]` entry such as `rbw get example.com {email}`, or `--password -` on stdin), atsfill signs in by itself, and again whenever a form command finds the session signed out.
112
112
  Where a system's sign-up allows it, `atsfill login <adapter> --create --email <address>` creates the account with a password atsfill generates and keeps in the system's secret store, never printed; creating an account is a side effect, never part of `fill` or `send`.
113
113
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "atsfill"
3
- version = "0.0.4.dev89"
3
+ version = "0.0.4.dev90"
4
4
  description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "atsfill"
3
- version = "0.0.4.dev89"
3
+ version = "0.0.4.dev90"
4
4
  description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -236,7 +236,7 @@ class Phenom:
236
236
  SideEffect(
237
237
  "fill",
238
238
  "hiring_system",
239
- "each step is submitted to Phenom on Next, which keeps a candidate profile from the"
239
+ "each step is submitted to Phenom on Next, which keeps an account profile from the"
240
240
  " first step",
241
241
  ),
242
242
  SideEffect("submit", "employer", "the application reaches the employer"),
@@ -703,7 +703,7 @@ def _fill(page: Page, field: Field, raw: dict[str, Any], answer: Answer) -> None
703
703
  case "file", _:
704
704
  files = [answer] if isinstance(answer, str) else answer
705
705
  delete = box.locator(DELETE_FILE)
706
- while (count := delete.count()) > 0: # the draft's or the profile's files
706
+ while (count := delete.count()) > 0: # the draft's or the account profile's files
707
707
  delete.first.click()
708
708
  deadline = time.monotonic() + UPLOAD_TIMEOUT_MS / 1000
709
709
  while delete.count() == count and time.monotonic() < deadline:
@@ -1,7 +1,7 @@
1
1
  """Welcome to the Jungle (`welcometothejungle.com` jobs and their `easyapply.jobs` links), as
2
2
  docs/adapters/wttj.md observes.
3
3
 
4
- Applying needs an account: the form opens in a modal, prefilled from the profile. Nothing is
4
+ Applying needs an account: the form opens in a modal, prefilled from the account profile. Nothing is
5
5
  sent before submit, so the read-back is the form's inputs and the CV's shown name.
6
6
  """
7
7
 
@@ -118,7 +118,7 @@ class WelcomeToTheJungle:
118
118
  while location.count() and not location.input_value() and time.monotonic() < deadline:
119
119
  page.wait_for_timeout(
120
120
  LOCATION_POLL_MS
121
- ) # the profile's location comes last, a second later
121
+ ) # the account profile's location comes last, a second later
122
122
  fields: dict[str, Field] = {}
123
123
  for raw in form.evaluate(_READ):
124
124
  if raw["id"] not in fields and (field := _field(raw)) is not None:
@@ -135,7 +135,7 @@ class WelcomeToTheJungle:
135
135
  box = target.locator("xpath=..")
136
136
  remove = box.locator("button[title=Remove]")
137
137
  if remove.count():
138
- remove.click() # the profile's CV; never made the default
138
+ remove.click() # the account profile's CV; never made the default
139
139
  target.set_input_files(answer)
140
140
  box.locator(f'[data-id="{answer.rsplit("/", 1)[-1]}"]').wait_for()
141
141
  case FieldType.CHOICE, str():
@@ -175,7 +175,7 @@ def _suggest(page: Page, field: Field, box: Locator, answer: str) -> None:
175
175
  options = page.locator("[role=option]:visible").filter(has_not=page.locator("svg"))
176
176
  for _ in range(SUGGEST_TRIES):
177
177
  box.click()
178
- box.press("Control+a") # `fill("")`, select-all and Delete, leaves the profile's value
178
+ box.press("Control+a") # `fill("")` (select-all, Delete) leaves the account profile's value
179
179
  box.press("Backspace")
180
180
  box.press_sequentially(answer, delay=KEY_DELAY_MS)
181
181
  deadline = time.monotonic() + SUGGEST_TIMEOUT_S
@@ -124,7 +124,7 @@ def _build_blocker() -> None:
124
124
  local = f"assets/{BLOCKER_LISTS}/{key}.txt"
125
125
  (build / local).parent.mkdir(exist_ok=True)
126
126
  (build / local).write_text(_filter_list([*urls, *entry.get("cdnURLs", [])]))
127
- entry.pop("off", None) # on from the start, the way a fresh profile reads it
127
+ entry.pop("off", None) # on from the start, the way a fresh browser profile reads it
128
128
  entry["contentURL"] = [local, *urls]
129
129
  entries["atsfill"] = {"content": "filters", "group": "custom", "title": "atsfill",
130
130
  "contentURL": [FILTERS]} # fmt: skip
@@ -34,7 +34,7 @@ class Field:
34
34
  options: list[str] | None = None
35
35
  max_length: int | None = None
36
36
  accept: list[str] | None = None
37
- prefilled: bool = False # holds a value before any answer, from the account's profile
37
+ prefilled: bool = False # holds a value before any answer, from the account profile
38
38
  unfillable: str | None = None # why atsfill cannot fill it, a reason (ADR 0014)
39
39
 
40
40
 
@@ -13,7 +13,7 @@
13
13
  # send_verified
14
14
  # unsupported
15
15
  # date, version, commit, by, reason: a round that ended without the adapter passing
16
- # the gate (ADR 0013), the known gap that stopped it
16
+ # the adapter gate (ADR 0013), the known gap that stopped it
17
17
  # out_of_scope
18
18
  # reason, date: a system atsfill will never fill, it needs the user live (ADR 0014)
19
19
  # send_broken
@@ -315,7 +315,7 @@ dry_run_verified = { date = 2026-10-22, version = "0.0.3", by = "adapter_gate",
315
315
  [isolvedhire]
316
316
  kind = "ats"
317
317
  share = 0.0047
318
- account = "to_read" # Apply now first verifies the email or phone with a one-time code, then creates an account on the employer's careers site; the application wizard (/apply/<job>-0.php) redirects to that site's login until then
318
+ account = "to_read" # Apply now first verifies the email or phone with an OTP, then creates an account on the employer's careers site; the application wizard (/apply/<job>-0.php) redirects to that site's login until then
319
319
  hosting = ["hosted"]
320
320
  mapped = { date = 2026-10-20, version = "0.0.2", by = "agent", commit = "7934b25" }
321
321
 
File without changes