Skip to content
Merged

Dankman #1272

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions config/claude/notify.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#!/usr/bin/env bash

# Claude Code Local Notification Script
# Sends macOS notifications via osascript
# Skips if Pushover is configured (to avoid duplicate notifications)
# Claude Code local notification script.
# Uses the shared local notifier and skips local popups when Pushover is configured.

# Source credentials to check if Pushover is configured
if [ -z "$PUSHOVER_API_TOKEN" ] || [ -z "$PUSHOVER_USER_KEY" ]; then
Expand All @@ -22,14 +21,22 @@ fi
# Read JSON input from stdin
input=$(cat)

# Function to send local macOS notification
# Function to send a local notification on the active platform
notify() {
local message="$1"
local sound="${2:-Sonar}"
local notifier

[ -z "$message" ] && return

osascript -e "display notification \"${message}\" with title \"Claude Code\" sound name \"${sound}\"" 2>/dev/null
notifier="$(command -v notify-local 2>/dev/null || true)"
if [ -z "$notifier" ] && [ -x "$HOME/.local/scripts/notify-local" ]; then
notifier="$HOME/.local/scripts/notify-local"
fi

if [ -n "$notifier" ]; then
"$notifier" "Claude Code" "$message" "$sound"
fi
}

# Handle Notification hook
Expand Down
2 changes: 1 addition & 1 deletion config/codex/config.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
notify = [
"bash",
"-lc",
"JSON=\"$1\"; LAST_MESSAGE=$(echo \"$JSON\" | jq -r '.\"last-assistant-message\" // \"Codex task completed\"'); osascript -e \"display notification \\\"$LAST_MESSAGE\\\" with title \\\"Codex\\\"\"",
"JSON=\"$1\"; LAST_MESSAGE=$(echo \"$JSON\" | jq -r '.\"last-assistant-message\" // \"Codex task completed\"'); \"$HOME/.local/scripts/notify-local\" \"Codex\" \"$LAST_MESSAGE\"",
"notify",
]

Expand Down
2 changes: 1 addition & 1 deletion config/codex/config.tpl.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
notify = [
"bash",
"-lc",
"JSON=\"$1\"; LAST_MESSAGE=$(echo \"$JSON\" | jq -r '.\"last-assistant-message\" // \"Codex task completed\"'); osascript -e \"display notification \\\"$LAST_MESSAGE\\\" with title \\\"Codex\\\"\"",
"JSON=\"$1\"; LAST_MESSAGE=$(echo \"$JSON\" | jq -r '.\"last-assistant-message\" // \"Codex task completed\"'); \"$HOME/.local/scripts/notify-local\" \"Codex\" \"$LAST_MESSAGE\"",
"notify",
]

Expand Down
7 changes: 1 addition & 6 deletions config/ghostty/config
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
#

auto-update-channel = tip
# theme = dark:Dracula,light:Catppuccin Latte
theme = Dracula
theme = dark:Dracula Custom,light:Catppuccin Latte Custom
background-opacity = 0.8
confirm-close-surface = true
macos-option-as-alt = true
Expand Down Expand Up @@ -47,9 +46,5 @@ keybind = ctrl+shift+z=toggle_split_zoom
keybind = ctrl+shift+e=equalize_splits
keybind = ctrl+shift+w=close_surface

# Split border styling
split-divider-color = #88c0d0

