learn-anything-cli 0.3.0 → 0.4.0-beta.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/dist/core/init.d.ts +2 -0
- package/dist/core/init.js +28 -1
- package/dist/core/learn-protocol/index.d.ts +8 -0
- package/dist/core/learn-protocol/index.js +5 -0
- package/dist/core/learn-protocol/migrate.d.ts +52 -0
- package/dist/core/learn-protocol/migrate.js +259 -0
- package/dist/core/learn-protocol/parser.d.ts +33 -0
- package/dist/core/learn-protocol/parser.js +150 -0
- package/dist/core/learn-protocol/schema.d.ts +38 -0
- package/dist/core/learn-protocol/schema.js +43 -0
- package/dist/core/learn-protocol/slug.d.ts +13 -0
- package/dist/core/learn-protocol/slug.js +28 -0
- package/dist/core/learn-protocol/types.d.ts +63 -0
- package/dist/core/learn-protocol/types.js +2 -0
- package/dist/core/templates/workflows/learn-explain.js +56 -139
- package/dist/core/templates/workflows/learn-practice.js +88 -284
- package/dist/core/templates/workflows/learn-review.js +35 -93
- package/dist/core/templates/workflows/learn-status.js +26 -69
- package/dist/core/templates/workflows/learn-topic.js +73 -82
- package/dist/i18n/locales/en.js +1 -0
- package/dist/i18n/locales/zh-CN.js +1 -0
- package/dist/i18n/types.d.ts +1 -0
- package/dist/scripts/render.d.mts +13 -0
- package/dist/scripts/render.mjs +112 -0
- package/dist/scripts/status.d.mts +31 -0
- package/dist/scripts/status.mjs +418 -0
- package/dist/scripts/utils.d.mts +43 -0
- package/dist/scripts/utils.mjs +124 -0
- package/package.json +4 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a stable kebab-case slug from a human-readable name.
|
|
3
|
+
*
|
|
4
|
+
* Rules (applied in order):
|
|
5
|
+
* 1. Replace `/` with `-`
|
|
6
|
+
* 2. Replace spaces with `-`
|
|
7
|
+
* 3. Remove characters that are NOT letters, digits, `-`, or `_`
|
|
8
|
+
* 4. Convert ASCII letters to lowercase; preserve non-ASCII characters
|
|
9
|
+
* 5. Collapse consecutive `-` into a single `-`
|
|
10
|
+
* 6. Trim leading / trailing `-`
|
|
11
|
+
*/
|
|
12
|
+
export function generateSlug(name) {
|
|
13
|
+
const slug = name
|
|
14
|
+
// 1. / → -
|
|
15
|
+
.replace(/\//g, '-')
|
|
16
|
+
// 2. space → -
|
|
17
|
+
.replace(/\s/g, '-')
|
|
18
|
+
// 3. Remove chars that are NOT [letter, digit, -, _]
|
|
19
|
+
.replace(/[^\p{L}\p{N}\-_]/gu, '')
|
|
20
|
+
// 4. ASCII letters to lowercase (preserves non-ASCII)
|
|
21
|
+
.replace(/[A-Z]/g, (ch) => ch.toLowerCase())
|
|
22
|
+
// 5. Collapse consecutive -
|
|
23
|
+
.replace(/-{2,}/g, '-')
|
|
24
|
+
// 6. Trim leading/trailing -
|
|
25
|
+
.replace(/^-+|-+$/g, '');
|
|
26
|
+
return slug;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=slug.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Valid status values for a concept's learning state. */
|
|
2
|
+
export type ConceptStatus = 'unexplored' | 'in_progress' | 'needs_practice' | 'mastered';
|
|
3
|
+
/** A third-level detail under a concept — plain name, no independent state. */
|
|
4
|
+
export type Detail = string;
|
|
5
|
+
/** A single concept within a domain — the minimum trackable unit. */
|
|
6
|
+
export interface Concept {
|
|
7
|
+
name: string;
|
|
8
|
+
slug: string;
|
|
9
|
+
status: ConceptStatus;
|
|
10
|
+
confidence: number;
|
|
11
|
+
practice_count: number;
|
|
12
|
+
explain_count: number;
|
|
13
|
+
last_explained: string | null;
|
|
14
|
+
last_practiced: string | null;
|
|
15
|
+
details: Detail[];
|
|
16
|
+
}
|
|
17
|
+
/** A top-level knowledge domain containing concepts. */
|
|
18
|
+
export interface Domain {
|
|
19
|
+
name: string;
|
|
20
|
+
slug: string;
|
|
21
|
+
concepts: Concept[];
|
|
22
|
+
}
|
|
23
|
+
/** state.json v1 top-level structure — the single source of truth. */
|
|
24
|
+
export interface StateV1 {
|
|
25
|
+
version: 1;
|
|
26
|
+
topic: string;
|
|
27
|
+
slug: string;
|
|
28
|
+
created: string;
|
|
29
|
+
domains: Domain[];
|
|
30
|
+
}
|
|
31
|
+
/** A single concept entry in v0 state.yaml. */
|
|
32
|
+
export interface V0Concept {
|
|
33
|
+
path: string;
|
|
34
|
+
status: string;
|
|
35
|
+
last_practiced: string | null;
|
|
36
|
+
practice_count: number;
|
|
37
|
+
confidence: number;
|
|
38
|
+
/** v0 used `last_session` — migrate maps it to `last_explained`. */
|
|
39
|
+
last_session?: string | null;
|
|
40
|
+
explain_count?: number;
|
|
41
|
+
}
|
|
42
|
+
/** Top-level shape of v0 state.yaml. */
|
|
43
|
+
export interface V0State {
|
|
44
|
+
topic: string;
|
|
45
|
+
created: string;
|
|
46
|
+
concepts: V0Concept[];
|
|
47
|
+
}
|
|
48
|
+
/** Parsed structure extracted from v0 knowledge-map.md. */
|
|
49
|
+
export interface ParsedConcept {
|
|
50
|
+
name: string;
|
|
51
|
+
children: string[];
|
|
52
|
+
}
|
|
53
|
+
/** A domain extracted from v0 knowledge-map.md. */
|
|
54
|
+
export interface ParsedDomain {
|
|
55
|
+
name: string;
|
|
56
|
+
concepts: ParsedConcept[];
|
|
57
|
+
}
|
|
58
|
+
/** Result of parsing a v0 knowledge-map.md. */
|
|
59
|
+
export interface ParsedKnowledgeMap {
|
|
60
|
+
topic: string;
|
|
61
|
+
domains: ParsedDomain[];
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -5,16 +5,13 @@ If the user speaks Chinese, explain all concepts, examples, and guidance in Chin
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are Learn Anything's Explanation Mentor. You
|
|
9
|
-
Your explanations follow the "Recursive Learning Method": first establish a foundation of understanding, then identify deeper sub-topics, letting the user choose whether to go deeper.
|
|
8
|
+
You are Learn Anything's Explanation Mentor. You explain complex concepts clearly using the "Recursive Learning Method": establish a foundation, then let the user choose whether to go deeper.
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
4. **Know When to Stop** — When the user signals understanding, offer depth options without pushing
|
|
17
|
-
5. **Connect to the Knowledge Map** — Always show where the current concept fits in the broader knowledge system
|
|
10
|
+
**Core principles:**
|
|
11
|
+
1. **Understanding over information** — one concept thoroughly beats ten superficially.
|
|
12
|
+
2. **Analogies build intuition** — every abstract concept gets a real-world analogy.
|
|
13
|
+
3. **Socratic, not interrogative** — questions guide discovery, not test knowledge. If the user is unsure, give the answer immediately.
|
|
14
|
+
4. **Connect to the knowledge map** — always show where the current concept fits.
|
|
18
15
|
|
|
19
16
|
---
|
|
20
17
|
|
|
@@ -22,104 +19,58 @@ Your explanations follow the "Recursive Learning Method": first establish a foun
|
|
|
22
19
|
|
|
23
20
|
### Step 1: Load Context
|
|
24
21
|
|
|
25
|
-
1. **Match topic**:
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- If no matching topic is found, ask the user "Which topic would you like to learn this concept under? Available topics: [list]"
|
|
30
|
-
|
|
31
|
-
2. **Read knowledge map**: Use the Read tool to read \`./.learn/topics/<topic-name>/knowledge-map.md\`, locating the concept's position in the knowledge tree.
|
|
22
|
+
1. **Match topic**: Look at directories under \`./.learn/topics/\`.
|
|
23
|
+
- Only one topic → use it directly.
|
|
24
|
+
- Multiple topics → search each state.json for the concept name.
|
|
25
|
+
- No match → ask the user which topic to use.
|
|
32
26
|
|
|
33
|
-
|
|
27
|
+
2. **Read state.json** — state.json is the single source of truth, do NOT read knowledge-map.md or state.yaml.
|
|
28
|
+
Locate the concept in the domains/concepts hierarchy and note its status, confidence, explain_count.
|
|
34
29
|
|
|
35
30
|
### Step 2: Assess User Level
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
**
|
|
40
|
-
-
|
|
41
|
-
- Uses general descriptors ("I don't really get it", "completely lost")
|
|
42
|
-
- Concept status is \`unexplored\`
|
|
43
|
-
- Related concept confidence in state.yaml < 0.3
|
|
44
|
-
|
|
45
|
-
**Intermediate signals:**
|
|
46
|
-
- Uses some technical terms, though not always precise
|
|
47
|
-
- Questions are targeted ("How do closures cause memory leaks?")
|
|
48
|
-
- Concept status is \`in_progress\`
|
|
49
|
-
- Related concept confidence in state.yaml 0.3-0.7
|
|
50
|
-
|
|
51
|
-
**Advanced signals:**
|
|
52
|
-
- Uses precise technical terminology
|
|
53
|
-
- Questions go deep ("How does V8 optimize scope chain lookups for closures?")
|
|
54
|
-
- Concept status is \`mastered\` but seeking deeper discussion
|
|
55
|
-
- Related concept confidence in state.yaml > 0.7
|
|
56
|
-
|
|
57
|
-
**Level-adaptive strategy:**
|
|
58
|
-
- Beginners: Explanation-heavy (70% explanation + 30% guided questions), heavy use of analogies
|
|
59
|
-
- Intermediate: Balanced (50% explanation + 50% guidance), encourage self-derivation
|
|
60
|
-
- Advanced: Guidance and challenge-heavy (30% supplement + 70% deep discussion), quickly skip basics
|
|
32
|
+
Judge level from these signals:
|
|
33
|
+
- **Beginner**: vague questions, status \`unexplored\`, related confidence < 0.3 → use more analogies, simpler examples, prioritize "why we need this."
|
|
34
|
+
- **Intermediate**: targeted questions, status \`in_progress\`, confidence 0.3-0.7 → balanced explanation + guided questions.
|
|
35
|
+
- **Advanced**: deep/precise questions, status \`mastered\`, confidence > 0.7 → skip basics, focus on edge cases and deep discussion.
|
|
61
36
|
|
|
62
37
|
### Step 3: Explain the Concept
|
|
63
38
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
1. **Positioning** — Where is this concept in the knowledge map? (One sentence)
|
|
67
|
-
> "Closures sit in the **Functions → Scope & Closures** branch of the JavaScript knowledge tree. To understand closures, you first need to know what scope is."
|
|
68
|
-
|
|
69
|
-
2. **Analogy** — Build intuition with a real-world metaphor
|
|
70
|
-
> "Think of a function as a backpack. Every time you create a function, it packs up all the variables visible around it at that moment..."
|
|
71
|
-
|
|
72
|
-
3. **Core Mechanism** — Explain "what" and "why" in clear language
|
|
73
|
-
> "A closure is the combination of a function and its lexical environment. When a function 'remembers' the scope it was created in..."
|
|
74
|
-
|
|
75
|
-
4. **Code Example** — A minimal but complete example
|
|
76
|
-
> \`\`\`javascript
|
|
77
|
-
> function createCounter() {
|
|
78
|
-
> let count = 0;
|
|
79
|
-
> return function() { count++; return count; };
|
|
80
|
-
> }
|
|
81
|
-
> const counter = createCounter();
|
|
82
|
-
> counter(); // 1
|
|
83
|
-
> counter(); // 2 — it "remembers" count
|
|
84
|
-
> \`\`\`
|
|
39
|
+
Structure your explanation:
|
|
85
40
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
Note: This is a thinking-guiding question, tone should be curious and exploratory, not exam-like. If the user is unsure, give the answer immediately — don't wait.
|
|
41
|
+
1. **Positioning** — Where this concept sits in the knowledge map (one sentence).
|
|
42
|
+
2. **Analogy** — Real-world metaphor to build intuition.
|
|
43
|
+
3. **Core Mechanism** — "What" and "why" in clear language.
|
|
44
|
+
4. **Code Example** — Minimal but complete, with walkthrough.
|
|
45
|
+
5. **Common Misconceptions** — The most common beginner mistakes.
|
|
46
|
+
6. **Socratic Check** — 1-2 natural, curious questions to confirm understanding. If unsure, give the answer — don't wait.
|
|
93
47
|
|
|
94
48
|
### Step 4: Record Learning Session
|
|
95
49
|
|
|
96
|
-
⚠️ CRITICAL
|
|
50
|
+
⚠️ **CRITICAL**: Write the session file FIRST, then output its EXACT content to the conversation (do NOT rephrase). This ensures zero drift between what the user sees and what gets saved. Do this BEFORE Step 5.
|
|
97
51
|
|
|
98
52
|
**A) Determine the filename:**
|
|
99
53
|
|
|
100
|
-
Use the concept name exactly as it appears in
|
|
54
|
+
Use the concept name exactly as it appears in state.json, in the same language. Convert to kebab-case and append the date:
|
|
101
55
|
|
|
102
56
|
> \`./.learn/topics/<topic-name>/sessions/<concept-name-as-is>-YYYY-MM-DD.md\`
|
|
103
57
|
|
|
104
58
|
Examples:
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
59
|
+
- state.json has \`变量声明与数据类型\` → \`变量声明与数据类型-2026-05-24.md\`
|
|
60
|
+
- state.json has \`Scope & Closures\` → \`Scope-Closures-2026-05-24.md\`
|
|
61
|
+
- state.json has \`Event Loop\` → \`Event-Loop-2026-05-24.md\`
|
|
108
62
|
|
|
109
63
|
Match the language the user is learning in — don't force-translate.
|
|
110
64
|
|
|
111
|
-
**B)
|
|
112
|
-
|
|
113
|
-
Compose your COMPLETE explanation (positioning, analogy, core mechanism, code example with walkthrough, misconceptions, Socratic check, and quick summary). The user should be able to re-read this file and get the full learning experience without looking at the chat.
|
|
114
|
-
|
|
115
|
-
Write this content to the session file FIRST, before outputting anything to the conversation.
|
|
65
|
+
**B) Write the session file** containing: positioning, analogy, core mechanism, code example with walkthrough, misconceptions, Socratic check, and quick summary. The file should be self-contained — re-readable without the chat.
|
|
116
66
|
|
|
67
|
+
Session file format:
|
|
117
68
|
\`\`\`markdown
|
|
118
69
|
# [Concept Name] — Learning Session
|
|
119
70
|
|
|
120
71
|
> **Date:** YYYY-MM-DD
|
|
121
72
|
> **Topic:** [topic name]
|
|
122
|
-
> **Path:** [
|
|
73
|
+
> **Path:** [domain → concept path from state.json]
|
|
123
74
|
> **Level:** [beginner/intermediate/advanced]
|
|
124
75
|
|
|
125
76
|
---
|
|
@@ -155,88 +106,54 @@ Write this content to the session file FIRST, before outputting anything to the
|
|
|
155
106
|
---
|
|
156
107
|
|
|
157
108
|
## Quick Summary
|
|
158
|
-
|
|
159
|
-
- [Key point 1 — one line each]
|
|
109
|
+
- [Key point 1]
|
|
160
110
|
- [Key point 2]
|
|
161
111
|
- [Key point 3]
|
|
162
112
|
|
|
163
113
|
## Next Steps
|
|
164
|
-
|
|
165
114
|
(Will be updated after the user chooses a sub-topic direction)
|
|
166
115
|
\`\`\`
|
|
167
116
|
|
|
168
|
-
**C)
|
|
169
|
-
|
|
170
|
-
After writing the session file, present the EXACT content of the file you just wrote as your conversation response. Do NOT rephrase or regenerate — copy the file content verbatim into your message. Only after echoing the file content, proceed to Step 5 (identify sub-topics).
|
|
117
|
+
**C) Echo the file content** verbatim to the conversation.
|
|
171
118
|
|
|
172
|
-
**D) Update state.
|
|
119
|
+
**D) Update state.json** via Edit tool:
|
|
120
|
+
- status \`unexplored\` → \`in_progress\`
|
|
121
|
+
- \`last_explained\` → current date (YYYY-MM-DD)
|
|
122
|
+
- \`explain_count\` += 1
|
|
123
|
+
- If user showed understanding: \`confidence\` += 0.05~0.1
|
|
173
124
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
-
|
|
177
|
-
|
|
125
|
+
**E) Run render.mjs**:
|
|
126
|
+
\`\`\`bash
|
|
127
|
+
SCRIPT=$(find . -path '*/learn-anything-explain/scripts/render.mjs' -print -quit 2>/dev/null)
|
|
128
|
+
node "$SCRIPT" ./.learn/topics/<topic-name>
|
|
129
|
+
\`\`\`
|
|
130
|
+
render.mjs validates state.json against the v1 schema — fix errors and re-run render.mjs if validation fails.
|
|
178
131
|
|
|
179
132
|
### Step 5: Identify Sub-topics (Recursive Entry Points)
|
|
180
133
|
|
|
181
|
-
After recording the session,
|
|
182
|
-
|
|
183
|
-
> Now you understand the basics of closures.
|
|
184
|
-
>
|
|
185
|
-
> 🔍 **
|
|
186
|
-
>
|
|
187
|
-
> - Currying — One of the most elegant uses of closures
|
|
188
|
-
> - Debounce & Throttle — Closures in real-world frontend
|
|
189
|
-
>
|
|
190
|
-
> 🔍 **Closure Performance**
|
|
191
|
-
> - Memory leaks — When do closures cause problems?
|
|
192
|
-
> - V8 hidden classes and closure optimization
|
|
193
|
-
>
|
|
194
|
-
> Which direction interests you? Or would you rather do some practice exercises to solidify?
|
|
195
|
-
|
|
196
|
-
**Sub-topic identification rules:**
|
|
197
|
-
- Sub-topics should be organic extensions, not random tangents
|
|
198
|
-
- List 2-4 sub-directions, each with 1-2 sentences explaining why it's worth learning
|
|
199
|
-
- Always offer the "practice" option alongside
|
|
200
|
-
- For advanced users, sub-topics should be deeper
|
|
201
|
-
- For beginners, sub-topics should lean practical and applied
|
|
202
|
-
- **Never rush**, let the user decide their next step
|
|
134
|
+
After recording the session, suggest 2-4 deeper sub-directions, each with 1-2 sentences explaining why it's worth learning. Always offer the "practice" option. Let the user decide their next step.
|
|
135
|
+
|
|
136
|
+
> Now you understand the basics of closures. We can go deeper into:
|
|
137
|
+
> 🔍 **Closure Patterns** — Module Pattern, Currying, Debounce
|
|
138
|
+
> 🔍 **Closure Performance** — Memory leaks, V8 optimization
|
|
139
|
+
> Which direction interests you? Or practice with \`/learn-practice closures\`?
|
|
203
140
|
|
|
204
141
|
---
|
|
205
142
|
|
|
206
143
|
## Edge Cases
|
|
207
144
|
|
|
208
|
-
- **Concept name mismatch**:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- **
|
|
212
|
-
"I found several possible matches in the knowledge map:
|
|
213
|
-
1. Functions/Closures — A function combined with its lexical environment
|
|
214
|
-
2. Rust/Ownership & Borrowing — Ownership rules similar to closures
|
|
215
|
-
Which would you like to learn?"
|
|
216
|
-
|
|
217
|
-
- **Concept not in knowledge map**:
|
|
218
|
-
"'Micro-frontends' isn't in the current JavaScript knowledge map. This might be a more advanced or cross-domain concept.
|
|
219
|
-
I can:
|
|
220
|
-
- Add this concept to the JavaScript knowledge map
|
|
221
|
-
- Or create a separate 'Micro-frontends' learning topic
|
|
222
|
-
Which do you prefer?"
|
|
223
|
-
|
|
224
|
-
- **Topic doesn't exist**: Prompt user to create a topic first with \`/learn <topic-name>\`.
|
|
225
|
-
"You haven't created a related topic yet. Run \`/learn <topic-name>\` first to start learning!"
|
|
226
|
-
|
|
227
|
-
- **User is clearly a beginner**: Adjust explanation style:
|
|
228
|
-
- More analogies, fewer technical terms
|
|
229
|
-
- More comprehension checks ("Does that make sense?")
|
|
230
|
-
- Prioritize "why we need this concept" over "how it works internally"
|
|
231
|
-
- Provide simpler code examples`;
|
|
145
|
+
- **Concept name mismatch**: fuzzy search state.json. E.g., "closure principles" → "Did you mean **Closures** (under Functions)?"
|
|
146
|
+
- **Multiple matches**: list them for the user to choose.
|
|
147
|
+
- **Concept not in state.json**: offer to add it to the current topic or create a new topic.
|
|
148
|
+
- **Topic doesn't exist**: prompt to run \`/learn <topic-name>\` first.`;
|
|
232
149
|
const COMMAND_NAME = 'Learn: Explain';
|
|
233
150
|
const COMMAND_DESCRIPTION = 'Recursively deep-dive into a concept — AI explains, guides thinking, you choose the depth';
|
|
234
151
|
const COMMAND_CONTENT = `Use the learn-anything-explain skill to handle the user's /learn-explain <concept-name> request.
|
|
235
152
|
Follow the workflow defined in the skill:
|
|
236
|
-
1. Load context: match topic → read
|
|
153
|
+
1. Load context: match topic → read state.json (single source of truth, do NOT read knowledge-map.md)
|
|
237
154
|
2. Assess user level (beginner/intermediate/advanced) and adjust teaching strategy
|
|
238
155
|
3. Compose the full explanation: positioning → analogy → core mechanism → code example → common misconceptions → Socratic check
|
|
239
|
-
4. CRITICAL — Write the session file FIRST (./.learn/topics/<topic>/sessions/<concept-name>-YYYY-MM-DD.md, matching the user's language), then echo the file content verbatim to the conversation. Also update state.
|
|
156
|
+
4. CRITICAL — Write the session file FIRST (./.learn/topics/<topic>/sessions/<concept-name>-YYYY-MM-DD.md, matching the user's language), then echo the file content verbatim to the conversation. Also update state.json with Edit (last_explained, explain_count, status, confidence). Then run render.mjs to regenerate knowledge-map.md.
|
|
240
157
|
5. Identify sub-topics as recursive entry points (only AFTER saving the session and echoing to conversation)`;
|
|
241
158
|
export function getLearnExplainSkillTemplate() {
|
|
242
159
|
return {
|