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:
qystishere
2026-03-25 00:23:26 +03:00
committed by GitHub
parent 34c847a9e3
commit 07db59ef0d

View File

@@ -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;
}