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
16 changes: 14 additions & 2 deletions bin/gs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ changed_part() {
}

cmd_sync() {
local repo shell bin="$HOME/.local/share/gentle-ai/main" reg="$HOME/.pi/gentle-ai/dev-binary.json" name
local ai_files="" repo shell bin="$HOME/.local/share/gentle-ai/main" reg="$HOME/.pi/gentle-ai/dev-binary.json" name
# Versions before the sync power the closing message: restart only on change.
local shell_before ai_before engram_before
shell_before=$(shell_version); ai_before=$(ai_version); engram_before=$(engram_version)
Expand Down Expand Up @@ -353,7 +353,16 @@ cmd_sync() {
else
local ai_sync=(sync)
[ -n "${GS_SYNC_AGENTS:-}" ] && ai_sync+=(--agents "$GS_SYNC_AGENTS")
run_quiet 'gentle-ai sync' "$ai_bin" "${ai_sync[@]}"
# Like run_quiet, but keeps the output: its file count feeds the restart hint.
local ai_out; ai_out=$(mktemp)
if "$ai_bin" "${ai_sync[@]}" >"$ai_out" 2>&1; then
printf ' %-34s ok\n' 'gentle-ai sync'
else
printf ' %-34s FAILED\n' 'gentle-ai sync'
sed 's/^/ /' "$ai_out"
fi
ai_files=$(sed -n 's/^Sync actions executed: \([0-9][0-9]*\) files* changed.*/\1/p' "$ai_out" | head -1)
rm -f "$ai_out"
fi
# gs sync is the only upgrade path; older homemade scripts drift the hosts apart.
for name in "$HOME/.local/bin/gentle-maintainer-upgrade" "$HOME/.local/bin/gentle-sync.sh" \
Expand Down Expand Up @@ -385,6 +394,9 @@ cmd_sync() {
if is_workshop && grep -qE 'npm:gentle-(pi|engram)|git:github.com/Gentleman-Programming/gentle-(pi|shell)' "$HOME/.pi/agent/settings.json" 2>/dev/null; then
printf 'WARN: ~/.pi/agent/settings.json lists a published gentle-pi/gentle-engram again; remove it\n'
fi
if [ -n "$ai_files" ] && [ "$ai_files" -gt 0 ]; then
changed="$changed managed configs ($ai_files files)"
fi
if [ -n "$changed" ]; then
printf 'changed:%s\n Restart Pi to pick them up.\n' "$changed"
else
Expand Down
1 change: 1 addition & 0 deletions scripts/check-install-symlinks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ printf '%s\n' seed > "$seed_src"
seed_absent="$tmp_dir/seed/absent.json"
seed_file "$seed_src" "$seed_absent" >/dev/null
[[ -f "$seed_absent" && ! -L "$seed_absent" && "$(<"$seed_absent")" == seed ]]
[[ "$(stat -c %a "$seed_absent" 2>/dev/null || stat -f %Lp "$seed_absent")" == 644 ]]

seed_link="$tmp_dir/seed-link.json"
ln -s "$seed_src" "$seed_link"
Expand Down
2 changes: 2 additions & 0 deletions scripts/seed-file.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ seed_file() {
local tmp
tmp="$(mktemp "$dst.seed.XXXXXX")"
cp "$src" "$tmp"
# mktemp creates 0600; configs are world-readable like a plain cp.
chmod 0644 "$tmp"
# mv over a symlink replaces the link itself, never its target.
mv -f "$tmp" "$dst"
echo " ✓ $dst seeded from $src"
Expand Down
8 changes: 7 additions & 1 deletion scripts/test-gs-sync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ case "\$name \$1" in
printf '#!/bin/sh\necho "engram 3.0.0"\n' >"\$GOBIN/engram"; chmod +x "\$GOBIN/engram" ;;
esac; done ;;
"gentle-ai --version") echo "gentle-ai 4.2.1" ;;
"gentle-ai sync") [ -n "\${FAKE_AI_SYNC_FAIL:-}" ] && { echo "Error: partial sync"; exit 1; }; echo "managed sync executed" ;;
"gentle-ai sync") [ -n "\${FAKE_AI_SYNC_FAIL:-}" ] && { echo "Error: partial sync"; exit 1; }; echo "managed sync executed"; [ -n "\${FAKE_AI_SYNC_CHANGED:-}" ] && echo "Sync actions executed: \$FAKE_AI_SYNC_CHANGED files changed"; true ;;
esac
exit 0
EOF
Expand All @@ -51,6 +51,12 @@ engram_line=$(grep -n 'cmd/engram@main' "$log" | cut -d: -f1)
sync_line=$(grep -n '^gentle-ai|sync' "$log" | cut -d: -f1)
(( engram_line < sync_line )) || fail 'gentle-ai sync ran before the binaries step' "$(cat "$log")"

[[ "$out" == *'nothing changed'* ]] || fail 'no-op sync should not ask for a Pi restart' "$out"

# 1b. Config changes from gentle-ai sync also ask for a Pi restart.
out=$(run_sync FAKE_AI_SYNC_CHANGED=3) || fail 'gs sync exited non-zero' "$out"
[[ "$out" == *'changed: managed configs (3 files)'*'Restart Pi'* ]] || fail 'config changes not reported' "$out"

# 2. GS_SYNC_AGENTS scopes the runtimes for this host.
out=$(run_sync GS_SYNC_AGENTS=claude-code,opencode,pi) || fail 'scoped gs sync exited non-zero' "$out"
[[ "$(ai_sync_calls)" == 'gentle-ai|sync --agents claude-code,opencode,pi' ]] || fail 'agents scope not forwarded' "$(cat "$log")"
Expand Down
Loading