mirror of
https://github.com/aljazceru/claude-code-viewer.git
synced 2025-12-28 02:34:21 +01:00
feat: send reserved feature for current session
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { ChatInputProps } from "./ChatInput";
|
||||
|
||||
describe("ChatInput Props", () => {
|
||||
it("should have correct type definition for enableScheduledSend", () => {
|
||||
const props: ChatInputProps = {
|
||||
projectId: "test-project",
|
||||
onSubmit: async () => {},
|
||||
isPending: false,
|
||||
placeholder: "Type your message...",
|
||||
buttonText: "Send",
|
||||
enableScheduledSend: true,
|
||||
baseSessionId: null,
|
||||
};
|
||||
|
||||
expect(props.enableScheduledSend).toBe(true);
|
||||
expect(props.baseSessionId).toBe(null);
|
||||
});
|
||||
|
||||
it("should allow enableScheduledSend to be undefined", () => {
|
||||
const props: ChatInputProps = {
|
||||
projectId: "test-project",
|
||||
onSubmit: async () => {},
|
||||
isPending: false,
|
||||
placeholder: "Type your message...",
|
||||
buttonText: "Send",
|
||||
};
|
||||
|
||||
expect(props.enableScheduledSend).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should allow baseSessionId to be a string", () => {
|
||||
const props: ChatInputProps = {
|
||||
projectId: "test-project",
|
||||
onSubmit: async () => {},
|
||||
isPending: false,
|
||||
placeholder: "Type your message...",
|
||||
buttonText: "Send",
|
||||
baseSessionId: "session-123",
|
||||
};
|
||||
|
||||
expect(props.baseSessionId).toBe("session-123");
|
||||
});
|
||||
|
||||
it("should validate datetime format parsing logic", () => {
|
||||
const scheduledTime = "2025-10-26T15:30";
|
||||
const match = scheduledTime.match(
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/,
|
||||
);
|
||||
|
||||
expect(match).not.toBeNull();
|
||||
|
||||
if (match) {
|
||||
const year = Number(match[1]);
|
||||
const month = Number(match[2]);
|
||||
const day = Number(match[3]);
|
||||
const hours = Number(match[4]);
|
||||
const minutes = Number(match[5]);
|
||||
|
||||
expect(year).toBe(2025);
|
||||
expect(month).toBe(10);
|
||||
expect(day).toBe(26);
|
||||
expect(hours).toBe(15);
|
||||
expect(minutes).toBe(30);
|
||||
|
||||
const localDate = new Date(year, month - 1, day, hours, minutes);
|
||||
expect(localDate.getFullYear()).toBe(2025);
|
||||
expect(localDate.getMonth()).toBe(9); // 0-indexed
|
||||
expect(localDate.getDate()).toBe(26);
|
||||
expect(localDate.getHours()).toBe(15);
|
||||
expect(localDate.getMinutes()).toBe(30);
|
||||
}
|
||||
});
|
||||
|
||||
it("should handle invalid datetime format", () => {
|
||||
const invalidTime = "invalid-datetime";
|
||||
const match = invalidTime.match(
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/,
|
||||
);
|
||||
|
||||
expect(match).toBeNull();
|
||||
});
|
||||
|
||||
it("should generate default scheduled time with correct format", () => {
|
||||
const now = new Date();
|
||||
now.setHours(now.getHours() + 1);
|
||||
const formatted = now.toISOString().slice(0, 16);
|
||||
|
||||
// Verify format is correct (YYYY-MM-DDTHH:mm)
|
||||
expect(formatted).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/);
|
||||
|
||||
// Verify the format can be parsed back
|
||||
const parsed = new Date(formatted);
|
||||
expect(parsed).toBeInstanceOf(Date);
|
||||
expect(Number.isNaN(parsed.getTime())).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -8,8 +8,19 @@ import {
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
import { type FC, useCallback, useId, useRef, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "../../../../../components/ui/button";
|
||||
import { Input } from "../../../../../components/ui/input";
|
||||
import { Label } from "../../../../../components/ui/label";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "../../../../../components/ui/select";
|
||||
import { Textarea } from "../../../../../components/ui/textarea";
|
||||
import { useCreateSchedulerJob } from "../../../../../hooks/useScheduler";
|
||||
import { useConfig } from "../../../../hooks/useConfig";
|
||||
import type { CommandCompletionRef } from "./CommandCompletion";
|
||||
import type { FileCompletionRef } from "./FileCompletion";
|
||||
@@ -33,6 +44,8 @@ export interface ChatInputProps {
|
||||
containerClassName?: string;
|
||||
disabled?: boolean;
|
||||
buttonSize?: "sm" | "default" | "lg";
|
||||
enableScheduledSend?: boolean;
|
||||
baseSessionId?: string | null;
|
||||
}
|
||||
|
||||
export const ChatInput: FC<ChatInputProps> = ({
|
||||
@@ -46,6 +59,8 @@ export const ChatInput: FC<ChatInputProps> = ({
|
||||
containerClassName = "",
|
||||
disabled = false,
|
||||
buttonSize = "lg",
|
||||
enableScheduledSend = false,
|
||||
baseSessionId = null,
|
||||
}) => {
|
||||
const { i18n } = useLingui();
|
||||
const [message, setMessage] = useState("");
|
||||
@@ -56,6 +71,19 @@ export const ChatInput: FC<ChatInputProps> = ({
|
||||
relative: { top: number; left: number };
|
||||
absolute: { top: number; left: number };
|
||||
}>({ relative: { top: 0, left: 0 }, absolute: { top: 0, left: 0 } });
|
||||
const [sendMode, setSendMode] = useState<"immediate" | "scheduled">(
|
||||
"immediate",
|
||||
);
|
||||
const [scheduledTime, setScheduledTime] = useState(() => {
|
||||
const now = new Date();
|
||||
now.setHours(now.getHours() + 1);
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(now.getDate()).padStart(2, "0");
|
||||
const hours = String(now.getHours()).padStart(2, "0");
|
||||
const minutes = String(now.getMinutes()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}T${hours}:${minutes}`;
|
||||
});
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
@@ -64,6 +92,7 @@ export const ChatInput: FC<ChatInputProps> = ({
|
||||
const fileCompletionRef = useRef<FileCompletionRef>(null);
|
||||
const helpId = useId();
|
||||
const { config } = useConfig();
|
||||
const createSchedulerJob = useCreateSchedulerJob();
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!message.trim() && attachedFiles.length === 0) return;
|
||||
@@ -88,14 +117,73 @@ export const ChatInput: FC<ChatInputProps> = ({
|
||||
|
||||
const finalText = message.trim() + additionalText;
|
||||
|
||||
await onSubmit({
|
||||
text: finalText,
|
||||
images: images.length > 0 ? images : undefined,
|
||||
documents: documents.length > 0 ? documents : undefined,
|
||||
});
|
||||
if (enableScheduledSend && sendMode === "scheduled") {
|
||||
// Create a scheduler job for scheduled send
|
||||
const match = scheduledTime.match(
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/,
|
||||
);
|
||||
if (!match) {
|
||||
throw new Error("Invalid datetime format");
|
||||
}
|
||||
const year = Number(match[1]);
|
||||
const month = Number(match[2]);
|
||||
const day = Number(match[3]);
|
||||
const hours = Number(match[4]);
|
||||
const minutes = Number(match[5]);
|
||||
const localDate = new Date(year, month - 1, day, hours, minutes);
|
||||
|
||||
setMessage("");
|
||||
setAttachedFiles([]);
|
||||
try {
|
||||
await createSchedulerJob.mutateAsync({
|
||||
name: `Scheduled message at ${scheduledTime}`,
|
||||
schedule: {
|
||||
type: "reserved",
|
||||
reservedExecutionTime: localDate.toISOString(),
|
||||
},
|
||||
message: {
|
||||
content: finalText,
|
||||
projectId,
|
||||
baseSessionId,
|
||||
},
|
||||
enabled: true,
|
||||
});
|
||||
|
||||
toast.success(
|
||||
i18n._({
|
||||
id: "chat.scheduled_send.success",
|
||||
message: "Message scheduled successfully",
|
||||
}),
|
||||
{
|
||||
description: i18n._({
|
||||
id: "chat.scheduled_send.success_description",
|
||||
message: "You can view and manage it in the Scheduler tab",
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
setMessage("");
|
||||
setAttachedFiles([]);
|
||||
} catch (error) {
|
||||
toast.error(
|
||||
i18n._({
|
||||
id: "chat.scheduled_send.failed",
|
||||
message: "Failed to schedule message",
|
||||
}),
|
||||
{
|
||||
description: error instanceof Error ? error.message : undefined,
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Immediate send
|
||||
await onSubmit({
|
||||
text: finalText,
|
||||
images: images.length > 0 ? images : undefined,
|
||||
documents: documents.length > 0 ? documents : undefined,
|
||||
});
|
||||
|
||||
setMessage("");
|
||||
setAttachedFiles([]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -338,33 +426,93 @@ export const ChatInput: FC<ChatInputProps> = ({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={
|
||||
(!message.trim() && attachedFiles.length === 0) ||
|
||||
isPending ||
|
||||
disabled
|
||||
}
|
||||
size={buttonSize}
|
||||
className="gap-2 transition-all duration-200 hover:shadow-md hover:scale-105 active:scale-95 bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-500 hover:to-purple-500 disabled:from-muted disabled:to-muted"
|
||||
>
|
||||
{isPending ? (
|
||||
<>
|
||||
<LoaderIcon className="w-4 h-4 animate-spin" />
|
||||
<span>
|
||||
<Trans
|
||||
id="chat.status.processing"
|
||||
message="Processing..."
|
||||
/>
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<SendIcon className="w-4 h-4" />
|
||||
{buttonText}
|
||||
</>
|
||||
<div className="flex items-center gap-2">
|
||||
{enableScheduledSend && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Label htmlFor="send-mode" className="text-xs sr-only">
|
||||
<Trans id="chat.send_mode.label" message="Send mode" />
|
||||
</Label>
|
||||
<Select
|
||||
value={sendMode}
|
||||
onValueChange={(value: "immediate" | "scheduled") =>
|
||||
setSendMode(value)
|
||||
}
|
||||
disabled={isPending || disabled}
|
||||
>
|
||||
<SelectTrigger
|
||||
id="send-mode"
|
||||
className="h-8 w-[140px] text-xs"
|
||||
>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="immediate">
|
||||
<Trans
|
||||
id="chat.send_mode.immediate"
|
||||
message="Send now"
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value="scheduled">
|
||||
<Trans
|
||||
id="chat.send_mode.scheduled"
|
||||
message="Schedule send"
|
||||
/>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
{sendMode === "scheduled" && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Label
|
||||
htmlFor="scheduled-time"
|
||||
className="text-xs sr-only"
|
||||
>
|
||||
<Trans
|
||||
id="chat.send_mode.scheduled_time"
|
||||
message="Scheduled time"
|
||||
/>
|
||||
</Label>
|
||||
<Input
|
||||
id="scheduled-time"
|
||||
type="datetime-local"
|
||||
value={scheduledTime}
|
||||
onChange={(e) => setScheduledTime(e.target.value)}
|
||||
disabled={isPending || disabled}
|
||||
className="h-8 w-[180px] text-xs"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={
|
||||
(!message.trim() && attachedFiles.length === 0) ||
|
||||
isPending ||
|
||||
disabled
|
||||
}
|
||||
size={buttonSize}
|
||||
className="gap-2 transition-all duration-200 hover:shadow-md hover:scale-105 active:scale-95 bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-500 hover:to-purple-500 disabled:from-muted disabled:to-muted"
|
||||
>
|
||||
{isPending ? (
|
||||
<>
|
||||
<LoaderIcon className="w-4 h-4 animate-spin" />
|
||||
<span>
|
||||
<Trans
|
||||
id="chat.status.processing"
|
||||
message="Processing..."
|
||||
/>
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<SendIcon className="w-4 h-4" />
|
||||
{buttonText}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<InlineCompletion
|
||||
|
||||
@@ -26,18 +26,24 @@ export const ContinueChat: FC<{
|
||||
const getPlaceholder = () => {
|
||||
const behavior = config?.enterKeyBehavior;
|
||||
if (behavior === "enter-send") {
|
||||
return i18n._(
|
||||
"Type your message... (Start with / for commands, @ for files, Enter to send)",
|
||||
);
|
||||
return i18n._({
|
||||
id: "chat.placeholder.continue.enter",
|
||||
message:
|
||||
"Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)",
|
||||
});
|
||||
}
|
||||
if (behavior === "command-enter-send") {
|
||||
return i18n._(
|
||||
"Type your message... (Start with / for commands, @ for files, Command+Enter to send)",
|
||||
);
|
||||
return i18n._({
|
||||
id: "chat.placeholder.continue.command_enter",
|
||||
message:
|
||||
"Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)",
|
||||
});
|
||||
}
|
||||
return i18n._(
|
||||
"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)",
|
||||
);
|
||||
return i18n._({
|
||||
id: "chat.placeholder.continue.shift_enter",
|
||||
message:
|
||||
"Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)",
|
||||
});
|
||||
};
|
||||
|
||||
const buttonText = <Trans id="chat.send" message="Send" />;
|
||||
@@ -56,6 +62,8 @@ export const ContinueChat: FC<{
|
||||
minHeight="min-h-[120px]"
|
||||
containerClassName=""
|
||||
buttonSize="lg"
|
||||
enableScheduledSend={true}
|
||||
baseSessionId={sessionId}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,18 +25,24 @@ export const ResumeChat: FC<{
|
||||
const getPlaceholder = () => {
|
||||
const behavior = config?.enterKeyBehavior;
|
||||
if (behavior === "enter-send") {
|
||||
return i18n._(
|
||||
"Type your message... (Start with / for commands, @ for files, Enter to send)",
|
||||
);
|
||||
return i18n._({
|
||||
id: "chat.placeholder.resume.enter",
|
||||
message:
|
||||
"Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)",
|
||||
});
|
||||
}
|
||||
if (behavior === "command-enter-send") {
|
||||
return i18n._(
|
||||
"Type your message... (Start with / for commands, @ for files, Command+Enter to send)",
|
||||
);
|
||||
return i18n._({
|
||||
id: "chat.placeholder.resume.command_enter",
|
||||
message:
|
||||
"Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)",
|
||||
});
|
||||
}
|
||||
return i18n._(
|
||||
"Type your message... (Start with / for commands, @ for files, Shift+Enter to send)",
|
||||
);
|
||||
return i18n._({
|
||||
id: "chat.placeholder.resume.shift_enter",
|
||||
message:
|
||||
"Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)",
|
||||
});
|
||||
};
|
||||
|
||||
const buttonText = <Trans id="chat.resume" message="Resume" />;
|
||||
@@ -55,6 +61,8 @@ export const ResumeChat: FC<{
|
||||
minHeight="min-h-[120px]"
|
||||
containerClassName=""
|
||||
buttonSize="lg"
|
||||
enableScheduledSend={true}
|
||||
baseSessionId={sessionId}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -163,19 +163,19 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
{job ? (
|
||||
<Trans
|
||||
id="scheduler.dialog.title.edit"
|
||||
message="スケジュールジョブを編集"
|
||||
message="Edit Scheduled Job"
|
||||
/>
|
||||
) : (
|
||||
<Trans
|
||||
id="scheduler.dialog.title.create"
|
||||
message="スケジュールジョブを作成"
|
||||
message="Create Scheduled Job"
|
||||
/>
|
||||
)}
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
<Trans
|
||||
id="scheduler.dialog.description"
|
||||
message="Claude Code にメッセージを送信するスケジュールジョブを設定します"
|
||||
message="Set up a scheduled job to send messages to Claude Code"
|
||||
/>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -185,12 +185,12 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<div className="flex items-center justify-between rounded-lg border p-4">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="enabled" className="text-base font-semibold">
|
||||
<Trans id="scheduler.form.enabled" message="有効化" />
|
||||
<Trans id="scheduler.form.enabled" message="Enabled" />
|
||||
</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
<Trans
|
||||
id="scheduler.form.enabled.description"
|
||||
message="このスケジュールジョブを有効または無効にします"
|
||||
message="Enable or disable this scheduled job"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
@@ -205,7 +205,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
{/* Job Name */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="job-name">
|
||||
<Trans id="scheduler.form.name" message="ジョブ名" />
|
||||
<Trans id="scheduler.form.name" message="Job Name" />
|
||||
</Label>
|
||||
<Input
|
||||
id="job-name"
|
||||
@@ -213,7 +213,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder={_({
|
||||
id: "scheduler.form.name.placeholder",
|
||||
message: "例: 日次レポート",
|
||||
message: "e.g., Daily Report",
|
||||
})}
|
||||
disabled={isSubmitting}
|
||||
/>
|
||||
@@ -224,7 +224,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<Label>
|
||||
<Trans
|
||||
id="scheduler.form.schedule_type"
|
||||
message="スケジュールタイプ"
|
||||
message="Schedule Type"
|
||||
/>
|
||||
</Label>
|
||||
<Select
|
||||
@@ -241,13 +241,13 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<SelectItem value="cron">
|
||||
<Trans
|
||||
id="scheduler.form.schedule_type.cron"
|
||||
message="定期実行 (Cron)"
|
||||
message="Recurring (Cron)"
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value="reserved">
|
||||
<Trans
|
||||
id="scheduler.form.schedule_type.reserved"
|
||||
message="予約実行"
|
||||
message="One-time"
|
||||
/>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
@@ -265,7 +265,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<Label htmlFor="reserved-datetime">
|
||||
<Trans
|
||||
id="scheduler.form.reserved_time"
|
||||
message="実行予定日時"
|
||||
message="Scheduled Date and Time"
|
||||
/>
|
||||
</Label>
|
||||
<Input
|
||||
@@ -278,7 +278,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<Trans
|
||||
id="scheduler.form.reserved_time.hint"
|
||||
message="指定した日時に一度だけ実行されます。実行後は自動的に削除されます"
|
||||
message="Will run once at the specified time, then be automatically deleted"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
@@ -287,7 +287,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
{/* Message Content */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="message-content">
|
||||
<Trans id="scheduler.form.message" message="メッセージ内容" />
|
||||
<Trans id="scheduler.form.message" message="Message Content" />
|
||||
</Label>
|
||||
<div className="relative" ref={completion.containerRef}>
|
||||
<Textarea
|
||||
@@ -301,14 +301,16 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
placeholder={i18n._({
|
||||
id: "scheduler.form.message.placeholder",
|
||||
message:
|
||||
"Claude Code に送信するメッセージを入力... (/ でコマンド補完、@ でファイル補完)",
|
||||
"Type message to send to Claude Code... (/ for commands, @ for files)",
|
||||
})}
|
||||
rows={4}
|
||||
disabled={isSubmitting}
|
||||
className="resize-none"
|
||||
aria-label={i18n._(
|
||||
"Message input with completion support (/ for commands, @ for files)",
|
||||
)}
|
||||
aria-label={i18n._({
|
||||
id: "scheduler.form.message.aria_label",
|
||||
message:
|
||||
"Message input with completion support (/ for commands, @ for files)",
|
||||
})}
|
||||
aria-expanded={
|
||||
messageContent.startsWith("/") || messageContent.includes("@")
|
||||
}
|
||||
@@ -333,7 +335,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<Trans
|
||||
id="scheduler.form.message.hint"
|
||||
message="/ でコマンド補完、@ でファイル補完"
|
||||
message="/ for commands, @ for files"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
@@ -344,7 +346,7 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<Label>
|
||||
<Trans
|
||||
id="scheduler.form.concurrency_policy"
|
||||
message="同時実行ポリシー"
|
||||
message="Concurrency Policy"
|
||||
/>
|
||||
</Label>
|
||||
<Select
|
||||
@@ -361,13 +363,13 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
<SelectItem value="skip">
|
||||
<Trans
|
||||
id="scheduler.form.concurrency_policy.skip"
|
||||
message="実行中の場合はスキップ"
|
||||
message="Skip if running"
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value="run">
|
||||
<Trans
|
||||
id="scheduler.form.concurrency_policy.run"
|
||||
message="実行中でも実行する"
|
||||
message="Run even if running"
|
||||
/>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
@@ -382,18 +384,18 @@ export const SchedulerJobDialog: FC<SchedulerJobDialogProps> = ({
|
||||
onClick={() => onOpenChange(false)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
<Trans id="common.cancel" message="キャンセル" />
|
||||
<Trans id="common.cancel" message="Cancel" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={!isFormValid || isSubmitting}
|
||||
>
|
||||
{isSubmitting ? (
|
||||
<Trans id="common.saving" message="保存中..." />
|
||||
<Trans id="common.saving" message="Saving..." />
|
||||
) : job ? (
|
||||
<Trans id="common.update" message="更新" />
|
||||
<Trans id="common.update" message="Update" />
|
||||
) : (
|
||||
<Trans id="common.create" message="作成" />
|
||||
<Trans id="common.create" message="Create" />
|
||||
)}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
@@ -40,7 +40,9 @@ export const SessionSidebar: FC<{
|
||||
{
|
||||
id: "sessions",
|
||||
icon: MessageSquareIcon,
|
||||
title: "Show session list",
|
||||
title: (
|
||||
<Trans id="sidebar.show.session.list" message="Show session list" />
|
||||
),
|
||||
content: (
|
||||
<Suspense fallback={<Loading />}>
|
||||
<SessionsTab
|
||||
@@ -53,13 +55,23 @@ export const SessionSidebar: FC<{
|
||||
{
|
||||
id: "mcp",
|
||||
icon: PlugIcon,
|
||||
title: "Show MCP server settings",
|
||||
title: (
|
||||
<Trans
|
||||
id="sidebar.show.mcp.settings"
|
||||
message="Show MCP server settings"
|
||||
/>
|
||||
),
|
||||
content: <McpTab projectId={projectId} />,
|
||||
},
|
||||
{
|
||||
id: "scheduler",
|
||||
icon: CalendarClockIcon,
|
||||
title: "Show scheduler jobs",
|
||||
title: (
|
||||
<Trans
|
||||
id="sidebar.show.scheduler.jobs"
|
||||
message="Show scheduler jobs"
|
||||
/>
|
||||
),
|
||||
content: (
|
||||
<SchedulerTab projectId={projectId} sessionId={currentSessionId} />
|
||||
),
|
||||
|
||||
@@ -1266,11 +1266,155 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
42
|
||||
49
|
||||
]
|
||||
],
|
||||
"translation": "Send"
|
||||
},
|
||||
"chat.send_mode.label": {
|
||||
"message": "Send mode",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 433]
|
||||
],
|
||||
"translation": "Send mode"
|
||||
},
|
||||
"chat.send_mode.immediate": {
|
||||
"message": "Send now",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 452]
|
||||
],
|
||||
"translation": "Send now"
|
||||
},
|
||||
"chat.send_mode.scheduled": {
|
||||
"message": "Schedule send",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 458]
|
||||
],
|
||||
"translation": "Schedule send"
|
||||
},
|
||||
"chat.send_mode.scheduled_time": {
|
||||
"message": "Scheduled time",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 472]
|
||||
],
|
||||
"translation": "Scheduled time"
|
||||
},
|
||||
"chat.attach_file": {
|
||||
"message": "Attach",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 408]
|
||||
],
|
||||
"translation": "Attach"
|
||||
},
|
||||
"chat.placeholder.continue.enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
32
|
||||
]
|
||||
],
|
||||
"translation": "Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)"
|
||||
},
|
||||
"chat.placeholder.continue.command_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
39
|
||||
]
|
||||
],
|
||||
"translation": "Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)"
|
||||
},
|
||||
"chat.placeholder.continue.shift_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
45
|
||||
]
|
||||
],
|
||||
"translation": "Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)"
|
||||
},
|
||||
"chat.placeholder.resume.enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ResumeChat.tsx",
|
||||
31
|
||||
]
|
||||
],
|
||||
"translation": "Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)"
|
||||
},
|
||||
"chat.placeholder.resume.command_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ResumeChat.tsx",
|
||||
38
|
||||
]
|
||||
],
|
||||
"translation": "Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)"
|
||||
},
|
||||
"chat.placeholder.resume.shift_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ResumeChat.tsx",
|
||||
44
|
||||
]
|
||||
],
|
||||
"translation": "Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)"
|
||||
},
|
||||
"chat.scheduled_send.success": {
|
||||
"message": "Message scheduled successfully",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 152]
|
||||
],
|
||||
"translation": "Message scheduled successfully"
|
||||
},
|
||||
"chat.scheduled_send.success_description": {
|
||||
"message": "You can view and manage it in the Scheduler tab",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 157]
|
||||
],
|
||||
"translation": "You can view and manage it in the Scheduler tab"
|
||||
},
|
||||
"chat.scheduled_send.failed": {
|
||||
"message": "Failed to schedule message",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 168]
|
||||
],
|
||||
"translation": "Failed to schedule message"
|
||||
},
|
||||
"settings.section.session_display": {
|
||||
"message": "Session Display",
|
||||
"placeholders": {},
|
||||
@@ -1337,6 +1481,10 @@
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
258
|
||||
],
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx",
|
||||
56
|
||||
]
|
||||
],
|
||||
"translation": "Show MCP server settings"
|
||||
@@ -1356,10 +1504,26 @@
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
231
|
||||
],
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx",
|
||||
43
|
||||
]
|
||||
],
|
||||
"translation": "Show session list"
|
||||
},
|
||||
"sidebar.show.scheduler.jobs": {
|
||||
"message": "Show scheduler jobs",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx",
|
||||
62
|
||||
]
|
||||
],
|
||||
"translation": "Show scheduler jobs"
|
||||
},
|
||||
"system.info.tab.title": {
|
||||
"message": "Show system information",
|
||||
"placeholders": {},
|
||||
@@ -1777,5 +1941,281 @@
|
||||
["src/routes/projects/$projectId/sessions/$sessionId/index.tsx", 17]
|
||||
],
|
||||
"translation": "The session you are looking for does not exist."
|
||||
},
|
||||
"scheduler.dialog.title.edit": {
|
||||
"message": "Edit Scheduled Job",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
166
|
||||
]
|
||||
],
|
||||
"translation": "Edit Scheduled Job"
|
||||
},
|
||||
"scheduler.dialog.title.create": {
|
||||
"message": "Create Scheduled Job",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
171
|
||||
]
|
||||
],
|
||||
"translation": "Create Scheduled Job"
|
||||
},
|
||||
"scheduler.dialog.description": {
|
||||
"message": "Set up a scheduled job to send messages to Claude Code",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
178
|
||||
]
|
||||
],
|
||||
"translation": "Set up a scheduled job to send messages to Claude Code"
|
||||
},
|
||||
"scheduler.form.enabled": {
|
||||
"message": "Enabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
188
|
||||
]
|
||||
],
|
||||
"translation": "Enabled"
|
||||
},
|
||||
"scheduler.form.enabled.description": {
|
||||
"message": "Enable or disable this scheduled job",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
193
|
||||
]
|
||||
],
|
||||
"translation": "Enable or disable this scheduled job"
|
||||
},
|
||||
"scheduler.form.name": {
|
||||
"message": "Job Name",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
208
|
||||
]
|
||||
],
|
||||
"translation": "Job Name"
|
||||
},
|
||||
"scheduler.form.name.placeholder": {
|
||||
"message": "e.g., Daily Report",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
216
|
||||
]
|
||||
],
|
||||
"translation": "e.g., Daily Report"
|
||||
},
|
||||
"scheduler.form.schedule_type": {
|
||||
"message": "Schedule Type",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
227
|
||||
]
|
||||
],
|
||||
"translation": "Schedule Type"
|
||||
},
|
||||
"scheduler.form.schedule_type.cron": {
|
||||
"message": "Recurring (Cron)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
244
|
||||
]
|
||||
],
|
||||
"translation": "Recurring (Cron)"
|
||||
},
|
||||
"scheduler.form.schedule_type.reserved": {
|
||||
"message": "One-time",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
250
|
||||
]
|
||||
],
|
||||
"translation": "One-time"
|
||||
},
|
||||
"scheduler.form.reserved_time": {
|
||||
"message": "Scheduled Date and Time",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
268
|
||||
]
|
||||
],
|
||||
"translation": "Scheduled Date and Time"
|
||||
},
|
||||
"scheduler.form.reserved_time.hint": {
|
||||
"message": "Will run once at the specified time, then be automatically deleted",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
281
|
||||
]
|
||||
],
|
||||
"translation": "Will run once at the specified time, then be automatically deleted"
|
||||
},
|
||||
"scheduler.form.message": {
|
||||
"message": "Message Content",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
290
|
||||
]
|
||||
],
|
||||
"translation": "Message Content"
|
||||
},
|
||||
"scheduler.form.message.placeholder": {
|
||||
"message": "Type message to send to Claude Code... (/ for commands, @ for files)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
304
|
||||
]
|
||||
],
|
||||
"translation": "Type message to send to Claude Code... (/ for commands, @ for files)"
|
||||
},
|
||||
"scheduler.form.message.aria_label": {
|
||||
"message": "Message input with completion support (/ for commands, @ for files)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
311
|
||||
]
|
||||
],
|
||||
"translation": "Message input with completion support (/ for commands, @ for files)"
|
||||
},
|
||||
"scheduler.form.message.hint": {
|
||||
"message": "/ for commands, @ for files",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
337
|
||||
]
|
||||
],
|
||||
"translation": "/ for commands, @ for files"
|
||||
},
|
||||
"scheduler.form.concurrency_policy": {
|
||||
"message": "Concurrency Policy",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
348
|
||||
]
|
||||
],
|
||||
"translation": "Concurrency Policy"
|
||||
},
|
||||
"scheduler.form.concurrency_policy.skip": {
|
||||
"message": "Skip if running",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
365
|
||||
]
|
||||
],
|
||||
"translation": "Skip if running"
|
||||
},
|
||||
"scheduler.form.concurrency_policy.run": {
|
||||
"message": "Run even if running",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
371
|
||||
]
|
||||
],
|
||||
"translation": "Run even if running"
|
||||
},
|
||||
"common.cancel": {
|
||||
"message": "Cancel",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
386
|
||||
]
|
||||
],
|
||||
"translation": "Cancel"
|
||||
},
|
||||
"common.saving": {
|
||||
"message": "Saving...",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
393
|
||||
]
|
||||
],
|
||||
"translation": "Saving..."
|
||||
},
|
||||
"common.update": {
|
||||
"message": "Update",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
395
|
||||
]
|
||||
],
|
||||
"translation": "Update"
|
||||
},
|
||||
"common.create": {
|
||||
"message": "Create",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
397
|
||||
]
|
||||
],
|
||||
"translation": "Create"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1266,11 +1266,155 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
42
|
||||
49
|
||||
]
|
||||
],
|
||||
"translation": "送信"
|
||||
},
|
||||
"chat.send_mode.label": {
|
||||
"message": "Send mode",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 433]
|
||||
],
|
||||
"translation": "送信モード"
|
||||
},
|
||||
"chat.send_mode.immediate": {
|
||||
"message": "Send now",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 452]
|
||||
],
|
||||
"translation": "今すぐ送信"
|
||||
},
|
||||
"chat.send_mode.scheduled": {
|
||||
"message": "Schedule send",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 458]
|
||||
],
|
||||
"translation": "予約送信"
|
||||
},
|
||||
"chat.send_mode.scheduled_time": {
|
||||
"message": "Scheduled time",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 472]
|
||||
],
|
||||
"translation": "送信予定時刻"
|
||||
},
|
||||
"chat.attach_file": {
|
||||
"message": "Attach",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 408]
|
||||
],
|
||||
"translation": "添付"
|
||||
},
|
||||
"chat.placeholder.continue.enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
32
|
||||
]
|
||||
],
|
||||
"translation": "メッセージを入力... (/でコマンド、@でファイル、Enterで送信、または予約送信)"
|
||||
},
|
||||
"chat.placeholder.continue.command_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
39
|
||||
]
|
||||
],
|
||||
"translation": "メッセージを入力... (/でコマンド、@でファイル、Command+Enterで送信、または予約送信)"
|
||||
},
|
||||
"chat.placeholder.continue.shift_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ContinueChat.tsx",
|
||||
45
|
||||
]
|
||||
],
|
||||
"translation": "メッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信、または予約送信)"
|
||||
},
|
||||
"chat.placeholder.resume.enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ResumeChat.tsx",
|
||||
31
|
||||
]
|
||||
],
|
||||
"translation": "メッセージを入力... (/でコマンド、@でファイル、Enterで送信、または予約送信)"
|
||||
},
|
||||
"chat.placeholder.resume.command_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Command+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ResumeChat.tsx",
|
||||
38
|
||||
]
|
||||
],
|
||||
"translation": "メッセージを入力... (/でコマンド、@でファイル、Command+Enterで送信、または予約送信)"
|
||||
},
|
||||
"chat.placeholder.resume.shift_enter": {
|
||||
"message": "Type your message... (Start with / for commands, @ for files, Shift+Enter to send, or schedule for later)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/resumeChat/ResumeChat.tsx",
|
||||
44
|
||||
]
|
||||
],
|
||||
"translation": "メッセージを入力... (/でコマンド、@でファイル、Shift+Enterで送信、または予約送信)"
|
||||
},
|
||||
"chat.scheduled_send.success": {
|
||||
"message": "Message scheduled successfully",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 152]
|
||||
],
|
||||
"translation": "メッセージを予約しました"
|
||||
},
|
||||
"chat.scheduled_send.success_description": {
|
||||
"message": "You can view and manage it in the Scheduler tab",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 157]
|
||||
],
|
||||
"translation": "スケジューラタブで確認・管理できます"
|
||||
},
|
||||
"chat.scheduled_send.failed": {
|
||||
"message": "Failed to schedule message",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/app/projects/[projectId]/components/chatForm/ChatInput.tsx", 168]
|
||||
],
|
||||
"translation": "メッセージの予約に失敗しました"
|
||||
},
|
||||
"settings.section.session_display": {
|
||||
"message": "Session Display",
|
||||
"placeholders": {},
|
||||
@@ -1337,6 +1481,10 @@
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
258
|
||||
],
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx",
|
||||
56
|
||||
]
|
||||
],
|
||||
"translation": "MCPサーバー設定を表示"
|
||||
@@ -1356,10 +1504,26 @@
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/MobileSidebar.tsx",
|
||||
231
|
||||
],
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx",
|
||||
43
|
||||
]
|
||||
],
|
||||
"translation": "セッション一覧を表示"
|
||||
},
|
||||
"sidebar.show.scheduler.jobs": {
|
||||
"message": "Show scheduler jobs",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx",
|
||||
62
|
||||
]
|
||||
],
|
||||
"translation": "スケジューラジョブを表示"
|
||||
},
|
||||
"system.info.tab.title": {
|
||||
"message": "Show system information",
|
||||
"placeholders": {},
|
||||
@@ -1777,5 +1941,281 @@
|
||||
["src/routes/projects/$projectId/sessions/$sessionId/index.tsx", 17]
|
||||
],
|
||||
"translation": "お探しのセッションは存在しません。"
|
||||
},
|
||||
"scheduler.dialog.title.edit": {
|
||||
"message": "Edit Scheduled Job",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
166
|
||||
]
|
||||
],
|
||||
"translation": "スケジュールジョブを編集"
|
||||
},
|
||||
"scheduler.dialog.title.create": {
|
||||
"message": "Create Scheduled Job",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
171
|
||||
]
|
||||
],
|
||||
"translation": "スケジュールジョブを作成"
|
||||
},
|
||||
"scheduler.dialog.description": {
|
||||
"message": "Set up a scheduled job to send messages to Claude Code",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
178
|
||||
]
|
||||
],
|
||||
"translation": "Claude Codeにメッセージを送信するスケジュールジョブを設定します"
|
||||
},
|
||||
"scheduler.form.enabled": {
|
||||
"message": "Enabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
188
|
||||
]
|
||||
],
|
||||
"translation": "有効化"
|
||||
},
|
||||
"scheduler.form.enabled.description": {
|
||||
"message": "Enable or disable this scheduled job",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
193
|
||||
]
|
||||
],
|
||||
"translation": "このスケジュールジョブを有効または無効にします"
|
||||
},
|
||||
"scheduler.form.name": {
|
||||
"message": "Job Name",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
208
|
||||
]
|
||||
],
|
||||
"translation": "ジョブ名"
|
||||
},
|
||||
"scheduler.form.name.placeholder": {
|
||||
"message": "e.g., Daily Report",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
216
|
||||
]
|
||||
],
|
||||
"translation": "例: 日次レポート"
|
||||
},
|
||||
"scheduler.form.schedule_type": {
|
||||
"message": "Schedule Type",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
227
|
||||
]
|
||||
],
|
||||
"translation": "スケジュールタイプ"
|
||||
},
|
||||
"scheduler.form.schedule_type.cron": {
|
||||
"message": "Recurring (Cron)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
244
|
||||
]
|
||||
],
|
||||
"translation": "定期実行 (Cron)"
|
||||
},
|
||||
"scheduler.form.schedule_type.reserved": {
|
||||
"message": "One-time",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
250
|
||||
]
|
||||
],
|
||||
"translation": "予約実行"
|
||||
},
|
||||
"scheduler.form.reserved_time": {
|
||||
"message": "Scheduled Date and Time",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
268
|
||||
]
|
||||
],
|
||||
"translation": "実行予定日時"
|
||||
},
|
||||
"scheduler.form.reserved_time.hint": {
|
||||
"message": "Will run once at the specified time, then be automatically deleted",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
281
|
||||
]
|
||||
],
|
||||
"translation": "指定した日時に一度だけ実行されます。実行後は自動的に削除されます"
|
||||
},
|
||||
"scheduler.form.message": {
|
||||
"message": "Message Content",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
290
|
||||
]
|
||||
],
|
||||
"translation": "メッセージ内容"
|
||||
},
|
||||
"scheduler.form.message.placeholder": {
|
||||
"message": "Type message to send to Claude Code... (/ for commands, @ for files)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
304
|
||||
]
|
||||
],
|
||||
"translation": "Claude Codeに送信するメッセージを入力... (/でコマンド補完、@でファイル補完)"
|
||||
},
|
||||
"scheduler.form.message.aria_label": {
|
||||
"message": "Message input with completion support (/ for commands, @ for files)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
311
|
||||
]
|
||||
],
|
||||
"translation": "補完機能付きメッセージ入力 (/でコマンド、@でファイル)"
|
||||
},
|
||||
"scheduler.form.message.hint": {
|
||||
"message": "/ for commands, @ for files",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
337
|
||||
]
|
||||
],
|
||||
"translation": "/でコマンド補完、@でファイル補完"
|
||||
},
|
||||
"scheduler.form.concurrency_policy": {
|
||||
"message": "Concurrency Policy",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
348
|
||||
]
|
||||
],
|
||||
"translation": "同時実行ポリシー"
|
||||
},
|
||||
"scheduler.form.concurrency_policy.skip": {
|
||||
"message": "Skip if running",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
365
|
||||
]
|
||||
],
|
||||
"translation": "実行中の場合はスキップ"
|
||||
},
|
||||
"scheduler.form.concurrency_policy.run": {
|
||||
"message": "Run even if running",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
371
|
||||
]
|
||||
],
|
||||
"translation": "実行中でも実行する"
|
||||
},
|
||||
"common.cancel": {
|
||||
"message": "Cancel",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
386
|
||||
]
|
||||
],
|
||||
"translation": "キャンセル"
|
||||
},
|
||||
"common.saving": {
|
||||
"message": "Saving...",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
393
|
||||
]
|
||||
],
|
||||
"translation": "保存中..."
|
||||
},
|
||||
"common.update": {
|
||||
"message": "Update",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
395
|
||||
]
|
||||
],
|
||||
"translation": "更新"
|
||||
},
|
||||
"common.create": {
|
||||
"message": "Create",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/app/projects/[projectId]/sessions/[sessionId]/components/scheduler/SchedulerJobDialog.tsx",
|
||||
397
|
||||
]
|
||||
],
|
||||
"translation": "作成"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user