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.
Files changed (51) hide show
  1. {hades_cli-0.1.2 → hades_cli-0.1.4}/.gitignore +3 -0
  2. {hades_cli-0.1.2 → hades_cli-0.1.4}/PKG-INFO +2 -2
  3. {hades_cli-0.1.2 → hades_cli-0.1.4}/README.md +1 -1
  4. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/_version.py +2 -2
  5. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/watch.py +15 -4
  6. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/process_checker.py +13 -3
  7. hades_cli-0.1.4/tests/test_process_checker.py +26 -0
  8. hades_cli-0.1.2/AGENTS.md +0 -13
  9. hades_cli-0.1.2/CLAUDE.md +0 -13
  10. {hades_cli-0.1.2 → hades_cli-0.1.4}/.github/workflows/pylint.yml +0 -0
  11. {hades_cli-0.1.2 → hades_cli-0.1.4}/.github/workflows/python-publish.yml +0 -0
  12. {hades_cli-0.1.2 → hades_cli-0.1.4}/.python-version +0 -0
  13. {hades_cli-0.1.2 → hades_cli-0.1.4}/PRD.md +0 -0
  14. {hades_cli-0.1.2 → hades_cli-0.1.4}/SECURITY.md +0 -0
  15. {hades_cli-0.1.2 → hades_cli-0.1.4}/docs/agents/domain.md +0 -0
  16. {hades_cli-0.1.2 → hades_cli-0.1.4}/docs/agents/issue-tracker.md +0 -0
  17. {hades_cli-0.1.2 → hades_cli-0.1.4}/docs/agents/triage-labels.md +0 -0
  18. {hades_cli-0.1.2 → hades_cli-0.1.4}/pyproject.toml +0 -0
  19. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/__init__.py +0 -0
  20. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/classify.py +0 -0
  21. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/cli.py +0 -0
  22. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/__init__.py +0 -0
  23. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/archive.py +0 -0
  24. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/attention.py +0 -0
  25. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/export.py +0 -0
  26. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/list.py +0 -0
  27. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/purge.py +0 -0
  28. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/search.py +0 -0
  29. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/show.py +0 -0
  30. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/commands/stats.py +0 -0
  31. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/db.py +0 -0
  32. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/indexer.py +0 -0
  33. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/models.py +0 -0
  34. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/__init__.py +0 -0
  35. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/base.py +0 -0
  36. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/claude.py +0 -0
  37. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/codex.py +0 -0
  38. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/common.py +0 -0
  39. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/cowork.py +0 -0
  40. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/sources/gemini.py +0 -0
  41. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/transcript.py +0 -0
  42. {hades_cli-0.1.2 → hades_cli-0.1.4}/src/hades/waiting.py +0 -0
  43. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/__init__.py +0 -0
  44. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/conftest.py +0 -0
  45. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_classify.py +0 -0
  46. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_commands.py +0 -0
  47. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_db.py +0 -0
  48. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_indexer.py +0 -0
  49. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_second_pass.py +0 -0
  50. {hades_cli-0.1.2 → hades_cli-0.1.4}/tests/test_transcript.py +0 -0
  51. {hades_cli-0.1.2 → hades_cli-0.1.4}/uv.lock +0 -0
@@ -10,3 +10,6 @@ build/
10
10
  src/hades/_version.py
11
11
  .claude/
12
12
  .vscode/
13
+
14
+ AGENTS.md
15
+ CLAUDE.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hades-cli
3
- Version: 0.1.2
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
- > *The dead or the living will be seen by Hades. No AI session escapes.*
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
- > *The dead or the living will be seen by Hades. No AI session escapes.*
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.2'
22
- __version_tuple__ = version_tuple = (0, 1, 2)
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=1, screen=False) as live:
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
- live.update(table)
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
- time.sleep(REFRESH_SECONDS)
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
- if name == "gemini" or ("gemini" in cmdline and "cli" in cmdline):
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