cc-sessions 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/bin/cc +15 -12
  4. data/bin/cc-bookmark +9 -37
  5. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cad93912f48c81f33e5532c4a6015164d192899ba9e0bcaaa6a434270e99f881
4
- data.tar.gz: b3600372722bcd711e490dacbb52e298cb45f1ffc7438c47bbae87dad0d17088
3
+ metadata.gz: e5d11bb510817b94f744a4fcbcf84377f11e0eb3dbacc62de24a12b070440ab3
4
+ data.tar.gz: f39fcd03d01726cf2aed5373f1d8172a1775d7ad44f8e4945b86d2ee918c690a
5
5
  SHA512:
6
- metadata.gz: 3f575d1ae31c07665d31b1e31ae25f5bf509bc3a5c23f5598d44d9720d7e870cbc0e15ecb55a2c2ad34ac399bff45bf5bfb97688d02ba2cb5df10e0b79feb1f7
7
- data.tar.gz: 8fb66ea0011e696e15161e7e3dbdf2a13b83dfcc4c3abba8ab8148d8d400d208c4bcfba4fce580aae05c4a0855ad3165290e98807fe1843fd802aa320f65f81e
6
+ metadata.gz: b107bb851e4a8cdb041a85da1fe94fe22327e52ff5d8cb2a149a36c07414f550f2f7c2f59e1ee5757cd6b63365926b90713482f5e030e220e39c2874a9335298
7
+ data.tar.gz: '05790790d708513d61beabd74d8b372d6974dc66057418b48525ef4be979a3e6c883b3cd59209c75567727355304df2ca805512789f7da0a164f3a9e37d96c49'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.5.0] - 2026-03-03
4
+
5
+ ### Fixed
6
+ - Sessions no longer inherit bookmarks from unrelated sessions in the same directory
7
+ - Removed path-based sibling matching in `find_resume_breadcrumb` — now only matches exact session IDs
8
+ - Removed `find_tags_for_path` from `cc` — running session tags now resolved by session ID, not directory path
9
+ - Running indicator (green dot) in `cc -l` now matches by session ID instead of path
10
+
11
+ ### Changed
12
+ - `find_resume_breadcrumb` takes a session ID only, not a directory — eliminates cross-contamination
13
+ - `cc -C` uses session-ID-based tag lookup instead of path matching
14
+
3
15
  ## [1.4.2] - 2026-03-03
4
16
 
5
17
  ### Fixed
data/bin/cc CHANGED
@@ -139,11 +139,12 @@ def find_session_by_tag(tag)
139
139
  nil
140
140
  end
141
141
 
142
- def find_tags_for_path(path, bookmarks)
143
- bookmarks['sessions'].each_value do |entry|
144
- return entry['tags'] if entry['path'] == path
145
- end
146
- []
142
+ def find_tags_for_session_dir(session_dir, bookmarks)
143
+ session_id = detect_session_id(session_dir)
144
+ return [] unless session_id
145
+
146
+ entry = bookmarks['sessions'][session_id]
147
+ entry ? entry['tags'] : []
147
148
  end
148
149
 
149
150
  def session_exists_in_dir?(dir)
@@ -187,18 +188,20 @@ def delete_bookmark_by_tag(tag)
187
188
  end
188
189
  end
189
190
 
190
- def running_session_dirs
191
+ def running_session_ids
191
192
  pids = `pgrep -x claude 2>/dev/null`.split.map(&:to_i)
192
- dirs = Set.new
193
+ ids = Set.new
193
194
  pids.each do |pid|
194
195
  cwd_link = "/proc/#{pid}/cwd"
195
196
  next unless File.exist?(cwd_link)
196
197
  begin
197
- dirs << resolve_session_dir(File.readlink(cwd_link))
198
+ session_dir = resolve_session_dir(File.readlink(cwd_link))
199
+ sid = detect_session_id(session_dir)
200
+ ids << sid if sid
198
201
  rescue Errno::EACCES
199
202
  end
200
203
  end
201
- dirs
204
+ ids
202
205
  end
203
206
 
204
207
  def list_bookmarks
@@ -211,11 +214,11 @@ def list_bookmarks
211
214
  return
212
215
  end
213
216
 
214
- running = running_session_dirs
217
+ running = running_session_ids
215
218
 
216
219
  items = bookmarks['sessions'].map do |id, entry|
217
220
  { id: id, path: entry['path'], tags: entry['tags'], exists: Dir.exist?(entry['path']),
218
- running: running.include?(entry['path']) }
221
+ running: running.include?(id) }
219
222
  end
