Wire Devtool
Reference: devtools/README.md.
Warning: bindings, protocols, registry, shell, transport, transport-panel, and wire are internal platform packages, not tools — do not wire them. feature-flags is an example of a real tool.
1. Identify the tool
- Ask for the tool name if not already provided as an argument or in context.
- If
devtools/<tool-name>/does not exist, stop and tell the user to generate it first:pnpm --filter @devtools/registry add-tool - If it exists, read only
devtools/<tool-name>/src/types.tsto determine whether the tool has props (file present = has props). Do not read anything else.
2. Ask where to wire
AskUserQuestion({
questions: [
{
question: "Which host apps should I wire this tool into?",
header: "Host wiring",
multiSelect: true,
options: [
{ label: "LLD", description: "apps/ledger-live-desktop" },
{ label: "LLM", description: "apps/ledger-live-mobile" },
{ label: "web-tools", description: "apps/web-tools" },
]
}
]
})
Stop here if the user selects none.
If the tool has props, check whether devtools/bindings/src/use<ToolName>ToolProps.ts already exists.
- If it exists, skip to step 4 and use it directly.
- If it does not exist, ask:
AskUserQuestion({
questions: [
{
question: "Should I create a bindings hook for this tool?",
header: "Bindings",
multiSelect: false,
options: [
{ label: "Yes", description: "Create use<ToolName>Props in @devtools/bindings and wire it into selected hosts." },
{ label: "No", description: "Skip bindings — wire with config: undefined for now." },
]
}
]
})
3. Create bindings (if requested)
Create devtools/bindings/src/use<ToolName>Props.ts — a hook that reads from the host's state and returns the tool's props type. Then re-export it from devtools/bindings/src/index.ts.
// devtools/bindings/src/useMyToolProps.ts
import type { MyToolProps } from "@devtools/my-tool";
export function useMyToolProps(): MyToolProps {
return {
// TODO: replace with real selectors
property: undefined,
};
}
4. Wire into host apps
In LLD — apps/ledger-live-desktop/src/mvvm/features/DevTools/screens/DevToolsScreen/useDevToolsScreenViewModel.ts
In LLM — apps/ledger-live-mobile/src/mvvm/features/DevTools/screens/DevToolsScreen/useDevToolsScreenViewModel.ts
In web-tools — apps/web-tools/src/pages/dev-tools.tsx
The host never imports from @devtools/<tool> directly and never needs a workspace dependency on the tool package. The props type is already part of DevToolsConfig (from @devtools/shell → @devtools/registry), so TypeScript infers the correct config type from the id alone.
- Propless tool: add the entry with
config: undefined. No import, no hook, no dep. - Tool with props: import the bindings hook from
@devtools/bindings, call it, pass the result asconfig.
// propless
{ id: "my-tool", config: undefined }
// with props — only import is from @devtools/bindings
import { useMyToolProps } from "@devtools/bindings";
const myToolProps = useMyToolProps();
{ id: "my-tool", config: myToolProps }
Add the entry to the config array:
const config: DevToolsConfig = useMemo(
() => [
{ id: "feature-flags", config: featureFlagsProps },
{ id: "my-tool", config: myToolProps }, // or config: undefined
],
[featureFlagsProps, myToolProps],
);
5. Done
Suggest the user opens DevTools in the app to verify the tool appears.