@gethmy/mcp 2.3.2 → 2.3.4
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 +199 -4
- package/dist/index.js +199 -4
- package/dist/lib/api-client.js +1 -433
- package/dist/lib/config.js +0 -18
- package/package.json +9 -5
- package/src/api-client.ts +6 -0
- package/src/memory-cleanup.ts +158 -0
- package/src/server.ts +140 -7
- package/dist/lib/active-learning.js +0 -974
- package/dist/lib/auto-session.js +0 -195
- package/dist/lib/cli.js +0 -34964
- package/dist/lib/consolidation.js +0 -388
- package/dist/lib/context-assembly.js +0 -1311
- package/dist/lib/graph-expansion.js +0 -147
- package/dist/lib/http.js +0 -1962
- package/dist/lib/index.js +0 -29527
- package/dist/lib/lifecycle-maintenance.js +0 -672
- package/dist/lib/memory-cleanup.js +0 -1361
- package/dist/lib/onboard.js +0 -2592
- package/dist/lib/prompt-builder.js +0 -481
- package/dist/lib/remote.js +0 -31756
- package/dist/lib/server.js +0 -29524
- package/dist/lib/skills.js +0 -776
- package/dist/lib/tui/agents.js +0 -137
- package/dist/lib/tui/docs.js +0 -1647
- package/dist/lib/tui/setup.js +0 -5828
- package/dist/lib/tui/theme.js +0 -192
- package/dist/lib/tui/writer.js +0 -1173
package/dist/cli.js
CHANGED
|
@@ -28465,6 +28465,85 @@ function generateHealthReport(report) {
|
|
|
28465
28465
|
return lines.join(`
|
|
28466
28466
|
`);
|
|
28467
28467
|
}
|
|
28468
|
+
async function purgeMemories(client3, workspaceId, projectId, options) {
|
|
28469
|
+
const dryRun = options.dryRun !== false;
|
|
28470
|
+
const { filters } = options;
|
|
28471
|
+
const hasFilter = filters.tier || filters.scope || filters.type || filters.olderThanDays !== undefined || filters.maxConfidence !== undefined || filters.tags && filters.tags.length > 0;
|
|
28472
|
+
if (!hasFilter) {
|
|
28473
|
+
throw new Error("At least one narrowing filter (tier, scope, type, olderThanDays, maxConfidence, tags) is required.");
|
|
28474
|
+
}
|
|
28475
|
+
const allMatches = [];
|
|
28476
|
+
let offset = 0;
|
|
28477
|
+
const pageSize = 100;
|
|
28478
|
+
const now = Date.now();
|
|
28479
|
+
while (true) {
|
|
28480
|
+
const result = await client3.listMemoryEntities({
|
|
28481
|
+
workspace_id: workspaceId,
|
|
28482
|
+
project_id: projectId,
|
|
28483
|
+
type: filters.type,
|
|
28484
|
+
scope: filters.scope,
|
|
28485
|
+
tags: filters.tags,
|
|
28486
|
+
limit: pageSize,
|
|
28487
|
+
offset
|
|
28488
|
+
});
|
|
28489
|
+
const entities = result.entities || [];
|
|
28490
|
+
if (entities.length === 0)
|
|
28491
|
+
break;
|
|
28492
|
+
for (const entity of entities) {
|
|
28493
|
+
if (filters.tier && entity.memory_tier !== filters.tier)
|
|
28494
|
+
continue;
|
|
28495
|
+
if (filters.maxConfidence !== undefined && entity.confidence > filters.maxConfidence)
|
|
28496
|
+
continue;
|
|
28497
|
+
if (filters.olderThanDays !== undefined) {
|
|
28498
|
+
const ref = entity.last_accessed_at || entity.created_at;
|
|
28499
|
+
const ageDays = (now - new Date(ref).getTime()) / MS_PER_DAY;
|
|
28500
|
+
if (ageDays < filters.olderThanDays)
|
|
28501
|
+
continue;
|
|
28502
|
+
}
|
|
28503
|
+
allMatches.push(entity);
|
|
28504
|
+
}
|
|
28505
|
+
if (entities.length < pageSize)
|
|
28506
|
+
break;
|
|
28507
|
+
offset += pageSize;
|
|
28508
|
+
}
|
|
28509
|
+
const items = allMatches.map((e) => ({
|
|
28510
|
+
id: e.id,
|
|
28511
|
+
title: e.title,
|
|
28512
|
+
type: e.type,
|
|
28513
|
+
tier: e.memory_tier,
|
|
28514
|
+
confidence: e.confidence,
|
|
28515
|
+
ageDays: Math.round((now - new Date(e.last_accessed_at || e.created_at).getTime()) / MS_PER_DAY)
|
|
28516
|
+
}));
|
|
28517
|
+
const errors3 = [];
|
|
28518
|
+
let purged = 0;
|
|
28519
|
+
if (!dryRun) {
|
|
28520
|
+
for (let i = 0;i < allMatches.length; i += CONCURRENCY_LIMIT) {
|
|
28521
|
+
const batch = allMatches.slice(i, i + CONCURRENCY_LIMIT);
|
|
28522
|
+
const results = await Promise.allSettled(batch.map((e) => client3.deleteMemoryEntity(e.id)));
|
|
28523
|
+
for (let j = 0;j < results.length; j++) {
|
|
28524
|
+
if (results[j].status === "fulfilled") {
|
|
28525
|
+
purged++;
|
|
28526
|
+
} else {
|
|
28527
|
+
errors3.push({
|
|
28528
|
+
entityId: batch[j].id,
|
|
28529
|
+
message: results[j].status === "rejected" ? String(results[j].reason) : "Unknown error"
|
|
28530
|
+
});
|
|
28531
|
+
}
|
|
28532
|
+
}
|
|
28533
|
+
}
|
|
28534
|
+
}
|
|
28535
|
+
return {
|
|
28536
|
+
success: errors3.length === 0,
|
|
28537
|
+
dryRun,
|
|
28538
|
+
timestamp: new Date().toISOString(),
|
|
28539
|
+
workspace: { id: workspaceId, projectId },
|
|
28540
|
+
filters,
|
|
28541
|
+
matched: allMatches.length,
|
|
28542
|
+
purged: dryRun ? 0 : purged,
|
|
28543
|
+
items,
|
|
28544
|
+
errors: errors3
|
|
28545
|
+
};
|
|
28546
|
+
}
|
|
28468
28547
|
|
|
28469
28548
|
// src/onboard.ts
|
|
28470
28549
|
async function onboardNewUser(params) {
|
|
@@ -29060,6 +29139,20 @@ var TOOLS = {
|
|
|
29060
29139
|
estimatedMinutesRemaining: {
|
|
29061
29140
|
type: "number",
|
|
29062
29141
|
description: "Updated time estimate"
|
|
29142
|
+
},
|
|
29143
|
+
actions: {
|
|
29144
|
+
type: "array",
|
|
29145
|
+
items: {
|
|
29146
|
+
type: "object",
|
|
29147
|
+
properties: {
|
|
29148
|
+
description: {
|
|
29149
|
+
type: "string",
|
|
29150
|
+
description: "What was done, e.g. 'Edited CardDetailSheet.tsx — added done toggle'"
|
|
29151
|
+
}
|
|
29152
|
+
},
|
|
29153
|
+
required: ["description"]
|
|
29154
|
+
},
|
|
29155
|
+
description: "Actions performed since last update. Each becomes a visible activity log entry."
|
|
29063
29156
|
}
|
|
29064
29157
|
},
|
|
29065
29158
|
required: ["cardId", "agentIdentifier", "agentName"]
|
|
@@ -29941,6 +30034,53 @@ var TOOLS = {
|
|
|
29941
30034
|
},
|
|
29942
30035
|
required: []
|
|
29943
30036
|
}
|
|
30037
|
+
},
|
|
30038
|
+
harmony_purge_memories: {
|
|
30039
|
+
description: "Bulk-delete memory entities matching filters within a project. Requires at least one narrowing filter (tier, scope, type, olderThanDays, maxConfidence, tags). Dry-run by default — preview what would be deleted before executing.",
|
|
30040
|
+
inputSchema: {
|
|
30041
|
+
type: "object",
|
|
30042
|
+
properties: {
|
|
30043
|
+
workspaceId: {
|
|
30044
|
+
type: "string",
|
|
30045
|
+
description: "Workspace ID (optional if context set)"
|
|
30046
|
+
},
|
|
30047
|
+
projectId: {
|
|
30048
|
+
type: "string",
|
|
30049
|
+
description: "Project ID (required — purge is project-scoped). Falls back to active project context."
|
|
30050
|
+
},
|
|
30051
|
+
dryRun: {
|
|
30052
|
+
type: "boolean",
|
|
30053
|
+
description: "Preview what would be deleted without executing (default: true)"
|
|
30054
|
+
},
|
|
30055
|
+
tier: {
|
|
30056
|
+
type: "string",
|
|
30057
|
+
enum: ["draft", "episode", "reference"],
|
|
30058
|
+
description: 'Filter by memory tier (e.g. "draft")'
|
|
30059
|
+
},
|
|
30060
|
+
scope: {
|
|
30061
|
+
type: "string",
|
|
30062
|
+
description: 'Filter by scope (e.g. "private", "project", "workspace")'
|
|
30063
|
+
},
|
|
30064
|
+
type: {
|
|
30065
|
+
type: "string",
|
|
30066
|
+
description: 'Filter by entity type (e.g. "error", "pattern", "lesson", "decision")'
|
|
30067
|
+
},
|
|
30068
|
+
olderThanDays: {
|
|
30069
|
+
type: "number",
|
|
30070
|
+
description: "Only include entities not accessed in at least this many days"
|
|
30071
|
+
},
|
|
30072
|
+
maxConfidence: {
|
|
30073
|
+
type: "number",
|
|
30074
|
+
description: "Only include entities with confidence at or below this value (e.g. 0.3 for low-confidence junk)"
|
|
30075
|
+
},
|
|
30076
|
+
tags: {
|
|
30077
|
+
type: "array",
|
|
30078
|
+
items: { type: "string" },
|
|
30079
|
+
description: "Only include entities matching these tags"
|
|
30080
|
+
}
|
|
30081
|
+
},
|
|
30082
|
+
required: []
|
|
30083
|
+
}
|
|
29944
30084
|
}
|
|
29945
30085
|
};
|
|
29946
30086
|
var RESOURCES = [
|
|
@@ -30570,12 +30710,20 @@ async function handleToolCall(name, args, deps) {
|
|
|
30570
30710
|
const agentIdentifier = exports_external.string().min(1).max(100).parse(args.agentIdentifier);
|
|
30571
30711
|
const agentName = exports_external.string().min(1).max(100).parse(args.agentName);
|
|
30572
30712
|
const progressPercent = args.progressPercent !== undefined ? exports_external.number().min(0).max(100).parse(args.progressPercent) : undefined;
|
|
30573
|
-
const
|
|
30713
|
+
const callerActions = args.actions;
|
|
30714
|
+
const now = new Date().toISOString();
|
|
30715
|
+
const callerRecentActions = [
|
|
30716
|
+
...args.recentActions || [],
|
|
30717
|
+
...(callerActions || []).map((a) => ({
|
|
30718
|
+
action: a.description,
|
|
30719
|
+
ts: now
|
|
30720
|
+
}))
|
|
30721
|
+
];
|
|
30574
30722
|
const memSession = getMemorySession(cardId);
|
|
30575
30723
|
let mergedRecentActions;
|
|
30576
30724
|
if (memSession?.dirty) {
|
|
30577
|
-
mergedRecentActions = mergeMemoryActionsInto(cardId, callerRecentActions
|
|
30578
|
-
} else if (callerRecentActions) {
|
|
30725
|
+
mergedRecentActions = mergeMemoryActionsInto(cardId, callerRecentActions);
|
|
30726
|
+
} else if (callerRecentActions.length > 0) {
|
|
30579
30727
|
mergedRecentActions = callerRecentActions;
|
|
30580
30728
|
}
|
|
30581
30729
|
const result = await client3.updateAgentProgress(cardId, {
|
|
@@ -31485,6 +31633,42 @@ async function handleToolCall(name, args, deps) {
|
|
|
31485
31633
|
healthReport: report.healthReport
|
|
31486
31634
|
};
|
|
31487
31635
|
}
|
|
31636
|
+
case "harmony_purge_memories": {
|
|
31637
|
+
const workspaceId = args.workspaceId || deps.getActiveWorkspaceId();
|
|
31638
|
+
if (!workspaceId) {
|
|
31639
|
+
throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
|
|
31640
|
+
}
|
|
31641
|
+
const projectId = args.projectId || deps.getActiveProjectId();
|
|
31642
|
+
if (!projectId) {
|
|
31643
|
+
throw new Error("No project specified. Purge requires a project scope. Use harmony_set_project_context or provide projectId.");
|
|
31644
|
+
}
|
|
31645
|
+
const filters = {};
|
|
31646
|
+
if (args.tier)
|
|
31647
|
+
filters.tier = args.tier;
|
|
31648
|
+
if (args.scope)
|
|
31649
|
+
filters.scope = args.scope;
|
|
31650
|
+
if (args.type)
|
|
31651
|
+
filters.type = args.type;
|
|
31652
|
+
if (args.olderThanDays !== undefined)
|
|
31653
|
+
filters.olderThanDays = args.olderThanDays;
|
|
31654
|
+
if (args.maxConfidence !== undefined)
|
|
31655
|
+
filters.maxConfidence = args.maxConfidence;
|
|
31656
|
+
if (args.tags)
|
|
31657
|
+
filters.tags = args.tags;
|
|
31658
|
+
const report = await purgeMemories(client3, workspaceId, projectId, {
|
|
31659
|
+
dryRun: args.dryRun,
|
|
31660
|
+
filters
|
|
31661
|
+
});
|
|
31662
|
+
return {
|
|
31663
|
+
success: report.success,
|
|
31664
|
+
dryRun: report.dryRun,
|
|
31665
|
+
matched: report.matched,
|
|
31666
|
+
purged: report.purged,
|
|
31667
|
+
items: report.items,
|
|
31668
|
+
errors: report.errors,
|
|
31669
|
+
message: report.dryRun ? `Found ${report.matched} entities matching filters. Run with dryRun=false to delete.` : `Purged ${report.purged} of ${report.matched} matching entities.`
|
|
31670
|
+
};
|
|
31671
|
+
}
|
|
31488
31672
|
default:
|
|
31489
31673
|
throw new Error(`Unknown tool: ${name}`);
|
|
31490
31674
|
}
|
|
@@ -31522,15 +31706,26 @@ class HarmonyMCPServer {
|
|
|
31522
31706
|
const cv = this.server.getClientVersion();
|
|
31523
31707
|
return cv ? { name: cv.name, version: cv.version } : null;
|
|
31524
31708
|
});
|
|
31709
|
+
let exitCode = 0;
|
|
31525
31710
|
const handleShutdown = async () => {
|
|
31526
31711
|
try {
|
|
31527
31712
|
await shutdownAllSessions();
|
|
31528
31713
|
} catch {}
|
|
31529
31714
|
destroyAutoSession();
|
|
31530
|
-
process.exit(
|
|
31715
|
+
process.exit(exitCode);
|
|
31531
31716
|
};
|
|
31532
31717
|
process.on("SIGINT", handleShutdown);
|
|
31533
31718
|
process.on("SIGTERM", handleShutdown);
|
|
31719
|
+
process.on("uncaughtException", (err) => {
|
|
31720
|
+
console.error("MCP server uncaught exception:", err);
|
|
31721
|
+
exitCode = 1;
|
|
31722
|
+
handleShutdown();
|
|
31723
|
+
});
|
|
31724
|
+
process.on("unhandledRejection", (reason) => {
|
|
31725
|
+
console.error("MCP server unhandled rejection:", reason);
|
|
31726
|
+
exitCode = 1;
|
|
31727
|
+
handleShutdown();
|
|
31728
|
+
});
|
|
31534
31729
|
try {
|
|
31535
31730
|
if (isConfigured()) {
|
|
31536
31731
|
const workspaceId = getActiveWorkspaceId();
|
package/dist/index.js
CHANGED
|
@@ -26225,6 +26225,85 @@ function generateHealthReport(report) {
|
|
|
26225
26225
|
return lines.join(`
|
|
26226
26226
|
`);
|
|
26227
26227
|
}
|
|
26228
|
+
async function purgeMemories(client3, workspaceId, projectId, options) {
|
|
26229
|
+
const dryRun = options.dryRun !== false;
|
|
26230
|
+
const { filters } = options;
|
|
26231
|
+
const hasFilter = filters.tier || filters.scope || filters.type || filters.olderThanDays !== undefined || filters.maxConfidence !== undefined || filters.tags && filters.tags.length > 0;
|
|
26232
|
+
if (!hasFilter) {
|
|
26233
|
+
throw new Error("At least one narrowing filter (tier, scope, type, olderThanDays, maxConfidence, tags) is required.");
|
|
26234
|
+
}
|
|
26235
|
+
const allMatches = [];
|
|
26236
|
+
let offset = 0;
|
|
26237
|
+
const pageSize = 100;
|
|
26238
|
+
const now = Date.now();
|
|
26239
|
+
while (true) {
|
|
26240
|
+
const result = await client3.listMemoryEntities({
|
|
26241
|
+
workspace_id: workspaceId,
|
|
26242
|
+
project_id: projectId,
|
|
26243
|
+
type: filters.type,
|
|
26244
|
+
scope: filters.scope,
|
|
26245
|
+
tags: filters.tags,
|
|
26246
|
+
limit: pageSize,
|
|
26247
|
+
offset
|
|
26248
|
+
});
|
|
26249
|
+
const entities = result.entities || [];
|
|
26250
|
+
if (entities.length === 0)
|
|
26251
|
+
break;
|
|
26252
|
+
for (const entity of entities) {
|
|
26253
|
+
if (filters.tier && entity.memory_tier !== filters.tier)
|
|
26254
|
+
continue;
|
|
26255
|
+
if (filters.maxConfidence !== undefined && entity.confidence > filters.maxConfidence)
|
|
26256
|
+
continue;
|
|
26257
|
+
if (filters.olderThanDays !== undefined) {
|
|
26258
|
+
const ref = entity.last_accessed_at || entity.created_at;
|
|
26259
|
+
const ageDays = (now - new Date(ref).getTime()) / MS_PER_DAY;
|
|
26260
|
+
if (ageDays < filters.olderThanDays)
|
|
26261
|
+
continue;
|
|
26262
|
+
}
|
|
26263
|
+
allMatches.push(entity);
|
|
26264
|
+
}
|
|
26265
|
+
if (entities.length < pageSize)
|
|
26266
|
+
break;
|
|
26267
|
+
offset += pageSize;
|
|
26268
|
+
}
|
|
26269
|
+
const items = allMatches.map((e) => ({
|
|
26270
|
+
id: e.id,
|
|
26271
|
+
title: e.title,
|
|
26272
|
+
type: e.type,
|
|
26273
|
+
tier: e.memory_tier,
|
|
26274
|
+
confidence: e.confidence,
|
|
26275
|
+
ageDays: Math.round((now - new Date(e.last_accessed_at || e.created_at).getTime()) / MS_PER_DAY)
|
|
26276
|
+
}));
|
|
26277
|
+
const errors3 = [];
|
|
26278
|
+
let purged = 0;
|
|
26279
|
+
if (!dryRun) {
|
|
26280
|
+
for (let i = 0;i < allMatches.length; i += CONCURRENCY_LIMIT) {
|
|
26281
|
+
const batch = allMatches.slice(i, i + CONCURRENCY_LIMIT);
|
|
26282
|
+
const results = await Promise.allSettled(batch.map((e) => client3.deleteMemoryEntity(e.id)));
|
|
26283
|
+
for (let j = 0;j < results.length; j++) {
|
|
26284
|
+
if (results[j].status === "fulfilled") {
|
|
26285
|
+
purged++;
|
|
26286
|
+
} else {
|
|
26287
|
+
errors3.push({
|
|
26288
|
+
entityId: batch[j].id,
|
|
26289
|
+
message: results[j].status === "rejected" ? String(results[j].reason) : "Unknown error"
|
|
26290
|
+
});
|
|
26291
|
+
}
|
|
26292
|
+
}
|
|
26293
|
+
}
|
|
26294
|
+
}
|
|
26295
|
+
return {
|
|
26296
|
+
success: errors3.length === 0,
|
|
26297
|
+
dryRun,
|
|
26298
|
+
timestamp: new Date().toISOString(),
|
|
26299
|
+
workspace: { id: workspaceId, projectId },
|
|
26300
|
+
filters,
|
|
26301
|
+
matched: allMatches.length,
|
|
26302
|
+
purged: dryRun ? 0 : purged,
|
|
26303
|
+
items,
|
|
26304
|
+
errors: errors3
|
|
26305
|
+
};
|
|
26306
|
+
}
|
|
26228
26307
|
|
|
26229
26308
|
// src/onboard.ts
|
|
26230
26309
|
async function onboardNewUser(params) {
|
|
@@ -26820,6 +26899,20 @@ var TOOLS = {
|
|
|
26820
26899
|
estimatedMinutesRemaining: {
|
|
26821
26900
|
type: "number",
|
|
26822
26901
|
description: "Updated time estimate"
|
|
26902
|
+
},
|
|
26903
|
+
actions: {
|
|
26904
|
+
type: "array",
|
|
26905
|
+
items: {
|
|
26906
|
+
type: "object",
|
|
26907
|
+
properties: {
|
|
26908
|
+
description: {
|
|
26909
|
+
type: "string",
|
|
26910
|
+
description: "What was done, e.g. 'Edited CardDetailSheet.tsx — added done toggle'"
|
|
26911
|
+
}
|
|
26912
|
+
},
|
|
26913
|
+
required: ["description"]
|
|
26914
|
+
},
|
|
26915
|
+
description: "Actions performed since last update. Each becomes a visible activity log entry."
|
|
26823
26916
|
}
|
|
26824
26917
|
},
|
|
26825
26918
|
required: ["cardId", "agentIdentifier", "agentName"]
|
|
@@ -27701,6 +27794,53 @@ var TOOLS = {
|
|
|
27701
27794
|
},
|
|
27702
27795
|
required: []
|
|
27703
27796
|
}
|
|
27797
|
+
},
|
|
27798
|
+
harmony_purge_memories: {
|
|
27799
|
+
description: "Bulk-delete memory entities matching filters within a project. Requires at least one narrowing filter (tier, scope, type, olderThanDays, maxConfidence, tags). Dry-run by default — preview what would be deleted before executing.",
|
|
27800
|
+
inputSchema: {
|
|
27801
|
+
type: "object",
|
|
27802
|
+
properties: {
|
|
27803
|
+
workspaceId: {
|
|
27804
|
+
type: "string",
|
|
27805
|
+
description: "Workspace ID (optional if context set)"
|
|
27806
|
+
},
|
|
27807
|
+
projectId: {
|
|
27808
|
+
type: "string",
|
|
27809
|
+
description: "Project ID (required — purge is project-scoped). Falls back to active project context."
|
|
27810
|
+
},
|
|
27811
|
+
dryRun: {
|
|
27812
|
+
type: "boolean",
|
|
27813
|
+
description: "Preview what would be deleted without executing (default: true)"
|
|
27814
|
+
},
|
|
27815
|
+
tier: {
|
|
27816
|
+
type: "string",
|
|
27817
|
+
enum: ["draft", "episode", "reference"],
|
|
27818
|
+
description: 'Filter by memory tier (e.g. "draft")'
|
|
27819
|
+
},
|
|
27820
|
+
scope: {
|
|
27821
|
+
type: "string",
|
|
27822
|
+
description: 'Filter by scope (e.g. "private", "project", "workspace")'
|
|
27823
|
+
},
|
|
27824
|
+
type: {
|
|
27825
|
+
type: "string",
|
|
27826
|
+
description: 'Filter by entity type (e.g. "error", "pattern", "lesson", "decision")'
|
|
27827
|
+
},
|
|
27828
|
+
olderThanDays: {
|
|
27829
|
+
type: "number",
|
|
27830
|
+
description: "Only include entities not accessed in at least this many days"
|
|
27831
|
+
},
|
|
27832
|
+
maxConfidence: {
|
|
27833
|
+
type: "number",
|
|
27834
|
+
description: "Only include entities with confidence at or below this value (e.g. 0.3 for low-confidence junk)"
|
|
27835
|
+
},
|
|
27836
|
+
tags: {
|
|
27837
|
+
type: "array",
|
|
27838
|
+
items: { type: "string" },
|
|
27839
|
+
description: "Only include entities matching these tags"
|
|
27840
|
+
}
|
|
27841
|
+
},
|
|
27842
|
+
required: []
|
|
27843
|
+
}
|
|
27704
27844
|
}
|
|
27705
27845
|
};
|
|
27706
27846
|
var RESOURCES = [
|
|
@@ -28330,12 +28470,20 @@ async function handleToolCall(name, args, deps) {
|
|
|
28330
28470
|
const agentIdentifier = exports_external.string().min(1).max(100).parse(args.agentIdentifier);
|
|
28331
28471
|
const agentName = exports_external.string().min(1).max(100).parse(args.agentName);
|
|
28332
28472
|
const progressPercent = args.progressPercent !== undefined ? exports_external.number().min(0).max(100).parse(args.progressPercent) : undefined;
|
|
28333
|
-
const
|
|
28473
|
+
const callerActions = args.actions;
|
|
28474
|
+
const now = new Date().toISOString();
|
|
28475
|
+
const callerRecentActions = [
|
|
28476
|
+
...args.recentActions || [],
|
|
28477
|
+
...(callerActions || []).map((a) => ({
|
|
28478
|
+
action: a.description,
|
|
28479
|
+
ts: now
|
|
28480
|
+
}))
|
|
28481
|
+
];
|
|
28334
28482
|
const memSession = getMemorySession(cardId);
|
|
28335
28483
|
let mergedRecentActions;
|
|
28336
28484
|
if (memSession?.dirty) {
|
|
28337
|
-
mergedRecentActions = mergeMemoryActionsInto(cardId, callerRecentActions
|
|
28338
|
-
} else if (callerRecentActions) {
|
|
28485
|
+
mergedRecentActions = mergeMemoryActionsInto(cardId, callerRecentActions);
|
|
28486
|
+
} else if (callerRecentActions.length > 0) {
|
|
28339
28487
|
mergedRecentActions = callerRecentActions;
|
|
28340
28488
|
}
|
|
28341
28489
|
const result = await client3.updateAgentProgress(cardId, {
|
|
@@ -29245,6 +29393,42 @@ async function handleToolCall(name, args, deps) {
|
|
|
29245
29393
|
healthReport: report.healthReport
|
|
29246
29394
|
};
|
|
29247
29395
|
}
|
|
29396
|
+
case "harmony_purge_memories": {
|
|
29397
|
+
const workspaceId = args.workspaceId || deps.getActiveWorkspaceId();
|
|
29398
|
+
if (!workspaceId) {
|
|
29399
|
+
throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
|
|
29400
|
+
}
|
|
29401
|
+
const projectId = args.projectId || deps.getActiveProjectId();
|
|
29402
|
+
if (!projectId) {
|
|
29403
|
+
throw new Error("No project specified. Purge requires a project scope. Use harmony_set_project_context or provide projectId.");
|
|
29404
|
+
}
|
|
29405
|
+
const filters = {};
|
|
29406
|
+
if (args.tier)
|
|
29407
|
+
filters.tier = args.tier;
|
|
29408
|
+
if (args.scope)
|
|
29409
|
+
filters.scope = args.scope;
|
|
29410
|
+
if (args.type)
|
|
29411
|
+
filters.type = args.type;
|
|
29412
|
+
if (args.olderThanDays !== undefined)
|
|
29413
|
+
filters.olderThanDays = args.olderThanDays;
|
|
29414
|
+
if (args.maxConfidence !== undefined)
|
|
29415
|
+
filters.maxConfidence = args.maxConfidence;
|
|
29416
|
+
if (args.tags)
|
|
29417
|
+
filters.tags = args.tags;
|
|
29418
|
+
const report = await purgeMemories(client3, workspaceId, projectId, {
|
|
29419
|
+
dryRun: args.dryRun,
|
|
29420
|
+
filters
|
|
29421
|
+
});
|
|
29422
|
+
return {
|
|
29423
|
+
success: report.success,
|
|
29424
|
+
dryRun: report.dryRun,
|
|
29425
|
+
matched: report.matched,
|
|
29426
|
+
purged: report.purged,
|
|
29427
|
+
items: report.items,
|
|
29428
|
+
errors: report.errors,
|
|
29429
|
+
message: report.dryRun ? `Found ${report.matched} entities matching filters. Run with dryRun=false to delete.` : `Purged ${report.purged} of ${report.matched} matching entities.`
|
|
29430
|
+
};
|
|
29431
|
+
}
|
|
29248
29432
|
default:
|
|
29249
29433
|
throw new Error(`Unknown tool: ${name}`);
|
|
29250
29434
|
}
|
|
@@ -29282,15 +29466,26 @@ class HarmonyMCPServer {
|
|
|
29282
29466
|
const cv = this.server.getClientVersion();
|
|
29283
29467
|
return cv ? { name: cv.name, version: cv.version } : null;
|
|
29284
29468
|
});
|
|
29469
|
+
let exitCode = 0;
|
|
29285
29470
|
const handleShutdown = async () => {
|
|
29286
29471
|
try {
|
|
29287
29472
|
await shutdownAllSessions();
|
|
29288
29473
|
} catch {}
|
|
29289
29474
|
destroyAutoSession();
|
|
29290
|
-
process.exit(
|
|
29475
|
+
process.exit(exitCode);
|
|
29291
29476
|
};
|
|
29292
29477
|
process.on("SIGINT", handleShutdown);
|
|
29293
29478
|
process.on("SIGTERM", handleShutdown);
|
|
29479
|
+
process.on("uncaughtException", (err) => {
|
|
29480
|
+
console.error("MCP server uncaught exception:", err);
|
|
29481
|
+
exitCode = 1;
|
|
29482
|
+
handleShutdown();
|
|
29483
|
+
});
|
|
29484
|
+
process.on("unhandledRejection", (reason) => {
|
|
29485
|
+
console.error("MCP server unhandled rejection:", reason);
|
|
29486
|
+
exitCode = 1;
|
|
29487
|
+
handleShutdown();
|
|
29488
|
+
});
|
|
29294
29489
|
try {
|
|
29295
29490
|
if (isConfigured()) {
|
|
29296
29491
|
const workspaceId = getActiveWorkspaceId();
|