import { startTransition, type ReactNode } from "react"; import type { Source, } from "@executor/react"; import { useSource, useSources, } from "@executor/react"; import { Alert, Button, SourceToolExplorer, parseSourceToolExplorerSearch, useSourcePluginNavigation, useSourcePluginRouteParams, useSourcePluginSearch, type SourceToolExplorerSearch, } from "@executor/react/plugins"; const LOCAL_TOOLS_SOURCE_KIND = "local-tools"; const localToolsSummary = (
File-backed tools loaded from .executor/tools. Restart the executor session after adding the first local tool so the source is provisioned.
); function LocalToolsSourceRoute(props: { children: (source: Source) => ReactNode; }) { const params = useSourcePluginRouteParams<{ sourceId?: string }>(); const sourceId = typeof params.sourceId === "string" ? params.sourceId : null; const source = useSource(sourceId ?? ""); if (sourceId === null || source.status === "error") { return (
This local tools source is unavailable.
); } if (source.status === "loading") { return (
Loading source...
); } if (source.data.kind !== LOCAL_TOOLS_SOURCE_KIND) { return (
Expected a local-tools source, but received {source.data.kind}.
); } return props.children(source.data); } function LocalToolsSourceDetailPage(props: { source: Source; }) { const navigation = useSourcePluginNavigation(); const search = parseSourceToolExplorerSearch( useSourcePluginSearch(), ) satisfies SourceToolExplorerSearch; const tab = search.tab === "discover" ? "discover" : "model"; const query = search.query ?? ""; return ( navigation.updateSearch({ tab: next.tab ?? tab, ...(next.tool !== undefined ? { tool: next.tool || undefined } : { tool: search.tool }), ...(next.query !== undefined ? { query: next.query || undefined } : { query }), })} summary={localToolsSummary} /> ); } export function LocalToolsAddPage() { const sources = useSources(); const navigation = useSourcePluginNavigation(); if (sources.status === "loading") { return (
Loading sources...
); } if (sources.status === "error") { return (
Failed loading sources.
); } const localToolsSource = sources.data.find( (source) => source.kind === LOCAL_TOOLS_SOURCE_KIND, ) ?? null; return (

Local Tools

File-backed tools from .executor/tools promoted into a first-class source.

The source is provisioned automatically when the executor session starts and finds local tool files in .executor/tools.

Existing tool path behavior is preserved, so a file like {" "}.executor/tools/demo.ts {" "}still appears as tools.demo(...).

{localToolsSource ? ( ) : ( No local tools source is active yet. Create a tool in {" "}.executor/tools {" "}and restart the executor session. )}
); } export function LocalToolsDetailRoute() { return ( {(source) => } ); }