linkshell-cli 0.2.67 → 0.2.69

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.
@@ -26,6 +26,8 @@ export declare class AcpClient {
26
26
  sessionId: string;
27
27
  content: unknown[];
28
28
  clientMessageId: string;
29
+ model?: string;
30
+ reasoningEffort?: string;
29
31
  }): Promise<unknown>;
30
32
  cancel(input: {
31
33
  sessionId?: string;
@@ -65,6 +65,8 @@ export class AcpClient {
65
65
  if (this.protocol === "codex-app-server") {
66
66
  return this.transport.request("turn/start", {
67
67
  threadId: input.sessionId,
68
+ model: input.model,
69
+ effort: input.reasoningEffort,
68
70
  input: input.content.map((block) => {
69
71
  const raw = block;
70
72
  if (raw.type === "image" && raw.data) {
@@ -77,7 +79,11 @@ export class AcpClient {
77
79
  return this.transport.request("session/prompt", {
78
80
  sessionId: input.sessionId,
79
81
  prompt: input.content,
80
- _meta: { linkshellClientMessageId: input.clientMessageId },
82
+ _meta: {
83
+ linkshellClientMessageId: input.clientMessageId,
84
+ model: input.model,
85
+ reasoningEffort: input.reasoningEffort,
86
+ },
81
87
  }, 60_000);
82
88
  }
83
89
  cancel(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"acp-client.js","sourceRoot":"","sources":["../../../../../src/runtime/acp/acp-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"acp-client.js","sourceRoot":"","sources":["../../../../../src/runtime/acp/acp-client.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,9 @@ export declare class AgentSessionProxy {
10
10
  private currentTurnId;
11
11
  private messages;
12
12
  private toolCalls;
13
+ private toolOutputBuffers;
14
+ private plan;
15
+ private planDeltaBuffers;
13
16
  private pendingPermissions;
14
17
  private permissionWaiters;
15
18
  private permissionSources;
@@ -31,9 +34,20 @@ export declare class AgentSessionProxy {
31
34
  private sendSessionList;
32
35
  private handleNotification;
33
36
  private handlePermission;
37
+ private handleAgentMessageDelta;
38
+ private handlePlanUpdated;
39
+ private handlePlanDelta;
40
+ private handleItemStarted;
41
+ private handleItemCompleted;
42
+ private handleToolDelta;
43
+ private handleFilePatchUpdated;
44
+ private handleCommandExecDelta;
45
+ private handleCompletedMessageItem;
46
+ private toolCallFromItem;
34
47
  private handleUpdate;
35
48
  private handleExit;
36
49
  private cancelPendingPermissions;
50
+ private upsertMessage;
37
51
  private sendCapabilities;
38
52
  private sendSnapshot;
39
53
  private sendUpdate;
@@ -23,6 +23,122 @@ function firstString(value, keys) {
23
23
  }
24
24
  return undefined;
25
25
  }
26
+ function asRecord(value) {
27
+ return typeof value === "object" && value ? value : undefined;
28
+ }
29
+ function extractItem(value) {
30
+ const raw = asRecord(value);
31
+ if (!raw)
32
+ return undefined;
33
+ return asRecord(raw.item) ?? raw;
34
+ }
35
+ function stringifyDefined(value) {
36
+ if (value === undefined || value === null || value === "")
37
+ return undefined;
38
+ return stringify(value);
39
+ }
40
+ function appendCapped(current, delta, maxLength) {
41
+ const next = `${current ?? ""}${delta}`;
42
+ if (next.length <= maxLength)
43
+ return next;
44
+ return next.slice(next.length - maxLength);
45
+ }
46
+ function decodeBase64(value) {
47
+ if (!value)
48
+ return undefined;
49
+ try {
50
+ return Buffer.from(value, "base64").toString("utf8");
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ }
56
+ function normalizeToolStatus(value, completedFallback = false) {
57
+ if (value === "completed" || value === "succeeded" || value === "success" || value === "applied") {
58
+ return "completed";
59
+ }
60
+ if (value === "failed" || value === "error" || value === "declined" || value === "cancelled") {
61
+ return "failed";
62
+ }
63
+ if (value === "pending" || value === "queued")
64
+ return "pending";
65
+ if (value === "running" || value === "inProgress" || value === "executing")
66
+ return "running";
67
+ return completedFallback ? "completed" : "running";
68
+ }
69
+ function normalizePlanStatus(value) {
70
+ if (value === "completed" || value === "done")
71
+ return "completed";
72
+ if (value === "inProgress" || value === "running" || value === "active")
73
+ return "in_progress";
74
+ return "pending";
75
+ }
76
+ function planStepFromItem(item) {
77
+ const text = firstString(item, ["text", "title", "description", "message"]);
78
+ if (!text)
79
+ return undefined;
80
+ return {
81
+ id: firstString(item, ["id", "itemId"]) ?? id("plan"),
82
+ text,
83
+ status: normalizePlanStatus(item.status),
84
+ };
85
+ }
86
+ function nameFromToolMethod(method) {
87
+ if (method.includes("commandExecution"))
88
+ return "命令";
89
+ if (method.includes("fileChange"))
90
+ return "文件修改";
91
+ if (method.includes("mcpToolCall"))
92
+ return "MCP 工具";
93
+ return "工具";
94
+ }
95
+ function toolNameFromItem(item) {
96
+ const itemType = firstString(item, ["type"]);
97
+ if (itemType === "commandExecution")
98
+ return "命令";
99
+ if (itemType === "fileChange")
100
+ return "文件修改";
101
+ if (itemType === "mcpToolCall") {
102
+ const server = firstString(item, ["server"]);
103
+ const tool = firstString(item, ["tool", "toolName", "name"]);
104
+ return [server, tool].filter(Boolean).join(" · ") || "MCP 工具";
105
+ }
106
+ if (itemType === "dynamicToolCall") {
107
+ const namespace = firstString(item, ["namespace"]);
108
+ const tool = firstString(item, ["tool", "toolName", "name"]);
109
+ return [namespace, tool].filter(Boolean).join(" · ") || "工具";
110
+ }
111
+ return firstString(item, ["toolName", "tool", "name", "title"]) ?? itemType;
112
+ }
113
+ function toolInputFromItem(item) {
114
+ const itemType = firstString(item, ["type"]);
115
+ if (itemType === "commandExecution") {
116
+ const command = firstString(item, ["command"]);
117
+ const cwd = firstString(item, ["cwd"]);
118
+ if (command && cwd)
119
+ return `${command}\n\ncwd: ${cwd}`;
120
+ return command ?? cwd;
121
+ }
122
+ if (itemType === "fileChange") {
123
+ const changes = Array.isArray(item.changes) ? item.changes : [];
124
+ return summarizeFileChanges(changes);
125
+ }
126
+ return stringifyDefined(item.arguments ?? item.input ?? item.toolInput);
127
+ }
128
+ function summarizeFileChanges(changes) {
129
+ const lines = changes
130
+ .map((change) => {
131
+ const raw = asRecord(change);
132
+ if (!raw)
133
+ return undefined;
134
+ const path = firstString(raw, ["path", "file", "filePath", "absolutePath", "relativePath"]) ??
135
+ firstString(asRecord(raw.update) ?? {}, ["path", "file", "filePath"]);
136
+ const kind = firstString(raw, ["kind", "type", "operation", "action"]);
137
+ return [kind, path].filter(Boolean).join(" ");
138
+ })
139
+ .filter((line) => Boolean(line));
140
+ return lines.length > 0 ? lines.slice(0, 8).join("\n") : undefined;
141
+ }
26
142
  export class AgentSessionProxy {
27
143
  input;
28
144
  client;
@@ -33,6 +149,9 @@ export class AgentSessionProxy {
33
149
  currentTurnId;
34
150
  messages = [];
35
151
  toolCalls = new Map();
152
+ toolOutputBuffers = new Map();
153
+ plan = [];
154
+ planDeltaBuffers = new Map();
36
155
  pendingPermissions = new Map();
37
156
  permissionWaiters = new Map();
38
157
  permissionSources = new Map();
@@ -199,6 +318,8 @@ export class AgentSessionProxy {
199
318
  sessionId: payload.agentSessionId ?? this.agentSessionId,
200
319
  content: payload.contentBlocks,
201
320
  clientMessageId: payload.clientMessageId,
321
+ model: payload.model,
322
+ reasoningEffort: payload.reasoningEffort,
202
323
  });
203
324
  this.currentTurnId = this.extractTurnId(result) ?? this.currentTurnId;
204
325
  if (this.status === "running") {
@@ -250,7 +371,12 @@ export class AgentSessionProxy {
250
371
  }
251
372
  if (method === "initialized" ||
252
373
  method.startsWith("account/") ||
253
- method.startsWith("mcpServer/startupStatus/")) {
374
+ method.startsWith("mcpServer/startupStatus/") ||
375
+ method === "thread/status/changed" ||
376
+ method === "thread/tokenUsage/updated" ||
377
+ method === "turn/diff/updated" ||
378
+ method === "serverRequest/resolved" ||
379
+ method === "mcpServer/oauthLogin/completed") {
254
380
  return;
255
381
  }
256
382
  if (method === "thread/started") {
@@ -275,11 +401,45 @@ export class AgentSessionProxy {
275
401
  this.handlePermission(params, false, method);
276
402
  return;
277
403
  }
278
- if (method === "session/update" || method.startsWith("item/")) {
404
+ switch (method) {
405
+ case "item/agentMessage/delta":
406
+ this.handleAgentMessageDelta(params);
407
+ return;
408
+ case "turn/plan/updated":
409
+ this.handlePlanUpdated(params);
410
+ return;
411
+ case "item/plan/delta":
412
+ this.handlePlanDelta(params);
413
+ return;
414
+ case "item/started":
415
+ this.handleItemStarted(params);
416
+ return;
417
+ case "item/completed":
418
+ this.handleItemCompleted(params);
419
+ return;
420
+ case "item/commandExecution/outputDelta":
421
+ case "item/fileChange/outputDelta":
422
+ case "item/mcpToolCall/progress":
423
+ this.handleToolDelta(method, params);
424
+ return;
425
+ case "item/fileChange/patchUpdated":
426
+ this.handleFilePatchUpdated(params);
427
+ return;
428
+ case "command/exec/outputDelta":
429
+ this.handleCommandExecDelta(params);
430
+ return;
431
+ case "item/autoApprovalReview/started":
432
+ case "item/autoApprovalReview/completed":
433
+ case "item/commandExecution/terminalInteraction":
434
+ return;
435
+ }
436
+ if (method === "session/update") {
279
437
  this.handleUpdate(params);
280
438
  return;
281
439
  }
282
- this.handleUpdate({ method, params });
440
+ if (this.input.verbose) {
441
+ process.stderr.write(`[agent] ignored ${method}\n`);
442
+ }
283
443
  }
284
444
  handlePermission(params, waitForResponse, source) {
285
445
  const raw = typeof params === "object" && params ? params : {};
@@ -316,12 +476,228 @@ export class AgentSessionProxy {
316
476
  this.permissionWaiters.set(requestId, { resolve, timer });
317
477
  });
318
478
  }
479
+ handleAgentMessageDelta(params) {
480
+ const raw = asRecord(params);
481
+ if (!raw)
482
+ return;
483
+ const itemId = firstString(raw, ["itemId", "id", "messageId"]) ?? id("msg");
484
+ const delta = firstString(raw, ["delta", "text", "content"]);
485
+ if (!delta)
486
+ return;
487
+ const current = this.messages.find((message) => message.id === itemId);
488
+ const message = {
489
+ id: itemId,
490
+ role: "assistant",
491
+ content: `${current?.content ?? ""}${delta}`,
492
+ createdAt: current?.createdAt ?? Date.now(),
493
+ isStreaming: true,
494
+ };
495
+ this.upsertMessage(message);
496
+ this.status = "running";
497
+ this.sendUpdate({ kind: "message_delta", message, delta, status: "running" });
498
+ }
499
+ handlePlanUpdated(params) {
500
+ const raw = asRecord(params);
501
+ const plan = Array.isArray(raw?.plan) ? raw.plan : [];
502
+ this.plan = plan
503
+ .map((entry, index) => {
504
+ const step = asRecord(entry);
505
+ const text = firstString(step ?? {}, ["text", "title", "description", "message"]);
506
+ if (!text)
507
+ return undefined;
508
+ return {
509
+ id: firstString(step ?? {}, ["id"]) ?? `plan-${index + 1}`,
510
+ text,
511
+ status: normalizePlanStatus(step?.status),
512
+ };
513
+ })
514
+ .filter((step) => Boolean(step));
515
+ if (this.plan.length > 0) {
516
+ this.sendUpdate({ kind: "plan", plan: this.plan, status: "running" });
517
+ }
518
+ }
519
+ handlePlanDelta(params) {
520
+ const raw = asRecord(params);
521
+ if (!raw)
522
+ return;
523
+ const itemId = firstString(raw, ["itemId", "id"]) ?? id("plan");
524
+ const delta = firstString(raw, ["delta", "text"]);
525
+ if (!delta)
526
+ return;
527
+ const text = `${this.planDeltaBuffers.get(itemId) ?? ""}${delta}`;
528
+ this.planDeltaBuffers.set(itemId, text);
529
+ const existing = this.plan.findIndex((step) => step.id === itemId);
530
+ const step = { id: itemId, text, status: "in_progress" };
531
+ if (existing >= 0)
532
+ this.plan[existing] = step;
533
+ else
534
+ this.plan.push(step);
535
+ this.sendUpdate({ kind: "plan", plan: this.plan, status: "running" });
536
+ }
537
+ handleItemStarted(params) {
538
+ const item = extractItem(params);
539
+ if (!item)
540
+ return;
541
+ const itemType = firstString(item, ["type"]);
542
+ if (itemType === "agentMessage" || itemType === "assistantMessage") {
543
+ this.handleCompletedMessageItem(item, true);
544
+ return;
545
+ }
546
+ if (itemType === "plan") {
547
+ const planStep = planStepFromItem(item);
548
+ if (planStep) {
549
+ const existing = this.plan.findIndex((step) => step.id === planStep.id);
550
+ if (existing >= 0)
551
+ this.plan[existing] = planStep;
552
+ else
553
+ this.plan.push(planStep);
554
+ this.sendUpdate({ kind: "plan", plan: this.plan, status: "running" });
555
+ }
556
+ return;
557
+ }
558
+ const toolCall = this.toolCallFromItem(item, "running");
559
+ if (!toolCall)
560
+ return;
561
+ this.toolCalls.set(toolCall.id, toolCall);
562
+ this.sendUpdate({ kind: "tool_call", toolCall, status: "running" });
563
+ }
564
+ handleItemCompleted(params) {
565
+ const item = extractItem(params);
566
+ if (!item)
567
+ return;
568
+ const itemType = firstString(item, ["type"]);
569
+ if (itemType === "agentMessage" || itemType === "assistantMessage") {
570
+ this.handleCompletedMessageItem(item, false);
571
+ return;
572
+ }
573
+ if (itemType === "plan") {
574
+ const planStep = planStepFromItem(item);
575
+ if (planStep) {
576
+ const existing = this.plan.findIndex((step) => step.id === planStep.id);
577
+ const completed = { ...planStep, status: "completed" };
578
+ if (existing >= 0)
579
+ this.plan[existing] = completed;
580
+ else
581
+ this.plan.push(completed);
582
+ this.sendUpdate({ kind: "plan", plan: this.plan, status: this.status === "running" ? "running" : "idle" });
583
+ }
584
+ return;
585
+ }
586
+ const toolCall = this.toolCallFromItem(item, normalizeToolStatus(item.status, true));
587
+ if (!toolCall)
588
+ return;
589
+ const bufferedOutput = this.toolOutputBuffers.get(toolCall.id);
590
+ if (bufferedOutput && !toolCall.output)
591
+ toolCall.output = bufferedOutput;
592
+ this.toolCalls.set(toolCall.id, toolCall);
593
+ this.sendUpdate({ kind: "tool_result", toolCall, status: this.status === "running" ? "running" : "idle" });
594
+ }
595
+ handleToolDelta(method, params) {
596
+ const raw = asRecord(params);
597
+ if (!raw)
598
+ return;
599
+ const itemId = firstString(raw, ["itemId", "id", "toolCallId"]) ?? id("tool");
600
+ const delta = firstString(raw, ["delta", "message", "text"]);
601
+ if (!delta)
602
+ return;
603
+ const output = appendCapped(this.toolOutputBuffers.get(itemId), delta, 6000);
604
+ this.toolOutputBuffers.set(itemId, output);
605
+ const existing = this.toolCalls.get(itemId);
606
+ const toolCall = {
607
+ id: itemId,
608
+ name: existing?.name ?? nameFromToolMethod(method),
609
+ input: existing?.input,
610
+ output,
611
+ status: "running",
612
+ };
613
+ this.toolCalls.set(itemId, toolCall);
614
+ this.sendUpdate({ kind: "tool_call", toolCall, status: "running" });
615
+ }
616
+ handleFilePatchUpdated(params) {
617
+ const raw = asRecord(params);
618
+ if (!raw)
619
+ return;
620
+ const itemId = firstString(raw, ["itemId", "id"]) ?? id("file");
621
+ const changes = Array.isArray(raw.changes) ? raw.changes : [];
622
+ const output = summarizeFileChanges(changes);
623
+ const existing = this.toolCalls.get(itemId);
624
+ const toolCall = {
625
+ id: itemId,
626
+ name: existing?.name ?? "文件修改",
627
+ input: existing?.input,
628
+ output: output || existing?.output,
629
+ status: existing?.status ?? "running",
630
+ };
631
+ this.toolCalls.set(itemId, toolCall);
632
+ this.sendUpdate({ kind: "tool_call", toolCall, status: "running" });
633
+ }
634
+ handleCommandExecDelta(params) {
635
+ const raw = asRecord(params);
636
+ if (!raw)
637
+ return;
638
+ const processId = firstString(raw, ["processId", "id"]) ?? id("exec");
639
+ const delta = firstString(raw, ["delta", "text"]) ??
640
+ decodeBase64(firstString(raw, ["deltaBase64"]));
641
+ if (!delta)
642
+ return;
643
+ const output = appendCapped(this.toolOutputBuffers.get(processId), delta, 6000);
644
+ this.toolOutputBuffers.set(processId, output);
645
+ const existing = this.toolCalls.get(processId);
646
+ const toolCall = {
647
+ id: processId,
648
+ name: existing?.name ?? "命令输出",
649
+ input: existing?.input,
650
+ output,
651
+ status: "running",
652
+ };
653
+ this.toolCalls.set(processId, toolCall);
654
+ this.sendUpdate({ kind: "tool_call", toolCall, status: "running" });
655
+ }
656
+ handleCompletedMessageItem(item, streaming) {
657
+ const itemId = firstString(item, ["id"]) ?? id("msg");
658
+ const existing = this.messages.find((message) => message.id === itemId);
659
+ const content = firstString(item, ["text", "content", "message"]) ?? existing?.content;
660
+ if (!content)
661
+ return;
662
+ const message = {
663
+ id: itemId,
664
+ role: "assistant",
665
+ content,
666
+ createdAt: existing?.createdAt ?? Date.now(),
667
+ isStreaming: streaming,
668
+ };
669
+ this.upsertMessage(message);
670
+ this.sendUpdate({
671
+ kind: streaming ? "message_delta" : "message",
672
+ message,
673
+ status: this.status === "running" ? "running" : "idle",
674
+ });
675
+ }
676
+ toolCallFromItem(item, fallbackStatus) {
677
+ const itemId = firstString(item, ["id", "itemId", "toolCallId"]);
678
+ if (!itemId)
679
+ return undefined;
680
+ const itemType = firstString(item, ["type"]);
681
+ const name = toolNameFromItem(item);
682
+ const output = firstString(item, ["aggregatedOutput", "output", "stdout", "stderr"]) ??
683
+ stringifyDefined(item.result ?? item.error ?? item.contentItems);
684
+ const bufferedOutput = this.toolOutputBuffers.get(itemId);
685
+ return {
686
+ id: itemId,
687
+ name: name ?? itemType ?? "tool",
688
+ input: toolInputFromItem(item),
689
+ output: output ?? bufferedOutput,
690
+ status: normalizeToolStatus(item.status, fallbackStatus === "completed"),
691
+ };
692
+ }
319
693
  handleUpdate(params) {
320
694
  const raw = typeof params === "object" && params ? params : {};
321
695
  const nested = typeof raw.params === "object" && raw.params ? raw.params : {};
322
696
  const text = firstString(raw, ["delta", "text", "content", "message"]) ??
323
697
  firstString(nested, ["delta", "text", "content", "message"]) ??
324
- stringify(raw.update ?? raw.params ?? params);
698
+ undefined;
699
+ if (!text)
700
+ return;
325
701
  const role = raw.role === "user" || raw.role === "system" ? raw.role : "assistant";
326
702
  if (firstString(raw, ["toolName", "tool", "name"])) {
327
703
  const toolCall = {
@@ -344,9 +720,7 @@ export class AgentSessionProxy {
344
720
  createdAt: Date.now(),
345
721
  isStreaming: raw.done === false || raw.isStreaming === true,
346
722
  };
347
- this.messages.push(message);
348
- if (this.messages.length > 100)
349
- this.messages.shift();
723
+ this.upsertMessage(message);
350
724
  this.status = raw.done === true ? "idle" : "running";
351
725
  this.sendUpdate({
352
726
  kind: "message",
@@ -370,6 +744,15 @@ export class AgentSessionProxy {
370
744
  }
371
745
  this.permissionWaiters.clear();
372
746
  }
747
+ upsertMessage(message) {
748
+ const existing = this.messages.findIndex((entry) => entry.id === message.id);
749
+ if (existing >= 0)
750
+ this.messages[existing] = message;
751
+ else
752
+ this.messages.push(message);
753
+ if (this.messages.length > 100)
754
+ this.messages.shift();
755
+ }
373
756
  sendCapabilities() {
374
757
  const enabled = Boolean(this.client && this.initialized && !this.error);
375
758
  this.input.send(createEnvelope({
@@ -385,7 +768,7 @@ export class AgentSessionProxy {
385
768
  supportsImages: false,
386
769
  supportsAudio: false,
387
770
  supportsPermission: enabled,
388
- supportsPlan: false,
771
+ supportsPlan: enabled,
389
772
  supportsCancel: enabled,
390
773
  },
391
774
  }));