awb-agent-manager 1.0.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/LICENSE +21 -0
- package/README.md +246 -0
- package/dist/lib/agent-lockfile.d.ts +37 -0
- package/dist/lib/agent-lockfile.js +205 -0
- package/dist/lib/agent-lockfile.js.map +1 -0
- package/dist/lib/agent-manager-commands.d.ts +34 -0
- package/dist/lib/agent-manager-commands.js +531 -0
- package/dist/lib/agent-manager-commands.js.map +1 -0
- package/dist/lib/base-session-manager.d.ts +127 -0
- package/dist/lib/base-session-manager.js +667 -0
- package/dist/lib/base-session-manager.js.map +1 -0
- package/dist/lib/chat-attachment-prep.d.ts +35 -0
- package/dist/lib/chat-attachment-prep.js +180 -0
- package/dist/lib/chat-attachment-prep.js.map +1 -0
- package/dist/lib/chat-session-manager.d.ts +29 -0
- package/dist/lib/chat-session-manager.js +400 -0
- package/dist/lib/chat-session-manager.js.map +1 -0
- package/dist/lib/circuit-breaker.d.ts +34 -0
- package/dist/lib/circuit-breaker.js +146 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/cli-adapters/antigravity.d.ts +15 -0
- package/dist/lib/cli-adapters/antigravity.js +114 -0
- package/dist/lib/cli-adapters/antigravity.js.map +1 -0
- package/dist/lib/cli-adapters/base.d.ts +115 -0
- package/dist/lib/cli-adapters/base.js +111 -0
- package/dist/lib/cli-adapters/base.js.map +1 -0
- package/dist/lib/cli-adapters/claude.d.ts +19 -0
- package/dist/lib/cli-adapters/claude.js +233 -0
- package/dist/lib/cli-adapters/claude.js.map +1 -0
- package/dist/lib/cli-adapters/codex.d.ts +14 -0
- package/dist/lib/cli-adapters/codex.js +152 -0
- package/dist/lib/cli-adapters/codex.js.map +1 -0
- package/dist/lib/cli-adapters/deepseek.d.ts +15 -0
- package/dist/lib/cli-adapters/deepseek.js +70 -0
- package/dist/lib/cli-adapters/deepseek.js.map +1 -0
- package/dist/lib/cli-adapters/index.d.ts +8 -0
- package/dist/lib/cli-adapters/index.js +27 -0
- package/dist/lib/cli-adapters/index.js.map +1 -0
- package/dist/lib/cli-adapters/model-introspect.d.ts +3 -0
- package/dist/lib/cli-adapters/model-introspect.js +65 -0
- package/dist/lib/cli-adapters/model-introspect.js.map +1 -0
- package/dist/lib/cli-error-signatures.d.ts +9 -0
- package/dist/lib/cli-error-signatures.js +22 -0
- package/dist/lib/cli-error-signatures.js.map +1 -0
- package/dist/lib/cli-output-summary.d.ts +2 -0
- package/dist/lib/cli-output-summary.js +104 -0
- package/dist/lib/cli-output-summary.js.map +1 -0
- package/dist/lib/cli-resolver.d.ts +2 -0
- package/dist/lib/cli-resolver.js +177 -0
- package/dist/lib/cli-resolver.js.map +1 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.js +124 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +36 -0
- package/dist/lib/constants.js +51 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/environment-provisioner.d.ts +31 -0
- package/dist/lib/environment-provisioner.js +182 -0
- package/dist/lib/environment-provisioner.js.map +1 -0
- package/dist/lib/error-log-uploader.d.ts +19 -0
- package/dist/lib/error-log-uploader.js +138 -0
- package/dist/lib/error-log-uploader.js.map +1 -0
- package/dist/lib/event-dispatcher.d.ts +149 -0
- package/dist/lib/event-dispatcher.js +799 -0
- package/dist/lib/event-dispatcher.js.map +1 -0
- package/dist/lib/event-log-recorder.d.ts +11 -0
- package/dist/lib/event-log-recorder.js +77 -0
- package/dist/lib/event-log-recorder.js.map +1 -0
- package/dist/lib/event-stream.d.ts +26 -0
- package/dist/lib/event-stream.js +177 -0
- package/dist/lib/event-stream.js.map +1 -0
- package/dist/lib/fs-browser.d.ts +30 -0
- package/dist/lib/fs-browser.js +287 -0
- package/dist/lib/fs-browser.js.map +1 -0
- package/dist/lib/host-mcp/logs.d.ts +19 -0
- package/dist/lib/host-mcp/logs.js +102 -0
- package/dist/lib/host-mcp/logs.js.map +1 -0
- package/dist/lib/host-mcp/platform.d.ts +24 -0
- package/dist/lib/host-mcp/platform.js +133 -0
- package/dist/lib/host-mcp/platform.js.map +1 -0
- package/dist/lib/host-mcp/screens.d.ts +22 -0
- package/dist/lib/host-mcp/screens.js +172 -0
- package/dist/lib/host-mcp/screens.js.map +1 -0
- package/dist/lib/host-mcp/server.d.ts +3 -0
- package/dist/lib/host-mcp/server.js +233 -0
- package/dist/lib/host-mcp/server.js.map +1 -0
- package/dist/lib/host-mcp/tools.d.ts +172 -0
- package/dist/lib/host-mcp/tools.js +1241 -0
- package/dist/lib/host-mcp/tools.js.map +1 -0
- package/dist/lib/instance-heartbeat.d.ts +55 -0
- package/dist/lib/instance-heartbeat.js +118 -0
- package/dist/lib/instance-heartbeat.js.map +1 -0
- package/dist/lib/legacy-import.d.ts +17 -0
- package/dist/lib/legacy-import.js +70 -0
- package/dist/lib/legacy-import.js.map +1 -0
- package/dist/lib/logging.d.ts +3 -0
- package/dist/lib/logging.js +65 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/managed-agent-context.d.ts +25 -0
- package/dist/lib/managed-agent-context.js +33 -0
- package/dist/lib/managed-agent-context.js.map +1 -0
- package/dist/lib/managed-agent-store.d.ts +34 -0
- package/dist/lib/managed-agent-store.js +160 -0
- package/dist/lib/managed-agent-store.js.map +1 -0
- package/dist/lib/managed-agents.d.ts +24 -0
- package/dist/lib/managed-agents.js +87 -0
- package/dist/lib/managed-agents.js.map +1 -0
- package/dist/lib/mcp-client.d.ts +8 -0
- package/dist/lib/mcp-client.js +122 -0
- package/dist/lib/mcp-client.js.map +1 -0
- package/dist/lib/orphan-cleanup.d.ts +6 -0
- package/dist/lib/orphan-cleanup.js +108 -0
- package/dist/lib/orphan-cleanup.js.map +1 -0
- package/dist/lib/presence-heartbeat.d.ts +8 -0
- package/dist/lib/presence-heartbeat.js +61 -0
- package/dist/lib/presence-heartbeat.js.map +1 -0
- package/dist/lib/prompts.d.ts +29 -0
- package/dist/lib/prompts.js +208 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/rest.d.ts +61 -0
- package/dist/lib/rest.js +307 -0
- package/dist/lib/rest.js.map +1 -0
- package/dist/lib/run-provisioner.d.ts +21 -0
- package/dist/lib/run-provisioner.js +115 -0
- package/dist/lib/run-provisioner.js.map +1 -0
- package/dist/lib/self-path.d.ts +7 -0
- package/dist/lib/self-path.js +29 -0
- package/dist/lib/self-path.js.map +1 -0
- package/dist/lib/self-update.d.ts +46 -0
- package/dist/lib/self-update.js +482 -0
- package/dist/lib/self-update.js.map +1 -0
- package/dist/lib/service-install.d.ts +23 -0
- package/dist/lib/service-install.js +673 -0
- package/dist/lib/service-install.js.map +1 -0
- package/dist/lib/setup.d.ts +16 -0
- package/dist/lib/setup.js +157 -0
- package/dist/lib/setup.js.map +1 -0
- package/dist/lib/subagent-manager.d.ts +84 -0
- package/dist/lib/subagent-manager.js +793 -0
- package/dist/lib/subagent-manager.js.map +1 -0
- package/dist/lib/subagent-monitor.d.ts +43 -0
- package/dist/lib/subagent-monitor.js +229 -0
- package/dist/lib/subagent-monitor.js.map +1 -0
- package/dist/lib/ticket-session-manager.d.ts +23 -0
- package/dist/lib/ticket-session-manager.js +471 -0
- package/dist/lib/ticket-session-manager.js.map +1 -0
- package/dist/lib/worktree-manager.d.ts +39 -0
- package/dist/lib/worktree-manager.js +226 -0
- package/dist/lib/worktree-manager.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +670 -0
- package/dist/main.js.map +1 -0
- package/dist/package.json +57 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 parnmanas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# awb-agent-manager
|
|
2
|
+
|
|
3
|
+
Standalone subagent runner for [AI Workflow Board](../../README.md). Connects to
|
|
4
|
+
an AWB server over SSE + REST, spawns CLI-driven agents (Claude, Codex, Antigravity,
|
|
5
|
+
or any custom binary that speaks MCP), and reports liveness back to the AWB
|
|
6
|
+
admin dashboard.
|
|
7
|
+
|
|
8
|
+
This package replaces the daemon that used to live inside the
|
|
9
|
+
`@parnmanas/awb` Claude plugin. The plugin (in
|
|
10
|
+
[`submodules/claude-plugins/ai-workflow-board/`](../../../claude-plugins/ai-workflow-board/))
|
|
11
|
+
is now a pure stdio↔HTTP MCP forwarder. agent-manager owns everything else:
|
|
12
|
+
SSE event delivery, persistent ticket/chat sessions, subagent supervision, fs
|
|
13
|
+
browser, instance heartbeats, and CLI lifecycle management.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
17
|
+
│ AWB server (NestJS) │
|
|
18
|
+
│ ├── /api/agent-manager/* pairing, agent identity RPC │
|
|
19
|
+
│ ├── /api/admin/agent-manager/* instance dashboard, command │
|
|
20
|
+
│ └── SSE event stream ─────────────┐ │
|
|
21
|
+
└─────────────────────────────────────┬─┘ │
|
|
22
|
+
│ HTTP (Bearer key) │
|
|
23
|
+
▼ │
|
|
24
|
+
┌─────────────────────────────────────────────────────────────────┐│
|
|
25
|
+
│ awb-agent-manager (this package) ││
|
|
26
|
+
│ ├── EventStream SSE consumer + reconnect ││
|
|
27
|
+
│ ├── EventDispatcher route → ticket / chat / fs / command ││
|
|
28
|
+
│ ├── ManagedAgents spawn / stop / restart CLI children ││
|
|
29
|
+
│ └── InstanceHeartbeat per-process registry ping ──────────────┘
|
|
30
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
31
|
+
│ stdio
|
|
32
|
+
▼
|
|
33
|
+
claude / codex / antigravity / custom CLI
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
### npm (recommended)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm i -g @awb/agent-manager
|
|
42
|
+
awb-agent-manager --version
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
> The package is not yet published to the public npm registry. Until it ships,
|
|
46
|
+
> install from a local checkout (see "Development").
|
|
47
|
+
|
|
48
|
+
### Docker
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
docker run --rm -it \
|
|
52
|
+
-v "$HOME/.config/awb-agent-manager:/data" \
|
|
53
|
+
-e AWB_AGENT_MANAGER_HOME=/data \
|
|
54
|
+
ghcr.io/parnmanas/awb-agent-manager:latest
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The image bundles `node:22-alpine` plus the manager binary. Mount a host
|
|
58
|
+
directory for `AWB_AGENT_MANAGER_HOME` so config + lockfile survive container
|
|
59
|
+
restarts. Bind-mount each agent's working directory the same way (e.g.
|
|
60
|
+
`-v $HOME/repos:/repos`) and configure those paths inside AWB.
|
|
61
|
+
|
|
62
|
+
## First run — pairing with an AWB server
|
|
63
|
+
|
|
64
|
+
The manager bootstraps from a one-time pairing token minted by an AWB admin.
|
|
65
|
+
After redeeming, the manager stores its API key and agent identity in
|
|
66
|
+
`$AWB_AGENT_MANAGER_HOME/config.json` (default
|
|
67
|
+
`~/.config/awb-agent-manager/config.json`).
|
|
68
|
+
|
|
69
|
+
1. **Mint** — In the AWB admin UI: _Admin → Agent Manager → Pair manager…_.
|
|
70
|
+
The dialog returns a raw token (long-form) and a 6-char display code; copy
|
|
71
|
+
either. Both are shown only once. TTL 10 minutes, single-use.
|
|
72
|
+
2. **Run the wizard** — On the host that will run the manager:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
awb-agent-manager setup
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
You'll be prompted for:
|
|
79
|
+
- AWB server URL (e.g. `https://awb.example.com:7700`)
|
|
80
|
+
- Pairing token (paste from step 1)
|
|
81
|
+
- CLI to drive (`claude` / `codex` / `antigravity`, default `claude`)
|
|
82
|
+
|
|
83
|
+
The wizard calls `/api/agent-manager/pair/redeem`, then writes
|
|
84
|
+
`~/.config/awb-agent-manager/config.json` with mode 0600. Output:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
✓ paired
|
|
88
|
+
agent_id <uuid>
|
|
89
|
+
workspace_id <uuid>
|
|
90
|
+
apiKey awb_abcd***xyz9
|
|
91
|
+
✓ wrote ~/.config/awb-agent-manager/config.json (mode 0600)
|
|
92
|
+
|
|
93
|
+
Next: run `awb-agent-manager` to start the manager.
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Non-interactive form (CI / Ansible — fails fast on missing fields):
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
awb-agent-manager setup \
|
|
100
|
+
--url https://awb.example.com:7700 \
|
|
101
|
+
--token ABCXYZ123 \
|
|
102
|
+
--cli claude \
|
|
103
|
+
--non-interactive
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`instance_id` defaults to `<hostname>-<rand6>` — pass `--instance-id <id>`
|
|
107
|
+
for a stable label across re-pairings on the same box. `--force`
|
|
108
|
+
overwrites an existing config.json.
|
|
109
|
+
|
|
110
|
+
3. **Start** — `awb-agent-manager`. The process registers with the AWB
|
|
111
|
+
instance dashboard and starts listening for `agent_manager_command` SSE
|
|
112
|
+
events.
|
|
113
|
+
|
|
114
|
+
4. **Add managed agents** — Back in AWB, _Agent Manager → Managed Agents →
|
|
115
|
+
Create_. Pick the CLI (`claude` / `codex` / `antigravity` / `custom`), point at
|
|
116
|
+
a working directory, and leave _Spawn on this manager after create_ on for
|
|
117
|
+
one-click setup. The manager provisions a per-agent apiKey, writes its
|
|
118
|
+
on-disk config + mcp-config.json, and starts routing matching ticket /
|
|
119
|
+
chat / mention events to subagents that run under that agent's identity.
|
|
120
|
+
|
|
121
|
+
On manager restart, agents previously spawned this way auto-rehydrate
|
|
122
|
+
from disk — no need to re-click Spawn.
|
|
123
|
+
|
|
124
|
+
## Run as a background service
|
|
125
|
+
|
|
126
|
+
`awb-agent-manager service install` registers the manager so it starts on
|
|
127
|
+
boot/logon and auto-restarts on crash. The installer detects your host's
|
|
128
|
+
service manager and dispatches accordingly:
|
|
129
|
+
|
|
130
|
+
| Host | Backend | Default unit path |
|
|
131
|
+
|------------------------------|------------------------|----------------------------------------------------|
|
|
132
|
+
| Linux + systemd | systemd unit | `~/.config/systemd/user/awb-agent-manager.service` |
|
|
133
|
+
| Linux + Synology DSM | rc.d boot script | `/usr/local/etc/rc.d/awb-agent-manager.sh` |
|
|
134
|
+
| Linux without systemd | sysvinit | `/etc/init.d/awb-agent-manager` |
|
|
135
|
+
| macOS | launchd | `~/Library/LaunchAgents/com.awb.agent-manager.plist` |
|
|
136
|
+
| Windows | Task Scheduler | task `awb-agent-manager` (logon trigger) |
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# user scope (no admin/sudo) — runs at logon, recommended for laptops
|
|
140
|
+
awb-agent-manager service install
|
|
141
|
+
|
|
142
|
+
# system scope — runs at boot, requires sudo / Administrator shell
|
|
143
|
+
awb-agent-manager service install --system
|
|
144
|
+
|
|
145
|
+
# preview without writing or running registrar
|
|
146
|
+
awb-agent-manager service install --dry-run
|
|
147
|
+
|
|
148
|
+
# force a specific backend (e.g. testing sysvinit on a systemd host)
|
|
149
|
+
awb-agent-manager service install --platform sysvinit
|
|
150
|
+
|
|
151
|
+
# remove
|
|
152
|
+
awb-agent-manager service uninstall [--system]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Notes:
|
|
156
|
+
- Linux user-mode systemd services stop at logout. Run
|
|
157
|
+
`sudo loginctl enable-linger $USER` to keep the manager running after the
|
|
158
|
+
installing user logs out.
|
|
159
|
+
- Synology DSM and bare sysvinit always install at system scope (the boot
|
|
160
|
+
directories are root-owned). The `--system` flag is implied.
|
|
161
|
+
- Windows user-mode tasks fire at logon only. Re-run with `--system` from
|
|
162
|
+
an elevated PowerShell for a boot-time task running as `LocalSystem`.
|
|
163
|
+
- macOS uses `launchctl bootstrap` on modern macOS and falls back to
|
|
164
|
+
`launchctl load -w` on older releases. Logs land in `/tmp/awb-agent-manager.log`.
|
|
165
|
+
|
|
166
|
+
## Migration from the claude-plugin daemon (≤ v0.39)
|
|
167
|
+
|
|
168
|
+
The plugin daemon is gone as of plugin v0.40.0. Everything it owned moved
|
|
169
|
+
here. Migration is opt-in but easy:
|
|
170
|
+
|
|
171
|
+
- agent-manager auto-imports `~/.claude/channels/awb/{config,agent}.json` on
|
|
172
|
+
first run if `~/.config/awb-agent-manager/config.json` is missing. A
|
|
173
|
+
`MIGRATED-TO-AGENT-MANAGER.txt` marker is dropped next to the legacy files;
|
|
174
|
+
subsequent starts skip the import. Legacy files are never deleted — the
|
|
175
|
+
plugin's stdio MCP proxy still reads them.
|
|
176
|
+
- The first run will refuse to start while the legacy daemon's
|
|
177
|
+
`~/.claude/channels/awb/agent.lock` is owned by a live PID. Stop the old
|
|
178
|
+
Claude session (or `kill` the daemon) first, then start
|
|
179
|
+
`awb-agent-manager`. Pass `--force` to take over a stale lock owned by a
|
|
180
|
+
dead PID.
|
|
181
|
+
|
|
182
|
+
## Configuration
|
|
183
|
+
|
|
184
|
+
| Source | Precedence |
|
|
185
|
+
|--------------------------------------------------|------------------|
|
|
186
|
+
| `--config <path>` flag | 1 (highest) |
|
|
187
|
+
| `$AWB_AGENT_MANAGER_HOME/config.json` | 2 |
|
|
188
|
+
| `$XDG_CONFIG_HOME/awb-agent-manager/config.json` | 3 (Linux) |
|
|
189
|
+
| `%APPDATA%\awb-agent-manager\config.json` | 3 (Windows) |
|
|
190
|
+
| `~/.config/awb-agent-manager/config.json` | 4 (fallback) |
|
|
191
|
+
|
|
192
|
+
Schema (`config.json`):
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"url": "https://awb.example.com",
|
|
197
|
+
"apiKey": "<bearer key from pairing>",
|
|
198
|
+
"workspace_id": "<workspace uuid>",
|
|
199
|
+
"agent_id": "<manager agent uuid>",
|
|
200
|
+
"cli": "claude",
|
|
201
|
+
"delegation": {
|
|
202
|
+
"enabled": true,
|
|
203
|
+
"max_concurrent_subagents": 4
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
CLI flags (`awb-agent-manager --help`):
|
|
209
|
+
|
|
210
|
+
| Flag | Meaning |
|
|
211
|
+
|-------------------------|---------------------------------------------------------|
|
|
212
|
+
| `-c, --config <path>` | Override config.json path |
|
|
213
|
+
| `-w, --workspace <id>` | Override `workspace_id` from config |
|
|
214
|
+
| `-f, --force` | Take over a lockfile owned by a stale or live owner |
|
|
215
|
+
| `--dry-run` | Load config, log what would happen, exit |
|
|
216
|
+
| `-h, --help` | Show full usage |
|
|
217
|
+
| `-v, --version` | Print version |
|
|
218
|
+
|
|
219
|
+
Signals:
|
|
220
|
+
|
|
221
|
+
| Signal | Behavior |
|
|
222
|
+
|--------------|-----------------------------------------------------------|
|
|
223
|
+
| `SIGTERM`/`SIGINT` | Graceful drain (stop subagents, release lock) |
|
|
224
|
+
| `SIGHUP` | Re-read `config.json` (delegation tunables hot-reload) |
|
|
225
|
+
| `SIGUSR1` | Self-update hook (currently a stub — upgrade via npm) |
|
|
226
|
+
|
|
227
|
+
## Development
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# from this directory
|
|
231
|
+
npm install # workspace install at the repo root also works
|
|
232
|
+
npm run build # tsc → dist/
|
|
233
|
+
npm run dev # tsx watch src/main.ts
|
|
234
|
+
node dist/main.js -h
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The full AWB workspace builds via turbo from the repo root:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
cd ../.. # submodules/ai-workflow-board
|
|
241
|
+
npm install
|
|
242
|
+
npm run build # builds agent-manager + client + server
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
For deep reference (config schema, SSE event types, security model, internals)
|
|
246
|
+
see [`docs/agent-manager.md`](../../docs/agent-manager.md).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const LOCK_PATH: string;
|
|
2
|
+
export type LockRole = 'manager';
|
|
3
|
+
export interface LockPayload {
|
|
4
|
+
pid: number;
|
|
5
|
+
role: LockRole;
|
|
6
|
+
version: string;
|
|
7
|
+
started_at: string;
|
|
8
|
+
}
|
|
9
|
+
export interface LockHandle {
|
|
10
|
+
release(): void;
|
|
11
|
+
path: string;
|
|
12
|
+
payload: LockPayload;
|
|
13
|
+
}
|
|
14
|
+
interface ParsedLock {
|
|
15
|
+
pid: number;
|
|
16
|
+
role?: string;
|
|
17
|
+
started_at?: string;
|
|
18
|
+
version?: string;
|
|
19
|
+
}
|
|
20
|
+
interface AcquireOptions {
|
|
21
|
+
role: LockRole;
|
|
22
|
+
version: string;
|
|
23
|
+
force?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function acquireAgentLock(opts: AcquireOptions): LockHandle;
|
|
26
|
+
export declare function inspectAgentLock(): ParsedLock | null;
|
|
27
|
+
export interface LegacyLockState {
|
|
28
|
+
present: boolean;
|
|
29
|
+
alive: boolean;
|
|
30
|
+
pid: number | null;
|
|
31
|
+
role?: string;
|
|
32
|
+
version?: string;
|
|
33
|
+
started_at?: string;
|
|
34
|
+
path: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function inspectLegacyAgentLock(): LegacyLockState;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { writeFileSync, readFileSync, unlinkSync, mkdirSync, existsSync, } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
4
|
+
import { AGENT_MANAGER_HOME, LEGACY_LOCK_PATH } from './constants.js';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { log } from './logging.js';
|
|
7
|
+
export const LOCK_PATH = join(AGENT_MANAGER_HOME, 'agent.lock');
|
|
8
|
+
const FORCE_KILL_GRACE_MS = 1500;
|
|
9
|
+
function readLock() {
|
|
10
|
+
try {
|
|
11
|
+
const raw = readFileSync(LOCK_PATH, 'utf8');
|
|
12
|
+
const parsed = JSON.parse(raw);
|
|
13
|
+
const pid = Number.isFinite(parsed?.pid) ? parsed.pid : 0;
|
|
14
|
+
return pid > 0
|
|
15
|
+
? {
|
|
16
|
+
pid,
|
|
17
|
+
role: parsed.role,
|
|
18
|
+
started_at: parsed.started_at,
|
|
19
|
+
version: parsed.version,
|
|
20
|
+
}
|
|
21
|
+
: null;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function isPidAlive(pid) {
|
|
28
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
29
|
+
return false;
|
|
30
|
+
try {
|
|
31
|
+
process.kill(pid, 0);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
return err?.code === 'EPERM';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function writeLockAtomic(payload) {
|
|
39
|
+
try {
|
|
40
|
+
mkdirSync(dirname(LOCK_PATH), { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
}
|
|
44
|
+
writeFileSync(LOCK_PATH, JSON.stringify(payload, null, 2) + '\n', { flag: 'wx' });
|
|
45
|
+
}
|
|
46
|
+
function writeLockOverwrite(payload) {
|
|
47
|
+
try {
|
|
48
|
+
mkdirSync(dirname(LOCK_PATH), { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
}
|
|
52
|
+
writeFileSync(LOCK_PATH, JSON.stringify(payload, null, 2) + '\n');
|
|
53
|
+
}
|
|
54
|
+
export function acquireAgentLock(opts) {
|
|
55
|
+
const role = opts?.role;
|
|
56
|
+
const version = opts?.version || 'unknown';
|
|
57
|
+
const force = opts?.force === true;
|
|
58
|
+
if (role !== 'manager') {
|
|
59
|
+
throw new Error(`acquireAgentLock: invalid role ${JSON.stringify(role)}`);
|
|
60
|
+
}
|
|
61
|
+
const payload = {
|
|
62
|
+
pid: process.pid,
|
|
63
|
+
role,
|
|
64
|
+
version,
|
|
65
|
+
started_at: new Date().toISOString(),
|
|
66
|
+
};
|
|
67
|
+
try {
|
|
68
|
+
writeLockAtomic(payload);
|
|
69
|
+
log(`[lockfile] acquired ${LOCK_PATH} (role=${role} pid=${process.pid})`);
|
|
70
|
+
return makeReleaseHandle(payload);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (err?.code !== 'EEXIST')
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
const existing = readLock();
|
|
77
|
+
if (!existing) {
|
|
78
|
+
log(`[lockfile] removing unparseable lockfile at ${LOCK_PATH}`);
|
|
79
|
+
try {
|
|
80
|
+
unlinkSync(LOCK_PATH);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
}
|
|
84
|
+
writeLockAtomic(payload);
|
|
85
|
+
log(`[lockfile] acquired after stale-cleanup (role=${role} pid=${process.pid})`);
|
|
86
|
+
return makeReleaseHandle(payload);
|
|
87
|
+
}
|
|
88
|
+
if (!isPidAlive(existing.pid)) {
|
|
89
|
+
log(`[lockfile] reusing stale lock (previous owner pid=${existing.pid} role=${existing.role || '?'} dead)`);
|
|
90
|
+
try {
|
|
91
|
+
unlinkSync(LOCK_PATH);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
}
|
|
95
|
+
writeLockAtomic(payload);
|
|
96
|
+
log(`[lockfile] acquired after stale-cleanup (role=${role} pid=${process.pid})`);
|
|
97
|
+
return makeReleaseHandle(payload);
|
|
98
|
+
}
|
|
99
|
+
if (!force) {
|
|
100
|
+
const e = new Error(`AWB agent-manager lockfile held by pid=${existing.pid} role=${existing.role || '?'} ` +
|
|
101
|
+
`version=${existing.version || '?'} since ${existing.started_at || '?'}. ` +
|
|
102
|
+
`Stop it first, or pass --force to take over.`);
|
|
103
|
+
e.code = 'EAGENTLOCKED';
|
|
104
|
+
throw e;
|
|
105
|
+
}
|
|
106
|
+
log(`[lockfile] --force: SIGTERM previous owner pid=${existing.pid} role=${existing.role || '?'}`);
|
|
107
|
+
try {
|
|
108
|
+
process.kill(existing.pid, 'SIGTERM');
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
}
|
|
112
|
+
return forceTakeover(payload, existing.pid);
|
|
113
|
+
}
|
|
114
|
+
async function forceTakeoverAsync(payload, prevPid) {
|
|
115
|
+
const start = Date.now();
|
|
116
|
+
while (Date.now() - start < FORCE_KILL_GRACE_MS) {
|
|
117
|
+
if (!isPidAlive(prevPid))
|
|
118
|
+
break;
|
|
119
|
+
await delay(100);
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
writeLockAtomic(payload);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
if (err?.code !== 'EEXIST')
|
|
126
|
+
throw err;
|
|
127
|
+
writeLockOverwrite(payload);
|
|
128
|
+
}
|
|
129
|
+
log(`[lockfile] --force: acquired by overwrite (role=${payload.role} pid=${process.pid})`);
|
|
130
|
+
}
|
|
131
|
+
function forceTakeover(payload, prevPid) {
|
|
132
|
+
try {
|
|
133
|
+
writeLockOverwrite(payload);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
log(`[lockfile] --force overwrite failed: ${err?.message ?? err}`);
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
forceTakeoverAsync(payload, prevPid).catch((err) => log(`[lockfile] takeover poll: ${err?.message ?? err}`));
|
|
140
|
+
return makeReleaseHandle(payload);
|
|
141
|
+
}
|
|
142
|
+
function makeReleaseHandle(payload) {
|
|
143
|
+
let released = false;
|
|
144
|
+
process.on('exit', () => {
|
|
145
|
+
if (released)
|
|
146
|
+
return;
|
|
147
|
+
safeUnlinkOwn(payload.pid);
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
release() {
|
|
151
|
+
if (released)
|
|
152
|
+
return;
|
|
153
|
+
released = true;
|
|
154
|
+
safeUnlinkOwn(payload.pid);
|
|
155
|
+
},
|
|
156
|
+
path: LOCK_PATH,
|
|
157
|
+
payload,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function safeUnlinkOwn(myPid) {
|
|
161
|
+
try {
|
|
162
|
+
const raw = readFileSync(LOCK_PATH, 'utf8');
|
|
163
|
+
const parsed = JSON.parse(raw);
|
|
164
|
+
if (parsed?.pid !== myPid)
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
unlinkSync(LOCK_PATH);
|
|
172
|
+
log(`[lockfile] released ${LOCK_PATH}`);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export function inspectAgentLock() {
|
|
178
|
+
return readLock();
|
|
179
|
+
}
|
|
180
|
+
export function inspectLegacyAgentLock() {
|
|
181
|
+
if (!existsSync(LEGACY_LOCK_PATH)) {
|
|
182
|
+
return { present: false, alive: false, pid: null, path: LEGACY_LOCK_PATH };
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
const raw = readFileSync(LEGACY_LOCK_PATH, 'utf8');
|
|
186
|
+
const parsed = JSON.parse(raw);
|
|
187
|
+
const pid = Number.isFinite(parsed?.pid) ? parsed.pid : 0;
|
|
188
|
+
if (pid <= 0) {
|
|
189
|
+
return { present: true, alive: false, pid: null, path: LEGACY_LOCK_PATH };
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
present: true,
|
|
193
|
+
alive: isPidAlive(pid),
|
|
194
|
+
pid,
|
|
195
|
+
role: parsed.role,
|
|
196
|
+
version: parsed.version,
|
|
197
|
+
started_at: parsed.started_at,
|
|
198
|
+
path: LEGACY_LOCK_PATH,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return { present: true, alive: false, pid: null, path: LEGACY_LOCK_PATH };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=agent-lockfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-lockfile.js","sourceRoot":"","sources":["../../src/lib/agent-lockfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type AwbConfig } from './rest.js';
|
|
2
|
+
import type { ManagedAgentRegistry } from './managed-agents.js';
|
|
3
|
+
import type { ManagedAgentContextRegistry } from './managed-agent-context.js';
|
|
4
|
+
import type { BaseSessionManager } from './base-session-manager.js';
|
|
5
|
+
import type { SubagentManager } from './subagent-manager.js';
|
|
6
|
+
import type { CircuitBreaker } from './circuit-breaker.js';
|
|
7
|
+
type CommandKind = 'spawn_agent' | 'stop_agent' | 'restart_agent' | 'restart_all_agents' | 'set_working_dir' | 'reload_config' | 'update_plugins' | 'refresh_mcp_config' | 'pull_working_dir' | 'update_manager' | 'restart_manager';
|
|
8
|
+
export interface AgentManagerCommandPayload {
|
|
9
|
+
command_id: string;
|
|
10
|
+
instance_id: string;
|
|
11
|
+
agent_id?: string;
|
|
12
|
+
command: CommandKind | string;
|
|
13
|
+
args?: Record<string, any>;
|
|
14
|
+
issued_by?: string;
|
|
15
|
+
issued_at?: string;
|
|
16
|
+
timestamp?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface CommandHandlerDeps {
|
|
19
|
+
getInstanceId(): string | null;
|
|
20
|
+
registry: ManagedAgentRegistry;
|
|
21
|
+
contextRegistry?: ManagedAgentContextRegistry | null;
|
|
22
|
+
chatSessionManager?: Pick<BaseSessionManager, 'stopForAgent'> | null;
|
|
23
|
+
ticketSessionManager?: Pick<BaseSessionManager, 'stopForAgent'> | null;
|
|
24
|
+
subagentManager?: Pick<SubagentManager, 'stopForAgent'> | null;
|
|
25
|
+
circuitBreaker?: CircuitBreaker | null;
|
|
26
|
+
reloadConfig?: () => Promise<string> | string;
|
|
27
|
+
requestStreamReconnect?: () => Promise<void> | void;
|
|
28
|
+
}
|
|
29
|
+
export declare class AgentManagerCommandHandler {
|
|
30
|
+
#private;
|
|
31
|
+
constructor(config: AwbConfig, deps: CommandHandlerDeps);
|
|
32
|
+
handle(raw: string): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export {};
|