sticky-note-cli 2.6.5 → 2.6.7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sticky-note-cli",
3
- "version": "2.6.5",
3
+ "version": "2.6.7",
4
4
  "description": "Human-to-human handoff for AI coding assistants. Git-backed shared memory for Claude Code and Copilot CLI.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -181,6 +181,25 @@ function detectAndFormatOverlaps(threads, currentUser) {
181
181
  lines.push(
182
182
  "\n**Consider coordinating with these teammates before starting work.**\n"
183
183
  );
184
+
185
+ // Write a visible banner directly to stderr so the user sees it in
186
+ // their terminal regardless of whether the AI surfaces it.
187
+ const stderrLines = ["\n⚠️ OVERLAP DETECTED — someone else is touching your files:"];
188
+ for (const { thread, overlap } of warnings) {
189
+ const user = thread.user || thread.author || "unknown";
190
+ const status = thread.status === "stuck" ? "STUCK" : "OPEN";
191
+ const narrative = thread.narrative || thread.last_note || "";
192
+ const narrativeSnip = narrative.length > 80
193
+ ? narrative.substring(0, 80) + "…"
194
+ : narrative;
195
+ stderrLines.push(
196
+ ` [${status}] ${user}: ${overlap.join(", ")}` +
197
+ (narrativeSnip ? ` — ${narrativeSnip}` : "")
198
+ );
199
+ }
200
+ stderrLines.push("");
201
+ process.stderr.write(stderrLines.join("\n") + "\n");
202
+
184
203
  return lines.join("\n");
185
204
  }
186
205
 
@@ -442,7 +461,7 @@ function main() {
442
461
  const scored = [];
443
462
  for (const t of live) {
444
463
  // V2.5: Skip threads already injected this session by PreToolUse or session-start
445
- if (isThreadInjected(t.id)) continue;
464
+ if (isThreadInjected(t.id, sessionId)) continue;
446
465
 
447
466
  let s = scoreThread(t, recentlyModified, currentBranch, currentUser, keywords);
448
467
  if (resumeThreadId && t.id === resumeThreadId) {
@@ -169,7 +169,7 @@ function main() {
169
169
 
170
170
  // Filter out already-injected threads
171
171
  const newThreads = fileAttr.threads.filter(
172
- (t) => !isThreadInjected(t.thread ? t.thread.id : t.id)
172
+ (t) => !isThreadInjected(t.thread ? t.thread.id : t.id, sessionId)
173
173
  );
174
174
 
175
175
  if (newThreads.length === 0) {
@@ -394,6 +394,24 @@ function formatOverlapWarnings(threads, currentUser, memory) {
394
394
  lines.push(
395
395
  "\n**Consider coordinating with these teammates before starting work.**"
396
396
  );
397
+
398
+ // Write a visible banner directly to stderr so the user sees it
399
+ const stderrLines = ["\n⚠️ OVERLAP DETECTED — someone else is touching your files:"];
400
+ for (const { thread, overlap } of warnings) {
401
+ const user = thread.user || thread.author || "unknown";
402
+ const status = thread.status === "stuck" ? "STUCK" : "OPEN";
403
+ const narrative = thread.narrative || thread.last_note || "";
404
+ const narrativeSnip = narrative.length > 80
405
+ ? narrative.substring(0, 80) + "…"
406
+ : narrative;
407
+ stderrLines.push(
408
+ ` [${status}] ${user}: ${overlap.join(", ")}` +
409
+ (narrativeSnip ? ` — ${narrativeSnip}` : "")
410
+ );
411
+ }
412
+ stderrLines.push("");
413
+ process.stderr.write(stderrLines.join("\n") + "\n");
414
+
397
415
  return lines.join("\n");
398
416
  }
399
417
 
@@ -569,8 +569,14 @@ function clearInjectedSet() {
569
569
  }
570
570
  }
571
571
 
572
- function isThreadInjected(threadId) {
572
+ function isThreadInjected(threadId, sessionId) {
573
573
  const data = loadInjectedSet();
574
+ // Only consider threads injected in the SAME session — the file is shared
575
+ // across concurrent sessions and stale entries from other sessions must
576
+ // not suppress injection.
577
+ if (sessionId && data.session_id && data.session_id !== sessionId) {
578
+ return false;
579
+ }
574
580
  return (data.thread_ids || []).includes(threadId);
575
581
  }
576
582