@oddessentials/agent-guild 0.33.2 → 0.35.0
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/README.md +126 -359
- package/bin/agent-guild.mjs +29 -3
- package/package.json +1 -1
- package/src/manager/autostart.mjs +104 -20
- package/src/manager/environment-pins.mjs +289 -0
- package/src/manager/environment-probe.mjs +11 -0
- package/src/manager/environment.mjs +320 -15
- package/src/manager/github-views.mjs +34 -2
- package/src/manager/github.mjs +3 -1
- package/src/manager/launch.mjs +93 -1
- package/src/manager/main.mjs +25 -12
- package/src/manager/server.mjs +37 -6
- package/src/manager/systemd-service.mjs +312 -0
- package/web/app.js +163 -9
- package/web/environment.js +239 -34
- package/web/index.html +24 -8
- package/web/styles.css +39 -0
package/README.md
CHANGED
|
@@ -11,13 +11,12 @@
|
|
|
11
11
|
<a href="https://www.youtube.com/watch?v=ziT62WtXQ1M"><img src="https://img.shields.io/badge/trailer-watch%20on%20YouTube-e5534b?logo=youtube&logoColor=white" alt="Watch the Agent Guild trailer on YouTube"></a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
|
-
**Agent Guild** runs Claude Code, Codex CLI, Antigravity CLI, Grok Build and
|
|
15
|
-
own shell side by side, in real terminals, from one local web page.
|
|
16
|
-
|
|
17
|
-
which helper agents it has summoned. Close the page whenever you like; the
|
|
18
|
-
sessions keep working.
|
|
14
|
+
**Agent Guild** runs Claude Code, Codex CLI, Antigravity CLI, Grok Build and
|
|
15
|
+
your own shell side by side, in real terminals, from one local web page.
|
|
16
|
+
Close the page whenever you like; the sessions keep running.
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
[Try the demo](https://oddessentials.github.io/agent-guild/) in your browser
|
|
19
|
+
(simulated, nothing installed) or [watch the trailer](https://www.youtube.com/watch?v=ziT62WtXQ1M).
|
|
21
20
|
|
|
22
21
|
<picture>
|
|
23
22
|
<source media="(prefers-color-scheme: light)" srcset="docs/images/overview-light.webp">
|
|
@@ -31,378 +30,146 @@ npm install -g @oddessentials/agent-guild
|
|
|
31
30
|
agent-guild
|
|
32
31
|
```
|
|
33
32
|
|
|
34
|
-
The page opens in your browser.
|
|
35
|
-
in
|
|
33
|
+
The page opens in your browser. Press **New** on a tool's card to start a
|
|
34
|
+
session. Sign in to each tool inside its first session, as you would in any
|
|
35
|
+
terminal.
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
| Requirement | |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| Node.js | 22 or newer |
|
|
40
|
+
| Windows | 10 version 1809 or later, x64 or arm64. No WSL needed. |
|
|
41
|
+
| macOS | 11 or later, Intel or Apple silicon |
|
|
42
|
+
| Linux | x64 or arm64, with a desktop or over SSH |
|
|
43
|
+
|
|
44
|
+
No compiler is needed. A missing tool shows **Install** on its card;
|
|
45
|
+
Antigravity CLI, which is not on npm, shows its install command instead.
|
|
46
|
+
|
|
47
|
+
## Setup
|
|
48
|
+
|
|
49
|
+
### Access token
|
|
50
|
+
|
|
51
|
+
You do not create one. The first run generates it, and `agent-guild` opens
|
|
52
|
+
the page with it. If a browser asks for it, open the link that
|
|
53
|
+
`agent-guild url` prints. Anyone with that link can use your terminals.
|
|
54
|
+
|
|
55
|
+
To replace it, stop the manager (this ends running sessions), delete
|
|
56
|
+
`auth-token` from the [data folder](docs/configuration.md#data-folder), and
|
|
57
|
+
start again.
|
|
58
|
+
|
|
59
|
+
### Headless Linux server
|
|
60
|
+
|
|
61
|
+
1. On the server:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
npm install -g @oddessentials/agent-guild
|
|
65
|
+
agent-guild --no-browser
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
It prints `Open: http://127.0.0.1:47821/#token=…`.
|
|
69
|
+
|
|
70
|
+
2. On your computer, open a tunnel and leave it open:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
ssh -L 47821:127.0.0.1:47821 you@server
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
3. Open the printed link in your browser. The local port must be `47821`;
|
|
77
|
+
any other port is refused.
|
|
78
|
+
|
|
79
|
+
To start Agent Guild when the server boots, choose **Settings → Startup →
|
|
80
|
+
When the computer starts** in the page, then run once on the server:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
sudo loginctl enable-linger $USER
|
|
84
|
+
```
|
|
40
85
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
86
|
+
This needs systemd and is not offered under WSL. `agent-guild status` shows
|
|
87
|
+
the result.
|
|
88
|
+
|
|
89
|
+
### Remote access with Tailscale
|
|
90
|
+
|
|
91
|
+
Use your terminals from a phone or another computer on your
|
|
92
|
+
[Tailscale](https://tailscale.com) network.
|
|
93
|
+
|
|
94
|
+
You need Tailscale 1.52 or later, signed in on both devices in the same
|
|
95
|
+
tailnet, with MagicDNS on.
|
|
96
|
+
|
|
97
|
+
1. In the page, choose **Settings → Remote access → Enable remote access**.
|
|
98
|
+
2. If it shows **Open Tailscale approval**, approve HTTPS there, then choose
|
|
99
|
+
**Continue setup**.
|
|
100
|
+
3. If it says **Tailscale needs permission**, run the command under
|
|
101
|
+
**Connection details** in a terminal allowed to manage Tailscale, then
|
|
102
|
+
choose **Continue setup**.
|
|
103
|
+
4. Choose **Connect another device** and scan the QR code, or open the
|
|
104
|
+
sign-in link, on the other device.
|
|
105
|
+
|
|
106
|
+
The sign-in link contains your access token. **Disable remote access** turns
|
|
107
|
+
it off; sessions keep running. On a headless server, do this through the SSH
|
|
108
|
+
tunnel above. For another reverse proxy, see
|
|
109
|
+
[configuration](docs/configuration.md#reverse-proxies).
|
|
110
|
+
|
|
111
|
+
### macOS keychain
|
|
112
|
+
|
|
113
|
+
The first Claude Code usage meter may ask for access to the
|
|
114
|
+
"Claude Code-credentials" keychain item. Choose **Always Allow**.
|
|
45
115
|
|
|
46
116
|
## Features
|
|
47
117
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
mouse or a finger, to put the cards in the order you want; this browser
|
|
61
|
-
remembers it, and new sessions join at the end.
|
|
62
|
-
|
|
63
|
-
**Two terminals at once.** **Split** in the terminal's header, or Ctrl+click
|
|
64
|
-
(⌘-click on a Mac) on a card's **Open**, shows a second session beside the
|
|
65
|
-
first, or above it on a tall, narrow window. Click a terminal to work in it;
|
|
66
|
-
drag the divider, or focus it and use the arrow keys, to resize them. The
|
|
67
|
-
session name in the header switches the focused terminal to another session.
|
|
68
|
-
On a phone one terminal shows at a time, with a button to switch to the
|
|
69
|
-
other. This browser reopens the terminals you had open after a reload.
|
|
70
|
-
|
|
71
|
-
On phones and tablets, a strip below the terminal provides **← ↑ ↓ → Enter
|
|
72
|
-
Esc**. Tap once to move through a prompt, confirm a choice or send Escape.
|
|
73
|
-
The keys act on the focused terminal and leave the on-screen keyboard as
|
|
74
|
-
it is. They are disabled while the terminal reconnects or after it exits;
|
|
75
|
-
taps made while disconnected are never replayed.
|
|
76
|
-
|
|
77
|
-
On a touchscreen, **Copy…** opens a still copy of the terminal text. Touch and
|
|
78
|
-
hold to select, then use **Copy selection** or the browser's Copy menu. **Done**
|
|
79
|
-
returns to the live terminal; the session keeps running while you copy. The
|
|
80
|
-
view includes retained scrollback, or the current screen of a full-screen tool.
|
|
81
|
-
|
|
82
|
-
**Pick your shell.** The Shell card offers the shells installed on your
|
|
83
|
-
computer and remembers your choice in this browser. On Windows it defaults
|
|
84
|
-
to PowerShell 7 when installed, then Windows PowerShell; Git Bash and Command
|
|
85
|
-
Prompt are also offered when found. On macOS and Linux it follows your login
|
|
86
|
-
shell. Pick the default chip to clear a saved choice and follow the default
|
|
87
|
-
again. The choice applies to new sessions.
|
|
88
|
-
|
|
89
|
-
**See the manager environment.** The Shell card summarizes detected Node.js,
|
|
90
|
-
Python, Go, .NET SDK, R and Rust versions. **Environment details** shows the
|
|
91
|
-
resolved paths, detection results, .NET runtimes and detected nvm/NVM for
|
|
92
|
-
Windows, vfox, uv and pnpm launchers. Tools are listed by presence; their
|
|
93
|
-
activation is not inferred. This describes the computer running Agent Guild
|
|
94
|
-
and its manager environment, including when viewed remotely. Selected shells,
|
|
95
|
-
projects and existing sessions may use different versions.
|
|
96
|
-
|
|
97
|
-
Python always uses `python` when it is found on the manager's PATH; otherwise
|
|
98
|
-
it uses `python3`. A broken `python` remains the primary result, with a
|
|
99
|
-
different `python3` shown separately. **Not found** means no command was
|
|
100
|
-
resolved, **Runtime unavailable** means a launcher was found but no runtime
|
|
101
|
-
could safely be reported, and **Probe failed** means inspection or the version
|
|
102
|
-
check failed. Missing optional runtimes never prevent starting a shell.
|
|
103
|
-
|
|
104
|
-
Discovery runs on first viewing and again on **Refresh**, in an isolated
|
|
105
|
-
helper with a neutral temporary working directory. It does not load shell
|
|
106
|
-
profiles, activate tools, download runtimes or modify installations. Unknown
|
|
107
|
-
script/shim launchers and Windows execution aliases are left unverified.
|
|
108
|
-
Refresh checks the manager's current environment; it does not reload its
|
|
109
|
-
PATH from a shell. Existing results remain visible during refresh. Go reports
|
|
110
|
-
the local bundled toolchain with automatic switching disabled, and the Node
|
|
111
|
-
version running Agent Guild is also shown in details.
|
|
112
|
-
|
|
113
|
-
**Work inside tmux or herdr.** When installed, the Shell card also offers
|
|
114
|
-
tmux (3.2 or later, on macOS and Linux) and herdr. A tmux card runs a tmux
|
|
115
|
-
session of its own, with your own configuration, and tools in it report to
|
|
116
|
-
the card as they would in a shell. A herdr card opens your herdr session and
|
|
117
|
-
shows the agents herdr sees in its panes, working, blocked or idle. Stopping
|
|
118
|
-
or closing either card only detaches it, as closing a terminal window would:
|
|
119
|
-
the session keeps running, **Reattach** on the card brings it back, and the
|
|
120
|
-
card names the command that reattaches it from a terminal. Stopping or
|
|
121
|
-
restarting the manager detaches them the same way, and the cards come back,
|
|
122
|
-
closed and ready to reattach, when it starts again.
|
|
123
|
-
|
|
124
|
-
Open **Terminal multiplexers** on the Shell card to install, update or
|
|
125
|
-
uninstall tmux and herdr. Operations run in a terminal so you can read their
|
|
126
|
-
output and answer package-manager prompts. tmux uses Homebrew on macOS and
|
|
127
|
-
Homebrew or apt, dnf, or pacman on Linux; a distribution must offer 3.2 or
|
|
128
|
-
later. Update distro packages with their package manager. Native Windows
|
|
129
|
-
offers herdr instead of tmux.
|
|
130
|
-
|
|
131
|
-
Herdr updates leave its existing servers and panes running, including
|
|
132
|
-
Homebrew updates. New starts and reattachments wait until the operation
|
|
133
|
-
finishes. Uninstall requires herdr's servers to be stopped and their status
|
|
134
|
-
to be verifiable. tmux asks before changing a copy that attached or detached
|
|
135
|
-
cards depend on. Settings and session data are kept. If a multiplexer is
|
|
136
|
-
missing when the manager starts, its saved cards wait for it and return
|
|
137
|
-
when it is detected again, provided their sessions still exist.
|
|
138
|
-
|
|
139
|
-
<img src="docs/images/terminal.webp" alt="An open Claude Code session with its helper agents shown in the header">
|
|
140
|
-
|
|
141
|
-
**Agents and models at work.** Helper agents that a tool starts appear on its
|
|
142
|
-
card as familiars while they run, and the card names the model in use. The
|
|
143
|
-
character comes alive while the session works, and the session's level rises
|
|
144
|
-
with every hour it runs.
|
|
145
|
-
|
|
146
|
-
**Several subscriptions per tool.** Add a work account next to your personal
|
|
147
|
-
one and switch with a chip on the card. Each account keeps its own sign-in,
|
|
148
|
-
usage meters and sessions. See [Accounts](docs/configuration.md#accounts).
|
|
149
|
-
|
|
150
|
-
**See what is left of your limits.** Claude Code and Codex CLI
|
|
151
|
-
cards show a meter for each rate-limit window, such as 5-hour and 7-day, with
|
|
152
|
-
the time until it resets. They also show your plan, Claude's extra-usage
|
|
153
|
-
spend and Codex's credit balance when the account has them. Any other tool
|
|
154
|
-
can supply a command that prints its usage.
|
|
155
|
-
|
|
156
|
-
**Pick the right model.** Each card grades the tool's newest fully
|
|
157
|
-
benchmarked model on coding, intelligence and agentic work, from S to D. Open it to compare every
|
|
158
|
-
model the tool offers across 13 benchmarks: Artificial Analysis indexes and
|
|
159
|
-
Design Arena results for websites, UI, game dev, data visualization, 3D, SVG,
|
|
160
|
-
web apps, full stack and mobile. It also shows context size and price.
|
|
161
|
-
|
|
162
|
-
<img src="docs/images/models.webp" alt="The Claude Code models dialog with benchmark tiers for each model">
|
|
163
|
-
|
|
164
|
-
**Pick up where you left off.** **Existing…** lists the tool's own earlier
|
|
165
|
-
sessions, newest first, read from where the tool keeps them. Filter by title,
|
|
166
|
-
folder or id and resume one in its own folder, or resume any session by id.
|
|
167
|
-
|
|
168
|
-
<img src="docs/images/history.webp" alt="The Claude Code session history with a filter and Resume buttons">
|
|
169
|
-
|
|
170
|
-
**Agentic development news.** A newsfeed gathers about 20 sources on AI
|
|
171
|
-
coding, agents and local models, including vendor blogs, Hacker News, arXiv,
|
|
172
|
-
and releases of the tools you have installed. The five latest headlines
|
|
173
|
-
appear on the page; **All news** opens the full feed with News, Releases and Research
|
|
174
|
-
filters.
|
|
175
|
-
|
|
176
|
-
<img src="docs/images/news.webp" alt="The news panel with today's items from news sources and tool releases">
|
|
177
|
-
|
|
178
|
-
**Always current.** When a new Agent Guild is published, **Upgrade to
|
|
179
|
-
vX.Y.Z** installs it while your sessions keep running, and **Restart to use
|
|
180
|
-
vX.Y.Z** switches over when you are ready. The version badge opens
|
|
181
|
-
**What's new** with the notes of every release.
|
|
182
|
-
|
|
183
|
-
<img src="docs/images/whats-new.webp" alt="The What's new panel listing the release notes of each version">
|
|
184
|
-
|
|
185
|
-
**Keep notes at hand.** **Notes** in the top bar opens a notepad for prompts,
|
|
186
|
-
commands and to-dos in the side panel, next to your terminals. It saves up to
|
|
187
|
-
100,000 characters as you type. The same notes follow every browser signed in
|
|
188
|
-
to this manager, including one opened through remote access. This browser
|
|
189
|
-
keeps a copy too: if the manager is unreachable, the line under the title
|
|
190
|
-
says the notes are saved in this browser only, and they sync when it is back.
|
|
191
|
-
|
|
192
|
-
**GitHub beside your work.** **GitHub** in the top bar opens the side panel.
|
|
193
|
-
Sign in to one or more GitHub accounts, then search the repositories of all
|
|
194
|
-
of them from the box at its top; it starts on the repository the focused
|
|
195
|
-
terminal's folder is a clone of. **Issues** lists, opens, edits and closes
|
|
196
|
-
issues. **Actions** shows the latest workflow runs and whether one is still
|
|
197
|
-
going, refreshing while it is on screen. **Pull requests** lists the open
|
|
198
|
-
ones. **Branches** lists every remote branch of the selected repository, with
|
|
199
|
-
its default and protected branches marked. Filter by name, copy a branch name,
|
|
200
|
-
or open it on GitHub. Larger lists load progressively; **Refresh** checks for
|
|
201
|
-
changes while keeping your place in the list. **Repositories** lists and creates
|
|
202
|
-
repositories and clones them over SSH with a key Agent Guild keeps for each account. On a wide window the side panel
|
|
203
|
-
makes room for itself; on a smaller one it lies over the cards, and over the
|
|
204
|
-
terminals when they would get too narrow. Drag its edge to resize it. Escape
|
|
205
|
-
or **Close** puts it away.
|
|
118
|
+
* Real terminals that survive closing or reloading the page
|
|
119
|
+
* Two terminals side by side with **Split**
|
|
120
|
+
* Install and update each tool from its card
|
|
121
|
+
* Helper agents and the model in use, shown on each card
|
|
122
|
+
([setup per tool](docs/agent-reporting.md))
|
|
123
|
+
* Rate-limit meters for Claude Code and Codex CLI
|
|
124
|
+
* Several accounts per tool ([accounts](docs/configuration.md#accounts))
|
|
125
|
+
* Model grades and benchmarks for each tool's models
|
|
126
|
+
* Resume a tool's earlier sessions with **Existing…**
|
|
127
|
+
* GitHub issues, pull requests, workflow runs, branches and cloning
|
|
128
|
+
* Shared notes, a news feed, six skins, light and dark mode
|
|
129
|
+
* tmux and herdr sessions that keep running when the manager stops
|
|
206
130
|
|
|
207
131
|
<img src="docs/images/workspace.webp" alt="Two terminals side by side with the GitHub panel showing the workflow runs of the focused terminal's repository">
|
|
208
132
|
|
|
209
|
-
**Settings.** The Settings menu in the top bar picks a skin and light or
|
|
210
|
-
dark mode, without a reload. On a narrow window the top bar's buttons gather
|
|
211
|
-
under its menu button. **Guild** is the default fantasy look;
|
|
212
|
-
**Professional** is a plain business look with no characters; **Orbital**
|
|
213
|
-
puts a crew of little robots in deep space; **Grove** is a calm moss garden
|
|
214
|
-
of gentle nature spirits; **Gnomeland** is a lantern-lit village of gnome
|
|
215
|
-
builders, engineers with a little magic; **Goblinville** is a steam-powered
|
|
216
|
-
town of goblin, orc, ogre and troll builders on stilts over a bog. The page
|
|
217
|
-
follows your system's light or dark setting until you pick one. See
|
|
218
|
-
[docs/SKINS.md](docs/SKINS.md) to make another. **Alert sounds**, off until
|
|
219
|
-
you turn them on in the same menu, chime when the session manager confirms
|
|
220
|
-
a stop or restart, remains unavailable after a brief recovery check, or a
|
|
221
|
-
new version is discovered after the initial version check. Session activity
|
|
222
|
-
and assistant responses have no sounds:
|
|
223
|
-
the providers do not yet offer consistently reliable completion signals.
|
|
224
|
-
**Launch at sign-in**, in the same menu, starts the session manager in the
|
|
225
|
-
background whenever you sign in to the computer running Agent Guild; open
|
|
226
|
-
the page as usual afterwards. On Windows it is an entry in Task Manager's
|
|
227
|
-
Startup apps, on macOS a background item named Agent Guild under System
|
|
228
|
-
Settings › General › Login Items & Extensions, and on Linux an entry named
|
|
229
|
-
Agent Guild in the desktop's startup settings, so it needs a desktop session
|
|
230
|
-
there: a server reached over SSH does not start it. macOS keeps its own
|
|
231
|
-
switch for that item, which Agent Guild cannot read: switched off there, it
|
|
232
|
-
does not start even while **Launch at sign-in** is checked. While it is on,
|
|
233
|
-
the setting says when it last ran at sign-in and whether the session manager
|
|
234
|
-
started then.
|
|
235
|
-
|
|
236
|
-
The browser tab icon adds a rotating green ring whenever any session card says
|
|
237
|
-
**Working**, including Shell and task cards. It mirrors the cards' terminal
|
|
238
|
-
activity, not assistant completion. The ring remains visible with reduced
|
|
239
|
-
motion or when the browser pauses animation. During a connection interruption,
|
|
240
|
-
it reflects the last card state until the page reconnects.
|
|
241
|
-
|
|
242
|
-
Sounds play in one eligible tab per browser and origin after browser playback
|
|
243
|
-
permission (usually a click or keypress). They require Web Locks and writable
|
|
244
|
-
local storage. Opening or reconnecting a page does not replay old alerts,
|
|
245
|
-
even when a different manager has taken over. Closing a browser does not
|
|
246
|
-
stop the manager. After an unexpected disconnect, an already connected page
|
|
247
|
-
checks the local health endpoint twice, two seconds apart, with a one-second
|
|
248
|
-
timeout per request. If both fail, it shows “Manager unavailable” and alerts
|
|
249
|
-
once; it cannot confirm whether the process exited or sessions ended.
|
|
250
|
-
A successful health check, reconnection, or closing the page cancels the alert.
|
|
251
|
-
There is no added polling while connected and no additional monitoring process.
|
|
252
|
-
|
|
253
133
|
## Commands
|
|
254
134
|
|
|
255
135
|
| Command | What it does |
|
|
256
136
|
| --- | --- |
|
|
257
|
-
| `agent-guild`
|
|
137
|
+
| `agent-guild` | Start the manager if needed and open the page. `--no-browser` prints the link instead. |
|
|
258
138
|
| `agent-guild status` | Show whether the manager is running and list its sessions. |
|
|
259
|
-
| `agent-guild stop` | Stop the manager
|
|
260
|
-
| `agent-guild restart` |
|
|
261
|
-
| `agent-guild url` | Print the page
|
|
262
|
-
| `agent-guild start` | Run the manager in the foreground
|
|
139
|
+
| `agent-guild stop` | Stop the manager and end every session. |
|
|
140
|
+
| `agent-guild restart` | Restart the manager on the installed version and end every session. |
|
|
141
|
+
| `agent-guild url` | Print the page link with the access token. |
|
|
142
|
+
| `agent-guild start` | Run the manager in the foreground. |
|
|
263
143
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
asks before you close it with sessions running. Sessions end when the manager
|
|
267
|
-
stops or the computer restarts.
|
|
144
|
+
Sessions end when the manager stops or the computer restarts. tmux and herdr
|
|
145
|
+
sessions survive a manager stop.
|
|
268
146
|
|
|
269
|
-
##
|
|
147
|
+
## Privacy
|
|
270
148
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
| Platform | Data folder |
|
|
276
|
-
| --- | --- |
|
|
277
|
-
| Windows | `%APPDATA%\AgentGuild` |
|
|
278
|
-
| macOS | `~/Library/Application Support/AgentGuild` |
|
|
279
|
-
| Linux | `~/.config/agent-guild` |
|
|
280
|
-
|
|
281
|
-
The full reference, including every field and environment variable, is in
|
|
282
|
-
[docs/configuration.md](docs/configuration.md).
|
|
283
|
-
|
|
284
|
-
## Show agents and models
|
|
285
|
-
|
|
286
|
-
Agents are reported by the coding tool's hooks, not guessed from its output.
|
|
287
|
-
Each helper agent appears on the card while it runs. Agent Guild gives every
|
|
288
|
-
Claude Code and Codex CLI session its reporting hooks for that session only,
|
|
289
|
-
without changing the tool's own settings. Antigravity CLI has no such option:
|
|
290
|
-
turn on **Agent reporting** on its card once, which installs an Agent Guild
|
|
291
|
-
plugin into Antigravity. It reports the model and the conversation, but no
|
|
292
|
-
helper agents or shell commands. Grok Build cannot take hooks for one session yet; add the hooks
|
|
293
|
-
from [examples/grok-hooks.json](examples/grok-hooks.json) to see its agents.
|
|
294
|
-
When a tool's hooks have not reported some time after a prompt was sent,
|
|
295
|
-
because hooks are turned off, restricted by an administrator or not trusted
|
|
296
|
-
for the folder, the card says so.
|
|
297
|
-
|
|
298
|
-
The card also names the model, from the hooks, from `--model` or from the
|
|
299
|
-
tool's screen.
|
|
300
|
-
|
|
301
|
-
Any other tool or script can report agents and its model too. See
|
|
302
|
-
[docs/agent-reporting.md](docs/agent-reporting.md).
|
|
303
|
-
|
|
304
|
-
## Security and privacy
|
|
305
|
-
|
|
306
|
-
* The manager listens on `127.0.0.1` only. **Settings → Remote access** sets
|
|
307
|
-
up a private Tailscale address without restarting your terminals. See
|
|
308
|
-
[remote access and other proxies](docs/configuration.md#reverse-proxies).
|
|
309
|
-
* Every API call needs a random per-user token, stored in the data folder
|
|
310
|
-
with owner-only permissions. Anyone who can run programs as your user can
|
|
311
|
-
read it, as with any local developer tool.
|
|
312
|
-
* Requests with a foreign `Host` or `Origin` header are refused, so other
|
|
313
|
-
websites cannot reach your terminals through your browser.
|
|
314
|
-
* Tools inside a session get a separate token that can only report agents
|
|
315
|
-
for that session.
|
|
316
|
-
* GitHub sign-ins, the SSH key Agent Guild makes for each GitHub account and
|
|
317
|
-
GitHub's SSH host keys are kept in the `github` folder of the data folder,
|
|
318
|
-
readable only by you. A clone uses only that key and those host keys; your
|
|
319
|
-
own `~/.ssh` and Git configuration are not read or changed.
|
|
320
|
-
* Usage meters are fetched by the manager with each tool's own sign-in. The
|
|
321
|
-
page only receives percentages. On macOS the first lookup may ask for
|
|
322
|
-
keychain access to the "Claude Code-credentials" item; choose Always Allow.
|
|
323
|
-
* **Launch at sign-in** writes outside the data folder only while it is on:
|
|
324
|
-
the `AgentGuild` value under
|
|
325
|
-
`HKCU\Software\Microsoft\Windows\CurrentVersion\Run` on Windows, which
|
|
326
|
-
runs `autostart.js` from the data folder through `wscript.exe` so no
|
|
327
|
-
console window opens;
|
|
328
|
-
`~/Library/LaunchAgents/com.oddessentials.agent-guild.plist` on macOS,
|
|
329
|
-
which runs the `Agent Guild` script in the data folder so that macOS lists
|
|
330
|
-
it by that name; and `~/.config/autostart/agent-guild.desktop` on Linux,
|
|
331
|
-
which runs `autostart.sh` from the data folder. On Linux, a Node.js,
|
|
332
|
-
package or data folder path holding `"`, `` ` ``, `$` or `\` cannot be
|
|
333
|
-
used, because desktops read those differently in a startup entry; the
|
|
334
|
-
setting then says so. Each sign-in touches `sign-in-attempt` and records
|
|
335
|
-
its outcome in `sign-in.json` in the data folder.
|
|
336
|
-
Turning it off removes them, and an entry whose Agent Guild package has
|
|
337
|
-
been uninstalled or moved removes itself at the next sign-in. With nvm,
|
|
338
|
-
the package lives in the Node.js version's folder, so uninstalling that
|
|
339
|
-
version counts as uninstalling Agent Guild; a Homebrew Node.js upgrade
|
|
340
|
-
or a Snap Node.js refresh does not. On macOS and Linux what the entry runs at sign-in, including a
|
|
341
|
-
missing Node.js, is appended to `manager.log`.
|
|
342
|
-
The entry saves the manager's listening port, including the assigned port
|
|
343
|
-
when started with `AGENT_GUILD_PORT=0`. Enabled entries are updated when
|
|
344
|
-
the manager starts. A macOS entry disabled through `launchctl` stays off
|
|
345
|
-
until you explicitly turn **Launch at sign-in** back on.
|
|
346
|
-
|
|
347
|
-
The manager makes these outbound requests, and none of them carry your code
|
|
348
|
-
or prompts:
|
|
149
|
+
The manager listens on `127.0.0.1` only. Remote access goes through a private
|
|
150
|
+
Tailscale route or your own reverse proxy to that address. None of these
|
|
151
|
+
requests carry your code or prompts:
|
|
349
152
|
|
|
350
153
|
| To | For | How often |
|
|
351
154
|
| --- | --- | --- |
|
|
352
|
-
| npm registry |
|
|
353
|
-
| Anthropic and OpenAI
|
|
354
|
-
| OpenRouter
|
|
355
|
-
|
|
|
356
|
-
| GitHub
|
|
357
|
-
| herdr.dev
|
|
358
|
-
|
|
|
359
|
-
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
[
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
```sh
|
|
371
|
-
git clone https://github.com/oddessentials/agent-guild.git
|
|
372
|
-
cd agent-guild
|
|
373
|
-
npm install
|
|
374
|
-
npm start # open the page, starting a manager from this checkout if none runs
|
|
375
|
-
npm test
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
* The tests start real managers and real pseudo-terminals, using a small fake
|
|
379
|
-
coding tool in `tests/fixtures`. CI runs them on Windows, macOS and Linux
|
|
380
|
-
with Node.js 22, 24 and 26, and installs the packed package on x64 and
|
|
381
|
-
arm64.
|
|
382
|
-
* `node tests/browser/proxy.mjs` checks the real UI and terminal through a
|
|
383
|
-
local HTTPS proxy with an isolated manager and test certificates. Set
|
|
384
|
-
`CHROME_PATH` to Chrome or Edge if it is not in a standard location.
|
|
385
|
-
* In a checkout, `launchers/AgentGuild.cmd` (Windows) and
|
|
386
|
-
`launchers/AgentGuild.command` (macOS) start Agent Guild with a
|
|
387
|
-
double-click.
|
|
388
|
-
* `node docs/capture/capture.mjs --root <folder>` refreshes the screenshots
|
|
389
|
-
in `docs/images` from the real page, with demo sessions in place of real
|
|
390
|
-
tools. The cards show the folder's path, so pick a neutral one such as
|
|
391
|
-
`D:\code` or `/work`. It needs Chrome or Edge and leaves any running
|
|
392
|
-
manager alone. See the comment at the top of the script for options.
|
|
393
|
-
* Pull request titles follow
|
|
394
|
-
[Conventional Commits](https://www.conventionalcommits.org/). Merging to
|
|
395
|
-
`main` publishes a release to npm and GitHub when it includes a `feat`,
|
|
396
|
-
`fix`, `perf` or `revert`.
|
|
397
|
-
|
|
398
|
-
## Current limits
|
|
399
|
-
|
|
400
|
-
* Sessions end when the manager stops or the computer restarts, except a
|
|
401
|
-
Shell session in tmux or herdr, which keeps running in it while the
|
|
402
|
-
manager is stopped.
|
|
403
|
-
* Antigravity CLI and Grok Build have no usage meter.
|
|
404
|
-
* Antigravity CLI has one account per computer user: it keeps its sign-in in
|
|
405
|
-
the system keychain and has no setting for another home folder.
|
|
155
|
+
| npm registry | Version checks | Hourly |
|
|
156
|
+
| Anthropic and OpenAI | Usage meters, with the tool's own sign-in | Every minute while the page is open |
|
|
157
|
+
| OpenRouter | Model list for benchmarks | Every 6 hours |
|
|
158
|
+
| News feeds, Hacker News, arXiv, GitHub | News feed | Every 30 minutes while the page is open |
|
|
159
|
+
| GitHub releases | What's new | Hourly, more often just after a release |
|
|
160
|
+
| herdr.dev, Homebrew | Multiplexer version checks | Hourly |
|
|
161
|
+
| GitHub, GitHub Status | GitHub panel | When you use it |
|
|
162
|
+
| Package sources | Installs and updates | When you ask |
|
|
163
|
+
|
|
164
|
+
Failed news, model list and release checks retry after 10 minutes.
|
|
165
|
+
`AGENT_GUILD_NO_UPDATE_CHECK=1` turns off version checks and self-upgrade.
|
|
166
|
+
|
|
167
|
+
## More
|
|
168
|
+
|
|
169
|
+
* [Configuration](docs/configuration.md): add tools, accounts, environment variables, reverse proxies
|
|
170
|
+
* [Agent reporting](docs/agent-reporting.md): show agents from any tool
|
|
171
|
+
* [Skins](docs/SKINS.md): make your own look
|
|
172
|
+
* [Contributing](CONTRIBUTING.md)
|
|
406
173
|
|
|
407
174
|
## License
|
|
408
175
|
|
package/bin/agent-guild.mjs
CHANGED
|
@@ -19,8 +19,9 @@ import {
|
|
|
19
19
|
readRuntimeFile,
|
|
20
20
|
resolvePort,
|
|
21
21
|
} from '../src/manager/config.mjs';
|
|
22
|
-
import { spawnManager } from '../src/manager/launch.mjs';
|
|
22
|
+
import { defaultBoot, serviceFor, spawnManager, startService } from '../src/manager/launch.mjs';
|
|
23
23
|
import { recordSignIn } from '../src/manager/autostart.mjs';
|
|
24
|
+
import { EXIT_PORT_IN_USE, describeStartup, startupState, startupSummary, unitPort } from '../src/manager/systemd-service.mjs';
|
|
24
25
|
|
|
25
26
|
function usage() {
|
|
26
27
|
console.log(`Usage: agent-guild [command] [--no-browser]
|
|
@@ -105,6 +106,11 @@ async function ensureManager({ port = null } = {}) {
|
|
|
105
106
|
const running = await health(knownUrl);
|
|
106
107
|
if (running) return { url: knownUrl, started: false, version: running.version };
|
|
107
108
|
|
|
109
|
+
// While the boot service is on for this port, systemd is the one that starts a manager.
|
|
110
|
+
const { boot, note } = await serviceFor(listenPort);
|
|
111
|
+
if (boot) return startService({ boot, port: listenPort, url: expectedUrl, health });
|
|
112
|
+
if (note) console.log(note);
|
|
113
|
+
|
|
108
114
|
const child = spawnManager({ env: { ...process.env, AGENT_GUILD_PORT: String(listenPort) } });
|
|
109
115
|
|
|
110
116
|
let exited = false;
|
|
@@ -223,15 +229,26 @@ async function cmdStatus() {
|
|
|
223
229
|
const h = await health(url);
|
|
224
230
|
if (!h) {
|
|
225
231
|
console.log('Session manager is not running.');
|
|
232
|
+
// With no manager to ask, the boot service is read from systemd directly.
|
|
233
|
+
const boot = defaultBoot();
|
|
234
|
+
const read = boot && await boot.read().catch(() => null);
|
|
235
|
+
if (read?.enabled) {
|
|
236
|
+
const port = unitPort(await boot.text().catch(() => null));
|
|
237
|
+
console.log(describeStartup(startupState(read.show, { port }), { linger: read.linger, user: boot.user }));
|
|
238
|
+
}
|
|
226
239
|
process.exitCode = 3;
|
|
227
240
|
return;
|
|
228
241
|
}
|
|
229
|
-
const
|
|
242
|
+
const headers = { Authorization: `Bearer ${loadOrCreateToken()}` };
|
|
243
|
+
const res = await fetch(`${url}/api/v1/sessions`, { headers });
|
|
230
244
|
const { sessions = [] } = res.ok ? await res.json() : {};
|
|
231
245
|
const running = sessions.filter((s) => s.status === 'running').length;
|
|
232
246
|
console.log(`Session manager ${h.version} running at ${url} (pid ${h.pid}).`);
|
|
233
247
|
const notice = versionNotice(h.version);
|
|
234
248
|
if (notice) console.log(notice);
|
|
249
|
+
const startup = await fetch(`${url}/api/v1/autostart`, { headers }).then((r) => (r.ok ? r.json() : {}), () => ({}));
|
|
250
|
+
const summary = startupSummary(startup.autostart);
|
|
251
|
+
if (summary) console.log(summary);
|
|
235
252
|
console.log(`${sessions.length} session(s), ${running} running.`);
|
|
236
253
|
for (const s of sessions) {
|
|
237
254
|
const model = s.model ? ` [${s.model.displayName || s.model.name}]` : '';
|
|
@@ -255,10 +272,19 @@ async function main() {
|
|
|
255
272
|
switch (command) {
|
|
256
273
|
case 'open': return cmdOpen({ browser: !flags.has('--no-browser'), signIn: flags.has('--sign-in') });
|
|
257
274
|
case 'start': {
|
|
275
|
+
// `--service`: run by the Linux boot service, which systemd supervises.
|
|
276
|
+
const supervised = flags.has('--service');
|
|
258
277
|
await import('../src/manager/main.mjs').then(async (m) => {
|
|
259
278
|
process.on('uncaughtException', (err) => console.error('[manager] unexpected error:', err));
|
|
260
279
|
process.on('unhandledRejection', (err) => console.error('[manager] unhandled rejection:', err));
|
|
261
|
-
const { shutdown } = await m.startManager()
|
|
280
|
+
const { shutdown } = await m.startManager({ supervised }).catch((err) => {
|
|
281
|
+
// Another manager has the port: an exit systemd does not retry, and the page reports.
|
|
282
|
+
if (supervised && err.code === 'EADDRINUSE') {
|
|
283
|
+
console.error(`agent-guild: ${err.message}`);
|
|
284
|
+
process.exit(EXIT_PORT_IN_USE);
|
|
285
|
+
}
|
|
286
|
+
throw err;
|
|
287
|
+
});
|
|
262
288
|
console.log(`Open: ${pageUrl(readRuntimeFile()?.url ?? baseUrl(), loadOrCreateToken())}`);
|
|
263
289
|
for (const sig of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
|
264
290
|
process.on(sig, () => shutdown(sig).then(() => process.exit(0)));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oddessentials/agent-guild",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Launch and watch AI coding-assistant terminal sessions from one local web page. A bundled session manager owns the terminals so the page can close and reconnect.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|