gnosys-mcp 2.4.0 → 2.5.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/cli.js +207 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/federated.d.ts +111 -0
- package/dist/lib/federated.d.ts.map +1 -0
- package/dist/lib/federated.js +340 -0
- package/dist/lib/federated.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2397,5 +2397,212 @@ program
|
|
|
2397
2397
|
centralDb?.close();
|
|
2398
2398
|
}
|
|
2399
2399
|
});
|
|
2400
|
+
// ─── gnosys fsearch (federated search) ───────────────────────────────────
|
|
2401
|
+
program
|
|
2402
|
+
.command("fsearch <query>")
|
|
2403
|
+
.description("Federated search across all scopes with tier boosting (project > user > global)")
|
|
2404
|
+
.option("-l, --limit <n>", "Max results", "20")
|
|
2405
|
+
.option("-d, --directory <dir>", "Project directory for context")
|
|
2406
|
+
.option("--no-global", "Exclude global-scope memories")
|
|
2407
|
+
.option("--json", "Output as JSON")
|
|
2408
|
+
.action(async (query, opts) => {
|
|
2409
|
+
let centralDb = null;
|
|
2410
|
+
try {
|
|
2411
|
+
centralDb = GnosysDB.openCentral();
|
|
2412
|
+
if (!centralDb.isAvailable()) {
|
|
2413
|
+
console.error("Central DB not available.");
|
|
2414
|
+
process.exit(1);
|
|
2415
|
+
}
|
|
2416
|
+
const { federatedSearch, detectCurrentProject } = await import("./lib/federated.js");
|
|
2417
|
+
const projectId = await detectCurrentProject(centralDb, opts.directory || undefined);
|
|
2418
|
+
const results = federatedSearch(centralDb, query, {
|
|
2419
|
+
limit: parseInt(opts.limit, 10),
|
|
2420
|
+
projectId,
|
|
2421
|
+
includeGlobal: opts.global,
|
|
2422
|
+
});
|
|
2423
|
+
if (opts.json) {
|
|
2424
|
+
console.log(JSON.stringify({ query, projectId, count: results.length, results }, null, 2));
|
|
2425
|
+
}
|
|
2426
|
+
else {
|
|
2427
|
+
if (results.length === 0) {
|
|
2428
|
+
console.log(`No results for "${query}".`);
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
const ctx = projectId ? `Context: project ${projectId}` : "No project detected";
|
|
2432
|
+
console.log(ctx);
|
|
2433
|
+
for (const [i, r] of results.entries()) {
|
|
2434
|
+
const proj = r.projectName ? ` [${r.projectName}]` : "";
|
|
2435
|
+
console.log(`\n${i + 1}. ${r.title} (${r.category})${proj}`);
|
|
2436
|
+
console.log(` scope: ${r.scope} | score: ${r.score.toFixed(4)} | boosts: ${r.boosts.join(", ")}`);
|
|
2437
|
+
if (r.snippet)
|
|
2438
|
+
console.log(` ${r.snippet.substring(0, 120)}`);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
catch (err) {
|
|
2443
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
2444
|
+
process.exit(1);
|
|
2445
|
+
}
|
|
2446
|
+
finally {
|
|
2447
|
+
centralDb?.close();
|
|
2448
|
+
}
|
|
2449
|
+
});
|
|
2450
|
+
// ─── gnosys ambiguity ────────────────────────────────────────────────────
|
|
2451
|
+
program
|
|
2452
|
+
.command("ambiguity <query>")
|
|
2453
|
+
.description("Check if a query matches memories in multiple projects")
|
|
2454
|
+
.option("--json", "Output as JSON")
|
|
2455
|
+
.action(async (query, opts) => {
|
|
2456
|
+
let centralDb = null;
|
|
2457
|
+
try {
|
|
2458
|
+
centralDb = GnosysDB.openCentral();
|
|
2459
|
+
if (!centralDb.isAvailable()) {
|
|
2460
|
+
console.error("Central DB not available.");
|
|
2461
|
+
process.exit(1);
|
|
2462
|
+
}
|
|
2463
|
+
const { detectAmbiguity } = await import("./lib/federated.js");
|
|
2464
|
+
const ambiguity = detectAmbiguity(centralDb, query);
|
|
2465
|
+
if (opts.json) {
|
|
2466
|
+
console.log(JSON.stringify({ query, ambiguous: !!ambiguity, ...(ambiguity || {}) }, null, 2));
|
|
2467
|
+
}
|
|
2468
|
+
else if (!ambiguity) {
|
|
2469
|
+
console.log(`No ambiguity for "${query}" — matches at most one project.`);
|
|
2470
|
+
}
|
|
2471
|
+
else {
|
|
2472
|
+
console.log(ambiguity.message);
|
|
2473
|
+
for (const c of ambiguity.candidates) {
|
|
2474
|
+
console.log(`\n ${c.projectName} (${c.projectId})`);
|
|
2475
|
+
console.log(` Dir: ${c.workingDirectory}`);
|
|
2476
|
+
console.log(` Matching memories: ${c.memoryCount}`);
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
catch (err) {
|
|
2481
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
2482
|
+
process.exit(1);
|
|
2483
|
+
}
|
|
2484
|
+
finally {
|
|
2485
|
+
centralDb?.close();
|
|
2486
|
+
}
|
|
2487
|
+
});
|
|
2488
|
+
// ─── gnosys briefing ─────────────────────────────────────────────────────
|
|
2489
|
+
program
|
|
2490
|
+
.command("briefing")
|
|
2491
|
+
.description("Generate project briefing — memory state summary, categories, recent activity, top tags")
|
|
2492
|
+
.option("-p, --project <id>", "Project ID (auto-detects if omitted)")
|
|
2493
|
+
.option("-a, --all", "Generate briefings for all projects")
|
|
2494
|
+
.option("-d, --directory <dir>", "Project directory for auto-detection")
|
|
2495
|
+
.option("--json", "Output as JSON")
|
|
2496
|
+
.action(async (opts) => {
|
|
2497
|
+
let centralDb = null;
|
|
2498
|
+
try {
|
|
2499
|
+
centralDb = GnosysDB.openCentral();
|
|
2500
|
+
if (!centralDb.isAvailable()) {
|
|
2501
|
+
console.error("Central DB not available.");
|
|
2502
|
+
process.exit(1);
|
|
2503
|
+
}
|
|
2504
|
+
const { generateBriefing, generateAllBriefings, detectCurrentProject } = await import("./lib/federated.js");
|
|
2505
|
+
if (opts.all) {
|
|
2506
|
+
const briefings = generateAllBriefings(centralDb);
|
|
2507
|
+
if (opts.json) {
|
|
2508
|
+
console.log(JSON.stringify({ count: briefings.length, briefings }, null, 2));
|
|
2509
|
+
}
|
|
2510
|
+
else {
|
|
2511
|
+
if (briefings.length === 0) {
|
|
2512
|
+
console.log("No projects registered.");
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
for (const b of briefings) {
|
|
2516
|
+
console.log(`\n## ${b.projectName}`);
|
|
2517
|
+
console.log(b.summary);
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
let pid = opts.project || null;
|
|
2523
|
+
if (!pid)
|
|
2524
|
+
pid = await detectCurrentProject(centralDb, opts.directory || undefined);
|
|
2525
|
+
if (!pid) {
|
|
2526
|
+
console.error("No project specified and none detected.");
|
|
2527
|
+
process.exit(1);
|
|
2528
|
+
}
|
|
2529
|
+
const briefing = generateBriefing(centralDb, pid);
|
|
2530
|
+
if (!briefing) {
|
|
2531
|
+
console.error(`Project not found: ${pid}`);
|
|
2532
|
+
process.exit(1);
|
|
2533
|
+
}
|
|
2534
|
+
if (opts.json) {
|
|
2535
|
+
console.log(JSON.stringify(briefing, null, 2));
|
|
2536
|
+
}
|
|
2537
|
+
else {
|
|
2538
|
+
console.log(`# Briefing: ${briefing.projectName}`);
|
|
2539
|
+
console.log(`Directory: ${briefing.workingDirectory}`);
|
|
2540
|
+
console.log(`Active memories: ${briefing.activeMemories} / ${briefing.totalMemories}`);
|
|
2541
|
+
console.log(`\nCategories:`);
|
|
2542
|
+
for (const [cat, count] of Object.entries(briefing.categories).sort((a, b) => b[1] - a[1])) {
|
|
2543
|
+
console.log(` ${cat}: ${count}`);
|
|
2544
|
+
}
|
|
2545
|
+
console.log(`\nRecent activity (7d):`);
|
|
2546
|
+
if (briefing.recentActivity.length === 0) {
|
|
2547
|
+
console.log(" None");
|
|
2548
|
+
}
|
|
2549
|
+
for (const r of briefing.recentActivity) {
|
|
2550
|
+
console.log(` - ${r.title} (${r.modified})`);
|
|
2551
|
+
}
|
|
2552
|
+
console.log(`\nTop tags: ${briefing.topTags.slice(0, 10).map((t) => `${t.tag}(${t.count})`).join(", ") || "None"}`);
|
|
2553
|
+
console.log(`\n${briefing.summary}`);
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
catch (err) {
|
|
2557
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
2558
|
+
process.exit(1);
|
|
2559
|
+
}
|
|
2560
|
+
finally {
|
|
2561
|
+
centralDb?.close();
|
|
2562
|
+
}
|
|
2563
|
+
});
|
|
2564
|
+
// ─── gnosys working-set ──────────────────────────────────────────────────
|
|
2565
|
+
program
|
|
2566
|
+
.command("working-set")
|
|
2567
|
+
.description("Show the implicit working set — recently modified memories for the current project")
|
|
2568
|
+
.option("-d, --directory <dir>", "Project directory")
|
|
2569
|
+
.option("-w, --window <hours>", "Lookback window in hours", "24")
|
|
2570
|
+
.option("--json", "Output as JSON")
|
|
2571
|
+
.action(async (opts) => {
|
|
2572
|
+
let centralDb = null;
|
|
2573
|
+
try {
|
|
2574
|
+
centralDb = GnosysDB.openCentral();
|
|
2575
|
+
if (!centralDb.isAvailable()) {
|
|
2576
|
+
console.error("Central DB not available.");
|
|
2577
|
+
process.exit(1);
|
|
2578
|
+
}
|
|
2579
|
+
const { getWorkingSet, formatWorkingSet, detectCurrentProject } = await import("./lib/federated.js");
|
|
2580
|
+
const pid = await detectCurrentProject(centralDb, opts.directory || undefined);
|
|
2581
|
+
if (!pid) {
|
|
2582
|
+
console.error("No project detected.");
|
|
2583
|
+
process.exit(1);
|
|
2584
|
+
}
|
|
2585
|
+
const windowHours = parseInt(opts.window, 10);
|
|
2586
|
+
const workingSet = getWorkingSet(centralDb, pid, { windowHours });
|
|
2587
|
+
if (opts.json) {
|
|
2588
|
+
console.log(JSON.stringify({
|
|
2589
|
+
projectId: pid,
|
|
2590
|
+
windowHours,
|
|
2591
|
+
count: workingSet.length,
|
|
2592
|
+
memories: workingSet.map((m) => ({ id: m.id, title: m.title, category: m.category, modified: m.modified })),
|
|
2593
|
+
}, null, 2));
|
|
2594
|
+
}
|
|
2595
|
+
else {
|
|
2596
|
+
console.log(formatWorkingSet(workingSet));
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
catch (err) {
|
|
2600
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
2601
|
+
process.exit(1);
|
|
2602
|
+
}
|
|
2603
|
+
finally {
|
|
2604
|
+
centralDb?.close();
|
|
2605
|
+
}
|
|
2606
|
+
});
|
|
2400
2607
|
program.parse();
|
|
2401
2608
|
//# sourceMappingURL=cli.js.map
|