shadok-ai 0.17.21 → 0.17.23

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.
@@ -40,4 +40,14 @@ seen?: ReadonlySet<string>,
40
40
  * transcript a second time. Treating it like any other visited fork pinned
41
41
  * the tail to a dead one for good — nothing streamed, the chat was silent
42
42
  * live and perfect on every reload, and no restart could recover it. */
43
- ownId?: string): string | null;
43
+ ownId?: string,
44
+ /** Directories to search for the fork. Defaults to the frozen file's OWN
45
+ * directory — but a fork does NOT always land there. Claude Code derives the
46
+ * project dir from the cwd it is LAUNCHED with, so a session created in a
47
+ * worktree and later resumed at the repo root (the worktree pruned) writes
48
+ * its context-overflow continuation under a DIFFERENT project dir. Scanning
49
+ * one directory is then blind to it — the exact freeze this followed. The
50
+ * caller passes every project dir so the lineage is found wherever it landed;
51
+ * the root-match still keeps a sibling's transcript from being adopted, so
52
+ * widening the search cannot mis-attribute across the boundary. */
53
+ searchDirs?: readonly string[]): string | null;
package/dist/forktrace.js CHANGED
@@ -109,7 +109,17 @@ seen = new Set(),
109
109
  * transcript a second time. Treating it like any other visited fork pinned
110
110
  * the tail to a dead one for good — nothing streamed, the chat was silent
111
111
  * live and perfect on every reload, and no restart could recover it. */
112
- ownId) {
112
+ ownId,
113
+ /** Directories to search for the fork. Defaults to the frozen file's OWN
114
+ * directory — but a fork does NOT always land there. Claude Code derives the
115
+ * project dir from the cwd it is LAUNCHED with, so a session created in a
116
+ * worktree and later resumed at the repo root (the worktree pruned) writes
117
+ * its context-overflow continuation under a DIFFERENT project dir. Scanning
118
+ * one directory is then blind to it — the exact freeze this followed. The
119
+ * caller passes every project dir so the lineage is found wherever it landed;
120
+ * the root-match still keeps a sibling's transcript from being adopted, so
121
+ * widening the search cannot mis-attribute across the boundary. */
122
+ searchDirs) {
113
123
  let myMtime;
114
124
  try {
115
125
  myMtime = fs.statSync(myFile).mtimeMs;
@@ -117,30 +127,32 @@ ownId) {
117
127
  catch {
118
128
  return null; // our own file vanished — nothing to reason about
119
129
  }
120
- const dir = path.dirname(myFile);
121
- let names;
122
- try {
123
- names = fs.readdirSync(dir);
124
- }
125
- catch {
126
- return null;
127
- }
130
+ const dirs = searchDirs ?? [path.dirname(myFile)];
128
131
  const candidates = [];
129
- for (const name of names) {
130
- const id = idFromTranscriptName(name);
131
- if (!id || id === tailId || (seen.has(id) && id !== ownId))
132
- continue;
133
- const f = path.join(dir, name);
134
- let mtime;
132
+ for (const dir of dirs) {
133
+ let names;
135
134
  try {
136
- mtime = fs.statSync(f).mtimeMs;
135
+ names = fs.readdirSync(dir);
137
136
  }
138
137
  catch {
139
- continue; // vanished mid-scan
138
+ continue; // a listed dir that vanished/denied — skip, don't abort the scan
139
+ }
140
+ for (const name of names) {
141
+ const id = idFromTranscriptName(name);
142
+ if (!id || id === tailId || (seen.has(id) && id !== ownId))
143
+ continue;
144
+ const f = path.join(dir, name);
145
+ let mtime;
146
+ try {
147
+ mtime = fs.statSync(f).mtimeMs;
148
+ }
149
+ catch {
150
+ continue; // vanished mid-scan
151
+ }
152
+ if (mtime <= myMtime)
153
+ continue; // the fork is newer than the frozen file
154
+ candidates.push({ id, mtime, root: rootIdOfFile(f) });
140
155
  }
141
- if (mtime <= myMtime)
142
- continue; // the fork is newer than the frozen file
143
- candidates.push({ id, mtime, root: rootIdOfFile(f) });
144
156
  }
145
157
  return forkTarget(candidates, tailId, myRoot);
146
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"forktrace.js","sourceRoot":"","sources":["../src/forktrace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"forktrace.js","sourceRoot":"","sources":["../src/forktrace.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -5983,11 +5983,25 @@ function maybeFollowFork(s) {
5983
5983
  // when the file has no root record yet (a session that never took a turn).
5984
5984
  const myRoot = (s.rootId ??= rootIdOfFile(myFile) ?? s.id);
5985
5985
  const seen = (s.tailSeen ??= new Set([tailId]));
5986
+ // Search EVERY project dir, not just the frozen file's own: a session whose
5987
+ // cwd drifted (created in a worktree, resumed at the repo root once the
5988
+ // worktree was pruned) writes its context-overflow continuation under a
5989
+ // DIFFERENT project dir, and scanning one directory is blind to it — the chat
5990
+ // freezes while the TUI is fine. The root-match inside detectFork still bars a
5991
+ // sibling's transcript, so widening the search cannot mis-attribute.
5992
+ const projectsRoot = path.join(s.transcriptHome, ".claude", "projects");
5993
+ let searchDirs;
5994
+ try {
5995
+ searchDirs = fs.readdirSync(projectsRoot).map((d) => path.join(projectsRoot, d));
5996
+ }
5997
+ catch {
5998
+ searchDirs = [path.dirname(myFile)];
5999
+ }
5986
6000
  // `s.id` is passed so the hunt can come HOME: every restart respawns with
5987
6001
  // `--resume <s.id>`, so the session's own transcript becomes the live file
5988
6002
  // again, and excluding it as a visited fork left the tail on a dead one for
5989
6003
  // good (see `detectFork`).
5990
- const target = detectFork(myFile, tailId, myRoot, seen, s.id);
6004
+ const target = detectFork(myFile, tailId, myRoot, seen, s.id, searchDirs);
5991
6005
  if (!target)
5992
6006
  return;
5993
6007
  const home = target === s.id;