# Active panel highlighting (dim unfocused splits)
unfocused-split-opacity = 0.7
unfocused-split-fill = #1e1e2e
6 changes: 6 additions & 0 deletions config/ghostty/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@ in
xdg.configFile."ghostty/config" = {
text = configText;
};
xdg.configFile."ghostty/themes/Dracula Custom" = {
source = ./themes + "/Dracula Custom";
};
xdg.configFile."ghostty/themes/Catppuccin Latte Custom" = {
source = ./themes + "/Catppuccin Latte Custom";
Comment on lines +11 to +15

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using theme filenames with spaces and building the source path via string concatenation is fragile in Nix/Home Manager (spaces can cause awkward store name/path handling, and string-vs-path coercion can be surprising). Consider renaming the theme files to space-free names (e.g., Dracula-Custom, Catppuccin-Latte-Custom) and referencing them as proper Nix paths so source is unambiguously a path.

Suggested change
xdg.configFile."ghostty/themes/Dracula Custom" = {
source = ./themes + "/Dracula Custom";
};
xdg.configFile."ghostty/themes/Catppuccin Latte Custom" = {
source = ./themes + "/Catppuccin Latte Custom";
xdg.configFile."ghostty/themes/Dracula-Custom" = {
source = ./themes/Dracula-Custom;
};
xdg.configFile."ghostty/themes/Catppuccin-Latte-Custom" = {
source = ./themes/Catppuccin-Latte-Custom;

Copilot uses AI. Check for mistakes.
};
}
24 changes: 24 additions & 0 deletions config/ghostty/themes/Catppuccin Latte Custom
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
palette = 0=#5c5f77
palette = 1=#d20f39
palette = 2=#40a02b
palette = 3=#df8e1d
palette = 4=#1e66f5
palette = 5=#ea76cb
palette = 6=#179299
palette = 7=#acb0be
palette = 8=#6c6f85
palette = 9=#de293e
palette = 10=#49af3d
palette = 11=#eea02d
palette = 12=#456eff
palette = 13=#fe85d8
palette = 14=#2d9fa8
palette = 15=#bcc0cc
background = #eff1f5
foreground = #4c4f69
cursor-color = #dc8a78
cursor-text = #eff1f5
selection-background = #acb0be
selection-foreground = #4c4f69
unfocused-split-fill = #dce0e8
split-divider-color = #7287fd
24 changes: 24 additions & 0 deletions config/ghostty/themes/Dracula Custom
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
palette = 0=#21222c
palette = 1=#ff5555
palette = 2=#50fa7b
palette = 3=#f1fa8c
palette = 4=#bd93f9
palette = 5=#ff79c6
palette = 6=#8be9fd
palette = 7=#f8f8f2
palette = 8=#6272a4
palette = 9=#ff6e6e
palette = 10=#69ff94
palette = 11=#ffffa5
palette = 12=#d6acff
palette = 13=#ff92df
palette = 14=#a4ffff
palette = 15=#ffffff
background = #282a36
foreground = #f8f8f2
cursor-color = #f8f8f2
cursor-text = #282a36
selection-background = #44475a
selection-foreground = #ffffff
unfocused-split-fill = #1e1e2e
split-divider-color = #88c0d0
14 changes: 1 addition & 13 deletions config/gtk/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
gtk = lib.mkIf pkgs.stdenv.isLinux {
enable = true;
theme = {
name = "Adwaita-dark";
name = "Adwaita";
package = pkgs.gnome-themes-extra;
};
iconTheme = {
Expand All @@ -19,17 +19,5 @@
name = "Adwaita";
size = 24;
};
gtk3.extraConfig = {
gtk-application-prefer-dark-theme = 1;
};
gtk4.extraConfig = {
gtk-application-prefer-dark-theme = 1;
};
};

dconf.settings = lib.mkIf pkgs.stdenv.isLinux {
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
};
}
1 change: 0 additions & 1 deletion config/hyprland/hyprland.conf
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ env = XCURSOR_THEME,Adwaita
env = XCURSOR_SIZE,24
env = HYPRCURSOR_SIZE,24
env = HYPRCURSOR_THEME,Adwaita
env = GTK_THEME,Adwaita:dark
env = GDK_SCALE,1.5
env = QT_AUTO_SCREEN_SCALE_FACTOR,1
env = QT_QPA_PLATFORM,wayland
Expand Down
1 change: 1 addition & 0 deletions home-manager/modules/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
./cargo-globals
./openclaw
./local-binaries
./local-scripts
./npm-globals
./tailscale
./uv-globals
Expand Down
22 changes: 22 additions & 0 deletions home-manager/modules/local-scripts/clipboard-copy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash

set -euo pipefail

if command -v pbcopy >/dev/null 2>&1; then
exec pbcopy
fi

if [[ -n ${WAYLAND_DISPLAY:-} ]] && command -v wl-copy >/dev/null 2>&1; then
exec wl-copy
fi

if command -v xclip >/dev/null 2>&1; then
exec xclip -selection clipboard
fi

if command -v xsel >/dev/null 2>&1; then
exec xsel --clipboard --input
fi

printf 'No clipboard backend available\n' >&2
exit 1
13 changes: 13 additions & 0 deletions home-manager/modules/local-scripts/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{ ... }:
{
home.file.".local/scripts/clipboard-copy" = {
executable = true;
force = true;
source = ./clipboard-copy.sh;
};
home.file.".local/scripts/notify-local" = {
executable = true;
force = true;
source = ./notify-local.sh;
};
}
50 changes: 50 additions & 0 deletions home-manager/modules/local-scripts/notify-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env bash

set -euo pipefail

title="${1:-Notification}"
message="${2:-}"
sound="${3:-}"

if [[ -z $message ]]; then
exit 0
fi

title="${title//$'\n'/ }"
message="${message//$'\n'/ }"
sound="${sound//$'\n'/ }"

