@gethmy/mcp 2.3.1 → 2.3.2

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 (34) hide show
  1. package/dist/lib/active-learning.js +939 -787
  2. package/dist/lib/api-client.js +2527 -644
  3. package/dist/lib/auto-session.js +177 -196
  4. package/dist/lib/cli.js +34954 -128
  5. package/dist/lib/config.js +235 -201
  6. package/dist/lib/consolidation.js +374 -289
  7. package/dist/lib/context-assembly.js +1265 -838
  8. package/dist/lib/graph-expansion.js +139 -155
  9. package/dist/lib/http.js +1917 -130
  10. package/dist/lib/index.js +29525 -5
  11. package/dist/lib/lifecycle-maintenance.js +663 -79
  12. package/dist/lib/memory-cleanup.js +1315 -409
  13. package/dist/lib/onboard.js +2588 -32
  14. package/dist/lib/prompt-builder.js +438 -445
  15. package/dist/lib/remote.js +31733 -143
  16. package/dist/lib/server.js +29388 -3229
  17. package/dist/lib/skills.js +315 -132
  18. package/dist/lib/tui/agents.js +128 -107
  19. package/dist/lib/tui/docs.js +1590 -687
  20. package/dist/lib/tui/setup.js +5698 -804
  21. package/dist/lib/tui/theme.js +183 -86
  22. package/dist/lib/tui/writer.js +1149 -176
  23. package/package.json +2 -2
  24. package/src/memory-cleanup.ts +2 -4
  25. package/dist/lib/__tests__/active-learning.test.js +0 -386
  26. package/dist/lib/__tests__/agent-performance-profiles.test.js +0 -325
  27. package/dist/lib/__tests__/auto-session.test.js +0 -661
  28. package/dist/lib/__tests__/context-assembly.test.js +0 -362
  29. package/dist/lib/__tests__/graph-expansion.test.js +0 -150
  30. package/dist/lib/__tests__/integration-memory-crud.test.js +0 -797
  31. package/dist/lib/__tests__/integration-memory-system.test.js +0 -281
  32. package/dist/lib/__tests__/lifecycle-maintenance.test.js +0 -207
  33. package/dist/lib/__tests__/pattern-detection.test.js +0 -295
  34. package/dist/lib/__tests__/prompt-builder.test.js +0 -418
