buildpartner 0.3.4 → 0.3.6

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 (57) hide show
  1. package/dist/bin/cli.js +6 -0
  2. package/dist/bin/cli.js.map +1 -1
  3. package/dist/src/api-client.d.ts +13 -9
  4. package/dist/src/api-client.js +14 -31
  5. package/dist/src/api-client.js.map +1 -1
  6. package/dist/src/commands/log-session.d.ts +3 -6
  7. package/dist/src/commands/log-session.js +10 -149
  8. package/dist/src/commands/log-session.js.map +1 -1
  9. package/dist/src/commands/reset.d.ts +1 -0
  10. package/dist/src/commands/reset.js +130 -0
  11. package/dist/src/commands/reset.js.map +1 -0
  12. package/dist/src/commands/setup.js +95 -404
  13. package/dist/src/commands/setup.js.map +1 -1
  14. package/dist/src/commands/sync.d.ts +6 -0
  15. package/dist/src/commands/sync.js +36 -0
  16. package/dist/src/commands/sync.js.map +1 -0
  17. package/dist/src/mcp/catch-up.d.ts +6 -0
  18. package/dist/src/mcp/catch-up.js +28 -0
  19. package/dist/src/mcp/catch-up.js.map +1 -0
  20. package/dist/src/mcp/server.d.ts +13 -0
  21. package/dist/src/mcp/server.js +71 -81
  22. package/dist/src/mcp/server.js.map +1 -1
  23. package/dist/src/mcp/subscription-gate.d.ts +2 -2
  24. package/dist/src/mcp/subscription-gate.js +4 -9
  25. package/dist/src/mcp/subscription-gate.js.map +1 -1
  26. package/dist/src/mcp/tools/get-profile.js +7 -70
  27. package/dist/src/mcp/tools/get-profile.js.map +1 -1
  28. package/dist/src/mcp/tools/get-stats.d.ts +8 -34
  29. package/dist/src/mcp/tools/get-stats.js +7 -97
  30. package/dist/src/mcp/tools/get-stats.js.map +1 -1
  31. package/dist/src/mcp/tools/get-suggestions.js +10 -121
  32. package/dist/src/mcp/tools/get-suggestions.js.map +1 -1
  33. package/dist/src/mcp/tools/log-highlight.d.ts +2 -10
  34. package/dist/src/mcp/tools/log-highlight.js +5 -19
  35. package/dist/src/mcp/tools/log-highlight.js.map +1 -1
  36. package/dist/src/mcp/tools/quest.d.ts +3 -77
  37. package/dist/src/mcp/tools/quest.js +6 -70
  38. package/dist/src/mcp/tools/quest.js.map +1 -1
  39. package/dist/src/readers/extract-signals.d.ts +23 -0
  40. package/dist/src/readers/extract-signals.js +50 -0
  41. package/dist/src/readers/extract-signals.js.map +1 -0
  42. package/dist/src/readers/session-reader.d.ts +0 -14
  43. package/dist/src/readers/session-reader.js +3 -122
  44. package/dist/src/readers/session-reader.js.map +1 -1
  45. package/dist/src/readers/session-sync.d.ts +24 -0
  46. package/dist/src/readers/session-sync.js +114 -0
  47. package/dist/src/readers/session-sync.js.map +1 -0
  48. package/dist/src/store/local-store.d.ts +12 -60
  49. package/dist/src/store/local-store.js +16 -113
  50. package/dist/src/store/local-store.js.map +1 -1
  51. package/dist/src/store/quest-store.d.ts +5 -68
  52. package/dist/src/store/quest-store.js +9 -277
  53. package/dist/src/store/quest-store.js.map +1 -1
  54. package/dist/src/store/status-store.d.ts +5 -68
  55. package/dist/src/store/status-store.js +8 -281
  56. package/dist/src/store/status-store.js.map +1 -1
  57. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -17,6 +17,11 @@ async function main() {
17
17
  await logSession();
18
18
  break;
19
19
  }
