memory-journal-mcp 7.3.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 +68 -63
- package/dist/{chunk-CHWIPVQN.js → chunk-5ZA77VUW.js} +592 -86
- package/dist/{chunk-ZJJD2F5T.js → chunk-P5V2VY6N.js} +239 -40
- package/dist/cli.js +8 -3
- package/dist/index.d.ts +17 -2
- package/dist/index.js +2 -2
- package/dist/{tools-MNMGDTQI.js → tools-WZUENKJ6.js} +1 -1
- package/package.json +1 -1
- 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
|
@@ -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(),
|
|
@@ -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)
|
|
@@ -389,8 +392,8 @@ function getCoreTools(context) {
|
|
|
389
392
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
|
|
390
393
|
handler: (params) => {
|
|
391
394
|
try {
|
|
392
|
-
const { limit, is_personal } = GetRecentEntriesSchema.parse(params);
|
|
393
|
-
const entries = db.getRecentEntries(limit, is_personal);
|
|
395
|
+
const { limit, is_personal, sort_by } = GetRecentEntriesSchema.parse(params);
|
|
396
|
+
const entries = db.getRecentEntries(limit, is_personal, sort_by);
|
|
394
397
|
return { success: true, entries, count: entries.length };
|
|
395
398
|
} catch (err) {
|
|
396
399
|
return formatHandlerError(err);
|
|
@@ -459,10 +462,19 @@ var DEDUP_KEY_LENGTH = 200;
|
|
|
459
462
|
function calcPerDbLimit(limit, hasTeamDb) {
|
|
460
463
|
return hasTeamDb ? Math.min(limit * 2, MAX_QUERY_LIMIT) : limit;
|
|
461
464
|
}
|
|
462
|
-
function mergeAndDedup(personal, team, limit) {
|
|
465
|
+
function mergeAndDedup(personal, team, limit, sortBy = "timestamp") {
|
|
463
466
|
const seen = /* @__PURE__ */ new Set();
|
|
464
467
|
const merged = [];
|
|
465
|
-
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
|
+
});
|
|
466
478
|
for (const entry of all) {
|
|
467
479
|
const key = entry.content.slice(0, DEDUP_KEY_LENGTH);
|
|
468
480
|
if (!seen.has(key)) {
|
|
@@ -536,7 +548,7 @@ function ftsSearch(query, db, teamDb, options) {
|
|
|
536
548
|
const perDbLimit = calcPerDbLimit(options.limit, !!teamDb);
|
|
537
549
|
let personalEntries;
|
|
538
550
|
if (!query && !hasFilters) {
|
|
539
|
-
personalEntries = db.getRecentEntries(perDbLimit, options.isPersonal);
|
|
551
|
+
personalEntries = db.getRecentEntries(perDbLimit, options.isPersonal, options.sortBy);
|
|
540
552
|
} else {
|
|
541
553
|
personalEntries = db.searchEntries(query || "", {
|
|
542
554
|
limit: perDbLimit,
|
|
@@ -549,13 +561,14 @@ function ftsSearch(query, db, teamDb, options) {
|
|
|
549
561
|
tags: options.tags,
|
|
550
562
|
entryType: options.entryType,
|
|
551
563
|
startDate: options.startDate,
|
|
552
|
-
endDate: options.endDate
|
|
564
|
+
endDate: options.endDate,
|
|
565
|
+
sortBy: options.sortBy
|
|
553
566
|
});
|
|
554
567
|
}
|
|
555
568
|
if (teamDb && options.isPersonal !== true) {
|
|
556
569
|
let teamEntries;
|
|
557
570
|
if (!query && !hasFilters) {
|
|
558
|
-
teamEntries = teamDb.getRecentEntries(perDbLimit);
|
|
571
|
+
teamEntries = teamDb.getRecentEntries(perDbLimit, void 0, options.sortBy);
|
|
559
572
|
} else {
|
|
560
573
|
teamEntries = teamDb.searchEntries(query || "", {
|
|
561
574
|
limit: perDbLimit,
|
|
@@ -567,13 +580,15 @@ function ftsSearch(query, db, teamDb, options) {
|
|
|
567
580
|
tags: options.tags,
|
|
568
581
|
entryType: options.entryType,
|
|
569
582
|
startDate: options.startDate,
|
|
570
|
-
endDate: options.endDate
|
|
583
|
+
endDate: options.endDate,
|
|
584
|
+
sortBy: options.sortBy
|
|
571
585
|
});
|
|
572
586
|
}
|
|
573
587
|
const merged = mergeAndDedup(
|
|
574
588
|
personalEntries.map((e) => ({ ...e, source: "personal" })),
|
|
575
589
|
teamEntries.map((e) => ({ ...e, source: "team" })),
|
|
576
|
-
options.limit
|
|
590
|
+
options.limit,
|
|
591
|
+
options.sortBy
|
|
577
592
|
);
|
|
578
593
|
return { entries: merged, count: merged.length };
|
|
579
594
|
}
|
|
@@ -651,7 +666,8 @@ var SearchEntriesSchema = z.object({
|
|
|
651
666
|
tags: z.array(z.string()).optional(),
|
|
652
667
|
entry_type: z.enum(ENTRY_TYPES).optional(),
|
|
653
668
|
start_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE).optional(),
|
|
654
|
-
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")
|
|
655
671
|
});
|
|
656
672
|
var SearchEntriesSchemaMcp = z.object({
|
|
657
673
|
query: z.string().optional(),
|
|
@@ -668,7 +684,8 @@ var SearchEntriesSchemaMcp = z.object({
|
|
|
668
684
|
tags: z.array(z.string()).optional(),
|
|
669
685
|
entry_type: z.string().optional(),
|
|
670
686
|
start_date: z.string().optional(),
|
|
671
|
-
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")
|
|
672
689
|
});
|
|
673
690
|
var SearchByDateRangeSchema = z.object({
|
|
674
691
|
start_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE),
|
|
@@ -680,7 +697,8 @@ var SearchByDateRangeSchema = z.object({
|
|
|
680
697
|
issue_number: z.number().optional(),
|
|
681
698
|
pr_number: z.number().optional(),
|
|
682
699
|
workflow_run_id: z.number().optional(),
|
|
683
|
-
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")
|
|
684
702
|
});
|
|
685
703
|
var SearchByDateRangeSchemaMcp = z.object({
|
|
686
704
|
start_date: z.string(),
|
|
@@ -692,7 +710,8 @@ var SearchByDateRangeSchemaMcp = z.object({
|
|
|
692
710
|
issue_number: relaxedNumber().optional(),
|
|
693
711
|
pr_number: relaxedNumber().optional(),
|
|
694
712
|
workflow_run_id: relaxedNumber().optional(),
|
|
695
|
-
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")
|
|
696
715
|
});
|
|
697
716
|
var SemanticSearchSchema = z.object({
|
|
698
717
|
query: z.string().optional(),
|
|
@@ -786,7 +805,8 @@ function getSearchTools(context) {
|
|
|
786
805
|
tags: input.tags,
|
|
787
806
|
entryType: input.entry_type,
|
|
788
807
|
startDate: input.start_date,
|
|
789
|
-
endDate: input.end_date
|
|
808
|
+
endDate: input.end_date,
|
|
809
|
+
sortBy: input.sort_by
|
|
790
810
|
};
|
|
791
811
|
switch (effectiveMode) {
|
|
792
812
|
case "semantic": {
|
|
@@ -805,9 +825,29 @@ function getSearchTools(context) {
|
|
|
805
825
|
const entries = semanticResults.map((r) => {
|
|
806
826
|
const entry = entriesMap.get(r.entryId);
|
|
807
827
|
if (!entry) return null;
|
|
808
|
-
if (!passMetadataFilters(
|
|
828
|
+
if (!passMetadataFilters(
|
|
829
|
+
entry,
|
|
830
|
+
searchOptions,
|
|
831
|
+
db
|
|
832
|
+
))
|
|
833
|
+
return null;
|
|
809
834
|
return { ...entry, source: "personal" };
|
|
810
|
-
}).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
|
+
}
|
|
811
851
|
return {
|
|
812
852
|
success: true,
|
|
813
853
|
entries,
|
|
@@ -826,6 +866,22 @@ function getSearchTools(context) {
|
|
|
826
866
|
vectorManager,
|
|
827
867
|
searchOptions
|
|
828
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
|
+
}
|
|
829
885
|
return {
|
|
830
886
|
success: true,
|
|
831
887
|
entries,
|
|
@@ -878,7 +934,8 @@ function getSearchTools(context) {
|
|
|
878
934
|
issueNumber: input.issue_number,
|
|
879
935
|
prNumber: input.pr_number,
|
|
880
936
|
workflowRunId: input.workflow_run_id,
|
|
881
|
-
limit: perDbLimit
|
|
937
|
+
limit: perDbLimit,
|
|
938
|
+
sortBy: input.sort_by
|
|
882
939
|
});
|
|
883
940
|
if (teamDb && input.is_personal !== true) {
|
|
884
941
|
const teamEntries = teamDb.searchByDateRange(
|
|
@@ -891,13 +948,15 @@ function getSearchTools(context) {
|
|
|
891
948
|
issueNumber: input.issue_number,
|
|
892
949
|
prNumber: input.pr_number,
|
|
893
950
|
workflowRunId: input.workflow_run_id,
|
|
894
|
-
limit: perDbLimit
|
|
951
|
+
limit: perDbLimit,
|
|
952
|
+
sortBy: input.sort_by
|
|
895
953
|
}
|
|
896
954
|
);
|
|
897
955
|
const merged = mergeAndDedup(
|
|
898
956
|
personalEntries.map((e) => ({ ...e, source: "personal" })),
|
|
899
957
|
teamEntries.map((e) => ({ ...e, source: "team" })),
|
|
900
|
-
input.limit
|
|
958
|
+
input.limit,
|
|
959
|
+
input.sort_by
|
|
901
960
|
);
|
|
902
961
|
return { success: true, entries: merged, count: merged.length };
|
|
903
962
|
}
|
|
@@ -975,7 +1034,8 @@ function getSearchTools(context) {
|
|
|
975
1034
|
startDate: input.start_date,
|
|
976
1035
|
endDate: input.end_date
|
|
977
1036
|
};
|
|
978
|
-
if (!passMetadataFilters(entry, filterOptions, db))
|
|
1037
|
+
if (!passMetadataFilters(entry, filterOptions, db))
|
|
1038
|
+
return null;
|
|
979
1039
|
if (input.entry_id !== void 0 && entry.id === input.entry_id)
|
|
980
1040
|
return null;
|
|
981
1041
|
return {
|
|
@@ -2697,7 +2757,8 @@ var CloseGitHubIssueWithEntryOutputSchema = z.object({
|
|
|
2697
2757
|
}).optional(),
|
|
2698
2758
|
kanban: z.object({
|
|
2699
2759
|
moved: z.boolean(),
|
|
2700
|
-
projectNumber: z.number(),
|
|
2760
|
+
projectNumber: z.number().optional(),
|
|
2761
|
+
error: z.string().optional(),
|
|
2701
2762
|
message: z.string().optional()
|
|
2702
2763
|
}).optional(),
|
|
2703
2764
|
message: z.string().optional(),
|
|
@@ -4720,20 +4781,24 @@ var TeamCreateEntrySchemaMcp = z.object({
|
|
|
4720
4781
|
author: z.string().optional()
|
|
4721
4782
|
});
|
|
4722
4783
|
var TeamGetRecentSchema = z.object({
|
|
4723
|
-
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")
|
|
4724
4786
|
});
|
|
4725
4787
|
var TeamGetRecentSchemaMcp = z.object({
|
|
4726
|
-
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")
|
|
4727
4790
|
});
|
|
4728
4791
|
var TeamSearchSchema = z.object({
|
|
4729
4792
|
query: z.string().optional(),
|
|
4730
4793
|
tags: z.array(z.string()).optional(),
|
|
4731
|
-
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")
|
|
4732
4796
|
});
|
|
4733
4797
|
var TeamSearchSchemaMcp = z.object({
|
|
4734
4798
|
query: z.string().optional(),
|
|
4735
4799
|
tags: z.array(z.string()).optional(),
|
|
4736
|
-
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")
|
|
4737
4802
|
});
|
|
4738
4803
|
var TeamGetEntryByIdSchema = z.object({
|
|
4739
4804
|
entry_id: z.number(),
|
|
@@ -4748,14 +4813,16 @@ var TeamSearchByDateRangeSchema = z.object({
|
|
|
4748
4813
|
end_date: z.string().regex(DATE_FORMAT_REGEX, DATE_FORMAT_MESSAGE),
|
|
4749
4814
|
entry_type: z.enum(ENTRY_TYPES).optional(),
|
|
4750
4815
|
tags: z.array(z.string()).optional(),
|
|
4751
|
-
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")
|
|
4752
4818
|
});
|
|
4753
4819
|
var TeamSearchByDateRangeSchemaMcp = z.object({
|
|
4754
4820
|
start_date: z.string().optional().describe("Start date (YYYY-MM-DD)"),
|
|
4755
4821
|
end_date: z.string().optional().describe("End date (YYYY-MM-DD)"),
|
|
4756
4822
|
entry_type: z.string().optional(),
|
|
4757
4823
|
tags: z.array(z.string()).optional(),
|
|
4758
|
-
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")
|
|
4759
4826
|
});
|
|
4760
4827
|
var TeamUpdateEntrySchema = z.object({
|
|
4761
4828
|
entry_id: z.number(),
|
|
@@ -5042,6 +5109,40 @@ var TeamCrossProjectInsightsOutputSchema = z.object({
|
|
|
5042
5109
|
success: z.boolean().optional(),
|
|
5043
5110
|
error: z.string().optional()
|
|
5044
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);
|
|
5045
5146
|
|
|
5046
5147
|
// src/handlers/tools/team/core-tools.ts
|
|
5047
5148
|
function getTeamCoreTools(context) {
|
|
@@ -5154,8 +5255,8 @@ function getTeamCoreTools(context) {
|
|
|
5154
5255
|
if (!teamDb) {
|
|
5155
5256
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5156
5257
|
}
|
|
5157
|
-
const { limit } = TeamGetRecentSchema.parse(params);
|
|
5158
|
-
const entries = teamDb.getRecentEntries(limit);
|
|
5258
|
+
const { limit, sort_by } = TeamGetRecentSchema.parse(params);
|
|
5259
|
+
const entries = teamDb.getRecentEntries(limit, void 0, sort_by);
|
|
5159
5260
|
const authorMap = batchFetchAuthors(
|
|
5160
5261
|
teamDb,
|
|
5161
5262
|
entries.map((e) => e.id)
|
|
@@ -5211,13 +5312,16 @@ function getTeamSearchTools(context) {
|
|
|
5211
5312
|
if (!teamDb) {
|
|
5212
5313
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5213
5314
|
}
|
|
5214
|
-
const { query, tags, limit } = TeamSearchSchema.parse(params);
|
|
5215
|
-
const searchLimit = tags && tags.length > 0 ? Math.max(limit * 5, 50) : limit;
|
|
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;
|
|
5216
5317
|
let entries;
|
|
5217
5318
|
if (query) {
|
|
5218
|
-
entries = teamDb.searchEntries(query, {
|
|
5319
|
+
entries = teamDb.searchEntries(query, {
|
|
5320
|
+
limit: searchLimit,
|
|
5321
|
+
sortBy: sort_by
|
|
5322
|
+
});
|
|
5219
5323
|
} else {
|
|
5220
|
-
entries = teamDb.getRecentEntries(searchLimit);
|
|
5324
|
+
entries = teamDb.getRecentEntries(searchLimit, void 0, sort_by);
|
|
5221
5325
|
}
|
|
5222
5326
|
if (tags && tags.length > 0) {
|
|
5223
5327
|
const entryIds = entries.map((e) => e.id);
|
|
@@ -5271,7 +5375,7 @@ function getTeamSearchTools(context) {
|
|
|
5271
5375
|
if (!teamDb) {
|
|
5272
5376
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5273
5377
|
}
|
|
5274
|
-
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);
|
|
5275
5379
|
if (start_date > end_date) {
|
|
5276
5380
|
return {
|
|
5277
5381
|
success: false,
|
|
@@ -5285,7 +5389,8 @@ function getTeamSearchTools(context) {
|
|
|
5285
5389
|
const entries = teamDb.searchByDateRange(start_date, end_date, {
|
|
5286
5390
|
entryType: entry_type,
|
|
5287
5391
|
tags,
|
|
5288
|
-
limit
|
|
5392
|
+
limit,
|
|
5393
|
+
sortBy: sort_by
|
|
5289
5394
|
});
|
|
5290
5395
|
const authorMap = batchFetchAuthors(
|
|
5291
5396
|
teamDb,
|
|
@@ -5516,6 +5621,7 @@ function getTeamAnalyticsTools(context) {
|
|
|
5516
5621
|
);
|
|
5517
5622
|
if (!projectsResult[0] || projectsResult[0].values.length === 0) {
|
|
5518
5623
|
return {
|
|
5624
|
+
success: true,
|
|
5519
5625
|
project_count: 0,
|
|
5520
5626
|
total_entries: 0,
|
|
5521
5627
|
projects: [],
|
|
@@ -5592,6 +5698,7 @@ function getTeamAnalyticsTools(context) {
|
|
|
5592
5698
|
)
|
|
5593
5699
|
}));
|
|
5594
5700
|
return {
|
|
5701
|
+
success: true,
|
|
5595
5702
|
project_count: projects.length,
|
|
5596
5703
|
total_entries: totalEntries,
|
|
5597
5704
|
projects: projects.map((p) => ({
|
|
@@ -5606,6 +5713,97 @@ function getTeamAnalyticsTools(context) {
|
|
|
5606
5713
|
return formatHandlerError(err);
|
|
5607
5714
|
}
|
|
5608
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
|
+
}
|
|
5609
5807
|
}
|
|
5610
5808
|
];
|
|
5611
5809
|
}
|
|
@@ -7774,7 +7972,8 @@ var TOOL_GROUPS = {
|
|
|
7774
7972
|
"team_get_vector_index_stats",
|
|
7775
7973
|
"team_rebuild_vector_index",
|
|
7776
7974
|
"team_add_to_vector_index",
|
|
7777
|
-
"team_get_cross_project_insights"
|
|
7975
|
+
"team_get_cross_project_insights",
|
|
7976
|
+
"team_get_collaboration_matrix"
|
|
7778
7977
|
],
|
|
7779
7978
|
codemode: ["mj_execute_code"]
|
|
7780
7979
|
};
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { VERSION, createServer } from './chunk-
|
|
2
|
-
import { DEFAULT_AUDIT_LOG_MAX_SIZE_BYTES } from './chunk-
|
|
1
|
+
import { VERSION, createServer } from './chunk-5ZA77VUW.js';
|
|
2
|
+
import { DEFAULT_AUDIT_LOG_MAX_SIZE_BYTES } from './chunk-P5V2VY6N.js';
|
|
3
3
|
import './chunk-OKOVZ5QE.js';
|
|
4
4
|
import { logger } from './chunk-WXDEVIFL.js';
|
|
5
5
|
import { Command } from 'commander';
|
|
@@ -35,6 +35,10 @@ program.name("memory-journal-mcp").description("Project context management for A
|
|
|
35
35
|
"--rebuild-index-interval <minutes>",
|
|
36
36
|
"Vector index rebuild interval in minutes, HTTP only (0 = disabled)",
|
|
37
37
|
"0"
|
|
38
|
+
).option(
|
|
39
|
+
"--digest-interval <minutes>",
|
|
40
|
+
"Analytics digest interval in minutes, HTTP only (0 = disabled; recommended: 1440 for daily)",
|
|
41
|
+
"0"
|
|
38
42
|
).option(
|
|
39
43
|
"--sandbox-mode <mode>",
|
|
40
44
|
'Code Mode sandbox: "worker" (production, default) or "vm" (lightweight)',
|
|
@@ -150,7 +154,8 @@ program.name("memory-journal-mcp").description("Project context management for A
|
|
|
150
154
|
backupIntervalMinutes: parseInt(options.backupInterval, 10),
|
|
151
155
|
keepBackups: parseInt(options.keepBackups, 10),
|
|
152
156
|
vacuumIntervalMinutes: parseInt(options.vacuumInterval, 10),
|
|
153
|
-
rebuildIndexIntervalMinutes: parseInt(options.rebuildIndexInterval, 10)
|
|
157
|
+
rebuildIndexIntervalMinutes: parseInt(options.rebuildIndexInterval, 10),
|
|
158
|
+
digestIntervalMinutes: parseInt(options.digestInterval, 10)
|
|
154
159
|
},
|
|
155
160
|
sandboxMode: options.sandboxMode,
|
|
156
161
|
// OAuth 2.1
|
package/dist/index.d.ts
CHANGED
|
@@ -383,7 +383,7 @@ interface IDatabaseAdapter {
|
|
|
383
383
|
getEntryByIdIncludeDeleted(id: number): JournalEntry | null;
|
|
384
384
|
getEntriesByIds(ids: number[]): Map<number, JournalEntry>;
|
|
385
385
|
calculateImportance(entryId: number): ImportanceResult;
|
|
386
|
-
getRecentEntries(limit?: number, isPersonal?: boolean): JournalEntry[];
|
|
386
|
+
getRecentEntries(limit?: number, isPersonal?: boolean, sortBy?: 'timestamp' | 'importance'): JournalEntry[];
|
|
387
387
|
getEntriesPage(offset: number, limit: number): JournalEntry[];
|
|
388
388
|
getActiveEntryCount(): number;
|
|
389
389
|
updateEntry(id: number, updates: {
|
|
@@ -405,6 +405,7 @@ interface IDatabaseAdapter {
|
|
|
405
405
|
entryType?: EntryType;
|
|
406
406
|
startDate?: string;
|
|
407
407
|
endDate?: string;
|
|
408
|
+
sortBy?: 'timestamp' | 'importance';
|
|
408
409
|
}): JournalEntry[];
|
|
409
410
|
searchByDateRange(startDate: string, endDate: string, options?: {
|
|
410
411
|
entryType?: EntryType;
|
|
@@ -415,6 +416,7 @@ interface IDatabaseAdapter {
|
|
|
415
416
|
prNumber?: number;
|
|
416
417
|
workflowRunId?: number;
|
|
417
418
|
limit?: number;
|
|
419
|
+
sortBy?: 'timestamp' | 'importance';
|
|
418
420
|
}): JournalEntry[];
|
|
419
421
|
getStatistics(groupBy?: 'day' | 'week' | 'month' | 'year', startDate?: string, endDate?: string, projectBreakdown?: boolean): Record<string, unknown>;
|
|
420
422
|
getTagsForEntry(entryId: number): string[];
|
|
@@ -468,6 +470,17 @@ interface IDatabaseAdapter {
|
|
|
468
470
|
getRawDb(): unknown;
|
|
469
471
|
pragma(command: string): void;
|
|
470
472
|
executeRawQuery(sql: string, params?: unknown[]): QueryResult[];
|
|
473
|
+
saveAnalyticsSnapshot(type: string, data: Record<string, unknown>): number;
|
|
474
|
+
getLatestAnalyticsSnapshot(type: string): {
|
|
475
|
+
id: number;
|
|
476
|
+
createdAt: string;
|
|
477
|
+
data: Record<string, unknown>;
|
|
478
|
+
} | null;
|
|
479
|
+
getAnalyticsSnapshots(type: string, limit?: number): {
|
|
480
|
+
id: number;
|
|
481
|
+
createdAt: string;
|
|
482
|
+
data: Record<string, unknown>;
|
|
483
|
+
}[];
|
|
471
484
|
}
|
|
472
485
|
|
|
473
486
|
/**
|
|
@@ -488,6 +501,8 @@ interface SchedulerOptions {
|
|
|
488
501
|
vacuumIntervalMinutes: number;
|
|
489
502
|
/** Vector index rebuild interval in minutes (0 = disabled) */
|
|
490
503
|
rebuildIndexIntervalMinutes: number;
|
|
504
|
+
/** Analytics digest interval in minutes (0 = disabled; recommended: 1440 for daily) */
|
|
505
|
+
digestIntervalMinutes: number;
|
|
491
506
|
}
|
|
492
507
|
|
|
493
508
|
/**
|
|
@@ -510,7 +525,7 @@ type SandboxMode = 'vm' | 'worker';
|
|
|
510
525
|
/**
|
|
511
526
|
* Tool group definitions mapping group names to tool names
|
|
512
527
|
*
|
|
513
|
-
* All
|
|
528
|
+
* All 68 tools are categorized here for filtering support.
|
|
514
529
|
*/
|
|
515
530
|
declare const TOOL_GROUPS: Record<ToolGroup, string[]>;
|
|
516
531
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { VERSION, createServer } from './chunk-
|
|
2
|
-
export { META_GROUPS, TOOL_GROUPS, calculateTokenSavings, filterTools, getAllToolNames, getFilterSummary, getToolFilterFromEnv, getToolGroup, isToolEnabled, parseToolFilter } from './chunk-
|
|
1
|
+
export { VERSION, createServer } from './chunk-5ZA77VUW.js';
|
|
2
|
+
export { META_GROUPS, TOOL_GROUPS, calculateTokenSavings, filterTools, getAllToolNames, getFilterSummary, getToolFilterFromEnv, getToolGroup, isToolEnabled, parseToolFilter } from './chunk-P5V2VY6N.js';
|
|
3
3
|
import './chunk-OKOVZ5QE.js';
|
|
4
4
|
export { logger } from './chunk-WXDEVIFL.js';
|
|
5
5
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory-journal-mcp",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.0",
|
|
4
4
|
"description": "Project context management for AI-assisted development - Persistent knowledge graphs and intelligent context recall across fragmented AI threads",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
package/skills/README.md
CHANGED
|
@@ -42,18 +42,22 @@ The markdown body contains the full instructions the agent follows once the skil
|
|
|
42
42
|
| ---------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
43
43
|
| `autonomous-dev` | Harness for autonomous software development — alignment gates, adversarial agents, Git workflows, and CI/CD pipelines |
|
|
44
44
|
| `bun` | Master the Bun all-in-one toolkit — runtime, package manager, test runner, and bundler |
|
|
45
|
+
| `docker` | Production-grade Docker — multi-stage builds, security hardening, Compose v2, BuildKit, and CI/CD integration |
|
|
46
|
+
| `github-actions` | GitHub Actions CI/CD — SHA pinning, reusable workflows, caching, matrix strategies, and artifacts v4 |
|
|
45
47
|
| `github-commander` | GitHub pipeline workflows for orchestrating issues, regressions, and deployments |
|
|
46
48
|
| `gitlab` | Specialized assistant skill for managing repositories, code search, and CI/CD in GitLab |
|
|
47
49
|
| `golang` | Master Go development with production-grade best practices from Google and Uber style guides |
|
|
48
|
-
| `typescript` | Enterprise-grade TypeScript development with type-safe patterns, Zod validation, and modern tooling |
|
|
49
50
|
| `mysql` | Enterprise MySQL production rules — query safety, connection pooling, strict schema configurations |
|
|
50
51
|
| `playwright-standard` | Opinionated guidance for Playwright E2E/API tests, Page Object Models, and CI/CD resilience |
|
|
51
52
|
| `postgres` | Advanced PostgreSQL patterns — indexing layouts, JSONB querying, transactional guardrails, and RLS |
|
|
53
|
+
| `python` | Modern Python engineering — uv, ruff, type hints, pytest, Pydantic v2, and src/ layout project structure |
|
|
52
54
|
| `react-best-practices` | Vercel engineering guidelines for React/Next.js performance, hooks, and bundle optimization |
|
|
53
55
|
| `rust` | Master Rust development using a layer-based "meta-cognition" framework for borrowing, lifetimes, and architecture |
|
|
54
56
|
| `shadcn-ui` | Deep knowledge of shadcn/ui components, patterns, forms, and best practices |
|
|
55
57
|
| `skill-builder` | Guide for creating, evaluating, and refining agent skills — progressive disclosure, triggers, and testing |
|
|
56
58
|
| `sqlite` | Production configurations for concurrency (WAL), typing (STRICT), and data integrity |
|
|
59
|
+
| `tailwind-css` | Tailwind CSS v4 — CSS-first configuration, @theme directive, dark mode, responsive design, and v3 migration |
|
|
60
|
+
| `typescript` | Enterprise-grade TypeScript development with type-safe patterns, Zod validation, and modern tooling |
|
|
57
61
|
| `vitest-standard` | Comprehensive unit testing expertise covering Vitest, TDD, mocking strategies, and test architecture |
|
|
58
62
|
|
|
59
63
|
## GitHub Commander Workflows
|