@rookiestar/eng-lang-tutor 1.2.4 → 1.2.5

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 (52) hide show
  1. package/README.md +15 -0
  2. package/package.json +8 -6
  3. package/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  4. package/scripts/__pycache__/audio_composer.cpython-313.pyc +0 -0
  5. package/scripts/__pycache__/audio_converter.cpython-313.pyc +0 -0
  6. package/scripts/__pycache__/audio_enhancer.cpython-313.pyc +0 -0
  7. package/scripts/__pycache__/audio_utils.cpython-313.pyc +0 -0
  8. package/scripts/__pycache__/command_parser.cpython-313.pyc +0 -0
  9. package/scripts/__pycache__/constants.cpython-313.pyc +0 -0
  10. package/scripts/__pycache__/cron_push.cpython-313.pyc +0 -0
  11. package/scripts/__pycache__/dedup.cpython-313.pyc +0 -0
  12. package/scripts/__pycache__/error_notebook.cpython-313.pyc +0 -0
  13. package/scripts/__pycache__/feishu_voice.cpython-313.pyc +0 -0
  14. package/scripts/__pycache__/gamification.cpython-313.pyc +0 -0
  15. package/scripts/__pycache__/scorer.cpython-313.pyc +0 -0
  16. package/scripts/__pycache__/state_manager.cpython-313.pyc +0 -0
  17. package/scripts/__pycache__/utils.cpython-313.pyc +0 -0
  18. package/scripts/audio/__pycache__/__init__.cpython-313.pyc +0 -0
  19. package/scripts/audio/__pycache__/composer.cpython-313.pyc +0 -0
  20. package/scripts/audio/__pycache__/converter.cpython-313.pyc +0 -0
  21. package/scripts/audio/__pycache__/feishu_voice.cpython-313.pyc +0 -0
  22. package/scripts/audio/__pycache__/utils.cpython-313.pyc +0 -0
  23. package/scripts/audio/tts/__pycache__/__init__.cpython-313.pyc +0 -0
  24. package/scripts/audio/tts/__pycache__/base.cpython-313.pyc +0 -0
  25. package/scripts/audio/tts/__pycache__/manager.cpython-313.pyc +0 -0
  26. package/scripts/audio/tts/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  27. package/scripts/audio/tts/providers/__pycache__/edge.cpython-313.pyc +0 -0
  28. package/scripts/audio/tts/providers/__pycache__/xunfei.cpython-313.pyc +0 -0
  29. package/scripts/cli/__pycache__/__init__.cpython-313.pyc +0 -0
  30. package/scripts/cli/__pycache__/cli.cpython-313.pyc +0 -0
  31. package/scripts/cli/__pycache__/command_parser.cpython-313.pyc +0 -0
  32. package/scripts/core/__pycache__/__init__.cpython-313.pyc +0 -0
  33. package/scripts/core/__pycache__/constants.cpython-313.pyc +0 -0
  34. package/scripts/core/__pycache__/error_notebook.cpython-313.pyc +0 -0
  35. package/scripts/core/__pycache__/gamification.cpython-313.pyc +0 -0
  36. package/scripts/core/__pycache__/scorer.cpython-313.pyc +0 -0
  37. package/scripts/core/__pycache__/state_manager.cpython-313.pyc +0 -0
  38. package/scripts/release.py +255 -0
  39. package/scripts/scheduling/__pycache__/__init__.cpython-313.pyc +0 -0
  40. package/scripts/scheduling/__pycache__/cron_push.cpython-313.pyc +0 -0
  41. package/scripts/utils/__pycache__/__init__.cpython-313.pyc +0 -0
  42. package/scripts/utils/__pycache__/dedup.cpython-313.pyc +0 -0
  43. package/scripts/utils/__pycache__/helpers.cpython-313.pyc +0 -0
  44. package/.claude/settings.local.json +0 -22
  45. package/.gitignore +0 -32
  46. package/CHANGELOG.md +0 -88
  47. package/CLAUDE.md +0 -275
  48. package/backups/state_backup_20260227_063358.json +0 -47
  49. package/backups/state_backup_20260227_063405.json +0 -47
  50. package/backups/state_backup_20260227_064016.json +0 -47
  51. package/bin/eng-lang-tutor.js +0 -177
  52. package/docs/OPENCLAW_DEPLOYMENT.md +0 -241