20
+ case "sync": {
21
+ const { sync } = await import("../src/commands/sync.js");
22
+ await sync();
23
+ break;
24
+ }
20
25
  case "stats": {
21
26
  const { setup } = await import("../src/commands/setup.js");
22
27
  // Quick stats mode
@@ -31,6 +36,7 @@ async function main() {
31
36
  buildpartner setup Interactive setup + backfill
32
37
  buildpartner setup --token X Pre-authenticated setup
33
38
  buildpartner serve Start MCP server
39
+ buildpartner sync Re-sync all sessions to server
34
40
  buildpartner log-session Log current session (hook)
35
41
  buildpartner stats Quick stats
36
42
  `);
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";AAEA,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YAC3D,MAAM,KAAK,EAAE,CAAC;YACd,MAAM;QACR,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YAC3D,MAAM,KAAK,EAAE,CAAC;YACd,MAAM;QACR,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;YACtE,MAAM,UAAU,EAAE,CAAC;YACnB,MAAM;QACR,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YAC3D,mBAAmB;YACnB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,MAAM;QACR,CAAC;QACD;YACE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;CASjB,CAAC,CAAC;IACD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";AAEA,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YAC3D,MAAM,KAAK,EAAE,CAAC;YACd,MAAM;QACR,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YAC3D,MAAM,KAAK,EAAE,CAAC;YACd,MAAM;QACR,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;YACtE,MAAM,UAAU,EAAE,CAAC;YACnB,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YACzD,MAAM,IAAI,EAAE,CAAC;YACb,MAAM;QACR,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YAC3D,mBAAmB;YACnB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,MAAM;QACR,CAAC;QACD;YACE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUjB,CAAC,CAAC;IACD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1,18 +1,22 @@
1
- export declare const API_BASE = "https://buildpartner.ai";
2
1
  /**
3
- * Fetch from the BuildPartner API with auth.
4
- * Returns null if offline or auth missing (caller should fall back to local).
2
+ * API client for the BuildPartner server.
3
+ * All API calls from the CLI go through this module.
4
+ * Handles auth headers, timeouts, and error logging automatically.
5
+ */
6
+ export declare const API_BASE = "https://www.buildpartner.ai";
7
+ /**
8
+ * Make an authenticated request to the BuildPartner API.
9
+ * Returns the raw Response, or null if offline/unauthenticated.
10
+ * Callers should check res.status for specific error handling (e.g. 403 = trial expired).
5
11
  */
6
12
  export declare function apiFetch(path: string, options?: RequestInit): Promise<Response | null>;
7
13
  /**
8
- * GET from API, parse JSON. Returns null on failure.
14
+ * GET from the API and parse JSON. Returns null on any failure.
15
+ * Use apiFetch() directly when you need to check specific status codes.
9
16
  */
10
17
  export declare function apiGet<T>(path: string): Promise<T | null>;
11
18
  /**
12
- * POST to API, parse JSON. Returns null on failure.
19
+ * POST to the API and parse JSON. Returns null on any failure.
20
+ * Use apiFetch() directly when you need to check specific status codes.
13
21
  */
14
22
  export declare function apiPost<T>(path: string, body: unknown): Promise<T | null>;
15
- /**
16
- * Track a usage event. Fire and forget, never blocks, never fails.
17
- */
18
- export declare function track(event: string, metadata?: Record<string, unknown>): void;
@@ -1,16 +1,20 @@
1
+ /**
2
+ * API client for the BuildPartner server.
3
+ * All API calls from the CLI go through this module.
4
+ * Handles auth headers, timeouts, and error logging automatically.
5
+ */
1
6
  import { readAuth, logError } from "./store/local-store.js";
2
- export const API_BASE = "https://buildpartner.ai";
7
+ export const API_BASE = "https://www.buildpartner.ai";
3
8
  /**
4
- * Fetch from the BuildPartner API with auth.
5
- * Returns null if offline or auth missing (caller should fall back to local).
9
+ * Make an authenticated request to the BuildPartner API.
10
+ * Returns the raw Response, or null if offline/unauthenticated.
11
+ * Callers should check res.status for specific error handling (e.g. 403 = trial expired).
6
12
  */
7
13
  export async function apiFetch(path, options) {
8
14
  const auth = readAuth();
9
15
  if (!auth?.token)
10
16
  return null;
11
17
  try {
12
- const controller = new AbortController();
13
- const timeout = setTimeout(() => controller.abort(), 5000);
14
18
  const res = await fetch(`${API_BASE}${path}`, {
15
19
  ...options,
16
20
  headers: {
@@ -18,9 +22,8 @@ export async function apiFetch(path, options) {
18
22
  "Content-Type": "application/json",
19
23
  ...options?.headers,
20
24
  },
21
- signal: controller.signal,
25
+ signal: AbortSignal.timeout(5000),
22
26
  });
23
- clearTimeout(timeout);
24
27
  return res;
25
28
  }
26
29
  catch (err) {
@@ -29,7 +32,8 @@ export async function apiFetch(path, options) {
29
32
  }
30
33
  }
31
34
  /**
32
- * GET from API, parse JSON. Returns null on failure.
35
+ * GET from the API and parse JSON. Returns null on any failure.
36
+ * Use apiFetch() directly when you need to check specific status codes.
33
37
  */
34
38
  export async function apiGet(path) {
35
39
  const res = await apiFetch(path);
@@ -38,7 +42,8 @@ export async function apiGet(path) {
38
42
  return res.json();
39
43
  }
40
44
  /**
41
- * POST to API, parse JSON. Returns null on failure.
45
+ * POST to the API and parse JSON. Returns null on any failure.
46
+ * Use apiFetch() directly when you need to check specific status codes.
42
47
  */
43
48
  export async function apiPost(path, body) {
44
49
  const res = await apiFetch(path, {
@@ -49,26 +54,4 @@ export async function apiPost(path, body) {
49
54
  return null;
50
55
  return res.json();
51
56
  }
52
- /**
53
- * Track a usage event. Fire and forget, never blocks, never fails.
54
- */
55
- export function track(event, metadata) {
56
- const auth = readAuth();
57
- const payload = {
58
- event,
59
- token: auth?.token || null,
60
- metadata: {
61
- ...metadata,
62
- username: auth?.username || "anonymous",
63
- timestamp: new Date().toISOString(),
64
- },
65
- };
66
- // Fire and forget
67
- fetch(`${API_BASE}/api/buildpartner/track`, {
68
- method: "POST",
69
- headers: { "Content-Type": "application/json" },
70
- body: JSON.stringify(payload),
71
- signal: AbortSignal.timeout(3000),
72
- }).catch(() => { });
73
- }
74
57
  //# sourceMappingURL=api-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,CAAC,MAAM,QAAQ,GAAG,yBAAyB,CAAC;AAElD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAqB;IAChE,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;QAE3D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,EAAE;YAC5C,GAAG,OAAO;YACV,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACvC,cAAc,EAAE,kBAAkB;gBAClC,GAAG,OAAO,EAAE,OAAO;aACpB;YACD,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAI,IAAY;IAC1C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAI,IAAY,EAAE,IAAa;IAC1D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;QAC/B,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,KAAa,EAAE,QAAkC;IACrE,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG;QACd,KAAK;QACL,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,IAAI;QAC1B,QAAQ,EAAE;YACR,GAAG,QAAQ;YACX,QAAQ,EAAE,IAAI,EAAE,QAAQ,IAAI,WAAW;YACvC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC;KACF,CAAC;IAEF,kBAAkB;IAClB,KAAK,CAAC,GAAG,QAAQ,yBAAyB,EAAE;QAC1C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;KAClC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/api-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,CAAC,MAAM,QAAQ,GAAG,6BAA6B,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAqB;IAChE,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,EAAE;YAC5C,GAAG,OAAO;YACV,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACvC,cAAc,EAAE,kBAAkB;gBAClC,GAAG,OAAO,EAAE,OAAO;aACpB;YACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAI,IAAY;IAC1C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAI,IAAY,EAAE,IAAa;IAC1D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;QAC/B,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC"}
@@ -1,10 +1,7 @@
1
1
  /**
2
- * Hook handler: classify + log the most recent session.
3
- * Called by the Claude Code "stop" hook after every session.
2
+ * Hook handler: extract signals from the most recent session and POST to server.
3
+ * Called by Claude Code "stop" hook after every session.
4
4
  *
5
- * Requirements:
6
- * - Must complete in <1 second
7
- * - Must not produce any stdout (silent)
8
- * - Must not fail loudly; errors go to ~/.buildpartner/errors.log
5
+ * Requirements: <1 second, no stdout, no loud failures.
9
6
  */
10
7
  export declare function logSession(): Promise<void>;
@@ -1,162 +1,23 @@
1
- import { readdirSync, statSync } from "fs";
2
- import { join } from "path";
3
- import { homedir } from "os";
4
- import { parseSession, extractTooling } from "../readers/session-reader.js";
5
- import { classifySession } from "../classifiers/activity-classifier.js";
6
- import { appendSession, isSessionLogged, readProfile, readAuth, updateProfile, logError } from "../store/local-store.js";
7
- import { API_BASE, track } from "../api-client.js";
8
- import { incrementSessionCounter } from "../store/status-store.js";
1
+ import { readAuth, logError } from "../store/local-store.js";
2
+ import { scanMostRecentSession, syncToServer } from "../readers/session-sync.js";
9
3
  /**
10
- * Hook handler: classify + log the most recent session.
11
- * Called by the Claude Code "stop" hook after every session.
4
+ * Hook handler: extract signals from the most recent session and POST to server.
5
+ * Called by Claude Code "stop" hook after every session.
12
6
  *
13
- * Requirements:
14
- * - Must complete in <1 second
15
- * - Must not produce any stdout (silent)
16
- * - Must not fail loudly; errors go to ~/.buildpartner/errors.log
7
+ * Requirements: <1 second, no stdout, no loud failures.
17
8
  */
18
9
  export async function logSession() {
19
10
  try {
20
- const sessionFile = findMostRecentSession();
21
- if (!sessionFile)
22
- return;
23
- const parsed = parseSession(sessionFile);
24
- if (!parsed || parsed.userPromptCount === 0)
11
+ const auth = readAuth();
12
+ if (!auth?.token)
25
13
  return;
26
- // Skip if already logged
27
- if (parsed.startTime && isSessionLogged(parsed.startTime, parsed.projectPath)) {
14
+ const signals = scanMostRecentSession();
15
+ if (!signals)
28
16
  return;
29
- }
30
- const result = classifySession(parsed);
31
- const tooling = extractTooling(parsed);
32
- // Compute duration
33
- let durationMinutes = 0;
34
- if (parsed.startTime && parsed.endTime) {
35
- const ms = new Date(parsed.endTime).getTime() - new Date(parsed.startTime).getTime();
36
- durationMinutes = Math.round(ms / 60000);
37
- }
38
- // Estimate tokens
39
- const estimatedTokens = parsed.toolCalls.length * 1500 + parsed.userPromptCount * 2000;
40
- // Extract project name (just folder name, not full path)
41
- const projectName = parsed.projectPath.split("/").filter(Boolean).pop() || "";
42
- const sessionData = {
43
- timestamp: parsed.startTime || new Date().toISOString(),
44
- project: parsed.projectPath,
45
- activity_type: result.activityType,
46
- tokens: estimatedTokens,
47
- duration_minutes: durationMinutes,
48
- prompts: parsed.userPromptCount,
49
- files_touched: parsed.filesTouched.slice(0, 20),
50
- summary: parsed.summary || "",
51
- mcp_servers_used: tooling.mcpServersUsed,
52
- mcp_tool_counts: tooling.mcpToolCounts,
53
- skills_invoked: tooling.skillsInvoked,
54
- tool_counts: tooling.toolCounts,
55
- };
56
- // Write locally
57
- appendSession(sessionData);
58
- // Increment session counter for status API reminders
59
- incrementSessionCounter();
60
- // Track the hook firing
61
- track("hook.session_logged", {
62
- activity_type: sessionData.activity_type,
63
- tokens: sessionData.tokens,
64
- duration_minutes: sessionData.duration_minutes,
65
- project_name: projectName,
66
- });
67
- // Sync to server (fire and forget, don't block)
68
- const auth = readAuth();
69
- if (auth?.token) {
70
- syncToServer(auth.token, {
71
- timestamp: sessionData.timestamp,
72
- activity_type: sessionData.activity_type,
73
- tokens: sessionData.tokens,
74
- duration_minutes: sessionData.duration_minutes,
75
- prompts: sessionData.prompts,
76
- project_name: projectName,
77
- summary: sessionData.summary,
78
- mcp_servers_used: sessionData.mcp_servers_used,
79
- skills_invoked: sessionData.skills_invoked,
80
- tool_counts: sessionData.tool_counts,
81
- }).catch((err) => logError(err));
82
- }
83
- // Update profile streak
84
- const profile = readProfile();
85
- if (profile) {
86
- const today = new Date().toISOString().slice(0, 10);
87
- const lastDate = profile.last_session?.slice(0, 10);
88
- let newStreak = profile.streak_current;
89
- if (lastDate === today) {
90
- // Same day, no streak change
91
- }
92
- else if (lastDate === getYesterday()) {
93
- newStreak++;
94
- }
95
- else {
96
- newStreak = 1;
97
- }
98
- updateProfile({
99
- streak_current: newStreak,
100
- streak_best: Math.max(profile.streak_best, newStreak),
101
- total_sessions: profile.total_sessions + 1,
102
- total_tokens: profile.total_tokens + estimatedTokens,
103
- last_session: new Date().toISOString(),
104
- });
105
- }
17
+ await syncToServer([signals], auth.token);
106
18
  }
107
19
  catch (err) {
108
20
  logError(err);
109
21
  }
110
22
  }
111
- async function syncToServer(token, session) {
112
- const controller = new AbortController();
113
- const timeout = setTimeout(() => controller.abort(), 4000);
114
- try {
115
- await fetch(`${API_BASE}/api/buildpartner/sync`, {
116
- method: "POST",
117
- headers: {
118
- "Authorization": `Bearer ${token}`,
119
- "Content-Type": "application/json",
120
- },
121
- body: JSON.stringify({ sessions: [session] }),
122
- signal: controller.signal,
123
- });
124
- }
125
- finally {
126
- clearTimeout(timeout);
127
- }
128
- }
129
- function findMostRecentSession() {
130
- const projectsDir = join(homedir(), ".claude", "projects");
131
- let newest = null;
132
- try {
133
- for (const projectDir of readdirSync(projectsDir)) {
134
- const fullDir = join(projectsDir, projectDir);
135
- if (!statSync(fullDir).isDirectory())
136
- continue;
137
- for (const file of readdirSync(fullDir)) {
138
- if (!file.endsWith(".jsonl"))
139
- continue;
140
- const fullPath = join(fullDir, file);
141
- const mtime = statSync(fullPath).mtimeMs;
142
- if (!newest || mtime > newest.mtime) {
143
- newest = { path: fullPath, mtime };
144
- }
145
- }
146
- }
147
- }
148
- catch {
149
- return null;
150
- }
151
- // Only return if modified in the last 5 minutes
152
- if (newest && Date.now() - newest.mtime < 5 * 60 * 1000) {
153
- return newest.path;
154
- }
155
- return newest?.path || null;
156
- }
157
- function getYesterday() {
158
- const d = new Date();
159
- d.setDate(d.getDate() - 1);
160
- return d.toISOString().slice(0, 10);
161
- }
162
23
  //# sourceMappingURL=log-session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"log-session.js","sourceRoot":"","sources":["../../../src/commands/log-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"log-session.js","sourceRoot":"","sources":["../../../src/commands/log-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,EAAE,KAAK;YAAE,OAAO;QAEzB,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function reset(): Promise<void>;
@@ -0,0 +1,130 @@
1
+ import { existsSync, readFileSync, writeFileSync, rmSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ import { getBuildPartnerDir } from "../store/local-store.js";
5
+ const CLAUDE_JSON_PATH = join(homedir(), ".claude.json");
6
+ const LEGACY_MCP_PATH = join(homedir(), ".claude", "mcp_servers.json");
7
+ const SETTINGS_PATH = join(homedir(), ".claude", "settings.json");
8
+ const GLOBAL_SKILLS_DIR = join(homedir(), ".claude", "skills");
9
+ const BUILDPARTNER_HOOK_COMMAND = "npx buildpartner log-session";
10
+ export async function reset() {
11
+ console.log("\n BuildPartner Full Reset\n");
12
+ const removed = [];
13
+ // 1. Remove ~/.buildpartner/ directory
14
+ const bpDir = getBuildPartnerDir();
15
+ if (existsSync(bpDir)) {
16
+ rmSync(bpDir, { recursive: true, force: true });
17
+ removed.push("~/.buildpartner/ (all local data)");
18
+ }
19
+ // 2. Remove bp-* and mp-* (legacy) skill directories from ~/.claude/skills/
20
+ if (existsSync(GLOBAL_SKILLS_DIR)) {
21
+ try {
22
+ const entries = readdirSync(GLOBAL_SKILLS_DIR);
23
+ const bpSkills = entries.filter((e) => e.startsWith("bp-") || e.startsWith("mp-"));
24
+ for (const skill of bpSkills) {
25
+ rmSync(join(GLOBAL_SKILLS_DIR, skill), { recursive: true, force: true });
26
+ }
27
+ if (bpSkills.length > 0) {
28
+ removed.push(`${bpSkills.length} skills from ~/.claude/skills/`);
29
+ }
30
+ }
31
+ catch { }
32
+ }
33
+ // 3. Remove MCP server from ~/.claude.json (buildpartner + legacy myplayer)
34
+ if (existsSync(CLAUDE_JSON_PATH)) {
35
+ try {
36
+ const config = JSON.parse(readFileSync(CLAUDE_JSON_PATH, "utf-8"));
37
+ let changed = false;
38
+ for (const key of ["buildpartner", "myplayer"]) {
39
+ if (config.mcpServers?.[key]) {
40
+ delete config.mcpServers[key];
41
+ changed = true;
42
+ }
43
+ }
44
+ if (changed) {
45
+ writeFileSync(CLAUDE_JSON_PATH, JSON.stringify(config, null, 2) + "\n");
46
+ removed.push("MCP server from ~/.claude.json");
47
+ }
48
+ }
49
+ catch { }
50
+ }
51
+ // 4. Remove MCP server from legacy path (buildpartner + legacy myplayer)
52
+ if (existsSync(LEGACY_MCP_PATH)) {
53
+ try {
54
+ const config = JSON.parse(readFileSync(LEGACY_MCP_PATH, "utf-8"));
55
+ let changed = false;
56
+ for (const key of ["buildpartner", "myplayer"]) {
57
+ if (config.mcpServers?.[key]) {
58
+ delete config.mcpServers[key];
59
+ changed = true;
60
+ }
61
+ if (config[key]) {
62
+ delete config[key];
63
+ changed = true;
64
+ }
65
+ }
66
+ if (changed) {
67
+ writeFileSync(LEGACY_MCP_PATH, JSON.stringify(config, null, 2) + "\n");
68
+ removed.push("MCP server from ~/.claude/mcp_servers.json");
69
+ }
70
+ }
71
+ catch { }
72
+ }
73
+ // 5. Remove hook and permission from ~/.claude/settings.json
74
+ if (existsSync(SETTINGS_PATH)) {
75
+ try {
76
+ const settings = JSON.parse(readFileSync(SETTINGS_PATH, "utf-8"));
77
+ let changed = false;
78
+ // Remove Stop hook
79
+ if (Array.isArray(settings?.hooks?.Stop)) {
80
+ const before = settings.hooks.Stop.length;
81
+ settings.hooks.Stop = settings.hooks.Stop.filter((entry) => {
82
+ if (typeof entry !== "object" || entry === null)
83
+ return true;
84
+ const innerHooks = entry.hooks;
85
+ if (!Array.isArray(innerHooks))
86
+ return true;
87
+ return !innerHooks.some((h) => typeof h === "object" &&
88
+ h !== null &&
89
+ h.command === BUILDPARTNER_HOOK_COMMAND);
90
+ });
91
+ if (settings.hooks.Stop.length < before) {
92
+ changed = true;
93
+ removed.push("Stop hook from ~/.claude/settings.json");
94
+ }
95
+ }
96
+ // Remove permissions (buildpartner + legacy myplayer)
97
+ if (Array.isArray(settings?.permissions?.allow)) {
98
+ const allow = settings.permissions.allow;
99
+ const toRemove = ["mcp__buildpartner__*", "mcp__myplayer__*"];
100
+ let removedPerms = false;
101
+ for (const perm of toRemove) {
102
+ const idx = allow.indexOf(perm);
103
+ if (idx !== -1) {
104
+ allow.splice(idx, 1);
105
+ removedPerms = true;
106
+ }
107
+ }
108
+ if (removedPerms) {
109
+ changed = true;
110
+ removed.push("MCP permissions from ~/.claude/settings.json");
111
+ }
112
+ }
113
+ if (changed) {
114
+ writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + "\n");
115
+ }
116
+ }
117
+ catch { }
118
+ }
119
+ if (removed.length === 0) {
120
+ console.log(" Nothing to reset. BuildPartner is not installed.\n");
121
+ }
122
+ else {
123
+ console.log(" Removed:");
124
+ for (const item of removed) {
125
+ console.log(` - ${item}`);
126
+ }
127
+ console.log("\n Run `npx buildpartner setup` to reinstall.\n");
128
+ }
129
+ }
130
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../../src/commands/reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACzD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;AACvE,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAClE,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC/D,MAAM,yBAAyB,GAAG,8BAA8B,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,uCAAuC;IACvC,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IACpD,CAAC;IAED,4EAA4E;IAC5E,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YACnF,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,gCAAgC,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,4EAA4E;IAC5E,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;YACnE,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,KAAK,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC/C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7B,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBAC9B,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;YACH,CAAC;YACD,IAAI,OAAO,EAAE,CAAC;gBACZ,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,yEAAyE;IACzE,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;YAClE,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,KAAK,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC/C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7B,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBAC9B,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;gBACD,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBAChB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;oBACnB,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;YACH,CAAC;YACD,IAAI,OAAO,EAAE,CAAC;gBACZ,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;gBACvE,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,6DAA6D;IAC7D,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;YAClE,IAAI,OAAO,GAAG,KAAK,CAAC;YAEpB,mBAAmB;YACnB,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;gBACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC1C,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAc,EAAE,EAAE;oBAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;wBAAE,OAAO,IAAI,CAAC;oBAC7D,MAAM,UAAU,GAAI,KAAiC,CAAC,KAAK,CAAC;oBAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;wBAAE,OAAO,IAAI,CAAC;oBAC5C,OAAO,CAAC,UAAU,CAAC,IAAI,CACrB,CAAC,CAAU,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,QAAQ;wBACrB,CAAC,KAAK,IAAI;wBACT,CAA6B,CAAC,OAAO,KAAK,yBAAyB,CACvE,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACH,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;oBACxC,OAAO,GAAG,IAAI,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;YAED,sDAAsD;YACtD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC;gBAChD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAiB,CAAC;gBACrD,MAAM,QAAQ,GAAG,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;gBAC9D,IAAI,YAAY,GAAG,KAAK,CAAC;gBACzB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;oBAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAChC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;wBACf,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;wBACrB,YAAY,GAAG,IAAI,CAAC;oBACtB,CAAC;gBACH,CAAC;gBACD,IAAI,YAAY,EAAE,CAAC;oBACjB,OAAO,GAAG,IAAI,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}