@rookiestar/eng-lang-tutor 1.0.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.

Potentially problematic release.


This version of @rookiestar/eng-lang-tutor might be problematic. Click here for more details.

@@ -0,0 +1,228 @@
1
+ # OpenClaw 部署指南
2
+
3
+ 本文档说明如何将 `eng-lang-tutor` skill 部署到 OpenClaw 服务器,并通过 Discord 等渠道使用。
4
+
5
+ ## 1. 前置条件
6
+
7
+ - 一台已安装 OpenClaw 的服务器
8
+ - OpenClaw Gateway 正在运行
9
+ - 已配置好 Discord Bot(可选其他渠道)
10
+
11
+ ## 2. 部署步骤
12
+
13
+ ### 2.1 上传 Skill 到服务器
14
+
15
+ **方式 A:使用 SCP 上传**
16
+
17
+ ```bash
18
+ # 在本地机器上执行
19
+ scp -r /path/to/eng-lang-tutor user@your-server:~/.openclaw/skills/
20
+ ```
21
+
22
+ **方式 B:使用 Git Clone**
23
+
24
+ ```bash
25
+ # 在服务器上执行
26
+ cd ~/.openclaw/skills/
27
+ git clone https://github.com/rookiestar/eng-lang-tutor.git
28
+ ```
29
+
30
+ ### 2.2 确认目录结构
31
+
32
+ 确保目录结构如下:
33
+
34
+ ```
35
+ ~/.openclaw/skills/eng-lang-tutor/
36
+ ├── SKILL.md # 核心技能文件(必需)
37
+ ├── scripts/ # Python 脚本
38
+ │ ├── state_manager.py
39
+ │ ├── scorer.py
40
+ │ ├── gamification.py
41
+ │ └── dedup.py
42
+ ├── templates/ # JSON Schema
43
+ ├── references/ # 参考资源
44
+ ├── examples/ # 示例文件
45
+ └── data/ # 运行时数据
46
+ ```
47
+
48
+ ### 2.3 验证 Skill 加载
49
+
50
+ ```bash
51
+ # 查看已加载的 skills
52
+ openclaw skills list
53
+
54
+ # 查看特定 skill 详情
55
+ openclaw skills info eng-lang-tutor
56
+ ```
57
+
58
+ ## 3. 配置 Discord 渠道
59
+
60
+ ### 3.1 创建 Discord Bot
61
+
62
+ 1. 访问 [Discord Developer Portal](https://discord.com/developers/applications)
63
+ 2. 创建新应用,命名为你的 Bot
64
+ 3. 进入 Bot 页面,创建 Bot 并获取 Token
65
+ 4. 启用 Message Content Intent
66
+
67
+ ### 3.2 配置 OpenClaw
68
+
69
+ ```bash
70
+ # 设置 Discord Token
71
+ openclaw config set discord.token YOUR_BOT_TOKEN
72
+
73
+ # 设置服务器 ID(可选)
74
+ openclaw config set discord.guildId YOUR_SERVER_ID
75
+ ```
76
+
77
+ ### 3.3 邀请 Bot 到服务器
78
+
79
+ 1. 在 Discord Developer Portal 中,进入 OAuth2 > URL Generator
80
+ 2. 选择 `bot` 和 `applications.commands` scope
81
+ 3. 选择所需权限(Send Messages, Read Messages 等)
82
+ 4. 复制生成的邀请链接并在浏览器中打开
83
+ 5. 选择要添加 Bot 的服务器
84
+
85
+ ### 3.4 完成配对
86
+
87
+ 首次与 Bot 对话时,会收到配对码:
88
+
89
+ ```bash
90
+ # 在服务器上执行配对
91
+ openclaw pairing approve discord YOUR_PAIRING_CODE
92
+ ```
93
+
94
+ ## 4. 使用 Skill
95
+
96
+ ### 4.1 通过 Discord 使用
97
+
98
+ 在 Discord 中与 Bot 对话,触发英语学习功能:
99
+
100
+ ```
101
+ # 触发今日知识点
102
+ 今天有什么英语知识点?
103
+
104
+ # 触发 Quiz
105
+ 给我出个 Quiz
106
+
107
+ # 查看学习进度
108
+ 我的学习进度怎么样?
109
+ ```
110
+
111
+ ### 4.2 设置定时推送(cron)
112
+
113
+ ```bash
114
+ # 编辑 crontab
115
+ crontab -e
116
+
117
+ # 添加每日定时推送(例如每天早上 9 点)
118
+ 0 9 * * * openclaw agent --channel discord --message "每日英语学习时间到!今天的知识点是:" --agent eng-lang-tutor
119
+ ```
120
+
121
+ ## 5. 进阶配置
122
+
123
+ ### 5.1 配置用户偏好
124
+
125
+ 在 Discord 中与 Bot 对话设置:
126
+
127
+ ```
128
+ 设置我的 CEFR 等级为 B2
129
+ 我的导师风格设为严谨
130
+ 调整主题配比,增加职场内容的比例
131
+ ```
132
+
133
+ ### 5.2 配置环境变量
134
+
135
+ 在服务器上设置 API 密钥(如果使用外部 LLM):
136
+
137
+ ```bash
138
+ # 编辑 OpenClaw 配置
139
+ openclaw config set model.provider anthropic
140
+ openclaw config set model.api_key YOUR_API_KEY
141
+ ```
142
+
143
+ ### 5.3 数据持久化
144
+
145
+ 确保 `data/` 目录有正确的写入权限:
146
+
147
+ ```bash
148
+ chmod -R 755 ~/.openclaw/skills/eng-lang-tutor/data/
149
+ ```
150
+
151
+ ## 6. 故障排查
152
+
153
+ ### 6.1 Skill 未加载
154
+
155
+ ```bash
156
+ # 检查 skill 目录
157
+ ls -la ~/.openclaw/skills/eng-lang-tutor/
158
+
159
+ # 检查 SKILL.md 是否存在
160
+ cat ~/.openclaw/skills/eng-lang-tutor/SKILL.md
161
+
162
+ # 重启 Gateway
163
+ openclaw gateway restart
164
+ ```
165
+
166
+ ### 6.2 Discord 无响应
167
+
168
+ ```bash
169
+ # 检查 Gateway 日志
170
+ openclaw logs
171
+
172
+ # 验证 Discord Token
173
+ openclaw config get discord.token
174
+
175
+ # 检查 Bot 状态
176
+ openclaw doctor
177
+ ```
178
+
179
+ ### 6.3 Python 脚本错误
180
+
181
+ ```bash
182
+ # 检查 Python 环境
183
+ python3 --version
184
+
185
+ # 安装依赖(如有需要)
186
+ pip3 install -r ~/.openclaw/skills/eng-lang-tutor/requirements.txt
187
+
188
+ # 手动测试脚本
189
+ cd ~/.openclaw/skills/eng-lang-tutor/scripts/
190
+ python3 state_manager.py --show
191
+ ```
192
+
193
+ ## 7. 架构图
194
+
195
+ ```
196
+ ┌─────────────────────────────────────────────────────────┐
197
+ │ Discord │
198
+ │ (用户交互) │
199
+ └─────────────────────────┬───────────────────────────────┘
200
+
201
+
202
+ ┌─────────────────────────────────────────────────────────┐
203
+ │ OpenClaw Gateway │
204
+ │ (消息路由 + 会话管理) │
205
+ └─────────────────────────┬───────────────────────────────┘
206
+
207
+
208
+ ┌─────────────────────────────────────────────────────────┐
209
+ │ eng-lang-tutor Skill │
210
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
211
+ │ │ SKILL.md │ │ scripts/ │ │ data/ │ │
212
+ │ │ (技能描述) │ │ (Python代码) │ │ (状态存储) │ │
213
+ │ └─────────────┘ └─────────────┘ └─────────────┘ │
214
+ └─────────────────────────────────────────────────────────┘
215
+
216
+
217
+ ┌─────────────────────────────────────────────────────────┐
218
+ │ LLM Provider │
219
+ │ (Claude/GPT/Qwen 等) │
220
+ └─────────────────────────────────────────────────────────┘
221
+ ```
222
+
223
+ ## 8. 参考链接
224
+
225
+ - [OpenClaw 官方文档](https://docs.openclaw.ai)
226
+ - [OpenClaw GitHub](https://github.com/openclaw/openclaw)
227
+ - [Discord 开发者门户](https://discord.com/developers/applications)
228
+ - [OpenClaw Skills 开发指南](https://docs.openclaw.ai/skills)
@@ -0,0 +1,130 @@
1
+ {
2
+ "date": "2026-02-20",
3
+ "topic_fingerprint": "workplace_touch_base",
4
+ "category": "oral",
5
+ "topic": "workplace",
6
+ "scene": {
7
+ "context": "You want to briefly connect with a colleague about a project or task. This is common in American workplaces for quick check-ins without scheduling a formal meeting.",
8
+ "formality": "neutral"
9
+ },
10
+ "expressions": [
11
+ {
12
+ "phrase": "Let's touch base",
13
+ "pronunciation_tip": "Sounds like 'touch base', not 'touch bases'. It comes from baseball!",
14
+ "usage_note": "Use this when you want to have a brief, informal check-in. Very common in American business culture."
15
+ },
16
+ {
17
+ "phrase": "Can we touch base on this?",
18
+ "pronunciation_tip": "Natural speed: 'Can-we-touch-base-on-this' flows together.",
19
+ "usage_note": "Add 'on this' when referring to a specific topic or project."
20
+ }
21
+ ],
22
+ "alternatives": [
23
+ "Let's sync up",
24
+ "Can we catch up briefly?",
25
+ "Let's check in",
26
+ "Do you have a minute to connect?"
27
+ ],
28
+ "chinglish_trap": {
29
+ "wrong": "Let's discuss together. / I want to communicate with you.",
30
+ "correct": "Let's touch base. / Can we sync up?",
31
+ "explanation": "Chinese speakers often translate directly, using 'discuss together' or 'communicate with you', which sounds formal and awkward in casual workplace settings. 'Touch base' is the natural American way to suggest a quick check-in."
32
+ },
33
+ "examples": [
34
+ {
35
+ "situation": "Morning standup meeting",
36
+ "dialogue": [
37
+ "A: Hey, I haven't seen the latest mockups. Can we touch base on those?",
38
+ "B: Sure, I'll swing by your desk after lunch.",
39
+ "A: Perfect, thanks!"
40
+ ]
41
+ },
42
+ {
43
+ "situation": "Email follow-up",
44
+ "dialogue": [
45
+ "A: I'm heading into a meeting, but let's touch base later about the client presentation.",
46
+ "B: Sounds good. I'll be free around 3.",
47
+ "A: Great, I'll ping you then."
48
+ ]
49
+ }
50
+ ],
51
+ "extended_learning": {
52
+ "related_phrases": [
53
+ "circle back - return to a topic later",
54
+ "loop in - include someone in communication",
55
+ "keep in the loop - keep someone informed"
56
+ ],
57
+ "cultural_note": "The phrase 'touch base' comes from baseball, where runners must touch each base to score. In business, it means making brief contact to share updates or align on goals. Americans use this several times per day in corporate settings!",
58
+ "common_mistakes": [
59
+ "Saying 'touch bases' (wrong plural)",
60
+ "Using it for long, formal meetings (it implies brevity)",
61
+ "Not following up after saying you'll 'touch base'"
62
+ ]
63
+ },
64
+ "references": {
65
+ "dictionary": {
66
+ "source": "merriam-webster",
67
+ "url": "https://www.merriam-webster.com/dictionary/touch%20base",
68
+ "note": "Official definition and usage examples"
69
+ },
70
+ "usage_context": {
71
+ "source": "youglish",
72
+ "url": "https://youglish.com/pronounce/touch%20base/english/us",
73
+ "note": "Hear it in 1000+ real YouTube videos"
74
+ },
75
+ "etymology": {
76
+ "source": "etymonline",
77
+ "url": "https://www.etymonline.com/word/touch",
78
+ "note": "From baseball: runners must touch each base to score"
79
+ }
80
+ },
81
+ "display": {
82
+ "title": "🏢 今日知识点 | Today's Knowledge Point",
83
+ "topic_tag": "🏷️ 主题: 职场口语 | Workplace Oral",
84
+ "formality_tag": "📊 正式度: 中性 | Neutral",
85
+ "scene_intro": "🎬 场景 | Scene",
86
+ "scene_text": "Quick check-in with colleagues without scheduling a formal meeting.",
87
+ "expressions_title": "💬 核心表达 | Key Expressions",
88
+ "expressions_formatted": [
89
+ {
90
+ "emoji": "✨",
91
+ "phrase": "**Let's touch base**",
92
+ "phrase_plain": "Let's touch base",
93
+ "pronunciation": "🔊 Sounds like 'touch base' (not 'bases')! From baseball ⚾",
94
+ "usage": "💡 Brief, informal check-in."
95
+ },
96
+ {
97
+ "emoji": "✨",
98
+ "phrase": "**Can we touch base on this?**",
99
+ "phrase_plain": "Can we touch base on this?",
100
+ "pronunciation": "🔊 Flows: Can-we-touch-base-ON-this.",
101
+ "usage": "💡 Use when referring to a specific topic."
102
+ }
103
+ ],
104
+ "alternatives_title": "🔄 其他说法 | Alternatives",
105
+ "alternatives_formatted": "• **Let's sync up**\n• **Can we catch up briefly?**\n• **Let's check in**\n• Do you have a minute to connect?",
106
+ "chinglish_title": "⚠️ Chinglish 陷阱 | Chinglish Trap",
107
+ "chinglish_formatted": "❌ Wrong: \"Let's discuss together.\"\n❌ Wrong: \"I want to communicate with you.\"\n✅ Correct: **Let's touch base!**\n✅ Correct: **Can we sync up?**\n\n📝 Why? Direct translation sounds formal and awkward. **Touch base** is the natural American way!",
108
+ "examples_title": "🗣️ 对话示例 | Example Dialogues",
109
+ "examples_formatted": [
110
+ {
111
+ "situation_emoji": "☕",
112
+ "situation": "Morning standup",
113
+ "dialogue": "💬 A: Hey, can we **touch base** on those mockups?\n💬 B: Sure, I'll swing by after lunch.\n💬 A: Perfect, thanks!",
114
+ "key_phrase_highlight": "**touch base**"
115
+ },
116
+ {
117
+ "situation_emoji": "📧",
118
+ "situation": "Email follow-up",
119
+ "dialogue": "💬 A: Let's **touch base** later about the presentation.\n💬 B: Sounds good. Free around 3?\n💬 A: Great, I'll ping you then!",
120
+ "key_phrase_highlight": "**touch base**"
121
+ }
122
+ ],
123
+ "extended_title": "📚 延伸学习 | Extended Learning",
124
+ "extended_formatted": "🔗 Related: **circle back** | **loop in** | **keep in the loop**\n\n🌎 Cultural Note: From baseball ⚾ - runners **touch** each **base** to score. Americans use this phrase several times a day!\n\n🚫 Common Mistakes:\n • Saying 'touch bases' ❌\n • Using for long meetings (it implies brevity)\n • Not following up",
125
+ "references_title": "📖 权威参考 | References",
126
+ "references_formatted": "📚 [Merriam-Webster](https://www.merriam-webster.com/dictionary/touch%20base) - Definition & examples\n🎬 [YouGlish](https://youglish.com/pronounce/touch%20base/english/us) - 1000+ YouTube videos\n📜 [Etymonline](https://www.etymonline.com/word/touch) - Word origin",
127
+ "footer": "───────────────────\n📅 2026-02-20 | 📝 Take the quiz to earn XP!"
128
+ },
129
+ "generated": true
130
+ }
@@ -0,0 +1,92 @@
1
+ {
2
+ "quiz_date": "2026-02-20",
3
+ "keypoint_fingerprint": "workplace_touch_base",
4
+ "questions": [
5
+ {
6
+ "id": 1,
7
+ "type": "multiple_choice",
8
+ "question": "Your colleague asks to 'touch base' about a project. What do they mean?",
9
+ "context": "You receive a Slack message: 'Hey, can we touch base on the Q4 report?'",
10
+ "options": [
11
+ "A. They want to have a formal presentation",
12
+ "B. They want to have a brief check-in conversation",
13
+ "C. They want to cancel the project",
14
+ "D. They want you to write the entire report"
15
+ ],
16
+ "correct_answer": "B",
17
+ "explanation": "'Touch base' means having a brief, informal check-in. It comes from baseball and implies a quick connection, not a formal meeting.",
18
+ "xp_value": 10,
19
+ "display": {
20
+ "type_emoji": "🔤",
21
+ "type_name": "选择题 | Multiple Choice",
22
+ "question_formatted": "💬 Your colleague asks to **'touch base'**. What do they mean?",
23
+ "context_formatted": "📱 Slack: \"Hey, can we **touch base** on the Q4 report?\"",
24
+ "options_formatted": [
25
+ "⬜ A. They want a formal presentation",
26
+ "⬜ B. They want a brief check-in",
27
+ "⬜ C. They want to cancel the project",
28
+ "⬜ D. They want you to write the report"
29
+ ],
30
+ "correct_feedback": "✅ Correct! **'Touch base'** = quick check-in ⚡",
31
+ "wrong_feedback": "❌ Not quite. **'Touch base'** means a brief, informal chat!",
32
+ "key_phrase": "**touch base**",
33
+ "xp_display": "💎 +10 XP"
34
+ }
35
+ },
36
+ {
37
+ "id": 2,
38
+ "type": "chinglish_fix",
39
+ "question": "Identify and fix the Chinglish expression in this email:",
40
+ "context": "\"Hi Team, I want to communicate with you about the project. Let's discuss together tomorrow.\"",
41
+ "correct_answer": "touch base / sync up / check in",
42
+ "explanation": "'Communicate with you' and 'discuss together' are direct translations that sound formal and awkward. Americans would say 'touch base' or 'sync up' instead.",
43
+ "xp_value": 15,
44
+ "display": {
45
+ "type_emoji": "🔧",
46
+ "type_name": "Chinglish 修正 | Fix the Chinglish",
47
+ "question_formatted": "🔧 Find and fix the Chinglish expressions:",
48
+ "email_formatted": "📧 Original email:\n\"Hi Team, I want to 'communicate with you' about the project. Let's 'discuss together' tomorrow.\"",
49
+ "hint": "💡 Hint: How would an American say this naturally?",
50
+ "correct_feedback": "✅ Fixed! **\"Let's touch base\"** or **\"Let's sync up\"** sounds much better! 🎉",
51
+ "wrong_feedback": "❌ 'Communicate with you' → **'touch base'**\n❌ 'Discuss together' → **'sync up'**",
52
+ "answer_formatted": "📝 Better: \"Hi Team, can we **touch base** about the project? Let's **sync up** tomorrow.\"",
53
+ "key_phrase": "**touch base / sync up**",
54
+ "xp_display": "💎 +15 XP"
55
+ }
56
+ },
57
+ {
58
+ "id": 3,
59
+ "type": "fill_blank",
60
+ "question": "Complete the sentence with the correct expression:",
61
+ "context": "You want to suggest a quick meeting with your manager. You say: 'I wanted to ___ on the project timeline.'",
62
+ "word_bank": ["touch base", "discuss together", "communicate"],
63
+ "correct_answer": "touch base",
64
+ "explanation": "'Touch base' is the natural American expression for suggesting a quick check-in. 'Discuss together' sounds awkward and redundant.",
65
+ "xp_value": 12,
66
+ "display": {
67
+ "type_emoji": "✏️",
68
+ "type_name": "填空题 | Fill in the Blank",
69
+ "question_formatted": "✏️ Complete the sentence:",
70
+ "context_formatted": "💼 To your manager: \"I wanted to **___** on the project timeline.\"",
71
+ "word_bank_formatted": "📦 Word Bank: [ **touch base** | 'discuss together' ❌ | 'communicate' ❌ ]",
72
+ "correct_feedback": "✅ Perfect! **'Touch base'** is the way to go! 🎯",
73
+ "wrong_feedback": "❌ 'Discuss together' sounds awkward. Try **'touch base'**!",
74
+ "key_phrase": "**touch base**",
75
+ "xp_display": "💎 +12 XP"
76
+ }
77
+ }
78
+ ],
79
+ "total_xp": 37,
80
+ "passing_score": 70,
81
+ "display": {
82
+ "header": "📝 今日测验 | Daily Quiz",
83
+ "date": "📅 2026-02-20",
84
+ "topic": "🏷️ Topic: **workplace_touch_base**",
85
+ "instructions": "🎯 3道小题,答对2道就过关!3 questions, get 2 right to pass!",
86
+ "progress_bar": "⬜⬜⬜ 0/3 questions",
87
+ "key_phrase_summary": "🔑 Key Phrase: **touch base** = 快速沟通/碰头",
88
+ "xp_summary": "💎 Total XP: 37 | 🏆 Pass: 2/3 correct",
89
+ "footer": "───────────────────\n💪 Good luck! 加油! 🚀"
90
+ },
91
+ "generated": true
92
+ }
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Post-install script for @rookiestar/eng-lang-tutor
5
+ *
6
+ * This script runs automatically after npm install and:
7
+ * 1. Installs the skill to ~/.openclaw/skills/eng-lang-tutor/
8
+ * 2. Migrates data from old data/ directory if needed (handled by Python code)
9
+ */
10
+
11
+ const path = require('path');
12
+ const fs = require('fs');
13
+ const os = require('os');
14
+
15
+ const SKILL_NAME = 'eng-lang-tutor';
16
+ const SKILLS_DIR = path.join(os.homedir(), '.openclaw', 'skills');
17
+ const SKILL_TARGET = path.join(SKILLS_DIR, SKILL_NAME);
18
+
19
+ // Get the package root directory
20
+ const PACKAGE_ROOT = path.resolve(__dirname, '..');
21
+
22
+ function install() {
23
+ console.log(`\n📦 Setting up ${SKILL_NAME} skill...\n`);
24
+
25
+ // Create skills directory if it doesn't exist
26
+ if (!fs.existsSync(SKILLS_DIR)) {
27
+ fs.mkdirSync(SKILLS_DIR, { recursive: true });
28
+ console.log(`✓ Created skills directory: ${SKILLS_DIR}`);
29
+ }
30
+
31
+ // Remove existing installation if present
32
+ if (fs.existsSync(SKILL_TARGET)) {
33
+ console.log(`✓ Updating existing installation...`);
34
+ fs.rmSync(SKILL_TARGET, { recursive: true, force: true });
35
+ }
36
+
37
+ // Create target directory
38
+ fs.mkdirSync(SKILL_TARGET, { recursive: true });
39
+
40
+ // Files and directories to copy
41
+ const itemsToCopy = [
42
+ 'scripts',
43
+ 'templates',
44
+ 'references',
45
+ 'examples',
46
+ 'docs',
47
+ 'SKILL.md',
48
+ 'CLAUDE.md',
49
+ 'README.md',
50
+ 'README_EN.md',
51
+ 'requirements.txt'
52
+ ];
53
+
54
+ // Copy each item
55
+ let copiedCount = 0;
56
+ for (const item of itemsToCopy) {
57
+ const sourcePath = path.join(PACKAGE_ROOT, item);
58
+ const targetPath = path.join(SKILL_TARGET, item);
59
+
60
+ if (!fs.existsSync(sourcePath)) {
61
+ continue;
62
+ }
63
+
64
+ try {
65
+ if (fs.statSync(sourcePath).isDirectory()) {
66
+ copyDir(sourcePath, targetPath);
67
+ } else {
68
+ fs.copyFileSync(sourcePath, targetPath);
69
+ }
70
+ copiedCount++;
71
+ } catch (err) {
72
+ console.error(` Warning: Could not copy ${item}: ${err.message}`);
73
+ }
74
+ }
75
+
76
+ console.log(`✓ Copied ${copiedCount} items to ${SKILL_TARGET}`);
77
+
78
+ // Show post-install message
79
+ console.log(`
80
+ ╔═══════════════════════════════════════════════════════════════╗
81
+ ║ Installation Complete! ║
82
+ ╠═══════════════════════════════════════════════════════════════╣
83
+ ║ ║
84
+ ║ ${SKILL_NAME} has been installed to: ║
85
+ ║ ${SKILL_TARGET}
86
+ ║ ║
87
+ ║ Next steps: ║
88
+ ║ 1. Install Python dependencies: ║
89
+ ║ pip install -r ${SKILL_TARGET}/requirements.txt ║
90
+ ║ ║
91
+ ║ 2. Restart your OpenClaw agent ║
92
+ ║ ║
93
+ ║ 3. Configure through onboarding (first time only) ║
94
+ ║ ║
95
+ ║ Data location: ║
96
+ ║ ~/.openclaw/state/eng-lang-tutor/ ║
97
+ ║ (or set OPENCLAW_STATE_DIR env var) ║
98
+ ║ ║
99
+ ║ Commands: ║
100
+ ║ npx eng-lang-tutor install - Reinstall skill ║
101
+ ║ npx eng-lang-tutor uninstall - Remove skill ║
102
+ ║ ║
103
+ ╚═══════════════════════════════════════════════════════════════╝
104
+ `);
105
+ }
106
+
107
+ function copyDir(src, dest) {
108
+ fs.mkdirSync(dest, { recursive: true });
109
+
110
+ const entries = fs.readdirSync(src, { withFileTypes: true });
111
+
112
+ for (const entry of entries) {
113
+ const srcPath = path.join(src, entry.name);
114
+ const destPath = path.join(dest, entry.name);
115
+
116
+ if (entry.isDirectory()) {
117
+ copyDir(srcPath, destPath);
118
+ } else {
119
+ fs.copyFileSync(srcPath, destPath);
120
+ }
121
+ }
122
+ }
123
+
124
+ // Run installation
125
+ try {
126
+ install();
127
+ } catch (err) {
128
+ console.error(`\n❌ Installation failed: ${err.message}`);
129
+ console.error('You may need to run the install manually:');
130
+ console.error(' npx eng-lang-tutor install\n');
131
+ process.exit(0); // Don't fail npm install
132
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@rookiestar/eng-lang-tutor",
3
+ "version": "1.0.0",
4
+ "description": "English language tutor skill for OpenClaw - Learn authentic American English expressions with gamification",
5
+ "keywords": [
6
+ "english",
7
+ "language-learning",
8
+ "tutor",
9
+ "openclaw",
10
+ "skill",
11
+ "gamification"
12
+ ],
13
+ "author": "rookiestar",
14
+ "license": "MIT",
15
+ "bin": {
16
+ "eng-lang-tutor": "./bin/eng-lang-tutor.js"
17
+ },
18
+ "scripts": {
19
+ "postinstall": "node npm-scripts/install.js"
20
+ },
21
+ "files": [
22
+ "bin/",
23
+ "npm-scripts/",
24
+ "scripts/",
25
+ "templates/",
26
+ "references/",
27
+ "examples/",
28
+ "docs/",
29
+ "SKILL.md",
30
+ "CLAUDE.md",
31
+ "README.md",
32
+ "README_EN.md",
33
+ "requirements.txt"
34
+ ],
35
+ "engines": {
36
+ "node": ">=14.0.0"
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/rookiestar/eng-lang-tutor.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/rookiestar/eng-lang-tutor/issues"
44
+ },
45
+ "homepage": "https://github.com/rookiestar/eng-lang-tutor#readme"
46
+ }