Wire Devtool
SkillAI & modelsWire an existing devtool package into host apps (LLD, LLM, web-tools) and optionally create bindings
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Wire Devtool skill
What this skill tells your AI
The instructions your AI receives, as published by ledgerhq/ledger-live in .agents/skills/wire-devtool/SKILL.md and read by ahel’s review.
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.
Signals
- GitHub stars
- 617
- Forks
- 491
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
wire-devtool- Source
- github.com/ledgerhq/ledger-live