@massa-ai/mcp-client 1.2.1 → 1.4.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.
- package/dist/config-cli.js +257 -175
- package/dist/index.js +201 -122
- package/package.json +4 -4
package/dist/config-cli.js
CHANGED
|
@@ -557,7 +557,8 @@ __export(exports_config_loader, {
|
|
|
557
557
|
getConfigPath: () => getConfigPath,
|
|
558
558
|
getConfigForEnv: () => getConfigForEnv,
|
|
559
559
|
getConfigDir: () => getConfigDir,
|
|
560
|
-
configExists: () => configExists
|
|
560
|
+
configExists: () => configExists,
|
|
561
|
+
__resetMigrationForTests: () => __resetMigrationForTests
|
|
561
562
|
});
|
|
562
563
|
import fs from "fs";
|
|
563
564
|
import path3 from "path";
|
|
@@ -627,6 +628,9 @@ function migrateDataDirOnce() {
|
|
|
627
628
|
console.error(`[massa-ai] Data directory migration skipped:`, err);
|
|
628
629
|
}
|
|
629
630
|
}
|
|
631
|
+
function __resetMigrationForTests() {
|
|
632
|
+
migrationAttempted = false;
|
|
633
|
+
}
|
|
630
634
|
function saveConfig(config) {
|
|
631
635
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
632
636
|
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
@@ -636,7 +640,7 @@ function saveConfig(config) {
|
|
|
636
640
|
function initConfig() {
|
|
637
641
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
638
642
|
saveConfig(defaultMassaAiConfig);
|
|
639
|
-
console.
|
|
643
|
+
console.error(`Created default config at ${CONFIG_FILE}`);
|
|
640
644
|
}
|
|
641
645
|
}
|
|
642
646
|
function getConfigForEnv() {
|
|
@@ -688,7 +692,7 @@ var import_dotenv, envPath;
|
|
|
688
692
|
var init_env = __esm(() => {
|
|
689
693
|
import_dotenv = __toESM(require_main(), 1);
|
|
690
694
|
envPath = findEnvFile();
|
|
691
|
-
import_dotenv.config({ path: envPath });
|
|
695
|
+
import_dotenv.config({ path: envPath, quiet: true });
|
|
692
696
|
try {
|
|
693
697
|
const { loadConfigSafe: loadConfigSafe2, migrateDataDirOnce: migrateDataDirOnce2 } = (init_config_loader(), __toCommonJS(exports_config_loader));
|
|
694
698
|
migrateDataDirOnce2();
|
|
@@ -6957,11 +6961,7 @@ class Logger {
|
|
|
6957
6961
|
return `[${timestamp}] [${level}] ${message}${metaStr}`;
|
|
6958
6962
|
}
|
|
6959
6963
|
write(message, level) {
|
|
6960
|
-
|
|
6961
|
-
console.error(message);
|
|
6962
|
-
} else {
|
|
6963
|
-
console.log(message);
|
|
6964
|
-
}
|
|
6964
|
+
console.error(message);
|
|
6965
6965
|
}
|
|
6966
6966
|
debug(message, meta) {
|
|
6967
6967
|
if (this.shouldLog(LogLevel.DEBUG)) {
|
|
@@ -7405,8 +7405,9 @@ class FileFilterCache {
|
|
|
7405
7405
|
}
|
|
7406
7406
|
invalidateProject(projectId) {
|
|
7407
7407
|
let removed = 0;
|
|
7408
|
+
const prefix = `project:${projectId}`;
|
|
7408
7409
|
for (const [key, _entry] of this.cache.entries()) {
|
|
7409
|
-
if (key.startsWith(
|
|
7410
|
+
if (key === prefix || key.startsWith(`${prefix}|`)) {
|
|
7410
7411
|
this.cache.delete(key);
|
|
7411
7412
|
removed++;
|
|
7412
7413
|
}
|
|
@@ -109741,9 +109742,9 @@ class SearchCachePg {
|
|
|
109741
109742
|
if (this.l1Cache.size <= this.L1_MAX_SIZE)
|
|
109742
109743
|
return;
|
|
109743
109744
|
let oldestKey = null;
|
|
109744
|
-
let oldestTime =
|
|
109745
|
+
let oldestTime = Infinity;
|
|
109745
109746
|
for (const [key, entry2] of this.l1Cache.entries()) {
|
|
109746
|
-
if (entry2.lastAccessed
|
|
109747
|
+
if (entry2.lastAccessed <= oldestTime) {
|
|
109747
109748
|
oldestTime = entry2.lastAccessed;
|
|
109748
109749
|
oldestKey = key;
|
|
109749
109750
|
}
|
|
@@ -110352,7 +110353,8 @@ function generationDefinitionIdentityColumns(def) {
|
|
|
110352
110353
|
}
|
|
110353
110354
|
if (parsed.kind !== def.kind)
|
|
110354
110355
|
throw new TypeError(`definition_fqn_kind_mismatch:${def.id}`);
|
|
110355
|
-
|
|
110356
|
+
const terminalMatchesName = parsed.qualifiedName === def.name || parsed.qualifiedName.endsWith(`.${def.name}`);
|
|
110357
|
+
if (!terminalMatchesName) {
|
|
110356
110358
|
throw new TypeError(`definition_fqn_name_mismatch:${def.id}`);
|
|
110357
110359
|
}
|
|
110358
110360
|
if (def.qualified_name !== undefined && def.qualified_name !== parsed.qualifiedName) {
|
|
@@ -110639,11 +110641,24 @@ async function writeFileGeneration(input) {
|
|
|
110639
110641
|
last_known_good_generation_id = EXCLUDED.last_known_good_generation_id,
|
|
110640
110642
|
last_successful_at = EXCLUDED.last_successful_at
|
|
110641
110643
|
`;
|
|
110642
|
-
|
|
110644
|
+
const seenDefinitionIds = new Set;
|
|
110645
|
+
const uniqueDefinitions = definitions.filter((definition) => {
|
|
110646
|
+
if (seenDefinitionIds.has(definition.id))
|
|
110647
|
+
return false;
|
|
110648
|
+
seenDefinitionIds.add(definition.id);
|
|
110649
|
+
return true;
|
|
110650
|
+
});
|
|
110651
|
+
for (const definition of uniqueDefinitions) {
|
|
110643
110652
|
const identity = generationDefinitionIdentityColumns(definition);
|
|
110644
110653
|
await tx.$executeRaw`
|
|
110645
110654
|
INSERT INTO symbol_definitions (id, project_id, generation_id, file_path, name, kind, line_start, line_end, exported, doc_comment, indexed_at, qualified_name, canonical_signature, signature_hash, legacy_fqn, source_span)
|
|
110646
110655
|
VALUES (${definition.id}, ${lease.projectId}, ${lease.generationId}, ${file2.relative_path}, ${definition.name}, ${definition.kind}, ${definition.line_start}, ${definition.line_end}, ${definition.exported}, ${definition.doc_comment ?? null}, ${new Date(definition.indexed_at)}, ${identity.qualifiedName}, ${identity.canonicalSignature}, ${identity.signatureHash}, ${identity.legacyFqn}, ${identity.sourceSpan}::jsonb)
|
|
110656
|
+
ON CONFLICT (project_id, generation_id, id) DO UPDATE SET
|
|
110657
|
+
name = EXCLUDED.name, kind = EXCLUDED.kind, line_start = EXCLUDED.line_start,
|
|
110658
|
+
line_end = EXCLUDED.line_end, exported = EXCLUDED.exported, doc_comment = EXCLUDED.doc_comment,
|
|
110659
|
+
indexed_at = EXCLUDED.indexed_at, qualified_name = EXCLUDED.qualified_name,
|
|
110660
|
+
canonical_signature = EXCLUDED.canonical_signature, signature_hash = EXCLUDED.signature_hash,
|
|
110661
|
+
legacy_fqn = EXCLUDED.legacy_fqn, source_span = EXCLUDED.source_span
|
|
110647
110662
|
`;
|
|
110648
110663
|
}
|
|
110649
110664
|
for (const reference of references) {
|
|
@@ -110894,7 +110909,7 @@ async function upsertWorkspace(ws) {
|
|
|
110894
110909
|
AND generation.id = 'legacy-' || md5(current_workspace.project_id)
|
|
110895
110910
|
AND generation.project_id = current_workspace.project_id
|
|
110896
110911
|
`;
|
|
110897
|
-
});
|
|
110912
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
110898
110913
|
}
|
|
110899
110914
|
async function updateWorkspaceStatus(projectId, status, opts) {
|
|
110900
110915
|
const lastError = typeof opts === "string" ? opts : opts?.lastError ?? null;
|
|
@@ -110965,7 +110980,7 @@ async function updateWorkspaceStatus(projectId, status, opts) {
|
|
|
110965
110980
|
FROM active_counts c
|
|
110966
110981
|
WHERE w.project_id = c.project_id AND EXISTS (SELECT 1 FROM updated_generation)
|
|
110967
110982
|
`;
|
|
110968
|
-
});
|
|
110983
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
110969
110984
|
}
|
|
110970
110985
|
var init_symbol_repo_workspace = __esm(() => {
|
|
110971
110986
|
init_prisma_client();
|
|
@@ -112574,7 +112589,7 @@ class MemoryRepositoryPg {
|
|
|
112574
112589
|
importance: m.importance,
|
|
112575
112590
|
tags: JSON.stringify(tagsArr),
|
|
112576
112591
|
embedding: m.embedding,
|
|
112577
|
-
metadata: m.metadata ? JSON.stringify(m.metadata)
|
|
112592
|
+
metadata: m.metadata == null ? null : typeof m.metadata === "string" ? m.metadata : JSON.stringify(m.metadata),
|
|
112578
112593
|
created_at: m.created_at instanceof Date ? m.created_at.getTime() : Number(m.created_at),
|
|
112579
112594
|
updated_at: m.updated_at instanceof Date ? m.updated_at.getTime() : Number(m.updated_at),
|
|
112580
112595
|
access_count: m.access_count,
|
|
@@ -112768,7 +112783,7 @@ class MemoryRepositoryPg {
|
|
|
112768
112783
|
pinned, deleted_at
|
|
112769
112784
|
FROM memories
|
|
112770
112785
|
WHERE deleted_at IS NULL
|
|
112771
|
-
ORDER BY created_at DESC
|
|
112786
|
+
ORDER BY created_at DESC, id DESC
|
|
112772
112787
|
LIMIT ${limit} OFFSET ${offset}
|
|
112773
112788
|
`;
|
|
112774
112789
|
return rows.map((r) => this.toMemoryRow(r));
|
|
@@ -112776,7 +112791,7 @@ class MemoryRepositoryPg {
|
|
|
112776
112791
|
async findRecentByTag(tag, opts) {
|
|
112777
112792
|
const since = new Date(opts.sinceMs);
|
|
112778
112793
|
const conditions = [
|
|
112779
|
-
import_prisma2.Prisma.sql`${tag} = ANY(tags)`,
|
|
112794
|
+
import_prisma2.Prisma.sql`${tag} = ANY(tags::text[])`,
|
|
112780
112795
|
import_prisma2.Prisma.sql`created_at >= ${since}`
|
|
112781
112796
|
];
|
|
112782
112797
|
if (opts.sessionId)
|
|
@@ -113319,7 +113334,8 @@ function restoreWorkingMemoryBuffer(snapshot) {
|
|
|
113319
113334
|
for (const e of snapshot.entries) {
|
|
113320
113335
|
if (!e || !e.result || typeof e.id !== "string")
|
|
113321
113336
|
continue;
|
|
113322
|
-
|
|
113337
|
+
const lastAccessedAt = e.lastAccessedAt ?? now2;
|
|
113338
|
+
if (now2 - lastAccessedAt >= snapshot.config.ttlMs)
|
|
113323
113339
|
continue;
|
|
113324
113340
|
const result = e.result;
|
|
113325
113341
|
buf.entries.set(e.id, {
|
|
@@ -113327,7 +113343,7 @@ function restoreWorkingMemoryBuffer(snapshot) {
|
|
|
113327
113343
|
queryTokens: new Set,
|
|
113328
113344
|
contentTokens: tokenize(result.content || ""),
|
|
113329
113345
|
addedAt: e.addedAt ?? now2,
|
|
113330
|
-
lastAccessedAt
|
|
113346
|
+
lastAccessedAt,
|
|
113331
113347
|
baselineScore: e.baselineScore ?? result.score
|
|
113332
113348
|
});
|
|
113333
113349
|
}
|
|
@@ -123720,10 +123736,10 @@ class GraphQueries {
|
|
|
123720
123736
|
return new Map;
|
|
123721
123737
|
}
|
|
123722
123738
|
const rows = await getPrismaClient2().$queryRaw`
|
|
123723
|
-
SELECT id, content, type, level, importance,
|
|
123739
|
+
SELECT id, content, type, level, importance, tags,
|
|
123724
123740
|
created_at, updated_at, access_count, user_id, session_id, project_id, agent_id,
|
|
123725
123741
|
NULL::bytea AS embedding, NULL::text AS metadata, NULL::timestamp AS last_accessed,
|
|
123726
|
-
pinned
|
|
123742
|
+
CASE WHEN pinned THEN 1 ELSE 0 END AS pinned, deleted_at
|
|
123727
123743
|
FROM memories WHERE id = ANY(${memoryIds}::text[])`;
|
|
123728
123744
|
const result = new Map;
|
|
123729
123745
|
for (const row of rows) {
|
|
@@ -128266,6 +128282,7 @@ function buildStructuralResolverDefinitions(documents) {
|
|
|
128266
128282
|
return Object.freeze(documents.flatMap((document2) => document2.structure.symbols.map((symbol27) => {
|
|
128267
128283
|
const key = `${document2.file}\x00${symbol27.qualifiedName}\x00${symbol27.kind}`;
|
|
128268
128284
|
const visibleNested = document2.dialect === "java" ? symbol27.signatureMaterial.modifiers.includes("public") && (["class", "interface", "enum"].includes(symbol27.kind) || symbol27.signatureMaterial.modifiers.includes("static")) : !symbol27.signatureMaterial.modifiers.includes("private");
|
|
128285
|
+
const isExportMarker = symbol27.kind === "export";
|
|
128269
128286
|
return Object.freeze({
|
|
128270
128287
|
identity: Object.freeze({
|
|
128271
128288
|
file: document2.file,
|
|
@@ -128278,7 +128295,7 @@ function buildStructuralResolverDefinitions(documents) {
|
|
|
128278
128295
|
typeTokens: symbol27.signatureMaterial.typeTokens,
|
|
128279
128296
|
modifiers: symbol27.signatureMaterial.modifiers,
|
|
128280
128297
|
scope: symbol27.qualifiedName === symbol27.name ? "top_level" : "nested",
|
|
128281
|
-
overload: (groups.get(key) ?? 0) > 1 ? "overloaded" : "unique"
|
|
128298
|
+
overload: (groups.get(key) ?? 0) > 1 || isExportMarker ? "overloaded" : "unique"
|
|
128282
128299
|
}),
|
|
128283
128300
|
exported: symbol27.exported || !symbol27.name.startsWith("#") && !symbol27.name.startsWith("%23") && visibleNested && exportedRoots.has(`${document2.file}\x00${symbol27.qualifiedName.split(".")[0]}`),
|
|
128284
128301
|
defaultExport: symbol27.defaultExport
|
|
@@ -128947,6 +128964,7 @@ class ResolveStage {
|
|
|
128947
128964
|
timestamp: Date.now()
|
|
128948
128965
|
});
|
|
128949
128966
|
}
|
|
128967
|
+
await new Promise((resolve6) => setTimeout(resolve6, 0));
|
|
128950
128968
|
}
|
|
128951
128969
|
const durationMs = Math.round(performance.now() - t0);
|
|
128952
128970
|
ctx.emit({
|
|
@@ -129270,6 +129288,47 @@ var init_resolve = __esm(() => {
|
|
|
129270
129288
|
STRUCTURAL_SEED_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".rb", ".php", ".lua", ".c", ".h", ".cpp", ".hpp", ".go", ".rs", ".zig", ".java", ".kt", ".kts", ".scala", ".cs", ".swift", ".dart", ".ex", ".exs", ".erl", ".clj", ".ml", ".hs", ".vue", ".md", ".json", ".yaml", ".yml"]);
|
|
129271
129289
|
});
|
|
129272
129290
|
|
|
129291
|
+
// ../../packages/core/dist/data/with-deadlock-retry.js
|
|
129292
|
+
function isRetriableTransactionError(error51) {
|
|
129293
|
+
if (!error51 || typeof error51 !== "object")
|
|
129294
|
+
return false;
|
|
129295
|
+
const code = error51.code;
|
|
129296
|
+
if (typeof code === "string" && RETRIABLE_SQLSTATES.has(code))
|
|
129297
|
+
return true;
|
|
129298
|
+
const message = error51.message;
|
|
129299
|
+
if (typeof message === "string" && /Code:\s*`(?:40P01|40001|40P02)`/.test(message)) {
|
|
129300
|
+
return true;
|
|
129301
|
+
}
|
|
129302
|
+
return false;
|
|
129303
|
+
}
|
|
129304
|
+
async function withDeadlockRetry(operation, options = {}) {
|
|
129305
|
+
const maxAttempts = options.maxAttempts ?? 5;
|
|
129306
|
+
const baseDelayMs = options.baseDelayMs ?? 75;
|
|
129307
|
+
for (let attempt = 1;attempt <= maxAttempts; attempt++) {
|
|
129308
|
+
try {
|
|
129309
|
+
return await operation();
|
|
129310
|
+
} catch (error51) {
|
|
129311
|
+
if (!isRetriableTransactionError(error51) || attempt === maxAttempts)
|
|
129312
|
+
throw error51;
|
|
129313
|
+
const delayMs = baseDelayMs * 2 ** (attempt - 1);
|
|
129314
|
+
logger.warn("Retriable DB lock cycle; retrying operation", {
|
|
129315
|
+
operation: options.operation ?? "unknown",
|
|
129316
|
+
attempt,
|
|
129317
|
+
maxAttempts,
|
|
129318
|
+
delayMs,
|
|
129319
|
+
error: error51?.message?.slice(0, 120)
|
|
129320
|
+
});
|
|
129321
|
+
await new Promise((resolve6) => setTimeout(resolve6, delayMs));
|
|
129322
|
+
}
|
|
129323
|
+
}
|
|
129324
|
+
throw new Error("withDeadlockRetry exhausted retries");
|
|
129325
|
+
}
|
|
129326
|
+
var RETRIABLE_SQLSTATES;
|
|
129327
|
+
var init_with_deadlock_retry = __esm(() => {
|
|
129328
|
+
init_dist();
|
|
129329
|
+
RETRIABLE_SQLSTATES = new Set(["40P01", "40001", "40P02"]);
|
|
129330
|
+
});
|
|
129331
|
+
|
|
129273
129332
|
// ../../packages/core/dist/services/etl/stages/load.js
|
|
129274
129333
|
import path18 from "path";
|
|
129275
129334
|
function formatDuration(ms) {
|
|
@@ -129386,8 +129445,12 @@ class LoadStage {
|
|
|
129386
129445
|
return;
|
|
129387
129446
|
try {
|
|
129388
129447
|
const [chunkCount, symCount] = await Promise.all([
|
|
129389
|
-
mode === "structural" ? Promise.resolve(0) : this.loadToSearchStores(ctx, file2),
|
|
129390
|
-
|
|
129448
|
+
mode === "structural" ? Promise.resolve(0) : withDeadlockRetry(() => this.loadToSearchStores(ctx, file2), {
|
|
129449
|
+
operation: "etl.loadToSearchStores"
|
|
129450
|
+
}),
|
|
129451
|
+
mode === "semantic" ? Promise.resolve(file2.symbols.length) : withDeadlockRetry(() => this.loadToSymbolDb(ctx, file2), {
|
|
129452
|
+
operation: "etl.loadToSymbolDb"
|
|
129453
|
+
})
|
|
129391
129454
|
]);
|
|
129392
129455
|
if (!ctx.graphGenerationLease && mode !== "structural") {
|
|
129393
129456
|
await getSymbolRepository().upsertFile({
|
|
@@ -129579,6 +129642,7 @@ class LoadStage {
|
|
|
129579
129642
|
}
|
|
129580
129643
|
var init_load = __esm(() => {
|
|
129581
129644
|
init_dist();
|
|
129645
|
+
init_with_deadlock_retry();
|
|
129582
129646
|
init_vector_store_factory();
|
|
129583
129647
|
init_keyword_search_factory();
|
|
129584
129648
|
init_symbol_repository_factory();
|
|
@@ -129776,7 +129840,7 @@ class GraphGenerationRepositoryPg {
|
|
|
129776
129840
|
AND graph_lease_token = ${lease.leaseToken}
|
|
129777
129841
|
`;
|
|
129778
129842
|
return { status: "renewed", leaseExpiresAt: renewed[0].lease_expires_at.getTime() };
|
|
129779
|
-
});
|
|
129843
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
129780
129844
|
}
|
|
129781
129845
|
async complete(lease) {
|
|
129782
129846
|
return getPrismaClient2().$transaction(async (tx) => {
|
|
@@ -129950,7 +130014,7 @@ class GraphGenerationCoordinator {
|
|
|
129950
130014
|
} while (true);
|
|
129951
130015
|
}
|
|
129952
130016
|
async heartbeat(lease) {
|
|
129953
|
-
const outcome2 = await this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS);
|
|
130017
|
+
const outcome2 = await withDeadlockRetry(() => this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS), { operation: "graph_generation.heartbeat", maxAttempts: 3 });
|
|
129954
130018
|
if (outcome2.status !== "renewed")
|
|
129955
130019
|
throw new Error("graph_generation_lease_lost");
|
|
129956
130020
|
}
|
|
@@ -129986,6 +130050,7 @@ class GraphGenerationCoordinator {
|
|
|
129986
130050
|
var GRAPH_GENERATION_LEASE_TTL_MS = 300000;
|
|
129987
130051
|
var init_graph_generation_coordinator = __esm(() => {
|
|
129988
130052
|
init_graph_generation_repository_factory();
|
|
130053
|
+
init_with_deadlock_retry();
|
|
129989
130054
|
});
|
|
129990
130055
|
|
|
129991
130056
|
// ../../packages/core/dist/services/etl/pipeline.js
|
|
@@ -130063,6 +130128,7 @@ var init_pipeline = __esm(() => {
|
|
|
130063
130128
|
init_symbol_repository_factory();
|
|
130064
130129
|
init_index_job_tracker();
|
|
130065
130130
|
init_cache_factory();
|
|
130131
|
+
init_index_manager();
|
|
130066
130132
|
init_vector_store_factory();
|
|
130067
130133
|
init_keyword_search_factory();
|
|
130068
130134
|
init_alias_resolver();
|
|
@@ -130354,6 +130420,16 @@ var init_pipeline = __esm(() => {
|
|
|
130354
130420
|
}
|
|
130355
130421
|
};
|
|
130356
130422
|
await getSearchCache().invalidateProject(projectId);
|
|
130423
|
+
try {
|
|
130424
|
+
const admissionMarker = new IndexManager(await getVectorStore());
|
|
130425
|
+
await admissionMarker.updateIndexMetadata(projectId, projectPath, discovered.map((file2) => file2.relativePath));
|
|
130426
|
+
} catch (markerError) {
|
|
130427
|
+
logger.warn("EtlPipeline: search-admission marker write failed", {
|
|
130428
|
+
projectId,
|
|
130429
|
+
jobId,
|
|
130430
|
+
error: markerError.message.slice(0, 160)
|
|
130431
|
+
});
|
|
130432
|
+
}
|
|
130357
130433
|
indexJobTracker.updateProgress(jobId, result.filesIndexed, result.filesIndexed);
|
|
130358
130434
|
await indexJobTracker.setResultAndFlush(jobId, {
|
|
130359
130435
|
filesIndexed: result.filesIndexed,
|
|
@@ -131694,16 +131770,14 @@ var TOOL_NAME_NORMALIZE, classifyToolCall = (_source, payload) => {
|
|
|
131694
131770
|
const cmdRaw = field2(payload, "command") ?? (toolInput && typeof toolInput === "object" ? toolInput.command : undefined);
|
|
131695
131771
|
const cmd = lower(cmdRaw);
|
|
131696
131772
|
if (cmd.startsWith("git ") || cmd.includes(" git ")) {
|
|
131697
|
-
if (cmd.includes("commit") || cmd.includes("merge") || cmd.includes("rebase")) {
|
|
131698
|
-
return "git-changes";
|
|
131699
|
-
}
|
|
131700
131773
|
return "git-changes";
|
|
131701
131774
|
}
|
|
131702
131775
|
return "tool-calls";
|
|
131703
131776
|
}
|
|
131704
131777
|
case "TodoWrite":
|
|
131705
|
-
case "Task":
|
|
131706
131778
|
return "tasks";
|
|
131779
|
+
case "Task":
|
|
131780
|
+
return "subagents-spawned";
|
|
131707
131781
|
case "WebFetch":
|
|
131708
131782
|
return "web-fetch";
|
|
131709
131783
|
case "WebSearch":
|
|
@@ -131720,8 +131794,6 @@ var TOOL_NAME_NORMALIZE, classifyToolCall = (_source, payload) => {
|
|
|
131720
131794
|
return "memories-stored";
|
|
131721
131795
|
case "compact_snapshot":
|
|
131722
131796
|
return "compaction-snapshots";
|
|
131723
|
-
case "Task":
|
|
131724
|
-
return "subagents-spawned";
|
|
131725
131797
|
default:
|
|
131726
131798
|
if (toolName.startsWith("mcp__"))
|
|
131727
131799
|
return "mcp-calls";
|
|
@@ -150348,8 +150420,6 @@ var init_recover_project = __esm(() => {
|
|
|
150348
150420
|
|
|
150349
150421
|
// src/config-cli.ts
|
|
150350
150422
|
init_config();
|
|
150351
|
-
var args = process.argv.slice(2);
|
|
150352
|
-
var command = args[0];
|
|
150353
150423
|
function help() {
|
|
150354
150424
|
console.log(`
|
|
150355
150425
|
massa-ai-config - Configuration manager for massa-ai
|
|
@@ -150384,13 +150454,13 @@ Examples:
|
|
|
150384
150454
|
massa-ai-config recover my-project --path /home/user/renamed-dir
|
|
150385
150455
|
`);
|
|
150386
150456
|
}
|
|
150387
|
-
function parseOptions(
|
|
150457
|
+
function parseOptions(args) {
|
|
150388
150458
|
const options = {};
|
|
150389
|
-
for (let i = 0;i <
|
|
150390
|
-
if (
|
|
150391
|
-
const key =
|
|
150392
|
-
if (i + 1 <
|
|
150393
|
-
options[key] =
|
|
150459
|
+
for (let i = 0;i < args.length; i++) {
|
|
150460
|
+
if (args[i].startsWith("--")) {
|
|
150461
|
+
const key = args[i].slice(2);
|
|
150462
|
+
if (i + 1 < args.length && !args[i + 1].startsWith("--")) {
|
|
150463
|
+
options[key] = args[i + 1];
|
|
150394
150464
|
i++;
|
|
150395
150465
|
} else {
|
|
150396
150466
|
options[key] = true;
|
|
@@ -150399,147 +150469,159 @@ function parseOptions(args2) {
|
|
|
150399
150469
|
}
|
|
150400
150470
|
return options;
|
|
150401
150471
|
}
|
|
150402
|
-
|
|
150403
|
-
|
|
150404
|
-
|
|
150405
|
-
|
|
150406
|
-
|
|
150407
|
-
|
|
150408
|
-
case "init": {
|
|
150409
|
-
initConfig();
|
|
150410
|
-
if (options.mistral && typeof options.mistral === "string") {
|
|
150411
|
-
const config3 = loadConfig();
|
|
150412
|
-
config3.embedding = {
|
|
150413
|
-
provider: "mistral",
|
|
150414
|
-
model: "mistral-embed",
|
|
150415
|
-
apiKey: options.mistral,
|
|
150416
|
-
dimensions: 1024
|
|
150417
|
-
};
|
|
150418
|
-
saveConfig(config3);
|
|
150419
|
-
console.log("\u2713 Configured for Mistral embeddings");
|
|
150420
|
-
} else if (options.openai && typeof options.openai === "string") {
|
|
150421
|
-
const config3 = loadConfig();
|
|
150422
|
-
config3.embedding = {
|
|
150423
|
-
provider: "openai",
|
|
150424
|
-
model: "text-embedding-3-small",
|
|
150425
|
-
apiKey: options.openai,
|
|
150426
|
-
dimensions: 1536
|
|
150427
|
-
};
|
|
150428
|
-
saveConfig(config3);
|
|
150429
|
-
console.log("\u2713 Configured for OpenAI embeddings");
|
|
150430
|
-
} else {
|
|
150431
|
-
console.log("\u2713 Configured for Ollama (local) embeddings");
|
|
150432
|
-
}
|
|
150433
|
-
console.log(`
|
|
150434
|
-
Config file: ${getConfigPath()}`);
|
|
150435
|
-
break;
|
|
150436
|
-
}
|
|
150437
|
-
case "path": {
|
|
150438
|
-
console.log(getConfigPath());
|
|
150439
|
-
break;
|
|
150472
|
+
async function runCli(argv) {
|
|
150473
|
+
const args = argv;
|
|
150474
|
+
const command = args[0];
|
|
150475
|
+
if (!command || command === "--help" || command === "-h") {
|
|
150476
|
+
help();
|
|
150477
|
+
return 0;
|
|
150440
150478
|
}
|
|
150441
|
-
|
|
150442
|
-
|
|
150443
|
-
|
|
150479
|
+
const options = parseOptions(args.slice(1));
|
|
150480
|
+
switch (command) {
|
|
150481
|
+
case "init": {
|
|
150482
|
+
initConfig();
|
|
150483
|
+
if (options.mistral && typeof options.mistral === "string") {
|
|
150484
|
+
const config3 = loadConfig();
|
|
150485
|
+
config3.embedding = {
|
|
150486
|
+
provider: "mistral",
|
|
150487
|
+
model: "mistral-embed",
|
|
150488
|
+
apiKey: options.mistral,
|
|
150489
|
+
dimensions: 1024
|
|
150490
|
+
};
|
|
150491
|
+
saveConfig(config3);
|
|
150492
|
+
console.log("\u2713 Configured for Mistral embeddings");
|
|
150493
|
+
} else if (options.openai && typeof options.openai === "string") {
|
|
150494
|
+
const config3 = loadConfig();
|
|
150495
|
+
config3.embedding = {
|
|
150496
|
+
provider: "openai",
|
|
150497
|
+
model: "text-embedding-3-small",
|
|
150498
|
+
apiKey: options.openai,
|
|
150499
|
+
dimensions: 1536
|
|
150500
|
+
};
|
|
150501
|
+
saveConfig(config3);
|
|
150502
|
+
console.log("\u2713 Configured for OpenAI embeddings");
|
|
150503
|
+
} else {
|
|
150504
|
+
console.log("\u2713 Configured for Ollama (local) embeddings");
|
|
150505
|
+
}
|
|
150444
150506
|
console.log(`
|
|
150507
|
+
Config file: ${getConfigPath()}`);
|
|
150508
|
+
break;
|
|
150509
|
+
}
|
|
150510
|
+
case "path": {
|
|
150511
|
+
console.log(getConfigPath());
|
|
150512
|
+
break;
|
|
150513
|
+
}
|
|
150514
|
+
case "show": {
|
|
150515
|
+
if (!configExists()) {
|
|
150516
|
+
console.log("No config file found. Run `massa-ai-config init` to create one.");
|
|
150517
|
+
console.log(`
|
|
150445
150518
|
Using defaults:`);
|
|
150446
|
-
|
|
150447
|
-
|
|
150448
|
-
}
|
|
150449
|
-
const config3 = loadConfig();
|
|
150450
|
-
console.log(JSON.stringify(config3, null, 2));
|
|
150451
|
-
break;
|
|
150452
|
-
}
|
|
150453
|
-
case "set": {
|
|
150454
|
-
const key = args[1];
|
|
150455
|
-
const value = args[2];
|
|
150456
|
-
if (!key || !value) {
|
|
150457
|
-
console.error("Usage: massa-ai-config set <key> <value>");
|
|
150458
|
-
process.exit(1);
|
|
150459
|
-
}
|
|
150460
|
-
const config3 = loadConfig();
|
|
150461
|
-
const keys = key.split(".");
|
|
150462
|
-
let obj = config3;
|
|
150463
|
-
for (let i = 0;i < keys.length - 1; i++) {
|
|
150464
|
-
obj = obj[keys[i]];
|
|
150465
|
-
}
|
|
150466
|
-
const parsedValue = isNaN(Number(value)) ? value : Number(value);
|
|
150467
|
-
obj[keys[keys.length - 1]] = parsedValue;
|
|
150468
|
-
saveConfig(config3);
|
|
150469
|
-
console.log(`\u2713 Set ${key} = ${value}`);
|
|
150470
|
-
break;
|
|
150471
|
-
}
|
|
150472
|
-
case "use": {
|
|
150473
|
-
const provider = args[1];
|
|
150474
|
-
if (!provider || !["ollama", "mistral", "openai"].includes(provider)) {
|
|
150475
|
-
console.error("Provider must be: ollama, mistral, or openai");
|
|
150476
|
-
process.exit(1);
|
|
150477
|
-
}
|
|
150478
|
-
const config3 = loadConfig();
|
|
150479
|
-
if (provider === "ollama") {
|
|
150480
|
-
config3.embedding = {
|
|
150481
|
-
provider: "ollama",
|
|
150482
|
-
model: options.model || "qwen3-embedding:8b",
|
|
150483
|
-
baseURL: options["base-url"] || "http://localhost:11434",
|
|
150484
|
-
dimensions: 768
|
|
150485
|
-
};
|
|
150486
|
-
} else if (provider === "mistral") {
|
|
150487
|
-
if (!options["api-key"]) {
|
|
150488
|
-
console.error("Error: --api-key required for Mistral");
|
|
150489
|
-
process.exit(1);
|
|
150490
|
-
}
|
|
150491
|
-
config3.embedding = {
|
|
150492
|
-
provider: "mistral",
|
|
150493
|
-
model: options.model || "mistral-embed",
|
|
150494
|
-
apiKey: options["api-key"],
|
|
150495
|
-
dimensions: 1024
|
|
150496
|
-
};
|
|
150497
|
-
} else if (provider === "openai") {
|
|
150498
|
-
if (!options["api-key"]) {
|
|
150499
|
-
console.error("Error: --api-key required for OpenAI");
|
|
150500
|
-
process.exit(1);
|
|
150519
|
+
console.log(JSON.stringify(defaultMassaAiConfig, null, 2));
|
|
150520
|
+
return 0;
|
|
150501
150521
|
}
|
|
150502
|
-
config3
|
|
150503
|
-
|
|
150504
|
-
|
|
150505
|
-
apiKey: options["api-key"],
|
|
150506
|
-
dimensions: 1536
|
|
150507
|
-
};
|
|
150522
|
+
const config3 = loadConfig();
|
|
150523
|
+
console.log(JSON.stringify(config3, null, 2));
|
|
150524
|
+
break;
|
|
150508
150525
|
}
|
|
150509
|
-
|
|
150510
|
-
|
|
150511
|
-
|
|
150512
|
-
|
|
150513
|
-
|
|
150514
|
-
|
|
150515
|
-
|
|
150516
|
-
|
|
150517
|
-
|
|
150518
|
-
|
|
150519
|
-
|
|
150526
|
+
case "set": {
|
|
150527
|
+
const key = args[1];
|
|
150528
|
+
const value = args[2];
|
|
150529
|
+
if (!key || !value) {
|
|
150530
|
+
console.error("Usage: massa-ai-config set <key> <value>");
|
|
150531
|
+
return 1;
|
|
150532
|
+
}
|
|
150533
|
+
const config3 = loadConfig();
|
|
150534
|
+
const keys = key.split(".");
|
|
150535
|
+
let obj = config3;
|
|
150536
|
+
for (let i = 0;i < keys.length - 1; i++) {
|
|
150537
|
+
obj = obj[keys[i]];
|
|
150538
|
+
}
|
|
150539
|
+
const parsedValue = isNaN(Number(value)) ? value : Number(value);
|
|
150540
|
+
obj[keys[keys.length - 1]] = parsedValue;
|
|
150541
|
+
saveConfig(config3);
|
|
150542
|
+
console.log(`\u2713 Set ${key} = ${value}`);
|
|
150543
|
+
break;
|
|
150520
150544
|
}
|
|
150521
|
-
|
|
150522
|
-
|
|
150523
|
-
|
|
150545
|
+
case "use": {
|
|
150546
|
+
const provider = args[1];
|
|
150547
|
+
if (!provider || !["ollama", "mistral", "openai"].includes(provider)) {
|
|
150548
|
+
console.error("Provider must be: ollama, mistral, or openai");
|
|
150549
|
+
return 1;
|
|
150550
|
+
}
|
|
150551
|
+
const config3 = loadConfig();
|
|
150552
|
+
if (provider === "ollama") {
|
|
150553
|
+
config3.embedding = {
|
|
150554
|
+
provider: "ollama",
|
|
150555
|
+
model: options.model || "qwen3-embedding:8b",
|
|
150556
|
+
baseURL: options["base-url"] || "http://localhost:11434",
|
|
150557
|
+
dimensions: 768
|
|
150558
|
+
};
|
|
150559
|
+
} else if (provider === "mistral") {
|
|
150560
|
+
if (!options["api-key"]) {
|
|
150561
|
+
console.error("Error: --api-key required for Mistral");
|
|
150562
|
+
return 1;
|
|
150563
|
+
}
|
|
150564
|
+
config3.embedding = {
|
|
150565
|
+
provider: "mistral",
|
|
150566
|
+
model: options.model || "mistral-embed",
|
|
150567
|
+
apiKey: options["api-key"],
|
|
150568
|
+
dimensions: 1024
|
|
150569
|
+
};
|
|
150570
|
+
} else if (provider === "openai") {
|
|
150571
|
+
if (!options["api-key"]) {
|
|
150572
|
+
console.error("Error: --api-key required for OpenAI");
|
|
150573
|
+
return 1;
|
|
150574
|
+
}
|
|
150575
|
+
config3.embedding = {
|
|
150576
|
+
provider: "openai",
|
|
150577
|
+
model: options.model || "text-embedding-3-small",
|
|
150578
|
+
apiKey: options["api-key"],
|
|
150579
|
+
dimensions: 1536
|
|
150580
|
+
};
|
|
150581
|
+
}
|
|
150582
|
+
saveConfig(config3);
|
|
150583
|
+
console.log(`\u2713 Switched to ${provider} embeddings`);
|
|
150584
|
+
console.log(` Model: ${config3.embedding.model}`);
|
|
150585
|
+
break;
|
|
150524
150586
|
}
|
|
150525
|
-
|
|
150526
|
-
const
|
|
150527
|
-
const
|
|
150528
|
-
if (!
|
|
150529
|
-
console.error(
|
|
150530
|
-
|
|
150531
|
-
}
|
|
150532
|
-
|
|
150533
|
-
|
|
150534
|
-
|
|
150535
|
-
|
|
150536
|
-
|
|
150537
|
-
|
|
150587
|
+
case "recover": {
|
|
150588
|
+
const projectId = args[1];
|
|
150589
|
+
const newPath = options.path;
|
|
150590
|
+
if (!projectId) {
|
|
150591
|
+
console.error("Error: projectId required. Usage: massa-ai-config recover <projectId> --path <newPath>");
|
|
150592
|
+
return 1;
|
|
150593
|
+
}
|
|
150594
|
+
if (!newPath || typeof newPath !== "string") {
|
|
150595
|
+
console.error("Error: --path required. Usage: massa-ai-config recover <projectId> --path <newPath>");
|
|
150596
|
+
return 1;
|
|
150597
|
+
}
|
|
150598
|
+
try {
|
|
150599
|
+
const { recoverProjectPath: recoverProjectPath2 } = await Promise.resolve().then(() => (init_recover_project(), exports_recover_project));
|
|
150600
|
+
const result = await recoverProjectPath2(projectId, newPath);
|
|
150601
|
+
if (!result.found) {
|
|
150602
|
+
console.error(`Error: project "${projectId}" not found. Cannot recover \u2014 the project must be indexed first.`);
|
|
150603
|
+
return 1;
|
|
150604
|
+
}
|
|
150605
|
+
console.log(`\u2713 Recovered project "${projectId}" \u2014 path updated to ${newPath}`);
|
|
150606
|
+
console.log(` Previous path: ${result.oldPath ?? "(none)"}`);
|
|
150607
|
+
} catch (e) {
|
|
150608
|
+
const err = e;
|
|
150609
|
+
console.error(`Error: recovery failed \u2014 ${err.message}`);
|
|
150610
|
+
return 1;
|
|
150611
|
+
}
|
|
150612
|
+
break;
|
|
150538
150613
|
}
|
|
150539
|
-
|
|
150614
|
+
default:
|
|
150615
|
+
console.error(`Unknown command: ${command}`);
|
|
150616
|
+
help();
|
|
150617
|
+
return 1;
|
|
150540
150618
|
}
|
|
150541
|
-
|
|
150542
|
-
|
|
150543
|
-
|
|
150544
|
-
|
|
150619
|
+
return 0;
|
|
150620
|
+
}
|
|
150621
|
+
if (import.meta.main) {
|
|
150622
|
+
runCli(process.argv.slice(2)).then((code) => process.exit(code));
|
|
150545
150623
|
}
|
|
150624
|
+
export {
|
|
150625
|
+
runCli,
|
|
150626
|
+
parseOptions
|
|
150627
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -25554,7 +25554,8 @@ __export(exports_config_loader, {
|
|
|
25554
25554
|
getConfigPath: () => getConfigPath,
|
|
25555
25555
|
getConfigForEnv: () => getConfigForEnv,
|
|
25556
25556
|
getConfigDir: () => getConfigDir,
|
|
25557
|
-
configExists: () => configExists
|
|
25557
|
+
configExists: () => configExists,
|
|
25558
|
+
__resetMigrationForTests: () => __resetMigrationForTests
|
|
25558
25559
|
});
|
|
25559
25560
|
import fs from "fs";
|
|
25560
25561
|
import path3 from "path";
|
|
@@ -25624,6 +25625,9 @@ function migrateDataDirOnce() {
|
|
|
25624
25625
|
console.error(`[massa-ai] Data directory migration skipped:`, err);
|
|
25625
25626
|
}
|
|
25626
25627
|
}
|
|
25628
|
+
function __resetMigrationForTests() {
|
|
25629
|
+
migrationAttempted = false;
|
|
25630
|
+
}
|
|
25627
25631
|
function saveConfig(config2) {
|
|
25628
25632
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
25629
25633
|
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
@@ -25633,7 +25637,7 @@ function saveConfig(config2) {
|
|
|
25633
25637
|
function initConfig() {
|
|
25634
25638
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
25635
25639
|
saveConfig(defaultMassaAiConfig);
|
|
25636
|
-
console.
|
|
25640
|
+
console.error(`Created default config at ${CONFIG_FILE}`);
|
|
25637
25641
|
}
|
|
25638
25642
|
}
|
|
25639
25643
|
function getConfigForEnv() {
|
|
@@ -25685,7 +25689,7 @@ var import_dotenv, envPath;
|
|
|
25685
25689
|
var init_env = __esm(() => {
|
|
25686
25690
|
import_dotenv = __toESM(require_main(), 1);
|
|
25687
25691
|
envPath = findEnvFile();
|
|
25688
|
-
import_dotenv.config({ path: envPath });
|
|
25692
|
+
import_dotenv.config({ path: envPath, quiet: true });
|
|
25689
25693
|
try {
|
|
25690
25694
|
const { loadConfigSafe: loadConfigSafe2, migrateDataDirOnce: migrateDataDirOnce2 } = (init_config_loader(), __toCommonJS(exports_config_loader));
|
|
25691
25695
|
migrateDataDirOnce2();
|
|
@@ -31954,11 +31958,7 @@ class Logger {
|
|
|
31954
31958
|
return `[${timestamp}] [${level}] ${message}${metaStr}`;
|
|
31955
31959
|
}
|
|
31956
31960
|
write(message, level) {
|
|
31957
|
-
|
|
31958
|
-
console.error(message);
|
|
31959
|
-
} else {
|
|
31960
|
-
console.log(message);
|
|
31961
|
-
}
|
|
31961
|
+
console.error(message);
|
|
31962
31962
|
}
|
|
31963
31963
|
debug(message, meta3) {
|
|
31964
31964
|
if (this.shouldLog(LogLevel.DEBUG)) {
|
|
@@ -32402,8 +32402,9 @@ class FileFilterCache {
|
|
|
32402
32402
|
}
|
|
32403
32403
|
invalidateProject(projectId) {
|
|
32404
32404
|
let removed = 0;
|
|
32405
|
+
const prefix = `project:${projectId}`;
|
|
32405
32406
|
for (const [key, _entry] of this.cache.entries()) {
|
|
32406
|
-
if (key.startsWith(
|
|
32407
|
+
if (key === prefix || key.startsWith(`${prefix}|`)) {
|
|
32407
32408
|
this.cache.delete(key);
|
|
32408
32409
|
removed++;
|
|
32409
32410
|
}
|
|
@@ -116300,9 +116301,9 @@ class SearchCachePg {
|
|
|
116300
116301
|
if (this.l1Cache.size <= this.L1_MAX_SIZE)
|
|
116301
116302
|
return;
|
|
116302
116303
|
let oldestKey = null;
|
|
116303
|
-
let oldestTime =
|
|
116304
|
+
let oldestTime = Infinity;
|
|
116304
116305
|
for (const [key, entry2] of this.l1Cache.entries()) {
|
|
116305
|
-
if (entry2.lastAccessed
|
|
116306
|
+
if (entry2.lastAccessed <= oldestTime) {
|
|
116306
116307
|
oldestTime = entry2.lastAccessed;
|
|
116307
116308
|
oldestKey = key;
|
|
116308
116309
|
}
|
|
@@ -116911,7 +116912,8 @@ function generationDefinitionIdentityColumns(def) {
|
|
|
116911
116912
|
}
|
|
116912
116913
|
if (parsed.kind !== def.kind)
|
|
116913
116914
|
throw new TypeError(`definition_fqn_kind_mismatch:${def.id}`);
|
|
116914
|
-
|
|
116915
|
+
const terminalMatchesName = parsed.qualifiedName === def.name || parsed.qualifiedName.endsWith(`.${def.name}`);
|
|
116916
|
+
if (!terminalMatchesName) {
|
|
116915
116917
|
throw new TypeError(`definition_fqn_name_mismatch:${def.id}`);
|
|
116916
116918
|
}
|
|
116917
116919
|
if (def.qualified_name !== undefined && def.qualified_name !== parsed.qualifiedName) {
|
|
@@ -117198,11 +117200,24 @@ async function writeFileGeneration(input) {
|
|
|
117198
117200
|
last_known_good_generation_id = EXCLUDED.last_known_good_generation_id,
|
|
117199
117201
|
last_successful_at = EXCLUDED.last_successful_at
|
|
117200
117202
|
`;
|
|
117201
|
-
|
|
117203
|
+
const seenDefinitionIds = new Set;
|
|
117204
|
+
const uniqueDefinitions = definitions.filter((definition) => {
|
|
117205
|
+
if (seenDefinitionIds.has(definition.id))
|
|
117206
|
+
return false;
|
|
117207
|
+
seenDefinitionIds.add(definition.id);
|
|
117208
|
+
return true;
|
|
117209
|
+
});
|
|
117210
|
+
for (const definition of uniqueDefinitions) {
|
|
117202
117211
|
const identity = generationDefinitionIdentityColumns(definition);
|
|
117203
117212
|
await tx.$executeRaw`
|
|
117204
117213
|
INSERT INTO symbol_definitions (id, project_id, generation_id, file_path, name, kind, line_start, line_end, exported, doc_comment, indexed_at, qualified_name, canonical_signature, signature_hash, legacy_fqn, source_span)
|
|
117205
117214
|
VALUES (${definition.id}, ${lease.projectId}, ${lease.generationId}, ${file2.relative_path}, ${definition.name}, ${definition.kind}, ${definition.line_start}, ${definition.line_end}, ${definition.exported}, ${definition.doc_comment ?? null}, ${new Date(definition.indexed_at)}, ${identity.qualifiedName}, ${identity.canonicalSignature}, ${identity.signatureHash}, ${identity.legacyFqn}, ${identity.sourceSpan}::jsonb)
|
|
117215
|
+
ON CONFLICT (project_id, generation_id, id) DO UPDATE SET
|
|
117216
|
+
name = EXCLUDED.name, kind = EXCLUDED.kind, line_start = EXCLUDED.line_start,
|
|
117217
|
+
line_end = EXCLUDED.line_end, exported = EXCLUDED.exported, doc_comment = EXCLUDED.doc_comment,
|
|
117218
|
+
indexed_at = EXCLUDED.indexed_at, qualified_name = EXCLUDED.qualified_name,
|
|
117219
|
+
canonical_signature = EXCLUDED.canonical_signature, signature_hash = EXCLUDED.signature_hash,
|
|
117220
|
+
legacy_fqn = EXCLUDED.legacy_fqn, source_span = EXCLUDED.source_span
|
|
117206
117221
|
`;
|
|
117207
117222
|
}
|
|
117208
117223
|
for (const reference of references) {
|
|
@@ -117453,7 +117468,7 @@ async function upsertWorkspace(ws) {
|
|
|
117453
117468
|
AND generation.id = 'legacy-' || md5(current_workspace.project_id)
|
|
117454
117469
|
AND generation.project_id = current_workspace.project_id
|
|
117455
117470
|
`;
|
|
117456
|
-
});
|
|
117471
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
117457
117472
|
}
|
|
117458
117473
|
async function updateWorkspaceStatus(projectId, status, opts) {
|
|
117459
117474
|
const lastError = typeof opts === "string" ? opts : opts?.lastError ?? null;
|
|
@@ -117524,7 +117539,7 @@ async function updateWorkspaceStatus(projectId, status, opts) {
|
|
|
117524
117539
|
FROM active_counts c
|
|
117525
117540
|
WHERE w.project_id = c.project_id AND EXISTS (SELECT 1 FROM updated_generation)
|
|
117526
117541
|
`;
|
|
117527
|
-
});
|
|
117542
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
117528
117543
|
}
|
|
117529
117544
|
var init_symbol_repo_workspace = __esm(() => {
|
|
117530
117545
|
init_prisma_client();
|
|
@@ -119133,7 +119148,7 @@ class MemoryRepositoryPg {
|
|
|
119133
119148
|
importance: m.importance,
|
|
119134
119149
|
tags: JSON.stringify(tagsArr),
|
|
119135
119150
|
embedding: m.embedding,
|
|
119136
|
-
metadata: m.metadata ? JSON.stringify(m.metadata)
|
|
119151
|
+
metadata: m.metadata == null ? null : typeof m.metadata === "string" ? m.metadata : JSON.stringify(m.metadata),
|
|
119137
119152
|
created_at: m.created_at instanceof Date ? m.created_at.getTime() : Number(m.created_at),
|
|
119138
119153
|
updated_at: m.updated_at instanceof Date ? m.updated_at.getTime() : Number(m.updated_at),
|
|
119139
119154
|
access_count: m.access_count,
|
|
@@ -119327,7 +119342,7 @@ class MemoryRepositoryPg {
|
|
|
119327
119342
|
pinned, deleted_at
|
|
119328
119343
|
FROM memories
|
|
119329
119344
|
WHERE deleted_at IS NULL
|
|
119330
|
-
ORDER BY created_at DESC
|
|
119345
|
+
ORDER BY created_at DESC, id DESC
|
|
119331
119346
|
LIMIT ${limit} OFFSET ${offset}
|
|
119332
119347
|
`;
|
|
119333
119348
|
return rows.map((r) => this.toMemoryRow(r));
|
|
@@ -119335,7 +119350,7 @@ class MemoryRepositoryPg {
|
|
|
119335
119350
|
async findRecentByTag(tag, opts) {
|
|
119336
119351
|
const since = new Date(opts.sinceMs);
|
|
119337
119352
|
const conditions = [
|
|
119338
|
-
import_prisma2.Prisma.sql`${tag} = ANY(tags)`,
|
|
119353
|
+
import_prisma2.Prisma.sql`${tag} = ANY(tags::text[])`,
|
|
119339
119354
|
import_prisma2.Prisma.sql`created_at >= ${since}`
|
|
119340
119355
|
];
|
|
119341
119356
|
if (opts.sessionId)
|
|
@@ -119878,7 +119893,8 @@ function restoreWorkingMemoryBuffer(snapshot) {
|
|
|
119878
119893
|
for (const e of snapshot.entries) {
|
|
119879
119894
|
if (!e || !e.result || typeof e.id !== "string")
|
|
119880
119895
|
continue;
|
|
119881
|
-
|
|
119896
|
+
const lastAccessedAt = e.lastAccessedAt ?? now2;
|
|
119897
|
+
if (now2 - lastAccessedAt >= snapshot.config.ttlMs)
|
|
119882
119898
|
continue;
|
|
119883
119899
|
const result = e.result;
|
|
119884
119900
|
buf.entries.set(e.id, {
|
|
@@ -119886,7 +119902,7 @@ function restoreWorkingMemoryBuffer(snapshot) {
|
|
|
119886
119902
|
queryTokens: new Set,
|
|
119887
119903
|
contentTokens: tokenize(result.content || ""),
|
|
119888
119904
|
addedAt: e.addedAt ?? now2,
|
|
119889
|
-
lastAccessedAt
|
|
119905
|
+
lastAccessedAt,
|
|
119890
119906
|
baselineScore: e.baselineScore ?? result.score
|
|
119891
119907
|
});
|
|
119892
119908
|
}
|
|
@@ -126449,6 +126465,7 @@ function buildStructuralResolverDefinitions(documents) {
|
|
|
126449
126465
|
return Object.freeze(documents.flatMap((document2) => document2.structure.symbols.map((symbol27) => {
|
|
126450
126466
|
const key = `${document2.file}\x00${symbol27.qualifiedName}\x00${symbol27.kind}`;
|
|
126451
126467
|
const visibleNested = document2.dialect === "java" ? symbol27.signatureMaterial.modifiers.includes("public") && (["class", "interface", "enum"].includes(symbol27.kind) || symbol27.signatureMaterial.modifiers.includes("static")) : !symbol27.signatureMaterial.modifiers.includes("private");
|
|
126468
|
+
const isExportMarker = symbol27.kind === "export";
|
|
126452
126469
|
return Object.freeze({
|
|
126453
126470
|
identity: Object.freeze({
|
|
126454
126471
|
file: document2.file,
|
|
@@ -126461,7 +126478,7 @@ function buildStructuralResolverDefinitions(documents) {
|
|
|
126461
126478
|
typeTokens: symbol27.signatureMaterial.typeTokens,
|
|
126462
126479
|
modifiers: symbol27.signatureMaterial.modifiers,
|
|
126463
126480
|
scope: symbol27.qualifiedName === symbol27.name ? "top_level" : "nested",
|
|
126464
|
-
overload: (groups.get(key) ?? 0) > 1 ? "overloaded" : "unique"
|
|
126481
|
+
overload: (groups.get(key) ?? 0) > 1 || isExportMarker ? "overloaded" : "unique"
|
|
126465
126482
|
}),
|
|
126466
126483
|
exported: symbol27.exported || !symbol27.name.startsWith("#") && !symbol27.name.startsWith("%23") && visibleNested && exportedRoots.has(`${document2.file}\x00${symbol27.qualifiedName.split(".")[0]}`),
|
|
126467
126484
|
defaultExport: symbol27.defaultExport
|
|
@@ -127130,6 +127147,7 @@ class ResolveStage {
|
|
|
127130
127147
|
timestamp: Date.now()
|
|
127131
127148
|
});
|
|
127132
127149
|
}
|
|
127150
|
+
await new Promise((resolve5) => setTimeout(resolve5, 0));
|
|
127133
127151
|
}
|
|
127134
127152
|
const durationMs = Math.round(performance.now() - t0);
|
|
127135
127153
|
ctx.emit({
|
|
@@ -127453,6 +127471,47 @@ var init_resolve = __esm(() => {
|
|
|
127453
127471
|
STRUCTURAL_SEED_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".rb", ".php", ".lua", ".c", ".h", ".cpp", ".hpp", ".go", ".rs", ".zig", ".java", ".kt", ".kts", ".scala", ".cs", ".swift", ".dart", ".ex", ".exs", ".erl", ".clj", ".ml", ".hs", ".vue", ".md", ".json", ".yaml", ".yml"]);
|
|
127454
127472
|
});
|
|
127455
127473
|
|
|
127474
|
+
// ../../packages/core/dist/data/with-deadlock-retry.js
|
|
127475
|
+
function isRetriableTransactionError(error51) {
|
|
127476
|
+
if (!error51 || typeof error51 !== "object")
|
|
127477
|
+
return false;
|
|
127478
|
+
const code = error51.code;
|
|
127479
|
+
if (typeof code === "string" && RETRIABLE_SQLSTATES.has(code))
|
|
127480
|
+
return true;
|
|
127481
|
+
const message = error51.message;
|
|
127482
|
+
if (typeof message === "string" && /Code:\s*`(?:40P01|40001|40P02)`/.test(message)) {
|
|
127483
|
+
return true;
|
|
127484
|
+
}
|
|
127485
|
+
return false;
|
|
127486
|
+
}
|
|
127487
|
+
async function withDeadlockRetry(operation, options = {}) {
|
|
127488
|
+
const maxAttempts = options.maxAttempts ?? 5;
|
|
127489
|
+
const baseDelayMs = options.baseDelayMs ?? 75;
|
|
127490
|
+
for (let attempt = 1;attempt <= maxAttempts; attempt++) {
|
|
127491
|
+
try {
|
|
127492
|
+
return await operation();
|
|
127493
|
+
} catch (error51) {
|
|
127494
|
+
if (!isRetriableTransactionError(error51) || attempt === maxAttempts)
|
|
127495
|
+
throw error51;
|
|
127496
|
+
const delayMs = baseDelayMs * 2 ** (attempt - 1);
|
|
127497
|
+
logger.warn("Retriable DB lock cycle; retrying operation", {
|
|
127498
|
+
operation: options.operation ?? "unknown",
|
|
127499
|
+
attempt,
|
|
127500
|
+
maxAttempts,
|
|
127501
|
+
delayMs,
|
|
127502
|
+
error: error51?.message?.slice(0, 120)
|
|
127503
|
+
});
|
|
127504
|
+
await new Promise((resolve5) => setTimeout(resolve5, delayMs));
|
|
127505
|
+
}
|
|
127506
|
+
}
|
|
127507
|
+
throw new Error("withDeadlockRetry exhausted retries");
|
|
127508
|
+
}
|
|
127509
|
+
var RETRIABLE_SQLSTATES;
|
|
127510
|
+
var init_with_deadlock_retry = __esm(() => {
|
|
127511
|
+
init_dist();
|
|
127512
|
+
RETRIABLE_SQLSTATES = new Set(["40P01", "40001", "40P02"]);
|
|
127513
|
+
});
|
|
127514
|
+
|
|
127456
127515
|
// ../../packages/core/dist/services/etl/stages/load.js
|
|
127457
127516
|
import path15 from "path";
|
|
127458
127517
|
function formatDuration(ms) {
|
|
@@ -127569,8 +127628,12 @@ class LoadStage {
|
|
|
127569
127628
|
return;
|
|
127570
127629
|
try {
|
|
127571
127630
|
const [chunkCount, symCount] = await Promise.all([
|
|
127572
|
-
mode === "structural" ? Promise.resolve(0) : this.loadToSearchStores(ctx, file2),
|
|
127573
|
-
|
|
127631
|
+
mode === "structural" ? Promise.resolve(0) : withDeadlockRetry(() => this.loadToSearchStores(ctx, file2), {
|
|
127632
|
+
operation: "etl.loadToSearchStores"
|
|
127633
|
+
}),
|
|
127634
|
+
mode === "semantic" ? Promise.resolve(file2.symbols.length) : withDeadlockRetry(() => this.loadToSymbolDb(ctx, file2), {
|
|
127635
|
+
operation: "etl.loadToSymbolDb"
|
|
127636
|
+
})
|
|
127574
127637
|
]);
|
|
127575
127638
|
if (!ctx.graphGenerationLease && mode !== "structural") {
|
|
127576
127639
|
await getSymbolRepository().upsertFile({
|
|
@@ -127762,6 +127825,7 @@ class LoadStage {
|
|
|
127762
127825
|
}
|
|
127763
127826
|
var init_load = __esm(() => {
|
|
127764
127827
|
init_dist();
|
|
127828
|
+
init_with_deadlock_retry();
|
|
127765
127829
|
init_vector_store_factory();
|
|
127766
127830
|
init_keyword_search_factory();
|
|
127767
127831
|
init_symbol_repository_factory();
|
|
@@ -127959,7 +128023,7 @@ class GraphGenerationRepositoryPg {
|
|
|
127959
128023
|
AND graph_lease_token = ${lease.leaseToken}
|
|
127960
128024
|
`;
|
|
127961
128025
|
return { status: "renewed", leaseExpiresAt: renewed[0].lease_expires_at.getTime() };
|
|
127962
|
-
});
|
|
128026
|
+
}, { timeout: 60000, maxWait: 1e4 });
|
|
127963
128027
|
}
|
|
127964
128028
|
async complete(lease) {
|
|
127965
128029
|
return getPrismaClient2().$transaction(async (tx) => {
|
|
@@ -128133,7 +128197,7 @@ class GraphGenerationCoordinator {
|
|
|
128133
128197
|
} while (true);
|
|
128134
128198
|
}
|
|
128135
128199
|
async heartbeat(lease) {
|
|
128136
|
-
const outcome2 = await this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS);
|
|
128200
|
+
const outcome2 = await withDeadlockRetry(() => this.repository.heartbeat(lease, GRAPH_GENERATION_LEASE_TTL_MS), { operation: "graph_generation.heartbeat", maxAttempts: 3 });
|
|
128137
128201
|
if (outcome2.status !== "renewed")
|
|
128138
128202
|
throw new Error("graph_generation_lease_lost");
|
|
128139
128203
|
}
|
|
@@ -128169,6 +128233,7 @@ class GraphGenerationCoordinator {
|
|
|
128169
128233
|
var GRAPH_GENERATION_LEASE_TTL_MS = 300000;
|
|
128170
128234
|
var init_graph_generation_coordinator = __esm(() => {
|
|
128171
128235
|
init_graph_generation_repository_factory();
|
|
128236
|
+
init_with_deadlock_retry();
|
|
128172
128237
|
});
|
|
128173
128238
|
|
|
128174
128239
|
// ../../packages/core/dist/services/etl/pipeline.js
|
|
@@ -128246,6 +128311,7 @@ var init_pipeline = __esm(() => {
|
|
|
128246
128311
|
init_symbol_repository_factory();
|
|
128247
128312
|
init_index_job_tracker();
|
|
128248
128313
|
init_cache_factory();
|
|
128314
|
+
init_index_manager();
|
|
128249
128315
|
init_vector_store_factory();
|
|
128250
128316
|
init_keyword_search_factory();
|
|
128251
128317
|
init_alias_resolver();
|
|
@@ -128537,6 +128603,16 @@ var init_pipeline = __esm(() => {
|
|
|
128537
128603
|
}
|
|
128538
128604
|
};
|
|
128539
128605
|
await getSearchCache().invalidateProject(projectId);
|
|
128606
|
+
try {
|
|
128607
|
+
const admissionMarker = new IndexManager(await getVectorStore());
|
|
128608
|
+
await admissionMarker.updateIndexMetadata(projectId, projectPath, discovered.map((file2) => file2.relativePath));
|
|
128609
|
+
} catch (markerError) {
|
|
128610
|
+
logger.warn("EtlPipeline: search-admission marker write failed", {
|
|
128611
|
+
projectId,
|
|
128612
|
+
jobId,
|
|
128613
|
+
error: markerError.message.slice(0, 160)
|
|
128614
|
+
});
|
|
128615
|
+
}
|
|
128540
128616
|
indexJobTracker.updateProgress(jobId, result.filesIndexed, result.filesIndexed);
|
|
128541
128617
|
await indexJobTracker.setResultAndFlush(jobId, {
|
|
128542
128618
|
filesIndexed: result.filesIndexed,
|
|
@@ -131951,10 +132027,10 @@ class GraphQueries {
|
|
|
131951
132027
|
return new Map;
|
|
131952
132028
|
}
|
|
131953
132029
|
const rows = await getPrismaClient2().$queryRaw`
|
|
131954
|
-
SELECT id, content, type, level, importance,
|
|
132030
|
+
SELECT id, content, type, level, importance, tags,
|
|
131955
132031
|
created_at, updated_at, access_count, user_id, session_id, project_id, agent_id,
|
|
131956
132032
|
NULL::bytea AS embedding, NULL::text AS metadata, NULL::timestamp AS last_accessed,
|
|
131957
|
-
pinned
|
|
132033
|
+
CASE WHEN pinned THEN 1 ELSE 0 END AS pinned, deleted_at
|
|
131958
132034
|
FROM memories WHERE id = ANY(${memoryIds}::text[])`;
|
|
131959
132035
|
const result = new Map;
|
|
131960
132036
|
for (const row of rows) {
|
|
@@ -133259,7 +133335,7 @@ class CompressContextTool {
|
|
|
133259
133335
|
} catch (error51) {
|
|
133260
133336
|
logger.error("Failed to compress context", error51, {
|
|
133261
133337
|
strategy,
|
|
133262
|
-
contentLength: content.length
|
|
133338
|
+
contentLength: typeof content === "string" ? content.length : 0
|
|
133263
133339
|
});
|
|
133264
133340
|
return {
|
|
133265
133341
|
success: false,
|
|
@@ -135381,16 +135457,14 @@ var TOOL_NAME_NORMALIZE, classifyToolCall = (_source, payload) => {
|
|
|
135381
135457
|
const cmdRaw = field2(payload, "command") ?? (toolInput && typeof toolInput === "object" ? toolInput.command : undefined);
|
|
135382
135458
|
const cmd = lower(cmdRaw);
|
|
135383
135459
|
if (cmd.startsWith("git ") || cmd.includes(" git ")) {
|
|
135384
|
-
if (cmd.includes("commit") || cmd.includes("merge") || cmd.includes("rebase")) {
|
|
135385
|
-
return "git-changes";
|
|
135386
|
-
}
|
|
135387
135460
|
return "git-changes";
|
|
135388
135461
|
}
|
|
135389
135462
|
return "tool-calls";
|
|
135390
135463
|
}
|
|
135391
135464
|
case "TodoWrite":
|
|
135392
|
-
case "Task":
|
|
135393
135465
|
return "tasks";
|
|
135466
|
+
case "Task":
|
|
135467
|
+
return "subagents-spawned";
|
|
135394
135468
|
case "WebFetch":
|
|
135395
135469
|
return "web-fetch";
|
|
135396
135470
|
case "WebSearch":
|
|
@@ -135407,8 +135481,6 @@ var TOOL_NAME_NORMALIZE, classifyToolCall = (_source, payload) => {
|
|
|
135407
135481
|
return "memories-stored";
|
|
135408
135482
|
case "compact_snapshot":
|
|
135409
135483
|
return "compaction-snapshots";
|
|
135410
|
-
case "Task":
|
|
135411
|
-
return "subagents-spawned";
|
|
135412
135484
|
default:
|
|
135413
135485
|
if (toolName.startsWith("mcp__"))
|
|
135414
135486
|
return "mcp-calls";
|
|
@@ -168147,36 +168219,37 @@ function resolveFlavor(request) {
|
|
|
168147
168219
|
// src/index.ts
|
|
168148
168220
|
init_config();
|
|
168149
168221
|
var args = process.argv.slice(2);
|
|
168150
|
-
|
|
168151
|
-
|
|
168152
|
-
|
|
168153
|
-
|
|
168154
|
-
|
|
168155
|
-
|
|
168156
|
-
|
|
168157
|
-
|
|
168222
|
+
function processCliArgs(cliArgs) {
|
|
168223
|
+
if (cliArgs.includes("--config-show")) {
|
|
168224
|
+
try {
|
|
168225
|
+
const config3 = loadConfig();
|
|
168226
|
+
console.log(JSON.stringify(config3, null, 2));
|
|
168227
|
+
return 0;
|
|
168228
|
+
} catch (error51) {
|
|
168229
|
+
console.error("Error loading config:", error51 instanceof Error ? error51.message : String(error51));
|
|
168230
|
+
return 1;
|
|
168231
|
+
}
|
|
168158
168232
|
}
|
|
168159
|
-
|
|
168160
|
-
|
|
168161
|
-
|
|
168162
|
-
process.exit(0);
|
|
168163
|
-
}
|
|
168164
|
-
if (args.includes("--config-dir")) {
|
|
168165
|
-
console.log(getConfigDir());
|
|
168166
|
-
process.exit(0);
|
|
168167
|
-
}
|
|
168168
|
-
if (args.includes("--config-init")) {
|
|
168169
|
-
try {
|
|
168170
|
-
initConfig();
|
|
168171
|
-
console.log(`Configuration initialized at: ${getConfigPath()}`);
|
|
168172
|
-
process.exit(0);
|
|
168173
|
-
} catch (error51) {
|
|
168174
|
-
console.error("Error initializing config:", error51 instanceof Error ? error51.message : String(error51));
|
|
168175
|
-
process.exit(1);
|
|
168233
|
+
if (cliArgs.includes("--config-path")) {
|
|
168234
|
+
console.log(getConfigPath());
|
|
168235
|
+
return 0;
|
|
168176
168236
|
}
|
|
168177
|
-
|
|
168178
|
-
|
|
168179
|
-
|
|
168237
|
+
if (cliArgs.includes("--config-dir")) {
|
|
168238
|
+
console.log(getConfigDir());
|
|
168239
|
+
return 0;
|
|
168240
|
+
}
|
|
168241
|
+
if (cliArgs.includes("--config-init")) {
|
|
168242
|
+
try {
|
|
168243
|
+
initConfig();
|
|
168244
|
+
console.log(`Configuration initialized at: ${getConfigPath()}`);
|
|
168245
|
+
return 0;
|
|
168246
|
+
} catch (error51) {
|
|
168247
|
+
console.error("Error initializing config:", error51 instanceof Error ? error51.message : String(error51));
|
|
168248
|
+
return 1;
|
|
168249
|
+
}
|
|
168250
|
+
}
|
|
168251
|
+
if (cliArgs.includes("--help") || cliArgs.includes("-h")) {
|
|
168252
|
+
console.log(`
|
|
168180
168253
|
massa-ai MCP Client
|
|
168181
168254
|
|
|
168182
168255
|
Usage:
|
|
@@ -168196,7 +168269,24 @@ Examples:
|
|
|
168196
168269
|
npx @massa-ai/mcp-client --config-show
|
|
168197
168270
|
npx @massa-ai/mcp-client --config-path
|
|
168198
168271
|
`);
|
|
168199
|
-
|
|
168272
|
+
return 0;
|
|
168273
|
+
}
|
|
168274
|
+
const KNOWN_FLAGS = ["--config-show", "--config-path", "--config-dir", "--config-init", "--help", "-h"];
|
|
168275
|
+
const unknown3 = cliArgs.filter((a) => a.startsWith("-") && !KNOWN_FLAGS.includes(a));
|
|
168276
|
+
if (unknown3.length) {
|
|
168277
|
+
console.error(`Unknown flag: ${unknown3[0]}
|
|
168278
|
+
Run 'massa-ai --help' for usage.`);
|
|
168279
|
+
return 2;
|
|
168280
|
+
}
|
|
168281
|
+
return;
|
|
168282
|
+
}
|
|
168283
|
+
if (import.meta.main) {
|
|
168284
|
+
const code = processCliArgs(args);
|
|
168285
|
+
if (code !== undefined)
|
|
168286
|
+
process.exit(code);
|
|
168287
|
+
if (!configExists()) {
|
|
168288
|
+
initConfig();
|
|
168289
|
+
}
|
|
168200
168290
|
}
|
|
168201
168291
|
function textContent(text3) {
|
|
168202
168292
|
return { content: [{ type: "text", text: text3 }] };
|
|
@@ -168204,22 +168294,6 @@ function textContent(text3) {
|
|
|
168204
168294
|
function isEmbeddedMode() {
|
|
168205
168295
|
return process.env.MASSA_AI_EMBEDDED === "true";
|
|
168206
168296
|
}
|
|
168207
|
-
var KNOWN_FLAGS = ["--config-show", "--config-path", "--config-dir", "--config-init", "--help", "-h"];
|
|
168208
|
-
var unknown3 = args.filter((a) => a.startsWith("-") && !KNOWN_FLAGS.includes(a));
|
|
168209
|
-
if (unknown3.length) {
|
|
168210
|
-
console.error(`Unknown flag: ${unknown3[0]}
|
|
168211
|
-
Run 'massa-ai --help' for usage.`);
|
|
168212
|
-
process.exit(2);
|
|
168213
|
-
}
|
|
168214
|
-
if (!configExists()) {
|
|
168215
|
-
initConfig();
|
|
168216
|
-
console.log(`
|
|
168217
|
-
[massa-ai] Initialized with default configuration
|
|
168218
|
-
[massa-ai] Config: ${getConfigPath()}
|
|
168219
|
-
[massa-ai] Provider: Ollama (local, free)
|
|
168220
|
-
[massa-ai] To change: npx @massa-ai/mcp-client massa-ai-config use mistral --api-key YOUR_KEY
|
|
168221
|
-
`);
|
|
168222
|
-
}
|
|
168223
168297
|
|
|
168224
168298
|
class McpProxyServer {
|
|
168225
168299
|
server;
|
|
@@ -168246,32 +168320,34 @@ class McpProxyServer {
|
|
|
168246
168320
|
this.setupHandlers();
|
|
168247
168321
|
}
|
|
168248
168322
|
setupHandlers() {
|
|
168249
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async (request) =>
|
|
168250
|
-
|
|
168251
|
-
|
|
168252
|
-
|
|
168253
|
-
|
|
168254
|
-
|
|
168255
|
-
|
|
168256
|
-
|
|
168257
|
-
|
|
168258
|
-
|
|
168259
|
-
|
|
168260
|
-
|
|
168261
|
-
|
|
168262
|
-
return {
|
|
168263
|
-
content: [
|
|
168264
|
-
{
|
|
168265
|
-
type: "text",
|
|
168266
|
-
text: JSON.stringify({
|
|
168267
|
-
success: false,
|
|
168268
|
-
error: error51 instanceof Error ? error51.message : String(error51)
|
|
168269
|
-
})
|
|
168270
|
-
}
|
|
168271
|
-
]
|
|
168272
|
-
};
|
|
168323
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async (request) => this.handleListTools(request));
|
|
168324
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => this.handleCallTool(request));
|
|
168325
|
+
}
|
|
168326
|
+
async handleListTools(request) {
|
|
168327
|
+
const result = pageToolDefinitions(TOOL_DEFINITIONS, request.params?.cursor);
|
|
168328
|
+
const flavor = resolveFlavor(request);
|
|
168329
|
+
return applyMoonshotFlavor(result, flavor);
|
|
168330
|
+
}
|
|
168331
|
+
async handleCallTool(request) {
|
|
168332
|
+
const { name: name26, arguments: args2 } = request.params;
|
|
168333
|
+
try {
|
|
168334
|
+
if (name26 === "index") {
|
|
168335
|
+
return await this.handleIndexTool(args2 ?? {});
|
|
168273
168336
|
}
|
|
168274
|
-
|
|
168337
|
+
return await proxyCallTool(this.apiClient, name26, args2 ?? {});
|
|
168338
|
+
} catch (error51) {
|
|
168339
|
+
return {
|
|
168340
|
+
content: [
|
|
168341
|
+
{
|
|
168342
|
+
type: "text",
|
|
168343
|
+
text: JSON.stringify({
|
|
168344
|
+
success: false,
|
|
168345
|
+
error: error51 instanceof Error ? error51.message : String(error51)
|
|
168346
|
+
})
|
|
168347
|
+
}
|
|
168348
|
+
]
|
|
168349
|
+
};
|
|
168350
|
+
}
|
|
168275
168351
|
}
|
|
168276
168352
|
async handleIndexTool(args2) {
|
|
168277
168353
|
const projectPath2 = args2.projectPath;
|
|
@@ -168304,27 +168380,30 @@ class McpProxyServer {
|
|
|
168304
168380
|
}
|
|
168305
168381
|
async start() {
|
|
168306
168382
|
const healthy = await this.apiClient.healthCheck();
|
|
168307
|
-
if (!healthy) {
|
|
168308
|
-
console.log(`[massa-ai-mcp] Warning: Tools API is not reachable (mode: ${this.mode}). Requests will fail until API is available.`);
|
|
168309
|
-
} else {
|
|
168310
|
-
console.log(`[massa-ai-mcp] Connected (mode: ${this.mode})`);
|
|
168311
|
-
}
|
|
168312
168383
|
await this.server.connect(this.transport);
|
|
168313
168384
|
}
|
|
168314
168385
|
async close() {
|
|
168315
168386
|
await this.server.close();
|
|
168316
168387
|
}
|
|
168317
168388
|
}
|
|
168318
|
-
|
|
168319
|
-
client
|
|
168320
|
-
|
|
168321
|
-
|
|
168322
|
-
|
|
168323
|
-
|
|
168324
|
-
|
|
168325
|
-
|
|
168326
|
-
|
|
168327
|
-
|
|
168328
|
-
|
|
168329
|
-
|
|
168330
|
-
|
|
168389
|
+
if (import.meta.main) {
|
|
168390
|
+
const client = new McpProxyServer;
|
|
168391
|
+
client.start().catch((error51) => {
|
|
168392
|
+
console.error("Failed to start MCP client:", error51);
|
|
168393
|
+
process.exit(1);
|
|
168394
|
+
});
|
|
168395
|
+
process.on("SIGINT", async () => {
|
|
168396
|
+
await client.close();
|
|
168397
|
+
process.exit(0);
|
|
168398
|
+
});
|
|
168399
|
+
process.on("SIGTERM", async () => {
|
|
168400
|
+
await client.close();
|
|
168401
|
+
process.exit(0);
|
|
168402
|
+
});
|
|
168403
|
+
}
|
|
168404
|
+
export {
|
|
168405
|
+
textContent,
|
|
168406
|
+
processCliArgs,
|
|
168407
|
+
isEmbeddedMode,
|
|
168408
|
+
McpProxyServer
|
|
168409
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massa-ai/mcp-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.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",
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"dev": "bun run --watch src/index.ts",
|
|
17
17
|
"start": "bun run src/index.ts",
|
|
18
18
|
"build": "bun build src/index.ts src/config-cli.ts --outdir=dist --target=bun",
|
|
19
|
-
"test": "bun
|
|
19
|
+
"test": "bun scripts/run-tests-isolated.ts",
|
|
20
20
|
"type-check": "tsc --noEmit"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@massa-ai/core": "^1.
|
|
24
|
-
"@massa-ai/shared": "^1.
|
|
23
|
+
"@massa-ai/core": "^1.4.0",
|
|
24
|
+
"@massa-ai/shared": "^1.4.0",
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|