@wu529778790/open-im 1.10.9-beta.5 → 1.10.9-beta.6
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.
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* 认证:ANTHROPIC_API_KEY 或 CLAUDE_CODE_OAUTH_TOKEN
|
|
10
10
|
*/
|
|
11
11
|
import { unstable_v2_createSession, unstable_v2_resumeSession } from '@anthropic-ai/claude-agent-sdk';
|
|
12
|
-
import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
12
|
+
import { existsSync, readFileSync, readdirSync, statSync, openSync, readSync, closeSync } from 'fs';
|
|
13
13
|
import { execSync } from 'child_process';
|
|
14
14
|
import { homedir } from 'os';
|
|
15
15
|
import { join } from 'path';
|
|
@@ -53,17 +53,19 @@ loadUserPluginSettings();
|
|
|
53
53
|
* ~/.claude/projects/-Users-mac-github-open-im/
|
|
54
54
|
*/
|
|
55
55
|
function workDirToProjectPath(workDir) {
|
|
56
|
-
// Claude Code
|
|
56
|
+
// Claude Code 将路径中的 / 替换为 -,leading - 保留
|
|
57
57
|
// /Users/mac/github/open-im → -Users-mac-github-open-im
|
|
58
58
|
return workDir.replace(/\//g, '-');
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* 检查 CLI 进程是否正在使用某个 session(通过
|
|
61
|
+
* 检查 CLI 进程是否正在使用某个 session(通过 ps 检测)
|
|
62
|
+
* 注意:仅支持 macOS/Linux,Windows 上会静默返回 false
|
|
62
63
|
*/
|
|
63
64
|
function isCliSessionActive(sessionId) {
|
|
64
65
|
try {
|
|
65
|
-
// macOS: 用 ps 搜索包含该 sessionId 的 claude 进程
|
|
66
|
-
|
|
66
|
+
// macOS/Linux: 用 ps 搜索包含该 sessionId 的 claude 进程
|
|
67
|
+
// -F 固定字符串匹配,避免正则意外;-- 防止 sessionId 被误认为 flag
|
|
68
|
+
const result = execSync(`ps -axo pid,command 2>/dev/null | grep -v grep | grep "claude" | grep -F -- "${sessionId}" || true`, { encoding: 'utf-8', timeout: 3000 });
|
|
67
69
|
return result.trim().length > 0;
|
|
68
70
|
}
|
|
69
71
|
catch {
|
|
@@ -98,7 +100,7 @@ export function findLatestClaudeSession(workDir, homeOverride) {
|
|
|
98
100
|
// 跳过空文件
|
|
99
101
|
if (stat.size === 0)
|
|
100
102
|
continue;
|
|
101
|
-
sessions.push({ sessionId, mtime: stat.mtimeMs, filePath });
|
|
103
|
+
sessions.push({ sessionId, mtime: stat.mtimeMs, filePath, size: stat.size });
|
|
102
104
|
}
|
|
103
105
|
catch {
|
|
104
106
|
continue;
|
|
@@ -111,7 +113,7 @@ export function findLatestClaudeSession(workDir, homeOverride) {
|
|
|
111
113
|
// 按修改时间倒序,最新的在前
|
|
112
114
|
sessions.sort((a, b) => b.mtime - a.mtime);
|
|
113
115
|
const latest = sessions[0];
|
|
114
|
-
log.info(`Found latest Claude Code session: ${latest.sessionId} (mtime: ${new Date(latest.mtime).toISOString()}, size: ${
|
|
116
|
+
log.info(`Found latest Claude Code session: ${latest.sessionId} (mtime: ${new Date(latest.mtime).toISOString()}, size: ${latest.size})`);
|
|
115
117
|
return latest;
|
|
116
118
|
}
|
|
117
119
|
catch (err) {
|
|
@@ -121,11 +123,17 @@ export function findLatestClaudeSession(workDir, homeOverride) {
|
|
|
121
123
|
}
|
|
122
124
|
/**
|
|
123
125
|
* 从 JSONL 文件的第一行提取 sessionId,验证文件内容与文件名一致。
|
|
126
|
+
* 只读取前 4KB,避免大文件全量读入内存。
|
|
124
127
|
*/
|
|
125
128
|
function validateSessionFile(filePath, expectedSessionId) {
|
|
129
|
+
let fd;
|
|
126
130
|
try {
|
|
127
|
-
|
|
128
|
-
const
|
|
131
|
+
fd = openSync(filePath, 'r');
|
|
132
|
+
const buf = Buffer.alloc(4096);
|
|
133
|
+
const bytesRead = readSync(fd, buf, 0, 4096, 0);
|
|
134
|
+
if (bytesRead === 0)
|
|
135
|
+
return false;
|
|
136
|
+
const firstLine = buf.toString('utf-8', 0, bytesRead).split('\n')[0];
|
|
129
137
|
if (!firstLine)
|
|
130
138
|
return false;
|
|
131
139
|
const firstEntry = JSON.parse(firstLine);
|
|
@@ -134,6 +142,14 @@ function validateSessionFile(filePath, expectedSessionId) {
|
|
|
134
142
|
catch {
|
|
135
143
|
return false;
|
|
136
144
|
}
|
|
145
|
+
finally {
|
|
146
|
+
if (fd !== undefined) {
|
|
147
|
+
try {
|
|
148
|
+
closeSync(fd);
|
|
149
|
+
}
|
|
150
|
+
catch { /* ignore */ }
|
|
151
|
+
}
|
|
152
|
+
}
|
|
137
153
|
}
|
|
138
154
|
// 存储所有活跃的 SDKSession 对象,key 为 sessionId
|
|
139
155
|
// 使用 Map 而不是 Set,因为我们需要通过 sessionId 获取 session
|
|
@@ -357,7 +373,7 @@ async function getOrCreateSession(sessionId, workDir, model, permissionMode, onS
|
|
|
357
373
|
return { session, sessionId: latest.sessionId };
|
|
358
374
|
}
|
|
359
375
|
catch (err) {
|
|
360
|
-
log.warn(`Failed to auto-resume CLI session ${latest.sessionId},
|
|
376
|
+
log.warn(`Failed to auto-resume CLI session ${latest.sessionId}, skipping auto-resume: ${err}`);
|
|
361
377
|
}
|
|
362
378
|
}
|
|
363
379
|
else {
|