agent-lookout 0.2.4 → 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.
- package/CHANGELOG.md +26 -0
- package/PRIVACY.md +92 -16
- package/README.md +11 -5
- package/SECURITY.md +27 -9
- package/dist/assets/HistoryPanel-TXa0oPH4.js +1 -0
- package/dist/assets/SessionPanel-BStoG7uq.js +1 -0
- package/dist/assets/index-BsTJp5-3.css +1 -0
- package/dist/assets/index-a7ubgAmE.js +3 -0
- package/dist/cli/agent-lookout.js +4 -4
- package/dist/cli/{chunk-XVXSGVEW.js → chunk-NWVEVCRT.js} +9 -2
- package/dist/cli/{chunk-63XPRBHW.js → chunk-OT3EGOTY.js} +38 -7
- package/dist/cli/{chunk-KNOLJ3IC.js → chunk-Q73JDXXW.js} +1 -1
- package/dist/cli/{mcpServer-HGH6PY4W.js → mcpServer-IFB2FEOZ.js} +9 -6
- package/dist/cli/{startCommand-KNXMVM2U.js → startCommand-J3QS26SZ.js} +2898 -401
- package/dist/index.html +2 -2
- package/docs/API.md +165 -61
- package/docs/GUIDE.md +289 -23
- package/package.json +1 -1
- package/dist/assets/HistoryPanel-CIjshvhu.js +0 -1
- package/dist/assets/SessionPanel-eBOdTLD9.js +0 -1
- package/dist/assets/index-B-myfVQS.js +0 -2
- package/dist/assets/index-Cceyz9yZ.css +0 -1
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,9 +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.
|
|
66
68
|
|
|
67
|
-
Claude Code sessions idle for a day or more whose process still runs are also listed over the list, under Left running, where they can be hidden or ended: see [Sessions left running](#sessions-left-running).
|
|
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).
|
|
68
70
|
|
|
69
71
|
Click a row, or move to its name with Tab and press Enter, to open the session's [details](#a-sessions-details).
|
|
70
72
|
|
|
@@ -81,7 +83,7 @@ Board shows the same sessions in a column for each status, so you can see at a g
|
|
|
81
83
|
| Idle | Sessions ready for a new prompt, then stale ones with their own mark. The heading counts them apart: `Idle 1 Stale 1` |
|
|
82
84
|
| Finished or failed | Sessions that finished or failed, failures first |
|
|
83
85
|
|
|
84
|
-
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).
|
|
85
87
|
|
|
86
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.
|
|
87
89
|
|
|
@@ -109,7 +111,7 @@ The details show everything Agent Lookout knows about the session:
|
|
|
109
111
|
- its own events, newest first, as the Events log shows them
|
|
110
112
|
- its row of the Timeline over the last hour
|
|
111
113
|
|
|
112
|
-
A session with a Jump button has it at the top of its details, and it works as it does in the list. It is the amber one while the session needs you. A session Agent Lookout can stop has a [Stop](#stop-a-session) button beside it.
|
|
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).
|
|
113
115
|
|
|
114
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.
|
|
115
117
|
|
|
@@ -214,15 +216,17 @@ The card for status files gives the folder it reads, normally `~/.agent-lookout/
|
|
|
214
216
|
|
|
215
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.
|
|
216
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
|
+
|
|
217
221
|
#### What each agent can report
|
|
218
222
|
|
|
219
|
-
Under the cards, What each agent can report has a row for each agent and a column for each thing Agent Lookout can show of its sessions, and for [Stop](#stop-a-session), what it can do to one, with Yes, No or Partly in each. Point at No or Partly, or move to it with Tab, to read why. In a narrow window each agent has a block of its own, with the reason under each No and Partly. A No means Agent Lookout cannot show it for that agent's sessions, so not seeing it is not good news. The [branch](#branches) is not in the table, because it is read the same way for every agent.
|
|
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.
|
|
220
224
|
|
|
221
|
-
| Agent | Working and idle | Needs you | Finished | Failed | Names | Jump | Quiet for | Stop |
|
|
222
|
-
| ------------ | ---------------- | --------- | -------- | ------ | ------ | ------ | --------- | ------ |
|
|
223
|
-
| Claude Code | Yes | Yes | Partly | Partly | Yes | Partly | No | Partly |
|
|
224
|
-
| Codex | Yes | No | Partly | No | Partly | No | Yes | No |
|
|
225
|
-
| Status files | Partly | Partly | Partly | Partly | Partly | No | Partly | No |
|
|
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 |
|
|
226
230
|
|
|
227
231
|
Why, for each No and Partly:
|
|
228
232
|
|
|
@@ -231,12 +235,14 @@ Why, for each No and Partly:
|
|
|
231
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.
|
|
232
236
|
- Claude Code, Quiet for: The file Agent Lookout reads is not rewritten as a session works.
|
|
233
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.
|
|
234
239
|
- Codex, Needs you: Codex does not record approval waits, so a session waiting for you shows as working.
|
|
235
240
|
- Codex, Finished: From Codex 0.155 on, once no Codex program has the session open.
|
|
236
241
|
- Codex, Failed: Codex does not record errors in its files.
|
|
237
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.
|
|
238
243
|
- Codex, Jump: Codex's files name no process to find, and Codex documents no link to a session.
|
|
239
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.
|
|
240
246
|
- Status files, Working and idle: If the agent writes working and idle.
|
|
241
247
|
- Status files, Needs you: If the agent writes waiting.
|
|
242
248
|
- Status files, Finished: If the agent writes finished.
|
|
@@ -245,10 +251,13 @@ Why, for each No and Partly:
|
|
|
245
251
|
- Status files, Jump: Nothing in a status file is used to reach a session.
|
|
246
252
|
- Status files, Quiet for: If the agent writes its file again as it works.
|
|
247
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.
|
|
248
257
|
|
|
249
258
|
### Settings
|
|
250
259
|
|
|
251
|
-
Settings has
|
|
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.
|
|
252
261
|
|
|
253
262
|
#### Notifications
|
|
254
263
|
|
|
@@ -307,6 +316,22 @@ A notification shows the session's name outside the dashboard: over other apps,
|
|
|
307
316
|
|
|
308
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.
|
|
309
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
|
+
|
|
310
335
|
#### History
|
|
311
336
|
|
|
312
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.
|
|
@@ -572,7 +597,7 @@ A Claude Code session that runs in a terminal or in VS Code, and a Claude Code b
|
|
|
572
597
|
|
|
573
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.
|
|
574
599
|
|
|
575
|
-
Agent Lookout then checks again that the process is that session: it reads the session's file in `~/.claude/sessions` again and asks `ps` when the process started, and does nothing unless both agree with what it found before. A session in a terminal or VS Code is sent SIGTERM, which ends Claude Code the way closing it does, and Agent Lookout waits up to 10 seconds for it to end. A background job is stopped with `claude stop` and its ID, since Claude Code would start its process again if it were ended another way. The session leaves the list within a second or two, a background job shows as finished, and the Events log says it was stopped from Agent Lookout.
|
|
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.
|
|
576
601
|
|
|
577
602
|
| What the details say | Why |
|
|
578
603
|
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -591,7 +616,7 @@ Agent Lookout then checks again that the process is that session: it reads the s
|
|
|
591
616
|
|
|
592
617
|
### Sessions left running
|
|
593
618
|
|
|
594
|
-
Closing a Claude Code tab in VS Code can leave its process running, and the session then sits idle for days. Over the Sessions list, or the board, a band says how many Claude Code sessions have been idle for a day or more with their process still running: those Agent Lookout can stop, and those in the desktop app. Press Review… to list them, the longest idle first, each with its folder, its app and how long it has been idle, and Close to fold the list again. They stay in the list under Idle too.
|
|
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.
|
|
595
620
|
|
|
596
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.
|
|
597
622
|
|
|
@@ -599,6 +624,57 @@ End all… lists each one again with a tick, all ticked, up to 20, which is as m
|
|
|
599
624
|
|
|
600
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.
|
|
601
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
|
+
|
|
602
678
|
## Keyboard
|
|
603
679
|
|
|
604
680
|
Every view answers to a few keys. Press `?` to see them all.
|
|
@@ -697,6 +773,7 @@ With `--json` it prints:
|
|
|
697
773
|
"id": "claude-code:00000000-0000-4000-8000-000000000001",
|
|
698
774
|
"name": "checkout-flow",
|
|
699
775
|
"agent": "Claude Code",
|
|
776
|
+
"machine": null,
|
|
700
777
|
"reason": "permission",
|
|
701
778
|
"waitingSince": 1791205668000,
|
|
702
779
|
"waitedMs": 252000
|
|
@@ -713,6 +790,7 @@ With `--json` it prints:
|
|
|
713
790
|
| `id` | The session's id, as `/api/sessions` gives it |
|
|
714
791
|
| `name` | The session's name, exactly as its agent gave it |
|
|
715
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 |
|
|
716
794
|
| `reason` | `permission`, `question` or `other` |
|
|
717
795
|
| `waitingSince` | When the wait began, in milliseconds since 1970, or `null` when that is not known |
|
|
718
796
|
| `waitedMs` | How long it has waited, in milliseconds, or `null` |
|
|
@@ -813,11 +891,11 @@ It finds Agent Lookout as `agent-lookout status` does: at `http://127.0.0.1:4777
|
|
|
813
891
|
|
|
814
892
|
It has three tools:
|
|
815
893
|
|
|
816
|
-
| Tool | Answers
|
|
817
|
-
| ---------------------- |
|
|
818
|
-
| `list_sessions` | Every session, those that need you first, longest wait first, then the rest by status, with its `id`, `name`, `agent`, `status`, the `reason` when it needs you, its `folder`, `branch` or `commit`, with [pull requests](#pull-requests) on its `pullRequest`, `app`, `since` and, for a working session, `quietFor`. Give it a `status` to list only those |
|
|
819
|
-
| `sessions_needing_you` | The sessions that need you, longest wait first, with how long each has waited, and a `summary` in one sentence
|
|
820
|
-
| `sources` | Each source's state, as the Sources view says it, and its row of [what each agent can report](#what-each-agent-can-report), with the reason for each no and partly
|
|
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 |
|
|
821
899
|
|
|
822
900
|
Each answers in JSON. `sessions_needing_you` gives, for example:
|
|
823
901
|
|
|
@@ -831,6 +909,7 @@ Each answers in JSON. `sessions_needing_you` gives, for example:
|
|
|
831
909
|
"id": "status-files:checkout-flow.json",
|
|
832
910
|
"name": "checkout-flow",
|
|
833
911
|
"agent": "Night Shift",
|
|
912
|
+
"machine": null,
|
|
834
913
|
"reason": "permission",
|
|
835
914
|
"folder": "storefront",
|
|
836
915
|
"branch": null,
|
|
@@ -846,7 +925,7 @@ Each answers in JSON. `sessions_needing_you` gives, for example:
|
|
|
846
925
|
}
|
|
847
926
|
```
|
|
848
927
|
|
|
849
|
-
Times are in ISO 8601. A field that is not known is `null`. `counted` is `false` until Agent Lookout has read an agent, when an empty list says nothing, and the summary says so. When an agent's sessions could not be read, such as Claude Code's, the summary names that agent and says its sessions are not counted. `pullRequest` is `{ "number": 51, "checks": "failing" }` for a branch whose pull request Agent Lookout found, with `checks` one of `failing`, `pending`, `passing` and `none`, and `null` for every other session and whenever `AGENT_LOOKOUT_PULL_REQUESTS` is not `on`. It never holds the title, which someone else may have written. `quietFor` is how long a working session's agent has written nothing to the file it is read from, given whenever the agent's source gives that time. From 5 minutes it is what the Sessions list shows as [Quiet for](#quiet-for). Not every agent can report a wait: a Codex session waiting for your approval shows as working. `sources` says which can report what.
|
|
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.
|
|
850
929
|
|
|
851
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.
|
|
852
931
|
|
|
@@ -875,6 +954,109 @@ echo "Deleted: the session has gone"
|
|
|
875
954
|
|
|
876
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.
|
|
877
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
|
+
|
|
878
1060
|
| Field | Needed | What it holds |
|
|
879
1061
|
| -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
880
1062
|
| `agent` | Yes | The agent's name, shown wherever the agent is named, such as `my-agent`. Up to 40 characters are kept. |
|
|
@@ -898,6 +1080,54 @@ The session appears in Sessions as `docs-site`, in Terminal, moves to Needs you
|
|
|
898
1080
|
|
|
899
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.
|
|
900
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
|
+
|
|
901
1131
|
## On Linux
|
|
902
1132
|
|
|
903
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.
|
|
@@ -921,9 +1151,9 @@ Agent Lookout runs `ps` from `/usr/bin` or `/bin`. Where it is not there, as on
|
|
|
921
1151
|
|
|
922
1152
|
## What it does not do yet
|
|
923
1153
|
|
|
924
|
-
It
|
|
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.
|
|
925
1155
|
|
|
926
|
-
A notification, an email or a post is sent for four events
|
|
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.
|
|
927
1157
|
|
|
928
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.
|
|
929
1159
|
|
|
@@ -954,16 +1184,20 @@ AGENT_LOOKOUT_CLAUDE_FEED=off npx agent-lookout
|
|
|
954
1184
|
| `AGENT_LOOKOUT_CLAUDE_BIN` | The full path of the `claude` program. When set, it is the only place Agent Lookout looks. |
|
|
955
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. |
|
|
956
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. |
|
|
957
|
-
| `AGENT_LOOKOUT_WAITING_TEXT` | Set to `off` and Agent Lookout never opens a Claude Code transcript. A waiting session then shows its reason alone, without what it is asking.
|
|
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). |
|
|
958
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. |
|
|
959
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. |
|
|
960
1190
|
| `AGENT_LOOKOUT_STATUS_DIR` | A folder of [status files](#your-own-agents) to read in place of `~/.agent-lookout/sessions`. |
|
|
961
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). |
|
|
962
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`. |
|
|
963
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. |
|
|
964
1195
|
| `AGENT_LOOKOUT_TMUX` | Set to `off` and Agent Lookout never runs `tmux`. Sessions in tmux are still listed, without a Jump button. |
|
|
965
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. |
|
|
966
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. |
|
|
967
1201
|
| `AGENT_LOOKOUT_EMAIL_TO` | The one address emails go to. With `AGENT_LOOKOUT_SMTP_URL` set too, it turns [email](#email) on. |
|
|
968
1202
|
| `AGENT_LOOKOUT_SMTP_URL` | The mail server emails go through, with the user name and password: `smtps://name:password@server:port`. |
|
|
969
1203
|
| `AGENT_LOOKOUT_EMAIL_FROM` | The address emails come from. The default is the address they go to. |
|
|
@@ -975,11 +1209,13 @@ AGENT_LOOKOUT_CLAUDE_FEED=off npx agent-lookout
|
|
|
975
1209
|
| `AGENT_LOOKOUT_WEBHOOK_AFTER` | How many seconds a wait lasts before it is posted, from 0 to 86400. The default is 60. |
|
|
976
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). |
|
|
977
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. |
|
|
978
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. |
|
|
979
1215
|
|
|
980
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.
|
|
981
1217
|
|
|
982
|
-
The Claude Code, transcript, Codex, status file, history, notification, tmux, terminal tab, stop, email, webhook and pull request settings work with `npx agent-lookout` and `agent-lookout`, and in a clone with `npm start` and `npm run dev`. The port and address settings apply to `npx agent-lookout`, `agent-lookout` and `npm start`, and `AGENT_LOOKOUT_URL` to `agent-lookout status` and `agent-lookout mcp` only. To choose the port for `npm run dev`, pass it after `--`:
|
|
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 `--`:
|
|
983
1219
|
|
|
984
1220
|
```sh
|
|
985
1221
|
npm run dev -- --port 5180
|
|
@@ -1051,6 +1287,7 @@ It behaves as a Mac app does:
|
|
|
1051
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.
|
|
1052
1288
|
- Settings… in the Agent Lookout menu, or Cmd+comma, opens the Settings view. The Help menu opens this guide.
|
|
1053
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.
|
|
1054
1291
|
- It opens where you left it, at the size you left it.
|
|
1055
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.
|
|
1056
1293
|
- Check for Updates…, in the Agent Lookout menu under About, checks for a newer version at once. [Updates](#updates) says how.
|
|
@@ -1138,6 +1375,7 @@ Use `http://localhost:5173` if you started it with `npm run dev`. It prints the
|
|
|
1138
1375
|
4. With a dashboard tab open, check that the page does not say Agent Lookout has stopped updating.
|
|
1139
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.
|
|
1140
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.
|
|
1141
1379
|
|
|
1142
1380
|
### No email arrives
|
|
1143
1381
|
|
|
@@ -1145,6 +1383,7 @@ Use `http://localhost:5173` if you started it with `npm run dev`. It prints the
|
|
|
1145
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.
|
|
1146
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.
|
|
1147
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.
|
|
1148
1387
|
|
|
1149
1388
|
### No post arrives
|
|
1150
1389
|
|
|
@@ -1152,11 +1391,38 @@ Use `http://localhost:5173` if you started it with `npm run dev`. It prints the
|
|
|
1152
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.
|
|
1153
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.
|
|
1154
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.
|
|
1155
1395
|
|
|
1156
1396
|
### No pull request shows
|
|
1157
1397
|
|
|
1158
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.
|
|
1159
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.
|
|
1425
|
+
|
|
1160
1426
|
### The page says Agent Lookout has stopped updating
|
|
1161
1427
|
|
|
1162
1428
|
The program serving the page has stopped. The page keeps the last thing it saw, under a notice that says how old it is, and its timers stop at the last moment it heard from Agent Lookout. Start it again with `npx agent-lookout`, or in a clone with `npm start` or `npm run dev`, and the page catches up on its own.
|