agent-lookout 0.2.3 → 0.2.5

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 (38) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/PRIVACY.md +139 -19
  3. package/README.md +18 -8
  4. package/SECURITY.md +36 -8
  5. package/dist/THIRD-PARTY-LICENSES.md +195 -0
  6. package/dist/assets/HistoryPanel-TXa0oPH4.js +1 -0
  7. package/dist/assets/SessionPanel-BStoG7uq.js +1 -0
  8. package/dist/assets/index-BsTJp5-3.css +1 -0
  9. package/dist/assets/index-a7ubgAmE.js +3 -0
  10. package/dist/assets/radix-BH0JH8UU.js +41 -0
  11. package/dist/cli/agent-lookout.js +4 -4
  12. package/dist/cli/{chunk-4C34YX6S.js → chunk-NWVEVCRT.js} +14 -3
  13. package/dist/cli/{chunk-GOX5UB5L.js → chunk-OT3EGOTY.js} +120 -7
  14. package/dist/cli/{chunk-54ODUY75.js → chunk-Q73JDXXW.js} +1 -1
  15. package/dist/cli/mcpServer-IFB2FEOZ.js +23667 -0
  16. package/dist/cli/{startCommand-H6O35VYR.js → startCommand-J3QS26SZ.js} +4887 -1216
  17. package/dist/index.html +3 -3
  18. package/docs/API.md +266 -55
  19. package/docs/GUIDE.md +396 -61
  20. package/package.json +5 -5
  21. package/dist/assets/HistoryPanel-DMnhIoFB.js +0 -1
  22. package/dist/assets/SessionPanel-BNm9wCzf.js +0 -1
  23. package/dist/assets/atkinson-hyperlegible-mono-latin-400-normal-Cmjm2dBj.woff +0 -0
  24. package/dist/assets/atkinson-hyperlegible-mono-latin-500-normal-BV5ipwqM.woff +0 -0
  25. package/dist/assets/atkinson-hyperlegible-mono-latin-600-normal-CuPF9o0F.woff +0 -0
  26. package/dist/assets/atkinson-hyperlegible-mono-latin-ext-400-normal-ITMuFrSK.woff +0 -0
  27. package/dist/assets/atkinson-hyperlegible-mono-latin-ext-500-normal-BiHEOgiK.woff +0 -0
  28. package/dist/assets/atkinson-hyperlegible-mono-latin-ext-600-normal-ZiH-ObRk.woff +0 -0
  29. package/dist/assets/atkinson-hyperlegible-next-latin-400-normal-DPp7N0cD.woff +0 -0
  30. package/dist/assets/atkinson-hyperlegible-next-latin-500-normal-B0CYqHl3.woff +0 -0
  31. package/dist/assets/atkinson-hyperlegible-next-latin-600-normal-BhgCag5w.woff +0 -0
  32. package/dist/assets/atkinson-hyperlegible-next-latin-ext-400-normal-qxMiU51n.woff +0 -0
  33. package/dist/assets/atkinson-hyperlegible-next-latin-ext-500-normal-oZS3KxrF.woff +0 -0
  34. package/dist/assets/atkinson-hyperlegible-next-latin-ext-600-normal-BBAQIogt.woff +0 -0
  35. package/dist/assets/index-Ckda8OV4.js +0 -2
  36. package/dist/assets/index-DFR77qn5.css +0 -1
  37. package/dist/assets/radix-27o0jeIu.js +0 -41
  38. package/dist/cli/mcpServer-QQFQR6DC.js +0 -246
package/CHANGELOG.md CHANGED
@@ -2,6 +2,49 @@
2
2
 
3
3
  Changes that a user of Agent Lookout would notice, newest first.
4
4
 
