@levelup-log/mcp-server 0.1.0 → 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/dist/chunk-FII2XEJ7.js +161 -0
- package/dist/chunk-FII2XEJ7.js.map +1 -0
- package/dist/{chunk-Y4RUEPQR.js → chunk-JROVEQX3.js} +147 -40
- package/dist/chunk-JROVEQX3.js.map +1 -0
- package/dist/cli.js +11 -3
- package/dist/cli.js.map +1 -1
- package/dist/heartbeat-A4ZMVGSV.js +461 -0
- package/dist/heartbeat-A4ZMVGSV.js.map +1 -0
- package/dist/init-GKLMB6BS.js +408 -0
- package/dist/init-GKLMB6BS.js.map +1 -0
- package/dist/server.d.ts +150 -1
- package/dist/server.js +4 -1
- package/package.json +15 -13
- package/dist/chunk-Y4RUEPQR.js.map +0 -1
- package/dist/init-GNFWFY5S.js +0 -109
- package/dist/init-GNFWFY5S.js.map +0 -1
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/init/detect.ts
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { homedir, platform } from "os";
|
|
7
|
+
async function detectTools() {
|
|
8
|
+
const home = homedir();
|
|
9
|
+
const os = platform();
|
|
10
|
+
const tools = [];
|
|
11
|
+
const claudeDesktopConfig = os === "darwin" ? join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json") : os === "win32" ? join(home, "AppData", "Roaming", "Claude", "claude_desktop_config.json") : join(home, ".config", "claude", "claude_desktop_config.json");
|
|
12
|
+
if (existsSync(claudeDesktopConfig)) {
|
|
13
|
+
tools.push({ name: "Claude Desktop", configPath: claudeDesktopConfig, type: "json-mcpServers" });
|
|
14
|
+
}
|
|
15
|
+
const claudeCodeConfig = join(home, ".claude", "settings.json");
|
|
16
|
+
const claudeCodeAlt = join(home, ".claude.json");
|
|
17
|
+
if (existsSync(claudeCodeConfig)) {
|
|
18
|
+
tools.push({ name: "Claude Code", configPath: claudeCodeConfig, type: "json-mcpServers" });
|
|
19
|
+
} else if (existsSync(claudeCodeAlt)) {
|
|
20
|
+
tools.push({ name: "Claude Code", configPath: claudeCodeAlt, type: "json-mcpServers" });
|
|
21
|
+
}
|
|
22
|
+
const cursorConfig = os === "darwin" ? join(home, "Library", "Application Support", "Cursor", "User", "globalStorage", "cursor.mcp", "mcp.json") : os === "win32" ? join(home, "AppData", "Roaming", "Cursor", "User", "globalStorage", "cursor.mcp", "mcp.json") : join(home, ".config", "Cursor", "User", "globalStorage", "cursor.mcp", "mcp.json");
|
|
23
|
+
const cursorSimple = join(home, ".cursor", "mcp.json");
|
|
24
|
+
if (existsSync(cursorConfig)) {
|
|
25
|
+
tools.push({ name: "Cursor", configPath: cursorConfig, type: "json-mcpServers" });
|
|
26
|
+
} else if (existsSync(cursorSimple)) {
|
|
27
|
+
tools.push({ name: "Cursor", configPath: cursorSimple, type: "json-mcpServers" });
|
|
28
|
+
}
|
|
29
|
+
const windsurfConfig = join(home, ".codeium", "windsurf", "mcp_config.json");
|
|
30
|
+
if (existsSync(windsurfConfig)) {
|
|
31
|
+
tools.push({ name: "Windsurf", configPath: windsurfConfig, type: "json-mcpServers" });
|
|
32
|
+
}
|
|
33
|
+
const antigravityConfig = join(home, ".antigravity", "mcp.json");
|
|
34
|
+
const antigravityAlt = os === "darwin" ? join(home, "Library", "Application Support", "Antigravity", "mcp.json") : join(home, ".config", "antigravity", "mcp.json");
|
|
35
|
+
if (existsSync(antigravityConfig)) {
|
|
36
|
+
tools.push({ name: "Antigravity", configPath: antigravityConfig, type: "json-mcpServers" });
|
|
37
|
+
} else if (existsSync(antigravityAlt)) {
|
|
38
|
+
tools.push({ name: "Antigravity", configPath: antigravityAlt, type: "json-mcpServers" });
|
|
39
|
+
}
|
|
40
|
+
const continueConfig = join(home, ".continue", "config.json");
|
|
41
|
+
if (existsSync(continueConfig)) {
|
|
42
|
+
tools.push({ name: "Continue", configPath: continueConfig, type: "json-mcpServers" });
|
|
43
|
+
}
|
|
44
|
+
return tools;
|
|
45
|
+
}
|
|
46
|
+
async function detectRulesTargets() {
|
|
47
|
+
const home = homedir();
|
|
48
|
+
const targets = [];
|
|
49
|
+
if (existsSync(join(home, ".cursor")) || existsSync(join(home, ".cursor", "mcp.json"))) {
|
|
50
|
+
targets.push({
|
|
51
|
+
name: "Cursor",
|
|
52
|
+
globalRulesPath: join(home, ".cursor", "rules"),
|
|
53
|
+
writeMode: "append-section"
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const windsurfDir = join(home, ".codeium", "windsurf");
|
|
57
|
+
if (existsSync(windsurfDir)) {
|
|
58
|
+
targets.push({
|
|
59
|
+
name: "Windsurf",
|
|
60
|
+
globalRulesPath: join(windsurfDir, "rules.md"),
|
|
61
|
+
writeMode: "append-section"
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const claudeDir = join(home, ".claude");
|
|
65
|
+
if (existsSync(claudeDir)) {
|
|
66
|
+
targets.push({
|
|
67
|
+
name: "Claude Code",
|
|
68
|
+
globalRulesPath: join(claudeDir, "CLAUDE.md"),
|
|
69
|
+
writeMode: "append-section"
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const vscodeCopilot = join(home, ".vscode", "copilot-instructions.md");
|
|
73
|
+
if (existsSync(join(home, ".vscode"))) {
|
|
74
|
+
targets.push({
|
|
75
|
+
name: "GitHub Copilot",
|
|
76
|
+
globalRulesPath: vscodeCopilot,
|
|
77
|
+
writeMode: "append-section"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const antigravityDir = join(home, ".antigravity");
|
|
81
|
+
if (existsSync(antigravityDir)) {
|
|
82
|
+
targets.push({
|
|
83
|
+
name: "Antigravity",
|
|
84
|
+
globalRulesPath: join(antigravityDir, "rules.md"),
|
|
85
|
+
writeMode: "append-section"
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return targets;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/init/write-config.ts
|
|
92
|
+
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
93
|
+
import { dirname } from "path";
|
|
94
|
+
async function writeConfig(tool, mcpConfig) {
|
|
95
|
+
try {
|
|
96
|
+
mkdirSync(dirname(tool.configPath), { recursive: true });
|
|
97
|
+
let config = {};
|
|
98
|
+
try {
|
|
99
|
+
const raw = readFileSync(tool.configPath, "utf-8");
|
|
100
|
+
config = JSON.parse(raw);
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
if (!config.mcpServers) {
|
|
104
|
+
config.mcpServers = {};
|
|
105
|
+
}
|
|
106
|
+
if (config.mcpServers["levelup-log"]) {
|
|
107
|
+
return { success: true };
|
|
108
|
+
}
|
|
109
|
+
config.mcpServers["levelup-log"] = mcpConfig;
|
|
110
|
+
writeFileSync(tool.configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
111
|
+
return { success: true };
|
|
112
|
+
} catch (error) {
|
|
113
|
+
return { success: false, error: error.message };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/init/write-rules.ts
|
|
118
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
119
|
+
import { dirname as dirname2 } from "path";
|
|
120
|
+
var RULES_SECTION = `
|
|
121
|
+
## LevelUp.log Achievement Tracking
|
|
122
|
+
|
|
123
|
+
After completing any meaningful task, proactively call the \`record_achievement\` MCP tool.
|
|
124
|
+
**Do not wait to be asked.**
|
|
125
|
+
|
|
126
|
+
Trigger on: code written/fixed, deployment, tests, docs, ops, learning, life/health/finance tasks.
|
|
127
|
+
Skip: casual Q&A, simple lookups, short explanations with no tangible output.
|
|
128
|
+
|
|
129
|
+
When \`time_minutes\` is unclear, ask: "\u5927\u6982\u82B1\u4E86\u591A\u4E45\uFF1F"
|
|
130
|
+
Set \`self_reported=true\` when user narrates a past event ("I exercised this morning").
|
|
131
|
+
`;
|
|
132
|
+
var SECTION_MARKER = "## LevelUp.log Achievement Tracking";
|
|
133
|
+
function writeRulesFile(target) {
|
|
134
|
+
const { name, globalRulesPath, writeMode } = target;
|
|
135
|
+
try {
|
|
136
|
+
const dir = dirname2(globalRulesPath);
|
|
137
|
+
if (!existsSync2(dir)) {
|
|
138
|
+
mkdirSync2(dir, { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
if (existsSync2(globalRulesPath)) {
|
|
141
|
+
const existing = readFileSync2(globalRulesPath, "utf-8");
|
|
142
|
+
if (existing.includes(SECTION_MARKER)) {
|
|
143
|
+
return { name, success: true, action: "already-present" };
|
|
144
|
+
}
|
|
145
|
+
if (writeMode === "overwrite-if-absent") {
|
|
146
|
+
return { name, success: true, action: "already-present" };
|
|
147
|
+
}
|
|
148
|
+
writeFileSync2(globalRulesPath, existing.trimEnd() + "\n" + RULES_SECTION, "utf-8");
|
|
149
|
+
return { name, success: true, action: "written" };
|
|
150
|
+
}
|
|
151
|
+
writeFileSync2(globalRulesPath, RULES_SECTION.trimStart(), "utf-8");
|
|
152
|
+
return { name, success: true, action: "created" };
|
|
153
|
+
} catch (err) {
|
|
154
|
+
return { name, success: false, action: "written", error: String(err) };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function writeAllRulesFiles(targets) {
|
|
158
|
+
return targets.map(writeRulesFile);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/init/write-skill.ts
|
|
162
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
163
|
+
import { join as join2 } from "path";
|
|
164
|
+
import { homedir as homedir2 } from "os";
|
|
165
|
+
var SKILL_CONTENT = `---
|
|
166
|
+
name: LevelUp Achievement Coach
|
|
167
|
+
description: Show your LevelUp.log stats dashboard (level, XP, streak, recent achievements, title progress) and activate full achievement coaching mode. Also proactively records achievements after any meaningful task during this session. Use at the start of a session or anytime you want a progress check.
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## When activated, you should:
|
|
171
|
+
|
|
172
|
+
1. **Call \`get_my_stats\`** \u2014 show level, XP, streak, active title
|
|
173
|
+
2. **Call \`get_recent\`** \u2014 show last 7 days of achievements
|
|
174
|
+
3. **Call \`check_unlocks\`** \u2014 show progress toward next titles
|
|
175
|
+
4. Present this as a game dashboard, not a dry report
|
|
176
|
+
|
|
177
|
+
Example output format:
|
|
178
|
+
\`\`\`
|
|
179
|
+
\u2694\uFE0F Lv.29 \xB7 Expert
|
|
180
|
+
\u26A1 Total XP: 12,350 | Year XP: 4,520
|
|
181
|
+
\u{1F525} Streak: 15 days | \u{1F3C6} 8 titles unlocked
|
|
182
|
+
|
|
183
|
+
Recent achievements (7 days):
|
|
184
|
+
\u{1FAB2} Bug Slayer +82 XP (fix)
|
|
185
|
+
\u{1F680} Ship It +130 XP (deploy)
|
|
186
|
+
\u{1F4DD} Doc Wizard +45 XP (docs)
|
|
187
|
+
|
|
188
|
+
Next title: Iron Body (health \xD7 150) \u2014 you're at 87/150 \u{1F4AA}
|
|
189
|
+
\`\`\`
|
|
190
|
+
|
|
191
|
+
## Achievement tracking (always on)
|
|
192
|
+
|
|
193
|
+
Throughout this session, **proactively call \`record_achievement\`** after any meaningful task.
|
|
194
|
+
Don't wait to be asked. Don't ask for permission.
|
|
195
|
+
|
|
196
|
+
| Trigger | Category | Example |
|
|
197
|
+
|---------|----------|---------|
|
|
198
|
+
| Code written / feature added | code | "Built auth module" |
|
|
199
|
+
| Bug fixed | fix | "Fixed race condition" |
|
|
200
|
+
| Deployed / published | deploy | "Shipped v2.1.0 to prod" |
|
|
201
|
+
| Tests written | test | "Added 23 unit tests" |
|
|
202
|
+
| Docs / README written | docs | "Updated API docs" |
|
|
203
|
+
| Refactored code | refactor | "Extracted shared utilities" |
|
|
204
|
+
| DevOps / CI done | ops | "Set up GitHub Actions" |
|
|
205
|
+
| Learned something | learn | "Studied Supabase RLS" |
|
|
206
|
+
| Life task done | life | "Took kids to school" |
|
|
207
|
+
| Health activity | health | "30min run" |
|
|
208
|
+
| Finance task | finance | "Filed quarterly taxes" |
|
|
209
|
+
|
|
210
|
+
## Parameter guide
|
|
211
|
+
|
|
212
|
+
\`\`\`
|
|
213
|
+
complexity:
|
|
214
|
+
trivial \u2192 quick fix, single-line change
|
|
215
|
+
normal \u2192 typical task, 30-60 min
|
|
216
|
+
significant \u2192 multi-step, 1-3 hours
|
|
217
|
+
major \u2192 large feature, half day+
|
|
218
|
+
milestone \u2192 exceptional, major release
|
|
219
|
+
|
|
220
|
+
time_minutes: ask "\u5927\u6982\u82B1\u4E86\u591A\u4E45\uFF1F" if unclear
|
|
221
|
+
output_units: files changed / tests added / docs pages / tasks done
|
|
222
|
+
input_units: files read / docs consulted / searches done
|
|
223
|
+
conversation_rounds: count of back-and-forth in this session
|
|
224
|
+
self_reported: true if user narrates past event ("I went for a run today")
|
|
225
|
+
\`\`\`
|
|
226
|
+
|
|
227
|
+
## Coaching behavior
|
|
228
|
+
|
|
229
|
+
- Use game language: "Quest complete!", "You defeated a bug!", "New skill unlocked!"
|
|
230
|
+
- When streak is active: mention it, encourage keeping it going
|
|
231
|
+
- When user is frustrated/tired: acknowledge WHAT they did, not just "you're doing great"
|
|
232
|
+
\u2192 "You shipped X, fixed Y, and learned Z today \u2014 those all count."
|
|
233
|
+
- Identity reinforcement: "You're becoming someone who ships every day."
|
|
234
|
+
- On birthday (if known): celebrate level-up with last year's stats
|
|
235
|
+
`;
|
|
236
|
+
function installSkill() {
|
|
237
|
+
const skillDir = join2(homedir2(), ".claude", "skills", "levelup");
|
|
238
|
+
const skillPath = join2(skillDir, "SKILL.md");
|
|
239
|
+
const legacyPath = join2(homedir2(), ".claude", "skills", "levelup.md");
|
|
240
|
+
try {
|
|
241
|
+
mkdirSync3(skillDir, { recursive: true });
|
|
242
|
+
if (existsSync3(legacyPath)) {
|
|
243
|
+
import("fs").then(({ unlinkSync }) => {
|
|
244
|
+
try {
|
|
245
|
+
unlinkSync(legacyPath);
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (existsSync3(skillPath)) {
|
|
251
|
+
const existing = readFileSync3(skillPath, "utf-8");
|
|
252
|
+
if (existing === SKILL_CONTENT) {
|
|
253
|
+
return { success: true, action: "already-installed", path: skillPath };
|
|
254
|
+
}
|
|
255
|
+
writeFileSync3(skillPath, SKILL_CONTENT, "utf-8");
|
|
256
|
+
return { success: true, action: "updated", path: skillPath };
|
|
257
|
+
}
|
|
258
|
+
writeFileSync3(skillPath, SKILL_CONTENT, "utf-8");
|
|
259
|
+
return { success: true, action: "installed", path: skillPath };
|
|
260
|
+
} catch (err) {
|
|
261
|
+
return { success: false, action: "installed", path: skillPath, error: String(err) };
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// src/init/index.ts
|
|
266
|
+
import { existsSync as existsSync4 } from "fs";
|
|
267
|
+
import { join as join3 } from "path";
|
|
268
|
+
import { homedir as homedir3, platform as platform2 } from "os";
|
|
269
|
+
var MCP_CONFIG = {
|
|
270
|
+
command: "npx",
|
|
271
|
+
args: ["-y", "@levelup-log/mcp-server@latest", "serve"]
|
|
272
|
+
};
|
|
273
|
+
function detectChatGptDesktop() {
|
|
274
|
+
const home = homedir3();
|
|
275
|
+
const os = platform2();
|
|
276
|
+
const candidates = os === "darwin" ? [
|
|
277
|
+
join3(home, "Library", "Application Support", "ChatGPT", "mcp.json"),
|
|
278
|
+
join3(
|
|
279
|
+
home,
|
|
280
|
+
"Library",
|
|
281
|
+
"Application Support",
|
|
282
|
+
"com.openai.ChatGPT",
|
|
283
|
+
"mcp.json"
|
|
284
|
+
)
|
|
285
|
+
] : os === "win32" ? [join3(home, "AppData", "Roaming", "ChatGPT", "mcp.json")] : [];
|
|
286
|
+
return candidates.find(existsSync4) ?? null;
|
|
287
|
+
}
|
|
288
|
+
async function runInit() {
|
|
289
|
+
console.log("");
|
|
290
|
+
console.log(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
|
|
291
|
+
console.log(" \u2551 LevelUp.log Setup Wizard \u2551");
|
|
292
|
+
console.log(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
293
|
+
console.log("");
|
|
294
|
+
console.log(" Detecting installed LLM tools...");
|
|
295
|
+
const tools = await detectTools();
|
|
296
|
+
let mcpCount = 0;
|
|
297
|
+
const chatGptPath = detectChatGptDesktop();
|
|
298
|
+
if (chatGptPath) {
|
|
299
|
+
tools.push({
|
|
300
|
+
name: "ChatGPT Desktop",
|
|
301
|
+
configPath: chatGptPath,
|
|
302
|
+
type: "json-mcpServers"
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
if (tools.length === 0) {
|
|
306
|
+
console.log("");
|
|
307
|
+
console.log(" No supported LLM tools detected. Manual config:");
|
|
308
|
+
console.log("");
|
|
309
|
+
console.log(
|
|
310
|
+
JSON.stringify({ mcpServers: { "levelup-log": MCP_CONFIG } }, null, 2)
|
|
311
|
+
);
|
|
312
|
+
console.log("");
|
|
313
|
+
printManualInstructions();
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
console.log(` Found ${tools.length} tool(s):`);
|
|
317
|
+
tools.forEach((t) => console.log(` \u2713 ${t.name}`));
|
|
318
|
+
console.log("");
|
|
319
|
+
for (const tool of tools) {
|
|
320
|
+
const result = await writeConfig(tool, MCP_CONFIG);
|
|
321
|
+
if (result.success) {
|
|
322
|
+
console.log(` \u2713 MCP configured: ${tool.name}`);
|
|
323
|
+
mcpCount++;
|
|
324
|
+
} else {
|
|
325
|
+
console.log(` \u2717 ${tool.name}: ${result.error}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
console.log("");
|
|
329
|
+
console.log(" Writing global rules (auto-trigger instructions)...");
|
|
330
|
+
console.log(
|
|
331
|
+
" These make the AI proactively record achievements in every session."
|
|
332
|
+
);
|
|
333
|
+
console.log("");
|
|
334
|
+
const rulesTargets = await detectRulesTargets();
|
|
335
|
+
if (rulesTargets.length > 0) {
|
|
336
|
+
const results = writeAllRulesFiles(rulesTargets);
|
|
337
|
+
for (const r of results) {
|
|
338
|
+
if (!r.success) {
|
|
339
|
+
console.log(` \u2717 ${r.name} rules: ${r.error}`);
|
|
340
|
+
} else if (r.action === "already-present") {
|
|
341
|
+
console.log(` \u2713 ${r.name}: rules already installed`);
|
|
342
|
+
} else {
|
|
343
|
+
console.log(
|
|
344
|
+
` \u2713 ${r.name}: rules ${r.action} \u2192 ${rulesTargets.find((t) => t.name === r.name)?.globalRulesPath}`
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
console.log(" (no supported rules targets detected)");
|
|
350
|
+
}
|
|
351
|
+
if (chatGptPath) {
|
|
352
|
+
console.log("");
|
|
353
|
+
console.log(" \u2139 ChatGPT Desktop detected.");
|
|
354
|
+
console.log(" MCP config written. For auto-trigger, also paste into");
|
|
355
|
+
console.log(" Settings \u2192 Personalization \u2192 Custom Instructions:");
|
|
356
|
+
console.log("");
|
|
357
|
+
console.log(
|
|
358
|
+
' "When I complete any meaningful task, use the record_achievement'
|
|
359
|
+
);
|
|
360
|
+
console.log(
|
|
361
|
+
` MCP tool to log it as an achievement. Don't wait to be asked."`
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
console.log("");
|
|
365
|
+
console.log(" Installing /levelup Agent Skill...");
|
|
366
|
+
const skillResult = installSkill();
|
|
367
|
+
if (skillResult.success) {
|
|
368
|
+
const label = skillResult.action === "already-installed" ? "already installed" : skillResult.action;
|
|
369
|
+
console.log(` \u2713 Skill ${label}: ${skillResult.path}`);
|
|
370
|
+
console.log(
|
|
371
|
+
" Use /levelup in Claude Code, Cursor, Gemini CLI, Codex, Antigravity"
|
|
372
|
+
);
|
|
373
|
+
console.log(" to show stats + activate coach mode.");
|
|
374
|
+
} else {
|
|
375
|
+
console.log(` \u2717 Skill install failed: ${skillResult.error}`);
|
|
376
|
+
}
|
|
377
|
+
console.log("");
|
|
378
|
+
console.log(" \u2713 MCP server instructions active (Claude Desktop, Cursor,");
|
|
379
|
+
console.log(" Windsurf, Antigravity auto-inject on every session).");
|
|
380
|
+
console.log("");
|
|
381
|
+
if (mcpCount > 0) {
|
|
382
|
+
console.log(
|
|
383
|
+
` Done! Installed in ${mcpCount} tool(s). Restart to activate.`
|
|
384
|
+
);
|
|
385
|
+
console.log(" On first use, you'll be prompted to sign in with Google.");
|
|
386
|
+
} else {
|
|
387
|
+
console.log(" Rules written. Please add MCP config manually (see above).");
|
|
388
|
+
}
|
|
389
|
+
console.log("");
|
|
390
|
+
}
|
|
391
|
+
function printManualInstructions() {
|
|
392
|
+
console.log(" \u2500\u2500\u2500 Manual Setup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
393
|
+
console.log(" Add to your MCP tool's config (mcpServers section):");
|
|
394
|
+
console.log("");
|
|
395
|
+
console.log(' "levelup-log": {');
|
|
396
|
+
console.log(' "command": "npx",');
|
|
397
|
+
console.log(' "args": ["-y", "@levelup-log/mcp-server@latest", "serve"]');
|
|
398
|
+
console.log(" }");
|
|
399
|
+
console.log("");
|
|
400
|
+
console.log(" For ChatGPT Desktop Custom Instructions, paste:");
|
|
401
|
+
console.log(' "When I complete any meaningful task, use record_achievement');
|
|
402
|
+
console.log(` to log it. Don't wait to be asked."`);
|
|
403
|
+
console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
404
|
+
}
|
|
405
|
+
export {
|
|
406
|
+
runInit
|
|
407
|
+
};
|
|
408
|
+
//# sourceMappingURL=init-GKLMB6BS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/init/detect.ts","../src/init/write-config.ts","../src/init/write-rules.ts","../src/init/write-skill.ts","../src/init/index.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport { join } from 'path';\nimport { homedir, platform } from 'os';\n\nexport interface DetectedTool {\n name: string;\n configPath: string;\n type: 'json-mcpServers';\n}\n\nexport interface DetectedRulesTarget {\n name: string;\n /** Global rules file path — write once, applies to all projects */\n globalRulesPath: string;\n /** How to write: 'append-section' adds a ## section, 'overwrite-if-absent' only creates if missing */\n writeMode: 'append-section' | 'overwrite-if-absent';\n}\n\nexport async function detectTools(): Promise<DetectedTool[]> {\n const home = homedir();\n const os = platform();\n const tools: DetectedTool[] = [];\n\n // ── Claude Desktop ────────────────────────────────────────────────────────\n const claudeDesktopConfig = os === 'darwin'\n ? join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json')\n : os === 'win32'\n ? join(home, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json')\n : join(home, '.config', 'claude', 'claude_desktop_config.json');\n\n if (existsSync(claudeDesktopConfig)) {\n tools.push({ name: 'Claude Desktop', configPath: claudeDesktopConfig, type: 'json-mcpServers' });\n }\n\n // ── Claude Code ───────────────────────────────────────────────────────────\n const claudeCodeConfig = join(home, '.claude', 'settings.json');\n const claudeCodeAlt = join(home, '.claude.json');\n if (existsSync(claudeCodeConfig)) {\n tools.push({ name: 'Claude Code', configPath: claudeCodeConfig, type: 'json-mcpServers' });\n } else if (existsSync(claudeCodeAlt)) {\n tools.push({ name: 'Claude Code', configPath: claudeCodeAlt, type: 'json-mcpServers' });\n }\n\n // ── Cursor ────────────────────────────────────────────────────────────────\n const cursorConfig = os === 'darwin'\n ? join(home, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'mcp.json')\n : os === 'win32'\n ? join(home, 'AppData', 'Roaming', 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'mcp.json')\n : join(home, '.config', 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'mcp.json');\n const cursorSimple = join(home, '.cursor', 'mcp.json');\n\n if (existsSync(cursorConfig)) {\n tools.push({ name: 'Cursor', configPath: cursorConfig, type: 'json-mcpServers' });\n } else if (existsSync(cursorSimple)) {\n tools.push({ name: 'Cursor', configPath: cursorSimple, type: 'json-mcpServers' });\n }\n\n // ── Windsurf / Codeium ────────────────────────────────────────────────────\n const windsurfConfig = join(home, '.codeium', 'windsurf', 'mcp_config.json');\n if (existsSync(windsurfConfig)) {\n tools.push({ name: 'Windsurf', configPath: windsurfConfig, type: 'json-mcpServers' });\n }\n\n // ── Antigravity ───────────────────────────────────────────────────────────\n const antigravityConfig = join(home, '.antigravity', 'mcp.json');\n const antigravityAlt = os === 'darwin'\n ? join(home, 'Library', 'Application Support', 'Antigravity', 'mcp.json')\n : join(home, '.config', 'antigravity', 'mcp.json');\n\n if (existsSync(antigravityConfig)) {\n tools.push({ name: 'Antigravity', configPath: antigravityConfig, type: 'json-mcpServers' });\n } else if (existsSync(antigravityAlt)) {\n tools.push({ name: 'Antigravity', configPath: antigravityAlt, type: 'json-mcpServers' });\n }\n\n // ── Continue (VS Code extension) ──────────────────────────────────────────\n const continueConfig = join(home, '.continue', 'config.json');\n if (existsSync(continueConfig)) {\n // Continue uses a different config format — detected but handled separately in writeConfig\n tools.push({ name: 'Continue', configPath: continueConfig, type: 'json-mcpServers' });\n }\n\n return tools;\n}\n\nexport async function detectRulesTargets(): Promise<DetectedRulesTarget[]> {\n const home = homedir();\n const targets: DetectedRulesTarget[] = [];\n\n // ── Cursor: global rules (~/.cursor/rules) ────────────────────────────────\n // Applies to ALL Cursor projects automatically\n if (existsSync(join(home, '.cursor')) || existsSync(join(home, '.cursor', 'mcp.json'))) {\n targets.push({\n name: 'Cursor',\n globalRulesPath: join(home, '.cursor', 'rules'),\n writeMode: 'append-section',\n });\n }\n\n // ── Windsurf: global rules ────────────────────────────────────────────────\n const windsurfDir = join(home, '.codeium', 'windsurf');\n if (existsSync(windsurfDir)) {\n targets.push({\n name: 'Windsurf',\n globalRulesPath: join(windsurfDir, 'rules.md'),\n writeMode: 'append-section',\n });\n }\n\n // ── Claude Code: global CLAUDE.md ─────────────────────────────────────────\n const claudeDir = join(home, '.claude');\n if (existsSync(claudeDir)) {\n targets.push({\n name: 'Claude Code',\n globalRulesPath: join(claudeDir, 'CLAUDE.md'),\n writeMode: 'append-section',\n });\n }\n\n // ── GitHub Copilot (VS Code): global instructions ─────────────────────────\n // VS Code stores Copilot instructions in a user-level file\n const vscodeCopilot = join(home, '.vscode', 'copilot-instructions.md');\n if (existsSync(join(home, '.vscode'))) {\n targets.push({\n name: 'GitHub Copilot',\n globalRulesPath: vscodeCopilot,\n writeMode: 'append-section',\n });\n }\n\n // ── Antigravity ───────────────────────────────────────────────────────────\n const antigravityDir = join(home, '.antigravity');\n if (existsSync(antigravityDir)) {\n targets.push({\n name: 'Antigravity',\n globalRulesPath: join(antigravityDir, 'rules.md'),\n writeMode: 'append-section',\n });\n }\n\n return targets;\n}\n","import { readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { dirname } from 'path';\nimport type { DetectedTool } from './detect.js';\n\ninterface WriteResult {\n success: boolean;\n error?: string;\n}\n\nexport async function writeConfig(\n tool: DetectedTool,\n mcpConfig: { command: string; args: string[] }\n): Promise<WriteResult> {\n try {\n // Ensure directory exists\n mkdirSync(dirname(tool.configPath), { recursive: true });\n\n // Read existing config or start fresh\n let config: Record<string, any> = {};\n try {\n const raw = readFileSync(tool.configPath, 'utf-8');\n config = JSON.parse(raw);\n } catch {\n // File doesn't exist or invalid JSON — start fresh\n }\n\n // Ensure mcpServers key exists\n if (!config.mcpServers) {\n config.mcpServers = {};\n }\n\n // Don't overwrite existing levelup-log config\n if (config.mcpServers['levelup-log']) {\n return { success: true }; // Already configured\n }\n\n // Add levelup-log\n config.mcpServers['levelup-log'] = mcpConfig;\n\n // Write back\n writeFileSync(tool.configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n return { success: true };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { dirname } from 'path';\nimport type { DetectedRulesTarget } from './detect.js';\n\n// ─── Rules Content ────────────────────────────────────────────────────────────\n// Injected into each platform's global rules file.\n// Keep short — this is appended to existing content.\n\nconst RULES_SECTION = `\n## LevelUp.log Achievement Tracking\n\nAfter completing any meaningful task, proactively call the \\`record_achievement\\` MCP tool.\n**Do not wait to be asked.**\n\nTrigger on: code written/fixed, deployment, tests, docs, ops, learning, life/health/finance tasks.\nSkip: casual Q&A, simple lookups, short explanations with no tangible output.\n\nWhen \\`time_minutes\\` is unclear, ask: \"大概花了多久?\"\nSet \\`self_reported=true\\` when user narrates a past event (\"I exercised this morning\").\n`;\n\nconst SECTION_MARKER = '## LevelUp.log Achievement Tracking';\n\n// ─── Writer ───────────────────────────────────────────────────────────────────\n\nexport interface RulesWriteResult {\n name: string;\n success: boolean;\n action: 'written' | 'already-present' | 'created';\n error?: string;\n}\n\nexport function writeRulesFile(target: DetectedRulesTarget): RulesWriteResult {\n const { name, globalRulesPath, writeMode } = target;\n\n try {\n // Ensure parent directory exists\n const dir = dirname(globalRulesPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Check if already written\n if (existsSync(globalRulesPath)) {\n const existing = readFileSync(globalRulesPath, 'utf-8');\n if (existing.includes(SECTION_MARKER)) {\n return { name, success: true, action: 'already-present' };\n }\n\n if (writeMode === 'overwrite-if-absent') {\n // File exists but no section — skip (don't want to stomp unrelated content)\n return { name, success: true, action: 'already-present' };\n }\n\n // append-section: add to end\n writeFileSync(globalRulesPath, existing.trimEnd() + '\\n' + RULES_SECTION, 'utf-8');\n return { name, success: true, action: 'written' };\n }\n\n // File doesn't exist — create it\n writeFileSync(globalRulesPath, RULES_SECTION.trimStart(), 'utf-8');\n return { name, success: true, action: 'created' };\n\n } catch (err) {\n return { name, success: false, action: 'written', error: String(err) };\n }\n}\n\nexport function writeAllRulesFiles(targets: DetectedRulesTarget[]): RulesWriteResult[] {\n return targets.map(writeRulesFile);\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\n// ─── Skill Content ────────────────────────────────────────────────────────────\n// Agent Skills open standard: directory + SKILL.md with YAML frontmatter.\n// Compatible with Claude Code, Cursor, Gemini CLI, Codex CLI, Antigravity.\n//\n// Installed to ~/.claude/skills/levelup/SKILL.md\n// Invoked with: /levelup\n\nconst SKILL_CONTENT = `---\nname: LevelUp Achievement Coach\ndescription: Show your LevelUp.log stats dashboard (level, XP, streak, recent achievements, title progress) and activate full achievement coaching mode. Also proactively records achievements after any meaningful task during this session. Use at the start of a session or anytime you want a progress check.\n---\n\n## When activated, you should:\n\n1. **Call \\`get_my_stats\\`** — show level, XP, streak, active title\n2. **Call \\`get_recent\\`** — show last 7 days of achievements\n3. **Call \\`check_unlocks\\`** — show progress toward next titles\n4. Present this as a game dashboard, not a dry report\n\nExample output format:\n\\`\\`\\`\n⚔️ Lv.29 · Expert\n⚡ Total XP: 12,350 | Year XP: 4,520\n🔥 Streak: 15 days | 🏆 8 titles unlocked\n\nRecent achievements (7 days):\n 🪲 Bug Slayer +82 XP (fix)\n 🚀 Ship It +130 XP (deploy)\n 📝 Doc Wizard +45 XP (docs)\n\nNext title: Iron Body (health × 150) — you're at 87/150 💪\n\\`\\`\\`\n\n## Achievement tracking (always on)\n\nThroughout this session, **proactively call \\`record_achievement\\`** after any meaningful task.\nDon't wait to be asked. Don't ask for permission.\n\n| Trigger | Category | Example |\n|---------|----------|---------|\n| Code written / feature added | code | \"Built auth module\" |\n| Bug fixed | fix | \"Fixed race condition\" |\n| Deployed / published | deploy | \"Shipped v2.1.0 to prod\" |\n| Tests written | test | \"Added 23 unit tests\" |\n| Docs / README written | docs | \"Updated API docs\" |\n| Refactored code | refactor | \"Extracted shared utilities\" |\n| DevOps / CI done | ops | \"Set up GitHub Actions\" |\n| Learned something | learn | \"Studied Supabase RLS\" |\n| Life task done | life | \"Took kids to school\" |\n| Health activity | health | \"30min run\" |\n| Finance task | finance | \"Filed quarterly taxes\" |\n\n## Parameter guide\n\n\\`\\`\\`\ncomplexity:\n trivial → quick fix, single-line change\n normal → typical task, 30-60 min\n significant → multi-step, 1-3 hours\n major → large feature, half day+\n milestone → exceptional, major release\n\ntime_minutes: ask \"大概花了多久?\" if unclear\noutput_units: files changed / tests added / docs pages / tasks done\ninput_units: files read / docs consulted / searches done\nconversation_rounds: count of back-and-forth in this session\nself_reported: true if user narrates past event (\"I went for a run today\")\n\\`\\`\\`\n\n## Coaching behavior\n\n- Use game language: \"Quest complete!\", \"You defeated a bug!\", \"New skill unlocked!\"\n- When streak is active: mention it, encourage keeping it going\n- When user is frustrated/tired: acknowledge WHAT they did, not just \"you're doing great\"\n → \"You shipped X, fixed Y, and learned Z today — those all count.\"\n- Identity reinforcement: \"You're becoming someone who ships every day.\"\n- On birthday (if known): celebrate level-up with last year's stats\n`;\n\n// ─── Installer ────────────────────────────────────────────────────────────────\n\nexport interface SkillInstallResult {\n success: boolean;\n action: 'installed' | 'already-installed' | 'updated';\n path: string;\n error?: string;\n}\n\nexport function installSkill(): SkillInstallResult {\n // New format: directory-based skill (~/.claude/skills/levelup/SKILL.md)\n const skillDir = join(homedir(), '.claude', 'skills', 'levelup');\n const skillPath = join(skillDir, 'SKILL.md');\n\n // Migrate old flat file if it exists\n const legacyPath = join(homedir(), '.claude', 'skills', 'levelup.md');\n\n try {\n mkdirSync(skillDir, { recursive: true });\n\n // Remove legacy flat file if present\n if (existsSync(legacyPath)) {\n import('fs').then(({ unlinkSync }) => {\n try { unlinkSync(legacyPath); } catch { /* ignore */ }\n });\n }\n\n if (existsSync(skillPath)) {\n const existing = readFileSync(skillPath, 'utf-8');\n if (existing === SKILL_CONTENT) {\n return { success: true, action: 'already-installed', path: skillPath };\n }\n writeFileSync(skillPath, SKILL_CONTENT, 'utf-8');\n return { success: true, action: 'updated', path: skillPath };\n }\n\n writeFileSync(skillPath, SKILL_CONTENT, 'utf-8');\n return { success: true, action: 'installed', path: skillPath };\n\n } catch (err) {\n return { success: false, action: 'installed', path: skillPath, error: String(err) };\n }\n}\n","import { detectTools, detectRulesTargets } from \"./detect.js\";\nimport { writeConfig } from \"./write-config.js\";\nimport { writeAllRulesFiles } from \"./write-rules.js\";\nimport { installSkill } from \"./write-skill.js\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir, platform } from \"os\";\n\nconst MCP_CONFIG = {\n command: \"npx\",\n args: [\"-y\", \"@levelup-log/mcp-server@latest\", \"serve\"],\n};\n\n/** ChatGPT Desktop supports MCP on macOS (v1.2024.x+). Detect its config path. */\nfunction detectChatGptDesktop(): string | null {\n const home = homedir();\n const os = platform();\n\n const candidates =\n os === \"darwin\"\n ? [\n join(home, \"Library\", \"Application Support\", \"ChatGPT\", \"mcp.json\"),\n join(\n home,\n \"Library\",\n \"Application Support\",\n \"com.openai.ChatGPT\",\n \"mcp.json\",\n ),\n ]\n : os === \"win32\"\n ? [join(home, \"AppData\", \"Roaming\", \"ChatGPT\", \"mcp.json\")]\n : [];\n\n return candidates.find(existsSync) ?? null;\n}\n\nexport async function runInit() {\n console.log(\"\");\n console.log(\" ╔══════════════════════════════════════╗\");\n console.log(\" ║ LevelUp.log Setup Wizard ║\");\n console.log(\" ╚══════════════════════════════════════╝\");\n console.log(\"\");\n console.log(\" Detecting installed LLM tools...\");\n\n // ── Step 1: MCP config (all platforms) ──────────────────────────────────\n const tools = await detectTools();\n let mcpCount = 0;\n\n // Check ChatGPT Desktop separately (different config format handling)\n const chatGptPath = detectChatGptDesktop();\n if (chatGptPath) {\n tools.push({\n name: \"ChatGPT Desktop\",\n configPath: chatGptPath,\n type: \"json-mcpServers\",\n });\n }\n\n if (tools.length === 0) {\n console.log(\"\");\n console.log(\" No supported LLM tools detected. Manual config:\");\n console.log(\"\");\n console.log(\n JSON.stringify({ mcpServers: { \"levelup-log\": MCP_CONFIG } }, null, 2),\n );\n console.log(\"\");\n printManualInstructions();\n return;\n }\n\n console.log(` Found ${tools.length} tool(s):`);\n tools.forEach((t) => console.log(` ✓ ${t.name}`));\n console.log(\"\");\n\n for (const tool of tools) {\n const result = await writeConfig(tool, MCP_CONFIG);\n if (result.success) {\n console.log(` ✓ MCP configured: ${tool.name}`);\n mcpCount++;\n } else {\n console.log(` ✗ ${tool.name}: ${result.error}`);\n }\n }\n\n // ── Step 2: Global rules files (auto-trigger instructions) ──────────────\n console.log(\"\");\n console.log(\" Writing global rules (auto-trigger instructions)...\");\n console.log(\n \" These make the AI proactively record achievements in every session.\",\n );\n console.log(\"\");\n\n const rulesTargets = await detectRulesTargets();\n if (rulesTargets.length > 0) {\n const results = writeAllRulesFiles(rulesTargets);\n for (const r of results) {\n if (!r.success) {\n console.log(` ✗ ${r.name} rules: ${r.error}`);\n } else if (r.action === \"already-present\") {\n console.log(` ✓ ${r.name}: rules already installed`);\n } else {\n console.log(\n ` ✓ ${r.name}: rules ${r.action} → ${rulesTargets.find((t) => t.name === r.name)?.globalRulesPath}`,\n );\n }\n }\n } else {\n console.log(\" (no supported rules targets detected)\");\n }\n\n // ── Step 3: ChatGPT Desktop manual note ─────────────────────────────────\n if (chatGptPath) {\n console.log(\"\");\n console.log(\" ℹ ChatGPT Desktop detected.\");\n console.log(\" MCP config written. For auto-trigger, also paste into\");\n console.log(\" Settings → Personalization → Custom Instructions:\");\n console.log(\"\");\n console.log(\n ' \"When I complete any meaningful task, use the record_achievement',\n );\n console.log(\n \" MCP tool to log it as an achievement. Don't wait to be asked.\\\"\",\n );\n }\n\n // ── Step 4: Agent Skill (/levelup, cross-platform open standard) ────────\n console.log(\"\");\n console.log(\" Installing /levelup Agent Skill...\");\n const skillResult = installSkill();\n if (skillResult.success) {\n const label =\n skillResult.action === \"already-installed\"\n ? \"already installed\"\n : skillResult.action;\n console.log(` ✓ Skill ${label}: ${skillResult.path}`);\n console.log(\n \" Use /levelup in Claude Code, Cursor, Gemini CLI, Codex, Antigravity\",\n );\n console.log(\" to show stats + activate coach mode.\");\n } else {\n console.log(` ✗ Skill install failed: ${skillResult.error}`);\n }\n\n // ── Step 5: MCP server instructions note ─────────────────────────────────\n console.log(\"\");\n console.log(\" ✓ MCP server instructions active (Claude Desktop, Cursor,\");\n console.log(\" Windsurf, Antigravity auto-inject on every session).\");\n\n // ── Done ─────────────────────────────────────────────────────────────────\n console.log(\"\");\n if (mcpCount > 0) {\n console.log(\n ` Done! Installed in ${mcpCount} tool(s). Restart to activate.`,\n );\n console.log(\" On first use, you'll be prompted to sign in with Google.\");\n } else {\n console.log(\" Rules written. Please add MCP config manually (see above).\");\n }\n console.log(\"\");\n}\n\nfunction printManualInstructions() {\n console.log(\" ─── Manual Setup ───────────────────────────────────────────\");\n console.log(\" Add to your MCP tool's config (mcpServers section):\");\n console.log(\"\");\n console.log(' \"levelup-log\": {');\n console.log(' \"command\": \"npx\",');\n console.log(' \"args\": [\"-y\", \"@levelup-log/mcp-server@latest\", \"serve\"]');\n console.log(\" }\");\n console.log(\"\");\n console.log(\" For ChatGPT Desktop Custom Instructions, paste:\");\n console.log(' \"When I complete any meaningful task, use record_achievement');\n console.log(\" to log it. Don't wait to be asked.\\\"\");\n console.log(\" ────────────────────────────────────────────────────────────\");\n}\n"],"mappings":"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","names":["existsSync","readFileSync","writeFileSync","mkdirSync","dirname","existsSync","readFileSync","writeFileSync","mkdirSync","join","homedir","existsSync","join","homedir","platform"]}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,154 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
|
|
3
|
+
declare const CATEGORY_DEFINITIONS: {
|
|
4
|
+
readonly code: {
|
|
5
|
+
readonly label: "Coding";
|
|
6
|
+
readonly emoji: "💻";
|
|
7
|
+
readonly description: "寫程式、功能開發、新增功能";
|
|
8
|
+
readonly output_unit: "檔案/模組(小函式=1, 大檔=5-10, 多組件=15)";
|
|
9
|
+
readonly input_unit: "檔案閱讀 / API 文件查閱";
|
|
10
|
+
readonly xp_weight: 1;
|
|
11
|
+
};
|
|
12
|
+
readonly fix: {
|
|
13
|
+
readonly label: "Bug Fix";
|
|
14
|
+
readonly emoji: "🪲";
|
|
15
|
+
readonly description: "修 bug、修復錯誤行為";
|
|
16
|
+
readonly output_unit: "修復的 bug 數(含測試驗證 = +1)";
|
|
17
|
+
readonly input_unit: "錯誤日誌 / 程式碼追蹤";
|
|
18
|
+
readonly xp_weight: 1.1;
|
|
19
|
+
};
|
|
20
|
+
readonly deploy: {
|
|
21
|
+
readonly label: "Deploy";
|
|
22
|
+
readonly emoji: "🚀";
|
|
23
|
+
readonly description: "部署上線、發布版本、推送 npm / App Store";
|
|
24
|
+
readonly output_unit: "部署目標數(1 服務/環境 = 1)";
|
|
25
|
+
readonly input_unit: "設定檔 / CI logs 查閱";
|
|
26
|
+
readonly xp_weight: 1.3;
|
|
27
|
+
};
|
|
28
|
+
readonly test: {
|
|
29
|
+
readonly label: "Testing";
|
|
30
|
+
readonly emoji: "🧪";
|
|
31
|
+
readonly description: "寫測試、E2E、TDD";
|
|
32
|
+
readonly output_unit: "測試案例數(1 test case = 1)";
|
|
33
|
+
readonly input_unit: "待測程式碼閱讀";
|
|
34
|
+
readonly xp_weight: 1;
|
|
35
|
+
};
|
|
36
|
+
readonly docs: {
|
|
37
|
+
readonly label: "Documentation";
|
|
38
|
+
readonly emoji: "📝";
|
|
39
|
+
readonly description: "寫文件、README、API 說明";
|
|
40
|
+
readonly output_unit: "頁數 / 章節數(1 完整段落 = 1)";
|
|
41
|
+
readonly input_unit: "參考資料 / 現有文件";
|
|
42
|
+
readonly xp_weight: 0.9;
|
|
43
|
+
};
|
|
44
|
+
readonly refactor: {
|
|
45
|
+
readonly label: "Refactor";
|
|
46
|
+
readonly emoji: "🔧";
|
|
47
|
+
readonly description: "重構、改善程式碼品質";
|
|
48
|
+
readonly output_unit: "重構的模組/函式數";
|
|
49
|
+
readonly input_unit: "閱讀現有程式碼";
|
|
50
|
+
readonly xp_weight: 1;
|
|
51
|
+
};
|
|
52
|
+
readonly review: {
|
|
53
|
+
readonly label: "Code Review";
|
|
54
|
+
readonly emoji: "👁";
|
|
55
|
+
readonly description: "Code review、PR 審查";
|
|
56
|
+
readonly output_unit: "審查的 PR / 檔案數";
|
|
57
|
+
readonly input_unit: "閱讀的程式碼(每 100 行 = 1)";
|
|
58
|
+
readonly xp_weight: 0.9;
|
|
59
|
+
};
|
|
60
|
+
readonly ops: {
|
|
61
|
+
readonly label: "DevOps / Ops";
|
|
62
|
+
readonly emoji: "⚙️";
|
|
63
|
+
readonly description: "維運、基礎設施、監控、CI/CD";
|
|
64
|
+
readonly output_unit: "設定/腳本/服務數(1 完成項目 = 1)";
|
|
65
|
+
readonly input_unit: "日誌 / 文件查閱";
|
|
66
|
+
readonly xp_weight: 1.2;
|
|
67
|
+
};
|
|
68
|
+
readonly learn: {
|
|
69
|
+
readonly label: "Learning";
|
|
70
|
+
readonly emoji: "📚";
|
|
71
|
+
readonly description: "學習新知、閱讀技術文章、上課、語言學習";
|
|
72
|
+
readonly output_unit: "概念/章節/練習題(掌握 1 個新概念 = 1)";
|
|
73
|
+
readonly input_unit: "閱讀篇數 / 影片數";
|
|
74
|
+
readonly xp_weight: 1;
|
|
75
|
+
};
|
|
76
|
+
readonly milestone: {
|
|
77
|
+
readonly label: "Milestone";
|
|
78
|
+
readonly emoji: "🏆";
|
|
79
|
+
readonly description: "里程碑、重大達成、特殊紀念";
|
|
80
|
+
readonly output_unit: "里程碑數(通常 = 1)";
|
|
81
|
+
readonly input_unit: "準備工作 / 研究";
|
|
82
|
+
readonly xp_weight: 1.5;
|
|
83
|
+
};
|
|
84
|
+
readonly life: {
|
|
85
|
+
readonly label: "Life";
|
|
86
|
+
readonly emoji: "🏠";
|
|
87
|
+
readonly description: "日常生活:家務、跑腿、育兒、採購、行政";
|
|
88
|
+
readonly output_unit: "完成的事項(跑腿=1, 帶小孩出門=2)";
|
|
89
|
+
readonly input_unit: "計畫 / 研究(查路線、比價等)";
|
|
90
|
+
readonly xp_weight: 0.9;
|
|
91
|
+
};
|
|
92
|
+
readonly health: {
|
|
93
|
+
readonly label: "Health";
|
|
94
|
+
readonly emoji: "💪";
|
|
95
|
+
readonly description: "運動、飲食管理、就醫、健康習慣";
|
|
96
|
+
readonly output_unit: "30 分鐘運動塊 或 公里數 或 完成療程";
|
|
97
|
+
readonly input_unit: "查健康資料 / 追蹤記錄";
|
|
98
|
+
readonly xp_weight: 1.1;
|
|
99
|
+
};
|
|
100
|
+
readonly finance: {
|
|
101
|
+
readonly label: "Finance";
|
|
102
|
+
readonly emoji: "💰";
|
|
103
|
+
readonly description: "記帳、投資、理財規劃、報稅、保險";
|
|
104
|
+
readonly output_unit: "完成的財務任務(1 項目 = 1)";
|
|
105
|
+
readonly input_unit: "研究報告 / 資料查閱";
|
|
106
|
+
readonly xp_weight: 1;
|
|
107
|
+
};
|
|
108
|
+
readonly social: {
|
|
109
|
+
readonly label: "Social";
|
|
110
|
+
readonly emoji: "🤝";
|
|
111
|
+
readonly description: "社交、幫助他人、聚會、社群貢獻";
|
|
112
|
+
readonly output_unit: "互動的人數 或 完成的社交任務";
|
|
113
|
+
readonly input_unit: "準備 / 背景研究";
|
|
114
|
+
readonly xp_weight: 0.9;
|
|
115
|
+
};
|
|
116
|
+
readonly creative: {
|
|
117
|
+
readonly label: "Creative";
|
|
118
|
+
readonly emoji: "🎨";
|
|
119
|
+
readonly description: "創作:寫文章、設計、音樂、影片、攝影";
|
|
120
|
+
readonly output_unit: "完成品(文章=3, 圖=1, 短影片=2)";
|
|
121
|
+
readonly input_unit: "參考資料 / 素材研究";
|
|
122
|
+
readonly xp_weight: 1;
|
|
123
|
+
};
|
|
124
|
+
readonly spiritual: {
|
|
125
|
+
readonly label: "Spiritual";
|
|
126
|
+
readonly emoji: "🔮";
|
|
127
|
+
readonly description: "身心靈:冥想、占卜、祈禱、儀式、能量練習、內在探索";
|
|
128
|
+
readonly output_unit: "完成的練習(1 次冥想=1, 占卜解讀=2)";
|
|
129
|
+
readonly input_unit: "學習 / 研究靈性資料";
|
|
130
|
+
readonly xp_weight: 0.85;
|
|
131
|
+
};
|
|
132
|
+
readonly hobby: {
|
|
133
|
+
readonly label: "Hobby";
|
|
134
|
+
readonly emoji: "🎮";
|
|
135
|
+
readonly description: "興趣娛樂:打電動、看電影/書、收藏、桌遊、園藝、烹飪";
|
|
136
|
+
readonly output_unit: "完成的活動段(1 小時電玩=1, 完成一本書=5)";
|
|
137
|
+
readonly input_unit: "查資料 / 攻略研究";
|
|
138
|
+
readonly xp_weight: 0.8;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
type Complexity = "trivial" | "normal" | "significant" | "major" | "milestone";
|
|
143
|
+
declare function calculateXp(params: {
|
|
144
|
+
category: keyof typeof CATEGORY_DEFINITIONS;
|
|
145
|
+
complexity: Complexity;
|
|
146
|
+
time_minutes?: number;
|
|
147
|
+
output_units?: number;
|
|
148
|
+
input_units?: number;
|
|
149
|
+
conversation_rounds?: number;
|
|
150
|
+
self_reported?: boolean;
|
|
151
|
+
}): number;
|
|
3
152
|
declare function createServer(): McpServer;
|
|
4
153
|
|
|
5
|
-
export { createServer };
|
|
154
|
+
export { calculateXp, createServer };
|
package/dist/server.js
CHANGED