一键导入
upy-diagram
第七步——软件架构图生成。读取 firmware/ 代码和 project-manifest.json,LLM 生成中间 JSON,脚本渲染 Mermaid 文本架构图(.md 代码块,CLI 原生可读)+ SVG + PNG + HTML(双击浏览器可看)。触发:upy-generate 完成后。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
第七步——软件架构图生成。读取 firmware/ 代码和 project-manifest.json,LLM 生成中间 JSON,脚本渲染 Mermaid 文本架构图(.md 代码块,CLI 原生可读)+ SVG + PNG + HTML(双击浏览器可看)。触发:upy-generate 完成后。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | upy-diagram |
| description | 第七步——软件架构图生成。读取 firmware/ 代码和 project-manifest.json,LLM 生成中间 JSON,脚本渲染 Mermaid 文本架构图(.md 代码块,CLI 原生可读)+ SVG + PNG + HTML(双击浏览器可看)。触发:upy-generate 完成后。 |
给定 project-manifest.json(phase: generate)和 firmware/ 下所有 .py 文件,LLM 理解 diagram.schema.json 后分析代码结构、执行流程、数据流向,填入中间 JSON,再由脚本校验并生成 Mermaid 文本图(Markdown 代码块)+ SVG + PNG + HTML。Mermaid .md + SVG + PNG + HTML 均为必需输出,脚本默认 --format all。LLM 负责阅读代码并填写 JSON,脚本只做校验和渲染。
python --version
python -c "import jsonschema; print('jsonschema OK')"
缺失则提示安装:pip install jsonschema
SVG 渲染需要网络(mermaid.ink API,零本地依赖),详见 Step 6。
在执行任何分析之前,先询问用户需要的架构图复杂度。 复杂度控制下面所有约束参数的上限,影响图的精简程度。
AskUserQuestion(
questions=[{
"question": "架构图需要哪种复杂度?",
"header": "架构图复杂度",
"options": [
{"label": "简单", "description": "高度精简,只保留核心模块/依赖/步骤,适合快速浏览"},
{"label": "中等 (推荐)", "description": "平衡信息量和可读性,适合日常开发和沟通"},
{"label": "详细", "description": "完整展开,模块/步骤/数据流全部保留,适合复杂项目或归档文档"}
],
"multiSelect": False
}]
)
参数对照表(LLM 以选中档位为约束上限):
| 参数 | 简单 | 中等(默认) | 详细 |
|---|---|---|---|
architecture 总模块数 | ≤6 | ≤10 | ≤16 |
| 每层模块上限 | ≤2 | ≤4 | ≤6 |
cross_layer_deps 总边数 | ≤6 | ≤12 | ≤20 |
cross_layer_deps[].label | ≤4 字 | ≤6 字 | ≤10 字 |
role | ≤8 字 | ≤10 字 | ≤14 字 |
flow[] 总步数 | ≤5 | ≤8 | ≤14 |
flow[].action | ≤4 字 | ≤6 字 | ≤8 字 |
flow[].detail | ≤8 字 | ≤12 字 | ≤16 字 |
data_flow[] 总边数 | ≤2 | ≤4 | ≤8 |
data_flow[].data | ≤6 字 | ≤8 字 | ≤12 字 |
选择后 LLM 严格按对应栏位的数值作为上限,Step 3 中所有约束描述均以选中档位为准。默认:中等。
读取中间 JSON schema:
G:/MicroPython_Skills/upy-project-gen-toolchain-spec/diagram.schema.json
理解 4 个必需字段:meta, architecture, flow, data_flow,以及可选字段 task_registry, diagnostics。
读取以下所有文件(每个文件必须通读):
{project_dir}/project-manifest.json
{project_dir}/firmware/main.py ← 入口:DI 装配链 + 流程步骤
{project_dir}/firmware/conf.py ← 配置常量
{project_dir}/firmware/board.py ← 板级 pin 常量映射
{project_dir}/firmware/boot.py ← 启动代码
{project_dir}/firmware/lib/ ← 基础库(logger/scheduler/time_helper 等)
{project_dir}/firmware/drivers/ ← 驱动工厂 + mock(每个 driver 一个包)
{project_dir}/firmware/tasks/ ← 业务 task 文件
meta — 元数据从 manifest 提取:project, mode, mcu, source_phase。
generated_at 填当前 UTC 时间(ISO 8601)。
architecture.layers[] — 分层架构层定义(自下而上):
| 层 ID | label | 包含哪些模块 |
|---|---|---|
board | 板级层(Board) | board.py — pin 常量映射 |
lib | 基础库(Library) | lib/ 下所有 .py:logger, scheduler, time_helper 等 |
driver | 驱动层(Driver) | drivers/<name>_driver/__init__.py — 各器件工厂 |
task | 任务层(Task) | tasks/*.py — 业务 task 函数 |
entry | 入口层(Entry) | main.py — DI 装配入口 |
test | 测试层(Test) | test/pc/*.py — PC 端测试;test/device/*.py — 设备端测试 |
可选附加层:host(host/ 下有代码时)。
每个 module 对象:
name:Python import 路径,如 tasks.sensor_taskpath:相对文件路径,如 firmware/tasks/sensor_task.pyrole:模块职责的中文简述,上限以 Step 0 所选档位为准(从 docstring 首行提取,无 docstring 则 LLM 补写。节点框宽度有限,过长文本会导致节点膨胀、布局拥挤)provides:导出的函数名/类名列表(从 def / class 提取,排除 _ 前缀的私有符号)depends_on:依赖的模块名列表(从 import / from X import 提取,排除 machine 和标准库)depends_on_machine:是否直接 import machine(true 仅 main.py)has_mock:drivers/<name>_driver/mock.py 是否存在is_generated:文件是否由 upy-generate 生成(@Generated : upy-generate 标记)is_template:文件是否来自 scaffold 模板source:来源枚举(scaffold_template / llm_generated / upypi_download / github_download / cold_driver / user_custom)LLM 自主决定:
cross_layer_deps[].label:边标签上限以 Step 0 所选档位为准(如 "导入"、"注入"、"日志";过长的边标签会使连线拥挤难以辨认)cross_layer_deps[].style:solid(直接依赖)/ dashed(DI 注入依赖)/ dotted(测试依赖)flow[] — 执行流程从 main.py 提取执行步骤序列,每一步:
seq:从 1 开始的序号phase:步骤阶段
boot → 启动延时、WDT 设置init → I2C/SPI 总线初始化、日志初始化scan → I2C 器件扫描(scan_xxx_i2c())create → 驱动实例创建(create_xxx())assembly → DI 装配(驱动注入 task)run → 调度器启动 / 事件循环运行shutdown → 清理(如存在)action:中文简短标题,上限以 Step 0 所选档位为准(如 "初始化 I2C";时序图参与者宽度有限,过长文本会被截断)detail:具体参数,上限以 Step 0 所选档位为准(I2C 地址、Pin 脚号、频率等;会在 action 下方折行显示)source_line:在 main.py 中的行号depends_on_step:前置步骤 seq(如 create 依赖 scan 成功)on_error:失败策略(fatal 终止 / skip_device 跳过该器件继续 / retry 重试 / degrade 降级运行)is_conditional + branches:条件分支(如 scan 成功→create,失败→skip)LLM 自主决定: 步骤粒度(一个 init 动作可拆成多步或合并),总步骤数以 Step 0 所选档位为上限(合并相似操作,不要每个函数调用都单独一步);条件分支的细节。
data_flow[] — 数据流分析 task 函数之间的数据传递:
from / to:数据来源和去向(模块名或函数名)data:传递的数据描述,上限以 Step 0 所选档位为准(如 "温湿度读数"、"报警状态")channel:传输通道
shared_dict → 通过共享 dict 传递(如 data["temp"] = ...)function_return → 函数返回值传递global_var → 全局变量queue → 通过 Queue 传递(async 模式)callback_param → 回调函数参数rate:刷新频率(如 1Hz、on_change、100ms)LLM 自主决定: data_flow 的粒度(可合并同类型流或逐条列出),总边数以 Step 0 所选档位为上限(只保留核心数据流,过于细节或单向无分支的流省略)。
task_registry[] — 任务注册清单从 main.py 提取调度器注册信息(timer 模式从 sc.register() 提取,async 模式从 asyncio.create_task() 提取):
name:任务名callback:回调函数名interval_ms:执行间隔mode:periodic / once / on_eventdiagnostics — 诊断信息LLM 分析代码后填写:
total_modules:architecture 中的模块总数total_dependencies:depends_on 的依赖边总数max_depth:依赖图最大深度(从 entry 向下数)circular_deps:检测到的循环依赖(应为空数组)orphan_modules:未被任何模块依赖的模块(如纯工具函数)machine_direct_access:直接 import machine 的模块(除 main.py 外应警告)python G:/MicroPython_Skills/upy-project-gen-toolchain-spec/scripts/validate_json.py \
--schema G:/MicroPython_Skills/upy-project-gen-toolchain-spec/diagram.schema.json \
--json {project_dir}/docs/diagram.json
校验失败 → 修改 diagram.json → 重新校验,直到 pass。
这是本 skill 的主要输出。 脚本从 diagram.json 生成 3 个 Markdown 文件(内含 Mermaid 代码块)+ 3 个 SVG + 3 个 PNG + 3 个 HTML。CLI 直接可读,VS Code / GitHub 原生渲染,HTML 双击浏览器即看。
python G:/MicroPython_Skills/upy-diagram/scripts/render_diagram_local.py \
--input {project_dir}/docs/diagram.json \
--output {project_dir}/docs/
脚本默认 --format all,同时输出 .md、.svg、.png 和 .html:
| 文件 | Mermaid 图类型 | 内容 |
|---|---|---|
docs/architecture.md + .svg + .png + .html | graph TB | 分层架构图:subgraph 按层分组,节点=模块,边=依赖 |
docs/flowchart.md + .svg + .png + .html | sequenceDiagram | 执行流程图:MCU 参与者,按 phase 分组,条件分支 + 错误处理 |
docs/data_flow.md + .svg + .png + .html | graph LR | 数据流图:模块间数据通道,不同类型箭头表示不同 channel |
SVG 通过 mermaid.ink API 渲染(零本地依赖,需要网络),矢量格式清晰不模糊。
脚本默认使用 mermaid.ink API 渲染 SVG(零本地依赖,需要网络):
# 仅 SVG(跳过 .md 重写):
python G:/MicroPython_Skills/upy-diagram/scripts/render_diagram_local.py \
--input {project_dir}/docs/diagram.json \
--output {project_dir}/docs/ \
--format svg
原理:Mermaid 代码 Base64 编码 → GET https://mermaid.ink/img/{base64}?type=svg → 保存 SVG。
HTML 使用 Mermaid.js CDN 直接在浏览器中渲染,与 mermaid.ink 无关。
备选方案 — PNG(mermaid.ink 同样支持):
python G:/MicroPython_Skills/upy-diagram/scripts/render_diagram_local.py \
--input {project_dir}/docs/diagram.json \
--output {project_dir}/docs/ \
--format png
备选方案 — mermaid-cli(本地渲染,需要 Node.js):
npm install -g @mermaid-js/mermaid-cli
python G:/MicroPython_Skills/upy-diagram/scripts/render_diagram_local.py \
--input {project_dir}/docs/diagram.json \
--output {project_dir}/docs/ \
--format png-local
cd {project_dir} && python -c "
import json, os
from datetime import datetime, timezone
path = 'project-manifest.json'
with open(path, 'r', encoding='utf-8') as f:
m = json.load(f)
m['diagrams'] = m.get('diagrams', {})
m['diagrams']['json'] = 'docs/diagram.json'
m['diagrams']['architecture'] = 'docs/architecture.md'
m['diagrams']['architecture_svg'] = 'docs/architecture.svg'
m['diagrams']['architecture_png'] = 'docs/architecture.png'
m['diagrams']['architecture_html'] = 'docs/architecture.html'
m['diagrams']['flowchart'] = 'docs/flowchart.md'
m['diagrams']['flowchart_svg'] = 'docs/flowchart.svg'
m['diagrams']['flowchart_png'] = 'docs/flowchart.png'
m['diagrams']['flowchart_html'] = 'docs/flowchart.html'
m['diagrams']['data_flow'] = 'docs/data_flow.md'
m['diagrams']['data_flow_svg'] = 'docs/data_flow.svg'
m['diagrams']['data_flow_png'] = 'docs/data_flow.png'
m['diagrams']['data_flow_html'] = 'docs/data_flow.html'
m['diagrams']['generated_at'] = datetime.now(timezone.utc).isoformat()
with open(path, 'w', encoding='utf-8') as f:
json.dump(m, f, ensure_ascii=False, indent=2)
print('[OK] manifest diagrams updated')
"
upy-generate:输入完整 firmware 代码 + manifestupy-wiring 并行:可同时生成LLM 生成 JSON,脚本只做校验 + 渲染:与 upy-generate 模式一致
schema 是唯一契约:diagram.json 必须通过 validate_json.py 校验
必须通读所有 firmware/*.py:不跳过任何文件,架构分析基于真实代码
层 ID 必须使用 enum 值:board, lib, driver, task, entry, host, test
flow phase 必须使用 enum 值:boot, init, scan, create, assembly, run, shutdown
data_flow channel 必须使用 enum 值:function_return, shared_dict, global_var, queue, callback_param
module.source 必须使用 enum 值:scaffold_template, llm_generated, upypi_download, github_download, cold_driver, user_custom
provides/depends_on 从真实 import 和 def 提取:不编造符号
diagnostics 如实填写:包括 orphan_modules 和 machine_direct_access 警告
渲染脚本防御式读取:缺失字段不会崩溃,但会在 stderr 输出警告
SVG + PNG + HTML 为必需输出:脚本默认 --format all,同时生成 .md、.svg、.png 和 .html;仅 --format md 可跳过图片和HTML
可读性约束(各档位上限见 Step 0 参数对照表,默认中等。保证 PNG 在 16:9 比例下清晰可读):
| 字段 | 简单 | 中等(默认) | 详细 | 说明 |
|---|---|---|---|---|
architecture 总模块数 | ≤6 | ≤10 | ≤16 | 合并功能相近的模块 |
| 每层模块数 | ≤2 | ≤4 | ≤6 | 按层拆分上限 |
role | ≤8 字 | ≤10 字 | ≤14 字 | 节点框第 2 行,过长导致节点膨胀 |
cross_layer_deps[].label | ≤4 字 | ≤6 字 | ≤10 字 | 边标签嵌在箭头中间,过长使连线拥挤 |
cross_layer_deps[] 总边数 | ≤6 | ≤12 | ≤20 | 跨层边是拥挤主因,只保留核心依赖 |
flow[].action | ≤4 字 | ≤6 字 | ≤8 字 | 时序图纵向空间受 16:9 限制 |
flow[].detail | ≤8 字 | ≤12 字 | ≤16 字 | 在 action 下方折行,过长侵占垂直空间 |
flow[] 总步数 | ≤5 | ≤8 | ≤14 | 合并相似步骤,不要逐行翻译代码 |
data_flow[].data | ≤6 字 | ≤8 字 | ≤12 字 | 边标签,过长导致箭头被挤压 |
data_flow[] 总边数 | ≤2 | ≤4 | ≤8 | 只保留核心数据流 |
| 16:9 比例 | ≤70% | ≤70% | ≤70% | LLM 预演 Mermaid 渲染,超出即合并 |
Analyze MicroPythonOS App ideas directly or when invoked by mpos-plan-app. Use to turn natural-language MPOS App requests into requirements, default app identity, manifest draft, Activity/Service plan, MPOS/LVGL API plan, dependency risk, test/deploy plan, mandatory MicroPythonOS resource links, and a JSON handoff before code generation.
Deploy or preview a MicroPythonOS app on desktop, web, device copy, MPK install, or installer/flash guidance paths. Use when Codex needs to launch a confirmed app for manual preview, copy it to a board with mpremote, validate an MPK on-device, or route firmware install and erase to install.micropythonos.com. Does not own app generation, static lint, packaging, or default smoke testing.
MicroPythonOS 基础开发知识库。提供代码架构、App/MPK 约束、LVGL 编程约定、MPY API reference、官方 docs 专题 reference、AGENTS 本地强约束。mpos-plan-app / mpos-analyze-app / mpos-prepare-deps / mpos-gen-app / mpos-test-app / mpos-package-app / mpos-deploy-app / mpos-publish-app 均依赖此 skill。
Generate, update, and repeatedly repair MicroPythonOS App code after requirements are confirmed. Use after mpos-analyze-app and optionally mpos-prepare-deps to create or modify an internal_filesystem/apps package directory with root MANIFEST.JSON, root icon_64x64.png, assets/*.py entrypoints/dependencies, dependency adapters, and validation results. Always defaults to a two-phase flow: first produce a generation plan and ask for confirmation, then write files only after explicit user confirmation. Supports repeated calls for user feature changes and test-failure repair loops. Does not analyze vague requirements, prepare external dependencies, package MPK files, deploy devices, flash firmware, publish to upystore, or rebuild lvgl_micropython.
Package and validate a single MicroPythonOS App as an MPK release artifact. Use when Codex needs to create a .mpk, validate an MPOS App manifest/icon/package structure, emit one app_index_entry.json fragment, run optional temporary install validation, or prepare AppStore/upystore publishing artifacts without uploading.
Orchestrate a MicroPythonOS App workflow across analyze, dependency preparation, generation, testing, packaging, deployment, and upystore publishing. Use when Codex needs to start from a natural-language app request, continue or resume an interrupted MPOS app task, decide the next mpos-* skill, maintain per-app plan_state.json and activity_log.jsonl under tmp/mpos-plan-app, handle user requirement changes with invalidation confirmation, or run the default path through mpos-publish-app. Does not implement code, download dependencies, test, package, deploy, flash, or upload directly.