@velvetmonkey/flywheel-crank 0.7.2 → 0.8.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/index.js +474 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -179,7 +179,29 @@ function insertInSection(content, section, newContent, position, options) {
|
|
|
179
179
|
const lines = content.split("\n");
|
|
180
180
|
const formattedContent = newContent.trim();
|
|
181
181
|
if (position === "prepend") {
|
|
182
|
-
|
|
182
|
+
if (options?.preserveListNesting) {
|
|
183
|
+
let indent = "";
|
|
184
|
+
for (let i = section.contentStartLine; i <= section.endLine; i++) {
|
|
185
|
+
const line = lines[i];
|
|
186
|
+
const trimmed = line.trim();
|
|
187
|
+
if (trimmed === "")
|
|
188
|
+
continue;
|
|
189
|
+
const listMatch = line.match(/^(\s*)[-*+]\s|^(\s*)\d+\.\s|^(\s*)[-*+]\s*\[[ xX]\]/);
|
|
190
|
+
if (listMatch) {
|
|
191
|
+
indent = listMatch[1] || listMatch[2] || listMatch[3] || "";
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
if (indent) {
|
|
197
|
+
const indentedContent = formattedContent.split("\n").map((line) => indent + line).join("\n");
|
|
198
|
+
lines.splice(section.contentStartLine, 0, indentedContent);
|
|
199
|
+
} else {
|
|
200
|
+
lines.splice(section.contentStartLine, 0, formattedContent);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
lines.splice(section.contentStartLine, 0, formattedContent);
|
|
204
|
+
}
|
|
183
205
|
} else {
|
|
184
206
|
let lastContentLineIdx = -1;
|
|
185
207
|
for (let i = section.endLine; i >= section.contentStartLine; i--) {
|
|
@@ -496,6 +518,7 @@ import path4 from "path";
|
|
|
496
518
|
|
|
497
519
|
// src/core/stemmer.ts
|
|
498
520
|
var STOPWORDS = /* @__PURE__ */ new Set([
|
|
521
|
+
// Articles, pronouns, prepositions (basic)
|
|
499
522
|
"the",
|
|
500
523
|
"a",
|
|
501
524
|
"an",
|
|
@@ -596,11 +619,385 @@ var STOPWORDS = /* @__PURE__ */ new Set([
|
|
|
596
619
|
"there",
|
|
597
620
|
"any",
|
|
598
621
|
"now",
|
|
599
|
-
"new",
|
|
600
622
|
"even",
|
|
601
623
|
"much",
|
|
602
624
|
"back",
|
|
603
|
-
|
|
625
|
+
// Common verbs (critical for reducing false positives)
|
|
626
|
+
// These create matches like "Completed" → "Complete Guide"
|
|
627
|
+
"going",
|
|
628
|
+
"went",
|
|
629
|
+
"gone",
|
|
630
|
+
"come",
|
|
631
|
+
"came",
|
|
632
|
+
"coming",
|
|
633
|
+
"work",
|
|
634
|
+
"worked",
|
|
635
|
+
"working",
|
|
636
|
+
"works",
|
|
637
|
+
"make",
|
|
638
|
+
"made",
|
|
639
|
+
"making",
|
|
640
|
+
"makes",
|
|
641
|
+
"take",
|
|
642
|
+
"took",
|
|
643
|
+
"taken",
|
|
644
|
+
"taking",
|
|
645
|
+
"takes",
|
|
646
|
+
"give",
|
|
647
|
+
"gave",
|
|
648
|
+
"given",
|
|
649
|
+
"giving",
|
|
650
|
+
"gives",
|
|
651
|
+
"find",
|
|
652
|
+
"found",
|
|
653
|
+
"finding",
|
|
654
|
+
"finds",
|
|
655
|
+
"know",
|
|
656
|
+
"knew",
|
|
657
|
+
"known",
|
|
658
|
+
"knowing",
|
|
659
|
+
"knows",
|
|
660
|
+
"think",
|
|
661
|
+
"thought",
|
|
662
|
+
"thinking",
|
|
663
|
+
"thinks",
|
|
664
|
+
"look",
|
|
665
|
+
"looked",
|
|
666
|
+
"looking",
|
|
667
|
+
"looks",
|
|
668
|
+
"want",
|
|
669
|
+
"wanted",
|
|
670
|
+
"wanting",
|
|
671
|
+
"wants",
|
|
672
|
+
"tell",
|
|
673
|
+
"told",
|
|
674
|
+
"telling",
|
|
675
|
+
"tells",
|
|
676
|
+
"keep",
|
|
677
|
+
"kept",
|
|
678
|
+
"keeping",
|
|
679
|
+
"keeps",
|
|
680
|
+
"start",
|
|
681
|
+
"started",
|
|
682
|
+
"starting",
|
|
683
|
+
"starts",
|
|
684
|
+
"complete",
|
|
685
|
+
"completed",
|
|
686
|
+
"completing",
|
|
687
|
+
"completes",
|
|
688
|
+
"finish",
|
|
689
|
+
"finished",
|
|
690
|
+
"finishing",
|
|
691
|
+
"finishes",
|
|
692
|
+
"begin",
|
|
693
|
+
"began",
|
|
694
|
+
"begun",
|
|
695
|
+
"beginning",
|
|
696
|
+
"begins",
|
|
697
|
+
"end",
|
|
698
|
+
"ended",
|
|
699
|
+
"ending",
|
|
700
|
+
"ends",
|
|
701
|
+
"add",
|
|
702
|
+
"added",
|
|
703
|
+
"adding",
|
|
704
|
+
"adds",
|
|
705
|
+
"update",
|
|
706
|
+
"updated",
|
|
707
|
+
"updating",
|
|
708
|
+
"updates",
|
|
709
|
+
"change",
|
|
710
|
+
"changed",
|
|
711
|
+
"changing",
|
|
712
|
+
"changes",
|
|
713
|
+
"remove",
|
|
714
|
+
"removed",
|
|
715
|
+
"removing",
|
|
716
|
+
"removes",
|
|
717
|
+
"fix",
|
|
718
|
+
"fixed",
|
|
719
|
+
"fixing",
|
|
720
|
+
"fixes",
|
|
721
|
+
"create",
|
|
722
|
+
"created",
|
|
723
|
+
"creating",
|
|
724
|
+
"creates",
|
|
725
|
+
"build",
|
|
726
|
+
"built",
|
|
727
|
+
"building",
|
|
728
|
+
"builds",
|
|
729
|
+
"run",
|
|
730
|
+
"ran",
|
|
731
|
+
"running",
|
|
732
|
+
"runs",
|
|
733
|
+
"test",
|
|
734
|
+
"tested",
|
|
735
|
+
"testing",
|
|
736
|
+
"tests",
|
|
737
|
+
"release",
|
|
738
|
+
"released",
|
|
739
|
+
"releasing",
|
|
740
|
+
"releases",
|
|
741
|
+
"use",
|
|
742
|
+
"used",
|
|
743
|
+
"using",
|
|
744
|
+
"uses",
|
|
745
|
+
"get",
|
|
746
|
+
"got",
|
|
747
|
+
"gotten",
|
|
748
|
+
"getting",
|
|
749
|
+
"gets",
|
|
750
|
+
"set",
|
|
751
|
+
"setting",
|
|
752
|
+
"sets",
|
|
753
|
+
"put",
|
|
754
|
+
"putting",
|
|
755
|
+
"puts",
|
|
756
|
+
"try",
|
|
757
|
+
"tried",
|
|
758
|
+
"trying",
|
|
759
|
+
"tries",
|
|
760
|
+
"move",
|
|
761
|
+
"moved",
|
|
762
|
+
"moving",
|
|
763
|
+
"moves",
|
|
764
|
+
"show",
|
|
765
|
+
"showed",
|
|
766
|
+
"shown",
|
|
767
|
+
"showing",
|
|
768
|
+
"shows",
|
|
769
|
+
"help",
|
|
770
|
+
"helped",
|
|
771
|
+
"helping",
|
|
772
|
+
"helps",
|
|
773
|
+
"read",
|
|
774
|
+
"reading",
|
|
775
|
+
"reads",
|
|
776
|
+
"write",
|
|
777
|
+
"wrote",
|
|
778
|
+
"written",
|
|
779
|
+
"writing",
|
|
780
|
+
"writes",
|
|
781
|
+
"call",
|
|
782
|
+
"called",
|
|
783
|
+
"calling",
|
|
784
|
+
"calls",
|
|
785
|
+
"feel",
|
|
786
|
+
"felt",
|
|
787
|
+
"feeling",
|
|
788
|
+
"feels",
|
|
789
|
+
"seem",
|
|
790
|
+
"seemed",
|
|
791
|
+
"seeming",
|
|
792
|
+
"seems",
|
|
793
|
+
"turn",
|
|
794
|
+
"turned",
|
|
795
|
+
"turning",
|
|
796
|
+
"turns",
|
|
797
|
+
"leave",
|
|
798
|
+
"left",
|
|
799
|
+
"leaving",
|
|
800
|
+
"leaves",
|
|
801
|
+
"play",
|
|
802
|
+
"played",
|
|
803
|
+
"playing",
|
|
804
|
+
"plays",
|
|
805
|
+
"hold",
|
|
806
|
+
"held",
|
|
807
|
+
"holding",
|
|
808
|
+
"holds",
|
|
809
|
+
"bring",
|
|
810
|
+
"brought",
|
|
811
|
+
"bringing",
|
|
812
|
+
"brings",
|
|
813
|
+
"happen",
|
|
814
|
+
"happened",
|
|
815
|
+
"happening",
|
|
816
|
+
"happens",
|
|
817
|
+
"include",
|
|
818
|
+
"included",
|
|
819
|
+
"including",
|
|
820
|
+
"includes",
|
|
821
|
+
"continue",
|
|
822
|
+
"continued",
|
|
823
|
+
"continuing",
|
|
824
|
+
"continues",
|
|
825
|
+
"send",
|
|
826
|
+
"sent",
|
|
827
|
+
"sending",
|
|
828
|
+
"sends",
|
|
829
|
+
"receive",
|
|
830
|
+
"received",
|
|
831
|
+
"receiving",
|
|
832
|
+
"receives",
|
|
833
|
+
"follow",
|
|
834
|
+
"followed",
|
|
835
|
+
"following",
|
|
836
|
+
"follows",
|
|
837
|
+
"stop",
|
|
838
|
+
"stopped",
|
|
839
|
+
"stopping",
|
|
840
|
+
"stops",
|
|
841
|
+
"open",
|
|
842
|
+
"opened",
|
|
843
|
+
"opening",
|
|
844
|
+
"opens",
|
|
845
|
+
"close",
|
|
846
|
+
"closed",
|
|
847
|
+
"closing",
|
|
848
|
+
"closes",
|
|
849
|
+
"done",
|
|
850
|
+
"doing",
|
|
851
|
+
// Time words
|
|
852
|
+
"today",
|
|
853
|
+
"tomorrow",
|
|
854
|
+
"yesterday",
|
|
855
|
+
"daily",
|
|
856
|
+
"weekly",
|
|
857
|
+
"monthly",
|
|
858
|
+
"yearly",
|
|
859
|
+
"annually",
|
|
860
|
+
"morning",
|
|
861
|
+
"afternoon",
|
|
862
|
+
"evening",
|
|
863
|
+
"night",
|
|
864
|
+
"week",
|
|
865
|
+
"month",
|
|
866
|
+
"year",
|
|
867
|
+
"hour",
|
|
868
|
+
"minute",
|
|
869
|
+
"second",
|
|
870
|
+
"time",
|
|
871
|
+
"date",
|
|
872
|
+
"day",
|
|
873
|
+
"days",
|
|
874
|
+
"weeks",
|
|
875
|
+
"months",
|
|
876
|
+
"years",
|
|
877
|
+
"currently",
|
|
878
|
+
"recently",
|
|
879
|
+
"later",
|
|
880
|
+
"earlier",
|
|
881
|
+
"soon",
|
|
882
|
+
"always",
|
|
883
|
+
"never",
|
|
884
|
+
"sometimes",
|
|
885
|
+
"often",
|
|
886
|
+
"usually",
|
|
887
|
+
"rarely",
|
|
888
|
+
// Generic/filler words
|
|
889
|
+
"thing",
|
|
890
|
+
"things",
|
|
891
|
+
"stuff",
|
|
892
|
+
"something",
|
|
893
|
+
"anything",
|
|
894
|
+
"nothing",
|
|
895
|
+
"everything",
|
|
896
|
+
"someone",
|
|
897
|
+
"anyone",
|
|
898
|
+
"noone",
|
|
899
|
+
"everyone",
|
|
900
|
+
"somewhere",
|
|
901
|
+
"anywhere",
|
|
902
|
+
"nowhere",
|
|
903
|
+
"everywhere",
|
|
904
|
+
"good",
|
|
905
|
+
"better",
|
|
906
|
+
"best",
|
|
907
|
+
"great",
|
|
908
|
+
"nice",
|
|
909
|
+
"okay",
|
|
910
|
+
"fine",
|
|
911
|
+
"right",
|
|
912
|
+
"wrong",
|
|
913
|
+
"bad",
|
|
914
|
+
"worse",
|
|
915
|
+
"worst",
|
|
916
|
+
"lot",
|
|
917
|
+
"lots",
|
|
918
|
+
"many",
|
|
919
|
+
"several",
|
|
920
|
+
"various",
|
|
921
|
+
"different",
|
|
922
|
+
"similar",
|
|
923
|
+
"another",
|
|
924
|
+
"next",
|
|
925
|
+
"last",
|
|
926
|
+
"first",
|
|
927
|
+
"second",
|
|
928
|
+
"third",
|
|
929
|
+
"new",
|
|
930
|
+
"old",
|
|
931
|
+
"big",
|
|
932
|
+
"small",
|
|
933
|
+
"large",
|
|
934
|
+
"little",
|
|
935
|
+
"long",
|
|
936
|
+
"short",
|
|
937
|
+
"high",
|
|
938
|
+
"low",
|
|
939
|
+
"full",
|
|
940
|
+
"empty",
|
|
941
|
+
"whole",
|
|
942
|
+
"part",
|
|
943
|
+
"real",
|
|
944
|
+
"true",
|
|
945
|
+
"false",
|
|
946
|
+
"actual",
|
|
947
|
+
"main",
|
|
948
|
+
"important",
|
|
949
|
+
// Descriptive/qualifier words
|
|
950
|
+
"really",
|
|
951
|
+
"actually",
|
|
952
|
+
"basically",
|
|
953
|
+
"probably",
|
|
954
|
+
"definitely",
|
|
955
|
+
"certainly",
|
|
956
|
+
"possibly",
|
|
957
|
+
"maybe",
|
|
958
|
+
"perhaps",
|
|
959
|
+
"like",
|
|
960
|
+
"likely",
|
|
961
|
+
"unlikely",
|
|
962
|
+
"almost",
|
|
963
|
+
"nearly",
|
|
964
|
+
"quite",
|
|
965
|
+
"rather",
|
|
966
|
+
"pretty",
|
|
967
|
+
"still",
|
|
968
|
+
"already",
|
|
969
|
+
"yet",
|
|
970
|
+
"though",
|
|
971
|
+
"although",
|
|
972
|
+
"however",
|
|
973
|
+
"therefore",
|
|
974
|
+
"thus",
|
|
975
|
+
"hence",
|
|
976
|
+
"truly",
|
|
977
|
+
"simply",
|
|
978
|
+
"easily",
|
|
979
|
+
"quickly",
|
|
980
|
+
"slowly",
|
|
981
|
+
"well",
|
|
982
|
+
"just",
|
|
983
|
+
"ever",
|
|
984
|
+
"either",
|
|
985
|
+
"neither",
|
|
986
|
+
"whether",
|
|
987
|
+
"because",
|
|
988
|
+
"since",
|
|
989
|
+
"while",
|
|
990
|
+
"until",
|
|
991
|
+
"unless",
|
|
992
|
+
"except",
|
|
993
|
+
"besides",
|
|
994
|
+
"anyway",
|
|
995
|
+
"otherwise",
|
|
996
|
+
"instead",
|
|
997
|
+
"meanwhile",
|
|
998
|
+
"furthermore",
|
|
999
|
+
"moreover",
|
|
1000
|
+
"nevertheless"
|
|
604
1001
|
]);
|
|
605
1002
|
function isConsonant(word, i) {
|
|
606
1003
|
const c = word[i];
|
|
@@ -1130,36 +1527,88 @@ function isLikelyArticleTitle(name) {
|
|
|
1130
1527
|
}
|
|
1131
1528
|
return false;
|
|
1132
1529
|
}
|
|
1133
|
-
var
|
|
1134
|
-
|
|
1135
|
-
|
|
1530
|
+
var STRICTNESS_CONFIGS = {
|
|
1531
|
+
conservative: {
|
|
1532
|
+
minWordLength: 5,
|
|
1533
|
+
minSuggestionScore: 15,
|
|
1534
|
+
// Requires exact match (10) + at least one stem (5)
|
|
1535
|
+
minMatchRatio: 0.6,
|
|
1536
|
+
// 60% of multi-word entity must match
|
|
1537
|
+
requireMultipleMatches: true,
|
|
1538
|
+
// Single-word entities need multiple content matches
|
|
1539
|
+
stemMatchBonus: 3,
|
|
1540
|
+
// Lower bonus for stem-only matches
|
|
1541
|
+
exactMatchBonus: 10
|
|
1542
|
+
// Standard bonus for exact matches
|
|
1543
|
+
},
|
|
1544
|
+
balanced: {
|
|
1545
|
+
minWordLength: 4,
|
|
1546
|
+
minSuggestionScore: 8,
|
|
1547
|
+
// At least one exact match or two stem matches
|
|
1548
|
+
minMatchRatio: 0.4,
|
|
1549
|
+
// 40% of multi-word entity must match
|
|
1550
|
+
requireMultipleMatches: false,
|
|
1551
|
+
stemMatchBonus: 5,
|
|
1552
|
+
// Standard bonus for stem matches
|
|
1553
|
+
exactMatchBonus: 10
|
|
1554
|
+
// Standard bonus for exact matches
|
|
1555
|
+
},
|
|
1556
|
+
aggressive: {
|
|
1557
|
+
minWordLength: 4,
|
|
1558
|
+
minSuggestionScore: 5,
|
|
1559
|
+
// Single stem match is enough
|
|
1560
|
+
minMatchRatio: 0.3,
|
|
1561
|
+
// 30% of multi-word entity must match
|
|
1562
|
+
requireMultipleMatches: false,
|
|
1563
|
+
stemMatchBonus: 6,
|
|
1564
|
+
// Higher bonus for stem matches
|
|
1565
|
+
exactMatchBonus: 10
|
|
1566
|
+
// Standard bonus for exact matches
|
|
1567
|
+
}
|
|
1568
|
+
};
|
|
1569
|
+
var DEFAULT_STRICTNESS = "conservative";
|
|
1570
|
+
var MIN_SUGGESTION_SCORE = STRICTNESS_CONFIGS.balanced.minSuggestionScore;
|
|
1571
|
+
var MIN_MATCH_RATIO = STRICTNESS_CONFIGS.balanced.minMatchRatio;
|
|
1572
|
+
function scoreEntity(entityName, contentTokens, contentStems, config) {
|
|
1136
1573
|
const entityTokens = tokenize(entityName);
|
|
1137
1574
|
if (entityTokens.length === 0)
|
|
1138
1575
|
return 0;
|
|
1139
1576
|
const entityStems = entityTokens.map((t) => stem(t));
|
|
1140
1577
|
let score = 0;
|
|
1141
1578
|
let matchedWords = 0;
|
|
1579
|
+
let exactMatches = 0;
|
|
1142
1580
|
for (let i = 0; i < entityTokens.length; i++) {
|
|
1143
1581
|
const token = entityTokens[i];
|
|
1144
1582
|
const entityStem = entityStems[i];
|
|
1145
1583
|
if (contentTokens.has(token)) {
|
|
1146
|
-
score +=
|
|
1584
|
+
score += config.exactMatchBonus;
|
|
1147
1585
|
matchedWords++;
|
|
1586
|
+
exactMatches++;
|
|
1148
1587
|
} else if (contentStems.has(entityStem)) {
|
|
1149
|
-
score +=
|
|
1588
|
+
score += config.stemMatchBonus;
|
|
1150
1589
|
matchedWords++;
|
|
1151
1590
|
}
|
|
1152
1591
|
}
|
|
1153
1592
|
if (entityTokens.length > 1) {
|
|
1154
1593
|
const matchRatio = matchedWords / entityTokens.length;
|
|
1155
|
-
if (matchRatio <
|
|
1594
|
+
if (matchRatio < config.minMatchRatio) {
|
|
1595
|
+
return 0;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
if (config.requireMultipleMatches && entityTokens.length === 1) {
|
|
1599
|
+
if (exactMatches === 0) {
|
|
1156
1600
|
return 0;
|
|
1157
1601
|
}
|
|
1158
1602
|
}
|
|
1159
1603
|
return score;
|
|
1160
1604
|
}
|
|
1161
1605
|
function suggestRelatedLinks(content, options = {}) {
|
|
1162
|
-
const {
|
|
1606
|
+
const {
|
|
1607
|
+
maxSuggestions = 3,
|
|
1608
|
+
excludeLinked = true,
|
|
1609
|
+
strictness = DEFAULT_STRICTNESS
|
|
1610
|
+
} = options;
|
|
1611
|
+
const config = STRICTNESS_CONFIGS[strictness];
|
|
1163
1612
|
const emptyResult = { suggestions: [], suffix: "" };
|
|
1164
1613
|
if (SUGGESTION_PATTERN.test(content)) {
|
|
1165
1614
|
return emptyResult;
|
|
@@ -1191,11 +1640,11 @@ function suggestRelatedLinks(content, options = {}) {
|
|
|
1191
1640
|
if (linkedEntities.has(entityName.toLowerCase())) {
|
|
1192
1641
|
continue;
|
|
1193
1642
|
}
|
|
1194
|
-
const score = scoreEntity(entityName, contentTokens, contentStems);
|
|
1643
|
+
const score = scoreEntity(entityName, contentTokens, contentStems, config);
|
|
1195
1644
|
if (score > 0) {
|
|
1196
1645
|
directlyMatchedEntities.add(entityName);
|
|
1197
1646
|
}
|
|
1198
|
-
if (score >=
|
|
1647
|
+
if (score >= config.minSuggestionScore) {
|
|
1199
1648
|
scoredEntities.push({ name: entityName, score });
|
|
1200
1649
|
}
|
|
1201
1650
|
}
|
|
@@ -1215,7 +1664,7 @@ function suggestRelatedLinks(content, options = {}) {
|
|
|
1215
1664
|
const existing = scoredEntities.find((e) => e.name === entityName);
|
|
1216
1665
|
if (existing) {
|
|
1217
1666
|
existing.score += boost;
|
|
1218
|
-
} else if (boost >=
|
|
1667
|
+
} else if (boost >= config.minSuggestionScore) {
|
|
1219
1668
|
scoredEntities.push({ name: entityName, score: boost });
|
|
1220
1669
|
}
|
|
1221
1670
|
}
|
|
@@ -1248,10 +1697,11 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1248
1697
|
format: z.enum(["plain", "bullet", "task", "numbered", "timestamp-bullet"]).default("plain").describe("How to format the content"),
|
|
1249
1698
|
commit: z.boolean().default(false).describe("If true, commit this change to git (creates undo point)"),
|
|
1250
1699
|
skipWikilinks: z.boolean().default(false).describe("If true, skip auto-wikilink application (wikilinks are applied by default)"),
|
|
1251
|
-
preserveListNesting: z.boolean().default(
|
|
1252
|
-
suggestOutgoingLinks: z.boolean().default(true).describe('Append suggested outgoing wikilinks based on content (e.g., "\u2192 [[AI]] [[Philosophy]]"). Set false to disable.')
|
|
1700
|
+
preserveListNesting: z.boolean().default(true).describe("Detect and preserve the indentation level of surrounding list items. Set false to disable."),
|
|
1701
|
+
suggestOutgoingLinks: z.boolean().default(true).describe('Append suggested outgoing wikilinks based on content (e.g., "\u2192 [[AI]] [[Philosophy]]"). Set false to disable.'),
|
|
1702
|
+
maxSuggestions: z.number().min(1).max(10).default(3).describe("Maximum number of suggested wikilinks to append (1-10, default: 3)")
|
|
1253
1703
|
},
|
|
1254
|
-
async ({ path: notePath, section, content, position, format, commit, skipWikilinks, preserveListNesting, suggestOutgoingLinks }) => {
|
|
1704
|
+
async ({ path: notePath, section, content, position, format, commit, skipWikilinks, preserveListNesting, suggestOutgoingLinks, maxSuggestions }) => {
|
|
1255
1705
|
try {
|
|
1256
1706
|
const fullPath = path5.join(vaultPath2, notePath);
|
|
1257
1707
|
try {
|
|
@@ -1277,7 +1727,7 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1277
1727
|
let { content: processedContent, wikilinkInfo } = maybeApplyWikilinks(content, skipWikilinks);
|
|
1278
1728
|
let suggestInfo;
|
|
1279
1729
|
if (suggestOutgoingLinks && !skipWikilinks) {
|
|
1280
|
-
const result2 = suggestRelatedLinks(processedContent);
|
|
1730
|
+
const result2 = suggestRelatedLinks(processedContent, { maxSuggestions });
|
|
1281
1731
|
if (result2.suffix) {
|
|
1282
1732
|
processedContent = processedContent + " " + result2.suffix;
|
|
1283
1733
|
suggestInfo = `Suggested: ${result2.suggestions.join(", ")}`;
|
|
@@ -1415,9 +1865,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1415
1865
|
useRegex: z.boolean().default(false).describe("Treat search as regex"),
|
|
1416
1866
|
commit: z.boolean().default(false).describe("If true, commit this change to git (creates undo point)"),
|
|
1417
1867
|
skipWikilinks: z.boolean().default(false).describe("If true, skip auto-wikilink application on replacement text"),
|
|
1418
|
-
suggestOutgoingLinks: z.boolean().default(true).describe('Append suggested outgoing wikilinks based on content (e.g., "\u2192 [[AI]] [[Philosophy]]"). Set false to disable.')
|
|
1868
|
+
suggestOutgoingLinks: z.boolean().default(true).describe('Append suggested outgoing wikilinks based on content (e.g., "\u2192 [[AI]] [[Philosophy]]"). Set false to disable.'),
|
|
1869
|
+
maxSuggestions: z.number().min(1).max(10).default(3).describe("Maximum number of suggested wikilinks to append (1-10, default: 3)")
|
|
1419
1870
|
},
|
|
1420
|
-
async ({ path: notePath, section, search, replacement, mode, useRegex, commit, skipWikilinks, suggestOutgoingLinks }) => {
|
|
1871
|
+
async ({ path: notePath, section, search, replacement, mode, useRegex, commit, skipWikilinks, suggestOutgoingLinks, maxSuggestions }) => {
|
|
1421
1872
|
try {
|
|
1422
1873
|
const fullPath = path5.join(vaultPath2, notePath);
|
|
1423
1874
|
try {
|
|
@@ -1443,7 +1894,7 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1443
1894
|
let { content: processedReplacement, wikilinkInfo } = maybeApplyWikilinks(replacement, skipWikilinks);
|
|
1444
1895
|
let suggestInfo;
|
|
1445
1896
|
if (suggestOutgoingLinks && !skipWikilinks) {
|
|
1446
|
-
const result2 = suggestRelatedLinks(processedReplacement);
|
|
1897
|
+
const result2 = suggestRelatedLinks(processedReplacement, { maxSuggestions });
|
|
1447
1898
|
if (result2.suffix) {
|
|
1448
1899
|
processedReplacement = processedReplacement + " " + result2.suffix;
|
|
1449
1900
|
suggestInfo = `Suggested: ${result2.suggestions.join(", ")}`;
|
|
@@ -1652,9 +2103,10 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
1652
2103
|
commit: z2.boolean().default(false).describe("If true, commit this change to git (creates undo point)"),
|
|
1653
2104
|
skipWikilinks: z2.boolean().default(false).describe("If true, skip auto-wikilink application (wikilinks are applied by default)"),
|
|
1654
2105
|
suggestOutgoingLinks: z2.boolean().default(true).describe('Append suggested outgoing wikilinks based on content (e.g., "\u2192 [[AI]] [[Philosophy]]"). Set false to disable.'),
|
|
2106
|
+
maxSuggestions: z2.number().min(1).max(10).default(3).describe("Maximum number of suggested wikilinks to append (1-10, default: 3)"),
|
|
1655
2107
|
preserveListNesting: z2.boolean().default(true).describe("Preserve indentation when inserting into nested lists. Default: true")
|
|
1656
2108
|
},
|
|
1657
|
-
async ({ path: notePath, section, task, position, completed, commit, skipWikilinks, suggestOutgoingLinks, preserveListNesting }) => {
|
|
2109
|
+
async ({ path: notePath, section, task, position, completed, commit, skipWikilinks, suggestOutgoingLinks, maxSuggestions, preserveListNesting }) => {
|
|
1658
2110
|
try {
|
|
1659
2111
|
const fullPath = path6.join(vaultPath2, notePath);
|
|
1660
2112
|
try {
|
|
@@ -1680,7 +2132,7 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
1680
2132
|
let { content: processedTask, wikilinkInfo } = maybeApplyWikilinks(task.trim(), skipWikilinks);
|
|
1681
2133
|
let suggestInfo;
|
|
1682
2134
|
if (suggestOutgoingLinks && !skipWikilinks) {
|
|
1683
|
-
const result2 = suggestRelatedLinks(processedTask);
|
|
2135
|
+
const result2 = suggestRelatedLinks(processedTask, { maxSuggestions });
|
|
1684
2136
|
if (result2.suffix) {
|
|
1685
2137
|
processedTask = processedTask + " " + result2.suffix;
|
|
1686
2138
|
suggestInfo = `Suggested: ${result2.suggestions.join(", ")}`;
|