build(ccusage): use nix for unix native fallback#1318
Conversation
Switch ensure-native-binary to build Unix fallback binaries through the flake instead of invoking cargo directly. Linux now uses the static package, Darwin x64 uses the dedicated cross package, and Darwin arm64 uses the native ccusage package. Keep the Windows fallback on cargo build because the flake does not provide Windows native package builds. Add a focused Nushell test for the platform-to-flake mapping and wire it into the root test aggregate.
|
@coderabbitai review |
@ryoppippi I have started the AI code review. It will take a few minutes to complete. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough
ChangesNix-based native binary build flow
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | 7ec0d06 | Commit Preview URL Branch Preview URL |
Jun 14 2026, 08:20 PM |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get PR details
gh pr view 1318 --repo ccusage/ccusage --json title,body,files,additions,deletions,commits
echo "=== PR Files Changed ==="
gh pr diff 1318 --repo ccusage/ccusageLength of output: 8891
Review:
|
In Nushell, calling `last` on an empty list raises a runtime error rather than returning null, so the `if $out_path == null` guard was unreachable. Check the filtered line list with `is-empty` before calling `last` so the missing-output-path branch can actually fire. Also swap `run-external nix build` for `^nix build` to match the `^cargo`, `^ldd`, `^otool` style used elsewhere in this script. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
ccusage
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-darwin-x64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-x64
commit: |
Rename the Cargo fallback path parameter from binary_name to executable_name so it is clear that the value is the platform-specific output filename, not the Cargo bin target. The Cargo target remains ccusage because Windows output is ccusage.exe while the Cargo bin name does not include the executable suffix.
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
Remove the non-Unix Cargo fallback from ensure-native-binary so the script always resolves a configured Nix package before building. Unsupported platforms now fail with the existing missing Nix package error instead of invoking Cargo. CI builds Windows native packages through the dedicated Windows action, not through this package prepack script.
|
@coderabbitai @cubic-dev-ai Updated the branch after review. The unreachable output-path guard and ^nix style were already addressed in 7f7406f. For the Cargo fallback note: this prepack script should not handle Windows at all, so 9749292 removes the Cargo fallback instead of changing the Cargo target name. Validation: direnv exec . just fmt; direnv exec . just test-nu-scripts; direnv exec . fish -c "cd apps/ccusage && scripts/ensure-native-binary.nu"; git diff --check. |
@ryoppippi The three points from the earlier review are all handled now:
The diff looks clean and the validation commands you ran ( Tip: get faster answers by chatting with cubic’s review copilot in the review UI |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get the latest diff to verify the addressed issues
gh pr diff 1318 --repo ccusage/ccusageLength of output: 5915
|
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/ccusage/scripts/ensure-native-binary.nu (1)
26-36:⚠️ Potential issue | 🟠 Major | ⚡ Quick winCopy the validated Nix output into the native package before exiting.
build_nix_binaryreturns a Nix store path, but this branch only validates that path and then ends.$native_package_root/bin/$binary_nameis never created or updated, so a supported Unix target with no preexisting package binary still leaves the package payload empty. Fail early when$native_package_rootisnull, then stage$built_binaryinto$native_binary.Proposed fix
if not (is_portable_binary $target_platform $built_binary) { error make { msg: $"($built_binary) depends on dynamic libraries that do not exist on end-user machines; rebuild it \(Linux packages must be static, macOS packages may only link system dylibs)" } } + if $native_package_root == null { + error make { + msg: $"No native package directory matches ($target_platform)-($target_arch)" + } + } + mkdir ($native_package_root | path join bin) + cp --force $built_binary $native_binary }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/ccusage/scripts/ensure-native-binary.nu` around lines 26 - 36, After the validation checks for the built binary in the build_nix_binary function block (specifically after the is_portable_binary check), add logic to fail early if $native_package_root is null, then copy the validated $built_binary to $native_package_root/bin/$binary_name to actually stage the binary into the native package directory. Currently the code validates the built binary but never copies it to the destination, leaving the package payload empty.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@apps/ccusage/scripts/ensure-native-binary.nu`:
- Around line 26-36: After the validation checks for the built binary in the
build_nix_binary function block (specifically after the is_portable_binary
check), add logic to fail early if $native_package_root is null, then copy the
validated $built_binary to $native_package_root/bin/$binary_name to actually
stage the binary into the native package directory. Currently the code validates
the built binary but never copies it to the destination, leaving the package
payload empty.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7fe3e4cb-2b40-473c-891e-c86e168d1aff
📒 Files selected for processing (1)
apps/ccusage/scripts/ensure-native-binary.nu
Copy the validated Nix build output into the matching native package directory when ensure-native-binary has to build a missing or stale Unix native binary. The package bin directories are ignored generated artifacts, so this preserves clean source control while ensuring local prepack fallback builds produce a package payload.
|
@coderabbitai @cubic-dev-ai Addressed the remaining staging feedback in 7ec0d06 by copying the validated Nix fallback output into the matching native package bin directory. Validation: direnv exec . just fmt; direnv exec . just test-nu-scripts; direnv exec . fish -c "cd apps/ccusage && scripts/ensure-native-binary.nu"; git diff --check. |
@ryoppippi The staging feedback is handled in 7ec0d06. The three new lines you added after the validation checks are exactly right:
This means the package directory will have a real binary even when Tip: get faster answers by chatting with cubic’s review copilot in the review UI |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get the latest diff to verify the addressed issues
gh pr diff 1318 --repo ccusage/ccusage
echo "=== Commit 7ec0d06b details ==="
gh api repos/ccusage/ccusage/commits/7ec0d06bLength of output: 12423
The staging step comes after both the version check and the portability check, so only binaries that have passed all validation gates are written into the package payload. Nothing left to flag here. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact sizeLower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |


Switches the ccusage native-binary fallback to Nix-backed package builds.
Linux now builds the static flake package, macOS x64 uses the dedicated Darwin x64 package, and macOS arm64 uses the native ccusage package. Unsupported platforms fail when no Nix package mapping exists; Windows native packages are built by the dedicated CI action instead of this prepack script.
Testing:
Summary by CodeRabbit