memory-journal-mcp 7.2.0 → 7.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/README.md +69 -64
- package/dist/{chunk-GR4T3SRW.js → chunk-5ZA77VUW.js} +688 -121
- package/dist/{chunk-ORV7ZZOE.js → chunk-P5V2VY6N.js} +365 -74
- package/dist/{chunk-IWKLHSPU.js → chunk-WXDEVIFL.js} +6 -6
- package/dist/cli.js +9 -4
- package/dist/github-integration-YODGZH3K.js +1 -0
- package/dist/index.d.ts +17 -2
- package/dist/index.js +3 -3
- package/dist/{tools-CXR2FEB2.js → tools-WZUENKJ6.js} +2 -2
- package/package.json +4 -4
- package/skills/README.md +5 -1
- package/skills/docker/SKILL.md +262 -0
- package/skills/github-actions/SKILL.md +315 -0
- package/skills/package.json +5 -1
- package/skills/python/SKILL.md +257 -0
- package/skills/tailwind-css/SKILL.md +268 -0
- package/dist/github-integration-2TFMXHIJ.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { transformAutoReturn } from './chunk-OKOVZ5QE.js';
|
|
2
|
-
import { GitHubIntegration, resolveAuthor, logger, ValidationError, ResourceNotFoundError, assertSafeDirectoryPath, MemoryJournalMcpError, matchSuggestion, ConfigurationError } from './chunk-
|
|
2
|
+
import { GitHubIntegration, resolveAuthor, logger, ValidationError, ResourceNotFoundError, assertSafeDirectoryPath, MemoryJournalMcpError, matchSuggestion, ConfigurationError } from './chunk-WXDEVIFL.js';
|
|
3
3
|
import { z, ZodError } from 'zod';
|
|
4
4
|
import { open, stat, mkdir, rename, appendFile, readdir, readFile } from 'fs/promises';
|
|
5
5
|
import { tmpdir } from 'os';
|
|
@@ -59,7 +59,7 @@ async function resolveIssueUrl(context, projectNumber, issueNumber, existingUrl)
|
|
|
59
59
|
([_, v]) => v.project_number === projectNumber
|
|
60
60
|
);
|
|
61
61
|
if (entry) {
|
|
62
|
-
const { GitHubIntegration: GitHubIntegration2 } = await import('./github-integration-
|
|
62
|
+
const { GitHubIntegration: GitHubIntegration2 } = await import('./github-integration-YODGZH3K.js');
|
|
63
63
|
const targetGithub = new GitHubIntegration2(entry[1].path);
|
|
64
64
|
const repoInfo = await targetGithub.getRepoInfo();
|
|
65
65
|
if (repoInfo.owner && repoInfo.repo) {
|
|
@@ -114,7 +114,7 @@ var SIGNIFICANCE_TYPES = [
|
|
|
114
114
|
"release"
|
|
115
115
|
];
|
|
116
116
|
var MAX_CONTENT_LENGTH = 5e4;
|
|
117
|
-
var MAX_QUERY_LIMIT = 500;
|
|
117
|
+
var MAX_QUERY_LIMIT = Number("500");
|
|
118
118
|
var DATE_MIN_SENTINEL = "1970-01-01";
|
|
119
119
|
var DATE_MAX_SENTINEL = "2999-12-31";
|
|
120
120
|
var DATE_FORMAT_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
@@ -140,7 +140,8 @@ var EntryOutputSchema = z.object({
|
|
|
140
140
|
workflowRunId: z.number().nullable().optional(),
|
|
141
141
|
workflowName: z.string().nullable().optional(),
|
|
142
142
|
workflowStatus: z.string().nullable().optional(),
|
|
143
|
-
source: z.enum(["personal", "team"]).optional()
|
|
143
|
+
source: z.enum(["personal", "team"]).optional(),
|
|
144
|
+
importanceScore: z.number().optional().describe("Importance score (0.0-1.0), present when sort_by=importance")
|
|
144
145
|
}).extend(ErrorFieldsMixin.shape);
|
|
145
146
|
var EntriesListOutputSchema = z.object({
|
|
146
147
|
entries: z.array(EntryOutputSchema).optional(),
|
|
@@ -208,7 +209,7 @@ var CreateEntrySchemaMcp = z.object({
|
|
|
208
209
|
share_with_team: z.boolean().optional().default(false)
|
|
209
210
|
});
|
|
210
211
|
var GetEntryByIdSchema = z.object({
|
|
211
|
-
entry_id: z.number(),
|
|
212
|
+
entry_id: z.number().int(),
|
|
212
213
|
include_relationships: z.boolean().optional().default(true)
|
|
213
214
|
});
|
|
214
215
|
var GetEntryByIdSchemaMcp = z.object({
|
|
@@ -217,11 +218,13 @@ var GetEntryByIdSchemaMcp = z.object({
|
|
|
217
218
|
});
|
|
218
219
|
var GetRecentEntriesSchema = z.object({
|
|
219
220
|
limit: z.number().min(1).max(MAX_QUERY_LIMIT).optional().default(5),
|
|
220
|
-
is_personal: z.boolean().optional()
|
|
221
|
+
is_personal: z.boolean().optional(),
|
|
222
|
+
sort_by: z.enum(["timestamp", "importance"]).optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
221
223
|
});
|
|
222
224
|
var GetRecentEntriesSchemaMcp = z.object({
|
|
223
225
|
limit: relaxedNumber().optional().default(5),
|
|
224
|
-
is_personal: z.boolean().optional()
|
|
226
|
+
is_personal: z.boolean().optional(),
|
|
227
|
+
sort_by: z.string().optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
225
228
|
});
|
|
226
229
|
var CreateEntryMinimalSchema = z.object({
|
|
227
230
|
content: z.string().min(1).max(MAX_CONTENT_LENGTH)
|
|
@@ -247,6 +250,7 @@ var EntryByIdOutputSchema = z.object({
|
|
|
247
250
|
error: z.string().optional()
|
|
248
251
|
}).extend(ErrorFieldsMixin.shape);
|
|
249
252
|
var TestSimpleOutputSchema = z.object({
|
|
253
|
+
success: z.boolean().optional(),
|
|
250
254
|
message: z.string()
|
|
251
255
|
}).extend(ErrorFieldsMixin.shape);
|
|
252
256
|
var TagsListOutputSchema = z.object({
|
|
@@ -364,6 +368,7 @@ function getCoreTools(context) {
|
|
|
364
368
|
}
|
|
365
369
|
const { score: importance, breakdown: importanceBreakdown } = db.calculateImportance(entry_id);
|
|
366
370
|
const result = {
|
|
371
|
+
success: true,
|
|
367
372
|
entry,
|
|
368
373
|
importance,
|
|
369
374
|
importanceBreakdown
|
|
@@ -387,9 +392,9 @@ function getCoreTools(context) {
|
|
|
387
392
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
|
|
388
393
|
handler: (params) => {
|
|
389
394
|
try {
|
|
390
|
-
const { limit, is_personal } = GetRecentEntriesSchema.parse(params);
|
|
391
|
-
const entries = db.getRecentEntries(limit, is_personal);
|
|
392
|
-
return { entries, count: entries.length };
|
|
395
|
+
const { limit, is_personal, sort_by } = GetRecentEntriesSchema.parse(params);
|
|
396
|
+
const entries = db.getRecentEntries(limit, is_personal, sort_by);
|
|
397
|
+
return { success: true, entries, count: entries.length };
|
|
393
398
|
} catch (err) {
|
|
394
399
|
return formatHandlerError(err);
|
|
395
400
|
}
|
|
@@ -425,7 +430,7 @@ function getCoreTools(context) {
|
|
|
425
430
|
handler: (params) => {
|
|
426
431
|
try {
|
|
427
432
|
const { message } = TestSimpleSchema.parse(params);
|
|
428
|
-
return { message: `Test response: ${message}` };
|
|
433
|
+
return { success: true, message: `Test response: ${message}` };
|
|
429
434
|
} catch (err) {
|
|
430
435
|
return formatHandlerError(err);
|
|
431
436
|
}
|
|
@@ -443,7 +448,7 @@ function getCoreTools(context) {
|
|
|
443
448
|
try {
|
|
444
449
|
const rawTags = db.listTags();
|
|
445
450
|
const tags = rawTags.map((t) => ({ name: t.name, count: t.usageCount }));
|
|
446
|
-
return { tags, count: tags.length };
|
|
451
|
+
return { success: true, tags, count: tags.length };
|
|
447
452
|
} catch (err) {
|
|
448
453
|
return formatHandlerError(err);
|
|
449
454
|
}
|
|
@@ -457,10 +462,19 @@ var DEDUP_KEY_LENGTH = 200;
|
|
|
457
462
|
function calcPerDbLimit(limit, hasTeamDb) {
|
|
458
463
|
return hasTeamDb ? Math.min(limit * 2, MAX_QUERY_LIMIT) : limit;
|
|
459
464
|
}
|
|
460
|
-
function mergeAndDedup(personal, team, limit) {
|
|
465
|
+
function mergeAndDedup(personal, team, limit, sortBy = "timestamp") {
|
|
461
466
|
const seen = /* @__PURE__ */ new Set();
|
|
462
467
|
const merged = [];
|
|
463
|
-
const all = [...personal, ...team].sort((a, b) =>
|
|
468
|
+
const all = [...personal, ...team].sort((a, b) => {
|
|
469
|
+
if (sortBy === "importance") {
|
|
470
|
+
const scoreA = Number(a["importanceScore"]) || 0;
|
|
471
|
+
const scoreB = Number(b["importanceScore"]) || 0;
|
|
472
|
+
if (scoreA !== scoreB) {
|
|
473
|
+
return scoreB - scoreA;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return b.timestamp.localeCompare(a.timestamp);
|
|
477
|
+
});
|
|
464
478
|
for (const entry of all) {
|
|
465
479
|
const key = entry.content.slice(0, DEDUP_KEY_LENGTH);
|
|
466
480
|
if (!seen.has(key)) {
|
|
@@ -470,6 +484,30 @@ function mergeAndDedup(personal, team, limit) {
|
|
|
470
484
|
}
|
|
471
485
|
return limit !== void 0 ? merged.slice(0, limit) : merged;
|
|
472
486
|
}
|
|
487
|
+
function passMetadataFilters(entry, options, db) {
|
|
488
|
+
if (options.isPersonal !== void 0 && entry.isPersonal !== options.isPersonal) return false;
|
|
489
|
+
if (options.projectNumber !== void 0 && entry.projectNumber !== options.projectNumber)
|
|
490
|
+
return false;
|
|
491
|
+
if (options.issueNumber !== void 0 && entry.issueNumber !== options.issueNumber) return false;
|
|
492
|
+
if (options.prNumber !== void 0 && entry.prNumber !== options.prNumber) return false;
|
|
493
|
+
if (options.prStatus !== void 0 && entry.prStatus !== options.prStatus) return false;
|
|
494
|
+
if (options.workflowRunId !== void 0 && entry.workflowRunId !== options.workflowRunId)
|
|
495
|
+
return false;
|
|
496
|
+
if (options.entryType && entry.entryType !== options.entryType) return false;
|
|
497
|
+
if (options.startDate) {
|
|
498
|
+
const entryDate = entry.timestamp.split("T")[0] ?? "";
|
|
499
|
+
if (entryDate < options.startDate) return false;
|
|
500
|
+
}
|
|
501
|
+
if (options.endDate) {
|
|
502
|
+
const entryDate = entry.timestamp.split("T")[0] ?? "";
|
|
503
|
+
if (entryDate > options.endDate) return false;
|
|
504
|
+
}
|
|
505
|
+
if (options.tags && options.tags.length > 0) {
|
|
506
|
+
const entryTags = Array.isArray(entry.tags) ? entry.tags : db.getTagsForEntry(entry.id);
|
|
507
|
+
if (!options.tags.some((t) => entryTags.includes(t))) return false;
|
|
508
|
+
}
|
|
509
|
+
return true;
|
|
510
|
+
}
|
|
473
511
|
|
|
474
512
|
// src/handlers/tools/search/auto.ts
|
|
475
513
|
var QUESTION_PATTERNS = [
|
|
@@ -510,7 +548,7 @@ function ftsSearch(query, db, teamDb, options) {
|
|
|
510
548
|
const perDbLimit = calcPerDbLimit(options.limit, !!teamDb);
|
|
511
549
|
let personalEntries;
|
|
512
550
|
if (!query && !hasFilters) {
|
|
513
|
-
personalEntries = db.getRecentEntries(perDbLimit, options.isPersonal);
|
|
551
|
+
personalEntries = db.getRecentEntries(perDbLimit, options.isPersonal, options.sortBy);
|
|
514
552
|
} else {
|
|
515
553
|
personalEntries = db.searchEntries(query || "", {
|
|
516
554
|
limit: perDbLimit,
|
|
@@ -523,13 +561,14 @@ function ftsSearch(query, db, teamDb, options) {
|
|
|
523
561
|
tags: options.tags,
|
|
524
562
|
entryType: options.entryType,
|
|
525
563
|
startDate: options.startDate,
|
|
526
|
-
endDate: options.endDate
|
|
564
|
+
endDate: options.endDate,
|
|
565
|
+
sortBy: options.sortBy
|
|
527
566
|
});
|
|
528
567
|
}
|
|
529
568
|
if (teamDb && options.isPersonal !== true) {
|
|
530
569
|
let teamEntries;
|
|
531
570
|
if (!query && !hasFilters) {
|
|
532
|
-
teamEntries = teamDb.getRecentEntries(perDbLimit);
|
|
571
|
+
teamEntries = teamDb.getRecentEntries(perDbLimit, void 0, options.sortBy);
|
|
533
572
|
} else {
|
|
534
573
|
teamEntries = teamDb.searchEntries(query || "", {
|
|
535
574
|
limit: perDbLimit,
|
|
@@ -541,13 +580,15 @@ function ftsSearch(query, db, teamDb, options) {
|
|
|
541
580
|
tags: options.tags,
|
|
542
581
|
entryType: options.entryType,
|
|
543
582
|
startDate: options.startDate,
|
|
544
|
-
endDate: options.endDate
|
|
583
|
+
endDate: options.endDate,
|
|
584
|
+
sortBy: options.sortBy
|
|
545
585
|
});
|
|
546
586
|
}
|
|
547
587
|
const merged = mergeAndDedup(
|
|
548
588
|
personalEntries.map((e) => ({ ...e, source: "personal" })),
|
|
549
589
|
teamEntries.map((e) => ({ ...e, source: "team" })),
|
|
550
|
-
options.limit
|
|
590
|
+
options.limit,
|
|
591
|
+
options.sortBy
|
|
551
592
|
);
|
|
552
593
|
return { entries: merged, count: merged.length };
|
|
553
594
|
}
|
|
@@ -603,7 +644,7 @@ async function hybridSearch(query, db, vectorManager, options) {
|
|
|
603
644
|
for (const id of sortedIds) {
|
|
604
645
|
const entry = entriesMap.get(id);
|
|
605
646
|
if (!entry) continue;
|
|
606
|
-
if (
|
|
647
|
+
if (!passMetadataFilters(entry, options, db)) continue;
|
|
607
648
|
entries.push({ ...entry, source: "personal" });
|
|
608
649
|
}
|
|
609
650
|
return { entries, fusionScores };
|
|
@@ -625,7 +666,8 @@ var SearchEntriesSchema = z.object({
|
|
|
625
666
|
tags: z.array(z.string()).optional(),
|
|
626
667
|
entry_type: z.enum(ENTRY_TYPES).optional(),
|
|
627
668
|
start_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional(),
|
|
628
|
-
end_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional()
|
|
669
|
+
end_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional(),
|
|
670
|
+
sort_by: z.enum(["timestamp", "importance"]).optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
629
671
|
});
|
|
630
672
|
var SearchEntriesSchemaMcp = z.object({
|
|
631
673
|
query: z.string().optional(),
|
|
@@ -642,7 +684,8 @@ var SearchEntriesSchemaMcp = z.object({
|
|
|
642
684
|
tags: z.array(z.string()).optional(),
|
|
643
685
|
entry_type: z.string().optional(),
|
|
644
686
|
start_date: z.string().optional(),
|
|
645
|
-
end_date: z.string().optional()
|
|
687
|
+
end_date: z.string().optional(),
|
|
688
|
+
sort_by: z.string().optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
646
689
|
});
|
|
647
690
|
var SearchByDateRangeSchema = z.object({
|
|
648
691
|
start_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE),
|
|
@@ -654,7 +697,8 @@ var SearchByDateRangeSchema = z.object({
|
|
|
654
697
|
issue_number: z.number().optional(),
|
|
655
698
|
pr_number: z.number().optional(),
|
|
656
699
|
workflow_run_id: z.number().optional(),
|
|
657
|
-
limit: z.number().max(MAX_QUERY_LIMIT).optional().default(500)
|
|
700
|
+
limit: z.number().max(MAX_QUERY_LIMIT).optional().default(500),
|
|
701
|
+
sort_by: z.enum(["timestamp", "importance"]).optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
658
702
|
});
|
|
659
703
|
var SearchByDateRangeSchemaMcp = z.object({
|
|
660
704
|
start_date: z.string(),
|
|
@@ -666,7 +710,8 @@ var SearchByDateRangeSchemaMcp = z.object({
|
|
|
666
710
|
issue_number: relaxedNumber().optional(),
|
|
667
711
|
pr_number: relaxedNumber().optional(),
|
|
668
712
|
workflow_run_id: relaxedNumber().optional(),
|
|
669
|
-
limit: relaxedNumber().optional().default(500)
|
|
713
|
+
limit: relaxedNumber().optional().default(500),
|
|
714
|
+
sort_by: z.string().optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
670
715
|
});
|
|
671
716
|
var SemanticSearchSchema = z.object({
|
|
672
717
|
query: z.string().optional(),
|
|
@@ -738,7 +783,9 @@ function getSearchTools(context) {
|
|
|
738
783
|
...formatHandlerError(
|
|
739
784
|
new ValidationError(
|
|
740
785
|
"Search requires either a query string or at least one filter",
|
|
741
|
-
{
|
|
786
|
+
{
|
|
787
|
+
suggestion: "Provide a search query or use get_recent_entries instead"
|
|
788
|
+
}
|
|
742
789
|
)
|
|
743
790
|
),
|
|
744
791
|
entries: [],
|
|
@@ -758,7 +805,8 @@ function getSearchTools(context) {
|
|
|
758
805
|
tags: input.tags,
|
|
759
806
|
entryType: input.entry_type,
|
|
760
807
|
startDate: input.start_date,
|
|
761
|
-
endDate: input.end_date
|
|
808
|
+
endDate: input.end_date,
|
|
809
|
+
sortBy: input.sort_by
|
|
762
810
|
};
|
|
763
811
|
switch (effectiveMode) {
|
|
764
812
|
case "semantic": {
|
|
@@ -766,9 +814,10 @@ function getSearchTools(context) {
|
|
|
766
814
|
const result = ftsSearch(input.query, db, teamDb, searchOptions);
|
|
767
815
|
return { ...result, searchMode: "fts (fallback)" };
|
|
768
816
|
}
|
|
817
|
+
const internalLimit = hasFilters ? Math.min(Math.max(input.limit * 10, 100), 1e3) : input.limit * 2;
|
|
769
818
|
const semanticResults = await vectorManager.search(
|
|
770
819
|
query,
|
|
771
|
-
|
|
820
|
+
internalLimit,
|
|
772
821
|
0.25
|
|
773
822
|
);
|
|
774
823
|
const entryIds = semanticResults.map((r) => r.entryId);
|
|
@@ -776,11 +825,31 @@ function getSearchTools(context) {
|
|
|
776
825
|
const entries = semanticResults.map((r) => {
|
|
777
826
|
const entry = entriesMap.get(r.entryId);
|
|
778
827
|
if (!entry) return null;
|
|
779
|
-
if (
|
|
828
|
+
if (!passMetadataFilters(
|
|
829
|
+
entry,
|
|
830
|
+
searchOptions,
|
|
831
|
+
db
|
|
832
|
+
))
|
|
780
833
|
return null;
|
|
781
834
|
return { ...entry, source: "personal" };
|
|
782
|
-
}).filter((e) => e !== null);
|
|
835
|
+
}).filter((e) => e !== null).slice(0, input.limit);
|
|
836
|
+
if (input.sort_by === "importance") {
|
|
837
|
+
const scored = entries.map((e) => {
|
|
838
|
+
const { score } = db.calculateImportance(e.id);
|
|
839
|
+
return { ...e, importanceScore: Math.round(score * 100) / 100 };
|
|
840
|
+
});
|
|
841
|
+
scored.sort(
|
|
842
|
+
(a, b) => (b.importanceScore ?? 0) - (a.importanceScore ?? 0)
|
|
843
|
+
);
|
|
844
|
+
return {
|
|
845
|
+
success: true,
|
|
846
|
+
entries: scored,
|
|
847
|
+
count: scored.length,
|
|
848
|
+
searchMode: isAuto ? "semantic (auto)" : "semantic"
|
|
849
|
+
};
|
|
850
|
+
}
|
|
783
851
|
return {
|
|
852
|
+
success: true,
|
|
784
853
|
entries,
|
|
785
854
|
count: entries.length,
|
|
786
855
|
searchMode: isAuto ? "semantic (auto)" : "semantic"
|
|
@@ -797,7 +866,24 @@ function getSearchTools(context) {
|
|
|
797
866
|
vectorManager,
|
|
798
867
|
searchOptions
|
|
799
868
|
);
|
|
869
|
+
if (input.sort_by === "importance") {
|
|
870
|
+
const scored = entries.map((e) => {
|
|
871
|
+
const entryId = e["id"];
|
|
872
|
+
const { score } = db.calculateImportance(entryId);
|
|
873
|
+
return { ...e, importanceScore: Math.round(score * 100) / 100 };
|
|
874
|
+
});
|
|
875
|
+
scored.sort(
|
|
876
|
+
(a, b) => (b.importanceScore ?? 0) - (a.importanceScore ?? 0)
|
|
877
|
+
);
|
|
878
|
+
return {
|
|
879
|
+
success: true,
|
|
880
|
+
entries: scored,
|
|
881
|
+
count: scored.length,
|
|
882
|
+
searchMode: isAuto ? "hybrid (auto)" : "hybrid"
|
|
883
|
+
};
|
|
884
|
+
}
|
|
800
885
|
return {
|
|
886
|
+
success: true,
|
|
801
887
|
entries,
|
|
802
888
|
count: entries.length,
|
|
803
889
|
searchMode: isAuto ? "hybrid (auto)" : "hybrid"
|
|
@@ -808,6 +894,7 @@ function getSearchTools(context) {
|
|
|
808
894
|
const result = ftsSearch(input.query, db, teamDb, searchOptions);
|
|
809
895
|
return {
|
|
810
896
|
...result,
|
|
897
|
+
success: true,
|
|
811
898
|
searchMode: isAuto ? "fts (auto)" : "fts"
|
|
812
899
|
};
|
|
813
900
|
}
|
|
@@ -847,7 +934,8 @@ function getSearchTools(context) {
|
|
|
847
934
|
issueNumber: input.issue_number,
|
|
848
935
|
prNumber: input.pr_number,
|
|
849
936
|
workflowRunId: input.workflow_run_id,
|
|
850
|
-
limit: perDbLimit
|
|
937
|
+
limit: perDbLimit,
|
|
938
|
+
sortBy: input.sort_by
|
|
851
939
|
});
|
|
852
940
|
if (teamDb && input.is_personal !== true) {
|
|
853
941
|
const teamEntries = teamDb.searchByDateRange(
|
|
@@ -860,17 +948,23 @@ function getSearchTools(context) {
|
|
|
860
948
|
issueNumber: input.issue_number,
|
|
861
949
|
prNumber: input.pr_number,
|
|
862
950
|
workflowRunId: input.workflow_run_id,
|
|
863
|
-
limit: perDbLimit
|
|
951
|
+
limit: perDbLimit,
|
|
952
|
+
sortBy: input.sort_by
|
|
864
953
|
}
|
|
865
954
|
);
|
|
866
955
|
const merged = mergeAndDedup(
|
|
867
956
|
personalEntries.map((e) => ({ ...e, source: "personal" })),
|
|
868
957
|
teamEntries.map((e) => ({ ...e, source: "team" })),
|
|
869
|
-
input.limit
|
|
958
|
+
input.limit,
|
|
959
|
+
input.sort_by
|
|
870
960
|
);
|
|
871
|
-
return { entries: merged, count: merged.length };
|
|
961
|
+
return { success: true, entries: merged, count: merged.length };
|
|
872
962
|
}
|
|
873
|
-
return {
|
|
963
|
+
return {
|
|
964
|
+
success: true,
|
|
965
|
+
entries: personalEntries,
|
|
966
|
+
count: personalEntries.length
|
|
967
|
+
};
|
|
874
968
|
} catch (err) {
|
|
875
969
|
return formatHandlerError(err);
|
|
876
970
|
}
|
|
@@ -912,17 +1006,19 @@ function getSearchTools(context) {
|
|
|
912
1006
|
count: 0
|
|
913
1007
|
};
|
|
914
1008
|
}
|
|
1009
|
+
const hasFilters = input.is_personal !== void 0 || input.tags !== void 0 || input.entry_type !== void 0 || input.start_date !== void 0 || input.end_date !== void 0;
|
|
1010
|
+
const internalLimit = hasFilters ? Math.min(Math.max(input.limit * 10, 100), 1e3) : input.limit * 2;
|
|
915
1011
|
let results;
|
|
916
1012
|
if (input.entry_id !== void 0) {
|
|
917
1013
|
results = await vectorManager.searchByEntryId(
|
|
918
1014
|
input.entry_id,
|
|
919
|
-
|
|
1015
|
+
internalLimit,
|
|
920
1016
|
input.similarity_threshold ?? 0.25
|
|
921
1017
|
);
|
|
922
1018
|
} else {
|
|
923
1019
|
results = await vectorManager.search(
|
|
924
1020
|
input.query ?? "",
|
|
925
|
-
|
|
1021
|
+
internalLimit,
|
|
926
1022
|
input.similarity_threshold ?? 0.25
|
|
927
1023
|
);
|
|
928
1024
|
}
|
|
@@ -931,29 +1027,22 @@ function getSearchTools(context) {
|
|
|
931
1027
|
const entries = results.map((r) => {
|
|
932
1028
|
const entry = entriesMap.get(r.entryId);
|
|
933
1029
|
if (!entry) return null;
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1030
|
+
const filterOptions = {
|
|
1031
|
+
isPersonal: input.is_personal,
|
|
1032
|
+
tags: input.tags,
|
|
1033
|
+
entryType: input.entry_type,
|
|
1034
|
+
startDate: input.start_date,
|
|
1035
|
+
endDate: input.end_date
|
|
1036
|
+
};
|
|
1037
|
+
if (!passMetadataFilters(entry, filterOptions, db))
|
|
941
1038
|
return null;
|
|
942
|
-
if (input.start_date) {
|
|
943
|
-
const entryDate = entry.timestamp.split("T")[0] ?? "";
|
|
944
|
-
if (entryDate < input.start_date) return null;
|
|
945
|
-
}
|
|
946
|
-
if (input.end_date) {
|
|
947
|
-
const entryDate = entry.timestamp.split("T")[0] ?? "";
|
|
948
|
-
if (entryDate > input.end_date) return null;
|
|
949
|
-
}
|
|
950
1039
|
if (input.entry_id !== void 0 && entry.id === input.entry_id)
|
|
951
1040
|
return null;
|
|
952
1041
|
return {
|
|
953
1042
|
...entry,
|
|
954
1043
|
similarity: Math.round(r.score * 100) / 100
|
|
955
1044
|
};
|
|
956
|
-
}).filter((e) => e !== null);
|
|
1045
|
+
}).filter((e) => e !== null).slice(0, input.limit);
|
|
957
1046
|
const stats = vectorManager.getStats();
|
|
958
1047
|
const isIndexEmpty = stats.itemCount === 0;
|
|
959
1048
|
const includeHint = input.hint_on_empty ?? true;
|
|
@@ -962,6 +1051,7 @@ function getSearchTools(context) {
|
|
|
962
1051
|
const allNoise = entries.length > 0 && bestSimilarity < QUALITY_FLOOR2;
|
|
963
1052
|
const hint = isIndexEmpty && includeHint ? "No entries in vector index. Use rebuild_vector_index to index existing entries." : entries.length === 0 && includeHint ? `No entries matched your query above the similarity threshold (${String(input.similarity_threshold ?? 0.25)}). Try lowering similarity_threshold (e.g., 0.15) for broader matches.` : allNoise ? `Results may be noise \u2014 best similarity (${String(bestSimilarity)}) is below quality floor (${String(QUALITY_FLOOR2)}). Try a more specific query or raise similarity_threshold to filter weak matches.` : void 0;
|
|
964
1053
|
return {
|
|
1054
|
+
success: true,
|
|
965
1055
|
query: input.query,
|
|
966
1056
|
...input.entry_id !== void 0 ? { entryId: input.entry_id } : {},
|
|
967
1057
|
entries,
|
|
@@ -1120,7 +1210,7 @@ function getAnalyticsTools(context) {
|
|
|
1120
1210
|
end_date,
|
|
1121
1211
|
project_breakdown
|
|
1122
1212
|
);
|
|
1123
|
-
return { ...stats, groupBy: group_by };
|
|
1213
|
+
return { success: true, ...stats, groupBy: group_by };
|
|
1124
1214
|
} catch (err) {
|
|
1125
1215
|
return formatHandlerError(err);
|
|
1126
1216
|
}
|
|
@@ -1162,6 +1252,7 @@ function getAnalyticsTools(context) {
|
|
|
1162
1252
|
);
|
|
1163
1253
|
if (!projectsResult[0] || projectsResult[0].values.length === 0) {
|
|
1164
1254
|
return {
|
|
1255
|
+
success: true,
|
|
1165
1256
|
project_count: 0,
|
|
1166
1257
|
total_entries: 0,
|
|
1167
1258
|
projects: [],
|
|
@@ -1233,6 +1324,7 @@ function getAnalyticsTools(context) {
|
|
|
1233
1324
|
)
|
|
1234
1325
|
}));
|
|
1235
1326
|
return {
|
|
1327
|
+
success: true,
|
|
1236
1328
|
project_count: projects.length,
|
|
1237
1329
|
total_entries: totalEntries,
|
|
1238
1330
|
projects: projects.map((p) => ({
|
|
@@ -1338,6 +1430,24 @@ function getRelationshipTools(context) {
|
|
|
1338
1430
|
success: false
|
|
1339
1431
|
};
|
|
1340
1432
|
}
|
|
1433
|
+
const fromEntry = db.getEntryById(input.from_entry_id);
|
|
1434
|
+
if (!fromEntry || fromEntry.deletedAt) {
|
|
1435
|
+
return {
|
|
1436
|
+
...formatHandlerError(
|
|
1437
|
+
new ResourceNotFoundError("Entry", String(input.from_entry_id))
|
|
1438
|
+
),
|
|
1439
|
+
success: false
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
const toEntry = db.getEntryById(input.to_entry_id);
|
|
1443
|
+
if (!toEntry || toEntry.deletedAt) {
|
|
1444
|
+
return {
|
|
1445
|
+
...formatHandlerError(
|
|
1446
|
+
new ResourceNotFoundError("Entry", String(input.to_entry_id))
|
|
1447
|
+
),
|
|
1448
|
+
success: false
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1341
1451
|
const existingRelationships = db.getRelationships(input.from_entry_id);
|
|
1342
1452
|
const existing = existingRelationships.find(
|
|
1343
1453
|
(r) => r.fromEntryId === input.from_entry_id && r.toEntryId === input.to_entry_id && r.relationshipType === input.relationship_type
|
|
@@ -1400,6 +1510,9 @@ function getRelationshipTools(context) {
|
|
|
1400
1510
|
const entry = db.getEntryById(input.entry_id);
|
|
1401
1511
|
if (!entry) {
|
|
1402
1512
|
return {
|
|
1513
|
+
...formatHandlerError(
|
|
1514
|
+
new ResourceNotFoundError("Entry", String(input.entry_id))
|
|
1515
|
+
),
|
|
1403
1516
|
success: false,
|
|
1404
1517
|
entry_count: 0,
|
|
1405
1518
|
relationship_count: 0,
|
|
@@ -2612,7 +2725,8 @@ var CreateGitHubIssueWithEntryOutputSchema = z.object({
|
|
|
2612
2725
|
project: z.object({
|
|
2613
2726
|
projectNumber: z.number(),
|
|
2614
2727
|
added: z.boolean(),
|
|
2615
|
-
message: z.string(),
|
|
2728
|
+
message: z.string().optional(),
|
|
2729
|
+
error: z.string().optional(),
|
|
2616
2730
|
initialStatus: z.object({
|
|
2617
2731
|
status: z.string(),
|
|
2618
2732
|
set: z.boolean()
|
|
@@ -2643,7 +2757,8 @@ var CloseGitHubIssueWithEntryOutputSchema = z.object({
|
|
|
2643
2757
|
}).optional(),
|
|
2644
2758
|
kanban: z.object({
|
|
2645
2759
|
moved: z.boolean(),
|
|
2646
|
-
projectNumber: z.number(),
|
|
2760
|
+
projectNumber: z.number().optional(),
|
|
2761
|
+
error: z.string().optional(),
|
|
2647
2762
|
message: z.string().optional()
|
|
2648
2763
|
}).optional(),
|
|
2649
2764
|
message: z.string().optional(),
|
|
@@ -2711,6 +2826,7 @@ var DeleteMilestoneOutputSchema = z.object({
|
|
|
2711
2826
|
instruction: z.string().optional()
|
|
2712
2827
|
}).extend(ErrorFieldsMixin.shape);
|
|
2713
2828
|
var RepoInsightsOutputSchema = z.object({
|
|
2829
|
+
success: z.boolean().optional(),
|
|
2714
2830
|
owner: z.string().optional(),
|
|
2715
2831
|
repo: z.string().optional(),
|
|
2716
2832
|
section: z.string().optional(),
|
|
@@ -4304,6 +4420,7 @@ function getGitHubInsightsTools(context) {
|
|
|
4304
4420
|
const repo = resolved.repo;
|
|
4305
4421
|
const section = input.sections;
|
|
4306
4422
|
const result = {
|
|
4423
|
+
success: true,
|
|
4307
4424
|
owner,
|
|
4308
4425
|
repo,
|
|
4309
4426
|
section
|
|
@@ -4664,20 +4781,24 @@ var TeamCreateEntrySchemaMcp = z.object({
|
|
|
4664
4781
|
author: z.string().optional()
|
|
4665
4782
|
});
|
|
4666
4783
|
var TeamGetRecentSchema = z.object({
|
|
4667
|
-
limit: z.number().min(1).max(500).optional().default(10)
|
|
4784
|
+
limit: z.number().min(1).max(500).optional().default(10),
|
|
4785
|
+
sort_by: z.enum(["timestamp", "importance"]).optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
4668
4786
|
});
|
|
4669
4787
|
var TeamGetRecentSchemaMcp = z.object({
|
|
4670
|
-
limit: relaxedNumber().optional().default(10)
|
|
4788
|
+
limit: relaxedNumber().optional().default(10),
|
|
4789
|
+
sort_by: z.string().optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
4671
4790
|
});
|
|
4672
4791
|
var TeamSearchSchema = z.object({
|
|
4673
4792
|
query: z.string().optional(),
|
|
4674
4793
|
tags: z.array(z.string()).optional(),
|
|
4675
|
-
limit: z.number().max(500).optional().default(10)
|
|
4794
|
+
limit: z.number().max(500).optional().default(10),
|
|
4795
|
+
sort_by: z.enum(["timestamp", "importance"]).optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
4676
4796
|
});
|
|
4677
4797
|
var TeamSearchSchemaMcp = z.object({
|
|
4678
4798
|
query: z.string().optional(),
|
|
4679
4799
|
tags: z.array(z.string()).optional(),
|
|
4680
|
-
limit: relaxedNumber().optional().default(10)
|
|
4800
|
+
limit: relaxedNumber().optional().default(10),
|
|
4801
|
+
sort_by: z.string().optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
4681
4802
|
});
|
|
4682
4803
|
var TeamGetEntryByIdSchema = z.object({
|
|
4683
4804
|
entry_id: z.number(),
|
|
@@ -4692,14 +4813,16 @@ var TeamSearchByDateRangeSchema = z.object({
|
|
|
4692
4813
|
end_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE),
|
|
4693
4814
|
entry_type: z.enum(ENTRY_TYPES).optional(),
|
|
4694
4815
|
tags: z.array(z.string()).optional(),
|
|
4695
|
-
limit: z.number().max(500).optional().default(50)
|
|
4816
|
+
limit: z.number().max(500).optional().default(50),
|
|
4817
|
+
sort_by: z.enum(["timestamp", "importance"]).optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
4696
4818
|
});
|
|
4697
4819
|
var TeamSearchByDateRangeSchemaMcp = z.object({
|
|
4698
4820
|
start_date: z.string().optional().describe("Start date (YYYY-MM-DD)"),
|
|
4699
4821
|
end_date: z.string().optional().describe("End date (YYYY-MM-DD)"),
|
|
4700
4822
|
entry_type: z.string().optional(),
|
|
4701
4823
|
tags: z.array(z.string()).optional(),
|
|
4702
|
-
limit: relaxedNumber().optional().default(50)
|
|
4824
|
+
limit: relaxedNumber().optional().default(50),
|
|
4825
|
+
sort_by: z.string().optional().default("timestamp").describe("Sort results by timestamp (default) or importance score")
|
|
4703
4826
|
});
|
|
4704
4827
|
var TeamUpdateEntrySchema = z.object({
|
|
4705
4828
|
entry_id: z.number(),
|
|
@@ -4891,6 +5014,10 @@ var TeamSemanticSearchSchema = z.object({
|
|
|
4891
5014
|
entry_id: z.number().optional().describe("Find entries related to this entry ID"),
|
|
4892
5015
|
limit: z.number().max(500).optional().default(10),
|
|
4893
5016
|
similarity_threshold: z.number().optional().default(0.25),
|
|
5017
|
+
tags: z.array(z.string()).optional(),
|
|
5018
|
+
entry_type: z.enum(ENTRY_TYPES).optional(),
|
|
5019
|
+
start_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional(),
|
|
5020
|
+
end_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional(),
|
|
4894
5021
|
hint_on_empty: z.boolean().optional().default(true).describe("Include hint when no results found (default: true)")
|
|
4895
5022
|
});
|
|
4896
5023
|
var TeamSemanticSearchSchemaMcp = z.object({
|
|
@@ -4898,6 +5025,10 @@ var TeamSemanticSearchSchemaMcp = z.object({
|
|
|
4898
5025
|
entry_id: relaxedNumber().optional().describe("Find entries related to this entry ID"),
|
|
4899
5026
|
limit: relaxedNumber().optional().default(10),
|
|
4900
5027
|
similarity_threshold: relaxedNumber().optional().default(0.25),
|
|
5028
|
+
tags: z.array(z.string()).optional(),
|
|
5029
|
+
entry_type: z.string().optional(),
|
|
5030
|
+
start_date: z.string().optional(),
|
|
5031
|
+
end_date: z.string().optional(),
|
|
4901
5032
|
hint_on_empty: z.boolean().optional().default(true).describe("Include hint when no results found (default: true)")
|
|
4902
5033
|
});
|
|
4903
5034
|
var TeamAddToVectorIndexSchema = z.object({
|
|
@@ -4978,6 +5109,40 @@ var TeamCrossProjectInsightsOutputSchema = z.object({
|
|
|
4978
5109
|
success: z.boolean().optional(),
|
|
4979
5110
|
error: z.string().optional()
|
|
4980
5111
|
}).extend(ErrorFieldsMixin.shape);
|
|
5112
|
+
var TeamCollaborationMatrixSchema = z.object({
|
|
5113
|
+
period: z.enum(["week", "month", "quarter"]).optional().default("month").describe("Time granularity for the activity heatmap"),
|
|
5114
|
+
limit: z.number().max(100).optional().default(20).describe("Max authors to include")
|
|
5115
|
+
});
|
|
5116
|
+
var TeamCollaborationMatrixSchemaMcp = z.object({
|
|
5117
|
+
period: z.string().optional().default("month"),
|
|
5118
|
+
limit: relaxedNumber().optional().default(20)
|
|
5119
|
+
});
|
|
5120
|
+
var TeamCollaborationMatrixOutputSchema = z.object({
|
|
5121
|
+
success: z.boolean().optional(),
|
|
5122
|
+
totalAuthors: z.number().optional(),
|
|
5123
|
+
totalEntries: z.number().optional(),
|
|
5124
|
+
authorActivity: z.array(
|
|
5125
|
+
z.object({
|
|
5126
|
+
author: z.string(),
|
|
5127
|
+
period: z.string(),
|
|
5128
|
+
entryCount: z.number()
|
|
5129
|
+
})
|
|
5130
|
+
).optional(),
|
|
5131
|
+
crossAuthorLinks: z.array(
|
|
5132
|
+
z.object({
|
|
5133
|
+
fromAuthor: z.string(),
|
|
5134
|
+
toAuthor: z.string(),
|
|
5135
|
+
linkCount: z.number()
|
|
5136
|
+
})
|
|
5137
|
+
).optional(),
|
|
5138
|
+
impactFactor: z.array(
|
|
5139
|
+
z.object({
|
|
5140
|
+
author: z.string(),
|
|
5141
|
+
inboundLinks: z.number()
|
|
5142
|
+
})
|
|
5143
|
+
).optional(),
|
|
5144
|
+
error: z.string().optional()
|
|
5145
|
+
}).extend(ErrorFieldsMixin.shape);
|
|
4981
5146
|
|
|
4982
5147
|
// src/handlers/tools/team/core-tools.ts
|
|
4983
5148
|
function getTeamCoreTools(context) {
|
|
@@ -5090,8 +5255,8 @@ function getTeamCoreTools(context) {
|
|
|
5090
5255
|
if (!teamDb) {
|
|
5091
5256
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5092
5257
|
}
|
|
5093
|
-
const { limit } = TeamGetRecentSchema.parse(params);
|
|
5094
|
-
const entries = teamDb.getRecentEntries(limit);
|
|
5258
|
+
const { limit, sort_by } = TeamGetRecentSchema.parse(params);
|
|
5259
|
+
const entries = teamDb.getRecentEntries(limit, void 0, sort_by);
|
|
5095
5260
|
const authorMap = batchFetchAuthors(
|
|
5096
5261
|
teamDb,
|
|
5097
5262
|
entries.map((e) => e.id)
|
|
@@ -5147,12 +5312,16 @@ function getTeamSearchTools(context) {
|
|
|
5147
5312
|
if (!teamDb) {
|
|
5148
5313
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5149
5314
|
}
|
|
5150
|
-
const { query, tags, limit } = TeamSearchSchema.parse(params);
|
|
5315
|
+
const { query, tags, limit, sort_by } = TeamSearchSchema.parse(params);
|
|
5316
|
+
const searchLimit = tags && tags.length > 0 ? Math.min(Math.max(limit * 5, 50), 1e3) : limit;
|
|
5151
5317
|
let entries;
|
|
5152
5318
|
if (query) {
|
|
5153
|
-
entries = teamDb.searchEntries(query, {
|
|
5319
|
+
entries = teamDb.searchEntries(query, {
|
|
5320
|
+
limit: searchLimit,
|
|
5321
|
+
sortBy: sort_by
|
|
5322
|
+
});
|
|
5154
5323
|
} else {
|
|
5155
|
-
entries = teamDb.getRecentEntries(
|
|
5324
|
+
entries = teamDb.getRecentEntries(searchLimit, void 0, sort_by);
|
|
5156
5325
|
}
|
|
5157
5326
|
if (tags && tags.length > 0) {
|
|
5158
5327
|
const entryIds = entries.map((e) => e.id);
|
|
@@ -5178,6 +5347,7 @@ function getTeamSearchTools(context) {
|
|
|
5178
5347
|
});
|
|
5179
5348
|
}
|
|
5180
5349
|
}
|
|
5350
|
+
entries = entries.slice(0, limit);
|
|
5181
5351
|
const authorMap = batchFetchAuthors(
|
|
5182
5352
|
teamDb,
|
|
5183
5353
|
entries.map((e) => e.id)
|
|
@@ -5186,7 +5356,7 @@ function getTeamSearchTools(context) {
|
|
|
5186
5356
|
...e,
|
|
5187
5357
|
author: authorMap.get(e.id) ?? null
|
|
5188
5358
|
}));
|
|
5189
|
-
return { entries: enriched, count: enriched.length };
|
|
5359
|
+
return { success: true, entries: enriched, count: enriched.length };
|
|
5190
5360
|
} catch (err) {
|
|
5191
5361
|
return formatHandlerError(err);
|
|
5192
5362
|
}
|
|
@@ -5205,7 +5375,7 @@ function getTeamSearchTools(context) {
|
|
|
5205
5375
|
if (!teamDb) {
|
|
5206
5376
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5207
5377
|
}
|
|
5208
|
-
const { start_date, end_date, entry_type, tags, limit } = TeamSearchByDateRangeSchema.parse(params);
|
|
5378
|
+
const { start_date, end_date, entry_type, tags, limit, sort_by } = TeamSearchByDateRangeSchema.parse(params);
|
|
5209
5379
|
if (start_date > end_date) {
|
|
5210
5380
|
return {
|
|
5211
5381
|
success: false,
|
|
@@ -5219,7 +5389,8 @@ function getTeamSearchTools(context) {
|
|
|
5219
5389
|
const entries = teamDb.searchByDateRange(start_date, end_date, {
|
|
5220
5390
|
entryType: entry_type,
|
|
5221
5391
|
tags,
|
|
5222
|
-
limit
|
|
5392
|
+
limit,
|
|
5393
|
+
sortBy: sort_by
|
|
5223
5394
|
});
|
|
5224
5395
|
const authorMap = batchFetchAuthors(
|
|
5225
5396
|
teamDb,
|
|
@@ -5229,7 +5400,7 @@ function getTeamSearchTools(context) {
|
|
|
5229
5400
|
...e,
|
|
5230
5401
|
author: authorMap.get(e.id) ?? null
|
|
5231
5402
|
}));
|
|
5232
|
-
return { entries: enriched, count: enriched.length };
|
|
5403
|
+
return { success: true, entries: enriched, count: enriched.length };
|
|
5233
5404
|
} catch (err) {
|
|
5234
5405
|
return formatHandlerError(err);
|
|
5235
5406
|
}
|
|
@@ -5450,6 +5621,7 @@ function getTeamAnalyticsTools(context) {
|
|
|
5450
5621
|
);
|
|
5451
5622
|
if (!projectsResult[0] || projectsResult[0].values.length === 0) {
|
|
5452
5623
|
return {
|
|
5624
|
+
success: true,
|
|
5453
5625
|
project_count: 0,
|
|
5454
5626
|
total_entries: 0,
|
|
5455
5627
|
projects: [],
|
|
@@ -5526,6 +5698,7 @@ function getTeamAnalyticsTools(context) {
|
|
|
5526
5698
|
)
|
|
5527
5699
|
}));
|
|
5528
5700
|
return {
|
|
5701
|
+
success: true,
|
|
5529
5702
|
project_count: projects.length,
|
|
5530
5703
|
total_entries: totalEntries,
|
|
5531
5704
|
projects: projects.map((p) => ({
|
|
@@ -5540,6 +5713,97 @@ function getTeamAnalyticsTools(context) {
|
|
|
5540
5713
|
return formatHandlerError(err);
|
|
5541
5714
|
}
|
|
5542
5715
|
}
|
|
5716
|
+
},
|
|
5717
|
+
{
|
|
5718
|
+
name: "team_get_collaboration_matrix",
|
|
5719
|
+
title: "Team Collaboration Matrix",
|
|
5720
|
+
description: "Analyze cross-author collaboration: activity heatmap per period, cross-linking patterns between authors, and impact factor (inbound links). Requires TEAM_DB_PATH.",
|
|
5721
|
+
group: "team",
|
|
5722
|
+
inputSchema: TeamCollaborationMatrixSchemaMcp,
|
|
5723
|
+
outputSchema: TeamCollaborationMatrixOutputSchema,
|
|
5724
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
|
|
5725
|
+
handler: (params) => {
|
|
5726
|
+
try {
|
|
5727
|
+
if (!teamDb) {
|
|
5728
|
+
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5729
|
+
}
|
|
5730
|
+
const { period, limit } = TeamCollaborationMatrixSchema.parse(params);
|
|
5731
|
+
const dateFormat = period === "week" ? "%Y-W%W" : period === "quarter" ? "%Y-Q" : "%Y-%m";
|
|
5732
|
+
const activityResult = teamDb.executeRawQuery(
|
|
5733
|
+
`SELECT
|
|
5734
|
+
COALESCE(author, 'unknown') AS author,
|
|
5735
|
+
strftime('${dateFormat}', timestamp) AS period,
|
|
5736
|
+
COUNT(*) AS entry_count
|
|
5737
|
+
FROM memory_journal
|
|
5738
|
+
WHERE deleted_at IS NULL
|
|
5739
|
+
GROUP BY author, period
|
|
5740
|
+
ORDER BY period DESC, entry_count DESC
|
|
5741
|
+
LIMIT ?`,
|
|
5742
|
+
[limit * 10]
|
|
5743
|
+
// Up to 10 periods per author
|
|
5744
|
+
);
|
|
5745
|
+
const authorActivity = activityResult[0]?.values.map((row) => ({
|
|
5746
|
+
author: row[0],
|
|
5747
|
+
period: row[1],
|
|
5748
|
+
entryCount: row[2]
|
|
5749
|
+
})) ?? [];
|
|
5750
|
+
const crossLinkResult = teamDb.executeRawQuery(
|
|
5751
|
+
`SELECT
|
|
5752
|
+
COALESCE(m1.author, 'unknown') AS from_author,
|
|
5753
|
+
COALESCE(m2.author, 'unknown') AS to_author,
|
|
5754
|
+
COUNT(*) AS link_count
|
|
5755
|
+
FROM relationships r
|
|
5756
|
+
JOIN memory_journal m1 ON r.from_entry_id = m1.id
|
|
5757
|
+
JOIN memory_journal m2 ON r.to_entry_id = m2.id
|
|
5758
|
+
WHERE m1.deleted_at IS NULL AND m2.deleted_at IS NULL
|
|
5759
|
+
AND COALESCE(m1.author, 'unknown') != COALESCE(m2.author, 'unknown')
|
|
5760
|
+
GROUP BY from_author, to_author
|
|
5761
|
+
ORDER BY link_count DESC
|
|
5762
|
+
LIMIT ?`,
|
|
5763
|
+
[limit]
|
|
5764
|
+
);
|
|
5765
|
+
const crossAuthorLinks = crossLinkResult[0]?.values.map((row) => ({
|
|
5766
|
+
fromAuthor: row[0],
|
|
5767
|
+
toAuthor: row[1],
|
|
5768
|
+
linkCount: row[2]
|
|
5769
|
+
})) ?? [];
|
|
5770
|
+
const impactResult = teamDb.executeRawQuery(
|
|
5771
|
+
`SELECT
|
|
5772
|
+
COALESCE(m2.author, 'unknown') AS author,
|
|
5773
|
+
COUNT(*) AS inbound_links
|
|
5774
|
+
FROM relationships r
|
|
5775
|
+
JOIN memory_journal m2 ON r.to_entry_id = m2.id
|
|
5776
|
+
WHERE m2.deleted_at IS NULL
|
|
5777
|
+
GROUP BY author
|
|
5778
|
+
ORDER BY inbound_links DESC
|
|
5779
|
+
LIMIT ?`,
|
|
5780
|
+
[limit]
|
|
5781
|
+
);
|
|
5782
|
+
const impactFactor = impactResult[0]?.values.map((row) => ({
|
|
5783
|
+
author: row[0],
|
|
5784
|
+
inboundLinks: row[1]
|
|
5785
|
+
})) ?? [];
|
|
5786
|
+
const totalsResult = teamDb.executeRawQuery(
|
|
5787
|
+
`SELECT
|
|
5788
|
+
COUNT(DISTINCT COALESCE(author, 'unknown')) AS total_authors,
|
|
5789
|
+
COUNT(*) AS total_entries
|
|
5790
|
+
FROM memory_journal
|
|
5791
|
+
WHERE deleted_at IS NULL`
|
|
5792
|
+
);
|
|
5793
|
+
const totalAuthors = totalsResult[0]?.values[0]?.[0] ?? 0;
|
|
5794
|
+
const totalEntries = totalsResult[0]?.values[0]?.[1] ?? 0;
|
|
5795
|
+
return {
|
|
5796
|
+
success: true,
|
|
5797
|
+
totalAuthors,
|
|
5798
|
+
totalEntries,
|
|
5799
|
+
authorActivity,
|
|
5800
|
+
crossAuthorLinks,
|
|
5801
|
+
impactFactor
|
|
5802
|
+
};
|
|
5803
|
+
} catch (err) {
|
|
5804
|
+
return formatHandlerError(err);
|
|
5805
|
+
}
|
|
5806
|
+
}
|
|
5543
5807
|
}
|
|
5544
5808
|
];
|
|
5545
5809
|
}
|
|
@@ -5638,6 +5902,17 @@ function getTeamRelationshipTools(context) {
|
|
|
5638
5902
|
const { entry_id, tag, depth } = TeamVisualizeRelationshipsSchema.parse(params);
|
|
5639
5903
|
let entryIds = [];
|
|
5640
5904
|
if (entry_id !== void 0) {
|
|
5905
|
+
const fromEntry = teamDb.getEntryById(entry_id);
|
|
5906
|
+
if (!fromEntry) {
|
|
5907
|
+
return {
|
|
5908
|
+
success: false,
|
|
5909
|
+
error: `Team entry ${String(entry_id)} not found`,
|
|
5910
|
+
code: "RESOURCE_NOT_FOUND",
|
|
5911
|
+
category: "resource",
|
|
5912
|
+
suggestion: "Verify the team entry ID and try again",
|
|
5913
|
+
recoverable: true
|
|
5914
|
+
};
|
|
5915
|
+
}
|
|
5641
5916
|
entryIds = [entry_id];
|
|
5642
5917
|
const visited = new Set(entryIds);
|
|
5643
5918
|
let frontier = [...entryIds];
|
|
@@ -6083,17 +6358,19 @@ function getTeamVectorTools(context) {
|
|
|
6083
6358
|
count: 0
|
|
6084
6359
|
};
|
|
6085
6360
|
}
|
|
6361
|
+
const hasFilters = input.tags !== void 0 || input.entry_type !== void 0 || input.start_date !== void 0 || input.end_date !== void 0;
|
|
6362
|
+
const internalLimit = hasFilters ? Math.min(Math.max(input.limit * 10, 100), 1e3) : input.limit * 2;
|
|
6086
6363
|
let results;
|
|
6087
6364
|
if (input.entry_id !== void 0) {
|
|
6088
6365
|
results = await teamVectorManager.searchByEntryId(
|
|
6089
6366
|
input.entry_id,
|
|
6090
|
-
|
|
6367
|
+
internalLimit,
|
|
6091
6368
|
input.similarity_threshold ?? 0.25
|
|
6092
6369
|
);
|
|
6093
6370
|
} else {
|
|
6094
6371
|
results = await teamVectorManager.search(
|
|
6095
6372
|
input.query ?? "",
|
|
6096
|
-
|
|
6373
|
+
internalLimit,
|
|
6097
6374
|
input.similarity_threshold ?? 0.25
|
|
6098
6375
|
);
|
|
6099
6376
|
}
|
|
@@ -6105,12 +6382,24 @@ function getTeamVectorTools(context) {
|
|
|
6105
6382
|
if (!entry) return null;
|
|
6106
6383
|
if (input.entry_id !== void 0 && entry.id === input.entry_id)
|
|
6107
6384
|
return null;
|
|
6385
|
+
if (!passMetadataFilters(
|
|
6386
|
+
entry,
|
|
6387
|
+
{
|
|
6388
|
+
tags: input.tags,
|
|
6389
|
+
entryType: input.entry_type,
|
|
6390
|
+
startDate: input.start_date,
|
|
6391
|
+
endDate: input.end_date
|
|
6392
|
+
},
|
|
6393
|
+
teamDb
|
|
6394
|
+
)) {
|
|
6395
|
+
return null;
|
|
6396
|
+
}
|
|
6108
6397
|
return {
|
|
6109
6398
|
...entry,
|
|
6110
6399
|
author: authorMap.get(r.entryId) ?? null,
|
|
6111
6400
|
similarity: Math.round(r.score * 100) / 100
|
|
6112
6401
|
};
|
|
6113
|
-
}).filter((e) => e !== null);
|
|
6402
|
+
}).filter((e) => e !== null).slice(0, input.limit);
|
|
6114
6403
|
const stats = teamVectorManager.getStats();
|
|
6115
6404
|
const isIndexEmpty = stats.itemCount === 0;
|
|
6116
6405
|
const includeHint = input.hint_on_empty ?? true;
|
|
@@ -6118,6 +6407,7 @@ function getTeamVectorTools(context) {
|
|
|
6118
6407
|
const allNoise = entries.length > 0 && bestSimilarity < QUALITY_FLOOR;
|
|
6119
6408
|
const hint = isIndexEmpty && includeHint ? "No entries in team vector index. Use team_rebuild_vector_index to index existing entries." : entries.length === 0 && includeHint ? `No entries matched your query above the similarity threshold (${String(input.similarity_threshold ?? 0.25)}). Try lowering similarity_threshold (e.g., 0.15) for broader matches.` : allNoise ? `Results may be noise \u2014 best similarity (${String(bestSimilarity)}) is below quality floor (${String(QUALITY_FLOOR)}). Try a more specific query or raise similarity_threshold to filter weak matches.` : void 0;
|
|
6120
6409
|
return {
|
|
6410
|
+
success: true,
|
|
6121
6411
|
query: input.query,
|
|
6122
6412
|
...input.entry_id !== void 0 ? { entryId: input.entry_id } : {},
|
|
6123
6413
|
entries,
|
|
@@ -7682,7 +7972,8 @@ var TOOL_GROUPS = {
|
|
|
7682
7972
|
"team_get_vector_index_stats",
|
|
7683
7973
|
"team_rebuild_vector_index",
|
|
7684
7974
|
"team_add_to_vector_index",
|
|
7685
|
-
"team_get_cross_project_insights"
|
|
7975
|
+
"team_get_cross_project_insights",
|
|
7976
|
+
"team_get_collaboration_matrix"
|
|
7686
7977
|
],
|
|
7687
7978
|
codemode: ["mj_execute_code"]
|
|
7688
7979
|
};
|