buildpartner 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.
Files changed (109) hide show
  1. package/dist/bin/cli.d.ts +2 -0
  2. package/dist/bin/cli.js +44 -0
  3. package/dist/bin/cli.js.map +1 -0
  4. package/dist/src/api-client.d.ts +18 -0
  5. package/dist/src/api-client.js +74 -0
  6. package/dist/src/api-client.js.map +1 -0
  7. package/dist/src/classifiers/activity-classifier.d.ts +12 -0
  8. package/dist/src/classifiers/activity-classifier.js +300 -0
  9. package/dist/src/classifiers/activity-classifier.js.map +1 -0
  10. package/dist/src/classifiers/path-detector.d.ts +33 -0
  11. package/dist/src/classifiers/path-detector.js +98 -0
  12. package/dist/src/classifiers/path-detector.js.map +1 -0
  13. package/dist/src/commands/log-session.d.ts +10 -0
  14. package/dist/src/commands/log-session.js +162 -0
  15. package/dist/src/commands/log-session.js.map +1 -0
  16. package/dist/src/commands/serve.d.ts +1 -0
  17. package/dist/src/commands/serve.js +5 -0
  18. package/dist/src/commands/serve.js.map +1 -0
  19. package/dist/src/commands/setup.d.ts +1 -0
  20. package/dist/src/commands/setup.js +578 -0
  21. package/dist/src/commands/setup.js.map +1 -0
  22. package/dist/src/constants.d.ts +9 -0
  23. package/dist/src/constants.js +12 -0
  24. package/dist/src/constants.js.map +1 -0
  25. package/dist/src/installer/hook-installer.d.ts +19 -0
  26. package/dist/src/installer/hook-installer.js +114 -0
  27. package/dist/src/installer/hook-installer.js.map +1 -0
  28. package/dist/src/installer/mcp-installer.d.ts +9 -0
  29. package/dist/src/installer/mcp-installer.js +80 -0
  30. package/dist/src/installer/mcp-installer.js.map +1 -0
  31. package/dist/src/installer/skill-installer.d.ts +5 -0
  32. package/dist/src/installer/skill-installer.js +55 -0
  33. package/dist/src/installer/skill-installer.js.map +1 -0
  34. package/dist/src/installer/skill-sync.d.ts +10 -0
  35. package/dist/src/installer/skill-sync.js +76 -0
  36. package/dist/src/installer/skill-sync.js.map +1 -0
  37. package/dist/src/mcp/server.d.ts +3 -0
  38. package/dist/src/mcp/server.js +106 -0
  39. package/dist/src/mcp/server.js.map +1 -0
  40. package/dist/src/mcp/subscription-gate.d.ts +19 -0
  41. package/dist/src/mcp/subscription-gate.js +74 -0
  42. package/dist/src/mcp/subscription-gate.js.map +1 -0
  43. package/dist/src/mcp/tools/ai-profile.d.ts +88 -0
  44. package/dist/src/mcp/tools/ai-profile.js +123 -0
  45. package/dist/src/mcp/tools/ai-profile.js.map +1 -0
  46. package/dist/src/mcp/tools/classify-session.d.ts +31 -0
  47. package/dist/src/mcp/tools/classify-session.js +34 -0
  48. package/dist/src/mcp/tools/classify-session.js.map +1 -0
  49. package/dist/src/mcp/tools/get-knowledge.d.ts +25 -0
  50. package/dist/src/mcp/tools/get-knowledge.js +31 -0
  51. package/dist/src/mcp/tools/get-knowledge.js.map +1 -0
  52. package/dist/src/mcp/tools/get-profile.d.ts +1 -0
  53. package/dist/src/mcp/tools/get-profile.js +77 -0
  54. package/dist/src/mcp/tools/get-profile.js.map +1 -0
  55. package/dist/src/mcp/tools/get-stats.d.ts +58 -0
  56. package/dist/src/mcp/tools/get-stats.js +135 -0
  57. package/dist/src/mcp/tools/get-stats.js.map +1 -0
  58. package/dist/src/mcp/tools/get-suggestions.d.ts +7 -0
  59. package/dist/src/mcp/tools/get-suggestions.js +176 -0
  60. package/dist/src/mcp/tools/get-suggestions.js.map +1 -0
  61. package/dist/src/mcp/tools/get-training.d.ts +48 -0
  62. package/dist/src/mcp/tools/get-training.js +102 -0
  63. package/dist/src/mcp/tools/get-training.js.map +1 -0
  64. package/dist/src/mcp/tools/log-highlight.d.ts +32 -0
  65. package/dist/src/mcp/tools/log-highlight.js +39 -0
  66. package/dist/src/mcp/tools/log-highlight.js.map +1 -0
  67. package/dist/src/mcp/tools/quest.d.ts +78 -0
  68. package/dist/src/mcp/tools/quest.js +72 -0
  69. package/dist/src/mcp/tools/quest.js.map +1 -0
  70. package/dist/src/mcp/tools/web-search.d.ts +15 -0
  71. package/dist/src/mcp/tools/web-search.js +17 -0
  72. package/dist/src/mcp/tools/web-search.js.map +1 -0
  73. package/dist/src/readers/history-reader.d.ts +28 -0
  74. package/dist/src/readers/history-reader.js +83 -0
  75. package/dist/src/readers/history-reader.js.map +1 -0
  76. package/dist/src/readers/session-reader.d.ts +89 -0
  77. package/dist/src/readers/session-reader.js +310 -0
  78. package/dist/src/readers/session-reader.js.map +1 -0
  79. package/dist/src/readers/stats-reader.d.ts +38 -0
  80. package/dist/src/readers/stats-reader.js +125 -0
  81. package/dist/src/readers/stats-reader.js.map +1 -0
  82. package/dist/src/store/local-store.d.ts +72 -0
  83. package/dist/src/store/local-store.js +145 -0
  84. package/dist/src/store/local-store.js.map +1 -0
  85. package/dist/src/store/quest-store.d.ts +77 -0
  86. package/dist/src/store/quest-store.js +309 -0
  87. package/dist/src/store/quest-store.js.map +1 -0
  88. package/dist/src/store/status-store.d.ts +73 -0
  89. package/dist/src/store/status-store.js +372 -0
  90. package/dist/src/store/status-store.js.map +1 -0
  91. package/dist/src/suggestions/rules.d.ts +1 -0
  92. package/dist/src/suggestions/rules.js +2 -0
  93. package/dist/src/suggestions/rules.js.map +1 -0
  94. package/dist/src/suggestions/video-links.d.ts +1 -0
  95. package/dist/src/suggestions/video-links.js +2 -0
  96. package/dist/src/suggestions/video-links.js.map +1 -0
  97. package/package.json +35 -0
  98. package/skills/he-coach/SKILL.md +56 -0
  99. package/skills/he-consult/SKILL.md +43 -0
  100. package/skills/he-enhance-claude-md/SKILL.md +58 -0
  101. package/skills/he-flex-socials/SKILL.md +50 -0
  102. package/skills/he-full-audit/SKILL.md +119 -0
  103. package/skills/he-improve-skill/SKILL.md +111 -0
  104. package/skills/he-interview/SKILL.md +54 -0
  105. package/skills/he-life-story/SKILL.md +64 -0
  106. package/skills/he-log-experience/SKILL.md +68 -0
  107. package/skills/he-open-dashboard/SKILL.md +27 -0
  108. package/skills/he-quest-status/SKILL.md +48 -0
  109. package/skills/he-recap-week/SKILL.md +49 -0
@@ -0,0 +1,176 @@
1
+ import { readSessions, readHighlights, readProfile, readAuth } from "../../store/local-store.js";
2
+ import { apiGet } from "../../api-client.js";
3
+ const VIDEO_LINKS = {
4
+ deploy: "How I Deploy Apps in Minutes",
5
+ "mcp-server": "Build Your First MCP Server",
6
+ automation: "How I Automated My Content Pipeline",
7
+ content: "My AI Content Creation System",
8
+ };
9
+ const ALL_ACTIVITY_TYPES = [
10
+ "code", "content", "research", "automation", "design", "ops", "data", "debug",
11
+ ];
12
+ export async function getSuggestions() {
13
+ const auth = readAuth();
14
+ // Try API first
15
+ if (auth?.username) {
16
+ const apiData = await apiGet(`/api/myplayer/dashboard?username=${auth.username}`);
17
+ if (apiData) {
18
+ return generateSuggestions(apiData);
19
+ }
20
+ }
21
+ // Fallback to local
22
+ return generateLocalSuggestions();
23
+ }
24
+ function generateSuggestions(data) {
25
+ const suggestions = [];
26
+ const sessions = data.sessions;
27
+ const total = data.stats.total_sessions || 1;
28
+ if (sessions.length < 5) {
29
+ return [{ message: "Keep going! Log a few more sessions and your AI trainer will have personalized tips for you.", category: "getting-started" }];
30
+ }
31
+ // Recent sessions (last 2 weeks)
32
+ const twoWeeksAgo = new Date();
33
+ twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14);
34
+ const recent = sessions.filter((s) => new Date(s.timestamp) >= twoWeeksAgo);
35
+ const recentTotal = recent.length || 1;
36
+ const recentDist = {};
37
+ for (const s of recent) {
38
+ recentDist[s.activity_type] = (recentDist[s.activity_type] || 0) + 1;
39
+ }
40
+ // One type > 70%
41
+ for (const [type, count] of Object.entries(recentDist)) {
42
+ if (count / recentTotal > 0.7 && recent.length >= 5) {
43
+ const adjacent = getAdjacentType(type);
44
+ suggestions.push({
45
+ message: `You're deep in ${capitalize(type)}. Try ${capitalize(adjacent)} to expand your range.`,
46
+ category: "activity-balance",
47
+ });
48
+ break;
49
+ }
50
+ }
51
+ // Never-used types
52
+ for (const type of ALL_ACTIVITY_TYPES) {
53
+ if (!data.distribution[type]) {
54
+ suggestions.push({
55
+ message: `You haven't tried ${capitalize(type)} yet. Here's an idea: ${getTypeExample(type)}`,
56
+ category: "activity-balance",
57
+ });
58
+ break;
59
+ }
60
+ }
61
+ // No highlights
62
+ if (data.stats.total_sessions >= 10 && data.stats.total_highlights === 0) {
63
+ suggestions.push({
64
+ message: `You've got ${data.stats.total_sessions} sessions but no highlights. Promote your best work with /my-player-log-highlight.`,
65
+ category: "progression",
66
+ });
67
+ }
68
+ // No deploys
69
+ const codeSessions = sessions.filter((s) => s.activity_type === "code");
70
+ const hasDeploySignals = sessions.some((s) => s.summary?.toLowerCase().includes("deploy") || s.summary?.toLowerCase().includes("ship"));
71
+ if (codeSessions.length >= 3 && !hasDeploySignals) {
72
+ suggestions.push({
73
+ message: `You've built ${codeSessions.length} things but deployed none. Ship one.`,
74
+ category: "progression",
75
+ video: VIDEO_LINKS["deploy"],
76
+ });
77
+ }
78
+ // Duration trending down
79
+ if (recent.length >= 6) {
80
+ const firstHalf = recent.slice(0, Math.floor(recent.length / 2));
81
+ const secondHalf = recent.slice(Math.floor(recent.length / 2));
82
+ const avgFirst = firstHalf.reduce((s, e) => s + (e.duration_minutes || 0), 0) / firstHalf.length;
83
+ const avgSecond = secondHalf.reduce((s, e) => s + (e.duration_minutes || 0), 0) / secondHalf.length;
84
+ if (avgSecond < avgFirst * 0.8 && avgFirst > 0) {
85
+ suggestions.push({
86
+ message: `Your sessions are getting shorter (${Math.round(avgFirst)} min to ${Math.round(avgSecond)} min). You're getting more efficient.`,
87
+ category: "progression",
88
+ });
89
+ }
90
+ }
91
+ // MCP/workspace recommendations
92
+ const mcpServers = new Set(Object.keys(data.workspace.mcp_servers));
93
+ const tools = data.workspace.tools;
94
+ if (!mcpServers.has("supabase-prod") && !mcpServers.has("supabase-dev") && !mcpServers.has("supabase") && codeSessions.length >= 5) {
95
+ suggestions.push({
96
+ message: "You do a lot of coding but don't use Supabase MCP. It lets you query and manage your database directly from Claude Code.",
97
+ category: "workspace",
98
+ });
99
+ }
100
+ if ((mcpServers.has("claude_ai_Notion") || mcpServers.has("notion")) && !mcpServers.has("linear")) {
101
+ suggestions.push({
102
+ message: "You use Notion heavily. Try the Linear MCP for faster task tracking directly in Claude Code.",
103
+ category: "workspace",
104
+ });
105
+ }
106
+ const readCount = tools["Read"] || 0;
107
+ const grepCount = tools["Grep"] || 0;
108
+ if (readCount > 100 && grepCount < readCount * 0.1) {
109
+ suggestions.push({
110
+ message: `You've used Read ${readCount} times but Grep only ${grepCount} times. Try Grep to search code instead of reading files one by one.`,
111
+ category: "tool-tip",
112
+ });
113
+ }
114
+ return suggestions.slice(0, 3);
115
+ }
116
+ function generateLocalSuggestions() {
117
+ const sessions = readSessions();
118
+ const highlights = readHighlights();
119
+ const profile = readProfile();
120
+ const suggestions = [];
121
+ if (sessions.length < 5) {
122
+ return [{ message: "Keep going! Log a few more sessions and your AI trainer will have personalized tips for you.", category: "getting-started" }];
123
+ }
124
+ const twoWeeksAgo = new Date();
125
+ twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14);
126
+ const recent = sessions.filter((s) => s.timestamp >= twoWeeksAgo.toISOString());
127
+ const recentTotal = recent.length || 1;
128
+ const recentDist = {};
129
+ for (const s of recent)
130
+ recentDist[s.activity_type] = (recentDist[s.activity_type] || 0) + 1;
131
+ for (const [type, count] of Object.entries(recentDist)) {
132
+ if (count / recentTotal > 0.7 && recent.length >= 5) {
133
+ suggestions.push({
134
+ message: `You're deep in ${capitalize(type)}. Try ${capitalize(getAdjacentType(type))} to expand your range.`,
135
+ category: "activity-balance",
136
+ });
137
+ break;
138
+ }
139
+ }
140
+ if (sessions.length >= 10 && highlights.length === 0) {
141
+ suggestions.push({
142
+ message: `You've got ${sessions.length} sessions but no highlights. Promote your best work with /my-player-log-highlight.`,
143
+ category: "progression",
144
+ });
145
+ }
146
+ const codeSessions = sessions.filter((s) => s.activity_type === "code");
147
+ const hasDeploySignals = sessions.some((s) => s.summary?.toLowerCase().includes("deploy") || s.summary?.toLowerCase().includes("ship"));
148
+ if (codeSessions.length >= 3 && !hasDeploySignals) {
149
+ suggestions.push({ message: `You've built ${codeSessions.length} things but deployed none. Ship one.`, category: "progression", video: VIDEO_LINKS["deploy"] });
150
+ }
151
+ return suggestions.slice(0, 3);
152
+ }
153
+ function capitalize(s) {
154
+ return s.charAt(0).toUpperCase() + s.slice(1);
155
+ }
156
+ function getAdjacentType(type) {
157
+ const adjacency = {
158
+ code: "automation", content: "research", research: "code", automation: "data",
159
+ design: "code", ops: "automation", data: "research", debug: "code",
160
+ };
161
+ return adjacency[type] || "code";
162
+ }
163
+ function getTypeExample(type) {
164
+ const examples = {
165
+ code: "Build a quick prototype of an idea you've been thinking about.",
166
+ content: "Write up what you learned in your last coding session.",
167
+ research: "Deep dive into a new technology that interests you.",
168
+ automation: "Automate something you do manually every week.",
169
+ design: "Plan out the architecture of your next project before building.",
170
+ ops: "Set up CI/CD for one of your projects.",
171
+ data: "Analyze your own usage patterns or project metrics.",
172
+ debug: "Fix that bug you've been putting off.",
173
+ };
174
+ return examples[type] || "Try something new.";
175
+ }
176
+ //# sourceMappingURL=get-suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-suggestions.js","sourceRoot":"","sources":["../../../../src/mcp/tools/get-suggestions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACjG,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAS7C,MAAM,WAAW,GAA2B;IAC1C,MAAM,EAAE,8BAA8B;IACtC,YAAY,EAAE,6BAA6B;IAC3C,UAAU,EAAE,qCAAqC;IACjD,OAAO,EAAE,+BAA+B;CACzC,CAAC;AAEF,MAAM,kBAAkB,GAAmB;IACzC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO;CAC9E,CAAC;AAqBF,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IAExB,gBAAgB;IAChB,IAAI,IAAI,EAAE,QAAQ,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAoB,oCAAoC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrG,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,OAAO,wBAAwB,EAAE,CAAC;AACpC,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAuB;IAClD,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,CAAC;IAE7C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,8FAA8F,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACpJ,CAAC;IAED,iCAAiC;IACjC,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;IAC/B,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,CAAC;IAC5E,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAEvC,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACvE,CAAC;IAED,iBAAiB;IACjB,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,IAAI,KAAK,GAAG,WAAW,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAoB,CAAC,CAAC;YACvD,WAAW,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,kBAAkB,UAAU,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,QAAQ,CAAC,wBAAwB;gBAChG,QAAQ,EAAE,kBAAkB;aAC7B,CAAC,CAAC;YACH,MAAM;QACR,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,qBAAqB,UAAU,CAAC,IAAI,CAAC,yBAAyB,cAAc,CAAC,IAAI,CAAC,EAAE;gBAC7F,QAAQ,EAAE,kBAAkB;aAC7B,CAAC,CAAC;YACH,MAAM;QACR,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,KAAK,CAAC,EAAE,CAAC;QACzE,WAAW,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,cAAc,IAAI,CAAC,KAAK,CAAC,cAAc,oFAAoF;YACpI,QAAQ,EAAE,aAAa;SACxB,CAAC,CAAC;IACL,CAAC;IAED,aAAa;IACb,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC;IACxE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACxI,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAClD,WAAW,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,gBAAgB,YAAY,CAAC,MAAM,sCAAsC;YAClF,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,yBAAyB;IACzB,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;QACjG,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;QACpG,IAAI,SAAS,GAAG,QAAQ,GAAG,GAAG,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YAC/C,WAAW,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,sCAAsC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,uCAAuC;gBAC1I,QAAQ,EAAE,aAAa;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACnI,WAAW,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,0HAA0H;YACnI,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClG,WAAW,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,8FAA8F;YACvG,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,SAAS,GAAG,GAAG,IAAI,SAAS,GAAG,SAAS,GAAG,GAAG,EAAE,CAAC;QACnD,WAAW,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,oBAAoB,SAAS,wBAAwB,SAAS,sEAAsE;YAC7I,QAAQ,EAAE,UAAU;SACrB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,wBAAwB;IAC/B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAiB,EAAE,CAAC;IAErC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,8FAA8F,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACpJ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;IAC/B,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;IAChF,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACvC,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAE7F,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,IAAI,KAAK,GAAG,WAAW,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACpD,WAAW,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,kBAAkB,UAAU,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,eAAe,CAAC,IAAoB,CAAC,CAAC,wBAAwB;gBAC7H,QAAQ,EAAE,kBAAkB;aAC7B,CAAC,CAAC;YACH,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,WAAW,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,cAAc,QAAQ,CAAC,MAAM,oFAAoF;YAC1H,QAAQ,EAAE,aAAa;SACxB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC;IACxE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACxI,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAClD,WAAW,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,gBAAgB,YAAY,CAAC,MAAM,sCAAsC,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAClK,CAAC;IAED,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,eAAe,CAAC,IAAkB;IACzC,MAAM,SAAS,GAAuC;QACpD,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;QAC7E,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM;KACnE,CAAC;IACF,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;AACnC,CAAC;AAED,SAAS,cAAc,CAAC,IAAkB;IACxC,MAAM,QAAQ,GAAiC;QAC7C,IAAI,EAAE,gEAAgE;QACtE,OAAO,EAAE,wDAAwD;QACjE,QAAQ,EAAE,qDAAqD;QAC/D,UAAU,EAAE,gDAAgD;QAC5D,MAAM,EAAE,iEAAiE;QACzE,GAAG,EAAE,wCAAwC;QAC7C,IAAI,EAAE,qDAAqD;QAC3D,KAAK,EAAE,uCAAuC;KAC/C,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC;AAChD,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ export declare const getTrainingSchema: {
3
+ topic: z.ZodString;
4
+ };
5
+ export declare const listTrainingSchema: {
6
+ expert: z.ZodOptional<z.ZodString>;
7
+ category: z.ZodOptional<z.ZodString>;
8
+ };
9
+ interface TrainingResponse {
10
+ topic: string;
11
+ title: string;
12
+ expert?: string;
13
+ category?: string;
14
+ version: string;
15
+ tier_required: string;
16
+ user_tier: string;
17
+ content: string;
18
+ content_length: number;
19
+ full_content_length?: number;
20
+ upgrade_url?: string;
21
+ last_updated: string;
22
+ }
23
+ interface TrainingListResponse {
24
+ user_tier: string;
25
+ topics: {
26
+ id: string;
27
+ title: string;
28
+ expert: string;
29
+ category: string;
30
+ description: string;
31
+ tier: string;
32
+ version: string;
33
+ locked: boolean;
34
+ }[];
35
+ upgrade_url: string;
36
+ }
37
+ export declare function getTraining({ topic }: {
38
+ topic: string;
39
+ }): Promise<TrainingResponse | {
40
+ error: string;
41
+ }>;
42
+ export declare function listTraining({ expert, category }?: {
43
+ expert?: string;
44
+ category?: string;
45
+ }): Promise<TrainingListResponse | {
46
+ error: string;
47
+ }>;
48
+ export {};
@@ -0,0 +1,102 @@
1
+ import { z } from "zod";
2
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
3
+ import { join } from "path";
4
+ import { homedir } from "os";
5
+ import { apiFetch } from "../../api-client.js";
6
+ const CACHE_DIR = join(homedir(), ".myplayer", "cache", "training");
7
+ const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
8
+ export const getTrainingSchema = {
9
+ topic: z.string().describe("The training data topic slug to fetch (e.g., 'sales-value-equation', 'content-hooks')"),
10
+ };
11
+ export const listTrainingSchema = {
12
+ expert: z.string().optional().describe("Filter by expert (e.g., 'gary-halbert', 'austin-marchese'). Omit to list all."),
13
+ category: z.string().optional().describe("Filter by category (e.g., 'copywriting', 'marketing', 'sales', 'ai-automation'). Omit to list all."),
14
+ };
15
+ export async function getTraining({ topic }) {
16
+ // Check cache first
17
+ const cached = readCache(topic);
18
+ if (cached) {
19
+ return {
20
+ topic: cached.topic,
21
+ title: cached.title,
22
+ version: cached.version,
23
+ tier_required: cached.tier,
24
+ user_tier: cached.tier,
25
+ content: cached.content,
26
+ content_length: cached.content.length,
27
+ last_updated: cached.fetched_at,
28
+ };
29
+ }
30
+ // Fetch from API
31
+ const res = await apiFetch(`/api/training/${encodeURIComponent(topic)}`);
32
+ if (!res || !res.ok) {
33
+ // Try cache even if expired
34
+ const staleCache = readCache(topic, true);
35
+ if (staleCache) {
36
+ return {
37
+ topic: staleCache.topic,
38
+ title: staleCache.title,
39
+ version: staleCache.version,
40
+ tier_required: staleCache.tier,
41
+ user_tier: staleCache.tier,
42
+ content: staleCache.content + "\n\n[Cached version - could not reach API]",
43
+ content_length: staleCache.content.length,
44
+ last_updated: staleCache.fetched_at,
45
+ };
46
+ }
47
+ return { error: `Could not fetch training data for '${topic}'. Check your connection.` };
48
+ }
49
+ const data = (await res.json());
50
+ // Cache the result
51
+ writeCache(topic, {
52
+ topic: data.topic,
53
+ version: data.version,
54
+ fetched_at: new Date().toISOString(),
55
+ content: data.content,
56
+ tier: data.tier_required,
57
+ title: data.title,
58
+ });
59
+ return data;
60
+ }
61
+ export async function listTraining({ expert, category } = {}) {
62
+ const params = new URLSearchParams();
63
+ if (expert)
64
+ params.set("expert", expert);
65
+ if (category)
66
+ params.set("category", category);
67
+ const qs = params.toString();
68
+ const path = qs ? `/api/training?${qs}` : "/api/training";
69
+ const res = await apiFetch(path);
70
+ if (!res || !res.ok) {
71
+ return { error: "Could not fetch training topics. Check your connection." };
72
+ }
73
+ return (await res.json());
74
+ }
75
+ // --- Cache ---
76
+ function readCache(topic, ignoreExpiry = false) {
77
+ try {
78
+ const cachePath = join(CACHE_DIR, `${topic}.json`);
79
+ if (!existsSync(cachePath))
80
+ return null;
81
+ const cached = JSON.parse(readFileSync(cachePath, "utf-8"));
82
+ if (!ignoreExpiry) {
83
+ const age = Date.now() - new Date(cached.fetched_at).getTime();
84
+ if (age > CACHE_TTL_MS)
85
+ return null;
86
+ }
87
+ return cached;
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ }
93
+ function writeCache(topic, data) {
94
+ try {
95
+ mkdirSync(CACHE_DIR, { recursive: true });
96
+ writeFileSync(join(CACHE_DIR, `${topic}.json`), JSON.stringify(data, null, 2));
97
+ }
98
+ catch {
99
+ // Cache write failures are non-fatal
100
+ }
101
+ }
102
+ //# sourceMappingURL=get-training.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-training.js","sourceRoot":"","sources":["../../../../src/mcp/tools/get-training.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ import type { ActivityType } from "../../classifiers/activity-classifier.js";
3
+ export declare const logHighlightSchema: {
4
+ title: z.ZodString;
5
+ description: z.ZodString;
6
+ activity_type: z.ZodEnum<{
7
+ content: "content";
8
+ code: "code";
9
+ research: "research";
10
+ automation: "automation";
11
+ design: "design";
12
+ ops: "ops";
13
+ data: "data";
14
+ debug: "debug";
15
+ }>;
16
+ tech_stack: z.ZodArray<z.ZodString>;
17
+ session_id: z.ZodOptional<z.ZodString>;
18
+ };
19
+ export declare function logHighlight({ title, description, activity_type, tech_stack, session_id, }: {
20
+ title: string;
21
+ description: string;
22
+ activity_type: ActivityType;
23
+ tech_stack: string[];
24
+ session_id?: string;
25
+ }): Promise<{
26
+ id: string;
27
+ title: string;
28
+ description: string;
29
+ activity_type: ActivityType;
30
+ tech_stack: string[];
31
+ created_at: string;
32
+ }>;
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ import { appendHighlight } from "../../store/local-store.js";
3
+ import { apiPost } from "../../api-client.js";
4
+ export const logHighlightSchema = {
5
+ title: z.string().describe("Title for the highlight build"),
6
+ description: z.string().describe("Description of what was built"),
7
+ activity_type: z
8
+ .enum(["code", "content", "research", "automation", "design", "ops", "data", "debug"])
9
+ .describe("Activity type"),
10
+ tech_stack: z.array(z.string()).describe("Technologies used"),
11
+ session_id: z.string().optional().describe("Associated session ID"),
12
+ };
13
+ export async function logHighlight({ title, description, activity_type, tech_stack, session_id, }) {
14
+ // Save locally
15
+ const highlight = appendHighlight({
16
+ session_id: session_id || "",
17
+ title,
18
+ description,
19
+ activity_type,
20
+ tech_stack,
21
+ });
22
+ // Sync to server
23
+ await apiPost("/api/myplayer/highlights", {
24
+ title,
25
+ description,
26
+ activity_type,
27
+ tech_stack,
28
+ session_id: session_id || null,
29
+ });
30
+ return {
31
+ id: highlight.id,
32
+ title: highlight.title,
33
+ description: highlight.description,
34
+ activity_type: highlight.activity_type,
35
+ tech_stack: highlight.tech_stack,
36
+ created_at: highlight.created_at,
37
+ };
38
+ }
39
+ //# sourceMappingURL=log-highlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-highlight.js","sourceRoot":"","sources":["../../../../src/mcp/tools/log-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAsB,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAG9C,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC3D,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IACjE,aAAa,EAAE,CAAC;SACb,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;SACrF,QAAQ,CAAC,eAAe,CAAC;IAC5B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;IAC7D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;CACpE,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EACjC,KAAK,EACL,WAAW,EACX,aAAa,EACb,UAAU,EACV,UAAU,GAOX;IACC,eAAe;IACf,MAAM,SAAS,GAAG,eAAe,CAAC;QAChC,UAAU,EAAE,UAAU,IAAI,EAAE;QAC5B,KAAK;QACL,WAAW;QACX,aAAa;QACb,UAAU;KACX,CAAC,CAAC;IAEH,iBAAiB;IACjB,MAAM,OAAO,CAAC,0BAA0B,EAAE;QACxC,KAAK;QACL,WAAW;QACX,aAAa;QACb,UAAU;QACV,UAAU,EAAE,UAAU,IAAI,IAAI;KAC/B,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,SAAS,CAAC,EAAE;QAChB,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,aAAa,EAAE,SAAS,CAAC,aAAa;QACtC,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,UAAU,EAAE,SAAS,CAAC,UAAU;KACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,78 @@
1
+ import type { QuestPath } from "../../store/quest-store.js";
2
+ import { z } from "zod";
3
+ export declare const getQuestSchema: {};
4
+ export declare const completeQuestSchema: {
5
+ quest_id: z.ZodString;
6
+ };
7
+ export declare function getQuestStatus(): Promise<{
8
+ environment: string;
9
+ active_quest: {
10
+ id: string;
11
+ title: string;
12
+ description: string;
13
+ prompt: string;
14
+ path: QuestPath;
15
+ } | null;
16
+ progress: {
17
+ total: string;
18
+ core: {
19
+ completed: number;
20
+ total: number;
21
+ };
22
+ builder: {
23
+ completed: number;
24
+ total: number;
25
+ };
26
+ storyteller: {
27
+ completed: number;
28
+ total: number;
29
+ };
30
+ systems_thinker: {
31
+ completed: number;
32
+ total: number;
33
+ };
34
+ all_done: boolean;
35
+ core_done: boolean;
36
+ paths_unlocked: boolean;
37
+ };
38
+ quests: {
39
+ id: string;
40
+ title: string;
41
+ description: string;
42
+ prompt: string;
43
+ path: QuestPath;
44
+ order: number;
45
+ status: import("../../store/quest-store.js").QuestStatus;
46
+ completed_at: string | null;
47
+ }[];
48
+ coming_soon: {
49
+ status: "coming_soon";
50
+ id: string;
51
+ title: string;
52
+ path: QuestPath;
53
+ description: string;
54
+ }[];
55
+ }>;
56
+ export declare function markQuestComplete({ quest_id }: {
57
+ quest_id: string;
58
+ }): Promise<{
59
+ error: string;
60
+ completed?: undefined;
61
+ completed_path?: undefined;
62
+ paths_unlocked?: undefined;
63
+ next_quest?: undefined;
64
+ message?: undefined;
65
+ } | {
66
+ completed: string;
67
+ completed_path: QuestPath;
68
+ paths_unlocked: boolean;
69
+ next_quest: {
70
+ id: string;
71
+ title: string;
72
+ description: string;
73
+ path: QuestPath;
74
+ } | null;
75
+ message: string;
76
+ error?: undefined;
77
+ }>;
78
+ export declare function getFirstRunTip(skillName: string): string | null;
@@ -0,0 +1,72 @@
1
+ import { getActiveQuest, getQuestProgress, completeQuest, readQuests, QUEST_DEFINITIONS, COMING_SOON_QUESTS, isFirstSkillRun, markSkillRun, getEnvironment, } from "../../store/quest-store.js";
2
+ import { z } from "zod";
3
+ export const getQuestSchema = {};
4
+ export const completeQuestSchema = {
5
+ quest_id: z.string().describe("The quest ID to mark as completed"),
6
+ };
7
+ export async function getQuestStatus() {
8
+ const active = getActiveQuest();
9
+ const progress = getQuestProgress();
10
+ const state = readQuests();
11
+ const env = getEnvironment();
12
+ const quests = QUEST_DEFINITIONS.map((def) => ({
13
+ id: def.id,
14
+ title: def.title,
15
+ description: def.description,
16
+ prompt: def.prompt,
17
+ path: def.path,
18
+ order: def.order,
19
+ status: state.quests[def.id]?.status || "locked",
20
+ completed_at: state.quests[def.id]?.completed_at || null,
21
+ }));
22
+ const comingSoon = COMING_SOON_QUESTS.map((q) => ({
23
+ ...q,
24
+ status: "coming_soon",
25
+ }));
26
+ return {
27
+ environment: env,
28
+ active_quest: active
29
+ ? { id: active.id, title: active.title, description: active.description, prompt: active.prompt, path: active.path }
30
+ : null,
31
+ progress: {
32
+ total: `${progress.completed}/${progress.total}`,
33
+ core: progress.core,
34
+ builder: progress.builder,
35
+ storyteller: progress.storyteller,
36
+ systems_thinker: progress.systemsThinker,
37
+ all_done: progress.allDone,
38
+ core_done: progress.core.completed === progress.core.total,
39
+ paths_unlocked: progress.core.completed === progress.core.total,
40
+ },
41
+ quests,
42
+ coming_soon: comingSoon,
43
+ };
44
+ }
45
+ export async function markQuestComplete({ quest_id }) {
46
+ const result = completeQuest(quest_id);
47
+ if (!result) {
48
+ return { error: "Quest not found or already completed." };
49
+ }
50
+ const active = getActiveQuest();
51
+ const progress = getQuestProgress();
52
+ // Check if core just finished (path quests unlocked)
53
+ const pathsJustUnlocked = result.path === "core" && progress.core.completed === progress.core.total;
54
+ return {
55
+ completed: result.title,
56
+ completed_path: result.path,
57
+ paths_unlocked: pathsJustUnlocked,
58
+ next_quest: active ? { id: active.id, title: active.title, description: active.description, path: active.path } : null,
59
+ message: pathsJustUnlocked
60
+ ? `Core quests complete! You've unlocked 3 paths: Builder, Storyteller, and Systems Thinker. Type /quest to pick your path.`
61
+ : active
62
+ ? `Quest complete! Next up: ${active.title}`
63
+ : "All quests completed! You're a BuildPartner expert.",
64
+ };
65
+ }
66
+ export function getFirstRunTip(skillName) {
67
+ if (!isFirstSkillRun(skillName))
68
+ return null;
69
+ markSkillRun(skillName);
70
+ return `---\nTip: This is a "skill" -- a markdown file that tells Claude what to do. You can see it at ~/.claude/skills/${skillName}/SKILL.md or create your own by asking Claude: "Create a skill called [name] that does [thing]." Skills are how you teach Claude your workflows.`;
71
+ }
72
+ //# sourceMappingURL=quest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quest.js","sourceRoot":"","sources":["../../../../src/mcp/tools/quest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export declare const webSearchSchema: {
3
+ query: z.ZodString;
4
+ num_results: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
5
+ };
6
+ interface SearchResult {
7
+ title: string;
8
+ url: string;
9
+ snippet: string;
10
+ }
11
+ export declare function webSearch({ query, num_results }: {
12
+ query: string;
13
+ num_results: number;
14
+ }): Promise<SearchResult[]>;
15
+ export {};
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ import { apiPost } from "../../api-client.js";
3
+ export const webSearchSchema = {
4
+ query: z.string().describe("The search query"),
5
+ num_results: z.number().optional().default(5).describe("Number of results to return (default 5)"),
6
+ };
7
+ export async function webSearch({ query, num_results }) {
8
+ const response = await apiPost("/api/myplayer/search", {
9
+ query,
10
+ num_results,
11
+ });
12
+ if (!response || !response.results) {
13
+ return [{ title: "Search unavailable", url: "", snippet: "Could not reach the search API. Check your internet connection and try again." }];
14
+ }
15
+ return response.results;
16
+ }
17
+ //# sourceMappingURL=web-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../../../src/mcp/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC;CAClG,CAAC;AAYF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAA0C;IAC5F,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAiB,sBAAsB,EAAE;QACrE,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnC,OAAO,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,+EAA+E,EAAE,CAAC,CAAC;IAC9I,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,28 @@
1
+ export interface HistoryEntry {
2
+ display: string;
3
+ timestamp: number;
4
+ project: string;
5
+ sessionId: string;
6
+ pastedContents?: Record<string, unknown>;
7
+ }
8
+ export interface HistorySummary {
9
+ totalEntries: number;
10
+ uniqueSessions: number;
11
+ uniqueProjects: string[];
12
+ firstTimestamp: number | null;
13
+ lastTimestamp: number | null;
14
+ sessionsByProject: Record<string, Set<string>>;
15
+ }
16
+ /**
17
+ * Parse ~/.claude/history.jsonl — the prompt history log.
18
+ * Each line is a JSON object representing a user prompt submission.
19
+ */
20
+ export declare function readHistory(): HistoryEntry[];
21
+ /**
22
+ * Get a summary of history data: session counts, project list, date range.
23
+ */
24
+ export declare function getHistorySummary(): HistorySummary;
25
+ /**
26
+ * Get all unique session IDs grouped by project path.
27
+ */
28
+ export declare function getSessionsByProject(): Record<string, string[]>;