Skip to content
Merged
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,8 @@ llm-update: ## Regenerate tool configs from models.json.
.PHONY: overlays-update
overlays-update: ## Upgrade all custom overlays to latest versions.
@echo "🔄 Upgrading custom overlays..."
@if [ "$$CI" = "true" ] || [ "$$IN_DOCKER" = "true" ]; then \
echo "⏭️ Skipping overlay upgrade in CI/Docker"; \
@if [ "$$IN_DOCKER" = "true" ]; then \
echo "⏭️ Skipping overlay upgrade in Docker"; \
else \
./scripts/upgrade-overlays.sh all; \
fi
Expand Down
1 change: 1 addition & 0 deletions home-manager/packages/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ with pkgs;
claude-code
cmake
codex
moshi-hook

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.

medium

The package list under lib.optionals stdenv.isLinux is sorted alphabetically. moshi-hook should be moved to its correct alphabetical position, which is between libsecret and opencode.

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.

Nit — alphabetical ordering: this Linux block is sorted alphabetically (atop, below, binutils, blueman, bubblewrap, claude-code, cmake, codex, collectd, fwupd, gcc, gemini-cli, glib, keychain, libiconv, libsecret, opencode, ...). moshi-hook should sit between libsecret and opencode, not between codex and collectd.

collectd
fwupd
gcc
Expand Down
2 changes: 1 addition & 1 deletion home-manager/services/moshi-hook/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ in
};
Service = {
Type = "simple";
ExecStart = "%h/.local/bin/moshi-hook serve";
ExecStart = "${pkgs.moshi-hook}/bin/moshi-hook serve";
Restart = "always";
RestartSec = 5;
};
Expand Down
27 changes: 27 additions & 0 deletions overlays/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,33 @@
}
)
inputs.noctalia-shell.overlays.default
(_: prev: {
moshi-hook = prev.stdenv.mkDerivation rec {
pname = "moshi-hook";
version = "0.2.69";
src = prev.fetchurl {
url = "https://cdn.getmoshi.app/hook/v${version}/moshi-hook_${
if prev.stdenv.isDarwin then "Darwin" else "Linux"
}_${if prev.stdenv.hostPlatform.isAarch64 then "arm64" else "x86_64"}.tar.gz";
sha256 =
if prev.stdenv.isLinux && prev.stdenv.hostPlatform.isx86_64 then
"3903e2e5d1dba02f9e1f53df8cea6e2b3260e1581461b9a07ca65f18814b8b08"
else if prev.stdenv.isLinux && prev.stdenv.hostPlatform.isAarch64 then
"0a30e081399543551bbd0ba3320f3b28be814a585e5c591e168f8fd6d9565f07"
else if prev.stdenv.isDarwin && prev.stdenv.hostPlatform.isAarch64 then
"52258126b675dad210a8f04b83d8e90b359951af37474ff985d2c3f49102d981"
else
"7cf24d316bafffc59d30e05d6ad6b27d4c03c9953ce901056f57f03c25e4b83b";
};
sourceRoot = ".";
dontConfigure = true;
dontBuild = true;
Comment on lines +95 to +96

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.

medium

For prebuilt binaries (especially Go binaries or binaries running on macOS), stripping them can corrupt the executable or invalidate ad-hoc code signatures (leading to Killed: 9 errors). It is highly recommended to set dontStrip = true; to prevent Nix from attempting to strip the binary.

      dontConfigure = true;
      dontBuild = true;
      dontStrip = true;

installPhase = ''
install -Dm755 moshi-hook $out/bin/moshi-hook
ln -s moshi-hook $out/bin/moshi

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.

Nit — the moshi symlink is unused. grep -rn '\bmoshi\b' across the repo shows only moshi-hook invocations (systemd unit, hooks.json, moshi-hooks.ts, homebrew cask). Unless upstream expects both names, this symlink can be removed to keep the derivation minimal.

'';
};
})
(final: prev: {
nightlyPkgs = import inputs.nixpkgs-nightly {
inherit (prev) system config;
Expand Down
119 changes: 110 additions & 9 deletions scripts/upgrade-overlays.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
#!/usr/bin/env bash
# Extensible overlay upgrade script
# Usage: ./scripts/upgrade-overlays.sh <target>
# Usage: ./scripts/upgrade-overlays.sh <overlay|all>

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
OVERLAY_FILE="${OVERLAY_FILE:-$REPO_ROOT/overlays/default.nix}"
MOSHI_HOOK_CDN="${MOSHI_HOOK_CDN:-https://cdn.getmoshi.app}"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# --- Common utilities ---

log_info() {
echo -e "${GREEN}$1${NC}"
}
Expand All @@ -25,15 +28,109 @@ log_error() {
}

usage() {
echo "Usage: $0 <target>"
echo "Usage: $0 <overlay|all>"
echo ""
echo "Available commands:"
echo " all - Run all overlay upgrades (none configured yet)"
echo "Available overlays:"
echo " moshi-hook - Upgrade the pinned moshi-hook binaries"
echo " all - Upgrade all overlays"
echo ""
echo "Examples:"
echo " $0 moshi-hook"
echo " $0 all"
}

require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
log_error "Missing required dependency: $1"
exit 1
fi
}

checksum_for() {
local asset="$1"
awk -v asset="$asset" '$2 == asset { print $1; found = 1; exit } END { if (!found) exit 1 }' "$MOSHI_CHECKSUMS_FILE"
}

validate_checksum() {
local asset="$1"
local checksum="$2"
if [[ ! $checksum =~ ^[[:xdigit:]]{64}$ ]]; then
log_error "Invalid checksum for $asset"
exit 1
fi
}

upgrade_moshi_hook() {
local latest_version version current_version
local linux_x86_64 linux_arm64 darwin_arm64 darwin_x86_64

latest_version="$(curl -fsSL "$MOSHI_HOOK_CDN/hook/latest/version.txt" | tr -d '[:space:]')"
case "$latest_version" in
v*) version="${latest_version#v}" ;;
*) version="$latest_version" ;;
esac

if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
log_error "Invalid moshi-hook version: $latest_version"
exit 1
fi

current_version="$(sed -n '/moshi-hook = prev.stdenv.mkDerivation rec {/,/sourceRoot =/p' "$OVERLAY_FILE" | sed -n 's/.*version = "\([^"]*\)";.*/\1/p' | head -1)"
echo " Current version: ${current_version:-unknown}"
echo " Latest version: $version"

MOSHI_CHECKSUMS_FILE="$(mktemp)"
curl -fsSL "$MOSHI_HOOK_CDN/hook/v$version/checksums.txt" -o "$MOSHI_CHECKSUMS_FILE"

linux_x86_64="$(checksum_for moshi-hook_Linux_x86_64.tar.gz)"
linux_arm64="$(checksum_for moshi-hook_Linux_arm64.tar.gz)"
darwin_arm64="$(checksum_for moshi-hook_Darwin_arm64.tar.gz)"
darwin_x86_64="$(checksum_for moshi-hook_Darwin_x86_64.tar.gz)"
validate_checksum moshi-hook_Linux_x86_64.tar.gz "$linux_x86_64"
validate_checksum moshi-hook_Linux_arm64.tar.gz "$linux_arm64"
validate_checksum moshi-hook_Darwin_arm64.tar.gz "$darwin_arm64"
validate_checksum moshi-hook_Darwin_x86_64.tar.gz "$darwin_x86_64"

if [[ $current_version == "$version" ]]; then
rm -f "$MOSHI_CHECKSUMS_FILE"
log_info "✅ moshi-hook is already on latest version ($version)"
return 0
fi

awk \
-v version="$version" \
-v linux_x86_64="$linux_x86_64" \
-v linux_arm64="$linux_arm64" \
-v darwin_arm64="$darwin_arm64" \
-v darwin_x86_64="$darwin_x86_64" '
/moshi-hook = prev.stdenv.mkDerivation rec \{/ { in_moshi = 1 }
in_moshi && /version = "[^"]*";/ {
sub(/version = "[^"]*";/, "version = \"" version "\";")
}
in_moshi && /isLinux && prev.stdenv.hostPlatform.isx86_64 then/ { pending_hash = linux_x86_64 }
in_moshi && /isLinux && prev.stdenv.hostPlatform.isAarch64 then/ { pending_hash = linux_arm64 }
in_moshi && /isDarwin && prev.stdenv.hostPlatform.isAarch64 then/ { pending_hash = darwin_arm64 }
in_moshi && /^ else$/ { pending_hash = darwin_x86_64 }
in_moshi && pending_hash != "" && $0 ~ /^[[:space:]]*"[^"]*";?$/ {
sub(/"[^"]*"/, "\"" pending_hash "\"")
pending_hash = ""
updated_hashes++
}
in_moshi && /^ \};$/ { in_moshi = 0 }
{ print }
END {
if (updated_hashes != 4) {
print "expected four moshi-hook checksums in " FILENAME > "/dev/stderr"
exit 1
}
}
' "$OVERLAY_FILE" >"$OVERLAY_FILE.tmp"
mv -f "$OVERLAY_FILE.tmp" "$OVERLAY_FILE"
rm -f "$MOSHI_CHECKSUMS_FILE"

