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/docs/GUIDE.md CHANGED
@@ -26,6 +26,8 @@ The Overview has six parts. The Needs you panel and the Last hour chart share th
26
26
 
27
27
  The Needs you panel holds the sessions that are waiting for you. For each one it gives the session's name, the reason, and where it runs: the project folder, the [git branch](#branches) when the folder is in a repository, the app, and the agent once more than one is found, as in `storefront on checkout-flow in VS Code · Claude Code`. An app that is not known is left out. The reason is waiting for permission, asked you a question or, for anything else, waiting for you. Under it, a Claude Code session says what it is asking, read from the last message of its transcript: the command it wants to run, as in `Run: npm test`, the file it wants to edit, write or read, as in `Edit: src/app.ts`, the address or search it wants, "Approve the plan", the tool it wants to use, or the question it put to you. A line too long for two lines is cut, and hover over it or move to it with Tab to read all of it. When Claude Code's own words say more than the reason, hover over the reason or move to it with Tab to read them. The folder's full path is shown the same way. A timer says how long the session has waited, and a Claude Code session that runs in VS Code, inside tmux or in a tab of Terminal or iTerm2 has a Jump button. [Jump](#jump) says what it does for each. With more than one waiting, the longest wait comes first and the others are listed under it. Click a session's name, or move to it with Tab and press Enter, to open its [details](#a-sessions-details).
28
28
 
29
+ With the Agent Lookout plugin installed in Claude Code, a Claude Code session waiting for permission shows the whole of what it asks in place of that line: every line of the command it wants to run, with its description, or the tool and each of its inputs. Deny and Allow sit under it. [Answer a permission prompt](#answer-a-permission-prompt) says what each does.
30
+
29
31
  Under the sessions, Waited on you has a bar for each session that waited, longest first. A wait that is still open is a filled amber bar that grows each second. A wait that was answered is an outlined bar. The bars reach back no further than the last hour, nor before Agent Lookout started, and the heading says from when. The line under them says how much of that time Agent Lookout did not measure. When no session waited in that time, the bars are left out.
30
32
 
31
33
  The panel ends with four counts.
@@ -62,7 +64,9 @@ The Sessions list holds every session that is not waiting for you, grouped in th
62
64
 
63
65
  When the list is too narrow for every column, the app is left out first and then the folder with its branch, so names keep their room. In a narrow window both are left out and the status moves under the name. The Needs you panel still gives the branch of each session that needs you.
64
66
 
65
- A Claude Code session in VS Code, inside tmux or in a tab of Terminal or iTerm2 has a Jump button here too.
67
+ A Claude Code session in VS Code, inside tmux or in a tab of Terminal or iTerm2 has a Jump button here too. A Claude Code background job that has finished, failed or been stopped has a [Resume](#resume-a-session) button in the same place.
68
+
69
+ Claude Code sessions idle for a day or more, or as long as the [idle rule](#time-rules) says, 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).
66
70
 
67
71
  Click a row, or move to its name with Tab and press Enter, to open the session's [details](#a-sessions-details).
68
72
 
@@ -79,7 +83,7 @@ Board shows the same sessions in a column for each status, so you can see at a g
79
83
  | Idle | Sessions ready for a new prompt, then stale ones with their own mark. The heading counts them apart: `Idle 1 Stale 1` |
80
84
  | Finished or failed | Sessions that finished or failed, failures first |
81
85
 
82
- Each card gives what a row of the list does: the session's name, its folder and [branch](#branches), as in `storefront on checkout-flow`, the app it runs in when it is known, the agent once there is more than one, its status and how long it has had it, and [Quiet for](#quiet-for) when that applies. A session that has a Jump button in the list has one on its card, and it works the same way. A long name is cut, and the whole name shows when you hover over it or move to it with Tab. Click a card, or move to its name and press Enter, to open the session's [details](#a-sessions-details).
86
+ Each card gives what a row of the list does: the session's name, its folder and [branch](#branches), as in `storefront on checkout-flow`, the app it runs in when it is known, the agent once there is more than one, its status and how long it has had it, and [Quiet for](#quiet-for) when that applies. A session that has a Jump or a Resume button in the list has one on its card, and it works the same way. A long name is cut, and the whole name shows when you hover over it or move to it with Tab. Click a card, or move to its name and press Enter, to open the session's [details](#a-sessions-details).
83
87
 
84
88
  When a card's folder is named other than its repository, as a worktree's usually is, the card names the repository first: `storefront · storefront-checkout on checkout-flow`. The repository's name, the folder and the branch then take a line each when the column is too narrow for them side by side.
85
89
 
@@ -101,12 +105,13 @@ The details show everything Agent Lookout knows about the session:
101
105
  - its agent, and the app it runs in when that is known
102
106
  - the full path of its folder, which you can select and copy
103
107
  - its [repository](#repositories), and its [branch](#branches) or the commit when no branch is checked out
108
+ - 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
109
  - when it started and its process ID, when its agent reports them
105
110
  - 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
111
  - its own events, newest first, as the Events log shows them
107
112
  - its row of the Timeline over the last hour
108
113
 
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.
114
+ 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. A session that can be [resumed](#resume-a-session) has Resume there instead, with the command it copies at the top of the details. A session with a permission prompt Agent Lookout holds shows it at the top of its details, with [Allow and Deny](#answer-a-permission-prompt).
110
115
 
111
116
  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
117
 
@@ -159,9 +164,31 @@ git worktree add ../storefront-billing -b billing-webhooks
159
164
 
160
165
  Repos then lists both sessions under `storefront`, each with its own folder and branch.
161
166
 
167
+ #### Pull requests
168
+
169
+ 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`.
170
+
171
+ ```sh
172
+ AGENT_LOOKOUT_PULL_REQUESTS=on npx agent-lookout
173
+ ```
174
+
175
+ 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.
176
+
177
+ With it on:
178
+
179
+ - 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.
180
+ - 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.
181
+ - `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.
182
+
183
+ 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`.
184
+
185
+ 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.
186
+
187
+ 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.
188
+
162
189
  #### Events
163
190
 
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 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.
191
+ 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
192
 
166
193
  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
194
 
@@ -189,15 +216,17 @@ The card for status files gives the folder it reads, normally `~/.agent-lookout/
189
216
 
190
217
  When an agent is not on this computer, its card says Not found, and after the first few seconds the Overview does not mention it, unless neither is found.
191
218
 
219
+ Each [other machine](#another-machine-over-ssh) named in `AGENT_LOOKOUT_REMOTES` has a card too, titled with its name. It says Connected, Connecting or Not connected, and why when it is not, and its rows give the ssh target, the command Agent Lookout runs, the two routes it asks for, how often, the version of Agent Lookout there and what each source there is doing.
220
+
192
221
  #### What each agent can report
193
222
 
194
- 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.
223
+ 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) and [Answer](#answer-a-permission-prompt), 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.
195
224
 
196
- | Agent | Working and idle | Needs you | Finished | Failed | Names | Jump | Quiet for |
197
- | ------------ | ---------------- | --------- | -------- | ------ | ------ | ------ | --------- |
198
- | Claude Code | Yes | Yes | Partly | Partly | Yes | Partly | No |
199
- | Codex | Yes | No | Partly | No | Partly | No | Yes |
200
- | Status files | Partly | Partly | Partly | Partly | Partly | No | Partly |
225
+ | Agent | Working and idle | Needs you | Finished | Failed | Names | Jump | Quiet for | Stop | Answer |
226
+ | ------------ | ---------------- | --------- | -------- | ------ | ------ | ------ | --------- | ------ | ------ |
227
+ | Claude Code | Yes | Yes | Partly | Partly | Yes | Partly | No | Partly | Partly |
228
+ | Codex | Yes | No | Partly | No | Partly | No | Yes | No | No |
229
+ | Status files | Partly | Partly | Partly | Partly | Partly | No | Partly | No | No |
201
230
 
202
231
  Why, for each No and Partly:
203
232
 
@@ -205,11 +234,15 @@ Why, for each No and Partly:
205
234
  - Claude Code, Failed: Only background jobs. Any other session leaves the list without saying how it ended.
206
235
  - 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.
207
236
  - Claude Code, Quiet for: The file Agent Lookout reads is not rewritten as a session works.
237
+ - Claude Code, Stop: In a terminal, in VS Code and for background jobs. Not in the desktop app.
238
+ - Claude Code, Answer: With the Agent Lookout plugin installed. Allow only when all it allows is shown, so edits, plans and questions can only be denied.
208
239
  - Codex, Needs you: Codex does not record approval waits, so a session waiting for you shows as working.
209
240
  - Codex, Finished: From Codex 0.155 on, once no Codex program has the session open.
210
241
  - Codex, Failed: Codex does not record errors in its files.
211
242
  - 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.
212
243
  - Codex, Jump: Codex's files name no process to find, and Codex documents no link to a session.
244
+ - Codex, Stop: Codex's files name no process that Agent Lookout could confirm and stop.
245
+ - Codex, Answer: Codex records no approval waits, so there is nothing to answer from here.
213
246
  - Status files, Working and idle: If the agent writes working and idle.
214
247
  - Status files, Needs you: If the agent writes waiting.
215
248
  - Status files, Finished: If the agent writes finished.
@@ -217,10 +250,14 @@ Why, for each No and Partly:
217
250
  - Status files, Names: If the agent writes a name. Otherwise the folder's or the file's name is used.
218
251
  - Status files, Jump: Nothing in a status file is used to reach a session.
219
252
  - Status files, Quiet for: If the agent writes its file again as it works.
253
+ - Status files, Stop: Any program can write a status file, so nothing in one is used to stop a session.
254
+ - Status files, Answer: A status file only says a session waits, and holds nothing to answer it through.
255
+
256
+ Each [other machine](#another-machine-over-ssh) adds a row for each agent found there, such as Claude Code on devbox, with what that machine's Agent Lookout says its agent can report, and No for Jump, Stop and Answer, which act on this computer only.
220
257
 
221
258
  ### Settings
222
259
 
223
- Settings has six 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. 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.
260
+ Settings has nine 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. [Time rules](#time-rules) reminds you of a long wait, sets how long a session is idle before it is stale, and holds everything back during quiet hours. 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. Permission prompts says whether Allow and Deny are offered, and whether the [plugin](#install-the-plugin)'s requests reach Agent Lookout. 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.
224
261
 
225
262
  #### Notifications
226
263
 
@@ -279,6 +316,22 @@ A notification shows the session's name outside the dashboard: over other apps,
279
316
 
280
317
  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.
281
318
 
319
+ #### Time rules
320
+
321
+ The Time rules card has three rules, each with an Off and On switch, and all three are off until you turn them on. Agent Lookout keeps them in `~/.agent-lookout/settings.json`, so they hold with no dashboard tab open and after a restart. A change takes effect at once. The card shows what Agent Lookout saved: if a change could not be saved, a note says why and the switch stays as it was. A field is read when you leave it or press Enter, and Escape puts back what it held.
322
+
323
+ Remind me of a long wait sends a reminder once a session has waited the minutes you set: 10 unless you change them, from 1 to 1,440. It goes once for each wait, the way the wait's first notice went: as a notification while Needs you is switched on, as an email or a webhook post while `needs-you` is among the events those send. It says how long the session has waited. The notification reads "Has waited 10 minutes for permission" under the session's name, takes the place of the wait's own, and is cleared when the session moves on. The email's subject and the post's line say "checkout-flow has waited 10 minutes for permission", and the post has `reminder: true`. A wait that had already gone on longer when the page opened, or when Agent Lookout started, is not reminded of, and nor is one whose first email or post went only once it had waited that long, since that one says how long already. Set more minutes while a session waits, and it is reminded of again once it has waited those.
324
+
325
+ Mark idle sessions stale sets how long a session is idle before it is stale, in hours or days, from an hour to 30 days: 2 days unless you change them. A stale session is counted under Stale rather than Idle, its idle line in the Timeline turns to dots where it became stale, and a Claude Code session among them whose process still runs is listed under [Left running](#sessions-left-running), where it can be ended. With the rule off, a session is stale after a day.
326
+
327
+ Quiet hours hold back every notification, email and post between two times on your computer's clock: 22:00 to 08:00 unless you change them. When the end comes before the start, they run past midnight, and the days you tick are the days they begin on: with Monday to Friday ticked, Friday night is quiet until Saturday morning, and Saturday night is not. With no day ticked they never begin. When they end, a session still waiting is notified as usual, and everything else held comes as one summary on each channel, such as "While quiet: checkout-flow waited 25 minutes, docs-site waited 1 hour 5 minutes over 2 waits and billing-webhooks finished": one notification headed While quiet, which stays until you clear it, one email and one webhook post. A session that waited and then finished, failed or ended is one item, as in "checkout-flow waited 25 minutes then ended". Each summary holds what its channel would have sent, so a wait answered before the email's delay was up is in no email. Turn on Leave answered waits out of the summary and it names only the sessions that finished, failed or ended. With nothing to say, there is no summary. Turning quiet hours off while they hold ends them at once. While they hold, a line under the times says so: "Quiet now, until 08:00. Notifications, emails and posts are held." In the Mac app, the notice of a new version waits for them to end too.
328
+
329
+ The rules apply on top of the switches under Notifications, and of the settings for [email](#email) and the [webhook](#webhook), which still choose what goes where. Quiet hours go by the clock and time zone of the computer Agent Lookout runs on, and a dashboard tab follows what Agent Lookout says, so a tab in another time zone holds and sums up at the same moments. A dashboard tab opened during quiet hours sums up what happened after it opened. With no tab open, Agent Lookout shows its own summary on a Mac, and it covers all of the quiet hours. The rules set here cover the sessions of [another machine](#another-machine-over-ssh) too, as they cover this computer's.
330
+
331
+ What quiet hours hold is kept in memory only. If Agent Lookout is stopped or restarted while they hold, what it held so far is forgotten: no summary comes of those hours, and a session that began waiting before the restart and still waits is not notified when they end. With the long wait reminder on, it is still reminded of, if it had not yet waited the reminder's minutes at the restart.
332
+
333
+ `AGENT_LOOKOUT_SETTINGS_FILE` keeps the rules in another file. Agent Lookout reads the file as it starts and writes it whole when you change a rule, with mode 600, in a folder it makes with mode 700, and never through a link. If it cannot read the file, the rules it holds are off, the card says why in a note, and the terminal you started Agent Lookout in prints the same line. A file that is not JSON is written again by your first change. One it could not read at all, such as one larger than 64 KB, is never written over: a change is not saved until you mend or remove the file and start Agent Lookout again. [PRIVACY.md](../PRIVACY.md#the-settings-file) says what the file holds.
334
+
282
335
  #### History
283
336
 
284
337
  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.
@@ -538,6 +591,90 @@ In the [desktop app](#desktop-app) the collector runs inside Agent Lookout itsel
538
591
 
539
592
  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.
540
593
 
594
+ ## Stop a session
595
+
596
+ 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.
597
+
598
+ 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.
599
+
600
+ 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. The details then offer [Resume](#resume-a-session), until you close them.
601
+
602
+ | What the details say | Why |
603
+ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
604
+ | Stopped. Its process has ended, and its conversation is kept. | It worked. |
605
+ | 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. |
606
+ | 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. |
607
+ | That session has already ended. | It ended before Stop reached it. |
608
+ | 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. |
609
+
610
+ #### Which sessions have Stop
611
+
612
+ - 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.
613
+ - 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.
614
+ - 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.
615
+ - Not a Codex session, and not a session from a status file.
616
+
617
+ ### Sessions left running
618
+
619
+ 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, or as long as the [idle rule](#time-rules) says while it is on: 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.
620
+
621
+ 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.
622
+
623
+ 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.
624
+
625
+ 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.
626
+
627
+ ## Resume a session
628
+
629
+ A Claude Code session that has ended can be continued with `claude --resume` and its session ID. Its Resume button copies the command that does it, such as:
630
+
631
+ ```sh
632
+ cd '/Users/example/code/storefront' && claude --resume 6f1c2d3e-4a5b-4c6d-8e7f-0a1b2c3d4e5f
633
+ ```
634
+
635
+ Paste it in a terminal and run it. It goes to the session's folder first, because Claude Code keeps a conversation under the folder it ran in, so it works from any folder. The folder is in single quotes, so one with spaces, quotes or `$` in its name works in sh, bash and zsh, and `&&` keeps `claude` from starting anywhere else when the folder has gone. Agent Lookout runs nothing: it puts the text on the clipboard. For two seconds the button says Copied. Hover over it, or move to it with Tab, to see the command. In a session's details the command is shown in full under the head, so you can read it, or select it, before you run it. If the browser or the Mac app does not let the page write to the clipboard, a line says Not copied, and the command is shown to select and copy by hand: under the session's name in the list and on the board, and in the details under the command.
636
+
637
+ #### Which sessions have Resume
638
+
639
+ - A Claude Code background job that Claude Code lists as finished, failed or stopped, with its process gone, for as long as its row stays: 24 hours. These come from the `claude` command, so they are not listed with `AGENT_LOOKOUT_CLAUDE_FEED=off`.
640
+ - A Claude Code session you stopped with [Stop](#stop-a-session), in its details, once Stop has said it stopped, until you close them, or until the list shows it running again, as a background job does once `claude attach` opens it.
641
+ - Only when Claude Code gave the session's ID, a UUID, and its folder is known as a whole path. A job listed without its session ID has no Resume, and nor does a folder holding a line break or another control character, or a backslash, which fish would read inside the quotes.
642
+ - Not a session whose process still runs: resuming it would open a second copy of the same conversation. Not one that left the list on its own, since Agent Lookout cannot tell whether its process ended. Not a Codex session, and not a session from a status file.
643
+
644
+ ## Answer a permission prompt
645
+
646
+ With the Agent Lookout plugin installed in Claude Code, a Claude Code session that waits for your permission shows Deny and Allow in the [Needs you](#needs-you) panel and at the top of its [details](#a-sessions-details). Above them is the whole of what it asks: for a shell command, every line of the command, in the mono, with any other input such as `run_in_background` and then the description Claude gave it, and for any other tool, its name and each of its inputs. While Allow is offered, all of it is drawn, however many lines it has. Press Allow to let that one request go ahead, or Deny to refuse it. Deny comes first, so it is in the same place whether Allow is offered or not. Neither button has focus until you move to it, and neither takes a press in the first second a request is shown, so a click meant for what was there before is not taken as an answer. A line then says what came of it, and the Events log says the session had a request allowed or denied from Agent Lookout. When the session asks again, its next request is shown under that line.
647
+
648
+ The prompt in the session is still there, and still works: whichever you answer first wins. Answered in the session, the request leaves the dashboard within a few seconds. A Deny from the dashboard lets Claude carry on without the tool, and tells it that you denied it from Agent Lookout, while No in the terminal stops the turn.
649
+
650
+ Allow is offered only when the whole of what it allows is shown. Deny alone is offered, with a line that says why, for an edit, a new file or a notebook edit, since the change itself is not shown, for a plan or a question, which take more than yes or no, for a request longer than 4,000 characters or 40 lines, for one that holds characters that cannot be shown as they are, which are written as their codes, for one with more than two blank lines in a row, which could push what follows out of sight, and for a command holding right-to-left letters, such as Hebrew or Arabic, which can draw it in another order than it runs. Agent Lookout allows or denies that one request and nothing more: it never changes the command and never saves a rule, so "Yes, and don't ask again" is answered in the session. Claude Code's own deny rules still apply after an Allow.
651
+
652
+ A request waits for an answer for 5 minutes, or `AGENT_LOOKOUT_ANSWER_WAIT` seconds, and then leaves the dashboard, and the prompt in the session decides. It also leaves when the session stops waiting, or ends. With Agent Lookout not running, the plugin does nothing and Claude Code asks as usual.
653
+
654
+ | What it says | Why |
655
+ | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
656
+ | Allowed from Agent Lookout. | Claude Code was told to allow it. |
657
+ | Denied from Agent Lookout. Claude carries on without it. | Claude Code was told to deny it. |
658
+ | It was answered in the session, or is no longer waiting, so nothing was sent. | You answered in the session first, or it stopped waiting before the answer reached it. |
659
+ | That request is no longer held, so nothing was sent. | It waited longer than Agent Lookout holds a request, or a newer one replaced it. |
660
+ | Agent Lookout did not answer in time. The session shows whether it went on. | Agent Lookout gave no answer within 10 seconds. The answer may have reached it all the same. |
661
+ | The answer could not be handed to the session. | Something went wrong in Agent Lookout. Nothing more is known of it. |
662
+
663
+ ### Install the plugin
664
+
665
+ The plugin is one hook that Claude Code runs as it is about to ask you for permission. It hands the request to Agent Lookout on this computer, over a socket only you can open, and prints the answer when you press Allow or Deny. It is in this repository, in `plugins/agent-lookout/`. In Claude Code, run:
666
+
667
+ ```text
668
+ /plugin marketplace add Olanetsoft/agent-lookout
669
+ /plugin install agent-lookout@agent-lookout
670
+ ```
671
+
672
+ From a shell, `claude plugin marketplace add Olanetsoft/agent-lookout` and `claude plugin install agent-lookout@agent-lookout` do the same. Claude Code records the plugin in its own settings, and runs its hook wherever Claude Code runs: in a terminal, in VS Code and in the desktop app. Agent Lookout itself writes nothing under `~/.claude`. To take it away, run `/plugin uninstall agent-lookout@agent-lookout`. The hook needs `curl`, which macOS has, and most Linux systems do.
673
+
674
+ Settings, under Permission prompts, says whether the plugin's requests reach Agent Lookout. When a Claude Code session waits for permission and no request comes, it says the plugin may not be installed.
675
+
676
+ To take Allow and Deny away altogether, start Agent Lookout with `AGENT_LOOKOUT_ANSWER=off`. [PRIVACY.md](../PRIVACY.md#the-claude-code-plugin-and-permission-prompts) says what the plugin sends, what Agent Lookout keeps and what it checks before it answers.
677
+
541
678
  ## Keyboard
542
679
 
543
680
  Every view answers to a few keys. Press `?` to see them all.
@@ -636,6 +773,7 @@ With `--json` it prints:
636
773
  "id": "claude-code:00000000-0000-4000-8000-000000000001",
637
774
  "name": "checkout-flow",
638
775
  "agent": "Claude Code",
776
+ "machine": null,
639
777
  "reason": "permission",
640
778
  "waitingSince": 1791205668000,
641
779
  "waitedMs": 252000
@@ -644,17 +782,19 @@ With `--json` it prints:
644
782
  }
645
783
  ```
646
784
 
647
- | Field | What it holds |
648
- | -------------------------------------- | --------------------------------------------------------------------------------- |
649
- | `counted` | `false` until an agent has been read, when the numbers below are not a count |
650
- | `needsYou`, `working`, `idle`, `stale` | How many sessions have each status, counted as above |
651
- | `waiting` | The sessions that need you, longest wait first |
652
- | `id` | The session's id, as `/api/sessions` gives it |
653
- | `name` | The session's name, exactly as its agent gave it |
654
- | `agent` | `Claude Code`, or the agent a [status file](#your-own-agents) names |
655
- | `reason` | `permission`, `question` or `other` |
656
- | `waitingSince` | When the wait began, in milliseconds since 1970, or `null` when that is not known |
657
- | `waitedMs` | How long it has waited, in milliseconds, or `null` |
785
+ | Field | What it holds |
786
+ | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
787
+ | `counted` | `false` until an agent has been read, when the numbers below are not a count |
788
+ | `needsYou`, `working`, `idle`, `stale` | How many sessions have each status, counted as above |
789
+ | `waiting` | The sessions that need you, longest wait first |
790
+ | `id` | The session's id, as `/api/sessions` gives it |
791
+ | `name` | The session's name, exactly as its agent gave it |
792
+ | `agent` | `Claude Code`, or the agent a [status file](#your-own-agents) names |
793
+ | `machine` | The [other machine](#another-machine-over-ssh) it runs on, such as `devbox`, or `null` for this computer. Its line in the text says `on devbox` after the name |
794
+ | `reason` | `permission`, `question` or `other` |
795
+ | `waitingSince` | When the wait began, in milliseconds since 1970, or `null` when that is not known |
796
+ | `waitedMs` | How long it has waited, in milliseconds, or `null` |
797
+ | `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 |
658
798
 
659
799
  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.
660
800
 
@@ -711,7 +851,7 @@ The prompt then runs the command each time it is drawn, which adds about a tenth
711
851
 
712
852
  ## For your agents
713
853
 
714
- `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.
854
+ `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.
715
855
 
716
856
  To add it to Claude Code, run this once:
717
857
 
@@ -751,11 +891,11 @@ It finds Agent Lookout as `agent-lookout status` does: at `http://127.0.0.1:4777
751
891
 
752
892
  It has three tools:
753
893
 
754
- | Tool | Answers |
755
- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
756
- | `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 |
757
- | `sessions_needing_you` | The sessions that need you, longest wait first, with how long each has waited, and a `summary` in one sentence |
758
- | `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 |
894
+ | Tool | Answers |
895
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
896
+ | `list_sessions` | Every session, those that need you first, longest wait first, then the rest by status, with its `id`, `name`, `agent`, the `machine` it runs on, or `null` for this computer, `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 |
897
+ | `sessions_needing_you` | The sessions that need you, longest wait first, with how long each has waited, and a `summary` in one sentence |
898
+ | `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 |
759
899
 
760
900
  Each answers in JSON. `sessions_needing_you` gives, for example:
761
901
 
@@ -769,10 +909,12 @@ Each answers in JSON. `sessions_needing_you` gives, for example:
769
909
  "id": "status-files:checkout-flow.json",
770
910
  "name": "checkout-flow",
771
911
  "agent": "Night Shift",
912
+ "machine": null,
772
913
  "reason": "permission",
773
914
  "folder": "storefront",
774
915
  "branch": null,
775
916
  "commit": null,
917
+ "pullRequest": null,
776
918
  "app": "VS Code",
777
919
  "since": "2026-10-06T09:09:48.000Z",
778
920
  "waited": "4m 12s",
@@ -783,7 +925,7 @@ Each answers in JSON. `sessions_needing_you` gives, for example:
783
925
  }
784
926
  ```
785
927
 
786
- 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.
928
+ Times are in ISO 8601. A field that is not known is `null`. A session on [another machine](#another-machine-over-ssh) has that machine's name in `machine`, and the summary says it after the name, `"checkout-flow" on devbox`: its `folder` is on that machine, not this one. `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.
787
929
 
788
930
  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.
789
931
 
@@ -812,6 +954,109 @@ echo "Deleted: the session has gone"
812
954
 
813
955
  The session appears in Sessions as `docs-site`, in Terminal, moves to Needs you as Asked you a question, and leaves the list when the file is deleted. Once there is more than one agent on the screen, each row names its own, here `my-agent`. If you set `AGENT_LOOKOUT_STATUS_DIR`, put that folder in the first line instead.
814
956
 
957
+ An agent written in Python or JavaScript can do the same from its own code. In each example below, `report` writes the file with the agent's own process ID in `pid`. The agent calls it as its work starts, when it waits for you and when it works again, and the file is deleted when the program ends, even when Ctrl-C, `kill` or closing its terminal stops it. Both write to `AGENT_LOOKOUT_STATUS_DIR` when it is set, and to `~/.agent-lookout/sessions` otherwise, and make the folder when it is not there.
958
+
959
+ In Python 3.8 or later, save this as `my_agent.py` and run `python3 my_agent.py`:
960
+
961
+ ```python
962
+ import atexit
963
+ import json
964
+ import os
965
+ import signal
966
+ import sys
967
+ import time
968
+ from pathlib import Path
969
+
970
+ default = Path.home() / ".agent-lookout" / "sessions"
971
+ folder = Path(os.environ.get("AGENT_LOOKOUT_STATUS_DIR") or default)
972
+ status_file = folder / "my-agent.json"
973
+ last = {"status": None, "since": None}
974
+
975
+
976
+ def report(status, reason=None):
977
+ # since is when this status began, so it changes only with the status.
978
+ if status != last["status"]:
979
+ last.update(status=status, since=round(time.time() * 1000))
980
+ fields = {
981
+ "agent": "my-agent",
982
+ "name": "docs-site",
983
+ "cwd": os.getcwd(),
984
+ "status": status,
985
+ "reason": reason,
986
+ "since": last["since"],
987
+ "app": "terminal",
988
+ "pid": os.getpid(),
989
+ }
990
+ folder.mkdir(parents=True, exist_ok=True)
991
+ # Written whole under a name that starts with a dot, which is never read, then renamed.
992
+ temp = folder / ".my-agent.json"
993
+ temp.write_text(json.dumps(fields))
994
+ os.replace(temp, status_file)
995
+
996
+
997
+ atexit.register(lambda: status_file.unlink(missing_ok=True))
998
+ # On kill or a closed terminal, end the program as on Ctrl-C, so the file is deleted then too.
999
+ for signum in (signal.SIGTERM, signal.SIGHUP):
1000
+ signal.signal(signum, lambda number, frame: sys.exit(128 + number))
1001
+
1002
+ report("working") # As the work starts.
1003
+ time.sleep(8)
1004
+ report("waiting", "question") # When it needs you.
1005
+ time.sleep(8)
1006
+ report("working") # When it works again.
1007
+ time.sleep(8)
1008
+ ```
1009
+
1010
+ In Node.js 18 or later, save this as `my-agent.mjs` and run `node my-agent.mjs`:
1011
+
1012
+ ```js
1013
+ import fs from "node:fs";
1014
+ import os from "node:os";
1015
+ import path from "node:path";
1016
+
1017
+ const folder =
1018
+ process.env.AGENT_LOOKOUT_STATUS_DIR || path.join(os.homedir(), ".agent-lookout", "sessions");
1019
+ const statusFile = path.join(folder, "my-agent.json");
1020
+ const last = { status: null, since: null };
1021
+
1022
+ function report(status, reason) {
1023
+ // since is when this status began, so it changes only with the status.
1024
+ if (status !== last.status) Object.assign(last, { status, since: Date.now() });
1025
+ const fields = {
1026
+ agent: "my-agent",
1027
+ name: "docs-site",
1028
+ cwd: process.cwd(),
1029
+ status,
1030
+ reason,
1031
+ since: last.since,
1032
+ app: "terminal",
1033
+ pid: process.pid,
1034
+ };
1035
+ fs.mkdirSync(folder, { recursive: true });
1036
+ // Written whole under a name that starts with a dot, which is never read, then renamed.
1037
+ const temp = path.join(folder, ".my-agent.json");
1038
+ fs.writeFileSync(temp, JSON.stringify(fields));
1039
+ fs.renameSync(temp, statusFile);
1040
+ }
1041
+
1042
+ process.on("exit", () => fs.rmSync(statusFile, { force: true }));
1043
+ // On Ctrl-C, kill or a closed terminal, end the program the usual way, so the file is deleted.
1044
+ for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
1045
+ process.on(signal, () => process.exit(128 + os.constants.signals[signal]));
1046
+ }
1047
+
1048
+ const wait = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1000));
1049
+
1050
+ report("working"); // As the work starts.
1051
+ await wait(8);
1052
+ report("waiting", "question"); // When it needs you.
1053
+ await wait(8);
1054
+ report("working"); // When it works again.
1055
+ await wait(8);
1056
+ ```
1057
+
1058
+ Each shows `docs-site` working, then in Needs you as Asked you a question, then working again, for 8 seconds each, and the session leaves the list as the program ends. A program killed outright, as with `kill -9`, cannot delete its file, and `pid` covers that: Agent Lookout sees the process has gone and drops the session within about 2 seconds. While your agent works, have it call `report` again now and then with the same status, so the session is not shown as quiet.
1059
+
815
1060
  | Field | Needed | What it holds |
816
1061
  | -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
817
1062
  | `agent` | Yes | The agent's name, shown wherever the agent is named, such as `my-agent`. Up to 40 characters are kept. |
@@ -835,6 +1080,54 @@ The session appears in Sessions as `docs-site`, in Terminal, moves to Needs you
835
1080
 
836
1081
  Agent Lookout only reads the folder. It never makes it, and never writes, renames or deletes anything in it. When a session ends, delete its file, or write `finished` or `failed` to keep it on screen for a day and delete the file after that, for example the next time the agent starts. A file that is no longer shown still takes one of the 200 places until it is deleted. Any program that can write in the folder can put a session on the dashboard. Under your home folder, that means programs you run.
837
1082
 
1083
+ ## Another machine over SSH
1084
+
1085
+ Agent Lookout can show the sessions on another machine you reach with ssh, such as a dev box or a cloud VM, beside the ones on this computer. It takes two steps, and a third to check.
1086
+
1087
+ 1. On the other machine, start Agent Lookout as usual, and leave it running:
1088
+
1089
+ ```sh
1090
+ npx agent-lookout
1091
+ ```
1092
+
1093
+ There it listens on that machine's `127.0.0.1:4777` only, as it does here, so nothing else on its network can reach it.
1094
+
1095
+ 2. On this computer, name the machine when you start Agent Lookout:
1096
+
1097
+ ```sh
1098
+ AGENT_LOOKOUT_REMOTES=devbox=dev@devbox.local npx agent-lookout
1099
+ ```
1100
+
1101
+ `devbox` is the name shown beside its sessions, and `dev@devbox.local` is what you type after `ssh` to reach it: a host from your `~/.ssh/config`, a host name, or `user@host`. Name more machines with commas, up to eight: `devbox=dev@devbox.local,gpu=gpu-vm`. When Agent Lookout listens on another port there, give it after a colon: `gpu=gpu-vm:4800`.
1102
+
1103
+ 3. Open Sources. The devbox card says Connected, with the version of Agent Lookout there, and its sessions are in the lists on the Overview with `devbox` beside each. If it says Not connected, its card says why and what to do, and [If a machine's card says Not connected](#if-a-machines-card-says-not-connected) has more.
1104
+
1105
+ `ssh dev@devbox.local` must connect from a terminal here without asking you anything first: Agent Lookout runs ssh so that it never asks for a password, a passphrase or whether to trust a host key, and never sees a key or a password itself.
1106
+
1107
+ ### How it works
1108
+
1109
+ For each machine Agent Lookout runs your own `ssh`, as this command, with a free port of this computer's in place of `53211`:
1110
+
1111
+ ```sh
1112
+ ssh -N -o BatchMode=yes -o ExitOnForwardFailure=yes -o ServerAliveInterval=15 -o ControlMaster=no -o ControlPath=none -L 127.0.0.1:53211:127.0.0.1:4777 -- dev@devbox.local
1113
+ ```
1114
+
1115
+ It forwards that port on this computer's loopback to Agent Lookout's on the other machine's loopback, and runs no command there. ssh signs in with your ssh config and your agent. BatchMode stops it asking anything. `ControlMaster=no` and `ControlPath=none` make it a connection of its own every time, even when your ssh config shares connections, so it never joins an ssh you have open, never leaves one running in the background, and its forward ends when it ends.
1116
+
1117
+ - Every 2 seconds, Agent Lookout asks the other machine's Agent Lookout for two things through the tunnel, `GET /api/health` and `GET /api/sessions`, and nothing else. This computer installs nothing there and leaves nothing there. The Agent Lookout you started there keeps its own Events log and history, as it does on any machine, unless it was started with `AGENT_LOOKOUT_HISTORY=off`.
1118
+ - Its sessions appear in the same lists as this computer's, each with the machine's name beside its own, and so do its waits and its events in the charts and the Events log, so two sessions of one name, one here and one there, are told apart. A waiting one is in Needs you and is counted there, and its notification names the machine after the session, `docs-site on devbox`. What a waiting session is asking shows when the other machine sends it, as it does, unless `AGENT_LOOKOUT_WAITING_TEXT=off` is set here, which turns it off for every machine. `agent-lookout status` and `agent-lookout mcp` name the machine too.
1119
+ - Its sessions have no Jump, no Stop and no Allow or Deny. Each acts on this computer only.
1120
+ - The [time rules](#time-rules) set on this computer cover its sessions too. A wait there is reminded of and held through quiet hours here by the rules set here, its reminder and its line in the summary naming the machine as its notification does, and a session there idle longer than Mark idle sessions stale says here is counted as stale here. The rules set on the other machine go with what that machine sends itself, and are not read here.
1121
+ - Sources has a card for each machine. It says Connected, with the version of Agent Lookout there and what each of its sources is doing; Connecting, while ssh signs in the first time; or Not connected, with the reason and what to do: ssh was not found, the machine turned ssh away and ssh's own words for why, the connection dropped, no Agent Lookout is answering on its port, or what answers there is not Agent Lookout or sends a list this version cannot read. A first connection that has not answered within 10 seconds is Not connected, still connecting, until ssh connects or gives up. [What each agent can report](#what-each-agent-can-report) has a row for each agent found there, such as Claude Code on devbox.
1122
+ - A machine that is not connected, as when it is switched off, is no fault: nothing on the Overview turns red or amber for it. The header says `devbox not connected`, and while nothing on this computer needs you the hero says `Nothing on this computer needs you`, and that devbox's sessions are not known. The charts go on without its sessions.
1123
+ - When ssh ends, Agent Lookout starts it again after 1 second, then 2, 5, 10 and 30 seconds, and then every minute, until it connects. ssh notices within a minute that the other machine has gone. When Agent Lookout stops, it ends every ssh it started, with SIGKILL if one has not ended 2 seconds after SIGTERM.
1124
+ - A machine that is slow or cannot be reached does not hold up this computer's sessions. Each read waits for it half a second at most, and a slower answer is used at the next read.
1125
+ - A name is letters, digits and dashes, up to 24, starting with a letter or a digit. A target is letters, digits, dots, dashes and underscores, with at most one `@`. A space, a leading dash or any other punctuation, a name given twice, or more than eight machines, and no machine is read: Agent Lookout prints one line saying which entry is wrong, Sources shows an Other machines card that says the same, and it carries on with this computer alone.
1126
+ - ssh is looked for on your `PATH`, then in `/usr/bin`, `/opt/homebrew/bin` and `/usr/local/bin`. `AGENT_LOOKOUT_SSH_BIN` names another, and then it is the only one looked at.
1127
+ - While a tunnel is up, any program or user on this computer can reach the other machine's Agent Lookout through its port, as [SECURITY.md](../SECURITY.md) says. Name a machine only from a computer whose other users you trust with it.
1128
+
1129
+ A session on another machine is read as that machine's Agent Lookout reads it, so what it can show is what its agent can show there. Each machine is read on its own: Agent Lookout there does not pass on the sessions of a machine it reads in turn.
1130
+
838
1131
  ## On Linux
839
1132
 
840
1133
  Agent Lookout is installed and started on Linux as on a Mac, and reads the same folders: `~/.claude/sessions`, `~/.codex` and `~/.agent-lookout/sessions`. CI runs every test on Ubuntu, and there it also starts the built app with `npm start` and checks that it lists a Claude Code session, Codex sessions and a session from a status file, each with the right status. No one has yet used it on a Linux desktop.
@@ -852,15 +1145,15 @@ These are macOS only:
852
1145
  - 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.
853
1146
  - [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.
854
1147
 
855
- 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.
1148
+ 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.
856
1149
 
857
1150
  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.
858
1151
 
859
1152
  ## What it does not do yet
860
1153
 
861
- 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.
1154
+ It does not resume a session itself: for a Claude Code session that has ended, [Resume](#resume-a-session) copies the command that does, and you run it. It cannot send a session a message. 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. It [answers a permission prompt](#answer-a-permission-prompt) only for a Claude Code session with the plugin installed, allows or denies that one request only, and offers Deny alone for an edit, a plan or a question, and for a request it cannot show whole and as it is. 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), on this computer and on [another machine](#another-machine-over-ssh) running Agent Lookout that you reach over SSH. 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.
862
1155
 
863
- 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.
1156
+ A notification, an email or a post is sent for four events: a session starting to wait, finishing, failing or ending, and, with the [time rules](#time-rules) on, also a reminder of a long wait and a summary of quiet hours. 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.
864
1157
 
865
1158
  A Codex session never shows as needing you. Codex's session files do not record when it is waiting for your approval, so a Codex session that is waiting for you shows as working. Once it has written nothing for 5 minutes, its row says how long it has been [quiet](#quiet-for), which is the sign to look. A Claude Code session never says how long it has been quiet. A Codex session also appears only once its first prompt is sent, because Codex creates its file then. Past sessions the Codex desktop app imports from another agent appear only once you use them in Codex. A session from the Codex desktop app is named after its folder, because the app does not keep the titles it shows in the names file Agent Lookout reads.
866
1159
 
@@ -884,37 +1177,45 @@ Put a setting in front of the command that starts Agent Lookout:
884
1177
  AGENT_LOOKOUT_CLAUDE_FEED=off npx agent-lookout
885
1178
  ```
886
1179
 
887
- | Setting | What it does |
888
- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
889
- | `AGENT_LOOKOUT_PORT` | The port `npx agent-lookout`, `agent-lookout` and `npm start` listen on. The default is 4777. |
890
- | `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. |
891
- | `AGENT_LOOKOUT_CLAUDE_BIN` | The full path of the `claude` program. When set, it is the only place Agent Lookout looks. |
892
- | `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. |
893
- | `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. |
894
- | `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. |
895
- | `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. |
896
- | `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. |
897
- | `AGENT_LOOKOUT_STATUS_DIR` | A folder of [status files](#your-own-agents) to read in place of `~/.agent-lookout/sessions`. |
898
- | `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). |
899
- | `AGENT_LOOKOUT_HISTORY_DIR` | A folder to keep the [history](#history) in, in place of `~/.agent-lookout/history`. |
900
- | `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. |
901
- | `AGENT_LOOKOUT_TMUX` | Set to `off` and Agent Lookout never runs `tmux`. Sessions in tmux are still listed, without a Jump button. |
902
- | `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. |
903
- | `AGENT_LOOKOUT_EMAIL_TO` | The one address emails go to. With `AGENT_LOOKOUT_SMTP_URL` set too, it turns [email](#email) on. |
904
- | `AGENT_LOOKOUT_SMTP_URL` | The mail server emails go through, with the user name and password: `smtps://name:password@server:port`. |
905
- | `AGENT_LOOKOUT_EMAIL_FROM` | The address emails come from. The default is the address they go to. |
906
- | `AGENT_LOOKOUT_EMAIL_AFTER` | How many seconds a wait lasts before it is emailed, from 0 to 86400. The default is 60. |
907
- | `AGENT_LOOKOUT_EMAIL_EVENTS` | What is emailed: `needs-you`, `finished`, `failed` and `ended`, any of them, separated by commas. The default is `needs-you`. |
908
- | `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). |
909
- | `AGENT_LOOKOUT_WEBHOOK_URL` | The one address [webhook](#webhook) posts go to, beginning with `https://`. It turns the webhook on. |
910
- | `AGENT_LOOKOUT_WEBHOOK_EVENTS` | What is posted, as for `AGENT_LOOKOUT_EMAIL_EVENTS`. The default is `needs-you`. |
911
- | `AGENT_LOOKOUT_WEBHOOK_AFTER` | How many seconds a wait lasts before it is posted, from 0 to 86400. The default is 60. |
912
- | `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). |
913
- | `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. |
1180
+ | Setting | What it does |
1181
+ | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1182
+ | `AGENT_LOOKOUT_PORT` | The port `npx agent-lookout`, `agent-lookout` and `npm start` listen on. The default is 4777. |
1183
+ | `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. |
1184
+ | `AGENT_LOOKOUT_CLAUDE_BIN` | The full path of the `claude` program. When set, it is the only place Agent Lookout looks. |
1185
+ | `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. |
1186
+ | `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. |
1187
+ | `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, and so does one on [another machine](#another-machine-over-ssh). |
1188
+ | `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. |
1189
+ | `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. |
1190
+ | `AGENT_LOOKOUT_STATUS_DIR` | A folder of [status files](#your-own-agents) to read in place of `~/.agent-lookout/sessions`. |
1191
+ | `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). |
1192
+ | `AGENT_LOOKOUT_HISTORY_DIR` | A folder to keep the [history](#history) in, in place of `~/.agent-lookout/history`. |
1193
+ | `AGENT_LOOKOUT_SETTINGS_FILE` | A file to keep the [time rules](#time-rules) in, in place of `~/.agent-lookout/settings.json`. |
1194
+ | `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. |
1195
+ | `AGENT_LOOKOUT_TMUX` | Set to `off` and Agent Lookout never runs `tmux`. Sessions in tmux are still listed, without a Jump button. |
1196
+ | `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. |
1197
+ | `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. |
1198
+ | `AGENT_LOOKOUT_ANSWER` | Set to `off` and Agent Lookout never answers a permission prompt: it opens no socket for the plugin, no session shows Allow or Deny, and the server answers no request to answer one. |
1199
+ | `AGENT_LOOKOUT_ANSWER_SOCKET` | The socket the [plugin](#install-the-plugin) sends permission requests to, in place of `~/.agent-lookout/answer.sock`. Set the same in the environment Claude Code starts with, so its hook finds it. With `AGENT_LOOKOUT_CLAUDE_HOME` set, nothing is answered unless this is set too. |
1200
+ | `AGENT_LOOKOUT_ANSWER_WAIT` | How many seconds a permission request waits for Allow or Deny before the prompt in the session is left to decide, from 5 to 540. The default is 300. |
1201
+ | `AGENT_LOOKOUT_EMAIL_TO` | The one address emails go to. With `AGENT_LOOKOUT_SMTP_URL` set too, it turns [email](#email) on. |
1202
+ | `AGENT_LOOKOUT_SMTP_URL` | The mail server emails go through, with the user name and password: `smtps://name:password@server:port`. |
1203
+ | `AGENT_LOOKOUT_EMAIL_FROM` | The address emails come from. The default is the address they go to. |
1204
+ | `AGENT_LOOKOUT_EMAIL_AFTER` | How many seconds a wait lasts before it is emailed, from 0 to 86400. The default is 60. |
1205
+ | `AGENT_LOOKOUT_EMAIL_EVENTS` | What is emailed: `needs-you`, `finished`, `failed` and `ended`, any of them, separated by commas. The default is `needs-you`. |
1206
+ | `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). |
1207
+ | `AGENT_LOOKOUT_WEBHOOK_URL` | The one address [webhook](#webhook) posts go to, beginning with `https://`. It turns the webhook on. |
1208
+ | `AGENT_LOOKOUT_WEBHOOK_EVENTS` | What is posted, as for `AGENT_LOOKOUT_EMAIL_EVENTS`. The default is `needs-you`. |
1209
+ | `AGENT_LOOKOUT_WEBHOOK_AFTER` | How many seconds a wait lasts before it is posted, from 0 to 86400. The default is 60. |
1210
+ | `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). |
1211
+ | `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 |
1212
+ | `AGENT_LOOKOUT_REMOTES` | Other machines to read over SSH, as `name=target`, separated by commas, such as `devbox=dev@devbox.local,gpu=gpu-vm:4800`. Unset, none is read. See [Another machine over SSH](#another-machine-over-ssh). |
1213
+ | `AGENT_LOOKOUT_SSH_BIN` | The full path of the `ssh` program used to reach those machines. When set, it is the only place Agent Lookout looks. |
1214
+ | `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. |
914
1215
 
915
1216
  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.
916
1217
 
917
- The Claude Code, transcript, Codex, status file, history, 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 `--`:
1218
+ The Claude Code, transcript, Codex, status file, history, settings file, notification, tmux, terminal tab, stop, other machine, 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 `--`:
918
1219
 
919
1220
  ```sh
920
1221
  npm run dev -- --port 5180
@@ -950,7 +1251,7 @@ It prints `{"ok":true,"version":"0.2.1"}`, or a later version number. If you run
950
1251
 
951
1252
  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.
952
1253
 
953
- 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`.
1254
+ 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`.
954
1255
 
955
1256
  In a clone, run `npm run build` and `npm link` once in the `agent-lookout` folder, then `agent-lookout` from any folder.
956
1257
 
@@ -986,6 +1287,7 @@ It behaves as a Mac app does:
986
1287
  - 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.
987
1288
  - Settings… in the Agent Lookout menu, or Cmd+comma, opens the Settings view. The Help menu opens this guide.
988
1289
  - Right-click selected text to copy it, or in the search field to cut, copy and paste.
1290
+ - [Resume](#resume-a-session) copies its command as it does in a browser. The window may write to the clipboard when you press a button that copies, and never reads it.
989
1291
  - It opens where you left it, at the size you left it.
990
1292
  - 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.
991
1293
  - Check for Updates…, in the Agent Lookout menu under About, checks for a newer version at once. [Updates](#updates) says how.
@@ -1073,6 +1375,7 @@ Use `http://localhost:5173` if you started it with `npm run dev`. It prints the
1073
1375
  4. With a dashboard tab open, check that the page does not say Agent Lookout has stopped updating.
1074
1376
  5. With no dashboard tab open, Agent Lookout shows notifications itself on a Mac only, and only once a page that has notifications on has been open since Agent Lookout started, or when it was started with `AGENT_LOOKOUT_NOTIFICATIONS=on`. Those arrive as Script Editor's notifications, not your browser's.
1075
1377
  6. A session that was already waiting when you opened the page, or when Agent Lookout started, sends nothing, nor does one that had already finished. Wait for the next one, or check the Needs you panel.
1378
+ 7. Check [Time rules](#time-rules) in Settings. During quiet hours nothing is shown until they end.
1076
1379
 
1077
1380
  ### No email arrives
1078
1381
 
@@ -1080,6 +1383,7 @@ Use `http://localhost:5173` if you started it with `npm run dev`. It prints the
1080
1383
  2. If it says the last email could not be sent, the reason says what went wrong: the user name and password, a server that did not answer, or one that refused the connection or the email. Check the server's name and port, that the address begins `smtps://` or `smtp://` as your provider says, and that the password is an app password, with its special characters written as described under [Email](#email). A server that refused the email often refuses the sender: if emails go to an address other than the one you sign in with, set `AGENT_LOOKOUT_EMAIL_FROM` to the address you sign in with.
1081
1384
  3. If it says where emails 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.
1082
1385
  4. If it says when the last email was sent, the mail server took it. Look in the spam folder of the address the card shows.
1386
+ 5. Check [Time rules](#time-rules) in Settings. During quiet hours no email goes until they end.
1083
1387
 
1084
1388
  ### No post arrives
1085
1389
 
@@ -1087,6 +1391,37 @@ Use `http://localhost:5173` if you started it with `npm run dev`. It prints the
1087
1391
  2. If it says the last post failed, the reason says what went wrong. An address that refused the post most often was copied wrong, or its webhook was removed or its channel archived: copy the address again from the service's settings. A redirect means the address is not the webhook's own. An address that did not answer in time, could not be found or had nothing answering is a problem with the network or with the service. A secure connection that failed most often means something on the network, such as a company proxy, stands between this computer and the service, or that this computer's clock is wrong. A connection that failed otherwise was cut off on the way: try again on another network.
1088
1392
  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.
1089
1393
  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.
1394
+ 5. Check [Time rules](#time-rules) in Settings. During quiet hours no post goes until they end.
1395
+
1396
+ ### No pull request shows
1397
+
1398
+ 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.
1399
+
1400
+ ### If a machine's card says Not connected
1401
+
1402
+ A machine named in `AGENT_LOOKOUT_REMOTES` is read through ssh, then through Agent Lookout on that machine, so check each in turn. Its card in Sources says which went wrong, and what to do.
1403
+
1404
+ 1. In a terminal on this computer, run ssh as Agent Lookout does, with the target you named:
1405
+
1406
+ ```sh
1407
+ ssh -o BatchMode=yes dev@devbox.local true
1408
+ ```
1409
+
1410
+ It should end at once and print nothing. If it asks for a password or a passphrase, or whether to trust the host's key, or fails, Agent Lookout's ssh fails the same way: add your key to your ssh agent, or answer the question once in a plain `ssh dev@devbox.local`, then try again.
1411
+
1412
+ 2. On the other machine, check that Agent Lookout is running there:
1413
+
1414
+ ```sh
1415
+ curl -s http://127.0.0.1:4777/api/health
1416
+ ```
1417
+
1418
+ It should print `{"ok":true,"version":"…"}`. If nothing answers, start it there with `npx agent-lookout`. If it listens on another port there, give that port after the target here, `devbox=dev@devbox.local:4800`.
1419
+
1420
+ 3. If the card says `AGENT_LOOKOUT_SSH_BIN` names a program that cannot be run, correct it, or unset it to use the ssh on your `PATH`.
1421
+
1422
+ 4. If Sources has an Other machines card that says Not set up, `AGENT_LOOKOUT_REMOTES` could not be read: the card says which entry is wrong. Correct it and start Agent Lookout again.
1423
+
1424
+ A machine that is switched off, or asleep, is Not connected until it is back, and is connected again on its own within a minute of that.
1090
1425
 
1091
1426
  ### The page says Agent Lookout has stopped updating
1092
1427