From 8b43b165223436556007aa34dae056aa5320a873 Mon Sep 17 00:00:00 2001 From: d-kimsuon Date: Sun, 26 Oct 2025 21:26:44 +0900 Subject: [PATCH] chore: disable permisseion setting if feature unavailable --- src/components/SettingsControls.tsx | 15 +++++- src/components/SystemInfoCard.tsx | 44 +++++------------ src/hooks/useFeatureFlags.ts | 29 ++++++++++++ src/lib/api/queries.ts | 13 +++++ src/lib/i18n/locales/en/messages.json | 47 +++++++++++-------- src/lib/i18n/locales/en/messages.ts | 2 +- src/lib/i18n/locales/ja/messages.json | 47 +++++++++++-------- src/lib/i18n/locales/ja/messages.ts | 2 +- src/server/core/feature-flag/models/flag.ts | 11 +++++ .../presentation/FeatureFlagController.ts | 43 +++++++++++++++++ src/server/hono/route.ts | 14 ++++++ src/server/main.ts | 2 + 12 files changed, 194 insertions(+), 75 deletions(-) create mode 100644 src/hooks/useFeatureFlags.ts create mode 100644 src/server/core/feature-flag/models/flag.ts create mode 100644 src/server/core/feature-flag/presentation/FeatureFlagController.ts diff --git a/src/components/SettingsControls.tsx b/src/components/SettingsControls.tsx index 69840f9..164e559 100644 --- a/src/components/SettingsControls.tsx +++ b/src/components/SettingsControls.tsx @@ -10,6 +10,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { useFeatureFlags } from "@/hooks/useFeatureFlags"; import { useTheme } from "@/hooks/useTheme"; import { projectDetailQuery, projectListQuery } from "../lib/api/queries"; import type { SupportedLocale } from "../lib/i18n/schema"; @@ -36,6 +37,9 @@ export const SettingsControls: FC = ({ const queryClient = useQueryClient(); const { theme } = useTheme(); const { i18n } = useLingui(); + const { isFlagEnabled } = useFeatureFlags(); + + const isToolApprovalAvailable = isFlagEnabled("tool-approval"); const handleHideNoUserMessageChange = async () => { const newConfig = { @@ -222,6 +226,7 @@ export const SettingsControls: FC = ({ - {showDescriptions && ( + {showDescriptions && isToolApprovalAvailable && (

= ({ />

)} + {showDescriptions && !isToolApprovalAvailable && ( +

+ +

+ )}
diff --git a/src/components/SystemInfoCard.tsx b/src/components/SystemInfoCard.tsx index 2da9b72..d71cbde 100644 --- a/src/components/SystemInfoCard.tsx +++ b/src/components/SystemInfoCard.tsx @@ -2,11 +2,8 @@ import { Trans } from "@lingui/react"; import { useSuspenseQuery } from "@tanstack/react-query"; import { CheckCircle2, ChevronDown, ChevronRight, XCircle } from "lucide-react"; import { type FC, type ReactNode, useState } from "react"; -import { - claudeCodeFeaturesQuery, - claudeCodeMetaQuery, - systemVersionQuery, -} from "@/lib/api/queries"; +import { useFeatureFlags } from "@/hooks/useFeatureFlags"; +import { claudeCodeMetaQuery, systemVersionQuery } from "@/lib/api/queries"; import { Badge } from "./ui/badge"; import { Collapsible, @@ -27,48 +24,33 @@ interface FeatureInfo { const getFeatureInfo = (featureName: string): FeatureInfo => { switch (featureName) { - case "canUseTool": + case "tool-approval": return { title: ( ), description: ( ), }; - case "uuidOnSDKMessage": - return { - title: ( - - ), - description: ( - - ), - }; - case "agentSdk": + case "agent-sdk": return { title: ( ), description: ( ), }; @@ -96,9 +78,7 @@ export const SystemInfoCard: FC = () => { ...claudeCodeMetaQuery, }); - const { data: claudeCodeFeaturesData } = useSuspenseQuery({ - ...claudeCodeFeaturesQuery, - }); + const { flags } = useFeatureFlags(); return (
@@ -185,7 +165,7 @@ export const SystemInfoCard: FC = () => {
    - {claudeCodeFeaturesData?.features.map(({ name, enabled }) => { + {flags.map(({ name, enabled }) => { const featureInfo = getFeatureInfo(name); return (
  • diff --git a/src/hooks/useFeatureFlags.ts b/src/hooks/useFeatureFlags.ts new file mode 100644 index 0000000..9e68d15 --- /dev/null +++ b/src/hooks/useFeatureFlags.ts @@ -0,0 +1,29 @@ +import { useSuspenseQuery } from "@tanstack/react-query"; +import { useCallback, useMemo } from "react"; +import { featureFlagsQuery } from "../lib/api/queries"; +import type { FlagName } from "../server/core/feature-flag/models/flag"; + +export const useFeatureFlags = () => { + const { data } = useSuspenseQuery({ + queryKey: featureFlagsQuery.queryKey, + queryFn: featureFlagsQuery.queryFn, + }); + + const enabledFlags = useMemo(() => { + return new Set( + data.flags.filter((flag) => flag.enabled).map((flag) => flag.name), + ); + }, [data.flags]); + + const isFlagEnabled = useCallback( + (flagName: FlagName) => { + return enabledFlags.has(flagName); + }, + [enabledFlags], + ); + + return { + flags: data.flags, + isFlagEnabled, + } as const; +}; diff --git a/src/lib/api/queries.ts b/src/lib/api/queries.ts index e58534c..2538821 100644 --- a/src/lib/api/queries.ts +++ b/src/lib/api/queries.ts @@ -262,3 +262,16 @@ export const schedulerJobsQuery = { return await response.json(); }, } as const; + +export const featureFlagsQuery = { + queryKey: ["flags"], + queryFn: async () => { + const response = await honoClient.api.flags.$get(); + + if (!response.ok) { + throw new Error(`Failed to fetch feature flags: ${response.statusText}`); + } + + return await response.json(); + }, +} as const; diff --git a/src/lib/i18n/locales/en/messages.json b/src/lib/i18n/locales/en/messages.json index 88a8354..a63ba02 100644 --- a/src/lib/i18n/locales/en/messages.json +++ b/src/lib/i18n/locales/en/messages.json @@ -368,11 +368,11 @@ "translation": "Choose your preferred language" }, "system_info.feature.agent_sdk.title": { - "message": "Claude Agent SDK", + "message": "Enhanced Agent Mode", "placeholders": {}, "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 65]], - "translation": "Claude Agent SDK" + "origin": [["src/components/SystemInfoCard.tsx", 49]], + "translation": "Enhanced Agent Mode" }, "system_info.claude_code": { "message": "Claude Code", @@ -486,6 +486,13 @@ "origin": [["src/components/SettingsControls.tsx", 255]], "translation": "Control how Claude Code handles permission requests for file operations" }, + "settings.permission.mode.unavailable": { + "message": "This feature is not available in your Claude Code version. All tools will be automatically approved.", + "placeholders": {}, + "comments": [], + "origin": [["src/components/SettingsControls.tsx", 272]], + "translation": "This feature is not available in your Claude Code version. All tools will be automatically approved." + }, "session.conversation.in.progress": { "message": "Conversation is in progress...", "placeholders": {}, @@ -599,13 +606,6 @@ "origin": [["src/components/GlobalSidebar.tsx", 56]], "translation": "Display and behavior preferences" }, - "system_info.feature.can_use_tool.description": { - "message": "Dynamically control tool usage permissions and request user approval before tool execution (v1.0.82+)", - "placeholders": {}, - "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 41]], - "translation": "Dynamically control tool usage permissions and request user approval before tool execution (v1.0.82+)" - }, "settings.locale.en": { "message": "English", "placeholders": {}, @@ -1506,13 +1506,6 @@ ], "translation": "Tool Result" }, - "system_info.feature.can_use_tool.title": { - "message": "Tool Use Permission Control", - "placeholders": {}, - "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 35]], - "translation": "Tool Use Permission Control" - }, "sessions.total": { "message": "total", "placeholders": {}, @@ -1629,11 +1622,25 @@ "translation": "Document type not supported for display" }, "system_info.feature.agent_sdk.description": { - "message": "Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)", + "message": "Uses @anthropic-ai/claude-agent-sdk instead of @anthropic-ai/claude-code for enhanced capabilities", "placeholders": {}, "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 71]], - "translation": "Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)" + "origin": [["src/components/SystemInfoCard.tsx", 53]], + "translation": "Uses @anthropic-ai/claude-agent-sdk instead of @anthropic-ai/claude-code for enhanced capabilities" + }, + "system_info.feature.tool_approval.title": { + "message": "Tool Execution Approval", + "placeholders": {}, + "comments": [], + "origin": [["src/components/SystemInfoCard.tsx", 35]], + "translation": "Tool Execution Approval" + }, + "system_info.feature.tool_approval.description": { + "message": "Allows you to approve or reject tool executions before Claude runs them, giving you full control over actions", + "placeholders": {}, + "comments": [], + "origin": [["src/components/SystemInfoCard.tsx", 41]], + "translation": "Allows you to approve or reject tool executions before Claude runs them, giving you full control over actions" }, "system_info.version_label": { "message": "Version", diff --git a/src/lib/i18n/locales/en/messages.ts b/src/lib/i18n/locales/en/messages.ts index e1badd9..1326498 100644 --- a/src/lib/i18n/locales/en/messages.ts +++ b/src/lib/i18n/locales/en/messages.ts @@ -1 +1 @@ -/*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"Available commands\":[\"Available commands\"],\"Available files and directories\":[\"Available files and directories\"],\"Close sidebar\":[\"Close sidebar\"],\"Compare from\":[\"Compare from\"],\"Compare to\":[\"Compare to\"],\"Failed to commit\":[\"Failed to commit\"],\"Failed to commit and push\":[\"Failed to commit and push\"],\"Failed to push\":[\"Failed to push\"],\"Message input with completion support\":[\"Message input with completion support\"],\"Reload MCP servers\":[\"Reload MCP servers\"],\"Retry Push\":[\"Retry Push\"],\"Select enter key behavior\":[\"Select enter key behavior\"],\"Select language\":[\"Select language\"],\"Select permission mode\":[\"Select permission mode\"],\"Select theme\":[\"Select theme\"],\"Type your message here... (Start with / for commands, @ for files, Command+Enter to send)\":[\"Type your message here... (Start with / for commands, @ for files, Command+Enter to send)\"],\"Type your message here... (Start with / for commands, @ for files, Enter to send)\":[\"Type your message here... (Start with / for commands, @ for files, Enter to send)\"],\"Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)\"],\"Type your message... (Start with / for commands, @ for files, Command+Enter to send)\":[\"Type your message... (Start with / for commands, @ for files, Command+Enter to send)\"],\"Type your message... (Start with / for commands, @ for files, Enter to send)\":[\"Type your message... (Start with / for commands, @ for files, Enter to send)\"],\"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)\"],\"Uncommitted changes\":[\"Uncommitted changes\"],\"assistant.thinking\":[\"Thinking\"],\"assistant.tool.input_parameters\":[\"Input Parameters\"],\"assistant.tool.message_count\":[[\"count\"],\" messages\"],\"assistant.tool.result\":[\"Tool Result\"],\"assistant.tool.task_id\":[\"Task ID\"],\"assistant.tool.tool_id\":[\"Tool ID\"],\"assistant.tool.view_task\":[\"View Task\"],\"assistant.tool.view_task_details\":[\"View Task\"],\"chat.autocomplete.active\":[\"Autocomplete active\"],\"chat.button.start\":[\"Start Chat\"],\"chat.error.send_failed\":[\"Failed to send message. Please try again.\"],\"chat.modal.title\":[\"Start New Chat\"],\"chat.resume\":[\"Resume\"],\"chat.send\":[\"Send\"],\"chat.status.processing\":[\"Processing...\"],\"common.action.cancel\":[\"Cancel\"],\"common.error\":[\"Error\"],\"common.loading\":[\"Loading...\"],\"conversation.error.raw_content\":[\"Raw Content:\"],\"conversation.error.report_issue\":[\"Report this issue\"],\"conversation.error.schema\":[\"Schema Error\"],\"conversation.error.schema_validation\":[\"Schema Validation Error\"],\"conversation.error.schema_validation.description\":[\"This conversation entry failed to parse correctly. This might indicate a format change or parsing issue.\"],\"cron_builder.cron_expression\":[\"Cron Expression\"],\"cron_builder.custom\":[\"Custom\"],\"cron_builder.daily\":[\"Daily\"],\"cron_builder.day_of_week\":[\"Day of Week\"],\"cron_builder.expression\":[\"Expression\"],\"cron_builder.friday\":[\"Friday\"],\"cron_builder.hour\":[\"Hour (0-23)\"],\"cron_builder.hourly\":[\"Hourly\"],\"cron_builder.minute\":[\"Minute (0-59)\"],\"cron_builder.monday\":[\"Monday\"],\"cron_builder.preview\":[\"Preview\"],\"cron_builder.saturday\":[\"Saturday\"],\"cron_builder.schedule_type\":[\"Schedule Type\"],\"cron_builder.sunday\":[\"Sunday\"],\"cron_builder.thursday\":[\"Thursday\"],\"cron_builder.tuesday\":[\"Tuesday\"],\"cron_builder.wednesday\":[\"Wednesday\"],\"cron_builder.weekly\":[\"Weekly\"],\"diff.commit\":[\"Commit\"],\"diff.commit.changes\":[\"Commit Changes\"],\"diff.commit.message\":[\"Commit message\"],\"diff.commit.push\":[\"Commit & Push\"],\"diff.committing\":[\"Committing...\"],\"diff.committing.pushing\":[\"Committing & Pushing...\"],\"diff.deselect.all\":[\"Deselect All\"],\"diff.enter.message\":[\"Enter a commit message\"],\"diff.files\":[\"files\"],\"diff.files.changed\":[\"files changed\"],\"diff.loading\":[\"Loading diff...\"],\"diff.push\":[\"Push\"],\"diff.pushing\":[\"Pushing...\"],\"diff.select.all\":[\"Select All\"],\"diff.select.file\":[\"Select at least one file\"],\"directory_picker.current\":[\"Current:\"],\"directory_picker.loading\":[\"Loading...\"],\"directory_picker.no_directories\":[\"No directories found\"],\"directory_picker.select\":[\"Select This Directory\"],\"mcp.error.load_failed\":[\"Failed to load MCP servers: \",[\"error\"]],\"mcp.no.servers\":[\"No MCP servers found\"],\"mcp.title\":[\"MCP Servers\"],\"notfound.button.go_home\":[\"Go to Home\"],\"notfound.default.description\":[\"The page you are looking for does not exist or has been moved.\"],\"notfound.default.title\":[\"Page Not Found\"],\"notfound.project.description\":[\"The project you are looking for does not exist.\"],\"notfound.project.title\":[\"Project Not Found\"],\"notfound.session.description\":[\"The session you are looking for does not exist.\"],\"notfound.session.title\":[\"Session Not Found\"],\"notification.beep\":[\"Beep\"],\"notification.chime\":[\"Chime\"],\"notification.description\":[\"Select a sound to play when a task completes\"],\"notification.none\":[\"None\"],\"notification.ping\":[\"Ping\"],\"notification.pop\":[\"Pop\"],\"notification.test\":[\"Test\"],\"project.create.action.create\":[\"Create Project\"],\"project.create.action.creating\":[\"Creating...\"],\"project.create.description\":[\"Select a directory to initialize as a Claude Code project. This will run <0>/init in the selected directory.\"],\"project.create.selected_directory\":[\"Selected directory:\"],\"project.create.title\":[\"Create New Project\"],\"project.error.back_to_projects\":[\"Back to Projects\"],\"project.error.description\":[\"We encountered an error while loading this project\"],\"project.error.details_title\":[\"Error Details\"],\"project.error.error_id\":[\"Error ID:\"],\"project.error.title\":[\"Failed to load project\"],\"project.error.try_again\":[\"Try Again\"],\"project.new\":[\"New Project\"],\"project.not_found.back_to_projects\":[\"Back to Projects\"],\"project.not_found.description\":[\"The project you are looking for does not exist or has been removed\"],\"project.not_found.title\":[\"Project Not Found\"],\"project_list.last_modified\":[\"Last modified:\"],\"project_list.messages\":[\"Messages:\"],\"project_list.no_projects.description\":[\"No Claude Code projects found in your ~/.claude/projects directory. Start a conversation with Claude Code to create your first project.\"],\"project_list.no_projects.title\":[\"No projects found\"],\"project_list.view_conversations\":[\"View Conversations\"],\"projects.page.description\":[\"Browse your Claude Code conversation history and project interactions\"],\"projects.page.loading\":[\"Loading projects...\"],\"projects.page.title\":[\"Your Projects\"],\"session.conversation.abort\":[\"Abort\"],\"session.conversation.in.progress\":[\"Conversation is in progress...\"],\"session.conversation.paused\":[\"Conversation is paused...\"],\"session.processing\":[\"Claude Code is processing...\"],\"session.status.paused\":[\"Paused\"],\"session.status.running\":[\"Running\"],\"sessions.load.more\":[\"Load More\"],\"sessions.new\":[\"New\"],\"sessions.title\":[\"Sessions\"],\"sessions.total\":[\"total\"],\"settings.description\":[\"Display and behavior preferences\"],\"settings.input.enter_key_behavior\":[\"Enter Key Behavior\"],\"settings.input.enter_key_behavior.command_enter\":[\"Command+Enter to send\"],\"settings.input.enter_key_behavior.description\":[\"Choose how the Enter key behaves in message input\"],\"settings.input.enter_key_behavior.enter\":[\"Enter to send\"],\"settings.input.enter_key_behavior.shift_enter\":[\"Shift+Enter to send (default)\"],\"settings.loading\":[\"Loading settings...\"],\"settings.locale\":[\"Language\"],\"settings.locale.description\":[\"Choose your preferred language\"],\"settings.locale.en\":[\"English\"],\"settings.locale.ja\":[\"日本語\"],\"settings.notifications\":[\"Notifications\"],\"settings.permission.mode\":[\"Permission Mode\"],\"settings.permission.mode.accept_edits\":[\"Accept Edits (Auto-approve file edits)\"],\"settings.permission.mode.bypass_permissions\":[\"Bypass Permissions (No prompts)\"],\"settings.permission.mode.default\":[\"Default (Ask permission)\"],\"settings.permission.mode.description\":[\"Control how Claude Code handles permission requests for file operations\"],\"settings.permission.mode.plan\":[\"Plan Mode (Planning only)\"],\"settings.section.notifications\":[\"Notifications\"],\"settings.section.session_display\":[\"Session Display\"],\"settings.section.system_info\":[\"System Information\"],\"settings.session.display\":[\"Session Display\"],\"settings.session.hide_no_user_message\":[\"Hide sessions without user messages\"],\"settings.session.hide_no_user_message.description\":[\"Only show sessions that contain user commands or messages\"],\"settings.session.unify_same_title\":[\"Unify sessions with same title\"],\"settings.session.unify_same_title.description\":[\"Show only the latest session when multiple sessions have the same title\"],\"settings.tab.title\":[\"Settings for display and notifications\"],\"settings.theme\":[\"Theme\"],\"settings.theme.dark\":[\"Dark\"],\"settings.theme.description\":[\"Choose your preferred color theme\"],\"settings.theme.light\":[\"Light\"],\"settings.theme.system\":[\"System\"],\"settings.title\":[\"Settings\"],\"sidebar.back.to.projects\":[\"Back to projects\"],\"sidebar.show.mcp.settings\":[\"Show MCP server settings\"],\"sidebar.show.session.list\":[\"Show session list\"],\"system.info.tab.title\":[\"Show system information\"],\"system_info.available_features\":[\"Available Features\"],\"system_info.claude_code\":[\"Claude Code\"],\"system_info.description\":[\"Version and feature information\"],\"system_info.executable_path\":[\"Executable\"],\"system_info.feature.agent_sdk.description\":[\"Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)\"],\"system_info.feature.agent_sdk.title\":[\"Claude Agent SDK\"],\"system_info.feature.can_use_tool.description\":[\"Dynamically control tool usage permissions and request user approval before tool execution (v1.0.82+)\"],\"system_info.feature.can_use_tool.title\":[\"Tool Use Permission Control\"],\"system_info.feature.unknown.description\":[\"Feature information not available\"],\"system_info.feature.uuid_on_sdk_message.description\":[\"Adds unique identifiers to SDK messages for better tracking (v1.0.86+)\"],\"system_info.feature.uuid_on_sdk_message.title\":[\"Message UUID Support\"],\"system_info.loading\":[\"Loading system information...\"],\"system_info.title\":[\"System Information\"],\"system_info.unknown\":[\"Unknown\"],\"system_info.version_label\":[\"Version\"],\"system_info.viewer_version\":[\"Claude Code Viewer\"],\"user.content.image\":[\"Attached Image\"],\"user.content.image.description\":[\"Image attached by user\"],\"user.content.unsupported_media\":[\"Unsupported Media\"],\"user.content.unsupported_media.description\":[\"Media type not supported for display\"]}")as Messages; \ No newline at end of file +/*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"Available commands\":[\"Available commands\"],\"Available files and directories\":[\"Available files and directories\"],\"Close sidebar\":[\"Close sidebar\"],\"Compare from\":[\"Compare from\"],\"Compare to\":[\"Compare to\"],\"Failed to commit\":[\"Failed to commit\"],\"Failed to commit and push\":[\"Failed to commit and push\"],\"Failed to push\":[\"Failed to push\"],\"Message input with completion support\":[\"Message input with completion support\"],\"Reload MCP servers\":[\"Reload MCP servers\"],\"Retry Push\":[\"Retry Push\"],\"Select enter key behavior\":[\"Select enter key behavior\"],\"Select language\":[\"Select language\"],\"Select permission mode\":[\"Select permission mode\"],\"Select theme\":[\"Select theme\"],\"Type your message here... (Start with / for commands, @ for files, Command+Enter to send)\":[\"Type your message here... (Start with / for commands, @ for files, Command+Enter to send)\"],\"Type your message here... (Start with / for commands, @ for files, Enter to send)\":[\"Type your message here... (Start with / for commands, @ for files, Enter to send)\"],\"Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)\"],\"Type your message... (Start with / for commands, @ for files, Command+Enter to send)\":[\"Type your message... (Start with / for commands, @ for files, Command+Enter to send)\"],\"Type your message... (Start with / for commands, @ for files, Enter to send)\":[\"Type your message... (Start with / for commands, @ for files, Enter to send)\"],\"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)\"],\"Uncommitted changes\":[\"Uncommitted changes\"],\"assistant.thinking\":[\"Thinking\"],\"assistant.tool.input_parameters\":[\"Input Parameters\"],\"assistant.tool.message_count\":[[\"count\"],\" messages\"],\"assistant.tool.result\":[\"Tool Result\"],\"assistant.tool.task_id\":[\"Task ID\"],\"assistant.tool.tool_id\":[\"Tool ID\"],\"assistant.tool.view_task\":[\"View Task\"],\"assistant.tool.view_task_details\":[\"View Task\"],\"chat.autocomplete.active\":[\"Autocomplete active\"],\"chat.button.start\":[\"Start Chat\"],\"chat.error.send_failed\":[\"Failed to send message. Please try again.\"],\"chat.modal.title\":[\"Start New Chat\"],\"chat.resume\":[\"Resume\"],\"chat.send\":[\"Send\"],\"chat.status.processing\":[\"Processing...\"],\"common.action.cancel\":[\"Cancel\"],\"common.error\":[\"Error\"],\"common.loading\":[\"Loading...\"],\"conversation.error.raw_content\":[\"Raw Content:\"],\"conversation.error.report_issue\":[\"Report this issue\"],\"conversation.error.schema\":[\"Schema Error\"],\"conversation.error.schema_validation\":[\"Schema Validation Error\"],\"conversation.error.schema_validation.description\":[\"This conversation entry failed to parse correctly. This might indicate a format change or parsing issue.\"],\"cron_builder.cron_expression\":[\"Cron Expression\"],\"cron_builder.custom\":[\"Custom\"],\"cron_builder.daily\":[\"Daily\"],\"cron_builder.day_of_week\":[\"Day of Week\"],\"cron_builder.expression\":[\"Expression\"],\"cron_builder.friday\":[\"Friday\"],\"cron_builder.hour\":[\"Hour (0-23)\"],\"cron_builder.hourly\":[\"Hourly\"],\"cron_builder.minute\":[\"Minute (0-59)\"],\"cron_builder.monday\":[\"Monday\"],\"cron_builder.preview\":[\"Preview\"],\"cron_builder.saturday\":[\"Saturday\"],\"cron_builder.schedule_type\":[\"Schedule Type\"],\"cron_builder.sunday\":[\"Sunday\"],\"cron_builder.thursday\":[\"Thursday\"],\"cron_builder.tuesday\":[\"Tuesday\"],\"cron_builder.wednesday\":[\"Wednesday\"],\"cron_builder.weekly\":[\"Weekly\"],\"diff.commit\":[\"Commit\"],\"diff.commit.changes\":[\"Commit Changes\"],\"diff.commit.message\":[\"Commit message\"],\"diff.commit.push\":[\"Commit & Push\"],\"diff.committing\":[\"Committing...\"],\"diff.committing.pushing\":[\"Committing & Pushing...\"],\"diff.deselect.all\":[\"Deselect All\"],\"diff.enter.message\":[\"Enter a commit message\"],\"diff.files\":[\"files\"],\"diff.files.changed\":[\"files changed\"],\"diff.loading\":[\"Loading diff...\"],\"diff.push\":[\"Push\"],\"diff.pushing\":[\"Pushing...\"],\"diff.select.all\":[\"Select All\"],\"diff.select.file\":[\"Select at least one file\"],\"directory_picker.current\":[\"Current:\"],\"directory_picker.loading\":[\"Loading...\"],\"directory_picker.no_directories\":[\"No directories found\"],\"directory_picker.select\":[\"Select This Directory\"],\"mcp.error.load_failed\":[\"Failed to load MCP servers: \",[\"error\"]],\"mcp.no.servers\":[\"No MCP servers found\"],\"mcp.title\":[\"MCP Servers\"],\"notfound.button.go_home\":[\"Go to Home\"],\"notfound.default.description\":[\"The page you are looking for does not exist or has been moved.\"],\"notfound.default.title\":[\"Page Not Found\"],\"notfound.project.description\":[\"The project you are looking for does not exist.\"],\"notfound.project.title\":[\"Project Not Found\"],\"notfound.session.description\":[\"The session you are looking for does not exist.\"],\"notfound.session.title\":[\"Session Not Found\"],\"notification.beep\":[\"Beep\"],\"notification.chime\":[\"Chime\"],\"notification.description\":[\"Select a sound to play when a task completes\"],\"notification.none\":[\"None\"],\"notification.ping\":[\"Ping\"],\"notification.pop\":[\"Pop\"],\"notification.test\":[\"Test\"],\"project.create.action.create\":[\"Create Project\"],\"project.create.action.creating\":[\"Creating...\"],\"project.create.description\":[\"Select a directory to initialize as a Claude Code project. This will run <0>/init in the selected directory.\"],\"project.create.selected_directory\":[\"Selected directory:\"],\"project.create.title\":[\"Create New Project\"],\"project.error.back_to_projects\":[\"Back to Projects\"],\"project.error.description\":[\"We encountered an error while loading this project\"],\"project.error.details_title\":[\"Error Details\"],\"project.error.error_id\":[\"Error ID:\"],\"project.error.title\":[\"Failed to load project\"],\"project.error.try_again\":[\"Try Again\"],\"project.new\":[\"New Project\"],\"project.not_found.back_to_projects\":[\"Back to Projects\"],\"project.not_found.description\":[\"The project you are looking for does not exist or has been removed\"],\"project.not_found.title\":[\"Project Not Found\"],\"project_list.last_modified\":[\"Last modified:\"],\"project_list.messages\":[\"Messages:\"],\"project_list.no_projects.description\":[\"No Claude Code projects found in your ~/.claude/projects directory. Start a conversation with Claude Code to create your first project.\"],\"project_list.no_projects.title\":[\"No projects found\"],\"project_list.view_conversations\":[\"View Conversations\"],\"projects.page.description\":[\"Browse your Claude Code conversation history and project interactions\"],\"projects.page.loading\":[\"Loading projects...\"],\"projects.page.title\":[\"Your Projects\"],\"session.conversation.abort\":[\"Abort\"],\"session.conversation.in.progress\":[\"Conversation is in progress...\"],\"session.conversation.paused\":[\"Conversation is paused...\"],\"session.processing\":[\"Claude Code is processing...\"],\"session.status.paused\":[\"Paused\"],\"session.status.running\":[\"Running\"],\"sessions.load.more\":[\"Load More\"],\"sessions.new\":[\"New\"],\"sessions.title\":[\"Sessions\"],\"sessions.total\":[\"total\"],\"settings.description\":[\"Display and behavior preferences\"],\"settings.input.enter_key_behavior\":[\"Enter Key Behavior\"],\"settings.input.enter_key_behavior.command_enter\":[\"Command+Enter to send\"],\"settings.input.enter_key_behavior.description\":[\"Choose how the Enter key behaves in message input\"],\"settings.input.enter_key_behavior.enter\":[\"Enter to send\"],\"settings.input.enter_key_behavior.shift_enter\":[\"Shift+Enter to send (default)\"],\"settings.loading\":[\"Loading settings...\"],\"settings.locale\":[\"Language\"],\"settings.locale.description\":[\"Choose your preferred language\"],\"settings.locale.en\":[\"English\"],\"settings.locale.ja\":[\"日本語\"],\"settings.notifications\":[\"Notifications\"],\"settings.permission.mode\":[\"Permission Mode\"],\"settings.permission.mode.accept_edits\":[\"Accept Edits (Auto-approve file edits)\"],\"settings.permission.mode.bypass_permissions\":[\"Bypass Permissions (No prompts)\"],\"settings.permission.mode.default\":[\"Default (Ask permission)\"],\"settings.permission.mode.description\":[\"Control how Claude Code handles permission requests for file operations\"],\"settings.permission.mode.plan\":[\"Plan Mode (Planning only)\"],\"settings.permission.mode.unavailable\":[\"This feature is not available in your Claude Code version. All tools will be automatically approved.\"],\"settings.section.notifications\":[\"Notifications\"],\"settings.section.session_display\":[\"Session Display\"],\"settings.section.system_info\":[\"System Information\"],\"settings.session.display\":[\"Session Display\"],\"settings.session.hide_no_user_message\":[\"Hide sessions without user messages\"],\"settings.session.hide_no_user_message.description\":[\"Only show sessions that contain user commands or messages\"],\"settings.session.unify_same_title\":[\"Unify sessions with same title\"],\"settings.session.unify_same_title.description\":[\"Show only the latest session when multiple sessions have the same title\"],\"settings.tab.title\":[\"Settings for display and notifications\"],\"settings.theme\":[\"Theme\"],\"settings.theme.dark\":[\"Dark\"],\"settings.theme.description\":[\"Choose your preferred color theme\"],\"settings.theme.light\":[\"Light\"],\"settings.theme.system\":[\"System\"],\"settings.title\":[\"Settings\"],\"sidebar.back.to.projects\":[\"Back to projects\"],\"sidebar.show.mcp.settings\":[\"Show MCP server settings\"],\"sidebar.show.session.list\":[\"Show session list\"],\"system.info.tab.title\":[\"Show system information\"],\"system_info.available_features\":[\"Available Features\"],\"system_info.claude_code\":[\"Claude Code\"],\"system_info.description\":[\"Version and feature information\"],\"system_info.executable_path\":[\"Executable\"],\"system_info.feature.agent_sdk.description\":[\"Uses @anthropic-ai/claude-agent-sdk instead of @anthropic-ai/claude-code for enhanced capabilities\"],\"system_info.feature.agent_sdk.title\":[\"Enhanced Agent Mode\"],\"system_info.feature.tool_approval.description\":[\"Allows you to approve or reject tool executions before Claude runs them, giving you full control over actions\"],\"system_info.feature.tool_approval.title\":[\"Tool Execution Approval\"],\"system_info.feature.unknown.description\":[\"Feature information not available\"],\"system_info.feature.uuid_on_sdk_message.description\":[\"Adds unique identifiers to SDK messages for better tracking (v1.0.86+)\"],\"system_info.feature.uuid_on_sdk_message.title\":[\"Message UUID Support\"],\"system_info.loading\":[\"Loading system information...\"],\"system_info.title\":[\"System Information\"],\"system_info.unknown\":[\"Unknown\"],\"system_info.version_label\":[\"Version\"],\"system_info.viewer_version\":[\"Claude Code Viewer\"],\"user.content.document.pdf\":[\"PDF Document\"],\"user.content.document.text\":[\"Text Document\"],\"user.content.image\":[\"Attached Image\"],\"user.content.image.description\":[\"Image attached by user\"],\"user.content.unsupported_document\":[\"Unsupported Document\"],\"user.content.unsupported_document.description\":[\"Document type not supported for display\"],\"user.content.unsupported_media\":[\"Unsupported Media\"],\"user.content.unsupported_media.description\":[\"Media type not supported for display\"]}")as Messages; \ No newline at end of file diff --git a/src/lib/i18n/locales/ja/messages.json b/src/lib/i18n/locales/ja/messages.json index 7b669f2..de30ee8 100644 --- a/src/lib/i18n/locales/ja/messages.json +++ b/src/lib/i18n/locales/ja/messages.json @@ -368,11 +368,11 @@ "translation": "お好みの言語を選択" }, "system_info.feature.agent_sdk.title": { - "message": "Claude Agent SDK", + "message": "Enhanced Agent Mode", "placeholders": {}, "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 65]], - "translation": "Claude Agent SDK" + "origin": [["src/components/SystemInfoCard.tsx", 49]], + "translation": "拡張エージェントモード" }, "system_info.claude_code": { "message": "Claude Code", @@ -486,6 +486,13 @@ "origin": [["src/components/SettingsControls.tsx", 255]], "translation": "ファイル操作の権限リクエストの処理方法を制御" }, + "settings.permission.mode.unavailable": { + "message": "This feature is not available in your Claude Code version. All tools will be automatically approved.", + "placeholders": {}, + "comments": [], + "origin": [["src/components/SettingsControls.tsx", 272]], + "translation": "お使いのClaude Codeバージョンではこの機能は利用できません。すべてのツールは自動で承認されます。" + }, "session.conversation.in.progress": { "message": "Conversation is in progress...", "placeholders": {}, @@ -599,13 +606,6 @@ "origin": [["src/components/GlobalSidebar.tsx", 56]], "translation": "表示と動作の設定" }, - "system_info.feature.can_use_tool.description": { - "message": "Dynamically control tool usage permissions and request user approval before tool execution (v1.0.82+)", - "placeholders": {}, - "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 41]], - "translation": "動的にツールの使用許可を制御し、ツール実行前にユーザーの承認を求めることができます (v1.0.82+)" - }, "settings.locale.en": { "message": "English", "placeholders": {}, @@ -1506,13 +1506,6 @@ ], "translation": "ツール実行結果" }, - "system_info.feature.can_use_tool.title": { - "message": "Tool Use Permission Control", - "placeholders": {}, - "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 35]], - "translation": "ツール使用権限制御" - }, "sessions.total": { "message": "total", "placeholders": {}, @@ -1629,11 +1622,25 @@ "translation": "文書タイプは表示がサポートされていません" }, "system_info.feature.agent_sdk.description": { - "message": "Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)", + "message": "Uses @anthropic-ai/claude-agent-sdk instead of @anthropic-ai/claude-code for enhanced capabilities", "placeholders": {}, "comments": [], - "origin": [["src/components/SystemInfoCard.tsx", 71]], - "translation": "Claude Code SDKではなくClaude Agent SDKを使用 (v1.0.125+)" + "origin": [["src/components/SystemInfoCard.tsx", 53]], + "translation": "@anthropic-ai/claude-code ではなく @anthropic-ai/claude-agent-sdk を利用します" + }, + "system_info.feature.tool_approval.title": { + "message": "Tool Execution Approval", + "placeholders": {}, + "comments": [], + "origin": [["src/components/SystemInfoCard.tsx", 35]], + "translation": "ツール実行承認" + }, + "system_info.feature.tool_approval.description": { + "message": "Allows you to approve or reject tool executions before Claude runs them, giving you full control over actions", + "placeholders": {}, + "comments": [], + "origin": [["src/components/SystemInfoCard.tsx", 41]], + "translation": "Claude がツールを実行する前に承認または拒否でき、アクションを完全にコントロールできます" }, "system_info.version_label": { "message": "Version", diff --git a/src/lib/i18n/locales/ja/messages.ts b/src/lib/i18n/locales/ja/messages.ts index 5432f65..49630a8 100644 --- a/src/lib/i18n/locales/ja/messages.ts +++ b/src/lib/i18n/locales/ja/messages.ts @@ -1 +1 @@ -/*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"Available commands\":[\"利用可能なコマンド\"],\"Available files and directories\":[\"利用可能なファイルとディレクトリ\"],\"Close sidebar\":[\"サイドバーを閉じる\"],\"Compare from\":[\"比較元\"],\"Compare to\":[\"比較先\"],\"Failed to commit\":[\"コミットに失敗しました\"],\"Failed to commit and push\":[\"コミットとプッシュに失敗しました\"],\"Failed to push\":[\"プッシュに失敗しました\"],\"Message input with completion support\":[\"補完機能付きメッセージ入力\"],\"Reload MCP servers\":[\"MCPサーバーを再読み込み\"],\"Retry Push\":[\"プッシュを再試行\"],\"Select enter key behavior\":[\"Enterキーの動作を選択\"],\"Select language\":[\"言語を選択\"],\"Select permission mode\":[\"権限モードを選択\"],\"Select theme\":[\"テーマを選択\"],\"Type your message here... (Start with / for commands, @ for files, Command+Enter to send)\":[\"ここにメッセージを入力... (/でコマンド、@でファイル、Command+Enterで送信)\"],\"Type your message here... (Start with / for commands, @ for files, Enter to send)\":[\"ここにメッセージを入力... (/でコマンド、@でファイル、Enterで送信)\"],\"Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"ここにメッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信)\"],\"Type your message... (Start with / for commands, @ for files, Command+Enter to send)\":[\"メッセージを入力... (/でコマンド、@でファイル、Command+Enterで送信)\"],\"Type your message... (Start with / for commands, @ for files, Enter to send)\":[\"メッセージを入力... (/でコマンド、@でファイル、Enterで送信)\"],\"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"メッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信)\"],\"Uncommitted changes\":[\"未コミットの変更\"],\"assistant.thinking\":[\"思考中\"],\"assistant.tool.input_parameters\":[\"入力パラメータ\"],\"assistant.tool.message_count\":[[\"count\"],\"件のメッセージ\"],\"assistant.tool.result\":[\"ツール実行結果\"],\"assistant.tool.task_id\":[\"タスクID\"],\"assistant.tool.tool_id\":[\"ツールID\"],\"assistant.tool.view_task\":[\"タスクを表示\"],\"assistant.tool.view_task_details\":[\"タスクを確認\"],\"chat.autocomplete.active\":[\"オートコンプリート有効\"],\"chat.button.start\":[\"チャット開始\"],\"chat.error.send_failed\":[\"メッセージの送信に失敗しました。もう一度お試しください。\"],\"chat.modal.title\":[\"新しいチャットを開始\"],\"chat.resume\":[\"再開\"],\"chat.send\":[\"送信\"],\"chat.status.processing\":[\"処理中...\"],\"common.action.cancel\":[\"キャンセル\"],\"common.error\":[\"エラー\"],\"common.loading\":[\"読み込み中...\"],\"conversation.error.raw_content\":[\"生データ:\"],\"conversation.error.report_issue\":[\"この問題を報告\"],\"conversation.error.schema\":[\"スキーマエラー\"],\"conversation.error.schema_validation\":[\"スキーマ検証エラー\"],\"conversation.error.schema_validation.description\":[\"この会話エントリの解析に失敗しました。フォーマットの変更または解析の問題が考えられます。\"],\"cron_builder.cron_expression\":[\"Cron式\"],\"cron_builder.custom\":[\"カスタム\"],\"cron_builder.daily\":[\"毎日\"],\"cron_builder.day_of_week\":[\"曜日\"],\"cron_builder.expression\":[\"Cron式\"],\"cron_builder.friday\":[\"金曜日\"],\"cron_builder.hour\":[\"時 (0-23)\"],\"cron_builder.hourly\":[\"毎時\"],\"cron_builder.minute\":[\"分 (0-59)\"],\"cron_builder.monday\":[\"月曜日\"],\"cron_builder.preview\":[\"プレビュー\"],\"cron_builder.saturday\":[\"土曜日\"],\"cron_builder.schedule_type\":[\"スケジュールタイプ\"],\"cron_builder.sunday\":[\"日曜日\"],\"cron_builder.thursday\":[\"木曜日\"],\"cron_builder.tuesday\":[\"火曜日\"],\"cron_builder.wednesday\":[\"水曜日\"],\"cron_builder.weekly\":[\"毎週\"],\"diff.commit\":[\"コミット\"],\"diff.commit.changes\":[\"変更をコミット\"],\"diff.commit.message\":[\"コミットメッセージ\"],\"diff.commit.push\":[\"コミット&プッシュ\"],\"diff.committing\":[\"コミット中...\"],\"diff.committing.pushing\":[\"コミット&プッシュ中...\"],\"diff.deselect.all\":[\"すべて選択解除\"],\"diff.enter.message\":[\"コミットメッセージを入力\"],\"diff.files\":[\"ファイル\"],\"diff.files.changed\":[\"ファイルが変更されました\"],\"diff.loading\":[\"差分を読み込み中...\"],\"diff.push\":[\"プッシュ\"],\"diff.pushing\":[\"プッシュ中...\"],\"diff.select.all\":[\"すべて選択\"],\"diff.select.file\":[\"少なくとも1つのファイルを選択してください\"],\"directory_picker.current\":[\"現在:\"],\"directory_picker.loading\":[\"読み込み中...\"],\"directory_picker.no_directories\":[\"ディレクトリが見つかりません\"],\"directory_picker.select\":[\"このディレクトリを選択\"],\"mcp.error.load_failed\":[\"MCPサーバーの読み込みに失敗しました: \",[\"error\"]],\"mcp.no.servers\":[\"MCPサーバーが見つかりません\"],\"mcp.title\":[\"MCPサーバー\"],\"notfound.button.go_home\":[\"ホームに戻る\"],\"notfound.default.description\":[\"お探しのページは存在しないか、移動されました。\"],\"notfound.default.title\":[\"ページが見つかりません\"],\"notfound.project.description\":[\"お探しのプロジェクトは存在しません。\"],\"notfound.project.title\":[\"プロジェクトが見つかりません\"],\"notfound.session.description\":[\"お探しのセッションは存在しません。\"],\"notfound.session.title\":[\"セッションが見つかりません\"],\"notification.beep\":[\"ビープ音\"],\"notification.chime\":[\"チャイム\"],\"notification.description\":[\"Claude Code のタスクが完了した時に再生する音を選択してください\"],\"notification.none\":[\"なし\"],\"notification.ping\":[\"ピン\"],\"notification.pop\":[\"ポップ\"],\"notification.test\":[\"テスト\"],\"project.create.action.create\":[\"プロジェクトを作成\"],\"project.create.action.creating\":[\"作成中...\"],\"project.create.description\":[\"Claude Codeプロジェクトとして初期化するディレクトリを選択してください。選択したディレクトリで<0>/initが実行されます。\"],\"project.create.selected_directory\":[\"選択したディレクトリ:\"],\"project.create.title\":[\"新規プロジェクトを作成\"],\"project.error.back_to_projects\":[\"プロジェクト一覧に戻る\"],\"project.error.description\":[\"このプロジェクトの読み込み中にエラーが発生しました\"],\"project.error.details_title\":[\"エラー詳細\"],\"project.error.error_id\":[\"エラーID:\"],\"project.error.title\":[\"プロジェクトの読み込みに失敗しました\"],\"project.error.try_again\":[\"再試行\"],\"project.new\":[\"新規プロジェクト\"],\"project.not_found.back_to_projects\":[\"プロジェクト一覧に戻る\"],\"project.not_found.description\":[\"お探しのプロジェクトは存在しないか、削除されています\"],\"project.not_found.title\":[\"プロジェクトが見つかりません\"],\"project_list.last_modified\":[\"最終更新:\"],\"project_list.messages\":[\"メッセージ:\"],\"project_list.no_projects.description\":[\"~/.claude/projectsディレクトリにClaude Codeプロジェクトが見つかりません。Claude Codeとの会話を開始して、最初のプロジェクトを作成してください。\"],\"project_list.no_projects.title\":[\"プロジェクトが見つかりません\"],\"project_list.view_conversations\":[\"会話を表示\"],\"projects.page.description\":[\"Claude Codeの会話履歴とプロジェクトの操作を閲覧\"],\"projects.page.loading\":[\"プロジェクトを読み込み中...\"],\"projects.page.title\":[\"プロジェクト\"],\"session.conversation.abort\":[\"中止\"],\"session.conversation.in.progress\":[\"会話を進行中...\"],\"session.conversation.paused\":[\"会話を一時停止中...\"],\"session.processing\":[\"Claude Codeが処理中...\"],\"session.status.paused\":[\"一時停止\"],\"session.status.running\":[\"実行中\"],\"sessions.load.more\":[\"さらに読み込む\"],\"sessions.new\":[\"新規\"],\"sessions.title\":[\"セッション\"],\"sessions.total\":[\"合計\"],\"settings.description\":[\"表示と動作の設定\"],\"settings.input.enter_key_behavior\":[\"Enterキーの動作\"],\"settings.input.enter_key_behavior.command_enter\":[\"Command+Enterで送信\"],\"settings.input.enter_key_behavior.description\":[\"メッセージ入力でのEnterキーの動作を選択\"],\"settings.input.enter_key_behavior.enter\":[\"Enterで送信\"],\"settings.input.enter_key_behavior.shift_enter\":[\"Shift+Enterで送信(デフォルト)\"],\"settings.loading\":[\"設定を読み込み中...\"],\"settings.locale\":[\"言語\"],\"settings.locale.description\":[\"お好みの言語を選択\"],\"settings.locale.en\":[\"English\"],\"settings.locale.ja\":[\"日本語\"],\"settings.notifications\":[\"通知\"],\"settings.permission.mode\":[\"権限モード\"],\"settings.permission.mode.accept_edits\":[\"編集を承認(ファイル編集を自動承認)\"],\"settings.permission.mode.bypass_permissions\":[\"権限をバイパス(プロンプトなし)\"],\"settings.permission.mode.default\":[\"デフォルト(権限を確認)\"],\"settings.permission.mode.description\":[\"ファイル操作の権限リクエストの処理方法を制御\"],\"settings.permission.mode.plan\":[\"プランモード(計画のみ)\"],\"settings.section.notifications\":[\"通知\"],\"settings.section.session_display\":[\"セッション表示\"],\"settings.section.system_info\":[\"システム情報\"],\"settings.session.display\":[\"セッション表示\"],\"settings.session.hide_no_user_message\":[\"ユーザーメッセージのないセッションを非表示\"],\"settings.session.hide_no_user_message.description\":[\"ユーザーコマンドまたはメッセージを含むセッションのみを表示\"],\"settings.session.unify_same_title\":[\"同じタイトルのセッションを統合\"],\"settings.session.unify_same_title.description\":[\"同じタイトルの複数のセッションがある場合、最新のセッションのみを表示\"],\"settings.tab.title\":[\"表示と通知の設定\"],\"settings.theme\":[\"テーマ\"],\"settings.theme.dark\":[\"ダーク\"],\"settings.theme.description\":[\"お好みのカラーテーマを選択\"],\"settings.theme.light\":[\"ライト\"],\"settings.theme.system\":[\"システム\"],\"settings.title\":[\"設定\"],\"sidebar.back.to.projects\":[\"プロジェクト一覧に戻る\"],\"sidebar.show.mcp.settings\":[\"MCPサーバー設定を表示\"],\"sidebar.show.session.list\":[\"セッション一覧を表示\"],\"system.info.tab.title\":[\"システム情報を表示\"],\"system_info.available_features\":[\"利用可能機能\"],\"system_info.claude_code\":[\"Claude Code\"],\"system_info.description\":[\"バージョンと機能情報\"],\"system_info.executable_path\":[\"実行ファイル\"],\"system_info.feature.agent_sdk.description\":[\"Claude Code SDKではなくClaude Agent SDKを使用 (v1.0.125+)\"],\"system_info.feature.agent_sdk.title\":[\"Claude Agent SDK\"],\"system_info.feature.can_use_tool.description\":[\"動的にツールの使用許可を制御し、ツール実行前にユーザーの承認を求めることができます (v1.0.82+)\"],\"system_info.feature.can_use_tool.title\":[\"ツール使用権限制御\"],\"system_info.feature.unknown.description\":[\"機能情報は利用できません\"],\"system_info.feature.uuid_on_sdk_message.description\":[\"SDKメッセージに一意の識別子を追加して追跡を改善します (v1.0.86+)\"],\"system_info.feature.uuid_on_sdk_message.title\":[\"メッセージUUIDサポート\"],\"system_info.loading\":[\"システム情報を読み込んでいます...\"],\"system_info.title\":[\"システム情報\"],\"system_info.unknown\":[\"不明\"],\"system_info.version_label\":[\"バージョン\"],\"system_info.viewer_version\":[\"Claude Code Viewer\"],\"user.content.image\":[\"添付画像\"],\"user.content.image.description\":[\"ユーザーが添付した画像\"],\"user.content.unsupported_media\":[\"サポートされていないメディア\"],\"user.content.unsupported_media.description\":[\"表示がサポートされていないメディア形式です\"]}")as Messages; \ No newline at end of file +/*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"Available commands\":[\"利用可能なコマンド\"],\"Available files and directories\":[\"利用可能なファイルとディレクトリ\"],\"Close sidebar\":[\"サイドバーを閉じる\"],\"Compare from\":[\"比較元\"],\"Compare to\":[\"比較先\"],\"Failed to commit\":[\"コミットに失敗しました\"],\"Failed to commit and push\":[\"コミットとプッシュに失敗しました\"],\"Failed to push\":[\"プッシュに失敗しました\"],\"Message input with completion support\":[\"補完機能付きメッセージ入力\"],\"Reload MCP servers\":[\"MCPサーバーを再読み込み\"],\"Retry Push\":[\"プッシュを再試行\"],\"Select enter key behavior\":[\"Enterキーの動作を選択\"],\"Select language\":[\"言語を選択\"],\"Select permission mode\":[\"権限モードを選択\"],\"Select theme\":[\"テーマを選択\"],\"Type your message here... (Start with / for commands, @ for files, Command+Enter to send)\":[\"ここにメッセージを入力... (/でコマンド、@でファイル、Command+Enterで送信)\"],\"Type your message here... (Start with / for commands, @ for files, Enter to send)\":[\"ここにメッセージを入力... (/でコマンド、@でファイル、Enterで送信)\"],\"Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"ここにメッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信)\"],\"Type your message... (Start with / for commands, @ for files, Command+Enter to send)\":[\"メッセージを入力... (/でコマンド、@でファイル、Command+Enterで送信)\"],\"Type your message... (Start with / for commands, @ for files, Enter to send)\":[\"メッセージを入力... (/でコマンド、@でファイル、Enterで送信)\"],\"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)\":[\"メッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信)\"],\"Uncommitted changes\":[\"未コミットの変更\"],\"assistant.thinking\":[\"思考中\"],\"assistant.tool.input_parameters\":[\"入力パラメータ\"],\"assistant.tool.message_count\":[[\"count\"],\"件のメッセージ\"],\"assistant.tool.result\":[\"ツール実行結果\"],\"assistant.tool.task_id\":[\"タスクID\"],\"assistant.tool.tool_id\":[\"ツールID\"],\"assistant.tool.view_task\":[\"タスクを表示\"],\"assistant.tool.view_task_details\":[\"タスクを確認\"],\"chat.autocomplete.active\":[\"オートコンプリート有効\"],\"chat.button.start\":[\"チャット開始\"],\"chat.error.send_failed\":[\"メッセージの送信に失敗しました。もう一度お試しください。\"],\"chat.modal.title\":[\"新しいチャットを開始\"],\"chat.resume\":[\"再開\"],\"chat.send\":[\"送信\"],\"chat.status.processing\":[\"処理中...\"],\"common.action.cancel\":[\"キャンセル\"],\"common.error\":[\"エラー\"],\"common.loading\":[\"読み込み中...\"],\"conversation.error.raw_content\":[\"生データ:\"],\"conversation.error.report_issue\":[\"この問題を報告\"],\"conversation.error.schema\":[\"スキーマエラー\"],\"conversation.error.schema_validation\":[\"スキーマ検証エラー\"],\"conversation.error.schema_validation.description\":[\"この会話エントリの解析に失敗しました。フォーマットの変更または解析の問題が考えられます。\"],\"cron_builder.cron_expression\":[\"Cron式\"],\"cron_builder.custom\":[\"カスタム\"],\"cron_builder.daily\":[\"毎日\"],\"cron_builder.day_of_week\":[\"曜日\"],\"cron_builder.expression\":[\"Cron式\"],\"cron_builder.friday\":[\"金曜日\"],\"cron_builder.hour\":[\"時 (0-23)\"],\"cron_builder.hourly\":[\"毎時\"],\"cron_builder.minute\":[\"分 (0-59)\"],\"cron_builder.monday\":[\"月曜日\"],\"cron_builder.preview\":[\"プレビュー\"],\"cron_builder.saturday\":[\"土曜日\"],\"cron_builder.schedule_type\":[\"スケジュールタイプ\"],\"cron_builder.sunday\":[\"日曜日\"],\"cron_builder.thursday\":[\"木曜日\"],\"cron_builder.tuesday\":[\"火曜日\"],\"cron_builder.wednesday\":[\"水曜日\"],\"cron_builder.weekly\":[\"毎週\"],\"diff.commit\":[\"コミット\"],\"diff.commit.changes\":[\"変更をコミット\"],\"diff.commit.message\":[\"コミットメッセージ\"],\"diff.commit.push\":[\"コミット&プッシュ\"],\"diff.committing\":[\"コミット中...\"],\"diff.committing.pushing\":[\"コミット&プッシュ中...\"],\"diff.deselect.all\":[\"すべて選択解除\"],\"diff.enter.message\":[\"コミットメッセージを入力\"],\"diff.files\":[\"ファイル\"],\"diff.files.changed\":[\"ファイルが変更されました\"],\"diff.loading\":[\"差分を読み込み中...\"],\"diff.push\":[\"プッシュ\"],\"diff.pushing\":[\"プッシュ中...\"],\"diff.select.all\":[\"すべて選択\"],\"diff.select.file\":[\"少なくとも1つのファイルを選択してください\"],\"directory_picker.current\":[\"現在:\"],\"directory_picker.loading\":[\"読み込み中...\"],\"directory_picker.no_directories\":[\"ディレクトリが見つかりません\"],\"directory_picker.select\":[\"このディレクトリを選択\"],\"mcp.error.load_failed\":[\"MCPサーバーの読み込みに失敗しました: \",[\"error\"]],\"mcp.no.servers\":[\"MCPサーバーが見つかりません\"],\"mcp.title\":[\"MCPサーバー\"],\"notfound.button.go_home\":[\"ホームに戻る\"],\"notfound.default.description\":[\"お探しのページは存在しないか、移動されました。\"],\"notfound.default.title\":[\"ページが見つかりません\"],\"notfound.project.description\":[\"お探しのプロジェクトは存在しません。\"],\"notfound.project.title\":[\"プロジェクトが見つかりません\"],\"notfound.session.description\":[\"お探しのセッションは存在しません。\"],\"notfound.session.title\":[\"セッションが見つかりません\"],\"notification.beep\":[\"ビープ音\"],\"notification.chime\":[\"チャイム\"],\"notification.description\":[\"Claude Code のタスクが完了した時に再生する音を選択してください\"],\"notification.none\":[\"なし\"],\"notification.ping\":[\"ピン\"],\"notification.pop\":[\"ポップ\"],\"notification.test\":[\"テスト\"],\"project.create.action.create\":[\"プロジェクトを作成\"],\"project.create.action.creating\":[\"作成中...\"],\"project.create.description\":[\"Claude Codeプロジェクトとして初期化するディレクトリを選択してください。選択したディレクトリで<0>/initが実行されます。\"],\"project.create.selected_directory\":[\"選択したディレクトリ:\"],\"project.create.title\":[\"新規プロジェクトを作成\"],\"project.error.back_to_projects\":[\"プロジェクト一覧に戻る\"],\"project.error.description\":[\"このプロジェクトの読み込み中にエラーが発生しました\"],\"project.error.details_title\":[\"エラー詳細\"],\"project.error.error_id\":[\"エラーID:\"],\"project.error.title\":[\"プロジェクトの読み込みに失敗しました\"],\"project.error.try_again\":[\"再試行\"],\"project.new\":[\"新規プロジェクト\"],\"project.not_found.back_to_projects\":[\"プロジェクト一覧に戻る\"],\"project.not_found.description\":[\"お探しのプロジェクトは存在しないか、削除されています\"],\"project.not_found.title\":[\"プロジェクトが見つかりません\"],\"project_list.last_modified\":[\"最終更新:\"],\"project_list.messages\":[\"メッセージ:\"],\"project_list.no_projects.description\":[\"~/.claude/projectsディレクトリにClaude Codeプロジェクトが見つかりません。Claude Codeとの会話を開始して、最初のプロジェクトを作成してください。\"],\"project_list.no_projects.title\":[\"プロジェクトが見つかりません\"],\"project_list.view_conversations\":[\"会話を表示\"],\"projects.page.description\":[\"Claude Codeの会話履歴とプロジェクトの操作を閲覧\"],\"projects.page.loading\":[\"プロジェクトを読み込み中...\"],\"projects.page.title\":[\"プロジェクト\"],\"session.conversation.abort\":[\"中止\"],\"session.conversation.in.progress\":[\"会話を進行中...\"],\"session.conversation.paused\":[\"会話を一時停止中...\"],\"session.processing\":[\"Claude Codeが処理中...\"],\"session.status.paused\":[\"一時停止\"],\"session.status.running\":[\"実行中\"],\"sessions.load.more\":[\"さらに読み込む\"],\"sessions.new\":[\"新規\"],\"sessions.title\":[\"セッション\"],\"sessions.total\":[\"合計\"],\"settings.description\":[\"表示と動作の設定\"],\"settings.input.enter_key_behavior\":[\"Enterキーの動作\"],\"settings.input.enter_key_behavior.command_enter\":[\"Command+Enterで送信\"],\"settings.input.enter_key_behavior.description\":[\"メッセージ入力でのEnterキーの動作を選択\"],\"settings.input.enter_key_behavior.enter\":[\"Enterで送信\"],\"settings.input.enter_key_behavior.shift_enter\":[\"Shift+Enterで送信(デフォルト)\"],\"settings.loading\":[\"設定を読み込み中...\"],\"settings.locale\":[\"言語\"],\"settings.locale.description\":[\"お好みの言語を選択\"],\"settings.locale.en\":[\"English\"],\"settings.locale.ja\":[\"日本語\"],\"settings.notifications\":[\"通知\"],\"settings.permission.mode\":[\"権限モード\"],\"settings.permission.mode.accept_edits\":[\"編集を承認(ファイル編集を自動承認)\"],\"settings.permission.mode.bypass_permissions\":[\"権限をバイパス(プロンプトなし)\"],\"settings.permission.mode.default\":[\"デフォルト(権限を確認)\"],\"settings.permission.mode.description\":[\"ファイル操作の権限リクエストの処理方法を制御\"],\"settings.permission.mode.plan\":[\"プランモード(計画のみ)\"],\"settings.permission.mode.unavailable\":[\"お使いのClaude Codeバージョンではこの機能は利用できません。すべてのツールは自動で承認されます。\"],\"settings.section.notifications\":[\"通知\"],\"settings.section.session_display\":[\"セッション表示\"],\"settings.section.system_info\":[\"システム情報\"],\"settings.session.display\":[\"セッション表示\"],\"settings.session.hide_no_user_message\":[\"ユーザーメッセージのないセッションを非表示\"],\"settings.session.hide_no_user_message.description\":[\"ユーザーコマンドまたはメッセージを含むセッションのみを表示\"],\"settings.session.unify_same_title\":[\"同じタイトルのセッションを統合\"],\"settings.session.unify_same_title.description\":[\"同じタイトルの複数のセッションがある場合、最新のセッションのみを表示\"],\"settings.tab.title\":[\"表示と通知の設定\"],\"settings.theme\":[\"テーマ\"],\"settings.theme.dark\":[\"ダーク\"],\"settings.theme.description\":[\"お好みのカラーテーマを選択\"],\"settings.theme.light\":[\"ライト\"],\"settings.theme.system\":[\"システム\"],\"settings.title\":[\"設定\"],\"sidebar.back.to.projects\":[\"プロジェクト一覧に戻る\"],\"sidebar.show.mcp.settings\":[\"MCPサーバー設定を表示\"],\"sidebar.show.session.list\":[\"セッション一覧を表示\"],\"system.info.tab.title\":[\"システム情報を表示\"],\"system_info.available_features\":[\"利用可能機能\"],\"system_info.claude_code\":[\"Claude Code\"],\"system_info.description\":[\"バージョンと機能情報\"],\"system_info.executable_path\":[\"実行ファイル\"],\"system_info.feature.agent_sdk.description\":[\"@anthropic-ai/claude-code ではなく @anthropic-ai/claude-agent-sdk を利用します\"],\"system_info.feature.agent_sdk.title\":[\"拡張エージェントモード\"],\"system_info.feature.tool_approval.description\":[\"Claude がツールを実行する前に承認または拒否でき、アクションを完全にコントロールできます\"],\"system_info.feature.tool_approval.title\":[\"ツール実行承認\"],\"system_info.feature.unknown.description\":[\"機能情報は利用できません\"],\"system_info.feature.uuid_on_sdk_message.description\":[\"SDKメッセージに一意の識別子を追加して追跡を改善します (v1.0.86+)\"],\"system_info.feature.uuid_on_sdk_message.title\":[\"メッセージUUIDサポート\"],\"system_info.loading\":[\"システム情報を読み込んでいます...\"],\"system_info.title\":[\"システム情報\"],\"system_info.unknown\":[\"不明\"],\"system_info.version_label\":[\"バージョン\"],\"system_info.viewer_version\":[\"Claude Code Viewer\"],\"user.content.document.pdf\":[\"PDF文書\"],\"user.content.document.text\":[\"テキスト文書\"],\"user.content.image\":[\"添付画像\"],\"user.content.image.description\":[\"ユーザーが添付した画像\"],\"user.content.unsupported_document\":[\"サポートされていない文書\"],\"user.content.unsupported_document.description\":[\"文書タイプは表示がサポートされていません\"],\"user.content.unsupported_media\":[\"サポートされていないメディア\"],\"user.content.unsupported_media.description\":[\"表示がサポートされていないメディア形式です\"]}")as Messages; \ No newline at end of file diff --git a/src/server/core/feature-flag/models/flag.ts b/src/server/core/feature-flag/models/flag.ts new file mode 100644 index 0000000..483e117 --- /dev/null +++ b/src/server/core/feature-flag/models/flag.ts @@ -0,0 +1,11 @@ +export type Flag = + | { + name: "tool-approval"; + enabled: boolean; + } + | { + name: "agent-sdk"; + enabled: boolean; + }; + +export type FlagName = Flag["name"]; diff --git a/src/server/core/feature-flag/presentation/FeatureFlagController.ts b/src/server/core/feature-flag/presentation/FeatureFlagController.ts new file mode 100644 index 0000000..d1649fa --- /dev/null +++ b/src/server/core/feature-flag/presentation/FeatureFlagController.ts @@ -0,0 +1,43 @@ +import { Context, Effect, Layer } from "effect"; +import type { ControllerResponse } from "../../../lib/effect/toEffectResponse"; +import type { InferEffect } from "../../../lib/effect/types"; +import { ClaudeCodeService } from "../../claude-code/services/ClaudeCodeService"; +import type { Flag } from "../models/flag"; + +const LayerImpl = Effect.gen(function* () { + const claudeCodeService = yield* ClaudeCodeService; + + const getFlags = () => + Effect.gen(function* () { + const claudeCodeFeatures = + yield* claudeCodeService.getAvailableFeatures(); + + return { + response: { + flags: [ + { + name: "tool-approval", + enabled: claudeCodeFeatures.canUseTool, + }, + { + name: "agent-sdk", + enabled: claudeCodeFeatures.agentSdk, + }, + ] satisfies Flag[], + }, + status: 200, + } as const satisfies ControllerResponse; + }); + + return { + getFlags, + }; +}); + +export type IFeatureFlagController = InferEffect; +export class FeatureFlagController extends Context.Tag("FeatureFlagController")< + FeatureFlagController, + IFeatureFlagController +>() { + static Live = Layer.effect(this, LayerImpl); +} diff --git a/src/server/hono/route.ts b/src/server/hono/route.ts index 715e6da..f29843b 100644 --- a/src/server/hono/route.ts +++ b/src/server/hono/route.ts @@ -13,6 +13,7 @@ import { userMessageInputSchema } from "../core/claude-code/schema"; import { ClaudeCodeLifeCycleService } from "../core/claude-code/services/ClaudeCodeLifeCycleService"; import { TypeSafeSSE } from "../core/events/functions/typeSafeSSE"; import { SSEController } from "../core/events/presentation/SSEController"; +import { FeatureFlagController } from "../core/feature-flag/presentation/FeatureFlagController"; import { FileSystemController } from "../core/file-system/presentation/FileSystemController"; import { GitController } from "../core/git/presentation/GitController"; import { CommitRequestSchema, PushRequestSchema } from "../core/git/schema"; @@ -49,6 +50,7 @@ export const routes = (app: HonoAppType) => const fileSystemController = yield* FileSystemController; const claudeCodeController = yield* ClaudeCodeController; const schedulerController = yield* SchedulerController; + const featureFlagController = yield* FeatureFlagController; // services const envService = yield* EnvService; @@ -553,6 +555,18 @@ export const routes = (app: HonoAppType) => return response; }, ) + + /** + * FeatureFlagController Routes + */ + .get("/api/flags", async (c) => { + const response = await effectToResponse( + c, + featureFlagController.getFlags().pipe(Effect.provide(runtime)), + ); + + return response; + }) ); }); diff --git a/src/server/main.ts b/src/server/main.ts index 423a95b..152c068 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -13,6 +13,7 @@ import { ClaudeCodeService } from "./core/claude-code/services/ClaudeCodeService import { ClaudeCodeSessionProcessService } from "./core/claude-code/services/ClaudeCodeSessionProcessService"; import { SSEController } from "./core/events/presentation/SSEController"; import { FileWatcherService } from "./core/events/services/fileWatcher"; +import { FeatureFlagController } from "./core/feature-flag/presentation/FeatureFlagController"; import { FileSystemController } from "./core/file-system/presentation/FileSystemController"; import { GitController } from "./core/git/presentation/GitController"; import { GitService } from "./core/git/services/GitService"; @@ -68,6 +69,7 @@ const program = routes(honoApp) Effect.provide(FileSystemController.Live), Effect.provide(SSEController.Live), Effect.provide(SchedulerController.Live), + Effect.provide(FeatureFlagController.Live), ) .pipe( /** Application */