package/README.md CHANGED
@@ -84,6 +84,21 @@ openclaw skills list
84
84
  openclaw skills info eng-lang-tutor
85
85
  ```
86
86
 
87
+ ### 卸载
88
+
89
+ ```bash
90
+ # 卸载 npm 包并清除所有数据(包括状态和媒体文件)
91
+ npm uninstall -g @rookiestar/eng-lang-tutor && rm -rf ~/.openclaw/state/eng-lang-tutor ~/.openclaw/media/eng-lang-tutor
92
+ ```
93
+
94
+ **如需保留学习数据,仅卸载软件:**
95
+
96
+ ```bash
97
+ npm uninstall -g @rookiestar/eng-lang-tutor
98
+ ```
99
+
100
+ > 注意:`~/.openclaw/state/eng-lang-tutor/` 存储学习进度、XP、连胜等数据;`~/.openclaw/media/eng-lang-tutor/` 存储生成的音频文件。
101
+
87
102
  **重启 Gateway:**
88
103
 
89
104
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rookiestar/eng-lang-tutor",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "description": "地道美式英语导师 - OpenClaw Skill for learning authentic American English",
5
5
  "main": "scripts/cli/cli.py",
6
6
  "bin": {
@@ -29,11 +29,13 @@
29
29
  },
30
30
  "homepage": "https://github.com/rookiestar/Skills/tree/main/eng-lang-tutor#readme",
31
31
  "files": [
32
- "**/*",
33
- "!tests/**",
34
- "!**/*.pyc",
35
- "!**/__pycache__/**",
36
- "!.DS_Store"
32
+ "scripts/",
33
+ "templates/",
34
+ "examples/",
35
+ "references/",
36
+ "SKILL.md",
37
+ "README.md",
38
+ "requirements.txt"
37
39
  ],
38
40
  "engines": {
39
41
  "node": ">=14.0.0"
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Release Script - Manages file visibility across local repo, remote repo, and npm package.
4
+
5
+ This script handles three layers:
6
+ 1. Local repo - All tracked files (managed by .gitignore)
7
+ 2. Remote repo - Public files only
8
+ 3. npm package - Minimal user-facing files
9
+
10
+ Usage:
11
+ python3 scripts/release.py --check # Show file distribution
12
+ python3 scripts/release.py --sync-remote # Sync to remote (dry-run)
13
+ python3 scripts/release.py --npm-pack # Create npm tarball
14
+ """
15
+
16
+ import argparse
17
+ import subprocess
18
+ import json
19
+ from pathlib import Path
20
+ from typing import Set
21
+
22
+ # Files/directories to EXCLUDE from remote repo (not publicly visible)
23
+ REMOTE_EXCLUDE = {
24
+ "tests/",
25
+ "package.json",
26
+ "package-lock.json",
27
+ "bin/",
28
+ "scripts/setup.py",
29
+ ".gitignore",
30
+ ".gitattributes",
31
+ ".npmignore",
32
+ "*.egg-info/",
33
+ ".pytest_cache/",
34
+ "__pycache__/",
35
+ ".coverage",
36
+ "htmlcov/",
37
+ ".tox/",
38
+ ".nox/",
39
+ ".claude/",
40
+ "*.pyc",
41
+ "*.pyo",
42
+ "*.tgz",
43
+ }
44
+
45
+ # Files/directories to EXCLUDE from npm package (in addition to REMOTE_EXCLUDE)
46
+ # npm package should be minimal - only what users need to run
47
+ NPM_EXCLUDE = REMOTE_EXCLUDE | {
48
+ "CLAUDE.md", # Development guide for Claude AI
49
+ "docs/", # Internal documentation
50
+ "examples/", # Sample files (not needed for runtime)
51
+ "references/", # Reference materials
52
+ "*.md", # All markdown except README.md
53
+ }
54
+
55
+ # Files that MUST be included in npm package
56
+ NPM_INCLUDE = {
57
+ "README.md", # Keep README for npm display
58
+ "package.json", # Required for npm
59
+ "requirements.txt", # Python dependencies
60
+ "scripts/", # All scripts (excluding setup.py)
61
+ "templates/", # Prompt templates
62
+ "SKILL.md", # Skill documentation
63
+ }
64
+
65
+
66
+ def get_tracked_files() -> Set[str]:
67
+ """Get all files tracked by git."""
68
+ result = subprocess.run(
69
+ ["git", "ls-files"],
70
+ capture_output=True,
71
+ text=True,
72
+ cwd=Path(__file__).parent.parent
73
+ )
74
+ return set(result.stdout.strip().split("\n"))
75
+
76
+
77
+ def should_exclude(path: str, exclude_patterns: Set[str]) -> bool:
78
+ """Check if a path should be excluded based on patterns."""
79
+ for pattern in exclude_patterns:
80
+ if pattern.endswith("/"):
81
+ if path.startswith(pattern) or "/" + pattern in path:
82
+ return True
83
+ elif pattern.startswith("*."):
84
+ if path.endswith(pattern[1:]):
85
+ return True
86
+ else:
87
+ if path == pattern or path.startswith(pattern + "/"):
88
+ return True
89
+ return False
90
+
91
+
92
+ def categorize_files():
93
+ """Categorize files into local, remote, and npm groups."""
94
+ tracked = get_tracked_files()
95
+
96
+ local_only = set()
97
+ remote_files = set()
98
+ npm_files = set()
99
+
100
+ for file in tracked:
101
+ # Skip empty strings
102
+ if not file:
103
+ continue
104
+
105
+ # Check if in remote exclude list
106
+ if should_exclude(file, REMOTE_EXCLUDE):
107
+ local_only.add(file)
108
+ else:
109
+ remote_files.add(file)
110
+
111
+ # Check if should be in npm package
112
+ if should_exclude(file, NPM_EXCLUDE):
113
+ # Check if explicitly included
114
+ included = False
115
+ for inc_pattern in NPM_INCLUDE:
116
+ if inc_pattern.endswith("/"):
117
+ if file.startswith(inc_pattern):
118
+ included = True
119
+ break
120
+ elif file == inc_pattern:
121
+ included = True
122
+ break
123
+
124
+ if included:
125
+ npm_files.add(file)
126
+ else:
127
+ npm_files.add(file)
128
+
129
+ return local_only, remote_files, npm_files
130
+
131
+
132
+ def show_distribution():
133
+ """Show file distribution across three layers."""
134
+ local_only, remote_files, npm_files = categorize_files()
135
+
136
+ print("=" * 60)
137
+ print("FILE DISTRIBUTION ACROSS THREE LAYERS")
138
+ print("=" * 60)
139
+
140
+ print(f"\n📦 LOCAL REPO ONLY ({len(local_only)} files)")
141
+ print("-" * 40)
142
+ for f in sorted(local_only):
143
+ print(f" {f}")
144
+
145
+ print(f"\n🌐 REMOTE REPO (public, {len(remote_files)} files)")
146
+ print("-" * 40)
147
+ for f in sorted(remote_files):
148
+ print(f" {f}")
149
+
150
+ print(f"\n📦 NPM PACKAGE ({len(npm_files)} files)")
151
+ print("-" * 40)
152
+ for f in sorted(npm_files):
153
+ print(f" {f}")
154
+
155
+ print("\n" + "=" * 60)
156
+ print(f"SUMMARY: Local={len(local_only) + len(remote_files)} | Remote={len(remote_files)} | npm={len(npm_files)}")
157
+ print("=" * 60)
158
+
159
+
160
+ def create_gitattributes():
161
+ """Create .gitattributes with export-ignore for local-only files."""
162
+ eng_lang_tutor_dir = Path(__file__).parent.parent
163
+ gitattributes_path = eng_lang_tutor_dir / ".gitattributes"
164
+
165
+ # Patterns to exclude from git archive (remote export)
166
+ export_ignore_patterns = [
167
+ "tests/",
168
+ ".pytest_cache/",
169
+ "*.pyc",
170
+ "*.pyo",
171
+ ".coverage",
172
+ "htmlcov/",
173
+ ".tox/",
174
+ ".nox/",
175
+ ".claude/",
176
+ "*.egg-info/",
177
+ "*.tgz",
178
+ ]
179
+
180
+ content = "# Files to exclude from git archive export\n"
181
+ content += "# These files are tracked locally but not exported to remote archives\n\n"
182
+
183
+ for pattern in export_ignore_patterns:
184
+ content += f"{pattern} export-ignore\n"
185
+
186
+ gitattributes_path.write_text(content)
187
+ print(f"✓ Created {gitattributes_path}")
188
+ print("\nNote: This affects 'git archive' only.")
189
+ print("For selective push to remote, consider using a separate public branch.")
190
+
191
+
192
+ def npm_pack():
193
+ """Create npm tarball with proper file filtering."""
194
+ eng_lang_tutor_dir = Path(__file__).parent.parent
195
+
196
+ # Update package.json files field for npm
197
+ package_json_path = eng_lang_tutor_dir / "package.json"
198
+
199
+ with open(package_json_path) as f:
200
+ package = json.load(f)
201
+
202
+ # Set files field to include only what we want
203
+ package["files"] = [
204
+ "scripts/",
205
+ "templates/",
206
+ "SKILL.md",
207
+ "README.md",
208
+ "requirements.txt",
209
+ ]
210
+
211
+ # Remove tests from npm package
212
+ if "!tests/**" in package.get("files", []):
213
+ pass # Already excluded
214
+
215
+ print("npm pack would include:")
216
+ print(json.dumps(package.get("files", []), indent=2))
217
+
218
+ print("\nRun the following to create npm package:")
219
+ print(f" cd {eng_lang_tutor_dir} && npm pack")
220
+
221
+
222
+ def main():
223
+ parser = argparse.ArgumentParser(
224
+ description="Manage file visibility across local repo, remote repo, and npm package"
225
+ )
226
+ parser.add_argument(
227
+ "--check",
228
+ action="store_true",
229
+ help="Show file distribution across three layers"
230
+ )
231
+ parser.add_argument(
232
+ "--create-gitattributes",
233
+ action="store_true",
234
+ help="Create .gitattributes with export-ignore rules"
235
+ )
236
+ parser.add_argument(
237
+ "--npm-pack",
238
+ action="store_true",
239
+ help="Show npm pack configuration"
240
+ )
241
+
242
+ args = parser.parse_args()
243
+
244
+ if args.check:
245
+ show_distribution()
246
+ elif args.create_gitattributes:
247
+ create_gitattributes()
248
+ elif args.npm_pack:
249
+ npm_pack()
250
+ else:
251
+ parser.print_help()
252
+
253
+
254
+ if __name__ == "__main__":
255
+ main()
@@ -1,22 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(python3 -m pytest:*)",
5
- "Bash(pytest:*)",
6
- "Bash(find:*)",
7
- "Bash(git add:*)",
8
- "Bash(git commit:*)",
9
- "Bash(git push)",
10
- "mcp__brave-search__brave_web_search",
11
- "mcp__web-search-prime__webSearchPrime",
12
- "mcp__zread__get_repo_structure",
13
- "mcp__zread__read_file",
14
- "mcp__zread__search_doc",
15
- "mcp__web-reader__webReader",
16
- "WebSearch",
17
- "mcp__fetch__fetch",
18
- "Bash(wc:*)",
19
- "Bash(python3 -m py_compile:*)"
20
- ]
21
- }
22
- }
package/.gitignore DELETED
@@ -1,32 +0,0 @@
1
- # Python
2
- __pycache__/
3
- *.py[cod]
4
- *$py.class
5
- *.so
6
- .Python
7
- .venv/
8
- venv/
9
- ENV/
10
-
11
- # IDE
12
- .idea/
13
- .vscode/
14
- *.swp
15
- *.swo
16
-
17
- # OS
18
- .DS_Store
19
- Thumbs.db
20
-
21
- # Backups
22
- backups/
23
- *.bak
24
-
25
- # User data
26
- data/state.json
27
- data/logs/
28
- data/daily/
29
-
30
- # npm
31
- node_modules/
32
- *.tgz
package/CHANGELOG.md DELETED
@@ -1,88 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- ## [1.2.4] - 2026-02-27
6
-
7
- ### Fixed
8
- - **TTS voice selection**: Audio composer now automatically selects appropriate voices based on TTS provider
9
- - Edge-TTS: `en-US-JennyNeural`, `en-US-EricNeural`
10
- - XunFei: `catherine`, `henry`
11
- - **CLI import paths**: Fixed broken imports in `state_manager.py` CLI module
12
-
13
- ### Changed
14
- - **npm package**: Removed automatic `pip install` from postinstall script
15
- - Added `eng-lang-tutor-setup` CLI tool for manual dependency installation
16
- - Supports `--venv`, `--user`, and `--check` options
17
- - **Test coverage**: Added 38 new tests covering:
18
- - `scripts/audio/utils.py` (6 tests)
19
- - `scripts/audio/converter.py` (16 tests)
20
- - `scripts/utils/helpers.py` (16 tests)
21
- - **Test fixes**: Fixed pre-existing test failures in CLI and TTS modules
22
-
23
- ## [1.2.3] - 2026-02-27
24
-
25
- ### Changed
26
- - Version bump for npm publishing
27
-
28
- ## [1.2.0] - 2026-02-27
29
-
30
- ### Changed
31
- - Initial npm package setup
32
-
33
- ## [1.0.1] - 2025-02-27
34
-
35
- ### Fixed
36
- - **TTS voice selection**: Audio composer now automatically selects appropriate voices based on TTS provider
37
- - Edge-TTS: `en-US-JennyNeural`, `en-US-EricNeural`
38
- - XunFei: `catherine`, `henry`
39
- - **CLI import paths**: Fixed broken imports in `state_manager.py` CLI module
40
-
41
- ### Changed
42
- - **npm package**: Removed automatic `pip install` from postinstall script
43
- - Added `eng-lang-tutor-setup` CLI tool for manual dependency installation
44
- - Supports `--venv`, `--user`, and `--check` options
45
- - **Test coverage**: Added 38 new tests covering:
46
- - `scripts/audio/utils.py` (6 tests)
47
- - `scripts/audio/converter.py` (16 tests)
48
- - `scripts/utils/helpers.py` (16 tests)
49
- - **Test fixes**: Fixed pre-existing test failures in CLI and TTS modules
50
-
51
- ## [1.0.1] - 2025-02-27
52
-
53
- ### Changed
54
- - Version bump for npm publishing (1.0.0 was previously unpublished)
55
-
56
- ## [1.0.0] - 2025-02-26
57
-
58
- Initial release.
59
-
60
- ### Added
61
-
62
- **Core Features:**
63
- - Daily knowledge points with authentic American English expressions
64
- - Quiz system with 4 question types (multiple choice, Chinglish fix, fill blank, dialogue completion)
65
- - Duolingo-style gamification (XP, levels 1-20, streaks, badges, gems)
66
- - Error notebook for tracking and reviewing mistakes
67
- - 14-day content deduplication
68
-
69
- **CEFR Support:**
70
- - Complete CEFR level definitions (A1-C2) with Can-Do Statements
71
- - 12 sample JSON files covering all 6 CEFR levels
72
- - Content difficulty adjusted by user's CEFR level
73
-
74
- **Audio:**
75
- - TTS audio generation (Edge-TTS default, XunFei optional)
76
- - Async audio generation with background threading
77
- - Context manager pattern for reliable temp file cleanup
78
-
79
- **Configuration:**
80
- - 7-step onboarding flow
81
- - Initialization guard check before content generation
82
- - Centralized configuration constants
83
- - Prompt version control via `_meta.prompt_version` field
84
-
85
- **Documentation:**
86
- - SKILL.md, README.md, CLAUDE.md
87
- - OpenClaw deployment guide
88
- - Prompt templates (keypoint generation, quiz generation, etc.)