add-cyberbrick-sample
Automates the workflow for CyberBrick sample creation and maintenance, including index synchronization and multi-language translations.
Install
mkdir -p .claude/skills/add-cyberbrick-sample && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10183" && unzip -o skill.zip -d .claude/skills/add-cyberbrick-sample && rm skill.zipInstalls to .claude/skills/add-cyberbrick-sample
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
新增或更新 CyberBrick MicroPython 範例工作區的完整工作流程。當使用者提到新增範例、更新範例、add sample、update sample、修改範例積木、建立範例積木、新增 CyberBrick 示範程式、sample workspace、範例工作區、更新翻譯、stringTranslations、nameTranslations、字串翻譯、標籤翻譯 時自動啟用。包含從 Blockly 工作區匯出 JSON、建立或覆蓋範例檔、更新索引、15 語系翻譯填寫(含識別字名稱翻譯 nameTranslations 與 text 積木字串翻譯 stringTranslations)、本機驗證到推送上線的完整流程。Full workflow for adding or updating a CyberBrick MicroPython sample workspace: export Blockly JSON, create or overwrite sample file, update index, fill 15-language translations (nameTranslations for identifiers, stringTranslations for text labels), local validation, and push to production.Key capabilities
- →Export Blockly JSON from workspace
- →Create or overwrite sample JSON files
- →Update index.json metadata
- →Generate 15-language translations
- →Validate sample workspace structure
How it works
It automates the lifecycle of a sample workspace by validating the JSON structure, updating the index, and managing localized translations for identifiers and text.
Inputs & outputs
When to use add-cyberbrick-sample
- →Create a new robotics sample workspace
- →Update existing Blockly sample files
- →Translate sample labels and identifiers
- →Synchronize samples with the master index
About this skill
新增或更新 CyberBrick 範例工作區技能 Add / Update CyberBrick Sample Skill
在 media/samples/ 新增或更新一個合規的 CyberBrick MicroPython 範例工作區,並同步雲端索引 index.json,完成 15 語系本地化描述。
適用情境 When to Use
- 想新增 CyberBrick 專題範例(如巡線機器人、避障機器人)
- 想更新現有範例的積木內容或翻譯描述
- 驗證範例能被範例瀏覽器正確載入
架構背景 Architecture Context
media/samples/
├── index.json ← 雲端優先範例索引
├── cyberbrick-soccer-robot.json ← 既有範例
└── {新範例 id}.json ← 你將建立的檔案
雲端 URL(上線後生效):
https://raw.githubusercontent.com/Shen-Ming-Hong/singular-blockly/master/media/samples/index.json
https://raw.githubusercontent.com/Shen-Ming-Hong/singular-blockly/master/media/samples/{filename}
驗證規則(validateSampleWorkspace + validateSampleFilename):
filename必須是純 basename、不含路徑分隔符、副檔名必須是.json- 工作區 JSON 必須有非 null 的
workspace物件 board欄位必須是"cyberbrick"
15 個語系代碼 Locale Codes
en / zh-hant / ja / ko / de / fr / es / it / pt-br / ru / pl / cs / hu / bg / tr
工作流程 Workflow
Phase 0: 確認範例資訊 Gather Info
向使用者確認或自行決定以下資訊:
| 欄位 | 說明 | 範例 |
|---|---|---|
id | kebab-case 唯一識別碼 | cyberbrick-line-follower |
filename | 與 id 相同加 .json | cyberbrick-line-follower.json |
title | 各語系標題(en 必填) | "Line Follower" |
description | 各語系描述(en 必填) | "A workspace for line following." |
若使用者未提供翻譯,先以 i18n-maintenance 產生並審計可明確判斷的翻譯。en 必須非空;其他語系屬 optional fallback,不得只因缺少值而製造硬錯誤,但必須在完成摘要列出未提供語系。不得用空字串冒充已完成翻譯。
Phase 1: 取得工作區 JSON Get Workspace JSON
方法 A:使用者提供(推薦)
- 請使用者在 Extension Development Host 中:
- 切換至 CyberBrick 板子
- 拖出積木並建立範例程式
- 開啟 VS Code 指令面板 →
Singular Blockly: Open Blockly Editor - 確認工作區正確後,打開
blockly/main.json,複製全部內容
方法 B:讀取現有 main.json
# 從目前工作區取得
Get-Content -Path "blockly/main.json" -Raw
方法 C:以既有範例為基礎
# 複製既有範例並修改
Copy-Item media/samples/cyberbrick-soccer-robot.json media/samples/{new-filename}.json
Phase 2: 建立範例 JSON 檔 Create Sample File
建立 media/samples/{filename}.json,結構如下:
{
"workspace": {
/* Blockly 工作區序列化物件,來自 main.json */
},
"board": "cyberbrick"
}
⚠️ 必要規則:
board必須是字串"cyberbrick"(驗證函式強制檢查)workspace必須是物件(非 null、非陣列)filename不得包含/、\、..等路徑字元
若使用者提供的 main.json 已是完整的工作區 JSON(含 blocks、variables 等),則整個物件作為 workspace 的值。
Phase 2.5: Generate Name Translations 生成名稱翻譯映射
若範例工作區的積木中包含中文(繁體中文)函式名稱或變數名稱,必須在 {filename}.json 頂層加入 nameTranslations 欄位,讓非中文使用者載入範本時自動看到可讀的識別字(FR-003/FR-008)。
掃描策略 Scan Strategy
掃描範圍:全量掃描,不設排除規則
- 變數名稱:
workspace.variables[].name── 涵蓋全域變數與函式參數名稱 - 函式名稱:遞迴遍歷所有積木,找出
type === "arduino_function"的fields.NAME
// 掃描積木樹(Node 腳本範例)
function scanBlocks(blocks) {
if (!Array.isArray(blocks)) {
return;
}
for (const b of blocks) {
if (!b) {
continue;
}
if (b.type === 'arduino_function' && b.fields?.NAME) {
funcs.add(b.fields.NAME);
}
if (b.inputs) {
for (const k of Object.keys(b.inputs)) {
const inp = b.inputs[k];
if (inp?.block) {
scanBlocks([inp.block]);
}
if (inp?.shadow) {
scanBlocks([inp.shadow]);
}
}
}
if (b.next?.block) {
scanBlocks([b.next.block]);
}
}
}
scanBlocks(workspace.blocks.blocks);
14 個非 zh-hant 語系清單與翻譯格式
翻譯映射放在 nameTranslations.variables 與 nameTranslations.functions,
key 為原始中文名稱,value 為含以下 14 個語系的物件:
| 語系代碼 | 語言 | 語系代碼 | 語言 |
|---|---|---|---|
en | 英文(必填,作為回退) | ru | 俄文 |
ja | 日文 | pl | 波蘭文 |
ko | 韓文 | cs | 捷克文 |
de | 德文 | hu | 匈牙利文 |
fr | 法文 | bg | 保加利亞文 |
es | 西班牙文 | tr | 土耳其文 |
it | 義大利文 | pt-br | 葡萄牙文(巴西) |
完整格式範例:
"nameTranslations": {
"variables": {
"前後搖桿數值": {
"en": "joystick_forward_back",
"ja": "joystick_forward_back",
"ko": "joystick_forward_back",
"de": "joystick_vorwaerts_zurueck",
"fr": "joystick_avant_arriere",
"es": "joystick_adelante_atras",
"it": "joystick_avanti_indietro",
"pt-br": "joystick_frente_tras",
"ru": "joystick_vpered_nazad",
"pl": "joystick_przod_tyl",
"cs": "joystick_dopredu_dozadu",
"hu": "joystick_elore_hatra",
"bg": "joystick_napreed_nazad",
"tr": "joystick_ileri_geri"
}
},
"functions": {
"遙控器": {
"en": "controller",
"ja": "controller",
"ko": "controller",
"de": "fernsteuerung",
"fr": "telecommande",
"es": "controlador",
"it": "telecomando",
"pt-br": "controle",
"ru": "pult",
"pl": "kontroler",
"cs": "ovladac",
"hu": "taviranyito",
"bg": "distantsionno",
"tr": "uzaktan_kumanda"
}
}
}
識別字合法性規則 Identifier Validity Rules
每個翻譯值必須符合本專案的跨平台 ASCII 程式識別字規則:
- ✅ 以字母(
a-z、A-Z)或底線(_)開頭 - ✅ 後接字母、數字(
0-9)、底線 - ❌ 不含空格、連字號(
-)、標點符號(.、!、'…) - ❌ 不以數字開頭
- ❌ 不含重音字母(
é、ó、ü、ñ…),請用 ASCII 等效(e、o、u、n) - ❌ 不含 CJK 字元(中日韓文字),即使 Unicode 合法也不使用,確保跨平台相容性
驗證腳本:
const identRe = /^[A-Za-z_][A-Za-z0-9_]*$/;
for (const [key, entry] of Object.entries(nameTranslations.variables ?? {})) {
for (const [locale, val] of Object.entries(entry)) {
if (!identRe.test(val)) {
console.error(`INVALID variables["${key}"]["${locale}"] = "${val}"`);
}
}
}
Phase 2.5 驗證清單
- 所有
workspace.variables[].name均有對應的variables映射 - 所有
arduino_function.fields.NAME均有對應的functions映射 - 所有翻譯值通過
/^[A-Za-z_][A-Za-z0-9_]*$/識別字合法性驗證 -
en欄位已填(不允許空字串) - 若名稱為純 ASCII 英文(已是合法識別字),仍需填入
nameTranslations,以確保結構完整 - 若工作區完全無中文名稱:可省略
nameTranslations欄位(向後相容)
Phase 2.6: Generate String Translations 生成字串翻譯映射
若積木中有 text 類型積木(type === "text")的 fields.TEXT 包含中文字串(如 "前:", "按鈕:"),可加入 stringTranslations 欄位讓這些標籤在載入時自動顯示目標語系文字。
與
nameTranslations的差異:stringTranslations翻譯的是任意顯示字串,無識別字格式限制,值可包含冒號、空格、標點等任何字元,只要非空字串即合規。
掃描策略 Scan Strategy
遞迴遍歷所有積木,找出 type === "text" 且 fields.TEXT 為中文字串的積木:
// 掃描 text 積木(Node 腳本範例)
const textStrings = new Set();
function scanTextBlocks(blocks) {
if (!Array.isArray(blocks)) return;
for (const b of blocks) {
if (!b) continue;
if (b.type === 'text' && b.fields?.TEXT) {
const text = b.fields.TEXT;
// 只收集含有非 ASCII 字元(如中文)的字串
if (/[^\x00-\x7F]/.test(text)) {
textStrings.add(text);
}
}
if (b.inputs) {
for (const k of Object.keys(b.inputs)) {
const inp = b.inputs[k];
if (inp?.block) scanTextBlocks([inp.block]);
if (inp?.shadow) scanTextBlocks([inp.shadow]);
}
}
if (b.next?.block) scanTextBlocks([b.next.block]);
}
}
scanTextBlocks(workspace.blocks.blocks);
格式規則 Format Rules
stringTranslations為Record<string, Record<string, string>>- 外層 key:原始中文字串(zh-hant 基準,完整比對)
- 內層 key:14 個非 zh-hant 語系代碼
- 內層 value:任意非空字串,無識別字格式限制(可含冒號、空格等)
- zh-hant 不填入(載入時原始字串即為 zh-hant 顯示值)
完整格式範例:
"stringTranslations": {
"前:": {
"en": "Fwd:",
"ja": "前:",
"ko": "전:",
"de": "Vor:",
"fr": "Av:",
"es": "Adel:",
"it": "Avanti:",
"pt-br": "Frt:",
"ru": "Вп:",
"pl": "Prz:",
"cs": "Vpr:",
"hu": "Előre:",
"bg": "Напр:",
"tr": "İleri:"
},
"按鈕:": {
"en": "Btn:",
"ja": "ボタン:",
"ko": "버튼:",
"de": "Taste:",
"fr": "Btn:",
"es": "Btn:",
"it": "Btn:",
"pt-br": "Btn:",
"ru": "Кнп:",
"pl": "Przc:",
"cs": "Tl:",
"hu": "Gomb:",
"bg": "Копче:",
"tr": "Btn:"
}
}
三層回退策略 Fallback
- 目標語系的翻譯值(若非空字串)
- →
en翻譯值(若非空字串且目標非 en) - → 保留原始中文字串(向後相容)
Phase 2.6 驗證清單
- 所有中文
text積木字串均有對應的stringTranslations映射 - 所有 14 個非 zh-hant 語系均已填入(或至少
en已填) - 翻譯值為非空字串(可包含冒號、空格等,無識別字限制)
- 若工作區完全無中文 text 字串:可省略
stringTranslations欄位(向後相容)
Phase 3: 同步索引 Sync index.json
依照 Phase 0 判斷的模式執行:
ADD 模式:在 samples 陣列末尾新增條目
UPDATE metadata 模式:找到對應 id 的條目,只更新 title / description 欄位,保留其他欄位不變
# 確認目標 id 存在
$index = Get-Content media/samples/index.json | ConvertFrom-Json
$entry = $index.samples | Where-Object { $_.id -eq "{id}" }
if (-not $entry) { Write-Error "id '{id}' not found in index.json" }
UPDATE workspace 模式:直接跳過此步驟(index.json 無需異動)
ADD / UPDATE metadata 使用的完整條目格式:
在 media/samples/index.json 的 samples 陣列末尾新增條目(ADD),或直接更新對應條目的 title/description(UPDATE metadata):
{
"id": "{id}",
"filename": "{filename}",
"board": "cyberbrick",
"title": {
"en": "{英文標題}",
"zh-hant": "{繁體中文標題}",
"ja": "{日文標題}",
"ko": "{韓文標題}",
"de": "{德文標題}",
"fr": "{法文標題}",
"es": "{西班牙文標題}",
"it": "{義大利文標題}",
"pt-br": "{葡萄牙文(巴西)標題}",
"ru": "{俄文標題}",
"pl": "{波蘭文標題}",
"cs": "{捷克文標題}",
"hu": "{匈牙利文標題}",
"bg": "{保加利亞文標題}",
"tr": "{土耳其文標題}"
},
"description": {
"en": "{英文描述}",
"zh-hant": "{繁體中文描述}",
"ja": "{日文描述}",
"ko": "{韓文描述}",
"de": "{德文描述}",
"fr": "{法文描述}",
"es": "{西班牙文描述}",
"it": "{義大利文描述}",
"pt-br": "{葡萄牙文(巴西)描述}",
"ru": "{俄文描述}",
"pl": "{波蘭文描述}",
"cs": "{捷克文描述}",
"hu": "{匈牙利文描述}",
"bg": "{保加利亞文描述}",
"tr": "{土耳其文描述}"
}
}
💡
en必須存在且非空。尚未提供的其他 locale 應省略該 key,讓範例瀏覽器 fallback 到en;已提供的 locale 必須是通過語意審計的非空字串。
Phase 4: 本機驗證 Local Validation
4.1 JSON 格式驗證
# 驗證 index.json 格式合法
Get-Content media/samples/index.json | ConvertFrom-Json | Select-Object -ExpandProperty samples | Select-Object id, filename, board
# 驗證新範例 JSON 結構
$sample = G
---
*Content truncated.*
When not to use it
- →When the sample ID is not kebab-case
- →When the board type is not cyberbrick
Limitations
- →Requires board type to be cyberbrick
- →Requires kebab-case for IDs
How it compares
It provides a full-stack workflow including translation management and index synchronization, rather than just saving a file.
Compared to similar skills
add-cyberbrick-sample side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| add-cyberbrick-sample (this skill) | 0 | 4mo | Review | Intermediate |
| telegram-bot-builder | 106 | 6mo | Review | Intermediate |
| codex-cli-bridge | 9 | 9mo | Review | Intermediate |
| code-to-music | 17 | 10mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
telegram-bot-builder
davila7
Expert in building Telegram bots that solve real problems - from simple automation to complex AI-powered bots. Covers bot architecture, the Telegram Bot API, user experience, monetization strategies, and scaling bots to thousands of users. Use when: telegram bot, bot api, telegram automation, chat bot telegram, tg bot.
codex-cli-bridge
alirezarezvani
Bridge between Claude Code and OpenAI Codex CLI - generates AGENTS.md from CLAUDE.md, provides Codex CLI execution helpers, and enables seamless interoperability between both tools
code-to-music
Cam10001110101
Tools, patterns, and utilities for creating music with code. Output as a .mp3 file with realistic instrument sounds. Write custom compositions to bring creativity to life through music. This skill should be used whenever the user asks for music to be created. Never use this skill for replicating songs, beats, riffs, or other sensitive works. The skill is not suitable for vocal/lyrical music, audio mixing/mastering (reverb, EQ, compression), real-time MIDI playback, or professional studio recording quality.
jianying-editor
luoluoluo22
剪映 (JianYing) AI自动化剪辑的高级封装 API (JyWrapper)。提供开箱即用的 Python 接口,支持录屏、素材导入、字幕生成、Web 动效合成及项目导出。
manim
davila7
Comprehensive guide for Manim Community - Python framework for creating mathematical animations and educational videos with programmatic control
pdf-processing-pro
davila7
Production-ready PDF processing with forms, tables, OCR, validation, and batch operations. Use when working with complex PDF workflows in production environments, processing large volumes of PDFs, or requiring robust error handling and validation.