wooster 0.1.0__tar.gz
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.
- wooster-0.1.0/.claude/settings.local.json +40 -0
- wooster-0.1.0/.gitignore +13 -0
- wooster-0.1.0/CHANGELOG.md +22 -0
- wooster-0.1.0/CONTRIBUTING.md +87 -0
- wooster-0.1.0/LICENSE +21 -0
- wooster-0.1.0/PKG-INFO +237 -0
- wooster-0.1.0/README.md +209 -0
- wooster-0.1.0/assets/ss1.png +0 -0
- wooster-0.1.0/assets/ss2.png +0 -0
- wooster-0.1.0/assets/wooster.png +0 -0
- wooster-0.1.0/pyproject.toml +41 -0
- wooster-0.1.0/wooster/__init__.py +1 -0
- wooster-0.1.0/wooster/cli.py +99 -0
- wooster-0.1.0/wooster/commands.py +254 -0
- wooster-0.1.0/wooster/db.py +75 -0
- wooster-0.1.0/wooster/discovery.py +311 -0
- wooster-0.1.0/wooster/display.py +131 -0
- wooster-0.1.0/wooster/tui.py +373 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(python3 -c \"import rich; print\\(rich.__version__\\)\")",
|
|
5
|
+
"Bash(python3 -c \"import sqlite3; print\\(''sqlite3 ok''\\)\")",
|
|
6
|
+
"Bash(chmod:*)",
|
|
7
|
+
"Bash(./agents add:*)",
|
|
8
|
+
"Bash(./agents list:*)",
|
|
9
|
+
"Bash(./agents todo:*)",
|
|
10
|
+
"Bash(./agents done:*)",
|
|
11
|
+
"Bash(./agents show:*)",
|
|
12
|
+
"Bash(./agents clear:*)",
|
|
13
|
+
"Bash(rm -f ~/.agents/agents.db)",
|
|
14
|
+
"Bash(python3 agents:*)",
|
|
15
|
+
"Bash(./agents)",
|
|
16
|
+
"Bash(./agents -v)",
|
|
17
|
+
"Bash(./agents --help)",
|
|
18
|
+
"Bash(ps -eo pid,state,wchan,command)",
|
|
19
|
+
"Bash(ps -eo pid,wmesg,command)",
|
|
20
|
+
"Bash(ps -eo pid,tty,state,command)",
|
|
21
|
+
"Bash(ps -eo pid,ppid,state,command)",
|
|
22
|
+
"Bash(ps -eo pid,ppid,state,%cpu,command)",
|
|
23
|
+
"Bash(for pid:*)",
|
|
24
|
+
"Bash(do echo:*)",
|
|
25
|
+
"Bash(done)",
|
|
26
|
+
"Bash(pip install:*)",
|
|
27
|
+
"Bash(python:*)",
|
|
28
|
+
"Bash(python3 -m nestor.cli clear)",
|
|
29
|
+
"Bash(nestor scan:*)",
|
|
30
|
+
"Bash(nestor bar:*)",
|
|
31
|
+
"Bash(nestor:*)",
|
|
32
|
+
"Bash(ps -eo pid,tty,command)",
|
|
33
|
+
"Bash(python3 -m nestor.cli)",
|
|
34
|
+
"Bash(echo \"EXIT: $?\")",
|
|
35
|
+
"Bash(python3:*)",
|
|
36
|
+
"Bash(ls /Users/oha/nestor/*.tmp)",
|
|
37
|
+
"Bash(git -C /Users/oha/nestor status)"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
wooster-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-03-21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Initial release
|
|
10
|
+
- CLI entry point with argparse subcommands
|
|
11
|
+
- SQLite database storage at `~/.wooster/wooster.db` with WAL mode
|
|
12
|
+
- **Auto-discovery**: scans `ps` for running Claude Code, Codex, Gemini, Aider, Copilot, Cursor, and GPT CLI processes
|
|
13
|
+
- **Child process deduplication**: filters out subprocess forks, only tracks leader processes
|
|
14
|
+
- **Duplicate numbering**: multiple sessions in the same directory get `#1`, `#2`, etc.
|
|
15
|
+
- **Idle heuristic**: flags likely-idle agents with sleeping state + low CPU + no network activity as `🔔 idle?`
|
|
16
|
+
- **CWD resolution**: uses `lsof` to find the working directory of each agent process
|
|
17
|
+
- **Watch mode**: `wooster watch [-n SECONDS]` for continuous terminal refresh
|
|
18
|
+
- **Manual agent management**: `add`, `update`, `done`, `rm`, `clear`
|
|
19
|
+
- **Todo system**: attach and complete todos per agent
|
|
20
|
+
- **Sorted output**: waiting agents at top, done agents at bottom
|
|
21
|
+
- **Stats bar**: summary counts with timestamp
|
|
22
|
+
- **Emoji icons**: per-type and per-status visual indicators
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Contributing to Wooster
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing to Wooster!
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Clone the repo
|
|
9
|
+
git clone https://github.com/oha/wooster.git
|
|
10
|
+
cd wooster
|
|
11
|
+
|
|
12
|
+
# Install uv if you don't have it
|
|
13
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
14
|
+
|
|
15
|
+
# Create a virtual environment and install in dev mode
|
|
16
|
+
uv sync
|
|
17
|
+
|
|
18
|
+
# Run wooster
|
|
19
|
+
uv run wooster
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Project structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
wooster/
|
|
26
|
+
├── bin/wooster # Standalone executable (no install needed)
|
|
27
|
+
├── wooster/
|
|
28
|
+
│ ├── __init__.py # Version string
|
|
29
|
+
│ ├── cli.py # Argparse setup + command routing
|
|
30
|
+
│ ├── db.py # SQLite schema, connection, migrations
|
|
31
|
+
│ ├── discovery.py # Process scanning, waiting detection, DB sync
|
|
32
|
+
│ ├── display.py # Table formatting, icons, stats bar
|
|
33
|
+
│ └── commands.py # All subcommand handlers
|
|
34
|
+
├── pyproject.toml # Project config (uv/hatch)
|
|
35
|
+
├── README.md
|
|
36
|
+
├── CHANGELOG.md
|
|
37
|
+
├── CONTRIBUTING.md
|
|
38
|
+
└── LICENSE
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## How it works
|
|
42
|
+
|
|
43
|
+
1. **`db.py`** — SQLite database at `~/.wooster/wooster.db`. Two tables: `agents` and `todos`. Uses WAL mode for concurrent access.
|
|
44
|
+
|
|
45
|
+
2. **`discovery.py`** — Scans `ps` output for known AI CLI patterns. Filters child processes, resolves CWDs via `lsof`, detects idle agents (sleeping + <0.5% CPU = waiting for input).
|
|
46
|
+
|
|
47
|
+
3. **`display.py`** — Formats the agent table with emoji icons, stats bar, and sorted output (waiting first, done last).
|
|
48
|
+
|
|
49
|
+
4. **`commands.py`** — All subcommand handlers. Each one opens a DB connection, does its thing, and closes.
|
|
50
|
+
|
|
51
|
+
5. **`cli.py`** — Argparse setup and routing. This is the entry point for both `bin/wooster` and `pip install`.
|
|
52
|
+
|
|
53
|
+
## Adding a new agent type
|
|
54
|
+
|
|
55
|
+
1. Add a regex pattern to `AGENT_PATTERNS` in `wooster/discovery.py`
|
|
56
|
+
2. Add an icon to `TYPE_ICON` in `wooster/display.py`
|
|
57
|
+
3. Add the type string to the `--type` choices in `wooster/cli.py`
|
|
58
|
+
|
|
59
|
+
## Adding a new command
|
|
60
|
+
|
|
61
|
+
1. Write the handler in `wooster/commands.py`
|
|
62
|
+
2. Add the argparse subparser in `wooster/cli.py`
|
|
63
|
+
3. Add it to the `cmd_map` dict in `wooster/cli.py`
|
|
64
|
+
|
|
65
|
+
## Code style
|
|
66
|
+
|
|
67
|
+
- Pure Python 3 stdlib only — no external dependencies
|
|
68
|
+
- Keep it simple, no over-engineering
|
|
69
|
+
- Functions over classes where possible
|
|
70
|
+
- Emoji icons are fine for terminal output
|
|
71
|
+
|
|
72
|
+
## Submitting changes
|
|
73
|
+
|
|
74
|
+
1. Fork the repo
|
|
75
|
+
2. Create a branch (`git checkout -b my-feature`)
|
|
76
|
+
3. Make your changes
|
|
77
|
+
4. Test with `uv run wooster` and verify the output looks right
|
|
78
|
+
5. Commit and push
|
|
79
|
+
6. Open a PR
|
|
80
|
+
|
|
81
|
+
## Reporting bugs
|
|
82
|
+
|
|
83
|
+
Open an issue at https://github.com/oha/wooster/issues with:
|
|
84
|
+
- What you ran
|
|
85
|
+
- What you expected
|
|
86
|
+
- What happened instead
|
|
87
|
+
- Your OS and Python version (`python3 --version`)
|
wooster-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 oha
|
|
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.
|
wooster-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wooster
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI to track AI coding agents (Claude Code, Codex, Gemini, etc.) in real time
|
|
5
|
+
Project-URL: Homepage, https://github.com/oha/wooster
|
|
6
|
+
Project-URL: Repository, https://github.com/oha/wooster
|
|
7
|
+
Project-URL: Issues, https://github.com/oha/wooster/issues
|
|
8
|
+
Author: oha
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,ai,claude,cli,codex,gemini,monitoring
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
25
|
+
Classifier: Topic :: System :: Monitoring
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# wooster
|
|
30
|
+
|
|
31
|
+
A process monitor for AI coding agents. Built for **Claude Code** and **Codex**, it also works with other CLI agents (custom).
|
|
32
|
+
|
|
33
|
+
When you're running multiple agents across terminal sessions, it gets impossible to remember which CLI is doing what, which ones finished, and which ones need your input. Wooster auto-discovers them and gives you a single dashboard.
|
|
34
|
+
|
|
35
|
+
> **Note:** Idle detection is tuned and tested for Claude Code and Codex. Other agents are auto-detected but the idle/running heuristic may be less accurate. You can also add custom agents via config.
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Auto-discovery** — scans running processes for known AI CLIs, no manual setup
|
|
40
|
+
- **Smart idle detection** — detects idle agents using child process activity, not just CPU (tuned for Claude Code and Codex)
|
|
41
|
+
- **Interactive TUI** — `wooster top` gives you an htop-style monitor with live CPU, memory, process trees, and keybindings to kill/manage agents
|
|
42
|
+
- **Desktop notifications** — get notified when an agent goes idle or finishes (macOS)
|
|
43
|
+
- **Compact bar mode** — `wooster bar` for tmux status bars or small terminal panes
|
|
44
|
+
- **Custom agents** — add your own CLI patterns via `~/.wooster/config.json`
|
|
45
|
+
- **Zero dependencies** — pure Python 3, uses only stdlib
|
|
46
|
+
|
|
47
|
+
## Supported agents
|
|
48
|
+
|
|
49
|
+
Tested and tuned:
|
|
50
|
+
|
|
51
|
+
| Type | CLI | Idle detection |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `claude` | `claude` (Claude Code) | accurate |
|
|
54
|
+
| `codex` | `codex` (OpenAI Codex CLI) | accurate |
|
|
55
|
+
|
|
56
|
+
Also auto-detected (idle detection may vary):
|
|
57
|
+
|
|
58
|
+
| Type | CLI |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `gemini` | `gemini` (Google Gemini CLI) |
|
|
61
|
+
| `aider` | `aider` |
|
|
62
|
+
| `copilot` | `github-copilot`, `copilot-cli` |
|
|
63
|
+
| `cursor` | `cursor` |
|
|
64
|
+
| `gpt` | `sgpt`, `chatgpt` |
|
|
65
|
+
|
|
66
|
+
## Quick start
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Install
|
|
70
|
+
pip install -e .
|
|
71
|
+
|
|
72
|
+
# Just run it. Auto-discovers everything
|
|
73
|
+
wooster
|
|
74
|
+
|
|
75
|
+
# htop-style
|
|
76
|
+
wooster top
|
|
77
|
+
|
|
78
|
+
# Continuous monitoring (refreshes every 2s)
|
|
79
|
+
wooster watch
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Usage
|
|
83
|
+
|
|
84
|
+
### Monitoring
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Auto-scan + list all agents (default)
|
|
88
|
+
wooster
|
|
89
|
+
|
|
90
|
+
# Interactive TUI
|
|
91
|
+
wooster top # htop for agents
|
|
92
|
+
wooster top -n 5 # refresh every 5s
|
|
93
|
+
|
|
94
|
+
# Continuous watch mode
|
|
95
|
+
wooster watch # refresh every 2s
|
|
96
|
+
wooster watch -n 5 # refresh every 5s
|
|
97
|
+
|
|
98
|
+
# Single-line compact status
|
|
99
|
+
wooster bar # one-shot
|
|
100
|
+
wooster bar --watch # continuous single-line updates
|
|
101
|
+
|
|
102
|
+
# Raw process scan (verbose debug output)
|
|
103
|
+
wooster scan
|
|
104
|
+
|
|
105
|
+
# Show full detail for an agent
|
|
106
|
+
wooster show 3
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Managing agents
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Manually register an agent
|
|
113
|
+
wooster add "auth-refactor" -t claude -s "Refactoring auth middleware"
|
|
114
|
+
wooster add "auth-refactor" -t claude --status running
|
|
115
|
+
|
|
116
|
+
# Update an agent
|
|
117
|
+
wooster update 3 --summary "Now working on tests"
|
|
118
|
+
wooster update 3 -s done
|
|
119
|
+
wooster update 3 --name "auth-refactor-v2"
|
|
120
|
+
|
|
121
|
+
# Mark as done
|
|
122
|
+
wooster done 3
|
|
123
|
+
|
|
124
|
+
# Kill a stuck agent (sends SIGTERM)
|
|
125
|
+
wooster kill 3
|
|
126
|
+
|
|
127
|
+
# Remove an agent from the list
|
|
128
|
+
wooster rm 3
|
|
129
|
+
|
|
130
|
+
# Clear all agents
|
|
131
|
+
wooster clear
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Todos
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Add a todo to an agent
|
|
138
|
+
wooster todo 3 "Review PR after this finishes"
|
|
139
|
+
|
|
140
|
+
# Mark a todo as done
|
|
141
|
+
wooster todo-done 3 1
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### tmux integration
|
|
145
|
+
|
|
146
|
+
Add to your `.tmux.conf` for a status bar showing agent counts:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
set -g status-right '#(wooster bar)'
|
|
150
|
+
set -g status-interval 5
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Interactive TUI (`wooster top`)
|
|
154
|
+
|
|
155
|
+

|
|
156
|
+
|
|
157
|
+
An htop-style split-screen monitor:
|
|
158
|
+
|
|
159
|
+
- **Top half** — agent list with live CPU%, memory, TTY, uptime
|
|
160
|
+
- **Bottom half** — process tree for the selected agent showing every subprocess
|
|
161
|
+
|
|
162
|
+
Keybindings:
|
|
163
|
+
|
|
164
|
+
| Key | Action |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `j` / `↓` | Select next agent |
|
|
167
|
+
| `↑` | Select previous agent |
|
|
168
|
+
| `k` | Kill selected agent (SIGTERM) |
|
|
169
|
+
| `d` | Mark selected as done |
|
|
170
|
+
| `r` | Remove from list |
|
|
171
|
+
| `h` | Toggle showing done agents |
|
|
172
|
+
| `q` / `ESC` | Quit |
|
|
173
|
+
|
|
174
|
+
## Custom agents
|
|
175
|
+
|
|
176
|
+
Add your own CLI patterns in `~/.wooster/config.json`:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"agents": [
|
|
181
|
+
{"pattern": "my-internal-agent", "type": "custom"},
|
|
182
|
+
{"pattern": "acme-coder", "type": "acme"}
|
|
183
|
+
],
|
|
184
|
+
"idle_threshold_cpu": 2.0,
|
|
185
|
+
"idle_scans": 3
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- `pattern` — regex matched against the process command line
|
|
190
|
+
- `type` — label shown in the type column
|
|
191
|
+
- `idle_threshold_cpu` — CPU% below which an agent is considered potentially idle (default: 2.0)
|
|
192
|
+
- `idle_scans` — number of consecutive idle scans before flagging as idle (default: 3)
|
|
193
|
+
|
|
194
|
+
## How it works
|
|
195
|
+
|
|
196
|
+
### Process discovery
|
|
197
|
+
|
|
198
|
+
Runs `ps -eo pid,ppid,tty,state,%cpu,lstart,command` and matches against known AI CLI patterns. Child processes (e.g., codex spawning subprocesses) are filtered out so you only see the session leader. CWDs are resolved via a single batched `lsof` call.
|
|
199
|
+
|
|
200
|
+
### Idle detection
|
|
201
|
+
|
|
202
|
+
An auto-discovered agent is flagged as `idle?` when all of these are true:
|
|
203
|
+
|
|
204
|
+
1. Process state is **sleeping** (`S` state)
|
|
205
|
+
2. CPU usage is **< 2%**
|
|
206
|
+
3. **No active child processes** (non-zombie children doing work)
|
|
207
|
+
4. The above conditions persist for **3 consecutive scans** (~6 seconds)
|
|
208
|
+
|
|
209
|
+
This approach uses child process activity as the primary signal rather than network connections, which proved unreliable due to persistent WebSocket/HTTP2 keep-alive connections.
|
|
210
|
+
|
|
211
|
+
### PID reuse protection
|
|
212
|
+
|
|
213
|
+
Agents are tracked by `(PID, process start time)` rather than PID alone, so a recycled PID from a different process won't be confused with the original agent.
|
|
214
|
+
|
|
215
|
+
### Desktop notifications
|
|
216
|
+
|
|
217
|
+
macOS notifications fire once when an agent transitions to idle or exits. Notifications are deduplicated — you won't get repeat alerts from brief CPU fluctuations.
|
|
218
|
+
|
|
219
|
+
### Data storage
|
|
220
|
+
|
|
221
|
+
Agent state is stored in `~/.wooster/wooster.db` by default (SQLite with WAL mode for safe concurrent access). Override the path with `WOOSTER_DB_PATH`. Old completed agents are auto-pruned after 7 days, capped at 500 entries.
|
|
222
|
+
|
|
223
|
+
## Output (`wooster` / `wooster watch`)
|
|
224
|
+
|
|
225
|
+

|
|
226
|
+
|
|
227
|
+
Idle agents sort to the top.
|
|
228
|
+
|
|
229
|
+
## Requirements
|
|
230
|
+
|
|
231
|
+
- Python 3.9+
|
|
232
|
+
- macOS (uses `ps` and `lsof` for process inspection)
|
|
233
|
+
- Terminal with Unicode support
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT
|
wooster-0.1.0/README.md
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# wooster
|
|
2
|
+
|
|
3
|
+
A process monitor for AI coding agents. Built for **Claude Code** and **Codex**, it also works with other CLI agents (custom).
|
|
4
|
+
|
|
5
|
+
When you're running multiple agents across terminal sessions, it gets impossible to remember which CLI is doing what, which ones finished, and which ones need your input. Wooster auto-discovers them and gives you a single dashboard.
|
|
6
|
+
|
|
7
|
+
> **Note:** Idle detection is tuned and tested for Claude Code and Codex. Other agents are auto-detected but the idle/running heuristic may be less accurate. You can also add custom agents via config.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Auto-discovery** — scans running processes for known AI CLIs, no manual setup
|
|
12
|
+
- **Smart idle detection** — detects idle agents using child process activity, not just CPU (tuned for Claude Code and Codex)
|
|
13
|
+
- **Interactive TUI** — `wooster top` gives you an htop-style monitor with live CPU, memory, process trees, and keybindings to kill/manage agents
|
|
14
|
+
- **Desktop notifications** — get notified when an agent goes idle or finishes (macOS)
|
|
15
|
+
- **Compact bar mode** — `wooster bar` for tmux status bars or small terminal panes
|
|
16
|
+
- **Custom agents** — add your own CLI patterns via `~/.wooster/config.json`
|
|
17
|
+
- **Zero dependencies** — pure Python 3, uses only stdlib
|
|
18
|
+
|
|
19
|
+
## Supported agents
|
|
20
|
+
|
|
21
|
+
Tested and tuned:
|
|
22
|
+
|
|
23
|
+
| Type | CLI | Idle detection |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `claude` | `claude` (Claude Code) | accurate |
|
|
26
|
+
| `codex` | `codex` (OpenAI Codex CLI) | accurate |
|
|
27
|
+
|
|
28
|
+
Also auto-detected (idle detection may vary):
|
|
29
|
+
|
|
30
|
+
| Type | CLI |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `gemini` | `gemini` (Google Gemini CLI) |
|
|
33
|
+
| `aider` | `aider` |
|
|
34
|
+
| `copilot` | `github-copilot`, `copilot-cli` |
|
|
35
|
+
| `cursor` | `cursor` |
|
|
36
|
+
| `gpt` | `sgpt`, `chatgpt` |
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Install
|
|
42
|
+
pip install -e .
|
|
43
|
+
|
|
44
|
+
# Just run it. Auto-discovers everything
|
|
45
|
+
wooster
|
|
46
|
+
|
|
47
|
+
# htop-style
|
|
48
|
+
wooster top
|
|
49
|
+
|
|
50
|
+
# Continuous monitoring (refreshes every 2s)
|
|
51
|
+
wooster watch
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
### Monitoring
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Auto-scan + list all agents (default)
|
|
60
|
+
wooster
|
|
61
|
+
|
|
62
|
+
# Interactive TUI
|
|
63
|
+
wooster top # htop for agents
|
|
64
|
+
wooster top -n 5 # refresh every 5s
|
|
65
|
+
|
|
66
|
+
# Continuous watch mode
|
|
67
|
+
wooster watch # refresh every 2s
|
|
68
|
+
wooster watch -n 5 # refresh every 5s
|
|
69
|
+
|
|
70
|
+
# Single-line compact status
|
|
71
|
+
wooster bar # one-shot
|
|
72
|
+
wooster bar --watch # continuous single-line updates
|
|
73
|
+
|
|
74
|
+
# Raw process scan (verbose debug output)
|
|
75
|
+
wooster scan
|
|
76
|
+
|
|
77
|
+
# Show full detail for an agent
|
|
78
|
+
wooster show 3
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Managing agents
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Manually register an agent
|
|
85
|
+
wooster add "auth-refactor" -t claude -s "Refactoring auth middleware"
|
|
86
|
+
wooster add "auth-refactor" -t claude --status running
|
|
87
|
+
|
|
88
|
+
# Update an agent
|
|
89
|
+
wooster update 3 --summary "Now working on tests"
|
|
90
|
+
wooster update 3 -s done
|
|
91
|
+
wooster update 3 --name "auth-refactor-v2"
|
|
92
|
+
|
|
93
|
+
# Mark as done
|
|
94
|
+
wooster done 3
|
|
95
|
+
|
|
96
|
+
# Kill a stuck agent (sends SIGTERM)
|
|
97
|
+
wooster kill 3
|
|
98
|
+
|
|
99
|
+
# Remove an agent from the list
|
|
100
|
+
wooster rm 3
|
|
101
|
+
|
|
102
|
+
# Clear all agents
|
|
103
|
+
wooster clear
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Todos
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Add a todo to an agent
|
|
110
|
+
wooster todo 3 "Review PR after this finishes"
|
|
111
|
+
|
|
112
|
+
# Mark a todo as done
|
|
113
|
+
wooster todo-done 3 1
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### tmux integration
|
|
117
|
+
|
|
118
|
+
Add to your `.tmux.conf` for a status bar showing agent counts:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
set -g status-right '#(wooster bar)'
|
|
122
|
+
set -g status-interval 5
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Interactive TUI (`wooster top`)
|
|
126
|
+
|
|
127
|
+

|
|
128
|
+
|
|
129
|
+
An htop-style split-screen monitor:
|
|
130
|
+
|
|
131
|
+
- **Top half** — agent list with live CPU%, memory, TTY, uptime
|
|
132
|
+
- **Bottom half** — process tree for the selected agent showing every subprocess
|
|
133
|
+
|
|
134
|
+
Keybindings:
|
|
135
|
+
|
|
136
|
+
| Key | Action |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `j` / `↓` | Select next agent |
|
|
139
|
+
| `↑` | Select previous agent |
|
|
140
|
+
| `k` | Kill selected agent (SIGTERM) |
|
|
141
|
+
| `d` | Mark selected as done |
|
|
142
|
+
| `r` | Remove from list |
|
|
143
|
+
| `h` | Toggle showing done agents |
|
|
144
|
+
| `q` / `ESC` | Quit |
|
|
145
|
+
|
|
146
|
+
## Custom agents
|
|
147
|
+
|
|
148
|
+
Add your own CLI patterns in `~/.wooster/config.json`:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"agents": [
|
|
153
|
+
{"pattern": "my-internal-agent", "type": "custom"},
|
|
154
|
+
{"pattern": "acme-coder", "type": "acme"}
|
|
155
|
+
],
|
|
156
|
+
"idle_threshold_cpu": 2.0,
|
|
157
|
+
"idle_scans": 3
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
- `pattern` — regex matched against the process command line
|
|
162
|
+
- `type` — label shown in the type column
|
|
163
|
+
- `idle_threshold_cpu` — CPU% below which an agent is considered potentially idle (default: 2.0)
|
|
164
|
+
- `idle_scans` — number of consecutive idle scans before flagging as idle (default: 3)
|
|
165
|
+
|
|
166
|
+
## How it works
|
|
167
|
+
|
|
168
|
+
### Process discovery
|
|
169
|
+
|
|
170
|
+
Runs `ps -eo pid,ppid,tty,state,%cpu,lstart,command` and matches against known AI CLI patterns. Child processes (e.g., codex spawning subprocesses) are filtered out so you only see the session leader. CWDs are resolved via a single batched `lsof` call.
|
|
171
|
+
|
|
172
|
+
### Idle detection
|
|
173
|
+
|
|
174
|
+
An auto-discovered agent is flagged as `idle?` when all of these are true:
|
|
175
|
+
|
|
176
|
+
1. Process state is **sleeping** (`S` state)
|
|
177
|
+
2. CPU usage is **< 2%**
|
|
178
|
+
3. **No active child processes** (non-zombie children doing work)
|
|
179
|
+
4. The above conditions persist for **3 consecutive scans** (~6 seconds)
|
|
180
|
+
|
|
181
|
+
This approach uses child process activity as the primary signal rather than network connections, which proved unreliable due to persistent WebSocket/HTTP2 keep-alive connections.
|
|
182
|
+
|
|
183
|
+
### PID reuse protection
|
|
184
|
+
|
|
185
|
+
Agents are tracked by `(PID, process start time)` rather than PID alone, so a recycled PID from a different process won't be confused with the original agent.
|
|
186
|
+
|
|
187
|
+
### Desktop notifications
|
|
188
|
+
|
|
189
|
+
macOS notifications fire once when an agent transitions to idle or exits. Notifications are deduplicated — you won't get repeat alerts from brief CPU fluctuations.
|
|
190
|
+
|
|
191
|
+
### Data storage
|
|
192
|
+
|
|
193
|
+
Agent state is stored in `~/.wooster/wooster.db` by default (SQLite with WAL mode for safe concurrent access). Override the path with `WOOSTER_DB_PATH`. Old completed agents are auto-pruned after 7 days, capped at 500 entries.
|
|
194
|
+
|
|
195
|
+
## Output (`wooster` / `wooster watch`)
|
|
196
|
+
|
|
197
|
+

|
|
198
|
+
|
|
199
|
+
Idle agents sort to the top.
|
|
200
|
+
|
|
201
|
+
## Requirements
|
|
202
|
+
|
|
203
|
+
- Python 3.9+
|
|
204
|
+
- macOS (uses `ps` and `lsof` for process inspection)
|
|
205
|
+
- Terminal with Unicode support
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "wooster"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "CLI to track AI coding agents (Claude Code, Codex, Gemini, etc.) in real time"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { text = "MIT" }
|
|
7
|
+
requires-python = ">=3.8"
|
|
8
|
+
authors = [{ name = "oha" }]
|
|
9
|
+
keywords = ["ai", "agents", "cli", "monitoring", "claude", "codex", "gemini"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Environment :: Console",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Operating System :: MacOS",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.8",
|
|
18
|
+
"Programming Language :: Python :: 3.9",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Topic :: Software Development :: Build Tools",
|
|
24
|
+
"Topic :: System :: Monitoring",
|
|
25
|
+
]
|
|
26
|
+
dependencies = []
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/oha/wooster"
|
|
30
|
+
Repository = "https://github.com/oha/wooster"
|
|
31
|
+
Issues = "https://github.com/oha/wooster/issues"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
wooster = "wooster.cli:main"
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["hatchling"]
|
|
38
|
+
build-backend = "hatchling.build"
|
|
39
|
+
|
|
40
|
+
[tool.hatch.build.targets.wheel]
|
|
41
|
+
packages = ["wooster"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|