@levelup-log/mcp-server 0.4.0 → 0.4.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/dist/cli.js
CHANGED
|
@@ -15,7 +15,7 @@ async function serve() {
|
|
|
15
15
|
console.error("LevelUp.log MCP server running on stdio");
|
|
16
16
|
}
|
|
17
17
|
async function init() {
|
|
18
|
-
const { runInit } = await import("./init-
|
|
18
|
+
const { runInit } = await import("./init-S6MGBOW7.js");
|
|
19
19
|
await runInit();
|
|
20
20
|
}
|
|
21
21
|
async function heartbeat() {
|
|
@@ -266,9 +266,13 @@ function installSkill() {
|
|
|
266
266
|
import { existsSync as existsSync4 } from "fs";
|
|
267
267
|
import { join as join3 } from "path";
|
|
268
268
|
import { homedir as homedir3, platform as platform2 } from "os";
|
|
269
|
+
import { createRequire } from "module";
|
|
270
|
+
var _require = createRequire(import.meta.url);
|
|
271
|
+
var _pkg = _require("../../package.json");
|
|
272
|
+
var PINNED_VERSION = _pkg.version;
|
|
269
273
|
var MCP_CONFIG = {
|
|
270
274
|
command: "npx",
|
|
271
|
-
args: ["-y",
|
|
275
|
+
args: ["-y", `@levelup-log/mcp-server@${PINNED_VERSION}`]
|
|
272
276
|
};
|
|
273
277
|
function detectChatGptDesktop() {
|
|
274
278
|
const home = homedir3();
|
|
@@ -405,4 +409,4 @@ function printManualInstructions() {
|
|
|
405
409
|
export {
|
|
406
410
|
runInit
|
|
407
411
|
};
|
|
408
|
-
//# sourceMappingURL=init-
|
|
412
|
+
//# sourceMappingURL=init-S6MGBOW7.js.map
|
|
@@ -1 +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"]}
|
|
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\nimport { createRequire } from \"module\";\nconst _require = createRequire(import.meta.url);\nconst _pkg = _require(\"../../package.json\") as { version: string };\nconst PINNED_VERSION = _pkg.version; // e.g. \"0.4.0\" — pinned at install time\n\nconst MCP_CONFIG = {\n command: \"npx\",\n args: [\"-y\", `@levelup-log/mcp-server@${PINNED_VERSION}`],\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"]}
|