Agent skill

Library Migration Guide

by ailyProject in ailyProject/aily-blockly

Complete guide for converting Arduino/ESP32 hardware libraries into Aily Blockly compatible format.

GPL-3.0Auto-check passedDevelopment

Install Library Migration Guide

skills CLI
$ npx skills add ailyProject/aily-blockly --skill library-migration-guide -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ailyProject/aily-blockly library-migration-guide --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ailyProject/aily-blockly.git skills-src && mkdir -p .claude/skills && cp -r skills-src/public/skills/library-migration-guide .claude/skills/library-migration-guide && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
library-migration-guide
GitHub stars
3.8k
Token cost
~3.1k tokens
SKILL.md length
836 words
Files
2
Skills in repo
6
Repo updated
First seen
Licence
GPL-3.0

At a glance

Complete guide for converting Arduino/ESP32 hardware libraries into Aily Blockly compatible format.

  • Works in 2 steps: Use the existing environment/project… → If no project exists, use project with…
  • Tasks that involve Embedded systems
  • SKILL.md covers Conversion Workflow, Detailed Code Specification, Block Design Rules and Code Generation Rules, plus 4 more sections
  • Calls npm; reaches blockly.diandeng.tech

What it does

Library Migration Guide is an agent skill from ailyProject/aily-blockly. Complete guide for converting Arduino/ESP32 hardware libraries into Aily Blockly compatible format. Covers the full workflow: source analysis, block.json design, generator.js implementation, toolbox.json configuration, bus initialization (Serial/I2C/SPI), board adaptation, and packaging.

Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `Blockly_Library_CODE_Conventions.md`).

It sits in Development, covering Embedded systems and Code migrations. It works with ESP32 and npm. The repository describes itself as: AI IDE for hardware development, support Arduino, MicroPython, ESP32, STM32, RP2040, Nrf5x... The licence is GPL-3.0.

When your agent uses it

  • Tasks that involve Embedded systems
  • Tasks that involve Code migrations

Example prompts

  • “/library-migration-guide”

Requirements

  • Node.js

Workflow steps

2 steps, taken from the first numbered list in SKILL.md.

  1. Use the existing environment/project context first to determine whether a project is already open.
  2. If no project exists, use project with action="create" to create one, then continue with the new project path.

What it can do on your machine

Read from SKILL.md and the folder at commit 4aace5a. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • blockly.diandeng.tech

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Library Migration Guide loads about 3.1k tokens when it runs. Until then it costs about 78 tokens; SKILL.md has 836 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~78
When it runs · the whole SKILL.md, loaded when a task matches
~3.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from ailyProject/aily-blockly at commit 4aace5a, republished under its GPL-3.0 licence (© ailyProject). 836 words, ~3,137 tokens.

Download SKILL.mdSave it as .claude/skills/library-migration-guide/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
library-migration-guide
description
Complete guide for converting Arduino/ESP32 hardware libraries into Aily Blockly compatible format. Covers the full workflow: source analysis, block.json design, generator.js implementation, toolbox.json configuration, bus initialization (Serial/I2C/SPI), board adaptation, and packaging.
metadata.version
4.0.0
metadata.author
aily-team
metadata.scope
global
metadata.agents
mainAgent
metadata.auto-activate
false
metadata.tags
library,migration,conversion,block-json,generator,serial,i2c,spi,board-config

Blockly Library Conversion Guide

A systematic guide for converting Arduino libraries into Aily Blockly libraries, based on real conversion cases (ArduinoJson, OneButton, MQTT/PubSubClient, DHT, INA219, VL53L0X, etc.).

Conversion Workflow

Prerequisites
  1. Use the existing environment/project context first to determine whether a project is already open.
  2. If no project exists, use project with action="create" to create one, then continue with the new project path.
⚠️ CRITICAL: Library Working Directory

All library files MUST be created in <projectPath>/<library-name>/, NOT in node_modules/.

  • ✅ Correct: <projectPath>/lib-grove_motor/block.json
  • ❌ Wrong: <projectPath>/node_modules/@aily-project/lib-grove_motor/block.json

The node_modules/ directory is managed by npm and is write-protected. After creating the library locally, install it with: npm install ./<library-name>

