@yeaft/webchat-agent 0.1.81 → 0.1.83
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/crew/session.js +35 -6
- package/crew/shared-dir.js +1 -1
- package/package.json +1 -1
package/crew/session.js
CHANGED
|
@@ -87,8 +87,19 @@ function isValidProjectDir(dir) {
|
|
|
87
87
|
// Session Lifecycle
|
|
88
88
|
// =====================================================================
|
|
89
89
|
|
|
90
|
+
/**
|
|
91
|
+
* 生成角色配置的规范化签名(sorted role name list)
|
|
92
|
+
* 用于比较新旧 session 的角色配置是否一致
|
|
93
|
+
*/
|
|
94
|
+
export function getRolesSignature(roles) {
|
|
95
|
+
if (!roles || roles.length === 0) return '';
|
|
96
|
+
const names = roles.map(r => r.name).sort();
|
|
97
|
+
return names.join(',');
|
|
98
|
+
}
|
|
99
|
+
|
|
90
100
|
/**
|
|
91
101
|
* 查找指定 projectDir 的已有 crew session
|
|
102
|
+
* 返回 { sessionId, source, roles } 或 null
|
|
92
103
|
*/
|
|
93
104
|
async function findExistingSessionByProjectDir(projectDir) {
|
|
94
105
|
const normalizedDir = projectDir.replace(/\/+$/, '');
|
|
@@ -96,7 +107,11 @@ async function findExistingSessionByProjectDir(projectDir) {
|
|
|
96
107
|
for (const [, session] of crewSessions) {
|
|
97
108
|
if (session.projectDir.replace(/\/+$/, '') === normalizedDir
|
|
98
109
|
&& session.status !== 'completed') {
|
|
99
|
-
return {
|
|
110
|
+
return {
|
|
111
|
+
sessionId: session.id,
|
|
112
|
+
source: 'active',
|
|
113
|
+
roles: Array.from(session.roles.values())
|
|
114
|
+
};
|
|
100
115
|
}
|
|
101
116
|
}
|
|
102
117
|
|
|
@@ -110,7 +125,7 @@ async function findExistingSessionByProjectDir(projectDir) {
|
|
|
110
125
|
|
|
111
126
|
if (match) {
|
|
112
127
|
const meta = await loadSessionMeta(match.sharedDir);
|
|
113
|
-
if (meta) return { sessionId: match.sessionId, source: 'index' };
|
|
128
|
+
if (meta) return { sessionId: match.sessionId, source: 'index', roles: meta.roles || [] };
|
|
114
129
|
await removeFromCrewIndex(match.sessionId);
|
|
115
130
|
}
|
|
116
131
|
|
|
@@ -133,12 +148,26 @@ export async function createCrewSession(msg) {
|
|
|
133
148
|
username
|
|
134
149
|
} = msg;
|
|
135
150
|
|
|
136
|
-
//
|
|
151
|
+
// 同目录检查:如果已有同目录的 session,比较角色配置
|
|
137
152
|
const existingSession = await findExistingSessionByProjectDir(projectDir);
|
|
138
153
|
if (existingSession) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
154
|
+
const newRoles = expandRoles(rawRoles);
|
|
155
|
+
const newSig = getRolesSignature(newRoles);
|
|
156
|
+
const oldSig = getRolesSignature(existingSession.roles);
|
|
157
|
+
|
|
158
|
+
if (newSig === oldSig) {
|
|
159
|
+
// 角色配置相同,安全 auto-resume
|
|
160
|
+
console.log(`[Crew] Found existing session for ${projectDir}: ${existingSession.sessionId}, roles match, auto-resuming`);
|
|
161
|
+
await resumeCrewSession({ sessionId: existingSession.sessionId, userId, username });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 角色配置不同 → 清理旧 session,用新配置走正常创建流程
|
|
166
|
+
console.log(`[Crew] Roles changed for ${projectDir}: old=[${oldSig}] new=[${newSig}], discarding old session ${existingSession.sessionId}`);
|
|
167
|
+
if (existingSession.source === 'active') {
|
|
168
|
+
crewSessions.delete(existingSession.sessionId);
|
|
169
|
+
}
|
|
170
|
+
await removeFromCrewIndex(existingSession.sessionId);
|
|
142
171
|
}
|
|
143
172
|
|
|
144
173
|
const roles = expandRoles(rawRoles);
|
package/crew/shared-dir.js
CHANGED
|
@@ -40,7 +40,7 @@ function extractMemorySection(fileContent, titles, defaults) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* Backup memory content from .crew/CLAUDE.md and .crew/roles
|
|
43
|
+
* Backup memory content from .crew/CLAUDE.md and .crew/roles/<role>/CLAUDE.md
|
|
44
44
|
* before deletion. Writes .crew/.memory-backup.json.
|
|
45
45
|
*/
|
|
46
46
|
export async function backupMemoryContent(crewDir) {
|