learn-anything-cli 0.2.1 → 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 +2 -0
- package/dist/cli/index.js +1 -1
- package/dist/core/command-generation/registry.js +1 -1
- package/dist/core/config.js +148 -20
- package/dist/core/init.js +8 -5
- package/dist/core/shared/skill-generation.js +25 -5
- package/dist/core/templates/skill-templates.d.ts +5 -5
- package/dist/core/templates/skill-templates.js +5 -5
- package/dist/core/templates/workflows/learn-explain.js +20 -14
- package/dist/core/templates/workflows/learn-practice.js +6 -4
- package/dist/i18n/index.js +1 -4
- package/package.json +21 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Learn Anything
|
|
2
2
|
|
|
3
|
+
[English](./README.md) | [中文](./README.zh-CN.md)
|
|
4
|
+
|
|
3
5
|
AI-powered recursive learning system — turns your AI coding assistant into an interactive tutor using the Socratic method and TDD-style exercises.
|
|
4
6
|
|
|
5
7
|
Generate skill and command files for **30+ AI tools** (Claude Code, Cursor, Gemini CLI, Codex, Copilot, Windsurf, etc.), then use slash commands to systematically master any technical topic.
|
package/dist/cli/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { claudeAdapter, cursorAdapter, codexAdapter, geminiAdapter
|
|
1
|
+
import { claudeAdapter, cursorAdapter, codexAdapter, geminiAdapter } from './adapters/index.js';
|
|
2
2
|
export class CommandAdapterRegistry {
|
|
3
3
|
static adapters = new Map();
|
|
4
4
|
static {
|
package/dist/core/config.js
CHANGED
|
@@ -1,33 +1,161 @@
|
|
|
1
1
|
export const LEARN_DIR = '.learn';
|
|
2
2
|
export const AI_TOOLS = [
|
|
3
|
-
{
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
{
|
|
4
|
+
name: 'Amazon Q Developer',
|
|
5
|
+
value: 'amazon-q',
|
|
6
|
+
available: true,
|
|
7
|
+
successLabel: 'Amazon Q Developer',
|
|
8
|
+
skillsDir: '.amazonq',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: 'Antigravity',
|
|
12
|
+
value: 'antigravity',
|
|
13
|
+
available: true,
|
|
14
|
+
successLabel: 'Antigravity',
|
|
15
|
+
skillsDir: '.agent',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Auggie (Augment CLI)',
|
|
19
|
+
value: 'auggie',
|
|
20
|
+
available: true,
|
|
21
|
+
successLabel: 'Auggie',
|
|
22
|
+
skillsDir: '.augment',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'Bob Shell',
|
|
26
|
+
value: 'bob',
|
|
27
|
+
available: true,
|
|
28
|
+
successLabel: 'Bob Shell',
|
|
29
|
+
skillsDir: '.bob',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'Claude Code',
|
|
33
|
+
value: 'claude',
|
|
34
|
+
available: true,
|
|
35
|
+
successLabel: 'Claude Code',
|
|
36
|
+
skillsDir: '.claude',
|
|
37
|
+
},
|
|
8
38
|
{ name: 'Cline', value: 'cline', available: true, successLabel: 'Cline', skillsDir: '.cline' },
|
|
9
39
|
{ name: 'Codex', value: 'codex', available: true, successLabel: 'Codex', skillsDir: '.codex' },
|
|
10
|
-
{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
40
|
+
{
|
|
41
|
+
name: 'ForgeCode',
|
|
42
|
+
value: 'forgecode',
|
|
43
|
+
available: true,
|
|
44
|
+
successLabel: 'ForgeCode',
|
|
45
|
+
skillsDir: '.forge',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'CodeBuddy Code (CLI)',
|
|
49
|
+
value: 'codebuddy',
|
|
50
|
+
available: true,
|
|
51
|
+
successLabel: 'CodeBuddy Code',
|
|
52
|
+
skillsDir: '.codebuddy',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Continue',
|
|
56
|
+
value: 'continue',
|
|
57
|
+
available: true,
|
|
58
|
+
successLabel: 'Continue (VS Code / JetBrains / Cli)',
|
|
59
|
+
skillsDir: '.continue',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'CoStrict',
|
|
63
|
+
value: 'costrict',
|
|
64
|
+
available: true,
|
|
65
|
+
successLabel: 'CoStrict',
|
|
66
|
+
skillsDir: '.cospec',
|
|
67
|
+
},
|
|
14
68
|
{ name: 'Crush', value: 'crush', available: true, successLabel: 'Crush', skillsDir: '.crush' },
|
|
15
|
-
{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
69
|
+
{
|
|
70
|
+
name: 'Cursor',
|
|
71
|
+
value: 'cursor',
|
|
72
|
+
available: true,
|
|
73
|
+
successLabel: 'Cursor',
|
|
74
|
+
skillsDir: '.cursor',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'Factory Droid',
|
|
78
|
+
value: 'factory',
|
|
79
|
+
available: true,
|
|
80
|
+
successLabel: 'Factory Droid',
|
|
81
|
+
skillsDir: '.factory',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'Gemini CLI',
|
|
85
|
+
value: 'gemini',
|
|
86
|
+
available: true,
|
|
87
|
+
successLabel: 'Gemini CLI',
|
|
88
|
+
skillsDir: '.gemini',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'GitHub Copilot',
|
|
92
|
+
value: 'github-copilot',
|
|
93
|
+
available: true,
|
|
94
|
+
successLabel: 'GitHub Copilot',
|
|
95
|
+
skillsDir: '.github',
|
|
96
|
+
detectionPaths: [
|
|
97
|
+
'.github/copilot-instructions.md',
|
|
98
|
+
'.github/instructions',
|
|
99
|
+
'.github/workflows/copilot-setup-steps.yml',
|
|
100
|
+
'.github/prompts',
|
|
101
|
+
'.github/agents',
|
|
102
|
+
'.github/skills',
|
|
103
|
+
'.github/.mcp.json',
|
|
104
|
+
],
|
|
105
|
+
},
|
|
19
106
|
{ name: 'iFlow', value: 'iflow', available: true, successLabel: 'iFlow', skillsDir: '.iflow' },
|
|
20
107
|
{ name: 'Junie', value: 'junie', available: true, successLabel: 'Junie', skillsDir: '.junie' },
|
|
21
|
-
{
|
|
108
|
+
{
|
|
109
|
+
name: 'Kilo Code',
|
|
110
|
+
value: 'kilocode',
|
|
111
|
+
available: true,
|
|
112
|
+
successLabel: 'Kilo Code',
|
|
113
|
+
skillsDir: '.kilocode',
|
|
114
|
+
},
|
|
22
115
|
{ name: 'Kiro', value: 'kiro', available: true, successLabel: 'Kiro', skillsDir: '.kiro' },
|
|
23
|
-
{
|
|
116
|
+
{
|
|
117
|
+
name: 'OpenCode',
|
|
118
|
+
value: 'opencode',
|
|
119
|
+
available: true,
|
|
120
|
+
successLabel: 'OpenCode',
|
|
121
|
+
skillsDir: '.opencode',
|
|
122
|
+
},
|
|
24
123
|
{ name: 'Pi', value: 'pi', available: true, successLabel: 'Pi', skillsDir: '.pi' },
|
|
25
124
|
{ name: 'Qoder', value: 'qoder', available: true, successLabel: 'Qoder', skillsDir: '.qoder' },
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
125
|
+
{
|
|
126
|
+
name: 'Lingma',
|
|
127
|
+
value: 'lingma',
|
|
128
|
+
available: true,
|
|
129
|
+
successLabel: 'Lingma',
|
|
130
|
+
skillsDir: '.lingma',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'Qwen Code',
|
|
134
|
+
value: 'qwen',
|
|
135
|
+
available: true,
|
|
136
|
+
successLabel: 'Qwen Code',
|
|
137
|
+
skillsDir: '.qwen',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'RooCode',
|
|
141
|
+
value: 'roocode',
|
|
142
|
+
available: true,
|
|
143
|
+
successLabel: 'RooCode',
|
|
144
|
+
skillsDir: '.roo',
|
|
145
|
+
},
|
|
29
146
|
{ name: 'Trae', value: 'trae', available: true, successLabel: 'Trae', skillsDir: '.trae' },
|
|
30
|
-
{
|
|
31
|
-
|
|
147
|
+
{
|
|
148
|
+
name: 'Windsurf',
|
|
149
|
+
value: 'windsurf',
|
|
150
|
+
available: true,
|
|
151
|
+
successLabel: 'Windsurf',
|
|
152
|
+
skillsDir: '.windsurf',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: 'AGENTS.md (works with Amp, VS Code, …)',
|
|
156
|
+
value: 'agents',
|
|
157
|
+
available: false,
|
|
158
|
+
successLabel: 'your AGENTS.md-compatible assistant',
|
|
159
|
+
},
|
|
32
160
|
];
|
|
33
161
|
//# sourceMappingURL=config.js.map
|
package/dist/core/init.js
CHANGED
|
@@ -5,8 +5,8 @@ import { createRequire } from 'module';
|
|
|
5
5
|
import { FileSystemUtils } from '../utils/file-system.js';
|
|
6
6
|
import { AI_TOOLS, LEARN_DIR } from './config.js';
|
|
7
7
|
import { isInteractive } from '../utils/interactive.js';
|
|
8
|
-
import { generateCommands, CommandAdapterRegistry
|
|
9
|
-
import { getSkillTemplates, getCommandContents, generateSkillContent
|
|
8
|
+
import { generateCommands, CommandAdapterRegistry } from './command-generation/index.js';
|
|
9
|
+
import { getSkillTemplates, getCommandContents, generateSkillContent } from './shared/index.js';
|
|
10
10
|
import { getMessages } from '../i18n/index.js';
|
|
11
11
|
const require = createRequire(import.meta.url);
|
|
12
12
|
const { version: VERSION } = require('../../package.json');
|
|
@@ -53,7 +53,10 @@ export class InitCommand {
|
|
|
53
53
|
}
|
|
54
54
|
if (selectedTools.length === 0) {
|
|
55
55
|
console.log(chalk.yellow(m.init.noToolsSelected));
|
|
56
|
-
console.log(chalk.dim(m.init.availableTools(availableTools
|
|
56
|
+
console.log(chalk.dim(m.init.availableTools(availableTools
|
|
57
|
+
.filter((t) => t.available)
|
|
58
|
+
.map((t) => t.value)
|
|
59
|
+
.join(', '))));
|
|
57
60
|
return;
|
|
58
61
|
}
|
|
59
62
|
// Generate skill files for each tool
|
|
@@ -77,7 +80,7 @@ export class InitCommand {
|
|
|
77
80
|
console.log(cmd(chalk.cyan('/learn:status [topic-name]'), chalk.dim(' — Visualize learning state as knowledge map heatmap')));
|
|
78
81
|
console.log('');
|
|
79
82
|
}
|
|
80
|
-
async detectTools(
|
|
83
|
+
async detectTools(_resolvedPath) {
|
|
81
84
|
return AI_TOOLS;
|
|
82
85
|
}
|
|
83
86
|
hasToolDir(resolvedPath, tool) {
|
|
@@ -93,7 +96,7 @@ export class InitCommand {
|
|
|
93
96
|
}
|
|
94
97
|
async interactiveSelect(tools) {
|
|
95
98
|
const availableTools = tools.filter((t) => t.available && t.skillsDir);
|
|
96
|
-
const {
|
|
99
|
+
const { checkbox } = await import('@inquirer/prompts');
|
|
97
100
|
// Auto-detect existing tool dirs and pre-select them
|
|
98
101
|
const detected = availableTools.filter((t) => this.hasToolDir(process.cwd(), t));
|
|
99
102
|
const detectedValues = new Set(detected.map((t) => t.value));
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { getLearnTopicSkillTemplate, getLearnExplainSkillTemplate, getLearnPracticeSkillTemplate, getLearnReviewSkillTemplate, getLearnStatusSkillTemplate, getLearnTopicCommandTemplate, getLearnExplainCommandTemplate, getLearnPracticeCommandTemplate, getLearnReviewCommandTemplate, getLearnStatusCommandTemplate, } from '../templates/skill-templates.js';
|
|
2
2
|
export function getSkillTemplates() {
|
|
3
3
|
return [
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
{
|
|
5
|
+
template: getLearnTopicSkillTemplate(),
|
|
6
|
+
dirName: 'learn-anything-topic',
|
|
7
|
+
workflowId: 'topic',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
template: getLearnExplainSkillTemplate(),
|
|
11
|
+
dirName: 'learn-anything-explain',
|
|
12
|
+
workflowId: 'explain',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
template: getLearnPracticeSkillTemplate(),
|
|
16
|
+
dirName: 'learn-anything-practice',
|
|
17
|
+
workflowId: 'practice',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
template: getLearnReviewSkillTemplate(),
|
|
21
|
+
dirName: 'learn-anything-review',
|
|
22
|
+
workflowId: 'review',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
template: getLearnStatusSkillTemplate(),
|
|
26
|
+
dirName: 'learn-anything-status',
|
|
27
|
+
workflowId: 'status',
|
|
28
|
+
},
|
|
9
29
|
];
|
|
10
30
|
}
|
|
11
31
|
export function getCommandTemplates() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { SkillTemplate, CommandTemplate } from './types.js';
|
|
2
|
-
export { getLearnTopicSkillTemplate, getLearnTopicCommandTemplate } from './workflows/learn-topic.js';
|
|
3
|
-
export { getLearnExplainSkillTemplate, getLearnExplainCommandTemplate } from './workflows/learn-explain.js';
|
|
4
|
-
export { getLearnPracticeSkillTemplate, getLearnPracticeCommandTemplate } from './workflows/learn-practice.js';
|
|
5
|
-
export { getLearnReviewSkillTemplate, getLearnReviewCommandTemplate } from './workflows/learn-review.js';
|
|
6
|
-
export { getLearnStatusSkillTemplate, getLearnStatusCommandTemplate } from './workflows/learn-status.js';
|
|
2
|
+
export { getLearnTopicSkillTemplate, getLearnTopicCommandTemplate, } from './workflows/learn-topic.js';
|
|
3
|
+
export { getLearnExplainSkillTemplate, getLearnExplainCommandTemplate, } from './workflows/learn-explain.js';
|
|
4
|
+
export { getLearnPracticeSkillTemplate, getLearnPracticeCommandTemplate, } from './workflows/learn-practice.js';
|
|
5
|
+
export { getLearnReviewSkillTemplate, getLearnReviewCommandTemplate, } from './workflows/learn-review.js';
|
|
6
|
+
export { getLearnStatusSkillTemplate, getLearnStatusCommandTemplate, } from './workflows/learn-status.js';
|
|
7
7
|
//# sourceMappingURL=skill-templates.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { getLearnTopicSkillTemplate, getLearnTopicCommandTemplate } from './workflows/learn-topic.js';
|
|
2
|
-
export { getLearnExplainSkillTemplate, getLearnExplainCommandTemplate } from './workflows/learn-explain.js';
|
|
3
|
-
export { getLearnPracticeSkillTemplate, getLearnPracticeCommandTemplate } from './workflows/learn-practice.js';
|
|
4
|
-
export { getLearnReviewSkillTemplate, getLearnReviewCommandTemplate } from './workflows/learn-review.js';
|
|
5
|
-
export { getLearnStatusSkillTemplate, getLearnStatusCommandTemplate } from './workflows/learn-status.js';
|
|
1
|
+
export { getLearnTopicSkillTemplate, getLearnTopicCommandTemplate, } from './workflows/learn-topic.js';
|
|
2
|
+
export { getLearnExplainSkillTemplate, getLearnExplainCommandTemplate, } from './workflows/learn-explain.js';
|
|
3
|
+
export { getLearnPracticeSkillTemplate, getLearnPracticeCommandTemplate, } from './workflows/learn-practice.js';
|
|
4
|
+
export { getLearnReviewSkillTemplate, getLearnReviewCommandTemplate, } from './workflows/learn-review.js';
|
|
5
|
+
export { getLearnStatusSkillTemplate, getLearnStatusCommandTemplate, } from './workflows/learn-status.js';
|
|
6
6
|
//# sourceMappingURL=skill-templates.js.map
|
|
@@ -93,7 +93,7 @@ Synthesize these signals to judge whether the user is beginner, intermediate, or
|
|
|
93
93
|
|
|
94
94
|
### Step 4: Record Learning Session
|
|
95
95
|
|
|
96
|
-
⚠️ CRITICAL —
|
|
96
|
+
⚠️ CRITICAL — Write the session file FIRST, then output its content to the conversation. This ensures zero drift between what the user sees and what gets saved. Do this BEFORE presenting sub-topics (Step 5).
|
|
97
97
|
|
|
98
98
|
**A) Determine the filename:**
|
|
99
99
|
|
|
@@ -108,9 +108,11 @@ Examples:
|
|
|
108
108
|
|
|
109
109
|
Match the language the user is learning in — don't force-translate.
|
|
110
110
|
|
|
111
|
-
**B)
|
|
111
|
+
**B) Compose then WRITE the session file FIRST — use the Write tool:**
|
|
112
112
|
|
|
113
|
-
|
|
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.
|
|
114
116
|
|
|
115
117
|
\`\`\`markdown
|
|
116
118
|
# [Concept Name] — Learning Session
|
|
@@ -124,31 +126,31 @@ The session file must contain the COMPLETE explanation you just delivered — no
|
|
|
124
126
|
|
|
125
127
|
## Positioning
|
|
126
128
|
|
|
127
|
-
[
|
|
129
|
+
[Write the one-sentence positioning — where this concept sits in the knowledge map]
|
|
128
130
|
|
|
129
131
|
## Analogy
|
|
130
132
|
|
|
131
|
-
[
|
|
133
|
+
[Write the real-world metaphor/analogy you composed]
|
|
132
134
|
|
|
133
135
|
## Core Mechanism
|
|
134
136
|
|
|
135
|
-
[
|
|
137
|
+
[Write the full "what and why" explanation in clear language, with all details]
|
|
136
138
|
|
|
137
139
|
## Code Example
|
|
138
140
|
|
|
139
141
|
\`\`\`[language]
|
|
140
|
-
[
|
|
142
|
+
[Write the complete code example, with all comments]
|
|
141
143
|
\`\`\`
|
|
142
144
|
|
|
143
145
|
[Include your walkthrough of the code — what each part does]
|
|
144
146
|
|
|
145
147
|
## Common Misconceptions
|
|
146
148
|
|
|
147
|
-
[
|
|
149
|
+
[Write the misconceptions you identified]
|
|
148
150
|
|
|
149
151
|
## Socratic Check
|
|
150
152
|
|
|
151
|
-
[
|
|
153
|
+
[Write the thinking questions you composed]
|
|
152
154
|
|
|
153
155
|
---
|
|
154
156
|
|
|
@@ -163,9 +165,13 @@ The session file must contain the COMPLETE explanation you just delivered — no
|
|
|
163
165
|
(Will be updated after the user chooses a sub-topic direction)
|
|
164
166
|
\`\`\`
|
|
165
167
|
|
|
166
|
-
**C)
|
|
168
|
+
**C) Output the file content to the conversation:**
|
|
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).
|
|
171
|
+
|
|
172
|
+
**D) Update state.yaml — use the Edit tool:**
|
|
167
173
|
|
|
168
|
-
Edit \`./.learn/topics/<topic-name>/state.yaml\`:
|
|
174
|
+
In the same turn, also use the Edit tool to update \`./.learn/topics/<topic-name>/state.yaml\`:
|
|
169
175
|
- If concept status is \`unexplored\`, update to \`in_progress\`
|
|
170
176
|
- Update \`last_session\` to current date
|
|
171
177
|
- If the user showed good understanding, increase \`confidence\` by 0.05 to 0.1
|
|
@@ -229,9 +235,9 @@ const COMMAND_CONTENT = `Use the learn-anything-explain skill to handle the user
|
|
|
229
235
|
Follow the workflow defined in the skill:
|
|
230
236
|
1. Load context: match topic → read knowledge map → read learning state
|
|
231
237
|
2. Assess user level (beginner/intermediate/advanced) and adjust teaching strategy
|
|
232
|
-
3.
|
|
233
|
-
4. CRITICAL —
|
|
234
|
-
5. Identify sub-topics as recursive entry points (only AFTER saving the session)`;
|
|
238
|
+
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.yaml with Edit.
|
|
240
|
+
5. Identify sub-topics as recursive entry points (only AFTER saving the session and echoing to conversation)`;
|
|
235
241
|
export function getLearnExplainSkillTemplate() {
|
|
236
242
|
return {
|
|
237
243
|
name: SKILL_NAME,
|
|
@@ -310,9 +310,11 @@ The user submits their code or answer in the chat. Review it using the framework
|
|
|
310
310
|
- Set status to needs_practice
|
|
311
311
|
- Note specific areas to focus on
|
|
312
312
|
|
|
313
|
-
|
|
313
|
+
⚠️ CRITICAL — Write the session file FIRST, then echo its content to the conversation. This ensures zero drift between what the user sees and what gets saved.
|
|
314
314
|
|
|
315
|
-
|
|
315
|
+
1. **Write the session file** — Use the Write tool to create \`./.learn/topics/<topic-name>/sessions/<concept-name>-practice-YYYY-MM-DD.md\` with the full feedback content (see Step 5 for naming rules and format). Include everything: your acknowledgment, Socratic follow-up questions, edge case discussion, code quality tips, and final assessment.
|
|
316
|
+
|
|
317
|
+
2. **Output the file content to the conversation** — After writing, present the exact content of the file you just wrote as your conversation response. Do NOT rephrase or regenerate it — copy the file content verbatim into your message.
|
|
316
318
|
|
|
317
319
|
### Step 5: Practice Session Record Format
|
|
318
320
|
|
|
@@ -375,8 +377,8 @@ Follow the workflow defined in the skill:
|
|
|
375
377
|
2. Assess difficulty level based on state.yaml (beginner/intermediate/challenge)
|
|
376
378
|
3. Project Mode: use Bash to create exercise dir → use Write to create README.md + starter file → tell user to open in IDE
|
|
377
379
|
Chat Mode: generate exercise in chat (background → requirements → code template → hint)
|
|
378
|
-
4. Project Mode: use Read to review user's code file → optionally use Bash to run it →
|
|
379
|
-
Chat Mode: review code submitted in chat →
|
|
380
|
+
4. Project Mode: use Read to review user's code file → optionally use Bash to run it → compose feedback → Write session file FIRST → echo file content verbatim to conversation + Edit to update state.yaml
|
|
381
|
+
Chat Mode: review code submitted in chat → compose feedback → Write session file FIRST → echo file content verbatim to conversation + Edit to update state.yaml`;
|
|
380
382
|
export function getLearnPracticeSkillTemplate() {
|
|
381
383
|
return {
|
|
382
384
|
name: SKILL_NAME,
|
package/dist/i18n/index.js
CHANGED
|
@@ -8,10 +8,7 @@ export function getMessages(locale) {
|
|
|
8
8
|
return messages[locale];
|
|
9
9
|
}
|
|
10
10
|
export function detectSystemLocale() {
|
|
11
|
-
const langEnv = process.env.LANG ||
|
|
12
|
-
process.env.LC_ALL ||
|
|
13
|
-
process.env.LANGUAGE ||
|
|
14
|
-
'';
|
|
11
|
+
const langEnv = process.env.LANG || process.env.LC_ALL || process.env.LANGUAGE || '';
|
|
15
12
|
if (/^zh[_-]/i.test(langEnv)) {
|
|
16
13
|
return 'zh-CN';
|
|
17
14
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "learn-anything-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "AI-powered recursive learning system with Socratic method and TDD practice",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"learn-anything-cli",
|
|
@@ -46,14 +46,24 @@
|
|
|
46
46
|
"test": "vitest run",
|
|
47
47
|
"test:watch": "vitest",
|
|
48
48
|
"lint": "eslint src/",
|
|
49
|
-
"
|
|
49
|
+
"format": "prettier --write .",
|
|
50
|
+
"format:check": "prettier --check .",
|
|
51
|
+
"prepublishOnly": "pnpm run build",
|
|
52
|
+
"prepare": "husky"
|
|
50
53
|
},
|
|
51
54
|
"engines": {
|
|
52
55
|
"node": ">=20.0.0"
|
|
53
56
|
},
|
|
54
57
|
"devDependencies": {
|
|
58
|
+
"@commitlint/cli": "^21.0.2",
|
|
59
|
+
"@commitlint/config-conventional": "^21.0.2",
|
|
60
|
+
"@eslint/js": "^10.0.1",
|
|
55
61
|
"@types/node": "^24.2.0",
|
|
56
62
|
"eslint": "^9.39.2",
|
|
63
|
+
"eslint-config-prettier": "^10.1.8",
|
|
64
|
+
"husky": "^9.1.7",
|
|
65
|
+
"lint-staged": "^17.0.7",
|
|
66
|
+
"prettier": "^3.8.3",
|
|
57
67
|
"typescript": "^5.9.3",
|
|
58
68
|
"typescript-eslint": "^8.50.1",
|
|
59
69
|
"vitest": "^3.2.4"
|
|
@@ -65,5 +75,14 @@
|
|
|
65
75
|
"fast-glob": "^3.3.3",
|
|
66
76
|
"yaml": "^2.8.2",
|
|
67
77
|
"zod": "^4.0.17"
|
|
78
|
+
},
|
|
79
|
+
"lint-staged": {
|
|
80
|
+
"*.{ts,js,mjs}": [
|
|
81
|
+
"eslint --fix",
|
|
82
|
+
"prettier --write"
|
|
83
|
+
],
|
|
84
|
+
"*.{json,md,yml,yaml}": [
|
|
85
|
+
"prettier --write"
|
|
86
|
+
]
|
|
68
87
|
}
|
|
69
88
|
}
|