agent-lookout 0.2.1 → 0.2.4

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 (39) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/PRIVACY.md +113 -25
  3. package/README.md +21 -15
  4. package/SECURITY.md +20 -8
  5. package/bin/agent-lookout.mjs +49 -24
  6. package/dist/THIRD-PARTY-LICENSES.md +195 -0
  7. package/dist/assets/HistoryPanel-CIjshvhu.js +1 -0
  8. package/dist/assets/SessionPanel-eBOdTLD9.js +1 -0
  9. package/dist/assets/index-B-myfVQS.js +2 -0
  10. package/dist/assets/index-Cceyz9yZ.css +1 -0
  11. package/dist/assets/radix-BH0JH8UU.js +41 -0
  12. package/dist/cli/agent-lookout.js +4 -4
  13. package/dist/cli/{chunk-PQ3B5TN6.js → chunk-63XPRBHW.js} +88 -2
  14. package/dist/cli/{chunk-XJM5RZNV.js → chunk-KNOLJ3IC.js} +1 -1
  15. package/dist/cli/{chunk-UYGESSPG.js → chunk-XVXSGVEW.js} +6 -2
  16. package/dist/cli/mcpServer-HGH6PY4W.js +23664 -0
  17. package/dist/cli/{startCommand-ZV2NQ6YG.js → startCommand-KNXMVM2U.js} +3417 -676
  18. package/dist/index.html +3 -3
  19. package/docs/API.md +301 -79
  20. package/docs/GUIDE.md +215 -67
  21. package/package.json +6 -6
  22. package/dist/assets/HistoryPanel-Llcz5XPi.js +0 -1
  23. package/dist/assets/SessionPanel-B4g_6Unu.js +0 -1
  24. package/dist/assets/atkinson-hyperlegible-mono-latin-400-normal-Cmjm2dBj.woff +0 -0
  25. package/dist/assets/atkinson-hyperlegible-mono-latin-500-normal-BV5ipwqM.woff +0 -0
  26. package/dist/assets/atkinson-hyperlegible-mono-latin-600-normal-CuPF9o0F.woff +0 -0
  27. package/dist/assets/atkinson-hyperlegible-mono-latin-ext-400-normal-ITMuFrSK.woff +0 -0
  28. package/dist/assets/atkinson-hyperlegible-mono-latin-ext-500-normal-BiHEOgiK.woff +0 -0
  29. package/dist/assets/atkinson-hyperlegible-mono-latin-ext-600-normal-ZiH-ObRk.woff +0 -0
  30. package/dist/assets/atkinson-hyperlegible-next-latin-400-normal-DPp7N0cD.woff +0 -0
  31. package/dist/assets/atkinson-hyperlegible-next-latin-500-normal-B0CYqHl3.woff +0 -0
  32. package/dist/assets/atkinson-hyperlegible-next-latin-600-normal-BhgCag5w.woff +0 -0
  33. package/dist/assets/atkinson-hyperlegible-next-latin-ext-400-normal-qxMiU51n.woff +0 -0
  34. package/dist/assets/atkinson-hyperlegible-next-latin-ext-500-normal-oZS3KxrF.woff +0 -0
  35. package/dist/assets/atkinson-hyperlegible-next-latin-ext-600-normal-BBAQIogt.woff +0 -0
  36. package/dist/assets/index-DRcy1hT5.js +0 -2
  37. package/dist/assets/index-Dz4q_OYZ.css +0 -1
  38. package/dist/assets/radix-27o0jeIu.js +0 -41
  39. package/dist/cli/mcpServer-CGLIGL4X.js +0 -246
package/docs/GUIDE.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ## Requirements
4
4
 
