Repository navigation
chore(nix): modularize tooling and migrate hooks - #1139
Conversation
Replace the lefthook configuration with git-hooks.nix using prek as the runner so hook installation and tool resolution come from the Nix dev shell instead of ad hoc shell setup. Split the flake into flake-parts modules under nix/, add treefmt-nix formatting checks, and keep the package derivation in root package.nix/default.nix so package construction is separate from flake outputs. Move hook-only checks for config schema and skill syncing into Nix-generated scripts. These checks report stale generated files instead of staging fixes automatically, and the Claude skill symlinks are synced to match .agents/skills.
|
@coderabbitai please review this PR. |
|
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 (6)
✅ Files skipped from review due to trivial changes (3)
📝 WalkthroughWalkthroughThis PR refactors the project's Nix flake architecture to use ChangesNix Flake-Parts Refactoring and Modular Tooling Architecture
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
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 | f1ccccd | Commit Preview URL Branch Preview URL |
May 23 2026, 09:59 PM |
🧩 Analysis chainLet me gather the PR details first. 🏁 Script executed: Length of output: 2543 🏁 Script executed: Length of output: 37285
Review:
|
| Area | Status |
|---|---|
| flake-parts migration | ✅ Clean |
passthru sharing pattern |
✅ Well-designed |
| Hook coverage parity with lefthook.yml | ✅ Complete |
nix/sync-skills.nix shell script |
✅ Correct |
scripts/sync-skills.ts fix |
✅ Correct |
.gitignore update for .pre-commit-config.yaml |
✅ Necessary |
renovate in devShell via enabledPackages |
|
check.enable = false |
❓ Intentional? |
ccusage-treefmt pass_filenames |
💡 Consider being explicit |
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
Make the treefmt hook filename behavior explicit and use the conventional parent path when importing the root package wrapper.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
nix/dev-shell.nix (1)
62-65: ⚡ Quick winConsider making shellHook paths more robust.
The file tests use relative paths (
pnpm-lock.yaml,node_modules/.pnpm/lock.yaml) which assume the current directory is the repository root. While typical Nix workflows (direnv,nix develop) activate from the repo root, this could fail if the shell is entered from a subdirectory.Consider adding a safety check or changing to absolute paths to ensure the pnpm install logic works correctly regardless of the initial directory.
🛡️ Suggested improvement
shellHook = '' + # Ensure we're in the project root for pnpm operations + if [ -f "flake.nix" ]; then # Install dependencies only if node_modules/.pnpm/lock.yaml is older than pnpm-lock.yaml if [ ! -f node_modules/.pnpm/lock.yaml ] || [ pnpm-lock.yaml -nt node_modules/.pnpm/lock.yaml ]; then echo "📦 Installing dependencies..." pnpm install --frozen-lockfile fi + fi ${config.pre-commit.shellHook} '';Alternatively, store the project root path and use it explicitly:
shellHook = let # Note: This approach requires the project source to be available projectRoot = toString root; in '' cd "${projectRoot}" || exit 1 # Install dependencies only if node_modules/.pnpm/lock.yaml is older than pnpm-lock.yaml if [ ! -f node_modules/.pnpm/lock.yaml ] || [ pnpm-lock.yaml -nt node_modules/.pnpm/lock.yaml ]; then echo "📦 Installing dependencies..." pnpm install --frozen-lockfile fi ${config.pre-commit.shellHook} '';🤖 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/dev-shell.nix` around lines 62 - 65, The shellHook currently uses relative paths (pnpm-lock.yaml, node_modules/.pnpm/lock.yaml) which can break if the shell is opened from a subdirectory; modify the shellHook to derive the repo root (use the existing root variable, e.g. projectRoot = toString root) and either cd into that directory at the start of the shellHook or use absolute paths based on projectRoot when testing files and running pnpm install, and ensure you still append ${config.pre-commit.shellHook} after those commands so the pre-commit hook runs.
🤖 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/dev-shell.nix`:
- Around line 62-65: The shellHook currently uses relative paths
(pnpm-lock.yaml, node_modules/.pnpm/lock.yaml) which can break if the shell is
opened from a subdirectory; modify the shellHook to derive the repo root (use
the existing root variable, e.g. projectRoot = toString root) and either cd into
that directory at the start of the shellHook or use absolute paths based on
projectRoot when testing files and running pnpm install, and ensure you still
append ${config.pre-commit.shellHook} after those commands so the pre-commit
hook runs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bffbd0fc-4e0c-4443-b326-41119d3e586c
⛔ Files ignored due to path filters (1)
flake.lockis excluded by!**/*.lock
📒 Files selected for processing (16)
.claude/skills/create-pr.claude/skills/fs-fixture.claude/skills/pr-ai-review-workflow.gitignoredefault.nixflake.nixlefthook.ymlnix/checks.nixnix/dev-shell.nixnix/git-hooks.nixnix/packages.nixnix/static-package.nixnix/sync-skills.nixnix/treefmt.nixpackage.nixscripts/sync-skills.ts
💤 Files with no reviewable changes (3)
- .claude/skills/fs-fixture
- lefthook.yml
- .claude/skills/pr-ai-review-workflow
|
@coderabbitai I pushed a follow-up that makes the treefmt hook filename behavior explicit and cleans up the package import path. Please review the latest commit. |
|
@cubic-dev-ai please review the latest commit as well. |
There was a problem hiding this comment.
1 issue found across 17 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
@ryoppippi I have started the AI code review. It will take a few minutes to complete. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 822
Both follow-up items are resolved. The PR looks good overall! 🐇 If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
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: |
Update the Nix check source filter to ignore build and cache directory names anywhere in the repository tree, not only at the repository root. This prevents nested outputs such as rust/target, package dist directories, and coverage directories from being copied into check derivations.
|
@coderabbitai @cubic-dev-ai I pushed a follow-up fix for the nested build-output filtering issue in the Nix checks. Please review the latest commit. |
@ryoppippi I have started the AI code review. It will take a few minutes to complete. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 877
The old A couple of small notes (non-blocking):
The fix is solid. PR looks good overall! 🐇 |
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. |
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. |
Replace the hand-written skill sync scripts with an agent-skills-nix based local sync app. The Nix dev shell now generates .claude/skills from .agents/skills, while .claude/skills is ignored and .claude/CLAUDE.md documents the local workflow. The git hooks no longer run skill sync checks because generated skills are not committed. Use nix-filter for the local skill source and for repository check source filtering so generated and build output directories stay out of Nix sources.
|
@coderabbitai @cubic-dev-ai I pushed a follow-up that moves repo-local skill generation to agent-skills-nix, keeps it local-only via the Nix dev shell, ignores generated .claude/skills, and updates the PR description. Please review the latest commit. |
@ryoppippi I have started the AI code review. It will take a few minutes to complete. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 23031
✅ What's improved
🔍 Two minor observations (non-blocking)1.
2. ${lib.getExe config.packages.syncAgentSkills}
${config.pre-commit.shellHook}Since 📋 Summary
PR looks good overall. 🐇 |
Switch the project-local Claude skills target from a copied tree to a symlinked Nix bundle, matching the dotfiles setup and making .claude/skills clearly generated. The sync wrapper now refuses to overwrite an existing directory, so users explicitly remove old generated copies before switching to the Nix-managed symlink. Also relax always-on validation guidance to rely on git hooks and CI for covered checks.
|
@coderabbitai @cubic-dev-ai I pushed a follow-up that switches repo-local skill sync to a local-only symlinked agent-skills-nix bundle and updates the validation guidance to rely on hooks/CI for covered checks. Please review the latest commit. |
@ryoppippi I have started the AI code review. It will take a few minutes to complete. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 4691
✅
|
| Change | Status |
|---|---|
structure = "link" (single symlink) |
✅ Simpler and correct |
| Migration guard for existing plain dir | ✅ Well-written |
AGENT_SKILLS_ROOT env override |
✅ Good flexibility |
.gitignore symlink handling fix |
✅ Necessary |
| Documentation aligned to new model | ✅ Clean |
PR looks good! 🐇
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 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. |
Summary
Validation
Summary by CodeRabbit
New Features
Chores
Documentation