linkshell-cli 0.3.13 → 0.3.14

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.
@@ -102,6 +102,7 @@ function extractMessageText(value: unknown): string | undefined {
102
102
  .map((part) => {
103
103
  if (typeof part === "string") return part;
104
104
  const record = asRecord(part);
105
+ if (record?.type === "tool_use" || record?.type === "tool_result") return "";
105
106
  return typeof record?.text === "string" ? record.text : "";
106
107
  })
107
108
  .join(" ");
@@ -372,15 +373,18 @@ function claudeFileEntry(name: string | undefined, input: Record<string, unknown
372
373
  if (typeof rawPath !== "string" || !rawPath.trim()) return undefined;
373
374
  const path = rawPath.trim();
374
375
  const kind = name === "Write" ? "create" : "update";
376
+ const edits = Array.isArray(input.edits) ? input.edits.map((entry) => asRecord(entry)).filter(Boolean) : [];
375
377
  const added = typeof input.new_string === "string"
376
- ? input.new_string.split(/\r?\n/).filter((line) => line.length > 0).length
378
+ ? countNonEmptyLines(input.new_string)
377
379
  : typeof input.content === "string"
378
- ? input.content.split(/\r?\n/).filter((line) => line.length > 0).length
379
- : Array.isArray(input.edits)
380
- ? input.edits.length
380
+ ? countNonEmptyLines(input.content)
381
+ : edits.length > 0
382
+ ? edits.reduce((sum, edit) => sum + countNonEmptyLines(typeof edit?.new_string === "string" ? edit.new_string : ""), 0)
381
383
  : undefined;
382
384
  const removed = typeof input.old_string === "string"
383
- ? input.old_string.split(/\r?\n/).filter((line) => line.length > 0).length
385
+ ? countNonEmptyLines(input.old_string)
386
+ : edits.length > 0
387
+ ? edits.reduce((sum, edit) => sum + countNonEmptyLines(typeof edit?.old_string === "string" ? edit.old_string : ""), 0)
384
388
  : undefined;
385
389
  const entry: NonNullable<StoredAgentTimelineItem["fileChange"]>["entries"][number] = { path, kind };
386
390
  if (added && added > 0) entry.added = added;
@@ -392,6 +396,10 @@ function claudeFileEntry(name: string | undefined, input: Record<string, unknown
392
396
  };
393
397
  }
394
398
 
399
+ function countNonEmptyLines(value: string): number {
400
+ return value.split(/\r?\n/).filter((line) => line.length > 0).length;
401
+ }
402
+
395
403
  function claudeCommandExecution(input: Record<string, unknown> | undefined): StoredAgentTimelineItem["commandExecution"] | undefined {
396
404
  if (!input) return undefined;
397
405
  const command = typeof input.command === "string" ? input.command : undefined;
@@ -473,6 +481,7 @@ function completeClaudeToolItem(
473
481
  export function loadClaudeStoredTimeline(
474
482
  sessionId: string,
475
483
  conversationId: string,
484
+ options: { maxItems?: number } = {},
476
485
  ): { items: StoredAgentTimelineItem[] } {
477
486
  const filePath = findClaudeSessionFile(sessionId);
478
487
  if (!filePath) return { items: [] };
@@ -549,6 +558,6 @@ export function loadClaudeStoredTimeline(
549
558
  return {
550
559
  items: [...itemsById.values()]
551
560
  .sort((a, b) => a.createdAt - b.createdAt)
552
- .slice(-MAX_HISTORY_ITEMS),
561
+ .slice(-Math.max(1, options.maxItems ?? MAX_HISTORY_ITEMS)),
553
562
  };
554
563
  }
@@ -14,6 +14,8 @@ export interface CodexStoredSession {
14
14
  createdAt?: number;
15
15
  lastModified: number;
16
16
  archived?: boolean;
17
+ status?: string;
18
+ runningTurnId?: string;
17
19
  }
18
20
 
19
21
  export interface StoredAgentTimelineItem {
@@ -693,6 +695,7 @@ export function loadCodexStoredTimeline(
693
695
  sessionId: string,
694
696
  conversationId: string,
695
697
  inputCwd: string,
698
+ options: { maxItems?: number } = {},
696
699
  ): { items: StoredAgentTimelineItem[] } {
697
700
  const file = findCodexSessionFile(sessionId, inputCwd);
698
701
  if (!file) return { items: [] };
@@ -794,6 +797,6 @@ export function loadCodexStoredTimeline(
794
797
  return {
795
798
  items: [...itemsById.values()]
796
799
  .sort((a, b) => a.createdAt - b.createdAt)
797
- .slice(-MAX_HISTORY_ITEMS),
800
+ .slice(-Math.max(1, options.maxItems ?? MAX_HISTORY_ITEMS)),
798
801
  };
799
802
  }
@@ -611,7 +611,9 @@ export class BridgeSession {
611
611
  case "agent.v2.cancel":
612
612
  case "agent.v2.permission.respond":
613
613
  case "agent.v2.structured_input.respond":
614
- case "agent.v2.snapshot.request": {
614
+ case "agent.v2.snapshot.request":
615
+ case "agent.v2.history.request":
616
+ case "agent.v2.delta.request": {
615
617
  if (!this.agentWorkspace) {
616
618
  this.send(
617
619
  createEnvelope({
@@ -970,10 +972,7 @@ export class BridgeSession {
970
972
  return;
971
973
  }
972
974
  const machineId = this.machineIdentity?.machineId;
973
- const enriched = machineId && (
974
- message.type === "agent.v2.capabilities" ||
975
- message.type === "agent.v2.snapshot"
976
- )
975
+ const enriched = machineId && message.type.startsWith("agent.v2.")
977
976
  ? {
978
977
  ...message,
979
978
  payload: {