diff options
Diffstat (limited to 'claude')
| -rw-r--r-- | claude/sessions.txt | 5 | ||||
| -rwxr-xr-x | claude/sync.sh | 67 | ||||
| -rw-r--r-- | claude/systemd/claude-code@.service | 17 |
3 files changed, 89 insertions, 0 deletions
diff --git a/claude/sessions.txt b/claude/sessions.txt new file mode 100644 index 0000000..6df2af0 --- /dev/null +++ b/claude/sessions.txt @@ -0,0 +1,5 @@ +# Claude Code セッション設定 +# 形式: <user>:<repo> +yyamashita:hetzner-infra +yyamashita:tokyo-livehouse-events +yyamashita:whois-band diff --git a/claude/sync.sh b/claude/sync.sh new file mode 100755 index 0000000..26f3da1 --- /dev/null +++ b/claude/sync.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# サーバー上で root として手動実行する +# 各ユーザーの Claude Code systemd user service を sessions.txt に基づいて同期する +set -euo pipefail + +APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" +TEMPLATE_SRC="$APP_DIR/claude/systemd/claude-code@.service" +SESSIONS_FILE="$APP_DIR/claude/sessions.txt" + +declare -A user_repos + +while IFS= read -r line; do + [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue + user="${line%%:*}" + repo="${line#*:}" + user_repos["$user"]+=" $repo" +done < "$SESSIONS_FILE" + +for user in "${!user_repos[@]}"; do + uid=$(id -u "$user" 2>/dev/null) || { echo "WARNING: user $user not found, skipping"; continue; } + runtime_dir="/run/user/$uid" + systemd_dir="/home/$user/.config/systemd/user" + + mkdir -p "$systemd_dir" + chown "$user:$user" "$systemd_dir" + + if ! diff -q "$TEMPLATE_SRC" "$systemd_dir/claude-code@.service" >/dev/null 2>&1; then + echo "[$user] Updating claude-code@.service template" + cp "$TEMPLATE_SRC" "$systemd_dir/claude-code@.service" + chown "$user:$user" "$systemd_dir/claude-code@.service" + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user daemon-reload + fi + + desired=() + for repo in ${user_repos[$user]}; do + [[ -z "$repo" ]] && continue + desired+=("$repo") + repo_path="/home/$user/workspaces/repos/$repo" + if [[ ! -d "$repo_path" ]]; then + echo "[$user] WARNING: $repo_path not found, skipping $repo" + continue + fi + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user enable "claude-code@${repo}.service" 2>/dev/null || true + if ! runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user is-active "claude-code@${repo}.service" >/dev/null 2>&1; then + echo "[$user] Starting claude-code@${repo}.service" + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user start "claude-code@${repo}.service" || true + fi + done + + while IFS= read -r unit; do + instance="${unit#claude-code@}" + instance="${instance%.service}" + if ! printf '%s\n' "${desired[@]}" | grep -qx "$instance"; then + echo "[$user] Disabling claude-code@${instance}.service" + runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user disable --now "claude-code@${instance}.service" || true + fi + done < <(runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ + systemctl --user list-unit-files --plain --no-legend 'claude-code@*.service' 2>/dev/null \ + | awk '$2 == "enabled" {print $1}') +done + +echo "Claude Code session sync complete." diff --git a/claude/systemd/claude-code@.service b/claude/systemd/claude-code@.service new file mode 100644 index 0000000..e3983b6 --- /dev/null +++ b/claude/systemd/claude-code@.service @@ -0,0 +1,17 @@ +[Unit] +Description=Claude Code Remote Session (%i) +After=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +WorkingDirectory=/home/yyamashita/workspaces/repos/%i +ExecStart=/usr/bin/tmux new-session -d -s claude-%i -c /home/yyamashita/workspaces/repos/%i /usr/local/bin/claude --remote-control %i --dangerously-skip-permissions +ExecStop=/usr/bin/tmux kill-session -t claude-%i +Environment=HOME=/home/yyamashita +Environment=USER=yyamashita +Environment=XDG_RUNTIME_DIR=/run/user/1000 +Environment=TMUX_TMPDIR=/tmp + +[Install] +WantedBy=default.target |