@@ -1,214 +1,195 @@
1
- /**
2
- * Auto-Session Tracking
3
- *
4
- * Automatically detects agent session boundaries by monitoring tool calls.
5
- * Sessions auto-start when card-mutating tools are called, and auto-end
6
- * after 10 minutes of inactivity or when a different card is worked on.
7
- *
8
- * Agent identity is resolved from the MCP client's `initialize` handshake
9
- * (clientInfo.name), so "Claude Code", "Cursor", "Codex", etc. are
10
- * detected automatically — no hardcoded fallback needed.
11
- */
12
- /** Well-known MCP client names → human-friendly display names */
13
- const CLIENT_DISPLAY_NAMES = {
14
- "claude-code": "Claude Code",
15
- "claude-desktop": "Claude Desktop",
16
- cursor: "Cursor",
17
- windsurf: "Windsurf",
18
- cline: "Cline",
19
- continue: "Continue",
20
- "codex-cli": "OpenAI Codex",
21
- zed: "Zed",
22
- "gemini-cli": "Gemini CLI",
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
+
31
+ // src/auto-session.ts
32
+ var CLIENT_DISPLAY_NAMES = {
33
+ "claude-code": "Claude Code",
34
+ "claude-desktop": "Claude Desktop",
35
+ cursor: "Cursor",
36
+ windsurf: "Windsurf",
37
+ cline: "Cline",
38
+ continue: "Continue",
39
+ "codex-cli": "OpenAI Codex",
40
+ zed: "Zed",
41
+ "gemini-cli": "Gemini CLI"
23
42
  };
24
- /** Derive a slug-style identifier from a client name */
25
43
  function toIdentifier(name) {
26
- return name.toLowerCase().replace(/\s+/g, "-");
44
+ return name.toLowerCase().replace(/\s+/g, "-");
27
45
  }
28
- /** Resolve agent identity from MCP client info */
29
- export function resolveAgentIdentity(info) {
30
- if (!info?.name) {
31
- return { agentIdentifier: "unknown", agentName: "Unknown Agent" };
32
- }
33
- const key = toIdentifier(info.name);
34
- const displayName = CLIENT_DISPLAY_NAMES[key] ?? info.name; // use raw name if not in map
35
- return { agentIdentifier: key, agentName: displayName };
46
+ function resolveAgentIdentity(info) {
47
+ if (!info?.name) {
48
+ return { agentIdentifier: "unknown", agentName: "Unknown Agent" };
49
+ }
50
+ const key = toIdentifier(info.name);
51
+ const displayName = CLIENT_DISPLAY_NAMES[key] ?? info.name;
52
+ return { agentIdentifier: key, agentName: displayName };
36
53
  }
37
- /** Tools that trigger auto-start of a session */
38
- export const AUTO_START_TRIGGERS = new Set([
39
- "harmony_generate_prompt",
40
- "harmony_update_card",
41
- "harmony_move_card",
42
- "harmony_create_subtask",
43
- "harmony_toggle_subtask",
44
- "harmony_add_label_to_card",
45
- "harmony_remove_label_from_card",
54
+ var AUTO_START_TRIGGERS = new Set([
55
+ "harmony_generate_prompt",
56
+ "harmony_update_card",
57
+ "harmony_move_card",
58
+ "harmony_create_subtask",
59
+ "harmony_toggle_subtask",
60
+ "harmony_add_label_to_card",
61
+ "harmony_remove_label_from_card"
46
62
  ]);
47
- export const INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
48
- const CHECK_INTERVAL_MS = 60 * 1000; // 60 seconds
49
- const activeSessions = new Map();
50
- let inactivityTimer = null;
51
- let endCallback = null;
52
- let clientGetter = null;
53
- let clientInfoGetter = null;
54
- /**
55
- * Initialize auto-session tracking.
56
- * @param callback Called when an auto-session ends (runs the learning pipeline)
57
- * @param getClient Function to get the current API client
58
- * @param getClientInfo Function to get MCP client identity from the initialize handshake
59
- */
60
- export function initAutoSession(callback, getClient, getClientInfo) {
61
- endCallback = callback;
62
- clientGetter = getClient;
63
- clientInfoGetter = getClientInfo ?? null;
64
- if (inactivityTimer)
65
- clearInterval(inactivityTimer);
66
- inactivityTimer = setInterval(checkInactivity, CHECK_INTERVAL_MS);
63
+ var INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000;
64
+ var CHECK_INTERVAL_MS = 60 * 1000;
65
+ var activeSessions = new Map;
66
+ var inactivityTimer = null;
67
+ var endCallback = null;
68
+ var clientGetter = null;
69
+ var clientInfoGetter = null;
70
+ function initAutoSession(callback, getClient, getClientInfo) {
71
+ endCallback = callback;
72
+ clientGetter = getClient;
73
+ clientInfoGetter = getClientInfo ?? null;
74
+ if (inactivityTimer)
75
+ clearInterval(inactivityTimer);
76
+ inactivityTimer = setInterval(checkInactivity, CHECK_INTERVAL_MS);
67
77
  }
68
- /**
69
- * Track activity on a card. Auto-starts a session if needed.
70
- */
71
- export async function trackActivity(cardId, options) {
72
- const now = Date.now();
73
- const existing = activeSessions.get(cardId);
74
- if (existing) {
75
- // Update last activity timestamp
76
- existing.lastActivityAt = now;
77
- return;
78
- }
79
- // Only auto-start if the tool is a trigger
80
- if (!options?.autoStart)
81
- return;
82
- const client = options?.client ?? clientGetter?.();
83
- if (!client)
84
- return;
85
- // Collect auto-sessions on other cards to end (avoid mutating map during iteration)
86
- const toEnd = [];
87
- for (const [otherCardId, session] of activeSessions) {
88
- if (otherCardId !== cardId && !session.isExplicit) {
89
- toEnd.push(otherCardId);
90
- }
78
+ async function trackActivity(cardId, options) {
79
+ const now = Date.now();
80
+ const existing = activeSessions.get(cardId);
81
+ if (existing) {
82
+ existing.lastActivityAt = now;
83
+ return;
84
+ }
85
+ if (!options?.autoStart)
86
+ return;
87
+ const client = options?.client ?? clientGetter?.();
88
+ if (!client)
89
+ return;
90
+ const toEnd = [];
91
+ for (const [otherCardId, session] of activeSessions) {
92
+ if (otherCardId !== cardId && !session.isExplicit) {
93
+ toEnd.push(otherCardId);
91
94
  }
92
- for (const otherCardId of toEnd) {
93
- await autoEndSession(client, otherCardId, "completed");
94
- }
95
- // Resolve agent identity from MCP client info
96
- const info = clientInfoGetter?.() ?? null;
97
- const { agentIdentifier, agentName } = resolveAgentIdentity(info);
98
- // Start a new auto-session
99
- try {
100
- await client.startAgentSession(cardId, {
101
- agentIdentifier,
102
- agentName,
103
- status: "working",
104
- });
105
- }
106
- catch {
107
- // Session start failed (might already have one), still track locally
108
- }
109
- activeSessions.set(cardId, {
110
- cardId,
111
- startedAt: now,
112
- lastActivityAt: now,
113
- isExplicit: false,
114
- agentIdentifier,
115
- agentName,
95
+ }
96
+ for (const otherCardId of toEnd) {
97
+ await autoEndSession(client, otherCardId, "completed");
98
+ }
99
+ const info = clientInfoGetter?.() ?? null;
100
+ const { agentIdentifier, agentName } = resolveAgentIdentity(info);
101
+ try {
102
+ await client.startAgentSession(cardId, {
103
+ agentIdentifier,
104
+ agentName,
105
+ status: "working"
116
106
  });
107
+ } catch {}
108
+ activeSessions.set(cardId, {
109
+ cardId,
110
+ startedAt: now,
111
+ lastActivityAt: now,
112
+ isExplicit: false,
113
+ agentIdentifier,
114
+ agentName
115
+ });
117
116
  }
118
- /**
119
- * Mark a session as explicitly started (won't be auto-ended by card switching or inactivity).
120
- * Optionally accepts the real agent identifier/name to store in the session.
121
- */
122
- export function markExplicit(cardId, options) {
123
- const existing = activeSessions.get(cardId);
124
- if (existing) {
125
- existing.isExplicit = true;
126
- if (options?.agentIdentifier)
127
- existing.agentIdentifier = options.agentIdentifier;
128
- if (options?.agentName)
129
- existing.agentName = options.agentName;
130
- }
131
- else {
132
- // Track the explicit session even if we didn't auto-start it
133
- activeSessions.set(cardId, {
134
- cardId,
135
- startedAt: Date.now(),
136
- lastActivityAt: Date.now(),
137
- isExplicit: true,
138
- agentIdentifier: options?.agentIdentifier ?? "explicit",
139
- agentName: options?.agentName ?? "Explicit Agent",
140
- });
141
- }
117
+ function markExplicit(cardId, options) {
118
+ const existing = activeSessions.get(cardId);
119
+ if (existing) {
120
+ existing.isExplicit = true;
121
+ if (options?.agentIdentifier)
122
+ existing.agentIdentifier = options.agentIdentifier;
123
+ if (options?.agentName)
124
+ existing.agentName = options.agentName;
125
+ } else {
126
+ activeSessions.set(cardId, {
127
+ cardId,
128
+ startedAt: Date.now(),
129
+ lastActivityAt: Date.now(),
130
+ isExplicit: true,
131
+ agentIdentifier: options?.agentIdentifier ?? "explicit",
132
+ agentName: options?.agentName ?? "Explicit Agent"
133
+ });
134
+ }
142
135
  }
143
- /**
144
- * Remove a session from tracking (called when session is explicitly ended).
145
- */
146
- export function untrack(cardId) {
147
- activeSessions.delete(cardId);
136
+ function untrack(cardId) {
137
+ activeSessions.delete(cardId);
148
138
  }
149
- /**
150
- * End all active auto-sessions (called on process shutdown).
151
- */
152
- export async function shutdownAllSessions() {
153
- const client = clientGetter?.();
154
- if (!client)
155
- return;
156
- // Snapshot keys to avoid mutating map during iteration
157
- const cardIds = [...activeSessions.keys()];
158
- const promises = cardIds.map((cardId) => autoEndSession(client, cardId, "paused"));
159
- await Promise.allSettled(promises);
139
+ async function shutdownAllSessions() {
140
+ const client = clientGetter?.();
141
+ if (!client)
142
+ return;
143
+ const cardIds = [...activeSessions.keys()];
144
+ const promises = cardIds.map((cardId) => autoEndSession(client, cardId, "paused"));
145
+ await Promise.allSettled(promises);
160
146
  }
161
- /**
162
- * Clean up the interval timer (for tests).
163
- */
164
- export function destroyAutoSession() {
165
- if (inactivityTimer) {
166
- clearInterval(inactivityTimer);
167
- inactivityTimer = null;
168
- }
169
- activeSessions.clear();
170
- endCallback = null;
171
- clientGetter = null;
172
- clientInfoGetter = null;
147
+ function destroyAutoSession() {
148
+ if (inactivityTimer) {
149
+ clearInterval(inactivityTimer);
150
+ inactivityTimer = null;
151
+ }
152
+ activeSessions.clear();
153
+ endCallback = null;
154
+ clientGetter = null;
155
+ clientInfoGetter = null;
173
156
  }
174
- /**
175
- * Get a snapshot of active sessions (for testing/debugging).
176
- */
177
- export function getActiveSessions() {
178
- return activeSessions;
157
+ function getActiveSessions() {
158
+ return activeSessions;
179
159
  }
180
- /**
181
- * Run inactivity check immediately (exported for testing).
182
- * In production, called by the setInterval timer every 60s.
183
- */
184
- export function checkInactivity() {
185
- const now = Date.now();
186
- const client = clientGetter?.();
187
- if (!client)
188
- return;
189
- // Snapshot keys to avoid mutating map during iteration
190
- const entries = [...activeSessions.entries()];
191
- for (const [cardId, session] of entries) {
192
- if (session.isExplicit)
193
- continue;
194
- if (now - session.lastActivityAt > INACTIVITY_TIMEOUT_MS) {
195
- autoEndSession(client, cardId, "completed").catch(() => { });
196
- }
160
+ function checkInactivity() {
161
+ const now = Date.now();
162
+ const client = clientGetter?.();
163
+ if (!client)
164
+ return;
165
+ const entries = [...activeSessions.entries()];
166
+ for (const [cardId, session] of entries) {
167
+ if (session.isExplicit)
168
+ continue;
169
+ if (now - session.lastActivityAt > INACTIVITY_TIMEOUT_MS) {
170
+ autoEndSession(client, cardId, "completed").catch(() => {});
197
171
  }
172
+ }
198
173
  }
199
- // --- Internal ---
200
174
  async function autoEndSession(client, cardId, status) {
201
- activeSessions.delete(cardId);
202
- try {
203
- await client.endAgentSession(cardId, { status });
204
- }
205
- catch {
206
- // Best-effort end
207
- }
208
- try {
209
- await endCallback?.(client, cardId, status);
210
- }
211
- catch {
212
- // Best-effort pipeline
213
- }
175
+ activeSessions.delete(cardId);
176
+ try {
177
+ await client.endAgentSession(cardId, { status });
178
+ } catch {}
179
+ try {
180
+ await endCallback?.(client, cardId, status);
181
+ } catch {}
214
182
  }
183
+ export {
184
+ untrack,
185
+ trackActivity,
186
+ shutdownAllSessions,
187
+ resolveAgentIdentity,
188
+ markExplicit,
189
+ initAutoSession,
190
+ getActiveSessions,
191
+ destroyAutoSession,
192
+ checkInactivity,
193
+ INACTIVITY_TIMEOUT_MS,
194
+ AUTO_START_TRIGGERS
195
+ };