5
+ ## 0.2.5 - 2026-10-07
6
+
7
+ Answer a Claude Code permission prompt from the dashboard, watch the sessions on another machine over SSH, copy the command that resumes a finished session, and set reminders, quiet hours and how long a session is idle before it counts as stale.
8
+
9
+ ### Added
10
+
11
+ - Answer a Claude Code permission prompt from the dashboard. Install the Agent Lookout plugin in Claude Code with `/plugin marketplace add Olanetsoft/agent-lookout` and `/plugin install agent-lookout@agent-lookout`, and a session waiting for permission shows Allow and Deny in Needs you and in its details. For a shell command it shows the whole command, every line, before Allow, and for any other tool its name and every input. Deny comes first and is always offered. Allow is not offered for an edit or a new file, a plan or a question, or a request too long to show whole, with more than two blank lines in a row, with characters that cannot be shown as they are, or, for a command, with right-to-left letters. Neither button takes a press in the first second a request is shown. Agent Lookout allows or denies that one request: it rewrites no command and saves no permission rule. The prompt in the session still works, and whichever is answered first wins. Without Agent Lookout running, the plugin does nothing and Claude Code asks as usual. The Events log records each answer. [Answer a permission prompt](docs/GUIDE.md#answer-a-permission-prompt) has the details.
12
+ - `AGENT_LOOKOUT_ANSWER=off` takes Allow and Deny away, and `AGENT_LOOKOUT_ANSWER_WAIT` sets how long a request waits for an answer from the dashboard, 300 seconds unless you set it.
13
+ - Watch the sessions on another machine you reach with ssh, such as a dev box or a cloud VM, beside this computer's. Start Agent Lookout there as usual, then start it here with `AGENT_LOOKOUT_REMOTES=devbox=dev@devbox.local`, naming more machines with commas, up to eight, and a port after a colon when it is not 4777. Agent Lookout runs your own `ssh`, which signs in with your config and agent and is never asked for a password, in a connection of its own that never joins one you have open and ends when Agent Lookout stops, forwards a port on each side's loopback, and every 2 seconds asks Agent Lookout there for `/api/health` and `/api/sessions`, and nothing else. Its sessions appear in the same lists with the machine's name beside each, and in the Timeline, the Events log, the waits, `agent-lookout status` and `agent-lookout mcp`, waiting ones in Needs you and its notifications, with no Jump, no Stop and no Allow or Deny. Sources has a card for each machine that says Connected, Connecting or Not connected, why and what to do, and What each agent can report a row for each agent there. While a machine is not connected, the header and the hero say so, so the Overview never looks all clear for sessions it cannot see. A dropped connection is started again on its own. A setting that cannot be read is shown in Sources as well as on the console. `AGENT_LOOKOUT_SSH_BIN` names another `ssh`. [Another machine over SSH](docs/GUIDE.md#another-machine-over-ssh) has the details.
14
+ - [Your own agents](docs/GUIDE.md#your-own-agents) has a short example in Python and one in Node.js, with nothing to install, for an agent of your own to copy. Each writes its status file as the work starts, when it waits for you and when it works again, deletes it when the program ends, also on Ctrl-C, `kill` or a closed terminal, and writes its `pid`, so its session goes when it is killed outright too.
15
+ - Resume a Claude Code session that has ended. A background job that finished, failed or was stopped has Resume where a Jump would be, in the Sessions list, on the board and in its details, and a session you stop with Stop has it in its details. Resume copies `cd '<folder>' && claude --resume <session ID>`, which goes to the session's folder and continues its conversation from any folder, in sh, bash or zsh. Agent Lookout runs nothing: it puts the command on the clipboard, shows it on hover and in full in the details, and leaves it on the page to select by hand if the clipboard is refused. A session whose process still runs, a Codex session, a session from a status file and one whose folder holds a backslash or a control character have no Resume. The Mac app's window may now write to the clipboard, and still never reads it. [Resume a session](docs/GUIDE.md#resume-a-session) has the details.
16
+ - Time rules, a card in Settings with three rules, each with its own Off and On, and all off until you turn them on. Agent Lookout keeps them in `~/.agent-lookout/settings.json`, or the file `AGENT_LOOKOUT_SETTINGS_FILE` names, so they hold with no dashboard open and after a restart. They cover the sessions of another machine read over SSH too, by the rules set on this computer. [Time rules](docs/GUIDE.md#time-rules) has the details.
17
+ - Remind me of a long wait tells you again once a session has waited the minutes you set, 10 unless you change them: once for each wait, by each of notifications, email and the webhook that is on for a wait, in words such as "checkout-flow has waited 10 minutes for permission".
18
+ - Mark idle sessions stale sets how long a session is idle before it counts as stale, from an hour to 30 days, 2 days unless you change it. The Stale count, the Timeline and Left running go by it, and so does ending the sessions left running. With it off, a session is stale after a day, as before.
19
+ - Quiet hours hold back every notification, email and webhook post between two times, such as 22:00 to 08:00, past midnight if the end comes first, on the days you tick. When they end, a session still waiting is notified as usual, and the rest comes as one summary on each channel, such as "While quiet: checkout-flow waited 25 minutes and billing-webhooks finished". The summary can leave out the waits that were answered. While they hold, the Time rules card says so, and in the Mac app the notice of a new version waits for them to end.
20
+ - `GET /api/settings` gives the time rules, and `POST /api/settings/time-rules`, which only the dashboard's own page can send, changes them. Each snapshot from `GET /api/sessions` carries the rules it was made by, as `timeRules`, and whether it was made in quiet hours, as `quiet`.
21
+
22
+ ### Changed
23
+
24
+ - Agent Lookout now answers a permission prompt, with the plugin installed, only when you press Allow or Deny, and never on its own. What each agent can report, in Sources, has an Answer column, and Settings has a Permission prompts card that says whether the plugin's requests arrive.
25
+
26
+ ### Fixed
27
+
28
+ - Waits counted a wait that ended with Stop as two waits, one on each side of the stop. It is one wait again, and so is one answered with Allow or Deny.
29
+ - On a phone, Sources split a command in the middle of a flag, `claude agents --json -` on one line and `-all` on the next. A command or a path on any view now breaks only between its words, and a path after a slash, and one too long to sit beside its label takes a line of its own under it.
30
+
31
+ ## 0.2.4 - 2026-10-06
32
+
33
+ Stop a Claude Code session from its details and end the ones left running, see the pull request and checks for a session's branch, and install a much smaller package with npx.
34
+
35
+ ### Added
36
+
37
+ - A session's pull request on github.com, and how its checks stand, can be shown. Start Agent Lookout with `AGENT_LOOKOUT_PULL_REQUESTS=on` and it asks your own GitHub CLI, `gh`, with the login `gh` already has, so Agent Lookout never sees a token. A session's details then have a Pull request fact: its number and title, as a link that opens it on github.com in your browser, and whether it is open, a draft, merged or closed, with how many checks are failing, pending and passing. In the Sessions list and on the board, a branch whose open pull request has a failing check has a small cross after it, which says which pull request on hover or Tab. It asks only about a branch of a repository whose remote is on github.com, read from the repository's own `config`, never about the default branch or a branch named with digits alone, such as `51`, which `gh` would take for a pull request's number, and at most once every 2 minutes for each repository and branch. With it on, `gh` sends GitHub the repository's owner and name and the branch's name. Without `gh`, or with `gh` not signed in, the Pull requests card in Settings says so and nothing else changes. `agent-lookout mcp` and `agent-lookout status --json` give a branch's pull request as its number and the state of its checks, and only with the setting on. It is off by default, and any value but `on` or `off` leaves it off with one line at start that names the setting. [Pull requests](docs/GUIDE.md#pull-requests) has the details.
38
+ - Stop a Claude Code session from its details. Stop asks first, naming the session, saying what it does and how to open the conversation again with `claude --resume`, with focus on Cancel. Once you confirm, Agent Lookout reads the session's file in `~/.claude/sessions` and asks `ps` again, and acts only when both say the process is that session: a session in a terminal or VS Code is sent SIGTERM, never SIGKILL, and one still running 10 seconds later is said to be, and a background job is stopped with `claude stop`. The Events log records each stop. A session in Claude Code's desktop app has no Stop, and its details say to stop it there. Codex sessions and sessions from status files have none either. [Stop a session](docs/GUIDE.md#stop-a-session) has the details.
39
+ - Left running, a band over the Sessions list and the board, counts the Claude Code sessions idle for a day or more whose process still runs, as after a VS Code tab is closed. Review… lists each with how long it has been idle. Hide until it changes hides one in this browser. End all… lists each one with a tick and ends those you keep ticked, up to 20 at a time, and a session that has done anything since the list was drawn is left running.
40
+ - `AGENT_LOOKOUT_STOP=off` takes Stop and the ending of sessions left running away.
41
+
42
+ ### Changed
43
+
44
+ - `npx agent-lookout` installs about 4 MB, down from about 30 MB, and downloads under 2 MB. The parts of the MCP SDK and zod that `agent-lookout mcp` uses are now inside the package, so neither is installed, nor are the web servers that came with the SDK, and `mcp` works as before. The one package it installs besides itself is nodemailer, for email.
45
+ - The dashboard's fonts are `.woff2` files only. Every browser the dashboard supports reads them, so the `.woff` copies, which none of them downloaded, are no longer in the package.
46
+ - Agent Lookout no longer only watches: it stops a session when you press Stop and confirm, and never on its own. It still never starts or answers one. What each agent can report, in Sources, has a Stop column.
47
+
5
48
  ## 0.2.3 - 2026-10-06
6
49
 
7
50
  The Mac app shows waiting sessions in the menu bar, the Overview says how long sessions waited on you today and over seven days, email and the webhook can carry what a waiting session is asking, new versions on npm come with provenance, and Node.js 22.12 is now the minimum.
@@ -14,6 +57,7 @@ The Mac app shows waiting sessions in the menu bar, the Overview says how long s
14
57
 
15
58
  ### Changed
16
59
 
60
+ - The dashboard leaves out an event of a kind it does not know, where it showed one as a change of status.
17
61
  - Agent Lookout needs Node.js 22.12 or newer. Node.js 20 reached the end of its life on 30 April 2026 and no longer gets security fixes, so it is no longer supported. On an older Node, `npx agent-lookout` and `agent-lookout` stop at once with one line that names the version needed and the version found, and exit with 1, or with 2 for `agent-lookout status`. The Mac app needs no Node.js.
18
62
  - The Overview has a Waits card that says how long sessions waited on you today and over the last 7 days, with a bar for each day and the five sessions that waited longest, today or over the 7 days, with how many times each waited. It is worked out on this computer from the history Agent Lookout keeps, counts only the time Agent Lookout was running, and says how much of each day and of the 7 days that was. With `AGENT_LOOKOUT_HISTORY=off` it covers only the time since Agent Lookout started, and says so. `GET /api/waits` gives the same totals to a program on this computer.
19
63
 
package/PRIVACY.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # Privacy
2
2
 
3
- Agent Lookout runs on your machine and reads a small amount of metadata about your Claude Code and Codex sessions, and about the sessions of any agent that writes a status file for Agent Lookout to read, and which git branch each session's folder has checked out. By default Agent Lookout itself sends nothing anywhere. Email notifications are off unless you set them up. Once you do, it sends a short email when a session has waited, and, if you choose, when one finishes, fails or ends, through the mail server you name, to the address you name, and nothing else. [Email](#email) says what one holds. Webhook posts are off unless you set an address for them. Once you do, it sends the same notices as short JSON posts to that one address, such as a Slack channel's incoming webhook, and nowhere else. [Webhook](#webhook) says what one holds. The Mac app, and only the Mac app, asks GitHub about once a day whether a newer version of it has been released, unless you turn that off in Settings. It sends nothing about your sessions: [Updates (Mac app only)](#updates-mac-app-only) says what it sends. The npm package, `npx agent-lookout` and the repository never check for anything. It does run Claude Code's own listing command, which may contact Anthropic the way Claude Code normally does. Its MCP server, `agent-lookout mcp`, runs only once you add it to an agent's app, and answers that app and nothing else. That app may pass what it learns to its model: [The MCP server](#the-mcp-server) says what an answer holds.
3
+ Agent Lookout runs on your machine and reads a small amount of metadata about your Claude Code and Codex sessions, and about the sessions of any agent that writes a status file for Agent Lookout to read, and which git branch each session's folder has checked out. By default Agent Lookout itself sends nothing anywhere. Email notifications are off unless you set them up. Once you do, it sends a short email when a session has waited, and, if you choose, when one finishes, fails or ends, through the mail server you name, to the address you name, and nothing else. [Email](#email) says what one holds. Webhook posts are off unless you set an address for them. Once you do, it sends the same notices as short JSON posts to that one address, such as a Slack channel's incoming webhook, and nowhere else. [Webhook](#webhook) says what one holds. The Mac app, and only the Mac app, asks GitHub about once a day whether a newer version of it has been released, unless you turn that off in Settings. It sends nothing about your sessions: [Updates (Mac app only)](#updates-mac-app-only) says what it sends. The npm package, `npx agent-lookout` and the repository never check for anything. Pull requests are off unless you start Agent Lookout with `AGENT_LOOKOUT_PULL_REQUESTS=on`. Then it runs your own GitHub CLI, `gh`, which sends GitHub the owner and name of a session's repository and the name of its branch, with `gh`'s own login, which Agent Lookout never reads: [`gh`](#gh) says what it sends and when. Other machines are read only once you name them in `AGENT_LOOKOUT_REMOTES`. Then it runs your own `ssh` to each and asks the Agent Lookout running there for its sessions, and sends nothing of this computer's: [Another machine over SSH](#another-machine-over-ssh) says what is read. It does run Claude Code's own listing command, which may contact Anthropic the way Claude Code normally does. Its MCP server, `agent-lookout mcp`, runs only once you add it to an agent's app, and answers that app and nothing else. That app may pass what it learns to its model: [The MCP server](#the-mcp-server) says what an answer holds.
4
4
 
5
5
  For a Claude Code session that is waiting for you, Agent Lookout reads the last message of its transcript, to show what the session is asking, such as the command it wants to run or the question it put to you. It reads nothing of a transcript while the session is not waiting, and keeps nothing of it once the wait ends. It sends that line off the machine only if you turn it on for email, with `AGENT_LOOKOUT_EMAIL_ASKING=on`, or for the webhook, with `AGENT_LOOKOUT_WEBHOOK_ASKING=on`, and then only in the email or post for that wait. No answer of `agent-lookout mcp` holds it. [Claude Code's transcripts](#claude-codes-transcripts) says exactly what is read, and `AGENT_LOOKOUT_WAITING_TEXT=off` turns it off.
6
6
 
7
7
  For Codex, Agent Lookout opens Codex's session files, which hold the whole conversation. It reads them to find when each turn started and ended, and keeps only that and the few fields listed below. It keeps no prompt, reply, command or output.
8
8
 
9
+ Agent Lookout stops a Claude Code session only when you press Stop in its details and confirm, or end the sessions left running after a confirmation that lists each one. It answers a Claude Code permission prompt only when you press Allow or Deny, and only with its Claude Code plugin installed. It never acts on a session on its own. [Stopping a session](#stopping-a-session) and [The Claude Code plugin and permission prompts](#the-claude-code-plugin-and-permission-prompts) say what it checks first and what it runs.
10
+
9
11
  ## What it reads and runs
10
12
 
11
13
  ### Claude Code's session registry
@@ -92,6 +94,22 @@ macOS asks you once whether the program Agent Lookout runs in may control the ap
92
94
 
93
95
  Agent Lookout asks the operating system whether each Claude Code session's process still exists with a signal-0 check on the process ID, which sends nothing to the process. It does the same for each status file that names a process.
94
96
 
97
+ ### Stopping a session
98
+
99
+ A Claude Code session in a terminal or in VS Code, and a Claude Code background job, has a Stop button in its details, when its registry file names its kind, `interactive` or `bg`, and records its process's start time. A session in Claude Code's desktop app has none, since that app looks after its own processes, and nor does a session whose kind or app is not known, a Codex session or a session from a status file. A background job has one only while Agent Lookout may run the `claude` command, as [`claude agents --json --all`](#claude-agents---json---all) says. The dashboard is told only that a session can be stopped, and whether by a signal or by `claude stop`: the process ID it already shows, the start time and the job's ID stay in the server, in memory.
100
+
101
+ Nothing is done until you press Stop and then Stop session. The page then sends the server the session's ID and nothing else, and the server makes every check again at that moment, remembering nothing from before:
102
+
103
+ - It reads the session's registry file, `~/.claude/sessions/<pid>.json`, again, as an ordinary file of 256 KB or less, following no link. It must still name that session and that process, be of the same kind, and record the same start time.
104
+ - It runs `ps -o pid=,lstart= -p <pid>` again, for that one process, and goes on only when `ps` gives the same start time the file recorded, to the second. When `ps` gives none, or one it cannot compare, nothing is done.
105
+ - It never stops the first process, its own process, the process it was started from or any process above that, such as the Claude Code session whose terminal started it. To find those, it runs `ps -A -o pid=,ppid=`, which prints the ID of every process and of its parent, and nothing else, follows its own process up through its parents, and drops the list. It stops no process of another user's.
106
+
107
+ Then, for a session in a terminal or in VS Code, it sends SIGTERM to that one process, by the system call, as `kill -TERM <pid>` would, and looks every 200 milliseconds, for up to 10 seconds, whether it has ended. If it is still running, the page says so. It never sends SIGKILL to a session, and it signals no other session. For a background job, it runs the `claude` binary it found for `claude agents`, as `claude stop <id>`, with the job's ID that `claude agents` gave it and nothing else, started directly, never through a shell, with stdin closed, a 10 second timeout and the same two variables as `claude agents`. If `claude stop` runs past its 10 seconds, Agent Lookout ends that command, and anything it started, with SIGTERM and then SIGKILL, as it does `claude agents` when that runs past its time: that command is Agent Lookout's own, not the session. It never signals a background job's process, which Claude Code's supervisor would start again. Once a job is stopped, it runs `claude agents --json --all` once more at the next poll, so the job shows as stopped.
108
+
109
+ The sessions left running are the Claude Code sessions that have been idle for 24 hours or more, or as long as the [idle rule](docs/GUIDE.md#time-rules) says while it is on, by their registry file's status time, whose process still runs and which can be stopped. The Sessions card says how many there are, and lists them when you press Review…. End all… lists each one again, up to 20 at a time, and ending them sends the server each session's ID and the moment its idle began, as the page showed it. The server makes every check above for each one, and also checks that its registry file, and its own latest list of sessions, still say it is idle, since that same moment, and that this was 24 hours or more ago, or as long ago as the idle rule says. A session that has done anything since is left running.
110
+
111
+ Stopping keeps the conversation: it touches no transcript and no file under `~/.claude`, and a registry file left behind is not deleted. The Events log keeps one event for each session stopped, with its ID, its name, the status it had and that Agent Lookout stopped it, as [The history](#the-history) says. With `AGENT_LOOKOUT_STOP=off`, nothing is offered Stop, and the server answers no request to stop a session.
112
+
95
113
  ### Codex's files
96
114
 
97
115
  Agent Lookout reads Codex's folder: the one `AGENT_LOOKOUT_CODEX_HOME` names, otherwise the one Codex's own `CODEX_HOME` names, otherwise `~/.codex`. It runs no Codex program, changes no Codex setting and installs no hook. None of these files is documented by Codex. [docs/adapters/codex.md](docs/adapters/codex.md) records where each one comes from.
@@ -135,7 +153,32 @@ It reads only ordinary files of 4 KB or less, and on macOS and Linux it does not
135
153
 
136
154
  With the branch it keeps which repository the folder belongs to, so the dashboard can group the worktrees of one repository together. A repository is known by its own git folder, which all its worktrees share: a `.git` folder is its own, a worktree's `commondir` names it, and any other `.git` file, such as a submodule's, names it in its one line. Agent Lookout reads nothing more for this. It keeps two things about the repository: its name, cleaned and cut as a branch is, and an id to tell repositories apart, the first 16 characters of the SHA-256 hash of the git folder's path. The name is that of the folder that holds `.git`, such as `storefront`, and for a worktree the one its repository's git folder gives: `storefront` for `storefront/.git`, `storefront/.bare` or `storefront.git`. Both are in the session list the API serves on this computer, beside the branch, and nowhere else: no email, post, notification or answer of `agent-lookout mcp` holds them. The path itself is not sent. The id is never shown, and holds no part of the path, though someone who guessed a path could check the guess against it.
137
155
 
138
- It reads nothing else in a repository: no other branch or reference, no `packed-refs`, no configuration, no index, no logs, no objects, and none of the files you work on.
156
+ It reads nothing else in a repository: no other branch or reference, no `packed-refs`, no configuration, no index, no logs, no objects, and none of the files you work on. The one exception is with `AGENT_LOOKOUT_PULL_REQUESTS=on`, when it also reads the repository's `config` and its remote's `HEAD`, as [`gh`](#gh) describes.
157
+
158
+ ### `gh`
159
+
160
+ Only with `AGENT_LOOKOUT_PULL_REQUESTS=on`, Agent Lookout shows each session's pull request on github.com and its checks. It asks your own GitHub CLI, `gh`, for them. With the setting left out or `off`, which is the default, it reads none of the files below, never looks for `gh` and never runs it. Any other value leaves it off too, and Agent Lookout prints one line at start that names the setting.
161
+
162
+ To know where to look, it reads two more files in the git folder of each repository a session is in, the one [Git repositories](#git-repositories) finds, and writes nothing:
163
+
164
+ - `config`, of at most 64 KB, an ordinary file it does not follow as a link. From it, it keeps each remote's name and first `url`, the `gh-resolved` line that `gh repo set-default` writes, each branch's `remote` and `pushRemote`, and `remote.pushDefault`, and drops the rest of the file. Of a remote's address it keeps only the owner and the name of a repository on github.com, never the address itself, and never a user name, password or token written in it. It does not read your global git configuration.
165
+ - `refs/remotes/<remote>/HEAD`, of at most 4 KB, which names the remote's default branch.
166
+
167
+ It asks only about a branch of a repository whose remote is on github.com, and never about the default branch, the one that `HEAD` names, or `main` or `master` when it was never written. A remote on any other host, such as a GitHub Enterprise server, is never asked about. Nor is a branch whose name is only digits, with or without a `#` before them, such as `51` or `#51`, since `gh` would read it as the number of a pull request rather than as a branch.
168
+
169
+ For each repository and branch your sessions are on, it runs, at most once every 2 minutes and never on every poll:
170
+
171
+ ```sh
172
+ gh pr view --repo github.com/<owner>/<repository> --json number,title,state,isDraft,statusCheckRollup -- <branch>
173
+ ```
174
+
175
+ where `<branch>` is the branch's name, or `<owner>:<branch>` for a branch pushed to a fork. `gh` is found on `PATH`, then at `/opt/homebrew/bin/gh`, `/usr/local/bin/gh`, `/opt/local/bin/gh` and `/usr/bin/gh`, and is started directly, by that full path, never through a shell, with stdin closed and a 15 second timeout, one question at a time. It is given the environment Agent Lookout was started with, less Agent Lookout's own settings, so it signs in with its own login, as it does in your terminal, with `GH_PROMPT_DISABLED`, `GH_NO_UPDATE_NOTIFIER`, `GH_NO_EXTENSION_UPDATE_NOTIFIER`, `GH_SPINNER_DISABLED` and `NO_COLOR` set, and `GH_FORCE_TTY`, `GH_DEBUG`, `DEBUG`, `GH_PAGER` and `PAGER` taken out. Agent Lookout never reads, keeps or passes on a token, and never reads `gh`'s own configuration or login.
176
+
177
+ `gh` then asks GitHub's API, over HTTPS, for that one pull request. What goes to GitHub is the repository's owner and name and the branch's name, with your login, as when you run the command yourself. Nothing about your sessions, their names, folders or what they are asking goes. What GitHub keeps of the request is governed by GitHub's terms, and what `gh` does besides by its own settings.
178
+
179
+ From the answer it keeps the pull request's number, its title, whether it is open, a draft, merged or closed, and how many of its checks are failing, pending and passing. It keeps no check's name, link or log, no body, comment, author or review. The title is cleaned of control characters and of the characters that change the direction of text, and cut to 200 characters. The link to the pull request is made from the repository and the number, not taken from GitHub's answer. All of it is kept in memory only, for as long as a session is on that branch, and is never written to disk, to the history or to the Events log. When `gh` is not there, is not signed in, or does not answer, nothing of what it printed is kept or shown: Settings says which, in words of Agent Lookout's own.
180
+
181
+ The pull request is in the session list the API serves on this computer, and so on the dashboard, and in answers of `agent-lookout mcp` and `agent-lookout status --json` as its number and how its checks stand, never its title, as [The MCP server](#the-mcp-server) says. No email, webhook post or notification holds it.
139
182
 
140
183
  ### `osascript`
141
184
 
@@ -147,9 +190,33 @@ With notifications on, and no dashboard page open to show one, Agent Lookout sho
147
190
 
148
191
  Only when you start it with `agent-lookout --open`, Agent Lookout runs `/usr/bin/open` on macOS, or `xdg-open` on Linux, once, to open its own address in your default browser. It gives it one argument, the address it listens on, such as `http://127.0.0.1:4777`, and nothing else. The program is started directly, never through a shell, with nothing connected to its input or output. Agent Lookout waits up to 10 seconds for it to end, to tell whether it worked, and never stops it: `xdg-open` can keep running until the browser it started is closed. Without `--open`, neither is ever run.
149
192
 
193
+ ### The Claude Code plugin and permission prompts
194
+
195
+ Agent Lookout can answer a Claude Code permission prompt only once you install its plugin in Claude Code, which you do yourself, in Claude Code, with `/plugin marketplace add Olanetsoft/agent-lookout` and `/plugin install agent-lookout@agent-lookout`. Claude Code records that in its own settings. Agent Lookout writes nothing under `~/.claude`, and `/plugin uninstall agent-lookout@agent-lookout` takes the plugin away again.
196
+
197
+ The plugin is one hook, a short `sh` script, which Claude Code runs as it is about to ask you for permission, while it shows its own prompt. The script checks for Agent Lookout's socket, `~/.agent-lookout/answer.sock`, or the one `AGENT_LOOKOUT_ANSWER_SOCKET` names, and with none there it exits at once and prints nothing. Otherwise it runs `curl` once, which sends the request over that socket, on this computer and nowhere else, and prints the answer, if there is one. What Claude Code hands the hook, and so what the request holds, is the session's ID, the path of its transcript, its working folder, its scratchpad folder, the ID of the prompt being answered, its permission mode, the tool's name, the tool's input, which is the whole command for a shell command and the whole file for a new file, and the permission rules Claude Code suggests. Agent Lookout reads it as it arrives, keeps the session's ID, the tool's name, what it shows of the input, and whether a subagent asks, and lets the rest go at once. It takes no request larger than 1 MiB. A request is held only once the registry file of a session Agent Lookout lists says it waits for permission, which it must say within 3 seconds, so a request for any other session is let go then, answering nothing, and is never shown.
198
+
199
+ Agent Lookout listens on that socket while it runs, unless you start it with `AGENT_LOOKOUT_ANSWER=off`, or with `AGENT_LOOKOUT_CLAUDE_HOME` set and `AGENT_LOOKOUT_ANSWER_SOCKET` not. It makes the folder with mode 700 if it is not there, and gives its own folder, `~/.agent-lookout`, mode 700 if others could open it. A folder that `AGENT_LOOKOUT_ANSWER_SOCKET` names, which it did not make, it never changes: if others can open it, answering is off, and Settings says why. It gives the socket mode 600, so only your user can connect. A browser cannot reach a socket. It removes the socket when it stops, and one left by a copy that crashed is replaced. A second copy that finds the first answering there leaves it be, and its Settings say so.
200
+
201
+ While the session waits, Agent Lookout holds the request. It reads the session's registry file, `~/.claude/sessions/<pid>.json`, again every half second, as an ordinary file it opens without following a link, and lets the request go, answering nothing, as soon as the file no longer says the session is waiting for permission, or says it is waiting again in a later wait, which is what happens when you answer in the session. It also lets it go when the hook's connection closes, when a newer request of the same session arrives, and after `AGENT_LOOKOUT_ANSWER_WAIT` seconds, 300 unless you set it. The prompt in the session then decides, as it would without the plugin. What it shows of the request, the whole command or the tool and its inputs, is held in memory while the request is held. It goes to the dashboard in the session list, and nowhere else: it is never written to disk and never put in an event, the history, a notification, an email, a webhook post, `agent-lookout status` or an answer of `agent-lookout mcp`.
202
+
203
+ It answers only when you press Allow or Deny on the dashboard. The page sends the session's ID, Agent Lookout's own ID for the request, and the answer. Agent Lookout reads the registry file once more, and answers only if it still says the session is waiting for permission, in the same wait the request was shown in. The answer is one of two fixed texts, allow, or deny with a fixed sentence that says you denied it from Agent Lookout. It never changes the command or the tool's input, and never saves a permission rule, so each Allow allows that one request. Allow is offered only when the whole of what it allows is shown, and not for an edit or a new file, a plan or a question, a request too long to show whole or with more than two blank lines in a row, one with characters that cannot be shown as they are, or a command with right-to-left letters. The Events log keeps one event for each answer, with the session's ID and name, and whether it was allowed or denied, and nothing of what was asked.
204
+
205
+ Settings says whether a request has reached Agent Lookout. To tell, it notes when a Claude Code session waiting for permission sent no request within 5 seconds, which is what a session without the plugin does, and keeps that time and the time of the last request, in memory only.
206
+
207
+ ### Another machine over SSH
208
+
209
+ Only when `AGENT_LOOKOUT_REMOTES` names other machines, Agent Lookout reads the sessions of the Agent Lookout running on each, through an SSH tunnel it opens with your own `ssh`. Unset, it never looks for `ssh`.
210
+
211
+ For each machine it runs `ssh -N -o BatchMode=yes -o ExitOnForwardFailure=yes -o ServerAliveInterval=15 -o ControlMaster=no -o ControlPath=none -L 127.0.0.1:<a free port>:127.0.0.1:<its port> -- <target>`, with the target you named, such as `dev@devbox.local`, after `--`, and with the port Agent Lookout listens on there, 4777 unless you give another. `ssh` is the one on your `PATH`, or in `/usr/bin`, `/opt/homebrew/bin` or `/usr/local/bin`, or the one `AGENT_LOOKOUT_SSH_BIN` names. It is started directly, by its full path, never through a shell, with nothing on its input, and given the environment Agent Lookout was started with, so it uses your `~/.ssh/config` and your ssh agent as it does in a terminal. With BatchMode it asks nothing, so Agent Lookout never sees, types or keeps a password, a passphrase or a key, and never answers a question about a host key. ssh runs no command on the other machine: it forwards one port on this computer's `127.0.0.1` to Agent Lookout's port on that machine's own `127.0.0.1`. With `ControlMaster=no` and `ControlPath=none` it makes a connection of its own every time, even when your ssh config shares connections, so it never joins an ssh you have open and never leaves one running in the background: the forward ends when that ssh ends. Agent Lookout keeps the last lines ssh writes about a failure, in memory, and shows the last of them on the machine's card in Sources, such as `Permission denied (publickey).` When ssh ends, it is started again after a wait, and when Agent Lookout stops, it ends it.
212
+
213
+ Through that port, every 2 seconds, it sends two requests and no others: `GET /api/health`, whose answer is the version of Agent Lookout there, and `GET /api/sessions`, whose answer is that machine's sessions and sources, as [docs/API.md](docs/API.md#get-apisessions) describes. The requests carry nothing of this computer's: no session, no setting, and not the `X-Agent-Lookout-Notifications` header, so they change nothing that machine's Agent Lookout believes about its own pages. Of the answer it keeps, in memory, what this computer shows of its own sessions: each session's name, folder, status, reason, the vendor's wording of a wait, its times, its app, its branch and repository name, its agent's name and whether its process still runs. It drops each session's process ID, Jump, Stop and links, and any permission request that machine holds for it, with what the request would run, as the answer is read, so nothing about a session there can act on this computer. It keeps each source there by its name and its state, and what each of its agents can report. It does not take that machine's time rules, or its word on whether it is in quiet hours: this computer's own decide when a session there is stale, and when a wait there is reminded of or held back here.
214
+
215
+ That includes what a waiting session there is asking, such as `Run: npm test`, when that machine's Agent Lookout sends it, which it does unless `AGENT_LOOKOUT_WAITING_TEXT=off` is set there. With `AGENT_LOOKOUT_WAITING_TEXT=off` set on this computer, it is dropped as it arrives, and a waiting session there shows its reason alone, as one here does. Otherwise it is shown here as a waiting session's is, and in the notifications on this computer, and is kept no longer than the wait, as here. Like a session's on this computer, a session there and its events go into the history kept on this computer, without what it is asking, and into an email or a webhook post as the settings for those say.
216
+
150
217
  ### Settings
151
218
 
152
- It reads twenty-four settings from the environment: `AGENT_LOOKOUT_CLAUDE_HOME`, `AGENT_LOOKOUT_CLAUDE_BIN`, `AGENT_LOOKOUT_CLAUDE_FEED`, `AGENT_LOOKOUT_WAITING_TEXT`, `AGENT_LOOKOUT_CODEX_HOME`, `AGENT_LOOKOUT_STATUS_DIR`, `AGENT_LOOKOUT_HISTORY`, `AGENT_LOOKOUT_HISTORY_DIR`, `AGENT_LOOKOUT_NOTIFICATIONS`, `AGENT_LOOKOUT_TMUX`, `AGENT_LOOKOUT_TERMINAL_JUMP`, `AGENT_LOOKOUT_PORT`, `AGENT_LOOKOUT_HOST`, Codex's own `CODEX_HOME`, the six email settings, `AGENT_LOOKOUT_EMAIL_TO`, `AGENT_LOOKOUT_SMTP_URL`, `AGENT_LOOKOUT_EMAIL_FROM`, `AGENT_LOOKOUT_EMAIL_AFTER`, `AGENT_LOOKOUT_EMAIL_EVENTS` and `AGENT_LOOKOUT_EMAIL_ASKING`, and the four webhook settings, `AGENT_LOOKOUT_WEBHOOK_URL`, `AGENT_LOOKOUT_WEBHOOK_EVENTS`, `AGENT_LOOKOUT_WEBHOOK_AFTER` and `AGENT_LOOKOUT_WEBHOOK_ASKING`. The `agent-lookout` command reads one more, `AGENT_LOOKOUT_URL`, the address of the Agent Lookout to ask, and `agent-lookout status` reads tmux's own `TMUX`, only to tell whether tmux is running it. `AGENT_LOOKOUT_CLAUDE_HOME` replaces `~/.claude` in everything above. [Email](#email) says how the email settings are kept, and [Webhook](#webhook) how the webhook's are. The [guide](docs/GUIDE.md#settings-you-can-change) says what each setting does.
219
+ It reads thirty-two settings from the environment: `AGENT_LOOKOUT_CLAUDE_HOME`, `AGENT_LOOKOUT_CLAUDE_BIN`, `AGENT_LOOKOUT_CLAUDE_FEED`, `AGENT_LOOKOUT_WAITING_TEXT`, `AGENT_LOOKOUT_CODEX_HOME`, `AGENT_LOOKOUT_STATUS_DIR`, `AGENT_LOOKOUT_HISTORY`, `AGENT_LOOKOUT_HISTORY_DIR`, `AGENT_LOOKOUT_SETTINGS_FILE`, `AGENT_LOOKOUT_NOTIFICATIONS`, `AGENT_LOOKOUT_TMUX`, `AGENT_LOOKOUT_TERMINAL_JUMP`, `AGENT_LOOKOUT_STOP`, `AGENT_LOOKOUT_PULL_REQUESTS`, `AGENT_LOOKOUT_ANSWER`, `AGENT_LOOKOUT_ANSWER_SOCKET`, `AGENT_LOOKOUT_ANSWER_WAIT`, `AGENT_LOOKOUT_PORT`, `AGENT_LOOKOUT_HOST`, `AGENT_LOOKOUT_REMOTES`, `AGENT_LOOKOUT_SSH_BIN`, Codex's own `CODEX_HOME`, the six email settings, `AGENT_LOOKOUT_EMAIL_TO`, `AGENT_LOOKOUT_SMTP_URL`, `AGENT_LOOKOUT_EMAIL_FROM`, `AGENT_LOOKOUT_EMAIL_AFTER`, `AGENT_LOOKOUT_EMAIL_EVENTS` and `AGENT_LOOKOUT_EMAIL_ASKING`, and the four webhook settings, `AGENT_LOOKOUT_WEBHOOK_URL`, `AGENT_LOOKOUT_WEBHOOK_EVENTS`, `AGENT_LOOKOUT_WEBHOOK_AFTER` and `AGENT_LOOKOUT_WEBHOOK_ASKING`. The `agent-lookout` command reads one more, `AGENT_LOOKOUT_URL`, the address of the Agent Lookout to ask, and `agent-lookout status` reads tmux's own `TMUX`, only to tell whether tmux is running it. `AGENT_LOOKOUT_CLAUDE_HOME` replaces `~/.claude` in everything above. [Email](#email) says how the email settings are kept, and [Webhook](#webhook) how the webhook's are. The time rules are not in the environment: Agent Lookout keeps them in a file of its own, as [The settings file](#the-settings-file) says. The [guide](docs/GUIDE.md#settings-you-can-change) says what each setting does.
153
220
 
154
221
  ## What it never reads
155
222
 
@@ -157,14 +224,16 @@ It reads twenty-four settings from the environment: `AGENT_LOOKOUT_CLAUDE_HOME`,
157
224
  - Claude Code's transcripts, in `~/.claude/projects/` or anywhere else, beyond the end of a waiting session's own, as [Claude Code's transcripts](#claude-codes-transcripts) describes. Of what it reads there, it keeps one line about the tool the session is asking to use, and none of your prompts, the agent's replies, your code or the output of tools.
158
225
  - Claude Code's settings, credentials, history and memory files.
159
226
  - Codex's `auth.json`, `config.toml`, `history.jsonl`, its SQLite files (`*.sqlite`), its `log/` folder, `archived_sessions/` and compressed session files (`*.jsonl.zst`), and the Codex desktop app's `external_agent_session_imports.json` and `.codex-global-state.json`.
160
- - In a git repository, anything but the `.git` file, `HEAD` and a worktree's `commondir` described under [Git repositories](#git-repositories).
227
+ - In a git repository, anything but the `.git` file, `HEAD` and a worktree's `commondir` described under [Git repositories](#git-repositories), and with `AGENT_LOOKOUT_PULL_REQUESTS=on`, the `config` and the remote's `HEAD` described under [`gh`](#gh).
228
+ - `gh`'s configuration, its login and any token, and your global git configuration.
229
+ - Your `~/.ssh` folder: keys, `known_hosts` and ssh config. For the machines `AGENT_LOOKOUT_REMOTES` names, `ssh` reads them itself, as it does in a terminal.
161
230
  - The files of any other application.
162
231
 
163
- It runs no program but the `claude` binary, `ps`, `tmux`, on macOS `osascript`, to show a notification and to bring a tab of Terminal or iTerm2 forward, and, only for `--open`, `open` or `xdg-open`. The Mac app also runs `ditto` and `plutil` to unpack and check a newer version of itself, and, only when you press Install and Restart, a short `sh` script that puts it in place, as [Updates (Mac app only)](#updates-mac-app-only) describes. It runs no git command. It never writes to `~/.claude`, to the Codex folder, to the folder of status files, to any git repository or to any agent tool's files, and it never sends input to a session. It never makes, renames or deletes a status file. The one thing it changes outside itself is which tmux pane, window and session are selected, or which tab of Terminal or iTerm2 is in front, and only when you press Jump.
232
+ It runs no program but the `claude` binary, for `claude agents` and, only when you stop a background job, `claude stop`, `ps`, `tmux`, on macOS `osascript`, to show a notification and to bring a tab of Terminal or iTerm2 forward, only for `--open`, `open` or `xdg-open`, only with `AGENT_LOOKOUT_PULL_REQUESTS=on`, `gh`, and, only for the machines `AGENT_LOOKOUT_REMOTES` names, `ssh`, as [Another machine over SSH](#another-machine-over-ssh) describes. The Mac app also runs `ditto` and `plutil` to unpack and check a newer version of itself, and, only when you press Install and Restart, a short `sh` script that puts it in place, as [Updates (Mac app only)](#updates-mac-app-only) describes. It runs no git command. The plugin's hook, which Claude Code runs and not Agent Lookout, runs `curl`. It never writes to `~/.claude`, to the Codex folder, to the folder of status files, to any git repository or to any agent tool's files, and it never sends input to a session. It never makes, renames or deletes a status file. It changes three things outside itself, and each only when you ask: which tmux pane, window and session are selected, or which tab of Terminal or iTerm2 is in front, when you press Jump, when you press Stop and confirm, whether a Claude Code session's process runs, as [Stopping a session](#stopping-a-session) describes, and, when you press Allow or Deny, the answer to that one permission prompt, as [The Claude Code plugin and permission prompts](#the-claude-code-plugin-and-permission-prompts) describes. It never sends a session anything else.
164
233
 
165
234
  ## Network
166
235
 
167
- With email and the webhook off, which is the default, the only network traffic Agent Lookout's own code makes is between its own server and the dashboard in your browser, or the `agent-lookout status` and `agent-lookout mcp` commands, on the same machine. With email set up, it also connects to the mail server you named, once for each email, as [Email](#email) describes. With a webhook address set, it also connects to that address, once for each post, as [Webhook](#webhook) describes. One more connection never leaves the machine either: before `npm start` or `agent-lookout` begins listening, it connects once to its own address and port to see whether another program already answers there, and sends nothing over that connection. There is no telemetry, no analytics, no crash reporting and no account. There is no update check either, except in the Mac app, which asks GitHub about once a day whether a newer version of it is out, as [Updates (Mac app only)](#updates-mac-app-only) describes. Fonts and scripts are bundled, so the page loads nothing from the internet.
236
+ With email, the webhook and other machines off, which is the default, the only network traffic Agent Lookout's own code makes is between its own server and the dashboard in your browser, or the `agent-lookout status` and `agent-lookout mcp` commands, on the same machine. With email set up, it also connects to the mail server you named, once for each email, as [Email](#email) describes. With a webhook address set, it also connects to that address, once for each post, as [Webhook](#webhook) describes. With `AGENT_LOOKOUT_PULL_REQUESTS=on`, it runs `gh`, which connects to GitHub, at most once every 2 minutes for each repository and branch your sessions are on, as [`gh`](#gh) describes. With other machines named in `AGENT_LOOKOUT_REMOTES`, your own `ssh` connects to each, and Agent Lookout sends its two requests to Agent Lookout there through that connection, as [Another machine over SSH](#another-machine-over-ssh) describes. Agent Lookout itself connects only to the end of the tunnel on this computer's `127.0.0.1`. One more connection never leaves the machine either: before `npm start` or `agent-lookout` begins listening, it connects once to its own address and port to see whether another program already answers there, and sends nothing over that connection. There is no telemetry, no analytics, no crash reporting and no account. There is no update check either, except in the Mac app, which asks GitHub about once a day whether a newer version of it is out, as [Updates (Mac app only)](#updates-mac-app-only) describes. Fonts and scripts are bundled, so the page loads nothing from the internet.
168
237
 
169
238
  Started with `npx agent-lookout`, npm itself contacts its registry: to download the package the first time, and each time after to ask whether a newer version is out, as it does for any package it runs. That is npm's own traffic, not Agent Lookout's. Installed with `npm install -g agent-lookout` and started as `agent-lookout`, npm is not involved.
170
239
 
@@ -174,11 +243,11 @@ The `claude agents` command is Claude Code's own program, and it may contact Ant
174
243
 
175
244
  The API refuses any request whose `Host` header is not `localhost`, `127.0.0.1` or `[::1]`, any request whose `Origin` header names another site, and any request the browser marks as cross-site. It sends no CORS headers. Together these stop a website you visit from reading your session names and paths through your browser.
176
245
 
177
- Each request the dashboard makes carries one header of Agent Lookout's own, `X-Agent-Lookout-Notifications`, which says which events that page has notifications on for: `off`, `on`, which means a session starting to wait, or `on; events=` followed by the names of the events, such as `on; events=needs-you,finished`. It holds nothing else. It goes to Agent Lookout's own server and nowhere else. [Notifications](#notifications) says what the server does with it. The request the Jump button sends for a session in tmux, Terminal or iTerm2 carries one more, `X-Agent-Lookout-Action: jump`, which names what is asked for, and the request the Clear history button in Settings sends carries `X-Agent-Lookout-Action: clear-history`, with an empty body.
246
+ Each request the dashboard makes carries one header of Agent Lookout's own, `X-Agent-Lookout-Notifications`, which says which events that page has notifications on for: `off`, `on`, which means a session starting to wait, or `on; events=` followed by the names of the events, such as `on; events=needs-you,finished`. It holds nothing else. It goes to Agent Lookout's own server and nowhere else. [Notifications](#notifications) says what the server does with it. The request the Jump button sends for a session in tmux, Terminal or iTerm2 carries one more, `X-Agent-Lookout-Action: jump`, which names what is asked for, and the request the Clear history button in Settings sends carries `X-Agent-Lookout-Action: clear-history`, with an empty body. The request Stop session sends carries `X-Agent-Lookout-Action: stop` and the session's ID, and the one that ends the sessions left running carries `X-Agent-Lookout-Action: clean-up`, with each session's ID and the moment its idle began. The one Allow and Deny send carries `X-Agent-Lookout-Action: answer`, with the session's ID, Agent Lookout's own ID for the request and the answer.
178
247
 
179
- The local server has no password. While Agent Lookout is running, another program on the same machine can request the same data, and on a shared computer so can another user account. Such a program can also send that header, and so turn the notifications the server shows on or off. It can also ask the server to select a tmux pane, or bring a tab of Terminal or iTerm2 forward, as the Jump button does, and to clear the history, as the Clear history button does.
248
+ The local server has no password. While Agent Lookout is running, another program on the same machine can request the same data, and on a shared computer so can another user account. Such a program can also send that header, and so turn the notifications the server shows on or off. It can also ask the server to select a tmux pane, or bring a tab of Terminal or iTerm2 forward, as the Jump button does, to clear the history, as the Clear history button does, to stop a Claude Code session, or end the sessions left running, as Stop and End all… do, with every check of [Stopping a session](#stopping-a-session), and to answer a permission prompt Agent Lookout is holding, as Allow and Deny do. A program that can do that can already type into your terminal, but on a shared computer another account could not. The Mac app opens no port, so there only its own window can do any of this. `AGENT_LOOKOUT_STOP=off` takes stopping away, and `AGENT_LOOKOUT_ANSWER=off` takes answering away.
180
249
 
181
- For a session in VS Code, the Jump button opens a `vscode://` address that contains the session ID. Your operating system hands it to VS Code. For a session in tmux, the Jump button sends a request that holds the session's ID to Agent Lookout's own server, which selects the pane as described under [`tmux`](#tmux). For a session in Terminal or iTerm2 it sends the same request, and the server brings the tab forward as described under [Terminal and iTerm2](#terminal-and-iterm2). That request and the one Clear history sends are the only ones that change anything, and the server answers them only for a page served from this machine. [SECURITY.md](SECURITY.md) lists its checks.
250
+ For a session in VS Code, the Jump button opens a `vscode://` address that contains the session ID. Your operating system hands it to VS Code. For a session in tmux, the Jump button sends a request that holds the session's ID to Agent Lookout's own server, which selects the pane as described under [`tmux`](#tmux). For a session in Terminal or iTerm2 it sends the same request, and the server brings the tab forward as described under [Terminal and iTerm2](#terminal-and-iterm2). That request, the one Clear history sends, the ones Stop session and End send and the one Allow and Deny send are the only ones that change anything, and the server answers them only for a page served from this machine. [SECURITY.md](SECURITY.md) lists its checks.
182
251
 
183
252
  ## Notifications
184
253
 
@@ -192,9 +261,9 @@ A notification is made in one of two ways. While a dashboard page is open, the p
192
261
 
193
262
  With notifications on, when one of the events switched on happens, the dashboard page makes a notification through the browser's Notifications API, and the browser hands it to the operating system to show. It holds:
194
263
 
195
- - the session's name, as its title
264
+ - the session's name, as its title, followed by "on" and the machine's name for a session on another machine
196
265
  - what happened, as its text: for a session that starts waiting, the reason, "Waiting for permission", "Asked you a question" or "Waiting for you", followed, for a Claude Code session, by what it is asking when its transcript says, as in "Waiting for permission: Run: npm test", and otherwise "Finished", "Failed" or "Ended"
197
- - a tag that is not shown, which the browser uses to keep one notification for each session: `agent-lookout:claude-code:` followed by the session's ID, or by its job ID or process ID when it has no session ID, for Codex `agent-lookout:codex:` followed by the session's ID, and for a status file `agent-lookout:status-files:` followed by the file's name
266
+ - a tag that is not shown, which the browser uses to keep one notification for each session: `agent-lookout:claude-code:` followed by the session's ID, or by its job ID or process ID when it has no session ID, for Codex `agent-lookout:codex:` followed by the session's ID, for a status file `agent-lookout:status-files:` followed by the file's name, and for a session on another machine `agent-lookout:remote:` followed by the machine's name and the session's own tag there
198
267
 
199
268
  It holds none of Claude Code's own wording for the wait, and not the session's folder. What a session is asking can hold a command, which can name any path, a web address, or a file: relative to the session's folder when the file is inside it, and the file's full path when it is outside it, which can name your home folder. No push service, no service worker and no network request is involved. The page that is open in your browser makes the notification, and can do so only while it is open.
200
269
 
@@ -208,11 +277,15 @@ The browser gives its permission to the address, such as `localhost:5173`, not t
208
277
 
209
278
  The local server shows notifications on this machine too. When one of the events switched on happens and no dashboard page is open to show it, the server runs `osascript`, as [described above](#osascript), and macOS shows the notification. It holds:
210
279
 
211
- - the session's name, as its title
280
+ - the session's name, as its title, with the machine's name for a session on another machine
212
281
  - what happened, as its text, in the same wordings, with what a waiting session is asking
213
282
 
214
283
  It holds none of Claude Code's own wording and no tag. As in the page's, what a session is asking can hold a command, a web address, or a file's full path when the file is outside the session's folder. No network request is involved. On any system but macOS the server shows nothing.
215
284
 
285
+ ### Reminders and summaries
286
+
287
+ With the [time rules](docs/GUIDE.md#time-rules) on, the page and the server make two more kinds of notification, in the same two ways and by the same switches. A reminder of a long wait has the session's name as its title, with the machine's name for a session on another machine, and as its text how long it has waited and for what, with what it is asking after it, as in "Has waited 10 minutes for permission: Run: npm test". On the page it takes the place of the wait's own, with its tag. The summary made when quiet hours end has "While quiet" as its title, and as its text the names of the sessions that waited, finished, failed or ended while they held, each with the machine's name for a session on another machine, with how long each waited, as in "checkout-flow waited 25 minutes and billing-webhooks finished". It holds nothing a session was asking. The page's has the tag `agent-lookout:while-quiet`, and stays until you clear it. During quiet hours neither the page nor the server makes any notification.
288
+
216
289
  The server shows them only while notifications are on, and only for the events switched on, and it learns both from the dashboard. Each request a dashboard page makes says, in the `X-Agent-Lookout-Notifications` header, which events are on when that page's choice is on and the browser allows notifications, and `off` otherwise. The server keeps the last thing a page said, in memory, for as long as it runs, and never writes it to disk. Before any page has said anything it is off, unless `AGENT_LOOKOUT_NOTIFICATIONS=on` was set when Agent Lookout started, which turns it on for a session starting to wait. A page that says `off` after that turns it off all the same. The header is listened to only on a request that passes the checks described under [Network](#network), so a page at another address cannot set it.
217
290
 
218
291
  While a page that has notifications on is open and asking every 2 seconds, the page shows each notification and the server does not. The server holds its own back for a few seconds when such a page has just been asking, and drops it once that page has fetched the sessions.
@@ -238,6 +311,8 @@ An email is plain text. Its subject is the session's name followed by the reason
238
311
  - the agent, such as Claude Code or Codex, or the agent a status file names
239
312
  - one line saying Agent Lookout sent it and how to stop these emails
240
313
 
314
+ With the [time rules](docs/GUIDE.md#time-rules) on, two more kinds of email can be sent. A reminder of a long wait is the email of a wait with a subject that says how long it has waited, such as "checkout-flow has waited 10 minutes for permission", and a line on how often reminders come. The summary sent when quiet hours end has the subject "While quiet:" followed by the first few sessions' names and what happened, and in its body, one line for each session that waited, finished, failed or ended while they held, with how long it waited and from when, or when it finished, failed or ended, at most 50, and a line on where quiet hours are set. A summary holds the sessions' names alone, nothing of what they were asking and no folder.
315
+
241
316
  It holds no folder path, no prompt, none of Claude Code's own wording for the wait, no link, no image, nothing that reports back when it is opened and, unless you set `AGENT_LOOKOUT_EMAIL_ASKING=on` (below), nothing of what a waiting session is asking. Its headers are the ones the mail library writes for every email: From, with the name Agent Lookout and the sender's address, To, Subject, Date, Message-ID, and three that say it is plain text in UTF-8. A session's name and its folder's name are cut to 80 characters, and anything in them that would end a line becomes a space, so nothing in a name can add a header or a recipient.
242
317
 
243
318
  #### What a waiting session is asking, in an email
@@ -304,6 +379,43 @@ It holds:
304
379
  - `at`: when it happened, as a time in UTC: when the wait began, or when Agent Lookout saw the session finish, fail or end.
305
380
  - `waitedSeconds`, for a wait only: how long it had waited when it was posted.
306
381
 
382
+ With the [time rules](docs/GUIDE.md#time-rules) on, two more kinds of post can be sent. A reminder of a long wait is the post of a wait, with the line saying how long it has waited, such as "checkout-flow has waited 10 minutes for permission", and one more field, `"reminder": true`. The summary sent when quiet hours end looks like this:
383
+
384
+ ```json
385
+ {
386
+ "text": "While quiet: checkout-flow waited 25 minutes and billing-webhooks finished",
387
+ "event": "quiet-summary",
388
+ "from": "2026-10-05T21:00:00.000Z",
389
+ "to": "2026-10-06T07:00:00.000Z",
390
+ "items": [
391
+ {
392
+ "event": "needs-you",
393
+ "session": {
394
+ "name": "checkout-flow",
395
+ "agent": "Claude Code",
396
+ "folder": "storefront",
397
+ "app": "VS Code"
398
+ },
399
+ "at": "2026-10-05T22:10:00.000Z",
400
+ "waitedSeconds": 1500,
401
+ "times": 1
402
+ },
403
+ {
404
+ "event": "finished",
405
+ "session": {
406
+ "name": "billing-webhooks",
407
+ "agent": "Claude Code",
408
+ "folder": "billing",
409
+ "app": "Terminal"
410
+ },
411
+ "at": "2026-10-06T00:12:00.000Z"
412
+ }
413
+ ]
414
+ }
415
+ ```
416
+
417
+ `from` and `to` are when Agent Lookout saw the quiet hours begin and end, and `items` holds each session that waited, finished, failed or ended while they held, at most 100, with `more` saying how many were left out. A session that waited and then finished, failed or ended is one item, whose `then` says what it did and when, as `{"event": "ended", "at": "..."}`. Each item's `session` holds what a post's always does, and no item holds anything a session was asking.
418
+
307
419
  It holds no folder path, no prompt, none of Claude Code's own wording for the wait, no session ID or process ID, nothing about this computer and, unless you set `AGENT_LOOKOUT_WEBHOOK_ASKING=on` (below), nothing of what a waiting session is asking. Its headers are `Content-Type: application/json`, `Content-Length`, `User-Agent: Agent Lookout/` followed by the version, `Host` and `Connection: close`. It carries no cookie and no other header.
308
420
 
309
421
  A session's name, its folder's name and its agent's are each cut to 80 characters, and anything in them that would end a line becomes a space. In `text`, `<`, `>` and `&` are written as `&lt;`, `&gt;` and `&amp;`, which Slack shows as the characters themselves, and each `@` is followed by a space of no width, so nothing in a name can mention someone, ping a channel or make a link that shows other words than its address. The JSON is written whole by Node's own writer, so nothing in a name can add a field. Slack does show a web address written out in a name as a link to that address.
@@ -379,7 +491,7 @@ For each tool the agent calls, it asks Agent Lookout's own server for the list o
379
491
 
380
492
  It answers the app that started it, over stdout, and nothing and nobody else. An answer is one of three:
381
493
 
382
- - For each session: its ID, its name, its agent, its status, why it waits, the name of its folder and never the rest of the path, its branch or commit, its app, when its status began, and how long its agent has written nothing. Never what a waiting session is asking, which is read from its transcript.
494
+ - For each session: its ID, its name, its agent, the other machine it runs on, when it runs on one read over SSH, its status, why it waits, the name of its folder and never the rest of the path, its branch or commit, its app, when its status began, and how long its agent has written nothing. With `AGENT_LOOKOUT_PULL_REQUESTS=on`, also the number of its branch's pull request and whether its checks are failing, pending or passing, and never its title. Never what a waiting session is asking, which is read from its transcript.
383
495
  - For each session that needs you: the same, with how long it has waited, and one sentence naming each of them and any agent that could not be read.
384
496
  - For each source: its state, the sentence that says how it is read or what went wrong, which can name the folders Agent Lookout reads, such as `~/.claude/sessions`, and what its agent can report.
385
497
 
@@ -387,7 +499,7 @@ When Agent Lookout cannot be reached, the answer is one sentence that says so, w
387
499
 
388
500
  ### What happens to an answer
389
501
 
390
- What the app does with an answer is up to the app. An agent's app normally hands each answer to its model, and for most agents the model runs on the vendor's servers, so the names of your sessions, their folders and their branches can leave this computer that way, under that app's own settings and terms. Add the server only to an app you would show your session names to, and remove it from the app to stop it: for Claude Code, `claude mcp remove agent-lookout`.
502
+ What the app does with an answer is up to the app. An agent's app normally hands each answer to its model, and for most agents the model runs on the vendor's servers, so the names of your sessions, their folders and their branches, and with `AGENT_LOOKOUT_PULL_REQUESTS=on` the numbers of their pull requests and whether their checks pass, can leave this computer that way, under that app's own settings and terms. Add the server only to an app you would show your session names to, and remove it from the app to stop it: for Claude Code, `claude mcp remove agent-lookout`.
391
503
 
392
504
  ### What is kept
393
505
 
@@ -395,9 +507,9 @@ Nothing. Each answer is worked out from one reading of the list and is gone once
395
507
 
396
508
  ## Storage
397
509
 
398
- Agent Lookout keeps one thing about your sessions on disk: the history behind the Events log and the charts, so that they are still there after it restarts. [The history](#the-history) says what it holds, where it is, how long it is kept, how to clear it and how to turn it off. Apart from that, its own code writes no files, except the Mac app's, below.
510
+ Agent Lookout keeps one thing about your sessions on disk: the history behind the Events log and the charts, so that they are still there after it restarts. [The history](#the-history) says what it holds, where it is, how long it is kept, how to clear it and how to turn it off. It also keeps its time rules in a file, which holds nothing about your sessions: [The settings file](#the-settings-file). Apart from those, its own code writes no files, except the Mac app's, below.
399
511
 
400
- The latest session list is held in memory only, and is gone when Agent Lookout stops. What a waiting session is asking is in that list only while it waits, and in no event or point of history, on disk or in memory. With `AGENT_LOOKOUT_EMAIL_ASKING=on` or `AGENT_LOOKOUT_WEBHOOK_ASKING=on`, it is also in the email or post for that wait from the moment it is written until it is handed over, and nowhere else. So are the tmux panes and terminal tabs it last found, the branches and repositories it last read, and what the dashboard pages last said about notifications.
512
+ The latest session list is held in memory only, and is gone when Agent Lookout stops. What a waiting session is asking is in that list only while it waits, and in no event or point of history, on disk or in memory. So is a permission request held for the dashboard, which is also kept in memory only while it is held. With `AGENT_LOOKOUT_EMAIL_ASKING=on` or `AGENT_LOOKOUT_WEBHOOK_ASKING=on`, it is also in the email or post for that wait from the moment it is written until it is handed over, and nowhere else. So are the tmux panes and terminal tabs it last found, the branches and repositories it last read, with pull requests on the pull requests `gh` last gave and where each branch's is looked for, and what the dashboard pages last said about notifications.
401
513
 
402
514
  ### The history
403
515
 
@@ -405,7 +517,7 @@ The history is kept in the folder `~/.agent-lookout/history`, beside the folder
405
517
 
406
518
  It writes there what it already holds in memory for the Events log and the charts, and nothing else:
407
519
 
408
- - Each event: its ID, its time, the session's ID and name, whether the session appeared, changed status or ended, the status it changed from and to, and how serious the change was. A session's ID is its agent's own ID for it, or the name of its status file.
520
+ - Each event: its ID, its time, the session's ID and name, whether the session appeared, changed status, ended, was stopped from Agent Lookout or had a permission prompt answered from it, the status it changed from and to, how serious the change was, for a session that was stopped, that Agent Lookout stopped it, and for a prompt that was answered, that Agent Lookout answered it and whether it allowed or denied it. A session's ID is its agent's own ID for it, or the name of its status file.
409
521
  - Each history point, one for each poll: its time, and how many sessions were waiting on you, working, idle, and in all.
410
522
  - When Agent Lookout started writing, and when the history was cleared.
411
523
 
@@ -419,6 +531,12 @@ To clear the history, press Clear history on the History card in Settings and co
419
531
 
420
532
  To keep nothing on disk, start Agent Lookout with `AGENT_LOOKOUT_HISTORY=off`. It then makes no folder and writes no file, and the last 1,000 events, the last six hours of history and what the Waits card counts are held in memory only and are gone when it stops.
421
533
 
534
+ ### The settings file
535
+
536
+ Agent Lookout keeps the [time rules](docs/GUIDE.md#time-rules) you set in Settings in `~/.agent-lookout/settings.json`, beside the history, or in the file `AGENT_LOOKOUT_SETTINGS_FILE` names, so they hold with no dashboard open and after a restart. It holds the three rules and nothing else of Agent Lookout's: whether each is on, the minutes before a reminder, the hours before a session is stale, and the times and days of quiet hours with the switch for the summary. It holds nothing about a session.
537
+
538
+ Agent Lookout reads it once, as it starts, and writes it only when you change a rule in Settings, through `POST /api/settings/time-rules`, which only the dashboard's own page can send. It writes the file whole: to a new file of mode 600, so only your user can read or change it, in the same folder, which then takes the old one's place, and makes the folder with mode 700 when it is not there. It neither reads nor writes through a link, at the file's name or the folder's, and reads no file larger than 64 KB. Anything else the file holds, such as a later version's settings, is written back as it was. A file it found but could not read as it started, such as one larger than 64 KB or one it may not read, it never writes over: a change is not saved until the file is mended or removed and Agent Lookout started again. Until you change a rule, nothing is written and no folder is made. To go back to every rule off, delete the file while Agent Lookout is stopped.
539
+
422
540
  With notifications on, each notification holds a session's name, and for a wait what the session is asking, and the operating system keeps it in its notification list, as does the browser for one it made. [Notifications](#notifications) says what it holds and how long it stays. With email set up, each email holds a session's name and its folder's name, and with `AGENT_LOOKOUT_EMAIL_ASKING=on` the email for a wait holds what the session was asking, and the mail server and the mailbox keep it, as [Email](#email) says. With a webhook set up, each post holds the same, with `AGENT_LOOKOUT_WEBHOOK_ASKING=on` for what a session was asking, and the service it went to keeps it, as [Webhook](#webhook) says.
423
541
 
424
542
  The tools that run it write files of their own. None of these holds session data.
@@ -431,11 +549,13 @@ The tools that run it write files of their own. None of these holds session data
431
549
 
432
550
  The Mac app keeps the history in the same folder as `npx agent-lookout` and `npm start`, and four files of its own. `window-state.json`, in `~/Library/Application Support/Agent Lookout/`, holds the window's place and size and the colour of the theme it last showed. `update-state.json`, beside it, holds whether it checks for updates by itself, when it last checked, the last version it told you of and, during an install, the version being installed, as [Updates (Mac app only)](#updates-mac-app-only) says, and a newer version it downloads waits in the system's temporary folder until it is installed or the app quits. `menu-bar-state.json`, beside it, holds whether its icon is shown in the menu bar. Its log, `~/Library/Logs/Agent Lookout/main.log`, holds the errors it met and the lines `npm start` would print, such as the one that says an email setting is wrong. None of them holds a session's name, though an error in the log can name a file the app could not read. Electron, which the app is built on, keeps the page's local storage, below, and caches of its own in the first folder.
433
551
 
434
- The dashboard saves six values in your browser's local storage. Your theme choice is under the key `agent-lookout-theme`. Whether notifications are on is under the key `agent-lookout-notifications`, as `on` or `off`, and is written only when you turn them on or off. The events that send one are under the key `agent-lookout-notification-events`, as their names separated by commas, such as `needs-you,finished`, and are written only when you switch one. The apps the page has said macOS will ask about, when you first jumped to a tab of one, are under the key `agent-lookout-automation-note`, as `Terminal`, `iTerm2` or both separated by a comma. The last time the Events log was on screen is under the key `agent-lookout-last-looked`, as a number of milliseconds since 1970, and is written when the page goes out of sight or is closed. It is what the line in the Events log that marks where you left off is drawn from, and while that line still shows, the time kept is the line's own. It holds nothing about any session or event. Whether the Sessions card shows the list, the list grouped by repository or the board is under the key `agent-lookout-sessions-layout`, as `list`, `repositories` or `board`, and is written only when you choose one. All six belong to one browser at one address.
552
+ The dashboard saves seven values in your browser's local storage. Your theme choice is under the key `agent-lookout-theme`. Whether notifications are on is under the key `agent-lookout-notifications`, as `on` or `off`, and is written only when you turn them on or off. The events that send one are under the key `agent-lookout-notification-events`, as their names separated by commas, such as `needs-you,finished`, and are written only when you switch one. The apps the page has said macOS will ask about, when you first jumped to a tab of one, are under the key `agent-lookout-automation-note`, as `Terminal`, `iTerm2` or both separated by a comma. The last time the Events log was on screen is under the key `agent-lookout-last-looked`, as a number of milliseconds since 1970, and is written when the page goes out of sight or is closed. It is what the line in the Events log that marks where you left off is drawn from, and while that line still shows, the time kept is the line's own. It holds nothing about any session or event. Whether the Sessions card shows the list, the list grouped by repository or the board is under the key `agent-lookout-sessions-layout`, as `list`, `repositories` or `board`, and is written only when you choose one. The sessions left running that you hid until they change are under the key `agent-lookout-hidden-sessions`, as a list of each one's ID and the moment its idle began, at most 100, and are written only when you hide one. All seven belong to one browser at one address.
435
553
 
436
554
  ## What is on screen
437
555
 
438
- Session names, folder paths, repository names, branch names and what a waiting session is asking, such as a command or a file, can show what you are working on. Check a screenshot before you share it.
556
+ Session names, folder paths, repository names, branch names, pull request titles and what a waiting session is asking, such as a command or a file, can show what you are working on. Check a screenshot before you share it.
557
+
558
+ Resume puts a session's folder path and its ID on the clipboard, and only when you press it. From there, anything that reads your clipboard can see them, such as a clipboard manager, and on a Mac with Handoff on, Universal Clipboard makes them available on your other Apple devices. The page never reads the clipboard.
439
559
 
440
560
  With notifications on, a session's name, and what a waiting session is asking, also appear in a system notification, outside the dashboard: over other apps, in Notification Centre and, depending on your system's settings, on the lock screen and while you mirror, share or record the screen. One the dashboard page made for a wait stays there until the session stops waiting or you clear it, and one that says Finished, Failed or Ended stays until you clear it. One the server showed stays until you clear it. To keep names off those, open Notifications in System Settings on macOS and change what your browser's notifications may show, which does not cover the ones the server shows, or leave notifications off. In the Mac app, the number of sessions that need you is shown in the menu bar, beside its icon, and the menu it opens lists their names and what each is asking, with the agent, project, branch or app of two that share a name. Both show while you share or record the screen. To keep them off the menu bar, set Show in menu bar to Off in Settings. An email shows the same name, and the folder's, wherever that mailbox is read, including the notifications a phone shows for it, and so does what a waiting session is asking, with `AGENT_LOOKOUT_EMAIL_ASKING=on`. A webhook post shows them to everyone who can read the channel it goes to, and in the notifications their apps show for it, and with `AGENT_LOOKOUT_WEBHOOK_ASKING=on` shows what a waiting session is asking there too.
441
561
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Agent Lookout shows the AI agent sessions on your Mac or Linux computer in one browser page, and which need you.
4
4
 
5
- It finds Claude Code and Codex sessions with no setup, and the sessions of any other agent that writes a small status file. It only watches: it never starts, stops or answers a session. By default Agent Lookout itself sends nothing anywhere. Start it with `npx agent-lookout`, or download the [Mac app](#mac-app).
5
+ It finds Claude Code and Codex sessions with no setup, and the sessions of any other agent that writes a small status file. It never starts a session. It stops one only when you press Stop and confirm, and answers a Claude Code permission prompt only when you press Allow or Deny, with its Claude Code plugin installed: it never acts on its own. By default Agent Lookout itself sends nothing anywhere. Start it with `npx agent-lookout`, or download the [Mac app](#mac-app).
6
6
 
7
7
  [Install](#install) · [Guide](docs/GUIDE.md) · [Privacy](#privacy) · [Roadmap](https://github.com/Olanetsoft/agent-lookout/milestones) · [Website](https://agent-lookout.vercel.app)
8
8
 
@@ -18,7 +18,12 @@ It finds Claude Code and Codex sessions with no setup, and the sessions of any o
18
18
  | [Needs you](docs/GUIDE.md#needs-you) | Lists the sessions waiting for permission or for an answer, longest wait first, each with a timer. For Claude Code it also says what the session is asking, such as `Run: npm test`. |
19
19
  | [Sessions](docs/GUIDE.md#sessions) | Lists the other sessions by status, by repository or on a board, each with its folder and git branch. Click one to see its details. |
20
20
  | [Jump](docs/GUIDE.md#jump) | Takes you to a Claude Code session. It opens it in VS Code, selects its tmux pane, or on a Mac brings its Terminal or iTerm2 tab to the front. |
21
+ | [Stop](docs/GUIDE.md#stop-a-session) | Ends a Claude Code session's process when you press Stop in its details and confirm. The conversation is kept. Sessions left running, idle for a day or more, can be ended together after a confirmation. |
22
+ | [Resume](docs/GUIDE.md#resume-a-session) | Copies the command that continues a Claude Code session that has ended, `cd` to its folder and `claude --resume` with its ID, for you to run in a terminal. It runs nothing itself. |
23
+ | [Allow and Deny](docs/GUIDE.md#answer-a-permission-prompt) | Answers a Claude Code permission prompt from the dashboard, with the Agent Lookout plugin installed in Claude Code. It shows the whole command first, and the prompt in the session still works. |
21
24
  | [Notifications](docs/GUIDE.md#notifications) | Tell you when a session starts waiting and, if you choose, when one finishes, fails or ends. Off until you turn them on. On a Mac they keep coming after you close the tab, once a page with them on has been open. |
25
+ | [Time rules](docs/GUIDE.md#time-rules) | Remind you of a long wait, set how long a session is idle before it is stale, and hold everything back during quiet hours, with one summary when they end. Off until you turn them on. |
26
+ | [Pull requests](docs/GUIDE.md#pull-requests) | Shows a session's pull request on github.com and its checks, through your own `gh`, and marks a branch whose checks are failing. Off until you turn it on. |
22
27
  | [Email](docs/GUIDE.md#email) and [webhook](docs/GUIDE.md#webhook) | Send the same events to one email address, or to one webhook such as a Slack channel's, for when you are away. Off until you set them up. |
23
28
  | [`agent-lookout status`](docs/GUIDE.md#in-the-terminal) | Prints which sessions need you, for a terminal, a tmux status line or a script. |
24
29
  | [`agent-lookout mcp`](docs/GUIDE.md#for-your-agents) | Lets an AI agent ask which sessions need you. Its tools only read. |
@@ -73,7 +78,7 @@ Kept in Applications, it updates itself: about once a day it asks GitHub whether
73
78
  npx agent-lookout
74
79
  ```
75
80
 
76
- The first time, npm names the package and asks `Ok to proceed? (y)`. Press Enter. npm downloads about 30 MB and keeps it in its cache. Then Agent Lookout prints:
81
+ The first time, npm names the package and asks `Ok to proceed? (y)`. Press Enter. npm downloads under 2 MB and keeps it in its cache. Then Agent Lookout prints:
77
82
 
78
83
  ```text
79
84
  Agent Lookout is running at http://127.0.0.1:4777
@@ -162,7 +167,7 @@ It asks `http://127.0.0.1:4777`, then `http://localhost:5173`. If Agent Lookout
162
167
 
163
168
  ## For your agents
164
169
 
165
- `agent-lookout mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server. It lets an AI agent ask which sessions are running and which need you, so one agent can keep track of the others. Its three tools, `list_sessions`, `sessions_needing_you` and `sources`, only read. It asks the Agent Lookout that is running, and starts nothing.
170
+ `agent-lookout mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server. It lets an AI agent ask which sessions are running and which need you, so one agent can keep track of the others. Its three tools, `list_sessions`, `sessions_needing_you` and `sources`, only read: none of them can stop a session. It asks the Agent Lookout that is running, and starts nothing.
166
171
 
167
172
  To add it to Claude Code for all your folders, run this once:
168
173
 
@@ -188,8 +193,10 @@ AGENT_LOOKOUT_CLAUDE_FEED=off npx agent-lookout
188
193
  | `AGENT_LOOKOUT_URL` | The address `agent-lookout status` and `agent-lookout mcp` ask, such as `http://127.0.0.1:4778`. Set it where those commands run, not where Agent Lookout starts. |
189
194
  | `AGENT_LOOKOUT_NOTIFICATIONS=on` | On a Mac, shows notifications of waits from the moment it starts, with no dashboard tab open. |
190
195
  | `AGENT_LOOKOUT_CLAUDE_FEED=off` | Never runs the `claude` command. Sessions come from Claude Code's session files alone. |
191
- | `AGENT_LOOKOUT_WAITING_TEXT=off` | Never opens a Claude Code transcript. A waiting session shows its reason alone. |
196
+ | `AGENT_LOOKOUT_WAITING_TEXT=off` | Never opens a Claude Code transcript. A waiting session shows its reason alone, here and on another machine read over SSH. |
192
197
  | `AGENT_LOOKOUT_HISTORY=off` | Keeps the Events log and the charts in memory only, so they start empty each time. Nothing is written to `~/.agent-lookout/history`. |
198
+ | `AGENT_LOOKOUT_STOP=off` | Takes away Stop and the ending of sessions left running. No session is ever stopped from Agent Lookout. |
199
+ | `AGENT_LOOKOUT_ANSWER=off` | Takes away Allow and Deny. No socket is opened for the plugin, and no permission prompt is answered from Agent Lookout. |
193
200
 
194
201
  [The guide](docs/GUIDE.md#settings-you-can-change) lists every setting, those for [email](docs/GUIDE.md#email) and the [webhook](docs/GUIDE.md#webhook) among them. The theme and the page's notifications are in the dashboard's Settings view.
195
202
 
@@ -197,20 +204,23 @@ AGENT_LOOKOUT_CLAUDE_FEED=off npx agent-lookout
197
204
 
198
205
  By default Agent Lookout itself sends nothing anywhere: no telemetry, no analytics, no crash reports and no account. The one exception is the Mac app, which asks GitHub about once a day whether a newer version of it is out and sends nothing about your sessions: Settings turns that off, [Updates (Mac app only)](PRIVACY.md#updates-mac-app-only) says what it sends, and `npx agent-lookout` and the repository never check. Its fonts and scripts are bundled, so the page loads nothing from the internet. It keeps the Events log and the counts behind the charts on this computer, in `~/.agent-lookout/history`, so they are still there after a restart: for 8 days and up to 20 MB, with each session's name and status changes and no folder path, prompt or anything a waiting session is asking. Clear history in Settings deletes them, and `AGENT_LOOKOUT_HISTORY=off` keeps them in memory only. [PRIVACY.md](PRIVACY.md) lists everything it reads, runs, keeps and can send.
199
206
 
207
+ - Pull requests are off until you start Agent Lookout with `AGENT_LOOKOUT_PULL_REQUESTS=on`. Then it runs your own GitHub CLI, `gh`, which sends GitHub the owner and name of a session's repository and the name of its branch, with `gh`'s own login, so Agent Lookout never sees a token. It asks at most once every 2 minutes for each repository and branch, only for a remote on github.com and never about the default branch. [`gh`](PRIVACY.md#gh) says what it reads and keeps.
200
208
  - Email and the webhook are off until you set them up. Then each goes only to the one address you name, and email goes through the mail server you name. A message holds the session's name, what happened and when, how long a wait has lasted, and the names of its folder, app and agent. It holds no path and no prompt, unless you also turn on what a waiting session is asking, below.
201
209
  - Started with `npx agent-lookout`, npm contacts its registry: to download the package the first time, and each time after to ask whether a newer version is out. That is npm's own traffic, not Agent Lookout's. Installed with `npm install -g agent-lookout` and started as `agent-lookout`, npm is not involved.
202
210
  - It runs Claude Code's own `claude agents` command, which may contact Anthropic the way Claude Code normally does. `AGENT_LOOKOUT_CLAUDE_FEED=off` stops it running that command.
203
211
  - While a Claude Code session waits for you, it reads the end of its transcript to show what it asks, such as `Run: npm test`. It forgets that line when the wait ends. The line stays on this machine unless you start Agent Lookout with `AGENT_LOOKOUT_EMAIL_ASKING=on` or `AGENT_LOOKOUT_WEBHOOK_ASKING=on`, which put it in the email or post for that wait. It can hold a command, a web address or a file's full path. No answer of `agent-lookout mcp` holds it. `AGENT_LOOKOUT_WAITING_TEXT=off` turns it off.
204
212
  - Codex's session files hold your conversations. Agent Lookout reads them for when each turn started and ended, and for a few details such as the session's folder. It keeps none of your prompts, Codex's replies or the commands Codex ran.
213
+ - With the [Agent Lookout plugin](docs/GUIDE.md#answer-a-permission-prompt) installed in Claude Code, each permission request, the tool and its input, which for a new file is the whole file, goes from Claude Code to Agent Lookout over a socket in `~/.agent-lookout` that only you can open. Agent Lookout keeps what it shows of it in memory until the prompt is answered, and never writes it down or sends it on.
205
214
  - `agent-lookout mcp` does nothing until you add it to an agent's app. That app usually hands its answers, with your session names, folders and branches, to its model, which for most agents runs on the vendor's servers. [The MCP server](PRIVACY.md#the-mcp-server) says what an answer holds.
215
+ - Other machines are read only once you name them in `AGENT_LOOKOUT_REMOTES`. Then it runs your own `ssh` to each, which signs in with your config and agent, and asks the Agent Lookout running there for its sessions, sending nothing of this computer's. While it is connected, other programs and user accounts on this computer can reach Agent Lookout there through its tunnel, as they can reach it here. [Another machine over SSH](PRIVACY.md#another-machine-over-ssh) says what is read.
206
216
  - Jump to a Terminal or iTerm2 tab needs macOS to let the program you start Agent Lookout from control that app. macOS asks once, and what you allow covers anything else you run from that program. Choose Don't Allow and only that Jump stops working. `AGENT_LOOKOUT_TERMINAL_JUMP=off` turns it off.
207
217
 
208
- It listens on a loopback address only, `127.0.0.1`, or `::1` if you set `AGENT_LOOKOUT_HOST`, and refuses any other, so other computers cannot reach it. It turns away requests from websites open in your browser. It has no password. While it runs, other programs and other user accounts on this computer can read it. They can also turn the notifications it shows on or off, do what the Jump button does, and clear the history. It writes to no agent's files. The one thing it changes outside itself is which tmux pane, or which Terminal or iTerm2 tab, is in front, when you press Jump.
218
+ It listens on a loopback address only, `127.0.0.1`, or `::1` if you set `AGENT_LOOKOUT_HOST`, and refuses any other, so other computers cannot reach it. It turns away requests from websites open in your browser. It has no password. While it runs, other programs and other user accounts on this computer can read it. They can also turn the notifications it shows on or off, change the time rules, do what the Jump button does, clear the history, stop a Claude Code session as the Stop button does, and answer a permission prompt it is holding as Allow and Deny do. The Mac app opens no port, so there only its own window can. It writes to no agent's files. It changes three things outside itself, and only when you ask. When you press Jump, it brings a tmux pane, or a Terminal or iTerm2 tab, to the front. When you press Stop and confirm, it ends that Claude Code session's process. When you press Allow or Deny, it answers that one permission prompt, and rewrites nothing and saves no rule. `AGENT_LOOKOUT_STOP=off` takes Stop away, and `AGENT_LOOKOUT_ANSWER=off` takes Allow and Deny away.
209
219
 
210
220
  ## What it does not do yet
211
221
 
212
- - Neither it nor an agent using `agent-lookout mcp` can stop, resume or answer a session.
213
- - It shows only sessions on this computer. Cloud sessions, Codex cloud tasks and chats in a browser tab do not appear.
222
+ - It does not resume a session itself: Resume copies the command that does, for a Claude Code session that has ended. It cannot send a session a message. It stops a Claude Code session only when you press Stop and confirm, and not one in the desktop app. It answers a permission prompt only with the plugin installed, and offers Deny alone for an edit, since it does not show the change, for a plan or a question, and for a request it cannot show whole and as it is. An agent using `agent-lookout mcp` can do none of these.
223
+ - It shows sessions on this computer, and on [another machine](docs/GUIDE.md#another-machine-over-ssh) running Agent Lookout that you reach over SSH. Cloud sessions, Codex cloud tasks and chats in a browser tab do not appear.
214
224
  - Claude Code's session files and Codex's files are not documented by their makers. An update to either can make Agent Lookout show less, or nothing, until it is updated. [docs/adapters/codex.md](docs/adapters/codex.md#what-breaks-when-codex-changes) lists what breaks when Codex changes.
215
225
  - The Mac app is not signed with an Apple Developer ID yet, so the first time it is opened, macOS does not open it until you allow it in Privacy & Security. There is no app for Linux. Support for more agents is planned in the [milestones](https://github.com/Olanetsoft/agent-lookout/milestones).
216
226
 
@@ -235,4 +245,4 @@ Bug reports, fixes and support for other agents are welcome. For anything larger
235
245
 
236
246
  ## License
237
247
 
238
- Agent Lookout is [MIT licensed](LICENSE). The package's `dist/THIRD-PARTY-LICENSES.md` lists the licences of the libraries and fonts the dashboard includes. It is an unofficial project, not affiliated with or endorsed by Anthropic, OpenAI or any other agent maker. See [DISCLAIMER.md](DISCLAIMER.md).
248
+ Agent Lookout is [MIT licensed](LICENSE). The package's `dist/THIRD-PARTY-LICENSES.md` lists the licences of the libraries and fonts the dashboard and the command include. It is an unofficial project, not affiliated with or endorsed by Anthropic, OpenAI or any other agent maker. See [DISCLAIMER.md](DISCLAIMER.md).