feat: usage analytics, repo graph, read modes + filter waves 16-32 (514 filters)#35
Conversation
…es, filter wave 16 Pilar A — `tokenix usage`: absolute token spend + ≈USD cost from agent transcripts (daily/weekly/monthly/session/model/project, 5-hour blocks with burn rate, month-end forecast, --cost-mode, --statusline, --json). New src/usage.rs + shared src/transcripts.rs (conversation_audit refactored to reuse it); gain.rs ModelPrice extended with output/cache rates + price_for / usage_cost helpers. Pilar B — `tokenix graph`: repo-wide hotspots (god nodes, bottlenecks, blast-radius leaders) + Graphviz DOT export (graph.rs repo_hotspots / format_repo_report / format_edges_dot). New Usage and Graph dashboard tabs. Pilar C — `tokenix read --mode full|outline|signatures|diff|density:X` (entropy-filtered reads). Filter wave 16: cargo tree, npm ls, kubectl explain, ip, ss, lsof, netstat, systemctl list-* (386 filters, 800 golden cases). Docs: README.md + AGENTS.md updated. Tests: 263 passed, fmt clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vw2xCqT8ozZKw5VtWgWAAn
Adds 128 bundled output filters across 16 thematic waves, each with >=2 embedded golden cases (success/output + clean/failure path) and never-mask guards. 1056 golden cases now run through the real apply_filter pipeline. - k8s: kustomize skaffold argocd flux istioctl kube-score kube-linter helmfile - containers: podman buildah nerdctl dive crane ko docker-scout - IaC: terrascan infracost terraform-docs kics cdktf sam serverless cfn-lint - python: pyupgrade autoflake interrogate radon twine refurb pip-compile pipdeptree - js/ts: dprint xo size-limit attw publint tsup changeset standard - testing: ava tap c8 gotestsum ginkgo hyperfine shellspec wdio - go: go-run go-install goimports gocritic gci goreleaser swag mockgen - rust: cargo-add/publish/fix/machete/outdated/udeps/expand/tarpaulin/llvm-cov - db: dbmate atlas sqlx drizzle-kit knex sequelize migrate pg_dump - security: nuclei kube-bench prowler dependency-check retire scorecard git-secrets ggshield - linters: proselint write-good alex textlint htmlhint jsonlint taplo protolint - build: buck2 pants earthly dagger moon mill scons please - mobile/fe: flutter-build dart-analyze dart-test pod fastlane expo astro gatsby - data/ml: dvc mlflow great-expectations nbconvert spark-submit kafka-topics airflow prefect - infra: vault consul nomad ansible-galaxy rclone restic doctl kubens - misc: osv-scanner typos lychee clj-kondo hugo codespell nox README.md + AGENTS.md counts synced: 514 filters, 1056 golden cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vw2xCqT8ozZKw5VtWgWAAn
There was a problem hiding this comment.
Code Review
This pull request introduces comprehensive token spend analytics and a repo-wide symbol graph overview. It adds a new usage command and TUI tab to parse agent transcripts and calculate absolute token spend and USD costs, utilizing an expanded pricing model in gain.rs. It also adds a graph command and TUI tab to identify hotspots, bottlenecks, and blast-radius leaders across the symbol graph. Additionally, many new output filters were added, and the read command was enhanced with new modes. Feedback was provided on src/usage.rs to prevent potential panics when slicing strings with multi-byte UTF-8 characters, and to avoid timezone/DST resolution issues in floor_hour by using Timelike methods.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| fn short(s: &str) -> String { | ||
| if s.len() > 20 { | ||
| format!("{}…", &s[..19]) | ||
| } else { | ||
| s.to_string() | ||
| } | ||
| } |
There was a problem hiding this comment.
Slicing a string slice by byte index (&s[..19]) can panic if the boundary falls in the middle of a multi-byte UTF-8 character. Since project names or session IDs can contain non-ASCII characters, use a Unicode-aware approach to safely truncate the string.
| fn short(s: &str) -> String { | |
| if s.len() > 20 { | |
| format!("{}…", &s[..19]) | |
| } else { | |
| s.to_string() | |
| } | |
| } | |
| fn short(s: &str) -> String { | |
| if s.chars().count() > 20 { | |
| format!("{}…", s.chars().take(19).collect::<String>()) | |
| } else { | |
| s.to_string() | |
| } | |
| } |
| fn floor_hour(ts: DateTime<Local>) -> DateTime<Local> { | ||
| Local | ||
| .with_ymd_and_hms(ts.year(), ts.month(), ts.day(), ts.hour(), 0, 0) | ||
| .single() | ||
| .unwrap_or(ts) | ||
| } |
There was a problem hiding this comment.
Using Local.with_ymd_and_hms can return None or Ambiguous during Daylight Saving Time (DST) transitions (e.g., when the clock rolls back), causing the function to fall back to the unfloored timestamp. Using Timelike methods (with_minute, with_second, with_nanosecond) is safer and avoids timezone/DST resolution issues entirely.
| fn floor_hour(ts: DateTime<Local>) -> DateTime<Local> { | |
| Local | |
| .with_ymd_and_hms(ts.year(), ts.month(), ts.day(), ts.hour(), 0, 0) | |
| .single() | |
| .unwrap_or(ts) | |
| } | |
| fn floor_hour(ts: DateTime<Local>) -> DateTime<Local> { | |
| ts.with_minute(0) | |
| .and_then(|t| t.with_second(0)) | |
| .and_then(|t| t.with_nanosecond(0)) | |
| .unwrap_or(ts) | |
| } |
3d052b6 to
3cd8779
Compare
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
|
Este PR tem conflitos de merge que não puderam ser resolvidos automaticamente. Por favor, resolva manualmente. |
|
✅ Conflitos de Merge Resolvidos Oi @juninmd! Os conflitos de merge do PR #35 foram resolvidos automaticamente. Resumo: Resolved 3 conflict(s) and pushed 🤖 Origem Automatizada
|
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
|
⏳ Aguardando pipeline O pipeline de CI/CD está com estado |
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <gemini-code-assist[bot]@users.noreply.github.com>
|



Summary
Bundles two areas of work on this branch:
ea72f6a, wave 16 filters).3cd8779): 128 new output filters (394 -> 514), each with >=2 embedded golden cases and never-mask-failure guards. 1056 golden cases now run through the realapply_filterpipeline.New filter coverage (waves 17-32)
Verification
cargo test filters::-> 41 passed, 1 ignored, 0 failed (golden, never-mask, no-inflate, >=70% economy, command-variant resolution).Output formats researched against upstream docs for accuracy.
🤖 Generated with Claude Code