Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions apps/desktop/src/main/todo-agent/trpc-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,12 @@ export const createTodoAgentRouter = () => {

/**
* Edit the user-authored fields (description / goal) of a TODO
* session that has not started yet. Allowed only in pre-start
* states (queued / failed / aborted / escalated) so a running
* worker's prompt can never mutate under its feet. When the
* description / goal changes we rewrite the session's goal.md
* so the next run picks up the edit.
* session. Allowed in queued / preparing / failed / aborted /
* escalated. `preparing` is safe because the supervisor has
* not spawned Claude yet and `prepareArtifacts` will rewrite
* goal.md before it is read. Refused once the session is
* running / verifying so the worker's prompt never mutates
* under its feet.
*/
updateFields: publicProcedure
.input(
Expand All @@ -251,14 +252,15 @@ export const createTodoAgentRouter = () => {
}
if (
session.status !== "queued" &&
session.status !== "preparing" &&
session.status !== "failed" &&
session.status !== "aborted" &&
session.status !== "escalated"
) {
throw new TRPCError({
code: "PRECONDITION_FAILED",
message:
"実行中またはキュー済みでないセッションは編集できません。中断してから再度お試しください。",
"実行中のセッションは編集できません。中断してから再度お試しください。",
});
}
const patch: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,25 @@ function SessionDetail({ session, onDeleted }: SessionDetailProps) {
}
}, [invalidate, rerunMut, session.id]);

const canEditFields = canStart && !isRunning;
// `preparing` is still editable: the supervisor has not spawned
// Claude yet, and prepareArtifacts rewrites goal.md before Claude
// reads it, so an edit during preparing still takes effect.
const canEditFields = canStart || session.status === "preparing";

// Bail out of any in-flight edit the moment the session starts
// actually running — e.g. a queued session whose turn arrived
// mid-edit — so the user doesn't hit Save only to get rejected by
// the backend guard. Only cancel on running/verifying; terminal
// states stay editable (rerun path).
useEffect(() => {
if (!editingField) return;
if (session.status !== "running" && session.status !== "verifying") return;
setEditingField(null);
setEditDraft("");
toast.warning(
"タスクの実行が開始されたため編集を中止しました。中断してから再度編集してください。",
);
}, [editingField, session.status]);

const startEditField = useCallback(
(field: "description" | "goal") => {
Expand Down
Loading