codex-statusline 0.2.1__tar.gz → 0.2.2__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 (30) hide show
  1. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/PKG-INFO +2 -3
  2. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/README.md +1 -2
  3. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/codex_statusline.egg-info/PKG-INFO +2 -3
  4. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/pyproject.toml +1 -1
  5. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/__init__.py +1 -1
  6. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/cli.py +19 -46
  7. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/render.py +1 -1
  8. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_update.py +4 -4
  9. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/LICENSE +0 -0
  10. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/codex_statusline.egg-info/SOURCES.txt +0 -0
  11. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/codex_statusline.egg-info/dependency_links.txt +0 -0
  12. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/codex_statusline.egg-info/entry_points.txt +0 -0
  13. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/codex_statusline.egg-info/top_level.txt +0 -0
  14. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/setup.cfg +0 -0
  15. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/__main__.py +0 -0
  16. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/configure.py +0 -0
  17. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/data.py +0 -0
  18. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/entry.py +0 -0
  19. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/hook.py +0 -0
  20. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/launcher.py +0 -0
  21. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/manage.py +0 -0
  22. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/src/update.py +0 -0
  23. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_auto_shells.py +0 -0
  24. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_configure.py +0 -0
  25. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_data.py +0 -0
  26. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_fish.py +0 -0
  27. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_management.py +0 -0
  28. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_render.py +0 -0
  29. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_startup.py +0 -0
  30. {codex_statusline-0.2.1 → codex_statusline-0.2.2}/tests/test_tmux.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-statusline
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A tmux statusline for OpenAI Codex CLI: context usage, 5h and weekly quota, and session tokens at a glance. Local-only.
5
5
  Author: Zimo Xu
6
6
  License-Expression: MIT
@@ -59,7 +59,7 @@ Prefer to do it yourself:
59
59
 
60
60
  ```sh
61
61
  uv tool install codex-statusline # or: pipx install codex-statusline
62
- codex-statusline install # add --dry-run to only preview the diff
62
+ codex-statusline install # add --dry-run to see the plan first
63
63
  ```
64
64
 
65
65
  Then **open a new terminal** and run `codex`. The first time, Codex asks you to review a hook: confirm it is `codex-statusline binding`.
@@ -76,7 +76,6 @@ codex exec 'task' # non-interactive: passed straight through, no bar
76
76
  codex-statusline config # pick segments, theme and colors interactively
77
77
  codex-statusline update # upgrade, whichever way you installed it
78
78
  codex-statusline doctor # check versions and dependencies
79
- codex-statusline preview --width 80 # try it without launching Codex
80
79
  codex-statusline uninstall
81
80
  ```
82
81
 
@@ -38,7 +38,7 @@ Prefer to do it yourself:
38
38
 
39
39
  ```sh
40
40
  uv tool install codex-statusline # or: pipx install codex-statusline
41
- codex-statusline install # add --dry-run to only preview the diff
41
+ codex-statusline install # add --dry-run to see the plan first
42
42
  ```
43
43
 
44
44
  Then **open a new terminal** and run `codex`. The first time, Codex asks you to review a hook: confirm it is `codex-statusline binding`.
@@ -55,7 +55,6 @@ codex exec 'task' # non-interactive: passed straight through, no bar
55
55
  codex-statusline config # pick segments, theme and colors interactively
56
56
  codex-statusline update # upgrade, whichever way you installed it
57
57
  codex-statusline doctor # check versions and dependencies
58
- codex-statusline preview --width 80 # try it without launching Codex
59
58
  codex-statusline uninstall
60
59
  ```
61
60
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-statusline
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A tmux statusline for OpenAI Codex CLI: context usage, 5h and weekly quota, and session tokens at a glance. Local-only.
5
5
  Author: Zimo Xu
6
6
  License-Expression: MIT
@@ -59,7 +59,7 @@ Prefer to do it yourself:
59
59
 
60
60
  ```sh
61
61
  uv tool install codex-statusline # or: pipx install codex-statusline
62
- codex-statusline install # add --dry-run to only preview the diff
62
+ codex-statusline install # add --dry-run to see the plan first
63
63
  ```
64
64
 
65
65
  Then **open a new terminal** and run `codex`. The first time, Codex asks you to review a hook: confirm it is `codex-statusline binding`.
@@ -76,7 +76,6 @@ codex exec 'task' # non-interactive: passed straight through, no bar
76
76
  codex-statusline config # pick segments, theme and colors interactively
77
77
  codex-statusline update # upgrade, whichever way you installed it
78
78
  codex-statusline doctor # check versions and dependencies
79
- codex-statusline preview --width 80 # try it without launching Codex
80
79
  codex-statusline uninstall
