Sources: extracted from two upstream archives (skill-repo, skills-main),
merged with the following policy:
- 15 broken symlinks (pointing to /Users/jameslee/.cc-switch/skills or
../../.agents/skills on a foreign machine) discarded
- 3 real name collisions with identical content (ai-pair, ifind-http-api,
zhipu-websearch) kept as one copy
- Functional overlaps deduped keeping the strongest variant:
- docx family: kept docx (official, full toolchain) + docx-cn
(GB/T 9704 Chinese official-document constants),
dropped docx_writer (no scripts, name collided with docx)
- humanizer family: kept humanizer-zh (6 zh reference docs),
dropped humanizer (en, redundant for CN workflow)
- Skills that only ran in a foreign environment removed:
ablemind-ops, app-publish, hlb-design-system, openclaw-adj-skill,
claude-driver
- alphapai excluded from this public repo because its SKILL.md hard-coded
live credentials
Result: 25 skills, 572 files, ~7.5 MB.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
439 lines
14 KiB
Markdown
439 lines
14 KiB
Markdown
# Job JSON 完整 Schema
|
||
|
||
Job JSON 是 PptEngine 的声明式配置格式,支持两种模式:
|
||
- **template 模式**(默认):基于 PPT 模板 + slides 配置进行占位符替换
|
||
- **composer 模式**(推荐):基于 PageComposer + pages 配置从零构建 PPT
|
||
|
||
## 顶层字段
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `mode` | 否 | `"template"` (默认) 或 `"composer"` |
|
||
| `template` | 条件 | template 模式必填 |
|
||
| `slides` | 条件 | template 模式必填 |
|
||
| `theme` | 条件 | composer 模式用,默认 `"jp_finance"` |
|
||
| `pages` | 条件 | composer 模式必填 |
|
||
| `datasources` | 否 | 数据源配置(两种模式共用)|
|
||
| `transforms` | 否 | 数据转换配置(两种模式共用)|
|
||
| `params` | 否 | 自定义参数 |
|
||
| `output` | 是 | 输出配置 |
|
||
|
||
## Composer 模式 annotated skeleton
|
||
|
||
```json
|
||
{
|
||
"mode": "composer",
|
||
"theme": "jp_finance", // THEMES 中的名称
|
||
"datasources": {
|
||
"数据源名称": {
|
||
"type": "csv", // "csv" | "xlsx" | "tushare"
|
||
// ... 类型相关字段见下方
|
||
}
|
||
},
|
||
"transforms": { // 可选
|
||
"转换后名称": {
|
||
"from": "数据源名称",
|
||
"ops": [{"type": "sort", "sort_by": ["trade_date"]}]
|
||
}
|
||
},
|
||
"pages": [ // 页面列表(按顺序生成)
|
||
{
|
||
"layout": "title_dark", // LAYOUT_REGISTRY 中的布局名称
|
||
"data": { // 传给布局函数的 data dict
|
||
"title": "报告标题",
|
||
"date": "2026-02"
|
||
}
|
||
},
|
||
{
|
||
"layout": "chart_full",
|
||
"data": {
|
||
"title": "营收与利润",
|
||
"source": "revenue_df", // ← 引用 datasources/transforms 中的名称
|
||
"categories_col": "年度",
|
||
"series_config": [
|
||
{"key": "营收", "name": "营收(亿元)", "type": "bar", "axis": "primary"},
|
||
{"key": "利润", "name": "利润(亿元)", "type": "line", "axis": "secondary"}
|
||
],
|
||
"style_config": {"color_scheme": "jp_finance"},
|
||
"layout_config": {
|
||
"legend_config": {"font_size_pt": 9},
|
||
"value_axis_config": {"number_format": "#,##0"}
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"output": {
|
||
"path": "output/report.pptx",
|
||
"overwrite": true,
|
||
"add_metadata": true
|
||
}
|
||
}
|
||
```
|
||
|
||
### source 引用解析规则
|
||
|
||
引擎在渲染时自动将 `source` 引用解析为实际 DataFrame:
|
||
|
||
1. **顶层 source**:`data.source` → `data.df`(替换为 DataFrame)
|
||
2. **嵌套 source**(`two_charts`):`data.left.source` / `data.right.source` → 各自的 `df`
|
||
3. 引用范围:可引用 `datasources` 或 `transforms` 中的任意 key
|
||
|
||
### style_config / layout_config 的 JSON 表达
|
||
|
||
- `style_config`:直接传 `StyleConfig` 构造参数的 dict,如 `{"color_scheme": "jp_finance", "line_width_pt": 2.0}`
|
||
- `layout_config`:支持嵌套子对象:
|
||
- `legend_config` → `LegendConfig` 参数
|
||
- `value_axis_config` / `secondary_value_axis_config` → `ValueAxisConfig` 参数
|
||
- `category_axis_config` → `CategoryAxisConfig` 参数
|
||
- `date_axis_config` → 预设名字符串:`"daily"`, `"weekly"`, `"biweekly"`, `"monthly"`, `"quarterly"`, `"yearly"`
|
||
|
||
## Template 模式 annotated skeleton
|
||
|
||
```json
|
||
{
|
||
"template": {
|
||
"path": "aim/aim03.pptx", // 模板路径(相对于 ppt-st 项目根,或绝对路径)
|
||
"master": null, // 母版名称(可选)
|
||
"notes": null // 备注(可选)
|
||
},
|
||
"datasources": {
|
||
"数据源名称": { // 自定义名称,后续 source 字段引用
|
||
"type": "csv", // "csv" | "xlsx" | "tushare"
|
||
// ... 类型相关字段见下方
|
||
}
|
||
},
|
||
"transforms": { // 可选:数据转换
|
||
"转换后名称": {
|
||
"from": "数据源名称", // 字符串或数组(多源 concat)
|
||
"ops": [ // 有序操作列表
|
||
{"type": "sort", "sort_by": ["trade_date"]}
|
||
]
|
||
}
|
||
},
|
||
"slides": [ // 幻灯片列表(按顺序对应模板页)
|
||
{
|
||
"id": "slide_1", // 唯一标识
|
||
"layout": null, // 版式名(null 使用模板现有页)
|
||
"texts": [ // 文本替换
|
||
{"target": "文本框名", "value": "替换值(支持 Jinja2)"}
|
||
],
|
||
"tables": [ // 表格渲染
|
||
{"target": "表格名", "source": "数据源名", "columns": ["col1"], "header": ["列1"]}
|
||
],
|
||
"charts": [ // 图表渲染
|
||
{
|
||
"mode": "update", // "create" | "update" | "excel_embedded"
|
||
"target": "图表名", // update 模式下模板中的图表名称
|
||
"source": "数据源名",
|
||
"categories": "日期列名",
|
||
"series": [
|
||
{"key": "列名", "name": "显示名", "axis": "primary"}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"params": {}, // 自定义参数(传入渲染上下文)
|
||
"output": {
|
||
"path": "output/report.pptx", // 输出路径
|
||
"overwrite": true,
|
||
"add_metadata": true // 是否添加生成信息到 PPT 元数据
|
||
}
|
||
}
|
||
```
|
||
|
||
## DataSource 字段表
|
||
|
||
### type: "csv"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `path` | 是 | CSV 文件路径(相对于 data_dir 或绝对路径)|
|
||
| `encoding` | 否 | 编码,默认 `utf-8` |
|
||
|
||
### type: "xlsx"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `path` | 是 | Excel 文件路径 |
|
||
| `sheet_name` | 否 | 工作表名,默认第一个 |
|
||
| `encoding` | 否 | 编码,默认 `utf-8` |
|
||
|
||
### type: "tushare"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `api_name` | 否 | API 接口名,默认 `index_daily`。支持 `index_daily`, `pro_bar` |
|
||
| `ts_code` | 是 | 股票/指数代码,如 `600519.SH`, `000300.SH` |
|
||
| `start_date` | 否 | 起始日期 `YYYYMMDD`,默认一年前 |
|
||
| `end_date` | 否 | 结束日期 `YYYYMMDD`,默认今天 |
|
||
| `fields` | 否 | 返回字段列表 |
|
||
|
||
前置条件: 环境变量 `TUSHARE_TOKEN` 或 `.env` 文件中配置。
|
||
|
||
## TransformOp 字段表
|
||
|
||
每个 op 是 `transforms[name].ops[]` 数组中的一项。
|
||
|
||
### type: "groupby"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `by` | 是 | 分组列名列表 |
|
||
| `agg` | 是 | 聚合方式 `{"列名": "sum/mean/count/..."}` |
|
||
|
||
### type: "pivot"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `index` | 是 | 行索引列名 |
|
||
| `columns` | 是 | 列索引列名 |
|
||
| `values` | 是 | 值列名 |
|
||
|
||
### type: "merge"
|
||
|
||
**未实现** — 会抛 `NotImplementedError`。用 `from: [src1, src2]` 做 concat 替代。
|
||
|
||
### type: "compute"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `expr` | 是 | pandas eval 表达式,如 `"close / close.iloc[0] - 1"` |
|
||
| `output_col` | 是 | 输出列名 |
|
||
|
||
### type: "filter"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `condition` | 是 | pandas query 表达式,如 `"close > 100"` |
|
||
|
||
### type: "sort"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `sort_by` | 是 | 排序列名列表 |
|
||
| `ascending` | 否 | 是否升序,默认 `true` |
|
||
|
||
### type: "rename"
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `map` | 是 | 列名映射 `{"旧名": "新名"}` |
|
||
|
||
## SlideSpec
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `id` | 是 | 唯一标识 |
|
||
| `layout` | 否 | 版式名称(null 使用模板现有页面)|
|
||
| `texts` | 否 | 文本替换列表 `[{target, value}]` |
|
||
| `tables` | 否 | 表格渲染列表 `[{target, source, columns, header?, number_format?}]` |
|
||
| `charts` | 否 | 图表渲染列表(见 ChartSpec)|
|
||
|
||
## ChartSpec
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `mode` | 否 | `"create"` / `"update"` / `"excel_embedded"`,默认 `"update"` |
|
||
| `target` | 条件 | update 模式下的模板图表名称 |
|
||
| `target_placeholder` | 条件 | create/excel_embedded 模式下的占位符名 |
|
||
| `source` | 是 | 数据源名称(引用 datasources 或 transforms 的键)|
|
||
| `categories` | 是 | 分类列名 |
|
||
| `series` | 是 | 系列配置 `[{key, name, axis?}]` |
|
||
|
||
## ComposerPageSpec(composer 模式)
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `layout` | 是 | LAYOUT_REGISTRY 中的布局名称 |
|
||
| `data` | 是 | 传给布局函数的 data dict(各布局字段见下表)|
|
||
|
||
### 各布局的 data 字段
|
||
|
||
| 布局 | 必填字段 | 可选字段 |
|
||
|------|---------|---------|
|
||
| `title_dark` | `title` | `subtitle`, `date` |
|
||
| `title_light` | `title` | `subtitle`, `date` |
|
||
| `kpi_cards` | `title`, `cards: [{label, value}]` | `cards[].change`, `cards[].color` |
|
||
| `chart_full` | `title`, `source`, `categories_col`, `series_config` | `subtitle`, `style_config`, `layout_config` |
|
||
| `chart_text` | `title`, `source`, `categories_col`, `series_config`, `text_body` | `text_title`, `text_bullets`, `style_config`, `layout_config` |
|
||
| `two_charts` | `title`, `left: {source, categories_col, series_config}`, `right: {...}` | `left_title`, `right_title` |
|
||
| `comparison_table` | `title`, `headers`, `rows` | |
|
||
| `bullet_points` | `title`, `items: [{icon, label, desc}]` | |
|
||
| `section_divider` | `title`, `number` | |
|
||
| `conclusion_dark` | `verdict` | `items` |
|
||
|
||
### series_config 字段(composer 模式)
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `key` | 是 | DataFrame 列名 |
|
||
| `name` | 是 | 图表中显示的系列名称 |
|
||
| `type` | 否 | `"bar"`, `"line"`, `"area"`(默认按引擎决定)|
|
||
| `axis` | 否 | `"primary"` (左轴) 或 `"secondary"` (右轴) |
|
||
|
||
## 示例: Composer 模式完整版
|
||
|
||
```json
|
||
{
|
||
"mode": "composer",
|
||
"theme": "jp_finance",
|
||
"datasources": {
|
||
"revenue": {"type": "csv", "path": "data/revenue.csv"},
|
||
"stock": {
|
||
"type": "tushare",
|
||
"api_name": "pro_bar",
|
||
"ts_code": "600519.SH",
|
||
"start_date": "20240101",
|
||
"end_date": "20241231"
|
||
}
|
||
},
|
||
"transforms": {
|
||
"stock_sorted": {
|
||
"from": "stock",
|
||
"ops": [{"type": "sort", "sort_by": ["trade_date"]}]
|
||
}
|
||
},
|
||
"pages": [
|
||
{
|
||
"layout": "title_dark",
|
||
"data": {"title": "贵州茅台2024年度分析", "date": "2024-12"}
|
||
},
|
||
{
|
||
"layout": "kpi_cards",
|
||
"data": {
|
||
"title": "核心指标",
|
||
"cards": [
|
||
{"label": "营收", "value": "1,505亿", "change": "+17.2%"},
|
||
{"label": "净利润", "value": "747亿", "change": "+19.1%"},
|
||
{"label": "毛利率", "value": "91.5%", "change": "+0.3pp"}
|
||
]
|
||
}
|
||
},
|
||
{
|
||
"layout": "chart_full",
|
||
"data": {
|
||
"title": "营收与利润趋势",
|
||
"source": "revenue",
|
||
"categories_col": "年度",
|
||
"series_config": [
|
||
{"key": "营收", "name": "营收(亿元)", "type": "bar", "axis": "primary"},
|
||
{"key": "净利润", "name": "净利润(亿元)", "type": "line", "axis": "secondary"}
|
||
],
|
||
"style_config": {"color_scheme": "jp_finance"},
|
||
"layout_config": {
|
||
"legend_config": {"font_size_pt": 9, "font_name": "黑体"},
|
||
"value_axis_config": {"number_format": "#,##0"},
|
||
"secondary_value_axis_config": {"number_format": "#,##0"}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"layout": "two_charts",
|
||
"data": {
|
||
"title": "股价与成交量",
|
||
"left_title": "日收盘价",
|
||
"right_title": "日成交量",
|
||
"left": {
|
||
"source": "stock_sorted",
|
||
"categories_col": "trade_date",
|
||
"series_config": [{"key": "close", "name": "收盘价", "type": "line", "axis": "primary"}],
|
||
"layout_config": {"date_axis_config": "monthly"}
|
||
},
|
||
"right": {
|
||
"source": "stock_sorted",
|
||
"categories_col": "trade_date",
|
||
"series_config": [{"key": "vol", "name": "成交量(手)", "type": "bar", "axis": "primary"}],
|
||
"layout_config": {"date_axis_config": "monthly"}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"layout": "conclusion_dark",
|
||
"data": {"verdict": "茅台护城河坚固,品牌溢价持续"}
|
||
}
|
||
],
|
||
"output": {"path": "output/moutai_2024.pptx"}
|
||
}
|
||
```
|
||
|
||
## 示例: Template 模式最小版
|
||
|
||
```json
|
||
{
|
||
"template": {"path": "aim/aim03.pptx"},
|
||
"datasources": {},
|
||
"slides": [
|
||
{
|
||
"id": "cover",
|
||
"texts": [
|
||
{"target": "标题", "value": "2024年度报告"}
|
||
]
|
||
}
|
||
],
|
||
"output": {"path": "/tmp/minimal.pptx"}
|
||
}
|
||
```
|
||
|
||
## 示例: Template 模式完整版(含 Tushare + 变换 + 图表)
|
||
|
||
```json
|
||
{
|
||
"template": {"path": "aim/aim03.pptx"},
|
||
"datasources": {
|
||
"stock": {
|
||
"type": "tushare",
|
||
"api_name": "pro_bar",
|
||
"ts_code": "600519.SH",
|
||
"start_date": "20240101",
|
||
"end_date": "20241231"
|
||
},
|
||
"index": {
|
||
"type": "tushare",
|
||
"api_name": "pro_bar",
|
||
"ts_code": "000300.SH",
|
||
"start_date": "20240101",
|
||
"end_date": "20241231"
|
||
}
|
||
},
|
||
"transforms": {
|
||
"merged": {
|
||
"from": ["stock", "index"],
|
||
"ops": [
|
||
{"type": "sort", "sort_by": ["trade_date"]},
|
||
{"type": "rename", "map": {"close": "收盘价"}}
|
||
]
|
||
}
|
||
},
|
||
"slides": [
|
||
{
|
||
"id": "cover",
|
||
"texts": [
|
||
{"target": "标题", "value": "贵州茅台2024年度分析"},
|
||
{"target": "日期", "value": "2024-12-31"}
|
||
]
|
||
},
|
||
{
|
||
"id": "chart_page",
|
||
"charts": [
|
||
{
|
||
"mode": "update",
|
||
"target": "当年收益率走势图",
|
||
"source": "merged",
|
||
"categories": "trade_date",
|
||
"series": [
|
||
{"key": "收盘价", "name": "茅台收盘价", "axis": "primary"}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"params": {"year": 2024},
|
||
"output": {
|
||
"path": "output/moutai_2024.pptx",
|
||
"overwrite": true,
|
||
"add_metadata": true
|
||
}
|
||
}
|
||
```
|