-
Notifications
You must be signed in to change notification settings - Fork 0
feat: upgrade dependencies and configurations #653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
You do not have enough credits to review this pull request. Please purchase more credits to continue. |
|
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughSummary by CodeRabbitRelease Notes
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughAdds git-ai checkpoints/hooks and a git-ai dependency; introduces a ClawDBot static template and hydrate script plus a kyber-only systemd user service; standardizes GLM model references to 4.7; updates many Home Manager / Nix modules, Fish functions, tests, and CI workflow (auto-merge step). Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Hydrate as hydrate.sh
participant Secrets as Secrets\n(files)
participant Template as clawdbot.template.json
participant Config as clawdbot.json\n(generated)
participant Systemd as systemd.user\n(clawdbot-gateway)
participant Gateway as ClawDBot\nGateway
User->>Hydrate: run hydrate.sh with args
Hydrate->>Secrets: read secret files (CLIPROXY_API_KEY,\nTELEGRAM_TOKEN,GATEWAY_TOKEN,ANTHROPIC_API_KEY)
Secrets-->>Hydrate: return values
Hydrate->>Template: load template file
Template-->>Hydrate: template content
Hydrate->>Config: substitute placeholders and write\nclawdbot.json (emit path)
Systemd->>Config: service uses generated config on start
Systemd->>Gateway: ExecStart runs clawdbot gateway process
Gateway-->>Systemd: service running
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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 |
Mesa DescriptionTL;DRUpgraded dependencies and configurations, standardizing LLM models on What changed?
Description generated by Mesa. Update settings |
Summary of ChangesHello @shunkakinoki, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request focuses on a comprehensive upgrade of dependencies and configurations across various development tools and AI services. The primary goal is to enhance the stability, functionality, and integration of AI-assisted workflows, particularly with Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a significant number of updates, primarily focused on upgrading dependencies, standardizing model references to glm-4.7, and integrating git-ai checkpoint hooks. The changes are extensive, touching configuration files for various tools like Claude, Cursor, and Gemini, as well as NixOS and home-manager setups. The refactoring of the clawdbot module and the improvements to the cargo-globals installation script are notable enhancements. My review has identified a few areas for improvement to increase robustness and consistency. I've pointed out a potential bug in the shell script for installing cargo globals, suggested pinning a git dependency to a specific revision for reproducible builds, and recommended making new hook commands non-blocking to align with existing patterns in the codebase. Overall, these are solid improvements to the repository's tooling and configuration.
| path = "lib.rs" | ||
|
|
||
| [dependencies] | ||
| git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a git dependency pointing to a branch (main) can lead to non-reproducible builds, as the branch can be updated at any time. It's best practice to pin the dependency to a specific commit hash using rev to ensure build stability and predictability. The resolved commit hash from Cargo.lock can be used here.
| git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" } | |
| git-ai = { git = "https://github.com/git-ai-project/git-ai", rev = "be15ad1b43dfa2febe643e3ed81be4e801df4d09" } |
| fi | ||
| ;; | ||
| git) | ||
| GIT_URL=$(echo "$dep" | jq -r '.value.git') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When jq -r '.value.git' is used on a JSON object where the git key is missing, it outputs the string "null". The condition [ -n "$GIT_URL" ] will then evaluate to true because "null" is a non-empty string, causing the script to proceed with an invalid git URL. To fix this, you should either check for the string "null" explicitly (e.g., [ "$GIT_URL" != "null" ]) or use jq's // empty operator to ensure an empty string is produced for missing keys, which the -n test will then correctly handle.
| GIT_URL=$(echo "$dep" | jq -r '.value.git') | |
| GIT_URL=$(echo "$dep" | jq -r '.value.git // empty') |
| "hooks": { | ||
| "afterFileEdit": [ | ||
| { | ||
| "command": "git-ai checkpoint cursor --hook-input stdin" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hook command could block the editor if git-ai checkpoint fails or hangs. For a better user experience, it's recommended to make the hook non-blocking by redirecting its output and ignoring failures. This would also make it consistent with the similar hook in config/claude/settings.json which is non-blocking.
| "command": "git-ai checkpoint cursor --hook-input stdin" | |
| "command": "git-ai checkpoint cursor --hook-input stdin 2>/dev/null || true" |
| ], | ||
| "beforeSubmitPrompt": [ | ||
| { | ||
| "command": "git-ai checkpoint cursor --hook-input stdin" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the afterFileEdit hook, this command could block the UI if it fails. To prevent this and ensure a smooth user experience, consider running it in a non-blocking way by redirecting output and ignoring the exit code. This would make it consistent with other hooks in this PR.
| "command": "git-ai checkpoint cursor --hook-input stdin" | |
| "command": "git-ai checkpoint cursor --hook-input stdin 2>/dev/null || true" |
| "BeforeTool": [ | ||
| { | ||
| "matcher": "write_file|replace", | ||
| "command": "git-ai checkpoint gemini --hook-input stdin" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hook command could block the editor if it fails or takes too long to execute. To ensure a non-blocking user experience and maintain consistency with other hooks in this PR (like in config/claude/settings.json), it's advisable to make it non-blocking by ignoring failures.
| "command": "git-ai checkpoint gemini --hook-input stdin" | |
| "command": "git-ai checkpoint gemini --hook-input stdin 2>/dev/null || true" |
| "AfterTool": [ | ||
| { | ||
| "matcher": "write_file|replace", | ||
| "command": "git-ai checkpoint gemini --hook-input stdin" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hook command could block the editor if it fails or takes too long to execute. To ensure a non-blocking user experience and maintain consistency with other hooks in this PR (like in config/claude/settings.json), it's advisable to make it non-blocking by ignoring failures.
| "command": "git-ai checkpoint gemini --hook-input stdin" | |
| "command": "git-ai checkpoint gemini --hook-input stdin 2>/dev/null || true" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
home-manager/programs/fish/functions/_ocxe_function.fish (1)
1-9: Description is inconsistent with the actual provider.The function description says "via OpenRouter" but the model now uses
cliproxyapi/glm-4-7instead ofopenrouter-preset/glm-4-7. Consider updating the description to reflect the actual provider.-function _ocxe_function --description "Run OpenCode with GLM-4.7 via OpenRouter" +function _ocxe_function --description "Run OpenCode with GLM-4.7 via CLIProxy API"
🤖 Fix all issues with AI agents
In `@Cargo.toml`:
- Line 10: Replace the floating git branch reference for the git-ai dependency
with a pinned revision or tag to ensure reproducible builds: locate the git
dependency entry for "git-ai" in the Cargo.toml and replace branch = "main" with
either rev = "<commit-sha>" or tag = "<tag-name>" (using the specific commit SHA
or release tag you want to lock to) so the crate is fetched deterministically.
In `@config/opencode/opencode.jsonc`:
- Around line 188-191: The id value for the preset is inconsistent with its key:
update the "id" field for the glm-4.7 entry so it matches the key's period
format (change the id in the object that currently reads "@preset/glm-4-7" to
use "@preset/glm-4.7"); locate the glm-4.7 object in the config and replace the
hyphenated id string with the period-formatted id to ensure lookups like glm-4.7
resolve correctly.
In `@scripts/upgrade-overlays.sh`:
- Around line 98-110: The nix_config uses hostname for Linux configs which is
wrong; instead detect system architecture (reuse arch=$(uname -m) logic) and map
it to the flake naming (e.g., x86_64-linux or aarch64-linux) and set
nix_config=".#homeConfigurations.$(whoami)@${arch}-linux.activationPackage"
(adjust mapping from uname -m values to flake strings where needed). Update the
else branch that assigns nix_config to use the arch variable and mapping logic
(symbols: nix_config, arch, OSTYPE, uname -m) so Linux homeConfigurations
reference username@system-architecture rather than username@hostname.
🧹 Nitpick comments (8)
config/gemini/settings.json (1)
1-19: Add error suppression and timeout to git-ai hook commands for resilience.The Gemini hooks lack error handling compared to the Claude configuration. Claude's git-ai hooks include error suppression (
2>/dev/null || true) and a 5-second timeout, allowing graceful degradation if git-ai is unavailable or fails. The Gemini hooks have neither safeguard:"command": "git-ai checkpoint gemini --hook-input stdin"Without error suppression, a failed git-ai invocation could interrupt the workflow. Consider adding the same defensive measures used in Claude settings:
"command": "git-ai checkpoint gemini --hook-input stdin 2>/dev/null || true", "timeout": 5home-manager/modules/cargo-globals/install-cargo-globals.sh (1)
77-81: Consider capturing or suppressing installation output more intentionally.The
2>&1redirects stderr to stdout but the output isn't captured or suppressed. This means installation output will print to terminal but the exit status is still checked. If you want cleaner output, consider redirecting to/dev/nullor capturing for conditional display.- if ! cargo install "$NAME" --version "$VERSION" --locked 2>&1; then - if ! cargo install "$NAME" --version "$VERSION" 2>&1; then + if ! cargo install "$NAME" --version "$VERSION" --locked; then + if ! cargo install "$NAME" --version "$VERSION"; thenThis applies similarly to lines 103-104 for git dependencies.
config/clawdbot/hydrate.sh (2)
42-48: Remove unused__TELEGRAM_TOKEN__substitution.The template file uses
tokenFile(a file path) for Telegram authentication, not a direct__TELEGRAM_TOKEN__placeholder. This sed substitution on line 44 won't match anything in the template and is dead code.♻️ Proposed fix
`@sed`@ \ -e "s|__CLIPROXY_API_KEY__|${CLIPROXY_API_KEY}|g" \ - -e "s|__TELEGRAM_TOKEN__|${TELEGRAM_TOKEN}|g" \ -e "s|__GATEWAY_TOKEN__|${GATEWAY_TOKEN}|g" \ -e "s|__CHROMIUM_PATH__|${CHROMIUM_PATH}|g" \ -e "s|__HOME__|${HOME}|g" \ "$TEMPLATE" > "$CONFIG"
29-33: Consider removing unusedTELEGRAM_TOKENloading.Since the template uses
tokenFilefor Telegram (pointing to the token file directly), loadingTELEGRAM_TOKENinto a variable (line 31) serves no purpose. The hydrate.sh already writes the token to${SECRETS_DIR}/telegram-tokenvia the activation script, and the template'stokenFilepoints there.♻️ Proposed fix
# Load secrets from files or environment CLIPROXY_API_KEY="${CLIPROXY_API_KEY:-$(read_secret "${SECRETS_DIR}/cliproxy-key")}" -TELEGRAM_TOKEN="${TELEGRAM_TOKEN:-$(read_secret "${SECRETS_DIR}/telegram-token")}" GATEWAY_TOKEN="${GATEWAY_TOKEN:-$(read_secret "${SECRETS_DIR}/gateway-token")}" ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-$(read_secret "${SECRETS_DIR}/anthropic-key")}"home-manager/modules/clawdbot/default.nix (3)
86-90:WorkingDirectorymay not exist when service starts.The service's
WorkingDirectoryis set to${homeDir}/.clawdbot, but this directory is created inside the hydrate script (line 39 of hydrate.sh viamkdir -p). If systemd attempts to verify the directory beforeExecStartruns, the service may fail.Consider either:
- Adding a
ExecStartPreto create the directory, or- Using
WorkingDirectory=~and letting the script handle the directory change.♻️ Option 1: Add ExecStartPre
Service = { Type = "simple"; + ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${homeDir}/.clawdbot"; ExecStart = "${pkgs.bash}/bin/bash ${hydrateScript}"; Restart = "always";
89-90: Log directory in/tmpmay not survive reboots.The activation creates
/tmp/clawdbotduringhome-manager switch, but/tmpis typically cleared on reboot. When the systemd service starts after a reboot, the directory won't exist and logging will fail.Consider using systemd's
RuntimeDirectoryorLogsDirectorydirectives which handle directory creation automatically:♻️ Use RuntimeDirectory for logs
Service = { Type = "simple"; ExecStart = "${pkgs.bash}/bin/bash ${hydrateScript}"; Restart = "always"; RestartSec = "5s"; Environment = [ "HOME=${homeDir}" ]; WorkingDirectory = "${homeDir}/.clawdbot"; - StandardOutput = "append:/tmp/clawdbot/clawdbot-gateway.log"; - StandardError = "append:/tmp/clawdbot/clawdbot-gateway.log"; + RuntimeDirectory = "clawdbot"; + StandardOutput = "append:%t/clawdbot/clawdbot-gateway.log"; + StandardError = "append:%t/clawdbot/clawdbot-gateway.log"; };Then the
clawdbotLogDiractivation can be removed.Also applies to: 97-102
53-53:.envparsing may truncate values containing=.The
cut -d= -f2approach will truncate values that contain=characters. For example,KEY="value=with=equals"would extract only"value".Consider using
sedorcut -d= -f2-to capture everything after the first=:♻️ Proposed fix
- CLIPROXY_KEY=$(grep -E "^CLIPROXY_API_KEY=" "$ENV_FILE" 2>/dev/null | cut -d= -f2 | tr -d '"' | tr -d '\n' || true) + CLIPROXY_KEY=$(grep -E "^CLIPROXY_API_KEY=" "$ENV_FILE" 2>/dev/null | cut -d= -f2- | tr -d '"' | tr -d '\n' || true)Apply similarly to lines 58 and 63.
config/cliproxyapi/config.yaml (1)
89-97: Model updates look good.The glm-4.6 → glm-4.7 migration is consistent across both providers. One observation: the z-ai entry (line 96-97) has identical
nameandaliasvalues (glm-4.7). While not incorrect, this could be simplified by omitting the alias if it matches the name.♻️ Optional: Remove redundant alias
- name: "z-ai" base-url: "https://api.z.ai/api/coding/paas/v4" api-key-entries: - api-key: "__ZAI_API_KEY__" models: - name: "glm-4.7" - alias: "glm-4.7"
| path = "lib.rs" | ||
|
|
||
| [dependencies] | ||
| git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pin git dependency to a specific revision for reproducibility.
Using branch = "main" makes builds non-reproducible—the dependency can change without any update to this file. Consider pinning to a specific rev (commit SHA) or tag:
-git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" }
+git-ai = { git = "https://github.com/git-ai-project/git-ai", rev = "<commit-sha>" }This ensures consistent builds across environments and CI runs.
🤖 Prompt for AI Agents
In `@Cargo.toml` at line 10, Replace the floating git branch reference for the
git-ai dependency with a pinned revision or tag to ensure reproducible builds:
locate the git dependency entry for "git-ai" in the Cargo.toml and replace
branch = "main" with either rev = "<commit-sha>" or tag = "<tag-name>" (using
the specific commit SHA or release tag you want to lock to) so the crate is
fetched deterministically.
| "glm-4.7": { | ||
| "id": "@preset/glm-4-7", | ||
| "name": "Preset GLM-4.7 (via OpenRouter)" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
rg -n -C2 'glm-4-7|openrouter-preset/glm-4-7|@preset/glm-4-7' --type json --type jsoncRepository: shunkakinoki/dotfiles
Length of output: 94
🏁 Script executed:
# Also check if there are any references in other file types
rg -n 'glm-4-7' --type js --type jsx --type ts --type tsx --type mdRepository: shunkakinoki/dotfiles
Length of output: 92
🏁 Script executed:
# Get context around the changed lines in the file
cat -n config/opencode/opencode.jsonc | sed -n '180,200p'Repository: shunkakinoki/dotfiles
Length of output: 726
🏁 Script executed:
rg -n 'glm-4' --max-count 20Repository: shunkakinoki/dotfiles
Length of output: 3466
🏁 Script executed:
# Search for any `@preset` references
rg -n '@preset' --max-count 20Repository: shunkakinoki/dotfiles
Length of output: 609
🏁 Script executed:
# Check if there are any config files that might reference these models
fd -e json -e jsonc -e js -e ts | head -20Repository: shunkakinoki/dotfiles
Length of output: 662
Fix inconsistency: ID field should use period format to match the key.
The key at line 188 was renamed to glm-4.7 (with period), but the id field at line 189 still uses the old format @preset/glm-4-7 (with hyphens). This mismatch between key and ID can cause lookup failures. Update line 189 to:
"id": "@preset/glm-4.7",
🤖 Prompt for AI Agents
In `@config/opencode/opencode.jsonc` around lines 188 - 191, The id value for the
preset is inconsistent with its key: update the "id" field for the glm-4.7 entry
so it matches the key's period format (change the id in the object that
currently reads "@preset/glm-4-7" to use "@preset/glm-4.7"); locate the glm-4.7
object in the config and replace the hyphenated id string with the
period-formatted id to ensure lookups like glm-4.7 resolve correctly.
scripts/upgrade-overlays.sh
Outdated
| # Detect platform and build configuration | ||
| local nix_config | ||
| if [[ "$OSTYPE" == "darwin"* ]]; then | ||
| local arch | ||
| arch=$(uname -m) | ||
| if [[ "$arch" == "arm64" ]]; then | ||
| nix_config=".#darwinConfigurations.aarch64-darwin.system" | ||
| else | ||
| nix_config=".#darwinConfigurations.x86_64-darwin.system" | ||
| fi | ||
| else | ||
| nix_config=".#homeConfigurations.$(whoami)@$(hostname).activationPackage" | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check how homeConfigurations are named in flake.nix
echo "=== homeConfigurations in flake.nix ==="
rg -n 'homeConfigurations' flake.nix -A 5 || echo "Not found"
echo ""
echo "=== Any username@hostname patterns ==="
rg -n '@' flake.nix | head -20 || echo "Not found"
echo ""
echo "=== Full flake.nix size and structure check ==="
wc -l flake.nixRepository: shunkakinoki/dotfiles
Length of output: 794
Fix the homeConfigurations reference to use the system architecture instead of hostname.
The code assumes Linux homeConfigurations are named $(whoami)@$(hostname), but the actual flake.nix defines them as username@system-architecture (e.g., "ubuntu@x86_64-linux"). The $(hostname) variable will return the machine hostname, not the architecture string, causing the build to fail. Detect the system architecture (as done for Darwin) and use it in the configuration path.
🤖 Prompt for AI Agents
In `@scripts/upgrade-overlays.sh` around lines 98 - 110, The nix_config uses
hostname for Linux configs which is wrong; instead detect system architecture
(reuse arch=$(uname -m) logic) and map it to the flake naming (e.g.,
x86_64-linux or aarch64-linux) and set
nix_config=".#homeConfigurations.$(whoami)@${arch}-linux.activationPackage"
(adjust mapping from uname -m values to flake strings where needed). Update the
else branch that assigns nix_config to use the arch variable and mapping logic
(symbols: nix_config, arch, OSTYPE, uname -m) so Linux homeConfigurations
reference username@system-architecture rather than username@hostname.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a significant upgrade and refactoring effort focused on dependency management, model version updates, and configuration improvements across the dotfiles repository.
Changes:
- Refactored clawdbot module from a complex multi-host configuration to a simplified kyber-only gateway setup with template-based configuration
- Enhanced cargo globals installation with git dependency support, macOS SDK configuration, and improved libiconv integration
- Updated model references from GLM-4.6 to GLM-4.7 across all AI tool configurations (opencode, Fish functions, cliproxyapi)
- Added git-ai checkpoint integration for Gemini CLI and Cursor IDE with hook-based workflow tracking
- Enabled GitHub workflow auto-merge for automated overlay upgrades
Reviewed changes
Copilot reviewed 30 out of 32 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/cargo_globals_spec.sh | Updated tests to verify git dependency support in cargo globals installer |
| scripts/upgrade-overlays.sh | Added platform detection for macOS (arm64/x86_64) and Linux in pnpm hash computation |
| overlays/default.nix | Updated clawdbot pnpmDepsHash to latest value |
| home-manager/programs/fish/functions/_zpo_function.fish | Added new Fish function for zellij primary session attachment |
| home-manager/programs/fish/functions/_ocxeh_function.fish | Updated model reference from openrouter-preset to cliproxyapi provider |
| home-manager/programs/fish/functions/_ocxe_function.fish | Updated model references to use cliproxyapi provider |
| home-manager/programs/fish/default.nix | Alphabetically sorted function list and added _zpo_function |
| home-manager/packages/default.nix | Added libiconv package for cargo build support on macOS |
| home-manager/modules/clawdbot/extract-secrets.sh | Removed standalone secret extraction script (integrated into module) |
| home-manager/modules/clawdbot/default.nix | Complete rewrite: simplified to kyber-only, removed programs.clawdbot usage, added hydrate script integration |
| home-manager/modules/cargo-globals/install-cargo-globals.sh | Enhanced with macOS SDK path setup, git dependency support, improved error handling |
| home-manager/modules/cargo-globals/default.nix | Added comprehensive libiconv environment configuration for macOS builds |
| home-manager/default.nix | Removed nix-clawdbot.homeManagerModules.clawdbot import |
| flake.lock | Updated nix-clawdbot to latest commit |
| config/pi/models.json | Removed GLM-4.6 model entry |
| config/opencode/opencode.jsonc | Updated to GLM-4.7, removed GLM-4.6 references, standardized model IDs |
| config/llm/extra-openai-models.yaml | Updated Claude model versions and added GLM-4.7 configuration |
| config/llm/default_model.txt | New file setting glm-4.7 as default model |
| config/llm/default.nix | Added default_model.txt symlinks for both macOS and Linux |
| config/gemini/settings.json | New file adding git-ai checkpoint hooks for file operations |
| config/gemini/default.nix | New module for gemini CLI configuration |
| config/default.nix | Added cursor and gemini configuration imports |
| config/cursor/hooks.json | New file with git-ai checkpoint integration for Cursor IDE |
| config/cursor/default.nix | New module for Cursor IDE configuration |
| config/cliproxyapi/config.yaml | Updated routing strategy to fill-first, replaced GLM-4.6 with OpenRouter preset for GLM-4.7 |
| config/clawdbot/hydrate.sh | New runtime configuration hydration script with secret injection |
| config/clawdbot/clawdbot.template.json | New template-based configuration for clawdbot gateway |
| config/claude/settings.json | Added git-ai checkpoint hooks for file write operations |
| config/ccs/config.template.yaml | Added comprehensive quota management configuration section |
| Cargo.toml | Added git-ai as git dependency from main branch |
| Cargo.lock | Extensive additions for git-ai and its transitive dependencies |
| .github/workflows/upgrade.yml | Added auto-merge step for automated overlay upgrade PRs |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if ! cargo install "$NAME" --version "$VERSION" --locked 2>&1; then | ||
| if ! cargo install "$NAME" --version "$VERSION" 2>&1; then |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error output is redirected to the same file descriptor as standard output without suppression (2>&1). This means error messages will be captured but not necessarily visible to the user during installation. Consider whether errors should be shown separately or at least logged distinctly from successful output.
| if ! cargo install "$NAME" --version "$VERSION" --locked 2>&1; then | |
| if ! cargo install "$NAME" --version "$VERSION" 2>&1; then | |
| if ! cargo install "$NAME" --version "$VERSION" --locked; then | |
| if ! cargo install "$NAME" --version "$VERSION"; then |
| path = "lib.rs" | ||
|
|
||
| [dependencies] | ||
| git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" } |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The git-ai dependency is pinned to branch = "main" which does not provide reproducible builds. Consider pinning to a specific commit SHA or tag instead for better reproducibility and stability.
| git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" } | |
| git-ai = { git = "https://github.com/git-ai-project/git-ai", rev = "0123456789abcdef0123456789abcdef01234567" } |
| home.activation.clawdbotSecrets = lib.mkIf (lib ? hm && lib.hm ? dag) ( | ||
| in | ||
| # Only enable on kyber (gateway host) and outside CI | ||
| lib.mkIf (host.isKyber && !env.isCI) { |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clawdbot module has been refactored to only run on kyber (line 27 condition: host.isKyber && !env.isCI), but this represents a significant behavioral change that removes clawdbot support from all other hosts. The PR description states "Refactored clawdbot module for better configuration management" but doesn't mention this significant scope reduction. Verify this is intentional and document it clearly if so.
| CCS_AUTH="${homeDir}/.ccs/cliproxy/auth" | ||
| # Extract Anthropic key from ccs auth if available | ||
| if [ -d "$CCS_AUTH" ]; then | ||
| ANTHROPIC_FILE=$(find "$CCS_AUTH" -name "*.json" -exec grep -l "anthropic" {} \; 2>/dev/null | head -1) | ||
| if [ -n "$ANTHROPIC_FILE" ] && [ -f "$ANTHROPIC_FILE" ]; then | ||
| ${pkgs.jq}/bin/jq -r '.api_key // empty' "$ANTHROPIC_FILE" 2>/dev/null | tr -d '\n' > "$SECRETS_DIR/anthropic-key" || true | ||
| fi | ||
| fi |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The secret extraction logic has changed from the previous implementation. The new code looks for secrets in ~/.ccs/cliproxy/auth (line 40) and expects a different JSON structure with .api_key field (line 46), whereas the old implementation looked in ~/.cli-proxy-api/objectstore/auths for .access_token. Verify that this path and field name change is correct and that secrets will be found at the new location.
| CCS_AUTH="${homeDir}/.ccs/cliproxy/auth" | |
| # Extract Anthropic key from ccs auth if available | |
| if [ -d "$CCS_AUTH" ]; then | |
| ANTHROPIC_FILE=$(find "$CCS_AUTH" -name "*.json" -exec grep -l "anthropic" {} \; 2>/dev/null | head -1) | |
| if [ -n "$ANTHROPIC_FILE" ] && [ -f "$ANTHROPIC_FILE" ]; then | |
| ${pkgs.jq}/bin/jq -r '.api_key // empty' "$ANTHROPIC_FILE" 2>/dev/null | tr -d '\n' > "$SECRETS_DIR/anthropic-key" || true | |
| fi | |
| fi | |
| CCS_AUTH_DIRS=( | |
| "${homeDir}/.ccs/cliproxy/auth" | |
| "${homeDir}/.cli-proxy-api/objectstore/auths" | |
| ) | |
| # Extract Anthropic key from ccs auth if available (support new and legacy locations/fields) | |
| for CCS_AUTH in "${CCS_AUTH_DIRS[@]}"; do | |
| if [ -d "$CCS_AUTH" ]; then | |
| ANTHROPIC_FILE=$(find "$CCS_AUTH" -name "*.json" -exec grep -l "anthropic" {} \; 2>/dev/null | head -1) | |
| if [ -n "$ANTHROPIC_FILE" ] && [ -f "$ANTHROPIC_FILE" ]; then | |
| ${pkgs.jq}/bin/jq -r '.api_key // .access_token // empty' "$ANTHROPIC_FILE" 2>/dev/null | tr -d '\n' > "$SECRETS_DIR/anthropic-key" || true | |
| # Stop after successfully writing the key | |
| if [ -s "$SECRETS_DIR/anthropic-key" ]; then | |
| break | |
| fi | |
| fi | |
| fi | |
| done |
| fi | ||
| # Ensure proper permissions | ||
| chmod 600 "$SECRETS_DIR"/*.key "$SECRETS_DIR"/*-token 2>/dev/null || true |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The chmod command on line 70 will fail silently (with || true) if there are no .key or *-token files in the directory. While this is intentional to avoid errors, it means permission issues won't be visible. Consider logging when files are successfully protected or when they're missing.
| chmod 600 "$SECRETS_DIR"/*.key "$SECRETS_DIR"/*-token 2>/dev/null || true | |
| if ls "$SECRETS_DIR"/*.key "$SECRETS_DIR"/*-token >/dev/null 2>&1; then | |
| if ! chmod 600 "$SECRETS_DIR"/*.key "$SECRETS_DIR"/*-token; then | |
| echo "Warning: failed to set permissions on one or more secret files in $SECRETS_DIR" >&2 | |
| else | |
| echo "Protected secret files in $SECRETS_DIR" | |
| fi | |
| else | |
| echo "No .key or *-token secret files found in $SECRETS_DIR to protect" | |
| fi |
| StandardOutput = "append:/tmp/clawdbot/clawdbot-gateway.log"; | ||
| StandardError = "append:/tmp/clawdbot/clawdbot-gateway.log"; |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The systemd service logs to /tmp/clawdbot/clawdbot-gateway.log which will be lost on system reboot. Consider using a persistent location like $HOME/.local/state/clawdbot/logs/ or /var/log/clawdbot/ for production use.
| - name: Enable Auto-Merge | ||
| if: steps.cpr.outputs.pull-request-number | ||
| run: gh pr merge ${{ steps.cpr.outputs.pull-request-number }} --squash --auto | ||
| env: | ||
| GH_TOKEN: ${{ secrets.PAT_TOKEN }} |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The auto-merge feature is enabled without any checks or approvals. This means that automated overlay upgrades will be merged automatically even if they fail tests or introduce breaking changes. Consider adding a check for CI status or requiring at least one approval before enabling auto-merge.
| "hooks": { | ||
| "afterFileEdit": [ | ||
| { | ||
| "command": "git-ai checkpoint cursor --hook-input stdin" |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR description mentions "Fixed git-ai command paths in hooks.json to be relative" but the cursor hooks.json uses absolute command references like "git-ai checkpoint cursor --hook-input stdin" without any path prefix. The commands rely on git-ai being in PATH. If "relative" means removing a path prefix, verify that git-ai is properly added to PATH in all contexts where these hooks will execute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@config/clawdbot/clawdbot.template.json`:
- Around line 55-68: The template contains hard-coded Telegram IDs under
"channels" -> "telegram" (notably the group entry "-1003612372477" and the
"allowFrom" array) which may expose PII; replace specific numeric IDs with
non-identifying placeholders or empty structures (e.g., use placeholder keys
like "<GROUP_ID_PLACEHOLDER>" and an empty "allowFrom": []), and ensure the
"groups" map only contains template-safe entries (or comments) rather than real
IDs so the template no longer includes any real user/group identifiers.
- Around line 2-7: The template currently defaults the "browser" config to
"noSandbox": true which weakens security; change the default to false (or remove
the key) and make sandbox disabling opt‑in via a clearer config placeholder or
env-driven flag (e.g., a "__NO_SANDBOX__" placeholder or read from process env)
so consumers must explicitly opt in; update the "browser" object keys
("noSandbox", "executablePath", "headless") to reflect the safer default and add
a short comment or README note indicating that noSandbox should only be used in
constrained environments with justification.
- Around line 37-46: Update the default agent model reference under the "agents"
-> "defaults" -> "model" -> "primary" key: replace the non-existent
"anthropic/claude-opus-4-5" value with the declared model ID
"claude-opus-4-5-20251101" (the cliproxy provider model), ensuring the
"agents"/"defaults"/"model" entry points to an available provider model.
🧹 Nitpick comments (2)
config/clawdbot/clawdbot.template.json (1)
69-75: Consider defaulting gateway bind to loopback.
Binding to LAN increases exposure; if LAN access isn’t required by default, prefer localhost and let hydrate/overrides enable LAN.home-manager/modules/cargo-globals/default.nix (1)
8-13: Add a short comment explaining the Darwin libiconv bindings.These paths are non-obvious; a brief rationale will help future maintainers.
♻️ Suggested doc tweak
let isDarwin = pkgs.stdenv.isDarwin; + # libiconv paths are required for some cargo builds on Darwin in Nix envs. libiconvPkgConfigPath = lib.optionalString isDarwin ":${pkgs.libiconv.dev}/lib/pkgconfig"; libiconvLibraryPath = lib.optionalString isDarwin "${pkgs.libiconv.out}/lib"; libiconvCPath = lib.optionalString isDarwin "${pkgs.libiconv.dev}/include";As per coding guidelines, ...
| "browser": { | ||
| "enabled": true, | ||
| "executablePath": "__CHROMIUM_PATH__", | ||
| "headless": true, | ||
| "noSandbox": true | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid defaulting to noSandbox: true.
Running Chromium without the sandbox weakens isolation; make it opt‑in for constrained environments only.
🔧 Suggested safer default
- "noSandbox": true
+ "noSandbox": false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "browser": { | |
| "enabled": true, | |
| "executablePath": "__CHROMIUM_PATH__", | |
| "headless": true, | |
| "noSandbox": true | |
| }, | |
| "browser": { | |
| "enabled": true, | |
| "executablePath": "__CHROMIUM_PATH__", | |
| "headless": true, | |
| "noSandbox": false | |
| }, |
🤖 Prompt for AI Agents
In `@config/clawdbot/clawdbot.template.json` around lines 2 - 7, The template
currently defaults the "browser" config to "noSandbox": true which weakens
security; change the default to false (or remove the key) and make sandbox
disabling opt‑in via a clearer config placeholder or env-driven flag (e.g., a
"__NO_SANDBOX__" placeholder or read from process env) so consumers must
explicitly opt in; update the "browser" object keys ("noSandbox",
"executablePath", "headless") to reflect the safer default and add a short
comment or README note indicating that noSandbox should only be used in
constrained environments with justification.
| "agents": { | ||
| "defaults": { | ||
| "model": {"primary": "anthropic/claude-opus-4-5"}, | ||
| "workspace": "__HOME__/.clawdbot/workspace", | ||
| "thinkingDefault": "high", | ||
| "maxConcurrent": 4, | ||
| "subagents": {"maxConcurrent": 8} | ||
| }, | ||
| "list": [{"id": "main", "default": true}] | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Search for model-related definitions, aliases, and provider configurations
rg -n "anthropic/claude-opus-4-5|cliproxy/claude-opus-4-5|model.*alias|provider.*model|declared.*model" --type json --type js --type ts -B 2 -A 2Repository: shunkakinoki/dotfiles
Length of output: 447
🏁 Script executed:
# Also search for clawdbot configuration files and model definitions
fd -e json -e js -e ts -e yaml -e yml | grep -i "clawdbot\|model\|alias\|provider" | head -20Repository: shunkakinoki/dotfiles
Length of output: 161
🏁 Script executed:
# Look for any references to anthropic/claude-opus models
rg -n "anthropic/claude" --type json --type js --type ts -B 1 -A 1Repository: shunkakinoki/dotfiles
Length of output: 316
🏁 Script executed:
# Check the pi/models.json file
cat config/pi/models.jsonRepository: shunkakinoki/dotfiles
Length of output: 4487
🏁 Script executed:
# Check the llm/extra-openai-models.yaml file
cat config/llm/extra-openai-models.yamlRepository: shunkakinoki/dotfiles
Length of output: 603
🏁 Script executed:
# Search for clawdbot configuration or scripts that define/use models
fd -e json -e js -e ts -e yaml -e yml -e toml | xargs grep -l "clawdbot" | head -10Repository: shunkakinoki/dotfiles
Length of output: 103
🏁 Script executed:
# Search for any model provider configuration or mapping
rg -n "provider|model.*id|alias" config/clawdbot/ --type json --type js --type yamlRepository: shunkakinoki/dotfiles
Length of output: 125
🏁 Script executed:
# Read the full clawdbot.template.json file
cat config/clawdbot/clawdbot.template.jsonRepository: shunkakinoki/dotfiles
Length of output: 5287
🏁 Script executed:
# Also search for any model mapping or routing logic in clawdbot-related files
rg -n "anthropic|cliproxy|model.*mapping|routing" config/clawdbot/ -A 3Repository: shunkakinoki/dotfiles
Length of output: 1340
Update the default model reference to a declared model ID.
anthropic/claude-opus-4-5 does not exist in the defined providers. The correct model ID is claude-opus-4-5-20251101 (available in the cliproxy provider).
🤖 Prompt for AI Agents
In `@config/clawdbot/clawdbot.template.json` around lines 37 - 46, Update the
default agent model reference under the "agents" -> "defaults" -> "model" ->
"primary" key: replace the non-existent "anthropic/claude-opus-4-5" value with
the declared model ID "claude-opus-4-5-20251101" (the cliproxy provider model),
ensuring the "agents"/"defaults"/"model" entry points to an available provider
model.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6 issues found across 32 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="config/cursor/default.nix">
<violation number="1" location="config/cursor/default.nix:4">
P2: `source = ./hooks.json` references a non-existent file; Nix evaluation will fail unless `hooks.json` is added alongside `default.nix`.</violation>
</file>
<file name="config/clawdbot/hydrate.sh">
<violation number="1" location="config/clawdbot/hydrate.sh:43">
P2: Secrets are interpolated into sed replacements without escaping, so special characters in tokens can corrupt the generated config.</violation>
</file>
<file name="Cargo.toml">
<violation number="1" location="Cargo.toml:10">
P2: Git dependency tracks the moving `main` branch without a pinned revision or tag, making builds non‑reproducible and susceptible to upstream changes.</violation>
</file>
<file name="config/claude/settings.json">
<violation number="1" location="config/claude/settings.json:206">
P2: Hook payload is injected into command-line arguments, risking exposure via process listings and failure when payloads exceed OS argument-length limits.</violation>
</file>
<file name="scripts/upgrade-overlays.sh">
<violation number="1" location="scripts/upgrade-overlays.sh:106">
P2: The new Intel macOS branch references `darwinConfigurations.x86_64-darwin`, but the flake only defines `aarch64-darwin`, so the script will fail to build on x86_64 macs and cannot compute pnpmDepsHash.</violation>
<violation number="2" location="scripts/upgrade-overlays.sh:109">
P2: Non-darwin homeConfigurations attr path uses `@` without quoting, which can make `nix build` fail to resolve the flake attribute.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| { config, ... }: | ||
| { | ||
| home.file.".cursor/hooks.json" = { | ||
| source = ./hooks.json; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: source = ./hooks.json references a non-existent file; Nix evaluation will fail unless hooks.json is added alongside default.nix.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/cursor/default.nix, line 4:
<comment>`source = ./hooks.json` references a non-existent file; Nix evaluation will fail unless `hooks.json` is added alongside `default.nix`.</comment>
<file context>
@@ -0,0 +1,7 @@
+{ config, ... }:
+{
+ home.file.".cursor/hooks.json" = {
+ source = ./hooks.json;
+ force = true;
+ };
</file context>
|
|
||
| # Generate config from template with secret substitution | ||
| @sed@ \ | ||
| -e "s|__CLIPROXY_API_KEY__|${CLIPROXY_API_KEY}|g" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Secrets are interpolated into sed replacements without escaping, so special characters in tokens can corrupt the generated config.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/clawdbot/hydrate.sh, line 43:
<comment>Secrets are interpolated into sed replacements without escaping, so special characters in tokens can corrupt the generated config.</comment>
<file context>
@@ -0,0 +1,58 @@
+
+# Generate config from template with secret substitution
+@sed@ \
+ -e "s|__CLIPROXY_API_KEY__|${CLIPROXY_API_KEY}|g" \
+ -e "s|__TELEGRAM_TOKEN__|${TELEGRAM_TOKEN}|g" \
+ -e "s|__GATEWAY_TOKEN__|${GATEWAY_TOKEN}|g" \
</file context>
| path = "lib.rs" | ||
|
|
||
| [dependencies] | ||
| git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Git dependency tracks the moving main branch without a pinned revision or tag, making builds non‑reproducible and susceptible to upstream changes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Cargo.toml, line 10:
<comment>Git dependency tracks the moving `main` branch without a pinned revision or tag, making builds non‑reproducible and susceptible to upstream changes.</comment>
<file context>
@@ -7,4 +7,5 @@ edition = "2021"
path = "lib.rs"
[dependencies]
+git-ai = { git = "https://github.com/git-ai-project/git-ai", branch = "main" }
worktrunk = "0.18.2"
</file context>
| "hooks": [ | ||
| { | ||
| "type": "command", | ||
| "command": "git-ai checkpoint claude --hook-input \"$(cat)\" 2>/dev/null || true", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Hook payload is injected into command-line arguments, risking exposure via process listings and failure when payloads exceed OS argument-length limits.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/claude/settings.json, line 206:
<comment>Hook payload is injected into command-line arguments, risking exposure via process listings and failure when payloads exceed OS argument-length limits.</comment>
<file context>
@@ -185,6 +185,28 @@
+ "hooks": [
+ {
+ "type": "command",
+ "command": "git-ai checkpoint claude --hook-input \"$(cat)\" 2>/dev/null || true",
+ "timeout": 5
+ }
</file context>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@home-manager/modules/clawdbot/default.nix`:
- Line 141: The systemd service sets WorkingDirectory = "${homeDir}/.clawdbot"
but no activation step ensures that directory exists; add an activation block
(e.g., in the module's activationCommands or a dedicated home.activation entry)
that runs mkdir -p "${homeDir}/.clawdbot" and sets ownership/permissions as
appropriate (chown -R ${config.home.username}:${config.home.username}
"${homeDir}/.clawdbot" or use ${builtins.toString config.home.user} style), so
the directory is created before systemd enables/starts the service; reference
the WorkingDirectory assignment and add the activationCommands/activationScripts
in the same Nix module.
- Around line 93-101: The current extraction pipeline writes an empty file when
jq yields no key; change it to capture the jq output to a variable (or temp
file) first and only write to "$SECRETS_DIR/anthropic-key" if the captured value
is non-empty: locate the block using CCS_AUTH, ANTHROPIC_FILE and SECRETS_DIR,
run ${pkgs.jq}/bin/jq -r '.api_key // empty' "$ANTHROPIC_FILE" into a variable
(or temp), test that the string is non-empty, and then echo/write it to
"$SECRETS_DIR/anthropic-key" (otherwise skip creating the file); ensure errors
still redirect to /dev/null or are handled as before.
♻️ Duplicate comments (2)
home-manager/modules/clawdbot/default.nix (2)
122-123: Silent failure on chmod masks permission issues.The
chmod 600 ... || truesuppresses errors when no files match or when permission changes fail. While this prevents activation failures, it also hides legitimate problems. Consider at minimum logging when files are protected.
142-143: Ephemeral log location loses logs on reboot.Logging to
/tmp/clawdbot/means logs are lost when the system reboots. For a production gateway service, consider using a persistent location.
🧹 Nitpick comments (2)
home-manager/modules/clawdbot/default.nix (2)
76-79: Consider adding a brief comment explaining the kyber-only restriction.The module is now limited to
host.isKyber && !env.isCI, which is a significant scope change. A short inline comment documenting why this runs only on kyber would help future maintainers understand the design decision.As per coding guidelines, documenting configuration decisions in Nix files is recommended.
📝 Suggested documentation
in -# Only enable on kyber (gateway host) and outside CI +# Only enable on kyber (the designated gateway host for clawdbot service) +# This service requires persistent secrets and systemd user services, +# which are only configured for this specific host. lib.mkIf (host.isKyber && !env.isCI) {
1-156: Consider extracting configurable options.Per coding guidelines, modules should use
mkOptionfor configurable values. Key candidates here include:
enableoption (instead of hardcodedhost.isKyber && !env.isCI)secretsDirpathlogDirpathversionof clawdbotThis would make the module more reusable and self-documenting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 issues found across 6 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="home-manager/programs/fish/functions/_fzf_chrome_history.fish">
<violation number="1" location="home-manager/programs/fish/functions/_fzf_chrome_history.fish:23">
P2: Grouping only by title returns arbitrary url/date per title; recency ordering isn’t guaranteed to reflect the most recent visit.</violation>
</file>
<file name="home-manager/programs/fish/functions/_fzf_shell_history.fish">
<violation number="1" location="home-manager/programs/fish/functions/_fzf_shell_history.fish:1">
P2: Function rename leaves completion definitions still referencing `_fzf_cmd_history`, which will break fish completions/bindings for this command.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| title, | ||
| datetime(last_visit_time/1000000 + strftime('%s', '1601-01-01'), 'unixepoch', 'localtime') as date | ||
| FROM urls | ||
| GROUP BY title |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Grouping only by title returns arbitrary url/date per title; recency ordering isn’t guaranteed to reflect the most recent visit.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/fish/functions/_fzf_chrome_history.fish, line 23:
<comment>Grouping only by title returns arbitrary url/date per title; recency ordering isn’t guaranteed to reflect the most recent visit.</comment>
<file context>
@@ -0,0 +1,51 @@
+ title,
+ datetime(last_visit_time/1000000 + strftime('%s', '1601-01-01'), 'unixepoch', 'localtime') as date
+ FROM urls
+ GROUP BY title
+ ORDER BY last_visit_time DESC
+ LIMIT 10000
</file context>
| @@ -1,6 +1,6 @@ | |||
| function _fzf_cmd_history --description="fzf command history" | |||
| function _fzf_shell_history --description="fzf shell history" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Function rename leaves completion definitions still referencing _fzf_cmd_history, which will break fish completions/bindings for this command.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/fish/functions/_fzf_shell_history.fish, line 1:
<comment>Function rename leaves completion definitions still referencing `_fzf_cmd_history`, which will break fish completions/bindings for this command.</comment>
<file context>
@@ -1,6 +1,6 @@
-function _fzf_cmd_history --description="fzf command history"
+function _fzf_shell_history --description="fzf shell history"
set -l search_term (commandline --current-token)
- set -l prompt_name 'Command History'
</file context>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
home-manager/modules/uv-globals/install-uv-globals.sh (1)
34-51: Fix Python version parsing for ranges/empty values.The current
sedapproach can yield invalid values (e.g.,"3.13.3.14") or empty strings, which breaks the fallback install.✅ Proposed fix
-# Parse Python version from requires-python (e.g., ">=3.13" -> "3.13") -PYTHON_VERSION=$(dasel -f "$PYPROJECT" -r toml 'project.requires-python' 2>/dev/null | sed 's/[^0-9.]//g' || echo "3.13") +# Parse Python version from requires-python (e.g., ">=3.13,<3.14" -> "3.13") +PYTHON_VERSION=$( + dasel -f "$PYPROJECT" -r toml 'project.requires-python' 2>/dev/null \ + | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' \ + | head -n1 || true +) +if [ -z "$PYTHON_VERSION" ]; then + PYTHON_VERSION="3.13" +fi
♻️ Duplicate comments (3)
home-manager/modules/clawdbot/default.nix (2)
139-140: Logs in /tmp will be lost on reboot.The service logs to
/tmp/clawdbot/clawdbot-gateway.logwhich is cleared on system reboot. For a persistent gateway service, consider using a persistent log location like${homeDir}/.local/state/clawdbot/logs/or configure systemd journal logging instead.♻️ Suggested improvement for persistent logging
- StandardOutput = "append:/tmp/clawdbot/clawdbot-gateway.log"; - StandardError = "append:/tmp/clawdbot/clawdbot-gateway.log"; + StandardOutput = "journal"; + StandardError = "journal";Or for file-based persistent logging:
- StandardOutput = "append:/tmp/clawdbot/clawdbot-gateway.log"; - StandardError = "append:/tmp/clawdbot/clawdbot-gateway.log"; + StandardOutput = "append:${homeDir}/.local/state/clawdbot/clawdbot-gateway.log"; + StandardError = "append:${homeDir}/.local/state/clawdbot/clawdbot-gateway.log";If using the file-based approach, update the log directory activation accordingly.
93-98: Potential empty secret file creation.When
jq -r '.api_key // empty'returns empty, the redirection still creates an empty file at$SECRETS_DIR/anthropic-key. This could cause downstream issues if code expects the file to either not exist or contain a valid key.🔧 Suggested fix to avoid empty files
if [ -n "$ANTHROPIC_FILE" ] && [ -f "$ANTHROPIC_FILE" ]; then - ${pkgs.jq}/bin/jq -r '.api_key // empty' "$ANTHROPIC_FILE" 2>/dev/null | tr -d '\n' > "$SECRETS_DIR/anthropic-key" || true + ANTHROPIC_KEY=$(${pkgs.jq}/bin/jq -r '.api_key // empty' "$ANTHROPIC_FILE" 2>/dev/null | tr -d '\n') + if [ -n "$ANTHROPIC_KEY" ]; then + echo -n "$ANTHROPIC_KEY" > "$SECRETS_DIR/anthropic-key" + fi fihome-manager/modules/cargo-globals/install-cargo-globals.sh (1)
86-90: Use// emptyconsistently for git URL extraction.Lines 87-89 correctly use
// emptyfor optional fields, but line 86 doesn't. While the KIND check on line 66 provides some protection, adding// emptywould ensure consistency and prevent edge cases where.value.gitmight be an empty string or malformed.Suggested fix
- GIT_URL=$(echo "$dep" | jq -r '.value.git') + GIT_URL=$(echo "$dep" | jq -r '.value.git // empty')
🧹 Nitpick comments (4)
config/codex/config.toml (1)
8-28: Sort feature flags alphabetically and add explanatory comments.Per coding guidelines, configuration keys should be sorted alphabetically when possible, and complex configurations in TOML files should include comments. The current feature flags are neither sorted nor documented, making it difficult to understand what each flag controls (e.g.,
steer,unified_exec,child_agents_md).♻️ Suggested refactor with alphabetical sorting and placeholder comments
[features] -undo = false -shell_tool = true -web_search_request = false -web_search_cached = false -unified_exec = false -apply_patch_freeform = false -exec_policy = true -experimental_windows_sandbox = false -elevated_windows_sandbox = false -remote_compaction = true -remote_models = true -shell_snapshot = true -child_agents_md = false -powershell_utf8 = false -enable_request_compression = false -collab = false -connectors = false -steer = false -collaboration_modes = true -responses_websockets = false +# Patch application settings +apply_patch_freeform = false + +# Agent and collaboration features +child_agents_md = false +collab = false +collaboration_modes = true +connectors = false + +# Compression and performance +enable_request_compression = false + +# Execution policies +exec_policy = true +unified_exec = false + +# Windows sandbox settings +elevated_windows_sandbox = false +experimental_windows_sandbox = false +powershell_utf8 = false + +# Remote features +remote_compaction = true +remote_models = true +responses_websockets = false + +# Shell and search features +shell_snapshot = true +shell_tool = true +steer = false +undo = false +web_search_cached = false +web_search_request = falsepyproject.toml (1)
2-11: Consider sorting[project]keys alphabetically for consistency.This keeps TOML configs consistent and easier to scan. As per coding guidelines, ...
spec/clawdbot_hydrate_spec.sh (1)
36-56: Tests verify secret file names but not the loading logic.These tests check that certain strings appear in the script (e.g.,
cliproxy-key,telegram-token) but don't verify the actual extraction logic. Consider adding integration tests that mock the secret files and verify the script correctly reads them.home-manager/modules/clawdbot/default.nix (1)
44-55: Silent error suppression may hide build failures.Line 49 uses
|| truewhich will silently ignore missing directories. While this may be intentional for optional components, consider logging when directories are missing to aid debugging.♻️ Suggested improvement
# Copy all relevant directories for the monorepo cp -r dist node_modules package.json $out/lib/clawdbot/ - cp -r extensions ui apps tools $out/lib/clawdbot/ 2>/dev/null || true + for dir in extensions ui apps tools; do + if [ -d "$dir" ]; then + cp -r "$dir" $out/lib/clawdbot/ + fi + done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 (1)
Makefile (1)
153-166: Guard dotagents-sync when the submodule is missing.Since
switchnow depends ondotagents-sync, a fresh clone without submodules will fail. Consider skipping with a clear hint ifdotagents/or its Makefile is absent.🛠️ Suggested update
dotagents-sync: ## Sync dotagents (commands, skills, MCP configuration). - @$(MAKE) -C dotagents sync + `@if` [ -f dotagents/Makefile ]; then \ + $(MAKE) -C dotagents sync; \ + else \ + echo "⚠️ dotagents submodule missing. Run 'make git-submodule-sync' first."; \ + fi
🤖 Fix all issues with AI agents
In `@Makefile`:
- Around line 29-34: NIX_USER_TRUSTED detection only matches '*' or the
username; update the shell expression that sets NIX_USER_TRUSTED to also detect
group-based trust by extracting the trusted-users line and checking whether it
contains any of the current user's groups (entries like `@wheel`), e.g. get the
user's groups via id -nG (or similar) and test if any group name appears in the
trusted-users value prefixed with '@', in addition to the existing checks for
'*' and $(shell whoami); adjust the grep/regex logic around the NIX_USER_TRUSTED
assignment so it returns "yes" when the user is a member of any trusted group.
In `@package.json`:
- Line 30: Add "clawdbot": "^2026.1.24-3" to the package.json
trustedDependencies object so Bun will allow its postinstall script to run;
locate the trustedDependencies key and add the entry exactly as "clawdbot":
"^2026.1.24-3" (ensuring JSON remains valid, comma placement correct).
♻️ Duplicate comments (1)
home-manager/modules/clawdbot/default.nix (1)
21-29: Ensure service directories exist before startup.
WorkingDirectoryand the log file path require directories that aren’t created here. If nothing else creates them, the service can fail to start or open logs. Please verify directory creation elsewhere or add tmpfiles/activation logic.✅ Example using user tmpfiles
lib.mkIf (host.isKyber) { + systemd.user.tmpfiles.rules = [ + "d %h/.clawdbot 0700 - - -" + "d /tmp/clawdbot 0700 - - -" + ]; + systemd.user.services.clawdbot-gateway = { Unit = { Description = "Clawdbot gateway";#!/bin/bash # Check if any other module or script creates the directories rg -n "clawdbot" -C3 rg -n "mkdir -p .*clawdbot" -C3
🧹 Nitpick comments (1)
scripts/upgrade-overlays.sh (1)
9-9: Unused variableOVERLAY_FILE.This variable is defined but never used in the script. If no overlay upgrades are currently configured, consider removing this dead code to avoid confusion.
♻️ Proposed fix
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -OVERLAY_FILE="$REPO_ROOT/overlays/default.nix"
| # Common cache settings (only applied when user is trusted to avoid warnings) | ||
| NIX_SUBSTITUTERS := https://cache.nixos.org https://devenv.cachix.org https://cachix.cachix.org | ||
| NIX_TRUSTED_KEYS := cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw= cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM= | ||
| NIX_CACHIX_CONF := /etc/nix/cachix.conf | ||
| # Check if user is trusted (to avoid "ignoring untrusted substituter" warnings) | ||
| NIX_USER_TRUSTED := $(shell grep -qE "trusted-users.*=.*(\\*|$(shell whoami))" /etc/nix/nix.conf 2>/dev/null && echo "yes" || echo "no") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broaden trusted-user detection to include group-based trust.
trusted-users often uses group entries like @wheel or @admin; Line 34 only checks * or the username, so trusted users in groups will be treated as untrusted and caches won’t be used. Consider matching group memberships too.
🛠️ Suggested update
-NIX_USER_TRUSTED := $(shell grep -qE "trusted-users.*=.*(\\*|$(shell whoami))" /etc/nix/nix.conf 2>/dev/null && echo "yes" || echo "no")
+NIX_USER_TRUSTED := $(shell \
+ user="$(shell whoami)"; \
+ groups="$$(id -Gn "$$user" 2>/dev/null | tr ' ' '\n' | sed 's/^/@/')" ; \
+ pattern="\\*|$$user|$$(printf '%s\n' $$groups | paste -sd'|' -)"; \
+ grep -qE "trusted-users.*=.*($$pattern)" /etc/nix/nix.conf 2>/dev/null && echo "yes" || echo "no")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Common cache settings (only applied when user is trusted to avoid warnings) | |
| NIX_SUBSTITUTERS := https://cache.nixos.org https://devenv.cachix.org https://cachix.cachix.org | |
| NIX_TRUSTED_KEYS := cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw= cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM= | |
| NIX_CACHIX_CONF := /etc/nix/cachix.conf | |
| # Check if user is trusted (to avoid "ignoring untrusted substituter" warnings) | |
| NIX_USER_TRUSTED := $(shell grep -qE "trusted-users.*=.*(\\*|$(shell whoami))" /etc/nix/nix.conf 2>/dev/null && echo "yes" || echo "no") | |
| # Common cache settings (only applied when user is trusted to avoid warnings) | |
| NIX_SUBSTITUTERS := https://cache.nixos.org https://devenv.cachix.org https://cachix.cachix.org | |
| NIX_TRUSTED_KEYS := cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw= cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM= | |
| NIX_CACHIX_CONF := /etc/nix/cachix.conf | |
| # Check if user is trusted (to avoid "ignoring untrusted substituter" warnings) | |
| NIX_USER_TRUSTED := $(shell \ | |
| user="$(shell whoami)"; \ | |
| groups="$$(id -Gn "$$user" 2>/dev/null | tr ' ' '\n' | sed 's/^/@/')" ; \ | |
| pattern="\\*|$$user|$$(printf '%s\n' $$groups | paste -sd'|' -)"; \ | |
| grep -qE "trusted-users.*=.*($$pattern)" /etc/nix/nix.conf 2>/dev/null && echo "yes" || echo "no") |
🤖 Prompt for AI Agents
In `@Makefile` around lines 29 - 34, NIX_USER_TRUSTED detection only matches '*'
or the username; update the shell expression that sets NIX_USER_TRUSTED to also
detect group-based trust by extracting the trusted-users line and checking
whether it contains any of the current user's groups (entries like `@wheel`), e.g.
get the user's groups via id -nG (or similar) and test if any group name appears
in the trusted-users value prefixed with '@', in addition to the existing checks
for '*' and $(shell whoami); adjust the grep/regex logic around the
NIX_USER_TRUSTED assignment so it returns "yes" when the user is a member of any
trusted group.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="home-manager/modules/clawdbot/default.nix">
<violation number="1" location="home-manager/modules/clawdbot/default.nix:21">
P2: Log directory is created only during activation, but logs are written to /tmp on every service start; /tmp is volatile so the directory can be missing after reboot, causing logging or service start failures.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
…ript - Added `git-ai` dependency to `Cargo.toml` from the main branch of the GitHub repository. - Updated `install-cargo-globals.sh` to support parsing of git dependencies and handle version strings more robustly. - Improved the logic for installing dependencies, including support for git repositories with branch, tag, and revision options. - Modified `default.nix` to update the pnpmDepsHash for clawdbot. - Enhanced `upgrade-overlays.sh` to dynamically detect platform and build configuration for better compatibility. - Updated tests in `cargo_globals_spec.sh` to verify support for new dependency formats and installation methods.
…d git-ai checkpoint hooks
…tra-openai-models.yaml
…ns and add clawdbot_hydrate_spec.sh for testing
…unctionality and Python version support
… execution and refactor default.nix for improved readability
…ve JSON formatting
- Added clawdbot dependency to package.json. - Refactored upgrade-overlays.sh script to simplify usage and remove unnecessary functions. - Updated usage instructions to reflect changes in command structure. - Removed clawdbot upgrade logic from the script as it is no longer configured. - Updated tests to reflect the removal of clawdbot upgrade functionality and adjusted output expectations.
…om clawdbot service configuration
- Pre-install Node 22 and 20 via activation script - Set Node 22 as default version - Create stable ~/.local/bin/node symlink for systemd services - Remove hardcoded node path from clawdbot module (now managed by fnm)
Changes
Testing
Generated with opencode by claude-sonnet
Summary by cubic
Standardized models on glm-4.7 and added git-ai checkpoint hooks across Cursor, Gemini, and Claude. Improved routing, cross-platform cargo installs, and automated overlay upgrade PRs with auto-merge; plus small fish history UX updates.
New Features
Refactors
Written for commit c8b0c12. Summary will update on new commits.