5
5
  - macOS or Linux. Agent Lookout is developed and tested on macOS. On Linux it has been checked in CI by starting it with `npm start`, and not yet by a person on a Linux desktop. [On Linux](#on-linux) says what differs there. Windows is untested.
6
- - Node.js 20.19 or newer. On Node 22 it needs 22.12 or newer. The [Mac app](#desktop-app) needs no Node.js.
6
+ - Node.js 22.12 or newer. The [Mac app](#desktop-app) needs no Node.js.
7
7
  - Claude Code, Codex or both. Neither needs any setup. Any other agent can appear too, by writing a status file: see [Your own agents](#your-own-agents).
8
8
  - For Claude Code, a version that has the `claude agents` command. `claude agents --help` should print `Usage: claude agents`. Without that command Agent Lookout still reads the session files, but cannot list background jobs that have finished or failed.
9
9
  - For Codex, version 0.155 or later, so that Agent Lookout can tell a session that has ended from one that is idle.
@@ -20,7 +20,7 @@ The header over each view says how many sessions are being watched and, in a wid
20
20
 
21
21
  ### Overview
22
22
 
23
- The Overview has five parts. The Needs you panel and the Last hour chart share the top row, the Sessions list and the Events log share the next, and the Timeline runs under both. In a narrower window they are one column in that order. The Sessions list can also be shown as a [board](#board), and any session, in it or in the Needs you panel, can be opened to see its [details](#a-sessions-details).
23
+ The Overview has six parts. The Needs you panel and the Last hour chart share the top row, the Sessions list and the Events log share the next, and the Timeline runs under both, with Waits under it. In a narrower window they are one column in that order. The Sessions list can also be shown as a [board](#board), and any session, in it or in the Needs you panel, can be opened to see its [details](#a-sessions-details).
24
24
 
25
25
  #### Needs you
26
26
 
@@ -64,6 +64,8 @@ When the list is too narrow for every column, the app is left out first and then
64
64
 
65
65
  A Claude Code session in VS Code, inside tmux or in a tab of Terminal or iTerm2 has a Jump button here too.
66
66
 
67
+ Claude Code sessions idle for a day or more whose process still runs are also listed over the list, under Left running, where they can be hidden or ended: see [Sessions left running](#sessions-left-running).
68
+
67
69
  Click a row, or move to its name with Tab and press Enter, to open the session's [details](#a-sessions-details).
68
70
 
69
71
  The switch at the top right of the Sessions list, or under its title on a phone, chooses List, Repos or Board. Repos groups the same rows by [repository](#repositories), and Board lays them out in columns.
@@ -101,12 +103,13 @@ The details show everything Agent Lookout knows about the session:
101
103
  - its agent, and the app it runs in when that is known
102
104
  - the full path of its folder, which you can select and copy
103
105
  - its [repository](#repositories), and its [branch](#branches) or the commit when no branch is checked out
106
+ - with pull requests on, its branch's [pull request](#pull-requests): its number and title, a link that opens it on github.com in your browser, whether it is open, a draft, merged or closed, and how many of its checks are failing, pending and passing
104
107
  - when it started and its process ID, when its agent reports them
105
108
  - how many times it waited for you and how long in all, over the same time as the bars in the Needs you panel
106
109
  - its own events, newest first, as the Events log shows them
107
110
  - its row of the Timeline over the last hour
108
111
 
109
- A session with a Jump button has it at the top of its details, and it works as it does in the list. It is the amber one while the session needs you.
112
+ A session with a Jump button has it at the top of its details, and it works as it does in the list. It is the amber one while the session needs you. A session Agent Lookout can stop has a [Stop](#stop-a-session) button beside it.
110
113
 
111
114
  Each session's details have an address of their own, such as `#overview/session/claude-code:` followed by the session's ID, so a bookmark or a reload opens them again, and the browser's Back button closes them. `Esc` or the close button closes them too, and puts focus back on the session's name. If the session leaves the list while its details are open, they say so and keep what was last known of it. An address for a session Agent Lookout is not watching says so, with a button back to the Overview.
112
115
 
@@ -159,15 +162,43 @@ git worktree add ../storefront-billing -b billing-webhooks
159
162
 
160
163
  Repos then lists both sessions under `storefront`, each with its own folder and branch.
161
164
 
165
+ #### Pull requests
166
+
167
+ Agent Lookout can show the pull request on github.com for each session's branch, and whether its checks pass, so a session whose pull request has a failing check stands out. It is off unless you turn it on, because it asks GitHub: start Agent Lookout with `AGENT_LOOKOUT_PULL_REQUESTS=on`.
168
+
169
+ ```sh
170
+ AGENT_LOOKOUT_PULL_REQUESTS=on npx agent-lookout
171
+ ```
172
+
173
+ It asks through your own [GitHub CLI](https://cli.github.com), `gh`, with the login `gh` already has, so Agent Lookout never sees or keeps a token. Install `gh` and run `gh auth login` once if you have not. Agent Lookout looks for `gh` on your `PATH`, then in `/opt/homebrew/bin`, `/usr/local/bin`, `/opt/local/bin` and `/usr/bin`, as it does for tmux.
174
+
175
+ With it on:
176
+
177
+ - A session's details have a Pull request fact under its branch: the pull request's number and title, as a link that opens it on github.com in your browser, and under them whether it is open, a draft, merged or closed and how its checks stand, such as `Open, 2 checks failing, 1 pending, 4 passing`. A check that was skipped or ended neutral counts as passing, and one that was cancelled or timed out as failing.
178
+ - In the Sessions list and on the board, a branch whose pull request is open, or a draft, and has a check failing has a small cross after it. Hover over it, or move to it with Tab, to read which pull request and how its checks stand. The list shows it under the folder, and so leaves it out in a narrow window, as it does the branch.
179
+ - `agent-lookout mcp` gives each session's pull request as its number and how its checks stand, and `agent-lookout status --json` does for a waiting session. Neither gives the title.
180
+
181
+ Agent Lookout asks only about a branch of a repository whose remote is on github.com. It reads the remote from the repository's own `config` file, as it reads the branch from `HEAD`, and runs no git command. A remote on any other host, a GitHub Enterprise server's among them, is passed over, as is a host name your SSH configuration stands in for github.com. It never asks about the repository's default branch, the one its remote's `HEAD` names, or `main` or `master` when that was never written. Nor does it ask about a branch whose name is only digits, such as `51` or `#51`, which `gh` would take for the number of a pull request rather than a branch. It asks for a pull request from the branch of the same name, the way `gh pr view` does, in the repository `gh repo set-default` chose, or else in the remote named `upstream`, `github` or `origin`, in that order. A branch pushed to someone else's copy, a fork, is looked for as `owner:branch`.
182
+
183
+ It asks `gh` once for each repository and branch your sessions are on, however many sessions are on it, and again only after 2 minutes, never on every poll. So a pull request you open, or a check that finishes, shows within about 2 minutes. Each question runs `gh pr view` and waits up to 15 seconds for it. A branch no session is on any more is forgotten.
184
+
185
+ The Pull requests card in Settings says whether this is on, and when `gh` was last asked. Without `gh`, or with `gh` not signed in, it says so, and no pull request is shown until that changes: Agent Lookout keeps working as before. What `gh` sends GitHub, for each question, is the repository's owner and name and the branch's name, with `gh`'s own login. [PRIVACY.md](../PRIVACY.md#gh) has the details.
186
+
162
187
  #### Events
163
188
 
164
- The Events log records each session appearing, changing status and ending, newest first. When a wait ends, it says how long the wait lasted if it saw the wait begin. When Agent Lookout measured nothing for a while in the last hour, such as while the computer was asleep, a row says when watching resumed and how long was not measured. While the log still holds everything since Agent Lookout started, it ends with Started watching.
189
+ The Events log records each session appearing, changing status and ending, newest first, and each session [stopped](#stop-a-session) from Agent Lookout. When a wait ends, it says how long the wait lasted if it saw the wait begin. When Agent Lookout measured nothing for a while in the last hour, such as while the computer was asleep or Agent Lookout was stopped, a row says when watching resumed and how long was not measured. The log is kept on this computer with the charts' counts, so a restart does not empty it: see [History](#history). While the log still holds everything since Agent Lookout started, it ends with Started watching, and its heading says since when, with the day when that was not today. Once the history has been cleared, it ends with History cleared instead.
165
190
 
166
191
  When you come back to the tab after it was in the background or minimised, or open the dashboard again, a line in the log marks where you left off, such as New since 14:02:37, and the log's heading says how many events arrived since, such as 3 new. The events above the line are the new ones. The line and the count go once the line has been in view for 10 seconds, or when you open Sources or Settings. If more arrived than the log shows at once, scroll down the log to the line. With the tab in front all the time there is never a line. Events that arrive while the line is showing join the new ones above it. A wait among the new events has its usual mark, and nothing else changes colour. The one thing kept for this is the time you left off, in your browser.
167
192
 
168
193
  #### Timeline
169
194
 
170
- The Timeline draws each session's status over the last hour, one row for each session. Hatched stretches are time Agent Lookout did not measure, such as the time before it started. The legend at the top of the card names each mark.
195
+ The Timeline draws each session's status over the last hour, one row for each session. Hatched stretches are time Agent Lookout did not measure, such as the time before it started or while it was stopped. The legend at the top of the card names each mark.
196
+
197
+ #### Waits
198
+
199
+ Waits says how long sessions waited on you today and over the last 7 days, which are today and the six days before it, so you can see whether waiting on you is getting better or worse, and which sessions wait the longest. Each figure gives how many waits it took. By day has a bar for each of the 7 days, oldest first, with how long sessions waited that day and how much of it Agent Lookout measured. A day it did not measure at all is hatched, with a dash. Longest waits lists the five sessions that waited longest, with how many times each waited and whether it is waiting now, today or over the 7 days, by the switch beside it.
200
+
201
+ Waits counts only the time Agent Lookout was running, from the [history](#history) it keeps, and the line under the figures says how much of today and of the 7 days that was. Time it was stopped, the computer was asleep, or a source did not answer is left out, and a wait that went on across it counts for the time either side and is still one wait. A wait already under way when Agent Lookout started counts from when it started, so it can be shorter here than in the Needs you panel, which shows how long the session has waited in all. When two sessions wait at once, each one's wait counts, so two waiting for a minute is two minutes. With `AGENT_LOOKOUT_HISTORY=off` it covers only the time since Agent Lookout started, and says so. Only Claude Code sessions and sessions from a status file can be seen waiting, so a Codex session never counts. A wait that is still open is amber at the end of today's bar, as in the Last hour chart, and goes on second by second. The page asks for the totals every 30 seconds, and at once when a wait opens or ends or you come back to the page, and they are worked out on this computer and sent nowhere.
171
202
 
172
203
  ### Sources
173
204
 
@@ -185,13 +216,13 @@ When an agent is not on this computer, its card says Not found, and after the fi
185
216
 
186
217
  #### What each agent can report
187
218
 
188
- Under the cards, What each agent can report has a row for each agent and a column for each thing Agent Lookout can show of its sessions, with Yes, No or Partly in each. Point at No or Partly, or move to it with Tab, to read why. In a narrow window each agent has a block of its own, with the reason under each No and Partly. A No means Agent Lookout cannot show it for that agent's sessions, so not seeing it is not good news. The [branch](#branches) is not in the table, because it is read the same way for every agent.
219
+ Under the cards, What each agent can report has a row for each agent and a column for each thing Agent Lookout can show of its sessions, and for [Stop](#stop-a-session), what it can do to one, with Yes, No or Partly in each. Point at No or Partly, or move to it with Tab, to read why. In a narrow window each agent has a block of its own, with the reason under each No and Partly. A No means Agent Lookout cannot show it for that agent's sessions, so not seeing it is not good news. The [branch](#branches) is not in the table, because it is read the same way for every agent.
189
220
 
190
- | Agent | Working and idle | Needs you | Finished | Failed | Names | Jump | Quiet for |
191
- | ------------ | ---------------- | --------- | -------- | ------ | ------ | ------ | --------- |
192
- | Claude Code | Yes | Yes | Partly | Partly | Yes | Partly | No |
193
- | Codex | Yes | No | Partly | No | Partly | No | Yes |
194
- | Status files | Partly | Partly | Partly | Partly | Partly | No | Partly |
221
+ | Agent | Working and idle | Needs you | Finished | Failed | Names | Jump | Quiet for | Stop |
222
+ | ------------ | ---------------- | --------- | -------- | ------ | ------ | ------ | --------- | ------ |
223
+ | Claude Code | Yes | Yes | Partly | Partly | Yes | Partly | No | Partly |
224
+ | Codex | Yes | No | Partly | No | Partly | No | Yes | No |
225
+ | Status files | Partly | Partly | Partly | Partly | Partly | No | Partly | No |
195
226
 
196
227
  Why, for each No and Partly:
197
228
 
@@ -199,11 +230,13 @@ Why, for each No and Partly:
199
230
  - Claude Code, Failed: Only background jobs. Any other session leaves the list without saying how it ended.
200
231
  - Claude Code, Jump: In VS Code, in tmux, and in a tab of Terminal or iTerm2 on a Mac. Not in the desktop app or another terminal.
201
232
  - Claude Code, Quiet for: The file Agent Lookout reads is not rewritten as a session works.
233
+ - Claude Code, Stop: In a terminal, in VS Code and for background jobs. Not in the desktop app.
202
234
  - Codex, Needs you: Codex does not record approval waits, so a session waiting for you shows as working.
203
235
  - Codex, Finished: From Codex 0.155 on, once no Codex program has the session open.
204
236
  - Codex, Failed: Codex does not record errors in its files.
205
237
  - Codex, Names: The desktop app does not keep its titles in the names file Agent Lookout reads, so its sessions take their folder's name.
206
238
  - Codex, Jump: Codex's files name no process to find, and Codex documents no link to a session.
239
+ - Codex, Stop: Codex's files name no process that Agent Lookout could confirm and stop.
207
240
  - Status files, Working and idle: If the agent writes working and idle.
208
241
  - Status files, Needs you: If the agent writes waiting.
209
242
  - Status files, Finished: If the agent writes finished.
@@ -211,10 +244,11 @@ Why, for each No and Partly:
211
244
  - Status files, Names: If the agent writes a name. Otherwise the folder's or the file's name is used.
212
245
  - Status files, Jump: Nothing in a status file is used to reach a session.
213
246
  - Status files, Quiet for: If the agent writes its file again as it works.
247
+ - Status files, Stop: Any program can write a status file, so nothing in one is used to stop a session.
214
248
 
215
249
  ### Settings
216
250
 
217
- Settings has five cards, and in the Mac app a sixth, [Updates](#updates). Theme chooses Night, which is the default, Day, or System, which follows your computer's setting. Notifications turns notifications on and off, for the dashboard page and for Agent Lookout itself, and chooses what sends one. Email says whether Agent Lookout emails you, and for what, and Webhook whether it posts to a webhook, such as a Slack channel's, and for what. Both are set up when you start it, not here. This copy shows the version you are running and where Agent Lookout sends your data: nowhere, or only in the emails and webhook posts you set up.
251
+ Settings has seven cards, and in the Mac app two more, [Menu bar](#menu-bar) and [Updates](#updates). Theme chooses Night, which is the default, Day, or System, which follows your computer's setting. Notifications turns notifications on and off, for the dashboard page and for Agent Lookout itself, and chooses what sends one. History says where the Events log and the charts are kept, how much they hold and since when, and clears them. Email says whether Agent Lookout emails you, and for what, and Webhook whether it posts to a webhook, such as a Slack channel's, and for what. Pull requests says whether each session's [pull request](#pull-requests) is shown, and whether `gh` can be asked for them. All three are set up when you start it, not here. This copy shows the version you are running and where Agent Lookout sends your data: nowhere, or only in the emails and webhook posts you set up, and with pull requests on, the names of repositories and branches to GitHub, through `gh`, unless `gh` was not found or is not signed in, when nothing goes to GitHub.
218
252
 
219
253
  #### Notifications
220
254
 
@@ -273,6 +307,20 @@ A notification shows the session's name outside the dashboard: over other apps,
273
307
 
274
308
  The browser gives its permission to the address, not to Agent Lookout. Another program you later serve at the same address, such as another project's dev server on `localhost:5173`, can show notifications without asking. To take the permission back, remove it for that address in the browser's site settings. `npx agent-lookout` and `npm start` serve Agent Lookout at `127.0.0.1:4777`, an address other tools are less likely to use. [PRIVACY.md](../PRIVACY.md#notifications) says what a notification holds and where it is kept.
275
309
 
310
+ #### History
311
+
312
+ The Events log and the counts behind the charts are written to `~/.agent-lookout/history` every 5 seconds, and once more as Agent Lookout stops, so they are still there when it starts again. The time it was not running shows as time not measured, as the time the computer was asleep does: a Watching resumed row in the Events log, and hatching in the Timeline and the Last hour chart. Every restart gets that row, however short the stop and however long ago the history before it ends.
313
+
314
+ A session that changed status or ended while Agent Lookout was stopped is found by the first poll after it starts again, and the Events log and the charts record the change at that poll, as they do when the computer wakes. A session the history holds no event of, because nothing about it changed while Agent Lookout watched, is shown with its present status only from the restart, unless its agent says when that status began.
315
+
316
+ The History card says that history is kept on this computer for 8 days, and gives the folder, how much the files hold out of 20 MB, and how far back they go. Each day's history is deleted once that day ended more than 8 days ago, and when the files would hold more than 20 MB the oldest is deleted first, so they never hold more. They hold the events and counts the dashboard shows, and no folder path, prompt or anything a waiting session is asking. [PRIVACY.md](../PRIVACY.md#the-history) has the details.
317
+
318
+ Clear history asks first, in the card: Clear history again to go ahead, or Cancel. It deletes the files and empties the Events log and the charts, which then start with History cleared. The card says when it was cleared. Files written by a later version of Agent Lookout are left alone.
319
+
320
+ `AGENT_LOOKOUT_HISTORY_DIR` keeps the files in another folder. With `AGENT_LOOKOUT_HISTORY=off` nothing is written: the card says history is kept in memory only and has no button, and the Events log and the charts start empty each time Agent Lookout starts.
321
+
322
+ When two copies run at once, such as the Mac app and `npx agent-lookout`, one of them writes the history. The other shows what had been kept when it started and keeps what it sees in memory. Its card says another copy is writing the history, and whether that copy reads sessions from other folders, and has no button. It takes over when the first one stops. To try Agent Lookout on empty folders without writing to your history, set `AGENT_LOOKOUT_HISTORY_DIR` to an empty folder too.
323
+
276
324
  #### Email
277
325
 
278
326
  Agent Lookout can also email you when a session has waited for a while, for when you are away from the computer, and, if you choose, when a session finishes, fails or ends. It is off unless you set it up. With it off, which is the default, Agent Lookout sends no email and opens no connection to a mail server.
@@ -288,7 +336,7 @@ Two settings turn email on:
288
336
  | `AGENT_LOOKOUT_EMAIL_TO` | The one address emails go to |
289
337
  | `AGENT_LOOKOUT_SMTP_URL` | The mail server, as `smtps://name:password@server:port`, or `smtp://` |
290
338
 
291
- Three more can be left out. `AGENT_LOOKOUT_EMAIL_FROM` is the address emails come from, which is the address they go to unless you set it. If emails go to an address other than the one you sign in to the mail server with, set `AGENT_LOOKOUT_EMAIL_FROM` to the address you sign in with. Most providers refuse to send from any other. `AGENT_LOOKOUT_EMAIL_AFTER` is how many seconds a wait lasts before it is emailed: 60 unless you set it, and 0 for at once. `AGENT_LOOKOUT_EMAIL_EVENTS` is what is emailed: one or more of `needs-you`, `finished`, `failed` and `ended`, the four events described under [Notifications](#notifications), separated by commas, such as `needs-you,finished`. Unless you set it, it is `needs-you`, a wait alone. The switches in Settings choose notifications only, not emails, because the page cannot change how Agent Lookout was started.
339
+ Four more can be left out. `AGENT_LOOKOUT_EMAIL_FROM` is the address emails come from, which is the address they go to unless you set it. If emails go to an address other than the one you sign in to the mail server with, set `AGENT_LOOKOUT_EMAIL_FROM` to the address you sign in with. Most providers refuse to send from any other. `AGENT_LOOKOUT_EMAIL_AFTER` is how many seconds a wait lasts before it is emailed: 60 unless you set it, and 0 for at once. `AGENT_LOOKOUT_EMAIL_EVENTS` is what is emailed: one or more of `needs-you`, `finished`, `failed` and `ended`, the four events described under [Notifications](#notifications), separated by commas, such as `needs-you,finished`. Unless you set it, it is `needs-you`, a wait alone. `AGENT_LOOKOUT_EMAIL_ASKING`, `on` or `off`, is whether the email for a wait says what the session is asking, and is `off` unless you set it: [What a waiting session is asking](#what-a-waiting-session-is-asking-by-email) says what that adds. The switches in Settings choose notifications only, not emails, because the page cannot change how Agent Lookout was started.
292
340
 
293
341
  In `AGENT_LOOKOUT_SMTP_URL`, write any `@`, `:`, `/`, `?`, `#` or `%` in the user name or the password as `%40`, `%3A`, `%2F`, `%3F`, `%23` or `%25`. A user name that is an email address is the usual case: `name@example.com` is written `name%40example.com`.
294
342
 
@@ -328,11 +376,38 @@ Then start Agent Lookout with them, brackets included:
328
376
 
329
377
  The brackets keep the settings to this one run, so the terminal does not keep them afterwards, and no program you start from it later is handed the password. In a clone, use `npm start` or `npm run dev` in place of `npx agent-lookout`, inside the same brackets.
330
378
 
331
- To check that it worked, open Settings. The Email card says where emails go and after how long, with most of the address hidden, such as "Emails go to Y…@gmail.com after a wait of 1 minute." With other events set, it names each one, such as "Emails go to Y…@gmail.com when a session has waited 1 minute or finishes." Once an email has been tried, the line under it says when the last one was sent, such as "Last sent at 14:02.", or, in a note headed "The last email could not be sent", why it could not be, such as "The mail server did not accept the user name and password." If a setting cannot be read, email stays off: the card says "Email is off.", and a note headed "Email is not set up correctly" names the setting, and the terminal you started Agent Lookout in prints one line that says the same. Neither ever shows the password.
379
+ To check that it worked, open Settings. The Email card says where emails go and after how long, with most of the address hidden, such as "Emails go to Y…@gmail.com after a wait of 1 minute." With other events set, it names each one, such as "Emails go to Y…@gmail.com when a session has waited 1 minute or finishes." Under that, a line says whether the email for a wait says what the session is asking, as [below](#what-a-waiting-session-is-asking-by-email) describes. Once an email has been tried, the line under those says when the last one was sent, such as "Last sent at 14:02.", or, in a note headed "The last email could not be sent", why it could not be, such as "The mail server did not accept the user name and password." If a setting cannot be read, email stays off: the card says "Email is off.", and a note headed "Email is not set up correctly" names the setting, and the terminal you started Agent Lookout in prints one line that says the same. Neither ever shows the password.
332
380
 
333
381
  The card can say where emails go before any has been tried, so a wrong password or port shows only once a wait has lasted the delay. To try it at once, start Agent Lookout with `AGENT_LOOKOUT_EMAIL_AFTER=0` as well, and let a session ask for permission. The card then says whether the email went. Start it again without that setting afterwards.
334
382
 
335
- An email's subject names the session and what happened: "checkout-flow is waiting for permission", "checkout-flow asked you a question" or "checkout-flow is waiting for you", and "billing-webhooks finished", "billing-webhooks failed" or "billing-webhooks ended". Its text says how long the session has waited and since when, or when Agent Lookout saw it finish, fail or end, then the name of its project folder, its app and its agent, leaving out any that is not known, and how to stop these emails. It holds no path, no prompt and no link. [PRIVACY.md](../PRIVACY.md#email) lists all it holds.
383
+ An email's subject names the session and what happened: "checkout-flow is waiting for permission", "checkout-flow asked you a question" or "checkout-flow is waiting for you", and "billing-webhooks finished", "billing-webhooks failed" or "billing-webhooks ended". Its text says how long the session has waited and since when, or when Agent Lookout saw it finish, fail or end, then the name of its project folder, its app and its agent, leaving out any that is not known, and how to stop these emails. It holds no path, no prompt, no link and, unless you set `AGENT_LOOKOUT_EMAIL_ASKING=on` (below), nothing of what a waiting session is asking. [PRIVACY.md](../PRIVACY.md#email) lists all it holds.
384
+
385
+ ##### What a waiting session is asking, by email
386
+
387
+ An email leaves out what a waiting session is asking, the line under its reason in the Needs you panel, such as `Run: npm test`, because that line can hold a command, a web address or a file's full path, and an email leaves this computer. If that line is what tells you whether to go back now, start Agent Lookout with `AGENT_LOOKOUT_EMAIL_ASKING=on` as well:
388
+
389
+ ```sh
390
+ (source ~/.agent-lookout-email && AGENT_LOOKOUT_EMAIL_ASKING=on npx agent-lookout)
391
+ ```
392
+
393
+ The email for a wait then has one more line, before the folder's name:
394
+
395
+ ```text
396
+ checkout-flow is waiting for permission.
397
+
398
+ It has waited 1 minute, since 14:02.
399
+
400
+ Asking: Run: npm test
401
+ Folder: storefront
402
+ App: VS Code
403
+ Agent: Claude Code
404
+
405
+ Sent by Agent Lookout on your computer. To stop these emails, start it again without AGENT_LOOKOUT_EMAIL_TO.
406
+ ```
407
+
408
+ It is the line the dashboard shows, cleaned and cut the same way: one line of at most 200 characters. A command in it can name any path, a server or a password typed on the command line, a web address can show as a link in your mail app, and a file outside the session's folder is named by its full path, which can name your home folder. Your mail server and your mailbox keep it, as they keep the rest of the email. It is never in the subject, and never in an email for a session that finished, failed or ended. Only a Claude Code session has one, and only when its transcript says, so other waits send the same email as before. It is taken from the sessions at the moment the email is sent, and Agent Lookout keeps nothing of it afterwards. With `AGENT_LOOKOUT_WAITING_TEXT=off` no transcript is read, so there is nothing to add.
409
+
410
+ The Email card then says "Emails for a wait say what the session is asking." under where emails go, and "Emails leave out what a waiting session is asking." while the setting is off or left out. Any value but `on` or `off` turns email off, and the card and the terminal name the setting, as for any other setting that cannot be read. To leave the line out again, start Agent Lookout without `AGENT_LOOKOUT_EMAIL_ASKING`. The webhook has a setting of its own for this, so the line can come to your mailbox and stay out of a channel others read.
336
411
 
337
412
  - One email goes for a wait that has lasted the delay and is still open. A wait you answer before then sends nothing.
338
413
  - Each wait sends one email at most. A session you answer that waits again later sends another.
@@ -356,7 +431,7 @@ It is set up with a setting in the environment when you start Agent Lookout, not
356
431
  | --------------------------- | ------------------------------------------------------ |
357
432
  | `AGENT_LOOKOUT_WEBHOOK_URL` | The one address posts go to, beginning with `https://` |
358
433
 
359
- Two more can be left out. `AGENT_LOOKOUT_WEBHOOK_EVENTS` is what is posted, written as for email: one or more of `needs-you`, `finished`, `failed` and `ended`, separated by commas, and `needs-you` unless you set it. `AGENT_LOOKOUT_WEBHOOK_AFTER` is how many seconds a wait lasts before it is posted: 60 unless you set it, and 0 for at once. A finish, a failure or an end is posted at once. These are separate from the email settings, so email and the webhook can send different events.
434
+ Three more can be left out. `AGENT_LOOKOUT_WEBHOOK_EVENTS` is what is posted, written as for email: one or more of `needs-you`, `finished`, `failed` and `ended`, separated by commas, and `needs-you` unless you set it. `AGENT_LOOKOUT_WEBHOOK_AFTER` is how many seconds a wait lasts before it is posted: 60 unless you set it, and 0 for at once. A finish, a failure or an end is posted at once. `AGENT_LOOKOUT_WEBHOOK_ASKING`, `on` or `off`, is whether the post for a wait says what the session is asking, and is `off` unless you set it: [What a waiting session is asking](#what-a-waiting-session-is-asking-in-a-post) says what that adds. These are separate from the email settings, so email and the webhook can send different events, and one can say what a session is asking while the other does not.
360
435
 
361
436
  The address is a secret. Anyone who has it can post to the channel, so keep it out of screenshots, issues and shared files. Agent Lookout never shows it: Settings shows its host alone, and that in full, so with a service that puts its secret in the host, keep Settings out of screenshots too.
362
437
 
@@ -388,9 +463,15 @@ For Slack:
388
463
 
389
464
  For Discord, create a webhook in the channel's settings, under Integrations, copy its address and add `/slack` to the end of it: Discord then takes the same posts.
390
465
 
391
- To check that it worked, open Settings. The Webhook card says where posts go and when, naming only the host, such as "Posts go to hooks.slack.com after a wait of 1 minute." Once a post has been tried, the line under it says when the last one went, such as "Last posted at 14:02.", or, in a note headed "The last post failed", why it did not, such as "The address refused the post (status 403)." If a setting cannot be read, the webhook stays off: the card says "The webhook is off.", and a note headed "The webhook is not set up correctly" names the setting, and the terminal you started Agent Lookout in prints one line that says the same. Neither ever shows the address. To try it at once, start Agent Lookout with `AGENT_LOOKOUT_WEBHOOK_AFTER=0` as well, `(source ~/.agent-lookout-webhook && AGENT_LOOKOUT_WEBHOOK_AFTER=0 npx agent-lookout)`, and let a session ask for permission. The card then says whether the post went. Start it again without that setting afterwards, or every wait is posted as soon as it begins.
466
+ To check that it worked, open Settings. The Webhook card says where posts go and when, naming only the host, such as "Posts go to hooks.slack.com after a wait of 1 minute." Under that, a line says whether the post for a wait says what the session is asking, as [below](#what-a-waiting-session-is-asking-in-a-post) describes. Once a post has been tried, the line under those says when the last one went, such as "Last posted at 14:02.", or, in a note headed "The last post failed", why it did not, such as "The address refused the post (status 403)." If a setting cannot be read, the webhook stays off: the card says "The webhook is off.", and a note headed "The webhook is not set up correctly" names the setting, and the terminal you started Agent Lookout in prints one line that says the same. Neither ever shows the address. To try it at once, start Agent Lookout with `AGENT_LOOKOUT_WEBHOOK_AFTER=0` as well, `(source ~/.agent-lookout-webhook && AGENT_LOOKOUT_WEBHOOK_AFTER=0 npx agent-lookout)`, and let a session ask for permission. The card then says whether the post went. Start it again without that setting afterwards, or every wait is posted as soon as it begins.
392
467
 
393
- A post shows in the channel as one line, such as "checkout-flow is waiting for permission (4m 12s, storefront, VS Code, Claude Code)" or "billing-webhooks finished (billing-webhooks, Terminal, Claude Code)": the session's name, what happened, and in brackets how long it has waited, its project folder's name, its app and its agent, leaving out any that is not known. The post also carries the same in fields of its own, for a program to read. It holds no path and no prompt, and a link only where a session's name has a web address written out in it. [PRIVACY.md](../PRIVACY.md#webhook) lists all it holds.
468
+ A post shows in the channel as one line, such as "checkout-flow is waiting for permission (4m 12s, storefront, VS Code, Claude Code)" or "billing-webhooks finished (billing-webhooks, Terminal, Claude Code)": the session's name, what happened, and in brackets how long it has waited, its project folder's name, its app and its agent, leaving out any that is not known. The post also carries the same in fields of its own, for a program to read. It holds no path, no prompt, a link only where a session's name has a web address written out in it and, unless you set `AGENT_LOOKOUT_WEBHOOK_ASKING=on` (below), nothing of what a waiting session is asking. [PRIVACY.md](../PRIVACY.md#webhook) lists all it holds.
469
+
470
+ ##### What a waiting session is asking, in a post
471
+
472
+ A post leaves out what a waiting session is asking, such as `Run: npm test`, for the reasons an email does. Start Agent Lookout with `AGENT_LOOKOUT_WEBHOOK_ASKING=on` as well, and the post for a wait says it after the reason, as the notification of a wait does: "checkout-flow is waiting for permission: Run: npm test (4m 12s, storefront, VS Code, Claude Code)". It is in a field of its own too, `asking`, for a program to read. It is the line the dashboard shows, cleaned and cut the same way, so it can hold a command, which can name any path, a server or a password typed on the command line, a web address, which Slack shows as a link, or a file's full path when the file is outside the session's folder. Everyone who can read the channel sees it, and the service keeps it. It cannot mention anyone or ping a channel, as a session's name cannot. It is never in a post for a session that finished, failed or ended, and only a Claude Code session has one. It is taken from the sessions at the moment the post is sent, and Agent Lookout keeps nothing of it afterwards.
473
+
474
+ The Webhook card then says "Posts for a wait say what the session is asking." under where posts go, and "Posts leave out what a waiting session is asking." while the setting is off or left out. Any value but `on` or `off` turns the webhook off, and the card and the terminal name the setting. To leave the line out again, start Agent Lookout without `AGENT_LOOKOUT_WEBHOOK_ASKING`.
394
475
 
395
476
  Posts follow the rules emails do. One goes for a wait that has lasted the delay and is still open, and one at most for each wait. A finish, a failure or an end goes as soon as it is seen. Nothing is sent for what was already true when Agent Lookout starts. At most 20 posts are tried in any hour, counted apart from emails. A post that could not be sent is not tried again, and a redirect is never followed.
396
477
 
@@ -485,6 +566,39 @@ In the [desktop app](#desktop-app) the collector runs inside Agent Lookout itsel
485
566
 
486
567
  To stop Agent Lookout looking for tabs at all, start it with `AGENT_LOOKOUT_TERMINAL_JUMP=off`. It then runs neither `ps` for this nor `osascript` for Jump, and sessions in Terminal and iTerm2 have no button. [PRIVACY.md](../PRIVACY.md#terminal-and-iterm2) lists what it reads and runs.
487
568
 
569
+ ## Stop a session
570
+
571
+ A Claude Code session that runs in a terminal or in VS Code, and a Claude Code background job, has a Stop button at the top of its [details](#a-sessions-details), beside its Jump. Stop ends the session's process. It is not an interrupt: the session ends, and what it was doing stops part-way. Its conversation is kept, so `claude --resume` with the session's ID opens it again, and VS Code opens it from its session history. Agent Lookout stops a session only when you press Stop and confirm, and never on its own.
572
+
573
+ Stop asks first, at the top of the details: it names the session, says that its process ends now and how to open the conversation again, and, for a session that is working or waiting for you, that what it is doing stops part-way or that its question is left unanswered. Focus goes to Cancel, so pressing Enter does not stop it. Press Stop session to stop it.
574
+
575
+ Agent Lookout then checks again that the process is that session: it reads the session's file in `~/.claude/sessions` again and asks `ps` when the process started, and does nothing unless both agree with what it found before. A session in a terminal or VS Code is sent SIGTERM, which ends Claude Code the way closing it does, and Agent Lookout waits up to 10 seconds for it to end. A background job is stopped with `claude stop` and its ID, since Claude Code would start its process again if it were ended another way. The session leaves the list within a second or two, a background job shows as finished, and the Events log says it was stopped from Agent Lookout.
576
+
577
+ | What the details say | Why |
578
+ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
579
+ | Stopped. Its process has ended, and its conversation is kept. | It worked. |
580
+ | Asked to stop, still running. It had not ended 10 seconds later. | SIGTERM was sent and the process has not ended. Nothing stronger is sent. Look at the session where it runs. |
581
+ | Agent Lookout cannot confirm this process is that session, so it did not stop it. | Its file in `~/.claude/sessions` changed, or `ps` gave another start time, as when the process ID now belongs to another program. |
582
+ | That session has already ended. | It ended before Stop reached it. |
583
+ | Agent Lookout is not allowed to stop this process. | The process is another user's, or one Agent Lookout itself runs in or was started from, such as the session whose terminal started it. |
584
+
585
+ #### Which sessions have Stop
586
+
587
+ - A Claude Code session in a terminal of any app, tmux included, or in VS Code, whose file in `~/.claude/sessions` says it is an interactive session and records when its process started.
588
+ - A Claude Code background job, while Agent Lookout runs the `claude` command: not with `AGENT_LOOKOUT_CLAUDE_FEED=off`, and not with `AGENT_LOOKOUT_CLAUDE_HOME` set and `AGENT_LOOKOUT_CLAUDE_BIN` not.
589
+ - Not a session in Claude Code's desktop app, which looks after its own processes: its details say to stop it there. Not a session whose file does not say what kind it is, or which app it runs in.
590
+ - Not a Codex session, and not a session from a status file.
591
+
592
+ ### Sessions left running
593
+
594
+ Closing a Claude Code tab in VS Code can leave its process running, and the session then sits idle for days. Over the Sessions list, or the board, a band says how many Claude Code sessions have been idle for a day or more with their process still running: those Agent Lookout can stop, and those in the desktop app. Press Review… to list them, the longest idle first, each with its folder, its app and how long it has been idle, and Close to fold the list again. They stay in the list under Idle too.
595
+
596
+ Hide until it changes takes one out of Left running, in this browser only, until its status next changes. It does nothing to the session.
597
+
598
+ End all… lists each one again with a tick, all ticked, up to 20, which is as many as it ends at a time. Untick any you want to keep, and press End, which says how many it ends, such as End 3 sessions. Each one is stopped as Stop stops it, after the same checks, and only if it is still idle since the moment the list showed: a session that has done anything since is left running, even if it is idle again. A line then says what came of it, such as Ended 2. Left 1 running because it became active., and each row says what became of it. A session in the desktop app is listed with a line that says to stop it there, and has no tick.
599
+
600
+ To take Stop and the ending of sessions left running away altogether, start Agent Lookout with `AGENT_LOOKOUT_STOP=off`. [PRIVACY.md](../PRIVACY.md#stopping-a-session) says what Agent Lookout checks and runs to stop a session.
601
+
488
602
  ## Keyboard
489
603
 
490
604
  Every view answers to a few keys. Press `?` to see them all.
@@ -591,17 +705,18 @@ With `--json` it prints:
591
705
  }
592
706
  ```
593
707
 
594
- | Field | What it holds |
595
- | -------------------------------------- | --------------------------------------------------------------------------------- |
596
- | `counted` | `false` until an agent has been read, when the numbers below are not a count |
597
- | `needsYou`, `working`, `idle`, `stale` | How many sessions have each status, counted as above |
598
- | `waiting` | The sessions that need you, longest wait first |
599
- | `id` | The session's id, as `/api/sessions` gives it |
600
- | `name` | The session's name, exactly as its agent gave it |
601
- | `agent` | `Claude Code`, or the agent a [status file](#your-own-agents) names |
602
- | `reason` | `permission`, `question` or `other` |
603
- | `waitingSince` | When the wait began, in milliseconds since 1970, or `null` when that is not known |
604
- | `waitedMs` | How long it has waited, in milliseconds, or `null` |
708
+ | Field | What it holds |
709
+ | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
710
+ | `counted` | `false` until an agent has been read, when the numbers below are not a count |
711
+ | `needsYou`, `working`, `idle`, `stale` | How many sessions have each status, counted as above |
712
+ | `waiting` | The sessions that need you, longest wait first |
713
+ | `id` | The session's id, as `/api/sessions` gives it |
714
+ | `name` | The session's name, exactly as its agent gave it |
715
+ | `agent` | `Claude Code`, or the agent a [status file](#your-own-agents) names |
716
+ | `reason` | `permission`, `question` or `other` |
717
+ | `waitingSince` | When the wait began, in milliseconds since 1970, or `null` when that is not known |
718
+ | `waitedMs` | How long it has waited, in milliseconds, or `null` |
719
+ | `pullRequest` | With [pull requests](#pull-requests) on, `{ number, checks }` for its branch's pull request, with `checks` `failing`, `pending`, `passing` or `none`. Left out when there is none |
605
720
 
606
721
  Any character in a name that a terminal would act on is written as a `\u` escape, so the JSON is safe to print too.
607
722
 
@@ -658,7 +773,7 @@ The prompt then runs the command each time it is drawn, which adds about a tenth
658
773
 
659
774
  ## For your agents
660
775
 
661
- `agent-lookout mcp` lets an AI agent ask which sessions are running and which need you, so one agent can keep track of the others. It is a [Model Context Protocol](https://modelcontextprotocol.io) server. The agent's app starts it and speaks to it over stdin and stdout, so it listens on no port. It asks the Agent Lookout that is already running, the way `agent-lookout status` does, and starts nothing. Its tools only read: none of them can jump to a session, answer one or change a notification.
776
+ `agent-lookout mcp` lets an AI agent ask which sessions are running and which need you, so one agent can keep track of the others. It is a [Model Context Protocol](https://modelcontextprotocol.io) server. The agent's app starts it and speaks to it over stdin and stdout, so it listens on no port. It asks the Agent Lookout that is already running, the way `agent-lookout status` does, and starts nothing. Its tools only read: none of them can jump to a session, stop one, answer one or change a notification.
662
777
 
663
778
  To add it to Claude Code, run this once:
664
779
 
@@ -698,11 +813,11 @@ It finds Agent Lookout as `agent-lookout status` does: at `http://127.0.0.1:4777
698
813
 
699
814
  It has three tools:
700
815
 
701
- | Tool | Answers |
702
- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
703
- | `list_sessions` | Every session, those that need you first, longest wait first, then the rest by status, with its `id`, `name`, `agent`, `status`, the `reason` when it needs you, its `folder`, `branch` or `commit`, `app`, `since` and, for a working session, `quietFor`. Give it a `status` to list only those |
704
- | `sessions_needing_you` | The sessions that need you, longest wait first, with how long each has waited, and a `summary` in one sentence |
705
- | `sources` | Each source's state, as the Sources view says it, and its row of [what each agent can report](#what-each-agent-can-report), with the reason for each no and partly |
816
+ | Tool | Answers |
817
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
818
+ | `list_sessions` | Every session, those that need you first, longest wait first, then the rest by status, with its `id`, `name`, `agent`, `status`, the `reason` when it needs you, its `folder`, `branch` or `commit`, with [pull requests](#pull-requests) on its `pullRequest`, `app`, `since` and, for a working session, `quietFor`. Give it a `status` to list only those |
819
+ | `sessions_needing_you` | The sessions that need you, longest wait first, with how long each has waited, and a `summary` in one sentence |
820
+ | `sources` | Each source's state, as the Sources view says it, and its row of [what each agent can report](#what-each-agent-can-report), with the reason for each no and partly |
706
821
 
707
822
  Each answers in JSON. `sessions_needing_you` gives, for example:
708
823
 
@@ -720,6 +835,7 @@ Each answers in JSON. `sessions_needing_you` gives, for example:
720
835
  "folder": "storefront",
721
836
  "branch": null,
722
837
  "commit": null,
838
+ "pullRequest": null,
723
839
  "app": "VS Code",
724
840
  "since": "2026-10-06T09:09:48.000Z",
725
841
  "waited": "4m 12s",
@@ -730,7 +846,7 @@ Each answers in JSON. `sessions_needing_you` gives, for example:
730
846
  }
731
847
  ```
732
848
 
733
- Times are in ISO 8601. A field that is not known is `null`. `counted` is `false` until Agent Lookout has read an agent, when an empty list says nothing, and the summary says so. When an agent's sessions could not be read, such as Claude Code's, the summary names that agent and says its sessions are not counted. `quietFor` is how long a working session's agent has written nothing to the file it is read from, given whenever the agent's source gives that time. From 5 minutes it is what the Sessions list shows as [Quiet for](#quiet-for). Not every agent can report a wait: a Codex session waiting for your approval shows as working. `sources` says which can report what.
849
+ Times are in ISO 8601. A field that is not known is `null`. `counted` is `false` until Agent Lookout has read an agent, when an empty list says nothing, and the summary says so. When an agent's sessions could not be read, such as Claude Code's, the summary names that agent and says its sessions are not counted. `pullRequest` is `{ "number": 51, "checks": "failing" }` for a branch whose pull request Agent Lookout found, with `checks` one of `failing`, `pending`, `passing` and `none`, and `null` for every other session and whenever `AGENT_LOOKOUT_PULL_REQUESTS` is not `on`. It never holds the title, which someone else may have written. `quietFor` is how long a working session's agent has written nothing to the file it is read from, given whenever the agent's source gives that time. From 5 minutes it is what the Sessions list shows as [Quiet for](#quiet-for). Not every agent can report a wait: a Codex session waiting for your approval shows as working. `sources` says which can report what.
734
850
 
735
851
  A session's name, its agent's name, its folder and its branch are written by other programs, such as an agent that writes a [status file](#your-own-agents). The tools say so in their descriptions and in each answer, the summary puts each name in quotation marks, and anything a terminal would act on is taken out of them, as `agent-lookout status` does, and so is any character that shows nothing, in which words could be hidden from you but not from a model. An agent should still treat them as data, never as instructions.
736
852
 
@@ -799,13 +915,13 @@ These are macOS only:
799
915
  - Notifications with no dashboard tab open. On a Mac Agent Lookout shows those itself with `osascript`, which Linux does not have, so on Linux it shows none. Started with `AGENT_LOOKOUT_NOTIFICATIONS=on`, it prints a line saying so. Showing them with `notify-send` is left out for now. Keep a dashboard tab open to be notified.
800
916
  - [Jump to a tab of Terminal or iTerm2](#a-session-in-a-tab-of-terminal-or-iterm2), the two Mac apps it can bring forward. A session in a Linux terminal that is not running tmux has no Jump button.
801
917
 
802
- If the clock is set by more than a minute while a Claude Code session runs, that session can drop off the list until it is restarted. Linux's `ps` works out when a process started from the clock, so the start time it gives then no longer matches the one in the session's registry file, and the file looks like one a crashed session left behind.
918
+ If the clock is set by more than a minute while a Claude Code session runs, that session can drop off the list until it is restarted. Linux's `ps` works out when a process started from the clock, so the start time it gives then no longer matches the one in the session's registry file, and the file looks like one a crashed session left behind. Stop asks more, a start time within a second of the recorded one, so if the clock is set by more than a second, Stop says it cannot confirm that session's process until the session is restarted.
803
919
 
804
920
  Agent Lookout runs `ps` from `/usr/bin` or `/bin`. Where it is not there, as on NixOS, no session in tmux has a Jump button, and a registry file left behind by a session that crashed shows as a session if another program is given its process ID.
805
921
 
806
922
  ## What it does not do yet
807
923
 
808
- It cannot stop, resume or answer a session, and nor can an agent through [`agent-lookout mcp`](#for-your-agents), whose tools only read. It covers Claude Code and Codex, and any agent that writes a [status file](#your-own-agents), and only sessions on this computer. Cloud sessions, Codex cloud tasks and browser chats do not appear. [What each agent can report](#what-each-agent-can-report) has a table of what each agent can and cannot show.
924
+ It cannot resume or answer a session. It [stops](#stop-a-session) a Claude Code session only when you press Stop and confirm, and not one in the desktop app, a Codex session or a session from a status file. An agent through [`agent-lookout mcp`](#for-your-agents), whose tools only read, can do none of these. It covers Claude Code and Codex, and any agent that writes a [status file](#your-own-agents), and only sessions on this computer. Cloud sessions, Codex cloud tasks and browser chats do not appear. [What each agent can report](#what-each-agent-can-report) has a table of what each agent can and cannot show.
809
925
 
810
926
  A notification, an email or a post is sent for four events only: a session starting to wait, finishing, failing or ending. Only Claude Code sessions and sessions from a status file can be seen waiting. A Claude Code session that is not a background job does not say how it ended, so it sends Ended, never Finished or Failed. A Claude Code background job that starts and ends between two runs of the `claude` command, which is run every 30 seconds, leaves the list before the command lists it as finished, so it too sends Ended. A session from a Codex older than 0.155 is never shown as finished, so it sends Ended when it leaves the list, a day after it was last used. With no dashboard tab open, notifications are shown on a Mac only. Those come from Script Editor, unless Agent Lookout runs as the [desktop app](#desktop-app), cannot open the session, and are not cleared when the session moves on.
811
927
 
@@ -817,7 +933,7 @@ Codex sessions and sessions from status files have no Jump button. Nor do Claude
817
933
 
818
934
  Email and a webhook are the two ways it can tell you of a session away from this computer, and each sends to one address. A post is one line of text, with no buttons, and nothing can be answered from it. An email or a post that could not be sent is not tried again. The events are chosen when Agent Lookout starts, with `AGENT_LOOKOUT_EMAIL_EVENTS` and `AGENT_LOOKOUT_WEBHOOK_EVENTS`, and not in Settings.
819
935
 
820
- The Events log, the charts and the Timeline are kept in memory. They start empty each time Agent Lookout starts.
936
+ The history is kept for 8 days, but the charts show at most the last six hours of it, the Events log its newest 200 events, and Waits the last 7 days.
821
937
 
822
938
  A repository reached through a symbolic link by one session and by its real path from another is two groups of one name. A session's branch shows in the Sessions list, on its board card, in the Needs you panel, in the search and in the answers of `agent-lookout mcp`, and nowhere else: not in the Timeline, the Events log, a notification, an email, a webhook post or `agent-lookout status`. A repository in your home folder itself, as some people keep their settings in, is not looked in, so a session in a folder under it that is in no other repository shows no branch.
823
939
 
@@ -831,33 +947,39 @@ Put a setting in front of the command that starts Agent Lookout:
831
947
  AGENT_LOOKOUT_CLAUDE_FEED=off npx agent-lookout
832
948
  ```
833
949
 
834
- | Setting | What it does |
835
- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
836
- | `AGENT_LOOKOUT_PORT` | The port `npx agent-lookout`, `agent-lookout` and `npm start` listen on. The default is 4777. |
837
- | `AGENT_LOOKOUT_HOST` | The address `npx agent-lookout`, `agent-lookout` and `npm start` listen on: `127.0.0.1`, which is the default, `localhost` or `::1`. Anything else is refused, so other computers cannot reach it. |
838
- | `AGENT_LOOKOUT_CLAUDE_BIN` | The full path of the `claude` program. When set, it is the only place Agent Lookout looks. |
839
- | `AGENT_LOOKOUT_CLAUDE_HOME` | A folder to read in place of `~/.claude`. When set, the `claude` command is not run unless `AGENT_LOOKOUT_CLAUDE_BIN` is set too. |
840
- | `AGENT_LOOKOUT_CLAUDE_FEED` | Set to `off` and Agent Lookout never runs the `claude` command. Sessions come from the session files alone, and finished or failed background jobs are not listed. |
841
- | `AGENT_LOOKOUT_WAITING_TEXT` | Set to `off` and Agent Lookout never opens a Claude Code transcript. A waiting session then shows its reason alone, without what it is asking. |
842
- | `AGENT_LOOKOUT_CODEX_HOME` | A folder to read in place of the Codex folder. A folder with no `sessions` folder in it shows no Codex sessions. |
843
- | `CODEX_HOME` | Codex's own setting for where it keeps its files. When it is set, Agent Lookout reads that folder too, unless `AGENT_LOOKOUT_CODEX_HOME` is set. |
844
- | `AGENT_LOOKOUT_STATUS_DIR` | A folder of [status files](#your-own-agents) to read in place of `~/.agent-lookout/sessions`. |
845
- | `AGENT_LOOKOUT_NOTIFICATIONS` | Set to `on` and, on a Mac, Agent Lookout shows notifications of waits itself from the moment it starts. A dashboard page that has notifications off turns them off again. Anywhere else it prints a line saying it shows none itself. |
846
- | `AGENT_LOOKOUT_TMUX` | Set to `off` and Agent Lookout never runs `tmux`. Sessions in tmux are still listed, without a Jump button. |
847
- | `AGENT_LOOKOUT_TERMINAL_JUMP` | Set to `off` and Agent Lookout never looks for, or brings forward, a tab of Terminal or iTerm2. Sessions there are still listed, without a Jump button. |
848
- | `AGENT_LOOKOUT_EMAIL_TO` | The one address emails go to. With `AGENT_LOOKOUT_SMTP_URL` set too, it turns [email](#email) on. |
849
- | `AGENT_LOOKOUT_SMTP_URL` | The mail server emails go through, with the user name and password: `smtps://name:password@server:port`. |
850
- | `AGENT_LOOKOUT_EMAIL_FROM` | The address emails come from. The default is the address they go to. |
851
- | `AGENT_LOOKOUT_EMAIL_AFTER` | How many seconds a wait lasts before it is emailed, from 0 to 86400. The default is 60. |
852
- | `AGENT_LOOKOUT_EMAIL_EVENTS` | What is emailed: `needs-you`, `finished`, `failed` and `ended`, any of them, separated by commas. The default is `needs-you`. |
853
- | `AGENT_LOOKOUT_WEBHOOK_URL` | The one address [webhook](#webhook) posts go to, beginning with `https://`. It turns the webhook on. |
854
- | `AGENT_LOOKOUT_WEBHOOK_EVENTS` | What is posted, as for `AGENT_LOOKOUT_EMAIL_EVENTS`. The default is `needs-you`. |
855
- | `AGENT_LOOKOUT_WEBHOOK_AFTER` | How many seconds a wait lasts before it is posted, from 0 to 86400. The default is 60. |
856
- | `AGENT_LOOKOUT_URL` | The address `agent-lookout status` and `agent-lookout mcp` ask, such as `http://127.0.0.1:4778`, in place of `http://127.0.0.1:4777` and then `http://localhost:5173`. Only an address on this computer is accepted. Set it where the command runs, not where Agent Lookout starts. |
857
-
858
- To see the empty screen, set `AGENT_LOOKOUT_CLAUDE_HOME`, `AGENT_LOOKOUT_CODEX_HOME` and `AGENT_LOOKOUT_STATUS_DIR` to an empty folder. With only the first set, Codex sessions and sessions from status files still appear.
859
-
860
- The Claude Code, transcript, Codex, status file, notification, tmux, terminal tab, email and webhook settings work with `npx agent-lookout` and `agent-lookout`, and in a clone with `npm start` and `npm run dev`. The port and address settings apply to `npx agent-lookout`, `agent-lookout` and `npm start`, and `AGENT_LOOKOUT_URL` to `agent-lookout status` and `agent-lookout mcp` only. To choose the port for `npm run dev`, pass it after `--`:
950
+ | Setting | What it does |
951
+ | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
952
+ | `AGENT_LOOKOUT_PORT` | The port `npx agent-lookout`, `agent-lookout` and `npm start` listen on. The default is 4777. |
953
+ | `AGENT_LOOKOUT_HOST` | The address `npx agent-lookout`, `agent-lookout` and `npm start` listen on: `127.0.0.1`, which is the default, `localhost` or `::1`. Anything else is refused, so other computers cannot reach it. |
954
+ | `AGENT_LOOKOUT_CLAUDE_BIN` | The full path of the `claude` program. When set, it is the only place Agent Lookout looks. |
955
+ | `AGENT_LOOKOUT_CLAUDE_HOME` | A folder to read in place of `~/.claude`. When set, the `claude` command is not run unless `AGENT_LOOKOUT_CLAUDE_BIN` is set too. |
956
+ | `AGENT_LOOKOUT_CLAUDE_FEED` | Set to `off` and Agent Lookout never runs the `claude` command. Sessions come from the session files alone, and finished or failed background jobs are not listed. |
957
+ | `AGENT_LOOKOUT_WAITING_TEXT` | Set to `off` and Agent Lookout never opens a Claude Code transcript. A waiting session then shows its reason alone, without what it is asking. |
958
+ | `AGENT_LOOKOUT_CODEX_HOME` | A folder to read in place of the Codex folder. A folder with no `sessions` folder in it shows no Codex sessions. |
959
+ | `CODEX_HOME` | Codex's own setting for where it keeps its files. When it is set, Agent Lookout reads that folder too, unless `AGENT_LOOKOUT_CODEX_HOME` is set. |
960
+ | `AGENT_LOOKOUT_STATUS_DIR` | A folder of [status files](#your-own-agents) to read in place of `~/.agent-lookout/sessions`. |
961
+ | `AGENT_LOOKOUT_HISTORY` | Set to `off` and Agent Lookout keeps the Events log and the charts in memory only and writes nothing to disk, so they start empty each time it starts. See [History](#history). |
962
+ | `AGENT_LOOKOUT_HISTORY_DIR` | A folder to keep the [history](#history) in, in place of `~/.agent-lookout/history`. |
963
+ | `AGENT_LOOKOUT_NOTIFICATIONS` | Set to `on` and, on a Mac, Agent Lookout shows notifications of waits itself from the moment it starts. A dashboard page that has notifications off turns them off again. Anywhere else it prints a line saying it shows none itself. |
964
+ | `AGENT_LOOKOUT_TMUX` | Set to `off` and Agent Lookout never runs `tmux`. Sessions in tmux are still listed, without a Jump button. |
965
+ | `AGENT_LOOKOUT_TERMINAL_JUMP` | Set to `off` and Agent Lookout never looks for, or brings forward, a tab of Terminal or iTerm2. Sessions there are still listed, without a Jump button. |
966
+ | `AGENT_LOOKOUT_STOP` | Set to `off` and Agent Lookout never stops a session: no session has a Stop button, Left running has no End all…, and the server answers no request to stop one. |
967
+ | `AGENT_LOOKOUT_EMAIL_TO` | The one address emails go to. With `AGENT_LOOKOUT_SMTP_URL` set too, it turns [email](#email) on. |
968
+ | `AGENT_LOOKOUT_SMTP_URL` | The mail server emails go through, with the user name and password: `smtps://name:password@server:port`. |
969
+ | `AGENT_LOOKOUT_EMAIL_FROM` | The address emails come from. The default is the address they go to. |
970
+ | `AGENT_LOOKOUT_EMAIL_AFTER` | How many seconds a wait lasts before it is emailed, from 0 to 86400. The default is 60. |
971
+ | `AGENT_LOOKOUT_EMAIL_EVENTS` | What is emailed: `needs-you`, `finished`, `failed` and `ended`, any of them, separated by commas. The default is `needs-you`. |
972
+ | `AGENT_LOOKOUT_EMAIL_ASKING` | Set to `on` and the email for a wait says what the session is asking, such as `Run: npm test`, which can hold a command, a web address or a file's full path. The default is `off`. See [Email](#what-a-waiting-session-is-asking-by-email). |
973
+ | `AGENT_LOOKOUT_WEBHOOK_URL` | The one address [webhook](#webhook) posts go to, beginning with `https://`. It turns the webhook on. |
974
+ | `AGENT_LOOKOUT_WEBHOOK_EVENTS` | What is posted, as for `AGENT_LOOKOUT_EMAIL_EVENTS`. The default is `needs-you`. |
975
+ | `AGENT_LOOKOUT_WEBHOOK_AFTER` | How many seconds a wait lasts before it is posted, from 0 to 86400. The default is 60. |
976
+ | `AGENT_LOOKOUT_WEBHOOK_ASKING` | Set to `on` and the post for a wait says what the session is asking, as `AGENT_LOOKOUT_EMAIL_ASKING` does for email. The default is `off`. See [Webhook](#what-a-waiting-session-is-asking-in-a-post). |
977
+ | `AGENT_LOOKOUT_PULL_REQUESTS` | Set to `on` and Agent Lookout asks your own `gh` for each session's [pull request](#pull-requests) on github.com and its checks, and shows them. The default is `off`. With it on, the names of the repository and the branch go to GitHub, through `gh`, with `gh`'s own login. Any value but `on` or `off` leaves it off, and the card and the terminal name the setting |
978
+ | `AGENT_LOOKOUT_URL` | The address `agent-lookout status` and `agent-lookout mcp` ask, such as `http://127.0.0.1:4778`, in place of `http://127.0.0.1:4777` and then `http://localhost:5173`. Only an address on this computer is accepted. Set it where the command runs, not where Agent Lookout starts. |
979
+
980
+ To see the empty screen, set `AGENT_LOOKOUT_CLAUDE_HOME`, `AGENT_LOOKOUT_CODEX_HOME`, `AGENT_LOOKOUT_STATUS_DIR` and `AGENT_LOOKOUT_HISTORY_DIR` to an empty folder. With only the first set, Codex sessions and sessions from status files still appear.
981
+
982
+ The Claude Code, transcript, Codex, status file, history, notification, tmux, terminal tab, stop, email, webhook and pull request settings work with `npx agent-lookout` and `agent-lookout`, and in a clone with `npm start` and `npm run dev`. The port and address settings apply to `npx agent-lookout`, `agent-lookout` and `npm start`, and `AGENT_LOOKOUT_URL` to `agent-lookout status` and `agent-lookout mcp` only. To choose the port for `npm run dev`, pass it after `--`:
861
983
 
862
984
  ```sh
863
985
  npm run dev -- --port 5180
@@ -893,7 +1015,7 @@ It prints `{"ok":true,"version":"0.2.1"}`, or a later version number. If you run
893
1015
 
894
1016
  Every other setting under [Settings you can change](#settings-you-can-change) works with it as with `npm start`. It ends with 0 when you press Ctrl+C, and with 1 when it cannot start, such as when the port is in use. Under `npx agent-lookout`, the shell reports the interrupt instead, as exit code 130.
895
1017
 
896
- Agent Lookout is on npm, so `npx agent-lookout` starts it with nothing to clone or install first, and `npx agent-lookout --open` opens it in the browser as well. npm downloads the package the first time, about 30 MB with what it needs, and keeps it in its cache. The package holds the built dashboard and the collector as plain JavaScript, so it needs Node.js and nothing else. Each time, npx asks npm's registry whether a newer version is out, as it does for any package it runs. To start it without that, install it once with `npm install -g agent-lookout` and run `agent-lookout`.
1018
+ Agent Lookout is on npm, so `npx agent-lookout` starts it with nothing to clone or install first, and `npx agent-lookout --open` opens it in the browser as well. npm downloads the package the first time, under 2 MB with what it needs and about 4 MB once installed, and keeps it in its cache. The package holds the built dashboard and the collector as plain JavaScript, so it needs Node.js and nothing else. Each time, npx asks npm's registry whether a newer version is out, as it does for any package it runs. To start it without that, install it once with `npm install -g agent-lookout` and run `agent-lookout`.
897
1019
 
898
1020
  In a clone, run `npm run build` and `npm link` once in the `agent-lookout` folder, then `agent-lookout` from any folder.
899
1021
 
@@ -926,11 +1048,23 @@ It behaves as a Mac app does:
926
1048
  - Closing the window leaves it running, still watching your sessions and showing notifications. Click its icon in the Dock to open the window again. Cmd+Q quits it.
927
1049
  - With its window open or closed, its [notifications](#notifications) come from Agent Lookout, not from Script Editor, and clicking one opens the window.
928
1050
  - Its icon in the Dock shows how many sessions need you, with the window open or closed, and no number when none do.
1051
+ - Its icon in the menu bar shows the same count, and lists those sessions when you click it. Choose one to open its details. [Menu bar](#menu-bar) says more.
929
1052
  - Settings… in the Agent Lookout menu, or Cmd+comma, opens the Settings view. The Help menu opens this guide.
930
1053
  - Right-click selected text to copy it, or in the search field to cut, copy and paste.
931
1054
  - It opens where you left it, at the size you left it.
1055
+ - It keeps its [history](#history) in the same folder as `npx agent-lookout`, so the Events log and the charts carry over between the two.
932
1056
  - Check for Updates…, in the Agent Lookout menu under About, checks for a newer version at once. [Updates](#updates) says how.
933
1057
 
1058
+ ### Menu bar
1059
+
1060
+ The app puts the Agent Lookout mark in the menu bar, in the menu bar's own colour, light or dark. While one or more sessions need you, the small circle above its horizon, the lamp, is filled and the number of them is beside it, with the window open or closed. While none do, it is the mark alone, with the lamp hollow.
1061
+
1062
+ Click it to list the sessions that need you, the longest wait first, each with how long it has waited, as in `checkout-flow · 4m 12s`. Two sessions with the same name have what tells them apart in brackets, their agent, project, branch or app, as in `checkout-flow (Codex) · 4m 12s`. Under each name are the reason and what the session is asking, when that is known, cut to one line: rest the pointer on a session to read all of it. macOS shows the line under a name from macOS 14.4 on; before that, resting the pointer is the way to read it. Up to 10 sessions are listed, and a line under them counts the rest. Choose a session to open its [details](#a-sessions-details) in the window, which opens if it was closed. With nothing waiting, the menu says Nothing needs you, and before Agent Lookout has read any agent, Looking for agents…. It ends with Open Agent Lookout, Check for Updates…, Settings… and Quit Agent Lookout.
1063
+
1064
+ The times are those of the moment the pointer comes over the icon, or at most a minute old when you open the menu from the keyboard, and while it is open it stays as it is. A session that starts or stops waiting meanwhile shows the next time you open it, and the count beside the icon follows at once.
1065
+
1066
+ To take the icon out of the menu bar, open Settings and, under Menu bar, set Show in menu bar to Off. Set it to On to put it back. The app remembers the choice, and the count on the Dock icon stays either way. If macOS does not let the app put its icon there, the switch reads Off and the app's log, `~/Library/Logs/Agent Lookout/main.log`, says why.
1067
+
934
1068
  ### Updates
935
1069
 
936
1070
  The app can update itself from the project's [releases on GitHub](https://github.com/Olanetsoft/agent-lookout/releases). About once a day while it runs, it asks GitHub whether a newer version is out. It sends nothing about your sessions: GitHub sees the app's version number and your IP address, as with any web request. [Updates (Mac app only)](../PRIVACY.md#updates-mac-app-only) has the details. To turn it off, open Settings and, under Updates, set Check for updates automatically to Off. Check for Updates…, in the Agent Lookout menu and in Settings, checks at once either way. `npx agent-lookout` and the repository never check for anything.
@@ -953,6 +1087,16 @@ To work on the app, `npm run dev:desktop` builds it and opens it from `dist-elec
953
1087
 
954
1088
  ## When something goes wrong
955
1089
 
1090
+ ### It says it needs a newer Node.js
1091
+
1092
+ `npx agent-lookout` stops at once with one line, such as:
1093
+
1094
+ ```text
1095
+ Agent Lookout needs Node.js 22.12 or newer, and this is Node.js 20.19.4.
1096
+ ```
1097
+
1098
+ The `node` your terminal runs is older than that, and npm may also have printed `EBADENGINE Unsupported engine` as it installed the package. Install Node.js 22.12 or newer, from [nodejs.org](https://nodejs.org) or with a version manager, as `nvm install 22` does with nvm. Check that `node --version` prints `v22.12.0` or later, then start it again. `agent-lookout` says the same and exits with 1, and `agent-lookout status` exits with 2, so a script never takes it for a session that needs you. The [Mac app](#desktop-app) needs no Node.js.
1099
+
956
1100
  ### The port is in use
957
1101
 
958
1102
  `npx agent-lookout` stops with `Port 4777 is already in use`. Choose another port:
@@ -1009,6 +1153,10 @@ Use `http://localhost:5173` if you started it with `npm run dev`. It prints the
1009
1153
  3. If it says where posts go and nothing more, no wait has lasted the delay since Agent Lookout started. A session that was already waiting when it started sends nothing.
1010
1154
  4. If it says when the last post went, the service took it. Check the channel the webhook was made for, and that the app is still allowed to post there.
1011
1155
 
1156
+ ### No pull request shows
1157
+
1158
+ Pull requests are off unless Agent Lookout was started with `AGENT_LOOKOUT_PULL_REQUESTS=on`. The Pull requests card in Settings says whether they are on, and whether `gh` was found and is signed in: run `gh auth status` in a terminal to check, and `gh auth login` to sign in. A session shows one only when its branch has a pull request on github.com, its repository's remote is on github.com, and the branch is not the default one and is not named with digits alone, such as `51`. A new pull request, or a check that has finished, shows within about 2 minutes. The Mac app opened from the Finder or the Dock gets none of your shell's settings: [Desktop app](#desktop-app) says how to give it one.
1159
+
1012
1160
  ### The page says Agent Lookout has stopped updating
1013
1161
 
1014
1162
  The program serving the page has stopped. The page keeps the last thing it saw, under a notice that says how old it is, and its timers stop at the last moment it heard from Agent Lookout. Start it again with `npx agent-lookout`, or in a clone with `npm start` or `npm run dev`, and the page catches up on its own.