hades-cli 0.1.2__tar.gz → 0.1.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.
- {hades_cli-0.1.2 → hades_cli-0.1.4}/.gitignore +3 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/PKG-INFO +2 -2
- {hades_cli-0.1.2 → hades_cli-0.1.4}/README.md +1 -1
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/_version.py +2 -2
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/watch.py +15 -4
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/process_checker.py +13 -3
- hades_cli-0.1.4/tests/test_process_checker.py +26 -0
- hades_cli-0.1.2/AGENTS.md +0 -13
- hades_cli-0.1.2/CLAUDE.md +0 -13
- {hades_cli-0.1.2 → hades_cli-0.1.4}/.github/workflows/pylint.yml +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/.github/workflows/python-publish.yml +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/.python-version +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/PRD.md +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/SECURITY.md +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/docs/agents/domain.md +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/docs/agents/issue-tracker.md +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/docs/agents/triage-labels.md +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/pyproject.toml +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/__init__.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/classify.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/cli.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/__init__.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/archive.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/attention.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/export.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/list.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/purge.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/search.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/show.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/stats.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/db.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/indexer.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/models.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/__init__.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/base.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/claude.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/codex.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/common.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/cowork.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/gemini.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/transcript.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/waiting.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/__init__.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/conftest.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_classify.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_commands.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_db.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_indexer.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_second_pass.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_transcript.py +0 -0
- {hades_cli-0.1.2 → hades_cli-0.1.4}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hades-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: A local CLI for viewing, searching, and managing AI coding sessions across Claude Code, Codex, Gemini, and Cowork.
|
|
5
5
|
Project-URL: Homepage, https://github.com/mnghn07/hades
|
|
6
6
|
Project-URL: Repository, https://github.com/mnghn07/hades
|
|
@@ -17,7 +17,7 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
|
|
18
18
|
# hades
|
|
19
19
|
|
|
20
|
-
> *
|
|
20
|
+
> *Keeper of sessions, living and dead.*
|
|
21
21
|
|
|
22
22
|
A CLI for viewing, searching, and managing your AI coding sessions across Claude Code, Codex CLI, Gemini CLI, and Cowork — all from one terminal.
|
|
23
23
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# hades
|
|
2
2
|
|
|
3
|
-
> *
|
|
3
|
+
> *Keeper of sessions, living and dead.*
|
|
4
4
|
|
|
5
5
|
A CLI for viewing, searching, and managing your AI coding sessions across Claude Code, Codex CLI, Gemini CLI, and Cowork — all from one terminal.
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.1.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
21
|
+
__version__ = version = '0.1.4'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 4)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -5,9 +5,10 @@ from datetime import datetime, timezone
|
|
|
5
5
|
|
|
6
6
|
import typer
|
|
7
7
|
from rich import box
|
|
8
|
-
from rich.console import Console
|
|
8
|
+
from rich.console import Console, Group
|
|
9
9
|
from rich.live import Live
|
|
10
10
|
from rich.markup import escape
|
|
11
|
+
from rich.spinner import Spinner
|
|
11
12
|
from rich.table import Table
|
|
12
13
|
|
|
13
14
|
from hades.db import get_db
|
|
@@ -18,6 +19,7 @@ from hades.waiting import recent_human_sessions
|
|
|
18
19
|
console = Console()
|
|
19
20
|
|
|
20
21
|
REFRESH_SECONDS = 30
|
|
22
|
+
MIN_SPINNER_SECONDS = 0.5
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
def cmd_watch(
|
|
@@ -33,17 +35,26 @@ def cmd_watch(
|
|
|
33
35
|
console.print("[bold]hades watch[/bold] · refreshing every 30s · [dim]Ctrl+C to exit[/dim]\n")
|
|
34
36
|
|
|
35
37
|
try:
|
|
36
|
-
with Live(console=console, refresh_per_second=
|
|
38
|
+
with Live(console=console, refresh_per_second=4, screen=False) as live:
|
|
37
39
|
while True:
|
|
40
|
+
live.update(Spinner("dots", text="[dim]checking for sessions...[/dim]"))
|
|
41
|
+
live.refresh()
|
|
42
|
+
check_started = time.monotonic()
|
|
38
43
|
table, newly_waiting = _build_table(notified, refresh=True)
|
|
39
|
-
|
|
44
|
+
elapsed = time.monotonic() - check_started
|
|
45
|
+
if elapsed < MIN_SPINNER_SECONDS:
|
|
46
|
+
time.sleep(MIN_SPINNER_SECONDS - elapsed)
|
|
40
47
|
|
|
41
48
|
if notify:
|
|
42
49
|
for s in newly_waiting:
|
|
43
50
|
_send_notification(s)
|
|
44
51
|
notified.add(s["id"])
|
|
45
52
|
|
|
46
|
-
|
|
53
|
+
footer_spinner = Spinner("dots")
|
|
54
|
+
for remaining in range(REFRESH_SECONDS, 0, -1):
|
|
55
|
+
footer_spinner.update(text=f"[dim]next check in {remaining}s[/dim]")
|
|
56
|
+
live.update(Group(table, footer_spinner))
|
|
57
|
+
time.sleep(1)
|
|
47
58
|
except KeyboardInterrupt:
|
|
48
59
|
console.print("\n[dim]Stopped.[/dim]")
|
|
49
60
|
|
|
@@ -82,12 +82,22 @@ def _classify(name: str, cmdline: str) -> str | None:
|
|
|
82
82
|
if "stream-json" in cmdline and ("claude" in name or re.match(r"\d+\.\d+\.\d+", name)):
|
|
83
83
|
return "claude"
|
|
84
84
|
|
|
85
|
-
# Codex CLI
|
|
85
|
+
# Codex CLI: JS shim spawns a native binary named 'codex' as a child
|
|
86
|
+
# process (verified against a real npx-launched session), so the
|
|
87
|
+
# eventual process name is 'codex', not 'node'.
|
|
86
88
|
if "codex" in name:
|
|
87
89
|
return "codex"
|
|
88
90
|
|
|
89
|
-
# Gemini CLI (not the desktop app — already excluded by cwd check above)
|
|
90
|
-
|
|
91
|
+
# Gemini CLI (not the desktop app — already excluded by cwd check above).
|
|
92
|
+
# It's a pure-JS process (no native binary), so `name` is 'node', not
|
|
93
|
+
# 'gemini' — match the invoked script path instead (verified against a
|
|
94
|
+
# real npx-launched session, e.g. ".../node_modules/.bin/gemini").
|
|
95
|
+
if name == "gemini":
|
|
91
96
|
return "gemini"
|
|
97
|
+
if name == "node":
|
|
98
|
+
for part in cmdline.split():
|
|
99
|
+
basename = part.rsplit("/", 1)[-1]
|
|
100
|
+
if basename == "gemini":
|
|
101
|
+
return "gemini"
|
|
92
102
|
|
|
93
103
|
return None
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from hades.process_checker import _classify
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_claude_interactive_session_stream_json():
|
|
5
|
+
assert _classify("claude", "/x/claude --output-format stream-json --verbose") == "claude"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_claude_version_named_binary():
|
|
9
|
+
assert _classify("2.1.199", "/x/claude --output-format stream-json") == "claude"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_codex_native_binary_child_process():
|
|
13
|
+
assert _classify("codex", "/x/vendor/aarch64-apple-darwin/bin/codex") == "codex"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_gemini_npx_launched_script_path():
|
|
17
|
+
cmdline = "/x/node --max-old-space-size=24576 /x/.npm/_npx/hash/node_modules/.bin/gemini"
|
|
18
|
+
assert _classify("node", cmdline) == "gemini"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_gemini_direct_binary_name():
|
|
22
|
+
assert _classify("gemini", "/x/gemini") == "gemini"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_unrelated_node_process_not_classified():
|
|
26
|
+
assert _classify("node", "node -e some_unrelated_script.js") is None
|
hades_cli-0.1.2/AGENTS.md
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
## Agent skills
|
|
2
|
-
|
|
3
|
-
### Issue tracker
|
|
4
|
-
|
|
5
|
-
Issues live in GitHub Issues (gh CLI); external PRs are not a triage surface. See `docs/agents/issue-tracker.md`.
|
|
6
|
-
|
|
7
|
-
### Triage labels
|
|
8
|
-
|
|
9
|
-
Default label vocabulary (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`). See `docs/agents/triage-labels.md`.
|
|
10
|
-
|
|
11
|
-
### Domain docs
|
|
12
|
-
|
|
13
|
-
Single-context layout — one `CONTEXT.md` + `docs/adr/` at the repo root. See `docs/agents/domain.md`.
|
hades_cli-0.1.2/CLAUDE.md
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
## Agent skills
|
|
2
|
-
|
|
3
|
-
### Issue tracker
|
|
4
|
-
|
|
5
|
-
Issues live in GitHub Issues (gh CLI); external PRs are not a triage surface. See `docs/agents/issue-tracker.md`.
|
|
6
|
-
|
|
7
|
-
### Triage labels
|
|
8
|
-
|
|
9
|
-
Default label vocabulary (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`). See `docs/agents/triage-labels.md`.
|
|
10
|
-
|
|
11
|
-
### Domain docs
|
|
12
|
-
|
|
13
|
-
Single-context layout — one `CONTEXT.md` + `docs/adr/` at the repo root. See `docs/agents/domain.md`.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|