mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 14:26:07 +00:00
fix(cli): retain bundled skill and bias setup wizard toward apply
Fix #399: when agent integration is selected but all agents are deselected, the bundled skill was silently dropped. The skill is now always included when agent integration is selected, regardless of client selection. Fix #398: the setup wizard defaulted to cancellation at every step despite explicit setup intent. The capability picker now pre-selects agent integration, the agent picker pre-selects all detected agents, the final confirmation defaults to Yes, and accessible prompts default to Yes for pre-selected items. Agent option hints now describe the agent instead of the file operation. Update tests/cliSetup.test.ts to cover the new skill-retention (#399) and default-toward-apply (#398) behavior, including accessible-mode opt-out. Update docs/installation.md to describe the new pre-selection and Yes-default confirmation.
This commit is contained in:
1 parent
eb27f01aee
commit
fec5c3ce7f
3 files changed
+118
-44
No files matched your search
+32
-11
@@ -61,7 +61,7 @@ export const confirmInteractiveSetup = async (
|
||||
selectedActions.length === 1
|
||||
? "Apply this change?"
|
||||
: `Apply these ${String(selectedActions.length)} changes?`,
|
||||
initialValue: false,
|
||||
initialValue: true,
|
||||
active: "Yes, apply",
|
||||
inactive: "No, cancel",
|
||||
});
|
||||
@@ -131,9 +131,10 @@ const selectSetupActions = async (
|
||||
({ kind }) => kind !== "configure_client",
|
||||
);
|
||||
const capabilities = setupCapabilities(clientActions, componentActions);
|
||||
const preselectedCapabilityIds = defaultCapabilityIds(capabilities);
|
||||
const selectedCapabilities = accessible
|
||||
? await selectCapabilitiesAccessibly(capabilities)
|
||||
: await selectCapabilities(capabilities);
|
||||
? await selectCapabilitiesAccessibly(capabilities, preselectedCapabilityIds)
|
||||
: await selectCapabilities(capabilities, preselectedCapabilityIds);
|
||||
if (selectedCapabilities === undefined) return undefined;
|
||||
const selectedCapabilityIds = new Set(selectedCapabilities);
|
||||
const bundledSkillAction = componentActions.find(
|
||||
@@ -147,23 +148,35 @@ const selectSetupActions = async (
|
||||
.map(({ id }) => id);
|
||||
if (!selectedCapabilityIds.has(agentIntegrationCapabilityId))
|
||||
return selectedActionIds;
|
||||
const bundledSkillId =
|
||||
bundledSkillAction === undefined ? undefined : bundledSkillAction.id;
|
||||
if (clientActions.length === 0)
|
||||
return [
|
||||
...(bundledSkillAction === undefined ? [] : [bundledSkillAction.id]),
|
||||
...(bundledSkillId === undefined ? [] : [bundledSkillId]),
|
||||
...selectedActionIds,
|
||||
];
|
||||
const preselectedClientIds = clientActions.map(({ id }) => id);
|
||||
const selectedClients = accessible
|
||||
? await selectClientsAccessibly(clientActions)
|
||||
: await selectClients(clientActions);
|
||||
? await selectClientsAccessibly(clientActions, preselectedClientIds)
|
||||
: await selectClients(clientActions, preselectedClientIds);
|
||||
if (selectedClients === undefined) return undefined;
|
||||
if (selectedClients.length === 0) return selectedActionIds;
|
||||
return [
|
||||
...selectedClients,
|
||||
...(bundledSkillAction === undefined ? [] : [bundledSkillAction.id]),
|
||||
...(bundledSkillId === undefined ? [] : [bundledSkillId]),
|
||||
...selectedActionIds,
|
||||
];
|
||||
};
|
||||
|
||||
const defaultCapabilityIds = (
|
||||
capabilities: readonly SetupCapability[],
|
||||
): readonly string[] => {
|
||||
const hasAgentIntegration = capabilities.some(
|
||||
({ id }) => id === agentIntegrationCapabilityId,
|
||||
);
|
||||
if (!hasAgentIntegration) return [];
|
||||
return [agentIntegrationCapabilityId];
|
||||
};
|
||||
|
||||
const setupCapabilities = (
|
||||
clientActions: readonly SetupAction[],
|
||||
componentActions: readonly SetupAction[],
|
||||
@@ -192,6 +205,7 @@ const setupCapabilities = (
|
||||
|
||||
const selectCapabilities = async (
|
||||
capabilities: readonly SetupCapability[],
|
||||
initialValues: readonly string[],
|
||||
): Promise<readonly string[] | undefined> => {
|
||||
const selection = await multiselect({
|
||||
...promptStreams,
|
||||
@@ -201,6 +215,7 @@ const selectCapabilities = async (
|
||||
label: capability.label,
|
||||
hint: capability.hint,
|
||||
})),
|
||||
initialValues: [...initialValues],
|
||||
required: false,
|
||||
maxItems: Math.max(
|
||||
3,
|
||||
@@ -213,13 +228,15 @@ const selectCapabilities = async (
|
||||
|
||||
const selectCapabilitiesAccessibly = async (
|
||||
capabilities: readonly SetupCapability[],
|
||||
preselectedIds: readonly string[],
|
||||
): Promise<readonly string[] | undefined> => {
|
||||
const preselected = new Set(preselectedIds);
|
||||
const selected: string[] = [];
|
||||
for (const capability of capabilities) {
|
||||
const included = await confirm({
|
||||
...promptStreams,
|
||||
message: `Set up ${capability.label}? ${capability.hint}`,
|
||||
initialValue: false,
|
||||
initialValue: preselected.has(capability.id),
|
||||
vertical: true,
|
||||
});
|
||||
if (isCancel(included)) return undefined;
|
||||
@@ -230,6 +247,7 @@ const selectCapabilitiesAccessibly = async (
|
||||
|
||||
const selectClients = async (
|
||||
actions: readonly SetupAction[],
|
||||
initialValues: readonly string[],
|
||||
): Promise<readonly string[] | undefined> => {
|
||||
const selection = await multiselect({
|
||||
...promptStreams,
|
||||
@@ -237,8 +255,9 @@ const selectClients = async (
|
||||
options: actions.map((action) => ({
|
||||
value: action.id,
|
||||
label: `${action.label} (detected)`,
|
||||
hint: `${action.operation} · ${action.target}`,
|
||||
hint: `Configure the REA MCP server for ${action.label}`,
|
||||
})),
|
||||
initialValues: [...initialValues],
|
||||
required: false,
|
||||
maxItems: Math.max(
|
||||
3,
|
||||
@@ -251,13 +270,15 @@ const selectClients = async (
|
||||
|
||||
const selectClientsAccessibly = async (
|
||||
actions: readonly SetupAction[],
|
||||
initialValues: readonly string[],
|
||||
): Promise<readonly string[] | undefined> => {
|
||||
const preselected = new Set(initialValues);
|
||||
const selected: string[] = [];
|
||||
for (const action of actions) {
|
||||
const included = await confirm({
|
||||
...promptStreams,
|
||||
message: `Configure ${action.label}? ${action.target}`,
|
||||
initialValue: false,
|
||||
initialValue: preselected.has(action.id),
|
||||
vertical: true,
|
||||
});
|
||||
if (isCancel(included)) return undefined;
|
||||
|
||||
Reference in new issue
Block a user