@yottameta/yotta-lesson 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/NOTICE +12 -0
- package/README.md +156 -0
- package/README.zh-CN.md +148 -0
- package/SKILL.md +87 -0
- package/assets/banner.png +0 -0
- package/bin/install.js +163 -0
- package/install.sh +132 -0
- package/package.json +35 -9
- package/references/copyright.md +34 -0
- package/references/map-format.md +88 -0
- package/references/plan-format.md +61 -0
- package/scripts/yotta_lesson.py +653 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# 更新日志
|
|
2
|
+
|
|
3
|
+
## v0.1.0 (2026-09-24)
|
|
4
|
+
|
|
5
|
+
初始发布:
|
|
6
|
+
|
|
7
|
+
- 定位:元案 —— 本地、确定性的教案骨架与覆盖校验技能(零依赖,Python 3.8+ 标准库);不联网、不调用模型、不内置教材与题目原文。
|
|
8
|
+
- 输入:课标映射包 JSON(课题 / 知识点 / 重难点 / 易错点 / 课标来源)+ 可选结构配置 JSON(每课时分钟、环节与比例、必填环节、环节关键词)。
|
|
9
|
+
- 能力:教案骨架生成(学习目标带来源、重难点与易错点、五环节 + 分钟级时间分配、板书与评价清单)、覆盖检查(`knowledge_missing` / `stage_missing` / `source_missing` / `time_missing` / `minutes_mismatch`)、映射包 list / show / validate。
|
|
10
|
+
- 时间分配:最大余数法,各环节分钟合计精确等于「课时 × 每课时分钟」。
|
|
11
|
+
- CLI:`plan` / `check` / `map` / `template`;退出码 0 / 1 / 2 / 3 / 4;支持 `--periods`、`--format md|json`、`--out`、`--stdin`、`--gate findings=<n>`。
|
|
12
|
+
- 测试:55 项,Python 3.8.20 / 3.11.9 / 3.13.15 全绿;合成样例(完整教案 / 缺口教案)端到端通过。
|
|
13
|
+
- 文档:SKILL.md + references(map-format / plan-format / copyright)+ 中英 README + 四方式安装 + banner。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 YottaMeta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# NOTICE — YottaMeta 品牌声明
|
|
2
|
+
|
|
3
|
+
「YottaMeta」「元案」「yotta-lesson」以及本家族各技能名称(yotta-* 前缀)是 YottaMeta 的品牌与标识。
|
|
4
|
+
|
|
5
|
+
本软件以 MIT 许可证开源,任何人均可自由使用、修改与分发。若你在其基础上制作派生作品:
|
|
6
|
+
|
|
7
|
+
1. 不得继续使用 YottaMeta 或本家族名称(yotta-*、元案 等)作为派生作品的名称;
|
|
8
|
+
2. 不得暗示派生作品由 YottaMeta 官方维护、认可或与之存在关联;
|
|
9
|
+
3. 建议在派生作品中明确声明「与 YottaMeta 官方无关联」。
|
|
10
|
+
|
|
11
|
+
本技能由 YottaMeta 全新实现(零依赖自研 + 中文教学);不内置教材、课标与题目原文,
|
|
12
|
+
映射包只记录结构性元数据,示例中的课标来源为占位样例。
|
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<p align="center"><b>Language</b>: English · <a href="./README.zh-CN.md">中文</a></p>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="assets/banner.png" alt="yotta-lesson banner" width="100%" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">yotta-lesson · 元案 (YuanAn)</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">YottaMeta's <b>deterministic lesson-plan skeleton and coverage checker</b>: turn a curriculum
|
|
10
|
+
map into a lesson skeleton whose stage times add up exactly and whose objectives each carry a
|
|
11
|
+
<b>curriculum-standard source</b>, then check an existing lesson plan for <b>missing knowledge points,
|
|
12
|
+
missing stages, missing citations and time mismatches</b>.</p>
|
|
13
|
+
<p align="center">Pure Python 3.8+ standard library, zero dependencies; local-only — no network, no model
|
|
14
|
+
calls, no textbook or exam text bundled.</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue" /></a>
|
|
18
|
+
<a href="https://agentskills.io/"><img alt="Standard: agentskills.io" src="https://img.shields.io/badge/standard-agentskills.io-orange" /></a>
|
|
19
|
+
<a href="https://www.npmjs.com/package/@yottameta/yotta-lesson"><img alt="npm package" src="https://img.shields.io/npm/v/@yottameta/yotta-lesson" /></a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
## What it is
|
|
23
|
+
|
|
24
|
+
yotta-lesson reads a curriculum map (lesson id, knowledge points, key points, difficulties,
|
|
25
|
+
misconceptions, standard reference) plus an optional structure config, then produces:
|
|
26
|
+
|
|
27
|
+
- a lesson-plan skeleton — objectives with sources, key/difficult points, misconception reminders,
|
|
28
|
+
five stages with minute-level time allocation, board-work and evaluation checklist;
|
|
29
|
+
- a coverage check — run against an existing lesson text to list structural gaps with reasons.
|
|
30
|
+
|
|
31
|
+
It is a preparation aid. It does not write objectives on the teacher's behalf, does not generate
|
|
32
|
+
exercise content, and does not ship any textbook or exam material.
|
|
33
|
+
|
|
34
|
+
## Core value
|
|
35
|
+
|
|
36
|
+
- **Exact time allocation** — largest-remainder allocation, so stage minutes always sum to
|
|
37
|
+
`periods × minutes_per_period`.
|
|
38
|
+
- **Traceable objectives** — every objective carries the `standard` reference from the map.
|
|
39
|
+
- **Deterministic checks** — the same lesson text, map and config produce the same gap list.
|
|
40
|
+
- **Local and zero-dependency** — Python 3.8+ standard library; no network, no model, no upload.
|
|
41
|
+
- **Metadata only** — maps hold structural metadata, never textbook or question text.
|
|
42
|
+
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
Windows uses `python`, Linux / macOS use `python3`.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# 1. Create templates (curriculum map + structure config)
|
|
49
|
+
python3 scripts/yotta_lesson.py template --output-dir ./lesson-template
|
|
50
|
+
|
|
51
|
+
# 2. Build a lesson skeleton
|
|
52
|
+
python3 scripts/yotta_lesson.py plan --map lesson-map.json --lesson L1
|
|
53
|
+
|
|
54
|
+
# 3. Two-period variant as JSON
|
|
55
|
+
python3 scripts/yotta_lesson.py plan --map lesson-map.json --lesson L1 --periods 2 --format json
|
|
56
|
+
|
|
57
|
+
# 4. Check an existing lesson plan; fail CI when any gap appears
|
|
58
|
+
python3 scripts/yotta_lesson.py check --plan plan.md --map lesson-map.json --lesson L1 --gate findings=1
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Commands
|
|
62
|
+
|
|
63
|
+
| Command | Description |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `plan --map <file> --lesson <id>` | Build a lesson-plan skeleton |
|
|
66
|
+
| `plan --periods <n>` | Override the period count from the map |
|
|
67
|
+
| `plan --format md\|json` | Markdown (default) or JSON output |
|
|
68
|
+
| `check --plan <file>` | Check an existing lesson text for structural gaps |
|
|
69
|
+
| `check --stdin` | Read the lesson text from standard input |
|
|
70
|
+
| `check --gate findings=<n>` | Exit code 1 when the gap count reaches `n` |
|
|
71
|
+
| `map list / show / validate` | Inspect or validate the curriculum map |
|
|
72
|
+
| `template --output-dir <dir>` | Write starter map and structure config |
|
|
73
|
+
| `--version` | Print the engine version |
|
|
74
|
+
|
|
75
|
+
Exit codes: `0` ok | `1` gate triggered | `2` input error | `3` map / config error | `4` runtime error.
|
|
76
|
+
|
|
77
|
+
## Curriculum map
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"schema_version": "1.0",
|
|
82
|
+
"subject": "数学",
|
|
83
|
+
"grade": "七年级上",
|
|
84
|
+
"lessons": [
|
|
85
|
+
{
|
|
86
|
+
"id": "L1",
|
|
87
|
+
"title": "认识一元一次方程",
|
|
88
|
+
"periods": 1,
|
|
89
|
+
"knowledge": ["一元一次方程的定义", "方程的解"],
|
|
90
|
+
"key_points": ["一元一次方程的定义"],
|
|
91
|
+
"difficulties": ["由实际问题抽象出方程"],
|
|
92
|
+
"misconceptions": ["把含未知数的式子都当方程"],
|
|
93
|
+
"standard": "义务教育数学课程标准(2022 年版)· 方程与不等式"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Full field list and error table: [references/map-format.md](references/map-format.md).
|
|
100
|
+
|
|
101
|
+
## Gap kinds
|
|
102
|
+
|
|
103
|
+
`knowledge_missing`, `stage_missing`, `source_missing`, `time_missing`, `minutes_mismatch` —
|
|
104
|
+
definitions, report contract and exit codes: [references/plan-format.md](references/plan-format.md).
|
|
105
|
+
|
|
106
|
+
## Copyright and boundaries
|
|
107
|
+
|
|
108
|
+
- Maps store structural metadata only; no textbook, curriculum or exam text is bundled;
|
|
109
|
+
- `standard` is a citation label for traceability, not an interpretation of the curriculum;
|
|
110
|
+
- Output is a preparation aid — the teacher owns the final lesson design.
|
|
111
|
+
|
|
112
|
+
Details: [references/copyright.md](references/copyright.md).
|
|
113
|
+
|
|
114
|
+
## Installation
|
|
115
|
+
|
|
116
|
+
### Option 1 — npx (recommended)
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx -y @yottameta/yotta-lesson --agent codex # or: --agent claude | cursor | gemini | opencode ...
|
|
120
|
+
npx -y @yottameta/yotta-lesson --dir <skills-dir>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Option 2 — git clone
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
git clone https://github.com/YottaMeta/yotta-lesson.git <skills-dir>/yotta-lesson
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Option 3 — Download ZIP
|
|
130
|
+
|
|
131
|
+
Download ZIP from https://github.com/YottaMeta/yotta-lesson and extract it into your agent's skills directory.
|
|
132
|
+
|
|
133
|
+
### Option 4 — install.sh
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
bash install.sh --list
|
|
137
|
+
bash install.sh --agent codex
|
|
138
|
+
bash install.sh --dir <skills-dir>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Works with
|
|
142
|
+
|
|
143
|
+
- **yotta-mirror** — feed learning diagnostics back into the next lesson's focus;
|
|
144
|
+
- **yotta-item** (planned) — fill the example and practice slots with item content;
|
|
145
|
+
- **yotta-present** — render the skeleton in a consistent, copyable layout;
|
|
146
|
+
- **yotta-humanize** — natural-language polish for teacher-facing narratives;
|
|
147
|
+
- **yotta-memory** — store map versions and skeleton summaries on request.
|
|
148
|
+
|
|
149
|
+
## Requirements
|
|
150
|
+
|
|
151
|
+
- Python 3.8+ (standard library only)
|
|
152
|
+
- UTF-8 encoded JSON map and UTF-8 lesson text; no extra packages, no database, no service
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
<p align="center"><b>语言</b>: 中文 · <a href="./README.md">English</a></p>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="assets/banner.png" alt="yotta-lesson banner" width="100%" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">元案 yotta-lesson · 教案 / 学案</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">YottaMeta 的<b>确定性教案骨架与覆盖校验技能</b>:把课标映射包变成教案骨架——
|
|
10
|
+
环节时间精确到分钟、合计可校验,学习目标逐条带<b>课标来源</b>;再用一次确定性检查回答
|
|
11
|
+
<b>「知识点、环节、来源、时间都齐了吗」</b>。</p>
|
|
12
|
+
<p align="center">零依赖(Python 3.8+ 标准库),本地运行:不联网、不调用模型、不内置教材与题目原文。</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue" /></a>
|
|
16
|
+
<a href="https://agentskills.io/"><img alt="Standard: agentskills.io" src="https://img.shields.io/badge/standard-agentskills.io-orange" /></a>
|
|
17
|
+
<a href="https://www.npmjs.com/package/@yottameta/yotta-lesson"><img alt="npm package" src="https://img.shields.io/npm/v/@yottameta/yotta-lesson" /></a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
## 这是什么
|
|
21
|
+
|
|
22
|
+
元案读取课标映射包(课题 id、知识点、重难点、易错点、课标来源)与可选的结构配置,产出两样东西:
|
|
23
|
+
|
|
24
|
+
- **教案骨架**:学习目标(带来源)、重难点与易错点、五环节 + 分钟级时间分配、板书与评价清单;
|
|
25
|
+
- **覆盖检查**:对已有教案文本列出结构性缺口(未覆盖知识点、缺环节、缺来源、未标时间、合计时间不一致)。
|
|
26
|
+
|
|
27
|
+
它是备课辅助:不替教师写教学目标、不生成题目内容、不内置教材与题目原文。
|
|
28
|
+
|
|
29
|
+
## 核心价值
|
|
30
|
+
|
|
31
|
+
- **时间精确**:最大余数法分配,各环节分钟合计恒等于「课时 × 每课时分钟」;
|
|
32
|
+
- **来源可追**:每条学习目标都带映射包中的 `standard`;
|
|
33
|
+
- **确定性检查**:同一份教案、映射包与配置,得到同一份缺口清单;
|
|
34
|
+
- **本地零依赖**:Python 3.8+ 标准库,不联网、不调用模型、不上传教案;
|
|
35
|
+
- **只存结构性元数据**:映射包不含教材正文与题目原文。
|
|
36
|
+
|
|
37
|
+
## 快速开始
|
|
38
|
+
|
|
39
|
+
Windows 使用 `python`,Linux / macOS 使用 `python3`。
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 1. 生成模板(映射包 + 结构配置)
|
|
43
|
+
python3 scripts/yotta_lesson.py template --output-dir ./lesson-template
|
|
44
|
+
|
|
45
|
+
# 2. 生成教案骨架
|
|
46
|
+
python3 scripts/yotta_lesson.py plan --map lesson-map.json --lesson L1
|
|
47
|
+
|
|
48
|
+
# 3. 两课时版本,输出 JSON
|
|
49
|
+
python3 scripts/yotta_lesson.py plan --map lesson-map.json --lesson L1 --periods 2 --format json
|
|
50
|
+
|
|
51
|
+
# 4. 检查已有教案,缺口 ≥ 1 时让 CI 失败
|
|
52
|
+
python3 scripts/yotta_lesson.py check --plan plan.md --map lesson-map.json --lesson L1 --gate findings=1
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 命令一览
|
|
56
|
+
|
|
57
|
+
| 命令 | 说明 |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `plan --map <文件> --lesson <id>` | 生成教案骨架 |
|
|
60
|
+
| `plan --periods <n>` | 覆盖映射包中的课时数 |
|
|
61
|
+
| `plan --format md\|json` | 输出格式:Markdown(默认)或 JSON |
|
|
62
|
+
| `check --plan <文件>` | 检查已有教案的结构性缺口 |
|
|
63
|
+
| `check --stdin` | 从标准输入读取教案文本 |
|
|
64
|
+
| `check --gate findings=<n>` | 缺口数量达到 n 时退出码 1 |
|
|
65
|
+
| `map list / show / validate` | 映射包列表 / 详情 / 校验 |
|
|
66
|
+
| `template --output-dir <目录>` | 生成映射包与结构配置模板 |
|
|
67
|
+
| `--version` | 打印引擎版本 |
|
|
68
|
+
|
|
69
|
+
退出码:`0` 正常 | `1` 触发闸门 | `2` 输入错误 | `3` 映射或配置错误 | `4` 运行时错误。
|
|
70
|
+
|
|
71
|
+
## 映射包示例
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"schema_version": "1.0",
|
|
76
|
+
"subject": "数学",
|
|
77
|
+
"grade": "七年级上",
|
|
78
|
+
"lessons": [
|
|
79
|
+
{
|
|
80
|
+
"id": "L1",
|
|
81
|
+
"title": "认识一元一次方程",
|
|
82
|
+
"periods": 1,
|
|
83
|
+
"knowledge": ["一元一次方程的定义", "方程的解"],
|
|
84
|
+
"misconceptions": ["把含未知数的式子都当方程"],
|
|
85
|
+
"standard": "义务教育数学课程标准(2022 年版)· 方程与不等式"
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
完整字段与报错对照见 [references/map-format.md](references/map-format.md)。
|
|
92
|
+
|
|
93
|
+
## 缺口类型
|
|
94
|
+
|
|
95
|
+
`knowledge_missing`、`stage_missing`、`source_missing`、`time_missing`、`minutes_mismatch`——
|
|
96
|
+
定义、报告契约与退出码见 [references/plan-format.md](references/plan-format.md)。
|
|
97
|
+
|
|
98
|
+
## 版权与边界
|
|
99
|
+
|
|
100
|
+
- 映射包只存结构性元数据,不内置教材、课标与题目原文;
|
|
101
|
+
- `standard` 是引用标注(用于可追溯),不代表本技能对课标作出解释;
|
|
102
|
+
- 输出为备课辅助,教学设计的最终决定由教师负责。
|
|
103
|
+
|
|
104
|
+
细节见 [references/copyright.md](references/copyright.md)。
|
|
105
|
+
|
|
106
|
+
## 安装
|
|
107
|
+
|
|
108
|
+
### 方式一 — npx 一行装(推荐)
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npx -y @yottameta/yotta-lesson --agent codex # 亦可 --agent claude | cursor | gemini | opencode ...
|
|
112
|
+
npx -y @yottameta/yotta-lesson --dir <技能目录>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 方式二 — git clone
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
git clone https://github.com/YottaMeta/yotta-lesson.git <技能目录>/yotta-lesson
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 方式三 — 下载 ZIP
|
|
122
|
+
|
|
123
|
+
在 https://github.com/YottaMeta/yotta-lesson 页面点 Code → Download ZIP,解压到智能体的技能目录。
|
|
124
|
+
|
|
125
|
+
### 方式四 — install.sh
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
bash install.sh --list
|
|
129
|
+
bash install.sh --agent codex
|
|
130
|
+
bash install.sh --dir <技能目录>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 与家族技能协同
|
|
134
|
+
|
|
135
|
+
- **元镜 yotta-mirror**:用学情数据反哺下一轮备课的薄弱点;
|
|
136
|
+
- **元题 yotta-item**(规划中):在骨架的例题与练习位补入题目内容;
|
|
137
|
+
- **元呈 yotta-present**:把教案骨架渲染成统一格式;
|
|
138
|
+
- **元真 yotta-humanize**:教师-facing 叙述文字去 AI 味;
|
|
139
|
+
- **元忆 yotta-memory**:按需保存映射包版本与骨架摘要。
|
|
140
|
+
|
|
141
|
+
## 运行要求
|
|
142
|
+
|
|
143
|
+
- Python 3.8+(仅标准库)
|
|
144
|
+
- UTF-8 的 JSON 映射包与教案文本;不需要额外依赖、数据库或服务
|
|
145
|
+
|
|
146
|
+
## 许可证
|
|
147
|
+
|
|
148
|
+
MIT,见 [LICENSE](LICENSE) 与 [NOTICE](NOTICE)。
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yotta-lesson
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
description: 元案 —— 本地、确定性的教案骨架与覆盖校验技能:按版本化课标映射包(课题 / 知识点 / 重难点 / 易错点 / 课标来源)生成教案骨架,环节时间按课时精确分配(合计 = 课时 × 每课时分钟),学习目标逐条标注课标来源;`check` 子命令对已有教案文本做确定性缺口检查(未覆盖知识点、缺必填环节、缺课标来源、未标时间、合计时间不一致),输出带证据的 Markdown / JSON 清单,支持 `--gate findings=<n>` CI 闸门;零依赖 Python 3.8+,核心不联网、不调用模型、不含教材与题目原文。触发:用户要写教案 / 学案骨架、按课标核对教案结构、检查教案是否覆盖知识点与环节、把教案结构检查接入自动化流程时。边界:只生成结构性骨架与缺口清单,不生成题目内容、不生成学生评语、不替代教师的教学设计判断;不联网、不上传教案与校本映射;不内置教材版权原文,课标引用以官方文本为准。
|
|
5
|
+
license: MIT
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 元案(yotta-lesson)
|
|
9
|
+
|
|
10
|
+
本地、确定性的教案骨架与覆盖校验技能。元案把「课标映射包」变成可复算的教案骨架,
|
|
11
|
+
并把「这节课的知识点、环节、来源、时间齐了吗」变成一份确定性缺口清单。
|
|
12
|
+
|
|
13
|
+
可信契约:
|
|
14
|
+
|
|
15
|
+
- 教案骨架来自映射包与结构配置,同一输入得到同一结果(仅生成时间不同);
|
|
16
|
+
- 时间分配精确到分钟且合计可校验(课时 × 每课时分钟);
|
|
17
|
+
- 每条学习目标都带课标来源;缺口清单给出具体原因与关键词;
|
|
18
|
+
- 核心路径不联网、不调用模型,教案与映射包只在本机流转。
|
|
19
|
+
|
|
20
|
+
## 何时使用
|
|
21
|
+
|
|
22
|
+
- 按学校自备的课标 / 单元映射,快速起一份结构完整的教案骨架;
|
|
23
|
+
- 用 `check` 核对已有教案:知识点是否都覆盖、必填环节是否齐全、是否标了来源与时间;
|
|
24
|
+
- 教研组统一教案结构(同一映射包 + 同一结构配置 = 同一套骨架口径);
|
|
25
|
+
- 把教案结构检查接入批处理或 CI(`--gate findings=<n>`)。
|
|
26
|
+
|
|
27
|
+
**Do NOT trigger**:
|
|
28
|
+
|
|
29
|
+
- 不生成题目与学案题目内容(属元题),不生成学生评语;
|
|
30
|
+
- 不替代教师的教学设计判断:骨架与清单是备课辅助,最终设计由教师定稿;
|
|
31
|
+
- 不联网、不调用模型、不上传教案与校本映射;
|
|
32
|
+
- 不内置教材与课标原文,只记录结构性元数据;引用请以官方文本为准。
|
|
33
|
+
|
|
34
|
+
## 快速使用
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# 生成映射包与结构配置模板
|
|
38
|
+
python3 scripts/yotta_lesson.py template --output-dir ./lesson-template
|
|
39
|
+
|
|
40
|
+
# 生成教案骨架(Markdown)
|
|
41
|
+
python3 scripts/yotta_lesson.py plan --map lesson-map.json --lesson L1
|
|
42
|
+
|
|
43
|
+
# 两课时版本 + JSON 输出
|
|
44
|
+
python3 scripts/yotta_lesson.py plan --map lesson-map.json --lesson L1 --periods 2 --format json
|
|
45
|
+
|
|
46
|
+
# 检查已有教案的覆盖缺口,并在缺口 ≥ 1 时让 CI 失败
|
|
47
|
+
python3 scripts/yotta_lesson.py check --plan plan.md --map lesson-map.json --lesson L1 --gate findings=1
|
|
48
|
+
|
|
49
|
+
# 映射包操作
|
|
50
|
+
python3 scripts/yotta_lesson.py map validate --map lesson-map.json
|
|
51
|
+
python3 scripts/yotta_lesson.py map list --map lesson-map.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
退出码:`0` 正常 | `1` 触发 `--gate` | `2` 输入错误 | `3` 映射或配置错误 | `4` 运行时错误。
|
|
55
|
+
|
|
56
|
+
## 输入与输出
|
|
57
|
+
|
|
58
|
+
- **课标映射包**:JSON,逐课题声明 `id` / `title` / `periods` / `knowledge` / `key_points` / `difficulties` / `misconceptions` / `standard`(课标来源,必填);
|
|
59
|
+
- **结构配置**(可选):`minutes_per_period`、`stages`(环节与比例)、`required_stages`、`check_keywords`;
|
|
60
|
+
- **输出**:教案骨架 Markdown + JSON(`schema_version 1.0`,含 `objectives` / `stages` / `checklist` / `findings` / `sources` / `disclaimer`);
|
|
61
|
+
- **缺口检查**:`knowledge_missing` / `stage_missing` / `source_missing` / `time_missing` / `minutes_mismatch`。
|
|
62
|
+
|
|
63
|
+
字段规范见 `references/map-format.md`;报告契约见 `references/plan-format.md`。
|
|
64
|
+
|
|
65
|
+
## 版权与边界
|
|
66
|
+
|
|
67
|
+
- 映射包只存结构性元数据(课题 / 知识点 / 课标条目标识),不存教材正文与题目原文;
|
|
68
|
+
- 课标引用以官方文本为准,本技能不做课标解读;
|
|
69
|
+
- 输出为备课辅助,不用于教学评价结论。
|
|
70
|
+
|
|
71
|
+
详见 `references/copyright.md`。
|
|
72
|
+
|
|
73
|
+
## 家族协同
|
|
74
|
+
|
|
75
|
+
- **元镜 yotta-mirror**:用学情数据反哺下一轮备课的薄弱点;
|
|
76
|
+
- **元题 yotta-item**(规划中):在骨架的例题与练习位补入题目内容;
|
|
77
|
+
- **元呈 yotta-present**:把教案骨架渲染成统一格式;
|
|
78
|
+
- **元真 yotta-humanize**:教师-facing 叙述文字去 AI 味;
|
|
79
|
+
- **元忆 yotta-memory**:按需保存映射包版本与教案骨架摘要。
|
|
80
|
+
|
|
81
|
+
## 渐进披露
|
|
82
|
+
|
|
83
|
+
- 映射包与结构配置:`references/map-format.md`
|
|
84
|
+
- 骨架 / 检查报告契约与退出码:`references/plan-format.md`
|
|
85
|
+
- 版权与使用边界:`references/copyright.md`
|
|
86
|
+
|
|
87
|
+
按需读取,不必每次全读。
|
|
Binary file
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* yotta-lesson 跨平台安装器(YottaSkills)
|
|
4
|
+
* 用法:
|
|
5
|
+
* npx -y @yottameta/yotta-lesson --agent <name> # 按智能体默认用户级目录安装(推荐)
|
|
6
|
+
* npx -y @yottameta/yotta-lesson --dir PATH # 装到指定目录(用户改了目录的智能体)
|
|
7
|
+
* npx -y @yottameta/yotta-lesson -g # 安装到全部已知智能体用户级目录
|
|
8
|
+
* npx -y @yottameta/yotta-lesson # 安装到检测到的项目级目录
|
|
9
|
+
* npx -y @yottameta/yotta-lesson --list # 列出智能体 -> 默认目录
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const os = require('os');
|
|
15
|
+
|
|
16
|
+
const SKILL_NAME = 'yotta-lesson';
|
|
17
|
+
const PKG_ROOT = path.join(__dirname, '..');
|
|
18
|
+
|
|
19
|
+
// 智能体 -> 用户级默认技能目录(dirs 按优先级排列;--agent 装到第一个)
|
|
20
|
+
// 依据官方文档:.agents/skills 并非通用目录,被 OpenCode / Cursor / Cline / Amp /
|
|
21
|
+
// Kimi / Gemini CLI / GitHub Copilot 等读取;Claude Code 与 Codex 默认不读 .agents。
|
|
22
|
+
const AGENT_DIRS = {
|
|
23
|
+
claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
|
|
24
|
+
cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
|
|
25
|
+
codex: { label: 'Codex', dirs: ['.codex/skills'] }, // 特判:$CODEX_HOME/skills
|
|
26
|
+
gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
|
|
27
|
+
goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
|
|
28
|
+
amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
|
|
29
|
+
opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] }, // 特判:$XDG_CONFIG_HOME
|
|
30
|
+
windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
|
|
31
|
+
workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
|
|
32
|
+
kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
|
|
33
|
+
trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
|
|
34
|
+
'trae-cn': { label: 'Trae IDE(国内)', dirs: ['.trae-cn/skills'] },
|
|
35
|
+
qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
|
|
36
|
+
comate: { label: 'Comate 文心快码', dirs: ['.comate/skills'] },
|
|
37
|
+
codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
|
|
38
|
+
kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
|
|
39
|
+
agents: { label: '通用 AGENTS.md', dirs: ['.agents/skills'] },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Codex 用户级目录特判:优先 $CODEX_HOME/skills,否则 ~/.codex/skills
|
|
43
|
+
function codexUserDir() {
|
|
44
|
+
const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
45
|
+
return path.join(base, 'skills');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// OpenCode 用户级目录特判:优先 $XDG_CONFIG_HOME/opencode/skills,否则 ~/.config/opencode/skills
|
|
49
|
+
function opencodeUserDir() {
|
|
50
|
+
const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
51
|
+
return path.join(base, 'opencode', 'skills');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function resolveUserDir(rel) {
|
|
55
|
+
if (rel === '.codex/skills') return codexUserDir();
|
|
56
|
+
if (rel === '.config/opencode/skills') return opencodeUserDir();
|
|
57
|
+
return path.join(os.homedir(), rel);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function installTo(dest) {
|
|
61
|
+
const target = path.join(dest, SKILL_NAME);
|
|
62
|
+
fs.mkdirSync(target, { recursive: true });
|
|
63
|
+
copyDir(PKG_ROOT, target, new Set(['package.json', 'bin', 'node_modules', '.git']));
|
|
64
|
+
console.log('installed -> ' + target);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function copyDir(src, dst, skip) {
|
|
68
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
69
|
+
if (skip.has(entry.name)) continue;
|
|
70
|
+
const s = path.join(src, entry.name);
|
|
71
|
+
const d = path.join(dst, entry.name);
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
fs.mkdirSync(d, { recursive: true });
|
|
74
|
+
copyDir(s, d, skip);
|
|
75
|
+
} else if (entry.isFile()) {
|
|
76
|
+
fs.copyFileSync(s, d);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function displayDir(rel) {
|
|
82
|
+
if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
|
|
83
|
+
return '~/' + rel;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function main() {
|
|
87
|
+
const args = process.argv.slice(2);
|
|
88
|
+
const isGlobal = args.includes('-g') || args.includes('--global');
|
|
89
|
+
const list = args.includes('--list') || args.includes('-l');
|
|
90
|
+
let explicitDir = null;
|
|
91
|
+
const di = args.indexOf('--dir');
|
|
92
|
+
if (di !== -1 && args[di + 1]) explicitDir = args[di + 1];
|
|
93
|
+
let agent = null;
|
|
94
|
+
const ai = args.indexOf('--agent');
|
|
95
|
+
if (ai !== -1 && args[ai + 1]) agent = String(args[ai + 1]).toLowerCase();
|
|
96
|
+
|
|
97
|
+
if (list) {
|
|
98
|
+
console.log('智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):');
|
|
99
|
+
for (const [key, v] of Object.entries(AGENT_DIRS)) {
|
|
100
|
+
const resolved = v.dirs.map(displayDir);
|
|
101
|
+
console.log(' ' + key.padEnd(10) + v.label.padEnd(18) + resolved.join('、'));
|
|
102
|
+
}
|
|
103
|
+
console.log('\n说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。');
|
|
104
|
+
console.log('改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (explicitDir) { installTo(explicitDir); return; }
|
|
109
|
+
|
|
110
|
+
if (agent) {
|
|
111
|
+
const info = AGENT_DIRS[agent];
|
|
112
|
+
if (!info) {
|
|
113
|
+
console.log('未收录智能体: ' + agent + '。请用 --dir <路径> 指定技能目录。');
|
|
114
|
+
console.log('可用: ' + Object.keys(AGENT_DIRS).join(', '));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
installTo(resolveUserDir(info.dirs[0]));
|
|
118
|
+
console.log('完成。');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (isGlobal) {
|
|
123
|
+
const seen = new Set();
|
|
124
|
+
for (const v of Object.values(AGENT_DIRS)) {
|
|
125
|
+
for (const d of v.dirs) {
|
|
126
|
+
if (seen.has(d)) continue;
|
|
127
|
+
seen.add(d);
|
|
128
|
+
installTo(resolveUserDir(d));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
console.log('完成。');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const PROJECT_DIRS = [
|
|
136
|
+
'.claude/skills',
|
|
137
|
+
'.cursor/skills',
|
|
138
|
+
'.codex/skills',
|
|
139
|
+
'.config/goose/skills',
|
|
140
|
+
'.config/agents/skills',
|
|
141
|
+
'.opencode/skills',
|
|
142
|
+
'.codeium/windsurf/skills',
|
|
143
|
+
'.workbuddy/skills',
|
|
144
|
+
'.kiro/skills',
|
|
145
|
+
'.traecli/skills',
|
|
146
|
+
'.gemini/skills',
|
|
147
|
+
'.trae-cn/skills',
|
|
148
|
+
'.qwen/skills',
|
|
149
|
+
'.comate/skills',
|
|
150
|
+
'.codebuddy/skills',
|
|
151
|
+
'.kimi/skills',
|
|
152
|
+
'.agents/skills',
|
|
153
|
+
];
|
|
154
|
+
let installedAny = false;
|
|
155
|
+
for (const d of PROJECT_DIRS) {
|
|
156
|
+
if (fs.existsSync(d)) { installTo(d); installedAny = true; }
|
|
157
|
+
}
|
|
158
|
+
if (!installedAny) {
|
|
159
|
+
console.log('未检测到项目级智能体目录。可手动复制,或用 --agent <name> / -g 装到用户级。');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
main();
|