220
223
 
221
224
  index = 0
@@ -337,7 +340,7 @@ def show_current_sessions
337
340
  begin
338
341
  cwd = File.readlink(cwd_link)
339
342
  session_dir = resolve_session_dir(cwd)
340
- tags = find_tags_for_path(session_dir, bookmarks)
343
+ tags = find_tags_for_session_dir(session_dir, bookmarks)
341
344
  tag_str = tags.empty? ? dim('(no tags)') : green(tags.join(', '))
342
345
 
343
346
  puts " PID #{cyan(pid.to_s)}: #{session_dir}"
data/bin/cc-bookmark CHANGED
@@ -39,33 +39,16 @@ def detect_session_id(session_dir, exclude_id: nil)
39
39
  File.basename(newest, '.jsonl')
40
40
  end
41
41
 
42
- # Find all session IDs in the same project directory
43
- def sibling_session_ids(session_dir)
44
- encoded = session_dir.gsub('/', '-')
45
- project_dir = File.join(CLAUDE_PROJECTS, encoded)
46
- return [] unless Dir.exist?(project_dir)
47
-
48
- Dir.glob(File.join(project_dir, '*.jsonl'))
49
- .select { |f| File.file?(f) }
50
- .map { |f| File.basename(f, '.jsonl') }
51
- end
52
-
53
- # Check resume breadcrumbs left by `cc` to find tags for a continued session.
54
- # When `cc <tag>` resumes a session that later gets a new ID (context reset),
55
- # the breadcrumb links the old session ID to its tags.
56
- def find_resume_breadcrumb(session_dir, current_id, bookmarks)
57
- return nil unless Dir.exist?(RESUME_DIR)
42
+ # Find resume breadcrumb for a specific session ID only.
43
+ # Only matches exact session IDs — never scans siblings by path.
44
+ def find_resume_breadcrumb(session_id)
45
+ return nil unless session_id && Dir.exist?(RESUME_DIR)
58
46
 
59
- siblings = sibling_session_ids(session_dir)
60
- siblings.each do |sid|
61
- next if sid == current_id
62
- breadcrumb = File.join(RESUME_DIR, "#{sid}.json")
63
- next unless File.exist?(breadcrumb)
47
+ breadcrumb = File.join(RESUME_DIR, "#{session_id}.json")
48
+ return nil unless File.exist?(breadcrumb)
64
49
 
65
- tags = JSON.parse(File.read(breadcrumb))
66
- return [sid, tags] if tags.is_a?(Array)
67
- end
68
- nil
50
+ tags = JSON.parse(File.read(breadcrumb))
51
+ tags.is_a?(Array) ? tags : nil
69
52
  rescue
70
53
  nil
71
54
  end
@@ -169,18 +152,7 @@ if tags.empty?
169
152
  if entry
170
153
  puts "Current bookmark: #{entry['tags'].join(', ')}"
171
154
  else
172
- # Fallback: check resume breadcrumbs (legacy behavior, no env var)
173
- match = find_resume_breadcrumb(cwd, session_id, bookmarks)
174
- if match
175
- old_id, old_tags = match
176
- bookmarks['sessions'].delete(old_id)
177
- bookmarks['sessions'][session_id] = { 'path' => cwd, 'tags' => old_tags }
178
- save_bookmarks(bookmarks)
179
- FileUtils.rm_f(File.join(RESUME_DIR, "#{old_id}.json"))
180
- puts "Current bookmark: #{old_tags.join(', ')}"
181
- else
182
- puts "No bookmark for this session. Usage: /bm tag1 tag2 ..."
183
- end
155
+ puts "No bookmark for this session. Usage: /bm tag1 tag2 ..."
184
156
  end
185
157
  else
186
158
  puts "Could not detect session ID. Usage: /bm tag1 tag2 ..."
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cc-sessions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geir Isene
@@ -12,8 +12,8 @@ date: 2026-03-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'A simple tool for bookmarking and resuming Claude Code sessions. Tag
14
14
  sessions with meaningful names using /bm inside Claude Code, then quickly resume
15
- them with ''cc <tag>'' from anywhere. v1.4.2: Fix cwd drift in session detection
16
- on context continuations via hook.'
15
+ them with ''cc <tag>'' from anywhere. v1.5.0: Strict session-ID matching no more
16
+ path-based bookmark cross-contamination.'
17
17
  email:
18
18
  - g@isene.com
19
19
  executables: