@rookiestar/eng-lang-tutor 1.0.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/.claude/settings.local.json +22 -0
- package/.gitignore +32 -0
- package/CHANGELOG.md +37 -0
- package/CLAUDE.md +275 -0
- package/README.md +369 -0
- package/SKILL.md +613 -0
- package/bin/eng-lang-tutor.js +177 -0
- package/docs/OPENCLAW_DEPLOYMENT.md +241 -0
- package/examples/sample_keypoint_a1.json +112 -0
- package/examples/sample_keypoint_a2.json +124 -0
- package/examples/sample_keypoint_b1.json +135 -0
- package/examples/sample_keypoint_b2.json +137 -0
- package/examples/sample_keypoint_c1.json +134 -0
- package/examples/sample_keypoint_c2.json +141 -0
- package/examples/sample_quiz_a1.json +94 -0
- package/examples/sample_quiz_a2.json +94 -0
- package/examples/sample_quiz_b1.json +92 -0
- package/examples/sample_quiz_b2.json +94 -0
- package/examples/sample_quiz_c1.json +94 -0
- package/examples/sample_quiz_c2.json +104 -0
- package/package.json +41 -0
- package/references/resources.md +292 -0
- package/requirements.txt +16 -0
- package/scripts/__init__.py +28 -0
- package/scripts/audio/__init__.py +23 -0
- package/scripts/audio/composer.py +367 -0
- package/scripts/audio/converter.py +331 -0
- package/scripts/audio/feishu_voice.py +404 -0
- package/scripts/audio/tts/__init__.py +30 -0
- package/scripts/audio/tts/base.py +166 -0
- package/scripts/audio/tts/manager.py +306 -0
- package/scripts/audio/tts/providers/__init__.py +12 -0
- package/scripts/audio/tts/providers/edge.py +111 -0
- package/scripts/audio/tts/providers/xunfei.py +205 -0
- package/scripts/audio/utils.py +63 -0
- package/scripts/cli/__init__.py +7 -0
- package/scripts/cli/cli.py +229 -0
- package/scripts/cli/command_parser.py +336 -0
- package/scripts/core/__init__.py +30 -0
- package/scripts/core/constants.py +125 -0
- package/scripts/core/error_notebook.py +308 -0
- package/scripts/core/gamification.py +405 -0
- package/scripts/core/scorer.py +295 -0
- package/scripts/core/state_manager.py +814 -0
- package/scripts/eng-lang-tutor +16 -0
- package/scripts/scheduling/__init__.py +6 -0
- package/scripts/scheduling/cron_push.py +229 -0
- package/scripts/utils/__init__.py +12 -0
- package/scripts/utils/dedup.py +331 -0
- package/scripts/utils/helpers.py +82 -0
- package/templates/keypoint_schema.json +420 -0
- package/templates/prompt_templates.md +73 -0
- package/templates/prompts/display_guide.md +106 -0
- package/templates/prompts/initialization.md +350 -0
- package/templates/prompts/keypoint_generation.md +272 -0
- package/templates/prompts/output_rules.md +106 -0
- package/templates/prompts/quiz_generation.md +190 -0
- package/templates/prompts/responses.md +339 -0
- package/templates/prompts/shared_enums.md +252 -0
- package/templates/quiz_schema.json +214 -0
- package/templates/state_schema.json +277 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_meta": {
|
|
3
|
+
"prompt_version": "quiz_gen_v1.2"
|
|
4
|
+
},
|
|
5
|
+
"quiz_date": "2026-02-25",
|
|
6
|
+
"cefr_level": "A2",
|
|
7
|
+
"keypoint_fingerprint": "social_nice_to_meet_you",
|
|
8
|
+
"questions": [
|
|
9
|
+
{
|
|
10
|
+
"id": 1,
|
|
11
|
+
"type": "multiple_choice",
|
|
12
|
+
"question": "When do you say 'Nice to meet you'?",
|
|
13
|
+
"context": "Your colleague introduces you to a new team member.",
|
|
14
|
+
"options": [
|
|
15
|
+
"A. When you see an old friend",
|
|
16
|
+
"B. When you meet someone for the first time",
|
|
17
|
+
"C. When you say goodbye",
|
|
18
|
+
"D. When you ask for help"
|
|
19
|
+
],
|
|
20
|
+
"correct_answer": "B",
|
|
21
|
+
"explanation": "'Nice to meet you' is ONLY used when meeting someone for the FIRST time. For old friends, use 'Good to see you'. For goodbye, use 'See you later'.",
|
|
22
|
+
"xp_value": 10,
|
|
23
|
+
"display": {
|
|
24
|
+
"type_emoji": "๐ค",
|
|
25
|
+
"type_name": "้ๆฉ้ข | Multiple Choice",
|
|
26
|
+
"question_formatted": "๐ฌ When do you say **'Nice to meet you'**?",
|
|
27
|
+
"context_formatted": "๐ Your colleague introduces you to a new team member.",
|
|
28
|
+
"options_formatted": [
|
|
29
|
+
"โฌ A. When you see an old friend",
|
|
30
|
+
"โฌ B. When you meet someone for the first time",
|
|
31
|
+
"โฌ C. When you say goodbye",
|
|
32
|
+
"โฌ D. When you ask for help"
|
|
33
|
+
],
|
|
34
|
+
"hint": "๐ก 'Meet' = first time introduction",
|
|
35
|
+
"correct_feedback": "โ
Correct! **'Nice to meet you'** = first time only!",
|
|
36
|
+
"wrong_feedback": "โ **'Nice to meet you'** is for first-time introductions only!",
|
|
37
|
+
"xp_display": "๐ +10 XP"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": 2,
|
|
42
|
+
"type": "chinglish_fix",
|
|
43
|
+
"question": "Fix the mistake in this introduction:",
|
|
44
|
+
"chinglish_sentence": "Hi John! Nice to see you. This is our first meeting.",
|
|
45
|
+
"correct_answer": "Nice to meet you",
|
|
46
|
+
"explanation": "If this is your FIRST meeting, use 'Nice to MEET you', not 'see you'. 'See you' is for people you already know or have met before.",
|
|
47
|
+
"xp_value": 15,
|
|
48
|
+
"display": {
|
|
49
|
+
"type_emoji": "๐ง",
|
|
50
|
+
"type_name": "Chinglish ไฟฎๆญฃ | Fix the Chinglish",
|
|
51
|
+
"question_formatted": "๐ง Find and fix the error:",
|
|
52
|
+
"sentence_formatted": "๐ \"Hi John! **Nice to see you.** This is our first meeting.\"",
|
|
53
|
+
"hint": "๐ก If it's the FIRST meeting, 'see' or 'meet'?",
|
|
54
|
+
"correct_feedback": "โ
Fixed! **'Nice to meet you!'** for first introductions! ๐",
|
|
55
|
+
"wrong_feedback": "โ First time = **'Nice to meet you'**, not 'see you'!",
|
|
56
|
+
"xp_display": "๐ +15 XP"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": 3,
|
|
61
|
+
"type": "fill_blank",
|
|
62
|
+
"question": "Choose the correct phrase:",
|
|
63
|
+
"context": "You're at a party. Your friend introduces you to someone. You say: '___!'",
|
|
64
|
+
"word_bank": ["Nice to meet you", "Nice to see you", "Good to know you"],
|
|
65
|
+
"correct_answer": "Nice to meet you",
|
|
66
|
+
"explanation": "'Nice to meet you' is the standard phrase for first introductions. 'Nice to see you' is for people you already know. 'Good to know you' is not commonly used.",
|
|
67
|
+
"xp_value": 12,
|
|
68
|
+
"display": {
|
|
69
|
+
"type_emoji": "โ๏ธ",
|
|
70
|
+
"type_name": "ๅกซ็ฉบ้ข | Fill in the Blank",
|
|
71
|
+
"question_formatted": "โ๏ธ Complete the response:",
|
|
72
|
+
"context_formatted": "๐ Friend: \"This is Sarah.\" You: \"**___!**\"",
|
|
73
|
+
"word_bank_formatted": "๐ฆ Options: [ **Nice to meet you** | Nice to see you | Good to know you ]",
|
|
74
|
+
"hint": "๐ก First introduction = 'meet' or 'see'?",
|
|
75
|
+
"correct_feedback": "โ
Perfect! **'Nice to meet you!'** is the standard introduction! ๐ฏ",
|
|
76
|
+
"wrong_feedback": "โ For first introductions, say **'Nice to meet you!'**",
|
|
77
|
+
"xp_display": "๐ +12 XP"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"total_xp": 37,
|
|
82
|
+
"passing_score": 70,
|
|
83
|
+
"display": {
|
|
84
|
+
"header": "๐ ไปๆฅๆต้ช | Daily Quiz",
|
|
85
|
+
"date": "๐
2026-02-25",
|
|
86
|
+
"difficulty": "๐ Level: **A2** (ๅ็บง)",
|
|
87
|
+
"topic": "๐ท๏ธ Topic: **Nice to Meet You**",
|
|
88
|
+
"instructions": "๐ฏ 3้ๅฐ้ข๏ผ็ญๅฏน2้ๅฐฑ่ฟๅ
ณ๏ผ3 questions, get 2 right to pass!",
|
|
89
|
+
"progress_bar": "โฌโฌโฌ 0/3 questions",
|
|
90
|
+
"xp_summary": "๐ Total XP: 37 | ๐ Pass: 2/3 correct",
|
|
91
|
+
"footer": "โโโโโโโโโโโโโโโโโโโ\n๐ช Good luck! ๅ ๆฒน! ๐"
|
|
92
|
+
},
|
|
93
|
+
"generated": true
|
|
94
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"quiz_date": "2026-02-20",
|
|
3
|
+
"cefr_level": "B1",
|
|
4
|
+
"keypoint_fingerprint": "workplace_touch_base",
|
|
5
|
+
"questions": [
|
|
6
|
+
{
|
|
7
|
+
"id": 1,
|
|
8
|
+
"type": "multiple_choice",
|
|
9
|
+
"question": "Your colleague asks to 'touch base' about a project. What do they mean?",
|
|
10
|
+
"context": "You receive a Slack message: 'Hey, can we touch base on the Q4 report?'",
|
|
11
|
+
"options": [
|
|
12
|
+
"A. They want to have a formal presentation",
|
|
13
|
+
"B. They want to have a brief check-in conversation",
|
|
14
|
+
"C. They want to cancel the project",
|
|
15
|
+
"D. They want you to write the entire report"
|
|
16
|
+
],
|
|
17
|
+
"correct_answer": "B",
|
|
18
|
+
"explanation": "'Touch base' means having a brief, informal check-in. It comes from baseball and implies a quick connection, not a formal meeting.",
|
|
19
|
+
"xp_value": 10,
|
|
20
|
+
"display": {
|
|
21
|
+
"type_emoji": "๐ค",
|
|
22
|
+
"type_name": "้ๆฉ้ข | Multiple Choice",
|
|
23
|
+
"question_formatted": "๐ฌ Your colleague asks to **'touch base'**. What do they mean?",
|
|
24
|
+
"context_formatted": "๐ฑ Slack: \"Hey, can we **touch base** on the Q4 report?\"",
|
|
25
|
+
"options_formatted": [
|
|
26
|
+
"โฌ A. They want a formal presentation",
|
|
27
|
+
"โฌ B. They want a brief check-in",
|
|
28
|
+
"โฌ C. They want to cancel the project",
|
|
29
|
+
"โฌ D. They want you to write the report"
|
|
30
|
+
],
|
|
31
|
+
"correct_feedback": "โ
Correct! **'Touch base'** = quick check-in โก",
|
|
32
|
+
"wrong_feedback": "โ Not quite. **'Touch base'** means a brief, informal chat!",
|
|
33
|
+
"key_phrase": "**touch base**",
|
|
34
|
+
"xp_display": "๐ +10 XP"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": 2,
|
|
39
|
+
"type": "chinglish_fix",
|
|
40
|
+
"question": "Identify and fix the Chinglish expression in this email:",
|
|
41
|
+
"context": "\"Hi Team, I want to communicate with you about the project. Let's discuss together tomorrow.\"",
|
|
42
|
+
"correct_answer": "touch base / sync up / check in",
|
|
43
|
+
"explanation": "'Communicate with you' and 'discuss together' are direct translations that sound formal and awkward. Americans would say 'touch base' or 'sync up' instead.",
|
|
44
|
+
"xp_value": 15,
|
|
45
|
+
"display": {
|
|
46
|
+
"type_emoji": "๐ง",
|
|
47
|
+
"type_name": "Chinglish ไฟฎๆญฃ | Fix the Chinglish",
|
|
48
|
+
"question_formatted": "๐ง Find and fix the Chinglish expressions:",
|
|
49
|
+
"email_formatted": "๐ง Original email:\n\"Hi Team, I want to 'communicate with you' about the project. Let's 'discuss together' tomorrow.\"",
|
|
50
|
+
"hint": "๐ก Hint: How would an American say this naturally?",
|
|
51
|
+
"correct_feedback": "โ
Fixed! **\"Let's touch base\"** or **\"Let's sync up\"** sounds much better! ๐",
|
|
52
|
+
"wrong_feedback": "โ 'Communicate with you' โ **'touch base'**\nโ 'Discuss together' โ **'sync up'**",
|
|
53
|
+
"answer_formatted": "๐ Better: \"Hi Team, can we **touch base** about the project? Let's **sync up** tomorrow.\"",
|
|
54
|
+
"key_phrase": "**touch base / sync up**",
|
|
55
|
+
"xp_display": "๐ +15 XP"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": 3,
|
|
60
|
+
"type": "fill_blank",
|
|
61
|
+
"question": "Complete the sentence with the correct expression:",
|
|
62
|
+
"context": "You want to suggest a quick meeting with your manager. You say: 'I wanted to ___ on the project timeline.'",
|
|
63
|
+
"word_bank": ["touch base", "discuss together", "communicate"],
|
|
64
|
+
"correct_answer": "touch base",
|
|
65
|
+
"explanation": "'Touch base' is the natural American expression for suggesting a quick check-in. 'Discuss together' sounds awkward and redundant.",
|
|
66
|
+
"xp_value": 12,
|
|
67
|
+
"display": {
|
|
68
|
+
"type_emoji": "โ๏ธ",
|
|
69
|
+
"type_name": "ๅกซ็ฉบ้ข | Fill in the Blank",
|
|
70
|
+
"question_formatted": "โ๏ธ Complete the sentence:",
|
|
71
|
+
"context_formatted": "๐ผ To your manager: \"I wanted to **___** on the project timeline.\"",
|
|
72
|
+
"word_bank_formatted": "๐ฆ Word Bank: [ **touch base** | 'discuss together' โ | 'communicate' โ ]",
|
|
73
|
+
"correct_feedback": "โ
Perfect! **'Touch base'** is the way to go! ๐ฏ",
|
|
74
|
+
"wrong_feedback": "โ 'Discuss together' sounds awkward. Try **'touch base'**!",
|
|
75
|
+
"key_phrase": "**touch base**",
|
|
76
|
+
"xp_display": "๐ +12 XP"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"total_xp": 37,
|
|
81
|
+
"passing_score": 70,
|
|
82
|
+
"display": {
|
|
83
|
+
"header": "๐ ไปๆฅๆต้ช | Daily Quiz",
|
|
84
|
+
"date": "๐
2026-02-20",
|
|
85
|
+
"topic": "๐ท๏ธ Topic: **workplace_touch_base**",
|
|
86
|
+
"instructions": "๐ฏ 3้ๅฐ้ข๏ผ็ญๅฏน2้ๅฐฑ่ฟๅ
ณ๏ผ3 questions, get 2 right to pass!",
|
|
87
|
+
"progress_bar": "โฌโฌโฌ 0/3 questions",
|
|
88
|
+
"xp_summary": "๐ Total XP: 37 | ๐ Pass: 2/3 correct",
|
|
89
|
+
"footer": "โโโโโโโโโโโโโโโโโโโ\n๐ช Good luck! ๅ ๆฒน! ๐"
|
|
90
|
+
},
|
|
91
|
+
"generated": true
|
|
92
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_meta": {
|
|
3
|
+
"prompt_version": "quiz_gen_v1.2"
|
|
4
|
+
},
|
|
5
|
+
"quiz_date": "2026-02-25",
|
|
6
|
+
"cefr_level": "B2",
|
|
7
|
+
"keypoint_fingerprint": "workplace_circle_back",
|
|
8
|
+
"questions": [
|
|
9
|
+
{
|
|
10
|
+
"id": 1,
|
|
11
|
+
"type": "multiple_choice",
|
|
12
|
+
"question": "Your meeting is running over time. What's the most natural way to postpone a topic?",
|
|
13
|
+
"context": "You've spent 30 minutes on the budget discussion. There are still 3 agenda items left.",
|
|
14
|
+
"options": [
|
|
15
|
+
"A. Let's discuss again later",
|
|
16
|
+
"B. Let's circle back on this",
|
|
17
|
+
"C. Let's talk more about this",
|
|
18
|
+
"D. We should continue this conversation"
|
|
19
|
+
],
|
|
20
|
+
"correct_answer": "B",
|
|
21
|
+
"explanation": "'Circle back' is the standard corporate idiom for returning to a topic later. 'Discuss again' sounds mechanical. 'Talk more' and 'continue' don't imply postponement.",
|
|
22
|
+
"xp_value": 10,
|
|
23
|
+
"display": {
|
|
24
|
+
"type_emoji": "๐ค",
|
|
25
|
+
"type_name": "้ๆฉ้ข | Multiple Choice",
|
|
26
|
+
"question_formatted": "๐ฌ What's the most natural way to **postpone** a topic?",
|
|
27
|
+
"context_formatted": "โฐ Meeting running over. Need to move on.",
|
|
28
|
+
"options_formatted": [
|
|
29
|
+
"โฌ A. Let's discuss again later",
|
|
30
|
+
"โฌ B. Let's circle back on this",
|
|
31
|
+
"โฌ C. Let's talk more about this",
|
|
32
|
+
"โฌ D. We should continue this conversation"
|
|
33
|
+
],
|
|
34
|
+
"hint": "๐ก Which sounds most natural in American corporate culture?",
|
|
35
|
+
"correct_feedback": "โ
Correct! **'Circle back'** is the standard corporate idiom!",
|
|
36
|
+
"wrong_feedback": "โ **'Circle back'** is the most natural corporate expression here!",
|
|
37
|
+
"xp_display": "๐ +10 XP"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": 2,
|
|
42
|
+
"type": "chinglish_fix",
|
|
43
|
+
"question": "Make this sound more natural in American business:",
|
|
44
|
+
"chinglish_sentence": "We need to discuss this topic again after the meeting.",
|
|
45
|
+
"correct_answer": "Let's circle back on this after the meeting",
|
|
46
|
+
"explanation": "'Discuss this topic again' is grammatically correct but sounds mechanical. 'Circle back' is the idiomatic corporate expression that implies a planned return to the topic.",
|
|
47
|
+
"xp_value": 15,
|
|
48
|
+
"display": {
|
|
49
|
+
"type_emoji": "๐ง",
|
|
50
|
+
"type_name": "Chinglish ไฟฎๆญฃ | Fix the Chinglish",
|
|
51
|
+
"question_formatted": "๐ง Make this sound more corporate:",
|
|
52
|
+
"sentence_formatted": "๐ \"We need to **discuss this topic again** after the meeting.\"",
|
|
53
|
+
"hint": "๐ก Use a spatial metaphor that implies returning",
|
|
54
|
+
"correct_feedback": "โ
Much better! **'Let's circle back on this'** sounds professional! ๐",
|
|
55
|
+
"wrong_feedback": "โ Try **'Let's circle back on this'** instead of 'discuss again'",
|
|
56
|
+
"xp_display": "๐ +15 XP"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": 3,
|
|
61
|
+
"type": "fill_blank",
|
|
62
|
+
"question": "Complete with the correct corporate idiom:",
|
|
63
|
+
"context": "You want to include your colleague in future emails about a project. You say: 'I'll ___ on the project updates.'",
|
|
64
|
+
"word_bank": ["loop you in", "circle back", "touch base", "reach out"],
|
|
65
|
+
"correct_answer": "loop you in",
|
|
66
|
+
"explanation": "'Loop you in' means to include someone in communication. 'Circle back' is for returning to topics. 'Touch base' is for checking in. 'Reach out' is for initiating contact.",
|
|
67
|
+
"xp_value": 12,
|
|
68
|
+
"display": {
|
|
69
|
+
"type_emoji": "โ๏ธ",
|
|
70
|
+
"type_name": "ๅกซ็ฉบ้ข | Fill in the Blank",
|
|
71
|
+
"question_formatted": "โ๏ธ Complete the sentence:",
|
|
72
|
+
"context_formatted": "๐ง \"I'll **___** on the project updates.\"",
|
|
73
|
+
"word_bank_formatted": "๐ฆ Options: [ **loop you in** | circle back | touch base | reach out ]",
|
|
74
|
+
"hint": "๐ก Include someone = ?",
|
|
75
|
+
"correct_feedback": "โ
Perfect! **'Loop you in'** means include in communication! ๐ฏ",
|
|
76
|
+
"wrong_feedback": "โ **'Loop you in'** is for including someone in future communication!",
|
|
77
|
+
"xp_display": "๐ +12 XP"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"total_xp": 37,
|
|
82
|
+
"passing_score": 70,
|
|
83
|
+
"display": {
|
|
84
|
+
"header": "๐ ไปๆฅๆต้ช | Daily Quiz",
|
|
85
|
+
"date": "๐
2026-02-25",
|
|
86
|
+
"difficulty": "๐ Level: **B2** (ไธญ้ซ็บง)",
|
|
87
|
+
"topic": "๐ท๏ธ Topic: **Circle Back / Loop In**",
|
|
88
|
+
"instructions": "๐ฏ 3้ๅฐ้ข๏ผ็ญๅฏน2้ๅฐฑ่ฟๅ
ณ๏ผ3 questions, get 2 right to pass!",
|
|
89
|
+
"progress_bar": "โฌโฌโฌ 0/3 questions",
|
|
90
|
+
"xp_summary": "๐ Total XP: 37 | ๐ Pass: 2/3 correct",
|
|
91
|
+
"footer": "โโโโโโโโโโโโโโโโโโโ\n๐ช Good luck! ๅ ๆฒน! ๐"
|
|
92
|
+
},
|
|
93
|
+
"generated": true
|
|
94
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_meta": {
|
|
3
|
+
"prompt_version": "quiz_gen_v1.2"
|
|
4
|
+
},
|
|
5
|
+
"quiz_date": "2026-02-25",
|
|
6
|
+
"cefr_level": "C1",
|
|
7
|
+
"keypoint_fingerprint": "workplace_take_offline",
|
|
8
|
+
"questions": [
|
|
9
|
+
{
|
|
10
|
+
"id": 1,
|
|
11
|
+
"type": "multiple_choice",
|
|
12
|
+
"question": "A detailed technical debate is derailing your stakeholder meeting. What's the most diplomatic way to redirect?",
|
|
13
|
+
"context": "Engineers are deep in API latency details while business stakeholders look confused.",
|
|
14
|
+
"options": [
|
|
15
|
+
"A. This is boring, let's stop",
|
|
16
|
+
"B. Let's take this offline with just the engineering team",
|
|
17
|
+
"C. You shouldn't discuss this here",
|
|
18
|
+
"D. We don't have time for this"
|
|
19
|
+
],
|
|
20
|
+
"correct_answer": "B",
|
|
21
|
+
"explanation": "'Take this offline' is the diplomatic corporate phrase that redirects without dismissing. It implies the discussion is valid, just not in this forum. The other options are too blunt or rude.",
|
|
22
|
+
"xp_value": 10,
|
|
23
|
+
"display": {
|
|
24
|
+
"type_emoji": "๐ค",
|
|
25
|
+
"type_name": "้ๆฉ้ข | Multiple Choice",
|
|
26
|
+
"question_formatted": "๐ฌ What's the most **diplomatic** way to redirect?",
|
|
27
|
+
"context_formatted": "โ๏ธ Engineers debating API details. Stakeholders confused.",
|
|
28
|
+
"options_formatted": [
|
|
29
|
+
"โฌ A. This is boring, let's stop",
|
|
30
|
+
"โฌ B. Let's take this offline with just the engineering team",
|
|
31
|
+
"โฌ C. You shouldn't discuss this here",
|
|
32
|
+
"โฌ D. We don't have time for this"
|
|
33
|
+
],
|
|
34
|
+
"hint": "๐ก Which redirects politely without dismissing?",
|
|
35
|
+
"correct_feedback": "โ
Correct! **'Take this offline'** redirects diplomatically!",
|
|
36
|
+
"wrong_feedback": "โ **'Take this offline'** is the diplomatic corporate phrase!",
|
|
37
|
+
"xp_display": "๐ +10 XP"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": 2,
|
|
42
|
+
"type": "chinglish_fix",
|
|
43
|
+
"question": "A team member raises a sensitive performance issue in a large group meeting. Make your response more professional:",
|
|
44
|
+
"chinglish_sentence": "Let's talk privately about this later.",
|
|
45
|
+
"correct_answer": "Let's take this offline",
|
|
46
|
+
"explanation": "'Talk privately' can sound exclusionary or secretive in a group setting. 'Take offline' is the professional euphemism that sounds efficient rather than secretive. It implies appropriateness, not exclusion.",
|
|
47
|
+
"xp_value": 15,
|
|
48
|
+
"display": {
|
|
49
|
+
"type_emoji": "๐ง",
|
|
50
|
+
"type_name": "Chinglish ไฟฎๆญฃ | Fix the Chinglish",
|
|
51
|
+
"question_formatted": "๐ง Make this sound more corporate:",
|
|
52
|
+
"sentence_formatted": "๐ \"Let's **talk privately** about this later.\" (in a group meeting)",
|
|
53
|
+
"hint": "๐ก What's the professional euphemism?",
|
|
54
|
+
"correct_feedback": "โ
Much better! **'Take this offline'** sounds professional! ๐",
|
|
55
|
+
"wrong_feedback": "โ **'Take this offline'** is the professional euphemism!",
|
|
56
|
+
"xp_display": "๐ +15 XP"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": 3,
|
|
61
|
+
"type": "fill_blank",
|
|
62
|
+
"question": "Choose the idiom that means 'unproductive discussion':",
|
|
63
|
+
"context": "Your team has been discussing the same problem for 30 minutes with no progress. You say: 'We're ___ here. Let's move on.'",
|
|
64
|
+
"word_bank": ["spinning our wheels", "boiling the ocean", "touching base", "circling back"],
|
|
65
|
+
"correct_answer": "spinning our wheels",
|
|
66
|
+
"explanation": "'Spinning our wheels' comes from car imageryโwheels spinning in mud without moving forward. It describes unproductive discussion. 'Boiling the ocean' is about over-ambitious scope. The others don't fit this context.",
|
|
67
|
+
"xp_value": 12,
|
|
68
|
+
"display": {
|
|
69
|
+
"type_emoji": "โ๏ธ",
|
|
70
|
+
"type_name": "ๅกซ็ฉบ้ข | Fill in the Blank",
|
|
71
|
+
"question_formatted": "โ๏ธ Complete with the right idiom:",
|
|
72
|
+
"context_formatted": "๐ 30 minutes, no progress. \"We're **___** here.\"",
|
|
73
|
+
"word_bank_formatted": "๐ฆ Options: [ **spinning our wheels** | boiling the ocean | touching base | circling back ]",
|
|
74
|
+
"hint": "๐ก Car metaphor = going nowhere",
|
|
75
|
+
"correct_feedback": "โ
Perfect! **'Spinning our wheels'** = unproductive! ๐ฏ",
|
|
76
|
+
"wrong_feedback": "โ **'Spinning our wheels'** describes unproductive discussion!",
|
|
77
|
+
"xp_display": "๐ +12 XP"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"total_xp": 37,
|
|
82
|
+
"passing_score": 70,
|
|
83
|
+
"display": {
|
|
84
|
+
"header": "๐ ไปๆฅๆต้ช | Daily Quiz",
|
|
85
|
+
"date": "๐
2026-02-25",
|
|
86
|
+
"difficulty": "๐ Level: **C1** (้ซ็บง)",
|
|
87
|
+
"topic": "๐ท๏ธ Topic: **Take Offline / Spinning Wheels**",
|
|
88
|
+
"instructions": "๐ฏ 3้ๅฐ้ข๏ผ็ญๅฏน2้ๅฐฑ่ฟๅ
ณ๏ผ3 questions, get 2 right to pass!",
|
|
89
|
+
"progress_bar": "โฌโฌโฌ 0/3 questions",
|
|
90
|
+
"xp_summary": "๐ Total XP: 37 | ๐ Pass: 2/3 correct",
|
|
91
|
+
"footer": "โโโโโโโโโโโโโโโโโโโ\n๐ช Good luck! ๅ ๆฒน! ๐"
|
|
92
|
+
},
|
|
93
|
+
"generated": true
|
|
94
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_meta": {
|
|
3
|
+
"prompt_version": "quiz_gen_v1.2"
|
|
4
|
+
},
|
|
5
|
+
"quiz_date": "2026-02-25",
|
|
6
|
+
"cefr_level": "C2",
|
|
7
|
+
"keypoint_fingerprint": "workplace_boil_the_ocean",
|
|
8
|
+
"questions": [
|
|
9
|
+
{
|
|
10
|
+
"id": 1,
|
|
11
|
+
"type": "multiple_choice",
|
|
12
|
+
"question": "In an executive meeting, a VP proposes rebuilding the entire platform, adding AI, AND entering 3 new markets in Q1. What's the most strategic response?",
|
|
13
|
+
"context": "You need to push back diplomatically while showing strategic thinking.",
|
|
14
|
+
"options": [
|
|
15
|
+
"A. That's impossible, we can't do it",
|
|
16
|
+
"B. Let's not boil the oceanโwhat's the minimum viable scope?",
|
|
17
|
+
"C. I think we should do less",
|
|
18
|
+
"D. This is too ambitious"
|
|
19
|
+
],
|
|
20
|
+
"correct_answer": "B",
|
|
21
|
+
"explanation": "'Boil the ocean' is the C-suite idiom for impossibly ambitious scope. Using it shows strategic thinking. It's visual, slightly humorous, and makes the point diplomatically. The other options are too direct or unsophisticated for executive settings.",
|
|
22
|
+
"xp_value": 10,
|
|
23
|
+
"display": {
|
|
24
|
+
"type_emoji": "๐ค",
|
|
25
|
+
"type_name": "้ๆฉ้ข | Multiple Choice",
|
|
26
|
+
"question_formatted": "๐ฌ What's the most **strategic** response?",
|
|
27
|
+
"context_formatted": "๐ฏ VP proposes impossibly ambitious scope in executive meeting.",
|
|
28
|
+
"options_formatted": [
|
|
29
|
+
"โฌ A. That's impossible, we can't do it",
|
|
30
|
+
"โฌ B. Let's not boil the oceanโwhat's the minimum viable scope?",
|
|
31
|
+
"โฌ C. I think we should do less",
|
|
32
|
+
"โฌ D. This is too ambitious"
|
|
33
|
+
],
|
|
34
|
+
"hint": "๐ก Which shows C-suite language mastery?",
|
|
35
|
+
"correct_feedback": "โ
Excellent! **'Boil the ocean'** is strategic C-suite language!",
|
|
36
|
+
"wrong_feedback": "โ **'Boil the ocean'** shows strategic thinking at executive level!",
|
|
37
|
+
"xp_display": "๐ +10 XP"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": 2,
|
|
42
|
+
"type": "chinglish_fix",
|
|
43
|
+
"question": "Your CEO wants a complete digital transformation by Q2. Transform this response to sound more executive:",
|
|
44
|
+
"chinglish_sentence": "That's too ambitious. We need to reduce the scope.",
|
|
45
|
+
"correct_answer": "That's boiling the ocean. We need a phased approach.",
|
|
46
|
+
"explanation": "'Too ambitious' and 'reduce scope' sound unsophisticated. 'Boiling the ocean' and 'phased approach' are the idiomatic expressions that signal strategic thinking. The ocean metaphor is powerful and memorable.",
|
|
47
|
+
"xp_value": 15,
|
|
48
|
+
"display": {
|
|
49
|
+
"type_emoji": "๐ง",
|
|
50
|
+
"type_name": "Chinglish ไฟฎๆญฃ | Fix the Chinglish",
|
|
51
|
+
"question_formatted": "๐ง Make this sound more C-suite:",
|
|
52
|
+
"sentence_formatted": "๐ \"That's **too ambitious**. We need to **reduce the scope**.\"",
|
|
53
|
+
"hint": "๐ก Use the ocean metaphor and 'phased'",
|
|
54
|
+
"correct_feedback": "โ
Perfect! **'Boiling the ocean' + 'phased approach'** = executive language! ๐",
|
|
55
|
+
"wrong_feedback": "โ Try **'That's boiling the ocean. We need a phased approach.'**",
|
|
56
|
+
"xp_display": "๐ +15 XP"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": 3,
|
|
61
|
+
"type": "dialogue_completion",
|
|
62
|
+
"question": "What's the best next step after proposing a major initiative?",
|
|
63
|
+
"context": "You've proposed a new strategy. Before finalizing, you need buy-in from regional teams.",
|
|
64
|
+
"options": [
|
|
65
|
+
"A. Let's implement immediately",
|
|
66
|
+
"B. We need to socialize this with the regional teams first",
|
|
67
|
+
"C. Let's keep it confidential",
|
|
68
|
+
"D. We should decide now"
|
|
69
|
+
],
|
|
70
|
+
"correct_answer": "B",
|
|
71
|
+
"explanation": "'Socialize this' is uniquely corporate. It means systematically sharing with stakeholders to gather input and build consensus. It's more deliberate than 'discussing'โit's a process. This is standard C-suite decision-making language.",
|
|
72
|
+
"xp_value": 15,
|
|
73
|
+
"display": {
|
|
74
|
+
"type_emoji": "๐ฌ",
|
|
75
|
+
"type_name": "ๅฏน่ฏ่กฅๅ
จ | Dialogue Completion",
|
|
76
|
+
"question_formatted": "๐ฌ What's the best next step?",
|
|
77
|
+
"context_formatted": "๐ You've proposed a new strategy. Regional teams need input.",
|
|
78
|
+
"options_formatted": [
|
|
79
|
+
"โฌ A. Let's implement immediately",
|
|
80
|
+
"โฌ B. We need to socialize this with the regional teams first",
|
|
81
|
+
"โฌ C. Let's keep it confidential",
|
|
82
|
+
"โฌ D. We should decide now"
|
|
83
|
+
],
|
|
84
|
+
"hint": "๐ก Get stakeholder buy-in before deciding = ?",
|
|
85
|
+
"correct_feedback": "โ
Perfect! **'Socialize this'** = systematic stakeholder buy-in! ๐ฏ",
|
|
86
|
+
"wrong_feedback": "โ **'Socialize this with stakeholders'** is the C-suite process!",
|
|
87
|
+
"xp_display": "๐ +15 XP"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
"total_xp": 40,
|
|
92
|
+
"passing_score": 70,
|
|
93
|
+
"display": {
|
|
94
|
+
"header": "๐ ไปๆฅๆต้ช | Daily Quiz",
|
|
95
|
+
"date": "๐
2026-02-25",
|
|
96
|
+
"difficulty": "๐ Level: **C2** (็ฒพ้็บง)",
|
|
97
|
+
"topic": "๐ท๏ธ Topic: **Boil the Ocean / Socialize**",
|
|
98
|
+
"instructions": "๐ฏ 3้ๅฐ้ข๏ผ็ญๅฏน2้ๅฐฑ่ฟๅ
ณ๏ผ3 questions, get 2 right to pass!",
|
|
99
|
+
"progress_bar": "โฌโฌโฌ 0/3 questions",
|
|
100
|
+
"xp_summary": "๐ Total XP: 40 | ๐ Pass: 2/3 correct",
|
|
101
|
+
"footer": "โโโโโโโโโโโโโโโโโโโ\n๐ช Good luck! ๅ ๆฒน! ๐"
|
|
102
|
+
},
|
|
103
|
+
"generated": true
|
|
104
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rookiestar/eng-lang-tutor",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "ๅฐ้็พๅผ่ฑ่ฏญๅฏผๅธ - OpenClaw Skill for learning authentic American English",
|
|
5
|
+
"main": "scripts/cli/cli.py",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"postinstall": "python3 -m pip install -r requirements.txt --quiet"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"english",
|
|
11
|
+
"learning",
|
|
12
|
+
"openclaw",
|
|
13
|
+
"skill",
|
|
14
|
+
"tutor",
|
|
15
|
+
"cefr",
|
|
16
|
+
"american-english",
|
|
17
|
+
"language-learning",
|
|
18
|
+
"gamification"
|
|
19
|
+
],
|
|
20
|
+
"author": "RookieStar",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/rookiestar/Skills.git",
|
|
25
|
+
"directory": "eng-lang-tutor"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/rookiestar/Skills/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/rookiestar/Skills/tree/main/eng-lang-tutor#readme",
|
|
31
|
+
"files": [
|
|
32
|
+
"**/*",
|
|
33
|
+
"!tests/**",
|
|
34
|
+
"!**/*.pyc",
|
|
35
|
+
"!**/__pycache__/**",
|
|
36
|
+
"!.DS_Store"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=14.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|