escape_applescript() {
local value="$1"

value="${value//\\/\\\\}"
value="${value//\"/\\\"}"

printf '%s' "$value"
}

if command -v osascript >/dev/null 2>&1; then
escaped_title="$(escape_applescript "$title")"
escaped_message="$(escape_applescript "$message")"

if [[ -n $sound ]]; then
escaped_sound="$(escape_applescript "$sound")"
osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\" sound name \"$escaped_sound\"" >/dev/null 2>&1 || true
else
osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\"" >/dev/null 2>&1 || true

@cubic-dev-ai cubic-dev-ai Bot Mar 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The osascript path always exits even on failure, so fallback notifiers are never attempted when osascript is present but unusable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/modules/scripts/notify-local.sh, line 34:

<comment>The osascript path always exits even on failure, so fallback notifiers are never attempted when osascript is present but unusable.</comment>

<file context>
@@ -0,0 +1,50 @@
+    escaped_sound="$(escape_applescript "$sound")"
+    osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\" sound name \"$escaped_sound\"" >/dev/null 2>&1 || true
+  else
+    osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\"" >/dev/null 2>&1 || true
+  fi
+
</file context>
Fix with Cubic

fi

exit 0
fi

if command -v notify-send >/dev/null 2>&1; then
notify-send "$title" "$message" >/dev/null 2>&1 || true
exit 0
fi

if command -v terminal-notifier >/dev/null 2>&1; then
terminal-notifier -title "$title" -message "$message" >/dev/null 2>&1 || true
exit 0
fi
Comment on lines +26 to +48

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fallback chain exits even when the chosen backend fails.

Line 32/34/41/46 suppress errors with || true, then Line 37/42/47 unconditionally exits. If osascript or notify-send exists but fails at runtime, the script won’t try the next backend.

Suggested fix
 if command -v osascript >/dev/null 2>&1; then
   escaped_title="$(escape_applescript "$title")"
   escaped_message="$(escape_applescript "$message")"

   if [[ -n "$sound" ]]; then
     escaped_sound="$(escape_applescript "$sound")"
-    osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\" sound name \"$escaped_sound\"" >/dev/null 2>&1 || true
+    if osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\" sound name \"$escaped_sound\"" >/dev/null 2>&1; then
+      exit 0
+    fi
   else
-    osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\"" >/dev/null 2>&1 || true
+    if osascript -e "display notification \"$escaped_message\" with title \"$escaped_title\"" >/dev/null 2>&1; then
+      exit 0
+    fi
   fi
-
-  exit 0
 fi

 if command -v notify-send >/dev/null 2>&1; then
-  notify-send "$title" "$message" >/dev/null 2>&1 || true
-  exit 0
+  if notify-send "$title" "$message" >/dev/null 2>&1; then
+    exit 0
+  fi
 fi

 if command -v terminal-notifier >/dev/null 2>&1; then
