fix(hands): use hand.id instead of hand.name for API calls

- Fix HandTaskPanel to use hand.id when loading runs and triggering
- Fix HandsPanel to use hand.id for getHandDetails and triggerHand
- Fix WorkflowEditor to use hand.id as option value

The API expects hand identifiers, not names. This ensures correct
hand execution and run history loading.

Also clean up old plan files and add Gateway stability plan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-16 09:57:01 +08:00
parent a312524abb
commit 26e64a3fff
4 changed files with 217 additions and 8 deletions

View File

@@ -57,19 +57,19 @@ export function HandTaskPanel({ handId, onBack }: HandTaskPanelProps) {
// Load task history when hand is selected
useEffect(() => {
if (selectedHand) {
loadHandRuns(selectedHand.name, { limit: 50 });
loadHandRuns(selectedHand.id, { limit: 50 });
}
}, [selectedHand, loadHandRuns]);
// Get runs for this hand from store
const tasks: HandRun[] = selectedHand ? (handRuns[selectedHand.name] || []) : [];
const tasks: HandRun[] = selectedHand ? (handRuns[selectedHand.id] || []) : [];
// Refresh task history
const handleRefresh = useCallback(async () => {
if (!selectedHand) return;
setIsRefreshing(true);
try {
await loadHandRuns(selectedHand.name, { limit: 50 });
await loadHandRuns(selectedHand.id, { limit: 50 });
} finally {
setIsRefreshing(false);
}
@@ -80,11 +80,11 @@ export function HandTaskPanel({ handId, onBack }: HandTaskPanelProps) {
if (!selectedHand) return;
setIsActivating(true);
try {
await triggerHand(selectedHand.name);
await triggerHand(selectedHand.id);
// Refresh hands list and task history
await Promise.all([
loadHands(),
loadHandRuns(selectedHand.name, { limit: 50 }),
loadHandRuns(selectedHand.id, { limit: 50 }),
]);
} catch {
// Error is handled in store

View File

@@ -367,7 +367,7 @@ export function HandsPanel() {
const handleDetails = useCallback(async (hand: Hand) => {
// Load full details before showing modal
const { getHandDetails } = useGatewayStore.getState();
const details = await getHandDetails(hand.name);
const details = await getHandDetails(hand.id);
setSelectedHand(details || hand);
setShowModal(true);
}, []);
@@ -375,7 +375,7 @@ export function HandsPanel() {
const handleActivate = useCallback(async (hand: Hand) => {
setActivatingHandId(hand.id);
try {
await triggerHand(hand.name);
await triggerHand(hand.id);
// Refresh hands after activation
await loadHands();
} catch {

View File

@@ -84,7 +84,7 @@ function StepEditor({ step, hands, index, onUpdate, onRemove, onMoveUp, onMoveDo
>
<option value=""> Hand...</option>
{hands.map(hand => (
<option key={hand.id} value={hand.name}>
<option key={hand.id} value={hand.id}>
{hand.name} - {hand.description}
</option>
))}