Skip to content

feat(cli): redesign context-stats with action-based interface (#50)#52

Merged
luongnv89 merged 3 commits intomainfrom
feat/50-redesign-context-stats-cli-action-based
Apr 6, 2026
Merged

feat(cli): redesign context-stats with action-based interface (#50)#52
luongnv89 merged 3 commits intomainfrom
feat/50-redesign-context-stats-cli-action-based

Conversation

@luongnv89
Copy link
Copy Markdown
Owner

@luongnv89 luongnv89 commented Apr 6, 2026

Closes #50

Summary

Implements a strict, explicit action-based CLI interface for context-stats. The design enforces a clean, predictable pattern: users must always specify both the session ID and the action, with no hidden defaults or convenience shortcuts.

Pattern

context-stats <session_id> <action> [parameters]

The only exception is the explain action, which reads JSON from stdin and doesn't require a real session file, so it can be called as:

echo '{}' | context-stats explain

Approach

  • Strict argument parsing: both session_id and action are required positional arguments
  • Session ID validation prevents path traversal and injection attacks
  • Clean separation of action-specific logic
  • Explain action as special case for piped input

Changes

File Change
src/claude_statusline/cli/context_stats.py Strict session-first action-based parsing
tests/python/test_export.py Updated to use new required pattern
tests/python/test_state_rotation_validation.py Updated to use new required pattern

Test Results

  • All 317 Python tests pass
  • All 84 Node.js tests pass
  • Argument parsing validated for strict pattern
  • Session ID validation working correctly

Supported Usage

# Show live graphs
context-stats abc123def graph

# Show graphs once and exit
context-stats abc123def graph --no-watch

# Show only cumulative graph
context-stats abc123def graph --type cumulative

# Export session stats
context-stats abc123def export --output report.md

# Diagnostic dump (special case - no session needed)
echo '{"model":...}' | context-stats explain

Acceptance Criteria

  • Implement strict <session_id> <action> [parameters] pattern
  • Support three actions: graph, export, explain
  • Require both session ID and action for all operations
  • Allow explain exception for stdin piping
  • Validate session IDs to prevent injection
  • All tests pass

Implement an intuitive action-based CLI pattern that makes it easier to work
with sessions and perform common operations without cluttering the root command.

New CLI structure:
  context-stats [session_id] [action] [options]
  context-stats [action] [session_id] [options]

Supported actions:
- graph: Show live ASCII graphs of context usage (default)
- export: Export session stats as a markdown report
- explain: Diagnostic dump of Claude Code's JSON context (pipe JSON to stdin)

The implementation supports flexible argument ordering, allowing users to invoke
commands in the most natural way for their workflow:
  context-stats                  # Latest session, graph action
  context-stats session123       # Specific session, graph action
  context-stats graph            # Default behavior
  context-stats export           # Latest session, export action
  context-stats export session123 --output report.md
  context-stats session123 export --output report.md

Changes:
- Add action-based argument parsing via _normalize_argv() to distinguish
  actions from session IDs and support multiple calling patterns
- Create _build_graph_parser() for clean separation of graph action parsing
- Refactor parse_args() to route to appropriate action handler
- Enhance help text with action descriptions, options grouping, and examples
- Fix session_id injection for export/explain actions to avoid duplication
- Maintain backward compatibility: omitting action defaults to graph

All 317 Python tests pass, verifying argument parsing, validation, and behavior.
Remove support for action-first pattern (context-stats export ...) to keep
the implementation clean and simple. The interface now only supports:

  context-stats [session_id] [action] [options]
  context-stats [action] [options]   (for export, explain without session)
  context-stats [options]            (default to latest session, graph)

This maintains backward compatibility for common use cases while removing
unnecessary complexity from argument parsing.
Remove all convenience patterns and enforce absolute required pattern:
  context-stats <session_id> <action> [parameters]

Special case: explain can be called as 'context-stats explain' when piping
JSON from stdin, using '-' as internal placeholder for session_id.

This keeps the CLI interface clean, simple, and explicit - no hidden defaults
or auto-detection. Users must always specify both session ID and action.

Changes:
- Update _normalize_argv() to require both positional arguments
- Allow explain action as special case (reads from stdin, no session file needed)
- Validate session_id format to prevent path traversal/injection
- Update test suite to use new required pattern
- Update help text and examples to show strict pattern
@luongnv89 luongnv89 merged commit 661c685 into main Apr 6, 2026
47 of 50 checks passed
@luongnv89 luongnv89 deleted the feat/50-redesign-context-stats-cli-action-based branch April 6, 2026 21:09
luongnv89 added a commit that referenced this pull request Apr 6, 2026
- Change 'context-stats export <session_id>' to 'context-stats <session_id> export'
- Update both the usage example and the example output section
- Reflects the strict <session_id> <action> pattern from PR #52
luongnv89 added a commit that referenced this pull request Apr 6, 2026
- Update context-stats-cache-misses.md export command
- Update context-stats-export-output.md export command
- Update docs/context-stats.md with comprehensive CLI reference
- Update INSTALLATION_FIX.md with correct command syntax
- All examples now use strict <session_id> <action> pattern from PR #52

The strict pattern is:
  context-stats <session_id> <action> [parameters]

Common examples:
  context-stats <session_id> graph
  context-stats <session_id> export --output report.md
  echo '{}' | context-stats explain
luongnv89 added a commit that referenced this pull request Apr 6, 2026
) (#53)

* docs(readme): update export command to use correct CLI pattern

- Change 'context-stats export <session_id>' to 'context-stats <session_id> export'
- Update both the usage example and the example output section
- Reflects the strict <session_id> <action> pattern from PR #52

* docs: update all export command examples to use correct CLI pattern

- Update context-stats-cache-misses.md export command
- Update context-stats-export-output.md export command
- Update docs/context-stats.md with comprehensive CLI reference
- Update INSTALLATION_FIX.md with correct command syntax
- All examples now use strict <session_id> <action> pattern from PR #52

The strict pattern is:
  context-stats <session_id> <action> [parameters]

Common examples:
  context-stats <session_id> graph
  context-stats <session_id> export --output report.md
  echo '{}' | context-stats explain

* docs(context-stats): fix all command examples to use strict action-based pattern

- Update all Usage section examples to include session_id and action
- Fix Graph Types examples with correct <session_id> graph pattern
- Remove old --no-color example from explain action
- Update diagnostic dump to explain action (not command)
- Fix watch mode disable example
- Update watch mode section text to reflect new pattern

All examples now follow the strict pattern:
  context-stats <session_id> <action> [parameters]

* feat(testing): add clean E2E install smoke tests to pre-commit hook (#51)

Add scripts/e2e-install-test.sh that performs clean-install validation for all
three runtime implementations (Node.js, Python, Bash) and register it as a
local pre-commit hook. Each runtime test starts from a fresh state, asserts
all expected entry points exist, and verifies basic invocations exit 0 with
non-empty output. Failures report the exact failing command with a human-
readable summary.

* fix(lint): resolve ShellCheck warnings in e2e-install-test.sh

Remove unused YELLOW color variable (SC2034), remove dead pip_bin
variable that was never used (venv_pip used instead), and quote
exit_code comparisons to prevent word splitting (SC2086).

* fix(e2e): fix eval injection, dead tmpdir, set-e abort, npm pack fragility

- Replace eval in assert_statusline_ok with positional-arg pattern
  (same as assert_cmd_ok) to eliminate shell injection risk from paths
- Remove dead tmpdir block and duplicate trap in run_nodejs_e2e; the
  copied files were never used and the second trap silently overwrote
  the first, leaking $tmpdir on exit
- Remove explicit return 0/return 1 from helpers so they always return 0
  under set -euo pipefail — failures are recorded via fail() and the
  script continues accumulating counts rather than aborting early
- Use tail -1 on npm pack output to handle npm v7+ multi-line stdout

* fix(e2e): guard npm pack and npm install against set -e abort

Under set -euo pipefail, a failed command substitution or bare subshell
call aborts the script immediately before the error-recording guard fires.

- Append '|| true' to npm pack assignment so the empty-string check on
  the next line can fire and emit fail() on npm pack failure
- Use '&& npm_exit=0 || npm_exit=$?' pattern for npm install subshell so
  the failure is recorded via fail() rather than aborting the script

Also quote $npm_exit in comparison to satisfy ShellCheck SC2086.

* fix(tests): update fake python3 version in bats test to match script VERSION

The fake python3 stub returned 1.15.0 but context-stats.sh VERSION is
1.15.1, causing the version-mismatch guard to reject the call and exit 1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redesign context-stats CLI with action-based interface

1 participant