story-219: add Always Allow button to web UI permission dialog

Cherry-pick from feature branch — code was never squash-merged
despite story being accepted (bug 226).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-27 10:00:33 +00:00
parent de03cfe8b3
commit eeec745abc
6 changed files with 331 additions and 13 deletions

View File

@@ -11,6 +11,7 @@ export type WsRequest =
type: "permission_response";
request_id: string;
approved: boolean;
always_allow: boolean;
}
| { type: "ping" };
@@ -469,8 +470,17 @@ export class ChatWebSocket {
this.send({ type: "cancel" });
}
sendPermissionResponse(requestId: string, approved: boolean) {
this.send({ type: "permission_response", request_id: requestId, approved });
sendPermissionResponse(
requestId: string,
approved: boolean,
alwaysAllow = false,
) {
this.send({
type: "permission_response",
request_id: requestId,
approved,
always_allow: alwaysAllow,
});
}
close() {

View File

@@ -578,10 +578,14 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
}
};
const handlePermissionResponse = (approved: boolean) => {
const handlePermissionResponse = (approved: boolean, alwaysAllow = false) => {
const current = permissionQueue[0];
if (!current) return;
wsRef.current?.sendPermissionResponse(current.requestId, approved);
wsRef.current?.sendPermissionResponse(
current.requestId,
approved,
alwaysAllow,
);
setPermissionQueue((prev) => prev.slice(1));
};
@@ -1095,6 +1099,21 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
>
Approve
</button>
<button
type="button"
onClick={() => handlePermissionResponse(true, true)}
style={{
padding: "10px 20px",
borderRadius: "8px",
border: "none",
backgroundColor: "#4caf50",
color: "#fff",
cursor: "pointer",
fontSize: "0.9em",
}}
>
Always Allow
</button>
</div>
</div>
</div>

View File

@@ -53,6 +53,7 @@ export type WsRequest =
type: "permission_response";
request_id: string;
approved: boolean;
always_allow: boolean;
};
export type WsResponse =