@yottameta/yotta-lesson 0.0.0 → 0.1.1

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 ADDED
@@ -0,0 +1,19 @@
1
+ # 更新日志
2
+
3
+ ## v0.1.1 (2026-10-01)
4
+
5
+ - 文档修正:家族协同 / 边界 / 版权说明中元题的引用改为已发布实际口径(元题 = 按双向细目表从学校自备题库组卷 + 试卷结构校验,不生成题面,题面由题库提供);同步更新中英 README 与 `references/copyright.md`。
6
+ - 行为零变更:内核 / CLI / 退出码 / 门禁契约不变。
7
+ - 新增文档契约回归:家族引用不得回退为「规划中 / (planned)」。
8
+
9
+ ## v0.1.0 (2026-09-24)
10
+
11
+ 初始发布:
12
+
13
+ - 定位:元案 —— 本地、确定性的教案骨架与覆盖校验技能(零依赖,Python 3.8+ 标准库);不联网、不调用模型、不内置教材与题目原文。
14
+ - 输入:课标映射包 JSON(课题 / 知识点 / 重难点 / 易错点 / 课标来源)+ 可选结构配置 JSON(每课时分钟、环节与比例、必填环节、环节关键词)。
15
+ - 能力:教案骨架生成(学习目标带来源、重难点与易错点、五环节 + 分钟级时间分配、板书与评价清单)、覆盖检查(`knowledge_missing` / `stage_missing` / `source_missing` / `time_missing` / `minutes_mismatch`)、映射包 list / show / validate。
16
+ - 时间分配:最大余数法,各环节分钟合计精确等于「课时 × 每课时分钟」。
17
+ - CLI:`plan` / `check` / `map` / `template`;退出码 0 / 1 / 2 / 3 / 4;支持 `--periods`、`--format md|json`、`--out`、`--stdin`、`--gate findings=<n>`。
18
+ - 测试:55 项,Python 3.8.20 / 3.11.9 / 3.13.15 全绿;合成样例(完整教案 / 缺口教案)端到端通过。
19
+ - 文档: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** — assemble papers from a local item bank and run deterministic paper-structure checks (no item-text generation);
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).
@@ -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.1
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();