81
80
  ```
82
81
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codex-statusline"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "A tmux statusline for OpenAI Codex CLI: context usage, 5h and weekly quota, and session tokens at a glance. Local-only."
5
5
  requires-python = ">=3.11"
6
6
  license = "MIT"
@@ -1,3 +1,3 @@
1
1
  """A local-only tmux status area for the official Codex CLI."""
2
2
 
3
- __version__ = "0.2.1"
3
+ __version__ = "0.2.2"
@@ -3,7 +3,6 @@ import json
3
3
  import os
4
4
  import shutil
5
5
  import sys
6
- import time
7
6
  from pathlib import Path
8
7
 
9
8
  from . import __version__
@@ -26,34 +25,34 @@ def main():
26
25
  record()
27
26
  return 0
28
27
  parser = argparse.ArgumentParser(
29
- description="Third-party local tmux statusline for the official Codex CLI."
28
+ prog="codex-statusline",
29
+ description="A status bar for Codex CLI: context, 5h/weekly quota, and tokens. "
30
+ "Run `codex` as usual once installed.",
30
31
  )
31
32
  parser.add_argument("--version", action="version", version=__version__)
32
- sub = parser.add_subparsers(dest="action", required=True)
33
+ sub = parser.add_subparsers(dest="action", required=True, metavar="<command>", title="commands")
34
+ commands = {
35
+ "install": "hook the status bar into `codex` for your shells",
36
+ "uninstall": "remove everything install added",
37
+ "config": "choose what the bar shows, interactively",
38
+ "update": "upgrade to the latest release",
39
+ "doctor": "check Codex, tmux, and Python versions",
40
+ }
41
+ parsers = {
42
+ name: sub.add_parser(name, help=text, description=text) for name, text in commands.items()
43
+ }
33
44
  for name in ("install", "uninstall"):
34
- s = sub.add_parser(name)
45
+ s = parsers[name]
35
46
  s.add_argument(
36
47
  "--shell",
37
48
  choices=["auto", "bash", "zsh", "fish", "both", "all"],
38
49
  default="auto",
39
- help="default: all supported shells found on PATH",
40
- )
41
- s.add_argument("--home", default=str(Path.home()), help="target home (for isolated tests)")
42
- s.add_argument(
43
- "--yes",
44
- action="store_true",
45
- help="apply without asking",
50
+ help="default: every supported shell found on PATH",
46
51
  )
52
+ s.add_argument("--home", default=str(Path.home()), help=argparse.SUPPRESS) # tests
53
+ s.add_argument("--yes", action="store_true", help="apply without asking")
47
54
  s.add_argument("--diff", action="store_true", help="show the exact file changes")
48
- s.add_argument("--dry-run", action="store_true")
49
- sub.add_parser("doctor")
50
- sub.add_parser("config", help="choose segments, theme and thresholds interactively")
51
- sub.add_parser("update", help="upgrade codex-statusline the way it was installed")
52
- p = sub.add_parser("preview")
53
- p.add_argument("--width", type=int, default=120)
54
- p.add_argument("--theme", choices=["auto", "dark", "light"])
55
- p.add_argument("--ascii", action="store_true")
56
- p.add_argument("--tmux", action="store_true", help="emit tmux style syntax, not ANSI")
55
+ s.add_argument("--dry-run", action="store_true", help="show the plan, change nothing")
57
56
  ns = parser.parse_args(args)
58
57
  try:
59
58
  if ns.action in ("install", "uninstall"):
@@ -81,32 +80,6 @@ def main():
81
80
  }
82
81
  print(json.dumps(data, indent=2))
83
82
  return 0 if data["tmux"] and version(path) >= (0, 159, 0) else 1
84
- if ns.action == "preview":
85
- from .render import load_config, render
86
-
87
- cfg = load_config()
88
- now = time.time()
89
- state = {
90
- "context_used": 35,
91
- "tokens": 1_234_567,
92
- "quotas": {
93
- "5h": {"remaining": 78, "reset_at": now + 7200, "observed_at": now},
94
- "weekly": {"remaining": 39, "reset_at": now + 172800, "observed_at": now},
95
- },
96
- }
97
- print(
98
- render(
99
- state,
100
- ns.width,
101
- theme=ns.theme or cfg["theme"],
102
- ascii_only=ns.ascii or cfg["ascii"],
103
- tmux=ns.tmux,
104
- segments=cfg["segments"],
105
- warn_at=cfg["warn_at"],
106
- crit_at=cfg["crit_at"],
107
- )
108
- )
109
- return 0
110
83
  except (OSError, ValueError, RuntimeError, KeyError) as error:
111
84
  print(f"codex-statusline: {error}", file=sys.stderr)
112
85
  return 1
@@ -278,7 +278,7 @@ def render(
278
278
  hint = None
279
279
  if isinstance(update, str) and re.fullmatch(r"\d+(\.\d+)*", update):
280
280
  arrow = "^" if ascii_only else "↑"
281
- hint = (f"{arrow} {update} run: codex-statusline update", f"{arrow}{update}", "warning")
281
+ hint = (f"{arrow} update available: codex-statusline update", f"{arrow} update", "warning")
282
282
  head, rest = parts[0], parts[1:]
283
283
  compact_head = (head[1], head[2])
284
284
  # Widest first: all detail, compact head, all compact, then drop segments.
@@ -42,7 +42,7 @@ class UpdateTests(unittest.TestCase):
42
42
  def test_update_hint_is_dropped_first_when_narrow(self):
43
43
  state = {"context_used": 10, "now": 1000, "update": "0.2.0", "quotas": {}}
44
44
  wide = render(state, 240, tmux=False)
45
- self.assertIn("↑ 0.2.0 run: codex-statusline update", wide)
46
- self.assertIn("^0.2.0", render(state, 240, tmux=False, ascii_only=True).replace(" ", ""))
47
- self.assertNotIn("0.2.0", render(state, 40, tmux=False))
48
- self.assertNotIn("0.2.0", render(dict(state, update="#(evil)"), 240, tmux=False))
45
+ self.assertIn("↑ update available: codex-statusline update", wide)
46
+ self.assertIn("^ update available", render(state, 240, tmux=False, ascii_only=True))
47
+ self.assertNotIn("update", render(state, 40, tmux=False))
48
+ self.assertNotIn("update", render(dict(state, update="#(evil)"), 240, tmux=False))