Files
claude-code/src/commands/goal/GoalReplaceConfirmDialog.tsx
moy16 3e3e1de81b feat: /goal命令能力支持,参考codex实现 (#1261)
* feat: /goal命令能力支持,参考codex实现

* fix: 修复promp和提示词不一致的问题

* fix: 修复 goal 功能多项 AI 审查问题

- prompt 中 update 行为描述与运行时不一致(no-op → error)
- src/commands/goal/ 使用相对路径导入,改为 src/* 别名
- /goal 命令标记 bridgeSafe 但含交互式对话框,改为 false
- useGoalContinuation 中 origin 使用 as unknown as string 强转,改为直接传字符串
- ResumeConversation 路径缺少 goal hydration,补齐恢复逻辑
- onCancel 在非查询状态下误暂停 goal,加 queryGuard 守卫
- resumeGoal 允许从终态恢复,收紧为仅允许 paused 状态
- buildGoalContextBlock 生成畸形 XML 属性,改为合法 budget 属性

* fix: 修复剩余AI审查的问题

* fix: 防止goal状态丢失

* fix: 修复Biome规范错误问题

* fix: 修复部分情况下goal无法启动的问题

* fix: 增加断网后状态默认设置为PAUSE机制、完成暂停-恢复状态切换,且正常进行前端渲染。设置达到max turn后处理逻辑。

* fix: 修复终端异常断开情况,resume续跑;修复用户消息排队信息被goal输出信息覆盖的问题。

* fix: apply biome formatting to pass CI lint check

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: skip slash command echo in setUserInputOnProcessing to prevent UI flash

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: moyu <moyu@kingsoft.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 10:44:10 +08:00

76 lines
2.3 KiB
TypeScript

/**
* Confirmation dialog shown when the user runs `/goal <objective>`
* while a non-complete goal is already active.
*/
import * as React from 'react';
import { Box, Text } from '@anthropic/ink';
import type { GoalState } from 'src/types/logs.js';
import { Select } from 'src/components/CustomSelect/index.js';
import { PermissionDialog } from 'src/components/permissions/PermissionDialog.js';
import { formatGoalElapsed, formatGoalStatusLabel } from 'src/services/goal/goalState.js';
type Props = {
currentGoal: GoalState;
newObjective: string;
onConfirm: () => void;
onCancel: () => void;
};
export function GoalReplaceConfirmDialog({ currentGoal, newObjective, onConfirm, onCancel }: Props): React.ReactNode {
function handleResponse(value: 'yes' | 'no'): void {
if (value === 'yes') onConfirm();
else onCancel();
}
const tokensDisplay =
currentGoal.tokenBudget !== null
? `${currentGoal.tokensUsed} / ${currentGoal.tokenBudget}`
: `${currentGoal.tokensUsed}`;
return (
<PermissionDialog color="warning" title="Replace active goal?">
<Box flexDirection="column" marginTop={1} paddingX={1}>
<Text>A goal is already in progress. Replacing it will reset all progress and counters.</Text>
<Box marginTop={1} flexDirection="column">
<Text dimColor>Current goal:</Text>
<Text>
<Text dimColor>· Objective: </Text>
{currentGoal.objective}
</Text>
<Text>
<Text dimColor>· Status: </Text>
{formatGoalStatusLabel(currentGoal.status)}
</Text>
<Text>
<Text dimColor>· Time: </Text>
{formatGoalElapsed(currentGoal)}
</Text>
<Text>
<Text dimColor>· Tokens: </Text>
{tokensDisplay}
</Text>
</Box>
<Box marginTop={1} flexDirection="column">
<Text dimColor>New objective:</Text>
<Text>{newObjective}</Text>
</Box>
<Box marginTop={1}>
<Select
options={[
{ label: 'Yes, replace the goal', value: 'yes' as const },
{ label: 'No, keep the current goal', value: 'no' as const },
]}
onChange={handleResponse}
onCancel={onCancel}
/>
</Box>
</Box>
</PermissionDialog>
);
}