chatccc 0.2.48 → 0.2.49
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 +1 -1
- package/src/__tests__/cards.test.ts +23 -8
- package/src/session.ts +9 -3
package/package.json
CHANGED
|
@@ -311,7 +311,7 @@ describe("buildSessionsCard", () => {
|
|
|
311
311
|
|
|
312
312
|
it("returns valid JSON with session listing", () => {
|
|
313
313
|
const card = buildSessionsCard([
|
|
314
|
-
{ sessionId: "abc123", chatName: "test-group", active: true, turnCount: 5, elapsedSeconds: 120, model: "Claude Opus 4.7", tool: "claude" },
|
|
314
|
+
{ sessionId: "abc123", chatName: "test-group", chatId: "oc_test123", active: true, turnCount: 5, elapsedSeconds: 120, model: "Claude Opus 4.7", tool: "claude" },
|
|
315
315
|
]);
|
|
316
316
|
const parsed = JSON.parse(card);
|
|
317
317
|
expect(parsed.elements[0].text.content).toContain("共 **1** 个会话");
|
|
@@ -322,7 +322,7 @@ describe("buildSessionsCard", () => {
|
|
|
322
322
|
|
|
323
323
|
it("shows idle status for inactive sessions", () => {
|
|
324
324
|
const card = buildSessionsCard([
|
|
325
|
-
{ sessionId: "xyz", chatName: "", active: false, turnCount: 0, elapsedSeconds: null, model: "Claude Sonnet 4.6", tool: "claude" },
|
|
325
|
+
{ sessionId: "xyz", chatName: "", chatId: "oc_xyz", active: false, turnCount: 0, elapsedSeconds: null, model: "Claude Sonnet 4.6", tool: "claude" },
|
|
326
326
|
]);
|
|
327
327
|
const parsed = JSON.parse(card);
|
|
328
328
|
expect(parsed.elements[0].text.content).toContain("⚪ 空闲");
|
|
@@ -330,7 +330,7 @@ describe("buildSessionsCard", () => {
|
|
|
330
330
|
|
|
331
331
|
it("shows elapsed time for active sessions", () => {
|
|
332
332
|
const card = buildSessionsCard([
|
|
333
|
-
{ sessionId: "active123", chatName: "", active: true, turnCount: 3, elapsedSeconds: 95, model: "Claude Opus 4.7", tool: "claude" },
|
|
333
|
+
{ sessionId: "active123", chatName: "", chatId: "oc_active123", active: true, turnCount: 3, elapsedSeconds: 95, model: "Claude Opus 4.7", tool: "claude" },
|
|
334
334
|
]);
|
|
335
335
|
const parsed = JSON.parse(card);
|
|
336
336
|
expect(parsed.elements[0].text.content).toContain("1分35秒");
|
|
@@ -338,8 +338,8 @@ describe("buildSessionsCard", () => {
|
|
|
338
338
|
|
|
339
339
|
it("separates Claude Code and Cursor sessions", () => {
|
|
340
340
|
const card = buildSessionsCard([
|
|
341
|
-
{ sessionId: "c1", chatName: "", active: false, turnCount: 1, elapsedSeconds: null, model: "(留空)", tool: "claude" },
|
|
342
|
-
{ sessionId: "c2", chatName: "", active: false, turnCount: 2, elapsedSeconds: null, model: "claude-opus-4-7-max", tool: "cursor" },
|
|
341
|
+
{ sessionId: "c1", chatName: "", chatId: "oc_c1", active: false, turnCount: 1, elapsedSeconds: null, model: "(留空)", tool: "claude" },
|
|
342
|
+
{ sessionId: "c2", chatName: "", chatId: "oc_c2", active: false, turnCount: 2, elapsedSeconds: null, model: "claude-opus-4-7-max", tool: "cursor" },
|
|
343
343
|
]);
|
|
344
344
|
const parsed = JSON.parse(card);
|
|
345
345
|
const content: string = parsed.elements[0].text.content;
|
|
@@ -349,7 +349,7 @@ describe("buildSessionsCard", () => {
|
|
|
349
349
|
|
|
350
350
|
it("omits Cursor section when no Cursor sessions", () => {
|
|
351
351
|
const card = buildSessionsCard([
|
|
352
|
-
{ sessionId: "c1", chatName: "", active: false, turnCount: 1, elapsedSeconds: null, model: "(留空)", tool: "claude" },
|
|
352
|
+
{ sessionId: "c1", chatName: "", chatId: "oc_c1", active: false, turnCount: 1, elapsedSeconds: null, model: "(留空)", tool: "claude" },
|
|
353
353
|
]);
|
|
354
354
|
const parsed = JSON.parse(card);
|
|
355
355
|
const content: string = parsed.elements[0].text.content;
|
|
@@ -359,15 +359,30 @@ describe("buildSessionsCard", () => {
|
|
|
359
359
|
|
|
360
360
|
it("displays chatName when provided", () => {
|
|
361
361
|
const card = buildSessionsCard([
|
|
362
|
-
{ sessionId: "abc123", chatName: "帮我写代码-src", active: false, turnCount: 2, elapsedSeconds: null, model: "Claude Opus 4.7", tool: "claude" },
|
|
362
|
+
{ sessionId: "abc123", chatName: "帮我写代码-src", chatId: "oc_abc123", active: false, turnCount: 2, elapsedSeconds: null, model: "Claude Opus 4.7", tool: "claude" },
|
|
363
363
|
]);
|
|
364
364
|
const parsed = JSON.parse(card);
|
|
365
365
|
expect(parsed.elements[0].text.content).toContain("帮我写代码-src");
|
|
366
366
|
});
|
|
367
367
|
|
|
368
|
+
it("shows (群聊) tag for group chat sessions and not for private chats", () => {
|
|
369
|
+
const card = buildSessionsCard([
|
|
370
|
+
{ sessionId: "g1", chatName: "group-chat", chatId: "oc_group1", active: false, turnCount: 1, elapsedSeconds: null, model: "Claude Opus 4.7", tool: "claude" },
|
|
371
|
+
{ sessionId: "p1", chatName: "private-chat", chatId: "ou_private1", active: false, turnCount: 1, elapsedSeconds: null, model: "Claude Opus 4.7", tool: "claude" },
|
|
372
|
+
]);
|
|
373
|
+
const content: string = JSON.parse(card).elements[0].text.content;
|
|
374
|
+
expect(content).toContain("(群聊)");
|
|
375
|
+
// 群聊会话包含 (群聊)
|
|
376
|
+
expect(content).toMatch(/group-chat.*\(群聊\)/);
|
|
377
|
+
// 私聊会话不包含 (群聊)
|
|
378
|
+
expect(content).toMatch(/private-chat/);
|
|
379
|
+
const afterPrivateChat = content.split("private-chat")[1];
|
|
380
|
+
expect(afterPrivateChat).not.toContain("(群聊)");
|
|
381
|
+
});
|
|
382
|
+
|
|
368
383
|
it("includes /session help text in non-empty card", () => {
|
|
369
384
|
const card = buildSessionsCard([
|
|
370
|
-
{ sessionId: "abc123", chatName: "", active: false, turnCount: 2, elapsedSeconds: null, model: "Claude Opus 4.7", tool: "claude" },
|
|
385
|
+
{ sessionId: "abc123", chatName: "", chatId: "oc_abc123", active: false, turnCount: 2, elapsedSeconds: null, model: "Claude Opus 4.7", tool: "claude" },
|
|
371
386
|
]);
|
|
372
387
|
const parsed = JSON.parse(card);
|
|
373
388
|
expect(parsed.elements[2].text.content).toContain("/session 数字");
|
package/src/session.ts
CHANGED
|
@@ -525,7 +525,7 @@ export async function runAgentSession(
|
|
|
525
525
|
ensureDisplayLoop(sessionId);
|
|
526
526
|
|
|
527
527
|
// 设置最后活跃群头像为 busy
|
|
528
|
-
const activeCid = getLastActiveChat(sessionId);
|
|
528
|
+
const activeCid = getLastActiveChat(sessionId) ?? getChatsForSession(sessionId)[0];
|
|
529
529
|
if (activeCid) {
|
|
530
530
|
setChatAvatar(token, activeCid, tool, "busy").catch(() => {});
|
|
531
531
|
}
|
|
@@ -617,7 +617,7 @@ export async function runAgentSession(
|
|
|
617
617
|
running: false,
|
|
618
618
|
});
|
|
619
619
|
}
|
|
620
|
-
const active1 = getLastActiveChat(sessionId);
|
|
620
|
+
const active1 = getLastActiveChat(sessionId) ?? getChatsForSession(sessionId)[0];
|
|
621
621
|
if (active1) setChatAvatar(token, active1, tool, "idle").catch(() => {});
|
|
622
622
|
console.log(`[${ts()}] Session ${sessionId} stopped (content chunks: ${state.chunkCount})`);
|
|
623
623
|
if (tid) logTrace(tid, "SESSION_END", { sessionId, outcome: "stopped", chunks: state.chunkCount });
|
|
@@ -634,7 +634,7 @@ export async function runAgentSession(
|
|
|
634
634
|
running: false,
|
|
635
635
|
});
|
|
636
636
|
}
|
|
637
|
-
const active2 = getLastActiveChat(sessionId);
|
|
637
|
+
const active2 = getLastActiveChat(sessionId) ?? getChatsForSession(sessionId)[0];
|
|
638
638
|
if (active2) setChatAvatar(token, active2, tool, "idle").catch(() => {});
|
|
639
639
|
console.log(`[${ts()}] Session ${sessionId} stream complete (content chunks: ${state.chunkCount})`);
|
|
640
640
|
if (tid) logTrace(tid, "SESSION_END", { sessionId, chunks: state.chunkCount, finalTextLen: finalReply.length });
|
|
@@ -664,6 +664,12 @@ export function ensureDisplayLoop(sessionId: string): void {
|
|
|
664
664
|
if (state.status !== "running") {
|
|
665
665
|
clearInterval(interval);
|
|
666
666
|
displayLoops.delete(sessionId);
|
|
667
|
+
// 兜底:lastActiveChatMap 可能因进程重启丢失,从 registry 映射恢复头像
|
|
668
|
+
const fallbackChat = getChatsForSession(sessionId)[0];
|
|
669
|
+
if (fallbackChat) {
|
|
670
|
+
const t = await import("./feishu-platform.ts").then(m => m.getTenantAccessToken());
|
|
671
|
+
setChatAvatar(t, fallbackChat, state.tool, "idle").catch(() => {});
|
|
672
|
+
}
|
|
667
673
|
}
|
|
668
674
|
return;
|
|
669
675
|
}
|