mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-10-27 04:30:59 +00:00
Fix handling of local-only slash commands (#432)
Instead of parsing <local-command-stdout> tags from the message stream, intercept these commands early and forward the clean result from the success handler directly to the client. Applies to /context, /heapdump, and /extra-usage.
This commit is contained in:
@@ -227,6 +227,10 @@ function shouldHideClaudeAuth(): boolean {
|
||||
const IS_ROOT = (process.geteuid?.() ?? process.getuid?.()) === 0;
|
||||
const ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;
|
||||
|
||||
// Slash commands that the SDK handles locally without replaying the user
|
||||
// message and without invoking the model.
|
||||
const LOCAL_ONLY_COMMANDS = new Set(["/context", "/heapdump", "/extra-usage"]);
|
||||
|
||||
const PERMISSION_MODE_ALIASES: Record<string, PermissionMode> = {
|
||||
default: "default",
|
||||
acceptedits: "acceptEdits",
|
||||
@@ -471,6 +475,16 @@ export class ClaudeAcpAgent implements Agent {
|
||||
|
||||
let promptReplayed = false;
|
||||
|
||||
// These local-only commands return a result without replaying the user
|
||||
// message. Mark promptReplayed=true so their result isn't consumed as a
|
||||
// background task result.
|
||||
const firstText = params.prompt[0]?.type === "text" ? params.prompt[0].text : "";
|
||||
const isLocalOnlyCommand =
|
||||
firstText.startsWith("/") && LOCAL_ONLY_COMMANDS.has(firstText.split(" ", 1)[0]);
|
||||
if (isLocalOnlyCommand) {
|
||||
promptReplayed = true;
|
||||
}
|
||||
|
||||
if (session.promptRunning) {
|
||||
session.input.push(userMessage);
|
||||
const order = session.nextPendingOrder++;
|
||||
@@ -626,6 +640,20 @@ export class ClaudeAcpAgent implements Agent {
|
||||
if (message.is_error) {
|
||||
throw RequestError.internalError(undefined, message.result);
|
||||
}
|
||||
// For local-only commands (no model invocation), the result
|
||||
// text is the command output — forward it to the client.
|
||||
if (isLocalOnlyCommand) {
|
||||
for (const notification of toAcpNotifications(
|
||||
message.result,
|
||||
"assistant",
|
||||
params.sessionId,
|
||||
this.toolUseCache,
|
||||
this.client,
|
||||
this.logger,
|
||||
)) {
|
||||
await this.client.sessionUpdate(notification);
|
||||
}
|
||||
}
|
||||
return { stopReason: "end_turn", usage };
|
||||
}
|
||||
case "error_during_execution":
|
||||
@@ -716,22 +744,6 @@ export class ClaudeAcpAgent implements Agent {
|
||||
typeof message.message.content === "string" &&
|
||||
message.message.content.includes("<local-command-stdout>")
|
||||
) {
|
||||
// Handle /context by sending its reply as regular agent message.
|
||||
if (message.message.content.includes("Context Usage")) {
|
||||
for (const notification of toAcpNotifications(
|
||||
message.message.content
|
||||
.replace("<local-command-stdout>", "")
|
||||
.replace("</local-command-stdout>", ""),
|
||||
"assistant",
|
||||
params.sessionId,
|
||||
this.toolUseCache,
|
||||
this.client,
|
||||
this.logger,
|
||||
{ clientCapabilities: this.clientCapabilities },
|
||||
)) {
|
||||
await this.client.sessionUpdate(notification);
|
||||
}
|
||||
}
|
||||
this.logger.log(message.message.content);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user