@chinhae/atw-cli 0.2.9 → 0.3.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/README.md +29 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +243 -123
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +18 -3
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts +0 -3
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +45 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/index.d.ts +8 -0
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +19 -0
- package/dist/configurators/index.js.map +1 -1
- package/dist/migrations/manifests/0.2.10.json +9 -0
- package/dist/migrations/manifests/0.3.0.json +3410 -0
- package/dist/templates/atw/config.yaml +4 -3
- package/dist/templates/atw/index.d.ts +2 -0
- package/dist/templates/atw/index.d.ts.map +1 -1
- package/dist/templates/atw/index.js +4 -0
- package/dist/templates/atw/index.js.map +1 -1
- package/dist/templates/atw/scripts/common/noob_mode.py +102 -0
- package/dist/templates/atw/scripts/common/session_context.py +7 -0
- package/dist/templates/atw/scripts/noob_mode.py +41 -0
- package/dist/templates/atw/scripts/tickets.py +66 -10
- package/dist/templates/atw/workflow.md +81 -17
- package/dist/templates/common/bundled-skills/atw-code-review/SKILL.md +4 -2
- package/dist/templates/common/bundled-skills/atw-codebase-design/DESIGN-IT-TWICE.md +1 -1
- package/dist/templates/common/bundled-skills/atw-diagnosing-bugs/SKILL.md +2 -2
- package/dist/templates/common/bundled-skills/atw-domain-modeling/{CONTEXT-FORMAT.md → GLOSSARY-FORMAT.md} +10 -10
- package/dist/templates/common/bundled-skills/atw-domain-modeling/SKILL.md +12 -12
- package/dist/templates/common/bundled-skills/atw-handoff/SKILL.md +1 -1
- package/dist/templates/common/bundled-skills/atw-implement/SKILL.md +6 -4
- package/dist/templates/common/bundled-skills/atw-implement-spec/SKILL.md +79 -0
- package/dist/templates/common/bundled-skills/atw-implement-spec/agents/openai.yaml +5 -0
- package/dist/templates/common/bundled-skills/atw-improve-codebase-architecture/SKILL.md +5 -5
- package/dist/templates/common/bundled-skills/atw-init-repo/SKILL.md +6 -4
- package/dist/templates/common/bundled-skills/atw-init-repo/references/domain.md +8 -8
- package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw-local.md +5 -2
- package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw.md +5 -2
- package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-github.md +5 -4
- package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-gitlab.md +2 -2
- package/dist/templates/common/bundled-skills/atw-init-repo/references/triage-labels.md +1 -1
- package/dist/templates/common/bundled-skills/atw-interview/SKILL.md +9 -1
- package/dist/templates/common/bundled-skills/atw-map/SKILL.md +5 -5
- package/dist/templates/common/bundled-skills/atw-noob-mode/SKILL.md +101 -0
- package/dist/templates/common/bundled-skills/atw-noob-mode/agents/openai.yaml +3 -0
- package/dist/templates/common/bundled-skills/atw-prototype/scripts/build_explorer.py +15 -9
- package/dist/templates/common/bundled-skills/atw-spec/SKILL.md +1 -1
- package/dist/templates/common/bundled-skills/atw-tdd/SKILL.md +2 -2
- package/dist/templates/common/bundled-skills/atw-tickets/SKILL.md +4 -4
- package/dist/templates/common/bundled-skills/atw-triage/SKILL.md +2 -2
- package/dist/templates/common/commands/continue.md +1 -1
- package/dist/templates/opencode/plugins/inject-workflow-state.js +29 -1
- package/dist/templates/shared-hooks/inject-subagent-context.py +29 -3
- package/dist/templates/shared-hooks/inject-workflow-state.py +27 -3
- package/dist/templates/shared-hooks/session-start.py +23 -0
- package/dist/templates/snow/SNOW.md +1 -1
- package/dist/utils/file-writer.d.ts.map +1 -1
- package/dist/utils/file-writer.js +29 -16
- package/dist/utils/file-writer.js.map +1 -1
- package/dist/utils/interactive-guard.d.ts +2 -2
- package/dist/utils/interactive-guard.js +2 -2
- package/dist/utils/lang.d.ts +14 -0
- package/dist/utils/lang.d.ts.map +1 -0
- package/dist/utils/lang.js +20 -0
- package/dist/utils/lang.js.map +1 -0
- package/dist/utils/optional-skills.d.ts +90 -0
- package/dist/utils/optional-skills.d.ts.map +1 -0
- package/dist/utils/optional-skills.js +266 -0
- package/dist/utils/optional-skills.js.map +1 -0
- package/dist/utils/template-fetcher.d.ts +6 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -1
- package/dist/utils/template-fetcher.js +1 -1
- package/dist/utils/template-fetcher.js.map +1 -1
- package/package.json +2 -2
- package/dist/templates/common/bundled-skills/atw-merge/SKILL.md +0 -14
- package/dist/templates/common/bundled-skills/atw-merge/agents/openai.yaml +0 -3
- package/dist/templates/common/bundled-skills/dejargonizer/SKILL.md +0 -133
- package/dist/templates/common/bundled-skills/noob-mode/SKILL.md +0 -175
- package/dist/templates/common/bundled-skills/noob-mode/references/examples.md +0 -418
- package/dist/templates/common/bundled-skills/noob-mode/references/glossary.md +0 -368
- package/dist/templates/common/bundled-skills/oxy-explanation/SKILL.md +0 -80
- package/dist/templates/common/bundled-skills/oxy-learning-hub/SKILL.md +0 -179
- package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/course.css +0 -1044
- package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/course.js +0 -184
- package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/lesson-template.html +0 -125
- package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/summary-template.html +0 -659
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/publishing.md +0 -64
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/summary-mode.md +0 -96
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/GLOSSARY-FORMAT.md +0 -30
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/LEARNING-RECORD-FORMAT.md +0 -42
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/MISSION-FORMAT.md +0 -50
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/RESOURCES-FORMAT.md +0 -40
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching-mode.md +0 -251
- package/dist/templates/common/bundled-skills/oxy-learning-hub/references/workspace.md +0 -112
- package/dist/templates/common/bundled-skills/oxy-learning-hub/scripts/validate_html.py +0 -198
- package/dist/templates/common/bundled-skills/show-me/SKILL.md +0 -127
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/* ─────────────────────────────────────────────────────────────
|
|
2
|
-
Oxy Learning Hub · 课程共享脚本
|
|
3
|
-
由 lesson-template.html 通过 {{ASSET_PREFIX}}course.js 引入。
|
|
4
|
-
依赖的约定(模板与课程正文需保持一致):
|
|
5
|
-
#theme-toggle / #theme-label 主题切换按钮
|
|
6
|
-
#lesson-status / #complete-lesson 完成状态
|
|
7
|
-
#progress-line / #read-fill / #read-label 阅读进度
|
|
8
|
-
#toc-list 目录容器(条目按正文小节自动生成)
|
|
9
|
-
main section[id] > h2 目录来源
|
|
10
|
-
[data-quiz] .quiz-option 互动选择题
|
|
11
|
-
.copy-response[data-target] 开放题复制
|
|
12
|
-
───────────────────────────────────────────────────────────── */
|
|
13
|
-
(() => {
|
|
14
|
-
const root = document.documentElement;
|
|
15
|
-
|
|
16
|
-
/* ── 主题切换 ────────────────────────────────────────
|
|
17
|
-
首帧的主题由模板 <head> 中的内联脚本决定,避免闪色;
|
|
18
|
-
这里只负责按钮状态与后续切换。 */
|
|
19
|
-
const toggle = document.querySelector("#theme-toggle");
|
|
20
|
-
const themeLabel = document.querySelector("#theme-label");
|
|
21
|
-
|
|
22
|
-
const renderTheme = () => {
|
|
23
|
-
if (!toggle) return;
|
|
24
|
-
const toDark = root.dataset.theme !== "dark"; // 点击后要切到的目标
|
|
25
|
-
if (themeLabel) themeLabel.textContent = toDark ? "深色" : "浅色";
|
|
26
|
-
toggle.setAttribute(
|
|
27
|
-
"aria-label",
|
|
28
|
-
toDark ? "切换到深色主题" : "切换到浅色主题",
|
|
29
|
-
);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
if (toggle) {
|
|
33
|
-
toggle.addEventListener("click", () => {
|
|
34
|
-
root.dataset.theme = root.dataset.theme === "dark" ? "light" : "dark";
|
|
35
|
-
localStorage.setItem("oxy-theme", root.dataset.theme);
|
|
36
|
-
renderTheme();
|
|
37
|
-
});
|
|
38
|
-
window
|
|
39
|
-
.matchMedia("(prefers-color-scheme: dark)")
|
|
40
|
-
.addEventListener("change", (e) => {
|
|
41
|
-
if (localStorage.getItem("oxy-theme")) return; // 手动选过就不再跟随系统
|
|
42
|
-
root.dataset.theme = e.matches ? "dark" : "light";
|
|
43
|
-
renderTheme();
|
|
44
|
-
});
|
|
45
|
-
renderTheme();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/* ── 完成状态 ──────────────────────────────────────── */
|
|
49
|
-
const key = `oxy-learning:${location.pathname}:${document.title}`;
|
|
50
|
-
const status = document.querySelector("#lesson-status");
|
|
51
|
-
const complete = document.querySelector("#complete-lesson");
|
|
52
|
-
|
|
53
|
-
const renderCompletion = () => {
|
|
54
|
-
if (!status || !complete) return;
|
|
55
|
-
const done = localStorage.getItem(key) === "complete";
|
|
56
|
-
const dot = status.querySelector(".dot") ?? document.createElement("span");
|
|
57
|
-
dot.className = "dot";
|
|
58
|
-
status.replaceChildren(dot, done ? "已完成,等待你的回答" : "尚未标记完成");
|
|
59
|
-
status.classList.toggle("is-done", done);
|
|
60
|
-
complete.textContent = done ? "取消完成标记" : "标记本课已完成";
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
if (complete) {
|
|
64
|
-
complete.addEventListener("click", () => {
|
|
65
|
-
if (localStorage.getItem(key) === "complete")
|
|
66
|
-
localStorage.removeItem(key);
|
|
67
|
-
else localStorage.setItem(key, "complete");
|
|
68
|
-
renderCompletion();
|
|
69
|
-
});
|
|
70
|
-
renderCompletion();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/* ── 目录:按正文小节自动生成,课程不必手写一份 ──── */
|
|
74
|
-
const tocList = document.querySelector("#toc-list");
|
|
75
|
-
const sections = [...document.querySelectorAll("main section[id]")];
|
|
76
|
-
|
|
77
|
-
if (tocList) {
|
|
78
|
-
sections.forEach((section) => {
|
|
79
|
-
const heading = section.querySelector("h2");
|
|
80
|
-
if (!heading) return;
|
|
81
|
-
const num = heading.querySelector(".n")?.textContent.trim() ?? "";
|
|
82
|
-
const text = [...heading.childNodes]
|
|
83
|
-
.filter(
|
|
84
|
-
(node) => !(node.nodeType === 1 && node.classList.contains("n")),
|
|
85
|
-
)
|
|
86
|
-
.map((node) => node.textContent)
|
|
87
|
-
.join("")
|
|
88
|
-
.trim();
|
|
89
|
-
|
|
90
|
-
const link = document.createElement("a");
|
|
91
|
-
link.href = `#${section.id}`;
|
|
92
|
-
link.textContent = num ? `${num} ${text}` : text;
|
|
93
|
-
|
|
94
|
-
const item = document.createElement("li");
|
|
95
|
-
item.append(link);
|
|
96
|
-
tocList.append(item);
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const tocLinks = [...document.querySelectorAll("#toc-list a")];
|
|
101
|
-
if (tocLinks.length) {
|
|
102
|
-
const observer = new IntersectionObserver(
|
|
103
|
-
(entries) => {
|
|
104
|
-
entries.forEach((entry) => {
|
|
105
|
-
if (!entry.isIntersecting) return;
|
|
106
|
-
tocLinks.forEach((link) =>
|
|
107
|
-
link.classList.toggle(
|
|
108
|
-
"is-active",
|
|
109
|
-
link.getAttribute("href") === `#${entry.target.id}`,
|
|
110
|
-
),
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
},
|
|
114
|
-
{ rootMargin: "-88px 0px -70% 0px" },
|
|
115
|
-
);
|
|
116
|
-
sections.forEach((section) => observer.observe(section));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/* ── 阅读进度 ──────────────────────────────────────── */
|
|
120
|
-
const line = document.querySelector("#progress-line");
|
|
121
|
-
const fill = document.querySelector("#read-fill");
|
|
122
|
-
const readLabel = document.querySelector("#read-label");
|
|
123
|
-
|
|
124
|
-
const renderProgress = () => {
|
|
125
|
-
const scrollable =
|
|
126
|
-
document.documentElement.scrollHeight - window.innerHeight;
|
|
127
|
-
const pct =
|
|
128
|
-
scrollable > 0
|
|
129
|
-
? Math.min(100, Math.round((window.scrollY / scrollable) * 100))
|
|
130
|
-
: 0;
|
|
131
|
-
if (line) line.style.width = `${pct}%`;
|
|
132
|
-
if (fill) fill.style.width = `${pct}%`;
|
|
133
|
-
if (readLabel) readLabel.textContent = `已读 ${pct}%`;
|
|
134
|
-
};
|
|
135
|
-
window.addEventListener("scroll", renderProgress, { passive: true });
|
|
136
|
-
renderProgress();
|
|
137
|
-
|
|
138
|
-
/* ── 互动选择题 ────────────────────────────────────── */
|
|
139
|
-
document.querySelectorAll("[data-quiz]").forEach((quiz) => {
|
|
140
|
-
const feedback = quiz.querySelector(".quiz-feedback");
|
|
141
|
-
quiz.querySelectorAll(".quiz-option").forEach((option) => {
|
|
142
|
-
option.addEventListener("click", () => {
|
|
143
|
-
const correct = option.dataset.correct === "true";
|
|
144
|
-
option.classList.toggle("is-correct", correct);
|
|
145
|
-
option.classList.toggle("is-wrong", !correct);
|
|
146
|
-
if (feedback) {
|
|
147
|
-
feedback.className = `quiz-feedback ${correct ? "ok" : "no"}`;
|
|
148
|
-
feedback.textContent = `${correct ? "回答正确。" : "再想一想。"} ${option.dataset.explanation || ""}`;
|
|
149
|
-
}
|
|
150
|
-
if (correct) {
|
|
151
|
-
quiz.querySelectorAll(".quiz-option").forEach((item) => {
|
|
152
|
-
item.disabled = true;
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
/* ── 开放题复制 ────────────────────────────────────── */
|
|
160
|
-
document.querySelectorAll(".copy-response").forEach((button) => {
|
|
161
|
-
const reset = () => {
|
|
162
|
-
button.textContent = "复制我的回答";
|
|
163
|
-
};
|
|
164
|
-
button.addEventListener("click", async () => {
|
|
165
|
-
const field = document.querySelector(
|
|
166
|
-
`#${CSS.escape(button.dataset.target)}`,
|
|
167
|
-
);
|
|
168
|
-
if (!field) return;
|
|
169
|
-
if (!field.value.trim()) {
|
|
170
|
-
button.textContent = "还没写内容";
|
|
171
|
-
setTimeout(reset, 1600);
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
try {
|
|
175
|
-
await navigator.clipboard.writeText(field.value);
|
|
176
|
-
} catch {
|
|
177
|
-
field.select();
|
|
178
|
-
document.execCommand("copy");
|
|
179
|
-
}
|
|
180
|
-
button.textContent = "已复制,粘贴回对话即可";
|
|
181
|
-
setTimeout(reset, 2200);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
})();
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="zh-CN" data-theme="light">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<meta name="color-scheme" content="light dark" />
|
|
7
|
-
<title>{{TITLE}}</title>
|
|
8
|
-
<script>
|
|
9
|
-
// 必须内联且前置:先定主题再渲染,避免首帧闪白/闪黑
|
|
10
|
-
(() => {
|
|
11
|
-
const saved = localStorage.getItem("oxy-theme");
|
|
12
|
-
const sys = window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
13
|
-
? "dark"
|
|
14
|
-
: "light";
|
|
15
|
-
document.documentElement.dataset.theme = saved || sys;
|
|
16
|
-
})();
|
|
17
|
-
</script>
|
|
18
|
-
<link rel="stylesheet" href="{{ASSET_PREFIX}}course.css" />
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
<header class="topbar" data-od-id="topbar">
|
|
22
|
-
<div class="topbar-inner">
|
|
23
|
-
<div class="brand">
|
|
24
|
-
<span class="brand-mark">O</span>Oxy Learning Hub
|
|
25
|
-
<span class="crumb">{{CRUMB}}</span>
|
|
26
|
-
</div>
|
|
27
|
-
<div class="top-right">
|
|
28
|
-
<button
|
|
29
|
-
class="theme-toggle"
|
|
30
|
-
id="theme-toggle"
|
|
31
|
-
type="button"
|
|
32
|
-
aria-label="切换到深色主题"
|
|
33
|
-
>
|
|
34
|
-
<svg
|
|
35
|
-
class="icon-sun"
|
|
36
|
-
viewBox="0 0 24 24"
|
|
37
|
-
fill="none"
|
|
38
|
-
stroke="currentColor"
|
|
39
|
-
stroke-width="1.8"
|
|
40
|
-
stroke-linecap="round"
|
|
41
|
-
aria-hidden="true"
|
|
42
|
-
>
|
|
43
|
-
<circle cx="12" cy="12" r="4.2" />
|
|
44
|
-
<path
|
|
45
|
-
d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.3 5.3l1.6 1.6M17.1 17.1l1.6 1.6M18.7 5.3l-1.6 1.6M6.9 17.1l-1.6 1.6"
|
|
46
|
-
/>
|
|
47
|
-
</svg>
|
|
48
|
-
<svg
|
|
49
|
-
class="icon-moon"
|
|
50
|
-
viewBox="0 0 24 24"
|
|
51
|
-
fill="none"
|
|
52
|
-
stroke="currentColor"
|
|
53
|
-
stroke-width="1.8"
|
|
54
|
-
stroke-linecap="round"
|
|
55
|
-
stroke-linejoin="round"
|
|
56
|
-
aria-hidden="true"
|
|
57
|
-
>
|
|
58
|
-
<path
|
|
59
|
-
d="M20.5 14.4A8.6 8.6 0 1 1 9.6 3.5a6.9 6.9 0 0 0 10.9 10.9Z"
|
|
60
|
-
/>
|
|
61
|
-
</svg>
|
|
62
|
-
<span id="theme-label">深色</span>
|
|
63
|
-
</button>
|
|
64
|
-
<div class="status" id="lesson-status" aria-live="polite">
|
|
65
|
-
<span class="dot"></span>尚未标记完成
|
|
66
|
-
</div>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
<div class="progress-track">
|
|
70
|
-
<div class="progress-line" id="progress-line"></div>
|
|
71
|
-
</div>
|
|
72
|
-
</header>
|
|
73
|
-
|
|
74
|
-
<div class="layout">
|
|
75
|
-
<!-- 目录条目由 course.js 依据正文 section[id] 自动生成,课程不需要手写 -->
|
|
76
|
-
<aside class="toc" data-od-id="toc">
|
|
77
|
-
<p class="toc-head">本课结构</p>
|
|
78
|
-
<ol id="toc-list"></ol>
|
|
79
|
-
<div class="toc-meter">
|
|
80
|
-
<span id="read-label">已读 0%</span>
|
|
81
|
-
<div class="bar"><div class="fill" id="read-fill"></div></div>
|
|
82
|
-
</div>
|
|
83
|
-
</aside>
|
|
84
|
-
|
|
85
|
-
<main data-od-id="lesson">
|
|
86
|
-
<p class="kicker">{{KICKER}}</p>
|
|
87
|
-
<h1>{{TITLE}}</h1>
|
|
88
|
-
<p class="subtitle">{{SUBTITLE}}</p>
|
|
89
|
-
<div class="facts">{{FACTS}}</div>
|
|
90
|
-
|
|
91
|
-
<!--
|
|
92
|
-
{{CONTENT}}:本课正文,按 teaching-mode.md 的结构写成若干
|
|
93
|
-
<section id="s-xxx"><h2><span class="n">01</span>小标题</h2>…</section>,
|
|
94
|
-
编号建议 01–07(目标 / 旧知识提取 / 核心解释 / 示例 / 先预测再揭晓 /
|
|
95
|
-
练习 / 来源),导航固定为下面的 08。
|
|
96
|
-
-->
|
|
97
|
-
{{CONTENT}}
|
|
98
|
-
|
|
99
|
-
<section id="s-nav" data-od-id="section-nav">
|
|
100
|
-
<h2><span class="n">08</span>课程导航</h2>
|
|
101
|
-
{{NAVIGATION}}
|
|
102
|
-
</section>
|
|
103
|
-
|
|
104
|
-
<div class="note" data-od-id="continue-chat" style="margin-top: 34px">
|
|
105
|
-
<span class="label">回到对话继续</span>
|
|
106
|
-
{{CONTINUE}}
|
|
107
|
-
</div>
|
|
108
|
-
|
|
109
|
-
<div class="finish" data-od-id="finish">
|
|
110
|
-
<button class="btn-primary" id="complete-lesson" type="button">
|
|
111
|
-
标记本课已完成
|
|
112
|
-
</button>
|
|
113
|
-
<p>
|
|
114
|
-
标记只记录进度,不代表已经掌握——真正的判断依据是你在对话里的表述。
|
|
115
|
-
</p>
|
|
116
|
-
</div>
|
|
117
|
-
</main>
|
|
118
|
-
|
|
119
|
-
<!-- {{ASIDE}}:随读卡片,若干个 <div class="aside-card"><h4>…</h4>…</div> -->
|
|
120
|
-
<aside class="aside-notes" data-od-id="aside-notes">{{ASIDE}}</aside>
|
|
121
|
-
</div>
|
|
122
|
-
|
|
123
|
-
<script defer src="{{ASSET_PREFIX}}course.js"></script>
|
|
124
|
-
</body>
|
|
125
|
-
</html>
|