linkshell-cli 0.3.7 → 0.3.8

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.
@@ -83,6 +83,7 @@ export declare class AgentWorkspaceProxy {
83
83
  private updateConversationPreview;
84
84
  private updateConversationStatus;
85
85
  private sendSnapshot;
86
+ private hydrateStoredTimeline;
86
87
  private conversationIdFromParams;
87
88
  private fallbackConversationId;
88
89
  private rememberTurnConversationId;
@@ -5,8 +5,8 @@ import { createEnvelope, parseTypedPayload, } from "@linkshell/protocol";
5
5
  import { AcpClient } from "./acp-client.js";
6
6
  import { ClaudeSdkClient } from "./claude-sdk-client.js";
7
7
  import { ClaudeStreamJsonClient } from "./claude-stream-json-client.js";
8
- import { listClaudeStoredSessions } from "./claude-sessions.js";
9
- import { listCodexStoredSessions } from "./codex-sessions.js";
8
+ import { listClaudeStoredSessions, loadClaudeStoredTimeline } from "./claude-sessions.js";
9
+ import { listCodexStoredSessions, loadCodexStoredTimeline } from "./codex-sessions.js";
10
10
  import { resolveAgentCommand } from "./provider-resolver.js";
11
11
  const PERMISSION_TIMEOUT_MS = 5 * 60_000;
12
12
  const MAX_TIMELINE_ITEMS = 200;
@@ -1291,16 +1291,6 @@ export class AgentWorkspaceProxy {
1291
1291
  }
1292
1292
  async openConversation(payload) {
1293
1293
  const provider = payload.provider ?? this.input.availableProviders[0];
1294
- if (!provider) {
1295
- return this.openFailure(payload, "没有可用的 Agent provider。");
1296
- }
1297
- if (!this.input.availableProviders.includes(provider)) {
1298
- return this.openFailure(payload, `${providerLabel(provider)} 未安装或不可用。`);
1299
- }
1300
- const client = await this.ensureProviderClient(provider);
1301
- if (!client) {
1302
- return this.openFailure(payload, `${providerLabel(provider)} 启动失败。请确认 CLI 已安装并可用。`);
1303
- }
1304
1294
  const cwd = payload.cwd ?? this.input.cwd;
1305
1295
  let agentSessionId = payload.agentSessionId;
1306
1296
  let existingConversation = (payload.conversationId ? this.conversations.get(payload.conversationId) : undefined) ??
@@ -1309,6 +1299,7 @@ export class AgentWorkspaceProxy {
1309
1299
  if (payload.conversationId && existingConversation.id !== payload.conversationId) {
1310
1300
  existingConversation = this.adoptConversationId(existingConversation.id, payload.conversationId);
1311
1301
  }
1302
+ this.hydrateStoredTimeline(existingConversation);
1312
1303
  this.activeConversationId = existingConversation.id;
1313
1304
  this.input.send(createEnvelope({
1314
1305
  type: "agent.v2.conversation.opened",
@@ -1320,6 +1311,16 @@ export class AgentWorkspaceProxy {
1320
1311
  }));
1321
1312
  return existingConversation;
1322
1313
  }
1314
+ if (!provider) {
1315
+ return this.openFailure(payload, "没有可用的 Agent provider。");
1316
+ }
1317
+ if (!this.input.availableProviders.includes(provider)) {
1318
+ return this.openFailure(payload, `${providerLabel(provider)} 未安装或不可用。`);
1319
+ }
1320
+ const client = await this.ensureProviderClient(provider);
1321
+ if (!client) {
1322
+ return this.openFailure(payload, `${providerLabel(provider)} 启动失败。请确认 CLI 已安装并可用。`);
1323
+ }
1323
1324
  try {
1324
1325
  const result = agentSessionId
1325
1326
  ? await client.loadSession({ sessionId: agentSessionId, cwd })
@@ -1348,6 +1349,7 @@ export class AgentWorkspaceProxy {
1348
1349
  this.conversationByAgentSessionId.set(agentSessionId, conversation.id);
1349
1350
  this.activeConversationId = conversation.id;
1350
1351
  this.timelines.set(conversation.id, this.timelines.get(conversation.id) ?? []);
1352
+ this.hydrateStoredTimeline(conversation);
1351
1353
  this.input.send(createEnvelope({
1352
1354
  type: "agent.v2.conversation.opened",
1353
1355
  hostDeviceId: this.input.hostDeviceId,
@@ -2579,6 +2581,16 @@ export class AgentWorkspaceProxy {
2579
2581
  this.emitConversation(conversation);
2580
2582
  }
2581
2583
  sendSnapshot(conversationId) {
2584
+ if (conversationId) {
2585
+ const conversation = this.conversations.get(conversationId);
2586
+ if (conversation)
2587
+ this.hydrateStoredTimeline(conversation);
2588
+ }
2589
+ else if (this.activeConversationId) {
2590
+ const conversation = this.conversations.get(this.activeConversationId);
2591
+ if (conversation)
2592
+ this.hydrateStoredTimeline(conversation);
2593
+ }
2582
2594
  const conversations = [...this.conversations.values()];
2583
2595
  const items = conversationId
2584
2596
  ? this.timelines.get(conversationId) ?? []
@@ -2593,6 +2605,34 @@ export class AgentWorkspaceProxy {
2593
2605
  },
2594
2606
  }));
2595
2607
  }
2608
+ hydrateStoredTimeline(conversation) {
2609
+ if (!conversation.agentSessionId)
2610
+ return;
2611
+ const existing = this.timelines.get(conversation.id) ?? [];
2612
+ if (existing.length > 0)
2613
+ return;
2614
+ const result = conversation.provider === "codex"
2615
+ ? loadCodexStoredTimeline(conversation.agentSessionId, conversation.id, conversation.cwd || this.input.cwd)
2616
+ : conversation.provider === "claude"
2617
+ ? loadClaudeStoredTimeline(conversation.agentSessionId, conversation.id)
2618
+ : { items: [] };
2619
+ if (result.items.length === 0)
2620
+ return;
2621
+ const items = result.items
2622
+ .sort((a, b) => a.createdAt - b.createdAt)
2623
+ .slice(-MAX_TIMELINE_ITEMS);
2624
+ this.timelines.set(conversation.id, items);
2625
+ for (const item of items)
2626
+ this.rememberItemConversationId(conversation.id, item);
2627
+ const lastMessage = [...items].reverse().find((item) => item.text?.trim());
2628
+ if (lastMessage?.text && !conversation.lastMessagePreview) {
2629
+ conversation.lastMessagePreview = previewText(lastMessage.text);
2630
+ }
2631
+ const lastActivityAt = items.at(-1)?.createdAt;
2632
+ if (lastActivityAt) {
2633
+ conversation.lastActivityAt = Math.max(conversation.lastActivityAt, lastActivityAt);
2634
+ }
2635
+ }
2596
2636
  conversationIdFromParams(params) {
2597
2637
  const raw = asRecord(params);
2598
2638
  if (!raw)