Browse Source

fix(skills): Fix cc-session project resolution and output formatting

- resolve_project now tries all matching projects, picks first with
  JSONL files (handles multiple matches like old/new project paths)
- resolve_session uses portable ls+grep instead of find -printf
- Fix jq output to use -r flag for proper newline rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0xDarkMatter 1 month ago
parent
commit
88b2b231c2
1 changed files with 29 additions and 15 deletions
  1. 29 15
      skills/introspect/scripts/cc-session

+ 29 - 15
skills/introspect/scripts/cc-session

@@ -61,31 +61,45 @@ USAGE
 # Resolve project directory from current working directory
 resolve_project() {
   local project_filter="${1:-}"
+  local candidates=()
+
   if [[ -n "$project_filter" ]]; then
-    # Find by partial match
-    local found
-    found=$(ls "$PROJECTS_DIR" 2>/dev/null | grep -i "$project_filter" | head -1)
-    [[ -n "$found" ]] || die "No project matching '$project_filter'"
-    echo "$PROJECTS_DIR/$found"
+    # Find by partial match - collect all matches
+    while IFS= read -r d; do
+      candidates+=("$d")
+    done < <(ls "$PROJECTS_DIR" 2>/dev/null | grep -i "$project_filter")
   else
     # Derive from cwd
     local encoded
     encoded=$(pwd | sed 's/[:\\\/]/-/g' | sed 's/--*/-/g')
-    local found
-    found=$(ls "$PROJECTS_DIR" 2>/dev/null | grep -i "${encoded##*-}" | head -1)
-    if [[ -n "$found" ]]; then
-      echo "$PROJECTS_DIR/$found"
-    else
-      die "Cannot determine project from $(pwd). Use --project <name>"
-    fi
+    while IFS= read -r d; do
+      candidates+=("$d")
+    done < <(ls "$PROJECTS_DIR" 2>/dev/null | grep -i "${encoded##*-}")
   fi
+
+  [[ ${#candidates[@]} -gt 0 ]] || die "No project matching '${project_filter:-$(pwd)}'"
+
+  # Pick the candidate that actually has JSONL files, preferring most recent
+  for candidate in "${candidates[@]}"; do
+    local dir="$PROJECTS_DIR/$candidate"
+    # Check if directory contains any .jsonl files (not just subdirs)
+    if ls "$dir"/*.jsonl &>/dev/null; then
+      echo "$dir"
+      return
+    fi
+  done
+
+  # Fallback: return first match even without JSONL files
+  echo "$PROJECTS_DIR/${candidates[0]}"
 }
 
 # Resolve session file
 resolve_session() {
   local project_dir="$1"
   local recent="${2:-1}"
-  ls -t "$project_dir"/*.jsonl 2>/dev/null | grep -v 'agent-' | sed -n "${recent}p"
+  # Use ls on directory then filter - portable across Git Bash / macOS / Linux
+  ls -t "$project_dir/" 2>/dev/null | grep '\.jsonl$' | grep -v '^agent-' | sed -n "${recent}p" |
+    while read -r f; do echo "$project_dir/$f"; done
 }
 
 # --- Commands ---
@@ -115,14 +129,14 @@ cmd_overview() {
     cat "$f" | jq -r '.type' | sort | uniq -c | sort -rn
     echo ""
     echo "--- Timing ---"
-    cat "$f" | jq -sc '
+    cat "$f" | jq -rsc '
       ([.[] | select(.type == "system" and .subtype == "turn_duration") | .durationMs] | add // 0) as $total |
       ([.[] | select(.type == "system" and .subtype == "turn_duration")] | length) as $turns |
       "Total time: \($total / 1000 | floor)s (\($total / 60000 | floor)m \(($total / 1000 | floor) % 60)s)\nTurns: \($turns)\nAvg turn: \(if $turns > 0 then ($total / $turns / 1000 | floor) else 0 end)s"
     ' 2>/dev/null
     echo ""
     echo "--- Content ---"
-    cat "$f" | jq -sc '
+    cat "$f" | jq -rsc '
       ([.[] | select(.type == "user") | .message.content[]? | select(.type == "text")] | length) as $user_msgs |
       ([.[] | select(.type == "assistant") | .message.content[]? | select(.type == "tool_use")] | length) as $tools |
       ([.[] | select(.type == "assistant") | .message.content[]? | select(.type == "thinking")] | length) as $thinking |