clay-server 2.41.0 → 2.41.1
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/lib/project-sessions.js +21 -15
- package/lib/tui-transcript-index.js +11 -4
- package/package.json +1 -1
package/lib/project-sessions.js
CHANGED
|
@@ -110,6 +110,24 @@ function attachSessions(ctx) {
|
|
|
110
110
|
try { return usersModule.getClaudeOpenMode(uid) || "tui"; } catch (e) { return "tui"; }
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// Resolve the home directory where Claude Code writes JSONL for a
|
|
114
|
+
// given session. In OS-isolation mode each Clay user runs as a real
|
|
115
|
+
// Linux account so JSONL lives under /home/clay-name; for single-user
|
|
116
|
+
// installs we fall back to the daemon's own home.
|
|
117
|
+
function resolveSessionHome(session) {
|
|
118
|
+
var home = null;
|
|
119
|
+
if (osUsers && session && session.ownerId) {
|
|
120
|
+
try {
|
|
121
|
+
var ownerUser = usersModule.findUserById ? usersModule.findUserById(session.ownerId) : null;
|
|
122
|
+
if (ownerUser && ownerUser.linuxUser) {
|
|
123
|
+
var info = require("./os-users").resolveOsUserInfo(ownerUser.linuxUser);
|
|
124
|
+
if (info && info.home) home = info.home;
|
|
125
|
+
}
|
|
126
|
+
} catch (e) {}
|
|
127
|
+
}
|
|
128
|
+
return home || require("os").homedir();
|
|
129
|
+
}
|
|
130
|
+
|
|
113
131
|
// Watch the per-session jsonl Claude Code writes and mirror its auto /
|
|
114
132
|
// user titles into Clay's session.title. Lets TUI sessions move past the
|
|
115
133
|
// generic "New Session" label without us having to scrape the PTY output.
|
|
@@ -120,19 +138,7 @@ function attachSessions(ctx) {
|
|
|
120
138
|
if (session._titleWatcherStop) return; // already watching
|
|
121
139
|
var watcher;
|
|
122
140
|
try { watcher = require("./claude-jsonl-watcher"); } catch (e) { return; }
|
|
123
|
-
|
|
124
|
-
// to the daemon's home for single-user mode.
|
|
125
|
-
var home = null;
|
|
126
|
-
if (osUsers && session.ownerId) {
|
|
127
|
-
try {
|
|
128
|
-
var ownerUser = usersModule.findUserById ? usersModule.findUserById(session.ownerId) : null;
|
|
129
|
-
if (ownerUser && ownerUser.linuxUser) {
|
|
130
|
-
var info = require("./os-users").resolveOsUserInfo(ownerUser.linuxUser);
|
|
131
|
-
if (info && info.home) home = info.home;
|
|
132
|
-
}
|
|
133
|
-
} catch (e) {}
|
|
134
|
-
}
|
|
135
|
-
if (!home) home = require("os").homedir();
|
|
141
|
+
var home = resolveSessionHome(session);
|
|
136
142
|
var jsonlPath = watcher.jsonlPathFor(home, cwd, session.cliSessionId);
|
|
137
143
|
if (!jsonlPath) return;
|
|
138
144
|
var localId = session.localId;
|
|
@@ -181,7 +187,7 @@ function attachSessions(ctx) {
|
|
|
181
187
|
// message right away. The transcript is small enough that a full
|
|
182
188
|
// re-send beats maintaining a delta protocol.
|
|
183
189
|
try {
|
|
184
|
-
var newIndex = require("./tui-transcript-index").readAssistantIndex(cwd, s.cliSessionId);
|
|
190
|
+
var newIndex = require("./tui-transcript-index").readAssistantIndex(resolveSessionHome(s), cwd, s.cliSessionId);
|
|
185
191
|
send({
|
|
186
192
|
type: "tui_transcript_state",
|
|
187
193
|
id: s.localId,
|
|
@@ -707,7 +713,7 @@ function attachSessions(ctx) {
|
|
|
707
713
|
return true;
|
|
708
714
|
}
|
|
709
715
|
try {
|
|
710
|
-
var tprIndex = require("./tui-transcript-index").readAssistantIndex(cwd, tprSess.cliSessionId);
|
|
716
|
+
var tprIndex = require("./tui-transcript-index").readAssistantIndex(resolveSessionHome(tprSess), cwd, tprSess.cliSessionId);
|
|
711
717
|
sendTo(ws, {
|
|
712
718
|
type: "tui_transcript_state",
|
|
713
719
|
id: tprId,
|
|
@@ -24,9 +24,16 @@ var encodeCwd = utils.encodeCwd;
|
|
|
24
24
|
// positives when matched against a hovered terminal block.
|
|
25
25
|
var MIN_MATCH_LEN = 20;
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
// Claude Code writes its JSONL under the *running user's* home, which
|
|
28
|
+
// is not the daemon's home in OS-isolation mode (where each Clay user
|
|
29
|
+
// gets a real Linux account like /home/clay-name). Callers from the
|
|
30
|
+
// project context resolve the session owner's home and pass it in;
|
|
31
|
+
// when no home is provided we fall back to REAL_HOME for single-user
|
|
32
|
+
// installs.
|
|
33
|
+
function transcriptFilePath(home, cwd, cliSessionId) {
|
|
28
34
|
if (!cwd || !cliSessionId) return null;
|
|
29
|
-
|
|
35
|
+
var base = home || REAL_HOME;
|
|
36
|
+
return path.join(base, ".claude", "projects", encodeCwd(cwd), cliSessionId + ".jsonl");
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
// matchKey is just whitespace-normalized raw markdown. We intentionally
|
|
@@ -91,8 +98,8 @@ function parseAssistantTextLine(line, index) {
|
|
|
91
98
|
// session open or on a watcher-driven update is fine. We also return
|
|
92
99
|
// the mtime/size so callers can short-circuit re-reads when nothing
|
|
93
100
|
// changed.
|
|
94
|
-
function readAssistantIndex(cwd, cliSessionId) {
|
|
95
|
-
var file = transcriptFilePath(cwd, cliSessionId);
|
|
101
|
+
function readAssistantIndex(home, cwd, cliSessionId) {
|
|
102
|
+
var file = transcriptFilePath(home, cwd, cliSessionId);
|
|
96
103
|
if (!file) return { messages: [], mtimeMs: 0, byteLength: 0 };
|
|
97
104
|
var raw;
|
|
98
105
|
var stat;
|
package/package.json
CHANGED