log_info "✅ moshi-hook upgraded from ${current_version:-unknown} to $version"
}

main() {
local target="${1:-}"

Expand All @@ -43,14 +140,18 @@ main() {
fi

case "$target" in
all)
log_warn "No overlay upgrades configured."
moshi-hook | all)
require_command awk
require_command curl
require_command sed
require_command tr
upgrade_moshi_hook
;;
-h | --help)
usage
;;
*)
log_error "Unknown command: $target"
log_error "Unknown overlay: $target"
echo ""
usage
exit 1
Expand Down
67 changes: 60 additions & 7 deletions spec/upgrade_overlays_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ It 'shows usage when called without arguments'
When run bash "$SCRIPT"
The output should include 'Usage:'
The output should include 'upgrade-overlays.sh'
The output should include 'moshi-hook'
The output should include 'all'
The status should be failure
End

It 'shows usage with --help flag'
When run bash "$SCRIPT" --help
The output should include 'Usage:'
The output should include 'Available commands:'
The output should include 'Available overlays:'
The status should be success
End

Expand All @@ -30,16 +31,68 @@ End
Describe 'unknown overlay handling'
It 'fails for unknown overlay'
When run bash "$SCRIPT" unknown-overlay
The output should include 'Unknown command: unknown-overlay'
The output should include 'Available commands'
The output should include 'Unknown overlay: unknown-overlay'
The output should include 'Available overlays'
The status should be failure
End
End