If a file write operation returns a path/permission error, check your target path — you are likely writing to node_modules/ instead of <projectPath>/<library-name>/. Fix the path and retry. Do NOT attempt to bypass by using terminal commands (mkdir, echo, Out-File, etc.) to write into protected directories.

Step-by-step Process
  1. Source Analysis: Analyze the Arduino library header files to identify public APIs. Classify by operation type: initialization, connection, communication, status, maintenance, quick operations.

  2. Block Design: Design user-friendly blocks following block type mapping rules (see Section "Block Design Rules" below).

  3. Create Library Files in <projectPath>/<library-name>/:

    • block.json — Block definitions
    • generator.js — Code generator
    • toolbox.json — Toolbox configuration
    • package.json — Library metadata
  4. Copy Source Files: Use run_terminal to copy the Arduino source:

    • If src/ folder exists → copy to <projectPath>/<library-name>/src/<library-name>/
    • If no src/ folder → copy .c, .cpp, .h, .hpp files to <projectPath>/<library-name>/src/<library-name>/
  5. Write README.md: First read Blockly_Library_README_Conventions.md (fetch from https://blockly.diandeng.tech/files/Blockly_Library_README_Conventions.md), then follow its format.

  6. Post-conversion: Ask the user if they need help with:

    • Installing: npm i <library-path> (must specify the local library path)
    • Testing the converted library
    • Opening the library folder location
Library Directory Structure
library-name/
├─ block.json        // Block definitions
├─ generator.js      // Code generator
├─ toolbox.json      // Toolbox configuration
├─ package.json      // Library metadata
├─ README.md         // Human-readable documentation
├─ README_AI.md      // LLM-readable documentation
└─ src/
   └─ library-name/  // Copied Arduino source files

Detailed Code Specification

IMPORTANT: For complete code specification with detailed examples, read the companion file Blockly_Library_CODE_Conventions.md located in this skill's folder. It covers:

  • Full block.json design rules with templates for every block type
  • Complete generator.js implementation patterns with real-world examples
  • toolbox.json shadow blocks and organization
  • package.json configuration with board compatibility
  • Board adaptation patterns and WiFi library selection

The sections below summarize the critical rules that MUST be followed.


Block Design Rules

Block Type Mapping
Arduino PatternBlock TypeConnectionField Type
Object creation/initStatementprev/nextfield_input (user enters new var name)
Global object methodStatementprev/nextNo variable field (direct call)
Object method callStatementprev/nextfield_variable (select existing var)
Global object queryValueoutputNo variable field
Quick operationStatement/ValuestandardNo variable field, direct params
Event callbackHat blockNo prev/nextfield_variable + input_statement
Conditional callbackHybridprev/nextinput_value + input_statement
Status queryValueoutputfield_variable
field_input vs field_variable
  • field_input: For initialization blocks — user enters a NEW variable name
  • field_variable: For method call blocks — user selects an EXISTING variable (set variableTypes and defaultType)
  • Global objects (Serial, WiFi, Wire, SPI, httpUpdate, SPIFFS, ESP, EEPROM): No variable field needed
Reading Variable Names in generator.js
javascript
// field_input
const varName = block.getFieldValue('VAR') || 'defaultVar';

// field_variable
const varField = block.getField('VAR');
const varName = varField ? varField.getText() : 'defaultVar';

// Global object — use directly
const serialPort = block.getFieldValue('SERIAL') || 'Serial';
Board Config Template Variables (block.json)

Use these in field_dropdown options — auto-populated at runtime:

VariableUsage
${board.i2c}I2C interface list (Wire selector)
${board.digitalPins}Digital pin list
${board.analogPins}Analog pin list
${board.serialPort}Serial port list
${board.serialSpeed}Baud rate list
${board.interruptPins}Interrupt pin list
${board.interruptMode}Interrupt mode list
Show full SKILL.md (314 more words)Show less
Extensions

Register dynamic extensions in generator.js. Always unregister before registering:

javascript
if (Blockly.Extensions.isRegistered('ext_name')) {
  Blockly.Extensions.unregister('ext_name');
}
Blockly.Extensions.register('ext_name', function() { /* ... */ });

Code Generation Rules

Injection Methods & Execution Order

All injection methods take (tag, code) and auto-deduplicate by tag.

cpp
#include <Lib.h>        // addLibrary(tag, code)
#define MACRO val        // addMacro(tag, code)

Type globalVar;          // addVariable(tag, code)
MyClass obj;             // addObject(tag, code)
void helper() {}         // addFunction(tag, code, isGlobal?)

void setup() {
  Serial.begin(9600);    // addSetupBegin — bus-level init ONLY
  sensor.begin();        // addSetup — device/sensor init
  attachCb(handler);     // addSetupEnd — callbacks, depends on prior init
}

void loop() {
  btn.tick();            // addLoopBegin — polling/tick calls
  // [user blocks here]
}
Bus Initialization (MANDATORY)

Serial — Always use ensureSerialBegin(), NEVER write Serial.begin() directly:

javascript
// ✅ Correct
ensureSerialBegin('Serial', generator);           // default 9600
ensureSerialBegin('Serial', generator, 115200);   // custom baud
ensureSerialBegin(serialPort, generator, baud);   // dynamic

// ❌ FORBIDDEN
generator.addSetupBegin('serial_begin', 'Serial.begin(9600);');

I2C — Use wire_${wireName}_begin key for deduplication:

javascript
const wire = block.getFieldValue('WIRE') || 'Wire';
generator.addLibrary('Wire', '#include <Wire.h>');
const wireBeginKey = `wire_${wire}_begin`;
if (!generator.setupCodes_ || !generator.setupCodes_[wireBeginKey]) {
  generator.addSetup(wireBeginKey, wire + '.begin();\n');
}

SPI — Use spi_${spiName}_begin key for deduplication:

javascript
const spi = block.getFieldValue('SPI') || 'SPI';
generator.addLibrary('SPI', '#include <SPI.h>');
generator.addSetup(`spi_${spi}_begin`, spi + '.begin();\n');
Variable Management

Initialization blocks with field_input MUST implement a rename listener:

javascript
if (!block._varMonitorAttached) {
  block._varMonitorAttached = true;
  block._varLastName = block.getFieldValue('VAR') || 'defaultVar';
  registerVariableToBlockly(block._varLastName, 'VarType');
  const varField = block.getField('VAR');
  if (varField) {
    const orig = varField.onFinishEditing_;
    varField.onFinishEditing_ = function(newName) {
      if (typeof orig === 'function') orig.call(this, newName);
      const ws = block.workspace || Blockly.getMainWorkspace?.();
      const oldName = block._varLastName;
      if (ws && newName && newName !== oldName) {
        renameVariableInBlockly(block, oldName, newName, 'VarType');
        block._varLastName = newName;
      }
    };
  }
}
Generator Return Values
  • Statement blocks: return 'code;\n';
  • Value blocks: return [expr, generator.ORDER_ATOMIC];
  • Hat / event blocks: return ''; (empty string — event-driven, not in main flow)
  • Hybrid blocks: return 'conditional_code;\n'; (returned code runs inside parent callback)
valueToCode & ORDER Constants
javascript
// Extract input value (most cases use ORDER_ATOMIC)
const val = generator.valueToCode(block, 'INPUT', generator.ORDER_ATOMIC) || '0';

// Return value block
return [varName + '.read()', generator.ORDER_FUNCTION_CALL];
Board Adaptation

Access runtime board config via window['boardConfig']:

javascript
const boardConfig = window['boardConfig'];
// boardConfig.core — e.g. 'esp32:esp32', 'arduino:avr'
// boardConfig.name — board display name
// boardConfig.i2c — I2C interface list
// boardConfig.digitalPins — digital pin list

NEVER modify window['boardConfig'] directly — use independent storage like window['customXxx'].


toolbox.json Rules

All input_value slots MUST have shadow blocks:

json
{
  "kind": "block",
  "type": "sensor_read",
  "inputs": {
    "TIMEOUT": {"shadow": {"type": "math_number", "fields": {"NUM": 1000}}}
  }
}

Organize blocks by user cognitive flow using label separators:

json
{
  "kind": "category",
  "name": "SensorLib",
  "contents": [
    {"kind": "label", "text": "Setup"},
    {"kind": "block", "type": "sensor_init"},
    {"kind": "label", "text": "Read Data"},
    {"kind": "block", "type": "sensor_read"}
  ]
}

package.json Configuration

json
{
  "name": "@aily-project/lib-libname",
  "nickname": "Display Name",
  "description": "Brief description (<50 chars)",
  "version": "1.0.0",
  "compatibility": {
    "core": [],
    "voltage": [3.3, 5]
  },
  "keywords": ["aily", "blockly"],
  "tested": true,
  "url": "original library URL"
}

Board compatibility shorthand:

  • Universal: "core": [] (empty array = all boards)
  • ESP32 only: "core": ["esp32:esp32"]
  • Classic Arduino: "core": ["arduino:avr", "arduino:megaavr"]
  • IoT boards: "core": ["esp32:esp32", "esp8266:esp8266", "renesas_uno:unor4wifi"]

Common Anti-patterns

❌ Wrong✅ Correct
Write Serial.begin() directlyUse ensureSerialBegin(port, generator)
Hardcoded Wire key 'WIRE_BEGIN'Use wire_${wireName}_begin formatted key
Modify window['boardConfig']Use window['customXxx'] for custom storage
addSetupBegin for sensor initaddSetupBegin is bus-only; use addSetup for sensors
No shadow blocks for input_valueAlways configure shadow blocks in toolbox.json
Extension register without unregisterAlways unregister() before register()
addFunction without 3rd paramPass true when helper function must be globally visible
Skip ensureSerialBegin in quick opsQuick operations using Serial.println need it too

Quality Checklist

  • Covers 80%+ core features of the original library
  • New users can get started within 10 minutes
  • Common tasks complete in ≤ 3 steps
  • Generated code compiles 100%
  • Supports target development boards
  • All input_value have shadow blocks in toolbox.json
  • Serial init uses ensureSerialBegin()
  • I2C init uses wire_${wire}_begin key deduplication
  • SPI init uses spi_${spi}_begin key deduplication
  • addSetupBegin only used for bus-level initialization
  • Extensions unregister before register
  • Never directly modifies window['boardConfig']
  • Variable rename listener implemented on field_input blocks

© ailyProject, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in public/skills/library-migration-guide of ailyProject/aily-blockly.

  • SKILL.md
  • Blockly_Library_CODE_Conventions.md

Open the folder on GitHubat commit 4aace5a

Compare with similar skills

Library Migration Guide next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Library Migration Guide compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Library Migration Guide this skillailyProject/aily-blockly3.8k—~3.1kAutomated safety check: PassGPL-3.0
Migrate Internal Package into GhostTryGhost/Ghost56k—~3.8kAutomated safety check: PassMIT
Next Upgradevercel-labs/openreview1.7k6 repos~502Automated safety check: PassNone
RuView Hardware Setupruvnet/RuView97k—~1.8kAutomated safety check: NotesMIT
Esp32 Firmware Engineeralxv2016/folloup-sticky1161 repos~3.8kAutomated safety check: PassGPL-3.0
RuView mmWave Radar Setupruvnet/RuView97k—~907Automated safety check: NotesMIT

Similar skills

  • Moves a package from another TryGhost repository into Ghost as an internal workspace package while keeping its Git history, with checkpoints for the steps that need an administrator.

    56k GitHub stars~3.8k tokensUpdated today
    DevelopmentAuto-check passed
  • Next Upgrade

    vercel-labs/openreview

    Official

    Upgrade Next.js to the latest version following official migration guides and codemods

    1.7k GitHub starsUsed in 6 repos~502 tokens
    DevelopmentAuto-check passed
  • Brings a RuView CSI sensing node online by building ESP32-S3 or ESP32-C6 firmware, flashing the board, provisioning WiFi and checking the serial output.

    97k GitHub stars~1.8k tokensUpdated today
    DevelopmentAuto-check: notes
  • Esp32 Firmware Engineer

    alxv2016/folloup-sticky

    ESP32 firmware engineering for ESP-IDF projects. An agent skill from alxv2016/folloup-sticky.

    116 GitHub starsUsed in 1 repo~3.8k tokens
    DevelopmentAuto-check passed
  • Sets up and runs 60 GHz and 24 GHz mmWave radar sensing on ESP32 boards in RuView, alone or fused with WiFi CSI.

    97k GitHub stars~907 tokensUpdated today
    DevelopmentAuto-check: notes
  • Embedded Debug

    FastLED/FastLED

    Firmware crash analysis, stack trace decoder, and register dump interpreter for ESP32/ARM/AVR platforms.

    7.5k GitHub stars~1.4k tokensUpdated today
    DevelopmentAuto-check passed

More from ailyProject/aily-blockly

  • Abs Syntax Reference

    ailyProject/aily-blockly

    ABS 语法快速参考:权威 ABS 规则与示例 skill,覆盖块连接类型、参数顺序、语句输入、变量引用与常见示例。触发词:ABS、语法、块脚本

    3.8k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Blockly Best Practices

    ailyProject/aily-blockly

    Aily Blockly implementation workflow for scoped library evidence, ABS editing, workspace synchronization, and focused validation.

    3.8k GitHub stars~962 tokensUpdated today
    Auto-check passed
  • Chronicle

    ailyProject/aily-blockly

    Analyze indexed Aily chat session history for prior decisions, tool executions, project summaries, usage tips, and session-store reindexing.

    3.8k GitHub stars~1.6k tokensUpdated today
    Auto-check passed
  • Blockly Project Planning

    ailyProject/aily-blockly

    Blockly project planning and creation workflow for no-project hardware requests.

    3.8k GitHub stars~630 tokensUpdated today
    Auto-check passed
  • Review

    ailyProject/aily-blockly

    Review uncommitted code changes

    3.8k GitHub starsUsed in 1 repo~274 tokens
    Auto-check passed

Works with

Categories

Questions about Library Migration Guide

What does Library Migration Guide do?

Complete guide for converting Arduino/ESP32 hardware libraries into Aily Blockly compatible format. Library Migration Guide is an agent skill from ailyProject/aily-blockly. Complete guide for converting Arduino/ESP32 hardware libraries into Aily Blockly compatible format.

When should I use Library Migration Guide?

Library Migration Guide fits situations like: tasks that involve Embedded systems; tasks that involve Code migrations.

How do I install Library Migration Guide in Claude Code?

Run `npx skills add ailyProject/aily-blockly --skill library-migration-guide -a claude-code`. Or copy the skill folder (public/skills/library-migration-guide in ailyProject/aily-blockly) into .claude/skills/library-migration-guide in your project. Claude Code loads it when a task matches its description.

How do I install Library Migration Guide in Codex?

Run `npx skills add ailyProject/aily-blockly --skill library-migration-guide -a codex`. Or copy the skill folder (public/skills/library-migration-guide in ailyProject/aily-blockly) into .agents/skills/library-migration-guide in your project. Codex loads it when a task matches its description.

Can I use Library Migration Guide in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ailyProject/aily-blockly --skill library-migration-guide -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/library-migration-guide, .gemini/skills/library-migration-guide, .github/skills/library-migration-guide and .opencode/skills/library-migration-guide in your project.

What does Library Migration Guide need to run?

Going by SKILL.md and its folder, Library Migration Guide needs the command-line tools its instructions call (npm). Our summary lists: Node.js.

Does Library Migration Guide access the network?

SKILL.md names 1 domain. In commands or code: blockly.diandeng.tech; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is Library Migration Guide safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Library Migration Guide use?

Library Migration Guide is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Library Migration Guide use?

About 3.1k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Library Migration Guide?

Skills that share tags, products or a category with Library Migration Guide: Migrate Internal Package into Ghost (TryGhost/Ghost, 56k stars), Next Upgrade (vercel-labs/openreview, 1.7k stars), RuView Hardware Setup (ruvnet/RuView, 97k stars) and Esp32 Firmware Engineer (alxv2016/folloup-sticky, 116 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Library Migration Guide?

ailyProject (a GitHub organization) maintains it in ailyProject/aily-blockly, which has 3,834 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 9, 2026.

Source: ailyProject/aily-blockly on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.