MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / ToolTree

Function ToolTree

packages/react/src/components/tool-tree.tsx:291–442  ·  view source on GitHub ↗
(props: {
  tools: readonly ToolSummary[];
  selectedToolId: string | null;
  onSelect: (toolId: string) => void;
  /** When provided, each row gets a hover-revealed action menu that
   *  applies (or clears) a user policy for that exact node. Leaf rows
   *  emit the tool's full dotted id; group rows emit `prefix.*`. */
  onSetPolicy?: (pattern: string, action: ToolPolicyAction) => void;
  onClearPolicy?: (pattern: string) => void;
  /** Maps the displayed row path into the persisted policy pattern. */
  patternForDisplay?: (displayPattern: string) => string;
  /** Sorted user-authored policies (most-precedent first). Used to
   *  decide whether a node has its own exact-pattern user rule today
   *  (so the menu can show a "Clear" option). Optional — when absent,
   *  the menu hides "Clear". */
  policies?: ReadonlyArray<{ readonly pattern: string; readonly action: ToolPolicyAction }>;
  /** When true, render top-level sections per (owner, connection) account, each
   *  badged with its owner (Personal / Workspace). The dotted-name tree renders
   *  beneath each section. The same tool name can appear under two accounts (NOT
   *  deduped). When false/unset, render one flat tree (unchanged). */
  groupByConnection?: boolean;
})

Source from the content-addressed store, hash-verified

289// ---------------------------------------------------------------------------
290
291export function ToolTree(props: {
292 tools: readonly ToolSummary[];
293 selectedToolId: string | null;
294 onSelect: (toolId: string) => void;
295 /** When provided, each row gets a hover-revealed action menu that
296 * applies (or clears) a user policy for that exact node. Leaf rows
297 * emit the tool's full dotted id; group rows emit `prefix.*`. */
298 onSetPolicy?: (pattern: string, action: ToolPolicyAction) => void;
299 onClearPolicy?: (pattern: string) => void;
300 /** Maps the displayed row path into the persisted policy pattern. */
301 patternForDisplay?: (displayPattern: string) => string;
302 /** Sorted user-authored policies (most-precedent first). Used to
303 * decide whether a node has its own exact-pattern user rule today
304 * (so the menu can show a "Clear" option). Optional — when absent,
305 * the menu hides "Clear". */
306 policies?: ReadonlyArray<{ readonly pattern: string; readonly action: ToolPolicyAction }>;
307 /** When true, render top-level sections per (owner, connection) account, each
308 * badged with its owner (Personal / Workspace). The dotted-name tree renders
309 * beneath each section. The same tool name can appear under two accounts (NOT
310 * deduped). When false/unset, render one flat tree (unchanged). */
311 groupByConnection?: boolean;
312}) {
313 const {
314 tools,
315 selectedToolId,
316 onSelect,
317 onSetPolicy,
318 onClearPolicy,
319 patternForDisplay = toPolicyPattern,
320 policies,
321 groupByConnection,
322 } = props;
323 const exactPatterns = useMemo(() => {
324 if (!policies) return new Map<string, ToolPolicyAction>();
325 const m = new Map<string, ToolPolicyAction>();
326 for (const p of policies) m.set(p.pattern, p.action);
327 return m;
328 }, [policies]);
329 const [search, setSearch] = useState("");
330 const searchRef = useRef<HTMLInputElement>(null);
331 const selectedRowRef = useRef<HTMLButtonElement>(null);
332 const ownerDisplay = useOwnerDisplay();
333
334 const terms = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
335
336 const filteredTools = useMemo(() => {
337 if (terms.length === 0) return tools;
338 return tools.filter((t) => {
339 const corpus = [t.name, t.description ?? ""].join(" ").toLowerCase();
340 return terms.every((term) => corpus.includes(term));
341 });
342 }, [tools, terms]);
343
344 // Account sections (only when grouping). Each carries its already-filtered
345 // tools so empty sections drop out under an active search.
346 const accountGroups = useMemo(
347 () => (groupByConnection ? buildAccountGroups(filteredTools) : []),
348 [groupByConnection, filteredTools],

Callers

nothing calls this directly

Calls 4

useOwnerDisplayFunction · 0.90
ownerLabelFunction · 0.90
buildAccountGroupsFunction · 0.85
setMethod · 0.80

Tested by

no test coverage detected