教程概述
系列目录:CLI-Anything 教程系列索引
本教程是一个完整实战案例,演示如何为 Draw.io 生成 CLI 工具,涵盖 CLI-Anything 的全部 7 个阶段。
目标软件:Draw.io
Draw.io 简介
Draw.io(现称 diagrams.net)是一个免费的开源图表绘制工具,支持:
- 流程图、UML 图、网络图
- 多种导出格式(PNG、SVG、PDF)
- 离线桌面应用和在线版本
为什么选择 Draw.io?
- ✅ 代码开源,易于分析
- ✅ 有 Electron 桌面版本
- ✅ API 相对简单
- ✅ 实用价值高
实战演示:7 阶段完整流程
Phase 1: Analyze(分析)
目标:分析 Draw.io 源码,识别可 CLI 化的功能。
# 1. 克隆 Draw.io 源码
git clone https://github.com/jgraph/drawio.git
cd drawio
# 2. 启动 CLI-Anything 分析
/cli-anything ./drawio
分析输出:
# API 映射文档 - Draw.io
## 软件概述
- 名称: Draw.io / diagrams.net
- 版本: 24.x
- 技术栈: Electron, HTML5 Canvas, JavaScript
## 核心功能模块
### 1. 文件操作
- 新建图表
- 打开文件 (.drawio, .xml)
- 保存文件
- 导入 (PNG, SVG, Lucidchart)
- 导出 (PNG, SVG, PDF, HTML)
### 2. 图表操作
- 添加形状
- 连接形状
- 添加文本
- 样式设置
- 图层管理
### 3. 页面管理
- 新建页面
- 删除页面
- 重命名页面
- 页面排序
## CLI 化机会
| 功能 | API/方法 | CLI 命令建议 |
|-----|---------|-------------|
| 新建图表 | app.createFile() | diagram new |
| 打开文件 | app.loadFile() | diagram open |
| 保存文件 | app.saveFile() | diagram save |
| 导出 PNG | app.exportPng() | export png |
| 添加形状 | editor.addShape() | shape add |
| 连接形状 | editor.addConnector() | connector add |
## API 覆盖率评估
- 文件操作: 95%
- 图表操作: 85%
- 页面管理: 90%
- 样式设置: 70%
- **总计: 85%**
Phase 2: Design(设计)
目标:设计 CLI 命令组和状态模型。
# 架构设计文档 - Draw.io CLI
## CLI 概览
- CLI 名称: cli-anything-drawio
- 版本: 1.0.0
## 命令组结构
cli-anything-drawio ├── diagram # 图表管理 │ ├── new │ ├── open │ ├── save │ ├── close │ └── info ├── page # 页面管理 │ ├── new │ ├── delete │ ├── rename │ └── list ├── shape # 形状操作 │ ├── add │ ├── delete │ ├── move │ └── style ├── connector # 连接线 │ ├── add │ ├── delete │ └── style └── export # 导出 ├── png ├── svg ├── pdf └── html
## 状态模型
```python
class DrawioState:
project_id: str
diagram_path: Optional[str]
pages: List[PageState]
active_page_id: str
shapes: Dict[str, ShapeState]
connectors: List[ConnectorState]
modified: bool
输出格式
- 人类可读: 表格和 emoji
- JSON: 结构化数据
### Phase 3: Implement(实现)
**目标**:实现 CLI 代码。
**生成的代码结构**:
drawio/agent-harness/ ├── cli_anything/ │ ├── drawio/ │ │ ├── init.py │ │ ├── cli.py # 主 CLI │ │ ├── repl.py # REPL │ │ ├── state.py # 状态管理 │ │ ├── core/ │ │ │ ├── diagram.py │ │ │ ├── page.py │ │ │ ├── shape.py │ │ │ └── export.py │ │ └── utils/ │ │ └── backend.py # Draw.io 后端封装 │ └── tests/ ├── setup.py ├── README.md └── SKILL.md
**核心代码示例**:
```python
# cli_anything/drawio/core/diagram.py
import click
from ..state import DrawioState
from ..utils.backend import DrawioBackend
@click.group(name='diagram')
def diagram_group():
"""Diagram management commands."""
pass
@diagram_group.command(name='new')
@click.option('--name', '-n', required=True)
@click.option('--template', '-t', default='blank')
@click.pass_context
def diagram_new(ctx, name, template):
"""Create a new diagram."""
state = DrawioState(name=name, template=template)
# 使用后端创建实际文件
backend = DrawioBackend()
diagram_file = backend.create_diagram(name, template)
state.diagram_path = diagram_file
state.save(f"{name}.json")
click.echo(f"✓ Created diagram: {name}")
click.echo(f" Template: {template}")
@diagram_group.command(name='export')
@click.argument('output')
@click.option('--format', '-f', default='png',
type=click.Choice(['png', 'svg', 'pdf']))
@click.option('--page', '-p', help='Page to export')
@click.pass_context
def diagram_export(ctx, output, format, page):
"""Export diagram to various formats."""
state = ctx.obj['project_state']
backend = DrawioBackend()
result = backend.export(
state.diagram_path,
output,
format=format,
page=page
)
if result.success:
click.echo(f"✓ Exported to {output}")
click.echo(f" Format: {format}")
click.echo(f" Size: {result.file_size} bytes")
else:
click.echo(f"✗ Export failed: {result.error}", err=True)
Phase 4: Plan Tests(测试计划)
TEST.md 内容:
# 测试计划 - Draw.io CLI
## 单元测试
### diagram 模块
- [ ] diagram new - 正常创建
- [ ] diagram new - 参数验证
- [ ] diagram open - 打开现有文件
- [ ] diagram save - 保存修改
- [ ] diagram export - PNG 导出
- [ ] diagram export - 格式选择
### page 模块
- [ ] page new - 新建页面
- [ ] page delete - 删除页面
- [ ] page rename - 重命名
### shape 模块
- [ ] shape add - 添加形状
- [ ] shape delete - 删除形状
- [ ] shape move - 移动位置
## E2E 测试
### 场景 1: 创建-编辑-导出流程
1. 创建图表
2. 添加形状
3. 连接形状
4. 导出 PNG
5. 验证输出文件
### 场景 2: 多页面处理
1. 创建图表
2. 添加多个页面
3. 在每个页面添加内容
4. 批量导出所有页面
Phase 5: Write Tests(编写测试)
测试代码:
# tests/unit/test_diagram.py
import pytest
from click.testing import CliRunner
from cli_anything.drawio.cli import cli
class TestDiagramCommands:
def test_diagram_new(self, runner, temp_dir):
result = runner.invoke(cli, [
'--json',
'diagram', 'new',
'--name', 'TestDiagram'
])
assert result.exit_code == 0
output = json.loads(result.output)
assert output['success'] is True
def test_diagram_export_png(self, runner, temp_dir):
# 创建测试图表
diagram_path = temp_dir / 'test.drawio'
create_test_diagram(diagram_path)
output_path = temp_dir / 'output.png'
result = runner.invoke(cli, [
'--json',
'diagram', 'export', str(output_path),
'--format', 'png'
])
assert result.exit_code == 0
assert output_path.exists()
Phase 6: Document(文档)
SKILL.md 示例:
# Skill Definition: cli-anything-drawio
## Overview
**CLI Name**: cli-anything-drawio
**Target Software**: Draw.io / diagrams.net
**Purpose**: Create and edit diagrams programmatically
## Capabilities
### diagram - Diagram Management
- `diagram new` - Create new diagram
- `diagram open` - Open existing diagram
- `diagram export` - Export to PNG/SVG/PDF
### shape - Shape Operations
- `shape add` - Add shape to diagram
- `shape connect` - Connect shapes
## Usage Examples
### Create Flowchart
```bash
cli-anything-drawio diagram new --name Flowchart
cli-anything-drawio shape add --type process --text "Start"
cli-anything-drawio shape add --type decision --text "Check?"
cli-anything-drawio connector add --from 1 --to 2
cli-anything-drawio export png flowchart.png
### Phase 7: Publish(发布)
```bash
# 本地测试
pip install -e .
# 运行测试
pytest
# 构建发布
python -m build
# 上传到 PyPI
twine upload dist/*
使用生成的 CLI
命令行模式
# 创建新图表
cli-anything-drawio diagram new --name "MyFlowchart" --template flowchart
# 添加形状
cli-anything-drawio shape add --type "process" --text "Initialize" --x 100 --y 100
cli-anything-drawio shape add --type "decision" --text "Valid?" --x 100 --y 200
# 连接形状
cli-anything-drawio connector add --from-shape "shape_001" --to-shape "shape_002"
# 导出
cli-anything-drawio export png flowchart.png --border 10
REPL 模式
$ cli-anything-drawio
╔══════════════════════════════════════════╗
║ cli-anything-drawio v1.0.0 ║
║ Draw.io CLI for AI Agents ║
╚══════════════════════════════════════════╝
drawio> diagram new --name ProjectFlow
✓ Created diagram: ProjectFlow
drawio[ProjectFlow]> page new --name "Phase 1"
✓ Created page: Phase 1
drawio[ProjectFlow/Phase 1]> shape add --type rect --text "Requirements"
✓ Added shape: rect at (100, 100)
drawio[ProjectFlow/Phase 1]> export svg diagram.svg
✓ Exported: diagram.svg (15 KB)
drawio[ProjectFlow/Phase 1]> exit
迭代优化
# 发现缺少图层功能
/cli-anything:refine ./drawio "add layer management commands"
# 优化导出功能
/cli-anything:refine ./drawio "support batch export of all pages"
小结
本实战案例演示了完整的 CLI 生成流程:
- Analyze - 分析 Draw.io 源码,识别功能点
- Design - 设计命令组和状态模型
- Implement - 实现 Click CLI 和 REPL
- Plan Tests - 制定测试计划
- Write Tests - 编写 pytest 测试
- Document - 生成 SKILL.md 文档
- Publish - 发布到 PyPI
系列导航:
- ← 上一篇:教程 8:第七阶段 - 发布与优化
- → 下一篇:教程 10:CLI-Hub 与生态建设