@arcaneorion/dsh-teaching-board 0.4.1 → 0.5.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.
Files changed (36) hide show
  1. package/README.md +8 -3
  2. package/cordis.patch.yml +6 -2
  3. package/package.json +5 -3
  4. package/skills/stage-panel/SKILL.md +107 -0
  5. package/skills/stage-panel/references/diagram-selection.md +80 -0
  6. package/skills/stage-panel/references/html-patterns.md +93 -0
  7. package/skills/stage-panel/references/visual-style.md +43 -0
  8. package/skills/stage-panel/submode/code/SKILL.md +17 -0
  9. package/skills/stage-panel/submode/code/examples/go-hello-channel.json +36 -0
  10. package/skills/stage-panel/submode/code/examples/go-http-api-basics.json +58 -0
  11. package/skills/stage-panel/submode/code/examples/py-agent-loop.json +79 -0
  12. package/skills/stage-panel/submode/code/examples/py-ai-parameters-intro.json +65 -0
  13. package/skills/stage-panel/submode/code/examples/py-fizzbuzz-intro.json +74 -0
  14. package/skills/stage-panel/submode/code/examples/py-training-loop.json +114 -0
  15. package/skills/stage-panel/submode/code/examples/rs-move-basics.json +118 -0
  16. package/skills/stage-panel/submode/code/references/host-toolchains.md +61 -0
  17. package/skills/stage-panel/submode/code/schemas/lesson.schema.json +225 -0
  18. package/skills/stage-panel/submode/code/templates/lab.html +561 -0
  19. package/skills/stage-panel/submode/game-study/SKILL.md +16 -0
  20. package/skills/stage-panel/submode/game-study/examples/hft-microstructure.json +60 -0
  21. package/skills/stage-panel/submode/game-study/examples/securities-law.json +57 -0
  22. package/skills/stage-panel/submode/game-study/schemas/quest.schema.json +95 -0
  23. package/skills/stage-panel/submode/game-study/templates/quiz.html +516 -0
  24. package/skills/stage-panel/submode/learn/SKILL.md +16 -0
  25. package/skills/stage-panel/submode/learn/examples/epsilon-delta.json +140 -0
  26. package/skills/stage-panel/submode/learn/examples/template-showcase.json +147 -0
  27. package/skills/stage-panel/submode/learn/schemas/lesson.schema.json +184 -0
  28. package/skills/stage-panel/submode/learn/templates/lesson.html +782 -0
  29. package/skills/stage-panel/submode/ml/SKILL.md +9 -0
  30. package/skills/stage-panel/submode/ml/examples/gd.json +7 -0
  31. package/skills/stage-panel/submode/ml/templates/gd.html +217 -0
  32. package/skills/stage-panel/submode/quant/SKILL.md +9 -0
  33. package/skills/stage-panel/submode/quant/references/export_backtest_data.py +192 -0
  34. package/skills/stage-panel/submode/quant/templates/dashboard.html +381 -0
  35. package/src/index.js +11 -0
  36. package/src/skills.js +88 -0
package/README.md CHANGED
@@ -16,7 +16,7 @@ dsh plugin --profile web add @arcaneorion/dsh-teaching-board
16
16
  它是一个 **profile 级 bundle**:装一次,这个进程里所有会话都拿得到 `stage_*` 工具与「教学平面」页签。
17
17
  (`dsh plugin add` 会把依赖与 bundles 条目一起写进该 profile 的 manifest。)
18
18
 
19
- > **发布状态**:`@arcaneorion/dsh-teaching-board` 已发布(`0.4.0` 于 2026-09-15 10:17 CST 上线,当前 `0.4.1`)。
19
+ > **发布状态**:`@arcaneorion/dsh-teaching-board` 已发布(`0.4.0` 于 2026-09-15 10:17 CST 上线,当前 `0.5.0`)。
20
20
  > 改名前的 `@arcaneorion/dsh-stage-panel@0.1.0` 仍在 registry 上,对应本仓早期版本——**别再用**,
21
21
  > 装它只会拿到残缺面板(`npm deprecate @arcaneorion/dsh-stage-panel "renamed to @arcaneorion/dsh-teaching-board"` 可让老名字自己说明去向)。
22
22
 
@@ -44,6 +44,7 @@ dsh plugin --profile web add @arcaneorion/dsh-teaching-board
44
44
  | 截图交给 agent | client(父层) | PNG → `conversation.createDraftImages` → `inputActions.addImages` → 草稿图片 |
45
45
  | agent 主动截图 | host 工具 + client 监听 | `stage_snapshot` 工具 → client 从快照看到调用 → 拍图 → 作为用户消息提交 |
46
46
  | 状态条 / 方向选择 | host 工具 | `stage_status` / `stage_choice` |
47
+ | 自带使用手册 | host(`src/skills.js`) | 插件把包内 `skills/stage-panel/` 注册成 bundled skill:挂上插件就有纪律,任何 preset 都无需另外安装 |
47
48
 
48
49
  ## 架构:两条硬约束
