Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ GIT
HARD LIMITS
- Under 100 applications total.
- Weekly cap, enforced in code (count sent rows (Applied, Accepted, Rejected) with a date in the current week; refuse to
run past the limit). sheet.py: MAX_PER_WEEK = 11 is the default, changeable in the GUI (Settings > Applications per week, local_config.json "max_per_week", 1-30; sheet.max_per_week()), MAX_TOTAL = 99 (decided 2026-10-03). A week =
run past the limit). sheet.py: MAX_PER_WEEK = 11 is the default, changeable in the GUI (Settings > Applying > Applications per week, local_config.json "max_per_week", 1-30; sheet.max_per_week()), MAX_TOTAL = 99 (decided 2026-10-03). A week =
fixed 7-day periods from local_config.json "week_start" (sheet.week_window); without it, the last
7 days. Mine: week_start 2026-10-06 (reset because I started applying late), then every 7 days.
Approved rows beyond the cap just wait for the next week.
Expand Down Expand Up @@ -79,7 +79,7 @@ SAFETY RULES (most important)
profile. The script selects only the exact "resume_label" saved in profile.json and
never uploads anything.
(Added 2026-10-12, my request.) The company-site agent may also upload my unofficial transcript (local_config.json
"transcript_path"; GUI Settings > Your files keeps it as local/transcript.pdf; the homelab gets a copy there), only where
"transcript_path"; GUI Settings > Applying > Your files keeps it as local/transcript.pdf; the homelab gets a copy there), only where
a page asks for one. (2026-10-20) The resume and the transcript given in the GUI are NUauto's own copies in local/,
pushed to the homelab at once (docs/GUI.md, YOUR FILES).
7. (Changed 2026-10-03; GUI added 2026-10-05.) `nuauto apply` submits every Approved row, one at a
Expand Down
76 changes: 44 additions & 32 deletions docs/GUI.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ WHAT IT IS
devices (your phone). Every screen is the same; the page knows where it runs (state.where) and shows what only the
laptop can do (state.laptop_only: logins, terminal windows, the laptop's files, Bitwarden, setup's file steps, Quit) as
"On your laptop" with the reason; the server refuses those there (the Bitwarden card is left out). What it adds there:
each assistant session's screen (#/assistant/<slot>), the queue in Apply (each row's chip, the Assistants tab), Settings > This homelab (paired
each assistant session's screen (#/assistant/<slot>), the queue in Apply (each row's chip, the Assistants tab), Settings > Homelab > This homelab (paired
devices). Without a homelab none of it exists, and the laptop's app is unchanged.
- Each thing in one place (2026-10-14), with or without a homelab: Today has one list of what only you can do (the
assistants waiting for you first, each item opening where you do it: no second Mark done or Open job there); Apply
Expand Down Expand Up @@ -163,36 +163,48 @@ SCREENS
that is another entry's wording, naming both
Ctrl+F (Cmd+F on a Mac) goes to the screen's own search box: Apply, Review, Answers ([data-find]); elsewhere, and in
a dialog, the browser's own find
Settings every health check (run them now), logins (Google, NUworks, Claude Code, and Gmail: the read-only login
for the assistant's email codes, with a link to turn the Gmail API on), resume label, applications per
week (the weekly cap), week start; Your files (the resume and the transcript: YOUR FILES);
the company-site assistant: account email, effort (low / medium / high), assistants at once (1-3, on each
machine; no homelab needed), the folders it may read, your writeups (assist_writeups: the first place it
looks for essays), its job-site logins (how many; Export for Bitwarden: the import file in ~/Downloads,
mode 600, and how to import it); Summer internships (optional; local_config "internships",
docs/PIPELINE.md): on / off, the term as the lists name it (a new year's term moves the lists' addresses
with it), the match % to enter the pool (empty: the co-ops' bar), each list's address (empty: not read);
Password manager (optional, for anyone; local_config "password_manager": "bitwarden"): Use Bitwarden / Stop
using it, Install it (npm @bitwarden/cli, then bw login, in a terminal window), Add N to Bitwarden (a terminal
window: bw unlock asks your master password itself, then `nuauto accounts export --bitwarden`), Your own logins
(words their addresses contain, "bitwarden_import") + Import my logins (a terminal: unlock, then `bw list items
--search <word> | nuauto accounts import - --only <word>` per word), Check now; Homelab (a source install,
never the packaged app; onboard.homelab_link): its ssh name and folder, Check (over ssh, read-only:
onboard.homelab_probe: its hostname, Tailscale address, NUauto / Claude / timers / lingering / the
assistant's tools there), Use this homelab (local_config's server fields; NUauto then needs a restart: the
card offers Quit), Set it up (a terminal window: `nuauto onboard homelab-setup`, docs/DEPLOY.md's steps,
each asked first; sudo asks for the homelab's password there), Log in to Claude there (ssh -t ... claude),
Stop using it (local mode again); with one in use, its code (From GitHub's main / From this computer
instead: deploy_from_git, a run of `nuauto onboard homelab-deploy on|off`: the code pushed once, the
deploy timer turned on or off; your fork's address, deploy_repo) and the Mark-done links' public address
(web_base_url; the homelab's web page restarts with it); in the same card, NUauto on your homelab (homelab mode only, docs/REMOTE.md): its page on /
off (remote_app), its assistant on / off (remote_assist, which needs the page: both pushed to the homelab,
nuauto-web restarted), Start sessions by itself, one switch for NUworks rows and one for Other jobs rows
(remote_auto {"nuworks", "other"}), its hours (remote_hours), assistants at once (assist_slots), Pair this
computer, Open it; setup, logs, quit. On the homelab's page one This homelab card: Paired devices (each
one, "this one", Unpair, Make a pairing link for another device) and its assistant's queue settings (no
on / off: the laptop's); the email and effort only (folders, export: on your laptop); Your files read-only; no
Password manager card (Bitwarden unlocks on the laptop), no Quit
Settings in tabs (#/settings/<tab>; plain #/settings: the last tab this session, else Status), the same on the
homelab's page (2026-10-22, my request: it was one long page). A health poll redraws only Status's list
of checks, never a form being typed in.
Status: every health check (run them now); logins (Google, NUworks, Claude Code, and Gmail: the read-only
login for the assistant's email codes, with a link to turn the Gmail API on).
Jobs: What you're looking for (Setup's preferences step, the same form and save: term, year, match bars,
kinds of work with their bonuses and lower bars, tags; saving rebuilds the pool); Summer internships
(optional; local_config "internships", docs/PIPELINE.md): on / off, the term as the lists name it (a new
year's term moves the lists' addresses with it), the match % to enter the pool (empty: the co-ops' bar),
each list's address (empty: not read).
Applying: applications per week (the weekly cap), week start, the resume NUauto picks (resume label), a
link to your sheet (another sheet: Setup); Your files (the resume and the transcript: YOUR FILES).
Assistant: the company-site assistant: email for job-site accounts, effort (low / medium / high),
assistants at once (1-3, on each computer; no homelab needed), the folders it may read, writeups
(assist_writeups: the first place it looks for essays), its job-site logins (how many; with Bitwarden off,
Export for Bitwarden: the import file in ~/Downloads, mode 600, and how to import it; with it on, the
Password manager card's Add is the way in). Password manager (optional, for anyone; local_config
"password_manager": "bitwarden"): Use Bitwarden / Stop using it, Install it (npm @bitwarden/cli, then bw
login, in a terminal window), Add N to Bitwarden (a terminal window: bw unlock asks your master password
itself, then `nuauto accounts export --bitwarden`), Your own logins (words their addresses contain,
"bitwarden_import") + Import my logins (a terminal: unlock, then `bw list items --search <word> | nuauto
accounts import - --only <word>` per word), Check now.
Homelab (a source install, never the packaged app; onboard.homelab_link): not in use: its ssh name and
folder, Check (over ssh, read-only: onboard.homelab_probe: its hostname, Tailscale address, NUauto /
Claude / timers / lingering / the assistant's tools there), Use this homelab (local_config's server
fields; NUauto then needs a restart: the card offers Quit). In use: Set it up (a terminal window:
`nuauto onboard homelab-setup`, docs/DEPLOY.md's steps, each asked first; sudo asks for the homelab's
password there), Log in to Claude there (ssh -t ... claude), Stop using it (local mode again); folded
away: another homelab's ssh name and folder, and Advanced: its code (From GitHub's main / From this
computer instead: deploy_from_git, a run of `nuauto onboard homelab-deploy on|off`: the code pushed once,
the deploy timer turned on or off; your fork's address, deploy_repo) and the Mark-done links' public
address (web_base_url; the homelab's web page restarts with it). Its own card, NUauto on your homelab
(homelab mode only, docs/REMOTE.md): its page on / off (remote_app), its assistant on / off
(remote_assist, which needs the page: both pushed to the homelab, nuauto-web restarted), Start sessions
by itself, one switch for NUworks rows and one for Other jobs rows (remote_auto {"nuworks", "other"}),
its hours (remote_hours), Pair this computer, Open it, This app (link.py).
App: Discord, automatic updates, app icon (Setup's extras step, the same body); Setup (open it, Run a
self-test, logs); About (version, folders, Quit).
On the homelab's page: Homelab is This homelab (Paired devices: each one, "this one", Unpair, Make a
pairing link for another device) and Its assistant (its queue settings; no on / off: the laptop's);
Assistant: the email, effort and assistants at once only (folders, export: on your laptop), no Password
manager card (Bitwarden unlocks on the laptop); Applying: Your files read-only; App: Discord only, no Quit
Setup the wizard (below); opens by itself until setup is done (never on the homelab's page: setup is the
laptop's; there it says so, and the steps it can do are preferences, Discord and the resume label)
Past runs logs/ folders: actions.log and the screenshots before and after Submit
Expand Down Expand Up @@ -445,7 +457,7 @@ API (JSON; all need the cookie; POSTs need X-NUauto: 1)
POST /api/quit

YOUR FILES (2026-10-20, my request: "a way to upload a resume and a transcript into the gui")
- The resume (Setup's resume step, or Settings > Your files) and the transcript (Settings > Your files; optional, Remove
- The resume (Setup's resume step, or Settings > Applying > Your files) and the transcript (Settings > Applying > Your files; optional, Remove
takes it out) are given to NUauto by dropping or choosing the PDF in the page. NUauto keeps its own copy,
local/resume.pdf / local/transcript.pdf (mode 600; onboard.save_document: a PDF, up to 10 MB, the resume with text
Claude can read), and points resume_path / transcript_path at it. So changing the PDF you had elsewhere changes
Expand Down
6 changes: 3 additions & 3 deletions docs/REMOTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ Off again: Turn off in the same place (the homelab's page stops; its copies stay

PAIR YOUR PHONE (once per device)
nuauto review pair phone (laptop or homelab; --discord also posts the link to your Discord)
or, from a device already paired: the homelab page's Settings > Paired devices > Make a pairing link.
or, from a device already paired: the homelab page's Settings > Homelab > Paired devices > Make a pairing link.
Open the link on the phone, Tailscale on, and press Pair (within 10 minutes; the link works once). Pair the browser
you will use: a link tapped in Discord opens in Discord's own browser, which keeps its own cookies (copy it into
Safari / Chrome instead). Each browser is paired once; then bookmark http://<web_listen_host>:8766/ there (or Add to
Home Screen). The laptop's browser: Settings > Homelab > Pair this computer.
nuauto review devices / nuauto review unpair <name>|--all (or Settings > Paired devices > Unpair)
nuauto review devices / nuauto review unpair <name>|--all (or Settings > Homelab > Paired devices > Unpair)

THE QUEUE (remote.py; nuauto-assist.timer every 10 minutes runs `nuauto assist auto`)
- On with "remote_auto" (and remote_assist), per sheet tab: true = both; {"nuworks": true, "other": false} = each on
Expand Down Expand Up @@ -235,7 +235,7 @@ THE LAPTOP'S LINK (link.py, 2026-10-15, my request: "as much support and smooth
- Settings > Homelab > This app: Link this app makes the laptop's NUauto one of the page's paired devices: a one-time
pairing code from the homelab over ssh (`nuauto review pair` there), used up at once by the laptop's server. Its key:
local/homelab_link.json (600), never shown, never synced; the device is named "NUauto on <this computer>" in the
page's Paired devices. Unlink forgets it here and unpairs it there; unpaired there (Settings > This homelab), the app
page's Paired devices. Unlink forgets it here and unpairs it there; unpaired there (Settings > Homelab > This homelab), the app
forgets it at its next request and shows "not linked" until you press Link again.
- The laptop's server makes every request itself, to the page's own address (Tailscale), as that device; the laptop's
page only ever talks to the laptop's server (/api/homelab/...). What the homelab's page refuses, it refuses here too,
Expand Down
2 changes: 1 addition & 1 deletion src/nuauto/assist.py
Original file line number Diff line number Diff line change
Expand Up @@ -2166,7 +2166,7 @@ def main(argv):
from nuauto import sheet
if config.IS_SERVER and not config.REMOTE_APP:
sys.exit("The NUworks side runs on the laptop (you at a terminal or the GUI); on the homelab only from "
"NUauto's page there (Settings > NUauto on your homelab, on the laptop).")
"NUauto's page there (Settings > Homelab > NUauto on your homelab, on the laptop).")
apply.refuse_unattended(ui) # a real NUworks submit: you at a terminal or the GUI, never an agent
if nuworks_session():
sys.exit(NUWORKS_BUSY)
Expand Down
Loading
Loading