Files
claude-code-viewer/src/hooks/usePermissionRequests.ts
dobachi b7e9947efb feat: UI許可システムの実装
- permissionModeを設定可能に変更(bypassPermissions, default, acceptEdits, plan)
- defaultモード時のUI許可ダイアログを実装
  - canUseTool callbackによるプログラマティックな許可処理
  - SSEを使用したリアルタイム通信
  - 許可/拒否の選択UI
- PermissionDialog機能
  - 大きなダイアログサイズ(max-w-4xl, max-h-[80vh])
  - パラメータの折りたたみ表示
  - 各パラメータのコピーボタン
  - 長いテキストのスクロール対応
  - レスポンシブデザイン対応
2025-09-24 01:39:13 +09:00

55 lines
1.5 KiB
TypeScript

"use client";
import { useCallback, useState } from "react";
import { useServerEventListener } from "@/lib/sse/hook/useServerEventListener";
import type {
PermissionRequest,
PermissionResponse,
} from "@/types/permissions";
export const usePermissionRequests = () => {
const [currentPermissionRequest, setCurrentPermissionRequest] =
useState<PermissionRequest | null>(null);
const [isDialogOpen, setIsDialogOpen] = useState(false);
// Listen for permission requests from the server
useServerEventListener("permission_requested", (data) => {
if (data.permissionRequest) {
setCurrentPermissionRequest(data.permissionRequest);
setIsDialogOpen(true);
}
});
const handlePermissionResponse = useCallback(
async (response: PermissionResponse) => {
try {
const apiResponse = await fetch("/api/tasks/permission-response", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(response),
});
if (!apiResponse.ok) {
throw new Error("Failed to send permission response");
}
// Close the dialog
setIsDialogOpen(false);
setCurrentPermissionRequest(null);
} catch (error) {
console.error("Error sending permission response:", error);
// TODO: Show error toast to user
}
},
[],
);
return {
currentPermissionRequest,
isDialogOpen,
onPermissionResponse: handlePermissionResponse,
};
};