mirror of
https://github.com/aljazceru/claude-code-viewer.git
synced 2025-12-26 17:54:23 +01:00
feat: system information view
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Trans } from "@lingui/react";
|
||||
import { ChevronDown, Lightbulb, Settings } from "lucide-react";
|
||||
import { ChevronDown, Lightbulb, Wrench } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { useTheme } from "next-themes";
|
||||
import type { FC } from "react";
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
oneDark,
|
||||
oneLight,
|
||||
} from "react-syntax-highlighter/dist/esm/styles/prism";
|
||||
import z from "zod";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
Card,
|
||||
@@ -25,12 +26,28 @@ import {
|
||||
} from "@/components/ui/collapsible";
|
||||
import type { ToolResultContent } from "@/lib/conversation-schema/content/ToolResultContentSchema";
|
||||
import type { AssistantMessageContent } from "@/lib/conversation-schema/message/AssistantMessageSchema";
|
||||
import { Button } from "../../../../../../../components/ui/button";
|
||||
import type { SidechainConversation } from "../../../../../../../lib/conversation-schema";
|
||||
import { MarkdownContent } from "../../../../../../components/MarkdownContent";
|
||||
import { SidechainConversationModal } from "../conversationModal/SidechainConversationModal";
|
||||
|
||||
const taskToolInputSchema = z.object({
|
||||
prompt: z.string(),
|
||||
});
|
||||
|
||||
export const AssistantConversationContent: FC<{
|
||||
content: AssistantMessageContent;
|
||||
getToolResult: (toolUseId: string) => ToolResultContent | undefined;
|
||||
}> = ({ content, getToolResult }) => {
|
||||
getSidechainConversationByPrompt: (
|
||||
prompt: string,
|
||||
) => SidechainConversation | undefined;
|
||||
getSidechainConversations: (rootUuid: string) => SidechainConversation[];
|
||||
}> = ({
|
||||
content,
|
||||
getToolResult,
|
||||
getSidechainConversationByPrompt,
|
||||
getSidechainConversations,
|
||||
}) => {
|
||||
const { resolvedTheme } = useTheme();
|
||||
const syntaxTheme = resolvedTheme === "dark" ? oneDark : oneLight;
|
||||
if (content.type === "text") {
|
||||
@@ -71,11 +88,48 @@ export const AssistantConversationContent: FC<{
|
||||
if (content.type === "tool_use") {
|
||||
const toolResult = getToolResult(content.id);
|
||||
|
||||
const taskModal = (() => {
|
||||
const taskInput =
|
||||
content.name === "Task"
|
||||
? taskToolInputSchema.safeParse(content.input)
|
||||
: undefined;
|
||||
|
||||
if (taskInput === undefined || taskInput.success === false) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const conversation = getSidechainConversationByPrompt(
|
||||
taskInput.data.prompt,
|
||||
);
|
||||
|
||||
if (conversation === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return (
|
||||
<SidechainConversationModal
|
||||
conversation={conversation}
|
||||
sidechainConversations={getSidechainConversations(
|
||||
conversation.uuid,
|
||||
).map((original) => ({
|
||||
...original,
|
||||
isSidechain: false,
|
||||
}))}
|
||||
getToolResult={getToolResult}
|
||||
trigger={
|
||||
<Button variant="outline" size="sm">
|
||||
View Log
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
);
|
||||
})();
|
||||
|
||||
return (
|
||||
<Card className="border-blue-200 bg-blue-50/50 dark:border-blue-800 dark:bg-blue-950/20 gap-2 py-3 mb-2">
|
||||
<CardHeader className="py-0 px-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Settings className="h-4 w-4 text-blue-600 dark:text-blue-400" />
|
||||
<Wrench className="h-4 w-4 text-blue-600 dark:text-blue-400" />
|
||||
<CardTitle className="text-sm font-medium">
|
||||
<Trans id="assistant.tool_use" message="Tool Use" />
|
||||
</CardTitle>
|
||||
@@ -159,6 +213,7 @@ export const AssistantConversationContent: FC<{
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
)}
|
||||
{taskModal}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import type { FC } from "react";
|
||||
import type { Conversation } from "@/lib/conversation-schema";
|
||||
import type {
|
||||
Conversation,
|
||||
SidechainConversation,
|
||||
} from "@/lib/conversation-schema";
|
||||
import type { ToolResultContent } from "@/lib/conversation-schema/content/ToolResultContentSchema";
|
||||
import { SidechainConversationModal } from "../conversationModal/SidechainConversationModal";
|
||||
import { AssistantConversationContent } from "./AssistantConversationContent";
|
||||
@@ -13,11 +16,15 @@ export const ConversationItem: FC<{
|
||||
conversation: Conversation;
|
||||
getToolResult: (toolUseId: string) => ToolResultContent | undefined;
|
||||
isRootSidechain: (conversation: Conversation) => boolean;
|
||||
getSidechainConversations: (rootUuid: string) => Conversation[];
|
||||
getSidechainConversationByPrompt: (
|
||||
prompt: string,
|
||||
) => SidechainConversation | undefined;
|
||||
getSidechainConversations: (rootUuid: string) => SidechainConversation[];
|
||||
}> = ({
|
||||
conversation,
|
||||
getToolResult,
|
||||
isRootSidechain,
|
||||
getSidechainConversationByPrompt,
|
||||
getSidechainConversations,
|
||||
}) => {
|
||||
if (conversation.type === "summary") {
|
||||
@@ -54,13 +61,10 @@ export const ConversationItem: FC<{
|
||||
conversation={conversation}
|
||||
sidechainConversations={getSidechainConversations(
|
||||
conversation.uuid,
|
||||
).map((original) => {
|
||||
if (original.type === "summary") return original;
|
||||
return {
|
||||
...original,
|
||||
isSidechain: false,
|
||||
};
|
||||
})}
|
||||
).map((original) => ({
|
||||
...original,
|
||||
isSidechain: false,
|
||||
}))}
|
||||
getToolResult={getToolResult}
|
||||
/>
|
||||
);
|
||||
@@ -99,6 +103,10 @@ export const ConversationItem: FC<{
|
||||
<AssistantConversationContent
|
||||
content={content}
|
||||
getToolResult={getToolResult}
|
||||
getSidechainConversationByPrompt={
|
||||
getSidechainConversationByPrompt
|
||||
}
|
||||
getSidechainConversations={getSidechainConversations}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -126,8 +126,11 @@ export const ConversationList: FC<ConversationListProps> = ({
|
||||
conversations.filter((conversation) => conversation.type !== "x-error"),
|
||||
[conversations],
|
||||
);
|
||||
const { isRootSidechain, getSidechainConversations } =
|
||||
useSidechain(validConversations);
|
||||
const {
|
||||
isRootSidechain,
|
||||
getSidechainConversations,
|
||||
getSidechainConversationByPrompt,
|
||||
} = useSidechain(validConversations);
|
||||
|
||||
return (
|
||||
<ul>
|
||||
@@ -148,6 +151,7 @@ export const ConversationList: FC<ConversationListProps> = ({
|
||||
getToolResult={getToolResult}
|
||||
isRootSidechain={isRootSidechain}
|
||||
getSidechainConversations={getSidechainConversations}
|
||||
getSidechainConversationByPrompt={getSidechainConversationByPrompt}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
@@ -16,11 +16,13 @@ import type {
|
||||
SidechainConversation,
|
||||
} from "@/lib/conversation-schema";
|
||||
import type { ToolResultContent } from "@/lib/conversation-schema/content/ToolResultContentSchema";
|
||||
import { extractFirstUserText } from "../../../../../../../server/core/session/functions/extractFirstUserText";
|
||||
import { ConversationList } from "../conversationList/ConversationList";
|
||||
|
||||
type SidechainConversationModalProps = {
|
||||
conversation: SidechainConversation;
|
||||
sidechainConversations: Conversation[];
|
||||
trigger?: React.ReactNode;
|
||||
getToolResult: (toolUseId: string) => ToolResultContent | undefined;
|
||||
};
|
||||
|
||||
@@ -38,29 +40,12 @@ const sidechainTitle = (conversations: Conversation[]): string => {
|
||||
return defaultTitle;
|
||||
}
|
||||
|
||||
if (firstConversation.type !== "user") {
|
||||
return defaultTitle;
|
||||
}
|
||||
|
||||
const textContent =
|
||||
typeof firstConversation.message.content === "string"
|
||||
? firstConversation.message.content
|
||||
: (() => {
|
||||
const firstContent = firstConversation.message.content.at(0);
|
||||
if (firstContent === undefined) return null;
|
||||
|
||||
if (typeof firstContent === "string") return firstContent;
|
||||
if (firstContent.type === "text") return firstContent.text;
|
||||
|
||||
return null;
|
||||
})();
|
||||
|
||||
return textContent ?? defaultTitle;
|
||||
return extractFirstUserText(firstConversation) ?? defaultTitle;
|
||||
};
|
||||
|
||||
export const SidechainConversationModal: FC<
|
||||
SidechainConversationModalProps
|
||||
> = ({ conversation, sidechainConversations, getToolResult }) => {
|
||||
> = ({ conversation, sidechainConversations, trigger, getToolResult }) => {
|
||||
const title = sidechainTitle(sidechainConversations);
|
||||
|
||||
const rootUuid = conversation.uuid;
|
||||
@@ -68,19 +53,21 @@ export const SidechainConversationModal: FC<
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full mb-3 items-center justify-start"
|
||||
data-testid="sidechain-task-button"
|
||||
>
|
||||
<div className="flex items-center gap-2 overflow-hidden">
|
||||
<Eye className="h-4 w-4 flex-shrink-0" />
|
||||
<span className="overflow-hidden text-ellipsis">
|
||||
View Task: {title}
|
||||
</span>
|
||||
</div>
|
||||
</Button>
|
||||
{trigger ?? (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full mb-3 items-center justify-start"
|
||||
data-testid="sidechain-task-button"
|
||||
>
|
||||
<div className="flex items-center gap-2 overflow-hidden">
|
||||
<Eye className="h-4 w-4 flex-shrink-0" />
|
||||
<span className="overflow-hidden text-ellipsis">
|
||||
View Task: {title}
|
||||
</span>
|
||||
</div>
|
||||
</Button>
|
||||
)}
|
||||
</DialogTrigger>
|
||||
<DialogContent
|
||||
className="w-[95vw] md:w-[90vw] max-h-[80vh] overflow-hidden flex flex-col px-2 md:px-8"
|
||||
|
||||
@@ -15,6 +15,19 @@ export const useSidechain = (conversations: Conversation[]) => {
|
||||
);
|
||||
}, [sidechainConversations]);
|
||||
|
||||
const conversationPromptMap = useMemo(() => {
|
||||
return new Map<string, SidechainConversation>(
|
||||
sidechainConversations
|
||||
.filter((conv) => conv.type === "user")
|
||||
.filter(
|
||||
(conv) =>
|
||||
conv.parentUuid === null &&
|
||||
typeof conv.message.content === "string",
|
||||
)
|
||||
.map((conv) => [conv.message.content as string, conv] as const),
|
||||
);
|
||||
}, [sidechainConversations]);
|
||||
|
||||
const getRootConversationRecursive = useCallback(
|
||||
(conversation: SidechainConversation): SidechainConversation => {
|
||||
if (conversation.parentUuid === null) {
|
||||
@@ -72,8 +85,16 @@ export const useSidechain = (conversations: Conversation[]) => {
|
||||
[sidechainConversationGroups],
|
||||
);
|
||||
|
||||
const getSidechainConversationByPrompt = useCallback(
|
||||
(prompt: string) => {
|
||||
return conversationPromptMap.get(prompt);
|
||||
},
|
||||
[conversationPromptMap],
|
||||
);
|
||||
|
||||
return {
|
||||
isRootSidechain,
|
||||
getSidechainConversations,
|
||||
getSidechainConversationByPrompt,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Trans } from "@lingui/react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
import { InfoIcon, SettingsIcon } from "lucide-react";
|
||||
import { type FC, type ReactNode, Suspense, useState } from "react";
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import { cn } from "@/lib/utils";
|
||||
import { NotificationSettings } from "./NotificationSettings";
|
||||
import { SettingsControls } from "./SettingsControls";
|
||||
import { SystemInfoCard } from "./SystemInfoCard";
|
||||
|
||||
export interface SidebarTab {
|
||||
id: string;
|
||||
@@ -94,7 +95,31 @@ export const GlobalSidebar: FC<GlobalSidebarProps> = ({
|
||||
),
|
||||
};
|
||||
|
||||
const allTabs = [...additionalTabs, settingsTab];
|
||||
const systemInfoTab: SidebarTab = {
|
||||
id: "system-info",
|
||||
icon: InfoIcon,
|
||||
title: (
|
||||
<Trans id="settings.section.system_info" message="System Information" />
|
||||
),
|
||||
content: (
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="h-full flex items-center justify-center p-4">
|
||||
<div className="text-sm text-sidebar-foreground/70">
|
||||
<Trans
|
||||
id="system_info.loading"
|
||||
message="Loading system information..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<SystemInfoCard />
|
||||
</Suspense>
|
||||
),
|
||||
};
|
||||
|
||||
const allTabs = [...additionalTabs, settingsTab, systemInfoTab];
|
||||
const [activeTab, setActiveTab] = useState<string>(
|
||||
defaultActiveTab ?? allTabs[allTabs.length - 1]?.id ?? "settings",
|
||||
);
|
||||
|
||||
229
src/components/SystemInfoCard.tsx
Normal file
229
src/components/SystemInfoCard.tsx
Normal file
@@ -0,0 +1,229 @@
|
||||
"use client";
|
||||
|
||||
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 { Badge } from "./ui/badge";
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "./ui/collapsible";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "./ui/tooltip";
|
||||
|
||||
interface FeatureInfo {
|
||||
title: ReactNode;
|
||||
description: ReactNode;
|
||||
}
|
||||
|
||||
const getFeatureInfo = (featureName: string): FeatureInfo => {
|
||||
switch (featureName) {
|
||||
case "canUseTool":
|
||||
return {
|
||||
title: (
|
||||
<Trans
|
||||
id="system_info.feature.can_use_tool.title"
|
||||
message="Tool Use Permission Control"
|
||||
/>
|
||||
),
|
||||
description: (
|
||||
<Trans
|
||||
id="system_info.feature.can_use_tool.description"
|
||||
message="Dynamically control tool usage permissions and request user approval before tool execution (v1.0.82+)"
|
||||
/>
|
||||
),
|
||||
};
|
||||
case "uuidOnSDKMessage":
|
||||
return {
|
||||
title: (
|
||||
<Trans
|
||||
id="system_info.feature.uuid_on_sdk_message.title"
|
||||
message="Message UUID Support"
|
||||
/>
|
||||
),
|
||||
description: (
|
||||
<Trans
|
||||
id="system_info.feature.uuid_on_sdk_message.description"
|
||||
message="Adds unique identifiers to SDK messages for better tracking (v1.0.86+)"
|
||||
/>
|
||||
),
|
||||
};
|
||||
case "agentSdk":
|
||||
return {
|
||||
title: (
|
||||
<Trans
|
||||
id="system_info.feature.agent_sdk.title"
|
||||
message="Claude Agent SDK"
|
||||
/>
|
||||
),
|
||||
description: (
|
||||
<Trans
|
||||
id="system_info.feature.agent_sdk.description"
|
||||
message="Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)"
|
||||
/>
|
||||
),
|
||||
};
|
||||
default:
|
||||
return {
|
||||
title: featureName,
|
||||
description: (
|
||||
<Trans
|
||||
id="system_info.feature.unknown.description"
|
||||
message="Feature information not available"
|
||||
/>
|
||||
),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const SystemInfoCard: FC = () => {
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
const { data: versionData } = useSuspenseQuery({
|
||||
...systemVersionQuery,
|
||||
});
|
||||
|
||||
const { data: claudeCodeMetaData } = useSuspenseQuery({
|
||||
...claudeCodeMetaQuery,
|
||||
});
|
||||
|
||||
const { data: claudeCodeFeaturesData } = useSuspenseQuery({
|
||||
...claudeCodeFeaturesQuery,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="border-b border-sidebar-border p-4">
|
||||
<h2 className="font-semibold text-lg">
|
||||
<Trans id="system_info.title" message="System Information" />
|
||||
</h2>
|
||||
<p className="text-xs text-sidebar-foreground/70">
|
||||
<Trans
|
||||
id="system_info.description"
|
||||
message="Version and feature information"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto p-4 space-y-6">
|
||||
{/* Claude Code Viewer Version */}
|
||||
<div className="space-y-3">
|
||||
<h3 className="font-medium text-sm text-sidebar-foreground">
|
||||
<Trans
|
||||
id="system_info.viewer_version"
|
||||
message="Claude Code Viewer"
|
||||
/>
|
||||
</h3>
|
||||
<div className="flex justify-between items-center pl-2">
|
||||
<span className="text-xs text-sidebar-foreground/70">
|
||||
<Trans id="system_info.version_label" message="Version" />
|
||||
</span>
|
||||
<Badge variant="secondary" className="text-xs font-mono">
|
||||
v{versionData?.version || "Unknown"}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Claude Code Information */}
|
||||
<div className="space-y-3">
|
||||
<h3 className="font-medium text-sm text-sidebar-foreground">
|
||||
<Trans id="system_info.claude_code" message="Claude Code" />
|
||||
</h3>
|
||||
<div className="space-y-2 pl-2">
|
||||
<div className="space-y-1">
|
||||
<div className="text-xs text-sidebar-foreground/70">
|
||||
<Trans id="system_info.executable_path" message="Executable" />
|
||||
</div>
|
||||
<div className="text-xs text-sidebar-foreground font-mono break-all">
|
||||
{claudeCodeMetaData?.executablePath || (
|
||||
<span className="text-sidebar-foreground/50">
|
||||
<Trans id="system_info.unknown" message="Unknown" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center pt-1">
|
||||
<span className="text-xs text-sidebar-foreground/70">
|
||||
<Trans id="system_info.version_label" message="Version" />
|
||||
</span>
|
||||
<Badge variant="secondary" className="text-xs font-mono">
|
||||
{claudeCodeMetaData?.version || (
|
||||
<Trans id="system_info.unknown" message="Unknown" />
|
||||
)}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Available Features */}
|
||||
<div className="space-y-3">
|
||||
<Collapsible open={isExpanded} onOpenChange={setIsExpanded}>
|
||||
<CollapsibleTrigger className="flex w-full items-center justify-between group">
|
||||
<h3 className="font-medium text-sm text-sidebar-foreground">
|
||||
<Trans
|
||||
id="system_info.available_features"
|
||||
message="Available Features"
|
||||
/>
|
||||
</h3>
|
||||
{isExpanded ? (
|
||||
<ChevronDown className="h-4 w-4 text-sidebar-foreground/70 group-hover:text-sidebar-foreground transition-colors" />
|
||||
) : (
|
||||
<ChevronRight className="h-4 w-4 text-sidebar-foreground/70 group-hover:text-sidebar-foreground transition-colors" />
|
||||
)}
|
||||
</CollapsibleTrigger>
|
||||
|
||||
<CollapsibleContent className="pt-3">
|
||||
<TooltipProvider>
|
||||
<ul className="space-y-2 pl-2">
|
||||
{claudeCodeFeaturesData?.features.map(({ name, enabled }) => {
|
||||
const featureInfo = getFeatureInfo(name);
|
||||
return (
|
||||
<li key={name} className="flex items-start gap-2">
|
||||
{enabled ? (
|
||||
<CheckCircle2 className="h-3.5 w-3.5 text-green-500 dark:text-green-400 mt-0.5 flex-shrink-0" />
|
||||
) : (
|
||||
<XCircle className="h-3.5 w-3.5 text-sidebar-foreground/30 mt-0.5 flex-shrink-0" />
|
||||
)}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span
|
||||
className={
|
||||
enabled
|
||||
? "text-xs text-sidebar-foreground cursor-help"
|
||||
: "text-xs text-sidebar-foreground/50 line-through cursor-help"
|
||||
}
|
||||
>
|
||||
{featureInfo.title}
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side="right"
|
||||
className="max-w-xs text-xs"
|
||||
>
|
||||
{featureInfo.description}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</TooltipProvider>
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -206,3 +206,46 @@ export const configQuery = {
|
||||
return await response.json();
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const systemVersionQuery = {
|
||||
queryKey: ["version"],
|
||||
queryFn: async () => {
|
||||
const response = await honoClient.api.version.$get();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch system version: ${response.statusText}`);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const claudeCodeMetaQuery = {
|
||||
queryKey: ["cc", "meta"],
|
||||
queryFn: async () => {
|
||||
const response = await honoClient.api.cc.meta.$get();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch system features: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const claudeCodeFeaturesQuery = {
|
||||
queryKey: ["cc", "features"],
|
||||
queryFn: async () => {
|
||||
const response = await honoClient.api.cc.features.$get();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch claude code features: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -23,28 +23,6 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 306]],
|
||||
"translation": "Select theme"
|
||||
},
|
||||
"Reload MCP servers": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/McpTab.tsx",
|
||||
42
|
||||
]
|
||||
],
|
||||
"translation": "Reload MCP servers"
|
||||
},
|
||||
"Close sidebar": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
173
|
||||
]
|
||||
],
|
||||
"translation": "Close sidebar"
|
||||
},
|
||||
"Type your message... (Start with / for commands, @ for files, Enter to send)": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
@@ -90,6 +68,28 @@
|
||||
],
|
||||
"translation": "Type your message... (Start with / for commands, @ for files, Shift+Enter to send)"
|
||||
},
|
||||
"Reload MCP servers": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/McpTab.tsx",
|
||||
42
|
||||
]
|
||||
],
|
||||
"translation": "Reload MCP servers"
|
||||
},
|
||||
"Close sidebar": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
173
|
||||
]
|
||||
],
|
||||
"translation": "Close sidebar"
|
||||
},
|
||||
"Type your message here... (Start with / for commands, @ for files, Enter to send)": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
@@ -114,36 +114,6 @@
|
||||
],
|
||||
"translation": "Type your message here... (Start with / for commands, @ for files, Shift+Enter to send)"
|
||||
},
|
||||
"Available commands": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/CommandCompletion.tsx",
|
||||
193
|
||||
]
|
||||
],
|
||||
"translation": "Available commands"
|
||||
},
|
||||
"Message input with completion support": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 210]
|
||||
],
|
||||
"translation": "Message input with completion support"
|
||||
},
|
||||
"Available files and directories": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/FileCompletion.tsx",
|
||||
267
|
||||
]
|
||||
],
|
||||
"translation": "Available files and directories"
|
||||
},
|
||||
"Uncommitted changes": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
@@ -221,6 +191,36 @@
|
||||
],
|
||||
"translation": "Compare to"
|
||||
},
|
||||
"Available commands": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/CommandCompletion.tsx",
|
||||
193
|
||||
]
|
||||
],
|
||||
"translation": "Available commands"
|
||||
},
|
||||
"Available files and directories": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/FileCompletion.tsx",
|
||||
267
|
||||
]
|
||||
],
|
||||
"translation": "Available files and directories"
|
||||
},
|
||||
"Message input with completion support": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 210]
|
||||
],
|
||||
"translation": "Message input with completion support"
|
||||
},
|
||||
"session.conversation.abort": {
|
||||
"message": "Abort",
|
||||
"placeholders": {},
|
||||
@@ -244,6 +244,13 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 234]],
|
||||
"translation": "Accept Edits (Auto-approve file edits)"
|
||||
},
|
||||
"system_info.feature.uuid_on_sdk_message.description": {
|
||||
"message": "Adds unique identifiers to SDK messages for better tracking (v1.0.86+)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 56]],
|
||||
"translation": "Adds unique identifiers to SDK messages for better tracking (v1.0.86+)"
|
||||
},
|
||||
"chat.autocomplete.active": {
|
||||
"message": "Autocomplete active",
|
||||
"placeholders": {},
|
||||
@@ -253,6 +260,13 @@
|
||||
],
|
||||
"translation": "Autocomplete active"
|
||||
},
|
||||
"system_info.available_features": {
|
||||
"message": "Available Features",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 175]],
|
||||
"translation": "Available Features"
|
||||
},
|
||||
"sidebar.back.to.projects": {
|
||||
"message": "Back to projects",
|
||||
"placeholders": {},
|
||||
@@ -273,7 +287,7 @@
|
||||
"message": "Back to Projects",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 42]],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 45]],
|
||||
"translation": "Back to Projects"
|
||||
},
|
||||
"project.error.back_to_projects": {
|
||||
@@ -339,6 +353,20 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 290]],
|
||||
"translation": "Choose your preferred language"
|
||||
},
|
||||
"system_info.feature.agent_sdk.title": {
|
||||
"message": "Claude Agent SDK",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 65]],
|
||||
"translation": "Claude Agent SDK"
|
||||
},
|
||||
"system_info.claude_code": {
|
||||
"message": "Claude Code",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 141]],
|
||||
"translation": "Claude Code"
|
||||
},
|
||||
"session.processing": {
|
||||
"message": "Claude Code is processing...",
|
||||
"placeholders": {},
|
||||
@@ -351,6 +379,13 @@
|
||||
],
|
||||
"translation": "Claude Code is processing..."
|
||||
},
|
||||
"system_info.viewer_version": {
|
||||
"message": "Claude Code Viewer",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 123]],
|
||||
"translation": "Claude Code Viewer"
|
||||
},
|
||||
"settings.input.enter_key_behavior.command_enter": {
|
||||
"message": "Command+Enter to send",
|
||||
"placeholders": {},
|
||||
@@ -519,9 +554,16 @@
|
||||
"message": "Display and behavior preferences",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 55]],
|
||||
"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": {},
|
||||
@@ -581,6 +623,13 @@
|
||||
"origin": [["src/app/projects/[projectId]/error.tsx", 58]],
|
||||
"translation": "Error ID:"
|
||||
},
|
||||
"system_info.executable_path": {
|
||||
"message": "Executable",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 146]],
|
||||
"translation": "Executable"
|
||||
},
|
||||
"mcp.error.load_failed": {
|
||||
"message": "Failed to load MCP servers: {error}",
|
||||
"placeholders": {
|
||||
@@ -611,6 +660,13 @@
|
||||
],
|
||||
"translation": "Failed to send message. Please try again."
|
||||
},
|
||||
"system_info.feature.unknown.description": {
|
||||
"message": "Feature information not available",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 81]],
|
||||
"translation": "Feature information not available"
|
||||
},
|
||||
"diff.files": {
|
||||
"message": "files",
|
||||
"placeholders": {},
|
||||
@@ -661,7 +717,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
98
|
||||
152
|
||||
]
|
||||
],
|
||||
"translation": "Input Parameters"
|
||||
@@ -727,10 +783,17 @@
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
115
|
||||
],
|
||||
["src/components/GlobalSidebar.tsx", 66]
|
||||
["src/components/GlobalSidebar.tsx", 67]
|
||||
],
|
||||
"translation": "Loading settings..."
|
||||
},
|
||||
"system_info.loading": {
|
||||
"message": "Loading system information...",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 109]],
|
||||
"translation": "Loading system information..."
|
||||
},
|
||||
"directory_picker.loading": {
|
||||
"message": "Loading...",
|
||||
"placeholders": {},
|
||||
@@ -782,6 +845,13 @@
|
||||
],
|
||||
"translation": "Media type not supported for display"
|
||||
},
|
||||
"system_info.feature.uuid_on_sdk_message.title": {
|
||||
"message": "Message UUID Support",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 50]],
|
||||
"translation": "Message UUID Support"
|
||||
},
|
||||
"project_list.messages": {
|
||||
"message": "Messages:",
|
||||
"placeholders": {},
|
||||
@@ -852,7 +922,7 @@
|
||||
"message": "Notifications",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 84]],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 85]],
|
||||
"translation": "Notifications"
|
||||
},
|
||||
"settings.notifications": {
|
||||
@@ -927,7 +997,7 @@
|
||||
"message": "Project Not Found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 23]],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 26]],
|
||||
"translation": "Project Not Found"
|
||||
},
|
||||
"diff.push": {
|
||||
@@ -1094,7 +1164,7 @@
|
||||
"message": "Session Display",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 74]],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 75]],
|
||||
"translation": "Session Display"
|
||||
},
|
||||
"settings.session.display": {
|
||||
@@ -1125,7 +1195,7 @@
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 52]],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 53]],
|
||||
"translation": "Settings"
|
||||
},
|
||||
"settings.tab.title": {
|
||||
@@ -1137,7 +1207,7 @@
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
278
|
||||
],
|
||||
["src/components/GlobalSidebar.tsx", 43]
|
||||
["src/components/GlobalSidebar.tsx", 44]
|
||||
],
|
||||
"translation": "Settings for display and notifications"
|
||||
},
|
||||
@@ -1204,6 +1274,20 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 316]],
|
||||
"translation": "System"
|
||||
},
|
||||
"system_info.title": {
|
||||
"message": "System Information",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 109]],
|
||||
"translation": "System Information"
|
||||
},
|
||||
"settings.section.system_info": {
|
||||
"message": "System Information",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 102]],
|
||||
"translation": "System Information"
|
||||
},
|
||||
"notification.test": {
|
||||
"message": "Test",
|
||||
"placeholders": {},
|
||||
@@ -1215,7 +1299,7 @@
|
||||
"message": "The project you are looking for does not exist or has been removed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 29]],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 32]],
|
||||
"translation": "The project you are looking for does not exist or has been removed"
|
||||
},
|
||||
"settings.theme": {
|
||||
@@ -1232,7 +1316,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
53
|
||||
70
|
||||
]
|
||||
],
|
||||
"translation": "Thinking"
|
||||
@@ -1256,7 +1340,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
122
|
||||
176
|
||||
]
|
||||
],
|
||||
"translation": "Tool Result"
|
||||
@@ -1268,11 +1352,18 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
80
|
||||
134
|
||||
]
|
||||
],
|
||||
"translation": "Tool Use"
|
||||
},
|
||||
"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": {},
|
||||
@@ -1299,6 +1390,16 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 144]],
|
||||
"translation": "Unify sessions with same title"
|
||||
},
|
||||
"system_info.unknown": {
|
||||
"message": "Unknown",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SystemInfoCard.tsx", 151],
|
||||
["src/components/SystemInfoCard.tsx", 163]
|
||||
],
|
||||
"translation": "Unknown"
|
||||
},
|
||||
"user.content.unsupported_media": {
|
||||
"message": "Unsupported Media",
|
||||
"placeholders": {},
|
||||
@@ -1323,6 +1424,30 @@
|
||||
],
|
||||
"translation": "User uploaded image content"
|
||||
},
|
||||
"system_info.feature.agent_sdk.description": {
|
||||
"message": "Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 71]],
|
||||
"translation": "Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)"
|
||||
},
|
||||
"system_info.version_label": {
|
||||
"message": "Version",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SystemInfoCard.tsx", 130],
|
||||
["src/components/SystemInfoCard.tsx", 159]
|
||||
],
|
||||
"translation": "Version"
|
||||
},
|
||||
"system_info.description": {
|
||||
"message": "Version and feature information",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 112]],
|
||||
"translation": "Version and feature information"
|
||||
},
|
||||
"project_list.view_conversations": {
|
||||
"message": "View Conversations",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -23,28 +23,6 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 306]],
|
||||
"translation": "テーマを選択"
|
||||
},
|
||||
"Reload MCP servers": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/McpTab.tsx",
|
||||
42
|
||||
]
|
||||
],
|
||||
"translation": "MCPサーバーを再読み込み"
|
||||
},
|
||||
"Close sidebar": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
173
|
||||
]
|
||||
],
|
||||
"translation": "サイドバーを閉じる"
|
||||
},
|
||||
"Type your message... (Start with / for commands, @ for files, Enter to send)": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
@@ -90,6 +68,28 @@
|
||||
],
|
||||
"translation": "メッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信)"
|
||||
},
|
||||
"Reload MCP servers": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/McpTab.tsx",
|
||||
42
|
||||
]
|
||||
],
|
||||
"translation": "MCPサーバーを再読み込み"
|
||||
},
|
||||
"Close sidebar": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
173
|
||||
]
|
||||
],
|
||||
"translation": "サイドバーを閉じる"
|
||||
},
|
||||
"Type your message here... (Start with / for commands, @ for files, Enter to send)": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
@@ -114,36 +114,6 @@
|
||||
],
|
||||
"translation": "ここにメッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信)"
|
||||
},
|
||||
"Available commands": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/CommandCompletion.tsx",
|
||||
193
|
||||
]
|
||||
],
|
||||
"translation": "利用可能なコマンド"
|
||||
},
|
||||
"Message input with completion support": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 210]
|
||||
],
|
||||
"translation": "補完機能付きメッセージ入力"
|
||||
},
|
||||
"Available files and directories": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/FileCompletion.tsx",
|
||||
267
|
||||
]
|
||||
],
|
||||
"translation": "利用可能なファイルとディレクトリ"
|
||||
},
|
||||
"Uncommitted changes": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
@@ -221,6 +191,36 @@
|
||||
],
|
||||
"translation": "比較先"
|
||||
},
|
||||
"Available commands": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/CommandCompletion.tsx",
|
||||
193
|
||||
]
|
||||
],
|
||||
"translation": "利用可能なコマンド"
|
||||
},
|
||||
"Available files and directories": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/components/chatForm/FileCompletion.tsx",
|
||||
267
|
||||
]
|
||||
],
|
||||
"translation": "利用可能なファイルとディレクトリ"
|
||||
},
|
||||
"Message input with completion support": {
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 210]
|
||||
],
|
||||
"translation": "補完機能付きメッセージ入力"
|
||||
},
|
||||
"session.conversation.abort": {
|
||||
"message": "Abort",
|
||||
"placeholders": {},
|
||||
@@ -244,6 +244,13 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 234]],
|
||||
"translation": "編集を承認(ファイル編集を自動承認)"
|
||||
},
|
||||
"system_info.feature.uuid_on_sdk_message.description": {
|
||||
"message": "Adds unique identifiers to SDK messages for better tracking (v1.0.86+)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 56]],
|
||||
"translation": "SDKメッセージに一意の識別子を追加して追跡を改善します (v1.0.86+)"
|
||||
},
|
||||
"chat.autocomplete.active": {
|
||||
"message": "Autocomplete active",
|
||||
"placeholders": {},
|
||||
@@ -253,6 +260,13 @@
|
||||
],
|
||||
"translation": "オートコンプリート有効"
|
||||
},
|
||||
"system_info.available_features": {
|
||||
"message": "Available Features",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 175]],
|
||||
"translation": "利用可能機能"
|
||||
},
|
||||
"sidebar.back.to.projects": {
|
||||
"message": "Back to projects",
|
||||
"placeholders": {},
|
||||
@@ -273,7 +287,7 @@
|
||||
"message": "Back to Projects",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 42]],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 45]],
|
||||
"translation": "プロジェクト一覧に戻る"
|
||||
},
|
||||
"project.error.back_to_projects": {
|
||||
@@ -339,6 +353,20 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 290]],
|
||||
"translation": "お好みの言語を選択"
|
||||
},
|
||||
"system_info.feature.agent_sdk.title": {
|
||||
"message": "Claude Agent SDK",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 65]],
|
||||
"translation": "Claude Agent SDK"
|
||||
},
|
||||
"system_info.claude_code": {
|
||||
"message": "Claude Code",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 141]],
|
||||
"translation": "Claude Code"
|
||||
},
|
||||
"session.processing": {
|
||||
"message": "Claude Code is processing...",
|
||||
"placeholders": {},
|
||||
@@ -351,6 +379,13 @@
|
||||
],
|
||||
"translation": "Claude Codeが処理中..."
|
||||
},
|
||||
"system_info.viewer_version": {
|
||||
"message": "Claude Code Viewer",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 123]],
|
||||
"translation": "Claude Code Viewer"
|
||||
},
|
||||
"settings.input.enter_key_behavior.command_enter": {
|
||||
"message": "Command+Enter to send",
|
||||
"placeholders": {},
|
||||
@@ -519,9 +554,16 @@
|
||||
"message": "Display and behavior preferences",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 55]],
|
||||
"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": {},
|
||||
@@ -581,6 +623,13 @@
|
||||
"origin": [["src/app/projects/[projectId]/error.tsx", 58]],
|
||||
"translation": "エラーID:"
|
||||
},
|
||||
"system_info.executable_path": {
|
||||
"message": "Executable",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 146]],
|
||||
"translation": "実行ファイル"
|
||||
},
|
||||
"mcp.error.load_failed": {
|
||||
"message": "Failed to load MCP servers: {error}",
|
||||
"placeholders": {
|
||||
@@ -611,6 +660,13 @@
|
||||
],
|
||||
"translation": "メッセージの送信に失敗しました。もう一度お試しください。"
|
||||
},
|
||||
"system_info.feature.unknown.description": {
|
||||
"message": "Feature information not available",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 81]],
|
||||
"translation": "機能情報は利用できません"
|
||||
},
|
||||
"diff.files": {
|
||||
"message": "files",
|
||||
"placeholders": {},
|
||||
@@ -661,7 +717,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
98
|
||||
152
|
||||
]
|
||||
],
|
||||
"translation": "入力パラメータ"
|
||||
@@ -727,10 +783,17 @@
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
115
|
||||
],
|
||||
["src/components/GlobalSidebar.tsx", 66]
|
||||
["src/components/GlobalSidebar.tsx", 67]
|
||||
],
|
||||
"translation": "設定を読み込み中..."
|
||||
},
|
||||
"system_info.loading": {
|
||||
"message": "Loading system information...",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 109]],
|
||||
"translation": "システム情報を読み込んでいます..."
|
||||
},
|
||||
"directory_picker.loading": {
|
||||
"message": "Loading...",
|
||||
"placeholders": {},
|
||||
@@ -782,6 +845,13 @@
|
||||
],
|
||||
"translation": "表示がサポートされていないメディア形式です"
|
||||
},
|
||||
"system_info.feature.uuid_on_sdk_message.title": {
|
||||
"message": "Message UUID Support",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 50]],
|
||||
"translation": "メッセージUUIDサポート"
|
||||
},
|
||||
"project_list.messages": {
|
||||
"message": "Messages:",
|
||||
"placeholders": {},
|
||||
@@ -852,7 +922,7 @@
|
||||
"message": "Notifications",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 84]],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 85]],
|
||||
"translation": "通知"
|
||||
},
|
||||
"settings.notifications": {
|
||||
@@ -927,7 +997,7 @@
|
||||
"message": "Project Not Found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 23]],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 26]],
|
||||
"translation": "プロジェクトが見つかりません"
|
||||
},
|
||||
"diff.push": {
|
||||
@@ -1094,7 +1164,7 @@
|
||||
"message": "Session Display",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 74]],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 75]],
|
||||
"translation": "セッション表示"
|
||||
},
|
||||
"settings.session.display": {
|
||||
@@ -1125,7 +1195,7 @@
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 52]],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 53]],
|
||||
"translation": "設定"
|
||||
},
|
||||
"settings.tab.title": {
|
||||
@@ -1137,7 +1207,7 @@
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
278
|
||||
],
|
||||
["src/components/GlobalSidebar.tsx", 43]
|
||||
["src/components/GlobalSidebar.tsx", 44]
|
||||
],
|
||||
"translation": "表示と通知の設定"
|
||||
},
|
||||
@@ -1204,6 +1274,20 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 316]],
|
||||
"translation": "システム"
|
||||
},
|
||||
"system_info.title": {
|
||||
"message": "System Information",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 109]],
|
||||
"translation": "システム情報"
|
||||
},
|
||||
"settings.section.system_info": {
|
||||
"message": "System Information",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/GlobalSidebar.tsx", 102]],
|
||||
"translation": "システム情報"
|
||||
},
|
||||
"notification.test": {
|
||||
"message": "Test",
|
||||
"placeholders": {},
|
||||
@@ -1215,7 +1299,7 @@
|
||||
"message": "The project you are looking for does not exist or has been removed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 29]],
|
||||
"origin": [["src/app/projects/[projectId]/not-found.tsx", 32]],
|
||||
"translation": "お探しのプロジェクトは存在しないか、削除されています"
|
||||
},
|
||||
"settings.theme": {
|
||||
@@ -1232,7 +1316,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
53
|
||||
70
|
||||
]
|
||||
],
|
||||
"translation": "思考中"
|
||||
@@ -1256,7 +1340,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
122
|
||||
176
|
||||
]
|
||||
],
|
||||
"translation": "ツール実行結果"
|
||||
@@ -1268,11 +1352,18 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx",
|
||||
80
|
||||
134
|
||||
]
|
||||
],
|
||||
"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": {},
|
||||
@@ -1299,6 +1390,16 @@
|
||||
"origin": [["src/components/SettingsControls.tsx", 144]],
|
||||
"translation": "同じタイトルのセッションを統合"
|
||||
},
|
||||
"system_info.unknown": {
|
||||
"message": "Unknown",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SystemInfoCard.tsx", 151],
|
||||
["src/components/SystemInfoCard.tsx", 163]
|
||||
],
|
||||
"translation": "不明"
|
||||
},
|
||||
"user.content.unsupported_media": {
|
||||
"message": "Unsupported Media",
|
||||
"placeholders": {},
|
||||
@@ -1323,6 +1424,30 @@
|
||||
],
|
||||
"translation": "ユーザーがアップロードした画像コンテンツ"
|
||||
},
|
||||
"system_info.feature.agent_sdk.description": {
|
||||
"message": "Uses Claude Agent SDK instead of Claude Code SDK (v1.0.125+)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 71]],
|
||||
"translation": "Claude Code SDKではなくClaude Agent SDKを使用 (v1.0.125+)"
|
||||
},
|
||||
"system_info.version_label": {
|
||||
"message": "Version",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SystemInfoCard.tsx", 130],
|
||||
["src/components/SystemInfoCard.tsx", 159]
|
||||
],
|
||||
"translation": "バージョン"
|
||||
},
|
||||
"system_info.description": {
|
||||
"message": "Version and feature information",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/SystemInfoCard.tsx", 112]],
|
||||
"translation": "バージョンと機能情報"
|
||||
},
|
||||
"project_list.view_conversations": {
|
||||
"message": "View Conversations",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4,6 +4,7 @@ import type { ControllerResponse } from "../../../lib/effect/toEffectResponse";
|
||||
import type { InferEffect } from "../../../lib/effect/types";
|
||||
import { ApplicationContext } from "../../platform/services/ApplicationContext";
|
||||
import { ProjectRepository } from "../../project/infrastructure/ProjectRepository";
|
||||
import * as ClaudeCodeVersion from "../models/ClaudeCodeVersion";
|
||||
import { ClaudeCodeService } from "../services/ClaudeCodeService";
|
||||
|
||||
const LayerImpl = Effect.gen(function* () {
|
||||
@@ -80,9 +81,43 @@ const LayerImpl = Effect.gen(function* () {
|
||||
} as const satisfies ControllerResponse;
|
||||
});
|
||||
|
||||
const getClaudeCodeMeta = () =>
|
||||
Effect.gen(function* () {
|
||||
const config = yield* claudeCodeService.getClaudeCodeMeta();
|
||||
return {
|
||||
response: {
|
||||
executablePath: config.claudeCodeExecutablePath,
|
||||
version: config.claudeCodeVersion
|
||||
? ClaudeCodeVersion.versionText(config.claudeCodeVersion)
|
||||
: null,
|
||||
},
|
||||
status: 200,
|
||||
} as const satisfies ControllerResponse;
|
||||
});
|
||||
|
||||
const getAvailableFeatures = () =>
|
||||
Effect.gen(function* () {
|
||||
const features = yield* claudeCodeService.getAvailableFeatures();
|
||||
const featuresList = Object.entries(features).flatMap(([key, value]) => {
|
||||
return [
|
||||
{
|
||||
name: key as keyof typeof features,
|
||||
enabled: value,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
return {
|
||||
response: { features: featuresList },
|
||||
status: 200,
|
||||
} as const satisfies ControllerResponse;
|
||||
});
|
||||
|
||||
return {
|
||||
getClaudeCommands,
|
||||
getMcpListRoute,
|
||||
getClaudeCodeMeta,
|
||||
getAvailableFeatures,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -13,6 +13,21 @@ class ProjectPathNotFoundError extends Data.TaggedError(
|
||||
const LayerImpl = Effect.gen(function* () {
|
||||
const projectRepository = yield* ProjectRepository;
|
||||
|
||||
const getClaudeCodeMeta = () =>
|
||||
Effect.gen(function* () {
|
||||
const config = yield* ClaudeCode.Config;
|
||||
return config;
|
||||
});
|
||||
|
||||
const getAvailableFeatures = () =>
|
||||
Effect.gen(function* () {
|
||||
const config = yield* ClaudeCode.Config;
|
||||
const features = ClaudeCode.getAvailableFeatures(
|
||||
config.claudeCodeVersion,
|
||||
);
|
||||
return features;
|
||||
});
|
||||
|
||||
const getMcpList = (projectId: string) =>
|
||||
Effect.gen(function* () {
|
||||
const { project } = yield* projectRepository.getProject(projectId);
|
||||
@@ -27,7 +42,9 @@ const LayerImpl = Effect.gen(function* () {
|
||||
});
|
||||
|
||||
return {
|
||||
getClaudeCodeMeta,
|
||||
getMcpList,
|
||||
getAvailableFeatures,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { setCookie } from "hono/cookie";
|
||||
import { streamSSE } from "hono/streaming";
|
||||
import prexit from "prexit";
|
||||
import { z } from "zod";
|
||||
import packageJson from "../../../package.json" with { type: "json" };
|
||||
import { ClaudeCodeController } from "../core/claude-code/presentation/ClaudeCodeController";
|
||||
import { ClaudeCodePermissionController } from "../core/claude-code/presentation/ClaudeCodePermissionController";
|
||||
import { ClaudeCodeSessionProcessController } from "../core/claude-code/presentation/ClaudeCodeSessionProcessController";
|
||||
@@ -94,6 +95,12 @@ export const routes = (app: HonoAppType) =>
|
||||
});
|
||||
})
|
||||
|
||||
.get("/version", async (c) => {
|
||||
return c.json({
|
||||
version: packageJson.version,
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
* ProjectController Routes
|
||||
*/
|
||||
@@ -298,6 +305,26 @@ export const routes = (app: HonoAppType) =>
|
||||
return response;
|
||||
})
|
||||
|
||||
.get("/cc/meta", async (c) => {
|
||||
const response = await effectToResponse(
|
||||
c,
|
||||
claudeCodeController
|
||||
.getClaudeCodeMeta()
|
||||
.pipe(Effect.provide(runtime)),
|
||||
);
|
||||
return response;
|
||||
})
|
||||
|
||||
.get("/cc/features", async (c) => {
|
||||
const response = await effectToResponse(
|
||||
c,
|
||||
claudeCodeController
|
||||
.getAvailableFeatures()
|
||||
.pipe(Effect.provide(runtime)),
|
||||
);
|
||||
return response;
|
||||
})
|
||||
|
||||
/**
|
||||
* ClaudeCodeSessionProcessController Routes
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user