49
50
 
@@ -63,14 +64,18 @@ dsh plugin --profile web add @arcaneorion/dsh-teaching-board
63
64
  | 文件 | 说明 |
64
65
  |---|---|
65
66
  | `src/index.js` | host 半:`stage_panel / stage_status / stage_choice / stage_snapshot` 四个无状态工具 |
67
+ | `src/skills.js` | host 半:把包内 `skills/stage-panel/` 注册成 bundled skill(provider 模式,随 fiber 注销) |
68
+ | `skills/stage-panel/` | 行为层:使用手册 `SKILL.md` + 选型/布局/视觉三份规范 + 五个素材库 |
66
69
  | `src/client.js` | client 半:「教学平面」视图(工具栏 + 注入 runtime + 截图交付 + agent 请求监听) |
67
70
  | `package.json` / `cordis.patch.yml` | bundle 声明(行 id `teaching-board`),挂载进 `web` profile |
68
71
  | `PROTOTYPE-*.js` | 早期动态原型(`lwst-2`)存档,仅供历史参考 |
69
72
 
70
73
  ## 分层
71
74
 
72
- - **能力层(本 bundle,profile 级)**:投影 + 勾画 + 截图 + 工具。
73
- - **行为层(preset `arcane-stage-panel`)**:教学模式纪律、内容规范(图型/HTML 模式/视觉风格)。
75
+ - **能力层(本 bundle,profile 级)**:投影 + 勾画 + 截图 + 四个 `stage_*` 工具。
76
+ - **行为层(同一 bundle 自带)**:`skills/stage-panel/` —— 使用手册、选型/布局/视觉三份规范、五个素材库;插件 `apply` 时以 provider 方式注册进 `ctx.skills`(`skill-filesystem` 只扫固定的本地根目录,扫不到包内文件,所以必须由插件自己发布)。
77
+
78
+ > 旧布局把行为层放在 preset `arcane-stage-panel` 的 `skills/` 里:教学平面会话拿得到,**其余会话停在「有工具、没纪律」**。现已合并进插件——一份手册,所有挂载本插件的会话都能读到。
74
79
 
75
80
  ## 板面模型:一块板 = 一个主题
76
81
 
package/cordis.patch.yml CHANGED
@@ -1,5 +1,9 @@
1
- # 教学平面 bundle row: 板书视图(勾画 / 截图)+ stage_* 工具(能力层,profile 级)。
2
- # 行为层 = preset arcane-stage-panel(模式纪律与内容规范)。
1
+ # 教学平面 bundle row(能力层 + 行为层都在 @arcaneorion/dsh-teaching-board 里)。
2
+ #
3
+ # 能力层:板书视图(勾画 / 截图)+ stage_* 工具。
4
+ # 行为层:插件在 apply 时把自带的 skills/stage-panel/ 注册进 ctx.skills
5
+ # (bundled skill,见 src/skills.js)——挂上本插件就有使用手册,
6
+ # 不需要任何 preset 另外装一份。
3
7
  - insert:
4
8
  - id: teaching-board
5
9
  name: '@arcaneorion/dsh-teaching-board'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcaneorion/dsh-teaching-board",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -8,7 +8,7 @@
8
8
  "./client": "./src/client.js",
9
9
  "./package.json": "./package.json"
10
10
  },
11
- "description": "DSH teaching surface: project agent-generated self-contained HTML into a sandboxed in-session board with handwriting annotation and a built-in screenshot that returns to the conversation as a real user message.",
11
+ "description": "DSH teaching surface: project agent-generated self-contained HTML into a sandboxed in-session board with handwriting annotation and a built-in screenshot that returns to the conversation as a real user message. Ships its own usage skill (skills/stage-panel).",
12
12
  "license": "MIT",
13
13
  "author": "arcanexis",
14
14
  "repository": {
@@ -26,10 +26,12 @@
26
26
  "screenshot",
27
27
  "ui",
28
28
  "panel",
29
- "iframe"
29
+ "iframe",
30
+ "skill"
30
31
  ],
