vibe-learning-opencode 0.1.7 → 0.2.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/dist/index.js +56 -95
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,12 +4,12 @@ var CONFIG = {
|
|
|
4
4
|
COOLDOWN_MS: 15 * 60 * 1e3,
|
|
5
5
|
MAX_CONCEPTS: 10,
|
|
6
6
|
SIGNIFICANT_TOOLS: ["edit", "write", "bash"]
|
|
7
|
-
// 소문자로 변경
|
|
8
7
|
};
|
|
9
8
|
var toolCount = 0;
|
|
10
9
|
var lastLearningPrompt = 0;
|
|
11
10
|
var recentConcepts = [];
|
|
12
|
-
var
|
|
11
|
+
var seniorEnabled = true;
|
|
12
|
+
var afterEnabled = true;
|
|
13
13
|
var lastSessionID = null;
|
|
14
14
|
var FILE_CONCEPTS = [
|
|
15
15
|
{ pattern: /test|spec|__tests__/i, concept: "unit-testing" },
|
|
@@ -37,7 +37,8 @@ function extractConceptFromPath(filePath) {
|
|
|
37
37
|
}
|
|
38
38
|
var COMMAND_PROMPTS = {
|
|
39
39
|
status: `Execute NOW: Call mcp__vibe-learning__get_mode and mcp__vibe-learning__should_ask_question, then show:
|
|
40
|
-
-
|
|
40
|
+
- Senior mode: on/off
|
|
41
|
+
- After mode: on/off
|
|
41
42
|
- Cooldown status
|
|
42
43
|
- Consecutive skips`,
|
|
43
44
|
stats: `Execute NOW: Call mcp__vibe-learning__get_stats with period="month", then format as a dashboard showing:
|
|
@@ -60,61 +61,19 @@ var COMMAND_PROMPTS = {
|
|
|
60
61
|
"unknowns-save": `Execute NOW: Call mcp__vibe-learning__save_unknowns with period="month" and limit=20. Confirm file saved.`,
|
|
61
62
|
review: `Execute NOW: Call mcp__vibe-learning__get_due_reviews with limit=5. For each due concept, ask a level-appropriate question and record results.`,
|
|
62
63
|
interview: `Execute NOW: Call mcp__vibe-learning__get_stats with period="month". Then conduct interview-style Level 3-5 questions on the learned concepts.`,
|
|
63
|
-
pause: `Execute NOW: Call mcp__vibe-learning__set_mode with
|
|
64
|
-
off: `Execute NOW: Call mcp__vibe-learning__set_mode with
|
|
65
|
-
|
|
64
|
+
pause: `Execute NOW: Call mcp__vibe-learning__set_mode with paused_until set to 1 hour from now (ISO format). Confirm paused.`,
|
|
65
|
+
off: `Execute NOW: Call mcp__vibe-learning__set_mode with senior_enabled=false and after_enabled=false. Confirm learning is off (recording continues).`,
|
|
66
|
+
on: `Execute NOW: Call mcp__vibe-learning__set_mode with senior_enabled=true and after_enabled=true. Confirm full learning mode enabled.`,
|
|
67
|
+
"senior-on": `Execute NOW: Call mcp__vibe-learning__set_mode with senior_enabled=true. Confirm senior mode enabled.
|
|
66
68
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Before mode behavior: Check understanding BEFORE implementation. Ask one question, then proceed.`,
|
|
71
|
-
senior: `Execute NOW: Call mcp__vibe-learning__set_mode with mode="senior". Confirm Senior mode enabled.
|
|
72
|
-
|
|
73
|
-
CRITICAL - FOR ALL SUBSEQUENT TASKS, test understanding like a senior developer:
|
|
74
|
-
|
|
75
|
-
**[VibeLearning Senior Mode]**
|
|
76
|
-
[Round 1/3] [Senior-level question]?
|
|
77
|
-
_(skip: say "skip" to proceed)_
|
|
78
|
-
|
|
79
|
-
Question Style - Test understanding, not gather requirements:
|
|
80
|
-
\u274C WRONG: "What data will you cache?" (requirements gathering)
|
|
81
|
-
\u274C WRONG: "Redis or Memcached?" (tool selection)
|
|
82
|
-
\u2705 RIGHT: "Why do you need caching here?" (reasoning)
|
|
83
|
-
\u2705 RIGHT: "What is cache-aside pattern? How is it different from write-through?" (concept)
|
|
84
|
-
\u2705 RIGHT: "What problems can caching introduce?" (tradeoffs)
|
|
85
|
-
|
|
86
|
-
Flow:
|
|
87
|
-
- Round 1: Test conceptual understanding or ask WHY
|
|
88
|
-
- Round 2: Ask about tradeoffs, edge cases, or compare alternatives
|
|
89
|
-
- Round 3: (if needed) Give hint and ask again
|
|
90
|
-
- FINAL STEP (MANDATORY): Call record_learning tool, THEN say "Good! Implementing now."
|
|
91
|
-
|
|
92
|
-
\u26A0\uFE0F CRITICAL - After final round, call BOTH tools:
|
|
93
|
-
|
|
94
|
-
1. Record learning result:
|
|
95
|
-
mcp__vibe-learning__record_learning({
|
|
96
|
-
concept_id: "kebab-case-concept",
|
|
97
|
-
level: 3,
|
|
98
|
-
result: "correct" | "partial" | "skipped"
|
|
99
|
-
})
|
|
69
|
+
Senior mode behavior: Ask conceptual questions BEFORE implementation.`,
|
|
70
|
+
"senior-off": `Execute NOW: Call mcp__vibe-learning__set_mode with senior_enabled=false. Confirm senior mode disabled.`,
|
|
71
|
+
"after-on": `Execute NOW: Call mcp__vibe-learning__set_mode with after_enabled=true. Confirm after mode enabled.
|
|
100
72
|
|
|
101
|
-
|
|
102
|
-
mcp__vibe-
|
|
103
|
-
concept_id: "related-concept",
|
|
104
|
-
related_to: "main-concept",
|
|
105
|
-
context: "brief context",
|
|
106
|
-
why_important: "why important"
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
THEN say "Good! Implementing now."
|
|
110
|
-
|
|
111
|
-
ONE question per message. Wait for answer.`,
|
|
112
|
-
"senior-light": `Execute NOW: Call mcp__vibe-learning__set_mode with mode="senior_light". Confirm mode changed.
|
|
113
|
-
|
|
114
|
-
Senior Light behavior: Present counterarguments but proceed after round 1. Don't block, just give feedback.`
|
|
73
|
+
After mode behavior: Ask learning questions AFTER task completion.`,
|
|
74
|
+
"after-off": `Execute NOW: Call mcp__vibe-learning__set_mode with after_enabled=false. Confirm after mode disabled.`
|
|
115
75
|
};
|
|
116
|
-
var
|
|
117
|
-
senior: `Ask ONE question per round. Minimum 2 rounds required.
|
|
76
|
+
var SENIOR_BEHAVIOR_PROMPT = `Ask ONE question per round. Minimum 2 rounds required.
|
|
118
77
|
|
|
119
78
|
Format (MUST show header on Round 1):
|
|
120
79
|
**[VibeLearning Senior Mode]**
|
|
@@ -128,7 +87,7 @@ Flow:
|
|
|
128
87
|
- Round 3: If Round 2 vague, "[Round 3/3] Hint: [hint]. What do you think?"
|
|
129
88
|
- FINAL STEP (MANDATORY): Call record_learning, THEN say "Good thinking! Implementing now."
|
|
130
89
|
|
|
131
|
-
|
|
90
|
+
After final round, call BOTH tools:
|
|
132
91
|
|
|
133
92
|
1. mcp__vibe-learning__record_learning({
|
|
134
93
|
concept_id: "kebab-case-concept",
|
|
@@ -145,16 +104,7 @@ Flow:
|
|
|
145
104
|
|
|
146
105
|
THEN say "Good thinking! Implementing now."
|
|
147
106
|
|
|
148
|
-
ONE question per round. Be strict like a real senior
|
|
149
|
-
before: `[VibeLearning - Before Mode]
|
|
150
|
-
|
|
151
|
-
Ask ONE short question: "Before implementing, [question]?"
|
|
152
|
-
Then proceed regardless of answer.`,
|
|
153
|
-
senior_light: `[VibeLearning - Senior Light]
|
|
154
|
-
|
|
155
|
-
Briefly mention one alternative while implementing.
|
|
156
|
-
Example: "Using X, but Y is also an option if you need Z."`
|
|
157
|
-
};
|
|
107
|
+
ONE question per round. Be strict like a real senior.`;
|
|
158
108
|
var AUTO_LEARNING_PROMPT = `[VibeLearning - Task Completion]
|
|
159
109
|
|
|
160
110
|
Task completed. Execute these steps NOW (in order):
|
|
@@ -177,12 +127,13 @@ Call mcp__vibe-learning__get_concept_level for the main concept to register it i
|
|
|
177
127
|
|
|
178
128
|
**STEP 4: Ask Learning Question (CONDITIONAL)**
|
|
179
129
|
Call mcp__vibe-learning__should_ask_question to check.
|
|
180
|
-
- If shouldAsk is true
|
|
181
|
-
-
|
|
130
|
+
- If shouldAsk is true:
|
|
131
|
+
- Format:
|
|
132
|
+
**[VibeLearning]**
|
|
133
|
+
_Learning Question (Level X)_
|
|
134
|
+
[Your question here]?
|
|
182
135
|
- After user answers, call mcp__vibe-learning__record_learning
|
|
183
|
-
- If shouldAsk is false:
|
|
184
|
-
|
|
185
|
-
Ask naturally, like conversation. Keep it brief.`;
|
|
136
|
+
- If shouldAsk is false: skip silently (no cooldown message needed)`;
|
|
186
137
|
function parseLearnCommand(text) {
|
|
187
138
|
const lower = text.toLowerCase().trim();
|
|
188
139
|
if (lower === "/learn" || lower === "/learn status")
|
|
@@ -207,14 +158,20 @@ function parseLearnCommand(text) {
|
|
|
207
158
|
return "pause";
|
|
208
159
|
if (lower === "/learn off")
|
|
209
160
|
return "off";
|
|
210
|
-
if (lower === "/learn
|
|
211
|
-
return "
|
|
212
|
-
if (lower === "/learn
|
|
213
|
-
return "
|
|
214
|
-
if (lower === "/learn senior
|
|
215
|
-
return "senior-
|
|
161
|
+
if (lower === "/learn on")
|
|
162
|
+
return "on";
|
|
163
|
+
if (lower === "/learn senior on")
|
|
164
|
+
return "senior-on";
|
|
165
|
+
if (lower === "/learn senior off")
|
|
166
|
+
return "senior-off";
|
|
216
167
|
if (lower === "/learn senior")
|
|
217
|
-
return "senior";
|
|
168
|
+
return "senior-on";
|
|
169
|
+
if (lower === "/learn after on")
|
|
170
|
+
return "after-on";
|
|
171
|
+
if (lower === "/learn after off")
|
|
172
|
+
return "after-off";
|
|
173
|
+
if (lower === "/learn after")
|
|
174
|
+
return "after-on";
|
|
218
175
|
if (lower.startsWith("/learn focus "))
|
|
219
176
|
return "focus";
|
|
220
177
|
return null;
|
|
@@ -223,7 +180,7 @@ var VibeLearningPlugin = (ctx) => {
|
|
|
223
180
|
const { client } = ctx;
|
|
224
181
|
client.app.log({
|
|
225
182
|
level: "info",
|
|
226
|
-
message: "[VibeLearning] Plugin loaded"
|
|
183
|
+
message: "[VibeLearning] Plugin loaded (v2 - independent toggles)"
|
|
227
184
|
}).catch(() => {
|
|
228
185
|
});
|
|
229
186
|
const injectPrompt = (sessionID, prompt) => {
|
|
@@ -247,7 +204,7 @@ var VibeLearningPlugin = (ctx) => {
|
|
|
247
204
|
const concept = extractConceptFromPath(filePath);
|
|
248
205
|
if (concept)
|
|
249
206
|
addConcept(concept);
|
|
250
|
-
if (toolCount >= CONFIG.TOOL_THRESHOLD) {
|
|
207
|
+
if (afterEnabled && toolCount >= CONFIG.TOOL_THRESHOLD) {
|
|
251
208
|
const now = Date.now();
|
|
252
209
|
if (now - lastLearningPrompt >= CONFIG.COOLDOWN_MS) {
|
|
253
210
|
toolCount = 0;
|
|
@@ -275,18 +232,23 @@ var VibeLearningPlugin = (ctx) => {
|
|
|
275
232
|
lastSessionID = input.sessionID;
|
|
276
233
|
const cmd = parseLearnCommand(content);
|
|
277
234
|
if (cmd) {
|
|
278
|
-
if (cmd === "off")
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
else if (cmd === "senior")
|
|
285
|
-
|
|
286
|
-
else if (cmd === "senior-
|
|
287
|
-
|
|
288
|
-
else if (cmd === "
|
|
235
|
+
if (cmd === "off") {
|
|
236
|
+
seniorEnabled = false;
|
|
237
|
+
afterEnabled = false;
|
|
238
|
+
} else if (cmd === "on") {
|
|
239
|
+
seniorEnabled = true;
|
|
240
|
+
afterEnabled = true;
|
|
241
|
+
} else if (cmd === "senior-on") {
|
|
242
|
+
seniorEnabled = true;
|
|
243
|
+
} else if (cmd === "senior-off") {
|
|
244
|
+
seniorEnabled = false;
|
|
245
|
+
} else if (cmd === "after-on") {
|
|
246
|
+
afterEnabled = true;
|
|
247
|
+
} else if (cmd === "after-off") {
|
|
248
|
+
afterEnabled = false;
|
|
249
|
+
} else if (cmd === "pause") {
|
|
289
250
|
lastLearningPrompt = Date.now();
|
|
251
|
+
}
|
|
290
252
|
const prompt = COMMAND_PROMPTS[cmd];
|
|
291
253
|
if (prompt) {
|
|
292
254
|
client.tui.showToast({
|
|
@@ -302,16 +264,15 @@ var VibeLearningPlugin = (ctx) => {
|
|
|
302
264
|
client.app.log({ level: "info", message: `[VibeLearning] Command: ${cmd}` }).catch(() => {
|
|
303
265
|
});
|
|
304
266
|
} else {
|
|
305
|
-
|
|
306
|
-
if (modeBehavior && currentMode !== "after" && currentMode !== "off") {
|
|
267
|
+
if (seniorEnabled) {
|
|
307
268
|
const trimmed = content.trim();
|
|
308
269
|
if (trimmed.length > 10 && !trimmed.match(/^(yes|no|ok|skip|done|correct|partial|incorrect|got it|이해|알겠|넵|응|아니|스킵)/i)) {
|
|
309
270
|
setTimeout(() => {
|
|
310
271
|
if (lastSessionID) {
|
|
311
|
-
injectPrompt(lastSessionID,
|
|
272
|
+
injectPrompt(lastSessionID, SENIOR_BEHAVIOR_PROMPT);
|
|
312
273
|
}
|
|
313
274
|
}, 100);
|
|
314
|
-
client.app.log({ level: "info", message: `[VibeLearning] Injected
|
|
275
|
+
client.app.log({ level: "info", message: `[VibeLearning] Injected senior mode behavior` }).catch(() => {
|
|
315
276
|
});
|
|
316
277
|
}
|
|
317
278
|
}
|