MCPcopy
hub / github.com/claude-code-best/claude-code / PluginOptionsFlow

Function PluginOptionsFlow

src/commands/plugin/PluginOptionsFlow.tsx:64–150  ·  view source on GitHub ↗
({ plugin, pluginId, onDone }: Props)

Source from the content-addressed store, hash-verified

62};
63
64export function PluginOptionsFlow({ plugin, pluginId, onDone }: Props): React.ReactNode {
65 // Build the step list once at mount. Re-calling after a save would drop the
66 // item we just configured.
67 const [steps] = React.useState<ConfigStep[]>(() => {
68 const result: ConfigStep[] = [];
69
70 // Top-level manifest.userConfig
71 const unconfigured = getUnconfiguredOptions(plugin);
72 if (Object.keys(unconfigured).length > 0) {
73 result.push({
74 key: 'top-level',
75 title: `Configure ${plugin.name}`,
76 subtitle: 'Plugin options',
77 schema: unconfigured,
78 load: () => loadPluginOptions(pluginId),
79 save: values => savePluginOptions(pluginId, values, plugin.manifest.userConfig!),
80 });
81 }
82
83 // Per-channel userConfig (assistant-mode channels)
84 const channels: UnconfiguredChannel[] = getUnconfiguredChannels(plugin);
85 for (const channel of channels) {
86 result.push({
87 key: `channel:${channel.server}`,
88 title: `Configure ${channel.displayName}`,
89 subtitle: `Plugin: ${plugin.name}`,
90 schema: channel.configSchema,
91 load: () => loadMcpServerUserConfig(pluginId, channel.server) ?? undefined,
92 save: values => saveMcpServerUserConfig(pluginId, channel.server, values, channel.configSchema),
93 });
94 }
95
96 return result;
97 });
98
99 const [index, setIndex] = React.useState(0);
100
101 // Latest-ref: lets the effect close over the current onDone without
102 // re-running when the parent re-renders.
103 const onDoneRef = React.useRef(onDone);
104 onDoneRef.current = onDone;
105
106 // Nothing to configure → tell the caller and render nothing. Effect,
107 // not inline call: calling setState in the parent during our render
108 // is a React rules-of-hooks violation.
109 React.useEffect(() => {
110 if (steps.length === 0) {
111 onDoneRef.current('skipped');
112 }
113 }, [steps.length]);
114
115 if (steps.length === 0) {
116 return null;
117 }
118
119 const current = steps[index]!;
120
121 function handleSave(values: PluginOptionValues): void {

Callers

nothing calls this directly

Calls 9

getUnconfiguredOptionsFunction · 0.85
savePluginOptionsFunction · 0.85
getUnconfiguredChannelsFunction · 0.85
loadMcpServerUserConfigFunction · 0.85
saveMcpServerUserConfigFunction · 0.85
loadMethod · 0.80
keysMethod · 0.65
onDoneFunction · 0.50
pushMethod · 0.45

Tested by

no test coverage detected