diff --git a/scripts/provision-worktree.sh b/scripts/provision-worktree.sh index 14acc040..861a6037 100644 --- a/scripts/provision-worktree.sh +++ b/scripts/provision-worktree.sh @@ -335,6 +335,18 @@ disable_seeded_routines() { disable_seeded_routines +list_base_node_modules_paths() { + cd "$base_cwd" && + find . \ + -mindepth 1 \ + -maxdepth 4 \ + -type d \ + -name node_modules \ + ! -path './.git/*' \ + ! -path './.paperclip/*' \ + | sed 's#^\./##' +} + if [[ -f "$worktree_cwd/package.json" && -f "$worktree_cwd/pnpm-lock.yaml" ]]; then needs_install=0 @@ -342,32 +354,56 @@ if [[ -f "$worktree_cwd/package.json" && -f "$worktree_cwd/pnpm-lock.yaml" ]]; t [[ -n "$relative_path" ]] || continue target_path="$worktree_cwd/$relative_path" - if [[ -L "$target_path" ]]; then - rm "$target_path" + if [[ -L "$target_path" || ! -e "$target_path" ]]; then needs_install=1 - continue + break fi - - if [[ ! -e "$target_path" ]]; then - needs_install=1 - fi - done < <( - cd "$base_cwd" && - find . \ - -mindepth 1 \ - -maxdepth 3 \ - -type d \ - -name node_modules \ - ! -path './.git/*' \ - ! -path './.paperclip/*' \ - | sed 's#^\./##' - ) + done < <(list_base_node_modules_paths) if [[ "$needs_install" -eq 1 ]]; then + backup_suffix=".paperclip-backup-$BASHPID" + moved_symlink_paths=() + + while IFS= read -r relative_path; do + [[ -n "$relative_path" ]] || continue + target_path="$worktree_cwd/$relative_path" + if [[ -L "$target_path" ]]; then + backup_path="${target_path}${backup_suffix}" + rm -rf "$backup_path" + mv "$target_path" "$backup_path" + moved_symlink_paths+=("$relative_path") + fi + done < <(list_base_node_modules_paths) + + restore_moved_symlinks() { + local relative_path target_path backup_path + for relative_path in "${moved_symlink_paths[@]}"; do + target_path="$worktree_cwd/$relative_path" + backup_path="${target_path}${backup_suffix}" + [[ -L "$backup_path" ]] || continue + rm -rf "$target_path" + mv "$backup_path" "$target_path" + done + } + + cleanup_moved_symlinks() { + local relative_path target_path backup_path + for relative_path in "${moved_symlink_paths[@]}"; do + target_path="$worktree_cwd/$relative_path" + backup_path="${target_path}${backup_suffix}" + [[ -L "$backup_path" ]] && rm "$backup_path" + done + } + ( cd "$worktree_cwd" pnpm install --frozen-lockfile - ) + ) || { + restore_moved_symlinks + exit 1 + } + + cleanup_moved_symlinks fi exit 0 @@ -384,13 +420,5 @@ while IFS= read -r relative_path; do mkdir -p "$(dirname "$target_path")" ln -s "$source_path" "$target_path" done < <( - cd "$base_cwd" && - find . \ - -mindepth 1 \ - -maxdepth 3 \ - -type d \ - -name node_modules \ - ! -path './.git/*' \ - ! -path './.paperclip/*' \ - | sed 's#^\./##' + list_base_node_modules_paths ) diff --git a/server/src/services/heartbeat.ts b/server/src/services/heartbeat.ts index f585b834..0a3a1479 100644 --- a/server/src/services/heartbeat.ts +++ b/server/src/services/heartbeat.ts @@ -779,6 +779,8 @@ function enrichWakeContextSnapshot(input: { contextSnapshot[WAKE_COMMENT_IDS_KEY] = wakeCommentIds; contextSnapshot.commentId = latestCommentId; contextSnapshot.wakeCommentId = latestCommentId; + // Once comment ids are normalized into the snapshot, rebuild the structured + // wake payload from those ids later instead of carrying forward stale data. delete contextSnapshot[PAPERCLIP_WAKE_PAYLOAD_KEY]; } else if (!readNonEmptyString(contextSnapshot["wakeCommentId"]) && wakeCommentId) { contextSnapshot.wakeCommentId = wakeCommentId; @@ -814,6 +816,8 @@ export function mergeCoalescedContextSnapshot( merged[WAKE_COMMENT_IDS_KEY] = mergedCommentIds; merged.commentId = latestCommentId; merged.wakeCommentId = latestCommentId; + // The merged context should carry canonical comment ids; the next wake will + // regenerate any structured payload from those ids. delete merged[PAPERCLIP_WAKE_PAYLOAD_KEY]; } return merged;