linkshell-cli 0.3.21 → 0.3.22
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/acp-client.js +44 -12
- package/dist/cli/src/runtime/acp/acp-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/agent-workspace.js +4 -1
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/runtime/acp/acp-client.ts +43 -12
- package/src/runtime/acp/agent-workspace.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linkshell-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.22",
|
|
4
4
|
"description": "Remote terminal bridge for Claude Code / Codex / Gemini / Copilot — control from your phone",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cli/src/index.js",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"qrcode-terminal": "^0.12.0",
|
|
36
36
|
"ws": "^8.18.1",
|
|
37
37
|
"zod": "^4.4.3",
|
|
38
|
-
"@linkshell/
|
|
39
|
-
"@linkshell/
|
|
38
|
+
"@linkshell/gateway": "0.3.8",
|
|
39
|
+
"@linkshell/protocol": "0.3.10"
|
|
40
40
|
},
|
|
41
41
|
"optionalDependencies": {
|
|
42
42
|
"@anthropic-ai/claude-agent-sdk": "^0.2.128",
|
|
@@ -114,6 +114,37 @@ function permissionsForMode(
|
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
function sandboxPolicyForMode(
|
|
118
|
+
mode: AgentPermissionMode | undefined,
|
|
119
|
+
cwd: string,
|
|
120
|
+
): unknown | undefined {
|
|
121
|
+
if (mode === "full_access") return { type: "dangerFullAccess" };
|
|
122
|
+
if (mode === "read_only") return { type: "readOnly", networkAccess: false };
|
|
123
|
+
if (mode === "workspace_write") {
|
|
124
|
+
return {
|
|
125
|
+
type: "workspaceWrite",
|
|
126
|
+
writableRoots: [cwd],
|
|
127
|
+
networkAccess: false,
|
|
128
|
+
excludeTmpdirEnvVar: false,
|
|
129
|
+
excludeSlashTmp: false,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function approvalPolicyForMode(mode: AgentPermissionMode | undefined): unknown | undefined {
|
|
136
|
+
if (mode === "full_access") return "never";
|
|
137
|
+
if (mode === "read_only" || mode === "workspace_write") return "on-request";
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function sandboxModeForMode(mode: AgentPermissionMode | undefined): unknown | undefined {
|
|
142
|
+
if (mode === "full_access") return "danger-full-access";
|
|
143
|
+
if (mode === "read_only") return "read-only";
|
|
144
|
+
if (mode === "workspace_write") return "workspace-write";
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
117
148
|
export class AcpClient {
|
|
118
149
|
private readonly transport: JsonRpcStdioTransport;
|
|
119
150
|
private readonly protocol: AgentProtocol;
|
|
@@ -229,33 +260,33 @@ export class AcpClient {
|
|
|
229
260
|
cwd: string;
|
|
230
261
|
}): Promise<unknown> {
|
|
231
262
|
if (this.protocol === "codex-app-server") {
|
|
232
|
-
const
|
|
233
|
-
...(input.model ? { model: input.model } : {}),
|
|
234
|
-
...(input.reasoningEffort ? { reasoning_effort: input.reasoningEffort } : {}),
|
|
235
|
-
...(input.serviceTier ? { service_tier: input.serviceTier } : {}),
|
|
236
|
-
};
|
|
237
|
-
const collaborationMode = input.collaborationMode && input.collaborationMode !== "default"
|
|
263
|
+
const collaborationMode = input.collaborationMode && input.model
|
|
238
264
|
? {
|
|
239
265
|
mode: input.collaborationMode,
|
|
240
|
-
settings:
|
|
266
|
+
settings: {
|
|
267
|
+
model: input.model,
|
|
268
|
+
reasoning_effort: input.reasoningEffort ?? null,
|
|
269
|
+
developer_instructions: null,
|
|
270
|
+
},
|
|
241
271
|
}
|
|
242
272
|
: undefined;
|
|
243
273
|
return this.transport.request("turn/start", {
|
|
244
274
|
threadId: input.sessionId,
|
|
245
275
|
model: input.model,
|
|
246
276
|
effort: input.reasoningEffort,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
277
|
+
...(input.serviceTier === "fast" ? { serviceTier: input.serviceTier } : {}),
|
|
278
|
+
...(approvalPolicyForMode(input.permissionMode) ? { approvalPolicy: approvalPolicyForMode(input.permissionMode) } : {}),
|
|
279
|
+
...(sandboxPolicyForMode(input.permissionMode, input.cwd) ? { sandboxPolicy: sandboxPolicyForMode(input.permissionMode, input.cwd) } : {}),
|
|
280
|
+
...(collaborationMode ? { collaborationMode } : {}),
|
|
250
281
|
input: input.content.map((block) => {
|
|
251
282
|
const raw = block as { type?: string; text?: string; data?: string; path?: string; name?: string };
|
|
252
283
|
if (raw.type === "image" && raw.data) {
|
|
253
284
|
return { type: "image", url: raw.data };
|
|
254
285
|
}
|
|
255
286
|
if (raw.type === "file" && raw.path) {
|
|
256
|
-
return { type: "
|
|
287
|
+
return { type: "mention", path: raw.path, name: raw.name };
|
|
257
288
|
}
|
|
258
|
-
return { type: "text", text: raw.text ?? "" };
|
|
289
|
+
return { type: "text", text: raw.text ?? "", text_elements: [] };
|
|
259
290
|
}),
|
|
260
291
|
}, null);
|
|
261
292
|
}
|
|
@@ -918,6 +918,7 @@ const LINKSHELL_NATIVE_COMMANDS: Array<{
|
|
|
918
918
|
{ name: "review", description: "Ask the Agent to review current local changes", category: "Agent", argsMode: "optional" },
|
|
919
919
|
{ name: "subagents", description: "Ask the Agent to split work across subagents when useful", category: "Agent", argsMode: "optional" },
|
|
920
920
|
{ name: "compact", description: "Compact the active Codex context", category: "Codex", argsMode: "none", providers: ["codex"] },
|
|
921
|
+
{ name: "new", description: "Start a fresh Codex thread", category: "Codex", argsMode: "none", providers: ["codex"], destructive: true },
|
|
921
922
|
{ name: "clear", description: "Start a fresh Agent context for this conversation", category: "Agent", argsMode: "none", destructive: true },
|
|
922
923
|
{ name: "git-status", description: "Show branch and working tree status", category: "Git", argsMode: "none" },
|
|
923
924
|
{ name: "git-diff", description: "Show a compact diffstat for current changes", category: "Git", argsMode: "none" },
|
|
@@ -927,6 +928,7 @@ const LINKSHELL_NATIVE_COMMANDS: Array<{
|
|
|
927
928
|
{ name: "git-stash", description: "Stash current working tree changes", category: "Git", argsMode: "optional" },
|
|
928
929
|
{ name: "git-stash-pop", description: "Pop the latest stash", category: "Git", argsMode: "none" },
|
|
929
930
|
];
|
|
931
|
+
const CODEX_JSON_RPC_COMMANDS = new Set(["plan", "exit-plan", "review", "compact", "new"]);
|
|
930
932
|
const CLAUDE_REMOTE_HIDDEN_COMMANDS = new Set([
|
|
931
933
|
"add-dir",
|
|
932
934
|
"agents",
|
|
@@ -1200,6 +1202,7 @@ function customClaudeCommands(cwd: string): AgentCommandDescriptor[] {
|
|
|
1200
1202
|
function defaultProviderCommands(provider: AgentProvider, cwd: string, enabled: boolean): AgentCommandDescriptor[] {
|
|
1201
1203
|
const disabledReason = enabled ? undefined : `${providerLabel(provider)} 未安装或启动失败`;
|
|
1202
1204
|
const linkshellCommands = LINKSHELL_NATIVE_COMMANDS
|
|
1205
|
+
.filter((command) => provider !== "codex" || CODEX_JSON_RPC_COMMANDS.has(command.name))
|
|
1203
1206
|
.filter((command) => !command.providers || command.providers.includes(provider))
|
|
1204
1207
|
.map((command) => makeCommand({
|
|
1205
1208
|
provider,
|
|
@@ -2384,7 +2387,7 @@ export class AgentWorkspaceProxy {
|
|
|
2384
2387
|
return;
|
|
2385
2388
|
}
|
|
2386
2389
|
|
|
2387
|
-
if (command.name === "clear") {
|
|
2390
|
+
if (command.name === "clear" || command.name === "new") {
|
|
2388
2391
|
if (!client) throw new Error("Agent provider 不在线。");
|
|
2389
2392
|
const result = await client.newSession({ cwd: conversation.cwd });
|
|
2390
2393
|
const nextAgentSessionId = this.extractSessionId(result) ?? id("agent-session");
|