-  terminal-notifier -title "$title" -message "$message" >/dev/null 2>&1 || true
-  exit 0
+  terminal-notifier -title "$title" -message "$message" >/dev/null 2>&1 || true
 fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@home-manager/modules/scripts/notify-local.sh` around lines 26 - 48, The
fallback logic currently suppresses failures with "|| true" and then
unconditionally exits, so if osascript/notify-send/terminal-notifier exists but
fails the script won't try the next backend; change each backend block (the
osascript block that uses escaped_title/escaped_message/escaped_sound, the
notify-send invocation, and the terminal-notifier invocation) to run the
notification command without "|| true" and only exit 0 when that command returns
success (e.g. command && exit 0 or capture the exit status and conditionally
exit), so a runtime failure will fall through to the next backend.


exit 0
1 change: 1 addition & 0 deletions home-manager/programs/bash/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
export PATH="$HOME/.nix-profile/bin:$PATH"
export PATH="$HOME/.cargo/bin:$PATH"
export PATH="$HOME/.local/bin:$PATH"
export PATH="$HOME/.local/scripts:$PATH"
export PATH="$HOME/.bun/bin:$PATH"
export PATH="/opt/homebrew/opt/postgresql@18/bin:$PATH"
export PATH="/opt/homebrew/bin:$PATH"
Expand Down
2 changes: 2 additions & 0 deletions home-manager/programs/fish/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
fish_add_path -p -m ~/go/bin
fish_add_path -p -m ~/.cargo/bin
fish_add_path -p -m ~/.local/bin
fish_add_path -p -m ~/.local/scripts
fish_add_path -p -m ~/.bun/bin
fish_add_path -p -m /opt/homebrew/opt/postgresql@18/bin
fish_add_path -p -m /opt/homebrew/bin
Expand All @@ -60,6 +61,7 @@
fish_add_path -p -m ~/go/bin
fish_add_path -p -m ~/.cargo/bin
fish_add_path -p -m ~/.local/bin
fish_add_path -p -m ~/.local/scripts
fish_add_path -p -m ~/.bun/bin
fish_add_path -p -m /opt/homebrew/opt/postgresql@18/bin
fish_add_path -p -m /opt/homebrew/bin
Expand Down
2 changes: 1 addition & 1 deletion home-manager/programs/tmux/tmux.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ set-option -g repeat-time 1000

# Clipboard
set -g set-clipboard on
set -g @clipboard_cmd "command -v pbcopy >/dev/null 2>&1 && pbcopy || { [ -n \"$WAYLAND_DISPLAY\" ] && wl-copy || xclip -selection clipboard; }"
set -g @clipboard_cmd "~/.local/scripts/clipboard-copy"

# Status bar
set -g status "on"
Expand Down
1 change: 1 addition & 0 deletions home-manager/programs/zsh/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
export PATH="$HOME/.nix-profile/bin:$PATH"
export PATH="$HOME/.cargo/bin:$PATH"
export PATH="$HOME/.local/bin:$PATH"
export PATH="$HOME/.local/scripts:$PATH"
export PATH="$HOME/.bun/bin:$PATH"
export PATH="/opt/homebrew/opt/postgresql@18/bin:$PATH"
export PATH="/opt/homebrew/bin:$PATH"
Expand Down
5 changes: 5 additions & 0 deletions home-manager/services/darkman/dark-mode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail

@dconf@ write /org/gnome/desktop/interface/color-scheme "'prefer-dark'"
@dconf@ write /org/gnome/desktop/interface/gtk-theme "'Adwaita-dark'"
20 changes: 20 additions & 0 deletions home-manager/services/darkman/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ pkgs, ... }:
let
inherit (pkgs) lib;
dconf = "${pkgs.dconf}/bin/dconf";
readScript = file: builtins.replaceStrings [ "@dconf@" ] [ dconf ] (builtins.readFile file);
in
{
services.darkman = lib.mkIf pkgs.stdenv.isLinux {

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title suggests the scope is Darkman-focused, but the changes also introduce clipboard/notification helper binaries and Ghostty theme updates. Consider updating the PR title/description to reflect the broader scope or splitting the unrelated changes into separate PRs to make review and rollback safer.

Copilot uses AI. Check for mistakes.
enable = true;
settings = {
usegeoclue = true;
};
darkModeScripts = {
gtk-theme = readScript ./dark-mode.sh;
};
lightModeScripts = {
gtk-theme = readScript ./light-mode.sh;
};
Comment on lines +13 to +18

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These scripts only update GNOME dconf keys. However, Home Manager’s gtk.theme.name typically writes ~/.config/gtk-3.0/settings.ini / gtk-4.0/settings.ini (and similar), which many GTK apps read directly. That can lead to inconsistent theming where apps remain on the statically configured theme even after Darkman toggles dconf. To keep behavior consistent, either (a) have Darkman scripts also update the GTK settings.ini theme entries, or (b) avoid enforcing a static gtk.theme.name and rely on a single source of truth for theme switching.

Copilot uses AI. Check for mistakes.
};
}
5 changes: 5 additions & 0 deletions home-manager/services/darkman/light-mode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail

@dconf@ write /org/gnome/desktop/interface/color-scheme "'prefer-light'"
@dconf@ write /org/gnome/desktop/interface/gtk-theme "'Adwaita'"
2 changes: 2 additions & 0 deletions home-manager/services/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ let
brewUpgrader = import ./brew-upgrader { inherit pkgs; };
cliproxyapi = import ./cliproxyapi;
codeSyncer = import ./code-syncer { inherit pkgs; };
darkman = import ./darkman { inherit pkgs; };
docker = import ./docker { inherit lib pkgs; };
dockerPostgres = import ./docker-postgres { inherit pkgs; };
dotfilesUpdater = import ./dotfiles-updater { inherit pkgs; };
Expand All @@ -23,6 +24,7 @@ in
brewUpgrader
cliproxyapi
codeSyncer
darkman
docker
dockerPostgres
dotfilesUpdater
Expand Down
5 changes: 4 additions & 1 deletion named-hosts/matic/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,10 @@ inputs.nixpkgs.lib.nixosSystem {
"hyprland"
"gtk"
];
"org.freedesktop.impl.portal.Settings" = [ "gtk" ];
"org.freedesktop.impl.portal.Settings" = [
"darkman"
"gtk"
];
};
};
};
Expand Down
Loading
Loading