Describe 'all overlay target'
It 'reports no overlays configured'
When run bash "$SCRIPT" all
The output should include 'No overlay upgrades configured.'
Describe 'moshi-hook overlay target'
setup() {
TEMP_DIR=$(mktemp -d)
mkdir -p "$TEMP_DIR/cdn/hook/latest" "$TEMP_DIR/cdn/hook/v0.2.69" "$TEMP_DIR/overlays"
printf 'v0.2.69\n' >"$TEMP_DIR/cdn/hook/latest/version.txt"
cat >"$TEMP_DIR/cdn/hook/v0.2.69/checksums.txt" <<'EOF'
52258126b675dad210a8f04b83d8e90b359951af37474ff985d2c3f49102d981 moshi-hook_Darwin_arm64.tar.gz
7cf24d316bafffc59d30e05d6ad6b27d4c03c9953ce901056f57f03c25e4b83b moshi-hook_Darwin_x86_64.tar.gz
0a30e081399543551bbd0ba3320f3b28be814a585e5c591e168f8fd6d9565f07 moshi-hook_Linux_arm64.tar.gz
3903e2e5d1dba02f9e1f53df8cea6e2b3260e1581461b9a07ca65f18814b8b08 moshi-hook_Linux_x86_64.tar.gz
EOF
cat >"$TEMP_DIR/overlays/default.nix" <<'EOF'
{ inputs }:
[
(_: prev: {
moshi-hook = prev.stdenv.mkDerivation rec {
pname = "moshi-hook";
version = "0.2.55";
src = prev.fetchurl {
sha256 =
if prev.stdenv.isLinux && prev.stdenv.hostPlatform.isx86_64 then
"old-linux-x86"
else if prev.stdenv.isLinux && prev.stdenv.hostPlatform.isAarch64 then
"old-linux-arm"
else if prev.stdenv.isDarwin && prev.stdenv.hostPlatform.isAarch64 then
"old-darwin-arm"
else
"old-darwin-x86";
};
sourceRoot = ".";
};
})
]
EOF
}

cleanup() {
rm -rf "$TEMP_DIR"
}

Before 'setup'
After 'cleanup'

It 'updates moshi-hook from the all target'
When run env OVERLAY_FILE="$TEMP_DIR/overlays/default.nix" MOSHI_HOOK_CDN="file://$TEMP_DIR/cdn" bash "$SCRIPT" all
The output should include 'moshi-hook upgraded from 0.2.55 to 0.2.69'
The status should be success
End

It 'updates the version and all platform checksums'
When run bash -c "env OVERLAY_FILE='$TEMP_DIR/overlays/default.nix' MOSHI_HOOK_CDN='file://$TEMP_DIR/cdn' bash '$SCRIPT' moshi-hook >/dev/null && cat '$TEMP_DIR/overlays/default.nix'"
The output should include 'version = "0.2.69"'
The output should include '3903e2e5d1dba02f9e1f53df8cea6e2b3260e1581461b9a07ca65f18814b8b08'
The output should include '0a30e081399543551bbd0ba3320f3b28be814a585e5c591e168f8fd6d9565f07'
The output should include '52258126b675dad210a8f04b83d8e90b359951af37474ff985d2c3f49102d981'
The output should include '7cf24d316bafffc59d30e05d6ad6b27d4c03c9953ce901056f57f03c25e4b83b'
The status should be success
End
End
Expand Down
Loading