31
32
  "files": [
32
33
  "src",
34
+ "skills",
33
35
  "cordis.patch.yml",
34
36
  "README.md"
35
37
  ],
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: stage-panel
3
+ description: DSH 教学平面(板书面板)使用手册,随 @arcaneorion/dsh-teaching-board 插件发布:board id 与 op 语义、data-stage-region 替换约定、self-contained HTML 与 MathML 铁律、本地交互与 stage_choice 的分工、圈画与截图的往返纪律,以及选型 / 布局 / 视觉三份规范与五个素材库。
4
+ ---
5
+
6
+ # 教学平面 · 使用手册
7
+
8
+ > 这份手册随 `@arcaneorion/dsh-teaching-board` 一起发布:**会话挂着这个插件,就能读到它**,不需要任何 preset 额外安装。
9
+ > 它讲的是**怎么用**;「能开板、能圈画、能截图」是插件本身的**能力**。
10
+
11
+ ## 单一数据流
12
+
13
+ ```text
14
+ 会话 = 主上下文、唯一真相
15
+ 面板 = 会话的投影:agent 生成 self-contained HTML → stage_panel → 隔离 iframe
16
+ 本地 = 面板内交互(筛选 / tab / hover / 滑块 / 折叠)→ 只在面板里变,不打扰会话
17
+ 回声 = 需要 agent 知道的事 → 真实用户消息(stage_choice 点选 / DSH 输入框 / 截图)
18
+ ```
19
+
20
+ 没有私有状态、没有 RPC、没有 wait 闸门:面板当前的样子 = 会话里最近一次 `stage_*` 调用的参数。
21
+
22
+ ## 工具
23
+
24
+ | 工具 | 用途 | 必须记住的一点 |
25
+ |---|---|---|
26
+ | `stage_panel` | 写板书(HTML) | 同一个 `board` 的连续调用是**同一块板在演进**;换 `board` 才是换板 |
27
+ | `stage_status` | 状态条 + 上下文行 | 讲到哪、任务、阶段、等待态 |
28
+ | `stage_choice` | 发布方向选项 | 用户点选 = 一条真实用户消息;**发布后结束本轮**,不要 wait |
29
+ | `stage_snapshot` | 把当前画面(含圈画)截图发回 | 图在**下一轮**才看得到;每轮最多一次 |
30
+
31
+ ## 板面身份:`board` 与 `op`
32
+
33
+ 一块板 = 一个主题 / 一节课。`board` 用语义短名(`stats-se5`、`gradient-descent`),不要用序号。
34
+
35
+ | op | 语义 | 何时用 |
36
+ |---|---|---|
37
+ | `append`(默认) | 在板尾再写一段 | **默认选择**:接着讲、加一节、补一张表 |
38
+ | `open` | 开板,或整块重写 | 开新主题,或确实要推翻全部内容 |
39
+ | `set` | 替换一个区域 | 只更新某一块(例如"当前步骤"高亮) |
40
+ | `remove` | 擦掉一个区域 | 删掉已经讲完的临时块 |
41
+
42
+ **再讲一段时不要重发整块 HTML**:那会丢掉用户的圈画笔迹、把滚动位置顶回去,也白烧 token。用 `append`。
43
+
44
+ ### 区域替换的约定
45
+
46
+ `set` / `remove` 靠 HTML 里的 `data-stage-region="名称"` 定位,所以**写第一版时就要预判哪些块以后会被单独替换**,给它们挂上这个属性:
47
+
48
+ ```html
49
+ <section data-stage-region="当前步骤">…</section>
50
+ <section data-stage-region="练习">…</section>
51
+ ```
52
+
53
+ 没挂属性的内容只能靠 `open` 整块重写,而整块重写会清掉笔迹。**区域名从第一版就带上**,后面才改得动。
54
+
55
+ ## 铁律:self-contained
56
+
57
+ 面板运行在 `sandbox="allow-scripts"` 的隔离 iframe 里(没有 `allow-same-origin`),且按设计必须自带全部依赖:
58
+
59
+ - CSS / JS 全部内联;字体用系统字体栈,不要 web font。
60
+ - 图片用 `data:` URI;不要引用远程图片、CDN、外链样式表。
61
+ - **公式用 MathML**(浏览器原生,零依赖)。不要引 KaTeX / MathJax:它们要从外网加载脚本和字体,一失败就是空白公式。
62
+ - 交互脚本写在同一个文件的 `<script>` 里,数据写在同一个文件里;不要 `fetch()`。
63
+
64
+ ## 交互分工
65
+
66
+ - **面板内本地交互**(筛选、tab、hover、滑块、折叠):面板自己变就行,不进入会话,尽管加。
67
+ - **需要用户推进时**才用 `stage_choice`:下一步讲什么、要不要继续、选哪条路。发布后结束本轮——点选会以用户消息到达。
68
+ - **长文本输入**走 DSH 自己的输入框。不要在面板里复制"手动回传 / 发送到 CLI"卡片:那是旧原型的做法,现在唯一的回声通道是真实用户消息。
69
+ - 聊天区只留**推理与结论**,画面内容放面板;一轮只问一个决定。
70
+
71
+ ## 圈画与截图
72
+
73
+ - 用户可以用面板工具栏圈画、擦除、撤销、清空。
74
+ - `stage_snapshot` 把当前画面(含笔迹)截图发回会话,作为**一条带图片的真实用户消息**。
75
+ - 所以:调用后**结束本轮**,下一轮才看得到图。不要在同一个回合里假装已经看过。
76
+ - 前提是用户此刻停在「教学平面」页签;没挂着就截不到,会返回失败原因——请用户切过去再试。
77
+ - 每轮最多一次,不要连发。
78
+
79
+ ## 什么时候**不**开板
80
+
81
+ - 纯文本或一张小表格就能说清 → **纯文本就是正确答案**。板是放大器,不是入口。
82
+ - 选不出图型、或内容不值得可视化 → 不要为了"用上面板"而开板。
83
+ - 内容结构决定形式:证明推导、代码路径、协议时序、调试排查、错因复盘、密集图谱各有各的信息结构。**不要把任意内容塞进固定栏目的模板。**
84
+
85
+ ## 规范:选型 → 布局 → 视觉
86
+
87
+ 按这个顺序读,不要跳:
88
+
89
+ | 文件 | 管什么 |
90
+ |---|---|
91
+ | `references/diagram-selection.md` | 选型:信息类型 → 图型、Shannon 依据、生成前的声明格式 |
92
+ | `references/html-patterns.md` | 选型之后的 HTML 组织:不同任务类型的布局模式 |
93
+ | `references/visual-style.md` | 视觉语言:蓝灰控制台 / 硬描边 / 高对比(可选风格,不是强制) |
94
+
95
+ 生成前用 1-3 行在会话里说明"信息类型 → 图型",再开板。
96
+
97
+ ## 素材库(按需取用,不是五个必须套的模式)
98
+
99
+ | 素材 | 内容 | 用得上时 |
100
+ |---|---|---|
101
+ | `submode/code/` | lesson schema(starter / snippets / exercises / annotations / hints)+ lab.html + 7 个真实课程示例 | 代码展示与讲解 |
102
+ | `submode/learn/` | lesson schema(概念卡 / 结构 / 例子 / 问题)+ lesson.html + epsilon-delta 范例 | 结构化讲解 |
103
+ | `submode/game-study/` | quest schema(主动回忆 / 干扰项 / 错因)+ quiz.html + 两个真题库 | 出题与答题面板 |
104
+ | `submode/quant/` | 因子回测 dashboard.html + 数据导出脚本 | 回测结果呈现 |
105
+ | `submode/ml/` | 交互式数值可视化 gd.html + gd.json | 训练 / 优化过程演示 |
106
+
107
+ 它们是**起点素材**:可以借用布局与 schema,但内容结构说了算——不要为了套模板生成空 section 或不贴合内容的控件。
@@ -0,0 +1,80 @@
1
+ # 展现方式选型:信息类型 → 图型
2
+
3
+ 生成任何 panel 之前先完成选型。本文件是「选型」的唯一家:关系类型→图型的完整目录、Shannon 依据、声明格式。选型之后的 HTML 组织方式见 `html-patterns.md`,视觉语言见 `visual-style.md`。
4
+
5
+ ## 0. 一次三问
6
+
7
+ 1. **核心关系是哪一种?**(§2 结构关系 8 种 / §3 数据图表族)——决定图型。
8
+ 2. **读者在哪个阶段?** 读(第一眼建骨架)→ 看(第二遍看关系)→ 玩(深挖探索)——决定交互密度。
9
+ 3. **纯文本+表格能否说清?** 能 → 不生成 panel。文本是一等公民,panel 是放大器不是入口。
10
+
11
+ ## 1. Shannon 三把尺子
12
+
13
+ 展现形式的取舍本质是信息传输的取舍。三把尺子:
14
+
15
+ - **信息密度(熵)**:每元素承载的不可预测性。线性文本每字符熵最高、但需逐字解码;结构图把「关系」编码进位置,每元素熵降低、辨识提速。
16
+ - **冗余**:同一信息重复编码的次数。好的展示有意冗余——同一关系用「位置+颜色+标签」至少编码两遍,帮读者抗噪;装饰性动画不承载任何区分度,是噪声不是冗余。
17
+ - **信道带宽**:读者单次能接收的量有限(工作记忆约 4 组块)。一屏活跃元素超过约 9 个就必须分组、分页或分层展开;交互的本质是**按需分配带宽**——默认只给骨架,点击才注入细节。
18
+
19
+ 推导出的四条规则:
20
+
21
+ 1. 内容熵高(新颖叙述、不可预测的推理多)→ 以线性文本为主,图只给骨架。
22
+ 2. 关系可预测(层级/流程/状态)→ 图的压缩效率最高,优先用图。
23
+ 3. 一屏超过约 9 个活跃元素 → 分组或分层展开,不要硬塞。
24
+ 4. 想强调一个关系 → 给它至少两种编码(位置+颜色/标签);想删一个元素 → 先问它承载了什么区分度。
25
+
26
+ ## 2. 结构关系 8 种 → 图型
27
+
28
+ | # | 关系 | 选它的问句 | 图型 | 何时不用 |
29
+ |---|------|-----------|------|---------|
30
+ | 1 | 包含/层级 | 谁套着谁? | 树状图(思维导图=放射变体、旭日图=径向变体) | 只有一层 → 改列表 |
31
+ | 2 | 步骤顺序 | 先做什么后做什么? | 流程图;无分支时用时间线 | ≤3 步且无分支 → 编号列表 |
32
+ | 3 | 参与者消息 | 多方之间谁发给谁、按什么顺序? | 时序图/泳道图 | 只有两方一问一答 → 两行对照 |
33
+ | 4 | 静态连接 | 谁跟谁有联系(无层级)? | 网络图/组件框图/依赖 DAG | 边数会变毛球(>15 条)→ 矩阵表 |
34
+ | 5 | 状态变迁 | 它待在哪,什么事件让它换地方? | 状态机图 | 状态 >7 个 → 先分组 |
35
+ | 6 | 数据形状 | 实体之间是 1:N 还是 N:M? | ER 图 | 设计存储/日志格式前画,之后当参考 |
36
+ | 7 | 依赖方向 | 谁依赖谁、只能向下调? | 分层架构图 | 依赖双向或无分层 → 改网络图 |
37
+ | 8 | 交叉对照 | 两组维度要交叉看? | 矩阵表 | 关系只有一组维度 → 改清单 |
38
+
39
+ 树、时序、状态机、分层的最小骨架:
40
+
41
+ ```text
42
+ A 你 循环 模型 [空闲] --输入--> [思考] ┌─────────┐
43
+ ├─ B │──提问──→│ │ [思考] --工具调用--> [执行] │ 装配层 │
44
+ │ └─ D │ │──请求──→│ [执行] --完成--> [空闲] ├─────────┤
45
+ └─ C │ │←─分片───│ │ 服务层 │
46
+ ├─────────┤
47
+ │ 适配层 │
48
+ └─────────┘
49
+ ```
50
+
51
+ ## 3. 数据图表族(数值型信息)
52
+
53
+ 选型问句:**这些数字在回答什么问题?**
54
+
55
+ | 数字在回答 | 图型 | 防坑 |
56
+ |-----------|------|------|
57
+ | 类别之间比大小 | 柱状图 | 类别名太长转条形图 |
58
+ | 随时间怎么变 | 折线图 | 别截断 y 轴夸大变化 |
59
+ | 整体由什么构成 | 饼/环/堆叠柱 | 块 >5 改条形 |
60
+ | 两个量是否相关 | 散点图 | 相关≠因果,把第三变量标出来 |
61
+ | 数值怎么分布 | 直方图/箱线图 | 别拿均值冒充分布 |
62
+ | 总量怎么分流 | 桑基图 | 只用于守恒型流动 |
63
+
64
+ ## 4. 组合与递进
65
+
66
+ - 一个 panel 常是 2-3 种图组合,但**每层必须能独立回答一个不同的问题**——不是同一份数据换花样画三遍。
67
+ - 默认递进:读层给结论句 → 看层给主图 → 玩层做交互放大器(点开细节/筛选/对照)。
68
+ - 跨图一致性:同一实体在不同图里同名同色,读者不用重新对表。
69
+
70
+ ## 5. 声明格式(与 SKILL.md 标准流程挂钩)
71
+
72
+ 生成 panel 前,在 CLI 用 1-3 行声明选型,让用户可检查、可纠正:
73
+
74
+ ```text
75
+ 选型:核心关系=包含层级 → 树;次关系=依赖方向 → 分层图
76
+ 交互:第二步放大器(点节点看上下文),首屏纯读
77
+ ```
78
+
79
+ - 核心关系选不出图型 → 说明需求还没长成,先回终端问用户。
80
+ - 「不生成 panel:文本足够」也是合法的选型结论。
@@ -0,0 +1,93 @@
1
+ # HTML Panel Patterns
2
+
3
+ 当视觉结构比线性文字更适合表达任务时,生成 self-contained HTML panel。
4
+
5
+ > **高优先级:模板只是建议/参考,不是固定框架。先判断内容的认知结构,再选择布局、视觉层级和交互方式。**
6
+ >
7
+ > **展现选型的家在 `diagram-selection.md`:先按它声明「信息类型→图型」,本文件只管选型之后的 HTML 组织。**
8
+ >
9
+ > **不要为了套模板而生成固定栏目、空 section 或不贴合内容的控件。概念、证明、代码路径、协议时序、调试、审查和研究总结应拥有不同的信息结构。**
10
+
11
+ ## 默认视觉方向
12
+
13
+ panel 可以拥有自己的视觉语言,但默认应尽量呼应默认的蓝灰控制台风格(见 `visual-style.md`),而不是生成通用 dashboard。
14
+
15
+ 建议:
16
+
17
+ - 使用硬黑描边、小圆角、清晰分区和高对比文字。
18
+ - 优先使用 `#ffd43b` 黄、蓝灰/孔雀蓝背景、`#fff8d6` 奶油色内容面、`#35d8ff` 青色和 `#ffb454` 橙色点缀。
19
+ - 布局应像“任务控制台”:主信息最大,辅助说明和操作靠边,不用大块空洞营销式 hero。
20
+ - 可以使用网格、角标、编号、状态灯、HUD 小标签、漫画式阴影,但不要让装饰压过内容。
21
+ - 字体可优先选择清晰的 monospace 或有技术感的 display 字体;避免默认 AI 风格的紫色渐变、泛白卡片流和过度圆角。
22
+ - 如果任务需要不同基调,可以偏离默认风格,但要先服务任务语义,例如审查面板更克制,学习面板更友好,调试面板更强调证据。
23
+
24
+ ## 最小交互建议
25
+
26
+ **交互应嵌在信息附近,而不是被固定到底部或变成 A/B/C/D 模板。**
27
+
28
+ - 纯展示是有效输出;不需要用户继续推理时,不要强行加输入控件。
29
+ - tab、筛选、hover、展开、局部排序等只在 panel 内部改变显示,不回传会话。
30
+ - 只有需要 agent 继续使用用户补充的上下文时,才用 `stage_choice` 发布一个明确入口(点选 = 一条真实用户消息)。
31
+ - 需要用户写长文本时,请他使用 DSH 自己的输入框;不要在面板里复制“回传”控件。
32
+ - 不要把 Web 交互用于权限批准、命令执行、文件删除或网络授权。
33
+
34
+ ## 学习讲解
35
+
36
+ 用于概念、仓库行为、API、协议和算法。
37
+
38
+ 可包含:
39
+
40
+ - TL;DR 横幅
41
+ - 可点击或 hover 的流程图
42
+ - 术语条
43
+ - 示例 tab
44
+ - 需要用户信号时才加入热点、筛选器、排序 chips、小表单或下一步卡片
45
+
46
+ **`submode/learn` 是概念型学习面板的参考素材(lesson schema + lesson.html)。** 它适合用 lesson JSON 生成概念卡、结构图、例子、主动回忆问题和下一步候选。若内容更像证明推导、代码跟踪、协议时序、调试排查、错因复盘或密集图谱,应生成自定义 HTML panel,而不是套它的模板。
47
+
48
+ ## 代码理解
49
+
50
+ 用于陌生包、模块、执行路径或依赖地图。
51
+
52
+ 可包含:
53
+
54
+ - 模块盒子和箭头
55
+ - 高亮 hot path
56
+ - 入口点
57
+ - 测试表面
58
+ - 风险标记
59
+
60
+ ## 计划和对比
61
+
62
+ 用于需要空间化比较多个方案的任务。
63
+
64
+ 可包含:
65
+
66
+ - 并排方案
67
+ - 取舍矩阵
68
+ - 时间线
69
+ - 风险表
70
+ - 推荐路径
71
+
72
+ ## 调试和审查
73
+
74
+ 用于事故时间线、失败测试、带注释 diff 和根因分析。
75
+
76
+ 可包含:
77
+
78
+ - 按时间排列的事件轨
79
+ - 失败命令和输出片段
80
+ - 可疑原因
81
+ - 验证清单
82
+
83
+ ## 输出规则
84
+
85
+ - 每个 panel 优先是一个完整 HTML 文档。
86
+ - CSS 和 JavaScript 内联。
87
+ - 除非用户明确允许,不要依赖远程资源。
88
+ - panel 必须能在 iframe 中响应式显示。
89
+ - 纯展示是一等输出。只有交互能帮助用户表达文字里难以描述的上下文时,才加入交互。
90
+ - 需要用户推进时用 `stage_choice`:选项发布在面板底部,点选会以一条真实用户消息到达会话。
91
+ 面板内没有旧原型那种 `postMessage` 回传通道,也不需要自己造一个“发送”控件。
92
+
93
+ - 不要自动回传 hover、拖拽或探索性点击:这些交互只更新面板本地状态。
@@ -0,0 +1,43 @@
1
+ # 默认视觉风格
2
+
3
+ 默认是“本地飞船控制台”风格:蓝灰科幻底、高对比黄色、粗黑漫画描边。它只是**可替换的皮肤**——任务语义优先,不合身就换。
4
+
5
+ ## 方向
6
+
7
+ - 保留硬朗黑色描边和卡通块面。
8
+ - 黄色是主识别色和注意力颜色,保持强对比。
9
+ - 背景使用更明亮的蓝灰/孔雀蓝,不回到大面积黑色。
10
+ - 科幻感来自细网格、扫描线、状态灯和 HUD 小标签,不使用夸张光晕。
11
+ - 小圆角,避免柔软 pill-heavy UI。
12
+ - 面板自己就是主区域:不要在一个面板里再模拟出“左侧栏 + 底部输入”的旧 shell 布局。
13
+
14
+ ## 色板
15
+
16
+ ```text
17
+ Line: #07111b
18
+ Base: #31566e
19
+ Deck: #2e4f67
20
+ Panel: #2e4c66
21
+ Rail: #3a5d78
22
+ Yellow: #ffd43b
23
+ Cream: #fff8d6
24
+ Orange: #ffb454
25
+ Cyan: #35d8ff
26
+ ```
27
+
28
+ ## 布局
29
+
30
+ ```text
31
+ 紧凑顶部状态栏(可选)
32
+ 主信息区(占满面板)
33
+ 底部选项栏:只在 stage_choice 时出现
34
+ ```
35
+
36
+ 面板内容不被强制套用固定风格:可以拥有自己的视觉语言,但默认应呼应蓝灰科幻底、黄色高亮和漫画描边。
37
+
38
+ 布局默认值:
39
+
40
+ - 如果做顶部状态栏,控制在 ~52px 以内。
41
+ - 主信息区占满面板;不要为未激活的选项预留空白。
42
+ - 辅助说明后置或可折叠,不占主信息的位置。
43
+ - 移动端优先保证主信息可读。
@@ -0,0 +1,17 @@
1
+ # code —— 代码展示与讲解(面板交互模式·DSH 版)
2
+
3
+ 内容组织遵循 `schemas/lesson.schema.json`(starter / snippets / exercises / annotations / hints);
4
+ 示例见 `examples/*.json`;纯展示面板起点模板 `templates/lab.html`(语法高亮 + 讲解通道)。
5
+
6
+ ## 投递(DSH 原生)
7
+
8
+ 1. 按 lesson schema 组织好一课的素材;
9
+ 2. 渲染为 self-contained HTML(可套 lab.html 的布局与讲解通道,不套死);
10
+ 3. `stage_panel`(title=课程名)投影;文字回复只留推理摘要与讲解结论;
11
+ 4. 需要学习者推进(看下一步 / 做练习 / 换例子)→ `stage_choice`;点选/作答 = 用户消息,无 wait。
12
+
13
+ ## 纪律
14
+
15
+ - 编程主战场仍是编辑器:本子模式只把代码作为讲解素材展示,不编辑、不编译、不在浏览器执行。
16
+ - 讲解回合对 panel 内回传的消息正常继续即可。
17
+ - `references/host-toolchains.md` 只在涉及宿主工具链(编译/运行路径)时查阅。
@@ -0,0 +1,36 @@
1
+ {
2
+ "schema_version": 1,
3
+ "id": "go-hello-channel",
4
+ "title": "Go:channel 接收一行消息",
5
+ "subtitle": "最小可运行并发切片",
6
+ "lang": "go",
7
+ "level": "intro",
8
+ "stage": "运行 → 读输出",
9
+ "summary": "启动 goroutine 发送字符串,主 goroutine 从 channel 接收并打印。",
10
+ "objectives": [
11
+ "运行成功看到 hello from goroutine",
12
+ "解释若去掉 <-ch 会怎样"
13
+ ],
14
+ "focus": {
15
+ "concept": "channel-recv",
16
+ "trap": "missing-receive-deadlock"
17
+ },
18
+ "starter": {
19
+ "filename": "main.go",
20
+ "code": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tch := make(chan string, 1)\n\tgo func() {\n\t\tch <- \"hello from goroutine\"\n\t}()\n\tmsg := <-ch\n\tfmt.Println(msg)\n}\n"
21
+ },
22
+ "run": {
23
+ "filename": "main.go"
24
+ },
25
+ "exercises": [
26
+ {
27
+ "id": "e1",
28
+ "type": "short",
29
+ "prompt": "为什么这里用带缓冲 channel(容量 1)也能工作?无缓冲时要注意什么?"
30
+ }
31
+ ],
32
+ "hints": [
33
+ "无缓冲 channel 需要发送与接收双方都准备好。",
34
+ "教学时优先保证 main 会接收,避免进程挂起触发 timeout。"
35
+ ]
36
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "schema_version": 1,
3
+ "id": "go-http-api-basics",
4
+ "title": "Go 调用 API:逐行注释版",
5
+ "subtitle": "每行都有注释,零基础看懂",
6
+ "summary": "Go 完全零基础:每行代码都有中文注释,先运行看输出,再改参数,最后解释。",
7
+ "domain": "deployment",
8
+ "lang": "go",
9
+ "level": "intro",
10
+ "objectives": [
11
+ "看懂 Go 基本语法",
12
+ "理解调 API 的代码结构"
13
+ ],
14
+ "starter": {
15
+ "filename": "main.go",
16
+ "code": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\nfunc main() {\n\trequestBody := map[string]interface{}{\n\t\t\"model\": \"gpt-4o-mini\",\n\t\t\"messages\": []map[string]string{\n\t\t\t{\"role\": \"user\", \"content\": \"你好\"},\n\t\t},\n\t}\n\tjsonBody, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\tfmt.Println(\"JSON失败:\", err)\n\t\treturn\n\t}\n\tfmt.Println(\"JSON:\", string(jsonBody))\n\turl := \"https://api.alice001.top/v1/chat/completions\"\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewReader(jsonBody))\n\tif err != nil {\n\t\tfmt.Println(\"构造请求失败:\", err)\n\t\treturn\n\t}\n\tfmt.Println(\"方法:\", req.Method)\n\tfmt.Println(\"地址:\", req.URL)\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer sk-test\")\n\tfmt.Println(\"头:\", req.Header)\n}\n"
17
+ },
18
+ "run": {},
19
+ "activities": [
20
+ {
21
+ "id": "predict-output",
22
+ "type": "predict",
23
+ "prompt": "运行前预测:JSON 那行输出长什么样?方法、地址各是什么?",
24
+ "required": true,
25
+ "before_run": true
26
+ },
27
+ {
28
+ "id": "run-and-observe",
29
+ "type": "trace",
30
+ "prompt": "点运行,看输出和预测对比。",
31
+ "required": false
32
+ },
33
+ {
34
+ "id": "change-content",
35
+ "type": "implement",
36
+ "prompt": "把 content 的 你好 改成 你是谁,再运行,看 JSON 哪行变了。",
37
+ "required": true
38
+ },
39
+ {
40
+ "id": "explain-steps",
41
+ "type": "explain",
42
+ "prompt": "用自己的话说:这段代码从上到下做了哪几件事?",
43
+ "required": true
44
+ }
45
+ ],
46
+ "checks": [
47
+ {
48
+ "id": "check-runs",
49
+ "label": "代码能编译运行",
50
+ "type": "exit_code",
51
+ "expected": 0
52
+ }
53
+ ],
54
+ "submission": {
55
+ "require_run": true,
56
+ "require_reflection": true
57
+ }
58
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "schema_version": 1,
3
+ "id": "py-agent-loop",
4
+ "title": "Agent:拆开模型、工具与状态循环",
5
+ "subtitle": "用可运行的 mock model 看清 Agent harness",
6
+ "summary": "这个最小 Agent 不调用真实模型,而是用确定性 mock 暴露控制结构:模型提出动作,harness 调工具,把观察写回状态,再让模型生成最终回答。",
7
+ "domain": "agent",
8
+ "lang": "python",
9
+ "level": "intro",
10
+ "stage": "预测 → 运行 → 跟踪状态 → 修改失败路径",
11
+ "objectives": [
12
+ "区分模型与 harness",
13
+ "跟踪 action/observation 状态",
14
+ "增加未知工具的失败处理"
15
+ ],
16
+ "prerequisites": [
17
+ "Python 字典、函数、循环"
18
+ ],
19
+ "starter": {
20
+ "filename": "agent.py",
21
+ "code": "def calculator(expression: str) -> str:\n left, right = expression.split(\"+\")\n return str(int(left) + int(right))\n\n\ndef mock_model(messages: list[dict[str, str]]) -> dict[str, str]:\n if not any(message[\"role\"] == \"tool\" for message in messages):\n return {\"type\": \"tool_call\", \"name\": \"calculator\", \"args\": \"20+22\"}\n observation = messages[-1][\"content\"]\n return {\"type\": \"final\", \"content\": f\"The answer is {observation}.\"}\n\n\ndef run_agent() -> None:\n messages = [{\"role\": \"user\", \"content\": \"What is 20 + 22?\"}]\n for step in range(3):\n action = mock_model(messages)\n print(f\"step={step} action={action['type']}\")\n if action[\"type\"] == \"final\":\n print(f\"answer={action['content']}\")\n return\n observation = calculator(action[\"args\"])\n print(f\"tool={action['name']} observation={observation}\")\n messages.append({\"role\": \"tool\", \"content\": observation})\n raise RuntimeError(\"agent exceeded step limit\")\n\n\nrun_agent()\n"
22
+ },
23
+ "run": {
24
+ "filename": "agent.py"
25
+ },
26
+ "activities": [
27
+ {
28
+ "id": "predict-trace",
29
+ "type": "predict",
30
+ "prompt": "运行前写出你预计会出现的 action、tool observation 和 final answer 顺序。",
31
+ "required": true,
32
+ "before_run": true
33
+ },
34
+ {
35
+ "id": "explain-harness",
36
+ "type": "explain",
37
+ "prompt": "哪些代码属于模型决策,哪些属于 Agent harness?",
38
+ "required": true
39
+ },
40
+ {
41
+ "id": "transfer-unknown-tool",
42
+ "type": "transfer",
43
+ "prompt": "让 mock model 请求 unknown_tool,并为 harness 增加可观察的错误结果,而不是直接崩溃。",
44
+ "required": true
45
+ }
46
+ ],
47
+ "checks": [
48
+ {
49
+ "id": "exit-ok",
50
+ "label": "Agent 循环正常结束",
51
+ "type": "exit_code",
52
+ "expected": 0
53
+ },
54
+ {
55
+ "id": "tool-observation",
56
+ "label": "轨迹包含工具观察",
57
+ "type": "stdout_contains",
58
+ "expected": "observation=42"
59
+ },
60
+ {
61
+ "id": "final-answer",
62
+ "label": "最终答案包含 42",
63
+ "type": "stdout_contains",
64
+ "expected": "answer=The answer is 42."
65
+ }
66
+ ],
67
+ "hints": [
68
+ "模型只提出结构化动作;真正调用函数的是 harness。",
69
+ "工具失败也应转成 observation,让下一轮模型能够处理。"
70
+ ],
71
+ "submission": {
72
+ "require_run": true,
73
+ "require_reflection": true
74
+ },
75
+ "next": [
76
+ "agent-tool-schema",
77
+ "agent-evaluation-loop"
78
+ ]
79
+ }