Wire Devtool

SkillAI & models

Wire 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.

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

  1. Ask for the tool name if not already provided as an argument or in context.
  2. If devtools/<tool-name>/ does not exist, stop and tell the user to generate it first:
    pnpm --filter @devtools/registry add-tool
    
  3. If it exists, read only devtools/<tool-name>/src/types.ts to 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 LLDapps/ledger-live-desktop/src/mvvm/features/DevTools/screens/DevToolsScreen/useDevToolsScreenViewModel.ts In LLMapps/ledger-live-mobile/src/mvvm/features/DevTools/screens/DevToolsScreen/useDevToolsScreenViewModel.ts In web-toolsapps/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 as config.
// 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
618
Forks
490
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
wire-devtool
Source
github.com/ledgerhq/ledger-live