ccmon 0.5.4__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.
- ccmon-0.5.4/.github/workflows/ci.yml +41 -0
- ccmon-0.5.4/.github/workflows/publish.yml +108 -0
- ccmon-0.5.4/.gitignore +45 -0
- ccmon-0.5.4/.pre-commit-config.yaml +15 -0
- ccmon-0.5.4/CHANGELOG.md +132 -0
- ccmon-0.5.4/CLAUDE.md +23 -0
- ccmon-0.5.4/Makefile +28 -0
- ccmon-0.5.4/PKG-INFO +121 -0
- ccmon-0.5.4/README.md +108 -0
- ccmon-0.5.4/ccmon.py +640 -0
- ccmon-0.5.4/homebrew/ccmon.rb +21 -0
- ccmon-0.5.4/pyproject.toml +48 -0
- ccmon-0.5.4/pyrightconfig.json +5 -0
- ccmon-0.5.4/tests/__init__.py +0 -0
- ccmon-0.5.4/tests/test_app.py +107 -0
- ccmon-0.5.4/tests/test_data_layer.py +653 -0
- ccmon-0.5.4/uv.lock +432 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: astral-sh/setup-uv@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.11"
|
|
18
|
+
- name: Install dependencies
|
|
19
|
+
run: uv sync --group dev
|
|
20
|
+
- name: Ruff lint
|
|
21
|
+
run: uv run ruff check --output-format github
|
|
22
|
+
- name: Ruff format check
|
|
23
|
+
run: uv run ruff format --check
|
|
24
|
+
- name: Type check (pyright)
|
|
25
|
+
run: uv run pyright
|
|
26
|
+
|
|
27
|
+
test:
|
|
28
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
strategy:
|
|
31
|
+
matrix:
|
|
32
|
+
python-version: ["3.11", "3.12"]
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
- uses: astral-sh/setup-uv@v5
|
|
36
|
+
with:
|
|
37
|
+
python-version: ${{ matrix.python-version }}
|
|
38
|
+
- name: Install dependencies
|
|
39
|
+
run: uv sync --group dev
|
|
40
|
+
- name: Run tests
|
|
41
|
+
run: uv run pytest -q --tb=short --no-header --cov=ccmon --cov-fail-under=70
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish-pypi:
|
|
10
|
+
name: Publish to PyPI
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write
|
|
14
|
+
contents: read
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: astral-sh/setup-uv@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.11"
|
|
21
|
+
|
|
22
|
+
- name: Build
|
|
23
|
+
run: uv build
|
|
24
|
+
|
|
25
|
+
- name: Publish to PyPI
|
|
26
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
27
|
+
|
|
28
|
+
update-homebrew:
|
|
29
|
+
name: Update Homebrew formula
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
needs: publish-pypi
|
|
32
|
+
steps:
|
|
33
|
+
- name: Fetch tarball SHA256 from PyPI
|
|
34
|
+
id: pypi
|
|
35
|
+
run: |
|
|
36
|
+
VERSION="${{ github.ref_name }}"
|
|
37
|
+
# Strip leading 'v' from tag to get bare version number
|
|
38
|
+
PKG_VERSION="${VERSION#v}"
|
|
39
|
+
PYPI_JSON=$(curl -s "https://pypi.org/pypi/ccmon/${PKG_VERSION}/json")
|
|
40
|
+
SHA256=$(echo "$PYPI_JSON" | jq -r '
|
|
41
|
+
.urls[]
|
|
42
|
+
| select(.packagetype == "sdist" and (.filename | endswith(".tar.gz")))
|
|
43
|
+
| .digests.sha256
|
|
44
|
+
')
|
|
45
|
+
if [ -z "$SHA256" ] || [ "$SHA256" = "null" ]; then
|
|
46
|
+
echo "ERROR: Could not find sha256 for ccmon ${PKG_VERSION} on PyPI"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
echo "version=${PKG_VERSION}" >> "$GITHUB_OUTPUT"
|
|
50
|
+
echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT"
|
|
51
|
+
|
|
52
|
+
- name: Checkout homebrew-tap
|
|
53
|
+
uses: actions/checkout@v4
|
|
54
|
+
with:
|
|
55
|
+
repository: einerlei/homebrew-tap
|
|
56
|
+
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
57
|
+
path: homebrew-tap
|
|
58
|
+
|
|
59
|
+
- name: Update Formula/ccmon.rb
|
|
60
|
+
run: |
|
|
61
|
+
FORMULA="homebrew-tap/Formula/ccmon.rb"
|
|
62
|
+
VERSION="${{ steps.pypi.outputs.version }}"
|
|
63
|
+
SHA256="${{ steps.pypi.outputs.sha256 }}"
|
|
64
|
+
|
|
65
|
+
# Update url line (replace version in the PyPI tarball URL)
|
|
66
|
+
python3 - <<'PYEOF'
|
|
67
|
+
import re, os, sys
|
|
68
|
+
|
|
69
|
+
formula_path = os.environ.get("FORMULA", "homebrew-tap/Formula/ccmon.rb")
|
|
70
|
+
version = os.environ.get("VERSION")
|
|
71
|
+
sha256 = os.environ.get("SHA256")
|
|
72
|
+
|
|
73
|
+
with open(formula_path) as f:
|
|
74
|
+
content = f.read()
|
|
75
|
+
|
|
76
|
+
# Replace url line
|
|
77
|
+
content = re.sub(
|
|
78
|
+
r'(url\s+"https://files\.pythonhosted\.org/packages/source/c/ccmon/ccmon-)[^"]+(")',
|
|
79
|
+
rf'\g<1>{version}.tar.gz\g<2>',
|
|
80
|
+
content,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# Replace sha256 line (first occurrence — the top-level package sha256)
|
|
84
|
+
content = re.sub(
|
|
85
|
+
r'(sha256\s+")[a-f0-9]+"',
|
|
86
|
+
rf'\g<1>{sha256}"',
|
|
87
|
+
content,
|
|
88
|
+
count=1,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
with open(formula_path, "w") as f:
|
|
92
|
+
f.write(content)
|
|
93
|
+
|
|
94
|
+
print(f"Updated {formula_path} to version {version} sha256 {sha256[:16]}…")
|
|
95
|
+
PYEOF
|
|
96
|
+
env:
|
|
97
|
+
FORMULA: homebrew-tap/Formula/ccmon.rb
|
|
98
|
+
VERSION: ${{ steps.pypi.outputs.version }}
|
|
99
|
+
SHA256: ${{ steps.pypi.outputs.sha256 }}
|
|
100
|
+
|
|
101
|
+
- name: Commit and push
|
|
102
|
+
run: |
|
|
103
|
+
cd homebrew-tap
|
|
104
|
+
git config user.name "einerlei"
|
|
105
|
+
git config user.email "31n34731@gmail.com"
|
|
106
|
+
git add Formula/ccmon.rb
|
|
107
|
+
git commit -m "chore: bump ccmon to ${{ steps.pypi.outputs.version }}"
|
|
108
|
+
git push
|
ccmon-0.5.4/.gitignore
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
*.egg
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.whl
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# Poetry
|
|
18
|
+
# poetry.lock is intentionally tracked for reproducible installs
|
|
19
|
+
|
|
20
|
+
# Testing & coverage
|
|
21
|
+
.pytest_cache/
|
|
22
|
+
.coverage
|
|
23
|
+
htmlcov/
|
|
24
|
+
.tox/
|
|
25
|
+
|
|
26
|
+
# Type checkers
|
|
27
|
+
.mypy_cache/
|
|
28
|
+
.ruff_cache/
|
|
29
|
+
|
|
30
|
+
# IDE
|
|
31
|
+
.idea/
|
|
32
|
+
.vscode/
|
|
33
|
+
*.swp
|
|
34
|
+
*.swo
|
|
35
|
+
|
|
36
|
+
# macOS
|
|
37
|
+
.DS_Store
|
|
38
|
+
|
|
39
|
+
# Claude Code
|
|
40
|
+
.claude/
|
|
41
|
+
|
|
42
|
+
# Env files
|
|
43
|
+
.env
|
|
44
|
+
.env.*
|
|
45
|
+
!.env.example
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.9.10
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
- repo: local
|
|
9
|
+
hooks:
|
|
10
|
+
- id: pyright
|
|
11
|
+
name: pyright
|
|
12
|
+
entry: poetry run pyright
|
|
13
|
+
language: system
|
|
14
|
+
types: [python]
|
|
15
|
+
pass_filenames: false
|
ccmon-0.5.4/CHANGELOG.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## Releasing a new version
|
|
9
|
+
|
|
10
|
+
1. Update `version` in `pyproject.toml`
|
|
11
|
+
2. Update `__version__` in `ccmon.py`
|
|
12
|
+
3. Add release notes under a new `## [X.Y.Z] - YYYY-MM-DD` section below
|
|
13
|
+
4. Commit: `git commit -m "chore: release vX.Y.Z"`
|
|
14
|
+
5. Tag: `git tag vX.Y.Z`
|
|
15
|
+
6. Push: `git push && git push --tags`
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [Unreleased]
|
|
20
|
+
|
|
21
|
+
## [0.5.4] - 2026-05-10
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- Migrated build tooling from Poetry to uv (hatchling build backend, PEP 735 dependency groups)
|
|
25
|
+
|
|
26
|
+
## [0.5.3] - 2026-05-10
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- Token usage display: each agent pane shows its cumulative output-token count; the status bar shows the session-wide total
|
|
30
|
+
|
|
31
|
+
## [0.5.2] - 2026-05-10
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- `-a` as a short alias for `--all`
|
|
35
|
+
|
|
36
|
+
## [0.5.1] - 2026-05-10
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
- `--all` now shows sessions that are idle (waiting for user input); previously they disappeared after 5 seconds because Claude's last response was mistaken for a completed/expired agent
|
|
40
|
+
|
|
41
|
+
## [0.5.0] - 2026-05-05
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- Renamed package and command from `cctop` to `ccmon`
|
|
45
|
+
|
|
46
|
+
## [0.4.0] - 2026-05-04
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
- Positional `DIR` argument: `cctop .` or `cctop /path/to/project` filters to that directory
|
|
50
|
+
- `-p` short alias for `--project`
|
|
51
|
+
- Bare `cctop` (no arguments) defaults to the current working directory
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
- `--all` and `--project`/`-p`/positional DIR are now explicitly mutually exclusive with a clear error message
|
|
55
|
+
|
|
56
|
+
## [0.3.6] - 2026-05-04
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
- `make install` uses `pipx` (the standard for CLI tools); removed redundant `make install-pipx` target
|
|
60
|
+
|
|
61
|
+
## [0.3.5] - 2026-05-04
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
- `make install` now uses `pip install .`; `make install-pipx` added for pipx-based installs
|
|
65
|
+
- Removed `/delegate` skill reference from `CLAUDE.md` (it is a custom skill, not a Claude built-in)
|
|
66
|
+
|
|
67
|
+
## [0.3.4] - 2026-05-04
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
- `make install` now gives a clear error if `pipx` is not installed instead of a cryptic make failure
|
|
71
|
+
- `make test` coverage target corrected from `--cov=dashboard` to `--cov=cctop`
|
|
72
|
+
|
|
73
|
+
## [0.3.3] - 2026-05-04
|
|
74
|
+
|
|
75
|
+
### Fixed
|
|
76
|
+
- CI venv cache key now includes `pyproject.toml` so adding/changing dev dependencies (e.g. `pyright`) reliably invalidates the cache
|
|
77
|
+
|
|
78
|
+
## [0.3.2] - 2026-05-04
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
- Renamed main module from `dashboard.py` to `cctop.py` to align with CLI and project name
|
|
82
|
+
|
|
83
|
+
## [0.3.1] - 2026-05-04
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
- Ensured `pyright` is resolvable via `poetry run pyright` in CI by confirming it is
|
|
87
|
+
declared in the `[tool.poetry.group.dev.dependencies]` section; recreating the
|
|
88
|
+
virtual environment resolves stale-venv cache misses that caused "Command not found"
|
|
89
|
+
|
|
90
|
+
## [0.3.0] - 2026-05-04
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
- **Renamed** project to `cctop`; CLI entrypoint is now `cctop`
|
|
94
|
+
- Empty state message updated: "No active Claude Code session" (was "No subagents for project")
|
|
95
|
+
- App title updated to "Claude Code Monitor"
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
- `Makefile` with `lint`, `format`, `check`, and `test` targets for developer convenience
|
|
99
|
+
- `pytest-cov` with 70% coverage floor enforced in CI
|
|
100
|
+
- `pyright` type-checking step in CI lint job
|
|
101
|
+
- `.pre-commit-config.yaml` with ruff and pyright hooks
|
|
102
|
+
- 16 new unit tests covering `_render_output`, `_build_agent_type_lookup`, `_last_skill_call`
|
|
103
|
+
|
|
104
|
+
### Refactored
|
|
105
|
+
- Extracted `_status_display` helper; eliminated duplicated markup logic in `AgentPane`
|
|
106
|
+
|
|
107
|
+
## [0.2.1] - 2026-05-03
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
- Main Claude Code session pane: the parent session now appears alongside its
|
|
111
|
+
subagents, rendered with `◈` symbol and a cyan border (`pane--main` CSS class)
|
|
112
|
+
|
|
113
|
+
## [0.2.0] - 2026-05-03
|
|
114
|
+
|
|
115
|
+
### Added
|
|
116
|
+
- Test suite with pytest (unit tests for data layer and CLI)
|
|
117
|
+
- GitHub Actions CI workflow (lint + test on push/PR to main)
|
|
118
|
+
- `__version__` constant in `cctop.py`
|
|
119
|
+
- Expanded README with architecture overview, dev setup, and contributing guide
|
|
120
|
+
|
|
121
|
+
### Changed
|
|
122
|
+
- Code quality improvements based on review (type annotations, error handling)
|
|
123
|
+
|
|
124
|
+
## [0.1.0] - 2026-04-01
|
|
125
|
+
|
|
126
|
+
### Added
|
|
127
|
+
- Initial release: terminal TUI for monitoring Claude Code subagents
|
|
128
|
+
- Real-time auto-refresh (0.5s interval)
|
|
129
|
+
- Session filtering by project directory (`--project`, `--all` flags)
|
|
130
|
+
- Status tracking: running, completed, interrupted, unknown
|
|
131
|
+
- Stale agent expiry (10-minute timeout for non-running agents)
|
|
132
|
+
- 2-column grid layout with Rich-styled message history per agent
|
ccmon-0.5.4/CLAUDE.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# CLAUDE.md — Project instructions for Claude Code
|
|
2
|
+
|
|
3
|
+
## Version bumps
|
|
4
|
+
|
|
5
|
+
Every workflow that produces user-facing or tooling changes **must** include a version
|
|
6
|
+
bump. Use semantic versioning:
|
|
7
|
+
|
|
8
|
+
- Breaking change (renamed CLI, removed feature) → minor bump (0.x.0)
|
|
9
|
+
- New feature or behaviour change → minor bump (0.x.0)
|
|
10
|
+
- Bug fix or internal refactor only → patch bump (0.x.x)
|
|
11
|
+
|
|
12
|
+
Update both `pyproject.toml` (`version =`) and `ccmon.py` (`__version__ =`), and add a
|
|
13
|
+
`## [X.Y.Z] - YYYY-MM-DD` entry to `CHANGELOG.md` following the Keep a Changelog format.
|
|
14
|
+
|
|
15
|
+
## Smoke-test after changes
|
|
16
|
+
|
|
17
|
+
After any code change, verify the app starts:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
poetry run ccmon --help
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Unit tests passing is not sufficient — always run the CLI entrypoint too.
|
ccmon-0.5.4/Makefile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.PHONY: lint format check test install release
|
|
2
|
+
|
|
3
|
+
lint:
|
|
4
|
+
uv run ruff check .
|
|
5
|
+
|
|
6
|
+
format:
|
|
7
|
+
uv run ruff format .
|
|
8
|
+
|
|
9
|
+
check:
|
|
10
|
+
uv run ruff check . && uv run ruff format --check . && uv run pyright
|
|
11
|
+
|
|
12
|
+
test:
|
|
13
|
+
uv run pytest -q --tb=short --no-header --cov=ccmon --cov-fail-under=70
|
|
14
|
+
|
|
15
|
+
install:
|
|
16
|
+
@which pipx >/dev/null 2>&1 || { echo "pipx not found. Install with: brew install pipx"; exit 1; }
|
|
17
|
+
pipx install . --force
|
|
18
|
+
pipx ensurepath
|
|
19
|
+
@if ! echo "$$PATH" | grep -q "$$HOME/.local/bin"; then \
|
|
20
|
+
echo ""; \
|
|
21
|
+
echo " ccmon is installed but not yet in your PATH."; \
|
|
22
|
+
echo " Run: source ~/.zshrc"; \
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
release:
|
|
26
|
+
@test -n "$(VERSION)" || (echo "Usage: make release VERSION=x.y.z"; exit 1)
|
|
27
|
+
git tag v$(VERSION)
|
|
28
|
+
git push && git push --tags
|
ccmon-0.5.4/PKG-INFO
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ccmon
|
|
3
|
+
Version: 0.5.4
|
|
4
|
+
Summary: Terminal monitor for Claude Code sessions and subagents
|
|
5
|
+
Project-URL: Homepage, https://github.com/einerlei/ccmon
|
|
6
|
+
Project-URL: Repository, https://github.com/einerlei/ccmon
|
|
7
|
+
Project-URL: Changelog, https://github.com/einerlei/ccmon/blob/main/CHANGELOG.md
|
|
8
|
+
Author-email: einerlei <31n34731@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Requires-Dist: textual<9.0.0,>=8.2.5
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# ccmon
|
|
15
|
+
|
|
16
|
+
Terminal monitor for Claude Code sessions and subagents in real time. Run `ccmon` to watch your agents.
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- **Real-time monitoring** — watch subagent status, output, and activity as they run
|
|
21
|
+
- **Session filtering** — view agents from the current project, a specific project, or all projects
|
|
22
|
+
- **Status tracking** — running, completed, interrupted, or unknown states with visual indicators
|
|
23
|
+
- **Auto-refresh** — updates every 0.5 seconds without manual intervention
|
|
24
|
+
- **Stale expiry** — completed/interrupted agents are automatically removed after 10 minutes of inactivity
|
|
25
|
+
- **Manager agent visibility** — shows which specialised agent is currently running in manager-type agents
|
|
26
|
+
|
|
27
|
+
## Requirements
|
|
28
|
+
|
|
29
|
+
- Python 3.11+
|
|
30
|
+
- Poetry
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
### Homebrew (macOS, recommended)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
brew install einerlei/tap/ccmon
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### pipx (cross-platform)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pipx install ccmon
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### pip
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install ccmon
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Development setup
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/einerlei/ccmon.git
|
|
56
|
+
cd ccmon
|
|
57
|
+
poetry install
|
|
58
|
+
poetry run ccmon
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
ccmon
|
|
65
|
+
ccmon --project /path/to/project
|
|
66
|
+
ccmon --all
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Key bindings
|
|
70
|
+
|
|
71
|
+
| Key | Action |
|
|
72
|
+
|-----|--------|
|
|
73
|
+
| `r` | Manual refresh |
|
|
74
|
+
| `q` | Quit |
|
|
75
|
+
|
|
76
|
+
## Architecture
|
|
77
|
+
|
|
78
|
+
The monitor is a single-file Python application using the Textual TUI framework.
|
|
79
|
+
|
|
80
|
+
**Data sources:**
|
|
81
|
+
- Sessions: `~/.claude/sessions/*.json` — contains PID, working directory, and session ID
|
|
82
|
+
- Subagents: `~/.claude/projects/{project-dir}/{session-id}/subagents/` — per-agent metadata and message logs
|
|
83
|
+
|
|
84
|
+
**How it works:**
|
|
85
|
+
1. Loads active sessions from the sessions directory, filtering by project if specified
|
|
86
|
+
2. For each live session, discovers subagents and reads their `.meta.json` (metadata) and `.jsonl` (messages)
|
|
87
|
+
3. Infers agent status by analysing message history and checking process liveness
|
|
88
|
+
4. Expires completed/interrupted agents after 10 minutes without activity
|
|
89
|
+
5. Renders a two-column grid of agent panes with scrolling output
|
|
90
|
+
6. Refreshes every 0.5 seconds to keep the view current
|
|
91
|
+
|
|
92
|
+
## Development
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Install with dev dependencies
|
|
96
|
+
poetry install
|
|
97
|
+
|
|
98
|
+
# Run tests
|
|
99
|
+
poetry run pytest -q
|
|
100
|
+
|
|
101
|
+
# Lint and format
|
|
102
|
+
poetry run ruff check
|
|
103
|
+
poetry run ruff format --check
|
|
104
|
+
|
|
105
|
+
# Run the monitor
|
|
106
|
+
ccmon
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Contributing
|
|
110
|
+
|
|
111
|
+
1. Fork the repository
|
|
112
|
+
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
113
|
+
3. Commit your changes (`git commit -am 'Add feature'`)
|
|
114
|
+
4. Push to the branch (`git push origin feature/my-feature`)
|
|
115
|
+
5. Open a Pull Request
|
|
116
|
+
|
|
117
|
+
All code must pass `ruff check` and `ruff format --check`. Add tests for new functionality.
|
|
118
|
+
|
|
119
|
+
## Changelog
|
|
120
|
+
|
|
121
|
+
See [CHANGELOG.md](CHANGELOG.md)
|
ccmon-0.5.4/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# ccmon
|
|
2
|
+
|
|
3
|
+
Terminal monitor for Claude Code sessions and subagents in real time. Run `ccmon` to watch your agents.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Real-time monitoring** — watch subagent status, output, and activity as they run
|
|
8
|
+
- **Session filtering** — view agents from the current project, a specific project, or all projects
|
|
9
|
+
- **Status tracking** — running, completed, interrupted, or unknown states with visual indicators
|
|
10
|
+
- **Auto-refresh** — updates every 0.5 seconds without manual intervention
|
|
11
|
+
- **Stale expiry** — completed/interrupted agents are automatically removed after 10 minutes of inactivity
|
|
12
|
+
- **Manager agent visibility** — shows which specialised agent is currently running in manager-type agents
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- Python 3.11+
|
|
17
|
+
- Poetry
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
### Homebrew (macOS, recommended)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
brew install einerlei/tap/ccmon
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### pipx (cross-platform)
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pipx install ccmon
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### pip
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install ccmon
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Development setup
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/einerlei/ccmon.git
|
|
43
|
+
cd ccmon
|
|
44
|
+
poetry install
|
|
45
|
+
poetry run ccmon
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
ccmon
|
|
52
|
+
ccmon --project /path/to/project
|
|
53
|
+
ccmon --all
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Key bindings
|
|
57
|
+
|
|
58
|
+
| Key | Action |
|
|
59
|
+
|-----|--------|
|
|
60
|
+
| `r` | Manual refresh |
|
|
61
|
+
| `q` | Quit |
|
|
62
|
+
|
|
63
|
+
## Architecture
|
|
64
|
+
|
|
65
|
+
The monitor is a single-file Python application using the Textual TUI framework.
|
|
66
|
+
|
|
67
|
+
**Data sources:**
|
|
68
|
+
- Sessions: `~/.claude/sessions/*.json` — contains PID, working directory, and session ID
|
|
69
|
+
- Subagents: `~/.claude/projects/{project-dir}/{session-id}/subagents/` — per-agent metadata and message logs
|
|
70
|
+
|
|
71
|
+
**How it works:**
|
|
72
|
+
1. Loads active sessions from the sessions directory, filtering by project if specified
|
|
73
|
+
2. For each live session, discovers subagents and reads their `.meta.json` (metadata) and `.jsonl` (messages)
|
|
74
|
+
3. Infers agent status by analysing message history and checking process liveness
|
|
75
|
+
4. Expires completed/interrupted agents after 10 minutes without activity
|
|
76
|
+
5. Renders a two-column grid of agent panes with scrolling output
|
|
77
|
+
6. Refreshes every 0.5 seconds to keep the view current
|
|
78
|
+
|
|
79
|
+
## Development
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Install with dev dependencies
|
|
83
|
+
poetry install
|
|
84
|
+
|
|
85
|
+
# Run tests
|
|
86
|
+
poetry run pytest -q
|
|
87
|
+
|
|
88
|
+
# Lint and format
|
|
89
|
+
poetry run ruff check
|
|
90
|
+
poetry run ruff format --check
|
|
91
|
+
|
|
92
|
+
# Run the monitor
|
|
93
|
+
ccmon
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Contributing
|
|
97
|
+
|
|
98
|
+
1. Fork the repository
|
|
99
|
+
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
100
|
+
3. Commit your changes (`git commit -am 'Add feature'`)
|
|
101
|
+
4. Push to the branch (`git push origin feature/my-feature`)
|
|
102
|
+
5. Open a Pull Request
|
|
103
|
+
|
|
104
|
+
All code must pass `ruff check` and `ruff format --check`. Add tests for new functionality.
|
|
105
|
+
|
|
106
|
+
## Changelog
|
|
107
|
+
|
|
108
|
+
See [CHANGELOG.md](CHANGELOG.md)
|