Repository navigation
fix(nix): stabilise crane dependency cache - #1243
Conversation
Build dependency artifacts no longer inherit the LiteLLM pricing JSON path, which changes when the pinned pricing input is updated even though Cargo dependencies remain the same. Use a stable deps-only package version so release version bumps do not force a fresh dependency artifact. Reuse those deps-only arguments for static Linux builds to keep the caching behaviour consistent across package variants.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughSplit dependency-only crate build args: ChangesNix build dependency isolation via depsOnlyArgs
Dev flake, dev-shell and CI wiring
Sequence Diagram(s)Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 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)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | 6157464 | Commit Preview URL Branch Preview URL |
Jun 10 2026, 11:18 AM |
Document why the dependency-only crane arguments exclude pricing inputs and use a stable version. The comments keep the cache-key split understandable without changing build behaviour.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — Stabilises crane Rust dependency caching by excluding pricing file path and release version from deps-only build args.
package.nix— CreatesdepsOnlyArgsthat stripsCCUSAGE_PRICING_JSON_PATHand pinsversionto0.0.0so Rust deps aren't rebuilt on pricing or version bumps. ExposesdepsOnlyArgsviapassthrufor reuse.nix/static-package.nix— DerivesstaticDepsOnlyArgsfrom the shareddepsOnlyArgscache key with static-target overlays, keeping dep caching consistent across build variants.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
🧹 Nitpick comments (1)
nix/static-package.nix (1)
44-44: ⚡ Quick winClarify comment: "share" may mislead about cross-target caching.
The comment states "Share the same deps-only cache key" but adding
--target ${linuxStaticTarget}incargoExtraArgscreates a distinct cache artifact per target (e.g.,x86_64-unknown-linux-muslvsaarch64-unknown-linux-muslvs native). The intended benefit is that within each target, the cache remains stable (unaffected by pricing JSON or version bumps), not that the main package and static package share one cache.Consider rewording to clarify the stability goal rather than implying cross-target sharing:
-# Share the same deps-only cache key, then add static target settings. +# Reuse the stable deps-only base (excludes pricing, pins version), then add static target settings.🤖 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 `@nix/static-package.nix` at line 44, Update the inline comment that currently reads "Share the same deps-only cache key" to make it clear that adding `--target ${linuxStaticTarget}` in `cargoExtraArgs` creates a separate cache per target, and that the intent is to keep the deps-only cache stable within each specific target (so it isn't invalidated by unrelated changes like pricing JSON or version bumps), not to imply a single shared cache across different targets; reference the `cargoExtraArgs` and `${linuxStaticTarget}` symbols and rephrase to state the stability-per-target goal.
🤖 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.
Nitpick comments:
In `@nix/static-package.nix`:
- Line 44: Update the inline comment that currently reads "Share the same
deps-only cache key" to make it clear that adding `--target
${linuxStaticTarget}` in `cargoExtraArgs` creates a separate cache per target,
and that the intent is to keep the deps-only cache stable within each specific
target (so it isn't invalidated by unrelated changes like pricing JSON or
version bumps), not to imply a single shared cache across different targets;
reference the `cargoExtraArgs` and `${linuxStaticTarget}` symbols and rephrase
to state the stability-per-target goal.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ced9344a-9c41-4ced-9e89-871618a001ae
📒 Files selected for processing (2)
nix/static-package.nixpackage.nix
🚧 Files skipped from review as they are similar to previous changes (1)
- package.nix
ccusage
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-darwin-x64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-arm64
@ccusage/ccusage-win32-x64
commit: |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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. |
Move development-only Nix modules into dev/flake.nix so root package builds no longer carry treefmt, git-hooks, and agent-skills inputs. Switch setup-nix to nix-quick-install-action, split package and development cache scopes, and stop warming the dev shell by default. Add just tasks for frozen pnpm installs and large fixture generation so CI workflows call shared recipes instead of repeating command lines.
nix-quick-install-action installs Nix in single-user mode, while the restored Nix store cache can contain root-owned paths. Chown the restored store on Linux before running nix build so Nix can create store locks.
The single-user Nix install also writes build logs under /nix/var/log/nix. Include that directory in the ownership fix after restoring the Nix store cache.
CI Fix:
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — Moved development tooling into a separate dev/ flake to keep the main flake lean and split CI caching into package vs dev profiles.
dev/flake.nix+dev/flake.lock— New development flake that owns treefmt, git-hooks, agent-skills, and the dev shell, delegating package inputs to the main flake viafollows.flake.nix— Stripped dev-only inputs (agent-skills,git-hooks,treefmt-nix) and their imports, keeping only package/check logic with atouchupformatter disable..github/actions/setup-nix/action.yaml— Split intopackageanddevcache profiles, switched tonixbuild/nix-quick-install-action, made dev-shell warm-up conditional.- CI workflows — Updated all
nix developcalls tonix develop ./dev#ci, added explicitjust installsteps, and setcache-profile: devfor development jobs. nix/dev-shell.nix— Extracted package list intodevShellPackages, addeddevShells.ci(same tools, no shellHook).justfile— Addedinstallandgenerate-large-fixturerecipes, updatedfmt/check/schemato target the dev flake.- Nix modules (
agent-skills.nix,checks.nix,treefmt.nix) — Switched frominputs.selfto hardcodedroot = ./..for nix-filter and treefmt project root, keeping them correct when imported from the dev flake.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — Added a chown step to fix Nix store ownership after cache restoration with the quick installer.
.github/actions/setup-nix/action.yaml— AddedFix single-user Nix store ownershipstep that runssudo chown -R "$USER:$(id -gn)" /nix/store /nix/var/log/nix /nix/var/nixon Linux, fixing permission errors fromnixbuild/nix-quick-install-actionrestoring stores with wrong ownership.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
Use the Nix package build for the macOS arm64 native package in CI, matching the Linux Nix path while keeping Cargo builds for the remaining non-Nix platforms. Make the single-user Nix ownership fix portable across non-Windows runners so macOS Nix cache restores can use the same setup action.
Use the Nix package build for both macOS native package targets in CI and release workflows, leaving Cargo builds only for Windows.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.github/workflows/release.yaml (1)
100-100:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd
cache-profile: devfor consistency.The
npmjob usesnix develop ./dev#cicommands (lines 115-116) but does not specifycache-profile: dev. Jobs executing via./dev#cishould use the development cache scope to ensure consistent cache behavior and avoid misses.⚡ Proposed fix
- uses: ./.github/actions/setup-nix + with: + cache-profile: dev🤖 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 @.github/workflows/release.yaml at line 100, The workflow step that currently uses the local action "uses: ./.github/actions/setup-nix" should include the cache scope so the Nix dev environment lines that run "nix develop ./dev#ci" use the development cache; update that step to add the key "cache-profile: dev" alongside the existing keys for the setup action so jobs invoking "nix develop ./dev#ci" benefit from the dev cache profile..github/workflows/ci.yaml (1)
184-184:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd
cache-profile: devfor consistency.The
npm-publish-dry-run-and-upload-pkg-pr-nowjob usesnix develop ./dev#cicommands (lines 195, 197) but does not specifycache-profile: dev. All other jobs executing via./dev#cisetcache-profile: devto hit the development cache scope. This mismatch may cause cache misses and longer setup times.⚡ Proposed fix
- uses: ./.github/actions/setup-nix + with: + cache-profile: dev🤖 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 @.github/workflows/ci.yaml at line 184, In the npm-publish-dry-run-and-upload-pkg-pr-now job, update the setup step that uses ./.github/actions/setup-nix to include cache-profile: dev so it matches other jobs using ./dev#ci; locate the step with the uses: ./.github/actions/setup-nix reference in that job and add the cache-profile: dev input to ensure the Nix setup uses the development cache scope.
🧹 Nitpick comments (3)
.github/actions/setup-nix/action.yaml (2)
20-44: ⚡ Quick winConsider validating
cache-profileinput values.The two cache steps are mutually exclusive and only handle
'package'or'dev'values. If a caller passes an invalid value (e.g., typo like'packge'), both steps silently skip and no caching occurs, which could degrade CI performance without obvious failure.🛡️ Add a validation step
+ - name: Validate cache-profile input + if: inputs.cache-profile != 'package' && inputs.cache-profile != 'dev' + shell: bash + run: | + echo "::error::Invalid cache-profile '${{ inputs.cache-profile }}'. Must be 'package' or 'dev'." + exit 1 + - name: Cache Nix store for package builds🤖 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 @.github/actions/setup-nix/action.yaml around lines 20 - 44, Add an explicit validation step for the inputs.cache-profile value so typos don't silently disable caching: create a new job step named like "Validate cache-profile input" that runs early and checks inputs.cache-profile is either "package" or "dev" (or set a default), and fail or warn with a clear error if it's invalid; update the workflow to reference inputs.cache-profile in that check and keep the existing steps "Cache Nix store for package builds" and "Cache Nix store for development jobs" unchanged.
46-49: Confirmwarm-dev-shellusage (step is currently unused in this repo)
warm-dev-shellis only defined in.github/actions/setup-nix/action.yamland referenced in the step guard (if: inputs.warm-dev-shell == 'true'); there are no other workflow/action call sites in this repository that setwarm-dev-shell(e.g.,warm-dev-shell: true). As a result, the “Load Nix CI development environment” step never runs for current in-repo workflows.If this action is intended to be used only within this repo, consider removing the warmup input/step; otherwise, document it as an optional behavior for external callers.
🤖 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 @.github/actions/setup-nix/action.yaml around lines 46 - 49, The action defines an unused input warm-dev-shell and guards the "Load Nix CI development environment" step with if: inputs.warm-dev-shell == 'true' so that step never runs in-repo; either remove the warm-dev-shell input and delete the guarded step ("Load Nix CI development environment") to simplify the action, or keep the input but add clear documentation and examples showing how external callers can set warm-dev-shell: true (and update action metadata/README to document optional behavior), ensuring the guarded run line and the inputs section (warm-dev-shell) remain consistent with the chosen approach.dev/flake.nix (1)
39-47: No package-attribute collision:ccusageinput is only used for input pinning; dev packages come from../nix/packages.nix.
dev/flake.niximports../nix/packages.nix, which defines the dev flake’spackages(includingccusageandmodels-dev-pricing). Theccusageflake input is not referenced by the dev modules (nix/dev-shell.nix,nix/treefmt.nix,nix/checks.nix,nix/agent-skills.nix,nix/git-hooks.nix)—they readconfig.packages.ccusage.*from the imported module—so there’s no attribute collision/override withinputs.ccusage.*. The overlap is only that both the root flake and the dev flake expose similarly named packages (ccusage), defined independently by the samenix/packages.nixmodule.🤖 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 `@dev/flake.nix` around lines 39 - 47, The reviewer is worried about a package-attribute collision between inputs.ccusage and the dev flake's packages; fix this by either removing the unused top-level flake input (inputs.ccusage) if it's only kept for pinning, or add an explicit comment inside dev/flake.nix next to the imports array explaining that ../nix/packages.nix defines packages (including ccusage and models-dev-pricing) and that dev modules (nix/dev-shell.nix, nix/treefmt.nix, nix/checks.nix, nix/agent-skills.nix, nix/git-hooks.nix) read config.packages.ccusage.* from that module so inputs.ccusage is not used to provide dev packages; reference the imports list and the ../nix/packages.nix module when making the change.
🤖 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.
Inline comments:
In @.github/workflows/release.yaml:
- Around line 46-47: The build-native-packages job is incorrectly using the dev
cache profile; remove the "cache-profile: dev" setting (or change it to the
package/default cache scope) in the build-native-packages job so package builds
like the `nix build .#ccusage-static` step use the package cache rather than the
dev cache used by `./dev#ci` workflows; update the workflow so its cache
configuration matches the package-oriented job in ci.yaml.
In `@flake.nix`:
- Around line 34-40: The flake currently imports
inputs.flake-parts.flakeModules.touchup but only sets
touchup.attr.formatter.enable = false; either remove the touchup module import
or document why it must remain; to fix, search for
inputs.flake-parts.flakeModules.touchup and the touchup.attr.formatter.enable
assignment in flake.nix, and if no other touchup features are used remove the
module from the inputs and module list, otherwise add a concise comment above
touchup.attr.formatter.enable explaining why the module is required even though
only the formatter is disabled (e.g., to retain other default attributes or
compatibility).
---
Outside diff comments:
In @.github/workflows/ci.yaml:
- Line 184: In the npm-publish-dry-run-and-upload-pkg-pr-now job, update the
setup step that uses ./.github/actions/setup-nix to include cache-profile: dev
so it matches other jobs using ./dev#ci; locate the step with the uses:
./.github/actions/setup-nix reference in that job and add the cache-profile: dev
input to ensure the Nix setup uses the development cache scope.
In @.github/workflows/release.yaml:
- Line 100: The workflow step that currently uses the local action "uses:
./.github/actions/setup-nix" should include the cache scope so the Nix dev
environment lines that run "nix develop ./dev#ci" use the development cache;
update that step to add the key "cache-profile: dev" alongside the existing keys
for the setup action so jobs invoking "nix develop ./dev#ci" benefit from the
dev cache profile.
---
Nitpick comments:
In @.github/actions/setup-nix/action.yaml:
- Around line 20-44: Add an explicit validation step for the
inputs.cache-profile value so typos don't silently disable caching: create a new
job step named like "Validate cache-profile input" that runs early and checks
inputs.cache-profile is either "package" or "dev" (or set a default), and fail
or warn with a clear error if it's invalid; update the workflow to reference
inputs.cache-profile in that check and keep the existing steps "Cache Nix store
for package builds" and "Cache Nix store for development jobs" unchanged.
- Around line 46-49: The action defines an unused input warm-dev-shell and
guards the "Load Nix CI development environment" step with if:
inputs.warm-dev-shell == 'true' so that step never runs in-repo; either remove
the warm-dev-shell input and delete the guarded step ("Load Nix CI development
environment") to simplify the action, or keep the input but add clear
documentation and examples showing how external callers can set warm-dev-shell:
true (and update action metadata/README to document optional behavior), ensuring
the guarded run line and the inputs section (warm-dev-shell) remain consistent
with the chosen approach.
In `@dev/flake.nix`:
- Around line 39-47: The reviewer is worried about a package-attribute collision
between inputs.ccusage and the dev flake's packages; fix this by either removing
the unused top-level flake input (inputs.ccusage) if it's only kept for pinning,
or add an explicit comment inside dev/flake.nix next to the imports array
explaining that ../nix/packages.nix defines packages (including ccusage and
models-dev-pricing) and that dev modules (nix/dev-shell.nix, nix/treefmt.nix,
nix/checks.nix, nix/agent-skills.nix, nix/git-hooks.nix) read
config.packages.ccusage.* from that module so inputs.ccusage is not used to
provide dev packages; reference the imports list and the ../nix/packages.nix
module when making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4381962c-c5b7-4475-8396-6f5a1799d0e5
⛔ Files ignored due to path filters (2)
dev/flake.lockis excluded by!**/*.lockflake.lockis excluded by!**/*.lock
📒 Files selected for processing (12)
.envrc.github/actions/setup-nix/action.yaml.github/workflows/ci.yaml.github/workflows/release.yaml.github/workflows/update-pricing.yamldev/flake.nixflake.nixjustfilenix/agent-skills.nixnix/checks.nixnix/dev-shell.nixnix/treefmt.nix
| inputs.flake-parts.flakeModules.touchup | ||
| ./nix/packages.nix | ||
| ./nix/static-package.nix | ||
| ./nix/checks.nix | ||
| ./nix/dev-shell.nix | ||
| ]; | ||
|
|
||
| touchup.attr.formatter.enable = false; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Search for touchup references in Nix modules
rg -n 'touchup' --type nix nix/Repository: ryoppippi/ccusage
Length of output: 43
Clarify why touchup is imported only to disable its formatter
flake.nix imports inputs.flake-parts.flakeModules.touchup and then disables only touchup.attr.formatter.enable; if there’s no other touchup functionality relied on, consider removing the module import (or add a brief comment explaining why it must stay). Also, the nix/ directory contains no other touchup references.
🤖 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 `@flake.nix` around lines 34 - 40, The flake currently imports
inputs.flake-parts.flakeModules.touchup but only sets
touchup.attr.formatter.enable = false; either remove the touchup module import
or document why it must remain; to fix, search for
inputs.flake-parts.flakeModules.touchup and the touchup.attr.formatter.enable
assignment in flake.nix, and if no other touchup features are used remove the
module from the inputs and module list, otherwise add a concise comment above
touchup.attr.formatter.enable explaining why the module is required even though
only the formatter is disabled (e.g., to retain other default attributes or
compatibility).
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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.
✅ No new issues found.
Reviewed changes — Fixed a Nix store ownership issue, switched macOS native binary builds from Cargo to Nix for both arm64 and x64, and added a windows-11-arm matrix entry.
-
Fixed
chownto skip/nix/store— Removes/nix/storefrom the ownership fix loop insetup-nix/action.yaml, leaving only/nix/var/log/nixand/nix/var/nix. Prevents Nix daemon lock permission errors from chowning store paths that must remain root-owned. -
Switched macOS builds to Nix — Both
ci.yamlandrelease.yamlnow build Darwin binaries withnix build .#ccusage(binary pathresult/bin/ccusage) instead ofcargo build. The Cargo path is now exclusive to Windows. -
Simplified platform conditionals — Changed conditions from
matrix.platform == 'linux' || (matrix.platform == 'darwin' && matrix.arch == 'arm64')/!= 'linux' && !(darwin && arm64)to straightforward!= 'win32'/== 'win32'. More readable and less error-prone. -
Added
windows-11-armto build matrix — New native build entry uses Cargo (no Nix on Windows) withbinary: rust/target/release/ccusage.exe. -
Updated
release.yamlnpm and release jobs — Switched tonix develop ./dev#ciwithjust installfor consistency, and addedcache-profile: devto the release job's Nix setup.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
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 (2)
.github/workflows/ci.yaml (1)
187-187:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd
cache-profile: devto align cache scope with dev shell usage.This job runs
nix develop ./dev#cicommands (lines 198, 200), so it should use thedevcache profile. Using the defaultpackagecache pollutes the package cache with development dependencies and prevents cache rotation when dev tooling changes.For consistency, all other jobs that execute
./dev#cicommands (lint-check, test, ccusage-perf-comment, ccusage-rust-perf-comment) already setcache-profile: dev.🔧 Proposed fix
- uses: ./.github/actions/setup-nix + with: + cache-profile: dev - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1🤖 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 @.github/workflows/ci.yaml at line 187, The setup-nix action invocation (uses: ./.github/actions/setup-nix) is missing the cache-profile setting; update that action call to include cache-profile: dev so the job uses the dev cache profile (matching other jobs that run nix develop ./dev#ci) to avoid polluting the package cache and ensure proper cache rotation..github/workflows/release.yaml (1)
101-101:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd
cache-profile: devto align cache scope with dev shell usage.This job runs
nix develop ./dev#cicommands (lines 116, 117), so it should use thedevcache profile. Using the defaultpackagecache pollutes the package cache with development dependencies and prevents cache rotation when dev tooling changes.For consistency, the
releasejob (line 131) already setscache-profile: devwhen executing./dev#cicommands.🔧 Proposed fix
- uses: ./.github/actions/setup-nix + with: + cache-profile: dev - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0🤖 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 @.github/workflows/release.yaml at line 101, The step that invokes the custom action "uses: ./.github/actions/setup-nix" must include "cache-profile: dev" so the Nix cache scope matches the dev shell usage (the job runs "nix develop ./dev#ci"); update the step configuration for the setup-nix action to add cache-profile: dev (matching the existing pattern used in the release job) to avoid polluting the package cache with development dependencies.
🤖 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 @.github/workflows/ci.yaml:
- Line 187: The setup-nix action invocation (uses: ./.github/actions/setup-nix)
is missing the cache-profile setting; update that action call to include
cache-profile: dev so the job uses the dev cache profile (matching other jobs
that run nix develop ./dev#ci) to avoid polluting the package cache and ensure
proper cache rotation.
In @.github/workflows/release.yaml:
- Line 101: The step that invokes the custom action "uses:
./.github/actions/setup-nix" must include "cache-profile: dev" so the Nix cache
scope matches the dev shell usage (the job runs "nix develop ./dev#ci"); update
the step configuration for the setup-nix action to add cache-profile: dev
(matching the existing pattern used in the release job) to avoid polluting the
package cache with development dependencies.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 56608743-a833-4748-ac15-d80b43221f69
📒 Files selected for processing (3)
.github/actions/setup-nix/action.yaml.github/workflows/ci.yaml.github/workflows/release.yaml
Add a just flake-check recipe that runs both the root package flake and the development tooling flake. Use it from lint-check so the workflow has one explicit check command while preserving the split flake responsibilities. Make just typecheck depend on the frozen pnpm install so local and CI typechecks both install workspace dependencies first.
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/ci.yaml">
<violation number="1" location=".github/workflows/ci.yaml:33">
P3: Missing `--print-build-logs` on flake check commands. The original CI used this flag to surface build output during evaluation; without it, CI build failures are harder to debug.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| - run: nix develop --command just typecheck | ||
| with: | ||
| cache-profile: dev | ||
| - run: nix develop ./dev#ci --command just flake-check |
There was a problem hiding this comment.
P3: Missing --print-build-logs on flake check commands. The original CI used this flag to surface build output during evaluation; without it, CI build failures are harder to debug.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/ci.yaml, line 33:
<comment>Missing `--print-build-logs` on flake check commands. The original CI used this flag to surface build output during evaluation; without it, CI build failures are harder to debug.</comment>
<file context>
@@ -30,9 +30,7 @@ jobs:
- - run: nix flake check --print-build-logs
- - run: nix flake check ./dev --print-build-logs
- - run: nix develop ./dev#ci --command just install
+ - run: nix develop ./dev#ci --command just flake-check
- run: nix develop ./dev#ci --command just typecheck
</file context>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — Consolidated CI flake checks into a just flake-check recipe, added cache-profile: dev to the lint-check job, and made just typecheck auto-install frozen dependencies.
.github/workflows/ci.yamllint-checkjob — Addedcache-profile: devtosetup-nixso it matches other./dev#cijobs. Replaced the two flake-check steps withjust flake-checkand switched both remaining steps to the./dev#cidev shell.justfile—typechecknow depends oninstall(pnpm install --frozen-lockfile) so typechecks always run against the correct workspace dependencies. Addedflake-checkrecipe that runs bothnix flake check(root) andnix flake check ./dev.checkdepends ontypecheck flake-check.
DeepSeek Pro (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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 runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
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. |
* refactor(nix): merge development flake back into the root flake Fold dev/flake.nix back into flake.nix so the repository ships a single flake again: treefmt-nix, git-hooks, and agent-skills inputs return to the root flake, and the development modules (treefmt, git-hooks, dev-shell, agent-skills) are imported alongside the package modules. The dev/ flake split (#1243) existed to keep package-only CI builds from evaluating development inputs, trading a simpler setup for speed. With the Blacksmith sticky-disk Nix store cache (#1249) the extra evaluation cost no longer matters, so the simpler single-flake layout wins. The pins for the restored inputs (agent-skills, git-hooks, treefmt-nix and their transitive deps) are carried over verbatim from dev/flake.lock, so no input revisions change. The dev shell is reached with plain 'nix develop' / 'use flake' again, and all './dev#' flake references move back to the root flake. * refactor(ci): drop the ci dev shell and explicit pnpm install steps Remove devShells.ci and the just install / flake-check recipes that existed to keep CI shells free of side effects. Every workflow now enters the default dev shell with plain 'nix develop --command', whose shellHook installs pnpm dependencies, syncs agent skills, and installs git hooks. The shellHook now runs 'pnpm install --frozen-lockfile' unconditionally instead of comparing lockfile mtimes: an up-to-date install takes about a second, and the conditional occasionally kept stale node_modules around after branch switches. Also drop the warm-dev-shell input from the setup-nix action (nothing passed it any more) and restore the direct 'nix flake check --print-build-logs' step in the lint job. The separate ci shell and explicit install steps were a #1243-era optimisation to avoid paying the shellHook cost in CI; with sticky-disk caching the cost is noise and the extra indirection just made the setup harder to follow. * ci: report what the Nix and node_modules caches restored The sticky disk and cache-nix-action steps only log that a mount or restore happened, so job logs never showed whether the run started warm or cold, or what the restored data actually was. Add report steps after each restore that print the sticky disk key, the mount path, disk usage, and the number of restored Nix store paths or top-level node_modules entries, with an explicit cold-start message when the disk or cache comes back empty. * Revert "ci: report what the Nix and node_modules caches restored" This reverts commit af47cba. * Update nix/dev-shell.nix Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * chore(ci): update github actions * ci: simplify pnpm version resolution for the sticky disk key Read the packageManager pin with jq instead of a node -p invocation and a case statement. The resolved version only feeds the node_modules sticky disk cache key; the pnpm that actually runs self-resolves to the pinned version via manage-package-manager-versions regardless of which binary starts it. * ci: stop caching node_modules on a sticky disk Drop the root node_modules sticky disk and the pnpm version resolution that only existed to build its cache key. A warm disk saved roughly twenty seconds of pnpm install, while mounting cost five to forty-five seconds per job (and occasionally failed outright), every job committed a snapshot even when nothing ran pnpm, and the per-GB-billed disk grew to tens of gigabytes despite node_modules holding about 500 MB of files. Installing from the registry on each run is cheaper and simpler. The Nix store sticky disk stays; that one caches multi-gigabyte build closures that are genuinely expensive to recreate. --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

Summary
Stabilises the crane dependency artifact so Rust dependency caching is not invalidated by unrelated release version bumps or LiteLLM pricing input updates.
What Changed
Testing
Summary by cubic
Stabilizes the
cranedependency cache so Rust deps don’t rebuild on release bumps or pricing snapshot changes, and splits dev tooling into a separate flake to keep packages lean and CI caching predictable. Builds both macOS binaries with Nix and fixes single‑user Nix ownership on non‑Windows cache restores.Strips
CCUSAGE_PRICING_JSON_PATHfrom deps-only builds and pins the deps artifactversionto0.0.0; exposesdepsOnlyArgsand reuses it for static builds so both share a stable cache key.Adds comments in
package.nixandnix/static-package.nixexplaining the stable deps cache key.Refactors
dev/flake.nix;.envrcnow usesuse flake ./dev; adds a./dev#cishell.nixbuild/nix-quick-install-action, splits package vs dev cache profiles, and makes dev-shell warming optional./nix/var/log/nixand/nix/var/nixon non‑Windows before builds; stops chown‑ing/nix/storeto avoid lock permission issues.result/bin/ccusage.just flake-check, usenix develop ./dev#ci, and call sharedjusttasks (install,generate-large-fixture);typechecknow depends on a frozenpnpm install.Written for commit 6157464. Summary will update on new commits.
Summary by CodeRabbit
New Features
Chores