@velvetmonkey/flywheel-crank 0.8.0 → 0.9.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 +120 -40
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -14,6 +14,10 @@ import matter from "gray-matter";
|
|
|
14
14
|
|
|
15
15
|
// src/core/constants.ts
|
|
16
16
|
var HEADING_REGEX = /^(#{1,6})\s+(.+)$/;
|
|
17
|
+
function estimateTokens(content) {
|
|
18
|
+
const str = typeof content === "string" ? content : JSON.stringify(content);
|
|
19
|
+
return Math.ceil(str.length / 4);
|
|
20
|
+
}
|
|
17
21
|
|
|
18
22
|
// src/core/writer.ts
|
|
19
23
|
var SENSITIVE_PATH_PATTERNS = [
|
|
@@ -510,9 +514,12 @@ async function undoLastCommit(vaultPath2) {
|
|
|
510
514
|
import {
|
|
511
515
|
scanVaultEntities,
|
|
512
516
|
getAllEntities,
|
|
517
|
+
getEntityName,
|
|
518
|
+
getEntityAliases,
|
|
513
519
|
applyWikilinks,
|
|
514
520
|
loadEntityCache,
|
|
515
|
-
saveEntityCache
|
|
521
|
+
saveEntityCache,
|
|
522
|
+
ENTITY_CACHE_VERSION
|
|
516
523
|
} from "@velvetmonkey/vault-core";
|
|
517
524
|
import path4 from "path";
|
|
518
525
|
|
|
@@ -1411,6 +1418,12 @@ async function initializeEntityIndex(vaultPath2) {
|
|
|
1411
1418
|
try {
|
|
1412
1419
|
const cached = await loadEntityCache(cacheFile);
|
|
1413
1420
|
if (cached) {
|
|
1421
|
+
const cacheVersion = cached._metadata.version ?? 1;
|
|
1422
|
+
if (cacheVersion < ENTITY_CACHE_VERSION) {
|
|
1423
|
+
console.error(`[Crank] Cache version ${cacheVersion} < ${ENTITY_CACHE_VERSION}, rebuilding...`);
|
|
1424
|
+
await rebuildIndex(vaultPath2, cacheFile);
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1414
1427
|
entityIndex = cached;
|
|
1415
1428
|
indexReady = true;
|
|
1416
1429
|
console.error(`[Crank] Loaded ${cached._metadata.total_entities} entities from cache`);
|
|
@@ -1569,33 +1582,51 @@ var STRICTNESS_CONFIGS = {
|
|
|
1569
1582
|
var DEFAULT_STRICTNESS = "conservative";
|
|
1570
1583
|
var MIN_SUGGESTION_SCORE = STRICTNESS_CONFIGS.balanced.minSuggestionScore;
|
|
1571
1584
|
var MIN_MATCH_RATIO = STRICTNESS_CONFIGS.balanced.minMatchRatio;
|
|
1572
|
-
function
|
|
1573
|
-
const
|
|
1574
|
-
if (
|
|
1575
|
-
return 0;
|
|
1576
|
-
|
|
1585
|
+
function scoreNameAgainstContent(name, contentTokens, contentStems, config) {
|
|
1586
|
+
const nameTokens = tokenize(name);
|
|
1587
|
+
if (nameTokens.length === 0) {
|
|
1588
|
+
return { score: 0, matchedWords: 0, exactMatches: 0, totalTokens: 0 };
|
|
1589
|
+
}
|
|
1590
|
+
const nameStems = nameTokens.map((t) => stem(t));
|
|
1577
1591
|
let score = 0;
|
|
1578
1592
|
let matchedWords = 0;
|
|
1579
1593
|
let exactMatches = 0;
|
|
1580
|
-
for (let i = 0; i <
|
|
1581
|
-
const token =
|
|
1582
|
-
const
|
|
1594
|
+
for (let i = 0; i < nameTokens.length; i++) {
|
|
1595
|
+
const token = nameTokens[i];
|
|
1596
|
+
const nameStem = nameStems[i];
|
|
1583
1597
|
if (contentTokens.has(token)) {
|
|
1584
1598
|
score += config.exactMatchBonus;
|
|
1585
1599
|
matchedWords++;
|
|
1586
1600
|
exactMatches++;
|
|
1587
|
-
} else if (contentStems.has(
|
|
1601
|
+
} else if (contentStems.has(nameStem)) {
|
|
1588
1602
|
score += config.stemMatchBonus;
|
|
1589
1603
|
matchedWords++;
|
|
1590
1604
|
}
|
|
1591
1605
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1606
|
+
return { score, matchedWords, exactMatches, totalTokens: nameTokens.length };
|
|
1607
|
+
}
|
|
1608
|
+
function scoreEntity(entity, contentTokens, contentStems, config) {
|
|
1609
|
+
const entityName = getEntityName(entity);
|
|
1610
|
+
const aliases = getEntityAliases(entity);
|
|
1611
|
+
const nameResult = scoreNameAgainstContent(entityName, contentTokens, contentStems, config);
|
|
1612
|
+
let bestAliasResult = { score: 0, matchedWords: 0, exactMatches: 0, totalTokens: 0 };
|
|
1613
|
+
for (const alias of aliases) {
|
|
1614
|
+
const aliasResult = scoreNameAgainstContent(alias, contentTokens, contentStems, config);
|
|
1615
|
+
if (aliasResult.score > bestAliasResult.score) {
|
|
1616
|
+
bestAliasResult = aliasResult;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
const bestResult = nameResult.score >= bestAliasResult.score ? nameResult : bestAliasResult;
|
|
1620
|
+
const { score, matchedWords, exactMatches, totalTokens } = bestResult;
|
|
1621
|
+
if (totalTokens === 0)
|
|
1622
|
+
return 0;
|
|
1623
|
+
if (totalTokens > 1) {
|
|
1624
|
+
const matchRatio = matchedWords / totalTokens;
|
|
1594
1625
|
if (matchRatio < config.minMatchRatio) {
|
|
1595
1626
|
return 0;
|
|
1596
1627
|
}
|
|
1597
1628
|
}
|
|
1598
|
-
if (config.requireMultipleMatches &&
|
|
1629
|
+
if (config.requireMultipleMatches && totalTokens === 1) {
|
|
1599
1630
|
if (exactMatches === 0) {
|
|
1600
1631
|
return 0;
|
|
1601
1632
|
}
|
|
@@ -1628,7 +1659,7 @@ function suggestRelatedLinks(content, options = {}) {
|
|
|
1628
1659
|
const scoredEntities = [];
|
|
1629
1660
|
const directlyMatchedEntities = /* @__PURE__ */ new Set();
|
|
1630
1661
|
for (const entity of entities) {
|
|
1631
|
-
const entityName =
|
|
1662
|
+
const entityName = getEntityName(entity);
|
|
1632
1663
|
if (!entityName)
|
|
1633
1664
|
continue;
|
|
1634
1665
|
if (entityName.length > MAX_ENTITY_LENGTH) {
|
|
@@ -1640,7 +1671,7 @@ function suggestRelatedLinks(content, options = {}) {
|
|
|
1640
1671
|
if (linkedEntities.has(entityName.toLowerCase())) {
|
|
1641
1672
|
continue;
|
|
1642
1673
|
}
|
|
1643
|
-
const score = scoreEntity(
|
|
1674
|
+
const score = scoreEntity(entity, contentTokens, contentStems, config);
|
|
1644
1675
|
if (score > 0) {
|
|
1645
1676
|
directlyMatchedEntities.add(entityName);
|
|
1646
1677
|
}
|
|
@@ -1650,7 +1681,7 @@ function suggestRelatedLinks(content, options = {}) {
|
|
|
1650
1681
|
}
|
|
1651
1682
|
if (cooccurrenceIndex && directlyMatchedEntities.size > 0) {
|
|
1652
1683
|
for (const entity of entities) {
|
|
1653
|
-
const entityName =
|
|
1684
|
+
const entityName = getEntityName(entity);
|
|
1654
1685
|
if (!entityName)
|
|
1655
1686
|
continue;
|
|
1656
1687
|
if (entityName.length > MAX_ENTITY_LENGTH)
|
|
@@ -1710,8 +1741,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1710
1741
|
const result2 = {
|
|
1711
1742
|
success: false,
|
|
1712
1743
|
message: `File not found: ${notePath}`,
|
|
1713
|
-
path: notePath
|
|
1744
|
+
path: notePath,
|
|
1745
|
+
tokensEstimate: 0
|
|
1714
1746
|
};
|
|
1747
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1715
1748
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1716
1749
|
}
|
|
1717
1750
|
const { content: fileContent, frontmatter } = await readVaultFile(vaultPath2, notePath);
|
|
@@ -1720,8 +1753,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1720
1753
|
const result2 = {
|
|
1721
1754
|
success: false,
|
|
1722
1755
|
message: `Section not found: ${section}`,
|
|
1723
|
-
path: notePath
|
|
1756
|
+
path: notePath,
|
|
1757
|
+
tokensEstimate: 0
|
|
1724
1758
|
};
|
|
1759
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1725
1760
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1726
1761
|
}
|
|
1727
1762
|
let { content: processedContent, wikilinkInfo } = maybeApplyWikilinks(content, skipWikilinks);
|
|
@@ -1761,15 +1796,20 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1761
1796
|
path: notePath,
|
|
1762
1797
|
preview,
|
|
1763
1798
|
gitCommit,
|
|
1764
|
-
gitError
|
|
1799
|
+
gitError,
|
|
1800
|
+
tokensEstimate: 0
|
|
1801
|
+
// Will be set below
|
|
1765
1802
|
};
|
|
1803
|
+
result.tokensEstimate = estimateTokens(result);
|
|
1766
1804
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1767
1805
|
} catch (error) {
|
|
1768
1806
|
const result = {
|
|
1769
1807
|
success: false,
|
|
1770
1808
|
message: `Failed to add content: ${error instanceof Error ? error.message : String(error)}`,
|
|
1771
|
-
path: notePath
|
|
1809
|
+
path: notePath,
|
|
1810
|
+
tokensEstimate: 0
|
|
1772
1811
|
};
|
|
1812
|
+
result.tokensEstimate = estimateTokens(result);
|
|
1773
1813
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1774
1814
|
}
|
|
1775
1815
|
}
|
|
@@ -1794,8 +1834,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1794
1834
|
const result2 = {
|
|
1795
1835
|
success: false,
|
|
1796
1836
|
message: `File not found: ${notePath}`,
|
|
1797
|
-
path: notePath
|
|
1837
|
+
path: notePath,
|
|
1838
|
+
tokensEstimate: 0
|
|
1798
1839
|
};
|
|
1840
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1799
1841
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1800
1842
|
}
|
|
1801
1843
|
const { content: fileContent, frontmatter } = await readVaultFile(vaultPath2, notePath);
|
|
@@ -1804,8 +1846,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1804
1846
|
const result2 = {
|
|
1805
1847
|
success: false,
|
|
1806
1848
|
message: `Section not found: ${section}`,
|
|
1807
|
-
path: notePath
|
|
1849
|
+
path: notePath,
|
|
1850
|
+
tokensEstimate: 0
|
|
1808
1851
|
};
|
|
1852
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1809
1853
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1810
1854
|
}
|
|
1811
1855
|
const removeResult = removeFromSection(
|
|
@@ -1819,8 +1863,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1819
1863
|
const result2 = {
|
|
1820
1864
|
success: false,
|
|
1821
1865
|
message: `No content matching "${pattern}" found in section "${sectionBoundary.name}"`,
|
|
1822
|
-
path: notePath
|
|
1866
|
+
path: notePath,
|
|
1867
|
+
tokensEstimate: 0
|
|
1823
1868
|
};
|
|
1869
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1824
1870
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1825
1871
|
}
|
|
1826
1872
|
await writeVaultFile(vaultPath2, notePath, removeResult.content, frontmatter);
|
|
@@ -1840,15 +1886,19 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1840
1886
|
path: notePath,
|
|
1841
1887
|
preview: removeResult.removedLines.join("\n"),
|
|
1842
1888
|
gitCommit,
|
|
1843
|
-
gitError
|
|
1889
|
+
gitError,
|
|
1890
|
+
tokensEstimate: 0
|
|
1844
1891
|
};
|
|
1892
|
+
result.tokensEstimate = estimateTokens(result);
|
|
1845
1893
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1846
1894
|
} catch (error) {
|
|
1847
1895
|
const result = {
|
|
1848
1896
|
success: false,
|
|
1849
1897
|
message: `Failed to remove content: ${error instanceof Error ? error.message : String(error)}`,
|
|
1850
|
-
path: notePath
|
|
1898
|
+
path: notePath,
|
|
1899
|
+
tokensEstimate: 0
|
|
1851
1900
|
};
|
|
1901
|
+
result.tokensEstimate = estimateTokens(result);
|
|
1852
1902
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1853
1903
|
}
|
|
1854
1904
|
}
|
|
@@ -1877,8 +1927,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1877
1927
|
const result2 = {
|
|
1878
1928
|
success: false,
|
|
1879
1929
|
message: `File not found: ${notePath}`,
|
|
1880
|
-
path: notePath
|
|
1930
|
+
path: notePath,
|
|
1931
|
+
tokensEstimate: 0
|
|
1881
1932
|
};
|
|
1933
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1882
1934
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1883
1935
|
}
|
|
1884
1936
|
const { content: fileContent, frontmatter } = await readVaultFile(vaultPath2, notePath);
|
|
@@ -1887,8 +1939,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1887
1939
|
const result2 = {
|
|
1888
1940
|
success: false,
|
|
1889
1941
|
message: `Section not found: ${section}`,
|
|
1890
|
-
path: notePath
|
|
1942
|
+
path: notePath,
|
|
1943
|
+
tokensEstimate: 0
|
|
1891
1944
|
};
|
|
1945
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1892
1946
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1893
1947
|
}
|
|
1894
1948
|
let { content: processedReplacement, wikilinkInfo } = maybeApplyWikilinks(replacement, skipWikilinks);
|
|
@@ -1912,8 +1966,10 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1912
1966
|
const result2 = {
|
|
1913
1967
|
success: false,
|
|
1914
1968
|
message: `No content matching "${search}" found in section "${sectionBoundary.name}"`,
|
|
1915
|
-
path: notePath
|
|
1969
|
+
path: notePath,
|
|
1970
|
+
tokensEstimate: 0
|
|
1916
1971
|
};
|
|
1972
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
1917
1973
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
1918
1974
|
}
|
|
1919
1975
|
await writeVaultFile(vaultPath2, notePath, replaceResult.content, frontmatter);
|
|
@@ -1937,15 +1993,19 @@ function registerMutationTools(server2, vaultPath2) {
|
|
|
1937
1993
|
path: notePath,
|
|
1938
1994
|
preview: previewLines.join("\n"),
|
|
1939
1995
|
gitCommit,
|
|
1940
|
-
gitError
|
|
1996
|
+
gitError,
|
|
1997
|
+
tokensEstimate: 0
|
|
1941
1998
|
};
|
|
1999
|
+
result.tokensEstimate = estimateTokens(result);
|
|
1942
2000
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1943
2001
|
} catch (error) {
|
|
1944
2002
|
const result = {
|
|
1945
2003
|
success: false,
|
|
1946
2004
|
message: `Failed to replace content: ${error instanceof Error ? error.message : String(error)}`,
|
|
1947
|
-
path: notePath
|
|
2005
|
+
path: notePath,
|
|
2006
|
+
tokensEstimate: 0
|
|
1948
2007
|
};
|
|
2008
|
+
result.tokensEstimate = estimateTokens(result);
|
|
1949
2009
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1950
2010
|
}
|
|
1951
2011
|
}
|
|
@@ -2019,8 +2079,10 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2019
2079
|
const result2 = {
|
|
2020
2080
|
success: false,
|
|
2021
2081
|
message: `File not found: ${notePath}`,
|
|
2022
|
-
path: notePath
|
|
2082
|
+
path: notePath,
|
|
2083
|
+
tokensEstimate: 0
|
|
2023
2084
|
};
|
|
2085
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
2024
2086
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
2025
2087
|
}
|
|
2026
2088
|
const { content: fileContent, frontmatter } = await readVaultFile(vaultPath2, notePath);
|
|
@@ -2031,8 +2093,10 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2031
2093
|
const result2 = {
|
|
2032
2094
|
success: false,
|
|
2033
2095
|
message: `Section not found: ${section}`,
|
|
2034
|
-
path: notePath
|
|
2096
|
+
path: notePath,
|
|
2097
|
+
tokensEstimate: 0
|
|
2035
2098
|
};
|
|
2099
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
2036
2100
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
2037
2101
|
}
|
|
2038
2102
|
sectionBoundary = found;
|
|
@@ -2046,8 +2110,10 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2046
2110
|
const result2 = {
|
|
2047
2111
|
success: false,
|
|
2048
2112
|
message: `No task found matching "${task}"${section ? ` in section "${section}"` : ""}`,
|
|
2049
|
-
path: notePath
|
|
2113
|
+
path: notePath,
|
|
2114
|
+
tokensEstimate: 0
|
|
2050
2115
|
};
|
|
2116
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
2051
2117
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
2052
2118
|
}
|
|
2053
2119
|
const toggleResult = toggleTask(fileContent, matchingTask.line);
|
|
@@ -2055,8 +2121,10 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2055
2121
|
const result2 = {
|
|
2056
2122
|
success: false,
|
|
2057
2123
|
message: "Failed to toggle task",
|
|
2058
|
-
path: notePath
|
|
2124
|
+
path: notePath,
|
|
2125
|
+
tokensEstimate: 0
|
|
2059
2126
|
};
|
|
2127
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
2060
2128
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
2061
2129
|
}
|
|
2062
2130
|
await writeVaultFile(vaultPath2, notePath, toggleResult.content, frontmatter);
|
|
@@ -2078,15 +2146,19 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2078
2146
|
path: notePath,
|
|
2079
2147
|
preview: `${checkbox} ${matchingTask.text}`,
|
|
2080
2148
|
gitCommit,
|
|
2081
|
-
gitError
|
|
2149
|
+
gitError,
|
|
2150
|
+
tokensEstimate: 0
|
|
2082
2151
|
};
|
|
2152
|
+
result.tokensEstimate = estimateTokens(result);
|
|
2083
2153
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2084
2154
|
} catch (error) {
|
|
2085
2155
|
const result = {
|
|
2086
2156
|
success: false,
|
|
2087
2157
|
message: `Failed to toggle task: ${error instanceof Error ? error.message : String(error)}`,
|
|
2088
|
-
path: notePath
|
|
2158
|
+
path: notePath,
|
|
2159
|
+
tokensEstimate: 0
|
|
2089
2160
|
};
|
|
2161
|
+
result.tokensEstimate = estimateTokens(result);
|
|
2090
2162
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2091
2163
|
}
|
|
2092
2164
|
}
|
|
@@ -2115,8 +2187,10 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2115
2187
|
const result2 = {
|
|
2116
2188
|
success: false,
|
|
2117
2189
|
message: `File not found: ${notePath}`,
|
|
2118
|
-
path: notePath
|
|
2190
|
+
path: notePath,
|
|
2191
|
+
tokensEstimate: 0
|
|
2119
2192
|
};
|
|
2193
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
2120
2194
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
2121
2195
|
}
|
|
2122
2196
|
const { content: fileContent, frontmatter } = await readVaultFile(vaultPath2, notePath);
|
|
@@ -2125,8 +2199,10 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2125
2199
|
const result2 = {
|
|
2126
2200
|
success: false,
|
|
2127
2201
|
message: `Section not found: ${section}`,
|
|
2128
|
-
path: notePath
|
|
2202
|
+
path: notePath,
|
|
2203
|
+
tokensEstimate: 0
|
|
2129
2204
|
};
|
|
2205
|
+
result2.tokensEstimate = estimateTokens(result2);
|
|
2130
2206
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
2131
2207
|
}
|
|
2132
2208
|
let { content: processedTask, wikilinkInfo } = maybeApplyWikilinks(task.trim(), skipWikilinks);
|
|
@@ -2166,15 +2242,19 @@ function registerTaskTools(server2, vaultPath2) {
|
|
|
2166
2242
|
preview: taskLine + (infoLines.length > 0 ? `
|
|
2167
2243
|
(${infoLines.join("; ")})` : ""),
|
|
2168
2244
|
gitCommit,
|
|
2169
|
-
gitError
|
|
2245
|
+
gitError,
|
|
2246
|
+
tokensEstimate: 0
|
|
2170
2247
|
};
|
|
2248
|
+
result.tokensEstimate = estimateTokens(result);
|
|
2171
2249
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2172
2250
|
} catch (error) {
|
|
2173
2251
|
const result = {
|
|
2174
2252
|
success: false,
|
|
2175
2253
|
message: `Failed to add task: ${error instanceof Error ? error.message : String(error)}`,
|
|
2176
|
-
path: notePath
|
|
2254
|
+
path: notePath,
|
|
2255
|
+
tokensEstimate: 0
|
|
2177
2256
|
};
|
|
2257
|
+
result.tokensEstimate = estimateTokens(result);
|
|
2178
2258
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2179
2259
|
}
|
|
2180
2260
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velvetmonkey/flywheel-crank",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Deterministic vault mutations for Obsidian via MCP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
44
|
-
"@velvetmonkey/vault-core": "^0.
|
|
44
|
+
"@velvetmonkey/vault-core": "^0.2.0",
|
|
45
45
|
"gray-matter": "^4.0.3",
|
|
46
|
-
"
|
|
47
|
-
"
|
|
46
|
+
"simple-git": "^3.22.0",
|
|
47
|
+
"zod": "^3.22.4"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/node": "^20.10.0",
|