linkshell-cli 0.3.10 → 0.3.12
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/dist/cli/src/runtime/acp/agent-workspace.js +86 -18
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-sdk-client.d.ts +2 -1
- package/dist/cli/src/runtime/acp/claude-sdk-client.js +28 -0
- package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.d.ts +2 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js +27 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/codex-sessions.js +87 -4
- package/dist/cli/src/runtime/acp/codex-sessions.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/shared-protocol/src/index.d.ts +716 -716
- package/dist/shared-protocol/src/index.js +4 -4
- package/dist/shared-protocol/src/index.js.map +1 -1
- package/package.json +3 -3
- package/src/runtime/acp/agent-workspace.ts +99 -22
- package/src/runtime/acp/claude-sdk-client.ts +27 -1
- package/src/runtime/acp/claude-stream-json-client.ts +28 -2
- package/src/runtime/acp/codex-sessions.ts +88 -5
|
@@ -10,6 +10,8 @@ import { listCodexStoredSessions, loadCodexStoredTimeline } from "./codex-sessio
|
|
|
10
10
|
import { resolveAgentCommand } from "./provider-resolver.js";
|
|
11
11
|
const PERMISSION_TIMEOUT_MS = 5 * 60_000;
|
|
12
12
|
const MAX_TIMELINE_ITEMS = 200;
|
|
13
|
+
const MAX_SNAPSHOT_ITEMS = 80;
|
|
14
|
+
const MAX_SNAPSHOT_TEXT_BYTES = 128 * 1024;
|
|
13
15
|
function id(prefix) {
|
|
14
16
|
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
15
17
|
}
|
|
@@ -23,6 +25,62 @@ function stringify(value) {
|
|
|
23
25
|
return String(value);
|
|
24
26
|
}
|
|
25
27
|
}
|
|
28
|
+
function truncateUtf8(value, maxBytes = MAX_SNAPSHOT_TEXT_BYTES) {
|
|
29
|
+
if (!value)
|
|
30
|
+
return value;
|
|
31
|
+
if (Buffer.byteLength(value, "utf8") <= maxBytes)
|
|
32
|
+
return value;
|
|
33
|
+
let end = Math.min(value.length, maxBytes);
|
|
34
|
+
while (end > 0 && Buffer.byteLength(value.slice(0, end), "utf8") > maxBytes) {
|
|
35
|
+
end = Math.floor(end * 0.9);
|
|
36
|
+
}
|
|
37
|
+
return `${value.slice(0, end)}\n\n[truncated by LinkShell: original ${Buffer.byteLength(value, "utf8")} bytes]`;
|
|
38
|
+
}
|
|
39
|
+
function snapshotContentBlocks(blocks, options = {}) {
|
|
40
|
+
if (!blocks)
|
|
41
|
+
return undefined;
|
|
42
|
+
return blocks.map((block) => block.type === "image" && options.stripImages !== false
|
|
43
|
+
? { ...block, data: undefined, text: block.text || "图片附件" }
|
|
44
|
+
: { ...block, text: truncateUtf8(block.text) });
|
|
45
|
+
}
|
|
46
|
+
function snapshotTimelineItem(item, options = {}) {
|
|
47
|
+
return {
|
|
48
|
+
...item,
|
|
49
|
+
content: snapshotContentBlocks(item.content, options),
|
|
50
|
+
text: truncateUtf8(item.text),
|
|
51
|
+
toolCall: item.toolCall
|
|
52
|
+
? {
|
|
53
|
+
...item.toolCall,
|
|
54
|
+
input: truncateUtf8(item.toolCall.input),
|
|
55
|
+
output: truncateUtf8(item.toolCall.output),
|
|
56
|
+
}
|
|
57
|
+
: undefined,
|
|
58
|
+
commandExecution: item.commandExecution
|
|
59
|
+
? {
|
|
60
|
+
...item.commandExecution,
|
|
61
|
+
command: truncateUtf8(item.commandExecution.command, 16 * 1024),
|
|
62
|
+
output: truncateUtf8(item.commandExecution.output),
|
|
63
|
+
}
|
|
64
|
+
: undefined,
|
|
65
|
+
fileChange: item.fileChange
|
|
66
|
+
? {
|
|
67
|
+
...item.fileChange,
|
|
68
|
+
diff: truncateUtf8(item.fileChange.diff),
|
|
69
|
+
summary: truncateUtf8(item.fileChange.summary),
|
|
70
|
+
}
|
|
71
|
+
: undefined,
|
|
72
|
+
permission: item.permission
|
|
73
|
+
? {
|
|
74
|
+
...item.permission,
|
|
75
|
+
toolInput: truncateUtf8(item.permission.toolInput),
|
|
76
|
+
context: truncateUtf8(item.permission.context),
|
|
77
|
+
}
|
|
78
|
+
: undefined,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function snapshotTimelineItems(items) {
|
|
82
|
+
return items.slice(-MAX_SNAPSHOT_ITEMS).map((item) => snapshotTimelineItem(item));
|
|
83
|
+
}
|
|
26
84
|
function asRecord(value) {
|
|
27
85
|
return typeof value === "object" && value ? value : undefined;
|
|
28
86
|
}
|
|
@@ -556,6 +614,8 @@ function providerLabel(provider) {
|
|
|
556
614
|
return "Custom";
|
|
557
615
|
}
|
|
558
616
|
const ALL_REASONING_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh"];
|
|
617
|
+
const CLAUDE_REASONING_EFFORTS = ["low", "medium", "high", "xhigh"];
|
|
618
|
+
const AGENT_PERMISSION_MODES = ["read_only", "workspace_write", "full_access"];
|
|
559
619
|
const CLAUDE_REMOTE_HIDDEN_COMMANDS = new Set([
|
|
560
620
|
"add-dir",
|
|
561
621
|
"agents",
|
|
@@ -1236,7 +1296,7 @@ export class AgentWorkspaceProxy {
|
|
|
1236
1296
|
const supportsImages = enabled && protocolSupportsImages(protocol);
|
|
1237
1297
|
const isClaudeFallback = protocol === "claude-stream-json";
|
|
1238
1298
|
const supportsPermission = enabled && !isClaudeFallback;
|
|
1239
|
-
const supportsReasoningEffort = enabled
|
|
1299
|
+
const supportsReasoningEffort = enabled;
|
|
1240
1300
|
const commands = mergeCommands(defaultProviderCommands(provider, this.input.cwd, enabled), runtimeCapabilities?.commands);
|
|
1241
1301
|
const currentMode = [...this.conversations.values()].find((conversation) => conversation.provider === provider)?.collaborationMode;
|
|
1242
1302
|
return {
|
|
@@ -1248,12 +1308,12 @@ export class AgentWorkspaceProxy {
|
|
|
1248
1308
|
supportsPermission,
|
|
1249
1309
|
supportsPlan: enabled,
|
|
1250
1310
|
supportsCancel: enabled,
|
|
1251
|
-
models: runtimeCapabilities?.models,
|
|
1311
|
+
models: runtimeCapabilities?.models ?? [{ id: "default", label: "默认模型" }],
|
|
1252
1312
|
defaultModel: runtimeCapabilities?.defaultModel,
|
|
1253
1313
|
reasoningEfforts: supportsReasoningEffort
|
|
1254
|
-
? runtimeCapabilities?.reasoningEfforts ?? []
|
|
1314
|
+
? runtimeCapabilities?.reasoningEfforts ?? (provider === "claude" ? [...CLAUDE_REASONING_EFFORTS] : [...ALL_REASONING_EFFORTS])
|
|
1255
1315
|
: [],
|
|
1256
|
-
permissionModes: [],
|
|
1316
|
+
permissionModes: supportsPermission ? AGENT_PERMISSION_MODES : [],
|
|
1257
1317
|
commands,
|
|
1258
1318
|
modes: runtimeCapabilities?.modes ?? [],
|
|
1259
1319
|
currentMode,
|
|
@@ -1306,7 +1366,7 @@ export class AgentWorkspaceProxy {
|
|
|
1306
1366
|
hostDeviceId: this.input.hostDeviceId,
|
|
1307
1367
|
payload: {
|
|
1308
1368
|
conversation: existingConversation,
|
|
1309
|
-
snapshot: this.timelines.get(existingConversation.id) ?? [],
|
|
1369
|
+
snapshot: snapshotTimelineItems(this.timelines.get(existingConversation.id) ?? []),
|
|
1310
1370
|
},
|
|
1311
1371
|
}));
|
|
1312
1372
|
return existingConversation;
|
|
@@ -1353,7 +1413,7 @@ export class AgentWorkspaceProxy {
|
|
|
1353
1413
|
this.input.send(createEnvelope({
|
|
1354
1414
|
type: "agent.v2.conversation.opened",
|
|
1355
1415
|
hostDeviceId: this.input.hostDeviceId,
|
|
1356
|
-
payload: { conversation, snapshot: this.timelines.get(conversation.id) ?? [] },
|
|
1416
|
+
payload: { conversation, snapshot: snapshotTimelineItems(this.timelines.get(conversation.id) ?? []) },
|
|
1357
1417
|
}));
|
|
1358
1418
|
return conversation;
|
|
1359
1419
|
}
|
|
@@ -1392,7 +1452,7 @@ export class AgentWorkspaceProxy {
|
|
|
1392
1452
|
this.input.send(createEnvelope({
|
|
1393
1453
|
type: "agent.v2.conversation.opened",
|
|
1394
1454
|
hostDeviceId: this.input.hostDeviceId,
|
|
1395
|
-
payload: { conversation, snapshot: this.timelines.get(conversation.id) ?? [] },
|
|
1455
|
+
payload: { conversation, snapshot: snapshotTimelineItems(this.timelines.get(conversation.id) ?? []) },
|
|
1396
1456
|
}));
|
|
1397
1457
|
return conversation;
|
|
1398
1458
|
}
|
|
@@ -1436,10 +1496,18 @@ export class AgentWorkspaceProxy {
|
|
|
1436
1496
|
});
|
|
1437
1497
|
return;
|
|
1438
1498
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1499
|
+
if (Object.prototype.hasOwnProperty.call(payload, "model")) {
|
|
1500
|
+
conversation.model = payload.model ?? undefined;
|
|
1501
|
+
}
|
|
1502
|
+
if (Object.prototype.hasOwnProperty.call(payload, "reasoningEffort")) {
|
|
1503
|
+
conversation.reasoningEffort = payload.reasoningEffort ?? undefined;
|
|
1504
|
+
}
|
|
1505
|
+
if (Object.prototype.hasOwnProperty.call(payload, "permissionMode")) {
|
|
1506
|
+
conversation.permissionMode = payload.permissionMode ?? undefined;
|
|
1507
|
+
}
|
|
1508
|
+
if (Object.prototype.hasOwnProperty.call(payload, "collaborationMode")) {
|
|
1509
|
+
conversation.collaborationMode = payload.collaborationMode ?? "default";
|
|
1510
|
+
}
|
|
1443
1511
|
conversation.status = "running";
|
|
1444
1512
|
conversation.lastActivityAt = Date.now();
|
|
1445
1513
|
this.activeConversationId = conversation.id;
|
|
@@ -1459,10 +1527,10 @@ export class AgentWorkspaceProxy {
|
|
|
1459
1527
|
sessionId: conversation.agentSessionId,
|
|
1460
1528
|
content: payload.contentBlocks,
|
|
1461
1529
|
clientMessageId: payload.clientMessageId,
|
|
1462
|
-
model:
|
|
1463
|
-
reasoningEffort:
|
|
1464
|
-
permissionMode:
|
|
1465
|
-
collaborationMode:
|
|
1530
|
+
model: conversation.model,
|
|
1531
|
+
reasoningEffort: conversation.reasoningEffort,
|
|
1532
|
+
permissionMode: conversation.permissionMode,
|
|
1533
|
+
collaborationMode: conversation.collaborationMode,
|
|
1466
1534
|
cwd: conversation.cwd,
|
|
1467
1535
|
});
|
|
1468
1536
|
const nextAgentSessionId = this.extractSessionId(result);
|
|
@@ -2540,7 +2608,7 @@ export class AgentWorkspaceProxy {
|
|
|
2540
2608
|
this.input.send(createEnvelope({
|
|
2541
2609
|
type: "agent.v2.event",
|
|
2542
2610
|
hostDeviceId: this.input.hostDeviceId,
|
|
2543
|
-
payload: { conversationId, conversation, item },
|
|
2611
|
+
payload: { conversationId, conversation, item: snapshotTimelineItem(item, { stripImages: false }) },
|
|
2544
2612
|
}));
|
|
2545
2613
|
}
|
|
2546
2614
|
emitConversation(conversation) {
|
|
@@ -2593,8 +2661,8 @@ export class AgentWorkspaceProxy {
|
|
|
2593
2661
|
}
|
|
2594
2662
|
const conversations = [...this.conversations.values()];
|
|
2595
2663
|
const items = conversationId
|
|
2596
|
-
? this.timelines.get(conversationId) ?? []
|
|
2597
|
-
: [
|
|
2664
|
+
? snapshotTimelineItems(this.timelines.get(conversationId) ?? [])
|
|
2665
|
+
: [];
|
|
2598
2666
|
this.input.send(createEnvelope({
|
|
2599
2667
|
type: "agent.v2.snapshot",
|
|
2600
2668
|
hostDeviceId: this.input.hostDeviceId,
|