@massa-ai/mcp-client 1.35.0 → 1.36.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.
@@ -125291,6 +125291,7 @@ class IndexJobTracker {
125291
125291
  filesIndexed: r?.filesIndexed ?? 0,
125292
125292
  chunksIndexed: r?.chunksIndexed ?? 0,
125293
125293
  symbolsIndexed: 0,
125294
+ errors: r?.errors ?? 0,
125294
125295
  durationMs: r?.duration ?? 0,
125295
125296
  activatedGraphGenerationId: r?.activatedGraphGenerationId ?? ""
125296
125297
  });
@@ -128782,6 +128783,11 @@ var init_auto_checkpointer = __esm(() => {
128782
128783
  };
128783
128784
  });
128784
128785
 
128786
+ // ../../packages/core/dist/kernel/sanitize/strip-nul.js
128787
+ function stripNul(content) {
128788
+ return content.includes("\x00") ? content.replaceAll("\x00", "") : content;
128789
+ }
128790
+
128785
128791
  // ../../packages/core/dist/services/etl/stages/discover.js
128786
128792
  import fs11 from "fs/promises";
128787
128793
  import path17 from "path";
@@ -128872,7 +128878,7 @@ class DiscoverStage {
128872
128878
  const absolutePath = path17.join(ctx.projectPath, relativePath);
128873
128879
  try {
128874
128880
  const stat = await fs11.stat(absolutePath);
128875
- const content = await fs11.readFile(absolutePath, "utf-8");
128881
+ const content = stripNul(await fs11.readFile(absolutePath, "utf-8"));
128876
128882
  const contentHash = createHash8("sha256").update(content).digest("hex");
128877
128883
  let needsReparse = forceReindex;
128878
128884
  if (!forceReindex) {
@@ -132933,6 +132939,7 @@ class LoadStage {
132933
132939
  let chunksLoaded = 0;
132934
132940
  let symbolsLoaded = 0;
132935
132941
  let errors4 = 0;
132942
+ const fileErrors = [];
132936
132943
  let processedSinceStart = 0;
132937
132944
  let lastEtaLogAt = 0;
132938
132945
  const BATCH = 10;
@@ -133003,6 +133010,12 @@ class LoadStage {
133003
133010
  } catch (err) {
133004
133011
  errors4++;
133005
133012
  processedSinceStart++;
133013
+ if (fileErrors.length < MAX_FILE_ERRORS) {
133014
+ fileErrors.push({
133015
+ filePath: file2.file.relativePath,
133016
+ error: err.message
133017
+ });
133018
+ }
133006
133019
  if (emitLifecycle)
133007
133020
  ctx.emit({
133008
133021
  type: "file_error",
@@ -133068,7 +133081,7 @@ class LoadStage {
133068
133081
  duration: formatDuration(durationMs),
133069
133082
  filesPerSec: filesLoaded > 0 && durationMs > 0 ? Number((filesLoaded / durationMs * 1000).toFixed(2)) : 0
133070
133083
  });
133071
- return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors4 };
133084
+ return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors4, fileErrors };
133072
133085
  }
133073
133086
  async loadToSearchStores(ctx, file2) {
133074
133087
  if (file2.chunks.length === 0)
@@ -133140,6 +133153,7 @@ class LoadStage {
133140
133153
  return batch.definitions.length;
133141
133154
  }
133142
133155
  }
133156
+ var MAX_FILE_ERRORS = 50;
133143
133157
  var init_load = __esm(() => {
133144
133158
  init_dist();
133145
133159
  init_with_deadlock_retry();
@@ -133320,8 +133334,8 @@ class GraphGenerationRepositoryPg {
133320
133334
  async heartbeat(lease, leaseTtlMs) {
133321
133335
  const ttl = validateTtl2(leaseTtlMs);
133322
133336
  return getPrismaClient2().$transaction(async (tx) => {
133323
- const workspace = await lockWorkspace(tx, lease.projectId);
133324
133337
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
133338
+ const workspace = await lockWorkspace(tx, lease.projectId);
133325
133339
  if (!leaseMatches(workspace, generation, lease))
133326
133340
  return { status: "lease_lost" };
133327
133341
  const renewed = await tx.$queryRaw`
@@ -133344,8 +133358,8 @@ class GraphGenerationRepositoryPg {
133344
133358
  }
133345
133359
  async complete(lease) {
133346
133360
  return getPrismaClient2().$transaction(async (tx) => {
133347
- const workspace = await lockWorkspace(tx, lease.projectId);
133348
133361
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
133362
+ const workspace = await lockWorkspace(tx, lease.projectId);
133349
133363
  if (!leaseMatches(workspace, generation, lease))
133350
133364
  return { status: "lease_lost" };
133351
133365
  const live = await tx.$queryRaw`
@@ -133374,8 +133388,8 @@ class GraphGenerationRepositoryPg {
133374
133388
  }
133375
133389
  async activate(lease) {
133376
133390
  return getPrismaClient2().$transaction(async (tx) => {
133377
- const workspace = await lockWorkspace(tx, lease.projectId);
133378
133391
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
133392
+ const workspace = await lockWorkspace(tx, lease.projectId);
133379
133393
  if (!leaseMatches(workspace, generation, lease))
133380
133394
  return { status: "lease_lost" };
133381
133395
  if (workspace.active_graph_generation_id !== generation.expected_active_id) {
@@ -133425,8 +133439,8 @@ class GraphGenerationRepositoryPg {
133425
133439
  async abort(lease, reason) {
133426
133440
  const failureReason = boundedText2(reason, "reason", MAX_FAILURE_REASON);
133427
133441
  return getPrismaClient2().$transaction(async (tx) => {
133428
- const workspace = await lockWorkspace(tx, lease.projectId);
133429
133442
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
133443
+ const workspace = await lockWorkspace(tx, lease.projectId);
133430
133444
  if (!leaseMatches(workspace, generation, lease))
133431
133445
  return { status: "lease_lost" };
133432
133446
  const live = await tx.$queryRaw`
@@ -133502,7 +133516,7 @@ class GraphGenerationCoordinator {
133502
133516
  async begin(input) {
133503
133517
  const deadline = Date.now() + GRAPH_GENERATION_LEASE_TTL_MS;
133504
133518
  for (;; ) {
133505
- const outcome2 = await this.repository.begin({ ...input, leaseTtlMs: GRAPH_GENERATION_LEASE_TTL_MS });
133519
+ const outcome2 = await withDeadlockRetry(() => this.repository.begin({ ...input, leaseTtlMs: GRAPH_GENERATION_LEASE_TTL_MS }), { operation: "graph_generation.begin", maxAttempts: 5 });
133506
133520
  if (outcome2.status === "acquired")
133507
133521
  return outcome2.lease;
133508
133522
  if (outcome2.status === "stale_active") {
@@ -133514,12 +133528,12 @@ class GraphGenerationCoordinator {
133514
133528
  }
133515
133529
  }
133516
133530
  async heartbeat(lease) {
133517
- const outcome2 = await withDeadlockRetry(() => this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS), { operation: "graph_generation.heartbeat", maxAttempts: 3 });
133531
+ const outcome2 = await withDeadlockRetry(() => this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS), { operation: "graph_generation.heartbeat", maxAttempts: 5 });
133518
133532
  if (outcome2.status !== "renewed")
133519
133533
  throw new Error("graph_generation_lease_lost");
133520
133534
  }
133521
133535
  async activate(lease) {
133522
- const completeness = await this.repository.complete(lease);
133536
+ const completeness = await withDeadlockRetry(() => this.repository.complete(lease), { operation: "graph_generation.complete", maxAttempts: 5 });
133523
133537
  if (completeness.status === "incomplete") {
133524
133538
  throw new Error(`graph_generation_incomplete:${completeness.reasons.join(",")}`);
133525
133539
  }
@@ -133528,7 +133542,7 @@ class GraphGenerationCoordinator {
133528
133542
  if (completeness.status === "stale_active") {
133529
133543
  throw new Error(`graph_generation_stale_active:${completeness.activeGenerationId ?? "none"}`);
133530
133544
  }
133531
- const activation = await this.repository.activate(lease);
133545
+ const activation = await withDeadlockRetry(() => this.repository.activate(lease), { operation: "graph_generation.activate", maxAttempts: 5 });
133532
133546
  if (activation.status === "activated")
133533
133547
  return activation;
133534
133548
  if (activation.status === "incomplete") {
@@ -133539,7 +133553,7 @@ class GraphGenerationCoordinator {
133539
133553
  throw new Error(`graph_generation_stale_active:${activation.activeGenerationId ?? "none"}`);
133540
133554
  }
133541
133555
  async abort(lease, reason) {
133542
- const outcome2 = await this.repository.abort(lease, reason);
133556
+ const outcome2 = await withDeadlockRetry(() => this.repository.abort(lease, reason), { operation: "graph_generation.abort", maxAttempts: 5 });
133543
133557
  if (outcome2.status === "lease_lost")
133544
133558
  throw new Error("graph_generation_lease_lost_during_abort");
133545
133559
  }
@@ -133882,7 +133896,12 @@ var init_pipeline = __esm(() => {
133882
133896
  throw managedRunLeaseLost;
133883
133897
  stageTimings.load = Math.round(performance.now() - st4);
133884
133898
  if (loadResult.errors > 0) {
133885
- throw new Error(`ETL completed with ${loadResult.errors} file error${loadResult.errors === 1 ? "" : "s"}`);
133899
+ logger.warn("EtlPipeline: completed with file errors", {
133900
+ projectId,
133901
+ jobId,
133902
+ errors: loadResult.errors,
133903
+ fileErrors: (loadResult.fileErrors ?? []).slice(0, 10)
133904
+ });
133886
133905
  }
133887
133906
  const activationSnapshot = await abortable(this.discover.run(ctx, { forceReindex, includeTests: include_tests }), graphAbortController.signal);
133888
133907
  if (buildGraphInputSnapshotHash(activationSnapshot) !== graphGenerationLease.inputSnapshotHash) {
@@ -133939,6 +133958,7 @@ var init_pipeline = __esm(() => {
133939
133958
  filesIndexed: result.filesIndexed,
133940
133959
  chunksIndexed: result.chunksIndexed,
133941
133960
  errors: result.errors,
133961
+ fileErrors: loadResult.fileErrors ?? [],
133942
133962
  duration: durationMs,
133943
133963
  activatedGraphGenerationId: result.activatedGraphGenerationId,
133944
133964
  parserDiagnostics: result.parserDiagnostics
@@ -133949,6 +133969,7 @@ var init_pipeline = __esm(() => {
133949
133969
  filesIndexed: result.filesIndexed,
133950
133970
  chunksIndexed: result.chunksIndexed,
133951
133971
  symbolsIndexed: result.symbolsIndexed,
133972
+ errors: result.errors,
133952
133973
  durationMs,
133953
133974
  activatedGraphGenerationId: result.activatedGraphGenerationId
133954
133975
  });
package/dist/index.js CHANGED
@@ -124322,6 +124322,7 @@ class IndexJobTracker {
124322
124322
  filesIndexed: r?.filesIndexed ?? 0,
124323
124323
  chunksIndexed: r?.chunksIndexed ?? 0,
124324
124324
  symbolsIndexed: 0,
124325
+ errors: r?.errors ?? 0,
124325
124326
  durationMs: r?.duration ?? 0,
124326
124327
  activatedGraphGenerationId: r?.activatedGraphGenerationId ?? ""
124327
124328
  });
@@ -124343,6 +124344,11 @@ var init_index_job_tracker = __esm(() => {
124343
124344
  indexJobTracker = IndexJobTracker.getInstance();
124344
124345
  });
124345
124346
 
124347
+ // ../../packages/core/dist/kernel/sanitize/strip-nul.js
124348
+ function stripNul(content) {
124349
+ return content.includes("\x00") ? content.replaceAll("\x00", "") : content;
124350
+ }
124351
+
124346
124352
  // ../../packages/core/dist/services/etl/stages/discover.js
124347
124353
  import fs8 from "fs/promises";
124348
124354
  import path14 from "path";
@@ -124433,7 +124439,7 @@ class DiscoverStage {
124433
124439
  const absolutePath = path14.join(ctx.projectPath, relativePath);
124434
124440
  try {
124435
124441
  const stat = await fs8.stat(absolutePath);
124436
- const content = await fs8.readFile(absolutePath, "utf-8");
124442
+ const content = stripNul(await fs8.readFile(absolutePath, "utf-8"));
124437
124443
  const contentHash = createHash5("sha256").update(content).digest("hex");
124438
124444
  let needsReparse = forceReindex;
124439
124445
  if (!forceReindex) {
@@ -128494,6 +128500,7 @@ class LoadStage {
128494
128500
  let chunksLoaded = 0;
128495
128501
  let symbolsLoaded = 0;
128496
128502
  let errors4 = 0;
128503
+ const fileErrors = [];
128497
128504
  let processedSinceStart = 0;
128498
128505
  let lastEtaLogAt = 0;
128499
128506
  const BATCH = 10;
@@ -128564,6 +128571,12 @@ class LoadStage {
128564
128571
  } catch (err) {
128565
128572
  errors4++;
128566
128573
  processedSinceStart++;
128574
+ if (fileErrors.length < MAX_FILE_ERRORS) {
128575
+ fileErrors.push({
128576
+ filePath: file2.file.relativePath,
128577
+ error: err.message
128578
+ });
128579
+ }
128567
128580
  if (emitLifecycle)
128568
128581
  ctx.emit({
128569
128582
  type: "file_error",
@@ -128629,7 +128642,7 @@ class LoadStage {
128629
128642
  duration: formatDuration(durationMs),
128630
128643
  filesPerSec: filesLoaded > 0 && durationMs > 0 ? Number((filesLoaded / durationMs * 1000).toFixed(2)) : 0
128631
128644
  });
128632
- return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors4 };
128645
+ return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors4, fileErrors };
128633
128646
  }
128634
128647
  async loadToSearchStores(ctx, file2) {
128635
128648
  if (file2.chunks.length === 0)
@@ -128701,6 +128714,7 @@ class LoadStage {
128701
128714
  return batch.definitions.length;
128702
128715
  }
128703
128716
  }
128717
+ var MAX_FILE_ERRORS = 50;
128704
128718
  var init_load = __esm(() => {
128705
128719
  init_dist();
128706
128720
  init_with_deadlock_retry();
@@ -128881,8 +128895,8 @@ class GraphGenerationRepositoryPg {
128881
128895
  async heartbeat(lease, leaseTtlMs) {
128882
128896
  const ttl = validateTtl2(leaseTtlMs);
128883
128897
  return getPrismaClient2().$transaction(async (tx) => {
128884
- const workspace = await lockWorkspace(tx, lease.projectId);
128885
128898
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
128899
+ const workspace = await lockWorkspace(tx, lease.projectId);
128886
128900
  if (!leaseMatches(workspace, generation, lease))
128887
128901
  return { status: "lease_lost" };
128888
128902
  const renewed = await tx.$queryRaw`
@@ -128905,8 +128919,8 @@ class GraphGenerationRepositoryPg {
128905
128919
  }
128906
128920
  async complete(lease) {
128907
128921
  return getPrismaClient2().$transaction(async (tx) => {
128908
- const workspace = await lockWorkspace(tx, lease.projectId);
128909
128922
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
128923
+ const workspace = await lockWorkspace(tx, lease.projectId);
128910
128924
  if (!leaseMatches(workspace, generation, lease))
128911
128925
  return { status: "lease_lost" };
128912
128926
  const live = await tx.$queryRaw`
@@ -128935,8 +128949,8 @@ class GraphGenerationRepositoryPg {
128935
128949
  }
128936
128950
  async activate(lease) {
128937
128951
  return getPrismaClient2().$transaction(async (tx) => {
128938
- const workspace = await lockWorkspace(tx, lease.projectId);
128939
128952
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
128953
+ const workspace = await lockWorkspace(tx, lease.projectId);
128940
128954
  if (!leaseMatches(workspace, generation, lease))
128941
128955
  return { status: "lease_lost" };
128942
128956
  if (workspace.active_graph_generation_id !== generation.expected_active_id) {
@@ -128986,8 +129000,8 @@ class GraphGenerationRepositoryPg {
128986
129000
  async abort(lease, reason) {
128987
129001
  const failureReason = boundedText2(reason, "reason", MAX_FAILURE_REASON);
128988
129002
  return getPrismaClient2().$transaction(async (tx) => {
128989
- const workspace = await lockWorkspace(tx, lease.projectId);
128990
129003
  const generation = await lockGeneration(tx, lease.projectId, lease.generationId);
129004
+ const workspace = await lockWorkspace(tx, lease.projectId);
128991
129005
  if (!leaseMatches(workspace, generation, lease))
128992
129006
  return { status: "lease_lost" };
128993
129007
  const live = await tx.$queryRaw`
@@ -129063,7 +129077,7 @@ class GraphGenerationCoordinator {
129063
129077
  async begin(input) {
129064
129078
  const deadline = Date.now() + GRAPH_GENERATION_LEASE_TTL_MS;
129065
129079
  for (;; ) {
129066
- const outcome2 = await this.repository.begin({ ...input, leaseTtlMs: GRAPH_GENERATION_LEASE_TTL_MS });
129080
+ const outcome2 = await withDeadlockRetry(() => this.repository.begin({ ...input, leaseTtlMs: GRAPH_GENERATION_LEASE_TTL_MS }), { operation: "graph_generation.begin", maxAttempts: 5 });
129067
129081
  if (outcome2.status === "acquired")
129068
129082
  return outcome2.lease;
129069
129083
  if (outcome2.status === "stale_active") {
@@ -129075,12 +129089,12 @@ class GraphGenerationCoordinator {
129075
129089
  }
129076
129090
  }
129077
129091
  async heartbeat(lease) {
129078
- const outcome2 = await withDeadlockRetry(() => this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS), { operation: "graph_generation.heartbeat", maxAttempts: 3 });
129092
+ const outcome2 = await withDeadlockRetry(() => this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS), { operation: "graph_generation.heartbeat", maxAttempts: 5 });
129079
129093
  if (outcome2.status !== "renewed")
129080
129094
  throw new Error("graph_generation_lease_lost");
129081
129095
  }
129082
129096
  async activate(lease) {
129083
- const completeness = await this.repository.complete(lease);
129097
+ const completeness = await withDeadlockRetry(() => this.repository.complete(lease), { operation: "graph_generation.complete", maxAttempts: 5 });
129084
129098
  if (completeness.status === "incomplete") {
129085
129099
  throw new Error(`graph_generation_incomplete:${completeness.reasons.join(",")}`);
129086
129100
  }
@@ -129089,7 +129103,7 @@ class GraphGenerationCoordinator {
129089
129103
  if (completeness.status === "stale_active") {
129090
129104
  throw new Error(`graph_generation_stale_active:${completeness.activeGenerationId ?? "none"}`);
129091
129105
  }
129092
- const activation = await this.repository.activate(lease);
129106
+ const activation = await withDeadlockRetry(() => this.repository.activate(lease), { operation: "graph_generation.activate", maxAttempts: 5 });
129093
129107
  if (activation.status === "activated")
129094
129108
  return activation;
129095
129109
  if (activation.status === "incomplete") {
@@ -129100,7 +129114,7 @@ class GraphGenerationCoordinator {
129100
129114
  throw new Error(`graph_generation_stale_active:${activation.activeGenerationId ?? "none"}`);
129101
129115
  }
129102
129116
  async abort(lease, reason) {
129103
- const outcome2 = await this.repository.abort(lease, reason);
129117
+ const outcome2 = await withDeadlockRetry(() => this.repository.abort(lease, reason), { operation: "graph_generation.abort", maxAttempts: 5 });
129104
129118
  if (outcome2.status === "lease_lost")
129105
129119
  throw new Error("graph_generation_lease_lost_during_abort");
129106
129120
  }
@@ -129443,7 +129457,12 @@ var init_pipeline = __esm(() => {
129443
129457
  throw managedRunLeaseLost;
129444
129458
  stageTimings.load = Math.round(performance.now() - st4);
129445
129459
  if (loadResult.errors > 0) {
129446
- throw new Error(`ETL completed with ${loadResult.errors} file error${loadResult.errors === 1 ? "" : "s"}`);
129460
+ logger.warn("EtlPipeline: completed with file errors", {
129461
+ projectId,
129462
+ jobId,
129463
+ errors: loadResult.errors,
129464
+ fileErrors: (loadResult.fileErrors ?? []).slice(0, 10)
129465
+ });
129447
129466
  }
129448
129467
  const activationSnapshot = await abortable(this.discover.run(ctx, { forceReindex, includeTests: include_tests }), graphAbortController.signal);
129449
129468
  if (buildGraphInputSnapshotHash(activationSnapshot) !== graphGenerationLease.inputSnapshotHash) {
@@ -129500,6 +129519,7 @@ var init_pipeline = __esm(() => {
129500
129519
  filesIndexed: result.filesIndexed,
129501
129520
  chunksIndexed: result.chunksIndexed,
129502
129521
  errors: result.errors,
129522
+ fileErrors: loadResult.fileErrors ?? [],
129503
129523
  duration: durationMs,
129504
129524
  activatedGraphGenerationId: result.activatedGraphGenerationId,
129505
129525
  parserDiagnostics: result.parserDiagnostics
@@ -129510,6 +129530,7 @@ var init_pipeline = __esm(() => {
129510
129530
  filesIndexed: result.filesIndexed,
129511
129531
  chunksIndexed: result.chunksIndexed,
129512
129532
  symbolsIndexed: result.symbolsIndexed,
129533
+ errors: result.errors,
129513
129534
  durationMs,
129514
129535
  activatedGraphGenerationId: result.activatedGraphGenerationId
129515
129536
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massa-ai/mcp-client",
3
- "version": "1.35.0",
3
+ "version": "1.36.0",
4
4
  "description": "massa-ai MCP server - Semantic code search, memory, and context compression via Model Context Protocol",
5
5
  "author": "luizgmassa",
6
6
  "type": "module",
@@ -20,8 +20,8 @@
20
20
  "type-check": "tsc --noEmit"
21
21
  },
22
22
  "dependencies": {
23
- "@massa-ai/core": "^1.35.0",
24
- "@massa-ai/shared": "^1.35.0",
23
+ "@massa-ai/core": "^1.36.0",
24
+ "@massa-ai/shared": "^1.36.0",
25
25
  "@modelcontextprotocol/sdk": "^1.0.0"
26
26
  },
27
27
  "devDependencies": {