Skip to content

Commit e3ce13d

Browse files
jeremyederclaude
andcommitted
fix: address second round of CodeRabbit feedback
- state-sync/Dockerfile: add bash and sqlite packages (scripts require them) - agents-editor: use stable IDs for React keys instead of editable name Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2d1c700 commit e3ce13d

2 files changed

Lines changed: 28 additions & 8 deletions

File tree

components/frontend/src/components/claude-agent-options/_components/agents-editor.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { useRef } from "react";
34
import { Plus, Trash2 } from "lucide-react";
45
import type { z } from "zod";
56

@@ -21,27 +22,46 @@ import { StringListEditor } from "./string-list-editor";
2122
type AgentDef = z.infer<typeof agentDefinitionSchema>;
2223

2324
export function AgentsEditor({ value, onChange }: { value: Record<string, AgentDef>; onChange: (v: Record<string, AgentDef>) => void }) {
25+
const nextId = useRef(0);
26+
const ids = useRef<number[]>([]);
27+
2428
const entries = Object.entries(value);
29+
30+
// Sync IDs with entries length (handles external resets)
31+
while (ids.current.length < entries.length) {
32+
ids.current.push(nextId.current++);
33+
}
34+
ids.current.length = entries.length;
35+
2536
const addAgent = () => {
2637
let i = 1;
2738
while (`agent-${i}` in value) i++;
39+
ids.current.push(nextId.current++);
2840
onChange({ ...value, [`agent-${i}`]: { description: "", prompt: "" } });
2941
};
30-
const removeAgent = (name: string) => { const next = { ...value }; delete next[name]; onChange(next); };
31-
const updateAgentName = (oldName: string, newName: string) => {
42+
const removeAgent = (index: number) => {
43+
const name = entries[index][0];
44+
ids.current.splice(index, 1);
45+
const next = { ...value };
46+
delete next[name];
47+
onChange(next);
48+
};
49+
const updateAgentName = (index: number, newName: string) => {
3250
const next: Record<string, AgentDef> = {};
33-
for (const [k, v] of Object.entries(value)) next[k === oldName ? newName : k] = v;
51+
for (let i = 0; i < entries.length; i++) {
52+
next[i === index ? newName : entries[i][0]] = entries[i][1];
53+
}
3454
onChange(next);
3555
};
3656
const updateAgent = (name: string, agent: AgentDef) => onChange({ ...value, [name]: agent });
3757

3858
return (
3959
<div className="space-y-3">
4060
<p className="text-xs text-muted-foreground">Define custom sub-agents with their own prompt, tools, and model.</p>
41-
{entries.map(([name, agent]) => (
42-
<div key={name} className="border rounded-md p-3 space-y-3">
61+
{entries.map(([name, agent], i) => (
62+
<div key={ids.current[i]} className="border rounded-md p-3 space-y-3">
4363
<div className="flex items-center gap-2">
44-
<Input className="font-mono text-xs w-1/3" value={name} placeholder="agent-name" onChange={(e) => updateAgentName(name, e.target.value)} />
64+
<Input className="font-mono text-xs w-1/3" value={name} placeholder="agent-name" onChange={(e) => updateAgentName(i, e.target.value)} />
4565
<Select value={agent.model ?? "inherit"} onValueChange={(m) => updateAgent(name, { ...agent, model: m === "inherit" ? null : m as AgentDef["model"] })}>
4666
<SelectTrigger className="w-32"><SelectValue placeholder="Model" /></SelectTrigger>
4767
<SelectContent>
@@ -51,7 +71,7 @@ export function AgentsEditor({ value, onChange }: { value: Record<string, AgentD
5171
<SelectItem value="haiku">Haiku</SelectItem>
5272
</SelectContent>
5373
</Select>
54-
<Button type="button" variant="ghost" size="icon" className="ml-auto h-8 w-8" aria-label={`Remove ${name}`} onClick={() => removeAgent(name)}><Trash2 className="h-3 w-3" /></Button>
74+
<Button type="button" variant="ghost" size="icon" className="ml-auto h-8 w-8" aria-label={`Remove ${name}`} onClick={() => removeAgent(i)}><Trash2 className="h-3 w-3" /></Button>
5575
</div>
5676
<Input className="text-xs" placeholder="Description" value={agent.description} onChange={(e) => updateAgent(name, { ...agent, description: e.target.value })} />
5777
<Textarea className="font-mono text-xs" placeholder="Agent prompt..." rows={3} value={agent.prompt} onChange={(e) => updateAgent(name, { ...agent, prompt: e.target.value })} />

components/runners/state-sync/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
FROM alpine:3.21
22

3-
RUN apk add --no-cache rclone git jq
3+
RUN apk add --no-cache rclone git jq bash sqlite
44

55
# Copy scripts
66
COPY hydrate.sh /usr/local/bin/hydrate.sh

0 commit comments

Comments
 (0)